aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-11-11 05:51:24 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-11 05:51:24 -0500
commit3b621ee5df437d3f332a635ab6421aaa61a7dc2b (patch)
treec4a5236cee8eb7418770802313d36a55f1cc0b1e /drivers
parent7211bb9b64f17b23834d91fc3d0c1d78671ee9a8 (diff)
parent5e04e7fe774794b837e1d3897e6b96ae2d06679a (diff)
Merge branch 'master'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/acpi/container.c6
-rw-r--r--drivers/acpi/glue.c1
-rw-r--r--drivers/acpi/osl.c6
-rw-r--r--drivers/acpi/processor_idle.c37
-rw-r--r--drivers/acpi/scan.c6
-rw-r--r--drivers/acpi/video.c12
-rw-r--r--drivers/atm/horizon.c4
-rw-r--r--drivers/base/platform.c153
-rw-r--r--drivers/base/power/sysfs.c1
-rw-r--r--drivers/block/DAC960.c31
-rw-r--r--drivers/block/Kconfig12
-rw-r--r--drivers/block/Kconfig.iosched69
-rw-r--r--drivers/block/Makefile14
-rw-r--r--drivers/block/amiflop.c1
-rw-r--r--drivers/block/as-iosched.c1985
-rw-r--r--drivers/block/cciss.c12
-rw-r--r--drivers/block/cfq-iosched.c2428
-rw-r--r--drivers/block/deadline-iosched.c878
-rw-r--r--drivers/block/elevator.c802
-rw-r--r--drivers/block/floppy.c9
-rw-r--r--drivers/block/genhd.c726
-rw-r--r--drivers/block/ioctl.c275
-rw-r--r--drivers/block/ll_rw_blk.c3613
-rw-r--r--drivers/block/noop-iosched.c46
-rw-r--r--drivers/block/pktcdvd.c3
-rw-r--r--drivers/block/scsi_ioctl.c589
-rw-r--r--drivers/block/swim3.c20
-rw-r--r--drivers/bluetooth/bcm203x.c4
-rw-r--r--drivers/bluetooth/bfusb.c4
-rw-r--r--drivers/bluetooth/bluecard_cs.c3
-rw-r--r--drivers/bluetooth/bpa10x.c8
-rw-r--r--drivers/bluetooth/bt3c_cs.c3
-rw-r--r--drivers/bluetooth/btuart_cs.c3
-rw-r--r--drivers/bluetooth/dtl1_cs.c3
-rw-r--r--drivers/bluetooth/hci_bcsp.c3
-rw-r--r--drivers/bluetooth/hci_h4.c4
-rw-r--r--drivers/bluetooth/hci_ldisc.c4
-rw-r--r--drivers/bluetooth/hci_usb.c11
-rw-r--r--drivers/bluetooth/hci_vhci.c4
-rw-r--r--drivers/cdrom/mcdx.c4
-rw-r--r--drivers/char/agp/amd-k7-agp.c7
-rw-r--r--drivers/char/agp/amd64-agp.c1
-rw-r--r--drivers/char/agp/ati-agp.c7
-rw-r--r--drivers/char/agp/backend.c15
-rw-r--r--drivers/char/agp/efficeon-agp.c2
-rw-r--r--drivers/char/agp/frontend.c15
-rw-r--r--drivers/char/agp/generic.c19
-rw-r--r--drivers/char/agp/i460-agp.c23
-rw-r--r--drivers/char/agp/intel-agp.c5
-rw-r--r--drivers/char/agp/sgi-agp.c2
-rw-r--r--drivers/char/agp/sworks-agp.c28
-rw-r--r--drivers/char/consolemap.c12
-rw-r--r--drivers/char/drm/ati_pcigart.c4
-rw-r--r--drivers/char/drm/ffb_context.c6
-rw-r--r--drivers/char/drm/ffb_drv.c6
-rw-r--r--drivers/char/epca.c1
-rw-r--r--drivers/char/ip2.c1
-rw-r--r--drivers/char/ip2/i2ellis.c4
-rw-r--r--drivers/char/ipmi/ipmi_bt_sm.c38
-rw-r--r--drivers/char/ipmi/ipmi_kcs_sm.c48
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c952
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c4
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c183
-rw-r--r--drivers/char/ipmi/ipmi_si_sm.h1
-rw-r--r--drivers/char/ipmi/ipmi_smic_sm.c15
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c259
-rw-r--r--drivers/char/istallion.c7
-rw-r--r--drivers/char/mwave/tp3780i.c1
-rw-r--r--drivers/char/mxser.c48
-rw-r--r--drivers/char/n_hdlc.c3
-rw-r--r--drivers/char/pcmcia/synclink_cs.c3
-rw-r--r--drivers/char/rocket.c6
-rw-r--r--drivers/char/rtc.c65
-rw-r--r--drivers/char/selection.c3
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/stallion.c6
-rw-r--r--drivers/char/synclink.c11
-rw-r--r--drivers/char/synclinkmp.c10
-rw-r--r--drivers/char/sysrq.c4
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/char/tpm/tpm_nsc.c48
-rw-r--r--drivers/char/tty_io.c9
-rw-r--r--drivers/char/viocons.c1
-rw-r--r--drivers/char/viotape.c1
-rw-r--r--drivers/char/vt_ioctl.c5
-rw-r--r--drivers/char/watchdog/pcwd_pci.c1
-rw-r--r--drivers/char/watchdog/wdt_pci.c1
-rw-r--r--drivers/connector/Kconfig8
-rw-r--r--drivers/connector/Makefile1
-rw-r--r--drivers/connector/cn_proc.c222
-rw-r--r--drivers/cpufreq/cpufreq.c27
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c18
-rw-r--r--drivers/cpufreq/cpufreq_stats.c12
-rw-r--r--drivers/dio/dio.c3
-rw-r--r--drivers/eisa/eisa-bus.c8
-rw-r--r--drivers/fc4/fc.c32
-rw-r--r--drivers/fc4/soc.c3
-rw-r--r--drivers/fc4/socal.c3
-rw-r--r--drivers/firmware/dell_rbu.c122
-rw-r--r--drivers/firmware/edd.c3
-rw-r--r--drivers/firmware/efivars.c10
-rw-r--r--drivers/hwmon/hwmon.c1
-rw-r--r--drivers/hwmon/max1619.c14
-rw-r--r--drivers/hwmon/w83627hf.c16
-rw-r--r--drivers/hwmon/w83781d.c6
-rw-r--r--drivers/i2c/busses/i2c-ali1535.c1
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c1
-rw-r--r--drivers/i2c/busses/i2c-ali15x3.c1
-rw-r--r--drivers/i2c/busses/i2c-amd756-s4882.c6
-rw-r--r--drivers/i2c/busses/i2c-amd756.c1
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c1
-rw-r--r--drivers/i2c/busses/i2c-hydra.c1
-rw-r--r--drivers/i2c/busses/i2c-i801.c1
-rw-r--r--drivers/i2c/busses/i2c-i810.c1
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c1
-rw-r--r--drivers/i2c/busses/i2c-piix4.c1
-rw-r--r--drivers/i2c/busses/i2c-prosavage.c1
-rw-r--r--drivers/i2c/busses/i2c-savage4.c1
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c1
-rw-r--r--drivers/i2c/busses/i2c-sis630.c1
-rw-r--r--drivers/i2c/busses/i2c-sis96x.c1
-rw-r--r--drivers/i2c/busses/i2c-via.c1
-rw-r--r--drivers/i2c/busses/i2c-viapro.c28
-rw-r--r--drivers/i2c/busses/i2c-voodoo3.c1
-rw-r--r--drivers/i2c/chips/ds1337.c4
-rw-r--r--drivers/ide/Kconfig9
-rw-r--r--drivers/ide/ide-cd.c22
-rw-r--r--drivers/ide/ide-disk.c4
-rw-r--r--drivers/ide/ide-floppy.c10
-rw-r--r--drivers/ide/ide-iops.c6
-rw-r--r--drivers/ide/ide-probe.c9
-rw-r--r--drivers/ide/ide-tape.c4
-rw-r--r--drivers/ide/ide-taskfile.c20
-rw-r--r--drivers/ide/ide.c7
-rw-r--r--drivers/ide/legacy/ide-cs.c13
-rw-r--r--drivers/ide/pci/Makefile1
-rw-r--r--drivers/ide/pci/amd74xx.c3
-rw-r--r--drivers/ide/pci/cs5535.c305
-rw-r--r--drivers/ide/pci/cy82c693.c2
-rw-r--r--drivers/ide/pci/hpt366.c3
-rw-r--r--drivers/ide/pci/it821x.c3
-rw-r--r--drivers/ide/pci/siimage.c9
-rw-r--r--drivers/ide/ppc/pmac.c9
-rw-r--r--drivers/ide/setup-pci.c12
-rw-r--r--drivers/ieee1394/amdtp.c3
-rw-r--r--drivers/infiniband/core/agent.c3
-rw-r--r--drivers/infiniband/core/mad.c6
-rw-r--r--drivers/infiniband/core/packer.c2
-rw-r--r--drivers/infiniband/core/sysfs.c3
-rw-r--r--drivers/infiniband/core/ud_header.c1
-rw-r--r--drivers/infiniband/core/user_mad.c129
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c12
-rw-r--r--drivers/infiniband/core/verbs.c13
-rw-r--r--drivers/infiniband/hw/mthca/mthca_catas.c5
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cmd.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c16
-rw-r--r--drivers/infiniband/hw/mthca/mthca_dev.h2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c3
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.h1
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c113
-rw-r--r--drivers/infiniband/hw/mthca/mthca_srq.c25
-rw-r--r--drivers/infiniband/hw/mthca/mthca_wqe.h3
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h15
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_fs.c177
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c72
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c26
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c7
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c1
-rw-r--r--drivers/input/input.c29
-rw-r--r--drivers/input/keyboard/lkkbd.c101
-rw-r--r--drivers/input/keyboard/locomokbd.c63
-rw-r--r--drivers/input/misc/uinput.c10
-rw-r--r--drivers/input/mouse/logips2pp.c3
-rw-r--r--drivers/isdn/divert/divert_init.c1
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/divert/isdn_divert.c1
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c5
-rw-r--r--drivers/isdn/hisax/avm_pci.c12
-rw-r--r--drivers/isdn/hisax/avma1_cs.c4
-rw-r--r--drivers/isdn/hisax/config.c9
-rw-r--r--drivers/isdn/hisax/hfc_2bds0.c18
-rw-r--r--drivers/isdn/hisax/hfc_2bs0.c12
-rw-r--r--drivers/isdn/hisax/hfc_usb.c292
-rw-r--r--drivers/isdn/hisax/hfc_usb.h6
-rw-r--r--drivers/isdn/hisax/hisax_fcpcipnp.c1
-rw-r--r--drivers/isdn/hisax/hscx.c12
-rw-r--r--drivers/isdn/hisax/icc.c12
-rw-r--r--drivers/isdn/hisax/ipacx.c12
-rw-r--r--drivers/isdn/hisax/isac.c15
-rw-r--r--drivers/isdn/hisax/isar.c6
-rw-r--r--drivers/isdn/hisax/jade.c12
-rw-r--r--drivers/isdn/hisax/netjet.c32
-rw-r--r--drivers/isdn/hisax/st5481_init.c1
-rw-r--r--drivers/isdn/hisax/st5481_usb.c12
-rw-r--r--drivers/isdn/hisax/w6692.c12
-rw-r--r--drivers/isdn/hysdn/hycapi.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_init.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_net.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c4
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c1
-rw-r--r--drivers/isdn/i4l/isdn_common.c1
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c21
-rw-r--r--drivers/isdn/i4l/isdn_tty.c27
-rw-r--r--drivers/isdn/icn/icn.c3
-rw-r--r--drivers/isdn/icn/icn.h1
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c9
-rw-r--r--drivers/isdn/isdnloop/isdnloop.h1
-rw-r--r--drivers/isdn/pcbit/drv.c6
-rw-r--r--drivers/isdn/sc/includes.h1
-rw-r--r--drivers/isdn/sc/init.c3
-rw-r--r--drivers/isdn/sc/message.c3
-rw-r--r--drivers/macintosh/Kconfig19
-rw-r--r--drivers/macintosh/Makefile9
-rw-r--r--drivers/macintosh/adbhid.c3
-rw-r--r--drivers/macintosh/smu.c174
-rw-r--r--drivers/macintosh/therm_pm72.c3
-rw-r--r--drivers/macintosh/via-pmu.c10
-rw-r--r--drivers/macintosh/windfarm.h131
-rw-r--r--drivers/macintosh/windfarm_core.c426
-rw-r--r--drivers/macintosh/windfarm_cpufreq_clamp.c105
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c263
-rw-r--r--drivers/macintosh/windfarm_pid.c145
-rw-r--r--drivers/macintosh/windfarm_pid.h84
-rw-r--r--drivers/macintosh/windfarm_pm81.c879
-rw-r--r--drivers/macintosh/windfarm_pm91.c814
-rw-r--r--drivers/macintosh/windfarm_smu_controls.c282
-rw-r--r--drivers/macintosh/windfarm_smu_sensors.c479
-rw-r--r--drivers/md/bitmap.c34
-rw-r--r--drivers/md/md.c636
-rw-r--r--drivers/md/multipath.c31
-rw-r--r--drivers/md/raid1.c216
-rw-r--r--drivers/md/raid10.c63
-rw-r--r--drivers/md/raid5.c264
-rw-r--r--drivers/md/raid6main.c43
-rw-r--r--drivers/media/common/ir-common.c4
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c54
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h1
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c1
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig4
-rw-r--r--drivers/media/dvb/bt8xx/dst.c144
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c123
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h5
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c114
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.h1
-rw-r--r--drivers/media/dvb/dvb-core/demux.h5
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c118
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c59
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h5
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c4
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/cx24110.c1
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c54
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c4
-rw-r--r--drivers/media/dvb/frontends/l64781.c3
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c29
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h4
-rw-r--r--drivers/media/dvb/frontends/mt312.c3
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c1205
-rw-r--r--drivers/media/dvb/frontends/nxt200x.h61
-rw-r--r--drivers/media/dvb/frontends/or51132.c10
-rw-r--r--drivers/media/dvb/frontends/or51211.c8
-rw-r--r--drivers/media/dvb/frontends/stv0299.c100
-rw-r--r--drivers/media/dvb/frontends/stv0299.h3
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c21
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c9
-rw-r--r--drivers/media/dvb/ttpci/av7110.c6
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c3
-rw-r--r--drivers/media/dvb/ttpci/budget.c120
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c5
-rw-r--r--drivers/media/video/Kconfig63
-rw-r--r--drivers/media/video/Makefile5
-rw-r--r--drivers/media/video/arv.c13
-rw-r--r--drivers/media/video/bt832.c89
-rw-r--r--drivers/media/video/bt832.h4
-rw-r--r--drivers/media/video/bttv-cards.c5307
-rw-r--r--drivers/media/video/bttv-driver.c385
-rw-r--r--drivers/media/video/bttv-gpio.c2
-rw-r--r--drivers/media/video/bttv-i2c.c61
-rw-r--r--drivers/media/video/bttv-if.c4
-rw-r--r--drivers/media/video/bttv-risc.c110
-rw-r--r--drivers/media/video/bttv.h282
-rw-r--r--drivers/media/video/bttvp.h14
-rw-r--r--drivers/media/video/cs53l32a.c240
-rw-r--r--drivers/media/video/cx88/Kconfig91
-rw-r--r--drivers/media/video/cx88/Makefile6
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c677
-rw-r--r--drivers/media/video/cx88/cx88-cards.c474
-rw-r--r--drivers/media/video/cx88/cx88-core.c55
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c59
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c22
-rw-r--r--drivers/media/video/cx88/cx88-input.c2
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c25
-rw-r--r--drivers/media/video/cx88/cx88-reg.h12
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1184
-rw-r--r--drivers/media/video/cx88/cx88-video.c38
-rw-r--r--drivers/media/video/cx88/cx88.h55
-rw-r--r--drivers/media/video/em28xx/Kconfig12
-rw-r--r--drivers/media/video/em28xx/Makefile6
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c292
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c817
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c586
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c184
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c1933
-rw-r--r--drivers/media/video/em28xx/em28xx.h513
-rw-r--r--drivers/media/video/indycam.c262
-rw-r--r--drivers/media/video/indycam.h88
-rw-r--r--drivers/media/video/ir-kbd-gpio.c99
-rw-r--r--drivers/media/video/ir-kbd-i2c.c166
-rw-r--r--drivers/media/video/msp3400.c966
-rw-r--r--drivers/media/video/mt20xx.c206
-rw-r--r--drivers/media/video/saa6588.c11
-rw-r--r--drivers/media/video/saa711x.c593
-rw-r--r--drivers/media/video/saa7134/Kconfig68
-rw-r--r--drivers/media/video/saa7134/Makefile9
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c187
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c1047
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c587
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c120
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c370
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c28
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c403
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c375
-rw-r--r--drivers/media/video/saa7134/saa7134-reg.h27
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c29
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c27
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c185
-rw-r--r--drivers/media/video/saa7134/saa7134.h62
-rw-r--r--drivers/media/video/saa7191.c533
-rw-r--r--drivers/media/video/saa7191.h172
-rw-r--r--drivers/media/video/tda7432.c17
-rw-r--r--drivers/media/video/tda8290.c681
-rw-r--r--drivers/media/video/tda9875.c57
-rw-r--r--drivers/media/video/tda9887.c163
-rw-r--r--drivers/media/video/tea5767.c8
-rw-r--r--drivers/media/video/tuner-core.c74
-rw-r--r--drivers/media/video/tuner-simple.c143
-rw-r--r--drivers/media/video/tvaudio.c23
-rw-r--r--drivers/media/video/tveeprom.c458
-rw-r--r--drivers/media/video/tvmixer.c54
-rw-r--r--drivers/media/video/tvp5150.c829
-rw-r--r--drivers/media/video/tvp5150_reg.h173
-rw-r--r--drivers/media/video/v4l1-compat.c12
-rw-r--r--drivers/media/video/video-buf.c18
-rw-r--r--drivers/media/video/videocodec.c6
-rw-r--r--drivers/media/video/videodev.c3
-rw-r--r--drivers/media/video/vino.c1170
-rw-r--r--drivers/media/video/wm8775.c254
-rw-r--r--drivers/media/video/zoran_card.c14
-rw-r--r--drivers/media/video/zoran_driver.c4
-rw-r--r--drivers/media/video/zr36016.c1
-rw-r--r--drivers/media/video/zr36050.c1
-rw-r--r--drivers/media/video/zr36060.c1
-rw-r--r--drivers/message/fusion/mptbase.c7
-rw-r--r--drivers/message/fusion/mptbase.h3
-rw-r--r--drivers/message/fusion/mptctl.c1
-rw-r--r--drivers/message/fusion/mptctl.h1
-rw-r--r--drivers/message/fusion/mptlan.c10
-rw-r--r--drivers/message/fusion/mptlan.h1
-rw-r--r--drivers/message/fusion/mptscsih.c6
-rw-r--r--drivers/message/i2o/exec-osm.c1
-rw-r--r--drivers/message/i2o/iop.c15
-rw-r--r--drivers/mfd/mcp-core.c2
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c1
-rw-r--r--drivers/misc/hdpuftrs/hdpu_nexus.c1
-rw-r--r--drivers/misc/ibmasm/ibmasm.h1
-rw-r--r--drivers/mmc/mmc.c2
-rw-r--r--drivers/mmc/wbsd.c3
-rw-r--r--drivers/mtd/Kconfig40
-rw-r--r--drivers/mtd/Makefile5
-rw-r--r--drivers/mtd/afs.c16
-rw-r--r--drivers/mtd/chips/Kconfig22
-rw-r--r--drivers/mtd/chips/Makefile4
-rw-r--r--drivers/mtd/chips/amd_flash.c80
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c487
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c160
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0020.c184
-rw-r--r--drivers/mtd/chips/cfi_probe.c98
-rw-r--r--drivers/mtd/chips/cfi_util.c25
-rw-r--r--drivers/mtd/chips/chipreg.c6
-rw-r--r--drivers/mtd/chips/fwh_lock.h6
-rw-r--r--drivers/mtd/chips/gen_probe.c33
-rw-r--r--drivers/mtd/chips/jedec.c206
-rw-r--r--drivers/mtd/chips/jedec_probe.c48
-rw-r--r--drivers/mtd/chips/map_absent.c8
-rw-r--r--drivers/mtd/chips/sharp.c23
-rw-r--r--drivers/mtd/cmdlinepart.c56
-rw-r--r--drivers/mtd/devices/Kconfig8
-rw-r--r--drivers/mtd/devices/blkmtd.c17
-rw-r--r--drivers/mtd/devices/block2mtd.c8
-rw-r--r--drivers/mtd/devices/doc2000.c42
-rw-r--r--drivers/mtd/devices/doc2001.c24
-rw-r--r--drivers/mtd/devices/doc2001plus.c20
-rw-r--r--drivers/mtd/devices/docecc.c40
-rw-r--r--drivers/mtd/devices/docprobe.c84
-rw-r--r--drivers/mtd/devices/lart.c8
-rw-r--r--drivers/mtd/devices/phram.c14
-rw-r--r--drivers/mtd/devices/pmc551.c25
-rw-r--r--drivers/mtd/devices/slram.c30
-rw-r--r--drivers/mtd/ftl.c128
-rw-r--r--drivers/mtd/inftlcore.c60
-rw-r--r--drivers/mtd/inftlmount.c26
-rw-r--r--drivers/mtd/maps/Kconfig115
-rw-r--r--drivers/mtd/maps/Makefile7
-rw-r--r--drivers/mtd/maps/alchemy-flash.c12
-rw-r--r--drivers/mtd/maps/amd76xrom.c20
-rw-r--r--drivers/mtd/maps/arctic-mtd.c6
-rw-r--r--drivers/mtd/maps/autcpu12-nvram.c18
-rw-r--r--drivers/mtd/maps/bast-flash.c22
-rw-r--r--drivers/mtd/maps/beech-mtd.c6
-rw-r--r--drivers/mtd/maps/cdb89712.c34
-rw-r--r--drivers/mtd/maps/ceiva.c3
-rw-r--r--drivers/mtd/maps/cfi_flagadm.c12
-rw-r--r--drivers/mtd/maps/cstm_mips_ixx.c24
-rw-r--r--drivers/mtd/maps/dbox2-flash.c38
-rw-r--r--drivers/mtd/maps/dc21285.c34
-rw-r--r--drivers/mtd/maps/dilnetpc.c32
-rw-r--r--drivers/mtd/maps/dmv182.c8
-rw-r--r--drivers/mtd/maps/ebony.c7
-rw-r--r--drivers/mtd/maps/edb7312.c10
-rw-r--r--drivers/mtd/maps/epxa10db-flash.c12
-rw-r--r--drivers/mtd/maps/fortunet.c4
-rw-r--r--drivers/mtd/maps/h720x-flash.c16
-rw-r--r--drivers/mtd/maps/ichxrom.c21
-rw-r--r--drivers/mtd/maps/impa7.c16
-rw-r--r--drivers/mtd/maps/integrator-flash.c20
-rw-r--r--drivers/mtd/maps/ipaq-flash.c37
-rw-r--r--drivers/mtd/maps/iq80310.c7
-rw-r--r--drivers/mtd/maps/ixp2000.c35
-rw-r--r--drivers/mtd/maps/ixp4xx.c56
-rw-r--r--drivers/mtd/maps/l440gx.c18
-rw-r--r--drivers/mtd/maps/lubbock-flash.c17
-rw-r--r--drivers/mtd/maps/mainstone-flash.c22
-rw-r--r--drivers/mtd/maps/mbx860.c6
-rw-r--r--drivers/mtd/maps/mtx-1_flash.c96
-rw-r--r--drivers/mtd/maps/netsc520.c32
-rw-r--r--drivers/mtd/maps/nettel.c8
-rw-r--r--drivers/mtd/maps/ocelot.c10
-rw-r--r--drivers/mtd/maps/ocotea.c1
-rw-r--r--drivers/mtd/maps/octagon-5066.c36
-rw-r--r--drivers/mtd/maps/omap-toto-flash.c23
-rw-r--r--drivers/mtd/maps/omap_nor.c2
-rw-r--r--drivers/mtd/maps/pci.c6
-rw-r--r--drivers/mtd/maps/pcmciamtd.c30
-rw-r--r--drivers/mtd/maps/physmap.c8
-rw-r--r--drivers/mtd/maps/plat-ram.c13
-rw-r--r--drivers/mtd/maps/pnc2000.c8
-rw-r--r--drivers/mtd/maps/pq2fads.c88
-rw-r--r--drivers/mtd/maps/redwood.c4
-rw-r--r--drivers/mtd/maps/sa1100-flash.c9
-rw-r--r--drivers/mtd/maps/sbc8240.c4
-rw-r--r--drivers/mtd/maps/sbc_gxx.c46
-rw-r--r--drivers/mtd/maps/sc520cdp.c6
-rw-r--r--drivers/mtd/maps/scx200_docflash.c46
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c12
-rw-r--r--drivers/mtd/maps/solutionengine.c4
-rw-r--r--drivers/mtd/maps/sun_uflash.c16
-rw-r--r--drivers/mtd/maps/tqm834x.c291
-rw-r--r--drivers/mtd/maps/tqm8xxl.c26
-rw-r--r--drivers/mtd/maps/ts5500_flash.c44
-rw-r--r--drivers/mtd/maps/tsunami_flash.c6
-rw-r--r--drivers/mtd/maps/uclinux.c4
-rw-r--r--drivers/mtd/maps/vmax301.c24
-rw-r--r--drivers/mtd/maps/walnut.c17
-rw-r--r--drivers/mtd/maps/wr_sbc82xx_flash.c6
-rw-r--r--drivers/mtd/mtd_blkdevs.c44
-rw-r--r--drivers/mtd/mtdblock.c53
-rw-r--r--drivers/mtd/mtdchar.c86
-rw-r--r--drivers/mtd/mtdconcat.c13
-rw-r--r--drivers/mtd/mtdcore.c62
-rw-r--r--drivers/mtd/mtdpart.c99
-rw-r--r--drivers/mtd/nand/Kconfig26
-rw-r--r--drivers/mtd/nand/au1550nd.c166
-rw-r--r--drivers/mtd/nand/autcpu12.c23
-rw-r--r--drivers/mtd/nand/diskonchip.c100
-rw-r--r--drivers/mtd/nand/edb7312.c48
-rw-r--r--drivers/mtd/nand/h1910.c48
-rw-r--r--drivers/mtd/nand/nand_base.c534
-rw-r--r--drivers/mtd/nand/nand_bbt.c248
-rw-r--r--drivers/mtd/nand/nand_ecc.c44
-rw-r--r--drivers/mtd/nand/nand_ids.c30
-rw-r--r--drivers/mtd/nand/nandsim.c162
-rw-r--r--drivers/mtd/nand/ppchameleonevb.c6
-rw-r--r--drivers/mtd/nand/rtc_from4.c58
-rw-r--r--drivers/mtd/nand/s3c2410.c61
-rw-r--r--drivers/mtd/nand/sharpsl.c41
-rw-r--r--drivers/mtd/nand/spia.c6
-rw-r--r--drivers/mtd/nand/toto.c20
-rw-r--r--drivers/mtd/nftlcore.c92
-rw-r--r--drivers/mtd/nftlmount.c56
-rw-r--r--drivers/mtd/onenand/Kconfig38
-rw-r--r--drivers/mtd/onenand/Makefile11
-rw-r--r--drivers/mtd/onenand/generic.c147
-rw-r--r--drivers/mtd/onenand/onenand_base.c1590
-rw-r--r--drivers/mtd/onenand/onenand_bbt.c246
-rw-r--r--drivers/mtd/redboot.c4
-rw-r--r--drivers/mtd/rfd_ftl.c856
-rw-r--r--drivers/net/3c59x.c586
-rw-r--r--drivers/net/Kconfig15
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/b44.c178
-rw-r--r--drivers/net/b44.h75
-rw-r--r--drivers/net/bnx2.c484
-rw-r--r--drivers/net/bnx2.h119
-rw-r--r--drivers/net/bnx2_fw.h4053
-rw-r--r--drivers/net/bonding/bond_main.c32
-rw-r--r--drivers/net/bonding/bonding.h7
-rw-r--r--drivers/net/cassini.c1
-rw-r--r--drivers/net/cris/eth_v10.c149
-rw-r--r--drivers/net/depca.c24
-rw-r--r--drivers/net/dgrs.c16
-rw-r--r--drivers/net/dm9000.c1
-rw-r--r--drivers/net/e100.c6
-rw-r--r--drivers/net/e1000/e1000_ethtool.c2
-rw-r--r--drivers/net/e1000/e1000_hw.c101
-rw-r--r--drivers/net/e1000/e1000_hw.h42
-rw-r--r--drivers/net/e1000/e1000_main.c31
-rw-r--r--drivers/net/fec.c240
-rw-r--r--drivers/net/fec.h10
-rw-r--r--drivers/net/fec_8xx/Kconfig2
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c1
-rw-r--r--drivers/net/fs_enet/fs_enet.h1
-rw-r--r--drivers/net/fs_enet/mac-fcc.c1
-rw-r--r--drivers/net/fs_enet/mac-fec.c1
-rw-r--r--drivers/net/fs_enet/mac-scc.c1
-rw-r--r--drivers/net/gianfar.c1
-rw-r--r--drivers/net/gianfar.h1
-rw-r--r--drivers/net/gianfar_ethtool.c1
-rw-r--r--drivers/net/gianfar_mii.c1
-rw-r--r--drivers/net/hamradio/dmascc.c10
-rw-r--r--drivers/net/hp100.c1
-rw-r--r--drivers/net/ibmveth.c1
-rw-r--r--drivers/net/ioc3-eth.c42
-rw-r--r--drivers/net/irda/donauboe.c14
-rw-r--r--drivers/net/iseries_veth.c1
-rw-r--r--drivers/net/ixgb/ixgb_ethtool.c2
-rw-r--r--drivers/net/ixgb/ixgb_hw.c31
-rw-r--r--drivers/net/ixgb/ixgb_hw.h17
-rw-r--r--drivers/net/ixgb/ixgb_main.c2
-rw-r--r--drivers/net/jazzsonic.c28
-rw-r--r--drivers/net/mac8390.c1
-rw-r--r--drivers/net/macsonic.c27
-rw-r--r--drivers/net/mv643xx_eth.h1
-rw-r--r--drivers/net/ns83820.c13
-rw-r--r--drivers/net/phy/cicada.c1
-rw-r--r--drivers/net/phy/davicom.c1
-rw-r--r--drivers/net/phy/lxt.c1
-rw-r--r--drivers/net/phy/marvell.c1
-rw-r--r--drivers/net/phy/mdio_bus.c1
-rw-r--r--drivers/net/phy/phy.c1
-rw-r--r--drivers/net/phy/phy_device.c1
-rw-r--r--drivers/net/phy/qsemi.c1
-rw-r--r--drivers/net/ppp_async.c17
-rw-r--r--drivers/net/ppp_generic.c88
-rw-r--r--drivers/net/ppp_mppe.c724
-rw-r--r--drivers/net/ppp_mppe.h86
-rw-r--r--drivers/net/s2io.c54
-rw-r--r--drivers/net/sk98lin/h/skdrv1st.h3
-rw-r--r--drivers/net/sk_mca.c1
-rw-r--r--drivers/net/sk_mca.h2
-rw-r--r--drivers/net/skge.c267
-rw-r--r--drivers/net/skge.h2
-rw-r--r--drivers/net/spider_net.c1
-rw-r--r--drivers/net/starfire.c1
-rw-r--r--drivers/net/via-velocity.c1
-rw-r--r--drivers/net/wireless/airo.c38
-rw-r--r--drivers/net/wireless/airo.h9
-rw-r--r--drivers/net/wireless/airo_cs.c12
-rw-r--r--drivers/net/wireless/atmel.c2
-rw-r--r--drivers/net/wireless/atmel_cs.c6
-rw-r--r--drivers/net/wireless/hostap/hostap.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_plx.c1
-rw-r--r--drivers/net/wireless/ipw2100.c2858
-rw-r--r--drivers/net/wireless/ipw2100.h170
-rw-r--r--drivers/net/wireless/ipw2200.c6610
-rw-r--r--drivers/net/wireless/ipw2200.h575
-rw-r--r--drivers/net/wireless/orinoco.h1
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.c13
-rw-r--r--drivers/net/wireless/prism54/isl_38xx.h1
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.h1
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c12
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c1
-rw-r--r--drivers/net/wireless/wavelan_cs.c3
-rw-r--r--drivers/net/wireless/wl3501_cs.c3
-rw-r--r--drivers/parport/probe.c21
-rw-r--r--drivers/parport/share.c19
-rw-r--r--drivers/pci/access.c2
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c15
-rw-r--r--drivers/pci/hotplug/pciehp.h135
-rw-r--r--drivers/pci/hotplug/pciehp_core.c108
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c1979
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c113
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c840
-rw-r--r--drivers/pci/hotplug/pciehprm.h52
-rw-r--r--drivers/pci/hotplug/pciehprm_acpi.c1727
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.c465
-rw-r--r--drivers/pci/hotplug/pciehprm_nonacpi.h56
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c81
-rw-r--r--drivers/pci/hotplug/rpaphp.h2
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c76
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c2
-rw-r--r--drivers/pci/msi.c20
-rw-r--r--drivers/pci/pci-acpi.c11
-rw-r--r--drivers/pci/pci-driver.c12
-rw-r--r--drivers/pci/pci.c46
-rw-r--r--drivers/pci/quirks.c19
-rw-r--r--drivers/pcmcia/Kconfig2
-rw-r--r--drivers/pcmcia/Makefile6
-rw-r--r--drivers/pcmcia/au1000_db1x00.c1
-rw-r--r--drivers/pcmcia/au1000_generic.h2
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c2
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c2
-rw-r--r--drivers/pcmcia/cistpl.c12
-rw-r--r--drivers/pcmcia/cs.c6
-rw-r--r--drivers/pcmcia/i82365.c1
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c24
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c140
-rw-r--r--drivers/pnp/card.c4
-rw-r--r--drivers/pnp/core.c5
-rw-r--r--drivers/pnp/driver.c2
-rw-r--r--drivers/pnp/isapnp/core.c2
-rw-r--r--drivers/pnp/manager.c2
-rw-r--r--drivers/pnp/pnpacpi/core.c6
-rw-r--r--drivers/pnp/resource.c2
-rw-r--r--drivers/rapidio/Kconfig18
-rw-r--r--drivers/rapidio/Makefile6
-rw-r--r--drivers/rapidio/rio-access.c175
-rw-r--r--drivers/rapidio/rio-driver.c229
-rw-r--r--drivers/rapidio/rio-scan.c945
-rw-r--r--drivers/rapidio/rio-sysfs.c230
-rw-r--r--drivers/rapidio/rio.c510
-rw-r--r--drivers/rapidio/rio.h60
-rw-r--r--drivers/rapidio/switches/Makefile5
-rw-r--r--drivers/rapidio/switches/tsi500.c60
-rw-r--r--drivers/s390/block/dasd.c12
-rw-r--r--drivers/s390/block/dasd_devmap.c3
-rw-r--r--drivers/s390/block/dasd_diag.c64
-rw-r--r--drivers/s390/block/dasd_diag.h10
-rw-r--r--drivers/s390/char/con3215.c3
-rw-r--r--drivers/s390/char/keyboard.c15
-rw-r--r--drivers/s390/char/keyboard.h4
-rw-r--r--drivers/s390/char/raw3270.c3
-rw-r--r--drivers/s390/char/tape_core.c9
-rw-r--r--drivers/s390/char/vmcp.c4
-rw-r--r--drivers/s390/cio/ccwgroup.c6
-rw-r--r--drivers/s390/cio/cmf.c3
-rw-r--r--drivers/s390/cio/device_ops.c6
-rw-r--r--drivers/s390/cio/qdio.c17
-rw-r--r--drivers/s390/cio/qdio.h8
-rw-r--r--drivers/s390/crypto/z90main.c8
-rw-r--r--drivers/s390/net/claw.c37
-rw-r--r--drivers/s390/net/fsm.c3
-rw-r--r--drivers/s390/net/fsm.h6
-rw-r--r--drivers/s390/net/iucv.c12
-rw-r--r--drivers/s390/net/lcs.c3
-rw-r--r--drivers/s390/net/qeth_eddp.c3
-rw-r--r--drivers/s390/s390mach.h2
-rw-r--r--drivers/s390/scsi/zfcp_aux.c3
-rw-r--r--drivers/sbus/char/cpwatchdog.c24
-rw-r--r--drivers/sbus/char/display7seg.c32
-rw-r--r--drivers/sbus/char/envctrl.c31
-rw-r--r--drivers/sbus/char/openprom.c36
-rw-r--r--drivers/sbus/char/rtc.c22
-rw-r--r--drivers/scsi/3w-9xxx.c3
-rw-r--r--drivers/scsi/3w-xxxx.h1
-rw-r--r--drivers/scsi/NCR5380.c5
-rw-r--r--drivers/scsi/a2091.c1
-rw-r--r--drivers/scsi/aacraid/commsup.c14
-rw-r--r--drivers/scsi/aacraid/rkt.c6
-rw-r--r--drivers/scsi/aacraid/rx.c6
-rw-r--r--drivers/scsi/aacraid/sa.c6
-rw-r--r--drivers/scsi/advansys.c12
-rw-r--r--drivers/scsi/aha1542.c36
-rw-r--r--drivers/scsi/ahci.c4
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h1
-rw-r--r--drivers/scsi/aic7xxx_old.c3
-rw-r--r--drivers/scsi/amiga7xx.c1
-rw-r--r--drivers/scsi/arm/queue.c3
-rw-r--r--drivers/scsi/ata_piix.c3
-rw-r--r--drivers/scsi/atari_dma_emul.c2
-rw-r--r--drivers/scsi/bvme6000.c1
-rw-r--r--drivers/scsi/dc395x.c3
-rw-r--r--drivers/scsi/dpt_i2o.c61
-rw-r--r--drivers/scsi/eata.c3
-rw-r--r--drivers/scsi/gvp11.c1
-rw-r--r--drivers/scsi/ibmmca.c6
-rw-r--r--drivers/scsi/ide-scsi.c15
-rw-r--r--drivers/scsi/ips.c18
-rw-r--r--drivers/scsi/ips.h1
-rw-r--r--drivers/scsi/libata-core.c11
-rw-r--r--drivers/scsi/libata-scsi.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c9
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c12
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c7
-rw-r--r--drivers/scsi/megaraid/mega_common.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c5
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.c11
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.h1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c1
-rw-r--r--drivers/scsi/mvme147.c1
-rw-r--r--drivers/scsi/mvme16x.c1
-rw-r--r--drivers/scsi/nsp32.h1
-rw-r--r--drivers/scsi/osst.c9
-rw-r--r--drivers/scsi/pci2000.h3
-rw-r--r--drivers/scsi/pdc_adma.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c16
-rw-r--r--drivers/scsi/raid_class.c2
-rw-r--r--drivers/scsi/sata_mv.c4
-rw-r--r--drivers/scsi/sata_nv.c3
-rw-r--r--drivers/scsi/sata_promise.c4
-rw-r--r--drivers/scsi/sata_qstor.c3
-rw-r--r--drivers/scsi/sata_sil.c3
-rw-r--r--drivers/scsi/sata_sil24.c4
-rw-r--r--drivers/scsi/sata_sis.c3
-rw-r--r--drivers/scsi/sata_svw.c3
-rw-r--r--drivers/scsi/sata_sx4.c4
-rw-r--r--drivers/scsi/sata_uli.c3
-rw-r--r--drivers/scsi/sata_via.c3
-rw-r--r--drivers/scsi/sata_vsc.c3
-rw-r--r--drivers/scsi/scsi_debug.c4
-rw-r--r--drivers/scsi/scsi_transport_sas.c2
-rw-r--r--drivers/scsi/sg.c13
-rw-r--r--drivers/scsi/sgiwd93.c1
-rw-r--r--drivers/scsi/st.c3
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c1
-rw-r--r--drivers/scsi/u14-34f.c9
-rw-r--r--drivers/scsi/wd33c93.c1
-rw-r--r--drivers/serial/8250.c76
-rw-r--r--drivers/serial/8250.h1
-rw-r--r--drivers/serial/8250_au1x00.c102
-rw-r--r--drivers/serial/Kconfig8
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/crisv10.c9
-rw-r--r--drivers/serial/mcfserial.c37
-rw-r--r--drivers/serial/serial_core.c1
-rw-r--r--drivers/serial/sunsu.c2
-rw-r--r--drivers/sh/superhyway/superhyway-sysfs.c2
-rw-r--r--drivers/sh/superhyway/superhyway.c75
-rw-r--r--drivers/tc/.gitignore1
-rw-r--r--drivers/telephony/ixj.h1
-rw-r--r--drivers/usb/gadget/dummy_hcd.c1
-rw-r--r--drivers/usb/gadget/goku_udc.c1
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.h1
-rw-r--r--drivers/usb/gadget/net2280.c1
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c1
-rw-r--r--drivers/usb/gadget/rndis.c1
-rw-r--r--drivers/usb/host/ehci-pci.c1
-rw-r--r--drivers/usb/host/hc_crisv10.c1
-rw-r--r--drivers/usb/host/ohci-pci.c1
-rw-r--r--drivers/usb/host/uhci-hcd.c1
-rw-r--r--drivers/usb/media/pwc/pwc-if.c1
-rw-r--r--drivers/usb/media/pwc/pwc.h2
-rw-r--r--drivers/usb/media/w9968cf.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.h1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.c1
-rw-r--r--drivers/video/68328fb.c1
-rw-r--r--drivers/video/Kconfig182
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/acornfb.c1
-rw-r--r--drivers/video/amba-clcd.c3
-rw-r--r--drivers/video/amifb.c1
-rw-r--r--drivers/video/arcfb.c26
-rw-r--r--drivers/video/asiliantfb.c1
-rw-r--r--drivers/video/aty/ati_ids.h1
-rw-r--r--drivers/video/aty/aty128fb.c1
-rw-r--r--drivers/video/aty/atyfb_base.c59
-rw-r--r--drivers/video/aty/radeon_base.c3
-rw-r--r--drivers/video/aty/radeonfb.h3
-rw-r--r--drivers/video/backlight/backlight.c1
-rw-r--r--drivers/video/backlight/corgi_bl.c6
-rw-r--r--drivers/video/backlight/lcd.c1
-rw-r--r--drivers/video/bw2.c1
-rw-r--r--drivers/video/cfbcopyarea.c36
-rw-r--r--drivers/video/cfbfillrect.c24
-rw-r--r--drivers/video/cfbimgblt.c26
-rw-r--r--drivers/video/cg14.c1
-rw-r--r--drivers/video/cg3.c1
-rw-r--r--drivers/video/cg6.c7
-rw-r--r--drivers/video/chipsfb.c1
-rw-r--r--drivers/video/cirrusfb.c1
-rw-r--r--drivers/video/clps711xfb.c1
-rw-r--r--drivers/video/console/Kconfig19
-rw-r--r--drivers/video/console/Makefile7
-rw-r--r--drivers/video/console/bitblit.c53
-rw-r--r--drivers/video/console/fbcon.c487
-rw-r--r--drivers/video/console/fbcon.h62
-rw-r--r--drivers/video/console/fbcon_ccw.c428
-rw-r--r--drivers/video/console/fbcon_cw.c412
-rw-r--r--drivers/video/console/fbcon_rotate.c117
-rw-r--r--drivers/video/console/fbcon_rotate.h105
-rw-r--r--drivers/video/console/fbcon_ud.c454
-rw-r--r--drivers/video/console/font_rl.c4374
-rw-r--r--drivers/video/console/fonts.c4
-rw-r--r--drivers/video/console/softcursor.c (renamed from drivers/video/softcursor.c)8
-rw-r--r--drivers/video/console/tileblit.c13
-rw-r--r--drivers/video/console/vgacon.c3
-rw-r--r--drivers/video/controlfb.c1
-rw-r--r--drivers/video/cyber2000fb.c1
-rw-r--r--drivers/video/cyblafb.c1
-rw-r--r--drivers/video/dnfb.c1
-rw-r--r--drivers/video/epson1355fb.c1
-rw-r--r--drivers/video/fbmem.c299
-rw-r--r--drivers/video/fbmon.c48
-rw-r--r--drivers/video/fbsysfs.c67
-rw-r--r--drivers/video/ffb.c3
-rw-r--r--drivers/video/fm2fb.c1
-rw-r--r--drivers/video/gbefb.c19
-rw-r--r--drivers/video/geode/Kconfig1
-rw-r--r--drivers/video/geode/gx1fb_core.c1
-rw-r--r--drivers/video/hitfb.c1
-rw-r--r--drivers/video/hpfb.c1
-rw-r--r--drivers/video/i810/i810-i2c.c135
-rw-r--r--drivers/video/i810/i810.h3
-rw-r--r--drivers/video/i810/i810_main.c22
-rw-r--r--drivers/video/i810/i810_regs.h1
-rw-r--r--drivers/video/imsttfb.c1
-rw-r--r--drivers/video/imxfb.c1
-rw-r--r--drivers/video/intelfb/intelfb.h6
-rw-r--r--drivers/video/intelfb/intelfbdrv.c11
-rw-r--r--drivers/video/intelfb/intelfbhw.c6
-rw-r--r--drivers/video/kyro/fbdev.c1
-rw-r--r--drivers/video/leo.c1
-rw-r--r--drivers/video/logo/Kconfig2
-rw-r--r--drivers/video/macfb.c1
-rw-r--r--drivers/video/matrox/matroxfb_DAC1064.c4
-rw-r--r--drivers/video/matrox/matroxfb_accel.c2
-rw-r--r--drivers/video/matrox/matroxfb_base.c29
-rw-r--r--drivers/video/matrox/matroxfb_base.h5
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c1
-rw-r--r--drivers/video/maxinefb.c1
-rw-r--r--drivers/video/modedb.c88
-rw-r--r--drivers/video/neofb.c1
-rw-r--r--drivers/video/nvidia/nv_local.h2
-rw-r--r--drivers/video/nvidia/nv_of.c64
-rw-r--r--drivers/video/nvidia/nv_proto.h18
-rw-r--r--drivers/video/nvidia/nv_setup.c16
-rw-r--r--drivers/video/nvidia/nvidia.c128
-rw-r--r--drivers/video/offb.c1
-rw-r--r--drivers/video/p9100.c1
-rw-r--r--drivers/video/platinumfb.c1
-rw-r--r--drivers/video/pm2fb.c17
-rw-r--r--drivers/video/pmag-ba-fb.c1
-rw-r--r--drivers/video/pmagb-b-fb.c1
-rw-r--r--drivers/video/pvr2fb.c1
-rw-r--r--drivers/video/pxafb.c1
-rw-r--r--drivers/video/q40fb.c1
-rw-r--r--drivers/video/radeonfb.c1
-rw-r--r--drivers/video/s1d13xxxfb.c1
-rw-r--r--drivers/video/s3c2410fb.c2
-rw-r--r--drivers/video/sa1100fb.c1
-rw-r--r--drivers/video/savage/savagefb.h206
-rw-r--r--drivers/video/savage/savagefb_driver.c850
-rw-r--r--drivers/video/sgivwfb.c25
-rw-r--r--drivers/video/sis/sis_main.c2
-rw-r--r--drivers/video/skeletonfb.c9
-rw-r--r--drivers/video/sstfb.c1
-rw-r--r--drivers/video/stifb.c1
-rw-r--r--drivers/video/tcx.c1
-rw-r--r--drivers/video/tdfxfb.c1
-rw-r--r--drivers/video/tgafb.c1
-rw-r--r--drivers/video/tridentfb.c1
-rw-r--r--drivers/video/tx3912fb.c1
-rw-r--r--drivers/video/valkyriefb.c1
-rw-r--r--drivers/video/vesafb.c59
-rw-r--r--drivers/video/vfb.c1
-rw-r--r--drivers/video/vga16fb.c170
-rw-r--r--drivers/video/vgastate.c5
-rw-r--r--drivers/video/w100fb.c1
-rw-r--r--drivers/w1/w1_ds2433.c6
889 files changed, 57780 insertions, 35580 deletions
diff --git a/drivers/Makefile b/drivers/Makefile
index 65670be6ff1a..fac1e1603097 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -7,6 +7,7 @@
7 7
8obj-$(CONFIG_PCI) += pci/ usb/ 8obj-$(CONFIG_PCI) += pci/ usb/
9obj-$(CONFIG_PARISC) += parisc/ 9obj-$(CONFIG_PARISC) += parisc/
10obj-$(CONFIG_RAPIDIO) += rapidio/
10obj-y += video/ 11obj-y += video/
11obj-$(CONFIG_ACPI) += acpi/ 12obj-$(CONFIG_ACPI) += acpi/
12# PnP must come after ACPI since it will eventually need to check if acpi 13# PnP must come after ACPI since it will eventually need to check if acpi
@@ -67,3 +68,4 @@ obj-$(CONFIG_INFINIBAND) += infiniband/
67obj-$(CONFIG_SGI_IOC4) += sn/ 68obj-$(CONFIG_SGI_IOC4) += sn/
68obj-y += firmware/ 69obj-y += firmware/
69obj-$(CONFIG_CRYPTO) += crypto/ 70obj-$(CONFIG_CRYPTO) += crypto/
71obj-$(CONFIG_SUPERH) += sh/
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 10dd695a1dd9..27ec12c1fab0 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -118,11 +118,9 @@ static int acpi_container_remove(struct acpi_device *device, int type)
118{ 118{
119 acpi_status status = AE_OK; 119 acpi_status status = AE_OK;
120 struct acpi_container *pc = NULL; 120 struct acpi_container *pc = NULL;
121 pc = (struct acpi_container *)acpi_driver_data(device);
122
123 if (pc)
124 kfree(pc);
125 121
122 pc = (struct acpi_container *)acpi_driver_data(device);
123 kfree(pc);
126 return status; 124 return status;
127} 125}
128 126
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 3937adf4e5e5..aa993715d644 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -203,6 +203,7 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
203 acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL); 203 acpi_get_devices(PCI_ROOT_HID_STRING, find_pci_rootbridge, &find, NULL);
204 return find.handle; 204 return find.handle;
205} 205}
206EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
206 207
207/* Get device's handler per its address under its parent */ 208/* Get device's handler per its address under its parent */
208struct acpi_find_child { 209struct acpi_find_child {
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d528c750a380..e3cd0b16031a 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -313,8 +313,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
313 313
314void acpi_os_sleep(acpi_integer ms) 314void acpi_os_sleep(acpi_integer ms)
315{ 315{
316 current->state = TASK_INTERRUPTIBLE; 316 schedule_timeout_interruptible(msecs_to_jiffies(ms));
317 schedule_timeout(((signed long)ms * HZ) / 1000);
318} 317}
319 318
320EXPORT_SYMBOL(acpi_os_sleep); 319EXPORT_SYMBOL(acpi_os_sleep);
@@ -838,8 +837,7 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
838 837
839 ret = down_trylock(sem); 838 ret = down_trylock(sem);
840 for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) { 839 for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
841 current->state = TASK_INTERRUPTIBLE; 840 schedule_timeout_interruptible(1);
842 schedule_timeout(1);
843 ret = down_trylock(sem); 841 ret = down_trylock(sem);
844 } 842 }
845 843
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 161db4acfb91..573b6a97bb1f 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -167,6 +167,19 @@ acpi_processor_power_activate(struct acpi_processor *pr,
167 return; 167 return;
168} 168}
169 169
170static void acpi_safe_halt(void)
171{
172 int polling = test_thread_flag(TIF_POLLING_NRFLAG);
173 if (polling) {
174 clear_thread_flag(TIF_POLLING_NRFLAG);
175 smp_mb__after_clear_bit();
176 }
177 if (!need_resched())
178 safe_halt();
179 if (polling)
180 set_thread_flag(TIF_POLLING_NRFLAG);
181}
182
170static atomic_t c3_cpu_count; 183static atomic_t c3_cpu_count;
171 184
172static void acpi_processor_idle(void) 185static void acpi_processor_idle(void)
@@ -177,7 +190,7 @@ static void acpi_processor_idle(void)
177 int sleep_ticks = 0; 190 int sleep_ticks = 0;
178 u32 t1, t2 = 0; 191 u32 t1, t2 = 0;
179 192
180 pr = processors[raw_smp_processor_id()]; 193 pr = processors[smp_processor_id()];
181 if (!pr) 194 if (!pr)
182 return; 195 return;
183 196
@@ -197,8 +210,13 @@ static void acpi_processor_idle(void)
197 } 210 }
198 211
199 cx = pr->power.state; 212 cx = pr->power.state;
200 if (!cx) 213 if (!cx) {
201 goto easy_out; 214 if (pm_idle_save)
215 pm_idle_save();
216 else
217 acpi_safe_halt();
218 return;
219 }
202 220
203 /* 221 /*
204 * Check BM Activity 222 * Check BM Activity
@@ -278,7 +296,8 @@ static void acpi_processor_idle(void)
278 if (pm_idle_save) 296 if (pm_idle_save)
279 pm_idle_save(); 297 pm_idle_save();
280 else 298 else
281 safe_halt(); 299 acpi_safe_halt();
300
282 /* 301 /*
283 * TBD: Can't get time duration while in C1, as resumes 302 * TBD: Can't get time duration while in C1, as resumes
284 * go to an ISR rather than here. Need to instrument 303 * go to an ISR rather than here. Need to instrument
@@ -414,16 +433,6 @@ static void acpi_processor_idle(void)
414 */ 433 */
415 if (next_state != pr->power.state) 434 if (next_state != pr->power.state)
416 acpi_processor_power_activate(pr, next_state); 435 acpi_processor_power_activate(pr, next_state);
417
418 return;
419
420 easy_out:
421 /* do C1 instead of busy loop */
422 if (pm_idle_save)
423 pm_idle_save();
424 else
425 safe_halt();
426 return;
427} 436}
428 437
429static int acpi_processor_set_power_policy(struct acpi_processor *pr) 438static int acpi_processor_set_power_policy(struct acpi_processor *pr)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c6db591479de..23e2c6968a11 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -28,8 +28,7 @@ static int acpi_bus_trim(struct acpi_device *start, int rmdevice);
28static void acpi_device_release(struct kobject *kobj) 28static void acpi_device_release(struct kobject *kobj)
29{ 29{
30 struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj); 30 struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj);
31 if (dev->pnp.cid_list) 31 kfree(dev->pnp.cid_list);
32 kfree(dev->pnp.cid_list);
33 kfree(dev); 32 kfree(dev);
34} 33}
35 34
@@ -1117,8 +1116,7 @@ acpi_add_single_object(struct acpi_device **child,
1117 if (!result) 1116 if (!result)
1118 *child = device; 1117 *child = device;
1119 else { 1118 else {
1120 if (device->pnp.cid_list) 1119 kfree(device->pnp.cid_list);
1121 kfree(device->pnp.cid_list);
1122 kfree(device); 1120 kfree(device);
1123 } 1121 }
1124 1122
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index e383d6109ae1..f051b151580d 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -334,8 +334,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
334 return_VALUE(0); 334 return_VALUE(0);
335 335
336 err: 336 err:
337 if (buffer.pointer) 337 kfree(buffer.pointer);
338 kfree(buffer.pointer);
339 338
340 return_VALUE(status); 339 return_VALUE(status);
341} 340}
@@ -1488,8 +1487,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
1488 } 1487 }
1489 active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END; 1488 active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
1490 1489
1491 if (video->attached_array) 1490 kfree(video->attached_array);
1492 kfree(video->attached_array);
1493 1491
1494 video->attached_array = active_device_list; 1492 video->attached_array = active_device_list;
1495 video->attached_count = count; 1493 video->attached_count = count;
@@ -1645,8 +1643,7 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1645 printk(KERN_WARNING PREFIX 1643 printk(KERN_WARNING PREFIX
1646 "hhuuhhuu bug in acpi video driver.\n"); 1644 "hhuuhhuu bug in acpi video driver.\n");
1647 1645
1648 if (data->brightness) 1646 kfree(data->brightness);
1649 kfree(data->brightness);
1650 1647
1651 kfree(data); 1648 kfree(data);
1652 } 1649 }
@@ -1831,8 +1828,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
1831 acpi_video_bus_put_devices(video); 1828 acpi_video_bus_put_devices(video);
1832 acpi_video_bus_remove_fs(device); 1829 acpi_video_bus_remove_fs(device);
1833 1830
1834 if (video->attached_array) 1831 kfree(video->attached_array);
1835 kfree(video->attached_array);
1836 kfree(video); 1832 kfree(video);
1837 1833
1838 return_VALUE(0); 1834 return_VALUE(0);
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 0cded0468003..821c81e8cd38 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -1511,8 +1511,8 @@ static inline short setup_idle_tx_channel (hrz_dev * dev, hrz_vcc * vcc) {
1511 // a.k.a. prepare the channel and remember that we have done so. 1511 // a.k.a. prepare the channel and remember that we have done so.
1512 1512
1513 tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel]; 1513 tx_ch_desc * tx_desc = &memmap->tx_descs[tx_channel];
1514 u16 rd_ptr; 1514 u32 rd_ptr;
1515 u16 wr_ptr; 1515 u32 wr_ptr;
1516 u16 channel = vcc->channel; 1516 u16 channel = vcc->channel;
1517 1517
1518 unsigned long flags; 1518 unsigned long flags;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index d597c922af11..6d4736e89f1a 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -116,12 +116,115 @@ int platform_add_devices(struct platform_device **devs, int num)
116 return ret; 116 return ret;
117} 117}
118 118
119struct platform_object {
120 struct platform_device pdev;
121 char name[1];
122};
123
119/** 124/**
120 * platform_device_register - add a platform-level device 125 * platform_device_put
126 * @pdev: platform device to free
127 *
128 * Free all memory associated with a platform device. This function
129 * must _only_ be externally called in error cases. All other usage
130 * is a bug.
131 */
132void platform_device_put(struct platform_device *pdev)
133{
134 if (pdev)
135 put_device(&pdev->dev);
136}
137EXPORT_SYMBOL_GPL(platform_device_put);
138
139static void platform_device_release(struct device *dev)
140{
141 struct platform_object *pa = container_of(dev, struct platform_object, pdev.dev);
142
143 kfree(pa->pdev.dev.platform_data);
144 kfree(pa->pdev.resource);
145 kfree(pa);
146}
147
148/**
149 * platform_device_alloc
150 * @name: base name of the device we're adding
151 * @id: instance id
152 *
153 * Create a platform device object which can have other objects attached
154 * to it, and which will have attached objects freed when it is released.
155 */
156struct platform_device *platform_device_alloc(const char *name, unsigned int id)
157{
158 struct platform_object *pa;
159
160 pa = kzalloc(sizeof(struct platform_object) + strlen(name), GFP_KERNEL);
161 if (pa) {
162 strcpy(pa->name, name);
163 pa->pdev.name = pa->name;
164 pa->pdev.id = id;
165 device_initialize(&pa->pdev.dev);
166 pa->pdev.dev.release = platform_device_release;
167 }
168
169 return pa ? &pa->pdev : NULL;
170}
171EXPORT_SYMBOL_GPL(platform_device_alloc);
172
173/**
174 * platform_device_add_resources
175 * @pdev: platform device allocated by platform_device_alloc to add resources to
176 * @res: set of resources that needs to be allocated for the device
177 * @num: number of resources
178 *
179 * Add a copy of the resources to the platform device. The memory
180 * associated with the resources will be freed when the platform
181 * device is released.
182 */
183int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num)
184{
185 struct resource *r;
186
187 r = kmalloc(sizeof(struct resource) * num, GFP_KERNEL);
188 if (r) {
189 memcpy(r, res, sizeof(struct resource) * num);
190 pdev->resource = r;
191 pdev->num_resources = num;
192 }
193 return r ? 0 : -ENOMEM;
194}
195EXPORT_SYMBOL_GPL(platform_device_add_resources);
196
197/**
198 * platform_device_add_data
199 * @pdev: platform device allocated by platform_device_alloc to add resources to
200 * @data: platform specific data for this platform device
201 * @size: size of platform specific data
202 *
203 * Add a copy of platform specific data to the platform device's platform_data
204 * pointer. The memory associated with the platform data will be freed
205 * when the platform device is released.
206 */
207int platform_device_add_data(struct platform_device *pdev, void *data, size_t size)
208{
209 void *d;
210
211 d = kmalloc(size, GFP_KERNEL);
212 if (d) {
213 memcpy(d, data, size);
214 pdev->dev.platform_data = d;
215 }
216 return d ? 0 : -ENOMEM;
217}
218EXPORT_SYMBOL_GPL(platform_device_add_data);
219
220/**
221 * platform_device_add - add a platform device to device hierarchy
121 * @pdev: platform device we're adding 222 * @pdev: platform device we're adding
122 * 223 *
224 * This is part 2 of platform_device_register(), though may be called
225 * separately _iff_ pdev was allocated by platform_device_alloc().
123 */ 226 */
124int platform_device_register(struct platform_device * pdev) 227int platform_device_add(struct platform_device *pdev)
125{ 228{
126 int i, ret = 0; 229 int i, ret = 0;
127 230
@@ -174,6 +277,18 @@ int platform_device_register(struct platform_device * pdev)
174 release_resource(&pdev->resource[i]); 277 release_resource(&pdev->resource[i]);
175 return ret; 278 return ret;
176} 279}
280EXPORT_SYMBOL_GPL(platform_device_add);
281
282/**
283 * platform_device_register - add a platform-level device
284 * @pdev: platform device we're adding
285 *
286 */
287int platform_device_register(struct platform_device * pdev)
288{
289 device_initialize(&pdev->dev);
290 return platform_device_add(pdev);
291}
177 292
178/** 293/**
179 * platform_device_unregister - remove a platform-level device 294 * platform_device_unregister - remove a platform-level device
@@ -197,18 +312,6 @@ void platform_device_unregister(struct platform_device * pdev)
197 } 312 }
198} 313}
199 314
200struct platform_object {
201 struct platform_device pdev;
202 struct resource resources[0];
203};
204
205static void platform_device_release_simple(struct device *dev)
206{
207 struct platform_device *pdev = to_platform_device(dev);
208
209 kfree(container_of(pdev, struct platform_object, pdev));
210}
211
212/** 315/**
213 * platform_device_register_simple 316 * platform_device_register_simple
214 * @name: base name of the device we're adding 317 * @name: base name of the device we're adding
@@ -225,33 +328,29 @@ static void platform_device_release_simple(struct device *dev)
225struct platform_device *platform_device_register_simple(char *name, unsigned int id, 328struct platform_device *platform_device_register_simple(char *name, unsigned int id,
226 struct resource *res, unsigned int num) 329 struct resource *res, unsigned int num)
227{ 330{
228 struct platform_object *pobj; 331 struct platform_device *pdev;
229 int retval; 332 int retval;
230 333
231 pobj = kzalloc(sizeof(*pobj) + sizeof(struct resource) * num, GFP_KERNEL); 334 pdev = platform_device_alloc(name, id);
232 if (!pobj) { 335 if (!pdev) {
233 retval = -ENOMEM; 336 retval = -ENOMEM;
234 goto error; 337 goto error;
235 } 338 }
236 339
237 pobj->pdev.name = name;
238 pobj->pdev.id = id;
239 pobj->pdev.dev.release = platform_device_release_simple;
240
241 if (num) { 340 if (num) {
242 memcpy(pobj->resources, res, sizeof(struct resource) * num); 341 retval = platform_device_add_resources(pdev, res, num);
243 pobj->pdev.resource = pobj->resources; 342 if (retval)
244 pobj->pdev.num_resources = num; 343 goto error;
245 } 344 }
246 345
247 retval = platform_device_register(&pobj->pdev); 346 retval = platform_device_add(pdev);
248 if (retval) 347 if (retval)
249 goto error; 348 goto error;
250 349
251 return &pobj->pdev; 350 return pdev;
252 351
253error: 352error:
254 kfree(pobj); 353 platform_device_put(pdev);
255 return ERR_PTR(retval); 354 return ERR_PTR(retval);
256} 355}
257 356
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 89c57875f3e5..f3a0c562bcb5 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -3,6 +3,7 @@
3 */ 3 */
4 4
5#include <linux/device.h> 5#include <linux/device.h>
6#include <linux/string.h>
6#include "power.h" 7#include "power.h"
7 8
8 9
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 3760edfdc65c..70eaa5c7ac08 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -417,14 +417,12 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
417 * Remember the beginning of the group, but don't free it 417 * Remember the beginning of the group, but don't free it
418 * until we've reached the beginning of the next group. 418 * until we've reached the beginning of the next group.
419 */ 419 */
420 if (CommandGroup != NULL) 420 kfree(CommandGroup);
421 kfree(CommandGroup); 421 CommandGroup = Command;
422 CommandGroup = Command;
423 } 422 }
424 Controller->Commands[i] = NULL; 423 Controller->Commands[i] = NULL;
425 } 424 }
426 if (CommandGroup != NULL) 425 kfree(CommandGroup);
427 kfree(CommandGroup);
428 426
429 if (Controller->CombinedStatusBuffer != NULL) 427 if (Controller->CombinedStatusBuffer != NULL)
430 { 428 {
@@ -435,30 +433,23 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
435 433
436 if (ScatterGatherPool != NULL) 434 if (ScatterGatherPool != NULL)
437 pci_pool_destroy(ScatterGatherPool); 435 pci_pool_destroy(ScatterGatherPool);
438 if (Controller->FirmwareType == DAC960_V1_Controller) return; 436 if (Controller->FirmwareType == DAC960_V1_Controller)
437 return;
439 438
440 if (RequestSensePool != NULL) 439 if (RequestSensePool != NULL)
441 pci_pool_destroy(RequestSensePool); 440 pci_pool_destroy(RequestSensePool);
442 441
443 for (i = 0; i < DAC960_MaxLogicalDrives; i++) 442 for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
444 if (Controller->V2.LogicalDeviceInformation[i] != NULL)
445 {
446 kfree(Controller->V2.LogicalDeviceInformation[i]); 443 kfree(Controller->V2.LogicalDeviceInformation[i]);
447 Controller->V2.LogicalDeviceInformation[i] = NULL; 444 Controller->V2.LogicalDeviceInformation[i] = NULL;
448 } 445 }
449 446
450 for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++) 447 for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
451 { 448 {
452 if (Controller->V2.PhysicalDeviceInformation[i] != NULL) 449 kfree(Controller->V2.PhysicalDeviceInformation[i]);
453 { 450 Controller->V2.PhysicalDeviceInformation[i] = NULL;
454 kfree(Controller->V2.PhysicalDeviceInformation[i]); 451 kfree(Controller->V2.InquiryUnitSerialNumber[i]);
455 Controller->V2.PhysicalDeviceInformation[i] = NULL; 452 Controller->V2.InquiryUnitSerialNumber[i] = NULL;
456 }
457 if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)
458 {
459 kfree(Controller->V2.InquiryUnitSerialNumber[i]);
460 Controller->V2.InquiryUnitSerialNumber[i] = NULL;
461 }
462 } 453 }
463} 454}
464 455
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 51b0af1cebee..7b1cd93892be 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -409,16 +409,6 @@ config BLK_DEV_INITRD
409 for details. 409 for details.
410 410
411 411
412#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64
413#for instance.
414config LBD
415 bool "Support for Large Block Devices"
416 depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML
417 help
418 Say Y here if you want to attach large (bigger than 2TB) discs to
419 your machine, or if you want to have a raid or loopback device
420 bigger than 2TB. Otherwise say N.
421
422config CDROM_PKTCDVD 412config CDROM_PKTCDVD
423 tristate "Packet writing on CD/DVD media" 413 tristate "Packet writing on CD/DVD media"
424 depends on !UML 414 depends on !UML
@@ -455,8 +445,6 @@ config CDROM_PKTCDVD_WCACHE
455 445
456source "drivers/s390/block/Kconfig" 446source "drivers/s390/block/Kconfig"
457 447
458source "drivers/block/Kconfig.iosched"
459
460config ATA_OVER_ETH 448config ATA_OVER_ETH
461 tristate "ATA over Ethernet support" 449 tristate "ATA over Ethernet support"
462 depends on NET 450 depends on NET
diff --git a/drivers/block/Kconfig.iosched b/drivers/block/Kconfig.iosched
deleted file mode 100644
index 5b90d2fa63b8..000000000000
--- a/drivers/block/Kconfig.iosched
+++ /dev/null
@@ -1,69 +0,0 @@
1
2menu "IO Schedulers"
3
4config IOSCHED_NOOP
5 bool
6 default y
7 ---help---
8 The no-op I/O scheduler is a minimal scheduler that does basic merging
9 and sorting. Its main uses include non-disk based block devices like
10 memory devices, and specialised software or hardware environments
11 that do their own scheduling and require only minimal assistance from
12 the kernel.
13
14config IOSCHED_AS
15 tristate "Anticipatory I/O scheduler"
16 default y
17 ---help---
18 The anticipatory I/O scheduler is the default disk scheduler. It is
19 generally a good choice for most environments, but is quite large and
20 complex when compared to the deadline I/O scheduler, it can also be
21 slower in some cases especially some database loads.
22
23config IOSCHED_DEADLINE
24 tristate "Deadline I/O scheduler"
25 default y
26 ---help---
27 The deadline I/O scheduler is simple and compact, and is often as
28 good as the anticipatory I/O scheduler, and in some database
29 workloads, better. In the case of a single process performing I/O to
30 a disk at any one time, its behaviour is almost identical to the
31 anticipatory I/O scheduler and so is a good choice.
32
33config IOSCHED_CFQ
34 tristate "CFQ I/O scheduler"
35 default y
36 ---help---
37 The CFQ I/O scheduler tries to distribute bandwidth equally
38 among all processes in the system. It should provide a fair
39 working environment, suitable for desktop systems.
40
41choice
42 prompt "Default I/O scheduler"
43 default DEFAULT_AS
44 help
45 Select the I/O scheduler which will be used by default for all
46 block devices.
47
48 config DEFAULT_AS
49 bool "Anticipatory" if IOSCHED_AS
50
51 config DEFAULT_DEADLINE
52 bool "Deadline" if IOSCHED_DEADLINE
53
54 config DEFAULT_CFQ
55 bool "CFQ" if IOSCHED_CFQ
56
57 config DEFAULT_NOOP
58 bool "No-op"
59
60endchoice
61
62config DEFAULT_IOSCHED
63 string
64 default "anticipatory" if DEFAULT_AS
65 default "deadline" if DEFAULT_DEADLINE
66 default "cfq" if DEFAULT_CFQ
67 default "noop" if DEFAULT_NOOP
68
69endmenu
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 1cf09a1c065b..3ec1f8df87b1 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -4,21 +4,7 @@
4# 12 June 2000, Christoph Hellwig <hch@infradead.org> 4# 12 June 2000, Christoph Hellwig <hch@infradead.org>
5# Rewritten to use lists instead of if-statements. 5# Rewritten to use lists instead of if-statements.
6# 6#
7# Note : at this point, these files are compiled on all systems.
8# In the future, some of these should be built conditionally.
9#
10
11#
12# NOTE that ll_rw_blk.c must come early in linkage order - it starts the
13# kblockd threads
14#
15
16obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o
17 7
18obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
19obj-$(CONFIG_IOSCHED_AS) += as-iosched.o
20obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
21obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
22obj-$(CONFIG_MAC_FLOPPY) += swim3.o 8obj-$(CONFIG_MAC_FLOPPY) += swim3.o
23obj-$(CONFIG_BLK_DEV_FD) += floppy.o 9obj-$(CONFIG_BLK_DEV_FD) += floppy.o
24obj-$(CONFIG_BLK_DEV_FD98) += floppy98.o 10obj-$(CONFIG_BLK_DEV_FD98) += floppy98.o
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 1468e8cf712d..0acbfff8ad28 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1816,7 +1816,6 @@ out_blkdev:
1816} 1816}
1817 1817
1818#ifdef MODULE 1818#ifdef MODULE
1819#include <linux/version.h>
1820 1819
1821int init_module(void) 1820int init_module(void)
1822{ 1821{
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
deleted file mode 100644
index c6744ff38294..000000000000
--- a/drivers/block/as-iosched.c
+++ /dev/null
@@ -1,1985 +0,0 @@
1/*
2 * linux/drivers/block/as-iosched.c
3 *
4 * Anticipatory & deadline i/o scheduler.
5 *
6 * Copyright (C) 2002 Jens Axboe <axboe@suse.de>
7 * Nick Piggin <piggin@cyberone.com.au>
8 *
9 */
10#include <linux/kernel.h>
11#include <linux/fs.h>
12#include <linux/blkdev.h>
13#include <linux/elevator.h>
14#include <linux/bio.h>
15#include <linux/config.h>
16#include <linux/module.h>
17#include <linux/slab.h>
18#include <linux/init.h>
19#include <linux/compiler.h>
20#include <linux/hash.h>
21#include <linux/rbtree.h>
22#include <linux/interrupt.h>
23
24#define REQ_SYNC 1
25#define REQ_ASYNC 0
26
27/*
28 * See Documentation/block/as-iosched.txt
29 */
30
31/*
32 * max time before a read is submitted.
33 */
34#define default_read_expire (HZ / 8)
35
36/*
37 * ditto for writes, these limits are not hard, even
38 * if the disk is capable of satisfying them.
39 */
40#define default_write_expire (HZ / 4)
41
42/*
43 * read_batch_expire describes how long we will allow a stream of reads to
44 * persist before looking to see whether it is time to switch over to writes.
45 */
46#define default_read_batch_expire (HZ / 2)
47
48/*
49 * write_batch_expire describes how long we want a stream of writes to run for.
50 * This is not a hard limit, but a target we set for the auto-tuning thingy.
51 * See, the problem is: we can send a lot of writes to disk cache / TCQ in
52 * a short amount of time...
53 */
54#define default_write_batch_expire (HZ / 8)
55
56/*
57 * max time we may wait to anticipate a read (default around 6ms)
58 */
59#define default_antic_expire ((HZ / 150) ? HZ / 150 : 1)
60
61/*
62 * Keep track of up to 20ms thinktimes. We can go as big as we like here,
63 * however huge values tend to interfere and not decay fast enough. A program
64 * might be in a non-io phase of operation. Waiting on user input for example,
65 * or doing a lengthy computation. A small penalty can be justified there, and
66 * will still catch out those processes that constantly have large thinktimes.
67 */
68#define MAX_THINKTIME (HZ/50UL)
69
70/* Bits in as_io_context.state */
71enum as_io_states {
72 AS_TASK_RUNNING=0, /* Process has not exitted */
73 AS_TASK_IOSTARTED, /* Process has started some IO */
74 AS_TASK_IORUNNING, /* Process has completed some IO */
75};
76
77enum anticipation_status {
78 ANTIC_OFF=0, /* Not anticipating (normal operation) */
79 ANTIC_WAIT_REQ, /* The last read has not yet completed */
80 ANTIC_WAIT_NEXT, /* Currently anticipating a request vs
81 last read (which has completed) */
82 ANTIC_FINISHED, /* Anticipating but have found a candidate
83 * or timed out */
84};
85
86struct as_data {
87 /*
88 * run time data
89 */
90
91 struct request_queue *q; /* the "owner" queue */
92
93 /*
94 * requests (as_rq s) are present on both sort_list and fifo_list
95 */
96 struct rb_root sort_list[2];
97 struct list_head fifo_list[2];
98
99 struct as_rq *next_arq[2]; /* next in sort order */
100 sector_t last_sector[2]; /* last REQ_SYNC & REQ_ASYNC sectors */
101 struct list_head *hash; /* request hash */
102
103 unsigned long exit_prob; /* probability a task will exit while
104 being waited on */
105 unsigned long new_ttime_total; /* mean thinktime on new proc */
106 unsigned long new_ttime_mean;
107 u64 new_seek_total; /* mean seek on new proc */
108 sector_t new_seek_mean;
109
110 unsigned long current_batch_expires;
111 unsigned long last_check_fifo[2];
112 int changed_batch; /* 1: waiting for old batch to end */
113 int new_batch; /* 1: waiting on first read complete */
114 int batch_data_dir; /* current batch REQ_SYNC / REQ_ASYNC */
115 int write_batch_count; /* max # of reqs in a write batch */
116 int current_write_count; /* how many requests left this batch */
117 int write_batch_idled; /* has the write batch gone idle? */
118 mempool_t *arq_pool;
119
120 enum anticipation_status antic_status;
121 unsigned long antic_start; /* jiffies: when it started */
122 struct timer_list antic_timer; /* anticipatory scheduling timer */
123 struct work_struct antic_work; /* Deferred unplugging */
124 struct io_context *io_context; /* Identify the expected process */
125 int ioc_finished; /* IO associated with io_context is finished */
126 int nr_dispatched;
127
128 /*
129 * settings that change how the i/o scheduler behaves
130 */
131 unsigned long fifo_expire[2];
132 unsigned long batch_expire[2];
133 unsigned long antic_expire;
134};
135
136#define list_entry_fifo(ptr) list_entry((ptr), struct as_rq, fifo)
137
138/*
139 * per-request data.
140 */
141enum arq_state {
142 AS_RQ_NEW=0, /* New - not referenced and not on any lists */
143 AS_RQ_QUEUED, /* In the request queue. It belongs to the
144 scheduler */
145 AS_RQ_DISPATCHED, /* On the dispatch list. It belongs to the
146 driver now */
147 AS_RQ_PRESCHED, /* Debug poisoning for requests being used */
148 AS_RQ_REMOVED,
149 AS_RQ_MERGED,
150 AS_RQ_POSTSCHED, /* when they shouldn't be */
151};
152
153struct as_rq {
154 /*
155 * rbtree index, key is the starting offset
156 */
157 struct rb_node rb_node;
158 sector_t rb_key;
159
160 struct request *request;
161
162 struct io_context *io_context; /* The submitting task */
163
164 /*
165 * request hash, key is the ending offset (for back merge lookup)
166 */
167 struct list_head hash;
168 unsigned int on_hash;
169
170 /*
171 * expire fifo
172 */
173 struct list_head fifo;
174 unsigned long expires;
175
176 unsigned int is_sync;
177 enum arq_state state;
178};
179
180#define RQ_DATA(rq) ((struct as_rq *) (rq)->elevator_private)
181
182static kmem_cache_t *arq_pool;
183
184/*
185 * IO Context helper functions
186 */
187
188/* Called to deallocate the as_io_context */
189static void free_as_io_context(struct as_io_context *aic)
190{
191 kfree(aic);
192}
193
194/* Called when the task exits */
195static void exit_as_io_context(struct as_io_context *aic)
196{
197 WARN_ON(!test_bit(AS_TASK_RUNNING, &aic->state));
198 clear_bit(AS_TASK_RUNNING, &aic->state);
199}
200
201static struct as_io_context *alloc_as_io_context(void)
202{
203 struct as_io_context *ret;
204
205 ret = kmalloc(sizeof(*ret), GFP_ATOMIC);
206 if (ret) {
207 ret->dtor = free_as_io_context;
208 ret->exit = exit_as_io_context;
209 ret->state = 1 << AS_TASK_RUNNING;
210 atomic_set(&ret->nr_queued, 0);
211 atomic_set(&ret->nr_dispatched, 0);
212 spin_lock_init(&ret->lock);
213 ret->ttime_total = 0;
214 ret->ttime_samples = 0;
215 ret->ttime_mean = 0;
216 ret->seek_total = 0;
217 ret->seek_samples = 0;
218 ret->seek_mean = 0;
219 }
220
221 return ret;
222}
223
224/*
225 * If the current task has no AS IO context then create one and initialise it.
226 * Then take a ref on the task's io context and return it.
227 */
228static struct io_context *as_get_io_context(void)
229{
230 struct io_context *ioc = get_io_context(GFP_ATOMIC);
231 if (ioc && !ioc->aic) {
232 ioc->aic = alloc_as_io_context();
233 if (!ioc->aic) {
234 put_io_context(ioc);
235 ioc = NULL;
236 }
237 }
238 return ioc;
239}
240
241static void as_put_io_context(struct as_rq *arq)
242{
243 struct as_io_context *aic;
244
245 if (unlikely(!arq->io_context))
246 return;
247
248 aic = arq->io_context->aic;
249
250 if (arq->is_sync == REQ_SYNC && aic) {
251 spin_lock(&aic->lock);
252 set_bit(AS_TASK_IORUNNING, &aic->state);
253 aic->last_end_request = jiffies;
254 spin_unlock(&aic->lock);
255 }
256
257 put_io_context(arq->io_context);
258}
259
260/*
261 * the back merge hash support functions
262 */
263static const int as_hash_shift = 6;
264#define AS_HASH_BLOCK(sec) ((sec) >> 3)
265#define AS_HASH_FN(sec) (hash_long(AS_HASH_BLOCK((sec)), as_hash_shift))
266#define AS_HASH_ENTRIES (1 << as_hash_shift)
267#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
268#define list_entry_hash(ptr) list_entry((ptr), struct as_rq, hash)
269
270static inline void __as_del_arq_hash(struct as_rq *arq)
271{
272 arq->on_hash = 0;
273 list_del_init(&arq->hash);
274}
275
276static inline void as_del_arq_hash(struct as_rq *arq)
277{
278 if (arq->on_hash)
279 __as_del_arq_hash(arq);
280}
281
282static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq)
283{
284 struct request *rq = arq->request;
285
286 BUG_ON(arq->on_hash);
287
288 arq->on_hash = 1;
289 list_add(&arq->hash, &ad->hash[AS_HASH_FN(rq_hash_key(rq))]);
290}
291
292/*
293 * move hot entry to front of chain
294 */
295static inline void as_hot_arq_hash(struct as_data *ad, struct as_rq *arq)
296{
297 struct request *rq = arq->request;
298 struct list_head *head = &ad->hash[AS_HASH_FN(rq_hash_key(rq))];
299
300 if (!arq->on_hash) {
301 WARN_ON(1);
302 return;
303 }
304
305 if (arq->hash.prev != head) {
306 list_del(&arq->hash);
307 list_add(&arq->hash, head);
308 }
309}
310
311static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset)
312{
313 struct list_head *hash_list = &ad->hash[AS_HASH_FN(offset)];
314 struct list_head *entry, *next = hash_list->next;
315
316 while ((entry = next) != hash_list) {
317 struct as_rq *arq = list_entry_hash(entry);
318 struct request *__rq = arq->request;
319
320 next = entry->next;
321
322 BUG_ON(!arq->on_hash);
323
324 if (!rq_mergeable(__rq)) {
325 as_del_arq_hash(arq);
326 continue;
327 }
328
329 if (rq_hash_key(__rq) == offset)
330 return __rq;
331 }
332
333 return NULL;
334}
335
336/*
337 * rb tree support functions
338 */
339#define RB_NONE (2)
340#define RB_EMPTY(root) ((root)->rb_node == NULL)
341#define ON_RB(node) ((node)->rb_color != RB_NONE)
342#define RB_CLEAR(node) ((node)->rb_color = RB_NONE)
343#define rb_entry_arq(node) rb_entry((node), struct as_rq, rb_node)
344#define ARQ_RB_ROOT(ad, arq) (&(ad)->sort_list[(arq)->is_sync])
345#define rq_rb_key(rq) (rq)->sector
346
347/*
348 * as_find_first_arq finds the first (lowest sector numbered) request
349 * for the specified data_dir. Used to sweep back to the start of the disk
350 * (1-way elevator) after we process the last (highest sector) request.
351 */
352static struct as_rq *as_find_first_arq(struct as_data *ad, int data_dir)
353{
354 struct rb_node *n = ad->sort_list[data_dir].rb_node;
355
356 if (n == NULL)
357 return NULL;
358
359 for (;;) {
360 if (n->rb_left == NULL)
361 return rb_entry_arq(n);
362
363 n = n->rb_left;
364 }
365}
366
367/*
368 * Add the request to the rb tree if it is unique. If there is an alias (an
369 * existing request against the same sector), which can happen when using
370 * direct IO, then return the alias.
371 */
372static struct as_rq *as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
373{
374 struct rb_node **p = &ARQ_RB_ROOT(ad, arq)->rb_node;
375 struct rb_node *parent = NULL;
376 struct as_rq *__arq;
377 struct request *rq = arq->request;
378
379 arq->rb_key = rq_rb_key(rq);
380
381 while (*p) {
382 parent = *p;
383 __arq = rb_entry_arq(parent);
384
385 if (arq->rb_key < __arq->rb_key)
386 p = &(*p)->rb_left;
387 else if (arq->rb_key > __arq->rb_key)
388 p = &(*p)->rb_right;
389 else
390 return __arq;
391 }
392
393 rb_link_node(&arq->rb_node, parent, p);
394 rb_insert_color(&arq->rb_node, ARQ_RB_ROOT(ad, arq));
395
396 return NULL;
397}
398
399static inline void as_del_arq_rb(struct as_data *ad, struct as_rq *arq)
400{
401 if (!ON_RB(&arq->rb_node)) {
402 WARN_ON(1);
403 return;
404 }
405
406 rb_erase(&arq->rb_node, ARQ_RB_ROOT(ad, arq));
407 RB_CLEAR(&arq->rb_node);
408}
409
410static struct request *
411as_find_arq_rb(struct as_data *ad, sector_t sector, int data_dir)
412{
413 struct rb_node *n = ad->sort_list[data_dir].rb_node;
414 struct as_rq *arq;
415
416 while (n) {
417 arq = rb_entry_arq(n);
418
419 if (sector < arq->rb_key)
420 n = n->rb_left;
421 else if (sector > arq->rb_key)
422 n = n->rb_right;
423 else
424 return arq->request;
425 }
426
427 return NULL;
428}
429
430/*
431 * IO Scheduler proper
432 */
433
434#define MAXBACK (1024 * 1024) /*
435 * Maximum distance the disk will go backward
436 * for a request.
437 */
438
439#define BACK_PENALTY 2
440
441/*
442 * as_choose_req selects the preferred one of two requests of the same data_dir
443 * ignoring time - eg. timeouts, which is the job of as_dispatch_request
444 */
445static struct as_rq *
446as_choose_req(struct as_data *ad, struct as_rq *arq1, struct as_rq *arq2)
447{
448 int data_dir;
449 sector_t last, s1, s2, d1, d2;
450 int r1_wrap=0, r2_wrap=0; /* requests are behind the disk head */
451 const sector_t maxback = MAXBACK;
452
453 if (arq1 == NULL || arq1 == arq2)
454 return arq2;
455 if (arq2 == NULL)
456 return arq1;
457
458 data_dir = arq1->is_sync;
459
460 last = ad->last_sector[data_dir];
461 s1 = arq1->request->sector;
462 s2 = arq2->request->sector;
463
464 BUG_ON(data_dir != arq2->is_sync);
465
466 /*
467 * Strict one way elevator _except_ in the case where we allow
468 * short backward seeks which are biased as twice the cost of a
469 * similar forward seek.
470 */
471 if (s1 >= last)
472 d1 = s1 - last;
473 else if (s1+maxback >= last)
474 d1 = (last - s1)*BACK_PENALTY;
475 else {
476 r1_wrap = 1;
477 d1 = 0; /* shut up, gcc */
478 }
479
480 if (s2 >= last)
481 d2 = s2 - last;
482 else if (s2+maxback >= last)
483 d2 = (last - s2)*BACK_PENALTY;
484 else {
485 r2_wrap = 1;
486 d2 = 0;
487 }
488
489 /* Found required data */
490 if (!r1_wrap && r2_wrap)
491 return arq1;
492 else if (!r2_wrap && r1_wrap)
493 return arq2;
494 else if (r1_wrap && r2_wrap) {
495 /* both behind the head */
496 if (s1 <= s2)
497 return arq1;
498 else
499 return arq2;
500 }
501
502 /* Both requests in front of the head */
503 if (d1 < d2)
504 return arq1;
505 else if (d2 < d1)
506 return arq2;
507 else {
508 if (s1 >= s2)
509 return arq1;
510 else
511 return arq2;
512 }
513}
514
515/*
516 * as_find_next_arq finds the next request after @prev in elevator order.
517 * this with as_choose_req form the basis for how the scheduler chooses
518 * what request to process next. Anticipation works on top of this.
519 */
520static struct as_rq *as_find_next_arq(struct as_data *ad, struct as_rq *last)
521{
522 const int data_dir = last->is_sync;
523 struct as_rq *ret;
524 struct rb_node *rbnext = rb_next(&last->rb_node);
525 struct rb_node *rbprev = rb_prev(&last->rb_node);
526 struct as_rq *arq_next, *arq_prev;
527
528 BUG_ON(!ON_RB(&last->rb_node));
529
530 if (rbprev)
531 arq_prev = rb_entry_arq(rbprev);
532 else
533 arq_prev = NULL;
534
535 if (rbnext)
536 arq_next = rb_entry_arq(rbnext);
537 else {
538 arq_next = as_find_first_arq(ad, data_dir);
539 if (arq_next == last)
540 arq_next = NULL;
541 }
542
543 ret = as_choose_req(ad, arq_next, arq_prev);
544
545 return ret;
546}
547
548/*
549 * anticipatory scheduling functions follow
550 */
551
552/*
553 * as_antic_expired tells us when we have anticipated too long.
554 * The funny "absolute difference" math on the elapsed time is to handle
555 * jiffy wraps, and disks which have been idle for 0x80000000 jiffies.
556 */
557static int as_antic_expired(struct as_data *ad)
558{
559 long delta_jif;
560
561 delta_jif = jiffies - ad->antic_start;
562 if (unlikely(delta_jif < 0))
563 delta_jif = -delta_jif;
564 if (delta_jif < ad->antic_expire)
565 return 0;
566
567 return 1;
568}
569
570/*
571 * as_antic_waitnext starts anticipating that a nice request will soon be
572 * submitted. See also as_antic_waitreq
573 */
574static void as_antic_waitnext(struct as_data *ad)
575{
576 unsigned long timeout;
577
578 BUG_ON(ad->antic_status != ANTIC_OFF
579 && ad->antic_status != ANTIC_WAIT_REQ);
580
581 timeout = ad->antic_start + ad->antic_expire;
582
583 mod_timer(&ad->antic_timer, timeout);
584
585 ad->antic_status = ANTIC_WAIT_NEXT;
586}
587
588/*
589 * as_antic_waitreq starts anticipating. We don't start timing the anticipation
590 * until the request that we're anticipating on has finished. This means we
591 * are timing from when the candidate process wakes up hopefully.
592 */
593static void as_antic_waitreq(struct as_data *ad)
594{
595 BUG_ON(ad->antic_status == ANTIC_FINISHED);
596 if (ad->antic_status == ANTIC_OFF) {
597 if (!ad->io_context || ad->ioc_finished)
598 as_antic_waitnext(ad);
599 else
600 ad->antic_status = ANTIC_WAIT_REQ;
601 }
602}
603
604/*
605 * This is called directly by the functions in this file to stop anticipation.
606 * We kill the timer and schedule a call to the request_fn asap.
607 */
608static void as_antic_stop(struct as_data *ad)
609{
610 int status = ad->antic_status;
611
612 if (status == ANTIC_WAIT_REQ || status == ANTIC_WAIT_NEXT) {
613 if (status == ANTIC_WAIT_NEXT)
614 del_timer(&ad->antic_timer);
615 ad->antic_status = ANTIC_FINISHED;
616 /* see as_work_handler */
617 kblockd_schedule_work(&ad->antic_work);
618 }
619}
620
621/*
622 * as_antic_timeout is the timer function set by as_antic_waitnext.
623 */
624static void as_antic_timeout(unsigned long data)
625{
626 struct request_queue *q = (struct request_queue *)data;
627 struct as_data *ad = q->elevator->elevator_data;
628 unsigned long flags;
629
630 spin_lock_irqsave(q->queue_lock, flags);
631 if (ad->antic_status == ANTIC_WAIT_REQ
632 || ad->antic_status == ANTIC_WAIT_NEXT) {
633 struct as_io_context *aic = ad->io_context->aic;
634
635 ad->antic_status = ANTIC_FINISHED;
636 kblockd_schedule_work(&ad->antic_work);
637
638 if (aic->ttime_samples == 0) {
639 /* process anticipated on has exitted or timed out*/
640 ad->exit_prob = (7*ad->exit_prob + 256)/8;
641 }
642 }
643 spin_unlock_irqrestore(q->queue_lock, flags);
644}
645
646/*
647 * as_close_req decides if one request is considered "close" to the
648 * previous one issued.
649 */
650static int as_close_req(struct as_data *ad, struct as_rq *arq)
651{
652 unsigned long delay; /* milliseconds */
653 sector_t last = ad->last_sector[ad->batch_data_dir];
654 sector_t next = arq->request->sector;
655 sector_t delta; /* acceptable close offset (in sectors) */
656
657 if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished)
658 delay = 0;
659 else
660 delay = ((jiffies - ad->antic_start) * 1000) / HZ;
661
662 if (delay <= 1)
663 delta = 64;
664 else if (delay <= 20 && delay <= ad->antic_expire)
665 delta = 64 << (delay-1);
666 else
667 return 1;
668
669 return (last - (delta>>1) <= next) && (next <= last + delta);
670}
671
672/*
673 * as_can_break_anticipation returns true if we have been anticipating this
674 * request.
675 *
676 * It also returns true if the process against which we are anticipating
677 * submits a write - that's presumably an fsync, O_SYNC write, etc. We want to
678 * dispatch it ASAP, because we know that application will not be submitting
679 * any new reads.
680 *
681 * If the task which has submitted the request has exitted, break anticipation.
682 *
683 * If this task has queued some other IO, do not enter enticipation.
684 */
685static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
686{
687 struct io_context *ioc;
688 struct as_io_context *aic;
689 sector_t s;
690
691 ioc = ad->io_context;
692 BUG_ON(!ioc);
693
694 if (arq && ioc == arq->io_context) {
695 /* request from same process */
696 return 1;
697 }
698
699 if (ad->ioc_finished && as_antic_expired(ad)) {
700 /*
701 * In this situation status should really be FINISHED,
702 * however the timer hasn't had the chance to run yet.
703 */
704 return 1;
705 }
706
707 aic = ioc->aic;
708 if (!aic)
709 return 0;
710
711 if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
712 /* process anticipated on has exitted */
713 if (aic->ttime_samples == 0)
714 ad->exit_prob = (7*ad->exit_prob + 256)/8;
715 return 1;
716 }
717
718 if (atomic_read(&aic->nr_queued) > 0) {
719 /* process has more requests queued */
720 return 1;
721 }
722
723 if (atomic_read(&aic->nr_dispatched) > 0) {
724 /* process has more requests dispatched */
725 return 1;
726 }
727
728 if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, arq)) {
729 /*
730 * Found a close request that is not one of ours.
731 *
732 * This makes close requests from another process reset
733 * our thinktime delay. Is generally useful when there are
734 * two or more cooperating processes working in the same
735 * area.
736 */
737 spin_lock(&aic->lock);
738 aic->last_end_request = jiffies;
739 spin_unlock(&aic->lock);
740 return 1;
741 }
742
743
744 if (aic->ttime_samples == 0) {
745 if (ad->new_ttime_mean > ad->antic_expire)
746 return 1;
747 if (ad->exit_prob > 128)
748 return 1;
749 } else if (aic->ttime_mean > ad->antic_expire) {
750 /* the process thinks too much between requests */
751 return 1;
752 }
753
754 if (!arq)
755 return 0;
756
757 if (ad->last_sector[REQ_SYNC] < arq->request->sector)
758 s = arq->request->sector - ad->last_sector[REQ_SYNC];
759 else
760 s = ad->last_sector[REQ_SYNC] - arq->request->sector;
761
762 if (aic->seek_samples == 0) {
763 /*
764 * Process has just started IO. Use past statistics to
765 * guage success possibility
766 */
767 if (ad->new_seek_mean > s) {
768 /* this request is better than what we're expecting */
769 return 1;
770 }
771
772 } else {
773 if (aic->seek_mean > s) {
774 /* this request is better than what we're expecting */
775 return 1;
776 }
777 }
778
779 return 0;
780}
781
782/*
783 * as_can_anticipate indicates weather we should either run arq
784 * or keep anticipating a better request.
785 */
786static int as_can_anticipate(struct as_data *ad, struct as_rq *arq)
787{
788 if (!ad->io_context)
789 /*
790 * Last request submitted was a write
791 */
792 return 0;
793
794 if (ad->antic_status == ANTIC_FINISHED)
795 /*
796 * Don't restart if we have just finished. Run the next request
797 */
798 return 0;
799
800 if (as_can_break_anticipation(ad, arq))
801 /*
802 * This request is a good candidate. Don't keep anticipating,
803 * run it.
804 */
805 return 0;
806
807 /*
808 * OK from here, we haven't finished, and don't have a decent request!
809 * Status is either ANTIC_OFF so start waiting,
810 * ANTIC_WAIT_REQ so continue waiting for request to finish
811 * or ANTIC_WAIT_NEXT so continue waiting for an acceptable request.
812 *
813 */
814
815 return 1;
816}
817
818static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic, unsigned long ttime)
819{
820 /* fixed point: 1.0 == 1<<8 */
821 if (aic->ttime_samples == 0) {
822 ad->new_ttime_total = (7*ad->new_ttime_total + 256*ttime) / 8;
823 ad->new_ttime_mean = ad->new_ttime_total / 256;
824
825 ad->exit_prob = (7*ad->exit_prob)/8;
826 }
827 aic->ttime_samples = (7*aic->ttime_samples + 256) / 8;
828 aic->ttime_total = (7*aic->ttime_total + 256*ttime) / 8;
829 aic->ttime_mean = (aic->ttime_total + 128) / aic->ttime_samples;
830}
831
832static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic, sector_t sdist)
833{
834 u64 total;
835
836 if (aic->seek_samples == 0) {
837 ad->new_seek_total = (7*ad->new_seek_total + 256*(u64)sdist)/8;
838 ad->new_seek_mean = ad->new_seek_total / 256;
839 }
840
841 /*
842 * Don't allow the seek distance to get too large from the
843 * odd fragment, pagein, etc
844 */
845 if (aic->seek_samples <= 60) /* second&third seek */
846 sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*1024);
847 else
848 sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*64);
849
850 aic->seek_samples = (7*aic->seek_samples + 256) / 8;
851 aic->seek_total = (7*aic->seek_total + (u64)256*sdist) / 8;
852 total = aic->seek_total + (aic->seek_samples/2);
853 do_div(total, aic->seek_samples);
854 aic->seek_mean = (sector_t)total;
855}
856
857/*
858 * as_update_iohist keeps a decaying histogram of IO thinktimes, and
859 * updates @aic->ttime_mean based on that. It is called when a new
860 * request is queued.
861 */
862static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, struct request *rq)
863{
864 struct as_rq *arq = RQ_DATA(rq);
865 int data_dir = arq->is_sync;
866 unsigned long thinktime;
867 sector_t seek_dist;
868
869 if (aic == NULL)
870 return;
871
872 if (data_dir == REQ_SYNC) {
873 unsigned long in_flight = atomic_read(&aic->nr_queued)
874 + atomic_read(&aic->nr_dispatched);
875 spin_lock(&aic->lock);
876 if (test_bit(AS_TASK_IORUNNING, &aic->state) ||
877 test_bit(AS_TASK_IOSTARTED, &aic->state)) {
878 /* Calculate read -> read thinktime */
879 if (test_bit(AS_TASK_IORUNNING, &aic->state)
880 && in_flight == 0) {
881 thinktime = jiffies - aic->last_end_request;
882 thinktime = min(thinktime, MAX_THINKTIME-1);
883 } else
884 thinktime = 0;
885 as_update_thinktime(ad, aic, thinktime);
886
887 /* Calculate read -> read seek distance */
888 if (aic->last_request_pos < rq->sector)
889 seek_dist = rq->sector - aic->last_request_pos;
890 else
891 seek_dist = aic->last_request_pos - rq->sector;
892 as_update_seekdist(ad, aic, seek_dist);
893 }
894 aic->last_request_pos = rq->sector + rq->nr_sectors;
895 set_bit(AS_TASK_IOSTARTED, &aic->state);
896 spin_unlock(&aic->lock);
897 }
898}
899
900/*
901 * as_update_arq must be called whenever a request (arq) is added to
902 * the sort_list. This function keeps caches up to date, and checks if the
903 * request might be one we are "anticipating"
904 */
905static void as_update_arq(struct as_data *ad, struct as_rq *arq)
906{
907 const int data_dir = arq->is_sync;
908
909 /* keep the next_arq cache up to date */
910 ad->next_arq[data_dir] = as_choose_req(ad, arq, ad->next_arq[data_dir]);
911
912 /*
913 * have we been anticipating this request?
914 * or does it come from the same process as the one we are anticipating
915 * for?
916 */
917 if (ad->antic_status == ANTIC_WAIT_REQ
918 || ad->antic_status == ANTIC_WAIT_NEXT) {
919 if (as_can_break_anticipation(ad, arq))
920 as_antic_stop(ad);
921 }
922}
923
924/*
925 * Gathers timings and resizes the write batch automatically
926 */
927static void update_write_batch(struct as_data *ad)
928{
929 unsigned long batch = ad->batch_expire[REQ_ASYNC];
930 long write_time;
931
932 write_time = (jiffies - ad->current_batch_expires) + batch;
933 if (write_time < 0)
934 write_time = 0;
935
936 if (write_time > batch && !ad->write_batch_idled) {
937 if (write_time > batch * 3)
938 ad->write_batch_count /= 2;
939 else
940 ad->write_batch_count--;
941 } else if (write_time < batch && ad->current_write_count == 0) {
942 if (batch > write_time * 3)
943 ad->write_batch_count *= 2;
944 else
945 ad->write_batch_count++;
946 }
947
948 if (ad->write_batch_count < 1)
949 ad->write_batch_count = 1;
950}
951
952/*
953 * as_completed_request is to be called when a request has completed and
954 * returned something to the requesting process, be it an error or data.
955 */
956static void as_completed_request(request_queue_t *q, struct request *rq)
957{
958 struct as_data *ad = q->elevator->elevator_data;
959 struct as_rq *arq = RQ_DATA(rq);
960
961 WARN_ON(!list_empty(&rq->queuelist));
962
963 if (arq->state != AS_RQ_REMOVED) {
964 printk("arq->state %d\n", arq->state);
965 WARN_ON(1);
966 goto out;
967 }
968
969 if (ad->changed_batch && ad->nr_dispatched == 1) {
970 kblockd_schedule_work(&ad->antic_work);
971 ad->changed_batch = 0;
972
973 if (ad->batch_data_dir == REQ_SYNC)
974 ad->new_batch = 1;
975 }
976 WARN_ON(ad->nr_dispatched == 0);
977 ad->nr_dispatched--;
978
979 /*
980 * Start counting the batch from when a request of that direction is
981 * actually serviced. This should help devices with big TCQ windows
982 * and writeback caches
983 */
984 if (ad->new_batch && ad->batch_data_dir == arq->is_sync) {
985 update_write_batch(ad);
986 ad->current_batch_expires = jiffies +
987 ad->batch_expire[REQ_SYNC];
988 ad->new_batch = 0;
989 }
990
991 if (ad->io_context == arq->io_context && ad->io_context) {
992 ad->antic_start = jiffies;
993 ad->ioc_finished = 1;
994 if (ad->antic_status == ANTIC_WAIT_REQ) {
995 /*
996 * We were waiting on this request, now anticipate
997 * the next one
998 */
999 as_antic_waitnext(ad);
1000 }
1001 }
1002
1003 as_put_io_context(arq);
1004out:
1005 arq->state = AS_RQ_POSTSCHED;
1006}
1007
1008/*
1009 * as_remove_queued_request removes a request from the pre dispatch queue
1010 * without updating refcounts. It is expected the caller will drop the
1011 * reference unless it replaces the request at somepart of the elevator
1012 * (ie. the dispatch queue)
1013 */
1014static void as_remove_queued_request(request_queue_t *q, struct request *rq)
1015{
1016 struct as_rq *arq = RQ_DATA(rq);
1017 const int data_dir = arq->is_sync;
1018 struct as_data *ad = q->elevator->elevator_data;
1019
1020 WARN_ON(arq->state != AS_RQ_QUEUED);
1021
1022 if (arq->io_context && arq->io_context->aic) {
1023 BUG_ON(!atomic_read(&arq->io_context->aic->nr_queued));
1024 atomic_dec(&arq->io_context->aic->nr_queued);
1025 }
1026
1027 /*
1028 * Update the "next_arq" cache if we are about to remove its
1029 * entry
1030 */
1031 if (ad->next_arq[data_dir] == arq)
1032 ad->next_arq[data_dir] = as_find_next_arq(ad, arq);
1033
1034 list_del_init(&arq->fifo);
1035 as_del_arq_hash(arq);
1036 as_del_arq_rb(ad, arq);
1037}
1038
1039/*
1040 * as_fifo_expired returns 0 if there are no expired reads on the fifo,
1041 * 1 otherwise. It is ratelimited so that we only perform the check once per
1042 * `fifo_expire' interval. Otherwise a large number of expired requests
1043 * would create a hopeless seekstorm.
1044 *
1045 * See as_antic_expired comment.
1046 */
1047static int as_fifo_expired(struct as_data *ad, int adir)
1048{
1049 struct as_rq *arq;
1050 long delta_jif;
1051
1052 delta_jif = jiffies - ad->last_check_fifo[adir];
1053 if (unlikely(delta_jif < 0))
1054 delta_jif = -delta_jif;
1055 if (delta_jif < ad->fifo_expire[adir])
1056 return 0;
1057
1058 ad->last_check_fifo[adir] = jiffies;
1059
1060 if (list_empty(&ad->fifo_list[adir]))
1061 return 0;
1062
1063 arq = list_entry_fifo(ad->fifo_list[adir].next);
1064
1065 return time_after(jiffies, arq->expires);
1066}
1067
1068/*
1069 * as_batch_expired returns true if the current batch has expired. A batch
1070 * is a set of reads or a set of writes.
1071 */
1072static inline int as_batch_expired(struct as_data *ad)
1073{
1074 if (ad->changed_batch || ad->new_batch)
1075 return 0;
1076
1077 if (ad->batch_data_dir == REQ_SYNC)
1078 /* TODO! add a check so a complete fifo gets written? */
1079 return time_after(jiffies, ad->current_batch_expires);
1080
1081 return time_after(jiffies, ad->current_batch_expires)
1082 || ad->current_write_count == 0;
1083}
1084
1085/*
1086 * move an entry to dispatch queue
1087 */
1088static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq)
1089{
1090 struct request *rq = arq->request;
1091 const int data_dir = arq->is_sync;
1092
1093 BUG_ON(!ON_RB(&arq->rb_node));
1094
1095 as_antic_stop(ad);
1096 ad->antic_status = ANTIC_OFF;
1097
1098 /*
1099 * This has to be set in order to be correctly updated by
1100 * as_find_next_arq
1101 */
1102 ad->last_sector[data_dir] = rq->sector + rq->nr_sectors;
1103
1104 if (data_dir == REQ_SYNC) {
1105 /* In case we have to anticipate after this */
1106 copy_io_context(&ad->io_context, &arq->io_context);
1107 } else {
1108 if (ad->io_context) {
1109 put_io_context(ad->io_context);
1110 ad->io_context = NULL;
1111 }
1112
1113 if (ad->current_write_count != 0)
1114 ad->current_write_count--;
1115 }
1116 ad->ioc_finished = 0;
1117
1118 ad->next_arq[data_dir] = as_find_next_arq(ad, arq);
1119
1120 /*
1121 * take it off the sort and fifo list, add to dispatch queue
1122 */
1123 while (!list_empty(&rq->queuelist)) {
1124 struct request *__rq = list_entry_rq(rq->queuelist.next);
1125 struct as_rq *__arq = RQ_DATA(__rq);
1126
1127 list_del(&__rq->queuelist);
1128
1129 elv_dispatch_add_tail(ad->q, __rq);
1130
1131 if (__arq->io_context && __arq->io_context->aic)
1132 atomic_inc(&__arq->io_context->aic->nr_dispatched);
1133
1134 WARN_ON(__arq->state != AS_RQ_QUEUED);
1135 __arq->state = AS_RQ_DISPATCHED;
1136
1137 ad->nr_dispatched++;
1138 }
1139
1140 as_remove_queued_request(ad->q, rq);
1141 WARN_ON(arq->state != AS_RQ_QUEUED);
1142
1143 elv_dispatch_sort(ad->q, rq);
1144
1145 arq->state = AS_RQ_DISPATCHED;
1146 if (arq->io_context && arq->io_context->aic)
1147 atomic_inc(&arq->io_context->aic->nr_dispatched);
1148 ad->nr_dispatched++;
1149}
1150
1151/*
1152 * as_dispatch_request selects the best request according to
1153 * read/write expire, batch expire, etc, and moves it to the dispatch
1154 * queue. Returns 1 if a request was found, 0 otherwise.
1155 */
1156static int as_dispatch_request(request_queue_t *q, int force)
1157{
1158 struct as_data *ad = q->elevator->elevator_data;
1159 struct as_rq *arq;
1160 const int reads = !list_empty(&ad->fifo_list[REQ_SYNC]);
1161 const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]);
1162
1163 if (unlikely(force)) {
1164 /*
1165 * Forced dispatch, accounting is useless. Reset
1166 * accounting states and dump fifo_lists. Note that
1167 * batch_data_dir is reset to REQ_SYNC to avoid
1168 * screwing write batch accounting as write batch
1169 * accounting occurs on W->R transition.
1170 */
1171 int dispatched = 0;
1172
1173 ad->batch_data_dir = REQ_SYNC;
1174 ad->changed_batch = 0;
1175 ad->new_batch = 0;
1176
1177 while (ad->next_arq[REQ_SYNC]) {
1178 as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]);
1179 dispatched++;
1180 }
1181 ad->last_check_fifo[REQ_SYNC] = jiffies;
1182
1183 while (ad->next_arq[REQ_ASYNC]) {
1184 as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]);
1185 dispatched++;
1186 }
1187 ad->last_check_fifo[REQ_ASYNC] = jiffies;
1188
1189 return dispatched;
1190 }
1191
1192 /* Signal that the write batch was uncontended, so we can't time it */
1193 if (ad->batch_data_dir == REQ_ASYNC && !reads) {
1194 if (ad->current_write_count == 0 || !writes)
1195 ad->write_batch_idled = 1;
1196 }
1197
1198 if (!(reads || writes)
1199 || ad->antic_status == ANTIC_WAIT_REQ
1200 || ad->antic_status == ANTIC_WAIT_NEXT
1201 || ad->changed_batch)
1202 return 0;
1203
1204 if (!(reads && writes && as_batch_expired(ad)) ) {
1205 /*
1206 * batch is still running or no reads or no writes
1207 */
1208 arq = ad->next_arq[ad->batch_data_dir];
1209
1210 if (ad->batch_data_dir == REQ_SYNC && ad->antic_expire) {
1211 if (as_fifo_expired(ad, REQ_SYNC))
1212 goto fifo_expired;
1213
1214 if (as_can_anticipate(ad, arq)) {
1215 as_antic_waitreq(ad);
1216 return 0;
1217 }
1218 }
1219
1220 if (arq) {
1221 /* we have a "next request" */
1222 if (reads && !writes)
1223 ad->current_batch_expires =
1224 jiffies + ad->batch_expire[REQ_SYNC];
1225 goto dispatch_request;
1226 }
1227 }
1228
1229 /*
1230 * at this point we are not running a batch. select the appropriate
1231 * data direction (read / write)
1232 */
1233
1234 if (reads) {
1235 BUG_ON(RB_EMPTY(&ad->sort_list[REQ_SYNC]));
1236
1237 if (writes && ad->batch_data_dir == REQ_SYNC)
1238 /*
1239 * Last batch was a read, switch to writes
1240 */
1241 goto dispatch_writes;
1242
1243 if (ad->batch_data_dir == REQ_ASYNC) {
1244 WARN_ON(ad->new_batch);
1245 ad->changed_batch = 1;
1246 }
1247 ad->batch_data_dir = REQ_SYNC;
1248 arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next);
1249 ad->last_check_fifo[ad->batch_data_dir] = jiffies;
1250 goto dispatch_request;
1251 }
1252
1253 /*
1254 * the last batch was a read
1255 */
1256
1257 if (writes) {
1258dispatch_writes:
1259 BUG_ON(RB_EMPTY(&ad->sort_list[REQ_ASYNC]));
1260
1261 if (ad->batch_data_dir == REQ_SYNC) {
1262 ad->changed_batch = 1;
1263
1264 /*
1265 * new_batch might be 1 when the queue runs out of
1266 * reads. A subsequent submission of a write might
1267 * cause a change of batch before the read is finished.
1268 */
1269 ad->new_batch = 0;
1270 }
1271 ad->batch_data_dir = REQ_ASYNC;
1272 ad->current_write_count = ad->write_batch_count;
1273 ad->write_batch_idled = 0;
1274 arq = ad->next_arq[ad->batch_data_dir];
1275 goto dispatch_request;
1276 }
1277
1278 BUG();
1279 return 0;
1280
1281dispatch_request:
1282 /*
1283 * If a request has expired, service it.
1284 */
1285
1286 if (as_fifo_expired(ad, ad->batch_data_dir)) {
1287fifo_expired:
1288 arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next);
1289 BUG_ON(arq == NULL);
1290 }
1291
1292 if (ad->changed_batch) {
1293 WARN_ON(ad->new_batch);
1294
1295 if (ad->nr_dispatched)
1296 return 0;
1297
1298 if (ad->batch_data_dir == REQ_ASYNC)
1299 ad->current_batch_expires = jiffies +
1300 ad->batch_expire[REQ_ASYNC];
1301 else
1302 ad->new_batch = 1;
1303
1304 ad->changed_batch = 0;
1305 }
1306
1307 /*
1308 * arq is the selected appropriate request.
1309 */
1310 as_move_to_dispatch(ad, arq);
1311
1312 return 1;
1313}
1314
1315/*
1316 * Add arq to a list behind alias
1317 */
1318static inline void
1319as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alias)
1320{
1321 struct request *req = arq->request;
1322 struct list_head *insert = alias->request->queuelist.prev;
1323
1324 /*
1325 * Transfer list of aliases
1326 */
1327 while (!list_empty(&req->queuelist)) {
1328 struct request *__rq = list_entry_rq(req->queuelist.next);
1329 struct as_rq *__arq = RQ_DATA(__rq);
1330
1331 list_move_tail(&__rq->queuelist, &alias->request->queuelist);
1332
1333 WARN_ON(__arq->state != AS_RQ_QUEUED);
1334 }
1335
1336 /*
1337 * Another request with the same start sector on the rbtree.
1338 * Link this request to that sector. They are untangled in
1339 * as_move_to_dispatch
1340 */
1341 list_add(&arq->request->queuelist, insert);
1342
1343 /*
1344 * Don't want to have to handle merges.
1345 */
1346 as_del_arq_hash(arq);
1347 arq->request->flags |= REQ_NOMERGE;
1348}
1349
1350/*
1351 * add arq to rbtree and fifo
1352 */
1353static void as_add_request(request_queue_t *q, struct request *rq)
1354{
1355 struct as_data *ad = q->elevator->elevator_data;
1356 struct as_rq *arq = RQ_DATA(rq);
1357 struct as_rq *alias;
1358 int data_dir;
1359
1360 if (arq->state != AS_RQ_PRESCHED) {
1361 printk("arq->state: %d\n", arq->state);
1362 WARN_ON(1);
1363 }
1364 arq->state = AS_RQ_NEW;
1365
1366 if (rq_data_dir(arq->request) == READ
1367 || current->flags&PF_SYNCWRITE)
1368 arq->is_sync = 1;
1369 else
1370 arq->is_sync = 0;
1371 data_dir = arq->is_sync;
1372
1373 arq->io_context = as_get_io_context();
1374
1375 if (arq->io_context) {
1376 as_update_iohist(ad, arq->io_context->aic, arq->request);
1377 atomic_inc(&arq->io_context->aic->nr_queued);
1378 }
1379
1380 alias = as_add_arq_rb(ad, arq);
1381 if (!alias) {
1382 /*
1383 * set expire time (only used for reads) and add to fifo list
1384 */
1385 arq->expires = jiffies + ad->fifo_expire[data_dir];
1386 list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
1387
1388 if (rq_mergeable(arq->request))
1389 as_add_arq_hash(ad, arq);
1390 as_update_arq(ad, arq); /* keep state machine up to date */
1391
1392 } else {
1393 as_add_aliased_request(ad, arq, alias);
1394
1395 /*
1396 * have we been anticipating this request?
1397 * or does it come from the same process as the one we are
1398 * anticipating for?
1399 */
1400 if (ad->antic_status == ANTIC_WAIT_REQ
1401 || ad->antic_status == ANTIC_WAIT_NEXT) {
1402 if (as_can_break_anticipation(ad, arq))
1403 as_antic_stop(ad);
1404 }
1405 }
1406
1407 arq->state = AS_RQ_QUEUED;
1408}
1409
1410static void as_activate_request(request_queue_t *q, struct request *rq)
1411{
1412 struct as_rq *arq = RQ_DATA(rq);
1413
1414 WARN_ON(arq->state != AS_RQ_DISPATCHED);
1415 arq->state = AS_RQ_REMOVED;
1416 if (arq->io_context && arq->io_context->aic)
1417 atomic_dec(&arq->io_context->aic->nr_dispatched);
1418}
1419
1420static void as_deactivate_request(request_queue_t *q, struct request *rq)
1421{
1422 struct as_rq *arq = RQ_DATA(rq);
1423
1424 WARN_ON(arq->state != AS_RQ_REMOVED);
1425 arq->state = AS_RQ_DISPATCHED;
1426 if (arq->io_context && arq->io_context->aic)
1427 atomic_inc(&arq->io_context->aic->nr_dispatched);
1428}
1429
1430/*
1431 * as_queue_empty tells us if there are requests left in the device. It may
1432 * not be the case that a driver can get the next request even if the queue
1433 * is not empty - it is used in the block layer to check for plugging and
1434 * merging opportunities
1435 */
1436static int as_queue_empty(request_queue_t *q)
1437{
1438 struct as_data *ad = q->elevator->elevator_data;
1439
1440 return list_empty(&ad->fifo_list[REQ_ASYNC])
1441 && list_empty(&ad->fifo_list[REQ_SYNC]);
1442}
1443
1444static struct request *
1445as_former_request(request_queue_t *q, struct request *rq)
1446{
1447 struct as_rq *arq = RQ_DATA(rq);
1448 struct rb_node *rbprev = rb_prev(&arq->rb_node);
1449 struct request *ret = NULL;
1450
1451 if (rbprev)
1452 ret = rb_entry_arq(rbprev)->request;
1453
1454 return ret;
1455}
1456
1457static struct request *
1458as_latter_request(request_queue_t *q, struct request *rq)
1459{
1460 struct as_rq *arq = RQ_DATA(rq);
1461 struct rb_node *rbnext = rb_next(&arq->rb_node);
1462 struct request *ret = NULL;
1463
1464 if (rbnext)
1465 ret = rb_entry_arq(rbnext)->request;
1466
1467 return ret;
1468}
1469
1470static int
1471as_merge(request_queue_t *q, struct request **req, struct bio *bio)
1472{
1473 struct as_data *ad = q->elevator->elevator_data;
1474 sector_t rb_key = bio->bi_sector + bio_sectors(bio);
1475 struct request *__rq;
1476 int ret;
1477
1478 /*
1479 * see if the merge hash can satisfy a back merge
1480 */
1481 __rq = as_find_arq_hash(ad, bio->bi_sector);
1482 if (__rq) {
1483 BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
1484
1485 if (elv_rq_merge_ok(__rq, bio)) {
1486 ret = ELEVATOR_BACK_MERGE;
1487 goto out;
1488 }
1489 }
1490
1491 /*
1492 * check for front merge
1493 */
1494 __rq = as_find_arq_rb(ad, rb_key, bio_data_dir(bio));
1495 if (__rq) {
1496 BUG_ON(rb_key != rq_rb_key(__rq));
1497
1498 if (elv_rq_merge_ok(__rq, bio)) {
1499 ret = ELEVATOR_FRONT_MERGE;
1500 goto out;
1501 }
1502 }
1503
1504 return ELEVATOR_NO_MERGE;
1505out:
1506 if (ret) {
1507 if (rq_mergeable(__rq))
1508 as_hot_arq_hash(ad, RQ_DATA(__rq));
1509 }
1510 *req = __rq;
1511 return ret;
1512}
1513
1514static void as_merged_request(request_queue_t *q, struct request *req)
1515{
1516 struct as_data *ad = q->elevator->elevator_data;
1517 struct as_rq *arq = RQ_DATA(req);
1518
1519 /*
1520 * hash always needs to be repositioned, key is end sector
1521 */
1522 as_del_arq_hash(arq);
1523 as_add_arq_hash(ad, arq);
1524
1525 /*
1526 * if the merge was a front merge, we need to reposition request
1527 */
1528 if (rq_rb_key(req) != arq->rb_key) {
1529 struct as_rq *alias, *next_arq = NULL;
1530
1531 if (ad->next_arq[arq->is_sync] == arq)
1532 next_arq = as_find_next_arq(ad, arq);
1533
1534 /*
1535 * Note! We should really be moving any old aliased requests
1536 * off this request and try to insert them into the rbtree. We
1537 * currently don't bother. Ditto the next function.
1538 */
1539 as_del_arq_rb(ad, arq);
1540 if ((alias = as_add_arq_rb(ad, arq)) ) {
1541 list_del_init(&arq->fifo);
1542 as_add_aliased_request(ad, arq, alias);
1543 if (next_arq)
1544 ad->next_arq[arq->is_sync] = next_arq;
1545 }
1546 /*
1547 * Note! At this stage of this and the next function, our next
1548 * request may not be optimal - eg the request may have "grown"
1549 * behind the disk head. We currently don't bother adjusting.
1550 */
1551 }
1552}
1553
1554static void
1555as_merged_requests(request_queue_t *q, struct request *req,
1556 struct request *next)
1557{
1558 struct as_data *ad = q->elevator->elevator_data;
1559 struct as_rq *arq = RQ_DATA(req);
1560 struct as_rq *anext = RQ_DATA(next);
1561
1562 BUG_ON(!arq);
1563 BUG_ON(!anext);
1564
1565 /*
1566 * reposition arq (this is the merged request) in hash, and in rbtree
1567 * in case of a front merge
1568 */
1569 as_del_arq_hash(arq);
1570 as_add_arq_hash(ad, arq);
1571
1572 if (rq_rb_key(req) != arq->rb_key) {
1573 struct as_rq *alias, *next_arq = NULL;
1574
1575 if (ad->next_arq[arq->is_sync] == arq)
1576 next_arq = as_find_next_arq(ad, arq);
1577
1578 as_del_arq_rb(ad, arq);
1579 if ((alias = as_add_arq_rb(ad, arq)) ) {
1580 list_del_init(&arq->fifo);
1581 as_add_aliased_request(ad, arq, alias);
1582 if (next_arq)
1583 ad->next_arq[arq->is_sync] = next_arq;
1584 }
1585 }
1586
1587 /*
1588 * if anext expires before arq, assign its expire time to arq
1589 * and move into anext position (anext will be deleted) in fifo
1590 */
1591 if (!list_empty(&arq->fifo) && !list_empty(&anext->fifo)) {
1592 if (time_before(anext->expires, arq->expires)) {
1593 list_move(&arq->fifo, &anext->fifo);
1594 arq->expires = anext->expires;
1595 /*
1596 * Don't copy here but swap, because when anext is
1597 * removed below, it must contain the unused context
1598 */
1599 swap_io_context(&arq->io_context, &anext->io_context);
1600 }
1601 }
1602
1603 /*
1604 * Transfer list of aliases
1605 */
1606 while (!list_empty(&next->queuelist)) {
1607 struct request *__rq = list_entry_rq(next->queuelist.next);
1608 struct as_rq *__arq = RQ_DATA(__rq);
1609
1610 list_move_tail(&__rq->queuelist, &req->queuelist);
1611
1612 WARN_ON(__arq->state != AS_RQ_QUEUED);
1613 }
1614
1615 /*
1616 * kill knowledge of next, this one is a goner
1617 */
1618 as_remove_queued_request(q, next);
1619 as_put_io_context(anext);
1620
1621 anext->state = AS_RQ_MERGED;
1622}
1623
1624/*
1625 * This is executed in a "deferred" process context, by kblockd. It calls the
1626 * driver's request_fn so the driver can submit that request.
1627 *
1628 * IMPORTANT! This guy will reenter the elevator, so set up all queue global
1629 * state before calling, and don't rely on any state over calls.
1630 *
1631 * FIXME! dispatch queue is not a queue at all!
1632 */
1633static void as_work_handler(void *data)
1634{
1635 struct request_queue *q = data;
1636 unsigned long flags;
1637
1638 spin_lock_irqsave(q->queue_lock, flags);
1639 if (!as_queue_empty(q))
1640 q->request_fn(q);
1641 spin_unlock_irqrestore(q->queue_lock, flags);
1642}
1643
1644static void as_put_request(request_queue_t *q, struct request *rq)
1645{
1646 struct as_data *ad = q->elevator->elevator_data;
1647 struct as_rq *arq = RQ_DATA(rq);
1648
1649 if (!arq) {
1650 WARN_ON(1);
1651 return;
1652 }
1653
1654 if (unlikely(arq->state != AS_RQ_POSTSCHED &&
1655 arq->state != AS_RQ_PRESCHED &&
1656 arq->state != AS_RQ_MERGED)) {
1657 printk("arq->state %d\n", arq->state);
1658 WARN_ON(1);
1659 }
1660
1661 mempool_free(arq, ad->arq_pool);
1662 rq->elevator_private = NULL;
1663}
1664
1665static int as_set_request(request_queue_t *q, struct request *rq,
1666 struct bio *bio, gfp_t gfp_mask)
1667{
1668 struct as_data *ad = q->elevator->elevator_data;
1669 struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask);
1670
1671 if (arq) {
1672 memset(arq, 0, sizeof(*arq));
1673 RB_CLEAR(&arq->rb_node);
1674 arq->request = rq;
1675 arq->state = AS_RQ_PRESCHED;
1676 arq->io_context = NULL;
1677 INIT_LIST_HEAD(&arq->hash);
1678 arq->on_hash = 0;
1679 INIT_LIST_HEAD(&arq->fifo);
1680 rq->elevator_private = arq;
1681 return 0;
1682 }
1683
1684 return 1;
1685}
1686
1687static int as_may_queue(request_queue_t *q, int rw, struct bio *bio)
1688{
1689 int ret = ELV_MQUEUE_MAY;
1690 struct as_data *ad = q->elevator->elevator_data;
1691 struct io_context *ioc;
1692 if (ad->antic_status == ANTIC_WAIT_REQ ||
1693 ad->antic_status == ANTIC_WAIT_NEXT) {
1694 ioc = as_get_io_context();
1695 if (ad->io_context == ioc)
1696 ret = ELV_MQUEUE_MUST;
1697 put_io_context(ioc);
1698 }
1699
1700 return ret;
1701}
1702
1703static void as_exit_queue(elevator_t *e)
1704{
1705 struct as_data *ad = e->elevator_data;
1706
1707 del_timer_sync(&ad->antic_timer);
1708 kblockd_flush();
1709
1710 BUG_ON(!list_empty(&ad->fifo_list[REQ_SYNC]));
1711 BUG_ON(!list_empty(&ad->fifo_list[REQ_ASYNC]));
1712
1713 mempool_destroy(ad->arq_pool);
1714 put_io_context(ad->io_context);
1715 kfree(ad->hash);
1716 kfree(ad);
1717}
1718
1719/*
1720 * initialize elevator private data (as_data), and alloc a arq for
1721 * each request on the free lists
1722 */
1723static int as_init_queue(request_queue_t *q, elevator_t *e)
1724{
1725 struct as_data *ad;
1726 int i;
1727
1728 if (!arq_pool)
1729 return -ENOMEM;
1730
1731 ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node);
1732 if (!ad)
1733 return -ENOMEM;
1734 memset(ad, 0, sizeof(*ad));
1735
1736 ad->q = q; /* Identify what queue the data belongs to */
1737
1738 ad->hash = kmalloc_node(sizeof(struct list_head)*AS_HASH_ENTRIES,
1739 GFP_KERNEL, q->node);
1740 if (!ad->hash) {
1741 kfree(ad);
1742 return -ENOMEM;
1743 }
1744
1745 ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
1746 mempool_free_slab, arq_pool, q->node);
1747 if (!ad->arq_pool) {
1748 kfree(ad->hash);
1749 kfree(ad);
1750 return -ENOMEM;
1751 }
1752
1753 /* anticipatory scheduling helpers */
1754 ad->antic_timer.function = as_antic_timeout;
1755 ad->antic_timer.data = (unsigned long)q;
1756 init_timer(&ad->antic_timer);
1757 INIT_WORK(&ad->antic_work, as_work_handler, q);
1758
1759 for (i = 0; i < AS_HASH_ENTRIES; i++)
1760 INIT_LIST_HEAD(&ad->hash[i]);
1761
1762 INIT_LIST_HEAD(&ad->fifo_list[REQ_SYNC]);
1763 INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]);
1764 ad->sort_list[REQ_SYNC] = RB_ROOT;
1765 ad->sort_list[REQ_ASYNC] = RB_ROOT;
1766 ad->fifo_expire[REQ_SYNC] = default_read_expire;
1767 ad->fifo_expire[REQ_ASYNC] = default_write_expire;
1768 ad->antic_expire = default_antic_expire;
1769 ad->batch_expire[REQ_SYNC] = default_read_batch_expire;
1770 ad->batch_expire[REQ_ASYNC] = default_write_batch_expire;
1771 e->elevator_data = ad;
1772
1773 ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC];
1774 ad->write_batch_count = ad->batch_expire[REQ_ASYNC] / 10;
1775 if (ad->write_batch_count < 2)
1776 ad->write_batch_count = 2;
1777
1778 return 0;
1779}
1780
1781/*
1782 * sysfs parts below
1783 */
1784struct as_fs_entry {
1785 struct attribute attr;
1786 ssize_t (*show)(struct as_data *, char *);
1787 ssize_t (*store)(struct as_data *, const char *, size_t);
1788};
1789
1790static ssize_t
1791as_var_show(unsigned int var, char *page)
1792{
1793 return sprintf(page, "%d\n", var);
1794}
1795
1796static ssize_t
1797as_var_store(unsigned long *var, const char *page, size_t count)
1798{
1799 char *p = (char *) page;
1800
1801 *var = simple_strtoul(p, &p, 10);
1802 return count;
1803}
1804
1805static ssize_t as_est_show(struct as_data *ad, char *page)
1806{
1807 int pos = 0;
1808
1809 pos += sprintf(page+pos, "%lu %% exit probability\n", 100*ad->exit_prob/256);
1810 pos += sprintf(page+pos, "%lu ms new thinktime\n", ad->new_ttime_mean);
1811 pos += sprintf(page+pos, "%llu sectors new seek distance\n", (unsigned long long)ad->new_seek_mean);
1812
1813 return pos;
1814}
1815
1816#define SHOW_FUNCTION(__FUNC, __VAR) \
1817static ssize_t __FUNC(struct as_data *ad, char *page) \
1818{ \
1819 return as_var_show(jiffies_to_msecs((__VAR)), (page)); \
1820}
1821SHOW_FUNCTION(as_readexpire_show, ad->fifo_expire[REQ_SYNC]);
1822SHOW_FUNCTION(as_writeexpire_show, ad->fifo_expire[REQ_ASYNC]);
1823SHOW_FUNCTION(as_anticexpire_show, ad->antic_expire);
1824SHOW_FUNCTION(as_read_batchexpire_show, ad->batch_expire[REQ_SYNC]);
1825SHOW_FUNCTION(as_write_batchexpire_show, ad->batch_expire[REQ_ASYNC]);
1826#undef SHOW_FUNCTION
1827
1828#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX) \
1829static ssize_t __FUNC(struct as_data *ad, const char *page, size_t count) \
1830{ \
1831 int ret = as_var_store(__PTR, (page), count); \
1832 if (*(__PTR) < (MIN)) \
1833 *(__PTR) = (MIN); \
1834 else if (*(__PTR) > (MAX)) \
1835 *(__PTR) = (MAX); \
1836 *(__PTR) = msecs_to_jiffies(*(__PTR)); \
1837 return ret; \
1838}
1839STORE_FUNCTION(as_readexpire_store, &ad->fifo_expire[REQ_SYNC], 0, INT_MAX);
1840STORE_FUNCTION(as_writeexpire_store, &ad->fifo_expire[REQ_ASYNC], 0, INT_MAX);
1841STORE_FUNCTION(as_anticexpire_store, &ad->antic_expire, 0, INT_MAX);
1842STORE_FUNCTION(as_read_batchexpire_store,
1843 &ad->batch_expire[REQ_SYNC], 0, INT_MAX);
1844STORE_FUNCTION(as_write_batchexpire_store,
1845 &ad->batch_expire[REQ_ASYNC], 0, INT_MAX);
1846#undef STORE_FUNCTION
1847
1848static struct as_fs_entry as_est_entry = {
1849 .attr = {.name = "est_time", .mode = S_IRUGO },
1850 .show = as_est_show,
1851};
1852static struct as_fs_entry as_readexpire_entry = {
1853 .attr = {.name = "read_expire", .mode = S_IRUGO | S_IWUSR },
1854 .show = as_readexpire_show,
1855 .store = as_readexpire_store,
1856};
1857static struct as_fs_entry as_writeexpire_entry = {
1858 .attr = {.name = "write_expire", .mode = S_IRUGO | S_IWUSR },
1859 .show = as_writeexpire_show,
1860 .store = as_writeexpire_store,
1861};
1862static struct as_fs_entry as_anticexpire_entry = {
1863 .attr = {.name = "antic_expire", .mode = S_IRUGO | S_IWUSR },
1864 .show = as_anticexpire_show,
1865 .store = as_anticexpire_store,
1866};
1867static struct as_fs_entry as_read_batchexpire_entry = {
1868 .attr = {.name = "read_batch_expire", .mode = S_IRUGO | S_IWUSR },
1869 .show = as_read_batchexpire_show,
1870 .store = as_read_batchexpire_store,
1871};
1872static struct as_fs_entry as_write_batchexpire_entry = {
1873 .attr = {.name = "write_batch_expire", .mode = S_IRUGO | S_IWUSR },
1874 .show = as_write_batchexpire_show,
1875 .store = as_write_batchexpire_store,
1876};
1877
1878static struct attribute *default_attrs[] = {
1879 &as_est_entry.attr,
1880 &as_readexpire_entry.attr,
1881 &as_writeexpire_entry.attr,
1882 &as_anticexpire_entry.attr,
1883 &as_read_batchexpire_entry.attr,
1884 &as_write_batchexpire_entry.attr,
1885 NULL,
1886};
1887
1888#define to_as(atr) container_of((atr), struct as_fs_entry, attr)
1889
1890static ssize_t
1891as_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
1892{
1893 elevator_t *e = container_of(kobj, elevator_t, kobj);
1894 struct as_fs_entry *entry = to_as(attr);
1895
1896 if (!entry->show)
1897 return -EIO;
1898
1899 return entry->show(e->elevator_data, page);
1900}
1901
1902static ssize_t
1903as_attr_store(struct kobject *kobj, struct attribute *attr,
1904 const char *page, size_t length)
1905{
1906 elevator_t *e = container_of(kobj, elevator_t, kobj);
1907 struct as_fs_entry *entry = to_as(attr);
1908
1909 if (!entry->store)
1910 return -EIO;
1911
1912 return entry->store(e->elevator_data, page, length);
1913}
1914
1915static struct sysfs_ops as_sysfs_ops = {
1916 .show = as_attr_show,
1917 .store = as_attr_store,
1918};
1919
1920static struct kobj_type as_ktype = {
1921 .sysfs_ops = &as_sysfs_ops,
1922 .default_attrs = default_attrs,
1923};
1924
1925static struct elevator_type iosched_as = {
1926 .ops = {
1927 .elevator_merge_fn = as_merge,
1928 .elevator_merged_fn = as_merged_request,
1929 .elevator_merge_req_fn = as_merged_requests,
1930 .elevator_dispatch_fn = as_dispatch_request,
1931 .elevator_add_req_fn = as_add_request,
1932 .elevator_activate_req_fn = as_activate_request,
1933 .elevator_deactivate_req_fn = as_deactivate_request,
1934 .elevator_queue_empty_fn = as_queue_empty,
1935 .elevator_completed_req_fn = as_completed_request,
1936 .elevator_former_req_fn = as_former_request,
1937 .elevator_latter_req_fn = as_latter_request,
1938 .elevator_set_req_fn = as_set_request,
1939 .elevator_put_req_fn = as_put_request,
1940 .elevator_may_queue_fn = as_may_queue,
1941 .elevator_init_fn = as_init_queue,
1942 .elevator_exit_fn = as_exit_queue,
1943 },
1944
1945 .elevator_ktype = &as_ktype,
1946 .elevator_name = "anticipatory",
1947 .elevator_owner = THIS_MODULE,
1948};
1949
1950static int __init as_init(void)
1951{
1952 int ret;
1953
1954 arq_pool = kmem_cache_create("as_arq", sizeof(struct as_rq),
1955 0, 0, NULL, NULL);
1956 if (!arq_pool)
1957 return -ENOMEM;
1958
1959 ret = elv_register(&iosched_as);
1960 if (!ret) {
1961 /*
1962 * don't allow AS to get unregistered, since we would have
1963 * to browse all tasks in the system and release their
1964 * as_io_context first
1965 */
1966 __module_get(THIS_MODULE);
1967 return 0;
1968 }
1969
1970 kmem_cache_destroy(arq_pool);
1971 return ret;
1972}
1973
1974static void __exit as_exit(void)
1975{
1976 elv_unregister(&iosched_as);
1977 kmem_cache_destroy(arq_pool);
1978}
1979
1980module_init(as_init);
1981module_exit(as_exit);
1982
1983MODULE_AUTHOR("Nick Piggin");
1984MODULE_LICENSE("GPL");
1985MODULE_DESCRIPTION("anticipatory IO scheduler");
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 486b6e1c7dfb..a97c80b57737 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1096,14 +1096,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
1096cleanup1: 1096cleanup1:
1097 if (buff) { 1097 if (buff) {
1098 for(i=0; i<sg_used; i++) 1098 for(i=0; i<sg_used; i++)
1099 if(buff[i] != NULL) 1099 kfree(buff[i]);
1100 kfree(buff[i]);
1101 kfree(buff); 1100 kfree(buff);
1102 } 1101 }
1103 if (buff_size) 1102 kfree(buff_size);
1104 kfree(buff_size); 1103 kfree(ioc);
1105 if (ioc)
1106 kfree(ioc);
1107 return(status); 1104 return(status);
1108 } 1105 }
1109 default: 1106 default:
@@ -3034,8 +3031,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3034 return(1); 3031 return(1);
3035 3032
3036clean4: 3033clean4:
3037 if(hba[i]->cmd_pool_bits) 3034 kfree(hba[i]->cmd_pool_bits);
3038 kfree(hba[i]->cmd_pool_bits);
3039 if(hba[i]->cmd_pool) 3035 if(hba[i]->cmd_pool)
3040 pci_free_consistent(hba[i]->pdev, 3036 pci_free_consistent(hba[i]->pdev,
3041 NR_CMDS * sizeof(CommandList_struct), 3037 NR_CMDS * sizeof(CommandList_struct),
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
deleted file mode 100644
index ecacca9c877e..000000000000
--- a/drivers/block/cfq-iosched.c
+++ /dev/null
@@ -1,2428 +0,0 @@
1/*
2 * linux/drivers/block/cfq-iosched.c
3 *
4 * CFQ, or complete fairness queueing, disk scheduler.
5 *
6 * Based on ideas from a previously unfinished io
7 * scheduler (round robin per-process disk scheduling) and Andrea Arcangeli.
8 *
9 * Copyright (C) 2003 Jens Axboe <axboe@suse.de>
10 */
11#include <linux/kernel.h>
12#include <linux/fs.h>
13#include <linux/blkdev.h>
14#include <linux/elevator.h>
15#include <linux/bio.h>
16#include <linux/config.h>
17#include <linux/module.h>
18#include <linux/slab.h>
19#include <linux/init.h>
20#include <linux/compiler.h>
21#include <linux/hash.h>
22#include <linux/rbtree.h>
23#include <linux/mempool.h>
24#include <linux/ioprio.h>
25#include <linux/writeback.h>
26
27/*
28 * tunables
29 */
30static int cfq_quantum = 4; /* max queue in one round of service */
31static int cfq_queued = 8; /* minimum rq allocate limit per-queue*/
32static int cfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
33static int cfq_back_max = 16 * 1024; /* maximum backwards seek, in KiB */
34static int cfq_back_penalty = 2; /* penalty of a backwards seek */
35
36static int cfq_slice_sync = HZ / 10;
37static int cfq_slice_async = HZ / 25;
38static int cfq_slice_async_rq = 2;
39static int cfq_slice_idle = HZ / 100;
40
41#define CFQ_IDLE_GRACE (HZ / 10)
42#define CFQ_SLICE_SCALE (5)
43
44#define CFQ_KEY_ASYNC (0)
45#define CFQ_KEY_ANY (0xffff)
46
47/*
48 * disable queueing at the driver/hardware level
49 */
50static int cfq_max_depth = 2;
51
52/*
53 * for the hash of cfqq inside the cfqd
54 */
55#define CFQ_QHASH_SHIFT 6
56#define CFQ_QHASH_ENTRIES (1 << CFQ_QHASH_SHIFT)
57#define list_entry_qhash(entry) hlist_entry((entry), struct cfq_queue, cfq_hash)
58
59/*
60 * for the hash of crq inside the cfqq
61 */
62#define CFQ_MHASH_SHIFT 6
63#define CFQ_MHASH_BLOCK(sec) ((sec) >> 3)
64#define CFQ_MHASH_ENTRIES (1 << CFQ_MHASH_SHIFT)
65#define CFQ_MHASH_FN(sec) hash_long(CFQ_MHASH_BLOCK(sec), CFQ_MHASH_SHIFT)
66#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
67#define list_entry_hash(ptr) hlist_entry((ptr), struct cfq_rq, hash)
68
69#define list_entry_cfqq(ptr) list_entry((ptr), struct cfq_queue, cfq_list)
70#define list_entry_fifo(ptr) list_entry((ptr), struct request, queuelist)
71
72#define RQ_DATA(rq) (rq)->elevator_private
73
74/*
75 * rb-tree defines
76 */
77#define RB_NONE (2)
78#define RB_EMPTY(node) ((node)->rb_node == NULL)
79#define RB_CLEAR_COLOR(node) (node)->rb_color = RB_NONE
80#define RB_CLEAR(node) do { \
81 (node)->rb_parent = NULL; \
82 RB_CLEAR_COLOR((node)); \
83 (node)->rb_right = NULL; \
84 (node)->rb_left = NULL; \
85} while (0)
86#define RB_CLEAR_ROOT(root) ((root)->rb_node = NULL)
87#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node)
88#define rq_rb_key(rq) (rq)->sector
89
90static kmem_cache_t *crq_pool;
91static kmem_cache_t *cfq_pool;
92static kmem_cache_t *cfq_ioc_pool;
93
94#define CFQ_PRIO_LISTS IOPRIO_BE_NR
95#define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
96#define cfq_class_be(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_BE)
97#define cfq_class_rt(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_RT)
98
99#define ASYNC (0)
100#define SYNC (1)
101
102#define cfq_cfqq_dispatched(cfqq) \
103 ((cfqq)->on_dispatch[ASYNC] + (cfqq)->on_dispatch[SYNC])
104
105#define cfq_cfqq_class_sync(cfqq) ((cfqq)->key != CFQ_KEY_ASYNC)
106
107#define cfq_cfqq_sync(cfqq) \
108 (cfq_cfqq_class_sync(cfqq) || (cfqq)->on_dispatch[SYNC])
109
110/*
111 * Per block device queue structure
112 */
113struct cfq_data {
114 atomic_t ref;
115 request_queue_t *queue;
116
117 /*
118 * rr list of queues with requests and the count of them
119 */
120 struct list_head rr_list[CFQ_PRIO_LISTS];
121 struct list_head busy_rr;
122 struct list_head cur_rr;
123 struct list_head idle_rr;
124 unsigned int busy_queues;
125
126 /*
127 * non-ordered list of empty cfqq's
128 */
129 struct list_head empty_list;
130
131 /*
132 * cfqq lookup hash
133 */
134 struct hlist_head *cfq_hash;
135
136 /*
137 * global crq hash for all queues
138 */
139 struct hlist_head *crq_hash;
140
141 unsigned int max_queued;
142
143 mempool_t *crq_pool;
144
145 int rq_in_driver;
146
147 /*
148 * schedule slice state info
149 */
150 /*
151 * idle window management
152 */
153 struct timer_list idle_slice_timer;
154 struct work_struct unplug_work;
155
156 struct cfq_queue *active_queue;
157 struct cfq_io_context *active_cic;
158 int cur_prio, cur_end_prio;
159 unsigned int dispatch_slice;
160
161 struct timer_list idle_class_timer;
162
163 sector_t last_sector;
164 unsigned long last_end_request;
165
166 unsigned int rq_starved;
167
168 /*
169 * tunables, see top of file
170 */
171 unsigned int cfq_quantum;
172 unsigned int cfq_queued;
173 unsigned int cfq_fifo_expire[2];
174 unsigned int cfq_back_penalty;
175 unsigned int cfq_back_max;
176 unsigned int cfq_slice[2];
177 unsigned int cfq_slice_async_rq;
178 unsigned int cfq_slice_idle;
179 unsigned int cfq_max_depth;
180};
181
182/*
183 * Per process-grouping structure
184 */
185struct cfq_queue {
186 /* reference count */
187 atomic_t ref;
188 /* parent cfq_data */
189 struct cfq_data *cfqd;
190 /* cfqq lookup hash */
191 struct hlist_node cfq_hash;
192 /* hash key */
193 unsigned int key;
194 /* on either rr or empty list of cfqd */
195 struct list_head cfq_list;
196 /* sorted list of pending requests */
197 struct rb_root sort_list;
198 /* if fifo isn't expired, next request to serve */
199 struct cfq_rq *next_crq;
200 /* requests queued in sort_list */
201 int queued[2];
202 /* currently allocated requests */
203 int allocated[2];
204 /* fifo list of requests in sort_list */
205 struct list_head fifo;
206
207 unsigned long slice_start;
208 unsigned long slice_end;
209 unsigned long slice_left;
210 unsigned long service_last;
211
212 /* number of requests that are on the dispatch list */
213 int on_dispatch[2];
214
215 /* io prio of this group */
216 unsigned short ioprio, org_ioprio;
217 unsigned short ioprio_class, org_ioprio_class;
218
219 /* various state flags, see below */
220 unsigned int flags;
221};
222
223struct cfq_rq {
224 struct rb_node rb_node;
225 sector_t rb_key;
226 struct request *request;
227 struct hlist_node hash;
228
229 struct cfq_queue *cfq_queue;
230 struct cfq_io_context *io_context;
231
232 unsigned int crq_flags;
233};
234
235enum cfqq_state_flags {
236 CFQ_CFQQ_FLAG_on_rr = 0,
237 CFQ_CFQQ_FLAG_wait_request,
238 CFQ_CFQQ_FLAG_must_alloc,
239 CFQ_CFQQ_FLAG_must_alloc_slice,
240 CFQ_CFQQ_FLAG_must_dispatch,
241 CFQ_CFQQ_FLAG_fifo_expire,
242 CFQ_CFQQ_FLAG_idle_window,
243 CFQ_CFQQ_FLAG_prio_changed,
244 CFQ_CFQQ_FLAG_expired,
245};
246
247#define CFQ_CFQQ_FNS(name) \
248static inline void cfq_mark_cfqq_##name(struct cfq_queue *cfqq) \
249{ \
250 cfqq->flags |= (1 << CFQ_CFQQ_FLAG_##name); \
251} \
252static inline void cfq_clear_cfqq_##name(struct cfq_queue *cfqq) \
253{ \
254 cfqq->flags &= ~(1 << CFQ_CFQQ_FLAG_##name); \
255} \
256static inline int cfq_cfqq_##name(const struct cfq_queue *cfqq) \
257{ \
258 return (cfqq->flags & (1 << CFQ_CFQQ_FLAG_##name)) != 0; \
259}
260
261CFQ_CFQQ_FNS(on_rr);
262CFQ_CFQQ_FNS(wait_request);
263CFQ_CFQQ_FNS(must_alloc);
264CFQ_CFQQ_FNS(must_alloc_slice);
265CFQ_CFQQ_FNS(must_dispatch);
266CFQ_CFQQ_FNS(fifo_expire);
267CFQ_CFQQ_FNS(idle_window);
268CFQ_CFQQ_FNS(prio_changed);
269CFQ_CFQQ_FNS(expired);
270#undef CFQ_CFQQ_FNS
271
272enum cfq_rq_state_flags {
273 CFQ_CRQ_FLAG_is_sync = 0,
274};
275
276#define CFQ_CRQ_FNS(name) \
277static inline void cfq_mark_crq_##name(struct cfq_rq *crq) \
278{ \
279 crq->crq_flags |= (1 << CFQ_CRQ_FLAG_##name); \
280} \
281static inline void cfq_clear_crq_##name(struct cfq_rq *crq) \
282{ \
283 crq->crq_flags &= ~(1 << CFQ_CRQ_FLAG_##name); \
284} \
285static inline int cfq_crq_##name(const struct cfq_rq *crq) \
286{ \
287 return (crq->crq_flags & (1 << CFQ_CRQ_FLAG_##name)) != 0; \
288}
289
290CFQ_CRQ_FNS(is_sync);
291#undef CFQ_CRQ_FNS
292
293static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned int, unsigned short);
294static void cfq_dispatch_insert(request_queue_t *, struct cfq_rq *);
295static void cfq_put_cfqd(struct cfq_data *cfqd);
296
297#define process_sync(tsk) ((tsk)->flags & PF_SYNCWRITE)
298
299/*
300 * lots of deadline iosched dupes, can be abstracted later...
301 */
302static inline void cfq_del_crq_hash(struct cfq_rq *crq)
303{
304 hlist_del_init(&crq->hash);
305}
306
307static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq)
308{
309 const int hash_idx = CFQ_MHASH_FN(rq_hash_key(crq->request));
310
311 hlist_add_head(&crq->hash, &cfqd->crq_hash[hash_idx]);
312}
313
314static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset)
315{
316 struct hlist_head *hash_list = &cfqd->crq_hash[CFQ_MHASH_FN(offset)];
317 struct hlist_node *entry, *next;
318
319 hlist_for_each_safe(entry, next, hash_list) {
320 struct cfq_rq *crq = list_entry_hash(entry);
321 struct request *__rq = crq->request;
322
323 if (!rq_mergeable(__rq)) {
324 cfq_del_crq_hash(crq);
325 continue;
326 }
327
328 if (rq_hash_key(__rq) == offset)
329 return __rq;
330 }
331
332 return NULL;
333}
334
335/*
336 * scheduler run of queue, if there are requests pending and no one in the
337 * driver that will restart queueing
338 */
339static inline void cfq_schedule_dispatch(struct cfq_data *cfqd)
340{
341 if (!cfqd->rq_in_driver && cfqd->busy_queues)
342 kblockd_schedule_work(&cfqd->unplug_work);
343}
344
345static int cfq_queue_empty(request_queue_t *q)
346{
347 struct cfq_data *cfqd = q->elevator->elevator_data;
348
349 return !cfqd->busy_queues;
350}
351
352/*
353 * Lifted from AS - choose which of crq1 and crq2 that is best served now.
354 * We choose the request that is closest to the head right now. Distance
355 * behind the head are penalized and only allowed to a certain extent.
356 */
357static struct cfq_rq *
358cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2)
359{
360 sector_t last, s1, s2, d1 = 0, d2 = 0;
361 int r1_wrap = 0, r2_wrap = 0; /* requests are behind the disk head */
362 unsigned long back_max;
363
364 if (crq1 == NULL || crq1 == crq2)
365 return crq2;
366 if (crq2 == NULL)
367 return crq1;
368
369 if (cfq_crq_is_sync(crq1) && !cfq_crq_is_sync(crq2))
370 return crq1;
371 else if (cfq_crq_is_sync(crq2) && !cfq_crq_is_sync(crq1))
372 return crq2;
373
374 s1 = crq1->request->sector;
375 s2 = crq2->request->sector;
376
377 last = cfqd->last_sector;
378
379 /*
380 * by definition, 1KiB is 2 sectors
381 */
382 back_max = cfqd->cfq_back_max * 2;
383
384 /*
385 * Strict one way elevator _except_ in the case where we allow
386 * short backward seeks which are biased as twice the cost of a
387 * similar forward seek.
388 */
389 if (s1 >= last)
390 d1 = s1 - last;
391 else if (s1 + back_max >= last)
392 d1 = (last - s1) * cfqd->cfq_back_penalty;
393 else
394 r1_wrap = 1;
395
396 if (s2 >= last)
397 d2 = s2 - last;
398 else if (s2 + back_max >= last)
399 d2 = (last - s2) * cfqd->cfq_back_penalty;
400 else
401 r2_wrap = 1;
402
403 /* Found required data */
404 if (!r1_wrap && r2_wrap)
405 return crq1;
406 else if (!r2_wrap && r1_wrap)
407 return crq2;
408 else if (r1_wrap && r2_wrap) {
409 /* both behind the head */
410 if (s1 <= s2)
411 return crq1;
412 else
413 return crq2;
414 }
415
416 /* Both requests in front of the head */
417 if (d1 < d2)
418 return crq1;
419 else if (d2 < d1)
420 return crq2;
421 else {
422 if (s1 >= s2)
423 return crq1;
424 else
425 return crq2;
426 }
427}
428
429/*
430 * would be nice to take fifo expire time into account as well
431 */
432static struct cfq_rq *
433cfq_find_next_crq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
434 struct cfq_rq *last)
435{
436 struct cfq_rq *crq_next = NULL, *crq_prev = NULL;
437 struct rb_node *rbnext, *rbprev;
438
439 if (!(rbnext = rb_next(&last->rb_node))) {
440 rbnext = rb_first(&cfqq->sort_list);
441 if (rbnext == &last->rb_node)
442 rbnext = NULL;
443 }
444
445 rbprev = rb_prev(&last->rb_node);
446
447 if (rbprev)
448 crq_prev = rb_entry_crq(rbprev);
449 if (rbnext)
450 crq_next = rb_entry_crq(rbnext);
451
452 return cfq_choose_req(cfqd, crq_next, crq_prev);
453}
454
455static void cfq_update_next_crq(struct cfq_rq *crq)
456{
457 struct cfq_queue *cfqq = crq->cfq_queue;
458
459 if (cfqq->next_crq == crq)
460 cfqq->next_crq = cfq_find_next_crq(cfqq->cfqd, cfqq, crq);
461}
462
463static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted)
464{
465 struct cfq_data *cfqd = cfqq->cfqd;
466 struct list_head *list, *entry;
467
468 BUG_ON(!cfq_cfqq_on_rr(cfqq));
469
470 list_del(&cfqq->cfq_list);
471
472 if (cfq_class_rt(cfqq))
473 list = &cfqd->cur_rr;
474 else if (cfq_class_idle(cfqq))
475 list = &cfqd->idle_rr;
476 else {
477 /*
478 * if cfqq has requests in flight, don't allow it to be
479 * found in cfq_set_active_queue before it has finished them.
480 * this is done to increase fairness between a process that
481 * has lots of io pending vs one that only generates one
482 * sporadically or synchronously
483 */
484 if (cfq_cfqq_dispatched(cfqq))
485 list = &cfqd->busy_rr;
486 else
487 list = &cfqd->rr_list[cfqq->ioprio];
488 }
489
490 /*
491 * if queue was preempted, just add to front to be fair. busy_rr
492 * isn't sorted.
493 */
494 if (preempted || list == &cfqd->busy_rr) {
495 list_add(&cfqq->cfq_list, list);
496 return;
497 }
498
499 /*
500 * sort by when queue was last serviced
501 */
502 entry = list;
503 while ((entry = entry->prev) != list) {
504 struct cfq_queue *__cfqq = list_entry_cfqq(entry);
505
506 if (!__cfqq->service_last)
507 break;
508 if (time_before(__cfqq->service_last, cfqq->service_last))
509 break;
510 }
511
512 list_add(&cfqq->cfq_list, entry);
513}
514
515/*
516 * add to busy list of queues for service, trying to be fair in ordering
517 * the pending list according to last request service
518 */
519static inline void
520cfq_add_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
521{
522 BUG_ON(cfq_cfqq_on_rr(cfqq));
523 cfq_mark_cfqq_on_rr(cfqq);
524 cfqd->busy_queues++;
525
526 cfq_resort_rr_list(cfqq, 0);
527}
528
529static inline void
530cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq)
531{
532 BUG_ON(!cfq_cfqq_on_rr(cfqq));
533 cfq_clear_cfqq_on_rr(cfqq);
534 list_move(&cfqq->cfq_list, &cfqd->empty_list);
535
536 BUG_ON(!cfqd->busy_queues);
537 cfqd->busy_queues--;
538}
539
540/*
541 * rb tree support functions
542 */
543static inline void cfq_del_crq_rb(struct cfq_rq *crq)
544{
545 struct cfq_queue *cfqq = crq->cfq_queue;
546 struct cfq_data *cfqd = cfqq->cfqd;
547 const int sync = cfq_crq_is_sync(crq);
548
549 BUG_ON(!cfqq->queued[sync]);
550 cfqq->queued[sync]--;
551
552 cfq_update_next_crq(crq);
553
554 rb_erase(&crq->rb_node, &cfqq->sort_list);
555 RB_CLEAR_COLOR(&crq->rb_node);
556
557 if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY(&cfqq->sort_list))
558 cfq_del_cfqq_rr(cfqd, cfqq);
559}
560
561static struct cfq_rq *
562__cfq_add_crq_rb(struct cfq_rq *crq)
563{
564 struct rb_node **p = &crq->cfq_queue->sort_list.rb_node;
565 struct rb_node *parent = NULL;
566 struct cfq_rq *__crq;
567
568 while (*p) {
569 parent = *p;
570 __crq = rb_entry_crq(parent);
571
572 if (crq->rb_key < __crq->rb_key)
573 p = &(*p)->rb_left;
574 else if (crq->rb_key > __crq->rb_key)
575 p = &(*p)->rb_right;
576 else
577 return __crq;
578 }
579
580 rb_link_node(&crq->rb_node, parent, p);
581 return NULL;
582}
583
584static void cfq_add_crq_rb(struct cfq_rq *crq)
585{
586 struct cfq_queue *cfqq = crq->cfq_queue;
587 struct cfq_data *cfqd = cfqq->cfqd;
588 struct request *rq = crq->request;
589 struct cfq_rq *__alias;
590
591 crq->rb_key = rq_rb_key(rq);
592 cfqq->queued[cfq_crq_is_sync(crq)]++;
593
594 /*
595 * looks a little odd, but the first insert might return an alias.
596 * if that happens, put the alias on the dispatch list
597 */
598 while ((__alias = __cfq_add_crq_rb(crq)) != NULL)
599 cfq_dispatch_insert(cfqd->queue, __alias);
600
601 rb_insert_color(&crq->rb_node, &cfqq->sort_list);
602
603 if (!cfq_cfqq_on_rr(cfqq))
604 cfq_add_cfqq_rr(cfqd, cfqq);
605
606 /*
607 * check if this request is a better next-serve candidate
608 */
609 cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq);
610}
611
612static inline void
613cfq_reposition_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq)
614{
615 rb_erase(&crq->rb_node, &cfqq->sort_list);
616 cfqq->queued[cfq_crq_is_sync(crq)]--;
617
618 cfq_add_crq_rb(crq);
619}
620
621static struct request *cfq_find_rq_rb(struct cfq_data *cfqd, sector_t sector)
622
623{
624 struct cfq_queue *cfqq = cfq_find_cfq_hash(cfqd, current->pid, CFQ_KEY_ANY);
625 struct rb_node *n;
626
627 if (!cfqq)
628 goto out;
629
630 n = cfqq->sort_list.rb_node;
631 while (n) {
632 struct cfq_rq *crq = rb_entry_crq(n);
633
634 if (sector < crq->rb_key)
635 n = n->rb_left;
636 else if (sector > crq->rb_key)
637 n = n->rb_right;
638 else
639 return crq->request;
640 }
641
642out:
643 return NULL;
644}
645
646static void cfq_activate_request(request_queue_t *q, struct request *rq)
647{
648 struct cfq_data *cfqd = q->elevator->elevator_data;
649
650 cfqd->rq_in_driver++;
651}
652
653static void cfq_deactivate_request(request_queue_t *q, struct request *rq)
654{
655 struct cfq_data *cfqd = q->elevator->elevator_data;
656
657 WARN_ON(!cfqd->rq_in_driver);
658 cfqd->rq_in_driver--;
659}
660
661static void cfq_remove_request(struct request *rq)
662{
663 struct cfq_rq *crq = RQ_DATA(rq);
664
665 list_del_init(&rq->queuelist);
666 cfq_del_crq_rb(crq);
667 cfq_del_crq_hash(crq);
668}
669
670static int
671cfq_merge(request_queue_t *q, struct request **req, struct bio *bio)
672{
673 struct cfq_data *cfqd = q->elevator->elevator_data;
674 struct request *__rq;
675 int ret;
676
677 __rq = cfq_find_rq_hash(cfqd, bio->bi_sector);
678 if (__rq && elv_rq_merge_ok(__rq, bio)) {
679 ret = ELEVATOR_BACK_MERGE;
680 goto out;
681 }
682
683 __rq = cfq_find_rq_rb(cfqd, bio->bi_sector + bio_sectors(bio));
684 if (__rq && elv_rq_merge_ok(__rq, bio)) {
685 ret = ELEVATOR_FRONT_MERGE;
686 goto out;
687 }
688
689 return ELEVATOR_NO_MERGE;
690out:
691 *req = __rq;
692 return ret;
693}
694
695static void cfq_merged_request(request_queue_t *q, struct request *req)
696{
697 struct cfq_data *cfqd = q->elevator->elevator_data;
698 struct cfq_rq *crq = RQ_DATA(req);
699
700 cfq_del_crq_hash(crq);
701 cfq_add_crq_hash(cfqd, crq);
702
703 if (rq_rb_key(req) != crq->rb_key) {
704 struct cfq_queue *cfqq = crq->cfq_queue;
705
706 cfq_update_next_crq(crq);
707 cfq_reposition_crq_rb(cfqq, crq);
708 }
709}
710
711static void
712cfq_merged_requests(request_queue_t *q, struct request *rq,
713 struct request *next)
714{
715 cfq_merged_request(q, rq);
716
717 /*
718 * reposition in fifo if next is older than rq
719 */
720 if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
721 time_before(next->start_time, rq->start_time))
722 list_move(&rq->queuelist, &next->queuelist);
723
724 cfq_remove_request(next);
725}
726
727static inline void
728__cfq_set_active_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
729{
730 if (cfqq) {
731 /*
732 * stop potential idle class queues waiting service
733 */
734 del_timer(&cfqd->idle_class_timer);
735
736 cfqq->slice_start = jiffies;
737 cfqq->slice_end = 0;
738 cfqq->slice_left = 0;
739 cfq_clear_cfqq_must_alloc_slice(cfqq);
740 cfq_clear_cfqq_fifo_expire(cfqq);
741 cfq_clear_cfqq_expired(cfqq);
742 }
743
744 cfqd->active_queue = cfqq;
745}
746
747/*
748 * 0
749 * 0,1
750 * 0,1,2
751 * 0,1,2,3
752 * 0,1,2,3,4
753 * 0,1,2,3,4,5
754 * 0,1,2,3,4,5,6
755 * 0,1,2,3,4,5,6,7
756 */
757static int cfq_get_next_prio_level(struct cfq_data *cfqd)
758{
759 int prio, wrap;
760
761 prio = -1;
762 wrap = 0;
763 do {
764 int p;
765
766 for (p = cfqd->cur_prio; p <= cfqd->cur_end_prio; p++) {
767 if (!list_empty(&cfqd->rr_list[p])) {
768 prio = p;
769 break;
770 }
771 }
772
773 if (prio != -1)
774 break;
775 cfqd->cur_prio = 0;
776 if (++cfqd->cur_end_prio == CFQ_PRIO_LISTS) {
777 cfqd->cur_end_prio = 0;
778 if (wrap)
779 break;
780 wrap = 1;
781 }
782 } while (1);
783
784 if (unlikely(prio == -1))
785 return -1;
786
787 BUG_ON(prio >= CFQ_PRIO_LISTS);
788
789 list_splice_init(&cfqd->rr_list[prio], &cfqd->cur_rr);
790
791 cfqd->cur_prio = prio + 1;
792 if (cfqd->cur_prio > cfqd->cur_end_prio) {
793 cfqd->cur_end_prio = cfqd->cur_prio;
794 cfqd->cur_prio = 0;
795 }
796 if (cfqd->cur_end_prio == CFQ_PRIO_LISTS) {
797 cfqd->cur_prio = 0;
798 cfqd->cur_end_prio = 0;
799 }
800
801 return prio;
802}
803
804static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd)
805{
806 struct cfq_queue *cfqq;
807
808 /*
809 * if current queue is expired but not done with its requests yet,
810 * wait for that to happen
811 */
812 if ((cfqq = cfqd->active_queue) != NULL) {
813 if (cfq_cfqq_expired(cfqq) && cfq_cfqq_dispatched(cfqq))
814 return NULL;
815 }
816
817 /*
818 * if current list is non-empty, grab first entry. if it is empty,
819 * get next prio level and grab first entry then if any are spliced
820 */
821 if (!list_empty(&cfqd->cur_rr) || cfq_get_next_prio_level(cfqd) != -1)
822 cfqq = list_entry_cfqq(cfqd->cur_rr.next);
823
824 /*
825 * if we have idle queues and no rt or be queues had pending
826 * requests, either allow immediate service if the grace period
827 * has passed or arm the idle grace timer
828 */
829 if (!cfqq && !list_empty(&cfqd->idle_rr)) {
830 unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE;
831
832 if (time_after_eq(jiffies, end))
833 cfqq = list_entry_cfqq(cfqd->idle_rr.next);
834 else
835 mod_timer(&cfqd->idle_class_timer, end);
836 }
837
838 __cfq_set_active_queue(cfqd, cfqq);
839 return cfqq;
840}
841
842/*
843 * current cfqq expired its slice (or was too idle), select new one
844 */
845static void
846__cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
847 int preempted)
848{
849 unsigned long now = jiffies;
850
851 if (cfq_cfqq_wait_request(cfqq))
852 del_timer(&cfqd->idle_slice_timer);
853
854 if (!preempted && !cfq_cfqq_dispatched(cfqq))
855 cfqq->service_last = now;
856
857 cfq_clear_cfqq_must_dispatch(cfqq);
858 cfq_clear_cfqq_wait_request(cfqq);
859
860 /*
861 * store what was left of this slice, if the queue idled out
862 * or was preempted
863 */
864 if (time_after(now, cfqq->slice_end))
865 cfqq->slice_left = now - cfqq->slice_end;
866 else
867 cfqq->slice_left = 0;
868
869 if (cfq_cfqq_on_rr(cfqq))
870 cfq_resort_rr_list(cfqq, preempted);
871
872 if (cfqq == cfqd->active_queue)
873 cfqd->active_queue = NULL;
874
875 if (cfqd->active_cic) {
876 put_io_context(cfqd->active_cic->ioc);
877 cfqd->active_cic = NULL;
878 }
879
880 cfqd->dispatch_slice = 0;
881}
882
883static inline void cfq_slice_expired(struct cfq_data *cfqd, int preempted)
884{
885 struct cfq_queue *cfqq = cfqd->active_queue;
886
887 if (cfqq) {
888 /*
889 * use deferred expiry, if there are requests in progress as
890 * not to disturb the slice of the next queue
891 */
892 if (cfq_cfqq_dispatched(cfqq))
893 cfq_mark_cfqq_expired(cfqq);
894 else
895 __cfq_slice_expired(cfqd, cfqq, preempted);
896 }
897}
898
899static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq)
900
901{
902 WARN_ON(!RB_EMPTY(&cfqq->sort_list));
903 WARN_ON(cfqq != cfqd->active_queue);
904
905 /*
906 * idle is disabled, either manually or by past process history
907 */
908 if (!cfqd->cfq_slice_idle)
909 return 0;
910 if (!cfq_cfqq_idle_window(cfqq))
911 return 0;
912 /*
913 * task has exited, don't wait
914 */
915 if (cfqd->active_cic && !cfqd->active_cic->ioc->task)
916 return 0;
917
918 cfq_mark_cfqq_must_dispatch(cfqq);
919 cfq_mark_cfqq_wait_request(cfqq);
920
921 if (!timer_pending(&cfqd->idle_slice_timer)) {
922 unsigned long slice_left = min(cfqq->slice_end - 1, (unsigned long) cfqd->cfq_slice_idle);
923
924 cfqd->idle_slice_timer.expires = jiffies + slice_left;
925 add_timer(&cfqd->idle_slice_timer);
926 }
927
928 return 1;
929}
930
931static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq)
932{
933 struct cfq_data *cfqd = q->elevator->elevator_data;
934 struct cfq_queue *cfqq = crq->cfq_queue;
935
936 cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq);
937 cfq_remove_request(crq->request);
938 cfqq->on_dispatch[cfq_crq_is_sync(crq)]++;
939 elv_dispatch_sort(q, crq->request);
940}
941
942/*
943 * return expired entry, or NULL to just start from scratch in rbtree
944 */
945static inline struct cfq_rq *cfq_check_fifo(struct cfq_queue *cfqq)
946{
947 struct cfq_data *cfqd = cfqq->cfqd;
948 struct request *rq;
949 struct cfq_rq *crq;
950
951 if (cfq_cfqq_fifo_expire(cfqq))
952 return NULL;
953
954 if (!list_empty(&cfqq->fifo)) {
955 int fifo = cfq_cfqq_class_sync(cfqq);
956
957 crq = RQ_DATA(list_entry_fifo(cfqq->fifo.next));
958 rq = crq->request;
959 if (time_after(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) {
960 cfq_mark_cfqq_fifo_expire(cfqq);
961 return crq;
962 }
963 }
964
965 return NULL;
966}
967
968/*
969 * Scale schedule slice based on io priority. Use the sync time slice only
970 * if a queue is marked sync and has sync io queued. A sync queue with async
971 * io only, should not get full sync slice length.
972 */
973static inline int
974cfq_prio_to_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
975{
976 const int base_slice = cfqd->cfq_slice[cfq_cfqq_sync(cfqq)];
977
978 WARN_ON(cfqq->ioprio >= IOPRIO_BE_NR);
979
980 return base_slice + (base_slice/CFQ_SLICE_SCALE * (4 - cfqq->ioprio));
981}
982
983static inline void
984cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
985{
986 cfqq->slice_end = cfq_prio_to_slice(cfqd, cfqq) + jiffies;
987}
988
989static inline int
990cfq_prio_to_maxrq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
991{
992 const int base_rq = cfqd->cfq_slice_async_rq;
993
994 WARN_ON(cfqq->ioprio >= IOPRIO_BE_NR);
995
996 return 2 * (base_rq + base_rq * (CFQ_PRIO_LISTS - 1 - cfqq->ioprio));
997}
998
999/*
1000 * get next queue for service
1001 */
1002static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd, int force)
1003{
1004 unsigned long now = jiffies;
1005 struct cfq_queue *cfqq;
1006
1007 cfqq = cfqd->active_queue;
1008 if (!cfqq)
1009 goto new_queue;
1010
1011 if (cfq_cfqq_expired(cfqq))
1012 goto new_queue;
1013
1014 /*
1015 * slice has expired
1016 */
1017 if (!cfq_cfqq_must_dispatch(cfqq) && time_after(now, cfqq->slice_end))
1018 goto expire;
1019
1020 /*
1021 * if queue has requests, dispatch one. if not, check if
1022 * enough slice is left to wait for one
1023 */
1024 if (!RB_EMPTY(&cfqq->sort_list))
1025 goto keep_queue;
1026 else if (!force && cfq_cfqq_class_sync(cfqq) &&
1027 time_before(now, cfqq->slice_end)) {
1028 if (cfq_arm_slice_timer(cfqd, cfqq))
1029 return NULL;
1030 }
1031
1032expire:
1033 cfq_slice_expired(cfqd, 0);
1034new_queue:
1035 cfqq = cfq_set_active_queue(cfqd);
1036keep_queue:
1037 return cfqq;
1038}
1039
1040static int
1041__cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1042 int max_dispatch)
1043{
1044 int dispatched = 0;
1045
1046 BUG_ON(RB_EMPTY(&cfqq->sort_list));
1047
1048 do {
1049 struct cfq_rq *crq;
1050
1051 /*
1052 * follow expired path, else get first next available
1053 */
1054 if ((crq = cfq_check_fifo(cfqq)) == NULL)
1055 crq = cfqq->next_crq;
1056
1057 /*
1058 * finally, insert request into driver dispatch list
1059 */
1060 cfq_dispatch_insert(cfqd->queue, crq);
1061
1062 cfqd->dispatch_slice++;
1063 dispatched++;
1064
1065 if (!cfqd->active_cic) {
1066 atomic_inc(&crq->io_context->ioc->refcount);
1067 cfqd->active_cic = crq->io_context;
1068 }
1069
1070 if (RB_EMPTY(&cfqq->sort_list))
1071 break;
1072
1073 } while (dispatched < max_dispatch);
1074
1075 /*
1076 * if slice end isn't set yet, set it. if at least one request was
1077 * sync, use the sync time slice value
1078 */
1079 if (!cfqq->slice_end)
1080 cfq_set_prio_slice(cfqd, cfqq);
1081
1082 /*
1083 * expire an async queue immediately if it has used up its slice. idle
1084 * queue always expire after 1 dispatch round.
1085 */
1086 if ((!cfq_cfqq_sync(cfqq) &&
1087 cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) ||
1088 cfq_class_idle(cfqq))
1089 cfq_slice_expired(cfqd, 0);
1090
1091 return dispatched;
1092}
1093
1094static int
1095cfq_dispatch_requests(request_queue_t *q, int force)
1096{
1097 struct cfq_data *cfqd = q->elevator->elevator_data;
1098 struct cfq_queue *cfqq;
1099
1100 if (!cfqd->busy_queues)
1101 return 0;
1102
1103 cfqq = cfq_select_queue(cfqd, force);
1104 if (cfqq) {
1105 int max_dispatch;
1106
1107 /*
1108 * if idle window is disabled, allow queue buildup
1109 */
1110 if (!cfq_cfqq_idle_window(cfqq) &&
1111 cfqd->rq_in_driver >= cfqd->cfq_max_depth)
1112 return 0;
1113
1114 cfq_clear_cfqq_must_dispatch(cfqq);
1115 cfq_clear_cfqq_wait_request(cfqq);
1116 del_timer(&cfqd->idle_slice_timer);
1117
1118 if (!force) {
1119 max_dispatch = cfqd->cfq_quantum;
1120 if (cfq_class_idle(cfqq))
1121 max_dispatch = 1;
1122 } else
1123 max_dispatch = INT_MAX;
1124
1125 return __cfq_dispatch_requests(cfqd, cfqq, max_dispatch);
1126 }
1127
1128 return 0;
1129}
1130
1131/*
1132 * task holds one reference to the queue, dropped when task exits. each crq
1133 * in-flight on this queue also holds a reference, dropped when crq is freed.
1134 *
1135 * queue lock must be held here.
1136 */
1137static void cfq_put_queue(struct cfq_queue *cfqq)
1138{
1139 struct cfq_data *cfqd = cfqq->cfqd;
1140
1141 BUG_ON(atomic_read(&cfqq->ref) <= 0);
1142
1143 if (!atomic_dec_and_test(&cfqq->ref))
1144 return;
1145
1146 BUG_ON(rb_first(&cfqq->sort_list));
1147 BUG_ON(cfqq->allocated[READ] + cfqq->allocated[WRITE]);
1148 BUG_ON(cfq_cfqq_on_rr(cfqq));
1149
1150 if (unlikely(cfqd->active_queue == cfqq)) {
1151 __cfq_slice_expired(cfqd, cfqq, 0);
1152 cfq_schedule_dispatch(cfqd);
1153 }
1154
1155 cfq_put_cfqd(cfqq->cfqd);
1156
1157 /*
1158 * it's on the empty list and still hashed
1159 */
1160 list_del(&cfqq->cfq_list);
1161 hlist_del(&cfqq->cfq_hash);
1162 kmem_cache_free(cfq_pool, cfqq);
1163}
1164
1165static inline struct cfq_queue *
1166__cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned int key, unsigned int prio,
1167 const int hashval)
1168{
1169 struct hlist_head *hash_list = &cfqd->cfq_hash[hashval];
1170 struct hlist_node *entry, *next;
1171
1172 hlist_for_each_safe(entry, next, hash_list) {
1173 struct cfq_queue *__cfqq = list_entry_qhash(entry);
1174 const unsigned short __p = IOPRIO_PRIO_VALUE(__cfqq->ioprio_class, __cfqq->ioprio);
1175
1176 if (__cfqq->key == key && (__p == prio || prio == CFQ_KEY_ANY))
1177 return __cfqq;
1178 }
1179
1180 return NULL;
1181}
1182
1183static struct cfq_queue *
1184cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned int key, unsigned short prio)
1185{
1186 return __cfq_find_cfq_hash(cfqd, key, prio, hash_long(key, CFQ_QHASH_SHIFT));
1187}
1188
1189static void cfq_free_io_context(struct cfq_io_context *cic)
1190{
1191 struct cfq_io_context *__cic;
1192 struct list_head *entry, *next;
1193
1194 list_for_each_safe(entry, next, &cic->list) {
1195 __cic = list_entry(entry, struct cfq_io_context, list);
1196 kmem_cache_free(cfq_ioc_pool, __cic);
1197 }
1198
1199 kmem_cache_free(cfq_ioc_pool, cic);
1200}
1201
1202/*
1203 * Called with interrupts disabled
1204 */
1205static void cfq_exit_single_io_context(struct cfq_io_context *cic)
1206{
1207 struct cfq_data *cfqd = cic->cfqq->cfqd;
1208 request_queue_t *q = cfqd->queue;
1209
1210 WARN_ON(!irqs_disabled());
1211
1212 spin_lock(q->queue_lock);
1213
1214 if (unlikely(cic->cfqq == cfqd->active_queue)) {
1215 __cfq_slice_expired(cfqd, cic->cfqq, 0);
1216 cfq_schedule_dispatch(cfqd);
1217 }
1218
1219 cfq_put_queue(cic->cfqq);
1220 cic->cfqq = NULL;
1221 spin_unlock(q->queue_lock);
1222}
1223
1224/*
1225 * Another task may update the task cic list, if it is doing a queue lookup
1226 * on its behalf. cfq_cic_lock excludes such concurrent updates
1227 */
1228static void cfq_exit_io_context(struct cfq_io_context *cic)
1229{
1230 struct cfq_io_context *__cic;
1231 struct list_head *entry;
1232 unsigned long flags;
1233
1234 local_irq_save(flags);
1235
1236 /*
1237 * put the reference this task is holding to the various queues
1238 */
1239 list_for_each(entry, &cic->list) {
1240 __cic = list_entry(entry, struct cfq_io_context, list);
1241 cfq_exit_single_io_context(__cic);
1242 }
1243
1244 cfq_exit_single_io_context(cic);
1245 local_irq_restore(flags);
1246}
1247
1248static struct cfq_io_context *
1249cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask)
1250{
1251 struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask);
1252
1253 if (cic) {
1254 INIT_LIST_HEAD(&cic->list);
1255 cic->cfqq = NULL;
1256 cic->key = NULL;
1257 cic->last_end_request = jiffies;
1258 cic->ttime_total = 0;
1259 cic->ttime_samples = 0;
1260 cic->ttime_mean = 0;
1261 cic->dtor = cfq_free_io_context;
1262 cic->exit = cfq_exit_io_context;
1263 }
1264
1265 return cic;
1266}
1267
1268static void cfq_init_prio_data(struct cfq_queue *cfqq)
1269{
1270 struct task_struct *tsk = current;
1271 int ioprio_class;
1272
1273 if (!cfq_cfqq_prio_changed(cfqq))
1274 return;
1275
1276 ioprio_class = IOPRIO_PRIO_CLASS(tsk->ioprio);
1277 switch (ioprio_class) {
1278 default:
1279 printk(KERN_ERR "cfq: bad prio %x\n", ioprio_class);
1280 case IOPRIO_CLASS_NONE:
1281 /*
1282 * no prio set, place us in the middle of the BE classes
1283 */
1284 cfqq->ioprio = task_nice_ioprio(tsk);
1285 cfqq->ioprio_class = IOPRIO_CLASS_BE;
1286 break;
1287 case IOPRIO_CLASS_RT:
1288 cfqq->ioprio = task_ioprio(tsk);
1289 cfqq->ioprio_class = IOPRIO_CLASS_RT;
1290 break;
1291 case IOPRIO_CLASS_BE:
1292 cfqq->ioprio = task_ioprio(tsk);
1293 cfqq->ioprio_class = IOPRIO_CLASS_BE;
1294 break;
1295 case IOPRIO_CLASS_IDLE:
1296 cfqq->ioprio_class = IOPRIO_CLASS_IDLE;
1297 cfqq->ioprio = 7;
1298 cfq_clear_cfqq_idle_window(cfqq);
1299 break;
1300 }
1301
1302 /*
1303 * keep track of original prio settings in case we have to temporarily
1304 * elevate the priority of this queue
1305 */
1306 cfqq->org_ioprio = cfqq->ioprio;
1307 cfqq->org_ioprio_class = cfqq->ioprio_class;
1308
1309 if (cfq_cfqq_on_rr(cfqq))
1310 cfq_resort_rr_list(cfqq, 0);
1311
1312 cfq_clear_cfqq_prio_changed(cfqq);
1313}
1314
1315static inline void changed_ioprio(struct cfq_queue *cfqq)
1316{
1317 if (cfqq) {
1318 struct cfq_data *cfqd = cfqq->cfqd;
1319
1320 spin_lock(cfqd->queue->queue_lock);
1321 cfq_mark_cfqq_prio_changed(cfqq);
1322 cfq_init_prio_data(cfqq);
1323 spin_unlock(cfqd->queue->queue_lock);
1324 }
1325}
1326
1327/*
1328 * callback from sys_ioprio_set, irqs are disabled
1329 */
1330static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio)
1331{
1332 struct cfq_io_context *cic = ioc->cic;
1333
1334 changed_ioprio(cic->cfqq);
1335
1336 list_for_each_entry(cic, &cic->list, list)
1337 changed_ioprio(cic->cfqq);
1338
1339 return 0;
1340}
1341
1342static struct cfq_queue *
1343cfq_get_queue(struct cfq_data *cfqd, unsigned int key, unsigned short ioprio,
1344 gfp_t gfp_mask)
1345{
1346 const int hashval = hash_long(key, CFQ_QHASH_SHIFT);
1347 struct cfq_queue *cfqq, *new_cfqq = NULL;
1348
1349retry:
1350 cfqq = __cfq_find_cfq_hash(cfqd, key, ioprio, hashval);
1351
1352 if (!cfqq) {
1353 if (new_cfqq) {
1354 cfqq = new_cfqq;
1355 new_cfqq = NULL;
1356 } else if (gfp_mask & __GFP_WAIT) {
1357 spin_unlock_irq(cfqd->queue->queue_lock);
1358 new_cfqq = kmem_cache_alloc(cfq_pool, gfp_mask);
1359 spin_lock_irq(cfqd->queue->queue_lock);
1360 goto retry;
1361 } else {
1362 cfqq = kmem_cache_alloc(cfq_pool, gfp_mask);
1363 if (!cfqq)
1364 goto out;
1365 }
1366
1367 memset(cfqq, 0, sizeof(*cfqq));
1368
1369 INIT_HLIST_NODE(&cfqq->cfq_hash);
1370 INIT_LIST_HEAD(&cfqq->cfq_list);
1371 RB_CLEAR_ROOT(&cfqq->sort_list);
1372 INIT_LIST_HEAD(&cfqq->fifo);
1373
1374 cfqq->key = key;
1375 hlist_add_head(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
1376 atomic_set(&cfqq->ref, 0);
1377 cfqq->cfqd = cfqd;
1378 atomic_inc(&cfqd->ref);
1379 cfqq->service_last = 0;
1380 /*
1381 * set ->slice_left to allow preemption for a new process
1382 */
1383 cfqq->slice_left = 2 * cfqd->cfq_slice_idle;
1384 cfq_mark_cfqq_idle_window(cfqq);
1385 cfq_mark_cfqq_prio_changed(cfqq);
1386 cfq_init_prio_data(cfqq);
1387 }
1388
1389 if (new_cfqq)
1390 kmem_cache_free(cfq_pool, new_cfqq);
1391
1392 atomic_inc(&cfqq->ref);
1393out:
1394 WARN_ON((gfp_mask & __GFP_WAIT) && !cfqq);
1395 return cfqq;
1396}
1397
1398/*
1399 * Setup general io context and cfq io context. There can be several cfq
1400 * io contexts per general io context, if this process is doing io to more
1401 * than one device managed by cfq. Note that caller is holding a reference to
1402 * cfqq, so we don't need to worry about it disappearing
1403 */
1404static struct cfq_io_context *
1405cfq_get_io_context(struct cfq_data *cfqd, pid_t pid, gfp_t gfp_mask)
1406{
1407 struct io_context *ioc = NULL;
1408 struct cfq_io_context *cic;
1409
1410 might_sleep_if(gfp_mask & __GFP_WAIT);
1411
1412 ioc = get_io_context(gfp_mask);
1413 if (!ioc)
1414 return NULL;
1415
1416 if ((cic = ioc->cic) == NULL) {
1417 cic = cfq_alloc_io_context(cfqd, gfp_mask);
1418
1419 if (cic == NULL)
1420 goto err;
1421
1422 /*
1423 * manually increment generic io_context usage count, it
1424 * cannot go away since we are already holding one ref to it
1425 */
1426 ioc->cic = cic;
1427 ioc->set_ioprio = cfq_ioc_set_ioprio;
1428 cic->ioc = ioc;
1429 cic->key = cfqd;
1430 atomic_inc(&cfqd->ref);
1431 } else {
1432 struct cfq_io_context *__cic;
1433
1434 /*
1435 * the first cic on the list is actually the head itself
1436 */
1437 if (cic->key == cfqd)
1438 goto out;
1439
1440 /*
1441 * cic exists, check if we already are there. linear search
1442 * should be ok here, the list will usually not be more than
1443 * 1 or a few entries long
1444 */
1445 list_for_each_entry(__cic, &cic->list, list) {
1446 /*
1447 * this process is already holding a reference to
1448 * this queue, so no need to get one more
1449 */
1450 if (__cic->key == cfqd) {
1451 cic = __cic;
1452 goto out;
1453 }
1454 }
1455
1456 /*
1457 * nope, process doesn't have a cic assoicated with this
1458 * cfqq yet. get a new one and add to list
1459 */
1460 __cic = cfq_alloc_io_context(cfqd, gfp_mask);
1461 if (__cic == NULL)
1462 goto err;
1463
1464 __cic->ioc = ioc;
1465 __cic->key = cfqd;
1466 atomic_inc(&cfqd->ref);
1467 list_add(&__cic->list, &cic->list);
1468 cic = __cic;
1469 }
1470
1471out:
1472 return cic;
1473err:
1474 put_io_context(ioc);
1475 return NULL;
1476}
1477
1478static void
1479cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_io_context *cic)
1480{
1481 unsigned long elapsed, ttime;
1482
1483 /*
1484 * if this context already has stuff queued, thinktime is from
1485 * last queue not last end
1486 */
1487#if 0
1488 if (time_after(cic->last_end_request, cic->last_queue))
1489 elapsed = jiffies - cic->last_end_request;
1490 else
1491 elapsed = jiffies - cic->last_queue;
1492#else
1493 elapsed = jiffies - cic->last_end_request;
1494#endif
1495
1496 ttime = min(elapsed, 2UL * cfqd->cfq_slice_idle);
1497
1498 cic->ttime_samples = (7*cic->ttime_samples + 256) / 8;
1499 cic->ttime_total = (7*cic->ttime_total + 256*ttime) / 8;
1500 cic->ttime_mean = (cic->ttime_total + 128) / cic->ttime_samples;
1501}
1502
1503#define sample_valid(samples) ((samples) > 80)
1504
1505/*
1506 * Disable idle window if the process thinks too long or seeks so much that
1507 * it doesn't matter
1508 */
1509static void
1510cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1511 struct cfq_io_context *cic)
1512{
1513 int enable_idle = cfq_cfqq_idle_window(cfqq);
1514
1515 if (!cic->ioc->task || !cfqd->cfq_slice_idle)
1516 enable_idle = 0;
1517 else if (sample_valid(cic->ttime_samples)) {
1518 if (cic->ttime_mean > cfqd->cfq_slice_idle)
1519 enable_idle = 0;
1520 else
1521 enable_idle = 1;
1522 }
1523
1524 if (enable_idle)
1525 cfq_mark_cfqq_idle_window(cfqq);
1526 else
1527 cfq_clear_cfqq_idle_window(cfqq);
1528}
1529
1530
1531/*
1532 * Check if new_cfqq should preempt the currently active queue. Return 0 for
1533 * no or if we aren't sure, a 1 will cause a preempt.
1534 */
1535static int
1536cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
1537 struct cfq_rq *crq)
1538{
1539 struct cfq_queue *cfqq = cfqd->active_queue;
1540
1541 if (cfq_class_idle(new_cfqq))
1542 return 0;
1543
1544 if (!cfqq)
1545 return 1;
1546
1547 if (cfq_class_idle(cfqq))
1548 return 1;
1549 if (!cfq_cfqq_wait_request(new_cfqq))
1550 return 0;
1551 /*
1552 * if it doesn't have slice left, forget it
1553 */
1554 if (new_cfqq->slice_left < cfqd->cfq_slice_idle)
1555 return 0;
1556 if (cfq_crq_is_sync(crq) && !cfq_cfqq_sync(cfqq))
1557 return 1;
1558
1559 return 0;
1560}
1561
1562/*
1563 * cfqq preempts the active queue. if we allowed preempt with no slice left,
1564 * let it have half of its nominal slice.
1565 */
1566static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1567{
1568 struct cfq_queue *__cfqq, *next;
1569
1570 list_for_each_entry_safe(__cfqq, next, &cfqd->cur_rr, cfq_list)
1571 cfq_resort_rr_list(__cfqq, 1);
1572
1573 if (!cfqq->slice_left)
1574 cfqq->slice_left = cfq_prio_to_slice(cfqd, cfqq) / 2;
1575
1576 cfqq->slice_end = cfqq->slice_left + jiffies;
1577 __cfq_slice_expired(cfqd, cfqq, 1);
1578 __cfq_set_active_queue(cfqd, cfqq);
1579}
1580
1581/*
1582 * should really be a ll_rw_blk.c helper
1583 */
1584static void cfq_start_queueing(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1585{
1586 request_queue_t *q = cfqd->queue;
1587
1588 if (!blk_queue_plugged(q))
1589 q->request_fn(q);
1590 else
1591 __generic_unplug_device(q);
1592}
1593
1594/*
1595 * Called when a new fs request (crq) is added (to cfqq). Check if there's
1596 * something we should do about it
1597 */
1598static void
1599cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1600 struct cfq_rq *crq)
1601{
1602 struct cfq_io_context *cic;
1603
1604 cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq);
1605
1606 /*
1607 * we never wait for an async request and we don't allow preemption
1608 * of an async request. so just return early
1609 */
1610 if (!cfq_crq_is_sync(crq))
1611 return;
1612
1613 cic = crq->io_context;
1614
1615 cfq_update_io_thinktime(cfqd, cic);
1616 cfq_update_idle_window(cfqd, cfqq, cic);
1617
1618 cic->last_queue = jiffies;
1619
1620 if (cfqq == cfqd->active_queue) {
1621 /*
1622 * if we are waiting for a request for this queue, let it rip
1623 * immediately and flag that we must not expire this queue
1624 * just now
1625 */
1626 if (cfq_cfqq_wait_request(cfqq)) {
1627 cfq_mark_cfqq_must_dispatch(cfqq);
1628 del_timer(&cfqd->idle_slice_timer);
1629 cfq_start_queueing(cfqd, cfqq);
1630 }
1631 } else if (cfq_should_preempt(cfqd, cfqq, crq)) {
1632 /*
1633 * not the active queue - expire current slice if it is
1634 * idle and has expired it's mean thinktime or this new queue
1635 * has some old slice time left and is of higher priority
1636 */
1637 cfq_preempt_queue(cfqd, cfqq);
1638 cfq_mark_cfqq_must_dispatch(cfqq);
1639 cfq_start_queueing(cfqd, cfqq);
1640 }
1641}
1642
1643static void cfq_insert_request(request_queue_t *q, struct request *rq)
1644{
1645 struct cfq_data *cfqd = q->elevator->elevator_data;
1646 struct cfq_rq *crq = RQ_DATA(rq);
1647 struct cfq_queue *cfqq = crq->cfq_queue;
1648
1649 cfq_init_prio_data(cfqq);
1650
1651 cfq_add_crq_rb(crq);
1652
1653 list_add_tail(&rq->queuelist, &cfqq->fifo);
1654
1655 if (rq_mergeable(rq))
1656 cfq_add_crq_hash(cfqd, crq);
1657
1658 cfq_crq_enqueued(cfqd, cfqq, crq);
1659}
1660
1661static void cfq_completed_request(request_queue_t *q, struct request *rq)
1662{
1663 struct cfq_rq *crq = RQ_DATA(rq);
1664 struct cfq_queue *cfqq = crq->cfq_queue;
1665 struct cfq_data *cfqd = cfqq->cfqd;
1666 const int sync = cfq_crq_is_sync(crq);
1667 unsigned long now;
1668
1669 now = jiffies;
1670
1671 WARN_ON(!cfqd->rq_in_driver);
1672 WARN_ON(!cfqq->on_dispatch[sync]);
1673 cfqd->rq_in_driver--;
1674 cfqq->on_dispatch[sync]--;
1675
1676 if (!cfq_class_idle(cfqq))
1677 cfqd->last_end_request = now;
1678
1679 if (!cfq_cfqq_dispatched(cfqq)) {
1680 if (cfq_cfqq_on_rr(cfqq)) {
1681 cfqq->service_last = now;
1682 cfq_resort_rr_list(cfqq, 0);
1683 }
1684 if (cfq_cfqq_expired(cfqq)) {
1685 __cfq_slice_expired(cfqd, cfqq, 0);
1686 cfq_schedule_dispatch(cfqd);
1687 }
1688 }
1689
1690 if (cfq_crq_is_sync(crq))
1691 crq->io_context->last_end_request = now;
1692}
1693
1694static struct request *
1695cfq_former_request(request_queue_t *q, struct request *rq)
1696{
1697 struct cfq_rq *crq = RQ_DATA(rq);
1698 struct rb_node *rbprev = rb_prev(&crq->rb_node);
1699
1700 if (rbprev)
1701 return rb_entry_crq(rbprev)->request;
1702
1703 return NULL;
1704}
1705
1706static struct request *
1707cfq_latter_request(request_queue_t *q, struct request *rq)
1708{
1709 struct cfq_rq *crq = RQ_DATA(rq);
1710 struct rb_node *rbnext = rb_next(&crq->rb_node);
1711
1712 if (rbnext)
1713 return rb_entry_crq(rbnext)->request;
1714
1715 return NULL;
1716}
1717
1718/*
1719 * we temporarily boost lower priority queues if they are holding fs exclusive
1720 * resources. they are boosted to normal prio (CLASS_BE/4)
1721 */
1722static void cfq_prio_boost(struct cfq_queue *cfqq)
1723{
1724 const int ioprio_class = cfqq->ioprio_class;
1725 const int ioprio = cfqq->ioprio;
1726
1727 if (has_fs_excl()) {
1728 /*
1729 * boost idle prio on transactions that would lock out other
1730 * users of the filesystem
1731 */
1732 if (cfq_class_idle(cfqq))
1733 cfqq->ioprio_class = IOPRIO_CLASS_BE;
1734 if (cfqq->ioprio > IOPRIO_NORM)
1735 cfqq->ioprio = IOPRIO_NORM;
1736 } else {
1737 /*
1738 * check if we need to unboost the queue
1739 */
1740 if (cfqq->ioprio_class != cfqq->org_ioprio_class)
1741 cfqq->ioprio_class = cfqq->org_ioprio_class;
1742 if (cfqq->ioprio != cfqq->org_ioprio)
1743 cfqq->ioprio = cfqq->org_ioprio;
1744 }
1745
1746 /*
1747 * refile between round-robin lists if we moved the priority class
1748 */
1749 if ((ioprio_class != cfqq->ioprio_class || ioprio != cfqq->ioprio) &&
1750 cfq_cfqq_on_rr(cfqq))
1751 cfq_resort_rr_list(cfqq, 0);
1752}
1753
1754static inline pid_t cfq_queue_pid(struct task_struct *task, int rw)
1755{
1756 if (rw == READ || process_sync(task))
1757 return task->pid;
1758
1759 return CFQ_KEY_ASYNC;
1760}
1761
1762static inline int
1763__cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1764 struct task_struct *task, int rw)
1765{
1766#if 1
1767 if ((cfq_cfqq_wait_request(cfqq) || cfq_cfqq_must_alloc(cfqq)) &&
1768 !cfq_cfqq_must_alloc_slice(cfqq)) {
1769 cfq_mark_cfqq_must_alloc_slice(cfqq);
1770 return ELV_MQUEUE_MUST;
1771 }
1772
1773 return ELV_MQUEUE_MAY;
1774#else
1775 if (!cfqq || task->flags & PF_MEMALLOC)
1776 return ELV_MQUEUE_MAY;
1777 if (!cfqq->allocated[rw] || cfq_cfqq_must_alloc(cfqq)) {
1778 if (cfq_cfqq_wait_request(cfqq))
1779 return ELV_MQUEUE_MUST;
1780
1781 /*
1782 * only allow 1 ELV_MQUEUE_MUST per slice, otherwise we
1783 * can quickly flood the queue with writes from a single task
1784 */
1785 if (rw == READ || !cfq_cfqq_must_alloc_slice(cfqq)) {
1786 cfq_mark_cfqq_must_alloc_slice(cfqq);
1787 return ELV_MQUEUE_MUST;
1788 }
1789
1790 return ELV_MQUEUE_MAY;
1791 }
1792 if (cfq_class_idle(cfqq))
1793 return ELV_MQUEUE_NO;
1794 if (cfqq->allocated[rw] >= cfqd->max_queued) {
1795 struct io_context *ioc = get_io_context(GFP_ATOMIC);
1796 int ret = ELV_MQUEUE_NO;
1797
1798 if (ioc && ioc->nr_batch_requests)
1799 ret = ELV_MQUEUE_MAY;
1800
1801 put_io_context(ioc);
1802 return ret;
1803 }
1804
1805 return ELV_MQUEUE_MAY;
1806#endif
1807}
1808
1809static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio)
1810{
1811 struct cfq_data *cfqd = q->elevator->elevator_data;
1812 struct task_struct *tsk = current;
1813 struct cfq_queue *cfqq;
1814
1815 /*
1816 * don't force setup of a queue from here, as a call to may_queue
1817 * does not necessarily imply that a request actually will be queued.
1818 * so just lookup a possibly existing queue, or return 'may queue'
1819 * if that fails
1820 */
1821 cfqq = cfq_find_cfq_hash(cfqd, cfq_queue_pid(tsk, rw), tsk->ioprio);
1822 if (cfqq) {
1823 cfq_init_prio_data(cfqq);
1824 cfq_prio_boost(cfqq);
1825
1826 return __cfq_may_queue(cfqd, cfqq, tsk, rw);
1827 }
1828
1829 return ELV_MQUEUE_MAY;
1830}
1831
1832static void cfq_check_waiters(request_queue_t *q, struct cfq_queue *cfqq)
1833{
1834 struct cfq_data *cfqd = q->elevator->elevator_data;
1835 struct request_list *rl = &q->rq;
1836
1837 if (cfqq->allocated[READ] <= cfqd->max_queued || cfqd->rq_starved) {
1838 smp_mb();
1839 if (waitqueue_active(&rl->wait[READ]))
1840 wake_up(&rl->wait[READ]);
1841 }
1842
1843 if (cfqq->allocated[WRITE] <= cfqd->max_queued || cfqd->rq_starved) {
1844 smp_mb();
1845 if (waitqueue_active(&rl->wait[WRITE]))
1846 wake_up(&rl->wait[WRITE]);
1847 }
1848}
1849
1850/*
1851 * queue lock held here
1852 */
1853static void cfq_put_request(request_queue_t *q, struct request *rq)
1854{
1855 struct cfq_data *cfqd = q->elevator->elevator_data;
1856 struct cfq_rq *crq = RQ_DATA(rq);
1857
1858 if (crq) {
1859 struct cfq_queue *cfqq = crq->cfq_queue;
1860 const int rw = rq_data_dir(rq);
1861
1862 BUG_ON(!cfqq->allocated[rw]);
1863 cfqq->allocated[rw]--;
1864
1865 put_io_context(crq->io_context->ioc);
1866
1867 mempool_free(crq, cfqd->crq_pool);
1868 rq->elevator_private = NULL;
1869
1870 cfq_check_waiters(q, cfqq);
1871 cfq_put_queue(cfqq);
1872 }
1873}
1874
1875/*
1876 * Allocate cfq data structures associated with this request.
1877 */
1878static int
1879cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
1880 gfp_t gfp_mask)
1881{
1882 struct cfq_data *cfqd = q->elevator->elevator_data;
1883 struct task_struct *tsk = current;
1884 struct cfq_io_context *cic;
1885 const int rw = rq_data_dir(rq);
1886 pid_t key = cfq_queue_pid(tsk, rw);
1887 struct cfq_queue *cfqq;
1888 struct cfq_rq *crq;
1889 unsigned long flags;
1890
1891 might_sleep_if(gfp_mask & __GFP_WAIT);
1892
1893 cic = cfq_get_io_context(cfqd, key, gfp_mask);
1894
1895 spin_lock_irqsave(q->queue_lock, flags);
1896
1897 if (!cic)
1898 goto queue_fail;
1899
1900 if (!cic->cfqq) {
1901 cfqq = cfq_get_queue(cfqd, key, tsk->ioprio, gfp_mask);
1902 if (!cfqq)
1903 goto queue_fail;
1904
1905 cic->cfqq = cfqq;
1906 } else
1907 cfqq = cic->cfqq;
1908
1909 cfqq->allocated[rw]++;
1910 cfq_clear_cfqq_must_alloc(cfqq);
1911 cfqd->rq_starved = 0;
1912 atomic_inc(&cfqq->ref);
1913 spin_unlock_irqrestore(q->queue_lock, flags);
1914
1915 crq = mempool_alloc(cfqd->crq_pool, gfp_mask);
1916 if (crq) {
1917 RB_CLEAR(&crq->rb_node);
1918 crq->rb_key = 0;
1919 crq->request = rq;
1920 INIT_HLIST_NODE(&crq->hash);
1921 crq->cfq_queue = cfqq;
1922 crq->io_context = cic;
1923
1924 if (rw == READ || process_sync(tsk))
1925 cfq_mark_crq_is_sync(crq);
1926 else
1927 cfq_clear_crq_is_sync(crq);
1928
1929 rq->elevator_private = crq;
1930 return 0;
1931 }
1932
1933 spin_lock_irqsave(q->queue_lock, flags);
1934 cfqq->allocated[rw]--;
1935 if (!(cfqq->allocated[0] + cfqq->allocated[1]))
1936 cfq_mark_cfqq_must_alloc(cfqq);
1937 cfq_put_queue(cfqq);
1938queue_fail:
1939 if (cic)
1940 put_io_context(cic->ioc);
1941 /*
1942 * mark us rq allocation starved. we need to kickstart the process
1943 * ourselves if there are no pending requests that can do it for us.
1944 * that would be an extremely rare OOM situation
1945 */
1946 cfqd->rq_starved = 1;
1947 cfq_schedule_dispatch(cfqd);
1948 spin_unlock_irqrestore(q->queue_lock, flags);
1949 return 1;
1950}
1951
1952static void cfq_kick_queue(void *data)
1953{
1954 request_queue_t *q = data;
1955 struct cfq_data *cfqd = q->elevator->elevator_data;
1956 unsigned long flags;
1957
1958 spin_lock_irqsave(q->queue_lock, flags);
1959
1960 if (cfqd->rq_starved) {
1961 struct request_list *rl = &q->rq;
1962
1963 /*
1964 * we aren't guaranteed to get a request after this, but we
1965 * have to be opportunistic
1966 */
1967 smp_mb();
1968 if (waitqueue_active(&rl->wait[READ]))
1969 wake_up(&rl->wait[READ]);
1970 if (waitqueue_active(&rl->wait[WRITE]))
1971 wake_up(&rl->wait[WRITE]);
1972 }
1973
1974 blk_remove_plug(q);
1975 q->request_fn(q);
1976 spin_unlock_irqrestore(q->queue_lock, flags);
1977}
1978
1979/*
1980 * Timer running if the active_queue is currently idling inside its time slice
1981 */
1982static void cfq_idle_slice_timer(unsigned long data)
1983{
1984 struct cfq_data *cfqd = (struct cfq_data *) data;
1985 struct cfq_queue *cfqq;
1986 unsigned long flags;
1987
1988 spin_lock_irqsave(cfqd->queue->queue_lock, flags);
1989
1990 if ((cfqq = cfqd->active_queue) != NULL) {
1991 unsigned long now = jiffies;
1992
1993 /*
1994 * expired
1995 */
1996 if (time_after(now, cfqq->slice_end))
1997 goto expire;
1998
1999 /*
2000 * only expire and reinvoke request handler, if there are
2001 * other queues with pending requests
2002 */
2003 if (!cfqd->busy_queues) {
2004 cfqd->idle_slice_timer.expires = min(now + cfqd->cfq_slice_idle, cfqq->slice_end);
2005 add_timer(&cfqd->idle_slice_timer);
2006 goto out_cont;
2007 }
2008
2009 /*
2010 * not expired and it has a request pending, let it dispatch
2011 */
2012 if (!RB_EMPTY(&cfqq->sort_list)) {
2013 cfq_mark_cfqq_must_dispatch(cfqq);
2014 goto out_kick;
2015 }
2016 }
2017expire:
2018 cfq_slice_expired(cfqd, 0);
2019out_kick:
2020 cfq_schedule_dispatch(cfqd);
2021out_cont:
2022 spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
2023}
2024
2025/*
2026 * Timer running if an idle class queue is waiting for service
2027 */
2028static void cfq_idle_class_timer(unsigned long data)
2029{
2030 struct cfq_data *cfqd = (struct cfq_data *) data;
2031 unsigned long flags, end;
2032
2033 spin_lock_irqsave(cfqd->queue->queue_lock, flags);
2034
2035 /*
2036 * race with a non-idle queue, reset timer
2037 */
2038 end = cfqd->last_end_request + CFQ_IDLE_GRACE;
2039 if (!time_after_eq(jiffies, end)) {
2040 cfqd->idle_class_timer.expires = end;
2041 add_timer(&cfqd->idle_class_timer);
2042 } else
2043 cfq_schedule_dispatch(cfqd);
2044
2045 spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
2046}
2047
2048static void cfq_shutdown_timer_wq(struct cfq_data *cfqd)
2049{
2050 del_timer_sync(&cfqd->idle_slice_timer);
2051 del_timer_sync(&cfqd->idle_class_timer);
2052 blk_sync_queue(cfqd->queue);
2053}
2054
2055static void cfq_put_cfqd(struct cfq_data *cfqd)
2056{
2057 request_queue_t *q = cfqd->queue;
2058
2059 if (!atomic_dec_and_test(&cfqd->ref))
2060 return;
2061
2062 cfq_shutdown_timer_wq(cfqd);
2063 blk_put_queue(q);
2064
2065 mempool_destroy(cfqd->crq_pool);
2066 kfree(cfqd->crq_hash);
2067 kfree(cfqd->cfq_hash);
2068 kfree(cfqd);
2069}
2070
2071static void cfq_exit_queue(elevator_t *e)
2072{
2073 struct cfq_data *cfqd = e->elevator_data;
2074
2075 cfq_shutdown_timer_wq(cfqd);
2076 cfq_put_cfqd(cfqd);
2077}
2078
2079static int cfq_init_queue(request_queue_t *q, elevator_t *e)
2080{
2081 struct cfq_data *cfqd;
2082 int i;
2083
2084 cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL);
2085 if (!cfqd)
2086 return -ENOMEM;
2087
2088 memset(cfqd, 0, sizeof(*cfqd));
2089
2090 for (i = 0; i < CFQ_PRIO_LISTS; i++)
2091 INIT_LIST_HEAD(&cfqd->rr_list[i]);
2092
2093 INIT_LIST_HEAD(&cfqd->busy_rr);
2094 INIT_LIST_HEAD(&cfqd->cur_rr);
2095 INIT_LIST_HEAD(&cfqd->idle_rr);
2096 INIT_LIST_HEAD(&cfqd->empty_list);
2097
2098 cfqd->crq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL);
2099 if (!cfqd->crq_hash)
2100 goto out_crqhash;
2101
2102 cfqd->cfq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL);
2103 if (!cfqd->cfq_hash)
2104 goto out_cfqhash;
2105
2106 cfqd->crq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, crq_pool);
2107 if (!cfqd->crq_pool)
2108 goto out_crqpool;
2109
2110 for (i = 0; i < CFQ_MHASH_ENTRIES; i++)
2111 INIT_HLIST_HEAD(&cfqd->crq_hash[i]);
2112 for (i = 0; i < CFQ_QHASH_ENTRIES; i++)
2113 INIT_HLIST_HEAD(&cfqd->cfq_hash[i]);
2114
2115 e->elevator_data = cfqd;
2116
2117 cfqd->queue = q;
2118 atomic_inc(&q->refcnt);
2119
2120 cfqd->max_queued = q->nr_requests / 4;
2121 q->nr_batching = cfq_queued;
2122
2123 init_timer(&cfqd->idle_slice_timer);
2124 cfqd->idle_slice_timer.function = cfq_idle_slice_timer;
2125 cfqd->idle_slice_timer.data = (unsigned long) cfqd;
2126
2127 init_timer(&cfqd->idle_class_timer);
2128 cfqd->idle_class_timer.function = cfq_idle_class_timer;
2129 cfqd->idle_class_timer.data = (unsigned long) cfqd;
2130
2131 INIT_WORK(&cfqd->unplug_work, cfq_kick_queue, q);
2132
2133 atomic_set(&cfqd->ref, 1);
2134
2135 cfqd->cfq_queued = cfq_queued;
2136 cfqd->cfq_quantum = cfq_quantum;
2137 cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
2138 cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1];
2139 cfqd->cfq_back_max = cfq_back_max;
2140 cfqd->cfq_back_penalty = cfq_back_penalty;
2141 cfqd->cfq_slice[0] = cfq_slice_async;
2142 cfqd->cfq_slice[1] = cfq_slice_sync;
2143 cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
2144 cfqd->cfq_slice_idle = cfq_slice_idle;
2145 cfqd->cfq_max_depth = cfq_max_depth;
2146
2147 return 0;
2148out_crqpool:
2149 kfree(cfqd->cfq_hash);
2150out_cfqhash:
2151 kfree(cfqd->crq_hash);
2152out_crqhash:
2153 kfree(cfqd);
2154 return -ENOMEM;
2155}
2156
2157static void cfq_slab_kill(void)
2158{
2159 if (crq_pool)
2160 kmem_cache_destroy(crq_pool);
2161 if (cfq_pool)
2162 kmem_cache_destroy(cfq_pool);
2163 if (cfq_ioc_pool)
2164 kmem_cache_destroy(cfq_ioc_pool);
2165}
2166
2167static int __init cfq_slab_setup(void)
2168{
2169 crq_pool = kmem_cache_create("crq_pool", sizeof(struct cfq_rq), 0, 0,
2170 NULL, NULL);
2171 if (!crq_pool)
2172 goto fail;
2173
2174 cfq_pool = kmem_cache_create("cfq_pool", sizeof(struct cfq_queue), 0, 0,
2175 NULL, NULL);
2176 if (!cfq_pool)
2177 goto fail;
2178
2179 cfq_ioc_pool = kmem_cache_create("cfq_ioc_pool",
2180 sizeof(struct cfq_io_context), 0, 0, NULL, NULL);
2181 if (!cfq_ioc_pool)
2182 goto fail;
2183
2184 return 0;
2185fail:
2186 cfq_slab_kill();
2187 return -ENOMEM;
2188}
2189
2190/*
2191 * sysfs parts below -->
2192 */
2193struct cfq_fs_entry {
2194 struct attribute attr;
2195 ssize_t (*show)(struct cfq_data *, char *);
2196 ssize_t (*store)(struct cfq_data *, const char *, size_t);
2197};
2198
2199static ssize_t
2200cfq_var_show(unsigned int var, char *page)
2201{
2202 return sprintf(page, "%d\n", var);
2203}
2204
2205static ssize_t
2206cfq_var_store(unsigned int *var, const char *page, size_t count)
2207{
2208 char *p = (char *) page;
2209
2210 *var = simple_strtoul(p, &p, 10);
2211 return count;
2212}
2213
2214#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
2215static ssize_t __FUNC(struct cfq_data *cfqd, char *page) \
2216{ \
2217 unsigned int __data = __VAR; \
2218 if (__CONV) \
2219 __data = jiffies_to_msecs(__data); \
2220 return cfq_var_show(__data, (page)); \
2221}
2222SHOW_FUNCTION(cfq_quantum_show, cfqd->cfq_quantum, 0);
2223SHOW_FUNCTION(cfq_queued_show, cfqd->cfq_queued, 0);
2224SHOW_FUNCTION(cfq_fifo_expire_sync_show, cfqd->cfq_fifo_expire[1], 1);
2225SHOW_FUNCTION(cfq_fifo_expire_async_show, cfqd->cfq_fifo_expire[0], 1);
2226SHOW_FUNCTION(cfq_back_max_show, cfqd->cfq_back_max, 0);
2227SHOW_FUNCTION(cfq_back_penalty_show, cfqd->cfq_back_penalty, 0);
2228SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1);
2229SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1);
2230SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
2231SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
2232SHOW_FUNCTION(cfq_max_depth_show, cfqd->cfq_max_depth, 0);
2233#undef SHOW_FUNCTION
2234
2235#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
2236static ssize_t __FUNC(struct cfq_data *cfqd, const char *page, size_t count) \
2237{ \
2238 unsigned int __data; \
2239 int ret = cfq_var_store(&__data, (page), count); \
2240 if (__data < (MIN)) \
2241 __data = (MIN); \
2242 else if (__data > (MAX)) \
2243 __data = (MAX); \
2244 if (__CONV) \
2245 *(__PTR) = msecs_to_jiffies(__data); \
2246 else \
2247 *(__PTR) = __data; \
2248 return ret; \
2249}
2250STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, UINT_MAX, 0);
2251STORE_FUNCTION(cfq_queued_store, &cfqd->cfq_queued, 1, UINT_MAX, 0);
2252STORE_FUNCTION(cfq_fifo_expire_sync_store, &cfqd->cfq_fifo_expire[1], 1, UINT_MAX, 1);
2253STORE_FUNCTION(cfq_fifo_expire_async_store, &cfqd->cfq_fifo_expire[0], 1, UINT_MAX, 1);
2254STORE_FUNCTION(cfq_back_max_store, &cfqd->cfq_back_max, 0, UINT_MAX, 0);
2255STORE_FUNCTION(cfq_back_penalty_store, &cfqd->cfq_back_penalty, 1, UINT_MAX, 0);
2256STORE_FUNCTION(cfq_slice_idle_store, &cfqd->cfq_slice_idle, 0, UINT_MAX, 1);
2257STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1);
2258STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1);
2259STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX, 0);
2260STORE_FUNCTION(cfq_max_depth_store, &cfqd->cfq_max_depth, 1, UINT_MAX, 0);
2261#undef STORE_FUNCTION
2262
2263static struct cfq_fs_entry cfq_quantum_entry = {
2264 .attr = {.name = "quantum", .mode = S_IRUGO | S_IWUSR },
2265 .show = cfq_quantum_show,
2266 .store = cfq_quantum_store,
2267};
2268static struct cfq_fs_entry cfq_queued_entry = {
2269 .attr = {.name = "queued", .mode = S_IRUGO | S_IWUSR },
2270 .show = cfq_queued_show,
2271 .store = cfq_queued_store,
2272};
2273static struct cfq_fs_entry cfq_fifo_expire_sync_entry = {
2274 .attr = {.name = "fifo_expire_sync", .mode = S_IRUGO | S_IWUSR },
2275 .show = cfq_fifo_expire_sync_show,
2276 .store = cfq_fifo_expire_sync_store,
2277};
2278static struct cfq_fs_entry cfq_fifo_expire_async_entry = {
2279 .attr = {.name = "fifo_expire_async", .mode = S_IRUGO | S_IWUSR },
2280 .show = cfq_fifo_expire_async_show,
2281 .store = cfq_fifo_expire_async_store,
2282};
2283static struct cfq_fs_entry cfq_back_max_entry = {
2284 .attr = {.name = "back_seek_max", .mode = S_IRUGO | S_IWUSR },
2285 .show = cfq_back_max_show,
2286 .store = cfq_back_max_store,
2287};
2288static struct cfq_fs_entry cfq_back_penalty_entry = {
2289 .attr = {.name = "back_seek_penalty", .mode = S_IRUGO | S_IWUSR },
2290 .show = cfq_back_penalty_show,
2291 .store = cfq_back_penalty_store,
2292};
2293static struct cfq_fs_entry cfq_slice_sync_entry = {
2294 .attr = {.name = "slice_sync", .mode = S_IRUGO | S_IWUSR },
2295 .show = cfq_slice_sync_show,
2296 .store = cfq_slice_sync_store,
2297};
2298static struct cfq_fs_entry cfq_slice_async_entry = {
2299 .attr = {.name = "slice_async", .mode = S_IRUGO | S_IWUSR },
2300 .show = cfq_slice_async_show,
2301 .store = cfq_slice_async_store,
2302};
2303static struct cfq_fs_entry cfq_slice_async_rq_entry = {
2304 .attr = {.name = "slice_async_rq", .mode = S_IRUGO | S_IWUSR },
2305 .show = cfq_slice_async_rq_show,
2306 .store = cfq_slice_async_rq_store,
2307};
2308static struct cfq_fs_entry cfq_slice_idle_entry = {
2309 .attr = {.name = "slice_idle", .mode = S_IRUGO | S_IWUSR },
2310 .show = cfq_slice_idle_show,
2311 .store = cfq_slice_idle_store,
2312};
2313static struct cfq_fs_entry cfq_max_depth_entry = {
2314 .attr = {.name = "max_depth", .mode = S_IRUGO | S_IWUSR },
2315 .show = cfq_max_depth_show,
2316 .store = cfq_max_depth_store,
2317};
2318
2319static struct attribute *default_attrs[] = {
2320 &cfq_quantum_entry.attr,
2321 &cfq_queued_entry.attr,
2322 &cfq_fifo_expire_sync_entry.attr,
2323 &cfq_fifo_expire_async_entry.attr,
2324 &cfq_back_max_entry.attr,
2325 &cfq_back_penalty_entry.attr,
2326 &cfq_slice_sync_entry.attr,
2327 &cfq_slice_async_entry.attr,
2328 &cfq_slice_async_rq_entry.attr,
2329 &cfq_slice_idle_entry.attr,
2330 &cfq_max_depth_entry.attr,
2331 NULL,
2332};
2333
2334#define to_cfq(atr) container_of((atr), struct cfq_fs_entry, attr)
2335
2336static ssize_t
2337cfq_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
2338{
2339 elevator_t *e = container_of(kobj, elevator_t, kobj);
2340 struct cfq_fs_entry *entry = to_cfq(attr);
2341
2342 if (!entry->show)
2343 return -EIO;
2344
2345 return entry->show(e->elevator_data, page);
2346}
2347
2348static ssize_t
2349cfq_attr_store(struct kobject *kobj, struct attribute *attr,
2350 const char *page, size_t length)
2351{
2352 elevator_t *e = container_of(kobj, elevator_t, kobj);
2353 struct cfq_fs_entry *entry = to_cfq(attr);
2354
2355 if (!entry->store)
2356 return -EIO;
2357
2358 return entry->store(e->elevator_data, page, length);
2359}
2360
2361static struct sysfs_ops cfq_sysfs_ops = {
2362 .show = cfq_attr_show,
2363 .store = cfq_attr_store,
2364};
2365
2366static struct kobj_type cfq_ktype = {
2367 .sysfs_ops = &cfq_sysfs_ops,
2368 .default_attrs = default_attrs,
2369};
2370
2371static struct elevator_type iosched_cfq = {
2372 .ops = {
2373 .elevator_merge_fn = cfq_merge,
2374 .elevator_merged_fn = cfq_merged_request,
2375 .elevator_merge_req_fn = cfq_merged_requests,
2376 .elevator_dispatch_fn = cfq_dispatch_requests,
2377 .elevator_add_req_fn = cfq_insert_request,
2378 .elevator_activate_req_fn = cfq_activate_request,
2379 .elevator_deactivate_req_fn = cfq_deactivate_request,
2380 .elevator_queue_empty_fn = cfq_queue_empty,
2381 .elevator_completed_req_fn = cfq_completed_request,
2382 .elevator_former_req_fn = cfq_former_request,
2383 .elevator_latter_req_fn = cfq_latter_request,
2384 .elevator_set_req_fn = cfq_set_request,
2385 .elevator_put_req_fn = cfq_put_request,
2386 .elevator_may_queue_fn = cfq_may_queue,
2387 .elevator_init_fn = cfq_init_queue,
2388 .elevator_exit_fn = cfq_exit_queue,
2389 },
2390 .elevator_ktype = &cfq_ktype,
2391 .elevator_name = "cfq",
2392 .elevator_owner = THIS_MODULE,
2393};
2394
2395static int __init cfq_init(void)
2396{
2397 int ret;
2398
2399 /*
2400 * could be 0 on HZ < 1000 setups
2401 */
2402 if (!cfq_slice_async)
2403 cfq_slice_async = 1;
2404 if (!cfq_slice_idle)
2405 cfq_slice_idle = 1;
2406
2407 if (cfq_slab_setup())
2408 return -ENOMEM;
2409
2410 ret = elv_register(&iosched_cfq);
2411 if (ret)
2412 cfq_slab_kill();
2413
2414 return ret;
2415}
2416
2417static void __exit cfq_exit(void)
2418{
2419 elv_unregister(&iosched_cfq);
2420 cfq_slab_kill();
2421}
2422
2423module_init(cfq_init);
2424module_exit(cfq_exit);
2425
2426MODULE_AUTHOR("Jens Axboe");
2427MODULE_LICENSE("GPL");
2428MODULE_DESCRIPTION("Completely Fair Queueing IO scheduler");
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
deleted file mode 100644
index 7929471d7df7..000000000000
--- a/drivers/block/deadline-iosched.c
+++ /dev/null
@@ -1,878 +0,0 @@
1/*
2 * linux/drivers/block/deadline-iosched.c
3 *
4 * Deadline i/o scheduler.
5 *
6 * Copyright (C) 2002 Jens Axboe <axboe@suse.de>
7 */
8#include <linux/kernel.h>
9#include <linux/fs.h>
10#include <linux/blkdev.h>
11#include <linux/elevator.h>
12#include <linux/bio.h>
13#include <linux/config.h>
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/init.h>
17#include <linux/compiler.h>
18#include <linux/hash.h>
19#include <linux/rbtree.h>
20
21/*
22 * See Documentation/block/deadline-iosched.txt
23 */
24static int read_expire = HZ / 2; /* max time before a read is submitted. */
25static int write_expire = 5 * HZ; /* ditto for writes, these limits are SOFT! */
26static int writes_starved = 2; /* max times reads can starve a write */
27static int fifo_batch = 16; /* # of sequential requests treated as one
28 by the above parameters. For throughput. */
29
30static const int deadline_hash_shift = 5;
31#define DL_HASH_BLOCK(sec) ((sec) >> 3)
32#define DL_HASH_FN(sec) (hash_long(DL_HASH_BLOCK((sec)), deadline_hash_shift))
33#define DL_HASH_ENTRIES (1 << deadline_hash_shift)
34#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors)
35#define list_entry_hash(ptr) list_entry((ptr), struct deadline_rq, hash)
36#define ON_HASH(drq) (drq)->on_hash
37
38struct deadline_data {
39 /*
40 * run time data
41 */
42
43 /*
44 * requests (deadline_rq s) are present on both sort_list and fifo_list
45 */
46 struct rb_root sort_list[2];
47 struct list_head fifo_list[2];
48
49 /*
50 * next in sort order. read, write or both are NULL
51 */
52 struct deadline_rq *next_drq[2];
53 struct list_head *hash; /* request hash */
54 unsigned int batching; /* number of sequential requests made */
55 sector_t last_sector; /* head position */
56 unsigned int starved; /* times reads have starved writes */
57
58 /*
59 * settings that change how the i/o scheduler behaves
60 */
61 int fifo_expire[2];
62 int fifo_batch;
63 int writes_starved;
64 int front_merges;
65
66 mempool_t *drq_pool;
67};
68
69/*
70 * pre-request data.
71 */
72struct deadline_rq {
73 /*
74 * rbtree index, key is the starting offset
75 */
76 struct rb_node rb_node;
77 sector_t rb_key;
78
79 struct request *request;
80
81 /*
82 * request hash, key is the ending offset (for back merge lookup)
83 */
84 struct list_head hash;
85 char on_hash;
86
87 /*
88 * expire fifo
89 */
90 struct list_head fifo;
91 unsigned long expires;
92};
93
94static void deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq);
95
96static kmem_cache_t *drq_pool;
97
98#define RQ_DATA(rq) ((struct deadline_rq *) (rq)->elevator_private)
99
100/*
101 * the back merge hash support functions
102 */
103static inline void __deadline_del_drq_hash(struct deadline_rq *drq)
104{
105 drq->on_hash = 0;
106 list_del_init(&drq->hash);
107}
108
109static inline void deadline_del_drq_hash(struct deadline_rq *drq)
110{
111 if (ON_HASH(drq))
112 __deadline_del_drq_hash(drq);
113}
114
115static inline void
116deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
117{
118 struct request *rq = drq->request;
119
120 BUG_ON(ON_HASH(drq));
121
122 drq->on_hash = 1;
123 list_add(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]);
124}
125
126/*
127 * move hot entry to front of chain
128 */
129static inline void
130deadline_hot_drq_hash(struct deadline_data *dd, struct deadline_rq *drq)
131{
132 struct request *rq = drq->request;
133 struct list_head *head = &dd->hash[DL_HASH_FN(rq_hash_key(rq))];
134
135 if (ON_HASH(drq) && drq->hash.prev != head) {
136 list_del(&drq->hash);
137 list_add(&drq->hash, head);
138 }
139}
140
141static struct request *
142deadline_find_drq_hash(struct deadline_data *dd, sector_t offset)
143{
144 struct list_head *hash_list = &dd->hash[DL_HASH_FN(offset)];
145 struct list_head *entry, *next = hash_list->next;
146
147 while ((entry = next) != hash_list) {
148 struct deadline_rq *drq = list_entry_hash(entry);
149 struct request *__rq = drq->request;
150
151 next = entry->next;
152
153 BUG_ON(!ON_HASH(drq));
154
155 if (!rq_mergeable(__rq)) {
156 __deadline_del_drq_hash(drq);
157 continue;
158 }
159
160 if (rq_hash_key(__rq) == offset)
161 return __rq;
162 }
163
164 return NULL;
165}
166
167/*
168 * rb tree support functions
169 */
170#define RB_NONE (2)
171#define RB_EMPTY(root) ((root)->rb_node == NULL)
172#define ON_RB(node) ((node)->rb_color != RB_NONE)
173#define RB_CLEAR(node) ((node)->rb_color = RB_NONE)
174#define rb_entry_drq(node) rb_entry((node), struct deadline_rq, rb_node)
175#define DRQ_RB_ROOT(dd, drq) (&(dd)->sort_list[rq_data_dir((drq)->request)])
176#define rq_rb_key(rq) (rq)->sector
177
178static struct deadline_rq *
179__deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
180{
181 struct rb_node **p = &DRQ_RB_ROOT(dd, drq)->rb_node;
182 struct rb_node *parent = NULL;
183 struct deadline_rq *__drq;
184
185 while (*p) {
186 parent = *p;
187 __drq = rb_entry_drq(parent);
188
189 if (drq->rb_key < __drq->rb_key)
190 p = &(*p)->rb_left;
191 else if (drq->rb_key > __drq->rb_key)
192 p = &(*p)->rb_right;
193 else
194 return __drq;
195 }
196
197 rb_link_node(&drq->rb_node, parent, p);
198 return NULL;
199}
200
201static void
202deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
203{
204 struct deadline_rq *__alias;
205
206 drq->rb_key = rq_rb_key(drq->request);
207
208retry:
209 __alias = __deadline_add_drq_rb(dd, drq);
210 if (!__alias) {
211 rb_insert_color(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
212 return;
213 }
214
215 deadline_move_request(dd, __alias);
216 goto retry;
217}
218
219static inline void
220deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq)
221{
222 const int data_dir = rq_data_dir(drq->request);
223
224 if (dd->next_drq[data_dir] == drq) {
225 struct rb_node *rbnext = rb_next(&drq->rb_node);
226
227 dd->next_drq[data_dir] = NULL;
228 if (rbnext)
229 dd->next_drq[data_dir] = rb_entry_drq(rbnext);
230 }
231
232 BUG_ON(!ON_RB(&drq->rb_node));
233 rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq));
234 RB_CLEAR(&drq->rb_node);
235}
236
237static struct request *
238deadline_find_drq_rb(struct deadline_data *dd, sector_t sector, int data_dir)
239{
240 struct rb_node *n = dd->sort_list[data_dir].rb_node;
241 struct deadline_rq *drq;
242
243 while (n) {
244 drq = rb_entry_drq(n);
245
246 if (sector < drq->rb_key)
247 n = n->rb_left;
248 else if (sector > drq->rb_key)
249 n = n->rb_right;
250 else
251 return drq->request;
252 }
253
254 return NULL;
255}
256
257/*
258 * deadline_find_first_drq finds the first (lowest sector numbered) request
259 * for the specified data_dir. Used to sweep back to the start of the disk
260 * (1-way elevator) after we process the last (highest sector) request.
261 */
262static struct deadline_rq *
263deadline_find_first_drq(struct deadline_data *dd, int data_dir)
264{
265 struct rb_node *n = dd->sort_list[data_dir].rb_node;
266
267 for (;;) {
268 if (n->rb_left == NULL)
269 return rb_entry_drq(n);
270
271 n = n->rb_left;
272 }
273}
274
275/*
276 * add drq to rbtree and fifo
277 */
278static void
279deadline_add_request(struct request_queue *q, struct request *rq)
280{
281 struct deadline_data *dd = q->elevator->elevator_data;
282 struct deadline_rq *drq = RQ_DATA(rq);
283
284 const int data_dir = rq_data_dir(drq->request);
285
286 deadline_add_drq_rb(dd, drq);
287 /*
288 * set expire time (only used for reads) and add to fifo list
289 */
290 drq->expires = jiffies + dd->fifo_expire[data_dir];
291 list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]);
292
293 if (rq_mergeable(rq))
294 deadline_add_drq_hash(dd, drq);
295}
296
297/*
298 * remove rq from rbtree, fifo, and hash
299 */
300static void deadline_remove_request(request_queue_t *q, struct request *rq)
301{
302 struct deadline_rq *drq = RQ_DATA(rq);
303 struct deadline_data *dd = q->elevator->elevator_data;
304
305 list_del_init(&drq->fifo);
306 deadline_del_drq_rb(dd, drq);
307 deadline_del_drq_hash(drq);
308}
309
310static int
311deadline_merge(request_queue_t *q, struct request **req, struct bio *bio)
312{
313 struct deadline_data *dd = q->elevator->elevator_data;
314 struct request *__rq;
315 int ret;
316
317 /*
318 * see if the merge hash can satisfy a back merge
319 */
320 __rq = deadline_find_drq_hash(dd, bio->bi_sector);
321 if (__rq) {
322 BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector);
323
324 if (elv_rq_merge_ok(__rq, bio)) {
325 ret = ELEVATOR_BACK_MERGE;
326 goto out;
327 }
328 }
329
330 /*
331 * check for front merge
332 */
333 if (dd->front_merges) {
334 sector_t rb_key = bio->bi_sector + bio_sectors(bio);
335
336 __rq = deadline_find_drq_rb(dd, rb_key, bio_data_dir(bio));
337 if (__rq) {
338 BUG_ON(rb_key != rq_rb_key(__rq));
339
340 if (elv_rq_merge_ok(__rq, bio)) {
341 ret = ELEVATOR_FRONT_MERGE;
342 goto out;
343 }
344 }
345 }
346
347 return ELEVATOR_NO_MERGE;
348out:
349 if (ret)
350 deadline_hot_drq_hash(dd, RQ_DATA(__rq));
351 *req = __rq;
352 return ret;
353}
354
355static void deadline_merged_request(request_queue_t *q, struct request *req)
356{
357 struct deadline_data *dd = q->elevator->elevator_data;
358 struct deadline_rq *drq = RQ_DATA(req);
359
360 /*
361 * hash always needs to be repositioned, key is end sector
362 */
363 deadline_del_drq_hash(drq);
364 deadline_add_drq_hash(dd, drq);
365
366 /*
367 * if the merge was a front merge, we need to reposition request
368 */
369 if (rq_rb_key(req) != drq->rb_key) {
370 deadline_del_drq_rb(dd, drq);
371 deadline_add_drq_rb(dd, drq);
372 }
373}
374
375static void
376deadline_merged_requests(request_queue_t *q, struct request *req,
377 struct request *next)
378{
379 struct deadline_data *dd = q->elevator->elevator_data;
380 struct deadline_rq *drq = RQ_DATA(req);
381 struct deadline_rq *dnext = RQ_DATA(next);
382
383 BUG_ON(!drq);
384 BUG_ON(!dnext);
385
386 /*
387 * reposition drq (this is the merged request) in hash, and in rbtree
388 * in case of a front merge
389 */
390 deadline_del_drq_hash(drq);
391 deadline_add_drq_hash(dd, drq);
392
393 if (rq_rb_key(req) != drq->rb_key) {
394 deadline_del_drq_rb(dd, drq);
395 deadline_add_drq_rb(dd, drq);
396 }
397
398 /*
399 * if dnext expires before drq, assign its expire time to drq
400 * and move into dnext position (dnext will be deleted) in fifo
401 */
402 if (!list_empty(&drq->fifo) && !list_empty(&dnext->fifo)) {
403 if (time_before(dnext->expires, drq->expires)) {
404 list_move(&drq->fifo, &dnext->fifo);
405 drq->expires = dnext->expires;
406 }
407 }
408
409 /*
410 * kill knowledge of next, this one is a goner
411 */
412 deadline_remove_request(q, next);
413}
414
415/*
416 * move request from sort list to dispatch queue.
417 */
418static inline void
419deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq)
420{
421 request_queue_t *q = drq->request->q;
422
423 deadline_remove_request(q, drq->request);
424 elv_dispatch_add_tail(q, drq->request);
425}
426
427/*
428 * move an entry to dispatch queue
429 */
430static void
431deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq)
432{
433 const int data_dir = rq_data_dir(drq->request);
434 struct rb_node *rbnext = rb_next(&drq->rb_node);
435
436 dd->next_drq[READ] = NULL;
437 dd->next_drq[WRITE] = NULL;
438
439 if (rbnext)
440 dd->next_drq[data_dir] = rb_entry_drq(rbnext);
441
442 dd->last_sector = drq->request->sector + drq->request->nr_sectors;
443
444 /*
445 * take it off the sort and fifo list, move
446 * to dispatch queue
447 */
448 deadline_move_to_dispatch(dd, drq);
449}
450
451#define list_entry_fifo(ptr) list_entry((ptr), struct deadline_rq, fifo)
452
453/*
454 * deadline_check_fifo returns 0 if there are no expired reads on the fifo,
455 * 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir])
456 */
457static inline int deadline_check_fifo(struct deadline_data *dd, int ddir)
458{
459 struct deadline_rq *drq = list_entry_fifo(dd->fifo_list[ddir].next);
460
461 /*
462 * drq is expired!
463 */
464 if (time_after(jiffies, drq->expires))
465 return 1;
466
467 return 0;
468}
469
470/*
471 * deadline_dispatch_requests selects the best request according to
472 * read/write expire, fifo_batch, etc
473 */
474static int deadline_dispatch_requests(request_queue_t *q, int force)
475{
476 struct deadline_data *dd = q->elevator->elevator_data;
477 const int reads = !list_empty(&dd->fifo_list[READ]);
478 const int writes = !list_empty(&dd->fifo_list[WRITE]);
479 struct deadline_rq *drq;
480 int data_dir;
481
482 /*
483 * batches are currently reads XOR writes
484 */
485 if (dd->next_drq[WRITE])
486 drq = dd->next_drq[WRITE];
487 else
488 drq = dd->next_drq[READ];
489
490 if (drq) {
491 /* we have a "next request" */
492
493 if (dd->last_sector != drq->request->sector)
494 /* end the batch on a non sequential request */
495 dd->batching += dd->fifo_batch;
496
497 if (dd->batching < dd->fifo_batch)
498 /* we are still entitled to batch */
499 goto dispatch_request;
500 }
501
502 /*
503 * at this point we are not running a batch. select the appropriate
504 * data direction (read / write)
505 */
506
507 if (reads) {
508 BUG_ON(RB_EMPTY(&dd->sort_list[READ]));
509
510 if (writes && (dd->starved++ >= dd->writes_starved))
511 goto dispatch_writes;
512
513 data_dir = READ;
514
515 goto dispatch_find_request;
516 }
517
518 /*
519 * there are either no reads or writes have been starved
520 */
521
522 if (writes) {
523dispatch_writes:
524 BUG_ON(RB_EMPTY(&dd->sort_list[WRITE]));
525
526 dd->starved = 0;
527
528 data_dir = WRITE;
529
530 goto dispatch_find_request;
531 }
532
533 return 0;
534
535dispatch_find_request:
536 /*
537 * we are not running a batch, find best request for selected data_dir
538 */
539 if (deadline_check_fifo(dd, data_dir)) {
540 /* An expired request exists - satisfy it */
541 dd->batching = 0;
542 drq = list_entry_fifo(dd->fifo_list[data_dir].next);
543
544 } else if (dd->next_drq[data_dir]) {
545 /*
546 * The last req was the same dir and we have a next request in
547 * sort order. No expired requests so continue on from here.
548 */
549 drq = dd->next_drq[data_dir];
550 } else {
551 /*
552 * The last req was the other direction or we have run out of
553 * higher-sectored requests. Go back to the lowest sectored
554 * request (1 way elevator) and start a new batch.
555 */
556 dd->batching = 0;
557 drq = deadline_find_first_drq(dd, data_dir);
558 }
559
560dispatch_request:
561 /*
562 * drq is the selected appropriate request.
563 */
564 dd->batching++;
565 deadline_move_request(dd, drq);
566
567 return 1;
568}
569
570static int deadline_queue_empty(request_queue_t *q)
571{
572 struct deadline_data *dd = q->elevator->elevator_data;
573
574 return list_empty(&dd->fifo_list[WRITE])
575 && list_empty(&dd->fifo_list[READ]);
576}
577
578static struct request *
579deadline_former_request(request_queue_t *q, struct request *rq)
580{
581 struct deadline_rq *drq = RQ_DATA(rq);
582 struct rb_node *rbprev = rb_prev(&drq->rb_node);
583
584 if (rbprev)
585 return rb_entry_drq(rbprev)->request;
586
587 return NULL;
588}
589
590static struct request *
591deadline_latter_request(request_queue_t *q, struct request *rq)
592{
593 struct deadline_rq *drq = RQ_DATA(rq);
594 struct rb_node *rbnext = rb_next(&drq->rb_node);
595
596 if (rbnext)
597 return rb_entry_drq(rbnext)->request;
598
599 return NULL;
600}
601
602static void deadline_exit_queue(elevator_t *e)
603{
604 struct deadline_data *dd = e->elevator_data;
605
606 BUG_ON(!list_empty(&dd->fifo_list[READ]));
607 BUG_ON(!list_empty(&dd->fifo_list[WRITE]));
608
609 mempool_destroy(dd->drq_pool);
610 kfree(dd->hash);
611 kfree(dd);
612}
613
614/*
615 * initialize elevator private data (deadline_data), and alloc a drq for
616 * each request on the free lists
617 */
618static int deadline_init_queue(request_queue_t *q, elevator_t *e)
619{
620 struct deadline_data *dd;
621 int i;
622
623 if (!drq_pool)
624 return -ENOMEM;
625
626 dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node);
627 if (!dd)
628 return -ENOMEM;
629 memset(dd, 0, sizeof(*dd));
630
631 dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES,
632 GFP_KERNEL, q->node);
633 if (!dd->hash) {
634 kfree(dd);
635 return -ENOMEM;
636 }
637
638 dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
639 mempool_free_slab, drq_pool, q->node);
640 if (!dd->drq_pool) {
641 kfree(dd->hash);
642 kfree(dd);
643 return -ENOMEM;
644 }
645
646 for (i = 0; i < DL_HASH_ENTRIES; i++)
647 INIT_LIST_HEAD(&dd->hash[i]);
648
649 INIT_LIST_HEAD(&dd->fifo_list[READ]);
650 INIT_LIST_HEAD(&dd->fifo_list[WRITE]);
651 dd->sort_list[READ] = RB_ROOT;
652 dd->sort_list[WRITE] = RB_ROOT;
653 dd->fifo_expire[READ] = read_expire;
654 dd->fifo_expire[WRITE] = write_expire;
655 dd->writes_starved = writes_starved;
656 dd->front_merges = 1;
657 dd->fifo_batch = fifo_batch;
658 e->elevator_data = dd;
659 return 0;
660}
661
662static void deadline_put_request(request_queue_t *q, struct request *rq)
663{
664 struct deadline_data *dd = q->elevator->elevator_data;
665 struct deadline_rq *drq = RQ_DATA(rq);
666
667 mempool_free(drq, dd->drq_pool);
668 rq->elevator_private = NULL;
669}
670
671static int
672deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
673 gfp_t gfp_mask)
674{
675 struct deadline_data *dd = q->elevator->elevator_data;
676 struct deadline_rq *drq;
677
678 drq = mempool_alloc(dd->drq_pool, gfp_mask);
679 if (drq) {
680 memset(drq, 0, sizeof(*drq));
681 RB_CLEAR(&drq->rb_node);
682 drq->request = rq;
683
684 INIT_LIST_HEAD(&drq->hash);
685 drq->on_hash = 0;
686
687 INIT_LIST_HEAD(&drq->fifo);
688
689 rq->elevator_private = drq;
690 return 0;
691 }
692
693 return 1;
694}
695
696/*
697 * sysfs parts below
698 */
699struct deadline_fs_entry {
700 struct attribute attr;
701 ssize_t (*show)(struct deadline_data *, char *);
702 ssize_t (*store)(struct deadline_data *, const char *, size_t);
703};
704
705static ssize_t
706deadline_var_show(int var, char *page)
707{
708 return sprintf(page, "%d\n", var);
709}
710
711static ssize_t
712deadline_var_store(int *var, const char *page, size_t count)
713{
714 char *p = (char *) page;
715
716 *var = simple_strtol(p, &p, 10);
717 return count;
718}
719
720#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \
721static ssize_t __FUNC(struct deadline_data *dd, char *page) \
722{ \
723 int __data = __VAR; \
724 if (__CONV) \
725 __data = jiffies_to_msecs(__data); \
726 return deadline_var_show(__data, (page)); \
727}
728SHOW_FUNCTION(deadline_readexpire_show, dd->fifo_expire[READ], 1);
729SHOW_FUNCTION(deadline_writeexpire_show, dd->fifo_expire[WRITE], 1);
730SHOW_FUNCTION(deadline_writesstarved_show, dd->writes_starved, 0);
731SHOW_FUNCTION(deadline_frontmerges_show, dd->front_merges, 0);
732SHOW_FUNCTION(deadline_fifobatch_show, dd->fifo_batch, 0);
733#undef SHOW_FUNCTION
734
735#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
736static ssize_t __FUNC(struct deadline_data *dd, const char *page, size_t count) \
737{ \
738 int __data; \
739 int ret = deadline_var_store(&__data, (page), count); \
740 if (__data < (MIN)) \
741 __data = (MIN); \
742 else if (__data > (MAX)) \
743 __data = (MAX); \
744 if (__CONV) \
745 *(__PTR) = msecs_to_jiffies(__data); \
746 else \
747 *(__PTR) = __data; \
748 return ret; \
749}
750STORE_FUNCTION(deadline_readexpire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1);
751STORE_FUNCTION(deadline_writeexpire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1);
752STORE_FUNCTION(deadline_writesstarved_store, &dd->writes_starved, INT_MIN, INT_MAX, 0);
753STORE_FUNCTION(deadline_frontmerges_store, &dd->front_merges, 0, 1, 0);
754STORE_FUNCTION(deadline_fifobatch_store, &dd->fifo_batch, 0, INT_MAX, 0);
755#undef STORE_FUNCTION
756
757static struct deadline_fs_entry deadline_readexpire_entry = {
758 .attr = {.name = "read_expire", .mode = S_IRUGO | S_IWUSR },
759 .show = deadline_readexpire_show,
760 .store = deadline_readexpire_store,
761};
762static struct deadline_fs_entry deadline_writeexpire_entry = {
763 .attr = {.name = "write_expire", .mode = S_IRUGO | S_IWUSR },
764 .show = deadline_writeexpire_show,
765 .store = deadline_writeexpire_store,
766};
767static struct deadline_fs_entry deadline_writesstarved_entry = {
768 .attr = {.name = "writes_starved", .mode = S_IRUGO | S_IWUSR },
769 .show = deadline_writesstarved_show,
770 .store = deadline_writesstarved_store,
771};
772static struct deadline_fs_entry deadline_frontmerges_entry = {
773 .attr = {.name = "front_merges", .mode = S_IRUGO | S_IWUSR },
774 .show = deadline_frontmerges_show,
775 .store = deadline_frontmerges_store,
776};
777static struct deadline_fs_entry deadline_fifobatch_entry = {
778 .attr = {.name = "fifo_batch", .mode = S_IRUGO | S_IWUSR },
779 .show = deadline_fifobatch_show,
780 .store = deadline_fifobatch_store,
781};
782
783static struct attribute *default_attrs[] = {
784 &deadline_readexpire_entry.attr,
785 &deadline_writeexpire_entry.attr,
786 &deadline_writesstarved_entry.attr,
787 &deadline_frontmerges_entry.attr,
788 &deadline_fifobatch_entry.attr,
789 NULL,
790};
791
792#define to_deadline(atr) container_of((atr), struct deadline_fs_entry, attr)
793
794static ssize_t
795deadline_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
796{
797 elevator_t *e = container_of(kobj, elevator_t, kobj);
798 struct deadline_fs_entry *entry = to_deadline(attr);
799
800 if (!entry->show)
801 return -EIO;
802
803 return entry->show(e->elevator_data, page);
804}
805
806static ssize_t
807deadline_attr_store(struct kobject *kobj, struct attribute *attr,
808 const char *page, size_t length)
809{
810 elevator_t *e = container_of(kobj, elevator_t, kobj);
811 struct deadline_fs_entry *entry = to_deadline(attr);
812
813 if (!entry->store)
814 return -EIO;
815
816 return entry->store(e->elevator_data, page, length);
817}
818
819static struct sysfs_ops deadline_sysfs_ops = {
820 .show = deadline_attr_show,
821 .store = deadline_attr_store,
822};
823
824static struct kobj_type deadline_ktype = {
825 .sysfs_ops = &deadline_sysfs_ops,
826 .default_attrs = default_attrs,
827};
828
829static struct elevator_type iosched_deadline = {
830 .ops = {
831 .elevator_merge_fn = deadline_merge,
832 .elevator_merged_fn = deadline_merged_request,
833 .elevator_merge_req_fn = deadline_merged_requests,
834 .elevator_dispatch_fn = deadline_dispatch_requests,
835 .elevator_add_req_fn = deadline_add_request,
836 .elevator_queue_empty_fn = deadline_queue_empty,
837 .elevator_former_req_fn = deadline_former_request,
838 .elevator_latter_req_fn = deadline_latter_request,
839 .elevator_set_req_fn = deadline_set_request,
840 .elevator_put_req_fn = deadline_put_request,
841 .elevator_init_fn = deadline_init_queue,
842 .elevator_exit_fn = deadline_exit_queue,
843 },
844
845 .elevator_ktype = &deadline_ktype,
846 .elevator_name = "deadline",
847 .elevator_owner = THIS_MODULE,
848};
849
850static int __init deadline_init(void)
851{
852 int ret;
853
854 drq_pool = kmem_cache_create("deadline_drq", sizeof(struct deadline_rq),
855 0, 0, NULL, NULL);
856
857 if (!drq_pool)
858 return -ENOMEM;
859
860 ret = elv_register(&iosched_deadline);
861 if (ret)
862 kmem_cache_destroy(drq_pool);
863
864 return ret;
865}
866
867static void __exit deadline_exit(void)
868{
869 kmem_cache_destroy(drq_pool);
870 elv_unregister(&iosched_deadline);
871}
872
873module_init(deadline_init);
874module_exit(deadline_exit);
875
876MODULE_AUTHOR("Jens Axboe");
877MODULE_LICENSE("GPL");
878MODULE_DESCRIPTION("deadline IO scheduler");
diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c
deleted file mode 100644
index d4a49a3df829..000000000000
--- a/drivers/block/elevator.c
+++ /dev/null
@@ -1,802 +0,0 @@
1/*
2 * linux/drivers/block/elevator.c
3 *
4 * Block device elevator/IO-scheduler.
5 *
6 * Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
7 *
8 * 30042000 Jens Axboe <axboe@suse.de> :
9 *
10 * Split the elevator a bit so that it is possible to choose a different
11 * one or even write a new "plug in". There are three pieces:
12 * - elevator_fn, inserts a new request in the queue list
13 * - elevator_merge_fn, decides whether a new buffer can be merged with
14 * an existing request
15 * - elevator_dequeue_fn, called when a request is taken off the active list
16 *
17 * 20082000 Dave Jones <davej@suse.de> :
18 * Removed tests for max-bomb-segments, which was breaking elvtune
19 * when run without -bN
20 *
21 * Jens:
22 * - Rework again to work with bio instead of buffer_heads
23 * - loose bi_dev comparisons, partition handling is right now
24 * - completely modularize elevator setup and teardown
25 *
26 */
27#include <linux/kernel.h>
28#include <linux/fs.h>
29#include <linux/blkdev.h>
30#include <linux/elevator.h>
31#include <linux/bio.h>
32#include <linux/config.h>
33#include <linux/module.h>
34#include <linux/slab.h>
35#include <linux/init.h>
36#include <linux/compiler.h>
37#include <linux/delay.h>
38
39#include <asm/uaccess.h>
40
41static DEFINE_SPINLOCK(elv_list_lock);
42static LIST_HEAD(elv_list);
43
44/*
45 * can we safely merge with this request?
46 */
47inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
48{
49 if (!rq_mergeable(rq))
50 return 0;
51
52 /*
53 * different data direction or already started, don't merge
54 */
55 if (bio_data_dir(bio) != rq_data_dir(rq))
56 return 0;
57
58 /*
59 * same device and no special stuff set, merge is ok
60 */
61 if (rq->rq_disk == bio->bi_bdev->bd_disk &&
62 !rq->waiting && !rq->special)
63 return 1;
64
65 return 0;
66}
67EXPORT_SYMBOL(elv_rq_merge_ok);
68
69inline int elv_try_merge(struct request *__rq, struct bio *bio)
70{
71 int ret = ELEVATOR_NO_MERGE;
72
73 /*
74 * we can merge and sequence is ok, check if it's possible
75 */
76 if (elv_rq_merge_ok(__rq, bio)) {
77 if (__rq->sector + __rq->nr_sectors == bio->bi_sector)
78 ret = ELEVATOR_BACK_MERGE;
79 else if (__rq->sector - bio_sectors(bio) == bio->bi_sector)
80 ret = ELEVATOR_FRONT_MERGE;
81 }
82
83 return ret;
84}
85EXPORT_SYMBOL(elv_try_merge);
86
87static struct elevator_type *elevator_find(const char *name)
88{
89 struct elevator_type *e = NULL;
90 struct list_head *entry;
91
92 list_for_each(entry, &elv_list) {
93 struct elevator_type *__e;
94
95 __e = list_entry(entry, struct elevator_type, list);
96
97 if (!strcmp(__e->elevator_name, name)) {
98 e = __e;
99 break;
100 }
101 }
102
103 return e;
104}
105
106static void elevator_put(struct elevator_type *e)
107{
108 module_put(e->elevator_owner);
109}
110
111static struct elevator_type *elevator_get(const char *name)
112{
113 struct elevator_type *e;
114
115 spin_lock_irq(&elv_list_lock);
116
117 e = elevator_find(name);
118 if (e && !try_module_get(e->elevator_owner))
119 e = NULL;
120
121 spin_unlock_irq(&elv_list_lock);
122
123 return e;
124}
125
126static int elevator_attach(request_queue_t *q, struct elevator_type *e,
127 struct elevator_queue *eq)
128{
129 int ret = 0;
130
131 memset(eq, 0, sizeof(*eq));
132 eq->ops = &e->ops;
133 eq->elevator_type = e;
134
135 q->elevator = eq;
136
137 if (eq->ops->elevator_init_fn)
138 ret = eq->ops->elevator_init_fn(q, eq);
139
140 return ret;
141}
142
143static char chosen_elevator[16];
144
145static void elevator_setup_default(void)
146{
147 struct elevator_type *e;
148
149 /*
150 * If default has not been set, use the compiled-in selection.
151 */
152 if (!chosen_elevator[0])
153 strcpy(chosen_elevator, CONFIG_DEFAULT_IOSCHED);
154
155 /*
156 * If the given scheduler is not available, fall back to no-op.
157 */
158 if (!(e = elevator_find(chosen_elevator)))
159 strcpy(chosen_elevator, "noop");
160 elevator_put(e);
161}
162
163static int __init elevator_setup(char *str)
164{
165 strncpy(chosen_elevator, str, sizeof(chosen_elevator) - 1);
166 return 0;
167}
168
169__setup("elevator=", elevator_setup);
170
171int elevator_init(request_queue_t *q, char *name)
172{
173 struct elevator_type *e = NULL;
174 struct elevator_queue *eq;
175 int ret = 0;
176
177 INIT_LIST_HEAD(&q->queue_head);
178 q->last_merge = NULL;
179 q->end_sector = 0;
180 q->boundary_rq = NULL;
181
182 elevator_setup_default();
183
184 if (!name)
185 name = chosen_elevator;
186
187 e = elevator_get(name);
188 if (!e)
189 return -EINVAL;
190
191 eq = kmalloc(sizeof(struct elevator_queue), GFP_KERNEL);
192 if (!eq) {
193 elevator_put(e->elevator_type);
194 return -ENOMEM;
195 }
196
197 ret = elevator_attach(q, e, eq);
198 if (ret) {
199 kfree(eq);
200 elevator_put(e->elevator_type);
201 }
202
203 return ret;
204}
205
206void elevator_exit(elevator_t *e)
207{
208 if (e->ops->elevator_exit_fn)
209 e->ops->elevator_exit_fn(e);
210
211 elevator_put(e->elevator_type);
212 e->elevator_type = NULL;
213 kfree(e);
214}
215
216/*
217 * Insert rq into dispatch queue of q. Queue lock must be held on
218 * entry. If sort != 0, rq is sort-inserted; otherwise, rq will be
219 * appended to the dispatch queue. To be used by specific elevators.
220 */
221void elv_dispatch_sort(request_queue_t *q, struct request *rq)
222{
223 sector_t boundary;
224 struct list_head *entry;
225
226 if (q->last_merge == rq)
227 q->last_merge = NULL;
228
229 boundary = q->end_sector;
230
231 list_for_each_prev(entry, &q->queue_head) {
232 struct request *pos = list_entry_rq(entry);
233
234 if (pos->flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED))
235 break;
236 if (rq->sector >= boundary) {
237 if (pos->sector < boundary)
238 continue;
239 } else {
240 if (pos->sector >= boundary)
241 break;
242 }
243 if (rq->sector >= pos->sector)
244 break;
245 }
246
247 list_add(&rq->queuelist, entry);
248}
249
250int elv_merge(request_queue_t *q, struct request **req, struct bio *bio)
251{
252 elevator_t *e = q->elevator;
253 int ret;
254
255 if (q->last_merge) {
256 ret = elv_try_merge(q->last_merge, bio);
257 if (ret != ELEVATOR_NO_MERGE) {
258 *req = q->last_merge;
259 return ret;
260 }
261 }
262
263 if (e->ops->elevator_merge_fn)
264 return e->ops->elevator_merge_fn(q, req, bio);
265
266 return ELEVATOR_NO_MERGE;
267}
268
269void elv_merged_request(request_queue_t *q, struct request *rq)
270{
271 elevator_t *e = q->elevator;
272
273 if (e->ops->elevator_merged_fn)
274 e->ops->elevator_merged_fn(q, rq);
275
276 q->last_merge = rq;
277}
278
279void elv_merge_requests(request_queue_t *q, struct request *rq,
280 struct request *next)
281{
282 elevator_t *e = q->elevator;
283
284 if (e->ops->elevator_merge_req_fn)
285 e->ops->elevator_merge_req_fn(q, rq, next);
286
287 q->last_merge = rq;
288}
289
290void elv_requeue_request(request_queue_t *q, struct request *rq)
291{
292 elevator_t *e = q->elevator;
293
294 /*
295 * it already went through dequeue, we need to decrement the
296 * in_flight count again
297 */
298 if (blk_account_rq(rq)) {
299 q->in_flight--;
300 if (blk_sorted_rq(rq) && e->ops->elevator_deactivate_req_fn)
301 e->ops->elevator_deactivate_req_fn(q, rq);
302 }
303
304 rq->flags &= ~REQ_STARTED;
305
306 /*
307 * if this is the flush, requeue the original instead and drop the flush
308 */
309 if (rq->flags & REQ_BAR_FLUSH) {
310 clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
311 rq = rq->end_io_data;
312 }
313
314 __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
315}
316
317void __elv_add_request(request_queue_t *q, struct request *rq, int where,
318 int plug)
319{
320 if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
321 /*
322 * barriers implicitly indicate back insertion
323 */
324 if (where == ELEVATOR_INSERT_SORT)
325 where = ELEVATOR_INSERT_BACK;
326
327 /*
328 * this request is scheduling boundary, update end_sector
329 */
330 if (blk_fs_request(rq)) {
331 q->end_sector = rq_end_sector(rq);
332 q->boundary_rq = rq;
333 }
334 } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT)
335 where = ELEVATOR_INSERT_BACK;
336
337 if (plug)
338 blk_plug_device(q);
339
340 rq->q = q;
341
342 switch (where) {
343 case ELEVATOR_INSERT_FRONT:
344 rq->flags |= REQ_SOFTBARRIER;
345
346 list_add(&rq->queuelist, &q->queue_head);
347 break;
348
349 case ELEVATOR_INSERT_BACK:
350 rq->flags |= REQ_SOFTBARRIER;
351
352 while (q->elevator->ops->elevator_dispatch_fn(q, 1))
353 ;
354 list_add_tail(&rq->queuelist, &q->queue_head);
355 /*
356 * We kick the queue here for the following reasons.
357 * - The elevator might have returned NULL previously
358 * to delay requests and returned them now. As the
359 * queue wasn't empty before this request, ll_rw_blk
360 * won't run the queue on return, resulting in hang.
361 * - Usually, back inserted requests won't be merged
362 * with anything. There's no point in delaying queue
363 * processing.
364 */
365 blk_remove_plug(q);
366 q->request_fn(q);
367 break;
368
369 case ELEVATOR_INSERT_SORT:
370 BUG_ON(!blk_fs_request(rq));
371 rq->flags |= REQ_SORTED;
372 if (q->last_merge == NULL && rq_mergeable(rq))
373 q->last_merge = rq;
374 /*
375 * Some ioscheds (cfq) run q->request_fn directly, so
376 * rq cannot be accessed after calling
377 * elevator_add_req_fn.
378 */
379 q->elevator->ops->elevator_add_req_fn(q, rq);
380 break;
381
382 default:
383 printk(KERN_ERR "%s: bad insertion point %d\n",
384 __FUNCTION__, where);
385 BUG();
386 }
387
388 if (blk_queue_plugged(q)) {
389 int nrq = q->rq.count[READ] + q->rq.count[WRITE]
390 - q->in_flight;
391
392 if (nrq >= q->unplug_thresh)
393 __generic_unplug_device(q);
394 }
395}
396
397void elv_add_request(request_queue_t *q, struct request *rq, int where,
398 int plug)
399{
400 unsigned long flags;
401
402 spin_lock_irqsave(q->queue_lock, flags);
403 __elv_add_request(q, rq, where, plug);
404 spin_unlock_irqrestore(q->queue_lock, flags);
405}
406
407static inline struct request *__elv_next_request(request_queue_t *q)
408{
409 struct request *rq;
410
411 if (unlikely(list_empty(&q->queue_head) &&
412 !q->elevator->ops->elevator_dispatch_fn(q, 0)))
413 return NULL;
414
415 rq = list_entry_rq(q->queue_head.next);
416
417 /*
418 * if this is a barrier write and the device has to issue a
419 * flush sequence to support it, check how far we are
420 */
421 if (blk_fs_request(rq) && blk_barrier_rq(rq)) {
422 BUG_ON(q->ordered == QUEUE_ORDERED_NONE);
423
424 if (q->ordered == QUEUE_ORDERED_FLUSH &&
425 !blk_barrier_preflush(rq))
426 rq = blk_start_pre_flush(q, rq);
427 }
428
429 return rq;
430}
431
432struct request *elv_next_request(request_queue_t *q)
433{
434 struct request *rq;
435 int ret;
436
437 while ((rq = __elv_next_request(q)) != NULL) {
438 if (!(rq->flags & REQ_STARTED)) {
439 elevator_t *e = q->elevator;
440
441 /*
442 * This is the first time the device driver
443 * sees this request (possibly after
444 * requeueing). Notify IO scheduler.
445 */
446 if (blk_sorted_rq(rq) &&
447 e->ops->elevator_activate_req_fn)
448 e->ops->elevator_activate_req_fn(q, rq);
449
450 /*
451 * just mark as started even if we don't start
452 * it, a request that has been delayed should
453 * not be passed by new incoming requests
454 */
455 rq->flags |= REQ_STARTED;
456 }
457
458 if (!q->boundary_rq || q->boundary_rq == rq) {
459 q->end_sector = rq_end_sector(rq);
460 q->boundary_rq = NULL;
461 }
462
463 if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn)
464 break;
465
466 ret = q->prep_rq_fn(q, rq);
467 if (ret == BLKPREP_OK) {
468 break;
469 } else if (ret == BLKPREP_DEFER) {
470 /*
471 * the request may have been (partially) prepped.
472 * we need to keep this request in the front to
473 * avoid resource deadlock. REQ_STARTED will
474 * prevent other fs requests from passing this one.
475 */
476 rq = NULL;
477 break;
478 } else if (ret == BLKPREP_KILL) {
479 int nr_bytes = rq->hard_nr_sectors << 9;
480
481 if (!nr_bytes)
482 nr_bytes = rq->data_len;
483
484 blkdev_dequeue_request(rq);
485 rq->flags |= REQ_QUIET;
486 end_that_request_chunk(rq, 0, nr_bytes);
487 end_that_request_last(rq);
488 } else {
489 printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__,
490 ret);
491 break;
492 }
493 }
494
495 return rq;
496}
497
498void elv_dequeue_request(request_queue_t *q, struct request *rq)
499{
500 BUG_ON(list_empty(&rq->queuelist));
501
502 list_del_init(&rq->queuelist);
503
504 /*
505 * the time frame between a request being removed from the lists
506 * and to it is freed is accounted as io that is in progress at
507 * the driver side.
508 */
509 if (blk_account_rq(rq))
510 q->in_flight++;
511}
512
513int elv_queue_empty(request_queue_t *q)
514{
515 elevator_t *e = q->elevator;
516
517 if (!list_empty(&q->queue_head))
518 return 0;
519
520 if (e->ops->elevator_queue_empty_fn)
521 return e->ops->elevator_queue_empty_fn(q);
522
523 return 1;
524}
525
526struct request *elv_latter_request(request_queue_t *q, struct request *rq)
527{
528 struct list_head *next;
529
530 elevator_t *e = q->elevator;
531
532 if (e->ops->elevator_latter_req_fn)
533 return e->ops->elevator_latter_req_fn(q, rq);
534
535 next = rq->queuelist.next;
536 if (next != &q->queue_head && next != &rq->queuelist)
537 return list_entry_rq(next);
538
539 return NULL;
540}
541
542struct request *elv_former_request(request_queue_t *q, struct request *rq)
543{
544 struct list_head *prev;
545
546 elevator_t *e = q->elevator;
547
548 if (e->ops->elevator_former_req_fn)
549 return e->ops->elevator_former_req_fn(q, rq);
550
551 prev = rq->queuelist.prev;
552 if (prev != &q->queue_head && prev != &rq->queuelist)
553 return list_entry_rq(prev);
554
555 return NULL;
556}
557
558int elv_set_request(request_queue_t *q, struct request *rq, struct bio *bio,
559 gfp_t gfp_mask)
560{
561 elevator_t *e = q->elevator;
562
563 if (e->ops->elevator_set_req_fn)
564 return e->ops->elevator_set_req_fn(q, rq, bio, gfp_mask);
565
566 rq->elevator_private = NULL;
567 return 0;
568}
569
570void elv_put_request(request_queue_t *q, struct request *rq)
571{
572 elevator_t *e = q->elevator;
573
574 if (e->ops->elevator_put_req_fn)
575 e->ops->elevator_put_req_fn(q, rq);
576}
577
578int elv_may_queue(request_queue_t *q, int rw, struct bio *bio)
579{
580 elevator_t *e = q->elevator;
581
582 if (e->ops->elevator_may_queue_fn)
583 return e->ops->elevator_may_queue_fn(q, rw, bio);
584
585 return ELV_MQUEUE_MAY;
586}
587
588void elv_completed_request(request_queue_t *q, struct request *rq)
589{
590 elevator_t *e = q->elevator;
591
592 /*
593 * request is released from the driver, io must be done
594 */
595 if (blk_account_rq(rq)) {
596 q->in_flight--;
597 if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn)
598 e->ops->elevator_completed_req_fn(q, rq);
599 }
600}
601
602int elv_register_queue(struct request_queue *q)
603{
604 elevator_t *e = q->elevator;
605
606 e->kobj.parent = kobject_get(&q->kobj);
607 if (!e->kobj.parent)
608 return -EBUSY;
609
610 snprintf(e->kobj.name, KOBJ_NAME_LEN, "%s", "iosched");
611 e->kobj.ktype = e->elevator_type->elevator_ktype;
612
613 return kobject_register(&e->kobj);
614}
615
616void elv_unregister_queue(struct request_queue *q)
617{
618 if (q) {
619 elevator_t *e = q->elevator;
620 kobject_unregister(&e->kobj);
621 kobject_put(&q->kobj);
622 }
623}
624
625int elv_register(struct elevator_type *e)
626{
627 spin_lock_irq(&elv_list_lock);
628 if (elevator_find(e->elevator_name))
629 BUG();
630 list_add_tail(&e->list, &elv_list);
631 spin_unlock_irq(&elv_list_lock);
632
633 printk(KERN_INFO "io scheduler %s registered", e->elevator_name);
634 if (!strcmp(e->elevator_name, chosen_elevator))
635 printk(" (default)");
636 printk("\n");
637 return 0;
638}
639EXPORT_SYMBOL_GPL(elv_register);
640
641void elv_unregister(struct elevator_type *e)
642{
643 struct task_struct *g, *p;
644
645 /*
646 * Iterate every thread in the process to remove the io contexts.
647 */
648 read_lock(&tasklist_lock);
649 do_each_thread(g, p) {
650 struct io_context *ioc = p->io_context;
651 if (ioc && ioc->cic) {
652 ioc->cic->exit(ioc->cic);
653 ioc->cic->dtor(ioc->cic);
654 ioc->cic = NULL;
655 }
656 if (ioc && ioc->aic) {
657 ioc->aic->exit(ioc->aic);
658 ioc->aic->dtor(ioc->aic);
659 ioc->aic = NULL;
660 }
661 } while_each_thread(g, p);
662 read_unlock(&tasklist_lock);
663
664 spin_lock_irq(&elv_list_lock);
665 list_del_init(&e->list);
666 spin_unlock_irq(&elv_list_lock);
667}
668EXPORT_SYMBOL_GPL(elv_unregister);
669
670/*
671 * switch to new_e io scheduler. be careful not to introduce deadlocks -
672 * we don't free the old io scheduler, before we have allocated what we
673 * need for the new one. this way we have a chance of going back to the old
674 * one, if the new one fails init for some reason.
675 */
676static void elevator_switch(request_queue_t *q, struct elevator_type *new_e)
677{
678 elevator_t *old_elevator, *e;
679
680 /*
681 * Allocate new elevator
682 */
683 e = kmalloc(sizeof(elevator_t), GFP_KERNEL);
684 if (!e)
685 goto error;
686
687 /*
688 * Turn on BYPASS and drain all requests w/ elevator private data
689 */
690 spin_lock_irq(q->queue_lock);
691
692 set_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
693
694 while (q->elevator->ops->elevator_dispatch_fn(q, 1))
695 ;
696
697 while (q->rq.elvpriv) {
698 spin_unlock_irq(q->queue_lock);
699 msleep(10);
700 spin_lock_irq(q->queue_lock);
701 }
702
703 spin_unlock_irq(q->queue_lock);
704
705 /*
706 * unregister old elevator data
707 */
708 elv_unregister_queue(q);
709 old_elevator = q->elevator;
710
711 /*
712 * attach and start new elevator
713 */
714 if (elevator_attach(q, new_e, e))
715 goto fail;
716
717 if (elv_register_queue(q))
718 goto fail_register;
719
720 /*
721 * finally exit old elevator and turn off BYPASS.
722 */
723 elevator_exit(old_elevator);
724 clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
725 return;
726
727fail_register:
728 /*
729 * switch failed, exit the new io scheduler and reattach the old
730 * one again (along with re-adding the sysfs dir)
731 */
732 elevator_exit(e);
733 e = NULL;
734fail:
735 q->elevator = old_elevator;
736 elv_register_queue(q);
737 clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
738 kfree(e);
739error:
740 elevator_put(new_e);
741 printk(KERN_ERR "elevator: switch to %s failed\n",new_e->elevator_name);
742}
743
744ssize_t elv_iosched_store(request_queue_t *q, const char *name, size_t count)
745{
746 char elevator_name[ELV_NAME_MAX];
747 struct elevator_type *e;
748
749 memset(elevator_name, 0, sizeof(elevator_name));
750 strncpy(elevator_name, name, sizeof(elevator_name));
751
752 if (elevator_name[strlen(elevator_name) - 1] == '\n')
753 elevator_name[strlen(elevator_name) - 1] = '\0';
754
755 e = elevator_get(elevator_name);
756 if (!e) {
757 printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
758 return -EINVAL;
759 }
760
761 if (!strcmp(elevator_name, q->elevator->elevator_type->elevator_name)) {
762 elevator_put(e);
763 return count;
764 }
765
766 elevator_switch(q, e);
767 return count;
768}
769
770ssize_t elv_iosched_show(request_queue_t *q, char *name)
771{
772 elevator_t *e = q->elevator;
773 struct elevator_type *elv = e->elevator_type;
774 struct list_head *entry;
775 int len = 0;
776
777 spin_lock_irq(q->queue_lock);
778 list_for_each(entry, &elv_list) {
779 struct elevator_type *__e;
780
781 __e = list_entry(entry, struct elevator_type, list);
782 if (!strcmp(elv->elevator_name, __e->elevator_name))
783 len += sprintf(name+len, "[%s] ", elv->elevator_name);
784 else
785 len += sprintf(name+len, "%s ", __e->elevator_name);
786 }
787 spin_unlock_irq(q->queue_lock);
788
789 len += sprintf(len+name, "\n");
790 return len;
791}
792
793EXPORT_SYMBOL(elv_dispatch_sort);
794EXPORT_SYMBOL(elv_add_request);
795EXPORT_SYMBOL(__elv_add_request);
796EXPORT_SYMBOL(elv_requeue_request);
797EXPORT_SYMBOL(elv_next_request);
798EXPORT_SYMBOL(elv_dequeue_request);
799EXPORT_SYMBOL(elv_queue_empty);
800EXPORT_SYMBOL(elv_completed_request);
801EXPORT_SYMBOL(elevator_exit);
802EXPORT_SYMBOL(elevator_init);
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 5eadbb9d4d71..28002de783b6 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3714,6 +3714,12 @@ static int floppy_open(struct inode *inode, struct file *filp)
3714 USETF(FD_VERIFY); 3714 USETF(FD_VERIFY);
3715 } 3715 }
3716 3716
3717 /* set underlying gendisk policy to reflect real ro/rw status */
3718 if (UTESTF(FD_DISK_WRITABLE))
3719 inode->i_bdev->bd_disk->policy = 0;
3720 else
3721 inode->i_bdev->bd_disk->policy = 1;
3722
3717 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL))) 3723 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3718 goto out2; 3724 goto out2;
3719 3725
@@ -3770,8 +3776,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
3770 /* Allow ioctls if we have write-permissions even if read-only open. 3776 /* Allow ioctls if we have write-permissions even if read-only open.
3771 * Needed so that programs such as fdrawcmd still can work on write 3777 * Needed so that programs such as fdrawcmd still can work on write
3772 * protected disks */ 3778 * protected disks */
3773 if (filp->f_mode & 2 3779 if ((filp->f_mode & FMODE_WRITE) || !file_permission(filp, MAY_WRITE))
3774 || permission(filp->f_dentry->d_inode, 2, NULL) == 0)
3775 filp->private_data = (void *)8; 3780 filp->private_data = (void *)8;
3776 3781
3777 if (UFDCS->rawcmd == 1) 3782 if (UFDCS->rawcmd == 1)
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
deleted file mode 100644
index 54aec4a1ae13..000000000000
--- a/drivers/block/genhd.c
+++ /dev/null
@@ -1,726 +0,0 @@
1/*
2 * gendisk handling
3 */
4
5#include <linux/config.h>
6#include <linux/module.h>
7#include <linux/fs.h>
8#include <linux/genhd.h>
9#include <linux/kernel.h>
10#include <linux/blkdev.h>
11#include <linux/init.h>
12#include <linux/spinlock.h>
13#include <linux/seq_file.h>
14#include <linux/slab.h>
15#include <linux/kmod.h>
16#include <linux/kobj_map.h>
17#include <linux/buffer_head.h>
18
19#define MAX_PROBE_HASH 255 /* random */
20
21static struct subsystem block_subsys;
22
23static DECLARE_MUTEX(block_subsys_sem);
24
25/*
26 * Can be deleted altogether. Later.
27 *
28 */
29static struct blk_major_name {
30 struct blk_major_name *next;
31 int major;
32 char name[16];
33} *major_names[MAX_PROBE_HASH];
34
35/* index in the above - for now: assume no multimajor ranges */
36static inline int major_to_index(int major)
37{
38 return major % MAX_PROBE_HASH;
39}
40
41#ifdef CONFIG_PROC_FS
42/* get block device names in somewhat random order */
43int get_blkdev_list(char *p, int used)
44{
45 struct blk_major_name *n;
46 int i, len;
47
48 len = snprintf(p, (PAGE_SIZE-used), "\nBlock devices:\n");
49
50 down(&block_subsys_sem);
51 for (i = 0; i < ARRAY_SIZE(major_names); i++) {
52 for (n = major_names[i]; n; n = n->next) {
53 /*
54 * If the curent string plus the 5 extra characters
55 * in the line would run us off the page, then we're done
56 */
57 if ((len + used + strlen(n->name) + 5) >= PAGE_SIZE)
58 goto page_full;
59 len += sprintf(p+len, "%3d %s\n",
60 n->major, n->name);
61 }
62 }
63page_full:
64 up(&block_subsys_sem);
65
66 return len;
67}
68#endif
69
70int register_blkdev(unsigned int major, const char *name)
71{
72 struct blk_major_name **n, *p;
73 int index, ret = 0;
74
75 down(&block_subsys_sem);
76
77 /* temporary */
78 if (major == 0) {
79 for (index = ARRAY_SIZE(major_names)-1; index > 0; index--) {
80 if (major_names[index] == NULL)
81 break;
82 }
83
84 if (index == 0) {
85 printk("register_blkdev: failed to get major for %s\n",
86 name);
87 ret = -EBUSY;
88 goto out;
89 }
90 major = index;
91 ret = major;
92 }
93
94 p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL);
95 if (p == NULL) {
96 ret = -ENOMEM;
97 goto out;
98 }
99
100 p->major = major;
101 strlcpy(p->name, name, sizeof(p->name));
102 p->next = NULL;
103 index = major_to_index(major);
104
105 for (n = &major_names[index]; *n; n = &(*n)->next) {
106 if ((*n)->major == major)
107 break;
108 }
109 if (!*n)
110 *n = p;
111 else
112 ret = -EBUSY;
113
114 if (ret < 0) {
115 printk("register_blkdev: cannot get major %d for %s\n",
116 major, name);
117 kfree(p);
118 }
119out:
120 up(&block_subsys_sem);
121 return ret;
122}
123
124EXPORT_SYMBOL(register_blkdev);
125
126/* todo: make void - error printk here */
127int unregister_blkdev(unsigned int major, const char *name)
128{
129 struct blk_major_name **n;
130 struct blk_major_name *p = NULL;
131 int index = major_to_index(major);
132 int ret = 0;
133
134 down(&block_subsys_sem);
135 for (n = &major_names[index]; *n; n = &(*n)->next)
136 if ((*n)->major == major)
137 break;
138 if (!*n || strcmp((*n)->name, name))
139 ret = -EINVAL;
140 else {
141 p = *n;
142 *n = p->next;
143 }
144 up(&block_subsys_sem);
145 kfree(p);
146
147 return ret;
148}
149
150EXPORT_SYMBOL(unregister_blkdev);
151
152static struct kobj_map *bdev_map;
153
154/*
155 * Register device numbers dev..(dev+range-1)
156 * range must be nonzero
157 * The hash chain is sorted on range, so that subranges can override.
158 */
159void blk_register_region(dev_t dev, unsigned long range, struct module *module,
160 struct kobject *(*probe)(dev_t, int *, void *),
161 int (*lock)(dev_t, void *), void *data)
162{
163 kobj_map(bdev_map, dev, range, module, probe, lock, data);
164}
165
166EXPORT_SYMBOL(blk_register_region);
167
168void blk_unregister_region(dev_t dev, unsigned long range)
169{
170 kobj_unmap(bdev_map, dev, range);
171}
172
173EXPORT_SYMBOL(blk_unregister_region);
174
175static struct kobject *exact_match(dev_t dev, int *part, void *data)
176{
177 struct gendisk *p = data;
178 return &p->kobj;
179}
180
181static int exact_lock(dev_t dev, void *data)
182{
183 struct gendisk *p = data;
184
185 if (!get_disk(p))
186 return -1;
187 return 0;
188}
189
190/**
191 * add_disk - add partitioning information to kernel list
192 * @disk: per-device partitioning information
193 *
194 * This function registers the partitioning information in @disk
195 * with the kernel.
196 */
197void add_disk(struct gendisk *disk)
198{
199 disk->flags |= GENHD_FL_UP;
200 blk_register_region(MKDEV(disk->major, disk->first_minor),
201 disk->minors, NULL, exact_match, exact_lock, disk);
202 register_disk(disk);
203 blk_register_queue(disk);
204}
205
206EXPORT_SYMBOL(add_disk);
207EXPORT_SYMBOL(del_gendisk); /* in partitions/check.c */
208
209void unlink_gendisk(struct gendisk *disk)
210{
211 blk_unregister_queue(disk);
212 blk_unregister_region(MKDEV(disk->major, disk->first_minor),
213 disk->minors);
214}
215
216#define to_disk(obj) container_of(obj,struct gendisk,kobj)
217
218/**
219 * get_gendisk - get partitioning information for a given device
220 * @dev: device to get partitioning information for
221 *
222 * This function gets the structure containing partitioning
223 * information for the given device @dev.
224 */
225struct gendisk *get_gendisk(dev_t dev, int *part)
226{
227 struct kobject *kobj = kobj_lookup(bdev_map, dev, part);
228 return kobj ? to_disk(kobj) : NULL;
229}
230
231#ifdef CONFIG_PROC_FS
232/* iterator */
233static void *part_start(struct seq_file *part, loff_t *pos)
234{
235 struct list_head *p;
236 loff_t l = *pos;
237
238 down(&block_subsys_sem);
239 list_for_each(p, &block_subsys.kset.list)
240 if (!l--)
241 return list_entry(p, struct gendisk, kobj.entry);
242 return NULL;
243}
244
245static void *part_next(struct seq_file *part, void *v, loff_t *pos)
246{
247 struct list_head *p = ((struct gendisk *)v)->kobj.entry.next;
248 ++*pos;
249 return p==&block_subsys.kset.list ? NULL :
250 list_entry(p, struct gendisk, kobj.entry);
251}
252
253static void part_stop(struct seq_file *part, void *v)
254{
255 up(&block_subsys_sem);
256}
257
258static int show_partition(struct seq_file *part, void *v)
259{
260 struct gendisk *sgp = v;
261 int n;
262 char buf[BDEVNAME_SIZE];
263
264 if (&sgp->kobj.entry == block_subsys.kset.list.next)
265 seq_puts(part, "major minor #blocks name\n\n");
266
267 /* Don't show non-partitionable removeable devices or empty devices */
268 if (!get_capacity(sgp) ||
269 (sgp->minors == 1 && (sgp->flags & GENHD_FL_REMOVABLE)))
270 return 0;
271 if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)
272 return 0;
273
274 /* show the full disk and all non-0 size partitions of it */
275 seq_printf(part, "%4d %4d %10llu %s\n",
276 sgp->major, sgp->first_minor,
277 (unsigned long long)get_capacity(sgp) >> 1,
278 disk_name(sgp, 0, buf));
279 for (n = 0; n < sgp->minors - 1; n++) {
280 if (!sgp->part[n])
281 continue;
282 if (sgp->part[n]->nr_sects == 0)
283 continue;
284 seq_printf(part, "%4d %4d %10llu %s\n",
285 sgp->major, n + 1 + sgp->first_minor,
286 (unsigned long long)sgp->part[n]->nr_sects >> 1 ,
287 disk_name(sgp, n + 1, buf));
288 }
289
290 return 0;
291}
292
293struct seq_operations partitions_op = {
294 .start =part_start,
295 .next = part_next,
296 .stop = part_stop,
297 .show = show_partition
298};
299#endif
300
301
302extern int blk_dev_init(void);
303
304static struct kobject *base_probe(dev_t dev, int *part, void *data)
305{
306 if (request_module("block-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0)
307 /* Make old-style 2.4 aliases work */
308 request_module("block-major-%d", MAJOR(dev));
309 return NULL;
310}
311
312static int __init genhd_device_init(void)
313{
314 bdev_map = kobj_map_init(base_probe, &block_subsys_sem);
315 blk_dev_init();
316 subsystem_register(&block_subsys);
317 return 0;
318}
319
320subsys_initcall(genhd_device_init);
321
322
323
324/*
325 * kobject & sysfs bindings for block devices
326 */
327static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
328 char *page)
329{
330 struct gendisk *disk = to_disk(kobj);
331 struct disk_attribute *disk_attr =
332 container_of(attr,struct disk_attribute,attr);
333 ssize_t ret = -EIO;
334
335 if (disk_attr->show)
336 ret = disk_attr->show(disk,page);
337 return ret;
338}
339
340static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr,
341 const char *page, size_t count)
342{
343 struct gendisk *disk = to_disk(kobj);
344 struct disk_attribute *disk_attr =
345 container_of(attr,struct disk_attribute,attr);
346 ssize_t ret = 0;
347
348 if (disk_attr->store)
349 ret = disk_attr->store(disk, page, count);
350 return ret;
351}
352
353static struct sysfs_ops disk_sysfs_ops = {
354 .show = &disk_attr_show,
355 .store = &disk_attr_store,
356};
357
358static ssize_t disk_uevent_store(struct gendisk * disk,
359 const char *buf, size_t count)
360{
361 kobject_hotplug(&disk->kobj, KOBJ_ADD);
362 return count;
363}
364static ssize_t disk_dev_read(struct gendisk * disk, char *page)
365{
366 dev_t base = MKDEV(disk->major, disk->first_minor);
367 return print_dev_t(page, base);
368}
369static ssize_t disk_range_read(struct gendisk * disk, char *page)
370{
371 return sprintf(page, "%d\n", disk->minors);
372}
373static ssize_t disk_removable_read(struct gendisk * disk, char *page)
374{
375 return sprintf(page, "%d\n",
376 (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0));
377
378}
379static ssize_t disk_size_read(struct gendisk * disk, char *page)
380{
381 return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk));
382}
383
384static ssize_t disk_stats_read(struct gendisk * disk, char *page)
385{
386 preempt_disable();
387 disk_round_stats(disk);
388 preempt_enable();
389 return sprintf(page,
390 "%8u %8u %8llu %8u "
391 "%8u %8u %8llu %8u "
392 "%8u %8u %8u"
393 "\n",
394 disk_stat_read(disk, ios[0]), disk_stat_read(disk, merges[0]),
395 (unsigned long long)disk_stat_read(disk, sectors[0]),
396 jiffies_to_msecs(disk_stat_read(disk, ticks[0])),
397 disk_stat_read(disk, ios[1]), disk_stat_read(disk, merges[1]),
398 (unsigned long long)disk_stat_read(disk, sectors[1]),
399 jiffies_to_msecs(disk_stat_read(disk, ticks[1])),
400 disk->in_flight,
401 jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
402 jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
403}
404static struct disk_attribute disk_attr_uevent = {
405 .attr = {.name = "uevent", .mode = S_IWUSR },
406 .store = disk_uevent_store
407};
408static struct disk_attribute disk_attr_dev = {
409 .attr = {.name = "dev", .mode = S_IRUGO },
410 .show = disk_dev_read
411};
412static struct disk_attribute disk_attr_range = {
413 .attr = {.name = "range", .mode = S_IRUGO },
414 .show = disk_range_read
415};
416static struct disk_attribute disk_attr_removable = {
417 .attr = {.name = "removable", .mode = S_IRUGO },
418 .show = disk_removable_read
419};
420static struct disk_attribute disk_attr_size = {
421 .attr = {.name = "size", .mode = S_IRUGO },
422 .show = disk_size_read
423};
424static struct disk_attribute disk_attr_stat = {
425 .attr = {.name = "stat", .mode = S_IRUGO },
426 .show = disk_stats_read
427};
428
429static struct attribute * default_attrs[] = {
430 &disk_attr_uevent.attr,
431 &disk_attr_dev.attr,
432 &disk_attr_range.attr,
433 &disk_attr_removable.attr,
434 &disk_attr_size.attr,
435 &disk_attr_stat.attr,
436 NULL,
437};
438
439static void disk_release(struct kobject * kobj)
440{
441 struct gendisk *disk = to_disk(kobj);
442 kfree(disk->random);
443 kfree(disk->part);
444 free_disk_stats(disk);
445 kfree(disk);
446}
447
448static struct kobj_type ktype_block = {
449 .release = disk_release,
450 .sysfs_ops = &disk_sysfs_ops,
451 .default_attrs = default_attrs,
452};
453
454extern struct kobj_type ktype_part;
455
456static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
457{
458 struct kobj_type *ktype = get_ktype(kobj);
459
460 return ((ktype == &ktype_block) || (ktype == &ktype_part));
461}
462
463static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
464 int num_envp, char *buffer, int buffer_size)
465{
466 struct kobj_type *ktype = get_ktype(kobj);
467 struct device *physdev;
468 struct gendisk *disk;
469 struct hd_struct *part;
470 int length = 0;
471 int i = 0;
472
473 if (ktype == &ktype_block) {
474 disk = container_of(kobj, struct gendisk, kobj);
475 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
476 &length, "MINOR=%u", disk->first_minor);
477 } else if (ktype == &ktype_part) {
478 disk = container_of(kobj->parent, struct gendisk, kobj);
479 part = container_of(kobj, struct hd_struct, kobj);
480 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
481 &length, "MINOR=%u",
482 disk->first_minor + part->partno);
483 } else
484 return 0;
485
486 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &length,
487 "MAJOR=%u", disk->major);
488
489 /* add physical device, backing this device */
490 physdev = disk->driverfs_dev;
491 if (physdev) {
492 char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
493
494 add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
495 &length, "PHYSDEVPATH=%s", path);
496 kfree(path);
497
498 if (physdev->bus)
499 add_hotplug_env_var(envp, num_envp, &i,
500 buffer, buffer_size, &length,
501 "PHYSDEVBUS=%s",
502 physdev->bus->name);
503
504 if (physdev->driver)
505 add_hotplug_env_var(envp, num_envp, &i,
506 buffer, buffer_size, &length,
507 "PHYSDEVDRIVER=%s",
508 physdev->driver->name);
509 }
510
511 /* terminate, set to next free slot, shrink available space */
512 envp[i] = NULL;
513 envp = &envp[i];
514 num_envp -= i;
515 buffer = &buffer[length];
516 buffer_size -= length;
517
518 return 0;
519}
520
521static struct kset_hotplug_ops block_hotplug_ops = {
522 .filter = block_hotplug_filter,
523 .hotplug = block_hotplug,
524};
525
526/* declare block_subsys. */
527static decl_subsys(block, &ktype_block, &block_hotplug_ops);
528
529
530/*
531 * aggregate disk stat collector. Uses the same stats that the sysfs
532 * entries do, above, but makes them available through one seq_file.
533 * Watching a few disks may be efficient through sysfs, but watching
534 * all of them will be more efficient through this interface.
535 *
536 * The output looks suspiciously like /proc/partitions with a bunch of
537 * extra fields.
538 */
539
540/* iterator */
541static void *diskstats_start(struct seq_file *part, loff_t *pos)
542{
543 loff_t k = *pos;
544 struct list_head *p;
545
546 down(&block_subsys_sem);
547 list_for_each(p, &block_subsys.kset.list)
548 if (!k--)
549 return list_entry(p, struct gendisk, kobj.entry);
550 return NULL;
551}
552
553static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos)
554{
555 struct list_head *p = ((struct gendisk *)v)->kobj.entry.next;
556 ++*pos;
557 return p==&block_subsys.kset.list ? NULL :
558 list_entry(p, struct gendisk, kobj.entry);
559}
560
561static void diskstats_stop(struct seq_file *part, void *v)
562{
563 up(&block_subsys_sem);
564}
565
566static int diskstats_show(struct seq_file *s, void *v)
567{
568 struct gendisk *gp = v;
569 char buf[BDEVNAME_SIZE];
570 int n = 0;
571
572 /*
573 if (&sgp->kobj.entry == block_subsys.kset.list.next)
574 seq_puts(s, "major minor name"
575 " rio rmerge rsect ruse wio wmerge "
576 "wsect wuse running use aveq"
577 "\n\n");
578 */
579
580 preempt_disable();
581 disk_round_stats(gp);
582 preempt_enable();
583 seq_printf(s, "%4d %4d %s %u %u %llu %u %u %u %llu %u %u %u %u\n",
584 gp->major, n + gp->first_minor, disk_name(gp, n, buf),
585 disk_stat_read(gp, ios[0]), disk_stat_read(gp, merges[0]),
586 (unsigned long long)disk_stat_read(gp, sectors[0]),
587 jiffies_to_msecs(disk_stat_read(gp, ticks[0])),
588 disk_stat_read(gp, ios[1]), disk_stat_read(gp, merges[1]),
589 (unsigned long long)disk_stat_read(gp, sectors[1]),
590 jiffies_to_msecs(disk_stat_read(gp, ticks[1])),
591 gp->in_flight,
592 jiffies_to_msecs(disk_stat_read(gp, io_ticks)),
593 jiffies_to_msecs(disk_stat_read(gp, time_in_queue)));
594
595 /* now show all non-0 size partitions of it */
596 for (n = 0; n < gp->minors - 1; n++) {
597 struct hd_struct *hd = gp->part[n];
598
599 if (hd && hd->nr_sects)
600 seq_printf(s, "%4d %4d %s %u %u %u %u\n",
601 gp->major, n + gp->first_minor + 1,
602 disk_name(gp, n + 1, buf),
603 hd->ios[0], hd->sectors[0],
604 hd->ios[1], hd->sectors[1]);
605 }
606
607 return 0;
608}
609
610struct seq_operations diskstats_op = {
611 .start = diskstats_start,
612 .next = diskstats_next,
613 .stop = diskstats_stop,
614 .show = diskstats_show
615};
616
617struct gendisk *alloc_disk(int minors)
618{
619 return alloc_disk_node(minors, -1);
620}
621
622struct gendisk *alloc_disk_node(int minors, int node_id)
623{
624 struct gendisk *disk;
625
626 disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
627 if (disk) {
628 memset(disk, 0, sizeof(struct gendisk));
629 if (!init_disk_stats(disk)) {
630 kfree(disk);
631 return NULL;
632 }
633 if (minors > 1) {
634 int size = (minors - 1) * sizeof(struct hd_struct *);
635 disk->part = kmalloc_node(size, GFP_KERNEL, node_id);
636 if (!disk->part) {
637 kfree(disk);
638 return NULL;
639 }
640 memset(disk->part, 0, size);
641 }
642 disk->minors = minors;
643 kobj_set_kset_s(disk,block_subsys);
644 kobject_init(&disk->kobj);
645 rand_initialize_disk(disk);
646 }
647 return disk;
648}
649
650EXPORT_SYMBOL(alloc_disk);
651EXPORT_SYMBOL(alloc_disk_node);
652
653struct kobject *get_disk(struct gendisk *disk)
654{
655 struct module *owner;
656 struct kobject *kobj;
657
658 if (!disk->fops)
659 return NULL;
660 owner = disk->fops->owner;
661 if (owner && !try_module_get(owner))
662 return NULL;
663 kobj = kobject_get(&disk->kobj);
664 if (kobj == NULL) {
665 module_put(owner);
666 return NULL;
667 }
668 return kobj;
669
670}
671
672EXPORT_SYMBOL(get_disk);
673
674void put_disk(struct gendisk *disk)
675{
676 if (disk)
677 kobject_put(&disk->kobj);
678}
679
680EXPORT_SYMBOL(put_disk);
681
682void set_device_ro(struct block_device *bdev, int flag)
683{
684 if (bdev->bd_contains != bdev)
685 bdev->bd_part->policy = flag;
686 else
687 bdev->bd_disk->policy = flag;
688}
689
690EXPORT_SYMBOL(set_device_ro);
691
692void set_disk_ro(struct gendisk *disk, int flag)
693{
694 int i;
695 disk->policy = flag;
696 for (i = 0; i < disk->minors - 1; i++)
697 if (disk->part[i]) disk->part[i]->policy = flag;
698}
699
700EXPORT_SYMBOL(set_disk_ro);
701
702int bdev_read_only(struct block_device *bdev)
703{
704 if (!bdev)
705 return 0;
706 else if (bdev->bd_contains != bdev)
707 return bdev->bd_part->policy;
708 else
709 return bdev->bd_disk->policy;
710}
711
712EXPORT_SYMBOL(bdev_read_only);
713
714int invalidate_partition(struct gendisk *disk, int index)
715{
716 int res = 0;
717 struct block_device *bdev = bdget_disk(disk, index);
718 if (bdev) {
719 fsync_bdev(bdev);
720 res = __invalidate_device(bdev);
721 bdput(bdev);
722 }
723 return res;
724}
725
726EXPORT_SYMBOL(invalidate_partition);
diff --git a/drivers/block/ioctl.c b/drivers/block/ioctl.c
deleted file mode 100644
index 6e278474f9a8..000000000000
--- a/drivers/block/ioctl.c
+++ /dev/null
@@ -1,275 +0,0 @@
1#include <linux/sched.h> /* for capable() */
2#include <linux/blkdev.h>
3#include <linux/blkpg.h>
4#include <linux/backing-dev.h>
5#include <linux/buffer_head.h>
6#include <linux/smp_lock.h>
7#include <asm/uaccess.h>
8
9static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user *arg)
10{
11 struct block_device *bdevp;
12 struct gendisk *disk;
13 struct blkpg_ioctl_arg a;
14 struct blkpg_partition p;
15 long long start, length;
16 int part;
17 int i;
18
19 if (!capable(CAP_SYS_ADMIN))
20 return -EACCES;
21 if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg)))
22 return -EFAULT;
23 if (copy_from_user(&p, a.data, sizeof(struct blkpg_partition)))
24 return -EFAULT;
25 disk = bdev->bd_disk;
26 if (bdev != bdev->bd_contains)
27 return -EINVAL;
28 part = p.pno;
29 if (part <= 0 || part >= disk->minors)
30 return -EINVAL;
31 switch (a.op) {
32 case BLKPG_ADD_PARTITION:
33 start = p.start >> 9;
34 length = p.length >> 9;
35 /* check for fit in a hd_struct */
36 if (sizeof(sector_t) == sizeof(long) &&
37 sizeof(long long) > sizeof(long)) {
38 long pstart = start, plength = length;
39 if (pstart != start || plength != length
40 || pstart < 0 || plength < 0)
41 return -EINVAL;
42 }
43 /* partition number in use? */
44 down(&bdev->bd_sem);
45 if (disk->part[part - 1]) {
46 up(&bdev->bd_sem);
47 return -EBUSY;
48 }
49 /* overlap? */
50 for (i = 0; i < disk->minors - 1; i++) {
51 struct hd_struct *s = disk->part[i];
52
53 if (!s)
54 continue;
55 if (!(start+length <= s->start_sect ||
56 start >= s->start_sect + s->nr_sects)) {
57 up(&bdev->bd_sem);
58 return -EBUSY;
59 }
60 }
61 /* all seems OK */
62 add_partition(disk, part, start, length);
63 up(&bdev->bd_sem);
64 return 0;
65 case BLKPG_DEL_PARTITION:
66 if (!disk->part[part-1])
67 return -ENXIO;
68 if (disk->part[part - 1]->nr_sects == 0)
69 return -ENXIO;
70 bdevp = bdget_disk(disk, part);
71 if (!bdevp)
72 return -ENOMEM;
73 down(&bdevp->bd_sem);
74 if (bdevp->bd_openers) {
75 up(&bdevp->bd_sem);
76 bdput(bdevp);
77 return -EBUSY;
78 }
79 /* all seems OK */
80 fsync_bdev(bdevp);
81 invalidate_bdev(bdevp, 0);
82
83 down(&bdev->bd_sem);
84 delete_partition(disk, part);
85 up(&bdev->bd_sem);
86 up(&bdevp->bd_sem);
87 bdput(bdevp);
88
89 return 0;
90 default:
91 return -EINVAL;
92 }
93}
94
95static int blkdev_reread_part(struct block_device *bdev)
96{
97 struct gendisk *disk = bdev->bd_disk;
98 int res;
99
100 if (disk->minors == 1 || bdev != bdev->bd_contains)
101 return -EINVAL;
102 if (!capable(CAP_SYS_ADMIN))
103 return -EACCES;
104 if (down_trylock(&bdev->bd_sem))
105 return -EBUSY;
106 res = rescan_partitions(disk, bdev);
107 up(&bdev->bd_sem);
108 return res;
109}
110
111static int put_ushort(unsigned long arg, unsigned short val)
112{
113 return put_user(val, (unsigned short __user *)arg);
114}
115
116static int put_int(unsigned long arg, int val)
117{
118 return put_user(val, (int __user *)arg);
119}
120
121static int put_long(unsigned long arg, long val)
122{
123 return put_user(val, (long __user *)arg);
124}
125
126static int put_ulong(unsigned long arg, unsigned long val)
127{
128 return put_user(val, (unsigned long __user *)arg);
129}
130
131static int put_u64(unsigned long arg, u64 val)
132{
133 return put_user(val, (u64 __user *)arg);
134}
135
136static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev,
137 unsigned cmd, unsigned long arg)
138{
139 struct backing_dev_info *bdi;
140 int ret, n;
141
142 switch (cmd) {
143 case BLKRAGET:
144 case BLKFRAGET:
145 if (!arg)
146 return -EINVAL;
147 bdi = blk_get_backing_dev_info(bdev);
148 if (bdi == NULL)
149 return -ENOTTY;
150 return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
151 case BLKROGET:
152 return put_int(arg, bdev_read_only(bdev) != 0);
153 case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */
154 return put_int(arg, block_size(bdev));
155 case BLKSSZGET: /* get block device hardware sector size */
156 return put_int(arg, bdev_hardsect_size(bdev));
157 case BLKSECTGET:
158 return put_ushort(arg, bdev_get_queue(bdev)->max_sectors);
159 case BLKRASET:
160 case BLKFRASET:
161 if(!capable(CAP_SYS_ADMIN))
162 return -EACCES;
163 bdi = blk_get_backing_dev_info(bdev);
164 if (bdi == NULL)
165 return -ENOTTY;
166 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
167 return 0;
168 case BLKBSZSET:
169 /* set the logical block size */
170 if (!capable(CAP_SYS_ADMIN))
171 return -EACCES;
172 if (!arg)
173 return -EINVAL;
174 if (get_user(n, (int __user *) arg))
175 return -EFAULT;
176 if (bd_claim(bdev, file) < 0)
177 return -EBUSY;
178 ret = set_blocksize(bdev, n);
179 bd_release(bdev);
180 return ret;
181 case BLKPG:
182 return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg);
183 case BLKRRPART:
184 return blkdev_reread_part(bdev);
185 case BLKGETSIZE:
186 if ((bdev->bd_inode->i_size >> 9) > ~0UL)
187 return -EFBIG;
188 return put_ulong(arg, bdev->bd_inode->i_size >> 9);
189 case BLKGETSIZE64:
190 return put_u64(arg, bdev->bd_inode->i_size);
191 }
192 return -ENOIOCTLCMD;
193}
194
195static int blkdev_driver_ioctl(struct inode *inode, struct file *file,
196 struct gendisk *disk, unsigned cmd, unsigned long arg)
197{
198 int ret;
199 if (disk->fops->unlocked_ioctl)
200 return disk->fops->unlocked_ioctl(file, cmd, arg);
201
202 if (disk->fops->ioctl) {
203 lock_kernel();
204 ret = disk->fops->ioctl(inode, file, cmd, arg);
205 unlock_kernel();
206 return ret;
207 }
208
209 return -ENOTTY;
210}
211
212int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
213 unsigned long arg)
214{
215 struct block_device *bdev = inode->i_bdev;
216 struct gendisk *disk = bdev->bd_disk;
217 int ret, n;
218
219 switch(cmd) {
220 case BLKFLSBUF:
221 if (!capable(CAP_SYS_ADMIN))
222 return -EACCES;
223
224 ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
225 /* -EINVAL to handle old uncorrected drivers */
226 if (ret != -EINVAL && ret != -ENOTTY)
227 return ret;
228
229 lock_kernel();
230 fsync_bdev(bdev);
231 invalidate_bdev(bdev, 0);
232 unlock_kernel();
233 return 0;
234
235 case BLKROSET:
236 ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
237 /* -EINVAL to handle old uncorrected drivers */
238 if (ret != -EINVAL && ret != -ENOTTY)
239 return ret;
240 if (!capable(CAP_SYS_ADMIN))
241 return -EACCES;
242 if (get_user(n, (int __user *)(arg)))
243 return -EFAULT;
244 lock_kernel();
245 set_device_ro(bdev, n);
246 unlock_kernel();
247 return 0;
248 }
249
250 lock_kernel();
251 ret = blkdev_locked_ioctl(file, bdev, cmd, arg);
252 unlock_kernel();
253 if (ret != -ENOIOCTLCMD)
254 return ret;
255
256 return blkdev_driver_ioctl(inode, file, disk, cmd, arg);
257}
258
259/* Most of the generic ioctls are handled in the normal fallback path.
260 This assumes the blkdev's low level compat_ioctl always returns
261 ENOIOCTLCMD for unknown ioctls. */
262long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
263{
264 struct block_device *bdev = file->f_dentry->d_inode->i_bdev;
265 struct gendisk *disk = bdev->bd_disk;
266 int ret = -ENOIOCTLCMD;
267 if (disk->fops->compat_ioctl) {
268 lock_kernel();
269 ret = disk->fops->compat_ioctl(file, cmd, arg);
270 unlock_kernel();
271 }
272 return ret;
273}
274
275EXPORT_SYMBOL_GPL(blkdev_ioctl);
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
deleted file mode 100644
index 2747741677fb..000000000000
--- a/drivers/block/ll_rw_blk.c
+++ /dev/null
@@ -1,3613 +0,0 @@
1/*
2 * linux/drivers/block/ll_rw_blk.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 1994, Karl Keyte: Added support for disk statistics
6 * Elevator latency, (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
7 * Queue request tables / lock, selectable elevator, Jens Axboe <axboe@suse.de>
8 * kernel-doc documentation started by NeilBrown <neilb@cse.unsw.edu.au> - July2000
9 * bio rewrite, highmem i/o, etc, Jens Axboe <axboe@suse.de> - may 2001
10 */
11
12/*
13 * This handles all read/write requests to block devices
14 */
15#include <linux/config.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/backing-dev.h>
19#include <linux/bio.h>
20#include <linux/blkdev.h>
21#include <linux/highmem.h>
22#include <linux/mm.h>
23#include <linux/kernel_stat.h>
24#include <linux/string.h>
25#include <linux/init.h>
26#include <linux/bootmem.h> /* for max_pfn/max_low_pfn */
27#include <linux/completion.h>
28#include <linux/slab.h>
29#include <linux/swap.h>
30#include <linux/writeback.h>
31#include <linux/blkdev.h>
32
33/*
34 * for max sense size
35 */
36#include <scsi/scsi_cmnd.h>
37
38static void blk_unplug_work(void *data);
39static void blk_unplug_timeout(unsigned long data);
40static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io);
41
42/*
43 * For the allocated request tables
44 */
45static kmem_cache_t *request_cachep;
46
47/*
48 * For queue allocation
49 */
50static kmem_cache_t *requestq_cachep;
51
52/*
53 * For io context allocations
54 */
55static kmem_cache_t *iocontext_cachep;
56
57static wait_queue_head_t congestion_wqh[2] = {
58 __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
59 __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
60 };
61
62/*
63 * Controlling structure to kblockd
64 */
65static struct workqueue_struct *kblockd_workqueue;
66
67unsigned long blk_max_low_pfn, blk_max_pfn;
68
69EXPORT_SYMBOL(blk_max_low_pfn);
70EXPORT_SYMBOL(blk_max_pfn);
71
72/* Amount of time in which a process may batch requests */
73#define BLK_BATCH_TIME (HZ/50UL)
74
75/* Number of requests a "batching" process may submit */
76#define BLK_BATCH_REQ 32
77
78/*
79 * Return the threshold (number of used requests) at which the queue is
80 * considered to be congested. It include a little hysteresis to keep the
81 * context switch rate down.
82 */
83static inline int queue_congestion_on_threshold(struct request_queue *q)
84{
85 return q->nr_congestion_on;
86}
87
88/*
89 * The threshold at which a queue is considered to be uncongested
90 */
91static inline int queue_congestion_off_threshold(struct request_queue *q)
92{
93 return q->nr_congestion_off;
94}
95
96static void blk_queue_congestion_threshold(struct request_queue *q)
97{
98 int nr;
99
100 nr = q->nr_requests - (q->nr_requests / 8) + 1;
101 if (nr > q->nr_requests)
102 nr = q->nr_requests;
103 q->nr_congestion_on = nr;
104
105 nr = q->nr_requests - (q->nr_requests / 8) - (q->nr_requests / 16) - 1;
106 if (nr < 1)
107 nr = 1;
108 q->nr_congestion_off = nr;
109}
110
111/*
112 * A queue has just exitted congestion. Note this in the global counter of
113 * congested queues, and wake up anyone who was waiting for requests to be
114 * put back.
115 */
116static void clear_queue_congested(request_queue_t *q, int rw)
117{
118 enum bdi_state bit;
119 wait_queue_head_t *wqh = &congestion_wqh[rw];
120
121 bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
122 clear_bit(bit, &q->backing_dev_info.state);
123 smp_mb__after_clear_bit();
124 if (waitqueue_active(wqh))
125 wake_up(wqh);
126}
127
128/*
129 * A queue has just entered congestion. Flag that in the queue's VM-visible
130 * state flags and increment the global gounter of congested queues.
131 */
132static void set_queue_congested(request_queue_t *q, int rw)
133{
134 enum bdi_state bit;
135
136 bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested;
137 set_bit(bit, &q->backing_dev_info.state);
138}
139
140/**
141 * blk_get_backing_dev_info - get the address of a queue's backing_dev_info
142 * @bdev: device
143 *
144 * Locates the passed device's request queue and returns the address of its
145 * backing_dev_info
146 *
147 * Will return NULL if the request queue cannot be located.
148 */
149struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev)
150{
151 struct backing_dev_info *ret = NULL;
152 request_queue_t *q = bdev_get_queue(bdev);
153
154 if (q)
155 ret = &q->backing_dev_info;
156 return ret;
157}
158
159EXPORT_SYMBOL(blk_get_backing_dev_info);
160
161void blk_queue_activity_fn(request_queue_t *q, activity_fn *fn, void *data)
162{
163 q->activity_fn = fn;
164 q->activity_data = data;
165}
166
167EXPORT_SYMBOL(blk_queue_activity_fn);
168
169/**
170 * blk_queue_prep_rq - set a prepare_request function for queue
171 * @q: queue
172 * @pfn: prepare_request function
173 *
174 * It's possible for a queue to register a prepare_request callback which
175 * is invoked before the request is handed to the request_fn. The goal of
176 * the function is to prepare a request for I/O, it can be used to build a
177 * cdb from the request data for instance.
178 *
179 */
180void blk_queue_prep_rq(request_queue_t *q, prep_rq_fn *pfn)
181{
182 q->prep_rq_fn = pfn;
183}
184
185EXPORT_SYMBOL(blk_queue_prep_rq);
186
187/**
188 * blk_queue_merge_bvec - set a merge_bvec function for queue
189 * @q: queue
190 * @mbfn: merge_bvec_fn
191 *
192 * Usually queues have static limitations on the max sectors or segments that
193 * we can put in a request. Stacking drivers may have some settings that
194 * are dynamic, and thus we have to query the queue whether it is ok to
195 * add a new bio_vec to a bio at a given offset or not. If the block device
196 * has such limitations, it needs to register a merge_bvec_fn to control
197 * the size of bio's sent to it. Note that a block device *must* allow a
198 * single page to be added to an empty bio. The block device driver may want
199 * to use the bio_split() function to deal with these bio's. By default
200 * no merge_bvec_fn is defined for a queue, and only the fixed limits are
201 * honored.
202 */
203void blk_queue_merge_bvec(request_queue_t *q, merge_bvec_fn *mbfn)
204{
205 q->merge_bvec_fn = mbfn;
206}
207
208EXPORT_SYMBOL(blk_queue_merge_bvec);
209
210/**
211 * blk_queue_make_request - define an alternate make_request function for a device
212 * @q: the request queue for the device to be affected
213 * @mfn: the alternate make_request function
214 *
215 * Description:
216 * The normal way for &struct bios to be passed to a device
217 * driver is for them to be collected into requests on a request
218 * queue, and then to allow the device driver to select requests
219 * off that queue when it is ready. This works well for many block
220 * devices. However some block devices (typically virtual devices
221 * such as md or lvm) do not benefit from the processing on the
222 * request queue, and are served best by having the requests passed
223 * directly to them. This can be achieved by providing a function
224 * to blk_queue_make_request().
225 *
226 * Caveat:
227 * The driver that does this *must* be able to deal appropriately
228 * with buffers in "highmemory". This can be accomplished by either calling
229 * __bio_kmap_atomic() to get a temporary kernel mapping, or by calling
230 * blk_queue_bounce() to create a buffer in normal memory.
231 **/
232void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn)
233{
234 /*
235 * set defaults
236 */
237 q->nr_requests = BLKDEV_MAX_RQ;
238 blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
239 blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
240 q->make_request_fn = mfn;
241 q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
242 q->backing_dev_info.state = 0;
243 q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
244 blk_queue_max_sectors(q, MAX_SECTORS);
245 blk_queue_hardsect_size(q, 512);
246 blk_queue_dma_alignment(q, 511);
247 blk_queue_congestion_threshold(q);
248 q->nr_batching = BLK_BATCH_REQ;
249
250 q->unplug_thresh = 4; /* hmm */
251 q->unplug_delay = (3 * HZ) / 1000; /* 3 milliseconds */
252 if (q->unplug_delay == 0)
253 q->unplug_delay = 1;
254
255 INIT_WORK(&q->unplug_work, blk_unplug_work, q);
256
257 q->unplug_timer.function = blk_unplug_timeout;
258 q->unplug_timer.data = (unsigned long)q;
259
260 /*
261 * by default assume old behaviour and bounce for any highmem page
262 */
263 blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);
264
265 blk_queue_activity_fn(q, NULL, NULL);
266}
267
268EXPORT_SYMBOL(blk_queue_make_request);
269
270static inline void rq_init(request_queue_t *q, struct request *rq)
271{
272 INIT_LIST_HEAD(&rq->queuelist);
273
274 rq->errors = 0;
275 rq->rq_status = RQ_ACTIVE;
276 rq->bio = rq->biotail = NULL;
277 rq->ioprio = 0;
278 rq->buffer = NULL;
279 rq->ref_count = 1;
280 rq->q = q;
281 rq->waiting = NULL;
282 rq->special = NULL;
283 rq->data_len = 0;
284 rq->data = NULL;
285 rq->nr_phys_segments = 0;
286 rq->sense = NULL;
287 rq->end_io = NULL;
288 rq->end_io_data = NULL;
289}
290
291/**
292 * blk_queue_ordered - does this queue support ordered writes
293 * @q: the request queue
294 * @flag: see below
295 *
296 * Description:
297 * For journalled file systems, doing ordered writes on a commit
298 * block instead of explicitly doing wait_on_buffer (which is bad
299 * for performance) can be a big win. Block drivers supporting this
300 * feature should call this function and indicate so.
301 *
302 **/
303void blk_queue_ordered(request_queue_t *q, int flag)
304{
305 switch (flag) {
306 case QUEUE_ORDERED_NONE:
307 if (q->flush_rq)
308 kmem_cache_free(request_cachep, q->flush_rq);
309 q->flush_rq = NULL;
310 q->ordered = flag;
311 break;
312 case QUEUE_ORDERED_TAG:
313 q->ordered = flag;
314 break;
315 case QUEUE_ORDERED_FLUSH:
316 q->ordered = flag;
317 if (!q->flush_rq)
318 q->flush_rq = kmem_cache_alloc(request_cachep,
319 GFP_KERNEL);
320 break;
321 default:
322 printk("blk_queue_ordered: bad value %d\n", flag);
323 break;
324 }
325}
326
327EXPORT_SYMBOL(blk_queue_ordered);
328
329/**
330 * blk_queue_issue_flush_fn - set function for issuing a flush
331 * @q: the request queue
332 * @iff: the function to be called issuing the flush
333 *
334 * Description:
335 * If a driver supports issuing a flush command, the support is notified
336 * to the block layer by defining it through this call.
337 *
338 **/
339void blk_queue_issue_flush_fn(request_queue_t *q, issue_flush_fn *iff)
340{
341 q->issue_flush_fn = iff;
342}
343
344EXPORT_SYMBOL(blk_queue_issue_flush_fn);
345
346/*
347 * Cache flushing for ordered writes handling
348 */
349static void blk_pre_flush_end_io(struct request *flush_rq)
350{
351 struct request *rq = flush_rq->end_io_data;
352 request_queue_t *q = rq->q;
353
354 elv_completed_request(q, flush_rq);
355
356 rq->flags |= REQ_BAR_PREFLUSH;
357
358 if (!flush_rq->errors)
359 elv_requeue_request(q, rq);
360 else {
361 q->end_flush_fn(q, flush_rq);
362 clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
363 q->request_fn(q);
364 }
365}
366
367static void blk_post_flush_end_io(struct request *flush_rq)
368{
369 struct request *rq = flush_rq->end_io_data;
370 request_queue_t *q = rq->q;
371
372 elv_completed_request(q, flush_rq);
373
374 rq->flags |= REQ_BAR_POSTFLUSH;
375
376 q->end_flush_fn(q, flush_rq);
377 clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
378 q->request_fn(q);
379}
380
381struct request *blk_start_pre_flush(request_queue_t *q, struct request *rq)
382{
383 struct request *flush_rq = q->flush_rq;
384
385 BUG_ON(!blk_barrier_rq(rq));
386
387 if (test_and_set_bit(QUEUE_FLAG_FLUSH, &q->queue_flags))
388 return NULL;
389
390 rq_init(q, flush_rq);
391 flush_rq->elevator_private = NULL;
392 flush_rq->flags = REQ_BAR_FLUSH;
393 flush_rq->rq_disk = rq->rq_disk;
394 flush_rq->rl = NULL;
395
396 /*
397 * prepare_flush returns 0 if no flush is needed, just mark both
398 * pre and post flush as done in that case
399 */
400 if (!q->prepare_flush_fn(q, flush_rq)) {
401 rq->flags |= REQ_BAR_PREFLUSH | REQ_BAR_POSTFLUSH;
402 clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
403 return rq;
404 }
405
406 /*
407 * some drivers dequeue requests right away, some only after io
408 * completion. make sure the request is dequeued.
409 */
410 if (!list_empty(&rq->queuelist))
411 blkdev_dequeue_request(rq);
412
413 flush_rq->end_io_data = rq;
414 flush_rq->end_io = blk_pre_flush_end_io;
415
416 __elv_add_request(q, flush_rq, ELEVATOR_INSERT_FRONT, 0);
417 return flush_rq;
418}
419
420static void blk_start_post_flush(request_queue_t *q, struct request *rq)
421{
422 struct request *flush_rq = q->flush_rq;
423
424 BUG_ON(!blk_barrier_rq(rq));
425
426 rq_init(q, flush_rq);
427 flush_rq->elevator_private = NULL;
428 flush_rq->flags = REQ_BAR_FLUSH;
429 flush_rq->rq_disk = rq->rq_disk;
430 flush_rq->rl = NULL;
431
432 if (q->prepare_flush_fn(q, flush_rq)) {
433 flush_rq->end_io_data = rq;
434 flush_rq->end_io = blk_post_flush_end_io;
435
436 __elv_add_request(q, flush_rq, ELEVATOR_INSERT_FRONT, 0);
437 q->request_fn(q);
438 }
439}
440
441static inline int blk_check_end_barrier(request_queue_t *q, struct request *rq,
442 int sectors)
443{
444 if (sectors > rq->nr_sectors)
445 sectors = rq->nr_sectors;
446
447 rq->nr_sectors -= sectors;
448 return rq->nr_sectors;
449}
450
451static int __blk_complete_barrier_rq(request_queue_t *q, struct request *rq,
452 int sectors, int queue_locked)
453{
454 if (q->ordered != QUEUE_ORDERED_FLUSH)
455 return 0;
456 if (!blk_fs_request(rq) || !blk_barrier_rq(rq))
457 return 0;
458 if (blk_barrier_postflush(rq))
459 return 0;
460
461 if (!blk_check_end_barrier(q, rq, sectors)) {
462 unsigned long flags = 0;
463
464 if (!queue_locked)
465 spin_lock_irqsave(q->queue_lock, flags);
466
467 blk_start_post_flush(q, rq);
468
469 if (!queue_locked)
470 spin_unlock_irqrestore(q->queue_lock, flags);
471 }
472
473 return 1;
474}
475
476/**
477 * blk_complete_barrier_rq - complete possible barrier request
478 * @q: the request queue for the device
479 * @rq: the request
480 * @sectors: number of sectors to complete
481 *
482 * Description:
483 * Used in driver end_io handling to determine whether to postpone
484 * completion of a barrier request until a post flush has been done. This
485 * is the unlocked variant, used if the caller doesn't already hold the
486 * queue lock.
487 **/
488int blk_complete_barrier_rq(request_queue_t *q, struct request *rq, int sectors)
489{
490 return __blk_complete_barrier_rq(q, rq, sectors, 0);
491}
492EXPORT_SYMBOL(blk_complete_barrier_rq);
493
494/**
495 * blk_complete_barrier_rq_locked - complete possible barrier request
496 * @q: the request queue for the device
497 * @rq: the request
498 * @sectors: number of sectors to complete
499 *
500 * Description:
501 * See blk_complete_barrier_rq(). This variant must be used if the caller
502 * holds the queue lock.
503 **/
504int blk_complete_barrier_rq_locked(request_queue_t *q, struct request *rq,
505 int sectors)
506{
507 return __blk_complete_barrier_rq(q, rq, sectors, 1);
508}
509EXPORT_SYMBOL(blk_complete_barrier_rq_locked);
510
511/**
512 * blk_queue_bounce_limit - set bounce buffer limit for queue
513 * @q: the request queue for the device
514 * @dma_addr: bus address limit
515 *
516 * Description:
517 * Different hardware can have different requirements as to what pages
518 * it can do I/O directly to. A low level driver can call
519 * blk_queue_bounce_limit to have lower memory pages allocated as bounce
520 * buffers for doing I/O to pages residing above @page. By default
521 * the block layer sets this to the highest numbered "low" memory page.
522 **/
523void blk_queue_bounce_limit(request_queue_t *q, u64 dma_addr)
524{
525 unsigned long bounce_pfn = dma_addr >> PAGE_SHIFT;
526
527 /*
528 * set appropriate bounce gfp mask -- unfortunately we don't have a
529 * full 4GB zone, so we have to resort to low memory for any bounces.
530 * ISA has its own < 16MB zone.
531 */
532 if (bounce_pfn < blk_max_low_pfn) {
533 BUG_ON(dma_addr < BLK_BOUNCE_ISA);
534 init_emergency_isa_pool();
535 q->bounce_gfp = GFP_NOIO | GFP_DMA;
536 } else
537 q->bounce_gfp = GFP_NOIO;
538
539 q->bounce_pfn = bounce_pfn;
540}
541
542EXPORT_SYMBOL(blk_queue_bounce_limit);
543
544/**
545 * blk_queue_max_sectors - set max sectors for a request for this queue
546 * @q: the request queue for the device
547 * @max_sectors: max sectors in the usual 512b unit
548 *
549 * Description:
550 * Enables a low level driver to set an upper limit on the size of
551 * received requests.
552 **/
553void blk_queue_max_sectors(request_queue_t *q, unsigned short max_sectors)
554{
555 if ((max_sectors << 9) < PAGE_CACHE_SIZE) {
556 max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
557 printk("%s: set to minimum %d\n", __FUNCTION__, max_sectors);
558 }
559
560 q->max_sectors = q->max_hw_sectors = max_sectors;
561}
562
563EXPORT_SYMBOL(blk_queue_max_sectors);
564
565/**
566 * blk_queue_max_phys_segments - set max phys segments for a request for this queue
567 * @q: the request queue for the device
568 * @max_segments: max number of segments
569 *
570 * Description:
571 * Enables a low level driver to set an upper limit on the number of
572 * physical data segments in a request. This would be the largest sized
573 * scatter list the driver could handle.
574 **/
575void blk_queue_max_phys_segments(request_queue_t *q, unsigned short max_segments)
576{
577 if (!max_segments) {
578 max_segments = 1;
579 printk("%s: set to minimum %d\n", __FUNCTION__, max_segments);
580 }
581
582 q->max_phys_segments = max_segments;
583}
584
585EXPORT_SYMBOL(blk_queue_max_phys_segments);
586
587/**
588 * blk_queue_max_hw_segments - set max hw segments for a request for this queue
589 * @q: the request queue for the device
590 * @max_segments: max number of segments
591 *
592 * Description:
593 * Enables a low level driver to set an upper limit on the number of
594 * hw data segments in a request. This would be the largest number of
595 * address/length pairs the host adapter can actually give as once
596 * to the device.
597 **/
598void blk_queue_max_hw_segments(request_queue_t *q, unsigned short max_segments)
599{
600 if (!max_segments) {
601 max_segments = 1;
602 printk("%s: set to minimum %d\n", __FUNCTION__, max_segments);
603 }
604
605 q->max_hw_segments = max_segments;
606}
607
608EXPORT_SYMBOL(blk_queue_max_hw_segments);
609
610/**
611 * blk_queue_max_segment_size - set max segment size for blk_rq_map_sg
612 * @q: the request queue for the device
613 * @max_size: max size of segment in bytes
614 *
615 * Description:
616 * Enables a low level driver to set an upper limit on the size of a
617 * coalesced segment
618 **/
619void blk_queue_max_segment_size(request_queue_t *q, unsigned int max_size)
620{
621 if (max_size < PAGE_CACHE_SIZE) {
622 max_size = PAGE_CACHE_SIZE;
623 printk("%s: set to minimum %d\n", __FUNCTION__, max_size);
624 }
625
626 q->max_segment_size = max_size;
627}
628
629EXPORT_SYMBOL(blk_queue_max_segment_size);
630
631/**
632 * blk_queue_hardsect_size - set hardware sector size for the queue
633 * @q: the request queue for the device
634 * @size: the hardware sector size, in bytes
635 *
636 * Description:
637 * This should typically be set to the lowest possible sector size
638 * that the hardware can operate on (possible without reverting to
639 * even internal read-modify-write operations). Usually the default
640 * of 512 covers most hardware.
641 **/
642void blk_queue_hardsect_size(request_queue_t *q, unsigned short size)
643{
644 q->hardsect_size = size;
645}
646
647EXPORT_SYMBOL(blk_queue_hardsect_size);
648
649/*
650 * Returns the minimum that is _not_ zero, unless both are zero.
651 */
652#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r))
653
654/**
655 * blk_queue_stack_limits - inherit underlying queue limits for stacked drivers
656 * @t: the stacking driver (top)
657 * @b: the underlying device (bottom)
658 **/
659void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b)
660{
661 /* zero is "infinity" */
662 t->max_sectors = t->max_hw_sectors =
663 min_not_zero(t->max_sectors,b->max_sectors);
664
665 t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments);
666 t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);
667 t->max_segment_size = min(t->max_segment_size,b->max_segment_size);
668 t->hardsect_size = max(t->hardsect_size,b->hardsect_size);
669}
670
671EXPORT_SYMBOL(blk_queue_stack_limits);
672
673/**
674 * blk_queue_segment_boundary - set boundary rules for segment merging
675 * @q: the request queue for the device
676 * @mask: the memory boundary mask
677 **/
678void blk_queue_segment_boundary(request_queue_t *q, unsigned long mask)
679{
680 if (mask < PAGE_CACHE_SIZE - 1) {
681 mask = PAGE_CACHE_SIZE - 1;
682 printk("%s: set to minimum %lx\n", __FUNCTION__, mask);
683 }
684
685 q->seg_boundary_mask = mask;
686}
687
688EXPORT_SYMBOL(blk_queue_segment_boundary);
689
690/**
691 * blk_queue_dma_alignment - set dma length and memory alignment
692 * @q: the request queue for the device
693 * @mask: alignment mask
694 *
695 * description:
696 * set required memory and length aligment for direct dma transactions.
697 * this is used when buiding direct io requests for the queue.
698 *
699 **/
700void blk_queue_dma_alignment(request_queue_t *q, int mask)
701{
702 q->dma_alignment = mask;
703}
704
705EXPORT_SYMBOL(blk_queue_dma_alignment);
706
707/**
708 * blk_queue_find_tag - find a request by its tag and queue
709 *
710 * @q: The request queue for the device
711 * @tag: The tag of the request
712 *
713 * Notes:
714 * Should be used when a device returns a tag and you want to match
715 * it with a request.
716 *
717 * no locks need be held.
718 **/
719struct request *blk_queue_find_tag(request_queue_t *q, int tag)
720{
721 struct blk_queue_tag *bqt = q->queue_tags;
722
723 if (unlikely(bqt == NULL || tag >= bqt->real_max_depth))
724 return NULL;
725
726 return bqt->tag_index[tag];
727}
728
729EXPORT_SYMBOL(blk_queue_find_tag);
730
731/**
732 * __blk_queue_free_tags - release tag maintenance info
733 * @q: the request queue for the device
734 *
735 * Notes:
736 * blk_cleanup_queue() will take care of calling this function, if tagging
737 * has been used. So there's no need to call this directly.
738 **/
739static void __blk_queue_free_tags(request_queue_t *q)
740{
741 struct blk_queue_tag *bqt = q->queue_tags;
742
743 if (!bqt)
744 return;
745
746 if (atomic_dec_and_test(&bqt->refcnt)) {
747 BUG_ON(bqt->busy);
748 BUG_ON(!list_empty(&bqt->busy_list));
749
750 kfree(bqt->tag_index);
751 bqt->tag_index = NULL;
752
753 kfree(bqt->tag_map);
754 bqt->tag_map = NULL;
755
756 kfree(bqt);
757 }
758
759 q->queue_tags = NULL;
760 q->queue_flags &= ~(1 << QUEUE_FLAG_QUEUED);
761}
762
763/**
764 * blk_queue_free_tags - release tag maintenance info
765 * @q: the request queue for the device
766 *
767 * Notes:
768 * This is used to disabled tagged queuing to a device, yet leave
769 * queue in function.
770 **/
771void blk_queue_free_tags(request_queue_t *q)
772{
773 clear_bit(QUEUE_FLAG_QUEUED, &q->queue_flags);
774}
775
776EXPORT_SYMBOL(blk_queue_free_tags);
777
778static int
779init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth)
780{
781 struct request **tag_index;
782 unsigned long *tag_map;
783 int nr_ulongs;
784
785 if (depth > q->nr_requests * 2) {
786 depth = q->nr_requests * 2;
787 printk(KERN_ERR "%s: adjusted depth to %d\n",
788 __FUNCTION__, depth);
789 }
790
791 tag_index = kmalloc(depth * sizeof(struct request *), GFP_ATOMIC);
792 if (!tag_index)
793 goto fail;
794
795 nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG;
796 tag_map = kmalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC);
797 if (!tag_map)
798 goto fail;
799
800 memset(tag_index, 0, depth * sizeof(struct request *));
801 memset(tag_map, 0, nr_ulongs * sizeof(unsigned long));
802 tags->real_max_depth = depth;
803 tags->max_depth = depth;
804 tags->tag_index = tag_index;
805 tags->tag_map = tag_map;
806
807 return 0;
808fail:
809 kfree(tag_index);
810 return -ENOMEM;
811}
812
813/**
814 * blk_queue_init_tags - initialize the queue tag info
815 * @q: the request queue for the device
816 * @depth: the maximum queue depth supported
817 * @tags: the tag to use
818 **/
819int blk_queue_init_tags(request_queue_t *q, int depth,
820 struct blk_queue_tag *tags)
821{
822 int rc;
823
824 BUG_ON(tags && q->queue_tags && tags != q->queue_tags);
825
826 if (!tags && !q->queue_tags) {
827 tags = kmalloc(sizeof(struct blk_queue_tag), GFP_ATOMIC);
828 if (!tags)
829 goto fail;
830
831 if (init_tag_map(q, tags, depth))
832 goto fail;
833
834 INIT_LIST_HEAD(&tags->busy_list);
835 tags->busy = 0;
836 atomic_set(&tags->refcnt, 1);
837 } else if (q->queue_tags) {
838 if ((rc = blk_queue_resize_tags(q, depth)))
839 return rc;
840 set_bit(QUEUE_FLAG_QUEUED, &q->queue_flags);
841 return 0;
842 } else
843 atomic_inc(&tags->refcnt);
844
845 /*
846 * assign it, all done
847 */
848 q->queue_tags = tags;
849 q->queue_flags |= (1 << QUEUE_FLAG_QUEUED);
850 return 0;
851fail:
852 kfree(tags);
853 return -ENOMEM;
854}
855
856EXPORT_SYMBOL(blk_queue_init_tags);
857
858/**
859 * blk_queue_resize_tags - change the queueing depth
860 * @q: the request queue for the device
861 * @new_depth: the new max command queueing depth
862 *
863 * Notes:
864 * Must be called with the queue lock held.
865 **/
866int blk_queue_resize_tags(request_queue_t *q, int new_depth)
867{
868 struct blk_queue_tag *bqt = q->queue_tags;
869 struct request **tag_index;
870 unsigned long *tag_map;
871 int max_depth, nr_ulongs;
872
873 if (!bqt)
874 return -ENXIO;
875
876 /*
877 * if we already have large enough real_max_depth. just
878 * adjust max_depth. *NOTE* as requests with tag value
879 * between new_depth and real_max_depth can be in-flight, tag
880 * map can not be shrunk blindly here.
881 */
882 if (new_depth <= bqt->real_max_depth) {
883 bqt->max_depth = new_depth;
884 return 0;
885 }
886
887 /*
888 * save the old state info, so we can copy it back
889 */
890 tag_index = bqt->tag_index;
891 tag_map = bqt->tag_map;
892 max_depth = bqt->real_max_depth;
893
894 if (init_tag_map(q, bqt, new_depth))
895 return -ENOMEM;
896
897 memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *));
898 nr_ulongs = ALIGN(max_depth, BITS_PER_LONG) / BITS_PER_LONG;
899 memcpy(bqt->tag_map, tag_map, nr_ulongs * sizeof(unsigned long));
900
901 kfree(tag_index);
902 kfree(tag_map);
903 return 0;
904}
905
906EXPORT_SYMBOL(blk_queue_resize_tags);
907
908/**
909 * blk_queue_end_tag - end tag operations for a request
910 * @q: the request queue for the device
911 * @rq: the request that has completed
912 *
913 * Description:
914 * Typically called when end_that_request_first() returns 0, meaning
915 * all transfers have been done for a request. It's important to call
916 * this function before end_that_request_last(), as that will put the
917 * request back on the free list thus corrupting the internal tag list.
918 *
919 * Notes:
920 * queue lock must be held.
921 **/
922void blk_queue_end_tag(request_queue_t *q, struct request *rq)
923{
924 struct blk_queue_tag *bqt = q->queue_tags;
925 int tag = rq->tag;
926
927 BUG_ON(tag == -1);
928
929 if (unlikely(tag >= bqt->real_max_depth))
930 /*
931 * This can happen after tag depth has been reduced.
932 * FIXME: how about a warning or info message here?
933 */
934 return;
935
936 if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) {
937 printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
938 __FUNCTION__, tag);
939 return;
940 }
941
942 list_del_init(&rq->queuelist);
943 rq->flags &= ~REQ_QUEUED;
944 rq->tag = -1;
945
946 if (unlikely(bqt->tag_index[tag] == NULL))
947 printk(KERN_ERR "%s: tag %d is missing\n",
948 __FUNCTION__, tag);
949
950 bqt->tag_index[tag] = NULL;
951 bqt->busy--;
952}
953
954EXPORT_SYMBOL(blk_queue_end_tag);
955
956/**
957 * blk_queue_start_tag - find a free tag and assign it
958 * @q: the request queue for the device
959 * @rq: the block request that needs tagging
960 *
961 * Description:
962 * This can either be used as a stand-alone helper, or possibly be
963 * assigned as the queue &prep_rq_fn (in which case &struct request
964 * automagically gets a tag assigned). Note that this function
965 * assumes that any type of request can be queued! if this is not
966 * true for your device, you must check the request type before
967 * calling this function. The request will also be removed from
968 * the request queue, so it's the drivers responsibility to readd
969 * it if it should need to be restarted for some reason.
970 *
971 * Notes:
972 * queue lock must be held.
973 **/
974int blk_queue_start_tag(request_queue_t *q, struct request *rq)
975{
976 struct blk_queue_tag *bqt = q->queue_tags;
977 int tag;
978
979 if (unlikely((rq->flags & REQ_QUEUED))) {
980 printk(KERN_ERR
981 "%s: request %p for device [%s] already tagged %d",
982 __FUNCTION__, rq,
983 rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag);
984 BUG();
985 }
986
987 tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);
988 if (tag >= bqt->max_depth)
989 return 1;
990
991 __set_bit(tag, bqt->tag_map);
992
993 rq->flags |= REQ_QUEUED;
994 rq->tag = tag;
995 bqt->tag_index[tag] = rq;
996 blkdev_dequeue_request(rq);
997 list_add(&rq->queuelist, &bqt->busy_list);
998 bqt->busy++;
999 return 0;
1000}
1001
1002EXPORT_SYMBOL(blk_queue_start_tag);
1003
1004/**
1005 * blk_queue_invalidate_tags - invalidate all pending tags
1006 * @q: the request queue for the device
1007 *
1008 * Description:
1009 * Hardware conditions may dictate a need to stop all pending requests.
1010 * In this case, we will safely clear the block side of the tag queue and
1011 * readd all requests to the request queue in the right order.
1012 *
1013 * Notes:
1014 * queue lock must be held.
1015 **/
1016void blk_queue_invalidate_tags(request_queue_t *q)
1017{
1018 struct blk_queue_tag *bqt = q->queue_tags;
1019 struct list_head *tmp, *n;
1020 struct request *rq;
1021
1022 list_for_each_safe(tmp, n, &bqt->busy_list) {
1023 rq = list_entry_rq(tmp);
1024
1025 if (rq->tag == -1) {
1026 printk(KERN_ERR
1027 "%s: bad tag found on list\n", __FUNCTION__);
1028 list_del_init(&rq->queuelist);
1029 rq->flags &= ~REQ_QUEUED;
1030 } else
1031 blk_queue_end_tag(q, rq);
1032
1033 rq->flags &= ~REQ_STARTED;
1034 __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0);
1035 }
1036}
1037
1038EXPORT_SYMBOL(blk_queue_invalidate_tags);
1039
1040static char *rq_flags[] = {
1041 "REQ_RW",
1042 "REQ_FAILFAST",
1043 "REQ_SORTED",
1044 "REQ_SOFTBARRIER",
1045 "REQ_HARDBARRIER",
1046 "REQ_CMD",
1047 "REQ_NOMERGE",
1048 "REQ_STARTED",
1049 "REQ_DONTPREP",
1050 "REQ_QUEUED",
1051 "REQ_ELVPRIV",
1052 "REQ_PC",
1053 "REQ_BLOCK_PC",
1054 "REQ_SENSE",
1055 "REQ_FAILED",
1056 "REQ_QUIET",
1057 "REQ_SPECIAL",
1058 "REQ_DRIVE_CMD",
1059 "REQ_DRIVE_TASK",
1060 "REQ_DRIVE_TASKFILE",
1061 "REQ_PREEMPT",
1062 "REQ_PM_SUSPEND",
1063 "REQ_PM_RESUME",
1064 "REQ_PM_SHUTDOWN",
1065};
1066
1067void blk_dump_rq_flags(struct request *rq, char *msg)
1068{
1069 int bit;
1070
1071 printk("%s: dev %s: flags = ", msg,
1072 rq->rq_disk ? rq->rq_disk->disk_name : "?");
1073 bit = 0;
1074 do {
1075 if (rq->flags & (1 << bit))
1076 printk("%s ", rq_flags[bit]);
1077 bit++;
1078 } while (bit < __REQ_NR_BITS);
1079
1080 printk("\nsector %llu, nr/cnr %lu/%u\n", (unsigned long long)rq->sector,
1081 rq->nr_sectors,
1082 rq->current_nr_sectors);
1083 printk("bio %p, biotail %p, buffer %p, data %p, len %u\n", rq->bio, rq->biotail, rq->buffer, rq->data, rq->data_len);
1084
1085 if (rq->flags & (REQ_BLOCK_PC | REQ_PC)) {
1086 printk("cdb: ");
1087 for (bit = 0; bit < sizeof(rq->cmd); bit++)
1088 printk("%02x ", rq->cmd[bit]);
1089 printk("\n");
1090 }
1091}
1092
1093EXPORT_SYMBOL(blk_dump_rq_flags);
1094
1095void blk_recount_segments(request_queue_t *q, struct bio *bio)
1096{
1097 struct bio_vec *bv, *bvprv = NULL;
1098 int i, nr_phys_segs, nr_hw_segs, seg_size, hw_seg_size, cluster;
1099 int high, highprv = 1;
1100
1101 if (unlikely(!bio->bi_io_vec))
1102 return;
1103
1104 cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER);
1105 hw_seg_size = seg_size = nr_phys_segs = nr_hw_segs = 0;
1106 bio_for_each_segment(bv, bio, i) {
1107 /*
1108 * the trick here is making sure that a high page is never
1109 * considered part of another segment, since that might
1110 * change with the bounce page.
1111 */
1112 high = page_to_pfn(bv->bv_page) >= q->bounce_pfn;
1113 if (high || highprv)
1114 goto new_hw_segment;
1115 if (cluster) {
1116 if (seg_size + bv->bv_len > q->max_segment_size)
1117 goto new_segment;
1118 if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
1119 goto new_segment;
1120 if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
1121 goto new_segment;
1122 if (BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len))
1123 goto new_hw_segment;
1124
1125 seg_size += bv->bv_len;
1126 hw_seg_size += bv->bv_len;
1127 bvprv = bv;
1128 continue;
1129 }
1130new_segment:
1131 if (BIOVEC_VIRT_MERGEABLE(bvprv, bv) &&
1132 !BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len)) {
1133 hw_seg_size += bv->bv_len;
1134 } else {
1135new_hw_segment:
1136 if (hw_seg_size > bio->bi_hw_front_size)
1137 bio->bi_hw_front_size = hw_seg_size;
1138 hw_seg_size = BIOVEC_VIRT_START_SIZE(bv) + bv->bv_len;
1139 nr_hw_segs++;
1140 }
1141
1142 nr_phys_segs++;
1143 bvprv = bv;
1144 seg_size = bv->bv_len;
1145 highprv = high;
1146 }
1147 if (hw_seg_size > bio->bi_hw_back_size)
1148 bio->bi_hw_back_size = hw_seg_size;
1149 if (nr_hw_segs == 1 && hw_seg_size > bio->bi_hw_front_size)
1150 bio->bi_hw_front_size = hw_seg_size;
1151 bio->bi_phys_segments = nr_phys_segs;
1152 bio->bi_hw_segments = nr_hw_segs;
1153 bio->bi_flags |= (1 << BIO_SEG_VALID);
1154}
1155
1156
1157static int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
1158 struct bio *nxt)
1159{
1160 if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER)))
1161 return 0;
1162
1163 if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
1164 return 0;
1165 if (bio->bi_size + nxt->bi_size > q->max_segment_size)
1166 return 0;
1167
1168 /*
1169 * bio and nxt are contigous in memory, check if the queue allows
1170 * these two to be merged into one
1171 */
1172 if (BIO_SEG_BOUNDARY(q, bio, nxt))
1173 return 1;
1174
1175 return 0;
1176}
1177
1178static int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
1179 struct bio *nxt)
1180{
1181 if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
1182 blk_recount_segments(q, bio);
1183 if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID)))
1184 blk_recount_segments(q, nxt);
1185 if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) ||
1186 BIOVEC_VIRT_OVERSIZE(bio->bi_hw_front_size + bio->bi_hw_back_size))
1187 return 0;
1188 if (bio->bi_size + nxt->bi_size > q->max_segment_size)
1189 return 0;
1190
1191 return 1;
1192}
1193
1194/*
1195 * map a request to scatterlist, return number of sg entries setup. Caller
1196 * must make sure sg can hold rq->nr_phys_segments entries
1197 */
1198int blk_rq_map_sg(request_queue_t *q, struct request *rq, struct scatterlist *sg)
1199{
1200 struct bio_vec *bvec, *bvprv;
1201 struct bio *bio;
1202 int nsegs, i, cluster;
1203
1204 nsegs = 0;
1205 cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER);
1206
1207 /*
1208 * for each bio in rq
1209 */
1210 bvprv = NULL;
1211 rq_for_each_bio(bio, rq) {
1212 /*
1213 * for each segment in bio
1214 */
1215 bio_for_each_segment(bvec, bio, i) {
1216 int nbytes = bvec->bv_len;
1217
1218 if (bvprv && cluster) {
1219 if (sg[nsegs - 1].length + nbytes > q->max_segment_size)
1220 goto new_segment;
1221
1222 if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
1223 goto new_segment;
1224 if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
1225 goto new_segment;
1226
1227 sg[nsegs - 1].length += nbytes;
1228 } else {
1229new_segment:
1230 memset(&sg[nsegs],0,sizeof(struct scatterlist));
1231 sg[nsegs].page = bvec->bv_page;
1232 sg[nsegs].length = nbytes;
1233 sg[nsegs].offset = bvec->bv_offset;
1234
1235 nsegs++;
1236 }
1237 bvprv = bvec;
1238 } /* segments in bio */
1239 } /* bios in rq */
1240
1241 return nsegs;
1242}
1243
1244EXPORT_SYMBOL(blk_rq_map_sg);
1245
1246/*
1247 * the standard queue merge functions, can be overridden with device
1248 * specific ones if so desired
1249 */
1250
1251static inline int ll_new_mergeable(request_queue_t *q,
1252 struct request *req,
1253 struct bio *bio)
1254{
1255 int nr_phys_segs = bio_phys_segments(q, bio);
1256
1257 if (req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) {
1258 req->flags |= REQ_NOMERGE;
1259 if (req == q->last_merge)
1260 q->last_merge = NULL;
1261 return 0;
1262 }
1263
1264 /*
1265 * A hw segment is just getting larger, bump just the phys
1266 * counter.
1267 */
1268 req->nr_phys_segments += nr_phys_segs;
1269 return 1;
1270}
1271
1272static inline int ll_new_hw_segment(request_queue_t *q,
1273 struct request *req,
1274 struct bio *bio)
1275{
1276 int nr_hw_segs = bio_hw_segments(q, bio);
1277 int nr_phys_segs = bio_phys_segments(q, bio);
1278
1279 if (req->nr_hw_segments + nr_hw_segs > q->max_hw_segments
1280 || req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) {
1281 req->flags |= REQ_NOMERGE;
1282 if (req == q->last_merge)
1283 q->last_merge = NULL;
1284 return 0;
1285 }
1286
1287 /*
1288 * This will form the start of a new hw segment. Bump both
1289 * counters.
1290 */
1291 req->nr_hw_segments += nr_hw_segs;
1292 req->nr_phys_segments += nr_phys_segs;
1293 return 1;
1294}
1295
1296static int ll_back_merge_fn(request_queue_t *q, struct request *req,
1297 struct bio *bio)
1298{
1299 int len;
1300
1301 if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
1302 req->flags |= REQ_NOMERGE;
1303 if (req == q->last_merge)
1304 q->last_merge = NULL;
1305 return 0;
1306 }
1307 if (unlikely(!bio_flagged(req->biotail, BIO_SEG_VALID)))
1308 blk_recount_segments(q, req->biotail);
1309 if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
1310 blk_recount_segments(q, bio);
1311 len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size;
1312 if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio)) &&
1313 !BIOVEC_VIRT_OVERSIZE(len)) {
1314 int mergeable = ll_new_mergeable(q, req, bio);
1315
1316 if (mergeable) {
1317 if (req->nr_hw_segments == 1)
1318 req->bio->bi_hw_front_size = len;
1319 if (bio->bi_hw_segments == 1)
1320 bio->bi_hw_back_size = len;
1321 }
1322 return mergeable;
1323 }
1324
1325 return ll_new_hw_segment(q, req, bio);
1326}
1327
1328static int ll_front_merge_fn(request_queue_t *q, struct request *req,
1329 struct bio *bio)
1330{
1331 int len;
1332
1333 if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
1334 req->flags |= REQ_NOMERGE;
1335 if (req == q->last_merge)
1336 q->last_merge = NULL;
1337 return 0;
1338 }
1339 len = bio->bi_hw_back_size + req->bio->bi_hw_front_size;
1340 if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
1341 blk_recount_segments(q, bio);
1342 if (unlikely(!bio_flagged(req->bio, BIO_SEG_VALID)))
1343 blk_recount_segments(q, req->bio);
1344 if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) &&
1345 !BIOVEC_VIRT_OVERSIZE(len)) {
1346 int mergeable = ll_new_mergeable(q, req, bio);
1347
1348 if (mergeable) {
1349 if (bio->bi_hw_segments == 1)
1350 bio->bi_hw_front_size = len;
1351 if (req->nr_hw_segments == 1)
1352 req->biotail->bi_hw_back_size = len;
1353 }
1354 return mergeable;
1355 }
1356
1357 return ll_new_hw_segment(q, req, bio);
1358}
1359
1360static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
1361 struct request *next)
1362{
1363 int total_phys_segments;
1364 int total_hw_segments;
1365
1366 /*
1367 * First check if the either of the requests are re-queued
1368 * requests. Can't merge them if they are.
1369 */
1370 if (req->special || next->special)
1371 return 0;
1372
1373 /*
1374 * Will it become too large?
1375 */
1376 if ((req->nr_sectors + next->nr_sectors) > q->max_sectors)
1377 return 0;
1378
1379 total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
1380 if (blk_phys_contig_segment(q, req->biotail, next->bio))
1381 total_phys_segments--;
1382
1383 if (total_phys_segments > q->max_phys_segments)
1384 return 0;
1385
1386 total_hw_segments = req->nr_hw_segments + next->nr_hw_segments;
1387 if (blk_hw_contig_segment(q, req->biotail, next->bio)) {
1388 int len = req->biotail->bi_hw_back_size + next->bio->bi_hw_front_size;
1389 /*
1390 * propagate the combined length to the end of the requests
1391 */
1392 if (req->nr_hw_segments == 1)
1393 req->bio->bi_hw_front_size = len;
1394 if (next->nr_hw_segments == 1)
1395 next->biotail->bi_hw_back_size = len;
1396 total_hw_segments--;
1397 }
1398
1399 if (total_hw_segments > q->max_hw_segments)
1400 return 0;
1401
1402 /* Merge is OK... */
1403 req->nr_phys_segments = total_phys_segments;
1404 req->nr_hw_segments = total_hw_segments;
1405 return 1;
1406}
1407
1408/*
1409 * "plug" the device if there are no outstanding requests: this will
1410 * force the transfer to start only after we have put all the requests
1411 * on the list.
1412 *
1413 * This is called with interrupts off and no requests on the queue and
1414 * with the queue lock held.
1415 */
1416void blk_plug_device(request_queue_t *q)
1417{
1418 WARN_ON(!irqs_disabled());
1419
1420 /*
1421 * don't plug a stopped queue, it must be paired with blk_start_queue()
1422 * which will restart the queueing
1423 */
1424 if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
1425 return;
1426
1427 if (!test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
1428 mod_timer(&q->unplug_timer, jiffies + q->unplug_delay);
1429}
1430
1431EXPORT_SYMBOL(blk_plug_device);
1432
1433/*
1434 * remove the queue from the plugged list, if present. called with
1435 * queue lock held and interrupts disabled.
1436 */
1437int blk_remove_plug(request_queue_t *q)
1438{
1439 WARN_ON(!irqs_disabled());
1440
1441 if (!test_and_clear_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags))
1442 return 0;
1443
1444 del_timer(&q->unplug_timer);
1445 return 1;
1446}
1447
1448EXPORT_SYMBOL(blk_remove_plug);
1449
1450/*
1451 * remove the plug and let it rip..
1452 */
1453void __generic_unplug_device(request_queue_t *q)
1454{
1455 if (unlikely(test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)))
1456 return;
1457
1458 if (!blk_remove_plug(q))
1459 return;
1460
1461 q->request_fn(q);
1462}
1463EXPORT_SYMBOL(__generic_unplug_device);
1464
1465/**
1466 * generic_unplug_device - fire a request queue
1467 * @q: The &request_queue_t in question
1468 *
1469 * Description:
1470 * Linux uses plugging to build bigger requests queues before letting
1471 * the device have at them. If a queue is plugged, the I/O scheduler
1472 * is still adding and merging requests on the queue. Once the queue
1473 * gets unplugged, the request_fn defined for the queue is invoked and
1474 * transfers started.
1475 **/
1476void generic_unplug_device(request_queue_t *q)
1477{
1478 spin_lock_irq(q->queue_lock);
1479 __generic_unplug_device(q);
1480 spin_unlock_irq(q->queue_lock);
1481}
1482EXPORT_SYMBOL(generic_unplug_device);
1483
1484static void blk_backing_dev_unplug(struct backing_dev_info *bdi,
1485 struct page *page)
1486{
1487 request_queue_t *q = bdi->unplug_io_data;
1488
1489 /*
1490 * devices don't necessarily have an ->unplug_fn defined
1491 */
1492 if (q->unplug_fn)
1493 q->unplug_fn(q);
1494}
1495
1496static void blk_unplug_work(void *data)
1497{
1498 request_queue_t *q = data;
1499
1500 q->unplug_fn(q);
1501}
1502
1503static void blk_unplug_timeout(unsigned long data)
1504{
1505 request_queue_t *q = (request_queue_t *)data;
1506
1507 kblockd_schedule_work(&q->unplug_work);
1508}
1509
1510/**
1511 * blk_start_queue - restart a previously stopped queue
1512 * @q: The &request_queue_t in question
1513 *
1514 * Description:
1515 * blk_start_queue() will clear the stop flag on the queue, and call
1516 * the request_fn for the queue if it was in a stopped state when
1517 * entered. Also see blk_stop_queue(). Queue lock must be held.
1518 **/
1519void blk_start_queue(request_queue_t *q)
1520{
1521 clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags);
1522
1523 /*
1524 * one level of recursion is ok and is much faster than kicking
1525 * the unplug handling
1526 */
1527 if (!test_and_set_bit(QUEUE_FLAG_REENTER, &q->queue_flags)) {
1528 q->request_fn(q);
1529 clear_bit(QUEUE_FLAG_REENTER, &q->queue_flags);
1530 } else {
1531 blk_plug_device(q);
1532 kblockd_schedule_work(&q->unplug_work);
1533 }
1534}
1535
1536EXPORT_SYMBOL(blk_start_queue);
1537
1538/**
1539 * blk_stop_queue - stop a queue
1540 * @q: The &request_queue_t in question
1541 *
1542 * Description:
1543 * The Linux block layer assumes that a block driver will consume all
1544 * entries on the request queue when the request_fn strategy is called.
1545 * Often this will not happen, because of hardware limitations (queue
1546 * depth settings). If a device driver gets a 'queue full' response,
1547 * or if it simply chooses not to queue more I/O at one point, it can
1548 * call this function to prevent the request_fn from being called until
1549 * the driver has signalled it's ready to go again. This happens by calling
1550 * blk_start_queue() to restart queue operations. Queue lock must be held.
1551 **/
1552void blk_stop_queue(request_queue_t *q)
1553{
1554 blk_remove_plug(q);
1555 set_bit(QUEUE_FLAG_STOPPED, &q->queue_flags);
1556}
1557EXPORT_SYMBOL(blk_stop_queue);
1558
1559/**
1560 * blk_sync_queue - cancel any pending callbacks on a queue
1561 * @q: the queue
1562 *
1563 * Description:
1564 * The block layer may perform asynchronous callback activity
1565 * on a queue, such as calling the unplug function after a timeout.
1566 * A block device may call blk_sync_queue to ensure that any
1567 * such activity is cancelled, thus allowing it to release resources
1568 * the the callbacks might use. The caller must already have made sure
1569 * that its ->make_request_fn will not re-add plugging prior to calling
1570 * this function.
1571 *
1572 */
1573void blk_sync_queue(struct request_queue *q)
1574{
1575 del_timer_sync(&q->unplug_timer);
1576 kblockd_flush();
1577}
1578EXPORT_SYMBOL(blk_sync_queue);
1579
1580/**
1581 * blk_run_queue - run a single device queue
1582 * @q: The queue to run
1583 */
1584void blk_run_queue(struct request_queue *q)
1585{
1586 unsigned long flags;
1587
1588 spin_lock_irqsave(q->queue_lock, flags);
1589 blk_remove_plug(q);
1590 if (!elv_queue_empty(q))
1591 q->request_fn(q);
1592 spin_unlock_irqrestore(q->queue_lock, flags);
1593}
1594EXPORT_SYMBOL(blk_run_queue);
1595
1596/**
1597 * blk_cleanup_queue: - release a &request_queue_t when it is no longer needed
1598 * @q: the request queue to be released
1599 *
1600 * Description:
1601 * blk_cleanup_queue is the pair to blk_init_queue() or
1602 * blk_queue_make_request(). It should be called when a request queue is
1603 * being released; typically when a block device is being de-registered.
1604 * Currently, its primary task it to free all the &struct request
1605 * structures that were allocated to the queue and the queue itself.
1606 *
1607 * Caveat:
1608 * Hopefully the low level driver will have finished any
1609 * outstanding requests first...
1610 **/
1611void blk_cleanup_queue(request_queue_t * q)
1612{
1613 struct request_list *rl = &q->rq;
1614
1615 if (!atomic_dec_and_test(&q->refcnt))
1616 return;
1617
1618 if (q->elevator)
1619 elevator_exit(q->elevator);
1620
1621 blk_sync_queue(q);
1622
1623 if (rl->rq_pool)
1624 mempool_destroy(rl->rq_pool);
1625
1626 if (q->queue_tags)
1627 __blk_queue_free_tags(q);
1628
1629 blk_queue_ordered(q, QUEUE_ORDERED_NONE);
1630
1631 kmem_cache_free(requestq_cachep, q);
1632}
1633
1634EXPORT_SYMBOL(blk_cleanup_queue);
1635
1636static int blk_init_free_list(request_queue_t *q)
1637{
1638 struct request_list *rl = &q->rq;
1639
1640 rl->count[READ] = rl->count[WRITE] = 0;
1641 rl->starved[READ] = rl->starved[WRITE] = 0;
1642 rl->elvpriv = 0;
1643 init_waitqueue_head(&rl->wait[READ]);
1644 init_waitqueue_head(&rl->wait[WRITE]);
1645
1646 rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
1647 mempool_free_slab, request_cachep, q->node);
1648
1649 if (!rl->rq_pool)
1650 return -ENOMEM;
1651
1652 return 0;
1653}
1654
1655static int __make_request(request_queue_t *, struct bio *);
1656
1657request_queue_t *blk_alloc_queue(gfp_t gfp_mask)
1658{
1659 return blk_alloc_queue_node(gfp_mask, -1);
1660}
1661EXPORT_SYMBOL(blk_alloc_queue);
1662
1663request_queue_t *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
1664{
1665 request_queue_t *q;
1666
1667 q = kmem_cache_alloc_node(requestq_cachep, gfp_mask, node_id);
1668 if (!q)
1669 return NULL;
1670
1671 memset(q, 0, sizeof(*q));
1672 init_timer(&q->unplug_timer);
1673 atomic_set(&q->refcnt, 1);
1674
1675 q->backing_dev_info.unplug_io_fn = blk_backing_dev_unplug;
1676 q->backing_dev_info.unplug_io_data = q;
1677
1678 return q;
1679}
1680EXPORT_SYMBOL(blk_alloc_queue_node);
1681
1682/**
1683 * blk_init_queue - prepare a request queue for use with a block device
1684 * @rfn: The function to be called to process requests that have been
1685 * placed on the queue.
1686 * @lock: Request queue spin lock
1687 *
1688 * Description:
1689 * If a block device wishes to use the standard request handling procedures,
1690 * which sorts requests and coalesces adjacent requests, then it must
1691 * call blk_init_queue(). The function @rfn will be called when there
1692 * are requests on the queue that need to be processed. If the device
1693 * supports plugging, then @rfn may not be called immediately when requests
1694 * are available on the queue, but may be called at some time later instead.
1695 * Plugged queues are generally unplugged when a buffer belonging to one
1696 * of the requests on the queue is needed, or due to memory pressure.
1697 *
1698 * @rfn is not required, or even expected, to remove all requests off the
1699 * queue, but only as many as it can handle at a time. If it does leave
1700 * requests on the queue, it is responsible for arranging that the requests
1701 * get dealt with eventually.
1702 *
1703 * The queue spin lock must be held while manipulating the requests on the
1704 * request queue.
1705 *
1706 * Function returns a pointer to the initialized request queue, or NULL if
1707 * it didn't succeed.
1708 *
1709 * Note:
1710 * blk_init_queue() must be paired with a blk_cleanup_queue() call
1711 * when the block device is deactivated (such as at module unload).
1712 **/
1713
1714request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)
1715{
1716 return blk_init_queue_node(rfn, lock, -1);
1717}
1718EXPORT_SYMBOL(blk_init_queue);
1719
1720request_queue_t *
1721blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
1722{
1723 request_queue_t *q = blk_alloc_queue_node(GFP_KERNEL, node_id);
1724
1725 if (!q)
1726 return NULL;
1727
1728 q->node = node_id;
1729 if (blk_init_free_list(q))
1730 goto out_init;
1731
1732 /*
1733 * if caller didn't supply a lock, they get per-queue locking with
1734 * our embedded lock
1735 */
1736 if (!lock) {
1737 spin_lock_init(&q->__queue_lock);
1738 lock = &q->__queue_lock;
1739 }
1740
1741 q->request_fn = rfn;
1742 q->back_merge_fn = ll_back_merge_fn;
1743 q->front_merge_fn = ll_front_merge_fn;
1744 q->merge_requests_fn = ll_merge_requests_fn;
1745 q->prep_rq_fn = NULL;
1746 q->unplug_fn = generic_unplug_device;
1747 q->queue_flags = (1 << QUEUE_FLAG_CLUSTER);
1748 q->queue_lock = lock;
1749
1750 blk_queue_segment_boundary(q, 0xffffffff);
1751
1752 blk_queue_make_request(q, __make_request);
1753 blk_queue_max_segment_size(q, MAX_SEGMENT_SIZE);
1754
1755 blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS);
1756 blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS);
1757
1758 /*
1759 * all done
1760 */
1761 if (!elevator_init(q, NULL)) {
1762 blk_queue_congestion_threshold(q);
1763 return q;
1764 }
1765
1766 blk_cleanup_queue(q);
1767out_init:
1768 kmem_cache_free(requestq_cachep, q);
1769 return NULL;
1770}
1771EXPORT_SYMBOL(blk_init_queue_node);
1772
1773int blk_get_queue(request_queue_t *q)
1774{
1775 if (likely(!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
1776 atomic_inc(&q->refcnt);
1777 return 0;
1778 }
1779
1780 return 1;
1781}
1782
1783EXPORT_SYMBOL(blk_get_queue);
1784
1785static inline void blk_free_request(request_queue_t *q, struct request *rq)
1786{
1787 if (rq->flags & REQ_ELVPRIV)
1788 elv_put_request(q, rq);
1789 mempool_free(rq, q->rq.rq_pool);
1790}
1791
1792static inline struct request *
1793blk_alloc_request(request_queue_t *q, int rw, struct bio *bio,
1794 int priv, gfp_t gfp_mask)
1795{
1796 struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask);
1797
1798 if (!rq)
1799 return NULL;
1800
1801 /*
1802 * first three bits are identical in rq->flags and bio->bi_rw,
1803 * see bio.h and blkdev.h
1804 */
1805 rq->flags = rw;
1806
1807 if (priv) {
1808 if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) {
1809 mempool_free(rq, q->rq.rq_pool);
1810 return NULL;
1811 }
1812 rq->flags |= REQ_ELVPRIV;
1813 }
1814
1815 return rq;
1816}
1817
1818/*
1819 * ioc_batching returns true if the ioc is a valid batching request and
1820 * should be given priority access to a request.
1821 */
1822static inline int ioc_batching(request_queue_t *q, struct io_context *ioc)
1823{
1824 if (!ioc)
1825 return 0;
1826
1827 /*
1828 * Make sure the process is able to allocate at least 1 request
1829 * even if the batch times out, otherwise we could theoretically
1830 * lose wakeups.
1831 */
1832 return ioc->nr_batch_requests == q->nr_batching ||
1833 (ioc->nr_batch_requests > 0
1834 && time_before(jiffies, ioc->last_waited + BLK_BATCH_TIME));
1835}
1836
1837/*
1838 * ioc_set_batching sets ioc to be a new "batcher" if it is not one. This
1839 * will cause the process to be a "batcher" on all queues in the system. This
1840 * is the behaviour we want though - once it gets a wakeup it should be given
1841 * a nice run.
1842 */
1843static void ioc_set_batching(request_queue_t *q, struct io_context *ioc)
1844{
1845 if (!ioc || ioc_batching(q, ioc))
1846 return;
1847
1848 ioc->nr_batch_requests = q->nr_batching;
1849 ioc->last_waited = jiffies;
1850}
1851
1852static void __freed_request(request_queue_t *q, int rw)
1853{
1854 struct request_list *rl = &q->rq;
1855
1856 if (rl->count[rw] < queue_congestion_off_threshold(q))
1857 clear_queue_congested(q, rw);
1858
1859 if (rl->count[rw] + 1 <= q->nr_requests) {
1860 if (waitqueue_active(&rl->wait[rw]))
1861 wake_up(&rl->wait[rw]);
1862
1863 blk_clear_queue_full(q, rw);
1864 }
1865}
1866
1867/*
1868 * A request has just been released. Account for it, update the full and
1869 * congestion status, wake up any waiters. Called under q->queue_lock.
1870 */
1871static void freed_request(request_queue_t *q, int rw, int priv)
1872{
1873 struct request_list *rl = &q->rq;
1874
1875 rl->count[rw]--;
1876 if (priv)
1877 rl->elvpriv--;
1878
1879 __freed_request(q, rw);
1880
1881 if (unlikely(rl->starved[rw ^ 1]))
1882 __freed_request(q, rw ^ 1);
1883}
1884
1885#define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist)
1886/*
1887 * Get a free request, queue_lock must be held.
1888 * Returns NULL on failure, with queue_lock held.
1889 * Returns !NULL on success, with queue_lock *not held*.
1890 */
1891static struct request *get_request(request_queue_t *q, int rw, struct bio *bio,
1892 gfp_t gfp_mask)
1893{
1894 struct request *rq = NULL;
1895 struct request_list *rl = &q->rq;
1896 struct io_context *ioc = current_io_context(GFP_ATOMIC);
1897 int priv;
1898
1899 if (rl->count[rw]+1 >= q->nr_requests) {
1900 /*
1901 * The queue will fill after this allocation, so set it as
1902 * full, and mark this process as "batching". This process
1903 * will be allowed to complete a batch of requests, others
1904 * will be blocked.
1905 */
1906 if (!blk_queue_full(q, rw)) {
1907 ioc_set_batching(q, ioc);
1908 blk_set_queue_full(q, rw);
1909 }
1910 }
1911
1912 switch (elv_may_queue(q, rw, bio)) {
1913 case ELV_MQUEUE_NO:
1914 goto rq_starved;
1915 case ELV_MQUEUE_MAY:
1916 break;
1917 case ELV_MQUEUE_MUST:
1918 goto get_rq;
1919 }
1920
1921 if (blk_queue_full(q, rw) && !ioc_batching(q, ioc)) {
1922 /*
1923 * The queue is full and the allocating process is not a
1924 * "batcher", and not exempted by the IO scheduler
1925 */
1926 goto out;
1927 }
1928
1929get_rq:
1930 /*
1931 * Only allow batching queuers to allocate up to 50% over the defined
1932 * limit of requests, otherwise we could have thousands of requests
1933 * allocated with any setting of ->nr_requests
1934 */
1935 if (rl->count[rw] >= (3 * q->nr_requests / 2))
1936 goto out;
1937
1938 rl->count[rw]++;
1939 rl->starved[rw] = 0;
1940 if (rl->count[rw] >= queue_congestion_on_threshold(q))
1941 set_queue_congested(q, rw);
1942
1943 priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
1944 if (priv)
1945 rl->elvpriv++;
1946
1947 spin_unlock_irq(q->queue_lock);
1948
1949 rq = blk_alloc_request(q, rw, bio, priv, gfp_mask);
1950 if (!rq) {
1951 /*
1952 * Allocation failed presumably due to memory. Undo anything
1953 * we might have messed up.
1954 *
1955 * Allocating task should really be put onto the front of the
1956 * wait queue, but this is pretty rare.
1957 */
1958 spin_lock_irq(q->queue_lock);
1959 freed_request(q, rw, priv);
1960
1961 /*
1962 * in the very unlikely event that allocation failed and no
1963 * requests for this direction was pending, mark us starved
1964 * so that freeing of a request in the other direction will
1965 * notice us. another possible fix would be to split the
1966 * rq mempool into READ and WRITE
1967 */
1968rq_starved:
1969 if (unlikely(rl->count[rw] == 0))
1970 rl->starved[rw] = 1;
1971
1972 goto out;
1973 }
1974
1975 if (ioc_batching(q, ioc))
1976 ioc->nr_batch_requests--;
1977
1978 rq_init(q, rq);
1979 rq->rl = rl;
1980out:
1981 return rq;
1982}
1983
1984/*
1985 * No available requests for this queue, unplug the device and wait for some
1986 * requests to become available.
1987 *
1988 * Called with q->queue_lock held, and returns with it unlocked.
1989 */
1990static struct request *get_request_wait(request_queue_t *q, int rw,
1991 struct bio *bio)
1992{
1993 struct request *rq;
1994
1995 rq = get_request(q, rw, bio, GFP_NOIO);
1996 while (!rq) {
1997 DEFINE_WAIT(wait);
1998 struct request_list *rl = &q->rq;
1999
2000 prepare_to_wait_exclusive(&rl->wait[rw], &wait,
2001 TASK_UNINTERRUPTIBLE);
2002
2003 rq = get_request(q, rw, bio, GFP_NOIO);
2004
2005 if (!rq) {
2006 struct io_context *ioc;
2007
2008 __generic_unplug_device(q);
2009 spin_unlock_irq(q->queue_lock);
2010 io_schedule();
2011
2012 /*
2013 * After sleeping, we become a "batching" process and
2014 * will be able to allocate at least one request, and
2015 * up to a big batch of them for a small period time.
2016 * See ioc_batching, ioc_set_batching
2017 */
2018 ioc = current_io_context(GFP_NOIO);
2019 ioc_set_batching(q, ioc);
2020
2021 spin_lock_irq(q->queue_lock);
2022 }
2023 finish_wait(&rl->wait[rw], &wait);
2024 }
2025
2026 return rq;
2027}
2028
2029struct request *blk_get_request(request_queue_t *q, int rw, gfp_t gfp_mask)
2030{
2031 struct request *rq;
2032
2033 BUG_ON(rw != READ && rw != WRITE);
2034
2035 spin_lock_irq(q->queue_lock);
2036 if (gfp_mask & __GFP_WAIT) {
2037 rq = get_request_wait(q, rw, NULL);
2038 } else {
2039 rq = get_request(q, rw, NULL, gfp_mask);
2040 if (!rq)
2041 spin_unlock_irq(q->queue_lock);
2042 }
2043 /* q->queue_lock is unlocked at this point */
2044
2045 return rq;
2046}
2047EXPORT_SYMBOL(blk_get_request);
2048
2049/**
2050 * blk_requeue_request - put a request back on queue
2051 * @q: request queue where request should be inserted
2052 * @rq: request to be inserted
2053 *
2054 * Description:
2055 * Drivers often keep queueing requests until the hardware cannot accept
2056 * more, when that condition happens we need to put the request back
2057 * on the queue. Must be called with queue lock held.
2058 */
2059void blk_requeue_request(request_queue_t *q, struct request *rq)
2060{
2061 if (blk_rq_tagged(rq))
2062 blk_queue_end_tag(q, rq);
2063
2064 elv_requeue_request(q, rq);
2065}
2066
2067EXPORT_SYMBOL(blk_requeue_request);
2068
2069/**
2070 * blk_insert_request - insert a special request in to a request queue
2071 * @q: request queue where request should be inserted
2072 * @rq: request to be inserted
2073 * @at_head: insert request at head or tail of queue
2074 * @data: private data
2075 *
2076 * Description:
2077 * Many block devices need to execute commands asynchronously, so they don't
2078 * block the whole kernel from preemption during request execution. This is
2079 * accomplished normally by inserting aritficial requests tagged as
2080 * REQ_SPECIAL in to the corresponding request queue, and letting them be
2081 * scheduled for actual execution by the request queue.
2082 *
2083 * We have the option of inserting the head or the tail of the queue.
2084 * Typically we use the tail for new ioctls and so forth. We use the head
2085 * of the queue for things like a QUEUE_FULL message from a device, or a
2086 * host that is unable to accept a particular command.
2087 */
2088void blk_insert_request(request_queue_t *q, struct request *rq,
2089 int at_head, void *data)
2090{
2091 int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
2092 unsigned long flags;
2093
2094 /*
2095 * tell I/O scheduler that this isn't a regular read/write (ie it
2096 * must not attempt merges on this) and that it acts as a soft
2097 * barrier
2098 */
2099 rq->flags |= REQ_SPECIAL | REQ_SOFTBARRIER;
2100
2101 rq->special = data;
2102
2103 spin_lock_irqsave(q->queue_lock, flags);
2104
2105 /*
2106 * If command is tagged, release the tag
2107 */
2108 if (blk_rq_tagged(rq))
2109 blk_queue_end_tag(q, rq);
2110
2111 drive_stat_acct(rq, rq->nr_sectors, 1);
2112 __elv_add_request(q, rq, where, 0);
2113
2114 if (blk_queue_plugged(q))
2115 __generic_unplug_device(q);
2116 else
2117 q->request_fn(q);
2118 spin_unlock_irqrestore(q->queue_lock, flags);
2119}
2120
2121EXPORT_SYMBOL(blk_insert_request);
2122
2123/**
2124 * blk_rq_map_user - map user data to a request, for REQ_BLOCK_PC usage
2125 * @q: request queue where request should be inserted
2126 * @rq: request structure to fill
2127 * @ubuf: the user buffer
2128 * @len: length of user data
2129 *
2130 * Description:
2131 * Data will be mapped directly for zero copy io, if possible. Otherwise
2132 * a kernel bounce buffer is used.
2133 *
2134 * A matching blk_rq_unmap_user() must be issued at the end of io, while
2135 * still in process context.
2136 *
2137 * Note: The mapped bio may need to be bounced through blk_queue_bounce()
2138 * before being submitted to the device, as pages mapped may be out of
2139 * reach. It's the callers responsibility to make sure this happens. The
2140 * original bio must be passed back in to blk_rq_unmap_user() for proper
2141 * unmapping.
2142 */
2143int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
2144 unsigned int len)
2145{
2146 unsigned long uaddr;
2147 struct bio *bio;
2148 int reading;
2149
2150 if (len > (q->max_sectors << 9))
2151 return -EINVAL;
2152 if (!len || !ubuf)
2153 return -EINVAL;
2154
2155 reading = rq_data_dir(rq) == READ;
2156
2157 /*
2158 * if alignment requirement is satisfied, map in user pages for
2159 * direct dma. else, set up kernel bounce buffers
2160 */
2161 uaddr = (unsigned long) ubuf;
2162 if (!(uaddr & queue_dma_alignment(q)) && !(len & queue_dma_alignment(q)))
2163 bio = bio_map_user(q, NULL, uaddr, len, reading);
2164 else
2165 bio = bio_copy_user(q, uaddr, len, reading);
2166
2167 if (!IS_ERR(bio)) {
2168 rq->bio = rq->biotail = bio;
2169 blk_rq_bio_prep(q, rq, bio);
2170
2171 rq->buffer = rq->data = NULL;
2172 rq->data_len = len;
2173 return 0;
2174 }
2175
2176 /*
2177 * bio is the err-ptr
2178 */
2179 return PTR_ERR(bio);
2180}
2181
2182EXPORT_SYMBOL(blk_rq_map_user);
2183
2184/**
2185 * blk_rq_map_user_iov - map user data to a request, for REQ_BLOCK_PC usage
2186 * @q: request queue where request should be inserted
2187 * @rq: request to map data to
2188 * @iov: pointer to the iovec
2189 * @iov_count: number of elements in the iovec
2190 *
2191 * Description:
2192 * Data will be mapped directly for zero copy io, if possible. Otherwise
2193 * a kernel bounce buffer is used.
2194 *
2195 * A matching blk_rq_unmap_user() must be issued at the end of io, while
2196 * still in process context.
2197 *
2198 * Note: The mapped bio may need to be bounced through blk_queue_bounce()
2199 * before being submitted to the device, as pages mapped may be out of
2200 * reach. It's the callers responsibility to make sure this happens. The
2201 * original bio must be passed back in to blk_rq_unmap_user() for proper
2202 * unmapping.
2203 */
2204int blk_rq_map_user_iov(request_queue_t *q, struct request *rq,
2205 struct sg_iovec *iov, int iov_count)
2206{
2207 struct bio *bio;
2208
2209 if (!iov || iov_count <= 0)
2210 return -EINVAL;
2211
2212 /* we don't allow misaligned data like bio_map_user() does. If the
2213 * user is using sg, they're expected to know the alignment constraints
2214 * and respect them accordingly */
2215 bio = bio_map_user_iov(q, NULL, iov, iov_count, rq_data_dir(rq)== READ);
2216 if (IS_ERR(bio))
2217 return PTR_ERR(bio);
2218
2219 rq->bio = rq->biotail = bio;
2220 blk_rq_bio_prep(q, rq, bio);
2221 rq->buffer = rq->data = NULL;
2222 rq->data_len = bio->bi_size;
2223 return 0;
2224}
2225
2226EXPORT_SYMBOL(blk_rq_map_user_iov);
2227
2228/**
2229 * blk_rq_unmap_user - unmap a request with user data
2230 * @bio: bio to be unmapped
2231 * @ulen: length of user buffer
2232 *
2233 * Description:
2234 * Unmap a bio previously mapped by blk_rq_map_user().
2235 */
2236int blk_rq_unmap_user(struct bio *bio, unsigned int ulen)
2237{
2238 int ret = 0;
2239
2240 if (bio) {
2241 if (bio_flagged(bio, BIO_USER_MAPPED))
2242 bio_unmap_user(bio);
2243 else
2244 ret = bio_uncopy_user(bio);
2245 }
2246
2247 return 0;
2248}
2249
2250EXPORT_SYMBOL(blk_rq_unmap_user);
2251
2252/**
2253 * blk_rq_map_kern - map kernel data to a request, for REQ_BLOCK_PC usage
2254 * @q: request queue where request should be inserted
2255 * @rq: request to fill
2256 * @kbuf: the kernel buffer
2257 * @len: length of user data
2258 * @gfp_mask: memory allocation flags
2259 */
2260int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf,
2261 unsigned int len, gfp_t gfp_mask)
2262{
2263 struct bio *bio;
2264
2265 if (len > (q->max_sectors << 9))
2266 return -EINVAL;
2267 if (!len || !kbuf)
2268 return -EINVAL;
2269
2270 bio = bio_map_kern(q, kbuf, len, gfp_mask);
2271 if (IS_ERR(bio))
2272 return PTR_ERR(bio);
2273
2274 if (rq_data_dir(rq) == WRITE)
2275 bio->bi_rw |= (1 << BIO_RW);
2276
2277 rq->bio = rq->biotail = bio;
2278 blk_rq_bio_prep(q, rq, bio);
2279
2280 rq->buffer = rq->data = NULL;
2281 rq->data_len = len;
2282 return 0;
2283}
2284
2285EXPORT_SYMBOL(blk_rq_map_kern);
2286
2287/**
2288 * blk_execute_rq_nowait - insert a request into queue for execution
2289 * @q: queue to insert the request in
2290 * @bd_disk: matching gendisk
2291 * @rq: request to insert
2292 * @at_head: insert request at head or tail of queue
2293 * @done: I/O completion handler
2294 *
2295 * Description:
2296 * Insert a fully prepared request at the back of the io scheduler queue
2297 * for execution. Don't wait for completion.
2298 */
2299void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
2300 struct request *rq, int at_head,
2301 void (*done)(struct request *))
2302{
2303 int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
2304
2305 rq->rq_disk = bd_disk;
2306 rq->flags |= REQ_NOMERGE;
2307 rq->end_io = done;
2308 elv_add_request(q, rq, where, 1);
2309 generic_unplug_device(q);
2310}
2311
2312/**
2313 * blk_execute_rq - insert a request into queue for execution
2314 * @q: queue to insert the request in
2315 * @bd_disk: matching gendisk
2316 * @rq: request to insert
2317 * @at_head: insert request at head or tail of queue
2318 *
2319 * Description:
2320 * Insert a fully prepared request at the back of the io scheduler queue
2321 * for execution and wait for completion.
2322 */
2323int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk,
2324 struct request *rq, int at_head)
2325{
2326 DECLARE_COMPLETION(wait);
2327 char sense[SCSI_SENSE_BUFFERSIZE];
2328 int err = 0;
2329
2330 /*
2331 * we need an extra reference to the request, so we can look at
2332 * it after io completion
2333 */
2334 rq->ref_count++;
2335
2336 if (!rq->sense) {
2337 memset(sense, 0, sizeof(sense));
2338 rq->sense = sense;
2339 rq->sense_len = 0;
2340 }
2341
2342 rq->waiting = &wait;
2343 blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq);
2344 wait_for_completion(&wait);
2345 rq->waiting = NULL;
2346
2347 if (rq->errors)
2348 err = -EIO;
2349
2350 return err;
2351}
2352
2353EXPORT_SYMBOL(blk_execute_rq);
2354
2355/**
2356 * blkdev_issue_flush - queue a flush
2357 * @bdev: blockdev to issue flush for
2358 * @error_sector: error sector
2359 *
2360 * Description:
2361 * Issue a flush for the block device in question. Caller can supply
2362 * room for storing the error offset in case of a flush error, if they
2363 * wish to. Caller must run wait_for_completion() on its own.
2364 */
2365int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
2366{
2367 request_queue_t *q;
2368
2369 if (bdev->bd_disk == NULL)
2370 return -ENXIO;
2371
2372 q = bdev_get_queue(bdev);
2373 if (!q)
2374 return -ENXIO;
2375 if (!q->issue_flush_fn)
2376 return -EOPNOTSUPP;
2377
2378 return q->issue_flush_fn(q, bdev->bd_disk, error_sector);
2379}
2380
2381EXPORT_SYMBOL(blkdev_issue_flush);
2382
2383static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
2384{
2385 int rw = rq_data_dir(rq);
2386
2387 if (!blk_fs_request(rq) || !rq->rq_disk)
2388 return;
2389
2390 if (!new_io) {
2391 __disk_stat_inc(rq->rq_disk, merges[rw]);
2392 } else {
2393 disk_round_stats(rq->rq_disk);
2394 rq->rq_disk->in_flight++;
2395 }
2396}
2397
2398/*
2399 * add-request adds a request to the linked list.
2400 * queue lock is held and interrupts disabled, as we muck with the
2401 * request queue list.
2402 */
2403static inline void add_request(request_queue_t * q, struct request * req)
2404{
2405 drive_stat_acct(req, req->nr_sectors, 1);
2406
2407 if (q->activity_fn)
2408 q->activity_fn(q->activity_data, rq_data_dir(req));
2409
2410 /*
2411 * elevator indicated where it wants this request to be
2412 * inserted at elevator_merge time
2413 */
2414 __elv_add_request(q, req, ELEVATOR_INSERT_SORT, 0);
2415}
2416
2417/*
2418 * disk_round_stats() - Round off the performance stats on a struct
2419 * disk_stats.
2420 *
2421 * The average IO queue length and utilisation statistics are maintained
2422 * by observing the current state of the queue length and the amount of
2423 * time it has been in this state for.
2424 *
2425 * Normally, that accounting is done on IO completion, but that can result
2426 * in more than a second's worth of IO being accounted for within any one
2427 * second, leading to >100% utilisation. To deal with that, we call this
2428 * function to do a round-off before returning the results when reading
2429 * /proc/diskstats. This accounts immediately for all queue usage up to
2430 * the current jiffies and restarts the counters again.
2431 */
2432void disk_round_stats(struct gendisk *disk)
2433{
2434 unsigned long now = jiffies;
2435
2436 if (now == disk->stamp)
2437 return;
2438
2439 if (disk->in_flight) {
2440 __disk_stat_add(disk, time_in_queue,
2441 disk->in_flight * (now - disk->stamp));
2442 __disk_stat_add(disk, io_ticks, (now - disk->stamp));
2443 }
2444 disk->stamp = now;
2445}
2446
2447/*
2448 * queue lock must be held
2449 */
2450static void __blk_put_request(request_queue_t *q, struct request *req)
2451{
2452 struct request_list *rl = req->rl;
2453
2454 if (unlikely(!q))
2455 return;
2456 if (unlikely(--req->ref_count))
2457 return;
2458
2459 elv_completed_request(q, req);
2460
2461 req->rq_status = RQ_INACTIVE;
2462 req->rl = NULL;
2463
2464 /*
2465 * Request may not have originated from ll_rw_blk. if not,
2466 * it didn't come out of our reserved rq pools
2467 */
2468 if (rl) {
2469 int rw = rq_data_dir(req);
2470 int priv = req->flags & REQ_ELVPRIV;
2471
2472 BUG_ON(!list_empty(&req->queuelist));
2473
2474 blk_free_request(q, req);
2475 freed_request(q, rw, priv);
2476 }
2477}
2478
2479void blk_put_request(struct request *req)
2480{
2481 unsigned long flags;
2482 request_queue_t *q = req->q;
2483
2484 /*
2485 * Gee, IDE calls in w/ NULL q. Fix IDE and remove the
2486 * following if (q) test.
2487 */
2488 if (q) {
2489 spin_lock_irqsave(q->queue_lock, flags);
2490 __blk_put_request(q, req);
2491 spin_unlock_irqrestore(q->queue_lock, flags);
2492 }
2493}
2494
2495EXPORT_SYMBOL(blk_put_request);
2496
2497/**
2498 * blk_end_sync_rq - executes a completion event on a request
2499 * @rq: request to complete
2500 */
2501void blk_end_sync_rq(struct request *rq)
2502{
2503 struct completion *waiting = rq->waiting;
2504
2505 rq->waiting = NULL;
2506 __blk_put_request(rq->q, rq);
2507
2508 /*
2509 * complete last, if this is a stack request the process (and thus
2510 * the rq pointer) could be invalid right after this complete()
2511 */
2512 complete(waiting);
2513}
2514EXPORT_SYMBOL(blk_end_sync_rq);
2515
2516/**
2517 * blk_congestion_wait - wait for a queue to become uncongested
2518 * @rw: READ or WRITE
2519 * @timeout: timeout in jiffies
2520 *
2521 * Waits for up to @timeout jiffies for a queue (any queue) to exit congestion.
2522 * If no queues are congested then just wait for the next request to be
2523 * returned.
2524 */
2525long blk_congestion_wait(int rw, long timeout)
2526{
2527 long ret;
2528 DEFINE_WAIT(wait);
2529 wait_queue_head_t *wqh = &congestion_wqh[rw];
2530
2531 prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE);
2532 ret = io_schedule_timeout(timeout);
2533 finish_wait(wqh, &wait);
2534 return ret;
2535}
2536
2537EXPORT_SYMBOL(blk_congestion_wait);
2538
2539/*
2540 * Has to be called with the request spinlock acquired
2541 */
2542static int attempt_merge(request_queue_t *q, struct request *req,
2543 struct request *next)
2544{
2545 if (!rq_mergeable(req) || !rq_mergeable(next))
2546 return 0;
2547
2548 /*
2549 * not contigious
2550 */
2551 if (req->sector + req->nr_sectors != next->sector)
2552 return 0;
2553
2554 if (rq_data_dir(req) != rq_data_dir(next)
2555 || req->rq_disk != next->rq_disk
2556 || next->waiting || next->special)
2557 return 0;
2558
2559 /*
2560 * If we are allowed to merge, then append bio list
2561 * from next to rq and release next. merge_requests_fn
2562 * will have updated segment counts, update sector
2563 * counts here.
2564 */
2565 if (!q->merge_requests_fn(q, req, next))
2566 return 0;
2567
2568 /*
2569 * At this point we have either done a back merge
2570 * or front merge. We need the smaller start_time of
2571 * the merged requests to be the current request
2572 * for accounting purposes.
2573 */
2574 if (time_after(req->start_time, next->start_time))
2575 req->start_time = next->start_time;
2576
2577 req->biotail->bi_next = next->bio;
2578 req->biotail = next->biotail;
2579
2580 req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors;
2581
2582 elv_merge_requests(q, req, next);
2583
2584 if (req->rq_disk) {
2585 disk_round_stats(req->rq_disk);
2586 req->rq_disk->in_flight--;
2587 }
2588
2589 req->ioprio = ioprio_best(req->ioprio, next->ioprio);
2590
2591 __blk_put_request(q, next);
2592 return 1;
2593}
2594
2595static inline int attempt_back_merge(request_queue_t *q, struct request *rq)
2596{
2597 struct request *next = elv_latter_request(q, rq);
2598
2599 if (next)
2600 return attempt_merge(q, rq, next);
2601
2602 return 0;
2603}
2604
2605static inline int attempt_front_merge(request_queue_t *q, struct request *rq)
2606{
2607 struct request *prev = elv_former_request(q, rq);
2608
2609 if (prev)
2610 return attempt_merge(q, prev, rq);
2611
2612 return 0;
2613}
2614
2615/**
2616 * blk_attempt_remerge - attempt to remerge active head with next request
2617 * @q: The &request_queue_t belonging to the device
2618 * @rq: The head request (usually)
2619 *
2620 * Description:
2621 * For head-active devices, the queue can easily be unplugged so quickly
2622 * that proper merging is not done on the front request. This may hurt
2623 * performance greatly for some devices. The block layer cannot safely
2624 * do merging on that first request for these queues, but the driver can
2625 * call this function and make it happen any way. Only the driver knows
2626 * when it is safe to do so.
2627 **/
2628void blk_attempt_remerge(request_queue_t *q, struct request *rq)
2629{
2630 unsigned long flags;
2631
2632 spin_lock_irqsave(q->queue_lock, flags);
2633 attempt_back_merge(q, rq);
2634 spin_unlock_irqrestore(q->queue_lock, flags);
2635}
2636
2637EXPORT_SYMBOL(blk_attempt_remerge);
2638
2639static int __make_request(request_queue_t *q, struct bio *bio)
2640{
2641 struct request *req;
2642 int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync;
2643 unsigned short prio;
2644 sector_t sector;
2645
2646 sector = bio->bi_sector;
2647 nr_sectors = bio_sectors(bio);
2648 cur_nr_sectors = bio_cur_sectors(bio);
2649 prio = bio_prio(bio);
2650
2651 rw = bio_data_dir(bio);
2652 sync = bio_sync(bio);
2653
2654 /*
2655 * low level driver can indicate that it wants pages above a
2656 * certain limit bounced to low memory (ie for highmem, or even
2657 * ISA dma in theory)
2658 */
2659 blk_queue_bounce(q, &bio);
2660
2661 spin_lock_prefetch(q->queue_lock);
2662
2663 barrier = bio_barrier(bio);
2664 if (unlikely(barrier) && (q->ordered == QUEUE_ORDERED_NONE)) {
2665 err = -EOPNOTSUPP;
2666 goto end_io;
2667 }
2668
2669 spin_lock_irq(q->queue_lock);
2670
2671 if (unlikely(barrier) || elv_queue_empty(q))
2672 goto get_rq;
2673
2674 el_ret = elv_merge(q, &req, bio);
2675 switch (el_ret) {
2676 case ELEVATOR_BACK_MERGE:
2677 BUG_ON(!rq_mergeable(req));
2678
2679 if (!q->back_merge_fn(q, req, bio))
2680 break;
2681
2682 req->biotail->bi_next = bio;
2683 req->biotail = bio;
2684 req->nr_sectors = req->hard_nr_sectors += nr_sectors;
2685 req->ioprio = ioprio_best(req->ioprio, prio);
2686 drive_stat_acct(req, nr_sectors, 0);
2687 if (!attempt_back_merge(q, req))
2688 elv_merged_request(q, req);
2689 goto out;
2690
2691 case ELEVATOR_FRONT_MERGE:
2692 BUG_ON(!rq_mergeable(req));
2693
2694 if (!q->front_merge_fn(q, req, bio))
2695 break;
2696
2697 bio->bi_next = req->bio;
2698 req->bio = bio;
2699
2700 /*
2701 * may not be valid. if the low level driver said
2702 * it didn't need a bounce buffer then it better
2703 * not touch req->buffer either...
2704 */
2705 req->buffer = bio_data(bio);
2706 req->current_nr_sectors = cur_nr_sectors;
2707 req->hard_cur_sectors = cur_nr_sectors;
2708 req->sector = req->hard_sector = sector;
2709 req->nr_sectors = req->hard_nr_sectors += nr_sectors;
2710 req->ioprio = ioprio_best(req->ioprio, prio);
2711 drive_stat_acct(req, nr_sectors, 0);
2712 if (!attempt_front_merge(q, req))
2713 elv_merged_request(q, req);
2714 goto out;
2715
2716 /* ELV_NO_MERGE: elevator says don't/can't merge. */
2717 default:
2718 ;
2719 }
2720
2721get_rq:
2722 /*
2723 * Grab a free request. This is might sleep but can not fail.
2724 * Returns with the queue unlocked.
2725 */
2726 req = get_request_wait(q, rw, bio);
2727
2728 /*
2729 * After dropping the lock and possibly sleeping here, our request
2730 * may now be mergeable after it had proven unmergeable (above).
2731 * We don't worry about that case for efficiency. It won't happen
2732 * often, and the elevators are able to handle it.
2733 */
2734
2735 req->flags |= REQ_CMD;
2736
2737 /*
2738 * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
2739 */
2740 if (bio_rw_ahead(bio) || bio_failfast(bio))
2741 req->flags |= REQ_FAILFAST;
2742
2743 /*
2744 * REQ_BARRIER implies no merging, but lets make it explicit
2745 */
2746 if (unlikely(barrier))
2747 req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
2748
2749 req->errors = 0;
2750 req->hard_sector = req->sector = sector;
2751 req->hard_nr_sectors = req->nr_sectors = nr_sectors;
2752 req->current_nr_sectors = req->hard_cur_sectors = cur_nr_sectors;
2753 req->nr_phys_segments = bio_phys_segments(q, bio);
2754 req->nr_hw_segments = bio_hw_segments(q, bio);
2755 req->buffer = bio_data(bio); /* see ->buffer comment above */
2756 req->waiting = NULL;
2757 req->bio = req->biotail = bio;
2758 req->ioprio = prio;
2759 req->rq_disk = bio->bi_bdev->bd_disk;
2760 req->start_time = jiffies;
2761
2762 spin_lock_irq(q->queue_lock);
2763 if (elv_queue_empty(q))
2764 blk_plug_device(q);
2765 add_request(q, req);
2766out:
2767 if (sync)
2768 __generic_unplug_device(q);
2769
2770 spin_unlock_irq(q->queue_lock);
2771 return 0;
2772
2773end_io:
2774 bio_endio(bio, nr_sectors << 9, err);
2775 return 0;
2776}
2777
2778/*
2779 * If bio->bi_dev is a partition, remap the location
2780 */
2781static inline void blk_partition_remap(struct bio *bio)
2782{
2783 struct block_device *bdev = bio->bi_bdev;
2784
2785 if (bdev != bdev->bd_contains) {
2786 struct hd_struct *p = bdev->bd_part;
2787 const int rw = bio_data_dir(bio);
2788
2789 p->sectors[rw] += bio_sectors(bio);
2790 p->ios[rw]++;
2791
2792 bio->bi_sector += p->start_sect;
2793 bio->bi_bdev = bdev->bd_contains;
2794 }
2795}
2796
2797static void handle_bad_sector(struct bio *bio)
2798{
2799 char b[BDEVNAME_SIZE];
2800
2801 printk(KERN_INFO "attempt to access beyond end of device\n");
2802 printk(KERN_INFO "%s: rw=%ld, want=%Lu, limit=%Lu\n",
2803 bdevname(bio->bi_bdev, b),
2804 bio->bi_rw,
2805 (unsigned long long)bio->bi_sector + bio_sectors(bio),
2806 (long long)(bio->bi_bdev->bd_inode->i_size >> 9));
2807
2808 set_bit(BIO_EOF, &bio->bi_flags);
2809}
2810
2811/**
2812 * generic_make_request: hand a buffer to its device driver for I/O
2813 * @bio: The bio describing the location in memory and on the device.
2814 *
2815 * generic_make_request() is used to make I/O requests of block
2816 * devices. It is passed a &struct bio, which describes the I/O that needs
2817 * to be done.
2818 *
2819 * generic_make_request() does not return any status. The
2820 * success/failure status of the request, along with notification of
2821 * completion, is delivered asynchronously through the bio->bi_end_io
2822 * function described (one day) else where.
2823 *
2824 * The caller of generic_make_request must make sure that bi_io_vec
2825 * are set to describe the memory buffer, and that bi_dev and bi_sector are
2826 * set to describe the device address, and the
2827 * bi_end_io and optionally bi_private are set to describe how
2828 * completion notification should be signaled.
2829 *
2830 * generic_make_request and the drivers it calls may use bi_next if this
2831 * bio happens to be merged with someone else, and may change bi_dev and
2832 * bi_sector for remaps as it sees fit. So the values of these fields
2833 * should NOT be depended on after the call to generic_make_request.
2834 */
2835void generic_make_request(struct bio *bio)
2836{
2837 request_queue_t *q;
2838 sector_t maxsector;
2839 int ret, nr_sectors = bio_sectors(bio);
2840
2841 might_sleep();
2842 /* Test device or partition size, when known. */
2843 maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
2844 if (maxsector) {
2845 sector_t sector = bio->bi_sector;
2846
2847 if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
2848 /*
2849 * This may well happen - the kernel calls bread()
2850 * without checking the size of the device, e.g., when
2851 * mounting a device.
2852 */
2853 handle_bad_sector(bio);
2854 goto end_io;
2855 }
2856 }
2857
2858 /*
2859 * Resolve the mapping until finished. (drivers are
2860 * still free to implement/resolve their own stacking
2861 * by explicitly returning 0)
2862 *
2863 * NOTE: we don't repeat the blk_size check for each new device.
2864 * Stacking drivers are expected to know what they are doing.
2865 */
2866 do {
2867 char b[BDEVNAME_SIZE];
2868
2869 q = bdev_get_queue(bio->bi_bdev);
2870 if (!q) {
2871 printk(KERN_ERR
2872 "generic_make_request: Trying to access "
2873 "nonexistent block-device %s (%Lu)\n",
2874 bdevname(bio->bi_bdev, b),
2875 (long long) bio->bi_sector);
2876end_io:
2877 bio_endio(bio, bio->bi_size, -EIO);
2878 break;
2879 }
2880
2881 if (unlikely(bio_sectors(bio) > q->max_hw_sectors)) {
2882 printk("bio too big device %s (%u > %u)\n",
2883 bdevname(bio->bi_bdev, b),
2884 bio_sectors(bio),
2885 q->max_hw_sectors);
2886 goto end_io;
2887 }
2888
2889 if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
2890 goto end_io;
2891
2892 /*
2893 * If this device has partitions, remap block n
2894 * of partition p to block n+start(p) of the disk.
2895 */
2896 blk_partition_remap(bio);
2897
2898 ret = q->make_request_fn(q, bio);
2899 } while (ret);
2900}
2901
2902EXPORT_SYMBOL(generic_make_request);
2903
2904/**
2905 * submit_bio: submit a bio to the block device layer for I/O
2906 * @rw: whether to %READ or %WRITE, or maybe to %READA (read ahead)
2907 * @bio: The &struct bio which describes the I/O
2908 *
2909 * submit_bio() is very similar in purpose to generic_make_request(), and
2910 * uses that function to do most of the work. Both are fairly rough
2911 * interfaces, @bio must be presetup and ready for I/O.
2912 *
2913 */
2914void submit_bio(int rw, struct bio *bio)
2915{
2916 int count = bio_sectors(bio);
2917
2918 BIO_BUG_ON(!bio->bi_size);
2919 BIO_BUG_ON(!bio->bi_io_vec);
2920 bio->bi_rw |= rw;
2921 if (rw & WRITE)
2922 mod_page_state(pgpgout, count);
2923 else
2924 mod_page_state(pgpgin, count);
2925
2926 if (unlikely(block_dump)) {
2927 char b[BDEVNAME_SIZE];
2928 printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n",
2929 current->comm, current->pid,
2930 (rw & WRITE) ? "WRITE" : "READ",
2931 (unsigned long long)bio->bi_sector,
2932 bdevname(bio->bi_bdev,b));
2933 }
2934
2935 generic_make_request(bio);
2936}
2937
2938EXPORT_SYMBOL(submit_bio);
2939
2940static void blk_recalc_rq_segments(struct request *rq)
2941{
2942 struct bio *bio, *prevbio = NULL;
2943 int nr_phys_segs, nr_hw_segs;
2944 unsigned int phys_size, hw_size;
2945 request_queue_t *q = rq->q;
2946
2947 if (!rq->bio)
2948 return;
2949
2950 phys_size = hw_size = nr_phys_segs = nr_hw_segs = 0;
2951 rq_for_each_bio(bio, rq) {
2952 /* Force bio hw/phys segs to be recalculated. */
2953 bio->bi_flags &= ~(1 << BIO_SEG_VALID);
2954
2955 nr_phys_segs += bio_phys_segments(q, bio);
2956 nr_hw_segs += bio_hw_segments(q, bio);
2957 if (prevbio) {
2958 int pseg = phys_size + prevbio->bi_size + bio->bi_size;
2959 int hseg = hw_size + prevbio->bi_size + bio->bi_size;
2960
2961 if (blk_phys_contig_segment(q, prevbio, bio) &&
2962 pseg <= q->max_segment_size) {
2963 nr_phys_segs--;
2964 phys_size += prevbio->bi_size + bio->bi_size;
2965 } else
2966 phys_size = 0;
2967
2968 if (blk_hw_contig_segment(q, prevbio, bio) &&
2969 hseg <= q->max_segment_size) {
2970 nr_hw_segs--;
2971 hw_size += prevbio->bi_size + bio->bi_size;
2972 } else
2973 hw_size = 0;
2974 }
2975 prevbio = bio;
2976 }
2977
2978 rq->nr_phys_segments = nr_phys_segs;
2979 rq->nr_hw_segments = nr_hw_segs;
2980}
2981
2982static void blk_recalc_rq_sectors(struct request *rq, int nsect)
2983{
2984 if (blk_fs_request(rq)) {
2985 rq->hard_sector += nsect;
2986 rq->hard_nr_sectors -= nsect;
2987
2988 /*
2989 * Move the I/O submission pointers ahead if required.
2990 */
2991 if ((rq->nr_sectors >= rq->hard_nr_sectors) &&
2992 (rq->sector <= rq->hard_sector)) {
2993 rq->sector = rq->hard_sector;
2994 rq->nr_sectors = rq->hard_nr_sectors;
2995 rq->hard_cur_sectors = bio_cur_sectors(rq->bio);
2996 rq->current_nr_sectors = rq->hard_cur_sectors;
2997 rq->buffer = bio_data(rq->bio);
2998 }
2999
3000 /*
3001 * if total number of sectors is less than the first segment
3002 * size, something has gone terribly wrong
3003 */
3004 if (rq->nr_sectors < rq->current_nr_sectors) {
3005 printk("blk: request botched\n");
3006 rq->nr_sectors = rq->current_nr_sectors;
3007 }
3008 }
3009}
3010
3011static int __end_that_request_first(struct request *req, int uptodate,
3012 int nr_bytes)
3013{
3014 int total_bytes, bio_nbytes, error, next_idx = 0;
3015 struct bio *bio;
3016
3017 /*
3018 * extend uptodate bool to allow < 0 value to be direct io error
3019 */
3020 error = 0;
3021 if (end_io_error(uptodate))
3022 error = !uptodate ? -EIO : uptodate;
3023
3024 /*
3025 * for a REQ_BLOCK_PC request, we want to carry any eventual
3026 * sense key with us all the way through
3027 */
3028 if (!blk_pc_request(req))
3029 req->errors = 0;
3030
3031 if (!uptodate) {
3032 if (blk_fs_request(req) && !(req->flags & REQ_QUIET))
3033 printk("end_request: I/O error, dev %s, sector %llu\n",
3034 req->rq_disk ? req->rq_disk->disk_name : "?",
3035 (unsigned long long)req->sector);
3036 }
3037
3038 if (blk_fs_request(req) && req->rq_disk) {
3039 const int rw = rq_data_dir(req);
3040
3041 __disk_stat_add(req->rq_disk, sectors[rw], nr_bytes >> 9);
3042 }
3043
3044 total_bytes = bio_nbytes = 0;
3045 while ((bio = req->bio) != NULL) {
3046 int nbytes;
3047
3048 if (nr_bytes >= bio->bi_size) {
3049 req->bio = bio->bi_next;
3050 nbytes = bio->bi_size;
3051 bio_endio(bio, nbytes, error);
3052 next_idx = 0;
3053 bio_nbytes = 0;
3054 } else {
3055 int idx = bio->bi_idx + next_idx;
3056
3057 if (unlikely(bio->bi_idx >= bio->bi_vcnt)) {
3058 blk_dump_rq_flags(req, "__end_that");
3059 printk("%s: bio idx %d >= vcnt %d\n",
3060 __FUNCTION__,
3061 bio->bi_idx, bio->bi_vcnt);
3062 break;
3063 }
3064
3065 nbytes = bio_iovec_idx(bio, idx)->bv_len;
3066 BIO_BUG_ON(nbytes > bio->bi_size);
3067
3068 /*
3069 * not a complete bvec done
3070 */
3071 if (unlikely(nbytes > nr_bytes)) {
3072 bio_nbytes += nr_bytes;
3073 total_bytes += nr_bytes;
3074 break;
3075 }
3076
3077 /*
3078 * advance to the next vector
3079 */
3080 next_idx++;
3081 bio_nbytes += nbytes;
3082 }
3083
3084 total_bytes += nbytes;
3085 nr_bytes -= nbytes;
3086
3087 if ((bio = req->bio)) {
3088 /*
3089 * end more in this run, or just return 'not-done'
3090 */
3091 if (unlikely(nr_bytes <= 0))
3092 break;
3093 }
3094 }
3095
3096 /*
3097 * completely done
3098 */
3099 if (!req->bio)
3100 return 0;
3101
3102 /*
3103 * if the request wasn't completed, update state
3104 */
3105 if (bio_nbytes) {
3106 bio_endio(bio, bio_nbytes, error);
3107 bio->bi_idx += next_idx;
3108 bio_iovec(bio)->bv_offset += nr_bytes;
3109 bio_iovec(bio)->bv_len -= nr_bytes;
3110 }
3111
3112 blk_recalc_rq_sectors(req, total_bytes >> 9);
3113 blk_recalc_rq_segments(req);
3114 return 1;
3115}
3116
3117/**
3118 * end_that_request_first - end I/O on a request
3119 * @req: the request being processed
3120 * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error
3121 * @nr_sectors: number of sectors to end I/O on
3122 *
3123 * Description:
3124 * Ends I/O on a number of sectors attached to @req, and sets it up
3125 * for the next range of segments (if any) in the cluster.
3126 *
3127 * Return:
3128 * 0 - we are done with this request, call end_that_request_last()
3129 * 1 - still buffers pending for this request
3130 **/
3131int end_that_request_first(struct request *req, int uptodate, int nr_sectors)
3132{
3133 return __end_that_request_first(req, uptodate, nr_sectors << 9);
3134}
3135
3136EXPORT_SYMBOL(end_that_request_first);
3137
3138/**
3139 * end_that_request_chunk - end I/O on a request
3140 * @req: the request being processed
3141 * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error
3142 * @nr_bytes: number of bytes to complete
3143 *
3144 * Description:
3145 * Ends I/O on a number of bytes attached to @req, and sets it up
3146 * for the next range of segments (if any). Like end_that_request_first(),
3147 * but deals with bytes instead of sectors.
3148 *
3149 * Return:
3150 * 0 - we are done with this request, call end_that_request_last()
3151 * 1 - still buffers pending for this request
3152 **/
3153int end_that_request_chunk(struct request *req, int uptodate, int nr_bytes)
3154{
3155 return __end_that_request_first(req, uptodate, nr_bytes);
3156}
3157
3158EXPORT_SYMBOL(end_that_request_chunk);
3159
3160/*
3161 * queue lock must be held
3162 */
3163void end_that_request_last(struct request *req)
3164{
3165 struct gendisk *disk = req->rq_disk;
3166
3167 if (unlikely(laptop_mode) && blk_fs_request(req))
3168 laptop_io_completion();
3169
3170 if (disk && blk_fs_request(req)) {
3171 unsigned long duration = jiffies - req->start_time;
3172 const int rw = rq_data_dir(req);
3173
3174 __disk_stat_inc(disk, ios[rw]);
3175 __disk_stat_add(disk, ticks[rw], duration);
3176 disk_round_stats(disk);
3177 disk->in_flight--;
3178 }
3179 if (req->end_io)
3180 req->end_io(req);
3181 else
3182 __blk_put_request(req->q, req);
3183}
3184
3185EXPORT_SYMBOL(end_that_request_last);
3186
3187void end_request(struct request *req, int uptodate)
3188{
3189 if (!end_that_request_first(req, uptodate, req->hard_cur_sectors)) {
3190 add_disk_randomness(req->rq_disk);
3191 blkdev_dequeue_request(req);
3192 end_that_request_last(req);
3193 }
3194}
3195
3196EXPORT_SYMBOL(end_request);
3197
3198void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio)
3199{
3200 /* first three bits are identical in rq->flags and bio->bi_rw */
3201 rq->flags |= (bio->bi_rw & 7);
3202
3203 rq->nr_phys_segments = bio_phys_segments(q, bio);
3204 rq->nr_hw_segments = bio_hw_segments(q, bio);
3205 rq->current_nr_sectors = bio_cur_sectors(bio);
3206 rq->hard_cur_sectors = rq->current_nr_sectors;
3207 rq->hard_nr_sectors = rq->nr_sectors = bio_sectors(bio);
3208 rq->buffer = bio_data(bio);
3209
3210 rq->bio = rq->biotail = bio;
3211}
3212
3213EXPORT_SYMBOL(blk_rq_bio_prep);
3214
3215int kblockd_schedule_work(struct work_struct *work)
3216{
3217 return queue_work(kblockd_workqueue, work);
3218}
3219
3220EXPORT_SYMBOL(kblockd_schedule_work);
3221
3222void kblockd_flush(void)
3223{
3224 flush_workqueue(kblockd_workqueue);
3225}
3226EXPORT_SYMBOL(kblockd_flush);
3227
3228int __init blk_dev_init(void)
3229{
3230 kblockd_workqueue = create_workqueue("kblockd");
3231 if (!kblockd_workqueue)
3232 panic("Failed to create kblockd\n");
3233
3234 request_cachep = kmem_cache_create("blkdev_requests",
3235 sizeof(struct request), 0, SLAB_PANIC, NULL, NULL);
3236
3237 requestq_cachep = kmem_cache_create("blkdev_queue",
3238 sizeof(request_queue_t), 0, SLAB_PANIC, NULL, NULL);
3239
3240 iocontext_cachep = kmem_cache_create("blkdev_ioc",
3241 sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL);
3242
3243 blk_max_low_pfn = max_low_pfn;
3244 blk_max_pfn = max_pfn;
3245
3246 return 0;
3247}
3248
3249/*
3250 * IO Context helper functions
3251 */
3252void put_io_context(struct io_context *ioc)
3253{
3254 if (ioc == NULL)
3255 return;
3256
3257 BUG_ON(atomic_read(&ioc->refcount) == 0);
3258
3259 if (atomic_dec_and_test(&ioc->refcount)) {
3260 if (ioc->aic && ioc->aic->dtor)
3261 ioc->aic->dtor(ioc->aic);
3262 if (ioc->cic && ioc->cic->dtor)
3263 ioc->cic->dtor(ioc->cic);
3264
3265 kmem_cache_free(iocontext_cachep, ioc);
3266 }
3267}
3268EXPORT_SYMBOL(put_io_context);
3269
3270/* Called by the exitting task */
3271void exit_io_context(void)
3272{
3273 unsigned long flags;
3274 struct io_context *ioc;
3275
3276 local_irq_save(flags);
3277 task_lock(current);
3278 ioc = current->io_context;
3279 current->io_context = NULL;
3280 ioc->task = NULL;
3281 task_unlock(current);
3282 local_irq_restore(flags);
3283
3284 if (ioc->aic && ioc->aic->exit)
3285 ioc->aic->exit(ioc->aic);
3286 if (ioc->cic && ioc->cic->exit)
3287 ioc->cic->exit(ioc->cic);
3288
3289 put_io_context(ioc);
3290}
3291
3292/*
3293 * If the current task has no IO context then create one and initialise it.
3294 * Otherwise, return its existing IO context.
3295 *
3296 * This returned IO context doesn't have a specifically elevated refcount,
3297 * but since the current task itself holds a reference, the context can be
3298 * used in general code, so long as it stays within `current` context.
3299 */
3300struct io_context *current_io_context(gfp_t gfp_flags)
3301{
3302 struct task_struct *tsk = current;
3303 struct io_context *ret;
3304
3305 ret = tsk->io_context;
3306 if (likely(ret))
3307 return ret;
3308
3309 ret = kmem_cache_alloc(iocontext_cachep, gfp_flags);
3310 if (ret) {
3311 atomic_set(&ret->refcount, 1);
3312 ret->task = current;
3313 ret->set_ioprio = NULL;
3314 ret->last_waited = jiffies; /* doesn't matter... */
3315 ret->nr_batch_requests = 0; /* because this is 0 */
3316 ret->aic = NULL;
3317 ret->cic = NULL;
3318 tsk->io_context = ret;
3319 }
3320
3321 return ret;
3322}
3323EXPORT_SYMBOL(current_io_context);
3324
3325/*
3326 * If the current task has no IO context then create one and initialise it.
3327 * If it does have a context, take a ref on it.
3328 *
3329 * This is always called in the context of the task which submitted the I/O.
3330 */
3331struct io_context *get_io_context(gfp_t gfp_flags)
3332{
3333 struct io_context *ret;
3334 ret = current_io_context(gfp_flags);
3335 if (likely(ret))
3336 atomic_inc(&ret->refcount);
3337 return ret;
3338}
3339EXPORT_SYMBOL(get_io_context);
3340
3341void copy_io_context(struct io_context **pdst, struct io_context **psrc)
3342{
3343 struct io_context *src = *psrc;
3344 struct io_context *dst = *pdst;
3345
3346 if (src) {
3347 BUG_ON(atomic_read(&src->refcount) == 0);
3348 atomic_inc(&src->refcount);
3349 put_io_context(dst);
3350 *pdst = src;
3351 }
3352}
3353EXPORT_SYMBOL(copy_io_context);
3354
3355void swap_io_context(struct io_context **ioc1, struct io_context **ioc2)
3356{
3357 struct io_context *temp;
3358 temp = *ioc1;
3359 *ioc1 = *ioc2;
3360 *ioc2 = temp;
3361}
3362EXPORT_SYMBOL(swap_io_context);
3363
3364/*
3365 * sysfs parts below
3366 */
3367struct queue_sysfs_entry {
3368 struct attribute attr;
3369 ssize_t (*show)(struct request_queue *, char *);
3370 ssize_t (*store)(struct request_queue *, const char *, size_t);
3371};
3372
3373static ssize_t
3374queue_var_show(unsigned int var, char *page)
3375{
3376 return sprintf(page, "%d\n", var);
3377}
3378
3379static ssize_t
3380queue_var_store(unsigned long *var, const char *page, size_t count)
3381{
3382 char *p = (char *) page;
3383
3384 *var = simple_strtoul(p, &p, 10);
3385 return count;
3386}
3387
3388static ssize_t queue_requests_show(struct request_queue *q, char *page)
3389{
3390 return queue_var_show(q->nr_requests, (page));
3391}
3392
3393static ssize_t
3394queue_requests_store(struct request_queue *q, const char *page, size_t count)
3395{
3396 struct request_list *rl = &q->rq;
3397
3398 int ret = queue_var_store(&q->nr_requests, page, count);
3399 if (q->nr_requests < BLKDEV_MIN_RQ)
3400 q->nr_requests = BLKDEV_MIN_RQ;
3401 blk_queue_congestion_threshold(q);
3402
3403 if (rl->count[READ] >= queue_congestion_on_threshold(q))
3404 set_queue_congested(q, READ);
3405 else if (rl->count[READ] < queue_congestion_off_threshold(q))
3406 clear_queue_congested(q, READ);
3407
3408 if (rl->count[WRITE] >= queue_congestion_on_threshold(q))
3409 set_queue_congested(q, WRITE);
3410 else if (rl->count[WRITE] < queue_congestion_off_threshold(q))
3411 clear_queue_congested(q, WRITE);
3412
3413 if (rl->count[READ] >= q->nr_requests) {
3414 blk_set_queue_full(q, READ);
3415 } else if (rl->count[READ]+1 <= q->nr_requests) {
3416 blk_clear_queue_full(q, READ);
3417 wake_up(&rl->wait[READ]);
3418 }
3419
3420 if (rl->count[WRITE] >= q->nr_requests) {
3421 blk_set_queue_full(q, WRITE);
3422 } else if (rl->count[WRITE]+1 <= q->nr_requests) {
3423 blk_clear_queue_full(q, WRITE);
3424 wake_up(&rl->wait[WRITE]);
3425 }
3426 return ret;
3427}
3428
3429static ssize_t queue_ra_show(struct request_queue *q, char *page)
3430{
3431 int ra_kb = q->backing_dev_info.ra_pages << (PAGE_CACHE_SHIFT - 10);
3432
3433 return queue_var_show(ra_kb, (page));
3434}
3435
3436static ssize_t
3437queue_ra_store(struct request_queue *q, const char *page, size_t count)
3438{
3439 unsigned long ra_kb;
3440 ssize_t ret = queue_var_store(&ra_kb, page, count);
3441
3442 spin_lock_irq(q->queue_lock);
3443 if (ra_kb > (q->max_sectors >> 1))
3444 ra_kb = (q->max_sectors >> 1);
3445
3446 q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10);
3447 spin_unlock_irq(q->queue_lock);
3448
3449 return ret;
3450}
3451
3452static ssize_t queue_max_sectors_show(struct request_queue *q, char *page)
3453{
3454 int max_sectors_kb = q->max_sectors >> 1;
3455
3456 return queue_var_show(max_sectors_kb, (page));
3457}
3458
3459static ssize_t
3460queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
3461{
3462 unsigned long max_sectors_kb,
3463 max_hw_sectors_kb = q->max_hw_sectors >> 1,
3464 page_kb = 1 << (PAGE_CACHE_SHIFT - 10);
3465 ssize_t ret = queue_var_store(&max_sectors_kb, page, count);
3466 int ra_kb;
3467
3468 if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
3469 return -EINVAL;
3470 /*
3471 * Take the queue lock to update the readahead and max_sectors
3472 * values synchronously:
3473 */
3474 spin_lock_irq(q->queue_lock);
3475 /*
3476 * Trim readahead window as well, if necessary:
3477 */
3478 ra_kb = q->backing_dev_info.ra_pages << (PAGE_CACHE_SHIFT - 10);
3479 if (ra_kb > max_sectors_kb)
3480 q->backing_dev_info.ra_pages =
3481 max_sectors_kb >> (PAGE_CACHE_SHIFT - 10);
3482
3483 q->max_sectors = max_sectors_kb << 1;
3484 spin_unlock_irq(q->queue_lock);
3485
3486 return ret;
3487}
3488
3489static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page)
3490{
3491 int max_hw_sectors_kb = q->max_hw_sectors >> 1;
3492
3493 return queue_var_show(max_hw_sectors_kb, (page));
3494}
3495
3496
3497static struct queue_sysfs_entry queue_requests_entry = {
3498 .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
3499 .show = queue_requests_show,
3500 .store = queue_requests_store,
3501};
3502
3503static struct queue_sysfs_entry queue_ra_entry = {
3504 .attr = {.name = "read_ahead_kb", .mode = S_IRUGO | S_IWUSR },
3505 .show = queue_ra_show,
3506 .store = queue_ra_store,
3507};
3508
3509static struct queue_sysfs_entry queue_max_sectors_entry = {
3510 .attr = {.name = "max_sectors_kb", .mode = S_IRUGO | S_IWUSR },
3511 .show = queue_max_sectors_show,
3512 .store = queue_max_sectors_store,
3513};
3514
3515static struct queue_sysfs_entry queue_max_hw_sectors_entry = {
3516 .attr = {.name = "max_hw_sectors_kb", .mode = S_IRUGO },
3517 .show = queue_max_hw_sectors_show,
3518};
3519
3520static struct queue_sysfs_entry queue_iosched_entry = {
3521 .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
3522 .show = elv_iosched_show,
3523 .store = elv_iosched_store,
3524};
3525
3526static struct attribute *default_attrs[] = {
3527 &queue_requests_entry.attr,
3528 &queue_ra_entry.attr,
3529 &queue_max_hw_sectors_entry.attr,
3530 &queue_max_sectors_entry.attr,
3531 &queue_iosched_entry.attr,
3532 NULL,
3533};
3534
3535#define to_queue(atr) container_of((atr), struct queue_sysfs_entry, attr)
3536
3537static ssize_t
3538queue_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
3539{
3540 struct queue_sysfs_entry *entry = to_queue(attr);
3541 struct request_queue *q;
3542
3543 q = container_of(kobj, struct request_queue, kobj);
3544 if (!entry->show)
3545 return -EIO;
3546
3547 return entry->show(q, page);
3548}
3549
3550static ssize_t
3551queue_attr_store(struct kobject *kobj, struct attribute *attr,
3552 const char *page, size_t length)
3553{
3554 struct queue_sysfs_entry *entry = to_queue(attr);
3555 struct request_queue *q;
3556
3557 q = container_of(kobj, struct request_queue, kobj);
3558 if (!entry->store)
3559 return -EIO;
3560
3561 return entry->store(q, page, length);
3562}
3563
3564static struct sysfs_ops queue_sysfs_ops = {
3565 .show = queue_attr_show,
3566 .store = queue_attr_store,
3567};
3568
3569static struct kobj_type queue_ktype = {
3570 .sysfs_ops = &queue_sysfs_ops,
3571 .default_attrs = default_attrs,
3572};
3573
3574int blk_register_queue(struct gendisk *disk)
3575{
3576 int ret;
3577
3578 request_queue_t *q = disk->queue;
3579
3580 if (!q || !q->request_fn)
3581 return -ENXIO;
3582
3583 q->kobj.parent = kobject_get(&disk->kobj);
3584 if (!q->kobj.parent)
3585 return -EBUSY;
3586
3587 snprintf(q->kobj.name, KOBJ_NAME_LEN, "%s", "queue");
3588 q->kobj.ktype = &queue_ktype;
3589
3590 ret = kobject_register(&q->kobj);
3591 if (ret < 0)
3592 return ret;
3593
3594 ret = elv_register_queue(q);
3595 if (ret) {
3596 kobject_unregister(&q->kobj);
3597 return ret;
3598 }
3599
3600 return 0;
3601}
3602
3603void blk_unregister_queue(struct gendisk *disk)
3604{
3605 request_queue_t *q = disk->queue;
3606
3607 if (q && q->request_fn) {
3608 elv_unregister_queue(q);
3609
3610 kobject_unregister(&q->kobj);
3611 kobject_put(&disk->kobj);
3612 }
3613}
diff --git a/drivers/block/noop-iosched.c b/drivers/block/noop-iosched.c
deleted file mode 100644
index e54f006e7e60..000000000000
--- a/drivers/block/noop-iosched.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * elevator noop
3 */
4#include <linux/blkdev.h>
5#include <linux/elevator.h>
6#include <linux/bio.h>
7#include <linux/module.h>
8#include <linux/init.h>
9
10static void elevator_noop_add_request(request_queue_t *q, struct request *rq)
11{
12 rq->flags |= REQ_NOMERGE;
13 elv_dispatch_add_tail(q, rq);
14}
15
16static int elevator_noop_dispatch(request_queue_t *q, int force)
17{
18 return 0;
19}
20
21static struct elevator_type elevator_noop = {
22 .ops = {
23 .elevator_dispatch_fn = elevator_noop_dispatch,
24 .elevator_add_req_fn = elevator_noop_add_request,
25 },
26 .elevator_name = "noop",
27 .elevator_owner = THIS_MODULE,
28};
29
30static int __init noop_init(void)
31{
32 return elv_register(&elevator_noop);
33}
34
35static void __exit noop_exit(void)
36{
37 elv_unregister(&elevator_noop);
38}
39
40module_init(noop_init);
41module_exit(noop_exit);
42
43
44MODULE_AUTHOR("Jens Axboe");
45MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("No-op IO scheduler");
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index a280e679b1ca..59e5982a5db3 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -511,14 +511,11 @@ static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
511 */ 511 */
512static void pkt_iosched_process_queue(struct pktcdvd_device *pd) 512static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
513{ 513{
514 request_queue_t *q;
515 514
516 if (atomic_read(&pd->iosched.attention) == 0) 515 if (atomic_read(&pd->iosched.attention) == 0)
517 return; 516 return;
518 atomic_set(&pd->iosched.attention, 0); 517 atomic_set(&pd->iosched.attention, 0);
519 518
520 q = bdev_get_queue(pd->bdev);
521
522 for (;;) { 519 for (;;) {
523 struct bio *bio; 520 struct bio *bio;
524 int reads_queued, writes_queued; 521 int reads_queued, writes_queued;
diff --git a/drivers/block/scsi_ioctl.c b/drivers/block/scsi_ioctl.c
deleted file mode 100644
index 382dea7b224c..000000000000
--- a/drivers/block/scsi_ioctl.c
+++ /dev/null
@@ -1,589 +0,0 @@
1/*
2 * Copyright (C) 2001 Jens Axboe <axboe@suse.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public Licens
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
17 *
18 */
19#include <linux/kernel.h>
20#include <linux/errno.h>
21#include <linux/string.h>
22#include <linux/module.h>
23#include <linux/blkdev.h>
24#include <linux/completion.h>
25#include <linux/cdrom.h>
26#include <linux/slab.h>
27#include <linux/times.h>
28#include <asm/uaccess.h>
29
30#include <scsi/scsi.h>
31#include <scsi/scsi_ioctl.h>
32#include <scsi/scsi_cmnd.h>
33
34/* Command group 3 is reserved and should never be used. */
35const unsigned char scsi_command_size[8] =
36{
37 6, 10, 10, 12,
38 16, 12, 10, 10
39};
40
41EXPORT_SYMBOL(scsi_command_size);
42
43#define BLK_DEFAULT_TIMEOUT (60 * HZ)
44
45#include <scsi/sg.h>
46
47static int sg_get_version(int __user *p)
48{
49 static int sg_version_num = 30527;
50 return put_user(sg_version_num, p);
51}
52
53static int scsi_get_idlun(request_queue_t *q, int __user *p)
54{
55 return put_user(0, p);
56}
57
58static int scsi_get_bus(request_queue_t *q, int __user *p)
59{
60 return put_user(0, p);
61}
62
63static int sg_get_timeout(request_queue_t *q)
64{
65 return q->sg_timeout / (HZ / USER_HZ);
66}
67
68static int sg_set_timeout(request_queue_t *q, int __user *p)
69{
70 int timeout, err = get_user(timeout, p);
71
72 if (!err)
73 q->sg_timeout = timeout * (HZ / USER_HZ);
74
75 return err;
76}
77
78static int sg_get_reserved_size(request_queue_t *q, int __user *p)
79{
80 return put_user(q->sg_reserved_size, p);
81}
82
83static int sg_set_reserved_size(request_queue_t *q, int __user *p)
84{
85 int size, err = get_user(size, p);
86
87 if (err)
88 return err;
89
90 if (size < 0)
91 return -EINVAL;
92 if (size > (q->max_sectors << 9))
93 size = q->max_sectors << 9;
94
95 q->sg_reserved_size = size;
96 return 0;
97}
98
99/*
100 * will always return that we are ATAPI even for a real SCSI drive, I'm not
101 * so sure this is worth doing anything about (why would you care??)
102 */
103static int sg_emulated_host(request_queue_t *q, int __user *p)
104{
105 return put_user(1, p);
106}
107
108#define CMD_READ_SAFE 0x01
109#define CMD_WRITE_SAFE 0x02
110#define CMD_WARNED 0x04
111#define safe_for_read(cmd) [cmd] = CMD_READ_SAFE
112#define safe_for_write(cmd) [cmd] = CMD_WRITE_SAFE
113
114static int verify_command(struct file *file, unsigned char *cmd)
115{
116 static unsigned char cmd_type[256] = {
117
118 /* Basic read-only commands */
119 safe_for_read(TEST_UNIT_READY),
120 safe_for_read(REQUEST_SENSE),
121 safe_for_read(READ_6),
122 safe_for_read(READ_10),
123 safe_for_read(READ_12),
124 safe_for_read(READ_16),
125 safe_for_read(READ_BUFFER),
126 safe_for_read(READ_DEFECT_DATA),
127 safe_for_read(READ_LONG),
128 safe_for_read(INQUIRY),
129 safe_for_read(MODE_SENSE),
130 safe_for_read(MODE_SENSE_10),
131 safe_for_read(LOG_SENSE),
132 safe_for_read(START_STOP),
133 safe_for_read(GPCMD_VERIFY_10),
134 safe_for_read(VERIFY_16),
135
136 /* Audio CD commands */
137 safe_for_read(GPCMD_PLAY_CD),
138 safe_for_read(GPCMD_PLAY_AUDIO_10),
139 safe_for_read(GPCMD_PLAY_AUDIO_MSF),
140 safe_for_read(GPCMD_PLAY_AUDIO_TI),
141 safe_for_read(GPCMD_PAUSE_RESUME),
142
143 /* CD/DVD data reading */
144 safe_for_read(GPCMD_READ_BUFFER_CAPACITY),
145 safe_for_read(GPCMD_READ_CD),
146 safe_for_read(GPCMD_READ_CD_MSF),
147 safe_for_read(GPCMD_READ_DISC_INFO),
148 safe_for_read(GPCMD_READ_CDVD_CAPACITY),
149 safe_for_read(GPCMD_READ_DVD_STRUCTURE),
150 safe_for_read(GPCMD_READ_HEADER),
151 safe_for_read(GPCMD_READ_TRACK_RZONE_INFO),
152 safe_for_read(GPCMD_READ_SUBCHANNEL),
153 safe_for_read(GPCMD_READ_TOC_PMA_ATIP),
154 safe_for_read(GPCMD_REPORT_KEY),
155 safe_for_read(GPCMD_SCAN),
156 safe_for_read(GPCMD_GET_CONFIGURATION),
157 safe_for_read(GPCMD_READ_FORMAT_CAPACITIES),
158 safe_for_read(GPCMD_GET_EVENT_STATUS_NOTIFICATION),
159 safe_for_read(GPCMD_GET_PERFORMANCE),
160 safe_for_read(GPCMD_SEEK),
161 safe_for_read(GPCMD_STOP_PLAY_SCAN),
162
163 /* Basic writing commands */
164 safe_for_write(WRITE_6),
165 safe_for_write(WRITE_10),
166 safe_for_write(WRITE_VERIFY),
167 safe_for_write(WRITE_12),
168 safe_for_write(WRITE_VERIFY_12),
169 safe_for_write(WRITE_16),
170 safe_for_write(WRITE_LONG),
171 safe_for_write(WRITE_LONG_2),
172 safe_for_write(ERASE),
173 safe_for_write(GPCMD_MODE_SELECT_10),
174 safe_for_write(MODE_SELECT),
175 safe_for_write(LOG_SELECT),
176 safe_for_write(GPCMD_BLANK),
177 safe_for_write(GPCMD_CLOSE_TRACK),
178 safe_for_write(GPCMD_FLUSH_CACHE),
179 safe_for_write(GPCMD_FORMAT_UNIT),
180 safe_for_write(GPCMD_REPAIR_RZONE_TRACK),
181 safe_for_write(GPCMD_RESERVE_RZONE_TRACK),
182 safe_for_write(GPCMD_SEND_DVD_STRUCTURE),
183 safe_for_write(GPCMD_SEND_EVENT),
184 safe_for_write(GPCMD_SEND_KEY),
185 safe_for_write(GPCMD_SEND_OPC),
186 safe_for_write(GPCMD_SEND_CUE_SHEET),
187 safe_for_write(GPCMD_SET_SPEED),
188 safe_for_write(GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL),
189 safe_for_write(GPCMD_LOAD_UNLOAD),
190 safe_for_write(GPCMD_SET_STREAMING),
191 };
192 unsigned char type = cmd_type[cmd[0]];
193
194 /* Anybody who can open the device can do a read-safe command */
195 if (type & CMD_READ_SAFE)
196 return 0;
197
198 /* Write-safe commands just require a writable open.. */
199 if (type & CMD_WRITE_SAFE) {
200 if (file->f_mode & FMODE_WRITE)
201 return 0;
202 }
203
204 /* And root can do any command.. */
205 if (capable(CAP_SYS_RAWIO))
206 return 0;
207
208 if (!type) {
209 cmd_type[cmd[0]] = CMD_WARNED;
210 printk(KERN_WARNING "scsi: unknown opcode 0x%02x\n", cmd[0]);
211 }
212
213 /* Otherwise fail it with an "Operation not permitted" */
214 return -EPERM;
215}
216
217static int sg_io(struct file *file, request_queue_t *q,
218 struct gendisk *bd_disk, struct sg_io_hdr *hdr)
219{
220 unsigned long start_time;
221 int writing = 0, ret = 0;
222 struct request *rq;
223 struct bio *bio;
224 char sense[SCSI_SENSE_BUFFERSIZE];
225 unsigned char cmd[BLK_MAX_CDB];
226
227 if (hdr->interface_id != 'S')
228 return -EINVAL;
229 if (hdr->cmd_len > BLK_MAX_CDB)
230 return -EINVAL;
231 if (copy_from_user(cmd, hdr->cmdp, hdr->cmd_len))
232 return -EFAULT;
233 if (verify_command(file, cmd))
234 return -EPERM;
235
236 if (hdr->dxfer_len > (q->max_sectors << 9))
237 return -EIO;
238
239 if (hdr->dxfer_len)
240 switch (hdr->dxfer_direction) {
241 default:
242 return -EINVAL;
243 case SG_DXFER_TO_FROM_DEV:
244 case SG_DXFER_TO_DEV:
245 writing = 1;
246 break;
247 case SG_DXFER_FROM_DEV:
248 break;
249 }
250
251 rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
252 if (!rq)
253 return -ENOMEM;
254
255 if (hdr->iovec_count) {
256 const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
257 struct sg_iovec *iov;
258
259 iov = kmalloc(size, GFP_KERNEL);
260 if (!iov) {
261 ret = -ENOMEM;
262 goto out;
263 }
264
265 if (copy_from_user(iov, hdr->dxferp, size)) {
266 kfree(iov);
267 ret = -EFAULT;
268 goto out;
269 }
270
271 ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count);
272 kfree(iov);
273 } else if (hdr->dxfer_len)
274 ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
275
276 if (ret)
277 goto out;
278
279 /*
280 * fill in request structure
281 */
282 rq->cmd_len = hdr->cmd_len;
283 memcpy(rq->cmd, cmd, hdr->cmd_len);
284 if (sizeof(rq->cmd) != hdr->cmd_len)
285 memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len);
286
287 memset(sense, 0, sizeof(sense));
288 rq->sense = sense;
289 rq->sense_len = 0;
290
291 rq->flags |= REQ_BLOCK_PC;
292 bio = rq->bio;
293
294 /*
295 * bounce this after holding a reference to the original bio, it's
296 * needed for proper unmapping
297 */
298 if (rq->bio)
299 blk_queue_bounce(q, &rq->bio);
300
301 rq->timeout = (hdr->timeout * HZ) / 1000;
302 if (!rq->timeout)
303 rq->timeout = q->sg_timeout;
304 if (!rq->timeout)
305 rq->timeout = BLK_DEFAULT_TIMEOUT;
306
307 start_time = jiffies;
308
309 /* ignore return value. All information is passed back to caller
310 * (if he doesn't check that is his problem).
311 * N.B. a non-zero SCSI status is _not_ necessarily an error.
312 */
313 blk_execute_rq(q, bd_disk, rq, 0);
314
315 /* write to all output members */
316 hdr->status = 0xff & rq->errors;
317 hdr->masked_status = status_byte(rq->errors);
318 hdr->msg_status = msg_byte(rq->errors);
319 hdr->host_status = host_byte(rq->errors);
320 hdr->driver_status = driver_byte(rq->errors);
321 hdr->info = 0;
322 if (hdr->masked_status || hdr->host_status || hdr->driver_status)
323 hdr->info |= SG_INFO_CHECK;
324 hdr->resid = rq->data_len;
325 hdr->duration = ((jiffies - start_time) * 1000) / HZ;
326 hdr->sb_len_wr = 0;
327
328 if (rq->sense_len && hdr->sbp) {
329 int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);
330
331 if (!copy_to_user(hdr->sbp, rq->sense, len))
332 hdr->sb_len_wr = len;
333 }
334
335 if (blk_rq_unmap_user(bio, hdr->dxfer_len))
336 ret = -EFAULT;
337
338 /* may not have succeeded, but output values written to control
339 * structure (struct sg_io_hdr). */
340out:
341 blk_put_request(rq);
342 return ret;
343}
344
345#define OMAX_SB_LEN 16 /* For backward compatibility */
346
347static int sg_scsi_ioctl(struct file *file, request_queue_t *q,
348 struct gendisk *bd_disk, Scsi_Ioctl_Command __user *sic)
349{
350 struct request *rq;
351 int err;
352 unsigned int in_len, out_len, bytes, opcode, cmdlen;
353 char *buffer = NULL, sense[SCSI_SENSE_BUFFERSIZE];
354
355 /*
356 * get in an out lengths, verify they don't exceed a page worth of data
357 */
358 if (get_user(in_len, &sic->inlen))
359 return -EFAULT;
360 if (get_user(out_len, &sic->outlen))
361 return -EFAULT;
362 if (in_len > PAGE_SIZE || out_len > PAGE_SIZE)
363 return -EINVAL;
364 if (get_user(opcode, sic->data))
365 return -EFAULT;
366
367 bytes = max(in_len, out_len);
368 if (bytes) {
369 buffer = kmalloc(bytes, q->bounce_gfp | GFP_USER| __GFP_NOWARN);
370 if (!buffer)
371 return -ENOMEM;
372
373 memset(buffer, 0, bytes);
374 }
375
376 rq = blk_get_request(q, in_len ? WRITE : READ, __GFP_WAIT);
377
378 cmdlen = COMMAND_SIZE(opcode);
379
380 /*
381 * get command and data to send to device, if any
382 */
383 err = -EFAULT;
384 rq->cmd_len = cmdlen;
385 if (copy_from_user(rq->cmd, sic->data, cmdlen))
386 goto error;
387
388 if (copy_from_user(buffer, sic->data + cmdlen, in_len))
389 goto error;
390
391 err = verify_command(file, rq->cmd);
392 if (err)
393 goto error;
394
395 switch (opcode) {
396 case SEND_DIAGNOSTIC:
397 case FORMAT_UNIT:
398 rq->timeout = FORMAT_UNIT_TIMEOUT;
399 break;
400 case START_STOP:
401 rq->timeout = START_STOP_TIMEOUT;
402 break;
403 case MOVE_MEDIUM:
404 rq->timeout = MOVE_MEDIUM_TIMEOUT;
405 break;
406 case READ_ELEMENT_STATUS:
407 rq->timeout = READ_ELEMENT_STATUS_TIMEOUT;
408 break;
409 case READ_DEFECT_DATA:
410 rq->timeout = READ_DEFECT_DATA_TIMEOUT;
411 break;
412 default:
413 rq->timeout = BLK_DEFAULT_TIMEOUT;
414 break;
415 }
416
417 memset(sense, 0, sizeof(sense));
418 rq->sense = sense;
419 rq->sense_len = 0;
420
421 rq->data = buffer;
422 rq->data_len = bytes;
423 rq->flags |= REQ_BLOCK_PC;
424
425 blk_execute_rq(q, bd_disk, rq, 0);
426 err = rq->errors & 0xff; /* only 8 bit SCSI status */
427 if (err) {
428 if (rq->sense_len && rq->sense) {
429 bytes = (OMAX_SB_LEN > rq->sense_len) ?
430 rq->sense_len : OMAX_SB_LEN;
431 if (copy_to_user(sic->data, rq->sense, bytes))
432 err = -EFAULT;
433 }
434 } else {
435 if (copy_to_user(sic->data, buffer, out_len))
436 err = -EFAULT;
437 }
438
439error:
440 kfree(buffer);
441 blk_put_request(rq);
442 return err;
443}
444
445int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, void __user *arg)
446{
447 request_queue_t *q;
448 struct request *rq;
449 int close = 0, err;
450
451 q = bd_disk->queue;
452 if (!q)
453 return -ENXIO;
454
455 if (blk_get_queue(q))
456 return -ENXIO;
457
458 switch (cmd) {
459 /*
460 * new sgv3 interface
461 */
462 case SG_GET_VERSION_NUM:
463 err = sg_get_version(arg);
464 break;
465 case SCSI_IOCTL_GET_IDLUN:
466 err = scsi_get_idlun(q, arg);
467 break;
468 case SCSI_IOCTL_GET_BUS_NUMBER:
469 err = scsi_get_bus(q, arg);
470 break;
471 case SG_SET_TIMEOUT:
472 err = sg_set_timeout(q, arg);
473 break;
474 case SG_GET_TIMEOUT:
475 err = sg_get_timeout(q);
476 break;
477 case SG_GET_RESERVED_SIZE:
478 err = sg_get_reserved_size(q, arg);
479 break;
480 case SG_SET_RESERVED_SIZE:
481 err = sg_set_reserved_size(q, arg);
482 break;
483 case SG_EMULATED_HOST:
484 err = sg_emulated_host(q, arg);
485 break;
486 case SG_IO: {
487 struct sg_io_hdr hdr;
488
489 err = -EFAULT;
490 if (copy_from_user(&hdr, arg, sizeof(hdr)))
491 break;
492 err = sg_io(file, q, bd_disk, &hdr);
493 if (err == -EFAULT)
494 break;
495
496 if (copy_to_user(arg, &hdr, sizeof(hdr)))
497 err = -EFAULT;
498 break;
499 }
500 case CDROM_SEND_PACKET: {
501 struct cdrom_generic_command cgc;
502 struct sg_io_hdr hdr;
503
504 err = -EFAULT;
505 if (copy_from_user(&cgc, arg, sizeof(cgc)))
506 break;
507 cgc.timeout = clock_t_to_jiffies(cgc.timeout);
508 memset(&hdr, 0, sizeof(hdr));
509 hdr.interface_id = 'S';
510 hdr.cmd_len = sizeof(cgc.cmd);
511 hdr.dxfer_len = cgc.buflen;
512 err = 0;
513 switch (cgc.data_direction) {
514 case CGC_DATA_UNKNOWN:
515 hdr.dxfer_direction = SG_DXFER_UNKNOWN;
516 break;
517 case CGC_DATA_WRITE:
518 hdr.dxfer_direction = SG_DXFER_TO_DEV;
519 break;
520 case CGC_DATA_READ:
521 hdr.dxfer_direction = SG_DXFER_FROM_DEV;
522 break;
523 case CGC_DATA_NONE:
524 hdr.dxfer_direction = SG_DXFER_NONE;
525 break;
526 default:
527 err = -EINVAL;
528 }
529 if (err)
530 break;
531
532 hdr.dxferp = cgc.buffer;
533 hdr.sbp = cgc.sense;
534 if (hdr.sbp)
535 hdr.mx_sb_len = sizeof(struct request_sense);
536 hdr.timeout = cgc.timeout;
537 hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
538 hdr.cmd_len = sizeof(cgc.cmd);
539
540 err = sg_io(file, q, bd_disk, &hdr);
541 if (err == -EFAULT)
542 break;
543
544 if (hdr.status)
545 err = -EIO;
546
547 cgc.stat = err;
548 cgc.buflen = hdr.resid;
549 if (copy_to_user(arg, &cgc, sizeof(cgc)))
550 err = -EFAULT;
551
552 break;
553 }
554
555 /*
556 * old junk scsi send command ioctl
557 */
558 case SCSI_IOCTL_SEND_COMMAND:
559 printk(KERN_WARNING "program %s is using a deprecated SCSI ioctl, please convert it to SG_IO\n", current->comm);
560 err = -EINVAL;
561 if (!arg)
562 break;
563
564 err = sg_scsi_ioctl(file, q, bd_disk, arg);
565 break;
566 case CDROMCLOSETRAY:
567 close = 1;
568 case CDROMEJECT:
569 rq = blk_get_request(q, WRITE, __GFP_WAIT);
570 rq->flags |= REQ_BLOCK_PC;
571 rq->data = NULL;
572 rq->data_len = 0;
573 rq->timeout = BLK_DEFAULT_TIMEOUT;
574 memset(rq->cmd, 0, sizeof(rq->cmd));
575 rq->cmd[0] = GPCMD_START_STOP_UNIT;
576 rq->cmd[4] = 0x02 + (close != 0);
577 rq->cmd_len = 6;
578 err = blk_execute_rq(q, bd_disk, rq, 0);
579 blk_put_request(rq);
580 break;
581 default:
582 err = -ENOTTY;
583 }
584
585 blk_put_queue(q);
586 return err;
587}
588
589EXPORT_SYMBOL(scsi_cmd_ioctl);
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index e425ad3eebba..af7cb2bfd670 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -28,6 +28,7 @@
28#include <linux/devfs_fs_kernel.h> 28#include <linux/devfs_fs_kernel.h>
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/spinlock.h>
31#include <asm/io.h> 32#include <asm/io.h>
32#include <asm/dbdma.h> 33#include <asm/dbdma.h>
33#include <asm/prom.h> 34#include <asm/prom.h>
@@ -176,6 +177,7 @@ struct swim3 {
176 177
177struct floppy_state { 178struct floppy_state {
178 enum swim_state state; 179 enum swim_state state;
180 spinlock_t lock;
179 struct swim3 __iomem *swim3; /* hardware registers */ 181 struct swim3 __iomem *swim3; /* hardware registers */
180 struct dbdma_regs __iomem *dma; /* DMA controller registers */ 182 struct dbdma_regs __iomem *dma; /* DMA controller registers */
181 int swim3_intr; /* interrupt number for SWIM3 */ 183 int swim3_intr; /* interrupt number for SWIM3 */
@@ -304,7 +306,6 @@ static void do_fd_request(request_queue_t * q)
304#endif /* CONFIG_PMAC_MEDIABAY */ 306#endif /* CONFIG_PMAC_MEDIABAY */
305 start_request(&floppy_states[i]); 307 start_request(&floppy_states[i]);
306 } 308 }
307 sti();
308} 309}
309 310
310static void start_request(struct floppy_state *fs) 311static void start_request(struct floppy_state *fs)
@@ -370,7 +371,7 @@ static void set_timeout(struct floppy_state *fs, int nticks,
370{ 371{
371 unsigned long flags; 372 unsigned long flags;
372 373
373 save_flags(flags); cli(); 374 spin_lock_irqsave(&fs->lock, flags);
374 if (fs->timeout_pending) 375 if (fs->timeout_pending)
375 del_timer(&fs->timeout); 376 del_timer(&fs->timeout);
376 fs->timeout.expires = jiffies + nticks; 377 fs->timeout.expires = jiffies + nticks;
@@ -378,7 +379,7 @@ static void set_timeout(struct floppy_state *fs, int nticks,
378 fs->timeout.data = (unsigned long) fs; 379 fs->timeout.data = (unsigned long) fs;
379 add_timer(&fs->timeout); 380 add_timer(&fs->timeout);
380 fs->timeout_pending = 1; 381 fs->timeout_pending = 1;
381 restore_flags(flags); 382 spin_unlock_irqrestore(&fs->lock, flags);
382} 383}
383 384
384static inline void scan_track(struct floppy_state *fs) 385static inline void scan_track(struct floppy_state *fs)
@@ -790,14 +791,13 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state,
790{ 791{
791 unsigned long flags; 792 unsigned long flags;
792 793
793 save_flags(flags); 794 spin_lock_irqsave(&fs->lock, flags);
794 cli();
795 if (fs->state != idle) { 795 if (fs->state != idle) {
796 ++fs->wanted; 796 ++fs->wanted;
797 while (fs->state != available) { 797 while (fs->state != available) {
798 if (interruptible && signal_pending(current)) { 798 if (interruptible && signal_pending(current)) {
799 --fs->wanted; 799 --fs->wanted;
800 restore_flags(flags); 800 spin_unlock_irqrestore(&fs->lock, flags);
801 return -EINTR; 801 return -EINTR;
802 } 802 }
803 interruptible_sleep_on(&fs->wait); 803 interruptible_sleep_on(&fs->wait);
@@ -805,7 +805,7 @@ static int grab_drive(struct floppy_state *fs, enum swim_state state,
805 --fs->wanted; 805 --fs->wanted;
806 } 806 }
807 fs->state = state; 807 fs->state = state;
808 restore_flags(flags); 808 spin_unlock_irqrestore(&fs->lock, flags);
809 return 0; 809 return 0;
810} 810}
811 811
@@ -813,11 +813,10 @@ static void release_drive(struct floppy_state *fs)
813{ 813{
814 unsigned long flags; 814 unsigned long flags;
815 815
816 save_flags(flags); 816 spin_lock_irqsave(&fs->lock, flags);
817 cli();
818 fs->state = idle; 817 fs->state = idle;
819 start_request(fs); 818 start_request(fs);
820 restore_flags(flags); 819 spin_unlock_irqrestore(&fs->lock, flags);
821} 820}
822 821
823static int fd_eject(struct floppy_state *fs) 822static int fd_eject(struct floppy_state *fs)
@@ -1109,6 +1108,7 @@ static int swim3_add_device(struct device_node *swim)
1109 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); 1108 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
1110 1109
1111 memset(fs, 0, sizeof(*fs)); 1110 memset(fs, 0, sizeof(*fs));
1111 spin_lock_init(&fs->lock);
1112 fs->state = idle; 1112 fs->state = idle;
1113 fs->swim3 = (struct swim3 __iomem *) 1113 fs->swim3 = (struct swim3 __iomem *)
1114 ioremap(swim->addrs[0].address, 0x200); 1114 ioremap(swim->addrs[0].address, 0x200);
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 5fd3e4cb7525..8e7fb3551775 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -179,14 +179,12 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
179 if (ignore || (intf->cur_altsetting->desc.bInterfaceNumber != 0)) 179 if (ignore || (intf->cur_altsetting->desc.bInterfaceNumber != 0))
180 return -ENODEV; 180 return -ENODEV;
181 181
182 data = kmalloc(sizeof(*data), GFP_KERNEL); 182 data = kzalloc(sizeof(*data), GFP_KERNEL);
183 if (!data) { 183 if (!data) {
184 BT_ERR("Can't allocate memory for data structure"); 184 BT_ERR("Can't allocate memory for data structure");
185 return -ENOMEM; 185 return -ENOMEM;
186 } 186 }
187 187
188 memset(data, 0, sizeof(*data));
189
190 data->udev = udev; 188 data->udev = udev;
191 data->state = BCM203X_LOAD_MINIDRV; 189 data->state = BCM203X_LOAD_MINIDRV;
192 190
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 1e9db0156ea7..067e27893e4a 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -673,13 +673,11 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
673 } 673 }
674 674
675 /* Initialize control structure and load firmware */ 675 /* Initialize control structure and load firmware */
676 if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) { 676 if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) {
677 BT_ERR("Can't allocate memory for control structure"); 677 BT_ERR("Can't allocate memory for control structure");
678 goto done; 678 goto done;
679 } 679 }
680 680
681 memset(bfusb, 0, sizeof(struct bfusb));
682
683 bfusb->udev = udev; 681 bfusb->udev = udev;
684 bfusb->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress; 682 bfusb->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress;
685 bfusb->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress; 683 bfusb->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress;
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 26fe9c0e1d20..f36c563d72c4 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -870,10 +870,9 @@ static dev_link_t *bluecard_attach(void)
870 int ret; 870 int ret;
871 871
872 /* Create new info device */ 872 /* Create new info device */
873 info = kmalloc(sizeof(*info), GFP_KERNEL); 873 info = kzalloc(sizeof(*info), GFP_KERNEL);
874 if (!info) 874 if (!info)
875 return NULL; 875 return NULL;
876 memset(info, 0, sizeof(*info));
877 876
878 link = &info->link; 877 link = &info->link;
879 link->priv = info; 878 link->priv = info;
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 0db0400519c9..394796315adc 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -84,8 +84,8 @@ struct bpa10x_data {
84 84
85struct hci_vendor_hdr { 85struct hci_vendor_hdr {
86 __u8 type; 86 __u8 type;
87 __u16 snum; 87 __le16 snum;
88 __u16 dlen; 88 __le16 dlen;
89} __attribute__ ((packed)); 89} __attribute__ ((packed));
90 90
91static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count) 91static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
@@ -553,14 +553,12 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
553 if (intf->cur_altsetting->desc.bInterfaceNumber > 0) 553 if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
554 return -ENODEV; 554 return -ENODEV;
555 555
556 data = kmalloc(sizeof(*data), GFP_KERNEL); 556 data = kzalloc(sizeof(*data), GFP_KERNEL);
557 if (!data) { 557 if (!data) {
558 BT_ERR("Can't allocate data structure"); 558 BT_ERR("Can't allocate data structure");
559 return -ENOMEM; 559 return -ENOMEM;
560 } 560 }
561 561
562 memset(data, 0, sizeof(*data));
563
564 data->udev = udev; 562 data->udev = udev;
565 563
566 rwlock_init(&data->lock); 564 rwlock_init(&data->lock);
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 2e0338d80f32..d2a0add19cc8 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -671,10 +671,9 @@ static dev_link_t *bt3c_attach(void)
671 int ret; 671 int ret;
672 672
673 /* Create new info device */ 673 /* Create new info device */
674 info = kmalloc(sizeof(*info), GFP_KERNEL); 674 info = kzalloc(sizeof(*info), GFP_KERNEL);
675 if (!info) 675 if (!info)
676 return NULL; 676 return NULL;
677 memset(info, 0, sizeof(*info));
678 677
679 link = &info->link; 678 link = &info->link;
680 link->priv = info; 679 link->priv = info;
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 89486ea7a021..529a28a3209d 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -590,10 +590,9 @@ static dev_link_t *btuart_attach(void)
590 int ret; 590 int ret;
591 591
592 /* Create new info device */ 592 /* Create new info device */
593 info = kmalloc(sizeof(*info), GFP_KERNEL); 593 info = kzalloc(sizeof(*info), GFP_KERNEL);
594 if (!info) 594 if (!info)
595 return NULL; 595 return NULL;
596 memset(info, 0, sizeof(*info));
597 596
598 link = &info->link; 597 link = &info->link;
599 link->priv = info; 598 link->priv = info;
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 84c1f8839422..dec5980a1cd6 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -569,10 +569,9 @@ static dev_link_t *dtl1_attach(void)
569 int ret; 569 int ret;
570 570
571 /* Create new info device */ 571 /* Create new info device */
572 info = kmalloc(sizeof(*info), GFP_KERNEL); 572 info = kzalloc(sizeof(*info), GFP_KERNEL);
573 if (!info) 573 if (!info)
574 return NULL; 574 return NULL;
575 memset(info, 0, sizeof(*info));
576 575
577 link = &info->link; 576 link = &info->link;
578 link->priv = info; 577 link->priv = info;
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 0a4761415ac3..8fddfdfd0fbd 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -715,10 +715,9 @@ static int bcsp_open(struct hci_uart *hu)
715 715
716 BT_DBG("hu %p", hu); 716 BT_DBG("hu %p", hu);
717 717
718 bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC); 718 bcsp = kzalloc(sizeof(*bcsp), GFP_ATOMIC);
719 if (!bcsp) 719 if (!bcsp)
720 return -ENOMEM; 720 return -ENOMEM;
721 memset(bcsp, 0, sizeof(*bcsp));
722 721
723 hu->priv = bcsp; 722 hu->priv = bcsp;
724 skb_queue_head_init(&bcsp->unack); 723 skb_queue_head_init(&bcsp->unack);
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 12e369a66fc2..4804d474dc87 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -76,12 +76,10 @@ static int h4_open(struct hci_uart *hu)
76 76
77 BT_DBG("hu %p", hu); 77 BT_DBG("hu %p", hu);
78 78
79 h4 = kmalloc(sizeof(*h4), GFP_ATOMIC); 79 h4 = kzalloc(sizeof(*h4), GFP_ATOMIC);
80 if (!h4) 80 if (!h4)
81 return -ENOMEM; 81 return -ENOMEM;
82 82
83 memset(h4, 0, sizeof(*h4));
84
85 skb_queue_head_init(&h4->txq); 83 skb_queue_head_init(&h4->txq);
86 84
87 hu->priv = h4; 85 hu->priv = h4;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 4a775f6ea390..573ff6c1be5f 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -272,13 +272,11 @@ static int hci_uart_tty_open(struct tty_struct *tty)
272 if (hu) 272 if (hu)
273 return -EEXIST; 273 return -EEXIST;
274 274
275 if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) { 275 if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
276 BT_ERR("Can't allocate controll structure"); 276 BT_ERR("Can't allocate controll structure");
277 return -ENFILE; 277 return -ENFILE;
278 } 278 }
279 279
280 memset(hu, 0, sizeof(struct hci_uart));
281
282 tty->disc_data = hu; 280 tty->disc_data = hu;
283 hu->tty = tty; 281 hu->tty = tty;
284 282
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 6756cb20b753..057cb2b6e6d1 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -65,6 +65,7 @@
65#endif 65#endif
66 66
67static int ignore = 0; 67static int ignore = 0;
68static int ignore_dga = 0;
68static int ignore_csr = 0; 69static int ignore_csr = 0;
69static int ignore_sniffer = 0; 70static int ignore_sniffer = 0;
70static int reset = 0; 71static int reset = 0;
@@ -841,6 +842,9 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
841 if (ignore || id->driver_info & HCI_IGNORE) 842 if (ignore || id->driver_info & HCI_IGNORE)
842 return -ENODEV; 843 return -ENODEV;
843 844
845 if (ignore_dga && id->driver_info & HCI_DIGIANSWER)
846 return -ENODEV;
847
844 if (ignore_csr && id->driver_info & HCI_CSR) 848 if (ignore_csr && id->driver_info & HCI_CSR)
845 return -ENODEV; 849 return -ENODEV;
846 850
@@ -875,13 +879,11 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
875 goto done; 879 goto done;
876 } 880 }
877 881
878 if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) { 882 if (!(husb = kzalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
879 BT_ERR("Can't allocate: control structure"); 883 BT_ERR("Can't allocate: control structure");
880 goto done; 884 goto done;
881 } 885 }
882 886
883 memset(husb, 0, sizeof(struct hci_usb));
884
885 husb->udev = udev; 887 husb->udev = udev;
886 husb->bulk_out_ep = bulk_out_ep; 888 husb->bulk_out_ep = bulk_out_ep;
887 husb->bulk_in_ep = bulk_in_ep; 889 husb->bulk_in_ep = bulk_in_ep;
@@ -1072,6 +1074,9 @@ module_exit(hci_usb_exit);
1072module_param(ignore, bool, 0644); 1074module_param(ignore, bool, 0644);
1073MODULE_PARM_DESC(ignore, "Ignore devices from the matching table"); 1075MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
1074 1076
1077module_param(ignore_dga, bool, 0644);
1078MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
1079
1075module_param(ignore_csr, bool, 0644); 1080module_param(ignore_csr, bool, 0644);
1076MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001"); 1081MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
1077 1082
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 52cbd45c308f..85738223ff0c 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -261,12 +261,10 @@ static int vhci_open(struct inode *inode, struct file *file)
261 struct vhci_data *vhci; 261 struct vhci_data *vhci;
262 struct hci_dev *hdev; 262 struct hci_dev *hdev;
263 263
264 vhci = kmalloc(sizeof(struct vhci_data), GFP_KERNEL); 264 vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
265 if (!vhci) 265 if (!vhci)
266 return -ENOMEM; 266 return -ENOMEM;
267 267
268 memset(vhci, 0, sizeof(struct vhci_data));
269
270 skb_queue_head_init(&vhci->readq); 268 skb_queue_head_init(&vhci->readq);
271 init_waitqueue_head(&vhci->read_wait); 269 init_waitqueue_head(&vhci->read_wait);
272 270
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c
index b89420e6d704..a0b580c22d80 100644
--- a/drivers/cdrom/mcdx.c
+++ b/drivers/cdrom/mcdx.c
@@ -1085,7 +1085,7 @@ static int __init mcdx_init_drive(int drive)
1085 1085
1086 xtrace(INIT, "kmalloc space for stuffpt's\n"); 1086 xtrace(INIT, "kmalloc space for stuffpt's\n");
1087 xtrace(MALLOC, "init() malloc %d bytes\n", size); 1087 xtrace(MALLOC, "init() malloc %d bytes\n", size);
1088 if (!(stuffp = kmalloc(size, GFP_KERNEL))) { 1088 if (!(stuffp = kzalloc(size, GFP_KERNEL))) {
1089 xwarn("init() malloc failed\n"); 1089 xwarn("init() malloc failed\n");
1090 return 1; 1090 return 1;
1091 } 1091 }
@@ -1101,8 +1101,6 @@ static int __init mcdx_init_drive(int drive)
1101 sizeof(*stuffp), stuffp); 1101 sizeof(*stuffp), stuffp);
1102 1102
1103 /* set default values */ 1103 /* set default values */
1104 memset(stuffp, 0, sizeof(*stuffp));
1105
1106 stuffp->present = 0; /* this should be 0 already */ 1104 stuffp->present = 0; /* this should be 0 already */
1107 stuffp->toc = NULL; /* this should be NULL already */ 1105 stuffp->toc = NULL; /* this should be NULL already */
1108 1106
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 3a41672e4d66..1f776651ac64 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -94,19 +94,16 @@ static int amd_create_gatt_pages(int nr_tables)
94 int retval = 0; 94 int retval = 0;
95 int i; 95 int i;
96 96
97 tables = kmalloc((nr_tables + 1) * sizeof(struct amd_page_map *), 97 tables = kzalloc((nr_tables + 1) * sizeof(struct amd_page_map *),GFP_KERNEL);
98 GFP_KERNEL);
99 if (tables == NULL) 98 if (tables == NULL)
100 return -ENOMEM; 99 return -ENOMEM;
101 100
102 memset (tables, 0, sizeof(struct amd_page_map *) * (nr_tables + 1));
103 for (i = 0; i < nr_tables; i++) { 101 for (i = 0; i < nr_tables; i++) {
104 entry = kmalloc(sizeof(struct amd_page_map), GFP_KERNEL); 102 entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL);
105 if (entry == NULL) { 103 if (entry == NULL) {
106 retval = -ENOMEM; 104 retval = -ENOMEM;
107 break; 105 break;
108 } 106 }
109 memset (entry, 0, sizeof(struct amd_page_map));
110 tables[i] = entry; 107 tables[i] = entry;
111 retval = amd_create_page_map(entry); 108 retval = amd_create_page_map(entry);
112 if (retval != 0) 109 if (retval != 0)
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 0e6c3a31d344..78ce98a69f37 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -13,6 +13,7 @@
13#include <linux/pci.h> 13#include <linux/pci.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/agp_backend.h> 15#include <linux/agp_backend.h>
16#include <linux/mmzone.h>
16#include <asm/page.h> /* PAGE_SIZE */ 17#include <asm/page.h> /* PAGE_SIZE */
17#include "agp.h" 18#include "agp.h"
18 19
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 0b6e72642d6e..53372a83b675 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -118,14 +118,12 @@ static int ati_create_gatt_pages(int nr_tables)
118 int retval = 0; 118 int retval = 0;
119 int i; 119 int i;
120 120
121 tables = kmalloc((nr_tables + 1) * sizeof(ati_page_map *), 121 tables = kzalloc((nr_tables + 1) * sizeof(ati_page_map *),GFP_KERNEL);
122 GFP_KERNEL);
123 if (tables == NULL) 122 if (tables == NULL)
124 return -ENOMEM; 123 return -ENOMEM;
125 124
126 memset(tables, 0, sizeof(ati_page_map *) * (nr_tables + 1));
127 for (i = 0; i < nr_tables; i++) { 125 for (i = 0; i < nr_tables; i++) {
128 entry = kmalloc(sizeof(ati_page_map), GFP_KERNEL); 126 entry = kzalloc(sizeof(ati_page_map), GFP_KERNEL);
129 if (entry == NULL) { 127 if (entry == NULL) {
130 while (i>0) { 128 while (i>0) {
131 kfree (tables[i-1]); 129 kfree (tables[i-1]);
@@ -136,7 +134,6 @@ static int ati_create_gatt_pages(int nr_tables)
136 retval = -ENOMEM; 134 retval = -ENOMEM;
137 break; 135 break;
138 } 136 }
139 memset(entry, 0, sizeof(ati_page_map));
140 tables[i] = entry; 137 tables[i] = entry;
141 retval = ati_create_page_map(entry); 138 retval = ati_create_page_map(entry);
142 if (retval != 0) break; 139 if (retval != 0) break;
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 82b43c541c8d..27bca34b4a65 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -147,6 +147,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
147 printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); 147 printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
148 return -ENOMEM; 148 return -ENOMEM;
149 } 149 }
150 flush_agp_mappings();
150 151
151 bridge->scratch_page_real = virt_to_gart(addr); 152 bridge->scratch_page_real = virt_to_gart(addr);
152 bridge->scratch_page = 153 bridge->scratch_page =
@@ -187,9 +188,11 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
187 return 0; 188 return 0;
188 189
189err_out: 190err_out:
190 if (bridge->driver->needs_scratch_page) 191 if (bridge->driver->needs_scratch_page) {
191 bridge->driver->agp_destroy_page( 192 bridge->driver->agp_destroy_page(
192 gart_to_virt(bridge->scratch_page_real)); 193 gart_to_virt(bridge->scratch_page_real));
194 flush_agp_mappings();
195 }
193 if (got_gatt) 196 if (got_gatt)
194 bridge->driver->free_gatt_table(bridge); 197 bridge->driver->free_gatt_table(bridge);
195 if (got_keylist) { 198 if (got_keylist) {
@@ -211,9 +214,11 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
211 bridge->key_list = NULL; 214 bridge->key_list = NULL;
212 215
213 if (bridge->driver->agp_destroy_page && 216 if (bridge->driver->agp_destroy_page &&
214 bridge->driver->needs_scratch_page) 217 bridge->driver->needs_scratch_page) {
215 bridge->driver->agp_destroy_page( 218 bridge->driver->agp_destroy_page(
216 gart_to_virt(bridge->scratch_page_real)); 219 gart_to_virt(bridge->scratch_page_real));
220 flush_agp_mappings();
221 }
217} 222}
218 223
219/* When we remove the global variable agp_bridge from all drivers 224/* When we remove the global variable agp_bridge from all drivers
@@ -222,12 +227,12 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
222 227
223struct agp_bridge_data *agp_alloc_bridge(void) 228struct agp_bridge_data *agp_alloc_bridge(void)
224{ 229{
225 struct agp_bridge_data *bridge = kmalloc(sizeof(*bridge), GFP_KERNEL); 230 struct agp_bridge_data *bridge;
226 231
232 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
227 if (!bridge) 233 if (!bridge)
228 return NULL; 234 return NULL;
229 235
230 memset(bridge, 0, sizeof(*bridge));
231 atomic_set(&bridge->agp_in_use, 0); 236 atomic_set(&bridge->agp_in_use, 0);
232 atomic_set(&bridge->current_memory_agp, 0); 237 atomic_set(&bridge->current_memory_agp, 0);
233 238
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index ac19fdcd21c1..e7aea77a60f9 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge)
219 219
220 efficeon_private.l1_table[index] = page; 220 efficeon_private.l1_table[index] = page;
221 221
222 value = virt_to_gart(page) | pati | present | index; 222 value = virt_to_gart((unsigned long *)page) | pati | present | index;
223 223
224 pci_write_config_dword(agp_bridge->dev, 224 pci_write_config_dword(agp_bridge->dev,
225 EFFICEON_ATTPAGE, value); 225 EFFICEON_ATTPAGE, value);
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 3dfb6648547b..17f520c9d471 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -189,13 +189,12 @@ static int agp_create_segment(struct agp_client *client, struct agp_region *regi
189 struct agp_segment *user_seg; 189 struct agp_segment *user_seg;
190 size_t i; 190 size_t i;
191 191
192 seg = kmalloc((sizeof(struct agp_segment_priv) * region->seg_count), GFP_KERNEL); 192 seg = kzalloc((sizeof(struct agp_segment_priv) * region->seg_count), GFP_KERNEL);
193 if (seg == NULL) { 193 if (seg == NULL) {
194 kfree(region->seg_list); 194 kfree(region->seg_list);
195 region->seg_list = NULL; 195 region->seg_list = NULL;
196 return -ENOMEM; 196 return -ENOMEM;
197 } 197 }
198 memset(seg, 0, (sizeof(struct agp_segment_priv) * region->seg_count));
199 user_seg = region->seg_list; 198 user_seg = region->seg_list;
200 199
201 for (i = 0; i < region->seg_count; i++) { 200 for (i = 0; i < region->seg_count; i++) {
@@ -332,14 +331,11 @@ static struct agp_controller *agp_create_controller(pid_t id)
332{ 331{
333 struct agp_controller *controller; 332 struct agp_controller *controller;
334 333
335 controller = kmalloc(sizeof(struct agp_controller), GFP_KERNEL); 334 controller = kzalloc(sizeof(struct agp_controller), GFP_KERNEL);
336
337 if (controller == NULL) 335 if (controller == NULL)
338 return NULL; 336 return NULL;
339 337
340 memset(controller, 0, sizeof(struct agp_controller));
341 controller->pid = id; 338 controller->pid = id;
342
343 return controller; 339 return controller;
344} 340}
345 341
@@ -540,12 +536,10 @@ static struct agp_client *agp_create_client(pid_t id)
540{ 536{
541 struct agp_client *new_client; 537 struct agp_client *new_client;
542 538
543 new_client = kmalloc(sizeof(struct agp_client), GFP_KERNEL); 539 new_client = kzalloc(sizeof(struct agp_client), GFP_KERNEL);
544
545 if (new_client == NULL) 540 if (new_client == NULL)
546 return NULL; 541 return NULL;
547 542
548 memset(new_client, 0, sizeof(struct agp_client));
549 new_client->pid = id; 543 new_client->pid = id;
550 agp_insert_client(new_client); 544 agp_insert_client(new_client);
551 return new_client; 545 return new_client;
@@ -709,11 +703,10 @@ static int agp_open(struct inode *inode, struct file *file)
709 if (minor != AGPGART_MINOR) 703 if (minor != AGPGART_MINOR)
710 goto err_out; 704 goto err_out;
711 705
712 priv = kmalloc(sizeof(struct agp_file_private), GFP_KERNEL); 706 priv = kzalloc(sizeof(struct agp_file_private), GFP_KERNEL);
713 if (priv == NULL) 707 if (priv == NULL)
714 goto err_out_nomem; 708 goto err_out_nomem;
715 709
716 memset(priv, 0, sizeof(struct agp_file_private));
717 set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags); 710 set_bit(AGP_FF_ALLOW_CLIENT, &priv->access_flags);
718 priv->my_pid = current->pid; 711 priv->my_pid = current->pid;
719 712
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index ac9da0ca36b7..5567ce8d72b0 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -57,7 +57,8 @@ int map_page_into_agp(struct page *page)
57{ 57{
58 int i; 58 int i;
59 i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE); 59 i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE);
60 global_flush_tlb(); 60 /* Caller's responsibility to call global_flush_tlb() for
61 * performance reasons */
61 return i; 62 return i;
62} 63}
63EXPORT_SYMBOL_GPL(map_page_into_agp); 64EXPORT_SYMBOL_GPL(map_page_into_agp);
@@ -66,7 +67,8 @@ int unmap_page_from_agp(struct page *page)
66{ 67{
67 int i; 68 int i;
68 i = change_page_attr(page, 1, PAGE_KERNEL); 69 i = change_page_attr(page, 1, PAGE_KERNEL);
69 global_flush_tlb(); 70 /* Caller's responsibility to call global_flush_tlb() for
71 * performance reasons */
70 return i; 72 return i;
71} 73}
72EXPORT_SYMBOL_GPL(unmap_page_from_agp); 74EXPORT_SYMBOL_GPL(unmap_page_from_agp);
@@ -105,12 +107,10 @@ struct agp_memory *agp_create_memory(int scratch_pages)
105{ 107{
106 struct agp_memory *new; 108 struct agp_memory *new;
107 109
108 new = kmalloc(sizeof(struct agp_memory), GFP_KERNEL); 110 new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL);
109
110 if (new == NULL) 111 if (new == NULL)
111 return NULL; 112 return NULL;
112 113
113 memset(new, 0, sizeof(struct agp_memory));
114 new->key = agp_get_key(); 114 new->key = agp_get_key();
115 115
116 if (new->key < 0) { 116 if (new->key < 0) {
@@ -155,6 +155,7 @@ void agp_free_memory(struct agp_memory *curr)
155 for (i = 0; i < curr->page_count; i++) { 155 for (i = 0; i < curr->page_count; i++) {
156 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); 156 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]));
157 } 157 }
158 flush_agp_mappings();
158 } 159 }
159 agp_free_key(curr->key); 160 agp_free_key(curr->key);
160 vfree(curr->memory); 161 vfree(curr->memory);
@@ -212,7 +213,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
212 new->memory[i] = virt_to_gart(addr); 213 new->memory[i] = virt_to_gart(addr);
213 new->page_count++; 214 new->page_count++;
214 } 215 }
215 new->bridge = bridge; 216 new->bridge = bridge;
216 217
217 flush_agp_mappings(); 218 flush_agp_mappings();
218 219
@@ -414,7 +415,8 @@ static void agp_v2_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
414 u32 tmp; 415 u32 tmp;
415 416
416 if (*requested_mode & AGP2_RESERVED_MASK) { 417 if (*requested_mode & AGP2_RESERVED_MASK) {
417 printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode); 418 printk(KERN_INFO PFX "reserved bits set (%x) in mode 0x%x. Fixed.\n",
419 *requested_mode & AGP2_RESERVED_MASK, *requested_mode);
418 *requested_mode &= ~AGP2_RESERVED_MASK; 420 *requested_mode &= ~AGP2_RESERVED_MASK;
419 } 421 }
420 422
@@ -492,7 +494,8 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_
492 u32 tmp; 494 u32 tmp;
493 495
494 if (*requested_mode & AGP3_RESERVED_MASK) { 496 if (*requested_mode & AGP3_RESERVED_MASK) {
495 printk(KERN_INFO PFX "reserved bits set in mode 0x%x. Fixed.\n", *requested_mode); 497 printk(KERN_INFO PFX "reserved bits set (%x) in mode 0x%x. Fixed.\n",
498 *requested_mode & AGP3_RESERVED_MASK, *requested_mode);
496 *requested_mode &= ~AGP3_RESERVED_MASK; 499 *requested_mode &= ~AGP3_RESERVED_MASK;
497 } 500 }
498 501
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index a2d9e5e48bbe..8ee19a4a6bce 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -111,8 +111,10 @@ static int i460_fetch_size (void)
111 111
112 if (i460.io_page_shift != I460_IO_PAGE_SHIFT) { 112 if (i460.io_page_shift != I460_IO_PAGE_SHIFT) {
113 printk(KERN_ERR PFX 113 printk(KERN_ERR PFX
114 "I/O (GART) page-size %ZuKB doesn't match expected size %ZuKB\n", 114 "I/O (GART) page-size %luKB doesn't match expected "
115 1UL << (i460.io_page_shift - 10), 1UL << (I460_IO_PAGE_SHIFT)); 115 "size %luKB\n",
116 1UL << (i460.io_page_shift - 10),
117 1UL << (I460_IO_PAGE_SHIFT));
116 return 0; 118 return 0;
117 } 119 }
118 120
@@ -227,10 +229,9 @@ static int i460_configure (void)
227 */ 229 */
228 if (I460_IO_PAGE_SHIFT > PAGE_SHIFT) { 230 if (I460_IO_PAGE_SHIFT > PAGE_SHIFT) {
229 size = current_size->num_entries * sizeof(i460.lp_desc[0]); 231 size = current_size->num_entries * sizeof(i460.lp_desc[0]);
230 i460.lp_desc = kmalloc(size, GFP_KERNEL); 232 i460.lp_desc = kzalloc(size, GFP_KERNEL);
231 if (!i460.lp_desc) 233 if (!i460.lp_desc)
232 return -ENOMEM; 234 return -ENOMEM;
233 memset(i460.lp_desc, 0, size);
234 } 235 }
235 return 0; 236 return 0;
236} 237}
@@ -366,13 +367,12 @@ static int i460_alloc_large_page (struct lp_desc *lp)
366 } 367 }
367 368
368 map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8; 369 map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8;
369 lp->alloced_map = kmalloc(map_size, GFP_KERNEL); 370 lp->alloced_map = kzalloc(map_size, GFP_KERNEL);
370 if (!lp->alloced_map) { 371 if (!lp->alloced_map) {
371 free_pages((unsigned long) lpage, order); 372 free_pages((unsigned long) lpage, order);
372 printk(KERN_ERR PFX "Out of memory, we're in trouble...\n"); 373 printk(KERN_ERR PFX "Out of memory, we're in trouble...\n");
373 return -ENOMEM; 374 return -ENOMEM;
374 } 375 }
375 memset(lp->alloced_map, 0, map_size);
376 376
377 lp->paddr = virt_to_gart(lpage); 377 lp->paddr = virt_to_gart(lpage);
378 lp->refcount = 0; 378 lp->refcount = 0;
@@ -516,9 +516,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
516{ 516{
517 void *page; 517 void *page;
518 518
519 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) 519 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
520 page = agp_generic_alloc_page(agp_bridge); 520 page = agp_generic_alloc_page(agp_bridge);
521 else 521 global_flush_tlb();
522 } else
522 /* Returning NULL would cause problems */ 523 /* Returning NULL would cause problems */
523 /* AK: really dubious code. */ 524 /* AK: really dubious code. */
524 page = (void *)~0UL; 525 page = (void *)~0UL;
@@ -527,8 +528,10 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge)
527 528
528static void i460_destroy_page (void *page) 529static void i460_destroy_page (void *page)
529{ 530{
530 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) 531 if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) {
531 agp_generic_destroy_page(page); 532 agp_generic_destroy_page(page);
533 global_flush_tlb();
534 }
532} 535}
533 536
534#endif /* I460_LARGE_IO_PAGES */ 537#endif /* I460_LARGE_IO_PAGES */
@@ -538,7 +541,7 @@ static unsigned long i460_mask_memory (struct agp_bridge_data *bridge,
538{ 541{
539 /* Make sure the returned address is a valid GATT entry */ 542 /* Make sure the returned address is a valid GATT entry */
540 return bridge->driver->masks[0].mask 543 return bridge->driver->masks[0].mask
541 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12); 544 | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12);
542} 545}
543 546
544struct agp_bridge_driver intel_i460_driver = { 547struct agp_bridge_driver intel_i460_driver = {
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 1f7d415f432c..e7bed5047dcc 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -270,6 +270,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
270 270
271 switch (pg_count) { 271 switch (pg_count) {
272 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); 272 case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge);
273 global_flush_tlb();
273 break; 274 break;
274 case 4: 275 case 4:
275 /* kludge to get 4 physical pages for ARGB cursor */ 276 /* kludge to get 4 physical pages for ARGB cursor */
@@ -330,9 +331,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
330 if(curr->type == AGP_PHYS_MEMORY) { 331 if(curr->type == AGP_PHYS_MEMORY) {
331 if (curr->page_count == 4) 332 if (curr->page_count == 4)
332 i8xx_destroy_pages(gart_to_virt(curr->memory[0])); 333 i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
333 else 334 else {
334 agp_bridge->driver->agp_destroy_page( 335 agp_bridge->driver->agp_destroy_page(
335 gart_to_virt(curr->memory[0])); 336 gart_to_virt(curr->memory[0]));
337 global_flush_tlb();
338 }
336 vfree(curr->memory); 339 vfree(curr->memory);
337 } 340 }
338 kfree(curr); 341 kfree(curr);
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 7957fc91f6ad..4df7734b51c2 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -289,6 +289,8 @@ static int __devinit agp_sgi_init(void)
289 j = 0; 289 j = 0;
290 list_for_each_entry(info, &tioca_list, ca_list) { 290 list_for_each_entry(info, &tioca_list, ca_list) {
291 struct list_head *tmp; 291 struct list_head *tmp;
292 if (list_empty(info->ca_devices))
293 continue;
292 list_for_each(tmp, info->ca_devices) { 294 list_for_each(tmp, info->ca_devices) {
293 u8 cap_ptr; 295 u8 cap_ptr;
294 pdev = pci_dev_b(tmp); 296 pdev = pci_dev_b(tmp);
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 71ea59a1dbeb..3f8f7fa6b0ff 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -102,19 +102,17 @@ static int serverworks_create_gatt_pages(int nr_tables)
102 int retval = 0; 102 int retval = 0;
103 int i; 103 int i;
104 104
105 tables = kmalloc((nr_tables + 1) * sizeof(struct serverworks_page_map *), 105 tables = kzalloc((nr_tables + 1) * sizeof(struct serverworks_page_map *),
106 GFP_KERNEL); 106 GFP_KERNEL);
107 if (tables == NULL) { 107 if (tables == NULL)
108 return -ENOMEM; 108 return -ENOMEM;
109 } 109
110 memset(tables, 0, sizeof(struct serverworks_page_map *) * (nr_tables + 1));
111 for (i = 0; i < nr_tables; i++) { 110 for (i = 0; i < nr_tables; i++) {
112 entry = kmalloc(sizeof(struct serverworks_page_map), GFP_KERNEL); 111 entry = kzalloc(sizeof(struct serverworks_page_map), GFP_KERNEL);
113 if (entry == NULL) { 112 if (entry == NULL) {
114 retval = -ENOMEM; 113 retval = -ENOMEM;
115 break; 114 break;
116 } 115 }
117 memset(entry, 0, sizeof(struct serverworks_page_map));
118 tables[i] = entry; 116 tables[i] = entry;
119 retval = serverworks_create_page_map(entry); 117 retval = serverworks_create_page_map(entry);
120 if (retval != 0) break; 118 if (retval != 0) break;
@@ -244,13 +242,27 @@ static int serverworks_fetch_size(void)
244 */ 242 */
245static void serverworks_tlbflush(struct agp_memory *temp) 243static void serverworks_tlbflush(struct agp_memory *temp)
246{ 244{
245 unsigned long timeout;
246
247 writeb(1, serverworks_private.registers+SVWRKS_POSTFLUSH); 247 writeb(1, serverworks_private.registers+SVWRKS_POSTFLUSH);
248 while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1) 248 timeout = jiffies + 3*HZ;
249 while (readb(serverworks_private.registers+SVWRKS_POSTFLUSH) == 1) {
249 cpu_relax(); 250 cpu_relax();
251 if (time_after(jiffies, timeout)) {
252 printk(KERN_ERR PFX "TLB post flush took more than 3 seconds\n");
253 break;
254 }
255 }
250 256
251 writel(1, serverworks_private.registers+SVWRKS_DIRFLUSH); 257 writel(1, serverworks_private.registers+SVWRKS_DIRFLUSH);
252 while(readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1) 258 timeout = jiffies + 3*HZ;
259 while (readl(serverworks_private.registers+SVWRKS_DIRFLUSH) == 1) {
253 cpu_relax(); 260 cpu_relax();
261 if (time_after(jiffies, timeout)) {
262 printk(KERN_ERR PFX "TLB Dir flush took more than 3 seconds\n");
263 break;
264 }
265 }
254} 266}
255 267
256static int serverworks_configure(void) 268static int serverworks_configure(void)
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index 406dea914635..c85a4fa60da7 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -345,17 +345,15 @@ static void con_release_unimap(struct uni_pagedir *p)
345 for (i = 0; i < 32; i++) { 345 for (i = 0; i < 32; i++) {
346 if ((p1 = p->uni_pgdir[i]) != NULL) { 346 if ((p1 = p->uni_pgdir[i]) != NULL) {
347 for (j = 0; j < 32; j++) 347 for (j = 0; j < 32; j++)
348 if (p1[j]) 348 kfree(p1[j]);
349 kfree(p1[j]);
350 kfree(p1); 349 kfree(p1);
351 } 350 }
352 p->uni_pgdir[i] = NULL; 351 p->uni_pgdir[i] = NULL;
353 } 352 }
354 for (i = 0; i < 4; i++) 353 for (i = 0; i < 4; i++) {
355 if (p->inverse_translations[i]) { 354 kfree(p->inverse_translations[i]);
356 kfree(p->inverse_translations[i]); 355 p->inverse_translations[i] = NULL;
357 p->inverse_translations[i] = NULL; 356 }
358 }
359} 357}
360 358
361void con_free_unimap(struct vc_data *vc) 359void con_free_unimap(struct vc_data *vc)
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index 6d3fec160bff..efff0eec618c 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -203,10 +203,10 @@ int drm_ati_pcigart_init(drm_device_t * dev, drm_ati_pcigart_info * gart_info)
203 203
204 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { 204 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
205 if (gart_info->is_pcie) 205 if (gart_info->is_pcie)
206 *pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc; 206 *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
207 else 207 else
208 *pci_gart = cpu_to_le32(page_base); 208 *pci_gart = cpu_to_le32(page_base);
209 *pci_gart++; 209 pci_gart++;
210 page_base += ATI_PCIGART_PAGE_SIZE; 210 page_base += ATI_PCIGART_PAGE_SIZE;
211 } 211 }
212 } 212 }
diff --git a/drivers/char/drm/ffb_context.c b/drivers/char/drm/ffb_context.c
index 8a6cc2751bc9..1383727b443a 100644
--- a/drivers/char/drm/ffb_context.c
+++ b/drivers/char/drm/ffb_context.c
@@ -526,10 +526,8 @@ int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
526 if (idx < 0 || idx >= FFB_MAX_CTXS) 526 if (idx < 0 || idx >= FFB_MAX_CTXS)
527 return -EINVAL; 527 return -EINVAL;
528 528
529 if (fpriv->hw_state[idx] != NULL) { 529 kfree(fpriv->hw_state[idx]);
530 kfree(fpriv->hw_state[idx]); 530 fpriv->hw_state[idx] = NULL;
531 fpriv->hw_state[idx] = NULL;
532 }
533 return 0; 531 return 0;
534} 532}
535 533
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
index 5c121d6df9f2..c13f9abb41e9 100644
--- a/drivers/char/drm/ffb_drv.c
+++ b/drivers/char/drm/ffb_drv.c
@@ -245,14 +245,12 @@ static void ffb_driver_release(drm_device_t * dev, struct file *filp)
245 245
246static void ffb_driver_pretakedown(drm_device_t * dev) 246static void ffb_driver_pretakedown(drm_device_t * dev)
247{ 247{
248 if (dev->dev_private) 248 kfree(dev->dev_private);
249 kfree(dev->dev_private);
250} 249}
251 250
252static int ffb_driver_postcleanup(drm_device_t * dev) 251static int ffb_driver_postcleanup(drm_device_t * dev)
253{ 252{
254 if (ffb_position != NULL) 253 kfree(ffb_position);
255 kfree(ffb_position);
256 return 0; 254 return 0;
257} 255}
258 256
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index b7a0e4d6b934..407708a001e4 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -3113,7 +3113,6 @@ MODULE_DEVICE_TABLE(pci, epca_pci_tbl);
3113int __init init_PCI (void) 3113int __init init_PCI (void)
3114{ /* Begin init_PCI */ 3114{ /* Begin init_PCI */
3115 memset (&epca_driver, 0, sizeof (epca_driver)); 3115 memset (&epca_driver, 0, sizeof (epca_driver));
3116 epca_driver.owner = THIS_MODULE;
3117 epca_driver.name = "epca"; 3116 epca_driver.name = "epca";
3118 epca_driver.id_table = epca_pci_tbl; 3117 epca_driver.id_table = epca_pci_tbl;
3119 epca_driver.probe = epca_init_one; 3118 epca_driver.probe = epca_init_one;
diff --git a/drivers/char/ip2.c b/drivers/char/ip2.c
index 6cd12f23aa58..7cadfc6ef352 100644
--- a/drivers/char/ip2.c
+++ b/drivers/char/ip2.c
@@ -7,7 +7,6 @@
7// 7//
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/version.h>
11#include <linux/init.h> 10#include <linux/init.h>
12#include <linux/wait.h> 11#include <linux/wait.h>
13 12
diff --git a/drivers/char/ip2/i2ellis.c b/drivers/char/ip2/i2ellis.c
index f834d05ccc97..dd761a1e4f08 100644
--- a/drivers/char/ip2/i2ellis.c
+++ b/drivers/char/ip2/i2ellis.c
@@ -106,9 +106,7 @@ iiEllisInit(void)
106static void 106static void
107iiEllisCleanup(void) 107iiEllisCleanup(void)
108{ 108{
109 if ( pDelayTimer != NULL ) { 109 kfree(pDelayTimer);
110 kfree ( pDelayTimer );
111 }
112} 110}
113 111
114//****************************************************************************** 112//******************************************************************************
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index 33862670e285..58dcdee1cd71 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -28,6 +28,8 @@
28 28
29#include <linux/kernel.h> /* For printk. */ 29#include <linux/kernel.h> /* For printk. */
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/module.h>
32#include <linux/moduleparam.h>
31#include <linux/ipmi_msgdefs.h> /* for completion codes */ 33#include <linux/ipmi_msgdefs.h> /* for completion codes */
32#include "ipmi_si_sm.h" 34#include "ipmi_si_sm.h"
33 35
@@ -36,6 +38,8 @@ static int bt_debug = 0x00; /* Production value 0, see following flags */
36#define BT_DEBUG_ENABLE 1 38#define BT_DEBUG_ENABLE 1
37#define BT_DEBUG_MSG 2 39#define BT_DEBUG_MSG 2
38#define BT_DEBUG_STATES 4 40#define BT_DEBUG_STATES 4
41module_param(bt_debug, int, 0644);
42MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
39 43
40/* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds, 44/* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
41 and 64 byte buffers. However, one HP implementation wants 255 bytes of 45 and 64 byte buffers. However, one HP implementation wants 255 bytes of
@@ -43,7 +47,7 @@ static int bt_debug = 0x00; /* Production value 0, see following flags */
43 Since the Open IPMI architecture is single-message oriented at this 47 Since the Open IPMI architecture is single-message oriented at this
44 stage, the queue depth of BT is of no concern. */ 48 stage, the queue depth of BT is of no concern. */
45 49
46#define BT_NORMAL_TIMEOUT 2000000 /* seconds in microseconds */ 50#define BT_NORMAL_TIMEOUT 5000000 /* seconds in microseconds */
47#define BT_RETRY_LIMIT 2 51#define BT_RETRY_LIMIT 2
48#define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */ 52#define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */
49 53
@@ -202,7 +206,7 @@ static int bt_get_result(struct si_sm_data *bt,
202 msg_len = bt->read_count - 2; /* account for length & seq */ 206 msg_len = bt->read_count - 2; /* account for length & seq */
203 /* Always NetFn, Cmd, cCode */ 207 /* Always NetFn, Cmd, cCode */
204 if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) { 208 if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
205 printk(KERN_WARNING "BT results: bad msg_len = %d\n", msg_len); 209 printk(KERN_DEBUG "BT results: bad msg_len = %d\n", msg_len);
206 data[0] = bt->write_data[1] | 0x4; /* Kludge a response */ 210 data[0] = bt->write_data[1] | 0x4; /* Kludge a response */
207 data[1] = bt->write_data[3]; 211 data[1] = bt->write_data[3];
208 data[2] = IPMI_ERR_UNSPECIFIED; 212 data[2] = IPMI_ERR_UNSPECIFIED;
@@ -240,7 +244,7 @@ static void reset_flags(struct si_sm_data *bt)
240 BT_CONTROL(BT_B_BUSY); 244 BT_CONTROL(BT_B_BUSY);
241 BT_CONTROL(BT_CLR_WR_PTR); 245 BT_CONTROL(BT_CLR_WR_PTR);
242 BT_CONTROL(BT_SMS_ATN); 246 BT_CONTROL(BT_SMS_ATN);
243#ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION 247
244 if (BT_STATUS & BT_B2H_ATN) { 248 if (BT_STATUS & BT_B2H_ATN) {
245 int i; 249 int i;
246 BT_CONTROL(BT_H_BUSY); 250 BT_CONTROL(BT_H_BUSY);
@@ -250,7 +254,6 @@ static void reset_flags(struct si_sm_data *bt)
250 BMC2HOST; 254 BMC2HOST;
251 BT_CONTROL(BT_H_BUSY); 255 BT_CONTROL(BT_H_BUSY);
252 } 256 }
253#endif
254} 257}
255 258
256static inline void write_all_bytes(struct si_sm_data *bt) 259static inline void write_all_bytes(struct si_sm_data *bt)
@@ -295,7 +298,7 @@ static inline int read_all_bytes(struct si_sm_data *bt)
295 printk ("\n"); 298 printk ("\n");
296 } 299 }
297 if (bt->seq != bt->write_data[2]) /* idiot check */ 300 if (bt->seq != bt->write_data[2]) /* idiot check */
298 printk(KERN_WARNING "BT: internal error: sequence mismatch\n"); 301 printk(KERN_DEBUG "BT: internal error: sequence mismatch\n");
299 302
300 /* per the spec, the (NetFn, Seq, Cmd) tuples should match */ 303 /* per the spec, the (NetFn, Seq, Cmd) tuples should match */
301 if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */ 304 if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */
@@ -321,18 +324,17 @@ static void error_recovery(struct si_sm_data *bt, char *reason)
321 bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */ 324 bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
322 325
323 status = BT_STATUS; 326 status = BT_STATUS;
324 printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT, 327 printk(KERN_DEBUG "BT: %s in %s %s\n", reason, STATE2TXT,
325 STATUS2TXT(buf)); 328 STATUS2TXT(buf));
326 329
327 (bt->error_retries)++; 330 (bt->error_retries)++;
328 if (bt->error_retries > BT_RETRY_LIMIT) { 331 if (bt->error_retries > BT_RETRY_LIMIT) {
329 printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT); 332 printk(KERN_DEBUG "retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
330 bt->state = BT_STATE_HOSED; 333 bt->state = BT_STATE_HOSED;
331 if (!bt->nonzero_status) 334 if (!bt->nonzero_status)
332 printk(KERN_ERR "IPMI: BT stuck, try power cycle\n"); 335 printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
333 else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) { 336 else if (bt->error_retries <= BT_RETRY_LIMIT + 1) {
334 /* most likely during insmod */ 337 printk(KERN_DEBUG "IPMI: BT reset (takes 5 secs)\n");
335 printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
336 bt->state = BT_STATE_RESET1; 338 bt->state = BT_STATE_RESET1;
337 } 339 }
338 return; 340 return;
@@ -340,11 +342,11 @@ static void error_recovery(struct si_sm_data *bt, char *reason)
340 342
341 /* Sometimes the BMC queues get in an "off-by-one" state...*/ 343 /* Sometimes the BMC queues get in an "off-by-one" state...*/
342 if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) { 344 if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
343 printk("retry B2H_WAIT\n"); 345 printk(KERN_DEBUG "retry B2H_WAIT\n");
344 return; 346 return;
345 } 347 }
346 348
347 printk("restart command\n"); 349 printk(KERN_DEBUG "restart command\n");
348 bt->state = BT_STATE_RESTART; 350 bt->state = BT_STATE_RESTART;
349} 351}
350 352
@@ -372,17 +374,6 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
372 return SI_SM_HOSED; 374 return SI_SM_HOSED;
373 375
374 if (bt->state != BT_STATE_IDLE) { /* do timeout test */ 376 if (bt->state != BT_STATE_IDLE) { /* do timeout test */
375
376 /* Certain states, on error conditions, can lock up a CPU
377 because they are effectively in an infinite loop with
378 CALL_WITHOUT_DELAY (right back here with time == 0).
379 Prevent infinite lockup by ALWAYS decrementing timeout. */
380
381 /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
382 (noticed in ipmi_smic_sm.c January 2004) */
383
384 if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT))
385 time = 100;
386 bt->timeout -= time; 377 bt->timeout -= time;
387 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) { 378 if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
388 error_recovery(bt, "timed out"); 379 error_recovery(bt, "timed out");
@@ -483,6 +474,7 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
483 break; 474 break;
484 475
485 case BT_STATE_RESTART: /* don't reset retries! */ 476 case BT_STATE_RESTART: /* don't reset retries! */
477 reset_flags(bt);
486 bt->write_data[2] = ++bt->seq; 478 bt->write_data[2] = ++bt->seq;
487 bt->read_count = 0; 479 bt->read_count = 0;
488 bt->nonzero_status = 0; 480 bt->nonzero_status = 0;
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index d21853a594a3..da1554194d3d 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -38,16 +38,25 @@
38 */ 38 */
39 39
40#include <linux/kernel.h> /* For printk. */ 40#include <linux/kernel.h> /* For printk. */
41#include <linux/module.h>
42#include <linux/moduleparam.h>
41#include <linux/string.h> 43#include <linux/string.h>
44#include <linux/jiffies.h>
42#include <linux/ipmi_msgdefs.h> /* for completion codes */ 45#include <linux/ipmi_msgdefs.h> /* for completion codes */
43#include "ipmi_si_sm.h" 46#include "ipmi_si_sm.h"
44 47
45/* Set this if you want a printout of why the state machine was hosed 48/* kcs_debug is a bit-field
46 when it gets hosed. */ 49 * KCS_DEBUG_ENABLE - turned on for now
47#define DEBUG_HOSED_REASON 50 * KCS_DEBUG_MSG - commands and their responses
51 * KCS_DEBUG_STATES - state machine
52 */
53#define KCS_DEBUG_STATES 4
54#define KCS_DEBUG_MSG 2
55#define KCS_DEBUG_ENABLE 1
48 56
49/* Print the state machine state on entry every time. */ 57static int kcs_debug;
50#undef DEBUG_STATE 58module_param(kcs_debug, int, 0644);
59MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
51 60
52/* The states the KCS driver may be in. */ 61/* The states the KCS driver may be in. */
53enum kcs_states { 62enum kcs_states {
@@ -91,6 +100,7 @@ enum kcs_states {
91#define IBF_RETRY_TIMEOUT 1000000 100#define IBF_RETRY_TIMEOUT 1000000
92#define OBF_RETRY_TIMEOUT 1000000 101#define OBF_RETRY_TIMEOUT 1000000
93#define MAX_ERROR_RETRIES 10 102#define MAX_ERROR_RETRIES 10
103#define ERROR0_OBF_WAIT_JIFFIES (2*HZ)
94 104
95struct si_sm_data 105struct si_sm_data
96{ 106{
@@ -107,6 +117,7 @@ struct si_sm_data
107 unsigned int error_retries; 117 unsigned int error_retries;
108 long ibf_timeout; 118 long ibf_timeout;
109 long obf_timeout; 119 long obf_timeout;
120 unsigned long error0_timeout;
110}; 121};
111 122
112static unsigned int init_kcs_data(struct si_sm_data *kcs, 123static unsigned int init_kcs_data(struct si_sm_data *kcs,
@@ -175,11 +186,11 @@ static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
175{ 186{
176 (kcs->error_retries)++; 187 (kcs->error_retries)++;
177 if (kcs->error_retries > MAX_ERROR_RETRIES) { 188 if (kcs->error_retries > MAX_ERROR_RETRIES) {
178#ifdef DEBUG_HOSED_REASON 189 if (kcs_debug & KCS_DEBUG_ENABLE)
179 printk("ipmi_kcs_sm: kcs hosed: %s\n", reason); 190 printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n", reason);
180#endif
181 kcs->state = KCS_HOSED; 191 kcs->state = KCS_HOSED;
182 } else { 192 } else {
193 kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES;
183 kcs->state = KCS_ERROR0; 194 kcs->state = KCS_ERROR0;
184 } 195 }
185} 196}
@@ -248,14 +259,21 @@ static void restart_kcs_transaction(struct si_sm_data *kcs)
248static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data, 259static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
249 unsigned int size) 260 unsigned int size)
250{ 261{
262 unsigned int i;
263
251 if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) { 264 if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
252 return -1; 265 return -1;
253 } 266 }
254
255 if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) { 267 if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
256 return -2; 268 return -2;
257 } 269 }
258 270 if (kcs_debug & KCS_DEBUG_MSG) {
271 printk(KERN_DEBUG "start_kcs_transaction -");
272 for (i = 0; i < size; i ++) {
273 printk(" %02x", (unsigned char) (data [i]));
274 }
275 printk ("\n");
276 }
259 kcs->error_retries = 0; 277 kcs->error_retries = 0;
260 memcpy(kcs->write_data, data, size); 278 memcpy(kcs->write_data, data, size);
261 kcs->write_count = size; 279 kcs->write_count = size;
@@ -305,9 +323,9 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
305 323
306 status = read_status(kcs); 324 status = read_status(kcs);
307 325
308#ifdef DEBUG_STATE 326 if (kcs_debug & KCS_DEBUG_STATES)
309 printk(" State = %d, %x\n", kcs->state, status); 327 printk(KERN_DEBUG "KCS: State = %d, %x\n", kcs->state, status);
310#endif 328
311 /* All states wait for ibf, so just do it here. */ 329 /* All states wait for ibf, so just do it here. */
312 if (!check_ibf(kcs, status, time)) 330 if (!check_ibf(kcs, status, time))
313 return SI_SM_CALL_WITH_DELAY; 331 return SI_SM_CALL_WITH_DELAY;
@@ -409,6 +427,10 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
409 427
410 case KCS_ERROR0: 428 case KCS_ERROR0:
411 clear_obf(kcs, status); 429 clear_obf(kcs, status);
430 status = read_status(kcs);
431 if (GET_STATUS_OBF(status)) /* controller isn't responding */
432 if (time_before(jiffies, kcs->error0_timeout))
433 return SI_SM_CALL_WITH_TICK_DELAY;
412 write_cmd(kcs, KCS_GET_STATUS_ABORT); 434 write_cmd(kcs, KCS_GET_STATUS_ABORT);
413 kcs->state = KCS_ERROR1; 435 kcs->state = KCS_ERROR1;
414 break; 436 break;
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 32fa82c78c73..c1d06ba449b6 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -38,13 +38,13 @@
38#include <linux/sched.h> 38#include <linux/sched.h>
39#include <linux/poll.h> 39#include <linux/poll.h>
40#include <linux/spinlock.h> 40#include <linux/spinlock.h>
41#include <linux/rwsem.h>
42#include <linux/slab.h> 41#include <linux/slab.h>
43#include <linux/ipmi.h> 42#include <linux/ipmi.h>
44#include <linux/ipmi_smi.h> 43#include <linux/ipmi_smi.h>
45#include <linux/notifier.h> 44#include <linux/notifier.h>
46#include <linux/init.h> 45#include <linux/init.h>
47#include <linux/proc_fs.h> 46#include <linux/proc_fs.h>
47#include <linux/rcupdate.h>
48 48
49#define PFX "IPMI message handler: " 49#define PFX "IPMI message handler: "
50 50
@@ -65,10 +65,19 @@ struct proc_dir_entry *proc_ipmi_root = NULL;
65 the max message timer. This is in milliseconds. */ 65 the max message timer. This is in milliseconds. */
66#define MAX_MSG_TIMEOUT 60000 66#define MAX_MSG_TIMEOUT 60000
67 67
68
69/*
70 * The main "user" data structure.
71 */
68struct ipmi_user 72struct ipmi_user
69{ 73{
70 struct list_head link; 74 struct list_head link;
71 75
76 /* Set to "0" when the user is destroyed. */
77 int valid;
78
79 struct kref refcount;
80
72 /* The upper layer that handles receive messages. */ 81 /* The upper layer that handles receive messages. */
73 struct ipmi_user_hndl *handler; 82 struct ipmi_user_hndl *handler;
74 void *handler_data; 83 void *handler_data;
@@ -87,6 +96,15 @@ struct cmd_rcvr
87 ipmi_user_t user; 96 ipmi_user_t user;
88 unsigned char netfn; 97 unsigned char netfn;
89 unsigned char cmd; 98 unsigned char cmd;
99
100 /*
101 * This is used to form a linked lised during mass deletion.
102 * Since this is in an RCU list, we cannot use the link above
103 * or change any data until the RCU period completes. So we
104 * use this next variable during mass deletion so we can have
105 * a list and don't have to wait and restart the search on
106 * every individual deletion of a command. */
107 struct cmd_rcvr *next;
90}; 108};
91 109
92struct seq_table 110struct seq_table
@@ -150,13 +168,11 @@ struct ipmi_smi
150 /* What interface number are we? */ 168 /* What interface number are we? */
151 int intf_num; 169 int intf_num;
152 170
153 /* The list of upper layers that are using me. We read-lock 171 struct kref refcount;
154 this when delivering messages to the upper layer to keep 172
155 the user from going away while we are processing the 173 /* The list of upper layers that are using me. seq_lock
156 message. This means that you cannot add or delete a user 174 * protects this. */
157 from the receive callback. */ 175 struct list_head users;
158 rwlock_t users_lock;
159 struct list_head users;
160 176
161 /* Used for wake ups at startup. */ 177 /* Used for wake ups at startup. */
162 wait_queue_head_t waitq; 178 wait_queue_head_t waitq;
@@ -193,7 +209,7 @@ struct ipmi_smi
193 209
194 /* The list of command receivers that are registered for commands 210 /* The list of command receivers that are registered for commands
195 on this interface. */ 211 on this interface. */
196 rwlock_t cmd_rcvr_lock; 212 struct semaphore cmd_rcvrs_lock;
197 struct list_head cmd_rcvrs; 213 struct list_head cmd_rcvrs;
198 214
199 /* Events that were queues because no one was there to receive 215 /* Events that were queues because no one was there to receive
@@ -296,16 +312,17 @@ struct ipmi_smi
296 unsigned int events; 312 unsigned int events;
297}; 313};
298 314
315/* Used to mark an interface entry that cannot be used but is not a
316 * free entry, either, primarily used at creation and deletion time so
317 * a slot doesn't get reused too quickly. */
318#define IPMI_INVALID_INTERFACE_ENTRY ((ipmi_smi_t) ((long) 1))
319#define IPMI_INVALID_INTERFACE(i) (((i) == NULL) \
320 || (i == IPMI_INVALID_INTERFACE_ENTRY))
321
299#define MAX_IPMI_INTERFACES 4 322#define MAX_IPMI_INTERFACES 4
300static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES]; 323static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES];
301 324
302/* Used to keep interfaces from going away while operations are 325/* Directly protects the ipmi_interfaces data structure. */
303 operating on interfaces. Grab read if you are not modifying the
304 interfaces, write if you are. */
305static DECLARE_RWSEM(interfaces_sem);
306
307/* Directly protects the ipmi_interfaces data structure. This is
308 claimed in the timer interrupt. */
309static DEFINE_SPINLOCK(interfaces_lock); 326static DEFINE_SPINLOCK(interfaces_lock);
310 327
311/* List of watchers that want to know when smi's are added and 328/* List of watchers that want to know when smi's are added and
@@ -313,20 +330,72 @@ static DEFINE_SPINLOCK(interfaces_lock);
313static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers); 330static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers);
314static DECLARE_RWSEM(smi_watchers_sem); 331static DECLARE_RWSEM(smi_watchers_sem);
315 332
333
334static void free_recv_msg_list(struct list_head *q)
335{
336 struct ipmi_recv_msg *msg, *msg2;
337
338 list_for_each_entry_safe(msg, msg2, q, link) {
339 list_del(&msg->link);
340 ipmi_free_recv_msg(msg);
341 }
342}
343
344static void clean_up_interface_data(ipmi_smi_t intf)
345{
346 int i;
347 struct cmd_rcvr *rcvr, *rcvr2;
348 struct list_head list;
349
350 free_recv_msg_list(&intf->waiting_msgs);
351 free_recv_msg_list(&intf->waiting_events);
352
353 /* Wholesale remove all the entries from the list in the
354 * interface and wait for RCU to know that none are in use. */
355 down(&intf->cmd_rcvrs_lock);
356 list_add_rcu(&list, &intf->cmd_rcvrs);
357 list_del_rcu(&intf->cmd_rcvrs);
358 up(&intf->cmd_rcvrs_lock);
359 synchronize_rcu();
360
361 list_for_each_entry_safe(rcvr, rcvr2, &list, link)
362 kfree(rcvr);
363
364 for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
365 if ((intf->seq_table[i].inuse)
366 && (intf->seq_table[i].recv_msg))
367 {
368 ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
369 }
370 }
371}
372
373static void intf_free(struct kref *ref)
374{
375 ipmi_smi_t intf = container_of(ref, struct ipmi_smi, refcount);
376
377 clean_up_interface_data(intf);
378 kfree(intf);
379}
380
316int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) 381int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
317{ 382{
318 int i; 383 int i;
384 unsigned long flags;
319 385
320 down_read(&interfaces_sem);
321 down_write(&smi_watchers_sem); 386 down_write(&smi_watchers_sem);
322 list_add(&(watcher->link), &smi_watchers); 387 list_add(&(watcher->link), &smi_watchers);
388 up_write(&smi_watchers_sem);
389 spin_lock_irqsave(&interfaces_lock, flags);
323 for (i = 0; i < MAX_IPMI_INTERFACES; i++) { 390 for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
324 if (ipmi_interfaces[i] != NULL) { 391 ipmi_smi_t intf = ipmi_interfaces[i];
325 watcher->new_smi(i); 392 if (IPMI_INVALID_INTERFACE(intf))
326 } 393 continue;
394 spin_unlock_irqrestore(&interfaces_lock, flags);
395 watcher->new_smi(i);
396 spin_lock_irqsave(&interfaces_lock, flags);
327 } 397 }
328 up_write(&smi_watchers_sem); 398 spin_unlock_irqrestore(&interfaces_lock, flags);
329 up_read(&interfaces_sem);
330 return 0; 399 return 0;
331} 400}
332 401
@@ -471,8 +540,8 @@ static void deliver_response(struct ipmi_recv_msg *msg)
471 } 540 }
472 ipmi_free_recv_msg(msg); 541 ipmi_free_recv_msg(msg);
473 } else { 542 } else {
474 msg->user->handler->ipmi_recv_hndl(msg, 543 ipmi_user_t user = msg->user;
475 msg->user->handler_data); 544 user->handler->ipmi_recv_hndl(msg, user->handler_data);
476 } 545 }
477} 546}
478 547
@@ -662,15 +731,18 @@ int ipmi_create_user(unsigned int if_num,
662 if (! new_user) 731 if (! new_user)
663 return -ENOMEM; 732 return -ENOMEM;
664 733
665 down_read(&interfaces_sem); 734 spin_lock_irqsave(&interfaces_lock, flags);
666 if ((if_num >= MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL) 735 intf = ipmi_interfaces[if_num];
667 { 736 if ((if_num >= MAX_IPMI_INTERFACES) || IPMI_INVALID_INTERFACE(intf)) {
668 rv = -EINVAL; 737 spin_unlock_irqrestore(&interfaces_lock, flags);
669 goto out_unlock; 738 return -EINVAL;
670 } 739 }
671 740
672 intf = ipmi_interfaces[if_num]; 741 /* Note that each existing user holds a refcount to the interface. */
742 kref_get(&intf->refcount);
743 spin_unlock_irqrestore(&interfaces_lock, flags);
673 744
745 kref_init(&new_user->refcount);
674 new_user->handler = handler; 746 new_user->handler = handler;
675 new_user->handler_data = handler_data; 747 new_user->handler_data = handler_data;
676 new_user->intf = intf; 748 new_user->intf = intf;
@@ -678,98 +750,92 @@ int ipmi_create_user(unsigned int if_num,
678 750
679 if (!try_module_get(intf->handlers->owner)) { 751 if (!try_module_get(intf->handlers->owner)) {
680 rv = -ENODEV; 752 rv = -ENODEV;
681 goto out_unlock; 753 goto out_err;
682 } 754 }
683 755
684 if (intf->handlers->inc_usecount) { 756 if (intf->handlers->inc_usecount) {
685 rv = intf->handlers->inc_usecount(intf->send_info); 757 rv = intf->handlers->inc_usecount(intf->send_info);
686 if (rv) { 758 if (rv) {
687 module_put(intf->handlers->owner); 759 module_put(intf->handlers->owner);
688 goto out_unlock; 760 goto out_err;
689 } 761 }
690 } 762 }
691 763
692 write_lock_irqsave(&intf->users_lock, flags); 764 new_user->valid = 1;
693 list_add_tail(&new_user->link, &intf->users); 765 spin_lock_irqsave(&intf->seq_lock, flags);
694 write_unlock_irqrestore(&intf->users_lock, flags); 766 list_add_rcu(&new_user->link, &intf->users);
695 767 spin_unlock_irqrestore(&intf->seq_lock, flags);
696 out_unlock: 768 *user = new_user;
697 if (rv) { 769 return 0;
698 kfree(new_user);
699 } else {
700 *user = new_user;
701 }
702 770
703 up_read(&interfaces_sem); 771 out_err:
772 kfree(new_user);
773 kref_put(&intf->refcount, intf_free);
704 return rv; 774 return rv;
705} 775}
706 776
707static int ipmi_destroy_user_nolock(ipmi_user_t user) 777static void free_user(struct kref *ref)
778{
779 ipmi_user_t user = container_of(ref, struct ipmi_user, refcount);
780 kfree(user);
781}
782
783int ipmi_destroy_user(ipmi_user_t user)
708{ 784{
709 int rv = -ENODEV; 785 int rv = -ENODEV;
710 ipmi_user_t t_user; 786 ipmi_smi_t intf = user->intf;
711 struct cmd_rcvr *rcvr, *rcvr2;
712 int i; 787 int i;
713 unsigned long flags; 788 unsigned long flags;
789 struct cmd_rcvr *rcvr;
790 struct list_head *entry1, *entry2;
791 struct cmd_rcvr *rcvrs = NULL;
714 792
715 /* Find the user and delete them from the list. */ 793 user->valid = 1;
716 list_for_each_entry(t_user, &(user->intf->users), link) {
717 if (t_user == user) {
718 list_del(&t_user->link);
719 rv = 0;
720 break;
721 }
722 }
723 794
724 if (rv) { 795 /* Remove the user from the interface's sequence table. */
725 goto out_unlock; 796 spin_lock_irqsave(&intf->seq_lock, flags);
726 } 797 list_del_rcu(&user->link);
727 798
728 /* Remove the user from the interfaces sequence table. */
729 spin_lock_irqsave(&(user->intf->seq_lock), flags);
730 for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) { 799 for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
731 if (user->intf->seq_table[i].inuse 800 if (intf->seq_table[i].inuse
732 && (user->intf->seq_table[i].recv_msg->user == user)) 801 && (intf->seq_table[i].recv_msg->user == user))
733 { 802 {
734 user->intf->seq_table[i].inuse = 0; 803 intf->seq_table[i].inuse = 0;
735 } 804 }
736 } 805 }
737 spin_unlock_irqrestore(&(user->intf->seq_lock), flags); 806 spin_unlock_irqrestore(&intf->seq_lock, flags);
738 807
739 /* Remove the user from the command receiver's table. */ 808 /*
740 write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags); 809 * Remove the user from the command receiver's table. First
741 list_for_each_entry_safe(rcvr, rcvr2, &(user->intf->cmd_rcvrs), link) { 810 * we build a list of everything (not using the standard link,
811 * since other things may be using it till we do
812 * synchronize_rcu()) then free everything in that list.
813 */
814 down(&intf->cmd_rcvrs_lock);
815 list_for_each_safe_rcu(entry1, entry2, &intf->cmd_rcvrs) {
816 rcvr = list_entry(entry1, struct cmd_rcvr, link);
742 if (rcvr->user == user) { 817 if (rcvr->user == user) {
743 list_del(&rcvr->link); 818 list_del_rcu(&rcvr->link);
744 kfree(rcvr); 819 rcvr->next = rcvrs;
820 rcvrs = rcvr;
745 } 821 }
746 } 822 }
747 write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags); 823 up(&intf->cmd_rcvrs_lock);
824 synchronize_rcu();
825 while (rcvrs) {
826 rcvr = rcvrs;
827 rcvrs = rcvr->next;
828 kfree(rcvr);
829 }
748 830
749 kfree(user); 831 module_put(intf->handlers->owner);
832 if (intf->handlers->dec_usecount)
833 intf->handlers->dec_usecount(intf->send_info);
750 834
751 out_unlock: 835 kref_put(&intf->refcount, intf_free);
752 836
753 return rv; 837 kref_put(&user->refcount, free_user);
754}
755
756int ipmi_destroy_user(ipmi_user_t user)
757{
758 int rv;
759 ipmi_smi_t intf = user->intf;
760 unsigned long flags;
761 838
762 down_read(&interfaces_sem);
763 write_lock_irqsave(&intf->users_lock, flags);
764 rv = ipmi_destroy_user_nolock(user);
765 if (!rv) {
766 module_put(intf->handlers->owner);
767 if (intf->handlers->dec_usecount)
768 intf->handlers->dec_usecount(intf->send_info);
769 }
770
771 write_unlock_irqrestore(&intf->users_lock, flags);
772 up_read(&interfaces_sem);
773 return rv; 839 return rv;
774} 840}
775 841
@@ -823,62 +889,78 @@ int ipmi_get_my_LUN(ipmi_user_t user,
823 889
824int ipmi_set_gets_events(ipmi_user_t user, int val) 890int ipmi_set_gets_events(ipmi_user_t user, int val)
825{ 891{
826 unsigned long flags; 892 unsigned long flags;
827 struct ipmi_recv_msg *msg, *msg2; 893 ipmi_smi_t intf = user->intf;
894 struct ipmi_recv_msg *msg, *msg2;
895 struct list_head msgs;
828 896
829 read_lock(&(user->intf->users_lock)); 897 INIT_LIST_HEAD(&msgs);
830 spin_lock_irqsave(&(user->intf->events_lock), flags); 898
899 spin_lock_irqsave(&intf->events_lock, flags);
831 user->gets_events = val; 900 user->gets_events = val;
832 901
833 if (val) { 902 if (val) {
834 /* Deliver any queued events. */ 903 /* Deliver any queued events. */
835 list_for_each_entry_safe(msg, msg2, &(user->intf->waiting_events), link) { 904 list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) {
836 list_del(&msg->link); 905 list_del(&msg->link);
837 msg->user = user; 906 list_add_tail(&msg->link, &msgs);
838 deliver_response(msg);
839 } 907 }
840 } 908 }
841 909
842 spin_unlock_irqrestore(&(user->intf->events_lock), flags); 910 /* Hold the events lock while doing this to preserve order. */
843 read_unlock(&(user->intf->users_lock)); 911 list_for_each_entry_safe(msg, msg2, &msgs, link) {
912 msg->user = user;
913 kref_get(&user->refcount);
914 deliver_response(msg);
915 }
916
917 spin_unlock_irqrestore(&intf->events_lock, flags);
844 918
845 return 0; 919 return 0;
846} 920}
847 921
922static struct cmd_rcvr *find_cmd_rcvr(ipmi_smi_t intf,
923 unsigned char netfn,
924 unsigned char cmd)
925{
926 struct cmd_rcvr *rcvr;
927
928 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
929 if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd))
930 return rcvr;
931 }
932 return NULL;
933}
934
848int ipmi_register_for_cmd(ipmi_user_t user, 935int ipmi_register_for_cmd(ipmi_user_t user,
849 unsigned char netfn, 936 unsigned char netfn,
850 unsigned char cmd) 937 unsigned char cmd)
851{ 938{
852 struct cmd_rcvr *cmp; 939 ipmi_smi_t intf = user->intf;
853 unsigned long flags; 940 struct cmd_rcvr *rcvr;
854 struct cmd_rcvr *rcvr; 941 struct cmd_rcvr *entry;
855 int rv = 0; 942 int rv = 0;
856 943
857 944
858 rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); 945 rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
859 if (! rcvr) 946 if (! rcvr)
860 return -ENOMEM; 947 return -ENOMEM;
948 rcvr->cmd = cmd;
949 rcvr->netfn = netfn;
950 rcvr->user = user;
861 951
862 read_lock(&(user->intf->users_lock)); 952 down(&intf->cmd_rcvrs_lock);
863 write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
864 /* Make sure the command/netfn is not already registered. */ 953 /* Make sure the command/netfn is not already registered. */
865 list_for_each_entry(cmp, &(user->intf->cmd_rcvrs), link) { 954 entry = find_cmd_rcvr(intf, netfn, cmd);
866 if ((cmp->netfn == netfn) && (cmp->cmd == cmd)) { 955 if (entry) {
867 rv = -EBUSY; 956 rv = -EBUSY;
868 break; 957 goto out_unlock;
869 }
870 }
871
872 if (! rv) {
873 rcvr->cmd = cmd;
874 rcvr->netfn = netfn;
875 rcvr->user = user;
876 list_add_tail(&(rcvr->link), &(user->intf->cmd_rcvrs));
877 } 958 }
878 959
879 write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags); 960 list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
880 read_unlock(&(user->intf->users_lock));
881 961
962 out_unlock:
963 up(&intf->cmd_rcvrs_lock);
882 if (rv) 964 if (rv)
883 kfree(rcvr); 965 kfree(rcvr);
884 966
@@ -889,31 +971,28 @@ int ipmi_unregister_for_cmd(ipmi_user_t user,
889 unsigned char netfn, 971 unsigned char netfn,
890 unsigned char cmd) 972 unsigned char cmd)
891{ 973{
892 unsigned long flags; 974 ipmi_smi_t intf = user->intf;
893 struct cmd_rcvr *rcvr; 975 struct cmd_rcvr *rcvr;
894 int rv = -ENOENT;
895 976
896 read_lock(&(user->intf->users_lock)); 977 down(&intf->cmd_rcvrs_lock);
897 write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
898 /* Make sure the command/netfn is not already registered. */ 978 /* Make sure the command/netfn is not already registered. */
899 list_for_each_entry(rcvr, &(user->intf->cmd_rcvrs), link) { 979 rcvr = find_cmd_rcvr(intf, netfn, cmd);
900 if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) { 980 if ((rcvr) && (rcvr->user == user)) {
901 rv = 0; 981 list_del_rcu(&rcvr->link);
902 list_del(&rcvr->link); 982 up(&intf->cmd_rcvrs_lock);
903 kfree(rcvr); 983 synchronize_rcu();
904 break; 984 kfree(rcvr);
905 } 985 return 0;
986 } else {
987 up(&intf->cmd_rcvrs_lock);
988 return -ENOENT;
906 } 989 }
907 write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
908 read_unlock(&(user->intf->users_lock));
909
910 return rv;
911} 990}
912 991
913void ipmi_user_set_run_to_completion(ipmi_user_t user, int val) 992void ipmi_user_set_run_to_completion(ipmi_user_t user, int val)
914{ 993{
915 user->intf->handlers->set_run_to_completion(user->intf->send_info, 994 ipmi_smi_t intf = user->intf;
916 val); 995 intf->handlers->set_run_to_completion(intf->send_info, val);
917} 996}
918 997
919static unsigned char 998static unsigned char
@@ -1010,19 +1089,19 @@ static inline void format_lan_msg(struct ipmi_smi_msg *smi_msg,
1010 supplied in certain circumstances (mainly at panic time). If 1089 supplied in certain circumstances (mainly at panic time). If
1011 messages are supplied, they will be freed, even if an error 1090 messages are supplied, they will be freed, even if an error
1012 occurs. */ 1091 occurs. */
1013static inline int i_ipmi_request(ipmi_user_t user, 1092static int i_ipmi_request(ipmi_user_t user,
1014 ipmi_smi_t intf, 1093 ipmi_smi_t intf,
1015 struct ipmi_addr *addr, 1094 struct ipmi_addr *addr,
1016 long msgid, 1095 long msgid,
1017 struct kernel_ipmi_msg *msg, 1096 struct kernel_ipmi_msg *msg,
1018 void *user_msg_data, 1097 void *user_msg_data,
1019 void *supplied_smi, 1098 void *supplied_smi,
1020 struct ipmi_recv_msg *supplied_recv, 1099 struct ipmi_recv_msg *supplied_recv,
1021 int priority, 1100 int priority,
1022 unsigned char source_address, 1101 unsigned char source_address,
1023 unsigned char source_lun, 1102 unsigned char source_lun,
1024 int retries, 1103 int retries,
1025 unsigned int retry_time_ms) 1104 unsigned int retry_time_ms)
1026{ 1105{
1027 int rv = 0; 1106 int rv = 0;
1028 struct ipmi_smi_msg *smi_msg; 1107 struct ipmi_smi_msg *smi_msg;
@@ -1051,6 +1130,8 @@ static inline int i_ipmi_request(ipmi_user_t user,
1051 } 1130 }
1052 1131
1053 recv_msg->user = user; 1132 recv_msg->user = user;
1133 if (user)
1134 kref_get(&user->refcount);
1054 recv_msg->msgid = msgid; 1135 recv_msg->msgid = msgid;
1055 /* Store the message to send in the receive message so timeout 1136 /* Store the message to send in the receive message so timeout
1056 responses can get the proper response data. */ 1137 responses can get the proper response data. */
@@ -1725,11 +1806,11 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
1725 unsigned char version_major, 1806 unsigned char version_major,
1726 unsigned char version_minor, 1807 unsigned char version_minor,
1727 unsigned char slave_addr, 1808 unsigned char slave_addr,
1728 ipmi_smi_t *intf) 1809 ipmi_smi_t *new_intf)
1729{ 1810{
1730 int i, j; 1811 int i, j;
1731 int rv; 1812 int rv;
1732 ipmi_smi_t new_intf; 1813 ipmi_smi_t intf;
1733 unsigned long flags; 1814 unsigned long flags;
1734 1815
1735 1816
@@ -1745,189 +1826,142 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
1745 return -ENODEV; 1826 return -ENODEV;
1746 } 1827 }
1747 1828
1748 new_intf = kmalloc(sizeof(*new_intf), GFP_KERNEL); 1829 intf = kmalloc(sizeof(*intf), GFP_KERNEL);
1749 if (!new_intf) 1830 if (!intf)
1750 return -ENOMEM; 1831 return -ENOMEM;
1751 memset(new_intf, 0, sizeof(*new_intf)); 1832 memset(intf, 0, sizeof(*intf));
1752 1833 intf->intf_num = -1;
1753 new_intf->proc_dir = NULL; 1834 kref_init(&intf->refcount);
1835 intf->version_major = version_major;
1836 intf->version_minor = version_minor;
1837 for (j = 0; j < IPMI_MAX_CHANNELS; j++) {
1838 intf->channels[j].address = IPMI_BMC_SLAVE_ADDR;
1839 intf->channels[j].lun = 2;
1840 }
1841 if (slave_addr != 0)
1842 intf->channels[0].address = slave_addr;
1843 INIT_LIST_HEAD(&intf->users);
1844 intf->handlers = handlers;
1845 intf->send_info = send_info;
1846 spin_lock_init(&intf->seq_lock);
1847 for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
1848 intf->seq_table[j].inuse = 0;
1849 intf->seq_table[j].seqid = 0;
1850 }
1851 intf->curr_seq = 0;
1852#ifdef CONFIG_PROC_FS
1853 spin_lock_init(&intf->proc_entry_lock);
1854#endif
1855 spin_lock_init(&intf->waiting_msgs_lock);
1856 INIT_LIST_HEAD(&intf->waiting_msgs);
1857 spin_lock_init(&intf->events_lock);
1858 INIT_LIST_HEAD(&intf->waiting_events);
1859 intf->waiting_events_count = 0;
1860 init_MUTEX(&intf->cmd_rcvrs_lock);
1861 INIT_LIST_HEAD(&intf->cmd_rcvrs);
1862 init_waitqueue_head(&intf->waitq);
1863
1864 spin_lock_init(&intf->counter_lock);
1865 intf->proc_dir = NULL;
1754 1866
1755 rv = -ENOMEM; 1867 rv = -ENOMEM;
1756 1868 spin_lock_irqsave(&interfaces_lock, flags);
1757 down_write(&interfaces_sem);
1758 for (i = 0; i < MAX_IPMI_INTERFACES; i++) { 1869 for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
1759 if (ipmi_interfaces[i] == NULL) { 1870 if (ipmi_interfaces[i] == NULL) {
1760 new_intf->intf_num = i; 1871 intf->intf_num = i;
1761 new_intf->version_major = version_major; 1872 /* Reserve the entry till we are done. */
1762 new_intf->version_minor = version_minor; 1873 ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
1763 for (j = 0; j < IPMI_MAX_CHANNELS; j++) {
1764 new_intf->channels[j].address
1765 = IPMI_BMC_SLAVE_ADDR;
1766 new_intf->channels[j].lun = 2;
1767 }
1768 if (slave_addr != 0)
1769 new_intf->channels[0].address = slave_addr;
1770 rwlock_init(&(new_intf->users_lock));
1771 INIT_LIST_HEAD(&(new_intf->users));
1772 new_intf->handlers = handlers;
1773 new_intf->send_info = send_info;
1774 spin_lock_init(&(new_intf->seq_lock));
1775 for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
1776 new_intf->seq_table[j].inuse = 0;
1777 new_intf->seq_table[j].seqid = 0;
1778 }
1779 new_intf->curr_seq = 0;
1780#ifdef CONFIG_PROC_FS
1781 spin_lock_init(&(new_intf->proc_entry_lock));
1782#endif
1783 spin_lock_init(&(new_intf->waiting_msgs_lock));
1784 INIT_LIST_HEAD(&(new_intf->waiting_msgs));
1785 spin_lock_init(&(new_intf->events_lock));
1786 INIT_LIST_HEAD(&(new_intf->waiting_events));
1787 new_intf->waiting_events_count = 0;
1788 rwlock_init(&(new_intf->cmd_rcvr_lock));
1789 init_waitqueue_head(&new_intf->waitq);
1790 INIT_LIST_HEAD(&(new_intf->cmd_rcvrs));
1791
1792 spin_lock_init(&(new_intf->counter_lock));
1793
1794 spin_lock_irqsave(&interfaces_lock, flags);
1795 ipmi_interfaces[i] = new_intf;
1796 spin_unlock_irqrestore(&interfaces_lock, flags);
1797
1798 rv = 0; 1874 rv = 0;
1799 *intf = new_intf;
1800 break; 1875 break;
1801 } 1876 }
1802 } 1877 }
1878 spin_unlock_irqrestore(&interfaces_lock, flags);
1879 if (rv)
1880 goto out;
1803 1881
1804 downgrade_write(&interfaces_sem); 1882 /* FIXME - this is an ugly kludge, this sets the intf for the
1805 1883 caller before sending any messages with it. */
1806 if (rv == 0) 1884 *new_intf = intf;
1807 rv = add_proc_entries(*intf, i);
1808
1809 if (rv == 0) {
1810 if ((version_major > 1)
1811 || ((version_major == 1) && (version_minor >= 5)))
1812 {
1813 /* Start scanning the channels to see what is
1814 available. */
1815 (*intf)->null_user_handler = channel_handler;
1816 (*intf)->curr_channel = 0;
1817 rv = send_channel_info_cmd(*intf, 0);
1818 if (rv)
1819 goto out;
1820 1885
1821 /* Wait for the channel info to be read. */ 1886 if ((version_major > 1)
1822 up_read(&interfaces_sem); 1887 || ((version_major == 1) && (version_minor >= 5)))
1823 wait_event((*intf)->waitq, 1888 {
1824 ((*intf)->curr_channel>=IPMI_MAX_CHANNELS)); 1889 /* Start scanning the channels to see what is
1825 down_read(&interfaces_sem); 1890 available. */
1891 intf->null_user_handler = channel_handler;
1892 intf->curr_channel = 0;
1893 rv = send_channel_info_cmd(intf, 0);
1894 if (rv)
1895 goto out;
1826 1896
1827 if (ipmi_interfaces[i] != new_intf) 1897 /* Wait for the channel info to be read. */
1828 /* Well, it went away. Just return. */ 1898 wait_event(intf->waitq,
1829 goto out; 1899 intf->curr_channel >= IPMI_MAX_CHANNELS);
1830 } else { 1900 } else {
1831 /* Assume a single IPMB channel at zero. */ 1901 /* Assume a single IPMB channel at zero. */
1832 (*intf)->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB; 1902 intf->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
1833 (*intf)->channels[0].protocol 1903 intf->channels[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB;
1834 = IPMI_CHANNEL_PROTOCOL_IPMB;
1835 }
1836
1837 /* Call all the watcher interfaces to tell
1838 them that a new interface is available. */
1839 call_smi_watchers(i);
1840 } 1904 }
1841 1905
1842 out: 1906 if (rv == 0)
1843 up_read(&interfaces_sem); 1907 rv = add_proc_entries(intf, i);
1844 1908
1909 out:
1845 if (rv) { 1910 if (rv) {
1846 if (new_intf->proc_dir) 1911 if (intf->proc_dir)
1847 remove_proc_entries(new_intf); 1912 remove_proc_entries(intf);
1848 kfree(new_intf); 1913 kref_put(&intf->refcount, intf_free);
1914 if (i < MAX_IPMI_INTERFACES) {
1915 spin_lock_irqsave(&interfaces_lock, flags);
1916 ipmi_interfaces[i] = NULL;
1917 spin_unlock_irqrestore(&interfaces_lock, flags);
1918 }
1919 } else {
1920 spin_lock_irqsave(&interfaces_lock, flags);
1921 ipmi_interfaces[i] = intf;
1922 spin_unlock_irqrestore(&interfaces_lock, flags);
1923 call_smi_watchers(i);
1849 } 1924 }
1850 1925
1851 return rv; 1926 return rv;
1852} 1927}
1853 1928
1854static void free_recv_msg_list(struct list_head *q)
1855{
1856 struct ipmi_recv_msg *msg, *msg2;
1857
1858 list_for_each_entry_safe(msg, msg2, q, link) {
1859 list_del(&msg->link);
1860 ipmi_free_recv_msg(msg);
1861 }
1862}
1863
1864static void free_cmd_rcvr_list(struct list_head *q)
1865{
1866 struct cmd_rcvr *rcvr, *rcvr2;
1867
1868 list_for_each_entry_safe(rcvr, rcvr2, q, link) {
1869 list_del(&rcvr->link);
1870 kfree(rcvr);
1871 }
1872}
1873
1874static void clean_up_interface_data(ipmi_smi_t intf)
1875{
1876 int i;
1877
1878 free_recv_msg_list(&(intf->waiting_msgs));
1879 free_recv_msg_list(&(intf->waiting_events));
1880 free_cmd_rcvr_list(&(intf->cmd_rcvrs));
1881
1882 for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
1883 if ((intf->seq_table[i].inuse)
1884 && (intf->seq_table[i].recv_msg))
1885 {
1886 ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
1887 }
1888 }
1889}
1890
1891int ipmi_unregister_smi(ipmi_smi_t intf) 1929int ipmi_unregister_smi(ipmi_smi_t intf)
1892{ 1930{
1893 int rv = -ENODEV;
1894 int i; 1931 int i;
1895 struct ipmi_smi_watcher *w; 1932 struct ipmi_smi_watcher *w;
1896 unsigned long flags; 1933 unsigned long flags;
1897 1934
1898 down_write(&interfaces_sem); 1935 spin_lock_irqsave(&interfaces_lock, flags);
1899 if (list_empty(&(intf->users))) 1936 for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
1900 { 1937 if (ipmi_interfaces[i] == intf) {
1901 for (i = 0; i < MAX_IPMI_INTERFACES; i++) { 1938 /* Set the interface number reserved until we
1902 if (ipmi_interfaces[i] == intf) { 1939 * are done. */
1903 remove_proc_entries(intf); 1940 ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
1904 spin_lock_irqsave(&interfaces_lock, flags); 1941 intf->intf_num = -1;
1905 ipmi_interfaces[i] = NULL; 1942 break;
1906 clean_up_interface_data(intf);
1907 spin_unlock_irqrestore(&interfaces_lock,flags);
1908 kfree(intf);
1909 rv = 0;
1910 goto out_call_watcher;
1911 }
1912 } 1943 }
1913 } else {
1914 rv = -EBUSY;
1915 } 1944 }
1916 up_write(&interfaces_sem); 1945 spin_unlock_irqrestore(&interfaces_lock,flags);
1917 1946
1918 return rv; 1947 if (i == MAX_IPMI_INTERFACES)
1948 return -ENODEV;
1919 1949
1920 out_call_watcher: 1950 remove_proc_entries(intf);
1921 downgrade_write(&interfaces_sem);
1922 1951
1923 /* Call all the watcher interfaces to tell them that 1952 /* Call all the watcher interfaces to tell them that
1924 an interface is gone. */ 1953 an interface is gone. */
1925 down_read(&smi_watchers_sem); 1954 down_read(&smi_watchers_sem);
1926 list_for_each_entry(w, &smi_watchers, link) { 1955 list_for_each_entry(w, &smi_watchers, link)
1927 w->smi_gone(i); 1956 w->smi_gone(i);
1928 }
1929 up_read(&smi_watchers_sem); 1957 up_read(&smi_watchers_sem);
1930 up_read(&interfaces_sem); 1958
1959 /* Allow the entry to be reused now. */
1960 spin_lock_irqsave(&interfaces_lock, flags);
1961 ipmi_interfaces[i] = NULL;
1962 spin_unlock_irqrestore(&interfaces_lock,flags);
1963
1964 kref_put(&intf->refcount, intf_free);
1931 return 0; 1965 return 0;
1932} 1966}
1933 1967
@@ -1998,14 +2032,14 @@ static int handle_ipmb_get_msg_rsp(ipmi_smi_t intf,
1998static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, 2032static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
1999 struct ipmi_smi_msg *msg) 2033 struct ipmi_smi_msg *msg)
2000{ 2034{
2001 struct cmd_rcvr *rcvr; 2035 struct cmd_rcvr *rcvr;
2002 int rv = 0; 2036 int rv = 0;
2003 unsigned char netfn; 2037 unsigned char netfn;
2004 unsigned char cmd; 2038 unsigned char cmd;
2005 ipmi_user_t user = NULL; 2039 ipmi_user_t user = NULL;
2006 struct ipmi_ipmb_addr *ipmb_addr; 2040 struct ipmi_ipmb_addr *ipmb_addr;
2007 struct ipmi_recv_msg *recv_msg; 2041 struct ipmi_recv_msg *recv_msg;
2008 unsigned long flags; 2042 unsigned long flags;
2009 2043
2010 if (msg->rsp_size < 10) { 2044 if (msg->rsp_size < 10) {
2011 /* Message not big enough, just ignore it. */ 2045 /* Message not big enough, just ignore it. */
@@ -2023,16 +2057,14 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
2023 netfn = msg->rsp[4] >> 2; 2057 netfn = msg->rsp[4] >> 2;
2024 cmd = msg->rsp[8]; 2058 cmd = msg->rsp[8];
2025 2059
2026 read_lock(&(intf->cmd_rcvr_lock)); 2060 rcu_read_lock();
2027 2061 rcvr = find_cmd_rcvr(intf, netfn, cmd);
2028 /* Find the command/netfn. */ 2062 if (rcvr) {
2029 list_for_each_entry(rcvr, &(intf->cmd_rcvrs), link) { 2063 user = rcvr->user;
2030 if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) { 2064 kref_get(&user->refcount);
2031 user = rcvr->user; 2065 } else
2032 break; 2066 user = NULL;
2033 } 2067 rcu_read_unlock();
2034 }
2035 read_unlock(&(intf->cmd_rcvr_lock));
2036 2068
2037 if (user == NULL) { 2069 if (user == NULL) {
2038 /* We didn't find a user, deliver an error response. */ 2070 /* We didn't find a user, deliver an error response. */
@@ -2079,6 +2111,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf,
2079 message, so requeue it for handling 2111 message, so requeue it for handling
2080 later. */ 2112 later. */
2081 rv = 1; 2113 rv = 1;
2114 kref_put(&user->refcount, free_user);
2082 } else { 2115 } else {
2083 /* Extract the source address from the data. */ 2116 /* Extract the source address from the data. */
2084 ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr; 2117 ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr;
@@ -2179,14 +2212,14 @@ static int handle_lan_get_msg_rsp(ipmi_smi_t intf,
2179static int handle_lan_get_msg_cmd(ipmi_smi_t intf, 2212static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
2180 struct ipmi_smi_msg *msg) 2213 struct ipmi_smi_msg *msg)
2181{ 2214{
2182 struct cmd_rcvr *rcvr; 2215 struct cmd_rcvr *rcvr;
2183 int rv = 0; 2216 int rv = 0;
2184 unsigned char netfn; 2217 unsigned char netfn;
2185 unsigned char cmd; 2218 unsigned char cmd;
2186 ipmi_user_t user = NULL; 2219 ipmi_user_t user = NULL;
2187 struct ipmi_lan_addr *lan_addr; 2220 struct ipmi_lan_addr *lan_addr;
2188 struct ipmi_recv_msg *recv_msg; 2221 struct ipmi_recv_msg *recv_msg;
2189 unsigned long flags; 2222 unsigned long flags;
2190 2223
2191 if (msg->rsp_size < 12) { 2224 if (msg->rsp_size < 12) {
2192 /* Message not big enough, just ignore it. */ 2225 /* Message not big enough, just ignore it. */
@@ -2204,19 +2237,17 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
2204 netfn = msg->rsp[6] >> 2; 2237 netfn = msg->rsp[6] >> 2;
2205 cmd = msg->rsp[10]; 2238 cmd = msg->rsp[10];
2206 2239
2207 read_lock(&(intf->cmd_rcvr_lock)); 2240 rcu_read_lock();
2208 2241 rcvr = find_cmd_rcvr(intf, netfn, cmd);
2209 /* Find the command/netfn. */ 2242 if (rcvr) {
2210 list_for_each_entry(rcvr, &(intf->cmd_rcvrs), link) { 2243 user = rcvr->user;
2211 if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) { 2244 kref_get(&user->refcount);
2212 user = rcvr->user; 2245 } else
2213 break; 2246 user = NULL;
2214 } 2247 rcu_read_unlock();
2215 }
2216 read_unlock(&(intf->cmd_rcvr_lock));
2217 2248
2218 if (user == NULL) { 2249 if (user == NULL) {
2219 /* We didn't find a user, deliver an error response. */ 2250 /* We didn't find a user, just give up. */
2220 spin_lock_irqsave(&intf->counter_lock, flags); 2251 spin_lock_irqsave(&intf->counter_lock, flags);
2221 intf->unhandled_commands++; 2252 intf->unhandled_commands++;
2222 spin_unlock_irqrestore(&intf->counter_lock, flags); 2253 spin_unlock_irqrestore(&intf->counter_lock, flags);
@@ -2235,6 +2266,7 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t intf,
2235 message, so requeue it for handling 2266 message, so requeue it for handling
2236 later. */ 2267 later. */
2237 rv = 1; 2268 rv = 1;
2269 kref_put(&user->refcount, free_user);
2238 } else { 2270 } else {
2239 /* Extract the source address from the data. */ 2271 /* Extract the source address from the data. */
2240 lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr; 2272 lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr;
@@ -2286,8 +2318,6 @@ static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg,
2286 recv_msg->msg.data_len = msg->rsp_size - 3; 2318 recv_msg->msg.data_len = msg->rsp_size - 3;
2287} 2319}
2288 2320
2289/* This will be called with the intf->users_lock read-locked, so no need
2290 to do that here. */
2291static int handle_read_event_rsp(ipmi_smi_t intf, 2321static int handle_read_event_rsp(ipmi_smi_t intf,
2292 struct ipmi_smi_msg *msg) 2322 struct ipmi_smi_msg *msg)
2293{ 2323{
@@ -2313,7 +2343,7 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
2313 2343
2314 INIT_LIST_HEAD(&msgs); 2344 INIT_LIST_HEAD(&msgs);
2315 2345
2316 spin_lock_irqsave(&(intf->events_lock), flags); 2346 spin_lock_irqsave(&intf->events_lock, flags);
2317 2347
2318 spin_lock(&intf->counter_lock); 2348 spin_lock(&intf->counter_lock);
2319 intf->events++; 2349 intf->events++;
@@ -2321,12 +2351,14 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
2321 2351
2322 /* Allocate and fill in one message for every user that is getting 2352 /* Allocate and fill in one message for every user that is getting
2323 events. */ 2353 events. */
2324 list_for_each_entry(user, &(intf->users), link) { 2354 rcu_read_lock();
2355 list_for_each_entry_rcu(user, &intf->users, link) {
2325 if (! user->gets_events) 2356 if (! user->gets_events)
2326 continue; 2357 continue;
2327 2358
2328 recv_msg = ipmi_alloc_recv_msg(); 2359 recv_msg = ipmi_alloc_recv_msg();
2329 if (! recv_msg) { 2360 if (! recv_msg) {
2361 rcu_read_unlock();
2330 list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) { 2362 list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) {
2331 list_del(&recv_msg->link); 2363 list_del(&recv_msg->link);
2332 ipmi_free_recv_msg(recv_msg); 2364 ipmi_free_recv_msg(recv_msg);
@@ -2342,8 +2374,10 @@ static int handle_read_event_rsp(ipmi_smi_t intf,
2342 2374
2343 copy_event_into_recv_msg(recv_msg, msg); 2375 copy_event_into_recv_msg(recv_msg, msg);
2344 recv_msg->user = user; 2376 recv_msg->user = user;
2377 kref_get(&user->refcount);
2345 list_add_tail(&(recv_msg->link), &msgs); 2378 list_add_tail(&(recv_msg->link), &msgs);
2346 } 2379 }
2380 rcu_read_unlock();
2347 2381
2348 if (deliver_count) { 2382 if (deliver_count) {
2349 /* Now deliver all the messages. */ 2383 /* Now deliver all the messages. */
@@ -2382,9 +2416,8 @@ static int handle_bmc_rsp(ipmi_smi_t intf,
2382 struct ipmi_smi_msg *msg) 2416 struct ipmi_smi_msg *msg)
2383{ 2417{
2384 struct ipmi_recv_msg *recv_msg; 2418 struct ipmi_recv_msg *recv_msg;
2385 int found = 0;
2386 struct ipmi_user *user;
2387 unsigned long flags; 2419 unsigned long flags;
2420 struct ipmi_user *user;
2388 2421
2389 recv_msg = (struct ipmi_recv_msg *) msg->user_data; 2422 recv_msg = (struct ipmi_recv_msg *) msg->user_data;
2390 if (recv_msg == NULL) 2423 if (recv_msg == NULL)
@@ -2396,16 +2429,9 @@ static int handle_bmc_rsp(ipmi_smi_t intf,
2396 return 0; 2429 return 0;
2397 } 2430 }
2398 2431
2432 user = recv_msg->user;
2399 /* Make sure the user still exists. */ 2433 /* Make sure the user still exists. */
2400 list_for_each_entry(user, &(intf->users), link) { 2434 if (user && !user->valid) {
2401 if (user == recv_msg->user) {
2402 /* Found it, so we can deliver it */
2403 found = 1;
2404 break;
2405 }
2406 }
2407
2408 if ((! found) && recv_msg->user) {
2409 /* The user for the message went away, so give up. */ 2435 /* The user for the message went away, so give up. */
2410 spin_lock_irqsave(&intf->counter_lock, flags); 2436 spin_lock_irqsave(&intf->counter_lock, flags);
2411 intf->unhandled_local_responses++; 2437 intf->unhandled_local_responses++;
@@ -2486,7 +2512,7 @@ static int handle_new_recv_msg(ipmi_smi_t intf,
2486 { 2512 {
2487 /* It's a response to a response we sent. For this we 2513 /* It's a response to a response we sent. For this we
2488 deliver a send message response to the user. */ 2514 deliver a send message response to the user. */
2489 struct ipmi_recv_msg *recv_msg = msg->user_data; 2515 struct ipmi_recv_msg *recv_msg = msg->user_data;
2490 2516
2491 requeue = 0; 2517 requeue = 0;
2492 if (msg->rsp_size < 2) 2518 if (msg->rsp_size < 2)
@@ -2498,13 +2524,18 @@ static int handle_new_recv_msg(ipmi_smi_t intf,
2498 /* Invalid channel number */ 2524 /* Invalid channel number */
2499 goto out; 2525 goto out;
2500 2526
2501 if (recv_msg) { 2527 if (!recv_msg)
2502 recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE; 2528 goto out;
2503 recv_msg->msg.data = recv_msg->msg_data; 2529
2504 recv_msg->msg.data_len = 1; 2530 /* Make sure the user still exists. */
2505 recv_msg->msg_data[0] = msg->rsp[2]; 2531 if (!recv_msg->user || !recv_msg->user->valid)
2506 deliver_response(recv_msg); 2532 goto out;
2507 } 2533
2534 recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE;
2535 recv_msg->msg.data = recv_msg->msg_data;
2536 recv_msg->msg.data_len = 1;
2537 recv_msg->msg_data[0] = msg->rsp[2];
2538 deliver_response(recv_msg);
2508 } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) 2539 } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
2509 && (msg->rsp[1] == IPMI_GET_MSG_CMD)) 2540 && (msg->rsp[1] == IPMI_GET_MSG_CMD))
2510 { 2541 {
@@ -2570,14 +2601,11 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
2570 int rv; 2601 int rv;
2571 2602
2572 2603
2573 /* Lock the user lock so the user can't go away while we are
2574 working on it. */
2575 read_lock(&(intf->users_lock));
2576
2577 if ((msg->data_size >= 2) 2604 if ((msg->data_size >= 2)
2578 && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2)) 2605 && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2))
2579 && (msg->data[1] == IPMI_SEND_MSG_CMD) 2606 && (msg->data[1] == IPMI_SEND_MSG_CMD)
2580 && (msg->user_data == NULL)) { 2607 && (msg->user_data == NULL))
2608 {
2581 /* This is the local response to a command send, start 2609 /* This is the local response to a command send, start
2582 the timer for these. The user_data will not be 2610 the timer for these. The user_data will not be
2583 NULL if this is a response send, and we will let 2611 NULL if this is a response send, and we will let
@@ -2612,46 +2640,46 @@ void ipmi_smi_msg_received(ipmi_smi_t intf,
2612 } 2640 }
2613 2641
2614 ipmi_free_smi_msg(msg); 2642 ipmi_free_smi_msg(msg);
2615 goto out_unlock; 2643 goto out;
2616 } 2644 }
2617 2645
2618 /* To preserve message order, if the list is not empty, we 2646 /* To preserve message order, if the list is not empty, we
2619 tack this message onto the end of the list. */ 2647 tack this message onto the end of the list. */
2620 spin_lock_irqsave(&(intf->waiting_msgs_lock), flags); 2648 spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
2621 if (!list_empty(&(intf->waiting_msgs))) { 2649 if (!list_empty(&intf->waiting_msgs)) {
2622 list_add_tail(&(msg->link), &(intf->waiting_msgs)); 2650 list_add_tail(&msg->link, &intf->waiting_msgs);
2623 spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); 2651 spin_unlock(&intf->waiting_msgs_lock);
2624 goto out_unlock; 2652 goto out;
2625 } 2653 }
2626 spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); 2654 spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
2627 2655
2628 rv = handle_new_recv_msg(intf, msg); 2656 rv = handle_new_recv_msg(intf, msg);
2629 if (rv > 0) { 2657 if (rv > 0) {
2630 /* Could not handle the message now, just add it to a 2658 /* Could not handle the message now, just add it to a
2631 list to handle later. */ 2659 list to handle later. */
2632 spin_lock_irqsave(&(intf->waiting_msgs_lock), flags); 2660 spin_lock(&intf->waiting_msgs_lock);
2633 list_add_tail(&(msg->link), &(intf->waiting_msgs)); 2661 list_add_tail(&msg->link, &intf->waiting_msgs);
2634 spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); 2662 spin_unlock(&intf->waiting_msgs_lock);
2635 } else if (rv == 0) { 2663 } else if (rv == 0) {
2636 ipmi_free_smi_msg(msg); 2664 ipmi_free_smi_msg(msg);
2637 } 2665 }
2638 2666
2639 out_unlock: 2667 out:
2640 read_unlock(&(intf->users_lock)); 2668 return;
2641} 2669}
2642 2670
2643void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf) 2671void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
2644{ 2672{
2645 ipmi_user_t user; 2673 ipmi_user_t user;
2646 2674
2647 read_lock(&(intf->users_lock)); 2675 rcu_read_lock();
2648 list_for_each_entry(user, &(intf->users), link) { 2676 list_for_each_entry_rcu(user, &intf->users, link) {
2649 if (! user->handler->ipmi_watchdog_pretimeout) 2677 if (! user->handler->ipmi_watchdog_pretimeout)
2650 continue; 2678 continue;
2651 2679
2652 user->handler->ipmi_watchdog_pretimeout(user->handler_data); 2680 user->handler->ipmi_watchdog_pretimeout(user->handler_data);
2653 } 2681 }
2654 read_unlock(&(intf->users_lock)); 2682 rcu_read_unlock();
2655} 2683}
2656 2684
2657static void 2685static void
@@ -2691,8 +2719,65 @@ smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
2691 return smi_msg; 2719 return smi_msg;
2692} 2720}
2693 2721
2694static void 2722static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
2695ipmi_timeout_handler(long timeout_period) 2723 struct list_head *timeouts, long timeout_period,
2724 int slot, unsigned long *flags)
2725{
2726 struct ipmi_recv_msg *msg;
2727
2728 if (!ent->inuse)
2729 return;
2730
2731 ent->timeout -= timeout_period;
2732 if (ent->timeout > 0)
2733 return;
2734
2735 if (ent->retries_left == 0) {
2736 /* The message has used all its retries. */
2737 ent->inuse = 0;
2738 msg = ent->recv_msg;
2739 list_add_tail(&msg->link, timeouts);
2740 spin_lock(&intf->counter_lock);
2741 if (ent->broadcast)
2742 intf->timed_out_ipmb_broadcasts++;
2743 else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
2744 intf->timed_out_lan_commands++;
2745 else
2746 intf->timed_out_ipmb_commands++;
2747 spin_unlock(&intf->counter_lock);
2748 } else {
2749 struct ipmi_smi_msg *smi_msg;
2750 /* More retries, send again. */
2751
2752 /* Start with the max timer, set to normal
2753 timer after the message is sent. */
2754 ent->timeout = MAX_MSG_TIMEOUT;
2755 ent->retries_left--;
2756 spin_lock(&intf->counter_lock);
2757 if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
2758 intf->retransmitted_lan_commands++;
2759 else
2760 intf->retransmitted_ipmb_commands++;
2761 spin_unlock(&intf->counter_lock);
2762
2763 smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
2764 ent->seqid);
2765 if (! smi_msg)
2766 return;
2767
2768 spin_unlock_irqrestore(&intf->seq_lock, *flags);
2769 /* Send the new message. We send with a zero
2770 * priority. It timed out, I doubt time is
2771 * that critical now, and high priority
2772 * messages are really only for messages to the
2773 * local MC, which don't get resent. */
2774 intf->handlers->sender(intf->send_info,
2775 smi_msg, 0);
2776 spin_lock_irqsave(&intf->seq_lock, *flags);
2777 }
2778}
2779
2780static void ipmi_timeout_handler(long timeout_period)
2696{ 2781{
2697 ipmi_smi_t intf; 2782 ipmi_smi_t intf;
2698 struct list_head timeouts; 2783 struct list_head timeouts;
@@ -2706,14 +2791,14 @@ ipmi_timeout_handler(long timeout_period)
2706 spin_lock(&interfaces_lock); 2791 spin_lock(&interfaces_lock);
2707 for (i = 0; i < MAX_IPMI_INTERFACES; i++) { 2792 for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
2708 intf = ipmi_interfaces[i]; 2793 intf = ipmi_interfaces[i];
2709 if (intf == NULL) 2794 if (IPMI_INVALID_INTERFACE(intf))
2710 continue; 2795 continue;
2711 2796 kref_get(&intf->refcount);
2712 read_lock(&(intf->users_lock)); 2797 spin_unlock(&interfaces_lock);
2713 2798
2714 /* See if any waiting messages need to be processed. */ 2799 /* See if any waiting messages need to be processed. */
2715 spin_lock_irqsave(&(intf->waiting_msgs_lock), flags); 2800 spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
2716 list_for_each_entry_safe(smi_msg, smi_msg2, &(intf->waiting_msgs), link) { 2801 list_for_each_entry_safe(smi_msg, smi_msg2, &intf->waiting_msgs, link) {
2717 if (! handle_new_recv_msg(intf, smi_msg)) { 2802 if (! handle_new_recv_msg(intf, smi_msg)) {
2718 list_del(&smi_msg->link); 2803 list_del(&smi_msg->link);
2719 ipmi_free_smi_msg(smi_msg); 2804 ipmi_free_smi_msg(smi_msg);
@@ -2723,73 +2808,23 @@ ipmi_timeout_handler(long timeout_period)
2723 break; 2808 break;
2724 } 2809 }
2725 } 2810 }
2726 spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags); 2811 spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
2727 2812
2728 /* Go through the seq table and find any messages that 2813 /* Go through the seq table and find any messages that
2729 have timed out, putting them in the timeouts 2814 have timed out, putting them in the timeouts
2730 list. */ 2815 list. */
2731 spin_lock_irqsave(&(intf->seq_lock), flags); 2816 spin_lock_irqsave(&intf->seq_lock, flags);
2732 for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) { 2817 for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++)
2733 struct seq_table *ent = &(intf->seq_table[j]); 2818 check_msg_timeout(intf, &(intf->seq_table[j]),
2734 if (!ent->inuse) 2819 &timeouts, timeout_period, j,
2735 continue; 2820 &flags);
2736 2821 spin_unlock_irqrestore(&intf->seq_lock, flags);
2737 ent->timeout -= timeout_period; 2822
2738 if (ent->timeout > 0) 2823 list_for_each_entry_safe(msg, msg2, &timeouts, link)
2739 continue;
2740
2741 if (ent->retries_left == 0) {
2742 /* The message has used all its retries. */
2743 ent->inuse = 0;
2744 msg = ent->recv_msg;
2745 list_add_tail(&(msg->link), &timeouts);
2746 spin_lock(&intf->counter_lock);
2747 if (ent->broadcast)
2748 intf->timed_out_ipmb_broadcasts++;
2749 else if (ent->recv_msg->addr.addr_type
2750 == IPMI_LAN_ADDR_TYPE)
2751 intf->timed_out_lan_commands++;
2752 else
2753 intf->timed_out_ipmb_commands++;
2754 spin_unlock(&intf->counter_lock);
2755 } else {
2756 struct ipmi_smi_msg *smi_msg;
2757 /* More retries, send again. */
2758
2759 /* Start with the max timer, set to normal
2760 timer after the message is sent. */
2761 ent->timeout = MAX_MSG_TIMEOUT;
2762 ent->retries_left--;
2763 spin_lock(&intf->counter_lock);
2764 if (ent->recv_msg->addr.addr_type
2765 == IPMI_LAN_ADDR_TYPE)
2766 intf->retransmitted_lan_commands++;
2767 else
2768 intf->retransmitted_ipmb_commands++;
2769 spin_unlock(&intf->counter_lock);
2770 smi_msg = smi_from_recv_msg(intf,
2771 ent->recv_msg, j, ent->seqid);
2772 if (! smi_msg)
2773 continue;
2774
2775 spin_unlock_irqrestore(&(intf->seq_lock),flags);
2776 /* Send the new message. We send with a zero
2777 * priority. It timed out, I doubt time is
2778 * that critical now, and high priority
2779 * messages are really only for messages to the
2780 * local MC, which don't get resent. */
2781 intf->handlers->sender(intf->send_info,
2782 smi_msg, 0);
2783 spin_lock_irqsave(&(intf->seq_lock), flags);
2784 }
2785 }
2786 spin_unlock_irqrestore(&(intf->seq_lock), flags);
2787
2788 list_for_each_entry_safe(msg, msg2, &timeouts, link) {
2789 handle_msg_timeout(msg); 2824 handle_msg_timeout(msg);
2790 }
2791 2825
2792 read_unlock(&(intf->users_lock)); 2826 kref_put(&intf->refcount, intf_free);
2827 spin_lock(&interfaces_lock);
2793 } 2828 }
2794 spin_unlock(&interfaces_lock); 2829 spin_unlock(&interfaces_lock);
2795} 2830}
@@ -2802,7 +2837,7 @@ static void ipmi_request_event(void)
2802 spin_lock(&interfaces_lock); 2837 spin_lock(&interfaces_lock);
2803 for (i = 0; i < MAX_IPMI_INTERFACES; i++) { 2838 for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
2804 intf = ipmi_interfaces[i]; 2839 intf = ipmi_interfaces[i];
2805 if (intf == NULL) 2840 if (IPMI_INVALID_INTERFACE(intf))
2806 continue; 2841 continue;
2807 2842
2808 intf->handlers->request_events(intf->send_info); 2843 intf->handlers->request_events(intf->send_info);
@@ -2884,6 +2919,13 @@ struct ipmi_recv_msg *ipmi_alloc_recv_msg(void)
2884 return rv; 2919 return rv;
2885} 2920}
2886 2921
2922void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
2923{
2924 if (msg->user)
2925 kref_put(&msg->user->refcount, free_user);
2926 msg->done(msg);
2927}
2928
2887#ifdef CONFIG_IPMI_PANIC_EVENT 2929#ifdef CONFIG_IPMI_PANIC_EVENT
2888 2930
2889static void dummy_smi_done_handler(struct ipmi_smi_msg *msg) 2931static void dummy_smi_done_handler(struct ipmi_smi_msg *msg)
@@ -2964,7 +3006,7 @@ static void send_panic_events(char *str)
2964 /* For every registered interface, send the event. */ 3006 /* For every registered interface, send the event. */
2965 for (i = 0; i < MAX_IPMI_INTERFACES; i++) { 3007 for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
2966 intf = ipmi_interfaces[i]; 3008 intf = ipmi_interfaces[i];
2967 if (intf == NULL) 3009 if (IPMI_INVALID_INTERFACE(intf))
2968 continue; 3010 continue;
2969 3011
2970 /* Send the event announcing the panic. */ 3012 /* Send the event announcing the panic. */
@@ -2995,7 +3037,7 @@ static void send_panic_events(char *str)
2995 int j; 3037 int j;
2996 3038
2997 intf = ipmi_interfaces[i]; 3039 intf = ipmi_interfaces[i];
2998 if (intf == NULL) 3040 if (IPMI_INVALID_INTERFACE(intf))
2999 continue; 3041 continue;
3000 3042
3001 /* First job here is to figure out where to send the 3043 /* First job here is to figure out where to send the
@@ -3131,7 +3173,7 @@ static int panic_event(struct notifier_block *this,
3131 /* For every registered interface, set it to run to completion. */ 3173 /* For every registered interface, set it to run to completion. */
3132 for (i = 0; i < MAX_IPMI_INTERFACES; i++) { 3174 for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
3133 intf = ipmi_interfaces[i]; 3175 intf = ipmi_interfaces[i];
3134 if (intf == NULL) 3176 if (IPMI_INVALID_INTERFACE(intf))
3135 continue; 3177 continue;
3136 3178
3137 intf->handlers->set_run_to_completion(intf->send_info, 1); 3179 intf->handlers->set_run_to_completion(intf->send_info, 1);
@@ -3160,9 +3202,8 @@ static int ipmi_init_msghandler(void)
3160 printk(KERN_INFO "ipmi message handler version " 3202 printk(KERN_INFO "ipmi message handler version "
3161 IPMI_DRIVER_VERSION "\n"); 3203 IPMI_DRIVER_VERSION "\n");
3162 3204
3163 for (i = 0; i < MAX_IPMI_INTERFACES; i++) { 3205 for (i = 0; i < MAX_IPMI_INTERFACES; i++)
3164 ipmi_interfaces[i] = NULL; 3206 ipmi_interfaces[i] = NULL;
3165 }
3166 3207
3167#ifdef CONFIG_PROC_FS 3208#ifdef CONFIG_PROC_FS
3168 proc_ipmi_root = proc_mkdir("ipmi", NULL); 3209 proc_ipmi_root = proc_mkdir("ipmi", NULL);
@@ -3258,3 +3299,4 @@ EXPORT_SYMBOL(ipmi_get_my_LUN);
3258EXPORT_SYMBOL(ipmi_smi_add_proc_entry); 3299EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
3259EXPORT_SYMBOL(proc_ipmi_root); 3300EXPORT_SYMBOL(proc_ipmi_root);
3260EXPORT_SYMBOL(ipmi_user_set_run_to_completion); 3301EXPORT_SYMBOL(ipmi_user_set_run_to_completion);
3302EXPORT_SYMBOL(ipmi_free_recv_msg);
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index f66947722e12..e053eade0366 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -56,7 +56,7 @@ static int poweroff_powercycle;
56 56
57/* parameter definition to allow user to flag power cycle */ 57/* parameter definition to allow user to flag power cycle */
58module_param(poweroff_powercycle, int, 0644); 58module_param(poweroff_powercycle, int, 0644);
59MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down."); 59MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
60 60
61/* Stuff from the get device id command. */ 61/* Stuff from the get device id command. */
62static unsigned int mfg_id; 62static unsigned int mfg_id;
@@ -611,9 +611,7 @@ static int ipmi_poweroff_init (void)
611 } 611 }
612#endif 612#endif
613 613
614#ifdef CONFIG_PROC_FS
615 rv = ipmi_smi_watcher_register(&smi_watcher); 614 rv = ipmi_smi_watcher_register(&smi_watcher);
616#endif
617 if (rv) { 615 if (rv) {
618 unregister_sysctl_table(ipmi_table_header); 616 unregister_sysctl_table(ipmi_table_header);
619 printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv); 617 printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index b6e5cbfb09f8..ea89dca3dbb5 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -51,6 +51,8 @@
51#include <linux/list.h> 51#include <linux/list.h>
52#include <linux/pci.h> 52#include <linux/pci.h>
53#include <linux/ioport.h> 53#include <linux/ioport.h>
54#include <linux/notifier.h>
55#include <linux/kthread.h>
54#include <asm/irq.h> 56#include <asm/irq.h>
55#ifdef CONFIG_HIGH_RES_TIMERS 57#ifdef CONFIG_HIGH_RES_TIMERS
56#include <linux/hrtime.h> 58#include <linux/hrtime.h>
@@ -125,6 +127,7 @@ struct ipmi_device_id {
125 127
126struct smi_info 128struct smi_info
127{ 129{
130 int intf_num;
128 ipmi_smi_t intf; 131 ipmi_smi_t intf;
129 struct si_sm_data *si_sm; 132 struct si_sm_data *si_sm;
130 struct si_sm_handlers *handlers; 133 struct si_sm_handlers *handlers;
@@ -192,8 +195,7 @@ struct smi_info
192 unsigned long last_timeout_jiffies; 195 unsigned long last_timeout_jiffies;
193 196
194 /* Used to gracefully stop the timer without race conditions. */ 197 /* Used to gracefully stop the timer without race conditions. */
195 volatile int stop_operation; 198 atomic_t stop_operation;
196 volatile int timer_stopped;
197 199
198 /* The driver will disable interrupts when it gets into a 200 /* The driver will disable interrupts when it gets into a
199 situation where it cannot handle messages due to lack of 201 situation where it cannot handle messages due to lack of
@@ -220,8 +222,16 @@ struct smi_info
220 unsigned long events; 222 unsigned long events;
221 unsigned long watchdog_pretimeouts; 223 unsigned long watchdog_pretimeouts;
222 unsigned long incoming_messages; 224 unsigned long incoming_messages;
225
226 struct task_struct *thread;
223}; 227};
224 228
229static struct notifier_block *xaction_notifier_list;
230static int register_xaction_notifier(struct notifier_block * nb)
231{
232 return notifier_chain_register(&xaction_notifier_list, nb);
233}
234
225static void si_restart_short_timer(struct smi_info *smi_info); 235static void si_restart_short_timer(struct smi_info *smi_info);
226 236
227static void deliver_recv_msg(struct smi_info *smi_info, 237static void deliver_recv_msg(struct smi_info *smi_info,
@@ -281,6 +291,11 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
281 do_gettimeofday(&t); 291 do_gettimeofday(&t);
282 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec); 292 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
283#endif 293#endif
294 err = notifier_call_chain(&xaction_notifier_list, 0, smi_info);
295 if (err & NOTIFY_STOP_MASK) {
296 rv = SI_SM_CALL_WITHOUT_DELAY;
297 goto out;
298 }
284 err = smi_info->handlers->start_transaction( 299 err = smi_info->handlers->start_transaction(
285 smi_info->si_sm, 300 smi_info->si_sm,
286 smi_info->curr_msg->data, 301 smi_info->curr_msg->data,
@@ -291,6 +306,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
291 306
292 rv = SI_SM_CALL_WITHOUT_DELAY; 307 rv = SI_SM_CALL_WITHOUT_DELAY;
293 } 308 }
309 out:
294 spin_unlock(&(smi_info->msg_lock)); 310 spin_unlock(&(smi_info->msg_lock));
295 311
296 return rv; 312 return rv;
@@ -766,6 +782,29 @@ static void set_run_to_completion(void *send_info, int i_run_to_completion)
766 spin_unlock_irqrestore(&(smi_info->si_lock), flags); 782 spin_unlock_irqrestore(&(smi_info->si_lock), flags);
767} 783}
768 784
785static int ipmi_thread(void *data)
786{
787 struct smi_info *smi_info = data;
788 unsigned long flags;
789 enum si_sm_result smi_result;
790
791 set_user_nice(current, 19);
792 while (!kthread_should_stop()) {
793 spin_lock_irqsave(&(smi_info->si_lock), flags);
794 smi_result=smi_event_handler(smi_info, 0);
795 spin_unlock_irqrestore(&(smi_info->si_lock), flags);
796 if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
797 /* do nothing */
798 }
799 else if (smi_result == SI_SM_CALL_WITH_DELAY)
800 udelay(1);
801 else
802 schedule_timeout_interruptible(1);
803 }
804 return 0;
805}
806
807
769static void poll(void *send_info) 808static void poll(void *send_info)
770{ 809{
771 struct smi_info *smi_info = send_info; 810 struct smi_info *smi_info = send_info;
@@ -819,15 +858,13 @@ static void smi_timeout(unsigned long data)
819 enum si_sm_result smi_result; 858 enum si_sm_result smi_result;
820 unsigned long flags; 859 unsigned long flags;
821 unsigned long jiffies_now; 860 unsigned long jiffies_now;
822 unsigned long time_diff; 861 long time_diff;
823#ifdef DEBUG_TIMING 862#ifdef DEBUG_TIMING
824 struct timeval t; 863 struct timeval t;
825#endif 864#endif
826 865
827 if (smi_info->stop_operation) { 866 if (atomic_read(&smi_info->stop_operation))
828 smi_info->timer_stopped = 1;
829 return; 867 return;
830 }
831 868
832 spin_lock_irqsave(&(smi_info->si_lock), flags); 869 spin_lock_irqsave(&(smi_info->si_lock), flags);
833#ifdef DEBUG_TIMING 870#ifdef DEBUG_TIMING
@@ -835,7 +872,7 @@ static void smi_timeout(unsigned long data)
835 printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec); 872 printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec);
836#endif 873#endif
837 jiffies_now = jiffies; 874 jiffies_now = jiffies;
838 time_diff = ((jiffies_now - smi_info->last_timeout_jiffies) 875 time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
839 * SI_USEC_PER_JIFFY); 876 * SI_USEC_PER_JIFFY);
840 smi_result = smi_event_handler(smi_info, time_diff); 877 smi_result = smi_event_handler(smi_info, time_diff);
841 878
@@ -900,7 +937,7 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
900 smi_info->interrupts++; 937 smi_info->interrupts++;
901 spin_unlock(&smi_info->count_lock); 938 spin_unlock(&smi_info->count_lock);
902 939
903 if (smi_info->stop_operation) 940 if (atomic_read(&smi_info->stop_operation))
904 goto out; 941 goto out;
905 942
906#ifdef DEBUG_TIMING 943#ifdef DEBUG_TIMING
@@ -1419,7 +1456,7 @@ static u32 ipmi_acpi_gpe(void *context)
1419 smi_info->interrupts++; 1456 smi_info->interrupts++;
1420 spin_unlock(&smi_info->count_lock); 1457 spin_unlock(&smi_info->count_lock);
1421 1458
1422 if (smi_info->stop_operation) 1459 if (atomic_read(&smi_info->stop_operation))
1423 goto out; 1460 goto out;
1424 1461
1425#ifdef DEBUG_TIMING 1462#ifdef DEBUG_TIMING
@@ -1919,7 +1956,8 @@ static int try_get_dev_id(struct smi_info *smi_info)
1919 smi_result = smi_info->handlers->event(smi_info->si_sm, 0); 1956 smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
1920 for (;;) 1957 for (;;)
1921 { 1958 {
1922 if (smi_result == SI_SM_CALL_WITH_DELAY) { 1959 if (smi_result == SI_SM_CALL_WITH_DELAY ||
1960 smi_result == SI_SM_CALL_WITH_TICK_DELAY) {
1923 schedule_timeout_uninterruptible(1); 1961 schedule_timeout_uninterruptible(1);
1924 smi_result = smi_info->handlers->event( 1962 smi_result = smi_info->handlers->event(
1925 smi_info->si_sm, 100); 1963 smi_info->si_sm, 100);
@@ -2052,6 +2090,9 @@ static int oem_data_avail_to_receive_msg_avail(struct smi_info *smi_info)
2052 * IPMI Version = 0x51 IPMI 1.5 2090 * IPMI Version = 0x51 IPMI 1.5
2053 * Manufacturer ID = A2 02 00 Dell IANA 2091 * Manufacturer ID = A2 02 00 Dell IANA
2054 * 2092 *
2093 * Additionally, PowerEdge systems with IPMI < 1.5 may also assert
2094 * OEM0_DATA_AVAIL and needs to be treated as RECEIVE_MSG_AVAIL.
2095 *
2055 */ 2096 */
2056#define DELL_POWEREDGE_8G_BMC_DEVICE_ID 0x20 2097#define DELL_POWEREDGE_8G_BMC_DEVICE_ID 0x20
2057#define DELL_POWEREDGE_8G_BMC_DEVICE_REV 0x80 2098#define DELL_POWEREDGE_8G_BMC_DEVICE_REV 0x80
@@ -2061,16 +2102,87 @@ static void setup_dell_poweredge_oem_data_handler(struct smi_info *smi_info)
2061{ 2102{
2062 struct ipmi_device_id *id = &smi_info->device_id; 2103 struct ipmi_device_id *id = &smi_info->device_id;
2063 const char mfr[3]=DELL_IANA_MFR_ID; 2104 const char mfr[3]=DELL_IANA_MFR_ID;
2064 if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr)) 2105 if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr))) {
2065 && (id->device_id == DELL_POWEREDGE_8G_BMC_DEVICE_ID) 2106 if (id->device_id == DELL_POWEREDGE_8G_BMC_DEVICE_ID &&
2066 && (id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV) 2107 id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV &&
2067 && (id->ipmi_version == DELL_POWEREDGE_8G_BMC_IPMI_VERSION)) 2108 id->ipmi_version == DELL_POWEREDGE_8G_BMC_IPMI_VERSION) {
2068 { 2109 smi_info->oem_data_avail_handler =
2069 smi_info->oem_data_avail_handler = 2110 oem_data_avail_to_receive_msg_avail;
2070 oem_data_avail_to_receive_msg_avail; 2111 }
2112 else if (ipmi_version_major(id) < 1 ||
2113 (ipmi_version_major(id) == 1 &&
2114 ipmi_version_minor(id) < 5)) {
2115 smi_info->oem_data_avail_handler =
2116 oem_data_avail_to_receive_msg_avail;
2117 }
2071 } 2118 }
2072} 2119}
2073 2120
2121#define CANNOT_RETURN_REQUESTED_LENGTH 0xCA
2122static void return_hosed_msg_badsize(struct smi_info *smi_info)
2123{
2124 struct ipmi_smi_msg *msg = smi_info->curr_msg;
2125
2126 /* Make it a reponse */
2127 msg->rsp[0] = msg->data[0] | 4;
2128 msg->rsp[1] = msg->data[1];
2129 msg->rsp[2] = CANNOT_RETURN_REQUESTED_LENGTH;
2130 msg->rsp_size = 3;
2131 smi_info->curr_msg = NULL;
2132 deliver_recv_msg(smi_info, msg);
2133}
2134
2135/*
2136 * dell_poweredge_bt_xaction_handler
2137 * @info - smi_info.device_id must be populated
2138 *
2139 * Dell PowerEdge servers with the BT interface (x6xx and 1750) will
2140 * not respond to a Get SDR command if the length of the data
2141 * requested is exactly 0x3A, which leads to command timeouts and no
2142 * data returned. This intercepts such commands, and causes userspace
2143 * callers to try again with a different-sized buffer, which succeeds.
2144 */
2145
2146#define STORAGE_NETFN 0x0A
2147#define STORAGE_CMD_GET_SDR 0x23
2148static int dell_poweredge_bt_xaction_handler(struct notifier_block *self,
2149 unsigned long unused,
2150 void *in)
2151{
2152 struct smi_info *smi_info = in;
2153 unsigned char *data = smi_info->curr_msg->data;
2154 unsigned int size = smi_info->curr_msg->data_size;
2155 if (size >= 8 &&
2156 (data[0]>>2) == STORAGE_NETFN &&
2157 data[1] == STORAGE_CMD_GET_SDR &&
2158 data[7] == 0x3A) {
2159 return_hosed_msg_badsize(smi_info);
2160 return NOTIFY_STOP;
2161 }
2162 return NOTIFY_DONE;
2163}
2164
2165static struct notifier_block dell_poweredge_bt_xaction_notifier = {
2166 .notifier_call = dell_poweredge_bt_xaction_handler,
2167};
2168
2169/*
2170 * setup_dell_poweredge_bt_xaction_handler
2171 * @info - smi_info.device_id must be filled in already
2172 *
2173 * Fills in smi_info.device_id.start_transaction_pre_hook
2174 * when we know what function to use there.
2175 */
2176static void
2177setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info)
2178{
2179 struct ipmi_device_id *id = &smi_info->device_id;
2180 const char mfr[3]=DELL_IANA_MFR_ID;
2181 if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr)) &&
2182 smi_info->si_type == SI_BT)
2183 register_xaction_notifier(&dell_poweredge_bt_xaction_notifier);
2184}
2185
2074/* 2186/*
2075 * setup_oem_data_handler 2187 * setup_oem_data_handler
2076 * @info - smi_info.device_id must be filled in already 2188 * @info - smi_info.device_id must be filled in already
@@ -2084,6 +2196,18 @@ static void setup_oem_data_handler(struct smi_info *smi_info)
2084 setup_dell_poweredge_oem_data_handler(smi_info); 2196 setup_dell_poweredge_oem_data_handler(smi_info);
2085} 2197}
2086 2198
2199static void setup_xaction_handlers(struct smi_info *smi_info)
2200{
2201 setup_dell_poweredge_bt_xaction_handler(smi_info);
2202}
2203
2204static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
2205{
2206 if (smi_info->thread != ERR_PTR(-ENOMEM))
2207 kthread_stop(smi_info->thread);
2208 del_timer_sync(&smi_info->si_timer);
2209}
2210
2087/* Returns 0 if initialized, or negative on an error. */ 2211/* Returns 0 if initialized, or negative on an error. */
2088static int init_one_smi(int intf_num, struct smi_info **smi) 2212static int init_one_smi(int intf_num, struct smi_info **smi)
2089{ 2213{
@@ -2179,6 +2303,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
2179 goto out_err; 2303 goto out_err;
2180 2304
2181 setup_oem_data_handler(new_smi); 2305 setup_oem_data_handler(new_smi);
2306 setup_xaction_handlers(new_smi);
2182 2307
2183 /* Try to claim any interrupts. */ 2308 /* Try to claim any interrupts. */
2184 new_smi->irq_setup(new_smi); 2309 new_smi->irq_setup(new_smi);
@@ -2190,8 +2315,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
2190 new_smi->run_to_completion = 0; 2315 new_smi->run_to_completion = 0;
2191 2316
2192 new_smi->interrupt_disabled = 0; 2317 new_smi->interrupt_disabled = 0;
2193 new_smi->timer_stopped = 0; 2318 atomic_set(&new_smi->stop_operation, 0);
2194 new_smi->stop_operation = 0; 2319 new_smi->intf_num = intf_num;
2195 2320
2196 /* Start clearing the flags before we enable interrupts or the 2321 /* Start clearing the flags before we enable interrupts or the
2197 timer to avoid racing with the timer. */ 2322 timer to avoid racing with the timer. */
@@ -2209,7 +2334,11 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
2209 new_smi->si_timer.function = smi_timeout; 2334 new_smi->si_timer.function = smi_timeout;
2210 new_smi->last_timeout_jiffies = jiffies; 2335 new_smi->last_timeout_jiffies = jiffies;
2211 new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; 2336 new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
2337
2212 add_timer(&(new_smi->si_timer)); 2338 add_timer(&(new_smi->si_timer));
2339 if (new_smi->si_type != SI_BT)
2340 new_smi->thread = kthread_run(ipmi_thread, new_smi,
2341 "kipmi%d", new_smi->intf_num);
2213 2342
2214 rv = ipmi_register_smi(&handlers, 2343 rv = ipmi_register_smi(&handlers,
2215 new_smi, 2344 new_smi,
@@ -2251,12 +2380,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
2251 return 0; 2380 return 0;
2252 2381
2253 out_err_stop_timer: 2382 out_err_stop_timer:
2254 new_smi->stop_operation = 1; 2383 atomic_inc(&new_smi->stop_operation);
2255 2384 wait_for_timer_and_thread(new_smi);
2256 /* Wait for the timer to stop. This avoids problems with race
2257 conditions removing the timer here. */
2258 while (!new_smi->timer_stopped)
2259 schedule_timeout_uninterruptible(1);
2260 2385
2261 out_err: 2386 out_err:
2262 if (new_smi->intf) 2387 if (new_smi->intf)
@@ -2362,8 +2487,7 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
2362 spin_lock_irqsave(&(to_clean->si_lock), flags); 2487 spin_lock_irqsave(&(to_clean->si_lock), flags);
2363 spin_lock(&(to_clean->msg_lock)); 2488 spin_lock(&(to_clean->msg_lock));
2364 2489
2365 to_clean->stop_operation = 1; 2490 atomic_inc(&to_clean->stop_operation);
2366
2367 to_clean->irq_cleanup(to_clean); 2491 to_clean->irq_cleanup(to_clean);
2368 2492
2369 spin_unlock(&(to_clean->msg_lock)); 2493 spin_unlock(&(to_clean->msg_lock));
@@ -2374,10 +2498,7 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
2374 interrupt. */ 2498 interrupt. */
2375 synchronize_sched(); 2499 synchronize_sched();
2376 2500
2377 /* Wait for the timer to stop. This avoids problems with race 2501 wait_for_timer_and_thread(to_clean);
2378 conditions removing the timer here. */
2379 while (!to_clean->timer_stopped)
2380 schedule_timeout_uninterruptible(1);
2381 2502
2382 /* Interrupts and timeouts are stopped, now make sure the 2503 /* Interrupts and timeouts are stopped, now make sure the
2383 interface is in a clean state. */ 2504 interface is in a clean state. */
diff --git a/drivers/char/ipmi/ipmi_si_sm.h b/drivers/char/ipmi/ipmi_si_sm.h
index 62791dd42985..bf3d4962d6a5 100644
--- a/drivers/char/ipmi/ipmi_si_sm.h
+++ b/drivers/char/ipmi/ipmi_si_sm.h
@@ -62,6 +62,7 @@ enum si_sm_result
62{ 62{
63 SI_SM_CALL_WITHOUT_DELAY, /* Call the driver again immediately */ 63 SI_SM_CALL_WITHOUT_DELAY, /* Call the driver again immediately */
64 SI_SM_CALL_WITH_DELAY, /* Delay some before calling again. */ 64 SI_SM_CALL_WITH_DELAY, /* Delay some before calling again. */
65 SI_SM_CALL_WITH_TICK_DELAY, /* Delay at least 1 tick before calling again. */
65 SI_SM_TRANSACTION_COMPLETE, /* A transaction is finished. */ 66 SI_SM_TRANSACTION_COMPLETE, /* A transaction is finished. */
66 SI_SM_IDLE, /* The SM is in idle state. */ 67 SI_SM_IDLE, /* The SM is in idle state. */
67 SI_SM_HOSED, /* The hardware violated the state machine. */ 68 SI_SM_HOSED, /* The hardware violated the state machine. */
diff --git a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c
index add2aa2732f0..39d7e5ef1a2b 100644
--- a/drivers/char/ipmi/ipmi_smic_sm.c
+++ b/drivers/char/ipmi/ipmi_smic_sm.c
@@ -43,6 +43,8 @@
43 43
44#include <linux/kernel.h> /* For printk. */ 44#include <linux/kernel.h> /* For printk. */
45#include <linux/string.h> 45#include <linux/string.h>
46#include <linux/module.h>
47#include <linux/moduleparam.h>
46#include <linux/ipmi_msgdefs.h> /* for completion codes */ 48#include <linux/ipmi_msgdefs.h> /* for completion codes */
47#include "ipmi_si_sm.h" 49#include "ipmi_si_sm.h"
48 50
@@ -56,6 +58,8 @@
56#define SMIC_DEBUG_ENABLE 1 58#define SMIC_DEBUG_ENABLE 1
57 59
58static int smic_debug = 1; 60static int smic_debug = 1;
61module_param(smic_debug, int, 0644);
62MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
59 63
60enum smic_states { 64enum smic_states {
61 SMIC_IDLE, 65 SMIC_IDLE,
@@ -76,11 +80,17 @@ enum smic_states {
76#define SMIC_MAX_ERROR_RETRIES 3 80#define SMIC_MAX_ERROR_RETRIES 3
77 81
78/* Timeouts in microseconds. */ 82/* Timeouts in microseconds. */
79#define SMIC_RETRY_TIMEOUT 100000 83#define SMIC_RETRY_TIMEOUT 2000000
80 84
81/* SMIC Flags Register Bits */ 85/* SMIC Flags Register Bits */
82#define SMIC_RX_DATA_READY 0x80 86#define SMIC_RX_DATA_READY 0x80
83#define SMIC_TX_DATA_READY 0x40 87#define SMIC_TX_DATA_READY 0x40
88/*
89 * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by
90 * a few systems, and then only by Systems Management
91 * Interrupts, not by the OS. Always ignore these bits.
92 *
93 */
84#define SMIC_SMI 0x10 94#define SMIC_SMI 0x10
85#define SMIC_EVM_DATA_AVAIL 0x08 95#define SMIC_EVM_DATA_AVAIL 0x08
86#define SMIC_SMS_DATA_AVAIL 0x04 96#define SMIC_SMS_DATA_AVAIL 0x04
@@ -364,8 +374,7 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
364 switch (smic->state) { 374 switch (smic->state) {
365 case SMIC_IDLE: 375 case SMIC_IDLE:
366 /* in IDLE we check for available messages */ 376 /* in IDLE we check for available messages */
367 if (flags & (SMIC_SMI | 377 if (flags & SMIC_SMS_DATA_AVAIL)
368 SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
369 { 378 {
370 return SI_SM_ATTN; 379 return SI_SM_ATTN;
371 } 380 }
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 2da64bf7469c..1f3159eb1ede 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -47,6 +47,9 @@
47#include <linux/reboot.h> 47#include <linux/reboot.h>
48#include <linux/wait.h> 48#include <linux/wait.h>
49#include <linux/poll.h> 49#include <linux/poll.h>
50#include <linux/string.h>
51#include <linux/ctype.h>
52#include <asm/atomic.h>
50#ifdef CONFIG_X86_LOCAL_APIC 53#ifdef CONFIG_X86_LOCAL_APIC
51#include <asm/apic.h> 54#include <asm/apic.h>
52#endif 55#endif
@@ -158,27 +161,120 @@ static struct fasync_struct *fasync_q = NULL;
158static char pretimeout_since_last_heartbeat = 0; 161static char pretimeout_since_last_heartbeat = 0;
159static char expect_close; 162static char expect_close;
160 163
164static DECLARE_RWSEM(register_sem);
165
166/* Parameters to ipmi_set_timeout */
167#define IPMI_SET_TIMEOUT_NO_HB 0
168#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1
169#define IPMI_SET_TIMEOUT_FORCE_HB 2
170
171static int ipmi_set_timeout(int do_heartbeat);
172
161/* If true, the driver will start running as soon as it is configured 173/* If true, the driver will start running as soon as it is configured
162 and ready. */ 174 and ready. */
163static int start_now = 0; 175static int start_now = 0;
164 176
165module_param(timeout, int, 0); 177static int set_param_int(const char *val, struct kernel_param *kp)
178{
179 char *endp;
180 int l;
181 int rv = 0;
182
183 if (!val)
184 return -EINVAL;
185 l = simple_strtoul(val, &endp, 0);
186 if (endp == val)
187 return -EINVAL;
188
189 down_read(&register_sem);
190 *((int *)kp->arg) = l;
191 if (watchdog_user)
192 rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
193 up_read(&register_sem);
194
195 return rv;
196}
197
198static int get_param_int(char *buffer, struct kernel_param *kp)
199{
200 return sprintf(buffer, "%i", *((int *)kp->arg));
201}
202
203typedef int (*action_fn)(const char *intval, char *outval);
204
205static int action_op(const char *inval, char *outval);
206static int preaction_op(const char *inval, char *outval);
207static int preop_op(const char *inval, char *outval);
208static void check_parms(void);
209
210static int set_param_str(const char *val, struct kernel_param *kp)
211{
212 action_fn fn = (action_fn) kp->arg;
213 int rv = 0;
214 const char *end;
215 char valcp[16];
216 int len;
217
218 /* Truncate leading and trailing spaces. */
219 while (isspace(*val))
220 val++;
221 end = val + strlen(val) - 1;
222 while ((end >= val) && isspace(*end))
223 end--;
224 len = end - val + 1;
225 if (len > sizeof(valcp) - 1)
226 return -EINVAL;
227 memcpy(valcp, val, len);
228 valcp[len] = '\0';
229
230 down_read(&register_sem);
231 rv = fn(valcp, NULL);
232 if (rv)
233 goto out_unlock;
234
235 check_parms();
236 if (watchdog_user)
237 rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
238
239 out_unlock:
240 up_read(&register_sem);
241 return rv;
242}
243
244static int get_param_str(char *buffer, struct kernel_param *kp)
245{
246 action_fn fn = (action_fn) kp->arg;
247 int rv;
248
249 rv = fn(NULL, buffer);
250 if (rv)
251 return rv;
252 return strlen(buffer);
253}
254
255module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644);
166MODULE_PARM_DESC(timeout, "Timeout value in seconds."); 256MODULE_PARM_DESC(timeout, "Timeout value in seconds.");
167module_param(pretimeout, int, 0); 257
258module_param_call(pretimeout, set_param_int, get_param_int, &pretimeout, 0644);
168MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds."); 259MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds.");
169module_param_string(action, action, sizeof(action), 0); 260
261module_param_call(action, set_param_str, get_param_str, action_op, 0644);
170MODULE_PARM_DESC(action, "Timeout action. One of: " 262MODULE_PARM_DESC(action, "Timeout action. One of: "
171 "reset, none, power_cycle, power_off."); 263 "reset, none, power_cycle, power_off.");
172module_param_string(preaction, preaction, sizeof(preaction), 0); 264
265module_param_call(preaction, set_param_str, get_param_str, preaction_op, 0644);
173MODULE_PARM_DESC(preaction, "Pretimeout action. One of: " 266MODULE_PARM_DESC(preaction, "Pretimeout action. One of: "
174 "pre_none, pre_smi, pre_nmi, pre_int."); 267 "pre_none, pre_smi, pre_nmi, pre_int.");
175module_param_string(preop, preop, sizeof(preop), 0); 268
269module_param_call(preop, set_param_str, get_param_str, preop_op, 0644);
176MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: " 270MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: "
177 "preop_none, preop_panic, preop_give_data."); 271 "preop_none, preop_panic, preop_give_data.");
272
178module_param(start_now, int, 0); 273module_param(start_now, int, 0);
179MODULE_PARM_DESC(start_now, "Set to 1 to start the watchdog as" 274MODULE_PARM_DESC(start_now, "Set to 1 to start the watchdog as"
180 "soon as the driver is loaded."); 275 "soon as the driver is loaded.");
181module_param(nowayout, int, 0); 276
277module_param(nowayout, int, 0644);
182MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); 278MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
183 279
184/* Default state of the timer. */ 280/* Default state of the timer. */
@@ -200,6 +296,8 @@ static int ipmi_start_timer_on_heartbeat = 0;
200static unsigned char ipmi_version_major; 296static unsigned char ipmi_version_major;
201static unsigned char ipmi_version_minor; 297static unsigned char ipmi_version_minor;
202 298
299/* If a pretimeout occurs, this is used to allow only one panic to happen. */
300static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
203 301
204static int ipmi_heartbeat(void); 302static int ipmi_heartbeat(void);
205static void panic_halt_ipmi_heartbeat(void); 303static void panic_halt_ipmi_heartbeat(void);
@@ -294,11 +392,6 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg,
294 return rv; 392 return rv;
295} 393}
296 394
297/* Parameters to ipmi_set_timeout */
298#define IPMI_SET_TIMEOUT_NO_HB 0
299#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1
300#define IPMI_SET_TIMEOUT_FORCE_HB 2
301
302static int ipmi_set_timeout(int do_heartbeat) 395static int ipmi_set_timeout(int do_heartbeat)
303{ 396{
304 int send_heartbeat_now; 397 int send_heartbeat_now;
@@ -732,8 +825,6 @@ static struct miscdevice ipmi_wdog_miscdev = {
732 .fops = &ipmi_wdog_fops 825 .fops = &ipmi_wdog_fops
733}; 826};
734 827
735static DECLARE_RWSEM(register_sem);
736
737static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg, 828static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
738 void *handler_data) 829 void *handler_data)
739{ 830{
@@ -749,9 +840,10 @@ static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
749static void ipmi_wdog_pretimeout_handler(void *handler_data) 840static void ipmi_wdog_pretimeout_handler(void *handler_data)
750{ 841{
751 if (preaction_val != WDOG_PRETIMEOUT_NONE) { 842 if (preaction_val != WDOG_PRETIMEOUT_NONE) {
752 if (preop_val == WDOG_PREOP_PANIC) 843 if (preop_val == WDOG_PREOP_PANIC) {
753 panic("Watchdog pre-timeout"); 844 if (atomic_inc_and_test(&preop_panic_excl))
754 else if (preop_val == WDOG_PREOP_GIVE_DATA) { 845 panic("Watchdog pre-timeout");
846 } else if (preop_val == WDOG_PREOP_GIVE_DATA) {
755 spin_lock(&ipmi_read_lock); 847 spin_lock(&ipmi_read_lock);
756 data_to_read = 1; 848 data_to_read = 1;
757 wake_up_interruptible(&read_q); 849 wake_up_interruptible(&read_q);
@@ -825,7 +917,8 @@ ipmi_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled)
825 an error and not work unless we re-enable 917 an error and not work unless we re-enable
826 the timer. So do so. */ 918 the timer. So do so. */
827 pretimeout_since_last_heartbeat = 1; 919 pretimeout_since_last_heartbeat = 1;
828 panic(PFX "pre-timeout"); 920 if (atomic_inc_and_test(&preop_panic_excl))
921 panic(PFX "pre-timeout");
829 } 922 }
830 923
831 return NOTIFY_DONE; 924 return NOTIFY_DONE;
@@ -839,6 +932,7 @@ static struct nmi_handler ipmi_nmi_handler =
839 .handler = ipmi_nmi, 932 .handler = ipmi_nmi,
840 .priority = 0, /* Call us last. */ 933 .priority = 0, /* Call us last. */
841}; 934};
935int nmi_handler_registered;
842#endif 936#endif
843 937
844static int wdog_reboot_handler(struct notifier_block *this, 938static int wdog_reboot_handler(struct notifier_block *this,
@@ -921,59 +1015,86 @@ static struct ipmi_smi_watcher smi_watcher =
921 .smi_gone = ipmi_smi_gone 1015 .smi_gone = ipmi_smi_gone
922}; 1016};
923 1017
924static int __init ipmi_wdog_init(void) 1018static int action_op(const char *inval, char *outval)
925{ 1019{
926 int rv; 1020 if (outval)
1021 strcpy(outval, action);
1022
1023 if (!inval)
1024 return 0;
927 1025
928 if (strcmp(action, "reset") == 0) { 1026 if (strcmp(inval, "reset") == 0)
929 action_val = WDOG_TIMEOUT_RESET; 1027 action_val = WDOG_TIMEOUT_RESET;
930 } else if (strcmp(action, "none") == 0) { 1028 else if (strcmp(inval, "none") == 0)
931 action_val = WDOG_TIMEOUT_NONE; 1029 action_val = WDOG_TIMEOUT_NONE;
932 } else if (strcmp(action, "power_cycle") == 0) { 1030 else if (strcmp(inval, "power_cycle") == 0)
933 action_val = WDOG_TIMEOUT_POWER_CYCLE; 1031 action_val = WDOG_TIMEOUT_POWER_CYCLE;
934 } else if (strcmp(action, "power_off") == 0) { 1032 else if (strcmp(inval, "power_off") == 0)
935 action_val = WDOG_TIMEOUT_POWER_DOWN; 1033 action_val = WDOG_TIMEOUT_POWER_DOWN;
936 } else { 1034 else
937 action_val = WDOG_TIMEOUT_RESET; 1035 return -EINVAL;
938 printk(KERN_INFO PFX "Unknown action '%s', defaulting to" 1036 strcpy(action, inval);
939 " reset\n", action); 1037 return 0;
940 } 1038}
1039
1040static int preaction_op(const char *inval, char *outval)
1041{
1042 if (outval)
1043 strcpy(outval, preaction);
941 1044
942 if (strcmp(preaction, "pre_none") == 0) { 1045 if (!inval)
1046 return 0;
1047
1048 if (strcmp(inval, "pre_none") == 0)
943 preaction_val = WDOG_PRETIMEOUT_NONE; 1049 preaction_val = WDOG_PRETIMEOUT_NONE;
944 } else if (strcmp(preaction, "pre_smi") == 0) { 1050 else if (strcmp(inval, "pre_smi") == 0)
945 preaction_val = WDOG_PRETIMEOUT_SMI; 1051 preaction_val = WDOG_PRETIMEOUT_SMI;
946#ifdef HAVE_NMI_HANDLER 1052#ifdef HAVE_NMI_HANDLER
947 } else if (strcmp(preaction, "pre_nmi") == 0) { 1053 else if (strcmp(inval, "pre_nmi") == 0)
948 preaction_val = WDOG_PRETIMEOUT_NMI; 1054 preaction_val = WDOG_PRETIMEOUT_NMI;
949#endif 1055#endif
950 } else if (strcmp(preaction, "pre_int") == 0) { 1056 else if (strcmp(inval, "pre_int") == 0)
951 preaction_val = WDOG_PRETIMEOUT_MSG_INT; 1057 preaction_val = WDOG_PRETIMEOUT_MSG_INT;
952 } else { 1058 else
953 preaction_val = WDOG_PRETIMEOUT_NONE; 1059 return -EINVAL;
954 printk(KERN_INFO PFX "Unknown preaction '%s', defaulting to" 1060 strcpy(preaction, inval);
955 " none\n", preaction); 1061 return 0;
956 } 1062}
1063
1064static int preop_op(const char *inval, char *outval)
1065{
1066 if (outval)
1067 strcpy(outval, preop);
957 1068
958 if (strcmp(preop, "preop_none") == 0) { 1069 if (!inval)
1070 return 0;
1071
1072 if (strcmp(inval, "preop_none") == 0)
959 preop_val = WDOG_PREOP_NONE; 1073 preop_val = WDOG_PREOP_NONE;
960 } else if (strcmp(preop, "preop_panic") == 0) { 1074 else if (strcmp(inval, "preop_panic") == 0)
961 preop_val = WDOG_PREOP_PANIC; 1075 preop_val = WDOG_PREOP_PANIC;
962 } else if (strcmp(preop, "preop_give_data") == 0) { 1076 else if (strcmp(inval, "preop_give_data") == 0)
963 preop_val = WDOG_PREOP_GIVE_DATA; 1077 preop_val = WDOG_PREOP_GIVE_DATA;
964 } else { 1078 else
965 preop_val = WDOG_PREOP_NONE; 1079 return -EINVAL;
966 printk(KERN_INFO PFX "Unknown preop '%s', defaulting to" 1080 strcpy(preop, inval);
967 " none\n", preop); 1081 return 0;
968 } 1082}
969 1083
1084static void check_parms(void)
1085{
970#ifdef HAVE_NMI_HANDLER 1086#ifdef HAVE_NMI_HANDLER
1087 int do_nmi = 0;
1088 int rv;
1089
971 if (preaction_val == WDOG_PRETIMEOUT_NMI) { 1090 if (preaction_val == WDOG_PRETIMEOUT_NMI) {
1091 do_nmi = 1;
972 if (preop_val == WDOG_PREOP_GIVE_DATA) { 1092 if (preop_val == WDOG_PREOP_GIVE_DATA) {
973 printk(KERN_WARNING PFX "Pretimeout op is to give data" 1093 printk(KERN_WARNING PFX "Pretimeout op is to give data"
974 " but NMI pretimeout is enabled, setting" 1094 " but NMI pretimeout is enabled, setting"
975 " pretimeout op to none\n"); 1095 " pretimeout op to none\n");
976 preop_val = WDOG_PREOP_NONE; 1096 preop_op("preop_none", NULL);
1097 do_nmi = 0;
977 } 1098 }
978#ifdef CONFIG_X86_LOCAL_APIC 1099#ifdef CONFIG_X86_LOCAL_APIC
979 if (nmi_watchdog == NMI_IO_APIC) { 1100 if (nmi_watchdog == NMI_IO_APIC) {
@@ -983,18 +1104,48 @@ static int __init ipmi_wdog_init(void)
983 " Disabling IPMI nmi pretimeout.\n", 1104 " Disabling IPMI nmi pretimeout.\n",
984 nmi_watchdog); 1105 nmi_watchdog);
985 preaction_val = WDOG_PRETIMEOUT_NONE; 1106 preaction_val = WDOG_PRETIMEOUT_NONE;
986 } else { 1107 do_nmi = 0;
1108 }
987#endif 1109#endif
1110 }
1111 if (do_nmi && !nmi_handler_registered) {
988 rv = request_nmi(&ipmi_nmi_handler); 1112 rv = request_nmi(&ipmi_nmi_handler);
989 if (rv) { 1113 if (rv) {
990 printk(KERN_WARNING PFX "Can't register nmi handler\n"); 1114 printk(KERN_WARNING PFX
991 return rv; 1115 "Can't register nmi handler\n");
992 } 1116 return;
993#ifdef CONFIG_X86_LOCAL_APIC 1117 } else
994 } 1118 nmi_handler_registered = 1;
995#endif 1119 } else if (!do_nmi && nmi_handler_registered) {
1120 release_nmi(&ipmi_nmi_handler);
1121 nmi_handler_registered = 0;
996 } 1122 }
997#endif 1123#endif
1124}
1125
1126static int __init ipmi_wdog_init(void)
1127{
1128 int rv;
1129
1130 if (action_op(action, NULL)) {
1131 action_op("reset", NULL);
1132 printk(KERN_INFO PFX "Unknown action '%s', defaulting to"
1133 " reset\n", action);
1134 }
1135
1136 if (preaction_op(preaction, NULL)) {
1137 preaction_op("pre_none", NULL);
1138 printk(KERN_INFO PFX "Unknown preaction '%s', defaulting to"
1139 " none\n", preaction);
1140 }
1141
1142 if (preop_op(preop, NULL)) {
1143 preop_op("preop_none", NULL);
1144 printk(KERN_INFO PFX "Unknown preop '%s', defaulting to"
1145 " none\n", preop);
1146 }
1147
1148 check_parms();
998 1149
999 rv = ipmi_smi_watcher_register(&smi_watcher); 1150 rv = ipmi_smi_watcher_register(&smi_watcher);
1000 if (rv) { 1151 if (rv) {
@@ -1021,7 +1172,7 @@ static __exit void ipmi_unregister_watchdog(void)
1021 down_write(&register_sem); 1172 down_write(&register_sem);
1022 1173
1023#ifdef HAVE_NMI_HANDLER 1174#ifdef HAVE_NMI_HANDLER
1024 if (preaction_val == WDOG_PRETIMEOUT_NMI) 1175 if (nmi_handler_registered)
1025 release_nmi(&ipmi_nmi_handler); 1176 release_nmi(&ipmi_nmi_handler);
1026#endif 1177#endif
1027 1178
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index e3ddbdb85a2f..ce3bc0d45f1f 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -860,10 +860,9 @@ static void __exit istallion_module_exit(void)
860 if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) 860 if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
861 printk("STALLION: failed to un-register serial memory device, " 861 printk("STALLION: failed to un-register serial memory device, "
862 "errno=%d\n", -i); 862 "errno=%d\n", -i);
863 if (stli_tmpwritebuf != (char *) NULL) 863
864 kfree(stli_tmpwritebuf); 864 kfree(stli_tmpwritebuf);
865 if (stli_txcookbuf != (char *) NULL) 865 kfree(stli_txcookbuf);
866 kfree(stli_txcookbuf);
867 866
868 for (i = 0; (i < stli_nrbrds); i++) { 867 for (i = 0; (i < stli_nrbrds); i++) {
869 if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL) 868 if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL)
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
index d6c72e0934e2..cc3e54dd7234 100644
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -46,7 +46,6 @@
46* First release to the public 46* First release to the public
47*/ 47*/
48 48
49#include <linux/version.h>
50#include <linux/interrupt.h> 49#include <linux/interrupt.h>
51#include <linux/kernel.h> 50#include <linux/kernel.h>
52#include <linux/ptrace.h> 51#include <linux/ptrace.h>
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 45d012d85e8c..26448f176803 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -38,7 +38,6 @@
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/module.h> 40#include <linux/module.h>
41#include <linux/version.h>
42#include <linux/autoconf.h> 41#include <linux/autoconf.h>
43#include <linux/errno.h> 42#include <linux/errno.h>
44#include <linux/signal.h> 43#include <linux/signal.h>
@@ -470,6 +469,8 @@ static struct tty_operations mxser_ops = {
470 .stop = mxser_stop, 469 .stop = mxser_stop,
471 .start = mxser_start, 470 .start = mxser_start,
472 .hangup = mxser_hangup, 471 .hangup = mxser_hangup,
472 .break_ctl = mxser_rs_break,
473 .wait_until_sent = mxser_wait_until_sent,
473 .tiocmget = mxser_tiocmget, 474 .tiocmget = mxser_tiocmget,
474 .tiocmset = mxser_tiocmset, 475 .tiocmset = mxser_tiocmset,
475}; 476};
@@ -492,14 +493,18 @@ static int __init mxser_module_init(void)
492 493
493static void __exit mxser_module_exit(void) 494static void __exit mxser_module_exit(void)
494{ 495{
495 int i, err = 0; 496 int i, err;
496 497
497 if (verbose) 498 if (verbose)
498 printk(KERN_DEBUG "Unloading module mxser ...\n"); 499 printk(KERN_DEBUG "Unloading module mxser ...\n");
499 500
500 if ((err |= tty_unregister_driver(mxvar_sdriver))) 501 err = tty_unregister_driver(mxvar_sdriver);
502 if (!err)
503 put_tty_driver(mxvar_sdriver);
504 else
501 printk(KERN_ERR "Couldn't unregister MOXA Smartio/Industio family serial driver\n"); 505 printk(KERN_ERR "Couldn't unregister MOXA Smartio/Industio family serial driver\n");
502 506
507
503 for (i = 0; i < MXSER_BOARDS; i++) { 508 for (i = 0; i < MXSER_BOARDS; i++) {
504 struct pci_dev *pdev; 509 struct pci_dev *pdev;
505 510
@@ -688,7 +693,6 @@ static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxs
688static int mxser_init(void) 693static int mxser_init(void)
689{ 694{
690 int i, m, retval, b, n; 695 int i, m, retval, b, n;
691 int ret1;
692 struct pci_dev *pdev = NULL; 696 struct pci_dev *pdev = NULL;
693 int index; 697 int index;
694 unsigned char busnum, devnum; 698 unsigned char busnum, devnum;
@@ -722,24 +726,6 @@ static int mxser_init(void)
722 mxvar_sdriver->termios = mxvar_termios; 726 mxvar_sdriver->termios = mxvar_termios;
723 mxvar_sdriver->termios_locked = mxvar_termios_locked; 727 mxvar_sdriver->termios_locked = mxvar_termios_locked;
724 728
725 mxvar_sdriver->open = mxser_open;
726 mxvar_sdriver->close = mxser_close;
727 mxvar_sdriver->write = mxser_write;
728 mxvar_sdriver->put_char = mxser_put_char;
729 mxvar_sdriver->flush_chars = mxser_flush_chars;
730 mxvar_sdriver->write_room = mxser_write_room;
731 mxvar_sdriver->chars_in_buffer = mxser_chars_in_buffer;
732 mxvar_sdriver->flush_buffer = mxser_flush_buffer;
733 mxvar_sdriver->ioctl = mxser_ioctl;
734 mxvar_sdriver->throttle = mxser_throttle;
735 mxvar_sdriver->unthrottle = mxser_unthrottle;
736 mxvar_sdriver->set_termios = mxser_set_termios;
737 mxvar_sdriver->stop = mxser_stop;
738 mxvar_sdriver->start = mxser_start;
739 mxvar_sdriver->hangup = mxser_hangup;
740 mxvar_sdriver->break_ctl = mxser_rs_break;
741 mxvar_sdriver->wait_until_sent = mxser_wait_until_sent;
742
743 mxvar_diagflag = 0; 729 mxvar_diagflag = 0;
744 memset(mxvar_table, 0, MXSER_PORTS * sizeof(struct mxser_struct)); 730 memset(mxvar_table, 0, MXSER_PORTS * sizeof(struct mxser_struct));
745 memset(&mxvar_log, 0, sizeof(struct mxser_log)); 731 memset(&mxvar_log, 0, sizeof(struct mxser_log));
@@ -870,14 +856,11 @@ static int mxser_init(void)
870 } 856 }
871#endif 857#endif
872 858
873 ret1 = 0; 859 retval = tty_register_driver(mxvar_sdriver);
874 if (!(ret1 = tty_register_driver(mxvar_sdriver))) { 860 if (retval) {
875 return 0;
876 } else
877 printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family driver !\n"); 861 printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family driver !\n");
862 put_tty_driver(mxvar_sdriver);
878 863
879
880 if (ret1) {
881 for (i = 0; i < MXSER_BOARDS; i++) { 864 for (i = 0; i < MXSER_BOARDS; i++) {
882 if (mxsercfg[i].board_type == -1) 865 if (mxsercfg[i].board_type == -1)
883 continue; 866 continue;
@@ -886,10 +869,10 @@ static int mxser_init(void)
886 //todo: release io, vector 869 //todo: release io, vector
887 } 870 }
888 } 871 }
889 return -1; 872 return retval;
890 } 873 }
891 874
892 return (0); 875 return 0;
893} 876}
894 877
895static void mxser_do_softint(void *private_) 878static void mxser_do_softint(void *private_)
@@ -933,6 +916,9 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
933 struct mxser_struct *info; 916 struct mxser_struct *info;
934 int retval, line; 917 int retval, line;
935 918
919 /* initialize driver_data in case something fails */
920 tty->driver_data = NULL;
921
936 line = tty->index; 922 line = tty->index;
937 if (line == MXSER_PORTS) 923 if (line == MXSER_PORTS)
938 return 0; 924 return 0;
@@ -995,7 +981,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
995 if (tty->index == MXSER_PORTS) 981 if (tty->index == MXSER_PORTS)
996 return; 982 return;
997 if (!info) 983 if (!info)
998 BUG(); 984 return;
999 985
1000 spin_lock_irqsave(&info->slock, flags); 986 spin_lock_irqsave(&info->slock, flags);
1001 987
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index 5079beda69b5..c3660d8781a4 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -264,8 +264,7 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc)
264 } else 264 } else
265 break; 265 break;
266 } 266 }
267 if (n_hdlc->tbuf) 267 kfree(n_hdlc->tbuf);
268 kfree(n_hdlc->tbuf);
269 kfree(n_hdlc); 268 kfree(n_hdlc);
270 269
271} /* end of n_hdlc_release() */ 270} /* end of n_hdlc_release() */
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 02d7f046c10a..2c326ea53421 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2994,8 +2994,7 @@ int rx_alloc_buffers(MGSLPC_INFO *info)
2994 2994
2995void rx_free_buffers(MGSLPC_INFO *info) 2995void rx_free_buffers(MGSLPC_INFO *info)
2996{ 2996{
2997 if (info->rx_buf) 2997 kfree(info->rx_buf);
2998 kfree(info->rx_buf);
2999 info->rx_buf = NULL; 2998 info->rx_buf = NULL;
3000} 2999}
3001 3000
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 928b850cc679..d3bc731fbb27 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -2512,10 +2512,8 @@ static void rp_cleanup_module(void)
2512 "rocketport driver\n", -retval); 2512 "rocketport driver\n", -retval);
2513 put_tty_driver(rocket_driver); 2513 put_tty_driver(rocket_driver);
2514 2514
2515 for (i = 0; i < MAX_RP_PORTS; i++) { 2515 for (i = 0; i < MAX_RP_PORTS; i++)
2516 if (rp_table[i]) 2516 kfree(rp_table[i]);
2517 kfree(rp_table[i]);
2518 }
2519 2517
2520 for (i = 0; i < NUM_BOARDS; i++) { 2518 for (i = 0; i < NUM_BOARDS; i++) {
2521 if (rcktpt_io_addr[i] <= 0 || is_PCI[i]) 2519 if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 63fff7c1244a..a7f099fb7dfe 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -149,8 +149,22 @@ static void get_rtc_alm_time (struct rtc_time *alm_tm);
149#ifdef RTC_IRQ 149#ifdef RTC_IRQ
150static void rtc_dropped_irq(unsigned long data); 150static void rtc_dropped_irq(unsigned long data);
151 151
152static void set_rtc_irq_bit(unsigned char bit); 152static void set_rtc_irq_bit_locked(unsigned char bit);
153static void mask_rtc_irq_bit(unsigned char bit); 153static void mask_rtc_irq_bit_locked(unsigned char bit);
154
155static inline void set_rtc_irq_bit(unsigned char bit)
156{
157 spin_lock_irq(&rtc_lock);
158 set_rtc_irq_bit_locked(bit);
159 spin_unlock_irq(&rtc_lock);
160}
161
162static void mask_rtc_irq_bit(unsigned char bit)
163{
164 spin_lock_irq(&rtc_lock);
165 mask_rtc_irq_bit_locked(bit);
166 spin_unlock_irq(&rtc_lock);
167}
154#endif 168#endif
155 169
156static int rtc_proc_open(struct inode *inode, struct file *file); 170static int rtc_proc_open(struct inode *inode, struct file *file);
@@ -401,18 +415,19 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
401 } 415 }
402 case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ 416 case RTC_PIE_OFF: /* Mask periodic int. enab. bit */
403 { 417 {
404 mask_rtc_irq_bit(RTC_PIE); 418 unsigned long flags; /* can be called from isr via rtc_control() */
419 spin_lock_irqsave (&rtc_lock, flags);
420 mask_rtc_irq_bit_locked(RTC_PIE);
405 if (rtc_status & RTC_TIMER_ON) { 421 if (rtc_status & RTC_TIMER_ON) {
406 spin_lock_irq (&rtc_lock);
407 rtc_status &= ~RTC_TIMER_ON; 422 rtc_status &= ~RTC_TIMER_ON;
408 del_timer(&rtc_irq_timer); 423 del_timer(&rtc_irq_timer);
409 spin_unlock_irq (&rtc_lock);
410 } 424 }
425 spin_unlock_irqrestore (&rtc_lock, flags);
411 return 0; 426 return 0;
412 } 427 }
413 case RTC_PIE_ON: /* Allow periodic ints */ 428 case RTC_PIE_ON: /* Allow periodic ints */
414 { 429 {
415 430 unsigned long flags; /* can be called from isr via rtc_control() */
416 /* 431 /*
417 * We don't really want Joe User enabling more 432 * We don't really want Joe User enabling more
418 * than 64Hz of interrupts on a multi-user machine. 433 * than 64Hz of interrupts on a multi-user machine.
@@ -421,14 +436,14 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
421 (!capable(CAP_SYS_RESOURCE))) 436 (!capable(CAP_SYS_RESOURCE)))
422 return -EACCES; 437 return -EACCES;
423 438
439 spin_lock_irqsave (&rtc_lock, flags);
424 if (!(rtc_status & RTC_TIMER_ON)) { 440 if (!(rtc_status & RTC_TIMER_ON)) {
425 spin_lock_irq (&rtc_lock);
426 rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100; 441 rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
427 add_timer(&rtc_irq_timer); 442 add_timer(&rtc_irq_timer);
428 rtc_status |= RTC_TIMER_ON; 443 rtc_status |= RTC_TIMER_ON;
429 spin_unlock_irq (&rtc_lock);
430 } 444 }
431 set_rtc_irq_bit(RTC_PIE); 445 set_rtc_irq_bit_locked(RTC_PIE);
446 spin_unlock_irqrestore (&rtc_lock, flags);
432 return 0; 447 return 0;
433 } 448 }
434 case RTC_UIE_OFF: /* Mask ints from RTC updates. */ 449 case RTC_UIE_OFF: /* Mask ints from RTC updates. */
@@ -609,6 +624,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
609 { 624 {
610 int tmp = 0; 625 int tmp = 0;
611 unsigned char val; 626 unsigned char val;
627 unsigned long flags; /* can be called from isr via rtc_control() */
612 628
613 /* 629 /*
614 * The max we can do is 8192Hz. 630 * The max we can do is 8192Hz.
@@ -631,9 +647,9 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
631 if (arg != (1<<tmp)) 647 if (arg != (1<<tmp))
632 return -EINVAL; 648 return -EINVAL;
633 649
634 spin_lock_irq(&rtc_lock); 650 spin_lock_irqsave(&rtc_lock, flags);
635 if (hpet_set_periodic_freq(arg)) { 651 if (hpet_set_periodic_freq(arg)) {
636 spin_unlock_irq(&rtc_lock); 652 spin_unlock_irqrestore(&rtc_lock, flags);
637 return 0; 653 return 0;
638 } 654 }
639 rtc_freq = arg; 655 rtc_freq = arg;
@@ -641,7 +657,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
641 val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; 657 val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
642 val |= (16 - tmp); 658 val |= (16 - tmp);
643 CMOS_WRITE(val, RTC_FREQ_SELECT); 659 CMOS_WRITE(val, RTC_FREQ_SELECT);
644 spin_unlock_irq(&rtc_lock); 660 spin_unlock_irqrestore(&rtc_lock, flags);
645 return 0; 661 return 0;
646 } 662 }
647#endif 663#endif
@@ -844,12 +860,15 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg)
844#ifndef RTC_IRQ 860#ifndef RTC_IRQ
845 return -EIO; 861 return -EIO;
846#else 862#else
847 spin_lock_irq(&rtc_task_lock); 863 unsigned long flags;
864 if (cmd != RTC_PIE_ON && cmd != RTC_PIE_OFF && cmd != RTC_IRQP_SET)
865 return -EINVAL;
866 spin_lock_irqsave(&rtc_task_lock, flags);
848 if (rtc_callback != task) { 867 if (rtc_callback != task) {
849 spin_unlock_irq(&rtc_task_lock); 868 spin_unlock_irqrestore(&rtc_task_lock, flags);
850 return -ENXIO; 869 return -ENXIO;
851 } 870 }
852 spin_unlock_irq(&rtc_task_lock); 871 spin_unlock_irqrestore(&rtc_task_lock, flags);
853 return rtc_do_ioctl(cmd, arg, 1); 872 return rtc_do_ioctl(cmd, arg, 1);
854#endif 873#endif
855} 874}
@@ -1306,40 +1325,32 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm)
1306 * meddles with the interrupt enable/disable bits. 1325 * meddles with the interrupt enable/disable bits.
1307 */ 1326 */
1308 1327
1309static void mask_rtc_irq_bit(unsigned char bit) 1328static void mask_rtc_irq_bit_locked(unsigned char bit)
1310{ 1329{
1311 unsigned char val; 1330 unsigned char val;
1312 1331
1313 spin_lock_irq(&rtc_lock); 1332 if (hpet_mask_rtc_irq_bit(bit))
1314 if (hpet_mask_rtc_irq_bit(bit)) {
1315 spin_unlock_irq(&rtc_lock);
1316 return; 1333 return;
1317 }
1318 val = CMOS_READ(RTC_CONTROL); 1334 val = CMOS_READ(RTC_CONTROL);
1319 val &= ~bit; 1335 val &= ~bit;
1320 CMOS_WRITE(val, RTC_CONTROL); 1336 CMOS_WRITE(val, RTC_CONTROL);
1321 CMOS_READ(RTC_INTR_FLAGS); 1337 CMOS_READ(RTC_INTR_FLAGS);
1322 1338
1323 rtc_irq_data = 0; 1339 rtc_irq_data = 0;
1324 spin_unlock_irq(&rtc_lock);
1325} 1340}
1326 1341
1327static void set_rtc_irq_bit(unsigned char bit) 1342static void set_rtc_irq_bit_locked(unsigned char bit)
1328{ 1343{
1329 unsigned char val; 1344 unsigned char val;
1330 1345
1331 spin_lock_irq(&rtc_lock); 1346 if (hpet_set_rtc_irq_bit(bit))
1332 if (hpet_set_rtc_irq_bit(bit)) {
1333 spin_unlock_irq(&rtc_lock);
1334 return; 1347 return;
1335 }
1336 val = CMOS_READ(RTC_CONTROL); 1348 val = CMOS_READ(RTC_CONTROL);
1337 val |= bit; 1349 val |= bit;
1338 CMOS_WRITE(val, RTC_CONTROL); 1350 CMOS_WRITE(val, RTC_CONTROL);
1339 CMOS_READ(RTC_INTR_FLAGS); 1351 CMOS_READ(RTC_INTR_FLAGS);
1340 1352
1341 rtc_irq_data = 0; 1353 rtc_irq_data = 0;
1342 spin_unlock_irq(&rtc_lock);
1343} 1354}
1344#endif 1355#endif
1345 1356
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index 16d630f58bb4..5b187c895c18 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -246,8 +246,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
246 clear_selection(); 246 clear_selection();
247 return -ENOMEM; 247 return -ENOMEM;
248 } 248 }
249 if (sel_buffer) 249 kfree(sel_buffer);
250 kfree(sel_buffer);
251 sel_buffer = bp; 250 sel_buffer = bp;
252 251
253 obp = bp; 252 obp = bp;
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 352547eabf7b..0bbfce43031c 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -90,7 +90,6 @@
90#include <linux/fcntl.h> 90#include <linux/fcntl.h>
91#include <linux/major.h> 91#include <linux/major.h>
92#include <linux/delay.h> 92#include <linux/delay.h>
93#include <linux/version.h>
94#include <linux/pci.h> 93#include <linux/pci.h>
95#include <linux/init.h> 94#include <linux/init.h>
96#include <asm/uaccess.h> 95#include <asm/uaccess.h>
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 1c686414e0a1..95af2a941595 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -785,8 +785,7 @@ static void __exit stallion_module_exit(void)
785 "errno=%d\n", -i); 785 "errno=%d\n", -i);
786 class_destroy(stallion_class); 786 class_destroy(stallion_class);
787 787
788 if (stl_tmpwritebuf != (char *) NULL) 788 kfree(stl_tmpwritebuf);
789 kfree(stl_tmpwritebuf);
790 789
791 for (i = 0; (i < stl_nrbrds); i++) { 790 for (i = 0; (i < stl_nrbrds); i++) {
792 if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) 791 if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
@@ -804,8 +803,7 @@ static void __exit stallion_module_exit(void)
804 continue; 803 continue;
805 if (portp->tty != (struct tty_struct *) NULL) 804 if (portp->tty != (struct tty_struct *) NULL)
806 stl_hangup(portp->tty); 805 stl_hangup(portp->tty);
807 if (portp->tx.buf != (char *) NULL) 806 kfree(portp->tx.buf);
808 kfree(portp->tx.buf);
809 kfree(portp); 807 kfree(portp);
810 } 808 }
811 kfree(panelp); 809 kfree(panelp);
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 0133dc0e25d0..82c6abde68df 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -912,7 +912,6 @@ MODULE_DEVICE_TABLE(pci, synclink_pci_tbl);
912MODULE_LICENSE("GPL"); 912MODULE_LICENSE("GPL");
913 913
914static struct pci_driver synclink_pci_driver = { 914static struct pci_driver synclink_pci_driver = {
915 .owner = THIS_MODULE,
916 .name = "synclink", 915 .name = "synclink",
917 .id_table = synclink_pci_tbl, 916 .id_table = synclink_pci_tbl,
918 .probe = synclink_init_one, 917 .probe = synclink_init_one,
@@ -4016,9 +4015,7 @@ static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info)
4016 */ 4015 */
4017static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info) 4016static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info)
4018{ 4017{
4019 if ( info->intermediate_rxbuffer ) 4018 kfree(info->intermediate_rxbuffer);
4020 kfree(info->intermediate_rxbuffer);
4021
4022 info->intermediate_rxbuffer = NULL; 4019 info->intermediate_rxbuffer = NULL;
4023 4020
4024} /* end of mgsl_free_intermediate_rxbuffer_memory() */ 4021} /* end of mgsl_free_intermediate_rxbuffer_memory() */
@@ -4072,10 +4069,8 @@ static void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info)
4072 int i; 4069 int i;
4073 4070
4074 for ( i=0; i<info->num_tx_holding_buffers; ++i ) { 4071 for ( i=0; i<info->num_tx_holding_buffers; ++i ) {
4075 if ( info->tx_holding_buffers[i].buffer ) { 4072 kfree(info->tx_holding_buffers[i].buffer);
4076 kfree(info->tx_holding_buffers[i].buffer); 4073 info->tx_holding_buffers[i].buffer = NULL;
4077 info->tx_holding_buffers[i].buffer=NULL;
4078 }
4079 } 4074 }
4080 4075
4081 info->get_tx_holding_index = 0; 4076 info->get_tx_holding_index = 0;
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index f185724448b1..ee5a40be9f99 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -500,7 +500,6 @@ MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl);
500MODULE_LICENSE("GPL"); 500MODULE_LICENSE("GPL");
501 501
502static struct pci_driver synclinkmp_pci_driver = { 502static struct pci_driver synclinkmp_pci_driver = {
503 .owner = THIS_MODULE,
504 .name = "synclinkmp", 503 .name = "synclinkmp",
505 .id_table = synclinkmp_pci_tbl, 504 .id_table = synclinkmp_pci_tbl,
506 .probe = synclinkmp_init_one, 505 .probe = synclinkmp_init_one,
@@ -2788,10 +2787,8 @@ static void shutdown(SLMP_INFO * info)
2788 del_timer(&info->tx_timer); 2787 del_timer(&info->tx_timer);
2789 del_timer(&info->status_timer); 2788 del_timer(&info->status_timer);
2790 2789
2791 if (info->tx_buf) { 2790 kfree(info->tx_buf);
2792 kfree(info->tx_buf); 2791 info->tx_buf = NULL;
2793 info->tx_buf = NULL;
2794 }
2795 2792
2796 spin_lock_irqsave(&info->lock,flags); 2793 spin_lock_irqsave(&info->lock,flags);
2797 2794
@@ -3611,8 +3608,7 @@ int alloc_tmp_rx_buf(SLMP_INFO *info)
3611 3608
3612void free_tmp_rx_buf(SLMP_INFO *info) 3609void free_tmp_rx_buf(SLMP_INFO *info)
3613{ 3610{
3614 if (info->tmp_rx_buf) 3611 kfree(info->tmp_rx_buf);
3615 kfree(info->tmp_rx_buf);
3616 info->tmp_rx_buf = NULL; 3612 info->tmp_rx_buf = NULL;
3617} 3613}
3618 3614
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index feb25158c8ee..145275ebdd7e 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -354,7 +354,7 @@ struct sysrq_key_op *__sysrq_get_key_op (int key) {
354 return op_p; 354 return op_p;
355} 355}
356 356
357void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) { 357static void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p) {
358 int i; 358 int i;
359 359
360 i = sysrq_key_table_key2index(key); 360 i = sysrq_key_table_key2index(key);
@@ -419,7 +419,7 @@ void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
419 __handle_sysrq(key, pt_regs, tty, 1); 419 __handle_sysrq(key, pt_regs, tty, 1);
420} 420}
421 421
422int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, 422static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,
423 struct sysrq_key_op *remove_op_p) { 423 struct sysrq_key_op *remove_op_p) {
424 424
425 int retval; 425 int retval;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 99a60496ecc6..9293bcc4dc62 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/version.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/fs.h> 24#include <linux/fs.h>
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 8d125c974a2d..680a8e331887 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -287,10 +287,6 @@ static int __init init_nsc(void)
287 int lo, hi; 287 int lo, hi;
288 int nscAddrBase = TPM_ADDR; 288 int nscAddrBase = TPM_ADDR;
289 289
290 driver_register(&nsc_drv);
291
292 /* select PM channel 1 */
293 tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
294 290
295 /* verify that it is a National part (SID) */ 291 /* verify that it is a National part (SID) */
296 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { 292 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
@@ -300,6 +296,8 @@ static int __init init_nsc(void)
300 return -ENODEV; 296 return -ENODEV;
301 } 297 }
302 298
299 driver_register(&nsc_drv);
300
303 hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); 301 hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
304 lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); 302 lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
305 tpm_nsc.base = (hi<<8) | lo; 303 tpm_nsc.base = (hi<<8) | lo;
@@ -307,11 +305,11 @@ static int __init init_nsc(void)
307 /* enable the DPM module */ 305 /* enable the DPM module */
308 tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); 306 tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
309 307
310 pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL); 308 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
311 if ( !pdev ) 309 if (!pdev) {
312 return -ENOMEM; 310 rc = -ENOMEM;
313 311 goto err_unreg_drv;
314 memset(pdev, 0, sizeof(struct platform_device)); 312 }
315 313
316 pdev->name = "tpm_nscl0"; 314 pdev->name = "tpm_nscl0";
317 pdev->id = -1; 315 pdev->id = -1;
@@ -319,26 +317,16 @@ static int __init init_nsc(void)
319 pdev->dev.release = tpm_nsc_remove; 317 pdev->dev.release = tpm_nsc_remove;
320 pdev->dev.driver = &nsc_drv; 318 pdev->dev.driver = &nsc_drv;
321 319
322 if ((rc=platform_device_register(pdev)) < 0) { 320 if ((rc = platform_device_register(pdev)) < 0)
323 kfree(pdev); 321 goto err_free_dev;
324 pdev = NULL;
325 return rc;
326 }
327 322
328 if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) { 323 if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
329 platform_device_unregister(pdev); 324 rc = -EBUSY;
330 kfree(pdev); 325 goto err_unreg_dev;
331 pdev = NULL;
332 return -EBUSY;
333 } 326 }
334 327
335 if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) { 328 if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
336 release_region(tpm_nsc.base, 2); 329 goto err_rel_reg;
337 platform_device_unregister(pdev);
338 kfree(pdev);
339 pdev = NULL;
340 return rc;
341 }
342 330
343 dev_dbg(&pdev->dev, "NSC TPM detected\n"); 331 dev_dbg(&pdev->dev, "NSC TPM detected\n");
344 dev_dbg(&pdev->dev, 332 dev_dbg(&pdev->dev,
@@ -374,6 +362,16 @@ static int __init init_nsc(void)
374 tpm_read_index(nscAddrBase, 0x27) & 0x1F); 362 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
375 363
376 return 0; 364 return 0;
365
366err_rel_reg:
367 release_region(tpm_nsc.base, 2);
368err_unreg_dev:
369 platform_device_unregister(pdev);
370err_free_dev:
371 kfree(pdev);
372err_unreg_drv:
373 driver_unregister(&nsc_drv);
374 return rc;
377} 375}
378 376
379static void __exit cleanup_nsc(void) 377static void __exit cleanup_nsc(void)
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index c586bfa852ee..4b1eef51ec59 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1416,14 +1416,11 @@ end_init:
1416 1416
1417 /* Release locally allocated memory ... nothing placed in slots */ 1417 /* Release locally allocated memory ... nothing placed in slots */
1418free_mem_out: 1418free_mem_out:
1419 if (o_tp) 1419 kfree(o_tp);
1420 kfree(o_tp);
1421 if (o_tty) 1420 if (o_tty)
1422 free_tty_struct(o_tty); 1421 free_tty_struct(o_tty);
1423 if (ltp) 1422 kfree(ltp);
1424 kfree(ltp); 1423 kfree(tp);
1425 if (tp)
1426 kfree(tp);
1427 free_tty_struct(tty); 1424 free_tty_struct(tty);
1428 1425
1429fail_no_mem: 1426fail_no_mem:
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 98601c7d04a9..4d75c261f98a 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -26,7 +26,6 @@
26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */ 27 */
28#include <linux/config.h> 28#include <linux/config.h>
29#include <linux/version.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
32#include <linux/errno.h> 31#include <linux/errno.h>
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 867cc4e418c7..60aabdb4a046 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -32,7 +32,6 @@
32 * iseries/vio.h 32 * iseries/vio.h
33 */ 33 */
34#include <linux/config.h> 34#include <linux/config.h>
35#include <linux/version.h>
36#include <linux/module.h> 35#include <linux/module.h>
37#include <linux/kernel.h> 36#include <linux/kernel.h>
38#include <linux/errno.h> 37#include <linux/errno.h>
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 003dda147cd0..24011e7c81ff 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -80,6 +80,9 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
80 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry))) 80 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
81 return -EFAULT; 81 return -EFAULT;
82 82
83 if (!capable(CAP_SYS_TTY_CONFIG))
84 perm = 0;
85
83 switch (cmd) { 86 switch (cmd) {
84 case KDGKBENT: 87 case KDGKBENT:
85 key_map = key_maps[s]; 88 key_map = key_maps[s];
@@ -193,7 +196,7 @@ do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
193 int ret; 196 int ret;
194 197
195 if (!capable(CAP_SYS_TTY_CONFIG)) 198 if (!capable(CAP_SYS_TTY_CONFIG))
196 return -EPERM; 199 perm = 0;
197 200
198 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL); 201 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
199 if (!kbs) { 202 if (!kbs) {
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index d9ef55bdf88a..2451edbefece 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -755,7 +755,6 @@ static struct pci_device_id pcipcwd_pci_tbl[] = {
755MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl); 755MODULE_DEVICE_TABLE(pci, pcipcwd_pci_tbl);
756 756
757static struct pci_driver pcipcwd_driver = { 757static struct pci_driver pcipcwd_driver = {
758 .owner = THIS_MODULE,
759 .name = WATCHDOG_NAME, 758 .name = WATCHDOG_NAME,
760 .id_table = pcipcwd_pci_tbl, 759 .id_table = pcipcwd_pci_tbl,
761 .probe = pcipcwd_card_init, 760 .probe = pcipcwd_card_init,
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index dc9370f6c348..4b3311993d48 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -711,7 +711,6 @@ MODULE_DEVICE_TABLE(pci, wdtpci_pci_tbl);
711 711
712 712
713static struct pci_driver wdtpci_driver = { 713static struct pci_driver wdtpci_driver = {
714 .owner = THIS_MODULE,
715 .name = "wdt_pci", 714 .name = "wdt_pci",
716 .id_table = wdtpci_pci_tbl, 715 .id_table = wdtpci_pci_tbl,
717 .probe = wdtpci_init_one, 716 .probe = wdtpci_init_one,
diff --git a/drivers/connector/Kconfig b/drivers/connector/Kconfig
index 0bc2059c1e08..e0bdc0db9640 100644
--- a/drivers/connector/Kconfig
+++ b/drivers/connector/Kconfig
@@ -10,4 +10,12 @@ config CONNECTOR
10 Connector support can also be built as a module. If so, the module 10 Connector support can also be built as a module. If so, the module
11 will be called cn.ko. 11 will be called cn.ko.
12 12
13config PROC_EVENTS
14 boolean "Report process events to userspace"
15 depends on CONNECTOR=y
16 default y
17 ---help---
18 Provide a connector that reports process events to userspace. Send
19 events such as fork, exec, id change (uid, gid, suid, etc), and exit.
20
13endmenu 21endmenu
diff --git a/drivers/connector/Makefile b/drivers/connector/Makefile
index 12ca79e8234d..1f255e46e916 100644
--- a/drivers/connector/Makefile
+++ b/drivers/connector/Makefile
@@ -1,3 +1,4 @@
1obj-$(CONFIG_CONNECTOR) += cn.o 1obj-$(CONFIG_CONNECTOR) += cn.o
2obj-$(CONFIG_PROC_EVENTS) += cn_proc.o
2 3
3cn-y += cn_queue.o connector.o 4cn-y += cn_queue.o connector.o
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
new file mode 100644
index 000000000000..fcdf0fff13a6
--- /dev/null
+++ b/drivers/connector/cn_proc.c
@@ -0,0 +1,222 @@
1/*
2 * cn_proc.c - process events connector
3 *
4 * Copyright (C) Matt Helsley, IBM Corp. 2005
5 * Based on cn_fork.c by Guillaume Thouvenin <guillaume.thouvenin@bull.net>
6 * Original copyright notice follows:
7 * Copyright (C) 2005 BULL SA.
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/init.h>
28#include <asm/atomic.h>
29
30#include <linux/cn_proc.h>
31
32#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
33
34static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
35static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
36
37/* proc_counts is used as the sequence number of the netlink message */
38static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };
39
40static inline void get_seq(__u32 *ts, int *cpu)
41{
42 *ts = get_cpu_var(proc_event_counts)++;
43 *cpu = smp_processor_id();
44 put_cpu_var(proc_counts);
45}
46
47void proc_fork_connector(struct task_struct *task)
48{
49 struct cn_msg *msg;
50 struct proc_event *ev;
51 __u8 buffer[CN_PROC_MSG_SIZE];
52
53 if (atomic_read(&proc_event_num_listeners) < 1)
54 return;
55
56 msg = (struct cn_msg*)buffer;
57 ev = (struct proc_event*)msg->data;
58 get_seq(&msg->seq, &ev->cpu);
59 ev->what = PROC_EVENT_FORK;
60 ev->event_data.fork.parent_pid = task->real_parent->pid;
61 ev->event_data.fork.parent_tgid = task->real_parent->tgid;
62 ev->event_data.fork.child_pid = task->pid;
63 ev->event_data.fork.child_tgid = task->tgid;
64
65 memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
66 msg->ack = 0; /* not used */
67 msg->len = sizeof(*ev);
68 /* If cn_netlink_send() failed, the data is not sent */
69 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
70}
71
72void proc_exec_connector(struct task_struct *task)
73{
74 struct cn_msg *msg;
75 struct proc_event *ev;
76 __u8 buffer[CN_PROC_MSG_SIZE];
77
78 if (atomic_read(&proc_event_num_listeners) < 1)
79 return;
80
81 msg = (struct cn_msg*)buffer;
82 ev = (struct proc_event*)msg->data;
83 get_seq(&msg->seq, &ev->cpu);
84 ev->what = PROC_EVENT_EXEC;
85 ev->event_data.exec.process_pid = task->pid;
86 ev->event_data.exec.process_tgid = task->tgid;
87
88 memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
89 msg->ack = 0; /* not used */
90 msg->len = sizeof(*ev);
91 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
92}
93
94void proc_id_connector(struct task_struct *task, int which_id)
95{
96 struct cn_msg *msg;
97 struct proc_event *ev;
98 __u8 buffer[CN_PROC_MSG_SIZE];
99
100 if (atomic_read(&proc_event_num_listeners) < 1)
101 return;
102
103 msg = (struct cn_msg*)buffer;
104 ev = (struct proc_event*)msg->data;
105 ev->what = which_id;
106 ev->event_data.id.process_pid = task->pid;
107 ev->event_data.id.process_tgid = task->tgid;
108 if (which_id == PROC_EVENT_UID) {
109 ev->event_data.id.r.ruid = task->uid;
110 ev->event_data.id.e.euid = task->euid;
111 } else if (which_id == PROC_EVENT_GID) {
112 ev->event_data.id.r.rgid = task->gid;
113 ev->event_data.id.e.egid = task->egid;
114 } else
115 return;
116 get_seq(&msg->seq, &ev->cpu);
117
118 memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
119 msg->ack = 0; /* not used */
120 msg->len = sizeof(*ev);
121 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
122}
123
124void proc_exit_connector(struct task_struct *task)
125{
126 struct cn_msg *msg;
127 struct proc_event *ev;
128 __u8 buffer[CN_PROC_MSG_SIZE];
129
130 if (atomic_read(&proc_event_num_listeners) < 1)
131 return;
132
133 msg = (struct cn_msg*)buffer;
134 ev = (struct proc_event*)msg->data;
135 get_seq(&msg->seq, &ev->cpu);
136 ev->what = PROC_EVENT_EXIT;
137 ev->event_data.exit.process_pid = task->pid;
138 ev->event_data.exit.process_tgid = task->tgid;
139 ev->event_data.exit.exit_code = task->exit_code;
140 ev->event_data.exit.exit_signal = task->exit_signal;
141
142 memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
143 msg->ack = 0; /* not used */
144 msg->len = sizeof(*ev);
145 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
146}
147
148/*
149 * Send an acknowledgement message to userspace
150 *
151 * Use 0 for success, EFOO otherwise.
152 * Note: this is the negative of conventional kernel error
153 * values because it's not being returned via syscall return
154 * mechanisms.
155 */
156static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
157{
158 struct cn_msg *msg;
159 struct proc_event *ev;
160 __u8 buffer[CN_PROC_MSG_SIZE];
161
162 if (atomic_read(&proc_event_num_listeners) < 1)
163 return;
164
165 msg = (struct cn_msg*)buffer;
166 ev = (struct proc_event*)msg->data;
167 msg->seq = rcvd_seq;
168 ev->cpu = -1;
169 ev->what = PROC_EVENT_NONE;
170 ev->event_data.ack.err = err;
171 memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
172 msg->ack = rcvd_ack + 1;
173 msg->len = sizeof(*ev);
174 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
175}
176
177/**
178 * cn_proc_mcast_ctl
179 * @data: message sent from userspace via the connector
180 */
181static void cn_proc_mcast_ctl(void *data)
182{
183 struct cn_msg *msg = data;
184 enum proc_cn_mcast_op *mc_op = NULL;
185 int err = 0;
186
187 if (msg->len != sizeof(*mc_op))
188 return;
189
190 mc_op = (enum proc_cn_mcast_op*)msg->data;
191 switch (*mc_op) {
192 case PROC_CN_MCAST_LISTEN:
193 atomic_inc(&proc_event_num_listeners);
194 break;
195 case PROC_CN_MCAST_IGNORE:
196 atomic_dec(&proc_event_num_listeners);
197 break;
198 default:
199 err = EINVAL;
200 break;
201 }
202 cn_proc_ack(err, msg->seq, msg->ack);
203}
204
205/*
206 * cn_proc_init - initialization entry point
207 *
208 * Adds the connector callback to the connector driver.
209 */
210static int __init cn_proc_init(void)
211{
212 int err;
213
214 if ((err = cn_add_callback(&cn_proc_event_id, "cn_proc",
215 &cn_proc_mcast_ctl))) {
216 printk(KERN_WARNING "cn_proc failed to register\n");
217 return err;
218 }
219 return 0;
220}
221
222module_init(cn_proc_init);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 6c6121b85a54..23a63207d747 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -38,7 +38,6 @@ static struct cpufreq_driver *cpufreq_driver;
38static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS]; 38static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
39static DEFINE_SPINLOCK(cpufreq_driver_lock); 39static DEFINE_SPINLOCK(cpufreq_driver_lock);
40 40
41
42/* internal prototypes */ 41/* internal prototypes */
43static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); 42static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
44static void handle_update(void *data); 43static void handle_update(void *data);
@@ -593,12 +592,11 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
593 goto module_out; 592 goto module_out;
594 } 593 }
595 594
596 policy = kmalloc(sizeof(struct cpufreq_policy), GFP_KERNEL); 595 policy = kzalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
597 if (!policy) { 596 if (!policy) {
598 ret = -ENOMEM; 597 ret = -ENOMEM;
599 goto nomem_out; 598 goto nomem_out;
600 } 599 }
601 memset(policy, 0, sizeof(struct cpufreq_policy));
602 600
603 policy->cpu = cpu; 601 policy->cpu = cpu;
604 policy->cpus = cpumask_of_cpu(cpu); 602 policy->cpus = cpumask_of_cpu(cpu);
@@ -1116,24 +1114,21 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
1116 int retval = -EINVAL; 1114 int retval = -EINVAL;
1117 1115
1118 /* 1116 /*
1119 * Converted the lock_cpu_hotplug to preempt_disable() 1117 * If we are already in context of hotplug thread, we dont need to
1120 * and preempt_enable(). This is a bit kludgy and relies on how cpu 1118 * acquire the hotplug lock. Otherwise acquire cpucontrol to prevent
1121 * hotplug works. All we need is a guarantee that cpu hotplug won't make 1119 * hotplug from removing this cpu that we are working on.
1122 * progress on any cpu. Once we do preempt_disable(), this would ensure
1123 * that hotplug threads don't get onto this cpu, thereby delaying
1124 * the cpu remove process.
1125 *
1126 * We removed the lock_cpu_hotplug since we need to call this function
1127 * via cpu hotplug callbacks, which result in locking the cpu hotplug
1128 * thread itself. Agree this is not very clean, cpufreq community
1129 * could improve this if required. - Ashok Raj <ashok.raj@intel.com>
1130 */ 1120 */
1131 preempt_disable(); 1121 if (!current_in_cpu_hotplug())
1122 lock_cpu_hotplug();
1123
1132 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, 1124 dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
1133 target_freq, relation); 1125 target_freq, relation);
1134 if (cpu_online(policy->cpu) && cpufreq_driver->target) 1126 if (cpu_online(policy->cpu) && cpufreq_driver->target)
1135 retval = cpufreq_driver->target(policy, target_freq, relation); 1127 retval = cpufreq_driver->target(policy, target_freq, relation);
1136 preempt_enable(); 1128
1129 if (!current_in_cpu_hotplug())
1130 unlock_cpu_hotplug();
1131
1137 return retval; 1132 return retval;
1138} 1133}
1139EXPORT_SYMBOL_GPL(__cpufreq_driver_target); 1134EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index c1fc9c62bb51..17741111246b 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -48,7 +48,10 @@
48 * All times here are in uS. 48 * All times here are in uS.
49 */ 49 */
50static unsigned int def_sampling_rate; 50static unsigned int def_sampling_rate;
51#define MIN_SAMPLING_RATE (def_sampling_rate / 2) 51#define MIN_SAMPLING_RATE_RATIO (2)
52/* for correct statistics, we need at least 10 ticks between each measure */
53#define MIN_STAT_SAMPLING_RATE (MIN_SAMPLING_RATE_RATIO * jiffies_to_usecs(10))
54#define MIN_SAMPLING_RATE (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
52#define MAX_SAMPLING_RATE (500 * def_sampling_rate) 55#define MAX_SAMPLING_RATE (500 * def_sampling_rate)
53#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) 56#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000)
54#define DEF_SAMPLING_DOWN_FACTOR (1) 57#define DEF_SAMPLING_DOWN_FACTOR (1)
@@ -416,13 +419,16 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
416 if (dbs_enable == 1) { 419 if (dbs_enable == 1) {
417 unsigned int latency; 420 unsigned int latency;
418 /* policy latency is in nS. Convert it to uS first */ 421 /* policy latency is in nS. Convert it to uS first */
422 latency = policy->cpuinfo.transition_latency / 1000;
423 if (latency == 0)
424 latency = 1;
419 425
420 latency = policy->cpuinfo.transition_latency; 426 def_sampling_rate = latency *
421 if (latency < 1000)
422 latency = 1000;
423
424 def_sampling_rate = (latency / 1000) *
425 DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; 427 DEF_SAMPLING_RATE_LATENCY_MULTIPLIER;
428
429 if (def_sampling_rate < MIN_STAT_SAMPLING_RATE)
430 def_sampling_rate = MIN_STAT_SAMPLING_RATE;
431
426 dbs_tuners_ins.sampling_rate = def_sampling_rate; 432 dbs_tuners_ins.sampling_rate = def_sampling_rate;
427 dbs_tuners_ins.ignore_nice = 0; 433 dbs_tuners_ins.ignore_nice = 0;
428 434
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 3597f25d5efa..0bddb8e694d9 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -193,11 +193,15 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
193 unsigned int cpu = policy->cpu; 193 unsigned int cpu = policy->cpu;
194 if (cpufreq_stats_table[cpu]) 194 if (cpufreq_stats_table[cpu])
195 return -EBUSY; 195 return -EBUSY;
196 if ((stat = kmalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL) 196 if ((stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL)) == NULL)
197 return -ENOMEM; 197 return -ENOMEM;
198 memset(stat, 0, sizeof (struct cpufreq_stats));
199 198
200 data = cpufreq_cpu_get(cpu); 199 data = cpufreq_cpu_get(cpu);
200 if (data == NULL) {
201 ret = -EINVAL;
202 goto error_get_fail;
203 }
204
201 if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group))) 205 if ((ret = sysfs_create_group(&data->kobj, &stats_attr_group)))
202 goto error_out; 206 goto error_out;
203 207
@@ -217,12 +221,11 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
217 alloc_size += count * count * sizeof(int); 221 alloc_size += count * count * sizeof(int);
218#endif 222#endif
219 stat->max_state = count; 223 stat->max_state = count;
220 stat->time_in_state = kmalloc(alloc_size, GFP_KERNEL); 224 stat->time_in_state = kzalloc(alloc_size, GFP_KERNEL);
221 if (!stat->time_in_state) { 225 if (!stat->time_in_state) {
222 ret = -ENOMEM; 226 ret = -ENOMEM;
223 goto error_out; 227 goto error_out;
224 } 228 }
225 memset(stat->time_in_state, 0, alloc_size);
226 stat->freq_table = (unsigned int *)(stat->time_in_state + count); 229 stat->freq_table = (unsigned int *)(stat->time_in_state + count);
227 230
228#ifdef CONFIG_CPU_FREQ_STAT_DETAILS 231#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
@@ -245,6 +248,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy,
245 return 0; 248 return 0;
246error_out: 249error_out:
247 cpufreq_cpu_put(data); 250 cpufreq_cpu_put(data);
251error_get_fail:
248 kfree(stat); 252 kfree(stat);
249 cpufreq_stats_table[cpu] = NULL; 253 cpufreq_stats_table[cpu] = NULL;
250 return ret; 254 return ret;
diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
index a620f7d9ac8e..17502d6efae7 100644
--- a/drivers/dio/dio.c
+++ b/drivers/dio/dio.c
@@ -224,11 +224,10 @@ static int __init dio_init(void)
224 set_fs(fs); 224 set_fs(fs);
225 225
226 /* Found a board, allocate it an entry in the list */ 226 /* Found a board, allocate it an entry in the list */
227 dev = kmalloc(sizeof(struct dio_dev), GFP_KERNEL); 227 dev = kzalloc(sizeof(struct dio_dev), GFP_KERNEL);
228 if (!dev) 228 if (!dev)
229 return 0; 229 return 0;
230 230
231 memset(dev, 0, sizeof(struct dio_dev));
232 dev->bus = &dio_bus; 231 dev->bus = &dio_bus;
233 dev->dev.parent = &dio_bus.dev; 232 dev->dev.parent = &dio_bus.dev;
234 dev->dev.bus = &dio_bus_type; 233 dev->dev.bus = &dio_bus_type;
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index 1937743c8e29..4196137e66de 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -281,13 +281,11 @@ static int __init eisa_probe (struct eisa_root_device *root)
281 /* First try to get hold of slot 0. If there is no device 281 /* First try to get hold of slot 0. If there is no device
282 * here, simply fail, unless root->force_probe is set. */ 282 * here, simply fail, unless root->force_probe is set. */
283 283
284 if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL))) { 284 if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
285 printk (KERN_ERR "EISA: Couldn't allocate mainboard slot\n"); 285 printk (KERN_ERR "EISA: Couldn't allocate mainboard slot\n");
286 return -ENOMEM; 286 return -ENOMEM;
287 } 287 }
288 288
289 memset (edev, 0, sizeof (*edev));
290
291 if (eisa_request_resources (root, edev, 0)) { 289 if (eisa_request_resources (root, edev, 0)) {
292 printk (KERN_WARNING \ 290 printk (KERN_WARNING \
293 "EISA: Cannot allocate resource for mainboard\n"); 291 "EISA: Cannot allocate resource for mainboard\n");
@@ -317,13 +315,11 @@ static int __init eisa_probe (struct eisa_root_device *root)
317 force_probe: 315 force_probe:
318 316
319 for (c = 0, i = 1; i <= root->slots; i++) { 317 for (c = 0, i = 1; i <= root->slots; i++) {
320 if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL))) { 318 if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
321 printk (KERN_ERR "EISA: Out of memory for slot %d\n", 319 printk (KERN_ERR "EISA: Out of memory for slot %d\n",
322 i); 320 i);
323 continue; 321 continue;
324 } 322 }
325
326 memset (edev, 0, sizeof (*edev));
327 323
328 if (eisa_request_resources (root, edev, i)) { 324 if (eisa_request_resources (root, edev, i)) {
329 printk (KERN_WARNING \ 325 printk (KERN_WARNING \
diff --git a/drivers/fc4/fc.c b/drivers/fc4/fc.c
index e4710d1d1f9d..5c8943509cc1 100644
--- a/drivers/fc4/fc.c
+++ b/drivers/fc4/fc.c
@@ -266,13 +266,12 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status)
266 printk ("FC: Bad magic from REPORT_AL_MAP on %s - %08x\n", fc->name, p->magic); 266 printk ("FC: Bad magic from REPORT_AL_MAP on %s - %08x\n", fc->name, p->magic);
267 fc->state = FC_STATE_OFFLINE; 267 fc->state = FC_STATE_OFFLINE;
268 } else { 268 } else {
269 fc->posmap = (fcp_posmap *)kmalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL); 269 fc->posmap = (fcp_posmap *)kzalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
270 if (!fc->posmap) { 270 if (!fc->posmap) {
271 printk("FC: Not enough memory, offlining channel\n"); 271 printk("FC: Not enough memory, offlining channel\n");
272 fc->state = FC_STATE_OFFLINE; 272 fc->state = FC_STATE_OFFLINE;
273 } else { 273 } else {
274 int k; 274 int k;
275 memset(fc->posmap, 0, sizeof(fcp_posmap)+p->len);
276 /* FIXME: This is where SOCAL transfers our AL-PA. 275 /* FIXME: This is where SOCAL transfers our AL-PA.
277 Keep it here till we found out what other cards do... */ 276 Keep it here till we found out what other cards do... */
278 fc->sid = (p->magic & 0xff); 277 fc->sid = (p->magic & 0xff);
@@ -351,14 +350,12 @@ void fcp_register(fc_channel *fc, u8 type, int unregister)
351 fc->dma_scsi_rsp = fc->dma_scsi_cmd + slots * sizeof (fcp_cmd); 350 fc->dma_scsi_rsp = fc->dma_scsi_cmd + slots * sizeof (fcp_cmd);
352 fc->scsi_bitmap_end = (slots + 63) & ~63; 351 fc->scsi_bitmap_end = (slots + 63) & ~63;
353 size = fc->scsi_bitmap_end / 8; 352 size = fc->scsi_bitmap_end / 8;
354 fc->scsi_bitmap = kmalloc (size, GFP_KERNEL); 353 fc->scsi_bitmap = kzalloc (size, GFP_KERNEL);
355 memset (fc->scsi_bitmap, 0, size);
356 set_bit (0, fc->scsi_bitmap); 354 set_bit (0, fc->scsi_bitmap);
357 for (i = fc->can_queue; i < fc->scsi_bitmap_end; i++) 355 for (i = fc->can_queue; i < fc->scsi_bitmap_end; i++)
358 set_bit (i, fc->scsi_bitmap); 356 set_bit (i, fc->scsi_bitmap);
359 fc->scsi_free = fc->can_queue; 357 fc->scsi_free = fc->can_queue;
360 fc->cmd_slots = (fcp_cmnd **)kmalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL); 358 fc->cmd_slots = (fcp_cmnd **)kzalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
361 memset(fc->cmd_slots, 0, slots * sizeof(fcp_cmnd*));
362 fc->abort_count = 0; 359 fc->abort_count = 0;
363 } else { 360 } else {
364 fc->scsi_name[0] = 0; 361 fc->scsi_name[0] = 0;
@@ -541,12 +538,11 @@ int fcp_initialize(fc_channel *fcchain, int count)
541 FCND(("fcp_inititialize %08lx\n", (long)fcp_init)) 538 FCND(("fcp_inititialize %08lx\n", (long)fcp_init))
542 FCND(("fc_channels %08lx\n", (long)fc_channels)) 539 FCND(("fc_channels %08lx\n", (long)fc_channels))
543 FCND((" SID %d DID %d\n", fcchain->sid, fcchain->did)) 540 FCND((" SID %d DID %d\n", fcchain->sid, fcchain->did))
544 l = kmalloc(sizeof (ls) + count, GFP_KERNEL); 541 l = kzalloc(sizeof (ls) + count, GFP_KERNEL);
545 if (!l) { 542 if (!l) {
546 printk ("FC: Cannot allocate memory for initialization\n"); 543 printk ("FC: Cannot allocate memory for initialization\n");
547 return -ENOMEM; 544 return -ENOMEM;
548 } 545 }
549 memset (l, 0, sizeof(ls) + count);
550 l->magic = LSMAGIC; 546 l->magic = LSMAGIC;
551 l->count = count; 547 l->count = count;
552 FCND(("FCP Init for %d channels\n", count)) 548 FCND(("FCP Init for %d channels\n", count))
@@ -555,17 +551,15 @@ int fcp_initialize(fc_channel *fcchain, int count)
555 l->timer.function = fcp_login_timeout; 551 l->timer.function = fcp_login_timeout;
556 l->timer.data = (unsigned long)l; 552 l->timer.data = (unsigned long)l;
557 atomic_set (&l->todo, count); 553 atomic_set (&l->todo, count);
558 l->logi = kmalloc (count * 3 * sizeof(logi), GFP_KERNEL); 554 l->logi = kzalloc (count * 3 * sizeof(logi), GFP_KERNEL);
559 l->fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL); 555 l->fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
560 if (!l->logi || !l->fcmds) { 556 if (!l->logi || !l->fcmds) {
561 if (l->logi) kfree (l->logi); 557 kfree (l->logi);
562 if (l->fcmds) kfree (l->fcmds); 558 kfree (l->fcmds);
563 kfree (l); 559 kfree (l);
564 printk ("FC: Cannot allocate DMA memory for initialization\n"); 560 printk ("FC: Cannot allocate DMA memory for initialization\n");
565 return -ENOMEM; 561 return -ENOMEM;
566 } 562 }
567 memset (l->logi, 0, count * 3 * sizeof(logi));
568 memset (l->fcmds, 0, count * sizeof(fcp_cmnd));
569 for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) { 563 for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
570 fc->state = FC_STATE_UNINITED; 564 fc->state = FC_STATE_UNINITED;
571 fc->rst_pkt = NULL; /* kmalloc when first used */ 565 fc->rst_pkt = NULL; /* kmalloc when first used */
@@ -678,13 +672,11 @@ int fcp_forceoffline(fc_channel *fcchain, int count)
678 l.timer.function = fcp_login_timeout; 672 l.timer.function = fcp_login_timeout;
679 l.timer.data = (unsigned long)&l; 673 l.timer.data = (unsigned long)&l;
680 atomic_set (&l.todo, count); 674 atomic_set (&l.todo, count);
681 l.fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL); 675 l.fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
682 if (!l.fcmds) { 676 if (!l.fcmds) {
683 kfree (l.fcmds);
684 printk ("FC: Cannot allocate memory for forcing offline\n"); 677 printk ("FC: Cannot allocate memory for forcing offline\n");
685 return -ENOMEM; 678 return -ENOMEM;
686 } 679 }
687 memset (l.fcmds, 0, count * sizeof(fcp_cmnd));
688 FCND(("Initializing OFFLINE packets\n")) 680 FCND(("Initializing OFFLINE packets\n"))
689 for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) { 681 for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
690 fc->state = FC_STATE_UNINITED; 682 fc->state = FC_STATE_UNINITED;
@@ -1114,9 +1106,8 @@ int fc_do_plogi(fc_channel *fc, unsigned char alpa, fc_wwn *node, fc_wwn *nport)
1114 logi *l; 1106 logi *l;
1115 int status; 1107 int status;
1116 1108
1117 l = (logi *)kmalloc(2 * sizeof(logi), GFP_KERNEL); 1109 l = (logi *)kzalloc(2 * sizeof(logi), GFP_KERNEL);
1118 if (!l) return -ENOMEM; 1110 if (!l) return -ENOMEM;
1119 memset(l, 0, 2 * sizeof(logi));
1120 l->code = LS_PLOGI; 1111 l->code = LS_PLOGI;
1121 memcpy (&l->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn)); 1112 memcpy (&l->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn));
1122 memcpy (&l->node_wwn, &fc->wwn_node, sizeof(fc_wwn)); 1113 memcpy (&l->node_wwn, &fc->wwn_node, sizeof(fc_wwn));
@@ -1149,9 +1140,8 @@ int fc_do_prli(fc_channel *fc, unsigned char alpa)
1149 prli *p; 1140 prli *p;
1150 int status; 1141 int status;
1151 1142
1152 p = (prli *)kmalloc(2 * sizeof(prli), GFP_KERNEL); 1143 p = (prli *)kzalloc(2 * sizeof(prli), GFP_KERNEL);
1153 if (!p) return -ENOMEM; 1144 if (!p) return -ENOMEM;
1154 memset(p, 0, 2 * sizeof(prli));
1155 p->code = LS_PRLI; 1145 p->code = LS_PRLI;
1156 p->params[0] = 0x08002000; 1146 p->params[0] = 0x08002000;
1157 p->params[3] = 0x00000022; 1147 p->params[3] = 0x00000022;
diff --git a/drivers/fc4/soc.c b/drivers/fc4/soc.c
index 247b46302777..ec1f94738c59 100644
--- a/drivers/fc4/soc.c
+++ b/drivers/fc4/soc.c
@@ -556,10 +556,9 @@ static inline void soc_init(struct sbus_dev *sdev, int no)
556 int size, i; 556 int size, i;
557 int irq; 557 int irq;
558 558
559 s = kmalloc (sizeof (struct soc), GFP_KERNEL); 559 s = kzalloc (sizeof (struct soc), GFP_KERNEL);
560 if (s == NULL) 560 if (s == NULL)
561 return; 561 return;
562 memset (s, 0, sizeof(struct soc));
563 spin_lock_init(&s->lock); 562 spin_lock_init(&s->lock);
564 s->soc_no = no; 563 s->soc_no = no;
565 564
diff --git a/drivers/fc4/socal.c b/drivers/fc4/socal.c
index b2377dbd84a1..922e9613b2cf 100644
--- a/drivers/fc4/socal.c
+++ b/drivers/fc4/socal.c
@@ -665,9 +665,8 @@ static inline void socal_init(struct sbus_dev *sdev, int no)
665 int size, i; 665 int size, i;
666 int irq, node; 666 int irq, node;
667 667
668 s = kmalloc (sizeof (struct socal), GFP_KERNEL); 668 s = kzalloc (sizeof (struct socal), GFP_KERNEL);
669 if (!s) return; 669 if (!s) return;
670 memset (s, 0, sizeof(struct socal));
671 spin_lock_init(&s->lock); 670 spin_lock_init(&s->lock);
672 s->socal_no = no; 671 s->socal_no = no;
673 672
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 125929c9048f..6d83299e7c9b 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -34,7 +34,6 @@
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details. 35 * GNU General Public License for more details.
36 */ 36 */
37#include <linux/version.h>
38#include <linux/config.h> 37#include <linux/config.h>
39#include <linux/init.h> 38#include <linux/init.h>
40#include <linux/module.h> 39#include <linux/module.h>
@@ -50,7 +49,7 @@
50MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>"); 49MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
51MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems"); 50MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
52MODULE_LICENSE("GPL"); 51MODULE_LICENSE("GPL");
53MODULE_VERSION("3.0"); 52MODULE_VERSION("3.1");
54 53
55#define BIOS_SCAN_LIMIT 0xffffffff 54#define BIOS_SCAN_LIMIT 0xffffffff
56#define MAX_IMAGE_LENGTH 16 55#define MAX_IMAGE_LENGTH 16
@@ -73,6 +72,11 @@ module_param_string(image_type, image_type, sizeof (image_type), 0);
73MODULE_PARM_DESC(image_type, 72MODULE_PARM_DESC(image_type,
74 "BIOS image type. choose- mono or packet or init"); 73 "BIOS image type. choose- mono or packet or init");
75 74
75static unsigned long allocation_floor = 0x100000;
76module_param(allocation_floor, ulong, 0644);
77MODULE_PARM_DESC(allocation_floor,
78 "Minimum address for allocations when using Packet mode");
79
76struct packet_data { 80struct packet_data {
77 struct list_head list; 81 struct list_head list;
78 size_t length; 82 size_t length;
@@ -99,61 +103,122 @@ static int create_packet(void *data, size_t length)
99{ 103{
100 struct packet_data *newpacket; 104 struct packet_data *newpacket;
101 int ordernum = 0; 105 int ordernum = 0;
106 int retval = 0;
107 unsigned int packet_array_size = 0;
108 void **invalid_addr_packet_array = 0;
109 void *packet_data_temp_buf = 0;
110 unsigned int idx = 0;
102 111
103 pr_debug("create_packet: entry \n"); 112 pr_debug("create_packet: entry \n");
104 113
105 if (!rbu_data.packetsize) { 114 if (!rbu_data.packetsize) {
106 pr_debug("create_packet: packetsize not specified\n"); 115 pr_debug("create_packet: packetsize not specified\n");
107 return -EINVAL; 116 retval = -EINVAL;
117 goto out_noalloc;
108 } 118 }
119
109 spin_unlock(&rbu_data.lock); 120 spin_unlock(&rbu_data.lock);
110 newpacket = kmalloc(sizeof (struct packet_data), GFP_KERNEL); 121
111 spin_lock(&rbu_data.lock); 122 newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL);
112 123
113 if (!newpacket) { 124 if (!newpacket) {
114 printk(KERN_WARNING 125 printk(KERN_WARNING
115 "dell_rbu:%s: failed to allocate new " 126 "dell_rbu:%s: failed to allocate new "
116 "packet\n", __FUNCTION__); 127 "packet\n", __FUNCTION__);
117 return -ENOMEM; 128 retval = -ENOMEM;
129 spin_lock(&rbu_data.lock);
130 goto out_noalloc;
118 } 131 }
119 132
120 ordernum = get_order(length); 133 ordernum = get_order(length);
134
121 /* 135 /*
122 * there is no upper limit on memory 136 * BIOS errata mean we cannot allocate packets below 1MB or they will
123 * address for packetized mechanism 137 * be overwritten by BIOS.
138 *
139 * array to temporarily hold packets
140 * that are below the allocation floor
141 *
142 * NOTE: very simplistic because we only need the floor to be at 1MB
143 * due to BIOS errata. This shouldn't be used for higher floors
144 * or you will run out of mem trying to allocate the array.
124 */ 145 */
125 spin_unlock(&rbu_data.lock); 146 packet_array_size = max(
126 newpacket->data = (unsigned char *) __get_free_pages(GFP_KERNEL, 147 (unsigned int)(allocation_floor / rbu_data.packetsize),
127 ordernum); 148 (unsigned int)1);
128 spin_lock(&rbu_data.lock); 149 invalid_addr_packet_array = kzalloc(packet_array_size * sizeof(void*),
150 GFP_KERNEL);
129 151
130 pr_debug("create_packet: newpacket %p\n", newpacket->data); 152 if (!invalid_addr_packet_array) {
131
132 if (!newpacket->data) {
133 printk(KERN_WARNING 153 printk(KERN_WARNING
134 "dell_rbu:%s: failed to allocate new " 154 "dell_rbu:%s: failed to allocate "
135 "packet\n", __FUNCTION__); 155 "invalid_addr_packet_array \n",
136 kfree(newpacket); 156 __FUNCTION__);
137 return -ENOMEM; 157 retval = -ENOMEM;
158 spin_lock(&rbu_data.lock);
159 goto out_alloc_packet;
138 } 160 }
139 161
162 while (!packet_data_temp_buf) {
163 packet_data_temp_buf = (unsigned char *)
164 __get_free_pages(GFP_KERNEL, ordernum);
165 if (!packet_data_temp_buf) {
166 printk(KERN_WARNING
167 "dell_rbu:%s: failed to allocate new "
168 "packet\n", __FUNCTION__);
169 retval = -ENOMEM;
170 spin_lock(&rbu_data.lock);
171 goto out_alloc_packet_array;
172 }
173
174 if ((unsigned long)virt_to_phys(packet_data_temp_buf)
175 < allocation_floor) {
176 pr_debug("packet 0x%lx below floor at 0x%lx.\n",
177 (unsigned long)virt_to_phys(
178 packet_data_temp_buf),
179 allocation_floor);
180 invalid_addr_packet_array[idx++] = packet_data_temp_buf;
181 packet_data_temp_buf = 0;
182 }
183 }
184 spin_lock(&rbu_data.lock);
185
186 newpacket->data = packet_data_temp_buf;
187
188 pr_debug("create_packet: newpacket at physical addr %lx\n",
189 (unsigned long)virt_to_phys(newpacket->data));
190
191 /* packets may not have fixed size */
192 newpacket->length = length;
140 newpacket->ordernum = ordernum; 193 newpacket->ordernum = ordernum;
141 ++rbu_data.num_packets; 194 ++rbu_data.num_packets;
142 /* 195
143 * initialize the newly created packet headers 196 /* initialize the newly created packet headers */
144 */
145 INIT_LIST_HEAD(&newpacket->list); 197 INIT_LIST_HEAD(&newpacket->list);
146 list_add_tail(&newpacket->list, &packet_data_head.list); 198 list_add_tail(&newpacket->list, &packet_data_head.list);
147 /*
148 * packets may not have fixed size
149 */
150 newpacket->length = length;
151 199
152 memcpy(newpacket->data, data, length); 200 memcpy(newpacket->data, data, length);
153 201
154 pr_debug("create_packet: exit \n"); 202 pr_debug("create_packet: exit \n");
155 203
156 return 0; 204out_alloc_packet_array:
205 /* always free packet array */
206 for (;idx>0;idx--) {
207 pr_debug("freeing unused packet below floor 0x%lx.\n",
208 (unsigned long)virt_to_phys(
209 invalid_addr_packet_array[idx-1]));
210 free_pages((unsigned long)invalid_addr_packet_array[idx-1],
211 ordernum);
212 }
213 kfree(invalid_addr_packet_array);
214
215out_alloc_packet:
216 /* if error, free data */
217 if (retval)
218 kfree(newpacket);
219
220out_noalloc:
221 return retval;
157} 222}
158 223
159static int packetize_data(void *data, size_t length) 224static int packetize_data(void *data, size_t length)
@@ -693,3 +758,6 @@ static __exit void dcdrbu_exit(void)
693 758
694module_exit(dcdrbu_exit); 759module_exit(dcdrbu_exit);
695module_init(dcdrbu_init); 760module_init(dcdrbu_init);
761
762/* vim:noet:ts=8:sw=8
763*/
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 6996476669f1..b4502ed65793 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -715,7 +715,6 @@ edd_device_register(struct edd_device *edev, int i)
715 715
716 if (!edev) 716 if (!edev)
717 return 1; 717 return 1;
718 memset(edev, 0, sizeof (*edev));
719 edd_dev_set_info(edev, i); 718 edd_dev_set_info(edev, i);
720 kobject_set_name(&edev->kobj, "int13_dev%02x", 719 kobject_set_name(&edev->kobj, "int13_dev%02x",
721 0x80 + i); 720 0x80 + i);
@@ -756,7 +755,7 @@ edd_init(void)
756 return rc; 755 return rc;
757 756
758 for (i = 0; i < edd_num_devices() && !rc; i++) { 757 for (i = 0; i < edd_num_devices() && !rc; i++) {
759 edev = kmalloc(sizeof (*edev), GFP_KERNEL); 758 edev = kzalloc(sizeof (*edev), GFP_KERNEL);
760 if (!edev) 759 if (!edev)
761 return -ENOMEM; 760 return -ENOMEM;
762 761
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 33b17c6a46fb..bda5bce681b6 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -614,16 +614,14 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
614 char *short_name; 614 char *short_name;
615 struct efivar_entry *new_efivar; 615 struct efivar_entry *new_efivar;
616 616
617 short_name = kmalloc(short_name_size + 1, GFP_KERNEL); 617 short_name = kzalloc(short_name_size + 1, GFP_KERNEL);
618 new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL); 618 new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
619 619
620 if (!short_name || !new_efivar) { 620 if (!short_name || !new_efivar) {
621 kfree(short_name); 621 kfree(short_name);
622 kfree(new_efivar); 622 kfree(new_efivar);
623 return 1; 623 return 1;
624 } 624 }
625 memset(short_name, 0, short_name_size+1);
626 memset(new_efivar, 0, sizeof(struct efivar_entry));
627 625
628 memcpy(new_efivar->var.VariableName, variable_name, 626 memcpy(new_efivar->var.VariableName, variable_name,
629 variable_name_size); 627 variable_name_size);
@@ -674,14 +672,12 @@ efivars_init(void)
674 if (!efi_enabled) 672 if (!efi_enabled)
675 return -ENODEV; 673 return -ENODEV;
676 674
677 variable_name = kmalloc(variable_name_size, GFP_KERNEL); 675 variable_name = kzalloc(variable_name_size, GFP_KERNEL);
678 if (!variable_name) { 676 if (!variable_name) {
679 printk(KERN_ERR "efivars: Memory allocation failed.\n"); 677 printk(KERN_ERR "efivars: Memory allocation failed.\n");
680 return -ENOMEM; 678 return -ENOMEM;
681 } 679 }
682 680
683 memset(variable_name, 0, variable_name_size);
684
685 printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, 681 printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
686 EFIVARS_DATE); 682 EFIVARS_DATE);
687 683
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 6f48579799b5..dddd3eb9b387 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -16,6 +16,7 @@
16#include <linux/kdev_t.h> 16#include <linux/kdev_t.h>
17#include <linux/idr.h> 17#include <linux/idr.h>
18#include <linux/hwmon.h> 18#include <linux/hwmon.h>
19#include <linux/gfp.h>
19 20
20#define HWMON_ID_PREFIX "hwmon" 21#define HWMON_ID_PREFIX "hwmon"
21#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" 22#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 6a82ffae1bfd..69e7e125683b 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -193,7 +193,7 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
193 int err = 0; 193 int err = 0;
194 const char *name = ""; 194 const char *name = "";
195 u8 reg_config=0, reg_convrate=0, reg_status=0; 195 u8 reg_config=0, reg_convrate=0, reg_status=0;
196 u8 man_id, chip_id; 196
197 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 197 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
198 goto exit; 198 goto exit;
199 199
@@ -238,16 +238,15 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
238 } 238 }
239 239
240 if (kind <= 0) { /* identification */ 240 if (kind <= 0) { /* identification */
241 u8 man_id, chip_id;
241 242
242 man_id = i2c_smbus_read_byte_data(new_client, 243 man_id = i2c_smbus_read_byte_data(new_client,
243 MAX1619_REG_R_MAN_ID); 244 MAX1619_REG_R_MAN_ID);
244 chip_id = i2c_smbus_read_byte_data(new_client, 245 chip_id = i2c_smbus_read_byte_data(new_client,
245 MAX1619_REG_R_CHIP_ID); 246 MAX1619_REG_R_CHIP_ID);
246 247
247 if ((man_id == 0x4D) && (chip_id == 0x04)){ 248 if ((man_id == 0x4D) && (chip_id == 0x04))
248 kind = max1619; 249 kind = max1619;
249 }
250 }
251 250
252 if (kind <= 0) { /* identification failed */ 251 if (kind <= 0) { /* identification failed */
253 dev_info(&adapter->dev, 252 dev_info(&adapter->dev,
@@ -255,11 +254,10 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
255 "chip_id=0x%02X).\n", man_id, chip_id); 254 "chip_id=0x%02X).\n", man_id, chip_id);
256 goto exit_free; 255 goto exit_free;
257 } 256 }
258 257 }
259 258
260 if (kind == max1619){ 259 if (kind == max1619)
261 name = "max1619"; 260 name = "max1619";
262 }
263 261
264 /* We can fill in the remaining client fields */ 262 /* We can fill in the remaining client fields */
265 strlcpy(new_client->name, name, I2C_NAME_SIZE); 263 strlcpy(new_client->name, name, I2C_NAME_SIZE);
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 70ef926c3bd8..4e9a04e1f08e 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -180,11 +180,10 @@ superio_exit(void)
180#define W83781D_REG_BANK 0x4E 180#define W83781D_REG_BANK 0x4E
181 181
182#define W83781D_REG_CONFIG 0x40 182#define W83781D_REG_CONFIG 0x40
183#define W83781D_REG_ALARM1 0x41 183#define W83781D_REG_ALARM1 0x459
184#define W83781D_REG_ALARM2 0x42 184#define W83781D_REG_ALARM2 0x45A
185#define W83781D_REG_ALARM3 0x450 185#define W83781D_REG_ALARM3 0x45B
186 186
187#define W83781D_REG_IRQ 0x4C
188#define W83781D_REG_BEEP_CONFIG 0x4D 187#define W83781D_REG_BEEP_CONFIG 0x4D
189#define W83781D_REG_BEEP_INTS1 0x56 188#define W83781D_REG_BEEP_INTS1 0x56
190#define W83781D_REG_BEEP_INTS2 0x57 189#define W83781D_REG_BEEP_INTS2 0x57
@@ -1370,13 +1369,6 @@ static void w83627hf_init_client(struct i2c_client *client)
1370 W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); 1369 W83781D_REG_TEMP3_CONFIG, tmp & 0xfe);
1371 } 1370 }
1372 } 1371 }
1373
1374 /* enable comparator mode for temp2 and temp3 so
1375 alarm indication will work correctly */
1376 i = w83627hf_read_value(client, W83781D_REG_IRQ);
1377 if (!(i & 0x40))
1378 w83627hf_write_value(client, W83781D_REG_IRQ,
1379 i | 0x40);
1380 } 1372 }
1381 1373
1382 /* Start monitoring */ 1374 /* Start monitoring */
@@ -1400,7 +1392,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
1400 /* skip missing sensors */ 1392 /* skip missing sensors */
1401 if (((data->type == w83697hf) && (i == 1)) || 1393 if (((data->type == w83697hf) && (i == 1)) ||
1402 ((data->type == w83627thf || data->type == w83637hf) 1394 ((data->type == w83627thf || data->type == w83637hf)
1403 && (i == 4 || i == 5))) 1395 && (i == 5 || i == 6)))
1404 continue; 1396 continue;
1405 data->in[i] = 1397 data->in[i] =
1406 w83627hf_read_value(client, W83781D_REG_IN(i)); 1398 w83627hf_read_value(client, W83781D_REG_IN(i));
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 9265f32122fa..ffdb3a03e2b5 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -976,11 +976,9 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
976ERROR_SC_3: 976ERROR_SC_3:
977 i2c_detach_client(data->lm75[0]); 977 i2c_detach_client(data->lm75[0]);
978ERROR_SC_2: 978ERROR_SC_2:
979 if (data->lm75[1]) 979 kfree(data->lm75[1]);
980 kfree(data->lm75[1]);
981ERROR_SC_1: 980ERROR_SC_1:
982 if (data->lm75[0]) 981 kfree(data->lm75[0]);
983 kfree(data->lm75[0]);
984ERROR_SC_0: 982ERROR_SC_0:
985 return err; 983 return err;
986} 984}
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
index ba90f5140af6..3eb47890db40 100644
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -513,7 +513,6 @@ static void __devexit ali1535_remove(struct pci_dev *dev)
513} 513}
514 514
515static struct pci_driver ali1535_driver = { 515static struct pci_driver ali1535_driver = {
516 .owner = THIS_MODULE,
517 .name = "ali1535_smbus", 516 .name = "ali1535_smbus",
518 .id_table = ali1535_ids, 517 .id_table = ali1535_ids,
519 .probe = ali1535_probe, 518 .probe = ali1535_probe,
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index f1a62d892425..e6f63208fc4a 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -408,7 +408,6 @@ static struct pci_device_id __devinitdata ali1563_id_table[] = {
408MODULE_DEVICE_TABLE (pci, ali1563_id_table); 408MODULE_DEVICE_TABLE (pci, ali1563_id_table);
409 409
410static struct pci_driver ali1563_pci_driver = { 410static struct pci_driver ali1563_pci_driver = {
411 .owner = THIS_MODULE,
412 .name = "ali1563_smbus", 411 .name = "ali1563_smbus",
413 .id_table = ali1563_id_table, 412 .id_table = ali1563_id_table,
414 .probe = ali1563_probe, 413 .probe = ali1563_probe,
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
index 400b08ed4299..7a5c0941dbc1 100644
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -504,7 +504,6 @@ static void __devexit ali15x3_remove(struct pci_dev *dev)
504} 504}
505 505
506static struct pci_driver ali15x3_driver = { 506static struct pci_driver ali15x3_driver = {
507 .owner = THIS_MODULE,
508 .name = "ali15x3_smbus", 507 .name = "ali15x3_smbus",
509 .id_table = ali15x3_ids, 508 .id_table = ali15x3_ids,
510 .probe = ali15x3_probe, 509 .probe = ali15x3_probe,
diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c
index f51ab652300a..56c7d987590f 100644
--- a/drivers/i2c/busses/i2c-amd756-s4882.c
+++ b/drivers/i2c/busses/i2c-amd756-s4882.c
@@ -245,10 +245,8 @@ static void __exit amd756_s4882_exit(void)
245 kfree(s4882_adapter); 245 kfree(s4882_adapter);
246 s4882_adapter = NULL; 246 s4882_adapter = NULL;
247 } 247 }
248 if (s4882_algo) { 248 kfree(s4882_algo);
249 kfree(s4882_algo); 249 s4882_algo = NULL;
250 s4882_algo = NULL;
251 }
252 250
253 /* Restore physical bus */ 251 /* Restore physical bus */
254 if (i2c_add_adapter(&amd756_smbus)) 252 if (i2c_add_adapter(&amd756_smbus))
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index de035d137c3f..1750dedaf4b5 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -401,7 +401,6 @@ static void __devexit amd756_remove(struct pci_dev *dev)
401} 401}
402 402
403static struct pci_driver amd756_driver = { 403static struct pci_driver amd756_driver = {
404 .owner = THIS_MODULE,
405 .name = "amd756_smbus", 404 .name = "amd756_smbus",
406 .id_table = amd756_ids, 405 .id_table = amd756_ids,
407 .probe = amd756_probe, 406 .probe = amd756_probe,
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index f3b79a68dbec..e5ef560e686a 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -384,7 +384,6 @@ static void __devexit amd8111_remove(struct pci_dev *dev)
384} 384}
385 385
386static struct pci_driver amd8111_driver = { 386static struct pci_driver amd8111_driver = {
387 .owner = THIS_MODULE,
388 .name = "amd8111_smbus2", 387 .name = "amd8111_smbus2",
389 .id_table = amd8111_ids, 388 .id_table = amd8111_ids,
390 .probe = amd8111_probe, 389 .probe = amd8111_probe,
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
index 1b5354e24bf5..e0cb3b0f92fa 100644
--- a/drivers/i2c/busses/i2c-hydra.c
+++ b/drivers/i2c/busses/i2c-hydra.c
@@ -155,7 +155,6 @@ static void __devexit hydra_remove(struct pci_dev *dev)
155 155
156 156
157static struct pci_driver hydra_driver = { 157static struct pci_driver hydra_driver = {
158 .owner = THIS_MODULE,
159 .name = "hydra_smbus", 158 .name = "hydra_smbus",
160 .id_table = hydra_ids, 159 .id_table = hydra_ids,
161 .probe = hydra_probe, 160 .probe = hydra_probe,
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 4f63195069da..ac3eafa8aac0 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -560,7 +560,6 @@ static void __devexit i801_remove(struct pci_dev *dev)
560} 560}
561 561
562static struct pci_driver i801_driver = { 562static struct pci_driver i801_driver = {
563 .owner = THIS_MODULE,
564 .name = "i801_smbus", 563 .name = "i801_smbus",
565 .id_table = i801_ids, 564 .id_table = i801_ids,
566 .probe = i801_probe, 565 .probe = i801_probe,
diff --git a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
index 52bc30593bd7..748be30f2bae 100644
--- a/drivers/i2c/busses/i2c-i810.c
+++ b/drivers/i2c/busses/i2c-i810.c
@@ -233,7 +233,6 @@ static void __devexit i810_remove(struct pci_dev *dev)
233} 233}
234 234
235static struct pci_driver i810_driver = { 235static struct pci_driver i810_driver = {
236 .owner = THIS_MODULE,
237 .name = "i810_smbus", 236 .name = "i810_smbus",
238 .id_table = i810_ids, 237 .id_table = i810_ids,
239 .probe = i810_probe, 238 .probe = i810_probe,
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index fd26036e68a3..4d18e6e5f159 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -347,7 +347,6 @@ static void __devexit nforce2_remove(struct pci_dev *dev)
347} 347}
348 348
349static struct pci_driver nforce2_driver = { 349static struct pci_driver nforce2_driver = {
350 .owner = THIS_MODULE,
351 .name = "nForce2_smbus", 350 .name = "nForce2_smbus",
352 .id_table = nforce2_ids, 351 .id_table = nforce2_ids,
353 .probe = nforce2_probe, 352 .probe = nforce2_probe,
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 7d63eec423fe..692f47345481 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -462,7 +462,6 @@ static void __devexit piix4_remove(struct pci_dev *dev)
462} 462}
463 463
464static struct pci_driver piix4_driver = { 464static struct pci_driver piix4_driver = {
465 .owner = THIS_MODULE,
466 .name = "piix4_smbus", 465 .name = "piix4_smbus",
467 .id_table = piix4_ids, 466 .id_table = piix4_ids,
468 .probe = piix4_probe, 467 .probe = piix4_probe,
diff --git a/drivers/i2c/busses/i2c-prosavage.c b/drivers/i2c/busses/i2c-prosavage.c
index 42cb1d8ca659..9479525892e3 100644
--- a/drivers/i2c/busses/i2c-prosavage.c
+++ b/drivers/i2c/busses/i2c-prosavage.c
@@ -301,7 +301,6 @@ static struct pci_device_id prosavage_pci_tbl[] = {
301MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl); 301MODULE_DEVICE_TABLE (pci, prosavage_pci_tbl);
302 302
303static struct pci_driver prosavage_driver = { 303static struct pci_driver prosavage_driver = {
304 .owner = THIS_MODULE,
305 .name = "prosavage_smbus", 304 .name = "prosavage_smbus",
306 .id_table = prosavage_pci_tbl, 305 .id_table = prosavage_pci_tbl,
307 .probe = prosavage_probe, 306 .probe = prosavage_probe,
diff --git a/drivers/i2c/busses/i2c-savage4.c b/drivers/i2c/busses/i2c-savage4.c
index aebe87ba4033..0c8518298e4d 100644
--- a/drivers/i2c/busses/i2c-savage4.c
+++ b/drivers/i2c/busses/i2c-savage4.c
@@ -179,7 +179,6 @@ static void __devexit savage4_remove(struct pci_dev *dev)
179} 179}
180 180
181static struct pci_driver savage4_driver = { 181static struct pci_driver savage4_driver = {
182 .owner = THIS_MODULE,
183 .name = "savage4_smbus", 182 .name = "savage4_smbus",
184 .id_table = savage4_ids, 183 .id_table = savage4_ids,
185 .probe = savage4_probe, 184 .probe = savage4_probe,
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 3ad27c3ba15b..b57ab74d23ec 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -398,7 +398,6 @@ static void __devexit sis5595_remove(struct pci_dev *dev)
398} 398}
399 399
400static struct pci_driver sis5595_driver = { 400static struct pci_driver sis5595_driver = {
401 .owner = THIS_MODULE,
402 .name = "sis5595_smbus", 401 .name = "sis5595_smbus",
403 .id_table = sis5595_ids, 402 .id_table = sis5595_ids,
404 .probe = sis5595_probe, 403 .probe = sis5595_probe,
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
index 7f49e5fd3ff0..acb75e282414 100644
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -496,7 +496,6 @@ static void __devexit sis630_remove(struct pci_dev *dev)
496 496
497 497
498static struct pci_driver sis630_driver = { 498static struct pci_driver sis630_driver = {
499 .owner = THIS_MODULE,
500 .name = "sis630_smbus", 499 .name = "sis630_smbus",
501 .id_table = sis630_ids, 500 .id_table = sis630_ids,
502 .probe = sis630_probe, 501 .probe = sis630_probe,
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index 6a134c091324..3024907cdafe 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -329,7 +329,6 @@ static void __devexit sis96x_remove(struct pci_dev *dev)
329} 329}
330 330
331static struct pci_driver sis96x_driver = { 331static struct pci_driver sis96x_driver = {
332 .owner = THIS_MODULE,
333 .name = "sis96x_smbus", 332 .name = "sis96x_smbus",
334 .id_table = sis96x_ids, 333 .id_table = sis96x_ids,
335 .probe = sis96x_probe, 334 .probe = sis96x_probe,
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index 544a38e64394..484bbacfce6b 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -159,7 +159,6 @@ static void __devexit vt586b_remove(struct pci_dev *dev)
159 159
160 160
161static struct pci_driver vt586b_driver = { 161static struct pci_driver vt586b_driver = {
162 .owner = THIS_MODULE,
163 .name = "vt586b_smbus", 162 .name = "vt586b_smbus",
164 .id_table = vt586b_ids, 163 .id_table = vt586b_ids,
165 .probe = vt586b_probe, 164 .probe = vt586b_probe,
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index c9366b504833..47e52bf2c5ec 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -142,19 +142,18 @@ static int vt596_transaction(u8 size)
142 /* Make sure the SMBus host is ready to start transmitting */ 142 /* Make sure the SMBus host is ready to start transmitting */
143 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 143 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
144 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). " 144 dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
145 "Resetting... ", temp); 145 "Resetting...\n", temp);
146 146
147 outb_p(temp, SMBHSTSTS); 147 outb_p(temp, SMBHSTSTS);
148 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) { 148 if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
149 printk("Failed! (0x%02x)\n", temp); 149 dev_err(&vt596_adapter.dev, "SMBus reset failed! "
150 "(0x%02x)\n", temp);
150 return -1; 151 return -1;
151 } else {
152 printk("Successful!\n");
153 } 152 }
154 } 153 }
155 154
156 /* Start the transaction by setting bit 6 */ 155 /* Start the transaction by setting bit 6 */
157 outb_p(0x40 | (size & 0x3C), SMBHSTCNT); 156 outb_p(0x40 | size, SMBHSTCNT);
158 157
159 /* We will always wait for a fraction of a second */ 158 /* We will always wait for a fraction of a second */
160 do { 159 do {
@@ -171,7 +170,7 @@ static int vt596_transaction(u8 size)
171 if (temp & 0x10) { 170 if (temp & 0x10) {
172 result = -1; 171 result = -1;
173 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n", 172 dev_err(&vt596_adapter.dev, "Transaction failed (0x%02x)\n",
174 inb_p(SMBHSTCNT) & 0x3C); 173 size);
175 } 174 }
176 175
177 if (temp & 0x08) { 176 if (temp & 0x08) {
@@ -180,11 +179,13 @@ static int vt596_transaction(u8 size)
180 } 179 }
181 180
182 if (temp & 0x04) { 181 if (temp & 0x04) {
182 int read = inb_p(SMBHSTADD) & 0x01;
183 result = -1; 183 result = -1;
184 /* Quick commands are used to probe for chips, so 184 /* The quick and receive byte commands are used to probe
185 errors are expected, and we don't want to frighten the 185 for chips, so errors are expected, and we don't want
186 user. */ 186 to frighten the user. */
187 if ((inb_p(SMBHSTCNT) & 0x3C) != VT596_QUICK) 187 if (!((size == VT596_QUICK && !read) ||
188 (size == VT596_BYTE && read)))
188 dev_err(&vt596_adapter.dev, "Transaction error!\n"); 189 dev_err(&vt596_adapter.dev, "Transaction error!\n");
189 } 190 }
190 191
@@ -439,7 +440,6 @@ static struct pci_device_id vt596_ids[] = {
439MODULE_DEVICE_TABLE(pci, vt596_ids); 440MODULE_DEVICE_TABLE(pci, vt596_ids);
440 441
441static struct pci_driver vt596_driver = { 442static struct pci_driver vt596_driver = {
442 .owner = THIS_MODULE,
443 .name = "vt596_smbus", 443 .name = "vt596_smbus",
444 .id_table = vt596_ids, 444 .id_table = vt596_ids,
445 .probe = vt596_probe, 445 .probe = vt596_probe,
@@ -462,9 +462,9 @@ static void __exit i2c_vt596_exit(void)
462 } 462 }
463} 463}
464 464
465MODULE_AUTHOR( 465MODULE_AUTHOR("Kyosti Malkki <kmalkki@cc.hut.fi>, "
466 "Frodo Looijaard <frodol@dds.nl> and " 466 "Mark D. Studebaker <mdsxyz123@yahoo.com> and "
467 "Philip Edelbrock <phil@netroedge.com>"); 467 "Jean Delvare <khali@linux-fr.org>");
468MODULE_DESCRIPTION("vt82c596 SMBus driver"); 468MODULE_DESCRIPTION("vt82c596 SMBus driver");
469MODULE_LICENSE("GPL"); 469MODULE_LICENSE("GPL");
470 470
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
index 650c3ebde84c..b675773b0cc1 100644
--- a/drivers/i2c/busses/i2c-voodoo3.c
+++ b/drivers/i2c/busses/i2c-voodoo3.c
@@ -225,7 +225,6 @@ static void __devexit voodoo3_remove(struct pci_dev *dev)
225} 225}
226 226
227static struct pci_driver voodoo3_driver = { 227static struct pci_driver voodoo3_driver = {
228 .owner = THIS_MODULE,
229 .name = "voodoo3_smbus", 228 .name = "voodoo3_smbus",
230 .id_table = voodoo3_ids, 229 .id_table = voodoo3_ids,
231 .probe = voodoo3_probe, 230 .probe = voodoo3_probe,
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
index 01b037007410..02682fb794c8 100644
--- a/drivers/i2c/chips/ds1337.c
+++ b/drivers/i2c/chips/ds1337.c
@@ -164,9 +164,9 @@ static int ds1337_set_datetime(struct i2c_client *client, struct rtc_time *dt)
164 buf[1] = BIN2BCD(dt->tm_sec); 164 buf[1] = BIN2BCD(dt->tm_sec);
165 buf[2] = BIN2BCD(dt->tm_min); 165 buf[2] = BIN2BCD(dt->tm_min);
166 buf[3] = BIN2BCD(dt->tm_hour); 166 buf[3] = BIN2BCD(dt->tm_hour);
167 buf[4] = BIN2BCD(dt->tm_wday) + 1; 167 buf[4] = BIN2BCD(dt->tm_wday + 1);
168 buf[5] = BIN2BCD(dt->tm_mday); 168 buf[5] = BIN2BCD(dt->tm_mday);
169 buf[6] = BIN2BCD(dt->tm_mon) + 1; 169 buf[6] = BIN2BCD(dt->tm_mon + 1);
170 val = dt->tm_year; 170 val = dt->tm_year;
171 if (val >= 100) { 171 if (val >= 100) {
172 val -= 100; 172 val -= 100;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index a737886e39d1..42e5b8175cbf 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -539,6 +539,15 @@ config BLK_DEV_CS5530
539 539
540 It is safe to say Y to this question. 540 It is safe to say Y to this question.
541 541
542config BLK_DEV_CS5535
543 tristate "AMD CS5535 chipset support"
544 depends on X86 && !X86_64
545 help
546 Include support for UDMA on the NSC/AMD CS5535 companion chipset.
547 This will automatically be detected and configured if found.
548
549 It is safe to say Y to this question.
550
542config BLK_DEV_HPT34X 551config BLK_DEV_HPT34X
543 tristate "HPT34X chipset support" 552 tristate "HPT34X chipset support"
544 help 553 help
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 8b9d85526596..c2f47923d174 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3292,12 +3292,9 @@ static void ide_cd_release(struct kref *kref)
3292 ide_drive_t *drive = info->drive; 3292 ide_drive_t *drive = info->drive;
3293 struct gendisk *g = info->disk; 3293 struct gendisk *g = info->disk;
3294 3294
3295 if (info->buffer != NULL) 3295 kfree(info->buffer);
3296 kfree(info->buffer); 3296 kfree(info->toc);
3297 if (info->toc != NULL) 3297 kfree(info->changer_info);
3298 kfree(info->toc);
3299 if (info->changer_info != NULL)
3300 kfree(info->changer_info);
3301 if (devinfo->handle == drive && unregister_cdrom(devinfo)) 3298 if (devinfo->handle == drive && unregister_cdrom(devinfo))
3302 printk(KERN_ERR "%s: %s failed to unregister device from the cdrom " 3299 printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
3303 "driver.\n", __FUNCTION__, drive->name); 3300 "driver.\n", __FUNCTION__, drive->name);
@@ -3455,7 +3452,7 @@ static int ide_cd_probe(struct device *dev)
3455 printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name); 3452 printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
3456 goto failed; 3453 goto failed;
3457 } 3454 }
3458 info = kmalloc(sizeof(struct cdrom_info), GFP_KERNEL); 3455 info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
3459 if (info == NULL) { 3456 if (info == NULL) {
3460 printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name); 3457 printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
3461 goto failed; 3458 goto failed;
@@ -3469,8 +3466,6 @@ static int ide_cd_probe(struct device *dev)
3469 3466
3470 ide_register_subdriver(drive, &ide_cdrom_driver); 3467 ide_register_subdriver(drive, &ide_cdrom_driver);
3471 3468
3472 memset(info, 0, sizeof (struct cdrom_info));
3473
3474 kref_init(&info->kref); 3469 kref_init(&info->kref);
3475 3470
3476 info->drive = drive; 3471 info->drive = drive;
@@ -3489,12 +3484,9 @@ static int ide_cd_probe(struct device *dev)
3489 if (ide_cdrom_setup(drive)) { 3484 if (ide_cdrom_setup(drive)) {
3490 struct cdrom_device_info *devinfo = &info->devinfo; 3485 struct cdrom_device_info *devinfo = &info->devinfo;
3491 ide_unregister_subdriver(drive, &ide_cdrom_driver); 3486 ide_unregister_subdriver(drive, &ide_cdrom_driver);
3492 if (info->buffer != NULL) 3487 kfree(info->buffer);
3493 kfree(info->buffer); 3488 kfree(info->toc);
3494 if (info->toc != NULL) 3489 kfree(info->changer_info);
3495 kfree(info->toc);
3496 if (info->changer_info != NULL)
3497 kfree(info->changer_info);
3498 if (devinfo->handle == drive && unregister_cdrom(devinfo)) 3490 if (devinfo->handle == drive && unregister_cdrom(devinfo))
3499 printk (KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name); 3491 printk (KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
3500 kfree(info); 3492 kfree(info);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 234f5de3e929..e827b39e4b3c 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1215,7 +1215,7 @@ static int ide_disk_probe(struct device *dev)
1215 if (drive->media != ide_disk) 1215 if (drive->media != ide_disk)
1216 goto failed; 1216 goto failed;
1217 1217
1218 idkp = kmalloc(sizeof(*idkp), GFP_KERNEL); 1218 idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
1219 if (!idkp) 1219 if (!idkp)
1220 goto failed; 1220 goto failed;
1221 1221
@@ -1228,8 +1228,6 @@ static int ide_disk_probe(struct device *dev)
1228 1228
1229 ide_register_subdriver(drive, &idedisk_driver); 1229 ide_register_subdriver(drive, &idedisk_driver);
1230 1230
1231 memset(idkp, 0, sizeof(*idkp));
1232
1233 kref_init(&idkp->kref); 1231 kref_init(&idkp->kref);
1234 1232
1235 idkp->drive = drive; 1233 idkp->drive = drive;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 29c22fc278c6..f615ab759962 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2038,11 +2038,9 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2038 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); 2038 struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
2039 ide_drive_t *drive = floppy->drive; 2039 ide_drive_t *drive = floppy->drive;
2040 void __user *argp = (void __user *)arg; 2040 void __user *argp = (void __user *)arg;
2041 int err = generic_ide_ioctl(drive, file, bdev, cmd, arg); 2041 int err;
2042 int prevent = (arg) ? 1 : 0; 2042 int prevent = (arg) ? 1 : 0;
2043 idefloppy_pc_t pc; 2043 idefloppy_pc_t pc;
2044 if (err != -EINVAL)
2045 return err;
2046 2044
2047 switch (cmd) { 2045 switch (cmd) {
2048 case CDROMEJECT: 2046 case CDROMEJECT:
@@ -2094,7 +2092,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2094 case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS: 2092 case IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS:
2095 return idefloppy_get_format_progress(drive, argp); 2093 return idefloppy_get_format_progress(drive, argp);
2096 } 2094 }
2097 return -EINVAL; 2095 return generic_ide_ioctl(drive, file, bdev, cmd, arg);
2098} 2096}
2099 2097
2100static int idefloppy_media_changed(struct gendisk *disk) 2098static int idefloppy_media_changed(struct gendisk *disk)
@@ -2146,7 +2144,7 @@ static int ide_floppy_probe(struct device *dev)
2146 printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name); 2144 printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);
2147 goto failed; 2145 goto failed;
2148 } 2146 }
2149 if ((floppy = (idefloppy_floppy_t *) kmalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) { 2147 if ((floppy = (idefloppy_floppy_t *) kzalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
2150 printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name); 2148 printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
2151 goto failed; 2149 goto failed;
2152 } 2150 }
@@ -2159,8 +2157,6 @@ static int ide_floppy_probe(struct device *dev)
2159 2157
2160 ide_register_subdriver(drive, &idefloppy_driver); 2158 ide_register_subdriver(drive, &idefloppy_driver);
2161 2159
2162 memset(floppy, 0, sizeof(*floppy));
2163
2164 kref_init(&floppy->kref); 2160 kref_init(&floppy->kref);
2165 2161
2166 floppy->drive = drive; 2162 floppy->drive = drive;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 0b0aa4f51628..af7af958ab3e 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -104,8 +104,6 @@ void default_hwif_iops (ide_hwif_t *hwif)
104 hwif->INSL = ide_insl; 104 hwif->INSL = ide_insl;
105} 105}
106 106
107EXPORT_SYMBOL(default_hwif_iops);
108
109/* 107/*
110 * MMIO operations, typically used for SATA controllers 108 * MMIO operations, typically used for SATA controllers
111 */ 109 */
@@ -329,8 +327,6 @@ void default_hwif_transport(ide_hwif_t *hwif)
329 hwif->atapi_output_bytes = atapi_output_bytes; 327 hwif->atapi_output_bytes = atapi_output_bytes;
330} 328}
331 329
332EXPORT_SYMBOL(default_hwif_transport);
333
334/* 330/*
335 * Beginning of Taskfile OPCODE Library and feature sets. 331 * Beginning of Taskfile OPCODE Library and feature sets.
336 */ 332 */
@@ -529,8 +525,6 @@ int wait_for_ready (ide_drive_t *drive, int timeout)
529 return 0; 525 return 0;
530} 526}
531 527
532EXPORT_SYMBOL(wait_for_ready);
533
534/* 528/*
535 * This routine busy-waits for the drive status to be not "busy". 529 * This routine busy-waits for the drive status to be not "busy".
536 * It then checks the status for all of the "good" bits and none 530 * It then checks the status for all of the "good" bits and none
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index c1128ae5cd2f..02167a5b751d 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -596,14 +596,13 @@ static inline u8 probe_for_drive (ide_drive_t *drive)
596 * Also note that 0 everywhere means "can't do X" 596 * Also note that 0 everywhere means "can't do X"
597 */ 597 */
598 598
599 drive->id = kmalloc(SECTOR_WORDS *4, GFP_KERNEL); 599 drive->id = kzalloc(SECTOR_WORDS *4, GFP_KERNEL);
600 drive->id_read = 0; 600 drive->id_read = 0;
601 if(drive->id == NULL) 601 if(drive->id == NULL)
602 { 602 {
603 printk(KERN_ERR "ide: out of memory for id data.\n"); 603 printk(KERN_ERR "ide: out of memory for id data.\n");
604 return 0; 604 return 0;
605 } 605 }
606 memset(drive->id, 0, SECTOR_WORDS * 4);
607 strcpy(drive->id->model, "UNKNOWN"); 606 strcpy(drive->id->model, "UNKNOWN");
608 607
609 /* skip probing? */ 608 /* skip probing? */
@@ -1316,10 +1315,8 @@ static void drive_release_dev (struct device *dev)
1316 drive->devfs_name[0] = '\0'; 1315 drive->devfs_name[0] = '\0';
1317 } 1316 }
1318 ide_remove_drive_from_hwgroup(drive); 1317 ide_remove_drive_from_hwgroup(drive);
1319 if (drive->id != NULL) { 1318 kfree(drive->id);
1320 kfree(drive->id); 1319 drive->id = NULL;
1321 drive->id = NULL;
1322 }
1323 drive->present = 0; 1320 drive->present = 0;
1324 /* Messed up locking ... */ 1321 /* Messed up locking ... */
1325 spin_unlock_irq(&ide_lock); 1322 spin_unlock_irq(&ide_lock);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 47f2b832555f..0ac7eb8f40d5 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -4850,7 +4850,7 @@ static int ide_tape_probe(struct device *dev)
4850 printk(KERN_WARNING "ide-tape: Use drive %s with ide-scsi emulation and osst.\n", drive->name); 4850 printk(KERN_WARNING "ide-tape: Use drive %s with ide-scsi emulation and osst.\n", drive->name);
4851 printk(KERN_WARNING "ide-tape: OnStream support will be removed soon from ide-tape!\n"); 4851 printk(KERN_WARNING "ide-tape: OnStream support will be removed soon from ide-tape!\n");
4852 } 4852 }
4853 tape = (idetape_tape_t *) kmalloc (sizeof (idetape_tape_t), GFP_KERNEL); 4853 tape = (idetape_tape_t *) kzalloc (sizeof (idetape_tape_t), GFP_KERNEL);
4854 if (tape == NULL) { 4854 if (tape == NULL) {
4855 printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name); 4855 printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name);
4856 goto failed; 4856 goto failed;
@@ -4864,8 +4864,6 @@ static int ide_tape_probe(struct device *dev)
4864 4864
4865 ide_register_subdriver(drive, &idetape_driver); 4865 ide_register_subdriver(drive, &idetape_driver);
4866 4866
4867 memset(tape, 0, sizeof(*tape));
4868
4869 kref_init(&tape->kref); 4867 kref_init(&tape->kref);
4870 4868
4871 tape->drive = drive; 4869 tape->drive = drive;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index ace8edad6e96..54f9639c2a8c 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -161,8 +161,6 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
161 return ide_stopped; 161 return ide_stopped;
162} 162}
163 163
164EXPORT_SYMBOL(do_rw_taskfile);
165
166/* 164/*
167 * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd. 165 * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
168 */ 166 */
@@ -528,9 +526,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
528 526
529// printk("IDE Taskfile ...\n"); 527// printk("IDE Taskfile ...\n");
530 528
531 req_task = kmalloc(tasksize, GFP_KERNEL); 529 req_task = kzalloc(tasksize, GFP_KERNEL);
532 if (req_task == NULL) return -ENOMEM; 530 if (req_task == NULL) return -ENOMEM;
533 memset(req_task, 0, tasksize);
534 if (copy_from_user(req_task, buf, tasksize)) { 531 if (copy_from_user(req_task, buf, tasksize)) {
535 kfree(req_task); 532 kfree(req_task);
536 return -EFAULT; 533 return -EFAULT;
@@ -541,12 +538,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
541 538
542 if (taskout) { 539 if (taskout) {
543 int outtotal = tasksize; 540 int outtotal = tasksize;
544 outbuf = kmalloc(taskout, GFP_KERNEL); 541 outbuf = kzalloc(taskout, GFP_KERNEL);
545 if (outbuf == NULL) { 542 if (outbuf == NULL) {
546 err = -ENOMEM; 543 err = -ENOMEM;
547 goto abort; 544 goto abort;
548 } 545 }
549 memset(outbuf, 0, taskout);
550 if (copy_from_user(outbuf, buf + outtotal, taskout)) { 546 if (copy_from_user(outbuf, buf + outtotal, taskout)) {
551 err = -EFAULT; 547 err = -EFAULT;
552 goto abort; 548 goto abort;
@@ -555,12 +551,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
555 551
556 if (taskin) { 552 if (taskin) {
557 int intotal = tasksize + taskout; 553 int intotal = tasksize + taskout;
558 inbuf = kmalloc(taskin, GFP_KERNEL); 554 inbuf = kzalloc(taskin, GFP_KERNEL);
559 if (inbuf == NULL) { 555 if (inbuf == NULL) {
560 err = -ENOMEM; 556 err = -ENOMEM;
561 goto abort; 557 goto abort;
562 } 558 }
563 memset(inbuf, 0, taskin);
564 if (copy_from_user(inbuf, buf + intotal, taskin)) { 559 if (copy_from_user(inbuf, buf + intotal, taskin)) {
565 err = -EFAULT; 560 err = -EFAULT;
566 goto abort; 561 goto abort;
@@ -649,10 +644,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
649 } 644 }
650abort: 645abort:
651 kfree(req_task); 646 kfree(req_task);
652 if (outbuf != NULL) 647 kfree(outbuf);
653 kfree(outbuf); 648 kfree(inbuf);
654 if (inbuf != NULL)
655 kfree(inbuf);
656 649
657// printk("IDE Taskfile ioctl ended. rc = %i\n", err); 650// printk("IDE Taskfile ioctl ended. rc = %i\n", err);
658 651
@@ -709,10 +702,9 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
709 702
710 if (args[3]) { 703 if (args[3]) {
711 argsize = 4 + (SECTOR_WORDS * 4 * args[3]); 704 argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
712 argbuf = kmalloc(argsize, GFP_KERNEL); 705 argbuf = kzalloc(argsize, GFP_KERNEL);
713 if (argbuf == NULL) 706 if (argbuf == NULL)
714 return -ENOMEM; 707 return -ENOMEM;
715 memcpy(argbuf, args, 4);
716 } 708 }
717 if (set_transfer(drive, &tfargs)) { 709 if (set_transfer(drive, &tfargs)) {
718 xfer_rate = args[1]; 710 xfer_rate = args[1];
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 73ca8f73917d..8af179b531c3 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -803,6 +803,7 @@ found:
803 hwif->irq = hw->irq; 803 hwif->irq = hw->irq;
804 hwif->noprobe = 0; 804 hwif->noprobe = 0;
805 hwif->chipset = hw->chipset; 805 hwif->chipset = hw->chipset;
806 hwif->gendev.parent = hw->dev;
806 807
807 if (!initializing) { 808 if (!initializing) {
808 probe_hwif_init_with_fixup(hwif, fixup); 809 probe_hwif_init_with_fixup(hwif, fixup);
@@ -864,9 +865,8 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int r
864 down(&ide_setting_sem); 865 down(&ide_setting_sem);
865 while ((*p) && strcmp((*p)->name, name) < 0) 866 while ((*p) && strcmp((*p)->name, name) < 0)
866 p = &((*p)->next); 867 p = &((*p)->next);
867 if ((setting = kmalloc(sizeof(*setting), GFP_KERNEL)) == NULL) 868 if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
868 goto abort; 869 goto abort;
869 memset(setting, 0, sizeof(*setting));
870 if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL) 870 if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL)
871 goto abort; 871 goto abort;
872 strcpy(setting->name, name); 872 strcpy(setting->name, name);
@@ -889,8 +889,7 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int r
889 return 0; 889 return 0;
890abort: 890abort:
891 up(&ide_setting_sem); 891 up(&ide_setting_sem);
892 if (setting) 892 kfree(setting);
893 kfree(setting);
894 return -1; 893 return -1;
895} 894}
896 895
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index a35a58bef1a4..ef79805218e4 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -116,9 +116,8 @@ static dev_link_t *ide_attach(void)
116 DEBUG(0, "ide_attach()\n"); 116 DEBUG(0, "ide_attach()\n");
117 117
118 /* Create new ide device */ 118 /* Create new ide device */
119 info = kmalloc(sizeof(*info), GFP_KERNEL); 119 info = kzalloc(sizeof(*info), GFP_KERNEL);
120 if (!info) return NULL; 120 if (!info) return NULL;
121 memset(info, 0, sizeof(*info));
122 link = &info->link; link->priv = info; 121 link = &info->link; link->priv = info;
123 122
124 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 123 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -183,13 +182,14 @@ static void ide_detach(dev_link_t *link)
183 182
184} /* ide_detach */ 183} /* ide_detach */
185 184
186static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq) 185static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
187{ 186{
188 hw_regs_t hw; 187 hw_regs_t hw;
189 memset(&hw, 0, sizeof(hw)); 188 memset(&hw, 0, sizeof(hw));
190 ide_init_hwif_ports(&hw, io, ctl, NULL); 189 ide_init_hwif_ports(&hw, io, ctl, NULL);
191 hw.irq = irq; 190 hw.irq = irq;
192 hw.chipset = ide_pci; 191 hw.chipset = ide_pci;
192 hw.dev = &handle->dev;
193 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); 193 return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
194} 194}
195 195
@@ -221,9 +221,8 @@ static void ide_config(dev_link_t *link)
221 221
222 DEBUG(0, "ide_config(0x%p)\n", link); 222 DEBUG(0, "ide_config(0x%p)\n", link);
223 223
224 stk = kmalloc(sizeof(*stk), GFP_KERNEL); 224 stk = kzalloc(sizeof(*stk), GFP_KERNEL);
225 if (!stk) goto err_mem; 225 if (!stk) goto err_mem;
226 memset(stk, 0, sizeof(*stk));
227 cfg = &stk->parse.cftable_entry; 226 cfg = &stk->parse.cftable_entry;
228 227
229 tuple.TupleData = (cisdata_t *)&stk->buf; 228 tuple.TupleData = (cisdata_t *)&stk->buf;
@@ -329,12 +328,12 @@ static void ide_config(dev_link_t *link)
329 328
330 /* retry registration in case device is still spinning up */ 329 /* retry registration in case device is still spinning up */
331 for (hd = -1, i = 0; i < 10; i++) { 330 for (hd = -1, i = 0; i < 10; i++) {
332 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ); 331 hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, handle);
333 if (hd >= 0) break; 332 if (hd >= 0) break;
334 if (link->io.NumPorts1 == 0x20) { 333 if (link->io.NumPorts1 == 0x20) {
335 outb(0x02, ctl_base + 0x10); 334 outb(0x02, ctl_base + 0x10);
336 hd = idecs_register(io_base + 0x10, ctl_base + 0x10, 335 hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
337 link->irq.AssignedIRQ); 336 link->irq.AssignedIRQ, handle);
338 if (hd >= 0) { 337 if (hd >= 0) {
339 io_base += 0x10; 338 io_base += 0x10;
340 ctl_base += 0x10; 339 ctl_base += 0x10;
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index af46226c1796..f35d684edc25 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o
6obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o 6obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
7obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o 7obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
8obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o 8obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
9obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
9obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o 10obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
10obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o 11obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
11obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o 12obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 844a6c9fb949..21965e5ef25e 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -74,6 +74,7 @@ static struct amd_ide_chip {
74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, 74 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 },
75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, 75 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 },
76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, 76 { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 },
77 { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 },
77 { 0 } 78 { 0 }
78}; 79};
79 80
@@ -491,6 +492,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
491 /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), 492 /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"),
492 /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), 493 /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"),
493 /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), 494 /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"),
495 /* 17 */ DECLARE_AMD_DEV("AMD5536"),
494}; 496};
495 497
496static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) 498static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -527,6 +529,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = {
527 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, 529 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 },
528 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, 530 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 },
529 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, 531 { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 },
532 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 },
530 { 0, }, 533 { 0, },
531}; 534};
532MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); 535MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl);
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
new file mode 100644
index 000000000000..6eb305197f3c
--- /dev/null
+++ b/drivers/ide/pci/cs5535.c
@@ -0,0 +1,305 @@
1/*
2 * linux/drivers/ide/pci/cs5535.c
3 *
4 * Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
5 *
6 * History:
7 * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com>
8 * - Reworked tuneproc, set_drive, misc mods to prep for mainline
9 * - Work was sponsored by CIS (M) Sdn Bhd.
10 * Ported to Kernel 2.6.11 on June 26, 2005 by
11 * Wolfgang Zuleger <wolfgang.zuleger@gmx.de>
12 * Alexander Kiausch <alex.kiausch@t-online.de>
13 * Originally developed by AMD for 2.4/2.6
14 *
15 * Development of this chipset driver was funded
16 * by the nice folks at National Semiconductor/AMD.
17 *
18 * This program is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License version 2 as published by
20 * the Free Software Foundation.
21 *
22 * Documentation:
23 * CS5535 documentation available from AMD
24 */
25
26#include <linux/config.h>
27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/ide.h>
30
31#include "ide-timing.h"
32
33#define MSR_ATAC_BASE 0x51300000
34#define ATAC_GLD_MSR_CAP (MSR_ATAC_BASE+0)
35#define ATAC_GLD_MSR_CONFIG (MSR_ATAC_BASE+0x01)
36#define ATAC_GLD_MSR_SMI (MSR_ATAC_BASE+0x02)
37#define ATAC_GLD_MSR_ERROR (MSR_ATAC_BASE+0x03)
38#define ATAC_GLD_MSR_PM (MSR_ATAC_BASE+0x04)
39#define ATAC_GLD_MSR_DIAG (MSR_ATAC_BASE+0x05)
40#define ATAC_IO_BAR (MSR_ATAC_BASE+0x08)
41#define ATAC_RESET (MSR_ATAC_BASE+0x10)
42#define ATAC_CH0D0_PIO (MSR_ATAC_BASE+0x20)
43#define ATAC_CH0D0_DMA (MSR_ATAC_BASE+0x21)
44#define ATAC_CH0D1_PIO (MSR_ATAC_BASE+0x22)
45#define ATAC_CH0D1_DMA (MSR_ATAC_BASE+0x23)
46#define ATAC_PCI_ABRTERR (MSR_ATAC_BASE+0x24)
47#define ATAC_BM0_CMD_PRIM 0x00
48#define ATAC_BM0_STS_PRIM 0x02
49#define ATAC_BM0_PRD 0x04
50#define CS5535_CABLE_DETECT 0x48
51
52/* Format I PIO settings. We seperate out cmd and data for safer timings */
53
54static unsigned int cs5535_pio_cmd_timings[5] =
55{ 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 };
56static unsigned int cs5535_pio_dta_timings[5] =
57{ 0xF7F4, 0xF173, 0x8141, 0x5131, 0x1131 };
58
59static unsigned int cs5535_mwdma_timings[3] =
60{ 0x7F0FFFF3, 0x7F035352, 0x7f024241 };
61
62static unsigned int cs5535_udma_timings[5] =
63{ 0x7F7436A1, 0x7F733481, 0x7F723261, 0x7F713161, 0x7F703061 };
64
65/* Macros to check if the register is the reset value - reset value is an
66 invalid timing and indicates the register has not been set previously */
67
68#define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL) == 0x00009172 )
69#define CS5535_BAD_DMA(timings) ( (timings & 0x000FFFFF) == 0x00077771 )
70
71/****
72 * cs5535_set_speed - Configure the chipset to the new speed
73 * @drive: Drive to set up
74 * @speed: desired speed
75 *
76 * cs5535_set_speed() configures the chipset to a new speed.
77 */
78static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
79{
80
81 u32 reg = 0, dummy;
82 int unit = drive->select.b.unit;
83
84
85 /* Set the PIO timings */
86 if ((speed & XFER_MODE) == XFER_PIO) {
87 u8 pioa;
88 u8 piob;
89 u8 cmd;
90
91 pioa = speed - XFER_PIO_0;
92 piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]),
93 255, 4, NULL);
94 cmd = pioa < piob ? pioa : piob;
95
96 /* Write the speed of the current drive */
97 reg = (cs5535_pio_cmd_timings[cmd] << 16) |
98 cs5535_pio_dta_timings[pioa];
99 wrmsr(unit ? ATAC_CH0D1_PIO : ATAC_CH0D0_PIO, reg, 0);
100
101 /* And if nessesary - change the speed of the other drive */
102 rdmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, dummy);
103
104 if (((reg >> 16) & cs5535_pio_cmd_timings[cmd]) !=
105 cs5535_pio_cmd_timings[cmd]) {
106 reg &= 0x0000FFFF;
107 reg |= cs5535_pio_cmd_timings[cmd] << 16;
108 wrmsr(unit ? ATAC_CH0D0_PIO : ATAC_CH0D1_PIO, reg, 0);
109 }
110
111 /* Set bit 31 of the DMA register for PIO format 1 timings */
112 rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
113 wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA,
114 reg | 0x80000000UL, 0);
115 } else {
116 rdmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, dummy);
117
118 reg &= 0x80000000UL; /* Preserve the PIO format bit */
119
120 if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7)
121 reg |= cs5535_udma_timings[speed - XFER_UDMA_0];
122 else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
123 reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0];
124 else
125 return;
126
127 wrmsr(unit ? ATAC_CH0D1_DMA : ATAC_CH0D0_DMA, reg, 0);
128 }
129}
130
131static u8 cs5535_ratemask(ide_drive_t *drive)
132{
133 /* eighty93 will return 1 if it's 80core and capable of
134 exceeding udma2, 0 otherwise. we need ratemask to set
135 the max speed and if we can > udma2 then we return 2
136 which selects speed_max as udma4 which is the 5535's max
137 speed, and 1 selects udma2 which is the max for 40c */
138 if (!eighty_ninty_three(drive))
139 return 1;
140
141 return 2;
142}
143
144
145/****
146 * cs5535_set_drive - Configure the drive to the new speed
147 * @drive: Drive to set up
148 * @speed: desired speed
149 *
150 * cs5535_set_drive() configures the drive and the chipset to a
151 * new speed. It also can be called by upper layers.
152 */
153static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
154{
155 speed = ide_rate_filter(cs5535_ratemask(drive), speed);
156 ide_config_drive_speed(drive, speed);
157 cs5535_set_speed(drive, speed);
158
159 return 0;
160}
161
162/****
163 * cs5535_tuneproc - PIO setup
164 * @drive: drive to set up
165 * @pio: mode to use (255 for 'best possible')
166 *
167 * A callback from the upper layers for PIO-only tuning.
168 */
169static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed)
170{
171 u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3,
172 XFER_PIO_4 };
173
174 /* cs5535 max pio is pio 4, best_pio will check the blacklist.
175 i think we don't need to rate_filter the incoming xferspeed
176 since we know we're only going to choose pio */
177 xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL);
178 ide_config_drive_speed(drive, modes[xferspeed]);
179 cs5535_set_speed(drive, xferspeed);
180}
181
182static int cs5535_config_drive_for_dma(ide_drive_t *drive)
183{
184 u8 speed;
185
186 speed = ide_dma_speed(drive, cs5535_ratemask(drive));
187
188 /* If no DMA speed was available then let dma_check hit pio */
189 if (!speed) {
190 return 0;
191 }
192
193 cs5535_set_drive(drive, speed);
194 return ide_dma_enable(drive);
195}
196
197static int cs5535_dma_check(ide_drive_t *drive)
198{
199 ide_hwif_t *hwif = drive->hwif;
200 struct hd_driveid *id = drive->id;
201 u8 speed;
202
203 drive->init_speed = 0;
204
205 if ((id->capability & 1) && drive->autodma) {
206 if (ide_use_dma(drive)) {
207 if (cs5535_config_drive_for_dma(drive))
208 return hwif->ide_dma_on(drive);
209 }
210
211 goto fast_ata_pio;
212
213 } else if ((id->capability & 8) || (id->field_valid & 2)) {
214fast_ata_pio:
215 speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
216 cs5535_set_drive(drive, speed);
217 return hwif->ide_dma_off_quietly(drive);
218 }
219 /* IORDY not supported */
220 return 0;
221}
222
223static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
224{
225 u8 bit;
226
227 /* if a 80 wire cable was detected */
228 pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
229 return (bit & 1);
230}
231
232/****
233 * init_hwif_cs5535 - Initialize one ide cannel
234 * @hwif: Channel descriptor
235 *
236 * This gets invoked by the IDE driver once for each channel. It
237 * performs channel-specific pre-initialization before drive probing.
238 *
239 */
240static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
241{
242 int i;
243
244 hwif->autodma = 0;
245
246 hwif->tuneproc = &cs5535_tuneproc;
247 hwif->speedproc = &cs5535_set_drive;
248 hwif->ide_dma_check = &cs5535_dma_check;
249
250 hwif->atapi_dma = 1;
251 hwif->ultra_mask = 0x1F;
252 hwif->mwdma_mask = 0x07;
253
254
255 hwif->udma_four = cs5535_cable_detect(hwif->pci_dev);
256
257 if (!noautodma)
258 hwif->autodma = 1;
259
260 /* just setting autotune and not worrying about bios timings */
261 for (i = 0; i < 2; i++) {
262 hwif->drives[i].autotune = 1;
263 hwif->drives[i].autodma = hwif->autodma;
264 }
265}
266
267static ide_pci_device_t cs5535_chipset __devinitdata = {
268 .name = "CS5535",
269 .init_hwif = init_hwif_cs5535,
270 .channels = 1,
271 .autodma = AUTODMA,
272 .bootable = ON_BOARD,
273};
274
275static int __devinit cs5535_init_one(struct pci_dev *dev,
276 const struct pci_device_id *id)
277{
278 return ide_setup_pci_device(dev, &cs5535_chipset);
279}
280
281static struct pci_device_id cs5535_pci_tbl[] =
282{
283 { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID,
284 PCI_ANY_ID, 0, 0, 0},
285 { 0, },
286};
287
288MODULE_DEVICE_TABLE(pci, cs5535_pci_tbl);
289
290static struct pci_driver driver = {
291 .name = "CS5535_IDE",
292 .id_table = cs5535_pci_tbl,
293 .probe = cs5535_init_one,
294};
295
296static int __init cs5535_ide_init(void)
297{
298 return ide_pci_register_driver(&driver);
299}
300
301module_init(cs5535_ide_init);
302
303MODULE_AUTHOR("AMD");
304MODULE_DESCRIPTION("PCI driver module for AMD/NS CS5535 IDE");
305MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 5a33513f3dd1..9f41ecd56338 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -469,7 +469,7 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
469 469
470static __devinitdata ide_hwif_t *primary; 470static __devinitdata ide_hwif_t *primary;
471 471
472void __devinit init_iops_cy82c693(ide_hwif_t *hwif) 472static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
473{ 473{
474 if (PCI_FUNC(hwif->pci_dev->devfn) == 1) 474 if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
475 primary = hwif; 475 primary = hwif;
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 127619a109ed..7b589d948bf9 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1516,7 +1516,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
1516 1516
1517static void __devinit init_iops_hpt366(ide_hwif_t *hwif) 1517static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
1518{ 1518{
1519 struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL); 1519 struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL);
1520 unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4); 1520 unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4);
1521 u8 did, rid; 1521 u8 did, rid;
1522 1522
@@ -1524,7 +1524,6 @@ static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
1524 printk(KERN_WARNING "hpt366: out of memory.\n"); 1524 printk(KERN_WARNING "hpt366: out of memory.\n");
1525 return; 1525 return;
1526 } 1526 }
1527 memset(info, 0, sizeof(struct hpt_info));
1528 ide_set_hwifdata(hwif, info); 1527 ide_set_hwifdata(hwif, info);
1529 1528
1530 if(dmabase) { 1529 if(dmabase) {
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index e440036e651f..108fda83fea4 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -642,14 +642,13 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
642 642
643static void __devinit init_hwif_it821x(ide_hwif_t *hwif) 643static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
644{ 644{
645 struct it821x_dev *idev = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL); 645 struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
646 u8 conf; 646 u8 conf;
647 647
648 if(idev == NULL) { 648 if(idev == NULL) {
649 printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n"); 649 printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
650 goto fallback; 650 goto fallback;
651 } 651 }
652 memset(idev, 0, sizeof(struct it821x_dev));
653 ide_set_hwifdata(hwif, idev); 652 ide_set_hwifdata(hwif, idev);
654 653
655 pci_read_config_byte(hwif->pci_dev, 0x50, &conf); 654 pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 2b9961b88135..022d244f2eb0 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -701,6 +701,7 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
701 unsigned long barsize = pci_resource_len(dev, 5); 701 unsigned long barsize = pci_resource_len(dev, 5);
702 u8 tmpbyte = 0; 702 u8 tmpbyte = 0;
703 void __iomem *ioaddr; 703 void __iomem *ioaddr;
704 u32 tmp, irq_mask;
704 705
705 /* 706 /*
706 * Drop back to PIO if we can't map the mmio. Some 707 * Drop back to PIO if we can't map the mmio. Some
@@ -726,6 +727,14 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
726 pci_set_drvdata(dev, (void *) ioaddr); 727 pci_set_drvdata(dev, (void *) ioaddr);
727 728
728 if (pdev_is_sata(dev)) { 729 if (pdev_is_sata(dev)) {
730 /* make sure IDE0/1 interrupts are not masked */
731 irq_mask = (1 << 22) | (1 << 23);
732 tmp = readl(ioaddr + 0x48);
733 if (tmp & irq_mask) {
734 tmp &= ~irq_mask;
735 writel(tmp, ioaddr + 0x48);
736 readl(ioaddr + 0x48); /* flush */
737 }
729 writel(0, ioaddr + 0x148); 738 writel(0, ioaddr + 0x148);
730 writel(0, ioaddr + 0x1C8); 739 writel(0, ioaddr + 0x1C8);
731 } 740 }
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index d8c3d8ebad30..b3e65a65d202 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -497,16 +497,19 @@ pmu_hd_blink_init(void)
497 if (pmu_get_model() != PMU_KEYLARGO_BASED) 497 if (pmu_get_model() != PMU_KEYLARGO_BASED)
498 return 0; 498 return 0;
499 499
500 dt = find_devices("device-tree"); 500 dt = of_find_node_by_path("/");
501 if (dt == NULL) 501 if (dt == NULL)
502 return 0; 502 return 0;
503 model = (const char *)get_property(dt, "model", NULL); 503 model = (const char *)get_property(dt, "model", NULL);
504 if (model == NULL) 504 if (model == NULL)
505 return 0; 505 return 0;
506 if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && 506 if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
507 strncmp(model, "iBook", strlen("iBook")) != 0) 507 strncmp(model, "iBook", strlen("iBook")) != 0) {
508 of_node_put(dt);
508 return 0; 509 return 0;
509 510 }
511 of_node_put(dt);
512
510 pmu_blink_on.complete = 1; 513 pmu_blink_on.complete = 1;
511 pmu_blink_off.complete = 1; 514 pmu_blink_off.complete = 1;
512 spin_lock_init(&pmu_blink_lock); 515 spin_lock_init(&pmu_blink_lock);
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 18ed7765417c..d4f2111d4364 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -787,8 +787,9 @@ static int pre_init = 1; /* Before first ordered IDE scan */
787static LIST_HEAD(ide_pci_drivers); 787static LIST_HEAD(ide_pci_drivers);
788 788
789/* 789/*
790 * ide_register_pci_driver - attach IDE driver 790 * __ide_register_pci_driver - attach IDE driver
791 * @driver: pci driver 791 * @driver: pci driver
792 * @module: owner module of the driver
792 * 793 *
793 * Registers a driver with the IDE layer. The IDE layer arranges that 794 * Registers a driver with the IDE layer. The IDE layer arranges that
794 * boot time setup is done in the expected device order and then 795 * boot time setup is done in the expected device order and then
@@ -801,15 +802,16 @@ static LIST_HEAD(ide_pci_drivers);
801 * Returns are the same as for pci_register_driver 802 * Returns are the same as for pci_register_driver
802 */ 803 */
803 804
804int ide_pci_register_driver(struct pci_driver *driver) 805int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
805{ 806{
806 if(!pre_init) 807 if(!pre_init)
807 return pci_module_init(driver); 808 return __pci_register_driver(driver, module);
809 driver->driver.owner = module;
808 list_add_tail(&driver->node, &ide_pci_drivers); 810 list_add_tail(&driver->node, &ide_pci_drivers);
809 return 0; 811 return 0;
810} 812}
811 813
812EXPORT_SYMBOL_GPL(ide_pci_register_driver); 814EXPORT_SYMBOL_GPL(__ide_pci_register_driver);
813 815
814/** 816/**
815 * ide_unregister_pci_driver - unregister an IDE driver 817 * ide_unregister_pci_driver - unregister an IDE driver
@@ -897,6 +899,6 @@ void __init ide_scan_pcibus (int scan_direction)
897 { 899 {
898 list_del(l); 900 list_del(l);
899 d = list_entry(l, struct pci_driver, node); 901 d = list_entry(l, struct pci_driver, node);
900 pci_register_driver(d); 902 __pci_register_driver(d, d->driver.owner);
901 } 903 }
902} 904}
diff --git a/drivers/ieee1394/amdtp.c b/drivers/ieee1394/amdtp.c
index e8e28569a668..75897509c401 100644
--- a/drivers/ieee1394/amdtp.c
+++ b/drivers/ieee1394/amdtp.c
@@ -320,8 +320,7 @@ static void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx, int synchronous)
320 if ((control & OHCI1394_CONTEXT_ACTIVE) == 0) 320 if ((control & OHCI1394_CONTEXT_ACTIVE) == 0)
321 break; 321 break;
322 322
323 set_current_state(TASK_INTERRUPTIBLE); 323 schedule_timeout_interruptible(1);
324 schedule_timeout(1);
325 } 324 }
326 } 325 }
327} 326}
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
index 7545775d38ef..34b724afd28d 100644
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -37,6 +37,9 @@
37 * $Id: agent.c 1389 2004-12-27 22:56:47Z roland $ 37 * $Id: agent.c 1389 2004-12-27 22:56:47Z roland $
38 */ 38 */
39 39
40#include <linux/slab.h>
41#include <linux/string.h>
42
40#include "agent.h" 43#include "agent.h"
41#include "smi.h" 44#include "smi.h"
42 45
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 3d8175e5f054..41d6b4017acb 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -508,8 +508,7 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
508 wait_event(mad_agent_priv->wait, 508 wait_event(mad_agent_priv->wait,
509 !atomic_read(&mad_agent_priv->refcount)); 509 !atomic_read(&mad_agent_priv->refcount));
510 510
511 if (mad_agent_priv->reg_req) 511 kfree(mad_agent_priv->reg_req);
512 kfree(mad_agent_priv->reg_req);
513 ib_dereg_mr(mad_agent_priv->agent.mr); 512 ib_dereg_mr(mad_agent_priv->agent.mr);
514 kfree(mad_agent_priv); 513 kfree(mad_agent_priv);
515} 514}
@@ -2500,8 +2499,7 @@ error:
2500static void destroy_mad_qp(struct ib_mad_qp_info *qp_info) 2499static void destroy_mad_qp(struct ib_mad_qp_info *qp_info)
2501{ 2500{
2502 ib_destroy_qp(qp_info->qp); 2501 ib_destroy_qp(qp_info->qp);
2503 if (qp_info->snoop_table) 2502 kfree(qp_info->snoop_table);
2504 kfree(qp_info->snoop_table);
2505} 2503}
2506 2504
2507/* 2505/*
diff --git a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c
index 35df5010e723..c972d7235764 100644
--- a/drivers/infiniband/core/packer.c
+++ b/drivers/infiniband/core/packer.c
@@ -33,6 +33,8 @@
33 * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $ 33 * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $
34 */ 34 */
35 35
36#include <linux/string.h>
37
36#include <rdma/ib_pack.h> 38#include <rdma/ib_pack.h>
37 39
38static u64 value_read(int offset, int size, void *structure) 40static u64 value_read(int offset, int size, void *structure)
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index b8120650e711..08648b1a387e 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -36,6 +36,9 @@
36 36
37#include "core_priv.h" 37#include "core_priv.h"
38 38
39#include <linux/slab.h>
40#include <linux/string.h>
41
39#include <rdma/ib_mad.h> 42#include <rdma/ib_mad.h>
40 43
41struct ib_port { 44struct ib_port {
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c
index 527b23450ab3..997c07db6d8f 100644
--- a/drivers/infiniband/core/ud_header.c
+++ b/drivers/infiniband/core/ud_header.c
@@ -34,6 +34,7 @@
34 */ 34 */
35 35
36#include <linux/errno.h> 36#include <linux/errno.h>
37#include <linux/string.h>
37 38
38#include <rdma/ib_pack.h> 39#include <rdma/ib_pack.h>
39 40
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index aed5ca23fb22..5ea741f47fc8 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -31,7 +31,7 @@
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE. 32 * SOFTWARE.
33 * 33 *
34 * $Id: user_mad.c 2814 2005-07-06 19:14:09Z halr $ 34 * $Id: user_mad.c 4010 2005-11-09 23:11:56Z roland $
35 */ 35 */
36 36
37#include <linux/module.h> 37#include <linux/module.h>
@@ -110,13 +110,13 @@ struct ib_umad_device {
110}; 110};
111 111
112struct ib_umad_file { 112struct ib_umad_file {
113 struct ib_umad_port *port; 113 struct ib_umad_port *port;
114 struct list_head recv_list; 114 struct list_head recv_list;
115 struct list_head port_list; 115 struct list_head port_list;
116 spinlock_t recv_lock; 116 spinlock_t recv_lock;
117 wait_queue_head_t recv_wait; 117 wait_queue_head_t recv_wait;
118 struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; 118 struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS];
119 struct ib_mr *mr[IB_UMAD_MAX_AGENTS]; 119 int agents_dead;
120}; 120};
121 121
122struct ib_umad_packet { 122struct ib_umad_packet {
@@ -145,6 +145,12 @@ static void ib_umad_release_dev(struct kref *ref)
145 kfree(dev); 145 kfree(dev);
146} 146}
147 147
148/* caller must hold port->mutex at least for reading */
149static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id)
150{
151 return file->agents_dead ? NULL : file->agent[id];
152}
153
148static int queue_packet(struct ib_umad_file *file, 154static int queue_packet(struct ib_umad_file *file,
149 struct ib_mad_agent *agent, 155 struct ib_mad_agent *agent,
150 struct ib_umad_packet *packet) 156 struct ib_umad_packet *packet)
@@ -152,10 +158,11 @@ static int queue_packet(struct ib_umad_file *file,
152 int ret = 1; 158 int ret = 1;
153 159
154 down_read(&file->port->mutex); 160 down_read(&file->port->mutex);
161
155 for (packet->mad.hdr.id = 0; 162 for (packet->mad.hdr.id = 0;
156 packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; 163 packet->mad.hdr.id < IB_UMAD_MAX_AGENTS;
157 packet->mad.hdr.id++) 164 packet->mad.hdr.id++)
158 if (agent == file->agent[packet->mad.hdr.id]) { 165 if (agent == __get_agent(file, packet->mad.hdr.id)) {
159 spin_lock_irq(&file->recv_lock); 166 spin_lock_irq(&file->recv_lock);
160 list_add_tail(&packet->list, &file->recv_list); 167 list_add_tail(&packet->list, &file->recv_list);
161 spin_unlock_irq(&file->recv_lock); 168 spin_unlock_irq(&file->recv_lock);
@@ -327,7 +334,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
327 334
328 down_read(&file->port->mutex); 335 down_read(&file->port->mutex);
329 336
330 agent = file->agent[packet->mad.hdr.id]; 337 agent = __get_agent(file, packet->mad.hdr.id);
331 if (!agent) { 338 if (!agent) {
332 ret = -EINVAL; 339 ret = -EINVAL;
333 goto err_up; 340 goto err_up;
@@ -481,7 +488,7 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg)
481 } 488 }
482 489
483 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id) 490 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id)
484 if (!file->agent[agent_id]) 491 if (!__get_agent(file, agent_id))
485 goto found; 492 goto found;
486 493
487 ret = -ENOMEM; 494 ret = -ENOMEM;
@@ -505,29 +512,15 @@ found:
505 goto out; 512 goto out;
506 } 513 }
507 514
508 file->agent[agent_id] = agent;
509
510 file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE);
511 if (IS_ERR(file->mr[agent_id])) {
512 ret = -ENOMEM;
513 goto err;
514 }
515
516 if (put_user(agent_id, 515 if (put_user(agent_id,
517 (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) { 516 (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) {
518 ret = -EFAULT; 517 ret = -EFAULT;
519 goto err_mr; 518 ib_unregister_mad_agent(agent);
519 goto out;
520 } 520 }
521 521
522 file->agent[agent_id] = agent;
522 ret = 0; 523 ret = 0;
523 goto out;
524
525err_mr:
526 ib_dereg_mr(file->mr[agent_id]);
527
528err:
529 file->agent[agent_id] = NULL;
530 ib_unregister_mad_agent(agent);
531 524
532out: 525out:
533 up_write(&file->port->mutex); 526 up_write(&file->port->mutex);
@@ -536,27 +529,29 @@ out:
536 529
537static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) 530static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg)
538{ 531{
532 struct ib_mad_agent *agent = NULL;
539 u32 id; 533 u32 id;
540 int ret = 0; 534 int ret = 0;
541 535
542 down_write(&file->port->mutex); 536 if (get_user(id, (u32 __user *) arg))
537 return -EFAULT;
543 538
544 if (get_user(id, (u32 __user *) arg)) { 539 down_write(&file->port->mutex);
545 ret = -EFAULT;
546 goto out;
547 }
548 540
549 if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) { 541 if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !__get_agent(file, id)) {
550 ret = -EINVAL; 542 ret = -EINVAL;
551 goto out; 543 goto out;
552 } 544 }
553 545
554 ib_dereg_mr(file->mr[id]); 546 agent = file->agent[id];
555 ib_unregister_mad_agent(file->agent[id]);
556 file->agent[id] = NULL; 547 file->agent[id] = NULL;
557 548
558out: 549out:
559 up_write(&file->port->mutex); 550 up_write(&file->port->mutex);
551
552 if (agent)
553 ib_unregister_mad_agent(agent);
554
560 return ret; 555 return ret;
561} 556}
562 557
@@ -621,23 +616,29 @@ static int ib_umad_close(struct inode *inode, struct file *filp)
621 struct ib_umad_file *file = filp->private_data; 616 struct ib_umad_file *file = filp->private_data;
622 struct ib_umad_device *dev = file->port->umad_dev; 617 struct ib_umad_device *dev = file->port->umad_dev;
623 struct ib_umad_packet *packet, *tmp; 618 struct ib_umad_packet *packet, *tmp;
619 int already_dead;
624 int i; 620 int i;
625 621
626 down_write(&file->port->mutex); 622 down_write(&file->port->mutex);
627 for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) 623
628 if (file->agent[i]) { 624 already_dead = file->agents_dead;
629 ib_dereg_mr(file->mr[i]); 625 file->agents_dead = 1;
630 ib_unregister_mad_agent(file->agent[i]);
631 }
632 626
633 list_for_each_entry_safe(packet, tmp, &file->recv_list, list) 627 list_for_each_entry_safe(packet, tmp, &file->recv_list, list)
634 kfree(packet); 628 kfree(packet);
635 629
636 list_del(&file->port_list); 630 list_del(&file->port_list);
637 up_write(&file->port->mutex);
638 631
639 kfree(file); 632 downgrade_write(&file->port->mutex);
633
634 if (!already_dead)
635 for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
636 if (file->agent[i])
637 ib_unregister_mad_agent(file->agent[i]);
638
639 up_read(&file->port->mutex);
640 640
641 kfree(file);
641 kref_put(&dev->ref, ib_umad_release_dev); 642 kref_put(&dev->ref, ib_umad_release_dev);
642 643
643 return 0; 644 return 0;
@@ -801,7 +802,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
801 goto err_class; 802 goto err_class;
802 port->sm_dev->owner = THIS_MODULE; 803 port->sm_dev->owner = THIS_MODULE;
803 port->sm_dev->ops = &umad_sm_fops; 804 port->sm_dev->ops = &umad_sm_fops;
804 kobject_set_name(&port->dev->kobj, "issm%d", port->dev_num); 805 kobject_set_name(&port->sm_dev->kobj, "issm%d", port->dev_num);
805 if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) 806 if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
806 goto err_sm_cdev; 807 goto err_sm_cdev;
807 808
@@ -863,14 +864,36 @@ static void ib_umad_kill_port(struct ib_umad_port *port)
863 864
864 port->ib_dev = NULL; 865 port->ib_dev = NULL;
865 866
866 list_for_each_entry(file, &port->file_list, port_list) 867 /*
867 for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) { 868 * Now go through the list of files attached to this port and
868 if (!file->agent[id]) 869 * unregister all of their MAD agents. We need to hold
869 continue; 870 * port->mutex while doing this to avoid racing with
870 ib_dereg_mr(file->mr[id]); 871 * ib_umad_close(), but we can't hold the mutex for writing
871 ib_unregister_mad_agent(file->agent[id]); 872 * while calling ib_unregister_mad_agent(), since that might
872 file->agent[id] = NULL; 873 * deadlock by calling back into queue_packet(). So we
873 } 874 * downgrade our lock to a read lock, and then drop and
875 * reacquire the write lock for the next iteration.
876 *
877 * We do list_del_init() on the file's list_head so that the
878 * list_del in ib_umad_close() is still OK, even after the
879 * file is removed from the list.
880 */
881 while (!list_empty(&port->file_list)) {
882 file = list_entry(port->file_list.next, struct ib_umad_file,
883 port_list);
884
885 file->agents_dead = 1;
886 list_del_init(&file->port_list);
887
888 downgrade_write(&port->mutex);
889
890 for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id)
891 if (file->agent[id])
892 ib_unregister_mad_agent(file->agent[id]);
893
894 up_read(&port->mutex);
895 down_write(&port->mutex);
896 }
874 897
875 up_write(&port->mutex); 898 up_write(&port->mutex);
876 899
@@ -913,7 +936,7 @@ static void ib_umad_add_one(struct ib_device *device)
913 936
914err: 937err:
915 while (--i >= s) 938 while (--i >= s)
916 ib_umad_kill_port(&umad_dev->port[i]); 939 ib_umad_kill_port(&umad_dev->port[i - s]);
917 940
918 kref_put(&umad_dev->ref, ib_umad_release_dev); 941 kref_put(&umad_dev->ref, ib_umad_release_dev);
919} 942}
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 63a74151c60b..ed45da892b1c 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -708,7 +708,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
708 resp->wc[i].opcode = wc[i].opcode; 708 resp->wc[i].opcode = wc[i].opcode;
709 resp->wc[i].vendor_err = wc[i].vendor_err; 709 resp->wc[i].vendor_err = wc[i].vendor_err;
710 resp->wc[i].byte_len = wc[i].byte_len; 710 resp->wc[i].byte_len = wc[i].byte_len;
711 resp->wc[i].imm_data = wc[i].imm_data; 711 resp->wc[i].imm_data = (__u32 __force) wc[i].imm_data;
712 resp->wc[i].qp_num = wc[i].qp_num; 712 resp->wc[i].qp_num = wc[i].qp_num;
713 resp->wc[i].src_qp = wc[i].src_qp; 713 resp->wc[i].src_qp = wc[i].src_qp;
714 resp->wc[i].wc_flags = wc[i].wc_flags; 714 resp->wc[i].wc_flags = wc[i].wc_flags;
@@ -908,7 +908,12 @@ retry:
908 if (ret) 908 if (ret)
909 goto err_destroy; 909 goto err_destroy;
910 910
911 resp.qp_handle = uobj->uobject.id; 911 resp.qp_handle = uobj->uobject.id;
912 resp.max_recv_sge = attr.cap.max_recv_sge;
913 resp.max_send_sge = attr.cap.max_send_sge;
914 resp.max_recv_wr = attr.cap.max_recv_wr;
915 resp.max_send_wr = attr.cap.max_send_wr;
916 resp.max_inline_data = attr.cap.max_inline_data;
912 917
913 if (copy_to_user((void __user *) (unsigned long) cmd.response, 918 if (copy_to_user((void __user *) (unsigned long) cmd.response,
914 &resp, sizeof resp)) { 919 &resp, sizeof resp)) {
@@ -1135,7 +1140,7 @@ ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
1135 next->num_sge = user_wr->num_sge; 1140 next->num_sge = user_wr->num_sge;
1136 next->opcode = user_wr->opcode; 1141 next->opcode = user_wr->opcode;
1137 next->send_flags = user_wr->send_flags; 1142 next->send_flags = user_wr->send_flags;
1138 next->imm_data = user_wr->imm_data; 1143 next->imm_data = (__be32 __force) user_wr->imm_data;
1139 1144
1140 if (qp->qp_type == IB_QPT_UD) { 1145 if (qp->qp_type == IB_QPT_UD) {
1141 next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr, 1146 next->wr.ud.ah = idr_find(&ib_uverbs_ah_idr,
@@ -1701,7 +1706,6 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
1701 } 1706 }
1702 1707
1703 attr.max_wr = cmd.max_wr; 1708 attr.max_wr = cmd.max_wr;
1704 attr.max_sge = cmd.max_sge;
1705 attr.srq_limit = cmd.srq_limit; 1709 attr.srq_limit = cmd.srq_limit;
1706 1710
1707 ret = ib_modify_srq(srq, &attr, cmd.attr_mask); 1711 ret = ib_modify_srq(srq, &attr, cmd.attr_mask);
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 72d3ef786db5..4c15e112736c 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -40,6 +40,7 @@
40 40
41#include <linux/errno.h> 41#include <linux/errno.h>
42#include <linux/err.h> 42#include <linux/err.h>
43#include <linux/string.h>
43 44
44#include <rdma/ib_verbs.h> 45#include <rdma/ib_verbs.h>
45#include <rdma/ib_cache.h> 46#include <rdma/ib_cache.h>
@@ -324,16 +325,8 @@ EXPORT_SYMBOL(ib_destroy_cq);
324int ib_resize_cq(struct ib_cq *cq, 325int ib_resize_cq(struct ib_cq *cq,
325 int cqe) 326 int cqe)
326{ 327{
327 int ret; 328 return cq->device->resize_cq ?
328 329 cq->device->resize_cq(cq, cqe) : -ENOSYS;
329 if (!cq->device->resize_cq)
330 return -ENOSYS;
331
332 ret = cq->device->resize_cq(cq, &cqe);
333 if (!ret)
334 cq->cqe = cqe;
335
336 return ret;
337} 330}
338EXPORT_SYMBOL(ib_resize_cq); 331EXPORT_SYMBOL(ib_resize_cq);
339 332
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c
index 7ac52af43b99..c3bec7490f52 100644
--- a/drivers/infiniband/hw/mthca/mthca_catas.c
+++ b/drivers/infiniband/hw/mthca/mthca_catas.c
@@ -32,6 +32,9 @@
32 * $Id$ 32 * $Id$
33 */ 33 */
34 34
35#include <linux/jiffies.h>
36#include <linux/timer.h>
37
35#include "mthca_dev.h" 38#include "mthca_dev.h"
36 39
37enum { 40enum {
@@ -94,7 +97,7 @@ static void poll_catas(unsigned long dev_ptr)
94 } 97 }
95 98
96 spin_lock_irqsave(&catas_lock, flags); 99 spin_lock_irqsave(&catas_lock, flags);
97 if (dev->catas_err.stop) 100 if (!dev->catas_err.stop)
98 mod_timer(&dev->catas_err.timer, 101 mod_timer(&dev->catas_err.timer,
99 jiffies + MTHCA_CATAS_POLL_INTERVAL); 102 jiffies + MTHCA_CATAS_POLL_INTERVAL);
100 spin_unlock_irqrestore(&catas_lock, flags); 103 spin_unlock_irqrestore(&catas_lock, flags);
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 49f211d55df7..9ed34587fc5c 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1060,6 +1060,8 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev,
1060 dev_lim->hca.arbel.resize_srq = field & 1; 1060 dev_lim->hca.arbel.resize_srq = field & 1;
1061 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); 1061 MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET);
1062 dev_lim->max_sg = min_t(int, field, dev_lim->max_sg); 1062 dev_lim->max_sg = min_t(int, field, dev_lim->max_sg);
1063 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MAX_DESC_SZ_RQ_OFFSET);
1064 dev_lim->max_desc_sz = min_t(int, size, dev_lim->max_desc_sz);
1063 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET); 1065 MTHCA_GET(size, outbox, QUERY_DEV_LIM_MPT_ENTRY_SZ_OFFSET);
1064 dev_lim->mpt_entry_sz = size; 1066 dev_lim->mpt_entry_sz = size;
1065 MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET); 1067 MTHCA_GET(field, outbox, QUERY_DEV_LIM_PBL_SZ_OFFSET);
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index f98e23555826..4a8adcef2079 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -258,7 +258,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
258{ 258{
259 struct mthca_cq *cq; 259 struct mthca_cq *cq;
260 struct mthca_cqe *cqe; 260 struct mthca_cqe *cqe;
261 int prod_index; 261 u32 prod_index;
262 int nfreed = 0; 262 int nfreed = 0;
263 263
264 spin_lock_irq(&dev->cq_table.lock); 264 spin_lock_irq(&dev->cq_table.lock);
@@ -293,19 +293,15 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn,
293 * Now sweep backwards through the CQ, removing CQ entries 293 * Now sweep backwards through the CQ, removing CQ entries
294 * that match our QP by copying older entries on top of them. 294 * that match our QP by copying older entries on top of them.
295 */ 295 */
296 while (prod_index > cq->cons_index) { 296 while ((int) --prod_index - (int) cq->cons_index >= 0) {
297 cqe = get_cqe(cq, (prod_index - 1) & cq->ibcq.cqe); 297 cqe = get_cqe(cq, prod_index & cq->ibcq.cqe);
298 if (cqe->my_qpn == cpu_to_be32(qpn)) { 298 if (cqe->my_qpn == cpu_to_be32(qpn)) {
299 if (srq) 299 if (srq)
300 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); 300 mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe));
301 ++nfreed; 301 ++nfreed;
302 } 302 } else if (nfreed)
303 else if (nfreed) 303 memcpy(get_cqe(cq, (prod_index + nfreed) & cq->ibcq.cqe),
304 memcpy(get_cqe(cq, (prod_index - 1 + nfreed) & 304 cqe, MTHCA_CQ_ENTRY_SIZE);
305 cq->ibcq.cqe),
306 cqe,
307 MTHCA_CQ_ENTRY_SIZE);
308 --prod_index;
309 } 305 }
310 306
311 if (nfreed) { 307 if (nfreed) {
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index e7e5d3b4f004..497ff794ef6a 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -131,6 +131,7 @@ struct mthca_limits {
131 int max_sg; 131 int max_sg;
132 int num_qps; 132 int num_qps;
133 int max_wqes; 133 int max_wqes;
134 int max_desc_sz;
134 int max_qp_init_rdma; 135 int max_qp_init_rdma;
135 int reserved_qps; 136 int reserved_qps;
136 int num_srqs; 137 int num_srqs;
@@ -154,6 +155,7 @@ struct mthca_limits {
154 int reserved_mcgs; 155 int reserved_mcgs;
155 int num_pds; 156 int num_pds;
156 int reserved_pds; 157 int reserved_pds;
158 u32 page_size_cap;
157 u32 flags; 159 u32 flags;
158 u8 port_width_cap; 160 u8 port_width_cap;
159}; 161};
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 45c6328e780c..6f94b25f3acd 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -168,6 +168,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
168 mdev->limits.max_srq_wqes = dev_lim->max_srq_sz; 168 mdev->limits.max_srq_wqes = dev_lim->max_srq_sz;
169 mdev->limits.reserved_srqs = dev_lim->reserved_srqs; 169 mdev->limits.reserved_srqs = dev_lim->reserved_srqs;
170 mdev->limits.reserved_eecs = dev_lim->reserved_eecs; 170 mdev->limits.reserved_eecs = dev_lim->reserved_eecs;
171 mdev->limits.max_desc_sz = dev_lim->max_desc_sz;
171 /* 172 /*
172 * Subtract 1 from the limit because we need to allocate a 173 * Subtract 1 from the limit because we need to allocate a
173 * spare CQE so the HCA HW can tell the difference between an 174 * spare CQE so the HCA HW can tell the difference between an
@@ -181,6 +182,7 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim
181 mdev->limits.reserved_uars = dev_lim->reserved_uars; 182 mdev->limits.reserved_uars = dev_lim->reserved_uars;
182 mdev->limits.reserved_pds = dev_lim->reserved_pds; 183 mdev->limits.reserved_pds = dev_lim->reserved_pds;
183 mdev->limits.port_width_cap = dev_lim->max_port_width; 184 mdev->limits.port_width_cap = dev_lim->max_port_width;
185 mdev->limits.page_size_cap = ~(u32) (dev_lim->min_page_sz - 1);
184 mdev->limits.flags = dev_lim->flags; 186 mdev->limits.flags = dev_lim->flags;
185 187
186 /* IB_DEVICE_RESIZE_MAX_WR not supported by driver. 188 /* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
@@ -1196,7 +1198,6 @@ MODULE_DEVICE_TABLE(pci, mthca_pci_table);
1196 1198
1197static struct pci_driver mthca_driver = { 1199static struct pci_driver mthca_driver = {
1198 .name = DRV_NAME, 1200 .name = DRV_NAME,
1199 .owner = THIS_MODULE,
1200 .id_table = mthca_pci_table, 1201 .id_table = mthca_pci_table,
1201 .probe = mthca_init_one, 1202 .probe = mthca_init_one,
1202 .remove = __devexit_p(mthca_remove_one) 1203 .remove = __devexit_p(mthca_remove_one)
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 6b0166668269..4cc7e2846df1 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -90,6 +90,7 @@ static int mthca_query_device(struct ib_device *ibdev,
90 memcpy(&props->node_guid, out_mad->data + 12, 8); 90 memcpy(&props->node_guid, out_mad->data + 12, 8);
91 91
92 props->max_mr_size = ~0ull; 92 props->max_mr_size = ~0ull;
93 props->page_size_cap = mdev->limits.page_size_cap;
93 props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps; 94 props->max_qp = mdev->limits.num_qps - mdev->limits.reserved_qps;
94 props->max_qp_wr = mdev->limits.max_wqes; 95 props->max_qp_wr = mdev->limits.max_wqes;
95 props->max_sge = mdev->limits.max_sg; 96 props->max_sge = mdev->limits.max_sg;
@@ -615,11 +616,11 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
615 return ERR_PTR(err); 616 return ERR_PTR(err);
616 } 617 }
617 618
618 init_attr->cap.max_inline_data = 0;
619 init_attr->cap.max_send_wr = qp->sq.max; 619 init_attr->cap.max_send_wr = qp->sq.max;
620 init_attr->cap.max_recv_wr = qp->rq.max; 620 init_attr->cap.max_recv_wr = qp->rq.max;
621 init_attr->cap.max_send_sge = qp->sq.max_gs; 621 init_attr->cap.max_send_sge = qp->sq.max_gs;
622 init_attr->cap.max_recv_sge = qp->rq.max_gs; 622 init_attr->cap.max_recv_sge = qp->rq.max_gs;
623 init_attr->cap.max_inline_data = qp->max_inline_data;
623 624
624 return &qp->ibqp; 625 return &qp->ibqp;
625} 626}
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.h b/drivers/infiniband/hw/mthca/mthca_provider.h
index bcd4b01a339c..1e73947b4702 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.h
+++ b/drivers/infiniband/hw/mthca/mthca_provider.h
@@ -251,6 +251,7 @@ struct mthca_qp {
251 struct mthca_wq sq; 251 struct mthca_wq sq;
252 enum ib_sig_type sq_policy; 252 enum ib_sig_type sq_policy;
253 int send_wqe_offset; 253 int send_wqe_offset;
254 int max_inline_data;
254 255
255 u64 *wrid; 256 u64 *wrid;
256 union mthca_buf queue; 257 union mthca_buf queue;
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 8852ea477c21..760c418d5bc9 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -885,6 +885,48 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
885 return err; 885 return err;
886} 886}
887 887
888static void mthca_adjust_qp_caps(struct mthca_dev *dev,
889 struct mthca_pd *pd,
890 struct mthca_qp *qp)
891{
892 int max_data_size;
893
894 /*
895 * Calculate the maximum size of WQE s/g segments, excluding
896 * the next segment and other non-data segments.
897 */
898 max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) -
899 sizeof (struct mthca_next_seg);
900
901 switch (qp->transport) {
902 case MLX:
903 max_data_size -= 2 * sizeof (struct mthca_data_seg);
904 break;
905
906 case UD:
907 if (mthca_is_memfree(dev))
908 max_data_size -= sizeof (struct mthca_arbel_ud_seg);
909 else
910 max_data_size -= sizeof (struct mthca_tavor_ud_seg);
911 break;
912
913 default:
914 max_data_size -= sizeof (struct mthca_raddr_seg);
915 break;
916 }
917
918 /* We don't support inline data for kernel QPs (yet). */
919 if (!pd->ibpd.uobject)
920 qp->max_inline_data = 0;
921 else
922 qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE;
923
924 qp->sq.max_gs = max_data_size / sizeof (struct mthca_data_seg);
925 qp->rq.max_gs = (min(dev->limits.max_desc_sz, 1 << qp->rq.wqe_shift) -
926 sizeof (struct mthca_next_seg)) /
927 sizeof (struct mthca_data_seg);
928}
929
888/* 930/*
889 * Allocate and register buffer for WQEs. qp->rq.max, sq.max, 931 * Allocate and register buffer for WQEs. qp->rq.max, sq.max,
890 * rq.max_gs and sq.max_gs must all be assigned. 932 * rq.max_gs and sq.max_gs must all be assigned.
@@ -902,27 +944,53 @@ static int mthca_alloc_wqe_buf(struct mthca_dev *dev,
902 size = sizeof (struct mthca_next_seg) + 944 size = sizeof (struct mthca_next_seg) +
903 qp->rq.max_gs * sizeof (struct mthca_data_seg); 945 qp->rq.max_gs * sizeof (struct mthca_data_seg);
904 946
947 if (size > dev->limits.max_desc_sz)
948 return -EINVAL;
949
905 for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size; 950 for (qp->rq.wqe_shift = 6; 1 << qp->rq.wqe_shift < size;
906 qp->rq.wqe_shift++) 951 qp->rq.wqe_shift++)
907 ; /* nothing */ 952 ; /* nothing */
908 953
909 size = sizeof (struct mthca_next_seg) + 954 size = qp->sq.max_gs * sizeof (struct mthca_data_seg);
910 qp->sq.max_gs * sizeof (struct mthca_data_seg);
911 switch (qp->transport) { 955 switch (qp->transport) {
912 case MLX: 956 case MLX:
913 size += 2 * sizeof (struct mthca_data_seg); 957 size += 2 * sizeof (struct mthca_data_seg);
914 break; 958 break;
959
915 case UD: 960 case UD:
916 if (mthca_is_memfree(dev)) 961 size += mthca_is_memfree(dev) ?
917 size += sizeof (struct mthca_arbel_ud_seg); 962 sizeof (struct mthca_arbel_ud_seg) :
918 else 963 sizeof (struct mthca_tavor_ud_seg);
919 size += sizeof (struct mthca_tavor_ud_seg);
920 break; 964 break;
965
966 case UC:
967 size += sizeof (struct mthca_raddr_seg);
968 break;
969
970 case RC:
971 size += sizeof (struct mthca_raddr_seg);
972 /*
973 * An atomic op will require an atomic segment, a
974 * remote address segment and one scatter entry.
975 */
976 size = max_t(int, size,
977 sizeof (struct mthca_atomic_seg) +
978 sizeof (struct mthca_raddr_seg) +
979 sizeof (struct mthca_data_seg));
980 break;
981
921 default: 982 default:
922 /* bind seg is as big as atomic + raddr segs */ 983 break;
923 size += sizeof (struct mthca_bind_seg);
924 } 984 }
925 985
986 /* Make sure that we have enough space for a bind request */
987 size = max_t(int, size, sizeof (struct mthca_bind_seg));
988
989 size += sizeof (struct mthca_next_seg);
990
991 if (size > dev->limits.max_desc_sz)
992 return -EINVAL;
993
926 for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size; 994 for (qp->sq.wqe_shift = 6; 1 << qp->sq.wqe_shift < size;
927 qp->sq.wqe_shift++) 995 qp->sq.wqe_shift++)
928 ; /* nothing */ 996 ; /* nothing */
@@ -1066,6 +1134,8 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
1066 return ret; 1134 return ret;
1067 } 1135 }
1068 1136
1137 mthca_adjust_qp_caps(dev, pd, qp);
1138
1069 /* 1139 /*
1070 * If this is a userspace QP, we're done now. The doorbells 1140 * If this is a userspace QP, we're done now. The doorbells
1071 * will be allocated and buffers will be initialized in 1141 * will be allocated and buffers will be initialized in
@@ -1486,8 +1556,8 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1486 } 1556 }
1487 1557
1488 wqe += sizeof (struct mthca_atomic_seg); 1558 wqe += sizeof (struct mthca_atomic_seg);
1489 size += sizeof (struct mthca_raddr_seg) / 16 + 1559 size += (sizeof (struct mthca_raddr_seg) +
1490 sizeof (struct mthca_atomic_seg); 1560 sizeof (struct mthca_atomic_seg)) / 16;
1491 break; 1561 break;
1492 1562
1493 case IB_WR_RDMA_WRITE: 1563 case IB_WR_RDMA_WRITE:
@@ -1637,6 +1707,7 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1637{ 1707{
1638 struct mthca_dev *dev = to_mdev(ibqp->device); 1708 struct mthca_dev *dev = to_mdev(ibqp->device);
1639 struct mthca_qp *qp = to_mqp(ibqp); 1709 struct mthca_qp *qp = to_mqp(ibqp);
1710 __be32 doorbell[2];
1640 unsigned long flags; 1711 unsigned long flags;
1641 int err = 0; 1712 int err = 0;
1642 int nreq; 1713 int nreq;
@@ -1654,6 +1725,22 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1654 ind = qp->rq.next_ind; 1725 ind = qp->rq.next_ind;
1655 1726
1656 for (nreq = 0; wr; ++nreq, wr = wr->next) { 1727 for (nreq = 0; wr; ++nreq, wr = wr->next) {
1728 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
1729 nreq = 0;
1730
1731 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1732 doorbell[1] = cpu_to_be32(qp->qpn << 8);
1733
1734 wmb();
1735
1736 mthca_write64(doorbell,
1737 dev->kar + MTHCA_RECEIVE_DOORBELL,
1738 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
1739
1740 qp->rq.head += MTHCA_TAVOR_MAX_WQES_PER_RECV_DB;
1741 size0 = 0;
1742 }
1743
1657 if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) { 1744 if (mthca_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) {
1658 mthca_err(dev, "RQ %06x full (%u head, %u tail," 1745 mthca_err(dev, "RQ %06x full (%u head, %u tail,"
1659 " %d max, %d nreq)\n", qp->qpn, 1746 " %d max, %d nreq)\n", qp->qpn,
@@ -1711,8 +1798,6 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
1711 1798
1712out: 1799out:
1713 if (likely(nreq)) { 1800 if (likely(nreq)) {
1714 __be32 doorbell[2];
1715
1716 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0); 1801 doorbell[0] = cpu_to_be32((qp->rq.next_ind << qp->rq.wqe_shift) | size0);
1717 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq); 1802 doorbell[1] = cpu_to_be32((qp->qpn << 8) | nreq);
1718 1803
@@ -1806,8 +1891,8 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
1806 } 1891 }
1807 1892
1808 wqe += sizeof (struct mthca_atomic_seg); 1893 wqe += sizeof (struct mthca_atomic_seg);
1809 size += sizeof (struct mthca_raddr_seg) / 16 + 1894 size += (sizeof (struct mthca_raddr_seg) +
1810 sizeof (struct mthca_atomic_seg); 1895 sizeof (struct mthca_atomic_seg)) / 16;
1811 break; 1896 break;
1812 1897
1813 case IB_WR_RDMA_READ: 1898 case IB_WR_RDMA_READ:
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c
index 292f55be8cbd..f7d234295efe 100644
--- a/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -32,6 +32,9 @@
32 * $Id: mthca_srq.c 3047 2005-08-10 03:59:35Z roland $ 32 * $Id: mthca_srq.c 3047 2005-08-10 03:59:35Z roland $
33 */ 33 */
34 34
35#include <linux/slab.h>
36#include <linux/string.h>
37
35#include "mthca_dev.h" 38#include "mthca_dev.h"
36#include "mthca_cmd.h" 39#include "mthca_cmd.h"
37#include "mthca_memfree.h" 40#include "mthca_memfree.h"
@@ -414,6 +417,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
414{ 417{
415 struct mthca_dev *dev = to_mdev(ibsrq->device); 418 struct mthca_dev *dev = to_mdev(ibsrq->device);
416 struct mthca_srq *srq = to_msrq(ibsrq); 419 struct mthca_srq *srq = to_msrq(ibsrq);
420 __be32 doorbell[2];
417 unsigned long flags; 421 unsigned long flags;
418 int err = 0; 422 int err = 0;
419 int first_ind; 423 int first_ind;
@@ -429,6 +433,25 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
429 first_ind = srq->first_free; 433 first_ind = srq->first_free;
430 434
431 for (nreq = 0; wr; ++nreq, wr = wr->next) { 435 for (nreq = 0; wr; ++nreq, wr = wr->next) {
436 if (unlikely(nreq == MTHCA_TAVOR_MAX_WQES_PER_RECV_DB)) {
437 nreq = 0;
438
439 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
440 doorbell[1] = cpu_to_be32(srq->srqn << 8);
441
442 /*
443 * Make sure that descriptors are written
444 * before doorbell is rung.
445 */
446 wmb();
447
448 mthca_write64(doorbell,
449 dev->kar + MTHCA_RECEIVE_DOORBELL,
450 MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
451
452 first_ind = srq->first_free;
453 }
454
432 ind = srq->first_free; 455 ind = srq->first_free;
433 456
434 if (ind < 0) { 457 if (ind < 0) {
@@ -491,8 +514,6 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
491 } 514 }
492 515
493 if (likely(nreq)) { 516 if (likely(nreq)) {
494 __be32 doorbell[2];
495
496 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift); 517 doorbell[0] = cpu_to_be32(first_ind << srq->wqe_shift);
497 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq); 518 doorbell[1] = cpu_to_be32((srq->srqn << 8) | nreq);
498 519
diff --git a/drivers/infiniband/hw/mthca/mthca_wqe.h b/drivers/infiniband/hw/mthca/mthca_wqe.h
index 1f4c0ff28f79..73f1c0b9021e 100644
--- a/drivers/infiniband/hw/mthca/mthca_wqe.h
+++ b/drivers/infiniband/hw/mthca/mthca_wqe.h
@@ -49,7 +49,8 @@ enum {
49}; 49};
50 50
51enum { 51enum {
52 MTHCA_INVAL_LKEY = 0x100 52 MTHCA_INVAL_LKEY = 0x100,
53 MTHCA_TAVOR_MAX_WQES_PER_RECV_DB = 256
53}; 54};
54 55
55struct mthca_next_seg { 56struct mthca_next_seg {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 0095acc0fbbe..9923a15a9996 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -179,6 +179,7 @@ struct ipoib_dev_priv {
179#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 179#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
180 struct list_head fs_list; 180 struct list_head fs_list;
181 struct dentry *mcg_dentry; 181 struct dentry *mcg_dentry;
182 struct dentry *path_dentry;
182#endif 183#endif
183}; 184};
184 185
@@ -270,7 +271,6 @@ void ipoib_mcast_dev_flush(struct net_device *dev);
270 271
271#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 272#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
272struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev); 273struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev);
273void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter);
274int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter); 274int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter);
275void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter, 275void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
276 union ib_gid *gid, 276 union ib_gid *gid,
@@ -278,6 +278,11 @@ void ipoib_mcast_iter_read(struct ipoib_mcast_iter *iter,
278 unsigned int *queuelen, 278 unsigned int *queuelen,
279 unsigned int *complete, 279 unsigned int *complete,
280 unsigned int *send_only); 280 unsigned int *send_only);
281
282struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev);
283int ipoib_path_iter_next(struct ipoib_path_iter *iter);
284void ipoib_path_iter_read(struct ipoib_path_iter *iter,
285 struct ipoib_path *path);
281#endif 286#endif
282 287
283int ipoib_mcast_attach(struct net_device *dev, u16 mlid, 288int ipoib_mcast_attach(struct net_device *dev, u16 mlid,
@@ -299,13 +304,13 @@ void ipoib_pkey_poll(void *dev);
299int ipoib_pkey_dev_delay_open(struct net_device *dev); 304int ipoib_pkey_dev_delay_open(struct net_device *dev);
300 305
301#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG 306#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
302int ipoib_create_debug_file(struct net_device *dev); 307void ipoib_create_debug_files(struct net_device *dev);
303void ipoib_delete_debug_file(struct net_device *dev); 308void ipoib_delete_debug_files(struct net_device *dev);
304int ipoib_register_debugfs(void); 309int ipoib_register_debugfs(void);
305void ipoib_unregister_debugfs(void); 310void ipoib_unregister_debugfs(void);
306#else 311#else
307static inline int ipoib_create_debug_file(struct net_device *dev) { return 0; } 312static inline void ipoib_create_debug_files(struct net_device *dev) { }
308static inline void ipoib_delete_debug_file(struct net_device *dev) { } 313static inline void ipoib_delete_debug_files(struct net_device *dev) { }
309static inline int ipoib_register_debugfs(void) { return 0; } 314static inline int ipoib_register_debugfs(void) { return 0; }
310static inline void ipoib_unregister_debugfs(void) { } 315static inline void ipoib_unregister_debugfs(void) { }
311#endif 316#endif
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index 38b150f775e7..685258e34034 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -43,6 +43,18 @@ struct file_operations;
43 43
44static struct dentry *ipoib_root; 44static struct dentry *ipoib_root;
45 45
46static void format_gid(union ib_gid *gid, char *buf)
47{
48 int i, n;
49
50 for (n = 0, i = 0; i < 8; ++i) {
51 n += sprintf(buf + n, "%x",
52 be16_to_cpu(((__be16 *) gid->raw)[i]));
53 if (i < 7)
54 buf[n++] = ':';
55 }
56}
57
46static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos) 58static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
47{ 59{
48 struct ipoib_mcast_iter *iter; 60 struct ipoib_mcast_iter *iter;
@@ -54,7 +66,7 @@ static void *ipoib_mcg_seq_start(struct seq_file *file, loff_t *pos)
54 66
55 while (n--) { 67 while (n--) {
56 if (ipoib_mcast_iter_next(iter)) { 68 if (ipoib_mcast_iter_next(iter)) {
57 ipoib_mcast_iter_free(iter); 69 kfree(iter);
58 return NULL; 70 return NULL;
59 } 71 }
60 } 72 }
@@ -70,7 +82,7 @@ static void *ipoib_mcg_seq_next(struct seq_file *file, void *iter_ptr,
70 (*pos)++; 82 (*pos)++;
71 83
72 if (ipoib_mcast_iter_next(iter)) { 84 if (ipoib_mcast_iter_next(iter)) {
73 ipoib_mcast_iter_free(iter); 85 kfree(iter);
74 return NULL; 86 return NULL;
75 } 87 }
76 88
@@ -87,32 +99,32 @@ static int ipoib_mcg_seq_show(struct seq_file *file, void *iter_ptr)
87 struct ipoib_mcast_iter *iter = iter_ptr; 99 struct ipoib_mcast_iter *iter = iter_ptr;
88 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; 100 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
89 union ib_gid mgid; 101 union ib_gid mgid;
90 int i, n;
91 unsigned long created; 102 unsigned long created;
92 unsigned int queuelen, complete, send_only; 103 unsigned int queuelen, complete, send_only;
93 104
94 if (iter) { 105 if (!iter)
95 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen, 106 return 0;
96 &complete, &send_only);
97 107
98 for (n = 0, i = 0; i < sizeof mgid / 2; ++i) { 108 ipoib_mcast_iter_read(iter, &mgid, &created, &queuelen,
99 n += sprintf(gid_buf + n, "%x", 109 &complete, &send_only);
100 be16_to_cpu(((__be16 *) mgid.raw)[i]));
101 if (i < sizeof mgid / 2 - 1)
102 gid_buf[n++] = ':';
103 }
104 }
105 110
106 seq_printf(file, "GID: %*s", -(1 + (int) sizeof gid_buf), gid_buf); 111 format_gid(&mgid, gid_buf);
107 112
108 seq_printf(file, 113 seq_printf(file,
109 " created: %10ld queuelen: %4d complete: %d send_only: %d\n", 114 "GID: %s\n"
110 created, queuelen, complete, send_only); 115 " created: %10ld\n"
116 " queuelen: %9d\n"
117 " complete: %9s\n"
118 " send_only: %8s\n"
119 "\n",
120 gid_buf, created, queuelen,
121 complete ? "yes" : "no",
122 send_only ? "yes" : "no");
111 123
112 return 0; 124 return 0;
113} 125}
114 126
115static struct seq_operations ipoib_seq_ops = { 127static struct seq_operations ipoib_mcg_seq_ops = {
116 .start = ipoib_mcg_seq_start, 128 .start = ipoib_mcg_seq_start,
117 .next = ipoib_mcg_seq_next, 129 .next = ipoib_mcg_seq_next,
118 .stop = ipoib_mcg_seq_stop, 130 .stop = ipoib_mcg_seq_stop,
@@ -124,7 +136,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
124 struct seq_file *seq; 136 struct seq_file *seq;
125 int ret; 137 int ret;
126 138
127 ret = seq_open(file, &ipoib_seq_ops); 139 ret = seq_open(file, &ipoib_mcg_seq_ops);
128 if (ret) 140 if (ret)
129 return ret; 141 return ret;
130 142
@@ -134,7 +146,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
134 return 0; 146 return 0;
135} 147}
136 148
137static struct file_operations ipoib_fops = { 149static struct file_operations ipoib_mcg_fops = {
138 .owner = THIS_MODULE, 150 .owner = THIS_MODULE,
139 .open = ipoib_mcg_open, 151 .open = ipoib_mcg_open,
140 .read = seq_read, 152 .read = seq_read,
@@ -142,25 +154,138 @@ static struct file_operations ipoib_fops = {
142 .release = seq_release 154 .release = seq_release
143}; 155};
144 156
145int ipoib_create_debug_file(struct net_device *dev) 157static void *ipoib_path_seq_start(struct seq_file *file, loff_t *pos)
158{
159 struct ipoib_path_iter *iter;
160 loff_t n = *pos;
161
162 iter = ipoib_path_iter_init(file->private);
163 if (!iter)
164 return NULL;
165
166 while (n--) {
167 if (ipoib_path_iter_next(iter)) {
168 kfree(iter);
169 return NULL;
170 }
171 }
172
173 return iter;
174}
175
176static void *ipoib_path_seq_next(struct seq_file *file, void *iter_ptr,
177 loff_t *pos)
178{
179 struct ipoib_path_iter *iter = iter_ptr;
180
181 (*pos)++;
182
183 if (ipoib_path_iter_next(iter)) {
184 kfree(iter);
185 return NULL;
186 }
187
188 return iter;
189}
190
191static void ipoib_path_seq_stop(struct seq_file *file, void *iter_ptr)
192{
193 /* nothing for now */
194}
195
196static int ipoib_path_seq_show(struct seq_file *file, void *iter_ptr)
197{
198 struct ipoib_path_iter *iter = iter_ptr;
199 char gid_buf[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"];
200 struct ipoib_path path;
201 int rate;
202
203 if (!iter)
204 return 0;
205
206 ipoib_path_iter_read(iter, &path);
207
208 format_gid(&path.pathrec.dgid, gid_buf);
209
210 seq_printf(file,
211 "GID: %s\n"
212 " complete: %6s\n",
213 gid_buf, path.pathrec.dlid ? "yes" : "no");
214
215 if (path.pathrec.dlid) {
216 rate = ib_sa_rate_enum_to_int(path.pathrec.rate) * 25;
217
218 seq_printf(file,
219 " DLID: 0x%04x\n"
220 " SL: %12d\n"
221 " rate: %*d%s Gb/sec\n",
222 be16_to_cpu(path.pathrec.dlid),
223 path.pathrec.sl,
224 10 - ((rate % 10) ? 2 : 0),
225 rate / 10, rate % 10 ? ".5" : "");
226 }
227
228 seq_putc(file, '\n');
229
230 return 0;
231}
232
233static struct seq_operations ipoib_path_seq_ops = {
234 .start = ipoib_path_seq_start,
235 .next = ipoib_path_seq_next,
236 .stop = ipoib_path_seq_stop,
237 .show = ipoib_path_seq_show,
238};
239
240static int ipoib_path_open(struct inode *inode, struct file *file)
241{
242 struct seq_file *seq;
243 int ret;
244
245 ret = seq_open(file, &ipoib_path_seq_ops);
246 if (ret)
247 return ret;
248
249 seq = file->private_data;
250 seq->private = inode->u.generic_ip;
251
252 return 0;
253}
254
255static struct file_operations ipoib_path_fops = {
256 .owner = THIS_MODULE,
257 .open = ipoib_path_open,
258 .read = seq_read,
259 .llseek = seq_lseek,
260 .release = seq_release
261};
262
263void ipoib_create_debug_files(struct net_device *dev)
146{ 264{
147 struct ipoib_dev_priv *priv = netdev_priv(dev); 265 struct ipoib_dev_priv *priv = netdev_priv(dev);
148 char name[IFNAMSIZ + sizeof "_mcg"]; 266 char name[IFNAMSIZ + sizeof "_path"];
149 267
150 snprintf(name, sizeof name, "%s_mcg", dev->name); 268 snprintf(name, sizeof name, "%s_mcg", dev->name);
151
152 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO, 269 priv->mcg_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
153 ipoib_root, dev, &ipoib_fops); 270 ipoib_root, dev, &ipoib_mcg_fops);
154 271 if (!priv->mcg_dentry)
155 return priv->mcg_dentry ? 0 : -ENOMEM; 272 ipoib_warn(priv, "failed to create mcg debug file\n");
273
274 snprintf(name, sizeof name, "%s_path", dev->name);
275 priv->path_dentry = debugfs_create_file(name, S_IFREG | S_IRUGO,
276 ipoib_root, dev, &ipoib_path_fops);
277 if (!priv->path_dentry)
278 ipoib_warn(priv, "failed to create path debug file\n");
156} 279}
157 280
158void ipoib_delete_debug_file(struct net_device *dev) 281void ipoib_delete_debug_files(struct net_device *dev)
159{ 282{
160 struct ipoib_dev_priv *priv = netdev_priv(dev); 283 struct ipoib_dev_priv *priv = netdev_priv(dev);
161 284
162 if (priv->mcg_dentry) 285 if (priv->mcg_dentry)
163 debugfs_remove(priv->mcg_dentry); 286 debugfs_remove(priv->mcg_dentry);
287 if (priv->path_dentry)
288 debugfs_remove(priv->path_dentry);
164} 289}
165 290
166int ipoib_register_debugfs(void) 291int ipoib_register_debugfs(void)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index ce0296273e76..2fa30751f362 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -58,6 +58,11 @@ module_param_named(debug_level, ipoib_debug_level, int, 0644);
58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0"); 58MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0");
59#endif 59#endif
60 60
61struct ipoib_path_iter {
62 struct net_device *dev;
63 struct ipoib_path path;
64};
65
61static const u8 ipv4_bcast_addr[] = { 66static const u8 ipv4_bcast_addr[] = {
62 0x00, 0xff, 0xff, 0xff, 67 0x00, 0xff, 0xff, 0xff,
63 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00, 68 0xff, 0x12, 0x40, 0x1b, 0x00, 0x00, 0x00, 0x00,
@@ -250,6 +255,64 @@ static void path_free(struct net_device *dev, struct ipoib_path *path)
250 kfree(path); 255 kfree(path);
251} 256}
252 257
258#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
259
260struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev)
261{
262 struct ipoib_path_iter *iter;
263
264 iter = kmalloc(sizeof *iter, GFP_KERNEL);
265 if (!iter)
266 return NULL;
267
268 iter->dev = dev;
269 memset(iter->path.pathrec.dgid.raw, 0, 16);
270
271 if (ipoib_path_iter_next(iter)) {
272 kfree(iter);
273 return NULL;
274 }
275
276 return iter;
277}
278
279int ipoib_path_iter_next(struct ipoib_path_iter *iter)
280{
281 struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
282 struct rb_node *n;
283 struct ipoib_path *path;
284 int ret = 1;
285
286 spin_lock_irq(&priv->lock);
287
288 n = rb_first(&priv->path_tree);
289
290 while (n) {
291 path = rb_entry(n, struct ipoib_path, rb_node);
292
293 if (memcmp(iter->path.pathrec.dgid.raw, path->pathrec.dgid.raw,
294 sizeof (union ib_gid)) < 0) {
295 iter->path = *path;
296 ret = 0;
297 break;
298 }
299
300 n = rb_next(n);
301 }
302
303 spin_unlock_irq(&priv->lock);
304
305 return ret;
306}
307
308void ipoib_path_iter_read(struct ipoib_path_iter *iter,
309 struct ipoib_path *path)
310{
311 *path = iter->path;
312}
313
314#endif /* CONFIG_INFINIBAND_IPOIB_DEBUG */
315
253void ipoib_flush_paths(struct net_device *dev) 316void ipoib_flush_paths(struct net_device *dev)
254{ 317{
255 struct ipoib_dev_priv *priv = netdev_priv(dev); 318 struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -763,7 +826,7 @@ void ipoib_dev_cleanup(struct net_device *dev)
763{ 826{
764 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv; 827 struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv, *tcpriv;
765 828
766 ipoib_delete_debug_file(dev); 829 ipoib_delete_debug_files(dev);
767 830
768 /* Delete any child interfaces first */ 831 /* Delete any child interfaces first */
769 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) { 832 list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
@@ -972,8 +1035,7 @@ static struct net_device *ipoib_add_port(const char *format,
972 goto register_failed; 1035 goto register_failed;
973 } 1036 }
974 1037
975 if (ipoib_create_debug_file(priv->dev)) 1038 ipoib_create_debug_files(priv->dev);
976 goto debug_failed;
977 1039
978 if (ipoib_add_pkey_attr(priv->dev)) 1040 if (ipoib_add_pkey_attr(priv->dev))
979 goto sysfs_failed; 1041 goto sysfs_failed;
@@ -987,9 +1049,7 @@ static struct net_device *ipoib_add_port(const char *format,
987 return priv->dev; 1049 return priv->dev;
988 1050
989sysfs_failed: 1051sysfs_failed:
990 ipoib_delete_debug_file(priv->dev); 1052 ipoib_delete_debug_files(priv->dev);
991
992debug_failed:
993 unregister_netdev(priv->dev); 1053 unregister_netdev(priv->dev);
994 1054
995register_failed: 1055register_failed:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 3ecf78a9493a..c33ed87f9dff 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -120,12 +120,8 @@ static void ipoib_mcast_free(struct ipoib_mcast *mcast)
120 if (mcast->ah) 120 if (mcast->ah)
121 ipoib_put_ah(mcast->ah); 121 ipoib_put_ah(mcast->ah);
122 122
123 while (!skb_queue_empty(&mcast->pkt_queue)) { 123 while (!skb_queue_empty(&mcast->pkt_queue))
124 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 124 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
125
126 skb->dev = dev;
127 dev_kfree_skb_any(skb);
128 }
129 125
130 kfree(mcast); 126 kfree(mcast);
131} 127}
@@ -317,13 +313,8 @@ ipoib_mcast_sendonly_join_complete(int status,
317 IPOIB_GID_ARG(mcast->mcmember.mgid), status); 313 IPOIB_GID_ARG(mcast->mcmember.mgid), status);
318 314
319 /* Flush out any queued packets */ 315 /* Flush out any queued packets */
320 while (!skb_queue_empty(&mcast->pkt_queue)) { 316 while (!skb_queue_empty(&mcast->pkt_queue))
321 struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue); 317 dev_kfree_skb_any(skb_dequeue(&mcast->pkt_queue));
322
323 skb->dev = dev;
324
325 dev_kfree_skb_any(skb);
326 }
327 318
328 /* Clear the busy flag so we try again */ 319 /* Clear the busy flag so we try again */
329 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); 320 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
@@ -928,21 +919,16 @@ struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev)
928 return NULL; 919 return NULL;
929 920
930 iter->dev = dev; 921 iter->dev = dev;
931 memset(iter->mgid.raw, 0, sizeof iter->mgid); 922 memset(iter->mgid.raw, 0, 16);
932 923
933 if (ipoib_mcast_iter_next(iter)) { 924 if (ipoib_mcast_iter_next(iter)) {
934 ipoib_mcast_iter_free(iter); 925 kfree(iter);
935 return NULL; 926 return NULL;
936 } 927 }
937 928
938 return iter; 929 return iter;
939} 930}
940 931
941void ipoib_mcast_iter_free(struct ipoib_mcast_iter *iter)
942{
943 kfree(iter);
944}
945
946int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter) 932int ipoib_mcast_iter_next(struct ipoib_mcast_iter *iter)
947{ 933{
948 struct ipoib_dev_priv *priv = netdev_priv(iter->dev); 934 struct ipoib_dev_priv *priv = netdev_priv(iter->dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 332d730e60c2..d280b341a37f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -113,8 +113,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
113 113
114 priv->parent = ppriv->dev; 114 priv->parent = ppriv->dev;
115 115
116 if (ipoib_create_debug_file(priv->dev)) 116 ipoib_create_debug_files(priv->dev);
117 goto debug_failed;
118 117
119 if (ipoib_add_pkey_attr(priv->dev)) 118 if (ipoib_add_pkey_attr(priv->dev))
120 goto sysfs_failed; 119 goto sysfs_failed;
@@ -130,9 +129,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
130 return 0; 129 return 0;
131 130
132sysfs_failed: 131sysfs_failed:
133 ipoib_delete_debug_file(priv->dev); 132 ipoib_delete_debug_files(priv->dev);
134
135debug_failed:
136 unregister_netdev(priv->dev); 133 unregister_netdev(priv->dev);
137 134
138register_failed: 135register_failed:
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 2687e34aa5bc..321a3a10e69b 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -32,7 +32,6 @@
32 * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $ 32 * $Id: ib_srp.c 3932 2005-11-01 17:19:29Z roland $
33 */ 33 */
34 34
35#include <linux/version.h>
36#include <linux/module.h> 35#include <linux/module.h>
37#include <linux/init.h> 36#include <linux/init.h>
38#include <linux/slab.h> 37#include <linux/slab.h>
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 1a1654caedd5..c8ae2bb054e0 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -377,7 +377,7 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int
377 377
378 list_for_each_entry(dev, &input_dev_list, node) { 378 list_for_each_entry(dev, &input_dev_list, node) {
379 379
380 path = dev->dynalloc ? kobject_get_path(&dev->cdev.kobj, GFP_KERNEL) : NULL; 380 path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
381 381
382 len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", 382 len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
383 dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); 383 dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
@@ -669,7 +669,7 @@ static int input_dev_hotplug(struct class_device *cdev, char **envp,
669 INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name); 669 INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name);
670 if (dev->phys) 670 if (dev->phys)
671 INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys); 671 INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys);
672 if (dev->phys) 672 if (dev->uniq)
673 INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq); 673 INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);
674 674
675 INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX); 675 INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);
@@ -741,15 +741,21 @@ static void input_register_classdevice(struct input_dev *dev)
741 sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group); 741 sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
742} 742}
743 743
744void input_register_device(struct input_dev *dev) 744int input_register_device(struct input_dev *dev)
745{ 745{
746 struct input_handle *handle; 746 struct input_handle *handle;
747 struct input_handler *handler; 747 struct input_handler *handler;
748 struct input_device_id *id; 748 struct input_device_id *id;
749 749
750 set_bit(EV_SYN, dev->evbit); 750 if (!dev->dynalloc) {
751 printk(KERN_WARNING "input: device %s is statically allocated, will not register\n"
752 "Please convert to input_allocate_device() or contact dtor_core@ameritech.net\n",
753 dev->name ? dev->name : "<Unknown>");
754 return -EINVAL;
755 }
751 756
752 init_MUTEX(&dev->sem); 757 init_MUTEX(&dev->sem);
758 set_bit(EV_SYN, dev->evbit);
753 759
754 /* 760 /*
755 * If delay and period are pre-set by the driver, then autorepeating 761 * If delay and period are pre-set by the driver, then autorepeating
@@ -767,8 +773,7 @@ void input_register_device(struct input_dev *dev)
767 INIT_LIST_HEAD(&dev->h_list); 773 INIT_LIST_HEAD(&dev->h_list);
768 list_add_tail(&dev->node, &input_dev_list); 774 list_add_tail(&dev->node, &input_dev_list);
769 775
770 if (dev->dynalloc) 776 input_register_classdevice(dev);
771 input_register_classdevice(dev);
772 777
773 list_for_each_entry(handler, &input_handler_list, node) 778 list_for_each_entry(handler, &input_handler_list, node)
774 if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) 779 if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
@@ -776,8 +781,9 @@ void input_register_device(struct input_dev *dev)
776 if ((handle = handler->connect(handler, dev, id))) 781 if ((handle = handler->connect(handler, dev, id)))
777 input_link_handle(handle); 782 input_link_handle(handle);
778 783
779
780 input_wakeup_procfs_readers(); 784 input_wakeup_procfs_readers();
785
786 return 0;
781} 787}
782 788
783void input_unregister_device(struct input_dev *dev) 789void input_unregister_device(struct input_dev *dev)
@@ -797,11 +803,10 @@ void input_unregister_device(struct input_dev *dev)
797 803
798 list_del_init(&dev->node); 804 list_del_init(&dev->node);
799 805
800 if (dev->dynalloc) { 806 sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
801 sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); 807 sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
802 sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); 808 sysfs_remove_group(&dev->cdev.kobj, &input_dev_group);
803 class_device_unregister(&dev->cdev); 809 class_device_unregister(&dev->cdev);
804 }
805 810
806 input_wakeup_procfs_readers(); 811 input_wakeup_procfs_readers();
807} 812}
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 9481132532d0..77c4d9669ad0 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -273,11 +273,11 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = {
273 [0xfb] = KEY_APOSTROPHE, 273 [0xfb] = KEY_APOSTROPHE,
274}; 274};
275 275
276#define CHECK_LED(LED, BITS) do { \ 276#define CHECK_LED(LK, VAR_ON, VAR_OFF, LED, BITS) do { \
277 if (test_bit (LED, lk->dev->led)) \ 277 if (test_bit (LED, (LK)->dev->led)) \
278 leds_on |= BITS; \ 278 VAR_ON |= BITS; \
279 else \ 279 else \
280 leds_off |= BITS; \ 280 VAR_OFF |= BITS; \
281 } while (0) 281 } while (0)
282 282
283/* 283/*
@@ -298,6 +298,42 @@ struct lkkbd {
298 int ctrlclick_volume; 298 int ctrlclick_volume;
299}; 299};
300 300
301#ifdef LKKBD_DEBUG
302/*
303 * Responses from the keyboard and mapping back to their names.
304 */
305static struct {
306 unsigned char value;
307 unsigned char *name;
308} lk_response[] = {
309#define RESPONSE(x) { .value = (x), .name = #x, }
310 RESPONSE (LK_STUCK_KEY),
311 RESPONSE (LK_SELFTEST_FAILED),
312 RESPONSE (LK_ALL_KEYS_UP),
313 RESPONSE (LK_METRONOME),
314 RESPONSE (LK_OUTPUT_ERROR),
315 RESPONSE (LK_INPUT_ERROR),
316 RESPONSE (LK_KBD_LOCKED),
317 RESPONSE (LK_KBD_TEST_MODE_ACK),
318 RESPONSE (LK_PREFIX_KEY_DOWN),
319 RESPONSE (LK_MODE_CHANGE_ACK),
320 RESPONSE (LK_RESPONSE_RESERVED),
321#undef RESPONSE
322};
323
324static unsigned char *
325response_name (unsigned char value)
326{
327 int i;
328
329 for (i = 0; i < ARRAY_SIZE (lk_response); i++)
330 if (lk_response[i].value == value)
331 return lk_response[i].name;
332
333 return "<unknown>";
334}
335#endif /* LKKBD_DEBUG */
336
301/* 337/*
302 * Calculate volume parameter byte for a given volume. 338 * Calculate volume parameter byte for a given volume.
303 */ 339 */
@@ -440,43 +476,24 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
440 input_report_key (lk->dev, lk->keycode[i], 0); 476 input_report_key (lk->dev, lk->keycode[i], 0);
441 input_sync (lk->dev); 477 input_sync (lk->dev);
442 break; 478 break;
443 case LK_METRONOME: 479
444 DBG (KERN_INFO "Got LK_METRONOME and don't " 480 case 0x01:
445 "know how to handle...\n"); 481 DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n");
482 lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
483 lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
484 schedule_work (&lk->tq);
446 break; 485 break;
486
487 case LK_METRONOME:
447 case LK_OUTPUT_ERROR: 488 case LK_OUTPUT_ERROR:
448 DBG (KERN_INFO "Got LK_OUTPUT_ERROR and don't "
449 "know how to handle...\n");
450 break;
451 case LK_INPUT_ERROR: 489 case LK_INPUT_ERROR:
452 DBG (KERN_INFO "Got LK_INPUT_ERROR and don't "
453 "know how to handle...\n");
454 break;
455 case LK_KBD_LOCKED: 490 case LK_KBD_LOCKED:
456 DBG (KERN_INFO "Got LK_KBD_LOCKED and don't "
457 "know how to handle...\n");
458 break;
459 case LK_KBD_TEST_MODE_ACK: 491 case LK_KBD_TEST_MODE_ACK:
460 DBG (KERN_INFO "Got LK_KBD_TEST_MODE_ACK and don't "
461 "know how to handle...\n");
462 break;
463 case LK_PREFIX_KEY_DOWN: 492 case LK_PREFIX_KEY_DOWN:
464 DBG (KERN_INFO "Got LK_PREFIX_KEY_DOWN and don't "
465 "know how to handle...\n");
466 break;
467 case LK_MODE_CHANGE_ACK: 493 case LK_MODE_CHANGE_ACK:
468 DBG (KERN_INFO "Got LK_MODE_CHANGE_ACK and ignored "
469 "it properly...\n");
470 break;
471 case LK_RESPONSE_RESERVED: 494 case LK_RESPONSE_RESERVED:
472 DBG (KERN_INFO "Got LK_RESPONSE_RESERVED and don't " 495 DBG (KERN_INFO "Got %s and don't know how to handle...\n",
473 "know how to handle...\n"); 496 response_name (data));
474 break;
475 case 0x01:
476 DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n");
477 lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
478 lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
479 schedule_work (&lk->tq);
480 break; 497 break;
481 498
482 default: 499 default:
@@ -509,10 +526,10 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
509 526
510 switch (type) { 527 switch (type) {
511 case EV_LED: 528 case EV_LED:
512 CHECK_LED (LED_CAPSL, LK_LED_SHIFTLOCK); 529 CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
513 CHECK_LED (LED_COMPOSE, LK_LED_COMPOSE); 530 CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
514 CHECK_LED (LED_SCROLLL, LK_LED_SCROLLLOCK); 531 CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
515 CHECK_LED (LED_SLEEP, LK_LED_WAIT); 532 CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
516 if (leds_on != 0) { 533 if (leds_on != 0) {
517 lk->serio->write (lk->serio, LK_CMD_LED_ON); 534 lk->serio->write (lk->serio, LK_CMD_LED_ON);
518 lk->serio->write (lk->serio, leds_on); 535 lk->serio->write (lk->serio, leds_on);
@@ -574,10 +591,10 @@ lkkbd_reinit (void *data)
574 lk->serio->write (lk->serio, LK_CMD_SET_DEFAULTS); 591 lk->serio->write (lk->serio, LK_CMD_SET_DEFAULTS);
575 592
576 /* Set LEDs */ 593 /* Set LEDs */
577 CHECK_LED (LED_CAPSL, LK_LED_SHIFTLOCK); 594 CHECK_LED (lk, leds_on, leds_off, LED_CAPSL, LK_LED_SHIFTLOCK);
578 CHECK_LED (LED_COMPOSE, LK_LED_COMPOSE); 595 CHECK_LED (lk, leds_on, leds_off, LED_COMPOSE, LK_LED_COMPOSE);
579 CHECK_LED (LED_SCROLLL, LK_LED_SCROLLLOCK); 596 CHECK_LED (lk, leds_on, leds_off, LED_SCROLLL, LK_LED_SCROLLLOCK);
580 CHECK_LED (LED_SLEEP, LK_LED_WAIT); 597 CHECK_LED (lk, leds_on, leds_off, LED_SLEEP, LK_LED_WAIT);
581 if (leds_on != 0) { 598 if (leds_on != 0) {
582 lk->serio->write (lk->serio, LK_CMD_LED_ON); 599 lk->serio->write (lk->serio, LK_CMD_LED_ON);
583 lk->serio->write (lk->serio, leds_on); 600 lk->serio->write (lk->serio, leds_on);
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index 8935290256b3..2c510881874a 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -76,7 +76,7 @@ static unsigned char locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
76 76
77struct locomokbd { 77struct locomokbd {
78 unsigned char keycode[LOCOMOKBD_NUMKEYS]; 78 unsigned char keycode[LOCOMOKBD_NUMKEYS];
79 struct input_dev input; 79 struct input_dev *input;
80 char phys[32]; 80 char phys[32];
81 81
82 struct locomo_dev *ldev; 82 struct locomo_dev *ldev;
@@ -136,8 +136,7 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *
136 136
137 spin_lock_irqsave(&locomokbd->lock, flags); 137 spin_lock_irqsave(&locomokbd->lock, flags);
138 138
139 if (regs) 139 input_regs(locomokbd->input, regs);
140 input_regs(&locomokbd->input, regs);
141 140
142 locomokbd_charge_all(membase); 141 locomokbd_charge_all(membase);
143 142
@@ -152,16 +151,16 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd, struct pt_regs *
152 scancode = SCANCODE(col, row); 151 scancode = SCANCODE(col, row);
153 if (rowd & KB_ROWMASK(row)) { 152 if (rowd & KB_ROWMASK(row)) {
154 num_pressed += 1; 153 num_pressed += 1;
155 input_report_key(&locomokbd->input, locomokbd->keycode[scancode], 1); 154 input_report_key(locomokbd->input, locomokbd->keycode[scancode], 1);
156 } else { 155 } else {
157 input_report_key(&locomokbd->input, locomokbd->keycode[scancode], 0); 156 input_report_key(locomokbd->input, locomokbd->keycode[scancode], 0);
158 } 157 }
159 } 158 }
160 locomokbd_reset_col(membase, col); 159 locomokbd_reset_col(membase, col);
161 } 160 }
162 locomokbd_activate_all(membase); 161 locomokbd_activate_all(membase);
163 162
164 input_sync(&locomokbd->input); 163 input_sync(locomokbd->input);
165 164
166 /* if any keys are pressed, enable the timer */ 165 /* if any keys are pressed, enable the timer */
167 if (num_pressed) 166 if (num_pressed)
@@ -196,13 +195,15 @@ static void locomokbd_timer_callback(unsigned long data)
196static int locomokbd_probe(struct locomo_dev *dev) 195static int locomokbd_probe(struct locomo_dev *dev)
197{ 196{
198 struct locomokbd *locomokbd; 197 struct locomokbd *locomokbd;
198 struct input_dev *input_dev;
199 int i, ret; 199 int i, ret;
200 200
201 locomokbd = kmalloc(sizeof(struct locomokbd), GFP_KERNEL); 201 locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL);
202 if (!locomokbd) 202 input_dev = input_allocate_device();
203 return -ENOMEM; 203 if (!locomokbd || !input_dev) {
204 204 ret = -ENOMEM;
205 memset(locomokbd, 0, sizeof(struct locomokbd)); 205 goto free;
206 }
206 207
207 /* try and claim memory region */ 208 /* try and claim memory region */
208 if (!request_mem_region((unsigned long) dev->mapbase, 209 if (!request_mem_region((unsigned long) dev->mapbase,
@@ -224,27 +225,26 @@ static int locomokbd_probe(struct locomo_dev *dev)
224 locomokbd->timer.function = locomokbd_timer_callback; 225 locomokbd->timer.function = locomokbd_timer_callback;
225 locomokbd->timer.data = (unsigned long) locomokbd; 226 locomokbd->timer.data = (unsigned long) locomokbd;
226 227
227 locomokbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP); 228 locomokbd->input = input_dev;
229 strcpy(locomokbd->phys, "locomokbd/input0");
230
231 input_dev->name = "LoCoMo keyboard";
232 input_dev->phys = locomokbd->phys;
233 input_dev->id.bustype = BUS_HOST;
234 input_dev->id.vendor = 0x0001;
235 input_dev->id.product = 0x0001;
236 input_dev->id.version = 0x0100;
237 input_dev->private = locomokbd;
228 238
229 init_input_dev(&locomokbd->input); 239 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
230 locomokbd->input.keycode = locomokbd->keycode; 240 input_dev->keycode = locomokbd->keycode;
231 locomokbd->input.keycodesize = sizeof(unsigned char); 241 input_dev->keycodesize = sizeof(unsigned char);
232 locomokbd->input.keycodemax = ARRAY_SIZE(locomokbd_keycode); 242 input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode);
233 locomokbd->input.private = locomokbd;
234 243
235 memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode)); 244 memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
236 for (i = 0; i < LOCOMOKBD_NUMKEYS; i++) 245 for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
237 set_bit(locomokbd->keycode[i], locomokbd->input.keybit); 246 set_bit(locomokbd->keycode[i], input_dev->keybit);
238 clear_bit(0, locomokbd->input.keybit); 247 clear_bit(0, input_dev->keybit);
239
240 strcpy(locomokbd->phys, "locomokbd/input0");
241
242 locomokbd->input.name = "LoCoMo keyboard";
243 locomokbd->input.phys = locomokbd->phys;
244 locomokbd->input.id.bustype = BUS_XTKBD;
245 locomokbd->input.id.vendor = 0x0001;
246 locomokbd->input.id.product = 0x0001;
247 locomokbd->input.id.version = 0x0100;
248 248
249 /* attempt to get the interrupt */ 249 /* attempt to get the interrupt */
250 ret = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd); 250 ret = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
@@ -253,9 +253,7 @@ static int locomokbd_probe(struct locomo_dev *dev)
253 goto out; 253 goto out;
254 } 254 }
255 255
256 input_register_device(&locomokbd->input); 256 input_register_device(locomokbd->input);
257
258 printk(KERN_INFO "input: LoCoMo keyboard on locomokbd\n");
259 257
260 return 0; 258 return 0;
261 259
@@ -263,6 +261,7 @@ out:
263 release_mem_region((unsigned long) dev->mapbase, dev->length); 261 release_mem_region((unsigned long) dev->mapbase, dev->length);
264 locomo_set_drvdata(dev, NULL); 262 locomo_set_drvdata(dev, NULL);
265free: 263free:
264 input_free_device(input_dev);
266 kfree(locomokbd); 265 kfree(locomokbd);
267 266
268 return ret; 267 return ret;
@@ -276,7 +275,7 @@ static int locomokbd_remove(struct locomo_dev *dev)
276 275
277 del_timer_sync(&locomokbd->timer); 276 del_timer_sync(&locomokbd->timer);
278 277
279 input_unregister_device(&locomokbd->input); 278 input_unregister_device(locomokbd->input);
280 locomo_set_drvdata(dev, NULL); 279 locomo_set_drvdata(dev, NULL);
281 280
282 release_mem_region((unsigned long) dev->mapbase, dev->length); 281 release_mem_region((unsigned long) dev->mapbase, dev->length);
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 4015a91f4b6e..948c1cc01bc9 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -271,8 +271,7 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz
271 goto exit; 271 goto exit;
272 } 272 }
273 273
274 if (dev->name) 274 kfree(dev->name);
275 kfree(dev->name);
276 275
277 size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1; 276 size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
278 dev->name = name = kmalloc(size, GFP_KERNEL); 277 dev->name = name = kmalloc(size, GFP_KERNEL);
@@ -372,11 +371,8 @@ static int uinput_burn_device(struct uinput_device *udev)
372 if (test_bit(UIST_CREATED, &udev->state)) 371 if (test_bit(UIST_CREATED, &udev->state))
373 uinput_destroy_device(udev); 372 uinput_destroy_device(udev);
374 373
375 if (udev->dev->name) 374 kfree(udev->dev->name);
376 kfree(udev->dev->name); 375 kfree(udev->dev->phys);
377 if (udev->dev->phys)
378 kfree(udev->dev->phys);
379
380 kfree(udev->dev); 376 kfree(udev->dev);
381 kfree(udev); 377 kfree(udev);
382 378
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 0f69ff46c1ae..31a59f7abfaf 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -217,6 +217,9 @@ static struct ps2pp_info *get_model_info(unsigned char model)
217 { 61, PS2PP_KIND_MX, /* MX700 */ 217 { 61, PS2PP_KIND_MX, /* MX700 */
218 PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | 218 PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
219 PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, 219 PS2PP_EXTRA_BTN | PS2PP_NAV_BTN },
220 { 66, PS2PP_KIND_MX, /* MX3100 reciver */
221 PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN |
222 PS2PP_EXTRA_BTN | PS2PP_NAV_BTN | PS2PP_HWHEEL },
220 { 73, 0, PS2PP_SIDE_BTN }, 223 { 73, 0, PS2PP_SIDE_BTN },
221 { 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, 224 { 75, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
222 { 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL }, 225 { 76, PS2PP_KIND_WHEEL, PS2PP_WHEEL },
diff --git a/drivers/isdn/divert/divert_init.c b/drivers/isdn/divert/divert_init.c
index 434e684f5dbb..2f7c9fc2e898 100644
--- a/drivers/isdn/divert/divert_init.c
+++ b/drivers/isdn/divert/divert_init.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/version.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16 15
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 0b0ea26023e5..1b37d86d5ee1 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,7 +11,6 @@
11 11
12#include <linux/config.h> 12#include <linux/config.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/poll.h> 14#include <linux/poll.h>
16#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
17#ifdef CONFIG_PROC_FS 16#ifdef CONFIG_PROC_FS
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 0bfd698726a6..f1a1f9a9b88e 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -9,7 +9,6 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/version.h>
13#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
14 13
15#include "isdn_divert.h" 14#include "isdn_divert.h"
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index db9bad2b3d16..27391c32f3eb 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -212,11 +212,8 @@ static void avmcs_detach(dev_link_t *link)
212 212
213 /* Unlink device structure, free pieces */ 213 /* Unlink device structure, free pieces */
214 *linkp = link->next; 214 *linkp = link->next;
215 if (link->priv) { 215 kfree(link->priv);
216 kfree(link->priv);
217 }
218 kfree(link); 216 kfree(link);
219
220} /* avmcs_detach */ 217} /* avmcs_detach */
221 218
222/*====================================================================== 219/*======================================================================
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 625799ab0d14..5d8ee7368f7b 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -552,14 +552,10 @@ close_hdlcstate(struct BCState *bcs)
552{ 552{
553 modehdlc(bcs, 0, 0); 553 modehdlc(bcs, 0, 0);
554 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 554 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
555 if (bcs->hw.hdlc.rcvbuf) { 555 kfree(bcs->hw.hdlc.rcvbuf);
556 kfree(bcs->hw.hdlc.rcvbuf); 556 bcs->hw.hdlc.rcvbuf = NULL;
557 bcs->hw.hdlc.rcvbuf = NULL; 557 kfree(bcs->blog);
558 } 558 bcs->blog = NULL;
559 if (bcs->blog) {
560 kfree(bcs->blog);
561 bcs->blog = NULL;
562 }
563 skb_queue_purge(&bcs->rqueue); 559 skb_queue_purge(&bcs->rqueue);
564 skb_queue_purge(&bcs->squeue); 560 skb_queue_purge(&bcs->squeue);
565 if (bcs->tx_skb) { 561 if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 0e22991635e7..5f5a5ae740d2 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -236,9 +236,7 @@ static void avma1cs_detach(dev_link_t *link)
236 236
237 /* Unlink device structure, free pieces */ 237 /* Unlink device structure, free pieces */
238 *linkp = link->next; 238 *linkp = link->next;
239 if (link->priv) { 239 kfree(link->priv);
240 kfree(link->priv);
241 }
242 kfree(link); 240 kfree(link);
243 241
244} /* avma1cs_detach */ 242} /* avma1cs_detach */
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index fbaab4352902..8159bcecd0c2 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -787,8 +787,7 @@ static void ll_unload(struct IsdnCardState *cs)
787 ic.command = ISDN_STAT_UNLOAD; 787 ic.command = ISDN_STAT_UNLOAD;
788 ic.driver = cs->myid; 788 ic.driver = cs->myid;
789 cs->iif.statcallb(&ic); 789 cs->iif.statcallb(&ic);
790 if (cs->status_buf) 790 kfree(cs->status_buf);
791 kfree(cs->status_buf);
792 cs->status_read = NULL; 791 cs->status_read = NULL;
793 cs->status_write = NULL; 792 cs->status_write = NULL;
794 cs->status_end = NULL; 793 cs->status_end = NULL;
@@ -807,10 +806,8 @@ static void closecard(int cardnr)
807 806
808 skb_queue_purge(&csta->rq); 807 skb_queue_purge(&csta->rq);
809 skb_queue_purge(&csta->sq); 808 skb_queue_purge(&csta->sq);
810 if (csta->rcvbuf) { 809 kfree(csta->rcvbuf);
811 kfree(csta->rcvbuf); 810 csta->rcvbuf = NULL;
812 csta->rcvbuf = NULL;
813 }
814 if (csta->tx_skb) { 811 if (csta->tx_skb) {
815 dev_kfree_skb(csta->tx_skb); 812 dev_kfree_skb(csta->tx_skb);
816 csta->tx_skb = NULL; 813 csta->tx_skb = NULL;
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 7cf87793e790..637a261c9312 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -1052,18 +1052,12 @@ init2bds0(struct IsdnCardState *cs)
1052void 1052void
1053release2bds0(struct IsdnCardState *cs) 1053release2bds0(struct IsdnCardState *cs)
1054{ 1054{
1055 if (cs->bcs[0].hw.hfc.send) { 1055 kfree(cs->bcs[0].hw.hfc.send);
1056 kfree(cs->bcs[0].hw.hfc.send); 1056 cs->bcs[0].hw.hfc.send = NULL;
1057 cs->bcs[0].hw.hfc.send = NULL; 1057 kfree(cs->bcs[1].hw.hfc.send);
1058 } 1058 cs->bcs[1].hw.hfc.send = NULL;
1059 if (cs->bcs[1].hw.hfc.send) { 1059 kfree(cs->hw.hfcD.send);
1060 kfree(cs->bcs[1].hw.hfc.send); 1060 cs->hw.hfcD.send = NULL;
1061 cs->bcs[1].hw.hfc.send = NULL;
1062 }
1063 if (cs->hw.hfcD.send) {
1064 kfree(cs->hw.hfcD.send);
1065 cs->hw.hfcD.send = NULL;
1066 }
1067} 1061}
1068 1062
1069void 1063void
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index f978a5af8662..c964539cc43e 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -582,12 +582,8 @@ inithfc(struct IsdnCardState *cs)
582void 582void
583releasehfc(struct IsdnCardState *cs) 583releasehfc(struct IsdnCardState *cs)
584{ 584{
585 if (cs->bcs[0].hw.hfc.send) { 585 kfree(cs->bcs[0].hw.hfc.send);
586 kfree(cs->bcs[0].hw.hfc.send); 586 cs->bcs[0].hw.hfc.send = NULL;
587 cs->bcs[0].hw.hfc.send = NULL; 587 kfree(cs->bcs[1].hw.hfc.send);
588 } 588 cs->bcs[1].hw.hfc.send = NULL;
589 if (cs->bcs[1].hw.hfc.send) {
590 kfree(cs->bcs[1].hw.hfc.send);
591 cs->bcs[1].hw.hfc.send = NULL;
592 }
593} 589}
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index e2c3af49d72b..32bf0d5d0f9a 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * hfc_usb.c 2 * hfc_usb.c
3 * 3 *
4 * $Id: hfc_usb.c,v 4.34 2005/01/26 17:25:53 martinb1 Exp $ 4 * $Id: hfc_usb.c,v 4.36 2005/04/08 09:55:13 martinb1 Exp $
5 * 5 *
6 * modular HiSax ISDN driver for Colognechip HFC-S USB chip 6 * modular HiSax ISDN driver for Colognechip HFC-S USB chip
7 * 7 *
@@ -44,12 +44,8 @@
44#include "hisax_if.h" 44#include "hisax_if.h"
45#include "hfc_usb.h" 45#include "hfc_usb.h"
46 46
47/*
48* Version Information
49* (do not modify the CVS Makros $Revision: 4.34 $ and $Date: 2005/01/26 17:25:53 $ !)
50*/
51static const char *hfcusb_revision = 47static const char *hfcusb_revision =
52 "Revision: 4.34 $ Date: 2005/01/26 17:25:53 $ "; 48 "$Revision: 4.36 $ $Date: 2005/04/08 09:55:13 $ ";
53 49
54/* Hisax debug support 50/* Hisax debug support
55* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG 51* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG
@@ -63,81 +59,89 @@ module_param(debug, uint, 0);
63static int hfc_debug; 59static int hfc_debug;
64#endif 60#endif
65 61
62/* private vendor specific data */
63typedef struct {
64 __u8 led_scheme; // led display scheme
65 signed short led_bits[8]; // array of 8 possible LED bitmask settings
66 char *vend_name; // device name
67} hfcsusb_vdata;
66 68
67/****************************************/ 69/****************************************/
68/* data defining the devices to be used */ 70/* data defining the devices to be used */
69/****************************************/ 71/****************************************/
70static struct usb_device_id hfc_usb_idtab[] = { 72static struct usb_device_id hfcusb_idtab[] = {
71 {USB_DEVICE(0x0959, 0x2bd0)}, /* Colognechip USB eval TA */ 73 {
72 {USB_DEVICE(0x0675, 0x1688)}, /* DrayTek miniVigor 128 USB ISDN TA */ 74 .idVendor = 0x0959,
73 {USB_DEVICE(0x07b0, 0x0007)}, /* Billion USB TA 2 */ 75 .idProduct = 0x2bd0,
74 {USB_DEVICE(0x0742, 0x2008)}, /* Stollmann USB TA */ 76 .driver_info = (unsigned long) &((hfcsusb_vdata)
75 {USB_DEVICE(0x0742, 0x2009)}, /* Aceex USB ISDN TA */ 77 {LED_OFF, {4, 0, 2, 1},
76 {USB_DEVICE(0x0742, 0x200A)}, /* OEM USB ISDN TA */ 78 "ISDN USB TA (Cologne Chip HFC-S USB based)"}),
77 {USB_DEVICE(0x08e3, 0x0301)}, /* OliTec ISDN USB */ 79 },
78 {USB_DEVICE(0x07fa, 0x0846)}, /* Bewan ISDN USB TA */ 80 {
79 {USB_DEVICE(0x07fa, 0x0847)}, /* Djinn Numeris USB */ 81 .idVendor = 0x0675,
80 {USB_DEVICE(0x07b0, 0x0006)}, /* Twister ISDN USB TA */ 82 .idProduct = 0x1688,
81 {} /* end with an all-zeroes entry */ 83 .driver_info = (unsigned long) &((hfcsusb_vdata)
84 {LED_SCHEME1, {1, 2, 0, 0},
85 "DrayTek miniVigor 128 USB ISDN TA"}),
86 },
87 {
88 .idVendor = 0x07b0,
89 .idProduct = 0x0007,
90 .driver_info = (unsigned long) &((hfcsusb_vdata)
91 {LED_SCHEME1, {0x80, -64, -32, -16},
92 "Billion tiny USB ISDN TA 128"}),
93 },
94 {
95 .idVendor = 0x0742,
96 .idProduct = 0x2008,
97 .driver_info = (unsigned long) &((hfcsusb_vdata)
98 {LED_SCHEME1, {4, 0, 2, 1},
99 "Stollmann USB TA"}),
100 },
101 {
102 .idVendor = 0x0742,
103 .idProduct = 0x2009,
104 .driver_info = (unsigned long) &((hfcsusb_vdata)
105 {LED_SCHEME1, {4, 0, 2, 1},
106 "Aceex USB ISDN TA"}),
107 },
108 {
109 .idVendor = 0x0742,
110 .idProduct = 0x200A,
111 .driver_info = (unsigned long) &((hfcsusb_vdata)
112 {LED_SCHEME1, {4, 0, 2, 1},
113 "OEM USB ISDN TA"}),
114 },
115 {
116 .idVendor = 0x08e3,
117 .idProduct = 0x0301,
118 .driver_info = (unsigned long) &((hfcsusb_vdata)
119 {LED_SCHEME1, {2, 0, 1, 4},
120 "Olitec USB RNIS"}),
121 },
122 {
123 .idVendor = 0x07fa,
124 .idProduct = 0x0846,
125 .driver_info = (unsigned long) &((hfcsusb_vdata)
126 {LED_SCHEME1, {0x80, -64, -32, -16},
127 "Bewan Modem RNIS USB"}),
128 },
129 {
130 .idVendor = 0x07fa,
131 .idProduct = 0x0847,
132 .driver_info = (unsigned long) &((hfcsusb_vdata)
133 {LED_SCHEME1, {0x80, -64, -32, -16},
134 "Djinn Numeris USB"}),
135 },
136 {
137 .idVendor = 0x07b0,
138 .idProduct = 0x0006,
139 .driver_info = (unsigned long) &((hfcsusb_vdata)
140 {LED_SCHEME1, {0x80, -64, -32, -16},
141 "Twister ISDN TA"}),
142 },
82}; 143};
83 144
84/* driver internal device specific data:
85* VendorID, ProductID, Devicename, LED_SCHEME,
86* LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2
87*/
88static vendor_data vdata[] = {
89 /* CologneChip Eval TA */
90 {0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)",
91 LED_OFF, {4, 0, 2, 1}
92 }
93 ,
94 /* DrayTek miniVigor 128 USB ISDN TA */
95 {0x0675, 0x1688, "DrayTek miniVigor 128 USB ISDN TA",
96 LED_SCHEME1, {1, 2, 0, 0}
97 }
98 ,
99 /* Billion TA */
100 {0x07b0, 0x0007, "Billion tiny USB ISDN TA 128",
101 LED_SCHEME1, {0x80, -64, -32, -16}
102 }
103 ,
104 /* Stollmann TA */
105 {0x0742, 0x2008, "Stollmann USB TA",
106 LED_SCHEME1, {4, 0, 2, 1}
107 }
108 ,
109 /* Aceex USB ISDN TA */
110 {0x0742, 0x2009, "Aceex USB ISDN TA",
111 LED_SCHEME1, {4, 0, 2, 1}
112 }
113 ,
114 /* OEM USB ISDN TA */
115 {0x0742, 0x200A, "OEM USB ISDN TA",
116 LED_SCHEME1, {4, 0, 2, 1}
117 }
118 ,
119 /* Olitec TA */
120 {0x08e3, 0x0301, "Olitec USB RNIS",
121 LED_SCHEME1, {2, 0, 1, 4}
122 }
123 ,
124 /* Bewan TA */
125 {0x07fa, 0x0846, "Bewan Modem RNIS USB",
126 LED_SCHEME1, {0x80, -64, -32, -16}
127 }
128 ,
129 /* Bewan TA */
130 {0x07fa, 0x0847, "Djinn Numeris USB",
131 LED_SCHEME1, {0x80, -64, -32, -16}
132 }
133 ,
134 /* Twister ISDN TA */
135 {0x07b0, 0x0006, "Twister ISDN TA",
136 LED_SCHEME1, {0x80, -64, -32, -16}
137 }
138 ,
139 {0, 0, 0} /* EOL element */
140};
141 145
142/***************************************************************/ 146/***************************************************************/
143/* structure defining input+output fifos (interrupt/bulk mode) */ 147/* structure defining input+output fifos (interrupt/bulk mode) */
@@ -211,8 +215,6 @@ typedef struct hfcusb_data {
211 volatile __u8 l1_state; /* actual l1 state */ 215 volatile __u8 l1_state; /* actual l1 state */
212 struct timer_list t3_timer; /* timer 3 for activation/deactivation */ 216 struct timer_list t3_timer; /* timer 3 for activation/deactivation */
213 struct timer_list t4_timer; /* timer 4 for activation/deactivation */ 217 struct timer_list t4_timer; /* timer 4 for activation/deactivation */
214 struct timer_list led_timer; /* timer flashing leds */
215
216} hfcusb_data; 218} hfcusb_data;
217 219
218 220
@@ -227,7 +229,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num)
227 for (i = 0; list[i].name != NULL; i++) 229 for (i = 0; list[i].name != NULL; i++)
228 if (list[i].num == num) 230 if (list[i].num == num)
229 return (list[i].name); 231 return (list[i].name);
230 return "<unkown>"; 232 return "<unkown ERROR>";
231} 233}
232 234
233 235
@@ -335,93 +337,57 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset)
335 } 337 }
336} 338}
337 339
338/******************************************/
339/* invert B-channel LEDs if data is sent */
340/******************************************/
341static void
342led_timer(hfcusb_data * hfc)
343{
344 static int cnt = 0;
345
346 if (cnt) {
347 if (hfc->led_b_active & 1)
348 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
349 0);
350 if (hfc->led_b_active & 2)
351 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
352 0);
353 } else {
354 if (!(hfc->led_b_active & 1) || hfc->led_new_data & 1)
355 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
356 1);
357 if (!(hfc->led_b_active & 2) || hfc->led_new_data & 2)
358 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
359 1);
360 }
361
362 write_led(hfc, hfc->led_state);
363 hfc->led_new_data = 0;
364
365 cnt = !cnt;
366
367 /* restart 4 hz timer */
368 if (!timer_pending(&hfc->led_timer)) {
369 add_timer(&hfc->led_timer);
370 hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
371 }
372}
373
374/**************************/ 340/**************************/
375/* handle LED requests */ 341/* handle LED requests */
376/**************************/ 342/**************************/
377static void 343static void
378handle_led(hfcusb_data * hfc, int event) 344handle_led(hfcusb_data * hfc, int event)
379{ 345{
346 hfcsusb_vdata *driver_info =
347 (hfcsusb_vdata *) hfcusb_idtab[hfc->vend_idx].driver_info;
348
380 /* if no scheme -> no LED action */ 349 /* if no scheme -> no LED action */
381 if (vdata[hfc->vend_idx].led_scheme == LED_OFF) 350 if (driver_info->led_scheme == LED_OFF)
382 return; 351 return;
383 352
384 switch (event) { 353 switch (event) {
385 case LED_POWER_ON: 354 case LED_POWER_ON:
386 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[0], 355 set_led_bit(hfc, driver_info->led_bits[0],
387 0); 356 0);
388 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1], 357 set_led_bit(hfc, driver_info->led_bits[1],
389 1); 358 1);
390 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2], 359 set_led_bit(hfc, driver_info->led_bits[2],
391 1); 360 1);
392 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3], 361 set_led_bit(hfc, driver_info->led_bits[3],
393 1); 362 1);
394 break; 363 break;
395 case LED_POWER_OFF: /* no Power off handling */ 364 case LED_POWER_OFF: /* no Power off handling */
396 break; 365 break;
397 case LED_S0_ON: 366 case LED_S0_ON:
398 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1], 367 set_led_bit(hfc, driver_info->led_bits[1],
399 0); 368 0);
400 break; 369 break;
401 case LED_S0_OFF: 370 case LED_S0_OFF:
402 set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1], 371 set_led_bit(hfc, driver_info->led_bits[1],
403 1); 372 1);
404 break; 373 break;
405 case LED_B1_ON: 374 case LED_B1_ON:
406 hfc->led_b_active |= 1; 375 set_led_bit(hfc, driver_info->led_bits[2],
376 0);
407 break; 377 break;
408 case LED_B1_OFF: 378 case LED_B1_OFF:
409 hfc->led_b_active &= ~1; 379 set_led_bit(hfc, driver_info->led_bits[2],
410 break; 380 1);
411 case LED_B1_DATA:
412 hfc->led_new_data |= 1;
413 break; 381 break;
414 case LED_B2_ON: 382 case LED_B2_ON:
415 hfc->led_b_active |= 2; 383 set_led_bit(hfc, driver_info->led_bits[3],
384 0);
416 break; 385 break;
417 case LED_B2_OFF: 386 case LED_B2_OFF:
418 hfc->led_b_active &= ~2; 387 set_led_bit(hfc, driver_info->led_bits[3],
419 break; 388 1);
420 case LED_B2_DATA:
421 hfc->led_new_data |= 2;
422 break; 389 break;
423 } 390 }
424
425 write_led(hfc, hfc->led_state); 391 write_led(hfc, hfc->led_state);
426} 392}
427 393
@@ -725,14 +691,6 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
725 current_len + 1; 691 current_len + 1;
726 692
727 tx_offset += (current_len + 1); 693 tx_offset += (current_len + 1);
728 if (!transp_mode) {
729 if (fifon == HFCUSB_B1_TX)
730 handle_led(hfc,
731 LED_B1_DATA);
732 if (fifon == HFCUSB_B2_TX)
733 handle_led(hfc,
734 LED_B2_DATA);
735 }
736 } else { 694 } else {
737 urb->iso_frame_desc[k].offset = 695 urb->iso_frame_desc[k].offset =
738 tx_offset++; 696 tx_offset++;
@@ -966,14 +924,6 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
966 skb_trim(fifo->skbuff, 0); 924 skb_trim(fifo->skbuff, 0);
967 } 925 }
968 } 926 }
969
970 /* LED flashing only in HDLC mode */
971 if (!transp_mode) {
972 if (fifon == HFCUSB_B1_RX)
973 handle_led(hfc, LED_B1_DATA);
974 if (fifon == HFCUSB_B2_RX)
975 handle_led(hfc, LED_B2_DATA);
976 }
977} 927}
978 928
979/***********************************************/ 929/***********************************************/
@@ -1339,17 +1289,6 @@ usb_init(hfcusb_data * hfc)
1339 hfc->t4_timer.data = (long) hfc; 1289 hfc->t4_timer.data = (long) hfc;
1340 hfc->t4_timer.function = (void *) l1_timer_expire_t4; 1290 hfc->t4_timer.function = (void *) l1_timer_expire_t4;
1341 1291
1342 /* init the led timer */
1343 init_timer(&hfc->led_timer);
1344 hfc->led_timer.data = (long) hfc;
1345 hfc->led_timer.function = (void *) led_timer;
1346
1347 /* trigger 4 hz led timer */
1348 if (!timer_pending(&hfc->led_timer)) {
1349 hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
1350 add_timer(&hfc->led_timer);
1351 }
1352
1353 /* init the background machinery for control requests */ 1292 /* init the background machinery for control requests */
1354 hfc->ctrl_read.bRequestType = 0xc0; 1293 hfc->ctrl_read.bRequestType = 0xc0;
1355 hfc->ctrl_read.bRequest = 1; 1294 hfc->ctrl_read.bRequest = 1;
@@ -1440,13 +1379,18 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1440 attr, cfg_found, cidx, ep_addr; 1379 attr, cfg_found, cidx, ep_addr;
1441 int cmptbl[16], small_match, iso_packet_size, packet_size, 1380 int cmptbl[16], small_match, iso_packet_size, packet_size,
1442 alt_used = 0; 1381 alt_used = 0;
1382 hfcsusb_vdata *driver_info;
1443 1383
1444 vend_idx = 0xffff; 1384 vend_idx = 0xffff;
1445 for (i = 0; vdata[i].vendor; i++) { 1385 for (i = 0; hfcusb_idtab[i].idVendor; i++) {
1446 if (dev->descriptor.idVendor == vdata[i].vendor 1386 if (dev->descriptor.idVendor == hfcusb_idtab[i].idVendor
1447 && dev->descriptor.idProduct == vdata[i].prod_id) 1387 && dev->descriptor.idProduct ==
1388 hfcusb_idtab[i].idProduct) {
1448 vend_idx = i; 1389 vend_idx = i;
1390 continue;
1391 }
1449 } 1392 }
1393
1450#ifdef CONFIG_HISAX_DEBUG 1394#ifdef CONFIG_HISAX_DEBUG
1451 DBG(USB_DBG, 1395 DBG(USB_DBG,
1452 "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, 1396 "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum,
@@ -1457,10 +1401,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1457 ifnum, iface->desc.bAlternateSetting, intf->minor); 1401 ifnum, iface->desc.bAlternateSetting, intf->minor);
1458 1402
1459 if (vend_idx != 0xffff) { 1403 if (vend_idx != 0xffff) {
1460#ifdef CONFIG_HISAX_DEBUG
1461 DBG(USB_DBG, "HFC-S USB: found vendor idx:%d name:%s",
1462 vend_idx, vdata[vend_idx].vend_name);
1463#endif
1464 /* if vendor and product ID is OK, start probing alternate settings */ 1404 /* if vendor and product ID is OK, start probing alternate settings */
1465 alt_idx = 0; 1405 alt_idx = 0;
1466 small_match = 0xffff; 1406 small_match = 0xffff;
@@ -1687,9 +1627,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1687 usb_sndctrlpipe(context->dev, 0); 1627 usb_sndctrlpipe(context->dev, 0);
1688 context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); 1628 context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
1689 1629
1690 printk(KERN_INFO 1630 driver_info =
1691 "HFC-S USB: detected \"%s\"\n", 1631 (hfcsusb_vdata *) hfcusb_idtab[vend_idx].
1692 vdata[vend_idx].vend_name); 1632 driver_info;
1633 printk(KERN_INFO "HFC-S USB: detected \"%s\"\n",
1634 driver_info->vend_name);
1693#ifdef CONFIG_HISAX_DEBUG 1635#ifdef CONFIG_HISAX_DEBUG
1694 DBG(USB_DBG, 1636 DBG(USB_DBG,
1695 "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n", 1637 "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n",
@@ -1740,8 +1682,6 @@ hfc_usb_disconnect(struct usb_interface
1740 del_timer(&context->t3_timer); 1682 del_timer(&context->t3_timer);
1741 if (timer_pending(&context->t4_timer)) 1683 if (timer_pending(&context->t4_timer))
1742 del_timer(&context->t4_timer); 1684 del_timer(&context->t4_timer);
1743 if (timer_pending(&context->led_timer))
1744 del_timer(&context->led_timer);
1745 /* tell all fifos to terminate */ 1685 /* tell all fifos to terminate */
1746 for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { 1686 for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
1747 if (context->fifos[i].usb_transfer_mode == USB_ISOC) { 1687 if (context->fifos[i].usb_transfer_mode == USB_ISOC) {
@@ -1785,9 +1725,11 @@ hfc_usb_disconnect(struct usb_interface
1785/* our driver information structure */ 1725/* our driver information structure */
1786/************************************/ 1726/************************************/
1787static struct usb_driver hfc_drv = { 1727static struct usb_driver hfc_drv = {
1788 .owner = THIS_MODULE,.name = 1728 .owner = THIS_MODULE,
1789 "hfc_usb",.id_table = hfc_usb_idtab,.probe = 1729 .name = "hfc_usb",
1790 hfc_usb_probe,.disconnect = hfc_usb_disconnect, 1730 .id_table = hfcusb_idtab,
1731 .probe = hfc_usb_probe,
1732 .disconnect = hfc_usb_disconnect,
1791}; 1733};
1792static void __exit 1734static void __exit
1793hfc_usb_exit(void) 1735hfc_usb_exit(void)
@@ -1825,4 +1767,4 @@ module_exit(hfc_usb_exit);
1825MODULE_AUTHOR(DRIVER_AUTHOR); 1767MODULE_AUTHOR(DRIVER_AUTHOR);
1826MODULE_DESCRIPTION(DRIVER_DESC); 1768MODULE_DESCRIPTION(DRIVER_DESC);
1827MODULE_LICENSE("GPL"); 1769MODULE_LICENSE("GPL");
1828MODULE_DEVICE_TABLE(usb, hfc_usb_idtab); 1770MODULE_DEVICE_TABLE(usb, hfcusb_idtab);
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h
index 280dd29b30d6..ec52c1a7c22a 100644
--- a/drivers/isdn/hisax/hfc_usb.h
+++ b/drivers/isdn/hisax/hfc_usb.h
@@ -1,7 +1,7 @@
1/* 1/*
2* hfc_usb.h 2* hfc_usb.h
3* 3*
4* $Id: hfc_usb.h,v 4.1 2005/01/26 17:25:53 martinb1 Exp $ 4* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $
5*/ 5*/
6 6
7#ifndef __HFC_USB_H__ 7#ifndef __HFC_USB_H__
@@ -91,7 +91,7 @@
91/**********/ 91/**********/
92/* macros */ 92/* macros */
93/**********/ 93/**********/
94#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),0,0,HFC_CTRL_TIMEOUT) 94#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT)
95#define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT) 95#define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT)
96 96
97 97
@@ -186,6 +186,7 @@ static int validconf[][19] = {
186 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // EOL element 186 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} // EOL element
187}; 187};
188 188
189#ifdef CONFIG_HISAX_DEBUG
189// string description of chosen config 190// string description of chosen config
190static char *conf_str[] = { 191static char *conf_str[] = {
191 "4 Interrupt IN + 3 Isochron OUT", 192 "4 Interrupt IN + 3 Isochron OUT",
@@ -193,6 +194,7 @@ static char *conf_str[] = {
193 "4 Isochron IN + 3 Isochron OUT", 194 "4 Isochron IN + 3 Isochron OUT",
194 "3 Isochron IN + 3 Isochron OUT" 195 "3 Isochron IN + 3 Isochron OUT"
195}; 196};
197#endif
196 198
197 199
198typedef struct { 200typedef struct {
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.c b/drivers/isdn/hisax/hisax_fcpcipnp.c
index b4d795d40154..dc7ef957e897 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -23,7 +23,6 @@
23 * o tx_skb at PH_DEACTIVATE time 23 * o tx_skb at PH_DEACTIVATE time
24 */ 24 */
25 25
26#include <linux/version.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/init.h> 27#include <linux/init.h>
29#include <linux/pci.h> 28#include <linux/pci.h>
diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c
index 66dbaee77bfb..c8f9951f7914 100644
--- a/drivers/isdn/hisax/hscx.c
+++ b/drivers/isdn/hisax/hscx.c
@@ -156,14 +156,10 @@ close_hscxstate(struct BCState *bcs)
156{ 156{
157 modehscx(bcs, 0, bcs->channel); 157 modehscx(bcs, 0, bcs->channel);
158 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 158 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
159 if (bcs->hw.hscx.rcvbuf) { 159 kfree(bcs->hw.hscx.rcvbuf);
160 kfree(bcs->hw.hscx.rcvbuf); 160 bcs->hw.hscx.rcvbuf = NULL;
161 bcs->hw.hscx.rcvbuf = NULL; 161 kfree(bcs->blog);
162 } 162 bcs->blog = NULL;
163 if (bcs->blog) {
164 kfree(bcs->blog);
165 bcs->blog = NULL;
166 }
167 skb_queue_purge(&bcs->rqueue); 163 skb_queue_purge(&bcs->rqueue);
168 skb_queue_purge(&bcs->squeue); 164 skb_queue_purge(&bcs->squeue);
169 if (bcs->tx_skb) { 165 if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index b4ca5859b177..c615752b96aa 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -571,14 +571,10 @@ setstack_icc(struct PStack *st, struct IsdnCardState *cs)
571 571
572static void 572static void
573DC_Close_icc(struct IsdnCardState *cs) { 573DC_Close_icc(struct IsdnCardState *cs) {
574 if (cs->dc.icc.mon_rx) { 574 kfree(cs->dc.icc.mon_rx);
575 kfree(cs->dc.icc.mon_rx); 575 cs->dc.icc.mon_rx = NULL;
576 cs->dc.icc.mon_rx = NULL; 576 kfree(cs->dc.icc.mon_tx);
577 } 577 cs->dc.icc.mon_tx = NULL;
578 if (cs->dc.icc.mon_tx) {
579 kfree(cs->dc.icc.mon_tx);
580 cs->dc.icc.mon_tx = NULL;
581 }
582} 578}
583 579
584static void 580static void
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index efba2f448017..2e9afae1254a 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -762,14 +762,10 @@ bch_close_state(struct BCState *bcs)
762{ 762{
763 bch_mode(bcs, 0, bcs->channel); 763 bch_mode(bcs, 0, bcs->channel);
764 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 764 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
765 if (bcs->hw.hscx.rcvbuf) { 765 kfree(bcs->hw.hscx.rcvbuf);
766 kfree(bcs->hw.hscx.rcvbuf); 766 bcs->hw.hscx.rcvbuf = NULL;
767 bcs->hw.hscx.rcvbuf = NULL; 767 kfree(bcs->blog);
768 } 768 bcs->blog = NULL;
769 if (bcs->blog) {
770 kfree(bcs->blog);
771 bcs->blog = NULL;
772 }
773 skb_queue_purge(&bcs->rqueue); 769 skb_queue_purge(&bcs->rqueue);
774 skb_queue_purge(&bcs->squeue); 770 skb_queue_purge(&bcs->squeue);
775 if (bcs->tx_skb) { 771 if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index 85e063a08d23..565b7892c267 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -570,15 +570,12 @@ setstack_isac(struct PStack *st, struct IsdnCardState *cs)
570} 570}
571 571
572static void 572static void
573DC_Close_isac(struct IsdnCardState *cs) { 573DC_Close_isac(struct IsdnCardState *cs)
574 if (cs->dc.isac.mon_rx) { 574{
575 kfree(cs->dc.isac.mon_rx); 575 kfree(cs->dc.isac.mon_rx);
576 cs->dc.isac.mon_rx = NULL; 576 cs->dc.isac.mon_rx = NULL;
577 } 577 kfree(cs->dc.isac.mon_tx);
578 if (cs->dc.isac.mon_tx) { 578 cs->dc.isac.mon_tx = NULL;
579 kfree(cs->dc.isac.mon_tx);
580 cs->dc.isac.mon_tx = NULL;
581 }
582} 579}
583 580
584static void 581static void
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 642a87c51295..674af673ff96 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -1688,10 +1688,8 @@ close_isarstate(struct BCState *bcs)
1688{ 1688{
1689 modeisar(bcs, 0, bcs->channel); 1689 modeisar(bcs, 0, bcs->channel);
1690 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 1690 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
1691 if (bcs->hw.isar.rcvbuf) { 1691 kfree(bcs->hw.isar.rcvbuf);
1692 kfree(bcs->hw.isar.rcvbuf); 1692 bcs->hw.isar.rcvbuf = NULL;
1693 bcs->hw.isar.rcvbuf = NULL;
1694 }
1695 skb_queue_purge(&bcs->rqueue); 1693 skb_queue_purge(&bcs->rqueue);
1696 skb_queue_purge(&bcs->squeue); 1694 skb_queue_purge(&bcs->squeue);
1697 if (bcs->tx_skb) { 1695 if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index 363ae3179bbd..2659fecc2674 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -195,14 +195,10 @@ close_jadestate(struct BCState *bcs)
195{ 195{
196 modejade(bcs, 0, bcs->channel); 196 modejade(bcs, 0, bcs->channel);
197 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 197 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
198 if (bcs->hw.hscx.rcvbuf) { 198 kfree(bcs->hw.hscx.rcvbuf);
199 kfree(bcs->hw.hscx.rcvbuf); 199 bcs->hw.hscx.rcvbuf = NULL;
200 bcs->hw.hscx.rcvbuf = NULL; 200 kfree(bcs->blog);
201 } 201 bcs->blog = NULL;
202 if (bcs->blog) {
203 kfree(bcs->blog);
204 bcs->blog = NULL;
205 }
206 skb_queue_purge(&bcs->rqueue); 202 skb_queue_purge(&bcs->rqueue);
207 skb_queue_purge(&bcs->squeue); 203 skb_queue_purge(&bcs->squeue);
208 if (bcs->tx_skb) { 204 if (bcs->tx_skb) {
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index 94da03c30c51..47a47ef0968b 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -855,14 +855,10 @@ close_tigerstate(struct BCState *bcs)
855{ 855{
856 mode_tiger(bcs, 0, bcs->channel); 856 mode_tiger(bcs, 0, bcs->channel);
857 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 857 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
858 if (bcs->hw.tiger.rcvbuf) { 858 kfree(bcs->hw.tiger.rcvbuf);
859 kfree(bcs->hw.tiger.rcvbuf); 859 bcs->hw.tiger.rcvbuf = NULL;
860 bcs->hw.tiger.rcvbuf = NULL; 860 kfree(bcs->hw.tiger.sendbuf);
861 } 861 bcs->hw.tiger.sendbuf = NULL;
862 if (bcs->hw.tiger.sendbuf) {
863 kfree(bcs->hw.tiger.sendbuf);
864 bcs->hw.tiger.sendbuf = NULL;
865 }
866 skb_queue_purge(&bcs->rqueue); 862 skb_queue_purge(&bcs->rqueue);
867 skb_queue_purge(&bcs->squeue); 863 skb_queue_purge(&bcs->squeue);
868 if (bcs->tx_skb) { 864 if (bcs->tx_skb) {
@@ -967,20 +963,12 @@ inittiger(struct IsdnCardState *cs)
967static void 963static void
968releasetiger(struct IsdnCardState *cs) 964releasetiger(struct IsdnCardState *cs)
969{ 965{
970 if (cs->bcs[0].hw.tiger.send) { 966 kfree(cs->bcs[0].hw.tiger.send);
971 kfree(cs->bcs[0].hw.tiger.send); 967 cs->bcs[0].hw.tiger.send = NULL;
972 cs->bcs[0].hw.tiger.send = NULL; 968 cs->bcs[1].hw.tiger.send = NULL;
973 } 969 kfree(cs->bcs[0].hw.tiger.rec);
974 if (cs->bcs[1].hw.tiger.send) { 970 cs->bcs[0].hw.tiger.rec = NULL;
975 cs->bcs[1].hw.tiger.send = NULL; 971 cs->bcs[1].hw.tiger.rec = NULL;
976 }
977 if (cs->bcs[0].hw.tiger.rec) {
978 kfree(cs->bcs[0].hw.tiger.rec);
979 cs->bcs[0].hw.tiger.rec = NULL;
980 }
981 if (cs->bcs[1].hw.tiger.rec) {
982 cs->bcs[1].hw.tiger.rec = NULL;
983 }
984} 972}
985 973
986void 974void
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 2cf5d1a6df6c..8e192a3a3490 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -25,7 +25,6 @@
25 */ 25 */
26 26
27#include <linux/config.h> 27#include <linux/config.h>
28#include <linux/version.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/init.h> 29#include <linux/init.h>
31#include <linux/usb.h> 30#include <linux/usb.h>
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index 89fbeb58485d..b096b64b0253 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -335,14 +335,12 @@ void st5481_release_usb(struct st5481_adapter *adapter)
335 335
336 // Stop and free Control and Interrupt URBs 336 // Stop and free Control and Interrupt URBs
337 usb_kill_urb(ctrl->urb); 337 usb_kill_urb(ctrl->urb);
338 if (ctrl->urb->transfer_buffer) 338 kfree(ctrl->urb->transfer_buffer);
339 kfree(ctrl->urb->transfer_buffer);
340 usb_free_urb(ctrl->urb); 339 usb_free_urb(ctrl->urb);
341 ctrl->urb = NULL; 340 ctrl->urb = NULL;
342 341
343 usb_kill_urb(intr->urb); 342 usb_kill_urb(intr->urb);
344 if (intr->urb->transfer_buffer) 343 kfree(intr->urb->transfer_buffer);
345 kfree(intr->urb->transfer_buffer);
346 usb_free_urb(intr->urb); 344 usb_free_urb(intr->urb);
347 ctrl->urb = NULL; 345 ctrl->urb = NULL;
348} 346}
@@ -457,8 +455,7 @@ st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
457 err: 455 err:
458 for (j = 0; j < 2; j++) { 456 for (j = 0; j < 2; j++) {
459 if (urb[j]) { 457 if (urb[j]) {
460 if (urb[j]->transfer_buffer) 458 kfree(urb[j]->transfer_buffer);
461 kfree(urb[j]->transfer_buffer);
462 urb[j]->transfer_buffer = NULL; 459 urb[j]->transfer_buffer = NULL;
463 usb_free_urb(urb[j]); 460 usb_free_urb(urb[j]);
464 urb[j] = NULL; 461 urb[j] = NULL;
@@ -473,8 +470,7 @@ void st5481_release_isocpipes(struct urb* urb[2])
473 470
474 for (j = 0; j < 2; j++) { 471 for (j = 0; j < 2; j++) {
475 usb_kill_urb(urb[j]); 472 usb_kill_urb(urb[j]);
476 if (urb[j]->transfer_buffer) 473 kfree(urb[j]->transfer_buffer);
477 kfree(urb[j]->transfer_buffer);
478 usb_free_urb(urb[j]); 474 usb_free_urb(urb[j]);
479 urb[j] = NULL; 475 urb[j] = NULL;
480 } 476 }
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index 7baf8e488471..0352ee5f706c 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -819,14 +819,10 @@ close_w6692state(struct BCState *bcs)
819{ 819{
820 W6692Bmode(bcs, 0, bcs->channel); 820 W6692Bmode(bcs, 0, bcs->channel);
821 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) { 821 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
822 if (bcs->hw.w6692.rcvbuf) { 822 kfree(bcs->hw.w6692.rcvbuf);
823 kfree(bcs->hw.w6692.rcvbuf); 823 bcs->hw.w6692.rcvbuf = NULL;
824 bcs->hw.w6692.rcvbuf = NULL; 824 kfree(bcs->blog);
825 } 825 bcs->blog = NULL;
826 if (bcs->blog) {
827 kfree(bcs->blog);
828 bcs->blog = NULL;
829 }
830 skb_queue_purge(&bcs->rqueue); 826 skb_queue_purge(&bcs->rqueue);
831 skb_queue_purge(&bcs->squeue); 827 skb_queue_purge(&bcs->squeue);
832 if (bcs->tx_skb) { 828 if (bcs->tx_skb) {
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 1fd3d4e5f284..acc1d3cceebb 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/signal.h> 14#include <linux/signal.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/skbuff.h> 16#include <linux/skbuff.h>
diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
index 12c8137b5161..cb791f8e793a 100644
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -13,7 +13,6 @@
13#include <linux/config.h> 13#include <linux/config.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/version.h>
17#include <linux/poll.h> 16#include <linux/poll.h>
18#include <linux/vmalloc.h> 17#include <linux/vmalloc.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index babec8157ae6..aa01628d74c6 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/version.h>
18#include <linux/signal.h> 17#include <linux/signal.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/netdevice.h> 19#include <linux/netdevice.h>
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 639582f61f41..40e56143c768 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/version.h>
16#include <linux/poll.h> 15#include <linux/poll.h>
17#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
18#include <linux/pci.h> 17#include <linux/pci.h>
@@ -359,8 +358,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
359 } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) { 358 } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
360 /* read access -> output card info data */ 359 /* read access -> output card info data */
361 360
362 if (filep->private_data) 361 kfree(filep->private_data); /* release memory */
363 kfree(filep->private_data); /* release memory */
364 } 362 }
365 unlock_kernel(); 363 unlock_kernel();
366 return (retval); 364 return (retval);
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 4d57011c5737..6c26f1efabd5 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/version.h>
15#include <linux/poll.h> 14#include <linux/poll.h>
16#include <linux/proc_fs.h> 15#include <linux/proc_fs.h>
17#include <linux/pci.h> 16#include <linux/pci.h>
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 8a7d54a5c97d..4643df097bfe 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -14,7 +14,6 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/version.h>
18#include <linux/poll.h> 17#include <linux/poll.h>
19#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
20#include <linux/isdn.h> 19#include <linux/isdn.h>
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index d97a9be5469c..1a19a0f89428 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -364,10 +364,8 @@ isdn_ppp_release(int min, struct file *file)
364 isdn_net_hangup(&p->dev); 364 isdn_net_hangup(&p->dev);
365 } 365 }
366 for (i = 0; i < NUM_RCV_BUFFS; i++) { 366 for (i = 0; i < NUM_RCV_BUFFS; i++) {
367 if (is->rq[i].buf) { 367 kfree(is->rq[i].buf);
368 kfree(is->rq[i].buf); 368 is->rq[i].buf = NULL;
369 is->rq[i].buf = NULL;
370 }
371 } 369 }
372 is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */ 370 is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
373 is->last = is->rq; 371 is->last = is->rq;
@@ -378,14 +376,10 @@ isdn_ppp_release(int min, struct file *file)
378 is->slcomp = NULL; 376 is->slcomp = NULL;
379#endif 377#endif
380#ifdef CONFIG_IPPP_FILTER 378#ifdef CONFIG_IPPP_FILTER
381 if (is->pass_filter) { 379 kfree(is->pass_filter);
382 kfree(is->pass_filter); 380 is->pass_filter = NULL;
383 is->pass_filter = NULL; 381 kfree(is->active_filter);
384 } 382 is->active_filter = NULL;
385 if (is->active_filter) {
386 kfree(is->active_filter);
387 is->active_filter = NULL;
388 }
389#endif 383#endif
390 384
391/* TODO: if this was the previous master: link the stuff to the new master */ 385/* TODO: if this was the previous master: link the stuff to the new master */
@@ -914,8 +908,7 @@ isdn_ppp_cleanup(void)
914 kfree(ippp_table[i]); 908 kfree(ippp_table[i]);
915 909
916#ifdef CONFIG_ISDN_MPP 910#ifdef CONFIG_ISDN_MPP
917 if (isdn_ppp_bundle_arr) 911 kfree(isdn_ppp_bundle_arr);
918 kfree(isdn_ppp_bundle_arr);
919#endif /* CONFIG_ISDN_MPP */ 912#endif /* CONFIG_ISDN_MPP */
920 913
921} 914}
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index b37ef1f06b3d..8c404b4e2482 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -712,22 +712,14 @@ isdn_tty_modem_hup(modem_info * info, int local)
712#endif 712#endif
713 info->emu.vpar[4] = 0; 713 info->emu.vpar[4] = 0;
714 info->emu.vpar[5] = 8; 714 info->emu.vpar[5] = 8;
715 if (info->dtmf_state) { 715 kfree(info->dtmf_state);
716 kfree(info->dtmf_state); 716 info->dtmf_state = NULL;
717 info->dtmf_state = NULL; 717 kfree(info->silence_state);
718 } 718 info->silence_state = NULL;
719 if (info->silence_state) { 719 kfree(info->adpcms);
720 kfree(info->silence_state); 720 info->adpcms = NULL;
721 info->silence_state = NULL; 721 kfree(info->adpcmr);
722 } 722 info->adpcmr = NULL;
723 if (info->adpcms) {
724 kfree(info->adpcms);
725 info->adpcms = NULL;
726 }
727 if (info->adpcmr) {
728 kfree(info->adpcmr);
729 info->adpcmr = NULL;
730 }
731#endif 723#endif
732 if ((info->msr & UART_MSR_RI) && 724 if ((info->msr & UART_MSR_RI) &&
733 (info->emu.mdmreg[REG_RUNG] & BIT_RUNG)) 725 (info->emu.mdmreg[REG_RUNG] & BIT_RUNG))
@@ -1721,8 +1713,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
1721 */ 1713 */
1722 timeout = jiffies + HZ; 1714 timeout = jiffies + HZ;
1723 while (!(info->lsr & UART_LSR_TEMT)) { 1715 while (!(info->lsr & UART_LSR_TEMT)) {
1724 set_current_state(TASK_INTERRUPTIBLE); 1716 schedule_timeout_interruptible(20);
1725 schedule_timeout(20);
1726 if (time_after(jiffies,timeout)) 1717 if (time_after(jiffies,timeout))
1727 break; 1718 break;
1728 } 1719 }
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index 386df71eee74..6649f8bc9951 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -947,8 +947,7 @@ icn_loadproto(u_char __user * buffer, icn_card * card)
947 icn_maprelease_channel(card, 0); 947 icn_maprelease_channel(card, 0);
948 return -EIO; 948 return -EIO;
949 } 949 }
950 set_current_state(TASK_INTERRUPTIBLE); 950 schedule_timeout_interruptible(10);
951 schedule_timeout(10);
952 } 951 }
953 } 952 }
954 writeb(0x20, &sbuf_n); 953 writeb(0x20, &sbuf_n);
diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
index 9028cc3b5071..7d7245fb0b32 100644
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -35,7 +35,6 @@ typedef struct icn_cdef {
35#ifdef __KERNEL__ 35#ifdef __KERNEL__
36/* Kernel includes */ 36/* Kernel includes */
37 37
38#include <linux/version.h>
39#include <linux/errno.h> 38#include <linux/errno.h>
40#include <linux/fs.h> 39#include <linux/fs.h>
41#include <linux/major.h> 40#include <linux/major.h>
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index 14e1f8fbc61f..33d339700411 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1161,12 +1161,9 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
1161 if (a) { 1161 if (a) {
1162 if (!card->leased) { 1162 if (!card->leased) {
1163 card->leased = 1; 1163 card->leased = 1;
1164 while (card->ptype == ISDN_PTYPE_UNKNOWN) { 1164 while (card->ptype == ISDN_PTYPE_UNKNOWN)
1165 set_current_state(TASK_INTERRUPTIBLE); 1165 schedule_timeout_interruptible(10);
1166 schedule_timeout(10); 1166 schedule_timeout_interruptible(10);
1167 }
1168 set_current_state(TASK_INTERRUPTIBLE);
1169 schedule_timeout(10);
1170 sprintf(cbuf, "00;FV2ON\n01;EAZ1\n02;EAZ2\n"); 1167 sprintf(cbuf, "00;FV2ON\n01;EAZ1\n02;EAZ2\n");
1171 i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card); 1168 i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
1172 printk(KERN_INFO 1169 printk(KERN_INFO
diff --git a/drivers/isdn/isdnloop/isdnloop.h b/drivers/isdn/isdnloop/isdnloop.h
index 8fb7bc1bfe0f..d699fe53e1c3 100644
--- a/drivers/isdn/isdnloop/isdnloop.h
+++ b/drivers/isdn/isdnloop/isdnloop.h
@@ -33,7 +33,6 @@ typedef struct isdnloop_sdef {
33#ifdef __KERNEL__ 33#ifdef __KERNEL__
34/* Kernel includes */ 34/* Kernel includes */
35 35
36#include <linux/version.h>
37#include <linux/errno.h> 36#include <linux/errno.h>
38#include <linux/fs.h> 37#include <linux/fs.h>
39#include <linux/major.h> 38#include <linux/major.h>
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index 5de861f40816..94f21486bb24 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -561,10 +561,8 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
561 else 561 else
562 pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL); 562 pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
563 563
564 if (cbdata.data.setup.CalledPN) 564 kfree(cbdata.data.setup.CalledPN);
565 kfree(cbdata.data.setup.CalledPN); 565 kfree(cbdata.data.setup.CallingPN);
566 if (cbdata.data.setup.CallingPN)
567 kfree(cbdata.data.setup.CallingPN);
568 break; 566 break;
569 567
570 case MSG_CONN_CONF: 568 case MSG_CONN_CONF:
diff --git a/drivers/isdn/sc/includes.h b/drivers/isdn/sc/includes.h
index 4611da6e9231..5286e0c810a9 100644
--- a/drivers/isdn/sc/includes.h
+++ b/drivers/isdn/sc/includes.h
@@ -4,7 +4,6 @@
4 * 4 *
5 */ 5 */
6 6
7#include <linux/version.h>
8#include <linux/errno.h> 7#include <linux/errno.h>
9#include <asm/io.h> 8#include <asm/io.h>
10#include <linux/delay.h> 9#include <linux/delay.h>
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 1ebed041672d..62b7acfad8a4 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -529,8 +529,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
529 */ 529 */
530 x = 0; 530 x = 0;
531 while((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) { 531 while((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) {
532 set_current_state(TASK_INTERRUPTIBLE); 532 schedule_timeout_interruptible(1);
533 schedule_timeout(1);
534 x++; 533 x++;
535 } 534 }
536 if(x == 100) { 535 if(x == 100) {
diff --git a/drivers/isdn/sc/message.c b/drivers/isdn/sc/message.c
index ca204da3257d..0a0fe6b8039b 100644
--- a/drivers/isdn/sc/message.c
+++ b/drivers/isdn/sc/message.c
@@ -208,8 +208,7 @@ int send_and_receive(int card,
208 tries = 0; 208 tries = 0;
209 /* wait for the response */ 209 /* wait for the response */
210 while (tries < timeout) { 210 while (tries < timeout) {
211 set_current_state(TASK_INTERRUPTIBLE); 211 schedule_timeout_interruptible(1);
212 schedule_timeout(1);
213 212
214 pr_debug("SAR waiting..\n"); 213 pr_debug("SAR waiting..\n");
215 214
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index bc3e096d84f7..a0ea44c3e8b1 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -169,6 +169,25 @@ config THERM_PM72
169 This driver provides thermostat and fan control for the desktop 169 This driver provides thermostat and fan control for the desktop
170 G5 machines. 170 G5 machines.
171 171
172config WINDFARM
173 tristate "New PowerMac thermal control infrastructure"
174
175config WINDFARM_PM81
176 tristate "Support for thermal management on iMac G5"
177 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU
178 select I2C_PMAC_SMU
179 help
180 This driver provides thermal control for the iMacG5
181
182config WINDFARM_PM91
183 tristate "Support for thermal management on PowerMac9,1"
184 depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU
185 select I2C_PMAC_SMU
186 help
187 This driver provides thermal control for the PowerMac9,1
188 which is the recent (SMU based) single CPU desktop G5
189
190
172config ANSLCD 191config ANSLCD
173 tristate "Support for ANS LCD display" 192 tristate "Support for ANS LCD display"
174 depends on ADB_CUDA && PPC_PMAC 193 depends on ADB_CUDA && PPC_PMAC
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index 236291bd48a4..f4657aa81fb0 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -26,3 +26,12 @@ obj-$(CONFIG_ADB_MACIO) += macio-adb.o
26obj-$(CONFIG_THERM_PM72) += therm_pm72.o 26obj-$(CONFIG_THERM_PM72) += therm_pm72.o
27obj-$(CONFIG_THERM_WINDTUNNEL) += therm_windtunnel.o 27obj-$(CONFIG_THERM_WINDTUNNEL) += therm_windtunnel.o
28obj-$(CONFIG_THERM_ADT746X) += therm_adt746x.o 28obj-$(CONFIG_THERM_ADT746X) += therm_adt746x.o
29obj-$(CONFIG_WINDFARM) += windfarm_core.o
30obj-$(CONFIG_WINDFARM_PM81) += windfarm_smu_controls.o \
31 windfarm_smu_sensors.o \
32 windfarm_lm75_sensor.o windfarm_pid.o \
33 windfarm_cpufreq_clamp.o windfarm_pm81.o
34obj-$(CONFIG_WINDFARM_PM91) += windfarm_smu_controls.o \
35 windfarm_smu_sensors.o \
36 windfarm_lm75_sensor.o windfarm_pid.o \
37 windfarm_cpufreq_clamp.o windfarm_pm91.o
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index 8f02c155fdc0..c0b46bceb5df 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -857,8 +857,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
857static void adbhid_input_unregister(int id) 857static void adbhid_input_unregister(int id)
858{ 858{
859 input_unregister_device(adbhid[id]->input); 859 input_unregister_device(adbhid[id]->input);
860 if (adbhid[id]->keycode) 860 kfree(adbhid[id]->keycode);
861 kfree(adbhid[id]->keycode);
862 kfree(adbhid[id]); 861 kfree(adbhid[id]);
863 adbhid[id] = NULL; 862 adbhid[id] = NULL;
864} 863}
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 34f3c7e2d832..e8378274d710 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -47,13 +47,13 @@
47#include <asm/uaccess.h> 47#include <asm/uaccess.h>
48#include <asm/of_device.h> 48#include <asm/of_device.h>
49 49
50#define VERSION "0.6" 50#define VERSION "0.7"
51#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." 51#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp."
52 52
53#undef DEBUG_SMU 53#undef DEBUG_SMU
54 54
55#ifdef DEBUG_SMU 55#ifdef DEBUG_SMU
56#define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0) 56#define DPRINTK(fmt, args...) do { udbg_printf(KERN_DEBUG fmt , ##args); } while (0)
57#else 57#else
58#define DPRINTK(fmt, args...) do { } while (0) 58#define DPRINTK(fmt, args...) do { } while (0)
59#endif 59#endif
@@ -92,7 +92,7 @@ struct smu_device {
92 * for now, just hard code that 92 * for now, just hard code that
93 */ 93 */
94static struct smu_device *smu; 94static struct smu_device *smu;
95 95static DECLARE_MUTEX(smu_part_access);
96 96
97/* 97/*
98 * SMU driver low level stuff 98 * SMU driver low level stuff
@@ -113,9 +113,11 @@ static void smu_start_cmd(void)
113 113
114 DPRINTK("SMU: starting cmd %x, %d bytes data\n", cmd->cmd, 114 DPRINTK("SMU: starting cmd %x, %d bytes data\n", cmd->cmd,
115 cmd->data_len); 115 cmd->data_len);
116 DPRINTK("SMU: data buffer: %02x %02x %02x %02x ...\n", 116 DPRINTK("SMU: data buffer: %02x %02x %02x %02x %02x %02x %02x %02x\n",
117 ((u8 *)cmd->data_buf)[0], ((u8 *)cmd->data_buf)[1], 117 ((u8 *)cmd->data_buf)[0], ((u8 *)cmd->data_buf)[1],
118 ((u8 *)cmd->data_buf)[2], ((u8 *)cmd->data_buf)[3]); 118 ((u8 *)cmd->data_buf)[2], ((u8 *)cmd->data_buf)[3],
119 ((u8 *)cmd->data_buf)[4], ((u8 *)cmd->data_buf)[5],
120 ((u8 *)cmd->data_buf)[6], ((u8 *)cmd->data_buf)[7]);
119 121
120 /* Fill the SMU command buffer */ 122 /* Fill the SMU command buffer */
121 smu->cmd_buf->cmd = cmd->cmd; 123 smu->cmd_buf->cmd = cmd->cmd;
@@ -440,7 +442,7 @@ int smu_present(void)
440EXPORT_SYMBOL(smu_present); 442EXPORT_SYMBOL(smu_present);
441 443
442 444
443int smu_init (void) 445int __init smu_init (void)
444{ 446{
445 struct device_node *np; 447 struct device_node *np;
446 u32 *data; 448 u32 *data;
@@ -588,6 +590,8 @@ static void smu_expose_childs(void *unused)
588 sprintf(name, "smu-i2c-%02x", *reg); 590 sprintf(name, "smu-i2c-%02x", *reg);
589 of_platform_device_create(np, name, &smu->of_dev->dev); 591 of_platform_device_create(np, name, &smu->of_dev->dev);
590 } 592 }
593 if (device_is_compatible(np, "smu-sensors"))
594 of_platform_device_create(np, "smu-sensors", &smu->of_dev->dev);
591 } 595 }
592 596
593} 597}
@@ -845,6 +849,156 @@ int smu_queue_i2c(struct smu_i2c_cmd *cmd)
845 return 0; 849 return 0;
846} 850}
847 851
852/*
853 * Handling of "partitions"
854 */
855
856static int smu_read_datablock(u8 *dest, unsigned int addr, unsigned int len)
857{
858 DECLARE_COMPLETION(comp);
859 unsigned int chunk;
860 struct smu_cmd cmd;
861 int rc;
862 u8 params[8];
863
864 /* We currently use a chunk size of 0xe. We could check the
865 * SMU firmware version and use bigger sizes though
866 */
867 chunk = 0xe;
868
869 while (len) {
870 unsigned int clen = min(len, chunk);
871
872 cmd.cmd = SMU_CMD_MISC_ee_COMMAND;
873 cmd.data_len = 7;
874 cmd.data_buf = params;
875 cmd.reply_len = chunk;
876 cmd.reply_buf = dest;
877 cmd.done = smu_done_complete;
878 cmd.misc = &comp;
879 params[0] = SMU_CMD_MISC_ee_GET_DATABLOCK_REC;
880 params[1] = 0x4;
881 *((u32 *)&params[2]) = addr;
882 params[6] = clen;
883
884 rc = smu_queue_cmd(&cmd);
885 if (rc)
886 return rc;
887 wait_for_completion(&comp);
888 if (cmd.status != 0)
889 return rc;
890 if (cmd.reply_len != clen) {
891 printk(KERN_DEBUG "SMU: short read in "
892 "smu_read_datablock, got: %d, want: %d\n",
893 cmd.reply_len, clen);
894 return -EIO;
895 }
896 len -= clen;
897 addr += clen;
898 dest += clen;
899 }
900 return 0;
901}
902
903static struct smu_sdbp_header *smu_create_sdb_partition(int id)
904{
905 DECLARE_COMPLETION(comp);
906 struct smu_simple_cmd cmd;
907 unsigned int addr, len, tlen;
908 struct smu_sdbp_header *hdr;
909 struct property *prop;
910
911 /* First query the partition info */
912 smu_queue_simple(&cmd, SMU_CMD_PARTITION_COMMAND, 2,
913 smu_done_complete, &comp,
914 SMU_CMD_PARTITION_LATEST, id);
915 wait_for_completion(&comp);
916
917 /* Partition doesn't exist (or other error) */
918 if (cmd.cmd.status != 0 || cmd.cmd.reply_len != 6)
919 return NULL;
920
921 /* Fetch address and length from reply */
922 addr = *((u16 *)cmd.buffer);
923 len = cmd.buffer[3] << 2;
924 /* Calucluate total length to allocate, including the 17 bytes
925 * for "sdb-partition-XX" that we append at the end of the buffer
926 */
927 tlen = sizeof(struct property) + len + 18;
928
929 prop = kcalloc(tlen, 1, GFP_KERNEL);
930 if (prop == NULL)
931 return NULL;
932 hdr = (struct smu_sdbp_header *)(prop + 1);
933 prop->name = ((char *)prop) + tlen - 18;
934 sprintf(prop->name, "sdb-partition-%02x", id);
935 prop->length = len;
936 prop->value = (unsigned char *)hdr;
937 prop->next = NULL;
938
939 /* Read the datablock */
940 if (smu_read_datablock((u8 *)hdr, addr, len)) {
941 printk(KERN_DEBUG "SMU: datablock read failed while reading "
942 "partition %02x !\n", id);
943 goto failure;
944 }
945
946 /* Got it, check a few things and create the property */
947 if (hdr->id != id) {
948 printk(KERN_DEBUG "SMU: Reading partition %02x and got "
949 "%02x !\n", id, hdr->id);
950 goto failure;
951 }
952 if (prom_add_property(smu->of_node, prop)) {
953 printk(KERN_DEBUG "SMU: Failed creating sdb-partition-%02x "
954 "property !\n", id);
955 goto failure;
956 }
957
958 return hdr;
959 failure:
960 kfree(prop);
961 return NULL;
962}
963
964/* Note: Only allowed to return error code in pointers (using ERR_PTR)
965 * when interruptible is 1
966 */
967struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size,
968 int interruptible)
969{
970 char pname[32];
971 struct smu_sdbp_header *part;
972
973 if (!smu)
974 return NULL;
975
976 sprintf(pname, "sdb-partition-%02x", id);
977
978 if (interruptible) {
979 int rc;
980 rc = down_interruptible(&smu_part_access);
981 if (rc)
982 return ERR_PTR(rc);
983 } else
984 down(&smu_part_access);
985
986 part = (struct smu_sdbp_header *)get_property(smu->of_node,
987 pname, size);
988 if (part == NULL) {
989 part = smu_create_sdb_partition(id);
990 if (part != NULL && size)
991 *size = part->len << 2;
992 }
993 up(&smu_part_access);
994 return part;
995}
996
997struct smu_sdbp_header *smu_get_sdb_partition(int id, unsigned int *size)
998{
999 return __smu_get_sdb_partition(id, size, 0);
1000}
1001EXPORT_SYMBOL(smu_get_sdb_partition);
848 1002
849 1003
850/* 1004/*
@@ -918,6 +1072,14 @@ static ssize_t smu_write(struct file *file, const char __user *buf,
918 else if (hdr.cmdtype == SMU_CMDTYPE_WANTS_EVENTS) { 1072 else if (hdr.cmdtype == SMU_CMDTYPE_WANTS_EVENTS) {
919 pp->mode = smu_file_events; 1073 pp->mode = smu_file_events;
920 return 0; 1074 return 0;
1075 } else if (hdr.cmdtype == SMU_CMDTYPE_GET_PARTITION) {
1076 struct smu_sdbp_header *part;
1077 part = __smu_get_sdb_partition(hdr.cmd, NULL, 1);
1078 if (part == NULL)
1079 return -EINVAL;
1080 else if (IS_ERR(part))
1081 return PTR_ERR(part);
1082 return 0;
921 } else if (hdr.cmdtype != SMU_CMDTYPE_SMU) 1083 } else if (hdr.cmdtype != SMU_CMDTYPE_SMU)
922 return -EINVAL; 1084 return -EINVAL;
923 else if (pp->mode != smu_file_commands) 1085 else if (pp->mode != smu_file_commands)
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index cc507ceef153..3fc8cdd94c3d 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -1678,10 +1678,9 @@ static int main_control_loop(void *x)
1678 } 1678 }
1679 1679
1680 // FIXME: Deal with signals 1680 // FIXME: Deal with signals
1681 set_current_state(TASK_INTERRUPTIBLE);
1682 elapsed = jiffies - start; 1681 elapsed = jiffies - start;
1683 if (elapsed < HZ) 1682 if (elapsed < HZ)
1684 schedule_timeout(HZ - elapsed); 1683 schedule_timeout_interruptible(HZ - elapsed);
1685 } 1684 }
1686 1685
1687 out: 1686 out:
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 9bc6cc6e3845..564043508569 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -2053,6 +2053,7 @@ pmu_register_sleep_notifier(struct pmu_sleep_notifier *n)
2053 __list_add(&n->list, list->prev, list); 2053 __list_add(&n->list, list->prev, list);
2054 return 0; 2054 return 0;
2055} 2055}
2056EXPORT_SYMBOL(pmu_register_sleep_notifier);
2056 2057
2057int 2058int
2058pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n) 2059pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n)
@@ -2063,6 +2064,7 @@ pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n)
2063 n->list.next = NULL; 2064 n->list.next = NULL;
2064 return 0; 2065 return 0;
2065} 2066}
2067EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
2066#endif /* CONFIG_PM */ 2068#endif /* CONFIG_PM */
2067 2069
2068#if defined(CONFIG_PM) && defined(CONFIG_PPC32) 2070#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
@@ -2667,10 +2669,10 @@ powerbook_sleep_3400(void)
2667 asleep = 1; 2669 asleep = 1;
2668 2670
2669 /* Put the CPU into sleep mode */ 2671 /* Put the CPU into sleep mode */
2670 asm volatile("mfspr %0,1008" : "=r" (hid0) :); 2672 hid0 = mfspr(SPRN_HID0);
2671 hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP; 2673 hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP;
2672 asm volatile("mtspr 1008,%0" : : "r" (hid0)); 2674 mtspr(SPRN_HID0, hid0);
2673 _nmask_and_or_msr(0, MSR_POW | MSR_EE); 2675 mtmsr(mfmsr() | MSR_POW | MSR_EE);
2674 udelay(10); 2676 udelay(10);
2675 2677
2676 /* OK, we're awake again, start restoring things */ 2678 /* OK, we're awake again, start restoring things */
@@ -3139,8 +3141,6 @@ EXPORT_SYMBOL(pmu_i2c_stdsub_write);
3139EXPORT_SYMBOL(pmu_i2c_simple_read); 3141EXPORT_SYMBOL(pmu_i2c_simple_read);
3140EXPORT_SYMBOL(pmu_i2c_simple_write); 3142EXPORT_SYMBOL(pmu_i2c_simple_write);
3141#if defined(CONFIG_PM) && defined(CONFIG_PPC32) 3143#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
3142EXPORT_SYMBOL(pmu_register_sleep_notifier);
3143EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
3144EXPORT_SYMBOL(pmu_enable_irled); 3144EXPORT_SYMBOL(pmu_enable_irled);
3145EXPORT_SYMBOL(pmu_battery_count); 3145EXPORT_SYMBOL(pmu_battery_count);
3146EXPORT_SYMBOL(pmu_batteries); 3146EXPORT_SYMBOL(pmu_batteries);
diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h
new file mode 100644
index 000000000000..3f0cb0312ea3
--- /dev/null
+++ b/drivers/macintosh/windfarm.h
@@ -0,0 +1,131 @@
1/*
2 * Windfarm PowerMac thermal control.
3 *
4 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 */
9
10#ifndef __WINDFARM_H__
11#define __WINDFARM_H__
12
13#include <linux/kref.h>
14#include <linux/list.h>
15#include <linux/module.h>
16#include <linux/notifier.h>
17
18/* Display a 16.16 fixed point value */
19#define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16)
20
21/*
22 * Control objects
23 */
24
25struct wf_control;
26
27struct wf_control_ops {
28 int (*set_value)(struct wf_control *ct, s32 val);
29 int (*get_value)(struct wf_control *ct, s32 *val);
30 s32 (*get_min)(struct wf_control *ct);
31 s32 (*get_max)(struct wf_control *ct);
32 void (*release)(struct wf_control *ct);
33 struct module *owner;
34};
35
36struct wf_control {
37 struct list_head link;
38 struct wf_control_ops *ops;
39 char *name;
40 int type;
41 struct kref ref;
42};
43
44#define WF_CONTROL_TYPE_GENERIC 0
45#define WF_CONTROL_RPM_FAN 1
46#define WF_CONTROL_PWM_FAN 2
47
48
49/* Note about lifetime rules: wf_register_control() will initialize
50 * the kref and wf_unregister_control will decrement it, thus the
51 * object creating/disposing a given control shouldn't assume it
52 * still exists after wf_unregister_control has been called.
53 * wf_find_control will inc the refcount for you
54 */
55extern int wf_register_control(struct wf_control *ct);
56extern void wf_unregister_control(struct wf_control *ct);
57extern struct wf_control * wf_find_control(const char *name);
58extern int wf_get_control(struct wf_control *ct);
59extern void wf_put_control(struct wf_control *ct);
60
61static inline int wf_control_set_max(struct wf_control *ct)
62{
63 s32 vmax = ct->ops->get_max(ct);
64 return ct->ops->set_value(ct, vmax);
65}
66
67static inline int wf_control_set_min(struct wf_control *ct)
68{
69 s32 vmin = ct->ops->get_min(ct);
70 return ct->ops->set_value(ct, vmin);
71}
72
73/*
74 * Sensor objects
75 */
76
77struct wf_sensor;
78
79struct wf_sensor_ops {
80 int (*get_value)(struct wf_sensor *sr, s32 *val);
81 void (*release)(struct wf_sensor *sr);
82 struct module *owner;
83};
84
85struct wf_sensor {
86 struct list_head link;
87 struct wf_sensor_ops *ops;
88 char *name;
89 struct kref ref;
90};
91
92/* Same lifetime rules as controls */
93extern int wf_register_sensor(struct wf_sensor *sr);
94extern void wf_unregister_sensor(struct wf_sensor *sr);
95extern struct wf_sensor * wf_find_sensor(const char *name);
96extern int wf_get_sensor(struct wf_sensor *sr);
97extern void wf_put_sensor(struct wf_sensor *sr);
98
99/* For use by clients. Note that we are a bit racy here since
100 * notifier_block doesn't have a module owner field. I may fix
101 * it one day ...
102 *
103 * LOCKING NOTE !
104 *
105 * All "events" except WF_EVENT_TICK are called with an internal mutex
106 * held which will deadlock if you call basically any core routine.
107 * So don't ! Just take note of the event and do your actual operations
108 * from the ticker.
109 *
110 */
111extern int wf_register_client(struct notifier_block *nb);
112extern int wf_unregister_client(struct notifier_block *nb);
113
114/* Overtemp conditions. Those are refcounted */
115extern void wf_set_overtemp(void);
116extern void wf_clear_overtemp(void);
117extern int wf_is_overtemp(void);
118
119#define WF_EVENT_NEW_CONTROL 0 /* param is wf_control * */
120#define WF_EVENT_NEW_SENSOR 1 /* param is wf_sensor * */
121#define WF_EVENT_OVERTEMP 2 /* no param */
122#define WF_EVENT_NORMALTEMP 3 /* overtemp condition cleared */
123#define WF_EVENT_TICK 4 /* 1 second tick */
124
125/* Note: If that driver gets more broad use, we could replace the
126 * simplistic overtemp bits with "environmental conditions". That
127 * could then be used to also notify of things like fan failure,
128 * case open, battery conditions, ...
129 */
130
131#endif /* __WINDFARM_H__ */
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
new file mode 100644
index 000000000000..6c2a471ea6c0
--- /dev/null
+++ b/drivers/macintosh/windfarm_core.c
@@ -0,0 +1,426 @@
1/*
2 * Windfarm PowerMac thermal control. Core
3 *
4 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 *
9 * This core code tracks the list of sensors & controls, register
10 * clients, and holds the kernel thread used for control.
11 *
12 * TODO:
13 *
14 * Add some information about sensor/control type and data format to
15 * sensors/controls, and have the sysfs attribute stuff be moved
16 * generically here instead of hard coded in the platform specific
17 * driver as it us currently
18 *
19 * This however requires solving some annoying lifetime issues with
20 * sysfs which doesn't seem to have lifetime rules for struct attribute,
21 * I may have to create full features kobjects for every sensor/control
22 * instead which is a bit of an overkill imho
23 */
24
25#include <linux/types.h>
26#include <linux/errno.h>
27#include <linux/kernel.h>
28#include <linux/init.h>
29#include <linux/spinlock.h>
30#include <linux/smp_lock.h>
31#include <linux/kthread.h>
32#include <linux/jiffies.h>
33#include <linux/reboot.h>
34#include <linux/device.h>
35#include <linux/platform_device.h>
36
37#include "windfarm.h"
38
39#define VERSION "0.2"
40
41#undef DEBUG
42
43#ifdef DEBUG
44#define DBG(args...) printk(args)
45#else
46#define DBG(args...) do { } while(0)
47#endif
48
49static LIST_HEAD(wf_controls);
50static LIST_HEAD(wf_sensors);
51static DECLARE_MUTEX(wf_lock);
52static struct notifier_block *wf_client_list;
53static int wf_client_count;
54static unsigned int wf_overtemp;
55static unsigned int wf_overtemp_counter;
56struct task_struct *wf_thread;
57
58/*
59 * Utilities & tick thread
60 */
61
62static inline void wf_notify(int event, void *param)
63{
64 notifier_call_chain(&wf_client_list, event, param);
65}
66
67int wf_critical_overtemp(void)
68{
69 static char * critical_overtemp_path = "/sbin/critical_overtemp";
70 char *argv[] = { critical_overtemp_path, NULL };
71 static char *envp[] = { "HOME=/",
72 "TERM=linux",
73 "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
74 NULL };
75
76 return call_usermodehelper(critical_overtemp_path, argv, envp, 0);
77}
78EXPORT_SYMBOL_GPL(wf_critical_overtemp);
79
80static int wf_thread_func(void *data)
81{
82 unsigned long next, delay;
83
84 next = jiffies;
85
86 DBG("wf: thread started\n");
87
88 while(!kthread_should_stop()) {
89 try_to_freeze();
90
91 if (time_after_eq(jiffies, next)) {
92 wf_notify(WF_EVENT_TICK, NULL);
93 if (wf_overtemp) {
94 wf_overtemp_counter++;
95 /* 10 seconds overtemp, notify userland */
96 if (wf_overtemp_counter > 10)
97 wf_critical_overtemp();
98 /* 30 seconds, shutdown */
99 if (wf_overtemp_counter > 30) {
100 printk(KERN_ERR "windfarm: Overtemp "
101 "for more than 30"
102 " seconds, shutting down\n");
103 machine_power_off();
104 }
105 }
106 next += HZ;
107 }
108
109 delay = next - jiffies;
110 if (delay <= HZ)
111 schedule_timeout_interruptible(delay);
112
113 /* there should be no signal, but oh well */
114 if (signal_pending(current)) {
115 printk(KERN_WARNING "windfarm: thread got sigl !\n");
116 break;
117 }
118 }
119
120 DBG("wf: thread stopped\n");
121
122 return 0;
123}
124
125static void wf_start_thread(void)
126{
127 wf_thread = kthread_run(wf_thread_func, NULL, "kwindfarm");
128 if (IS_ERR(wf_thread)) {
129 printk(KERN_ERR "windfarm: failed to create thread,err %ld\n",
130 PTR_ERR(wf_thread));
131 wf_thread = NULL;
132 }
133}
134
135
136static void wf_stop_thread(void)
137{
138 if (wf_thread)
139 kthread_stop(wf_thread);
140 wf_thread = NULL;
141}
142
143/*
144 * Controls
145 */
146
147static void wf_control_release(struct kref *kref)
148{
149 struct wf_control *ct = container_of(kref, struct wf_control, ref);
150
151 DBG("wf: Deleting control %s\n", ct->name);
152
153 if (ct->ops && ct->ops->release)
154 ct->ops->release(ct);
155 else
156 kfree(ct);
157}
158
159int wf_register_control(struct wf_control *new_ct)
160{
161 struct wf_control *ct;
162
163 down(&wf_lock);
164 list_for_each_entry(ct, &wf_controls, link) {
165 if (!strcmp(ct->name, new_ct->name)) {
166 printk(KERN_WARNING "windfarm: trying to register"
167 " duplicate control %s\n", ct->name);
168 up(&wf_lock);
169 return -EEXIST;
170 }
171 }
172 kref_init(&new_ct->ref);
173 list_add(&new_ct->link, &wf_controls);
174
175 DBG("wf: Registered control %s\n", new_ct->name);
176
177 wf_notify(WF_EVENT_NEW_CONTROL, new_ct);
178 up(&wf_lock);
179
180 return 0;
181}
182EXPORT_SYMBOL_GPL(wf_register_control);
183
184void wf_unregister_control(struct wf_control *ct)
185{
186 down(&wf_lock);
187 list_del(&ct->link);
188 up(&wf_lock);
189
190 DBG("wf: Unregistered control %s\n", ct->name);
191
192 kref_put(&ct->ref, wf_control_release);
193}
194EXPORT_SYMBOL_GPL(wf_unregister_control);
195
196struct wf_control * wf_find_control(const char *name)
197{
198 struct wf_control *ct;
199
200 down(&wf_lock);
201 list_for_each_entry(ct, &wf_controls, link) {
202 if (!strcmp(ct->name, name)) {
203 if (wf_get_control(ct))
204 ct = NULL;
205 up(&wf_lock);
206 return ct;
207 }
208 }
209 up(&wf_lock);
210 return NULL;
211}
212EXPORT_SYMBOL_GPL(wf_find_control);
213
214int wf_get_control(struct wf_control *ct)
215{
216 if (!try_module_get(ct->ops->owner))
217 return -ENODEV;
218 kref_get(&ct->ref);
219 return 0;
220}
221EXPORT_SYMBOL_GPL(wf_get_control);
222
223void wf_put_control(struct wf_control *ct)
224{
225 struct module *mod = ct->ops->owner;
226 kref_put(&ct->ref, wf_control_release);
227 module_put(mod);
228}
229EXPORT_SYMBOL_GPL(wf_put_control);
230
231
232/*
233 * Sensors
234 */
235
236
237static void wf_sensor_release(struct kref *kref)
238{
239 struct wf_sensor *sr = container_of(kref, struct wf_sensor, ref);
240
241 DBG("wf: Deleting sensor %s\n", sr->name);
242
243 if (sr->ops && sr->ops->release)
244 sr->ops->release(sr);
245 else
246 kfree(sr);
247}
248
249int wf_register_sensor(struct wf_sensor *new_sr)
250{
251 struct wf_sensor *sr;
252
253 down(&wf_lock);
254 list_for_each_entry(sr, &wf_sensors, link) {
255 if (!strcmp(sr->name, new_sr->name)) {
256 printk(KERN_WARNING "windfarm: trying to register"
257 " duplicate sensor %s\n", sr->name);
258 up(&wf_lock);
259 return -EEXIST;
260 }
261 }
262 kref_init(&new_sr->ref);
263 list_add(&new_sr->link, &wf_sensors);
264
265 DBG("wf: Registered sensor %s\n", new_sr->name);
266
267 wf_notify(WF_EVENT_NEW_SENSOR, new_sr);
268 up(&wf_lock);
269
270 return 0;
271}
272EXPORT_SYMBOL_GPL(wf_register_sensor);
273
274void wf_unregister_sensor(struct wf_sensor *sr)
275{
276 down(&wf_lock);
277 list_del(&sr->link);
278 up(&wf_lock);
279
280 DBG("wf: Unregistered sensor %s\n", sr->name);
281
282 wf_put_sensor(sr);
283}
284EXPORT_SYMBOL_GPL(wf_unregister_sensor);
285
286struct wf_sensor * wf_find_sensor(const char *name)
287{
288 struct wf_sensor *sr;
289
290 down(&wf_lock);
291 list_for_each_entry(sr, &wf_sensors, link) {
292 if (!strcmp(sr->name, name)) {
293 if (wf_get_sensor(sr))
294 sr = NULL;
295 up(&wf_lock);
296 return sr;
297 }
298 }
299 up(&wf_lock);
300 return NULL;
301}
302EXPORT_SYMBOL_GPL(wf_find_sensor);
303
304int wf_get_sensor(struct wf_sensor *sr)
305{
306 if (!try_module_get(sr->ops->owner))
307 return -ENODEV;
308 kref_get(&sr->ref);
309 return 0;
310}
311EXPORT_SYMBOL_GPL(wf_get_sensor);
312
313void wf_put_sensor(struct wf_sensor *sr)
314{
315 struct module *mod = sr->ops->owner;
316 kref_put(&sr->ref, wf_sensor_release);
317 module_put(mod);
318}
319EXPORT_SYMBOL_GPL(wf_put_sensor);
320
321
322/*
323 * Client & notification
324 */
325
326int wf_register_client(struct notifier_block *nb)
327{
328 int rc;
329 struct wf_control *ct;
330 struct wf_sensor *sr;
331
332 down(&wf_lock);
333 rc = notifier_chain_register(&wf_client_list, nb);
334 if (rc != 0)
335 goto bail;
336 wf_client_count++;
337 list_for_each_entry(ct, &wf_controls, link)
338 wf_notify(WF_EVENT_NEW_CONTROL, ct);
339 list_for_each_entry(sr, &wf_sensors, link)
340 wf_notify(WF_EVENT_NEW_SENSOR, sr);
341 if (wf_client_count == 1)
342 wf_start_thread();
343 bail:
344 up(&wf_lock);
345 return rc;
346}
347EXPORT_SYMBOL_GPL(wf_register_client);
348
349int wf_unregister_client(struct notifier_block *nb)
350{
351 down(&wf_lock);
352 notifier_chain_unregister(&wf_client_list, nb);
353 wf_client_count++;
354 if (wf_client_count == 0)
355 wf_stop_thread();
356 up(&wf_lock);
357
358 return 0;
359}
360EXPORT_SYMBOL_GPL(wf_unregister_client);
361
362void wf_set_overtemp(void)
363{
364 down(&wf_lock);
365 wf_overtemp++;
366 if (wf_overtemp == 1) {
367 printk(KERN_WARNING "windfarm: Overtemp condition detected !\n");
368 wf_overtemp_counter = 0;
369 wf_notify(WF_EVENT_OVERTEMP, NULL);
370 }
371 up(&wf_lock);
372}
373EXPORT_SYMBOL_GPL(wf_set_overtemp);
374
375void wf_clear_overtemp(void)
376{
377 down(&wf_lock);
378 WARN_ON(wf_overtemp == 0);
379 if (wf_overtemp == 0) {
380 up(&wf_lock);
381 return;
382 }
383 wf_overtemp--;
384 if (wf_overtemp == 0) {
385 printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n");
386 wf_notify(WF_EVENT_NORMALTEMP, NULL);
387 }
388 up(&wf_lock);
389}
390EXPORT_SYMBOL_GPL(wf_clear_overtemp);
391
392int wf_is_overtemp(void)
393{
394 return (wf_overtemp != 0);
395}
396EXPORT_SYMBOL_GPL(wf_is_overtemp);
397
398static struct platform_device wf_platform_device = {
399 .name = "windfarm",
400};
401
402static int __init windfarm_core_init(void)
403{
404 DBG("wf: core loaded\n");
405
406 platform_device_register(&wf_platform_device);
407 return 0;
408}
409
410static void __exit windfarm_core_exit(void)
411{
412 BUG_ON(wf_client_count != 0);
413
414 DBG("wf: core unloaded\n");
415
416 platform_device_unregister(&wf_platform_device);
417}
418
419
420module_init(windfarm_core_init);
421module_exit(windfarm_core_exit);
422
423MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
424MODULE_DESCRIPTION("Core component of PowerMac thermal control");
425MODULE_LICENSE("GPL");
426
diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c
new file mode 100644
index 000000000000..607dbaca69c9
--- /dev/null
+++ b/drivers/macintosh/windfarm_cpufreq_clamp.c
@@ -0,0 +1,105 @@
1#include <linux/config.h>
2#include <linux/types.h>
3#include <linux/errno.h>
4#include <linux/kernel.h>
5#include <linux/delay.h>
6#include <linux/slab.h>
7#include <linux/init.h>
8#include <linux/wait.h>
9#include <linux/cpufreq.h>
10
11#include "windfarm.h"
12
13#define VERSION "0.3"
14
15static int clamped;
16static struct wf_control *clamp_control;
17
18static int clamp_notifier_call(struct notifier_block *self,
19 unsigned long event, void *data)
20{
21 struct cpufreq_policy *p = data;
22 unsigned long max_freq;
23
24 if (event != CPUFREQ_ADJUST)
25 return 0;
26
27 max_freq = clamped ? (p->cpuinfo.min_freq) : (p->cpuinfo.max_freq);
28 cpufreq_verify_within_limits(p, 0, max_freq);
29
30 return 0;
31}
32
33static struct notifier_block clamp_notifier = {
34 .notifier_call = clamp_notifier_call,
35};
36
37static int clamp_set(struct wf_control *ct, s32 value)
38{
39 if (value)
40 printk(KERN_INFO "windfarm: Clamping CPU frequency to "
41 "minimum !\n");
42 else
43 printk(KERN_INFO "windfarm: CPU frequency unclamped !\n");
44 clamped = value;
45 cpufreq_update_policy(0);
46 return 0;
47}
48
49static int clamp_get(struct wf_control *ct, s32 *value)
50{
51 *value = clamped;
52 return 0;
53}
54
55static s32 clamp_min(struct wf_control *ct)
56{
57 return 0;
58}
59
60static s32 clamp_max(struct wf_control *ct)
61{
62 return 1;
63}
64
65static struct wf_control_ops clamp_ops = {
66 .set_value = clamp_set,
67 .get_value = clamp_get,
68 .get_min = clamp_min,
69 .get_max = clamp_max,
70 .owner = THIS_MODULE,
71};
72
73static int __init wf_cpufreq_clamp_init(void)
74{
75 struct wf_control *clamp;
76
77 clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);
78 if (clamp == NULL)
79 return -ENOMEM;
80 cpufreq_register_notifier(&clamp_notifier, CPUFREQ_POLICY_NOTIFIER);
81 clamp->ops = &clamp_ops;
82 clamp->name = "cpufreq-clamp";
83 if (wf_register_control(clamp))
84 goto fail;
85 clamp_control = clamp;
86 return 0;
87 fail:
88 kfree(clamp);
89 return -ENODEV;
90}
91
92static void __exit wf_cpufreq_clamp_exit(void)
93{
94 if (clamp_control)
95 wf_unregister_control(clamp_control);
96}
97
98
99module_init(wf_cpufreq_clamp_init);
100module_exit(wf_cpufreq_clamp_exit);
101
102MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
103MODULE_DESCRIPTION("CPU frequency clamp for PowerMacs thermal control");
104MODULE_LICENSE("GPL");
105
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
new file mode 100644
index 000000000000..a0a41ad0f2b5
--- /dev/null
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -0,0 +1,263 @@
1/*
2 * Windfarm PowerMac thermal control. LM75 sensor
3 *
4 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 */
9
10#include <linux/types.h>
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/slab.h>
15#include <linux/init.h>
16#include <linux/wait.h>
17#include <linux/i2c.h>
18#include <linux/i2c-dev.h>
19#include <asm/prom.h>
20#include <asm/machdep.h>
21#include <asm/io.h>
22#include <asm/system.h>
23#include <asm/sections.h>
24
25#include "windfarm.h"
26
27#define VERSION "0.1"
28
29#undef DEBUG
30
31#ifdef DEBUG
32#define DBG(args...) printk(args)
33#else
34#define DBG(args...) do { } while(0)
35#endif
36
37struct wf_lm75_sensor {
38 int ds1775 : 1;
39 int inited : 1;
40 struct i2c_client i2c;
41 struct wf_sensor sens;
42};
43#define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens)
44#define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c)
45
46static int wf_lm75_attach(struct i2c_adapter *adapter);
47static int wf_lm75_detach(struct i2c_client *client);
48
49static struct i2c_driver wf_lm75_driver = {
50 .owner = THIS_MODULE,
51 .name = "wf_lm75",
52 .flags = I2C_DF_NOTIFY,
53 .attach_adapter = wf_lm75_attach,
54 .detach_client = wf_lm75_detach,
55};
56
57static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
58{
59 struct wf_lm75_sensor *lm = wf_to_lm75(sr);
60 s32 data;
61
62 if (lm->i2c.adapter == NULL)
63 return -ENODEV;
64
65 /* Init chip if necessary */
66 if (!lm->inited) {
67 u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1);
68
69 DBG("wf_lm75: Initializing %s, cfg was: %02x\n",
70 sr->name, cfg);
71
72 /* clear shutdown bit, keep other settings as left by
73 * the firmware for now
74 */
75 cfg_new = cfg & ~0x01;
76 i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new);
77 lm->inited = 1;
78
79 /* If we just powered it up, let's wait 200 ms */
80 msleep(200);
81 }
82
83 /* Read temperature register */
84 data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0));
85 data <<= 8;
86 *value = data;
87
88 return 0;
89}
90
91static void wf_lm75_release(struct wf_sensor *sr)
92{
93 struct wf_lm75_sensor *lm = wf_to_lm75(sr);
94
95 /* check if client is registered and detach from i2c */
96 if (lm->i2c.adapter) {
97 i2c_detach_client(&lm->i2c);
98 lm->i2c.adapter = NULL;
99 }
100
101 kfree(lm);
102}
103
104static struct wf_sensor_ops wf_lm75_ops = {
105 .get_value = wf_lm75_get,
106 .release = wf_lm75_release,
107 .owner = THIS_MODULE,
108};
109
110static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter,
111 u8 addr, int ds1775,
112 const char *loc)
113{
114 struct wf_lm75_sensor *lm;
115
116 DBG("wf_lm75: creating %s device at address 0x%02x\n",
117 ds1775 ? "ds1775" : "lm75", addr);
118
119 lm = kmalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
120 if (lm == NULL)
121 return NULL;
122 memset(lm, 0, sizeof(struct wf_lm75_sensor));
123
124 /* Usual rant about sensor names not beeing very consistent in
125 * the device-tree, oh well ...
126 * Add more entries below as you deal with more setups
127 */
128 if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
129 lm->sens.name = "hd-temp";
130 else
131 goto fail;
132
133 lm->inited = 0;
134 lm->sens.ops = &wf_lm75_ops;
135 lm->ds1775 = ds1775;
136 lm->i2c.addr = (addr >> 1) & 0x7f;
137 lm->i2c.adapter = adapter;
138 lm->i2c.driver = &wf_lm75_driver;
139 strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1);
140
141 if (i2c_attach_client(&lm->i2c)) {
142 printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
143 ds1775 ? "ds1775" : "lm75", lm->i2c.name);
144 goto fail;
145 }
146
147 if (wf_register_sensor(&lm->sens)) {
148 i2c_detach_client(&lm->i2c);
149 goto fail;
150 }
151
152 return lm;
153 fail:
154 kfree(lm);
155 return NULL;
156}
157
158static int wf_lm75_attach(struct i2c_adapter *adapter)
159{
160 u8 bus_id;
161 struct device_node *smu, *bus, *dev;
162
163 /* We currently only deal with LM75's hanging off the SMU
164 * i2c busses. If we extend that driver to other/older
165 * machines, we should split this function into SMU-i2c,
166 * keywest-i2c, PMU-i2c, ...
167 */
168
169 DBG("wf_lm75: adapter %s detected\n", adapter->name);
170
171 if (strncmp(adapter->name, "smu-i2c-", 8) != 0)
172 return 0;
173 smu = of_find_node_by_type(NULL, "smu");
174 if (smu == NULL)
175 return 0;
176
177 /* Look for the bus in the device-tree */
178 bus_id = (u8)simple_strtoul(adapter->name + 8, NULL, 16);
179
180 DBG("wf_lm75: bus ID is %x\n", bus_id);
181
182 /* Look for sensors subdir */
183 for (bus = NULL;
184 (bus = of_get_next_child(smu, bus)) != NULL;) {
185 u32 *reg;
186
187 if (strcmp(bus->name, "i2c"))
188 continue;
189 reg = (u32 *)get_property(bus, "reg", NULL);
190 if (reg == NULL)
191 continue;
192 if (bus_id == *reg)
193 break;
194 }
195 of_node_put(smu);
196 if (bus == NULL) {
197 printk(KERN_WARNING "windfarm: SMU i2c bus 0x%x not found"
198 " in device-tree !\n", bus_id);
199 return 0;
200 }
201
202 DBG("wf_lm75: bus found, looking for device...\n");
203
204 /* Now look for lm75(s) in there */
205 for (dev = NULL;
206 (dev = of_get_next_child(bus, dev)) != NULL;) {
207 const char *loc =
208 get_property(dev, "hwsensor-location", NULL);
209 u32 *reg = (u32 *)get_property(dev, "reg", NULL);
210 DBG(" dev: %s... (loc: %p, reg: %p)\n", dev->name, loc, reg);
211 if (loc == NULL || reg == NULL)
212 continue;
213 /* real lm75 */
214 if (device_is_compatible(dev, "lm75"))
215 wf_lm75_create(adapter, *reg, 0, loc);
216 /* ds1775 (compatible, better resolution */
217 else if (device_is_compatible(dev, "ds1775"))
218 wf_lm75_create(adapter, *reg, 1, loc);
219 }
220
221 of_node_put(bus);
222
223 return 0;
224}
225
226static int wf_lm75_detach(struct i2c_client *client)
227{
228 struct wf_lm75_sensor *lm = i2c_to_lm75(client);
229
230 DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name);
231
232 /* Mark client detached */
233 lm->i2c.adapter = NULL;
234
235 /* release sensor */
236 wf_unregister_sensor(&lm->sens);
237
238 return 0;
239}
240
241static int __init wf_lm75_sensor_init(void)
242{
243 int rc;
244
245 rc = i2c_add_driver(&wf_lm75_driver);
246 if (rc < 0)
247 return rc;
248 return 0;
249}
250
251static void __exit wf_lm75_sensor_exit(void)
252{
253 i2c_del_driver(&wf_lm75_driver);
254}
255
256
257module_init(wf_lm75_sensor_init);
258module_exit(wf_lm75_sensor_exit);
259
260MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
261MODULE_DESCRIPTION("LM75 sensor objects for PowerMacs thermal control");
262MODULE_LICENSE("GPL");
263
diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c
new file mode 100644
index 000000000000..2e803b368757
--- /dev/null
+++ b/drivers/macintosh/windfarm_pid.c
@@ -0,0 +1,145 @@
1/*
2 * Windfarm PowerMac thermal control. Generic PID helpers
3 *
4 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 */
9
10#include <linux/types.h>
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/string.h>
14#include <linux/module.h>
15
16#include "windfarm_pid.h"
17
18#undef DEBUG
19
20#ifdef DEBUG
21#define DBG(args...) printk(args)
22#else
23#define DBG(args...) do { } while(0)
24#endif
25
26void wf_pid_init(struct wf_pid_state *st, struct wf_pid_param *param)
27{
28 memset(st, 0, sizeof(struct wf_pid_state));
29 st->param = *param;
30 st->first = 1;
31}
32EXPORT_SYMBOL_GPL(wf_pid_init);
33
34s32 wf_pid_run(struct wf_pid_state *st, s32 new_sample)
35{
36 s64 error, integ, deriv;
37 s32 target;
38 int i, hlen = st->param.history_len;
39
40 /* Calculate error term */
41 error = new_sample - st->param.itarget;
42
43 /* Get samples into our history buffer */
44 if (st->first) {
45 for (i = 0; i < hlen; i++) {
46 st->samples[i] = new_sample;
47 st->errors[i] = error;
48 }
49 st->first = 0;
50 st->index = 0;
51 } else {
52 st->index = (st->index + 1) % hlen;
53 st->samples[st->index] = new_sample;
54 st->errors[st->index] = error;
55 }
56
57 /* Calculate integral term */
58 for (i = 0, integ = 0; i < hlen; i++)
59 integ += st->errors[(st->index + hlen - i) % hlen];
60 integ *= st->param.interval;
61
62 /* Calculate derivative term */
63 deriv = st->errors[st->index] -
64 st->errors[(st->index + hlen - 1) % hlen];
65 deriv /= st->param.interval;
66
67 /* Calculate target */
68 target = (s32)((integ * (s64)st->param.gr + deriv * (s64)st->param.gd +
69 error * (s64)st->param.gp) >> 36);
70 if (st->param.additive)
71 target += st->target;
72 target = max(target, st->param.min);
73 target = min(target, st->param.max);
74 st->target = target;
75
76 return st->target;
77}
78EXPORT_SYMBOL_GPL(wf_pid_run);
79
80void wf_cpu_pid_init(struct wf_cpu_pid_state *st,
81 struct wf_cpu_pid_param *param)
82{
83 memset(st, 0, sizeof(struct wf_cpu_pid_state));
84 st->param = *param;
85 st->first = 1;
86}
87EXPORT_SYMBOL_GPL(wf_cpu_pid_init);
88
89s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp)
90{
91 s64 error, integ, deriv, prop;
92 s32 target, sval, adj;
93 int i, hlen = st->param.history_len;
94
95 /* Calculate error term */
96 error = st->param.pmaxadj - new_power;
97
98 /* Get samples into our history buffer */
99 if (st->first) {
100 for (i = 0; i < hlen; i++) {
101 st->powers[i] = new_power;
102 st->errors[i] = error;
103 }
104 st->temps[0] = st->temps[1] = new_temp;
105 st->first = 0;
106 st->index = st->tindex = 0;
107 } else {
108 st->index = (st->index + 1) % hlen;
109 st->powers[st->index] = new_power;
110 st->errors[st->index] = error;
111 st->tindex = (st->tindex + 1) % 2;
112 st->temps[st->tindex] = new_temp;
113 }
114
115 /* Calculate integral term */
116 for (i = 0, integ = 0; i < hlen; i++)
117 integ += st->errors[(st->index + hlen - i) % hlen];
118 integ *= st->param.interval;
119 integ *= st->param.gr;
120 sval = st->param.tmax - ((integ >> 20) & 0xffffffff);
121 adj = min(st->param.ttarget, sval);
122
123 DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj);
124
125 /* Calculate derivative term */
126 deriv = st->temps[st->tindex] -
127 st->temps[(st->tindex + 2 - 1) % 2];
128 deriv /= st->param.interval;
129 deriv *= st->param.gd;
130
131 /* Calculate proportional term */
132 prop = (new_temp - adj);
133 prop *= st->param.gp;
134
135 DBG("deriv: %lx, prop: %lx\n", deriv, prop);
136
137 /* Calculate target */
138 target = st->target + (s32)((deriv + prop) >> 36);
139 target = max(target, st->param.min);
140 target = min(target, st->param.max);
141 st->target = target;
142
143 return st->target;
144}
145EXPORT_SYMBOL_GPL(wf_cpu_pid_run);
diff --git a/drivers/macintosh/windfarm_pid.h b/drivers/macintosh/windfarm_pid.h
new file mode 100644
index 000000000000..a364c2a2499c
--- /dev/null
+++ b/drivers/macintosh/windfarm_pid.h
@@ -0,0 +1,84 @@
1/*
2 * Windfarm PowerMac thermal control. Generic PID helpers
3 *
4 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 *
9 * This is a pair of generic PID helpers that can be used by
10 * control loops. One is the basic PID implementation, the
11 * other one is more specifically tailored to the loops used
12 * for CPU control with 2 input sample types (temp and power)
13 */
14
15/*
16 * *** Simple PID ***
17 */
18
19#define WF_PID_MAX_HISTORY 32
20
21/* This parameter array is passed to the PID algorithm. Currently,
22 * we don't support changing parameters on the fly as it's not needed
23 * but could be implemented (with necessary adjustment of the history
24 * buffer
25 */
26struct wf_pid_param {
27 int interval; /* Interval between samples in seconds */
28 int history_len; /* Size of history buffer */
29 int additive; /* 1: target relative to previous value */
30 s32 gd, gp, gr; /* PID gains */
31 s32 itarget; /* PID input target */
32 s32 min,max; /* min and max target values */
33};
34
35struct wf_pid_state {
36 int first; /* first run of the loop */
37 int index; /* index of current sample */
38 s32 target; /* current target value */
39 s32 samples[WF_PID_MAX_HISTORY]; /* samples history buffer */
40 s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */
41
42 struct wf_pid_param param;
43};
44
45extern void wf_pid_init(struct wf_pid_state *st, struct wf_pid_param *param);
46extern s32 wf_pid_run(struct wf_pid_state *st, s32 sample);
47
48
49/*
50 * *** CPU PID ***
51 */
52
53#define WF_CPU_PID_MAX_HISTORY 32
54
55/* This parameter array is passed to the CPU PID algorithm. Currently,
56 * we don't support changing parameters on the fly as it's not needed
57 * but could be implemented (with necessary adjustment of the history
58 * buffer
59 */
60struct wf_cpu_pid_param {
61 int interval; /* Interval between samples in seconds */
62 int history_len; /* Size of history buffer */
63 s32 gd, gp, gr; /* PID gains */
64 s32 pmaxadj; /* PID max power adjust */
65 s32 ttarget; /* PID input target */
66 s32 tmax; /* PID input max */
67 s32 min,max; /* min and max target values */
68};
69
70struct wf_cpu_pid_state {
71 int first; /* first run of the loop */
72 int index; /* index of current power */
73 int tindex; /* index of current temp */
74 s32 target; /* current target value */
75 s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */
76 s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */
77 s32 temps[2]; /* temp. history buffer */
78
79 struct wf_cpu_pid_param param;
80};
81
82extern void wf_cpu_pid_init(struct wf_cpu_pid_state *st,
83 struct wf_cpu_pid_param *param);
84extern s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 power, s32 temp);
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
new file mode 100644
index 000000000000..322c74b2687f
--- /dev/null
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -0,0 +1,879 @@
1/*
2 * Windfarm PowerMac thermal control. iMac G5
3 *
4 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 *
9 * The algorithm used is the PID control algorithm, used the same
10 * way the published Darwin code does, using the same values that
11 * are present in the Darwin 8.2 snapshot property lists (note however
12 * that none of the code has been re-used, it's a complete re-implementation
13 *
14 * The various control loops found in Darwin config file are:
15 *
16 * PowerMac8,1 and PowerMac8,2
17 * ===========================
18 *
19 * System Fans control loop. Different based on models. In addition to the
20 * usual PID algorithm, the control loop gets 2 additional pairs of linear
21 * scaling factors (scale/offsets) expressed as 4.12 fixed point values
22 * signed offset, unsigned scale)
23 *
24 * The targets are modified such as:
25 * - the linked control (second control) gets the target value as-is
26 * (typically the drive fan)
27 * - the main control (first control) gets the target value scaled with
28 * the first pair of factors, and is then modified as below
29 * - the value of the target of the CPU Fan control loop is retreived,
30 * scaled with the second pair of factors, and the max of that and
31 * the scaled target is applied to the main control.
32 *
33 * # model_id: 2
34 * controls : system-fan, drive-bay-fan
35 * sensors : hd-temp
36 * PID params : G_d = 0x15400000
37 * G_p = 0x00200000
38 * G_r = 0x000002fd
39 * History = 2 entries
40 * Input target = 0x3a0000
41 * Interval = 5s
42 * linear-factors : offset = 0xff38 scale = 0x0ccd
43 * offset = 0x0208 scale = 0x07ae
44 *
45 * # model_id: 3
46 * controls : system-fan, drive-bay-fan
47 * sensors : hd-temp
48 * PID params : G_d = 0x08e00000
49 * G_p = 0x00566666
50 * G_r = 0x0000072b
51 * History = 2 entries
52 * Input target = 0x350000
53 * Interval = 5s
54 * linear-factors : offset = 0xff38 scale = 0x0ccd
55 * offset = 0x0000 scale = 0x0000
56 *
57 * # model_id: 5
58 * controls : system-fan
59 * sensors : hd-temp
60 * PID params : G_d = 0x15400000
61 * G_p = 0x00233333
62 * G_r = 0x000002fd
63 * History = 2 entries
64 * Input target = 0x3a0000
65 * Interval = 5s
66 * linear-factors : offset = 0x0000 scale = 0x1000
67 * offset = 0x0091 scale = 0x0bae
68 *
69 * CPU Fan control loop. The loop is identical for all models. it
70 * has an additional pair of scaling factor. This is used to scale the
71 * systems fan control loop target result (the one before it gets scaled
72 * by the System Fans control loop itself). Then, the max value of the
73 * calculated target value and system fan value is sent to the fans
74 *
75 * controls : cpu-fan
76 * sensors : cpu-temp cpu-power
77 * PID params : From SMU sdb partition
78 * linear-factors : offset = 0xfb50 scale = 0x1000
79 *
80 * CPU Slew control loop. Not implemented. The cpufreq driver in linux is
81 * completely separate for now, though we could find a way to link it, either
82 * as a client reacting to overtemp notifications, or directling monitoring
83 * the CPU temperature
84 *
85 * WARNING ! The CPU control loop requires the CPU tmax for the current
86 * operating point. However, we currently are completely separated from
87 * the cpufreq driver and thus do not know what the current operating
88 * point is. Fortunately, we also do not have any hardware supporting anything
89 * but operating point 0 at the moment, thus we just peek that value directly
90 * from the SDB partition. If we ever end up with actually slewing the system
91 * clock and thus changing operating points, we'll have to find a way to
92 * communicate with the CPU freq driver;
93 *
94 */
95
96#include <linux/types.h>
97#include <linux/errno.h>
98#include <linux/kernel.h>
99#include <linux/delay.h>
100#include <linux/slab.h>
101#include <linux/init.h>
102#include <linux/spinlock.h>
103#include <linux/wait.h>
104#include <linux/kmod.h>
105#include <linux/device.h>
106#include <linux/platform_device.h>
107#include <asm/prom.h>
108#include <asm/machdep.h>
109#include <asm/io.h>
110#include <asm/system.h>
111#include <asm/sections.h>
112#include <asm/smu.h>
113
114#include "windfarm.h"
115#include "windfarm_pid.h"
116
117#define VERSION "0.4"
118
119#undef DEBUG
120
121#ifdef DEBUG
122#define DBG(args...) printk(args)
123#else
124#define DBG(args...) do { } while(0)
125#endif
126
127/* define this to force CPU overtemp to 74 degree, useful for testing
128 * the overtemp code
129 */
130#undef HACKED_OVERTEMP
131
132static int wf_smu_mach_model; /* machine model id */
133
134static struct device *wf_smu_dev;
135
136/* Controls & sensors */
137static struct wf_sensor *sensor_cpu_power;
138static struct wf_sensor *sensor_cpu_temp;
139static struct wf_sensor *sensor_hd_temp;
140static struct wf_control *fan_cpu_main;
141static struct wf_control *fan_hd;
142static struct wf_control *fan_system;
143static struct wf_control *cpufreq_clamp;
144
145/* Set to kick the control loop into life */
146static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started;
147
148/* Failure handling.. could be nicer */
149#define FAILURE_FAN 0x01
150#define FAILURE_SENSOR 0x02
151#define FAILURE_OVERTEMP 0x04
152
153static unsigned int wf_smu_failure_state;
154static int wf_smu_readjust, wf_smu_skipping;
155
156/*
157 * ****** System Fans Control Loop ******
158 *
159 */
160
161/* Parameters for the System Fans control loop. Parameters
162 * not in this table such as interval, history size, ...
163 * are common to all versions and thus hard coded for now.
164 */
165struct wf_smu_sys_fans_param {
166 int model_id;
167 s32 itarget;
168 s32 gd, gp, gr;
169
170 s16 offset0;
171 u16 scale0;
172 s16 offset1;
173 u16 scale1;
174};
175
176#define WF_SMU_SYS_FANS_INTERVAL 5
177#define WF_SMU_SYS_FANS_HISTORY_SIZE 2
178
179/* State data used by the system fans control loop
180 */
181struct wf_smu_sys_fans_state {
182 int ticks;
183 s32 sys_setpoint;
184 s32 hd_setpoint;
185 s16 offset0;
186 u16 scale0;
187 s16 offset1;
188 u16 scale1;
189 struct wf_pid_state pid;
190};
191
192/*
193 * Configs for SMU Sytem Fan control loop
194 */
195static struct wf_smu_sys_fans_param wf_smu_sys_all_params[] = {
196 /* Model ID 2 */
197 {
198 .model_id = 2,
199 .itarget = 0x3a0000,
200 .gd = 0x15400000,
201 .gp = 0x00200000,
202 .gr = 0x000002fd,
203 .offset0 = 0xff38,
204 .scale0 = 0x0ccd,
205 .offset1 = 0x0208,
206 .scale1 = 0x07ae,
207 },
208 /* Model ID 3 */
209 {
210 .model_id = 2,
211 .itarget = 0x350000,
212 .gd = 0x08e00000,
213 .gp = 0x00566666,
214 .gr = 0x0000072b,
215 .offset0 = 0xff38,
216 .scale0 = 0x0ccd,
217 .offset1 = 0x0000,
218 .scale1 = 0x0000,
219 },
220 /* Model ID 5 */
221 {
222 .model_id = 2,
223 .itarget = 0x3a0000,
224 .gd = 0x15400000,
225 .gp = 0x00233333,
226 .gr = 0x000002fd,
227 .offset0 = 0x0000,
228 .scale0 = 0x1000,
229 .offset1 = 0x0091,
230 .scale1 = 0x0bae,
231 },
232};
233#define WF_SMU_SYS_FANS_NUM_CONFIGS ARRAY_SIZE(wf_smu_sys_all_params)
234
235static struct wf_smu_sys_fans_state *wf_smu_sys_fans;
236
237/*
238 * ****** CPU Fans Control Loop ******
239 *
240 */
241
242
243#define WF_SMU_CPU_FANS_INTERVAL 1
244#define WF_SMU_CPU_FANS_MAX_HISTORY 16
245#define WF_SMU_CPU_FANS_SIBLING_SCALE 0x00001000
246#define WF_SMU_CPU_FANS_SIBLING_OFFSET 0xfffffb50
247
248/* State data used by the cpu fans control loop
249 */
250struct wf_smu_cpu_fans_state {
251 int ticks;
252 s32 cpu_setpoint;
253 s32 scale;
254 s32 offset;
255 struct wf_cpu_pid_state pid;
256};
257
258static struct wf_smu_cpu_fans_state *wf_smu_cpu_fans;
259
260
261
262/*
263 * ***** Implementation *****
264 *
265 */
266
267static void wf_smu_create_sys_fans(void)
268{
269 struct wf_smu_sys_fans_param *param = NULL;
270 struct wf_pid_param pid_param;
271 int i;
272
273 /* First, locate the params for this model */
274 for (i = 0; i < WF_SMU_SYS_FANS_NUM_CONFIGS; i++)
275 if (wf_smu_sys_all_params[i].model_id == wf_smu_mach_model) {
276 param = &wf_smu_sys_all_params[i];
277 break;
278 }
279
280 /* No params found, put fans to max */
281 if (param == NULL) {
282 printk(KERN_WARNING "windfarm: System fan config not found "
283 "for this machine model, max fan speed\n");
284 goto fail;
285 }
286
287 /* Alloc & initialize state */
288 wf_smu_sys_fans = kmalloc(sizeof(struct wf_smu_sys_fans_state),
289 GFP_KERNEL);
290 if (wf_smu_sys_fans == NULL) {
291 printk(KERN_WARNING "windfarm: Memory allocation error"
292 " max fan speed\n");
293 goto fail;
294 }
295 wf_smu_sys_fans->ticks = 1;
296 wf_smu_sys_fans->scale0 = param->scale0;
297 wf_smu_sys_fans->offset0 = param->offset0;
298 wf_smu_sys_fans->scale1 = param->scale1;
299 wf_smu_sys_fans->offset1 = param->offset1;
300
301 /* Fill PID params */
302 pid_param.gd = param->gd;
303 pid_param.gp = param->gp;
304 pid_param.gr = param->gr;
305 pid_param.interval = WF_SMU_SYS_FANS_INTERVAL;
306 pid_param.history_len = WF_SMU_SYS_FANS_HISTORY_SIZE;
307 pid_param.itarget = param->itarget;
308 pid_param.min = fan_system->ops->get_min(fan_system);
309 pid_param.max = fan_system->ops->get_max(fan_system);
310 if (fan_hd) {
311 pid_param.min =
312 max(pid_param.min,fan_hd->ops->get_min(fan_hd));
313 pid_param.max =
314 min(pid_param.max,fan_hd->ops->get_max(fan_hd));
315 }
316 wf_pid_init(&wf_smu_sys_fans->pid, &pid_param);
317
318 DBG("wf: System Fan control initialized.\n");
319 DBG(" itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
320 FIX32TOPRINT(pid_param.itarget), pid_param.min, pid_param.max);
321 return;
322
323 fail:
324
325 if (fan_system)
326 wf_control_set_max(fan_system);
327 if (fan_hd)
328 wf_control_set_max(fan_hd);
329}
330
331static void wf_smu_sys_fans_tick(struct wf_smu_sys_fans_state *st)
332{
333 s32 new_setpoint, temp, scaled, cputarget;
334 int rc;
335
336 if (--st->ticks != 0) {
337 if (wf_smu_readjust)
338 goto readjust;
339 return;
340 }
341 st->ticks = WF_SMU_SYS_FANS_INTERVAL;
342
343 rc = sensor_hd_temp->ops->get_value(sensor_hd_temp, &temp);
344 if (rc) {
345 printk(KERN_WARNING "windfarm: HD temp sensor error %d\n",
346 rc);
347 wf_smu_failure_state |= FAILURE_SENSOR;
348 return;
349 }
350
351 DBG("wf_smu: System Fans tick ! HD temp: %d.%03d\n",
352 FIX32TOPRINT(temp));
353
354 if (temp > (st->pid.param.itarget + 0x50000))
355 wf_smu_failure_state |= FAILURE_OVERTEMP;
356
357 new_setpoint = wf_pid_run(&st->pid, temp);
358
359 DBG("wf_smu: new_setpoint: %d RPM\n", (int)new_setpoint);
360
361 scaled = ((((s64)new_setpoint) * (s64)st->scale0) >> 12) + st->offset0;
362
363 DBG("wf_smu: scaled setpoint: %d RPM\n", (int)scaled);
364
365 cputarget = wf_smu_cpu_fans ? wf_smu_cpu_fans->pid.target : 0;
366 cputarget = ((((s64)cputarget) * (s64)st->scale1) >> 12) + st->offset1;
367 scaled = max(scaled, cputarget);
368 scaled = max(scaled, st->pid.param.min);
369 scaled = min(scaled, st->pid.param.max);
370
371 DBG("wf_smu: adjusted setpoint: %d RPM\n", (int)scaled);
372
373 if (st->sys_setpoint == scaled && new_setpoint == st->hd_setpoint)
374 return;
375 st->sys_setpoint = scaled;
376 st->hd_setpoint = new_setpoint;
377 readjust:
378 if (fan_system && wf_smu_failure_state == 0) {
379 rc = fan_system->ops->set_value(fan_system, st->sys_setpoint);
380 if (rc) {
381 printk(KERN_WARNING "windfarm: Sys fan error %d\n",
382 rc);
383 wf_smu_failure_state |= FAILURE_FAN;
384 }
385 }
386 if (fan_hd && wf_smu_failure_state == 0) {
387 rc = fan_hd->ops->set_value(fan_hd, st->hd_setpoint);
388 if (rc) {
389 printk(KERN_WARNING "windfarm: HD fan error %d\n",
390 rc);
391 wf_smu_failure_state |= FAILURE_FAN;
392 }
393 }
394}
395
396static void wf_smu_create_cpu_fans(void)
397{
398 struct wf_cpu_pid_param pid_param;
399 struct smu_sdbp_header *hdr;
400 struct smu_sdbp_cpupiddata *piddata;
401 struct smu_sdbp_fvt *fvt;
402 s32 tmax, tdelta, maxpow, powadj;
403
404 /* First, locate the PID params in SMU SBD */
405 hdr = smu_get_sdb_partition(SMU_SDB_CPUPIDDATA_ID, NULL);
406 if (hdr == 0) {
407 printk(KERN_WARNING "windfarm: CPU PID fan config not found "
408 "max fan speed\n");
409 goto fail;
410 }
411 piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
412
413 /* Get the FVT params for operating point 0 (the only supported one
414 * for now) in order to get tmax
415 */
416 hdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
417 if (hdr) {
418 fvt = (struct smu_sdbp_fvt *)&hdr[1];
419 tmax = ((s32)fvt->maxtemp) << 16;
420 } else
421 tmax = 0x5e0000; /* 94 degree default */
422
423 /* Alloc & initialize state */
424 wf_smu_cpu_fans = kmalloc(sizeof(struct wf_smu_cpu_fans_state),
425 GFP_KERNEL);
426 if (wf_smu_cpu_fans == NULL)
427 goto fail;
428 wf_smu_cpu_fans->ticks = 1;
429
430 wf_smu_cpu_fans->scale = WF_SMU_CPU_FANS_SIBLING_SCALE;
431 wf_smu_cpu_fans->offset = WF_SMU_CPU_FANS_SIBLING_OFFSET;
432
433 /* Fill PID params */
434 pid_param.interval = WF_SMU_CPU_FANS_INTERVAL;
435 pid_param.history_len = piddata->history_len;
436 if (pid_param.history_len > WF_CPU_PID_MAX_HISTORY) {
437 printk(KERN_WARNING "windfarm: History size overflow on "
438 "CPU control loop (%d)\n", piddata->history_len);
439 pid_param.history_len = WF_CPU_PID_MAX_HISTORY;
440 }
441 pid_param.gd = piddata->gd;
442 pid_param.gp = piddata->gp;
443 pid_param.gr = piddata->gr / pid_param.history_len;
444
445 tdelta = ((s32)piddata->target_temp_delta) << 16;
446 maxpow = ((s32)piddata->max_power) << 16;
447 powadj = ((s32)piddata->power_adj) << 16;
448
449 pid_param.tmax = tmax;
450 pid_param.ttarget = tmax - tdelta;
451 pid_param.pmaxadj = maxpow - powadj;
452
453 pid_param.min = fan_cpu_main->ops->get_min(fan_cpu_main);
454 pid_param.max = fan_cpu_main->ops->get_max(fan_cpu_main);
455
456 wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param);
457
458 DBG("wf: CPU Fan control initialized.\n");
459 DBG(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM\n",
460 FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax),
461 pid_param.min, pid_param.max);
462
463 return;
464
465 fail:
466 printk(KERN_WARNING "windfarm: CPU fan config not found\n"
467 "for this machine model, max fan speed\n");
468
469 if (cpufreq_clamp)
470 wf_control_set_max(cpufreq_clamp);
471 if (fan_cpu_main)
472 wf_control_set_max(fan_cpu_main);
473}
474
475static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
476{
477 s32 new_setpoint, temp, power, systarget;
478 int rc;
479
480 if (--st->ticks != 0) {
481 if (wf_smu_readjust)
482 goto readjust;
483 return;
484 }
485 st->ticks = WF_SMU_CPU_FANS_INTERVAL;
486
487 rc = sensor_cpu_temp->ops->get_value(sensor_cpu_temp, &temp);
488 if (rc) {
489 printk(KERN_WARNING "windfarm: CPU temp sensor error %d\n",
490 rc);
491 wf_smu_failure_state |= FAILURE_SENSOR;
492 return;
493 }
494
495 rc = sensor_cpu_power->ops->get_value(sensor_cpu_power, &power);
496 if (rc) {
497 printk(KERN_WARNING "windfarm: CPU power sensor error %d\n",
498 rc);
499 wf_smu_failure_state |= FAILURE_SENSOR;
500 return;
501 }
502
503 DBG("wf_smu: CPU Fans tick ! CPU temp: %d.%03d, power: %d.%03d\n",
504 FIX32TOPRINT(temp), FIX32TOPRINT(power));
505
506#ifdef HACKED_OVERTEMP
507 if (temp > 0x4a0000)
508 wf_smu_failure_state |= FAILURE_OVERTEMP;
509#else
510 if (temp > st->pid.param.tmax)
511 wf_smu_failure_state |= FAILURE_OVERTEMP;
512#endif
513 new_setpoint = wf_cpu_pid_run(&st->pid, power, temp);
514
515 DBG("wf_smu: new_setpoint: %d RPM\n", (int)new_setpoint);
516
517 systarget = wf_smu_sys_fans ? wf_smu_sys_fans->pid.target : 0;
518 systarget = ((((s64)systarget) * (s64)st->scale) >> 12)
519 + st->offset;
520 new_setpoint = max(new_setpoint, systarget);
521 new_setpoint = max(new_setpoint, st->pid.param.min);
522 new_setpoint = min(new_setpoint, st->pid.param.max);
523
524 DBG("wf_smu: adjusted setpoint: %d RPM\n", (int)new_setpoint);
525
526 if (st->cpu_setpoint == new_setpoint)
527 return;
528 st->cpu_setpoint = new_setpoint;
529 readjust:
530 if (fan_cpu_main && wf_smu_failure_state == 0) {
531 rc = fan_cpu_main->ops->set_value(fan_cpu_main,
532 st->cpu_setpoint);
533 if (rc) {
534 printk(KERN_WARNING "windfarm: CPU main fan"
535 " error %d\n", rc);
536 wf_smu_failure_state |= FAILURE_FAN;
537 }
538 }
539}
540
541
542/*
543 * ****** Attributes ******
544 *
545 */
546
547#define BUILD_SHOW_FUNC_FIX(name, data) \
548static ssize_t show_##name(struct device *dev, \
549 struct device_attribute *attr, \
550 char *buf) \
551{ \
552 ssize_t r; \
553 s32 val = 0; \
554 data->ops->get_value(data, &val); \
555 r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \
556 return r; \
557} \
558static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
559
560
561#define BUILD_SHOW_FUNC_INT(name, data) \
562static ssize_t show_##name(struct device *dev, \
563 struct device_attribute *attr, \
564 char *buf) \
565{ \
566 s32 val = 0; \
567 data->ops->get_value(data, &val); \
568 return sprintf(buf, "%d", val); \
569} \
570static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
571
572BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
573BUILD_SHOW_FUNC_INT(sys_fan, fan_system);
574BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
575
576BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
577BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
578BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
579
580/*
581 * ****** Setup / Init / Misc ... ******
582 *
583 */
584
585static void wf_smu_tick(void)
586{
587 unsigned int last_failure = wf_smu_failure_state;
588 unsigned int new_failure;
589
590 if (!wf_smu_started) {
591 DBG("wf: creating control loops !\n");
592 wf_smu_create_sys_fans();
593 wf_smu_create_cpu_fans();
594 wf_smu_started = 1;
595 }
596
597 /* Skipping ticks */
598 if (wf_smu_skipping && --wf_smu_skipping)
599 return;
600
601 wf_smu_failure_state = 0;
602 if (wf_smu_sys_fans)
603 wf_smu_sys_fans_tick(wf_smu_sys_fans);
604 if (wf_smu_cpu_fans)
605 wf_smu_cpu_fans_tick(wf_smu_cpu_fans);
606
607 wf_smu_readjust = 0;
608 new_failure = wf_smu_failure_state & ~last_failure;
609
610 /* If entering failure mode, clamp cpufreq and ramp all
611 * fans to full speed.
612 */
613 if (wf_smu_failure_state && !last_failure) {
614 if (cpufreq_clamp)
615 wf_control_set_max(cpufreq_clamp);
616 if (fan_system)
617 wf_control_set_max(fan_system);
618 if (fan_cpu_main)
619 wf_control_set_max(fan_cpu_main);
620 if (fan_hd)
621 wf_control_set_max(fan_hd);
622 }
623
624 /* If leaving failure mode, unclamp cpufreq and readjust
625 * all fans on next iteration
626 */
627 if (!wf_smu_failure_state && last_failure) {
628 if (cpufreq_clamp)
629 wf_control_set_min(cpufreq_clamp);
630 wf_smu_readjust = 1;
631 }
632
633 /* Overtemp condition detected, notify and start skipping a couple
634 * ticks to let the temperature go down
635 */
636 if (new_failure & FAILURE_OVERTEMP) {
637 wf_set_overtemp();
638 wf_smu_skipping = 2;
639 }
640
641 /* We only clear the overtemp condition if overtemp is cleared
642 * _and_ no other failure is present. Since a sensor error will
643 * clear the overtemp condition (can't measure temperature) at
644 * the control loop levels, but we don't want to keep it clear
645 * here in this case
646 */
647 if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
648 wf_clear_overtemp();
649}
650
651static void wf_smu_new_control(struct wf_control *ct)
652{
653 if (wf_smu_all_controls_ok)
654 return;
655
656 if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) {
657 if (wf_get_control(ct) == 0) {
658 fan_cpu_main = ct;
659 device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
660 }
661 }
662
663 if (fan_system == NULL && !strcmp(ct->name, "system-fan")) {
664 if (wf_get_control(ct) == 0) {
665 fan_system = ct;
666 device_create_file(wf_smu_dev, &dev_attr_sys_fan);
667 }
668 }
669
670 if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
671 if (wf_get_control(ct) == 0)
672 cpufreq_clamp = ct;
673 }
674
675 /* Darwin property list says the HD fan is only for model ID
676 * 0, 1, 2 and 3
677 */
678
679 if (wf_smu_mach_model > 3) {
680 if (fan_system && fan_cpu_main && cpufreq_clamp)
681 wf_smu_all_controls_ok = 1;
682 return;
683 }
684
685 if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
686 if (wf_get_control(ct) == 0) {
687 fan_hd = ct;
688 device_create_file(wf_smu_dev, &dev_attr_hd_fan);
689 }
690 }
691
692 if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp)
693 wf_smu_all_controls_ok = 1;
694}
695
696static void wf_smu_new_sensor(struct wf_sensor *sr)
697{
698 if (wf_smu_all_sensors_ok)
699 return;
700
701 if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
702 if (wf_get_sensor(sr) == 0) {
703 sensor_cpu_power = sr;
704 device_create_file(wf_smu_dev, &dev_attr_cpu_power);
705 }
706 }
707
708 if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
709 if (wf_get_sensor(sr) == 0) {
710 sensor_cpu_temp = sr;
711 device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
712 }
713 }
714
715 if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
716 if (wf_get_sensor(sr) == 0) {
717 sensor_hd_temp = sr;
718 device_create_file(wf_smu_dev, &dev_attr_hd_temp);
719 }
720 }
721
722 if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp)
723 wf_smu_all_sensors_ok = 1;
724}
725
726
727static int wf_smu_notify(struct notifier_block *self,
728 unsigned long event, void *data)
729{
730 switch(event) {
731 case WF_EVENT_NEW_CONTROL:
732 DBG("wf: new control %s detected\n",
733 ((struct wf_control *)data)->name);
734 wf_smu_new_control(data);
735 wf_smu_readjust = 1;
736 break;
737 case WF_EVENT_NEW_SENSOR:
738 DBG("wf: new sensor %s detected\n",
739 ((struct wf_sensor *)data)->name);
740 wf_smu_new_sensor(data);
741 break;
742 case WF_EVENT_TICK:
743 if (wf_smu_all_controls_ok && wf_smu_all_sensors_ok)
744 wf_smu_tick();
745 }
746
747 return 0;
748}
749
750static struct notifier_block wf_smu_events = {
751 .notifier_call = wf_smu_notify,
752};
753
754static int wf_init_pm(void)
755{
756 struct smu_sdbp_header *hdr;
757
758 hdr = smu_get_sdb_partition(SMU_SDB_SENSORTREE_ID, NULL);
759 if (hdr != 0) {
760 struct smu_sdbp_sensortree *st =
761 (struct smu_sdbp_sensortree *)&hdr[1];
762 wf_smu_mach_model = st->model_id;
763 }
764
765 printk(KERN_INFO "windfarm: Initializing for iMacG5 model ID %d\n",
766 wf_smu_mach_model);
767
768 return 0;
769}
770
771static int wf_smu_probe(struct device *ddev)
772{
773 wf_smu_dev = ddev;
774
775 wf_register_client(&wf_smu_events);
776
777 return 0;
778}
779
780static int wf_smu_remove(struct device *ddev)
781{
782 wf_unregister_client(&wf_smu_events);
783
784 /* XXX We don't have yet a guarantee that our callback isn't
785 * in progress when returning from wf_unregister_client, so
786 * we add an arbitrary delay. I'll have to fix that in the core
787 */
788 msleep(1000);
789
790 /* Release all sensors */
791 /* One more crappy race: I don't think we have any guarantee here
792 * that the attribute callback won't race with the sensor beeing
793 * disposed of, and I'm not 100% certain what best way to deal
794 * with that except by adding locks all over... I'll do that
795 * eventually but heh, who ever rmmod this module anyway ?
796 */
797 if (sensor_cpu_power) {
798 device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
799 wf_put_sensor(sensor_cpu_power);
800 }
801 if (sensor_cpu_temp) {
802 device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
803 wf_put_sensor(sensor_cpu_temp);
804 }
805 if (sensor_hd_temp) {
806 device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
807 wf_put_sensor(sensor_hd_temp);
808 }
809
810 /* Release all controls */
811 if (fan_cpu_main) {
812 device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
813 wf_put_control(fan_cpu_main);
814 }
815 if (fan_hd) {
816 device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
817 wf_put_control(fan_hd);
818 }
819 if (fan_system) {
820 device_remove_file(wf_smu_dev, &dev_attr_sys_fan);
821 wf_put_control(fan_system);
822 }
823 if (cpufreq_clamp)
824 wf_put_control(cpufreq_clamp);
825
826 /* Destroy control loops state structures */
827 if (wf_smu_sys_fans)
828 kfree(wf_smu_sys_fans);
829 if (wf_smu_cpu_fans)
830 kfree(wf_smu_cpu_fans);
831
832 wf_smu_dev = NULL;
833
834 return 0;
835}
836
837static struct device_driver wf_smu_driver = {
838 .name = "windfarm",
839 .bus = &platform_bus_type,
840 .probe = wf_smu_probe,
841 .remove = wf_smu_remove,
842};
843
844
845static int __init wf_smu_init(void)
846{
847 int rc = -ENODEV;
848
849 if (machine_is_compatible("PowerMac8,1") ||
850 machine_is_compatible("PowerMac8,2"))
851 rc = wf_init_pm();
852
853 if (rc == 0) {
854#ifdef MODULE
855 request_module("windfarm_smu_controls");
856 request_module("windfarm_smu_sensors");
857 request_module("windfarm_lm75_sensor");
858
859#endif /* MODULE */
860 driver_register(&wf_smu_driver);
861 }
862
863 return rc;
864}
865
866static void __exit wf_smu_exit(void)
867{
868
869 driver_unregister(&wf_smu_driver);
870}
871
872
873module_init(wf_smu_init);
874module_exit(wf_smu_exit);
875
876MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
877MODULE_DESCRIPTION("Thermal control logic for iMac G5");
878MODULE_LICENSE("GPL");
879
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c
new file mode 100644
index 000000000000..43243cf7410b
--- /dev/null
+++ b/drivers/macintosh/windfarm_pm91.c
@@ -0,0 +1,814 @@
1/*
2 * Windfarm PowerMac thermal control. SMU based 1 CPU desktop control loops
3 *
4 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 *
9 * The algorithm used is the PID control algorithm, used the same
10 * way the published Darwin code does, using the same values that
11 * are present in the Darwin 8.2 snapshot property lists (note however
12 * that none of the code has been re-used, it's a complete re-implementation
13 *
14 * The various control loops found in Darwin config file are:
15 *
16 * PowerMac9,1
17 * ===========
18 *
19 * Has 3 control loops: CPU fans is similar to PowerMac8,1 (though it doesn't
20 * try to play with other control loops fans). Drive bay is rather basic PID
21 * with one sensor and one fan. Slots area is a bit different as the Darwin
22 * driver is supposed to be capable of working in a special "AGP" mode which
23 * involves the presence of an AGP sensor and an AGP fan (possibly on the
24 * AGP card itself). I can't deal with that special mode as I don't have
25 * access to those additional sensor/fans for now (though ultimately, it would
26 * be possible to add sensor objects for them) so I'm only implementing the
27 * basic PCI slot control loop
28 */
29
30#include <linux/types.h>
31#include <linux/errno.h>
32#include <linux/kernel.h>
33#include <linux/delay.h>
34#include <linux/slab.h>
35#include <linux/init.h>
36#include <linux/spinlock.h>
37#include <linux/wait.h>
38#include <linux/kmod.h>
39#include <linux/device.h>
40#include <linux/platform_device.h>
41#include <asm/prom.h>
42#include <asm/machdep.h>
43#include <asm/io.h>
44#include <asm/system.h>
45#include <asm/sections.h>
46#include <asm/smu.h>
47
48#include "windfarm.h"
49#include "windfarm_pid.h"
50
51#define VERSION "0.4"
52
53#undef DEBUG
54
55#ifdef DEBUG
56#define DBG(args...) printk(args)
57#else
58#define DBG(args...) do { } while(0)
59#endif
60
61/* define this to force CPU overtemp to 74 degree, useful for testing
62 * the overtemp code
63 */
64#undef HACKED_OVERTEMP
65
66static struct device *wf_smu_dev;
67
68/* Controls & sensors */
69static struct wf_sensor *sensor_cpu_power;
70static struct wf_sensor *sensor_cpu_temp;
71static struct wf_sensor *sensor_hd_temp;
72static struct wf_sensor *sensor_slots_power;
73static struct wf_control *fan_cpu_main;
74static struct wf_control *fan_cpu_second;
75static struct wf_control *fan_cpu_third;
76static struct wf_control *fan_hd;
77static struct wf_control *fan_slots;
78static struct wf_control *cpufreq_clamp;
79
80/* Set to kick the control loop into life */
81static int wf_smu_all_controls_ok, wf_smu_all_sensors_ok, wf_smu_started;
82
83/* Failure handling.. could be nicer */
84#define FAILURE_FAN 0x01
85#define FAILURE_SENSOR 0x02
86#define FAILURE_OVERTEMP 0x04
87
88static unsigned int wf_smu_failure_state;
89static int wf_smu_readjust, wf_smu_skipping;
90
91/*
92 * ****** CPU Fans Control Loop ******
93 *
94 */
95
96
97#define WF_SMU_CPU_FANS_INTERVAL 1
98#define WF_SMU_CPU_FANS_MAX_HISTORY 16
99
100/* State data used by the cpu fans control loop
101 */
102struct wf_smu_cpu_fans_state {
103 int ticks;
104 s32 cpu_setpoint;
105 struct wf_cpu_pid_state pid;
106};
107
108static struct wf_smu_cpu_fans_state *wf_smu_cpu_fans;
109
110
111
112/*
113 * ****** Drive Fan Control Loop ******
114 *
115 */
116
117struct wf_smu_drive_fans_state {
118 int ticks;
119 s32 setpoint;
120 struct wf_pid_state pid;
121};
122
123static struct wf_smu_drive_fans_state *wf_smu_drive_fans;
124
125/*
126 * ****** Slots Fan Control Loop ******
127 *
128 */
129
130struct wf_smu_slots_fans_state {
131 int ticks;
132 s32 setpoint;
133 struct wf_pid_state pid;
134};
135
136static struct wf_smu_slots_fans_state *wf_smu_slots_fans;
137
138/*
139 * ***** Implementation *****
140 *
141 */
142
143
144static void wf_smu_create_cpu_fans(void)
145{
146 struct wf_cpu_pid_param pid_param;
147 struct smu_sdbp_header *hdr;
148 struct smu_sdbp_cpupiddata *piddata;
149 struct smu_sdbp_fvt *fvt;
150 s32 tmax, tdelta, maxpow, powadj;
151
152 /* First, locate the PID params in SMU SBD */
153 hdr = smu_get_sdb_partition(SMU_SDB_CPUPIDDATA_ID, NULL);
154 if (hdr == 0) {
155 printk(KERN_WARNING "windfarm: CPU PID fan config not found "
156 "max fan speed\n");
157 goto fail;
158 }
159 piddata = (struct smu_sdbp_cpupiddata *)&hdr[1];
160
161 /* Get the FVT params for operating point 0 (the only supported one
162 * for now) in order to get tmax
163 */
164 hdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
165 if (hdr) {
166 fvt = (struct smu_sdbp_fvt *)&hdr[1];
167 tmax = ((s32)fvt->maxtemp) << 16;
168 } else
169 tmax = 0x5e0000; /* 94 degree default */
170
171 /* Alloc & initialize state */
172 wf_smu_cpu_fans = kmalloc(sizeof(struct wf_smu_cpu_fans_state),
173 GFP_KERNEL);
174 if (wf_smu_cpu_fans == NULL)
175 goto fail;
176 wf_smu_cpu_fans->ticks = 1;
177
178 /* Fill PID params */
179 pid_param.interval = WF_SMU_CPU_FANS_INTERVAL;
180 pid_param.history_len = piddata->history_len;
181 if (pid_param.history_len > WF_CPU_PID_MAX_HISTORY) {
182 printk(KERN_WARNING "windfarm: History size overflow on "
183 "CPU control loop (%d)\n", piddata->history_len);
184 pid_param.history_len = WF_CPU_PID_MAX_HISTORY;
185 }
186 pid_param.gd = piddata->gd;
187 pid_param.gp = piddata->gp;
188 pid_param.gr = piddata->gr / pid_param.history_len;
189
190 tdelta = ((s32)piddata->target_temp_delta) << 16;
191 maxpow = ((s32)piddata->max_power) << 16;
192 powadj = ((s32)piddata->power_adj) << 16;
193
194 pid_param.tmax = tmax;
195 pid_param.ttarget = tmax - tdelta;
196 pid_param.pmaxadj = maxpow - powadj;
197
198 pid_param.min = fan_cpu_main->ops->get_min(fan_cpu_main);
199 pid_param.max = fan_cpu_main->ops->get_max(fan_cpu_main);
200
201 wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param);
202
203 DBG("wf: CPU Fan control initialized.\n");
204 DBG(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM\n",
205 FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax),
206 pid_param.min, pid_param.max);
207
208 return;
209
210 fail:
211 printk(KERN_WARNING "windfarm: CPU fan config not found\n"
212 "for this machine model, max fan speed\n");
213
214 if (cpufreq_clamp)
215 wf_control_set_max(cpufreq_clamp);
216 if (fan_cpu_main)
217 wf_control_set_max(fan_cpu_main);
218}
219
220static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st)
221{
222 s32 new_setpoint, temp, power;
223 int rc;
224
225 if (--st->ticks != 0) {
226 if (wf_smu_readjust)
227 goto readjust;
228 return;
229 }
230 st->ticks = WF_SMU_CPU_FANS_INTERVAL;
231
232 rc = sensor_cpu_temp->ops->get_value(sensor_cpu_temp, &temp);
233 if (rc) {
234 printk(KERN_WARNING "windfarm: CPU temp sensor error %d\n",
235 rc);
236 wf_smu_failure_state |= FAILURE_SENSOR;
237 return;
238 }
239
240 rc = sensor_cpu_power->ops->get_value(sensor_cpu_power, &power);
241 if (rc) {
242 printk(KERN_WARNING "windfarm: CPU power sensor error %d\n",
243 rc);
244 wf_smu_failure_state |= FAILURE_SENSOR;
245 return;
246 }
247
248 DBG("wf_smu: CPU Fans tick ! CPU temp: %d.%03d, power: %d.%03d\n",
249 FIX32TOPRINT(temp), FIX32TOPRINT(power));
250
251#ifdef HACKED_OVERTEMP
252 if (temp > 0x4a0000)
253 wf_smu_failure_state |= FAILURE_OVERTEMP;
254#else
255 if (temp > st->pid.param.tmax)
256 wf_smu_failure_state |= FAILURE_OVERTEMP;
257#endif
258 new_setpoint = wf_cpu_pid_run(&st->pid, power, temp);
259
260 DBG("wf_smu: new_setpoint: %d RPM\n", (int)new_setpoint);
261
262 if (st->cpu_setpoint == new_setpoint)
263 return;
264 st->cpu_setpoint = new_setpoint;
265 readjust:
266 if (fan_cpu_main && wf_smu_failure_state == 0) {
267 rc = fan_cpu_main->ops->set_value(fan_cpu_main,
268 st->cpu_setpoint);
269 if (rc) {
270 printk(KERN_WARNING "windfarm: CPU main fan"
271 " error %d\n", rc);
272 wf_smu_failure_state |= FAILURE_FAN;
273 }
274 }
275 if (fan_cpu_second && wf_smu_failure_state == 0) {
276 rc = fan_cpu_second->ops->set_value(fan_cpu_second,
277 st->cpu_setpoint);
278 if (rc) {
279 printk(KERN_WARNING "windfarm: CPU second fan"
280 " error %d\n", rc);
281 wf_smu_failure_state |= FAILURE_FAN;
282 }
283 }
284 if (fan_cpu_third && wf_smu_failure_state == 0) {
285 rc = fan_cpu_main->ops->set_value(fan_cpu_third,
286 st->cpu_setpoint);
287 if (rc) {
288 printk(KERN_WARNING "windfarm: CPU third fan"
289 " error %d\n", rc);
290 wf_smu_failure_state |= FAILURE_FAN;
291 }
292 }
293}
294
295static void wf_smu_create_drive_fans(void)
296{
297 struct wf_pid_param param = {
298 .interval = 5,
299 .history_len = 2,
300 .gd = 0x01e00000,
301 .gp = 0x00500000,
302 .gr = 0x00000000,
303 .itarget = 0x00200000,
304 };
305
306 /* Alloc & initialize state */
307 wf_smu_drive_fans = kmalloc(sizeof(struct wf_smu_drive_fans_state),
308 GFP_KERNEL);
309 if (wf_smu_drive_fans == NULL) {
310 printk(KERN_WARNING "windfarm: Memory allocation error"
311 " max fan speed\n");
312 goto fail;
313 }
314 wf_smu_drive_fans->ticks = 1;
315
316 /* Fill PID params */
317 param.additive = (fan_hd->type == WF_CONTROL_RPM_FAN);
318 param.min = fan_hd->ops->get_min(fan_hd);
319 param.max = fan_hd->ops->get_max(fan_hd);
320 wf_pid_init(&wf_smu_drive_fans->pid, &param);
321
322 DBG("wf: Drive Fan control initialized.\n");
323 DBG(" itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
324 FIX32TOPRINT(param.itarget), param.min, param.max);
325 return;
326
327 fail:
328 if (fan_hd)
329 wf_control_set_max(fan_hd);
330}
331
332static void wf_smu_drive_fans_tick(struct wf_smu_drive_fans_state *st)
333{
334 s32 new_setpoint, temp;
335 int rc;
336
337 if (--st->ticks != 0) {
338 if (wf_smu_readjust)
339 goto readjust;
340 return;
341 }
342 st->ticks = st->pid.param.interval;
343
344 rc = sensor_hd_temp->ops->get_value(sensor_hd_temp, &temp);
345 if (rc) {
346 printk(KERN_WARNING "windfarm: HD temp sensor error %d\n",
347 rc);
348 wf_smu_failure_state |= FAILURE_SENSOR;
349 return;
350 }
351
352 DBG("wf_smu: Drive Fans tick ! HD temp: %d.%03d\n",
353 FIX32TOPRINT(temp));
354
355 if (temp > (st->pid.param.itarget + 0x50000))
356 wf_smu_failure_state |= FAILURE_OVERTEMP;
357
358 new_setpoint = wf_pid_run(&st->pid, temp);
359
360 DBG("wf_smu: new_setpoint: %d\n", (int)new_setpoint);
361
362 if (st->setpoint == new_setpoint)
363 return;
364 st->setpoint = new_setpoint;
365 readjust:
366 if (fan_hd && wf_smu_failure_state == 0) {
367 rc = fan_hd->ops->set_value(fan_hd, st->setpoint);
368 if (rc) {
369 printk(KERN_WARNING "windfarm: HD fan error %d\n",
370 rc);
371 wf_smu_failure_state |= FAILURE_FAN;
372 }
373 }
374}
375
376static void wf_smu_create_slots_fans(void)
377{
378 struct wf_pid_param param = {
379 .interval = 1,
380 .history_len = 8,
381 .gd = 0x00000000,
382 .gp = 0x00000000,
383 .gr = 0x00020000,
384 .itarget = 0x00000000
385 };
386
387 /* Alloc & initialize state */
388 wf_smu_slots_fans = kmalloc(sizeof(struct wf_smu_slots_fans_state),
389 GFP_KERNEL);
390 if (wf_smu_slots_fans == NULL) {
391 printk(KERN_WARNING "windfarm: Memory allocation error"
392 " max fan speed\n");
393 goto fail;
394 }
395 wf_smu_slots_fans->ticks = 1;
396
397 /* Fill PID params */
398 param.additive = (fan_slots->type == WF_CONTROL_RPM_FAN);
399 param.min = fan_slots->ops->get_min(fan_slots);
400 param.max = fan_slots->ops->get_max(fan_slots);
401 wf_pid_init(&wf_smu_slots_fans->pid, &param);
402
403 DBG("wf: Slots Fan control initialized.\n");
404 DBG(" itarged=%d.%03d, min=%d RPM, max=%d RPM\n",
405 FIX32TOPRINT(param.itarget), param.min, param.max);
406 return;
407
408 fail:
409 if (fan_slots)
410 wf_control_set_max(fan_slots);
411}
412
413static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st)
414{
415 s32 new_setpoint, power;
416 int rc;
417
418 if (--st->ticks != 0) {
419 if (wf_smu_readjust)
420 goto readjust;
421 return;
422 }
423 st->ticks = st->pid.param.interval;
424
425 rc = sensor_slots_power->ops->get_value(sensor_slots_power, &power);
426 if (rc) {
427 printk(KERN_WARNING "windfarm: Slots power sensor error %d\n",
428 rc);
429 wf_smu_failure_state |= FAILURE_SENSOR;
430 return;
431 }
432
433 DBG("wf_smu: Slots Fans tick ! Slots power: %d.%03d\n",
434 FIX32TOPRINT(power));
435
436#if 0 /* Check what makes a good overtemp condition */
437 if (power > (st->pid.param.itarget + 0x50000))
438 wf_smu_failure_state |= FAILURE_OVERTEMP;
439#endif
440
441 new_setpoint = wf_pid_run(&st->pid, power);
442
443 DBG("wf_smu: new_setpoint: %d\n", (int)new_setpoint);
444
445 if (st->setpoint == new_setpoint)
446 return;
447 st->setpoint = new_setpoint;
448 readjust:
449 if (fan_slots && wf_smu_failure_state == 0) {
450 rc = fan_slots->ops->set_value(fan_slots, st->setpoint);
451 if (rc) {
452 printk(KERN_WARNING "windfarm: Slots fan error %d\n",
453 rc);
454 wf_smu_failure_state |= FAILURE_FAN;
455 }
456 }
457}
458
459
460/*
461 * ****** Attributes ******
462 *
463 */
464
465#define BUILD_SHOW_FUNC_FIX(name, data) \
466static ssize_t show_##name(struct device *dev, \
467 struct device_attribute *attr, \
468 char *buf) \
469{ \
470 ssize_t r; \
471 s32 val = 0; \
472 data->ops->get_value(data, &val); \
473 r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \
474 return r; \
475} \
476static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
477
478
479#define BUILD_SHOW_FUNC_INT(name, data) \
480static ssize_t show_##name(struct device *dev, \
481 struct device_attribute *attr, \
482 char *buf) \
483{ \
484 s32 val = 0; \
485 data->ops->get_value(data, &val); \
486 return sprintf(buf, "%d", val); \
487} \
488static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL);
489
490BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main);
491BUILD_SHOW_FUNC_INT(hd_fan, fan_hd);
492BUILD_SHOW_FUNC_INT(slots_fan, fan_slots);
493
494BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp);
495BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power);
496BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp);
497BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power);
498
499/*
500 * ****** Setup / Init / Misc ... ******
501 *
502 */
503
504static void wf_smu_tick(void)
505{
506 unsigned int last_failure = wf_smu_failure_state;
507 unsigned int new_failure;
508
509 if (!wf_smu_started) {
510 DBG("wf: creating control loops !\n");
511 wf_smu_create_drive_fans();
512 wf_smu_create_slots_fans();
513 wf_smu_create_cpu_fans();
514 wf_smu_started = 1;
515 }
516
517 /* Skipping ticks */
518 if (wf_smu_skipping && --wf_smu_skipping)
519 return;
520
521 wf_smu_failure_state = 0;
522 if (wf_smu_drive_fans)
523 wf_smu_drive_fans_tick(wf_smu_drive_fans);
524 if (wf_smu_slots_fans)
525 wf_smu_slots_fans_tick(wf_smu_slots_fans);
526 if (wf_smu_cpu_fans)
527 wf_smu_cpu_fans_tick(wf_smu_cpu_fans);
528
529 wf_smu_readjust = 0;
530 new_failure = wf_smu_failure_state & ~last_failure;
531
532 /* If entering failure mode, clamp cpufreq and ramp all
533 * fans to full speed.
534 */
535 if (wf_smu_failure_state && !last_failure) {
536 if (cpufreq_clamp)
537 wf_control_set_max(cpufreq_clamp);
538 if (fan_cpu_main)
539 wf_control_set_max(fan_cpu_main);
540 if (fan_cpu_second)
541 wf_control_set_max(fan_cpu_second);
542 if (fan_cpu_third)
543 wf_control_set_max(fan_cpu_third);
544 if (fan_hd)
545 wf_control_set_max(fan_hd);
546 if (fan_slots)
547 wf_control_set_max(fan_slots);
548 }
549
550 /* If leaving failure mode, unclamp cpufreq and readjust
551 * all fans on next iteration
552 */
553 if (!wf_smu_failure_state && last_failure) {
554 if (cpufreq_clamp)
555 wf_control_set_min(cpufreq_clamp);
556 wf_smu_readjust = 1;
557 }
558
559 /* Overtemp condition detected, notify and start skipping a couple
560 * ticks to let the temperature go down
561 */
562 if (new_failure & FAILURE_OVERTEMP) {
563 wf_set_overtemp();
564 wf_smu_skipping = 2;
565 }
566
567 /* We only clear the overtemp condition if overtemp is cleared
568 * _and_ no other failure is present. Since a sensor error will
569 * clear the overtemp condition (can't measure temperature) at
570 * the control loop levels, but we don't want to keep it clear
571 * here in this case
572 */
573 if (new_failure == 0 && last_failure & FAILURE_OVERTEMP)
574 wf_clear_overtemp();
575}
576
577
578static void wf_smu_new_control(struct wf_control *ct)
579{
580 if (wf_smu_all_controls_ok)
581 return;
582
583 if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) {
584 if (wf_get_control(ct) == 0) {
585 fan_cpu_main = ct;
586 device_create_file(wf_smu_dev, &dev_attr_cpu_fan);
587 }
588 }
589
590 if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) {
591 if (wf_get_control(ct) == 0)
592 fan_cpu_second = ct;
593 }
594
595 if (fan_cpu_third == NULL && !strcmp(ct->name, "cpu-front-fan-0")) {
596 if (wf_get_control(ct) == 0)
597 fan_cpu_third = ct;
598 }
599
600 if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) {
601 if (wf_get_control(ct) == 0)
602 cpufreq_clamp = ct;
603 }
604
605 if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) {
606 if (wf_get_control(ct) == 0) {
607 fan_hd = ct;
608 device_create_file(wf_smu_dev, &dev_attr_hd_fan);
609 }
610 }
611
612 if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) {
613 if (wf_get_control(ct) == 0) {
614 fan_slots = ct;
615 device_create_file(wf_smu_dev, &dev_attr_slots_fan);
616 }
617 }
618
619 if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd &&
620 fan_slots && cpufreq_clamp)
621 wf_smu_all_controls_ok = 1;
622}
623
624static void wf_smu_new_sensor(struct wf_sensor *sr)
625{
626 if (wf_smu_all_sensors_ok)
627 return;
628
629 if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) {
630 if (wf_get_sensor(sr) == 0) {
631 sensor_cpu_power = sr;
632 device_create_file(wf_smu_dev, &dev_attr_cpu_power);
633 }
634 }
635
636 if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) {
637 if (wf_get_sensor(sr) == 0) {
638 sensor_cpu_temp = sr;
639 device_create_file(wf_smu_dev, &dev_attr_cpu_temp);
640 }
641 }
642
643 if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) {
644 if (wf_get_sensor(sr) == 0) {
645 sensor_hd_temp = sr;
646 device_create_file(wf_smu_dev, &dev_attr_hd_temp);
647 }
648 }
649
650 if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) {
651 if (wf_get_sensor(sr) == 0) {
652 sensor_slots_power = sr;
653 device_create_file(wf_smu_dev, &dev_attr_slots_power);
654 }
655 }
656
657 if (sensor_cpu_power && sensor_cpu_temp &&
658 sensor_hd_temp && sensor_slots_power)
659 wf_smu_all_sensors_ok = 1;
660}
661
662
663static int wf_smu_notify(struct notifier_block *self,
664 unsigned long event, void *data)
665{
666 switch(event) {
667 case WF_EVENT_NEW_CONTROL:
668 DBG("wf: new control %s detected\n",
669 ((struct wf_control *)data)->name);
670 wf_smu_new_control(data);
671 wf_smu_readjust = 1;
672 break;
673 case WF_EVENT_NEW_SENSOR:
674 DBG("wf: new sensor %s detected\n",
675 ((struct wf_sensor *)data)->name);
676 wf_smu_new_sensor(data);
677 break;
678 case WF_EVENT_TICK:
679 if (wf_smu_all_controls_ok && wf_smu_all_sensors_ok)
680 wf_smu_tick();
681 }
682
683 return 0;
684}
685
686static struct notifier_block wf_smu_events = {
687 .notifier_call = wf_smu_notify,
688};
689
690static int wf_init_pm(void)
691{
692 printk(KERN_INFO "windfarm: Initializing for Desktop G5 model\n");
693
694 return 0;
695}
696
697static int wf_smu_probe(struct device *ddev)
698{
699 wf_smu_dev = ddev;
700
701 wf_register_client(&wf_smu_events);
702
703 return 0;
704}
705
706static int wf_smu_remove(struct device *ddev)
707{
708 wf_unregister_client(&wf_smu_events);
709
710 /* XXX We don't have yet a guarantee that our callback isn't
711 * in progress when returning from wf_unregister_client, so
712 * we add an arbitrary delay. I'll have to fix that in the core
713 */
714 msleep(1000);
715
716 /* Release all sensors */
717 /* One more crappy race: I don't think we have any guarantee here
718 * that the attribute callback won't race with the sensor beeing
719 * disposed of, and I'm not 100% certain what best way to deal
720 * with that except by adding locks all over... I'll do that
721 * eventually but heh, who ever rmmod this module anyway ?
722 */
723 if (sensor_cpu_power) {
724 device_remove_file(wf_smu_dev, &dev_attr_cpu_power);
725 wf_put_sensor(sensor_cpu_power);
726 }
727 if (sensor_cpu_temp) {
728 device_remove_file(wf_smu_dev, &dev_attr_cpu_temp);
729 wf_put_sensor(sensor_cpu_temp);
730 }
731 if (sensor_hd_temp) {
732 device_remove_file(wf_smu_dev, &dev_attr_hd_temp);
733 wf_put_sensor(sensor_hd_temp);
734 }
735 if (sensor_slots_power) {
736 device_remove_file(wf_smu_dev, &dev_attr_slots_power);
737 wf_put_sensor(sensor_slots_power);
738 }
739
740 /* Release all controls */
741 if (fan_cpu_main) {
742 device_remove_file(wf_smu_dev, &dev_attr_cpu_fan);
743 wf_put_control(fan_cpu_main);
744 }
745 if (fan_cpu_second)
746 wf_put_control(fan_cpu_second);
747 if (fan_cpu_third)
748 wf_put_control(fan_cpu_third);
749 if (fan_hd) {
750 device_remove_file(wf_smu_dev, &dev_attr_hd_fan);
751 wf_put_control(fan_hd);
752 }
753 if (fan_slots) {
754 device_remove_file(wf_smu_dev, &dev_attr_slots_fan);
755 wf_put_control(fan_slots);
756 }
757 if (cpufreq_clamp)
758 wf_put_control(cpufreq_clamp);
759
760 /* Destroy control loops state structures */
761 if (wf_smu_slots_fans)
762 kfree(wf_smu_cpu_fans);
763 if (wf_smu_drive_fans)
764 kfree(wf_smu_cpu_fans);
765 if (wf_smu_cpu_fans)
766 kfree(wf_smu_cpu_fans);
767
768 wf_smu_dev = NULL;
769
770 return 0;
771}
772
773static struct device_driver wf_smu_driver = {
774 .name = "windfarm",
775 .bus = &platform_bus_type,
776 .probe = wf_smu_probe,
777 .remove = wf_smu_remove,
778};
779
780
781static int __init wf_smu_init(void)
782{
783 int rc = -ENODEV;
784
785 if (machine_is_compatible("PowerMac9,1"))
786 rc = wf_init_pm();
787
788 if (rc == 0) {
789#ifdef MODULE
790 request_module("windfarm_smu_controls");
791 request_module("windfarm_smu_sensors");
792 request_module("windfarm_lm75_sensor");
793
794#endif /* MODULE */
795 driver_register(&wf_smu_driver);
796 }
797
798 return rc;
799}
800
801static void __exit wf_smu_exit(void)
802{
803
804 driver_unregister(&wf_smu_driver);
805}
806
807
808module_init(wf_smu_init);
809module_exit(wf_smu_exit);
810
811MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
812MODULE_DESCRIPTION("Thermal control logic for PowerMac9,1");
813MODULE_LICENSE("GPL");
814
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
new file mode 100644
index 000000000000..2c3158c81ff2
--- /dev/null
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -0,0 +1,282 @@
1/*
2 * Windfarm PowerMac thermal control. SMU based controls
3 *
4 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 */
9
10#include <linux/types.h>
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/slab.h>
15#include <linux/init.h>
16#include <linux/wait.h>
17#include <asm/prom.h>
18#include <asm/machdep.h>
19#include <asm/io.h>
20#include <asm/system.h>
21#include <asm/sections.h>
22#include <asm/smu.h>
23
24#include "windfarm.h"
25
26#define VERSION "0.3"
27
28#undef DEBUG
29
30#ifdef DEBUG
31#define DBG(args...) printk(args)
32#else
33#define DBG(args...) do { } while(0)
34#endif
35
36/*
37 * SMU fans control object
38 */
39
40static LIST_HEAD(smu_fans);
41
42struct smu_fan_control {
43 struct list_head link;
44 int fan_type; /* 0 = rpm, 1 = pwm */
45 u32 reg; /* index in SMU */
46 s32 value; /* current value */
47 s32 min, max; /* min/max values */
48 struct wf_control ctrl;
49};
50#define to_smu_fan(c) container_of(c, struct smu_fan_control, ctrl)
51
52static int smu_set_fan(int pwm, u8 id, u16 value)
53{
54 struct smu_cmd cmd;
55 u8 buffer[16];
56 DECLARE_COMPLETION(comp);
57 int rc;
58
59 /* Fill SMU command structure */
60 cmd.cmd = SMU_CMD_FAN_COMMAND;
61 cmd.data_len = 14;
62 cmd.reply_len = 16;
63 cmd.data_buf = cmd.reply_buf = buffer;
64 cmd.status = 0;
65 cmd.done = smu_done_complete;
66 cmd.misc = &comp;
67
68 /* Fill argument buffer */
69 memset(buffer, 0, 16);
70 buffer[0] = pwm ? 0x10 : 0x00;
71 buffer[1] = 0x01 << id;
72 *((u16 *)&buffer[2 + id * 2]) = value;
73
74 rc = smu_queue_cmd(&cmd);
75 if (rc)
76 return rc;
77 wait_for_completion(&comp);
78 return cmd.status;
79}
80
81static void smu_fan_release(struct wf_control *ct)
82{
83 struct smu_fan_control *fct = to_smu_fan(ct);
84
85 kfree(fct);
86}
87
88static int smu_fan_set(struct wf_control *ct, s32 value)
89{
90 struct smu_fan_control *fct = to_smu_fan(ct);
91
92 if (value < fct->min)
93 value = fct->min;
94 if (value > fct->max)
95 value = fct->max;
96 fct->value = value;
97
98 return smu_set_fan(fct->fan_type, fct->reg, value);
99}
100
101static int smu_fan_get(struct wf_control *ct, s32 *value)
102{
103 struct smu_fan_control *fct = to_smu_fan(ct);
104 *value = fct->value; /* todo: read from SMU */
105 return 0;
106}
107
108static s32 smu_fan_min(struct wf_control *ct)
109{
110 struct smu_fan_control *fct = to_smu_fan(ct);
111 return fct->min;
112}
113
114static s32 smu_fan_max(struct wf_control *ct)
115{
116 struct smu_fan_control *fct = to_smu_fan(ct);
117 return fct->max;
118}
119
120static struct wf_control_ops smu_fan_ops = {
121 .set_value = smu_fan_set,
122 .get_value = smu_fan_get,
123 .get_min = smu_fan_min,
124 .get_max = smu_fan_max,
125 .release = smu_fan_release,
126 .owner = THIS_MODULE,
127};
128
129static struct smu_fan_control *smu_fan_create(struct device_node *node,
130 int pwm_fan)
131{
132 struct smu_fan_control *fct;
133 s32 *v; u32 *reg;
134 char *l;
135
136 fct = kmalloc(sizeof(struct smu_fan_control), GFP_KERNEL);
137 if (fct == NULL)
138 return NULL;
139 fct->ctrl.ops = &smu_fan_ops;
140 l = (char *)get_property(node, "location", NULL);
141 if (l == NULL)
142 goto fail;
143
144 fct->fan_type = pwm_fan;
145 fct->ctrl.type = pwm_fan ? WF_CONTROL_PWM_FAN : WF_CONTROL_RPM_FAN;
146
147 /* We use the name & location here the same way we do for SMU sensors,
148 * see the comment in windfarm_smu_sensors.c. The locations are a bit
149 * less consistent here between the iMac and the desktop models, but
150 * that is good enough for our needs for now at least.
151 *
152 * One problem though is that Apple seem to be inconsistent with case
153 * and the kernel doesn't have strcasecmp =P
154 */
155
156 fct->ctrl.name = NULL;
157
158 /* Names used on desktop models */
159 if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") ||
160 !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan"))
161 fct->ctrl.name = "cpu-rear-fan-0";
162 else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1"))
163 fct->ctrl.name = "cpu-rear-fan-1";
164 else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") ||
165 !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan"))
166 fct->ctrl.name = "cpu-front-fan-0";
167 else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1"))
168 fct->ctrl.name = "cpu-front-fan-1";
169 else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan"))
170 fct->ctrl.name = "slots-fan";
171 else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay"))
172 fct->ctrl.name = "drive-bay-fan";
173
174 /* Names used on iMac models */
175 if (!strcmp(l, "System Fan") || !strcmp(l, "System fan"))
176 fct->ctrl.name = "system-fan";
177 else if (!strcmp(l, "CPU Fan") || !strcmp(l, "CPU fan"))
178 fct->ctrl.name = "cpu-fan";
179 else if (!strcmp(l, "Hard Drive") || !strcmp(l, "Hard drive"))
180 fct->ctrl.name = "drive-bay-fan";
181
182 /* Unrecognized fan, bail out */
183 if (fct->ctrl.name == NULL)
184 goto fail;
185
186 /* Get min & max values*/
187 v = (s32 *)get_property(node, "min-value", NULL);
188 if (v == NULL)
189 goto fail;
190 fct->min = *v;
191 v = (s32 *)get_property(node, "max-value", NULL);
192 if (v == NULL)
193 goto fail;
194 fct->max = *v;
195
196 /* Get "reg" value */
197 reg = (u32 *)get_property(node, "reg", NULL);
198 if (reg == NULL)
199 goto fail;
200 fct->reg = *reg;
201
202 if (wf_register_control(&fct->ctrl))
203 goto fail;
204
205 return fct;
206 fail:
207 kfree(fct);
208 return NULL;
209}
210
211
212static int __init smu_controls_init(void)
213{
214 struct device_node *smu, *fans, *fan;
215
216 if (!smu_present())
217 return -ENODEV;
218
219 smu = of_find_node_by_type(NULL, "smu");
220 if (smu == NULL)
221 return -ENODEV;
222
223 /* Look for RPM fans */
224 for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
225 if (!strcmp(fans->name, "rpm-fans"))
226 break;
227 for (fan = NULL;
228 fans && (fan = of_get_next_child(fans, fan)) != NULL;) {
229 struct smu_fan_control *fct;
230
231 fct = smu_fan_create(fan, 0);
232 if (fct == NULL) {
233 printk(KERN_WARNING "windfarm: Failed to create SMU "
234 "RPM fan %s\n", fan->name);
235 continue;
236 }
237 list_add(&fct->link, &smu_fans);
238 }
239 of_node_put(fans);
240
241
242 /* Look for PWM fans */
243 for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;)
244 if (!strcmp(fans->name, "pwm-fans"))
245 break;
246 for (fan = NULL;
247 fans && (fan = of_get_next_child(fans, fan)) != NULL;) {
248 struct smu_fan_control *fct;
249
250 fct = smu_fan_create(fan, 1);
251 if (fct == NULL) {
252 printk(KERN_WARNING "windfarm: Failed to create SMU "
253 "PWM fan %s\n", fan->name);
254 continue;
255 }
256 list_add(&fct->link, &smu_fans);
257 }
258 of_node_put(fans);
259 of_node_put(smu);
260
261 return 0;
262}
263
264static void __exit smu_controls_exit(void)
265{
266 struct smu_fan_control *fct;
267
268 while (!list_empty(&smu_fans)) {
269 fct = list_entry(smu_fans.next, struct smu_fan_control, link);
270 list_del(&fct->link);
271 wf_unregister_control(&fct->ctrl);
272 }
273}
274
275
276module_init(smu_controls_init);
277module_exit(smu_controls_exit);
278
279MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
280MODULE_DESCRIPTION("SMU control objects for PowerMacs thermal control");
281MODULE_LICENSE("GPL");
282
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c
new file mode 100644
index 000000000000..b558cc209d49
--- /dev/null
+++ b/drivers/macintosh/windfarm_smu_sensors.c
@@ -0,0 +1,479 @@
1/*
2 * Windfarm PowerMac thermal control. SMU based sensors
3 *
4 * (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 */
9
10#include <linux/types.h>
11#include <linux/errno.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
14#include <linux/slab.h>
15#include <linux/init.h>
16#include <linux/wait.h>
17#include <asm/prom.h>
18#include <asm/machdep.h>
19#include <asm/io.h>
20#include <asm/system.h>
21#include <asm/sections.h>
22#include <asm/smu.h>
23
24#include "windfarm.h"
25
26#define VERSION "0.2"
27
28#undef DEBUG
29
30#ifdef DEBUG
31#define DBG(args...) printk(args)
32#else
33#define DBG(args...) do { } while(0)
34#endif
35
36/*
37 * Various SMU "partitions" calibration objects for which we
38 * keep pointers here for use by bits & pieces of the driver
39 */
40static struct smu_sdbp_cpuvcp *cpuvcp;
41static int cpuvcp_version;
42static struct smu_sdbp_cpudiode *cpudiode;
43static struct smu_sdbp_slotspow *slotspow;
44static u8 *debugswitches;
45
46/*
47 * SMU basic sensors objects
48 */
49
50static LIST_HEAD(smu_ads);
51
52struct smu_ad_sensor {
53 struct list_head link;
54 u32 reg; /* index in SMU */
55 struct wf_sensor sens;
56};
57#define to_smu_ads(c) container_of(c, struct smu_ad_sensor, sens)
58
59static void smu_ads_release(struct wf_sensor *sr)
60{
61 struct smu_ad_sensor *ads = to_smu_ads(sr);
62
63 kfree(ads);
64}
65
66static int smu_read_adc(u8 id, s32 *value)
67{
68 struct smu_simple_cmd cmd;
69 DECLARE_COMPLETION(comp);
70 int rc;
71
72 rc = smu_queue_simple(&cmd, SMU_CMD_READ_ADC, 1,
73 smu_done_complete, &comp, id);
74 if (rc)
75 return rc;
76 wait_for_completion(&comp);
77 if (cmd.cmd.status != 0)
78 return cmd.cmd.status;
79 if (cmd.cmd.reply_len != 2) {
80 printk(KERN_ERR "winfarm: read ADC 0x%x returned %d bytes !\n",
81 id, cmd.cmd.reply_len);
82 return -EIO;
83 }
84 *value = *((u16 *)cmd.buffer);
85 return 0;
86}
87
88static int smu_cputemp_get(struct wf_sensor *sr, s32 *value)
89{
90 struct smu_ad_sensor *ads = to_smu_ads(sr);
91 int rc;
92 s32 val;
93 s64 scaled;
94
95 rc = smu_read_adc(ads->reg, &val);
96 if (rc) {
97 printk(KERN_ERR "windfarm: read CPU temp failed, err %d\n",
98 rc);
99 return rc;
100 }
101
102 /* Ok, we have to scale & adjust, taking units into account */
103 scaled = (s64)(((u64)val) * (u64)cpudiode->m_value);
104 scaled >>= 3;
105 scaled += ((s64)cpudiode->b_value) << 9;
106 *value = (s32)(scaled << 1);
107
108 return 0;
109}
110
111static int smu_cpuamp_get(struct wf_sensor *sr, s32 *value)
112{
113 struct smu_ad_sensor *ads = to_smu_ads(sr);
114 s32 val, scaled;
115 int rc;
116
117 rc = smu_read_adc(ads->reg, &val);
118 if (rc) {
119 printk(KERN_ERR "windfarm: read CPU current failed, err %d\n",
120 rc);
121 return rc;
122 }
123
124 /* Ok, we have to scale & adjust, taking units into account */
125 scaled = (s32)(val * (u32)cpuvcp->curr_scale);
126 scaled += (s32)cpuvcp->curr_offset;
127 *value = scaled << 4;
128
129 return 0;
130}
131
132static int smu_cpuvolt_get(struct wf_sensor *sr, s32 *value)
133{
134 struct smu_ad_sensor *ads = to_smu_ads(sr);
135 s32 val, scaled;
136 int rc;
137
138 rc = smu_read_adc(ads->reg, &val);
139 if (rc) {
140 printk(KERN_ERR "windfarm: read CPU voltage failed, err %d\n",
141 rc);
142 return rc;
143 }
144
145 /* Ok, we have to scale & adjust, taking units into account */
146 scaled = (s32)(val * (u32)cpuvcp->volt_scale);
147 scaled += (s32)cpuvcp->volt_offset;
148 *value = scaled << 4;
149
150 return 0;
151}
152
153static int smu_slotspow_get(struct wf_sensor *sr, s32 *value)
154{
155 struct smu_ad_sensor *ads = to_smu_ads(sr);
156 s32 val, scaled;
157 int rc;
158
159 rc = smu_read_adc(ads->reg, &val);
160 if (rc) {
161 printk(KERN_ERR "windfarm: read slots power failed, err %d\n",
162 rc);
163 return rc;
164 }
165
166 /* Ok, we have to scale & adjust, taking units into account */
167 scaled = (s32)(val * (u32)slotspow->pow_scale);
168 scaled += (s32)slotspow->pow_offset;
169 *value = scaled << 4;
170
171 return 0;
172}
173
174
175static struct wf_sensor_ops smu_cputemp_ops = {
176 .get_value = smu_cputemp_get,
177 .release = smu_ads_release,
178 .owner = THIS_MODULE,
179};
180static struct wf_sensor_ops smu_cpuamp_ops = {
181 .get_value = smu_cpuamp_get,
182 .release = smu_ads_release,
183 .owner = THIS_MODULE,
184};
185static struct wf_sensor_ops smu_cpuvolt_ops = {
186 .get_value = smu_cpuvolt_get,
187 .release = smu_ads_release,
188 .owner = THIS_MODULE,
189};
190static struct wf_sensor_ops smu_slotspow_ops = {
191 .get_value = smu_slotspow_get,
192 .release = smu_ads_release,
193 .owner = THIS_MODULE,
194};
195
196
197static struct smu_ad_sensor *smu_ads_create(struct device_node *node)
198{
199 struct smu_ad_sensor *ads;
200 char *c, *l;
201 u32 *v;
202
203 ads = kmalloc(sizeof(struct smu_ad_sensor), GFP_KERNEL);
204 if (ads == NULL)
205 return NULL;
206 c = (char *)get_property(node, "device_type", NULL);
207 l = (char *)get_property(node, "location", NULL);
208 if (c == NULL || l == NULL)
209 goto fail;
210
211 /* We currently pick the sensors based on the OF name and location
212 * properties, while Darwin uses the sensor-id's.
213 * The problem with the IDs is that they are model specific while it
214 * looks like apple has been doing a reasonably good job at keeping
215 * the names and locations consistents so I'll stick with the names
216 * and locations for now.
217 */
218 if (!strcmp(c, "temp-sensor") &&
219 !strcmp(l, "CPU T-Diode")) {
220 ads->sens.ops = &smu_cputemp_ops;
221 ads->sens.name = "cpu-temp";
222 } else if (!strcmp(c, "current-sensor") &&
223 !strcmp(l, "CPU Current")) {
224 ads->sens.ops = &smu_cpuamp_ops;
225 ads->sens.name = "cpu-current";
226 } else if (!strcmp(c, "voltage-sensor") &&
227 !strcmp(l, "CPU Voltage")) {
228 ads->sens.ops = &smu_cpuvolt_ops;
229 ads->sens.name = "cpu-voltage";
230 } else if (!strcmp(c, "power-sensor") &&
231 !strcmp(l, "Slots Power")) {
232 ads->sens.ops = &smu_slotspow_ops;
233 ads->sens.name = "slots-power";
234 if (slotspow == NULL) {
235 DBG("wf: slotspow partition (%02x) not found\n",
236 SMU_SDB_SLOTSPOW_ID);
237 goto fail;
238 }
239 } else
240 goto fail;
241
242 v = (u32 *)get_property(node, "reg", NULL);
243 if (v == NULL)
244 goto fail;
245 ads->reg = *v;
246
247 if (wf_register_sensor(&ads->sens))
248 goto fail;
249 return ads;
250 fail:
251 kfree(ads);
252 return NULL;
253}
254
255/*
256 * SMU Power combo sensor object
257 */
258
259struct smu_cpu_power_sensor {
260 struct list_head link;
261 struct wf_sensor *volts;
262 struct wf_sensor *amps;
263 int fake_volts : 1;
264 int quadratic : 1;
265 struct wf_sensor sens;
266};
267#define to_smu_cpu_power(c) container_of(c, struct smu_cpu_power_sensor, sens)
268
269static struct smu_cpu_power_sensor *smu_cpu_power;
270
271static void smu_cpu_power_release(struct wf_sensor *sr)
272{
273 struct smu_cpu_power_sensor *pow = to_smu_cpu_power(sr);
274
275 if (pow->volts)
276 wf_put_sensor(pow->volts);
277 if (pow->amps)
278 wf_put_sensor(pow->amps);
279 kfree(pow);
280}
281
282static int smu_cpu_power_get(struct wf_sensor *sr, s32 *value)
283{
284 struct smu_cpu_power_sensor *pow = to_smu_cpu_power(sr);
285 s32 volts, amps, power;
286 u64 tmps, tmpa, tmpb;
287 int rc;
288
289 rc = pow->amps->ops->get_value(pow->amps, &amps);
290 if (rc)
291 return rc;
292
293 if (pow->fake_volts) {
294 *value = amps * 12 - 0x30000;
295 return 0;
296 }
297
298 rc = pow->volts->ops->get_value(pow->volts, &volts);
299 if (rc)
300 return rc;
301
302 power = (s32)((((u64)volts) * ((u64)amps)) >> 16);
303 if (!pow->quadratic) {
304 *value = power;
305 return 0;
306 }
307 tmps = (((u64)power) * ((u64)power)) >> 16;
308 tmpa = ((u64)cpuvcp->power_quads[0]) * tmps;
309 tmpb = ((u64)cpuvcp->power_quads[1]) * ((u64)power);
310 *value = (tmpa >> 28) + (tmpb >> 28) + (cpuvcp->power_quads[2] >> 12);
311
312 return 0;
313}
314
315static struct wf_sensor_ops smu_cpu_power_ops = {
316 .get_value = smu_cpu_power_get,
317 .release = smu_cpu_power_release,
318 .owner = THIS_MODULE,
319};
320
321
322static struct smu_cpu_power_sensor *
323smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps)
324{
325 struct smu_cpu_power_sensor *pow;
326
327 pow = kmalloc(sizeof(struct smu_cpu_power_sensor), GFP_KERNEL);
328 if (pow == NULL)
329 return NULL;
330 pow->sens.ops = &smu_cpu_power_ops;
331 pow->sens.name = "cpu-power";
332
333 wf_get_sensor(volts);
334 pow->volts = volts;
335 wf_get_sensor(amps);
336 pow->amps = amps;
337
338 /* Some early machines need a faked voltage */
339 if (debugswitches && ((*debugswitches) & 0x80)) {
340 printk(KERN_INFO "windfarm: CPU Power sensor using faked"
341 " voltage !\n");
342 pow->fake_volts = 1;
343 } else
344 pow->fake_volts = 0;
345
346 /* Try to use quadratic transforms on PowerMac8,1 and 9,1 for now,
347 * I yet have to figure out what's up with 8,2 and will have to
348 * adjust for later, unless we can 100% trust the SDB partition...
349 */
350 if ((machine_is_compatible("PowerMac8,1") ||
351 machine_is_compatible("PowerMac8,2") ||
352 machine_is_compatible("PowerMac9,1")) &&
353 cpuvcp_version >= 2) {
354 pow->quadratic = 1;
355 DBG("windfarm: CPU Power using quadratic transform\n");
356 } else
357 pow->quadratic = 0;
358
359 if (wf_register_sensor(&pow->sens))
360 goto fail;
361 return pow;
362 fail:
363 kfree(pow);
364 return NULL;
365}
366
367static int smu_fetch_param_partitions(void)
368{
369 struct smu_sdbp_header *hdr;
370
371 /* Get CPU voltage/current/power calibration data */
372 hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL);
373 if (hdr == NULL) {
374 DBG("wf: cpuvcp partition (%02x) not found\n",
375 SMU_SDB_CPUVCP_ID);
376 return -ENODEV;
377 }
378 cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1];
379 /* Keep version around */
380 cpuvcp_version = hdr->version;
381
382 /* Get CPU diode calibration data */
383 hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL);
384 if (hdr == NULL) {
385 DBG("wf: cpudiode partition (%02x) not found\n",
386 SMU_SDB_CPUDIODE_ID);
387 return -ENODEV;
388 }
389 cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1];
390
391 /* Get slots power calibration data if any */
392 hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL);
393 if (hdr != NULL)
394 slotspow = (struct smu_sdbp_slotspow *)&hdr[1];
395
396 /* Get debug switches if any */
397 hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL);
398 if (hdr != NULL)
399 debugswitches = (u8 *)&hdr[1];
400
401 return 0;
402}
403
404static int __init smu_sensors_init(void)
405{
406 struct device_node *smu, *sensors, *s;
407 struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL;
408 int rc;
409
410 if (!smu_present())
411 return -ENODEV;
412
413 /* Get parameters partitions */
414 rc = smu_fetch_param_partitions();
415 if (rc)
416 return rc;
417
418 smu = of_find_node_by_type(NULL, "smu");
419 if (smu == NULL)
420 return -ENODEV;
421
422 /* Look for sensors subdir */
423 for (sensors = NULL;
424 (sensors = of_get_next_child(smu, sensors)) != NULL;)
425 if (!strcmp(sensors->name, "sensors"))
426 break;
427
428 of_node_put(smu);
429
430 /* Create basic sensors */
431 for (s = NULL;
432 sensors && (s = of_get_next_child(sensors, s)) != NULL;) {
433 struct smu_ad_sensor *ads;
434
435 ads = smu_ads_create(s);
436 if (ads == NULL)
437 continue;
438 list_add(&ads->link, &smu_ads);
439 /* keep track of cpu voltage & current */
440 if (!strcmp(ads->sens.name, "cpu-voltage"))
441 volt_sensor = ads;
442 else if (!strcmp(ads->sens.name, "cpu-current"))
443 curr_sensor = ads;
444 }
445
446 of_node_put(sensors);
447
448 /* Create CPU power sensor if possible */
449 if (volt_sensor && curr_sensor)
450 smu_cpu_power = smu_cpu_power_create(&volt_sensor->sens,
451 &curr_sensor->sens);
452
453 return 0;
454}
455
456static void __exit smu_sensors_exit(void)
457{
458 struct smu_ad_sensor *ads;
459
460 /* dispose of power sensor */
461 if (smu_cpu_power)
462 wf_unregister_sensor(&smu_cpu_power->sens);
463
464 /* dispose of basic sensors */
465 while (!list_empty(&smu_ads)) {
466 ads = list_entry(smu_ads.next, struct smu_ad_sensor, link);
467 list_del(&ads->link);
468 wf_unregister_sensor(&ads->sens);
469 }
470}
471
472
473module_init(smu_sensors_init);
474module_exit(smu_sensors_exit);
475
476MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
477MODULE_DESCRIPTION("SMU sensor objects for PowerMacs thermal control");
478MODULE_LICENSE("GPL");
479
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 01654fcabc52..51315302a85e 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -21,7 +21,6 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/version.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <linux/init.h> 26#include <linux/init.h>
@@ -272,7 +271,8 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde
272 return ERR_PTR(-ENOMEM); 271 return ERR_PTR(-ENOMEM);
273 272
274 ITERATE_RDEV(mddev, rdev, tmp) { 273 ITERATE_RDEV(mddev, rdev, tmp) {
275 if (! rdev->in_sync || rdev->faulty) 274 if (! test_bit(In_sync, &rdev->flags)
275 || test_bit(Faulty, &rdev->flags))
276 continue; 276 continue;
277 277
278 target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512); 278 target = (rdev->sb_offset << 1) + offset + index * (PAGE_SIZE/512);
@@ -292,7 +292,8 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
292 struct list_head *tmp; 292 struct list_head *tmp;
293 293
294 ITERATE_RDEV(mddev, rdev, tmp) 294 ITERATE_RDEV(mddev, rdev, tmp)
295 if (rdev->in_sync && !rdev->faulty) 295 if (test_bit(In_sync, &rdev->flags)
296 && !test_bit(Faulty, &rdev->flags))
296 md_super_write(mddev, rdev, 297 md_super_write(mddev, rdev,
297 (rdev->sb_offset<<1) + offset 298 (rdev->sb_offset<<1) + offset
298 + page->index * (PAGE_SIZE/512), 299 + page->index * (PAGE_SIZE/512),
@@ -300,7 +301,7 @@ static int write_sb_page(mddev_t *mddev, long offset, struct page *page, int wai
300 page); 301 page);
301 302
302 if (wait) 303 if (wait)
303 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 304 md_super_wait(mddev);
304 return 0; 305 return 0;
305} 306}
306 307
@@ -481,7 +482,8 @@ static int bitmap_read_sb(struct bitmap *bitmap)
481 /* verify that the bitmap-specific fields are valid */ 482 /* verify that the bitmap-specific fields are valid */
482 if (sb->magic != cpu_to_le32(BITMAP_MAGIC)) 483 if (sb->magic != cpu_to_le32(BITMAP_MAGIC))
483 reason = "bad magic"; 484 reason = "bad magic";
484 else if (sb->version != cpu_to_le32(BITMAP_MAJOR)) 485 else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
486 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
485 reason = "unrecognized superblock version"; 487 reason = "unrecognized superblock version";
486 else if (chunksize < 512 || chunksize > (1024 * 1024 * 4)) 488 else if (chunksize < 512 || chunksize > (1024 * 1024 * 4))
487 reason = "bitmap chunksize out of range (512B - 4MB)"; 489 reason = "bitmap chunksize out of range (512B - 4MB)";
@@ -526,6 +528,8 @@ success:
526 bitmap->daemon_lastrun = jiffies; 528 bitmap->daemon_lastrun = jiffies;
527 bitmap->max_write_behind = write_behind; 529 bitmap->max_write_behind = write_behind;
528 bitmap->flags |= sb->state; 530 bitmap->flags |= sb->state;
531 if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
532 bitmap->flags |= BITMAP_HOSTENDIAN;
529 bitmap->events_cleared = le64_to_cpu(sb->events_cleared); 533 bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
530 if (sb->state & BITMAP_STALE) 534 if (sb->state & BITMAP_STALE)
531 bitmap->events_cleared = bitmap->mddev->events; 535 bitmap->events_cleared = bitmap->mddev->events;
@@ -763,7 +767,10 @@ static void bitmap_file_set_bit(struct bitmap *bitmap, sector_t block)
763 767
764 /* set the bit */ 768 /* set the bit */
765 kaddr = kmap_atomic(page, KM_USER0); 769 kaddr = kmap_atomic(page, KM_USER0);
766 set_bit(bit, kaddr); 770 if (bitmap->flags & BITMAP_HOSTENDIAN)
771 set_bit(bit, kaddr);
772 else
773 ext2_set_bit(bit, kaddr);
767 kunmap_atomic(kaddr, KM_USER0); 774 kunmap_atomic(kaddr, KM_USER0);
768 PRINTK("set file bit %lu page %lu\n", bit, page->index); 775 PRINTK("set file bit %lu page %lu\n", bit, page->index);
769 776
@@ -821,8 +828,7 @@ int bitmap_unplug(struct bitmap *bitmap)
821 wake_up_process(bitmap->writeback_daemon->tsk)); 828 wake_up_process(bitmap->writeback_daemon->tsk));
822 spin_unlock_irq(&bitmap->write_lock); 829 spin_unlock_irq(&bitmap->write_lock);
823 } else 830 } else
824 wait_event(bitmap->mddev->sb_wait, 831 md_super_wait(bitmap->mddev);
825 atomic_read(&bitmap->mddev->pending_writes)==0);
826 } 832 }
827 return 0; 833 return 0;
828} 834}
@@ -890,6 +896,7 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
890 oldindex = ~0L; 896 oldindex = ~0L;
891 897
892 for (i = 0; i < chunks; i++) { 898 for (i = 0; i < chunks; i++) {
899 int b;
893 index = file_page_index(i); 900 index = file_page_index(i);
894 bit = file_page_offset(i); 901 bit = file_page_offset(i);
895 if (index != oldindex) { /* this is a new page, read it in */ 902 if (index != oldindex) { /* this is a new page, read it in */
@@ -938,7 +945,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start)
938 945
939 bitmap->filemap[bitmap->file_pages++] = page; 946 bitmap->filemap[bitmap->file_pages++] = page;
940 } 947 }
941 if (test_bit(bit, page_address(page))) { 948 if (bitmap->flags & BITMAP_HOSTENDIAN)
949 b = test_bit(bit, page_address(page));
950 else
951 b = ext2_test_bit(bit, page_address(page));
952 if (b) {
942 /* if the disk bit is set, set the memory bit */ 953 /* if the disk bit is set, set the memory bit */
943 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap), 954 bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
944 ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start) 955 ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start)
@@ -1096,7 +1107,10 @@ int bitmap_daemon_work(struct bitmap *bitmap)
1096 -1); 1107 -1);
1097 1108
1098 /* clear the bit */ 1109 /* clear the bit */
1099 clear_bit(file_page_offset(j), page_address(page)); 1110 if (bitmap->flags & BITMAP_HOSTENDIAN)
1111 clear_bit(file_page_offset(j), page_address(page));
1112 else
1113 ext2_clear_bit(file_page_offset(j), page_address(page));
1100 } 1114 }
1101 } 1115 }
1102 spin_unlock_irqrestore(&bitmap->lock, flags); 1116 spin_unlock_irqrestore(&bitmap->lock, flags);
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9ecf51ee596f..adf960d8a7c9 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -131,6 +131,8 @@ static ctl_table raid_root_table[] = {
131 131
132static struct block_device_operations md_fops; 132static struct block_device_operations md_fops;
133 133
134static int start_readonly;
135
134/* 136/*
135 * Enables to iterate over all existing md arrays 137 * Enables to iterate over all existing md arrays
136 * all_mddevs_lock protects this list. 138 * all_mddevs_lock protects this list.
@@ -181,7 +183,7 @@ static void mddev_put(mddev_t *mddev)
181 if (!mddev->raid_disks && list_empty(&mddev->disks)) { 183 if (!mddev->raid_disks && list_empty(&mddev->disks)) {
182 list_del(&mddev->all_mddevs); 184 list_del(&mddev->all_mddevs);
183 blk_put_queue(mddev->queue); 185 blk_put_queue(mddev->queue);
184 kfree(mddev); 186 kobject_unregister(&mddev->kobj);
185 } 187 }
186 spin_unlock(&all_mddevs_lock); 188 spin_unlock(&all_mddevs_lock);
187} 189}
@@ -330,18 +332,46 @@ static void free_disk_sb(mdk_rdev_t * rdev)
330static int super_written(struct bio *bio, unsigned int bytes_done, int error) 332static int super_written(struct bio *bio, unsigned int bytes_done, int error)
331{ 333{
332 mdk_rdev_t *rdev = bio->bi_private; 334 mdk_rdev_t *rdev = bio->bi_private;
335 mddev_t *mddev = rdev->mddev;
333 if (bio->bi_size) 336 if (bio->bi_size)
334 return 1; 337 return 1;
335 338
336 if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) 339 if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
337 md_error(rdev->mddev, rdev); 340 md_error(mddev, rdev);
338 341
339 if (atomic_dec_and_test(&rdev->mddev->pending_writes)) 342 if (atomic_dec_and_test(&mddev->pending_writes))
340 wake_up(&rdev->mddev->sb_wait); 343 wake_up(&mddev->sb_wait);
341 bio_put(bio); 344 bio_put(bio);
342 return 0; 345 return 0;
343} 346}
344 347
348static int super_written_barrier(struct bio *bio, unsigned int bytes_done, int error)
349{
350 struct bio *bio2 = bio->bi_private;
351 mdk_rdev_t *rdev = bio2->bi_private;
352 mddev_t *mddev = rdev->mddev;
353 if (bio->bi_size)
354 return 1;
355
356 if (!test_bit(BIO_UPTODATE, &bio->bi_flags) &&
357 error == -EOPNOTSUPP) {
358 unsigned long flags;
359 /* barriers don't appear to be supported :-( */
360 set_bit(BarriersNotsupp, &rdev->flags);
361 mddev->barriers_work = 0;
362 spin_lock_irqsave(&mddev->write_lock, flags);
363 bio2->bi_next = mddev->biolist;
364 mddev->biolist = bio2;
365 spin_unlock_irqrestore(&mddev->write_lock, flags);
366 wake_up(&mddev->sb_wait);
367 bio_put(bio);
368 return 0;
369 }
370 bio_put(bio2);
371 bio->bi_private = rdev;
372 return super_written(bio, bytes_done, error);
373}
374
345void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, 375void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
346 sector_t sector, int size, struct page *page) 376 sector_t sector, int size, struct page *page)
347{ 377{
@@ -350,16 +380,54 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
350 * and decrement it on completion, waking up sb_wait 380 * and decrement it on completion, waking up sb_wait
351 * if zero is reached. 381 * if zero is reached.
352 * If an error occurred, call md_error 382 * If an error occurred, call md_error
383 *
384 * As we might need to resubmit the request if BIO_RW_BARRIER
385 * causes ENOTSUPP, we allocate a spare bio...
353 */ 386 */
354 struct bio *bio = bio_alloc(GFP_NOIO, 1); 387 struct bio *bio = bio_alloc(GFP_NOIO, 1);
388 int rw = (1<<BIO_RW) | (1<<BIO_RW_SYNC);
355 389
356 bio->bi_bdev = rdev->bdev; 390 bio->bi_bdev = rdev->bdev;
357 bio->bi_sector = sector; 391 bio->bi_sector = sector;
358 bio_add_page(bio, page, size, 0); 392 bio_add_page(bio, page, size, 0);
359 bio->bi_private = rdev; 393 bio->bi_private = rdev;
360 bio->bi_end_io = super_written; 394 bio->bi_end_io = super_written;
395 bio->bi_rw = rw;
396
361 atomic_inc(&mddev->pending_writes); 397 atomic_inc(&mddev->pending_writes);
362 submit_bio((1<<BIO_RW)|(1<<BIO_RW_SYNC), bio); 398 if (!test_bit(BarriersNotsupp, &rdev->flags)) {
399 struct bio *rbio;
400 rw |= (1<<BIO_RW_BARRIER);
401 rbio = bio_clone(bio, GFP_NOIO);
402 rbio->bi_private = bio;
403 rbio->bi_end_io = super_written_barrier;
404 submit_bio(rw, rbio);
405 } else
406 submit_bio(rw, bio);
407}
408
409void md_super_wait(mddev_t *mddev)
410{
411 /* wait for all superblock writes that were scheduled to complete.
412 * if any had to be retried (due to BARRIER problems), retry them
413 */
414 DEFINE_WAIT(wq);
415 for(;;) {
416 prepare_to_wait(&mddev->sb_wait, &wq, TASK_UNINTERRUPTIBLE);
417 if (atomic_read(&mddev->pending_writes)==0)
418 break;
419 while (mddev->biolist) {
420 struct bio *bio;
421 spin_lock_irq(&mddev->write_lock);
422 bio = mddev->biolist;
423 mddev->biolist = bio->bi_next ;
424 bio->bi_next = NULL;
425 spin_unlock_irq(&mddev->write_lock);
426 submit_bio(bio->bi_rw, bio);
427 }
428 schedule();
429 }
430 finish_wait(&mddev->sb_wait, &wq);
363} 431}
364 432
365static int bi_complete(struct bio *bio, unsigned int bytes_done, int error) 433static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
@@ -610,7 +678,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
610 mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page); 678 mdp_super_t *sb = (mdp_super_t *)page_address(rdev->sb_page);
611 679
612 rdev->raid_disk = -1; 680 rdev->raid_disk = -1;
613 rdev->in_sync = 0; 681 rdev->flags = 0;
614 if (mddev->raid_disks == 0) { 682 if (mddev->raid_disks == 0) {
615 mddev->major_version = 0; 683 mddev->major_version = 0;
616 mddev->minor_version = sb->minor_version; 684 mddev->minor_version = sb->minor_version;
@@ -671,21 +739,19 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
671 return 0; 739 return 0;
672 740
673 if (mddev->level != LEVEL_MULTIPATH) { 741 if (mddev->level != LEVEL_MULTIPATH) {
674 rdev->faulty = 0;
675 rdev->flags = 0;
676 desc = sb->disks + rdev->desc_nr; 742 desc = sb->disks + rdev->desc_nr;
677 743
678 if (desc->state & (1<<MD_DISK_FAULTY)) 744 if (desc->state & (1<<MD_DISK_FAULTY))
679 rdev->faulty = 1; 745 set_bit(Faulty, &rdev->flags);
680 else if (desc->state & (1<<MD_DISK_SYNC) && 746 else if (desc->state & (1<<MD_DISK_SYNC) &&
681 desc->raid_disk < mddev->raid_disks) { 747 desc->raid_disk < mddev->raid_disks) {
682 rdev->in_sync = 1; 748 set_bit(In_sync, &rdev->flags);
683 rdev->raid_disk = desc->raid_disk; 749 rdev->raid_disk = desc->raid_disk;
684 } 750 }
685 if (desc->state & (1<<MD_DISK_WRITEMOSTLY)) 751 if (desc->state & (1<<MD_DISK_WRITEMOSTLY))
686 set_bit(WriteMostly, &rdev->flags); 752 set_bit(WriteMostly, &rdev->flags);
687 } else /* MULTIPATH are always insync */ 753 } else /* MULTIPATH are always insync */
688 rdev->in_sync = 1; 754 set_bit(In_sync, &rdev->flags);
689 return 0; 755 return 0;
690} 756}
691 757
@@ -699,6 +765,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
699 mdk_rdev_t *rdev2; 765 mdk_rdev_t *rdev2;
700 int next_spare = mddev->raid_disks; 766 int next_spare = mddev->raid_disks;
701 767
768
702 /* make rdev->sb match mddev data.. 769 /* make rdev->sb match mddev data..
703 * 770 *
704 * 1/ zero out disks 771 * 1/ zero out disks
@@ -758,23 +825,27 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
758 sb->disks[0].state = (1<<MD_DISK_REMOVED); 825 sb->disks[0].state = (1<<MD_DISK_REMOVED);
759 ITERATE_RDEV(mddev,rdev2,tmp) { 826 ITERATE_RDEV(mddev,rdev2,tmp) {
760 mdp_disk_t *d; 827 mdp_disk_t *d;
761 if (rdev2->raid_disk >= 0 && rdev2->in_sync && !rdev2->faulty) 828 int desc_nr;
762 rdev2->desc_nr = rdev2->raid_disk; 829 if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
830 && !test_bit(Faulty, &rdev2->flags))
831 desc_nr = rdev2->raid_disk;
763 else 832 else
764 rdev2->desc_nr = next_spare++; 833 desc_nr = next_spare++;
834 rdev2->desc_nr = desc_nr;
765 d = &sb->disks[rdev2->desc_nr]; 835 d = &sb->disks[rdev2->desc_nr];
766 nr_disks++; 836 nr_disks++;
767 d->number = rdev2->desc_nr; 837 d->number = rdev2->desc_nr;
768 d->major = MAJOR(rdev2->bdev->bd_dev); 838 d->major = MAJOR(rdev2->bdev->bd_dev);
769 d->minor = MINOR(rdev2->bdev->bd_dev); 839 d->minor = MINOR(rdev2->bdev->bd_dev);
770 if (rdev2->raid_disk >= 0 && rdev->in_sync && !rdev2->faulty) 840 if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
841 && !test_bit(Faulty, &rdev2->flags))
771 d->raid_disk = rdev2->raid_disk; 842 d->raid_disk = rdev2->raid_disk;
772 else 843 else
773 d->raid_disk = rdev2->desc_nr; /* compatibility */ 844 d->raid_disk = rdev2->desc_nr; /* compatibility */
774 if (rdev2->faulty) { 845 if (test_bit(Faulty, &rdev2->flags)) {
775 d->state = (1<<MD_DISK_FAULTY); 846 d->state = (1<<MD_DISK_FAULTY);
776 failed++; 847 failed++;
777 } else if (rdev2->in_sync) { 848 } else if (test_bit(In_sync, &rdev2->flags)) {
778 d->state = (1<<MD_DISK_ACTIVE); 849 d->state = (1<<MD_DISK_ACTIVE);
779 d->state |= (1<<MD_DISK_SYNC); 850 d->state |= (1<<MD_DISK_SYNC);
780 active++; 851 active++;
@@ -787,7 +858,6 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
787 if (test_bit(WriteMostly, &rdev2->flags)) 858 if (test_bit(WriteMostly, &rdev2->flags))
788 d->state |= (1<<MD_DISK_WRITEMOSTLY); 859 d->state |= (1<<MD_DISK_WRITEMOSTLY);
789 } 860 }
790
791 /* now set the "removed" and "faulty" bits on any missing devices */ 861 /* now set the "removed" and "faulty" bits on any missing devices */
792 for (i=0 ; i < mddev->raid_disks ; i++) { 862 for (i=0 ; i < mddev->raid_disks ; i++) {
793 mdp_disk_t *d = &sb->disks[i]; 863 mdp_disk_t *d = &sb->disks[i];
@@ -944,7 +1014,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
944 struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page); 1014 struct mdp_superblock_1 *sb = (struct mdp_superblock_1*)page_address(rdev->sb_page);
945 1015
946 rdev->raid_disk = -1; 1016 rdev->raid_disk = -1;
947 rdev->in_sync = 0; 1017 rdev->flags = 0;
948 if (mddev->raid_disks == 0) { 1018 if (mddev->raid_disks == 0) {
949 mddev->major_version = 1; 1019 mddev->major_version = 1;
950 mddev->patch_version = 0; 1020 mddev->patch_version = 0;
@@ -996,22 +1066,19 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
996 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); 1066 role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);
997 switch(role) { 1067 switch(role) {
998 case 0xffff: /* spare */ 1068 case 0xffff: /* spare */
999 rdev->faulty = 0;
1000 break; 1069 break;
1001 case 0xfffe: /* faulty */ 1070 case 0xfffe: /* faulty */
1002 rdev->faulty = 1; 1071 set_bit(Faulty, &rdev->flags);
1003 break; 1072 break;
1004 default: 1073 default:
1005 rdev->in_sync = 1; 1074 set_bit(In_sync, &rdev->flags);
1006 rdev->faulty = 0;
1007 rdev->raid_disk = role; 1075 rdev->raid_disk = role;
1008 break; 1076 break;
1009 } 1077 }
1010 rdev->flags = 0;
1011 if (sb->devflags & WriteMostly1) 1078 if (sb->devflags & WriteMostly1)
1012 set_bit(WriteMostly, &rdev->flags); 1079 set_bit(WriteMostly, &rdev->flags);
1013 } else /* MULTIPATH are always insync */ 1080 } else /* MULTIPATH are always insync */
1014 rdev->in_sync = 1; 1081 set_bit(In_sync, &rdev->flags);
1015 1082
1016 return 0; 1083 return 0;
1017} 1084}
@@ -1055,9 +1122,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
1055 1122
1056 ITERATE_RDEV(mddev,rdev2,tmp) { 1123 ITERATE_RDEV(mddev,rdev2,tmp) {
1057 i = rdev2->desc_nr; 1124 i = rdev2->desc_nr;
1058 if (rdev2->faulty) 1125 if (test_bit(Faulty, &rdev2->flags))
1059 sb->dev_roles[i] = cpu_to_le16(0xfffe); 1126 sb->dev_roles[i] = cpu_to_le16(0xfffe);
1060 else if (rdev2->in_sync) 1127 else if (test_bit(In_sync, &rdev2->flags))
1061 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk); 1128 sb->dev_roles[i] = cpu_to_le16(rdev2->raid_disk);
1062 else 1129 else
1063 sb->dev_roles[i] = cpu_to_le16(0xffff); 1130 sb->dev_roles[i] = cpu_to_le16(0xffff);
@@ -1115,6 +1182,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1115{ 1182{
1116 mdk_rdev_t *same_pdev; 1183 mdk_rdev_t *same_pdev;
1117 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; 1184 char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
1185 struct kobject *ko;
1118 1186
1119 if (rdev->mddev) { 1187 if (rdev->mddev) {
1120 MD_BUG(); 1188 MD_BUG();
@@ -1143,10 +1211,22 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1143 if (find_rdev_nr(mddev, rdev->desc_nr)) 1211 if (find_rdev_nr(mddev, rdev->desc_nr))
1144 return -EBUSY; 1212 return -EBUSY;
1145 } 1213 }
1214 bdevname(rdev->bdev,b);
1215 if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0)
1216 return -ENOMEM;
1146 1217
1147 list_add(&rdev->same_set, &mddev->disks); 1218 list_add(&rdev->same_set, &mddev->disks);
1148 rdev->mddev = mddev; 1219 rdev->mddev = mddev;
1149 printk(KERN_INFO "md: bind<%s>\n", bdevname(rdev->bdev,b)); 1220 printk(KERN_INFO "md: bind<%s>\n", b);
1221
1222 rdev->kobj.parent = &mddev->kobj;
1223 kobject_add(&rdev->kobj);
1224
1225 if (rdev->bdev->bd_part)
1226 ko = &rdev->bdev->bd_part->kobj;
1227 else
1228 ko = &rdev->bdev->bd_disk->kobj;
1229 sysfs_create_link(&rdev->kobj, ko, "block");
1150 return 0; 1230 return 0;
1151} 1231}
1152 1232
@@ -1160,6 +1240,8 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev)
1160 list_del_init(&rdev->same_set); 1240 list_del_init(&rdev->same_set);
1161 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); 1241 printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
1162 rdev->mddev = NULL; 1242 rdev->mddev = NULL;
1243 sysfs_remove_link(&rdev->kobj, "block");
1244 kobject_del(&rdev->kobj);
1163} 1245}
1164 1246
1165/* 1247/*
@@ -1215,7 +1297,7 @@ static void export_rdev(mdk_rdev_t * rdev)
1215 md_autodetect_dev(rdev->bdev->bd_dev); 1297 md_autodetect_dev(rdev->bdev->bd_dev);
1216#endif 1298#endif
1217 unlock_rdev(rdev); 1299 unlock_rdev(rdev);
1218 kfree(rdev); 1300 kobject_put(&rdev->kobj);
1219} 1301}
1220 1302
1221static void kick_rdev_from_array(mdk_rdev_t * rdev) 1303static void kick_rdev_from_array(mdk_rdev_t * rdev)
@@ -1287,7 +1369,8 @@ static void print_rdev(mdk_rdev_t *rdev)
1287 char b[BDEVNAME_SIZE]; 1369 char b[BDEVNAME_SIZE];
1288 printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n", 1370 printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
1289 bdevname(rdev->bdev,b), (unsigned long long)rdev->size, 1371 bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
1290 rdev->faulty, rdev->in_sync, rdev->desc_nr); 1372 test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
1373 rdev->desc_nr);
1291 if (rdev->sb_loaded) { 1374 if (rdev->sb_loaded) {
1292 printk(KERN_INFO "md: rdev superblock:\n"); 1375 printk(KERN_INFO "md: rdev superblock:\n");
1293 print_sb((mdp_super_t*)page_address(rdev->sb_page)); 1376 print_sb((mdp_super_t*)page_address(rdev->sb_page));
@@ -1344,7 +1427,7 @@ static void md_update_sb(mddev_t * mddev)
1344 int sync_req; 1427 int sync_req;
1345 1428
1346repeat: 1429repeat:
1347 spin_lock(&mddev->write_lock); 1430 spin_lock_irq(&mddev->write_lock);
1348 sync_req = mddev->in_sync; 1431 sync_req = mddev->in_sync;
1349 mddev->utime = get_seconds(); 1432 mddev->utime = get_seconds();
1350 mddev->events ++; 1433 mddev->events ++;
@@ -1367,11 +1450,11 @@ repeat:
1367 */ 1450 */
1368 if (!mddev->persistent) { 1451 if (!mddev->persistent) {
1369 mddev->sb_dirty = 0; 1452 mddev->sb_dirty = 0;
1370 spin_unlock(&mddev->write_lock); 1453 spin_unlock_irq(&mddev->write_lock);
1371 wake_up(&mddev->sb_wait); 1454 wake_up(&mddev->sb_wait);
1372 return; 1455 return;
1373 } 1456 }
1374 spin_unlock(&mddev->write_lock); 1457 spin_unlock_irq(&mddev->write_lock);
1375 1458
1376 dprintk(KERN_INFO 1459 dprintk(KERN_INFO
1377 "md: updating %s RAID superblock on device (in sync %d)\n", 1460 "md: updating %s RAID superblock on device (in sync %d)\n",
@@ -1381,11 +1464,11 @@ repeat:
1381 ITERATE_RDEV(mddev,rdev,tmp) { 1464 ITERATE_RDEV(mddev,rdev,tmp) {
1382 char b[BDEVNAME_SIZE]; 1465 char b[BDEVNAME_SIZE];
1383 dprintk(KERN_INFO "md: "); 1466 dprintk(KERN_INFO "md: ");
1384 if (rdev->faulty) 1467 if (test_bit(Faulty, &rdev->flags))
1385 dprintk("(skipping faulty "); 1468 dprintk("(skipping faulty ");
1386 1469
1387 dprintk("%s ", bdevname(rdev->bdev,b)); 1470 dprintk("%s ", bdevname(rdev->bdev,b));
1388 if (!rdev->faulty) { 1471 if (!test_bit(Faulty, &rdev->flags)) {
1389 md_super_write(mddev,rdev, 1472 md_super_write(mddev,rdev,
1390 rdev->sb_offset<<1, rdev->sb_size, 1473 rdev->sb_offset<<1, rdev->sb_size,
1391 rdev->sb_page); 1474 rdev->sb_page);
@@ -1399,21 +1482,106 @@ repeat:
1399 /* only need to write one superblock... */ 1482 /* only need to write one superblock... */
1400 break; 1483 break;
1401 } 1484 }
1402 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 1485 md_super_wait(mddev);
1403 /* if there was a failure, sb_dirty was set to 1, and we re-write super */ 1486 /* if there was a failure, sb_dirty was set to 1, and we re-write super */
1404 1487
1405 spin_lock(&mddev->write_lock); 1488 spin_lock_irq(&mddev->write_lock);
1406 if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) { 1489 if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
1407 /* have to write it out again */ 1490 /* have to write it out again */
1408 spin_unlock(&mddev->write_lock); 1491 spin_unlock_irq(&mddev->write_lock);
1409 goto repeat; 1492 goto repeat;
1410 } 1493 }
1411 mddev->sb_dirty = 0; 1494 mddev->sb_dirty = 0;
1412 spin_unlock(&mddev->write_lock); 1495 spin_unlock_irq(&mddev->write_lock);
1413 wake_up(&mddev->sb_wait); 1496 wake_up(&mddev->sb_wait);
1414 1497
1415} 1498}
1416 1499
1500struct rdev_sysfs_entry {
1501 struct attribute attr;
1502 ssize_t (*show)(mdk_rdev_t *, char *);
1503 ssize_t (*store)(mdk_rdev_t *, const char *, size_t);
1504};
1505
1506static ssize_t
1507state_show(mdk_rdev_t *rdev, char *page)
1508{
1509 char *sep = "";
1510 int len=0;
1511
1512 if (test_bit(Faulty, &rdev->flags)) {
1513 len+= sprintf(page+len, "%sfaulty",sep);
1514 sep = ",";
1515 }
1516 if (test_bit(In_sync, &rdev->flags)) {
1517 len += sprintf(page+len, "%sin_sync",sep);
1518 sep = ",";
1519 }
1520 if (!test_bit(Faulty, &rdev->flags) &&
1521 !test_bit(In_sync, &rdev->flags)) {
1522 len += sprintf(page+len, "%sspare", sep);
1523 sep = ",";
1524 }
1525 return len+sprintf(page+len, "\n");
1526}
1527
1528static struct rdev_sysfs_entry
1529rdev_state = __ATTR_RO(state);
1530
1531static ssize_t
1532super_show(mdk_rdev_t *rdev, char *page)
1533{
1534 if (rdev->sb_loaded && rdev->sb_size) {
1535 memcpy(page, page_address(rdev->sb_page), rdev->sb_size);
1536 return rdev->sb_size;
1537 } else
1538 return 0;
1539}
1540static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super);
1541
1542static struct attribute *rdev_default_attrs[] = {
1543 &rdev_state.attr,
1544 &rdev_super.attr,
1545 NULL,
1546};
1547static ssize_t
1548rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
1549{
1550 struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
1551 mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
1552
1553 if (!entry->show)
1554 return -EIO;
1555 return entry->show(rdev, page);
1556}
1557
1558static ssize_t
1559rdev_attr_store(struct kobject *kobj, struct attribute *attr,
1560 const char *page, size_t length)
1561{
1562 struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
1563 mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
1564
1565 if (!entry->store)
1566 return -EIO;
1567 return entry->store(rdev, page, length);
1568}
1569
1570static void rdev_free(struct kobject *ko)
1571{
1572 mdk_rdev_t *rdev = container_of(ko, mdk_rdev_t, kobj);
1573 kfree(rdev);
1574}
1575static struct sysfs_ops rdev_sysfs_ops = {
1576 .show = rdev_attr_show,
1577 .store = rdev_attr_store,
1578};
1579static struct kobj_type rdev_ktype = {
1580 .release = rdev_free,
1581 .sysfs_ops = &rdev_sysfs_ops,
1582 .default_attrs = rdev_default_attrs,
1583};
1584
1417/* 1585/*
1418 * Import a device. If 'super_format' >= 0, then sanity check the superblock 1586 * Import a device. If 'super_format' >= 0, then sanity check the superblock
1419 * 1587 *
@@ -1445,11 +1613,15 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
1445 if (err) 1613 if (err)
1446 goto abort_free; 1614 goto abort_free;
1447 1615
1616 rdev->kobj.parent = NULL;
1617 rdev->kobj.ktype = &rdev_ktype;
1618 kobject_init(&rdev->kobj);
1619
1448 rdev->desc_nr = -1; 1620 rdev->desc_nr = -1;
1449 rdev->faulty = 0; 1621 rdev->flags = 0;
1450 rdev->in_sync = 0;
1451 rdev->data_offset = 0; 1622 rdev->data_offset = 0;
1452 atomic_set(&rdev->nr_pending, 0); 1623 atomic_set(&rdev->nr_pending, 0);
1624 atomic_set(&rdev->read_errors, 0);
1453 1625
1454 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS; 1626 size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
1455 if (!size) { 1627 if (!size) {
@@ -1537,7 +1709,7 @@ static void analyze_sbs(mddev_t * mddev)
1537 if (mddev->level == LEVEL_MULTIPATH) { 1709 if (mddev->level == LEVEL_MULTIPATH) {
1538 rdev->desc_nr = i++; 1710 rdev->desc_nr = i++;
1539 rdev->raid_disk = rdev->desc_nr; 1711 rdev->raid_disk = rdev->desc_nr;
1540 rdev->in_sync = 1; 1712 set_bit(In_sync, &rdev->flags);
1541 } 1713 }
1542 } 1714 }
1543 1715
@@ -1551,6 +1723,162 @@ static void analyze_sbs(mddev_t * mddev)
1551 1723
1552} 1724}
1553 1725
1726static ssize_t
1727level_show(mddev_t *mddev, char *page)
1728{
1729 mdk_personality_t *p = mddev->pers;
1730 if (p == NULL && mddev->raid_disks == 0)
1731 return 0;
1732 if (mddev->level >= 0)
1733 return sprintf(page, "RAID-%d\n", mddev->level);
1734 else
1735 return sprintf(page, "%s\n", p->name);
1736}
1737
1738static struct md_sysfs_entry md_level = __ATTR_RO(level);
1739
1740static ssize_t
1741raid_disks_show(mddev_t *mddev, char *page)
1742{
1743 if (mddev->raid_disks == 0)
1744 return 0;
1745 return sprintf(page, "%d\n", mddev->raid_disks);
1746}
1747
1748static struct md_sysfs_entry md_raid_disks = __ATTR_RO(raid_disks);
1749
1750static ssize_t
1751action_show(mddev_t *mddev, char *page)
1752{
1753 char *type = "idle";
1754 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
1755 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) {
1756 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
1757 if (!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1758 type = "resync";
1759 else if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
1760 type = "check";
1761 else
1762 type = "repair";
1763 } else
1764 type = "recover";
1765 }
1766 return sprintf(page, "%s\n", type);
1767}
1768
1769static ssize_t
1770action_store(mddev_t *mddev, const char *page, size_t len)
1771{
1772 if (!mddev->pers || !mddev->pers->sync_request)
1773 return -EINVAL;
1774
1775 if (strcmp(page, "idle")==0 || strcmp(page, "idle\n")==0) {
1776 if (mddev->sync_thread) {
1777 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
1778 md_unregister_thread(mddev->sync_thread);
1779 mddev->sync_thread = NULL;
1780 mddev->recovery = 0;
1781 }
1782 return len;
1783 }
1784
1785 if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
1786 test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
1787 return -EBUSY;
1788 if (strcmp(page, "resync")==0 || strcmp(page, "resync\n")==0 ||
1789 strcmp(page, "recover")==0 || strcmp(page, "recover\n")==0)
1790 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1791 else {
1792 if (strcmp(page, "check")==0 || strcmp(page, "check\n")==0)
1793 set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
1794 else if (strcmp(page, "repair")!=0 && strcmp(page, "repair\n")!=0)
1795 return -EINVAL;
1796 set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
1797 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
1798 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1799 }
1800 md_wakeup_thread(mddev->thread);
1801 return len;
1802}
1803
1804static ssize_t
1805mismatch_cnt_show(mddev_t *mddev, char *page)
1806{
1807 return sprintf(page, "%llu\n",
1808 (unsigned long long) mddev->resync_mismatches);
1809}
1810
1811static struct md_sysfs_entry
1812md_scan_mode = __ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
1813
1814
1815static struct md_sysfs_entry
1816md_mismatches = __ATTR_RO(mismatch_cnt);
1817
1818static struct attribute *md_default_attrs[] = {
1819 &md_level.attr,
1820 &md_raid_disks.attr,
1821 NULL,
1822};
1823
1824static struct attribute *md_redundancy_attrs[] = {
1825 &md_scan_mode.attr,
1826 &md_mismatches.attr,
1827 NULL,
1828};
1829static struct attribute_group md_redundancy_group = {
1830 .name = NULL,
1831 .attrs = md_redundancy_attrs,
1832};
1833
1834
1835static ssize_t
1836md_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
1837{
1838 struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
1839 mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
1840 ssize_t rv;
1841
1842 if (!entry->show)
1843 return -EIO;
1844 mddev_lock(mddev);
1845 rv = entry->show(mddev, page);
1846 mddev_unlock(mddev);
1847 return rv;
1848}
1849
1850static ssize_t
1851md_attr_store(struct kobject *kobj, struct attribute *attr,
1852 const char *page, size_t length)
1853{
1854 struct md_sysfs_entry *entry = container_of(attr, struct md_sysfs_entry, attr);
1855 mddev_t *mddev = container_of(kobj, struct mddev_s, kobj);
1856 ssize_t rv;
1857
1858 if (!entry->store)
1859 return -EIO;
1860 mddev_lock(mddev);
1861 rv = entry->store(mddev, page, length);
1862 mddev_unlock(mddev);
1863 return rv;
1864}
1865
1866static void md_free(struct kobject *ko)
1867{
1868 mddev_t *mddev = container_of(ko, mddev_t, kobj);
1869 kfree(mddev);
1870}
1871
1872static struct sysfs_ops md_sysfs_ops = {
1873 .show = md_attr_show,
1874 .store = md_attr_store,
1875};
1876static struct kobj_type md_ktype = {
1877 .release = md_free,
1878 .sysfs_ops = &md_sysfs_ops,
1879 .default_attrs = md_default_attrs,
1880};
1881
1554int mdp_major = 0; 1882int mdp_major = 0;
1555 1883
1556static struct kobject *md_probe(dev_t dev, int *part, void *data) 1884static struct kobject *md_probe(dev_t dev, int *part, void *data)
@@ -1592,6 +1920,11 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
1592 add_disk(disk); 1920 add_disk(disk);
1593 mddev->gendisk = disk; 1921 mddev->gendisk = disk;
1594 up(&disks_sem); 1922 up(&disks_sem);
1923 mddev->kobj.parent = &disk->kobj;
1924 mddev->kobj.k_name = NULL;
1925 snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
1926 mddev->kobj.ktype = &md_ktype;
1927 kobject_register(&mddev->kobj);
1595 return NULL; 1928 return NULL;
1596} 1929}
1597 1930
@@ -1663,7 +1996,7 @@ static int do_md_run(mddev_t * mddev)
1663 1996
1664 /* devices must have minimum size of one chunk */ 1997 /* devices must have minimum size of one chunk */
1665 ITERATE_RDEV(mddev,rdev,tmp) { 1998 ITERATE_RDEV(mddev,rdev,tmp) {
1666 if (rdev->faulty) 1999 if (test_bit(Faulty, &rdev->flags))
1667 continue; 2000 continue;
1668 if (rdev->size < chunk_size / 1024) { 2001 if (rdev->size < chunk_size / 1024) {
1669 printk(KERN_WARNING 2002 printk(KERN_WARNING
@@ -1691,7 +2024,7 @@ static int do_md_run(mddev_t * mddev)
1691 * Also find largest hardsector size 2024 * Also find largest hardsector size
1692 */ 2025 */
1693 ITERATE_RDEV(mddev,rdev,tmp) { 2026 ITERATE_RDEV(mddev,rdev,tmp) {
1694 if (rdev->faulty) 2027 if (test_bit(Faulty, &rdev->flags))
1695 continue; 2028 continue;
1696 sync_blockdev(rdev->bdev); 2029 sync_blockdev(rdev->bdev);
1697 invalidate_bdev(rdev->bdev, 0); 2030 invalidate_bdev(rdev->bdev, 0);
@@ -1715,6 +2048,10 @@ static int do_md_run(mddev_t * mddev)
1715 2048
1716 mddev->recovery = 0; 2049 mddev->recovery = 0;
1717 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ 2050 mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
2051 mddev->barriers_work = 1;
2052
2053 if (start_readonly)
2054 mddev->ro = 2; /* read-only, but switch on first write */
1718 2055
1719 /* before we start the array running, initialise the bitmap */ 2056 /* before we start the array running, initialise the bitmap */
1720 err = bitmap_create(mddev); 2057 err = bitmap_create(mddev);
@@ -1730,12 +2067,24 @@ static int do_md_run(mddev_t * mddev)
1730 bitmap_destroy(mddev); 2067 bitmap_destroy(mddev);
1731 return err; 2068 return err;
1732 } 2069 }
2070 if (mddev->pers->sync_request)
2071 sysfs_create_group(&mddev->kobj, &md_redundancy_group);
2072 else if (mddev->ro == 2) /* auto-readonly not meaningful */
2073 mddev->ro = 0;
2074
1733 atomic_set(&mddev->writes_pending,0); 2075 atomic_set(&mddev->writes_pending,0);
1734 mddev->safemode = 0; 2076 mddev->safemode = 0;
1735 mddev->safemode_timer.function = md_safemode_timeout; 2077 mddev->safemode_timer.function = md_safemode_timeout;
1736 mddev->safemode_timer.data = (unsigned long) mddev; 2078 mddev->safemode_timer.data = (unsigned long) mddev;
1737 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */ 2079 mddev->safemode_delay = (20 * HZ)/1000 +1; /* 20 msec delay */
1738 mddev->in_sync = 1; 2080 mddev->in_sync = 1;
2081
2082 ITERATE_RDEV(mddev,rdev,tmp)
2083 if (rdev->raid_disk >= 0) {
2084 char nm[20];
2085 sprintf(nm, "rd%d", rdev->raid_disk);
2086 sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
2087 }
1739 2088
1740 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 2089 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
1741 md_wakeup_thread(mddev->thread); 2090 md_wakeup_thread(mddev->thread);
@@ -1821,16 +2170,19 @@ static int do_md_stop(mddev_t * mddev, int ro)
1821 2170
1822 if (ro) { 2171 if (ro) {
1823 err = -ENXIO; 2172 err = -ENXIO;
1824 if (mddev->ro) 2173 if (mddev->ro==1)
1825 goto out; 2174 goto out;
1826 mddev->ro = 1; 2175 mddev->ro = 1;
1827 } else { 2176 } else {
1828 bitmap_flush(mddev); 2177 bitmap_flush(mddev);
1829 wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0); 2178 md_super_wait(mddev);
1830 if (mddev->ro) 2179 if (mddev->ro)
1831 set_disk_ro(disk, 0); 2180 set_disk_ro(disk, 0);
1832 blk_queue_make_request(mddev->queue, md_fail_request); 2181 blk_queue_make_request(mddev->queue, md_fail_request);
1833 mddev->pers->stop(mddev); 2182 mddev->pers->stop(mddev);
2183 if (mddev->pers->sync_request)
2184 sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
2185
1834 module_put(mddev->pers->owner); 2186 module_put(mddev->pers->owner);
1835 mddev->pers = NULL; 2187 mddev->pers = NULL;
1836 if (mddev->ro) 2188 if (mddev->ro)
@@ -1857,9 +2209,18 @@ static int do_md_stop(mddev_t * mddev, int ro)
1857 * Free resources if final stop 2209 * Free resources if final stop
1858 */ 2210 */
1859 if (!ro) { 2211 if (!ro) {
2212 mdk_rdev_t *rdev;
2213 struct list_head *tmp;
1860 struct gendisk *disk; 2214 struct gendisk *disk;
1861 printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); 2215 printk(KERN_INFO "md: %s stopped.\n", mdname(mddev));
1862 2216
2217 ITERATE_RDEV(mddev,rdev,tmp)
2218 if (rdev->raid_disk >= 0) {
2219 char nm[20];
2220 sprintf(nm, "rd%d", rdev->raid_disk);
2221 sysfs_remove_link(&mddev->kobj, nm);
2222 }
2223
1863 export_array(mddev); 2224 export_array(mddev);
1864 2225
1865 mddev->array_size = 0; 2226 mddev->array_size = 0;
@@ -2012,7 +2373,7 @@ static int autostart_array(dev_t startdev)
2012 return err; 2373 return err;
2013 } 2374 }
2014 2375
2015 if (start_rdev->faulty) { 2376 if (test_bit(Faulty, &start_rdev->flags)) {
2016 printk(KERN_WARNING 2377 printk(KERN_WARNING
2017 "md: can not autostart based on faulty %s!\n", 2378 "md: can not autostart based on faulty %s!\n",
2018 bdevname(start_rdev->bdev,b)); 2379 bdevname(start_rdev->bdev,b));
@@ -2071,11 +2432,11 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
2071 nr=working=active=failed=spare=0; 2432 nr=working=active=failed=spare=0;
2072 ITERATE_RDEV(mddev,rdev,tmp) { 2433 ITERATE_RDEV(mddev,rdev,tmp) {
2073 nr++; 2434 nr++;
2074 if (rdev->faulty) 2435 if (test_bit(Faulty, &rdev->flags))
2075 failed++; 2436 failed++;
2076 else { 2437 else {
2077 working++; 2438 working++;
2078 if (rdev->in_sync) 2439 if (test_bit(In_sync, &rdev->flags))
2079 active++; 2440 active++;
2080 else 2441 else
2081 spare++; 2442 spare++;
@@ -2166,9 +2527,9 @@ static int get_disk_info(mddev_t * mddev, void __user * arg)
2166 info.minor = MINOR(rdev->bdev->bd_dev); 2527 info.minor = MINOR(rdev->bdev->bd_dev);
2167 info.raid_disk = rdev->raid_disk; 2528 info.raid_disk = rdev->raid_disk;
2168 info.state = 0; 2529 info.state = 0;
2169 if (rdev->faulty) 2530 if (test_bit(Faulty, &rdev->flags))
2170 info.state |= (1<<MD_DISK_FAULTY); 2531 info.state |= (1<<MD_DISK_FAULTY);
2171 else if (rdev->in_sync) { 2532 else if (test_bit(In_sync, &rdev->flags)) {
2172 info.state |= (1<<MD_DISK_ACTIVE); 2533 info.state |= (1<<MD_DISK_ACTIVE);
2173 info.state |= (1<<MD_DISK_SYNC); 2534 info.state |= (1<<MD_DISK_SYNC);
2174 } 2535 }
@@ -2261,7 +2622,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2261 validate_super(mddev, rdev); 2622 validate_super(mddev, rdev);
2262 rdev->saved_raid_disk = rdev->raid_disk; 2623 rdev->saved_raid_disk = rdev->raid_disk;
2263 2624
2264 rdev->in_sync = 0; /* just to be sure */ 2625 clear_bit(In_sync, &rdev->flags); /* just to be sure */
2265 if (info->state & (1<<MD_DISK_WRITEMOSTLY)) 2626 if (info->state & (1<<MD_DISK_WRITEMOSTLY))
2266 set_bit(WriteMostly, &rdev->flags); 2627 set_bit(WriteMostly, &rdev->flags);
2267 2628
@@ -2299,11 +2660,11 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
2299 else 2660 else
2300 rdev->raid_disk = -1; 2661 rdev->raid_disk = -1;
2301 2662
2302 rdev->faulty = 0; 2663 rdev->flags = 0;
2664
2303 if (rdev->raid_disk < mddev->raid_disks) 2665 if (rdev->raid_disk < mddev->raid_disks)
2304 rdev->in_sync = (info->state & (1<<MD_DISK_SYNC)); 2666 if (info->state & (1<<MD_DISK_SYNC))
2305 else 2667 set_bit(In_sync, &rdev->flags);
2306 rdev->in_sync = 0;
2307 2668
2308 if (info->state & (1<<MD_DISK_WRITEMOSTLY)) 2669 if (info->state & (1<<MD_DISK_WRITEMOSTLY))
2309 set_bit(WriteMostly, &rdev->flags); 2670 set_bit(WriteMostly, &rdev->flags);
@@ -2402,14 +2763,14 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
2402 goto abort_export; 2763 goto abort_export;
2403 } 2764 }
2404 2765
2405 if (rdev->faulty) { 2766 if (test_bit(Faulty, &rdev->flags)) {
2406 printk(KERN_WARNING 2767 printk(KERN_WARNING
2407 "md: can not hot-add faulty %s disk to %s!\n", 2768 "md: can not hot-add faulty %s disk to %s!\n",
2408 bdevname(rdev->bdev,b), mdname(mddev)); 2769 bdevname(rdev->bdev,b), mdname(mddev));
2409 err = -EINVAL; 2770 err = -EINVAL;
2410 goto abort_export; 2771 goto abort_export;
2411 } 2772 }
2412 rdev->in_sync = 0; 2773 clear_bit(In_sync, &rdev->flags);
2413 rdev->desc_nr = -1; 2774 rdev->desc_nr = -1;
2414 bind_rdev_to_array(rdev, mddev); 2775 bind_rdev_to_array(rdev, mddev);
2415 2776
@@ -2929,12 +3290,22 @@ static int md_ioctl(struct inode *inode, struct file *file,
2929 3290
2930 /* 3291 /*
2931 * The remaining ioctls are changing the state of the 3292 * The remaining ioctls are changing the state of the
2932 * superblock, so we do not allow read-only arrays 3293 * superblock, so we do not allow them on read-only arrays.
2933 * here: 3294 * However non-MD ioctls (e.g. get-size) will still come through
3295 * here and hit the 'default' below, so only disallow
3296 * 'md' ioctls, and switch to rw mode if started auto-readonly.
2934 */ 3297 */
2935 if (mddev->ro) { 3298 if (_IOC_TYPE(cmd) == MD_MAJOR &&
2936 err = -EROFS; 3299 mddev->ro && mddev->pers) {
2937 goto abort_unlock; 3300 if (mddev->ro == 2) {
3301 mddev->ro = 0;
3302 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3303 md_wakeup_thread(mddev->thread);
3304
3305 } else {
3306 err = -EROFS;
3307 goto abort_unlock;
3308 }
2938 } 3309 }
2939 3310
2940 switch (cmd) 3311 switch (cmd)
@@ -3064,21 +3435,17 @@ static int md_thread(void * arg)
3064 */ 3435 */
3065 3436
3066 allow_signal(SIGKILL); 3437 allow_signal(SIGKILL);
3067 complete(thread->event);
3068 while (!kthread_should_stop()) { 3438 while (!kthread_should_stop()) {
3069 void (*run)(mddev_t *);
3070 3439
3071 wait_event_interruptible_timeout(thread->wqueue, 3440 wait_event_timeout(thread->wqueue,
3072 test_bit(THREAD_WAKEUP, &thread->flags) 3441 test_bit(THREAD_WAKEUP, &thread->flags)
3073 || kthread_should_stop(), 3442 || kthread_should_stop(),
3074 thread->timeout); 3443 thread->timeout);
3075 try_to_freeze(); 3444 try_to_freeze();
3076 3445
3077 clear_bit(THREAD_WAKEUP, &thread->flags); 3446 clear_bit(THREAD_WAKEUP, &thread->flags);
3078 3447
3079 run = thread->run; 3448 thread->run(thread->mddev);
3080 if (run)
3081 run(thread->mddev);
3082 } 3449 }
3083 3450
3084 return 0; 3451 return 0;
@@ -3097,7 +3464,6 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3097 const char *name) 3464 const char *name)
3098{ 3465{
3099 mdk_thread_t *thread; 3466 mdk_thread_t *thread;
3100 struct completion event;
3101 3467
3102 thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL); 3468 thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL);
3103 if (!thread) 3469 if (!thread)
@@ -3106,18 +3472,14 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
3106 memset(thread, 0, sizeof(mdk_thread_t)); 3472 memset(thread, 0, sizeof(mdk_thread_t));
3107 init_waitqueue_head(&thread->wqueue); 3473 init_waitqueue_head(&thread->wqueue);
3108 3474
3109 init_completion(&event);
3110 thread->event = &event;
3111 thread->run = run; 3475 thread->run = run;
3112 thread->mddev = mddev; 3476 thread->mddev = mddev;
3113 thread->name = name;
3114 thread->timeout = MAX_SCHEDULE_TIMEOUT; 3477 thread->timeout = MAX_SCHEDULE_TIMEOUT;
3115 thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev)); 3478 thread->tsk = kthread_run(md_thread, thread, name, mdname(thread->mddev));
3116 if (IS_ERR(thread->tsk)) { 3479 if (IS_ERR(thread->tsk)) {
3117 kfree(thread); 3480 kfree(thread);
3118 return NULL; 3481 return NULL;
3119 } 3482 }
3120 wait_for_completion(&event);
3121 return thread; 3483 return thread;
3122} 3484}
3123 3485
@@ -3136,7 +3498,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev)
3136 return; 3498 return;
3137 } 3499 }
3138 3500
3139 if (!rdev || rdev->faulty) 3501 if (!rdev || test_bit(Faulty, &rdev->flags))
3140 return; 3502 return;
3141/* 3503/*
3142 dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n", 3504 dprintk("md_error dev:%s, rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",
@@ -3322,8 +3684,10 @@ static int md_seq_show(struct seq_file *seq, void *v)
3322 seq_printf(seq, "%s : %sactive", mdname(mddev), 3684 seq_printf(seq, "%s : %sactive", mdname(mddev),
3323 mddev->pers ? "" : "in"); 3685 mddev->pers ? "" : "in");
3324 if (mddev->pers) { 3686 if (mddev->pers) {
3325 if (mddev->ro) 3687 if (mddev->ro==1)
3326 seq_printf(seq, " (read-only)"); 3688 seq_printf(seq, " (read-only)");
3689 if (mddev->ro==2)
3690 seq_printf(seq, "(auto-read-only)");
3327 seq_printf(seq, " %s", mddev->pers->name); 3691 seq_printf(seq, " %s", mddev->pers->name);
3328 } 3692 }
3329 3693
@@ -3334,7 +3698,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
3334 bdevname(rdev->bdev,b), rdev->desc_nr); 3698 bdevname(rdev->bdev,b), rdev->desc_nr);
3335 if (test_bit(WriteMostly, &rdev->flags)) 3699 if (test_bit(WriteMostly, &rdev->flags))
3336 seq_printf(seq, "(W)"); 3700 seq_printf(seq, "(W)");
3337 if (rdev->faulty) { 3701 if (test_bit(Faulty, &rdev->flags)) {
3338 seq_printf(seq, "(F)"); 3702 seq_printf(seq, "(F)");
3339 continue; 3703 continue;
3340 } else if (rdev->raid_disk < 0) 3704 } else if (rdev->raid_disk < 0)
@@ -3363,11 +3727,15 @@ static int md_seq_show(struct seq_file *seq, void *v)
3363 if (mddev->pers) { 3727 if (mddev->pers) {
3364 mddev->pers->status (seq, mddev); 3728 mddev->pers->status (seq, mddev);
3365 seq_printf(seq, "\n "); 3729 seq_printf(seq, "\n ");
3366 if (mddev->curr_resync > 2) { 3730 if (mddev->pers->sync_request) {
3367 status_resync (seq, mddev); 3731 if (mddev->curr_resync > 2) {
3368 seq_printf(seq, "\n "); 3732 status_resync (seq, mddev);
3369 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2) 3733 seq_printf(seq, "\n ");
3370 seq_printf(seq, " resync=DELAYED\n "); 3734 } else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
3735 seq_printf(seq, "\tresync=DELAYED\n ");
3736 else if (mddev->recovery_cp < MaxSector)
3737 seq_printf(seq, "\tresync=PENDING\n ");
3738 }
3371 } else 3739 } else
3372 seq_printf(seq, "\n "); 3740 seq_printf(seq, "\n ");
3373 3741
@@ -3504,15 +3872,22 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
3504 if (bio_data_dir(bi) != WRITE) 3872 if (bio_data_dir(bi) != WRITE)
3505 return; 3873 return;
3506 3874
3875 BUG_ON(mddev->ro == 1);
3876 if (mddev->ro == 2) {
3877 /* need to switch to read/write */
3878 mddev->ro = 0;
3879 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3880 md_wakeup_thread(mddev->thread);
3881 }
3507 atomic_inc(&mddev->writes_pending); 3882 atomic_inc(&mddev->writes_pending);
3508 if (mddev->in_sync) { 3883 if (mddev->in_sync) {
3509 spin_lock(&mddev->write_lock); 3884 spin_lock_irq(&mddev->write_lock);
3510 if (mddev->in_sync) { 3885 if (mddev->in_sync) {
3511 mddev->in_sync = 0; 3886 mddev->in_sync = 0;
3512 mddev->sb_dirty = 1; 3887 mddev->sb_dirty = 1;
3513 md_wakeup_thread(mddev->thread); 3888 md_wakeup_thread(mddev->thread);
3514 } 3889 }
3515 spin_unlock(&mddev->write_lock); 3890 spin_unlock_irq(&mddev->write_lock);
3516 } 3891 }
3517 wait_event(mddev->sb_wait, mddev->sb_dirty==0); 3892 wait_event(mddev->sb_wait, mddev->sb_dirty==0);
3518} 3893}
@@ -3568,9 +3943,7 @@ static void md_do_sync(mddev_t *mddev)
3568 mddev->curr_resync = 2; 3943 mddev->curr_resync = 2;
3569 3944
3570 try_again: 3945 try_again:
3571 if (signal_pending(current) || 3946 if (kthread_should_stop()) {
3572 kthread_should_stop()) {
3573 flush_signals(current);
3574 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 3947 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
3575 goto skip; 3948 goto skip;
3576 } 3949 }
@@ -3590,9 +3963,8 @@ static void md_do_sync(mddev_t *mddev)
3590 * time 'round when curr_resync == 2 3963 * time 'round when curr_resync == 2
3591 */ 3964 */
3592 continue; 3965 continue;
3593 prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE); 3966 prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
3594 if (!signal_pending(current) && 3967 if (!kthread_should_stop() &&
3595 !kthread_should_stop() &&
3596 mddev2->curr_resync >= mddev->curr_resync) { 3968 mddev2->curr_resync >= mddev->curr_resync) {
3597 printk(KERN_INFO "md: delaying resync of %s" 3969 printk(KERN_INFO "md: delaying resync of %s"
3598 " until %s has finished resync (they" 3970 " until %s has finished resync (they"
@@ -3608,12 +3980,13 @@ static void md_do_sync(mddev_t *mddev)
3608 } 3980 }
3609 } while (mddev->curr_resync < 2); 3981 } while (mddev->curr_resync < 2);
3610 3982
3611 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) 3983 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
3612 /* resync follows the size requested by the personality, 3984 /* resync follows the size requested by the personality,
3613 * which defaults to physical size, but can be virtual size 3985 * which defaults to physical size, but can be virtual size
3614 */ 3986 */
3615 max_sectors = mddev->resync_max_sectors; 3987 max_sectors = mddev->resync_max_sectors;
3616 else 3988 mddev->resync_mismatches = 0;
3989 } else
3617 /* recovery follows the physical size of devices */ 3990 /* recovery follows the physical size of devices */
3618 max_sectors = mddev->size << 1; 3991 max_sectors = mddev->size << 1;
3619 3992
@@ -3626,7 +3999,8 @@ static void md_do_sync(mddev_t *mddev)
3626 3999
3627 is_mddev_idle(mddev); /* this also initializes IO event counters */ 4000 is_mddev_idle(mddev); /* this also initializes IO event counters */
3628 /* we don't use the checkpoint if there's a bitmap */ 4001 /* we don't use the checkpoint if there's a bitmap */
3629 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap) 4002 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !mddev->bitmap
4003 && ! test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
3630 j = mddev->recovery_cp; 4004 j = mddev->recovery_cp;
3631 else 4005 else
3632 j = 0; 4006 j = 0;
@@ -3699,13 +4073,12 @@ static void md_do_sync(mddev_t *mddev)
3699 } 4073 }
3700 4074
3701 4075
3702 if (signal_pending(current) || kthread_should_stop()) { 4076 if (kthread_should_stop()) {
3703 /* 4077 /*
3704 * got a signal, exit. 4078 * got a signal, exit.
3705 */ 4079 */
3706 printk(KERN_INFO 4080 printk(KERN_INFO
3707 "md: md_do_sync() got signal ... exiting\n"); 4081 "md: md_do_sync() got signal ... exiting\n");
3708 flush_signals(current);
3709 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 4082 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
3710 goto out; 4083 goto out;
3711 } 4084 }
@@ -3727,7 +4100,7 @@ static void md_do_sync(mddev_t *mddev)
3727 if (currspeed > sysctl_speed_limit_min) { 4100 if (currspeed > sysctl_speed_limit_min) {
3728 if ((currspeed > sysctl_speed_limit_max) || 4101 if ((currspeed > sysctl_speed_limit_max) ||
3729 !is_mddev_idle(mddev)) { 4102 !is_mddev_idle(mddev)) {
3730 msleep_interruptible(250); 4103 msleep(250);
3731 goto repeat; 4104 goto repeat;
3732 } 4105 }
3733 } 4106 }
@@ -3820,7 +4193,7 @@ void md_check_recovery(mddev_t *mddev)
3820 if (mddev_trylock(mddev)==0) { 4193 if (mddev_trylock(mddev)==0) {
3821 int spares =0; 4194 int spares =0;
3822 4195
3823 spin_lock(&mddev->write_lock); 4196 spin_lock_irq(&mddev->write_lock);
3824 if (mddev->safemode && !atomic_read(&mddev->writes_pending) && 4197 if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
3825 !mddev->in_sync && mddev->recovery_cp == MaxSector) { 4198 !mddev->in_sync && mddev->recovery_cp == MaxSector) {
3826 mddev->in_sync = 1; 4199 mddev->in_sync = 1;
@@ -3828,7 +4201,7 @@ void md_check_recovery(mddev_t *mddev)
3828 } 4201 }
3829 if (mddev->safemode == 1) 4202 if (mddev->safemode == 1)
3830 mddev->safemode = 0; 4203 mddev->safemode = 0;
3831 spin_unlock(&mddev->write_lock); 4204 spin_unlock_irq(&mddev->write_lock);
3832 4205
3833 if (mddev->sb_dirty) 4206 if (mddev->sb_dirty)
3834 md_update_sb(mddev); 4207 md_update_sb(mddev);
@@ -3864,9 +4237,13 @@ void md_check_recovery(mddev_t *mddev)
3864 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4237 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3865 goto unlock; 4238 goto unlock;
3866 } 4239 }
3867 if (mddev->recovery) 4240 /* Clear some bits that don't mean anything, but
3868 /* probably just the RECOVERY_NEEDED flag */ 4241 * might be left set
3869 mddev->recovery = 0; 4242 */
4243 clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
4244 clear_bit(MD_RECOVERY_ERR, &mddev->recovery);
4245 clear_bit(MD_RECOVERY_INTR, &mddev->recovery);
4246 clear_bit(MD_RECOVERY_DONE, &mddev->recovery);
3870 4247
3871 /* no recovery is running. 4248 /* no recovery is running.
3872 * remove any failed drives, then 4249 * remove any failed drives, then
@@ -3876,31 +4253,41 @@ void md_check_recovery(mddev_t *mddev)
3876 */ 4253 */
3877 ITERATE_RDEV(mddev,rdev,rtmp) 4254 ITERATE_RDEV(mddev,rdev,rtmp)
3878 if (rdev->raid_disk >= 0 && 4255 if (rdev->raid_disk >= 0 &&
3879 (rdev->faulty || ! rdev->in_sync) && 4256 (test_bit(Faulty, &rdev->flags) || ! test_bit(In_sync, &rdev->flags)) &&
3880 atomic_read(&rdev->nr_pending)==0) { 4257 atomic_read(&rdev->nr_pending)==0) {
3881 if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) 4258 if (mddev->pers->hot_remove_disk(mddev, rdev->raid_disk)==0) {
4259 char nm[20];
4260 sprintf(nm,"rd%d", rdev->raid_disk);
4261 sysfs_remove_link(&mddev->kobj, nm);
3882 rdev->raid_disk = -1; 4262 rdev->raid_disk = -1;
4263 }
3883 } 4264 }
3884 4265
3885 if (mddev->degraded) { 4266 if (mddev->degraded) {
3886 ITERATE_RDEV(mddev,rdev,rtmp) 4267 ITERATE_RDEV(mddev,rdev,rtmp)
3887 if (rdev->raid_disk < 0 4268 if (rdev->raid_disk < 0
3888 && !rdev->faulty) { 4269 && !test_bit(Faulty, &rdev->flags)) {
3889 if (mddev->pers->hot_add_disk(mddev,rdev)) 4270 if (mddev->pers->hot_add_disk(mddev,rdev)) {
4271 char nm[20];
4272 sprintf(nm, "rd%d", rdev->raid_disk);
4273 sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
3890 spares++; 4274 spares++;
3891 else 4275 } else
3892 break; 4276 break;
3893 } 4277 }
3894 } 4278 }
3895 4279
3896 if (!spares && (mddev->recovery_cp == MaxSector )) { 4280 if (spares) {
3897 /* nothing we can do ... */ 4281 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4282 clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
4283 } else if (mddev->recovery_cp < MaxSector) {
4284 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
4285 } else if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
4286 /* nothing to be done ... */
3898 goto unlock; 4287 goto unlock;
3899 } 4288
3900 if (mddev->pers->sync_request) { 4289 if (mddev->pers->sync_request) {
3901 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); 4290 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
3902 if (!spares)
3903 set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
3904 if (spares && mddev->bitmap && ! mddev->bitmap->file) { 4291 if (spares && mddev->bitmap && ! mddev->bitmap->file) {
3905 /* We are adding a device or devices to an array 4292 /* We are adding a device or devices to an array
3906 * which has the bitmap stored on all devices. 4293 * which has the bitmap stored on all devices.
@@ -3975,7 +4362,7 @@ static int __init md_init(void)
3975 " MD_SB_DISKS=%d\n", 4362 " MD_SB_DISKS=%d\n",
3976 MD_MAJOR_VERSION, MD_MINOR_VERSION, 4363 MD_MAJOR_VERSION, MD_MINOR_VERSION,
3977 MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS); 4364 MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MD_SB_DISKS);
3978 printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR, 4365 printk(KERN_INFO "md: bitmap version %d.%d\n", BITMAP_MAJOR_HI,
3979 BITMAP_MINOR); 4366 BITMAP_MINOR);
3980 4367
3981 if (register_blkdev(MAJOR_NR, "md")) 4368 if (register_blkdev(MAJOR_NR, "md"))
@@ -4039,7 +4426,7 @@ static void autostart_arrays(int part)
4039 if (IS_ERR(rdev)) 4426 if (IS_ERR(rdev))
4040 continue; 4427 continue;
4041 4428
4042 if (rdev->faulty) { 4429 if (test_bit(Faulty, &rdev->flags)) {
4043 MD_BUG(); 4430 MD_BUG();
4044 continue; 4431 continue;
4045 } 4432 }
@@ -4086,6 +4473,23 @@ static __exit void md_exit(void)
4086module_init(md_init) 4473module_init(md_init)
4087module_exit(md_exit) 4474module_exit(md_exit)
4088 4475
4476static int get_ro(char *buffer, struct kernel_param *kp)
4477{
4478 return sprintf(buffer, "%d", start_readonly);
4479}
4480static int set_ro(const char *val, struct kernel_param *kp)
4481{
4482 char *e;
4483 int num = simple_strtoul(val, &e, 10);
4484 if (*val && (*e == '\0' || *e == '\n')) {
4485 start_readonly = num;
4486 return 0;;
4487 }
4488 return -EINVAL;
4489}
4490
4491module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
4492
4089EXPORT_SYMBOL(register_md_personality); 4493EXPORT_SYMBOL(register_md_personality);
4090EXPORT_SYMBOL(unregister_md_personality); 4494EXPORT_SYMBOL(unregister_md_personality);
4091EXPORT_SYMBOL(md_error); 4495EXPORT_SYMBOL(md_error);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index c06f4474192b..145cdc5ad008 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -63,8 +63,8 @@ static int multipath_map (multipath_conf_t *conf)
63 63
64 rcu_read_lock(); 64 rcu_read_lock();
65 for (i = 0; i < disks; i++) { 65 for (i = 0; i < disks; i++) {
66 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 66 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
67 if (rdev && rdev->in_sync) { 67 if (rdev && test_bit(In_sync, &rdev->flags)) {
68 atomic_inc(&rdev->nr_pending); 68 atomic_inc(&rdev->nr_pending);
69 rcu_read_unlock(); 69 rcu_read_unlock();
70 return i; 70 return i;
@@ -139,8 +139,9 @@ static void unplug_slaves(mddev_t *mddev)
139 139
140 rcu_read_lock(); 140 rcu_read_lock();
141 for (i=0; i<mddev->raid_disks; i++) { 141 for (i=0; i<mddev->raid_disks; i++) {
142 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 142 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
143 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 143 if (rdev && !test_bit(Faulty, &rdev->flags)
144 && atomic_read(&rdev->nr_pending)) {
144 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 145 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
145 146
146 atomic_inc(&rdev->nr_pending); 147 atomic_inc(&rdev->nr_pending);
@@ -211,7 +212,7 @@ static void multipath_status (struct seq_file *seq, mddev_t *mddev)
211 for (i = 0; i < conf->raid_disks; i++) 212 for (i = 0; i < conf->raid_disks; i++)
212 seq_printf (seq, "%s", 213 seq_printf (seq, "%s",
213 conf->multipaths[i].rdev && 214 conf->multipaths[i].rdev &&
214 conf->multipaths[i].rdev->in_sync ? "U" : "_"); 215 test_bit(In_sync, &conf->multipaths[i].rdev->flags) ? "U" : "_");
215 seq_printf (seq, "]"); 216 seq_printf (seq, "]");
216} 217}
217 218
@@ -224,8 +225,8 @@ static int multipath_issue_flush(request_queue_t *q, struct gendisk *disk,
224 225
225 rcu_read_lock(); 226 rcu_read_lock();
226 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 227 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
227 mdk_rdev_t *rdev = conf->multipaths[i].rdev; 228 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
228 if (rdev && !rdev->faulty) { 229 if (rdev && !test_bit(Faulty, &rdev->flags)) {
229 struct block_device *bdev = rdev->bdev; 230 struct block_device *bdev = rdev->bdev;
230 request_queue_t *r_queue = bdev_get_queue(bdev); 231 request_queue_t *r_queue = bdev_get_queue(bdev);
231 232
@@ -265,10 +266,10 @@ static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
265 /* 266 /*
266 * Mark disk as unusable 267 * Mark disk as unusable
267 */ 268 */
268 if (!rdev->faulty) { 269 if (!test_bit(Faulty, &rdev->flags)) {
269 char b[BDEVNAME_SIZE]; 270 char b[BDEVNAME_SIZE];
270 rdev->in_sync = 0; 271 clear_bit(In_sync, &rdev->flags);
271 rdev->faulty = 1; 272 set_bit(Faulty, &rdev->flags);
272 mddev->sb_dirty = 1; 273 mddev->sb_dirty = 1;
273 conf->working_disks--; 274 conf->working_disks--;
274 printk(KERN_ALERT "multipath: IO failure on %s," 275 printk(KERN_ALERT "multipath: IO failure on %s,"
@@ -298,7 +299,7 @@ static void print_multipath_conf (multipath_conf_t *conf)
298 tmp = conf->multipaths + i; 299 tmp = conf->multipaths + i;
299 if (tmp->rdev) 300 if (tmp->rdev)
300 printk(" disk%d, o:%d, dev:%s\n", 301 printk(" disk%d, o:%d, dev:%s\n",
301 i,!tmp->rdev->faulty, 302 i,!test_bit(Faulty, &tmp->rdev->flags),
302 bdevname(tmp->rdev->bdev,b)); 303 bdevname(tmp->rdev->bdev,b));
303 } 304 }
304} 305}
@@ -330,8 +331,8 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
330 331
331 conf->working_disks++; 332 conf->working_disks++;
332 rdev->raid_disk = path; 333 rdev->raid_disk = path;
333 rdev->in_sync = 1; 334 set_bit(In_sync, &rdev->flags);
334 p->rdev = rdev; 335 rcu_assign_pointer(p->rdev, rdev);
335 found = 1; 336 found = 1;
336 } 337 }
337 338
@@ -350,7 +351,7 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
350 351
351 rdev = p->rdev; 352 rdev = p->rdev;
352 if (rdev) { 353 if (rdev) {
353 if (rdev->in_sync || 354 if (test_bit(In_sync, &rdev->flags) ||
354 atomic_read(&rdev->nr_pending)) { 355 atomic_read(&rdev->nr_pending)) {
355 printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number); 356 printk(KERN_ERR "hot-remove-disk, slot %d is identified" " but is still operational!\n", number);
356 err = -EBUSY; 357 err = -EBUSY;
@@ -482,7 +483,7 @@ static int multipath_run (mddev_t *mddev)
482 mddev->queue->max_sectors > (PAGE_SIZE>>9)) 483 mddev->queue->max_sectors > (PAGE_SIZE>>9))
483 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); 484 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
484 485
485 if (!rdev->faulty) 486 if (!test_bit(Faulty, &rdev->flags))
486 conf->working_disks++; 487 conf->working_disks++;
487 } 488 }
488 489
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e16f473bcf46..2da9d3ba902d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -301,7 +301,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
301{ 301{
302 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); 302 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
303 r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private); 303 r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
304 int mirror, behind; 304 int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
305 conf_t *conf = mddev_to_conf(r1_bio->mddev); 305 conf_t *conf = mddev_to_conf(r1_bio->mddev);
306 306
307 if (bio->bi_size) 307 if (bio->bi_size)
@@ -311,47 +311,54 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
311 if (r1_bio->bios[mirror] == bio) 311 if (r1_bio->bios[mirror] == bio)
312 break; 312 break;
313 313
314 /* 314 if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) {
315 * this branch is our 'one mirror IO has finished' event handler: 315 set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags);
316 */ 316 set_bit(R1BIO_BarrierRetry, &r1_bio->state);
317 if (!uptodate) { 317 r1_bio->mddev->barriers_work = 0;
318 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev); 318 } else {
319 /* an I/O failed, we can't clear the bitmap */
320 set_bit(R1BIO_Degraded, &r1_bio->state);
321 } else
322 /* 319 /*
323 * Set R1BIO_Uptodate in our master bio, so that 320 * this branch is our 'one mirror IO has finished' event handler:
324 * we will return a good error code for to the higher
325 * levels even if IO on some other mirrored buffer fails.
326 *
327 * The 'master' represents the composite IO operation to
328 * user-side. So if something waits for IO, then it will
329 * wait for the 'master' bio.
330 */ 321 */
331 set_bit(R1BIO_Uptodate, &r1_bio->state); 322 r1_bio->bios[mirror] = NULL;
332 323 bio_put(bio);
333 update_head_pos(mirror, r1_bio); 324 if (!uptodate) {
334 325 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
335 behind = test_bit(R1BIO_BehindIO, &r1_bio->state); 326 /* an I/O failed, we can't clear the bitmap */
336 if (behind) { 327 set_bit(R1BIO_Degraded, &r1_bio->state);
337 if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags)) 328 } else
338 atomic_dec(&r1_bio->behind_remaining); 329 /*
339 330 * Set R1BIO_Uptodate in our master bio, so that
340 /* In behind mode, we ACK the master bio once the I/O has safely 331 * we will return a good error code for to the higher
341 * reached all non-writemostly disks. Setting the Returned bit 332 * levels even if IO on some other mirrored buffer fails.
342 * ensures that this gets done only once -- we don't ever want to 333 *
343 * return -EIO here, instead we'll wait */ 334 * The 'master' represents the composite IO operation to
344 335 * user-side. So if something waits for IO, then it will
345 if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) && 336 * wait for the 'master' bio.
346 test_bit(R1BIO_Uptodate, &r1_bio->state)) { 337 */
347 /* Maybe we can return now */ 338 set_bit(R1BIO_Uptodate, &r1_bio->state);
348 if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) { 339
349 struct bio *mbio = r1_bio->master_bio; 340 update_head_pos(mirror, r1_bio);
350 PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n", 341
351 (unsigned long long) mbio->bi_sector, 342 if (behind) {
352 (unsigned long long) mbio->bi_sector + 343 if (test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags))
353 (mbio->bi_size >> 9) - 1); 344 atomic_dec(&r1_bio->behind_remaining);
354 bio_endio(mbio, mbio->bi_size, 0); 345
346 /* In behind mode, we ACK the master bio once the I/O has safely
347 * reached all non-writemostly disks. Setting the Returned bit
348 * ensures that this gets done only once -- we don't ever want to
349 * return -EIO here, instead we'll wait */
350
351 if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
352 test_bit(R1BIO_Uptodate, &r1_bio->state)) {
353 /* Maybe we can return now */
354 if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
355 struct bio *mbio = r1_bio->master_bio;
356 PRINTK(KERN_DEBUG "raid1: behind end write sectors %llu-%llu\n",
357 (unsigned long long) mbio->bi_sector,
358 (unsigned long long) mbio->bi_sector +
359 (mbio->bi_size >> 9) - 1);
360 bio_endio(mbio, mbio->bi_size, 0);
361 }
355 } 362 }
356 } 363 }
357 } 364 }
@@ -361,8 +368,16 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
361 * already. 368 * already.
362 */ 369 */
363 if (atomic_dec_and_test(&r1_bio->remaining)) { 370 if (atomic_dec_and_test(&r1_bio->remaining)) {
371 if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
372 reschedule_retry(r1_bio);
373 /* Don't dec_pending yet, we want to hold
374 * the reference over the retry
375 */
376 return 0;
377 }
364 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { 378 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
365 /* free extra copy of the data pages */ 379 /* free extra copy of the data pages */
380/* FIXME bio has been freed!!! */
366 int i = bio->bi_vcnt; 381 int i = bio->bi_vcnt;
367 while (i--) 382 while (i--)
368 __free_page(bio->bi_io_vec[i].bv_page); 383 __free_page(bio->bi_io_vec[i].bv_page);
@@ -416,12 +431,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
416 /* Choose the first operation device, for consistancy */ 431 /* Choose the first operation device, for consistancy */
417 new_disk = 0; 432 new_disk = 0;
418 433
419 for (rdev = conf->mirrors[new_disk].rdev; 434 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
420 !rdev || !rdev->in_sync 435 !rdev || !test_bit(In_sync, &rdev->flags)
421 || test_bit(WriteMostly, &rdev->flags); 436 || test_bit(WriteMostly, &rdev->flags);
422 rdev = conf->mirrors[++new_disk].rdev) { 437 rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) {
423 438
424 if (rdev && rdev->in_sync) 439 if (rdev && test_bit(In_sync, &rdev->flags))
425 wonly_disk = new_disk; 440 wonly_disk = new_disk;
426 441
427 if (new_disk == conf->raid_disks - 1) { 442 if (new_disk == conf->raid_disks - 1) {
@@ -434,12 +449,12 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
434 449
435 450
436 /* make sure the disk is operational */ 451 /* make sure the disk is operational */
437 for (rdev = conf->mirrors[new_disk].rdev; 452 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
438 !rdev || !rdev->in_sync || 453 !rdev || !test_bit(In_sync, &rdev->flags) ||
439 test_bit(WriteMostly, &rdev->flags); 454 test_bit(WriteMostly, &rdev->flags);
440 rdev = conf->mirrors[new_disk].rdev) { 455 rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) {
441 456
442 if (rdev && rdev->in_sync) 457 if (rdev && test_bit(In_sync, &rdev->flags))
443 wonly_disk = new_disk; 458 wonly_disk = new_disk;
444 459
445 if (new_disk <= 0) 460 if (new_disk <= 0)
@@ -474,10 +489,10 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
474 disk = conf->raid_disks; 489 disk = conf->raid_disks;
475 disk--; 490 disk--;
476 491
477 rdev = conf->mirrors[disk].rdev; 492 rdev = rcu_dereference(conf->mirrors[disk].rdev);
478 493
479 if (!rdev || 494 if (!rdev ||
480 !rdev->in_sync || 495 !test_bit(In_sync, &rdev->flags) ||
481 test_bit(WriteMostly, &rdev->flags)) 496 test_bit(WriteMostly, &rdev->flags))
482 continue; 497 continue;
483 498
@@ -496,11 +511,11 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
496 511
497 512
498 if (new_disk >= 0) { 513 if (new_disk >= 0) {
499 rdev = conf->mirrors[new_disk].rdev; 514 rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
500 if (!rdev) 515 if (!rdev)
501 goto retry; 516 goto retry;
502 atomic_inc(&rdev->nr_pending); 517 atomic_inc(&rdev->nr_pending);
503 if (!rdev->in_sync) { 518 if (!test_bit(In_sync, &rdev->flags)) {
504 /* cannot risk returning a device that failed 519 /* cannot risk returning a device that failed
505 * before we inc'ed nr_pending 520 * before we inc'ed nr_pending
506 */ 521 */
@@ -522,8 +537,8 @@ static void unplug_slaves(mddev_t *mddev)
522 537
523 rcu_read_lock(); 538 rcu_read_lock();
524 for (i=0; i<mddev->raid_disks; i++) { 539 for (i=0; i<mddev->raid_disks; i++) {
525 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 540 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
526 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 541 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
527 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 542 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
528 543
529 atomic_inc(&rdev->nr_pending); 544 atomic_inc(&rdev->nr_pending);
@@ -556,8 +571,8 @@ static int raid1_issue_flush(request_queue_t *q, struct gendisk *disk,
556 571
557 rcu_read_lock(); 572 rcu_read_lock();
558 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 573 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
559 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 574 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
560 if (rdev && !rdev->faulty) { 575 if (rdev && !test_bit(Faulty, &rdev->flags)) {
561 struct block_device *bdev = rdev->bdev; 576 struct block_device *bdev = rdev->bdev;
562 request_queue_t *r_queue = bdev_get_queue(bdev); 577 request_queue_t *r_queue = bdev_get_queue(bdev);
563 578
@@ -648,8 +663,9 @@ static int make_request(request_queue_t *q, struct bio * bio)
648 struct bio_list bl; 663 struct bio_list bl;
649 struct page **behind_pages = NULL; 664 struct page **behind_pages = NULL;
650 const int rw = bio_data_dir(bio); 665 const int rw = bio_data_dir(bio);
666 int do_barriers;
651 667
652 if (unlikely(bio_barrier(bio))) { 668 if (unlikely(!mddev->barriers_work && bio_barrier(bio))) {
653 bio_endio(bio, bio->bi_size, -EOPNOTSUPP); 669 bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
654 return 0; 670 return 0;
655 } 671 }
@@ -728,10 +744,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
728#endif 744#endif
729 rcu_read_lock(); 745 rcu_read_lock();
730 for (i = 0; i < disks; i++) { 746 for (i = 0; i < disks; i++) {
731 if ((rdev=conf->mirrors[i].rdev) != NULL && 747 if ((rdev=rcu_dereference(conf->mirrors[i].rdev)) != NULL &&
732 !rdev->faulty) { 748 !test_bit(Faulty, &rdev->flags)) {
733 atomic_inc(&rdev->nr_pending); 749 atomic_inc(&rdev->nr_pending);
734 if (rdev->faulty) { 750 if (test_bit(Faulty, &rdev->flags)) {
735 atomic_dec(&rdev->nr_pending); 751 atomic_dec(&rdev->nr_pending);
736 r1_bio->bios[i] = NULL; 752 r1_bio->bios[i] = NULL;
737 } else 753 } else
@@ -759,6 +775,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
759 atomic_set(&r1_bio->remaining, 0); 775 atomic_set(&r1_bio->remaining, 0);
760 atomic_set(&r1_bio->behind_remaining, 0); 776 atomic_set(&r1_bio->behind_remaining, 0);
761 777
778 do_barriers = bio->bi_rw & BIO_RW_BARRIER;
779 if (do_barriers)
780 set_bit(R1BIO_Barrier, &r1_bio->state);
781
762 bio_list_init(&bl); 782 bio_list_init(&bl);
763 for (i = 0; i < disks; i++) { 783 for (i = 0; i < disks; i++) {
764 struct bio *mbio; 784 struct bio *mbio;
@@ -771,7 +791,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
771 mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; 791 mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
772 mbio->bi_bdev = conf->mirrors[i].rdev->bdev; 792 mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
773 mbio->bi_end_io = raid1_end_write_request; 793 mbio->bi_end_io = raid1_end_write_request;
774 mbio->bi_rw = WRITE; 794 mbio->bi_rw = WRITE | do_barriers;
775 mbio->bi_private = r1_bio; 795 mbio->bi_private = r1_bio;
776 796
777 if (behind_pages) { 797 if (behind_pages) {
@@ -824,7 +844,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
824 for (i = 0; i < conf->raid_disks; i++) 844 for (i = 0; i < conf->raid_disks; i++)
825 seq_printf(seq, "%s", 845 seq_printf(seq, "%s",
826 conf->mirrors[i].rdev && 846 conf->mirrors[i].rdev &&
827 conf->mirrors[i].rdev->in_sync ? "U" : "_"); 847 test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
828 seq_printf(seq, "]"); 848 seq_printf(seq, "]");
829} 849}
830 850
@@ -840,14 +860,14 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
840 * next level up know. 860 * next level up know.
841 * else mark the drive as failed 861 * else mark the drive as failed
842 */ 862 */
843 if (rdev->in_sync 863 if (test_bit(In_sync, &rdev->flags)
844 && conf->working_disks == 1) 864 && conf->working_disks == 1)
845 /* 865 /*
846 * Don't fail the drive, act as though we were just a 866 * Don't fail the drive, act as though we were just a
847 * normal single drive 867 * normal single drive
848 */ 868 */
849 return; 869 return;
850 if (rdev->in_sync) { 870 if (test_bit(In_sync, &rdev->flags)) {
851 mddev->degraded++; 871 mddev->degraded++;
852 conf->working_disks--; 872 conf->working_disks--;
853 /* 873 /*
@@ -855,8 +875,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
855 */ 875 */
856 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 876 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
857 } 877 }
858 rdev->in_sync = 0; 878 clear_bit(In_sync, &rdev->flags);
859 rdev->faulty = 1; 879 set_bit(Faulty, &rdev->flags);
860 mddev->sb_dirty = 1; 880 mddev->sb_dirty = 1;
861 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n" 881 printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
862 " Operation continuing on %d devices\n", 882 " Operation continuing on %d devices\n",
@@ -881,7 +901,7 @@ static void print_conf(conf_t *conf)
881 tmp = conf->mirrors + i; 901 tmp = conf->mirrors + i;
882 if (tmp->rdev) 902 if (tmp->rdev)
883 printk(" disk %d, wo:%d, o:%d, dev:%s\n", 903 printk(" disk %d, wo:%d, o:%d, dev:%s\n",
884 i, !tmp->rdev->in_sync, !tmp->rdev->faulty, 904 i, !test_bit(In_sync, &tmp->rdev->flags), !test_bit(Faulty, &tmp->rdev->flags),
885 bdevname(tmp->rdev->bdev,b)); 905 bdevname(tmp->rdev->bdev,b));
886 } 906 }
887} 907}
@@ -913,11 +933,11 @@ static int raid1_spare_active(mddev_t *mddev)
913 for (i = 0; i < conf->raid_disks; i++) { 933 for (i = 0; i < conf->raid_disks; i++) {
914 tmp = conf->mirrors + i; 934 tmp = conf->mirrors + i;
915 if (tmp->rdev 935 if (tmp->rdev
916 && !tmp->rdev->faulty 936 && !test_bit(Faulty, &tmp->rdev->flags)
917 && !tmp->rdev->in_sync) { 937 && !test_bit(In_sync, &tmp->rdev->flags)) {
918 conf->working_disks++; 938 conf->working_disks++;
919 mddev->degraded--; 939 mddev->degraded--;
920 tmp->rdev->in_sync = 1; 940 set_bit(In_sync, &tmp->rdev->flags);
921 } 941 }
922 } 942 }
923 943
@@ -954,7 +974,7 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
954 found = 1; 974 found = 1;
955 if (rdev->saved_raid_disk != mirror) 975 if (rdev->saved_raid_disk != mirror)
956 conf->fullsync = 1; 976 conf->fullsync = 1;
957 p->rdev = rdev; 977 rcu_assign_pointer(p->rdev, rdev);
958 break; 978 break;
959 } 979 }
960 980
@@ -972,7 +992,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
972 print_conf(conf); 992 print_conf(conf);
973 rdev = p->rdev; 993 rdev = p->rdev;
974 if (rdev) { 994 if (rdev) {
975 if (rdev->in_sync || 995 if (test_bit(In_sync, &rdev->flags) ||
976 atomic_read(&rdev->nr_pending)) { 996 atomic_read(&rdev->nr_pending)) {
977 err = -EBUSY; 997 err = -EBUSY;
978 goto abort; 998 goto abort;
@@ -1153,6 +1173,36 @@ static void raid1d(mddev_t *mddev)
1153 if (test_bit(R1BIO_IsSync, &r1_bio->state)) { 1173 if (test_bit(R1BIO_IsSync, &r1_bio->state)) {
1154 sync_request_write(mddev, r1_bio); 1174 sync_request_write(mddev, r1_bio);
1155 unplug = 1; 1175 unplug = 1;
1176 } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
1177 /* some requests in the r1bio were BIO_RW_BARRIER
1178 * requests which failed with -ENOTSUPP. Hohumm..
1179 * Better resubmit without the barrier.
1180 * We know which devices to resubmit for, because
1181 * all others have had their bios[] entry cleared.
1182 */
1183 int i;
1184 clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
1185 clear_bit(R1BIO_Barrier, &r1_bio->state);
1186 for (i=0; i < conf->raid_disks; i++)
1187 if (r1_bio->bios[i]) {
1188 struct bio_vec *bvec;
1189 int j;
1190
1191 bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
1192 /* copy pages from the failed bio, as
1193 * this might be a write-behind device */
1194 __bio_for_each_segment(bvec, bio, j, 0)
1195 bvec->bv_page = bio_iovec_idx(r1_bio->bios[i], j)->bv_page;
1196 bio_put(r1_bio->bios[i]);
1197 bio->bi_sector = r1_bio->sector +
1198 conf->mirrors[i].rdev->data_offset;
1199 bio->bi_bdev = conf->mirrors[i].rdev->bdev;
1200 bio->bi_end_io = raid1_end_write_request;
1201 bio->bi_rw = WRITE;
1202 bio->bi_private = r1_bio;
1203 r1_bio->bios[i] = bio;
1204 generic_make_request(bio);
1205 }
1156 } else { 1206 } else {
1157 int disk; 1207 int disk;
1158 bio = r1_bio->bios[r1_bio->read_disk]; 1208 bio = r1_bio->bios[r1_bio->read_disk];
@@ -1260,7 +1310,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1260 * This call the bitmap_start_sync doesn't actually record anything 1310 * This call the bitmap_start_sync doesn't actually record anything
1261 */ 1311 */
1262 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && 1312 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
1263 !conf->fullsync) { 1313 !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
1264 /* We can skip this block, and probably several more */ 1314 /* We can skip this block, and probably several more */
1265 *skipped = 1; 1315 *skipped = 1;
1266 return sync_blocks; 1316 return sync_blocks;
@@ -1282,11 +1332,11 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1282 /* make sure disk is operational */ 1332 /* make sure disk is operational */
1283 wonly = disk; 1333 wonly = disk;
1284 while (conf->mirrors[disk].rdev == NULL || 1334 while (conf->mirrors[disk].rdev == NULL ||
1285 !conf->mirrors[disk].rdev->in_sync || 1335 !test_bit(In_sync, &conf->mirrors[disk].rdev->flags) ||
1286 test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags) 1336 test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags)
1287 ) { 1337 ) {
1288 if (conf->mirrors[disk].rdev && 1338 if (conf->mirrors[disk].rdev &&
1289 conf->mirrors[disk].rdev->in_sync) 1339 test_bit(In_sync, &conf->mirrors[disk].rdev->flags))
1290 wonly = disk; 1340 wonly = disk;
1291 if (disk <= 0) 1341 if (disk <= 0)
1292 disk = conf->raid_disks; 1342 disk = conf->raid_disks;
@@ -1333,11 +1383,12 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1333 bio->bi_rw = READ; 1383 bio->bi_rw = READ;
1334 bio->bi_end_io = end_sync_read; 1384 bio->bi_end_io = end_sync_read;
1335 } else if (conf->mirrors[i].rdev == NULL || 1385 } else if (conf->mirrors[i].rdev == NULL ||
1336 conf->mirrors[i].rdev->faulty) { 1386 test_bit(Faulty, &conf->mirrors[i].rdev->flags)) {
1337 still_degraded = 1; 1387 still_degraded = 1;
1338 continue; 1388 continue;
1339 } else if (!conf->mirrors[i].rdev->in_sync || 1389 } else if (!test_bit(In_sync, &conf->mirrors[i].rdev->flags) ||
1340 sector_nr + RESYNC_SECTORS > mddev->recovery_cp) { 1390 sector_nr + RESYNC_SECTORS > mddev->recovery_cp ||
1391 test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
1341 bio->bi_rw = WRITE; 1392 bio->bi_rw = WRITE;
1342 bio->bi_end_io = end_sync_write; 1393 bio->bi_end_io = end_sync_write;
1343 write_targets ++; 1394 write_targets ++;
@@ -1371,8 +1422,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1371 break; 1422 break;
1372 if (sync_blocks == 0) { 1423 if (sync_blocks == 0) {
1373 if (!bitmap_start_sync(mddev->bitmap, sector_nr, 1424 if (!bitmap_start_sync(mddev->bitmap, sector_nr,
1374 &sync_blocks, still_degraded) && 1425 &sync_blocks, still_degraded) &&
1375 !conf->fullsync) 1426 !conf->fullsync &&
1427 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
1376 break; 1428 break;
1377 if (sync_blocks < (PAGE_SIZE>>9)) 1429 if (sync_blocks < (PAGE_SIZE>>9))
1378 BUG(); 1430 BUG();
@@ -1478,7 +1530,7 @@ static int run(mddev_t *mddev)
1478 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9); 1530 blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
1479 1531
1480 disk->head_position = 0; 1532 disk->head_position = 0;
1481 if (!rdev->faulty && rdev->in_sync) 1533 if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
1482 conf->working_disks++; 1534 conf->working_disks++;
1483 } 1535 }
1484 conf->raid_disks = mddev->raid_disks; 1536 conf->raid_disks = mddev->raid_disks;
@@ -1518,7 +1570,7 @@ static int run(mddev_t *mddev)
1518 */ 1570 */
1519 for (j = 0; j < conf->raid_disks && 1571 for (j = 0; j < conf->raid_disks &&
1520 (!conf->mirrors[j].rdev || 1572 (!conf->mirrors[j].rdev ||
1521 !conf->mirrors[j].rdev->in_sync) ; j++) 1573 !test_bit(In_sync, &conf->mirrors[j].rdev->flags)) ; j++)
1522 /* nothing */; 1574 /* nothing */;
1523 conf->last_used = j; 1575 conf->last_used = j;
1524 1576
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index bbe40e9cf923..867f06ae33d9 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -496,6 +496,7 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
496 int disk, slot, nslot; 496 int disk, slot, nslot;
497 const int sectors = r10_bio->sectors; 497 const int sectors = r10_bio->sectors;
498 sector_t new_distance, current_distance; 498 sector_t new_distance, current_distance;
499 mdk_rdev_t *rdev;
499 500
500 raid10_find_phys(conf, r10_bio); 501 raid10_find_phys(conf, r10_bio);
501 rcu_read_lock(); 502 rcu_read_lock();
@@ -510,8 +511,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
510 slot = 0; 511 slot = 0;
511 disk = r10_bio->devs[slot].devnum; 512 disk = r10_bio->devs[slot].devnum;
512 513
513 while (!conf->mirrors[disk].rdev || 514 while ((rdev = rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
514 !conf->mirrors[disk].rdev->in_sync) { 515 !test_bit(In_sync, &rdev->flags)) {
515 slot++; 516 slot++;
516 if (slot == conf->copies) { 517 if (slot == conf->copies) {
517 slot = 0; 518 slot = 0;
@@ -527,8 +528,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
527 /* make sure the disk is operational */ 528 /* make sure the disk is operational */
528 slot = 0; 529 slot = 0;
529 disk = r10_bio->devs[slot].devnum; 530 disk = r10_bio->devs[slot].devnum;
530 while (!conf->mirrors[disk].rdev || 531 while ((rdev=rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
531 !conf->mirrors[disk].rdev->in_sync) { 532 !test_bit(In_sync, &rdev->flags)) {
532 slot ++; 533 slot ++;
533 if (slot == conf->copies) { 534 if (slot == conf->copies) {
534 disk = -1; 535 disk = -1;
@@ -547,11 +548,11 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio)
547 int ndisk = r10_bio->devs[nslot].devnum; 548 int ndisk = r10_bio->devs[nslot].devnum;
548 549
549 550
550 if (!conf->mirrors[ndisk].rdev || 551 if ((rdev=rcu_dereference(conf->mirrors[ndisk].rdev)) == NULL ||
551 !conf->mirrors[ndisk].rdev->in_sync) 552 !test_bit(In_sync, &rdev->flags))
552 continue; 553 continue;
553 554
554 if (!atomic_read(&conf->mirrors[ndisk].rdev->nr_pending)) { 555 if (!atomic_read(&rdev->nr_pending)) {
555 disk = ndisk; 556 disk = ndisk;
556 slot = nslot; 557 slot = nslot;
557 break; 558 break;
@@ -569,7 +570,7 @@ rb_out:
569 r10_bio->read_slot = slot; 570 r10_bio->read_slot = slot;
570/* conf->next_seq_sect = this_sector + sectors;*/ 571/* conf->next_seq_sect = this_sector + sectors;*/
571 572
572 if (disk >= 0 && conf->mirrors[disk].rdev) 573 if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL)
573 atomic_inc(&conf->mirrors[disk].rdev->nr_pending); 574 atomic_inc(&conf->mirrors[disk].rdev->nr_pending);
574 rcu_read_unlock(); 575 rcu_read_unlock();
575 576
@@ -583,8 +584,8 @@ static void unplug_slaves(mddev_t *mddev)
583 584
584 rcu_read_lock(); 585 rcu_read_lock();
585 for (i=0; i<mddev->raid_disks; i++) { 586 for (i=0; i<mddev->raid_disks; i++) {
586 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 587 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
587 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 588 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
588 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 589 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
589 590
590 atomic_inc(&rdev->nr_pending); 591 atomic_inc(&rdev->nr_pending);
@@ -614,8 +615,8 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk,
614 615
615 rcu_read_lock(); 616 rcu_read_lock();
616 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 617 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
617 mdk_rdev_t *rdev = conf->mirrors[i].rdev; 618 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
618 if (rdev && !rdev->faulty) { 619 if (rdev && !test_bit(Faulty, &rdev->flags)) {
619 struct block_device *bdev = rdev->bdev; 620 struct block_device *bdev = rdev->bdev;
620 request_queue_t *r_queue = bdev_get_queue(bdev); 621 request_queue_t *r_queue = bdev_get_queue(bdev);
621 622
@@ -768,9 +769,10 @@ static int make_request(request_queue_t *q, struct bio * bio)
768 rcu_read_lock(); 769 rcu_read_lock();
769 for (i = 0; i < conf->copies; i++) { 770 for (i = 0; i < conf->copies; i++) {
770 int d = r10_bio->devs[i].devnum; 771 int d = r10_bio->devs[i].devnum;
771 if (conf->mirrors[d].rdev && 772 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[d].rdev);
772 !conf->mirrors[d].rdev->faulty) { 773 if (rdev &&
773 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 774 !test_bit(Faulty, &rdev->flags)) {
775 atomic_inc(&rdev->nr_pending);
774 r10_bio->devs[i].bio = bio; 776 r10_bio->devs[i].bio = bio;
775 } else 777 } else
776 r10_bio->devs[i].bio = NULL; 778 r10_bio->devs[i].bio = NULL;
@@ -824,7 +826,7 @@ static void status(struct seq_file *seq, mddev_t *mddev)
824 for (i = 0; i < conf->raid_disks; i++) 826 for (i = 0; i < conf->raid_disks; i++)
825 seq_printf(seq, "%s", 827 seq_printf(seq, "%s",
826 conf->mirrors[i].rdev && 828 conf->mirrors[i].rdev &&
827 conf->mirrors[i].rdev->in_sync ? "U" : "_"); 829 test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_");
828 seq_printf(seq, "]"); 830 seq_printf(seq, "]");
829} 831}
830 832
@@ -839,7 +841,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
839 * next level up know. 841 * next level up know.
840 * else mark the drive as failed 842 * else mark the drive as failed
841 */ 843 */
842 if (rdev->in_sync 844 if (test_bit(In_sync, &rdev->flags)
843 && conf->working_disks == 1) 845 && conf->working_disks == 1)
844 /* 846 /*
845 * Don't fail the drive, just return an IO error. 847 * Don't fail the drive, just return an IO error.
@@ -849,7 +851,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
849 * really dead" tests... 851 * really dead" tests...
850 */ 852 */
851 return; 853 return;
852 if (rdev->in_sync) { 854 if (test_bit(In_sync, &rdev->flags)) {
853 mddev->degraded++; 855 mddev->degraded++;
854 conf->working_disks--; 856 conf->working_disks--;
855 /* 857 /*
@@ -857,8 +859,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
857 */ 859 */
858 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 860 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
859 } 861 }
860 rdev->in_sync = 0; 862 clear_bit(In_sync, &rdev->flags);
861 rdev->faulty = 1; 863 set_bit(Faulty, &rdev->flags);
862 mddev->sb_dirty = 1; 864 mddev->sb_dirty = 1;
863 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n" 865 printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n"
864 " Operation continuing on %d devices\n", 866 " Operation continuing on %d devices\n",
@@ -883,7 +885,8 @@ static void print_conf(conf_t *conf)
883 tmp = conf->mirrors + i; 885 tmp = conf->mirrors + i;
884 if (tmp->rdev) 886 if (tmp->rdev)
885 printk(" disk %d, wo:%d, o:%d, dev:%s\n", 887 printk(" disk %d, wo:%d, o:%d, dev:%s\n",
886 i, !tmp->rdev->in_sync, !tmp->rdev->faulty, 888 i, !test_bit(In_sync, &tmp->rdev->flags),
889 !test_bit(Faulty, &tmp->rdev->flags),
887 bdevname(tmp->rdev->bdev,b)); 890 bdevname(tmp->rdev->bdev,b));
888 } 891 }
889} 892}
@@ -936,11 +939,11 @@ static int raid10_spare_active(mddev_t *mddev)
936 for (i = 0; i < conf->raid_disks; i++) { 939 for (i = 0; i < conf->raid_disks; i++) {
937 tmp = conf->mirrors + i; 940 tmp = conf->mirrors + i;
938 if (tmp->rdev 941 if (tmp->rdev
939 && !tmp->rdev->faulty 942 && !test_bit(Faulty, &tmp->rdev->flags)
940 && !tmp->rdev->in_sync) { 943 && !test_bit(In_sync, &tmp->rdev->flags)) {
941 conf->working_disks++; 944 conf->working_disks++;
942 mddev->degraded--; 945 mddev->degraded--;
943 tmp->rdev->in_sync = 1; 946 set_bit(In_sync, &tmp->rdev->flags);
944 } 947 }
945 } 948 }
946 949
@@ -980,7 +983,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
980 p->head_position = 0; 983 p->head_position = 0;
981 rdev->raid_disk = mirror; 984 rdev->raid_disk = mirror;
982 found = 1; 985 found = 1;
983 p->rdev = rdev; 986 rcu_assign_pointer(p->rdev, rdev);
984 break; 987 break;
985 } 988 }
986 989
@@ -998,7 +1001,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
998 print_conf(conf); 1001 print_conf(conf);
999 rdev = p->rdev; 1002 rdev = p->rdev;
1000 if (rdev) { 1003 if (rdev) {
1001 if (rdev->in_sync || 1004 if (test_bit(In_sync, &rdev->flags) ||
1002 atomic_read(&rdev->nr_pending)) { 1005 atomic_read(&rdev->nr_pending)) {
1003 err = -EBUSY; 1006 err = -EBUSY;
1004 goto abort; 1007 goto abort;
@@ -1414,7 +1417,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1414 1417
1415 for (i=0 ; i<conf->raid_disks; i++) 1418 for (i=0 ; i<conf->raid_disks; i++)
1416 if (conf->mirrors[i].rdev && 1419 if (conf->mirrors[i].rdev &&
1417 !conf->mirrors[i].rdev->in_sync) { 1420 !test_bit(In_sync, &conf->mirrors[i].rdev->flags)) {
1418 /* want to reconstruct this device */ 1421 /* want to reconstruct this device */
1419 r10bio_t *rb2 = r10_bio; 1422 r10bio_t *rb2 = r10_bio;
1420 1423
@@ -1435,7 +1438,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1435 for (j=0; j<conf->copies;j++) { 1438 for (j=0; j<conf->copies;j++) {
1436 int d = r10_bio->devs[j].devnum; 1439 int d = r10_bio->devs[j].devnum;
1437 if (conf->mirrors[d].rdev && 1440 if (conf->mirrors[d].rdev &&
1438 conf->mirrors[d].rdev->in_sync) { 1441 test_bit(In_sync, &conf->mirrors[d].rdev->flags)) {
1439 /* This is where we read from */ 1442 /* This is where we read from */
1440 bio = r10_bio->devs[0].bio; 1443 bio = r10_bio->devs[0].bio;
1441 bio->bi_next = biolist; 1444 bio->bi_next = biolist;
@@ -1511,7 +1514,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1511 bio = r10_bio->devs[i].bio; 1514 bio = r10_bio->devs[i].bio;
1512 bio->bi_end_io = NULL; 1515 bio->bi_end_io = NULL;
1513 if (conf->mirrors[d].rdev == NULL || 1516 if (conf->mirrors[d].rdev == NULL ||
1514 conf->mirrors[d].rdev->faulty) 1517 test_bit(Faulty, &conf->mirrors[d].rdev->flags))
1515 continue; 1518 continue;
1516 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 1519 atomic_inc(&conf->mirrors[d].rdev->nr_pending);
1517 atomic_inc(&r10_bio->remaining); 1520 atomic_inc(&r10_bio->remaining);
@@ -1697,7 +1700,7 @@ static int run(mddev_t *mddev)
1697 mddev->queue->max_sectors = (PAGE_SIZE>>9); 1700 mddev->queue->max_sectors = (PAGE_SIZE>>9);
1698 1701
1699 disk->head_position = 0; 1702 disk->head_position = 0;
1700 if (!rdev->faulty && rdev->in_sync) 1703 if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags))
1701 conf->working_disks++; 1704 conf->working_disks++;
1702 } 1705 }
1703 conf->raid_disks = mddev->raid_disks; 1706 conf->raid_disks = mddev->raid_disks;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 6497295ebfb9..e2a40283e323 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -293,9 +293,31 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
293 return sh; 293 return sh;
294} 294}
295 295
296static int grow_stripes(raid5_conf_t *conf, int num) 296static int grow_one_stripe(raid5_conf_t *conf)
297{ 297{
298 struct stripe_head *sh; 298 struct stripe_head *sh;
299 sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL);
300 if (!sh)
301 return 0;
302 memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev));
303 sh->raid_conf = conf;
304 spin_lock_init(&sh->lock);
305
306 if (grow_buffers(sh, conf->raid_disks)) {
307 shrink_buffers(sh, conf->raid_disks);
308 kmem_cache_free(conf->slab_cache, sh);
309 return 0;
310 }
311 /* we just created an active stripe so... */
312 atomic_set(&sh->count, 1);
313 atomic_inc(&conf->active_stripes);
314 INIT_LIST_HEAD(&sh->lru);
315 release_stripe(sh);
316 return 1;
317}
318
319static int grow_stripes(raid5_conf_t *conf, int num)
320{
299 kmem_cache_t *sc; 321 kmem_cache_t *sc;
300 int devs = conf->raid_disks; 322 int devs = conf->raid_disks;
301 323
@@ -308,48 +330,39 @@ static int grow_stripes(raid5_conf_t *conf, int num)
308 return 1; 330 return 1;
309 conf->slab_cache = sc; 331 conf->slab_cache = sc;
310 while (num--) { 332 while (num--) {
311 sh = kmem_cache_alloc(sc, GFP_KERNEL); 333 if (!grow_one_stripe(conf))
312 if (!sh)
313 return 1;
314 memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev));
315 sh->raid_conf = conf;
316 spin_lock_init(&sh->lock);
317
318 if (grow_buffers(sh, conf->raid_disks)) {
319 shrink_buffers(sh, conf->raid_disks);
320 kmem_cache_free(sc, sh);
321 return 1; 334 return 1;
322 }
323 /* we just created an active stripe so... */
324 atomic_set(&sh->count, 1);
325 atomic_inc(&conf->active_stripes);
326 INIT_LIST_HEAD(&sh->lru);
327 release_stripe(sh);
328 } 335 }
329 return 0; 336 return 0;
330} 337}
331 338
332static void shrink_stripes(raid5_conf_t *conf) 339static int drop_one_stripe(raid5_conf_t *conf)
333{ 340{
334 struct stripe_head *sh; 341 struct stripe_head *sh;
335 342
336 while (1) { 343 spin_lock_irq(&conf->device_lock);
337 spin_lock_irq(&conf->device_lock); 344 sh = get_free_stripe(conf);
338 sh = get_free_stripe(conf); 345 spin_unlock_irq(&conf->device_lock);
339 spin_unlock_irq(&conf->device_lock); 346 if (!sh)
340 if (!sh) 347 return 0;
341 break; 348 if (atomic_read(&sh->count))
342 if (atomic_read(&sh->count)) 349 BUG();
343 BUG(); 350 shrink_buffers(sh, conf->raid_disks);
344 shrink_buffers(sh, conf->raid_disks); 351 kmem_cache_free(conf->slab_cache, sh);
345 kmem_cache_free(conf->slab_cache, sh); 352 atomic_dec(&conf->active_stripes);
346 atomic_dec(&conf->active_stripes); 353 return 1;
347 } 354}
355
356static void shrink_stripes(raid5_conf_t *conf)
357{
358 while (drop_one_stripe(conf))
359 ;
360
348 kmem_cache_destroy(conf->slab_cache); 361 kmem_cache_destroy(conf->slab_cache);
349 conf->slab_cache = NULL; 362 conf->slab_cache = NULL;
350} 363}
351 364
352static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done, 365static int raid5_end_read_request(struct bio * bi, unsigned int bytes_done,
353 int error) 366 int error)
354{ 367{
355 struct stripe_head *sh = bi->bi_private; 368 struct stripe_head *sh = bi->bi_private;
@@ -401,10 +414,35 @@ static int raid5_end_read_request (struct bio * bi, unsigned int bytes_done,
401 } 414 }
402#else 415#else
403 set_bit(R5_UPTODATE, &sh->dev[i].flags); 416 set_bit(R5_UPTODATE, &sh->dev[i].flags);
404#endif 417#endif
418 if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
419 printk("R5: read error corrected!!\n");
420 clear_bit(R5_ReadError, &sh->dev[i].flags);
421 clear_bit(R5_ReWrite, &sh->dev[i].flags);
422 }
423 if (atomic_read(&conf->disks[i].rdev->read_errors))
424 atomic_set(&conf->disks[i].rdev->read_errors, 0);
405 } else { 425 } else {
406 md_error(conf->mddev, conf->disks[i].rdev); 426 int retry = 0;
407 clear_bit(R5_UPTODATE, &sh->dev[i].flags); 427 clear_bit(R5_UPTODATE, &sh->dev[i].flags);
428 atomic_inc(&conf->disks[i].rdev->read_errors);
429 if (conf->mddev->degraded)
430 printk("R5: read error not correctable.\n");
431 else if (test_bit(R5_ReWrite, &sh->dev[i].flags))
432 /* Oh, no!!! */
433 printk("R5: read error NOT corrected!!\n");
434 else if (atomic_read(&conf->disks[i].rdev->read_errors)
435 > conf->max_nr_stripes)
436 printk("raid5: Too many read errors, failing device.\n");
437 else
438 retry = 1;
439 if (retry)
440 set_bit(R5_ReadError, &sh->dev[i].flags);
441 else {
442 clear_bit(R5_ReadError, &sh->dev[i].flags);
443 clear_bit(R5_ReWrite, &sh->dev[i].flags);
444 md_error(conf->mddev, conf->disks[i].rdev);
445 }
408 } 446 }
409 rdev_dec_pending(conf->disks[i].rdev, conf->mddev); 447 rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
410#if 0 448#if 0
@@ -487,19 +525,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
487 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 525 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
488 PRINTK("raid5: error called\n"); 526 PRINTK("raid5: error called\n");
489 527
490 if (!rdev->faulty) { 528 if (!test_bit(Faulty, &rdev->flags)) {
491 mddev->sb_dirty = 1; 529 mddev->sb_dirty = 1;
492 if (rdev->in_sync) { 530 if (test_bit(In_sync, &rdev->flags)) {
493 conf->working_disks--; 531 conf->working_disks--;
494 mddev->degraded++; 532 mddev->degraded++;
495 conf->failed_disks++; 533 conf->failed_disks++;
496 rdev->in_sync = 0; 534 clear_bit(In_sync, &rdev->flags);
497 /* 535 /*
498 * if recovery was running, make sure it aborts. 536 * if recovery was running, make sure it aborts.
499 */ 537 */
500 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 538 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
501 } 539 }
502 rdev->faulty = 1; 540 set_bit(Faulty, &rdev->flags);
503 printk (KERN_ALERT 541 printk (KERN_ALERT
504 "raid5: Disk failure on %s, disabling device." 542 "raid5: Disk failure on %s, disabling device."
505 " Operation continuing on %d devices\n", 543 " Operation continuing on %d devices\n",
@@ -965,7 +1003,13 @@ static void handle_stripe(struct stripe_head *sh)
965 } 1003 }
966 if (dev->written) written++; 1004 if (dev->written) written++;
967 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ 1005 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
968 if (!rdev || !rdev->in_sync) { 1006 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
1007 /* The ReadError flag wil just be confusing now */
1008 clear_bit(R5_ReadError, &dev->flags);
1009 clear_bit(R5_ReWrite, &dev->flags);
1010 }
1011 if (!rdev || !test_bit(In_sync, &rdev->flags)
1012 || test_bit(R5_ReadError, &dev->flags)) {
969 failed++; 1013 failed++;
970 failed_num = i; 1014 failed_num = i;
971 } else 1015 } else
@@ -980,6 +1024,14 @@ static void handle_stripe(struct stripe_head *sh)
980 if (failed > 1 && to_read+to_write+written) { 1024 if (failed > 1 && to_read+to_write+written) {
981 for (i=disks; i--; ) { 1025 for (i=disks; i--; ) {
982 int bitmap_end = 0; 1026 int bitmap_end = 0;
1027
1028 if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
1029 mdk_rdev_t *rdev = conf->disks[i].rdev;
1030 if (rdev && test_bit(In_sync, &rdev->flags))
1031 /* multiple read failures in one stripe */
1032 md_error(conf->mddev, rdev);
1033 }
1034
983 spin_lock_irq(&conf->device_lock); 1035 spin_lock_irq(&conf->device_lock);
984 /* fail all writes first */ 1036 /* fail all writes first */
985 bi = sh->dev[i].towrite; 1037 bi = sh->dev[i].towrite;
@@ -1015,7 +1067,8 @@ static void handle_stripe(struct stripe_head *sh)
1015 } 1067 }
1016 1068
1017 /* fail any reads if this device is non-operational */ 1069 /* fail any reads if this device is non-operational */
1018 if (!test_bit(R5_Insync, &sh->dev[i].flags)) { 1070 if (!test_bit(R5_Insync, &sh->dev[i].flags) ||
1071 test_bit(R5_ReadError, &sh->dev[i].flags)) {
1019 bi = sh->dev[i].toread; 1072 bi = sh->dev[i].toread;
1020 sh->dev[i].toread = NULL; 1073 sh->dev[i].toread = NULL;
1021 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags)) 1074 if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
@@ -1247,6 +1300,11 @@ static void handle_stripe(struct stripe_head *sh)
1247 !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) { 1300 !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) {
1248 /* parity is correct (on disc, not in buffer any more) */ 1301 /* parity is correct (on disc, not in buffer any more) */
1249 set_bit(STRIPE_INSYNC, &sh->state); 1302 set_bit(STRIPE_INSYNC, &sh->state);
1303 } else {
1304 conf->mddev->resync_mismatches += STRIPE_SECTORS;
1305 if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
1306 /* don't try to repair!! */
1307 set_bit(STRIPE_INSYNC, &sh->state);
1250 } 1308 }
1251 } 1309 }
1252 if (!test_bit(STRIPE_INSYNC, &sh->state)) { 1310 if (!test_bit(STRIPE_INSYNC, &sh->state)) {
@@ -1274,7 +1332,27 @@ static void handle_stripe(struct stripe_head *sh)
1274 md_done_sync(conf->mddev, STRIPE_SECTORS,1); 1332 md_done_sync(conf->mddev, STRIPE_SECTORS,1);
1275 clear_bit(STRIPE_SYNCING, &sh->state); 1333 clear_bit(STRIPE_SYNCING, &sh->state);
1276 } 1334 }
1277 1335
1336 /* If the failed drive is just a ReadError, then we might need to progress
1337 * the repair/check process
1338 */
1339 if (failed == 1 && ! conf->mddev->ro &&
1340 test_bit(R5_ReadError, &sh->dev[failed_num].flags)
1341 && !test_bit(R5_LOCKED, &sh->dev[failed_num].flags)
1342 && test_bit(R5_UPTODATE, &sh->dev[failed_num].flags)
1343 ) {
1344 dev = &sh->dev[failed_num];
1345 if (!test_bit(R5_ReWrite, &dev->flags)) {
1346 set_bit(R5_Wantwrite, &dev->flags);
1347 set_bit(R5_ReWrite, &dev->flags);
1348 set_bit(R5_LOCKED, &dev->flags);
1349 } else {
1350 /* let's read it back */
1351 set_bit(R5_Wantread, &dev->flags);
1352 set_bit(R5_LOCKED, &dev->flags);
1353 }
1354 }
1355
1278 spin_unlock(&sh->lock); 1356 spin_unlock(&sh->lock);
1279 1357
1280 while ((bi=return_bi)) { 1358 while ((bi=return_bi)) {
@@ -1305,8 +1383,8 @@ static void handle_stripe(struct stripe_head *sh)
1305 bi->bi_end_io = raid5_end_read_request; 1383 bi->bi_end_io = raid5_end_read_request;
1306 1384
1307 rcu_read_lock(); 1385 rcu_read_lock();
1308 rdev = conf->disks[i].rdev; 1386 rdev = rcu_dereference(conf->disks[i].rdev);
1309 if (rdev && rdev->faulty) 1387 if (rdev && test_bit(Faulty, &rdev->flags))
1310 rdev = NULL; 1388 rdev = NULL;
1311 if (rdev) 1389 if (rdev)
1312 atomic_inc(&rdev->nr_pending); 1390 atomic_inc(&rdev->nr_pending);
@@ -1379,8 +1457,8 @@ static void unplug_slaves(mddev_t *mddev)
1379 1457
1380 rcu_read_lock(); 1458 rcu_read_lock();
1381 for (i=0; i<mddev->raid_disks; i++) { 1459 for (i=0; i<mddev->raid_disks; i++) {
1382 mdk_rdev_t *rdev = conf->disks[i].rdev; 1460 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1383 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 1461 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
1384 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 1462 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
1385 1463
1386 atomic_inc(&rdev->nr_pending); 1464 atomic_inc(&rdev->nr_pending);
@@ -1424,8 +1502,8 @@ static int raid5_issue_flush(request_queue_t *q, struct gendisk *disk,
1424 1502
1425 rcu_read_lock(); 1503 rcu_read_lock();
1426 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 1504 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
1427 mdk_rdev_t *rdev = conf->disks[i].rdev; 1505 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1428 if (rdev && !rdev->faulty) { 1506 if (rdev && !test_bit(Faulty, &rdev->flags)) {
1429 struct block_device *bdev = rdev->bdev; 1507 struct block_device *bdev = rdev->bdev;
1430 request_queue_t *r_queue = bdev_get_queue(bdev); 1508 request_queue_t *r_queue = bdev_get_queue(bdev);
1431 1509
@@ -1567,6 +1645,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1567 return rv; 1645 return rv;
1568 } 1646 }
1569 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) && 1647 if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
1648 !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
1570 !conf->fullsync && sync_blocks >= STRIPE_SECTORS) { 1649 !conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
1571 /* we can skip this block, and probably more */ 1650 /* we can skip this block, and probably more */
1572 sync_blocks /= STRIPE_SECTORS; 1651 sync_blocks /= STRIPE_SECTORS;
@@ -1587,8 +1666,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1587 /* make sure we don't swamp the stripe cache if someone else 1666 /* make sure we don't swamp the stripe cache if someone else
1588 * is trying to get access 1667 * is trying to get access
1589 */ 1668 */
1590 set_current_state(TASK_UNINTERRUPTIBLE); 1669 schedule_timeout_uninterruptible(1);
1591 schedule_timeout(1);
1592 } 1670 }
1593 bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0); 1671 bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
1594 spin_lock(&sh->lock); 1672 spin_lock(&sh->lock);
@@ -1664,6 +1742,74 @@ static void raid5d (mddev_t *mddev)
1664 PRINTK("--- raid5d inactive\n"); 1742 PRINTK("--- raid5d inactive\n");
1665} 1743}
1666 1744
1745static ssize_t
1746raid5_show_stripe_cache_size(mddev_t *mddev, char *page)
1747{
1748 raid5_conf_t *conf = mddev_to_conf(mddev);
1749 if (conf)
1750 return sprintf(page, "%d\n", conf->max_nr_stripes);
1751 else
1752 return 0;
1753}
1754
1755static ssize_t
1756raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len)
1757{
1758 raid5_conf_t *conf = mddev_to_conf(mddev);
1759 char *end;
1760 int new;
1761 if (len >= PAGE_SIZE)
1762 return -EINVAL;
1763 if (!conf)
1764 return -ENODEV;
1765
1766 new = simple_strtoul(page, &end, 10);
1767 if (!*page || (*end && *end != '\n') )
1768 return -EINVAL;
1769 if (new <= 16 || new > 32768)
1770 return -EINVAL;
1771 while (new < conf->max_nr_stripes) {
1772 if (drop_one_stripe(conf))
1773 conf->max_nr_stripes--;
1774 else
1775 break;
1776 }
1777 while (new > conf->max_nr_stripes) {
1778 if (grow_one_stripe(conf))
1779 conf->max_nr_stripes++;
1780 else break;
1781 }
1782 return len;
1783}
1784
1785static struct md_sysfs_entry
1786raid5_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR,
1787 raid5_show_stripe_cache_size,
1788 raid5_store_stripe_cache_size);
1789
1790static ssize_t
1791stripe_cache_active_show(mddev_t *mddev, char *page)
1792{
1793 raid5_conf_t *conf = mddev_to_conf(mddev);
1794 if (conf)
1795 return sprintf(page, "%d\n", atomic_read(&conf->active_stripes));
1796 else
1797 return 0;
1798}
1799
1800static struct md_sysfs_entry
1801raid5_stripecache_active = __ATTR_RO(stripe_cache_active);
1802
1803static struct attribute *raid5_attrs[] = {
1804 &raid5_stripecache_size.attr,
1805 &raid5_stripecache_active.attr,
1806 NULL,
1807};
1808static struct attribute_group raid5_attrs_group = {
1809 .name = NULL,
1810 .attrs = raid5_attrs,
1811};
1812
1667static int run(mddev_t *mddev) 1813static int run(mddev_t *mddev)
1668{ 1814{
1669 raid5_conf_t *conf; 1815 raid5_conf_t *conf;
@@ -1710,7 +1856,7 @@ static int run(mddev_t *mddev)
1710 1856
1711 disk->rdev = rdev; 1857 disk->rdev = rdev;
1712 1858
1713 if (rdev->in_sync) { 1859 if (test_bit(In_sync, &rdev->flags)) {
1714 char b[BDEVNAME_SIZE]; 1860 char b[BDEVNAME_SIZE];
1715 printk(KERN_INFO "raid5: device %s operational as raid" 1861 printk(KERN_INFO "raid5: device %s operational as raid"
1716 " disk %d\n", bdevname(rdev->bdev,b), 1862 " disk %d\n", bdevname(rdev->bdev,b),
@@ -1805,6 +1951,7 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
1805 } 1951 }
1806 1952
1807 /* Ok, everything is just fine now */ 1953 /* Ok, everything is just fine now */
1954 sysfs_create_group(&mddev->kobj, &raid5_attrs_group);
1808 1955
1809 if (mddev->bitmap) 1956 if (mddev->bitmap)
1810 mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ; 1957 mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
@@ -1829,7 +1976,7 @@ abort:
1829 1976
1830 1977
1831 1978
1832static int stop (mddev_t *mddev) 1979static int stop(mddev_t *mddev)
1833{ 1980{
1834 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 1981 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
1835 1982
@@ -1838,6 +1985,7 @@ static int stop (mddev_t *mddev)
1838 shrink_stripes(conf); 1985 shrink_stripes(conf);
1839 free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER); 1986 free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
1840 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 1987 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
1988 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
1841 kfree(conf); 1989 kfree(conf);
1842 mddev->private = NULL; 1990 mddev->private = NULL;
1843 return 0; 1991 return 0;
@@ -1888,7 +2036,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
1888 for (i = 0; i < conf->raid_disks; i++) 2036 for (i = 0; i < conf->raid_disks; i++)
1889 seq_printf (seq, "%s", 2037 seq_printf (seq, "%s",
1890 conf->disks[i].rdev && 2038 conf->disks[i].rdev &&
1891 conf->disks[i].rdev->in_sync ? "U" : "_"); 2039 test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
1892 seq_printf (seq, "]"); 2040 seq_printf (seq, "]");
1893#if RAID5_DEBUG 2041#if RAID5_DEBUG
1894#define D(x) \ 2042#define D(x) \
@@ -1915,7 +2063,7 @@ static void print_raid5_conf (raid5_conf_t *conf)
1915 tmp = conf->disks + i; 2063 tmp = conf->disks + i;
1916 if (tmp->rdev) 2064 if (tmp->rdev)
1917 printk(" disk %d, o:%d, dev:%s\n", 2065 printk(" disk %d, o:%d, dev:%s\n",
1918 i, !tmp->rdev->faulty, 2066 i, !test_bit(Faulty, &tmp->rdev->flags),
1919 bdevname(tmp->rdev->bdev,b)); 2067 bdevname(tmp->rdev->bdev,b));
1920 } 2068 }
1921} 2069}
@@ -1929,12 +2077,12 @@ static int raid5_spare_active(mddev_t *mddev)
1929 for (i = 0; i < conf->raid_disks; i++) { 2077 for (i = 0; i < conf->raid_disks; i++) {
1930 tmp = conf->disks + i; 2078 tmp = conf->disks + i;
1931 if (tmp->rdev 2079 if (tmp->rdev
1932 && !tmp->rdev->faulty 2080 && !test_bit(Faulty, &tmp->rdev->flags)
1933 && !tmp->rdev->in_sync) { 2081 && !test_bit(In_sync, &tmp->rdev->flags)) {
1934 mddev->degraded--; 2082 mddev->degraded--;
1935 conf->failed_disks--; 2083 conf->failed_disks--;
1936 conf->working_disks++; 2084 conf->working_disks++;
1937 tmp->rdev->in_sync = 1; 2085 set_bit(In_sync, &tmp->rdev->flags);
1938 } 2086 }
1939 } 2087 }
1940 print_raid5_conf(conf); 2088 print_raid5_conf(conf);
@@ -1951,7 +2099,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
1951 print_raid5_conf(conf); 2099 print_raid5_conf(conf);
1952 rdev = p->rdev; 2100 rdev = p->rdev;
1953 if (rdev) { 2101 if (rdev) {
1954 if (rdev->in_sync || 2102 if (test_bit(In_sync, &rdev->flags) ||
1955 atomic_read(&rdev->nr_pending)) { 2103 atomic_read(&rdev->nr_pending)) {
1956 err = -EBUSY; 2104 err = -EBUSY;
1957 goto abort; 2105 goto abort;
@@ -1986,12 +2134,12 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
1986 */ 2134 */
1987 for (disk=0; disk < mddev->raid_disks; disk++) 2135 for (disk=0; disk < mddev->raid_disks; disk++)
1988 if ((p=conf->disks + disk)->rdev == NULL) { 2136 if ((p=conf->disks + disk)->rdev == NULL) {
1989 rdev->in_sync = 0; 2137 clear_bit(In_sync, &rdev->flags);
1990 rdev->raid_disk = disk; 2138 rdev->raid_disk = disk;
1991 found = 1; 2139 found = 1;
1992 if (rdev->saved_raid_disk != disk) 2140 if (rdev->saved_raid_disk != disk)
1993 conf->fullsync = 1; 2141 conf->fullsync = 1;
1994 p->rdev = rdev; 2142 rcu_assign_pointer(p->rdev, rdev);
1995 break; 2143 break;
1996 } 2144 }
1997 print_raid5_conf(conf); 2145 print_raid5_conf(conf);
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index 6437a95ffc1c..eae5a35629c5 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -507,19 +507,19 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
507 raid6_conf_t *conf = (raid6_conf_t *) mddev->private; 507 raid6_conf_t *conf = (raid6_conf_t *) mddev->private;
508 PRINTK("raid6: error called\n"); 508 PRINTK("raid6: error called\n");
509 509
510 if (!rdev->faulty) { 510 if (!test_bit(Faulty, &rdev->flags)) {
511 mddev->sb_dirty = 1; 511 mddev->sb_dirty = 1;
512 if (rdev->in_sync) { 512 if (test_bit(In_sync, &rdev->flags)) {
513 conf->working_disks--; 513 conf->working_disks--;
514 mddev->degraded++; 514 mddev->degraded++;
515 conf->failed_disks++; 515 conf->failed_disks++;
516 rdev->in_sync = 0; 516 clear_bit(In_sync, &rdev->flags);
517 /* 517 /*
518 * if recovery was running, make sure it aborts. 518 * if recovery was running, make sure it aborts.
519 */ 519 */
520 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 520 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
521 } 521 }
522 rdev->faulty = 1; 522 set_bit(Faulty, &rdev->flags);
523 printk (KERN_ALERT 523 printk (KERN_ALERT
524 "raid6: Disk failure on %s, disabling device." 524 "raid6: Disk failure on %s, disabling device."
525 " Operation continuing on %d devices\n", 525 " Operation continuing on %d devices\n",
@@ -1071,7 +1071,7 @@ static void handle_stripe(struct stripe_head *sh)
1071 } 1071 }
1072 if (dev->written) written++; 1072 if (dev->written) written++;
1073 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */ 1073 rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
1074 if (!rdev || !rdev->in_sync) { 1074 if (!rdev || !test_bit(In_sync, &rdev->flags)) {
1075 if ( failed < 2 ) 1075 if ( failed < 2 )
1076 failed_num[failed] = i; 1076 failed_num[failed] = i;
1077 failed++; 1077 failed++;
@@ -1464,8 +1464,8 @@ static void handle_stripe(struct stripe_head *sh)
1464 bi->bi_end_io = raid6_end_read_request; 1464 bi->bi_end_io = raid6_end_read_request;
1465 1465
1466 rcu_read_lock(); 1466 rcu_read_lock();
1467 rdev = conf->disks[i].rdev; 1467 rdev = rcu_dereference(conf->disks[i].rdev);
1468 if (rdev && rdev->faulty) 1468 if (rdev && test_bit(Faulty, &rdev->flags))
1469 rdev = NULL; 1469 rdev = NULL;
1470 if (rdev) 1470 if (rdev)
1471 atomic_inc(&rdev->nr_pending); 1471 atomic_inc(&rdev->nr_pending);
@@ -1538,8 +1538,8 @@ static void unplug_slaves(mddev_t *mddev)
1538 1538
1539 rcu_read_lock(); 1539 rcu_read_lock();
1540 for (i=0; i<mddev->raid_disks; i++) { 1540 for (i=0; i<mddev->raid_disks; i++) {
1541 mdk_rdev_t *rdev = conf->disks[i].rdev; 1541 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1542 if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { 1542 if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) {
1543 request_queue_t *r_queue = bdev_get_queue(rdev->bdev); 1543 request_queue_t *r_queue = bdev_get_queue(rdev->bdev);
1544 1544
1545 atomic_inc(&rdev->nr_pending); 1545 atomic_inc(&rdev->nr_pending);
@@ -1583,8 +1583,8 @@ static int raid6_issue_flush(request_queue_t *q, struct gendisk *disk,
1583 1583
1584 rcu_read_lock(); 1584 rcu_read_lock();
1585 for (i=0; i<mddev->raid_disks && ret == 0; i++) { 1585 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
1586 mdk_rdev_t *rdev = conf->disks[i].rdev; 1586 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
1587 if (rdev && !rdev->faulty) { 1587 if (rdev && !test_bit(Faulty, &rdev->flags)) {
1588 struct block_device *bdev = rdev->bdev; 1588 struct block_device *bdev = rdev->bdev;
1589 request_queue_t *r_queue = bdev_get_queue(bdev); 1589 request_queue_t *r_queue = bdev_get_queue(bdev);
1590 1590
@@ -1746,8 +1746,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
1746 /* make sure we don't swamp the stripe cache if someone else 1746 /* make sure we don't swamp the stripe cache if someone else
1747 * is trying to get access 1747 * is trying to get access
1748 */ 1748 */
1749 set_current_state(TASK_UNINTERRUPTIBLE); 1749 schedule_timeout_uninterruptible(1);
1750 schedule_timeout(1);
1751 } 1750 }
1752 bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0); 1751 bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
1753 spin_lock(&sh->lock); 1752 spin_lock(&sh->lock);
@@ -1869,7 +1868,7 @@ static int run(mddev_t *mddev)
1869 1868
1870 disk->rdev = rdev; 1869 disk->rdev = rdev;
1871 1870
1872 if (rdev->in_sync) { 1871 if (test_bit(In_sync, &rdev->flags)) {
1873 char b[BDEVNAME_SIZE]; 1872 char b[BDEVNAME_SIZE];
1874 printk(KERN_INFO "raid6: device %s operational as raid" 1873 printk(KERN_INFO "raid6: device %s operational as raid"
1875 " disk %d\n", bdevname(rdev->bdev,b), 1874 " disk %d\n", bdevname(rdev->bdev,b),
@@ -2053,7 +2052,7 @@ static void status (struct seq_file *seq, mddev_t *mddev)
2053 for (i = 0; i < conf->raid_disks; i++) 2052 for (i = 0; i < conf->raid_disks; i++)
2054 seq_printf (seq, "%s", 2053 seq_printf (seq, "%s",
2055 conf->disks[i].rdev && 2054 conf->disks[i].rdev &&
2056 conf->disks[i].rdev->in_sync ? "U" : "_"); 2055 test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_");
2057 seq_printf (seq, "]"); 2056 seq_printf (seq, "]");
2058#if RAID6_DUMPSTATE 2057#if RAID6_DUMPSTATE
2059 seq_printf (seq, "\n"); 2058 seq_printf (seq, "\n");
@@ -2079,7 +2078,7 @@ static void print_raid6_conf (raid6_conf_t *conf)
2079 tmp = conf->disks + i; 2078 tmp = conf->disks + i;
2080 if (tmp->rdev) 2079 if (tmp->rdev)
2081 printk(" disk %d, o:%d, dev:%s\n", 2080 printk(" disk %d, o:%d, dev:%s\n",
2082 i, !tmp->rdev->faulty, 2081 i, !test_bit(Faulty, &tmp->rdev->flags),
2083 bdevname(tmp->rdev->bdev,b)); 2082 bdevname(tmp->rdev->bdev,b));
2084 } 2083 }
2085} 2084}
@@ -2093,12 +2092,12 @@ static int raid6_spare_active(mddev_t *mddev)
2093 for (i = 0; i < conf->raid_disks; i++) { 2092 for (i = 0; i < conf->raid_disks; i++) {
2094 tmp = conf->disks + i; 2093 tmp = conf->disks + i;
2095 if (tmp->rdev 2094 if (tmp->rdev
2096 && !tmp->rdev->faulty 2095 && !test_bit(Faulty, &tmp->rdev->flags)
2097 && !tmp->rdev->in_sync) { 2096 && !test_bit(In_sync, &tmp->rdev->flags)) {
2098 mddev->degraded--; 2097 mddev->degraded--;
2099 conf->failed_disks--; 2098 conf->failed_disks--;
2100 conf->working_disks++; 2099 conf->working_disks++;
2101 tmp->rdev->in_sync = 1; 2100 set_bit(In_sync, &tmp->rdev->flags);
2102 } 2101 }
2103 } 2102 }
2104 print_raid6_conf(conf); 2103 print_raid6_conf(conf);
@@ -2115,7 +2114,7 @@ static int raid6_remove_disk(mddev_t *mddev, int number)
2115 print_raid6_conf(conf); 2114 print_raid6_conf(conf);
2116 rdev = p->rdev; 2115 rdev = p->rdev;
2117 if (rdev) { 2116 if (rdev) {
2118 if (rdev->in_sync || 2117 if (test_bit(In_sync, &rdev->flags) ||
2119 atomic_read(&rdev->nr_pending)) { 2118 atomic_read(&rdev->nr_pending)) {
2120 err = -EBUSY; 2119 err = -EBUSY;
2121 goto abort; 2120 goto abort;
@@ -2150,12 +2149,12 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
2150 */ 2149 */
2151 for (disk=0; disk < mddev->raid_disks; disk++) 2150 for (disk=0; disk < mddev->raid_disks; disk++)
2152 if ((p=conf->disks + disk)->rdev == NULL) { 2151 if ((p=conf->disks + disk)->rdev == NULL) {
2153 rdev->in_sync = 0; 2152 clear_bit(In_sync, &rdev->flags);
2154 rdev->raid_disk = disk; 2153 rdev->raid_disk = disk;
2155 found = 1; 2154 found = 1;
2156 if (rdev->saved_raid_disk != disk) 2155 if (rdev->saved_raid_disk != disk)
2157 conf->fullsync = 1; 2156 conf->fullsync = 1;
2158 p->rdev = rdev; 2157 rcu_assign_pointer(p->rdev, rdev);
2159 break; 2158 break;
2160 } 2159 }
2161 print_raid6_conf(conf); 2160 print_raid6_conf(conf);
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 31fccb4f05d6..4b71fd6f7aed 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -116,7 +116,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
116 [ 46 ] = KEY_BLUE, 116 [ 46 ] = KEY_BLUE,
117 [ 24 ] = KEY_KPPLUS, /* fine tune + */ 117 [ 24 ] = KEY_KPPLUS, /* fine tune + */
118 [ 25 ] = KEY_KPMINUS, /* fine tune - */ 118 [ 25 ] = KEY_KPMINUS, /* fine tune - */
119 [ 33 ] = KEY_KPDOT, 119 [ 33 ] = KEY_KPDOT,
120 [ 19 ] = KEY_KPENTER, 120 [ 19 ] = KEY_KPENTER,
121 [ 34 ] = KEY_BACK, 121 [ 34 ] = KEY_BACK,
122 [ 35 ] = KEY_PLAYPAUSE, 122 [ 35 ] = KEY_PLAYPAUSE,
@@ -239,7 +239,7 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
239 dprintk(1,"%s: key event code=%d down=%d\n", 239 dprintk(1,"%s: key event code=%d down=%d\n",
240 dev->name,ir->keycode,ir->keypressed); 240 dev->name,ir->keycode,ir->keypressed);
241 input_report_key(dev,ir->keycode,ir->keypressed); 241 input_report_key(dev,ir->keycode,ir->keypressed);
242 input_sync(dev); 242 input_sync(dev);
243} 243}
244 244
245/* -------------------------------------------------------------------------- */ 245/* -------------------------------------------------------------------------- */
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 47e28b0ee951..a35330315f65 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -13,6 +13,8 @@
13#include "bcm3510.h" 13#include "bcm3510.h"
14#include "stv0297.h" 14#include "stv0297.h"
15#include "mt312.h" 15#include "mt312.h"
16#include "lgdt330x.h"
17#include "dvb-pll.h"
16 18
17/* lnb control */ 19/* lnb control */
18 20
@@ -234,7 +236,6 @@ static struct stv0299_config samsung_tbmu24112_config = {
234 .inittab = samsung_tbmu24112_inittab, 236 .inittab = samsung_tbmu24112_inittab,
235 .mclk = 88000000UL, 237 .mclk = 88000000UL,
236 .invert = 0, 238 .invert = 0,
237 .enhanced_tuning = 0,
238 .skip_reinit = 0, 239 .skip_reinit = 0,
239 .lock_output = STV0229_LOCKOUTPUT_LK, 240 .lock_output = STV0229_LOCKOUTPUT_LK,
240 .volt13_op0_op1 = STV0299_VOLT13_OP1, 241 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -296,6 +297,52 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir
296 return request_firmware(fw, name, fc->dev); 297 return request_firmware(fw, name, fc->dev);
297} 298}
298 299
300static int lgdt3303_pll_set(struct dvb_frontend* fe,
301 struct dvb_frontend_parameters* params)
302{
303 struct flexcop_device *fc = fe->dvb->priv;
304 u8 buf[4];
305 struct i2c_msg msg =
306 { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 };
307 int err;
308
309 dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0);
310 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
311 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
312 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
313 printk(KERN_WARNING "lgdt3303: %s error "
314 "(addr %02x <- %02x, err = %i)\n",
315 __FUNCTION__, buf[0], buf[1], err);
316 if (err < 0)
317 return err;
318 else
319 return -EREMOTEIO;
320 }
321
322 buf[0] = 0x86 | 0x18;
323 buf[1] = 0x50;
324 msg.len = 2;
325 if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
326 printk(KERN_WARNING "lgdt3303: %s error "
327 "(addr %02x <- %02x, err = %i)\n",
328 __FUNCTION__, buf[0], buf[1], err);
329 if (err < 0)
330 return err;
331 else
332 return -EREMOTEIO;
333 }
334
335 return 0;
336}
337
338static struct lgdt330x_config air2pc_atsc_hd5000_config = {
339 .demod_address = 0x59,
340 .demod_chip = LGDT3303,
341 .serial_mpeg = 0x04,
342 .pll_set = lgdt3303_pll_set,
343 .clock_polarity_flip = 1,
344};
345
299static struct nxt2002_config samsung_tbmv_config = { 346static struct nxt2002_config samsung_tbmv_config = {
300 .demod_address = 0x0a, 347 .demod_address = 0x0a,
301 .request_firmware = flexcop_fe_request_firmware, 348 .request_firmware = flexcop_fe_request_firmware,
@@ -458,6 +505,11 @@ int flexcop_frontend_init(struct flexcop_device *fc)
458 fc->dev_type = FC_AIR_ATSC2; 505 fc->dev_type = FC_AIR_ATSC2;
459 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); 506 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
460 } else 507 } else
508 /* try the air atsc 3nd generation (lgdt3303) */
509 if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
510 fc->dev_type = FC_AIR_ATSC3;
511 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
512 } else
461 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ 513 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
462 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) { 514 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
463 fc->dev_type = FC_AIR_ATSC1; 515 fc->dev_type = FC_AIR_ATSC1;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 3a08d38b318a..62282d8dbfa8 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -51,6 +51,7 @@ const char *flexcop_device_names[] = {
51 "Sky2PC/SkyStar 2 DVB-S", 51 "Sky2PC/SkyStar 2 DVB-S",
52 "Sky2PC/SkyStar 2 DVB-S (old version)", 52 "Sky2PC/SkyStar 2 DVB-S (old version)",
53 "Cable2PC/CableStar 2 DVB-C", 53 "Cable2PC/CableStar 2 DVB-C",
54 "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
54}; 55};
55 56
56const char *flexcop_bus_names[] = { 57const char *flexcop_bus_names[] = {
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 4ae1eb5bfe98..23cc6431e2b8 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -26,6 +26,7 @@ typedef enum {
26 FC_SKY, 26 FC_SKY,
27 FC_SKY_OLD, 27 FC_SKY_OLD,
28 FC_CABLE, 28 FC_CABLE,
29 FC_AIR_ATSC3,
29} flexcop_device_type_t; 30} flexcop_device_type_t;
30 31
31typedef enum { 32typedef enum {
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 12873d435406..123ed96f6faa 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -193,6 +193,7 @@ static void flexcop_reset(struct flexcop_device *fc)
193 v204 = fc->read_ibi_reg(fc,misc_204); 193 v204 = fc->read_ibi_reg(fc,misc_204);
194 v204.misc_204.Per_reset_sig = 0; 194 v204.misc_204.Per_reset_sig = 0;
195 fc->write_ibi_reg(fc,misc_204,v204); 195 fc->write_ibi_reg(fc,misc_204,v204);
196 msleep(1);
196 v204.misc_204.Per_reset_sig = 1; 197 v204.misc_204.Per_reset_sig = 1;
197 fc->write_ibi_reg(fc,misc_204,v204); 198 fc->write_ibi_reg(fc,misc_204,v204);
198} 199}
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 1e85d16491b0..2337b41714e0 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -6,10 +6,12 @@ config DVB_BT8XX
6 select DVB_NXT6000 6 select DVB_NXT6000
7 select DVB_CX24110 7 select DVB_CX24110
8 select DVB_OR51211 8 select DVB_OR51211
9 select DVB_LGDT330X
9 help 10 help
10 Support for PCI cards based on the Bt8xx PCI bridge. Examples are 11 Support for PCI cards based on the Bt8xx PCI bridge. Examples are
11 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, 12 the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
12 the pcHDTV HD2000 cards, and certain AVerMedia cards. 13 the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and
14 some AVerMedia cards.
13 15
14 Since these cards have no MPEG decoder onboard, they transmit 16 Since these cards have no MPEG decoder onboard, they transmit
15 only compressed MPEG data over the PCI bus, so you need 17 only compressed MPEG data over the PCI bus, so you need
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c
index 34a837a1abf4..8977c7a313df 100644
--- a/drivers/media/dvb/bt8xx/dst.c
+++ b/drivers/media/dvb/bt8xx/dst.c
@@ -690,8 +690,8 @@ struct dst_types dst_tlist[] = {
690 .device_id = "DTT-CI", 690 .device_id = "DTT-CI",
691 .offset = 1, 691 .offset = 1,
692 .dst_type = DST_TYPE_IS_TERR, 692 .dst_type = DST_TYPE_IS_TERR,
693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, 693 .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE,
694 .dst_feature = 0 694 .dst_feature = DST_TYPE_HAS_CA
695 }, 695 },
696 696
697 { 697 {
@@ -796,6 +796,56 @@ static int dst_get_vendor(struct dst_state *state)
796 return 0; 796 return 0;
797} 797}
798 798
799static int dst_get_tuner_info(struct dst_state *state)
800{
801 u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
802 u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
803
804 get_tuner_1[7] = dst_check_sum(get_tuner_1, 7);
805 get_tuner_2[7] = dst_check_sum(get_tuner_2, 7);
806 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
807 if (dst_command(state, get_tuner_2, 8) < 0) {
808 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
809 return -1;
810 }
811 } else {
812 if (dst_command(state, get_tuner_1, 8) < 0) {
813 dprintk(verbose, DST_INFO, 1, "Unsupported Command");
814 return -1;
815 }
816 }
817 memset(&state->board_info, '\0', 8);
818 memcpy(&state->board_info, &state->rxbuffer, 8);
819 if (state->type_flags & DST_TYPE_HAS_MULTI_FE) {
820 if (state->board_info[1] == 0x0b) {
821 if (state->type_flags & DST_TYPE_HAS_TS204)
822 state->type_flags &= ~DST_TYPE_HAS_TS204;
823 state->type_flags |= DST_TYPE_HAS_NEWTUNE;
824 dprintk(verbose, DST_INFO, 1, "DST type has TS=188");
825 } else {
826 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
827 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
828 state->type_flags |= DST_TYPE_HAS_TS204;
829 dprintk(verbose, DST_INFO, 1, "DST type has TS=204");
830 }
831 } else {
832 if (state->board_info[0] == 0xbc) {
833 if (state->type_flags & DST_TYPE_HAS_TS204)
834 state->type_flags &= ~DST_TYPE_HAS_TS204;
835 state->type_flags |= DST_TYPE_HAS_NEWTUNE;
836 dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]);
837
838 } else if (state->board_info[0] == 0xcc) {
839 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
840 state->type_flags &= ~DST_TYPE_HAS_NEWTUNE;
841 state->type_flags |= DST_TYPE_HAS_TS204;
842 dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]);
843 }
844 }
845
846 return 0;
847}
848
799static int dst_get_device_id(struct dst_state *state) 849static int dst_get_device_id(struct dst_state *state)
800{ 850{
801 u8 reply; 851 u8 reply;
@@ -855,15 +905,12 @@ static int dst_get_device_id(struct dst_state *state)
855 state->dst_type = use_dst_type; 905 state->dst_type = use_dst_type;
856 dst_type_flags_print(state->type_flags); 906 dst_type_flags_print(state->type_flags);
857 907
858 if (state->type_flags & DST_TYPE_HAS_TS204) {
859 dst_packsize(state, 204);
860 }
861
862 return 0; 908 return 0;
863} 909}
864 910
865static int dst_probe(struct dst_state *state) 911static int dst_probe(struct dst_state *state)
866{ 912{
913 sema_init(&state->dst_mutex, 1);
867 if ((rdc_8820_reset(state)) < 0) { 914 if ((rdc_8820_reset(state)) < 0) {
868 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); 915 dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed.");
869 return -1; 916 return -1;
@@ -886,6 +933,13 @@ static int dst_probe(struct dst_state *state)
886 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); 933 dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command");
887 return 0; 934 return 0;
888 } 935 }
936 if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) {
937 if (dst_get_tuner_info(state) < 0)
938 dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command");
939 }
940 if (state->type_flags & DST_TYPE_HAS_TS204) {
941 dst_packsize(state, 204);
942 }
889 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { 943 if (state->type_flags & DST_TYPE_HAS_FW_BUILD) {
890 if (dst_fw_ver(state) < 0) { 944 if (dst_fw_ver(state) < 0) {
891 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); 945 dprintk(verbose, DST_INFO, 1, "FW: Unsupported command");
@@ -907,21 +961,23 @@ static int dst_probe(struct dst_state *state)
907int dst_command(struct dst_state *state, u8 *data, u8 len) 961int dst_command(struct dst_state *state, u8 *data, u8 len)
908{ 962{
909 u8 reply; 963 u8 reply;
964
965 down(&state->dst_mutex);
910 if ((dst_comm_init(state)) < 0) { 966 if ((dst_comm_init(state)) < 0) {
911 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); 967 dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed.");
912 return -1; 968 goto error;
913 } 969 }
914 if (write_dst(state, data, len)) { 970 if (write_dst(state, data, len)) {
915 dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); 971 dprintk(verbose, DST_INFO, 1, "Tring to recover.. ");
916 if ((dst_error_recovery(state)) < 0) { 972 if ((dst_error_recovery(state)) < 0) {
917 dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); 973 dprintk(verbose, DST_ERROR, 1, "Recovery Failed.");
918 return -1; 974 goto error;
919 } 975 }
920 return -1; 976 goto error;
921 } 977 }
922 if ((dst_pio_disable(state)) < 0) { 978 if ((dst_pio_disable(state)) < 0) {
923 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); 979 dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed.");
924 return -1; 980 goto error;
925 } 981 }
926 if (state->type_flags & DST_TYPE_HAS_FW_1) 982 if (state->type_flags & DST_TYPE_HAS_FW_1)
927 udelay(3000); 983 udelay(3000);
@@ -929,36 +985,41 @@ int dst_command(struct dst_state *state, u8 *data, u8 len)
929 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); 985 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
930 if ((dst_error_recovery(state)) < 0) { 986 if ((dst_error_recovery(state)) < 0) {
931 dprintk(verbose, DST_INFO, 1, "Recovery Failed."); 987 dprintk(verbose, DST_INFO, 1, "Recovery Failed.");
932 return -1; 988 goto error;
933 } 989 }
934 return -1; 990 goto error;
935 } 991 }
936 if (reply != ACK) { 992 if (reply != ACK) {
937 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); 993 dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply);
938 return -1; 994 goto error;
939 } 995 }
940 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) 996 if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3))
941 return 0; 997 goto error;
942 if (state->type_flags & DST_TYPE_HAS_FW_1) 998 if (state->type_flags & DST_TYPE_HAS_FW_1)
943 udelay(3000); 999 udelay(3000);
944 else 1000 else
945 udelay(2000); 1001 udelay(2000);
946 if (!dst_wait_dst_ready(state, NO_DELAY)) 1002 if (!dst_wait_dst_ready(state, NO_DELAY))
947 return -1; 1003 goto error;
948 if (read_dst(state, state->rxbuffer, FIXED_COMM)) { 1004 if (read_dst(state, state->rxbuffer, FIXED_COMM)) {
949 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); 1005 dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. ");
950 if ((dst_error_recovery(state)) < 0) { 1006 if ((dst_error_recovery(state)) < 0) {
951 dprintk(verbose, DST_INFO, 1, "Recovery failed."); 1007 dprintk(verbose, DST_INFO, 1, "Recovery failed.");
952 return -1; 1008 goto error;
953 } 1009 }
954 return -1; 1010 goto error;
955 } 1011 }
956 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { 1012 if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) {
957 dprintk(verbose, DST_INFO, 1, "checksum failure"); 1013 dprintk(verbose, DST_INFO, 1, "checksum failure");
958 return -1; 1014 goto error;
959 } 1015 }
960 1016 up(&state->dst_mutex);
961 return 0; 1017 return 0;
1018
1019error:
1020 up(&state->dst_mutex);
1021 return -EIO;
1022
962} 1023}
963EXPORT_SYMBOL(dst_command); 1024EXPORT_SYMBOL(dst_command);
964 1025
@@ -1016,7 +1077,7 @@ static int dst_get_tuna(struct dst_state *state)
1016 return 0; 1077 return 0;
1017 state->diseq_flags &= ~(HAS_LOCK); 1078 state->diseq_flags &= ~(HAS_LOCK);
1018 if (!dst_wait_dst_ready(state, NO_DELAY)) 1079 if (!dst_wait_dst_ready(state, NO_DELAY))
1019 return 0; 1080 return -EIO;
1020 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) 1081 if (state->type_flags & DST_TYPE_HAS_NEWTUNE)
1021 /* how to get variable length reply ???? */ 1082 /* how to get variable length reply ???? */
1022 retval = read_dst(state, state->rx_tuna, 10); 1083 retval = read_dst(state, state->rx_tuna, 10);
@@ -1024,22 +1085,27 @@ static int dst_get_tuna(struct dst_state *state)
1024 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); 1085 retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM);
1025 if (retval < 0) { 1086 if (retval < 0) {
1026 dprintk(verbose, DST_DEBUG, 1, "read not successful"); 1087 dprintk(verbose, DST_DEBUG, 1, "read not successful");
1027 return 0; 1088 return retval;
1028 } 1089 }
1029 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1090 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1030 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { 1091 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) {
1031 dprintk(verbose, DST_INFO, 1, "checksum failure ? "); 1092 dprintk(verbose, DST_INFO, 1, "checksum failure ? ");
1032 return 0; 1093 return -EIO;
1033 } 1094 }
1034 } else { 1095 } else {
1035 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { 1096 if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) {
1036 dprintk(verbose, DST_INFO, 1, "checksum failure? "); 1097 dprintk(verbose, DST_INFO, 1, "checksum failure? ");
1037 return 0; 1098 return -EIO;
1038 } 1099 }
1039 } 1100 }
1040 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) 1101 if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0)
1041 return 0; 1102 return 0;
1042 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; 1103 if (state->dst_type == DST_TYPE_IS_SAT) {
1104 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3];
1105 } else {
1106 state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4];
1107 }
1108 state->decode_freq = state->decode_freq * 1000;
1043 state->decode_lock = 1; 1109 state->decode_lock = 1;
1044 state->diseq_flags |= HAS_LOCK; 1110 state->diseq_flags |= HAS_LOCK;
1045 1111
@@ -1062,10 +1128,10 @@ static int dst_write_tuna(struct dvb_frontend *fe)
1062 dst_set_voltage(fe, SEC_VOLTAGE_13); 1128 dst_set_voltage(fe, SEC_VOLTAGE_13);
1063 } 1129 }
1064 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); 1130 state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE);
1065 1131 down(&state->dst_mutex);
1066 if ((dst_comm_init(state)) < 0) { 1132 if ((dst_comm_init(state)) < 0) {
1067 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); 1133 dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed.");
1068 return -1; 1134 goto error;
1069 } 1135 }
1070 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { 1136 if (state->type_flags & DST_TYPE_HAS_NEWTUNE) {
1071 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); 1137 state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9);
@@ -1077,23 +1143,29 @@ static int dst_write_tuna(struct dvb_frontend *fe)
1077 if (retval < 0) { 1143 if (retval < 0) {
1078 dst_pio_disable(state); 1144 dst_pio_disable(state);
1079 dprintk(verbose, DST_DEBUG, 1, "write not successful"); 1145 dprintk(verbose, DST_DEBUG, 1, "write not successful");
1080 return retval; 1146 goto werr;
1081 } 1147 }
1082 if ((dst_pio_disable(state)) < 0) { 1148 if ((dst_pio_disable(state)) < 0) {
1083 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); 1149 dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !");
1084 return -1; 1150 goto error;
1085 } 1151 }
1086 if ((read_dst(state, &reply, GET_ACK) < 0)) { 1152 if ((read_dst(state, &reply, GET_ACK) < 0)) {
1087 dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); 1153 dprintk(verbose, DST_DEBUG, 1, "read verify not successful.");
1088 return -1; 1154 goto error;
1089 } 1155 }
1090 if (reply != ACK) { 1156 if (reply != ACK) {
1091 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); 1157 dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply);
1092 return 0; 1158 goto error;
1093 } 1159 }
1094 state->diseq_flags |= ATTEMPT_TUNE; 1160 state->diseq_flags |= ATTEMPT_TUNE;
1095 1161 retval = dst_get_tuna(state);
1096 return dst_get_tuna(state); 1162werr:
1163 up(&state->dst_mutex);
1164 return retval;
1165
1166error:
1167 up(&state->dst_mutex);
1168 return -EIO;
1097} 1169}
1098 1170
1099/* 1171/*
@@ -1331,9 +1403,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
1331{ 1403{
1332 /* check if the ASIC is there */ 1404 /* check if the ASIC is there */
1333 if (dst_probe(state) < 0) { 1405 if (dst_probe(state) < 0) {
1334 if (state) 1406 kfree(state);
1335 kfree(state);
1336
1337 return NULL; 1407 return NULL;
1338 } 1408 }
1339 /* determine settings based on type */ 1409 /* determine settings based on type */
@@ -1349,9 +1419,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
1349 break; 1419 break;
1350 default: 1420 default:
1351 dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); 1421 dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
1352 if (state) 1422 kfree(state);
1353 kfree(state);
1354
1355 return NULL; 1423 return NULL;
1356 } 1424 }
1357 1425
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 6776a592045f..e6541aff3996 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -69,62 +69,53 @@ static int ca_set_pid(void)
69} 69}
70 70
71 71
72static int put_checksum(u8 *check_string, int length) 72static void put_checksum(u8 *check_string, int length)
73{ 73{
74 u8 i = 0, checksum = 0; 74 dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum.");
75 75 dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length);
76 dprintk(verbose, DST_CA_DEBUG, 1, " ========================= Checksum calculation ==========================="); 76 check_string[length] = dst_check_sum (check_string, length);
77 dprintk(verbose, DST_CA_DEBUG, 1, " String Length=[0x%02x]", length); 77 dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]);
78 dprintk(verbose, DST_CA_DEBUG, 1, " String=[");
79
80 while (i < length) {
81 dprintk(verbose, DST_CA_DEBUG, 0, " %02x", check_string[i]);
82 checksum += check_string[i];
83 i++;
84 }
85 dprintk(verbose, DST_CA_DEBUG, 0, " ]\n");
86 dprintk(verbose, DST_CA_DEBUG, 1, "Sum=[%02x]\n", checksum);
87 check_string[length] = ~checksum + 1;
88 dprintk(verbose, DST_CA_DEBUG, 1, " Checksum=[%02x]", check_string[length]);
89 dprintk(verbose, DST_CA_DEBUG, 1, " ==========================================================================");
90
91 return 0;
92} 78}
93 79
94static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) 80static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read)
95{ 81{
96 u8 reply; 82 u8 reply;
97 83
84 down(&state->dst_mutex);
98 dst_comm_init(state); 85 dst_comm_init(state);
99 msleep(65); 86 msleep(65);
100 87
101 if (write_dst(state, data, len)) { 88 if (write_dst(state, data, len)) {
102 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); 89 dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover");
103 dst_error_recovery(state); 90 dst_error_recovery(state);
104 return -1; 91 goto error;
105 } 92 }
106 if ((dst_pio_disable(state)) < 0) { 93 if ((dst_pio_disable(state)) < 0) {
107 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); 94 dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed.");
108 return -1; 95 goto error;
109 } 96 }
110 if (read_dst(state, &reply, GET_ACK) < 0) { 97 if (read_dst(state, &reply, GET_ACK) < 0) {
111 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 98 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
112 dst_error_recovery(state); 99 dst_error_recovery(state);
113 return -1; 100 goto error;
114 } 101 }
115 if (read) { 102 if (read) {
116 if (! dst_wait_dst_ready(state, LONG_DELAY)) { 103 if (! dst_wait_dst_ready(state, LONG_DELAY)) {
117 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); 104 dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready");
118 return -1; 105 goto error;
119 } 106 }
120 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ 107 if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */
121 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); 108 dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover");
122 dst_error_recovery(state); 109 dst_error_recovery(state);
123 return -1; 110 goto error;
124 } 111 }
125 } 112 }
126 113 up(&state->dst_mutex);
127 return 0; 114 return 0;
115
116error:
117 up(&state->dst_mutex);
118 return -EIO;
128} 119}
129 120
130 121
@@ -166,7 +157,7 @@ static int ca_get_app_info(struct dst_state *state)
166 return 0; 157 return 0;
167} 158}
168 159
169static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg) 160static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg)
170{ 161{
171 int i; 162 int i;
172 u8 slot_cap[256]; 163 u8 slot_cap[256];
@@ -192,25 +183,25 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps,
192 p_ca_caps->descr_num = slot_cap[7]; 183 p_ca_caps->descr_num = slot_cap[7];
193 p_ca_caps->descr_type = 1; 184 p_ca_caps->descr_type = 1;
194 185
195 if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) 186 if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps)))
196 return -EFAULT; 187 return -EFAULT;
197 188
198 return 0; 189 return 0;
199} 190}
200 191
201/* Need some more work */ 192/* Need some more work */
202static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 193static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
203{ 194{
204 return -EOPNOTSUPP; 195 return -EOPNOTSUPP;
205} 196}
206 197
207 198
208static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg) 199static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg)
209{ 200{
210 int i; 201 int i;
211 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; 202 static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff};
212 203
213 u8 *slot_info = state->rxbuffer; 204 u8 *slot_info = state->messages;
214 205
215 put_checksum(&slot_command[0], 7); 206 put_checksum(&slot_command[0], 7);
216 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { 207 if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) {
@@ -238,19 +229,19 @@ static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_s
238 } else 229 } else
239 p_ca_slot_info->flags = 0; 230 p_ca_slot_info->flags = 0;
240 231
241 if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) 232 if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info)))
242 return -EFAULT; 233 return -EFAULT;
243 234
244 return 0; 235 return 0;
245} 236}
246 237
247 238
248static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 239static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
249{ 240{
250 u8 i = 0; 241 u8 i = 0;
251 u32 command = 0; 242 u32 command = 0;
252 243
253 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 244 if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg)))
254 return -EFAULT; 245 return -EFAULT;
255 246
256 if (p_ca_message->msg) { 247 if (p_ca_message->msg) {
@@ -266,7 +257,7 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message,
266 switch (command) { 257 switch (command) {
267 case CA_APP_INFO: 258 case CA_APP_INFO:
268 memcpy(p_ca_message->msg, state->messages, 128); 259 memcpy(p_ca_message->msg, state->messages, 128);
269 if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) 260 if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) )
270 return -EFAULT; 261 return -EFAULT;
271 break; 262 break;
272 } 263 }
@@ -315,7 +306,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l
315 return 0; 306 return 0;
316} 307}
317 308
318u32 asn_1_decode(u8 *asn_1_array) 309static u32 asn_1_decode(u8 *asn_1_array)
319{ 310{
320 u8 length_field = 0, word_count = 0, count = 0; 311 u8 length_field = 0, word_count = 0, count = 0;
321 u32 length = 0; 312 u32 length = 0;
@@ -328,7 +319,8 @@ u32 asn_1_decode(u8 *asn_1_array)
328 } else { 319 } else {
329 word_count = length_field & 0x7f; 320 word_count = length_field & 0x7f;
330 for (count = 0; count < word_count; count++) { 321 for (count = 0; count < word_count; count++) {
331 length = (length | asn_1_array[count + 1]) << 8; 322 length = length << 8;
323 length += asn_1_array[count + 1];
332 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); 324 dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length);
333 } 325 }
334 } 326 }
@@ -399,13 +391,14 @@ static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message
399 return 0; 391 return 0;
400} 392}
401 393
402static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) 394static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg)
403{ 395{
404 int i = 0; 396 int i = 0;
405 unsigned int ca_message_header_len; 397 unsigned int ca_message_header_len;
406 398
407 u32 command = 0; 399 u32 command = 0;
408 struct ca_msg *hw_buffer; 400 struct ca_msg *hw_buffer;
401 int result = 0;
409 402
410 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 403 if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
411 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 404 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -413,8 +406,11 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
413 } 406 }
414 dprintk(verbose, DST_CA_DEBUG, 1, " "); 407 dprintk(verbose, DST_CA_DEBUG, 1, " ");
415 408
416 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) 409 if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) {
417 return -EFAULT; 410 result = -EFAULT;
411 goto free_mem_and_exit;
412 }
413
418 414
419 if (p_ca_message->msg) { 415 if (p_ca_message->msg) {
420 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ 416 ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */
@@ -433,7 +429,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
433 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); 429 dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT");
434 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started 430 if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started
435 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); 431 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !");
436 return -1; 432 result = -1;
433 goto free_mem_and_exit;
437 } 434 }
438 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); 435 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !");
439 break; 436 break;
@@ -442,7 +439,8 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
442 /* Have to handle the 2 basic types of cards here */ 439 /* Have to handle the 2 basic types of cards here */
443 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { 440 if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) {
444 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); 441 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !");
445 return -1; 442 result = -1;
443 goto free_mem_and_exit;
446 } 444 }
447 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); 445 dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !");
448 break; 446 break;
@@ -451,22 +449,28 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message,
451 449
452 if ((ca_get_app_info(state)) < 0) { 450 if ((ca_get_app_info(state)) < 0) {
453 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); 451 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !");
454 return -1; 452 result = -1;
453 goto free_mem_and_exit;
455 } 454 }
456 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); 455 dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !");
457 break; 456 break;
458 } 457 }
459 } 458 }
460 return 0; 459free_mem_and_exit:
460 kfree (hw_buffer);
461
462 return result;
461} 463}
462 464
463static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) 465static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
464{ 466{
465 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; 467 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
466 struct dst_state* state = (struct dst_state*) dvbdev->priv; 468 struct dst_state* state = (struct dst_state*) dvbdev->priv;
467 struct ca_slot_info *p_ca_slot_info; 469 struct ca_slot_info *p_ca_slot_info;
468 struct ca_caps *p_ca_caps; 470 struct ca_caps *p_ca_caps;
469 struct ca_msg *p_ca_message; 471 struct ca_msg *p_ca_message;
472 void __user *arg = (void __user *)ioctl_arg;
473 int result = 0;
470 474
471 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { 475 if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) {
472 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); 476 dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure");
@@ -486,14 +490,16 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
486 dprintk(verbose, DST_CA_INFO, 1, " Sending message"); 490 dprintk(verbose, DST_CA_INFO, 1, " Sending message");
487 if ((ca_send_message(state, p_ca_message, arg)) < 0) { 491 if ((ca_send_message(state, p_ca_message, arg)) < 0) {
488 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); 492 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !");
489 return -1; 493 result = -1;
494 goto free_mem_and_exit;
490 } 495 }
491 break; 496 break;
492 case CA_GET_MSG: 497 case CA_GET_MSG:
493 dprintk(verbose, DST_CA_INFO, 1, " Getting message"); 498 dprintk(verbose, DST_CA_INFO, 1, " Getting message");
494 if ((ca_get_message(state, p_ca_message, arg)) < 0) { 499 if ((ca_get_message(state, p_ca_message, arg)) < 0) {
495 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); 500 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !");
496 return -1; 501 result = -1;
502 goto free_mem_and_exit;
497 } 503 }
498 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); 504 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !");
499 break; 505 break;
@@ -506,7 +512,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
506 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); 512 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info");
507 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { 513 if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) {
508 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); 514 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !");
509 return -1; 515 result = -1;
516 goto free_mem_and_exit;
510 } 517 }
511 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); 518 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !");
512 break; 519 break;
@@ -514,7 +521,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
514 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); 521 dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities");
515 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { 522 if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) {
516 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); 523 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !");
517 return -1; 524 result = -1;
525 goto free_mem_and_exit;
518 } 526 }
519 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); 527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !");
520 break; 528 break;
@@ -522,7 +530,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
522 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); 530 dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description");
523 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { 531 if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) {
524 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); 532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !");
525 return -1; 533 result = -1;
534 goto free_mem_and_exit;
526 } 535 }
527 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); 536 dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !");
528 break; 537 break;
@@ -530,7 +539,8 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
530 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); 539 dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler");
531 if ((ca_set_slot_descr()) < 0) { 540 if ((ca_set_slot_descr()) < 0) {
532 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); 541 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !");
533 return -1; 542 result = -1;
543 goto free_mem_and_exit;
534 } 544 }
535 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); 545 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !");
536 break; 546 break;
@@ -538,14 +548,19 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
538 dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); 548 dprintk(verbose, DST_CA_INFO, 1, " Setting PID");
539 if ((ca_set_pid()) < 0) { 549 if ((ca_set_pid()) < 0) {
540 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); 550 dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !");
541 return -1; 551 result = -1;
552 goto free_mem_and_exit;
542 } 553 }
543 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); 554 dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !");
544 default: 555 default:
545 return -EOPNOTSUPP; 556 result = -EOPNOTSUPP;
546 }; 557 };
558 free_mem_and_exit:
559 kfree (p_ca_message);
560 kfree (p_ca_slot_info);
561 kfree (p_ca_caps);
547 562
548 return 0; 563 return result;
549} 564}
550 565
551static int dst_ca_open(struct inode *inode, struct file *file) 566static int dst_ca_open(struct inode *inode, struct file *file)
@@ -582,7 +597,7 @@ static int dst_ca_write(struct file *file, const char __user *buffer, size_t len
582 597
583static struct file_operations dst_ca_fops = { 598static struct file_operations dst_ca_fops = {
584 .owner = THIS_MODULE, 599 .owner = THIS_MODULE,
585 .ioctl = (void *)dst_ca_ioctl, 600 .ioctl = dst_ca_ioctl,
586 .open = dst_ca_open, 601 .open = dst_ca_open,
587 .release = dst_ca_release, 602 .release = dst_ca_release,
588 .read = dst_ca_read, 603 .read = dst_ca_read,
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 3281a6ca3685..81557f38fe38 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -22,6 +22,7 @@
22#ifndef DST_COMMON_H 22#ifndef DST_COMMON_H
23#define DST_COMMON_H 23#define DST_COMMON_H
24 24
25#include <linux/smp_lock.h>
25#include <linux/dvb/frontend.h> 26#include <linux/dvb/frontend.h>
26#include <linux/device.h> 27#include <linux/device.h>
27#include "bt878.h" 28#include "bt878.h"
@@ -49,6 +50,7 @@
49#define DST_TYPE_HAS_FW_BUILD 64 50#define DST_TYPE_HAS_FW_BUILD 64
50#define DST_TYPE_HAS_OBS_REGS 128 51#define DST_TYPE_HAS_OBS_REGS 128
51#define DST_TYPE_HAS_INC_COUNT 256 52#define DST_TYPE_HAS_INC_COUNT 256
53#define DST_TYPE_HAS_MULTI_FE 512
52 54
53/* Card capability list */ 55/* Card capability list */
54 56
@@ -117,6 +119,9 @@ struct dst_state {
117 u8 fw_version[8]; 119 u8 fw_version[8];
118 u8 card_info[8]; 120 u8 card_info[8];
119 u8 vendor[8]; 121 u8 vendor[8];
122 u8 board_info[8];
123
124 struct semaphore dst_mutex;
120}; 125};
121 126
122struct dst_types { 127struct dst_types {
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index c5c7672cd538..2e398090cf63 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -34,6 +34,7 @@
34#include "dvb_frontend.h" 34#include "dvb_frontend.h"
35#include "dvb-bt8xx.h" 35#include "dvb-bt8xx.h"
36#include "bt878.h" 36#include "bt878.h"
37#include "dvb-pll.h"
37 38
38static int debug; 39static int debug;
39 40
@@ -279,7 +280,7 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front
279 data[0] = (div >> 8) & 0x7f; 280 data[0] = (div >> 8) & 0x7f;
280 data[1] = div & 0xff; 281 data[1] = div & 0xff;
281 data[2] = ((div >> 10) & 0x60) | cfg; 282 data[2] = ((div >> 10) & 0x60) | cfg;
282 data[3] = cpump | band_select; 283 data[3] = (cpump << 6) | band_select;
283 284
284 i2c_transfer(card->i2c_adapter, &msg, 1); 285 i2c_transfer(card->i2c_adapter, &msg, 1);
285 return (div * 166666 - 36000000); 286 return (div * 166666 - 36000000);
@@ -522,9 +523,7 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt)
522 /* 523 /*
523 * Reset the frontend, must be called before trying 524 * Reset the frontend, must be called before trying
524 * to initialise the MT352 or mt352_attach 525 * to initialise the MT352 or mt352_attach
525 * will fail. 526 * will fail. Same goes for the nxt6000 frontend.
526 *
527 * Presumably not required for the NXT6000 frontend.
528 * 527 *
529 */ 528 */
530 529
@@ -546,14 +545,63 @@ static struct mt352_config digitv_alps_tded4_config = {
546 .pll_set = digitv_alps_tded4_pll_set, 545 .pll_set = digitv_alps_tded4_pll_set,
547}; 546};
548 547
548static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
549{
550 struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
551 u8 buf[4];
552 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
553 int err;
554
555 dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0);
556 dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
557 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
558 if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) {
559 printk(KERN_WARNING "dvb-bt8xx: %s error "
560 "(addr %02x <- %02x, err = %i)\n",
561 __FUNCTION__, buf[0], buf[1], err);
562 if (err < 0)
563 return err;
564 else
565 return -EREMOTEIO;
566 }
567
568 /* Set the Auxiliary Byte. */
569 buf[2] &= ~0x20;
570 buf[2] |= 0x18;
571 buf[3] = 0x50;
572 i2c_transfer(card->i2c_adapter, &msg, 1);
573
574 return 0;
575}
576
577static struct lgdt330x_config tdvs_tua6034_config = {
578 .demod_address = 0x0e,
579 .demod_chip = LGDT3303,
580 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
581 .pll_set = tdvs_tua6034_pll_set,
582};
583
584static void lgdt330x_reset(struct dvb_bt8xx_card *bt)
585{
586 /* Set pin 27 of the lgdt3303 chip high to reset the frontend */
587
588 /* Pulse the reset line */
589 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
590 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */
591 msleep(100);
592
593 bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */
594 msleep(100);
595}
596
549static void frontend_init(struct dvb_bt8xx_card *card, u32 type) 597static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
550{ 598{
551 int ret; 599 int ret;
552 struct dst_state* state = NULL; 600 struct dst_state* state = NULL;
553 601
554 switch(type) { 602 switch(type) {
555#ifdef BTTV_DVICO_DVBT_LITE 603#ifdef BTTV_BOARD_DVICO_DVBT_LITE
556 case BTTV_DVICO_DVBT_LITE: 604 case BTTV_BOARD_DVICO_DVBT_LITE:
557 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); 605 card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter);
558 if (card->fe != NULL) { 606 if (card->fe != NULL) {
559 card->fe->ops->info.frequency_min = 174000000; 607 card->fe->ops->info.frequency_min = 174000000;
@@ -562,10 +610,19 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
562 break; 610 break;
563#endif 611#endif
564 612
565#ifdef BTTV_TWINHAN_VP3021 613#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
566 case BTTV_TWINHAN_VP3021: 614 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
615 lgdt330x_reset(card);
616 card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter);
617 if (card->fe != NULL)
618 dprintk ("dvb_bt8xx: lgdt330x detected\n");
619 break;
620#endif
621
622#ifdef BTTV_BOARD_TWINHAN_VP3021
623 case BTTV_BOARD_TWINHAN_VP3021:
567#else 624#else
568 case BTTV_NEBULA_DIGITV: 625 case BTTV_BOARD_NEBULA_DIGITV:
569#endif 626#endif
570 /* 627 /*
571 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); 628 * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK);
@@ -573,6 +630,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
573 */ 630 */
574 631
575 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ 632 /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */
633 digitv_alps_tded4_reset(card);
576 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); 634 card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter);
577 if (card->fe != NULL) { 635 if (card->fe != NULL) {
578 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); 636 dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n");
@@ -587,11 +645,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
587 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); 645 dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n");
588 break; 646 break;
589 647
590 case BTTV_AVDVBT_761: 648 case BTTV_BOARD_AVDVBT_761:
591 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter); 649 card->fe = sp887x_attach(&microtune_mt7202dtf_config, card->i2c_adapter);
592 break; 650 break;
593 651
594 case BTTV_AVDVBT_771: 652 case BTTV_BOARD_AVDVBT_771:
595 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); 653 card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter);
596 if (card->fe != NULL) { 654 if (card->fe != NULL) {
597 card->fe->ops->info.frequency_min = 174000000; 655 card->fe->ops->info.frequency_min = 174000000;
@@ -599,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
599 } 657 }
600 break; 658 break;
601 659
602 case BTTV_TWINHAN_DST: 660 case BTTV_BOARD_TWINHAN_DST:
603 /* DST is not a frontend driver !!! */ 661 /* DST is not a frontend driver !!! */
604 state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); 662 state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL);
605 /* Setup the Card */ 663 /* Setup the Card */
@@ -620,11 +678,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type)
620 ret = dst_ca_attach(state, &card->dvb_adapter); 678 ret = dst_ca_attach(state, &card->dvb_adapter);
621 break; 679 break;
622 680
623 case BTTV_PINNACLESAT: 681 case BTTV_BOARD_PINNACLESAT:
624 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); 682 card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter);
625 break; 683 break;
626 684
627 case BTTV_PC_HDTV: 685 case BTTV_BOARD_PC_HDTV:
628 card->fe = or51211_attach(&or51211_config, card->i2c_adapter); 686 card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
629 break; 687 break;
630 } 688 }
@@ -746,7 +804,7 @@ static int dvb_bt8xx_probe(struct device *dev)
746 card->i2c_adapter = &sub->core->i2c_adap; 804 card->i2c_adapter = &sub->core->i2c_adap;
747 805
748 switch(sub->core->type) { 806 switch(sub->core->type) {
749 case BTTV_PINNACLESAT: 807 case BTTV_BOARD_PINNACLESAT:
750 card->gpio_mode = 0x0400c060; 808 card->gpio_mode = 0x0400c060;
751 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, 809 /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR,
752 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ 810 BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */
@@ -754,8 +812,8 @@ static int dvb_bt8xx_probe(struct device *dev)
754 card->irq_err_ignore = 0; 812 card->irq_err_ignore = 0;
755 break; 813 break;
756 814
757#ifdef BTTV_DVICO_DVBT_LITE 815#ifdef BTTV_BOARD_DVICO_DVBT_LITE
758 case BTTV_DVICO_DVBT_LITE: 816 case BTTV_BOARD_DVICO_DVBT_LITE:
759#endif 817#endif
760 card->gpio_mode = 0x0400C060; 818 card->gpio_mode = 0x0400C060;
761 card->op_sync_orin = 0; 819 card->op_sync_orin = 0;
@@ -765,26 +823,34 @@ static int dvb_bt8xx_probe(struct device *dev)
765 * DA_APP(parallel) */ 823 * DA_APP(parallel) */
766 break; 824 break;
767 825
768#ifdef BTTV_TWINHAN_VP3021 826#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE
769 case BTTV_TWINHAN_VP3021: 827 case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE:
828#endif
829 card->gpio_mode = 0x0400c060;
830 card->op_sync_orin = BT878_RISC_SYNC_MASK;
831 card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR;
832 break;
833
834#ifdef BTTV_BOARD_TWINHAN_VP3021
835 case BTTV_BOARD_TWINHAN_VP3021:
770#else 836#else
771 case BTTV_NEBULA_DIGITV: 837 case BTTV_BOARD_NEBULA_DIGITV:
772#endif 838#endif
773 case BTTV_AVDVBT_761: 839 case BTTV_BOARD_AVDVBT_761:
774 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); 840 card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5);
775 card->op_sync_orin = 0; 841 card->op_sync_orin = 0;
776 card->irq_err_ignore = 0; 842 card->irq_err_ignore = 0;
777 /* A_PWRDN DA_SBR DA_APP (high speed serial) */ 843 /* A_PWRDN DA_SBR DA_APP (high speed serial) */
778 break; 844 break;
779 845
780 case BTTV_AVDVBT_771: //case 0x07711461: 846 case BTTV_BOARD_AVDVBT_771: //case 0x07711461:
781 card->gpio_mode = 0x0400402B; 847 card->gpio_mode = 0x0400402B;
782 card->op_sync_orin = BT878_RISC_SYNC_MASK; 848 card->op_sync_orin = BT878_RISC_SYNC_MASK;
783 card->irq_err_ignore = 0; 849 card->irq_err_ignore = 0;
784 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ 850 /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/
785 break; 851 break;
786 852
787 case BTTV_TWINHAN_DST: 853 case BTTV_BOARD_TWINHAN_DST:
788 card->gpio_mode = 0x2204f2c; 854 card->gpio_mode = 0x2204f2c;
789 card->op_sync_orin = BT878_RISC_SYNC_MASK; 855 card->op_sync_orin = BT878_RISC_SYNC_MASK;
790 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | 856 card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR |
@@ -802,7 +868,7 @@ static int dvb_bt8xx_probe(struct device *dev)
802 * RISC+FIFO ENABLE */ 868 * RISC+FIFO ENABLE */
803 break; 869 break;
804 870
805 case BTTV_PC_HDTV: 871 case BTTV_BOARD_PC_HDTV:
806 card->gpio_mode = 0x0100EC7B; 872 card->gpio_mode = 0x0100EC7B;
807 card->op_sync_orin = 0; 873 card->op_sync_orin = 0;
808 card->irq_err_ignore = 0; 874 card->irq_err_ignore = 0;
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
index 9ec8e5bd6c1f..cf035a80361c 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h
@@ -35,6 +35,7 @@
35#include "nxt6000.h" 35#include "nxt6000.h"
36#include "cx24110.h" 36#include "cx24110.h"
37#include "or51211.h" 37#include "or51211.h"
38#include "lgdt330x.h"
38 39
39struct dvb_bt8xx_card { 40struct dvb_bt8xx_card {
40 struct semaphore lock; 41 struct semaphore lock;
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index 9719a3b30f78..7d7b0067f228 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -48,8 +48,11 @@
48 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter. 48 * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
49 */ 49 */
50 50
51#ifndef DMX_MAX_SECTION_SIZE
52#define DMX_MAX_SECTION_SIZE 4096
53#endif
51#ifndef DMX_MAX_SECFEED_SIZE 54#ifndef DMX_MAX_SECFEED_SIZE
52#define DMX_MAX_SECFEED_SIZE 4096 55#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
53#endif 56#endif
54 57
55 58
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index dc476dda2b71..b4c899b15959 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -246,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
246 246
247 for (n = 0; sec->secbufp + 2 < limit; n++) { 247 for (n = 0; sec->secbufp + 2 < limit; n++) {
248 seclen = section_length(sec->secbuf); 248 seclen = section_length(sec->secbuf);
249 if (seclen <= 0 || seclen > DMX_MAX_SECFEED_SIZE 249 if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
250 || seclen + sec->secbufp > limit) 250 || seclen + sec->secbufp > limit)
251 return 0; 251 return 0;
252 sec->seclen = seclen; 252 sec->seclen = seclen;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index a8bc84240b50..6ffa6b216363 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -42,8 +42,6 @@
42#include "dvb_frontend.h" 42#include "dvb_frontend.h"
43#include "dvbdev.h" 43#include "dvbdev.h"
44 44
45// #define DEBUG_LOCKLOSS 1
46
47static int dvb_frontend_debug; 45static int dvb_frontend_debug;
48static int dvb_shutdown_timeout = 5; 46static int dvb_shutdown_timeout = 5;
49static int dvb_force_auto_inversion; 47static int dvb_force_auto_inversion;
@@ -438,25 +436,6 @@ static int dvb_frontend_thread(void *data)
438 if (s & FE_HAS_LOCK) 436 if (s & FE_HAS_LOCK)
439 continue; 437 continue;
440 else { /* if we _WERE_ tuned, but now don't have a lock */ 438 else { /* if we _WERE_ tuned, but now don't have a lock */
441#ifdef DEBUG_LOCKLOSS
442 /* first of all try setting the tone again if it was on - this
443 * sometimes works around problems with noisy power supplies */
444 if (fe->ops->set_tone && (fepriv->tone == SEC_TONE_ON)) {
445 fe->ops->set_tone(fe, fepriv->tone);
446 mdelay(100);
447 s = 0;
448 fe->ops->read_status(fe, &s);
449 if (s & FE_HAS_LOCK) {
450 printk("DVB%i: Lock was lost, but regained by setting "
451 "the tone. This may indicate your power supply "
452 "is noisy/slightly incompatable with this DVB-S "
453 "adapter\n", fe->dvb->num);
454 fepriv->state = FESTATE_TUNED;
455 continue;
456 }
457 }
458#endif
459 /* some other reason for losing the lock - start zigzagging */
460 fepriv->state = FESTATE_ZIGZAG_FAST; 439 fepriv->state = FESTATE_ZIGZAG_FAST;
461 fepriv->started_auto_step = fepriv->auto_step; 440 fepriv->started_auto_step = fepriv->auto_step;
462 check_wrapped = 0; 441 check_wrapped = 0;
@@ -577,6 +556,49 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
577 fepriv->thread_pid); 556 fepriv->thread_pid);
578} 557}
579 558
559s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
560{
561 return ((curtime.tv_usec < lasttime.tv_usec) ?
562 1000000 - lasttime.tv_usec + curtime.tv_usec :
563 curtime.tv_usec - lasttime.tv_usec);
564}
565EXPORT_SYMBOL(timeval_usec_diff);
566
567static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec)
568{
569 curtime->tv_usec += add_usec;
570 if (curtime->tv_usec >= 1000000) {
571 curtime->tv_usec -= 1000000;
572 curtime->tv_sec++;
573 }
574}
575
576/*
577 * Sleep until gettimeofday() > waketime + add_usec
578 * This needs to be as precise as possible, but as the delay is
579 * usually between 2ms and 32ms, it is done using a scheduled msleep
580 * followed by usleep (normally a busy-wait loop) for the remainder
581 */
582void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec)
583{
584 struct timeval lasttime;
585 s32 delta, newdelta;
586
587 timeval_usec_add(waketime, add_usec);
588
589 do_gettimeofday(&lasttime);
590 delta = timeval_usec_diff(lasttime, *waketime);
591 if (delta > 2500) {
592 msleep((delta - 1500) / 1000);
593 do_gettimeofday(&lasttime);
594 newdelta = timeval_usec_diff(lasttime, *waketime);
595 delta = (newdelta > delta) ? 0 : newdelta;
596 }
597 if (delta > 0)
598 udelay(delta);
599}
600EXPORT_SYMBOL(dvb_frontend_sleep_until);
601
580static int dvb_frontend_start(struct dvb_frontend *fe) 602static int dvb_frontend_start(struct dvb_frontend *fe)
581{ 603{
582 int ret; 604 int ret;
@@ -728,6 +750,60 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file,
728 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); 750 err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg);
729 fepriv->state = FESTATE_DISEQC; 751 fepriv->state = FESTATE_DISEQC;
730 fepriv->status = 0; 752 fepriv->status = 0;
753 } else if (fe->ops->set_voltage) {
754 /*
755 * NOTE: This is a fallback condition. Some frontends
756 * (stv0299 for instance) take longer than 8msec to
757 * respond to a set_voltage command. Those switches
758 * need custom routines to switch properly. For all
759 * other frontends, the following shoule work ok.
760 * Dish network legacy switches (as used by Dish500)
761 * are controlled by sending 9-bit command words
762 * spaced 8msec apart.
763 * the actual command word is switch/port dependant
764 * so it is up to the userspace application to send
765 * the right command.
766 * The command must always start with a '0' after
767 * initialization, so parg is 8 bits and does not
768 * include the initialization or start bit
769 */
770 unsigned int cmd = ((unsigned int) parg) << 1;
771 struct timeval nexttime;
772 struct timeval tv[10];
773 int i;
774 u8 last = 1;
775 if (dvb_frontend_debug)
776 printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd);
777 do_gettimeofday(&nexttime);
778 if (dvb_frontend_debug)
779 memcpy(&tv[0], &nexttime, sizeof(struct timeval));
780 /* before sending a command, initialize by sending
781 * a 32ms 18V to the switch
782 */
783 fe->ops->set_voltage(fe, SEC_VOLTAGE_18);
784 dvb_frontend_sleep_until(&nexttime, 32000);
785
786 for (i = 0; i < 9; i++) {
787 if (dvb_frontend_debug)
788 do_gettimeofday(&tv[i + 1]);
789 if ((cmd & 0x01) != last) {
790 /* set voltage to (last ? 13V : 18V) */
791 fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18);
792 last = (last) ? 0 : 1;
793 }
794 cmd = cmd >> 1;
795 if (i != 8)
796 dvb_frontend_sleep_until(&nexttime, 8000);
797 }
798 if (dvb_frontend_debug) {
799 printk("%s(%d): switch delay (should be 32k followed by all 8k\n",
800 __FUNCTION__, fe->dvb->num);
801 for (i = 1; i < 10; i++)
802 printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
803 }
804 err = 0;
805 fepriv->state = FESTATE_DISEQC;
806 fepriv->status = 0;
731 } 807 }
732 break; 808 break;
733 809
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 9c2c1d1136bd..348c9b0b988a 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -101,4 +101,7 @@ extern int dvb_register_frontend(struct dvb_adapter* dvb,
101 101
102extern int dvb_unregister_frontend(struct dvb_frontend* fe); 102extern int dvb_unregister_frontend(struct dvb_frontend* fe);
103 103
104extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
105extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
106
104#endif 107#endif
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index e55322ef76b3..49f541d9a042 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -43,11 +43,9 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */ 43 { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */
44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */ 44 { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */
45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */ 45 { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */
46 { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */
47 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ 46 { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */
48 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ 47 { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */
49 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ 48 { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */
50 { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
51 { 0x02, 0x14, KEY_MUTE }, /* MUTE */ 49 { 0x02, 0x14, KEY_MUTE }, /* MUTE */
52 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */ 50 { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */
53 { 0x02, 0x19, KEY_RECORD }, /* RECORD */ 51 { 0x02, 0x19, KEY_RECORD }, /* RECORD */
@@ -57,8 +55,6 @@ static struct dvb_usb_rc_key a800_rc_keys[] = {
57 { 0x02, 0x1d, KEY_BACK }, /* << / RED */ 55 { 0x02, 0x1d, KEY_BACK }, /* << / RED */
58 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */ 56 { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */
59 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */ 57 { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */
60 { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */
61 { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
62 { 0x02, 0x04, KEY_EPG }, /* EPG */ 58 { 0x02, 0x04, KEY_EPG }, /* EPG */
63 { 0x02, 0x15, KEY_MENU }, /* MENU */ 59 { 0x02, 0x15, KEY_MENU }, /* MENU */
64 60
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index 0058505634a0..aa271a2496d5 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -82,13 +82,15 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d)
82static struct dvb_usb_properties dibusb1_1_properties; 82static struct dvb_usb_properties dibusb1_1_properties;
83static struct dvb_usb_properties dibusb1_1_an2235_properties; 83static struct dvb_usb_properties dibusb1_1_an2235_properties;
84static struct dvb_usb_properties dibusb2_0b_properties; 84static struct dvb_usb_properties dibusb2_0b_properties;
85static struct dvb_usb_properties artec_t1_usb2_properties;
85 86
86static int dibusb_probe(struct usb_interface *intf, 87static int dibusb_probe(struct usb_interface *intf,
87 const struct usb_device_id *id) 88 const struct usb_device_id *id)
88{ 89{
89 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 || 90 if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 ||
90 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 || 91 dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 ||
91 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0) 92 dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0 ||
93 dvb_usb_device_init(intf,&artec_t1_usb2_properties,THIS_MODULE,NULL) == 0)
92 return 0; 94 return 0;
93 95
94 return -EINVAL; 96 return -EINVAL;
@@ -128,10 +130,13 @@ static struct usb_device_id dibusb_dib3000mb_table [] = {
128 130
129/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, 131/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
130 132
133/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
134/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
135
131// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 136// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
132 137
133#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 138#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
134/* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, 139/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
135#endif 140#endif
136 { } /* Terminating entry */ 141 { } /* Terminating entry */
137}; 142};
@@ -264,7 +269,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
264 }, 269 },
265#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs 270#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs
266 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", 271 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
267 { &dibusb_dib3000mb_table[28], NULL }, 272 { &dibusb_dib3000mb_table[30], NULL },
268 { NULL }, 273 { NULL },
269 }, 274 },
270#endif 275#endif
@@ -273,7 +278,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = {
273 278
274static struct dvb_usb_properties dibusb2_0b_properties = { 279static struct dvb_usb_properties dibusb2_0b_properties = {
275 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, 280 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
276 .pid_filter_count = 32, 281 .pid_filter_count = 16,
277 282
278 .usb_ctrl = CYPRESS_FX2, 283 .usb_ctrl = CYPRESS_FX2,
279 284
@@ -321,6 +326,52 @@ static struct dvb_usb_properties dibusb2_0b_properties = {
321 } 326 }
322}; 327};
323 328
329static struct dvb_usb_properties artec_t1_usb2_properties = {
330 .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
331 .pid_filter_count = 16,
332
333 .usb_ctrl = CYPRESS_FX2,
334
335 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
336
337 .size_of_priv = sizeof(struct dibusb_state),
338
339 .streaming_ctrl = dibusb2_0_streaming_ctrl,
340 .pid_filter = dibusb_pid_filter,
341 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
342 .power_ctrl = dibusb2_0_power_ctrl,
343 .frontend_attach = dibusb_dib3000mb_frontend_attach,
344 .tuner_attach = dibusb_tuner_probe_and_attach,
345
346 .rc_interval = DEFAULT_RC_INTERVAL,
347 .rc_key_map = dibusb_rc_keys,
348 .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
349 .rc_query = dibusb_rc_query,
350
351 .i2c_algo = &dibusb_i2c_algo,
352
353 .generic_bulk_ctrl_endpoint = 0x01,
354 /* parameter for the MPEG2-data transfer */
355 .urb = {
356 .type = DVB_USB_BULK,
357 .count = 7,
358 .endpoint = 0x06,
359 .u = {
360 .bulk = {
361 .buffersize = 4096,
362 }
363 }
364 },
365
366 .num_device_descs = 1,
367 .devices = {
368 { "Artec T1 USB2.0",
369 { &dibusb_dib3000mb_table[28], NULL },
370 { &dibusb_dib3000mb_table[29], NULL },
371 },
372 }
373};
374
324static struct usb_driver dibusb_driver = { 375static struct usb_driver dibusb_driver = {
325 .owner = THIS_MODULE, 376 .owner = THIS_MODULE,
326 .name = "dvb_usb_dibusb_mb", 377 .name = "dvb_usb_dibusb_mb",
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
index 6611f62977c0..2d99d05c7eab 100644
--- a/drivers/media/dvb/dvb-usb/dibusb.h
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -11,7 +11,9 @@
11#ifndef _DVB_USB_DIBUSB_H_ 11#ifndef _DVB_USB_DIBUSB_H_
12#define _DVB_USB_DIBUSB_H_ 12#define _DVB_USB_DIBUSB_H_
13 13
14#define DVB_USB_LOG_PREFIX "dibusb" 14#ifndef DVB_USB_LOG_PREFIX
15 #define DVB_USB_LOG_PREFIX "dibusb"
16#endif
15#include "dvb-usb.h" 17#include "dvb-usb.h"
16 18
17#include "dib3000.h" 19#include "dib3000.h"
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 0818996bf150..6be99e537e12 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -43,10 +43,14 @@
43#define USB_PID_COMPRO_DVBU2000_WARM 0xd001 43#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
44#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c 44#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
45#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d 45#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
46#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
47#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
46#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 48#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
47#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 49#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
48#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 50#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
49#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 51#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
52#define USB_PID_DIBCOM_STK7700 0x1e14
53#define USB_PID_DIBCOM_STK7700_REENUM 0x1e15
50#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 54#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
51#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 55#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
52#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 56#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
@@ -68,6 +72,7 @@
68#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 72#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
69#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 73#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
70#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 74#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
75#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
71#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 76#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
72#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 77#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
73#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e 78#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
index f5799a4c228e..36b7048c02d2 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -196,7 +196,9 @@ static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, un
196 dvb_usb_free_stream_buffers(d); 196 dvb_usb_free_stream_buffers(d);
197 return -ENOMEM; 197 return -ENOMEM;
198 } 198 }
199 deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]); 199 deb_mem("buffer %d: %p (dma: %llu)\n",
200 d->buf_num, d->buf_list[d->buf_num],
201 (unsigned long long)d->dma_addr[d->buf_num]);
200 memset(d->buf_list[d->buf_num],0,size); 202 memset(d->buf_list[d->buf_num],0,size);
201 } 203 }
202 deb_mem("allocation successful\n"); 204 deb_mem("allocation successful\n");
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index a50a41f6f79d..8e269e1c1f9d 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -164,6 +164,14 @@ config DVB_NXT2002
164 help 164 help
165 An ATSC 8VSB tuner module. Say Y when you want to support this frontend. 165 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
166 166
167config DVB_NXT200X
168 tristate "Nextwave NXT2002/NXT2004 based"
169 depends on DVB_CORE
170 select FW_LOADER
171 help
172 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
173 to support this frontend.
174
167config DVB_OR51211 175config DVB_OR51211
168 tristate "or51211 based (pcHDTV HD2000 card)" 176 tristate "or51211 based (pcHDTV HD2000 card)"
169 depends on DVB_CORE 177 depends on DVB_CORE
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index ad8658ffd60a..a98760fe08a1 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
26obj-$(CONFIG_DVB_TDA10021) += tda10021.o 26obj-$(CONFIG_DVB_TDA10021) += tda10021.o
27obj-$(CONFIG_DVB_STV0297) += stv0297.o 27obj-$(CONFIG_DVB_STV0297) += stv0297.o
28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o 28obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
29obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
29obj-$(CONFIG_DVB_OR51211) += or51211.o 30obj-$(CONFIG_DVB_OR51211) += or51211.o
30obj-$(CONFIG_DVB_OR51132) += or51132.o 31obj-$(CONFIG_DVB_OR51132) += or51132.o
31obj-$(CONFIG_DVB_BCM3510) += bcm3510.o 32obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index d4b97989e3ed..654d7dc879d9 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -27,6 +27,7 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/jiffies.h>
30 31
31#include "dvb_frontend.h" 32#include "dvb_frontend.h"
32#include "cx24110.h" 33#include "cx24110.h"
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 536c35d969b7..f857b869616c 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -226,7 +226,7 @@ struct dvb_pll_desc dvb_pll_tua6034 = {
226EXPORT_SYMBOL(dvb_pll_tua6034); 226EXPORT_SYMBOL(dvb_pll_tua6034);
227 227
228/* Infineon TUA6034 228/* Infineon TUA6034
229 * used in LG Innotek TDVS-H062F 229 * used in LG TDVS H061F and LG TDVS H062F
230 */ 230 */
231struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { 231struct dvb_pll_desc dvb_pll_tdvs_tua6034 = {
232 .name = "LG/Infineon TUA6034", 232 .name = "LG/Infineon TUA6034",
@@ -292,6 +292,58 @@ struct dvb_pll_desc dvb_pll_tded4 = {
292}; 292};
293EXPORT_SYMBOL(dvb_pll_tded4); 293EXPORT_SYMBOL(dvb_pll_tded4);
294 294
295/* ALPS TDHU2
296 * used in AverTVHD MCE A180
297 */
298struct dvb_pll_desc dvb_pll_tdhu2 = {
299 .name = "ALPS TDHU2",
300 .min = 54000000,
301 .max = 864000000,
302 .count = 4,
303 .entries = {
304 { 162000000, 44000000, 62500, 0x85, 0x01 },
305 { 426000000, 44000000, 62500, 0x85, 0x02 },
306 { 782000000, 44000000, 62500, 0x85, 0x08 },
307 { 999999999, 44000000, 62500, 0x85, 0x88 },
308 }
309};
310EXPORT_SYMBOL(dvb_pll_tdhu2);
311
312/* Philips TUV1236D
313 * used in ATI HDTV Wonder
314 */
315struct dvb_pll_desc dvb_pll_tuv1236d = {
316 .name = "Philips TUV1236D",
317 .min = 54000000,
318 .max = 864000000,
319 .count = 3,
320 .entries = {
321 { 157250000, 44000000, 62500, 0xc6, 0x41 },
322 { 454000000, 44000000, 62500, 0xc6, 0x42 },
323 { 999999999, 44000000, 62500, 0xc6, 0x44 },
324 },
325};
326EXPORT_SYMBOL(dvb_pll_tuv1236d);
327
328/* Samsung TBMV30111IN
329 * used in Air2PC ATSC - 2nd generation (nxt2002)
330 */
331struct dvb_pll_desc dvb_pll_tbmv30111in = {
332 .name = "Samsung TBMV30111IN",
333 .min = 54000000,
334 .max = 860000000,
335 .count = 4,
336 .entries = {
337 { 172000000, 44000000, 166666, 0xb4, 0x01 },
338 { 214000000, 44000000, 166666, 0xb4, 0x02 },
339 { 467000000, 44000000, 166666, 0xbc, 0x02 },
340 { 721000000, 44000000, 166666, 0xbc, 0x08 },
341 { 841000000, 44000000, 166666, 0xf4, 0x08 },
342 { 999999999, 44000000, 166666, 0xfc, 0x02 },
343 }
344};
345EXPORT_SYMBOL(dvb_pll_tbmv30111in);
346
295/* ----------------------------------------------------------- */ 347/* ----------------------------------------------------------- */
296/* code */ 348/* code */
297 349
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 205b2d1a8852..497d31dcf41e 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -36,6 +36,10 @@ extern struct dvb_pll_desc dvb_pll_tda665x;
36extern struct dvb_pll_desc dvb_pll_fmd1216me; 36extern struct dvb_pll_desc dvb_pll_fmd1216me;
37extern struct dvb_pll_desc dvb_pll_tded4; 37extern struct dvb_pll_desc dvb_pll_tded4;
38 38
39extern struct dvb_pll_desc dvb_pll_tuv1236d;
40extern struct dvb_pll_desc dvb_pll_tdhu2;
41extern struct dvb_pll_desc dvb_pll_tbmv30111in;
42
39int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, 43int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
40 u32 freq, int bandwidth); 44 u32 freq, int bandwidth);
41 45
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
index 794be520d590..645946a992d9 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -148,7 +148,7 @@ struct dvb_frontend* dvb_dummy_fe_qpsk_attach()
148 return &state->frontend; 148 return &state->frontend;
149 149
150error: 150error:
151 if (state) kfree(state); 151 kfree(state);
152 return NULL; 152 return NULL;
153} 153}
154 154
@@ -171,7 +171,7 @@ struct dvb_frontend* dvb_dummy_fe_qam_attach()
171 return &state->frontend; 171 return &state->frontend;
172 172
173error: 173error:
174 if (state) kfree(state); 174 kfree(state);
175 return NULL; 175 return NULL;
176} 176}
177 177
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index faaad1ae8559..19b4bf7c21a7 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -559,7 +559,8 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config,
559 return &state->frontend; 559 return &state->frontend;
560 560
561error: 561error:
562 if (reg0x3e >= 0) l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */ 562 if (reg0x3e >= 0)
563 l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */
563 kfree(state); 564 kfree(state);
564 return NULL; 565 return NULL;
565} 566}
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 8dde72bd1046..6a33f5a19a8d 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -26,6 +26,8 @@
26 * DViCO FusionHDTV 3 Gold-Q 26 * DViCO FusionHDTV 3 Gold-Q
27 * DViCO FusionHDTV 3 Gold-T 27 * DViCO FusionHDTV 3 Gold-T
28 * DViCO FusionHDTV 5 Gold 28 * DViCO FusionHDTV 5 Gold
29 * DViCO FusionHDTV 5 Lite
30 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
29 * 31 *
30 * TODO: 32 * TODO:
31 * signal strength always returns 0. 33 * signal strength always returns 0.
@@ -222,6 +224,11 @@ static int lgdt330x_init(struct dvb_frontend* fe)
222 0x4c, 0x14 224 0x4c, 0x14
223 }; 225 };
224 226
227 static u8 flip_lgdt3303_init_data[] = {
228 0x4c, 0x14,
229 0x87, 0xf3
230 };
231
225 struct lgdt330x_state* state = fe->demodulator_priv; 232 struct lgdt330x_state* state = fe->demodulator_priv;
226 char *chip_name; 233 char *chip_name;
227 int err; 234 int err;
@@ -234,8 +241,13 @@ static int lgdt330x_init(struct dvb_frontend* fe)
234 break; 241 break;
235 case LGDT3303: 242 case LGDT3303:
236 chip_name = "LGDT3303"; 243 chip_name = "LGDT3303";
237 err = i2c_write_demod_bytes(state, lgdt3303_init_data, 244 if (state->config->clock_polarity_flip) {
238 sizeof(lgdt3303_init_data)); 245 err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data,
246 sizeof(flip_lgdt3303_init_data));
247 } else {
248 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
249 sizeof(lgdt3303_init_data));
250 }
239 break; 251 break;
240 default: 252 default:
241 chip_name = "undefined"; 253 chip_name = "undefined";
@@ -731,8 +743,7 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
731 return &state->frontend; 743 return &state->frontend;
732 744
733error: 745error:
734 if (state) 746 kfree(state);
735 kfree(state);
736 dprintk("%s: ERROR\n",__FUNCTION__); 747 dprintk("%s: ERROR\n",__FUNCTION__);
737 return NULL; 748 return NULL;
738} 749}
@@ -744,9 +755,8 @@ static struct dvb_frontend_ops lgdt3302_ops = {
744 .frequency_min= 54000000, 755 .frequency_min= 54000000,
745 .frequency_max= 858000000, 756 .frequency_max= 858000000,
746 .frequency_stepsize= 62500, 757 .frequency_stepsize= 62500,
747 /* Symbol rate is for all VSB modes need to check QAM */ 758 .symbol_rate_min = 5056941, /* QAM 64 */
748 .symbol_rate_min = 10762000, 759 .symbol_rate_max = 10762000, /* VSB 8 */
749 .symbol_rate_max = 10762000,
750 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB 760 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
751 }, 761 },
752 .init = lgdt330x_init, 762 .init = lgdt330x_init,
@@ -768,9 +778,8 @@ static struct dvb_frontend_ops lgdt3303_ops = {
768 .frequency_min= 54000000, 778 .frequency_min= 54000000,
769 .frequency_max= 858000000, 779 .frequency_max= 858000000,
770 .frequency_stepsize= 62500, 780 .frequency_stepsize= 62500,
771 /* Symbol rate is for all VSB modes need to check QAM */ 781 .symbol_rate_min = 5056941, /* QAM 64 */
772 .symbol_rate_min = 10762000, 782 .symbol_rate_max = 10762000, /* VSB 8 */
773 .symbol_rate_max = 10762000,
774 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB 783 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
775 }, 784 },
776 .init = lgdt330x_init, 785 .init = lgdt330x_init,
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index e209ba1e47c5..2a6529cccf1a 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -47,6 +47,10 @@ struct lgdt330x_config
47 47
48 /* Need to set device param for start_dma */ 48 /* Need to set device param for start_dma */
49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
50
51 /* Flip the polarity of the mpeg data transfer clock using alternate init data
52 * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */
53 int clock_polarity_flip;
50}; 54};
51 55
52extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, 56extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index e38454901dd1..9c67f406d581 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -677,8 +677,7 @@ struct dvb_frontend* mt312_attach(const struct mt312_config* config,
677 return &state->frontend; 677 return &state->frontend;
678 678
679error: 679error:
680 if (state) 680 kfree(state);
681 kfree(state);
682 return NULL; 681 return NULL;
683} 682}
684 683
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
new file mode 100644
index 000000000000..bad0933eb714
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -0,0 +1,1205 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
5 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
6 * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22*/
23
24/*
25 * NOTES ABOUT THIS DRIVER
26 *
27 * This Linux driver supports:
28 * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
29 * AverTVHD MCE A180 (NXT2004)
30 * ATI HDTV Wonder (NXT2004)
31 *
32 * This driver needs external firmware. Please use the command
33 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
34 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
35 * download/extract the appropriate firmware, and then copy it to
36 * /usr/lib/hotplug/firmware/ or /lib/firmware/
37 * (depending on configuration of firmware hotplug).
38 */
39#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
40#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
41#define CRC_CCIT_MASK 0x1021
42
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/module.h>
46#include <linux/moduleparam.h>
47
48#include "dvb_frontend.h"
49#include "dvb-pll.h"
50#include "nxt200x.h"
51
52struct nxt200x_state {
53
54 struct i2c_adapter* i2c;
55 struct dvb_frontend_ops ops;
56 const struct nxt200x_config* config;
57 struct dvb_frontend frontend;
58
59 /* demodulator private data */
60 nxt_chip_type demod_chip;
61 u8 initialised:1;
62};
63
64static int debug;
65#define dprintk(args...) \
66 do { \
67 if (debug) printk(KERN_DEBUG "nxt200x: " args); \
68 } while (0)
69
70static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
71{
72 int err;
73 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
74
75 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
76 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
77 __FUNCTION__, addr, err);
78 return -EREMOTEIO;
79 }
80 return 0;
81}
82
83static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len)
84{
85 int err;
86 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
87
88 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
89 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
90 __FUNCTION__, addr, err);
91 return -EREMOTEIO;
92 }
93 return 0;
94}
95
96static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 len)
97{
98 u8 buf2 [len+1];
99 int err;
100 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
101
102 buf2[0] = reg;
103 memcpy(&buf2[1], buf, len);
104
105 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
106 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
107 __FUNCTION__, state->config->demod_address, err);
108 return -EREMOTEIO;
109 }
110 return 0;
111}
112
113static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len)
114{
115 u8 reg2 [] = { reg };
116
117 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
118 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
119
120 int err;
121
122 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
123 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
124 __FUNCTION__, state->config->demod_address, err);
125 return -EREMOTEIO;
126 }
127 return 0;
128}
129
130static u16 nxt200x_crc(u16 crc, u8 c)
131{
132 u8 i;
133 u16 input = (u16) c & 0xFF;
134
135 input<<=8;
136 for(i=0; i<8; i++) {
137 if((crc^input) & 0x8000)
138 crc=(crc<<1)^CRC_CCIT_MASK;
139 else
140 crc<<=1;
141 input<<=1;
142 }
143 return crc;
144}
145
146static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
147{
148 u8 attr, len2, buf;
149 dprintk("%s\n", __FUNCTION__);
150
151 /* set mutli register register */
152 nxt200x_writebytes(state, 0x35, &reg, 1);
153
154 /* send the actual data */
155 nxt200x_writebytes(state, 0x36, data, len);
156
157 switch (state->demod_chip) {
158 case NXT2002:
159 len2 = len;
160 buf = 0x02;
161 break;
162 case NXT2004:
163 /* probably not right, but gives correct values */
164 attr = 0x02;
165 if (reg & 0x80) {
166 attr = attr << 1;
167 if (reg & 0x04)
168 attr = attr >> 1;
169 }
170 /* set write bit */
171 len2 = ((attr << 4) | 0x10) | len;
172 buf = 0x80;
173 break;
174 default:
175 return -EINVAL;
176 break;
177 }
178
179 /* set multi register length */
180 nxt200x_writebytes(state, 0x34, &len2, 1);
181
182 /* toggle the multireg write bit */
183 nxt200x_writebytes(state, 0x21, &buf, 1);
184
185 nxt200x_readbytes(state, 0x21, &buf, 1);
186
187 switch (state->demod_chip) {
188 case NXT2002:
189 if ((buf & 0x02) == 0)
190 return 0;
191 break;
192 case NXT2004:
193 if (buf == 0)
194 return 0;
195 break;
196 default:
197 return -EINVAL;
198 break;
199 }
200
201 printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg);
202
203 return 0;
204}
205
206static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
207{
208 int i;
209 u8 buf, len2, attr;
210 dprintk("%s\n", __FUNCTION__);
211
212 /* set mutli register register */
213 nxt200x_writebytes(state, 0x35, &reg, 1);
214
215 switch (state->demod_chip) {
216 case NXT2002:
217 /* set multi register length */
218 len2 = len & 0x80;
219 nxt200x_writebytes(state, 0x34, &len2, 1);
220
221 /* read the actual data */
222 nxt200x_readbytes(state, reg, data, len);
223 return 0;
224 break;
225 case NXT2004:
226 /* probably not right, but gives correct values */
227 attr = 0x02;
228 if (reg & 0x80) {
229 attr = attr << 1;
230 if (reg & 0x04)
231 attr = attr >> 1;
232 }
233
234 /* set multi register length */
235 len2 = (attr << 4) | len;
236 nxt200x_writebytes(state, 0x34, &len2, 1);
237
238 /* toggle the multireg bit*/
239 buf = 0x80;
240 nxt200x_writebytes(state, 0x21, &buf, 1);
241
242 /* read the actual data */
243 for(i = 0; i < len; i++) {
244 nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
245 }
246 return 0;
247 break;
248 default:
249 return -EINVAL;
250 break;
251 }
252}
253
254static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
255{
256 u8 buf, stopval, counter = 0;
257 dprintk("%s\n", __FUNCTION__);
258
259 /* set correct stop value */
260 switch (state->demod_chip) {
261 case NXT2002:
262 stopval = 0x40;
263 break;
264 case NXT2004:
265 stopval = 0x10;
266 break;
267 default:
268 stopval = 0;
269 break;
270 }
271
272 buf = 0x80;
273 nxt200x_writebytes(state, 0x22, &buf, 1);
274
275 while (counter < 20) {
276 nxt200x_readbytes(state, 0x31, &buf, 1);
277 if (buf & stopval)
278 return;
279 msleep(10);
280 counter++;
281 }
282
283 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
284 return;
285}
286
287static void nxt200x_microcontroller_start (struct nxt200x_state* state)
288{
289 u8 buf;
290 dprintk("%s\n", __FUNCTION__);
291
292 buf = 0x00;
293 nxt200x_writebytes(state, 0x22, &buf, 1);
294}
295
296static void nxt2004_microcontroller_init (struct nxt200x_state* state)
297{
298 u8 buf[9];
299 u8 counter = 0;
300 dprintk("%s\n", __FUNCTION__);
301
302 buf[0] = 0x00;
303 nxt200x_writebytes(state, 0x2b, buf, 1);
304 buf[0] = 0x70;
305 nxt200x_writebytes(state, 0x34, buf, 1);
306 buf[0] = 0x04;
307 nxt200x_writebytes(state, 0x35, buf, 1);
308 buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
309 buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
310 nxt200x_writebytes(state, 0x36, buf, 9);
311 buf[0] = 0x80;
312 nxt200x_writebytes(state, 0x21, buf, 1);
313
314 while (counter < 20) {
315 nxt200x_readbytes(state, 0x21, buf, 1);
316 if (buf[0] == 0)
317 return;
318 msleep(10);
319 counter++;
320 }
321
322 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n");
323
324 return;
325}
326
327static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
328{
329 u8 buf, count = 0;
330
331 dprintk("%s\n", __FUNCTION__);
332
333 dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]);
334
335 /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
336 * direct write is required for Philips TUV1236D and ALPS TDHU2 */
337 switch (state->demod_chip) {
338 case NXT2004:
339 if (i2c_writebytes(state, state->config->pll_address, data, 4))
340 printk(KERN_WARNING "nxt200x: error writing to tuner\n");
341 /* wait until we have a lock */
342 while (count < 20) {
343 i2c_readbytes(state, state->config->pll_address, &buf, 1);
344 if (buf & 0x40)
345 return 0;
346 msleep(100);
347 count++;
348 }
349 printk("nxt2004: timeout waiting for tuner lock\n");
350 break;
351 case NXT2002:
352 /* set the i2c transfer speed to the tuner */
353 buf = 0x03;
354 nxt200x_writebytes(state, 0x20, &buf, 1);
355
356 /* setup to transfer 4 bytes via i2c */
357 buf = 0x04;
358 nxt200x_writebytes(state, 0x34, &buf, 1);
359
360 /* write actual tuner bytes */
361 nxt200x_writebytes(state, 0x36, data, 4);
362
363 /* set tuner i2c address */
364 buf = state->config->pll_address;
365 nxt200x_writebytes(state, 0x35, &buf, 1);
366
367 /* write UC Opmode to begin transfer */
368 buf = 0x80;
369 nxt200x_writebytes(state, 0x21, &buf, 1);
370
371 while (count < 20) {
372 nxt200x_readbytes(state, 0x21, &buf, 1);
373 if ((buf & 0x80)== 0x00)
374 return 0;
375 msleep(100);
376 count++;
377 }
378 printk("nxt2002: timeout error writing tuner\n");
379 break;
380 default:
381 return -EINVAL;
382 break;
383 }
384 return 0;
385}
386
387static void nxt200x_agc_reset(struct nxt200x_state* state)
388{
389 u8 buf;
390 dprintk("%s\n", __FUNCTION__);
391
392 switch (state->demod_chip) {
393 case NXT2002:
394 buf = 0x08;
395 nxt200x_writebytes(state, 0x08, &buf, 1);
396 buf = 0x00;
397 nxt200x_writebytes(state, 0x08, &buf, 1);
398 break;
399 case NXT2004:
400 nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
401 buf = 0x08;
402 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
403 buf = 0x00;
404 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
405 break;
406 default:
407 break;
408 }
409 return;
410}
411
412static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
413{
414
415 struct nxt200x_state* state = fe->demodulator_priv;
416 u8 buf[3], written = 0, chunkpos = 0;
417 u16 rambase, position, crc = 0;
418
419 dprintk("%s\n", __FUNCTION__);
420 dprintk("Firmware is %zu bytes\n", fw->size);
421
422 /* Get the RAM base for this nxt2002 */
423 nxt200x_readbytes(state, 0x10, buf, 1);
424
425 if (buf[0] & 0x10)
426 rambase = 0x1000;
427 else
428 rambase = 0x0000;
429
430 dprintk("rambase on this nxt2002 is %04X\n", rambase);
431
432 /* Hold the micro in reset while loading firmware */
433 buf[0] = 0x80;
434 nxt200x_writebytes(state, 0x2B, buf, 1);
435
436 for (position = 0; position < fw->size; position++) {
437 if (written == 0) {
438 crc = 0;
439 chunkpos = 0x28;
440 buf[0] = ((rambase + position) >> 8);
441 buf[1] = (rambase + position) & 0xFF;
442 buf[2] = 0x81;
443 /* write starting address */
444 nxt200x_writebytes(state, 0x29, buf, 3);
445 }
446 written++;
447 chunkpos++;
448
449 if ((written % 4) == 0)
450 nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
451
452 crc = nxt200x_crc(crc, fw->data[position]);
453
454 if ((written == 255) || (position+1 == fw->size)) {
455 /* write remaining bytes of firmware */
456 nxt200x_writebytes(state, chunkpos+4-(written %4),
457 &fw->data[position-(written %4) + 1],
458 written %4);
459 buf[0] = crc << 8;
460 buf[1] = crc & 0xFF;
461
462 /* write crc */
463 nxt200x_writebytes(state, 0x2C, buf, 2);
464
465 /* do a read to stop things */
466 nxt200x_readbytes(state, 0x2A, buf, 1);
467
468 /* set transfer mode to complete */
469 buf[0] = 0x80;
470 nxt200x_writebytes(state, 0x2B, buf, 1);
471
472 written = 0;
473 }
474 }
475
476 return 0;
477};
478
479static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
480{
481
482 struct nxt200x_state* state = fe->demodulator_priv;
483 u8 buf[3];
484 u16 rambase, position, crc=0;
485
486 dprintk("%s\n", __FUNCTION__);
487 dprintk("Firmware is %zu bytes\n", fw->size);
488
489 /* set rambase */
490 rambase = 0x1000;
491
492 /* hold the micro in reset while loading firmware */
493 buf[0] = 0x80;
494 nxt200x_writebytes(state, 0x2B, buf,1);
495
496 /* calculate firmware CRC */
497 for (position = 0; position < fw->size; position++) {
498 crc = nxt200x_crc(crc, fw->data[position]);
499 }
500
501 buf[0] = rambase >> 8;
502 buf[1] = rambase & 0xFF;
503 buf[2] = 0x81;
504 /* write starting address */
505 nxt200x_writebytes(state,0x29,buf,3);
506
507 for (position = 0; position < fw->size;) {
508 nxt200x_writebytes(state, 0x2C, &fw->data[position],
509 fw->size-position > 255 ? 255 : fw->size-position);
510 position += (fw->size-position > 255 ? 255 : fw->size-position);
511 }
512 buf[0] = crc >> 8;
513 buf[1] = crc & 0xFF;
514
515 dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
516
517 /* write crc */
518 nxt200x_writebytes(state, 0x2C, buf,2);
519
520 /* do a read to stop things */
521 nxt200x_readbytes(state, 0x2C, buf, 1);
522
523 /* set transfer mode to complete */
524 buf[0] = 0x80;
525 nxt200x_writebytes(state, 0x2B, buf,1);
526
527 return 0;
528};
529
530static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
531 struct dvb_frontend_parameters *p)
532{
533 struct nxt200x_state* state = fe->demodulator_priv;
534 u8 buf[4];
535
536 /* stop the micro first */
537 nxt200x_microcontroller_stop(state);
538
539 if (state->demod_chip == NXT2004) {
540 /* make sure demod is set to digital */
541 buf[0] = 0x04;
542 nxt200x_writebytes(state, 0x14, buf, 1);
543 buf[0] = 0x00;
544 nxt200x_writebytes(state, 0x17, buf, 1);
545 }
546
547 /* get tuning information */
548 dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0);
549
550 /* set additional params */
551 switch (p->u.vsb.modulation) {
552 case QAM_64:
553 case QAM_256:
554 /* Set punctured clock for QAM */
555 /* This is just a guess since I am unable to test it */
556 if (state->config->set_ts_params)
557 state->config->set_ts_params(fe, 1);
558
559 /* set input */
560 if (state->config->set_pll_input)
561 state->config->set_pll_input(buf, 1);
562 break;
563 case VSB_8:
564 /* Set non-punctured clock for VSB */
565 if (state->config->set_ts_params)
566 state->config->set_ts_params(fe, 0);
567
568 /* set input */
569 if (state->config->set_pll_input)
570 state->config->set_pll_input(buf, 0);
571 break;
572 default:
573 return -EINVAL;
574 break;
575 }
576
577 /* write frequency information */
578 nxt200x_writetuner(state, buf);
579
580 /* reset the agc now that tuning has been completed */
581 nxt200x_agc_reset(state);
582
583 /* set target power level */
584 switch (p->u.vsb.modulation) {
585 case QAM_64:
586 case QAM_256:
587 buf[0] = 0x74;
588 break;
589 case VSB_8:
590 buf[0] = 0x70;
591 break;
592 default:
593 return -EINVAL;
594 break;
595 }
596 nxt200x_writebytes(state, 0x42, buf, 1);
597
598 /* configure sdm */
599 switch (state->demod_chip) {
600 case NXT2002:
601 buf[0] = 0x87;
602 break;
603 case NXT2004:
604 buf[0] = 0x07;
605 break;
606 default:
607 return -EINVAL;
608 break;
609 }
610 nxt200x_writebytes(state, 0x57, buf, 1);
611
612 /* write sdm1 input */
613 buf[0] = 0x10;
614 buf[1] = 0x00;
615 nxt200x_writebytes(state, 0x58, buf, 2);
616
617 /* write sdmx input */
618 switch (p->u.vsb.modulation) {
619 case QAM_64:
620 buf[0] = 0x68;
621 break;
622 case QAM_256:
623 buf[0] = 0x64;
624 break;
625 case VSB_8:
626 buf[0] = 0x60;
627 break;
628 default:
629 return -EINVAL;
630 break;
631 }
632 buf[1] = 0x00;
633 nxt200x_writebytes(state, 0x5C, buf, 2);
634
635 /* write adc power lpf fc */
636 buf[0] = 0x05;
637 nxt200x_writebytes(state, 0x43, buf, 1);
638
639 if (state->demod_chip == NXT2004) {
640 /* write ??? */
641 buf[0] = 0x00;
642 buf[1] = 0x00;
643 nxt200x_writebytes(state, 0x46, buf, 2);
644 }
645
646 /* write accumulator2 input */
647 buf[0] = 0x80;
648 buf[1] = 0x00;
649 nxt200x_writebytes(state, 0x4B, buf, 2);
650
651 /* write kg1 */
652 buf[0] = 0x00;
653 nxt200x_writebytes(state, 0x4D, buf, 1);
654
655 /* write sdm12 lpf fc */
656 buf[0] = 0x44;
657 nxt200x_writebytes(state, 0x55, buf, 1);
658
659 /* write agc control reg */
660 buf[0] = 0x04;
661 nxt200x_writebytes(state, 0x41, buf, 1);
662
663 if (state->demod_chip == NXT2004) {
664 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
665 buf[0] = 0x24;
666 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
667
668 /* soft reset? */
669 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
670 buf[0] = 0x10;
671 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
672 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
673 buf[0] = 0x00;
674 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
675
676 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
677 buf[0] = 0x04;
678 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
679 buf[0] = 0x00;
680 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
681 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
682 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
683 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
684 buf[0] = 0x11;
685 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
686 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
687 buf[0] = 0x44;
688 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
689 }
690
691 /* write agc ucgp0 */
692 switch (p->u.vsb.modulation) {
693 case QAM_64:
694 buf[0] = 0x02;
695 break;
696 case QAM_256:
697 buf[0] = 0x03;
698 break;
699 case VSB_8:
700 buf[0] = 0x00;
701 break;
702 default:
703 return -EINVAL;
704 break;
705 }
706 nxt200x_writebytes(state, 0x30, buf, 1);
707
708 /* write agc control reg */
709 buf[0] = 0x00;
710 nxt200x_writebytes(state, 0x41, buf, 1);
711
712 /* write accumulator2 input */
713 buf[0] = 0x80;
714 buf[1] = 0x00;
715 nxt200x_writebytes(state, 0x49, buf,2);
716 nxt200x_writebytes(state, 0x4B, buf,2);
717
718 /* write agc control reg */
719 buf[0] = 0x04;
720 nxt200x_writebytes(state, 0x41, buf, 1);
721
722 nxt200x_microcontroller_start(state);
723
724 if (state->demod_chip == NXT2004) {
725 nxt2004_microcontroller_init(state);
726
727 /* ???? */
728 buf[0] = 0xF0;
729 buf[1] = 0x00;
730 nxt200x_writebytes(state, 0x5C, buf, 2);
731 }
732
733 /* adjacent channel detection should be done here, but I don't
734 have any stations with this need so I cannot test it */
735
736 return 0;
737}
738
739static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
740{
741 struct nxt200x_state* state = fe->demodulator_priv;
742 u8 lock;
743 nxt200x_readbytes(state, 0x31, &lock, 1);
744
745 *status = 0;
746 if (lock & 0x20) {
747 *status |= FE_HAS_SIGNAL;
748 *status |= FE_HAS_CARRIER;
749 *status |= FE_HAS_VITERBI;
750 *status |= FE_HAS_SYNC;
751 *status |= FE_HAS_LOCK;
752 }
753 return 0;
754}
755
756static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
757{
758 struct nxt200x_state* state = fe->demodulator_priv;
759 u8 b[3];
760
761 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
762
763 *ber = ((b[0] << 8) + b[1]) * 8;
764
765 return 0;
766}
767
768static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
769{
770 struct nxt200x_state* state = fe->demodulator_priv;
771 u8 b[2];
772 u16 temp = 0;
773
774 /* setup to read cluster variance */
775 b[0] = 0x00;
776 nxt200x_writebytes(state, 0xA1, b, 1);
777
778 /* get multreg val */
779 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
780
781 temp = (b[0] << 8) | b[1];
782 *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
783
784 return 0;
785}
786
787static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
788{
789
790 struct nxt200x_state* state = fe->demodulator_priv;
791 u8 b[2];
792 u16 temp = 0, temp2;
793 u32 snrdb = 0;
794
795 /* setup to read cluster variance */
796 b[0] = 0x00;
797 nxt200x_writebytes(state, 0xA1, b, 1);
798
799 /* get multreg val from 0xA6 */
800 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
801
802 temp = (b[0] << 8) | b[1];
803 temp2 = 0x7FFF - temp;
804
805 /* snr will be in db */
806 if (temp2 > 0x7F00)
807 snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
808 else if (temp2 > 0x7EC0)
809 snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
810 else if (temp2 > 0x7C00)
811 snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
812 else
813 snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
814
815 /* the value reported back from the frontend will be FFFF=32db 0000=0db */
816 *snr = snrdb * (0xFFFF/32000);
817
818 return 0;
819}
820
821static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
822{
823 struct nxt200x_state* state = fe->demodulator_priv;
824 u8 b[3];
825
826 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
827 *ucblocks = b[2];
828
829 return 0;
830}
831
832static int nxt200x_sleep(struct dvb_frontend* fe)
833{
834 return 0;
835}
836
837static int nxt2002_init(struct dvb_frontend* fe)
838{
839 struct nxt200x_state* state = fe->demodulator_priv;
840 const struct firmware *fw;
841 int ret;
842 u8 buf[2];
843
844 /* request the firmware, this will block until someone uploads it */
845 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
846 ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev);
847 printk("nxt2002: Waiting for firmware upload(2)...\n");
848 if (ret) {
849 printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
850 return ret;
851 }
852
853 ret = nxt2002_load_firmware(fe, fw);
854 if (ret) {
855 printk("nxt2002: Writing firmware to device failed\n");
856 release_firmware(fw);
857 return ret;
858 }
859 printk("nxt2002: Firmware upload complete\n");
860
861 /* Put the micro into reset */
862 nxt200x_microcontroller_stop(state);
863
864 /* ensure transfer is complete */
865 buf[0]=0x00;
866 nxt200x_writebytes(state, 0x2B, buf, 1);
867
868 /* Put the micro into reset for real this time */
869 nxt200x_microcontroller_stop(state);
870
871 /* soft reset everything (agc,frontend,eq,fec)*/
872 buf[0] = 0x0F;
873 nxt200x_writebytes(state, 0x08, buf, 1);
874 buf[0] = 0x00;
875 nxt200x_writebytes(state, 0x08, buf, 1);
876
877 /* write agc sdm configure */
878 buf[0] = 0xF1;
879 nxt200x_writebytes(state, 0x57, buf, 1);
880
881 /* write mod output format */
882 buf[0] = 0x20;
883 nxt200x_writebytes(state, 0x09, buf, 1);
884
885 /* write fec mpeg mode */
886 buf[0] = 0x7E;
887 buf[1] = 0x00;
888 nxt200x_writebytes(state, 0xE9, buf, 2);
889
890 /* write mux selection */
891 buf[0] = 0x00;
892 nxt200x_writebytes(state, 0xCC, buf, 1);
893
894 return 0;
895}
896
897static int nxt2004_init(struct dvb_frontend* fe)
898{
899 struct nxt200x_state* state = fe->demodulator_priv;
900 const struct firmware *fw;
901 int ret;
902 u8 buf[3];
903
904 /* ??? */
905 buf[0]=0x00;
906 nxt200x_writebytes(state, 0x1E, buf, 1);
907
908 /* request the firmware, this will block until someone uploads it */
909 printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
910 ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev);
911 printk("nxt2004: Waiting for firmware upload(2)...\n");
912 if (ret) {
913 printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
914 return ret;
915 }
916
917 ret = nxt2004_load_firmware(fe, fw);
918 if (ret) {
919 printk("nxt2004: Writing firmware to device failed\n");
920 release_firmware(fw);
921 return ret;
922 }
923 printk("nxt2004: Firmware upload complete\n");
924
925 /* ensure transfer is complete */
926 buf[0] = 0x01;
927 nxt200x_writebytes(state, 0x19, buf, 1);
928
929 nxt2004_microcontroller_init(state);
930 nxt200x_microcontroller_stop(state);
931 nxt200x_microcontroller_stop(state);
932 nxt2004_microcontroller_init(state);
933 nxt200x_microcontroller_stop(state);
934
935 /* soft reset everything (agc,frontend,eq,fec)*/
936 buf[0] = 0xFF;
937 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
938 buf[0] = 0x00;
939 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
940
941 /* write agc sdm configure */
942 buf[0] = 0xD7;
943 nxt200x_writebytes(state, 0x57, buf, 1);
944
945 /* ???*/
946 buf[0] = 0x07;
947 buf[1] = 0xfe;
948 nxt200x_writebytes(state, 0x35, buf, 2);
949 buf[0] = 0x12;
950 nxt200x_writebytes(state, 0x34, buf, 1);
951 buf[0] = 0x80;
952 nxt200x_writebytes(state, 0x21, buf, 1);
953
954 /* ???*/
955 buf[0] = 0x21;
956 nxt200x_writebytes(state, 0x0A, buf, 1);
957
958 /* ???*/
959 buf[0] = 0x01;
960 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
961
962 /* write fec mpeg mode */
963 buf[0] = 0x7E;
964 buf[1] = 0x00;
965 nxt200x_writebytes(state, 0xE9, buf, 2);
966
967 /* write mux selection */
968 buf[0] = 0x00;
969 nxt200x_writebytes(state, 0xCC, buf, 1);
970
971 /* ???*/
972 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
973 buf[0] = 0x00;
974 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
975
976 /* soft reset? */
977 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
978 buf[0] = 0x10;
979 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
980 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
981 buf[0] = 0x00;
982 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
983
984 /* ???*/
985 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
986 buf[0] = 0x01;
987 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
988 buf[0] = 0x70;
989 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
990 buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
991 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
992
993 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
994 buf[0] = 0x11;
995 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
996 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
997 buf[0] = 0x40;
998 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
999
1000 nxt200x_readbytes(state, 0x10, buf, 1);
1001 buf[0] = 0x10;
1002 nxt200x_writebytes(state, 0x10, buf, 1);
1003 nxt200x_readbytes(state, 0x0A, buf, 1);
1004 buf[0] = 0x21;
1005 nxt200x_writebytes(state, 0x0A, buf, 1);
1006
1007 nxt2004_microcontroller_init(state);
1008
1009 buf[0] = 0x21;
1010 nxt200x_writebytes(state, 0x0A, buf, 1);
1011 buf[0] = 0x7E;
1012 nxt200x_writebytes(state, 0xE9, buf, 1);
1013 buf[0] = 0x00;
1014 nxt200x_writebytes(state, 0xEA, buf, 1);
1015
1016 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1017 buf[0] = 0x00;
1018 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1019 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1020 buf[0] = 0x00;
1021 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1022
1023 /* soft reset? */
1024 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1025 buf[0] = 0x10;
1026 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1027 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1028 buf[0] = 0x00;
1029 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1030
1031 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1032 buf[0] = 0x04;
1033 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1034 buf[0] = 0x00;
1035 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1036 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
1037 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1038
1039 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1040 buf[0] = 0x11;
1041 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1042
1043 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1044 buf[0] = 0x44;
1045 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1046
1047 /* initialize tuner */
1048 nxt200x_readbytes(state, 0x10, buf, 1);
1049 buf[0] = 0x12;
1050 nxt200x_writebytes(state, 0x10, buf, 1);
1051 buf[0] = 0x04;
1052 nxt200x_writebytes(state, 0x13, buf, 1);
1053 buf[0] = 0x00;
1054 nxt200x_writebytes(state, 0x16, buf, 1);
1055 buf[0] = 0x04;
1056 nxt200x_writebytes(state, 0x14, buf, 1);
1057 buf[0] = 0x00;
1058 nxt200x_writebytes(state, 0x14, buf, 1);
1059 nxt200x_writebytes(state, 0x17, buf, 1);
1060 nxt200x_writebytes(state, 0x14, buf, 1);
1061 nxt200x_writebytes(state, 0x17, buf, 1);
1062
1063 return 0;
1064}
1065
1066static int nxt200x_init(struct dvb_frontend* fe)
1067{
1068 struct nxt200x_state* state = fe->demodulator_priv;
1069 int ret = 0;
1070
1071 if (!state->initialised) {
1072 switch (state->demod_chip) {
1073 case NXT2002:
1074 ret = nxt2002_init(fe);
1075 break;
1076 case NXT2004:
1077 ret = nxt2004_init(fe);
1078 break;
1079 default:
1080 return -EINVAL;
1081 break;
1082 }
1083 state->initialised = 1;
1084 }
1085 return ret;
1086}
1087
1088static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1089{
1090 fesettings->min_delay_ms = 500;
1091 fesettings->step_size = 0;
1092 fesettings->max_drift = 0;
1093 return 0;
1094}
1095
1096static void nxt200x_release(struct dvb_frontend* fe)
1097{
1098 struct nxt200x_state* state = fe->demodulator_priv;
1099 kfree(state);
1100}
1101
1102static struct dvb_frontend_ops nxt200x_ops;
1103
1104struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
1105 struct i2c_adapter* i2c)
1106{
1107 struct nxt200x_state* state = NULL;
1108 u8 buf [] = {0,0,0,0,0};
1109
1110 /* allocate memory for the internal state */
1111 state = (struct nxt200x_state*) kmalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
1112 if (state == NULL)
1113 goto error;
1114 memset(state,0,sizeof(*state));
1115
1116 /* setup the state */
1117 state->config = config;
1118 state->i2c = i2c;
1119 memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
1120 state->initialised = 0;
1121
1122 /* read card id */
1123 nxt200x_readbytes(state, 0x00, buf, 5);
1124 dprintk("NXT info: %02X %02X %02X %02X %02X\n",
1125 buf[0], buf[1], buf[2], buf[3], buf[4]);
1126
1127 /* set demod chip */
1128 switch (buf[0]) {
1129 case 0x04:
1130 state->demod_chip = NXT2002;
1131 printk("nxt200x: NXT2002 Detected\n");
1132 break;
1133 case 0x05:
1134 state->demod_chip = NXT2004;
1135 printk("nxt200x: NXT2004 Detected\n");
1136 break;
1137 default:
1138 goto error;
1139 }
1140
1141 /* make sure demod chip is supported */
1142 switch (state->demod_chip) {
1143 case NXT2002:
1144 if (buf[0] != 0x04) goto error; /* device id */
1145 if (buf[1] != 0x02) goto error; /* fab id */
1146 if (buf[2] != 0x11) goto error; /* month */
1147 if (buf[3] != 0x20) goto error; /* year msb */
1148 if (buf[4] != 0x00) goto error; /* year lsb */
1149 break;
1150 case NXT2004:
1151 if (buf[0] != 0x05) goto error; /* device id */
1152 break;
1153 default:
1154 goto error;
1155 }
1156
1157 /* create dvb_frontend */
1158 state->frontend.ops = &state->ops;
1159 state->frontend.demodulator_priv = state;
1160 return &state->frontend;
1161
1162error:
1163 kfree(state);
1164 printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",
1165 buf[0], buf[1], buf[2], buf[3], buf[4]);
1166 return NULL;
1167}
1168
1169static struct dvb_frontend_ops nxt200x_ops = {
1170
1171 .info = {
1172 .name = "Nextwave NXT200X VSB/QAM frontend",
1173 .type = FE_ATSC,
1174 .frequency_min = 54000000,
1175 .frequency_max = 860000000,
1176 .frequency_stepsize = 166666, /* stepsize is just a guess */
1177 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1178 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1179 FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
1180 },
1181
1182 .release = nxt200x_release,
1183
1184 .init = nxt200x_init,
1185 .sleep = nxt200x_sleep,
1186
1187 .set_frontend = nxt200x_setup_frontend_parameters,
1188 .get_tune_settings = nxt200x_get_tune_settings,
1189
1190 .read_status = nxt200x_read_status,
1191 .read_ber = nxt200x_read_ber,
1192 .read_signal_strength = nxt200x_read_signal_strength,
1193 .read_snr = nxt200x_read_snr,
1194 .read_ucblocks = nxt200x_read_ucblocks,
1195};
1196
1197module_param(debug, int, 0644);
1198MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1199
1200MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
1201MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob");
1202MODULE_LICENSE("GPL");
1203
1204EXPORT_SYMBOL(nxt200x_attach);
1205
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
new file mode 100644
index 000000000000..1d9d70bc37ef
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -0,0 +1,61 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
5 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
6 * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22*/
23
24#ifndef NXT200X_H
25#define NXT200X_H
26
27#include <linux/dvb/frontend.h>
28#include <linux/firmware.h>
29
30typedef enum nxt_chip_t {
31 NXTUNDEFINED,
32 NXT2002,
33 NXT2004
34}nxt_chip_type;
35
36struct nxt200x_config
37{
38 /* the demodulator's i2c address */
39 u8 demod_address;
40
41 /* tuner information */
42 u8 pll_address;
43 struct dvb_pll_desc *pll_desc;
44
45 /* used to set pll input */
46 int (*set_pll_input)(u8* buf, int input);
47
48 /* need to set device param for start_dma */
49 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
50};
51
52extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
53 struct i2c_adapter* i2c);
54
55#endif /* NXT200X_H */
56
57/*
58 * Local variables:
59 * c-basic-offset: 8
60 * End:
61 */
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index 817b044c7fd1..78bded861d02 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -468,6 +468,7 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
468 unsigned char snd_buf[2]; 468 unsigned char snd_buf[2];
469 u8 rcvr_stat; 469 u8 rcvr_stat;
470 u16 snr_equ; 470 u16 snr_equ;
471 u32 signal_strength;
471 int usK; 472 int usK;
472 473
473 snd_buf[0]=0x04; 474 snd_buf[0]=0x04;
@@ -503,7 +504,11 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
503 usK = (rcvr_stat & 0x10) ? 3 : 0; 504 usK = (rcvr_stat & 0x10) ? 3 : 0;
504 505
505 /* The value reported back from the frontend will be FFFF=100% 0000=0% */ 506 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
506 *strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000; 507 signal_strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
508 if (signal_strength > 0xffff)
509 *strength = 0xffff;
510 else
511 *strength = signal_strength;
507 dprintk("read_signal_strength %i\n",*strength); 512 dprintk("read_signal_strength %i\n",*strength);
508 513
509 return 0; 514 return 0;
@@ -577,8 +582,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config,
577 return &state->frontend; 582 return &state->frontend;
578 583
579error: 584error:
580 if (state) 585 kfree(state);
581 kfree(state);
582 return NULL; 586 return NULL;
583} 587}
584 588
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 8a9db23dd1b7..531f76246e5f 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -339,6 +339,7 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
339 u8 rec_buf[2]; 339 u8 rec_buf[2];
340 u8 snd_buf[4]; 340 u8 snd_buf[4];
341 u8 snr_equ; 341 u8 snr_equ;
342 u32 signal_strength;
342 343
343 /* SNR after Equalizer */ 344 /* SNR after Equalizer */
344 snd_buf[0] = 0x04; 345 snd_buf[0] = 0x04;
@@ -358,8 +359,11 @@ static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
358 snr_equ = rec_buf[0] & 0xff; 359 snr_equ = rec_buf[0] & 0xff;
359 360
360 /* The value reported back from the frontend will be FFFF=100% 0000=0% */ 361 /* The value reported back from the frontend will be FFFF=100% 0000=0% */
361 *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000; 362 signal_strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
362 363 if (signal_strength > 0xffff)
364 *strength = 0xffff;
365 else
366 *strength = signal_strength;
363 dprintk("read_signal_strength %i\n",*strength); 367 dprintk("read_signal_strength %i\n",*strength);
364 368
365 return 0; 369 return 0;
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 889d9257215d..29c48665e130 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -64,8 +64,12 @@ struct stv0299_state {
64 u32 tuner_frequency; 64 u32 tuner_frequency;
65 u32 symbol_rate; 65 u32 symbol_rate;
66 fe_code_rate_t fec_inner; 66 fe_code_rate_t fec_inner;
67 int errmode;
67}; 68};
68 69
70#define STATUS_BER 0
71#define STATUS_UCBLOCKS 1
72
69static int debug; 73static int debug;
70static int debug_legacy_dish_switch; 74static int debug_legacy_dish_switch;
71#define dprintk(args...) \ 75#define dprintk(args...) \
@@ -383,36 +387,6 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
383 }; 387 };
384} 388}
385 389
386static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime)
387{
388 return ((curtime.tv_usec < lasttime.tv_usec) ?
389 1000000 - lasttime.tv_usec + curtime.tv_usec :
390 curtime.tv_usec - lasttime.tv_usec);
391}
392
393static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec)
394{
395 struct timeval lasttime;
396 s32 delta, newdelta;
397
398 waketime->tv_usec += add_usec;
399 if (waketime->tv_usec >= 1000000) {
400 waketime->tv_usec -= 1000000;
401 waketime->tv_sec++;
402 }
403
404 do_gettimeofday (&lasttime);
405 delta = stv0299_calc_usec_delay (lasttime, *waketime);
406 if (delta > 2500) {
407 msleep ((delta - 1500) / 1000);
408 do_gettimeofday (&lasttime);
409 newdelta = stv0299_calc_usec_delay (lasttime, *waketime);
410 delta = (newdelta > delta) ? 0 : newdelta;
411 }
412 if (delta > 0)
413 udelay (delta);
414}
415
416static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) 390static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
417{ 391{
418 struct stv0299_state* state = fe->demodulator_priv; 392 struct stv0299_state* state = fe->demodulator_priv;
@@ -440,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
440 memcpy (&tv[0], &nexttime, sizeof (struct timeval)); 414 memcpy (&tv[0], &nexttime, sizeof (struct timeval));
441 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ 415 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
442 416
443 stv0299_sleep_until (&nexttime, 32000); 417 dvb_frontend_sleep_until(&nexttime, 32000);
444 418
445 for (i=0; i<9; i++) { 419 for (i=0; i<9; i++) {
446 if (debug_legacy_dish_switch) 420 if (debug_legacy_dish_switch)
@@ -454,13 +428,13 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd)
454 cmd = cmd >> 1; 428 cmd = cmd >> 1;
455 429
456 if (i != 8) 430 if (i != 8)
457 stv0299_sleep_until (&nexttime, 8000); 431 dvb_frontend_sleep_until(&nexttime, 8000);
458 } 432 }
459 if (debug_legacy_dish_switch) { 433 if (debug_legacy_dish_switch) {
460 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", 434 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
461 __FUNCTION__, fe->dvb->num); 435 __FUNCTION__, fe->dvb->num);
462 for (i=1; i < 10; i++) 436 for (i = 1; i < 10; i++)
463 printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i])); 437 printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
464 } 438 }
465 439
466 return 0; 440 return 0;
@@ -517,8 +491,7 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
517{ 491{
518 struct stv0299_state* state = fe->demodulator_priv; 492 struct stv0299_state* state = fe->demodulator_priv;
519 493
520 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x10); 494 if (state->errmode != STATUS_BER) return 0;
521 msleep(100);
522 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); 495 *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
523 496
524 return 0; 497 return 0;
@@ -557,9 +530,8 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
557{ 530{
558 struct stv0299_state* state = fe->demodulator_priv; 531 struct stv0299_state* state = fe->demodulator_priv;
559 532
560 stv0299_writeregI(state, 0x34, (stv0299_readreg(state, 0x34) & 0xcf) | 0x30); 533 if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
561 msleep(100); 534 else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
562 *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
563 535
564 return 0; 536 return 0;
565} 537}
@@ -581,49 +553,14 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
581 if (state->config->invert) invval = (~invval) & 1; 553 if (state->config->invert) invval = (~invval) & 1;
582 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); 554 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
583 555
584 if (state->config->enhanced_tuning) { 556 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
585 /* check if we should do a finetune */ 557 state->config->pll_set(fe, state->i2c, p);
586 int frequency_delta = p->frequency - state->tuner_frequency; 558 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
587 int minmax = p->u.qpsk.symbol_rate / 2000;
588 if (minmax < 5000) minmax = 5000;
589
590 if ((frequency_delta > -minmax) && (frequency_delta < minmax) && (frequency_delta != 0) &&
591 (state->fec_inner == p->u.qpsk.fec_inner) &&
592 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
593 int Drot_freq = (frequency_delta << 16) / (state->config->mclk / 1000);
594
595 // zap the derotator registers first
596 stv0299_writeregI(state, 0x22, 0x00);
597 stv0299_writeregI(state, 0x23, 0x00);
598
599 // now set them as we want
600 stv0299_writeregI(state, 0x22, Drot_freq >> 8);
601 stv0299_writeregI(state, 0x23, Drot_freq);
602 } else {
603 /* A "normal" tune is requested */
604 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
605 state->config->pll_set(fe, state->i2c, p);
606 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
607
608 stv0299_writeregI(state, 0x32, 0x80);
609 stv0299_writeregI(state, 0x22, 0x00);
610 stv0299_writeregI(state, 0x23, 0x00);
611 stv0299_writeregI(state, 0x32, 0x19);
612 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
613 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
614 }
615 } else {
616 stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */
617 state->config->pll_set(fe, state->i2c, p);
618 stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */
619 559
620 stv0299_set_FEC (state, p->u.qpsk.fec_inner); 560 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
621 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); 561 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
622 stv0299_writeregI(state, 0x22, 0x00); 562 stv0299_writeregI(state, 0x22, 0x00);
623 stv0299_writeregI(state, 0x23, 0x00); 563 stv0299_writeregI(state, 0x23, 0x00);
624 stv0299_readreg (state, 0x23);
625 stv0299_writeregI(state, 0x12, 0xb9);
626 }
627 564
628 state->tuner_frequency = p->frequency; 565 state->tuner_frequency = p->frequency;
629 state->fec_inner = p->u.qpsk.fec_inner; 566 state->fec_inner = p->u.qpsk.fec_inner;
@@ -708,6 +645,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
708 state->tuner_frequency = 0; 645 state->tuner_frequency = 0;
709 state->symbol_rate = 0; 646 state->symbol_rate = 0;
710 state->fec_inner = 0; 647 state->fec_inner = 0;
648 state->errmode = STATUS_BER;
711 649
712 /* check if the demod is there */ 650 /* check if the demod is there */
713 stv0299_writeregI(state, 0x02, 0x34); /* standby off */ 651 stv0299_writeregI(state, 0x02, 0x34); /* standby off */
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index d0c4484861e1..9af3d71c89db 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -73,9 +73,6 @@ struct stv0299_config
73 /* does the inversion require inversion? */ 73 /* does the inversion require inversion? */
74 u8 invert:1; 74 u8 invert:1;
75 75
76 /* Should the enhanced tuning code be used? */
77 u8 enhanced_tuning:1;
78
79 /* Skip reinitialisation? */ 76 /* Skip reinitialisation? */
80 u8 skip_reinit:1; 77 u8 skip_reinit:1;
81 78
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 3529c618f828..7968743826fc 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -420,7 +420,7 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
420 struct tda1004x_state* state = fe->demodulator_priv; 420 struct tda1004x_state* state = fe->demodulator_priv;
421 421
422 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); 422 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
423 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 423 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10
424 if (state->config->xtal_freq == TDA10046_XTAL_4M ) { 424 if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
425 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); 425 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
426 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 426 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
@@ -597,7 +597,10 @@ static int tda10046_init(struct dvb_frontend* fe)
597 // Init the tuner PLL 597 // Init the tuner PLL
598 if (state->config->pll_init) { 598 if (state->config->pll_init) {
599 tda1004x_enable_tuner_i2c(state); 599 tda1004x_enable_tuner_i2c(state);
600 state->config->pll_init(fe); 600 if (state->config->pll_init(fe)) {
601 printk(KERN_ERR "tda1004x: pll init failed\n");
602 return -EIO;
603 }
601 tda1004x_disable_tuner_i2c(state); 604 tda1004x_disable_tuner_i2c(state);
602 } 605 }
603 606
@@ -667,7 +670,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
667 670
668 // set frequency 671 // set frequency
669 tda1004x_enable_tuner_i2c(state); 672 tda1004x_enable_tuner_i2c(state);
670 state->config->pll_set(fe, fe_params); 673 if (state->config->pll_set(fe, fe_params)) {
674 printk(KERN_ERR "tda1004x: pll set failed\n");
675 return -EIO;
676 }
671 tda1004x_disable_tuner_i2c(state); 677 tda1004x_disable_tuner_i2c(state);
672 678
673 // Hardcoded to use auto as much as possible on the TDA10045 as it 679 // Hardcoded to use auto as much as possible on the TDA10045 as it
@@ -832,6 +838,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
832 838
833 case TDA1004X_DEMOD_TDA10046: 839 case TDA1004X_DEMOD_TDA10046:
834 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); 840 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
841 msleep(1);
842 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
835 break; 843 break;
836 } 844 }
837 845
@@ -1129,7 +1137,12 @@ static int tda1004x_sleep(struct dvb_frontend* fe)
1129 if (state->config->pll_sleep != NULL) { 1137 if (state->config->pll_sleep != NULL) {
1130 tda1004x_enable_tuner_i2c(state); 1138 tda1004x_enable_tuner_i2c(state);
1131 state->config->pll_sleep(fe); 1139 state->config->pll_sleep(fe);
1132 tda1004x_disable_tuner_i2c(state); 1140 if (state->config->if_freq != TDA10046_FREQ_052) {
1141 /* special hack for Philips EUROPA Based boards:
1142 * keep the I2c bridge open for tuner access in analog mode
1143 */
1144 tda1004x_disable_tuner_i2c(state);
1145 }
1133 } 1146 }
1134 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); 1147 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1135 break; 1148 break;
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 85b437bbddcd..bbebd1c4caca 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -286,15 +286,10 @@ static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets)
286 * although one packet has been transfered. 286 * although one packet has been transfered.
287 */ 287 */
288 if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { 288 if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) {
289 unsigned int i = 0, valid; 289 unsigned int i = 0;
290 while (pluto->dma_buf[i] == 0x47) 290 while (pluto->dma_buf[i] == 0x47)
291 i += 188; 291 i += 188;
292 valid = i / 188; 292 nbpackets = i / 188;
293 if (nbpackets != valid) {
294 dev_err(&pluto->pdev->dev, "nbpackets=%u valid=%u\n",
295 nbpackets, valid);
296 nbpackets = valid;
297 }
298 } 293 }
299 294
300 dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); 295 dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets);
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 22b203f8ff27..87ea52757a21 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -1566,7 +1566,7 @@ static u8 alps_bsru6_inittab[] = {
1566 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1566 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1567 0x10, 0x3f, // AGC2 0x3d 1567 0x10, 0x3f, // AGC2 0x3d
1568 0x11, 0x84, 1568 0x11, 0x84,
1569 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1569 0x12, 0xb9,
1570 0x15, 0xc9, // lock detector threshold 1570 0x15, 0xc9, // lock detector threshold
1571 0x16, 0x00, 1571 0x16, 0x00,
1572 0x17, 0x00, 1572 0x17, 0x00,
@@ -1644,7 +1644,6 @@ static struct stv0299_config alps_bsru6_config = {
1644 .inittab = alps_bsru6_inittab, 1644 .inittab = alps_bsru6_inittab,
1645 .mclk = 88000000UL, 1645 .mclk = 88000000UL,
1646 .invert = 1, 1646 .invert = 1,
1647 .enhanced_tuning = 0,
1648 .skip_reinit = 0, 1647 .skip_reinit = 0,
1649 .lock_output = STV0229_LOCKOUTPUT_1, 1648 .lock_output = STV0229_LOCKOUTPUT_1,
1650 .volt13_op0_op1 = STV0299_VOLT13_OP1, 1649 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -1669,7 +1668,7 @@ static u8 alps_bsbe1_inittab[] = {
1669 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1668 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1670 0x10, 0x3f, // AGC2 0x3d 1669 0x10, 0x3f, // AGC2 0x3d
1671 0x11, 0x84, 1670 0x11, 0x84,
1672 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1671 0x12, 0xb9,
1673 0x15, 0xc9, // lock detector threshold 1672 0x15, 0xc9, // lock detector threshold
1674 0x16, 0x00, 1673 0x16, 0x00,
1675 0x17, 0x00, 1674 0x17, 0x00,
@@ -1721,7 +1720,6 @@ static struct stv0299_config alps_bsbe1_config = {
1721 .inittab = alps_bsbe1_inittab, 1720 .inittab = alps_bsbe1_inittab,
1722 .mclk = 88000000UL, 1721 .mclk = 88000000UL,
1723 .invert = 1, 1722 .invert = 1,
1724 .enhanced_tuning = 0,
1725 .skip_reinit = 0, 1723 .skip_reinit = 0,
1726 .min_delay_ms = 100, 1724 .min_delay_ms = 100,
1727 .set_symbol_rate = alps_bsru6_set_symbol_rate, 1725 .set_symbol_rate = alps_bsru6_set_symbol_rate,
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 7692cd23f839..aa75dc03a0b3 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -499,7 +499,7 @@ static u8 typhoon_cinergy1200s_inittab[] = {
499 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 499 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
500 0x10, 0x3f, // AGC2 0x3d 500 0x10, 0x3f, // AGC2 0x3d
501 0x11, 0x84, 501 0x11, 0x84,
502 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 502 0x12, 0xb9,
503 0x15, 0xc9, // lock detector threshold 503 0x15, 0xc9, // lock detector threshold
504 0x16, 0x00, 504 0x16, 0x00,
505 0x17, 0x00, 505 0x17, 0x00,
@@ -531,7 +531,6 @@ static struct stv0299_config typhoon_config = {
531 .inittab = typhoon_cinergy1200s_inittab, 531 .inittab = typhoon_cinergy1200s_inittab,
532 .mclk = 88000000UL, 532 .mclk = 88000000UL,
533 .invert = 0, 533 .invert = 0,
534 .enhanced_tuning = 0,
535 .skip_reinit = 0, 534 .skip_reinit = 0,
536 .lock_output = STV0229_LOCKOUTPUT_1, 535 .lock_output = STV0229_LOCKOUTPUT_1,
537 .volt13_op0_op1 = STV0299_VOLT13_OP0, 536 .volt13_op0_op1 = STV0299_VOLT13_OP0,
@@ -546,7 +545,6 @@ static struct stv0299_config cinergy_1200s_config = {
546 .inittab = typhoon_cinergy1200s_inittab, 545 .inittab = typhoon_cinergy1200s_inittab,
547 .mclk = 88000000UL, 546 .mclk = 88000000UL,
548 .invert = 0, 547 .invert = 0,
549 .enhanced_tuning = 0,
550 .skip_reinit = 0, 548 .skip_reinit = 0,
551 .lock_output = STV0229_LOCKOUTPUT_0, 549 .lock_output = STV0229_LOCKOUTPUT_0,
552 .volt13_op0_op1 = STV0299_VOLT13_OP0, 550 .volt13_op0_op1 = STV0299_VOLT13_OP0,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 51c30ba68140..75fb92d60998 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -490,7 +490,7 @@ static u8 alps_bsru6_inittab[] = {
490 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 490 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
491 0x10, 0x3f, // AGC2 0x3d 491 0x10, 0x3f, // AGC2 0x3d
492 0x11, 0x84, 492 0x11, 0x84,
493 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 493 0x12, 0xb9,
494 0x15, 0xc9, // lock detector threshold 494 0x15, 0xc9, // lock detector threshold
495 0x16, 0x00, 495 0x16, 0x00,
496 0x17, 0x00, 496 0x17, 0x00,
@@ -580,7 +580,6 @@ static struct stv0299_config alps_bsru6_config = {
580 .inittab = alps_bsru6_inittab, 580 .inittab = alps_bsru6_inittab,
581 .mclk = 88000000UL, 581 .mclk = 88000000UL,
582 .invert = 1, 582 .invert = 1,
583 .enhanced_tuning = 0,
584 .skip_reinit = 0, 583 .skip_reinit = 0,
585 .lock_output = STV0229_LOCKOUTPUT_1, 584 .lock_output = STV0229_LOCKOUTPUT_1,
586 .volt13_op0_op1 = STV0299_VOLT13_OP1, 585 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -710,7 +709,6 @@ static struct stv0299_config philips_su1278_tt_config = {
710 .inittab = philips_su1278_tt_inittab, 709 .inittab = philips_su1278_tt_inittab,
711 .mclk = 64000000UL, 710 .mclk = 64000000UL,
712 .invert = 0, 711 .invert = 0,
713 .enhanced_tuning = 1,
714 .skip_reinit = 1, 712 .skip_reinit = 1,
715 .lock_output = STV0229_LOCKOUTPUT_1, 713 .lock_output = STV0229_LOCKOUTPUT_1,
716 .volt13_op0_op1 = STV0299_VOLT13_OP1, 714 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index b1f21ef0e3b3..755df81cbc49 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -305,7 +305,7 @@ static u8 alps_bsru6_inittab[] = {
305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 305 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
306 0x10, 0x3f, // AGC2 0x3d 306 0x10, 0x3f, // AGC2 0x3d
307 0x11, 0x84, 307 0x11, 0x84,
308 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 308 0x12, 0xb9,
309 0x15, 0xc9, // lock detector threshold 309 0x15, 0xc9, // lock detector threshold
310 0x16, 0x00, 310 0x16, 0x00,
311 0x17, 0x00, 311 0x17, 0x00,
@@ -379,7 +379,6 @@ static struct stv0299_config alps_bsru6_config = {
379 .inittab = alps_bsru6_inittab, 379 .inittab = alps_bsru6_inittab,
380 .mclk = 88000000UL, 380 .mclk = 88000000UL,
381 .invert = 1, 381 .invert = 1,
382 .enhanced_tuning = 0,
383 .skip_reinit = 0, 382 .skip_reinit = 0,
384 .lock_output = STV0229_LOCKOUTPUT_1, 383 .lock_output = STV0229_LOCKOUTPUT_1,
385 .volt13_op0_op1 = STV0299_VOLT13_OP1, 384 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 43d6c8268642..4fd8bbc47037 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -226,12 +226,14 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg)
226 return 0; 226 return 0;
227} 227}
228 228
229static void lnbp21_init(struct budget* budget) 229static int lnbp21_init(struct budget* budget)
230{ 230{
231 u8 buf = 0x00; 231 u8 buf = 0x00;
232 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) }; 232 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = &buf, .len = sizeof(buf) };
233 233
234 i2c_transfer (&budget->i2c_adap, &msg, 1); 234 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
235 return -EIO;
236 return 0;
235} 237}
236 238
237static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 239static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -273,7 +275,7 @@ static u8 alps_bsru6_inittab[] = {
273 0x01, 0x15, 275 0x01, 0x15,
274 0x02, 0x00, 276 0x02, 0x00,
275 0x03, 0x00, 277 0x03, 0x00,
276 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ 278 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
277 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ 279 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
278 0x06, 0x40, /* DAC not used, set to high impendance mode */ 280 0x06, 0x40, /* DAC not used, set to high impendance mode */
279 0x07, 0x00, /* DAC LSB */ 281 0x07, 0x00, /* DAC LSB */
@@ -284,7 +286,7 @@ static u8 alps_bsru6_inittab[] = {
284 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 286 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
285 0x10, 0x3f, // AGC2 0x3d 287 0x10, 0x3f, // AGC2 0x3d
286 0x11, 0x84, 288 0x11, 0x84,
287 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 289 0x12, 0xb9,
288 0x15, 0xc9, // lock detector threshold 290 0x15, 0xc9, // lock detector threshold
289 0x16, 0x00, 291 0x16, 0x00,
290 0x17, 0x00, 292 0x17, 0x00,
@@ -358,7 +360,6 @@ static struct stv0299_config alps_bsru6_config = {
358 .inittab = alps_bsru6_inittab, 360 .inittab = alps_bsru6_inittab,
359 .mclk = 88000000UL, 361 .mclk = 88000000UL,
360 .invert = 1, 362 .invert = 1,
361 .enhanced_tuning = 0,
362 .skip_reinit = 0, 363 .skip_reinit = 0,
363 .lock_output = STV0229_LOCKOUTPUT_1, 364 .lock_output = STV0229_LOCKOUTPUT_1,
364 .volt13_op0_op1 = STV0299_VOLT13_OP1, 365 .volt13_op0_op1 = STV0299_VOLT13_OP1,
@@ -367,6 +368,79 @@ static struct stv0299_config alps_bsru6_config = {
367 .pll_set = alps_bsru6_pll_set, 368 .pll_set = alps_bsru6_pll_set,
368}; 369};
369 370
371static u8 alps_bsbe1_inittab[] = {
372 0x01, 0x15,
373 0x02, 0x30,
374 0x03, 0x00,
375 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
376 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
377 0x06, 0x40, /* DAC not used, set to high impendance mode */
378 0x07, 0x00, /* DAC LSB */
379 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
380 0x09, 0x00, /* FIFO */
381 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
382 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
383 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
384 0x10, 0x3f, // AGC2 0x3d
385 0x11, 0x84,
386 0x12, 0xb9,
387 0x15, 0xc9, // lock detector threshold
388 0x16, 0x00,
389 0x17, 0x00,
390 0x18, 0x00,
391 0x19, 0x00,
392 0x1a, 0x00,
393 0x1f, 0x50,
394 0x20, 0x00,
395 0x21, 0x00,
396 0x22, 0x00,
397 0x23, 0x00,
398 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
399 0x29, 0x1e, // 1/2 threshold
400 0x2a, 0x14, // 2/3 threshold
401 0x2b, 0x0f, // 3/4 threshold
402 0x2c, 0x09, // 5/6 threshold
403 0x2d, 0x05, // 7/8 threshold
404 0x2e, 0x01,
405 0x31, 0x1f, // test all FECs
406 0x32, 0x19, // viterbi and synchro search
407 0x33, 0xfc, // rs control
408 0x34, 0x93, // error control
409 0x0f, 0x92, // 0x80 = inverse AGC
410 0xff, 0xff
411};
412
413static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
414{
415 int ret;
416 u8 data[4];
417 u32 div;
418 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
419
420 if ((params->frequency < 950000) || (params->frequency > 2150000))
421 return -EINVAL;
422
423 div = (params->frequency + (125 - 1)) / 125; // round correctly
424 data[0] = (div >> 8) & 0x7f;
425 data[1] = div & 0xff;
426 data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
427 data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
428
429 ret = i2c_transfer(i2c, &msg, 1);
430 return (ret != 1) ? -EIO : 0;
431}
432
433static struct stv0299_config alps_bsbe1_config = {
434 .demod_address = 0x68,
435 .inittab = alps_bsbe1_inittab,
436 .mclk = 88000000UL,
437 .invert = 1,
438 .skip_reinit = 0,
439 .min_delay_ms = 100,
440 .set_symbol_rate = alps_bsru6_set_symbol_rate,
441 .pll_set = alps_bsbe1_pll_set,
442};
443
370static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 444static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
371{ 445{
372 struct budget* budget = (struct budget*) fe->dvb->priv; 446 struct budget* budget = (struct budget*) fe->dvb->priv;
@@ -500,6 +574,19 @@ static u8 read_pwm(struct budget* budget)
500static void frontend_init(struct budget *budget) 574static void frontend_init(struct budget *budget)
501{ 575{
502 switch(budget->dev->pci->subsystem_device) { 576 switch(budget->dev->pci->subsystem_device) {
577 case 0x1017:
578 // try the ALPS BSBE1 now
579 budget->dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget->i2c_adap);
580 if (budget->dvb_frontend) {
581 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
582 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
583 if (lnbp21_init(budget)) {
584 printk("%s: No LNBP21 found!\n", __FUNCTION__);
585 goto error_out;
586 }
587 }
588
589 break;
503 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) 590 case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659))
504 case 0x1013: 591 case 0x1013:
505 // try the ALPS BSRV2 first of all 592 // try the ALPS BSRV2 first of all
@@ -554,7 +641,10 @@ static void frontend_init(struct budget *budget)
554 if (budget->dvb_frontend) { 641 if (budget->dvb_frontend) {
555 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; 642 budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage;
556 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; 643 budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
557 lnbp21_init(budget); 644 if (lnbp21_init(budget)) {
645 printk("%s: No LNBP21 found!\n", __FUNCTION__);
646 goto error_out;
647 }
558 break; 648 break;
559 } 649 }
560 } 650 }
@@ -566,13 +656,17 @@ static void frontend_init(struct budget *budget)
566 budget->dev->pci->subsystem_vendor, 656 budget->dev->pci->subsystem_vendor,
567 budget->dev->pci->subsystem_device); 657 budget->dev->pci->subsystem_device);
568 } else { 658 } else {
569 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { 659 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend))
570 printk("budget: Frontend registration failed!\n"); 660 goto error_out;
571 if (budget->dvb_frontend->ops->release)
572 budget->dvb_frontend->ops->release(budget->dvb_frontend);
573 budget->dvb_frontend = NULL;
574 }
575 } 661 }
662 return;
663
664error_out:
665 printk("budget: Frontend registration failed!\n");
666 if (budget->dvb_frontend->ops->release)
667 budget->dvb_frontend->ops->release(budget->dvb_frontend);
668 budget->dvb_frontend = NULL;
669 return;
576} 670}
577 671
578static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) 672static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
@@ -618,6 +712,7 @@ static int budget_detach (struct saa7146_dev* dev)
618 712
619static struct saa7146_extension budget_extension; 713static struct saa7146_extension budget_extension;
620 714
715MAKE_BUDGET_INFO(ttbs2, "TT-Budget/WinTV-NOVA-S PCI (rev AL/alps bsbe1 lnbp21 frontend)", BUDGET_TT);
621MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); 716MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT);
622MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); 717MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT);
623MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 718MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
@@ -630,6 +725,7 @@ static struct pci_device_id pci_tbl[] = {
630 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), 725 MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004),
631 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), 726 MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005),
632 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), 727 MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
728 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
633 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), 729 MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016),
634 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), 730 MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60),
635 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), 731 MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61),
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index d200ab0ad9e7..fd53d6010502 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -1198,7 +1198,7 @@ static u8 alps_bsbe1_inittab[] = {
1198 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1198 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1199 0x10, 0x3f, // AGC2 0x3d 1199 0x10, 0x3f, // AGC2 0x3d
1200 0x11, 0x84, 1200 0x11, 0x84,
1201 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1201 0x12, 0xb9,
1202 0x15, 0xc9, // lock detector threshold 1202 0x15, 0xc9, // lock detector threshold
1203 0x16, 0x00, 1203 0x16, 0x00,
1204 0x17, 0x00, 1204 0x17, 0x00,
@@ -1240,7 +1240,7 @@ static u8 alps_bsru6_inittab[] = {
1240 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ 1240 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1241 0x10, 0x3f, // AGC2 0x3d 1241 0x10, 0x3f, // AGC2 0x3d
1242 0x11, 0x84, 1242 0x11, 0x84,
1243 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on 1243 0x12, 0xb9,
1244 0x15, 0xc9, // lock detector threshold 1244 0x15, 0xc9, // lock detector threshold
1245 0x16, 0x00, 1245 0x16, 0x00,
1246 0x17, 0x00, 1246 0x17, 0x00,
@@ -1335,7 +1335,6 @@ static struct stv0299_config alps_stv0299_config = {
1335 .inittab = alps_bsru6_inittab, 1335 .inittab = alps_bsru6_inittab,
1336 .mclk = 88000000UL, 1336 .mclk = 88000000UL,
1337 .invert = 1, 1337 .invert = 1,
1338 .enhanced_tuning = 0,
1339 .skip_reinit = 0, 1338 .skip_reinit = 0,
1340 .lock_output = STV0229_LOCKOUTPUT_1, 1339 .lock_output = STV0229_LOCKOUTPUT_1,
1341 .volt13_op0_op1 = STV0299_VOLT13_OP1, 1340 .volt13_op0_op1 = STV0299_VOLT13_OP1,
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index bbb989df4cf0..199b01188858 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -25,6 +25,16 @@ config VIDEO_BT848
25 To compile this driver as a module, choose M here: the 25 To compile this driver as a module, choose M here: the
26 module will be called bttv. 26 module will be called bttv.
27 27
28config VIDEO_BT848_DVB
29 tristate "DVB/ATSC Support for bt878 based TV cards"
30 depends on VIDEO_BT848 && DVB_CORE
31 select DVB_BT8XX
32 ---help---
33 This adds support for DVB/ATSC cards based on the BT878 chip.
34
35 To compile this driver as a module, choose M here: the
36 module will be called dvb-bt8xx.
37
28config VIDEO_SAA6588 38config VIDEO_SAA6588
29 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards" 39 tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
30 depends on VIDEO_DEV && I2C && VIDEO_BT848 40 depends on VIDEO_DEV && I2C && VIDEO_BT848
@@ -243,29 +253,7 @@ config VIDEO_MEYE
243 To compile this driver as a module, choose M here: the 253 To compile this driver as a module, choose M here: the
244 module will be called meye. 254 module will be called meye.
245 255
246config VIDEO_SAA7134 256source "drivers/media/video/saa7134/Kconfig"
247 tristate "Philips SAA7134 support"
248 depends on VIDEO_DEV && PCI && I2C && SOUND
249 select VIDEO_BUF
250 select VIDEO_IR
251 select VIDEO_TUNER
252 select CRC32
253 ---help---
254 This is a video4linux driver for Philips SAA7130/7134 based
255 TV cards.
256
257 To compile this driver as a module, choose M here: the
258 module will be called saa7134.
259
260config VIDEO_SAA7134_DVB
261 tristate "DVB Support for saa7134 based TV cards"
262 depends on VIDEO_SAA7134 && DVB_CORE
263 select VIDEO_BUF_DVB
264 select DVB_MT352
265 select DVB_TDA1004X
266 ---help---
267 This adds support for DVB cards based on the
268 Philips saa7134 chip.
269 257
270config VIDEO_MXB 258config VIDEO_MXB
271 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'" 259 tristate "Siemens-Nixdorf 'Multimedia eXtension Board'"
@@ -316,34 +304,9 @@ config VIDEO_HEXIUM_GEMINI
316 To compile this driver as a module, choose M here: the 304 To compile this driver as a module, choose M here: the
317 module will be called hexium_gemini. 305 module will be called hexium_gemini.
318 306
319config VIDEO_CX88 307source "drivers/media/video/cx88/Kconfig"
320 tristate "Conexant 2388x (bt878 successor) support"
321 depends on VIDEO_DEV && PCI && I2C && EXPERIMENTAL
322 select I2C_ALGOBIT
323 select FW_LOADER
324 select VIDEO_BTCX
325 select VIDEO_BUF
326 select VIDEO_TUNER
327 select VIDEO_TVEEPROM
328 select VIDEO_IR
329 ---help---
330 This is a video4linux driver for Conexant 2388x based
331 TV cards.
332 308
333 To compile this driver as a module, choose M here: the 309source "drivers/media/video/em28xx/Kconfig"
334 module will be called cx8800
335
336config VIDEO_CX88_DVB
337 tristate "DVB Support for cx2388x based TV cards"
338 depends on VIDEO_CX88 && DVB_CORE
339 select VIDEO_BUF_DVB
340 select DVB_MT352
341 select DVB_OR51132
342 select DVB_CX22702
343 select DVB_LGDT330X
344 ---help---
345 This adds support for DVB/ATSC cards based on the
346 Connexant 2388x chip.
347 310
348config VIDEO_OVCAMCHIP 311config VIDEO_OVCAMCHIP
349 tristate "OmniVision Camera Chip support" 312 tristate "OmniVision Camera Chip support"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 046b82de9285..3ac465992400 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -5,7 +5,6 @@
5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ 5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o 6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o
7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o 7zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o
8rds-objs := saa6588.o
9zr36067-objs := zoran_procfs.o zoran_device.o \ 8zr36067-objs := zoran_procfs.o zoran_device.o \
10 zoran_driver.o zoran_card.o 9 zoran_driver.o zoran_card.o
11tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o 10tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o
@@ -16,7 +15,7 @@ obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
16obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o 15obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
17 16
18obj-$(CONFIG_VIDEO_ZR36120) += zoran.o 17obj-$(CONFIG_VIDEO_ZR36120) += zoran.o
19obj-$(CONFIG_VIDEO_SAA6588) += rds.o 18obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
20obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o 19obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
21obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o 20obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
22obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o 21obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
@@ -39,6 +38,8 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
39obj-$(CONFIG_VIDEO_MEYE) += meye.o 38obj-$(CONFIG_VIDEO_MEYE) += meye.o
40obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ 39obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
41obj-$(CONFIG_VIDEO_CX88) += cx88/ 40obj-$(CONFIG_VIDEO_CX88) += cx88/
41obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
42obj-$(CONFIG_VIDEO_EM28XX) += saa711x.o tvp5150.o
42obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/ 43obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
43obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o 44obj-$(CONFIG_VIDEO_MXB) += saa7111.o tuner.o tda9840.o tea6415c.o tea6420.o mxb.o
44obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o 45obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 87fd3a7bb392..881cdcb1875d 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -22,7 +22,6 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/devfs_fs_kernel.h> 23#include <linux/devfs_fs_kernel.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/version.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/fs.h> 27#include <linux/fs.h>
@@ -865,10 +864,8 @@ out_dev:
865 864
866out_irq: 865out_irq:
867#endif 866#endif
868 for (i = 0; i < MAX_AR_HEIGHT; i++) { 867 for (i = 0; i < MAX_AR_HEIGHT; i++)
869 if (ar->frame[i]) 868 kfree(ar->frame[i]);
870 kfree(ar->frame[i]);
871 }
872 869
873out_line_buff: 870out_line_buff:
874#if USE_INT 871#if USE_INT
@@ -899,10 +896,8 @@ static void __exit ar_cleanup_module(void)
899#if USE_INT 896#if USE_INT
900 free_irq(M32R_IRQ_INT3, ar); 897 free_irq(M32R_IRQ_INT3, ar);
901#endif 898#endif
902 for (i = 0; i < MAX_AR_HEIGHT; i++) { 899 for (i = 0; i < MAX_AR_HEIGHT; i++)
903 if (ar->frame[i]) 900 kfree(ar->frame[i]);
904 kfree(ar->frame[i]);
905 }
906#if USE_INT 901#if USE_INT
907 kfree(ar->line_buff); 902 kfree(ar->line_buff);
908#endif 903#endif
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 76c1b63ebdf2..e4063950ae57 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -32,7 +32,6 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33 33
34#include <media/audiochip.h> 34#include <media/audiochip.h>
35#include <media/id.h>
36#include "bttv.h" 35#include "bttv.h"
37#include "bt832.h" 36#include "bt832.h"
38 37
@@ -54,36 +53,36 @@ static struct i2c_driver driver;
54static struct i2c_client client_template; 53static struct i2c_client client_template;
55 54
56struct bt832 { 55struct bt832 {
57 struct i2c_client client; 56 struct i2c_client client;
58}; 57};
59 58
60int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf) 59int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
61{ 60{
62 int i,rc; 61 int i,rc;
63 buf[0]=0x80; // start at register 0 with auto-increment 62 buf[0]=0x80; // start at register 0 with auto-increment
64 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) 63 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
65 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc); 64 printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc);
66 65
67 for(i=0;i<65;i++) 66 for(i=0;i<65;i++)
68 buf[i]=0; 67 buf[i]=0;
69 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) 68 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
70 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc); 69 printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc);
71 70
72 // Note: On READ the first byte is the current index 71 // Note: On READ the first byte is the current index
73 // (e.g. 0x80, what we just wrote) 72 // (e.g. 0x80, what we just wrote)
74 73
75 if(1) { 74 if(1) {
76 int i; 75 int i;
77 printk("BT832 hexdump:\n"); 76 printk("BT832 hexdump:\n");
78 for(i=1;i<65;i++) { 77 for(i=1;i<65;i++) {
79 if(i!=1) { 78 if(i!=1) {
80 if(((i-1)%8)==0) printk(" "); 79 if(((i-1)%8)==0) printk(" ");
81 if(((i-1)%16)==0) printk("\n"); 80 if(((i-1)%16)==0) printk("\n");
82 } 81 }
83 printk(" %02x",buf[i]); 82 printk(" %02x",buf[i]);
84 } 83 }
85 printk("\n"); 84 printk("\n");
86 } 85 }
87 return 0; 86 return 0;
88} 87}
89 88
@@ -102,13 +101,13 @@ int bt832_init(struct i2c_client *i2c_client_s)
102 return 0; 101 return 0;
103 } 102 }
104 103
105 printk("Write 0 tp VPSTATUS\n"); 104 printk("Write 0 tp VPSTATUS\n");
106 buf[0]=BT832_VP_STATUS; // Reg.52 105 buf[0]=BT832_VP_STATUS; // Reg.52
107 buf[1]= 0x00; 106 buf[1]= 0x00;
108 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 107 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
109 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 108 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
110 109
111 bt832_hexdump(i2c_client_s,buf); 110 bt832_hexdump(i2c_client_s,buf);
112 111
113 112
114 // Leave low power mode: 113 // Leave low power mode:
@@ -116,17 +115,17 @@ int bt832_init(struct i2c_client *i2c_client_s)
116 buf[0]=BT832_CAM_SETUP0; //0x39 57 115 buf[0]=BT832_CAM_SETUP0; //0x39 57
117 buf[1]=0x08; 116 buf[1]=0x08;
118 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 117 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
119 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc); 118 printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
120 119
121 bt832_hexdump(i2c_client_s,buf); 120 bt832_hexdump(i2c_client_s,buf);
122 121
123 printk("Write 0 tp VPSTATUS\n"); 122 printk("Write 0 tp VPSTATUS\n");
124 buf[0]=BT832_VP_STATUS; // Reg.52 123 buf[0]=BT832_VP_STATUS; // Reg.52
125 buf[1]= 0x00; 124 buf[1]= 0x00;
126 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 125 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
127 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); 126 printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc);
128 127
129 bt832_hexdump(i2c_client_s,buf); 128 bt832_hexdump(i2c_client_s,buf);
130 129
131 130
132 // Enable Output 131 // Enable Output
@@ -134,22 +133,22 @@ int bt832_init(struct i2c_client *i2c_client_s)
134 buf[0]=BT832_VP_CONTROL1; // Reg.40 133 buf[0]=BT832_VP_CONTROL1; // Reg.40
135 buf[1]= 0x27 & (~0x01); // Default | !skip 134 buf[1]= 0x27 & (~0x01); // Default | !skip
136 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 135 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
137 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); 136 printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
138 137
139 bt832_hexdump(i2c_client_s,buf); 138 bt832_hexdump(i2c_client_s,buf);
140 139
141 140
142 // for testing (even works when no camera attached) 141 // for testing (even works when no camera attached)
143 printk("bt832: *** Generate NTSC M Bars *****\n"); 142 printk("bt832: *** Generate NTSC M Bars *****\n");
144 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 143 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
145 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally 144 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
146 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) 145 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
147 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc); 146 printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
148 147
149 printk("Bt832: Camera Present: %s\n", 148 printk("Bt832: Camera Present: %s\n",
150 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); 149 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
151 150
152 bt832_hexdump(i2c_client_s,buf); 151 bt832_hexdump(i2c_client_s,buf);
153 kfree(buf); 152 kfree(buf);
154 return 1; 153 return 1;
155} 154}
@@ -162,17 +161,17 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
162 161
163 printk("bt832_attach\n"); 162 printk("bt832_attach\n");
164 163
165 client_template.adapter = adap; 164 client_template.adapter = adap;
166 client_template.addr = addr; 165 client_template.addr = addr;
167 166
168 printk("bt832: chip found @ 0x%x\n", addr<<1); 167 printk("bt832: chip found @ 0x%x\n", addr<<1);
169 168
170 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 169 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
171 return -ENOMEM; 170 return -ENOMEM;
172 memset(t,0,sizeof(*t)); 171 memset(t,0,sizeof(*t));
173 t->client = client_template; 172 t->client = client_template;
174 i2c_set_clientdata(&t->client, t); 173 i2c_set_clientdata(&t->client, t);
175 i2c_attach_client(&t->client); 174 i2c_attach_client(&t->client);
176 175
177 if(! bt832_init(&t->client)) { 176 if(! bt832_init(&t->client)) {
178 bt832_detach(&t->client); 177 bt832_detach(&t->client);
@@ -211,7 +210,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
211 210
212 printk("bt832: command %x\n",cmd); 211 printk("bt832: command %x\n",cmd);
213 212
214 switch (cmd) { 213 switch (cmd) {
215 case BT832_HEXDUMP: { 214 case BT832_HEXDUMP: {
216 unsigned char *buf; 215 unsigned char *buf;
217 buf=kmalloc(65,GFP_KERNEL); 216 buf=kmalloc(65,GFP_KERNEL);
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
index 9b6a8d2c96b5..1ce8fa71f7db 100644
--- a/drivers/media/video/bt832.h
+++ b/drivers/media/video/bt832.h
@@ -233,8 +233,8 @@ SetInterlaceMode( spec.interlace );
233/* from web: 233/* from web:
234 Video Sampling 234 Video Sampling
235Digital video is a sampled form of analog video. The most common sampling schemes in use today are: 235Digital video is a sampled form of analog video. The most common sampling schemes in use today are:
236 Pixel Clock Horiz Horiz Vert 236 Pixel Clock Horiz Horiz Vert
237 Rate Total Active 237 Rate Total Active
238NTSC square pixel 12.27 MHz 780 640 525 238NTSC square pixel 12.27 MHz 780 640 525
239NTSC CCIR-601 13.5 MHz 858 720 525 239NTSC CCIR-601 13.5 MHz 858 720 525
240NTSC 4FSc 14.32 MHz 910 768 525 240NTSC 4FSc 14.32 MHz 910 768 525
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 0881a17d5226..3413bace443a 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -6,7 +6,7 @@
6 like the big tvcards array for the most part 6 like the big tvcards array for the most part
7 7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de) 9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> 10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11 11
12 This program is free software; you can redistribute it and/or modify 12 This program is free software; you can redistribute it and/or modify
@@ -145,162 +145,163 @@ static struct CARD {
145 int cardnr; 145 int cardnr;
146 char *name; 146 char *name;
147} cards[] __devinitdata = { 147} cards[] __devinitdata = {
148 { 0x13eb0070, BTTV_HAUPPAUGE878, "Hauppauge WinTV" }, 148 { 0x13eb0070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV" },
149 { 0x39000070, BTTV_HAUPPAUGE878, "Hauppauge WinTV-D" }, 149 { 0x39000070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV-D" },
150 { 0x45000070, BTTV_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" }, 150 { 0x45000070, BTTV_BOARD_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
151 { 0xff000070, BTTV_OSPREY1x0, "Osprey-100" }, 151 { 0xff000070, BTTV_BOARD_OSPREY1x0, "Osprey-100" },
152 { 0xff010070, BTTV_OSPREY2x0_SVID,"Osprey-200" }, 152 { 0xff010070, BTTV_BOARD_OSPREY2x0_SVID,"Osprey-200" },
153 { 0xff020070, BTTV_OSPREY500, "Osprey-500" }, 153 { 0xff020070, BTTV_BOARD_OSPREY500, "Osprey-500" },
154 { 0xff030070, BTTV_OSPREY2000, "Osprey-2000" }, 154 { 0xff030070, BTTV_BOARD_OSPREY2000, "Osprey-2000" },
155 { 0xff040070, BTTV_OSPREY540, "Osprey-540" }, 155 { 0xff040070, BTTV_BOARD_OSPREY540, "Osprey-540" },
156 156 { 0xff070070, BTTV_BOARD_OSPREY440, "Osprey-440" },
157 { 0x00011002, BTTV_ATI_TVWONDER, "ATI TV Wonder" }, 157
158 { 0x00031002, BTTV_ATI_TVWONDERVE,"ATI TV Wonder/VE" }, 158 { 0x00011002, BTTV_BOARD_ATI_TVWONDER, "ATI TV Wonder" },
159 159 { 0x00031002, BTTV_BOARD_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
160 { 0x6606107d, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 160
161 { 0x6607107d, BTTV_WINFASTVC100, "Leadtek WinFast VC 100" }, 161 { 0x6606107d, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
162 { 0x6609107d, BTTV_WINFAST2000, "Leadtek TV 2000 XP" }, 162 { 0x6607107d, BTTV_BOARD_WINFASTVC100, "Leadtek WinFast VC 100" },
163 { 0x263610b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, 163 { 0x6609107d, BTTV_BOARD_WINFAST2000, "Leadtek TV 2000 XP" },
164 { 0x264510b4, BTTV_STB2, "STB TV PCI FM, Gateway P/N 6000704" }, 164 { 0x263610b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
165 { 0x402010fc, BTTV_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" }, 165 { 0x264510b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
166 { 0x405010fc, BTTV_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" }, 166 { 0x402010fc, BTTV_BOARD_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
167 { 0x407010fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, 167 { 0x405010fc, BTTV_BOARD_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
168 { 0xd01810fc, BTTV_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" }, 168 { 0x407010fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
169 169 { 0xd01810fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
170 { 0x001211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 170
171 { 0x001211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
171 /* some cards ship with byteswapped IDs ... */ 172 /* some cards ship with byteswapped IDs ... */
172 { 0x1200bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 173 { 0x1200bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
173 { 0xff00bd11, BTTV_PINNACLE, "Pinnacle PCTV [bswap]" }, 174 { 0xff00bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
174 /* this seems to happen as well ... */ 175 /* this seems to happen as well ... */
175 { 0xff1211bd, BTTV_PINNACLE, "Pinnacle PCTV" }, 176 { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
176 177
177 { 0x3000121a, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, 178 { 0x3000121a, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
178 { 0x263710b4, BTTV_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" }, 179 { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
179 { 0x3060121a, BTTV_STB2, "3Dfx VoodooTV 100/ STB OEM" }, 180 { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" },
180 181
181 { 0x3000144f, BTTV_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" }, 182 { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
182 { 0xa005144f, BTTV_MAGICTVIEW063, "CPH06X TView99-Card" }, 183 { 0xa005144f, BTTV_BOARD_MAGICTVIEW063, "CPH06X TView99-Card" },
183 { 0x3002144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" }, 184 { 0x3002144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
184 { 0x3005144f, BTTV_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" }, 185 { 0x3005144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
185 { 0x5000144f, BTTV_MAGICTVIEW061, "Askey CPH050" }, 186 { 0x5000144f, BTTV_BOARD_MAGICTVIEW061, "Askey CPH050" },
186 { 0x300014ff, BTTV_MAGICTVIEW061, "TView 99 (CPH061)" }, 187 { 0x300014ff, BTTV_BOARD_MAGICTVIEW061, "TView 99 (CPH061)" },
187 { 0x300214ff, BTTV_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" }, 188 { 0x300214ff, BTTV_BOARD_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
188 189
189 { 0x00011461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, 190 { 0x00011461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
190 { 0x00021461, BTTV_AVERMEDIA98, "AVermedia TVCapture 98" }, 191 { 0x00021461, BTTV_BOARD_AVERMEDIA98, "AVermedia TVCapture 98" },
191 { 0x00031461, BTTV_AVPHONE98, "AVerMedia TVPhone98" }, 192 { 0x00031461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
192 { 0x00041461, BTTV_AVERMEDIA98, "AVerMedia TVCapture 98" }, 193 { 0x00041461, BTTV_BOARD_AVERMEDIA98, "AVerMedia TVCapture 98" },
193 { 0x03001461, BTTV_AVERMEDIA98, "VDOMATE TV TUNER CARD" }, 194 { 0x03001461, BTTV_BOARD_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
194 195
195 { 0x1117153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" }, 196 { 0x1117153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
196 { 0x1118153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" }, 197 { 0x1118153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
197 { 0x1119153b, BTTV_TERRATVALUE, "Terratec TValue (Philips PAL I)" }, 198 { 0x1119153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
198 { 0x111a153b, BTTV_TERRATVALUE, "Terratec TValue (Temic PAL I)" }, 199 { 0x111a153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
199 200
200 { 0x1123153b, BTTV_TERRATVRADIO, "Terratec TV Radio+" }, 201 { 0x1123153b, BTTV_BOARD_TERRATVRADIO, "Terratec TV Radio+" },
201 { 0x1127153b, BTTV_TERRATV, "Terratec TV+ (V1.05)" }, 202 { 0x1127153b, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.05)" },
202 /* clashes with FlyVideo 203 /* clashes with FlyVideo
203 *{ 0x18521852, BTTV_TERRATV, "Terratec TV+ (V1.10)" }, */ 204 *{ 0x18521852, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.10)" }, */
204 { 0x1134153b, BTTV_TERRATVALUE, "Terratec TValue (LR102)" }, 205 { 0x1134153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (LR102)" },
205 { 0x1135153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */ 206 { 0x1135153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
206 { 0x5018153b, BTTV_TERRATVALUE, "Terratec TValue" }, /* ?? */ 207 { 0x5018153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue" }, /* ?? */
207 { 0xff3b153b, BTTV_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */ 208 { 0xff3b153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
208 209
209 { 0x400015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 210 { 0x400015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
210 { 0x400a15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV" }, 211 { 0x400a15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
211 { 0x400d15b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 212 { 0x400d15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
212 { 0x401015b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 213 { 0x401015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
213 { 0x401615b0, BTTV_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" }, 214 { 0x401615b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
214 215
215 { 0x1430aa00, BTTV_PV143, "Provideo PV143A" }, 216 { 0x1430aa00, BTTV_BOARD_PV143, "Provideo PV143A" },
216 { 0x1431aa00, BTTV_PV143, "Provideo PV143B" }, 217 { 0x1431aa00, BTTV_BOARD_PV143, "Provideo PV143B" },
217 { 0x1432aa00, BTTV_PV143, "Provideo PV143C" }, 218 { 0x1432aa00, BTTV_BOARD_PV143, "Provideo PV143C" },
218 { 0x1433aa00, BTTV_PV143, "Provideo PV143D" }, 219 { 0x1433aa00, BTTV_BOARD_PV143, "Provideo PV143D" },
219 { 0x1433aa03, BTTV_PV143, "Security Eyes" }, 220 { 0x1433aa03, BTTV_BOARD_PV143, "Security Eyes" },
220 221
221 { 0x1460aa00, BTTV_PV150, "Provideo PV150A-1" }, 222 { 0x1460aa00, BTTV_BOARD_PV150, "Provideo PV150A-1" },
222 { 0x1461aa01, BTTV_PV150, "Provideo PV150A-2" }, 223 { 0x1461aa01, BTTV_BOARD_PV150, "Provideo PV150A-2" },
223 { 0x1462aa02, BTTV_PV150, "Provideo PV150A-3" }, 224 { 0x1462aa02, BTTV_BOARD_PV150, "Provideo PV150A-3" },
224 { 0x1463aa03, BTTV_PV150, "Provideo PV150A-4" }, 225 { 0x1463aa03, BTTV_BOARD_PV150, "Provideo PV150A-4" },
225 226
226 { 0x1464aa04, BTTV_PV150, "Provideo PV150B-1" }, 227 { 0x1464aa04, BTTV_BOARD_PV150, "Provideo PV150B-1" },
227 { 0x1465aa05, BTTV_PV150, "Provideo PV150B-2" }, 228 { 0x1465aa05, BTTV_BOARD_PV150, "Provideo PV150B-2" },
228 { 0x1466aa06, BTTV_PV150, "Provideo PV150B-3" }, 229 { 0x1466aa06, BTTV_BOARD_PV150, "Provideo PV150B-3" },
229 { 0x1467aa07, BTTV_PV150, "Provideo PV150B-4" }, 230 { 0x1467aa07, BTTV_BOARD_PV150, "Provideo PV150B-4" },
230 231
231 { 0xa132ff00, BTTV_IVC100, "IVC-100" }, 232 { 0xa132ff00, BTTV_BOARD_IVC100, "IVC-100" },
232 { 0xa1550000, BTTV_IVC200, "IVC-200" }, 233 { 0xa1550000, BTTV_BOARD_IVC200, "IVC-200" },
233 { 0xa1550001, BTTV_IVC200, "IVC-200" }, 234 { 0xa1550001, BTTV_BOARD_IVC200, "IVC-200" },
234 { 0xa1550002, BTTV_IVC200, "IVC-200" }, 235 { 0xa1550002, BTTV_BOARD_IVC200, "IVC-200" },
235 { 0xa1550003, BTTV_IVC200, "IVC-200" }, 236 { 0xa1550003, BTTV_BOARD_IVC200, "IVC-200" },
236 { 0xa1550100, BTTV_IVC200, "IVC-200G" }, 237 { 0xa1550100, BTTV_BOARD_IVC200, "IVC-200G" },
237 { 0xa1550101, BTTV_IVC200, "IVC-200G" }, 238 { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" },
238 { 0xa1550102, BTTV_IVC200, "IVC-200G" }, 239 { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" },
239 { 0xa1550103, BTTV_IVC200, "IVC-200G" }, 240 { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" },
240 { 0xa182ff00, BTTV_IVC120, "IVC-120G" }, 241 { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" },
241 { 0xa182ff01, BTTV_IVC120, "IVC-120G" }, 242 { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" },
242 { 0xa182ff02, BTTV_IVC120, "IVC-120G" }, 243 { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" },
243 { 0xa182ff03, BTTV_IVC120, "IVC-120G" }, 244 { 0xa182ff03, BTTV_BOARD_IVC120, "IVC-120G" },
244 { 0xa182ff04, BTTV_IVC120, "IVC-120G" }, 245 { 0xa182ff04, BTTV_BOARD_IVC120, "IVC-120G" },
245 { 0xa182ff05, BTTV_IVC120, "IVC-120G" }, 246 { 0xa182ff05, BTTV_BOARD_IVC120, "IVC-120G" },
246 { 0xa182ff06, BTTV_IVC120, "IVC-120G" }, 247 { 0xa182ff06, BTTV_BOARD_IVC120, "IVC-120G" },
247 { 0xa182ff07, BTTV_IVC120, "IVC-120G" }, 248 { 0xa182ff07, BTTV_BOARD_IVC120, "IVC-120G" },
248 { 0xa182ff08, BTTV_IVC120, "IVC-120G" }, 249 { 0xa182ff08, BTTV_BOARD_IVC120, "IVC-120G" },
249 { 0xa182ff09, BTTV_IVC120, "IVC-120G" }, 250 { 0xa182ff09, BTTV_BOARD_IVC120, "IVC-120G" },
250 { 0xa182ff0a, BTTV_IVC120, "IVC-120G" }, 251 { 0xa182ff0a, BTTV_BOARD_IVC120, "IVC-120G" },
251 { 0xa182ff0b, BTTV_IVC120, "IVC-120G" }, 252 { 0xa182ff0b, BTTV_BOARD_IVC120, "IVC-120G" },
252 { 0xa182ff0c, BTTV_IVC120, "IVC-120G" }, 253 { 0xa182ff0c, BTTV_BOARD_IVC120, "IVC-120G" },
253 { 0xa182ff0d, BTTV_IVC120, "IVC-120G" }, 254 { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
254 { 0xa182ff0e, BTTV_IVC120, "IVC-120G" }, 255 { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
255 { 0xa182ff0f, BTTV_IVC120, "IVC-120G" }, 256 { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
256 257
257 { 0x41424344, BTTV_GRANDTEC, "GrandTec Multi Capture" }, 258 { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
258 { 0x01020304, BTTV_XGUARD, "Grandtec Grand X-Guard" }, 259 { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
259 260
260 { 0x18501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, 261 { 0x18501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
261 { 0xa0501851, BTTV_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" }, 262 { 0xa0501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
262 { 0x18511851, BTTV_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" }, 263 { 0x18511851, BTTV_BOARD_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
263 { 0x18521852, BTTV_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" }, 264 { 0x18521852, BTTV_BOARD_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
264 { 0x41a0a051, BTTV_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" }, 265 { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
265 { 0x18501f7f, BTTV_FLYVIDEO_98, "Lifeview Flyvideo 98" }, 266 { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" },
266 267
267 { 0x010115cb, BTTV_GMV1, "AG GMV1" }, 268 { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" },
268 { 0x010114c7, BTTV_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" }, 269 { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
269 270
270 { 0x10b42636, BTTV_HAUPPAUGE878, "STB ???" }, 271 { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" },
271 { 0x217d6606, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 272 { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
272 { 0xfff6f6ff, BTTV_WINFAST2000, "Leadtek WinFast TV 2000" }, 273 { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
273 { 0x03116000, BTTV_SENSORAY311, "Sensoray 311" }, 274 { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" },
274 { 0x00790e11, BTTV_WINDVR, "Canopus WinDVR PCI" }, 275 { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" },
275 { 0xa0fca1a0, BTTV_ZOLTRIX, "Face to Face Tvmax" }, 276 { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" },
276 { 0x20007063, BTTV_PC_HDTV, "pcHDTV HD-2000 TV"}, 277 { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"},
277 { 0x82b2aa6a, BTTV_SIMUS_GVC1100, "SIMUS GVC1100" }, 278 { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" },
278 { 0x146caa0c, BTTV_PV951, "ituner spectra8" }, 279 { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" },
279 { 0x200a1295, BTTV_PXC200, "ImageNation PXC200A" }, 280 { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" },
280 281
281 { 0x40111554, BTTV_PV_BT878P_9B, "Prolink Pixelview PV-BT" }, 282 { 0x40111554, BTTV_BOARD_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
282 { 0x17de0a01, BTTV_KWORLD, "Mecer TV/FM/Video Tuner" }, 283 { 0x17de0a01, BTTV_BOARD_KWORLD, "Mecer TV/FM/Video Tuner" },
283 284
284 { 0x01051805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" }, 285 { 0x01051805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
285 { 0x01061805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" }, 286 { 0x01061805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
286 { 0x01071805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" }, 287 { 0x01071805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
287 { 0x01081805, BTTV_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" }, 288 { 0x01081805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
288 289
289 { 0x15409511, BTTV_ACORP_Y878F, "Acorp Y878F" }, 290 { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
290 291
291 /* likely broken, vendor id doesn't match the other magic views ... 292 /* likely broken, vendor id doesn't match the other magic views ...
292 * { 0xa0fca04f, BTTV_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ 293 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
293 294
294 /* DVB cards (using pci function .1 for mpeg data xfer) */ 295 /* DVB cards (using pci function .1 for mpeg data xfer) */
295 { 0x01010071, BTTV_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, 296 { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
296 { 0x07611461, BTTV_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, 297 { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
297 { 0x001c11bd, BTTV_PINNACLESAT, "Pinnacle PCTV Sat" }, 298 { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
298 { 0x002611bd, BTTV_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, 299 { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
299 { 0x00011822, BTTV_TWINHAN_DST, "Twinhan VisionPlus DVB" }, 300 { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" },
300 { 0xfc00270f, BTTV_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, 301 { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
301 { 0x07711461, BTTV_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, 302 { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
302 { 0xdb1018ac, BTTV_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, 303 { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
303 { 0xd50018ac, BTTV_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, 304 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
304 305
305 { 0, -1, NULL } 306 { 0, -1, NULL }
306}; 307};
@@ -309,2116 +310,2494 @@ static struct CARD {
309/* array with description for bt848 / bt878 tv/grabber cards */ 310/* array with description for bt848 / bt878 tv/grabber cards */
310 311
311struct tvcard bttv_tvcards[] = { 312struct tvcard bttv_tvcards[] = {
312{ 313 /* ---- card 0x00 ---------------------------------- */
313/* ---- card 0x00 ---------------------------------- */ 314 [BTTV_BOARD_UNKNOWN] = {
314 .name = " *** UNKNOWN/GENERIC *** ", 315 .name = " *** UNKNOWN/GENERIC *** ",
315 .video_inputs = 4, 316 .video_inputs = 4,
316 .audio_inputs = 1, 317 .audio_inputs = 1,
317 .tuner = 0, 318 .tuner = 0,
318 .svhs = 2, 319 .svhs = 2,
319 .muxsel = { 2, 3, 1, 0}, 320 .muxsel = { 2, 3, 1, 0},
320 .tuner_type = -1, 321 .tuner_type = -1,
321 .tuner_addr = ADDR_UNSET, 322 .tuner_addr = ADDR_UNSET,
322},{ 323 .radio_addr = ADDR_UNSET,
323 .name = "MIRO PCTV", 324 },
324 .video_inputs = 4, 325 [BTTV_BOARD_MIRO] = {
325 .audio_inputs = 1, 326 .name = "MIRO PCTV",
326 .tuner = 0, 327 .video_inputs = 4,
327 .svhs = 2, 328 .audio_inputs = 1,
328 .gpiomask = 15, 329 .tuner = 0,
329 .muxsel = { 2, 3, 1, 1}, 330 .svhs = 2,
330 .audiomux = { 2, 0, 0, 0, 10}, 331 .gpiomask = 15,
331 .needs_tvaudio = 1, 332 .muxsel = { 2, 3, 1, 1},
332 .tuner_type = -1, 333 .audiomux = { 2, 0, 0, 0, 10},
333 .tuner_addr = ADDR_UNSET, 334 .needs_tvaudio = 1,
334},{ 335 .tuner_type = -1,
335 .name = "Hauppauge (bt848)", 336 .tuner_addr = ADDR_UNSET,
336 .video_inputs = 4, 337 .radio_addr = ADDR_UNSET,
337 .audio_inputs = 1, 338 },
338 .tuner = 0, 339 [BTTV_BOARD_HAUPPAUGE] = {
339 .svhs = 2, 340 .name = "Hauppauge (bt848)",
340 .gpiomask = 7, 341 .video_inputs = 4,
341 .muxsel = { 2, 3, 1, 1}, 342 .audio_inputs = 1,
342 .audiomux = { 0, 1, 2, 3, 4}, 343 .tuner = 0,
343 .needs_tvaudio = 1, 344 .svhs = 2,
344 .tuner_type = -1, 345 .gpiomask = 7,
345 .tuner_addr = ADDR_UNSET, 346 .muxsel = { 2, 3, 1, 1},
346},{ 347 .audiomux = { 0, 1, 2, 3, 4},
347 .name = "STB, Gateway P/N 6000699 (bt848)", 348 .needs_tvaudio = 1,
348 .video_inputs = 3, 349 .tuner_type = -1,
349 .audio_inputs = 1, 350 .tuner_addr = ADDR_UNSET,
350 .tuner = 0, 351 .radio_addr = ADDR_UNSET,
351 .svhs = 2, 352 },
352 .gpiomask = 7, 353 [BTTV_BOARD_STB] = {
353 .muxsel = { 2, 3, 1, 1}, 354 .name = "STB, Gateway P/N 6000699 (bt848)",
354 .audiomux = { 4, 0, 2, 3, 1}, 355 .video_inputs = 3,
355 .no_msp34xx = 1, 356 .audio_inputs = 1,
356 .needs_tvaudio = 1, 357 .tuner = 0,
357 .tuner_type = TUNER_PHILIPS_NTSC, 358 .svhs = 2,
358 .tuner_addr = ADDR_UNSET, 359 .gpiomask = 7,
359 .pll = PLL_28, 360 .muxsel = { 2, 3, 1, 1},
360 .has_radio = 1, 361 .audiomux = { 4, 0, 2, 3, 1},
361},{ 362 .no_msp34xx = 1,
362 363 .needs_tvaudio = 1,
363/* ---- card 0x04 ---------------------------------- */ 364 .tuner_type = TUNER_PHILIPS_NTSC,
364 .name = "Intel Create and Share PCI/ Smart Video Recorder III", 365 .tuner_addr = ADDR_UNSET,
365 .video_inputs = 4, 366 .radio_addr = ADDR_UNSET,
366 .audio_inputs = 0, 367 .pll = PLL_28,
367 .tuner = -1, 368 .has_radio = 1,
368 .svhs = 2, 369 },
369 .gpiomask = 0, 370
370 .muxsel = { 2, 3, 1, 1}, 371 /* ---- card 0x04 ---------------------------------- */
371 .audiomux = { 0 }, 372 [BTTV_BOARD_INTEL] = {
372 .needs_tvaudio = 0, 373 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
373 .tuner_type = 4, 374 .video_inputs = 4,
374 .tuner_addr = ADDR_UNSET, 375 .audio_inputs = 0,
375},{ 376 .tuner = -1,
376 .name = "Diamond DTV2000", 377 .svhs = 2,
377 .video_inputs = 4, 378 .gpiomask = 0,
378 .audio_inputs = 1, 379 .muxsel = { 2, 3, 1, 1},
379 .tuner = 0, 380 .audiomux = { 0 },
380 .svhs = 2, 381 .needs_tvaudio = 0,
381 .gpiomask = 3, 382 .tuner_type = 4,
382 .muxsel = { 2, 3, 1, 0}, 383 .tuner_addr = ADDR_UNSET,
383 .audiomux = { 0, 1, 0, 1, 3}, 384 .radio_addr = ADDR_UNSET,
384 .needs_tvaudio = 1, 385 },
385 .tuner_type = -1, 386 [BTTV_BOARD_DIAMOND] = {
386 .tuner_addr = ADDR_UNSET, 387 .name = "Diamond DTV2000",
387},{ 388 .video_inputs = 4,
388 .name = "AVerMedia TVPhone", 389 .audio_inputs = 1,
389 .video_inputs = 3, 390 .tuner = 0,
390 .audio_inputs = 1, 391 .svhs = 2,
391 .tuner = 0, 392 .gpiomask = 3,
392 .svhs = 3, 393 .muxsel = { 2, 3, 1, 0},
393 .muxsel = { 2, 3, 1, 1}, 394 .audiomux = { 0, 1, 0, 1, 3},
394 .gpiomask = 0x0f, 395 .needs_tvaudio = 1,
395 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0}, 396 .tuner_type = -1,
396 /* 0x04 for some cards ?? */ 397 .tuner_addr = ADDR_UNSET,
397 .needs_tvaudio = 1, 398 .radio_addr = ADDR_UNSET,
398 .tuner_type = -1, 399 },
399 .tuner_addr = ADDR_UNSET, 400 [BTTV_BOARD_AVERMEDIA] = {
400 .audio_hook = avermedia_tvphone_audio, 401 .name = "AVerMedia TVPhone",
401 .has_remote = 1, 402 .video_inputs = 3,
402},{ 403 .audio_inputs = 1,
403 .name = "MATRIX-Vision MV-Delta", 404 .tuner = 0,
404 .video_inputs = 5, 405 .svhs = 3,
405 .audio_inputs = 1, 406 .muxsel = { 2, 3, 1, 1},
406 .tuner = -1, 407 .gpiomask = 0x0f,
407 .svhs = 3, 408 .audiomux = { 0x0c, 0x04, 0x08, 0x04, 0},
408 .gpiomask = 0, 409 /* 0x04 for some cards ?? */
409 .muxsel = { 2, 3, 1, 0, 0}, 410 .needs_tvaudio = 1,
410 .audiomux = {0 }, 411 .tuner_type = -1,
411 .needs_tvaudio = 1, 412 .tuner_addr = ADDR_UNSET,
412 .tuner_type = -1, 413 .radio_addr = ADDR_UNSET,
413 .tuner_addr = ADDR_UNSET, 414 .audio_hook = avermedia_tvphone_audio,
414},{ 415 .has_remote = 1,
415 416 },
416/* ---- card 0x08 ---------------------------------- */ 417 [BTTV_BOARD_MATRIX_VISION] = {
417 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26", 418 .name = "MATRIX-Vision MV-Delta",
418 .video_inputs = 4, 419 .video_inputs = 5,
419 .audio_inputs = 1, 420 .audio_inputs = 1,
420 .tuner = 0, 421 .tuner = -1,
421 .svhs = 2, 422 .svhs = 3,
422 .gpiomask = 0xc00, 423 .gpiomask = 0,
423 .muxsel = { 2, 3, 1, 1}, 424 .muxsel = { 2, 3, 1, 0, 0},
424 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0}, 425 .audiomux = {0 },
425 .needs_tvaudio = 1, 426 .needs_tvaudio = 1,
426 .pll = PLL_28, 427 .tuner_type = -1,
427 .tuner_type = -1, 428 .tuner_addr = ADDR_UNSET,
428 .tuner_addr = ADDR_UNSET, 429 .radio_addr = ADDR_UNSET,
429},{ 430 },
430 .name = "IMS/IXmicro TurboTV", 431
431 .video_inputs = 3, 432 /* ---- card 0x08 ---------------------------------- */
432 .audio_inputs = 1, 433 [BTTV_BOARD_FLYVIDEO] = {
433 .tuner = 0, 434 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
434 .svhs = 2, 435 .video_inputs = 4,
435 .gpiomask = 3, 436 .audio_inputs = 1,
436 .muxsel = { 2, 3, 1, 1}, 437 .tuner = 0,
437 .audiomux = { 1, 1, 2, 3, 0}, 438 .svhs = 2,
438 .needs_tvaudio = 0, 439 .gpiomask = 0xc00,
439 .pll = PLL_28, 440 .muxsel = { 2, 3, 1, 1},
440 .tuner_type = TUNER_TEMIC_PAL, 441 .audiomux = { 0, 0xc00, 0x800, 0x400, 0xc00, 0},
441 .tuner_addr = ADDR_UNSET, 442 .needs_tvaudio = 1,
442},{ 443 .pll = PLL_28,
443 .name = "Hauppauge (bt878)", 444 .tuner_type = -1,
444 .video_inputs = 4, 445 .tuner_addr = ADDR_UNSET,
445 .audio_inputs = 1, 446 .radio_addr = ADDR_UNSET,
446 .tuner = 0, 447 },
447 .svhs = 2, 448 [BTTV_BOARD_TURBOTV] = {
448 .gpiomask = 0x0f, /* old: 7 */ 449 .name = "IMS/IXmicro TurboTV",
449 .muxsel = { 2, 0, 1, 1}, 450 .video_inputs = 3,
450 .audiomux = { 0, 1, 2, 3, 4}, 451 .audio_inputs = 1,
451 .needs_tvaudio = 1, 452 .tuner = 0,
452 .pll = PLL_28, 453 .svhs = 2,
453 .tuner_type = -1, 454 .gpiomask = 3,
454 .tuner_addr = ADDR_UNSET, 455 .muxsel = { 2, 3, 1, 1},
455},{ 456 .audiomux = { 1, 1, 2, 3, 0},
456 .name = "MIRO PCTV pro", 457 .needs_tvaudio = 0,
457 .video_inputs = 3, 458 .pll = PLL_28,
458 .audio_inputs = 1, 459 .tuner_type = TUNER_TEMIC_PAL,
459 .tuner = 0, 460 .tuner_addr = ADDR_UNSET,
460 .svhs = 2, 461 .radio_addr = ADDR_UNSET,
461 .gpiomask = 0x3014f, 462 },
462 .muxsel = { 2, 3, 1, 1}, 463 [BTTV_BOARD_HAUPPAUGE878] = {
463 .audiomux = { 0x20001,0x10001, 0, 0,10}, 464 .name = "Hauppauge (bt878)",
464 .needs_tvaudio = 1, 465 .video_inputs = 4,
465 .tuner_type = -1, 466 .audio_inputs = 1,
466 .tuner_addr = ADDR_UNSET, 467 .tuner = 0,
467},{ 468 .svhs = 2,
468 469 .gpiomask = 0x0f, /* old: 7 */
469/* ---- card 0x0c ---------------------------------- */ 470 .muxsel = { 2, 0, 1, 1},
470 .name = "ADS Technologies Channel Surfer TV (bt848)", 471 .audiomux = { 0, 1, 2, 3, 4},
471 .video_inputs = 3, 472 .needs_tvaudio = 1,
472 .audio_inputs = 1, 473 .pll = PLL_28,
473 .tuner = 0, 474 .tuner_type = -1,
474 .svhs = 2, 475 .tuner_addr = ADDR_UNSET,
475 .gpiomask = 15, 476 .radio_addr = ADDR_UNSET,
476 .muxsel = { 2, 3, 1, 1}, 477 },
477 .audiomux = { 13, 14, 11, 7, 0, 0}, 478 [BTTV_BOARD_MIROPRO] = {
478 .needs_tvaudio = 1, 479 .name = "MIRO PCTV pro",
479 .tuner_type = -1, 480 .video_inputs = 3,
480 .tuner_addr = ADDR_UNSET, 481 .audio_inputs = 1,
481},{ 482 .tuner = 0,
482 .name = "AVerMedia TVCapture 98", 483 .svhs = 2,
483 .video_inputs = 3, 484 .gpiomask = 0x3014f,
484 .audio_inputs = 4, 485 .muxsel = { 2, 3, 1, 1},
485 .tuner = 0, 486 .audiomux = { 0x20001,0x10001, 0, 0,10},
486 .svhs = 2, 487 .needs_tvaudio = 1,
487 .gpiomask = 15, 488 .tuner_type = -1,
488 .muxsel = { 2, 3, 1, 1}, 489 .tuner_addr = ADDR_UNSET,
489 .audiomux = { 13, 14, 11, 7, 0, 0}, 490 .radio_addr = ADDR_UNSET,
490 .needs_tvaudio = 1, 491 },
491 .msp34xx_alt = 1, 492
492 .pll = PLL_28, 493 /* ---- card 0x0c ---------------------------------- */
493 .tuner_type = TUNER_PHILIPS_PAL, 494 [BTTV_BOARD_ADSTECH_TV] = {
494 .tuner_addr = ADDR_UNSET, 495 .name = "ADS Technologies Channel Surfer TV (bt848)",
495 .audio_hook = avermedia_tv_stereo_audio, 496 .video_inputs = 3,
496},{ 497 .audio_inputs = 1,
497 .name = "Aimslab Video Highway Xtreme (VHX)", 498 .tuner = 0,
498 .video_inputs = 3, 499 .svhs = 2,
499 .audio_inputs = 1, 500 .gpiomask = 15,
500 .tuner = 0, 501 .muxsel = { 2, 3, 1, 1},
501 .svhs = 2, 502 .audiomux = { 13, 14, 11, 7, 0, 0},
502 .gpiomask = 7, 503 .needs_tvaudio = 1,
503 .muxsel = { 2, 3, 1, 1}, 504 .tuner_type = -1,
504 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */ 505 .tuner_addr = ADDR_UNSET,
505 .needs_tvaudio = 1, 506 .radio_addr = ADDR_UNSET,
506 .pll = PLL_28, 507 },
507 .tuner_type = -1, 508 [BTTV_BOARD_AVERMEDIA98] = {
508 .tuner_addr = ADDR_UNSET, 509 .name = "AVerMedia TVCapture 98",
509},{ 510 .video_inputs = 3,
510 .name = "Zoltrix TV-Max", 511 .audio_inputs = 4,
511 .video_inputs = 3, 512 .tuner = 0,
512 .audio_inputs = 1, 513 .svhs = 2,
513 .tuner = 0, 514 .gpiomask = 15,
514 .svhs = 2, 515 .muxsel = { 2, 3, 1, 1},
515 .gpiomask = 15, 516 .audiomux = { 13, 14, 11, 7, 0, 0},
516 .muxsel = { 2, 3, 1, 1}, 517 .needs_tvaudio = 1,
517 .audiomux = {0 , 0, 1 , 0, 10}, 518 .msp34xx_alt = 1,
518 .needs_tvaudio = 1, 519 .pll = PLL_28,
519 .tuner_type = -1, 520 .tuner_type = TUNER_PHILIPS_PAL,
520 .tuner_addr = ADDR_UNSET, 521 .tuner_addr = ADDR_UNSET,
521},{ 522 .radio_addr = ADDR_UNSET,
522 523 .audio_hook = avermedia_tv_stereo_audio,
523/* ---- card 0x10 ---------------------------------- */ 524 .no_gpioirq = 1,
524 .name = "Prolink Pixelview PlayTV (bt878)", 525 },
525 .video_inputs = 3, 526 [BTTV_BOARD_VHX] = {
526 .audio_inputs = 1, 527 .name = "Aimslab Video Highway Xtreme (VHX)",
527 .tuner = 0, 528 .video_inputs = 3,
528 .svhs = 2, 529 .audio_inputs = 1,
529 .gpiomask = 0x01fe00, 530 .tuner = 0,
530 .muxsel = { 2, 3, 1, 1}, 531 .svhs = 2,
531 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */ 532 .gpiomask = 7,
532 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, 533 .muxsel = { 2, 3, 1, 1},
533 .needs_tvaudio = 1, 534 .audiomux = { 0, 2, 1, 3, 4}, /* old: { 0, 1, 2, 3, 4} */
534 .pll = PLL_28, 535 .needs_tvaudio = 1,
535 .tuner_type = -1, 536 .pll = PLL_28,
536},{ 537 .tuner_type = -1,
537 .name = "Leadtek WinView 601", 538 .tuner_addr = ADDR_UNSET,
538 .video_inputs = 3, 539 .radio_addr = ADDR_UNSET,
539 .audio_inputs = 1, 540 },
540 .tuner = 0, 541 [BTTV_BOARD_ZOLTRIX] = {
541 .svhs = 2, 542 .name = "Zoltrix TV-Max",
542 .gpiomask = 0x8300f8, 543 .video_inputs = 3,
543 .muxsel = { 2, 3, 1, 1,0}, 544 .audio_inputs = 1,
544 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007}, 545 .tuner = 0,
545 .needs_tvaudio = 1, 546 .svhs = 2,
546 .tuner_type = -1, 547 .gpiomask = 15,
547 .tuner_addr = ADDR_UNSET, 548 .muxsel = { 2, 3, 1, 1},
548 .audio_hook = winview_audio, 549 .audiomux = {0 , 0, 1 , 0, 10},
549 .has_radio = 1, 550 .needs_tvaudio = 1,
550},{ 551 .tuner_type = -1,
551 .name = "AVEC Intercapture", 552 .tuner_addr = ADDR_UNSET,
552 .video_inputs = 3, 553 .radio_addr = ADDR_UNSET,
553 .audio_inputs = 2, 554 },
554 .tuner = 0, 555
555 .svhs = 2, 556 /* ---- card 0x10 ---------------------------------- */
556 .gpiomask = 0, 557 [BTTV_BOARD_PIXVIEWPLAYTV] = {
557 .muxsel = {2, 3, 1, 1}, 558 .name = "Prolink Pixelview PlayTV (bt878)",
558 .audiomux = {1, 0, 0, 0, 0}, 559 .video_inputs = 3,
559 .needs_tvaudio = 1, 560 .audio_inputs = 1,
560 .tuner_type = -1, 561 .tuner = 0,
561 .tuner_addr = ADDR_UNSET, 562 .svhs = 2,
562},{ 563 .gpiomask = 0x01fe00,
563 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)", 564 .muxsel = { 2, 3, 1, 1},
564 .video_inputs = 4, 565 #if 0
565 .audio_inputs = 1, 566 /* old */
566 .tuner = -1, 567 .audiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 },
567 .svhs = -1, 568 #else
568 .gpiomask = 0x8dff00, 569 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
569 .muxsel = { 2, 3, 1, 1}, 570 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
570 .audiomux = { 0 }, 571 #endif
571 .no_msp34xx = 1, 572 .needs_tvaudio = 1,
572 .tuner_type = -1, 573 .pll = PLL_28,
573 .tuner_addr = ADDR_UNSET, 574 .tuner_type = -1,
574},{ 575 },
575 576 [BTTV_BOARD_WINVIEW_601] = {
576/* ---- card 0x14 ---------------------------------- */ 577 .name = "Leadtek WinView 601",
577 .name = "CEI Raffles Card", 578 .video_inputs = 3,
578 .video_inputs = 3, 579 .audio_inputs = 1,
579 .audio_inputs = 3, 580 .tuner = 0,
580 .tuner = 0, 581 .svhs = 2,
581 .svhs = 2, 582 .gpiomask = 0x8300f8,
582 .muxsel = {2, 3, 1, 1}, 583 .muxsel = { 2, 3, 1, 1,0},
583 .tuner_type = -1, 584 .audiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007,0xcfa007},
584 .tuner_addr = ADDR_UNSET, 585 .needs_tvaudio = 1,
585},{ 586 .tuner_type = -1,
586 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50", 587 .tuner_addr = ADDR_UNSET,
587 .video_inputs = 4, 588 .radio_addr = ADDR_UNSET,
588 .audio_inputs = 2, /* tuner, line in */ 589 .audio_hook = winview_audio,
589 .tuner = 0, 590 .has_radio = 1,
590 .svhs = 2, 591 },
591 .gpiomask = 0x1800, 592 [BTTV_BOARD_AVEC_INTERCAP] = {
592 .muxsel = { 2, 3, 1, 1}, 593 .name = "AVEC Intercapture",
593 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 594 .video_inputs = 3,
594 .pll = PLL_28, 595 .audio_inputs = 2,
595 .tuner_type = TUNER_PHILIPS_PAL_I, 596 .tuner = 0,
596 .tuner_addr = ADDR_UNSET, 597 .svhs = 2,
597},{ 598 .gpiomask = 0,
598 .name = "Askey CPH050/ Phoebe Tv Master + FM", 599 .muxsel = {2, 3, 1, 1},
599 .video_inputs = 3, 600 .audiomux = {1, 0, 0, 0, 0},
600 .audio_inputs = 1, 601 .needs_tvaudio = 1,
601 .tuner = 0, 602 .tuner_type = -1,
602 .svhs = 2, 603 .tuner_addr = ADDR_UNSET,
603 .gpiomask = 0xc00, 604 .radio_addr = ADDR_UNSET,
604 .muxsel = { 2, 3, 1, 1}, 605 },
605 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0}, 606 [BTTV_BOARD_LIFE_FLYKIT] = {
606 .needs_tvaudio = 1, 607 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
607 .pll = PLL_28, 608 .video_inputs = 4,
608 .tuner_type = -1, 609 .audio_inputs = 1,
609 .tuner_addr = ADDR_UNSET, 610 .tuner = -1,
610},{ 611 .svhs = -1,
611 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878", 612 .gpiomask = 0x8dff00,
612 .video_inputs = 3, 613 .muxsel = { 2, 3, 1, 1},
613 .audio_inputs = 1, 614 .audiomux = { 0 },
614 .tuner = 0, 615 .no_msp34xx = 1,
615 .svhs = -1, 616 .tuner_type = -1,
616 .gpiomask = 7, 617 .tuner_addr = ADDR_UNSET,
617 .muxsel = { 2, 3, -1 }, 618 .radio_addr = ADDR_UNSET,
618 .digital_mode = DIGITAL_MODE_CAMERA, 619 },
619 .audiomux = { 0, 0, 0, 0, 0 }, 620
620 .no_msp34xx = 1, 621 /* ---- card 0x14 ---------------------------------- */
621 .pll = PLL_28, 622 [BTTV_BOARD_CEI_RAFFLES] = {
622 .tuner_type = TUNER_ALPS_TSBB5_PAL_I, 623 .name = "CEI Raffles Card",
623 .tuner_addr = ADDR_UNSET, 624 .video_inputs = 3,
624},{ 625 .audio_inputs = 3,
625 626 .tuner = 0,
626/* ---- card 0x18 ---------------------------------- */ 627 .svhs = 2,
627 .name = "Askey CPH05X/06X (bt878) [many vendors]", 628 .muxsel = {2, 3, 1, 1},
628 .video_inputs = 3, 629 .tuner_type = -1,
629 .audio_inputs = 1, 630 .tuner_addr = ADDR_UNSET,
630 .tuner = 0, 631 .radio_addr = ADDR_UNSET,
631 .svhs = 2, 632 },
632 .gpiomask = 0xe00, 633 [BTTV_BOARD_CONFERENCETV] = {
633 .muxsel = { 2, 3, 1, 1}, 634 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
634 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00}, 635 .video_inputs = 4,
635 .needs_tvaudio = 1, 636 .audio_inputs = 2, /* tuner, line in */
636 .pll = PLL_28, 637 .tuner = 0,
637 .tuner_type = -1, 638 .svhs = 2,
638 .tuner_addr = ADDR_UNSET, 639 .gpiomask = 0x1800,
639 .has_remote = 1, 640 .muxsel = { 2, 3, 1, 1},
640},{ 641 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
641 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar", 642 .pll = PLL_28,
642 .video_inputs = 3, 643 .tuner_type = TUNER_PHILIPS_PAL_I,
643 .audio_inputs = 1, 644 .tuner_addr = ADDR_UNSET,
644 .tuner = 0, 645 .radio_addr = ADDR_UNSET,
645 .svhs = 2, 646 },
646 .gpiomask = 0x1f0fff, 647 [BTTV_BOARD_PHOEBE_TVMAS] = {
647 .muxsel = { 2, 3, 1, 1}, 648 .name = "Askey CPH050/ Phoebe Tv Master + FM",
648 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000}, 649 .video_inputs = 3,
649 .needs_tvaudio = 0, 650 .audio_inputs = 1,
650 .tuner_type = TUNER_PHILIPS_PAL, 651 .tuner = 0,
651 .tuner_addr = ADDR_UNSET, 652 .svhs = 2,
652 .audio_hook = terratv_audio, 653 .gpiomask = 0xc00,
653},{ 654 .muxsel = { 2, 3, 1, 1},
654 .name = "Hauppauge WinCam newer (bt878)", 655 .audiomux = {0, 1, 0x800, 0x400, 0xc00, 0},
655 .video_inputs = 4, 656 .needs_tvaudio = 1,
656 .audio_inputs = 1, 657 .pll = PLL_28,
657 .tuner = 0, 658 .tuner_type = -1,
658 .svhs = 3, 659 .tuner_addr = ADDR_UNSET,
659 .gpiomask = 7, 660 .radio_addr = ADDR_UNSET,
660 .muxsel = { 2, 0, 1, 1}, 661 },
661 .audiomux = { 0, 1, 2, 3, 4}, 662 [BTTV_BOARD_MODTEC_205] = {
662 .needs_tvaudio = 1, 663 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
663 .tuner_type = -1, 664 .video_inputs = 3,
664 .tuner_addr = ADDR_UNSET, 665 .audio_inputs = 1,
665},{ 666 .tuner = 0,
666 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50", 667 .svhs = -1,
667 .video_inputs = 4, 668 .gpiomask = 7,
668 .audio_inputs = 2, 669 .muxsel = { 2, 3, -1 },
669 .tuner = 0, 670 .digital_mode = DIGITAL_MODE_CAMERA,
670 .svhs = 2, 671 .audiomux = { 0, 0, 0, 0, 0 },
671 .gpiomask = 0x1800, 672 .no_msp34xx = 1,
672 .muxsel = { 2, 3, 1, 1}, 673 .pll = PLL_28,
673 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800}, 674 .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
674 .pll = PLL_28, 675 .tuner_addr = ADDR_UNSET,
675 .tuner_type = TUNER_PHILIPS_SECAM, 676 .radio_addr = ADDR_UNSET,
676 .tuner_addr = ADDR_UNSET, 677 },
677},{ 678
678 679 /* ---- card 0x18 ---------------------------------- */
679/* ---- card 0x1c ---------------------------------- */ 680 [BTTV_BOARD_MAGICTVIEW061] = {
680 .name = "Terratec TerraTV+ Version 1.1 (bt878)", 681 .name = "Askey CPH05X/06X (bt878) [many vendors]",
681 .video_inputs = 3, 682 .video_inputs = 3,
682 .audio_inputs = 1, 683 .audio_inputs = 1,
683 .tuner = 0, 684 .tuner = 0,
684 .svhs = 2, 685 .svhs = 2,
685 .gpiomask = 0x1f0fff, 686 .gpiomask = 0xe00,
686 .muxsel = { 2, 3, 1, 1}, 687 .muxsel = { 2, 3, 1, 1},
687 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000}, 688 .audiomux = {0x400, 0x400, 0x400, 0x400, 0xc00},
688 .needs_tvaudio = 0, 689 .needs_tvaudio = 1,
689 .tuner_type = TUNER_PHILIPS_PAL, 690 .pll = PLL_28,
690 .tuner_addr = ADDR_UNSET, 691 .tuner_type = -1,
691 .audio_hook = terratv_audio, 692 .tuner_addr = ADDR_UNSET,
692 /* GPIO wiring: 693 .radio_addr = ADDR_UNSET,
693 External 20 pin connector (for Active Radio Upgrade board) 694 .has_remote = 1,
694 gpio00: i2c-sda 695 },
695 gpio01: i2c-scl 696 [BTTV_BOARD_VOBIS_BOOSTAR] = {
696 gpio02: om5610-data 697 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
697 gpio03: om5610-clk 698 .video_inputs = 3,
698 gpio04: om5610-wre 699 .audio_inputs = 1,
699 gpio05: om5610-stereo 700 .tuner = 0,
700 gpio06: rds6588-davn 701 .svhs = 2,
701 gpio07: Pin 7 n.c. 702 .gpiomask = 0x1f0fff,
702 gpio08: nIOW 703 .muxsel = { 2, 3, 1, 1},
703 gpio09+10: nIOR, nSEL ?? (bt878) 704 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000},
704 gpio09: nIOR (bt848) 705 .needs_tvaudio = 0,
705 gpio10: nSEL (bt848) 706 .tuner_type = TUNER_PHILIPS_PAL,
706 Sound Routing: 707 .tuner_addr = ADDR_UNSET,
707 gpio16: u2-A0 (1st 4052bt) 708 .radio_addr = ADDR_UNSET,
708 gpio17: u2-A1 709 .audio_hook = terratv_audio,
709 gpio18: u2-nEN 710 },
710 gpio19: u4-A0 (2nd 4052) 711 [BTTV_BOARD_HAUPPAUG_WCAM] = {
711 gpio20: u4-A1 712 .name = "Hauppauge WinCam newer (bt878)",
712 u4-nEN - GND 713 .video_inputs = 4,
713 Btspy: 714 .audio_inputs = 1,
714 00000 : Cdrom (internal audio input) 715 .tuner = 0,
715 10000 : ext. Video audio input 716 .svhs = 3,
716 20000 : TV Mono 717 .gpiomask = 7,
717 a0000 : TV Mono/2 718 .muxsel = { 2, 0, 1, 1},
718 1a0000 : TV Stereo 719 .audiomux = { 0, 1, 2, 3, 4},
719 30000 : Radio 720 .needs_tvaudio = 1,
720 40000 : Mute 721 .tuner_type = -1,
721*/ 722 .tuner_addr = ADDR_UNSET,
722 723 .radio_addr = ADDR_UNSET,
723},{ 724 },
724 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */ 725 [BTTV_BOARD_MAXI] = {
725 .name = "Imagenation PXC200", 726 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
726 .video_inputs = 5, 727 .video_inputs = 4,
727 .audio_inputs = 1, 728 .audio_inputs = 2,
728 .tuner = -1, 729 .tuner = 0,
729 .svhs = 1, /* was: 4 */ 730 .svhs = 2,
730 .gpiomask = 0, 731 .gpiomask = 0x1800,
731 .muxsel = { 2, 3, 1, 0, 0}, 732 .muxsel = { 2, 3, 1, 1},
732 .audiomux = { 0 }, 733 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
733 .needs_tvaudio = 1, 734 .pll = PLL_28,
734 .tuner_type = -1, 735 .tuner_type = TUNER_PHILIPS_SECAM,
735 .tuner_addr = ADDR_UNSET, 736 .tuner_addr = ADDR_UNSET,
736 .muxsel_hook = PXC200_muxsel, 737 .radio_addr = ADDR_UNSET,
737 738 },
738},{ 739
739 .name = "Lifeview FlyVideo 98 LR50", 740 /* ---- card 0x1c ---------------------------------- */
740 .video_inputs = 4, 741 [BTTV_BOARD_TERRATV] = {
741 .audio_inputs = 1, 742 .name = "Terratec TerraTV+ Version 1.1 (bt878)",
742 .tuner = 0, 743 .video_inputs = 3,
743 .svhs = 2, 744 .audio_inputs = 1,
744 .gpiomask = 0x1800, /* 0x8dfe00 */ 745 .tuner = 0,
745 .muxsel = { 2, 3, 1, 1}, 746 .svhs = 2,
746 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 }, 747 .gpiomask = 0x1f0fff,
747 .pll = PLL_28, 748 .muxsel = { 2, 3, 1, 1},
748 .tuner_type = -1, 749 .audiomux = { 0x20000, 0x30000, 0x10000, 0x00000, 0x40000},
749 .tuner_addr = ADDR_UNSET, 750 .needs_tvaudio = 0,
750},{ 751 .tuner_type = TUNER_PHILIPS_PAL,
751 .name = "Formac iProTV, Formac ProTV I (bt848)", 752 .tuner_addr = ADDR_UNSET,
752 .video_inputs = 4, 753 .radio_addr = ADDR_UNSET,
753 .audio_inputs = 1, 754 .audio_hook = terratv_audio,
754 .tuner = 0, 755 /* GPIO wiring:
755 .svhs = 3, 756 External 20 pin connector (for Active Radio Upgrade board)
756 .gpiomask = 1, 757 gpio00: i2c-sda
757 .muxsel = { 2, 3, 1, 1}, 758 gpio01: i2c-scl
758 .audiomux = { 1, 0, 0, 0, 0 }, 759 gpio02: om5610-data
759 .pll = PLL_28, 760 gpio03: om5610-clk
760 .tuner_type = TUNER_PHILIPS_PAL, 761 gpio04: om5610-wre
761 .tuner_addr = ADDR_UNSET, 762 gpio05: om5610-stereo
762},{ 763 gpio06: rds6588-davn
763 764 gpio07: Pin 7 n.c.
764/* ---- card 0x20 ---------------------------------- */ 765 gpio08: nIOW
765 .name = "Intel Create and Share PCI/ Smart Video Recorder III", 766 gpio09+10: nIOR, nSEL ?? (bt878)
766 .video_inputs = 4, 767 gpio09: nIOR (bt848)
767 .audio_inputs = 0, 768 gpio10: nSEL (bt848)
768 .tuner = -1, 769 Sound Routing:
769 .svhs = 2, 770 gpio16: u2-A0 (1st 4052bt)
770 .gpiomask = 0, 771 gpio17: u2-A1
771 .muxsel = { 2, 3, 1, 1}, 772 gpio18: u2-nEN
772 .audiomux = { 0 }, 773 gpio19: u4-A0 (2nd 4052)
773 .needs_tvaudio = 0, 774 gpio20: u4-A1
774 .tuner_type = 4, 775 u4-nEN - GND
775 .tuner_addr = ADDR_UNSET, 776 Btspy:
776},{ 777 00000 : Cdrom (internal audio input)
777 .name = "Terratec TerraTValue Version Bt878", 778 10000 : ext. Video audio input
778 .video_inputs = 3, 779 20000 : TV Mono
779 .audio_inputs = 1, 780 a0000 : TV Mono/2
780 .tuner = 0, 781 1a0000 : TV Stereo
781 .svhs = 2, 782 30000 : Radio
782 .gpiomask = 0xffff00, 783 40000 : Mute
783 .muxsel = { 2, 3, 1, 1},
784 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
785 .needs_tvaudio = 1,
786 .pll = PLL_28,
787 .tuner_type = TUNER_PHILIPS_PAL,
788 .tuner_addr = ADDR_UNSET,
789},{
790 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
791 .video_inputs = 4,
792 .audio_inputs = 1,
793 .tuner = 0,
794 .svhs = 2,
795 .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
796 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
797 .gpiomask = 0xb33000,
798 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
799 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
800 gpio23 -- hef4052:nEnable (0x800000)
801 gpio12 -- hef4052:A1
802 gpio13 -- hef4052:A0
803 0x0000: external audio
804 0x1000: FM
805 0x2000: TV
806 0x3000: n.c.
807 Note: There exists another variant "Winfast 2000" with tv stereo !?
808 Note: eeprom only contains FF and pci subsystem id 107d:6606
809 */
810 .needs_tvaudio = 0,
811 .pll = PLL_28,
812 .has_radio = 1,
813 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
814 .tuner_addr = ADDR_UNSET,
815 .audio_hook = winfast2000_audio,
816 .has_remote = 1,
817},{
818 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
819 .video_inputs = 4,
820 .audio_inputs = 3,
821 .tuner = 0,
822 .svhs = 2,
823 .gpiomask = 0x1800,
824 .muxsel = { 2, 3, 1, 1},
825 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
826 .pll = PLL_28,
827 .tuner_type = -1,
828 .tuner_addr = ADDR_UNSET,
829},{
830
831/* ---- card 0x24 ---------------------------------- */
832 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
833 .video_inputs = 4,
834 .audio_inputs = 3,
835 .tuner = 0,
836 .svhs = 2,
837 .gpiomask = 0x1800,
838 .muxsel = { 2, 3, 1, 1},
839 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
840 .pll = PLL_28,
841 .tuner_type = -1,
842 .tuner_addr = ADDR_UNSET,
843 .has_radio = 1,
844},{
845 .name = "Prolink PixelView PlayTV pro",
846 .video_inputs = 3,
847 .audio_inputs = 1,
848 .tuner = 0,
849 .svhs = 2,
850 .gpiomask = 0xff,
851 .muxsel = { 2, 3, 1, 1 },
852 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
853 .no_msp34xx = 1,
854 .pll = PLL_28,
855 .tuner_type = -1,
856 .tuner_addr = ADDR_UNSET,
857},{
858 .name = "Askey CPH06X TView99",
859 .video_inputs = 4,
860 .audio_inputs = 1,
861 .tuner = 0,
862 .svhs = 2,
863 .gpiomask = 0x551e00,
864 .muxsel = { 2, 3, 1, 0},
865 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
866 .needs_tvaudio = 1,
867 .pll = PLL_28,
868 .tuner_type = 1,
869 .tuner_addr = ADDR_UNSET,
870 .has_remote = 1,
871},{
872 .name = "Pinnacle PCTV Studio/Rave",
873 .video_inputs = 3,
874 .audio_inputs = 1,
875 .tuner = 0,
876 .svhs = 2,
877 .gpiomask = 0x03000F,
878 .muxsel = { 2, 3, 1, 1},
879 .audiomux = { 2, 0xd0001, 0, 0, 1},
880 .needs_tvaudio = 0,
881 .pll = PLL_28,
882 .tuner_type = -1,
883 .tuner_addr = ADDR_UNSET,
884},{
885
886/* ---- card 0x28 ---------------------------------- */
887 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
888 .video_inputs = 3,
889 .audio_inputs = 1,
890 .tuner = 0,
891 .svhs = 2,
892 .gpiomask = 7,
893 .muxsel = { 2, 3, 1, 1},
894 .audiomux = { 4, 0, 2, 3, 1},
895 .no_msp34xx = 1,
896 .needs_tvaudio = 1,
897 .tuner_type = TUNER_PHILIPS_NTSC,
898 .tuner_addr = ADDR_UNSET,
899 .pll = PLL_28,
900 .has_radio = 1,
901},{
902 .name = "AVerMedia TVPhone 98",
903 .video_inputs = 3,
904 .audio_inputs = 4,
905 .tuner = 0,
906 .svhs = 2,
907 .gpiomask = 15,
908 .muxsel = { 2, 3, 1, 1},
909 .audiomux = { 13, 4, 11, 7, 0, 0},
910 .needs_tvaudio = 1,
911 .pll = PLL_28,
912 .tuner_type = -1,
913 .tuner_addr = ADDR_UNSET,
914 .has_radio = 1,
915 .audio_hook = avermedia_tvphone_audio,
916},{
917 .name = "ProVideo PV951", /* pic16c54 */
918 .video_inputs = 3,
919 .audio_inputs = 1,
920 .tuner = 0,
921 .svhs = 2,
922 .gpiomask = 0,
923 .muxsel = { 2, 3, 1, 1},
924 .audiomux = { 0, 0, 0, 0, 0},
925 .needs_tvaudio = 1,
926 .no_msp34xx = 1,
927 .pll = PLL_28,
928 .tuner_type = 1,
929 .tuner_addr = ADDR_UNSET,
930},{
931 .name = "Little OnAir TV",
932 .video_inputs = 3,
933 .audio_inputs = 1,
934 .tuner = 0,
935 .svhs = 2,
936 .gpiomask = 0xe00b,
937 .muxsel = {2, 3, 1, 1},
938 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
939 .no_msp34xx = 1,
940 .tuner_type = -1,
941 .tuner_addr = ADDR_UNSET,
942},{
943
944/* ---- card 0x2c ---------------------------------- */
945 .name = "Sigma TVII-FM",
946 .video_inputs = 2,
947 .audio_inputs = 1,
948 .tuner = 0,
949 .svhs = -1,
950 .gpiomask = 3,
951 .muxsel = {2, 3, 1, 1},
952 .audiomux = {1, 1, 0, 2, 3},
953 .no_msp34xx = 1,
954 .pll = PLL_NONE,
955 .tuner_type = -1,
956 .tuner_addr = ADDR_UNSET,
957},{
958 .name = "MATRIX-Vision MV-Delta 2",
959 .video_inputs = 5,
960 .audio_inputs = 1,
961 .tuner = -1,
962 .svhs = 3,
963 .gpiomask = 0,
964 .muxsel = { 2, 3, 1, 0, 0},
965 .audiomux = {0 },
966 .no_msp34xx = 1,
967 .pll = PLL_28,
968 .tuner_type = -1,
969 .tuner_addr = ADDR_UNSET,
970},{
971 .name = "Zoltrix Genie TV/FM",
972 .video_inputs = 3,
973 .audio_inputs = 1,
974 .tuner = 0,
975 .svhs = 2,
976 .gpiomask = 0xbcf03f,
977 .muxsel = { 2, 3, 1, 1},
978 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
979 .no_msp34xx = 1,
980 .pll = PLL_28,
981 .tuner_type = 21,
982 .tuner_addr = ADDR_UNSET,
983},{
984 .name = "Terratec TV/Radio+",
985 .video_inputs = 3,
986 .audio_inputs = 1,
987 .tuner = 0,
988 .svhs = 2,
989 .gpiomask = 0x70000,
990 .muxsel = { 2, 3, 1, 1},
991 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
992 .needs_tvaudio = 1,
993 .no_msp34xx = 1,
994 .pll = PLL_35,
995 .tuner_type = 1,
996 .tuner_addr = ADDR_UNSET,
997 .has_radio = 1,
998},{
999
1000/* ---- card 0x30 ---------------------------------- */
1001 .name = "Askey CPH03x/ Dynalink Magic TView",
1002 .video_inputs = 3,
1003 .audio_inputs = 1,
1004 .tuner = 0,
1005 .svhs = 2,
1006 .gpiomask = 15,
1007 .muxsel = { 2, 3, 1, 1},
1008 .audiomux = {2,0,0,0,1},
1009 .needs_tvaudio = 1,
1010 .pll = PLL_28,
1011 .tuner_type = -1,
1012 .tuner_addr = ADDR_UNSET,
1013},{
1014 .name = "IODATA GV-BCTV3/PCI",
1015 .video_inputs = 3,
1016 .audio_inputs = 1,
1017 .tuner = 0,
1018 .svhs = 2,
1019 .gpiomask = 0x010f00,
1020 .muxsel = {2, 3, 0, 0},
1021 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1022 .no_msp34xx = 1,
1023 .pll = PLL_28,
1024 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1025 .tuner_addr = ADDR_UNSET,
1026 .audio_hook = gvbctv3pci_audio,
1027},{
1028 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
1029 .video_inputs = 5,
1030 .audio_inputs = 1,
1031 .tuner = 0,
1032 .svhs = 3,
1033 .gpiomask = 0xAA0000,
1034 .muxsel = { 2,3,1,1,-1 },
1035 .digital_mode = DIGITAL_MODE_CAMERA,
1036 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
1037 .no_msp34xx = 1,
1038 .pll = PLL_28,
1039 .tuner_type = TUNER_PHILIPS_PAL_I,
1040 .tuner_addr = ADDR_UNSET,
1041 .has_remote = 1,
1042 /* GPIO wiring: (different from Rev.4C !)
1043 GPIO17: U4.A0 (first hef4052bt)
1044 GPIO19: U4.A1
1045 GPIO20: U5.A1 (second hef4052bt)
1046 GPIO21: U4.nEN
1047 GPIO22: BT832 Reset Line
1048 GPIO23: A5,A0, U5,nEN
1049 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1050 */
1051},{
1052 .name = "Eagle Wireless Capricorn2 (bt878A)",
1053 .video_inputs = 4,
1054 .audio_inputs = 1,
1055 .tuner = 0,
1056 .svhs = 2,
1057 .gpiomask = 7,
1058 .muxsel = { 2, 0, 1, 1},
1059 .audiomux = { 0, 1, 2, 3, 4},
1060 .pll = PLL_28,
1061 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1062 .tuner_addr = ADDR_UNSET,
1063},{
1064
1065/* ---- card 0x34 ---------------------------------- */
1066 /* David Härdeman <david@2gen.com> */
1067 .name = "Pinnacle PCTV Studio Pro",
1068 .video_inputs = 4,
1069 .audio_inputs = 1,
1070 .tuner = 0,
1071 .svhs = 3,
1072 .gpiomask = 0x03000F,
1073 .muxsel = { 2, 3, 1, 1},
1074 .audiomux = { 1, 0xd0001, 0, 0, 10},
1075 /* sound path (5 sources):
1076 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1077 0= ext. Audio IN
1078 1= from MUX2
1079 2= Mono TV sound from Tuner
1080 3= not connected
1081 MUX2 (mask 0x30000):
1082 0,2,3= from MSP34xx
1083 1= FM stereo Radio from Tuner */
1084 .needs_tvaudio = 0,
1085 .pll = PLL_28,
1086 .tuner_type = -1,
1087 .tuner_addr = ADDR_UNSET,
1088},{
1089 /* Claas Langbehn <claas@bigfoot.com>,
1090 Sven Grothklags <sven@upb.de> */
1091 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1092 .video_inputs = 4,
1093 .audio_inputs = 3,
1094 .tuner = 0,
1095 .svhs = 2,
1096 .gpiomask = 0x1c,
1097 .muxsel = { 2, 3, 1, 1},
1098 .audiomux = { 0, 0, 0x10, 8, 4 },
1099 .needs_tvaudio = 1,
1100 .pll = PLL_28,
1101 .tuner_type = TUNER_PHILIPS_PAL,
1102 .tuner_addr = ADDR_UNSET,
1103 .has_radio = 1,
1104},{
1105 /* Tim Röstermundt <rosterm@uni-muenster.de>
1106 in de.comp.os.unix.linux.hardware:
1107 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1108 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1109 options tuner type=5 */
1110 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1111 .video_inputs = 4,
1112 .audio_inputs = 1,
1113 .tuner = 0,
1114 .svhs = 2,
1115 .gpiomask = 0x18e0,
1116 .muxsel = { 2, 3, 1, 1},
1117 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1118 /* For cards with tda9820/tda9821:
1119 0x0000: Tuner normal stereo
1120 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1121 0x0880: Tuner A2 stereo */
1122 .pll = PLL_28,
1123 .tuner_type = -1,
1124 .tuner_addr = ADDR_UNSET,
1125},{
1126 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1127 old Easy TV BT848 version (model CPH031) */
1128 .name = "Askey CPH031/ BESTBUY Easy TV",
1129 .video_inputs = 4,
1130 .audio_inputs = 1,
1131 .tuner = 0,
1132 .svhs = 2,
1133 .gpiomask = 0xF,
1134 .muxsel = { 2, 3, 1, 0},
1135 .audiomux = { 2, 0, 0, 0, 10},
1136 .needs_tvaudio = 0,
1137 .pll = PLL_28,
1138 .tuner_type = TUNER_TEMIC_PAL,
1139 .tuner_addr = ADDR_UNSET,
1140},{
1141
1142/* ---- card 0x38 ---------------------------------- */
1143 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1144 .name = "Lifeview FlyVideo 98FM LR50",
1145 .video_inputs = 4,
1146 .audio_inputs = 3,
1147 .tuner = 0,
1148 .svhs = 2,
1149 .gpiomask = 0x1800,
1150 .muxsel = { 2, 3, 1, 1},
1151 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1152 .pll = PLL_28,
1153 .tuner_type = 5,
1154 .tuner_addr = ADDR_UNSET,
1155},{
1156 /* This is the ultimate cheapo capture card
1157 * just a BT848A on a small PCB!
1158 * Steve Hosgood <steve@equiinet.com> */
1159 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1160 .video_inputs = 2,
1161 .audio_inputs = 0,
1162 .tuner = -1,
1163 .svhs = 1,
1164 .gpiomask = 0,
1165 .muxsel = { 3, 1 },
1166 .audiomux = { 0 },
1167 .needs_tvaudio = 0,
1168 .no_msp34xx = 1,
1169 .pll = PLL_35,
1170 .tuner_type = -1,
1171 .tuner_addr = ADDR_UNSET,
1172},{
1173 /* Daniel Herrington <daniel.herrington@home.com> */
1174 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1175 .video_inputs = 3,
1176 .audio_inputs = 1,
1177 .tuner = 0,
1178 .svhs = 2,
1179 .gpiomask = 0xe00,
1180 .muxsel = { 2, 3, 1, 1},
1181 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1182 .needs_tvaudio = 1,
1183 .pll = PLL_28,
1184 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1185 .tuner_addr = ADDR_UNSET,
1186},{
1187 /* Matti Mottus <mottus@physic.ut.ee> */
1188 .name = "Askey CPH03x TV Capturer",
1189 .video_inputs = 4,
1190 .audio_inputs = 1,
1191 .tuner = 0,
1192 .svhs = 2,
1193 .gpiomask = 0x03000F,
1194 .muxsel = { 2, 3, 1, 0},
1195 .audiomux = { 2,0,0,0,1 },
1196 .pll = PLL_28,
1197 .tuner_type = 0,
1198 .tuner_addr = ADDR_UNSET,
1199},{
1200
1201/* ---- card 0x3c ---------------------------------- */
1202 /* Philip Blundell <philb@gnu.org> */
1203 .name = "Modular Technology MM100PCTV",
1204 .video_inputs = 2,
1205 .audio_inputs = 2,
1206 .tuner = 0,
1207 .svhs = -1,
1208 .gpiomask = 11,
1209 .muxsel = { 2, 3, 1, 1},
1210 .audiomux = { 2, 0, 0, 1, 8},
1211 .pll = PLL_35,
1212 .tuner_type = TUNER_TEMIC_PAL,
1213 .tuner_addr = ADDR_UNSET,
1214},{
1215 /* Adrian Cox <adrian@humboldt.co.uk */
1216 .name = "AG Electronics GMV1",
1217 .video_inputs = 2,
1218 .audio_inputs = 0,
1219 .tuner = -1,
1220 .svhs = 1,
1221 .gpiomask = 0xF,
1222 .muxsel = { 2, 2},
1223 .audiomux = { },
1224 .no_msp34xx = 1,
1225 .needs_tvaudio = 0,
1226 .pll = PLL_28,
1227 .tuner_type = -1,
1228 .tuner_addr = ADDR_UNSET,
1229},{
1230 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1231 new Easy TV BT878 version (model CPH061)
1232 special thanks to Informatica Mieres for providing the card */
1233 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1234 .video_inputs = 3,
1235 .audio_inputs = 2,
1236 .tuner = 0,
1237 .svhs = 2,
1238 .gpiomask = 0xFF,
1239 .muxsel = { 2, 3, 1, 0},
1240 .audiomux = { 1, 0, 4, 4, 9},
1241 .needs_tvaudio = 0,
1242 .pll = PLL_28,
1243 .tuner_type = TUNER_PHILIPS_PAL,
1244 .tuner_addr = ADDR_UNSET,
1245},{
1246 /* Lukas Gebauer <geby@volny.cz> */
1247 .name = "ATI TV-Wonder",
1248 .video_inputs = 3,
1249 .audio_inputs = 1,
1250 .tuner = 0,
1251 .svhs = 2,
1252 .gpiomask = 0xf03f,
1253 .muxsel = { 2, 3, 1, 0 },
1254 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1255 .pll = PLL_28,
1256 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1257 .tuner_addr = ADDR_UNSET,
1258},{
1259
1260/* ---- card 0x40 ---------------------------------- */
1261 /* Lukas Gebauer <geby@volny.cz> */
1262 .name = "ATI TV-Wonder VE",
1263 .video_inputs = 2,
1264 .audio_inputs = 1,
1265 .tuner = 0,
1266 .svhs = -1,
1267 .gpiomask = 1,
1268 .muxsel = { 2, 3, 0, 1},
1269 .audiomux = { 0, 0, 1, 0, 0},
1270 .no_msp34xx = 1,
1271 .pll = PLL_28,
1272 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1273 .tuner_addr = ADDR_UNSET,
1274},{
1275 /* DeeJay <deejay@westel900.net (2000S) */
1276 .name = "Lifeview FlyVideo 2000S LR90",
1277 .video_inputs = 3,
1278 .audio_inputs = 3,
1279 .tuner = 0,
1280 .svhs = 2,
1281 .gpiomask = 0x18e0,
1282 .muxsel = { 2, 3, 0, 1},
1283 /* Radio changed from 1e80 to 0x800 to make
1284 FlyVideo2000S in .hu happy (gm)*/
1285 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
1286 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
1287 .audio_hook = fv2000s_audio,
1288 .no_msp34xx = 1,
1289 .no_tda9875 = 1,
1290 .needs_tvaudio = 1,
1291 .pll = PLL_28,
1292 .tuner_type = 5,
1293 .tuner_addr = ADDR_UNSET,
1294},{
1295 .name = "Terratec TValueRadio",
1296 .video_inputs = 3,
1297 .audio_inputs = 1,
1298 .tuner = 0,
1299 .svhs = 2,
1300 .gpiomask = 0xffff00,
1301 .muxsel = { 2, 3, 1, 1},
1302 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
1303 .needs_tvaudio = 1,
1304 .pll = PLL_28,
1305 .tuner_type = TUNER_PHILIPS_PAL,
1306 .tuner_addr = ADDR_UNSET,
1307 .has_radio = 1,
1308},{
1309 /* TANAKA Kei <peg00625@nifty.com> */
1310 .name = "IODATA GV-BCTV4/PCI",
1311 .video_inputs = 3,
1312 .audio_inputs = 1,
1313 .tuner = 0,
1314 .svhs = 2,
1315 .gpiomask = 0x010f00,
1316 .muxsel = {2, 3, 0, 0},
1317 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1318 .no_msp34xx = 1,
1319 .pll = PLL_28,
1320 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
1321 .tuner_addr = ADDR_UNSET,
1322 .audio_hook = gvbctv3pci_audio,
1323},{
1324
1325/* ---- card 0x44 ---------------------------------- */
1326 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
1327 /* try "insmod msp3400 simple=0" if you have
1328 * sound problems with this card. */
1329 .video_inputs = 4,
1330 .audio_inputs = 1,
1331 .tuner = 0,
1332 .svhs = -1,
1333 .gpiomask = 0x4f8a00,
1334 /* 0x100000: 1=MSP enabled (0=disable again)
1335 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
1336 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
1337 /* tvtuner, radio, external,internal, mute, stereo
1338 * tuner, Composit, SVid, Composit-on-Svid-adapter */
1339 .muxsel = { 2, 3 ,0 ,1},
1340 .tuner_type = TUNER_MT2032,
1341 .tuner_addr = ADDR_UNSET,
1342 .pll = PLL_28,
1343 .has_radio = 1,
1344},{
1345 /* Philip Blundell <pb@nexus.co.uk> */
1346 .name = "Active Imaging AIMMS",
1347 .video_inputs = 1,
1348 .audio_inputs = 0,
1349 .tuner = -1,
1350 .tuner_type = -1,
1351 .tuner_addr = ADDR_UNSET,
1352 .pll = PLL_28,
1353 .muxsel = { 2 },
1354 .gpiomask = 0
1355},{
1356 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
1357 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
1358 .video_inputs = 3,
1359 .audio_inputs = 4,
1360 .tuner = 0,
1361 .svhs = 2,
1362 .gpiomask = 15,
1363 .muxsel = { 2, 3, 1, 1},
1364 .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
1365 .needs_tvaudio = 1,
1366 .pll = PLL_28,
1367 .tuner_type = 25,
1368 .tuner_addr = ADDR_UNSET,
1369 .has_remote = 1,
1370 /* GPIO wiring:
1371 GPIO0: U4.A0 (hef4052bt)
1372 GPIO1: U4.A1
1373 GPIO2: U4.A1 (second hef4052bt)
1374 GPIO3: U4.nEN, U5.A0, A5.nEN
1375 GPIO8-15: vrd866b ?
1376 */ 784 */
1377},{ 785
1378 .name = "Lifeview FlyVideo 98EZ (capture only) LR51", 786 },
1379 .video_inputs = 4, 787 [BTTV_BOARD_PXC200] = {
1380 .audio_inputs = 0, 788 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
1381 .tuner = -1, 789 .name = "Imagenation PXC200",
1382 .svhs = 2, 790 .video_inputs = 5,
1383 .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */ 791 .audio_inputs = 1,
1384 .pll = PLL_28, 792 .tuner = -1,
1385 .no_msp34xx = 1, 793 .svhs = 1, /* was: 4 */
1386 .tuner_type = UNSET, 794 .gpiomask = 0,
1387 .tuner_addr = ADDR_UNSET, 795 .muxsel = { 2, 3, 1, 0, 0},
1388},{ 796 .audiomux = { 0 },
1389 797 .needs_tvaudio = 1,
1390/* ---- card 0x48 ---------------------------------- */ 798 .tuner_type = -1,
1391 /* Dariusz Kowalewski <darekk@automex.pl> */ 799 .tuner_addr = ADDR_UNSET,
1392 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)", 800 .radio_addr = ADDR_UNSET,
1393 .video_inputs = 4, 801 .muxsel_hook = PXC200_muxsel,
1394 .audio_inputs = 1, 802
1395 .tuner = 0, 803 },
1396 .svhs = 2, 804 [BTTV_BOARD_FLYVIDEO_98] = {
1397 .gpiomask = 0x3f, 805 .name = "Lifeview FlyVideo 98 LR50",
1398 .muxsel = { 2, 3, 1, 1 }, 806 .video_inputs = 4,
1399 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 }, 807 .audio_inputs = 1,
1400 .needs_tvaudio = 1, 808 .tuner = 0,
1401 .no_msp34xx = 1, 809 .svhs = 2,
1402 .no_tda9875 = 1, 810 .gpiomask = 0x1800, /* 0x8dfe00 */
1403 .pll = PLL_28, 811 .muxsel = { 2, 3, 1, 1},
1404 .tuner_type = 5, 812 .audiomux = { 0, 0x0800, 0x1000, 0x1000, 0x1800, 0 },
1405 .tuner_addr = ADDR_UNSET, 813 .pll = PLL_28,
1406 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */ 814 .tuner_type = -1,
1407 .has_radio = 1, /* Note: not all cards have radio */ 815 .tuner_addr = ADDR_UNSET,
1408 .has_remote = 1, 816 .radio_addr = ADDR_UNSET,
1409 /* GPIO wiring: 817 },
1410 GPIO0: A0 hef4052 818 [BTTV_BOARD_IPROTV] = {
1411 GPIO1: A1 hef4052 819 .name = "Formac iProTV, Formac ProTV I (bt848)",
1412 GPIO3: nEN hef4052 820 .video_inputs = 4,
1413 GPIO8-15: vrd866b 821 .audio_inputs = 1,
1414 GPIO20,22,23: R30,R29,R28 822 .tuner = 0,
1415 */ 823 .svhs = 3,
1416},{ 824 .gpiomask = 1,
1417 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */ 825 .muxsel = { 2, 3, 1, 1},
1418 /* you must jumper JP5 for the card to work */ 826 .audiomux = { 1, 0, 0, 0, 0 },
1419 .name = "Sensoray 311", 827 .pll = PLL_28,
1420 .video_inputs = 5, 828 .tuner_type = TUNER_PHILIPS_PAL,
1421 .audio_inputs = 0, 829 .tuner_addr = ADDR_UNSET,
1422 .tuner = -1, 830 .radio_addr = ADDR_UNSET,
1423 .svhs = 4, 831 },
1424 .gpiomask = 0, 832
1425 .muxsel = { 2, 3, 1, 0, 0}, 833 /* ---- card 0x20 ---------------------------------- */
1426 .audiomux = { 0 }, 834 [BTTV_BOARD_INTEL_C_S_PCI] = {
1427 .needs_tvaudio = 0, 835 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
1428 .tuner_type = -1, 836 .video_inputs = 4,
1429 .tuner_addr = ADDR_UNSET, 837 .audio_inputs = 0,
1430},{ 838 .tuner = -1,
1431 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */ 839 .svhs = 2,
1432 .name = "RemoteVision MX (RV605)", 840 .gpiomask = 0,
1433 .video_inputs = 16, 841 .muxsel = { 2, 3, 1, 1},
1434 .audio_inputs = 0, 842 .audiomux = { 0 },
1435 .tuner = -1, 843 .needs_tvaudio = 0,
1436 .svhs = -1, 844 .tuner_type = 4,
1437 .gpiomask = 0x00, 845 .tuner_addr = ADDR_UNSET,
1438 .gpiomask2 = 0x07ff, 846 .radio_addr = ADDR_UNSET,
1439 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03, 847 },
1440 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 }, 848 [BTTV_BOARD_TERRATVALUE] = {
1441 .no_msp34xx = 1, 849 .name = "Terratec TerraTValue Version Bt878",
1442 .no_tda9875 = 1, 850 .video_inputs = 3,
1443 .tuner_type = -1, 851 .audio_inputs = 1,
1444 .tuner_addr = ADDR_UNSET, 852 .tuner = 0,
1445 .muxsel_hook = rv605_muxsel, 853 .svhs = 2,
1446},{ 854 .gpiomask = 0xffff00,
1447 .name = "Powercolor MTV878/ MTV878R/ MTV878F", 855 .muxsel = { 2, 3, 1, 1},
1448 .video_inputs = 3, 856 .audiomux = { 0x500, 0, 0x300, 0x900, 0x900},
1449 .audio_inputs = 2, 857 .needs_tvaudio = 1,
1450 .tuner = 0, 858 .pll = PLL_28,
1451 .svhs = 2, 859 .tuner_type = TUNER_PHILIPS_PAL,
1452 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ 860 .tuner_addr = ADDR_UNSET,
1453 .muxsel = { 2, 1, 1, }, 861 .radio_addr = ADDR_UNSET,
1454 .audiomux = { 0, 1, 2, 2, 4 }, 862 },
1455 .needs_tvaudio = 0, 863 [BTTV_BOARD_WINFAST2000] = {
1456 .tuner_type = TUNER_PHILIPS_PAL, 864 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
1457 .tuner_addr = ADDR_UNSET, 865 .video_inputs = 4,
1458 .pll = PLL_28, 866 .audio_inputs = 1,
1459 .has_radio = 1, 867 .tuner = 0,
1460},{ 868 .svhs = 2,
1461 869 .muxsel = { 2, 3, 1, 1, 0}, /* TV, CVid, SVid, CVid over SVid connector */
1462/* ---- card 0x4c ---------------------------------- */ 870 #if 0
1463 /* Masaki Suzuki <masaki@btree.org> */ 871 .gpiomask = 0xc33000,
1464 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)", 872 .audiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 },
1465 .video_inputs = 3, 873 #else
1466 .audio_inputs = 1, 874 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
1467 .tuner = 0, 875 .gpiomask = 0xb33000,
1468 .svhs = 2, 876 .audiomux = { 0x122000,0x1000,0x0000,0x620000,0x800000 },
1469 .gpiomask = 0x140007, 877 #endif
1470 .muxsel = { 2, 3, 1, 1 }, 878 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
1471 .audiomux = { 0, 1, 2, 3, 4, 0 }, 879 gpio23 -- hef4052:nEnable (0x800000)
1472 .tuner_type = TUNER_PHILIPS_NTSC, 880 gpio12 -- hef4052:A1
1473 .tuner_addr = ADDR_UNSET, 881 gpio13 -- hef4052:A0
1474 .audio_hook = windvr_audio, 882 0x0000: external audio
1475},{ 883 0x1000: FM
1476 .name = "GrandTec Multi Capture Card (Bt878)", 884 0x2000: TV
1477 .video_inputs = 4, 885 0x3000: n.c.
1478 .audio_inputs = 0, 886 Note: There exists another variant "Winfast 2000" with tv stereo !?
1479 .tuner = -1, 887 Note: eeprom only contains FF and pci subsystem id 107d:6606
1480 .svhs = -1, 888 */
1481 .gpiomask = 0, 889 .needs_tvaudio = 0,
1482 .muxsel = { 2, 3, 1, 0 }, 890 .pll = PLL_28,
1483 .audiomux = { 0 }, 891 .has_radio = 1,
1484 .needs_tvaudio = 0, 892 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
1485 .no_msp34xx = 1, 893 .tuner_addr = ADDR_UNSET,
1486 .pll = PLL_28, 894 .radio_addr = ADDR_UNSET,
1487 .tuner_type = -1, 895 .audio_hook = winfast2000_audio,
1488 .tuner_addr = ADDR_UNSET, 896 .has_remote = 1,
1489},{ 897 },
1490 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF", 898 [BTTV_BOARD_CHRONOS_VS2] = {
1491 .video_inputs = 4, 899 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
1492 .audio_inputs = 3, 900 .video_inputs = 4,
1493 .tuner = 0, 901 .audio_inputs = 3,
1494 .svhs = 2, 902 .tuner = 0,
1495 .gpiomask = 7, 903 .svhs = 2,
1496 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */ 904 .gpiomask = 0x1800,
1497 .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio! 905 .muxsel = { 2, 3, 1, 1},
1498 * This card lacks external Audio In, so we mute it on Ext. & Int. 906 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800},
1499 * The PCB can take a sbx1637/sbx1673, wiring unknown. 907 .pll = PLL_28,
1500 * This card lacks PCI subsystem ID, sigh. 908 .tuner_type = -1,
1501 * audiomux=1: lower volume, 2+3: mute 909 .tuner_addr = ADDR_UNSET,
1502 * btwincap uses 0x80000/0x80003 910 .radio_addr = ADDR_UNSET,
1503 */ 911 },
1504 .needs_tvaudio = 0, 912
1505 .no_msp34xx = 1, 913 /* ---- card 0x24 ---------------------------------- */
1506 .pll = PLL_28, 914 [BTTV_BOARD_TYPHOON_TVIEW] = {
1507 .tuner_type = 5, 915 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
1508 .tuner_addr = ADDR_UNSET, 916 .video_inputs = 4,
1509 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and 917 .audio_inputs = 3,
1510 radio signal strength indicators work fine. */ 918 .tuner = 0,
1511 .has_radio = 1, 919 .svhs = 2,
1512 /* GPIO Info: 920 .gpiomask = 0x1800,
1513 GPIO0,1: HEF4052 A0,A1 921 .muxsel = { 2, 3, 1, 1},
1514 GPIO2: HEF4052 nENABLE 922 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1515 GPIO3-7: n.c. 923 .pll = PLL_28,
1516 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card] 924 .tuner_type = -1,
1517 GPIO14,15: ?? 925 .tuner_addr = ADDR_UNSET,
1518 GPIO16-21: n.c. 926 .radio_addr = ADDR_UNSET,
1519 GPIO22,23: ?? 927 .has_radio = 1,
1520 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/ 928 },
1521},{ 929 [BTTV_BOARD_PXELVWPLTVPRO] = {
1522 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */ 930 .name = "Prolink PixelView PlayTV pro",
1523 .name = "DSP Design TCVIDEO", 931 .video_inputs = 3,
1524 .video_inputs = 4, 932 .audio_inputs = 1,
1525 .svhs = -1, 933 .tuner = 0,
1526 .muxsel = { 2, 3, 1, 0}, 934 .svhs = 2,
1527 .pll = PLL_28, 935 .gpiomask = 0xff,
1528 .tuner_type = -1, 936 .muxsel = { 2, 3, 1, 1 },
1529 .tuner_addr = ADDR_UNSET, 937 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
1530},{ 938 .no_msp34xx = 1,
1531 939 .pll = PLL_28,
1532 /* ---- card 0x50 ---------------------------------- */ 940 .tuner_type = -1,
1533 .name = "Hauppauge WinTV PVR", 941 .tuner_addr = ADDR_UNSET,
1534 .video_inputs = 4, 942 .radio_addr = ADDR_UNSET,
1535 .audio_inputs = 1, 943 },
1536 .tuner = 0, 944 [BTTV_BOARD_MAGICTVIEW063] = {
1537 .svhs = 2, 945 .name = "Askey CPH06X TView99",
1538 .muxsel = { 2, 0, 1, 1}, 946 .video_inputs = 4,
1539 .needs_tvaudio = 1, 947 .audio_inputs = 1,
1540 .pll = PLL_28, 948 .tuner = 0,
1541 .tuner_type = -1, 949 .svhs = 2,
1542 .tuner_addr = ADDR_UNSET, 950 .gpiomask = 0x551e00,
1543 951 .muxsel = { 2, 3, 1, 0},
1544 .gpiomask = 7, 952 .audiomux = { 0x551400, 0x551200, 0, 0, 0x551c00, 0x551200 },
1545 .audiomux = {7}, 953 .needs_tvaudio = 1,
1546},{ 954 .pll = PLL_28,
1547 .name = "IODATA GV-BCTV5/PCI", 955 .tuner_type = 1,
1548 .video_inputs = 3, 956 .tuner_addr = ADDR_UNSET,
1549 .audio_inputs = 1, 957 .radio_addr = ADDR_UNSET,
1550 .tuner = 0, 958 .has_remote = 1,
1551 .svhs = 2, 959 },
1552 .gpiomask = 0x0f0f80, 960 [BTTV_BOARD_PINNACLE] = {
1553 .muxsel = {2, 3, 1, 0}, 961 .name = "Pinnacle PCTV Studio/Rave",
1554 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0}, 962 .video_inputs = 3,
1555 .no_msp34xx = 1, 963 .audio_inputs = 1,
1556 .pll = PLL_28, 964 .tuner = 0,
1557 .tuner_type = TUNER_PHILIPS_NTSC_M, 965 .svhs = 2,
1558 .tuner_addr = ADDR_UNSET, 966 .gpiomask = 0x03000F,
1559 .audio_hook = gvbctv5pci_audio, 967 .muxsel = { 2, 3, 1, 1},
1560 .has_radio = 1, 968 .audiomux = { 2, 0xd0001, 0, 0, 1},
1561},{ 969 .needs_tvaudio = 0,
1562 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */ 970 .pll = PLL_28,
1563 .video_inputs = 4, /* id-inputs-clock */ 971 .tuner_type = -1,
1564 .audio_inputs = 0, 972 .tuner_addr = ADDR_UNSET,
1565 .tuner = -1, 973 .radio_addr = ADDR_UNSET,
1566 .svhs = 3, 974 },
1567 .muxsel = { 3, 2, 0, 1 }, 975
1568 .pll = PLL_28, 976 /* ---- card 0x28 ---------------------------------- */
1569 .tuner_type = -1, 977 [BTTV_BOARD_STB2] = {
1570 .tuner_addr = ADDR_UNSET, 978 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
1571 .no_msp34xx = 1, 979 .video_inputs = 3,
1572 .no_tda9875 = 1, 980 .audio_inputs = 1,
1573 .no_tda7432 = 1, 981 .tuner = 0,
1574},{ 982 .svhs = 2,
1575 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */ 983 .gpiomask = 7,
1576 .video_inputs = 3, 984 .muxsel = { 2, 3, 1, 1},
1577 .audio_inputs = 0, 985 .audiomux = { 4, 0, 2, 3, 1},
1578 .tuner = -1, 986 .no_msp34xx = 1,
1579 .svhs = 2, 987 .needs_tvaudio = 1,
1580 .muxsel = { 2, 3, 1 }, 988 .tuner_type = TUNER_PHILIPS_NTSC,
1581 .pll = PLL_28, 989 .tuner_addr = ADDR_UNSET,
1582 .tuner_type = -1, 990 .radio_addr = ADDR_UNSET,
1583 .tuner_addr = ADDR_UNSET, 991 .pll = PLL_28,
1584 .no_msp34xx = 1, 992 .has_radio = 1,
1585 .no_tda9875 = 1, 993 },
1586 .no_tda7432 = 1, 994 [BTTV_BOARD_AVPHONE98] = {
1587},{ 995 .name = "AVerMedia TVPhone 98",
1588 996 .video_inputs = 3,
1589 /* ---- card 0x54 ---------------------------------- */ 997 .audio_inputs = 4,
1590 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */ 998 .tuner = 0,
1591 .video_inputs = 2, 999 .svhs = 2,
1592 .audio_inputs = 0, 1000 .gpiomask = 15,
1593 .tuner = -1, 1001 .muxsel = { 2, 3, 1, 1},
1594 .svhs = 1, 1002 .audiomux = { 13, 4, 11, 7, 0, 0},
1595 .muxsel = { 3, 1 }, 1003 .needs_tvaudio = 1,
1596 .pll = PLL_28, 1004 .pll = PLL_28,
1597 .tuner_type = -1, 1005 .tuner_type = -1,
1598 .tuner_addr = ADDR_UNSET, 1006 .tuner_addr = ADDR_UNSET,
1599 .no_msp34xx = 1, 1007 .radio_addr = ADDR_UNSET,
1600 .no_tda9875 = 1, 1008 .has_radio = 1,
1601 .no_tda7432 = 1, 1009 .audio_hook = avermedia_tvphone_audio,
1602},{ 1010 },
1603 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */ 1011 [BTTV_BOARD_PV951] = {
1604 .video_inputs = 1, 1012 .name = "ProVideo PV951", /* pic16c54 */
1605 .audio_inputs = 0, 1013 .video_inputs = 3,
1606 .tuner = -1, 1014 .audio_inputs = 1,
1607 .svhs = -1, 1015 .tuner = 0,
1608 .muxsel = { 0 }, 1016 .svhs = 2,
1609 .pll = PLL_28, 1017 .gpiomask = 0,
1610 .tuner_type = -1, 1018 .muxsel = { 2, 3, 1, 1},
1611 .tuner_addr = ADDR_UNSET, 1019 .audiomux = { 0, 0, 0, 0, 0},
1612 .no_msp34xx = 1, 1020 .needs_tvaudio = 1,
1613 .no_tda9875 = 1, 1021 .no_msp34xx = 1,
1614 .no_tda7432 = 1, 1022 .pll = PLL_28,
1615},{ 1023 .tuner_type = 1,
1616 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */ 1024 .tuner_addr = ADDR_UNSET,
1617 .video_inputs = 2, 1025 .radio_addr = ADDR_UNSET,
1618 .audio_inputs = 0, 1026 },
1619 .tuner = -1, 1027 [BTTV_BOARD_ONAIR_TV] = {
1620 .svhs = 1, 1028 .name = "Little OnAir TV",
1621 .muxsel = { 0, 1 }, 1029 .video_inputs = 3,
1622 .pll = PLL_28, 1030 .audio_inputs = 1,
1623 .tuner_type = -1, 1031 .tuner = 0,
1624 .tuner_addr = ADDR_UNSET, 1032 .svhs = 2,
1625 .no_msp34xx = 1, 1033 .gpiomask = 0xe00b,
1626 .no_tda9875 = 1, 1034 .muxsel = {2, 3, 1, 1},
1627 .no_tda7432 = 1, 1035 .audiomux = {0xff9ff6, 0xff9ff6, 0xff1ff7, 0, 0xff3ffc},
1628},{ 1036 .no_msp34xx = 1,
1629 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */ 1037 .tuner_type = -1,
1630 .video_inputs = 1, 1038 .tuner_addr = ADDR_UNSET,
1631 .audio_inputs = 1, 1039 .radio_addr = ADDR_UNSET,
1632 .tuner = -1, 1040 },
1633 .svhs = -1, 1041
1634 .muxsel = { 0 }, 1042 /* ---- card 0x2c ---------------------------------- */
1635 .pll = PLL_28, 1043 [BTTV_BOARD_SIGMA_TVII_FM] = {
1636 .tuner_type = UNSET, 1044 .name = "Sigma TVII-FM",
1637 .tuner_addr = ADDR_UNSET, 1045 .video_inputs = 2,
1638 .no_msp34xx = 1, 1046 .audio_inputs = 1,
1639 .no_tda9875 = 1, 1047 .tuner = 0,
1640 .no_tda7432 = 1, 1048 .svhs = -1,
1641},{ 1049 .gpiomask = 3,
1642 1050 .muxsel = {2, 3, 1, 1},
1643 /* ---- card 0x58 ---------------------------------- */ 1051 .audiomux = {1, 1, 0, 2, 3},
1644 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */ 1052 .no_msp34xx = 1,
1645 .video_inputs = 2, 1053 .pll = PLL_NONE,
1646 .audio_inputs = 1, 1054 .tuner_type = -1,
1647 .tuner = -1, 1055 .tuner_addr = ADDR_UNSET,
1648 .svhs = 1, 1056 .radio_addr = ADDR_UNSET,
1649 .muxsel = { 0, 1 }, 1057 },
1650 .pll = PLL_28, 1058 [BTTV_BOARD_MATRIX_VISION2] = {
1651 .tuner_type = UNSET, 1059 .name = "MATRIX-Vision MV-Delta 2",
1652 .tuner_addr = ADDR_UNSET, 1060 .video_inputs = 5,
1653 .no_msp34xx = 1, 1061 .audio_inputs = 1,
1654 .no_tda9875 = 1, 1062 .tuner = -1,
1655 .no_tda7432 = 1, 1063 .svhs = 3,
1656},{ 1064 .gpiomask = 0,
1657 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */ 1065 .muxsel = { 2, 3, 1, 0, 0},
1658 .video_inputs = 2, 1066 .audiomux = {0 },
1659 .audio_inputs = 1, 1067 .no_msp34xx = 1,
1660 .tuner = -1, 1068 .pll = PLL_28,
1661 .svhs = 1, 1069 .tuner_type = -1,
1662 .muxsel = { 2, 3 }, 1070 .tuner_addr = ADDR_UNSET,
1663 .pll = PLL_28, 1071 .radio_addr = ADDR_UNSET,
1664 .tuner_type = UNSET, 1072 },
1665 .tuner_addr = ADDR_UNSET, 1073 [BTTV_BOARD_ZOLTRIX_GENIE] = {
1666 .no_msp34xx = 1, 1074 .name = "Zoltrix Genie TV/FM",
1667 .no_tda9875 = 1, 1075 .video_inputs = 3,
1668 .no_tda7432 = 1, 1076 .audio_inputs = 1,
1669},{ 1077 .tuner = 0,
1670 .name = "Osprey 500", /* 500 */ 1078 .svhs = 2,
1671 .video_inputs = 2, 1079 .gpiomask = 0xbcf03f,
1672 .audio_inputs = 1, 1080 .muxsel = { 2, 3, 1, 1},
1673 .tuner = -1, 1081 .audiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0, 0xbcb03f},
1674 .svhs = 1, 1082 .no_msp34xx = 1,
1675 .muxsel = { 2, 3 }, 1083 .pll = PLL_28,
1676 .pll = PLL_28, 1084 .tuner_type = 21,
1677 .tuner_type = -1, 1085 .tuner_addr = ADDR_UNSET,
1678 .tuner_addr = ADDR_UNSET, 1086 .radio_addr = ADDR_UNSET,
1679 .no_msp34xx = 1, 1087 },
1680 .no_tda9875 = 1, 1088 [BTTV_BOARD_TERRATVRADIO] = {
1681 .no_tda7432 = 1, 1089 .name = "Terratec TV/Radio+",
1682},{ 1090 .video_inputs = 3,
1683 .name = "Osprey 540", /* 540 */ 1091 .audio_inputs = 1,
1684 .video_inputs = 4, 1092 .tuner = 0,
1685 .audio_inputs = 1, 1093 .svhs = 2,
1686 .tuner = -1, 1094 .gpiomask = 0x70000,
1687 .pll = PLL_28, 1095 .muxsel = { 2, 3, 1, 1},
1688 .tuner_type = -1, 1096 .audiomux = { 0x20000, 0x30000, 0x10000, 0, 0x40000, 0x20000 },
1689 .tuner_addr = ADDR_UNSET, 1097 .needs_tvaudio = 1,
1690 .no_msp34xx = 1, 1098 .no_msp34xx = 1,
1691 .no_tda9875 = 1, 1099 .pll = PLL_35,
1692 .no_tda7432 = 1, 1100 .tuner_type = 1,
1693},{ 1101 .tuner_addr = ADDR_UNSET,
1694 1102 .radio_addr = ADDR_UNSET,
1695 /* ---- card 0x5C ---------------------------------- */ 1103 .has_radio = 1,
1696 .name = "Osprey 2000", /* 2000 */ 1104 },
1697 .video_inputs = 2, 1105
1698 .audio_inputs = 1, 1106 /* ---- card 0x30 ---------------------------------- */
1699 .tuner = -1, 1107 [BTTV_BOARD_DYNALINK] = {
1700 .svhs = 1, 1108 .name = "Askey CPH03x/ Dynalink Magic TView",
1701 .muxsel = { 2, 3 }, 1109 .video_inputs = 3,
1702 .pll = PLL_28, 1110 .audio_inputs = 1,
1703 .tuner_type = UNSET, 1111 .tuner = 0,
1704 .tuner_addr = ADDR_UNSET, 1112 .svhs = 2,
1705 .no_msp34xx = 1, 1113 .gpiomask = 15,
1706 .no_tda9875 = 1, 1114 .muxsel = { 2, 3, 1, 1},
1707 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ 1115 .audiomux = {2,0,0,0,1},
1708},{ 1116 .needs_tvaudio = 1,
1709 /* M G Berberich <berberic@forwiss.uni-passau.de> */ 1117 .pll = PLL_28,
1710 .name = "IDS Eagle", 1118 .tuner_type = -1,
1711 .video_inputs = 4, 1119 .tuner_addr = ADDR_UNSET,
1712 .audio_inputs = 0, 1120 .radio_addr = ADDR_UNSET,
1713 .tuner = -1, 1121 },
1714 .tuner_type = -1, 1122 [BTTV_BOARD_GVBCTV3PCI] = {
1715 .tuner_addr = ADDR_UNSET, 1123 .name = "IODATA GV-BCTV3/PCI",
1716 .svhs = -1, 1124 .video_inputs = 3,
1717 .gpiomask = 0, 1125 .audio_inputs = 1,
1718 .muxsel = { 0, 1, 2, 3 }, 1126 .tuner = 0,
1719 .muxsel_hook = eagle_muxsel, 1127 .svhs = 2,
1720 .no_msp34xx = 1, 1128 .gpiomask = 0x010f00,
1721 .no_tda9875 = 1, 1129 .muxsel = {2, 3, 0, 0},
1722 .pll = PLL_28, 1130 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
1723},{ 1131 .no_msp34xx = 1,
1724 .name = "Pinnacle PCTV Sat", 1132 .pll = PLL_28,
1725 .video_inputs = 2, 1133 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1726 .audio_inputs = 0, 1134 .tuner_addr = ADDR_UNSET,
1727 .svhs = 1, 1135 .radio_addr = ADDR_UNSET,
1728 .tuner = -1, 1136 .audio_hook = gvbctv3pci_audio,
1729 .tuner_type = -1, 1137 },
1730 .tuner_addr = ADDR_UNSET, 1138 [BTTV_BOARD_PXELVWPLTVPAK] = {
1731 .no_msp34xx = 1, 1139 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
1732 .no_tda9875 = 1, 1140 .video_inputs = 5,
1733 .no_tda7432 = 1, 1141 .audio_inputs = 1,
1734 .gpiomask = 0x01, 1142 .tuner = 0,
1735 .audiomux = { 0, 0, 0, 0, 1 }, 1143 .svhs = 3,
1736 .muxsel = { 3, 0, 1, 2}, 1144 .gpiomask = 0xAA0000,
1737 .needs_tvaudio = 0, 1145 .muxsel = { 2,3,1,1,-1 },
1738 .pll = PLL_28, 1146 .digital_mode = DIGITAL_MODE_CAMERA,
1739 .no_gpioirq = 1, 1147 .audiomux = { 0x20000, 0, 0x80000, 0x80000, 0xa8000, 0x46000 },
1740 .has_dvb = 1, 1148 .no_msp34xx = 1,
1741},{ 1149 .pll = PLL_28,
1742 .name = "Formac ProTV II (bt878)", 1150 .tuner_type = TUNER_PHILIPS_PAL_I,
1743 .video_inputs = 4, 1151 .tuner_addr = ADDR_UNSET,
1744 .audio_inputs = 1, 1152 .radio_addr = ADDR_UNSET,
1745 .tuner = 0, 1153 .has_remote = 1,
1746 .svhs = 3, 1154 /* GPIO wiring: (different from Rev.4C !)
1747 .gpiomask = 2, 1155 GPIO17: U4.A0 (first hef4052bt)
1748 /* TV, Comp1, Composite over SVID con, SVID */ 1156 GPIO19: U4.A1
1749 .muxsel = { 2, 3, 1, 1}, 1157 GPIO20: U5.A1 (second hef4052bt)
1750 .audiomux = { 2, 2, 0, 0, 0 }, 1158 GPIO21: U4.nEN
1751 .pll = PLL_28, 1159 GPIO22: BT832 Reset Line
1752 .has_radio = 1, 1160 GPIO23: A5,A0, U5,nEN
1753 .tuner_type = TUNER_PHILIPS_PAL, 1161 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1754 .tuner_addr = ADDR_UNSET, 1162 */
1755/* sound routing: 1163 },
1756 GPIO=0x00,0x01,0x03: mute (?) 1164 [BTTV_BOARD_EAGLE] = {
1757 0x02: both TV and radio (tuner: FM1216/I) 1165 .name = "Eagle Wireless Capricorn2 (bt878A)",
1758 The card has onboard audio connectors labeled "cdrom" and "board", 1166 .video_inputs = 4,
1759 not soldered here, though unknown wiring. 1167 .audio_inputs = 1,
1760 Card lacks: external audio in, pci subsystem id. 1168 .tuner = 0,
1761*/ 1169 .svhs = 2,
1762},{ 1170 .gpiomask = 7,
1763 1171 .muxsel = { 2, 0, 1, 1},
1764 /* ---- card 0x60 ---------------------------------- */ 1172 .audiomux = { 0, 1, 2, 3, 4},
1765 .name = "MachTV", 1173 .pll = PLL_28,
1766 .video_inputs = 3, 1174 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1767 .audio_inputs = 1, 1175 .tuner_addr = ADDR_UNSET,
1768 .tuner = 0, 1176 .radio_addr = ADDR_UNSET,
1769 .svhs = -1, 1177 },
1770 .gpiomask = 7, 1178
1771 .muxsel = { 2, 3, 1, 1}, 1179 /* ---- card 0x34 ---------------------------------- */
1772 .audiomux = { 0, 1, 2, 3, 4}, 1180 [BTTV_BOARD_PINNACLEPRO] = {
1773 .needs_tvaudio = 1, 1181 /* David Härdeman <david@2gen.com> */
1774 .tuner_type = 5, 1182 .name = "Pinnacle PCTV Studio Pro",
1775 .tuner_addr = ADDR_UNSET, 1183 .video_inputs = 4,
1776 .pll = 1, 1184 .audio_inputs = 1,
1777},{ 1185 .tuner = 0,
1778 .name = "Euresys Picolo", 1186 .svhs = 3,
1779 .video_inputs = 3, 1187 .gpiomask = 0x03000F,
1780 .audio_inputs = 0, 1188 .muxsel = { 2, 3, 1, 1},
1781 .tuner = -1, 1189 .audiomux = { 1, 0xd0001, 0, 0, 10},
1782 .svhs = 2, 1190 /* sound path (5 sources):
1783 .gpiomask = 0, 1191 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1784 .no_msp34xx = 1, 1192 0= ext. Audio IN
1785 .no_tda9875 = 1, 1193 1= from MUX2
1786 .no_tda7432 = 1, 1194 2= Mono TV sound from Tuner
1787 .muxsel = { 2, 0, 1}, 1195 3= not connected
1788 .pll = PLL_28, 1196 MUX2 (mask 0x30000):
1789 .tuner_type = UNSET, 1197 0,2,3= from MSP34xx
1790 .tuner_addr = ADDR_UNSET, 1198 1= FM stereo Radio from Tuner */
1791},{ 1199 .needs_tvaudio = 0,
1792 /* Luc Van Hoeylandt <luc@e-magic.be> */ 1200 .pll = PLL_28,
1793 .name = "ProVideo PV150", /* 0x4f */ 1201 .tuner_type = -1,
1794 .video_inputs = 2, 1202 .tuner_addr = ADDR_UNSET,
1795 .audio_inputs = 0, 1203 .radio_addr = ADDR_UNSET,
1796 .tuner = -1, 1204 },
1797 .svhs = -1, 1205 [BTTV_BOARD_TVIEW_RDS_FM] = {
1798 .gpiomask = 0, 1206 /* Claas Langbehn <claas@bigfoot.com>,
1799 .muxsel = { 2, 3 }, 1207 Sven Grothklags <sven@upb.de> */
1800 .audiomux = { 0 }, 1208 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1801 .needs_tvaudio = 0, 1209 .video_inputs = 4,
1802 .no_msp34xx = 1, 1210 .audio_inputs = 3,
1803 .pll = PLL_28, 1211 .tuner = 0,
1804 .tuner_type = UNSET, 1212 .svhs = 2,
1805 .tuner_addr = ADDR_UNSET, 1213 .gpiomask = 0x1c,
1806},{ 1214 .muxsel = { 2, 3, 1, 1},
1807 /* Hiroshi Takekawa <sian@big.or.jp> */ 1215 .audiomux = { 0, 0, 0x10, 8, 4 },
1808 /* This card lacks subsystem ID */ 1216 .needs_tvaudio = 1,
1809 .name = "AD-TVK503", /* 0x63 */ 1217 .pll = PLL_28,
1810 .video_inputs = 4, 1218 .tuner_type = TUNER_PHILIPS_PAL,
1811 .audio_inputs = 1, 1219 .tuner_addr = ADDR_UNSET,
1812 .tuner = 0, 1220 .radio_addr = ADDR_UNSET,
1813 .svhs = 2, 1221 .has_radio = 1,
1814 .gpiomask = 0x001e8007, 1222 },
1815 .muxsel = { 2, 3, 1, 0 }, 1223 [BTTV_BOARD_LIFETEC_9415] = {
1816 /* Tuner, Radio, external, internal, off, on */ 1224 /* Tim Röstermundt <rosterm@uni-muenster.de>
1817 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 }, 1225 in de.comp.os.unix.linux.hardware:
1818 .needs_tvaudio = 0, 1226 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1819 .no_msp34xx = 1, 1227 audiomux=0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1820 .pll = PLL_28, 1228 options tuner type=5 */
1821 .tuner_type = 2, 1229 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1822 .tuner_addr = ADDR_UNSET, 1230 .video_inputs = 4,
1823 .audio_hook = adtvk503_audio, 1231 .audio_inputs = 1,
1824},{ 1232 .tuner = 0,
1825 1233 .svhs = 2,
1826 /* ---- card 0x64 ---------------------------------- */ 1234 .gpiomask = 0x18e0,
1827 .name = "Hercules Smart TV Stereo", 1235 .muxsel = { 2, 3, 1, 1},
1828 .video_inputs = 4, 1236 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x18e0 },
1829 .audio_inputs = 1, 1237 /* For cards with tda9820/tda9821:
1830 .tuner = 0, 1238 0x0000: Tuner normal stereo
1831 .svhs = 2, 1239 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1832 .gpiomask = 0x00, 1240 0x0880: Tuner A2 stereo */
1833 .muxsel = { 2, 3, 1, 1 }, 1241 .pll = PLL_28,
1834 .needs_tvaudio = 1, 1242 .tuner_type = -1,
1835 .no_msp34xx = 1, 1243 .tuner_addr = ADDR_UNSET,
1836 .pll = PLL_28, 1244 .radio_addr = ADDR_UNSET,
1837 .tuner_type = 5, 1245 },
1838 .tuner_addr = ADDR_UNSET, 1246 [BTTV_BOARD_BESTBUY_EASYTV] = {
1839 /* Notes: 1247 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1840 - card lacks subsystem ID 1248 old Easy TV BT848 version (model CPH031) */
1841 - stereo variant w/ daughter board with tda9874a @0xb0 1249 .name = "Askey CPH031/ BESTBUY Easy TV",
1842 - Audio Routing: 1250 .video_inputs = 4,
1843 always from tda9874 independent of GPIO (?) 1251 .audio_inputs = 1,
1844 external line in: unknown 1252 .tuner = 0,
1845 - Other chips: em78p156elp @ 0x96 (probably IR remote control) 1253 .svhs = 2,
1846 hef4053 (instead 4052) for unknown function 1254 .gpiomask = 0xF,
1847 */ 1255 .muxsel = { 2, 3, 1, 0},
1848},{ 1256 .audiomux = { 2, 0, 0, 0, 10},
1849 .name = "Pace TV & Radio Card", 1257 .needs_tvaudio = 0,
1850 .video_inputs = 4, 1258 .pll = PLL_28,
1851 .audio_inputs = 1, 1259 .tuner_type = TUNER_TEMIC_PAL,
1852 .tuner = 0, 1260 .tuner_addr = ADDR_UNSET,
1853 .svhs = 2, 1261 .radio_addr = ADDR_UNSET,
1854 .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */ 1262 },
1855 .gpiomask = 0, 1263
1856 .no_tda9875 = 1, 1264 /* ---- card 0x38 ---------------------------------- */
1857 .no_tda7432 = 1, 1265 [BTTV_BOARD_FLYVIDEO_98FM] = {
1858 .tuner_type = 1, 1266 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1859 .tuner_addr = ADDR_UNSET, 1267 .name = "Lifeview FlyVideo 98FM LR50",
1860 .has_radio = 1, 1268 .video_inputs = 4,
1861 .pll = PLL_28, 1269 .audio_inputs = 3,
1862 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id 1270 .tuner = 0,
1863 only internal line out: (4pin header) RGGL 1271 .svhs = 2,
1864 Radio must be decoded by msp3410d (not routed through)*/ 1272 .gpiomask = 0x1800,
1865 /* 1273 .muxsel = { 2, 3, 1, 1},
1866 .digital_mode = DIGITAL_MODE_CAMERA, todo! 1274 .audiomux = { 0, 0x800, 0x1000, 0x1000, 0x1800, 0 },
1867 */ 1275 .pll = PLL_28,
1868},{ 1276 .tuner_type = 5,
1869 /* Chris Willing <chris@vislab.usyd.edu.au> */ 1277 .tuner_addr = ADDR_UNSET,
1870 .name = "IVC-200", 1278 .radio_addr = ADDR_UNSET,
1871 .video_inputs = 1, 1279 },
1872 .audio_inputs = 0, 1280 /* This is the ultimate cheapo capture card
1873 .tuner = -1, 1281 * just a BT848A on a small PCB!
1874 .tuner_type = -1, 1282 * Steve Hosgood <steve@equiinet.com> */
1875 .tuner_addr = ADDR_UNSET, 1283 [BTTV_BOARD_GRANDTEC] = {
1876 .svhs = -1, 1284 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1877 .gpiomask = 0xdf, 1285 .video_inputs = 2,
1878 .muxsel = { 2 }, 1286 .audio_inputs = 0,
1879 .pll = PLL_28, 1287 .tuner = -1,
1880},{ 1288 .svhs = 1,
1881 .name = "Grand X-Guard / Trust 814PCI", 1289 .gpiomask = 0,
1882 .video_inputs = 16, 1290 .muxsel = { 3, 1 },
1883 .audio_inputs = 0, 1291 .audiomux = { 0 },
1884 .tuner = -1, 1292 .needs_tvaudio = 0,
1885 .svhs = -1, 1293 .no_msp34xx = 1,
1886 .tuner_type = 4, 1294 .pll = PLL_35,
1887 .tuner_addr = ADDR_UNSET, 1295 .tuner_type = -1,
1888 .gpiomask2 = 0xff, 1296 .tuner_addr = ADDR_UNSET,
1889 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 }, 1297 .radio_addr = ADDR_UNSET,
1890 .muxsel_hook = xguard_muxsel, 1298 },
1891 .no_msp34xx = 1, 1299 [BTTV_BOARD_ASKEY_CPH060] = {
1892 .no_tda9875 = 1, 1300 /* Daniel Herrington <daniel.herrington@home.com> */
1893 .no_tda7432 = 1, 1301 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1894 .pll = PLL_28, 1302 .video_inputs = 3,
1895},{ 1303 .audio_inputs = 1,
1896 1304 .tuner = 0,
1897 /* ---- card 0x68 ---------------------------------- */ 1305 .svhs = 2,
1898 .name = "Nebula Electronics DigiTV", 1306 .gpiomask = 0xe00,
1899 .video_inputs = 1, 1307 .muxsel = { 2, 3, 1, 1},
1900 .tuner = -1, 1308 .audiomux = { 0x400, 0x400, 0x400, 0x400, 0x800, 0x400 },
1901 .svhs = -1, 1309 .needs_tvaudio = 1,
1902 .muxsel = { 2, 3, 1, 0}, 1310 .pll = PLL_28,
1903 .no_msp34xx = 1, 1311 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1904 .no_tda9875 = 1, 1312 .tuner_addr = ADDR_UNSET,
1905 .no_tda7432 = 1, 1313 .radio_addr = ADDR_UNSET,
1906 .pll = PLL_28, 1314 },
1907 .tuner_type = -1, 1315 [BTTV_BOARD_ASKEY_CPH03X] = {
1908 .tuner_addr = ADDR_UNSET, 1316 /* Matti Mottus <mottus@physic.ut.ee> */
1909 .has_dvb = 1, 1317 .name = "Askey CPH03x TV Capturer",
1910 .no_gpioirq = 1, 1318 .video_inputs = 4,
1911},{ 1319 .audio_inputs = 1,
1912 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */ 1320 .tuner = 0,
1913 .name = "ProVideo PV143", 1321 .svhs = 2,
1914 .video_inputs = 4, 1322 .gpiomask = 0x03000F,
1915 .audio_inputs = 0, 1323 .muxsel = { 2, 3, 1, 0},
1916 .tuner = -1, 1324 .audiomux = { 2,0,0,0,1 },
1917 .svhs = -1, 1325 .pll = PLL_28,
1918 .gpiomask = 0, 1326 .tuner_type = 0,
1919 .muxsel = { 2, 3, 1, 0 }, 1327 .tuner_addr = ADDR_UNSET,
1920 .audiomux = { 0 }, 1328 .radio_addr = ADDR_UNSET,
1921 .needs_tvaudio = 0, 1329 },
1922 .no_msp34xx = 1, 1330
1923 .pll = PLL_28, 1331 /* ---- card 0x3c ---------------------------------- */
1924 .tuner_type = -1, 1332 [BTTV_BOARD_MM100PCTV] = {
1925 .tuner_addr = ADDR_UNSET, 1333 /* Philip Blundell <philb@gnu.org> */
1926},{ 1334 .name = "Modular Technology MM100PCTV",
1927 /* M.Klahr@phytec.de */ 1335 .video_inputs = 2,
1928 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)", 1336 .audio_inputs = 2,
1929 .video_inputs = 4, 1337 .tuner = 0,
1930 .audio_inputs = 0, 1338 .svhs = -1,
1931 .tuner = -1, /* card has no tuner */ 1339 .gpiomask = 11,
1932 .svhs = 3, 1340 .muxsel = { 2, 3, 1, 1},
1933 .gpiomask = 0x00, 1341 .audiomux = { 2, 0, 0, 1, 8},
1934 .muxsel = { 2, 3, 1, 0}, 1342 .pll = PLL_35,
1935 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1343 .tuner_type = TUNER_TEMIC_PAL,
1936 .needs_tvaudio = 1, 1344 .tuner_addr = ADDR_UNSET,
1937 .pll = PLL_28, 1345 .radio_addr = ADDR_UNSET,
1938 .tuner_type = -1, 1346 },
1939 .tuner_addr = ADDR_UNSET, 1347 [BTTV_BOARD_GMV1] = {
1940},{ 1348 /* Adrian Cox <adrian@humboldt.co.uk */
1941 .name = "PHYTEC VD-009-X1 Combi (bt878)", 1349 .name = "AG Electronics GMV1",
1942 .video_inputs = 4, 1350 .video_inputs = 2,
1943 .audio_inputs = 0, 1351 .audio_inputs = 0,
1944 .tuner = -1, /* card has no tuner */ 1352 .tuner = -1,
1945 .svhs = 3, 1353 .svhs = 1,
1946 .gpiomask = 0x00, 1354 .gpiomask = 0xF,
1947 .muxsel = { 2, 3, 1, 1}, 1355 .muxsel = { 2, 2},
1948 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1356 .audiomux = { },
1949 .needs_tvaudio = 1, 1357 .no_msp34xx = 1,
1950 .pll = PLL_28, 1358 .needs_tvaudio = 0,
1951 .tuner_type = -1, 1359 .pll = PLL_28,
1952 .tuner_addr = ADDR_UNSET, 1360 .tuner_type = -1,
1953},{ 1361 .tuner_addr = ADDR_UNSET,
1954 1362 .radio_addr = ADDR_UNSET,
1955 /* ---- card 0x6c ---------------------------------- */ 1363 },
1956 .name = "PHYTEC VD-009 MiniDIN (bt878)", 1364 [BTTV_BOARD_BESTBUY_EASYTV2] = {
1957 .video_inputs = 10, 1365 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1958 .audio_inputs = 0, 1366 new Easy TV BT878 version (model CPH061)
1959 .tuner = -1, /* card has no tuner */ 1367 special thanks to Informatica Mieres for providing the card */
1960 .svhs = 9, 1368 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1961 .gpiomask = 0x00, 1369 .video_inputs = 3,
1962 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1370 .audio_inputs = 2,
1963 via the upper nibble of muxsel. here: used for 1371 .tuner = 0,
1964 xternal video-mux */ 1372 .svhs = 2,
1965 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 }, 1373 .gpiomask = 0xFF,
1966 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1374 .muxsel = { 2, 3, 1, 0},
1967 .needs_tvaudio = 1, 1375 .audiomux = { 1, 0, 4, 4, 9},
1968 .pll = PLL_28, 1376 .needs_tvaudio = 0,
1969 .tuner_type = -1, 1377 .pll = PLL_28,
1970 .tuner_addr = ADDR_UNSET, 1378 .tuner_type = TUNER_PHILIPS_PAL,
1971},{ 1379 .tuner_addr = ADDR_UNSET,
1972 .name = "PHYTEC VD-009 Combi (bt878)", 1380 .radio_addr = ADDR_UNSET,
1973 .video_inputs = 10, 1381 },
1974 .audio_inputs = 0, 1382 [BTTV_BOARD_ATI_TVWONDER] = {
1975 .tuner = -1, /* card has no tuner */ 1383 /* Lukas Gebauer <geby@volny.cz> */
1976 .svhs = 9, 1384 .name = "ATI TV-Wonder",
1977 .gpiomask = 0x00, 1385 .video_inputs = 3,
1978 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio 1386 .audio_inputs = 1,
1979 via the upper nibble of muxsel. here: used for 1387 .tuner = 0,
1980 xternal video-mux */ 1388 .svhs = 2,
1981 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 }, 1389 .gpiomask = 0xf03f,
1982 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1390 .muxsel = { 2, 3, 1, 0 },
1983 .needs_tvaudio = 1, 1391 .audiomux = { 0xbffe, 0, 0xbfff, 0, 0xbffe},
1984 .pll = PLL_28, 1392 .pll = PLL_28,
1985 .tuner_type = -1, 1393 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1986 .tuner_addr = ADDR_UNSET, 1394 .tuner_addr = ADDR_UNSET,
1987},{ 1395 .radio_addr = ADDR_UNSET,
1988 .name = "IVC-100", 1396 },
1989 .video_inputs = 4, 1397
1990 .audio_inputs = 0, 1398 /* ---- card 0x40 ---------------------------------- */
1991 .tuner = -1, 1399 [BTTV_BOARD_ATI_TVWONDERVE] = {
1992 .tuner_type = -1, 1400 /* Lukas Gebauer <geby@volny.cz> */
1993 .tuner_addr = ADDR_UNSET, 1401 .name = "ATI TV-Wonder VE",
1994 .svhs = -1, 1402 .video_inputs = 2,
1995 .gpiomask = 0xdf, 1403 .audio_inputs = 1,
1996 .muxsel = { 2, 3, 1, 0 }, 1404 .tuner = 0,
1997 .pll = PLL_28, 1405 .svhs = -1,
1998},{ 1406 .gpiomask = 1,
1999 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */ 1407 .muxsel = { 2, 3, 0, 1},
2000 .name = "IVC-120G", 1408 .audiomux = { 0, 0, 1, 0, 0},
2001 .video_inputs = 16, 1409 .no_msp34xx = 1,
2002 .audio_inputs = 0, /* card has no audio */ 1410 .pll = PLL_28,
2003 .tuner = -1, /* card has no tuner */ 1411 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
2004 .tuner_type = -1, 1412 .tuner_addr = ADDR_UNSET,
2005 .tuner_addr = ADDR_UNSET, 1413 .radio_addr = ADDR_UNSET,
2006 .svhs = -1, /* card has no svhs */ 1414 },
2007 .needs_tvaudio = 0, 1415 [BTTV_BOARD_FLYVIDEO2000] = {
2008 .no_msp34xx = 1, 1416 /* DeeJay <deejay@westel900.net (2000S) */
2009 .no_tda9875 = 1, 1417 .name = "Lifeview FlyVideo 2000S LR90",
2010 .no_tda7432 = 1, 1418 .video_inputs = 3,
2011 .gpiomask = 0x00, 1419 .audio_inputs = 3,
2012 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 1420 .tuner = 0,
2013 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }, 1421 .svhs = 2,
2014 .muxsel_hook = ivc120_muxsel, 1422 .gpiomask = 0x18e0,
2015 .pll = PLL_28, 1423 .muxsel = { 2, 3, 0, 1},
2016},{ 1424 /* Radio changed from 1e80 to 0x800 to make
2017 1425 FlyVideo2000S in .hu happy (gm)*/
2018 /* ---- card 0x70 ---------------------------------- */ 1426 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
2019 .name = "pcHDTV HD-2000 TV", 1427 .audiomux = { 0x0000,0x0800,0x1000,0x1000,0x1800, 0x1080 },
2020 .video_inputs = 4, 1428 .audio_hook = fv2000s_audio,
2021 .audio_inputs = 1, 1429 .no_msp34xx = 1,
2022 .tuner = 0, 1430 .no_tda9875 = 1,
2023 .svhs = 2, 1431 .needs_tvaudio = 1,
2024 .muxsel = { 2, 3, 1, 0}, 1432 .pll = PLL_28,
2025 .tuner_type = TUNER_PHILIPS_ATSC, 1433 .tuner_type = 5,
2026 .tuner_addr = ADDR_UNSET, 1434 .tuner_addr = ADDR_UNSET,
2027 .has_dvb = 1, 1435 .radio_addr = ADDR_UNSET,
2028},{ 1436 },
2029 .name = "Twinhan DST + clones", 1437 [BTTV_BOARD_TERRATVALUER] = {
2030 .no_msp34xx = 1, 1438 .name = "Terratec TValueRadio",
2031 .no_tda9875 = 1, 1439 .video_inputs = 3,
2032 .no_tda7432 = 1, 1440 .audio_inputs = 1,
2033 .tuner_type = TUNER_ABSENT, 1441 .tuner = 0,
2034 .tuner_addr = ADDR_UNSET, 1442 .svhs = 2,
2035 .no_video = 1, 1443 .gpiomask = 0xffff00,
2036 .has_dvb = 1, 1444 .muxsel = { 2, 3, 1, 1},
2037},{ 1445 .audiomux = { 0x500, 0x500, 0x300, 0x900, 0x900},
2038 .name = "Winfast VC100", 1446 .needs_tvaudio = 1,
2039 .video_inputs = 3, 1447 .pll = PLL_28,
2040 .audio_inputs = 0, 1448 .tuner_type = TUNER_PHILIPS_PAL,
2041 .svhs = 1, 1449 .tuner_addr = ADDR_UNSET,
2042 .tuner = -1, 1450 .radio_addr = ADDR_UNSET,
2043 .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */ 1451 .has_radio = 1,
2044 .no_msp34xx = 1, 1452 },
2045 .no_tda9875 = 1, 1453 [BTTV_BOARD_GVBCTV4PCI] = {
2046 .no_tda7432 = 1, 1454 /* TANAKA Kei <peg00625@nifty.com> */
2047 .tuner_type = TUNER_ABSENT, 1455 .name = "IODATA GV-BCTV4/PCI",
2048 .tuner_addr = ADDR_UNSET, 1456 .video_inputs = 3,
2049 .pll = PLL_28, 1457 .audio_inputs = 1,
2050},{ 1458 .tuner = 0,
2051 .name = "Teppro TEV-560/InterVision IV-560", 1459 .svhs = 2,
2052 .video_inputs = 3, 1460 .gpiomask = 0x010f00,
2053 .audio_inputs = 1, 1461 .muxsel = {2, 3, 0, 0},
2054 .tuner = 0, 1462 .audiomux = {0x10000, 0, 0x10000, 0, 0, 0},
2055 .svhs = 2, 1463 .no_msp34xx = 1,
2056 .gpiomask = 3, 1464 .pll = PLL_28,
2057 .muxsel = { 2, 3, 1, 1}, 1465 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
2058 .audiomux = { 1, 1, 1, 1, 0}, 1466 .tuner_addr = ADDR_UNSET,
2059 .needs_tvaudio = 1, 1467 .radio_addr = ADDR_UNSET,
2060 .tuner_type = TUNER_PHILIPS_PAL, 1468 .audio_hook = gvbctv3pci_audio,
2061 .tuner_addr = ADDR_UNSET, 1469 },
2062 .pll = PLL_35, 1470
2063},{ 1471 /* ---- card 0x44 ---------------------------------- */
2064 1472 [BTTV_BOARD_VOODOOTV_FM] = {
2065 /* ---- card 0x74 ---------------------------------- */ 1473 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
2066 .name = "SIMUS GVC1100", 1474 /* try "insmod msp3400 simple=0" if you have
2067 .video_inputs = 4, 1475 * sound problems with this card. */
2068 .audio_inputs = 0, 1476 .video_inputs = 4,
2069 .tuner = -1, 1477 .audio_inputs = 1,
2070 .svhs = -1, 1478 .tuner = 0,
2071 .tuner_type = -1, 1479 .svhs = -1,
2072 .tuner_addr = ADDR_UNSET, 1480 .gpiomask = 0x4f8a00,
2073 .pll = PLL_28, 1481 /* 0x100000: 1=MSP enabled (0=disable again)
2074 .muxsel = { 2, 2, 2, 2}, 1482 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
2075 .gpiomask = 0x3F, 1483 .audiomux = {0x947fff, 0x987fff,0x947fff,0x947fff, 0x947fff},
2076 .muxsel_hook = gvc1100_muxsel, 1484 /* tvtuner, radio, external,internal, mute, stereo
2077},{ 1485 * tuner, Composit, SVid, Composit-on-Svid-adapter */
2078 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */ 1486 .muxsel = { 2, 3 ,0 ,1},
2079 .name = "NGS NGSTV+", 1487 .tuner_type = TUNER_MT2032,
2080 .video_inputs = 3, 1488 .tuner_addr = ADDR_UNSET,
2081 .tuner = 0, 1489 .radio_addr = ADDR_UNSET,
2082 .svhs = 2, 1490 .pll = PLL_28,
2083 .gpiomask = 0x008007, 1491 .has_radio = 1,
2084 .muxsel = {2, 3, 0, 0}, 1492 },
2085 .audiomux = {0, 0, 0, 0, 0x000003, 0}, 1493 [BTTV_BOARD_AIMMS] = {
2086 .pll = PLL_28, 1494 /* Philip Blundell <pb@nexus.co.uk> */
2087 .tuner_type = TUNER_PHILIPS_PAL, 1495 .name = "Active Imaging AIMMS",
2088 .tuner_addr = ADDR_UNSET, 1496 .video_inputs = 1,
2089 .has_remote = 1, 1497 .audio_inputs = 0,
2090},{ 1498 .tuner = -1,
2091 /* http://linuxmedialabs.com */ 1499 .tuner_type = -1,
2092 .name = "LMLBT4", 1500 .tuner_addr = ADDR_UNSET,
2093 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */ 1501 .radio_addr = ADDR_UNSET,
2094 .audio_inputs = 0, 1502 .pll = PLL_28,
2095 .tuner = -1, 1503 .muxsel = { 2 },
2096 .svhs = -1, 1504 .gpiomask = 0
2097 .muxsel = { 2, 3, 1, 0 }, 1505 },
2098 .no_msp34xx = 1, 1506 [BTTV_BOARD_PV_BT878P_PLUS] = {
2099 .no_tda9875 = 1, 1507 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
2100 .no_tda7432 = 1, 1508 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
2101 .needs_tvaudio = 0, 1509 .video_inputs = 3,
2102 .tuner_type = -1, 1510 .audio_inputs = 4,
2103 .tuner_addr = ADDR_UNSET, 1511 .tuner = 0,
2104},{ 1512 .svhs = 2,
2105 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */ 1513 .gpiomask = 15,
2106 .name = "Tekram M205 PRO", 1514 .muxsel = { 2, 3, 1, 1},
2107 .video_inputs = 3, 1515 .audiomux = { 0, 0, 11, 7, 13, 0}, /* TV and Radio with same GPIO ! */
2108 .audio_inputs = 1, 1516 .needs_tvaudio = 1,
2109 .tuner = 0, 1517 .pll = PLL_28,
2110 .tuner_type = TUNER_PHILIPS_PAL, 1518 .tuner_type = 25,
2111 .tuner_addr = ADDR_UNSET, 1519 .tuner_addr = ADDR_UNSET,
2112 .svhs = 2, 1520 .radio_addr = ADDR_UNSET,
2113 .needs_tvaudio = 0, 1521 .has_remote = 1,
2114 .gpiomask = 0x68, 1522 /* GPIO wiring:
2115 .muxsel = { 2, 3, 1}, 1523 GPIO0: U4.A0 (hef4052bt)
2116 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 }, 1524 GPIO1: U4.A1
2117 .pll = PLL_28, 1525 GPIO2: U4.A1 (second hef4052bt)
2118},{ 1526 GPIO3: U4.nEN, U5.A0, A5.nEN
2119 1527 GPIO8-15: vrd866b ?
2120 /* ---- card 0x78 ---------------------------------- */ 1528 */
2121 /* Javier Cendan Ares <jcendan@lycos.es> */ 1529 },
2122 /* bt878 TV + FM without subsystem ID */ 1530 [BTTV_BOARD_FLYVIDEO98EZ] = {
2123 .name = "Conceptronic CONTVFMi", 1531 .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
2124 .video_inputs = 3, 1532 .video_inputs = 4,
2125 .audio_inputs = 1, 1533 .audio_inputs = 0,
2126 .tuner = 0, 1534 .tuner = -1,
2127 .svhs = 2, 1535 .svhs = 2,
2128 .gpiomask = 0x008007, 1536 .muxsel = { 2, 3, 1, 1}, /* AV1, AV2, SVHS, CVid adapter on SVHS */
2129 .muxsel = { 2, 3, 1, 1 }, 1537 .pll = PLL_28,
2130 .audiomux = { 0, 1, 2, 2, 3 }, 1538 .no_msp34xx = 1,
2131 .needs_tvaudio = 0, 1539 .tuner_type = UNSET,
2132 .pll = PLL_28, 1540 .tuner_addr = ADDR_UNSET,
2133 .tuner_type = TUNER_PHILIPS_PAL, 1541 .radio_addr = ADDR_UNSET,
2134 .tuner_addr = ADDR_UNSET, 1542 },
2135 .has_remote = 1, 1543
2136 .has_radio = 1, 1544 /* ---- card 0x48 ---------------------------------- */
2137},{ 1545 [BTTV_BOARD_PV_BT878P_9B] = {
2138 /*Eric DEBIEF <debief@telemsa.com>*/ 1546 /* Dariusz Kowalewski <darekk@automex.pl> */
2139 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/ 1547 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
2140 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_PICOLO_TETRA_CHIP*/ 1548 .video_inputs = 4,
2141 /*0x79 in bttv.h*/ 1549 .audio_inputs = 1,
2142 .name = "Euresys Picolo Tetra", 1550 .tuner = 0,
2143 .video_inputs = 4, 1551 .svhs = 2,
2144 .audio_inputs = 0, 1552 .gpiomask = 0x3f,
2145 .tuner = -1, 1553 .muxsel = { 2, 3, 1, 1 },
2146 .svhs = -1, 1554 .audiomux = { 0x01, 0x00, 0x03, 0x03, 0x09, 0x02 },
2147 .gpiomask = 0, 1555 .needs_tvaudio = 1,
2148 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ 1556 .no_msp34xx = 1,
2149 .no_msp34xx = 1, 1557 .no_tda9875 = 1,
2150 .no_tda9875 = 1, 1558 .pll = PLL_28,
2151 .no_tda7432 = 1, 1559 .tuner_type = 5,
2152 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/ 1560 .tuner_addr = ADDR_UNSET,
2153 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */ 1561 .radio_addr = ADDR_UNSET,
2154 .pll = PLL_28, 1562 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
2155 .needs_tvaudio = 0, 1563 .has_radio = 1, /* Note: not all cards have radio */
2156 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ 1564 .has_remote = 1,
2157 .tuner_type = -1, 1565 /* GPIO wiring:
2158 .tuner_addr = ADDR_UNSET, 1566 GPIO0: A0 hef4052
2159},{ 1567 GPIO1: A1 hef4052
2160 /* Spirit TV Tuner from http://spiritmodems.com.au */ 1568 GPIO3: nEN hef4052
2161 /* Stafford Goodsell <surge@goliath.homeunix.org> */ 1569 GPIO8-15: vrd866b
2162 .name = "Spirit TV Tuner", 1570 GPIO20,22,23: R30,R29,R28
2163 .video_inputs = 3, 1571 */
2164 .audio_inputs = 1, 1572 },
2165 .tuner = 0, 1573 [BTTV_BOARD_SENSORAY311] = {
2166 .svhs = 2, 1574 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
2167 .gpiomask = 0x0000000f, 1575 /* you must jumper JP5 for the card to work */
2168 .muxsel = { 2, 1, 1 }, 1576 .name = "Sensoray 311",
2169 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00}, 1577 .video_inputs = 5,
2170 .tuner_type = TUNER_TEMIC_PAL, 1578 .audio_inputs = 0,
2171 .tuner_addr = ADDR_UNSET, 1579 .tuner = -1,
2172 .no_msp34xx = 1, 1580 .svhs = 4,
2173 .no_tda9875 = 1, 1581 .gpiomask = 0,
2174},{ 1582 .muxsel = { 2, 3, 1, 0, 0},
2175 /* Wolfram Joost <wojo@frokaschwei.de> */ 1583 .audiomux = { 0 },
2176 .name = "AVerMedia AVerTV DVB-T 771", 1584 .needs_tvaudio = 0,
2177 .video_inputs = 2, 1585 .tuner_type = -1,
2178 .svhs = 1, 1586 .tuner_addr = ADDR_UNSET,
2179 .tuner = -1, 1587 .radio_addr = ADDR_UNSET,
2180 .tuner_type = TUNER_ABSENT, 1588 },
2181 .tuner_addr = ADDR_UNSET, 1589 [BTTV_BOARD_RV605] = {
2182 .muxsel = { 3 , 3 }, 1590 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
2183 .no_msp34xx = 1, 1591 .name = "RemoteVision MX (RV605)",
2184 .no_tda9875 = 1, 1592 .video_inputs = 16,
2185 .no_tda7432 = 1, 1593 .audio_inputs = 0,
2186 .pll = PLL_28, 1594 .tuner = -1,
2187 .has_dvb = 1, 1595 .svhs = -1,
2188 .no_gpioirq = 1, 1596 .gpiomask = 0x00,
2189 .has_remote = 1, 1597 .gpiomask2 = 0x07ff,
2190},{ 1598 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
2191 /* ---- card 0x7c ---------------------------------- */ 1599 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
2192 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */ 1600 .no_msp34xx = 1,
2193 /* Based on the Nebula card data - added remote and new card number - BTTV_AVDVBT_761, see also ir-kbd-gpio.c */ 1601 .no_tda9875 = 1,
2194 .name = "AverMedia AverTV DVB-T 761", 1602 .tuner_type = -1,
2195 .video_inputs = 2, 1603 .tuner_addr = ADDR_UNSET,
2196 .tuner = -1, 1604 .radio_addr = ADDR_UNSET,
2197 .svhs = 1, 1605 .muxsel_hook = rv605_muxsel,
2198 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */ 1606 },
2199 .no_msp34xx = 1, 1607 [BTTV_BOARD_POWERCLR_MTV878] = {
2200 .no_tda9875 = 1, 1608 .name = "Powercolor MTV878/ MTV878R/ MTV878F",
2201 .no_tda7432 = 1, 1609 .video_inputs = 3,
2202 .pll = PLL_28, 1610 .audio_inputs = 2,
2203 .tuner_type = -1, 1611 .tuner = 0,
2204 .tuner_addr = ADDR_UNSET, 1612 .svhs = 2,
2205 .has_dvb = 1, 1613 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
2206 .no_gpioirq = 1, 1614 .muxsel = { 2, 1, 1, },
2207 .has_remote = 1, 1615 .audiomux = { 0, 1, 2, 2, 4 },
2208},{ 1616 .needs_tvaudio = 0,
2209 /* andre.schwarz@matrix-vision.de */ 1617 .tuner_type = TUNER_PHILIPS_PAL,
2210 .name = "MATRIX Vision Sigma-SQ", 1618 .tuner_addr = ADDR_UNSET,
2211 .video_inputs = 16, 1619 .radio_addr = ADDR_UNSET,
2212 .audio_inputs = 0, 1620 .pll = PLL_28,
2213 .tuner = -1, 1621 .has_radio = 1,
2214 .svhs = -1, 1622 },
2215 .gpiomask = 0x0, 1623
2216 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 1624 /* ---- card 0x4c ---------------------------------- */
2217 3, 3, 3, 3, 3, 3, 3, 3 }, 1625 [BTTV_BOARD_WINDVR] = {
2218 .muxsel_hook = sigmaSQ_muxsel, 1626 /* Masaki Suzuki <masaki@btree.org> */
2219 .audiomux = { 0 }, 1627 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
2220 .no_msp34xx = 1, 1628 .video_inputs = 3,
2221 .pll = PLL_28, 1629 .audio_inputs = 1,
2222 .tuner_type = -1, 1630 .tuner = 0,
2223 .tuner_addr = ADDR_UNSET, 1631 .svhs = 2,
2224},{ 1632 .gpiomask = 0x140007,
2225 /* andre.schwarz@matrix-vision.de */ 1633 .muxsel = { 2, 3, 1, 1 },
2226 .name = "MATRIX Vision Sigma-SLC", 1634 .audiomux = { 0, 1, 2, 3, 4, 0 },
2227 .video_inputs = 4, 1635 .tuner_type = TUNER_PHILIPS_NTSC,
2228 .audio_inputs = 0, 1636 .tuner_addr = ADDR_UNSET,
2229 .tuner = -1, 1637 .radio_addr = ADDR_UNSET,
2230 .svhs = -1, 1638 .audio_hook = windvr_audio,
2231 .gpiomask = 0x0, 1639 },
2232 .muxsel = { 2, 2, 2, 2 }, 1640 [BTTV_BOARD_GRANDTEC_MULTI] = {
2233 .muxsel_hook = sigmaSLC_muxsel, 1641 .name = "GrandTec Multi Capture Card (Bt878)",
2234 .audiomux = { 0 }, 1642 .video_inputs = 4,
2235 .no_msp34xx = 1, 1643 .audio_inputs = 0,
2236 .pll = PLL_28, 1644 .tuner = -1,
2237 .tuner_type = -1, 1645 .svhs = -1,
2238 .tuner_addr = ADDR_UNSET, 1646 .gpiomask = 0,
2239},{ 1647 .muxsel = { 2, 3, 1, 0 },
2240 /* BTTV_APAC_VIEWCOMP */ 1648 .audiomux = { 0 },
2241 /* Attila Kondoros <attila.kondoros@chello.hu> */ 1649 .needs_tvaudio = 0,
2242 /* bt878 TV + FM 0x00000000 subsystem ID */ 1650 .no_msp34xx = 1,
2243 .name = "APAC Viewcomp 878(AMAX)", 1651 .pll = PLL_28,
2244 .video_inputs = 2, 1652 .tuner_type = -1,
2245 .audio_inputs = 1, 1653 .tuner_addr = ADDR_UNSET,
2246 .tuner = 0, 1654 .radio_addr = ADDR_UNSET,
2247 .svhs = -1, 1655 },
2248 .gpiomask = 0xFF, 1656 [BTTV_BOARD_KWORLD] = {
2249 .muxsel = { 2, 3, 1, 1}, 1657 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
2250 .audiomux = { 2, 0, 0, 0, 10}, 1658 .video_inputs = 4,
2251 .needs_tvaudio = 0, 1659 .audio_inputs = 3,
2252 .pll = PLL_28, 1660 .tuner = 0,
2253 .tuner_type = TUNER_PHILIPS_PAL, 1661 .svhs = 2,
2254 .tuner_addr = ADDR_UNSET, 1662 .gpiomask = 7,
2255 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */ 1663 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
2256 .has_radio = 1, /* not every card has radio */ 1664 .audiomux = { 0 ,0 ,4, 4,4,4},/* Yes, this tuner uses the same audio output for TV and FM radio!
2257},{ 1665 * This card lacks external Audio In, so we mute it on Ext. & Int.
2258 1666 * The PCB can take a sbx1637/sbx1673, wiring unknown.
2259 /* ---- card 0x80 ---------------------------------- */ 1667 * This card lacks PCI subsystem ID, sigh.
2260 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ 1668 * audiomux=1: lower volume, 2+3: mute
2261 .name = "DViCO FusionHDTV DVB-T Lite", 1669 * btwincap uses 0x80000/0x80003
2262 .tuner = -1, 1670 */
2263 .no_msp34xx = 1, 1671 .needs_tvaudio = 0,
2264 .no_tda9875 = 1, 1672 .no_msp34xx = 1,
2265 .no_tda7432 = 1, 1673 .pll = PLL_28,
2266 .pll = PLL_28, 1674 .tuner_type = 5,
2267 .no_video = 1, 1675 .tuner_addr = ADDR_UNSET,
2268 .has_dvb = 1, 1676 .radio_addr = ADDR_UNSET,
2269 .tuner_type = -1, 1677 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
2270 .tuner_addr = ADDR_UNSET, 1678 radio signal strength indicators work fine. */
2271},{ 1679 .has_radio = 1,
2272 /* Steven <photon38@pchome.com.tw> */ 1680 /* GPIO Info:
2273 .name = "V-Gear MyVCD", 1681 GPIO0,1: HEF4052 A0,A1
2274 .video_inputs = 3, 1682 GPIO2: HEF4052 nENABLE
2275 .audio_inputs = 1, 1683 GPIO3-7: n.c.
2276 .tuner = 0, 1684 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
2277 .svhs = 2, 1685 GPIO14,15: ??
2278 .gpiomask = 0x3f, 1686 GPIO16-21: n.c.
2279 .muxsel = {2, 3, 1, 0}, 1687 GPIO22,23: ??
2280 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31}, 1688 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
2281 .no_msp34xx = 1, 1689 },
2282 .pll = PLL_28, 1690 [BTTV_BOARD_DSP_TCVIDEO] = {
2283 .tuner_type = TUNER_PHILIPS_NTSC_M, 1691 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
2284 .tuner_addr = ADDR_UNSET, 1692 .name = "DSP Design TCVIDEO",
2285 .has_radio = 0, 1693 .video_inputs = 4,
2286},{ 1694 .svhs = -1,
2287 /* Rick C <cryptdragoon@gmail.com> */ 1695 .muxsel = { 2, 3, 1, 0},
2288 .name = "Super TV Tuner", 1696 .pll = PLL_28,
2289 .video_inputs = 4, 1697 .tuner_type = -1,
2290 .audio_inputs = 1, 1698 .tuner_addr = ADDR_UNSET,
2291 .tuner = 0, 1699 .radio_addr = ADDR_UNSET,
2292 .svhs = 2, 1700 },
2293 .muxsel = { 2, 3, 1, 0}, 1701
2294 .tuner_type = TUNER_PHILIPS_NTSC, 1702 /* ---- card 0x50 ---------------------------------- */
2295 .tuner_addr = ADDR_UNSET, 1703 [BTTV_BOARD_HAUPPAUGEPVR] = {
2296 .gpiomask = 0x008007, 1704 .name = "Hauppauge WinTV PVR",
2297 .audiomux = { 0, 0x000001,0,0, 0}, 1705 .video_inputs = 4,
2298 .needs_tvaudio = 1, 1706 .audio_inputs = 1,
2299 .has_radio = 1, 1707 .tuner = 0,
2300},{ 1708 .svhs = 2,
2301 /* Chris Fanning <video4linux@haydon.net> */ 1709 .muxsel = { 2, 0, 1, 1},
2302 .name = "Tibet Systems 'Progress DVR' CS16", 1710 .needs_tvaudio = 1,
2303 .video_inputs = 16, 1711 .pll = PLL_28,
2304 .audio_inputs = 0, 1712 .tuner_type = -1,
2305 .tuner = -1, 1713 .tuner_addr = ADDR_UNSET,
2306 .svhs = -1, 1714 .radio_addr = ADDR_UNSET,
2307 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, 1715
2308 .pll = PLL_28, 1716 .gpiomask = 7,
2309 .no_msp34xx = 1, 1717 .audiomux = {7},
2310 .no_tda9875 = 1, 1718 },
2311 .no_tda7432 = 1, 1719 [BTTV_BOARD_GVBCTV5PCI] = {
2312 .tuner_type = -1, 1720 .name = "IODATA GV-BCTV5/PCI",
2313 .tuner_addr = ADDR_UNSET, 1721 .video_inputs = 3,
2314 .muxsel_hook = tibetCS16_muxsel, 1722 .audio_inputs = 1,
2315}, 1723 .tuner = 0,
2316{ 1724 .svhs = 2,
2317 /* Bill Brack <wbrack@mmm.com.hk> */ 1725 .gpiomask = 0x0f0f80,
2318 /* 1726 .muxsel = {2, 3, 1, 0},
2319 * Note that, because of the card's wiring, the "master" 1727 .audiomux = {0x030000, 0x010000, 0, 0, 0x020000, 0},
2320 * BT878A chip (i.e. the one which controls the analog switch 1728 .no_msp34xx = 1,
2321 * and must use this card type) is the 2nd one detected. The 1729 .pll = PLL_28,
2322 * other 3 chips should use card type 0x85, whose description 1730 .tuner_type = TUNER_PHILIPS_NTSC_M,
2323 * follows this one. There is a EEPROM on the card (which is 1731 .tuner_addr = ADDR_UNSET,
2324 * connected to the I2C of one of those other chips), but is 1732 .radio_addr = ADDR_UNSET,
2325 * not currently handled. There is also a facility for a 1733 .audio_hook = gvbctv5pci_audio,
2326 * "monitor", which is also not currently implemented. 1734 .has_radio = 1,
2327 */ 1735 },
2328 .name = "Kodicom 4400R (master)", 1736 [BTTV_BOARD_OSPREY1x0] = {
2329 .video_inputs = 16, 1737 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
2330 .audio_inputs = 0, 1738 .video_inputs = 4, /* id-inputs-clock */
2331 .tuner = -1, 1739 .audio_inputs = 0,
2332 .tuner_type = -1, 1740 .tuner = -1,
2333 .tuner_addr = ADDR_UNSET, 1741 .svhs = 3,
2334 .svhs = -1, 1742 .muxsel = { 3, 2, 0, 1 },
2335 /* GPIO bits 0-9 used for analog switch: 1743 .pll = PLL_28,
2336 * 00 - 03: camera selector 1744 .tuner_type = -1,
2337 * 04 - 06: channel (controller) selector 1745 .tuner_addr = ADDR_UNSET,
2338 * 07: data (1->on, 0->off) 1746 .radio_addr = ADDR_UNSET,
2339 * 08: strobe 1747 .no_msp34xx = 1,
2340 * 09: reset 1748 .no_tda9875 = 1,
2341 * bit 16 is input from sync separator for the channel 1749 .no_tda7432 = 1,
2342 */ 1750 },
2343 .gpiomask = 0x0003ff, 1751 [BTTV_BOARD_OSPREY1x0_848] = {
2344 .no_gpioirq = 1, 1752 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
2345 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 1753 .video_inputs = 3,
2346 .pll = PLL_28, 1754 .audio_inputs = 0,
2347 .no_msp34xx = 1, 1755 .tuner = -1,
2348 .no_tda7432 = 1, 1756 .svhs = 2,
2349 .no_tda9875 = 1, 1757 .muxsel = { 2, 3, 1 },
2350 .muxsel_hook = kodicom4400r_muxsel, 1758 .pll = PLL_28,
2351}, 1759 .tuner_type = -1,
2352{ 1760 .tuner_addr = ADDR_UNSET,
2353 /* Bill Brack <wbrack@mmm.com.hk> */ 1761 .radio_addr = ADDR_UNSET,
2354 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the 1762 .no_msp34xx = 1,
2355 * one which controls the analog switch, and must use the card type) 1763 .no_tda9875 = 1,
2356 * is the 2nd one detected. The other 3 chips should use this card 1764 .no_tda7432 = 1,
2357 * type 1765 },
1766
1767 /* ---- card 0x54 ---------------------------------- */
1768 [BTTV_BOARD_OSPREY101_848] = {
1769 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
1770 .video_inputs = 2,
1771 .audio_inputs = 0,
1772 .tuner = -1,
1773 .svhs = 1,
1774 .muxsel = { 3, 1 },
1775 .pll = PLL_28,
1776 .tuner_type = -1,
1777 .tuner_addr = ADDR_UNSET,
1778 .radio_addr = ADDR_UNSET,
1779 .no_msp34xx = 1,
1780 .no_tda9875 = 1,
1781 .no_tda7432 = 1,
1782 },
1783 [BTTV_BOARD_OSPREY1x1] = {
1784 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
1785 .video_inputs = 1,
1786 .audio_inputs = 0,
1787 .tuner = -1,
1788 .svhs = -1,
1789 .muxsel = { 0 },
1790 .pll = PLL_28,
1791 .tuner_type = -1,
1792 .tuner_addr = ADDR_UNSET,
1793 .radio_addr = ADDR_UNSET,
1794 .no_msp34xx = 1,
1795 .no_tda9875 = 1,
1796 .no_tda7432 = 1,
1797 },
1798 [BTTV_BOARD_OSPREY1x1_SVID] = {
1799 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
1800 .video_inputs = 2,
1801 .audio_inputs = 0,
1802 .tuner = -1,
1803 .svhs = 1,
1804 .muxsel = { 0, 1 },
1805 .pll = PLL_28,
1806 .tuner_type = -1,
1807 .tuner_addr = ADDR_UNSET,
1808 .radio_addr = ADDR_UNSET,
1809 .no_msp34xx = 1,
1810 .no_tda9875 = 1,
1811 .no_tda7432 = 1,
1812 },
1813 [BTTV_BOARD_OSPREY2xx] = {
1814 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
1815 .video_inputs = 1,
1816 .audio_inputs = 1,
1817 .tuner = -1,
1818 .svhs = -1,
1819 .muxsel = { 0 },
1820 .pll = PLL_28,
1821 .tuner_type = UNSET,
1822 .tuner_addr = ADDR_UNSET,
1823 .radio_addr = ADDR_UNSET,
1824 .no_msp34xx = 1,
1825 .no_tda9875 = 1,
1826 .no_tda7432 = 1,
1827 },
1828
1829 /* ---- card 0x58 ---------------------------------- */
1830 [BTTV_BOARD_OSPREY2x0_SVID] = {
1831 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
1832 .video_inputs = 2,
1833 .audio_inputs = 1,
1834 .tuner = -1,
1835 .svhs = 1,
1836 .muxsel = { 0, 1 },
1837 .pll = PLL_28,
1838 .tuner_type = UNSET,
1839 .tuner_addr = ADDR_UNSET,
1840 .radio_addr = ADDR_UNSET,
1841 .no_msp34xx = 1,
1842 .no_tda9875 = 1,
1843 .no_tda7432 = 1,
1844 },
1845 [BTTV_BOARD_OSPREY2x0] = {
1846 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
1847 .video_inputs = 2,
1848 .audio_inputs = 1,
1849 .tuner = -1,
1850 .svhs = 1,
1851 .muxsel = { 2, 3 },
1852 .pll = PLL_28,
1853 .tuner_type = UNSET,
1854 .tuner_addr = ADDR_UNSET,
1855 .radio_addr = ADDR_UNSET,
1856 .no_msp34xx = 1,
1857 .no_tda9875 = 1,
1858 .no_tda7432 = 1,
1859 },
1860 [BTTV_BOARD_OSPREY500] = {
1861 .name = "Osprey 500", /* 500 */
1862 .video_inputs = 2,
1863 .audio_inputs = 1,
1864 .tuner = -1,
1865 .svhs = 1,
1866 .muxsel = { 2, 3 },
1867 .pll = PLL_28,
1868 .tuner_type = -1,
1869 .tuner_addr = ADDR_UNSET,
1870 .radio_addr = ADDR_UNSET,
1871 .no_msp34xx = 1,
1872 .no_tda9875 = 1,
1873 .no_tda7432 = 1,
1874 },
1875 [BTTV_BOARD_OSPREY540] = {
1876 .name = "Osprey 540", /* 540 */
1877 .video_inputs = 4,
1878 .audio_inputs = 1,
1879 .tuner = -1,
1880 #if 0 /* TODO ... */
1881 .svhs = OSPREY540_SVID_ANALOG,
1882 .muxsel = { [OSPREY540_COMP_ANALOG] = 2,
1883 [OSPREY540_SVID_ANALOG] = 3, },
1884 #endif
1885 .pll = PLL_28,
1886 .tuner_type = -1,
1887 .tuner_addr = ADDR_UNSET,
1888 .radio_addr = ADDR_UNSET,
1889 .no_msp34xx = 1,
1890 .no_tda9875 = 1,
1891 .no_tda7432 = 1,
1892 #if 0 /* TODO ... */
1893 .muxsel_hook = osprey_540_muxsel,
1894 .picture_hook = osprey_540_set_picture,
1895 #endif
1896 },
1897
1898 /* ---- card 0x5C ---------------------------------- */
1899 [BTTV_BOARD_OSPREY2000] = {
1900 .name = "Osprey 2000", /* 2000 */
1901 .video_inputs = 2,
1902 .audio_inputs = 1,
1903 .tuner = -1,
1904 .svhs = 1,
1905 .muxsel = { 2, 3 },
1906 .pll = PLL_28,
1907 .tuner_type = UNSET,
1908 .tuner_addr = ADDR_UNSET,
1909 .radio_addr = ADDR_UNSET,
1910 .no_msp34xx = 1,
1911 .no_tda9875 = 1,
1912 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
1913 },
1914 [BTTV_BOARD_IDS_EAGLE] = {
1915 /* M G Berberich <berberic@forwiss.uni-passau.de> */
1916 .name = "IDS Eagle",
1917 .video_inputs = 4,
1918 .audio_inputs = 0,
1919 .tuner = -1,
1920 .tuner_type = -1,
1921 .tuner_addr = ADDR_UNSET,
1922 .radio_addr = ADDR_UNSET,
1923 .svhs = -1,
1924 .gpiomask = 0,
1925 .muxsel = { 0, 1, 2, 3 },
1926 .muxsel_hook = eagle_muxsel,
1927 .no_msp34xx = 1,
1928 .no_tda9875 = 1,
1929 .pll = PLL_28,
1930 },
1931 [BTTV_BOARD_PINNACLESAT] = {
1932 .name = "Pinnacle PCTV Sat",
1933 .video_inputs = 2,
1934 .audio_inputs = 0,
1935 .svhs = 1,
1936 .tuner = -1,
1937 .tuner_type = -1,
1938 .tuner_addr = ADDR_UNSET,
1939 .radio_addr = ADDR_UNSET,
1940 .no_msp34xx = 1,
1941 .no_tda9875 = 1,
1942 .no_tda7432 = 1,
1943 .muxsel = { 3, 0, 1, 2},
1944 .pll = PLL_28,
1945 .no_gpioirq = 1,
1946 .has_dvb = 1,
1947 },
1948 [BTTV_BOARD_FORMAC_PROTV] = {
1949 .name = "Formac ProTV II (bt878)",
1950 .video_inputs = 4,
1951 .audio_inputs = 1,
1952 .tuner = 0,
1953 .svhs = 3,
1954 .gpiomask = 2,
1955 /* TV, Comp1, Composite over SVID con, SVID */
1956 .muxsel = { 2, 3, 1, 1},
1957 .audiomux = { 2, 2, 0, 0, 0 },
1958 .pll = PLL_28,
1959 .has_radio = 1,
1960 .tuner_type = TUNER_PHILIPS_PAL,
1961 .tuner_addr = ADDR_UNSET,
1962 .radio_addr = ADDR_UNSET,
1963 /* sound routing:
1964 GPIO=0x00,0x01,0x03: mute (?)
1965 0x02: both TV and radio (tuner: FM1216/I)
1966 The card has onboard audio connectors labeled "cdrom" and "board",
1967 not soldered here, though unknown wiring.
1968 Card lacks: external audio in, pci subsystem id.
2358 */ 1969 */
2359 .name = "Kodicom 4400R (slave)", 1970 },
2360 .video_inputs = 16, 1971
2361 .audio_inputs = 0, 1972 /* ---- card 0x60 ---------------------------------- */
2362 .tuner = -1, 1973 [BTTV_BOARD_MACHTV] = {
2363 .tuner_type = -1, 1974 .name = "MachTV",
2364 .tuner_addr = ADDR_UNSET, 1975 .video_inputs = 3,
2365 .svhs = -1, 1976 .audio_inputs = 1,
2366 .gpiomask = 0x010000, 1977 .tuner = 0,
2367 .no_gpioirq = 1, 1978 .svhs = -1,
2368 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, 1979 .gpiomask = 7,
2369 .pll = PLL_28, 1980 .muxsel = { 2, 3, 1, 1},
2370 .no_msp34xx = 1, 1981 .audiomux = { 0, 1, 2, 3, 4},
2371 .no_tda7432 = 1, 1982 .needs_tvaudio = 1,
2372 .no_tda9875 = 1, 1983 .tuner_type = 5,
2373 .muxsel_hook = kodicom4400r_muxsel, 1984 .tuner_addr = ADDR_UNSET,
2374}, 1985 .radio_addr = ADDR_UNSET,
2375{ 1986 .pll = PLL_28,
2376 /* ---- card 0x86---------------------------------- */ 1987 },
2377 /* Michael Henson <mhenson@clarityvi.com> */ 1988 [BTTV_BOARD_EURESYS_PICOLO] = {
2378 /* Adlink RTV24 with special unlock codes */ 1989 .name = "Euresys Picolo",
2379 .name = "Adlink RTV24", 1990 .video_inputs = 3,
2380 .video_inputs = 4, 1991 .audio_inputs = 0,
2381 .audio_inputs = 1, 1992 .tuner = -1,
2382 .tuner = 0, 1993 .svhs = 2,
2383 .svhs = 2, 1994 .gpiomask = 0,
2384 .muxsel = { 2, 3, 1, 0}, 1995 .no_msp34xx = 1,
2385 .tuner_type = -1, 1996 .no_tda9875 = 1,
2386 .tuner_addr = ADDR_UNSET, 1997 .no_tda7432 = 1,
2387 .pll = PLL_28, 1998 .muxsel = { 2, 0, 1},
2388}, 1999 .pll = PLL_28,
2389{ 2000 .tuner_type = UNSET,
2390 /* ---- card 0x87---------------------------------- */ 2001 .tuner_addr = ADDR_UNSET,
2391 /* Michael Krufky <mkrufky@m1k.net> */ 2002 .radio_addr = ADDR_UNSET,
2392 .name = "DViCO FusionHDTV 5 Lite", 2003 },
2393 .tuner = 0, 2004 [BTTV_BOARD_PV150] = {
2394 .tuner_type = TUNER_LG_TDVS_H062F, 2005 /* Luc Van Hoeylandt <luc@e-magic.be> */
2395 .tuner_addr = ADDR_UNSET, 2006 .name = "ProVideo PV150", /* 0x4f */
2396 .video_inputs = 3, 2007 .video_inputs = 2,
2397 .audio_inputs = 1, 2008 .audio_inputs = 0,
2398 .svhs = 2, 2009 .tuner = -1,
2399 .muxsel = { 2, 3, 1 }, 2010 .svhs = -1,
2400 .gpiomask = 0x00e00007, 2011 .gpiomask = 0,
2401 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 }, 2012 .muxsel = { 2, 3 },
2402 .no_msp34xx = 1, 2013 .audiomux = { 0 },
2403 .no_tda9875 = 1, 2014 .needs_tvaudio = 0,
2404 .no_tda7432 = 1, 2015 .no_msp34xx = 1,
2405},{ 2016 .pll = PLL_28,
2406 /* ---- card 0x88---------------------------------- */ 2017 .tuner_type = UNSET,
2407 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */ 2018 .tuner_addr = ADDR_UNSET,
2408 .name = "Acorp Y878F", 2019 .radio_addr = ADDR_UNSET,
2409 .video_inputs = 3, 2020 },
2410 .audio_inputs = 1, 2021 [BTTV_BOARD_AD_TVK503] = {
2411 .tuner = 0, 2022 /* Hiroshi Takekawa <sian@big.or.jp> */
2412 .svhs = 2, 2023 /* This card lacks subsystem ID */
2413 .gpiomask = 0x01fe00, 2024 .name = "AD-TVK503", /* 0x63 */
2414 .muxsel = { 2, 3, 1, 1}, 2025 .video_inputs = 4,
2415 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 }, 2026 .audio_inputs = 1,
2416 .needs_tvaudio = 1, 2027 .tuner = 0,
2417 .pll = PLL_28, 2028 .svhs = 2,
2418 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, 2029 .gpiomask = 0x001e8007,
2419 .tuner_addr = 0xc1 >>1, 2030 .muxsel = { 2, 3, 1, 0 },
2420 .has_radio = 1, 2031 /* Tuner, Radio, external, internal, off, on */
2421}}; 2032 .audiomux = { 0x08, 0x0f, 0x0a, 0x08, 0x0f, 0x08 },
2033 .needs_tvaudio = 0,
2034 .no_msp34xx = 1,
2035 .pll = PLL_28,
2036 .tuner_type = 2,
2037 .tuner_addr = ADDR_UNSET,
2038 .radio_addr = ADDR_UNSET,
2039 .audio_hook = adtvk503_audio,
2040 },
2041
2042 /* ---- card 0x64 ---------------------------------- */
2043 [BTTV_BOARD_HERCULES_SM_TV] = {
2044 .name = "Hercules Smart TV Stereo",
2045 .video_inputs = 4,
2046 .audio_inputs = 1,
2047 .tuner = 0,
2048 .svhs = 2,
2049 .gpiomask = 0x00,
2050 .muxsel = { 2, 3, 1, 1 },
2051 .needs_tvaudio = 1,
2052 .no_msp34xx = 1,
2053 .pll = PLL_28,
2054 .tuner_type = 5,
2055 .tuner_addr = ADDR_UNSET,
2056 .radio_addr = ADDR_UNSET,
2057 /* Notes:
2058 - card lacks subsystem ID
2059 - stereo variant w/ daughter board with tda9874a @0xb0
2060 - Audio Routing:
2061 always from tda9874 independent of GPIO (?)
2062 external line in: unknown
2063 - Other chips: em78p156elp @ 0x96 (probably IR remote control)
2064 hef4053 (instead 4052) for unknown function
2065 */
2066 },
2067 [BTTV_BOARD_PACETV] = {
2068 .name = "Pace TV & Radio Card",
2069 .video_inputs = 4,
2070 .audio_inputs = 1,
2071 .tuner = 0,
2072 .svhs = 2,
2073 .muxsel = { 2, 3, 1, 1}, /* Tuner, CVid, SVid, CVid over SVid connector */
2074 .gpiomask = 0,
2075 .no_tda9875 = 1,
2076 .no_tda7432 = 1,
2077 .tuner_type = 1,
2078 .tuner_addr = ADDR_UNSET,
2079 .radio_addr = ADDR_UNSET,
2080 .has_radio = 1,
2081 .pll = PLL_28,
2082 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
2083 only internal line out: (4pin header) RGGL
2084 Radio must be decoded by msp3410d (not routed through)*/
2085 /*
2086 .digital_mode = DIGITAL_MODE_CAMERA, todo!
2087 */
2088 },
2089 [BTTV_BOARD_IVC200] = {
2090 /* Chris Willing <chris@vislab.usyd.edu.au> */
2091 .name = "IVC-200",
2092 .video_inputs = 1,
2093 .audio_inputs = 0,
2094 .tuner = -1,
2095 .tuner_type = -1,
2096 .tuner_addr = ADDR_UNSET,
2097 .radio_addr = ADDR_UNSET,
2098 .svhs = -1,
2099 .gpiomask = 0xdf,
2100 .muxsel = { 2 },
2101 .pll = PLL_28,
2102 },
2103 [BTTV_BOARD_XGUARD] = {
2104 .name = "Grand X-Guard / Trust 814PCI",
2105 .video_inputs = 16,
2106 .audio_inputs = 0,
2107 .tuner = -1,
2108 .svhs = -1,
2109 .tuner_type = 4,
2110 .tuner_addr = ADDR_UNSET,
2111 .radio_addr = ADDR_UNSET,
2112 .gpiomask2 = 0xff,
2113 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
2114 .muxsel_hook = xguard_muxsel,
2115 .no_msp34xx = 1,
2116 .no_tda9875 = 1,
2117 .no_tda7432 = 1,
2118 .pll = PLL_28,
2119 },
2120
2121 /* ---- card 0x68 ---------------------------------- */
2122 [BTTV_BOARD_NEBULA_DIGITV] = {
2123 .name = "Nebula Electronics DigiTV",
2124 .video_inputs = 1,
2125 .tuner = -1,
2126 .svhs = -1,
2127 .muxsel = { 2, 3, 1, 0},
2128 .no_msp34xx = 1,
2129 .no_tda9875 = 1,
2130 .no_tda7432 = 1,
2131 .pll = PLL_28,
2132 .tuner_type = -1,
2133 .tuner_addr = ADDR_UNSET,
2134 .radio_addr = ADDR_UNSET,
2135 .has_dvb = 1,
2136 .no_gpioirq = 1,
2137 },
2138 [BTTV_BOARD_PV143] = {
2139 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
2140 .name = "ProVideo PV143",
2141 .video_inputs = 4,
2142 .audio_inputs = 0,
2143 .tuner = -1,
2144 .svhs = -1,
2145 .gpiomask = 0,
2146 .muxsel = { 2, 3, 1, 0 },
2147 .audiomux = { 0 },
2148 .needs_tvaudio = 0,
2149 .no_msp34xx = 1,
2150 .pll = PLL_28,
2151 .tuner_type = -1,
2152 .tuner_addr = ADDR_UNSET,
2153 .radio_addr = ADDR_UNSET,
2154 },
2155 [BTTV_BOARD_VD009X1_MINIDIN] = {
2156 /* M.Klahr@phytec.de */
2157 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
2158 .video_inputs = 4,
2159 .audio_inputs = 0,
2160 .tuner = -1, /* card has no tuner */
2161 .svhs = 3,
2162 .gpiomask = 0x00,
2163 .muxsel = { 2, 3, 1, 0},
2164 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2165 .needs_tvaudio = 1,
2166 .pll = PLL_28,
2167 .tuner_type = -1,
2168 .tuner_addr = ADDR_UNSET,
2169 .radio_addr = ADDR_UNSET,
2170 },
2171 [BTTV_BOARD_VD009X1_COMBI] = {
2172 .name = "PHYTEC VD-009-X1 Combi (bt878)",
2173 .video_inputs = 4,
2174 .audio_inputs = 0,
2175 .tuner = -1, /* card has no tuner */
2176 .svhs = 3,
2177 .gpiomask = 0x00,
2178 .muxsel = { 2, 3, 1, 1},
2179 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2180 .needs_tvaudio = 1,
2181 .pll = PLL_28,
2182 .tuner_type = -1,
2183 .tuner_addr = ADDR_UNSET,
2184 .radio_addr = ADDR_UNSET,
2185 },
2186
2187 /* ---- card 0x6c ---------------------------------- */
2188 [BTTV_BOARD_VD009_MINIDIN] = {
2189 .name = "PHYTEC VD-009 MiniDIN (bt878)",
2190 .video_inputs = 10,
2191 .audio_inputs = 0,
2192 .tuner = -1, /* card has no tuner */
2193 .svhs = 9,
2194 .gpiomask = 0x00,
2195 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2196 via the upper nibble of muxsel. here: used for
2197 xternal video-mux */
2198 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
2199 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2200 .needs_tvaudio = 1,
2201 .pll = PLL_28,
2202 .tuner_type = -1,
2203 .tuner_addr = ADDR_UNSET,
2204 .radio_addr = ADDR_UNSET,
2205 },
2206 [BTTV_BOARD_VD009_COMBI] = {
2207 .name = "PHYTEC VD-009 Combi (bt878)",
2208 .video_inputs = 10,
2209 .audio_inputs = 0,
2210 .tuner = -1, /* card has no tuner */
2211 .svhs = 9,
2212 .gpiomask = 0x00,
2213 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2214 via the upper nibble of muxsel. here: used for
2215 xternal video-mux */
2216 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
2217 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2218 .needs_tvaudio = 1,
2219 .pll = PLL_28,
2220 .tuner_type = -1,
2221 .tuner_addr = ADDR_UNSET,
2222 .radio_addr = ADDR_UNSET,
2223 },
2224 [BTTV_BOARD_IVC100] = {
2225 .name = "IVC-100",
2226 .video_inputs = 4,
2227 .audio_inputs = 0,
2228 .tuner = -1,
2229 .tuner_type = -1,
2230 .tuner_addr = ADDR_UNSET,
2231 .radio_addr = ADDR_UNSET,
2232 .svhs = -1,
2233 .gpiomask = 0xdf,
2234 .muxsel = { 2, 3, 1, 0 },
2235 .pll = PLL_28,
2236 },
2237 [BTTV_BOARD_IVC120] = {
2238 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
2239 .name = "IVC-120G",
2240 .video_inputs = 16,
2241 .audio_inputs = 0, /* card has no audio */
2242 .tuner = -1, /* card has no tuner */
2243 .tuner_type = -1,
2244 .tuner_addr = ADDR_UNSET,
2245 .radio_addr = ADDR_UNSET,
2246 .svhs = -1, /* card has no svhs */
2247 .needs_tvaudio = 0,
2248 .no_msp34xx = 1,
2249 .no_tda9875 = 1,
2250 .no_tda7432 = 1,
2251 .gpiomask = 0x00,
2252 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
2253 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
2254 .muxsel_hook = ivc120_muxsel,
2255 .pll = PLL_28,
2256 },
2257
2258 /* ---- card 0x70 ---------------------------------- */
2259 [BTTV_BOARD_PC_HDTV] = {
2260 .name = "pcHDTV HD-2000 TV",
2261 .video_inputs = 4,
2262 .audio_inputs = 1,
2263 .tuner = 0,
2264 .svhs = 2,
2265 .muxsel = { 2, 3, 1, 0},
2266 .tuner_type = TUNER_PHILIPS_ATSC,
2267 .tuner_addr = ADDR_UNSET,
2268 .radio_addr = ADDR_UNSET,
2269 .has_dvb = 1,
2270 },
2271 [BTTV_BOARD_TWINHAN_DST] = {
2272 .name = "Twinhan DST + clones",
2273 .no_msp34xx = 1,
2274 .no_tda9875 = 1,
2275 .no_tda7432 = 1,
2276 .tuner_type = TUNER_ABSENT,
2277 .tuner_addr = ADDR_UNSET,
2278 .radio_addr = ADDR_UNSET,
2279 .no_video = 1,
2280 .has_dvb = 1,
2281 },
2282 [BTTV_BOARD_WINFASTVC100] = {
2283 .name = "Winfast VC100",
2284 .video_inputs = 3,
2285 .audio_inputs = 0,
2286 .svhs = 1,
2287 .tuner = -1,
2288 .muxsel = { 3, 1, 1, 3}, /* Vid In, SVid In, Vid over SVid in connector */
2289 .no_msp34xx = 1,
2290 .no_tda9875 = 1,
2291 .no_tda7432 = 1,
2292 .tuner_type = TUNER_ABSENT,
2293 .tuner_addr = ADDR_UNSET,
2294 .radio_addr = ADDR_UNSET,
2295 .pll = PLL_28,
2296 },
2297 [BTTV_BOARD_TEV560] = {
2298 .name = "Teppro TEV-560/InterVision IV-560",
2299 .video_inputs = 3,
2300 .audio_inputs = 1,
2301 .tuner = 0,
2302 .svhs = 2,
2303 .gpiomask = 3,
2304 .muxsel = { 2, 3, 1, 1},
2305 .audiomux = { 1, 1, 1, 1, 0},
2306 .needs_tvaudio = 1,
2307 .tuner_type = TUNER_PHILIPS_PAL,
2308 .tuner_addr = ADDR_UNSET,
2309 .radio_addr = ADDR_UNSET,
2310 .pll = PLL_35,
2311 },
2312
2313 /* ---- card 0x74 ---------------------------------- */
2314 [BTTV_BOARD_SIMUS_GVC1100] = {
2315 .name = "SIMUS GVC1100",
2316 .video_inputs = 4,
2317 .audio_inputs = 0,
2318 .tuner = -1,
2319 .svhs = -1,
2320 .tuner_type = -1,
2321 .tuner_addr = ADDR_UNSET,
2322 .radio_addr = ADDR_UNSET,
2323 .pll = PLL_28,
2324 .muxsel = { 2, 2, 2, 2},
2325 .gpiomask = 0x3F,
2326 .muxsel_hook = gvc1100_muxsel,
2327 },
2328 [BTTV_BOARD_NGSTV_PLUS] = {
2329 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
2330 .name = "NGS NGSTV+",
2331 .video_inputs = 3,
2332 .tuner = 0,
2333 .svhs = 2,
2334 .gpiomask = 0x008007,
2335 .muxsel = {2, 3, 0, 0},
2336 .audiomux = {0, 0, 0, 0, 0x000003, 0},
2337 .pll = PLL_28,
2338 .tuner_type = TUNER_PHILIPS_PAL,
2339 .tuner_addr = ADDR_UNSET,
2340 .radio_addr = ADDR_UNSET,
2341 .has_remote = 1,
2342 },
2343 [BTTV_BOARD_LMLBT4] = {
2344 /* http://linuxmedialabs.com */
2345 .name = "LMLBT4",
2346 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
2347 .audio_inputs = 0,
2348 .tuner = -1,
2349 .svhs = -1,
2350 .muxsel = { 2, 3, 1, 0 },
2351 .no_msp34xx = 1,
2352 .no_tda9875 = 1,
2353 .no_tda7432 = 1,
2354 .needs_tvaudio = 0,
2355 .tuner_type = -1,
2356 .tuner_addr = ADDR_UNSET,
2357 .radio_addr = ADDR_UNSET,
2358 },
2359 [BTTV_BOARD_TEKRAM_M205] = {
2360 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
2361 .name = "Tekram M205 PRO",
2362 .video_inputs = 3,
2363 .audio_inputs = 1,
2364 .tuner = 0,
2365 .tuner_type = TUNER_PHILIPS_PAL,
2366 .tuner_addr = ADDR_UNSET,
2367 .radio_addr = ADDR_UNSET,
2368 .svhs = 2,
2369 .needs_tvaudio = 0,
2370 .gpiomask = 0x68,
2371 .muxsel = { 2, 3, 1},
2372 .audiomux = { 0x68, 0x68, 0x61, 0x61, 0x00 },
2373 .pll = PLL_28,
2374 },
2375
2376 /* ---- card 0x78 ---------------------------------- */
2377 [BTTV_BOARD_CONTVFMI] = {
2378 /* Javier Cendan Ares <jcendan@lycos.es> */
2379 /* bt878 TV + FM without subsystem ID */
2380 .name = "Conceptronic CONTVFMi",
2381 .video_inputs = 3,
2382 .audio_inputs = 1,
2383 .tuner = 0,
2384 .svhs = 2,
2385 .gpiomask = 0x008007,
2386 .muxsel = { 2, 3, 1, 1 },
2387 .audiomux = { 0, 1, 2, 2, 3 },
2388 .needs_tvaudio = 0,
2389 .pll = PLL_28,
2390 .tuner_type = TUNER_PHILIPS_PAL,
2391 .tuner_addr = ADDR_UNSET,
2392 .radio_addr = ADDR_UNSET,
2393 .has_remote = 1,
2394 .has_radio = 1,
2395 },
2396 [BTTV_BOARD_PICOLO_TETRA_CHIP] = {
2397 /*Eric DEBIEF <debief@telemsa.com>*/
2398 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/
2399 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/
2400 /*0x79 in bttv.h*/
2401 .name = "Euresys Picolo Tetra",
2402 .video_inputs = 4,
2403 .audio_inputs = 0,
2404 .tuner = -1,
2405 .svhs = -1,
2406 .gpiomask = 0,
2407 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
2408 .no_msp34xx = 1,
2409 .no_tda9875 = 1,
2410 .no_tda7432 = 1,
2411 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
2412 .audiomux = { 0, 0, 0, 0, 0, 0 }, /* card has no audio */
2413 .pll = PLL_28,
2414 .needs_tvaudio = 0,
2415 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
2416 .tuner_type = -1,
2417 .tuner_addr = ADDR_UNSET,
2418 .radio_addr = ADDR_UNSET,
2419 },
2420 [BTTV_BOARD_SPIRIT_TV] = {
2421 /* Spirit TV Tuner from http://spiritmodems.com.au */
2422 /* Stafford Goodsell <surge@goliath.homeunix.org> */
2423 .name = "Spirit TV Tuner",
2424 .video_inputs = 3,
2425 .audio_inputs = 1,
2426 .tuner = 0,
2427 .svhs = 2,
2428 .gpiomask = 0x0000000f,
2429 .muxsel = { 2, 1, 1 },
2430 .audiomux = { 0x02, 0x00, 0x00, 0x00, 0x00},
2431 .tuner_type = TUNER_TEMIC_PAL,
2432 .tuner_addr = ADDR_UNSET,
2433 .radio_addr = ADDR_UNSET,
2434 .no_msp34xx = 1,
2435 .no_tda9875 = 1,
2436 },
2437 [BTTV_BOARD_AVDVBT_771] = {
2438 /* Wolfram Joost <wojo@frokaschwei.de> */
2439 .name = "AVerMedia AVerTV DVB-T 771",
2440 .video_inputs = 2,
2441 .svhs = 1,
2442 .tuner = -1,
2443 .tuner_type = TUNER_ABSENT,
2444 .tuner_addr = ADDR_UNSET,
2445 .radio_addr = ADDR_UNSET,
2446 .muxsel = { 3 , 3 },
2447 .no_msp34xx = 1,
2448 .no_tda9875 = 1,
2449 .no_tda7432 = 1,
2450 .pll = PLL_28,
2451 .has_dvb = 1,
2452 .no_gpioirq = 1,
2453 .has_remote = 1,
2454 },
2455 /* ---- card 0x7c ---------------------------------- */
2456 [BTTV_BOARD_AVDVBT_761] = {
2457 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
2458 /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
2459 .name = "AverMedia AverTV DVB-T 761",
2460 .video_inputs = 2,
2461 .tuner = -1,
2462 .svhs = 1,
2463 .muxsel = { 3, 1, 2, 0}, /* Comp0, S-Video, ?, ? */
2464 .no_msp34xx = 1,
2465 .no_tda9875 = 1,
2466 .no_tda7432 = 1,
2467 .pll = PLL_28,
2468 .tuner_type = -1,
2469 .tuner_addr = ADDR_UNSET,
2470 .radio_addr = ADDR_UNSET,
2471 .has_dvb = 1,
2472 .no_gpioirq = 1,
2473 .has_remote = 1,
2474 },
2475 [BTTV_BOARD_MATRIX_VISIONSQ] = {
2476 /* andre.schwarz@matrix-vision.de */
2477 .name = "MATRIX Vision Sigma-SQ",
2478 .video_inputs = 16,
2479 .audio_inputs = 0,
2480 .tuner = -1,
2481 .svhs = -1,
2482 .gpiomask = 0x0,
2483 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
2484 3, 3, 3, 3, 3, 3, 3, 3 },
2485 .muxsel_hook = sigmaSQ_muxsel,
2486 .audiomux = { 0 },
2487 .no_msp34xx = 1,
2488 .pll = PLL_28,
2489 .tuner_type = -1,
2490 .tuner_addr = ADDR_UNSET,
2491 .radio_addr = ADDR_UNSET,
2492 },
2493 [BTTV_BOARD_MATRIX_VISIONSLC] = {
2494 /* andre.schwarz@matrix-vision.de */
2495 .name = "MATRIX Vision Sigma-SLC",
2496 .video_inputs = 4,
2497 .audio_inputs = 0,
2498 .tuner = -1,
2499 .svhs = -1,
2500 .gpiomask = 0x0,
2501 .muxsel = { 2, 2, 2, 2 },
2502 .muxsel_hook = sigmaSLC_muxsel,
2503 .audiomux = { 0 },
2504 .no_msp34xx = 1,
2505 .pll = PLL_28,
2506 .tuner_type = -1,
2507 .tuner_addr = ADDR_UNSET,
2508 .radio_addr = ADDR_UNSET,
2509 },
2510 /* BTTV_BOARD_APAC_VIEWCOMP */
2511 [BTTV_BOARD_APAC_VIEWCOMP] = {
2512 /* Attila Kondoros <attila.kondoros@chello.hu> */
2513 /* bt878 TV + FM 0x00000000 subsystem ID */
2514 .name = "APAC Viewcomp 878(AMAX)",
2515 .video_inputs = 2,
2516 .audio_inputs = 1,
2517 .tuner = 0,
2518 .svhs = -1,
2519 .gpiomask = 0xFF,
2520 .muxsel = { 2, 3, 1, 1},
2521 .audiomux = { 2, 0, 0, 0, 10},
2522 .needs_tvaudio = 0,
2523 .pll = PLL_28,
2524 .tuner_type = TUNER_PHILIPS_PAL,
2525 .tuner_addr = ADDR_UNSET,
2526 .radio_addr = ADDR_UNSET,
2527 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
2528 .has_radio = 1, /* not every card has radio */
2529 },
2530
2531 /* ---- card 0x80 ---------------------------------- */
2532 [BTTV_BOARD_DVICO_DVBT_LITE] = {
2533 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
2534 .name = "DViCO FusionHDTV DVB-T Lite",
2535 .tuner = -1,
2536 .no_msp34xx = 1,
2537 .no_tda9875 = 1,
2538 .no_tda7432 = 1,
2539 .pll = PLL_28,
2540 .no_video = 1,
2541 .has_dvb = 1,
2542 .tuner_type = -1,
2543 .tuner_addr = ADDR_UNSET,
2544 .radio_addr = ADDR_UNSET,
2545 },
2546 [BTTV_BOARD_VGEAR_MYVCD] = {
2547 /* Steven <photon38@pchome.com.tw> */
2548 .name = "V-Gear MyVCD",
2549 .video_inputs = 3,
2550 .audio_inputs = 1,
2551 .tuner = 0,
2552 .svhs = 2,
2553 .gpiomask = 0x3f,
2554 .muxsel = {2, 3, 1, 0},
2555 .audiomux = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31},
2556 .no_msp34xx = 1,
2557 .pll = PLL_28,
2558 .tuner_type = TUNER_PHILIPS_NTSC_M,
2559 .tuner_addr = ADDR_UNSET,
2560 .radio_addr = ADDR_UNSET,
2561 .has_radio = 0,
2562 #if 0
2563 .has_remote = 1,
2564 #endif
2565 },
2566 [BTTV_BOARD_SUPER_TV] = {
2567 /* Rick C <cryptdragoon@gmail.com> */
2568 .name = "Super TV Tuner",
2569 .video_inputs = 4,
2570 .audio_inputs = 1,
2571 .tuner = 0,
2572 .svhs = 2,
2573 .muxsel = { 2, 3, 1, 0},
2574 .tuner_type = TUNER_PHILIPS_NTSC,
2575 .tuner_addr = ADDR_UNSET,
2576 .radio_addr = ADDR_UNSET,
2577 .gpiomask = 0x008007,
2578 .audiomux = { 0, 0x000001,0,0, 0},
2579 .needs_tvaudio = 1,
2580 .has_radio = 1,
2581 },
2582 [BTTV_BOARD_TIBET_CS16] = {
2583 /* Chris Fanning <video4linux@haydon.net> */
2584 .name = "Tibet Systems 'Progress DVR' CS16",
2585 .video_inputs = 16,
2586 .audio_inputs = 0,
2587 .tuner = -1,
2588 .svhs = -1,
2589 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2590 .pll = PLL_28,
2591 .no_msp34xx = 1,
2592 .no_tda9875 = 1,
2593 .no_tda7432 = 1,
2594 .tuner_type = -1,
2595 .tuner_addr = ADDR_UNSET,
2596 .radio_addr = ADDR_UNSET,
2597 .muxsel_hook = tibetCS16_muxsel,
2598 },
2599 [BTTV_BOARD_KODICOM_4400R] = {
2600 /* Bill Brack <wbrack@mmm.com.hk> */
2601 /*
2602 * Note that, because of the card's wiring, the "master"
2603 * BT878A chip (i.e. the one which controls the analog switch
2604 * and must use this card type) is the 2nd one detected. The
2605 * other 3 chips should use card type 0x85, whose description
2606 * follows this one. There is a EEPROM on the card (which is
2607 * connected to the I2C of one of those other chips), but is
2608 * not currently handled. There is also a facility for a
2609 * "monitor", which is also not currently implemented.
2610 */
2611 .name = "Kodicom 4400R (master)",
2612 .video_inputs = 16,
2613 .audio_inputs = 0,
2614 .tuner = -1,
2615 .tuner_type = -1,
2616 .tuner_addr = ADDR_UNSET,
2617 .radio_addr = ADDR_UNSET,
2618 .svhs = -1,
2619 /* GPIO bits 0-9 used for analog switch:
2620 * 00 - 03: camera selector
2621 * 04 - 06: channel (controller) selector
2622 * 07: data (1->on, 0->off)
2623 * 08: strobe
2624 * 09: reset
2625 * bit 16 is input from sync separator for the channel
2626 */
2627 .gpiomask = 0x0003ff,
2628 .no_gpioirq = 1,
2629 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2630 .pll = PLL_28,
2631 .no_msp34xx = 1,
2632 .no_tda7432 = 1,
2633 .no_tda9875 = 1,
2634 .muxsel_hook = kodicom4400r_muxsel,
2635 },
2636 [BTTV_BOARD_KODICOM_4400R_SL] = {
2637 /* Bill Brack <wbrack@mmm.com.hk> */
2638 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
2639 * one which controls the analog switch, and must use the card type)
2640 * is the 2nd one detected. The other 3 chips should use this card
2641 * type
2642 */
2643 .name = "Kodicom 4400R (slave)",
2644 .video_inputs = 16,
2645 .audio_inputs = 0,
2646 .tuner = -1,
2647 .tuner_type = -1,
2648 .tuner_addr = ADDR_UNSET,
2649 .radio_addr = ADDR_UNSET,
2650 .svhs = -1,
2651 .gpiomask = 0x010000,
2652 .no_gpioirq = 1,
2653 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2654 .pll = PLL_28,
2655 .no_msp34xx = 1,
2656 .no_tda7432 = 1,
2657 .no_tda9875 = 1,
2658 .muxsel_hook = kodicom4400r_muxsel,
2659 },
2660 /* ---- card 0x86---------------------------------- */
2661 [BTTV_BOARD_ADLINK_RTV24] = {
2662 /* Michael Henson <mhenson@clarityvi.com> */
2663 /* Adlink RTV24 with special unlock codes */
2664 .name = "Adlink RTV24",
2665 .video_inputs = 4,
2666 .audio_inputs = 1,
2667 .tuner = 0,
2668 .svhs = 2,
2669 .muxsel = { 2, 3, 1, 0},
2670 .tuner_type = -1,
2671 .tuner_addr = ADDR_UNSET,
2672 .radio_addr = ADDR_UNSET,
2673 .pll = PLL_28,
2674 },
2675 /* ---- card 0x87---------------------------------- */
2676 [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
2677 /* Michael Krufky <mkrufky@m1k.net> */
2678 .name = "DViCO FusionHDTV 5 Lite",
2679 .tuner = 0,
2680 .tuner_type = TUNER_LG_TDVS_H062F,
2681 .tuner_addr = ADDR_UNSET,
2682 .radio_addr = ADDR_UNSET,
2683 .video_inputs = 3,
2684 .audio_inputs = 1,
2685 .svhs = 2,
2686 .muxsel = { 2, 3, 1 },
2687 .gpiomask = 0x00e00007,
2688 .audiomux = { 0x00400005, 0, 0x00000001, 0, 0x00c00007, 0 },
2689 .no_msp34xx = 1,
2690 .no_tda9875 = 1,
2691 .no_tda7432 = 1,
2692 .has_dvb = 1,
2693 },
2694 /* ---- card 0x88---------------------------------- */
2695 [BTTV_BOARD_ACORP_Y878F] = {
2696 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
2697 .name = "Acorp Y878F",
2698 .video_inputs = 3,
2699 .audio_inputs = 1,
2700 .tuner = 0,
2701 .svhs = 2,
2702 .gpiomask = 0x01fe00,
2703 .muxsel = { 2, 3, 1, 1},
2704 .audiomux = { 0x001e00, 0, 0x018000, 0x014000, 0x002000, 0 },
2705 .needs_tvaudio = 1,
2706 .pll = PLL_28,
2707 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
2708 .tuner_addr = 0xc1 >>1,
2709 .radio_addr = 0xc1 >>1,
2710 .has_radio = 1,
2711 },
2712 /* ---- card 0x89 ---------------------------------- */
2713 [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
2714 .name = "Conceptronic CTVFMi v2",
2715 .video_inputs = 3,
2716 .audio_inputs = 1,
2717 .tuner = 0,
2718 .svhs = 2,
2719 .gpiomask = 0x001c0007,
2720 .muxsel = { 2, 3, 1, 1 },
2721 .audiomux = { 0, 1, 2, 2, 3 },
2722 .needs_tvaudio = 0,
2723 .pll = PLL_28,
2724 .tuner_type = TUNER_TENA_9533_DI,
2725 .tuner_addr = ADDR_UNSET,
2726 .radio_addr = ADDR_UNSET,
2727 .has_remote = 1,
2728 .has_radio = 1,
2729 },
2730 /* ---- card 0x8a ---------------------------------- */
2731 [BTTV_BOARD_PV_BT878P_2E] = {
2732 .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
2733 .video_inputs = 5,
2734 .audio_inputs = 1,
2735 .tuner = 0,
2736 .svhs = 3,
2737 .gpiomask = 0x01fe00,
2738 .muxsel = { 2,3,1,1,-1 },
2739 .digital_mode = DIGITAL_MODE_CAMERA,
2740 .audiomux = { 0x00400, 0x10400, 0x04400, 0x80000, 0x12400, 0x46000 },
2741 .no_msp34xx = 1,
2742 .pll = PLL_28,
2743 .tuner_type = TUNER_LG_PAL_FM,
2744 .tuner_addr = ADDR_UNSET,
2745 .radio_addr = ADDR_UNSET,
2746 .has_remote = 1,
2747 },
2748 /* ---- card 0x8b ---------------------------------- */
2749 [BTTV_BOARD_PV_M4900] = {
2750 /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
2751 .name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
2752 .video_inputs = 3,
2753 .audio_inputs = 1,
2754 .tuner = 0,
2755 .svhs = 2,
2756 .gpiomask = 0x3f,
2757 .muxsel = { 2, 3, 1, 1 },
2758 .audiomux = { 0x21, 0x20, 0x24, 0x2c, 0x29, 0x29 },
2759 .no_msp34xx = 1,
2760 .pll = PLL_28,
2761 .tuner_type = TUNER_YMEC_TVF_5533MF,
2762 .tuner_addr = ADDR_UNSET,
2763 .radio_addr = ADDR_UNSET,
2764 .has_radio = 1,
2765 .has_remote = 1,
2766 },
2767 /* ---- card 0x8c ---------------------------------- */
2768 [BTTV_BOARD_OSPREY440] = {
2769 .name = "Osprey 440",
2770 .video_inputs = 1,
2771 .audio_inputs = 1,
2772 .tuner = -1,
2773 .svhs = 1,
2774 .muxsel = { 2 },
2775 .pll = PLL_28,
2776 .tuner_type = UNSET,
2777 .tuner_addr = ADDR_UNSET,
2778 .radio_addr = ADDR_UNSET,
2779 .no_msp34xx = 1,
2780 .no_tda9875 = 1,
2781 .no_tda7432 = 1,
2782 },
2783 /* ---- card 0x8d ---------------------------------- */
2784 [BTTV_BOARD_ASOUND_SKYEYE] = {
2785 .name = "Asound Skyeye PCTV",
2786 .video_inputs = 3,
2787 .audio_inputs = 1,
2788 .tuner = 0,
2789 .svhs = 2,
2790 .gpiomask = 15,
2791 .muxsel = { 2, 3, 1, 1},
2792 .audiomux = {2,0,0,0,1},
2793 .needs_tvaudio = 1,
2794 .pll = PLL_28,
2795 .tuner_type = 2,
2796 .tuner_addr = ADDR_UNSET,
2797 .radio_addr = ADDR_UNSET,
2798 },
2799
2800};
2422 2801
2423static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); 2802static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
2424 2803
@@ -2461,7 +2840,7 @@ void __devinit bttv_idcard(struct bttv *btv)
2461 btv->c.nr, btv->cardid & 0xffff, 2840 btv->c.nr, btv->cardid & 0xffff,
2462 (btv->cardid >> 16) & 0xffff); 2841 (btv->cardid >> 16) & 0xffff);
2463 printk(KERN_DEBUG "please mail id, board name and " 2842 printk(KERN_DEBUG "please mail id, board name and "
2464 "the correct card= insmod option to kraxel@bytesex.org\n"); 2843 "the correct card= insmod option to video4linux-list@redhat.com\n");
2465 } 2844 }
2466 } 2845 }
2467 2846
@@ -2510,11 +2889,11 @@ void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
2510 int type = -1; 2889 int type = -1;
2511 2890
2512 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13)) 2891 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
2513 type = BTTV_MODTEC_205; 2892 type = BTTV_BOARD_MODTEC_205;
2514 else if (0 == strncmp(eeprom_data+20,"Picolo",7)) 2893 else if (0 == strncmp(eeprom_data+20,"Picolo",7))
2515 type = BTTV_EURESYS_PICOLO; 2894 type = BTTV_BOARD_EURESYS_PICOLO;
2516 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0) 2895 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
2517 type = BTTV_HAUPPAUGE; /* old bt848 */ 2896 type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */
2518 2897
2519 if (-1 != type) { 2898 if (-1 != type) {
2520 btv->c.type = type; 2899 btv->c.type = type;
@@ -2548,7 +2927,7 @@ static void flyvideo_gpio(struct bttv *btv)
2548 switch(ttype) { 2927 switch(ttype) {
2549 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */ 2928 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */
2550 break; 2929 break;
2551 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */ 2930 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
2552 break; 2931 break;
2553 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */ 2932 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
2554 break; 2933 break;
@@ -2564,7 +2943,7 @@ static void flyvideo_gpio(struct bttv *btv)
2564 has_radio = gpio & 0x400000; 2943 has_radio = gpio & 0x400000;
2565 /* unknown 0x200000; 2944 /* unknown 0x200000;
2566 * unknown2 0x100000; */ 2945 * unknown2 0x100000; */
2567 is_capture_only = !(gpio & 0x008000); /* GPIO15 */ 2946 is_capture_only = !(gpio & 0x008000); /* GPIO15 */
2568 has_tda9820_tda9821 = !(gpio & 0x004000); 2947 has_tda9820_tda9821 = !(gpio & 0x004000);
2569 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */ 2948 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */
2570 /* 2949 /*
@@ -2601,7 +2980,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2601 char *info; 2980 char *info;
2602 2981
2603 gpio_inout(0xffffff, 0); 2982 gpio_inout(0xffffff, 0);
2604 gpio = gpio_read(); 2983 gpio = gpio_read();
2605 id = ((gpio>>10) & 63) -1; 2984 id = ((gpio>>10) & 63) -1;
2606 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx"); 2985 msp = bttv_I2CRead(btv, I2C_MSP3400, "MSP34xx");
2607 if (id < 32) { 2986 if (id < 32) {
@@ -2620,10 +2999,10 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2620 btv->has_radio = 0; 2999 btv->has_radio = 0;
2621 } 3000 }
2622 if (-1 != msp) { 3001 if (-1 != msp) {
2623 if (btv->c.type == BTTV_MIRO) 3002 if (btv->c.type == BTTV_BOARD_MIRO)
2624 btv->c.type = BTTV_MIROPRO; 3003 btv->c.type = BTTV_BOARD_MIROPRO;
2625 if (btv->c.type == BTTV_PINNACLE) 3004 if (btv->c.type == BTTV_BOARD_PINNACLE)
2626 btv->c.type = BTTV_PINNACLEPRO; 3005 btv->c.type = BTTV_BOARD_PINNACLEPRO;
2627 } 3006 }
2628 printk(KERN_INFO 3007 printk(KERN_INFO
2629 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n", 3008 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
@@ -2664,7 +3043,7 @@ static void miro_pinnacle_gpio(struct bttv *btv)
2664 break; 3043 break;
2665 } 3044 }
2666 if (-1 != msp) 3045 if (-1 != msp)
2667 btv->c.type = BTTV_PINNACLEPRO; 3046 btv->c.type = BTTV_BOARD_PINNACLEPRO;
2668 printk(KERN_INFO 3047 printk(KERN_INFO
2669 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", 3048 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
2670 btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); 3049 btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
@@ -2712,7 +3091,7 @@ static void eagle_muxsel(struct bttv *btv, unsigned int input)
2712 3091
2713static void gvc1100_muxsel(struct bttv *btv, unsigned int input) 3092static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
2714{ 3093{
2715 static const int masks[] = {0x30, 0x01, 0x12, 0x23}; 3094 static const int masks[] = {0x30, 0x01, 0x12, 0x23};
2716 gpio_write(masks[input%4]); 3095 gpio_write(masks[input%4]);
2717} 3096}
2718 3097
@@ -2778,26 +3157,27 @@ static void bttv_reset_audio(struct bttv *btv)
2778void __devinit bttv_init_card1(struct bttv *btv) 3157void __devinit bttv_init_card1(struct bttv *btv)
2779{ 3158{
2780 switch (btv->c.type) { 3159 switch (btv->c.type) {
2781 case BTTV_HAUPPAUGE: 3160 case BTTV_BOARD_HAUPPAUGE:
2782 case BTTV_HAUPPAUGE878: 3161 case BTTV_BOARD_HAUPPAUGE878:
2783 boot_msp34xx(btv,5); 3162 boot_msp34xx(btv,5);
2784 break; 3163 break;
2785 case BTTV_VOODOOTV_FM: 3164 case BTTV_BOARD_VOODOOTV_FM:
2786 boot_msp34xx(btv,20); 3165 boot_msp34xx(btv,20);
2787 break; 3166 break;
2788 case BTTV_AVERMEDIA98: 3167 case BTTV_BOARD_AVERMEDIA98:
2789 boot_msp34xx(btv,11); 3168 boot_msp34xx(btv,11);
2790 break; 3169 break;
2791 case BTTV_HAUPPAUGEPVR: 3170 case BTTV_BOARD_HAUPPAUGEPVR:
2792 pvr_boot(btv); 3171 pvr_boot(btv);
2793 break; 3172 break;
2794 case BTTV_TWINHAN_DST: 3173 case BTTV_BOARD_TWINHAN_DST:
2795 case BTTV_AVDVBT_771: 3174 case BTTV_BOARD_AVDVBT_771:
3175 case BTTV_BOARD_PINNACLESAT:
2796 btv->use_i2c_hw = 1; 3176 btv->use_i2c_hw = 1;
2797 break; 3177 break;
2798 case BTTV_ADLINK_RTV24: 3178 case BTTV_BOARD_ADLINK_RTV24:
2799 init_RTV24( btv ); 3179 init_RTV24( btv );
2800 break; 3180 break;
2801 3181
2802 } 3182 }
2803 if (!bttv_tvcards[btv->c.type].has_dvb) 3183 if (!bttv_tvcards[btv->c.type].has_dvb)
@@ -2810,53 +3190,53 @@ void __devinit bttv_init_card2(struct bttv *btv)
2810 int tda9887; 3190 int tda9887;
2811 int addr=ADDR_UNSET; 3191 int addr=ADDR_UNSET;
2812 3192
2813 btv->tuner_type = -1; 3193 btv->tuner_type = -1;
2814 3194
2815 if (BTTV_UNKNOWN == btv->c.type) { 3195 if (BTTV_BOARD_UNKNOWN == btv->c.type) {
2816 bttv_readee(btv,eeprom_data,0xa0); 3196 bttv_readee(btv,eeprom_data,0xa0);
2817 identify_by_eeprom(btv,eeprom_data); 3197 identify_by_eeprom(btv,eeprom_data);
2818 } 3198 }
2819 3199
2820 switch (btv->c.type) { 3200 switch (btv->c.type) {
2821 case BTTV_MIRO: 3201 case BTTV_BOARD_MIRO:
2822 case BTTV_MIROPRO: 3202 case BTTV_BOARD_MIROPRO:
2823 case BTTV_PINNACLE: 3203 case BTTV_BOARD_PINNACLE:
2824 case BTTV_PINNACLEPRO: 3204 case BTTV_BOARD_PINNACLEPRO:
2825 /* miro/pinnacle */ 3205 /* miro/pinnacle */
2826 miro_pinnacle_gpio(btv); 3206 miro_pinnacle_gpio(btv);
2827 break; 3207 break;
2828 case BTTV_FLYVIDEO_98: 3208 case BTTV_BOARD_FLYVIDEO_98:
2829 case BTTV_MAXI: 3209 case BTTV_BOARD_MAXI:
2830 case BTTV_LIFE_FLYKIT: 3210 case BTTV_BOARD_LIFE_FLYKIT:
2831 case BTTV_FLYVIDEO: 3211 case BTTV_BOARD_FLYVIDEO:
2832 case BTTV_TYPHOON_TVIEW: 3212 case BTTV_BOARD_TYPHOON_TVIEW:
2833 case BTTV_CHRONOS_VS2: 3213 case BTTV_BOARD_CHRONOS_VS2:
2834 case BTTV_FLYVIDEO_98FM: 3214 case BTTV_BOARD_FLYVIDEO_98FM:
2835 case BTTV_FLYVIDEO2000: 3215 case BTTV_BOARD_FLYVIDEO2000:
2836 case BTTV_FLYVIDEO98EZ: 3216 case BTTV_BOARD_FLYVIDEO98EZ:
2837 case BTTV_CONFERENCETV: 3217 case BTTV_BOARD_CONFERENCETV:
2838 case BTTV_LIFETEC_9415: 3218 case BTTV_BOARD_LIFETEC_9415:
2839 flyvideo_gpio(btv); 3219 flyvideo_gpio(btv);
2840 break; 3220 break;
2841 case BTTV_HAUPPAUGE: 3221 case BTTV_BOARD_HAUPPAUGE:
2842 case BTTV_HAUPPAUGE878: 3222 case BTTV_BOARD_HAUPPAUGE878:
2843 case BTTV_HAUPPAUGEPVR: 3223 case BTTV_BOARD_HAUPPAUGEPVR:
2844 /* pick up some config infos from the eeprom */ 3224 /* pick up some config infos from the eeprom */
2845 bttv_readee(btv,eeprom_data,0xa0); 3225 bttv_readee(btv,eeprom_data,0xa0);
2846 hauppauge_eeprom(btv); 3226 hauppauge_eeprom(btv);
2847 break; 3227 break;
2848 case BTTV_AVERMEDIA98: 3228 case BTTV_BOARD_AVERMEDIA98:
2849 case BTTV_AVPHONE98: 3229 case BTTV_BOARD_AVPHONE98:
2850 bttv_readee(btv,eeprom_data,0xa0); 3230 bttv_readee(btv,eeprom_data,0xa0);
2851 avermedia_eeprom(btv); 3231 avermedia_eeprom(btv);
2852 break; 3232 break;
2853 case BTTV_PXC200: 3233 case BTTV_BOARD_PXC200:
2854 init_PXC200(btv); 3234 init_PXC200(btv);
2855 break; 3235 break;
2856 case BTTV_PICOLO_TETRA_CHIP: 3236 case BTTV_BOARD_PICOLO_TETRA_CHIP:
2857 picolo_tetra_init(btv); 3237 picolo_tetra_init(btv);
2858 break; 3238 break;
2859 case BTTV_VHX: 3239 case BTTV_BOARD_VHX:
2860 btv->has_radio = 1; 3240 btv->has_radio = 1;
2861 btv->has_matchbox = 1; 3241 btv->has_matchbox = 1;
2862 btv->mbox_we = 0x20; 3242 btv->mbox_we = 0x20;
@@ -2865,58 +3245,58 @@ void __devinit bttv_init_card2(struct bttv *btv)
2865 btv->mbox_data = 0x10; 3245 btv->mbox_data = 0x10;
2866 btv->mbox_mask = 0x38; 3246 btv->mbox_mask = 0x38;
2867 break; 3247 break;
2868 case BTTV_VOBIS_BOOSTAR: 3248 case BTTV_BOARD_VOBIS_BOOSTAR:
2869 case BTTV_TERRATV: 3249 case BTTV_BOARD_TERRATV:
2870 terratec_active_radio_upgrade(btv); 3250 terratec_active_radio_upgrade(btv);
2871 break; 3251 break;
2872 case BTTV_MAGICTVIEW061: 3252 case BTTV_BOARD_MAGICTVIEW061:
2873 if (btv->cardid == 0x3002144f) { 3253 if (btv->cardid == 0x3002144f) {
2874 btv->has_radio=1; 3254 btv->has_radio=1;
2875 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr); 3255 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr);
2876 } 3256 }
2877 break; 3257 break;
2878 case BTTV_STB2: 3258 case BTTV_BOARD_STB2:
2879 if (btv->cardid == 0x3060121a) { 3259 if (btv->cardid == 0x3060121a) {
2880 /* Fix up entry for 3DFX VoodooTV 100, 3260 /* Fix up entry for 3DFX VoodooTV 100,
2881 which is an OEM STB card variant. */ 3261 which is an OEM STB card variant. */
2882 btv->has_radio=0; 3262 btv->has_radio=0;
2883 btv->tuner_type=TUNER_TEMIC_NTSC; 3263 btv->tuner_type=TUNER_TEMIC_NTSC;
2884 } 3264 }
2885 break; 3265 break;
2886 case BTTV_OSPREY1x0: 3266 case BTTV_BOARD_OSPREY1x0:
2887 case BTTV_OSPREY1x0_848: 3267 case BTTV_BOARD_OSPREY1x0_848:
2888 case BTTV_OSPREY101_848: 3268 case BTTV_BOARD_OSPREY101_848:
2889 case BTTV_OSPREY1x1: 3269 case BTTV_BOARD_OSPREY1x1:
2890 case BTTV_OSPREY1x1_SVID: 3270 case BTTV_BOARD_OSPREY1x1_SVID:
2891 case BTTV_OSPREY2xx: 3271 case BTTV_BOARD_OSPREY2xx:
2892 case BTTV_OSPREY2x0_SVID: 3272 case BTTV_BOARD_OSPREY2x0_SVID:
2893 case BTTV_OSPREY2x0: 3273 case BTTV_BOARD_OSPREY2x0:
2894 case BTTV_OSPREY500: 3274 case BTTV_BOARD_OSPREY500:
2895 case BTTV_OSPREY540: 3275 case BTTV_BOARD_OSPREY540:
2896 case BTTV_OSPREY2000: 3276 case BTTV_BOARD_OSPREY2000:
2897 bttv_readee(btv,eeprom_data,0xa0); 3277 bttv_readee(btv,eeprom_data,0xa0);
2898 osprey_eeprom(btv); 3278 osprey_eeprom(btv);
2899 break; 3279 break;
2900 case BTTV_IDS_EAGLE: 3280 case BTTV_BOARD_IDS_EAGLE:
2901 init_ids_eagle(btv); 3281 init_ids_eagle(btv);
2902 break; 3282 break;
2903 case BTTV_MODTEC_205: 3283 case BTTV_BOARD_MODTEC_205:
2904 bttv_readee(btv,eeprom_data,0xa0); 3284 bttv_readee(btv,eeprom_data,0xa0);
2905 modtec_eeprom(btv); 3285 modtec_eeprom(btv);
2906 break; 3286 break;
2907 case BTTV_LMLBT4: 3287 case BTTV_BOARD_LMLBT4:
2908 init_lmlbt4x(btv); 3288 init_lmlbt4x(btv);
2909 break; 3289 break;
2910 case BTTV_TIBET_CS16: 3290 case BTTV_BOARD_TIBET_CS16:
2911 tibetCS16_init(btv); 3291 tibetCS16_init(btv);
2912 break; 3292 break;
2913 case BTTV_KODICOM_4400R: 3293 case BTTV_BOARD_KODICOM_4400R:
2914 kodicom4400r_init(btv); 3294 kodicom4400r_init(btv);
2915 break; 3295 break;
2916 } 3296 }
2917 3297
2918 /* pll configuration */ 3298 /* pll configuration */
2919 if (!(btv->id==848 && btv->revision==0x11)) { 3299 if (!(btv->id==848 && btv->revision==0x11)) {
2920 /* defaults from card list */ 3300 /* defaults from card list */
2921 if (PLL_28 == bttv_tvcards[btv->c.type].pll) { 3301 if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
2922 btv->pll.pll_ifreq=28636363; 3302 btv->pll.pll_ifreq=28636363;
@@ -2927,26 +3307,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
2927 btv->pll.pll_crystal=BT848_IFORM_XT1; 3307 btv->pll.pll_crystal=BT848_IFORM_XT1;
2928 } 3308 }
2929 /* insmod options can override */ 3309 /* insmod options can override */
2930 switch (pll[btv->c.nr]) { 3310 switch (pll[btv->c.nr]) {
2931 case 0: /* none */ 3311 case 0: /* none */
2932 btv->pll.pll_crystal = 0; 3312 btv->pll.pll_crystal = 0;
2933 btv->pll.pll_ifreq = 0; 3313 btv->pll.pll_ifreq = 0;
2934 btv->pll.pll_ofreq = 0; 3314 btv->pll.pll_ofreq = 0;
2935 break; 3315 break;
2936 case 1: /* 28 MHz */ 3316 case 1: /* 28 MHz */
2937 case 28: 3317 case 28:
2938 btv->pll.pll_ifreq = 28636363; 3318 btv->pll.pll_ifreq = 28636363;
2939 btv->pll.pll_ofreq = 0; 3319 btv->pll.pll_ofreq = 0;
2940 btv->pll.pll_crystal = BT848_IFORM_XT0; 3320 btv->pll.pll_crystal = BT848_IFORM_XT0;
2941 break; 3321 break;
2942 case 2: /* 35 MHz */ 3322 case 2: /* 35 MHz */
2943 case 35: 3323 case 35:
2944 btv->pll.pll_ifreq = 35468950; 3324 btv->pll.pll_ifreq = 35468950;
2945 btv->pll.pll_ofreq = 0; 3325 btv->pll.pll_ofreq = 0;
2946 btv->pll.pll_crystal = BT848_IFORM_XT1; 3326 btv->pll.pll_crystal = BT848_IFORM_XT1;
2947 break; 3327 break;
2948 } 3328 }
2949 } 3329 }
2950 btv->pll.pll_current = -1; 3330 btv->pll.pll_current = -1;
2951 3331
2952 /* tuner configuration (from card list / autodetect / insmod option) */ 3332 /* tuner configuration (from card list / autodetect / insmod option) */
@@ -2955,23 +3335,26 @@ void __devinit bttv_init_card2(struct bttv *btv)
2955 3335
2956 if (UNSET != bttv_tvcards[btv->c.type].tuner_type) 3336 if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
2957 if(UNSET == btv->tuner_type) 3337 if(UNSET == btv->tuner_type)
2958 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type; 3338 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
2959 if (UNSET != tuner[btv->c.nr]) 3339 if (UNSET != tuner[btv->c.nr])
2960 btv->tuner_type = tuner[btv->c.nr]; 3340 btv->tuner_type = tuner[btv->c.nr];
2961 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type); 3341 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
2962 if (btv->pinnacle_id != UNSET) 3342
2963 bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
2964 &btv->pinnacle_id);
2965 if (btv->tuner_type != UNSET) { 3343 if (btv->tuner_type != UNSET) {
2966 struct tuner_setup tun_setup; 3344 struct tuner_setup tun_setup;
2967 3345
2968 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 3346 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
2969 tun_setup.type = btv->tuner_type; 3347 tun_setup.type = btv->tuner_type;
2970 tun_setup.addr = addr; 3348 tun_setup.addr = addr;
2971 3349
2972 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); 3350 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
2973 } 3351 }
2974 3352
3353 if (btv->pinnacle_id != UNSET) {
3354 bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE,
3355 &btv->pinnacle_id);
3356 }
3357
2975 btv->svhs = bttv_tvcards[btv->c.type].svhs; 3358 btv->svhs = bttv_tvcards[btv->c.type].svhs;
2976 if (svhs[btv->c.nr] != UNSET) 3359 if (svhs[btv->c.nr] != UNSET)
2977 btv->svhs = svhs[btv->c.nr]; 3360 btv->svhs = svhs[btv->c.nr];
@@ -2982,8 +3365,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
2982 btv->has_radio=1; 3365 btv->has_radio=1;
2983 if (bttv_tvcards[btv->c.type].has_remote) 3366 if (bttv_tvcards[btv->c.type].has_remote)
2984 btv->has_remote=1; 3367 btv->has_remote=1;
2985 if (bttv_tvcards[btv->c.type].no_gpioirq) 3368 if (!bttv_tvcards[btv->c.type].no_gpioirq)
2986 btv->gpioirq=0; 3369 btv->gpioirq=1;
2987 if (bttv_tvcards[btv->c.type].audio_hook) 3370 if (bttv_tvcards[btv->c.type].audio_hook)
2988 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; 3371 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
2989 3372
@@ -3024,6 +3407,9 @@ void __devinit bttv_init_card2(struct bttv *btv)
3024 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && 3407 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
3025 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) 3408 bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0)
3026 tda9887 = 1; 3409 tda9887 = 1;
3410 /* Hybrid DVB card, DOES have a tda9887 */
3411 if (btv->c.type == BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE)
3412 tda9887 = 1;
3027 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) || 3413 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) ||
3028 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) || 3414 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) ||
3029 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) || 3415 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) ||
@@ -3045,11 +3431,11 @@ static void modtec_eeprom(struct bttv *btv)
3045 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) { 3431 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) {
3046 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I; 3432 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I;
3047 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", 3433 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3048 btv->c.nr,&eeprom_data[0x1e]); 3434 btv->c.nr,&eeprom_data[0x1e]);
3049 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) { 3435 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
3050 btv->tuner_type=TUNER_PHILIPS_NTSC; 3436 btv->tuner_type=TUNER_PHILIPS_NTSC;
3051 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n", 3437 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3052 btv->c.nr,&eeprom_data[0x1e]); 3438 btv->c.nr,&eeprom_data[0x1e]);
3053 } else { 3439 } else {
3054 printk("bttv%d: Modtec: Unknown TunerString: %s\n", 3440 printk("bttv%d: Modtec: Unknown TunerString: %s\n",
3055 btv->c.nr,&eeprom_data[0x1e]); 3441 btv->c.nr,&eeprom_data[0x1e]);
@@ -3114,7 +3500,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
3114static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen) 3500static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3115{ 3501{
3116 u32 n; 3502 u32 n;
3117 u8 bits; 3503 u8 bits;
3118 int i; 3504 int i;
3119 3505
3120 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG); 3506 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG);
@@ -3150,19 +3536,19 @@ static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3150 3536
3151static int __devinit pvr_boot(struct bttv *btv) 3537static int __devinit pvr_boot(struct bttv *btv)
3152{ 3538{
3153 const struct firmware *fw_entry; 3539 const struct firmware *fw_entry;
3154 int rc; 3540 int rc;
3155 3541
3156 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); 3542 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
3157 if (rc != 0) { 3543 if (rc != 0) {
3158 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n", 3544 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n",
3159 btv->c.nr); 3545 btv->c.nr);
3160 return rc; 3546 return rc;
3161 } 3547 }
3162 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); 3548 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
3163 printk(KERN_INFO "bttv%d: altera firmware upload %s\n", 3549 printk(KERN_INFO "bttv%d: altera firmware upload %s\n",
3164 btv->c.nr, (rc < 0) ? "failed" : "ok"); 3550 btv->c.nr, (rc < 0) ? "failed" : "ok");
3165 release_firmware(fw_entry); 3551 release_firmware(fw_entry);
3166 return rc; 3552 return rc;
3167} 3553}
3168 3554
@@ -3176,33 +3562,33 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3176 unsigned long serial = 0; 3562 unsigned long serial = 0;
3177 3563
3178 if (btv->c.type == 0) { 3564 if (btv->c.type == 0) {
3179 /* this might be an antique... check for MMAC label in eeprom */ 3565 /* this might be an antique... check for MMAC label in eeprom */
3180 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) { 3566 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
3181 unsigned char checksum = 0; 3567 unsigned char checksum = 0;
3182 for (i =0; i<21; i++) 3568 for (i =0; i<21; i++)
3183 checksum += ee[i]; 3569 checksum += ee[i];
3184 if (checksum != ee[21]) 3570 if (checksum != ee[21])
3185 return; 3571 return;
3186 btv->c.type = BTTV_OSPREY1x0_848; 3572 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3187 for (i = 12; i < 21; i++) 3573 for (i = 12; i < 21; i++)
3188 serial *= 10, serial += ee[i] - '0'; 3574 serial *= 10, serial += ee[i] - '0';
3189 } 3575 }
3190 } else { 3576 } else {
3191 unsigned short type; 3577 unsigned short type;
3192 int offset = 4*16; 3578 int offset = 4*16;
3193 3579
3194 for(; offset < 8*16; offset += 16) { 3580 for(; offset < 8*16; offset += 16) {
3195 unsigned short checksum = 0; 3581 unsigned short checksum = 0;
3196 /* verify the checksum */ 3582 /* verify the checksum */
3197 for(i = 0; i<14; i++) checksum += ee[i+offset]; 3583 for(i = 0; i<14; i++) checksum += ee[i+offset];
3198 checksum = ~checksum; /* no idea why */ 3584 checksum = ~checksum; /* no idea why */
3199 if ((((checksum>>8)&0x0FF) == ee[offset+14]) && 3585 if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
3200 ((checksum & 0x0FF) == ee[offset+15])) { 3586 ((checksum & 0x0FF) == ee[offset+15])) {
3201 break; 3587 break;
3202 } 3588 }
3203 } 3589 }
3204 3590
3205 if (offset >= 8*16) 3591 if (offset >= 8*16)
3206 return; 3592 return;
3207 3593
3208 /* found a valid descriptor */ 3594 /* found a valid descriptor */
@@ -3212,47 +3598,47 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3212 3598
3213 /* 848 based */ 3599 /* 848 based */
3214 case 0x0004: 3600 case 0x0004:
3215 btv->c.type = BTTV_OSPREY1x0_848; 3601 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3216 break; 3602 break;
3217 case 0x0005: 3603 case 0x0005:
3218 btv->c.type = BTTV_OSPREY101_848; 3604 btv->c.type = BTTV_BOARD_OSPREY101_848;
3219 break; 3605 break;
3220 3606
3221 /* 878 based */ 3607 /* 878 based */
3222 case 0x0012: 3608 case 0x0012:
3223 case 0x0013: 3609 case 0x0013:
3224 btv->c.type = BTTV_OSPREY1x0; 3610 btv->c.type = BTTV_BOARD_OSPREY1x0;
3225 break; 3611 break;
3226 case 0x0014: 3612 case 0x0014:
3227 case 0x0015: 3613 case 0x0015:
3228 btv->c.type = BTTV_OSPREY1x1; 3614 btv->c.type = BTTV_BOARD_OSPREY1x1;
3229 break; 3615 break;
3230 case 0x0016: 3616 case 0x0016:
3231 case 0x0017: 3617 case 0x0017:
3232 case 0x0020: 3618 case 0x0020:
3233 btv->c.type = BTTV_OSPREY1x1_SVID; 3619 btv->c.type = BTTV_BOARD_OSPREY1x1_SVID;
3234 break; 3620 break;
3235 case 0x0018: 3621 case 0x0018:
3236 case 0x0019: 3622 case 0x0019:
3237 case 0x001E: 3623 case 0x001E:
3238 case 0x001F: 3624 case 0x001F:
3239 btv->c.type = BTTV_OSPREY2xx; 3625 btv->c.type = BTTV_BOARD_OSPREY2xx;
3240 break; 3626 break;
3241 case 0x001A: 3627 case 0x001A:
3242 case 0x001B: 3628 case 0x001B:
3243 btv->c.type = BTTV_OSPREY2x0_SVID; 3629 btv->c.type = BTTV_BOARD_OSPREY2x0_SVID;
3244 break; 3630 break;
3245 case 0x0040: 3631 case 0x0040:
3246 btv->c.type = BTTV_OSPREY500; 3632 btv->c.type = BTTV_BOARD_OSPREY500;
3247 break; 3633 break;
3248 case 0x0050: 3634 case 0x0050:
3249 case 0x0056: 3635 case 0x0056:
3250 btv->c.type = BTTV_OSPREY540; 3636 btv->c.type = BTTV_BOARD_OSPREY540;
3251 /* bttv_osprey_540_init(btv); */ 3637 /* bttv_osprey_540_init(btv); */
3252 break; 3638 break;
3253 case 0x0060: 3639 case 0x0060:
3254 case 0x0070: 3640 case 0x0070:
3255 btv->c.type = BTTV_OSPREY2x0; 3641 btv->c.type = BTTV_BOARD_OSPREY2x0;
3256 /* enable output on select control lines */ 3642 /* enable output on select control lines */
3257 gpio_inout(0xffffff,0x000303); 3643 gpio_inout(0xffffff,0x000303);
3258 break; 3644 break;
@@ -3274,27 +3660,27 @@ static void __devinit osprey_eeprom(struct bttv *btv)
3274/* AVermedia specific stuff, from bktr_card.c */ 3660/* AVermedia specific stuff, from bktr_card.c */
3275 3661
3276static int tuner_0_table[] = { 3662static int tuner_0_table[] = {
3277 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/, 3663 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
3278 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/, 3664 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
3279 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL, 3665 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
3280 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM, 3666 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
3281 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL, 3667 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
3282 TUNER_PHILIPS_FM1216ME_MK3 }; 3668 TUNER_PHILIPS_FM1216ME_MK3 };
3283 3669
3284static int tuner_1_table[] = { 3670static int tuner_1_table[] = {
3285 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL, 3671 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
3286 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3672 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3287 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL, 3673 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3288 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */ 3674 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
3289 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL}; 3675 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
3290 3676
3291static void __devinit avermedia_eeprom(struct bttv *btv) 3677static void __devinit avermedia_eeprom(struct bttv *btv)
3292{ 3678{
3293 int tuner_make,tuner_tv_fm,tuner_format,tuner=0; 3679 int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
3294 3680
3295 tuner_make = (eeprom_data[0x41] & 0x7); 3681 tuner_make = (eeprom_data[0x41] & 0x7);
3296 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3; 3682 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
3297 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4; 3683 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
3298 btv->has_remote = (eeprom_data[0x42] & 0x01); 3684 btv->has_remote = (eeprom_data[0x42] & 0x01);
3299 3685
3300 if (tuner_make == 0 || tuner_make == 2) 3686 if (tuner_make == 0 || tuner_make == 2)
@@ -3325,13 +3711,13 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3325{ 3711{
3326 /* fix up our card entry */ 3712 /* fix up our card entry */
3327 if(norm==VIDEO_MODE_NTSC) { 3713 if(norm==VIDEO_MODE_NTSC) {
3328 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x957fff; 3714 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x957fff;
3329 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x957fff; 3715 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x957fff;
3330 dprintk("bttv_tda9880_setnorm to NTSC\n"); 3716 dprintk("bttv_tda9880_setnorm to NTSC\n");
3331 } 3717 }
3332 else { 3718 else {
3333 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[0]=0x947fff; 3719 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[0]=0x947fff;
3334 bttv_tvcards[BTTV_VOODOOTV_FM].audiomux[4]=0x947fff; 3720 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].audiomux[4]=0x947fff;
3335 dprintk("bttv_tda9880_setnorm to PAL\n"); 3721 dprintk("bttv_tda9880_setnorm to PAL\n");
3336 } 3722 }
3337 /* set GPIO according */ 3723 /* set GPIO according */
@@ -3342,7 +3728,7 @@ void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3342 3728
3343/* 3729/*
3344 * reset/enable the MSP on some Hauppauge cards 3730 * reset/enable the MSP on some Hauppauge cards
3345 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)! 3731 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
3346 * 3732 *
3347 * Hauppauge: pin 5 3733 * Hauppauge: pin 5
3348 * Voodoo: pin 20 3734 * Voodoo: pin 20
@@ -3353,7 +3739,7 @@ static void __devinit boot_msp34xx(struct bttv *btv, int pin)
3353 3739
3354 gpio_inout(mask,mask); 3740 gpio_inout(mask,mask);
3355 gpio_bits(mask,0); 3741 gpio_bits(mask,0);
3356 udelay(2500); 3742 udelay(2500);
3357 gpio_bits(mask,mask); 3743 gpio_bits(mask,mask);
3358 3744
3359 if (bttv_gpio) 3745 if (bttv_gpio)
@@ -3429,7 +3815,7 @@ static void __devinit init_PXC200(struct bttv *btv)
3429 udelay(10); 3815 udelay(10);
3430 gpio_write(1<<2); 3816 gpio_write(1<<2);
3431 3817
3432 for (i = 0; i < ARRAY_SIZE(vals); i++) { 3818 for (i = 0; i < ARRAY_SIZE(vals); i++) {
3433 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1); 3819 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1);
3434 if (tmp != -1) { 3820 if (tmp != -1) {
3435 printk(KERN_INFO 3821 printk(KERN_INFO
@@ -3872,30 +4258,30 @@ avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
3872static void 4258static void
3873lt9415_audio(struct bttv *btv, struct video_audio *v, int set) 4259lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
3874{ 4260{
3875 int val = 0; 4261 int val = 0;
3876 4262
3877 if (gpio_read() & 0x4000) { 4263 if (gpio_read() & 0x4000) {
3878 v->mode = VIDEO_SOUND_MONO; 4264 v->mode = VIDEO_SOUND_MONO;
3879 return; 4265 return;
3880 } 4266 }
3881 4267
3882 if (set) { 4268 if (set) {
3883 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */ 4269 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
3884 val = 0x0080; 4270 val = 0x0080;
3885 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */ 4271 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
3886 val = 0x0880; 4272 val = 0x0880;
3887 if ((v->mode & VIDEO_SOUND_LANG1) || 4273 if ((v->mode & VIDEO_SOUND_LANG1) ||
3888 (v->mode & VIDEO_SOUND_MONO)) 4274 (v->mode & VIDEO_SOUND_MONO))
3889 val = 0; 4275 val = 0;
3890 gpio_bits(0x0880, val); 4276 gpio_bits(0x0880, val);
3891 if (bttv_gpio) 4277 if (bttv_gpio)
3892 bttv_gpio_tracking(btv,"lt9415"); 4278 bttv_gpio_tracking(btv,"lt9415");
3893 } else { 4279 } else {
3894 /* autodetect doesn't work with this card :-( */ 4280 /* autodetect doesn't work with this card :-( */
3895 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | 4281 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
3896 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 4282 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
3897 return; 4283 return;
3898 } 4284 }
3899} 4285}
3900 4286
3901/* TDA9821 on TerraTV+ Bt848, Bt878 */ 4287/* TDA9821 on TerraTV+ Bt848, Bt878 */
@@ -4018,26 +4404,26 @@ fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
4018static void 4404static void
4019windvr_audio(struct bttv *btv, struct video_audio *v, int set) 4405windvr_audio(struct bttv *btv, struct video_audio *v, int set)
4020{ 4406{
4021 unsigned long val = 0; 4407 unsigned long val = 0;
4022 4408
4023 if (set) { 4409 if (set) {
4024 if (v->mode & VIDEO_SOUND_MONO) 4410 if (v->mode & VIDEO_SOUND_MONO)
4025 val = 0x040000; 4411 val = 0x040000;
4026 if (v->mode & VIDEO_SOUND_LANG1) 4412 if (v->mode & VIDEO_SOUND_LANG1)
4027 val = 0; 4413 val = 0;
4028 if (v->mode & VIDEO_SOUND_LANG2) 4414 if (v->mode & VIDEO_SOUND_LANG2)
4029 val = 0x100000; 4415 val = 0x100000;
4030 if (v->mode & VIDEO_SOUND_STEREO) 4416 if (v->mode & VIDEO_SOUND_STEREO)
4031 val = 0; 4417 val = 0;
4032 if (val) { 4418 if (val) {
4033 gpio_bits(0x140000, val); 4419 gpio_bits(0x140000, val);
4034 if (bttv_gpio) 4420 if (bttv_gpio)
4035 bttv_gpio_tracking(btv,"windvr"); 4421 bttv_gpio_tracking(btv,"windvr");
4036 } 4422 }
4037 } else { 4423 } else {
4038 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO | 4424 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4039 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; 4425 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4040 } 4426 }
4041} 4427}
4042 4428
4043/* 4429/*
@@ -4280,10 +4666,10 @@ static void kodicom4400r_init(struct bttv *btv)
4280static void xguard_muxsel(struct bttv *btv, unsigned int input) 4666static void xguard_muxsel(struct bttv *btv, unsigned int input)
4281{ 4667{
4282 static const int masks[] = { 4668 static const int masks[] = {
4283 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10, 4669 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
4284 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10, 4670 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
4285 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11, 4671 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
4286 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11, 4672 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
4287 }; 4673 };
4288 gpio_write(masks[input%16]); 4674 gpio_write(masks[input%16]);
4289} 4675}
@@ -4388,10 +4774,10 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
4388 4774
4389static void PXC200_muxsel(struct bttv *btv, unsigned int input) 4775static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4390{ 4776{
4391 int rc; 4777 int rc;
4392 long mux; 4778 long mux;
4393 int bitmask; 4779 int bitmask;
4394 unsigned char buf[2]; 4780 unsigned char buf[2];
4395 4781
4396 /* Read PIC config to determine if this is a PXC200F */ 4782 /* Read PIC config to determine if this is a PXC200F */
4397 /* PX_I2C_CMD_CFG*/ 4783 /* PX_I2C_CMD_CFG*/
@@ -4421,14 +4807,14 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4421 /* bitmask=0x30f; */ 4807 /* bitmask=0x30f; */
4422 bitmask=0x302; 4808 bitmask=0x302;
4423 /* check whether we have a PXC200A */ 4809 /* check whether we have a PXC200A */
4424 if (btv->cardid == PX_PXC200A_CARDID) { 4810 if (btv->cardid == PX_PXC200A_CARDID) {
4425 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */ 4811 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
4426 bitmask |= 7<<4; /* the DAC */ 4812 bitmask |= 7<<4; /* the DAC */
4427 } 4813 }
4428 btwrite(bitmask, BT848_GPIO_OUT_EN); 4814 btwrite(bitmask, BT848_GPIO_OUT_EN);
4429 4815
4430 bitmask = btread(BT848_GPIO_DATA); 4816 bitmask = btread(BT848_GPIO_DATA);
4431 if (btv->cardid == PX_PXC200A_CARDID) 4817 if (btv->cardid == PX_PXC200A_CARDID)
4432 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7); 4818 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7);
4433 else /* older device */ 4819 else /* older device */
4434 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8); 4820 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8);
@@ -4441,7 +4827,7 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4441 * 4827 *
4442 * needed because bttv-driver sets mux before calling this function 4828 * needed because bttv-driver sets mux before calling this function
4443 */ 4829 */
4444 if (btv->cardid == PX_PXC200A_CARDID) 4830 if (btv->cardid == PX_PXC200A_CARDID)
4445 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM); 4831 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM);
4446 else /* older device */ 4832 else /* older device */
4447 btand(~BT848_IFORM_MUXSEL,BT848_IFORM); 4833 btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
@@ -4485,10 +4871,9 @@ void __devinit bttv_check_chipset(void)
4485 } 4871 }
4486 if (UNSET != latency) 4872 if (UNSET != latency)
4487 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency); 4873 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
4488 4874 while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
4489 while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL,
4490 PCI_DEVICE_ID_INTEL_82441, dev))) { 4875 PCI_DEVICE_ID_INTEL_82441, dev))) {
4491 unsigned char b; 4876 unsigned char b;
4492 pci_read_config_byte(dev, 0x53, &b); 4877 pci_read_config_byte(dev, 0x53, &b);
4493 if (bttv_debug) 4878 if (bttv_debug)
4494 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, " 4879 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "
@@ -4498,7 +4883,7 @@ void __devinit bttv_check_chipset(void)
4498 4883
4499int __devinit bttv_handle_chipset(struct bttv *btv) 4884int __devinit bttv_handle_chipset(struct bttv *btv)
4500{ 4885{
4501 unsigned char command; 4886 unsigned char command;
4502 4887
4503 if (!triton1 && !vsfx && UNSET == latency) 4888 if (!triton1 && !vsfx && UNSET == latency)
4504 return 0; 4889 return 0;
@@ -4519,13 +4904,13 @@ int __devinit bttv_handle_chipset(struct bttv *btv)
4519 btv->triton1 = BT848_INT_ETBF; 4904 btv->triton1 = BT848_INT_ETBF;
4520 } else { 4905 } else {
4521 /* bt878 has a bit in the pci config space for it */ 4906 /* bt878 has a bit in the pci config space for it */
4522 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command); 4907 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
4523 if (triton1) 4908 if (triton1)
4524 command |= BT878_EN_TBFX; 4909 command |= BT878_EN_TBFX;
4525 if (vsfx) 4910 if (vsfx)
4526 command |= BT878_EN_VSFX; 4911 command |= BT878_EN_VSFX;
4527 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command); 4912 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
4528 } 4913 }
4529 if (UNSET != latency) 4914 if (UNSET != latency)
4530 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency); 4915 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency);
4531 return 0; 4916 return 0;
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index c062a017491e..0005741d5514 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -3,7 +3,7 @@
3 bttv - Bt848 frame grabber driver 3 bttv - Bt848 frame grabber driver
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de> 5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
6 & Marcus Metzler <mocm@thp.uni-koeln.de> 6 & Marcus Metzler <mocm@thp.uni-koeln.de>
7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org> 7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
8 8
9 some v4l2 code lines are taken from Justin's bttv2 driver which is 9 some v4l2 code lines are taken from Justin's bttv2 driver which is
@@ -192,8 +192,8 @@ static u8 SRAM_Table[][60] =
192 192
193const struct bttv_tvnorm bttv_tvnorms[] = { 193const struct bttv_tvnorm bttv_tvnorms[] = {
194 /* PAL-BDGHI */ 194 /* PAL-BDGHI */
195 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ 195 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
196 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ 196 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
197 { 197 {
198 .v4l2_id = V4L2_STD_PAL, 198 .v4l2_id = V4L2_STD_PAL,
199 .name = "PAL", 199 .name = "PAL",
@@ -806,9 +806,9 @@ static void bt848A_set_timing(struct bttv *btv)
806 btv->c.nr,table_idx); 806 btv->c.nr,table_idx);
807 807
808 /* timing change...reset timing generator address */ 808 /* timing change...reset timing generator address */
809 btwrite(0x00, BT848_TGCTRL); 809 btwrite(0x00, BT848_TGCTRL);
810 btwrite(0x02, BT848_TGCTRL); 810 btwrite(0x02, BT848_TGCTRL);
811 btwrite(0x00, BT848_TGCTRL); 811 btwrite(0x00, BT848_TGCTRL);
812 812
813 len=SRAM_Table[table_idx][0]; 813 len=SRAM_Table[table_idx][0];
814 for(i = 1; i <= len; i++) 814 for(i = 1; i <= len; i++)
@@ -847,7 +847,7 @@ static void bt848_hue(struct bttv *btv, int hue)
847 847
848 /* -128 to 127 */ 848 /* -128 to 127 */
849 value = (hue >> 8) - 128; 849 value = (hue >> 8) - 128;
850 btwrite(value & 0xff, BT848_HUE); 850 btwrite(value & 0xff, BT848_HUE);
851} 851}
852 852
853static void bt848_contrast(struct bttv *btv, int cont) 853static void bt848_contrast(struct bttv *btv, int cont)
@@ -859,9 +859,9 @@ static void bt848_contrast(struct bttv *btv, int cont)
859 /* 0-511 */ 859 /* 0-511 */
860 value = (cont >> 7); 860 value = (cont >> 7);
861 hibit = (value >> 6) & 4; 861 hibit = (value >> 6) & 4;
862 btwrite(value & 0xff, BT848_CONTRAST_LO); 862 btwrite(value & 0xff, BT848_CONTRAST_LO);
863 btaor(hibit, ~4, BT848_E_CONTROL); 863 btaor(hibit, ~4, BT848_E_CONTROL);
864 btaor(hibit, ~4, BT848_O_CONTROL); 864 btaor(hibit, ~4, BT848_O_CONTROL);
865} 865}
866 866
867static void bt848_sat(struct bttv *btv, int color) 867static void bt848_sat(struct bttv *btv, int color)
@@ -873,12 +873,12 @@ static void bt848_sat(struct bttv *btv, int color)
873 /* 0-511 for the color */ 873 /* 0-511 for the color */
874 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; 874 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
875 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; 875 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
876 hibits = (val_u >> 7) & 2; 876 hibits = (val_u >> 7) & 2;
877 hibits |= (val_v >> 8) & 1; 877 hibits |= (val_v >> 8) & 1;
878 btwrite(val_u & 0xff, BT848_SAT_U_LO); 878 btwrite(val_u & 0xff, BT848_SAT_U_LO);
879 btwrite(val_v & 0xff, BT848_SAT_V_LO); 879 btwrite(val_v & 0xff, BT848_SAT_V_LO);
880 btaor(hibits, ~3, BT848_E_CONTROL); 880 btaor(hibits, ~3, BT848_E_CONTROL);
881 btaor(hibits, ~3, BT848_O_CONTROL); 881 btaor(hibits, ~3, BT848_O_CONTROL);
882} 882}
883 883
884/* ----------------------------------------------------------------------- */ 884/* ----------------------------------------------------------------------- */
@@ -891,7 +891,7 @@ video_mux(struct bttv *btv, unsigned int input)
891 if (input >= bttv_tvcards[btv->c.type].video_inputs) 891 if (input >= bttv_tvcards[btv->c.type].video_inputs)
892 return -EINVAL; 892 return -EINVAL;
893 893
894 /* needed by RemoteVideo MX */ 894 /* needed by RemoteVideo MX */
895 mask2 = bttv_tvcards[btv->c.type].gpiomask2; 895 mask2 = bttv_tvcards[btv->c.type].gpiomask2;
896 if (mask2) 896 if (mask2)
897 gpio_inout(mask2,mask2); 897 gpio_inout(mask2,mask2);
@@ -964,7 +964,7 @@ i2c_vidiocschan(struct bttv *btv)
964 c.norm = btv->tvnorm; 964 c.norm = btv->tvnorm;
965 c.channel = btv->input; 965 c.channel = btv->input;
966 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c); 966 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
967 if (btv->c.type == BTTV_VOODOOTV_FM) 967 if (btv->c.type == BTTV_BOARD_VOODOOTV_FM)
968 bttv_tda9880_setnorm(btv,c.norm); 968 bttv_tda9880_setnorm(btv,c.norm);
969} 969}
970 970
@@ -988,7 +988,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
988 bt848A_set_timing(btv); 988 bt848A_set_timing(btv);
989 989
990 switch (btv->c.type) { 990 switch (btv->c.type) {
991 case BTTV_VOODOOTV_FM: 991 case BTTV_BOARD_VOODOOTV_FM:
992 bttv_tda9880_setnorm(btv,norm); 992 bttv_tda9880_setnorm(btv,norm);
993 break; 993 break;
994 } 994 }
@@ -1055,22 +1055,22 @@ static void init_bt848(struct bttv *btv)
1055 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); 1055 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
1056 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM); 1056 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
1057 1057
1058 /* set planar and packed mode trigger points and */ 1058 /* set planar and packed mode trigger points and */
1059 /* set rising edge of inverted GPINTR pin as irq trigger */ 1059 /* set rising edge of inverted GPINTR pin as irq trigger */
1060 btwrite(BT848_GPIO_DMA_CTL_PKTP_32| 1060 btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
1061 BT848_GPIO_DMA_CTL_PLTP1_16| 1061 BT848_GPIO_DMA_CTL_PLTP1_16|
1062 BT848_GPIO_DMA_CTL_PLTP23_16| 1062 BT848_GPIO_DMA_CTL_PLTP23_16|
1063 BT848_GPIO_DMA_CTL_GPINTC| 1063 BT848_GPIO_DMA_CTL_GPINTC|
1064 BT848_GPIO_DMA_CTL_GPINTI, 1064 BT848_GPIO_DMA_CTL_GPINTI,
1065 BT848_GPIO_DMA_CTL); 1065 BT848_GPIO_DMA_CTL);
1066 1066
1067 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0; 1067 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1068 btwrite(val, BT848_E_SCLOOP); 1068 btwrite(val, BT848_E_SCLOOP);
1069 btwrite(val, BT848_O_SCLOOP); 1069 btwrite(val, BT848_O_SCLOOP);
1070 1070
1071 btwrite(0x20, BT848_E_VSCALE_HI); 1071 btwrite(0x20, BT848_E_VSCALE_HI);
1072 btwrite(0x20, BT848_O_VSCALE_HI); 1072 btwrite(0x20, BT848_O_VSCALE_HI);
1073 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0), 1073 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1074 BT848_ADC); 1074 BT848_ADC);
1075 1075
1076 btwrite(whitecrush_upper, BT848_WC_UP); 1076 btwrite(whitecrush_upper, BT848_WC_UP);
@@ -1089,7 +1089,7 @@ static void init_bt848(struct bttv *btv)
1089 bt848_contrast(btv, btv->contrast); 1089 bt848_contrast(btv, btv->contrast);
1090 bt848_sat(btv, btv->saturation); 1090 bt848_sat(btv, btv->saturation);
1091 1091
1092 /* interrupt */ 1092 /* interrupt */
1093 init_irqreg(btv); 1093 init_irqreg(btv);
1094} 1094}
1095 1095
@@ -1105,7 +1105,7 @@ static void bttv_reinit_bt848(struct bttv *btv)
1105 spin_unlock_irqrestore(&btv->s_lock,flags); 1105 spin_unlock_irqrestore(&btv->s_lock,flags);
1106 1106
1107 init_bt848(btv); 1107 init_bt848(btv);
1108 btv->pll.pll_current = -1; 1108 btv->pll.pll_current = -1;
1109 set_input(btv,btv->input); 1109 set_input(btv,btv->input);
1110} 1110}
1111 1111
@@ -1398,7 +1398,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
1398/* video4linux (1) interface */ 1398/* video4linux (1) interface */
1399 1399
1400static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf, 1400static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
1401 const struct bttv_format *fmt, 1401 const struct bttv_format *fmt,
1402 unsigned int width, unsigned int height, 1402 unsigned int width, unsigned int height,
1403 enum v4l2_field field) 1403 enum v4l2_field field)
1404{ 1404{
@@ -1521,8 +1521,8 @@ static const char *v4l1_ioctls[] = {
1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) 1521static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1522{ 1522{
1523 switch (cmd) { 1523 switch (cmd) {
1524 case BTTV_VERSION: 1524 case BTTV_VERSION:
1525 return BTTV_VERSION_CODE; 1525 return BTTV_VERSION_CODE;
1526 1526
1527 /* *** v4l1 *** ************************************************ */ 1527 /* *** v4l1 *** ************************************************ */
1528 case VIDIOCGFREQ: 1528 case VIDIOCGFREQ:
@@ -1576,32 +1576,32 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1576 return 0; 1576 return 0;
1577 } 1577 }
1578 1578
1579 case VIDIOCGCHAN: 1579 case VIDIOCGCHAN:
1580 { 1580 {
1581 struct video_channel *v = arg; 1581 struct video_channel *v = arg;
1582 unsigned int channel = v->channel; 1582 unsigned int channel = v->channel;
1583 1583
1584 if (channel >= bttv_tvcards[btv->c.type].video_inputs) 1584 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1585 return -EINVAL; 1585 return -EINVAL;
1586 v->tuners=0; 1586 v->tuners=0;
1587 v->flags = VIDEO_VC_AUDIO; 1587 v->flags = VIDEO_VC_AUDIO;
1588 v->type = VIDEO_TYPE_CAMERA; 1588 v->type = VIDEO_TYPE_CAMERA;
1589 v->norm = btv->tvnorm; 1589 v->norm = btv->tvnorm;
1590 if (channel == bttv_tvcards[btv->c.type].tuner) { 1590 if (channel == bttv_tvcards[btv->c.type].tuner) {
1591 strcpy(v->name,"Television"); 1591 strcpy(v->name,"Television");
1592 v->flags|=VIDEO_VC_TUNER; 1592 v->flags|=VIDEO_VC_TUNER;
1593 v->type=VIDEO_TYPE_TV; 1593 v->type=VIDEO_TYPE_TV;
1594 v->tuners=1; 1594 v->tuners=1;
1595 } else if (channel == btv->svhs) { 1595 } else if (channel == btv->svhs) {
1596 strcpy(v->name,"S-Video"); 1596 strcpy(v->name,"S-Video");
1597 } else { 1597 } else {
1598 sprintf(v->name,"Composite%d",channel); 1598 sprintf(v->name,"Composite%d",channel);
1599 } 1599 }
1600 return 0; 1600 return 0;
1601 } 1601 }
1602 case VIDIOCSCHAN: 1602 case VIDIOCSCHAN:
1603 { 1603 {
1604 struct video_channel *v = arg; 1604 struct video_channel *v = arg;
1605 unsigned int channel = v->channel; 1605 unsigned int channel = v->channel;
1606 1606
1607 if (channel >= bttv_tvcards[btv->c.type].video_inputs) 1607 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
@@ -1623,7 +1623,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1623 return 0; 1623 return 0;
1624 } 1624 }
1625 1625
1626 case VIDIOCGAUDIO: 1626 case VIDIOCGAUDIO:
1627 { 1627 {
1628 struct video_audio *v = arg; 1628 struct video_audio *v = arg;
1629 1629
@@ -1728,7 +1728,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1728 } else if (i->index == btv->svhs) { 1728 } else if (i->index == btv->svhs) {
1729 sprintf(i->name, "S-Video"); 1729 sprintf(i->name, "S-Video");
1730 } else { 1730 } else {
1731 sprintf(i->name,"Composite%d",i->index); 1731 sprintf(i->name,"Composite%d",i->index);
1732 } 1732 }
1733 if (i->index == btv->input) { 1733 if (i->index == btv->input) {
1734 __u32 dstatus = btread(BT848_DSTATUS); 1734 __u32 dstatus = btread(BT848_DSTATUS);
@@ -1851,6 +1851,11 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1851 up(&btv->lock); 1851 up(&btv->lock);
1852 return 0; 1852 return 0;
1853 } 1853 }
1854 case VIDIOC_LOG_STATUS:
1855 {
1856 bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, 0);
1857 return 0;
1858 }
1854 1859
1855 default: 1860 default:
1856 return -ENOIOCTLCMD; 1861 return -ENOIOCTLCMD;
@@ -1951,8 +1956,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
1951 } 1956 }
1952 1957
1953 down(&fh->cap.lock); 1958 down(&fh->cap.lock);
1954 if (fh->ov.clips) 1959 kfree(fh->ov.clips);
1955 kfree(fh->ov.clips);
1956 fh->ov.clips = clips; 1960 fh->ov.clips = clips;
1957 fh->ov.nclips = n; 1961 fh->ov.nclips = n;
1958 1962
@@ -2164,7 +2168,7 @@ static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
2164 if (0 != retval) 2168 if (0 != retval)
2165 return retval; 2169 return retval;
2166 if (locked_btres(fh->btv, RESOURCE_VBI)) 2170 if (locked_btres(fh->btv, RESOURCE_VBI))
2167 return -EBUSY; 2171 return -EBUSY;
2168 bttv_vbi_try_fmt(fh,f); 2172 bttv_vbi_try_fmt(fh,f);
2169 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]); 2173 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
2170 bttv_vbi_get_fmt(fh,f); 2174 bttv_vbi_get_fmt(fh,f);
@@ -2202,9 +2206,9 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2202 bttv_reinit_bt848(btv); 2206 bttv_reinit_bt848(btv);
2203 2207
2204 switch (cmd) { 2208 switch (cmd) {
2205 case VIDIOCSFREQ: 2209 case VIDIOCSFREQ:
2206 case VIDIOCSTUNER: 2210 case VIDIOCSTUNER:
2207 case VIDIOCSCHAN: 2211 case VIDIOCSCHAN:
2208 case VIDIOC_S_CTRL: 2212 case VIDIOC_S_CTRL:
2209 case VIDIOC_S_STD: 2213 case VIDIOC_S_STD:
2210 case VIDIOC_S_INPUT: 2214 case VIDIOC_S_INPUT:
@@ -2220,10 +2224,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2220 /* *** v4l1 *** ************************************************ */ 2224 /* *** v4l1 *** ************************************************ */
2221 case VIDIOCGCAP: 2225 case VIDIOCGCAP:
2222 { 2226 {
2223 struct video_capability *cap = arg; 2227 struct video_capability *cap = arg;
2224 2228
2225 memset(cap,0,sizeof(*cap)); 2229 memset(cap,0,sizeof(*cap));
2226 strcpy(cap->name,btv->video_dev->name); 2230 strcpy(cap->name,btv->video_dev->name);
2227 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { 2231 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2228 /* vbi */ 2232 /* vbi */
2229 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT; 2233 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
@@ -2243,7 +2247,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2243 } 2247 }
2244 cap->channels = bttv_tvcards[btv->c.type].video_inputs; 2248 cap->channels = bttv_tvcards[btv->c.type].video_inputs;
2245 cap->audios = bttv_tvcards[btv->c.type].audio_inputs; 2249 cap->audios = bttv_tvcards[btv->c.type].audio_inputs;
2246 return 0; 2250 return 0;
2247 } 2251 }
2248 2252
2249 case VIDIOCGPICT: 2253 case VIDIOCGPICT:
@@ -2292,7 +2296,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2292 bt848_hue(btv,pic->hue); 2296 bt848_hue(btv,pic->hue);
2293 bt848_sat(btv,pic->colour); 2297 bt848_sat(btv,pic->colour);
2294 up(&fh->cap.lock); 2298 up(&fh->cap.lock);
2295 return 0; 2299 return 0;
2296 } 2300 }
2297 2301
2298 case VIDIOCGWIN: 2302 case VIDIOCGWIN:
@@ -2353,8 +2357,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2353 unsigned long end; 2357 unsigned long end;
2354 2358
2355 if(!capable(CAP_SYS_ADMIN) && 2359 if(!capable(CAP_SYS_ADMIN) &&
2356 !capable(CAP_SYS_RAWIO)) 2360 !capable(CAP_SYS_RAWIO))
2357 return -EPERM; 2361 return -EPERM;
2358 end = (unsigned long)fbuf->base + 2362 end = (unsigned long)fbuf->base +
2359 fbuf->height * fbuf->bytesperline; 2363 fbuf->height * fbuf->bytesperline;
2360 down(&fh->cap.lock); 2364 down(&fh->cap.lock);
@@ -2428,7 +2432,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2428 } 2432 }
2429 2433
2430 /* switch over */ 2434 /* switch over */
2431 retval = bttv_switch_overlay(btv,fh,new); 2435 retval = bttv_switch_overlay(btv,fh,new);
2432 up(&fh->cap.lock); 2436 up(&fh->cap.lock);
2433 return retval; 2437 return retval;
2434 } 2438 }
@@ -2567,13 +2571,13 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2567 return 0; 2571 return 0;
2568 } 2572 }
2569 2573
2570 case BTTV_VERSION: 2574 case BTTV_VERSION:
2571 case VIDIOCGFREQ: 2575 case VIDIOCGFREQ:
2572 case VIDIOCSFREQ: 2576 case VIDIOCSFREQ:
2573 case VIDIOCGTUNER: 2577 case VIDIOCGTUNER:
2574 case VIDIOCSTUNER: 2578 case VIDIOCSTUNER:
2575 case VIDIOCGCHAN: 2579 case VIDIOCGCHAN:
2576 case VIDIOCSCHAN: 2580 case VIDIOCSCHAN:
2577 case VIDIOCGAUDIO: 2581 case VIDIOCGAUDIO:
2578 case VIDIOCSAUDIO: 2582 case VIDIOCSAUDIO:
2579 return bttv_common_ioctls(btv,cmd,arg); 2583 return bttv_common_ioctls(btv,cmd,arg);
@@ -2585,8 +2589,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2585 2589
2586 if (0 == v4l2) 2590 if (0 == v4l2)
2587 return -EINVAL; 2591 return -EINVAL;
2588 strcpy(cap->driver,"bttv"); 2592 strcpy(cap->driver,"bttv");
2589 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card)); 2593 strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
2590 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci)); 2594 sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci));
2591 cap->version = BTTV_VERSION_CODE; 2595 cap->version = BTTV_VERSION_CODE;
2592 cap->capabilities = 2596 cap->capabilities =
@@ -2723,8 +2727,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2723 fh->ov.w.height = fb->fmt.height; 2727 fh->ov.w.height = fb->fmt.height;
2724 btv->init.ov.w.width = fb->fmt.width; 2728 btv->init.ov.w.width = fb->fmt.width;
2725 btv->init.ov.w.height = fb->fmt.height; 2729 btv->init.ov.w.height = fb->fmt.height;
2726 if (fh->ov.clips) 2730 kfree(fh->ov.clips);
2727 kfree(fh->ov.clips);
2728 fh->ov.clips = NULL; 2731 fh->ov.clips = NULL;
2729 fh->ov.nclips = 0; 2732 fh->ov.nclips = 0;
2730 2733
@@ -2858,6 +2861,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
2858 case VIDIOC_S_TUNER: 2861 case VIDIOC_S_TUNER:
2859 case VIDIOC_G_FREQUENCY: 2862 case VIDIOC_G_FREQUENCY:
2860 case VIDIOC_S_FREQUENCY: 2863 case VIDIOC_S_FREQUENCY:
2864 case VIDIOC_LOG_STATUS:
2861 return bttv_common_ioctls(btv,cmd,arg); 2865 return bttv_common_ioctls(btv,cmd,arg);
2862 2866
2863 default: 2867 default:
@@ -3093,7 +3097,7 @@ static struct video_device bttv_video_template =
3093{ 3097{
3094 .name = "UNSET", 3098 .name = "UNSET",
3095 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER| 3099 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
3096 VID_TYPE_CLIPPING|VID_TYPE_SCALES, 3100 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
3097 .hardware = VID_HARDWARE_BT848, 3101 .hardware = VID_HARDWARE_BT848,
3098 .fops = &bttv_fops, 3102 .fops = &bttv_fops,
3099 .minor = -1, 3103 .minor = -1,
@@ -3139,7 +3143,7 @@ static int radio_open(struct inode *inode, struct file *file)
3139 audio_mux(btv,AUDIO_RADIO); 3143 audio_mux(btv,AUDIO_RADIO);
3140 3144
3141 up(&btv->lock); 3145 up(&btv->lock);
3142 return 0; 3146 return 0;
3143} 3147}
3144 3148
3145static int radio_release(struct inode *inode, struct file *file) 3149static int radio_release(struct inode *inode, struct file *file)
@@ -3162,34 +3166,34 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
3162 switch (cmd) { 3166 switch (cmd) {
3163 case VIDIOCGCAP: 3167 case VIDIOCGCAP:
3164 { 3168 {
3165 struct video_capability *cap = arg; 3169 struct video_capability *cap = arg;
3166 3170
3167 memset(cap,0,sizeof(*cap)); 3171 memset(cap,0,sizeof(*cap));
3168 strcpy(cap->name,btv->radio_dev->name); 3172 strcpy(cap->name,btv->radio_dev->name);
3169 cap->type = VID_TYPE_TUNER; 3173 cap->type = VID_TYPE_TUNER;
3170 cap->channels = 1; 3174 cap->channels = 1;
3171 cap->audios = 1; 3175 cap->audios = 1;
3172 return 0; 3176 return 0;
3173 } 3177 }
3174 3178
3175 case VIDIOCGTUNER: 3179 case VIDIOCGTUNER:
3176 { 3180 {
3177 struct video_tuner *v = arg; 3181 struct video_tuner *v = arg;
3178 3182
3179 if(v->tuner) 3183 if(v->tuner)
3180 return -EINVAL; 3184 return -EINVAL;
3181 memset(v,0,sizeof(*v)); 3185 memset(v,0,sizeof(*v));
3182 strcpy(v->name, "Radio"); 3186 strcpy(v->name, "Radio");
3183 bttv_call_i2c_clients(btv,cmd,v); 3187 bttv_call_i2c_clients(btv,cmd,v);
3184 return 0; 3188 return 0;
3185 } 3189 }
3186 case VIDIOCSTUNER: 3190 case VIDIOCSTUNER:
3187 /* nothing to do */ 3191 /* nothing to do */
3188 return 0; 3192 return 0;
3189 3193
3190 case BTTV_VERSION: 3194 case BTTV_VERSION:
3191 case VIDIOCGFREQ: 3195 case VIDIOCGFREQ:
3192 case VIDIOCSFREQ: 3196 case VIDIOCSFREQ:
3193 case VIDIOCGAUDIO: 3197 case VIDIOCGAUDIO:
3194 case VIDIOCSAUDIO: 3198 case VIDIOCSAUDIO:
3195 return bttv_common_ioctls(btv,cmd,arg); 3199 return bttv_common_ioctls(btv,cmd,arg);
@@ -3695,7 +3699,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3695 } 3699 }
3696 3700
3697 if (astat&BT848_INT_VSYNC) 3701 if (astat&BT848_INT_VSYNC)
3698 btv->field_count++; 3702 btv->field_count++;
3699 3703
3700 if (astat & BT848_INT_GPINT) { 3704 if (astat & BT848_INT_GPINT) {
3701 wake_up(&btv->gpioq); 3705 wake_up(&btv->gpioq);
@@ -3707,13 +3711,13 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3707 wake_up(&btv->i2c_queue); 3711 wake_up(&btv->i2c_queue);
3708 } 3712 }
3709 3713
3710 if ((astat & BT848_INT_RISCI) && (stat & (4<<28))) 3714 if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
3711 bttv_irq_switch_vbi(btv); 3715 bttv_irq_switch_vbi(btv);
3712 3716
3713 if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) 3717 if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
3714 bttv_irq_wakeup_top(btv); 3718 bttv_irq_wakeup_top(btv);
3715 3719
3716 if ((astat & BT848_INT_RISCI) && (stat & (1<<28))) 3720 if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
3717 bttv_irq_switch_video(btv); 3721 bttv_irq_switch_video(btv);
3718 3722
3719 if ((astat & BT848_INT_HLOCK) && btv->opt_automute) 3723 if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
@@ -3738,10 +3742,22 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3738 3742
3739 count++; 3743 count++;
3740 if (count > 4) { 3744 if (count > 4) {
3741 btwrite(0, BT848_INT_MASK); 3745
3742 printk(KERN_ERR 3746 if (count > 8 || !(astat & BT848_INT_GPINT)) {
3743 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr); 3747 btwrite(0, BT848_INT_MASK);
3748
3749 printk(KERN_ERR
3750 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
3751 } else {
3752 printk(KERN_ERR
3753 "bttv%d: IRQ lockup, clearing GPINT from int mask [", btv->c.nr);
3754
3755 btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
3756 BT848_INT_MASK);
3757 };
3758
3744 bttv_print_irqbits(stat,astat); 3759 bttv_print_irqbits(stat,astat);
3760
3745 printk("]\n"); 3761 printk("]\n");
3746 } 3762 }
3747 } 3763 }
@@ -3810,7 +3826,7 @@ static int __devinit bttv_register_video(struct bttv *btv)
3810 3826
3811 /* video */ 3827 /* video */
3812 btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); 3828 btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
3813 if (NULL == btv->video_dev) 3829 if (NULL == btv->video_dev)
3814 goto err; 3830 goto err;
3815 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0) 3831 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
3816 goto err; 3832 goto err;
@@ -3820,18 +3836,18 @@ static int __devinit bttv_register_video(struct bttv *btv)
3820 3836
3821 /* vbi */ 3837 /* vbi */
3822 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi"); 3838 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
3823 if (NULL == btv->vbi_dev) 3839 if (NULL == btv->vbi_dev)
3824 goto err; 3840 goto err;
3825 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 3841 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
3826 goto err; 3842 goto err;
3827 printk(KERN_INFO "bttv%d: registered device vbi%d\n", 3843 printk(KERN_INFO "bttv%d: registered device vbi%d\n",
3828 btv->c.nr,btv->vbi_dev->minor & 0x1f); 3844 btv->c.nr,btv->vbi_dev->minor & 0x1f);
3829 3845
3830 if (!btv->has_radio) 3846 if (!btv->has_radio)
3831 return 0; 3847 return 0;
3832 /* radio */ 3848 /* radio */
3833 btv->radio_dev = vdev_init(btv, &radio_template, "radio"); 3849 btv->radio_dev = vdev_init(btv, &radio_template, "radio");
3834 if (NULL == btv->radio_dev) 3850 if (NULL == btv->radio_dev)
3835 goto err; 3851 goto err;
3836 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) 3852 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
3837 goto err; 3853 goto err;
@@ -3852,11 +3868,11 @@ static int __devinit bttv_register_video(struct bttv *btv)
3852static void pci_set_command(struct pci_dev *dev) 3868static void pci_set_command(struct pci_dev *dev)
3853{ 3869{
3854#if defined(__powerpc__) 3870#if defined(__powerpc__)
3855 unsigned int cmd; 3871 unsigned int cmd;
3856 3872
3857 pci_read_config_dword(dev, PCI_COMMAND, &cmd); 3873 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
3858 cmd = (cmd | PCI_COMMAND_MEMORY ); 3874 cmd = (cmd | PCI_COMMAND_MEMORY );
3859 pci_write_config_dword(dev, PCI_COMMAND, cmd); 3875 pci_write_config_dword(dev, PCI_COMMAND, cmd);
3860#endif 3876#endif
3861} 3877}
3862 3878
@@ -3870,63 +3886,62 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3870 if (bttv_num == BTTV_MAX) 3886 if (bttv_num == BTTV_MAX)
3871 return -ENOMEM; 3887 return -ENOMEM;
3872 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num); 3888 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
3873 btv=&bttvs[bttv_num]; 3889 btv=&bttvs[bttv_num];
3874 memset(btv,0,sizeof(*btv)); 3890 memset(btv,0,sizeof(*btv));
3875 btv->c.nr = bttv_num; 3891 btv->c.nr = bttv_num;
3876 sprintf(btv->c.name,"bttv%d",btv->c.nr); 3892 sprintf(btv->c.name,"bttv%d",btv->c.nr);
3877 3893
3878 /* initialize structs / fill in defaults */ 3894 /* initialize structs / fill in defaults */
3879 init_MUTEX(&btv->lock); 3895 init_MUTEX(&btv->lock);
3880 init_MUTEX(&btv->reslock); 3896 init_MUTEX(&btv->reslock);
3881 spin_lock_init(&btv->s_lock); 3897 spin_lock_init(&btv->s_lock);
3882 spin_lock_init(&btv->gpio_lock); 3898 spin_lock_init(&btv->gpio_lock);
3883 init_waitqueue_head(&btv->gpioq); 3899 init_waitqueue_head(&btv->gpioq);
3884 init_waitqueue_head(&btv->i2c_queue); 3900 init_waitqueue_head(&btv->i2c_queue);
3885 INIT_LIST_HEAD(&btv->c.subs); 3901 INIT_LIST_HEAD(&btv->c.subs);
3886 INIT_LIST_HEAD(&btv->capture); 3902 INIT_LIST_HEAD(&btv->capture);
3887 INIT_LIST_HEAD(&btv->vcapture); 3903 INIT_LIST_HEAD(&btv->vcapture);
3888 v4l2_prio_init(&btv->prio); 3904 v4l2_prio_init(&btv->prio);
3889 3905
3890 init_timer(&btv->timeout); 3906 init_timer(&btv->timeout);
3891 btv->timeout.function = bttv_irq_timeout; 3907 btv->timeout.function = bttv_irq_timeout;
3892 btv->timeout.data = (unsigned long)btv; 3908 btv->timeout.data = (unsigned long)btv;
3893 3909
3894 btv->i2c_rc = -1; 3910 btv->i2c_rc = -1;
3895 btv->tuner_type = UNSET; 3911 btv->tuner_type = UNSET;
3896 btv->pinnacle_id = UNSET; 3912 btv->pinnacle_id = UNSET;
3897 btv->new_input = UNSET; 3913 btv->new_input = UNSET;
3898 btv->gpioirq = 1;
3899 btv->has_radio=radio[btv->c.nr]; 3914 btv->has_radio=radio[btv->c.nr];
3900 3915
3901 /* pci stuff (init, get irq/mmio, ... */ 3916 /* pci stuff (init, get irq/mmio, ... */
3902 btv->c.pci = dev; 3917 btv->c.pci = dev;
3903 btv->id = dev->device; 3918 btv->id = dev->device;
3904 if (pci_enable_device(dev)) { 3919 if (pci_enable_device(dev)) {
3905 printk(KERN_WARNING "bttv%d: Can't enable device.\n", 3920 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
3906 btv->c.nr); 3921 btv->c.nr);
3907 return -EIO; 3922 return -EIO;
3908 } 3923 }
3909 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) { 3924 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
3910 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n", 3925 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
3911 btv->c.nr); 3926 btv->c.nr);
3912 return -EIO; 3927 return -EIO;
3913 } 3928 }
3914 if (!request_mem_region(pci_resource_start(dev,0), 3929 if (!request_mem_region(pci_resource_start(dev,0),
3915 pci_resource_len(dev,0), 3930 pci_resource_len(dev,0),
3916 btv->c.name)) { 3931 btv->c.name)) {
3917 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", 3932 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
3918 btv->c.nr, pci_resource_start(dev,0)); 3933 btv->c.nr, pci_resource_start(dev,0));
3919 return -EBUSY; 3934 return -EBUSY;
3920 } 3935 }
3921 pci_set_master(dev); 3936 pci_set_master(dev);
3922 pci_set_command(dev); 3937 pci_set_command(dev);
3923 pci_set_drvdata(dev,btv); 3938 pci_set_drvdata(dev,btv);
3924 3939
3925 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision); 3940 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
3926 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); 3941 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
3927 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", 3942 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
3928 bttv_num,btv->id, btv->revision, pci_name(dev)); 3943 bttv_num,btv->id, btv->revision, pci_name(dev));
3929 printk("irq: %d, latency: %d, mmio: 0x%lx\n", 3944 printk("irq: %d, latency: %d, mmio: 0x%lx\n",
3930 btv->c.pci->irq, lat, pci_resource_start(dev,0)); 3945 btv->c.pci->irq, lat, pci_resource_start(dev,0));
3931 schedule(); 3946 schedule();
3932 3947
@@ -3937,23 +3952,23 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3937 goto fail1; 3952 goto fail1;
3938 } 3953 }
3939 3954
3940 /* identify card */ 3955 /* identify card */
3941 bttv_idcard(btv); 3956 bttv_idcard(btv);
3942 3957
3943 /* disable irqs, register irq handler */ 3958 /* disable irqs, register irq handler */
3944 btwrite(0, BT848_INT_MASK); 3959 btwrite(0, BT848_INT_MASK);
3945 result = request_irq(btv->c.pci->irq, bttv_irq, 3960 result = request_irq(btv->c.pci->irq, bttv_irq,
3946 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv); 3961 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
3947 if (result < 0) { 3962 if (result < 0) {
3948 printk(KERN_ERR "bttv%d: can't get IRQ %d\n", 3963 printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
3949 bttv_num,btv->c.pci->irq); 3964 bttv_num,btv->c.pci->irq);
3950 goto fail1; 3965 goto fail1;
3951 } 3966 }
3952 3967
3953 if (0 != bttv_handle_chipset(btv)) { 3968 if (0 != bttv_handle_chipset(btv)) {
3954 result = -EIO; 3969 result = -EIO;
3955 goto fail2; 3970 goto fail2;
3956 } 3971 }
3957 3972
3958 /* init options from insmod args */ 3973 /* init options from insmod args */
3959 btv->opt_combfilter = combfilter; 3974 btv->opt_combfilter = combfilter;
@@ -3979,29 +3994,29 @@ static int __devinit bttv_probe(struct pci_dev *dev,
3979 btv->input = 0; 3994 btv->input = 0;
3980 3995
3981 /* initialize hardware */ 3996 /* initialize hardware */
3982 if (bttv_gpio) 3997 if (bttv_gpio)
3983 bttv_gpio_tracking(btv,"pre-init"); 3998 bttv_gpio_tracking(btv,"pre-init");
3984 3999
3985 bttv_risc_init_main(btv); 4000 bttv_risc_init_main(btv);
3986 init_bt848(btv); 4001 init_bt848(btv);
3987 4002
3988 /* gpio */ 4003 /* gpio */
3989 btwrite(0x00, BT848_GPIO_REG_INP); 4004 btwrite(0x00, BT848_GPIO_REG_INP);
3990 btwrite(0x00, BT848_GPIO_OUT_EN); 4005 btwrite(0x00, BT848_GPIO_OUT_EN);
3991 if (bttv_verbose) 4006 if (bttv_verbose)
3992 bttv_gpio_tracking(btv,"init"); 4007 bttv_gpio_tracking(btv,"init");
3993 4008
3994 /* needs to be done before i2c is registered */ 4009 /* needs to be done before i2c is registered */
3995 bttv_init_card1(btv); 4010 bttv_init_card1(btv);
3996 4011
3997 /* register i2c + gpio */ 4012 /* register i2c + gpio */
3998 init_bttv_i2c(btv); 4013 init_bttv_i2c(btv);
3999 4014
4000 /* some card-specific stuff (needs working i2c) */ 4015 /* some card-specific stuff (needs working i2c) */
4001 bttv_init_card2(btv); 4016 bttv_init_card2(btv);
4002 init_irqreg(btv); 4017 init_irqreg(btv);
4003 4018
4004 /* register video4linux + input */ 4019 /* register video4linux + input */
4005 if (!bttv_tvcards[btv->c.type].no_video) { 4020 if (!bttv_tvcards[btv->c.type].no_video) {
4006 bttv_register_video(btv); 4021 bttv_register_video(btv);
4007 bt848_bright(btv,32768); 4022 bt848_bright(btv,32768);
@@ -4020,10 +4035,10 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4020 4035
4021 /* everything is fine */ 4036 /* everything is fine */
4022 bttv_num++; 4037 bttv_num++;
4023 return 0; 4038 return 0;
4024 4039
4025 fail2: 4040 fail2:
4026 free_irq(btv->c.pci->irq,btv); 4041 free_irq(btv->c.pci->irq,btv);
4027 4042
4028 fail1: 4043 fail1:
4029 if (btv->bt848_mmio) 4044 if (btv->bt848_mmio)
@@ -4036,12 +4051,12 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4036 4051
4037static void __devexit bttv_remove(struct pci_dev *pci_dev) 4052static void __devexit bttv_remove(struct pci_dev *pci_dev)
4038{ 4053{
4039 struct bttv *btv = pci_get_drvdata(pci_dev); 4054 struct bttv *btv = pci_get_drvdata(pci_dev);
4040 4055
4041 if (bttv_verbose) 4056 if (bttv_verbose)
4042 printk("bttv%d: unloading\n",btv->c.nr); 4057 printk("bttv%d: unloading\n",btv->c.nr);
4043 4058
4044 /* shutdown everything (DMA+IRQs) */ 4059 /* shutdown everything (DMA+IRQs) */
4045 btand(~15, BT848_GPIO_DMA_CTL); 4060 btand(~15, BT848_GPIO_DMA_CTL);
4046 btwrite(0, BT848_INT_MASK); 4061 btwrite(0, BT848_INT_MASK);
4047 btwrite(~0x0, BT848_INT_STAT); 4062 btwrite(~0x0, BT848_INT_STAT);
@@ -4054,7 +4069,7 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
4054 wake_up(&btv->gpioq); 4069 wake_up(&btv->gpioq);
4055 bttv_sub_del_devices(&btv->c); 4070 bttv_sub_del_devices(&btv->c);
4056 4071
4057 /* unregister i2c_bus + input */ 4072 /* unregister i2c_bus + input */
4058 fini_bttv_i2c(btv); 4073 fini_bttv_i2c(btv);
4059 4074
4060 /* unregister video4linux */ 4075 /* unregister video4linux */
@@ -4064,18 +4079,18 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
4064 btcx_riscmem_free(btv->c.pci,&btv->main); 4079 btcx_riscmem_free(btv->c.pci,&btv->main);
4065 4080
4066 /* free ressources */ 4081 /* free ressources */
4067 free_irq(btv->c.pci->irq,btv); 4082 free_irq(btv->c.pci->irq,btv);
4068 iounmap(btv->bt848_mmio); 4083 iounmap(btv->bt848_mmio);
4069 release_mem_region(pci_resource_start(btv->c.pci,0), 4084 release_mem_region(pci_resource_start(btv->c.pci,0),
4070 pci_resource_len(btv->c.pci,0)); 4085 pci_resource_len(btv->c.pci,0));
4071 4086
4072 pci_set_drvdata(pci_dev, NULL); 4087 pci_set_drvdata(pci_dev, NULL);
4073 return; 4088 return;
4074} 4089}
4075 4090
4076static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) 4091static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4077{ 4092{
4078 struct bttv *btv = pci_get_drvdata(pci_dev); 4093 struct bttv *btv = pci_get_drvdata(pci_dev);
4079 struct bttv_buffer_set idle; 4094 struct bttv_buffer_set idle;
4080 unsigned long flags; 4095 unsigned long flags;
4081 4096
@@ -4110,7 +4125,7 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4110 4125
4111static int bttv_resume(struct pci_dev *pci_dev) 4126static int bttv_resume(struct pci_dev *pci_dev)
4112{ 4127{
4113 struct bttv *btv = pci_get_drvdata(pci_dev); 4128 struct bttv *btv = pci_get_drvdata(pci_dev);
4114 unsigned long flags; 4129 unsigned long flags;
4115 int err; 4130 int err;
4116 4131
@@ -4155,24 +4170,24 @@ static int bttv_resume(struct pci_dev *pci_dev)
4155} 4170}
4156 4171
4157static struct pci_device_id bttv_pci_tbl[] = { 4172static struct pci_device_id bttv_pci_tbl[] = {
4158 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848, 4173 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
4159 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4174 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4160 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849, 4175 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
4161 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4176 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4162 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878, 4177 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
4163 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4178 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4164 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879, 4179 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
4165 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 4180 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4166 {0,} 4181 {0,}
4167}; 4182};
4168 4183
4169MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); 4184MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
4170 4185
4171static struct pci_driver bttv_pci_driver = { 4186static struct pci_driver bttv_pci_driver = {
4172 .name = "bttv", 4187 .name = "bttv",
4173 .id_table = bttv_pci_tbl, 4188 .id_table = bttv_pci_tbl,
4174 .probe = bttv_probe, 4189 .probe = bttv_probe,
4175 .remove = __devexit_p(bttv_remove), 4190 .remove = __devexit_p(bttv_remove),
4176 .suspend = bttv_suspend, 4191 .suspend = bttv_suspend,
4177 .resume = bttv_resume, 4192 .resume = bttv_resume,
4178}; 4193};
diff --git a/drivers/media/video/bttv-gpio.c b/drivers/media/video/bttv-gpio.c
index 6b280c03e398..575ce8b8e714 100644
--- a/drivers/media/video/bttv-gpio.c
+++ b/drivers/media/video/bttv-gpio.c
@@ -7,7 +7,7 @@
7 7
8 8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de) 10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
12 12
13 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index e684df37eb0e..77619eb131f6 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -5,7 +5,7 @@
5 bttv - Bt848 frame grabber driver 5 bttv - Bt848 frame grabber driver
6 6
7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
8 & Marcus Metzler (mocm@thp.uni-koeln.de) 8 & Marcus Metzler (mocm@thp.uni-koeln.de)
9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
10 10
11 This program is free software; you can redistribute it and/or modify 11 This program is free software; you can redistribute it and/or modify
@@ -237,7 +237,7 @@ bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
237 err: 237 err:
238 if (i2c_debug) 238 if (i2c_debug)
239 printk(" ERR: %d\n",retval); 239 printk(" ERR: %d\n",retval);
240 return retval; 240 return retval;
241} 241}
242 242
243static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 243static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
@@ -290,7 +290,13 @@ static struct i2c_adapter bttv_i2c_adap_hw_template = {
290 290
291static int attach_inform(struct i2c_client *client) 291static int attach_inform(struct i2c_client *client)
292{ 292{
293 struct bttv *btv = i2c_get_adapdata(client->adapter); 293 struct bttv *btv = i2c_get_adapdata(client->adapter);
294 int addr=ADDR_UNSET;
295
296
297 if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
298 addr = bttv_tvcards[btv->c.type].tuner_addr;
299
294 300
295 if (bttv_debug) 301 if (bttv_debug)
296 printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", 302 printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
@@ -300,19 +306,20 @@ static int attach_inform(struct i2c_client *client)
300 return 0; 306 return 0;
301 307
302 if (btv->tuner_type != UNSET) { 308 if (btv->tuner_type != UNSET) {
303 struct tuner_setup tun_setup; 309 struct tuner_setup tun_setup;
310
311 if ((addr==ADDR_UNSET) ||
312 (addr==client->addr)) {
304 313
305 tun_setup.mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV; 314 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
306 tun_setup.type = btv->tuner_type; 315 tun_setup.type = btv->tuner_type;
307 tun_setup.addr = ADDR_UNSET; 316 tun_setup.addr = addr;
317 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
318 }
308 319
309 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
310 } 320 }
311 321
312 if (btv->pinnacle_id != UNSET) 322 return 0;
313 client->driver->command(client,AUDC_CONFIG_PINNACLE,
314 &btv->pinnacle_id);
315 return 0;
316} 323}
317 324
318void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) 325void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
@@ -330,43 +337,43 @@ static struct i2c_client bttv_i2c_client_template = {
330/* read I2C */ 337/* read I2C */
331int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) 338int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
332{ 339{
333 unsigned char buffer = 0; 340 unsigned char buffer = 0;
334 341
335 if (0 != btv->i2c_rc) 342 if (0 != btv->i2c_rc)
336 return -1; 343 return -1;
337 if (bttv_verbose && NULL != probe_for) 344 if (bttv_verbose && NULL != probe_for)
338 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ", 345 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
339 btv->c.nr,probe_for,addr); 346 btv->c.nr,probe_for,addr);
340 btv->i2c_client.addr = addr >> 1; 347 btv->i2c_client.addr = addr >> 1;
341 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) { 348 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
342 if (NULL != probe_for) { 349 if (NULL != probe_for) {
343 if (bttv_verbose) 350 if (bttv_verbose)
344 printk("not found\n"); 351 printk("not found\n");
345 } else 352 } else
346 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n", 353 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
347 btv->c.nr,addr); 354 btv->c.nr,addr);
348 return -1; 355 return -1;
349 } 356 }
350 if (bttv_verbose && NULL != probe_for) 357 if (bttv_verbose && NULL != probe_for)
351 printk("found\n"); 358 printk("found\n");
352 return buffer; 359 return buffer;
353} 360}
354 361
355/* write I2C */ 362/* write I2C */
356int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, 363int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
357 unsigned char b2, int both) 364 unsigned char b2, int both)
358{ 365{
359 unsigned char buffer[2]; 366 unsigned char buffer[2];
360 int bytes = both ? 2 : 1; 367 int bytes = both ? 2 : 1;
361 368
362 if (0 != btv->i2c_rc) 369 if (0 != btv->i2c_rc)
363 return -1; 370 return -1;
364 btv->i2c_client.addr = addr >> 1; 371 btv->i2c_client.addr = addr >> 1;
365 buffer[0] = b1; 372 buffer[0] = b1;
366 buffer[1] = b2; 373 buffer[1] = b2;
367 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes)) 374 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
368 return -1; 375 return -1;
369 return 0; 376 return 0;
370} 377}
371 378
372/* read EEPROM content */ 379/* read EEPROM content */
@@ -431,8 +438,8 @@ int __devinit init_bttv_i2c(struct bttv *btv)
431 "bt%d #%d [%s]", btv->id, btv->c.nr, 438 "bt%d #%d [%s]", btv->id, btv->c.nr,
432 btv->use_i2c_hw ? "hw" : "sw"); 439 btv->use_i2c_hw ? "hw" : "sw");
433 440
434 i2c_set_adapdata(&btv->c.i2c_adap, btv); 441 i2c_set_adapdata(&btv->c.i2c_adap, btv);
435 btv->i2c_client.adapter = &btv->c.i2c_adap; 442 btv->i2c_client.adapter = &btv->c.i2c_adap;
436 443
437#ifdef I2C_CLASS_TV_ANALOG 444#ifdef I2C_CLASS_TV_ANALOG
438 if (bttv_tvcards[btv->c.type].no_video) 445 if (bttv_tvcards[btv->c.type].no_video)
diff --git a/drivers/media/video/bttv-if.c b/drivers/media/video/bttv-if.c
index e8aada772b89..19b564ab0e92 100644
--- a/drivers/media/video/bttv-if.c
+++ b/drivers/media/video/bttv-if.c
@@ -1,13 +1,13 @@
1/* 1/*
2 2
3 bttv-if.c -- old gpio interface to other kernel modules 3 bttv-if.c -- old gpio interface to other kernel modules
4 don't use in new code, will go away in 2.7 4 don't use in new code, will go away in 2.7
5 have a look at bttv-gpio.c instead. 5 have a look at bttv-gpio.c instead.
6 6
7 bttv - Bt848 frame grabber driver 7 bttv - Bt848 frame grabber driver
8 8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de) 10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
12 12
13 This program is free software; you can redistribute it and/or modify 13 This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/bttv-risc.c b/drivers/media/video/bttv-risc.c
index a5ed99b89445..b40e9734bf08 100644
--- a/drivers/media/video/bttv-risc.c
+++ b/drivers/media/video/bttv-risc.c
@@ -74,27 +74,27 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
74 } 74 }
75 if (bpl <= sg_dma_len(sg)-offset) { 75 if (bpl <= sg_dma_len(sg)-offset) {
76 /* fits into current chunk */ 76 /* fits into current chunk */
77 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| 77 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
78 BT848_RISC_EOL|bpl); 78 BT848_RISC_EOL|bpl);
79 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 79 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
80 offset+=bpl; 80 offset+=bpl;
81 } else { 81 } else {
82 /* scanline needs to be splitted */ 82 /* scanline needs to be splitted */
83 todo = bpl; 83 todo = bpl;
84 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL| 84 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
85 (sg_dma_len(sg)-offset)); 85 (sg_dma_len(sg)-offset));
86 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 86 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
87 todo -= (sg_dma_len(sg)-offset); 87 todo -= (sg_dma_len(sg)-offset);
88 offset = 0; 88 offset = 0;
89 sg++; 89 sg++;
90 while (todo > sg_dma_len(sg)) { 90 while (todo > sg_dma_len(sg)) {
91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE| 91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
92 sg_dma_len(sg)); 92 sg_dma_len(sg));
93 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 93 *(rp++)=cpu_to_le32(sg_dma_address(sg));
94 todo -= sg_dma_len(sg); 94 todo -= sg_dma_len(sg);
95 sg++; 95 sg++;
96 } 96 }
97 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL| 97 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
98 todo); 98 todo);
99 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 99 *(rp++)=cpu_to_le32(sg_dma_address(sg));
100 offset += todo; 100 offset += todo;
@@ -201,8 +201,8 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
201 ri |= BT848_RISC_EOL; 201 ri |= BT848_RISC_EOL;
202 202
203 /* write risc instruction */ 203 /* write risc instruction */
204 *(rp++)=cpu_to_le32(ri | ylen); 204 *(rp++)=cpu_to_le32(ri | ylen);
205 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) | 205 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
206 (ylen >> hshift)); 206 (ylen >> hshift));
207 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset); 207 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
208 yoffset += ylen; 208 yoffset += ylen;
@@ -319,7 +319,7 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
319 int width, int height, int interleaved, int norm) 319 int width, int height, int interleaved, int norm)
320{ 320{
321 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm]; 321 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
322 u32 xsf, sr; 322 u32 xsf, sr;
323 int vdelay; 323 int vdelay;
324 324
325 int swidth = tvnorm->swidth; 325 int swidth = tvnorm->swidth;
@@ -334,52 +334,52 @@ bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
334 334
335 vdelay = tvnorm->vdelay; 335 vdelay = tvnorm->vdelay;
336 336
337 xsf = (width*scaledtwidth)/swidth; 337 xsf = (width*scaledtwidth)/swidth;
338 geo->hscale = ((totalwidth*4096UL)/xsf-4096); 338 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
339 geo->hdelay = tvnorm->hdelayx1; 339 geo->hdelay = tvnorm->hdelayx1;
340 geo->hdelay = (geo->hdelay*width)/swidth; 340 geo->hdelay = (geo->hdelay*width)/swidth;
341 geo->hdelay &= 0x3fe; 341 geo->hdelay &= 0x3fe;
342 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512; 342 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
343 geo->vscale = (0x10000UL-sr) & 0x1fff; 343 geo->vscale = (0x10000UL-sr) & 0x1fff;
344 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) | 344 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
345 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0); 345 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
346 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0; 346 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
347 geo->vdelay = vdelay; 347 geo->vdelay = vdelay;
348 geo->width = width; 348 geo->width = width;
349 geo->sheight = tvnorm->sheight; 349 geo->sheight = tvnorm->sheight;
350 geo->vtotal = tvnorm->vtotal; 350 geo->vtotal = tvnorm->vtotal;
351 351
352 if (btv->opt_combfilter) { 352 if (btv->opt_combfilter) {
353 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0); 353 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
354 geo->comb = (width < 769) ? 1 : 0; 354 geo->comb = (width < 769) ? 1 : 0;
355 } else { 355 } else {
356 geo->vtc = 0; 356 geo->vtc = 0;
357 geo->comb = 0; 357 geo->comb = 0;
358 } 358 }
359} 359}
360 360
361static void 361static void
362bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd) 362bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
363{ 363{
364 int off = odd ? 0x80 : 0x00; 364 int off = odd ? 0x80 : 0x00;
365 365
366 if (geo->comb) 366 if (geo->comb)
367 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 367 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
368 else 368 else
369 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off); 369 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
370 370
371 btwrite(geo->vtc, BT848_E_VTC+off); 371 btwrite(geo->vtc, BT848_E_VTC+off);
372 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off); 372 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
373 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off); 373 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
374 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off); 374 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
375 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off); 375 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
376 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off); 376 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
377 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off); 377 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
378 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off); 378 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
379 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off); 379 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
380 btwrite(geo->crop, BT848_E_CROP+off); 380 btwrite(geo->crop, BT848_E_CROP+off);
381 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI); 381 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
382 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO); 382 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
383} 383}
384 384
385/* ---------------------------------------------------------- */ 385/* ---------------------------------------------------------- */
@@ -420,7 +420,7 @@ bttv_set_dma(struct bttv *btv, int override)
420 } else { 420 } else {
421 del_timer(&btv->timeout); 421 del_timer(&btv->timeout);
422 } 422 }
423 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd); 423 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
424 424
425 btaor(capctl, ~0x0f, BT848_CAP_CTL); 425 btaor(capctl, ~0x0f, BT848_CAP_CTL);
426 if (capctl) { 426 if (capctl) {
@@ -432,7 +432,7 @@ bttv_set_dma(struct bttv *btv, int override)
432 } else { 432 } else {
433 if (!btv->dma_on) 433 if (!btv->dma_on)
434 return; 434 return;
435 btand(~3, BT848_GPIO_DMA_CTL); 435 btand(~3, BT848_GPIO_DMA_CTL);
436 btv->dma_on = 0; 436 btv->dma_on = 0;
437 } 437 }
438 return; 438 return;
@@ -460,19 +460,19 @@ bttv_risc_init_main(struct bttv *btv)
460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP); 460 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2)); 461 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
462 462
463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC | 463 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
464 BT848_FIFO_STATUS_VRO); 464 BT848_FIFO_STATUS_VRO);
465 btv->main.cpu[9] = cpu_to_le32(0); 465 btv->main.cpu[9] = cpu_to_le32(0);
466 466
467 /* bottom field */ 467 /* bottom field */
468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP); 468 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2)); 469 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP); 470 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2)); 471 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
472 472
473 /* jump back to top field */ 473 /* jump back to top field */
474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP); 474 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2)); 475 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
476 476
477 return 0; 477 return 0;
478} 478}
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index d254e90e3bb9..124ea41dada4 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -20,123 +20,148 @@
20/* ---------------------------------------------------------- */ 20/* ---------------------------------------------------------- */
21/* exported by bttv-cards.c */ 21/* exported by bttv-cards.c */
22 22
23#define BTTV_UNKNOWN 0x00 23#define BTTV_BOARD_UNKNOWN 0x00
24#define BTTV_MIRO 0x01 24#define BTTV_BOARD_MIRO 0x01
25#define BTTV_HAUPPAUGE 0x02 25#define BTTV_BOARD_HAUPPAUGE 0x02
26#define BTTV_STB 0x03 26#define BTTV_BOARD_STB 0x03
27#define BTTV_INTEL 0x04 27#define BTTV_BOARD_INTEL 0x04
28#define BTTV_DIAMOND 0x05 28#define BTTV_BOARD_DIAMOND 0x05
29#define BTTV_AVERMEDIA 0x06 29#define BTTV_BOARD_AVERMEDIA 0x06
30#define BTTV_MATRIX_VISION 0x07 30#define BTTV_BOARD_MATRIX_VISION 0x07
31#define BTTV_FLYVIDEO 0x08 31#define BTTV_BOARD_FLYVIDEO 0x08
32#define BTTV_TURBOTV 0x09 32#define BTTV_BOARD_TURBOTV 0x09
33#define BTTV_HAUPPAUGE878 0x0a 33#define BTTV_BOARD_HAUPPAUGE878 0x0a
34#define BTTV_MIROPRO 0x0b 34#define BTTV_BOARD_MIROPRO 0x0b
35#define BTTV_ADSTECH_TV 0x0c 35#define BTTV_BOARD_ADSTECH_TV 0x0c
36#define BTTV_AVERMEDIA98 0x0d 36#define BTTV_BOARD_AVERMEDIA98 0x0d
37#define BTTV_VHX 0x0e 37#define BTTV_BOARD_VHX 0x0e
38#define BTTV_ZOLTRIX 0x0f 38#define BTTV_BOARD_ZOLTRIX 0x0f
39#define BTTV_PIXVIEWPLAYTV 0x10 39#define BTTV_BOARD_PIXVIEWPLAYTV 0x10
40#define BTTV_WINVIEW_601 0x11 40#define BTTV_BOARD_WINVIEW_601 0x11
41#define BTTV_AVEC_INTERCAP 0x12 41#define BTTV_BOARD_AVEC_INTERCAP 0x12
42#define BTTV_LIFE_FLYKIT 0x13 42#define BTTV_BOARD_LIFE_FLYKIT 0x13
43#define BTTV_CEI_RAFFLES 0x14 43#define BTTV_BOARD_CEI_RAFFLES 0x14
44#define BTTV_CONFERENCETV 0x15 44#define BTTV_BOARD_CONFERENCETV 0x15
45#define BTTV_PHOEBE_TVMAS 0x16 45#define BTTV_BOARD_PHOEBE_TVMAS 0x16
46#define BTTV_MODTEC_205 0x17 46#define BTTV_BOARD_MODTEC_205 0x17
47#define BTTV_MAGICTVIEW061 0x18 47#define BTTV_BOARD_MAGICTVIEW061 0x18
48#define BTTV_VOBIS_BOOSTAR 0x19 48#define BTTV_BOARD_VOBIS_BOOSTAR 0x19
49#define BTTV_HAUPPAUG_WCAM 0x1a 49#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a
50#define BTTV_MAXI 0x1b 50#define BTTV_BOARD_MAXI 0x1b
51#define BTTV_TERRATV 0x1c 51#define BTTV_BOARD_TERRATV 0x1c
52#define BTTV_PXC200 0x1d 52#define BTTV_BOARD_PXC200 0x1d
53#define BTTV_FLYVIDEO_98 0x1e 53#define BTTV_BOARD_FLYVIDEO_98 0x1e
54#define BTTV_IPROTV 0x1f 54#define BTTV_BOARD_IPROTV 0x1f
55#define BTTV_INTEL_C_S_PCI 0x20 55#define BTTV_BOARD_INTEL_C_S_PCI 0x20
56#define BTTV_TERRATVALUE 0x21 56#define BTTV_BOARD_TERRATVALUE 0x21
57#define BTTV_WINFAST2000 0x22 57#define BTTV_BOARD_WINFAST2000 0x22
58#define BTTV_CHRONOS_VS2 0x23 58#define BTTV_BOARD_CHRONOS_VS2 0x23
59#define BTTV_TYPHOON_TVIEW 0x24 59#define BTTV_BOARD_TYPHOON_TVIEW 0x24
60#define BTTV_PXELVWPLTVPRO 0x25 60#define BTTV_BOARD_PXELVWPLTVPRO 0x25
61#define BTTV_MAGICTVIEW063 0x26 61#define BTTV_BOARD_MAGICTVIEW063 0x26
62#define BTTV_PINNACLE 0x27 62#define BTTV_BOARD_PINNACLE 0x27
63#define BTTV_STB2 0x28 63#define BTTV_BOARD_STB2 0x28
64#define BTTV_AVPHONE98 0x29 64#define BTTV_BOARD_AVPHONE98 0x29
65#define BTTV_PV951 0x2a 65#define BTTV_BOARD_PV951 0x2a
66#define BTTV_ONAIR_TV 0x2b 66#define BTTV_BOARD_ONAIR_TV 0x2b
67#define BTTV_SIGMA_TVII_FM 0x2c 67#define BTTV_BOARD_SIGMA_TVII_FM 0x2c
68#define BTTV_MATRIX_VISION2 0x2d 68#define BTTV_BOARD_MATRIX_VISION2 0x2d
69#define BTTV_ZOLTRIX_GENIE 0x2e 69#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e
70#define BTTV_TERRATVRADIO 0x2f 70#define BTTV_BOARD_TERRATVRADIO 0x2f
71#define BTTV_DYNALINK 0x30 71#define BTTV_BOARD_DYNALINK 0x30
72#define BTTV_GVBCTV3PCI 0x31 72#define BTTV_BOARD_GVBCTV3PCI 0x31
73#define BTTV_PXELVWPLTVPAK 0x32 73#define BTTV_BOARD_PXELVWPLTVPAK 0x32
74#define BTTV_EAGLE 0x33 74#define BTTV_BOARD_EAGLE 0x33
75#define BTTV_PINNACLEPRO 0x34 75#define BTTV_BOARD_PINNACLEPRO 0x34
76#define BTTV_TVIEW_RDS_FM 0x35 76#define BTTV_BOARD_TVIEW_RDS_FM 0x35
77#define BTTV_LIFETEC_9415 0x36 77#define BTTV_BOARD_LIFETEC_9415 0x36
78#define BTTV_BESTBUY_EASYTV 0x37 78#define BTTV_BOARD_BESTBUY_EASYTV 0x37
79#define BTTV_FLYVIDEO_98FM 0x38 79#define BTTV_BOARD_FLYVIDEO_98FM 0x38
80#define BTTV_GMV1 0x3d 80#define BTTV_BOARD_GRANDTEC 0x39
81#define BTTV_BESTBUY_EASYTV2 0x3e 81#define BTTV_BOARD_ASKEY_CPH060 0x3a
82#define BTTV_ATI_TVWONDER 0x3f 82#define BTTV_BOARD_ASKEY_CPH03X 0x3b
83#define BTTV_ATI_TVWONDERVE 0x40 83#define BTTV_BOARD_MM100PCTV 0x3c
84#define BTTV_FLYVIDEO2000 0x41 84#define BTTV_BOARD_GMV1 0x3d
85#define BTTV_TERRATVALUER 0x42 85#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e
86#define BTTV_GVBCTV4PCI 0x43 86#define BTTV_BOARD_ATI_TVWONDER 0x3f
87#define BTTV_VOODOOTV_FM 0x44 87#define BTTV_BOARD_ATI_TVWONDERVE 0x40
88#define BTTV_AIMMS 0x45 88#define BTTV_BOARD_FLYVIDEO2000 0x41
89#define BTTV_PV_BT878P_PLUS 0x46 89#define BTTV_BOARD_TERRATVALUER 0x42
90#define BTTV_FLYVIDEO98EZ 0x47 90#define BTTV_BOARD_GVBCTV4PCI 0x43
91#define BTTV_PV_BT878P_9B 0x48 91#define BTTV_BOARD_VOODOOTV_FM 0x44
92#define BTTV_SENSORAY311 0x49 92#define BTTV_BOARD_AIMMS 0x45
93#define BTTV_RV605 0x4a 93#define BTTV_BOARD_PV_BT878P_PLUS 0x46
94#define BTTV_WINDVR 0x4c 94#define BTTV_BOARD_FLYVIDEO98EZ 0x47
95#define BTTV_GRANDTEC 0x4d 95#define BTTV_BOARD_PV_BT878P_9B 0x48
96#define BTTV_KWORLD 0x4e 96#define BTTV_BOARD_SENSORAY311 0x49
97#define BTTV_HAUPPAUGEPVR 0x50 97#define BTTV_BOARD_RV605 0x4a
98#define BTTV_GVBCTV5PCI 0x51 98#define BTTV_BOARD_POWERCLR_MTV878 0x4b
99#define BTTV_OSPREY1x0 0x52 99#define BTTV_BOARD_WINDVR 0x4c
100#define BTTV_OSPREY1x0_848 0x53 100#define BTTV_BOARD_GRANDTEC_MULTI 0x4d
101#define BTTV_OSPREY101_848 0x54 101#define BTTV_BOARD_KWORLD 0x4e
102#define BTTV_OSPREY1x1 0x55 102#define BTTV_BOARD_DSP_TCVIDEO 0x4f
103#define BTTV_OSPREY1x1_SVID 0x56 103#define BTTV_BOARD_HAUPPAUGEPVR 0x50
104#define BTTV_OSPREY2xx 0x57 104#define BTTV_BOARD_GVBCTV5PCI 0x51
105#define BTTV_OSPREY2x0_SVID 0x58 105#define BTTV_BOARD_OSPREY1x0 0x52
106#define BTTV_OSPREY2x0 0x59 106#define BTTV_BOARD_OSPREY1x0_848 0x53
107#define BTTV_OSPREY500 0x5a 107#define BTTV_BOARD_OSPREY101_848 0x54
108#define BTTV_OSPREY540 0x5b 108#define BTTV_BOARD_OSPREY1x1 0x55
109#define BTTV_OSPREY2000 0x5c 109#define BTTV_BOARD_OSPREY1x1_SVID 0x56
110#define BTTV_IDS_EAGLE 0x5d 110#define BTTV_BOARD_OSPREY2xx 0x57
111#define BTTV_PINNACLESAT 0x5e 111#define BTTV_BOARD_OSPREY2x0_SVID 0x58
112#define BTTV_FORMAC_PROTV 0x5f 112#define BTTV_BOARD_OSPREY2x0 0x59
113#define BTTV_EURESYS_PICOLO 0x61 113#define BTTV_BOARD_OSPREY500 0x5a
114#define BTTV_PV150 0x62 114#define BTTV_BOARD_OSPREY540 0x5b
115#define BTTV_AD_TVK503 0x63 115#define BTTV_BOARD_OSPREY2000 0x5c
116#define BTTV_IVC200 0x66 116#define BTTV_BOARD_IDS_EAGLE 0x5d
117#define BTTV_XGUARD 0x67 117#define BTTV_BOARD_PINNACLESAT 0x5e
118#define BTTV_NEBULA_DIGITV 0x68 118#define BTTV_BOARD_FORMAC_PROTV 0x5f
119#define BTTV_PV143 0x69 119#define BTTV_BOARD_MACHTV 0x60
120#define BTTV_IVC100 0x6e 120#define BTTV_BOARD_EURESYS_PICOLO 0x61
121#define BTTV_IVC120 0x6f 121#define BTTV_BOARD_PV150 0x62
122#define BTTV_PC_HDTV 0x70 122#define BTTV_BOARD_AD_TVK503 0x63
123#define BTTV_TWINHAN_DST 0x71 123#define BTTV_BOARD_HERCULES_SM_TV 0x64
124#define BTTV_WINFASTVC100 0x72 124#define BTTV_BOARD_PACETV 0x65
125#define BTTV_SIMUS_GVC1100 0x74 125#define BTTV_BOARD_IVC200 0x66
126#define BTTV_NGSTV_PLUS 0x75 126#define BTTV_BOARD_XGUARD 0x67
127#define BTTV_LMLBT4 0x76 127#define BTTV_BOARD_NEBULA_DIGITV 0x68
128#define BTTV_PICOLO_TETRA_CHIP 0x79 128#define BTTV_BOARD_PV143 0x69
129#define BTTV_AVDVBT_771 0x7b 129#define BTTV_BOARD_VD009X1_MINIDIN 0x6a
130#define BTTV_AVDVBT_761 0x7c 130#define BTTV_BOARD_VD009X1_COMBI 0x6b
131#define BTTV_MATRIX_VISIONSQ 0x7d 131#define BTTV_BOARD_VD009_MINIDIN 0x6c
132#define BTTV_MATRIX_VISIONSLC 0x7e 132#define BTTV_BOARD_VD009_COMBI 0x6d
133#define BTTV_APAC_VIEWCOMP 0x7f 133#define BTTV_BOARD_IVC100 0x6e
134#define BTTV_DVICO_DVBT_LITE 0x80 134#define BTTV_BOARD_IVC120 0x6f
135#define BTTV_TIBET_CS16 0x83 135#define BTTV_BOARD_PC_HDTV 0x70
136#define BTTV_KODICOM_4400R 0x84 136#define BTTV_BOARD_TWINHAN_DST 0x71
137#define BTTV_ADLINK_RTV24 0x86 137#define BTTV_BOARD_WINFASTVC100 0x72
138#define BTTV_DVICO_FUSIONHDTV_5_LITE 0x87 138#define BTTV_BOARD_TEV560 0x73
139#define BTTV_ACORP_Y878F 0x88 139#define BTTV_BOARD_SIMUS_GVC1100 0x74
140#define BTTV_BOARD_NGSTV_PLUS 0x75
141#define BTTV_BOARD_LMLBT4 0x76
142#define BTTV_BOARD_TEKRAM_M205 0x77
143#define BTTV_BOARD_CONTVFMI 0x78
144#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79
145#define BTTV_BOARD_SPIRIT_TV 0x7a
146#define BTTV_BOARD_AVDVBT_771 0x7b
147#define BTTV_BOARD_AVDVBT_761 0x7c
148#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d
149#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e
150#define BTTV_BOARD_APAC_VIEWCOMP 0x7f
151#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
152#define BTTV_BOARD_VGEAR_MYVCD 0x81
153#define BTTV_BOARD_SUPER_TV 0x82
154#define BTTV_BOARD_TIBET_CS16 0x83
155#define BTTV_BOARD_KODICOM_4400R 0x84
156#define BTTV_BOARD_KODICOM_4400R_SL 0x85
157#define BTTV_BOARD_ADLINK_RTV24 0x86
158#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
159#define BTTV_BOARD_ACORP_Y878F 0x88
160#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89
161#define BTTV_BOARD_PV_BT878P_2E 0x8a
162#define BTTV_BOARD_PV_M4900 0x8b
163#define BTTV_BOARD_OSPREY440 0x8c
164#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
140 165
141/* i2c address list */ 166/* i2c address list */
142#define I2C_TSA5522 0xc2 167#define I2C_TSA5522 0xc2
@@ -177,7 +202,7 @@ struct bttv_core {
177 struct list_head subs; /* struct bttv_sub_device */ 202 struct list_head subs; /* struct bttv_sub_device */
178 203
179 /* device config */ 204 /* device config */
180 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ 205 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
181 unsigned int type; /* card type (pointer into tvcards[]) */ 206 unsigned int type; /* card type (pointer into tvcards[]) */
182 char name[8]; /* dev name */ 207 char name[8]; /* dev name */
183}; 208};
@@ -186,16 +211,16 @@ struct bttv;
186 211
187struct tvcard 212struct tvcard
188{ 213{
189 char *name; 214 char *name;
190 unsigned int video_inputs; 215 unsigned int video_inputs;
191 unsigned int audio_inputs; 216 unsigned int audio_inputs;
192 unsigned int tuner; 217 unsigned int tuner;
193 unsigned int svhs; 218 unsigned int svhs;
194 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO 219 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
195 u32 gpiomask; 220 u32 gpiomask;
196 u32 muxsel[16]; 221 u32 muxsel[16];
197 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ 222 u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
198 u32 gpiomask2; /* GPIO MUX mask */ 223 u32 gpiomask2; /* GPIO MUX mask */
199 224
200 /* i2c audio flags */ 225 /* i2c audio flags */
201 unsigned int no_msp34xx:1; 226 unsigned int no_msp34xx:1;
@@ -218,6 +243,7 @@ struct tvcard
218 243
219 unsigned int tuner_type; 244 unsigned int tuner_type;
220 unsigned int tuner_addr; 245 unsigned int tuner_addr;
246 unsigned int radio_addr;
221 247
222 unsigned int has_radio; 248 unsigned int has_radio;
223 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); 249 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
@@ -246,7 +272,7 @@ extern int bttv_handle_chipset(struct bttv *btv);
246 interface below for new code */ 272 interface below for new code */
247 273
248/* returns card type + card ID (for bt878-based ones) 274/* returns card type + card ID (for bt878-based ones)
249 for possible values see lines below beginning with #define BTTV_UNKNOWN 275 for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN
250 returns negative value if error occurred 276 returns negative value if error occurred
251*/ 277*/
252extern int bttv_get_cardinfo(unsigned int card, int *type, 278extern int bttv_get_cardinfo(unsigned int card, int *type,
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index e0e7c7a84bc5..386f546f7d11 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -77,14 +77,14 @@
77struct bttv_tvnorm { 77struct bttv_tvnorm {
78 int v4l2_id; 78 int v4l2_id;
79 char *name; 79 char *name;
80 u32 Fsc; 80 u32 Fsc;
81 u16 swidth, sheight; /* scaled standard width, height */ 81 u16 swidth, sheight; /* scaled standard width, height */
82 u16 totalwidth; 82 u16 totalwidth;
83 u8 adelay, bdelay, iform; 83 u8 adelay, bdelay, iform;
84 u32 scaledtwidth; 84 u32 scaledtwidth;
85 u16 hdelayx1, hactivex1; 85 u16 hdelayx1, hactivex1;
86 u16 vdelay; 86 u16 vdelay;
87 u8 vbipack; 87 u8 vbipack;
88 u16 vtotal; 88 u16 vtotal;
89 int sram; 89 int sram;
90}; 90};
@@ -267,8 +267,8 @@ struct bttv {
267 267
268 /* card configuration info */ 268 /* card configuration info */
269 unsigned int cardid; /* pci subsystem id (bt878 based ones) */ 269 unsigned int cardid; /* pci subsystem id (bt878 based ones) */
270 unsigned int tuner_type; /* tuner chip type */ 270 unsigned int tuner_type; /* tuner chip type */
271 unsigned int pinnacle_id; 271 unsigned int pinnacle_id;
272 unsigned int svhs; 272 unsigned int svhs;
273 struct bttv_pll_info pll; 273 struct bttv_pll_info pll;
274 int triton1; 274 int triton1;
@@ -301,9 +301,9 @@ struct bttv {
301 301
302 /* locking */ 302 /* locking */
303 spinlock_t s_lock; 303 spinlock_t s_lock;
304 struct semaphore lock; 304 struct semaphore lock;
305 int resources; 305 int resources;
306 struct semaphore reslock; 306 struct semaphore reslock;
307#ifdef VIDIOC_G_PRIORITY 307#ifdef VIDIOC_G_PRIORITY
308 struct v4l2_prio_state prio; 308 struct v4l2_prio_state prio;
309#endif 309#endif
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
new file mode 100644
index 000000000000..780b352ec119
--- /dev/null
+++ b/drivers/media/video/cs53l32a.c
@@ -0,0 +1,240 @@
1/*
2 * cs53l32a (Adaptec AVC-2010 and AVC-2410) i2c ivtv driver.
3 * Copyright (C) 2005 Martin Vaughan
4 *
5 * Audio source switching for Adaptec AVC-2410 added by Trev Jackson
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22
23#include <linux/module.h>
24#include <linux/types.h>
25#include <linux/ioctl.h>
26#include <asm/uaccess.h>
27#include <linux/i2c.h>
28#include <linux/i2c-id.h>
29#include <linux/videodev.h>
30#include <media/audiochip.h>
31
32MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
33MODULE_AUTHOR("Martin Vaughan");
34MODULE_LICENSE("GPL");
35
36static int debug = 0;
37
38module_param(debug, bool, 0644);
39
40MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On");
41
42#define cs53l32a_dbg(fmt, arg...) \
43 do { \
44 if (debug) \
45 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
46 i2c_adapter_id(client->adapter), client->addr , ## arg); \
47 } while (0)
48
49#define cs53l32a_err(fmt, arg...) do { \
50 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
51 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
52#define cs53l32a_info(fmt, arg...) do { \
53 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
54 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
55
56static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
57
58
59I2C_CLIENT_INSMOD;
60
61/* ----------------------------------------------------------------------- */
62
63static int cs53l32a_write(struct i2c_client *client, u8 reg, u8 value)
64{
65 return i2c_smbus_write_byte_data(client, reg, value);
66}
67
68static int cs53l32a_read(struct i2c_client *client, u8 reg)
69{
70 return i2c_smbus_read_byte_data(client, reg);
71}
72
73static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
74 void *arg)
75{
76 int *input = arg;
77
78 switch (cmd) {
79 case AUDC_SET_INPUT:
80 switch (*input) {
81 case AUDIO_TUNER:
82 cs53l32a_write(client, 0x01, 0x01);
83 break;
84 case AUDIO_EXTERN:
85 cs53l32a_write(client, 0x01, 0x21);
86 break;
87 case AUDIO_MUTE:
88 cs53l32a_write(client, 0x03, 0xF0);
89 break;
90 case AUDIO_UNMUTE:
91 cs53l32a_write(client, 0x03, 0x30);
92 break;
93 default:
94 cs53l32a_err("Invalid input %d.\n", *input);
95 return -EINVAL;
96 }
97 break;
98
99 case VIDIOC_S_CTRL:
100 {
101 struct v4l2_control *ctrl = arg;
102
103 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
104 return -EINVAL;
105 if (ctrl->value > 12 || ctrl->value < -90)
106 return -EINVAL;
107 cs53l32a_write(client, 0x04, (u8) ctrl->value);
108 cs53l32a_write(client, 0x05, (u8) ctrl->value);
109 break;
110 }
111
112 case VIDIOC_LOG_STATUS:
113 {
114 u8 v = cs53l32a_read(client, 0x01);
115 u8 m = cs53l32a_read(client, 0x03);
116
117 cs53l32a_info("Input: %s%s\n",
118 v == 0x21 ? "external line in" : "tuner",
119 (m & 0xC0) ? " (muted)" : "");
120 break;
121 }
122
123 default:
124 return -EINVAL;
125 }
126 return 0;
127}
128
129/* ----------------------------------------------------------------------- */
130
131/* i2c implementation */
132
133/*
134 * Generic i2c probe
135 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
136 */
137
138static struct i2c_driver i2c_driver;
139
140static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind)
141{
142 struct i2c_client *client;
143 int i;
144
145 /* Check if the adapter supports the needed features */
146 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
147 return 0;
148
149 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
150 if (client == 0)
151 return -ENOMEM;
152
153 memset(client, 0, sizeof(struct i2c_client));
154 client->addr = address;
155 client->adapter = adapter;
156 client->driver = &i2c_driver;
157 client->flags = I2C_CLIENT_ALLOW_USE;
158 snprintf(client->name, sizeof(client->name) - 1, "cs53l32a");
159
160 cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
161
162 for (i = 1; i <= 7; i++) {
163 u8 v = cs53l32a_read(client, i);
164
165 cs53l32a_dbg("Read Reg %d %02x\n", i, v);
166 }
167
168 /* Set cs53l32a internal register for Adaptec 2010/2410 setup */
169
170 cs53l32a_write(client, 0x01, (u8) 0x21);
171 cs53l32a_write(client, 0x02, (u8) 0x29);
172 cs53l32a_write(client, 0x03, (u8) 0x30);
173 cs53l32a_write(client, 0x04, (u8) 0x00);
174 cs53l32a_write(client, 0x05, (u8) 0x00);
175 cs53l32a_write(client, 0x06, (u8) 0x00);
176 cs53l32a_write(client, 0x07, (u8) 0x00);
177
178 /* Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00 */
179
180 for (i = 1; i <= 7; i++) {
181 u8 v = cs53l32a_read(client, i);
182
183 cs53l32a_dbg("Read Reg %d %02x\n", i, v);
184 }
185
186 i2c_attach_client(client);
187
188 return 0;
189}
190
191static int cs53l32a_probe(struct i2c_adapter *adapter)
192{
193#ifdef I2C_CLASS_TV_ANALOG
194 if (adapter->class & I2C_CLASS_TV_ANALOG)
195#else
196 if (adapter->id == I2C_HW_B_BT848)
197#endif
198 return i2c_probe(adapter, &addr_data, cs53l32a_attach);
199 return 0;
200}
201
202static int cs53l32a_detach(struct i2c_client *client)
203{
204 int err;
205
206 err = i2c_detach_client(client);
207 if (err) {
208 return err;
209 }
210 kfree(client);
211
212 return 0;
213}
214
215/* ----------------------------------------------------------------------- */
216
217/* i2c implementation */
218static struct i2c_driver i2c_driver = {
219 .name = "cs53l32a",
220 .id = I2C_DRIVERID_CS53L32A,
221 .flags = I2C_DF_NOTIFY,
222 .attach_adapter = cs53l32a_probe,
223 .detach_client = cs53l32a_detach,
224 .command = cs53l32a_command,
225 .owner = THIS_MODULE,
226};
227
228
229static int __init cs53l32a_init_module(void)
230{
231 return i2c_add_driver(&i2c_driver);
232}
233
234static void __exit cs53l32a_cleanup_module(void)
235{
236 i2c_del_driver(&i2c_driver);
237}
238
239module_init(cs53l32a_init_module);
240module_exit(cs53l32a_cleanup_module);
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
new file mode 100644
index 000000000000..41818b6205b3
--- /dev/null
+++ b/drivers/media/video/cx88/Kconfig
@@ -0,0 +1,91 @@
1config VIDEO_CX88
2 tristate "Conexant 2388x (bt878 successor) support"
3 depends on VIDEO_DEV && PCI && I2C
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_BTCX
7 select VIDEO_BUF
8 select VIDEO_TUNER
9 select VIDEO_TVEEPROM
10 select VIDEO_IR
11 ---help---
12 This is a video4linux driver for Conexant 2388x based
13 TV cards.
14
15 To compile this driver as a module, choose M here: the
16 module will be called cx8800
17
18config VIDEO_CX88_DVB
19 tristate "DVB/ATSC Support for cx2388x based TV cards"
20 depends on VIDEO_CX88 && DVB_CORE
21 select VIDEO_BUF_DVB
22 ---help---
23 This adds support for DVB/ATSC cards based on the
24 Connexant 2388x chip.
25
26 To compile this driver as a module, choose M here: the
27 module will be called cx88-dvb.
28
29 You must also select one or more DVB/ATSC demodulators.
30 If you are unsure which you need, choose all of them.
31
32config VIDEO_CX88_DVB_ALL_FRONTENDS
33 bool "Build all supported frontends for cx2388x based TV cards"
34 default y
35 depends on VIDEO_CX88_DVB
36 select DVB_MT352
37 select DVB_OR51132
38 select DVB_CX22702
39 select DVB_LGDT330X
40 select DVB_NXT200X
41 ---help---
42 This builds cx88-dvb with all currently supported frontend
43 demodulators. If you wish to tweak your configuration, and
44 only include support for the hardware that you need, choose N here.
45
46 If you are unsure, choose Y.
47
48config VIDEO_CX88_DVB_MT352
49 tristate "Zarlink MT352 DVB-T Support"
50 default m
51 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
52 select DVB_MT352
53 ---help---
54 This adds DVB-T support for cards based on the
55 Connexant 2388x chip and the MT352 demodulator.
56
57config VIDEO_CX88_DVB_OR51132
58 tristate "OR51132 ATSC Support"
59 default m
60 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
61 select DVB_OR51132
62 ---help---
63 This adds ATSC 8VSB and QAM64/256 support for cards based on the
64 Connexant 2388x chip and the OR51132 demodulator.
65
66config VIDEO_CX88_DVB_CX22702
67 tristate "Conexant CX22702 DVB-T Support"
68 default m
69 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
70 select DVB_CX22702
71 ---help---
72 This adds DVB-T support for cards based on the
73 Connexant 2388x chip and the CX22702 demodulator.
74
75config VIDEO_CX88_DVB_LGDT330X
76 tristate "LG Electronics DT3302/DT3303 ATSC Support"
77 default m
78 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
79 select DVB_LGDT330X
80 ---help---
81 This adds ATSC 8VSB and QAM64/256 support for cards based on the
82 Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator.
83
84config VIDEO_CX88_DVB_NXT200X
85 tristate "NXT2002/NXT2004 ATSC Support"
86 default m
87 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
88 select DVB_NXT200X
89 ---help---
90 This adds ATSC 8VSB and QAM64/256 support for cards based on the
91 Connexant 2388x chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 107e48645e3a..0df40b773454 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -9,6 +9,9 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o
9EXTRA_CFLAGS += -I$(src)/.. 9EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends 11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
12ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
13 EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
14endif
12ifneq ($(CONFIG_DVB_CX22702),n) 15ifneq ($(CONFIG_DVB_CX22702),n)
13 EXTRA_CFLAGS += -DHAVE_CX22702=1 16 EXTRA_CFLAGS += -DHAVE_CX22702=1
14endif 17endif
@@ -21,3 +24,6 @@ endif
21ifneq ($(CONFIG_DVB_MT352),n) 24ifneq ($(CONFIG_DVB_MT352),n)
22 EXTRA_CFLAGS += -DHAVE_MT352=1 25 EXTRA_CFLAGS += -DHAVE_MT352=1
23endif 26endif
27ifneq ($(CONFIG_DVB_NXT200X),n)
28 EXTRA_CFLAGS += -DHAVE_NXT200X=1
29endif
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 0c0c59e94774..4ae3f78cccf2 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -38,7 +38,7 @@ MODULE_AUTHOR("Jelle Foks <jelle@foks.8m.com>");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40 40
41static unsigned int mpegbufs = 8; 41static unsigned int mpegbufs = 32;
42module_param(mpegbufs,int,0644); 42module_param(mpegbufs,int,0644);
43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32"); 43MODULE_PARM_DESC(mpegbufs,"number of mpeg buffers, range 2-32");
44 44
@@ -436,7 +436,7 @@ static int memory_write(struct cx88_core *core, u32 address, u32 value)
436 436
437static int memory_read(struct cx88_core *core, u32 address, u32 *value) 437static int memory_read(struct cx88_core *core, u32 address, u32 *value)
438{ 438{
439 int retval; 439 int retval;
440 u32 val; 440 u32 val;
441 441
442 /* Warning: address is dword address (4 bytes) */ 442 /* Warning: address is dword address (4 bytes) */
@@ -605,11 +605,11 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
605 u32 *dataptr; 605 u32 *dataptr;
606 606
607 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED); 607 retval = register_write(dev->core, IVTV_REG_VPU, 0xFFFFFFED);
608 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 608 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
609 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640); 609 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_REFRESH, 0x80000640);
610 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); 610 retval |= register_write(dev->core, IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A);
611 msleep(1); 611 msleep(1);
612 retval |= register_write(dev->core, IVTV_REG_APU, 0); 612 retval |= register_write(dev->core, IVTV_REG_APU, 0);
613 613
614 if (retval < 0) 614 if (retval < 0)
615 dprintk(0, "Error with register_write\n"); 615 dprintk(0, "Error with register_write\n");
@@ -657,13 +657,13 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
657 release_firmware(firmware); 657 release_firmware(firmware);
658 dprintk(0, "Firmware upload successful.\n"); 658 dprintk(0, "Firmware upload successful.\n");
659 659
660 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); 660 retval |= register_write(dev->core, IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST);
661 retval |= register_read(dev->core, IVTV_REG_SPU, &value); 661 retval |= register_read(dev->core, IVTV_REG_SPU, &value);
662 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE); 662 retval |= register_write(dev->core, IVTV_REG_SPU, value & 0xFFFFFFFE);
663 msleep(1); 663 msleep(1);
664 664
665 retval |= register_read(dev->core, IVTV_REG_VPU, &value); 665 retval |= register_read(dev->core, IVTV_REG_VPU, &value);
666 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8); 666 retval |= register_write(dev->core, IVTV_REG_VPU, value & 0xFFFFFFE8);
667 667
668 if (retval < 0) 668 if (retval < 0)
669 dprintk(0, "Error with register_write\n"); 669 dprintk(0, "Error with register_write\n");
@@ -683,84 +683,560 @@ DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | M
683================================================================================================================= 683=================================================================================================================
684*DB: "DirectBurn" 684*DB: "DirectBurn"
685*/ 685*/
686static void blackbird_codec_settings(struct cx8802_dev *dev) 686
687static struct blackbird_dnr default_dnr_params = {
688 .mode = BLACKBIRD_DNR_BITS_MANUAL,
689 .type = BLACKBIRD_MEDIAN_FILTER_DISABLED,
690 .spatial = 0,
691 .temporal = 0
692};
693static struct v4l2_mpeg_compression default_mpeg_params = {
694 .st_type = V4L2_MPEG_PS_2,
695 .st_bitrate = {
696 .mode = V4L2_BITRATE_CBR,
697 .min = 0,
698 .target = 0,
699 .max = 0
700 },
701 .ts_pid_pmt = 16,
702 .ts_pid_audio = 260,
703 .ts_pid_video = 256,
704 .ts_pid_pcr = 259,
705 .ps_size = 0,
706 .au_type = V4L2_MPEG_AU_2_II,
707 .au_bitrate = {
708 .mode = V4L2_BITRATE_CBR,
709 .min = 224,
710 .target = 224,
711 .max = 224
712 },
713 .au_sample_rate = 44100,
714 .au_pesid = 0,
715 .vi_type = V4L2_MPEG_VI_2,
716 .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
717 .vi_bitrate = {
718 .mode = V4L2_BITRATE_CBR,
719 .min = 4000,
720 .target = 4500,
721 .max = 6000
722 },
723 .vi_frame_rate = 25,
724 .vi_frames_per_gop = 15,
725 .vi_bframes_count = 2,
726 .vi_pesid = 0,
727 .closed_gops = 0,
728 .pulldown = 0
729};
730
731static enum blackbird_stream_type mpeg_stream_types[] = {
732 [V4L2_MPEG_SS_1] = BLACKBIRD_STREAM_MPEG1,
733 [V4L2_MPEG_PS_2] = BLACKBIRD_STREAM_PROGRAM,
734 [V4L2_MPEG_TS_2] = BLACKBIRD_STREAM_TRANSPORT,
735 [V4L2_MPEG_PS_DVD] = BLACKBIRD_STREAM_DVD,
736};
737static enum blackbird_aspect_ratio mpeg_stream_ratios[] = {
738 [V4L2_MPEG_ASPECT_SQUARE] = BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
739 [V4L2_MPEG_ASPECT_4_3] = BLACKBIRD_ASPECT_RATIO_4_3,
740 [V4L2_MPEG_ASPECT_16_9] = BLACKBIRD_ASPECT_RATIO_16_9,
741 [V4L2_MPEG_ASPECT_1_221] = BLACKBIRD_ASPECT_RATIO_221_100,
742};
743static enum blackbird_video_bitrate_type mpeg_video_bitrates[] = {
744 [V4L2_BITRATE_NONE] = BLACKBIRD_VIDEO_CBR,
745 [V4L2_BITRATE_CBR] = BLACKBIRD_VIDEO_CBR,
746 [V4L2_BITRATE_VBR] = BLACKBIRD_VIDEO_VBR,
747};
748/* find the best layer I/II bitrate to fit a given numeric value */
749struct bitrate_bits {
750 u32 bits; /* layer bits for the best fit */
751 u32 rate; /* actual numeric value for the layer best fit */
752};
753struct bitrate_approximation {
754 u32 target; /* numeric value of the rate we want */
755 struct bitrate_bits layer[2];
756};
757static struct bitrate_approximation mpeg_audio_bitrates[] = {
758 /* target layer[0].bits layer[0].rate layer[1].bits layer[1].rate */
759 { 0, { { 0, 0, }, { 0, 0, }, }, },
760 { 32, { { BLACKBIRD_AUDIO_BITS_LAYER_1_32 , 32, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_32 , 32, }, }, },
761 { 48, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_48 , 48, }, }, },
762 { 56, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_56 , 56, }, }, },
763 { 64, { { BLACKBIRD_AUDIO_BITS_LAYER_1_64 , 64, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_64 , 64, }, }, },
764 { 80, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_80 , 80, }, }, },
765 { 96, { { BLACKBIRD_AUDIO_BITS_LAYER_1_96 , 96, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_96 , 96, }, }, },
766 { 112, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_112, 112, }, }, },
767 { 128, { { BLACKBIRD_AUDIO_BITS_LAYER_1_128, 128, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_128, 128, }, }, },
768 { 160, { { BLACKBIRD_AUDIO_BITS_LAYER_1_160, 160, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_160, 160, }, }, },
769 { 192, { { BLACKBIRD_AUDIO_BITS_LAYER_1_192, 192, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_192, 192, }, }, },
770 { 224, { { BLACKBIRD_AUDIO_BITS_LAYER_1_224, 224, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_224, 224, }, }, },
771 { 256, { { BLACKBIRD_AUDIO_BITS_LAYER_1_256, 256, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_256, 256, }, }, },
772 { 288, { { BLACKBIRD_AUDIO_BITS_LAYER_1_288, 288, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
773 { 320, { { BLACKBIRD_AUDIO_BITS_LAYER_1_320, 320, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_320, 320, }, }, },
774 { 352, { { BLACKBIRD_AUDIO_BITS_LAYER_1_352, 352, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
775 { 384, { { BLACKBIRD_AUDIO_BITS_LAYER_1_384, 384, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
776 { 416, { { BLACKBIRD_AUDIO_BITS_LAYER_1_416, 416, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
777 { 448, { { BLACKBIRD_AUDIO_BITS_LAYER_1_448, 448, }, { BLACKBIRD_AUDIO_BITS_LAYER_2_384, 384, }, }, },
778};
779static const int BITRATES_SIZE = ARRAY_SIZE(mpeg_audio_bitrates);
780
781static void blackbird_set_default_params(struct cx8802_dev *dev)
687{ 782{
688 int bitrate_mode = 1; 783 struct v4l2_mpeg_compression *params = &dev->params;
689 int bitrate = 7500000; 784 u32 au_params;
690 int bitrate_peak = 7500000;
691 bitrate_mode = BLACKBIRD_VIDEO_CBR;
692 bitrate = 4000*1024;
693 bitrate_peak = 4000*1024;
694 785
695 /* assign stream type */ 786 /* assign stream type */
696 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM); 787 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
697 788 params->st_type = V4L2_MPEG_PS_2;
698 /* assign output port */ 789 if( params->st_type == V4L2_MPEG_SS_1 )
699 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ 790 params->vi_type = V4L2_MPEG_VI_1;
791 else
792 params->vi_type = V4L2_MPEG_VI_2;
793 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
700 794
701 /* assign framerate */ 795 /* assign framerate */
702 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25); 796 if( params->vi_frame_rate <= 25 )
703 797 {
704 /* assign frame size */ 798 params->vi_frame_rate = 25;
705 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0, 799 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
706 dev->height, dev->width); 800 }
801 else
802 {
803 params->vi_frame_rate = 30;
804 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
805 }
707 806
708 /* assign aspect ratio */ 807 /* assign aspect ratio */
709 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3); 808 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
710 809 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
711 /* assign bitrates */ 810 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
712 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0,
713 bitrate_mode, /* mode */
714 bitrate, /* bps */
715 bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
716 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
717 811
718 /* assign gop properties */ 812 /* assign gop properties */
719 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3); 813 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
814
815 /* assign gop closure */
816 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
720 817
721 /* assign 3 2 pulldown */ 818 /* assign 3 2 pulldown */
722 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED); 819 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
820
821 /* make sure the params are within bounds */
822 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
823 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
824 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
825 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
826 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
827 params->au_bitrate.mode = V4L2_BITRATE_NONE;
723 828
724 /* assign audio properties */ 829 /* assign audio properties */
725 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */ 830 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
726 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4)); 831 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
727 blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */
728 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0,
729 BLACKBIRD_AUDIO_BITS_44100HZ |
730 BLACKBIRD_AUDIO_BITS_LAYER_2 |
731 BLACKBIRD_AUDIO_BITS_LAYER_2_224 |
732 BLACKBIRD_AUDIO_BITS_STEREO |
733 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */ 832 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
734 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE | 833 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
735 BLACKBIRD_AUDIO_BITS_CRC_OFF | 834 BLACKBIRD_AUDIO_BITS_CRC_OFF |
736 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF | 835 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
737 BLACKBIRD_AUDIO_BITS_COPY 836 BLACKBIRD_AUDIO_BITS_COPY |
738 ); 837 0;
838 if( params->au_sample_rate <= 32000 )
839 {
840 params->au_sample_rate = 32000;
841 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
842 }
843 else if( params->au_sample_rate <= 44100 )
844 {
845 params->au_sample_rate = 44100;
846 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
847 }
848 else
849 {
850 params->au_sample_rate = 48000;
851 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
852 }
853 if( params->au_type == V4L2_MPEG_AU_2_I )
854 {
855 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
856 }
857 else
858 {
859 /* TODO: try to handle the other formats more gracefully */
860 params->au_type = V4L2_MPEG_AU_2_II;
861 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
862 }
863 if( params->au_bitrate.mode )
864 {
865 int layer;
866
867 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
868 params->au_bitrate.max = params->vi_bitrate.target;
869 else
870 params->au_bitrate.target = params->vi_bitrate.max;
871
872 layer = params->au_type;
873 if( params->au_bitrate.target == 0 )
874 {
875 /* TODO: use the minimum possible bitrate instead of 0 ? */
876 au_params |= 0;
877 }
878 else if( params->au_bitrate.target >=
879 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
880 {
881 /* clamp the bitrate to the max supported by the standard */
882 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
883 params->au_bitrate.max = params->au_bitrate.target;
884 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
885 }
886 else
887 {
888 /* round up to the nearest supported bitrate */
889 int i;
890 for(i = 1; i < BITRATES_SIZE; i++)
891 {
892 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
893 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
894 {
895 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
896 params->au_bitrate.max = params->au_bitrate.target;
897 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
898 break;
899 }
900 }
901 }
902 }
903 else
904 {
905 /* TODO: ??? */
906 params->au_bitrate.target = params->au_bitrate.max = 0;
907 au_params |= 0;
908 }
909 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
910
911 /* assign bitrates */
912 if( params->vi_bitrate.mode )
913 {
914 /* bitrate is set, let's figure out the cbr/vbr mess */
915 if( params->vi_bitrate.max < params->vi_bitrate.target )
916 {
917 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
918 params->vi_bitrate.max = params->vi_bitrate.target;
919 else
920 params->vi_bitrate.target = params->vi_bitrate.max;
921 }
922 }
923 else
924 {
925 if( params->st_bitrate.max < params->st_bitrate.target )
926 {
927 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
928 params->st_bitrate.target = params->st_bitrate.max;
929 else
930 params->st_bitrate.max = params->st_bitrate.target;
931 }
932 /* calculate vi_bitrate = st_bitrate - au_bitrate */
933 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
934 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
935 }
936 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
937 mpeg_video_bitrates[params->vi_bitrate.mode],
938 params->vi_bitrate.target * 1000, /* kbps -> bps */
939 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
940 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
941
942 /* TODO: implement the stream ID stuff:
943 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
944 ps_size, au_pesid, vi_pesid
945 */
946}
947#define CHECK_PARAM( name ) ( dev->params.name != params->name )
948#define IF_PARAM( name ) if( CHECK_PARAM( name ) )
949#define UPDATE_PARAM( name ) dev->params.name = params->name
950void blackbird_set_params(struct cx8802_dev *dev, struct v4l2_mpeg_compression *params)
951{
952 u32 au_params;
953
954 /* assign stream type */
955 if( params->st_type >= ARRAY_SIZE(mpeg_stream_types) )
956 params->st_type = V4L2_MPEG_PS_2;
957 if( params->st_type == V4L2_MPEG_SS_1 )
958 params->vi_type = V4L2_MPEG_VI_1;
959 else
960 params->vi_type = V4L2_MPEG_VI_2;
961 if( CHECK_PARAM( st_type ) || CHECK_PARAM( vi_type ) )
962 {
963 UPDATE_PARAM( st_type );
964 UPDATE_PARAM( vi_type );
965 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, mpeg_stream_types[params->st_type]);
966 }
967
968 /* assign framerate */
969 if( params->vi_frame_rate <= 25 )
970 params->vi_frame_rate = 25;
971 else
972 params->vi_frame_rate = 30;
973 IF_PARAM( vi_frame_rate )
974 {
975 UPDATE_PARAM( vi_frame_rate );
976 if( params->vi_frame_rate == 25 )
977 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
978 else
979 blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_NTSC_30);
980 }
981
982 /* assign aspect ratio */
983 if( params->vi_aspect_ratio >= ARRAY_SIZE(mpeg_stream_ratios) )
984 params->vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3;
985 IF_PARAM( vi_aspect_ratio )
986 {
987 UPDATE_PARAM( vi_aspect_ratio );
988 blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, mpeg_stream_ratios[params->vi_aspect_ratio]);
989 }
990
991 /* assign gop properties */
992 if( CHECK_PARAM( vi_frames_per_gop ) || CHECK_PARAM( vi_bframes_count ) )
993 {
994 UPDATE_PARAM( vi_frames_per_gop );
995 UPDATE_PARAM( vi_bframes_count );
996 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, params->vi_frames_per_gop, params->vi_bframes_count+1);
997 }
739 998
740 /* assign gop closure */ 999 /* assign gop closure */
741 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF); 1000 IF_PARAM( closed_gops )
1001 {
1002 UPDATE_PARAM( closed_gops );
1003 blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, params->closed_gops);
1004 }
1005
1006 /* assign 3 2 pulldown */
1007 IF_PARAM( pulldown )
1008 {
1009 UPDATE_PARAM( pulldown );
1010 blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, params->pulldown);
1011 }
1012
1013 /* make sure the params are within bounds */
1014 if( params->st_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1015 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1016 if( params->vi_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1017 params->vi_bitrate.mode = V4L2_BITRATE_NONE;
1018 if( params->au_bitrate.mode >= ARRAY_SIZE(mpeg_video_bitrates) )
1019 params->au_bitrate.mode = V4L2_BITRATE_NONE;
1020
1021 /* assign audio properties */
1022 /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
1023 au_params = BLACKBIRD_AUDIO_BITS_STEREO |
1024 /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
1025 BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
1026 BLACKBIRD_AUDIO_BITS_CRC_OFF |
1027 BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
1028 BLACKBIRD_AUDIO_BITS_COPY |
1029 0;
1030 if( params->au_sample_rate < 32000 )
1031 {
1032 params->au_sample_rate = 32000;
1033 au_params |= BLACKBIRD_AUDIO_BITS_32000HZ;
1034 }
1035 else if( params->au_sample_rate < 44100 )
1036 {
1037 params->au_sample_rate = 44100;
1038 au_params |= BLACKBIRD_AUDIO_BITS_44100HZ;
1039 }
1040 else
1041 {
1042 params->au_sample_rate = 48000;
1043 au_params |= BLACKBIRD_AUDIO_BITS_48000HZ;
1044 }
1045 if( params->au_type == V4L2_MPEG_AU_2_I )
1046 {
1047 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_1;
1048 }
1049 else
1050 {
1051 /* TODO: try to handle the other formats more gracefully */
1052 params->au_type = V4L2_MPEG_AU_2_II;
1053 au_params |= BLACKBIRD_AUDIO_BITS_LAYER_2;
1054 }
1055 if( params->au_bitrate.mode )
1056 {
1057 int layer;
1058
1059 if( params->au_bitrate.mode == V4L2_BITRATE_CBR )
1060 params->au_bitrate.max = params->vi_bitrate.target;
1061 else
1062 params->au_bitrate.target = params->vi_bitrate.max;
1063
1064 layer = params->au_type;
1065 if( params->au_bitrate.target == 0 )
1066 {
1067 /* TODO: use the minimum possible bitrate instead of 0 ? */
1068 au_params |= 0;
1069 }
1070 else if( params->au_bitrate.target >=
1071 mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate )
1072 {
1073 /* clamp the bitrate to the max supported by the standard */
1074 params->au_bitrate.target = mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].rate;
1075 params->au_bitrate.max = params->au_bitrate.target;
1076 au_params |= mpeg_audio_bitrates[BITRATES_SIZE-1].layer[layer].bits;
1077 }
1078 else
1079 {
1080 /* round up to the nearest supported bitrate */
1081 int i;
1082 for(i = 1; i < BITRATES_SIZE; i++)
1083 {
1084 if( params->au_bitrate.target > mpeg_audio_bitrates[i-1].layer[layer].rate &&
1085 params->au_bitrate.target <= mpeg_audio_bitrates[i].layer[layer].rate )
1086 {
1087 params->au_bitrate.target = mpeg_audio_bitrates[i].layer[layer].rate;
1088 params->au_bitrate.max = params->au_bitrate.target;
1089 au_params |= mpeg_audio_bitrates[i].layer[layer].bits;
1090 break;
1091 }
1092 }
1093 }
1094 }
1095 else
1096 {
1097 /* TODO: ??? */
1098 params->au_bitrate.target = params->au_bitrate.max = 0;
1099 au_params |= 0;
1100 }
1101 if( CHECK_PARAM( au_type ) || CHECK_PARAM( au_sample_rate )
1102 || CHECK_PARAM( au_bitrate.mode ) || CHECK_PARAM( au_bitrate.max )
1103 || CHECK_PARAM( au_bitrate.target )
1104 )
1105 {
1106 UPDATE_PARAM( au_type );
1107 UPDATE_PARAM( au_sample_rate );
1108 UPDATE_PARAM( au_bitrate );
1109 blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0, au_params );
1110 }
1111
1112 /* assign bitrates */
1113 if( params->vi_bitrate.mode )
1114 {
1115 /* bitrate is set, let's figure out the cbr/vbr mess */
1116 if( params->vi_bitrate.max < params->vi_bitrate.target )
1117 {
1118 if( params->vi_bitrate.mode == V4L2_BITRATE_CBR )
1119 params->vi_bitrate.max = params->vi_bitrate.target;
1120 else
1121 params->vi_bitrate.target = params->vi_bitrate.max;
1122 }
1123 }
1124 else
1125 {
1126 if( params->st_bitrate.max < params->st_bitrate.target )
1127 {
1128 if( params->st_bitrate.mode == V4L2_BITRATE_VBR )
1129 params->st_bitrate.target = params->st_bitrate.max;
1130 else
1131 params->st_bitrate.max = params->st_bitrate.target;
1132 }
1133 /* calculate vi_bitrate = st_bitrate - au_bitrate */
1134 params->vi_bitrate.max = params->st_bitrate.max - params->au_bitrate.max;
1135 params->vi_bitrate.target = params->st_bitrate.target - params->au_bitrate.target;
1136 }
1137 UPDATE_PARAM( st_bitrate );
1138 if( CHECK_PARAM( vi_bitrate.mode ) || CHECK_PARAM( vi_bitrate.max )
1139 || CHECK_PARAM( vi_bitrate.target )
1140 )
1141 {
1142 UPDATE_PARAM( vi_bitrate );
1143 blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 4, 0,
1144 mpeg_video_bitrates[params->vi_bitrate.mode],
1145 params->vi_bitrate.target * 1000, /* kbps -> bps */
1146 params->vi_bitrate.max * 1000 / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
1147 BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
1148 }
742 1149
1150 /* TODO: implement the stream ID stuff:
1151 ts_pid_pmt, ts_pid_audio, ts_pid_video, ts_pid_pcr,
1152 ps_size, au_pesid, vi_pesid
1153 */
1154 UPDATE_PARAM( ts_pid_pmt );
1155 UPDATE_PARAM( ts_pid_audio );
1156 UPDATE_PARAM( ts_pid_video );
1157 UPDATE_PARAM( ts_pid_pcr );
1158 UPDATE_PARAM( ps_size );
1159 UPDATE_PARAM( au_pesid );
1160 UPDATE_PARAM( vi_pesid );
1161}
743 1162
1163static void blackbird_set_default_dnr_params(struct cx8802_dev *dev)
1164{
744 /* assign dnr filter mode */ 1165 /* assign dnr filter mode */
1166 if( dev->dnr_params.mode > BLACKBIRD_DNR_BITS_AUTO )
1167 dev->dnr_params.mode = BLACKBIRD_DNR_BITS_MANUAL;
1168 if( dev->dnr_params.type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1169 dev->dnr_params.type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
745 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, 1170 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
746 BLACKBIRD_DNR_BITS_MANUAL, 1171 dev->dnr_params.mode,
747 BLACKBIRD_MEDIAN_FILTER_DISABLED 1172 dev->dnr_params.type
748 ); 1173 );
749 1174
750 /* assign dnr filter props*/ 1175 /* assign dnr filter props*/
751 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0); 1176 if( dev->dnr_params.spatial > 15 )
1177 dev->dnr_params.spatial = 15;
1178 if( dev->dnr_params.temporal > 31 )
1179 dev->dnr_params.temporal = 31;
1180 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0,
1181 dev->dnr_params.spatial,
1182 dev->dnr_params.temporal
1183 );
1184}
1185#define CHECK_DNR_PARAM( name ) ( dev->dnr_params.name != dnr_params->name )
1186#define UPDATE_DNR_PARAM( name ) dev->dnr_params.name = dnr_params->name
1187void blackbird_set_dnr_params(struct cx8802_dev *dev, struct blackbird_dnr* dnr_params)
1188{
1189 /* assign dnr filter mode */
1190 /* clamp values */
1191 if( dnr_params->mode > BLACKBIRD_DNR_BITS_AUTO )
1192 dnr_params->mode = BLACKBIRD_DNR_BITS_MANUAL;
1193 if( dnr_params->type > BLACKBIRD_MEDIAN_FILTER_DIAGONAL )
1194 dnr_params->type = BLACKBIRD_MEDIAN_FILTER_DISABLED;
1195 /* check if the params actually changed */
1196 if( CHECK_DNR_PARAM( mode ) || CHECK_DNR_PARAM( type ) )
1197 {
1198 UPDATE_DNR_PARAM( mode );
1199 UPDATE_DNR_PARAM( type );
1200 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0, dnr_params->mode, dnr_params->type);
1201 }
1202
1203 /* assign dnr filter props*/
1204 if( dnr_params->spatial > 15 )
1205 dnr_params->spatial = 15;
1206 if( dnr_params->temporal > 31 )
1207 dnr_params->temporal = 31;
1208 if( CHECK_DNR_PARAM( spatial ) || CHECK_DNR_PARAM( temporal ) )
1209 {
1210 UPDATE_DNR_PARAM( spatial );
1211 UPDATE_DNR_PARAM( temporal );
1212 blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, dnr_params->spatial, dnr_params->temporal);
1213 }
1214}
1215
1216static void blackbird_codec_settings(struct cx8802_dev *dev)
1217{
1218
1219 /* assign output port */
1220 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
1221
1222 /* assign frame size */
1223 blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
1224 dev->height, dev->width);
752 1225
753 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */ 1226 /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
754 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255); 1227 blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
755 1228
756 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */ 1229 /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
757 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0, 1230 blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
758 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ, 1231 BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
759 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ 1232 BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
760 ); 1233 );
761 1234
762 /* assign frame drop rate */ 1235 /* assign frame drop rate */
763 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */ 1236 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
1237
1238 blackbird_set_default_params(dev);
1239 blackbird_set_default_dnr_params(dev);
764} 1240}
765 1241
766static int blackbird_initialize_codec(struct cx8802_dev *dev) 1242static int blackbird_initialize_codec(struct cx8802_dev *dev)
@@ -851,15 +1327,10 @@ static int bb_buf_setup(struct videobuf_queue *q,
851 struct cx8802_fh *fh = q->priv_data; 1327 struct cx8802_fh *fh = q->priv_data;
852 1328
853 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */ 1329 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
854 fh->dev->ts_packet_count = 32; /* was: 100 */ 1330 fh->dev->ts_packet_count = mpegbufs; /* was: 100 */
855 1331
856 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; 1332 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
857 if (0 == *count) 1333 *count = fh->dev->ts_packet_count;
858 *count = mpegbufs;
859 if (*count < 2)
860 *count = 2;
861 if (*count > 32)
862 *count = 32;
863 return 0; 1334 return 0;
864} 1335}
865 1336
@@ -868,7 +1339,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
868 enum v4l2_field field) 1339 enum v4l2_field field)
869{ 1340{
870 struct cx8802_fh *fh = q->priv_data; 1341 struct cx8802_fh *fh = q->priv_data;
871 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb); 1342 return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field);
872} 1343}
873 1344
874static void 1345static void
@@ -920,8 +1391,6 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
920 V4L2_CAP_VIDEO_CAPTURE | 1391 V4L2_CAP_VIDEO_CAPTURE |
921 V4L2_CAP_READWRITE | 1392 V4L2_CAP_READWRITE |
922 V4L2_CAP_STREAMING | 1393 V4L2_CAP_STREAMING |
923 V4L2_CAP_VBI_CAPTURE |
924 V4L2_CAP_VIDEO_OVERLAY |
925 0; 1394 0;
926 if (UNSET != core->tuner_type) 1395 if (UNSET != core->tuner_type)
927 cap->capabilities |= V4L2_CAP_TUNER; 1396 cap->capabilities |= V4L2_CAP_TUNER;
@@ -941,27 +1410,52 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
941 1410
942 memset(f,0,sizeof(*f)); 1411 memset(f,0,sizeof(*f));
943 f->index = index; 1412 f->index = index;
944 strlcpy(f->description, "MPEG TS", sizeof(f->description)); 1413 strlcpy(f->description, "MPEG", sizeof(f->description));
945 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1414 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
946 f->pixelformat = V4L2_PIX_FMT_MPEG; 1415 f->pixelformat = V4L2_PIX_FMT_MPEG;
947 return 0; 1416 return 0;
948 } 1417 }
949 case VIDIOC_G_FMT: 1418 case VIDIOC_G_FMT:
950 case VIDIOC_S_FMT:
951 case VIDIOC_TRY_FMT:
952 { 1419 {
953 /* FIXME -- quick'n'dirty for exactly one size ... */
954 struct v4l2_format *f = arg; 1420 struct v4l2_format *f = arg;
955 1421
956 memset(f,0,sizeof(*f)); 1422 memset(f,0,sizeof(*f));
957 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1423 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1424 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1425 f->fmt.pix.bytesperline = 0;
1426 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
1427 f->fmt.pix.colorspace = 0;
958 f->fmt.pix.width = dev->width; 1428 f->fmt.pix.width = dev->width;
959 f->fmt.pix.height = dev->height; 1429 f->fmt.pix.height = dev->height;
1430 f->fmt.pix.field = fh->mpegq.field;
1431 dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
1432 dev->width, dev->height, fh->mpegq.field );
1433 return 0;
1434 }
1435 case VIDIOC_TRY_FMT:
1436 {
1437 struct v4l2_format *f = arg;
1438
1439 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1440 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
1441 f->fmt.pix.bytesperline = 0;
1442 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
1443 f->fmt.pix.colorspace = 0;
1444 dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
1445 dev->width, dev->height, fh->mpegq.field );
1446 return 0;
1447 }
1448 case VIDIOC_S_FMT:
1449 {
1450 struct v4l2_format *f = arg;
1451
1452 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
960 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 1453 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
961 f->fmt.pix.field = V4L2_FIELD_NONE;
962 f->fmt.pix.bytesperline = 0; 1454 f->fmt.pix.bytesperline = 0;
963 f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */; 1455 f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
964 f->fmt.pix.colorspace = 0; 1456 f->fmt.pix.colorspace = 0;
1457 dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
1458 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
965 return 0; 1459 return 0;
966 } 1460 }
967 1461
@@ -985,6 +1479,22 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
985 case VIDIOC_STREAMOFF: 1479 case VIDIOC_STREAMOFF:
986 return videobuf_streamoff(&fh->mpegq); 1480 return videobuf_streamoff(&fh->mpegq);
987 1481
1482 /* --- mpeg compression -------------------------------------- */
1483 case VIDIOC_G_MPEGCOMP:
1484 {
1485 struct v4l2_mpeg_compression *f = arg;
1486
1487 memcpy(f,&dev->params,sizeof(*f));
1488 return 0;
1489 }
1490 case VIDIOC_S_MPEGCOMP:
1491 {
1492 struct v4l2_mpeg_compression *f = arg;
1493
1494 blackbird_set_params(dev, f);
1495 return 0;
1496 }
1497
988 default: 1498 default:
989 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook ); 1499 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
990 } 1500 }
@@ -1034,16 +1544,17 @@ static int mpeg_open(struct inode *inode, struct file *file)
1034 file->private_data = fh; 1544 file->private_data = fh;
1035 fh->dev = dev; 1545 fh->dev = dev;
1036 1546
1037 /* FIXME: locking against other video device */
1038 cx88_set_scale(dev->core, dev->width, dev->height,
1039 V4L2_FIELD_INTERLACED);
1040
1041 videobuf_queue_init(&fh->mpegq, &blackbird_qops, 1547 videobuf_queue_init(&fh->mpegq, &blackbird_qops,
1042 dev->pci, &dev->slock, 1548 dev->pci, &dev->slock,
1043 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1549 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1044 V4L2_FIELD_TOP, 1550 V4L2_FIELD_INTERLACED,
1045 sizeof(struct cx88_buffer), 1551 sizeof(struct cx88_buffer),
1046 fh); 1552 fh);
1553
1554 /* FIXME: locking against other video device */
1555 cx88_set_scale(dev->core, dev->width, dev->height,
1556 fh->mpegq.field);
1557
1047 return 0; 1558 return 0;
1048} 1559}
1049 1560
@@ -1173,6 +1684,8 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1173 dev->core = core; 1684 dev->core = core;
1174 dev->width = 720; 1685 dev->width = 720;
1175 dev->height = 576; 1686 dev->height = 576;
1687 memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params));
1688 memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params));
1176 1689
1177 err = cx8802_init_common(dev); 1690 err = cx8802_init_common(dev);
1178 if (0 != err) 1691 if (0 != err)
@@ -1199,7 +1712,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1199 1712
1200static void __devexit blackbird_remove(struct pci_dev *pci_dev) 1713static void __devexit blackbird_remove(struct pci_dev *pci_dev)
1201{ 1714{
1202 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 1715 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
1203 1716
1204 /* blackbird */ 1717 /* blackbird */
1205 blackbird_unregister_video(dev); 1718 blackbird_unregister_video(dev);
@@ -1215,8 +1728,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
1215 { 1728 {
1216 .vendor = 0x14f1, 1729 .vendor = 0x14f1,
1217 .device = 0x8802, 1730 .device = 0x8802,
1218 .subvendor = PCI_ANY_ID, 1731 .subvendor = PCI_ANY_ID,
1219 .subdevice = PCI_ANY_ID, 1732 .subdevice = PCI_ANY_ID,
1220 },{ 1733 },{
1221 /* --- end of list --- */ 1734 /* --- end of list --- */
1222 } 1735 }
@@ -1224,10 +1737,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
1224MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); 1737MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
1225 1738
1226static struct pci_driver blackbird_pci_driver = { 1739static struct pci_driver blackbird_pci_driver = {
1227 .name = "cx88-blackbird", 1740 .name = "cx88-blackbird",
1228 .id_table = cx8802_pci_tbl, 1741 .id_table = cx8802_pci_tbl,
1229 .probe = blackbird_probe, 1742 .probe = blackbird_probe,
1230 .remove = __devexit_p(blackbird_remove), 1743 .remove = __devexit_p(blackbird_remove),
1231 .suspend = cx8802_suspend_common, 1744 .suspend = cx8802_suspend_common,
1232 .resume = cx8802_resume_common, 1745 .resume = cx8802_resume_common,
1233}; 1746};
@@ -1257,6 +1770,8 @@ module_exit(blackbird_fini);
1257 1770
1258EXPORT_SYMBOL(cx88_ioctl_hook); 1771EXPORT_SYMBOL(cx88_ioctl_hook);
1259EXPORT_SYMBOL(cx88_ioctl_translator); 1772EXPORT_SYMBOL(cx88_ioctl_translator);
1773EXPORT_SYMBOL(blackbird_set_params);
1774EXPORT_SYMBOL(blackbird_set_dnr_params);
1260 1775
1261/* ----------------------------------------------------------- */ 1776/* ----------------------------------------------------------- */
1262/* 1777/*
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 4da91d535a5b..f2268631b7c0 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -126,27 +126,27 @@ struct cx88_board cx88_boards[] = {
126 .input = {{ 126 .input = {{
127 .type = CX88_VMUX_TELEVISION, 127 .type = CX88_VMUX_TELEVISION,
128 .vmux = 0, 128 .vmux = 0,
129 .gpio0 = 0x03ff, 129 .gpio0 = 0x03ff,
130 },{ 130 },{
131 .type = CX88_VMUX_COMPOSITE1, 131 .type = CX88_VMUX_COMPOSITE1,
132 .vmux = 1, 132 .vmux = 1,
133 .gpio0 = 0x03fe, 133 .gpio0 = 0x03fe,
134 },{ 134 },{
135 .type = CX88_VMUX_SVIDEO, 135 .type = CX88_VMUX_SVIDEO,
136 .vmux = 2, 136 .vmux = 2,
137 .gpio0 = 0x03fe, 137 .gpio0 = 0x03fe,
138 }}, 138 }},
139 }, 139 },
140 [CX88_BOARD_WINFAST2000XP_EXPERT] = { 140 [CX88_BOARD_WINFAST2000XP_EXPERT] = {
141 .name = "Leadtek Winfast 2000XP Expert", 141 .name = "Leadtek Winfast 2000XP Expert",
142 .tuner_type = TUNER_PHILIPS_4IN1, 142 .tuner_type = TUNER_PHILIPS_4IN1,
143 .radio_type = UNSET, 143 .radio_type = UNSET,
144 .tuner_addr = ADDR_UNSET, 144 .tuner_addr = ADDR_UNSET,
145 .radio_addr = ADDR_UNSET, 145 .radio_addr = ADDR_UNSET,
146 .tda9887_conf = TDA9887_PRESENT, 146 .tda9887_conf = TDA9887_PRESENT,
147 .input = {{ 147 .input = {{
148 .type = CX88_VMUX_TELEVISION, 148 .type = CX88_VMUX_TELEVISION,
149 .vmux = 0, 149 .vmux = 0,
150 .gpio0 = 0x00F5e700, 150 .gpio0 = 0x00F5e700,
151 .gpio1 = 0x00003004, 151 .gpio1 = 0x00003004,
152 .gpio2 = 0x00F5e700, 152 .gpio2 = 0x00F5e700,
@@ -165,16 +165,16 @@ struct cx88_board cx88_boards[] = {
165 .gpio1 = 0x00003004, 165 .gpio1 = 0x00003004,
166 .gpio2 = 0x00F5c700, 166 .gpio2 = 0x00F5c700,
167 .gpio3 = 0x02000000, 167 .gpio3 = 0x02000000,
168 }}, 168 }},
169 .radio = { 169 .radio = {
170 .type = CX88_RADIO, 170 .type = CX88_RADIO,
171 .gpio0 = 0x00F5d700, 171 .gpio0 = 0x00F5d700,
172 .gpio1 = 0x00003004, 172 .gpio1 = 0x00003004,
173 .gpio2 = 0x00F5d700, 173 .gpio2 = 0x00F5d700,
174 .gpio3 = 0x02000000, 174 .gpio3 = 0x02000000,
175 }, 175 },
176 }, 176 },
177 [CX88_BOARD_AVERTV_303] = { 177 [CX88_BOARD_AVERTV_STUDIO_303] = {
178 .name = "AverTV Studio 303 (M126)", 178 .name = "AverTV Studio 303 (M126)",
179 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 179 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
180 .radio_type = UNSET, 180 .radio_type = UNSET,
@@ -206,7 +206,7 @@ struct cx88_board cx88_boards[] = {
206 .radio_type = UNSET, 206 .radio_type = UNSET,
207 .tuner_addr = ADDR_UNSET, 207 .tuner_addr = ADDR_UNSET,
208 .radio_addr = ADDR_UNSET, 208 .radio_addr = ADDR_UNSET,
209 .tda9887_conf = TDA9887_PRESENT, 209 .tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER_NTSC,
210 .input = {{ 210 .input = {{
211 .type = CX88_VMUX_TELEVISION, 211 .type = CX88_VMUX_TELEVISION,
212 .vmux = 0, 212 .vmux = 0,
@@ -214,32 +214,32 @@ struct cx88_board cx88_boards[] = {
214 .gpio1 = 0x000080c0, 214 .gpio1 = 0x000080c0,
215 .gpio2 = 0x0000ff40, 215 .gpio2 = 0x0000ff40,
216 },{ 216 },{
217 .type = CX88_VMUX_COMPOSITE1, 217 .type = CX88_VMUX_COMPOSITE1,
218 .vmux = 1, 218 .vmux = 1,
219 .gpio0 = 0x000040bf, 219 .gpio0 = 0x000040bf,
220 .gpio1 = 0x000080c0, 220 .gpio1 = 0x000080c0,
221 .gpio2 = 0x0000ff40, 221 .gpio2 = 0x0000ff40,
222 },{ 222 },{
223 .type = CX88_VMUX_SVIDEO, 223 .type = CX88_VMUX_SVIDEO,
224 .vmux = 2, 224 .vmux = 2,
225 .gpio0 = 0x000040bf, 225 .gpio0 = 0x000040bf,
226 .gpio1 = 0x000080c0, 226 .gpio1 = 0x000080c0,
227 .gpio2 = 0x0000ff40, 227 .gpio2 = 0x0000ff40,
228 }}, 228 }},
229 .radio = { 229 .radio = {
230 .type = CX88_RADIO, 230 .type = CX88_RADIO,
231 }, 231 },
232 }, 232 },
233 [CX88_BOARD_WINFAST_DV2000] = { 233 [CX88_BOARD_WINFAST_DV2000] = {
234 .name = "Leadtek Winfast DV2000", 234 .name = "Leadtek Winfast DV2000",
235 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, 235 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
236 .radio_type = UNSET, 236 .radio_type = UNSET,
237 .tuner_addr = ADDR_UNSET, 237 .tuner_addr = ADDR_UNSET,
238 .radio_addr = ADDR_UNSET, 238 .radio_addr = ADDR_UNSET,
239 .tda9887_conf = TDA9887_PRESENT, 239 .tda9887_conf = TDA9887_PRESENT,
240 .input = {{ 240 .input = {{
241 .type = CX88_VMUX_TELEVISION, 241 .type = CX88_VMUX_TELEVISION,
242 .vmux = 0, 242 .vmux = 0,
243 .gpio0 = 0x0035e700, 243 .gpio0 = 0x0035e700,
244 .gpio1 = 0x00003004, 244 .gpio1 = 0x00003004,
245 .gpio2 = 0x0035e700, 245 .gpio2 = 0x0035e700,
@@ -260,14 +260,14 @@ struct cx88_board cx88_boards[] = {
260 .gpio2 = 0x02000000, 260 .gpio2 = 0x02000000,
261 .gpio3 = 0x02000000, 261 .gpio3 = 0x02000000,
262 }}, 262 }},
263 .radio = { 263 .radio = {
264 .type = CX88_RADIO, 264 .type = CX88_RADIO,
265 .gpio0 = 0x0035d700, 265 .gpio0 = 0x0035d700,
266 .gpio1 = 0x00007004, 266 .gpio1 = 0x00007004,
267 .gpio2 = 0x0035d700, 267 .gpio2 = 0x0035d700,
268 .gpio3 = 0x02000000, 268 .gpio3 = 0x02000000,
269 }, 269 },
270 }, 270 },
271 [CX88_BOARD_LEADTEK_PVR2000] = { 271 [CX88_BOARD_LEADTEK_PVR2000] = {
272 // gpio values for PAL version from regspy by DScaler 272 // gpio values for PAL version from regspy by DScaler
273 .name = "Leadtek PVR 2000", 273 .name = "Leadtek PVR 2000",
@@ -296,25 +296,25 @@ struct cx88_board cx88_boards[] = {
296 .blackbird = 1, 296 .blackbird = 1,
297 }, 297 },
298 [CX88_BOARD_IODATA_GVVCP3PCI] = { 298 [CX88_BOARD_IODATA_GVVCP3PCI] = {
299 .name = "IODATA GV-VCP3/PCI", 299 .name = "IODATA GV-VCP3/PCI",
300 .tuner_type = TUNER_ABSENT, 300 .tuner_type = TUNER_ABSENT,
301 .radio_type = UNSET, 301 .radio_type = UNSET,
302 .tuner_addr = ADDR_UNSET, 302 .tuner_addr = ADDR_UNSET,
303 .radio_addr = ADDR_UNSET, 303 .radio_addr = ADDR_UNSET,
304 .input = {{ 304 .input = {{
305 .type = CX88_VMUX_COMPOSITE1, 305 .type = CX88_VMUX_COMPOSITE1,
306 .vmux = 0, 306 .vmux = 0,
307 },{ 307 },{
308 .type = CX88_VMUX_COMPOSITE2, 308 .type = CX88_VMUX_COMPOSITE2,
309 .vmux = 1, 309 .vmux = 1,
310 },{ 310 },{
311 .type = CX88_VMUX_SVIDEO, 311 .type = CX88_VMUX_SVIDEO,
312 .vmux = 2, 312 .vmux = 2,
313 }}, 313 }},
314 }, 314 },
315 [CX88_BOARD_PROLINK_PLAYTVPVR] = { 315 [CX88_BOARD_PROLINK_PLAYTVPVR] = {
316 .name = "Prolink PlayTV PVR", 316 .name = "Prolink PlayTV PVR",
317 .tuner_type = TUNER_PHILIPS_FM1236_MK3, 317 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
318 .radio_type = UNSET, 318 .radio_type = UNSET,
319 .tuner_addr = ADDR_UNSET, 319 .tuner_addr = ADDR_UNSET,
320 .radio_addr = ADDR_UNSET, 320 .radio_addr = ADDR_UNSET,
@@ -348,15 +348,15 @@ struct cx88_board cx88_boards[] = {
348 .type = CX88_VMUX_TELEVISION, 348 .type = CX88_VMUX_TELEVISION,
349 .vmux = 0, 349 .vmux = 0,
350 .gpio0 = 0x0000fde6, 350 .gpio0 = 0x0000fde6,
351 },{ 351 },{
352 .type = CX88_VMUX_SVIDEO, 352 .type = CX88_VMUX_SVIDEO,
353 .vmux = 2, 353 .vmux = 2,
354 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in? 354 .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in?
355 }}, 355 }},
356 .radio = { 356 .radio = {
357 .type = CX88_RADIO, 357 .type = CX88_RADIO,
358 .gpio0 = 0x0000fde2, 358 .gpio0 = 0x0000fde2,
359 }, 359 },
360 .blackbird = 1, 360 .blackbird = 1,
361 }, 361 },
362 [CX88_BOARD_MSI_TVANYWHERE] = { 362 [CX88_BOARD_MSI_TVANYWHERE] = {
@@ -372,34 +372,34 @@ struct cx88_board cx88_boards[] = {
372 .gpio0 = 0x00000fbf, 372 .gpio0 = 0x00000fbf,
373 .gpio2 = 0x0000fc08, 373 .gpio2 = 0x0000fc08,
374 },{ 374 },{
375 .type = CX88_VMUX_COMPOSITE1, 375 .type = CX88_VMUX_COMPOSITE1,
376 .vmux = 1, 376 .vmux = 1,
377 .gpio0 = 0x00000fbf, 377 .gpio0 = 0x00000fbf,
378 .gpio2 = 0x0000fc68, 378 .gpio2 = 0x0000fc68,
379 },{ 379 },{
380 .type = CX88_VMUX_SVIDEO, 380 .type = CX88_VMUX_SVIDEO,
381 .vmux = 2, 381 .vmux = 2,
382 .gpio0 = 0x00000fbf, 382 .gpio0 = 0x00000fbf,
383 .gpio2 = 0x0000fc68, 383 .gpio2 = 0x0000fc68,
384 }}, 384 }},
385 }, 385 },
386 [CX88_BOARD_KWORLD_DVB_T] = { 386 [CX88_BOARD_KWORLD_DVB_T] = {
387 .name = "KWorld/VStream XPert DVB-T", 387 .name = "KWorld/VStream XPert DVB-T",
388 .tuner_type = TUNER_ABSENT, 388 .tuner_type = TUNER_ABSENT,
389 .radio_type = UNSET, 389 .radio_type = UNSET,
390 .tuner_addr = ADDR_UNSET, 390 .tuner_addr = ADDR_UNSET,
391 .radio_addr = ADDR_UNSET, 391 .radio_addr = ADDR_UNSET,
392 .input = {{ 392 .input = {{
393 .type = CX88_VMUX_COMPOSITE1, 393 .type = CX88_VMUX_COMPOSITE1,
394 .vmux = 1, 394 .vmux = 1,
395 .gpio0 = 0x0700, 395 .gpio0 = 0x0700,
396 .gpio2 = 0x0101, 396 .gpio2 = 0x0101,
397 },{ 397 },{
398 .type = CX88_VMUX_SVIDEO, 398 .type = CX88_VMUX_SVIDEO,
399 .vmux = 2, 399 .vmux = 2,
400 .gpio0 = 0x0700, 400 .gpio0 = 0x0700,
401 .gpio2 = 0x0101, 401 .gpio2 = 0x0101,
402 }}, 402 }},
403 .dvb = 1, 403 .dvb = 1,
404 }, 404 },
405 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = { 405 [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
@@ -425,27 +425,27 @@ struct cx88_board cx88_boards[] = {
425 .radio_type = UNSET, 425 .radio_type = UNSET,
426 .tuner_addr = ADDR_UNSET, 426 .tuner_addr = ADDR_UNSET,
427 .radio_addr = ADDR_UNSET, 427 .radio_addr = ADDR_UNSET,
428 .input = {{ 428 .input = {{
429 .type = CX88_VMUX_TELEVISION, 429 .type = CX88_VMUX_TELEVISION,
430 .vmux = 0, 430 .vmux = 0,
431 .gpio0 = 0x07f8, 431 .gpio0 = 0x07f8,
432 },{ 432 },{
433 .type = CX88_VMUX_DEBUG, 433 .type = CX88_VMUX_DEBUG,
434 .vmux = 0, 434 .vmux = 0,
435 .gpio0 = 0x07f9, // mono from tuner chip 435 .gpio0 = 0x07f9, // mono from tuner chip
436 },{ 436 },{
437 .type = CX88_VMUX_COMPOSITE1, 437 .type = CX88_VMUX_COMPOSITE1,
438 .vmux = 1, 438 .vmux = 1,
439 .gpio0 = 0x000007fa, 439 .gpio0 = 0x000007fa,
440 },{ 440 },{
441 .type = CX88_VMUX_SVIDEO, 441 .type = CX88_VMUX_SVIDEO,
442 .vmux = 2, 442 .vmux = 2,
443 .gpio0 = 0x000007fa, 443 .gpio0 = 0x000007fa,
444 }}, 444 }},
445 .radio = { 445 .radio = {
446 .type = CX88_RADIO, 446 .type = CX88_RADIO,
447 .gpio0 = 0x000007f8, 447 .gpio0 = 0x000007f8,
448 }, 448 },
449 }, 449 },
450 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = { 450 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q] = {
451 .name = "DViCO FusionHDTV 3 Gold-Q", 451 .name = "DViCO FusionHDTV 3 Gold-Q",
@@ -489,28 +489,28 @@ struct cx88_board cx88_boards[] = {
489 }}, 489 }},
490 .dvb = 1, 490 .dvb = 1,
491 }, 491 },
492 [CX88_BOARD_HAUPPAUGE_DVB_T1] = { 492 [CX88_BOARD_HAUPPAUGE_DVB_T1] = {
493 .name = "Hauppauge Nova-T DVB-T", 493 .name = "Hauppauge Nova-T DVB-T",
494 .tuner_type = TUNER_ABSENT, 494 .tuner_type = TUNER_ABSENT,
495 .radio_type = UNSET, 495 .radio_type = UNSET,
496 .tuner_addr = ADDR_UNSET, 496 .tuner_addr = ADDR_UNSET,
497 .radio_addr = ADDR_UNSET, 497 .radio_addr = ADDR_UNSET,
498 .input = {{ 498 .input = {{
499 .type = CX88_VMUX_DVB, 499 .type = CX88_VMUX_DVB,
500 .vmux = 0, 500 .vmux = 0,
501 }}, 501 }},
502 .dvb = 1, 502 .dvb = 1,
503 }, 503 },
504 [CX88_BOARD_CONEXANT_DVB_T1] = { 504 [CX88_BOARD_CONEXANT_DVB_T1] = {
505 .name = "Conexant DVB-T reference design", 505 .name = "Conexant DVB-T reference design",
506 .tuner_type = TUNER_ABSENT, 506 .tuner_type = TUNER_ABSENT,
507 .radio_type = UNSET, 507 .radio_type = UNSET,
508 .tuner_addr = ADDR_UNSET, 508 .tuner_addr = ADDR_UNSET,
509 .radio_addr = ADDR_UNSET, 509 .radio_addr = ADDR_UNSET,
510 .input = {{ 510 .input = {{
511 .type = CX88_VMUX_DVB, 511 .type = CX88_VMUX_DVB,
512 .vmux = 0, 512 .vmux = 0,
513 }}, 513 }},
514 .dvb = 1, 514 .dvb = 1,
515 }, 515 },
516 [CX88_BOARD_PROVIDEO_PV259] = { 516 [CX88_BOARD_PROVIDEO_PV259] = {
@@ -543,12 +543,12 @@ struct cx88_board cx88_boards[] = {
543 .dvb = 1, 543 .dvb = 1,
544 }, 544 },
545 [CX88_BOARD_DNTV_LIVE_DVB_T] = { 545 [CX88_BOARD_DNTV_LIVE_DVB_T] = {
546 .name = "digitalnow DNTV Live! DVB-T", 546 .name = "digitalnow DNTV Live! DVB-T",
547 .tuner_type = TUNER_ABSENT, 547 .tuner_type = TUNER_ABSENT,
548 .radio_type = UNSET, 548 .radio_type = UNSET,
549 .tuner_addr = ADDR_UNSET, 549 .tuner_addr = ADDR_UNSET,
550 .radio_addr = ADDR_UNSET, 550 .radio_addr = ADDR_UNSET,
551 .input = {{ 551 .input = {{
552 .type = CX88_VMUX_COMPOSITE1, 552 .type = CX88_VMUX_COMPOSITE1,
553 .vmux = 1, 553 .vmux = 1,
554 .gpio0 = 0x00000700, 554 .gpio0 = 0x00000700,
@@ -705,44 +705,44 @@ struct cx88_board cx88_boards[] = {
705 .gpio0 = 0xbf60, 705 .gpio0 = 0xbf60,
706 }, 706 },
707 }, 707 },
708 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { 708 [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
709 .name = "DViCO FusionHDTV 3 Gold-T", 709 .name = "DViCO FusionHDTV 3 Gold-T",
710 .tuner_type = TUNER_THOMSON_DTT7611, 710 .tuner_type = TUNER_THOMSON_DTT7611,
711 .radio_type = UNSET, 711 .radio_type = UNSET,
712 .tuner_addr = ADDR_UNSET, 712 .tuner_addr = ADDR_UNSET,
713 .radio_addr = ADDR_UNSET, 713 .radio_addr = ADDR_UNSET,
714 .input = {{ 714 .input = {{
715 .type = CX88_VMUX_TELEVISION, 715 .type = CX88_VMUX_TELEVISION,
716 .vmux = 0, 716 .vmux = 0,
717 .gpio0 = 0x97ed, 717 .gpio0 = 0x97ed,
718 },{ 718 },{
719 .type = CX88_VMUX_COMPOSITE1, 719 .type = CX88_VMUX_COMPOSITE1,
720 .vmux = 1, 720 .vmux = 1,
721 .gpio0 = 0x97e9, 721 .gpio0 = 0x97e9,
722 },{ 722 },{
723 .type = CX88_VMUX_SVIDEO, 723 .type = CX88_VMUX_SVIDEO,
724 .vmux = 2, 724 .vmux = 2,
725 .gpio0 = 0x97e9, 725 .gpio0 = 0x97e9,
726 }}, 726 }},
727 .dvb = 1, 727 .dvb = 1,
728 }, 728 },
729 [CX88_BOARD_ADSTECH_DVB_T_PCI] = { 729 [CX88_BOARD_ADSTECH_DVB_T_PCI] = {
730 .name = "ADS Tech Instant TV DVB-T PCI", 730 .name = "ADS Tech Instant TV DVB-T PCI",
731 .tuner_type = TUNER_ABSENT, 731 .tuner_type = TUNER_ABSENT,
732 .radio_type = UNSET, 732 .radio_type = UNSET,
733 .tuner_addr = ADDR_UNSET, 733 .tuner_addr = ADDR_UNSET,
734 .radio_addr = ADDR_UNSET, 734 .radio_addr = ADDR_UNSET,
735 .input = {{ 735 .input = {{
736 .type = CX88_VMUX_COMPOSITE1, 736 .type = CX88_VMUX_COMPOSITE1,
737 .vmux = 1, 737 .vmux = 1,
738 .gpio0 = 0x0700, 738 .gpio0 = 0x0700,
739 .gpio2 = 0x0101, 739 .gpio2 = 0x0101,
740 },{ 740 },{
741 .type = CX88_VMUX_SVIDEO, 741 .type = CX88_VMUX_SVIDEO,
742 .vmux = 2, 742 .vmux = 2,
743 .gpio0 = 0x0700, 743 .gpio0 = 0x0700,
744 .gpio2 = 0x0101, 744 .gpio2 = 0x0101,
745 }}, 745 }},
746 .dvb = 1, 746 .dvb = 1,
747 }, 747 },
748 [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = { 748 [CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1] = {
@@ -762,20 +762,139 @@ struct cx88_board cx88_boards[] = {
762 .radio_addr = ADDR_UNSET, 762 .radio_addr = ADDR_UNSET,
763 .tda9887_conf = TDA9887_PRESENT, 763 .tda9887_conf = TDA9887_PRESENT,
764 .input = {{ 764 .input = {{
765 .type = CX88_VMUX_TELEVISION, 765 .type = CX88_VMUX_TELEVISION,
766 .vmux = 0, 766 .vmux = 0,
767 .gpio0 = 0x87fd, 767 .gpio0 = 0x87fd,
768 },{ 768 },{
769 .type = CX88_VMUX_COMPOSITE1, 769 .type = CX88_VMUX_COMPOSITE1,
770 .vmux = 1, 770 .vmux = 1,
771 .gpio0 = 0x87f9, 771 .gpio0 = 0x87f9,
772 },{ 772 },{
773 .type = CX88_VMUX_SVIDEO, 773 .type = CX88_VMUX_SVIDEO,
774 .vmux = 2, 774 .vmux = 2,
775 .gpio0 = 0x87f9, 775 .gpio0 = 0x87f9,
776 }}, 776 }},
777 .dvb = 1,
778 },
779 [CX88_BOARD_AVERMEDIA_ULTRATV_MC_550] = {
780 .name = "AverMedia UltraTV Media Center PCI 550",
781 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
782 .radio_type = UNSET,
783 .tuner_addr = ADDR_UNSET,
784 .radio_addr = ADDR_UNSET,
785 .tda9887_conf = TDA9887_PRESENT,
786 .blackbird = 1,
787 .input = {{
788 .type = CX88_VMUX_COMPOSITE1,
789 .vmux = 0,
790 .gpio0 = 0x0000cd73,
791 },{
792 .type = CX88_VMUX_SVIDEO,
793 .vmux = 1,
794 .gpio0 = 0x0000cd73,
795 },{
796 .type = CX88_VMUX_TELEVISION,
797 .vmux = 3,
798 .gpio0 = 0x0000cdb3,
799 }},
800 .radio = {
801 .type = CX88_RADIO,
802 .vmux = 2,
803 .gpio0 = 0x0000cdf3,
804 },
805 },
806 [CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = {
807 /* Alexander Wold <awold@bigfoot.com> */
808 .name = "Kworld V-Stream Xpert DVD",
809 .tuner_type = UNSET,
810 .input = {{
811 .type = CX88_VMUX_COMPOSITE1,
812 .vmux = 1,
813 .gpio0 = 0x03000000,
814 .gpio1 = 0x01000000,
815 .gpio2 = 0x02000000,
816 .gpio3 = 0x00100000,
817 },{
818 .type = CX88_VMUX_SVIDEO,
819 .vmux = 2,
820 .gpio0 = 0x03000000,
821 .gpio1 = 0x01000000,
822 .gpio2 = 0x02000000,
823 .gpio3 = 0x00100000,
824 }},
825 },
826 [CX88_BOARD_ATI_HDTVWONDER] = {
827 .name = "ATI HDTV Wonder",
828 .tuner_type = TUNER_PHILIPS_TUV1236D,
829 .radio_type = UNSET,
830 .tuner_addr = ADDR_UNSET,
831 .radio_addr = ADDR_UNSET,
832 .input = {{
833 .type = CX88_VMUX_TELEVISION,
834 .vmux = 0,
835 .gpio0 = 0x00000ff7,
836 .gpio1 = 0x000000ff,
837 .gpio2 = 0x00000001,
838 .gpio3 = 0x00000000,
839 },{
840 .type = CX88_VMUX_COMPOSITE1,
841 .vmux = 1,
842 .gpio0 = 0x00000ffe,
843 .gpio1 = 0x000000ff,
844 .gpio2 = 0x00000001,
845 .gpio3 = 0x00000000,
846 },{
847 .type = CX88_VMUX_SVIDEO,
848 .vmux = 2,
849 .gpio0 = 0x00000ffe,
850 .gpio1 = 0x000000ff,
851 .gpio2 = 0x00000001,
852 .gpio3 = 0x00000000,
853 }},
777 .dvb = 1, 854 .dvb = 1,
778 }, 855 },
856 [CX88_BOARD_WINFAST_DTV1000] = {
857 .name = "WinFast DTV1000-T",
858 .tuner_type = TUNER_ABSENT,
859 .radio_type = UNSET,
860 .tuner_addr = ADDR_UNSET,
861 .radio_addr = ADDR_UNSET,
862 .input = {{
863 .type = CX88_VMUX_DVB,
864 .vmux = 0,
865 }},
866 .dvb = 1,
867 },
868 [CX88_BOARD_AVERTV_303] = {
869 .name = "AVerTV 303 (M126)",
870 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
871 .radio_type = UNSET,
872 .tuner_addr = ADDR_UNSET,
873 .radio_addr = ADDR_UNSET,
874 .tda9887_conf = TDA9887_PRESENT,
875 .input = {{
876 .type = CX88_VMUX_TELEVISION,
877 .vmux = 0,
878 .gpio0 = 0x00ff,
879 .gpio1 = 0xe09f,
880 .gpio2 = 0x0010,
881 .gpio3 = 0x0000,
882 },{
883 .type = CX88_VMUX_COMPOSITE1,
884 .vmux = 1,
885 .gpio0 = 0x00ff,
886 .gpio1 = 0xe05f,
887 .gpio2 = 0x0010,
888 .gpio3 = 0x0000,
889 },{
890 .type = CX88_VMUX_SVIDEO,
891 .vmux = 2,
892 .gpio0 = 0x00ff,
893 .gpio1 = 0xe05f,
894 .gpio2 = 0x0010,
895 .gpio3 = 0x0000,
896 }},
897 },
779}; 898};
780const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 899const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
781 900
@@ -804,41 +923,41 @@ struct cx88_subid cx88_subids[] = {
804 .subdevice = 0x00f8, 923 .subdevice = 0x00f8,
805 .card = CX88_BOARD_ATI_WONDER_PRO, 924 .card = CX88_BOARD_ATI_WONDER_PRO,
806 },{ 925 },{
807 .subvendor = 0x107d, 926 .subvendor = 0x107d,
808 .subdevice = 0x6611, 927 .subdevice = 0x6611,
809 .card = CX88_BOARD_WINFAST2000XP_EXPERT, 928 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
929 },{
930 .subvendor = 0x107d,
931 .subdevice = 0x6613, /* NTSC */
932 .card = CX88_BOARD_WINFAST2000XP_EXPERT,
810 },{ 933 },{
811 .subvendor = 0x107d, 934 .subvendor = 0x107d,
812 .subdevice = 0x6613, /* NTSC */ 935 .subdevice = 0x6620,
813 .card = CX88_BOARD_WINFAST2000XP_EXPERT, 936 .card = CX88_BOARD_WINFAST_DV2000,
937 },{
938 .subvendor = 0x107d,
939 .subdevice = 0x663b,
940 .card = CX88_BOARD_LEADTEK_PVR2000,
814 },{ 941 },{
815 .subvendor = 0x107d, 942 .subvendor = 0x107d,
816 .subdevice = 0x6620, 943 .subdevice = 0x663C,
817 .card = CX88_BOARD_WINFAST_DV2000, 944 .card = CX88_BOARD_LEADTEK_PVR2000,
818 },{ 945 },{
819 .subvendor = 0x107d,
820 .subdevice = 0x663b,
821 .card = CX88_BOARD_LEADTEK_PVR2000,
822 },{
823 .subvendor = 0x107d,
824 .subdevice = 0x663C,
825 .card = CX88_BOARD_LEADTEK_PVR2000,
826 },{
827 .subvendor = 0x1461, 946 .subvendor = 0x1461,
828 .subdevice = 0x000b, 947 .subdevice = 0x000b,
829 .card = CX88_BOARD_AVERTV_303, 948 .card = CX88_BOARD_AVERTV_STUDIO_303,
830 },{ 949 },{
831 .subvendor = 0x1462, 950 .subvendor = 0x1462,
832 .subdevice = 0x8606, 951 .subdevice = 0x8606,
833 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER, 952 .card = CX88_BOARD_MSI_TVANYWHERE_MASTER,
834 },{ 953 },{
835 .subvendor = 0x10fc, 954 .subvendor = 0x10fc,
836 .subdevice = 0xd003, 955 .subdevice = 0xd003,
837 .card = CX88_BOARD_IODATA_GVVCP3PCI, 956 .card = CX88_BOARD_IODATA_GVVCP3PCI,
838 },{ 957 },{
839 .subvendor = 0x1043, 958 .subvendor = 0x1043,
840 .subdevice = 0x4823, /* with mpeg encoder */ 959 .subdevice = 0x4823, /* with mpeg encoder */
841 .card = CX88_BOARD_ASUS_PVR_416, 960 .card = CX88_BOARD_ASUS_PVR_416,
842 },{ 961 },{
843 .subvendor = 0x17de, 962 .subvendor = 0x17de,
844 .subdevice = 0x08a6, 963 .subdevice = 0x08a6,
@@ -852,43 +971,43 @@ struct cx88_subid cx88_subids[] = {
852 .subdevice = 0xd820, 971 .subdevice = 0xd820,
853 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T, 972 .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
854 },{ 973 },{
855 .subvendor = 0x18AC, 974 .subvendor = 0x18ac,
856 .subdevice = 0xDB00, 975 .subdevice = 0xdb00,
857 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1, 976 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
858 },{ 977 },{
859 .subvendor = 0x0070, 978 .subvendor = 0x0070,
860 .subdevice = 0x9002, 979 .subdevice = 0x9002,
861 .card = CX88_BOARD_HAUPPAUGE_DVB_T1, 980 .card = CX88_BOARD_HAUPPAUGE_DVB_T1,
862 },{ 981 },{
863 .subvendor = 0x14f1, 982 .subvendor = 0x14f1,
864 .subdevice = 0x0187, 983 .subdevice = 0x0187,
865 .card = CX88_BOARD_CONEXANT_DVB_T1, 984 .card = CX88_BOARD_CONEXANT_DVB_T1,
866 },{ 985 },{
867 .subvendor = 0x1540, 986 .subvendor = 0x1540,
868 .subdevice = 0x2580, 987 .subdevice = 0x2580,
869 .card = CX88_BOARD_PROVIDEO_PV259, 988 .card = CX88_BOARD_PROVIDEO_PV259,
870 },{ 989 },{
871 .subvendor = 0x18AC, 990 .subvendor = 0x18ac,
872 .subdevice = 0xDB10, 991 .subdevice = 0xdb10,
873 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, 992 .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS,
874 },{ 993 },{
875 .subvendor = 0x1554, 994 .subvendor = 0x1554,
876 .subdevice = 0x4811, 995 .subdevice = 0x4811,
877 .card = CX88_BOARD_PIXELVIEW, 996 .card = CX88_BOARD_PIXELVIEW,
878 },{ 997 },{
879 .subvendor = 0x7063, 998 .subvendor = 0x7063,
880 .subdevice = 0x3000, /* HD-3000 card */ 999 .subdevice = 0x3000, /* HD-3000 card */
881 .card = CX88_BOARD_PCHDTV_HD3000, 1000 .card = CX88_BOARD_PCHDTV_HD3000,
882 },{ 1001 },{
883 .subvendor = 0x17DE, 1002 .subvendor = 0x17de,
884 .subdevice = 0xA8A6, 1003 .subdevice = 0xa8a6,
885 .card = CX88_BOARD_DNTV_LIVE_DVB_T, 1004 .card = CX88_BOARD_DNTV_LIVE_DVB_T,
886 },{ 1005 },{
887 .subvendor = 0x0070, 1006 .subvendor = 0x0070,
888 .subdevice = 0x2801, 1007 .subdevice = 0x2801,
889 .card = CX88_BOARD_HAUPPAUGE_ROSLYN, 1008 .card = CX88_BOARD_HAUPPAUGE_ROSLYN,
890 },{ 1009 },{
891 .subvendor = 0x14F1, 1010 .subvendor = 0x14f1,
892 .subdevice = 0x0342, 1011 .subdevice = 0x0342,
893 .card = CX88_BOARD_DIGITALLOGIC_MEC, 1012 .card = CX88_BOARD_DIGITALLOGIC_MEC,
894 },{ 1013 },{
@@ -899,14 +1018,30 @@ struct cx88_subid cx88_subids[] = {
899 .subvendor = 0x1421, 1018 .subvendor = 0x1421,
900 .subdevice = 0x0334, 1019 .subdevice = 0x0334,
901 .card = CX88_BOARD_ADSTECH_DVB_T_PCI, 1020 .card = CX88_BOARD_ADSTECH_DVB_T_PCI,
902 },{ 1021 },{
903 .subvendor = 0x153b, 1022 .subvendor = 0x153b,
904 .subdevice = 0x1166, 1023 .subdevice = 0x1166,
905 .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1, 1024 .card = CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1,
906 },{ 1025 },{
907 .subvendor = 0x18ac, 1026 .subvendor = 0x18ac,
908 .subdevice = 0xd500, 1027 .subdevice = 0xd500,
909 .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD, 1028 .card = CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD,
1029 },{
1030 .subvendor = 0x1461,
1031 .subdevice = 0x8011,
1032 .card = CX88_BOARD_AVERMEDIA_ULTRATV_MC_550,
1033 },{
1034 .subvendor = PCI_VENDOR_ID_ATI,
1035 .subdevice = 0xa101,
1036 .card = CX88_BOARD_ATI_HDTVWONDER,
1037 },{
1038 .subvendor = 0x107d,
1039 .subdevice = 0x665f,
1040 .card = CX88_BOARD_WINFAST_DTV1000,
1041 },{
1042 .subvendor = 0x1461,
1043 .subdevice = 0x000a,
1044 .card = CX88_BOARD_AVERTV_303,
910 }, 1045 },
911}; 1046};
912const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); 1047const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids);
@@ -1108,6 +1243,19 @@ void cx88_card_setup(struct cx88_core *core)
1108 cx_clear(MO_GP0_IO, 0x00000007); 1243 cx_clear(MO_GP0_IO, 0x00000007);
1109 cx_set(MO_GP2_IO, 0x00000101); 1244 cx_set(MO_GP2_IO, 0x00000101);
1110 break; 1245 break;
1246 case CX88_BOARD_ATI_HDTVWONDER:
1247 if (0 == core->i2c_rc) {
1248 /* enable tuner */
1249 int i;
1250 u8 buffer [] = { 0x10,0x12,0x13,0x04,0x16,0x00,0x14,0x04,0x017,0x00 };
1251 core->i2c_client.addr = 0x0a;
1252
1253 for (i = 0; i < 5; i++)
1254 if (2 != i2c_master_send(&core->i2c_client,&buffer[i*2],2))
1255 printk(KERN_WARNING "%s: Unable to enable tuner(%i).\n",
1256 core->name, i);
1257 }
1258 break;
1111 } 1259 }
1112 if (cx88_boards[core->board].radio.type == CX88_RADIO) 1260 if (cx88_boards[core->board].radio.type == CX88_RADIO)
1113 core->has_radio = 1; 1261 core->has_radio = 1;
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index dc5c5c1f3461..eb806af17182 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -31,7 +31,7 @@
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/videodev.h> 34#include <linux/videodev2.h>
35 35
36#include "cx88.h" 36#include "cx88.h"
37 37
@@ -153,26 +153,26 @@ static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist,
153 } 153 }
154 if (bpl <= sg_dma_len(sg)-offset) { 154 if (bpl <= sg_dma_len(sg)-offset) {
155 /* fits into current chunk */ 155 /* fits into current chunk */
156 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl); 156 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
157 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 157 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
158 offset+=bpl; 158 offset+=bpl;
159 } else { 159 } else {
160 /* scanline needs to be splitted */ 160 /* scanline needs to be splitted */
161 todo = bpl; 161 todo = bpl;
162 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL| 162 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
163 (sg_dma_len(sg)-offset)); 163 (sg_dma_len(sg)-offset));
164 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset); 164 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
165 todo -= (sg_dma_len(sg)-offset); 165 todo -= (sg_dma_len(sg)-offset);
166 offset = 0; 166 offset = 0;
167 sg++; 167 sg++;
168 while (todo > sg_dma_len(sg)) { 168 while (todo > sg_dma_len(sg)) {
169 *(rp++)=cpu_to_le32(RISC_WRITE| 169 *(rp++)=cpu_to_le32(RISC_WRITE|
170 sg_dma_len(sg)); 170 sg_dma_len(sg));
171 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 171 *(rp++)=cpu_to_le32(sg_dma_address(sg));
172 todo -= sg_dma_len(sg); 172 todo -= sg_dma_len(sg);
173 sg++; 173 sg++;
174 } 174 }
175 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo); 175 *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
176 *(rp++)=cpu_to_le32(sg_dma_address(sg)); 176 *(rp++)=cpu_to_le32(sg_dma_address(sg));
177 offset += todo; 177 offset += todo;
178 } 178 }
@@ -309,7 +309,7 @@ struct sram_channel cx88_sram_channels[] = {
309 .name = "video y / packed", 309 .name = "video y / packed",
310 .cmds_start = 0x180040, 310 .cmds_start = 0x180040,
311 .ctrl_start = 0x180400, 311 .ctrl_start = 0x180400,
312 .cdt = 0x180400 + 64, 312 .cdt = 0x180400 + 64,
313 .fifo_start = 0x180c00, 313 .fifo_start = 0x180c00,
314 .fifo_size = 0x002800, 314 .fifo_size = 0x002800,
315 .ptr1_reg = MO_DMA21_PTR1, 315 .ptr1_reg = MO_DMA21_PTR1,
@@ -321,7 +321,7 @@ struct sram_channel cx88_sram_channels[] = {
321 .name = "video u", 321 .name = "video u",
322 .cmds_start = 0x180080, 322 .cmds_start = 0x180080,
323 .ctrl_start = 0x1804a0, 323 .ctrl_start = 0x1804a0,
324 .cdt = 0x1804a0 + 64, 324 .cdt = 0x1804a0 + 64,
325 .fifo_start = 0x183400, 325 .fifo_start = 0x183400,
326 .fifo_size = 0x000800, 326 .fifo_size = 0x000800,
327 .ptr1_reg = MO_DMA22_PTR1, 327 .ptr1_reg = MO_DMA22_PTR1,
@@ -333,7 +333,7 @@ struct sram_channel cx88_sram_channels[] = {
333 .name = "video v", 333 .name = "video v",
334 .cmds_start = 0x1800c0, 334 .cmds_start = 0x1800c0,
335 .ctrl_start = 0x180540, 335 .ctrl_start = 0x180540,
336 .cdt = 0x180540 + 64, 336 .cdt = 0x180540 + 64,
337 .fifo_start = 0x183c00, 337 .fifo_start = 0x183c00,
338 .fifo_size = 0x000800, 338 .fifo_size = 0x000800,
339 .ptr1_reg = MO_DMA23_PTR1, 339 .ptr1_reg = MO_DMA23_PTR1,
@@ -345,7 +345,7 @@ struct sram_channel cx88_sram_channels[] = {
345 .name = "vbi", 345 .name = "vbi",
346 .cmds_start = 0x180100, 346 .cmds_start = 0x180100,
347 .ctrl_start = 0x1805e0, 347 .ctrl_start = 0x1805e0,
348 .cdt = 0x1805e0 + 64, 348 .cdt = 0x1805e0 + 64,
349 .fifo_start = 0x184400, 349 .fifo_start = 0x184400,
350 .fifo_size = 0x001000, 350 .fifo_size = 0x001000,
351 .ptr1_reg = MO_DMA24_PTR1, 351 .ptr1_reg = MO_DMA24_PTR1,
@@ -357,7 +357,7 @@ struct sram_channel cx88_sram_channels[] = {
357 .name = "audio from", 357 .name = "audio from",
358 .cmds_start = 0x180140, 358 .cmds_start = 0x180140,
359 .ctrl_start = 0x180680, 359 .ctrl_start = 0x180680,
360 .cdt = 0x180680 + 64, 360 .cdt = 0x180680 + 64,
361 .fifo_start = 0x185400, 361 .fifo_start = 0x185400,
362 .fifo_size = 0x000200, 362 .fifo_size = 0x000200,
363 .ptr1_reg = MO_DMA25_PTR1, 363 .ptr1_reg = MO_DMA25_PTR1,
@@ -369,7 +369,7 @@ struct sram_channel cx88_sram_channels[] = {
369 .name = "audio to", 369 .name = "audio to",
370 .cmds_start = 0x180180, 370 .cmds_start = 0x180180,
371 .ctrl_start = 0x180720, 371 .ctrl_start = 0x180720,
372 .cdt = 0x180680 + 64, /* same as audio IN */ 372 .cdt = 0x180680 + 64, /* same as audio IN */
373 .fifo_start = 0x185400, /* same as audio IN */ 373 .fifo_start = 0x185400, /* same as audio IN */
374 .fifo_size = 0x000200, /* same as audio IN */ 374 .fifo_size = 0x000200, /* same as audio IN */
375 .ptr1_reg = MO_DMA26_PTR1, 375 .ptr1_reg = MO_DMA26_PTR1,
@@ -431,7 +431,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
431/* ------------------------------------------------------------------ */ 431/* ------------------------------------------------------------------ */
432/* debug helper code */ 432/* debug helper code */
433 433
434int cx88_risc_decode(u32 risc) 434static int cx88_risc_decode(u32 risc)
435{ 435{
436 static char *instr[16] = { 436 static char *instr[16] = {
437 [ RISC_SYNC >> 28 ] = "sync", 437 [ RISC_SYNC >> 28 ] = "sync",
@@ -845,19 +845,19 @@ static int set_tvaudio(struct cx88_core *core)
845 return 0; 845 return 0;
846 846
847 if (V4L2_STD_PAL_BG & norm->id) { 847 if (V4L2_STD_PAL_BG & norm->id) {
848 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_BG; 848 core->tvaudio = WW_BG;
849 849
850 } else if (V4L2_STD_PAL_DK & norm->id) { 850 } else if (V4L2_STD_PAL_DK & norm->id) {
851 core->tvaudio = nicam ? WW_NICAM_BGDKL : WW_A2_DK; 851 core->tvaudio = WW_DK;
852 852
853 } else if (V4L2_STD_PAL_I & norm->id) { 853 } else if (V4L2_STD_PAL_I & norm->id) {
854 core->tvaudio = WW_NICAM_I; 854 core->tvaudio = WW_I;
855 855
856 } else if (V4L2_STD_SECAM_L & norm->id) { 856 } else if (V4L2_STD_SECAM_L & norm->id) {
857 core->tvaudio = WW_SYSTEM_L_AM; 857 core->tvaudio = WW_L;
858 858
859 } else if (V4L2_STD_SECAM_DK & norm->id) { 859 } else if (V4L2_STD_SECAM_DK & norm->id) {
860 core->tvaudio = WW_A2_DK; 860 core->tvaudio = WW_DK;
861 861
862 } else if ((V4L2_STD_NTSC_M & norm->id) || 862 } else if ((V4L2_STD_NTSC_M & norm->id) ||
863 (V4L2_STD_PAL_M & norm->id)) { 863 (V4L2_STD_PAL_M & norm->id)) {
@@ -1137,7 +1137,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1137 if (!core->radio_addr) 1137 if (!core->radio_addr)
1138 core->radio_addr = cx88_boards[core->board].radio_addr; 1138 core->radio_addr = cx88_boards[core->board].radio_addr;
1139 1139
1140 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n", 1140 printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
1141 core->tuner_type, core->tuner_addr<<1, 1141 core->tuner_type, core->tuner_addr<<1,
1142 core->radio_type, core->radio_addr<<1); 1142 core->radio_type, core->radio_addr<<1);
1143 1143
@@ -1146,6 +1146,7 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1146 /* init hardware */ 1146 /* init hardware */
1147 cx88_reset(core); 1147 cx88_reset(core);
1148 cx88_i2c_init(core,pci); 1148 cx88_i2c_init(core,pci);
1149 cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
1149 cx88_card_setup(core); 1150 cx88_card_setup(core);
1150 cx88_ir_init(core,pci); 1151 cx88_ir_init(core,pci);
1151 1152
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 4334744652de..9cce91ec334b 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -29,7 +29,6 @@
29#include <linux/file.h> 29#include <linux/file.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31 31
32
33#include "cx88.h" 32#include "cx88.h"
34#include "dvb-pll.h" 33#include "dvb-pll.h"
35 34
@@ -46,6 +45,9 @@
46#ifdef HAVE_LGDT330X 45#ifdef HAVE_LGDT330X
47# include "lgdt330x.h" 46# include "lgdt330x.h"
48#endif 47#endif
48#ifdef HAVE_NXT200X
49# include "nxt200x.h"
50#endif
49 51
50MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 52MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
51MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 53MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -78,7 +80,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
78 enum v4l2_field field) 80 enum v4l2_field field)
79{ 81{
80 struct cx8802_dev *dev = q->priv_data; 82 struct cx8802_dev *dev = q->priv_data;
81 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb); 83 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field);
82} 84}
83 85
84static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 86static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
@@ -129,7 +131,7 @@ static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
129 static u8 reset [] = { 0x50, 0x80 }; 131 static u8 reset [] = { 0x50, 0x80 };
130 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; 132 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
131 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, 133 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
132 0x00, 0xFF, 0x00, 0x40, 0x40 }; 134 0x00, 0xFF, 0x00, 0x40, 0x40 };
133 static u8 dntv_extra[] = { 0xB5, 0x7A }; 135 static u8 dntv_extra[] = { 0xB5, 0x7A };
134 static u8 capt_range_cfg[] = { 0x75, 0x32 }; 136 static u8 capt_range_cfg[] = { 0x75, 0x32 };
135 137
@@ -285,6 +287,33 @@ static struct lgdt330x_config fusionhdtv_5_gold = {
285}; 287};
286#endif 288#endif
287 289
290#ifdef HAVE_NXT200X
291static int nxt200x_set_ts_param(struct dvb_frontend* fe,
292 int is_punctured)
293{
294 struct cx8802_dev *dev= fe->dvb->priv;
295 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
296 return 0;
297}
298
299static int nxt200x_set_pll_input(u8* buf, int input)
300{
301 if (input)
302 buf[3] |= 0x08;
303 else
304 buf[3] &= ~0x08;
305 return 0;
306}
307
308static struct nxt200x_config ati_hdtvwonder = {
309 .demod_address = 0x0a,
310 .pll_address = 0x61,
311 .pll_desc = &dvb_pll_tuv1236d,
312 .set_pll_input = nxt200x_set_pll_input,
313 .set_ts_params = nxt200x_set_ts_param,
314};
315#endif
316
288static int dvb_register(struct cx8802_dev *dev) 317static int dvb_register(struct cx8802_dev *dev)
289{ 318{
290 /* init struct videobuf_dvb */ 319 /* init struct videobuf_dvb */
@@ -300,6 +329,7 @@ static int dvb_register(struct cx8802_dev *dev)
300 break; 329 break;
301 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: 330 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
302 case CX88_BOARD_CONEXANT_DVB_T1: 331 case CX88_BOARD_CONEXANT_DVB_T1:
332 case CX88_BOARD_WINFAST_DTV1000:
303 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, 333 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
304 &dev->core->i2c_adap); 334 &dev->core->i2c_adap);
305 break; 335 break;
@@ -385,6 +415,12 @@ static int dvb_register(struct cx8802_dev *dev)
385 } 415 }
386 break; 416 break;
387#endif 417#endif
418#ifdef HAVE_NXT200X
419 case CX88_BOARD_ATI_HDTVWONDER:
420 dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder,
421 &dev->core->i2c_adap);
422 break;
423#endif
388 default: 424 default:
389 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 425 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
390 dev->core->name); 426 dev->core->name);
@@ -403,6 +439,9 @@ static int dvb_register(struct cx8802_dev *dev)
403 /* Put the analog decoder in standby to keep it quiet */ 439 /* Put the analog decoder in standby to keep it quiet */
404 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 440 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
405 441
442 /* Put the analog decoder in standby to keep it quiet */
443 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
444
406 /* register everything */ 445 /* register everything */
407 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev); 446 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
408} 447}
@@ -461,7 +500,7 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
461 500
462static void __devexit dvb_remove(struct pci_dev *pci_dev) 501static void __devexit dvb_remove(struct pci_dev *pci_dev)
463{ 502{
464 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 503 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
465 504
466 /* dvb */ 505 /* dvb */
467 videobuf_dvb_unregister(&dev->dvb); 506 videobuf_dvb_unregister(&dev->dvb);
@@ -476,8 +515,8 @@ static struct pci_device_id cx8802_pci_tbl[] = {
476 { 515 {
477 .vendor = 0x14f1, 516 .vendor = 0x14f1,
478 .device = 0x8802, 517 .device = 0x8802,
479 .subvendor = PCI_ANY_ID, 518 .subvendor = PCI_ANY_ID,
480 .subdevice = PCI_ANY_ID, 519 .subdevice = PCI_ANY_ID,
481 },{ 520 },{
482 /* --- end of list --- */ 521 /* --- end of list --- */
483 } 522 }
@@ -485,10 +524,10 @@ static struct pci_device_id cx8802_pci_tbl[] = {
485MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); 524MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
486 525
487static struct pci_driver dvb_pci_driver = { 526static struct pci_driver dvb_pci_driver = {
488 .name = "cx88-dvb", 527 .name = "cx88-dvb",
489 .id_table = cx8802_pci_tbl, 528 .id_table = cx8802_pci_tbl,
490 .probe = dvb_probe, 529 .probe = dvb_probe,
491 .remove = __devexit_p(dvb_remove), 530 .remove = __devexit_p(dvb_remove),
492 .suspend = cx8802_suspend_common, 531 .suspend = cx8802_suspend_common,
493 .resume = cx8802_resume_common, 532 .resume = cx8802_resume_common,
494}; 533};
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 761cebd40dbd..9790d412f192 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -3,7 +3,7 @@
3 cx88-i2c.c -- all the i2c code is here 3 cx88-i2c.c -- all the i2c code is here
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
6 & Marcus Metzler (mocm@thp.uni-koeln.de) 6 & Marcus Metzler (mocm@thp.uni-koeln.de)
7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net> 7 (c) 2002 Yurij Sysoev <yurij@naturesoft.net>
8 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> 8 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
9 9
@@ -90,7 +90,7 @@ static int cx8800_bit_getsda(void *data)
90 90
91static int attach_inform(struct i2c_client *client) 91static int attach_inform(struct i2c_client *client)
92{ 92{
93 struct tuner_setup tun_setup; 93 struct tuner_setup tun_setup;
94 struct cx88_core *core = i2c_get_adapdata(client->adapter); 94 struct cx88_core *core = i2c_get_adapdata(client->adapter);
95 95
96 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", 96 dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
@@ -98,7 +98,7 @@ static int attach_inform(struct i2c_client *client)
98 if (!client->driver->command) 98 if (!client->driver->command)
99 return 0; 99 return 0;
100 100
101 if (core->radio_type != UNSET) { 101 if (core->radio_type != UNSET) {
102 if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) { 102 if ((core->radio_addr==ADDR_UNSET)||(core->radio_addr==client->addr)) {
103 tun_setup.mode_mask = T_RADIO; 103 tun_setup.mode_mask = T_RADIO;
104 tun_setup.type = core->radio_type; 104 tun_setup.type = core->radio_type;
@@ -106,8 +106,8 @@ static int attach_inform(struct i2c_client *client)
106 106
107 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup); 107 client->driver->command (client, TUNER_SET_TYPE_ADDR, &tun_setup);
108 } 108 }
109 } 109 }
110 if (core->tuner_type != UNSET) { 110 if (core->tuner_type != UNSET) {
111 if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) { 111 if ((core->tuner_addr==ADDR_UNSET)||(core->tuner_addr==client->addr)) {
112 112
113 tun_setup.mode_mask = T_ANALOG_TV; 113 tun_setup.mode_mask = T_ANALOG_TV;
@@ -116,7 +116,7 @@ static int attach_inform(struct i2c_client *client)
116 116
117 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup); 117 client->driver->command (client,TUNER_SET_TYPE_ADDR, &tun_setup);
118 } 118 }
119 } 119 }
120 120
121 if (core->tda9887_conf) 121 if (core->tda9887_conf)
122 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf); 122 client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
@@ -159,7 +159,7 @@ static struct i2c_adapter cx8800_i2c_adap_template = {
159}; 159};
160 160
161static struct i2c_client cx8800_i2c_client_template = { 161static struct i2c_client cx8800_i2c_client_template = {
162 .name = "cx88xx internal", 162 .name = "cx88xx internal",
163}; 163};
164 164
165static char *i2c_devs[128] = { 165static char *i2c_devs[128] = {
@@ -202,10 +202,10 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
202 202
203 core->i2c_adap.dev.parent = &pci->dev; 203 core->i2c_adap.dev.parent = &pci->dev;
204 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name)); 204 strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
205 core->i2c_algo.data = core; 205 core->i2c_algo.data = core;
206 i2c_set_adapdata(&core->i2c_adap,core); 206 i2c_set_adapdata(&core->i2c_adap,core);
207 core->i2c_adap.algo_data = &core->i2c_algo; 207 core->i2c_adap.algo_data = &core->i2c_algo;
208 core->i2c_client.adapter = &core->i2c_adap; 208 core->i2c_client.adapter = &core->i2c_adap;
209 209
210 cx8800_bit_setscl(core,1); 210 cx8800_bit_setscl(core,1);
211 cx8800_bit_setsda(core,1); 211 cx8800_bit_setsda(core,1);
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index c27fe4c36f69..38b12ebaa49e 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -553,7 +553,7 @@ void cx88_ir_irq(struct cx88_core *core)
553 553
554 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ 554 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
555 ir_dprintk("pulse distance decoded wrong address\n"); 555 ir_dprintk("pulse distance decoded wrong address\n");
556 break; 556 break;
557 } 557 }
558 558
559 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */ 559 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index ee2300e1ae0b..35e6d0c2b872 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -54,7 +54,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
54{ 54{
55 struct cx88_core *core = dev->core; 55 struct cx88_core *core = dev->core;
56 56
57 dprintk(0, "cx8802_start_dma %d\n", buf->vb.width); 57 dprintk(0, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
58 58
59 /* setup fifo + format */ 59 /* setup fifo + format */
60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], 60 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -158,7 +158,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
158 158
159/* ------------------------------------------------------------------ */ 159/* ------------------------------------------------------------------ */
160 160
161int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf) 161int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
162 enum v4l2_field field)
162{ 163{
163 int size = dev->ts_packet_size * dev->ts_packet_count; 164 int size = dev->ts_packet_size * dev->ts_packet_count;
164 int rc; 165 int rc;
@@ -171,7 +172,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf)
171 buf->vb.width = dev->ts_packet_size; 172 buf->vb.width = dev->ts_packet_size;
172 buf->vb.height = dev->ts_packet_count; 173 buf->vb.height = dev->ts_packet_count;
173 buf->vb.size = size; 174 buf->vb.size = size;
174 buf->vb.field = V4L2_FIELD_TOP; 175 buf->vb.field = field /*V4L2_FIELD_TOP*/;
175 176
176 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL))) 177 if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
177 goto fail; 178 goto fail;
@@ -315,14 +316,14 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
315 spin_unlock(&dev->slock); 316 spin_unlock(&dev->slock);
316 } 317 }
317 318
318 /* other general errors */ 319 /* other general errors */
319 if (status & 0x1f0100) { 320 if (status & 0x1f0100) {
320 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); 321 dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
321 spin_lock(&dev->slock); 322 spin_lock(&dev->slock);
322 cx8802_stop_dma(dev); 323 cx8802_stop_dma(dev);
323 cx8802_restart_queue(dev,&dev->mpegq); 324 cx8802_restart_queue(dev,&dev->mpegq);
324 spin_unlock(&dev->slock); 325 spin_unlock(&dev->slock);
325 } 326 }
326} 327}
327 328
328#define MAX_IRQ_LOOP 10 329#define MAX_IRQ_LOOP 10
@@ -378,8 +379,8 @@ int cx8802_init_common(struct cx8802_dev *dev)
378 } 379 }
379 380
380 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); 381 pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
381 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); 382 pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat);
382 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " 383 printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
383 "latency: %d, mmio: 0x%lx\n", dev->core->name, 384 "latency: %d, mmio: 0x%lx\n", dev->core->name,
384 pci_name(dev->pci), dev->pci_rev, dev->pci->irq, 385 pci_name(dev->pci), dev->pci_rev, dev->pci->irq,
385 dev->pci_lat,pci_resource_start(dev->pci,0)); 386 dev->pci_lat,pci_resource_start(dev->pci,0));
@@ -429,7 +430,7 @@ void cx8802_fini_common(struct cx8802_dev *dev)
429 430
430int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) 431int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
431{ 432{
432 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 433 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
433 struct cx88_core *core = dev->core; 434 struct cx88_core *core = dev->core;
434 435
435 /* stop mpeg dma */ 436 /* stop mpeg dma */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 0a3a62fc9bbb..d3bf5b17b1d4 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -3,9 +3,9 @@
3 cx88x-hw.h - CX2388x register offsets 3 cx88x-hw.h - CX2388x register offsets
4 4
5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 5 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
6 2001 Michael Eskin 6 2001 Michael Eskin
7 2002 Yurij Sysoev <yurij@naturesoft.net> 7 2002 Yurij Sysoev <yurij@naturesoft.net>
8 2003 Gerd Knorr <kraxel@bytesex.org> 8 2003 Gerd Knorr <kraxel@bytesex.org>
9 9
10 This program is free software; you can redistribute it and/or modify 10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by 11 it under the terms of the GNU General Public License as published by
@@ -728,13 +728,13 @@
728#define ColorFormatGamma 0x1000 728#define ColorFormatGamma 0x1000
729 729
730#define Interlaced 0x1 730#define Interlaced 0x1
731#define NonInterlaced 0x0 731#define NonInterlaced 0x0
732 732
733#define FieldEven 0x1 733#define FieldEven 0x1
734#define FieldOdd 0x0 734#define FieldOdd 0x0
735 735
736#define TGReadWriteMode 0x0 736#define TGReadWriteMode 0x0
737#define TGEnableMode 0x1 737#define TGEnableMode 0x1
738 738
739#define DV_CbAlign 0x0 739#define DV_CbAlign 0x0
740#define DV_Y0Align 0x1 740#define DV_Y0Align 0x1
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 2765acee0285..6d9bec1c583b 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -57,39 +57,38 @@
57#include "cx88.h" 57#include "cx88.h"
58 58
59static unsigned int audio_debug = 0; 59static unsigned int audio_debug = 0;
60module_param(audio_debug,int,0644); 60module_param(audio_debug, int, 0644);
61MODULE_PARM_DESC(audio_debug,"enable debug messages [audio]"); 61MODULE_PARM_DESC(audio_debug, "enable debug messages [audio]");
62 62
63#define dprintk(fmt, arg...) if (audio_debug) \ 63#define dprintk(fmt, arg...) if (audio_debug) \
64 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg) 64 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
65 65
66/* ----------------------------------------------------------- */ 66/* ----------------------------------------------------------- */
67 67
68static char *aud_ctl_names[64] = 68static char *aud_ctl_names[64] = {
69{ 69 [EN_BTSC_FORCE_MONO] = "BTSC_FORCE_MONO",
70 [ EN_BTSC_FORCE_MONO ] = "BTSC_FORCE_MONO", 70 [EN_BTSC_FORCE_STEREO] = "BTSC_FORCE_STEREO",
71 [ EN_BTSC_FORCE_STEREO ] = "BTSC_FORCE_STEREO", 71 [EN_BTSC_FORCE_SAP] = "BTSC_FORCE_SAP",
72 [ EN_BTSC_FORCE_SAP ] = "BTSC_FORCE_SAP", 72 [EN_BTSC_AUTO_STEREO] = "BTSC_AUTO_STEREO",
73 [ EN_BTSC_AUTO_STEREO ] = "BTSC_AUTO_STEREO", 73 [EN_BTSC_AUTO_SAP] = "BTSC_AUTO_SAP",
74 [ EN_BTSC_AUTO_SAP ] = "BTSC_AUTO_SAP", 74 [EN_A2_FORCE_MONO1] = "A2_FORCE_MONO1",
75 [ EN_A2_FORCE_MONO1 ] = "A2_FORCE_MONO1", 75 [EN_A2_FORCE_MONO2] = "A2_FORCE_MONO2",
76 [ EN_A2_FORCE_MONO2 ] = "A2_FORCE_MONO2", 76 [EN_A2_FORCE_STEREO] = "A2_FORCE_STEREO",
77 [ EN_A2_FORCE_STEREO ] = "A2_FORCE_STEREO", 77 [EN_A2_AUTO_MONO2] = "A2_AUTO_MONO2",
78 [ EN_A2_AUTO_MONO2 ] = "A2_AUTO_MONO2", 78 [EN_A2_AUTO_STEREO] = "A2_AUTO_STEREO",
79 [ EN_A2_AUTO_STEREO ] = "A2_AUTO_STEREO", 79 [EN_EIAJ_FORCE_MONO1] = "EIAJ_FORCE_MONO1",
80 [ EN_EIAJ_FORCE_MONO1 ] = "EIAJ_FORCE_MONO1", 80 [EN_EIAJ_FORCE_MONO2] = "EIAJ_FORCE_MONO2",
81 [ EN_EIAJ_FORCE_MONO2 ] = "EIAJ_FORCE_MONO2", 81 [EN_EIAJ_FORCE_STEREO] = "EIAJ_FORCE_STEREO",
82 [ EN_EIAJ_FORCE_STEREO ] = "EIAJ_FORCE_STEREO", 82 [EN_EIAJ_AUTO_MONO2] = "EIAJ_AUTO_MONO2",
83 [ EN_EIAJ_AUTO_MONO2 ] = "EIAJ_AUTO_MONO2", 83 [EN_EIAJ_AUTO_STEREO] = "EIAJ_AUTO_STEREO",
84 [ EN_EIAJ_AUTO_STEREO ] = "EIAJ_AUTO_STEREO", 84 [EN_NICAM_FORCE_MONO1] = "NICAM_FORCE_MONO1",
85 [ EN_NICAM_FORCE_MONO1 ] = "NICAM_FORCE_MONO1", 85 [EN_NICAM_FORCE_MONO2] = "NICAM_FORCE_MONO2",
86 [ EN_NICAM_FORCE_MONO2 ] = "NICAM_FORCE_MONO2", 86 [EN_NICAM_FORCE_STEREO] = "NICAM_FORCE_STEREO",
87 [ EN_NICAM_FORCE_STEREO ] = "NICAM_FORCE_STEREO", 87 [EN_NICAM_AUTO_MONO2] = "NICAM_AUTO_MONO2",
88 [ EN_NICAM_AUTO_MONO2 ] = "NICAM_AUTO_MONO2", 88 [EN_NICAM_AUTO_STEREO] = "NICAM_AUTO_STEREO",
89 [ EN_NICAM_AUTO_STEREO ] = "NICAM_AUTO_STEREO", 89 [EN_FMRADIO_FORCE_MONO] = "FMRADIO_FORCE_MONO",
90 [ EN_FMRADIO_FORCE_MONO ] = "FMRADIO_FORCE_MONO", 90 [EN_FMRADIO_FORCE_STEREO] = "FMRADIO_FORCE_STEREO",
91 [ EN_FMRADIO_FORCE_STEREO ] = "FMRADIO_FORCE_STEREO", 91 [EN_FMRADIO_AUTO_STEREO] = "FMRADIO_AUTO_STEREO",
92 [ EN_FMRADIO_AUTO_STEREO ] = "FMRADIO_AUTO_STEREO",
93}; 92};
94 93
95struct rlist { 94struct rlist {
@@ -97,8 +96,7 @@ struct rlist {
97 u32 val; 96 u32 val;
98}; 97};
99 98
100static void set_audio_registers(struct cx88_core *core, 99static void set_audio_registers(struct cx88_core *core, const struct rlist *l)
101 const struct rlist *l)
102{ 100{
103 int i; 101 int i;
104 102
@@ -119,17 +117,18 @@ static void set_audio_registers(struct cx88_core *core,
119 } 117 }
120} 118}
121 119
122static void set_audio_start(struct cx88_core *core, 120static void set_audio_start(struct cx88_core *core, u32 mode)
123 u32 mode)
124{ 121{
125 // mute 122 // mute
126 cx_write(AUD_VOL_CTL, (1 << 6)); 123 cx_write(AUD_VOL_CTL, (1 << 6));
127 124
128 // start programming 125 // start programming
129 cx_write(AUD_CTL, 0x0000); 126 cx_write(MO_AUD_DMACNTRL, 0x0000);
130 cx_write(AUD_INIT, mode); 127 msleep(100);
131 cx_write(AUD_INIT_LD, 0x0001); 128 //cx_write(AUD_CTL, 0x0000);
132 cx_write(AUD_SOFT_RESET, 0x0001); 129 cx_write(AUD_INIT, mode);
130 cx_write(AUD_INIT_LD, 0x0001);
131 cx_write(AUD_SOFT_RESET, 0x0001);
133} 132}
134 133
135static void set_audio_finish(struct cx88_core *core, u32 ctl) 134static void set_audio_finish(struct cx88_core *core, u32 ctl)
@@ -148,12 +147,13 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
148 cx_write(AUD_I2SCNTL, 0); 147 cx_write(AUD_I2SCNTL, 0);
149 //cx_write(AUD_APB_IN_RATE_ADJ, 0); 148 //cx_write(AUD_APB_IN_RATE_ADJ, 0);
150 } else { 149 } else {
151 ctl |= EN_DAC_ENABLE; 150 ctl |= EN_DAC_ENABLE;
152 cx_write(AUD_CTL, ctl); 151 cx_write(AUD_CTL, ctl);
153 } 152 }
154 153
155 /* finish programming */ 154 /* finish programming */
156 cx_write(AUD_SOFT_RESET, 0x0000); 155 cx_write(AUD_SOFT_RESET, 0x0000);
156 cx_write(MO_AUD_DMACNTRL, 0x0003);
157 157
158 /* unmute */ 158 /* unmute */
159 volume = cx_sread(SHADOW_AUD_VOL_CTL); 159 volume = cx_sread(SHADOW_AUD_VOL_CTL);
@@ -162,486 +162,463 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl)
162 162
163/* ----------------------------------------------------------- */ 163/* ----------------------------------------------------------- */
164 164
165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, u32 mode) 165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap,
166 u32 mode)
166{ 167{
167 static const struct rlist btsc[] = { 168 static const struct rlist btsc[] = {
168 { AUD_AFE_12DB_EN, 0x00000001 }, 169 {AUD_AFE_12DB_EN, 0x00000001},
169 { AUD_OUT1_SEL, 0x00000013 }, 170 {AUD_OUT1_SEL, 0x00000013},
170 { AUD_OUT1_SHIFT, 0x00000000 }, 171 {AUD_OUT1_SHIFT, 0x00000000},
171 { AUD_POLY0_DDS_CONSTANT, 0x0012010c }, 172 {AUD_POLY0_DDS_CONSTANT, 0x0012010c},
172 { AUD_DMD_RA_DDS, 0x00c3e7aa }, 173 {AUD_DMD_RA_DDS, 0x00c3e7aa},
173 { AUD_DBX_IN_GAIN, 0x00004734 }, 174 {AUD_DBX_IN_GAIN, 0x00004734},
174 { AUD_DBX_WBE_GAIN, 0x00004640 }, 175 {AUD_DBX_WBE_GAIN, 0x00004640},
175 { AUD_DBX_SE_GAIN, 0x00008d31 }, 176 {AUD_DBX_SE_GAIN, 0x00008d31},
176 { AUD_DCOC_0_SRC, 0x0000001a }, 177 {AUD_DCOC_0_SRC, 0x0000001a},
177 { AUD_IIR1_4_SEL, 0x00000021 }, 178 {AUD_IIR1_4_SEL, 0x00000021},
178 { AUD_DCOC_PASS_IN, 0x00000003 }, 179 {AUD_DCOC_PASS_IN, 0x00000003},
179 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 180 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
180 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 181 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
181 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 182 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
182 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 183 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
183 { AUD_DN0_FREQ, 0x0000283b }, 184 {AUD_DN0_FREQ, 0x0000283b},
184 { AUD_DN2_SRC_SEL, 0x00000008 }, 185 {AUD_DN2_SRC_SEL, 0x00000008},
185 { AUD_DN2_FREQ, 0x00003000 }, 186 {AUD_DN2_FREQ, 0x00003000},
186 { AUD_DN2_AFC, 0x00000002 }, 187 {AUD_DN2_AFC, 0x00000002},
187 { AUD_DN2_SHFT, 0x00000000 }, 188 {AUD_DN2_SHFT, 0x00000000},
188 { AUD_IIR2_2_SEL, 0x00000020 }, 189 {AUD_IIR2_2_SEL, 0x00000020},
189 { AUD_IIR2_2_SHIFT, 0x00000000 }, 190 {AUD_IIR2_2_SHIFT, 0x00000000},
190 { AUD_IIR2_3_SEL, 0x0000001f }, 191 {AUD_IIR2_3_SEL, 0x0000001f},
191 { AUD_IIR2_3_SHIFT, 0x00000000 }, 192 {AUD_IIR2_3_SHIFT, 0x00000000},
192 { AUD_CRDC1_SRC_SEL, 0x000003ce }, 193 {AUD_CRDC1_SRC_SEL, 0x000003ce},
193 { AUD_CRDC1_SHIFT, 0x00000000 }, 194 {AUD_CRDC1_SHIFT, 0x00000000},
194 { AUD_CORDIC_SHIFT_1, 0x00000007 }, 195 {AUD_CORDIC_SHIFT_1, 0x00000007},
195 { AUD_DCOC_1_SRC, 0x0000001b }, 196 {AUD_DCOC_1_SRC, 0x0000001b},
196 { AUD_DCOC1_SHIFT, 0x00000000 }, 197 {AUD_DCOC1_SHIFT, 0x00000000},
197 { AUD_RDSI_SEL, 0x00000008 }, 198 {AUD_RDSI_SEL, 0x00000008},
198 { AUD_RDSQ_SEL, 0x00000008 }, 199 {AUD_RDSQ_SEL, 0x00000008},
199 { AUD_RDSI_SHIFT, 0x00000000 }, 200 {AUD_RDSI_SHIFT, 0x00000000},
200 { AUD_RDSQ_SHIFT, 0x00000000 }, 201 {AUD_RDSQ_SHIFT, 0x00000000},
201 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 202 {AUD_POLYPH80SCALEFAC, 0x00000003},
202 { /* end of list */ }, 203 { /* end of list */ },
203 }; 204 };
204 static const struct rlist btsc_sap[] = { 205 static const struct rlist btsc_sap[] = {
205 { AUD_AFE_12DB_EN, 0x00000001 }, 206 {AUD_AFE_12DB_EN, 0x00000001},
206 { AUD_DBX_IN_GAIN, 0x00007200 }, 207 {AUD_DBX_IN_GAIN, 0x00007200},
207 { AUD_DBX_WBE_GAIN, 0x00006200 }, 208 {AUD_DBX_WBE_GAIN, 0x00006200},
208 { AUD_DBX_SE_GAIN, 0x00006200 }, 209 {AUD_DBX_SE_GAIN, 0x00006200},
209 { AUD_IIR1_1_SEL, 0x00000000 }, 210 {AUD_IIR1_1_SEL, 0x00000000},
210 { AUD_IIR1_3_SEL, 0x00000001 }, 211 {AUD_IIR1_3_SEL, 0x00000001},
211 { AUD_DN1_SRC_SEL, 0x00000007 }, 212 {AUD_DN1_SRC_SEL, 0x00000007},
212 { AUD_IIR1_4_SHIFT, 0x00000006 }, 213 {AUD_IIR1_4_SHIFT, 0x00000006},
213 { AUD_IIR2_1_SHIFT, 0x00000000 }, 214 {AUD_IIR2_1_SHIFT, 0x00000000},
214 { AUD_IIR2_2_SHIFT, 0x00000000 }, 215 {AUD_IIR2_2_SHIFT, 0x00000000},
215 { AUD_IIR3_0_SHIFT, 0x00000000 }, 216 {AUD_IIR3_0_SHIFT, 0x00000000},
216 { AUD_IIR3_1_SHIFT, 0x00000000 }, 217 {AUD_IIR3_1_SHIFT, 0x00000000},
217 { AUD_IIR3_0_SEL, 0x0000000d }, 218 {AUD_IIR3_0_SEL, 0x0000000d},
218 { AUD_IIR3_1_SEL, 0x0000000e }, 219 {AUD_IIR3_1_SEL, 0x0000000e},
219 { AUD_DEEMPH1_SRC_SEL, 0x00000014 }, 220 {AUD_DEEMPH1_SRC_SEL, 0x00000014},
220 { AUD_DEEMPH1_SHIFT, 0x00000000 }, 221 {AUD_DEEMPH1_SHIFT, 0x00000000},
221 { AUD_DEEMPH1_G0, 0x00004000 }, 222 {AUD_DEEMPH1_G0, 0x00004000},
222 { AUD_DEEMPH1_A0, 0x00000000 }, 223 {AUD_DEEMPH1_A0, 0x00000000},
223 { AUD_DEEMPH1_B0, 0x00000000 }, 224 {AUD_DEEMPH1_B0, 0x00000000},
224 { AUD_DEEMPH1_A1, 0x00000000 }, 225 {AUD_DEEMPH1_A1, 0x00000000},
225 { AUD_DEEMPH1_B1, 0x00000000 }, 226 {AUD_DEEMPH1_B1, 0x00000000},
226 { AUD_OUT0_SEL, 0x0000003f }, 227 {AUD_OUT0_SEL, 0x0000003f},
227 { AUD_OUT1_SEL, 0x0000003f }, 228 {AUD_OUT1_SEL, 0x0000003f},
228 { AUD_DN1_AFC, 0x00000002 }, 229 {AUD_DN1_AFC, 0x00000002},
229 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 230 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
230 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 231 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
231 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 232 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
232 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 233 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
233 { AUD_IIR1_0_SEL, 0x0000001d }, 234 {AUD_IIR1_0_SEL, 0x0000001d},
234 { AUD_IIR1_2_SEL, 0x0000001e }, 235 {AUD_IIR1_2_SEL, 0x0000001e},
235 { AUD_IIR2_1_SEL, 0x00000002 }, 236 {AUD_IIR2_1_SEL, 0x00000002},
236 { AUD_IIR2_2_SEL, 0x00000004 }, 237 {AUD_IIR2_2_SEL, 0x00000004},
237 { AUD_IIR3_2_SEL, 0x0000000f }, 238 {AUD_IIR3_2_SEL, 0x0000000f},
238 { AUD_DCOC2_SHIFT, 0x00000001 }, 239 {AUD_DCOC2_SHIFT, 0x00000001},
239 { AUD_IIR3_2_SHIFT, 0x00000001 }, 240 {AUD_IIR3_2_SHIFT, 0x00000001},
240 { AUD_DEEMPH0_SRC_SEL, 0x00000014 }, 241 {AUD_DEEMPH0_SRC_SEL, 0x00000014},
241 { AUD_CORDIC_SHIFT_1, 0x00000006 }, 242 {AUD_CORDIC_SHIFT_1, 0x00000006},
242 { AUD_POLY0_DDS_CONSTANT, 0x000e4db2 }, 243 {AUD_POLY0_DDS_CONSTANT, 0x000e4db2},
243 { AUD_DMD_RA_DDS, 0x00f696e6 }, 244 {AUD_DMD_RA_DDS, 0x00f696e6},
244 { AUD_IIR2_3_SEL, 0x00000025 }, 245 {AUD_IIR2_3_SEL, 0x00000025},
245 { AUD_IIR1_4_SEL, 0x00000021 }, 246 {AUD_IIR1_4_SEL, 0x00000021},
246 { AUD_DN1_FREQ, 0x0000c965 }, 247 {AUD_DN1_FREQ, 0x0000c965},
247 { AUD_DCOC_PASS_IN, 0x00000003 }, 248 {AUD_DCOC_PASS_IN, 0x00000003},
248 { AUD_DCOC_0_SRC, 0x0000001a }, 249 {AUD_DCOC_0_SRC, 0x0000001a},
249 { AUD_DCOC_1_SRC, 0x0000001b }, 250 {AUD_DCOC_1_SRC, 0x0000001b},
250 { AUD_DCOC1_SHIFT, 0x00000000 }, 251 {AUD_DCOC1_SHIFT, 0x00000000},
251 { AUD_RDSI_SEL, 0x00000009 }, 252 {AUD_RDSI_SEL, 0x00000009},
252 { AUD_RDSQ_SEL, 0x00000009 }, 253 {AUD_RDSQ_SEL, 0x00000009},
253 { AUD_RDSI_SHIFT, 0x00000000 }, 254 {AUD_RDSI_SHIFT, 0x00000000},
254 { AUD_RDSQ_SHIFT, 0x00000000 }, 255 {AUD_RDSQ_SHIFT, 0x00000000},
255 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 256 {AUD_POLYPH80SCALEFAC, 0x00000003},
256 { /* end of list */ }, 257 { /* end of list */ },
257 }; 258 };
258 259
259 mode |= EN_FMRADIO_EN_RDS; 260 mode |= EN_FMRADIO_EN_RDS;
260 261
261 if (sap) { 262 if (sap) {
262 dprintk("%s SAP (status: unknown)\n",__FUNCTION__); 263 dprintk("%s SAP (status: unknown)\n", __FUNCTION__);
263 set_audio_start(core, SEL_SAP); 264 set_audio_start(core, SEL_SAP);
264 set_audio_registers(core, btsc_sap); 265 set_audio_registers(core, btsc_sap);
265 set_audio_finish(core, mode); 266 set_audio_finish(core, mode);
266 } else { 267 } else {
267 dprintk("%s (status: known-good)\n",__FUNCTION__); 268 dprintk("%s (status: known-good)\n", __FUNCTION__);
268 set_audio_start(core, SEL_BTSC); 269 set_audio_start(core, SEL_BTSC);
269 set_audio_registers(core, btsc); 270 set_audio_registers(core, btsc);
270 set_audio_finish(core, mode); 271 set_audio_finish(core, mode);
271 } 272 }
272} 273}
273 274
274 275static void set_audio_standard_NICAM(struct cx88_core *core, u32 mode)
275static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
276{ 276{
277 /* This is probably weird.. 277 static const struct rlist nicam_l[] = {
278 * Let's operate and find out. */ 278 {AUD_AFE_12DB_EN, 0x00000001},
279 279 {AUD_RATE_ADJ1, 0x00000060},
280 static const struct rlist nicam_l_mono[] = { 280 {AUD_RATE_ADJ2, 0x000000F9},
281 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 281 {AUD_RATE_ADJ3, 0x000001CC},
282 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 282 {AUD_RATE_ADJ4, 0x000002B3},
283 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 283 {AUD_RATE_ADJ5, 0x00000726},
284 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 284 {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
285 285 {AUD_DEEMPHDENOM2_R, 0x00000000},
286 { AUD_PDF_DDS_CNST_BYTE2, 0x48 }, 286 {AUD_ERRLOGPERIOD_R, 0x00000064},
287 { AUD_PDF_DDS_CNST_BYTE1, 0x3D }, 287 {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
288 { AUD_QAM_MODE, 0x00 }, 288 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
289 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 }, 289 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
290 { AUD_PHACC_FREQ_8MSB, 0x3a }, 290 {AUD_POLYPH80SCALEFAC, 0x00000003},
291 { AUD_PHACC_FREQ_8LSB, 0x4a }, 291 {AUD_DMD_RA_DDS, 0x00C00000},
292 292 {AUD_PLL_INT, 0x0000001E},
293 { AUD_DEEMPHGAIN_R, 0x6680 }, 293 {AUD_PLL_DDS, 0x00000000},
294 { AUD_DEEMPHNUMER1_R, 0x353DE }, 294 {AUD_PLL_FRAC, 0x0000E542},
295 { AUD_DEEMPHNUMER2_R, 0x1B1 }, 295 {AUD_START_TIMER, 0x00000000},
296 { AUD_DEEMPHDENOM1_R, 0x0F3D0 }, 296 {AUD_DEEMPHNUMER1_R, 0x000353DE},
297 { AUD_DEEMPHDENOM2_R, 0x0 }, 297 {AUD_DEEMPHNUMER2_R, 0x000001B1},
298 { AUD_FM_MODE_ENABLE, 0x7 }, 298 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
299 { AUD_POLYPH80SCALEFAC, 0x3 }, 299 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
300 { AUD_AFE_12DB_EN, 0x1 }, 300 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
301 { AAGC_GAIN, 0x0 }, 301 {AUD_QAM_MODE, 0x05},
302 { AAGC_HYST, 0x18 }, 302 {AUD_PHACC_FREQ_8MSB, 0x34},
303 { AAGC_DEF, 0x20 }, 303 {AUD_PHACC_FREQ_8LSB, 0x4C},
304 { AUD_DN0_FREQ, 0x0 }, 304 {AUD_DEEMPHGAIN_R, 0x00006680},
305 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 }, 305 {AUD_RATE_THRES_DMD, 0x000000C0},
306 { AUD_DCOC_0_SRC, 0x21 },
307 { AUD_IIR1_0_SEL, 0x0 },
308 { AUD_IIR1_0_SHIFT, 0x7 },
309 { AUD_IIR1_1_SEL, 0x2 },
310 { AUD_IIR1_1_SHIFT, 0x0 },
311 { AUD_DCOC_1_SRC, 0x3 },
312 { AUD_DCOC1_SHIFT, 0x0 },
313 { AUD_DCOC_PASS_IN, 0x0 },
314 { AUD_IIR1_2_SEL, 0x23 },
315 { AUD_IIR1_2_SHIFT, 0x0 },
316 { AUD_IIR1_3_SEL, 0x4 },
317 { AUD_IIR1_3_SHIFT, 0x7 },
318 { AUD_IIR1_4_SEL, 0x5 },
319 { AUD_IIR1_4_SHIFT, 0x7 },
320 { AUD_IIR3_0_SEL, 0x7 },
321 { AUD_IIR3_0_SHIFT, 0x0 },
322 { AUD_DEEMPH0_SRC_SEL, 0x11 },
323 { AUD_DEEMPH0_SHIFT, 0x0 },
324 { AUD_DEEMPH0_G0, 0x7000 },
325 { AUD_DEEMPH0_A0, 0x0 },
326 { AUD_DEEMPH0_B0, 0x0 },
327 { AUD_DEEMPH0_A1, 0x0 },
328 { AUD_DEEMPH0_B1, 0x0 },
329 { AUD_DEEMPH1_SRC_SEL, 0x11 },
330 { AUD_DEEMPH1_SHIFT, 0x0 },
331 { AUD_DEEMPH1_G0, 0x7000 },
332 { AUD_DEEMPH1_A0, 0x0 },
333 { AUD_DEEMPH1_B0, 0x0 },
334 { AUD_DEEMPH1_A1, 0x0 },
335 { AUD_DEEMPH1_B1, 0x0 },
336 { AUD_OUT0_SEL, 0x3F },
337 { AUD_OUT1_SEL, 0x3F },
338 { AUD_DMD_RA_DDS, 0x0F5C285 },
339 { AUD_PLL_INT, 0x1E },
340 { AUD_PLL_DDS, 0x0 },
341 { AUD_PLL_FRAC, 0x0E542 },
342
343 // setup QAM registers
344 { AUD_RATE_ADJ1, 0x00000100 },
345 { AUD_RATE_ADJ2, 0x00000200 },
346 { AUD_RATE_ADJ3, 0x00000300 },
347 { AUD_RATE_ADJ4, 0x00000400 },
348 { AUD_RATE_ADJ5, 0x00000500 },
349 { AUD_RATE_THRES_DMD, 0x000000C0 },
350 { /* end of list */ }, 306 { /* end of list */ },
351 }; 307 };
352 308
353 static const struct rlist nicam_l[] = { 309 static const struct rlist nicam_bgdki_common[] = {
354 // setup QAM registers 310 {AUD_AFE_12DB_EN, 0x00000001},
355 { AUD_RATE_ADJ1, 0x00000060 }, 311 {AUD_RATE_ADJ1, 0x00000010},
356 { AUD_RATE_ADJ2, 0x000000F9 }, 312 {AUD_RATE_ADJ2, 0x00000040},
357 { AUD_RATE_ADJ3, 0x000001CC }, 313 {AUD_RATE_ADJ3, 0x00000100},
358 { AUD_RATE_ADJ4, 0x000002B3 }, 314 {AUD_RATE_ADJ4, 0x00000400},
359 { AUD_RATE_ADJ5, 0x00000726 }, 315 {AUD_RATE_ADJ5, 0x00001000},
360 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 }, 316 //{ AUD_DMD_RA_DDS, 0x00c0d5ce },
361 { AUD_DEEMPHDENOM2_R, 0x00000000 }, 317 {AUD_ERRLOGPERIOD_R, 0x00000fff},
362 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 318 {AUD_ERRINTRPTTHSHLD1_R, 0x000003ff},
363 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 319 {AUD_ERRINTRPTTHSHLD2_R, 0x000000ff},
364 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 320 {AUD_ERRINTRPTTHSHLD3_R, 0x0000003f},
365 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 321 {AUD_POLYPH80SCALEFAC, 0x00000003},
366 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 322 {AUD_DEEMPHGAIN_R, 0x000023c2},
367 { AUD_DMD_RA_DDS, 0x00C00000 }, 323 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
368 { AUD_PLL_INT, 0x0000001E }, 324 {AUD_DEEMPHNUMER2_R, 0x0003023e},
369 { AUD_PLL_DDS, 0x00000000 }, 325 {AUD_DEEMPHDENOM1_R, 0x0000f3d0},
370 { AUD_PLL_FRAC, 0x0000E542 }, 326 {AUD_DEEMPHDENOM2_R, 0x00000000},
371 { AUD_START_TIMER, 0x00000000 }, 327 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
372 { AUD_DEEMPHNUMER1_R, 0x000353DE }, 328 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
373 { AUD_DEEMPHNUMER2_R, 0x000001B1 }, 329 {AUD_QAM_MODE, 0x05},
374 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
375 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
376 { AUD_QAM_MODE, 0x05 },
377 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
378 { AUD_PHACC_FREQ_8MSB, 0x34 },
379 { AUD_PHACC_FREQ_8LSB, 0x4C },
380 { AUD_DEEMPHGAIN_R, 0x00006680 },
381 { AUD_RATE_THRES_DMD, 0x000000C0 },
382 { /* end of list */ }, 330 { /* end of list */ },
383 } ; 331 };
384 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
385
386 if (!stereo) {
387 /* AM Mono */
388 set_audio_start(core, SEL_A2);
389 set_audio_registers(core, nicam_l_mono);
390 set_audio_finish(core, EN_A2_FORCE_MONO1);
391 } else {
392 /* Nicam Stereo */
393 set_audio_start(core, SEL_NICAM);
394 set_audio_registers(core, nicam_l);
395 set_audio_finish(core, 0x1924); /* FIXME */
396 }
397}
398 332
399static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo) 333 static const struct rlist nicam_i[] = {
400{ 334 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
401 static const struct rlist pal_i_fm_mono[] = { 335 {AUD_PHACC_FREQ_8MSB, 0x3a},
402 {AUD_ERRLOGPERIOD_R, 0x00000064}, 336 {AUD_PHACC_FREQ_8LSB, 0x93},
403 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 337 { /* end of list */ },
404 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
405 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
406 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
407 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
408 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
409 {AUD_QAM_MODE, 0x05},
410 {AUD_PHACC_FREQ_8MSB, 0x3a},
411 {AUD_PHACC_FREQ_8LSB, 0x93},
412 {AUD_DMD_RA_DDS, 0x002a4f2f},
413 {AUD_PLL_INT, 0x0000001e},
414 {AUD_PLL_DDS, 0x00000004},
415 {AUD_PLL_FRAC, 0x0000e542},
416 {AUD_RATE_ADJ1, 0x00000100},
417 {AUD_RATE_ADJ2, 0x00000200},
418 {AUD_RATE_ADJ3, 0x00000300},
419 {AUD_RATE_ADJ4, 0x00000400},
420 {AUD_RATE_ADJ5, 0x00000500},
421 {AUD_THR_FR, 0x00000000},
422 {AUD_PILOT_BQD_1_K0, 0x0000755b},
423 {AUD_PILOT_BQD_1_K1, 0x00551340},
424 {AUD_PILOT_BQD_1_K2, 0x006d30be},
425 {AUD_PILOT_BQD_1_K3, 0xffd394af},
426 {AUD_PILOT_BQD_1_K4, 0x00400000},
427 {AUD_PILOT_BQD_2_K0, 0x00040000},
428 {AUD_PILOT_BQD_2_K1, 0x002a4841},
429 {AUD_PILOT_BQD_2_K2, 0x00400000},
430 {AUD_PILOT_BQD_2_K3, 0x00000000},
431 {AUD_PILOT_BQD_2_K4, 0x00000000},
432 {AUD_MODE_CHG_TIMER, 0x00000060},
433 {AUD_AFE_12DB_EN, 0x00000001},
434 {AAGC_HYST, 0x0000000a},
435 {AUD_CORDIC_SHIFT_0, 0x00000007},
436 {AUD_CORDIC_SHIFT_1, 0x00000007},
437 {AUD_C1_UP_THR, 0x00007000},
438 {AUD_C1_LO_THR, 0x00005400},
439 {AUD_C2_UP_THR, 0x00005400},
440 {AUD_C2_LO_THR, 0x00003000},
441 {AUD_DCOC_0_SRC, 0x0000001a},
442 {AUD_DCOC0_SHIFT, 0x00000000},
443 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
444 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
445 {AUD_DCOC_PASS_IN, 0x00000003},
446 {AUD_IIR3_0_SEL, 0x00000021},
447 {AUD_DN2_AFC, 0x00000002},
448 {AUD_DCOC_1_SRC, 0x0000001b},
449 {AUD_DCOC1_SHIFT, 0x00000000},
450 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
451 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
452 {AUD_IIR3_1_SEL, 0x00000023},
453 {AUD_DN0_FREQ, 0x000035a3},
454 {AUD_DN2_FREQ, 0x000029c7},
455 {AUD_CRDC0_SRC_SEL, 0x00000511},
456 {AUD_IIR1_0_SEL, 0x00000001},
457 {AUD_IIR1_1_SEL, 0x00000000},
458 {AUD_IIR3_2_SEL, 0x00000003},
459 {AUD_IIR3_2_SHIFT, 0x00000000},
460 {AUD_IIR3_0_SEL, 0x00000002},
461 {AUD_IIR2_0_SEL, 0x00000021},
462 {AUD_IIR2_0_SHIFT, 0x00000002},
463 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
464 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
465 {AUD_POLYPH80SCALEFAC, 0x00000001},
466 {AUD_START_TIMER, 0x00000000},
467 { /* end of list */ },
468 };
469
470 static const struct rlist pal_i_nicam[] = {
471 { AUD_RATE_ADJ1, 0x00000010 },
472 { AUD_RATE_ADJ2, 0x00000040 },
473 { AUD_RATE_ADJ3, 0x00000100 },
474 { AUD_RATE_ADJ4, 0x00000400 },
475 { AUD_RATE_ADJ5, 0x00001000 },
476 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
477 { AUD_DEEMPHGAIN_R, 0x000023c2 },
478 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
479 { AUD_DEEMPHNUMER2_R, 0x0003023e },
480 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
481 { AUD_DEEMPHDENOM2_R, 0x00000000 },
482 { AUD_DEEMPHDENOM2_R, 0x00000000 },
483 { AUD_ERRLOGPERIOD_R, 0x00000fff },
484 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
485 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
486 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
487 { AUD_POLYPH80SCALEFAC, 0x00000003 },
488 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
489 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
490 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
491 { AUD_QAM_MODE, 0x05 },
492 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
493 { AUD_PHACC_FREQ_8MSB, 0x3a },
494 { AUD_PHACC_FREQ_8LSB, 0x93 },
495 { /* end of list */ },
496 }; 338 };
497 339
498 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo); 340 static const struct rlist nicam_default[] = {
341 {AUD_PDF_DDS_CNST_BYTE0, 0x16},
342 {AUD_PHACC_FREQ_8MSB, 0x34},
343 {AUD_PHACC_FREQ_8LSB, 0x4c},
344 { /* end of list */ },
345 };
499 346
500 if (!stereo) { 347 set_audio_start(core,SEL_NICAM);
501 /* FM Mono */ 348 switch (core->tvaudio) {
502 set_audio_start(core, SEL_A2); 349 case WW_L:
503 set_audio_registers(core, pal_i_fm_mono); 350 dprintk("%s SECAM-L NICAM (status: devel)\n", __FUNCTION__);
504 set_audio_finish(core, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1); 351 set_audio_registers(core, nicam_l);
505 } else { 352 break;
506 /* Nicam Stereo */ 353 case WW_I:
507 set_audio_start(core, SEL_NICAM); 354 dprintk("%s PAL-I NICAM (status: devel)\n", __FUNCTION__);
508 set_audio_registers(core, pal_i_nicam); 355 set_audio_registers(core, nicam_bgdki_common);
509 set_audio_finish(core, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO); 356 set_audio_registers(core, nicam_i);
510 } 357 break;
358 default:
359 dprintk("%s PAL-BGDK NICAM (status: unknown)\n", __FUNCTION__);
360 set_audio_registers(core, nicam_bgdki_common);
361 set_audio_registers(core, nicam_default);
362 break;
363 };
364
365 mode |= EN_DMTRX_LR | EN_DMTRX_BYPASS;
366 set_audio_finish(core, mode);
511} 367}
512 368
513static void set_audio_standard_A2(struct cx88_core *core, u32 mode) 369static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
514{ 370{
515 static const struct rlist a2_common[] = { 371 static const struct rlist a2_bgdk_common[] = {
516 {AUD_ERRLOGPERIOD_R, 0x00000064}, 372 {AUD_ERRLOGPERIOD_R, 0x00000064},
517 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 373 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
518 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, 374 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
519 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, 375 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
520 {AUD_PDF_DDS_CNST_BYTE2, 0x06}, 376 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
521 {AUD_PDF_DDS_CNST_BYTE1, 0x82}, 377 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
522 {AUD_PDF_DDS_CNST_BYTE0, 0x12}, 378 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
523 {AUD_QAM_MODE, 0x05}, 379 {AUD_QAM_MODE, 0x05},
524 {AUD_PHACC_FREQ_8MSB, 0x34}, 380 {AUD_PHACC_FREQ_8MSB, 0x34},
525 {AUD_PHACC_FREQ_8LSB, 0x4c}, 381 {AUD_PHACC_FREQ_8LSB, 0x4c},
526 {AUD_RATE_ADJ1, 0x00000100}, 382 {AUD_RATE_ADJ1, 0x00000100},
527 {AUD_RATE_ADJ2, 0x00000200}, 383 {AUD_RATE_ADJ2, 0x00000200},
528 {AUD_RATE_ADJ3, 0x00000300}, 384 {AUD_RATE_ADJ3, 0x00000300},
529 {AUD_RATE_ADJ4, 0x00000400}, 385 {AUD_RATE_ADJ4, 0x00000400},
530 {AUD_RATE_ADJ5, 0x00000500}, 386 {AUD_RATE_ADJ5, 0x00000500},
531 {AUD_THR_FR, 0x00000000}, 387 {AUD_THR_FR, 0x00000000},
532 {AAGC_HYST, 0x0000001a}, 388 {AAGC_HYST, 0x0000001a},
533 {AUD_PILOT_BQD_1_K0, 0x0000755b}, 389 {AUD_PILOT_BQD_1_K0, 0x0000755b},
534 {AUD_PILOT_BQD_1_K1, 0x00551340}, 390 {AUD_PILOT_BQD_1_K1, 0x00551340},
535 {AUD_PILOT_BQD_1_K2, 0x006d30be}, 391 {AUD_PILOT_BQD_1_K2, 0x006d30be},
536 {AUD_PILOT_BQD_1_K3, 0xffd394af}, 392 {AUD_PILOT_BQD_1_K3, 0xffd394af},
537 {AUD_PILOT_BQD_1_K4, 0x00400000}, 393 {AUD_PILOT_BQD_1_K4, 0x00400000},
538 {AUD_PILOT_BQD_2_K0, 0x00040000}, 394 {AUD_PILOT_BQD_2_K0, 0x00040000},
539 {AUD_PILOT_BQD_2_K1, 0x002a4841}, 395 {AUD_PILOT_BQD_2_K1, 0x002a4841},
540 {AUD_PILOT_BQD_2_K2, 0x00400000}, 396 {AUD_PILOT_BQD_2_K2, 0x00400000},
541 {AUD_PILOT_BQD_2_K3, 0x00000000}, 397 {AUD_PILOT_BQD_2_K3, 0x00000000},
542 {AUD_PILOT_BQD_2_K4, 0x00000000}, 398 {AUD_PILOT_BQD_2_K4, 0x00000000},
543 {AUD_MODE_CHG_TIMER, 0x00000040}, 399 {AUD_MODE_CHG_TIMER, 0x00000040},
544 {AUD_AFE_12DB_EN, 0x00000001}, 400 {AUD_AFE_12DB_EN, 0x00000001},
545 {AUD_CORDIC_SHIFT_0, 0x00000007}, 401 {AUD_CORDIC_SHIFT_0, 0x00000007},
546 {AUD_CORDIC_SHIFT_1, 0x00000007}, 402 {AUD_CORDIC_SHIFT_1, 0x00000007},
547 {AUD_DEEMPH0_G0, 0x00000380}, 403 {AUD_DEEMPH0_G0, 0x00000380},
548 {AUD_DEEMPH1_G0, 0x00000380}, 404 {AUD_DEEMPH1_G0, 0x00000380},
549 {AUD_DCOC_0_SRC, 0x0000001a}, 405 {AUD_DCOC_0_SRC, 0x0000001a},
550 {AUD_DCOC0_SHIFT, 0x00000000}, 406 {AUD_DCOC0_SHIFT, 0x00000000},
551 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, 407 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
552 {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, 408 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
553 {AUD_DCOC_PASS_IN, 0x00000003}, 409 {AUD_DCOC_PASS_IN, 0x00000003},
554 {AUD_IIR3_0_SEL, 0x00000021}, 410 {AUD_IIR3_0_SEL, 0x00000021},
555 {AUD_DN2_AFC, 0x00000002}, 411 {AUD_DN2_AFC, 0x00000002},
556 {AUD_DCOC_1_SRC, 0x0000001b}, 412 {AUD_DCOC_1_SRC, 0x0000001b},
557 {AUD_DCOC1_SHIFT, 0x00000000}, 413 {AUD_DCOC1_SHIFT, 0x00000000},
558 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, 414 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
559 {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, 415 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
560 {AUD_IIR3_1_SEL, 0x00000023}, 416 {AUD_IIR3_1_SEL, 0x00000023},
561 {AUD_RDSI_SEL, 0x00000017}, 417 {AUD_RDSI_SEL, 0x00000017},
562 {AUD_RDSI_SHIFT, 0x00000000}, 418 {AUD_RDSI_SHIFT, 0x00000000},
563 {AUD_RDSQ_SEL, 0x00000017}, 419 {AUD_RDSQ_SEL, 0x00000017},
564 {AUD_RDSQ_SHIFT, 0x00000000}, 420 {AUD_RDSQ_SHIFT, 0x00000000},
565 {AUD_PLL_INT, 0x0000001e}, 421 {AUD_PLL_INT, 0x0000001e},
566 {AUD_PLL_DDS, 0x00000000}, 422 {AUD_PLL_DDS, 0x00000000},
567 {AUD_PLL_FRAC, 0x0000e542}, 423 {AUD_PLL_FRAC, 0x0000e542},
568 {AUD_POLYPH80SCALEFAC, 0x00000001}, 424 {AUD_POLYPH80SCALEFAC, 0x00000001},
569 {AUD_START_TIMER, 0x00000000}, 425 {AUD_START_TIMER, 0x00000000},
570 { /* end of list */ }, 426 { /* end of list */ },
571 }; 427 };
572 428
573 static const struct rlist a2_bg[] = { 429 static const struct rlist a2_bg[] = {
574 {AUD_DMD_RA_DDS, 0x002a4f2f}, 430 {AUD_DMD_RA_DDS, 0x002a4f2f},
575 {AUD_C1_UP_THR, 0x00007000}, 431 {AUD_C1_UP_THR, 0x00007000},
576 {AUD_C1_LO_THR, 0x00005400}, 432 {AUD_C1_LO_THR, 0x00005400},
577 {AUD_C2_UP_THR, 0x00005400}, 433 {AUD_C2_UP_THR, 0x00005400},
578 {AUD_C2_LO_THR, 0x00003000}, 434 {AUD_C2_LO_THR, 0x00003000},
579 { /* end of list */ }, 435 { /* end of list */ },
580 }; 436 };
581 437
582 static const struct rlist a2_dk[] = { 438 static const struct rlist a2_dk[] = {
583 {AUD_DMD_RA_DDS, 0x002a4f2f}, 439 {AUD_DMD_RA_DDS, 0x002a4f2f},
584 {AUD_C1_UP_THR, 0x00007000}, 440 {AUD_C1_UP_THR, 0x00007000},
585 {AUD_C1_LO_THR, 0x00005400}, 441 {AUD_C1_LO_THR, 0x00005400},
586 {AUD_C2_UP_THR, 0x00005400}, 442 {AUD_C2_UP_THR, 0x00005400},
587 {AUD_C2_LO_THR, 0x00003000}, 443 {AUD_C2_LO_THR, 0x00003000},
588 {AUD_DN0_FREQ, 0x00003a1c}, 444 {AUD_DN0_FREQ, 0x00003a1c},
589 {AUD_DN2_FREQ, 0x0000d2e0}, 445 {AUD_DN2_FREQ, 0x0000d2e0},
590 { /* end of list */ }, 446 { /* end of list */ },
591 }; 447 };
592/* unknown, probably NTSC-M */ 448
593 static const struct rlist a2_m[] = { 449 static const struct rlist a1_i[] = {
594 {AUD_DMD_RA_DDS, 0x002a0425}, 450 {AUD_ERRLOGPERIOD_R, 0x00000064},
595 {AUD_C1_UP_THR, 0x00003c00}, 451 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
596 {AUD_C1_LO_THR, 0x00003000}, 452 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
597 {AUD_C2_UP_THR, 0x00006000}, 453 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
598 {AUD_C2_LO_THR, 0x00003c00}, 454 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
599 {AUD_DEEMPH0_A0, 0x00007a80}, 455 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
600 {AUD_DEEMPH1_A0, 0x00007a80}, 456 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
601 {AUD_DEEMPH0_G0, 0x00001200}, 457 {AUD_QAM_MODE, 0x05},
602 {AUD_DEEMPH1_G0, 0x00001200}, 458 {AUD_PHACC_FREQ_8MSB, 0x3a},
603 {AUD_DN0_FREQ, 0x0000283b}, 459 {AUD_PHACC_FREQ_8LSB, 0x93},
604 {AUD_DN1_FREQ, 0x00003418}, 460 {AUD_DMD_RA_DDS, 0x002a4f2f},
605 {AUD_DN2_FREQ, 0x000029c7}, 461 {AUD_PLL_INT, 0x0000001e},
606 {AUD_POLY0_DDS_CONSTANT, 0x000a7540}, 462 {AUD_PLL_DDS, 0x00000004},
463 {AUD_PLL_FRAC, 0x0000e542},
464 {AUD_RATE_ADJ1, 0x00000100},
465 {AUD_RATE_ADJ2, 0x00000200},
466 {AUD_RATE_ADJ3, 0x00000300},
467 {AUD_RATE_ADJ4, 0x00000400},
468 {AUD_RATE_ADJ5, 0x00000500},
469 {AUD_THR_FR, 0x00000000},
470 {AUD_PILOT_BQD_1_K0, 0x0000755b},
471 {AUD_PILOT_BQD_1_K1, 0x00551340},
472 {AUD_PILOT_BQD_1_K2, 0x006d30be},
473 {AUD_PILOT_BQD_1_K3, 0xffd394af},
474 {AUD_PILOT_BQD_1_K4, 0x00400000},
475 {AUD_PILOT_BQD_2_K0, 0x00040000},
476 {AUD_PILOT_BQD_2_K1, 0x002a4841},
477 {AUD_PILOT_BQD_2_K2, 0x00400000},
478 {AUD_PILOT_BQD_2_K3, 0x00000000},
479 {AUD_PILOT_BQD_2_K4, 0x00000000},
480 {AUD_MODE_CHG_TIMER, 0x00000060},
481 {AUD_AFE_12DB_EN, 0x00000001},
482 {AAGC_HYST, 0x0000000a},
483 {AUD_CORDIC_SHIFT_0, 0x00000007},
484 {AUD_CORDIC_SHIFT_1, 0x00000007},
485 {AUD_C1_UP_THR, 0x00007000},
486 {AUD_C1_LO_THR, 0x00005400},
487 {AUD_C2_UP_THR, 0x00005400},
488 {AUD_C2_LO_THR, 0x00003000},
489 {AUD_DCOC_0_SRC, 0x0000001a},
490 {AUD_DCOC0_SHIFT, 0x00000000},
491 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
492 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
493 {AUD_DCOC_PASS_IN, 0x00000003},
494 {AUD_IIR3_0_SEL, 0x00000021},
495 {AUD_DN2_AFC, 0x00000002},
496 {AUD_DCOC_1_SRC, 0x0000001b},
497 {AUD_DCOC1_SHIFT, 0x00000000},
498 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
499 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
500 {AUD_IIR3_1_SEL, 0x00000023},
501 {AUD_DN0_FREQ, 0x000035a3},
502 {AUD_DN2_FREQ, 0x000029c7},
503 {AUD_CRDC0_SRC_SEL, 0x00000511},
504 {AUD_IIR1_0_SEL, 0x00000001},
505 {AUD_IIR1_1_SEL, 0x00000000},
506 {AUD_IIR3_2_SEL, 0x00000003},
507 {AUD_IIR3_2_SHIFT, 0x00000000},
508 {AUD_IIR3_0_SEL, 0x00000002},
509 {AUD_IIR2_0_SEL, 0x00000021},
510 {AUD_IIR2_0_SHIFT, 0x00000002},
511 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
512 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
513 {AUD_POLYPH80SCALEFAC, 0x00000001},
514 {AUD_START_TIMER, 0x00000000},
607 { /* end of list */ }, 515 { /* end of list */ },
608 }; 516 };
609 517
610 static const struct rlist a2_deemph50[] = { 518 static const struct rlist am_l[] = {
611 {AUD_DEEMPH0_G0, 0x00000380}, 519 {AUD_ERRLOGPERIOD_R, 0x00000064},
612 {AUD_DEEMPH1_G0, 0x00000380}, 520 {AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF},
613 {AUD_DEEMPHGAIN_R, 0x000011e1}, 521 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001F},
614 {AUD_DEEMPHNUMER1_R, 0x0002a7bc}, 522 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000F},
615 {AUD_DEEMPHNUMER2_R, 0x0003023c}, 523 {AUD_PDF_DDS_CNST_BYTE2, 0x48},
616 { /* end of list */ }, 524 {AUD_PDF_DDS_CNST_BYTE1, 0x3D},
525 {AUD_QAM_MODE, 0x00},
526 {AUD_PDF_DDS_CNST_BYTE0, 0xf5},
527 {AUD_PHACC_FREQ_8MSB, 0x3a},
528 {AUD_PHACC_FREQ_8LSB, 0x4a},
529 {AUD_DEEMPHGAIN_R, 0x00006680},
530 {AUD_DEEMPHNUMER1_R, 0x000353DE},
531 {AUD_DEEMPHNUMER2_R, 0x000001B1},
532 {AUD_DEEMPHDENOM1_R, 0x0000F3D0},
533 {AUD_DEEMPHDENOM2_R, 0x00000000},
534 {AUD_FM_MODE_ENABLE, 0x00000007},
535 {AUD_POLYPH80SCALEFAC, 0x00000003},
536 {AUD_AFE_12DB_EN, 0x00000001},
537 {AAGC_GAIN, 0x00000000},
538 {AAGC_HYST, 0x00000018},
539 {AAGC_DEF, 0x00000020},
540 {AUD_DN0_FREQ, 0x00000000},
541 {AUD_POLY0_DDS_CONSTANT, 0x000E4DB2},
542 {AUD_DCOC_0_SRC, 0x00000021},
543 {AUD_IIR1_0_SEL, 0x00000000},
544 {AUD_IIR1_0_SHIFT, 0x00000007},
545 {AUD_IIR1_1_SEL, 0x00000002},
546 {AUD_IIR1_1_SHIFT, 0x00000000},
547 {AUD_DCOC_1_SRC, 0x00000003},
548 {AUD_DCOC1_SHIFT, 0x00000000},
549 {AUD_DCOC_PASS_IN, 0x00000000},
550 {AUD_IIR1_2_SEL, 0x00000023},
551 {AUD_IIR1_2_SHIFT, 0x00000000},
552 {AUD_IIR1_3_SEL, 0x00000004},
553 {AUD_IIR1_3_SHIFT, 0x00000007},
554 {AUD_IIR1_4_SEL, 0x00000005},
555 {AUD_IIR1_4_SHIFT, 0x00000007},
556 {AUD_IIR3_0_SEL, 0x00000007},
557 {AUD_IIR3_0_SHIFT, 0x00000000},
558 {AUD_DEEMPH0_SRC_SEL, 0x00000011},
559 {AUD_DEEMPH0_SHIFT, 0x00000000},
560 {AUD_DEEMPH0_G0, 0x00007000},
561 {AUD_DEEMPH0_A0, 0x00000000},
562 {AUD_DEEMPH0_B0, 0x00000000},
563 {AUD_DEEMPH0_A1, 0x00000000},
564 {AUD_DEEMPH0_B1, 0x00000000},
565 {AUD_DEEMPH1_SRC_SEL, 0x00000011},
566 {AUD_DEEMPH1_SHIFT, 0x00000000},
567 {AUD_DEEMPH1_G0, 0x00007000},
568 {AUD_DEEMPH1_A0, 0x00000000},
569 {AUD_DEEMPH1_B0, 0x00000000},
570 {AUD_DEEMPH1_A1, 0x00000000},
571 {AUD_DEEMPH1_B1, 0x00000000},
572 {AUD_OUT0_SEL, 0x0000003F},
573 {AUD_OUT1_SEL, 0x0000003F},
574 {AUD_DMD_RA_DDS, 0x00F5C285},
575 {AUD_PLL_INT, 0x0000001E},
576 {AUD_PLL_DDS, 0x00000000},
577 {AUD_PLL_FRAC, 0x0000E542},
578 {AUD_RATE_ADJ1, 0x00000100},
579 {AUD_RATE_ADJ2, 0x00000200},
580 {AUD_RATE_ADJ3, 0x00000300},
581 {AUD_RATE_ADJ4, 0x00000400},
582 {AUD_RATE_ADJ5, 0x00000500},
583 {AUD_RATE_THRES_DMD, 0x000000C0},
584 { /* end of list */ },
617 }; 585 };
618 586
619 static const struct rlist a2_deemph75[] = { 587 static const struct rlist a2_deemph50[] = {
620 {AUD_DEEMPH0_G0, 0x00000480}, 588 {AUD_DEEMPH0_G0, 0x00000380},
621 {AUD_DEEMPH1_G0, 0x00000480}, 589 {AUD_DEEMPH1_G0, 0x00000380},
622 {AUD_DEEMPHGAIN_R, 0x00009000}, 590 {AUD_DEEMPHGAIN_R, 0x000011e1},
623 {AUD_DEEMPHNUMER1_R, 0x000353de}, 591 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
624 {AUD_DEEMPHNUMER2_R, 0x000001b1}, 592 {AUD_DEEMPHNUMER2_R, 0x0003023c},
625 { /* end of list */ }, 593 { /* end of list */ },
626 }; 594 };
627 595
628 set_audio_start(core, SEL_A2); 596 set_audio_start(core, SEL_A2);
629 set_audio_registers(core, a2_common);
630 switch (core->tvaudio) { 597 switch (core->tvaudio) {
631 case WW_A2_BG: 598 case WW_BG:
632 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__); 599 dprintk("%s PAL-BG A1/2 (status: known-good)\n", __FUNCTION__);
633 set_audio_registers(core, a2_bg); 600 set_audio_registers(core, a2_bgdk_common);
634 set_audio_registers(core, a2_deemph50); 601 set_audio_registers(core, a2_bg);
602 set_audio_registers(core, a2_deemph50);
635 break; 603 break;
636 case WW_A2_DK: 604 case WW_DK:
637 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__); 605 dprintk("%s PAL-DK A1/2 (status: known-good)\n", __FUNCTION__);
638 set_audio_registers(core, a2_dk); 606 set_audio_registers(core, a2_bgdk_common);
639 set_audio_registers(core, a2_deemph50); 607 set_audio_registers(core, a2_dk);
608 set_audio_registers(core, a2_deemph50);
640 break; 609 break;
641 case WW_A2_M: 610 case WW_I:
642 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__); 611 dprintk("%s PAL-I A1 (status: known-good)\n", __FUNCTION__);
643 set_audio_registers(core, a2_m); 612 set_audio_registers(core, a1_i);
644 set_audio_registers(core, a2_deemph75); 613 set_audio_registers(core, a2_deemph50);
614 break;
615 case WW_L:
616 dprintk("%s AM-L (status: devel)\n", __FUNCTION__);
617 set_audio_registers(core, am_l);
618 break;
619 default:
620 dprintk("%s Warning: wrong value\n", __FUNCTION__);
621 return;
645 break; 622 break;
646 }; 623 };
647 624
@@ -656,71 +633,71 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
656 633
657 { /* end of list */ }, 634 { /* end of list */ },
658 }; 635 };
659 dprintk("%s (status: unknown)\n",__FUNCTION__); 636 dprintk("%s (status: unknown)\n", __FUNCTION__);
660 637
661 set_audio_start(core, SEL_EIAJ); 638 set_audio_start(core, SEL_EIAJ);
662 set_audio_registers(core, eiaj); 639 set_audio_registers(core, eiaj);
663 set_audio_finish(core, EN_EIAJ_AUTO_STEREO); 640 set_audio_finish(core, EN_EIAJ_AUTO_STEREO);
664} 641}
665 642
666static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph) 643static void set_audio_standard_FM(struct cx88_core *core,
644 enum cx88_deemph_type deemph)
667{ 645{
668 static const struct rlist fm_deemph_50[] = { 646 static const struct rlist fm_deemph_50[] = {
669 { AUD_DEEMPH0_G0, 0x0C45 }, 647 {AUD_DEEMPH0_G0, 0x0C45},
670 { AUD_DEEMPH0_A0, 0x6262 }, 648 {AUD_DEEMPH0_A0, 0x6262},
671 { AUD_DEEMPH0_B0, 0x1C29 }, 649 {AUD_DEEMPH0_B0, 0x1C29},
672 { AUD_DEEMPH0_A1, 0x3FC66}, 650 {AUD_DEEMPH0_A1, 0x3FC66},
673 { AUD_DEEMPH0_B1, 0x399A }, 651 {AUD_DEEMPH0_B1, 0x399A},
674 652
675 { AUD_DEEMPH1_G0, 0x0D80 }, 653 {AUD_DEEMPH1_G0, 0x0D80},
676 { AUD_DEEMPH1_A0, 0x6262 }, 654 {AUD_DEEMPH1_A0, 0x6262},
677 { AUD_DEEMPH1_B0, 0x1C29 }, 655 {AUD_DEEMPH1_B0, 0x1C29},
678 { AUD_DEEMPH1_A1, 0x3FC66}, 656 {AUD_DEEMPH1_A1, 0x3FC66},
679 { AUD_DEEMPH1_B1, 0x399A}, 657 {AUD_DEEMPH1_B1, 0x399A},
680 658
681 { AUD_POLYPH80SCALEFAC, 0x0003}, 659 {AUD_POLYPH80SCALEFAC, 0x0003},
682 { /* end of list */ }, 660 { /* end of list */ },
683 }; 661 };
684 static const struct rlist fm_deemph_75[] = { 662 static const struct rlist fm_deemph_75[] = {
685 { AUD_DEEMPH0_G0, 0x091B }, 663 {AUD_DEEMPH0_G0, 0x091B},
686 { AUD_DEEMPH0_A0, 0x6B68 }, 664 {AUD_DEEMPH0_A0, 0x6B68},
687 { AUD_DEEMPH0_B0, 0x11EC }, 665 {AUD_DEEMPH0_B0, 0x11EC},
688 { AUD_DEEMPH0_A1, 0x3FC66}, 666 {AUD_DEEMPH0_A1, 0x3FC66},
689 { AUD_DEEMPH0_B1, 0x399A }, 667 {AUD_DEEMPH0_B1, 0x399A},
690 668
691 { AUD_DEEMPH1_G0, 0x0AA0 }, 669 {AUD_DEEMPH1_G0, 0x0AA0},
692 { AUD_DEEMPH1_A0, 0x6B68 }, 670 {AUD_DEEMPH1_A0, 0x6B68},
693 { AUD_DEEMPH1_B0, 0x11EC }, 671 {AUD_DEEMPH1_B0, 0x11EC},
694 { AUD_DEEMPH1_A1, 0x3FC66}, 672 {AUD_DEEMPH1_A1, 0x3FC66},
695 { AUD_DEEMPH1_B1, 0x399A}, 673 {AUD_DEEMPH1_B1, 0x399A},
696 674
697 { AUD_POLYPH80SCALEFAC, 0x0003}, 675 {AUD_POLYPH80SCALEFAC, 0x0003},
698 { /* end of list */ }, 676 { /* end of list */ },
699 }; 677 };
700 678
701 /* It is enough to leave default values? */ 679 /* It is enough to leave default values? */
702 static const struct rlist fm_no_deemph[] = { 680 static const struct rlist fm_no_deemph[] = {
703 681
704 { AUD_POLYPH80SCALEFAC, 0x0003}, 682 {AUD_POLYPH80SCALEFAC, 0x0003},
705 { /* end of list */ }, 683 { /* end of list */ },
706 }; 684 };
707 685
708 dprintk("%s (status: unknown)\n",__FUNCTION__); 686 dprintk("%s (status: unknown)\n", __FUNCTION__);
709 set_audio_start(core, SEL_FMRADIO); 687 set_audio_start(core, SEL_FMRADIO);
710 688
711 switch (deemph) 689 switch (deemph) {
712 { 690 case FM_NO_DEEMPH:
713 case FM_NO_DEEMPH: 691 set_audio_registers(core, fm_no_deemph);
714 set_audio_registers(core, fm_no_deemph); 692 break;
715 break;
716 693
717 case FM_DEEMPH_50: 694 case FM_DEEMPH_50:
718 set_audio_registers(core, fm_deemph_50); 695 set_audio_registers(core, fm_deemph_50);
719 break; 696 break;
720 697
721 case FM_DEEMPH_75: 698 case FM_DEEMPH_75:
722 set_audio_registers(core, fm_deemph_75); 699 set_audio_registers(core, fm_deemph_75);
723 break; 700 break;
724 } 701 }
725 702
726 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO); 703 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);
@@ -728,36 +705,64 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
728 705
729/* ----------------------------------------------------------- */ 706/* ----------------------------------------------------------- */
730 707
708int cx88_detect_nicam(struct cx88_core *core)
709{
710 int i, j = 0;
711
712 dprintk("start nicam autodetect.\n");
713
714 for (i = 0; i < 6; i++) {
715 /* if bit1=1 then nicam is detected */
716 j += ((cx_read(AUD_NICAM_STATUS2) & 0x02) >> 1);
717
718 /* 3x detected: absolutly sure now */
719 if (j == 3) {
720 dprintk("nicam is detected.\n");
721 return 1;
722 }
723
724 /* wait a little bit for next reading status */
725 msleep(10);
726 }
727
728 dprintk("nicam is not detected.\n");
729 return 0;
730}
731
731void cx88_set_tvaudio(struct cx88_core *core) 732void cx88_set_tvaudio(struct cx88_core *core)
732{ 733{
733 switch (core->tvaudio) { 734 switch (core->tvaudio) {
734 case WW_BTSC: 735 case WW_BTSC:
735 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO); 736 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
736 break; 737 break;
737 case WW_NICAM_BGDKL: 738 case WW_BG:
738 set_audio_standard_NICAM_L(core,0); 739 case WW_DK:
739 break; 740 case WW_I:
740 case WW_NICAM_I: 741 case WW_L:
741 set_audio_standard_PAL_I(core,0); 742 /* prepare all dsp registers */
742 break; 743 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
743 case WW_A2_BG: 744
744 case WW_A2_DK: 745 /* set nicam mode - otherwise
745 case WW_A2_M: 746 AUD_NICAM_STATUS2 contains wrong values */
746 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 747 set_audio_standard_NICAM(core, EN_NICAM_AUTO_STEREO);
748 if (0 == cx88_detect_nicam(core)) {
749 /* fall back to fm / am mono */
750 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
751 core->use_nicam = 0;
752 } else {
753 core->use_nicam = 1;
754 }
747 break; 755 break;
748 case WW_EIAJ: 756 case WW_EIAJ:
749 set_audio_standard_EIAJ(core); 757 set_audio_standard_EIAJ(core);
750 break; 758 break;
751 case WW_FM: 759 case WW_FM:
752 set_audio_standard_FM(core,FM_NO_DEEMPH); 760 set_audio_standard_FM(core, FM_NO_DEEMPH);
753 break;
754 case WW_SYSTEM_L_AM:
755 set_audio_standard_NICAM_L(core, 1);
756 break; 761 break;
757 case WW_NONE: 762 case WW_NONE:
758 default: 763 default:
759 printk("%s/0: unknown tv audio mode [%d]\n", 764 printk("%s/0: unknown tv audio mode [%d]\n",
760 core->name, core->tvaudio); 765 core->name, core->tvaudio);
761 break; 766 break;
762 } 767 }
763 return; 768 return;
@@ -766,24 +771,16 @@ void cx88_set_tvaudio(struct cx88_core *core)
766void cx88_newstation(struct cx88_core *core) 771void cx88_newstation(struct cx88_core *core)
767{ 772{
768 core->audiomode_manual = UNSET; 773 core->audiomode_manual = UNSET;
769
770 switch (core->tvaudio) {
771 case WW_SYSTEM_L_AM:
772 /* try nicam ... */
773 core->audiomode_current = V4L2_TUNER_MODE_STEREO;
774 set_audio_standard_NICAM_L(core, 1);
775 break;
776 }
777} 774}
778 775
779void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t) 776void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
780{ 777{
781 static char *m[] = {"stereo", "dual mono", "mono", "sap"}; 778 static char *m[] = { "stereo", "dual mono", "mono", "sap" };
782 static char *p[] = {"no pilot", "pilot c1", "pilot c2", "?"}; 779 static char *p[] = { "no pilot", "pilot c1", "pilot c2", "?" };
783 u32 reg,mode,pilot; 780 u32 reg, mode, pilot;
784 781
785 reg = cx_read(AUD_STATUS); 782 reg = cx_read(AUD_STATUS);
786 mode = reg & 0x03; 783 mode = reg & 0x03;
787 pilot = (reg >> 2) & 0x03; 784 pilot = (reg >> 2) & 0x03;
788 785
789 if (core->astat != reg) 786 if (core->astat != reg)
@@ -800,14 +797,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
800 797
801# if 0 798# if 0
802 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | 799 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
803 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 800 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
804 t->rxsubchans = V4L2_TUNER_SUB_MONO; 801 t->rxsubchans = V4L2_TUNER_SUB_MONO;
805 t->audmode = V4L2_TUNER_MODE_MONO; 802 t->audmode = V4L2_TUNER_MODE_MONO;
806 803
807 switch (core->tvaudio) { 804 switch (core->tvaudio) {
808 case WW_BTSC: 805 case WW_BTSC:
809 t->capability = V4L2_TUNER_CAP_STEREO | 806 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP;
810 V4L2_TUNER_CAP_SAP;
811 t->rxsubchans = V4L2_TUNER_SUB_STEREO; 807 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
812 if (1 == pilot) { 808 if (1 == pilot) {
813 /* SAP */ 809 /* SAP */
@@ -819,13 +815,15 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
819 case WW_A2_M: 815 case WW_A2_M:
820 if (1 == pilot) { 816 if (1 == pilot) {
821 /* stereo */ 817 /* stereo */
822 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 818 t->rxsubchans =
819 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
823 if (0 == mode) 820 if (0 == mode)
824 t->audmode = V4L2_TUNER_MODE_STEREO; 821 t->audmode = V4L2_TUNER_MODE_STEREO;
825 } 822 }
826 if (2 == pilot) { 823 if (2 == pilot) {
827 /* dual language -- FIXME */ 824 /* dual language -- FIXME */
828 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 825 t->rxsubchans =
826 V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
829 t->audmode = V4L2_TUNER_MODE_LANG1; 827 t->audmode = V4L2_TUNER_MODE_LANG1;
830 } 828 }
831 break; 829 break;
@@ -840,7 +838,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
840 t->audmode = V4L2_TUNER_MODE_STEREO; 838 t->audmode = V4L2_TUNER_MODE_STEREO;
841 t->rxsubchans |= V4L2_TUNER_SUB_STEREO; 839 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
842 } 840 }
843 break ; 841 break;
844 default: 842 default:
845 /* nothing */ 843 /* nothing */
846 break; 844 break;
@@ -851,7 +849,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
851 849
852void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual) 850void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
853{ 851{
854 u32 ctl = UNSET; 852 u32 ctl = UNSET;
855 u32 mask = UNSET; 853 u32 mask = UNSET;
856 854
857 if (manual) { 855 if (manual) {
@@ -879,68 +877,58 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
879 break; 877 break;
880 } 878 }
881 break; 879 break;
882 case WW_A2_BG: 880 case WW_BG:
883 case WW_A2_DK: 881 case WW_DK:
884 case WW_A2_M: 882 case WW_I:
885 switch (mode) { 883 case WW_L:
886 case V4L2_TUNER_MODE_MONO: 884 if (1 == core->use_nicam) {
887 case V4L2_TUNER_MODE_LANG1: 885 switch (mode) {
888 set_audio_standard_A2(core, EN_A2_FORCE_MONO1); 886 case V4L2_TUNER_MODE_MONO:
889 break; 887 case V4L2_TUNER_MODE_LANG1:
890 case V4L2_TUNER_MODE_LANG2: 888 set_audio_standard_NICAM(core,
891 set_audio_standard_A2(core, EN_A2_FORCE_MONO2); 889 EN_NICAM_FORCE_MONO1);
892 break; 890 break;
893 case V4L2_TUNER_MODE_STEREO: 891 case V4L2_TUNER_MODE_LANG2:
894 set_audio_standard_A2(core, EN_A2_FORCE_STEREO); 892 set_audio_standard_NICAM(core,
895 break; 893 EN_NICAM_FORCE_MONO2);
896 } 894 break;
897 break; 895 case V4L2_TUNER_MODE_STEREO:
898 case WW_NICAM_BGDKL: 896 set_audio_standard_NICAM(core,
899 switch (mode) { 897 EN_NICAM_FORCE_STEREO);
900 case V4L2_TUNER_MODE_MONO: 898 break;
901 ctl = EN_NICAM_FORCE_MONO1; 899 }
902 mask = 0x3f; 900 } else {
903 break; 901 if ((core->tvaudio == WW_I) || (core->tvaudio == WW_L)) {
904 case V4L2_TUNER_MODE_LANG1: 902 /* fall back to fm / am mono */
905 ctl = EN_NICAM_AUTO_MONO2; 903 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
906 mask = 0x3f; 904 } else {
907 break; 905 /* TODO: Add A2 autodection */
908 case V4L2_TUNER_MODE_STEREO: 906 switch (mode) {
909 ctl = EN_NICAM_FORCE_STEREO | EN_DMTRX_LR; 907 case V4L2_TUNER_MODE_MONO:
910 mask = 0x93f; 908 case V4L2_TUNER_MODE_LANG1:
911 break; 909 set_audio_standard_A2(core,
912 } 910 EN_A2_FORCE_MONO1);
913 break; 911 break;
914 case WW_SYSTEM_L_AM: 912 case V4L2_TUNER_MODE_LANG2:
915 switch (mode) { 913 set_audio_standard_A2(core,
916 case V4L2_TUNER_MODE_MONO: 914 EN_A2_FORCE_MONO2);
917 case V4L2_TUNER_MODE_LANG1: /* FIXME */ 915 break;
918 set_audio_standard_NICAM_L(core, 0); 916 case V4L2_TUNER_MODE_STEREO:
919 break; 917 set_audio_standard_A2(core,
920 case V4L2_TUNER_MODE_STEREO: 918 EN_A2_FORCE_STEREO);
921 set_audio_standard_NICAM_L(core, 1); 919 break;
922 break; 920 }
923 } 921 }
924 break;
925 case WW_NICAM_I:
926 switch (mode) {
927 case V4L2_TUNER_MODE_MONO:
928 case V4L2_TUNER_MODE_LANG1:
929 set_audio_standard_PAL_I(core, 0);
930 break;
931 case V4L2_TUNER_MODE_STEREO:
932 set_audio_standard_PAL_I(core, 1);
933 break;
934 } 922 }
935 break; 923 break;
936 case WW_FM: 924 case WW_FM:
937 switch (mode) { 925 switch (mode) {
938 case V4L2_TUNER_MODE_MONO: 926 case V4L2_TUNER_MODE_MONO:
939 ctl = EN_FMRADIO_FORCE_MONO; 927 ctl = EN_FMRADIO_FORCE_MONO;
940 mask = 0x3f; 928 mask = 0x3f;
941 break; 929 break;
942 case V4L2_TUNER_MODE_STEREO: 930 case V4L2_TUNER_MODE_STEREO:
943 ctl = EN_FMRADIO_AUTO_STEREO; 931 ctl = EN_FMRADIO_AUTO_STEREO;
944 mask = 0x3f; 932 mask = 0x3f;
945 break; 933 break;
946 } 934 }
@@ -970,8 +958,8 @@ int cx88_audio_thread(void *data)
970 break; 958 break;
971 959
972 /* just monitor the audio status for now ... */ 960 /* just monitor the audio status for now ... */
973 memset(&t,0,sizeof(t)); 961 memset(&t, 0, sizeof(t));
974 cx88_get_stereo(core,&t); 962 cx88_get_stereo(core, &t);
975 963
976 if (UNSET != core->audiomode_manual) 964 if (UNSET != core->audiomode_manual)
977 /* manually set, don't do anything. */ 965 /* manually set, don't do anything. */
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 3dbc074fb515..24a48f8a48c1 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -34,6 +34,9 @@
34 34
35#include "cx88.h" 35#include "cx88.h"
36 36
37/* Include V4L1 specific functions. Should be removed soon */
38#include <linux/videodev.h>
39
37MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); 40MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
38MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 41MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
39MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
@@ -100,7 +103,7 @@ static struct cx88_tvnorm tvnorms[] = {
100 .id = V4L2_STD_PAL_I, 103 .id = V4L2_STD_PAL_I,
101 .cxiformat = VideoFormatPAL, 104 .cxiformat = VideoFormatPAL,
102 .cxoformat = 0x181f0008, 105 .cxoformat = 0x181f0008,
103 },{ 106 },{
104 .name = "PAL-M", 107 .name = "PAL-M",
105 .id = V4L2_STD_PAL_M, 108 .id = V4L2_STD_PAL_M,
106 .cxiformat = VideoFormatPALM, 109 .cxiformat = VideoFormatPALM,
@@ -470,7 +473,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
470 struct list_head *item; 473 struct list_head *item;
471 474
472 if (!list_empty(&q->active)) { 475 if (!list_empty(&q->active)) {
473 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); 476 buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
474 dprintk(2,"restart_queue [%p/%d]: restart dma\n", 477 dprintk(2,"restart_queue [%p/%d]: restart dma\n",
475 buf, buf->vb.i); 478 buf, buf->vb.i);
476 start_video_dma(dev, q, buf); 479 start_video_dma(dev, q, buf);
@@ -486,7 +489,7 @@ static int restart_video_queue(struct cx8800_dev *dev,
486 for (;;) { 489 for (;;) {
487 if (list_empty(&q->queued)) 490 if (list_empty(&q->queued))
488 return 0; 491 return 0;
489 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue); 492 buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
490 if (NULL == prev) { 493 if (NULL == prev) {
491 list_del(&buf->vb.queue); 494 list_del(&buf->vb.queue);
492 list_add_tail(&buf->vb.queue,&q->active); 495 list_add_tail(&buf->vb.queue,&q->active);
@@ -783,11 +786,11 @@ static int video_open(struct inode *inode, struct file *file)
783 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL); 786 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
784 } 787 }
785 788
786 return 0; 789 return 0;
787} 790}
788 791
789static ssize_t 792static ssize_t
790video_read(struct file *file, char *data, size_t count, loff_t *ppos) 793video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
791{ 794{
792 struct cx8800_fh *fh = file->private_data; 795 struct cx8800_fh *fh = file->private_data;
793 796
@@ -922,7 +925,7 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
922{ 925{
923 /* struct cx88_core *core = dev->core; */ 926 /* struct cx88_core *core = dev->core; */
924 struct cx88_ctrl *c = NULL; 927 struct cx88_ctrl *c = NULL;
925 u32 v_sat_value; 928 u32 v_sat_value;
926 u32 value; 929 u32 value;
927 int i; 930 int i;
928 931
@@ -1187,7 +1190,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1187 struct v4l2_format *f = arg; 1190 struct v4l2_format *f = arg;
1188 return cx8800_try_fmt(dev,fh,f); 1191 return cx8800_try_fmt(dev,fh,f);
1189 } 1192 }
1190 1193#ifdef HAVE_V4L1
1191 /* --- streaming capture ------------------------------------- */ 1194 /* --- streaming capture ------------------------------------- */
1192 case VIDIOCGMBUF: 1195 case VIDIOCGMBUF:
1193 { 1196 {
@@ -1213,6 +1216,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1213 } 1216 }
1214 return 0; 1217 return 0;
1215 } 1218 }
1219#endif
1216 case VIDIOC_REQBUFS: 1220 case VIDIOC_REQBUFS:
1217 return videobuf_reqbufs(get_queue(fh), arg); 1221 return videobuf_reqbufs(get_queue(fh), arg);
1218 1222
@@ -1244,7 +1248,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1244 res_free(dev,fh,res); 1248 res_free(dev,fh,res);
1245 return 0; 1249 return 0;
1246 } 1250 }
1247
1248 default: 1251 default:
1249 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl ); 1252 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl );
1250 } 1253 }
@@ -1252,15 +1255,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1252} 1255}
1253 1256
1254int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, 1257int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1255 struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl) 1258 struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl)
1256{ 1259{
1257 int err; 1260 int err;
1258 1261
1262 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1259 if (video_debug > 1) 1263 if (video_debug > 1)
1260 cx88_print_ioctl(core->name,cmd); 1264 cx88_print_ioctl(core->name,cmd);
1261 printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd );
1262 cx88_print_ioctl(core->name,cmd);
1263 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1264 1265
1265 switch (cmd) { 1266 switch (cmd) {
1266 /* ---------- tv norms ---------- */ 1267 /* ---------- tv norms ---------- */
@@ -1401,7 +1402,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1401 1402
1402 cx88_get_stereo(core ,t); 1403 cx88_get_stereo(core ,t);
1403 reg = cx_read(MO_DEVICE_STATUS); 1404 reg = cx_read(MO_DEVICE_STATUS);
1404 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; 1405 t->signal = (reg & (1<<5)) ? 0xffff : 0x0000;
1405 return 0; 1406 return 0;
1406 } 1407 }
1407 case VIDIOC_S_TUNER: 1408 case VIDIOC_S_TUNER:
@@ -1488,7 +1489,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1488 struct v4l2_capability *cap = arg; 1489 struct v4l2_capability *cap = arg;
1489 1490
1490 memset(cap,0,sizeof(*cap)); 1491 memset(cap,0,sizeof(*cap));
1491 strcpy(cap->driver, "cx8800"); 1492 strcpy(cap->driver, "cx8800");
1492 strlcpy(cap->card, cx88_boards[core->board].name, 1493 strlcpy(cap->card, cx88_boards[core->board].name,
1493 sizeof(cap->card)); 1494 sizeof(cap->card));
1494 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); 1495 sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
@@ -1505,6 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1505 1506
1506 memset(t,0,sizeof(*t)); 1507 memset(t,0,sizeof(*t));
1507 strcpy(t->name, "Radio"); 1508 strcpy(t->name, "Radio");
1509 t->type = V4L2_TUNER_RADIO;
1508 1510
1509 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t); 1511 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
1510 return 0; 1512 return 0;
@@ -1539,6 +1541,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1539 *id = 0; 1541 *id = 0;
1540 return 0; 1542 return 0;
1541 } 1543 }
1544#ifdef HAVE_V4L1
1542 case VIDIOCSTUNER: 1545 case VIDIOCSTUNER:
1543 { 1546 {
1544 struct video_tuner *v = arg; 1547 struct video_tuner *v = arg;
@@ -1549,6 +1552,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1549 cx88_call_i2c_clients(core,VIDIOCSTUNER,v); 1552 cx88_call_i2c_clients(core,VIDIOCSTUNER,v);
1550 return 0; 1553 return 0;
1551 } 1554 }
1555#endif
1552 case VIDIOC_S_TUNER: 1556 case VIDIOC_S_TUNER:
1553 { 1557 {
1554 struct v4l2_tuner *t = arg; 1558 struct v4l2_tuner *t = arg;
@@ -1829,8 +1833,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1829 1833
1830 /* print pci info */ 1834 /* print pci info */
1831 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 1835 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1832 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 1836 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1833 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " 1837 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1834 "latency: %d, mmio: 0x%lx\n", core->name, 1838 "latency: %d, mmio: 0x%lx\n", core->name,
1835 pci_name(pci_dev), dev->pci_rev, pci_dev->irq, 1839 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1836 dev->pci_lat,pci_resource_start(pci_dev,0)); 1840 dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -1946,7 +1950,7 @@ fail_free:
1946 1950
1947static void __devexit cx8800_finidev(struct pci_dev *pci_dev) 1951static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
1948{ 1952{
1949 struct cx8800_dev *dev = pci_get_drvdata(pci_dev); 1953 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
1950 struct cx88_core *core = dev->core; 1954 struct cx88_core *core = dev->core;
1951 1955
1952 /* stop thread */ 1956 /* stop thread */
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index f48dd4353568..b19d3a9e2298 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -22,7 +22,7 @@
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/i2c-algo-bit.h> 24#include <linux/i2c-algo-bit.h>
25#include <linux/videodev.h> 25#include <linux/videodev2.h>
26#include <linux/kdev_t.h> 26#include <linux/kdev_t.h>
27 27
28#include <media/tuner.h> 28#include <media/tuner.h>
@@ -148,7 +148,7 @@ extern struct sram_channel cx88_sram_channels[];
148#define CX88_BOARD_PIXELVIEW 3 148#define CX88_BOARD_PIXELVIEW 3
149#define CX88_BOARD_ATI_WONDER_PRO 4 149#define CX88_BOARD_ATI_WONDER_PRO 4
150#define CX88_BOARD_WINFAST2000XP_EXPERT 5 150#define CX88_BOARD_WINFAST2000XP_EXPERT 5
151#define CX88_BOARD_AVERTV_303 6 151#define CX88_BOARD_AVERTV_STUDIO_303 6
152#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7 152#define CX88_BOARD_MSI_TVANYWHERE_MASTER 7
153#define CX88_BOARD_WINFAST_DV2000 8 153#define CX88_BOARD_WINFAST_DV2000 8
154#define CX88_BOARD_LEADTEK_PVR2000 9 154#define CX88_BOARD_LEADTEK_PVR2000 9
@@ -174,6 +174,11 @@ extern struct sram_channel cx88_sram_channels[];
174#define CX88_BOARD_ADSTECH_DVB_T_PCI 29 174#define CX88_BOARD_ADSTECH_DVB_T_PCI 29
175#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30 175#define CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1 30
176#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31 176#define CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD 31
177#define CX88_BOARD_AVERMEDIA_ULTRATV_MC_550 32
178#define CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD 33
179#define CX88_BOARD_ATI_HDTVWONDER 34
180#define CX88_BOARD_WINFAST_DTV1000 35
181#define CX88_BOARD_AVERTV_303 36
177 182
178enum cx88_itype { 183enum cx88_itype {
179 CX88_VMUX_COMPOSITE1 = 1, 184 CX88_VMUX_COMPOSITE1 = 1,
@@ -203,8 +208,8 @@ struct cx88_board {
203 int tda9887_conf; 208 int tda9887_conf;
204 struct cx88_input input[MAX_CX88_INPUT]; 209 struct cx88_input input[MAX_CX88_INPUT];
205 struct cx88_input radio; 210 struct cx88_input radio;
206 int blackbird:1; 211 unsigned int blackbird:1;
207 int dvb:1; 212 unsigned int dvb:1;
208}; 213};
209 214
210struct cx88_subid { 215struct cx88_subid {
@@ -255,8 +260,8 @@ struct cx88_core {
255 /* pci stuff */ 260 /* pci stuff */
256 int pci_bus; 261 int pci_bus;
257 int pci_slot; 262 int pci_slot;
258 u32 __iomem *lmmio; 263 u32 __iomem *lmmio;
259 u8 __iomem *bmmio; 264 u8 __iomem *bmmio;
260 u32 shadow[SHADOW_MAX]; 265 u32 shadow[SHADOW_MAX];
261 int pci_irqmask; 266 int pci_irqmask;
262 267
@@ -287,6 +292,7 @@ struct cx88_core {
287 u32 audiomode_current; 292 u32 audiomode_current;
288 u32 input; 293 u32 input;
289 u32 astat; 294 u32 astat;
295 u32 use_nicam;
290 296
291 /* IR remote control state */ 297 /* IR remote control state */
292 struct cx88_IR *ir; 298 struct cx88_IR *ir;
@@ -370,6 +376,14 @@ struct cx8802_suspend_state {
370 int disabled; 376 int disabled;
371}; 377};
372 378
379/* TODO: move this to struct v4l2_mpeg_compression ? */
380struct blackbird_dnr {
381 u32 mode;
382 u32 type;
383 u32 spatial;
384 u32 temporal;
385};
386
373struct cx8802_dev { 387struct cx8802_dev {
374 struct cx88_core *core; 388 struct cx88_core *core;
375 spinlock_t slock; 389 spinlock_t slock;
@@ -400,6 +414,10 @@ struct cx8802_dev {
400 414
401 /* for switching modulation types */ 415 /* for switching modulation types */
402 unsigned char ts_gen_cntrl; 416 unsigned char ts_gen_cntrl;
417
418 /* mpeg params */
419 struct v4l2_mpeg_compression params;
420 struct blackbird_dnr dnr_params;
403}; 421};
404 422
405/* ----------------------------------------------------------- */ 423/* ----------------------------------------------------------- */
@@ -514,22 +532,20 @@ extern void cx88_card_setup(struct cx88_core *core);
514 532
515#define WW_NONE 1 533#define WW_NONE 1
516#define WW_BTSC 2 534#define WW_BTSC 2
517#define WW_NICAM_I 3 535#define WW_BG 3
518#define WW_NICAM_BGDKL 4 536#define WW_DK 4
519#define WW_A1 5 537#define WW_I 5
520#define WW_A2_BG 6 538#define WW_L 6
521#define WW_A2_DK 7 539#define WW_EIAJ 7
522#define WW_A2_M 8 540#define WW_I2SPT 8
523#define WW_EIAJ 9 541#define WW_FM 9
524#define WW_SYSTEM_L_AM 10
525#define WW_I2SPT 11
526#define WW_FM 12
527 542
528void cx88_set_tvaudio(struct cx88_core *core); 543void cx88_set_tvaudio(struct cx88_core *core);
529void cx88_newstation(struct cx88_core *core); 544void cx88_newstation(struct cx88_core *core);
530void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); 545void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
531void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); 546void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
532int cx88_audio_thread(void *data); 547int cx88_audio_thread(void *data);
548int cx88_detect_nicam(struct cx88_core *core);
533 549
534/* ----------------------------------------------------------- */ 550/* ----------------------------------------------------------- */
535/* cx88-input.c */ 551/* cx88-input.c */
@@ -541,7 +557,8 @@ void cx88_ir_irq(struct cx88_core *core);
541/* ----------------------------------------------------------- */ 557/* ----------------------------------------------------------- */
542/* cx88-mpeg.c */ 558/* cx88-mpeg.c */
543 559
544int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf); 560int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
561 enum v4l2_field field);
545void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf); 562void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf);
546void cx8802_cancel_buffers(struct cx8802_dev *dev); 563void cx8802_cancel_buffers(struct cx8802_dev *dev);
547 564
@@ -562,6 +579,10 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
562extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, 579extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
563 unsigned int cmd, void *arg); 580 unsigned int cmd, void *arg);
564extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); 581extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
582void blackbird_set_params(struct cx8802_dev *dev,
583 struct v4l2_mpeg_compression *params);
584void blackbird_set_dnr_params(struct cx8802_dev *dev,
585 struct blackbird_dnr* dnr_params);
565 586
566/* 587/*
567 * Local variables: 588 * Local variables:
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
new file mode 100644
index 000000000000..885fd0170086
--- /dev/null
+++ b/drivers/media/video/em28xx/Kconfig
@@ -0,0 +1,12 @@
1config VIDEO_EM28XX
2 tristate "Empia EM2800/2820/2840 USB video capture support"
3 depends on VIDEO_DEV && USB && I2C
4 select VIDEO_BUF
5 select VIDEO_TUNER
6 select VIDEO_TVEEPROM
7 select VIDEO_IR
8 ---help---
9 This is a video4linux driver for Empia 28xx based TV cards.
10
11 To compile this driver as a module, choose M here: the
12 module will be called em28xx
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
new file mode 100644
index 000000000000..da457a05b0dd
--- /dev/null
+++ b/drivers/media/video/em28xx/Makefile
@@ -0,0 +1,6 @@
1em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
2 em28xx-input.o
3
4obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
5
6EXTRA_CFLAGS += -I$(src)/..
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
new file mode 100644
index 000000000000..57779e63f35d
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -0,0 +1,292 @@
1/*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/delay.h>
28#include <linux/i2c.h>
29#include <linux/usb.h>
30#include <media/tuner.h>
31#include <media/audiochip.h>
32#include <media/tveeprom.h>
33#include "msp3400.h"
34
35#include "em28xx.h"
36
37struct em28xx_board em28xx_boards[] = {
38 [EM2800_BOARD_UNKNOWN] = {
39 .name = "Unknown EM2800 video grabber",
40 .is_em2800 = 1,
41 .vchannels = 2,
42 .norm = VIDEO_MODE_PAL,
43 .tda9887_conf = TDA9887_PRESENT,
44 .has_tuner = 1,
45 .decoder = EM28XX_SAA7113,
46 .input = {{
47 .type = EM28XX_VMUX_COMPOSITE1,
48 .vmux = 0,
49 .amux = 1,
50 },{
51 .type = EM28XX_VMUX_SVIDEO,
52 .vmux = 9,
53 .amux = 1,
54 }},
55 },
56 [EM2820_BOARD_UNKNOWN] = {
57 .name = "Unknown EM2820/2840 video grabber",
58 .is_em2800 = 0,
59 .vchannels = 2,
60 .norm = VIDEO_MODE_PAL,
61 .tda9887_conf = TDA9887_PRESENT,
62 .has_tuner = 1,
63 .decoder = EM28XX_SAA7113,
64 .input = {{
65 .type = EM28XX_VMUX_COMPOSITE1,
66 .vmux = 0,
67 .amux = 1,
68 },{
69 .type = EM28XX_VMUX_SVIDEO,
70 .vmux = 9,
71 .amux = 1,
72 }},
73 },
74 [EM2820_BOARD_TERRATEC_CINERGY_250] = {
75 .name = "Terratec Cinergy 250 USB",
76 .vchannels = 3,
77 .norm = VIDEO_MODE_PAL,
78 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
79 .tda9887_conf = TDA9887_PRESENT,
80 .has_tuner = 1,
81 .decoder = EM28XX_SAA7113,
82 .input = {{
83 .type = EM28XX_VMUX_TELEVISION,
84 .vmux = 2,
85 .amux = 0,
86 },{
87 .type = EM28XX_VMUX_COMPOSITE1,
88 .vmux = 0,
89 .amux = 1,
90 },{
91 .type = EM28XX_VMUX_SVIDEO,
92 .vmux = 9,
93 .amux = 1,
94 }},
95 },
96 [EM2820_BOARD_PINNACLE_USB_2] = {
97 .name = "Pinnacle PCTV USB 2",
98 .vchannels = 3,
99 .norm = VIDEO_MODE_PAL,
100 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
101 .tda9887_conf = TDA9887_PRESENT,
102 .has_tuner = 1,
103 .decoder = EM28XX_SAA7113,
104 .input = {{
105 .type = EM28XX_VMUX_TELEVISION,
106 .vmux = 2,
107 .amux = 0,
108 },{
109 .type = EM28XX_VMUX_COMPOSITE1,
110 .vmux = 0,
111 .amux = 1,
112 },{
113 .type = EM28XX_VMUX_SVIDEO,
114 .vmux = 9,
115 .amux = 1,
116 }},
117 },
118 [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
119 .name = "Hauppauge WinTV USB 2",
120 .vchannels = 3,
121 .norm = VIDEO_MODE_NTSC,
122 .tuner_type = TUNER_PHILIPS_FM1236_MK3,
123 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
124 .has_tuner = 1,
125 .decoder = EM28XX_TVP5150,
126 .has_msp34xx = 1,
127 /*FIXME: S-Video not tested */
128 .input = {{
129 .type = EM28XX_VMUX_TELEVISION,
130 .vmux = 0,
131 .amux = 6,
132 },{
133 .type = EM28XX_VMUX_SVIDEO,
134 .vmux = 2,
135 .amux = 1,
136 }},
137 },
138 [EM2820_BOARD_MSI_VOX_USB_2] = {
139 .name = "MSI VOX USB 2.0",
140 .vchannels = 3,
141 .norm = VIDEO_MODE_PAL,
142 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
143 .tda9887_conf = TDA9887_PRESENT|TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE,
144 .has_tuner = 1,
145 .decoder = EM28XX_SAA7114,
146 .input = {{
147 .type = EM28XX_VMUX_TELEVISION,
148 .vmux = 4,
149 .amux = 0,
150 },{
151 .type = EM28XX_VMUX_COMPOSITE1,
152 .vmux = 0,
153 .amux = 1,
154 },{
155 .type = EM28XX_VMUX_SVIDEO,
156 .vmux = 9,
157 .amux = 1,
158 }},
159 },
160 [EM2800_BOARD_TERRATEC_CINERGY_200] = {
161 .name = "Terratec Cinergy 200 USB",
162 .is_em2800 = 1,
163 .vchannels = 3,
164 .norm = VIDEO_MODE_PAL,
165 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
166 .tda9887_conf = TDA9887_PRESENT,
167 .has_tuner = 1,
168 .decoder = EM28XX_SAA7113,
169 .input = {{
170 .type = EM28XX_VMUX_TELEVISION,
171 .vmux = 2,
172 .amux = 0,
173 },{
174 .type = EM28XX_VMUX_COMPOSITE1,
175 .vmux = 0,
176 .amux = 1,
177 },{
178 .type = EM28XX_VMUX_SVIDEO,
179 .vmux = 9,
180 .amux = 1,
181 }},
182 },
183 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
184 .name = "Leadtek Winfast USB II",
185 .is_em2800 = 1,
186 .vchannels = 3,
187 .norm = VIDEO_MODE_PAL,
188 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
189 .tda9887_conf = TDA9887_PRESENT,
190 .has_tuner = 1,
191 .decoder = EM28XX_SAA7113,
192 .input = {{
193 .type = EM28XX_VMUX_TELEVISION,
194 .vmux = 2,
195 .amux = 0,
196 },{
197 .type = EM28XX_VMUX_COMPOSITE1,
198 .vmux = 0,
199 .amux = 1,
200 },{
201 .type = EM28XX_VMUX_SVIDEO,
202 .vmux = 9,
203 .amux = 1,
204 }},
205 },
206 [EM2800_BOARD_KWORLD_USB2800] = {
207 .name = "Kworld USB2800",
208 .is_em2800 = 1,
209 .vchannels = 3,
210 .norm = VIDEO_MODE_PAL,
211 .tuner_type = TUNER_PHILIPS_ATSC,
212 .tda9887_conf = TDA9887_PRESENT,
213 .has_tuner = 1,
214 .decoder = EM28XX_SAA7113,
215 .input = {{
216 .type = EM28XX_VMUX_TELEVISION,
217 .vmux = 2,
218 .amux = 0,
219 },{
220 .type = EM28XX_VMUX_COMPOSITE1,
221 .vmux = 0,
222 .amux = 1,
223 },{
224 .type = EM28XX_VMUX_SVIDEO,
225 .vmux = 9,
226 .amux = 1,
227 }},
228 },
229 [EM2820_BOARD_PINNACLE_DVC_90] = {
230 .name = "Pinnacle Dazzle DVC 90",
231 .vchannels = 3,
232 .norm = VIDEO_MODE_PAL,
233 .has_tuner = 0,
234 .decoder = EM28XX_SAA7113,
235 .input = {{
236 .type = EM28XX_VMUX_COMPOSITE1,
237 .vmux = 0,
238 .amux = 1,
239 },{
240 .type = EM28XX_VMUX_SVIDEO,
241 .vmux = 9,
242 .amux = 1,
243 }},
244 },
245};
246const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
247
248/* table of devices that work with this driver */
249struct usb_device_id em28xx_id_table [] = {
250 { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN },
251 { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_MSI_VOX_USB_2 },
252 { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
253 { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
254 { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
255 { USB_DEVICE(0x2304, 0x0207), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
256 { },
257};
258
259void em28xx_card_setup(struct em28xx *dev)
260{
261 /* request some modules */
262 if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) {
263 struct tveeprom tv;
264 struct v4l2_audioout ao;
265#ifdef CONFIG_MODULES
266 request_module("tveeprom");
267 request_module("ir-kbd-i2c");
268 request_module("msp3400");
269#endif
270 /* Call first TVeeprom */
271
272 dev->i2c_client.addr = 0xa0 >> 1;
273 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
274
275 dev->tuner_type= tv.tuner_type;
276 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
277 dev->has_msp34xx=1;
278 memset (&ao,0,sizeof(ao));
279
280 ao.index=2;
281 ao.mode=V4L2_AUDMODE_32BITS;
282 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao);
283 } else
284 dev->has_msp34xx=0;
285 }
286}
287
288EXPORT_SYMBOL(em28xx_boards);
289EXPORT_SYMBOL(em28xx_bcount);
290EXPORT_SYMBOL(em28xx_id_table);
291
292MODULE_DEVICE_TABLE (usb, em28xx_id_table);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
new file mode 100644
index 000000000000..d54bc0127484
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -0,0 +1,817 @@
1/*
2 em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/usb.h>
29#include <linux/vmalloc.h>
30
31#include "em28xx.h"
32
33/* #define ENABLE_DEBUG_ISOC_FRAMES */
34
35unsigned int core_debug;
36module_param(core_debug,int,0644);
37MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
38
39#define em28xx_coredbg(fmt, arg...) do {\
40 if (core_debug) \
41 printk(KERN_INFO "%s %s :"fmt, \
42 dev->name, __FUNCTION__ , ##arg); } while (0)
43
44unsigned int reg_debug;
45module_param(reg_debug,int,0644);
46MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
47
48#define em28xx_regdbg(fmt, arg...) do {\
49 if (reg_debug) \
50 printk(KERN_INFO "%s %s :"fmt, \
51 dev->name, __FUNCTION__ , ##arg); } while (0)
52
53unsigned int isoc_debug;
54module_param(isoc_debug,int,0644);
55MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]");
56
57#define em28xx_isocdbg(fmt, arg...) do {\
58 if (isoc_debug) \
59 printk(KERN_INFO "%s %s :"fmt, \
60 dev->name, __FUNCTION__ , ##arg); } while (0)
61
62static int alt = EM28XX_PINOUT;
63module_param(alt, int, 0644);
64MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
65
66/* ------------------------------------------------------------------ */
67/* debug help functions */
68
69static const char *v4l1_ioctls[] = {
70 "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT",
71 "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ",
72 "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT",
73 "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO",
74 "SMICROCODE", "GVBIFMT", "SVBIFMT" };
75#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls)
76
77static const char *v4l2_ioctls[] = {
78 "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT",
79 "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF",
80 "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON",
81 "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD",
82 "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER",
83 "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL",
84 "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43",
85 "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT",
86 "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR",
87 "S_MODULATOR"
88};
89#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
90
91void em28xx_print_ioctl(char *name, unsigned int cmd)
92{
93 char *dir;
94
95 switch (_IOC_DIR(cmd)) {
96 case _IOC_NONE: dir = "--"; break;
97 case _IOC_READ: dir = "r-"; break;
98 case _IOC_WRITE: dir = "-w"; break;
99 case _IOC_READ | _IOC_WRITE: dir = "rw"; break;
100 default: dir = "??"; break;
101 }
102 switch (_IOC_TYPE(cmd)) {
103 case 'v':
104 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n",
105 name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ?
106 v4l1_ioctls[_IOC_NR(cmd)] : "???");
107 break;
108 case 'V':
109 printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n",
110 name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ?
111 v4l2_ioctls[_IOC_NR(cmd)] : "???");
112 break;
113 default:
114 printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n",
115 name, cmd, dir, _IOC_NR(cmd));
116 }
117}
118
119static void *rvmalloc(size_t size)
120{
121 void *mem;
122 unsigned long adr;
123
124 size = PAGE_ALIGN(size);
125
126 mem = vmalloc_32((unsigned long)size);
127 if (!mem)
128 return NULL;
129
130 memset(mem, 0, size);
131
132 adr = (unsigned long)mem;
133 while (size > 0) {
134 SetPageReserved(vmalloc_to_page((void *)adr));
135 adr += PAGE_SIZE;
136 size -= PAGE_SIZE;
137 }
138
139 return mem;
140}
141
142static void rvfree(void *mem, size_t size)
143{
144 unsigned long adr;
145
146 if (!mem)
147 return;
148
149 size = PAGE_ALIGN(size);
150
151 adr = (unsigned long)mem;
152 while (size > 0) {
153 ClearPageReserved(vmalloc_to_page((void *)adr));
154 adr += PAGE_SIZE;
155 size -= PAGE_SIZE;
156 }
157
158 vfree(mem);
159}
160
161/*
162 * em28xx_request_buffers()
163 * allocate a number of buffers
164 */
165u32 em28xx_request_buffers(struct em28xx *dev, u32 count)
166{
167 const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */
168 void *buff = NULL;
169 u32 i;
170 em28xx_coredbg("requested %i buffers with size %i", count, imagesize);
171 if (count > EM28XX_NUM_FRAMES)
172 count = EM28XX_NUM_FRAMES;
173
174 dev->num_frames = count;
175 while (dev->num_frames > 0) {
176 if ((buff = rvmalloc(dev->num_frames * imagesize)))
177 break;
178 dev->num_frames--;
179 }
180
181 for (i = 0; i < dev->num_frames; i++) {
182 dev->frame[i].bufmem = buff + i * imagesize;
183 dev->frame[i].buf.index = i;
184 dev->frame[i].buf.m.offset = i * imagesize;
185 dev->frame[i].buf.length = dev->frame_size;
186 dev->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
187 dev->frame[i].buf.sequence = 0;
188 dev->frame[i].buf.field = V4L2_FIELD_NONE;
189 dev->frame[i].buf.memory = V4L2_MEMORY_MMAP;
190 dev->frame[i].buf.flags = 0;
191 }
192 return dev->num_frames;
193}
194
195/*
196 * em28xx_queue_unusedframes()
197 * add all frames that are not currently in use to the inbuffer queue
198 */
199void em28xx_queue_unusedframes(struct em28xx *dev)
200{
201 unsigned long lock_flags;
202 u32 i;
203
204 for (i = 0; i < dev->num_frames; i++)
205 if (dev->frame[i].state == F_UNUSED) {
206 dev->frame[i].state = F_QUEUED;
207 spin_lock_irqsave(&dev->queue_lock, lock_flags);
208 list_add_tail(&dev->frame[i].frame, &dev->inqueue);
209 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
210 }
211}
212
213/*
214 * em28xx_release_buffers()
215 * free frame buffers
216 */
217void em28xx_release_buffers(struct em28xx *dev)
218{
219 if (dev->num_frames) {
220 rvfree(dev->frame[0].bufmem,
221 dev->num_frames * PAGE_ALIGN(dev->frame[0].buf.length));
222 dev->num_frames = 0;
223 }
224}
225
226/*
227 * em28xx_read_reg_req()
228 * reads data from the usb device specifying bRequest
229 */
230int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
231 char *buf, int len)
232{
233 int ret, byte;
234
235 em28xx_regdbg("req=%02x, reg=%02x ", req, reg);
236
237 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
238 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
239 0x0000, reg, buf, len, HZ);
240
241 if (reg_debug){
242 printk(ret < 0 ? " failed!\n" : "%02x values: ", ret);
243 for (byte = 0; byte < len; byte++) {
244 printk(" %02x", buf[byte]);
245 }
246 printk("\n");
247 }
248
249 return ret;
250}
251
252/*
253 * em28xx_read_reg_req()
254 * reads data from the usb device specifying bRequest
255 */
256int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg)
257{
258 u8 val;
259 int ret;
260
261 em28xx_regdbg("req=%02x, reg=%02x:", req, reg);
262
263 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req,
264 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
265 0x0000, reg, &val, 1, HZ);
266
267 if (reg_debug)
268 printk(ret < 0 ? " failed!\n" : "%02x\n", val);
269
270 if (ret < 0)
271 return ret;
272
273 return val;
274}
275
276int em28xx_read_reg(struct em28xx *dev, u16 reg)
277{
278 return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg);
279}
280
281/*
282 * em28xx_write_regs_req()
283 * sends data to the usb device, specifying bRequest
284 */
285int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
286 int len)
287{
288 int ret;
289
290 /*usb_control_msg seems to expect a kmalloced buffer */
291 unsigned char *bufs = kmalloc(len, GFP_KERNEL);
292
293 em28xx_regdbg("req=%02x reg=%02x:", req, reg);
294
295 if (reg_debug) {
296 int i;
297 for (i = 0; i < len; ++i)
298 printk (" %02x", (unsigned char)buf[i]);
299 printk ("\n");
300 }
301
302 if (!bufs)
303 return -ENOMEM;
304 memcpy(bufs, buf, len);
305 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req,
306 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
307 0x0000, reg, bufs, len, HZ);
308 mdelay(5); /* FIXME: magic number */
309 kfree(bufs);
310 return ret;
311}
312
313int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len)
314{
315 return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len);
316}
317
318/*
319 * em28xx_write_reg_bits()
320 * sets only some bits (specified by bitmask) of a register, by first reading
321 * the actual value
322 */
323int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
324 u8 bitmask)
325{
326 int oldval;
327 u8 newval;
328 if ((oldval = em28xx_read_reg(dev, reg)) < 0)
329 return oldval;
330 newval = (((u8) oldval) & ~bitmask) | (val & bitmask);
331 return em28xx_write_regs(dev, reg, &newval, 1);
332}
333
334/*
335 * em28xx_write_ac97()
336 * write a 16 bit value to the specified AC97 address (LSB first!)
337 */
338int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val)
339{
340 int ret;
341 u8 addr = reg & 0x7f;
342 if ((ret = em28xx_write_regs(dev, AC97LSB_REG, val, 2)) < 0)
343 return ret;
344 if ((ret = em28xx_write_regs(dev, AC97ADDR_REG, &addr, 1)) < 0)
345 return ret;
346 if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0)
347 return ret;
348 else if (((u8) ret) & 0x01) {
349 em28xx_warn ("AC97 command still being exectuted: not handled properly!\n");
350 }
351 return 0;
352}
353
354int em28xx_audio_analog_set(struct em28xx *dev)
355{
356 char s[2] = { 0x00, 0x00 };
357 s[0] |= 0x1f - dev->volume;
358 s[1] |= 0x1f - dev->volume;
359 if (dev->mute)
360 s[1] |= 0x80;
361 return em28xx_write_ac97(dev, MASTER_AC97, s);
362}
363
364
365int em28xx_colorlevels_set_default(struct em28xx *dev)
366{
367 em28xx_write_regs(dev, YGAIN_REG, "\x10", 1); /* contrast */
368 em28xx_write_regs(dev, YOFFSET_REG, "\x00", 1); /* brightness */
369 em28xx_write_regs(dev, UVGAIN_REG, "\x10", 1); /* saturation */
370 em28xx_write_regs(dev, UOFFSET_REG, "\x00", 1);
371 em28xx_write_regs(dev, VOFFSET_REG, "\x00", 1);
372 em28xx_write_regs(dev, SHARPNESS_REG, "\x00", 1);
373
374 em28xx_write_regs(dev, GAMMA_REG, "\x20", 1);
375 em28xx_write_regs(dev, RGAIN_REG, "\x20", 1);
376 em28xx_write_regs(dev, GGAIN_REG, "\x20", 1);
377 em28xx_write_regs(dev, BGAIN_REG, "\x20", 1);
378 em28xx_write_regs(dev, ROFFSET_REG, "\x00", 1);
379 em28xx_write_regs(dev, GOFFSET_REG, "\x00", 1);
380 return em28xx_write_regs(dev, BOFFSET_REG, "\x00", 1);
381}
382
383int em28xx_capture_start(struct em28xx *dev, int start)
384{
385 int ret;
386 /* FIXME: which is the best order? */
387 /* video registers are sampled by VREF */
388 if ((ret = em28xx_write_reg_bits(dev, USBSUSP_REG, start ? 0x10 : 0x00,
389 0x10)) < 0)
390 return ret;
391 /* enable video capture */
392 return em28xx_write_regs(dev, VINENABLE_REG, start ? "\x67" : "\x27", 1);
393}
394
395int em28xx_outfmt_set_yuv422(struct em28xx *dev)
396{
397 em28xx_write_regs(dev, OUTFMT_REG, "\x34", 1);
398 em28xx_write_regs(dev, VINMODE_REG, "\x10", 1);
399 return em28xx_write_regs(dev, VINCTRL_REG, "\x11", 1);
400}
401
402int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
403 u8 ymax)
404{
405 em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", xmin, ymin, xmax, ymax);
406
407 em28xx_write_regs(dev, XMIN_REG, &xmin, 1);
408 em28xx_write_regs(dev, XMAX_REG, &xmax, 1);
409 em28xx_write_regs(dev, YMIN_REG, &ymin, 1);
410 return em28xx_write_regs(dev, YMAX_REG, &ymax, 1);
411}
412
413int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
414 u16 width, u16 height)
415{
416 u8 cwidth = width;
417 u8 cheight = height;
418 u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01);
419
420 em28xx_coredbg("em28xx Area Set: (%d,%d)\n", (width | (overflow & 2) << 7),
421 (height | (overflow & 1) << 8));
422
423 em28xx_write_regs(dev, HSTART_REG, &hstart, 1);
424 em28xx_write_regs(dev, VSTART_REG, &vstart, 1);
425 em28xx_write_regs(dev, CWIDTH_REG, &cwidth, 1);
426 em28xx_write_regs(dev, CHEIGHT_REG, &cheight, 1);
427 return em28xx_write_regs(dev, OFLOW_REG, &overflow, 1);
428}
429
430int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
431{
432 u8 mode;
433 /* the em2800 scaler only supports scaling down to 50% */
434 if(dev->is_em2800)
435 mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00);
436 else {
437 u8 buf[2];
438 buf[0] = h;
439 buf[1] = h >> 8;
440 em28xx_write_regs(dev, HSCALELOW_REG, (char *)buf, 2);
441 buf[0] = v;
442 buf[1] = v >> 8;
443 em28xx_write_regs(dev, VSCALELOW_REG, (char *)buf, 2);
444 /* it seems that both H and V scalers must be active to work correctly */
445 mode = (h || v)? 0x30: 0x00;
446 }
447 return em28xx_write_reg_bits(dev, COMPR_REG, mode, 0x30);
448}
449
450/* FIXME: this only function read values from dev */
451int em28xx_resolution_set(struct em28xx *dev)
452{
453 int width, height;
454 width = norm_maxw(dev);
455 height = norm_maxh(dev) >> 1;
456
457 em28xx_outfmt_set_yuv422(dev);
458 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
459 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
460 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
461}
462
463
464/******************* isoc transfer handling ****************************/
465
466#ifdef ENABLE_DEBUG_ISOC_FRAMES
467static void em28xx_isoc_dump(struct urb *urb, struct pt_regs *regs)
468{
469 int len = 0;
470 int ntrans = 0;
471 int i;
472
473 printk(KERN_DEBUG "isocIrq: sf=%d np=%d ec=%x\n",
474 urb->start_frame, urb->number_of_packets,
475 urb->error_count);
476 for (i = 0; i < urb->number_of_packets; i++) {
477 unsigned char *buf =
478 urb->transfer_buffer +
479 urb->iso_frame_desc[i].offset;
480 int alen = urb->iso_frame_desc[i].actual_length;
481 if (alen > 0) {
482 if (buf[0] == 0x88) {
483 ntrans++;
484 len += alen;
485 } else if (buf[0] == 0x22) {
486 printk(KERN_DEBUG
487 "= l=%d nt=%d bpp=%d\n",
488 len - 4 * ntrans, ntrans,
489 ntrans == 0 ? 0 : len / ntrans);
490 ntrans = 1;
491 len = alen;
492 } else
493 printk(KERN_DEBUG "!\n");
494 }
495 printk(KERN_DEBUG " n=%d s=%d al=%d %x\n", i,
496 urb->iso_frame_desc[i].status,
497 urb->iso_frame_desc[i].actual_length,
498 (unsigned int)
499 *((unsigned char *)(urb->transfer_buffer +
500 urb->iso_frame_desc[i].
501 offset)));
502 }
503}
504#endif
505
506static inline int em28xx_isoc_video(struct em28xx *dev,struct em28xx_frame_t **f,
507 unsigned long *lock_flags, unsigned char buf)
508{
509 if (!(buf & 0x01)) {
510 if ((*f)->state == F_GRABBING) {
511 /*previous frame is incomplete */
512 if ((*f)->fieldbytesused < dev->field_size) {
513 (*f)->state = F_ERROR;
514 em28xx_isocdbg ("dropping incomplete bottom field (%i missing bytes)",
515 dev->field_size-(*f)->fieldbytesused);
516 } else {
517 (*f)->state = F_DONE;
518 (*f)->buf.bytesused = dev->frame_size;
519 }
520 }
521 if ((*f)->state == F_DONE || (*f)->state == F_ERROR) {
522 /* move current frame to outqueue and get next free buffer from inqueue */
523 spin_lock_irqsave(&dev-> queue_lock, *lock_flags);
524 list_move_tail(&(*f)->frame, &dev->outqueue);
525 if (!list_empty(&dev->inqueue))
526 (*f) = list_entry(dev-> inqueue.next,
527 struct em28xx_frame_t,frame);
528 else
529 (*f) = NULL;
530 spin_unlock_irqrestore(&dev->queue_lock,*lock_flags);
531 }
532 if (!(*f)) {
533 em28xx_isocdbg ("new frame but no buffer is free");
534 return -1;
535 }
536 do_gettimeofday(&(*f)->buf.timestamp);
537 (*f)->buf.sequence = ++dev->frame_count;
538 (*f)->buf.field = V4L2_FIELD_INTERLACED;
539 (*f)->state = F_GRABBING;
540 (*f)->buf.bytesused = 0;
541 (*f)->top_field = 1;
542 (*f)->fieldbytesused = 0;
543 } else {
544 /* acquiring bottom field */
545 if ((*f)->state == F_GRABBING) {
546 if (!(*f)->top_field) {
547 (*f)->state = F_ERROR;
548 em28xx_isocdbg ("unexpected begin of bottom field; discarding it");
549 } else if ((*f)-> fieldbytesused < dev->field_size - 172) {
550 (*f)->state = F_ERROR;
551 em28xx_isocdbg ("dropping incomplete top field (%i missing bytes)",
552 dev->field_size-(*f)->fieldbytesused);
553 } else {
554 (*f)->top_field = 0;
555 (*f)->fieldbytesused = 0;
556 }
557 }
558 }
559 return (0);
560}
561
562static inline void em28xx_isoc_video_copy(struct em28xx *dev,
563 struct em28xx_frame_t **f, unsigned char *buf, int len)
564{
565 void *fieldstart, *startwrite, *startread;
566 int linesdone, currlinedone, offset, lencopy,remain;
567
568 if(dev->frame_size != (*f)->buf.length){
569 em28xx_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length);
570 return;
571 }
572
573 if ((*f)->fieldbytesused + len > dev->field_size)
574 len =dev->field_size - (*f)->fieldbytesused;
575
576 if (buf[0] != 0x88 && buf[0] != 0x22) {
577 em28xx_isocdbg("frame is not complete\n");
578 startread = buf;
579 len+=4;
580 } else
581 startread = buf + 4;
582
583 remain = len;
584
585 if ((*f)->top_field)
586 fieldstart = (*f)->bufmem;
587 else
588 fieldstart = (*f)->bufmem + dev->bytesperline;
589
590 linesdone = (*f)->fieldbytesused / dev->bytesperline;
591 currlinedone = (*f)->fieldbytesused % dev->bytesperline;
592 offset = linesdone * dev->bytesperline * 2 + currlinedone;
593 startwrite = fieldstart + offset;
594 lencopy = dev->bytesperline - currlinedone;
595 lencopy = lencopy > remain ? remain : lencopy;
596
597 memcpy(startwrite, startread, lencopy);
598 remain -= lencopy;
599
600 while (remain > 0) {
601 startwrite += lencopy + dev->bytesperline;
602 startread += lencopy;
603 if (dev->bytesperline > remain)
604 lencopy = remain;
605 else
606 lencopy = dev->bytesperline;
607
608 memcpy(startwrite, startread, lencopy);
609 remain -= lencopy;
610 }
611
612 (*f)->fieldbytesused += len;
613}
614
615/*
616 * em28xx_isoIrq()
617 * handles the incoming isoc urbs and fills the frames from our inqueue
618 */
619void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs)
620{
621 struct em28xx *dev = urb->context;
622 int i, status;
623 struct em28xx_frame_t **f;
624 unsigned long lock_flags;
625
626 if (!dev)
627 return;
628#ifdef ENABLE_DEBUG_ISOC_FRAMES
629 if (isoc_debug>1)
630 em28xx_isoc_dump(urb, regs);
631#endif
632
633 if (urb->status == -ENOENT)
634 return;
635
636 f = &dev->frame_current;
637
638 if (dev->stream == STREAM_INTERRUPT) {
639 dev->stream = STREAM_OFF;
640 if ((*f))
641 (*f)->state = F_QUEUED;
642 em28xx_isocdbg("stream interrupted");
643 wake_up_interruptible(&dev->wait_stream);
644 }
645
646 if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
647 return;
648
649 if (dev->stream == STREAM_ON && !list_empty(&dev->inqueue)) {
650 if (!(*f))
651 (*f) = list_entry(dev->inqueue.next,
652 struct em28xx_frame_t, frame);
653
654 for (i = 0; i < urb->number_of_packets; i++) {
655 unsigned char *buf = urb->transfer_buffer +
656 urb->iso_frame_desc[i].offset;
657 int len = urb->iso_frame_desc[i].actual_length - 4;
658
659 if (urb->iso_frame_desc[i].status) {
660 em28xx_isocdbg("data error: [%d] len=%d, status=%d", i,
661 urb->iso_frame_desc[i].actual_length,
662 urb->iso_frame_desc[i].status);
663 if (urb->iso_frame_desc[i].status != -EPROTO)
664 continue;
665 }
666 if (urb->iso_frame_desc[i].actual_length <= 0) {
667 em28xx_isocdbg("packet %d is empty",i);
668 continue;
669 }
670 if (urb->iso_frame_desc[i].actual_length >
671 dev->max_pkt_size) {
672 em28xx_isocdbg("packet bigger than packet size");
673 continue;
674 }
675 /*new frame */
676 if (buf[0] == 0x22 && buf[1] == 0x5a) {
677 em28xx_isocdbg("Video frame, length=%i!",len);
678
679 if (em28xx_isoc_video(dev,f,&lock_flags,buf[2]))
680 break;
681 } else if (buf[0]==0x33 && buf[1]==0x95 && buf[2]==0x00) {
682 em28xx_isocdbg("VBI HEADER!!!");
683 }
684
685 /* actual copying */
686 if ((*f)->state == F_GRABBING) {
687 em28xx_isoc_video_copy(dev,f,buf, len);
688 }
689 }
690 }
691
692 for (i = 0; i < urb->number_of_packets; i++) {
693 urb->iso_frame_desc[i].status = 0;
694 urb->iso_frame_desc[i].actual_length = 0;
695 }
696
697 urb->status = 0;
698 if ((status = usb_submit_urb(urb, GFP_ATOMIC))) {
699 em28xx_errdev("resubmit of urb failed (error=%i)\n", status);
700 dev->state |= DEV_MISCONFIGURED;
701 }
702 wake_up_interruptible(&dev->wait_frame);
703 return;
704}
705
706/*
707 * em28xx_uninit_isoc()
708 * deallocates the buffers and urbs allocated during em28xx_init_iosc()
709 */
710void em28xx_uninit_isoc(struct em28xx *dev)
711{
712 int i;
713
714 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
715 if (dev->urb[i]) {
716 usb_kill_urb(dev->urb[i]);
717 if (dev->transfer_buffer[i]){
718 usb_buffer_free(dev->udev,(EM28XX_NUM_PACKETS*dev->max_pkt_size),dev->transfer_buffer[i],dev->urb[i]->transfer_dma);
719 }
720 usb_free_urb(dev->urb[i]);
721 }
722 dev->urb[i] = NULL;
723 dev->transfer_buffer[i] = NULL;
724 }
725 em28xx_capture_start(dev, 0);
726}
727
728/*
729 * em28xx_init_isoc()
730 * allocates transfer buffers and submits the urbs for isoc transfer
731 */
732int em28xx_init_isoc(struct em28xx *dev)
733{
734 /* change interface to 3 which allowes the biggest packet sizes */
735 int i, errCode;
736 const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
737
738 /* reset streaming vars */
739 dev->frame_current = NULL;
740 dev->frame_count = 0;
741
742 /* allocate urbs */
743 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
744 struct urb *urb;
745 int j, k;
746 /* allocate transfer buffer */
747 urb = usb_alloc_urb(EM28XX_NUM_PACKETS, GFP_KERNEL);
748 if (!urb){
749 em28xx_errdev("cannot alloc urb %i\n", i);
750 em28xx_uninit_isoc(dev);
751 return -ENOMEM;
752 }
753 dev->transfer_buffer[i] = usb_buffer_alloc(dev->udev, sb_size, GFP_KERNEL,&urb->transfer_dma);
754 if (!dev->transfer_buffer[i]) {
755 em28xx_errdev
756 ("unable to allocate %i bytes for transfer buffer %i\n",
757 sb_size, i);
758 em28xx_uninit_isoc(dev);
759 return -ENOMEM;
760 }
761 memset(dev->transfer_buffer[i], 0, sb_size);
762 urb->dev = dev->udev;
763 urb->context = dev;
764 urb->pipe = usb_rcvisocpipe(dev->udev, 0x82);
765 urb->transfer_flags = URB_ISO_ASAP;
766 urb->interval = 1;
767 urb->transfer_buffer = dev->transfer_buffer[i];
768 urb->complete = em28xx_isocIrq;
769 urb->number_of_packets = EM28XX_NUM_PACKETS;
770 urb->transfer_buffer_length = sb_size;
771 for (j = k = 0; j < EM28XX_NUM_PACKETS;
772 j++, k += dev->max_pkt_size) {
773 urb->iso_frame_desc[j].offset = k;
774 urb->iso_frame_desc[j].length =
775 dev->max_pkt_size;
776 }
777 dev->urb[i] = urb;
778 }
779
780 /* submit urbs */
781 for (i = 0; i < EM28XX_NUM_BUFS; i++) {
782 errCode = usb_submit_urb(dev->urb[i], GFP_KERNEL);
783 if (errCode) {
784 em28xx_errdev("submit of urb %i failed (error=%i)\n", i,
785 errCode);
786 em28xx_uninit_isoc(dev);
787 return errCode;
788 }
789 }
790
791 return 0;
792}
793
794int em28xx_set_alternate(struct em28xx *dev)
795{
796 int errCode, prev_alt = dev->alt;
797 dev->alt = alt;
798 if (dev->alt == 0) {
799 int i;
800 for(i=0;i< dev->num_alt; i++)
801 if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
802 dev->alt=i;
803 }
804
805 if (dev->alt != prev_alt) {
806 dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt];
807 em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", dev->alt,
808 dev->max_pkt_size);
809 errCode = usb_set_interface(dev->udev, 0, dev->alt);
810 if (errCode < 0) {
811 em28xx_errdev ("cannot change alternate number to %d (error=%i)\n",
812 dev->alt, errCode);
813 return errCode;
814 }
815 }
816 return 0;
817}
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
new file mode 100644
index 000000000000..b32d9852f34c
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -0,0 +1,586 @@
1/*
2 em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/usb.h>
27#include <linux/i2c.h>
28#include <linux/video_decoder.h>
29
30#include "em28xx.h"
31#include <media/tuner.h>
32
33/* ----------------------------------------------------------- */
34
35static unsigned int i2c_scan = 0;
36module_param(i2c_scan, int, 0444);
37MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
38
39static unsigned int i2c_debug = 0;
40module_param(i2c_debug, int, 0644);
41MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
42
43#define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\
44 printk(fmt , ##args); } while (0)
45#define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
46 printk(KERN_DEBUG "%s at %s: " fmt, \
47 dev->name, __FUNCTION__ , ##args); } while (0)
48
49/*
50 * em2800_i2c_send_max4()
51 * send up to 4 bytes to the i2c device
52 */
53static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr,
54 char *buf, int len)
55{
56 int ret;
57 int write_timeout;
58 unsigned char b2[6];
59 BUG_ON(len < 1 || len > 4);
60 b2[5] = 0x80 + len - 1;
61 b2[4] = addr;
62 b2[3] = buf[0];
63 if (len > 1)
64 b2[2] = buf[1];
65 if (len > 2)
66 b2[1] = buf[2];
67 if (len > 3)
68 b2[0] = buf[3];
69
70 ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
71 if (ret != 2 + len) {
72 em28xx_warn("writting to i2c device failed (error=%i)\n", ret);
73 return -EIO;
74 }
75 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
76 write_timeout -= 5) {
77 ret = dev->em28xx_read_reg(dev, 0x05);
78 if (ret == 0x80 + len - 1)
79 return len;
80 mdelay(5);
81 }
82 em28xx_warn("i2c write timed out\n");
83 return -EIO;
84}
85
86/*
87 * em2800_i2c_send_bytes()
88 */
89static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf,
90 short len)
91{
92 char *bufPtr = buf;
93 int ret;
94 int wrcount = 0;
95 int count;
96 int maxLen = 4;
97 struct em28xx *dev = (struct em28xx *)data;
98 while (len > 0) {
99 count = (len > maxLen) ? maxLen : len;
100 ret = em2800_i2c_send_max4(dev, addr, bufPtr, count);
101 if (ret > 0) {
102 len -= count;
103 bufPtr += count;
104 wrcount += count;
105 } else
106 return (ret < 0) ? ret : -EFAULT;
107 }
108 return wrcount;
109}
110
111/*
112 * em2800_i2c_check_for_device()
113 * check if there is a i2c_device at the supplied address
114 */
115static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
116{
117 char msg;
118 int ret;
119 int write_timeout;
120 msg = addr;
121 ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1);
122 if (ret < 0) {
123 em28xx_warn("setting i2c device address failed (error=%i)\n",
124 ret);
125 return ret;
126 }
127 msg = 0x84;
128 ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1);
129 if (ret < 0) {
130 em28xx_warn("preparing i2c read failed (error=%i)\n", ret);
131 return ret;
132 }
133 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
134 write_timeout -= 5) {
135 unsigned msg = dev->em28xx_read_reg(dev, 0x5);
136 if (msg == 0x94)
137 return -ENODEV;
138 else if (msg == 0x84)
139 return 0;
140 mdelay(5);
141 }
142 return -ENODEV;
143}
144
145/*
146 * em2800_i2c_recv_bytes()
147 * read from the i2c device
148 */
149static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
150 char *buf, int len)
151{
152 int ret;
153 /* check for the device and set i2c read address */
154 ret = em2800_i2c_check_for_device(dev, addr);
155 if (ret) {
156 em28xx_warn
157 ("preparing read at i2c address 0x%x failed (error=%i)\n",
158 addr, ret);
159 return ret;
160 }
161 ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len);
162 if (ret < 0) {
163 em28xx_warn("reading from i2c device at 0x%x failed (error=%i)",
164 addr, ret);
165 return ret;
166 }
167 return ret;
168}
169
170/*
171 * em28xx_i2c_send_bytes()
172 * untested for more than 4 bytes
173 */
174static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf,
175 short len, int stop)
176{
177 int wrcount = 0;
178 struct em28xx *dev = (struct em28xx *)data;
179
180 wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len);
181
182 return wrcount;
183}
184
185/*
186 * em28xx_i2c_recv_bytes()
187 * read a byte from the i2c device
188 */
189static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr,
190 char *buf, int len)
191{
192 int ret;
193 ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len);
194 if (ret < 0) {
195 em28xx_warn("reading i2c device failed (error=%i)\n", ret);
196 return ret;
197 }
198 if (dev->em28xx_read_reg(dev, 0x5) != 0)
199 return -ENODEV;
200 return ret;
201}
202
203/*
204 * em28xx_i2c_check_for_device()
205 * check if there is a i2c_device at the supplied address
206 */
207static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr)
208{
209 char msg;
210 int ret;
211 msg = addr;
212
213 ret = dev->em28xx_read_reg_req(dev, 2, addr);
214 if (ret < 0) {
215 em28xx_warn("reading from i2c device failed (error=%i)\n", ret);
216 return ret;
217 }
218 if (dev->em28xx_read_reg(dev, 0x5) != 0)
219 return -ENODEV;
220 return 0;
221}
222
223/*
224 * em28xx_i2c_xfer()
225 * the main i2c transfer function
226 */
227static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap,
228 struct i2c_msg msgs[], int num)
229{
230 struct em28xx *dev = i2c_adap->algo_data;
231 int addr, rc, i, byte;
232
233 if (num <= 0)
234 return 0;
235 for (i = 0; i < num; i++) {
236 addr = msgs[i].addr << 1;
237 dprintk2(2,"%s %s addr=%x len=%d:",
238 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
239 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
240 if (!msgs[i].len) { /* no len: check only for device presence */
241 if (dev->is_em2800)
242 rc = em2800_i2c_check_for_device(dev, addr);
243 else
244 rc = em28xx_i2c_check_for_device(dev, addr);
245 if (rc < 0) {
246 dprintk2(2," no device\n");
247 return rc;
248 }
249
250 } else if (msgs[i].flags & I2C_M_RD) {
251 /* read bytes */
252 if (dev->is_em2800)
253 rc = em2800_i2c_recv_bytes(dev, addr,
254 msgs[i].buf,
255 msgs[i].len);
256 else
257 rc = em28xx_i2c_recv_bytes(dev, addr,
258 msgs[i].buf,
259 msgs[i].len);
260 if (i2c_debug>=2) {
261 for (byte = 0; byte < msgs[i].len; byte++) {
262 printk(" %02x", msgs[i].buf[byte]);
263 }
264 }
265 } else {
266 /* write bytes */
267 if (i2c_debug>=2) {
268 for (byte = 0; byte < msgs[i].len; byte++)
269 printk(" %02x", msgs[i].buf[byte]);
270 }
271 if (dev->is_em2800)
272 rc = em2800_i2c_send_bytes(dev, addr,
273 msgs[i].buf,
274 msgs[i].len);
275 else
276 rc = em28xx_i2c_send_bytes(dev, addr,
277 msgs[i].buf,
278 msgs[i].len,
279 i == num - 1);
280 if (rc < 0)
281 goto err;
282 }
283 if (i2c_debug>=2)
284 printk("\n");
285 }
286
287 return num;
288 err:
289 dprintk2(2," ERROR: %i\n", rc);
290 return rc;
291}
292
293static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
294{
295 unsigned char buf, *p = eedata;
296 struct em28xx_eeprom *em_eeprom = (void *)eedata;
297 int i, err, size = len, block;
298
299 dev->i2c_client.addr = 0xa0 >> 1;
300
301 /* Check if board has eeprom */
302 err = i2c_master_recv(&dev->i2c_client, &buf, 0);
303 if (err < 0)
304 return -1;
305
306 buf = 0;
307 if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) {
308 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
309 dev->name, err);
310 return -1;
311 }
312 while (size > 0) {
313 if (size > 16)
314 block = 16;
315 else
316 block = size;
317
318 if (block !=
319 (err = i2c_master_recv(&dev->i2c_client, p, block))) {
320 printk(KERN_WARNING
321 "%s: i2c eeprom read error (err=%d)\n",
322 dev->name, err);
323 return -1;
324 }
325 size -= block;
326 p += block;
327 }
328 for (i = 0; i < len; i++) {
329 if (0 == (i % 16))
330 printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
331 printk(" %02x", eedata[i]);
332 if (15 == (i % 16))
333 printk("\n");
334 }
335
336 printk(KERN_INFO "EEPROM ID= 0x%08x\n", em_eeprom->id);
337 printk(KERN_INFO "Vendor/Product ID= %04x:%04x\n", em_eeprom->vendor_ID,
338 em_eeprom->product_ID);
339
340 switch (em_eeprom->chip_conf >> 4 & 0x3) {
341 case 0:
342 printk(KERN_INFO "No audio on board.\n");
343 break;
344 case 1:
345 printk(KERN_INFO "AC97 audio (5 sample rates)\n");
346 break;
347 case 2:
348 printk(KERN_INFO "I2S audio, sample rate=32k\n");
349 break;
350 case 3:
351 printk(KERN_INFO "I2S audio, 3 sample rates\n");
352 break;
353 }
354
355 if (em_eeprom->chip_conf & 1 << 3)
356 printk(KERN_INFO "USB Remote wakeup capable\n");
357
358 if (em_eeprom->chip_conf & 1 << 2)
359 printk(KERN_INFO "USB Self power capable\n");
360
361 switch (em_eeprom->chip_conf & 0x3) {
362 case 0:
363 printk(KERN_INFO "500mA max power\n");
364 break;
365 case 1:
366 printk(KERN_INFO "400mA max power\n");
367 break;
368 case 2:
369 printk(KERN_INFO "300mA max power\n");
370 break;
371 case 3:
372 printk(KERN_INFO "200mA max power\n");
373 break;
374 }
375 printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n",
376 em_eeprom->string_idx_table,em_eeprom->string1,
377 em_eeprom->string2,em_eeprom->string3);
378
379 return 0;
380}
381
382/* ----------------------------------------------------------- */
383
384/*
385 * algo_control()
386 */
387static int algo_control(struct i2c_adapter *adapter,
388 unsigned int cmd, unsigned long arg)
389{
390 return 0;
391}
392
393/*
394 * functionality()
395 */
396static u32 functionality(struct i2c_adapter *adap)
397{
398 return I2C_FUNC_SMBUS_EMUL;
399}
400
401#ifndef I2C_PEC
402static void inc_use(struct i2c_adapter *adap)
403{
404 MOD_INC_USE_COUNT;
405}
406
407static void dec_use(struct i2c_adapter *adap)
408{
409 MOD_DEC_USE_COUNT;
410}
411#endif
412
413static int em28xx_set_tuner(int check_eeprom, struct i2c_client *client)
414{
415 struct em28xx *dev = client->adapter->algo_data;
416 struct tuner_setup tun_setup;
417
418 if (dev->has_tuner) {
419 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
420 tun_setup.type = dev->tuner_type;
421 tun_setup.addr = dev->tuner_addr;
422
423 em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
424 }
425
426 return (0);
427}
428
429/*
430 * attach_inform()
431 * gets called when a device attaches to the i2c bus
432 * does some basic configuration
433 */
434static int attach_inform(struct i2c_client *client)
435{
436 struct em28xx *dev = client->adapter->algo_data;
437
438 switch (client->addr << 1) {
439 case 0x86:
440 em28xx_i2c_call_clients(dev, TDA9887_SET_CONFIG, &dev->tda9887_conf);
441 break;
442 case 0x42:
443 dprintk1(1,"attach_inform: saa7114 detected.\n");
444 break;
445 case 0x4a:
446 dprintk1(1,"attach_inform: saa7113 detected.\n");
447 break;
448 case 0xa0:
449 dprintk1(1,"attach_inform: eeprom detected.\n");
450 break;
451 case 0x60:
452 case 0x8e:
453 {
454 struct IR_i2c *ir = i2c_get_clientdata(client);
455 dprintk1(1,"attach_inform: IR detected (%s).\n",ir->phys);
456 em28xx_set_ir(dev,ir);
457 break;
458 }
459 case 0x80:
460 case 0x88:
461 dprintk1(1,"attach_inform: msp34xx detected.\n");
462 break;
463 case 0xb8:
464 case 0xba:
465 dprintk1(1,"attach_inform: tvp5150 detected.\n");
466 break;
467 default:
468 dprintk1(1,"attach inform: detected I2C address %x\n", client->addr << 1);
469 dev->tuner_addr = client->addr;
470 em28xx_set_tuner(-1, client);
471 }
472
473 return 0;
474}
475
476static struct i2c_algorithm em28xx_algo = {
477 .master_xfer = em28xx_i2c_xfer,
478 .algo_control = algo_control,
479 .functionality = functionality,
480};
481
482static struct i2c_adapter em28xx_adap_template = {
483#ifdef I2C_PEC
484 .owner = THIS_MODULE,
485#else
486 .inc_use = inc_use,
487 .dec_use = dec_use,
488#endif
489#ifdef I2C_CLASS_TV_ANALOG
490 .class = I2C_CLASS_TV_ANALOG,
491#endif
492 .name = "em28xx",
493 .id = I2C_HW_B_EM28XX,
494 .algo = &em28xx_algo,
495 .client_register = attach_inform,
496};
497
498static struct i2c_client em28xx_client_template = {
499 .name = "em28xx internal",
500 .flags = I2C_CLIENT_ALLOW_USE,
501};
502
503/* ----------------------------------------------------------- */
504
505/*
506 * i2c_devs
507 * incomplete list of known devices
508 */
509static char *i2c_devs[128] = {
510 [0x4a >> 1] = "saa7113h",
511 [0x60 >> 1] = "remote IR sensor",
512 [0x8e >> 1] = "remote IR sensor",
513 [0x86 >> 1] = "tda9887",
514 [0x80 >> 1] = "msp34xx",
515 [0x88 >> 1] = "msp34xx",
516 [0xa0 >> 1] = "eeprom",
517 [0xb8 >> 1] = "tvp5150a",
518 [0xba >> 1] = "tvp5150a",
519 [0xc0 >> 1] = "tuner (analog)",
520 [0xc2 >> 1] = "tuner (analog)",
521 [0xc4 >> 1] = "tuner (analog)",
522 [0xc6 >> 1] = "tuner (analog)",
523};
524
525/*
526 * do_i2c_scan()
527 * check i2c address range for devices
528 */
529static void do_i2c_scan(char *name, struct i2c_client *c)
530{
531 unsigned char buf;
532 int i, rc;
533
534 for (i = 0; i < 128; i++) {
535 c->addr = i;
536 rc = i2c_master_recv(c, &buf, 0);
537 if (rc < 0)
538 continue;
539 printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name,
540 i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
541 }
542}
543
544/*
545 * em28xx_i2c_call_clients()
546 * send commands to all attached i2c devices
547 */
548void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg)
549{
550 BUG_ON(NULL == dev->i2c_adap.algo_data);
551 i2c_clients_command(&dev->i2c_adap, cmd, arg);
552}
553
554/*
555 * em28xx_i2c_register()
556 * register i2c bus
557 */
558int em28xx_i2c_register(struct em28xx *dev)
559{
560 BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg);
561 BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req);
562 dev->i2c_adap = em28xx_adap_template;
563 dev->i2c_adap.dev.parent = &dev->udev->dev;
564 strcpy(dev->i2c_adap.name, dev->name);
565 dev->i2c_adap.algo_data = dev;
566 i2c_add_adapter(&dev->i2c_adap);
567
568 dev->i2c_client = em28xx_client_template;
569 dev->i2c_client.adapter = &dev->i2c_adap;
570
571 em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));
572
573 if (i2c_scan)
574 do_i2c_scan(dev->name, &dev->i2c_client);
575 return 0;
576}
577
578/*
579 * em28xx_i2c_unregister()
580 * unregister i2c_bus
581 */
582int em28xx_i2c_unregister(struct em28xx *dev)
583{
584 i2c_del_adapter(&dev->i2c_adap);
585 return 0;
586}
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
new file mode 100644
index 000000000000..32c49df58adc
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -0,0 +1,184 @@
1/*
2 handle em28xx IR remotes via linux kernel input layer.
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/sched.h>
29#include <linux/interrupt.h>
30#include <linux/input.h>
31#include <linux/usb.h>
32
33#include "em28xx.h"
34
35static unsigned int disable_ir = 0;
36module_param(disable_ir, int, 0444);
37MODULE_PARM_DESC(disable_ir,"disable infrared remote support");
38
39static unsigned int ir_debug = 0;
40module_param(ir_debug, int, 0644);
41MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
42
43#define dprintk(fmt, arg...) if (ir_debug) \
44 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
45
46/* ---------------------------------------------------------------------- */
47
48static IR_KEYTAB_TYPE ir_codes_em_terratec[IR_KEYTAB_SIZE] = {
49 [ 0x01 ] = KEY_CHANNEL,
50 [ 0x02 ] = KEY_SELECT,
51 [ 0x03 ] = KEY_MUTE,
52 [ 0x04 ] = KEY_POWER,
53 [ 0x05 ] = KEY_KP1,
54 [ 0x06 ] = KEY_KP2,
55 [ 0x07 ] = KEY_KP3,
56 [ 0x08 ] = KEY_CHANNELUP,
57 [ 0x09 ] = KEY_KP4,
58 [ 0x0a ] = KEY_KP5,
59 [ 0x0b ] = KEY_KP6,
60 [ 0x0c ] = KEY_CHANNELDOWN,
61 [ 0x0d ] = KEY_KP7,
62 [ 0x0e ] = KEY_KP8,
63 [ 0x0f ] = KEY_KP9,
64 [ 0x10 ] = KEY_VOLUMEUP,
65 [ 0x11 ] = KEY_KP0,
66 [ 0x12 ] = KEY_MENU,
67 [ 0x13 ] = KEY_PRINT,
68 [ 0x14 ] = KEY_VOLUMEDOWN,
69 [ 0x16 ] = KEY_PAUSE,
70 [ 0x18 ] = KEY_RECORD,
71 [ 0x19 ] = KEY_REWIND,
72 [ 0x1a ] = KEY_PLAY,
73 [ 0x1b ] = KEY_FORWARD,
74 [ 0x1c ] = KEY_BACKSPACE,
75 [ 0x1e ] = KEY_STOP,
76 [ 0x40 ] = KEY_ZOOM,
77};
78
79/* ----------------------------------------------------------------------- */
80
81static int get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
82{
83 unsigned char b;
84
85 /* poll IR chip */
86 if (1 != i2c_master_recv(&ir->c,&b,1)) {
87 dprintk("read error\n");
88 return -EIO;
89 }
90
91 /* it seems that 0xFE indicates that a button is still hold
92 down, while 0xff indicates that no button is hold
93 down. 0xfe sequences are sometimes interrupted by 0xFF */
94
95 dprintk("key %02x\n", b);
96
97 if (b == 0xff)
98 return 0;
99
100 if (b == 0xfe)
101 /* keep old data */
102 return 1;
103
104 *ir_key = b;
105 *ir_raw = b;
106 return 1;
107}
108
109
110static int get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
111{
112 unsigned char buf[2];
113 unsigned char code;
114
115 /* poll IR chip */
116 if (2 != i2c_master_recv(&ir->c,buf,2))
117 return -EIO;
118
119 /* Does eliminate repeated parity code */
120 if (buf[1]==0xff)
121 return 0;
122
123 /* avoid fast reapeating */
124 if (buf[1]==ir->old)
125 return 0;
126 ir->old=buf[1];
127
128 /* Rearranges bits to the right order */
129 code= ((buf[0]&0x01)<<5) | /* 0010 0000 */
130 ((buf[0]&0x02)<<3) | /* 0001 0000 */
131 ((buf[0]&0x04)<<1) | /* 0000 1000 */
132 ((buf[0]&0x08)>>1) | /* 0000 0100 */
133 ((buf[0]&0x10)>>3) | /* 0000 0010 */
134 ((buf[0]&0x20)>>5); /* 0000 0001 */
135
136 dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n",code,buf[0]);
137
138 /* return key */
139 *ir_key = code;
140 *ir_raw = code;
141 return 1;
142}
143
144/* ----------------------------------------------------------------------- */
145void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir)
146{
147 if (disable_ir) {
148 ir->get_key=NULL;
149 return ;
150 }
151
152 /* detect & configure */
153 switch (dev->model) {
154 case (EM2800_BOARD_UNKNOWN):
155 break;
156 case (EM2820_BOARD_UNKNOWN):
157 break;
158 case (EM2800_BOARD_TERRATEC_CINERGY_200):
159 case (EM2820_BOARD_TERRATEC_CINERGY_250):
160 ir->ir_codes = ir_codes_em_terratec;
161 ir->get_key = get_key_terratec;
162 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM28XX Terratec)");
163 break;
164 case (EM2820_BOARD_PINNACLE_USB_2):
165 break;
166 case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
167 ir->ir_codes = ir_codes_hauppauge_new;
168 ir->get_key = get_key_em_haup;
169 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (EM2840 Hauppauge)");
170 break;
171 case (EM2820_BOARD_MSI_VOX_USB_2):
172 break;
173 case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
174 break;
175 case (EM2800_BOARD_KWORLD_USB2800):
176 break;
177 }
178}
179
180/* ----------------------------------------------------------------------
181 * Local variables:
182 * c-basic-offset: 8
183 * End:
184 */
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
new file mode 100644
index 000000000000..57c1826b928e
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -0,0 +1,1933 @@
1/*
2 em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
5 Markus Rechberger <mrechberger@gmail.com>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7 Sascha Sommer <saschasommer@freenet.de>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/usb.h>
29#include <linux/i2c.h>
30#include <linux/version.h>
31#include <linux/video_decoder.h>
32
33#include "em28xx.h"
34#include <media/tuner.h>
35
36#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
37 "Markus Rechberger <mrechberger@gmail.com>, " \
38 "Mauro Carvalho Chehab <mchehab@brturbo.com.br>, " \
39 "Sascha Sommer <saschasommer@freenet.de>"
40
41#define DRIVER_NAME "em28xx"
42#define DRIVER_DESC "Empia em28xx based USB video device driver"
43#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 0, 1)
44
45#define em28xx_videodbg(fmt, arg...) do {\
46 if (video_debug) \
47 printk(KERN_INFO "%s %s :"fmt, \
48 dev->name, __FUNCTION__ , ##arg); } while (0)
49
50MODULE_AUTHOR(DRIVER_AUTHOR);
51MODULE_DESCRIPTION(DRIVER_DESC);
52MODULE_LICENSE("GPL");
53
54static LIST_HEAD(em28xx_devlist);
55
56static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
57module_param_array(card, int, NULL, 0444);
58MODULE_PARM_DESC(card,"card type");
59
60static int tuner = -1;
61module_param(tuner, int, 0444);
62MODULE_PARM_DESC(tuner, "tuner type");
63
64static unsigned int video_debug = 0;
65module_param(video_debug,int,0644);
66MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
67
68/* supported tv norms */
69static struct em28xx_tvnorm tvnorms[] = {
70 {
71 .name = "PAL",
72 .id = V4L2_STD_PAL,
73 .mode = VIDEO_MODE_PAL,
74 }, {
75 .name = "NTSC",
76 .id = V4L2_STD_NTSC,
77 .mode = VIDEO_MODE_NTSC,
78 }, {
79 .name = "SECAM",
80 .id = V4L2_STD_SECAM,
81 .mode = VIDEO_MODE_SECAM,
82 }, {
83 .name = "PAL-M",
84 .id = V4L2_STD_PAL_M,
85 .mode = VIDEO_MODE_PAL,
86 }
87};
88
89static const unsigned char saa7114_i2c_init[] = {
90 0x00,0x00,0x01,0x08,0x02,0xc4,0x03,0x30,0x04,0x90,0x05,0x90,0x06,0xeb,0x07,0xe0,
91 0x08,0x88,0x09,0x40,0x0a,0x80,0x0b,0x44,0x0c,0x40,0x0d,0x00,0x0e,0x81,0x0f,0x2a,
92 0x10,0x06,0x11,0x00,0x12,0xc8,0x13,0x80,0x14,0x00,0x15,0x11,0x16,0x01,0x17,0x42,
93 0x18,0x40,0x19,0x80,0x40,0x00,0x41,0xff,0x42,0xff,0x43,0xff,0x44,0xff,0x45,0xff,
94 0x46,0xff,0x47,0xff,0x48,0xff,0x49,0xff,0x4a,0xff,0x4b,0xff,0x4c,0xff,0x4d,0xff,
95 0x4e,0xff,0x4f,0xff,0x50,0xff,0x51,0xff,0x52,0xff,0x53,0xff,0x54,0x5f,0x55,0xff,
96 0x56,0xff,0x57,0xff,0x58,0x00,0x59,0x47,0x5a,0x03,0x5b,0x03,0x5d,0x3e,0x5e,0x00,
97 0x80,0x1c,0x83,0x01,0x84,0xa5,0x85,0x10,0x86,0x45,0x87,0x41,0x88,0xf0,0x88,0x00,
98 0x88,0xf0,0x90,0x00,0x91,0x08,0x92,0x00,0x93,0x80,0x94,0x08,0x95,0x00,0x96,0xc0,
99 0x97,0x02,0x98,0x13,0x99,0x00,0x9a,0x38,0x9b,0x01,0x9c,0x80,0x9d,0x02,0x9e,0x06,
100 0x9f,0x01,0xa0,0x01,0xa1,0x00,0xa2,0x00,0xa4,0x80,0xa5,0x36,0xa6,0x36,0xa8,0x67,
101 0xa9,0x04,0xaa,0x00,0xac,0x33,0xad,0x02,0xae,0x00,0xb0,0xcd,0xb1,0x04,0xb2,0xcd,
102 0xb3,0x04,0xb4,0x01,0xb8,0x00,0xb9,0x00,0xba,0x00,0xbb,0x00,0xbc,0x00,0xbd,0x00,
103 0xbe,0x00,0xbf,0x00
104};
105
106#define TVNORMS ARRAY_SIZE(tvnorms)
107
108/* supported controls */
109static struct v4l2_queryctrl em28xx_qctrl[] = {
110 {
111 .id = V4L2_CID_BRIGHTNESS,
112 .type = V4L2_CTRL_TYPE_INTEGER,
113 .name = "Brightness",
114 .minimum = -128,
115 .maximum = 127,
116 .step = 1,
117 .default_value = 0,
118 .flags = 0,
119 },{
120 .id = V4L2_CID_CONTRAST,
121 .type = V4L2_CTRL_TYPE_INTEGER,
122 .name = "Contrast",
123 .minimum = 0x0,
124 .maximum = 0x1f,
125 .step = 0x1,
126 .default_value = 0x10,
127 .flags = 0,
128 },{
129 .id = V4L2_CID_SATURATION,
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "Saturation",
132 .minimum = 0x0,
133 .maximum = 0x1f,
134 .step = 0x1,
135 .default_value = 0x10,
136 .flags = 0,
137 },{
138 .id = V4L2_CID_AUDIO_VOLUME,
139 .type = V4L2_CTRL_TYPE_INTEGER,
140 .name = "Volume",
141 .minimum = 0x0,
142 .maximum = 0x1f,
143 .step = 0x1,
144 .default_value = 0x1f,
145 .flags = 0,
146 },{
147 .id = V4L2_CID_AUDIO_MUTE,
148 .type = V4L2_CTRL_TYPE_BOOLEAN,
149 .name = "Mute",
150 .minimum = 0,
151 .maximum = 1,
152 .step = 1,
153 .default_value = 1,
154 .flags = 0,
155 },{
156 .id = V4L2_CID_RED_BALANCE,
157 .type = V4L2_CTRL_TYPE_INTEGER,
158 .name = "Red chroma balance",
159 .minimum = -128,
160 .maximum = 127,
161 .step = 1,
162 .default_value = 0,
163 .flags = 0,
164 },{
165 .id = V4L2_CID_BLUE_BALANCE,
166 .type = V4L2_CTRL_TYPE_INTEGER,
167 .name = "Blue chroma balance",
168 .minimum = -128,
169 .maximum = 127,
170 .step = 1,
171 .default_value = 0,
172 .flags = 0,
173 },{
174 .id = V4L2_CID_GAMMA,
175 .type = V4L2_CTRL_TYPE_INTEGER,
176 .name = "Gamma",
177 .minimum = 0x0,
178 .maximum = 0x3f,
179 .step = 0x1,
180 .default_value = 0x20,
181 .flags = 0,
182 }
183};
184
185static struct usb_driver em28xx_usb_driver;
186
187static DECLARE_MUTEX(em28xx_sysfs_lock);
188static DECLARE_RWSEM(em28xx_disconnect);
189
190/********************* v4l2 interface ******************************************/
191
192static inline unsigned long kvirt_to_pa(unsigned long adr)
193{
194 unsigned long kva, ret;
195
196 kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
197 kva |= adr & (PAGE_SIZE - 1);
198 ret = __pa(kva);
199 return ret;
200}
201
202/*
203 * em28xx_config()
204 * inits registers with sane defaults
205 */
206static int em28xx_config(struct em28xx *dev)
207{
208
209 /* Sets I2C speed to 100 KHz */
210 em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1);
211
212 /* enable vbi capturing */
213 em28xx_audio_usb_mute(dev, 1);
214 dev->mute = 1; /* maybe not the right place... */
215 dev->volume = 0x1f;
216 em28xx_audio_analog_set(dev);
217 em28xx_audio_analog_setup(dev);
218 em28xx_outfmt_set_yuv422(dev);
219 em28xx_colorlevels_set_default(dev);
220 em28xx_compression_disable(dev);
221
222 return 0;
223}
224
225/*
226 * em28xx_config_i2c()
227 * configure i2c attached devices
228 */
229void em28xx_config_i2c(struct em28xx *dev)
230{
231 struct v4l2_frequency f;
232 struct video_decoder_init em28xx_vdi = {.data = NULL };
233
234
235 /* configure decoder */
236 if(dev->model == EM2820_BOARD_MSI_VOX_USB_2){
237 em28xx_vdi.data=saa7114_i2c_init;
238 em28xx_vdi.len=sizeof(saa7114_i2c_init);
239 }
240
241
242 em28xx_i2c_call_clients(dev, DECODER_INIT, &em28xx_vdi);
243 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &dev->ctl_input);
244/* em28xx_i2c_call_clients(dev,DECODER_SET_PICTURE, &dev->vpic); */
245/* em28xx_i2c_call_clients(dev,DECODER_SET_NORM,&dev->tvnorm->id); */
246/* em28xx_i2c_call_clients(dev,DECODER_ENABLE_OUTPUT,&output); */
247/* em28xx_i2c_call_clients(dev,DECODER_DUMP, NULL); */
248
249 /* configure tuner */
250 f.tuner = 0;
251 f.type = V4L2_TUNER_ANALOG_TV;
252 f.frequency = 9076; /* FIXME:remove magic number */
253 dev->ctl_freq = f.frequency;
254 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
255
256 /* configure tda9887 */
257
258
259/* em28xx_i2c_call_clients(dev,VIDIOC_S_STD,&dev->tvnorm->id); */
260}
261
262/*
263 * em28xx_empty_framequeues()
264 * prepare queues for incoming and outgoing frames
265 */
266static void em28xx_empty_framequeues(struct em28xx *dev)
267{
268 u32 i;
269
270 INIT_LIST_HEAD(&dev->inqueue);
271 INIT_LIST_HEAD(&dev->outqueue);
272
273 for (i = 0; i < EM28XX_NUM_FRAMES; i++) {
274 dev->frame[i].state = F_UNUSED;
275 dev->frame[i].buf.bytesused = 0;
276 }
277}
278
279static void video_mux(struct em28xx *dev, int index)
280{
281 int input, ainput;
282
283 input = INPUT(index)->vmux;
284 dev->ctl_input = index;
285 dev->ctl_ainput = INPUT(index)->amux;
286
287 em28xx_i2c_call_clients(dev, DECODER_SET_INPUT, &input);
288
289
290 em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput);
291
292 if (dev->has_msp34xx) {
293 em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput);
294 ainput = EM28XX_AUDIO_SRC_TUNER;
295 em28xx_audio_source(dev, ainput);
296 } else {
297 switch (dev->ctl_ainput) {
298 case 0:
299 ainput = EM28XX_AUDIO_SRC_TUNER;
300 break;
301 default:
302 ainput = EM28XX_AUDIO_SRC_LINE;
303 }
304 em28xx_audio_source(dev, ainput);
305 }
306}
307
308/*
309 * em28xx_v4l2_open()
310 * inits the device and starts isoc transfer
311 */
312static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
313{
314 int minor = iminor(inode);
315 int errCode = 0;
316 struct em28xx *h,*dev = NULL;
317 struct list_head *list;
318
319 list_for_each(list,&em28xx_devlist) {
320 h = list_entry(list, struct em28xx, devlist);
321 if (h->vdev->minor == minor) {
322 dev = h;
323 }
324 }
325
326 filp->private_data=dev;
327
328
329 em28xx_videodbg("users=%d\n", dev->users);
330
331 if (!down_read_trylock(&em28xx_disconnect))
332 return -ERESTARTSYS;
333
334 if (dev->users) {
335 em28xx_warn("this driver can be opened only once\n");
336 up_read(&em28xx_disconnect);
337 return -EBUSY;
338 }
339
340/* if(dev->vbi_dev->minor == minor){
341 dev->type=V4L2_BUF_TYPE_VBI_CAPTURE;
342 }*/
343 if (dev->vdev->minor == minor) {
344 dev->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
345 }
346
347 init_MUTEX(&dev->fileop_lock); /* to 1 == available */
348 spin_lock_init(&dev->queue_lock);
349 init_waitqueue_head(&dev->wait_frame);
350 init_waitqueue_head(&dev->wait_stream);
351
352 down(&dev->lock);
353
354 em28xx_set_alternate(dev);
355
356 dev->width = norm_maxw(dev);
357 dev->height = norm_maxh(dev);
358 dev->frame_size = dev->width * dev->height * 2;
359 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
360 dev->bytesperline = dev->width * 2;
361 dev->hscale = 0;
362 dev->vscale = 0;
363
364 em28xx_capture_start(dev, 1);
365 em28xx_resolution_set(dev);
366
367 /* start the transfer */
368 errCode = em28xx_init_isoc(dev);
369 if (errCode)
370 goto err;
371
372 dev->users++;
373 filp->private_data = dev;
374 dev->io = IO_NONE;
375 dev->stream = STREAM_OFF;
376 dev->num_frames = 0;
377
378 /* prepare queues */
379 em28xx_empty_framequeues(dev);
380
381 dev->state |= DEV_INITIALIZED;
382
383 video_mux(dev, 0);
384
385 err:
386 up(&dev->lock);
387 up_read(&em28xx_disconnect);
388 return errCode;
389}
390
391/*
392 * em28xx_realease_resources()
393 * unregisters the v4l2,i2c and usb devices
394 * called when the device gets disconected or at module unload
395*/
396static void em28xx_release_resources(struct em28xx *dev)
397{
398 down(&em28xx_sysfs_lock);
399
400 em28xx_info("V4L2 device /dev/video%d deregistered\n",
401 dev->vdev->minor);
402 list_del(&dev->devlist);
403 video_unregister_device(dev->vdev);
404/* video_unregister_device(dev->vbi_dev); */
405 em28xx_i2c_unregister(dev);
406 usb_put_dev(dev->udev);
407 up(&em28xx_sysfs_lock);
408}
409
410/*
411 * em28xx_v4l2_close()
412 * stops streaming and deallocates all resources allocated by the v4l2 calls and ioctls
413 */
414static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
415{
416 int errCode;
417 struct em28xx *dev=filp->private_data;
418
419 em28xx_videodbg("users=%d\n", dev->users);
420
421 down(&dev->lock);
422
423 em28xx_uninit_isoc(dev);
424
425 em28xx_release_buffers(dev);
426
427 /* the device is already disconnect, free the remaining resources */
428 if (dev->state & DEV_DISCONNECTED) {
429 em28xx_release_resources(dev);
430 up(&dev->lock);
431 kfree(dev);
432 return 0;
433 }
434
435 /* set alternate 0 */
436 dev->alt = 0;
437 em28xx_videodbg("setting alternate 0\n");
438 errCode = usb_set_interface(dev->udev, 0, 0);
439 if (errCode < 0) {
440 em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n",
441 errCode);
442 }
443
444 dev->users--;
445 wake_up_interruptible_nr(&dev->open, 1);
446 up(&dev->lock);
447 return 0;
448}
449
450/*
451 * em28xx_v4l2_read()
452 * will allocate buffers when called for the first time
453 */
454static ssize_t
455em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
456 loff_t * f_pos)
457{
458 struct em28xx_frame_t *f, *i;
459 unsigned long lock_flags;
460 int ret = 0;
461 struct em28xx *dev = filp->private_data;
462
463 if (down_interruptible(&dev->fileop_lock))
464 return -ERESTARTSYS;
465
466 if (dev->state & DEV_DISCONNECTED) {
467 em28xx_videodbg("device not present\n");
468 up(&dev->fileop_lock);
469 return -ENODEV;
470 }
471
472 if (dev->state & DEV_MISCONFIGURED) {
473 em28xx_videodbg("device misconfigured; close and open it again\n");
474 up(&dev->fileop_lock);
475 return -EIO;
476 }
477
478 if (dev->io == IO_MMAP) {
479 em28xx_videodbg ("IO method is set to mmap; close and open"
480 " the device again to choose the read method\n");
481 up(&dev->fileop_lock);
482 return -EINVAL;
483 }
484
485 if (dev->io == IO_NONE) {
486 if (!em28xx_request_buffers(dev, EM28XX_NUM_READ_FRAMES)) {
487 em28xx_errdev("read failed, not enough memory\n");
488 up(&dev->fileop_lock);
489 return -ENOMEM;
490 }
491 dev->io = IO_READ;
492 dev->stream = STREAM_ON;
493 em28xx_queue_unusedframes(dev);
494 }
495
496 if (!count) {
497 up(&dev->fileop_lock);
498 return 0;
499 }
500
501 if (list_empty(&dev->outqueue)) {
502 if (filp->f_flags & O_NONBLOCK) {
503 up(&dev->fileop_lock);
504 return -EAGAIN;
505 }
506 ret = wait_event_interruptible
507 (dev->wait_frame,
508 (!list_empty(&dev->outqueue)) ||
509 (dev->state & DEV_DISCONNECTED));
510 if (ret) {
511 up(&dev->fileop_lock);
512 return ret;
513 }
514 if (dev->state & DEV_DISCONNECTED) {
515 up(&dev->fileop_lock);
516 return -ENODEV;
517 }
518 }
519
520 f = list_entry(dev->outqueue.prev, struct em28xx_frame_t, frame);
521
522 spin_lock_irqsave(&dev->queue_lock, lock_flags);
523 list_for_each_entry(i, &dev->outqueue, frame)
524 i->state = F_UNUSED;
525 INIT_LIST_HEAD(&dev->outqueue);
526 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
527
528 em28xx_queue_unusedframes(dev);
529
530 if (count > f->buf.length)
531 count = f->buf.length;
532
533 if (copy_to_user(buf, f->bufmem, count)) {
534 up(&dev->fileop_lock);
535 return -EFAULT;
536 }
537 *f_pos += count;
538
539 up(&dev->fileop_lock);
540
541 return count;
542}
543
544/*
545 * em28xx_v4l2_poll()
546 * will allocate buffers when called for the first time
547 */
548static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
549{
550 unsigned int mask = 0;
551 struct em28xx *dev = filp->private_data;
552
553 if (down_interruptible(&dev->fileop_lock))
554 return POLLERR;
555
556 if (dev->state & DEV_DISCONNECTED) {
557 em28xx_videodbg("device not present\n");
558 } else if (dev->state & DEV_MISCONFIGURED) {
559 em28xx_videodbg("device is misconfigured; close and open it again\n");
560 } else {
561 if (dev->io == IO_NONE) {
562 if (!em28xx_request_buffers
563 (dev, EM28XX_NUM_READ_FRAMES)) {
564 em28xx_warn
565 ("poll() failed, not enough memory\n");
566 } else {
567 dev->io = IO_READ;
568 dev->stream = STREAM_ON;
569 }
570 }
571
572 if (dev->io == IO_READ) {
573 em28xx_queue_unusedframes(dev);
574 poll_wait(filp, &dev->wait_frame, wait);
575
576 if (!list_empty(&dev->outqueue))
577 mask |= POLLIN | POLLRDNORM;
578
579 up(&dev->fileop_lock);
580
581 return mask;
582 }
583 }
584
585 up(&dev->fileop_lock);
586 return POLLERR;
587}
588
589/*
590 * em28xx_vm_open()
591 */
592static void em28xx_vm_open(struct vm_area_struct *vma)
593{
594 struct em28xx_frame_t *f = vma->vm_private_data;
595 f->vma_use_count++;
596}
597
598/*
599 * em28xx_vm_close()
600 */
601static void em28xx_vm_close(struct vm_area_struct *vma)
602{
603 /* NOTE: buffers are not freed here */
604 struct em28xx_frame_t *f = vma->vm_private_data;
605 f->vma_use_count--;
606}
607
608static struct vm_operations_struct em28xx_vm_ops = {
609 .open = em28xx_vm_open,
610 .close = em28xx_vm_close,
611};
612
613/*
614 * em28xx_v4l2_mmap()
615 */
616static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
617{
618 unsigned long size = vma->vm_end - vma->vm_start,
619 start = vma->vm_start, pos, page;
620 u32 i;
621
622 struct em28xx *dev = filp->private_data;
623
624 if (down_interruptible(&dev->fileop_lock))
625 return -ERESTARTSYS;
626
627 if (dev->state & DEV_DISCONNECTED) {
628 em28xx_videodbg("mmap: device not present\n");
629 up(&dev->fileop_lock);
630 return -ENODEV;
631 }
632
633 if (dev->state & DEV_MISCONFIGURED) {
634 em28xx_videodbg ("mmap: Device is misconfigured; close and "
635 "open it again\n");
636 up(&dev->fileop_lock);
637 return -EIO;
638 }
639
640 if (dev->io != IO_MMAP || !(vma->vm_flags & VM_WRITE) ||
641 size != PAGE_ALIGN(dev->frame[0].buf.length)) {
642 up(&dev->fileop_lock);
643 return -EINVAL;
644 }
645
646 for (i = 0; i < dev->num_frames; i++) {
647 if ((dev->frame[i].buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
648 break;
649 }
650 if (i == dev->num_frames) {
651 em28xx_videodbg("mmap: user supplied mapping address is out of range\n");
652 up(&dev->fileop_lock);
653 return -EINVAL;
654 }
655
656 /* VM_IO is eventually going to replace PageReserved altogether */
657 vma->vm_flags |= VM_IO;
658 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
659
660 pos = (unsigned long)dev->frame[i].bufmem;
661 while (size > 0) { /* size is page-aligned */
662 page = vmalloc_to_pfn((void *)pos);
663 if (remap_pfn_range(vma, start, page, PAGE_SIZE,
664 vma->vm_page_prot)) {
665 em28xx_videodbg("mmap: rename page map failed\n");
666 up(&dev->fileop_lock);
667 return -EAGAIN;
668 }
669 start += PAGE_SIZE;
670 pos += PAGE_SIZE;
671 size -= PAGE_SIZE;
672 }
673
674 vma->vm_ops = &em28xx_vm_ops;
675 vma->vm_private_data = &dev->frame[i];
676
677 em28xx_vm_open(vma);
678 up(&dev->fileop_lock);
679 return 0;
680}
681
682/*
683 * em28xx_get_ctrl()
684 * return the current saturation, brightness or contrast, mute state
685 */
686static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl)
687{
688 s32 tmp;
689 switch (ctrl->id) {
690 case V4L2_CID_AUDIO_MUTE:
691 ctrl->value = dev->mute;
692 return 0;
693 case V4L2_CID_AUDIO_VOLUME:
694 ctrl->value = dev->volume;
695 return 0;
696 case V4L2_CID_BRIGHTNESS:
697 if ((tmp = em28xx_brightness_get(dev)) < 0)
698 return -EIO;
699 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
700 return 0;
701 case V4L2_CID_CONTRAST:
702 if ((ctrl->value = em28xx_contrast_get(dev)) < 0)
703 return -EIO;
704 return 0;
705 case V4L2_CID_SATURATION:
706 if ((ctrl->value = em28xx_saturation_get(dev)) < 0)
707 return -EIO;
708 return 0;
709 case V4L2_CID_RED_BALANCE:
710 if ((tmp = em28xx_v_balance_get(dev)) < 0)
711 return -EIO;
712 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
713 return 0;
714 case V4L2_CID_BLUE_BALANCE:
715 if ((tmp = em28xx_u_balance_get(dev)) < 0)
716 return -EIO;
717 ctrl->value = (s32) ((s8) tmp); /* FIXME: clenaer way to extend sign? */
718 return 0;
719 case V4L2_CID_GAMMA:
720 if ((ctrl->value = em28xx_gamma_get(dev)) < 0)
721 return -EIO;
722 return 0;
723 default:
724 return -EINVAL;
725 }
726}
727
728/*
729 * em28xx_set_ctrl()
730 * mute or set new saturation, brightness or contrast
731 */
732static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl)
733{
734 switch (ctrl->id) {
735 case V4L2_CID_AUDIO_MUTE:
736 if (ctrl->value != dev->mute) {
737 dev->mute = ctrl->value;
738 em28xx_audio_usb_mute(dev, ctrl->value);
739 return em28xx_audio_analog_set(dev);
740 }
741 return 0;
742 case V4L2_CID_AUDIO_VOLUME:
743 dev->volume = ctrl->value;
744 return em28xx_audio_analog_set(dev);
745 case V4L2_CID_BRIGHTNESS:
746 return em28xx_brightness_set(dev, ctrl->value);
747 case V4L2_CID_CONTRAST:
748 return em28xx_contrast_set(dev, ctrl->value);
749 case V4L2_CID_SATURATION:
750 return em28xx_saturation_set(dev, ctrl->value);
751 case V4L2_CID_RED_BALANCE:
752 return em28xx_v_balance_set(dev, ctrl->value);
753 case V4L2_CID_BLUE_BALANCE:
754 return em28xx_u_balance_set(dev, ctrl->value);
755 case V4L2_CID_GAMMA:
756 return em28xx_gamma_set(dev, ctrl->value);
757 default:
758 return -EINVAL;
759 }
760}
761
762/*
763 * em28xx_stream_interrupt()
764 * stops streaming
765 */
766static int em28xx_stream_interrupt(struct em28xx *dev)
767{
768 int ret = 0;
769
770 /* stop reading from the device */
771
772 dev->stream = STREAM_INTERRUPT;
773 ret = wait_event_timeout(dev->wait_stream,
774 (dev->stream == STREAM_OFF) ||
775 (dev->state & DEV_DISCONNECTED),
776 EM28XX_URB_TIMEOUT);
777 if (dev->state & DEV_DISCONNECTED)
778 return -ENODEV;
779 else if (ret) {
780 dev->state |= DEV_MISCONFIGURED;
781 em28xx_videodbg("device is misconfigured; close and "
782 "open /dev/video%d again\n", dev->vdev->minor);
783 return ret;
784 }
785
786 return 0;
787}
788
789static int em28xx_set_norm(struct em28xx *dev, int width, int height)
790{
791 unsigned int hscale, vscale;
792 unsigned int maxh, maxw;
793
794 maxw = norm_maxw(dev);
795 maxh = norm_maxh(dev);
796
797 /* width must even because of the YUYV format */
798 /* height must be even because of interlacing */
799 height &= 0xfffe;
800 width &= 0xfffe;
801
802 if (height < 32)
803 height = 32;
804 if (height > maxh)
805 height = maxh;
806 if (width < 48)
807 width = 48;
808 if (width > maxw)
809 width = maxw;
810
811 if ((hscale = (((unsigned long)maxw) << 12) / width - 4096L) >= 0x4000)
812 hscale = 0x3fff;
813 width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
814
815 if ((vscale = (((unsigned long)maxh) << 12) / height - 4096L) >= 0x4000)
816 vscale = 0x3fff;
817 height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
818
819 /* set new image size */
820 dev->width = width;
821 dev->height = height;
822 dev->frame_size = dev->width * dev->height * 2;
823 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
824 dev->bytesperline = dev->width * 2;
825 dev->hscale = hscale;
826 dev->vscale = vscale;
827
828 em28xx_resolution_set(dev);
829
830 return 0;
831}
832
833/*
834 * em28xx_v4l2_do_ioctl()
835 * This function is _not_ called directly, but from
836 * em28xx_v4l2_ioctl. Userspace
837 * copying is done already, arg is a kernel pointer.
838 */
839static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
840 struct em28xx *dev, unsigned int cmd, void *arg,
841 v4l2_kioctl driver_ioctl)
842{
843 int ret;
844
845 switch (cmd) {
846 /* ---------- tv norms ---------- */
847 case VIDIOC_ENUMSTD:
848 {
849 struct v4l2_standard *e = arg;
850 unsigned int i;
851
852 i = e->index;
853 if (i >= TVNORMS)
854 return -EINVAL;
855 ret = v4l2_video_std_construct(e, tvnorms[e->index].id,
856 tvnorms[e->index].name);
857 e->index = i;
858 if (ret < 0)
859 return ret;
860 return 0;
861 }
862 case VIDIOC_G_STD:
863 {
864 v4l2_std_id *id = arg;
865
866 *id = dev->tvnorm->id;
867 return 0;
868 }
869 case VIDIOC_S_STD:
870 {
871 v4l2_std_id *id = arg;
872 unsigned int i;
873
874 for (i = 0; i < TVNORMS; i++)
875 if (*id == tvnorms[i].id)
876 break;
877 if (i == TVNORMS)
878 for (i = 0; i < TVNORMS; i++)
879 if (*id & tvnorms[i].id)
880 break;
881 if (i == TVNORMS)
882 return -EINVAL;
883
884 down(&dev->lock);
885 dev->tvnorm = &tvnorms[i];
886
887 em28xx_set_norm(dev, dev->width, dev->height);
888
889/*
890 dev->width=norm_maxw(dev);
891 dev->height=norm_maxh(dev);
892 dev->frame_size=dev->width*dev->height*2;
893 dev->field_size=dev->frame_size>>1;
894 dev->bytesperline=dev->width*2;
895 dev->hscale=0;
896 dev->vscale=0;
897
898 em28xx_resolution_set(dev);
899*/
900/*
901 em28xx_uninit_isoc(dev);
902 em28xx_set_alternate(dev);
903 em28xx_capture_start(dev, 1);
904 em28xx_resolution_set(dev);
905 em28xx_init_isoc(dev);
906*/
907 em28xx_i2c_call_clients(dev, DECODER_SET_NORM,
908 &tvnorms[i].mode);
909 em28xx_i2c_call_clients(dev, VIDIOC_S_STD,
910 &dev->tvnorm->id);
911
912 up(&dev->lock);
913
914 return 0;
915 }
916
917 /* ------ input switching ---------- */
918 case VIDIOC_ENUMINPUT:
919 {
920 struct v4l2_input *i = arg;
921 unsigned int n;
922 static const char *iname[] = {
923 [EM28XX_VMUX_COMPOSITE1] = "Composite1",
924 [EM28XX_VMUX_COMPOSITE2] = "Composite2",
925 [EM28XX_VMUX_COMPOSITE3] = "Composite3",
926 [EM28XX_VMUX_COMPOSITE4] = "Composite4",
927 [EM28XX_VMUX_SVIDEO] = "S-Video",
928 [EM28XX_VMUX_TELEVISION] = "Television",
929 [EM28XX_VMUX_CABLE] = "Cable TV",
930 [EM28XX_VMUX_DVB] = "DVB",
931 [EM28XX_VMUX_DEBUG] = "for debug only",
932 };
933
934 n = i->index;
935 if (n >= MAX_EM28XX_INPUT)
936 return -EINVAL;
937 if (0 == INPUT(n)->type)
938 return -EINVAL;
939 memset(i, 0, sizeof(*i));
940 i->index = n;
941 i->type = V4L2_INPUT_TYPE_CAMERA;
942 strcpy(i->name, iname[INPUT(n)->type]);
943 if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) ||
944 (EM28XX_VMUX_CABLE == INPUT(n)->type))
945 i->type = V4L2_INPUT_TYPE_TUNER;
946 for (n = 0; n < ARRAY_SIZE(tvnorms); n++)
947 i->std |= tvnorms[n].id;
948 return 0;
949 }
950
951 case VIDIOC_G_INPUT:
952 {
953 int *i = arg;
954 *i = dev->ctl_input;
955
956 return 0;
957 }
958
959 case VIDIOC_S_INPUT:
960 {
961 int *index = arg;
962
963 if (*index >= MAX_EM28XX_INPUT)
964 return -EINVAL;
965 if (0 == INPUT(*index)->type)
966 return -EINVAL;
967
968 down(&dev->lock);
969 video_mux(dev, *index);
970 up(&dev->lock);
971
972 return 0;
973 }
974
975 case VIDIOC_G_AUDIO:
976 {
977 struct v4l2_audio *a = arg;
978 unsigned int index = a->index;
979
980 if (a->index > 1)
981 return -EINVAL;
982 memset(a, 0, sizeof(*a));
983 index = dev->ctl_ainput;
984
985 if (index == 0) {
986 strcpy(a->name, "Television");
987 } else {
988 strcpy(a->name, "Line In");
989 }
990 a->capability = V4L2_AUDCAP_STEREO;
991 a->index = index;
992 return 0;
993 }
994
995 case VIDIOC_S_AUDIO:
996 {
997 struct v4l2_audio *a = arg;
998 if (a->index != dev->ctl_ainput)
999 return -EINVAL;
1000
1001 return 0;
1002 }
1003
1004 /* --- controls ---------------------------------------------- */
1005 case VIDIOC_QUERYCTRL:
1006 {
1007 struct v4l2_queryctrl *qc = arg;
1008 u8 i, n;
1009 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
1010 for (i = 0; i < n; i++)
1011 if (qc->id && qc->id == em28xx_qctrl[i].id) {
1012 memcpy(qc, &(em28xx_qctrl[i]),
1013 sizeof(*qc));
1014 return 0;
1015 }
1016
1017 return -EINVAL;
1018 }
1019
1020 case VIDIOC_G_CTRL:
1021 {
1022 struct v4l2_control *ctrl = arg;
1023
1024
1025 return em28xx_get_ctrl(dev, ctrl);
1026 }
1027
1028 case VIDIOC_S_CTRL_OLD: /* ??? */
1029 case VIDIOC_S_CTRL:
1030 {
1031 struct v4l2_control *ctrl = arg;
1032 u8 i, n;
1033
1034
1035 n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]);
1036 for (i = 0; i < n; i++)
1037 if (ctrl->id == em28xx_qctrl[i].id) {
1038 if (ctrl->value <
1039 em28xx_qctrl[i].minimum
1040 || ctrl->value >
1041 em28xx_qctrl[i].maximum)
1042 return -ERANGE;
1043
1044 return em28xx_set_ctrl(dev, ctrl);
1045 }
1046 return -EINVAL;
1047 }
1048
1049 /* --- tuner ioctls ------------------------------------------ */
1050 case VIDIOC_G_TUNER:
1051 {
1052 struct v4l2_tuner *t = arg;
1053 int status = 0;
1054
1055 if (0 != t->index)
1056 return -EINVAL;
1057
1058 memset(t, 0, sizeof(*t));
1059 strcpy(t->name, "Tuner");
1060 t->type = V4L2_TUNER_ANALOG_TV;
1061 t->capability = V4L2_TUNER_CAP_NORM;
1062 t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
1063/* t->signal = 0xffff;*/
1064/* em28xx_i2c_call_clients(dev,VIDIOC_G_TUNER,t);*/
1065 /* No way to get signal strength? */
1066 down(&dev->lock);
1067 em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
1068 &status);
1069 up(&dev->lock);
1070 t->signal =
1071 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
1072
1073 em28xx_videodbg("VIDIO_G_TUNER: signal=%x, afc=%x\n", t->signal,
1074 t->afc);
1075 return 0;
1076 }
1077 case VIDIOC_S_TUNER:
1078 {
1079 struct v4l2_tuner *t = arg;
1080 int status = 0;
1081
1082 if (0 != t->index)
1083 return -EINVAL;
1084 memset(t, 0, sizeof(*t));
1085 strcpy(t->name, "Tuner");
1086 t->type = V4L2_TUNER_ANALOG_TV;
1087 t->capability = V4L2_TUNER_CAP_NORM;
1088 t->rangehigh = 0xffffffffUL; /* FIXME: set correct range */
1089/* t->signal = 0xffff; */
1090 /* No way to get signal strength? */
1091 down(&dev->lock);
1092 em28xx_i2c_call_clients(dev, DECODER_GET_STATUS,
1093 &status);
1094 up(&dev->lock);
1095 t->signal =
1096 (status & DECODER_STATUS_GOOD) != 0 ? 0xffff : 0;
1097
1098 em28xx_videodbg("VIDIO_S_TUNER: signal=%x, afc=%x\n",
1099 t->signal, t->afc);
1100 return 0;
1101 }
1102 case VIDIOC_G_FREQUENCY:
1103 {
1104 struct v4l2_frequency *f = arg;
1105
1106 memset(f, 0, sizeof(*f));
1107 f->type = V4L2_TUNER_ANALOG_TV;
1108 f->frequency = dev->ctl_freq;
1109
1110 return 0;
1111 }
1112 case VIDIOC_S_FREQUENCY:
1113 {
1114 struct v4l2_frequency *f = arg;
1115
1116 if (0 != f->tuner)
1117 return -EINVAL;
1118
1119 if (V4L2_TUNER_ANALOG_TV != f->type)
1120 return -EINVAL;
1121
1122 down(&dev->lock);
1123 dev->ctl_freq = f->frequency;
1124 em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
1125 up(&dev->lock);
1126 return 0;
1127 }
1128
1129 case VIDIOC_CROPCAP:
1130 {
1131 struct v4l2_cropcap *cc = arg;
1132
1133 if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1134 return -EINVAL;
1135 cc->bounds.left = 0;
1136 cc->bounds.top = 0;
1137 cc->bounds.width = dev->width;
1138 cc->bounds.height = dev->height;
1139 cc->defrect = cc->bounds;
1140 cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */
1141 cc->pixelaspect.denominator = 59;
1142 return 0;
1143 }
1144 case VIDIOC_STREAMON:
1145 {
1146 int *type = arg;
1147
1148 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1149 || dev->io != IO_MMAP)
1150 return -EINVAL;
1151
1152 if (list_empty(&dev->inqueue))
1153 return -EINVAL;
1154
1155 dev->stream = STREAM_ON; /* FIXME: Start video capture here? */
1156
1157 em28xx_videodbg("VIDIOC_STREAMON: starting stream\n");
1158
1159 return 0;
1160 }
1161 case VIDIOC_STREAMOFF:
1162 {
1163 int *type = arg;
1164 int ret;
1165
1166 if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1167 || dev->io != IO_MMAP)
1168 return -EINVAL;
1169
1170 if (dev->stream == STREAM_ON) {
1171 em28xx_videodbg ("VIDIOC_STREAMOFF: interrupting stream\n");
1172 if ((ret = em28xx_stream_interrupt(dev)))
1173 return ret;
1174 }
1175 em28xx_empty_framequeues(dev);
1176
1177 return 0;
1178 }
1179 default:
1180 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
1181 driver_ioctl);
1182 }
1183 return 0;
1184}
1185
1186/*
1187 * em28xx_v4l2_do_ioctl()
1188 * This function is _not_ called directly, but from
1189 * em28xx_v4l2_ioctl. Userspace
1190 * copying is done already, arg is a kernel pointer.
1191 */
1192static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1193 unsigned int cmd, void *arg)
1194{
1195 struct em28xx *dev = filp->private_data;
1196
1197 if (!dev)
1198 return -ENODEV;
1199
1200 if (video_debug > 1)
1201 em28xx_print_ioctl(dev->name,cmd);
1202
1203 switch (cmd) {
1204
1205 /* --- capabilities ------------------------------------------ */
1206 case VIDIOC_QUERYCAP:
1207 {
1208 struct v4l2_capability *cap = arg;
1209
1210 memset(cap, 0, sizeof(*cap));
1211 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1212 strlcpy(cap->card, em28xx_boards[dev->model].name,
1213 sizeof(cap->card));
1214 strlcpy(cap->bus_info, dev->udev->dev.bus_id,
1215 sizeof(cap->bus_info));
1216 cap->version = EM28XX_VERSION_CODE;
1217 cap->capabilities =
1218 V4L2_CAP_VIDEO_CAPTURE |
1219 V4L2_CAP_AUDIO |
1220 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1221 if (dev->has_tuner)
1222 cap->capabilities |= V4L2_CAP_TUNER;
1223 return 0;
1224 }
1225
1226 /* --- capture ioctls ---------------------------------------- */
1227 case VIDIOC_ENUM_FMT:
1228 {
1229 struct v4l2_fmtdesc *fmtd = arg;
1230
1231 if (fmtd->index != 0)
1232 return -EINVAL;
1233 memset(fmtd, 0, sizeof(*fmtd));
1234 fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1235 strcpy(fmtd->description, "Packed YUY2");
1236 fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
1237 memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
1238 return 0;
1239 }
1240
1241 case VIDIOC_G_FMT:
1242 {
1243 struct v4l2_format *format = arg;
1244
1245 em28xx_videodbg("VIDIOC_G_FMT: type=%s\n",
1246 format->type ==
1247 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
1248 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
1249 V4L2_BUF_TYPE_VBI_CAPTURE ?
1250 "V4L2_BUF_TYPE_VBI_CAPTURE " :
1251 "not supported");
1252
1253 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1254 return -EINVAL;
1255
1256 format->fmt.pix.width = dev->width;
1257 format->fmt.pix.height = dev->height;
1258 format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1259 format->fmt.pix.bytesperline = dev->bytesperline;
1260 format->fmt.pix.sizeimage = dev->frame_size;
1261 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1262 format->fmt.pix.field = dev->interlaced ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
1263
1264 em28xx_videodbg("VIDIOC_G_FMT: %dx%d\n", dev->width,
1265 dev->height);
1266 return 0;
1267 }
1268
1269 case VIDIOC_TRY_FMT:
1270 case VIDIOC_S_FMT:
1271 {
1272 struct v4l2_format *format = arg;
1273 u32 i;
1274 int ret = 0;
1275 int width = format->fmt.pix.width;
1276 int height = format->fmt.pix.height;
1277 unsigned int hscale, vscale;
1278 unsigned int maxh, maxw;
1279
1280 maxw = norm_maxw(dev);
1281 maxh = norm_maxh(dev);
1282
1283/* int both_fields; */
1284
1285 em28xx_videodbg("%s: type=%s\n",
1286 cmd ==
1287 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1288 "VIDIOC_S_FMT",
1289 format->type ==
1290 V4L2_BUF_TYPE_VIDEO_CAPTURE ?
1291 "V4L2_BUF_TYPE_VIDEO_CAPTURE" : format->type ==
1292 V4L2_BUF_TYPE_VBI_CAPTURE ?
1293 "V4L2_BUF_TYPE_VBI_CAPTURE " :
1294 "not supported");
1295
1296 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1297 return -EINVAL;
1298
1299 em28xx_videodbg("%s: requested %dx%d\n",
1300 cmd ==
1301 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1302 "VIDIOC_S_FMT", format->fmt.pix.width,
1303 format->fmt.pix.height);
1304
1305 /* FIXME: Move some code away from here */
1306 /* width must even because of the YUYV format */
1307 /* height must be even because of interlacing */
1308 height &= 0xfffe;
1309 width &= 0xfffe;
1310
1311 if (height < 32)
1312 height = 32;
1313 if (height > maxh)
1314 height = maxh;
1315 if (width < 48)
1316 width = 48;
1317 if (width > maxw)
1318 width = maxw;
1319
1320 if(dev->is_em2800){
1321 /* the em2800 can only scale down to 50% */
1322 if(height % (maxh / 2))
1323 height=maxh;
1324 if(width % (maxw / 2))
1325 width=maxw;
1326 /* according to empiatech support */
1327 /* the MaxPacketSize is to small to support */
1328 /* framesizes larger than 640x480 @ 30 fps */
1329 /* or 640x576 @ 25 fps. As this would cut */
1330 /* of a part of the image we prefer */
1331 /* 360x576 or 360x480 for now */
1332 if(width == maxw && height == maxh)
1333 width /= 2;
1334 }
1335
1336 if ((hscale =
1337 (((unsigned long)maxw) << 12) / width - 4096L) >=
1338 0x4000)
1339 hscale = 0x3fff;
1340 width =
1341 (((unsigned long)maxw) << 12) / (hscale + 4096L);
1342
1343 if ((vscale =
1344 (((unsigned long)maxh) << 12) / height - 4096L) >=
1345 0x4000)
1346 vscale = 0x3fff;
1347 height =
1348 (((unsigned long)maxh) << 12) / (vscale + 4096L);
1349
1350 format->fmt.pix.width = width;
1351 format->fmt.pix.height = height;
1352 format->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1353 format->fmt.pix.bytesperline = width * 2;
1354 format->fmt.pix.sizeimage = width * 2 * height;
1355 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1356 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
1357
1358 em28xx_videodbg("%s: returned %dx%d (%d, %d)\n",
1359 cmd ==
1360 VIDIOC_TRY_FMT ? "VIDIOC_TRY_FMT" :
1361 "VIDIOC_S_FMT", format->fmt.pix.width,
1362 format->fmt.pix.height, hscale, vscale);
1363
1364 if (cmd == VIDIOC_TRY_FMT)
1365 return 0;
1366
1367 for (i = 0; i < dev->num_frames; i++)
1368 if (dev->frame[i].vma_use_count) {
1369 em28xx_videodbg("VIDIOC_S_FMT failed. "
1370 "Unmap the buffers first.\n");
1371 return -EINVAL;
1372 }
1373
1374 /* stop io in case it is already in progress */
1375 if (dev->stream == STREAM_ON) {
1376 em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
1377 if ((ret = em28xx_stream_interrupt(dev)))
1378 return ret;
1379 }
1380
1381 em28xx_release_buffers(dev);
1382 dev->io = IO_NONE;
1383
1384 /* set new image size */
1385 dev->width = width;
1386 dev->height = height;
1387 dev->frame_size = dev->width * dev->height * 2;
1388 dev->field_size = dev->frame_size >> 1; /*both_fileds ? dev->frame_size>>1 : dev->frame_size; */
1389 dev->bytesperline = dev->width * 2;
1390 dev->hscale = hscale;
1391 dev->vscale = vscale;
1392/* dev->both_fileds = both_fileds; */
1393 em28xx_uninit_isoc(dev);
1394 em28xx_set_alternate(dev);
1395 em28xx_capture_start(dev, 1);
1396 em28xx_resolution_set(dev);
1397 em28xx_init_isoc(dev);
1398
1399 return 0;
1400 }
1401
1402 /* --- streaming capture ------------------------------------- */
1403 case VIDIOC_REQBUFS:
1404 {
1405 struct v4l2_requestbuffers *rb = arg;
1406 u32 i;
1407 int ret;
1408
1409 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1410 rb->memory != V4L2_MEMORY_MMAP)
1411 return -EINVAL;
1412
1413 if (dev->io == IO_READ) {
1414 em28xx_videodbg ("method is set to read;"
1415 " close and open the device again to"
1416 " choose the mmap I/O method\n");
1417 return -EINVAL;
1418 }
1419
1420 for (i = 0; i < dev->num_frames; i++)
1421 if (dev->frame[i].vma_use_count) {
1422 em28xx_videodbg ("VIDIOC_REQBUFS failed; previous buffers are still mapped\n");
1423 return -EINVAL;
1424 }
1425
1426 if (dev->stream == STREAM_ON) {
1427 em28xx_videodbg("VIDIOC_REQBUFS: interrupting stream\n");
1428 if ((ret = em28xx_stream_interrupt(dev)))
1429 return ret;
1430 }
1431
1432 em28xx_empty_framequeues(dev);
1433
1434 em28xx_release_buffers(dev);
1435 if (rb->count)
1436 rb->count =
1437 em28xx_request_buffers(dev, rb->count);
1438
1439 dev->frame_current = NULL;
1440
1441 em28xx_videodbg ("VIDIOC_REQBUFS: setting io method to mmap: num bufs %i\n",
1442 rb->count);
1443 dev->io = rb->count ? IO_MMAP : IO_NONE;
1444 return 0;
1445 }
1446
1447 case VIDIOC_QUERYBUF:
1448 {
1449 struct v4l2_buffer *b = arg;
1450
1451 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1452 b->index >= dev->num_frames || dev->io != IO_MMAP)
1453 return -EINVAL;
1454
1455 memcpy(b, &dev->frame[b->index].buf, sizeof(*b));
1456
1457 if (dev->frame[b->index].vma_use_count) {
1458 b->flags |= V4L2_BUF_FLAG_MAPPED;
1459 }
1460 if (dev->frame[b->index].state == F_DONE)
1461 b->flags |= V4L2_BUF_FLAG_DONE;
1462 else if (dev->frame[b->index].state != F_UNUSED)
1463 b->flags |= V4L2_BUF_FLAG_QUEUED;
1464 return 0;
1465 }
1466 case VIDIOC_QBUF:
1467 {
1468 struct v4l2_buffer *b = arg;
1469 unsigned long lock_flags;
1470
1471 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1472 b->index >= dev->num_frames || dev->io != IO_MMAP) {
1473 return -EINVAL;
1474 }
1475
1476 if (dev->frame[b->index].state != F_UNUSED) {
1477 return -EAGAIN;
1478 }
1479 dev->frame[b->index].state = F_QUEUED;
1480
1481 /* add frame to fifo */
1482 spin_lock_irqsave(&dev->queue_lock, lock_flags);
1483 list_add_tail(&dev->frame[b->index].frame,
1484 &dev->inqueue);
1485 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
1486
1487 return 0;
1488 }
1489 case VIDIOC_DQBUF:
1490 {
1491 struct v4l2_buffer *b = arg;
1492 struct em28xx_frame_t *f;
1493 unsigned long lock_flags;
1494 int ret = 0;
1495
1496 if (b->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1497 || dev->io != IO_MMAP)
1498 return -EINVAL;
1499
1500 if (list_empty(&dev->outqueue)) {
1501 if (dev->stream == STREAM_OFF)
1502 return -EINVAL;
1503 if (filp->f_flags & O_NONBLOCK)
1504 return -EAGAIN;
1505 ret = wait_event_interruptible
1506 (dev->wait_frame,
1507 (!list_empty(&dev->outqueue)) ||
1508 (dev->state & DEV_DISCONNECTED));
1509 if (ret)
1510 return ret;
1511 if (dev->state & DEV_DISCONNECTED)
1512 return -ENODEV;
1513 }
1514
1515 spin_lock_irqsave(&dev->queue_lock, lock_flags);
1516 f = list_entry(dev->outqueue.next,
1517 struct em28xx_frame_t, frame);
1518 list_del(dev->outqueue.next);
1519 spin_unlock_irqrestore(&dev->queue_lock, lock_flags);
1520
1521 f->state = F_UNUSED;
1522 memcpy(b, &f->buf, sizeof(*b));
1523
1524 if (f->vma_use_count)
1525 b->flags |= V4L2_BUF_FLAG_MAPPED;
1526
1527 return 0;
1528 }
1529 default:
1530 return em28xx_do_ioctl(inode, filp, dev, cmd, arg,
1531 em28xx_video_do_ioctl);
1532 }
1533 return 0;
1534}
1535
1536/*
1537 * em28xx_v4l2_ioctl()
1538 * handle v4l2 ioctl the main action happens in em28xx_v4l2_do_ioctl()
1539 */
1540static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
1541 unsigned int cmd, unsigned long arg)
1542{
1543 int ret = 0;
1544 struct em28xx *dev = filp->private_data;
1545
1546 if (down_interruptible(&dev->fileop_lock))
1547 return -ERESTARTSYS;
1548
1549 if (dev->state & DEV_DISCONNECTED) {
1550 em28xx_errdev("v4l2 ioctl: device not present\n");
1551 up(&dev->fileop_lock);
1552 return -ENODEV;
1553 }
1554
1555 if (dev->state & DEV_MISCONFIGURED) {
1556 em28xx_errdev
1557 ("v4l2 ioctl: device is misconfigured; close and open it again\n");
1558 up(&dev->fileop_lock);
1559 return -EIO;
1560 }
1561
1562 ret = video_usercopy(inode, filp, cmd, arg, em28xx_video_do_ioctl);
1563
1564 up(&dev->fileop_lock);
1565
1566 return ret;
1567}
1568
1569static struct file_operations em28xx_v4l_fops = {
1570 .owner = THIS_MODULE,
1571 .open = em28xx_v4l2_open,
1572 .release = em28xx_v4l2_close,
1573 .ioctl = em28xx_v4l2_ioctl,
1574 .read = em28xx_v4l2_read,
1575 .poll = em28xx_v4l2_poll,
1576 .mmap = em28xx_v4l2_mmap,
1577 .llseek = no_llseek,
1578};
1579
1580/******************************** usb interface *****************************************/
1581
1582/*
1583 * em28xx_init_dev()
1584 * allocates and inits the device structs, registers i2c bus and v4l device
1585 */
1586static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1587 int minor, int model)
1588{
1589 struct em28xx *dev = *devhandle;
1590 int retval = -ENOMEM;
1591 int errCode, i;
1592 unsigned int maxh, maxw;
1593
1594 dev->udev = udev;
1595 dev->model = model;
1596 init_MUTEX(&dev->lock);
1597 init_waitqueue_head(&dev->open);
1598
1599 dev->em28xx_write_regs = em28xx_write_regs;
1600 dev->em28xx_read_reg = em28xx_read_reg;
1601 dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len;
1602 dev->em28xx_write_regs_req = em28xx_write_regs_req;
1603 dev->em28xx_read_reg_req = em28xx_read_reg_req;
1604 dev->is_em2800 = em28xx_boards[model].is_em2800;
1605 dev->has_tuner = em28xx_boards[model].has_tuner;
1606 dev->has_msp34xx = em28xx_boards[model].has_msp34xx;
1607 dev->tda9887_conf = em28xx_boards[model].tda9887_conf;
1608 dev->decoder = em28xx_boards[model].decoder;
1609
1610 if (tuner >= 0)
1611 dev->tuner_type = tuner;
1612 else
1613 dev->tuner_type = em28xx_boards[model].tuner_type;
1614
1615 dev->video_inputs = em28xx_boards[model].vchannels;
1616
1617 for (i = 0; i < TVNORMS; i++)
1618 if (em28xx_boards[model].norm == tvnorms[i].mode)
1619 break;
1620 if (i == TVNORMS)
1621 i = 0;
1622
1623 dev->tvnorm = &tvnorms[i]; /* set default norm */
1624
1625 em28xx_videodbg("tvnorm=%s\n", dev->tvnorm->name);
1626
1627 maxw = norm_maxw(dev);
1628 maxh = norm_maxh(dev);
1629
1630 /* set default image size */
1631 dev->width = maxw;
1632 dev->height = maxh;
1633 dev->interlaced = EM28XX_INTERLACED_DEFAULT;
1634 dev->field_size = dev->width * dev->height;
1635 dev->frame_size =
1636 dev->interlaced ? dev->field_size << 1 : dev->field_size;
1637 dev->bytesperline = dev->width * 2;
1638 dev->hscale = 0;
1639 dev->vscale = 0;
1640 dev->ctl_input = 2;
1641
1642 /* setup video picture settings for saa7113h */
1643 memset(&dev->vpic, 0, sizeof(dev->vpic));
1644 dev->vpic.colour = 128 << 8;
1645 dev->vpic.hue = 128 << 8;
1646 dev->vpic.brightness = 128 << 8;
1647 dev->vpic.contrast = 192 << 8;
1648 dev->vpic.whiteness = 128 << 8; /* This one isn't used */
1649 dev->vpic.depth = 16;
1650 dev->vpic.palette = VIDEO_PALETTE_YUV422;
1651
1652#ifdef CONFIG_MODULES
1653 /* request some modules */
1654 if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114)
1655 request_module("saa711x");
1656 if (dev->decoder == EM28XX_TVP5150)
1657 request_module("tvp5150");
1658 if (dev->has_tuner)
1659 request_module("tuner");
1660 if (dev->tda9887_conf)
1661 request_module("tda9887");
1662#endif
1663 errCode = em28xx_config(dev);
1664 if (errCode) {
1665 em28xx_errdev("error configuring device\n");
1666 kfree(dev);
1667 return -ENOMEM;
1668 }
1669
1670 down(&dev->lock);
1671 /* register i2c bus */
1672 em28xx_i2c_register(dev);
1673
1674 /* Do board specific init and eeprom reading */
1675 em28xx_card_setup(dev);
1676
1677 /* configure the device */
1678 em28xx_config_i2c(dev);
1679
1680 up(&dev->lock);
1681
1682 errCode = em28xx_config(dev);
1683
1684#ifdef CONFIG_MODULES
1685 if (dev->has_msp34xx)
1686 request_module("msp3400");
1687#endif
1688 /* allocate and fill v4l2 device struct */
1689 dev->vdev = video_device_alloc();
1690 if (NULL == dev->vdev) {
1691 em28xx_errdev("cannot allocate video_device.\n");
1692 kfree(dev);
1693 return -ENOMEM;
1694 }
1695
1696 dev->vdev->type = VID_TYPE_CAPTURE;
1697 if (dev->has_tuner)
1698 dev->vdev->type |= VID_TYPE_TUNER;
1699 dev->vdev->hardware = 0;
1700 dev->vdev->fops = &em28xx_v4l_fops;
1701 dev->vdev->minor = -1;
1702 dev->vdev->dev = &dev->udev->dev;
1703 dev->vdev->release = video_device_release;
1704 snprintf(dev->vdev->name, sizeof(dev->vdev->name), "%s",
1705 "em28xx video");
1706 list_add_tail(&dev->devlist,&em28xx_devlist);
1707
1708 /* register v4l2 device */
1709 down(&dev->lock);
1710 if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1))) {
1711 em28xx_errdev("unable to register video device (error=%i).\n",
1712 retval);
1713 up(&dev->lock);
1714 list_del(&dev->devlist);
1715 video_device_release(dev->vdev);
1716 kfree(dev);
1717 return -ENODEV;
1718 }
1719 if (dev->has_msp34xx) {
1720 /* Send a reset to other chips via gpio */
1721 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1);
1722 udelay(2500);
1723 em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1);
1724 udelay(2500);
1725
1726 }
1727 video_mux(dev, 0);
1728
1729 up(&dev->lock);
1730
1731 em28xx_info("V4L2 device registered as /dev/video%d\n",
1732 dev->vdev->minor);
1733
1734 return 0;
1735}
1736
1737/*
1738 * em28xx_usb_probe()
1739 * checks for supported devices
1740 */
1741static int em28xx_usb_probe(struct usb_interface *interface,
1742 const struct usb_device_id *id)
1743{
1744 const struct usb_endpoint_descriptor *endpoint;
1745 struct usb_device *udev;
1746 struct usb_interface *uif;
1747 struct em28xx *dev = NULL;
1748 int retval = -ENODEV;
1749 int model,i,nr,ifnum;
1750
1751 udev = usb_get_dev(interface_to_usbdev(interface));
1752 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
1753
1754
1755 /* Don't register audio interfaces */
1756 if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) {
1757 em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n",
1758 udev->descriptor.idVendor,udev->descriptor.idProduct,
1759 ifnum,
1760 interface->altsetting[0].desc.bInterfaceClass);
1761 return -ENODEV;
1762 }
1763
1764 em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n",
1765 udev->descriptor.idVendor,udev->descriptor.idProduct,
1766 ifnum,
1767 interface->altsetting[0].desc.bInterfaceClass);
1768
1769 endpoint = &interface->cur_altsetting->endpoint[1].desc;
1770
1771 /* check if the the device has the iso in endpoint at the correct place */
1772 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1773 USB_ENDPOINT_XFER_ISOC) {
1774 em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n");
1775 return -ENODEV;
1776 }
1777 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
1778 em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n");
1779 return -ENODEV;
1780 }
1781
1782 model=id->driver_info;
1783 nr=interface->minor;
1784
1785 if (nr>EM28XX_MAXBOARDS) {
1786 printk (DRIVER_NAME ": Supports only %i em28xx boards.\n",EM28XX_MAXBOARDS);
1787 return -ENOMEM;
1788 }
1789
1790 /* allocate memory for our device state and initialize it */
1791 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
1792 if (dev == NULL) {
1793 em28xx_err(DRIVER_NAME ": out of memory!\n");
1794 return -ENOMEM;
1795 }
1796 memset(dev, 0, sizeof(*dev));
1797
1798 /* compute alternate max packet sizes */
1799 uif = udev->actconfig->interface[0];
1800
1801 dev->num_alt=uif->num_altsetting;
1802 printk(DRIVER_NAME ": Alternate settings: %i\n",dev->num_alt);
1803// dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)*
1804 dev->alt_max_pkt_size = kmalloc(32*
1805 dev->num_alt,GFP_KERNEL);
1806 if (dev->alt_max_pkt_size == NULL) {
1807 em28xx_err(DRIVER_NAME ": out of memory!\n");
1808 return -ENOMEM;
1809 }
1810
1811 for (i = 0; i < dev->num_alt ; i++) {
1812 u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
1813 wMaxPacketSize);
1814 dev->alt_max_pkt_size[i] =
1815 (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
1816 printk(DRIVER_NAME ": Alternate setting %i, max size= %i\n",i,
1817 dev->alt_max_pkt_size[i]);
1818 }
1819
1820 snprintf(dev->name, 29, "em28xx #%d", nr);
1821
1822 if ((card[nr]>=0)&&(card[nr]<em28xx_bcount))
1823 model=card[nr];
1824
1825 if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) {
1826 printk( "%s: Your board has no eeprom inside it and thus can't\n"
1827 "%s: be autodetected. Please pass card=<n> insmod option to\n"
1828 "%s: workaround that. Redirect complaints to the vendor of\n"
1829 "%s: the TV card. Best regards,\n"
1830 "%s: -- tux\n",
1831 dev->name,dev->name,dev->name,dev->name,dev->name);
1832 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
1833 dev->name);
1834 for (i = 0; i < em28xx_bcount; i++) {
1835 printk("%s: card=%d -> %s\n",
1836 dev->name, i, em28xx_boards[i].name);
1837 }
1838 }
1839
1840 /* allocate device struct */
1841 retval = em28xx_init_dev(&dev, udev, nr, model);
1842 if (retval)
1843 return retval;
1844
1845 em28xx_info("Found %s\n", em28xx_boards[model].name);
1846
1847 /* save our data pointer in this interface device */
1848 usb_set_intfdata(interface, dev);
1849 return 0;
1850}
1851
1852/*
1853 * em28xx_usb_disconnect()
1854 * called when the device gets diconencted
1855 * video device will be unregistered on v4l2_close in case it is still open
1856 */
1857static void em28xx_usb_disconnect(struct usb_interface *interface)
1858{
1859 struct em28xx *dev = usb_get_intfdata(interface);
1860 usb_set_intfdata(interface, NULL);
1861
1862 if (!dev)
1863 return;
1864
1865 down_write(&em28xx_disconnect);
1866
1867 down(&dev->lock);
1868
1869 em28xx_info("disconnecting %s\n", dev->vdev->name);
1870
1871 wake_up_interruptible_all(&dev->open);
1872
1873 if (dev->users) {
1874 em28xx_warn
1875 ("device /dev/video%d is open! Deregistration and memory "
1876 "deallocation are deferred on close.\n", dev->vdev->minor);
1877 dev->state |= DEV_MISCONFIGURED;
1878 em28xx_uninit_isoc(dev);
1879 dev->state |= DEV_DISCONNECTED;
1880 wake_up_interruptible(&dev->wait_frame);
1881 wake_up_interruptible(&dev->wait_stream);
1882 } else {
1883 dev->state |= DEV_DISCONNECTED;
1884 em28xx_release_resources(dev);
1885 }
1886
1887 up(&dev->lock);
1888
1889 if (!dev->users) {
1890 kfree(dev->alt_max_pkt_size);
1891 kfree(dev);
1892 }
1893
1894 up_write(&em28xx_disconnect);
1895}
1896
1897static struct usb_driver em28xx_usb_driver = {
1898 .owner = THIS_MODULE,
1899 .name = "em28xx",
1900 .probe = em28xx_usb_probe,
1901 .disconnect = em28xx_usb_disconnect,
1902 .id_table = em28xx_id_table,
1903};
1904
1905static int __init em28xx_module_init(void)
1906{
1907 int result;
1908
1909 printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n",
1910 (EM28XX_VERSION_CODE >> 16) & 0xff,
1911 (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff);
1912#ifdef SNAPSHOT
1913 printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n",
1914 SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100);
1915#endif
1916
1917 /* register this driver with the USB subsystem */
1918 result = usb_register(&em28xx_usb_driver);
1919 if (result)
1920 em28xx_err(DRIVER_NAME
1921 " usb_register failed. Error number %d.\n", result);
1922
1923 return result;
1924}
1925
1926static void __exit em28xx_module_exit(void)
1927{
1928 /* deregister this driver with the USB subsystem */
1929 usb_deregister(&em28xx_usb_driver);
1930}
1931
1932module_init(em28xx_module_init);
1933module_exit(em28xx_module_exit);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
new file mode 100644
index 000000000000..5c7a41ce69f3
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -0,0 +1,513 @@
1/*
2 em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it>
6 Mauro Carvalho Chehab <mchehab@brturbo.com.br>
7
8 Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#ifndef _EM28XX_H
26#define _EM28XX_H
27
28#include <linux/videodev.h>
29#include <linux/i2c.h>
30#include <media/ir-kbd-i2c.h>
31
32/* Boards supported by driver */
33
34#define EM2800_BOARD_UNKNOWN 0
35#define EM2820_BOARD_UNKNOWN 1
36#define EM2820_BOARD_TERRATEC_CINERGY_250 2
37#define EM2820_BOARD_PINNACLE_USB_2 3
38#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4
39#define EM2820_BOARD_MSI_VOX_USB_2 5
40#define EM2800_BOARD_TERRATEC_CINERGY_200 6
41#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7
42#define EM2800_BOARD_KWORLD_USB2800 8
43#define EM2820_BOARD_PINNACLE_DVC_90 9
44
45#define UNSET -1
46
47/* maximum number of em28xx boards */
48#define EM28XX_MAXBOARDS 1 /*FIXME: should be bigger */
49
50/* maximum number of frames that can be queued */
51#define EM28XX_NUM_FRAMES 5
52/* number of frames that get used for v4l2_read() */
53#define EM28XX_NUM_READ_FRAMES 2
54
55/* number of buffers for isoc transfers */
56#define EM28XX_NUM_BUFS 5
57
58/* number of packets for each buffer
59 windows requests only 40 packets .. so we better do the same
60 this is what I found out for all alternate numbers there!
61 */
62#define EM28XX_NUM_PACKETS 40
63
64/* default alternate; 0 means choose the best */
65#define EM28XX_PINOUT 0
66
67#define EM28XX_INTERLACED_DEFAULT 1
68
69/*
70#define (use usbview if you want to get the other alternate number infos)
71#define
72#define alternate number 2
73#define Endpoint Address: 82
74 Direction: in
75 Attribute: 1
76 Type: Isoc
77 Max Packet Size: 1448
78 Interval: 125us
79
80 alternate number 7
81
82 Endpoint Address: 82
83 Direction: in
84 Attribute: 1
85 Type: Isoc
86 Max Packet Size: 3072
87 Interval: 125us
88*/
89
90/* time to wait when stopping the isoc transfer */
91#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
92
93/* time in msecs to wait for i2c writes to finish */
94#define EM2800_I2C_WRITE_TIMEOUT 20
95
96/* the various frame states */
97enum em28xx_frame_state {
98 F_UNUSED = 0,
99 F_QUEUED,
100 F_GRABBING,
101 F_DONE,
102 F_ERROR,
103};
104
105/* stream states */
106enum em28xx_stream_state {
107 STREAM_OFF,
108 STREAM_INTERRUPT,
109 STREAM_ON,
110};
111
112/* frames */
113struct em28xx_frame_t {
114 void *bufmem;
115 struct v4l2_buffer buf;
116 enum em28xx_frame_state state;
117 struct list_head frame;
118 unsigned long vma_use_count;
119 int top_field;
120 int fieldbytesused;
121};
122
123/* io methods */
124enum em28xx_io_method {
125 IO_NONE,
126 IO_READ,
127 IO_MMAP,
128};
129
130/* inputs */
131
132#define MAX_EM28XX_INPUT 4
133enum enum28xx_itype {
134 EM28XX_VMUX_COMPOSITE1 = 1,
135 EM28XX_VMUX_COMPOSITE2,
136 EM28XX_VMUX_COMPOSITE3,
137 EM28XX_VMUX_COMPOSITE4,
138 EM28XX_VMUX_SVIDEO,
139 EM28XX_VMUX_TELEVISION,
140 EM28XX_VMUX_CABLE,
141 EM28XX_VMUX_DVB,
142 EM28XX_VMUX_DEBUG,
143 EM28XX_RADIO,
144};
145
146struct em28xx_input {
147 enum enum28xx_itype type;
148 unsigned int vmux;
149 unsigned int amux;
150};
151
152#define INPUT(nr) (&em28xx_boards[dev->model].input[nr])
153
154enum em28xx_decoder {
155 EM28XX_TVP5150,
156 EM28XX_SAA7113,
157 EM28XX_SAA7114
158};
159
160struct em28xx_board {
161 char *name;
162 int vchannels;
163 int norm;
164 int tuner_type;
165
166 /* i2c flags */
167 unsigned int is_em2800;
168 unsigned int tda9887_conf;
169
170 unsigned int has_tuner:1;
171 unsigned int has_msp34xx:1;
172
173 enum em28xx_decoder decoder;
174
175 struct em28xx_input input[MAX_EM28XX_INPUT];
176};
177
178struct em28xx_eeprom {
179 u32 id; /* 0x9567eb1a */
180 u16 vendor_ID;
181 u16 product_ID;
182
183 u16 chip_conf;
184
185 u16 board_conf;
186
187 u16 string1, string2, string3;
188
189 u8 string_idx_table;
190};
191
192/* device states */
193enum em28xx_dev_state {
194 DEV_INITIALIZED = 0x01,
195 DEV_DISCONNECTED = 0x02,
196 DEV_MISCONFIGURED = 0x04,
197};
198
199/* tvnorms */
200struct em28xx_tvnorm {
201 char *name;
202 v4l2_std_id id;
203 /* mode for saa7113h */
204 int mode;
205};
206
207/* main device struct */
208struct em28xx {
209 /* generic device properties */
210 char name[30]; /* name (including minor) of the device */
211 int model; /* index in the device_data struct */
212 unsigned int is_em2800;
213 int video_inputs; /* number of video inputs */
214 struct list_head devlist;
215 unsigned int has_tuner:1;
216 unsigned int has_msp34xx:1;
217 unsigned int has_tda9887:1;
218
219 enum em28xx_decoder decoder;
220
221 int tuner_type; /* type of the tuner */
222 int tuner_addr; /* tuner address */
223 int tda9887_conf;
224 /* i2c i/o */
225 struct i2c_adapter i2c_adap;
226 struct i2c_client i2c_client;
227 /* video for linux */
228 int users; /* user count for exclusive use */
229 struct video_device *vdev; /* video for linux device struct */
230 struct video_picture vpic; /* picture settings only used to init saa7113h */
231 struct em28xx_tvnorm *tvnorm; /* selected tv norm */
232 int ctl_freq; /* selected frequency */
233 unsigned int ctl_input; /* selected input */
234 unsigned int ctl_ainput; /* slected audio input */
235 int mute;
236 int volume;
237 /* frame properties */
238 struct em28xx_frame_t frame[EM28XX_NUM_FRAMES]; /* list of frames */
239 int num_frames; /* number of frames currently in use */
240 unsigned int frame_count; /* total number of transfered frames */
241 struct em28xx_frame_t *frame_current; /* the frame that is being filled */
242 int width; /* current frame width */
243 int height; /* current frame height */
244 int frame_size; /* current frame size */
245 int field_size; /* current field size */
246 int bytesperline;
247 int hscale; /* horizontal scale factor (see datasheet) */
248 int vscale; /* vertical scale factor (see datasheet) */
249 int interlaced; /* 1=interlace fileds, 0=just top fileds */
250 int type;
251
252 /* states */
253 enum em28xx_dev_state state;
254 enum em28xx_stream_state stream;
255 enum em28xx_io_method io;
256 /* locks */
257 struct semaphore lock, fileop_lock;
258 spinlock_t queue_lock;
259 struct list_head inqueue, outqueue;
260 wait_queue_head_t open, wait_frame, wait_stream;
261 struct video_device *vbi_dev;
262
263 unsigned char eedata[256];
264
265 /* usb transfer */
266 struct usb_device *udev; /* the usb device */
267 int alt; /* alternate */
268 int max_pkt_size; /* max packet size of isoc transaction */
269 int num_alt; /* Number of alternative settings */
270 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
271 struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
272 char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
273 /* helper funcs that call usb_control_msg */
274 int (*em28xx_write_regs) (struct em28xx * dev, u16 reg, char *buf,
275 int len);
276 int (*em28xx_read_reg) (struct em28xx * dev, u16 reg);
277 int (*em28xx_read_reg_req_len) (struct em28xx * dev, u8 req, u16 reg,
278 char *buf, int len);
279 int (*em28xx_write_regs_req) (struct em28xx * dev, u8 req, u16 reg,
280 char *buf, int len);
281 int (*em28xx_read_reg_req) (struct em28xx * dev, u8 req, u16 reg);
282};
283
284/* Provided by em28xx-i2c.c */
285
286void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
287int em28xx_i2c_register(struct em28xx *dev);
288int em28xx_i2c_unregister(struct em28xx *dev);
289
290/* Provided by em28xx-input.c */
291
292void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir);
293
294/* Provided by em28xx-core.c */
295
296void em28xx_print_ioctl(char *name, unsigned int cmd);
297
298u32 em28xx_request_buffers(struct em28xx *dev, u32 count);
299void em28xx_queue_unusedframes(struct em28xx *dev);
300void em28xx_release_buffers(struct em28xx *dev);
301
302int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
303 char *buf, int len);
304int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg);
305int em28xx_read_reg(struct em28xx *dev, u16 reg);
306int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
307 int len);
308int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len);
309int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
310 u8 bitmask);
311int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val);
312int em28xx_audio_analog_set(struct em28xx *dev);
313int em28xx_colorlevels_set_default(struct em28xx *dev);
314int em28xx_capture_start(struct em28xx *dev, int start);
315int em28xx_outfmt_set_yuv422(struct em28xx *dev);
316int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, u8 ymin,
317 u8 ymax);
318int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart,
319 u16 width, u16 height);
320int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v);
321int em28xx_resolution_set(struct em28xx *dev);
322void em28xx_isocIrq(struct urb *urb, struct pt_regs *regs);
323int em28xx_init_isoc(struct em28xx *dev);
324void em28xx_uninit_isoc(struct em28xx *dev);
325int em28xx_set_alternate(struct em28xx *dev);
326
327/* Provided by em28xx-cards.c */
328extern int em2800_variant_detect(struct usb_device* udev,int model);
329extern void em28xx_card_setup(struct em28xx *dev);
330extern struct em28xx_board em28xx_boards[];
331extern struct usb_device_id em28xx_id_table[];
332extern const unsigned int em28xx_bcount;
333
334/* em28xx registers */
335#define CHIPID_REG 0x0a
336#define USBSUSP_REG 0x0c /* */
337
338#define AUDIOSRC_REG 0x0e
339#define XCLK_REG 0x0f
340
341#define VINMODE_REG 0x10
342#define VINCTRL_REG 0x11
343#define VINENABLE_REG 0x12 /* */
344
345#define GAMMA_REG 0x14
346#define RGAIN_REG 0x15
347#define GGAIN_REG 0x16
348#define BGAIN_REG 0x17
349#define ROFFSET_REG 0x18
350#define GOFFSET_REG 0x19
351#define BOFFSET_REG 0x1a
352
353#define OFLOW_REG 0x1b
354#define HSTART_REG 0x1c
355#define VSTART_REG 0x1d
356#define CWIDTH_REG 0x1e
357#define CHEIGHT_REG 0x1f
358
359#define YGAIN_REG 0x20
360#define YOFFSET_REG 0x21
361#define UVGAIN_REG 0x22
362#define UOFFSET_REG 0x23
363#define VOFFSET_REG 0x24
364#define SHARPNESS_REG 0x25
365
366#define COMPR_REG 0x26
367#define OUTFMT_REG 0x27
368
369#define XMIN_REG 0x28
370#define XMAX_REG 0x29
371#define YMIN_REG 0x2a
372#define YMAX_REG 0x2b
373
374#define HSCALELOW_REG 0x30
375#define HSCALEHIGH_REG 0x31
376#define VSCALELOW_REG 0x32
377#define VSCALEHIGH_REG 0x33
378
379#define AC97LSB_REG 0x40
380#define AC97MSB_REG 0x41
381#define AC97ADDR_REG 0x42
382#define AC97BUSY_REG 0x43
383
384/* em202 registers */
385#define MASTER_AC97 0x02
386#define VIDEO_AC97 0x14
387
388/* register settings */
389#define EM28XX_AUDIO_SRC_TUNER 0xc0
390#define EM28XX_AUDIO_SRC_LINE 0x80
391
392/* printk macros */
393
394#define em28xx_err(fmt, arg...) do {\
395 printk(KERN_ERR fmt , ##arg); } while (0)
396
397#define em28xx_errdev(fmt, arg...) do {\
398 printk(KERN_ERR "%s: "fmt,\
399 dev->name , ##arg); } while (0)
400
401#define em28xx_info(fmt, arg...) do {\
402 printk(KERN_INFO "%s: "fmt,\
403 dev->name , ##arg); } while (0)
404#define em28xx_warn(fmt, arg...) do {\
405 printk(KERN_WARNING "%s: "fmt,\
406 dev->name , ##arg); } while (0)
407
408inline static int em28xx_audio_source(struct em28xx *dev, int input)
409{
410 return em28xx_write_reg_bits(dev, AUDIOSRC_REG, input, 0xc0);
411}
412
413inline static int em28xx_audio_usb_mute(struct em28xx *dev, int mute)
414{
415 return em28xx_write_reg_bits(dev, XCLK_REG, mute ? 0x00 : 0x80, 0x80);
416}
417
418inline static int em28xx_audio_analog_setup(struct em28xx *dev)
419{
420 /* unmute video mixer with default volume level */
421 return em28xx_write_ac97(dev, VIDEO_AC97, "\x08\x08");
422}
423
424inline static int em28xx_compression_disable(struct em28xx *dev)
425{
426 /* side effect of disabling scaler and mixer */
427 return em28xx_write_regs(dev, COMPR_REG, "\x00", 1);
428}
429
430inline static int em28xx_contrast_get(struct em28xx *dev)
431{
432 return em28xx_read_reg(dev, YGAIN_REG) & 0x1f;
433}
434
435inline static int em28xx_brightness_get(struct em28xx *dev)
436{
437 return em28xx_read_reg(dev, YOFFSET_REG);
438}
439
440inline static int em28xx_saturation_get(struct em28xx *dev)
441{
442 return em28xx_read_reg(dev, UVGAIN_REG) & 0x1f;
443}
444
445inline static int em28xx_u_balance_get(struct em28xx *dev)
446{
447 return em28xx_read_reg(dev, UOFFSET_REG);
448}
449
450inline static int em28xx_v_balance_get(struct em28xx *dev)
451{
452 return em28xx_read_reg(dev, VOFFSET_REG);
453}
454
455inline static int em28xx_gamma_get(struct em28xx *dev)
456{
457 return em28xx_read_reg(dev, GAMMA_REG) & 0x3f;
458}
459
460inline static int em28xx_contrast_set(struct em28xx *dev, s32 val)
461{
462 u8 tmp = (u8) val;
463 return em28xx_write_regs(dev, YGAIN_REG, &tmp, 1);
464}
465
466inline static int em28xx_brightness_set(struct em28xx *dev, s32 val)
467{
468 u8 tmp = (u8) val;
469 return em28xx_write_regs(dev, YOFFSET_REG, &tmp, 1);
470}
471
472inline static int em28xx_saturation_set(struct em28xx *dev, s32 val)
473{
474 u8 tmp = (u8) val;
475 return em28xx_write_regs(dev, UVGAIN_REG, &tmp, 1);
476}
477
478inline static int em28xx_u_balance_set(struct em28xx *dev, s32 val)
479{
480 u8 tmp = (u8) val;
481 return em28xx_write_regs(dev, UOFFSET_REG, &tmp, 1);
482}
483
484inline static int em28xx_v_balance_set(struct em28xx *dev, s32 val)
485{
486 u8 tmp = (u8) val;
487 return em28xx_write_regs(dev, VOFFSET_REG, &tmp, 1);
488}
489
490inline static int em28xx_gamma_set(struct em28xx *dev, s32 val)
491{
492 u8 tmp = (u8) val;
493 return em28xx_write_regs(dev, GAMMA_REG, &tmp, 1);
494}
495
496/*FIXME: maxw should be dependent of alt mode */
497inline static unsigned int norm_maxw(struct em28xx *dev)
498{
499 switch(dev->model){
500 case (EM2820_BOARD_MSI_VOX_USB_2): return(640);
501 default: return(720);
502 }
503}
504
505inline static unsigned int norm_maxh(struct em28xx *dev)
506{
507 switch(dev->model){
508 case (EM2820_BOARD_MSI_VOX_USB_2): return(480);
509 default: return (dev->tvnorm->id & V4L2_STD_625_50) ? 576 : 480;
510 }
511}
512
513#endif
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
index 26dd06ec89a2..deeef125eb92 100644
--- a/drivers/media/video/indycam.c
+++ b/drivers/media/video/indycam.c
@@ -27,15 +27,15 @@
27 27
28#include "indycam.h" 28#include "indycam.h"
29 29
30//#define INDYCAM_DEBUG 30#define INDYCAM_MODULE_VERSION "0.0.5"
31
32#define INDYCAM_MODULE_VERSION "0.0.3"
33 31
34MODULE_DESCRIPTION("SGI IndyCam driver"); 32MODULE_DESCRIPTION("SGI IndyCam driver");
35MODULE_VERSION(INDYCAM_MODULE_VERSION); 33MODULE_VERSION(INDYCAM_MODULE_VERSION);
36MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>"); 34MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
37MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
38 36
37// #define INDYCAM_DEBUG
38
39#ifdef INDYCAM_DEBUG 39#ifdef INDYCAM_DEBUG
40#define dprintk(x...) printk("IndyCam: " x); 40#define dprintk(x...) printk("IndyCam: " x);
41#define indycam_regdump(client) indycam_regdump_debug(client) 41#define indycam_regdump(client) indycam_regdump_debug(client)
@@ -46,14 +46,14 @@ MODULE_LICENSE("GPL");
46 46
47struct indycam { 47struct indycam {
48 struct i2c_client *client; 48 struct i2c_client *client;
49 int version; 49 u8 version;
50}; 50};
51 51
52static struct i2c_driver i2c_driver_indycam; 52static struct i2c_driver i2c_driver_indycam;
53 53
54static const unsigned char initseq[] = { 54static const u8 initseq[] = {
55 INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */ 55 INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */
56 INDYCAM_SHUTTER_DEFAULT, /* INDYCAM_SHUTTER */ 56 INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */
57 INDYCAM_GAIN_DEFAULT, /* INDYCAM_GAIN */ 57 INDYCAM_GAIN_DEFAULT, /* INDYCAM_GAIN */
58 0x00, /* INDYCAM_BRIGHTNESS (read-only) */ 58 0x00, /* INDYCAM_BRIGHTNESS (read-only) */
59 INDYCAM_RED_BALANCE_DEFAULT, /* INDYCAM_RED_BALANCE */ 59 INDYCAM_RED_BALANCE_DEFAULT, /* INDYCAM_RED_BALANCE */
@@ -64,12 +64,11 @@ static const unsigned char initseq[] = {
64 64
65/* IndyCam register handling */ 65/* IndyCam register handling */
66 66
67static int indycam_read_reg(struct i2c_client *client, unsigned char reg, 67static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value)
68 unsigned char *value)
69{ 68{
70 int ret; 69 int ret;
71 70
72 if (reg == INDYCAM_RESET) { 71 if (reg == INDYCAM_REG_RESET) {
73 dprintk("indycam_read_reg(): " 72 dprintk("indycam_read_reg(): "
74 "skipping write-only register %d\n", reg); 73 "skipping write-only register %d\n", reg);
75 *value = 0; 74 *value = 0;
@@ -77,24 +76,24 @@ static int indycam_read_reg(struct i2c_client *client, unsigned char reg,
77 } 76 }
78 77
79 ret = i2c_smbus_read_byte_data(client, reg); 78 ret = i2c_smbus_read_byte_data(client, reg);
79
80 if (ret < 0) { 80 if (ret < 0) {
81 printk(KERN_ERR "IndyCam: indycam_read_reg(): read failed, " 81 printk(KERN_ERR "IndyCam: indycam_read_reg(): read failed, "
82 "register = 0x%02x\n", reg); 82 "register = 0x%02x\n", reg);
83 return ret; 83 return ret;
84 } 84 }
85 85
86 *value = (unsigned char)ret; 86 *value = (u8)ret;
87 87
88 return 0; 88 return 0;
89} 89}
90 90
91static int indycam_write_reg(struct i2c_client *client, unsigned char reg, 91static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value)
92 unsigned char value)
93{ 92{
94 int err; 93 int err;
95 94
96 if ((reg == INDYCAM_BRIGHTNESS) 95 if ((reg == INDYCAM_REG_BRIGHTNESS)
97 || (reg == INDYCAM_VERSION)) { 96 || (reg == INDYCAM_REG_VERSION)) {
98 dprintk("indycam_write_reg(): " 97 dprintk("indycam_write_reg(): "
99 "skipping read-only register %d\n", reg); 98 "skipping read-only register %d\n", reg);
100 return 0; 99 return 0;
@@ -102,6 +101,7 @@ static int indycam_write_reg(struct i2c_client *client, unsigned char reg,
102 101
103 dprintk("Writing Reg %d = 0x%02x\n", reg, value); 102 dprintk("Writing Reg %d = 0x%02x\n", reg, value);
104 err = i2c_smbus_write_byte_data(client, reg, value); 103 err = i2c_smbus_write_byte_data(client, reg, value);
104
105 if (err) { 105 if (err) {
106 printk(KERN_ERR "IndyCam: indycam_write_reg(): write failed, " 106 printk(KERN_ERR "IndyCam: indycam_write_reg(): write failed, "
107 "register = 0x%02x, value = 0x%02x\n", reg, value); 107 "register = 0x%02x, value = 0x%02x\n", reg, value);
@@ -109,13 +109,12 @@ static int indycam_write_reg(struct i2c_client *client, unsigned char reg,
109 return err; 109 return err;
110} 110}
111 111
112static int indycam_write_block(struct i2c_client *client, unsigned char reg, 112static int indycam_write_block(struct i2c_client *client, u8 reg,
113 unsigned char length, unsigned char *data) 113 u8 length, u8 *data)
114{ 114{
115 unsigned char i; 115 int i, err;
116 int err;
117 116
118 for (i = reg; i < length; i++) { 117 for (i = 0; i < length; i++) {
119 err = indycam_write_reg(client, reg + i, data[i]); 118 err = indycam_write_reg(client, reg + i, data[i]);
120 if (err) 119 if (err)
121 return err; 120 return err;
@@ -130,7 +129,7 @@ static int indycam_write_block(struct i2c_client *client, unsigned char reg,
130static void indycam_regdump_debug(struct i2c_client *client) 129static void indycam_regdump_debug(struct i2c_client *client)
131{ 130{
132 int i; 131 int i;
133 unsigned char val; 132 u8 val;
134 133
135 for (i = 0; i < 9; i++) { 134 for (i = 0; i < 9; i++) {
136 indycam_read_reg(client, i, &val); 135 indycam_read_reg(client, i, &val);
@@ -139,76 +138,144 @@ static void indycam_regdump_debug(struct i2c_client *client)
139} 138}
140#endif 139#endif
141 140
142static int indycam_get_controls(struct i2c_client *client, 141static int indycam_get_control(struct i2c_client *client,
143 struct indycam_control *ctrl) 142 struct indycam_control *ctrl)
144{ 143{
145 unsigned char ctrl_reg; 144 struct indycam *camera = i2c_get_clientdata(client);
146 145 u8 reg;
147 indycam_read_reg(client, INDYCAM_CONTROL, &ctrl_reg); 146 int ret = 0;
148 ctrl->agc = (ctrl_reg & INDYCAM_CONTROL_AGCENA) 147
149 ? INDYCAM_VALUE_ENABLED 148 switch (ctrl->type) {
150 : INDYCAM_VALUE_DISABLED; 149 case INDYCAM_CONTROL_AGC:
151 ctrl->awb = (ctrl_reg & INDYCAM_CONTROL_AWBCTL) 150 case INDYCAM_CONTROL_AWB:
152 ? INDYCAM_VALUE_ENABLED 151 ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
153 : INDYCAM_VALUE_DISABLED; 152 if (ret)
154 indycam_read_reg(client, INDYCAM_SHUTTER, 153 return -EIO;
155 (unsigned char *)&ctrl->shutter); 154 if (ctrl->type == INDYCAM_CONTROL_AGC)
156 indycam_read_reg(client, INDYCAM_GAIN, 155 ctrl->value = (reg & INDYCAM_CONTROL_AGCENA)
157 (unsigned char *)&ctrl->gain); 156 ? 1 : 0;
158 indycam_read_reg(client, INDYCAM_RED_BALANCE, 157 else
159 (unsigned char *)&ctrl->red_balance); 158 ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL)
160 indycam_read_reg(client, INDYCAM_BLUE_BALANCE, 159 ? 1 : 0;
161 (unsigned char *)&ctrl->blue_balance); 160 break;
162 indycam_read_reg(client, INDYCAM_RED_SATURATION, 161 case INDYCAM_CONTROL_SHUTTER:
163 (unsigned char *)&ctrl->red_saturation); 162 ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, &reg);
164 indycam_read_reg(client, INDYCAM_BLUE_SATURATION, 163 if (ret)
165 (unsigned char *)&ctrl->blue_saturation); 164 return -EIO;
166 indycam_read_reg(client, INDYCAM_GAMMA, 165 ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1);
167 (unsigned char *)&ctrl->gamma); 166 break;
167 case INDYCAM_CONTROL_GAIN:
168 ret = indycam_read_reg(client, INDYCAM_REG_GAIN, &reg);
169 if (ret)
170 return -EIO;
171 ctrl->value = (s32)reg;
172 break;
173 case INDYCAM_CONTROL_RED_BALANCE:
174 ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, &reg);
175 if (ret)
176 return -EIO;
177 ctrl->value = (s32)reg;
178 break;
179 case INDYCAM_CONTROL_BLUE_BALANCE:
180 ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, &reg);
181 if (ret)
182 return -EIO;
183 ctrl->value = (s32)reg;
184 break;
185 case INDYCAM_CONTROL_RED_SATURATION:
186 ret = indycam_read_reg(client,
187 INDYCAM_REG_RED_SATURATION, &reg);
188 if (ret)
189 return -EIO;
190 ctrl->value = (s32)reg;
191 break;
192 case INDYCAM_CONTROL_BLUE_SATURATION:
193 ret = indycam_read_reg(client,
194 INDYCAM_REG_BLUE_SATURATION, &reg);
195 if (ret)
196 return -EIO;
197 ctrl->value = (s32)reg;
198 break;
199 case INDYCAM_CONTROL_GAMMA:
200 if (camera->version == CAMERA_VERSION_MOOSE) {
201 ret = indycam_read_reg(client,
202 INDYCAM_REG_GAMMA, &reg);
203 if (ret)
204 return -EIO;
205 ctrl->value = (s32)reg;
206 } else {
207 ctrl->value = INDYCAM_GAMMA_DEFAULT;
208 }
209 break;
210 default:
211 ret = -EINVAL;
212 }
168 213
169 return 0; 214 return ret;
170} 215}
171 216
172static int indycam_set_controls(struct i2c_client *client, 217static int indycam_set_control(struct i2c_client *client,
173 struct indycam_control *ctrl) 218 struct indycam_control *ctrl)
174{ 219{
175 unsigned char ctrl_reg; 220 struct indycam *camera = i2c_get_clientdata(client);
221 u8 reg;
222 int ret = 0;
223
224 switch (ctrl->type) {
225 case INDYCAM_CONTROL_AGC:
226 case INDYCAM_CONTROL_AWB:
227 ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
228 if (ret)
229 break;
176 230
177 indycam_read_reg(client, INDYCAM_CONTROL, &ctrl_reg); 231 if (ctrl->type == INDYCAM_CONTROL_AGC) {
178 if (ctrl->agc != INDYCAM_VALUE_UNCHANGED) { 232 if (ctrl->value)
179 if (ctrl->agc) 233 reg |= INDYCAM_CONTROL_AGCENA;
180 ctrl_reg |= INDYCAM_CONTROL_AGCENA; 234 else
181 else 235 reg &= ~INDYCAM_CONTROL_AGCENA;
182 ctrl_reg &= ~INDYCAM_CONTROL_AGCENA; 236 } else {
183 } 237 if (ctrl->value)
184 if (ctrl->awb != INDYCAM_VALUE_UNCHANGED) { 238 reg |= INDYCAM_CONTROL_AWBCTL;
185 if (ctrl->awb) 239 else
186 ctrl_reg |= INDYCAM_CONTROL_AWBCTL; 240 reg &= ~INDYCAM_CONTROL_AWBCTL;
187 else 241 }
188 ctrl_reg &= ~INDYCAM_CONTROL_AWBCTL; 242
243 ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg);
244 break;
245 case INDYCAM_CONTROL_SHUTTER:
246 reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1);
247 ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg);
248 break;
249 case INDYCAM_CONTROL_GAIN:
250 ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value);
251 break;
252 case INDYCAM_CONTROL_RED_BALANCE:
253 ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE,
254 ctrl->value);
255 break;
256 case INDYCAM_CONTROL_BLUE_BALANCE:
257 ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE,
258 ctrl->value);
259 break;
260 case INDYCAM_CONTROL_RED_SATURATION:
261 ret = indycam_write_reg(client, INDYCAM_REG_RED_SATURATION,
262 ctrl->value);
263 break;
264 case INDYCAM_CONTROL_BLUE_SATURATION:
265 ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION,
266 ctrl->value);
267 break;
268 case INDYCAM_CONTROL_GAMMA:
269 if (camera->version == CAMERA_VERSION_MOOSE) {
270 ret = indycam_write_reg(client, INDYCAM_REG_GAMMA,
271 ctrl->value);
272 }
273 break;
274 default:
275 ret = -EINVAL;
189 } 276 }
190 indycam_write_reg(client, INDYCAM_CONTROL, ctrl_reg);
191
192 if (ctrl->shutter >= 0)
193 indycam_write_reg(client, INDYCAM_SHUTTER, ctrl->shutter);
194 if (ctrl->gain >= 0)
195 indycam_write_reg(client, INDYCAM_GAIN, ctrl->gain);
196 if (ctrl->red_balance >= 0)
197 indycam_write_reg(client, INDYCAM_RED_BALANCE,
198 ctrl->red_balance);
199 if (ctrl->blue_balance >= 0)
200 indycam_write_reg(client, INDYCAM_BLUE_BALANCE,
201 ctrl->blue_balance);
202 if (ctrl->red_saturation >= 0)
203 indycam_write_reg(client, INDYCAM_RED_SATURATION,
204 ctrl->red_saturation);
205 if (ctrl->blue_saturation >= 0)
206 indycam_write_reg(client, INDYCAM_BLUE_SATURATION,
207 ctrl->blue_saturation);
208 if (ctrl->gamma >= 0)
209 indycam_write_reg(client, INDYCAM_GAMMA, ctrl->gamma);
210 277
211 return 0; 278 return ret;
212} 279}
213 280
214/* I2C-interface */ 281/* I2C-interface */
@@ -247,7 +314,8 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
247 if (err) 314 if (err)
248 goto out_free_camera; 315 goto out_free_camera;
249 316
250 camera->version = i2c_smbus_read_byte_data(client, INDYCAM_VERSION); 317 camera->version = i2c_smbus_read_byte_data(client,
318 INDYCAM_REG_VERSION);
251 if (camera->version != CAMERA_VERSION_INDY && 319 if (camera->version != CAMERA_VERSION_INDY &&
252 camera->version != CAMERA_VERSION_MOOSE) { 320 camera->version != CAMERA_VERSION_MOOSE) {
253 err = -ENODEV; 321 err = -ENODEV;
@@ -260,8 +328,7 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
260 indycam_regdump(client); 328 indycam_regdump(client);
261 329
262 // initialize 330 // initialize
263 err = indycam_write_block(client, 0, sizeof(initseq), 331 err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq);
264 (unsigned char *)&initseq);
265 if (err) { 332 if (err) {
266 printk(KERN_ERR "IndyCam initalization failed\n"); 333 printk(KERN_ERR "IndyCam initalization failed\n");
267 err = -EIO; 334 err = -EIO;
@@ -271,11 +338,10 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
271 indycam_regdump(client); 338 indycam_regdump(client);
272 339
273 // white balance 340 // white balance
274 err = indycam_write_reg(client, INDYCAM_CONTROL, 341 err = indycam_write_reg(client, INDYCAM_REG_CONTROL,
275 INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL); 342 INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
276 if (err) { 343 if (err) {
277 printk(KERN_ERR "IndyCam white balance " 344 printk(KERN_ERR "IndyCam: White balancing camera failed\n");
278 "initialization failed\n");
279 err = -EIO; 345 err = -EIO;
280 goto out_detach_client; 346 goto out_detach_client;
281 } 347 }
@@ -371,13 +437,11 @@ static int indycam_command(struct i2c_client *client, unsigned int cmd,
371 /* TODO: convert values for indycam_set_controls() */ 437 /* TODO: convert values for indycam_set_controls() */
372 break; 438 break;
373 } 439 }
374 case DECODER_INDYCAM_GET_CONTROLS: { 440 case DECODER_INDYCAM_GET_CONTROL: {
375 struct indycam_control *ctrl = arg; 441 return indycam_get_control(client, arg);
376 indycam_get_controls(client, ctrl);
377 } 442 }
378 case DECODER_INDYCAM_SET_CONTROLS: { 443 case DECODER_INDYCAM_SET_CONTROL: {
379 struct indycam_control *ctrl = arg; 444 return indycam_set_control(client, arg);
380 indycam_set_controls(client, ctrl);
381 } 445 }
382 default: 446 default:
383 return -EINVAL; 447 return -EINVAL;
@@ -388,12 +452,12 @@ static int indycam_command(struct i2c_client *client, unsigned int cmd,
388 452
389static struct i2c_driver i2c_driver_indycam = { 453static struct i2c_driver i2c_driver_indycam = {
390 .owner = THIS_MODULE, 454 .owner = THIS_MODULE,
391 .name = "indycam", 455 .name = "indycam",
392 .id = I2C_DRIVERID_INDYCAM, 456 .id = I2C_DRIVERID_INDYCAM,
393 .flags = I2C_DF_NOTIFY, 457 .flags = I2C_DF_NOTIFY,
394 .attach_adapter = indycam_probe, 458 .attach_adapter = indycam_probe,
395 .detach_client = indycam_detach, 459 .detach_client = indycam_detach,
396 .command = indycam_command, 460 .command = indycam_command,
397}; 461};
398 462
399static int __init indycam_init(void) 463static int __init indycam_init(void)
diff --git a/drivers/media/video/indycam.h b/drivers/media/video/indycam.h
index d9ddb6b79a03..e6ee82063ed8 100644
--- a/drivers/media/video/indycam.h
+++ b/drivers/media/video/indycam.h
@@ -22,21 +22,21 @@
22#define INDYCAM_VERSION_MINOR(x) ((x) & 0x0f) 22#define INDYCAM_VERSION_MINOR(x) ((x) & 0x0f)
23 23
24/* Register bus addresses */ 24/* Register bus addresses */
25#define INDYCAM_CONTROL 0x00 25#define INDYCAM_REG_CONTROL 0x00
26#define INDYCAM_SHUTTER 0x01 26#define INDYCAM_REG_SHUTTER 0x01
27#define INDYCAM_GAIN 0x02 27#define INDYCAM_REG_GAIN 0x02
28#define INDYCAM_BRIGHTNESS 0x03 /* read-only */ 28#define INDYCAM_REG_BRIGHTNESS 0x03 /* read-only */
29#define INDYCAM_RED_BALANCE 0x04 29#define INDYCAM_REG_RED_BALANCE 0x04
30#define INDYCAM_BLUE_BALANCE 0x05 30#define INDYCAM_REG_BLUE_BALANCE 0x05
31#define INDYCAM_RED_SATURATION 0x06 31#define INDYCAM_REG_RED_SATURATION 0x06
32#define INDYCAM_BLUE_SATURATION 0x07 32#define INDYCAM_REG_BLUE_SATURATION 0x07
33#define INDYCAM_GAMMA 0x08 33#define INDYCAM_REG_GAMMA 0x08
34#define INDYCAM_VERSION 0x0e /* read-only */ 34#define INDYCAM_REG_VERSION 0x0e /* read-only */
35#define INDYCAM_RESET 0x0f /* write-only */ 35#define INDYCAM_REG_RESET 0x0f /* write-only */
36 36
37#define INDYCAM_LED 0x46 37#define INDYCAM_REG_LED 0x46
38#define INDYCAM_ORIENTATION 0x47 38#define INDYCAM_REG_ORIENTATION 0x47
39#define INDYCAM_BUTTON 0x48 39#define INDYCAM_REG_BUTTON 0x48
40 40
41/* Field definitions of registers */ 41/* Field definitions of registers */
42#define INDYCAM_CONTROL_AGCENA (1<<0) /* automatic gain control */ 42#define INDYCAM_CONTROL_AGCENA (1<<0) /* automatic gain control */
@@ -59,13 +59,14 @@
59#define INDYCAM_ORIENTATION_BOTTOM_TO_TOP 0x40 59#define INDYCAM_ORIENTATION_BOTTOM_TO_TOP 0x40
60#define INDYCAM_BUTTON_RELEASED 0x10 60#define INDYCAM_BUTTON_RELEASED 0x10
61 61
62/* Values for controls */
62#define INDYCAM_SHUTTER_MIN 0x00 63#define INDYCAM_SHUTTER_MIN 0x00
63#define INDYCAM_SHUTTER_MAX 0xff 64#define INDYCAM_SHUTTER_MAX 0xff
64#define INDYCAM_GAIN_MIN 0x00 65#define INDYCAM_GAIN_MIN 0x00
65#define INDYCAM_GAIN_MAX 0xff 66#define INDYCAM_GAIN_MAX 0xff
66#define INDYCAM_RED_BALANCE_MIN 0x00 /* the effect is the opposite? */ 67#define INDYCAM_RED_BALANCE_MIN 0x00
67#define INDYCAM_RED_BALANCE_MAX 0xff 68#define INDYCAM_RED_BALANCE_MAX 0xff
68#define INDYCAM_BLUE_BALANCE_MIN 0x00 /* the effect is the opposite? */ 69#define INDYCAM_BLUE_BALANCE_MIN 0x00
69#define INDYCAM_BLUE_BALANCE_MAX 0xff 70#define INDYCAM_BLUE_BALANCE_MAX 0xff
70#define INDYCAM_RED_SATURATION_MIN 0x00 71#define INDYCAM_RED_SATURATION_MIN 0x00
71#define INDYCAM_RED_SATURATION_MAX 0xff 72#define INDYCAM_RED_SATURATION_MAX 0xff
@@ -74,34 +75,9 @@
74#define INDYCAM_GAMMA_MIN 0x00 75#define INDYCAM_GAMMA_MIN 0x00
75#define INDYCAM_GAMMA_MAX 0xff 76#define INDYCAM_GAMMA_MAX 0xff
76 77
77/* Driver interface definitions */ 78#define INDYCAM_AGC_DEFAULT 1
78 79#define INDYCAM_AWB_DEFAULT 0
79#define INDYCAM_VALUE_ENABLED 1 80#define INDYCAM_SHUTTER_DEFAULT 0xff
80#define INDYCAM_VALUE_DISABLED 0
81#define INDYCAM_VALUE_UNCHANGED -1
82
83/* When setting controls, a value of -1 leaves the control unchanged. */
84struct indycam_control {
85 int agc; /* boolean */
86 int awb; /* boolean */
87 int shutter;
88 int gain;
89 int red_balance;
90 int blue_balance;
91 int red_saturation;
92 int blue_saturation;
93 int gamma;
94};
95
96#define DECODER_INDYCAM_GET_CONTROLS _IOR('d', 193, struct indycam_control)
97#define DECODER_INDYCAM_SET_CONTROLS _IOW('d', 194, struct indycam_control)
98
99/* Default values for controls */
100
101#define INDYCAM_AGC_DEFAULT INDYCAM_VALUE_ENABLED
102#define INDYCAM_AWB_DEFAULT INDYCAM_VALUE_ENABLED
103
104#define INDYCAM_SHUTTER_DEFAULT INDYCAM_SHUTTER_60
105#define INDYCAM_GAIN_DEFAULT 0x80 81#define INDYCAM_GAIN_DEFAULT 0x80
106#define INDYCAM_RED_BALANCE_DEFAULT 0x18 82#define INDYCAM_RED_BALANCE_DEFAULT 0x18
107#define INDYCAM_BLUE_BALANCE_DEFAULT 0xa4 83#define INDYCAM_BLUE_BALANCE_DEFAULT 0xa4
@@ -109,4 +85,24 @@ struct indycam_control {
109#define INDYCAM_BLUE_SATURATION_DEFAULT 0xc0 85#define INDYCAM_BLUE_SATURATION_DEFAULT 0xc0
110#define INDYCAM_GAMMA_DEFAULT 0x80 86#define INDYCAM_GAMMA_DEFAULT 0x80
111 87
88/* Driver interface definitions */
89
90#define INDYCAM_CONTROL_AGC 0 /* boolean */
91#define INDYCAM_CONTROL_AWB 1 /* boolean */
92#define INDYCAM_CONTROL_SHUTTER 2
93#define INDYCAM_CONTROL_GAIN 3
94#define INDYCAM_CONTROL_RED_BALANCE 4
95#define INDYCAM_CONTROL_BLUE_BALANCE 5
96#define INDYCAM_CONTROL_RED_SATURATION 6
97#define INDYCAM_CONTROL_BLUE_SATURATION 7
98#define INDYCAM_CONTROL_GAMMA 8
99
100struct indycam_control {
101 u8 type;
102 s32 value;
103};
104
105#define DECODER_INDYCAM_GET_CONTROL _IOR('d', 193, struct indycam_control)
106#define DECODER_INDYCAM_SET_CONTROL _IOW('d', 194, struct indycam_control)
107
112#endif 108#endif
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index 234151e48edc..ed81934ef3cd 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -156,6 +156,71 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
156 156
157/* ---------------------------------------------------------------------- */ 157/* ---------------------------------------------------------------------- */
158 158
159/* Ricardo Cerqueira <v4l@cerqueira.org> */
160/* Weird matching, since the remote has "uncommon" keys */
161
162static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = {
163
164 [ 30 ] = KEY_POWER, // power
165 [ 7 ] = KEY_MEDIA, // source
166 [ 28 ] = KEY_SEARCH, // scan
167
168/* FIXME: duplicate keycodes?
169 *
170 * These four keys seem to share the same GPIO as CH+, CH-, <<< and >>>
171 * The GPIO values are
172 * 6397fb for both "Scan <" and "CH -",
173 * 639ffb for "Scan >" and "CH+",
174 * 6384fb for "Tune <" and "<<<",
175 * 638cfb for "Tune >" and ">>>", regardless of the mask.
176 *
177 * [ 23 ] = KEY_BACK, // fm scan <<
178 * [ 31 ] = KEY_FORWARD, // fm scan >>
179 *
180 * [ 4 ] = KEY_LEFT, // fm tuning <
181 * [ 12 ] = KEY_RIGHT, // fm tuning >
182 *
183 * For now, these four keys are disabled. Pressing them will generate
184 * the CH+/CH-/<<</>>> events
185 */
186
187 [ 3 ] = KEY_TUNER, // TV/FM
188
189 [ 0 ] = KEY_RECORD,
190 [ 8 ] = KEY_STOP,
191 [ 17 ] = KEY_PLAY,
192
193 [ 26 ] = KEY_PLAYPAUSE, // freeze
194 [ 25 ] = KEY_ZOOM, // zoom
195 [ 15 ] = KEY_TEXT, // min
196
197 [ 1 ] = KEY_KP1,
198 [ 11 ] = KEY_KP2,
199 [ 27 ] = KEY_KP3,
200 [ 5 ] = KEY_KP4,
201 [ 9 ] = KEY_KP5,
202 [ 21 ] = KEY_KP6,
203 [ 6 ] = KEY_KP7,
204 [ 10 ] = KEY_KP8,
205 [ 18 ] = KEY_KP9,
206 [ 2 ] = KEY_KP0,
207 [ 16 ] = KEY_LAST, // +100
208 [ 19 ] = KEY_LIST, // recall
209
210 [ 31 ] = KEY_CHANNELUP, // chn down
211 [ 23 ] = KEY_CHANNELDOWN, // chn up
212 [ 22 ] = KEY_VOLUMEUP, // vol down
213 [ 20 ] = KEY_VOLUMEDOWN, // vol up
214
215 [ 4 ] = KEY_KPMINUS, // <<<
216 [ 14 ] = KEY_SETUP, // function
217 [ 12 ] = KEY_KPPLUS, // >>>
218
219 [ 13 ] = KEY_GOTO, // mts
220 [ 29 ] = KEY_REFRESH, // reset
221 [ 24 ] = KEY_MUTE // mute/unmute
222};
223
159struct IR { 224struct IR {
160 struct bttv_sub_device *sub; 225 struct bttv_sub_device *sub;
161 struct input_dev *input; 226 struct input_dev *input;
@@ -282,53 +347,59 @@ static int ir_probe(struct device *dev)
282 347
283 /* detect & configure */ 348 /* detect & configure */
284 switch (sub->core->type) { 349 switch (sub->core->type) {
285 case BTTV_AVERMEDIA: 350 case BTTV_BOARD_AVERMEDIA:
286 case BTTV_AVPHONE98: 351 case BTTV_BOARD_AVPHONE98:
287 case BTTV_AVERMEDIA98: 352 case BTTV_BOARD_AVERMEDIA98:
288 ir_codes = ir_codes_avermedia; 353 ir_codes = ir_codes_avermedia;
289 ir->mask_keycode = 0xf88000; 354 ir->mask_keycode = 0xf88000;
290 ir->mask_keydown = 0x010000; 355 ir->mask_keydown = 0x010000;
291 ir->polling = 50; // ms 356 ir->polling = 50; // ms
292 break; 357 break;
293 358
294 case BTTV_AVDVBT_761: 359 case BTTV_BOARD_AVDVBT_761:
295 case BTTV_AVDVBT_771: 360 case BTTV_BOARD_AVDVBT_771:
296 ir_codes = ir_codes_avermedia_dvbt; 361 ir_codes = ir_codes_avermedia_dvbt;
297 ir->mask_keycode = 0x0f00c0; 362 ir->mask_keycode = 0x0f00c0;
298 ir->mask_keydown = 0x000020; 363 ir->mask_keydown = 0x000020;
299 ir->polling = 50; // ms 364 ir->polling = 50; // ms
300 break; 365 break;
301 366
302 case BTTV_PXELVWPLTVPAK: 367 case BTTV_BOARD_PXELVWPLTVPAK:
303 ir_codes = ir_codes_pixelview; 368 ir_codes = ir_codes_pixelview;
304 ir->mask_keycode = 0x003e00; 369 ir->mask_keycode = 0x003e00;
305 ir->mask_keyup = 0x010000; 370 ir->mask_keyup = 0x010000;
306 ir->polling = 50; // ms 371 ir->polling = 50; // ms
307 break; 372 break;
308 case BTTV_PV_BT878P_9B: 373 case BTTV_BOARD_PV_BT878P_9B:
309 case BTTV_PV_BT878P_PLUS: 374 case BTTV_BOARD_PV_BT878P_PLUS:
310 ir_codes = ir_codes_pixelview; 375 ir_codes = ir_codes_pixelview;
311 ir->mask_keycode = 0x001f00; 376 ir->mask_keycode = 0x001f00;
312 ir->mask_keyup = 0x008000; 377 ir->mask_keyup = 0x008000;
313 ir->polling = 50; // ms 378 ir->polling = 50; // ms
314 break; 379 break;
315 380
316 case BTTV_WINFAST2000: 381 case BTTV_BOARD_WINFAST2000:
317 ir_codes = ir_codes_winfast; 382 ir_codes = ir_codes_winfast;
318 ir->mask_keycode = 0x1f8; 383 ir->mask_keycode = 0x1f8;
319 break; 384 break;
320 case BTTV_MAGICTVIEW061: 385 case BTTV_BOARD_MAGICTVIEW061:
321 case BTTV_MAGICTVIEW063: 386 case BTTV_BOARD_MAGICTVIEW063:
322 ir_codes = ir_codes_winfast; 387 ir_codes = ir_codes_winfast;
323 ir->mask_keycode = 0x0008e000; 388 ir->mask_keycode = 0x0008e000;
324 ir->mask_keydown = 0x00200000; 389 ir->mask_keydown = 0x00200000;
325 break; 390 break;
326 case BTTV_APAC_VIEWCOMP: 391 case BTTV_BOARD_APAC_VIEWCOMP:
327 ir_codes = ir_codes_apac_viewcomp; 392 ir_codes = ir_codes_apac_viewcomp;
328 ir->mask_keycode = 0x001f00; 393 ir->mask_keycode = 0x001f00;
329 ir->mask_keyup = 0x008000; 394 ir->mask_keyup = 0x008000;
330 ir->polling = 50; // ms 395 ir->polling = 50; // ms
331 break; 396 break;
397 case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
398 ir_codes = ir_codes_conceptronic;
399 ir->mask_keycode = 0x001F00;
400 ir->mask_keyup = 0x006000;
401 ir->polling = 50; // ms
402 break;
332 } 403 }
333 if (NULL == ir_codes) { 404 if (NULL == ir_codes) {
334 kfree(ir); 405 kfree(ir);
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 9703d3d351f9..0085567a1421 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -8,6 +8,8 @@
8 * Christoph Bartelmus <lirc@bartelmus.de> 8 * Christoph Bartelmus <lirc@bartelmus.de>
9 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by 9 * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
10 * Ulrich Mueller <ulrich.mueller42@web.de> 10 * Ulrich Mueller <ulrich.mueller42@web.de>
11 * modified for em2820 based USB TV tuners by
12 * Markus Rechberger <mrechberger@gmail.com>
11 * 13 *
12 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -37,10 +39,9 @@
37#include <linux/slab.h> 39#include <linux/slab.h>
38#include <linux/i2c.h> 40#include <linux/i2c.h>
39#include <linux/workqueue.h> 41#include <linux/workqueue.h>
40
41#include <asm/semaphore.h> 42#include <asm/semaphore.h>
42
43#include <media/ir-common.h> 43#include <media/ir-common.h>
44#include <media/ir-kbd-i2c.h>
44 45
45/* Mark Phalan <phalanm@o2.ie> */ 46/* Mark Phalan <phalanm@o2.ie> */
46static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = { 47static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
@@ -81,57 +82,6 @@ static IR_KEYTAB_TYPE ir_codes_pv951[IR_KEYTAB_SIZE] = {
81 [ 28 ] = KEY_MEDIA, /* PC/TV */ 82 [ 28 ] = KEY_MEDIA, /* PC/TV */
82}; 83};
83 84
84static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
85 [ 0x3 ] = KEY_POWER,
86 [ 0x6f ] = KEY_MUTE,
87 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
88
89 [ 0x11 ] = KEY_KP0,
90 [ 0x4 ] = KEY_KP1,
91 [ 0x5 ] = KEY_KP2,
92 [ 0x6 ] = KEY_KP3,
93 [ 0x8 ] = KEY_KP4,
94 [ 0x9 ] = KEY_KP5,
95 [ 0xa ] = KEY_KP6,
96 [ 0xc ] = KEY_KP7,
97 [ 0xd ] = KEY_KP8,
98 [ 0xe ] = KEY_KP9,
99 [ 0x12 ] = KEY_KPDOT, /* 100+ */
100
101 [ 0x7 ] = KEY_VOLUMEUP,
102 [ 0xb ] = KEY_VOLUMEDOWN,
103 [ 0x1a ] = KEY_KPPLUS,
104 [ 0x18 ] = KEY_KPMINUS,
105 [ 0x15 ] = KEY_UP,
106 [ 0x1d ] = KEY_DOWN,
107 [ 0xf ] = KEY_CHANNELUP,
108 [ 0x13 ] = KEY_CHANNELDOWN,
109 [ 0x48 ] = KEY_ZOOM,
110
111 [ 0x1b ] = KEY_VIDEO, /* Video source */
112 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
113 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
114
115 [ 0x4b ] = KEY_RECORD,
116 [ 0x46 ] = KEY_PLAY,
117 [ 0x45 ] = KEY_PAUSE, /* Pause */
118 [ 0x44 ] = KEY_STOP,
119 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
120 [ 0x42 ] = KEY_REWIND, /* Backward ? */
121
122};
123
124struct IR {
125 struct i2c_client c;
126 struct input_dev *input;
127 struct ir_input_state ir;
128
129 struct work_struct work;
130 struct timer_list timer;
131 char phys[32];
132 int (*get_key)(struct IR*, u32*, u32*);
133};
134
135/* ----------------------------------------------------------------------- */ 85/* ----------------------------------------------------------------------- */
136/* insmod parameters */ 86/* insmod parameters */
137 87
@@ -144,7 +94,7 @@ module_param(debug, int, 0644); /* debug level (0,1,2) */
144 94
145/* ----------------------------------------------------------------------- */ 95/* ----------------------------------------------------------------------- */
146 96
147static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw) 97static int get_key_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
148{ 98{
149 unsigned char buf[3]; 99 unsigned char buf[3];
150 int start, toggle, dev, code; 100 int start, toggle, dev, code;
@@ -171,9 +121,9 @@ static int get_key_haup(struct IR *ir, u32 *ir_key, u32 *ir_raw)
171 return 1; 121 return 1;
172} 122}
173 123
174static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw) 124static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
175{ 125{
176 unsigned char b; 126 unsigned char b;
177 127
178 /* poll IR chip */ 128 /* poll IR chip */
179 if (1 != i2c_master_recv(&ir->c,&b,1)) { 129 if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -185,9 +135,9 @@ static int get_key_pixelview(struct IR *ir, u32 *ir_key, u32 *ir_raw)
185 return 1; 135 return 1;
186} 136}
187 137
188static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw) 138static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
189{ 139{
190 unsigned char b; 140 unsigned char b;
191 141
192 /* poll IR chip */ 142 /* poll IR chip */
193 if (1 != i2c_master_recv(&ir->c,&b,1)) { 143 if (1 != i2c_master_recv(&ir->c,&b,1)) {
@@ -205,7 +155,7 @@ static int get_key_pv951(struct IR *ir, u32 *ir_key, u32 *ir_raw)
205 return 1; 155 return 1;
206} 156}
207 157
208static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw) 158static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
209{ 159{
210 unsigned char b; 160 unsigned char b;
211 161
@@ -216,15 +166,15 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
216 } 166 }
217 167
218 /* it seems that 0xFE indicates that a button is still hold 168 /* it seems that 0xFE indicates that a button is still hold
219 down, while 0xFF indicates that no button is hold 169 down, while 0xff indicates that no button is hold
220 down. 0xFE sequences are sometimes interrupted by 0xFF */ 170 down. 0xfe sequences are sometimes interrupted by 0xFF */
221 171
222 dprintk(2,"key %02x\n", b); 172 dprintk(2,"key %02x\n", b);
223 173
224 if (b == 0xFF) 174 if (b == 0xff)
225 return 0; 175 return 0;
226 176
227 if (b == 0xFE) 177 if (b == 0xfe)
228 /* keep old data */ 178 /* keep old data */
229 return 1; 179 return 1;
230 180
@@ -233,31 +183,9 @@ static int get_key_knc1(struct IR *ir, u32 *ir_key, u32 *ir_raw)
233 return 1; 183 return 1;
234} 184}
235 185
236static int get_key_purpletv(struct IR *ir, u32 *ir_key, u32 *ir_raw)
237{
238 unsigned char b;
239
240 /* poll IR chip */
241 if (1 != i2c_master_recv(&ir->c,&b,1)) {
242 dprintk(1,"read error\n");
243 return -EIO;
244 }
245
246 /* no button press */
247 if (b==0)
248 return 0;
249
250 /* repeating */
251 if (b & 0x80)
252 return 1;
253
254 *ir_key = b;
255 *ir_raw = b;
256 return 1;
257}
258/* ----------------------------------------------------------------------- */ 186/* ----------------------------------------------------------------------- */
259 187
260static void ir_key_poll(struct IR *ir) 188static void ir_key_poll(struct IR_i2c *ir)
261{ 189{
262 static u32 ir_key, ir_raw; 190 static u32 ir_key, ir_raw;
263 int rc; 191 int rc;
@@ -278,13 +206,13 @@ static void ir_key_poll(struct IR *ir)
278 206
279static void ir_timer(unsigned long data) 207static void ir_timer(unsigned long data)
280{ 208{
281 struct IR *ir = (struct IR*)data; 209 struct IR_i2c *ir = (struct IR_i2c*)data;
282 schedule_work(&ir->work); 210 schedule_work(&ir->work);
283} 211}
284 212
285static void ir_work(void *data) 213static void ir_work(void *data)
286{ 214{
287 struct IR *ir = data; 215 struct IR_i2c *ir = data;
288 ir_key_poll(ir); 216 ir_key_poll(ir);
289 mod_timer(&ir->timer, jiffies+HZ/10); 217 mod_timer(&ir->timer, jiffies+HZ/10);
290} 218}
@@ -297,17 +225,17 @@ static int ir_detach(struct i2c_client *client);
297static int ir_probe(struct i2c_adapter *adap); 225static int ir_probe(struct i2c_adapter *adap);
298 226
299static struct i2c_driver driver = { 227static struct i2c_driver driver = {
300 .name = "ir remote kbd driver", 228 .name = "ir remote kbd driver",
301 .id = I2C_DRIVERID_EXP3, /* FIXME */ 229 .id = I2C_DRIVERID_EXP3, /* FIXME */
302 .flags = I2C_DF_NOTIFY, 230 .flags = I2C_DF_NOTIFY,
303 .attach_adapter = ir_probe, 231 .attach_adapter = ir_probe,
304 .detach_client = ir_detach, 232 .detach_client = ir_detach,
305}; 233};
306 234
307static struct i2c_client client_template = 235static struct i2c_client client_template =
308{ 236{
309 .name = "unset", 237 .name = "unset",
310 .driver = &driver 238 .driver = &driver
311}; 239};
312 240
313static int ir_attach(struct i2c_adapter *adap, int addr, 241static int ir_attach(struct i2c_adapter *adap, int addr,
@@ -316,10 +244,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
316 IR_KEYTAB_TYPE *ir_codes = NULL; 244 IR_KEYTAB_TYPE *ir_codes = NULL;
317 char *name; 245 char *name;
318 int ir_type; 246 int ir_type;
319 struct IR *ir; 247 struct IR_i2c *ir;
320 struct input_dev *input_dev; 248 struct input_dev *input_dev;
321 249
322 ir = kzalloc(sizeof(struct IR), GFP_KERNEL); 250 ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
323 input_dev = input_allocate_device(); 251 input_dev = input_allocate_device();
324 if (!ir || !input_dev) { 252 if (!ir || !input_dev) {
325 kfree(ir); 253 kfree(ir);
@@ -361,10 +289,10 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
361 ir_codes = ir_codes_empty; 289 ir_codes = ir_codes_empty;
362 break; 290 break;
363 case 0x7a: 291 case 0x7a:
364 name = "Purple TV"; 292 case 0x47:
365 ir->get_key = get_key_purpletv; 293 /* Handled by saa7134-input */
294 name = "SAA713x remote";
366 ir_type = IR_TYPE_OTHER; 295 ir_type = IR_TYPE_OTHER;
367 ir_codes = ir_codes_purpletv;
368 break; 296 break;
369 default: 297 default:
370 /* shouldn't happen */ 298 /* shouldn't happen */
@@ -373,9 +301,24 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
373 return -1; 301 return -1;
374 } 302 }
375 303
376 /* register i2c device */ 304 /* Sets name */
377 i2c_attach_client(&ir->c);
378 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name); 305 snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
306 ir->ir_codes=ir_codes;
307
308 /* register i2c device
309 * At device register, IR codes may be changed to be
310 * board dependent.
311 */
312 i2c_attach_client(&ir->c);
313
314 /* If IR not supported or disabled, unregisters driver */
315 if (ir->get_key == NULL) {
316 i2c_detach_client(&ir->c);
317 kfree(ir);
318 return -1;
319 }
320
321 /* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */
379 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0", 322 snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
380 ir->c.adapter->dev.bus_id, 323 ir->c.adapter->dev.bus_id,
381 ir->c.dev.bus_id); 324 ir->c.dev.bus_id);
@@ -386,6 +329,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
386 input_dev->name = ir->c.name; 329 input_dev->name = ir->c.name;
387 input_dev->phys = ir->phys; 330 input_dev->phys = ir->phys;
388 331
332 /* register event device */
389 input_register_device(ir->input); 333 input_register_device(ir->input);
390 334
391 /* start polling via eventd */ 335 /* start polling via eventd */
@@ -400,7 +344,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
400 344
401static int ir_detach(struct i2c_client *client) 345static int ir_detach(struct i2c_client *client)
402{ 346{
403 struct IR *ir = i2c_get_clientdata(client); 347 struct IR_i2c *ir = i2c_get_clientdata(client);
404 348
405 /* kill outstanding polls */ 349 /* kill outstanding polls */
406 del_timer(&ir->timer); 350 del_timer(&ir->timer);
@@ -428,9 +372,12 @@ static int ir_probe(struct i2c_adapter *adap)
428 */ 372 */
429 373
430 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1}; 374 static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
431 static const int probe_saa7134[] = { 0x7a, -1 }; 375 static const int probe_saa7134[] = { 0x7a, 0x47, -1 };
376 static const int probe_em28XX[] = { 0x30, 0x47, -1 };
432 const int *probe = NULL; 377 const int *probe = NULL;
433 struct i2c_client c; char buf; int i,rc; 378 struct i2c_client c;
379 unsigned char buf;
380 int i,rc;
434 381
435 switch (adap->id) { 382 switch (adap->id) {
436 case I2C_HW_B_BT848: 383 case I2C_HW_B_BT848:
@@ -439,6 +386,9 @@ static int ir_probe(struct i2c_adapter *adap)
439 case I2C_HW_SAA7134: 386 case I2C_HW_SAA7134:
440 probe = probe_saa7134; 387 probe = probe_saa7134;
441 break; 388 break;
389 case I2C_HW_B_EM28XX:
390 probe = probe_em28XX;
391 break;
442 } 392 }
443 if (NULL == probe) 393 if (NULL == probe)
444 return 0; 394 return 0;
@@ -447,11 +397,11 @@ static int ir_probe(struct i2c_adapter *adap)
447 c.adapter = adap; 397 c.adapter = adap;
448 for (i = 0; -1 != probe[i]; i++) { 398 for (i = 0; -1 != probe[i]; i++) {
449 c.addr = probe[i]; 399 c.addr = probe[i];
450 rc = i2c_master_recv(&c,&buf,1); 400 rc = i2c_master_recv(&c,&buf,0);
451 dprintk(1,"probe 0x%02x @ %s: %s\n", 401 dprintk(1,"probe 0x%02x @ %s: %s\n",
452 probe[i], adap->name, 402 probe[i], adap->name,
453 (1 == rc) ? "yes" : "no"); 403 (0 == rc) ? "yes" : "no");
454 if (1 == rc) { 404 if (0 == rc) {
455 ir_attach(adap,probe[i],0,0); 405 ir_attach(adap,probe[i],0,0);
456 break; 406 break;
457 } 407 }
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index 262890cb20a7..a23fb0338986 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -54,9 +54,41 @@
54#include <asm/pgtable.h> 54#include <asm/pgtable.h>
55 55
56#include <media/audiochip.h> 56#include <media/audiochip.h>
57#include <media/id.h>
58#include "msp3400.h" 57#include "msp3400.h"
59 58
59#define msp3400_dbg(fmt, arg...) \
60 do { \
61 if (debug) \
62 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
63 i2c_adapter_id(client->adapter), client->addr , ## arg); \
64 } while (0)
65
66/* Medium volume debug. */
67#define msp3400_dbg_mediumvol(fmt, arg...) \
68 do { \
69 if (debug >= 2) \
70 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
71 i2c_adapter_id(client->adapter), client->addr , ## arg); \
72 } while (0)
73
74/* High volume debug. Use with care. */
75#define msp3400_dbg_highvol(fmt, arg...) \
76 do { \
77 if (debug >= 16) \
78 printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
79 i2c_adapter_id(client->adapter), client->addr , ## arg); \
80 } while (0)
81
82#define msp3400_err(fmt, arg...) do { \
83 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
84 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
85#define msp3400_warn(fmt, arg...) do { \
86 printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \
87 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
88#define msp3400_info(fmt, arg...) do { \
89 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
90 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
91
60#define OPMODE_AUTO -1 92#define OPMODE_AUTO -1
61#define OPMODE_MANUAL 0 93#define OPMODE_MANUAL 0
62#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ 94#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */
@@ -73,15 +105,26 @@ static int dolby = 0;
73 105
74static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual 106static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual
75 (msp34xxg only) 0x00a0-0x03c0 */ 107 (msp34xxg only) 0x00a0-0x03c0 */
108#define DFP_COUNT 0x41
109static const int bl_dfp[] = {
110 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a,
111 0x0b, 0x0d, 0x0e, 0x10
112};
113
114#define IS_MSP34XX_G(msp) ((msp)->opmode==2)
76 115
77struct msp3400c { 116struct msp3400c {
78 int rev1,rev2; 117 int rev1,rev2;
79 118
80 int opmode; 119 int opmode;
120 int nicam;
81 int mode; 121 int mode;
82 int norm; 122 int norm;
123 int stereo;
83 int nicam_on; 124 int nicam_on;
84 int acb; 125 int acb;
126 int in_scart;
127 int i2s_mode;
85 int main, second; /* sound carrier */ 128 int main, second; /* sound carrier */
86 int input; 129 int input;
87 int source; /* see msp34xxg_set_source */ 130 int source; /* see msp34xxg_set_source */
@@ -91,9 +134,12 @@ struct msp3400c {
91 int rxsubchans; 134 int rxsubchans;
92 135
93 int muted; 136 int muted;
94 int volume, balance; 137 int left, right; /* volume */
95 int bass, treble; 138 int bass, treble;
96 139
140 /* shadow register set */
141 int dfp_regs[DFP_COUNT];
142
97 /* thread */ 143 /* thread */
98 struct task_struct *kthread; 144 struct task_struct *kthread;
99 wait_queue_head_t wq; 145 wait_queue_head_t wq;
@@ -101,6 +147,8 @@ struct msp3400c {
101 int watch_stereo:1; 147 int watch_stereo:1;
102}; 148};
103 149
150#define MIN(a,b) (((a)>(b))?(b):(a))
151#define MAX(a,b) (((a)>(b))?(a):(b))
104#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) 152#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00)
105#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') 153#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@')
106#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') 154#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@')
@@ -110,9 +158,6 @@ struct msp3400c {
110 158
111/* ---------------------------------------------------------------------- */ 159/* ---------------------------------------------------------------------- */
112 160
113#define dprintk if (debug >= 1) printk
114#define d2printk if (debug >= 2) printk
115
116/* read-only */ 161/* read-only */
117module_param(opmode, int, 0444); 162module_param(opmode, int, 0444);
118 163
@@ -132,11 +177,6 @@ MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Defau
132MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); 177MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
133MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); 178MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
134 179
135
136MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
137MODULE_AUTHOR("Gerd Knorr");
138MODULE_LICENSE("Dual BSD/GPL"); /* FreeBSD uses this too */
139
140/* ---------------------------------------------------------------------- */ 180/* ---------------------------------------------------------------------- */
141 181
142#define I2C_MSP3400C 0x80 182#define I2C_MSP3400C 0x80
@@ -153,6 +193,10 @@ static unsigned short normal_i2c[] = {
153}; 193};
154I2C_CLIENT_INSMOD; 194I2C_CLIENT_INSMOD;
155 195
196MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
197MODULE_AUTHOR("Gerd Knorr");
198MODULE_LICENSE("GPL");
199
156/* ----------------------------------------------------------------------- */ 200/* ----------------------------------------------------------------------- */
157/* functions for talking to the MSP3400C Sound processor */ 201/* functions for talking to the MSP3400C Sound processor */
158 202
@@ -172,68 +216,73 @@ static int msp3400c_reset(struct i2c_client *client)
172 { client->addr, I2C_M_RD, 2, read }, 216 { client->addr, I2C_M_RD, 2, read },
173 }; 217 };
174 218
219 msp3400_dbg_highvol("msp3400c_reset\n");
175 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || 220 if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) ||
176 (1 != i2c_transfer(client->adapter,&reset[1],1)) || 221 (1 != i2c_transfer(client->adapter,&reset[1],1)) ||
177 (2 != i2c_transfer(client->adapter,test,2)) ) { 222 (2 != i2c_transfer(client->adapter,test,2)) ) {
178 printk(KERN_ERR "msp3400: chip reset failed\n"); 223 msp3400_err("chip reset failed\n");
179 return -1; 224 return -1;
180 } 225 }
181 return 0; 226 return 0;
182} 227}
183 228
184static int 229static int msp3400c_read(struct i2c_client *client, int dev, int addr)
185msp3400c_read(struct i2c_client *client, int dev, int addr)
186{ 230{
187 int err; 231 int err,retval;
232
233 unsigned char write[3];
234 unsigned char read[2];
235 struct i2c_msg msgs[2] = {
236 { client->addr, 0, 3, write },
237 { client->addr, I2C_M_RD, 2, read }
238 };
188 239
189 unsigned char write[3]; 240 write[0] = dev+1;
190 unsigned char read[2]; 241 write[1] = addr >> 8;
191 struct i2c_msg msgs[2] = { 242 write[2] = addr & 0xff;
192 { client->addr, 0, 3, write },
193 { client->addr, I2C_M_RD, 2, read }
194 };
195 write[0] = dev+1;
196 write[1] = addr >> 8;
197 write[2] = addr & 0xff;
198 243
199 for (err = 0; err < 3;) { 244 for (err = 0; err < 3;) {
200 if (2 == i2c_transfer(client->adapter,msgs,2)) 245 if (2 == i2c_transfer(client->adapter,msgs,2))
201 break; 246 break;
202 err++; 247 err++;
203 printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)\n", 248 msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err,
204 err, dev, addr); 249 dev, addr);
205 msleep(10); 250 current->state = TASK_INTERRUPTIBLE;
251 schedule_timeout(msecs_to_jiffies(10));
206 } 252 }
207 if (3 == err) { 253 if (3 == err) {
208 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); 254 msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n");
209 msp3400c_reset(client); 255 msp3400c_reset(client);
210 return -1; 256 return -1;
211 } 257 }
212 return read[0] << 8 | read[1]; 258 retval = read[0] << 8 | read[1];
259 msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval);
260 return retval;
213} 261}
214 262
215static int 263static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
216msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
217{ 264{
218 int err; 265 int err;
219 unsigned char buffer[5]; 266 unsigned char buffer[5];
220 267
221 buffer[0] = dev; 268 buffer[0] = dev;
222 buffer[1] = addr >> 8; 269 buffer[1] = addr >> 8;
223 buffer[2] = addr & 0xff; 270 buffer[2] = addr & 0xff;
224 buffer[3] = val >> 8; 271 buffer[3] = val >> 8;
225 buffer[4] = val & 0xff; 272 buffer[4] = val & 0xff;
226 273
274 msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val);
227 for (err = 0; err < 3;) { 275 for (err = 0; err < 3;) {
228 if (5 == i2c_master_send(client, buffer, 5)) 276 if (5 == i2c_master_send(client, buffer, 5))
229 break; 277 break;
230 err++; 278 err++;
231 printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)\n", 279 msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err,
232 err, dev, addr); 280 dev, addr);
233 msleep(10); 281 current->state = TASK_INTERRUPTIBLE;
282 schedule_timeout(msecs_to_jiffies(10));
234 } 283 }
235 if (3 == err) { 284 if (3 == err) {
236 printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|\n"); 285 msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n");
237 msp3400c_reset(client); 286 msp3400c_reset(client);
238 return -1; 287 return -1;
239 } 288 }
@@ -266,45 +315,47 @@ static struct MSP_INIT_DATA_DEM {
266 int dfp_src; 315 int dfp_src;
267 int dfp_matrix; 316 int dfp_matrix;
268} msp_init_data[] = { 317} msp_init_data[] = {
269 /* AM (for carrier detect / msp3400) */ 318 { /* AM (for carrier detect / msp3400) */
270 { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 }, 319 {75, 19, 36, 35, 39, 40},
271 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 320 {75, 19, 36, 35, 39, 40},
272 0x00d0, 0x0500, 0x0020, 0x3000}, 321 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
273 322 0x00d0, 0x0500, 0x0020, 0x3000
274 /* AM (for carrier detect / msp3410) */ 323 },{ /* AM (for carrier detect / msp3410) */
275 { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 }, 324 {-1, -1, -8, 2, 59, 126},
276 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 325 {-1, -1, -8, 2, 59, 126},
277 0x00d0, 0x0100, 0x0020, 0x3000}, 326 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
278 327 0x00d0, 0x0100, 0x0020, 0x3000
279 /* FM Radio */ 328 },{ /* FM Radio */
280 { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 }, 329 {-8, -8, 4, 6, 78, 107},
281 MSP_CARRIER(10.7), MSP_CARRIER(10.7), 330 {-8, -8, 4, 6, 78, 107},
282 0x00d0, 0x0480, 0x0020, 0x3000 }, 331 MSP_CARRIER(10.7), MSP_CARRIER(10.7),
283 332 0x00d0, 0x0480, 0x0020, 0x3000
284 /* Terrestial FM-mono + FM-stereo */ 333 },{ /* Terrestial FM-mono + FM-stereo */
285 { { 3, 18, 27, 48, 66, 72 }, { 3, 18, 27, 48, 66, 72 }, 334 {3, 18, 27, 48, 66, 72},
286 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 335 {3, 18, 27, 48, 66, 72},
287 0x00d0, 0x0480, 0x0030, 0x3000}, 336 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
288 337 0x00d0, 0x0480, 0x0030, 0x3000
289 /* Sat FM-mono */ 338 },{ /* Sat FM-mono */
290 { { 1, 9, 14, 24, 33, 37 }, { 3, 18, 27, 48, 66, 72 }, 339 { 1, 9, 14, 24, 33, 37},
291 MSP_CARRIER(6.5), MSP_CARRIER(6.5), 340 { 3, 18, 27, 48, 66, 72},
292 0x00c6, 0x0480, 0x0000, 0x3000}, 341 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
293 342 0x00c6, 0x0480, 0x0000, 0x3000
294 /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ 343 },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */
295 { { -2, -8, -10, 10, 50, 86 }, { 3, 18, 27, 48, 66, 72 }, 344 {-2, -8, -10, 10, 50, 86},
296 MSP_CARRIER(5.5), MSP_CARRIER(5.5), 345 {3, 18, 27, 48, 66, 72},
297 0x00d0, 0x0040, 0x0120, 0x3000}, 346 MSP_CARRIER(5.5), MSP_CARRIER(5.5),
298 347 0x00d0, 0x0040, 0x0120, 0x3000
299 /* NICAM/FM -- I (6.0/6.552) */ 348 },{ /* NICAM/FM -- I (6.0/6.552) */
300 { { 2, 4, -6, -4, 40, 94 }, { 3, 18, 27, 48, 66, 72 }, 349 {2, 4, -6, -4, 40, 94},
301 MSP_CARRIER(6.0), MSP_CARRIER(6.0), 350 {3, 18, 27, 48, 66, 72},
302 0x00d0, 0x0040, 0x0120, 0x3000}, 351 MSP_CARRIER(6.0), MSP_CARRIER(6.0),
303 352 0x00d0, 0x0040, 0x0120, 0x3000
304 /* NICAM/AM -- L (6.5/5.85) */ 353 },{ /* NICAM/AM -- L (6.5/5.85) */
305 { { -2, -8, -10, 10, 50, 86 }, { -4, -12, -9, 23, 79, 126 }, 354 {-2, -8, -10, 10, 50, 86},
306 MSP_CARRIER(6.5), MSP_CARRIER(6.5), 355 {-4, -12, -9, 23, 79, 126},
307 0x00c6, 0x0140, 0x0120, 0x7c03}, 356 MSP_CARRIER(6.5), MSP_CARRIER(6.5),
357 0x00c6, 0x0140, 0x0120, 0x7c03
358 },
308}; 359};
309 360
310struct CARRIER_DETECT { 361struct CARRIER_DETECT {
@@ -338,32 +389,68 @@ static struct CARRIER_DETECT carrier_detect_65[] = {
338 389
339#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) 390#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
340 391
341/* ----------------------------------------------------------------------- */ 392/* ----------------------------------------------------------------------- *
393 * bits 9 8 5 - SCART DSP input Select:
394 * 0 0 0 - SCART 1 to DSP input (reset position)
395 * 0 1 0 - MONO to DSP input
396 * 1 0 0 - SCART 2 to DSP input
397 * 1 1 1 - Mute DSP input
398 *
399 * bits 11 10 6 - SCART 1 Output Select:
400 * 0 0 0 - undefined (reset position)
401 * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS)
402 * 1 0 0 - MONO input to SCART 1 Output
403 * 1 1 0 - SCART 1 DA to SCART 1 Output
404 * 0 0 1 - SCART 2 DA to SCART 1 Output
405 * 0 1 1 - SCART 1 Input to SCART 1 Output
406 * 1 1 1 - Mute SCART 1 Output
407 *
408 * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART):
409 * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position)
410 * 0 1 0 - SCART 1 Input to SCART 2 Output
411 * 1 0 0 - MONO input to SCART 2 Output
412 * 0 0 1 - SCART 2 DA to SCART 2 Output
413 * 0 1 1 - SCART 2 Input to SCART 2 Output
414 * 1 1 0 - Mute SCART 2 Output
415 *
416 * Bits 4 to 0 should be zero.
417 * ----------------------------------------------------------------------- */
342 418
343static int scarts[3][9] = { 419static int scarts[3][9] = {
344 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ 420 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */
345 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, 421 /* SCART DSP Input select */
346 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, 422 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 },
347 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, 423 /* SCART1 Output select */
424 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
425 /* SCART2 Output select */
426 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
348}; 427};
349 428
350static char *scart_names[] = { 429static char *scart_names[] = {
351 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" 430 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
352}; 431};
353 432
354static void 433static void msp3400c_set_scart(struct i2c_client *client, int in, int out)
355msp3400c_set_scart(struct i2c_client *client, int in, int out)
356{ 434{
357 struct msp3400c *msp = i2c_get_clientdata(client); 435 struct msp3400c *msp = i2c_get_clientdata(client);
358 436
359 if (-1 == scarts[out][in]) 437 msp->in_scart=in;
360 return; 438
439 if (in >= 1 && in <= 8 && out >= 0 && out <= 2) {
440 if (-1 == scarts[out][in])
441 return;
361 442
362 dprintk(KERN_DEBUG 443 msp->acb &= ~scarts[out][SCART_MASK];
363 "msp34xx: scart switch: %s => %d\n",scart_names[in],out); 444 msp->acb |= scarts[out][in];
364 msp->acb &= ~scarts[out][SCART_MASK]; 445 } else
365 msp->acb |= scarts[out][in]; 446 msp->acb = 0xf60; /* Mute Input and SCART 1 Output */
366 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb); 447
448 msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n",
449 scart_names[in], out, msp->acb);
450 msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb);
451
452 /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */
453 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
367} 454}
368 455
369/* ------------------------------------------------------------------------ */ 456/* ------------------------------------------------------------------------ */
@@ -378,33 +465,34 @@ static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
378} 465}
379 466
380static void msp3400c_setvolume(struct i2c_client *client, 467static void msp3400c_setvolume(struct i2c_client *client,
381 int muted, int volume, int balance) 468 int muted, int left, int right)
382{ 469 {
383 int val = 0, bal = 0; 470 int vol = 0, val = 0, balance = 0;
384 471
385 if (!muted) { 472 if (!muted) {
386 /* 0x7f instead if 0x73 here has sound quality issues, 473 /* 0x7f instead if 0x73 here has sound quality issues,
387 * probably due to overmodulation + clipping ... */ 474 * probably due to overmodulation + clipping ... */
388 val = (volume * 0x73 / 65535) << 8; 475 vol = (left > right) ? left : right;
476 val = (vol * 0x73 / 65535) << 8;
389 } 477 }
390 if (val) { 478 if (vol > 0) {
391 bal = (balance / 256) - 128; 479 balance = ((right - left) * 127) / vol;
392 } 480 }
393 dprintk(KERN_DEBUG 481
394 "msp34xx: setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", 482 msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n",
395 muted ? "on" : "off", volume, balance, val>>8, bal); 483 muted ? "on" : "off", left, right, val >> 8, balance);
396 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ 484 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
397 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ 485 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */
398 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, 486 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007,
399 muted ? 0x01 : (val | 0x01)); 487 muted ? 0x1 : (val | 0x1));
400 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, bal << 8); 488 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8);
401} 489}
402 490
403static void msp3400c_setbass(struct i2c_client *client, int bass) 491static void msp3400c_setbass(struct i2c_client *client, int bass)
404{ 492{
405 int val = ((bass-32768) * 0x60 / 65535) << 8; 493 int val = ((bass-32768) * 0x60 / 65535) << 8;
406 494
407 dprintk(KERN_DEBUG "msp34xx: setbass: %d 0x%02x\n",bass, val>>8); 495 msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8);
408 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ 496 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
409} 497}
410 498
@@ -412,7 +500,7 @@ static void msp3400c_settreble(struct i2c_client *client, int treble)
412{ 500{
413 int val = ((treble-32768) * 0x60 / 65535) << 8; 501 int val = ((treble-32768) * 0x60 / 65535) << 8;
414 502
415 dprintk(KERN_DEBUG "msp34xx: settreble: %d 0x%02x\n",treble, val>>8); 503 msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8);
416 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ 504 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
417} 505}
418 506
@@ -421,7 +509,7 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
421 struct msp3400c *msp = i2c_get_clientdata(client); 509 struct msp3400c *msp = i2c_get_clientdata(client);
422 int i; 510 int i;
423 511
424 dprintk(KERN_DEBUG "msp3400: setmode: %d\n",type); 512 msp3400_dbg("setmode: %d\n",type);
425 msp->mode = type; 513 msp->mode = type;
426 msp->audmode = V4L2_TUNER_MODE_MONO; 514 msp->audmode = V4L2_TUNER_MODE_MONO;
427 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 515 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -474,7 +562,8 @@ static void msp3400c_setmode(struct i2c_client *client, int type)
474 } 562 }
475} 563}
476 564
477static int best_audio_mode(int rxsubchans) 565/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */
566static int best_video_sound(int rxsubchans)
478{ 567{
479 if (rxsubchans & V4L2_TUNER_SUB_STEREO) 568 if (rxsubchans & V4L2_TUNER_SUB_STEREO)
480 return V4L2_TUNER_MODE_STEREO; 569 return V4L2_TUNER_MODE_STEREO;
@@ -486,31 +575,31 @@ static int best_audio_mode(int rxsubchans)
486} 575}
487 576
488/* turn on/off nicam + stereo */ 577/* turn on/off nicam + stereo */
489static void msp3400c_set_audmode(struct i2c_client *client, int audmode) 578static void msp3400c_setstereo(struct i2c_client *client, int mode)
490{ 579{
491 static char *strmode[16] = { 580 static char *strmode[] = { "0", "mono", "stereo", "3",
492#if __GNUC__ >= 3 581 "lang1", "5", "6", "7", "lang2"
493 [ 0 ... 15 ] = "invalid",
494#endif
495 [ V4L2_TUNER_MODE_MONO ] = "mono",
496 [ V4L2_TUNER_MODE_STEREO ] = "stereo",
497 [ V4L2_TUNER_MODE_LANG1 ] = "lang1",
498 [ V4L2_TUNER_MODE_LANG2 ] = "lang2",
499 }; 582 };
500 struct msp3400c *msp = i2c_get_clientdata(client); 583 struct msp3400c *msp = i2c_get_clientdata(client);
501 int nicam=0; /* channel source: FM/AM or nicam */ 584 int nicam = 0; /* channel source: FM/AM or nicam */
502 int src=0; 585 int src = 0;
503 586
504 BUG_ON(msp->opmode == OPMODE_SIMPLER); 587 if (IS_MSP34XX_G(msp)) {
505 msp->audmode = audmode; 588 /* this method would break everything, let's make sure
589 * it's never called
590 */
591 msp3400_dbg
592 ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n",
593 mode);
594 return;
595 }
506 596
507 /* switch demodulator */ 597 /* switch demodulator */
508 switch (msp->mode) { 598 switch (msp->mode) {
509 case MSP_MODE_FM_TERRA: 599 case MSP_MODE_FM_TERRA:
510 dprintk(KERN_DEBUG "msp3400: FM setstereo: %s\n", 600 msp3400_dbg("FM setstereo: %s\n", strmode[mode]);
511 strmode[audmode]);
512 msp3400c_setcarrier(client,msp->second,msp->main); 601 msp3400c_setcarrier(client,msp->second,msp->main);
513 switch (audmode) { 602 switch (mode) {
514 case V4L2_TUNER_MODE_STEREO: 603 case V4L2_TUNER_MODE_STEREO:
515 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); 604 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
516 break; 605 break;
@@ -522,9 +611,8 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
522 } 611 }
523 break; 612 break;
524 case MSP_MODE_FM_SAT: 613 case MSP_MODE_FM_SAT:
525 dprintk(KERN_DEBUG "msp3400: SAT setstereo: %s\n", 614 msp3400_dbg("SAT setstereo: %s\n", strmode[mode]);
526 strmode[audmode]); 615 switch (mode) {
527 switch (audmode) {
528 case V4L2_TUNER_MODE_MONO: 616 case V4L2_TUNER_MODE_MONO:
529 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); 617 msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
530 break; 618 break;
@@ -542,39 +630,35 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
542 case MSP_MODE_FM_NICAM1: 630 case MSP_MODE_FM_NICAM1:
543 case MSP_MODE_FM_NICAM2: 631 case MSP_MODE_FM_NICAM2:
544 case MSP_MODE_AM_NICAM: 632 case MSP_MODE_AM_NICAM:
545 dprintk(KERN_DEBUG "msp3400: NICAM setstereo: %s\n", 633 msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]);
546 strmode[audmode]);
547 msp3400c_setcarrier(client,msp->second,msp->main); 634 msp3400c_setcarrier(client,msp->second,msp->main);
548 if (msp->nicam_on) 635 if (msp->nicam_on)
549 nicam=0x0100; 636 nicam=0x0100;
550 break; 637 break;
551 case MSP_MODE_BTSC: 638 case MSP_MODE_BTSC:
552 dprintk(KERN_DEBUG "msp3400: BTSC setstereo: %s\n", 639 msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]);
553 strmode[audmode]);
554 nicam=0x0300; 640 nicam=0x0300;
555 break; 641 break;
556 case MSP_MODE_EXTERN: 642 case MSP_MODE_EXTERN:
557 dprintk(KERN_DEBUG "msp3400: extern setstereo: %s\n", 643 msp3400_dbg("extern setstereo: %s\n",strmode[mode]);
558 strmode[audmode]);
559 nicam = 0x0200; 644 nicam = 0x0200;
560 break; 645 break;
561 case MSP_MODE_FM_RADIO: 646 case MSP_MODE_FM_RADIO:
562 dprintk(KERN_DEBUG "msp3400: FM-Radio setstereo: %s\n", 647 msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]);
563 strmode[audmode]);
564 break; 648 break;
565 default: 649 default:
566 dprintk(KERN_DEBUG "msp3400: mono setstereo\n"); 650 msp3400_dbg("mono setstereo\n");
567 return; 651 return;
568 } 652 }
569 653
570 /* switch audio */ 654 /* switch audio */
571 switch (audmode) { 655 switch (best_video_sound(mode)) {
572 case V4L2_TUNER_MODE_STEREO: 656 case V4L2_TUNER_MODE_STEREO:
573 src = 0x0020 | nicam; 657 src = 0x0020 | nicam;
574 break; 658 break;
575 case V4L2_TUNER_MODE_MONO: 659 case V4L2_TUNER_MODE_MONO:
576 if (msp->mode == MSP_MODE_AM_NICAM) { 660 if (msp->mode == MSP_MODE_AM_NICAM) {
577 dprintk("msp3400: switching to AM mono\n"); 661 msp3400_dbg("switching to AM mono\n");
578 /* AM mono decoding is handled by tuner, not MSP chip */ 662 /* AM mono decoding is handled by tuner, not MSP chip */
579 /* SCART switching control register */ 663 /* SCART switching control register */
580 msp3400c_set_scart(client,SCART_MONO,0); 664 msp3400c_set_scart(client,SCART_MONO,0);
@@ -588,8 +672,7 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
588 src = 0x0010 | nicam; 672 src = 0x0010 | nicam;
589 break; 673 break;
590 } 674 }
591 dprintk(KERN_DEBUG 675 msp3400_dbg("setstereo final source/matrix = 0x%x\n", src);
592 "msp3400: setstereo final source/matrix = 0x%x\n", src);
593 676
594 if (dolby) { 677 if (dolby) {
595 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); 678 msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
@@ -605,29 +688,55 @@ static void msp3400c_set_audmode(struct i2c_client *client, int audmode)
605} 688}
606 689
607static void 690static void
608msp3400c_print_mode(struct msp3400c *msp) 691msp3400c_print_mode(struct i2c_client *client)
609{ 692{
693 struct msp3400c *msp = i2c_get_clientdata(client);
694
610 if (msp->main == msp->second) { 695 if (msp->main == msp->second) {
611 printk(KERN_DEBUG "msp3400: mono sound carrier: %d.%03d MHz\n", 696 msp3400_dbg("mono sound carrier: %d.%03d MHz\n",
612 msp->main/910000,(msp->main/910)%1000); 697 msp->main/910000,(msp->main/910)%1000);
613 } else { 698 } else {
614 printk(KERN_DEBUG "msp3400: main sound carrier: %d.%03d MHz\n", 699 msp3400_dbg("main sound carrier: %d.%03d MHz\n",
615 msp->main/910000,(msp->main/910)%1000); 700 msp->main/910000,(msp->main/910)%1000);
616 } 701 }
617 if (msp->mode == MSP_MODE_FM_NICAM1 || 702 if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2)
618 msp->mode == MSP_MODE_FM_NICAM2) 703 msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n",
619 printk(KERN_DEBUG "msp3400: NICAM/FM carrier : %d.%03d MHz\n",
620 msp->second/910000,(msp->second/910)%1000); 704 msp->second/910000,(msp->second/910)%1000);
621 if (msp->mode == MSP_MODE_AM_NICAM) 705 if (msp->mode == MSP_MODE_AM_NICAM)
622 printk(KERN_DEBUG "msp3400: NICAM/AM carrier : %d.%03d MHz\n", 706 msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n",
623 msp->second/910000,(msp->second/910)%1000); 707 msp->second/910000,(msp->second/910)%1000);
624 if (msp->mode == MSP_MODE_FM_TERRA && 708 if (msp->mode == MSP_MODE_FM_TERRA &&
625 msp->main != msp->second) { 709 msp->main != msp->second) {
626 printk(KERN_DEBUG "msp3400: FM-stereo carrier : %d.%03d MHz\n", 710 msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n",
627 msp->second/910000,(msp->second/910)%1000); 711 msp->second/910000,(msp->second/910)%1000);
628 } 712 }
629} 713}
630 714
715#define MSP3400_MAX 4
716static struct i2c_client *msps[MSP3400_MAX];
717static void msp3400c_restore_dfp(struct i2c_client *client)
718{
719 struct msp3400c *msp = i2c_get_clientdata(client);
720 int i;
721
722 for (i = 0; i < DFP_COUNT; i++) {
723 if (-1 == msp->dfp_regs[i])
724 continue;
725 msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]);
726 }
727}
728
729/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */
730static int msp3400c_write_dfp_with_default(struct i2c_client *client,
731 int addr, int default_value)
732{
733 struct msp3400c *msp = i2c_get_clientdata(client);
734 int value = default_value;
735 if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr])
736 value = msp->dfp_regs[addr];
737 return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value);
738}
739
631/* ----------------------------------------------------------------------- */ 740/* ----------------------------------------------------------------------- */
632 741
633struct REGISTER_DUMP { 742struct REGISTER_DUMP {
@@ -635,8 +744,15 @@ struct REGISTER_DUMP {
635 char *name; 744 char *name;
636}; 745};
637 746
638static int 747struct REGISTER_DUMP d1[] = {
639autodetect_stereo(struct i2c_client *client) 748 {0x007e, "autodetect"},
749 {0x0023, "C_AD_BITS "},
750 {0x0038, "ADD_BITS "},
751 {0x003e, "CIB_BITS "},
752 {0x0057, "ERROR_RATE"},
753};
754
755static int autodetect_stereo(struct i2c_client *client)
640{ 756{
641 struct msp3400c *msp = i2c_get_clientdata(client); 757 struct msp3400c *msp = i2c_get_clientdata(client);
642 int val; 758 int val;
@@ -649,8 +765,7 @@ autodetect_stereo(struct i2c_client *client)
649 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); 765 val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
650 if (val > 32767) 766 if (val > 32767)
651 val -= 65536; 767 val -= 65536;
652 dprintk(KERN_DEBUG 768 msp3400_dbg("stereo detect register: %d\n",val);
653 "msp34xx: stereo detect register: %d\n",val);
654 if (val > 4096) { 769 if (val > 4096) {
655 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; 770 rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
656 } else if (val < -4096) { 771 } else if (val < -4096) {
@@ -664,8 +779,7 @@ autodetect_stereo(struct i2c_client *client)
664 case MSP_MODE_FM_NICAM2: 779 case MSP_MODE_FM_NICAM2:
665 case MSP_MODE_AM_NICAM: 780 case MSP_MODE_AM_NICAM:
666 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); 781 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
667 dprintk(KERN_DEBUG 782 msp3400_dbg("nicam sync=%d, mode=%d\n",
668 "msp34xx: nicam sync=%d, mode=%d\n",
669 val & 1, (val & 0x1e) >> 1); 783 val & 1, (val & 0x1e) >> 1);
670 784
671 if (val & 1) { 785 if (val & 1) {
@@ -698,8 +812,7 @@ autodetect_stereo(struct i2c_client *client)
698 break; 812 break;
699 case MSP_MODE_BTSC: 813 case MSP_MODE_BTSC:
700 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); 814 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
701 dprintk(KERN_DEBUG 815 msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
702 "msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)\n",
703 val, 816 val,
704 (val & 0x0002) ? "no" : "yes", 817 (val & 0x0002) ? "no" : "yes",
705 (val & 0x0004) ? "no" : "yes", 818 (val & 0x0004) ? "no" : "yes",
@@ -713,13 +826,13 @@ autodetect_stereo(struct i2c_client *client)
713 } 826 }
714 if (rxsubchans != msp->rxsubchans) { 827 if (rxsubchans != msp->rxsubchans) {
715 update = 1; 828 update = 1;
716 dprintk(KERN_DEBUG "msp34xx: watch: rxsubchans %d => %d\n", 829 msp3400_dbg("watch: rxsubchans %d => %d\n",
717 msp->rxsubchans,rxsubchans); 830 msp->rxsubchans,rxsubchans);
718 msp->rxsubchans = rxsubchans; 831 msp->rxsubchans = rxsubchans;
719 } 832 }
720 if (newnicam != msp->nicam_on) { 833 if (newnicam != msp->nicam_on) {
721 update = 1; 834 update = 1;
722 dprintk(KERN_DEBUG "msp34xx: watch: nicam %d => %d\n", 835 msp3400_dbg("watch: nicam %d => %d\n",
723 msp->nicam_on,newnicam); 836 msp->nicam_on,newnicam);
724 msp->nicam_on = newnicam; 837 msp->nicam_on = newnicam;
725 } 838 }
@@ -741,8 +854,8 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout)
741 set_current_state(TASK_INTERRUPTIBLE); 854 set_current_state(TASK_INTERRUPTIBLE);
742 schedule(); 855 schedule();
743 } else { 856 } else {
744 set_current_state(TASK_INTERRUPTIBLE); 857 schedule_timeout_interruptible
745 schedule_timeout(msecs_to_jiffies(timeout)); 858 (msecs_to_jiffies(timeout));
746 } 859 }
747 } 860 }
748 861
@@ -756,8 +869,15 @@ static void watch_stereo(struct i2c_client *client)
756{ 869{
757 struct msp3400c *msp = i2c_get_clientdata(client); 870 struct msp3400c *msp = i2c_get_clientdata(client);
758 871
759 if (autodetect_stereo(client)) 872 if (autodetect_stereo(client)) {
760 msp3400c_set_audmode(client,best_audio_mode(msp->rxsubchans)); 873 if (msp->stereo & V4L2_TUNER_MODE_STEREO)
874 msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO);
875 else if (msp->stereo & VIDEO_SOUND_LANG1)
876 msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1);
877 else
878 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
879 }
880
761 if (once) 881 if (once)
762 msp->watch_stereo = 0; 882 msp->watch_stereo = 0;
763} 883}
@@ -769,14 +889,14 @@ static int msp3400c_thread(void *data)
769 struct CARRIER_DETECT *cd; 889 struct CARRIER_DETECT *cd;
770 int count, max1,max2,val1,val2, val,this; 890 int count, max1,max2,val1,val2, val,this;
771 891
772 printk("msp3400: kthread started\n"); 892 msp3400_info("msp3400 daemon started\n");
773 for (;;) { 893 for (;;) {
774 d2printk("msp3400: thread: sleep\n"); 894 msp3400_dbg_mediumvol("msp3400 thread: sleep\n");
775 msp34xx_sleep(msp,-1); 895 msp34xx_sleep(msp,-1);
776 d2printk("msp3400: thread: wakeup\n"); 896 msp3400_dbg_mediumvol("msp3400 thread: wakeup\n");
777 897
778 restart: 898 restart:
779 dprintk("msp3410: thread: restart scan\n"); 899 msp3400_dbg("thread: restart scan\n");
780 msp->restart = 0; 900 msp->restart = 0;
781 if (kthread_should_stop()) 901 if (kthread_should_stop())
782 break; 902 break;
@@ -784,9 +904,8 @@ static int msp3400c_thread(void *data)
784 if (VIDEO_MODE_RADIO == msp->norm || 904 if (VIDEO_MODE_RADIO == msp->norm ||
785 MSP_MODE_EXTERN == msp->mode) { 905 MSP_MODE_EXTERN == msp->mode) {
786 /* no carrier scan, just unmute */ 906 /* no carrier scan, just unmute */
787 printk("msp3400: thread: no carrier scan\n"); 907 msp3400_info("thread: no carrier scan\n");
788 msp3400c_setvolume(client, msp->muted, 908 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
789 msp->volume, msp->balance);
790 continue; 909 continue;
791 } 910 }
792 911
@@ -802,13 +921,14 @@ static int msp3400c_thread(void *data)
802 goto restart; 921 goto restart;
803 922
804 /* carrier detect pass #1 -- main carrier */ 923 /* carrier detect pass #1 -- main carrier */
805 cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main); 924 cd = carrier_detect_main;
925 count = CARRIER_COUNT(carrier_detect_main);
806 926
807 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { 927 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
808 /* autodetect doesn't work well with AM ... */ 928 /* autodetect doesn't work well with AM ... */
809 max1 = 3; 929 max1 = 3;
810 count = 0; 930 count = 0;
811 dprintk("msp3400: AM sound override\n"); 931 msp3400_dbg("AM sound override\n");
812 } 932 }
813 933
814 for (this = 0; this < count; this++) { 934 for (this = 0; this < count; this++) {
@@ -820,7 +940,7 @@ static int msp3400c_thread(void *data)
820 val -= 65536; 940 val -= 65536;
821 if (val1 < val) 941 if (val1 < val)
822 val1 = val, max1 = this; 942 val1 = val, max1 = this;
823 dprintk("msp3400: carrier1 val: %5d / %s\n", val,cd[this].name); 943 msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name);
824 } 944 }
825 945
826 /* carrier detect pass #2 -- second (stereo) carrier */ 946 /* carrier detect pass #2 -- second (stereo) carrier */
@@ -836,13 +956,16 @@ static int msp3400c_thread(void *data)
836 case 0: /* 4.5 */ 956 case 0: /* 4.5 */
837 case 2: /* 6.0 */ 957 case 2: /* 6.0 */
838 default: 958 default:
839 cd = NULL; count = 0; 959 cd = NULL;
960 count = 0;
840 break; 961 break;
841 } 962 }
842 963
843 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { 964 if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
844 /* autodetect doesn't work well with AM ... */ 965 /* autodetect doesn't work well with AM ... */
845 cd = NULL; count = 0; max2 = 0; 966 cd = NULL;
967 count = 0;
968 max2 = 0;
846 } 969 }
847 for (this = 0; this < count; this++) { 970 for (this = 0; this < count; this++) {
848 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); 971 msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
@@ -853,7 +976,7 @@ static int msp3400c_thread(void *data)
853 val -= 65536; 976 val -= 65536;
854 if (val2 < val) 977 if (val2 < val)
855 val2 = val, max2 = this; 978 val2 = val, max2 = this;
856 dprintk("msp3400: carrier2 val: %5d / %s\n", val,cd[this].name); 979 msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name);
857 } 980 }
858 981
859 /* programm the msp3400 according to the results */ 982 /* programm the msp3400 according to the results */
@@ -865,7 +988,7 @@ static int msp3400c_thread(void *data)
865 msp->second = carrier_detect_55[max2].cdo; 988 msp->second = carrier_detect_55[max2].cdo;
866 msp3400c_setmode(client, MSP_MODE_FM_TERRA); 989 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
867 msp->nicam_on = 0; 990 msp->nicam_on = 0;
868 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 991 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
869 msp->watch_stereo = 1; 992 msp->watch_stereo = 1;
870 } else if (max2 == 1 && HAVE_NICAM(msp)) { 993 } else if (max2 == 1 && HAVE_NICAM(msp)) {
871 /* B/G NICAM */ 994 /* B/G NICAM */
@@ -892,7 +1015,7 @@ static int msp3400c_thread(void *data)
892 msp->second = carrier_detect_65[max2].cdo; 1015 msp->second = carrier_detect_65[max2].cdo;
893 msp3400c_setmode(client, MSP_MODE_FM_TERRA); 1016 msp3400c_setmode(client, MSP_MODE_FM_TERRA);
894 msp->nicam_on = 0; 1017 msp->nicam_on = 0;
895 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1018 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
896 msp->watch_stereo = 1; 1019 msp->watch_stereo = 1;
897 } else if (max2 == 0 && 1020 } else if (max2 == 0 &&
898 msp->norm == VIDEO_MODE_SECAM) { 1021 msp->norm == VIDEO_MODE_SECAM) {
@@ -900,7 +1023,7 @@ static int msp3400c_thread(void *data)
900 msp->second = carrier_detect_65[max2].cdo; 1023 msp->second = carrier_detect_65[max2].cdo;
901 msp3400c_setmode(client, MSP_MODE_AM_NICAM); 1024 msp3400c_setmode(client, MSP_MODE_AM_NICAM);
902 msp->nicam_on = 0; 1025 msp->nicam_on = 0;
903 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1026 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
904 msp3400c_setcarrier(client, msp->second, msp->main); 1027 msp3400c_setcarrier(client, msp->second, msp->main);
905 /* volume prescale for SCART (AM mono input) */ 1028 /* volume prescale for SCART (AM mono input) */
906 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); 1029 msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
@@ -924,15 +1047,16 @@ static int msp3400c_thread(void *data)
924 msp->nicam_on = 0; 1047 msp->nicam_on = 0;
925 msp3400c_setcarrier(client, msp->second, msp->main); 1048 msp3400c_setcarrier(client, msp->second, msp->main);
926 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 1049 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
927 msp3400c_set_audmode(client, V4L2_TUNER_MODE_MONO); 1050 msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO);
928 break; 1051 break;
929 } 1052 }
930 1053
931 /* unmute */ 1054 /* unmute */
932 msp3400c_setvolume(client, msp->muted, 1055 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
933 msp->volume, msp->balance); 1056 msp3400c_restore_dfp(client);
1057
934 if (debug) 1058 if (debug)
935 msp3400c_print_mode(msp); 1059 msp3400c_print_mode(client);
936 1060
937 /* monitor tv audio mode */ 1061 /* monitor tv audio mode */
938 while (msp->watch_stereo) { 1062 while (msp->watch_stereo) {
@@ -941,7 +1065,7 @@ static int msp3400c_thread(void *data)
941 watch_stereo(client); 1065 watch_stereo(client);
942 } 1066 }
943 } 1067 }
944 dprintk(KERN_DEBUG "msp3400: thread: exit\n"); 1068 msp3400_dbg("thread: exit\n");
945 return 0; 1069 return 0;
946} 1070}
947 1071
@@ -985,10 +1109,12 @@ static inline const char *msp34xx_standard_mode_name(int mode)
985 return "unknown"; 1109 return "unknown";
986} 1110}
987 1111
988static int msp34xx_modus(int norm) 1112static int msp34xx_modus(struct i2c_client *client, int norm)
989{ 1113{
990 switch (norm) { 1114 switch (norm) {
991 case VIDEO_MODE_PAL: 1115 case VIDEO_MODE_PAL:
1116 msp3400_dbg("video mode selected to PAL\n");
1117
992#if 1 1118#if 1
993 /* experimental: not sure this works with all chip versions */ 1119 /* experimental: not sure this works with all chip versions */
994 return 0x7003; 1120 return 0x7003;
@@ -997,12 +1123,16 @@ static int msp34xx_modus(int norm)
997 return 0x1003; 1123 return 0x1003;
998#endif 1124#endif
999 case VIDEO_MODE_NTSC: /* BTSC */ 1125 case VIDEO_MODE_NTSC: /* BTSC */
1126 msp3400_dbg("video mode selected to NTSC\n");
1000 return 0x2003; 1127 return 0x2003;
1001 case VIDEO_MODE_SECAM: 1128 case VIDEO_MODE_SECAM:
1129 msp3400_dbg("video mode selected to SECAM\n");
1002 return 0x0003; 1130 return 0x0003;
1003 case VIDEO_MODE_RADIO: 1131 case VIDEO_MODE_RADIO:
1132 msp3400_dbg("video mode selected to Radio\n");
1004 return 0x0003; 1133 return 0x0003;
1005 case VIDEO_MODE_AUTO: 1134 case VIDEO_MODE_AUTO:
1135 msp3400_dbg("video mode selected to Auto\n");
1006 return 0x2003; 1136 return 0x2003;
1007 default: 1137 default:
1008 return 0x0003; 1138 return 0x0003;
@@ -1031,23 +1161,22 @@ static int msp3410d_thread(void *data)
1031 struct msp3400c *msp = i2c_get_clientdata(client); 1161 struct msp3400c *msp = i2c_get_clientdata(client);
1032 int mode,val,i,std; 1162 int mode,val,i,std;
1033 1163
1034 printk("msp3410: daemon started\n"); 1164 msp3400_info("msp3410 daemon started\n");
1035 for (;;) { 1165 for (;;) {
1036 d2printk(KERN_DEBUG "msp3410: thread: sleep\n"); 1166 msp3400_dbg_mediumvol("msp3410 thread: sleep\n");
1037 msp34xx_sleep(msp,-1); 1167 msp34xx_sleep(msp,-1);
1038 d2printk(KERN_DEBUG "msp3410: thread: wakeup\n"); 1168 msp3400_dbg_mediumvol("msp3410 thread: wakeup\n");
1039 1169
1040 restart: 1170 restart:
1041 dprintk("msp3410: thread: restart scan\n"); 1171 msp3400_dbg("thread: restart scan\n");
1042 msp->restart = 0; 1172 msp->restart = 0;
1043 if (kthread_should_stop()) 1173 if (kthread_should_stop())
1044 break; 1174 break;
1045 1175
1046 if (msp->mode == MSP_MODE_EXTERN) { 1176 if (msp->mode == MSP_MODE_EXTERN) {
1047 /* no carrier scan needed, just unmute */ 1177 /* no carrier scan needed, just unmute */
1048 dprintk(KERN_DEBUG "msp3410: thread: no carrier scan\n"); 1178 msp3400_dbg("thread: no carrier scan\n");
1049 msp3400c_setvolume(client, msp->muted, 1179 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1050 msp->volume, msp->balance);
1051 continue; 1180 continue;
1052 } 1181 }
1053 1182
@@ -1059,14 +1188,14 @@ static int msp3410d_thread(void *data)
1059 goto restart; 1188 goto restart;
1060 1189
1061 /* start autodetect */ 1190 /* start autodetect */
1062 mode = msp34xx_modus(msp->norm); 1191 mode = msp34xx_modus(client, msp->norm);
1063 std = msp34xx_standard(msp->norm); 1192 std = msp34xx_standard(msp->norm);
1064 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); 1193 msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
1065 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); 1194 msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
1066 msp->watch_stereo = 0; 1195 msp->watch_stereo = 0;
1067 1196
1068 if (debug) 1197 if (debug)
1069 printk(KERN_DEBUG "msp3410: setting mode: %s (0x%04x)\n", 1198 msp3400_dbg("setting mode: %s (0x%04x)\n",
1070 msp34xx_standard_mode_name(std) ,std); 1199 msp34xx_standard_mode_name(std) ,std);
1071 1200
1072 if (std != 1) { 1201 if (std != 1) {
@@ -1082,13 +1211,13 @@ static int msp3410d_thread(void *data)
1082 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); 1211 val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
1083 if (val < 0x07ff) 1212 if (val < 0x07ff)
1084 break; 1213 break;
1085 dprintk(KERN_DEBUG "msp3410: detection still in progress\n"); 1214 msp3400_dbg("detection still in progress\n");
1086 } 1215 }
1087 } 1216 }
1088 for (i = 0; modelist[i].name != NULL; i++) 1217 for (i = 0; modelist[i].name != NULL; i++)
1089 if (modelist[i].retval == val) 1218 if (modelist[i].retval == val)
1090 break; 1219 break;
1091 dprintk(KERN_DEBUG "msp3410: current mode: %s (0x%04x)\n", 1220 msp3400_dbg("current mode: %s (0x%04x)\n",
1092 modelist[i].name ? modelist[i].name : "unknown", 1221 modelist[i].name ? modelist[i].name : "unknown",
1093 val); 1222 val);
1094 msp->main = modelist[i].main; 1223 msp->main = modelist[i].main;
@@ -1096,7 +1225,7 @@ static int msp3410d_thread(void *data)
1096 1225
1097 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { 1226 if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
1098 /* autodetection has failed, let backup */ 1227 /* autodetection has failed, let backup */
1099 dprintk(KERN_DEBUG "msp3410: autodetection failed," 1228 msp3400_dbg("autodetection failed,"
1100 " switching to backup mode: %s (0x%04x)\n", 1229 " switching to backup mode: %s (0x%04x)\n",
1101 modelist[8].name ? modelist[8].name : "unknown",val); 1230 modelist[8].name ? modelist[8].name : "unknown",val);
1102 val = 0x0009; 1231 val = 0x0009;
@@ -1120,13 +1249,13 @@ static int msp3410d_thread(void *data)
1120 msp->rxsubchans = V4L2_TUNER_SUB_STEREO; 1249 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1121 msp->nicam_on = 1; 1250 msp->nicam_on = 1;
1122 msp->watch_stereo = 1; 1251 msp->watch_stereo = 1;
1123 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); 1252 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1124 break; 1253 break;
1125 case 0x0009: 1254 case 0x0009:
1126 msp->mode = MSP_MODE_AM_NICAM; 1255 msp->mode = MSP_MODE_AM_NICAM;
1127 msp->rxsubchans = V4L2_TUNER_SUB_MONO; 1256 msp->rxsubchans = V4L2_TUNER_SUB_MONO;
1128 msp->nicam_on = 1; 1257 msp->nicam_on = 1;
1129 msp3400c_set_audmode(client,V4L2_TUNER_MODE_MONO); 1258 msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO);
1130 msp->watch_stereo = 1; 1259 msp->watch_stereo = 1;
1131 break; 1260 break;
1132 case 0x0020: /* BTSC */ 1261 case 0x0020: /* BTSC */
@@ -1135,7 +1264,7 @@ static int msp3410d_thread(void *data)
1135 msp->rxsubchans = V4L2_TUNER_SUB_STEREO; 1264 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
1136 msp->nicam_on = 0; 1265 msp->nicam_on = 0;
1137 msp->watch_stereo = 1; 1266 msp->watch_stereo = 1;
1138 msp3400c_set_audmode(client,V4L2_TUNER_MODE_STEREO); 1267 msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO);
1139 break; 1268 break;
1140 case 0x0040: /* FM radio */ 1269 case 0x0040: /* FM radio */
1141 msp->mode = MSP_MODE_FM_RADIO; 1270 msp->mode = MSP_MODE_FM_RADIO;
@@ -1169,9 +1298,10 @@ static int msp3410d_thread(void *data)
1169 /* unmute, restore misc registers */ 1298 /* unmute, restore misc registers */
1170 msp3400c_setbass(client, msp->bass); 1299 msp3400c_setbass(client, msp->bass);
1171 msp3400c_settreble(client, msp->treble); 1300 msp3400c_settreble(client, msp->treble);
1172 msp3400c_setvolume(client, msp->muted, 1301 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1173 msp->volume, msp->balance); 1302 msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb);
1174 msp3400c_write(client, I2C_MSP3400C_DFP, 0x0013, msp->acb); 1303 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1304 msp3400c_restore_dfp(client);
1175 1305
1176 /* monitor tv audio mode */ 1306 /* monitor tv audio mode */
1177 while (msp->watch_stereo) { 1307 while (msp->watch_stereo) {
@@ -1180,7 +1310,7 @@ static int msp3410d_thread(void *data)
1180 watch_stereo(client); 1310 watch_stereo(client);
1181 } 1311 }
1182 } 1312 }
1183 dprintk(KERN_DEBUG "msp3410: thread: exit\n"); 1313 msp3400_dbg("thread: exit\n");
1184 return 0; 1314 return 0;
1185} 1315}
1186 1316
@@ -1195,7 +1325,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source);
1195/* (re-)initialize the msp34xxg, according to the current norm in msp->norm 1325/* (re-)initialize the msp34xxg, according to the current norm in msp->norm
1196 * return 0 if it worked, -1 if it failed 1326 * return 0 if it worked, -1 if it failed
1197 */ 1327 */
1198static int msp34xxg_init(struct i2c_client *client) 1328static int msp34xxg_reset(struct i2c_client *client)
1199{ 1329{
1200 struct msp3400c *msp = i2c_get_clientdata(client); 1330 struct msp3400c *msp = i2c_get_clientdata(client);
1201 int modus,std; 1331 int modus,std;
@@ -1210,8 +1340,10 @@ static int msp34xxg_init(struct i2c_client *client)
1210 0x0f20 /* mute DSP input, mute SCART 1 */)) 1340 0x0f20 /* mute DSP input, mute SCART 1 */))
1211 return -1; 1341 return -1;
1212 1342
1343 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1344
1213 /* step-by-step initialisation, as described in the manual */ 1345 /* step-by-step initialisation, as described in the manual */
1214 modus = msp34xx_modus(msp->norm); 1346 modus = msp34xx_modus(client, msp->norm);
1215 std = msp34xx_standard(msp->norm); 1347 std = msp34xx_standard(msp->norm);
1216 modus &= ~0x03; /* STATUS_CHANGE=0 */ 1348 modus &= ~0x03; /* STATUS_CHANGE=0 */
1217 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ 1349 modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */
@@ -1222,7 +1354,7 @@ static int msp34xxg_init(struct i2c_client *client)
1222 return -1; 1354 return -1;
1223 if (msp3400c_write(client, 1355 if (msp3400c_write(client,
1224 I2C_MSP3400C_DEM, 1356 I2C_MSP3400C_DEM,
1225 0x20/*stanard*/, 1357 0x20/*standard*/,
1226 std)) 1358 std))
1227 return -1; 1359 return -1;
1228 1360
@@ -1230,21 +1362,18 @@ static int msp34xxg_init(struct i2c_client *client)
1230 standard/audio autodetection right now */ 1362 standard/audio autodetection right now */
1231 msp34xxg_set_source(client, msp->source); 1363 msp34xxg_set_source(client, msp->source);
1232 1364
1233 if (msp3400c_write(client, I2C_MSP3400C_DFP, 1365 if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */
1234 0x0e, /* AM/FM Prescale */ 1366 0x3000
1235 0x3000 /* default: [15:8] 75khz deviation */)) 1367 /* default: [15:8] 75khz deviation */
1368 ))
1236 return -1; 1369 return -1;
1237 1370
1238 if (msp3400c_write(client, I2C_MSP3400C_DFP, 1371 if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */
1239 0x10, /* NICAM Prescale */ 1372 0x5a00
1240 0x5a00 /* default: 9db gain (as recommended) */)) 1373 /* default: 9db gain (as recommended) */
1374 ))
1241 return -1; 1375 return -1;
1242 1376
1243 if (msp3400c_write(client,
1244 I2C_MSP3400C_DEM,
1245 0x20, /* STANDARD SELECT */
1246 standard /* default: 0x01 for automatic standard select*/))
1247 return -1;
1248 return 0; 1377 return 0;
1249} 1378}
1250 1379
@@ -1254,27 +1383,27 @@ static int msp34xxg_thread(void *data)
1254 struct msp3400c *msp = i2c_get_clientdata(client); 1383 struct msp3400c *msp = i2c_get_clientdata(client);
1255 int val, std, i; 1384 int val, std, i;
1256 1385
1257 printk("msp34xxg: daemon started\n"); 1386 msp3400_info("msp34xxg daemon started\n");
1258 msp->source = 1; /* default */ 1387 msp->source = 1; /* default */
1259 for (;;) { 1388 for (;;) {
1260 d2printk(KERN_DEBUG "msp34xxg: thread: sleep\n"); 1389 msp3400_dbg_mediumvol("msp34xxg thread: sleep\n");
1261 msp34xx_sleep(msp,-1); 1390 msp34xx_sleep(msp,-1);
1262 d2printk(KERN_DEBUG "msp34xxg: thread: wakeup\n"); 1391 msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n");
1263 1392
1264 restart: 1393 restart:
1265 dprintk("msp34xxg: thread: restart scan\n"); 1394 msp3400_dbg("thread: restart scan\n");
1266 msp->restart = 0; 1395 msp->restart = 0;
1267 if (kthread_should_stop()) 1396 if (kthread_should_stop())
1268 break; 1397 break;
1269 1398
1270 /* setup the chip*/ 1399 /* setup the chip*/
1271 msp34xxg_init(client); 1400 msp34xxg_reset(client);
1272 std = standard; 1401 std = standard;
1273 if (std != 0x01) 1402 if (std != 0x01)
1274 goto unmute; 1403 goto unmute;
1275 1404
1276 /* watch autodetect */ 1405 /* watch autodetect */
1277 dprintk("msp34xxg: triggered autodetect, waiting for result\n"); 1406 msp3400_dbg("triggered autodetect, waiting for result\n");
1278 for (i = 0; i < 10; i++) { 1407 for (i = 0; i < 10; i++) {
1279 if (msp34xx_sleep(msp,100)) 1408 if (msp34xx_sleep(msp,100))
1280 goto restart; 1409 goto restart;
@@ -1285,23 +1414,23 @@ static int msp34xxg_thread(void *data)
1285 std = val; 1414 std = val;
1286 break; 1415 break;
1287 } 1416 }
1288 dprintk("msp34xxg: detection still in progress\n"); 1417 msp3400_dbg("detection still in progress\n");
1289 } 1418 }
1290 if (0x01 == std) { 1419 if (0x01 == std) {
1291 dprintk("msp34xxg: detection still in progress after 10 tries. giving up.\n"); 1420 msp3400_dbg("detection still in progress after 10 tries. giving up.\n");
1292 continue; 1421 continue;
1293 } 1422 }
1294 1423
1295 unmute: 1424 unmute:
1296 dprintk("msp34xxg: current mode: %s (0x%04x)\n", 1425 msp3400_dbg("current mode: %s (0x%04x)\n",
1297 msp34xx_standard_mode_name(std), std); 1426 msp34xx_standard_mode_name(std), std);
1298 1427
1299 /* unmute: dispatch sound to scart output, set scart volume */ 1428 /* unmute: dispatch sound to scart output, set scart volume */
1300 dprintk("msp34xxg: unmute\n"); 1429 msp3400_dbg("unmute\n");
1301 1430
1302 msp3400c_setbass(client, msp->bass); 1431 msp3400c_setbass(client, msp->bass);
1303 msp3400c_settreble(client, msp->treble); 1432 msp3400c_settreble(client, msp->treble);
1304 msp3400c_setvolume(client, msp->muted, msp->volume, msp->balance); 1433 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1305 1434
1306 /* restore ACB */ 1435 /* restore ACB */
1307 if (msp3400c_write(client, 1436 if (msp3400c_write(client,
@@ -1309,8 +1438,10 @@ static int msp34xxg_thread(void *data)
1309 0x13, /* ACB */ 1438 0x13, /* ACB */
1310 msp->acb)) 1439 msp->acb))
1311 return -1; 1440 return -1;
1441
1442 msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode);
1312 } 1443 }
1313 dprintk(KERN_DEBUG "msp34xxg: thread: exit\n"); 1444 msp3400_dbg("thread: exit\n");
1314 return 0; 1445 return 0;
1315} 1446}
1316 1447
@@ -1329,7 +1460,7 @@ static void msp34xxg_set_source(struct i2c_client *client, int source)
1329 * for MONO (source==0) downmixing set bit[7:0] to 0x30 1460 * for MONO (source==0) downmixing set bit[7:0] to 0x30
1330 */ 1461 */
1331 int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); 1462 int value = (source&0x07)<<8|(source==0 ? 0x30:0x20);
1332 dprintk("msp34xxg: set source to %d (0x%x)\n", source, value); 1463 msp3400_dbg("set source to %d (0x%x)\n", source, value);
1333 msp3400c_write(client, 1464 msp3400c_write(client,
1334 I2C_MSP3400C_DFP, 1465 I2C_MSP3400C_DFP,
1335 0x08, /* Loudspeaker Output */ 1466 0x08, /* Loudspeaker Output */
@@ -1380,7 +1511,7 @@ static void msp34xxg_detect_stereo(struct i2c_client *client)
1380 * this is a problem, I'll handle SAP just like lang1/lang2. 1511 * this is a problem, I'll handle SAP just like lang1/lang2.
1381 */ 1512 */
1382 } 1513 }
1383 dprintk("msp34xxg: status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", 1514 msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n",
1384 status, is_stereo, is_bilingual, msp->rxsubchans); 1515 status, is_stereo, is_bilingual, msp->rxsubchans);
1385} 1516}
1386 1517
@@ -1427,7 +1558,7 @@ static void msp_wake_thread(struct i2c_client *client);
1427 1558
1428static struct i2c_driver driver = { 1559static struct i2c_driver driver = {
1429 .owner = THIS_MODULE, 1560 .owner = THIS_MODULE,
1430 .name = "i2c msp3400 driver", 1561 .name = "msp3400",
1431 .id = I2C_DRIVERID_MSP3400, 1562 .id = I2C_DRIVERID_MSP3400,
1432 .flags = I2C_DF_NOTIFY, 1563 .flags = I2C_DF_NOTIFY,
1433 .attach_adapter = msp_probe, 1564 .attach_adapter = msp_probe,
@@ -1449,57 +1580,64 @@ static struct i2c_client client_template =
1449static int msp_attach(struct i2c_adapter *adap, int addr, int kind) 1580static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1450{ 1581{
1451 struct msp3400c *msp; 1582 struct msp3400c *msp;
1452 struct i2c_client *c; 1583 struct i2c_client *client = &client_template;
1453 int (*thread_func)(void *data) = NULL; 1584 int (*thread_func)(void *data) = NULL;
1585 int i;
1454 1586
1455 client_template.adapter = adap; 1587 client_template.adapter = adap;
1456 client_template.addr = addr; 1588 client_template.addr = addr;
1457 1589
1458 if (-1 == msp3400c_reset(&client_template)) { 1590 if (-1 == msp3400c_reset(&client_template)) {
1459 dprintk("msp34xx: no chip found\n"); 1591 msp3400_dbg("no chip found\n");
1460 return -1; 1592 return -1;
1461 } 1593 }
1462 1594
1463 if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) 1595 if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
1464 return -ENOMEM; 1596 return -ENOMEM;
1465 memcpy(c,&client_template,sizeof(struct i2c_client)); 1597 memcpy(client,&client_template,sizeof(struct i2c_client));
1466 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { 1598 if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
1467 kfree(c); 1599 kfree(client);
1468 return -ENOMEM; 1600 return -ENOMEM;
1469 } 1601 }
1470 1602
1471 memset(msp,0,sizeof(struct msp3400c)); 1603 memset(msp,0,sizeof(struct msp3400c));
1472 msp->volume = 58880; /* 0db gain */ 1604 msp->norm = VIDEO_MODE_NTSC;
1473 msp->balance = 32768; 1605 msp->left = 58880; /* 0db gain */
1474 msp->bass = 32768; 1606 msp->right = 58880; /* 0db gain */
1475 msp->treble = 32768; 1607 msp->bass = 32768;
1476 msp->input = -1; 1608 msp->treble = 32768;
1477 msp->muted = 1; 1609 msp->input = -1;
1478 1610 msp->muted = 0;
1479 i2c_set_clientdata(c, msp); 1611 msp->i2s_mode = 0;
1612 for (i = 0; i < DFP_COUNT; i++)
1613 msp->dfp_regs[i] = -1;
1614
1615 i2c_set_clientdata(client, msp);
1480 init_waitqueue_head(&msp->wq); 1616 init_waitqueue_head(&msp->wq);
1481 1617
1482 if (-1 == msp3400c_reset(c)) { 1618 if (-1 == msp3400c_reset(client)) {
1483 kfree(msp); 1619 kfree(msp);
1484 kfree(c); 1620 kfree(client);
1485 dprintk("msp34xx: no chip found\n"); 1621 msp3400_dbg("no chip found\n");
1486 return -1; 1622 return -1;
1487 } 1623 }
1488 1624
1489 msp->rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e); 1625 msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e);
1490 if (-1 != msp->rev1) 1626 if (-1 != msp->rev1)
1491 msp->rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f); 1627 msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f);
1492 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { 1628 if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) {
1493 kfree(msp); 1629 kfree(msp);
1494 kfree(c); 1630 kfree(client);
1495 dprintk("msp34xx: error while reading chip version\n"); 1631 msp3400_dbg("error while reading chip version\n");
1496 return -1; 1632 return -1;
1497 } 1633 }
1634 msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2);
1498 1635
1499 msp3400c_setvolume(c, msp->muted, msp->volume, msp->balance); 1636 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1500 1637
1501 snprintf(c->name, sizeof(c->name), "MSP34%02d%c-%c%d", 1638 snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d",
1502 (msp->rev2>>8)&0xff, (msp->rev1&0xff)+'@', 1639 ((msp->rev1>>4)&0x0f) + '3',
1640 (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@',
1503 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); 1641 ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f);
1504 1642
1505 msp->opmode = opmode; 1643 msp->opmode = opmode;
@@ -1513,7 +1651,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1513 } 1651 }
1514 1652
1515 /* hello world :-) */ 1653 /* hello world :-) */
1516 printk(KERN_INFO "msp34xx: init: chip=%s", c->name); 1654 msp3400_info("chip=%s", client->name);
1517 if (HAVE_NICAM(msp)) 1655 if (HAVE_NICAM(msp))
1518 printk(" +nicam"); 1656 printk(" +nicam");
1519 if (HAVE_SIMPLE(msp)) 1657 if (HAVE_SIMPLE(msp))
@@ -1542,29 +1680,49 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
1542 1680
1543 /* startup control thread if needed */ 1681 /* startup control thread if needed */
1544 if (thread_func) { 1682 if (thread_func) {
1545 msp->kthread = kthread_run(thread_func, c, "msp34xx"); 1683 msp->kthread = kthread_run(thread_func, client, "msp34xx");
1684
1546 if (NULL == msp->kthread) 1685 if (NULL == msp->kthread)
1547 printk(KERN_WARNING "msp34xx: kernel_thread() failed\n"); 1686 msp3400_warn("kernel_thread() failed\n");
1548 msp_wake_thread(c); 1687 msp_wake_thread(client);
1549 } 1688 }
1550 1689
1551 /* done */ 1690 /* done */
1552 i2c_attach_client(c); 1691 i2c_attach_client(client);
1692
1693 /* update our own array */
1694 for (i = 0; i < MSP3400_MAX; i++) {
1695 if (NULL == msps[i]) {
1696 msps[i] = client;
1697 break;
1698 }
1699 }
1700
1553 return 0; 1701 return 0;
1554} 1702}
1555 1703
1556static int msp_detach(struct i2c_client *client) 1704static int msp_detach(struct i2c_client *client)
1557{ 1705{
1558 struct msp3400c *msp = i2c_get_clientdata(client); 1706 struct msp3400c *msp = i2c_get_clientdata(client);
1707 int i;
1559 1708
1560 /* shutdown control thread */ 1709 /* shutdown control thread */
1561 if (msp->kthread >= 0) { 1710 if (msp->kthread) {
1562 msp->restart = 1; 1711 msp->restart = 1;
1563 kthread_stop(msp->kthread); 1712 kthread_stop(msp->kthread);
1564 } 1713 }
1565 msp3400c_reset(client); 1714 msp3400c_reset(client);
1715
1716 /* update our own array */
1717 for (i = 0; i < MSP3400_MAX; i++) {
1718 if (client == msps[i]) {
1719 msps[i] = NULL;
1720 break;
1721 }
1722 }
1566 1723
1567 i2c_detach_client(client); 1724 i2c_detach_client(client);
1725
1568 kfree(msp); 1726 kfree(msp);
1569 kfree(client); 1727 kfree(client);
1570 return 0; 1728 return 0;
@@ -1640,7 +1798,7 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1640 case OPMODE_MANUAL: 1798 case OPMODE_MANUAL:
1641 case OPMODE_SIMPLE: 1799 case OPMODE_SIMPLE:
1642 msp->watch_stereo = 0; 1800 msp->watch_stereo = 0;
1643 msp3400c_set_audmode(client, audmode); 1801 msp3400c_setstereo(client, audmode);
1644 break; 1802 break;
1645 case OPMODE_SIMPLER: 1803 case OPMODE_SIMPLER:
1646 msp34xxg_set_audmode(client, audmode); 1804 msp34xxg_set_audmode(client, audmode);
@@ -1648,16 +1806,18 @@ static void msp_any_set_audmode(struct i2c_client *client, int audmode)
1648 } 1806 }
1649} 1807}
1650 1808
1809
1651static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) 1810static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1652{ 1811{
1653 struct msp3400c *msp = i2c_get_clientdata(client); 1812 struct msp3400c *msp = i2c_get_clientdata(client);
1654 __u16 *sarg = arg; 1813 __u16 *sarg = arg;
1655 int scart = 0; 1814 int scart = 0;
1656 1815
1657 switch (cmd) { 1816 switch (cmd) {
1658 1817
1659 case AUDC_SET_INPUT: 1818 case AUDC_SET_INPUT:
1660 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)\n",*sarg); 1819 msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg);
1820
1661 if (*sarg == msp->input) 1821 if (*sarg == msp->input)
1662 break; 1822 break;
1663 msp->input = *sarg; 1823 msp->input = *sarg;
@@ -1691,15 +1851,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1691 msp3400c_set_scart(client,scart,0); 1851 msp3400c_set_scart(client,scart,0);
1692 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); 1852 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
1693 if (msp->opmode != OPMODE_SIMPLER) 1853 if (msp->opmode != OPMODE_SIMPLER)
1694 msp3400c_set_audmode(client, msp->audmode); 1854 msp3400c_setstereo(client, msp->audmode);
1695 } 1855 }
1696 msp_wake_thread(client); 1856 msp_wake_thread(client);
1697 break; 1857 break;
1698 1858
1699 case AUDC_SET_RADIO: 1859 case AUDC_SET_RADIO:
1700 dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIO\n"); 1860 msp3400_dbg("AUDC_SET_RADIO\n");
1701 msp->norm = VIDEO_MODE_RADIO; 1861 msp->norm = VIDEO_MODE_RADIO;
1702 dprintk(KERN_DEBUG "msp34xx: switching to radio mode\n"); 1862 msp3400_dbg("switching to radio mode\n");
1703 msp->watch_stereo = 0; 1863 msp->watch_stereo = 0;
1704 switch (msp->opmode) { 1864 switch (msp->opmode) {
1705 case OPMODE_MANUAL: 1865 case OPMODE_MANUAL:
@@ -1707,8 +1867,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1707 msp3400c_setmode(client,MSP_MODE_FM_RADIO); 1867 msp3400c_setmode(client,MSP_MODE_FM_RADIO);
1708 msp3400c_setcarrier(client, MSP_CARRIER(10.7), 1868 msp3400c_setcarrier(client, MSP_CARRIER(10.7),
1709 MSP_CARRIER(10.7)); 1869 MSP_CARRIER(10.7));
1710 msp3400c_setvolume(client, msp->muted, 1870 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1711 msp->volume, msp->balance);
1712 break; 1871 break;
1713 case OPMODE_SIMPLE: 1872 case OPMODE_SIMPLE:
1714 case OPMODE_SIMPLER: 1873 case OPMODE_SIMPLER:
@@ -1717,6 +1876,30 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1717 break; 1876 break;
1718 } 1877 }
1719 break; 1878 break;
1879 /* work-in-progress: hook to control the DFP registers */
1880 case MSP_SET_DFPREG:
1881 {
1882 struct msp_dfpreg *r = arg;
1883 int i;
1884
1885 if (r->reg < 0 || r->reg >= DFP_COUNT)
1886 return -EINVAL;
1887 for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++)
1888 if (r->reg == bl_dfp[i])
1889 return -EINVAL;
1890 msp->dfp_regs[r->reg] = r->value;
1891 msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value);
1892 return 0;
1893 }
1894 case MSP_GET_DFPREG:
1895 {
1896 struct msp_dfpreg *r = arg;
1897
1898 if (r->reg < 0 || r->reg >= DFP_COUNT)
1899 return -EINVAL;
1900 r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg);
1901 return 0;
1902 }
1720 1903
1721 /* --- v4l ioctls --- */ 1904 /* --- v4l ioctls --- */
1722 /* take care: bttv does userspace copying, we'll get a 1905 /* take care: bttv does userspace copying, we'll get a
@@ -1725,7 +1908,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1725 { 1908 {
1726 struct video_audio *va = arg; 1909 struct video_audio *va = arg;
1727 1910
1728 dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIO\n"); 1911 msp3400_dbg("VIDIOCGAUDIO\n");
1729 va->flags |= VIDEO_AUDIO_VOLUME | 1912 va->flags |= VIDEO_AUDIO_VOLUME |
1730 VIDEO_AUDIO_BASS | 1913 VIDEO_AUDIO_BASS |
1731 VIDEO_AUDIO_TREBLE | 1914 VIDEO_AUDIO_TREBLE |
@@ -1733,8 +1916,15 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1733 if (msp->muted) 1916 if (msp->muted)
1734 va->flags |= VIDEO_AUDIO_MUTE; 1917 va->flags |= VIDEO_AUDIO_MUTE;
1735 1918
1736 va->volume = msp->volume; 1919 if (msp->muted)
1737 va->balance = (va->volume) ? msp->balance : 32768; 1920 va->flags |= VIDEO_AUDIO_MUTE;
1921 va->volume = MAX(msp->left, msp->right);
1922 va->balance = (32768 * MIN(msp->left, msp->right)) /
1923 (va->volume ? va->volume : 1);
1924 va->balance = (msp->left < msp->right) ?
1925 (65535 - va->balance) : va->balance;
1926 if (0 == va->volume)
1927 va->balance = 32768;
1738 va->bass = msp->bass; 1928 va->bass = msp->bass;
1739 va->treble = msp->treble; 1929 va->treble = msp->treble;
1740 1930
@@ -1746,27 +1936,43 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1746 { 1936 {
1747 struct video_audio *va = arg; 1937 struct video_audio *va = arg;
1748 1938
1749 dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIO\n"); 1939 msp3400_dbg("VIDIOCSAUDIO\n");
1750 msp->muted = (va->flags & VIDEO_AUDIO_MUTE); 1940 msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
1751 msp->volume = va->volume; 1941 msp->left = (MIN(65536 - va->balance, 32768) *
1752 msp->balance = va->balance; 1942 va->volume) / 32768;
1943 msp->right = (MIN(va->balance, 32768) * va->volume) / 32768;
1753 msp->bass = va->bass; 1944 msp->bass = va->bass;
1754 msp->treble = va->treble; 1945 msp->treble = va->treble;
1755 1946 msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n",
1756 msp3400c_setvolume(client, msp->muted, 1947 va->volume);
1757 msp->volume, msp->balance); 1948 msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n",
1758 msp3400c_setbass(client,msp->bass); 1949 va->balance);
1759 msp3400c_settreble(client,msp->treble); 1950 msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n",
1951 va->flags);
1952 msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n",
1953 msp->left);
1954 msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n",
1955 msp->right);
1956 msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n",
1957 msp->bass);
1958 msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n",
1959 msp->treble);
1960 msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n",
1961 msp->mode);
1962 msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
1963 msp3400c_setbass(client, msp->bass);
1964 msp3400c_settreble(client, msp->treble);
1760 1965
1761 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) 1966 if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO)
1762 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); 1967 msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode));
1763 break; 1968 break;
1764 } 1969 }
1970
1765 case VIDIOCSCHAN: 1971 case VIDIOCSCHAN:
1766 { 1972 {
1767 struct video_channel *vc = arg; 1973 struct video_channel *vc = arg;
1768 1974
1769 dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHAN (norm=%d)\n",vc->norm); 1975 msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm);
1770 msp->norm = vc->norm; 1976 msp->norm = vc->norm;
1771 msp_wake_thread(client); 1977 msp_wake_thread(client);
1772 break; 1978 break;
@@ -1776,12 +1982,135 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1776 case VIDIOC_S_FREQUENCY: 1982 case VIDIOC_S_FREQUENCY:
1777 { 1983 {
1778 /* new channel -- kick audio carrier scan */ 1984 /* new channel -- kick audio carrier scan */
1779 dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQ\n"); 1985 msp3400_dbg("VIDIOCSFREQ\n");
1780 msp_wake_thread(client); 1986 msp_wake_thread(client);
1781 break; 1987 break;
1782 } 1988 }
1783 1989
1990 /* msp34xx specific */
1991 case MSP_SET_MATRIX:
1992 {
1993 struct msp_matrix *mspm = arg;
1994
1995 msp3400_dbg("MSP_SET_MATRIX\n");
1996 msp3400c_set_scart(client, mspm->input, mspm->output);
1997 break;
1998 }
1999
1784 /* --- v4l2 ioctls --- */ 2000 /* --- v4l2 ioctls --- */
2001 case VIDIOC_S_STD:
2002 {
2003 v4l2_std_id *id = arg;
2004
2005 /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/
2006 if (*id & V4L2_STD_PAL) {
2007 msp->norm=VIDEO_MODE_PAL;
2008 } else if (*id & V4L2_STD_SECAM) {
2009 msp->norm=VIDEO_MODE_SECAM;
2010 } else {
2011 msp->norm=VIDEO_MODE_NTSC;
2012 }
2013
2014 msp_wake_thread(client);
2015 return 0;
2016 }
2017
2018 case VIDIOC_ENUMINPUT:
2019 {
2020 struct v4l2_input *i = arg;
2021
2022 if (i->index != 0)
2023 return -EINVAL;
2024
2025 i->type = V4L2_INPUT_TYPE_TUNER;
2026 switch (i->index) {
2027 case AUDIO_RADIO:
2028 strcpy(i->name,"Radio");
2029 break;
2030 case AUDIO_EXTERN_1:
2031 strcpy(i->name,"Extern 1");
2032 break;
2033 case AUDIO_EXTERN_2:
2034 strcpy(i->name,"Extern 2");
2035 break;
2036 case AUDIO_TUNER:
2037 strcpy(i->name,"Television");
2038 break;
2039 default:
2040 return -EINVAL;
2041 }
2042 return 0;
2043 }
2044
2045 case VIDIOC_G_AUDIO:
2046 {
2047 struct v4l2_audio *a = arg;
2048
2049 memset(a,0,sizeof(*a));
2050
2051 switch (a->index) {
2052 case AUDIO_RADIO:
2053 strcpy(a->name,"Radio");
2054 break;
2055 case AUDIO_EXTERN_1:
2056 strcpy(a->name,"Extern 1");
2057 break;
2058 case AUDIO_EXTERN_2:
2059 strcpy(a->name,"Extern 2");
2060 break;
2061 case AUDIO_TUNER:
2062 strcpy(a->name,"Television");
2063 break;
2064 default:
2065 return -EINVAL;
2066 }
2067
2068 msp_any_detect_stereo(client);
2069 if (msp->audmode == V4L2_TUNER_MODE_STEREO) {
2070 a->capability=V4L2_AUDCAP_STEREO;
2071 }
2072
2073 break;
2074 }
2075 case VIDIOC_S_AUDIO:
2076 {
2077 struct v4l2_audio *sarg = arg;
2078
2079 switch (sarg->index) {
2080 case AUDIO_RADIO:
2081 /* Hauppauge uses IN2 for the radio */
2082 msp->mode = MSP_MODE_FM_RADIO;
2083 scart = SCART_IN2;
2084 break;
2085 case AUDIO_EXTERN_1:
2086 /* IN1 is often used for external input ... */
2087 msp->mode = MSP_MODE_EXTERN;
2088 scart = SCART_IN1;
2089 break;
2090 case AUDIO_EXTERN_2:
2091 /* ... sometimes it is IN2 through ;) */
2092 msp->mode = MSP_MODE_EXTERN;
2093 scart = SCART_IN2;
2094 break;
2095 case AUDIO_TUNER:
2096 msp->mode = -1;
2097 break;
2098 }
2099 if (scart) {
2100 msp->rxsubchans = V4L2_TUNER_SUB_STEREO;
2101 msp->audmode = V4L2_TUNER_MODE_STEREO;
2102 msp3400c_set_scart(client,scart,0);
2103 msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
2104 }
2105 if (sarg->capability==V4L2_AUDCAP_STEREO) {
2106 msp->audmode = V4L2_TUNER_MODE_STEREO;
2107 } else {
2108 msp->audmode &= ~V4L2_TUNER_MODE_STEREO;
2109 }
2110 msp_any_set_audmode(client, msp->audmode);
2111 msp_wake_thread(client);
2112 break;
2113 }
1785 case VIDIOC_G_TUNER: 2114 case VIDIOC_G_TUNER:
1786 { 2115 {
1787 struct v4l2_tuner *vt = arg; 2116 struct v4l2_tuner *vt = arg;
@@ -1804,13 +2133,46 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1804 break; 2133 break;
1805 } 2134 }
1806 2135
1807 /* msp34xx specific */ 2136 case VIDIOC_G_AUDOUT:
1808 case MSP_SET_MATRIX:
1809 { 2137 {
1810 struct msp_matrix *mspm = arg; 2138 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2139 int idx=a->index;
2140
2141 memset(a,0,sizeof(*a));
2142
2143 switch (idx) {
2144 case 0:
2145 strcpy(a->name,"Scart1 Out");
2146 break;
2147 case 1:
2148 strcpy(a->name,"Scart2 Out");
2149 break;
2150 case 2:
2151 strcpy(a->name,"I2S Out");
2152 break;
2153 default:
2154 return -EINVAL;
2155 }
2156 break;
2157
2158 }
2159 case VIDIOC_S_AUDOUT:
2160 {
2161 struct v4l2_audioout *a=(struct v4l2_audioout *)arg;
2162
2163 if (a->index<0||a->index>2)
2164 return -EINVAL;
2165
2166 if (a->index==2) {
2167 if (a->mode == V4L2_AUDMODE_32BITS)
2168 msp->i2s_mode=1;
2169 else
2170 msp->i2s_mode=0;
2171 }
2172 msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n",
2173 a->index,msp->i2s_mode);
2174 msp3400c_set_scart(client,msp->in_scart,a->index+1);
1811 2175
1812 dprintk(KERN_DEBUG "msp34xx: MSP_SET_MATRIX\n");
1813 msp3400c_set_scart(client, mspm->input, mspm->output);
1814 break; 2176 break;
1815 } 2177 }
1816 2178
@@ -1823,19 +2185,19 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
1823 2185
1824static int msp_suspend(struct device * dev, pm_message_t state) 2186static int msp_suspend(struct device * dev, pm_message_t state)
1825{ 2187{
1826 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 2188 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1827 2189
1828 dprintk("msp34xx: suspend\n"); 2190 msp3400_dbg("msp34xx: suspend\n");
1829 msp3400c_reset(c); 2191 msp3400c_reset(client);
1830 return 0; 2192 return 0;
1831} 2193}
1832 2194
1833static int msp_resume(struct device * dev) 2195static int msp_resume(struct device * dev)
1834{ 2196{
1835 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 2197 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1836 2198
1837 dprintk("msp34xx: resume\n"); 2199 msp3400_dbg("msp34xx: resume\n");
1838 msp_wake_thread(c); 2200 msp_wake_thread(client);
1839 return 0; 2201 return 0;
1840} 2202}
1841 2203
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c
index 972aa5e0aeef..2180018f06de 100644
--- a/drivers/media/video/mt20xx.c
+++ b/drivers/media/video/mt20xx.c
@@ -76,17 +76,17 @@ static int mt2032_compute_freq(struct i2c_client *c,
76 unsigned int xogc) //all in Hz 76 unsigned int xogc) //all in Hz
77{ 77{
78 struct tuner *t = i2c_get_clientdata(c); 78 struct tuner *t = i2c_get_clientdata(c);
79 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, 79 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
80 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; 80 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
81 81
82 fref= 5250 *1000; //5.25MHz 82 fref= 5250 *1000; //5.25MHz
83 desired_lo1=rfin+if1; 83 desired_lo1=rfin+if1;
84 84
85 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000); 85 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
86 lo1n=lo1/8; 86 lo1n=lo1/8;
87 lo1a=lo1-(lo1n*8); 87 lo1a=lo1-(lo1n*8);
88 88
89 s=rfin/1000/1000+1090; 89 s=rfin/1000/1000+1090;
90 90
91 if(optimize_vco) { 91 if(optimize_vco) {
92 if(s>1890) sel=0; 92 if(s>1890) sel=0;
@@ -96,34 +96,34 @@ static int mt2032_compute_freq(struct i2c_client *c,
96 else sel=4; // >1090 96 else sel=4; // >1090
97 } 97 }
98 else { 98 else {
99 if(s>1790) sel=0; // <1958 99 if(s>1790) sel=0; // <1958
100 else if(s>1617) sel=1; 100 else if(s>1617) sel=1;
101 else if(s>1449) sel=2; 101 else if(s>1449) sel=2;
102 else if(s>1291) sel=3; 102 else if(s>1291) sel=3;
103 else sel=4; // >1090 103 else sel=4; // >1090
104 } 104 }
105 *ret_sel=sel; 105 *ret_sel=sel;
106 106
107 lo1freq=(lo1a+8*lo1n)*fref; 107 lo1freq=(lo1a+8*lo1n)*fref;
108 108
109 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n", 109 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
110 rfin,lo1,lo1n,lo1a,sel,lo1freq); 110 rfin,lo1,lo1n,lo1a,sel,lo1freq);
111 111
112 desired_lo2=lo1freq-rfin-if2; 112 desired_lo2=lo1freq-rfin-if2;
113 lo2=(desired_lo2)/fref; 113 lo2=(desired_lo2)/fref;
114 lo2n=lo2/8; 114 lo2n=lo2/8;
115 lo2a=lo2-(lo2n*8); 115 lo2a=lo2-(lo2n*8);
116 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith 116 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
117 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000; 117 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
118 118
119 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", 119 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
120 rfin,lo2,lo2n,lo2a,lo2num,lo2freq); 120 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
121 121
122 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) { 122 if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
123 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", 123 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
124 lo1a, lo1n, lo2a,lo2n); 124 lo1a, lo1n, lo2a,lo2n);
125 return(-1); 125 return(-1);
126 } 126 }
127 127
128 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to); 128 mt2032_spurcheck(c, lo1freq, desired_lo2, spectrum_from, spectrum_to);
129 // should recalculate lo1 (one step up/down) 129 // should recalculate lo1 (one step up/down)
@@ -135,10 +135,10 @@ static int mt2032_compute_freq(struct i2c_client *c,
135 buf[3]=0x0f; //reserved 135 buf[3]=0x0f; //reserved
136 buf[4]=0x1f; 136 buf[4]=0x1f;
137 buf[5]=(lo2n-1) | (lo2a<<5); 137 buf[5]=(lo2n-1) | (lo2a<<5);
138 if(rfin >400*1000*1000) 138 if(rfin >400*1000*1000)
139 buf[6]=0xe4; 139 buf[6]=0xe4;
140 else 140 else
141 buf[6]=0xf4; // set PKEN per rev 1.2 141 buf[6]=0xf4; // set PKEN per rev 1.2
142 buf[7]=8+xogc; 142 buf[7]=8+xogc;
143 buf[8]=0xc3; //reserved 143 buf[8]=0xc3; //reserved
144 buf[9]=0x4e; //reserved 144 buf[9]=0x4e; //reserved
@@ -168,7 +168,7 @@ static int mt2032_check_lo_lock(struct i2c_client *c)
168 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]); 168 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
169 udelay(1000); 169 udelay(1000);
170 } 170 }
171 return lock; 171 return lock;
172} 172}
173 173
174static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock) 174static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
@@ -202,7 +202,7 @@ static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
202 202
203 buf[0]=0x0f; 203 buf[0]=0x0f;
204 buf[1]=sel; 204 buf[1]=sel;
205 i2c_master_send(c,buf,2); 205 i2c_master_send(c,buf,2);
206 lock=mt2032_check_lo_lock(c); 206 lock=mt2032_check_lo_lock(c);
207 return lock; 207 return lock;
208} 208}
@@ -219,23 +219,23 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
219 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", 219 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
220 rfin,if1,if2,from,to); 220 rfin,if1,if2,from,to);
221 221
222 buf[0]=0; 222 buf[0]=0;
223 ret=i2c_master_send(c,buf,1); 223 ret=i2c_master_send(c,buf,1);
224 i2c_master_recv(c,buf,21); 224 i2c_master_recv(c,buf,21);
225 225
226 buf[0]=0; 226 buf[0]=0;
227 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc); 227 ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,t->xogc);
228 if (ret<0) 228 if (ret<0)
229 return; 229 return;
230 230
231 // send only the relevant registers per Rev. 1.2 231 // send only the relevant registers per Rev. 1.2
232 buf[0]=0; 232 buf[0]=0;
233 ret=i2c_master_send(c,buf,4); 233 ret=i2c_master_send(c,buf,4);
234 buf[5]=5; 234 buf[5]=5;
235 ret=i2c_master_send(c,buf+5,4); 235 ret=i2c_master_send(c,buf+5,4);
236 buf[11]=11; 236 buf[11]=11;
237 ret=i2c_master_send(c,buf+11,3); 237 ret=i2c_master_send(c,buf+11,3);
238 if(ret!=3) 238 if(ret!=3)
239 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret); 239 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
240 240
241 // wait for PLLs to lock (per manual), retry LINT if not. 241 // wait for PLLs to lock (per manual), retry LINT if not.
@@ -253,7 +253,7 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
253 mdelay(10); 253 mdelay(10);
254 buf[1]=8+t->xogc; 254 buf[1]=8+t->xogc;
255 i2c_master_send(c,buf,2); 255 i2c_master_send(c,buf,2);
256 } 256 }
257 257
258 if (lock!=6) 258 if (lock!=6)
259 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n"); 259 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
@@ -284,7 +284,7 @@ static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
284 if2 = 38900*1000; 284 if2 = 38900*1000;
285 } 285 }
286 286
287 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, 287 mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
288 1090*1000*1000, if2, from, to); 288 1090*1000*1000, if2, from, to);
289} 289}
290 290
@@ -294,7 +294,7 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
294 int if2 = t->radio_if2; 294 int if2 = t->radio_if2;
295 295
296 // per Manual for FM tuning: first if center freq. 1085 MHz 296 // per Manual for FM tuning: first if center freq. 1085 MHz
297 mt2032_set_if_freq(c, freq * 1000 / 16, 297 mt2032_set_if_freq(c, freq * 1000 / 16,
298 1085*1000*1000,if2,if2,if2); 298 1085*1000*1000,if2,if2,if2);
299} 299}
300 300
@@ -302,57 +302,57 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
302static int mt2032_init(struct i2c_client *c) 302static int mt2032_init(struct i2c_client *c)
303{ 303{
304 struct tuner *t = i2c_get_clientdata(c); 304 struct tuner *t = i2c_get_clientdata(c);
305 unsigned char buf[21]; 305 unsigned char buf[21];
306 int ret,xogc,xok=0; 306 int ret,xogc,xok=0;
307 307
308 // Initialize Registers per spec. 308 // Initialize Registers per spec.
309 buf[1]=2; // Index to register 2 309 buf[1]=2; // Index to register 2
310 buf[2]=0xff; 310 buf[2]=0xff;
311 buf[3]=0x0f; 311 buf[3]=0x0f;
312 buf[4]=0x1f; 312 buf[4]=0x1f;
313 ret=i2c_master_send(c,buf+1,4); 313 ret=i2c_master_send(c,buf+1,4);
314 314
315 buf[5]=6; // Index register 6 315 buf[5]=6; // Index register 6
316 buf[6]=0xe4; 316 buf[6]=0xe4;
317 buf[7]=0x8f; 317 buf[7]=0x8f;
318 buf[8]=0xc3; 318 buf[8]=0xc3;
319 buf[9]=0x4e; 319 buf[9]=0x4e;
320 buf[10]=0xec; 320 buf[10]=0xec;
321 ret=i2c_master_send(c,buf+5,6); 321 ret=i2c_master_send(c,buf+5,6);
322 322
323 buf[12]=13; // Index register 13 323 buf[12]=13; // Index register 13
324 buf[13]=0x32; 324 buf[13]=0x32;
325 ret=i2c_master_send(c,buf+12,2); 325 ret=i2c_master_send(c,buf+12,2);
326 326
327 // Adjust XOGC (register 7), wait for XOK 327 // Adjust XOGC (register 7), wait for XOK
328 xogc=7; 328 xogc=7;
329 do { 329 do {
330 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 330 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
331 mdelay(10); 331 mdelay(10);
332 buf[0]=0x0e; 332 buf[0]=0x0e;
333 i2c_master_send(c,buf,1); 333 i2c_master_send(c,buf,1);
334 i2c_master_recv(c,buf,1); 334 i2c_master_recv(c,buf,1);
335 xok=buf[0]&0x01; 335 xok=buf[0]&0x01;
336 tuner_dbg("mt2032: xok = 0x%02x\n",xok); 336 tuner_dbg("mt2032: xok = 0x%02x\n",xok);
337 if (xok == 1) break; 337 if (xok == 1) break;
338 338
339 xogc--; 339 xogc--;
340 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07); 340 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
341 if (xogc == 3) { 341 if (xogc == 3) {
342 xogc=4; // min. 4 per spec 342 xogc=4; // min. 4 per spec
343 break; 343 break;
344 } 344 }
345 buf[0]=0x07; 345 buf[0]=0x07;
346 buf[1]=0x88 + xogc; 346 buf[1]=0x88 + xogc;
347 ret=i2c_master_send(c,buf,2); 347 ret=i2c_master_send(c,buf,2);
348 if (ret!=2) 348 if (ret!=2)
349 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret); 349 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
350 } while (xok != 1 ); 350 } while (xok != 1 );
351 t->xogc=xogc; 351 t->xogc=xogc;
352 352
353 t->tv_freq = mt2032_set_tv_freq; 353 t->tv_freq = mt2032_set_tv_freq;
354 t->radio_freq = mt2032_set_radio_freq; 354 t->radio_freq = mt2032_set_radio_freq;
355 return(1); 355 return(1);
356} 356}
357 357
358static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna) 358static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
@@ -426,7 +426,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
426 } 426 }
427 427
428 ret=i2c_master_send(c,buf,6); 428 ret=i2c_master_send(c,buf,6);
429 if (ret!=6) 429 if (ret!=6)
430 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); 430 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
431} 431}
432 432
@@ -437,11 +437,11 @@ static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
437 437
438 if (t->std & V4L2_STD_525_60) { 438 if (t->std & V4L2_STD_525_60) {
439 // NTSC 439 // NTSC
440 if2 = 45750*1000; 440 if2 = 45750*1000;
441 } else { 441 } else {
442 // PAL 442 // PAL
443 if2 = 38900*1000; 443 if2 = 38900*1000;
444 } 444 }
445 if (V4L2_TUNER_DIGITAL_TV == t->mode) { 445 if (V4L2_TUNER_DIGITAL_TV == t->mode) {
446 // DVB (pinnacle 300i) 446 // DVB (pinnacle 300i)
447 if2 = 36150*1000; 447 if2 = 36150*1000;
@@ -455,7 +455,7 @@ static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
455 struct tuner *t = i2c_get_clientdata(c); 455 struct tuner *t = i2c_get_clientdata(c);
456 int if2 = t->radio_if2; 456 int if2 = t->radio_if2;
457 457
458 mt2050_set_if_freq(c, freq*62500, if2); 458 mt2050_set_if_freq(c, freq * 1000 / 16, if2);
459 mt2050_set_antenna(c, radio_antenna); 459 mt2050_set_antenna(c, radio_antenna);
460} 460}
461 461
@@ -487,7 +487,7 @@ int microtune_init(struct i2c_client *c)
487{ 487{
488 struct tuner *t = i2c_get_clientdata(c); 488 struct tuner *t = i2c_get_clientdata(c);
489 char *name; 489 char *name;
490 unsigned char buf[21]; 490 unsigned char buf[21];
491 int company_code; 491 int company_code;
492 492
493 memset(buf,0,sizeof(buf)); 493 memset(buf,0,sizeof(buf));
@@ -496,17 +496,17 @@ int microtune_init(struct i2c_client *c)
496 t->standby = NULL; 496 t->standby = NULL;
497 name = "unknown"; 497 name = "unknown";
498 498
499 i2c_master_send(c,buf,1); 499 i2c_master_send(c,buf,1);
500 i2c_master_recv(c,buf,21); 500 i2c_master_recv(c,buf,21);
501 if (tuner_debug) { 501 if (tuner_debug) {
502 int i; 502 int i;
503 tuner_dbg("MT20xx hexdump:"); 503 tuner_dbg("MT20xx hexdump:");
504 for(i=0;i<21;i++) { 504 for(i=0;i<21;i++) {
505 printk(" %02x",buf[i]); 505 printk(" %02x",buf[i]);
506 if(((i+1)%8)==0) printk(" "); 506 if(((i+1)%8)==0) printk(" ");
507 } 507 }
508 printk("\n"); 508 printk("\n");
509 } 509 }
510 company_code = buf[0x11] << 8 | buf[0x12]; 510 company_code = buf[0x11] << 8 | buf[0x12];
511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n", 511 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
512 company_code,buf[0x13],buf[0x14]); 512 company_code,buf[0x13],buf[0x14]);
@@ -525,8 +525,8 @@ int microtune_init(struct i2c_client *c)
525 default: 525 default:
526 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", 526 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
527 name); 527 name);
528 return 0; 528 return 0;
529 } 529 }
530 530
531 strlcpy(c->name, name, sizeof(c->name)); 531 strlcpy(c->name, name, sizeof(c->name));
532 tuner_info("microtune %s found, OK\n",name); 532 tuner_info("microtune %s found, OK\n",name);
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index 72b70eb5da1d..dca3ddfd510f 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -31,7 +31,6 @@
31#include <linux/wait.h> 31#include <linux/wait.h>
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33 33
34#include <media/id.h>
35 34
36#include "rds.h" 35#include "rds.h"
37 36
@@ -246,7 +245,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
246 s->wr_index = 0; 245 s->wr_index = 0;
247 246
248 if (s->wr_index == s->rd_index) { 247 if (s->wr_index == s->rd_index) {
249 s->rd_index++; 248 s->rd_index += 3;
250 if (s->rd_index >= s->buf_size) 249 if (s->rd_index >= s->buf_size)
251 s->rd_index = 0; 250 s->rd_index = 0;
252 } else 251 } else
@@ -328,7 +327,7 @@ static void saa6588_work(void *data)
328 struct saa6588 *s = (struct saa6588 *)data; 327 struct saa6588 *s = (struct saa6588 *)data;
329 328
330 saa6588_i2c_poll(s); 329 saa6588_i2c_poll(s);
331 mod_timer(&s->timer, jiffies + HZ / 50); /* 20 msec */ 330 mod_timer(&s->timer, jiffies + msecs_to_jiffies(20));
332} 331}
333 332
334static int saa6588_configure(struct saa6588 *s) 333static int saa6588_configure(struct saa6588 *s)
@@ -434,9 +433,9 @@ static int saa6588_probe(struct i2c_adapter *adap)
434 return i2c_probe(adap, &addr_data, saa6588_attach); 433 return i2c_probe(adap, &addr_data, saa6588_attach);
435#else 434#else
436 switch (adap->id) { 435 switch (adap->id) {
437 case I2C_ALGO_BIT | I2C_HW_B_BT848: 436 case I2C_HW_B_BT848:
438 case I2C_ALGO_BIT | I2C_HW_B_RIVA: 437 case I2C_HW_B_RIVA:
439 case I2C_ALGO_SAA7134: 438 case I2C_HW_SAA7134:
440 return i2c_probe(adap, &addr_data, saa6588_attach); 439 return i2c_probe(adap, &addr_data, saa6588_attach);
441 break; 440 break;
442 } 441 }
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
new file mode 100644
index 000000000000..9aa8827de2c3
--- /dev/null
+++ b/drivers/media/video/saa711x.c
@@ -0,0 +1,593 @@
1/*
2 * saa711x - Philips SAA711x video decoder driver version 0.0.1
3 *
4 * To do: Now, it handles only saa7113/7114. Should be improved to
5 * handle all Philips saa711x devices.
6 *
7 * Based on saa7113 driver from Dave Perks <dperks@ibm.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/errno.h>
28#include <linux/fs.h>
29#include <linux/kernel.h>
30#include <linux/major.h>
31#include <linux/slab.h>
32#include <linux/mm.h>
33#include <linux/pci.h>
34#include <linux/signal.h>
35#include <asm/io.h>
36#include <asm/pgtable.h>
37#include <asm/page.h>
38#include <linux/sched.h>
39#include <asm/segment.h>
40#include <linux/types.h>
41#include <asm/uaccess.h>
42#include <linux/videodev.h>
43
44MODULE_DESCRIPTION("Philips SAA711x video decoder driver");
45MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland, Dwaine Garden");
46MODULE_LICENSE("GPL");
47
48#include <linux/i2c.h>
49#include <linux/i2c-dev.h>
50
51#define I2C_NAME(s) (s)->name
52
53#include <linux/video_decoder.h>
54
55static int debug = 0;
56MODULE_PARM(debug, "i");
57MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)");
58
59
60#define dprintk(num, format, args...) \
61 do { \
62 if (debug >= num) \
63 printk(format , ##args); \
64 } while (0)
65
66/* ----------------------------------------------------------------------- */
67
68struct saa711x {
69 unsigned char reg[32];
70
71 int norm;
72 int input;
73 int enable;
74 int bright;
75 int contrast;
76 int hue;
77 int sat;
78};
79
80#define I2C_SAA7113 0x4A
81#define I2C_SAA7114 0x42
82
83/* ----------------------------------------------------------------------- */
84
85static inline int
86saa711x_write (struct i2c_client *client,
87 u8 reg,
88 u8 value)
89{
90 struct saa711x *decoder = i2c_get_clientdata(client);
91
92 decoder->reg[reg] = value;
93 return i2c_smbus_write_byte_data(client, reg, value);
94}
95
96static int
97saa711x_write_block (struct i2c_client *client,
98 const u8 *data,
99 unsigned int len)
100{
101 int ret = -1;
102 u8 reg;
103
104 /* the saa711x has an autoincrement function, use it if
105 * the adapter understands raw I2C */
106 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
107 /* do raw I2C, not smbus compatible */
108 struct saa711x *decoder = i2c_get_clientdata(client);
109 struct i2c_msg msg;
110 u8 block_data[32];
111
112 msg.addr = client->addr;
113 msg.flags = 0;
114 while (len >= 2) {
115 msg.buf = (char *) block_data;
116 msg.len = 0;
117 block_data[msg.len++] = reg = data[0];
118 do {
119 block_data[msg.len++] =
120 decoder->reg[reg++] = data[1];
121 len -= 2;
122 data += 2;
123 } while (len >= 2 && data[0] == reg &&
124 msg.len < 32);
125 if ((ret = i2c_transfer(client->adapter,
126 &msg, 1)) < 0)
127 break;
128 }
129 } else {
130 /* do some slow I2C emulation kind of thing */
131 while (len >= 2) {
132 reg = *data++;
133 if ((ret = saa711x_write(client, reg,
134 *data++)) < 0)
135 break;
136 len -= 2;
137 }
138 }
139
140 return ret;
141}
142
143static int
144saa711x_init_decoder (struct i2c_client *client,
145 struct video_decoder_init *init)
146{
147 return saa711x_write_block(client, init->data, init->len);
148}
149
150static inline int
151saa711x_read (struct i2c_client *client,
152 u8 reg)
153{
154 return i2c_smbus_read_byte_data(client, reg);
155}
156
157/* ----------------------------------------------------------------------- */
158
159static const unsigned char saa711x_i2c_init[] = {
160 0x00, 0x00, /* PH711x_CHIP_VERSION 00 - ID byte */
161 0x01, 0x08, /* PH711x_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */
162 0x02, 0xc0, /* PH711x_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */
163 0x03, 0x23, /* PH711x_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */
164 0x04, 0x00, /* PH711x_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */
165 0x05, 0x00, /* PH711x_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */
166 0x06, 0xeb, /* PH711x_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */
167 0x07, 0xe0, /* PH711x_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */
168 0x08, 0x88, /* PH711x_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */
169 0x09, 0x00, /* PH711x_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */
170 0x0a, 0x80, /* PH711x_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */
171 0x0b, 0x47, /* PH711x_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */
172 0x0c, 0x40, /* PH711x_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */
173 0x0d, 0x00, /* PH711x_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */
174 0x0e, 0x01, /* PH711x_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */
175 0x0f, 0xaa, /* PH711x_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */
176 0x10, 0x00, /* PH711x_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */
177 0x11, 0x1C, /* PH711x_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */
178 0x12, 0x01, /* PH711x_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */
179 0x13, 0x00, /* PH711x_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */
180 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */
181 0x15, 0x00, /* PH711x_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */
182 0x16, 0x00, /* PH711x_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */
183 0x17, 0x00, /* PH711x_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
184};
185
186static int
187saa711x_command (struct i2c_client *client,
188 unsigned int cmd,
189 void *arg)
190{
191 struct saa711x *decoder = i2c_get_clientdata(client);
192
193 switch (cmd) {
194
195 case 0:
196 case DECODER_INIT:
197 {
198 struct video_decoder_init *init = arg;
199 if (NULL != init)
200 return saa711x_init_decoder(client, init);
201 else {
202 struct video_decoder_init vdi;
203 vdi.data = saa711x_i2c_init;
204 vdi.len = sizeof(saa711x_i2c_init);
205 return saa711x_init_decoder(client, &vdi);
206 }
207 }
208
209 case DECODER_DUMP:
210 {
211 int i;
212
213 for (i = 0; i < 32; i += 16) {
214 int j;
215
216 printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
217 for (j = 0; j < 16; ++j) {
218 printk(" %02x",
219 saa711x_read(client, i + j));
220 }
221 printk("\n");
222 }
223 }
224 break;
225
226 case DECODER_GET_CAPABILITIES:
227 {
228 struct video_decoder_capability *cap = arg;
229
230 cap->flags = VIDEO_DECODER_PAL |
231 VIDEO_DECODER_NTSC |
232 VIDEO_DECODER_SECAM |
233 VIDEO_DECODER_AUTO |
234 VIDEO_DECODER_CCIR;
235 cap->inputs = 8;
236 cap->outputs = 1;
237 }
238 break;
239
240 case DECODER_GET_STATUS:
241 {
242 int *iarg = arg;
243 int status;
244 int res;
245
246 status = saa711x_read(client, 0x1f);
247 dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
248 status);
249 res = 0;
250 if ((status & (1 << 6)) == 0) {
251 res |= DECODER_STATUS_GOOD;
252 }
253 switch (decoder->norm) {
254 case VIDEO_MODE_NTSC:
255 res |= DECODER_STATUS_NTSC;
256 break;
257 case VIDEO_MODE_PAL:
258 res |= DECODER_STATUS_PAL;
259 break;
260 case VIDEO_MODE_SECAM:
261 res |= DECODER_STATUS_SECAM;
262 break;
263 default:
264 case VIDEO_MODE_AUTO:
265 if ((status & (1 << 5)) != 0) {
266 res |= DECODER_STATUS_NTSC;
267 } else {
268 res |= DECODER_STATUS_PAL;
269 }
270 break;
271 }
272 if ((status & (1 << 0)) != 0) {
273 res |= DECODER_STATUS_COLOR;
274 }
275 *iarg = res;
276 }
277 break;
278
279 case DECODER_SET_GPIO:
280 {
281 int *iarg = arg;
282 if (0 != *iarg) {
283 saa711x_write(client, 0x11,
284 (decoder->reg[0x11] | 0x80));
285 } else {
286 saa711x_write(client, 0x11,
287 (decoder->reg[0x11] & 0x7f));
288 }
289 break;
290 }
291
292 case DECODER_SET_VBI_BYPASS:
293 {
294 int *iarg = arg;
295 if (0 != *iarg) {
296 saa711x_write(client, 0x13,
297 (decoder->reg[0x13] & 0xf0) | 0x0a);
298 } else {
299 saa711x_write(client, 0x13,
300 (decoder->reg[0x13] & 0xf0));
301 }
302 break;
303 }
304
305 case DECODER_SET_NORM:
306 {
307 int *iarg = arg;
308
309 switch (*iarg) {
310
311 case VIDEO_MODE_NTSC:
312 saa711x_write(client, 0x08,
313 (decoder->reg[0x08] & 0x3f) | 0x40);
314 saa711x_write(client, 0x0e,
315 (decoder->reg[0x0e] & 0x8f));
316 break;
317
318 case VIDEO_MODE_PAL:
319 saa711x_write(client, 0x08,
320 (decoder->reg[0x08] & 0x3f) | 0x00);
321 saa711x_write(client, 0x0e,
322 (decoder->reg[0x0e] & 0x8f));
323 break;
324
325 case VIDEO_MODE_SECAM:
326 saa711x_write(client, 0x08,
327 (decoder->reg[0x0e] & 0x3f) | 0x00);
328 saa711x_write(client, 0x0e,
329 (decoder->reg[0x0e] & 0x8f) | 0x50);
330 break;
331
332 case VIDEO_MODE_AUTO:
333 saa711x_write(client, 0x08,
334 (decoder->reg[0x08] & 0x3f) | 0x80);
335 saa711x_write(client, 0x0e,
336 (decoder->reg[0x0e] & 0x8f));
337 break;
338
339 default:
340 return -EINVAL;
341
342 }
343 decoder->norm = *iarg;
344 }
345 break;
346
347 case DECODER_SET_INPUT:
348 {
349 int *iarg = arg;
350 if (*iarg < 0 || *iarg > 9) {
351 return -EINVAL;
352 }
353 if (decoder->input != *iarg) {
354 decoder->input = *iarg;
355 /* select mode */
356 saa711x_write(client, 0x02,
357 (decoder->reg[0x02] & 0xf0) | decoder->input);
358 /* bypass chrominance trap for modes 4..7 */
359 saa711x_write(client, 0x09,
360 (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0));
361 }
362 }
363 break;
364
365 case DECODER_SET_OUTPUT:
366 {
367 int *iarg = arg;
368
369 /* not much choice of outputs */
370 if (*iarg != 0) {
371 return -EINVAL;
372 }
373 }
374 break;
375
376 case DECODER_ENABLE_OUTPUT:
377 {
378 int *iarg = arg;
379 int enable = (*iarg != 0);
380
381 if (decoder->enable != enable) {
382 decoder->enable = enable;
383
384 /* RJ: If output should be disabled (for
385 * playing videos), we also need a open PLL.
386 * The input is set to 0 (where no input
387 * source is connected), although this
388 * is not necessary.
389 *
390 * If output should be enabled, we have to
391 * reverse the above.
392 */
393
394 if (decoder->enable) {
395 saa711x_write(client, 0x02,
396 (decoder->
397 reg[0x02] & 0xf8) |
398 decoder->input);
399 saa711x_write(client, 0x08,
400 (decoder->reg[0x08] & 0xfb));
401 saa711x_write(client, 0x11,
402 (decoder->
403 reg[0x11] & 0xf3) | 0x0c);
404 } else {
405 saa711x_write(client, 0x02,
406 (decoder->reg[0x02] & 0xf8));
407 saa711x_write(client, 0x08,
408 (decoder->
409 reg[0x08] & 0xfb) | 0x04);
410 saa711x_write(client, 0x11,
411 (decoder->reg[0x11] & 0xf3));
412 }
413 }
414 }
415 break;
416
417 case DECODER_SET_PICTURE:
418 {
419 struct video_picture *pic = arg;
420
421 if (decoder->bright != pic->brightness) {
422 /* We want 0 to 255 we get 0-65535 */
423 decoder->bright = pic->brightness;
424 saa711x_write(client, 0x0a, decoder->bright >> 8);
425 }
426 if (decoder->contrast != pic->contrast) {
427 /* We want 0 to 127 we get 0-65535 */
428 decoder->contrast = pic->contrast;
429 saa711x_write(client, 0x0b,
430 decoder->contrast >> 9);
431 }
432 if (decoder->sat != pic->colour) {
433 /* We want 0 to 127 we get 0-65535 */
434 decoder->sat = pic->colour;
435 saa711x_write(client, 0x0c, decoder->sat >> 9);
436 }
437 if (decoder->hue != pic->hue) {
438 /* We want -128 to 127 we get 0-65535 */
439 decoder->hue = pic->hue;
440 saa711x_write(client, 0x0d,
441 (decoder->hue - 32768) >> 8);
442 }
443 }
444 break;
445
446 default:
447 return -EINVAL;
448 }
449
450 return 0;
451}
452
453/* ----------------------------------------------------------------------- */
454
455/*
456 * Generic i2c probe
457 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
458 */
459
460/* standard i2c insmod options */
461static unsigned short normal_i2c[] = {
462 I2C_SAA7113>>1, /* saa7113 */
463 I2C_SAA7114>>1, /* saa7114 */
464 I2C_CLIENT_END
465};
466
467I2C_CLIENT_INSMOD;
468
469
470static struct i2c_driver i2c_driver_saa711x;
471
472static int
473saa711x_detect_client (struct i2c_adapter *adapter,
474 int address,
475 int kind)
476{
477 int i;
478 struct i2c_client *client;
479 struct saa711x *decoder;
480 struct video_decoder_init vdi;
481
482 dprintk(1,
483 KERN_INFO
484 "saa711x.c: detecting saa711x client on address 0x%x\n",
485 address << 1);
486
487 /* Check if the adapter supports the needed features */
488 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
489 return 0;
490
491 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
492 if (client == 0)
493 return -ENOMEM;
494 memset(client, 0, sizeof(struct i2c_client));
495 client->addr = address;
496 client->adapter = adapter;
497 client->driver = &i2c_driver_saa711x;
498 client->flags = I2C_CLIENT_ALLOW_USE;
499 strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client)));
500 decoder = kmalloc(sizeof(struct saa711x), GFP_KERNEL);
501 if (decoder == NULL) {
502 kfree(client);
503 return -ENOMEM;
504 }
505 memset(decoder, 0, sizeof(struct saa711x));
506 decoder->norm = VIDEO_MODE_NTSC;
507 decoder->input = 0;
508 decoder->enable = 1;
509 decoder->bright = 32768;
510 decoder->contrast = 32768;
511 decoder->hue = 32768;
512 decoder->sat = 32768;
513 i2c_set_clientdata(client, decoder);
514
515 i = i2c_attach_client(client);
516 if (i) {
517 kfree(client);
518 kfree(decoder);
519 return i;
520 }
521
522 vdi.data = saa711x_i2c_init;
523 vdi.len = sizeof(saa711x_i2c_init);
524 i = saa711x_init_decoder(client, &vdi);
525 if (i < 0) {
526 dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
527 I2C_NAME(client), i);
528 } else {
529 dprintk(1,
530 KERN_INFO
531 "%s_attach: chip version %x at address 0x%x\n",
532 I2C_NAME(client), saa711x_read(client, 0x00) >> 4,
533 client->addr << 1);
534 }
535
536 return 0;
537}
538
539static int
540saa711x_attach_adapter (struct i2c_adapter *adapter)
541{
542 dprintk(1,
543 KERN_INFO
544 "saa711x.c: starting probe for adapter %s (0x%x)\n",
545 I2C_NAME(adapter), adapter->id);
546 return i2c_probe(adapter, &addr_data, &saa711x_detect_client);
547}
548
549static int
550saa711x_detach_client (struct i2c_client *client)
551{
552 struct saa711x *decoder = i2c_get_clientdata(client);
553 int err;
554
555 err = i2c_detach_client(client);
556 if (err) {
557 return err;
558 }
559
560 kfree(decoder);
561 kfree(client);
562
563 return 0;
564}
565
566/* ----------------------------------------------------------------------- */
567
568static struct i2c_driver i2c_driver_saa711x = {
569 .owner = THIS_MODULE,
570 .name = "saa711x",
571
572 .id = I2C_DRIVERID_SAA711X,
573 .flags = I2C_DF_NOTIFY,
574
575 .attach_adapter = saa711x_attach_adapter,
576 .detach_client = saa711x_detach_client,
577 .command = saa711x_command,
578};
579
580static int __init
581saa711x_init (void)
582{
583 return i2c_add_driver(&i2c_driver_saa711x);
584}
585
586static void __exit
587saa711x_exit (void)
588{
589 i2c_del_driver(&i2c_driver_saa711x);
590}
591
592module_init(saa711x_init);
593module_exit(saa711x_exit);
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
new file mode 100644
index 000000000000..624e8808a517
--- /dev/null
+++ b/drivers/media/video/saa7134/Kconfig
@@ -0,0 +1,68 @@
1config VIDEO_SAA7134
2 tristate "Philips SAA7134 support"
3 depends on VIDEO_DEV && PCI && I2C && SOUND
4 select VIDEO_BUF
5 select VIDEO_IR
6 select VIDEO_TUNER
7 select CRC32
8 ---help---
9 This is a video4linux driver for Philips SAA713x based
10 TV cards.
11
12 To compile this driver as a module, choose M here: the
13 module will be called saa7134.
14
15config VIDEO_SAA7134_DVB
16 tristate "DVB/ATSC Support for saa7134 based TV cards"
17 depends on VIDEO_SAA7134 && DVB_CORE
18 select VIDEO_BUF_DVB
19 ---help---
20 This adds support for DVB cards based on the
21 Philips saa7134 chip.
22
23 To compile this driver as a module, choose M here: the
24 module will be called saa7134-dvb.
25
26 You must also select one or more DVB demodulators.
27 If you are unsure which you need, choose all of them.
28
29config VIDEO_SAA7134_DVB_ALL_FRONTENDS
30 bool "Build all supported frontends for saa7134 based TV cards"
31 default y
32 depends on VIDEO_SAA7134_DVB
33 select DVB_MT352
34 select DVB_TDA1004X
35 select DVB_NXT200X
36 ---help---
37 This builds saa7134-dvb with all currently supported frontend
38 demodulators. If you wish to tweak your configuration, and
39 only include support for the hardware that you need, choose N here.
40
41 If you are unsure, choose Y.
42
43config VIDEO_SAA7134_DVB_MT352
44 tristate "Zarlink MT352 DVB-T Support"
45 default m
46 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
47 select DVB_MT352
48 ---help---
49 This adds DVB-T support for cards based on the
50 Philips saa7134 chip and the MT352 demodulator.
51
52config VIDEO_SAA7134_DVB_TDA1004X
53 tristate "Phillips TDA10045H/TDA10046H DVB-T Support"
54 default m
55 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
56 select DVB_TDA1004X
57 ---help---
58 This adds DVB-T support for cards based on the
59 Philips saa7134 chip and the TDA10045H/TDA10046H demodulator.
60
61config VIDEO_SAA7134_DVB_NXT200X
62 tristate "NXT2002/NXT2004 ATSC Support"
63 default m
64 depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
65 select DVB_NXT200X
66 ---help---
67 This adds ATSC 8VSB and QAM64/256 support for cards based on the
68 Philips saa7134 chip and the NXT2002/NXT2004 demodulator.
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index b778ffd94e65..e0b28f0533af 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -3,15 +3,22 @@ saa7134-objs := saa7134-cards.o saa7134-core.o saa7134-i2c.o \
3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \ 3 saa7134-oss.o saa7134-ts.o saa7134-tvaudio.o \
4 saa7134-vbi.o saa7134-video.o saa7134-input.o 4 saa7134-vbi.o saa7134-video.o saa7134-input.o
5 5
6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o saa6752hs.o 6obj-$(CONFIG_VIDEO_SAA7134) += saa7134.o saa7134-empress.o \
7 saa6752hs.o saa7134-alsa.o
7obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o 8obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
8 9
9EXTRA_CFLAGS += -I$(src)/.. 10EXTRA_CFLAGS += -I$(src)/..
10EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core 11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
11EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends 12EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
13ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
14 EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
15endif
12ifneq ($(CONFIG_DVB_MT352),n) 16ifneq ($(CONFIG_DVB_MT352),n)
13 EXTRA_CFLAGS += -DHAVE_MT352=1 17 EXTRA_CFLAGS += -DHAVE_MT352=1
14endif 18endif
15ifneq ($(CONFIG_DVB_TDA1004X),n) 19ifneq ($(CONFIG_DVB_TDA1004X),n)
16 EXTRA_CFLAGS += -DHAVE_TDA1004X=1 20 EXTRA_CFLAGS += -DHAVE_TDA1004X=1
17endif 21endif
22ifneq ($(CONFIG_DVB_NXT200X),n)
23 EXTRA_CFLAGS += -DHAVE_NXT200X=1
24endif
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 382911c6ef22..cdd1ed9c8065 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -13,7 +13,6 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/crc32.h> 14#include <linux/crc32.h>
15 15
16#include <media/id.h>
17 16
18#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 17#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
19#define MPEG_VIDEO_MAX_BITRATE_MAX 27000 18#define MPEG_VIDEO_MAX_BITRATE_MAX 27000
@@ -57,6 +56,7 @@ struct saa6752hs_state {
57 struct i2c_client client; 56 struct i2c_client client;
58 struct v4l2_mpeg_compression params; 57 struct v4l2_mpeg_compression params;
59 enum saa6752hs_videoformat video_format; 58 enum saa6752hs_videoformat video_format;
59 v4l2_std_id standard;
60}; 60};
61 61
62enum saa6752hs_command { 62enum saa6752hs_command {
@@ -74,58 +74,58 @@ enum saa6752hs_command {
74/* ---------------------------------------------------------------------- */ 74/* ---------------------------------------------------------------------- */
75 75
76static u8 PAT[] = { 76static u8 PAT[] = {
77 0xc2, // i2c register 77 0xc2, /* i2c register */
78 0x00, // table number for encoder 78 0x00, /* table number for encoder */
79 79
80 0x47, // sync 80 0x47, /* sync */
81 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) 81 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid(0) */
82 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) 82 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
83 83
84 0x00, // PSI pointer to start of table 84 0x00, /* PSI pointer to start of table */
85 85
86 0x00, // tid(0) 86 0x00, /* tid(0) */
87 0xb0, 0x0d, // section_syntax_indicator(1), section_length(13) 87 0xb0, 0x0d, /* section_syntax_indicator(1), section_length(13) */
88 88
89 0x00, 0x01, // transport_stream_id(1) 89 0x00, 0x01, /* transport_stream_id(1) */
90 90
91 0xc1, // version_number(0), current_next_indicator(1) 91 0xc1, /* version_number(0), current_next_indicator(1) */
92 92
93 0x00, 0x00, // section_number(0), last_section_number(0) 93 0x00, 0x00, /* section_number(0), last_section_number(0) */
94 94
95 0x00, 0x01, // program_number(1) 95 0x00, 0x01, /* program_number(1) */
96 96
97 0xe0, 0x00, // PMT PID 97 0xe0, 0x00, /* PMT PID */
98 98
99 0x00, 0x00, 0x00, 0x00 // CRC32 99 0x00, 0x00, 0x00, 0x00 /* CRC32 */
100}; 100};
101 101
102static u8 PMT[] = { 102static u8 PMT[] = {
103 0xc2, // i2c register 103 0xc2, /* i2c register */
104 0x01, // table number for encoder 104 0x01, /* table number for encoder */
105 105
106 0x47, // sync 106 0x47, /* sync */
107 0x40, 0x00, // transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid 107 0x40, 0x00, /* transport_error_indicator(0), payload_unit_start(1), transport_priority(0), pid */
108 0x10, // transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) 108 0x10, /* transport_scrambling_control(00), adaptation_field_control(01), continuity_counter(0) */
109 109
110 0x00, // PSI pointer to start of table 110 0x00, /* PSI pointer to start of table */
111 111
112 0x02, // tid(2) 112 0x02, /* tid(2) */
113 0xb0, 0x17, // section_syntax_indicator(1), section_length(23) 113 0xb0, 0x17, /* section_syntax_indicator(1), section_length(23) */
114 114
115 0x00, 0x01, // program_number(1) 115 0x00, 0x01, /* program_number(1) */
116 116
117 0xc1, // version_number(0), current_next_indicator(1) 117 0xc1, /* version_number(0), current_next_indicator(1) */
118 118
119 0x00, 0x00, // section_number(0), last_section_number(0) 119 0x00, 0x00, /* section_number(0), last_section_number(0) */
120 120
121 0xe0, 0x00, // PCR_PID 121 0xe0, 0x00, /* PCR_PID */
122 122
123 0xf0, 0x00, // program_info_length(0) 123 0xf0, 0x00, /* program_info_length(0) */
124 124
125 0x02, 0xe0, 0x00, 0xf0, 0x00, // video stream type(2), pid 125 0x02, 0xe0, 0x00, 0xf0, 0x00, /* video stream type(2), pid */
126 0x04, 0xe0, 0x00, 0xf0, 0x00, // audio stream type(4), pid 126 0x04, 0xe0, 0x00, 0xf0, 0x00, /* audio stream type(4), pid */
127 127
128 0x00, 0x00, 0x00, 0x00 // CRC32 128 0x00, 0x00, 0x00, 0x00 /* CRC32 */
129}; 129};
130 130
131static struct v4l2_mpeg_compression param_defaults = 131static struct v4l2_mpeg_compression param_defaults =
@@ -166,33 +166,33 @@ static int saa6752hs_chip_command(struct i2c_client* client,
166 unsigned long timeout; 166 unsigned long timeout;
167 int status = 0; 167 int status = 0;
168 168
169 // execute the command 169 /* execute the command */
170 switch(command) { 170 switch(command) {
171 case SAA6752HS_COMMAND_RESET: 171 case SAA6752HS_COMMAND_RESET:
172 buf[0] = 0x00; 172 buf[0] = 0x00;
173 break; 173 break;
174 174
175 case SAA6752HS_COMMAND_STOP: 175 case SAA6752HS_COMMAND_STOP:
176 buf[0] = 0x03; 176 buf[0] = 0x03;
177 break; 177 break;
178 178
179 case SAA6752HS_COMMAND_START: 179 case SAA6752HS_COMMAND_START:
180 buf[0] = 0x02; 180 buf[0] = 0x02;
181 break; 181 break;
182 182
183 case SAA6752HS_COMMAND_PAUSE: 183 case SAA6752HS_COMMAND_PAUSE:
184 buf[0] = 0x04; 184 buf[0] = 0x04;
185 break; 185 break;
186 186
187 case SAA6752HS_COMMAND_RECONFIGURE: 187 case SAA6752HS_COMMAND_RECONFIGURE:
188 buf[0] = 0x05; 188 buf[0] = 0x05;
189 break; 189 break;
190 190
191 case SAA6752HS_COMMAND_SLEEP: 191 case SAA6752HS_COMMAND_SLEEP:
192 buf[0] = 0x06; 192 buf[0] = 0x06;
193 break; 193 break;
194 194
195 case SAA6752HS_COMMAND_RECONFIGURE_FORCE: 195 case SAA6752HS_COMMAND_RECONFIGURE_FORCE:
196 buf[0] = 0x07; 196 buf[0] = 0x07;
197 break; 197 break;
198 198
@@ -200,13 +200,13 @@ static int saa6752hs_chip_command(struct i2c_client* client,
200 return -EINVAL; 200 return -EINVAL;
201 } 201 }
202 202
203 // set it and wait for it to be so 203 /* set it and wait for it to be so */
204 i2c_master_send(client, buf, 1); 204 i2c_master_send(client, buf, 1);
205 timeout = jiffies + HZ * 3; 205 timeout = jiffies + HZ * 3;
206 for (;;) { 206 for (;;) {
207 // get the current status 207 /* get the current status */
208 buf[0] = 0x10; 208 buf[0] = 0x10;
209 i2c_master_send(client, buf, 1); 209 i2c_master_send(client, buf, 1);
210 i2c_master_recv(client, buf, 1); 210 i2c_master_recv(client, buf, 1);
211 211
212 if (!(buf[0] & 0x20)) 212 if (!(buf[0] & 0x20))
@@ -216,61 +216,58 @@ static int saa6752hs_chip_command(struct i2c_client* client,
216 break; 216 break;
217 } 217 }
218 218
219 // wait a bit
220 msleep(10); 219 msleep(10);
221 } 220 }
222 221
223 // delay a bit to let encoder settle 222 /* delay a bit to let encoder settle */
224 msleep(50); 223 msleep(50);
225 224
226 // done 225 return status;
227 return status;
228} 226}
229 227
230 228
231static int saa6752hs_set_bitrate(struct i2c_client* client, 229static int saa6752hs_set_bitrate(struct i2c_client* client,
232 struct v4l2_mpeg_compression* params) 230 struct v4l2_mpeg_compression* params)
233{ 231{
234 u8 buf[3]; 232 u8 buf[3];
235 233
236 // set the bitrate mode 234 /* set the bitrate mode */
237 buf[0] = 0x71; 235 buf[0] = 0x71;
238 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1; 236 buf[1] = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ? 0 : 1;
239 i2c_master_send(client, buf, 2); 237 i2c_master_send(client, buf, 2);
240 238
241 // set the video bitrate 239 /* set the video bitrate */
242 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) { 240 if (params->vi_bitrate.mode == V4L2_BITRATE_VBR) {
243 // set the target bitrate 241 /* set the target bitrate */
244 buf[0] = 0x80; 242 buf[0] = 0x80;
245 buf[1] = params->vi_bitrate.target >> 8; 243 buf[1] = params->vi_bitrate.target >> 8;
246 buf[2] = params->vi_bitrate.target & 0xff; 244 buf[2] = params->vi_bitrate.target & 0xff;
247 i2c_master_send(client, buf, 3); 245 i2c_master_send(client, buf, 3);
248 246
249 // set the max bitrate 247 /* set the max bitrate */
250 buf[0] = 0x81; 248 buf[0] = 0x81;
251 buf[1] = params->vi_bitrate.max >> 8; 249 buf[1] = params->vi_bitrate.max >> 8;
252 buf[2] = params->vi_bitrate.max & 0xff; 250 buf[2] = params->vi_bitrate.max & 0xff;
253 i2c_master_send(client, buf, 3); 251 i2c_master_send(client, buf, 3);
254 } else { 252 } else {
255 // set the target bitrate (no max bitrate for CBR) 253 /* set the target bitrate (no max bitrate for CBR) */
256 buf[0] = 0x81; 254 buf[0] = 0x81;
257 buf[1] = params->vi_bitrate.target >> 8; 255 buf[1] = params->vi_bitrate.target >> 8;
258 buf[2] = params->vi_bitrate.target & 0xff; 256 buf[2] = params->vi_bitrate.target & 0xff;
259 i2c_master_send(client, buf, 3); 257 i2c_master_send(client, buf, 3);
260 } 258 }
261 259
262 // set the audio bitrate 260 /* set the audio bitrate */
263 buf[0] = 0x94; 261 buf[0] = 0x94;
264 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1; 262 buf[1] = (256 == params->au_bitrate.target) ? 0 : 1;
265 i2c_master_send(client, buf, 2); 263 i2c_master_send(client, buf, 2);
266 264
267 // set the total bitrate 265 /* set the total bitrate */
268 buf[0] = 0xb1; 266 buf[0] = 0xb1;
269 buf[1] = params->st_bitrate.target >> 8; 267 buf[1] = params->st_bitrate.target >> 8;
270 buf[2] = params->st_bitrate.target & 0xff; 268 buf[2] = params->st_bitrate.target & 0xff;
271 i2c_master_send(client, buf, 3); 269 i2c_master_send(client, buf, 3);
272 270
273 // return success
274 return 0; 271 return 0;
275} 272}
276 273
@@ -376,36 +373,43 @@ static int saa6752hs_init(struct i2c_client* client)
376 373
377 h = i2c_get_clientdata(client); 374 h = i2c_get_clientdata(client);
378 375
379 // Set video format - must be done first as it resets other settings 376 /* Set video format - must be done first as it resets other settings */
380 buf[0] = 0x41; 377 buf[0] = 0x41;
381 buf[1] = h->video_format; 378 buf[1] = h->video_format;
382 i2c_master_send(client, buf, 2); 379 i2c_master_send(client, buf, 2);
383 380
384 // set bitrate 381 /* Set number of lines in input signal */
385 saa6752hs_set_bitrate(client, &h->params); 382 buf[0] = 0x40;
383 buf[1] = 0x00;
384 if (h->standard & V4L2_STD_525_60)
385 buf[1] = 0x01;
386 i2c_master_send(client, buf, 2);
387
388 /* set bitrate */
389 saa6752hs_set_bitrate(client, &h->params);
386 390
387 // Set GOP structure {3, 13} 391 /* Set GOP structure {3, 13} */
388 buf[0] = 0x72; 392 buf[0] = 0x72;
389 buf[1] = 0x03; 393 buf[1] = 0x03;
390 buf[2] = 0x0D; 394 buf[2] = 0x0D;
391 i2c_master_send(client,buf,3); 395 i2c_master_send(client,buf,3);
392 396
393 // Set minimum Q-scale {4} 397 /* Set minimum Q-scale {4} */
394 buf[0] = 0x82; 398 buf[0] = 0x82;
395 buf[1] = 0x04; 399 buf[1] = 0x04;
396 i2c_master_send(client,buf,2); 400 i2c_master_send(client,buf,2);
397 401
398 // Set maximum Q-scale {12} 402 /* Set maximum Q-scale {12} */
399 buf[0] = 0x83; 403 buf[0] = 0x83;
400 buf[1] = 0x0C; 404 buf[1] = 0x0C;
401 i2c_master_send(client,buf,2); 405 i2c_master_send(client,buf,2);
402 406
403 // Set Output Protocol 407 /* Set Output Protocol */
404 buf[0] = 0xD0; 408 buf[0] = 0xD0;
405 buf[1] = 0x81; 409 buf[1] = 0x81;
406 i2c_master_send(client,buf,2); 410 i2c_master_send(client,buf,2);
407 411
408 // Set video output stream format {TS} 412 /* Set video output stream format {TS} */
409 buf[0] = 0xB0; 413 buf[0] = 0xB0;
410 buf[1] = 0x05; 414 buf[1] = 0x05;
411 i2c_master_send(client,buf,2); 415 i2c_master_send(client,buf,2);
@@ -421,9 +425,9 @@ static int saa6752hs_init(struct i2c_client* client)
421 localPAT[sizeof(PAT) - 1] = crc & 0xFF; 425 localPAT[sizeof(PAT) - 1] = crc & 0xFF;
422 426
423 /* compute PMT */ 427 /* compute PMT */
424 memcpy(localPMT, PMT, sizeof(PMT)); 428 memcpy(localPMT, PMT, sizeof(PMT));
425 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f); 429 localPMT[3] = 0x40 | ((h->params.ts_pid_pmt >> 8) & 0x0f);
426 localPMT[4] = h->params.ts_pid_pmt & 0xff; 430 localPMT[4] = h->params.ts_pid_pmt & 0xff;
427 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F); 431 localPMT[15] = 0xE0 | ((h->params.ts_pid_pcr >> 8) & 0x0F);
428 localPMT[16] = h->params.ts_pid_pcr & 0xFF; 432 localPMT[16] = h->params.ts_pid_pcr & 0xFF;
429 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F); 433 localPMT[20] = 0xE0 | ((h->params.ts_pid_video >> 8) & 0x0F);
@@ -436,39 +440,39 @@ static int saa6752hs_init(struct i2c_client* client)
436 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF; 440 localPMT[sizeof(PMT) - 2] = (crc >> 8) & 0xFF;
437 localPMT[sizeof(PMT) - 1] = crc & 0xFF; 441 localPMT[sizeof(PMT) - 1] = crc & 0xFF;
438 442
439 // Set Audio PID 443 /* Set Audio PID */
440 buf[0] = 0xC1; 444 buf[0] = 0xC1;
441 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; 445 buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF;
442 buf[2] = h->params.ts_pid_audio & 0xFF; 446 buf[2] = h->params.ts_pid_audio & 0xFF;
443 i2c_master_send(client,buf,3); 447 i2c_master_send(client,buf,3);
444 448
445 // Set Video PID 449 /* Set Video PID */
446 buf[0] = 0xC0; 450 buf[0] = 0xC0;
447 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; 451 buf[1] = (h->params.ts_pid_video >> 8) & 0xFF;
448 buf[2] = h->params.ts_pid_video & 0xFF; 452 buf[2] = h->params.ts_pid_video & 0xFF;
449 i2c_master_send(client,buf,3); 453 i2c_master_send(client,buf,3);
450 454
451 // Set PCR PID 455 /* Set PCR PID */
452 buf[0] = 0xC4; 456 buf[0] = 0xC4;
453 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; 457 buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF;
454 buf[2] = h->params.ts_pid_pcr & 0xFF; 458 buf[2] = h->params.ts_pid_pcr & 0xFF;
455 i2c_master_send(client,buf,3); 459 i2c_master_send(client,buf,3);
456 460
457 // Send SI tables 461 /* Send SI tables */
458 i2c_master_send(client,localPAT,sizeof(PAT)); 462 i2c_master_send(client,localPAT,sizeof(PAT));
459 i2c_master_send(client,localPMT,sizeof(PMT)); 463 i2c_master_send(client,localPMT,sizeof(PMT));
460 464
461 // mute then unmute audio. This removes buzzing artefacts 465 /* mute then unmute audio. This removes buzzing artefacts */
462 buf[0] = 0xa4; 466 buf[0] = 0xa4;
463 buf[1] = 1; 467 buf[1] = 1;
464 i2c_master_send(client, buf, 2); 468 i2c_master_send(client, buf, 2);
465 buf[1] = 0; 469 buf[1] = 0;
466 i2c_master_send(client, buf, 2); 470 i2c_master_send(client, buf, 2);
467 471
468 // start it going 472 /* start it going */
469 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); 473 saa6752hs_chip_command(client, SAA6752HS_COMMAND_START);
470 474
471 // readout current state 475 /* readout current state */
472 buf[0] = 0xE1; 476 buf[0] = 0xE1;
473 buf[1] = 0xA7; 477 buf[1] = 0xA7;
474 buf[2] = 0xFE; 478 buf[2] = 0xFE;
@@ -477,7 +481,7 @@ static int saa6752hs_init(struct i2c_client* client)
477 i2c_master_send(client, buf, 5); 481 i2c_master_send(client, buf, 5);
478 i2c_master_recv(client, buf2, 4); 482 i2c_master_recv(client, buf2, 4);
479 483
480 // change aspect ratio 484 /* change aspect ratio */
481 buf[0] = 0xE0; 485 buf[0] = 0xE0;
482 buf[1] = 0xA7; 486 buf[1] = 0xA7;
483 buf[2] = 0xFE; 487 buf[2] = 0xFE;
@@ -498,7 +502,6 @@ static int saa6752hs_init(struct i2c_client* client)
498 buf[8] = buf2[3]; 502 buf[8] = buf2[3];
499 i2c_master_send(client, buf, 9); 503 i2c_master_send(client, buf, 9);
500 504
501 // return success
502 return 0; 505 return 0;
503} 506}
504 507
@@ -506,16 +509,19 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
506{ 509{
507 struct saa6752hs_state *h; 510 struct saa6752hs_state *h;
508 511
509 printk("saa6752hs: chip found @ 0x%x\n", addr<<1); 512 printk("saa6752hs: chip found @ 0x%x\n", addr<<1);
510 513
511 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) 514 if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL)))
512 return -ENOMEM; 515 return -ENOMEM;
513 memset(h,0,sizeof(*h)); 516 memset(h,0,sizeof(*h));
514 h->client = client_template; 517 h->client = client_template;
515 h->params = param_defaults; 518 h->params = param_defaults;
516 h->client.adapter = adap; 519 h->client.adapter = adap;
517 h->client.addr = addr; 520 h->client.addr = addr;
518 521
522 /* Assume 625 input lines */
523 h->standard = 0;
524
519 i2c_set_clientdata(&h->client, h); 525 i2c_set_clientdata(&h->client, h);
520 i2c_attach_client(&h->client); 526 i2c_attach_client(&h->client);
521 return 0; 527 return 0;
@@ -545,7 +551,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
545 struct v4l2_mpeg_compression *params = arg; 551 struct v4l2_mpeg_compression *params = arg;
546 int err = 0; 552 int err = 0;
547 553
548 switch (cmd) { 554 switch (cmd) {
549 case VIDIOC_S_MPEGCOMP: 555 case VIDIOC_S_MPEGCOMP:
550 if (NULL == params) { 556 if (NULL == params) {
551 /* apply settings and start encoder */ 557 /* apply settings and start encoder */
@@ -559,7 +565,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
559 break; 565 break;
560 case VIDIOC_G_FMT: 566 case VIDIOC_G_FMT:
561 { 567 {
562 struct v4l2_format *f = arg; 568 struct v4l2_format *f = arg;
563 569
564 if (h->video_format == SAA6752HS_VF_UNKNOWN) 570 if (h->video_format == SAA6752HS_VF_UNKNOWN)
565 h->video_format = SAA6752HS_VF_D1; 571 h->video_format = SAA6752HS_VF_D1;
@@ -576,6 +582,9 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
576 saa6752hs_set_subsampling(client, f); 582 saa6752hs_set_subsampling(client, f);
577 break; 583 break;
578 } 584 }
585 case VIDIOC_S_STD:
586 h->standard = *((v4l2_std_id *) arg);
587 break;
579 default: 588 default:
580 /* nothing */ 589 /* nothing */
581 break; 590 break;
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
new file mode 100644
index 000000000000..4f3c42354329
--- /dev/null
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -0,0 +1,1047 @@
1/*
2 * SAA713x ALSA support for V4L
3 *
4 *
5 * Caveats:
6 * - Volume doesn't work (it's always at max)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <sound/driver.h>
24#include <linux/init.h>
25#include <linux/slab.h>
26#include <linux/time.h>
27#include <linux/wait.h>
28#include <linux/moduleparam.h>
29#include <linux/module.h>
30#include <sound/core.h>
31#include <sound/control.h>
32#include <sound/pcm.h>
33#include <sound/initval.h>
34
35#include "saa7134.h"
36#include "saa7134-reg.h"
37
38static unsigned int debug = 0;
39module_param(debug, int, 0644);
40MODULE_PARM_DESC(debug,"enable debug messages [alsa]");
41
42/*
43 * Configuration macros
44 */
45
46/* defaults */
47#define MIXER_ADDR_TVTUNER 0
48#define MIXER_ADDR_LINE1 1
49#define MIXER_ADDR_LINE2 2
50#define MIXER_ADDR_LAST 2
51
52static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
53static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
54static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
55
56module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
58
59#define dprintk(fmt, arg...) if (debug) \
60 printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
61
62/*
63 * Main chip structure
64 */
65typedef struct snd_card_saa7134 {
66 snd_card_t *card;
67 spinlock_t mixer_lock;
68 int mixer_volume[MIXER_ADDR_LAST+1][2];
69 int capture_source[MIXER_ADDR_LAST+1][2];
70 struct pci_dev *pci;
71 struct saa7134_dev *saadev;
72
73 unsigned long iobase;
74 int irq;
75
76 spinlock_t lock;
77} snd_card_saa7134_t;
78
79
80
81/*
82 * PCM structure
83 */
84
85typedef struct snd_card_saa7134_pcm {
86 struct saa7134_dev *saadev;
87
88 spinlock_t lock;
89 unsigned int pcm_size; /* buffer size */
90 unsigned int pcm_count; /* bytes per period */
91 unsigned int pcm_bps; /* bytes per second */
92 snd_pcm_substream_t *substream;
93} snd_card_saa7134_pcm_t;
94
95static snd_card_t *snd_saa7134_cards[SNDRV_CARDS];
96
97
98/*
99 * saa7134 DMA audio stop
100 *
101 * Called when the capture device is released or the buffer overflows
102 *
103 * - Copied verbatim from saa7134-oss's dsp_dma_stop. Can be dropped
104 * if we just share dsp_dma_stop and use it here
105 *
106 */
107
108static void saa7134_dma_stop(struct saa7134_dev *dev)
109
110{
111 dev->dmasound.dma_blk = -1;
112 dev->dmasound.dma_running = 0;
113 saa7134_set_dmabits(dev);
114}
115
116/*
117 * saa7134 DMA audio start
118 *
119 * Called when preparing the capture device for use
120 *
121 * - Copied verbatim from saa7134-oss's dsp_dma_start. Can be dropped
122 * if we just share dsp_dma_start and use it here
123 *
124 */
125
126static void saa7134_dma_start(struct saa7134_dev *dev)
127{
128 dev->dmasound.dma_blk = 0;
129 dev->dmasound.dma_running = 1;
130 saa7134_set_dmabits(dev);
131}
132
133/*
134 * saa7134 audio DMA IRQ handler
135 *
136 * Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt
137 * Handles shifting between the 2 buffers, manages the read counters,
138 * and notifies ALSA when periods elapse
139 *
140 * - Mostly copied from saa7134-oss's saa7134_irq_oss_done.
141 *
142 */
143
144void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
145{
146 int next_blk, reg = 0;
147
148 spin_lock(&dev->slock);
149 if (UNSET == dev->dmasound.dma_blk) {
150 dprintk("irq: recording stopped\n");
151 goto done;
152 }
153 if (0 != (status & 0x0f000000))
154 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
155 if (0 == (status & 0x10000000)) {
156 /* odd */
157 if (0 == (dev->dmasound.dma_blk & 0x01))
158 reg = SAA7134_RS_BA1(6);
159 } else {
160 /* even */
161 if (1 == (dev->dmasound.dma_blk & 0x01))
162 reg = SAA7134_RS_BA2(6);
163 }
164 if (0 == reg) {
165 dprintk("irq: field oops [%s]\n",
166 (status & 0x10000000) ? "even" : "odd");
167 goto done;
168 }
169
170 if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
171 dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
172 dev->dmasound.bufsize, dev->dmasound.blocks);
173 snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
174 saa7134_dma_stop(dev);
175 goto done;
176 }
177
178 /* next block addr */
179 next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
180 saa_writel(reg,next_blk * dev->dmasound.blksize);
181 if (debug > 2)
182 dprintk("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
183 (status & 0x10000000) ? "even" : "odd ", next_blk,
184 next_blk * dev->dmasound.blksize, dev->dmasound.blocks, dev->dmasound.blksize, dev->dmasound.read_count);
185
186 /* update status & wake waiting readers */
187 dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
188 dev->dmasound.read_count += dev->dmasound.blksize;
189
190 dev->dmasound.recording_on = reg;
191
192 if (dev->dmasound.read_count >= snd_pcm_lib_period_bytes(dev->dmasound.substream)) {
193 spin_unlock(&dev->slock);
194 snd_pcm_period_elapsed(dev->dmasound.substream);
195 spin_lock(&dev->slock);
196 }
197 done:
198 spin_unlock(&dev->slock);
199
200}
201
202/*
203 * IRQ request handler
204 *
205 * Runs along with saa7134's IRQ handler, discards anything that isn't
206 * DMA sound
207 *
208 */
209
210static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
211{
212 struct saa7134_dev *dev = (struct saa7134_dev*) dev_id;
213 unsigned long report, status;
214 int loop, handled = 0;
215
216 for (loop = 0; loop < 10; loop++) {
217 report = saa_readl(SAA7134_IRQ_REPORT);
218 status = saa_readl(SAA7134_IRQ_STATUS);
219
220 if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
221 handled = 1;
222 saa_writel(SAA7134_IRQ_REPORT,report);
223 saa7134_irq_alsa_done(dev, status);
224 } else {
225 goto out;
226 }
227 }
228
229 if (loop == 10) {
230 dprintk("error! looping IRQ!");
231 }
232
233out:
234 return IRQ_RETVAL(handled);
235}
236
237/*
238 * ALSA capture trigger
239 *
240 * - One of the ALSA capture callbacks.
241 *
242 * Called whenever a capture is started or stopped. Must be defined,
243 * but there's nothing we want to do here
244 *
245 */
246
247static int snd_card_saa7134_capture_trigger(snd_pcm_substream_t * substream,
248 int cmd)
249{
250 snd_pcm_runtime_t *runtime = substream->runtime;
251 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
252 struct saa7134_dev *dev=saapcm->saadev;
253 int err = 0;
254
255 spin_lock_irq(&dev->slock);
256 if (cmd == SNDRV_PCM_TRIGGER_START) {
257 /* start dma */
258 saa7134_dma_start(dev);
259 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
260 /* stop dma */
261 saa7134_dma_stop(dev);
262 } else {
263 err = -EINVAL;
264 }
265 spin_unlock_irq(&dev->slock);
266
267 return err;
268}
269
270/*
271 * DMA buffer config
272 *
273 * Sets the values that will later be used as the size of the buffer,
274 * size of the fragments, and total number of fragments.
275 * Must be called during the preparation stage, before memory is
276 * allocated
277 *
278 * - Copied verbatim from saa7134-oss. Can be dropped
279 * if we just share dsp_buffer_conf from OSS.
280 */
281
282static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
283{
284 if (blksize < 0x100)
285 blksize = 0x100;
286 if (blksize > 0x10000)
287 blksize = 0x10000;
288
289 if (blocks < 2)
290 blocks = 2;
291 if ((blksize * blocks) > 1024*1024)
292 blocks = 1024*1024 / blksize;
293
294 dev->dmasound.blocks = blocks;
295 dev->dmasound.blksize = blksize;
296 dev->dmasound.bufsize = blksize * blocks;
297
298 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
299 blocks,blksize,blksize * blocks / 1024);
300 return 0;
301}
302
303/*
304 * DMA buffer initialization
305 *
306 * Uses V4L functions to initialize the DMA. Shouldn't be necessary in
307 * ALSA, but I was unable to use ALSA's own DMA, and had to force the
308 * usage of V4L's
309 *
310 * - Copied verbatim from saa7134-oss. Can be dropped
311 * if we just share dsp_buffer_init from OSS.
312 */
313
314static int dsp_buffer_init(struct saa7134_dev *dev)
315{
316 int err;
317
318 if (!dev->dmasound.bufsize)
319 BUG();
320 videobuf_dma_init(&dev->dmasound.dma);
321 err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
322 (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
323 if (0 != err)
324 return err;
325 return 0;
326}
327
328/*
329 * ALSA PCM preparation
330 *
331 * - One of the ALSA capture callbacks.
332 *
333 * Called right after the capture device is opened, this function configures
334 * the buffer using the previously defined functions, allocates the memory,
335 * sets up the hardware registers, and then starts the DMA. When this function
336 * returns, the audio should be flowing.
337 *
338 */
339
340static int snd_card_saa7134_capture_prepare(snd_pcm_substream_t * substream)
341{
342 snd_pcm_runtime_t *runtime = substream->runtime;
343 int err, bswap, sign;
344 u32 fmt, control;
345 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
346 struct saa7134_dev *dev;
347 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
348 unsigned int bps;
349 unsigned long size;
350 unsigned count;
351
352 size = snd_pcm_lib_buffer_bytes(substream);
353 count = snd_pcm_lib_period_bytes(substream);
354
355 saapcm->saadev->dmasound.substream = substream;
356 bps = runtime->rate * runtime->channels;
357 bps *= snd_pcm_format_width(runtime->format);
358 bps /= 8;
359 if (bps <= 0)
360 return -EINVAL;
361 saapcm->pcm_bps = bps;
362 saapcm->pcm_size = snd_pcm_lib_buffer_bytes(substream);
363 saapcm->pcm_count = snd_pcm_lib_period_bytes(substream);
364
365
366 dev=saa7134->saadev;
367
368 dsp_buffer_conf(dev,saapcm->pcm_count,(saapcm->pcm_size/saapcm->pcm_count));
369
370 err = dsp_buffer_init(dev);
371 if (0 != err)
372 goto fail2;
373
374 /* prepare buffer */
375 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
376 return err;
377 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
378 goto fail1;
379 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
380 dev->dmasound.dma.sglist,
381 dev->dmasound.dma.sglen,
382 0)))
383 goto fail2;
384
385
386
387 switch (runtime->format) {
388 case SNDRV_PCM_FORMAT_U8:
389 case SNDRV_PCM_FORMAT_S8:
390 fmt = 0x00;
391 break;
392 case SNDRV_PCM_FORMAT_U16_LE:
393 case SNDRV_PCM_FORMAT_U16_BE:
394 case SNDRV_PCM_FORMAT_S16_LE:
395 case SNDRV_PCM_FORMAT_S16_BE:
396 fmt = 0x01;
397 break;
398 default:
399 err = -EINVAL;
400 return 1;
401 }
402
403 switch (runtime->format) {
404 case SNDRV_PCM_FORMAT_S8:
405 case SNDRV_PCM_FORMAT_S16_LE:
406 case SNDRV_PCM_FORMAT_S16_BE:
407 sign = 1;
408 break;
409 default:
410 sign = 0;
411 break;
412 }
413
414 switch (runtime->format) {
415 case SNDRV_PCM_FORMAT_U16_BE:
416 case SNDRV_PCM_FORMAT_S16_BE:
417 bswap = 1; break;
418 default:
419 bswap = 0; break;
420 }
421
422 switch (dev->pci->device) {
423 case PCI_DEVICE_ID_PHILIPS_SAA7134:
424 if (1 == runtime->channels)
425 fmt |= (1 << 3);
426 if (2 == runtime->channels)
427 fmt |= (3 << 3);
428 if (sign)
429 fmt |= 0x04;
430
431 fmt |= (MIXER_ADDR_TVTUNER == dev->dmasound.input) ? 0xc0 : 0x80;
432 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
433 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
434 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
435 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
436
437 break;
438 case PCI_DEVICE_ID_PHILIPS_SAA7133:
439 case PCI_DEVICE_ID_PHILIPS_SAA7135:
440 if (1 == runtime->channels)
441 fmt |= (1 << 4);
442 if (2 == runtime->channels)
443 fmt |= (2 << 4);
444 if (!sign)
445 fmt |= 0x04;
446 saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
447 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
448 //saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210);
449 break;
450 }
451
452 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
453 runtime->format, runtime->channels, fmt,
454 bswap ? 'b' : '-');
455 /* dma: setup channel 6 (= AUDIO) */
456 control = SAA7134_RS_CONTROL_BURST_16 |
457 SAA7134_RS_CONTROL_ME |
458 (dev->dmasound.pt.dma >> 12);
459 if (bswap)
460 control |= SAA7134_RS_CONTROL_BSWAP;
461
462 /* I should be able to use runtime->dma_addr in the control
463 byte, but it doesn't work. So I allocate the DMA using the
464 V4L functions, and force ALSA to use that as the DMA area */
465
466 runtime->dma_area = dev->dmasound.dma.vmalloc;
467
468 saa_writel(SAA7134_RS_BA1(6),0);
469 saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
470 saa_writel(SAA7134_RS_PITCH(6),0);
471 saa_writel(SAA7134_RS_CONTROL(6),control);
472
473 dev->dmasound.rate = runtime->rate;
474
475 return 0;
476 fail2:
477 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
478 fail1:
479 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
480 return err;
481
482
483}
484
485/*
486 * ALSA pointer fetching
487 *
488 * - One of the ALSA capture callbacks.
489 *
490 * Called whenever a period elapses, it must return the current hardware
491 * position of the buffer.
492 * Also resets the read counter used to prevent overruns
493 *
494 */
495
496static snd_pcm_uframes_t snd_card_saa7134_capture_pointer(snd_pcm_substream_t * substream)
497{
498 snd_pcm_runtime_t *runtime = substream->runtime;
499 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
500 struct saa7134_dev *dev=saapcm->saadev;
501
502
503
504 if (dev->dmasound.read_count) {
505 dev->dmasound.read_count -= snd_pcm_lib_period_bytes(substream);
506 dev->dmasound.read_offset += snd_pcm_lib_period_bytes(substream);
507 if (dev->dmasound.read_offset == dev->dmasound.bufsize)
508 dev->dmasound.read_offset = 0;
509 }
510
511 return bytes_to_frames(runtime, dev->dmasound.read_offset);
512}
513
514/*
515 * ALSA hardware capabilities definition
516 */
517
518static snd_pcm_hardware_t snd_card_saa7134_capture =
519{
520 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
521 SNDRV_PCM_INFO_BLOCK_TRANSFER |
522 SNDRV_PCM_INFO_MMAP_VALID),
523 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
524 SNDRV_PCM_FMTBIT_S16_BE | \
525 SNDRV_PCM_FMTBIT_S8 | \
526 SNDRV_PCM_FMTBIT_U8 | \
527 SNDRV_PCM_FMTBIT_U16_LE | \
528 SNDRV_PCM_FMTBIT_U16_BE,
529 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
530 .rate_min = 32000,
531 .rate_max = 48000,
532 .channels_min = 1,
533 .channels_max = 2,
534 .buffer_bytes_max = (256*1024),
535 .period_bytes_min = 64,
536 .period_bytes_max = (256*1024),
537 .periods_min = 2,
538 .periods_max = 1024,
539};
540
541static void snd_card_saa7134_runtime_free(snd_pcm_runtime_t *runtime)
542{
543 snd_card_saa7134_pcm_t *saapcm = runtime->private_data;
544
545 kfree(saapcm);
546}
547
548
549/*
550 * ALSA hardware params
551 *
552 * - One of the ALSA capture callbacks.
553 *
554 * Called on initialization, right before the PCM preparation
555 * Usually used in ALSA to allocate the DMA, but since we don't use the
556 * ALSA DMA it does nothing
557 *
558 */
559
560static int snd_card_saa7134_hw_params(snd_pcm_substream_t * substream,
561 snd_pcm_hw_params_t * hw_params)
562{
563
564 return 0;
565
566
567}
568
569/*
570 * ALSA hardware release
571 *
572 * - One of the ALSA capture callbacks.
573 *
574 * Called after closing the device, but before snd_card_saa7134_capture_close
575 * Usually used in ALSA to free the DMA, but since we don't use the
576 * ALSA DMA I'm almost sure this isn't necessary.
577 *
578 */
579
580static int snd_card_saa7134_hw_free(snd_pcm_substream_t * substream)
581{
582 return 0;
583}
584
585/*
586 * DMA buffer release
587 *
588 * Called after closing the device, during snd_card_saa7134_capture_close
589 *
590 */
591
592static int dsp_buffer_free(struct saa7134_dev *dev)
593{
594 if (!dev->dmasound.blksize)
595 BUG();
596
597 videobuf_dma_free(&dev->dmasound.dma);
598
599 dev->dmasound.blocks = 0;
600 dev->dmasound.blksize = 0;
601 dev->dmasound.bufsize = 0;
602
603 return 0;
604}
605
606/*
607 * ALSA capture finish
608 *
609 * - One of the ALSA capture callbacks.
610 *
611 * Called after closing the device. It stops the DMA audio and releases
612 * the buffers
613 *
614 */
615
616static int snd_card_saa7134_capture_close(snd_pcm_substream_t * substream)
617{
618 snd_card_saa7134_t *chip = snd_pcm_substream_chip(substream);
619 struct saa7134_dev *dev = chip->saadev;
620
621 /* unlock buffer */
622 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
623 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
624
625 dsp_buffer_free(dev);
626 return 0;
627}
628
629/*
630 * ALSA capture start
631 *
632 * - One of the ALSA capture callbacks.
633 *
634 * Called when opening the device. It creates and populates the PCM
635 * structure
636 *
637 */
638
639static int snd_card_saa7134_capture_open(snd_pcm_substream_t * substream)
640{
641 snd_pcm_runtime_t *runtime = substream->runtime;
642 snd_card_saa7134_pcm_t *saapcm;
643 snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
644 struct saa7134_dev *dev = saa7134->saadev;
645 int err;
646
647 down(&dev->dmasound.lock);
648
649 dev->dmasound.afmt = SNDRV_PCM_FORMAT_U8;
650 dev->dmasound.channels = 2;
651 dev->dmasound.read_count = 0;
652 dev->dmasound.read_offset = 0;
653
654 up(&dev->dmasound.lock);
655
656 saapcm = kzalloc(sizeof(*saapcm), GFP_KERNEL);
657 if (saapcm == NULL)
658 return -ENOMEM;
659 saapcm->saadev=saa7134->saadev;
660
661 spin_lock_init(&saapcm->lock);
662
663 saapcm->substream = substream;
664 runtime->private_data = saapcm;
665 runtime->private_free = snd_card_saa7134_runtime_free;
666 runtime->hw = snd_card_saa7134_capture;
667
668 if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
669 return err;
670
671 return 0;
672}
673
674/*
675 * ALSA capture callbacks definition
676 */
677
678static snd_pcm_ops_t snd_card_saa7134_capture_ops = {
679 .open = snd_card_saa7134_capture_open,
680 .close = snd_card_saa7134_capture_close,
681 .ioctl = snd_pcm_lib_ioctl,
682 .hw_params = snd_card_saa7134_hw_params,
683 .hw_free = snd_card_saa7134_hw_free,
684 .prepare = snd_card_saa7134_capture_prepare,
685 .trigger = snd_card_saa7134_capture_trigger,
686 .pointer = snd_card_saa7134_capture_pointer,
687};
688
689/*
690 * ALSA PCM setup
691 *
692 * Called when initializing the board. Sets up the name and hooks up
693 * the callbacks
694 *
695 */
696
697static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
698{
699 snd_pcm_t *pcm;
700 int err;
701
702 if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
703 return err;
704 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
705 pcm->private_data = saa7134;
706 pcm->info_flags = 0;
707 strcpy(pcm->name, "SAA7134 PCM");
708 return 0;
709}
710
711#define SAA713x_VOLUME(xname, xindex, addr) \
712{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
713 .info = snd_saa7134_volume_info, \
714 .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
715 .private_value = addr }
716
717static int snd_saa7134_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
718{
719 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
720 uinfo->count = 2;
721 uinfo->value.integer.min = 0;
722 uinfo->value.integer.max = 20;
723 return 0;
724}
725
726static int snd_saa7134_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
727{
728 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
729 int addr = kcontrol->private_value;
730
731 ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0];
732 ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1];
733 return 0;
734}
735
736static int snd_saa7134_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
737{
738 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
739 unsigned long flags;
740 int change, addr = kcontrol->private_value;
741 int left, right;
742
743 left = ucontrol->value.integer.value[0];
744 if (left < 0)
745 left = 0;
746 if (left > 20)
747 left = 20;
748 right = ucontrol->value.integer.value[1];
749 if (right < 0)
750 right = 0;
751 if (right > 20)
752 right = 20;
753 spin_lock_irqsave(&chip->mixer_lock, flags);
754 change = chip->mixer_volume[addr][0] != left ||
755 chip->mixer_volume[addr][1] != right;
756 chip->mixer_volume[addr][0] = left;
757 chip->mixer_volume[addr][1] = right;
758 spin_unlock_irqrestore(&chip->mixer_lock, flags);
759 return change;
760}
761
762#define SAA713x_CAPSRC(xname, xindex, addr) \
763{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
764 .info = snd_saa7134_capsrc_info, \
765 .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
766 .private_value = addr }
767
768static int snd_saa7134_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
769{
770 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
771 uinfo->count = 2;
772 uinfo->value.integer.min = 0;
773 uinfo->value.integer.max = 1;
774 return 0;
775}
776
777static int snd_saa7134_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
778{
779 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
780 unsigned long flags;
781 int addr = kcontrol->private_value;
782
783 spin_lock_irqsave(&chip->mixer_lock, flags);
784 ucontrol->value.integer.value[0] = chip->capture_source[addr][0];
785 ucontrol->value.integer.value[1] = chip->capture_source[addr][1];
786 spin_unlock_irqrestore(&chip->mixer_lock, flags);
787 return 0;
788}
789
790static int snd_saa7134_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
791{
792 snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
793 unsigned long flags;
794 int change, addr = kcontrol->private_value;
795 int left, right;
796 u32 anabar, xbarin;
797 int analog_io, rate;
798 struct saa7134_dev *dev;
799
800 dev = chip->saadev;
801
802 left = ucontrol->value.integer.value[0] & 1;
803 right = ucontrol->value.integer.value[1] & 1;
804 spin_lock_irqsave(&chip->mixer_lock, flags);
805
806 change = chip->capture_source[addr][0] != left ||
807 chip->capture_source[addr][1] != right;
808 chip->capture_source[addr][0] = left;
809 chip->capture_source[addr][1] = right;
810 dev->dmasound.input=addr;
811 spin_unlock_irqrestore(&chip->mixer_lock, flags);
812
813
814 if (change) {
815 switch (dev->pci->device) {
816
817 case PCI_DEVICE_ID_PHILIPS_SAA7134:
818 switch (addr) {
819 case MIXER_ADDR_TVTUNER:
820 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
821 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
822 break;
823 case MIXER_ADDR_LINE1:
824 case MIXER_ADDR_LINE2:
825 analog_io = (MIXER_ADDR_LINE1 == addr) ? 0x00 : 0x08;
826 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
827 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
828 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
829 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
830 break;
831 }
832
833 break;
834 case PCI_DEVICE_ID_PHILIPS_SAA7133:
835 case PCI_DEVICE_ID_PHILIPS_SAA7135:
836 xbarin = 0x03; // adc
837 anabar = 0;
838 switch (addr) {
839 case MIXER_ADDR_TVTUNER:
840 xbarin = 0; // Demodulator
841 anabar = 2; // DACs
842 break;
843 case MIXER_ADDR_LINE1:
844 anabar = 0; // aux1, aux1
845 break;
846 case MIXER_ADDR_LINE2:
847 anabar = 9; // aux2, aux2
848 break;
849 }
850
851 /* output xbar always main channel */
852 saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1, 0xbbbb10);
853
854 if (left || right) { // We've got data, turn the input on
855 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, xbarin);
856 saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
857 } else {
858 saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1, 0);
859 saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
860 }
861 break;
862 }
863 }
864
865 return change;
866}
867
868static snd_kcontrol_new_t snd_saa7134_controls[] = {
869SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
870SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
871SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
872SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
873SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
874SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
875};
876
877/*
878 * ALSA mixer setup
879 *
880 * Called when initializing the board. Sets up the name and hooks up
881 * the callbacks
882 *
883 */
884
885static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
886{
887 snd_card_t *card = chip->card;
888 unsigned int idx;
889 int err;
890
891 snd_assert(chip != NULL, return -EINVAL);
892 strcpy(card->mixername, "SAA7134 Mixer");
893
894 for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_controls); idx++) {
895 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_saa7134_controls[idx], chip))) < 0)
896 return err;
897 }
898 return 0;
899}
900
901static int snd_saa7134_free(snd_card_saa7134_t *chip)
902{
903 return 0;
904}
905
906static int snd_saa7134_dev_free(snd_device_t *device)
907{
908 snd_card_saa7134_t *chip = device->device_data;
909 return snd_saa7134_free(chip);
910}
911
912/*
913 * ALSA initialization
914 *
915 * Called by saa7134-core, it creates the basic structures and registers
916 * the ALSA devices
917 *
918 */
919
920int alsa_card_saa7134_create (struct saa7134_dev *saadev)
921{
922 static int dev;
923
924 snd_card_t *card;
925 snd_card_saa7134_t *chip;
926 int err;
927 static snd_device_ops_t ops = {
928 .dev_free = snd_saa7134_dev_free,
929 };
930
931
932 if (dev >= SNDRV_CARDS)
933 return -ENODEV;
934 if (!enable[dev])
935 return -ENODEV;
936
937 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
938
939 if (card == NULL)
940 return -ENOMEM;
941
942 strcpy(card->driver, "SAA7134");
943
944 /* Card "creation" */
945
946 chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
947 if (chip == NULL) {
948 return -ENOMEM;
949 }
950
951 spin_lock_init(&chip->lock);
952 spin_lock_init(&chip->mixer_lock);
953
954 chip->saadev = saadev;
955
956 chip->card = card;
957
958 chip->pci = saadev->pci;
959 chip->irq = saadev->pci->irq;
960 chip->iobase = pci_resource_start(saadev->pci, 0);
961
962 err = request_irq(saadev->pci->irq, saa7134_alsa_irq,
963 SA_SHIRQ | SA_INTERRUPT, saadev->name, saadev);
964
965 if (err < 0) {
966 printk(KERN_ERR "%s: can't get IRQ %d for ALSA\n",
967 saadev->name, saadev->pci->irq);
968 goto __nodev;
969 }
970
971 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
972 goto __nodev;
973 }
974
975 if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
976 goto __nodev;
977
978 if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
979 goto __nodev;
980
981 snd_card_set_dev(card, &chip->pci->dev);
982
983 /* End of "creation" */
984
985 strcpy(card->shortname, "SAA7134");
986 sprintf(card->longname, "%s at 0x%lx irq %d",
987 chip->saadev->name, chip->iobase, chip->irq);
988
989 if ((err = snd_card_register(card)) == 0) {
990 snd_saa7134_cards[dev] = card;
991 return 0;
992 }
993
994__nodev:
995 snd_card_free(card);
996 kfree(chip);
997 return err;
998}
999
1000/*
1001 * Module initializer
1002 *
1003 * Loops through present saa7134 cards, and assigns an ALSA device
1004 * to each one
1005 *
1006 */
1007
1008static int saa7134_alsa_init(void)
1009{
1010 struct saa7134_dev *saadev = NULL;
1011 struct list_head *list;
1012
1013 printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
1014
1015 list_for_each(list,&saa7134_devlist) {
1016 saadev = list_entry(list, struct saa7134_dev, devlist);
1017 alsa_card_saa7134_create(saadev);
1018 }
1019
1020 if (saadev == NULL)
1021 printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
1022
1023 return 0;
1024
1025}
1026
1027/*
1028 * Module destructor
1029 */
1030
1031void saa7134_alsa_exit(void)
1032{
1033 int idx;
1034
1035 for (idx = 0; idx < SNDRV_CARDS; idx++) {
1036 snd_card_free(snd_saa7134_cards[idx]);
1037 }
1038
1039 printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
1040
1041 return;
1042}
1043
1044module_init(saa7134_alsa_init);
1045module_exit(saa7134_alsa_exit);
1046MODULE_LICENSE("GPL");
1047MODULE_AUTHOR("Ricardo Cerqueira");
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index acc7a4335e23..663d03e5bc67 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -191,10 +191,14 @@ struct saa7134_board saa7134_boards[] = {
191 .amux = TV, 191 .amux = TV,
192 .tv = 1, 192 .tv = 1,
193 },{ 193 },{
194 .name = name_comp1, 194 .name = name_comp1, /* Composite signal on S-Video input */
195 .vmux = 0, 195 .vmux = 0,
196 .amux = LINE2, 196 .amux = LINE2,
197 },{ 197 },{
198 .name = name_comp2, /* Composite input */
199 .vmux = 3,
200 .amux = LINE2,
201 },{
198 .name = name_svideo, 202 .name = name_svideo,
199 .vmux = 8, 203 .vmux = 8,
200 .amux = LINE2, 204 .amux = LINE2,
@@ -2109,8 +2113,423 @@ struct saa7134_board saa7134_boards[] = {
2109 .gpio = 0x01, 2113 .gpio = 0x01,
2110 }, 2114 },
2111 }, 2115 },
2112}; 2116 [SAA7134_BOARD_BEHOLD_409FM] = {
2117 /* <http://tuner.beholder.ru>, Sergey <skiv@orel.ru> */
2118 .name = "Beholder BeholdTV 409 FM",
2119 .audio_clock = 0x00187de7,
2120 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
2121 .radio_type = UNSET,
2122 .tuner_addr = ADDR_UNSET,
2123 .radio_addr = ADDR_UNSET,
2124 .tda9887_conf = TDA9887_PRESENT,
2125 .inputs = {{
2126 .name = name_tv,
2127 .vmux = 3,
2128 .amux = TV,
2129 .tv = 1,
2130 },{
2131 .name = name_comp1,
2132 .vmux = 1,
2133 .amux = LINE1,
2134 },{
2135 .name = name_svideo,
2136 .vmux = 8,
2137 .amux = LINE1,
2138 }},
2139 .radio = {
2140 .name = name_radio,
2141 .amux = LINE2,
2142 },
2143 },
2144 [SAA7134_BOARD_GOTVIEW_7135] = {
2145 /* Mike Baikov <mike@baikov.com> */
2146 /* Andrey Cvetcov <ays14@yandex.ru> */
2147 .name = "GoTView 7135 PCI",
2148 .audio_clock = 0x00187de7,
2149 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
2150 .radio_type = UNSET,
2151 .tuner_addr = ADDR_UNSET,
2152 .radio_addr = ADDR_UNSET,
2153 .tda9887_conf = TDA9887_PRESENT,
2154 .gpiomask = 0x00200003,
2155 .inputs = {{
2156 .name = name_tv,
2157 .vmux = 1,
2158 .amux = TV,
2159 .tv = 1,
2160 .gpio = 0x00200003,
2161 },{
2162 .name = name_tv_mono,
2163 .vmux = 1,
2164 .amux = LINE2,
2165 .gpio = 0x00200003,
2166 },{
2167 .name = name_comp1,
2168 .vmux = 3,
2169 .amux = LINE1,
2170 .gpio = 0x00200003,
2171 },{
2172 .name = name_svideo,
2173 .vmux = 8,
2174 .amux = LINE1,
2175 .gpio = 0x00200003,
2176 }},
2177 .radio = {
2178 .name = name_radio,
2179 .amux = LINE2,
2180 .gpio = 0x00200003,
2181 },
2182 .mute = {
2183 .name = name_mute,
2184 .amux = TV,
2185 .gpio = 0x00200003,
2186 },
2187 },
2188 [SAA7134_BOARD_PHILIPS_EUROPA] = {
2189 .name = "Philips EUROPA V3 reference design",
2190 .audio_clock = 0x00187de7,
2191 .tuner_type = TUNER_PHILIPS_TD1316,
2192 .radio_type = UNSET,
2193 .tuner_addr = 0x61,
2194 .radio_addr = ADDR_UNSET,
2195 .tda9887_conf = TDA9887_PRESENT,
2196 .mpeg = SAA7134_MPEG_DVB,
2197 .inputs = {{
2198 .name = name_tv,
2199 .vmux = 3,
2200 .amux = TV,
2201 .tv = 1,
2202 },{
2203 .name = name_comp1,
2204 .vmux = 0,
2205 .amux = LINE2,
2206 },{
2207 .name = name_svideo,
2208 .vmux = 8,
2209 .amux = LINE2,
2210 }},
2211 },
2212 [SAA7134_BOARD_VIDEOMATE_DVBT_300] = {
2213 .name = "Compro Videomate DVB-T300",
2214 .audio_clock = 0x00187de7,
2215 .tuner_type = TUNER_PHILIPS_TD1316,
2216 .radio_type = UNSET,
2217 .tuner_addr = 0x61,
2218 .radio_addr = ADDR_UNSET,
2219 .tda9887_conf = TDA9887_PRESENT,
2220 .mpeg = SAA7134_MPEG_DVB,
2221 .inputs = {{
2222 .name = name_tv,
2223 .vmux = 3,
2224 .amux = TV,
2225 .tv = 1,
2226 },{
2227 .name = name_comp1,
2228 .vmux = 1,
2229 .amux = LINE2,
2230 },{
2231 .name = name_svideo,
2232 .vmux = 8,
2233 .amux = LINE2,
2234 }},
2235 },
2236 [SAA7134_BOARD_VIDEOMATE_DVBT_200] = {
2237 .name = "Compro Videomate DVB-T200",
2238 .tuner_type = TUNER_ABSENT,
2239 .audio_clock = 0x00187de7,
2240 .radio_type = UNSET,
2241 .tuner_addr = ADDR_UNSET,
2242 .radio_addr = ADDR_UNSET,
2243 .mpeg = SAA7134_MPEG_DVB,
2244 .inputs = {{
2245 .name = name_comp1,
2246 .vmux = 0,
2247 .amux = LINE1,
2248 },{
2249 .name = name_svideo,
2250 .vmux = 8,
2251 .amux = LINE1,
2252 }},
2253 },
2254 [SAA7134_BOARD_RTD_VFG7350] = {
2255 .name = "RTD Embedded Technologies VFG7350",
2256 .audio_clock = 0x00200000,
2257 .tuner_type = TUNER_ABSENT,
2258 .radio_type = UNSET,
2259 .tuner_addr = ADDR_UNSET,
2260 .radio_addr = ADDR_UNSET,
2261 .inputs = {{
2262 .name = "Composite 0",
2263 .vmux = 0,
2264 .amux = LINE1,
2265 },{
2266 .name = "Composite 1",
2267 .vmux = 1,
2268 .amux = LINE2,
2269 },{
2270 .name = "Composite 2",
2271 .vmux = 2,
2272 .amux = LINE1,
2273 },{
2274 .name = "Composite 3",
2275 .vmux = 3,
2276 .amux = LINE2,
2277 },{
2278 .name = "S-Video 0",
2279 .vmux = 8,
2280 .amux = LINE1,
2281 },{
2282 .name = "S-Video 1",
2283 .vmux = 9,
2284 .amux = LINE2,
2285 }},
2286 .mpeg = SAA7134_MPEG_EMPRESS,
2287 .video_out = CCIR656,
2288 .vid_port_opts = ( SET_T_CODE_POLARITY_NON_INVERTED |
2289 SET_CLOCK_NOT_DELAYED |
2290 SET_CLOCK_INVERTED |
2291 SET_VSYNC_OFF ),
2292 },
2293 [SAA7134_BOARD_RTD_VFG7330] = {
2294 .name = "RTD Embedded Technologies VFG7330",
2295 .audio_clock = 0x00200000,
2296 .tuner_type = TUNER_ABSENT,
2297 .radio_type = UNSET,
2298 .tuner_addr = ADDR_UNSET,
2299 .radio_addr = ADDR_UNSET,
2300 .inputs = {{
2301 .name = "Composite 0",
2302 .vmux = 0,
2303 .amux = LINE1,
2304 },{
2305 .name = "Composite 1",
2306 .vmux = 1,
2307 .amux = LINE2,
2308 },{
2309 .name = "Composite 2",
2310 .vmux = 2,
2311 .amux = LINE1,
2312 },{
2313 .name = "Composite 3",
2314 .vmux = 3,
2315 .amux = LINE2,
2316 },{
2317 .name = "S-Video 0",
2318 .vmux = 8,
2319 .amux = LINE1,
2320 },{
2321 .name = "S-Video 1",
2322 .vmux = 9,
2323 .amux = LINE2,
2324 }},
2325 },
2326 [SAA7134_BOARD_FLYTVPLATINUM_MINI2] = {
2327 .name = "LifeView FlyTV Platinum Mini2",
2328 .audio_clock = 0x00200000,
2329 .tuner_type = TUNER_PHILIPS_TDA8290,
2330 .radio_type = UNSET,
2331 .tuner_addr = ADDR_UNSET,
2332 .radio_addr = ADDR_UNSET,
2113 2333
2334 .inputs = {{
2335 .name = name_tv,
2336 .vmux = 1,
2337 .amux = TV,
2338 .tv = 1,
2339 },{
2340 .name = name_comp1, /* Composite signal on S-Video input */
2341 .vmux = 0,
2342 .amux = LINE2,
2343 },{
2344 .name = name_comp2, /* Composite input */
2345 .vmux = 3,
2346 .amux = LINE2,
2347 },{
2348 .name = name_svideo,
2349 .vmux = 8,
2350 .amux = LINE2,
2351 }},
2352 },
2353 [SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180] = {
2354 /* Michael Krufky <mkrufky@m1k.net>
2355 * Uses Alps Electric TDHU2, containing NXT2004 ATSC Decoder
2356 * AFAIK, there is no analog demod, thus,
2357 * no support for analog television.
2358 */
2359 .name = "AVerMedia AVerTVHD MCE A180",
2360 .audio_clock = 0x00187de7,
2361 .tuner_type = TUNER_ABSENT,
2362 .radio_type = UNSET,
2363 .tuner_addr = ADDR_UNSET,
2364 .radio_addr = ADDR_UNSET,
2365 .mpeg = SAA7134_MPEG_DVB,
2366 .inputs = {{
2367 .name = name_comp1,
2368 .vmux = 3,
2369 .amux = LINE2,
2370 },{
2371 .name = name_svideo,
2372 .vmux = 8,
2373 .amux = LINE2,
2374 }},
2375 },
2376 [SAA7134_BOARD_MONSTERTV_MOBILE] = {
2377 .name = "SKNet MonsterTV Mobile",
2378 .audio_clock = 0x00187de7,
2379 .tuner_type = TUNER_PHILIPS_TDA8290,
2380 .radio_type = UNSET,
2381 .tuner_addr = ADDR_UNSET,
2382 .radio_addr = ADDR_UNSET,
2383
2384 .inputs = {{
2385 .name = name_tv,
2386 .vmux = 1,
2387 .amux = TV,
2388 .tv = 1,
2389 },{
2390 .name = name_comp1,
2391 .vmux = 3,
2392 .amux = LINE1,
2393 },{
2394 .name = name_svideo,
2395 .vmux = 6,
2396 .amux = LINE1,
2397 }},
2398 },
2399 [SAA7134_BOARD_PINNACLE_PCTV_110i] = {
2400 .name = "Pinnacle PCTV 110i (saa7133)",
2401 .audio_clock = 0x00187de7,
2402 .tuner_type = TUNER_PHILIPS_TDA8290,
2403 .radio_type = UNSET,
2404 .tuner_addr = ADDR_UNSET,
2405 .radio_addr = ADDR_UNSET,
2406 .gpiomask = 0x080200000,
2407 .inputs = {{
2408 .name = name_tv,
2409 .vmux = 4,
2410 .amux = TV,
2411 .tv = 1,
2412 },{
2413 .name = name_comp1,
2414 .vmux = 1,
2415 .amux = LINE2,
2416 },{
2417 .name = name_svideo,
2418 .vmux = 8,
2419 .amux = LINE2,
2420 }},
2421 .radio = {
2422 .name = name_radio,
2423 .amux = LINE1,
2424 },
2425 },
2426 [SAA7134_BOARD_ASUSTeK_P7131_DUAL] = {
2427 .name = "ASUSTeK P7131 Dual",
2428 .audio_clock = 0x00187de7,
2429 .tuner_type = TUNER_PHILIPS_TDA8290,
2430 .radio_type = UNSET,
2431 .tuner_addr = ADDR_UNSET,
2432 .radio_addr = ADDR_UNSET,
2433 .gpiomask = 1 << 21,
2434 .mpeg = SAA7134_MPEG_DVB,
2435 .inputs = {{
2436 .name = name_tv,
2437 .vmux = 1,
2438 .amux = TV,
2439 .tv = 1,
2440 },{
2441 .name = name_comp1,
2442 .vmux = 3,
2443 .amux = LINE2,
2444 },{
2445 .name = name_svideo,
2446 .vmux = 8,
2447 .amux = LINE2,
2448 }},
2449 .radio = {
2450 .name = name_radio,
2451 .amux = TV,
2452 .gpio = 0x0200000,
2453 },
2454 },
2455 [SAA7134_BOARD_SEDNA_PC_TV_CARDBUS] = {
2456 /* Paul Tom Zalac <pzalac@gmail.com> */
2457 /* Pavel Mihaylov <bin@bash.info> */
2458 .name = "Sedna/MuchTV PC TV Cardbus TV/Radio (ITO25 Rev:2B)",
2459 /* Sedna/MuchTV (OEM) Cardbus TV Tuner */
2460 .audio_clock = 0x00187de7,
2461 .tuner_type = TUNER_PHILIPS_TDA8290,
2462 .radio_type = UNSET,
2463 .tuner_addr = ADDR_UNSET,
2464 .radio_addr = ADDR_UNSET,
2465 .gpiomask = 0xe880c0,
2466 .inputs = {{
2467 .name = name_tv,
2468 .vmux = 3,
2469 .amux = TV,
2470 .tv = 1,
2471 },{
2472 .name = name_comp1,
2473 .vmux = 1,
2474 .amux = LINE1,
2475 },{
2476 .name = name_svideo,
2477 .vmux = 6,
2478 .amux = LINE1,
2479 }},
2480 .radio = {
2481 .name = name_radio,
2482 .amux = LINE2,
2483 },
2484 },
2485 [SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV] = {
2486 /* "Cyril Lacoux (Yack)" <clacoux@ifeelgood.org> */
2487 .name = "ASUS Digimatrix TV",
2488 .audio_clock = 0x00200000,
2489 .tuner_type = TUNER_PHILIPS_FQ1216ME,
2490 .tda9887_conf = TDA9887_PRESENT,
2491 .radio_type = UNSET,
2492 .tuner_addr = ADDR_UNSET,
2493 .radio_addr = ADDR_UNSET,
2494 .inputs = {{
2495 .name = name_tv,
2496 .vmux = 1,
2497 .amux = TV,
2498 .tv = 1,
2499 },{
2500 .name = name_comp1,
2501 .vmux = 3,
2502 .amux = LINE1,
2503 },{
2504 .name = name_svideo,
2505 .vmux = 8,
2506 .amux = LINE1,
2507 }},
2508 },
2509 [SAA7134_BOARD_PHILIPS_TIGER] = {
2510 .name = "Philips Tiger reference design",
2511 .audio_clock = 0x00187de7,
2512 .tuner_type = TUNER_PHILIPS_TDA8290,
2513 .radio_type = UNSET,
2514 .tuner_addr = ADDR_UNSET,
2515 .radio_addr = ADDR_UNSET,
2516 .mpeg = SAA7134_MPEG_DVB,
2517 .inputs = {{
2518 .name = name_tv,
2519 .vmux = 1,
2520 .amux = TV,
2521 .tv = 1,
2522 },{
2523 .name = name_comp1,
2524 .vmux = 3,
2525 .amux = LINE1,
2526 },{
2527 .name = name_svideo,
2528 .vmux = 8,
2529 .amux = LINE1,
2530 }},
2531 },
2532};
2114 2533
2115const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); 2534const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
2116 2535
@@ -2145,19 +2564,19 @@ struct pci_device_id saa7134_pci_tbl[] = {
2145 },{ 2564 },{
2146 .vendor = PCI_VENDOR_ID_PHILIPS, 2565 .vendor = PCI_VENDOR_ID_PHILIPS,
2147 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2566 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2148 .subvendor = 0x153B, 2567 .subvendor = 0x153b,
2149 .subdevice = 0x1142, 2568 .subdevice = 0x1142,
2150 .driver_data = SAA7134_BOARD_CINERGY400, 2569 .driver_data = SAA7134_BOARD_CINERGY400,
2151 },{ 2570 },{
2152 .vendor = PCI_VENDOR_ID_PHILIPS, 2571 .vendor = PCI_VENDOR_ID_PHILIPS,
2153 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2572 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2154 .subvendor = 0x153B, 2573 .subvendor = 0x153b,
2155 .subdevice = 0x1143, 2574 .subdevice = 0x1143,
2156 .driver_data = SAA7134_BOARD_CINERGY600, 2575 .driver_data = SAA7134_BOARD_CINERGY600,
2157 },{ 2576 },{
2158 .vendor = PCI_VENDOR_ID_PHILIPS, 2577 .vendor = PCI_VENDOR_ID_PHILIPS,
2159 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2578 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2160 .subvendor = 0x153B, 2579 .subvendor = 0x153b,
2161 .subdevice = 0x1158, 2580 .subdevice = 0x1158,
2162 .driver_data = SAA7134_BOARD_CINERGY600_MK3, 2581 .driver_data = SAA7134_BOARD_CINERGY600_MK3,
2163 },{ 2582 },{
@@ -2193,6 +2612,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
2193 },{ 2612 },{
2194 .vendor = PCI_VENDOR_ID_PHILIPS, 2613 .vendor = PCI_VENDOR_ID_PHILIPS,
2195 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 2614 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2615 .subvendor = 0x14c0,
2616 .subdevice = 0x1212, /* minipci, LR1212 */
2617 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI2,
2618 },{
2619 .vendor = PCI_VENDOR_ID_PHILIPS,
2620 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2621 .subvendor = 0x4e42,
2622 .subdevice = 0x0212, /* OEM minipci, LR212 */
2623 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI,
2624 },{
2625 .vendor = PCI_VENDOR_ID_PHILIPS,
2626 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2196 .subvendor = 0x5168, /* Animation Technologies (LifeView) */ 2627 .subvendor = 0x5168, /* Animation Technologies (LifeView) */
2197 .subdevice = 0x0214, /* Standard PCI, LR214WF */ 2628 .subdevice = 0x0214, /* Standard PCI, LR214WF */
2198 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM, 2629 .driver_data = SAA7134_BOARD_FLYTVPLATINUM_FM,
@@ -2369,7 +2800,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
2369 },{ 2800 },{
2370 .vendor = PCI_VENDOR_ID_PHILIPS, 2801 .vendor = PCI_VENDOR_ID_PHILIPS,
2371 .device = PCI_DEVICE_ID_PHILIPS_SAA7130, 2802 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
2372 .subvendor = 0x153B, 2803 .subvendor = 0x153b,
2373 .subdevice = 0x1152, 2804 .subdevice = 0x1152,
2374 .driver_data = SAA7134_BOARD_CINERGY200, 2805 .driver_data = SAA7134_BOARD_CINERGY200,
2375 },{ 2806 },{
@@ -2434,13 +2865,18 @@ struct pci_device_id saa7134_pci_tbl[] = {
2434 .subvendor = 0x1421, 2865 .subvendor = 0x1421,
2435 .subdevice = 0x0350, /* PCI version */ 2866 .subdevice = 0x0350, /* PCI version */
2436 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, 2867 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2437
2438 },{ 2868 },{
2439 .vendor = PCI_VENDOR_ID_PHILIPS, 2869 .vendor = PCI_VENDOR_ID_PHILIPS,
2440 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 2870 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2441 .subvendor = 0x1421, 2871 .subvendor = 0x1421,
2442 .subdevice = 0x0370, /* cardbus version */ 2872 .subdevice = 0x0370, /* cardbus version */
2443 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, 2873 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2874 },{
2875 .vendor = PCI_VENDOR_ID_PHILIPS,
2876 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2877 .subvendor = 0x1421,
2878 .subdevice = 0x1370, /* cardbus version */
2879 .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
2444 2880
2445 },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */ 2881 },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */
2446 .vendor = PCI_VENDOR_ID_PHILIPS, 2882 .vendor = PCI_VENDOR_ID_PHILIPS,
@@ -2459,9 +2895,81 @@ struct pci_device_id saa7134_pci_tbl[] = {
2459 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2895 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2460 .subvendor = 0x1043, 2896 .subvendor = 0x1043,
2461 .subdevice = 0x0210, /* mini pci PAL/SECAM version */ 2897 .subdevice = 0x0210, /* mini pci PAL/SECAM version */
2462 .driver_data = SAA7134_BOARD_FLYTV_DIGIMATRIX, 2898 .driver_data = SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV,
2463 2899
2464 },{ 2900 },{
2901 .vendor = PCI_VENDOR_ID_PHILIPS,
2902 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2903 .subvendor = 0x0000, /* It shouldn't break anything, since subdevice id seems unique */
2904 .subdevice = 0x4091,
2905 .driver_data = SAA7134_BOARD_BEHOLD_409FM,
2906 },{
2907 .vendor = PCI_VENDOR_ID_PHILIPS,
2908 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2909 .subvendor = 0x5456, /* GoTView */
2910 .subdevice = 0x7135,
2911 .driver_data = SAA7134_BOARD_GOTVIEW_7135,
2912 },{
2913 .vendor = PCI_VENDOR_ID_PHILIPS,
2914 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2915 .subvendor = PCI_VENDOR_ID_PHILIPS,
2916 .subdevice = 0x2004,
2917 .driver_data = SAA7134_BOARD_PHILIPS_EUROPA,
2918 },{
2919 .vendor = PCI_VENDOR_ID_PHILIPS,
2920 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
2921 .subvendor = 0x185b,
2922 .subdevice = 0xc900,
2923 .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_300,
2924 },{
2925 .vendor = PCI_VENDOR_ID_PHILIPS,
2926 .device = PCI_DEVICE_ID_PHILIPS_SAA7130,
2927 .subvendor = 0x185b,
2928 .subdevice = 0xc901,
2929 .driver_data = SAA7134_BOARD_VIDEOMATE_DVBT_200,
2930 },{
2931 .vendor = PCI_VENDOR_ID_PHILIPS,
2932 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2933 .subvendor = 0x1435,
2934 .subdevice = 0x7350,
2935 .driver_data = SAA7134_BOARD_RTD_VFG7350,
2936 },{
2937 .vendor = PCI_VENDOR_ID_PHILIPS,
2938 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2939 .subvendor = 0x1435,
2940 .subdevice = 0x7330,
2941 .driver_data = SAA7134_BOARD_RTD_VFG7330,
2942 },{
2943 .vendor = PCI_VENDOR_ID_PHILIPS,
2944 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2945 .subvendor = 0x1461,
2946 .subdevice = 0x1044,
2947 .driver_data = SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180,
2948 },{
2949 .vendor = PCI_VENDOR_ID_PHILIPS,
2950 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2951 .subvendor = 0x1131,
2952 .subdevice = 0x4ee9,
2953 .driver_data = SAA7134_BOARD_MONSTERTV_MOBILE,
2954 },{
2955 .vendor = PCI_VENDOR_ID_PHILIPS,
2956 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2957 .subvendor = 0x11bd,
2958 .subdevice = 0x002e,
2959 .driver_data = SAA7134_BOARD_PINNACLE_PCTV_110i,
2960 },{
2961 .vendor = PCI_VENDOR_ID_PHILIPS,
2962 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2963 .subvendor = 0x1043,
2964 .subdevice = 0x4862,
2965 .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL,
2966 },{
2967 .vendor = PCI_VENDOR_ID_PHILIPS,
2968 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
2969 .subvendor = PCI_VENDOR_ID_PHILIPS,
2970 .subdevice = 0x2018,
2971 .driver_data = SAA7134_BOARD_PHILIPS_TIGER,
2972 },{
2465 /* --- boards without eeprom + subsystem ID --- */ 2973 /* --- boards without eeprom + subsystem ID --- */
2466 .vendor = PCI_VENDOR_ID_PHILIPS, 2974 .vendor = PCI_VENDOR_ID_PHILIPS,
2467 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 2975 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -2530,9 +3038,10 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2530 switch (dev->board) { 3038 switch (dev->board) {
2531 case SAA7134_BOARD_FLYVIDEO2000: 3039 case SAA7134_BOARD_FLYVIDEO2000:
2532 case SAA7134_BOARD_FLYVIDEO3000: 3040 case SAA7134_BOARD_FLYVIDEO3000:
2533 dev->has_remote = 1; 3041 dev->has_remote = SAA7134_REMOTE_GPIO;
2534 board_flyvideo(dev); 3042 board_flyvideo(dev);
2535 break; 3043 break;
3044 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
2536 case SAA7134_BOARD_FLYTVPLATINUM_FM: 3045 case SAA7134_BOARD_FLYTVPLATINUM_FM:
2537 case SAA7134_BOARD_CINERGY400: 3046 case SAA7134_BOARD_CINERGY400:
2538 case SAA7134_BOARD_CINERGY600: 3047 case SAA7134_BOARD_CINERGY600:
@@ -2550,10 +3059,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2550/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ 3059/* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */
2551 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 3060 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
2552 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 3061 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
3062 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
3063 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
2553 case SAA7134_BOARD_MANLI_MTV001: 3064 case SAA7134_BOARD_MANLI_MTV001:
2554 case SAA7134_BOARD_MANLI_MTV002: 3065 case SAA7134_BOARD_MANLI_MTV002:
3066 case SAA7134_BOARD_BEHOLD_409FM:
2555 case SAA7134_BOARD_AVACSSMARTTV: 3067 case SAA7134_BOARD_AVACSSMARTTV:
2556 dev->has_remote = 1; 3068 case SAA7134_BOARD_GOTVIEW_7135:
3069 case SAA7134_BOARD_KWORLD_TERMINATOR:
3070 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
3071 dev->has_remote = SAA7134_REMOTE_GPIO;
2557 break; 3072 break;
2558 case SAA7134_BOARD_MD5044: 3073 case SAA7134_BOARD_MD5044:
2559 printk("%s: seems there are two different versions of the MD5044\n" 3074 printk("%s: seems there are two different versions of the MD5044\n"
@@ -2565,11 +3080,14 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2565 /* power-up tuner chip */ 3080 /* power-up tuner chip */
2566 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); 3081 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
2567 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000); 3082 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000000);
2568 msleep(1); 3083 case SAA7134_BOARD_MONSTERTV_MOBILE:
3084 /* power-up tuner chip */
3085 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000);
3086 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004);
2569 break; 3087 break;
2570 case SAA7134_BOARD_FLYDVBTDUO: 3088 case SAA7134_BOARD_FLYDVBTDUO:
2571 case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: 3089 case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS:
2572 /* turn the fan on Hac: static for the time being */ 3090 /* turn the fan on */
2573 saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); 3091 saa_writeb(SAA7134_GPIO_GPMODE3, 0x08);
2574 saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); 3092 saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06);
2575 break; 3093 break;
@@ -2579,6 +3097,22 @@ int saa7134_board_init1(struct saa7134_dev *dev)
2579 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff); 3097 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0xffffffff, 0xffffffff);
2580 msleep(1); 3098 msleep(1);
2581 break; 3099 break;
3100 case SAA7134_BOARD_RTD_VFG7350:
3101
3102 /*
3103 * Make sure Production Test Register at offset 0x1D1 is cleared
3104 * to take chip out of test mode. Clearing bit 4 (TST_EN_AOUT)
3105 * prevents pin 105 from remaining low; keeping pin 105 low
3106 * continually resets the SAA6752 chip.
3107 */
3108
3109 saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
3110 break;
3111 /* i2c remotes */
3112 case SAA7134_BOARD_PINNACLE_PCTV_110i:
3113 case SAA7134_BOARD_UPMOST_PURPLE_TV:
3114 dev->has_remote = SAA7134_REMOTE_I2C;
3115 break;
2582 } 3116 }
2583 return 0; 3117 return 0;
2584} 3118}
@@ -2613,7 +3147,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
2613 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup); 3147 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR, &tun_setup);
2614 } 3148 }
2615 break; 3149 break;
2616case SAA7134_BOARD_MD7134: 3150 case SAA7134_BOARD_MD7134:
2617 { 3151 {
2618 struct tuner_setup tun_setup; 3152 struct tuner_setup tun_setup;
2619 u8 subaddr; 3153 u8 subaddr;
@@ -2680,6 +3214,33 @@ case SAA7134_BOARD_MD7134:
2680 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup); 3214 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
2681 } 3215 }
2682 break; 3216 break;
3217 case SAA7134_BOARD_PHILIPS_EUROPA:
3218 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
3219 /* The Philips EUROPA based hybrid boards have the tuner connected through
3220 * the channel decoder. We have to make it transparent to find it
3221 */
3222 {
3223 struct tuner_setup tun_setup;
3224 u8 data[] = { 0x07, 0x02};
3225 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
3226 i2c_transfer(&dev->i2c_adap, &msg, 1);
3227
3228 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
3229 tun_setup.type = dev->tuner_type;
3230 tun_setup.addr = dev->tuner_addr;
3231
3232 saa7134_i2c_call_clients (dev, TUNER_SET_TYPE_ADDR,&tun_setup);
3233 }
3234 break;
3235 case SAA7134_BOARD_PHILIPS_TIGER:
3236 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
3237 /* this is a hybrid board, initialize to analog mode */
3238 {
3239 u8 data[] = { 0x3c, 0x33, 0x68};
3240 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
3241 i2c_transfer(&dev->i2c_adap, &msg, 1);
3242 }
3243 break;
2683 } 3244 }
2684 return 0; 3245 return 0;
2685} 3246}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index e5e36f3c6250..19b88744fb31 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -57,6 +57,10 @@ static unsigned int oss = 0;
57module_param(oss, int, 0444); 57module_param(oss, int, 0444);
58MODULE_PARM_DESC(oss,"register oss devices (default: no)"); 58MODULE_PARM_DESC(oss,"register oss devices (default: no)");
59 59
60static unsigned int alsa = 0;
61module_param(alsa, int, 0444);
62MODULE_PARM_DESC(alsa,"register alsa devices (default: no)");
63
60static unsigned int latency = UNSET; 64static unsigned int latency = UNSET;
61module_param(latency, int, 0444); 65module_param(latency, int, 0444);
62MODULE_PARM_DESC(latency,"pci latency timer"); 66MODULE_PARM_DESC(latency,"pci latency timer");
@@ -190,6 +194,7 @@ void saa7134_track_gpio(struct saa7134_dev *dev, char *msg)
190 194
191static int need_empress; 195static int need_empress;
192static int need_dvb; 196static int need_dvb;
197static int need_alsa;
193 198
194static int pending_call(struct notifier_block *self, unsigned long state, 199static int pending_call(struct notifier_block *self, unsigned long state,
195 void *module) 200 void *module)
@@ -197,10 +202,12 @@ static int pending_call(struct notifier_block *self, unsigned long state,
197 if (module != THIS_MODULE || state != MODULE_STATE_LIVE) 202 if (module != THIS_MODULE || state != MODULE_STATE_LIVE)
198 return NOTIFY_DONE; 203 return NOTIFY_DONE;
199 204
200 if (need_empress) 205 if (need_empress)
201 request_module("saa7134-empress"); 206 request_module("saa7134-empress");
202 if (need_dvb) 207 if (need_dvb)
203 request_module("saa7134-dvb"); 208 request_module("saa7134-dvb");
209 if (need_alsa)
210 request_module("saa7134-alsa");
204 return NOTIFY_DONE; 211 return NOTIFY_DONE;
205} 212}
206 213
@@ -275,8 +282,8 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
275 282
276int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt) 283int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
277{ 284{
278 __le32 *cpu; 285 __le32 *cpu;
279 dma_addr_t dma_addr; 286 dma_addr_t dma_addr;
280 287
281 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr); 288 cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
282 if (NULL == cpu) 289 if (NULL == cpu)
@@ -436,7 +443,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
436 ctrl |= SAA7134_MAIN_CTRL_TE0; 443 ctrl |= SAA7134_MAIN_CTRL_TE0;
437 irq |= SAA7134_IRQ1_INTE_RA0_1 | 444 irq |= SAA7134_IRQ1_INTE_RA0_1 |
438 SAA7134_IRQ1_INTE_RA0_0; 445 SAA7134_IRQ1_INTE_RA0_0;
439 cap = dev->video_q.curr->vb.field; 446 cap = dev->video_q.curr->vb.field;
440 } 447 }
441 448
442 /* video capture -- dma 1+2 (planar modes) */ 449 /* video capture -- dma 1+2 (planar modes) */
@@ -465,7 +472,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
465 } 472 }
466 473
467 /* audio capture -- dma 3 */ 474 /* audio capture -- dma 3 */
468 if (dev->oss.dma_running) { 475 if (dev->dmasound.dma_running) {
469 ctrl |= SAA7134_MAIN_CTRL_TE6; 476 ctrl |= SAA7134_MAIN_CTRL_TE6;
470 irq |= SAA7134_IRQ1_INTE_RA3_1 | 477 irq |= SAA7134_IRQ1_INTE_RA3_1 |
471 SAA7134_IRQ1_INTE_RA3_0; 478 SAA7134_IRQ1_INTE_RA3_0;
@@ -570,6 +577,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
570 dev->name); 577 dev->name);
571 goto out; 578 goto out;
572 } 579 }
580
581 /* If alsa support is active and we get a sound report, exit
582 and let the saa7134-alsa module deal with it */
583
584 if ((report & SAA7134_IRQ_REPORT_DONE_RA3) && alsa) {
585 if (irq_debug > 1)
586 printk(KERN_DEBUG "%s/irq: ignoring interrupt for ALSA\n",
587 dev->name);
588 goto out;
589 }
590
573 handled = 1; 591 handled = 1;
574 saa_writel(SAA7134_IRQ_REPORT,report); 592 saa_writel(SAA7134_IRQ_REPORT,report);
575 if (irq_debug) 593 if (irq_debug)
@@ -591,13 +609,17 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
591 card_has_mpeg(dev)) 609 card_has_mpeg(dev))
592 saa7134_irq_ts_done(dev,status); 610 saa7134_irq_ts_done(dev,status);
593 611
594 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) 612 if ((report & SAA7134_IRQ_REPORT_DONE_RA3)) {
595 saa7134_irq_oss_done(dev,status); 613 if (oss) {
614 saa7134_irq_oss_done(dev,status);
615 }
616 }
596 617
597 if ((report & (SAA7134_IRQ_REPORT_GPIO16 | 618 if ((report & (SAA7134_IRQ_REPORT_GPIO16 |
598 SAA7134_IRQ_REPORT_GPIO18)) && 619 SAA7134_IRQ_REPORT_GPIO18)) &&
599 dev->remote) 620 dev->remote)
600 saa7134_input_irq(dev); 621 saa7134_input_irq(dev);
622
601 } 623 }
602 624
603 if (10 == loop) { 625 if (10 == loop) {
@@ -636,7 +658,7 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
636 658
637 saa_writel(SAA7134_IRQ1, 0); 659 saa_writel(SAA7134_IRQ1, 0);
638 saa_writel(SAA7134_IRQ2, 0); 660 saa_writel(SAA7134_IRQ2, 0);
639 init_MUTEX(&dev->lock); 661 init_MUTEX(&dev->lock);
640 spin_lock_init(&dev->slock); 662 spin_lock_init(&dev->slock);
641 663
642 saa7134_track_gpio(dev,"pre-init"); 664 saa7134_track_gpio(dev,"pre-init");
@@ -646,14 +668,6 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
646 saa7134_ts_init1(dev); 668 saa7134_ts_init1(dev);
647 saa7134_input_init1(dev); 669 saa7134_input_init1(dev);
648 670
649 switch (dev->pci->device) {
650 case PCI_DEVICE_ID_PHILIPS_SAA7134:
651 case PCI_DEVICE_ID_PHILIPS_SAA7133:
652 case PCI_DEVICE_ID_PHILIPS_SAA7135:
653 saa7134_oss_init1(dev);
654 break;
655 }
656
657 /* RAM FIFO config */ 671 /* RAM FIFO config */
658 saa_writel(SAA7134_FIFO_SIZE, 0x08070503); 672 saa_writel(SAA7134_FIFO_SIZE, 0x08070503);
659 saa_writel(SAA7134_THRESHOULD,0x02020202); 673 saa_writel(SAA7134_THRESHOULD,0x02020202);
@@ -668,6 +682,21 @@ static int saa7134_hwinit1(struct saa7134_dev *dev)
668 SAA7134_MAIN_CTRL_ESFE | 682 SAA7134_MAIN_CTRL_ESFE |
669 SAA7134_MAIN_CTRL_EBDAC); 683 SAA7134_MAIN_CTRL_EBDAC);
670 684
685 /*
686 * Initialize OSS _after_ enabling audio clock PLL and audio processing.
687 * OSS initialization writes to registers via the audio DSP; these
688 * writes will fail unless the audio clock has been started. At worst,
689 * audio will not work.
690 */
691
692 switch (dev->pci->device) {
693 case PCI_DEVICE_ID_PHILIPS_SAA7134:
694 case PCI_DEVICE_ID_PHILIPS_SAA7133:
695 case PCI_DEVICE_ID_PHILIPS_SAA7135:
696 saa7134_oss_init1(dev);
697 break;
698 }
699
671 /* enable peripheral devices */ 700 /* enable peripheral devices */
672 saa_writeb(SAA7134_SPECIAL_MODE, 0x01); 701 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
673 702
@@ -687,7 +716,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
687 saa7134_tvaudio_init2(dev); 716 saa7134_tvaudio_init2(dev);
688 717
689 /* enable IRQ's */ 718 /* enable IRQ's */
690 irq2_mask = 719 irq2_mask =
691 SAA7134_IRQ2_INTE_DEC3 | 720 SAA7134_IRQ2_INTE_DEC3 |
692 SAA7134_IRQ2_INTE_DEC2 | 721 SAA7134_IRQ2_INTE_DEC2 |
693 SAA7134_IRQ2_INTE_DEC1 | 722 SAA7134_IRQ2_INTE_DEC1 |
@@ -695,10 +724,12 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
695 SAA7134_IRQ2_INTE_PE | 724 SAA7134_IRQ2_INTE_PE |
696 SAA7134_IRQ2_INTE_AR; 725 SAA7134_IRQ2_INTE_AR;
697 726
698 if (dev->has_remote) 727 if (dev->has_remote == SAA7134_REMOTE_GPIO)
699 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | 728 irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 |
700 SAA7134_IRQ2_INTE_GPIO18A | 729 SAA7134_IRQ2_INTE_GPIO18A |
701 SAA7134_IRQ2_INTE_GPIO16 ); 730 SAA7134_IRQ2_INTE_GPIO16 );
731 else if (dev->has_remote == SAA7134_REMOTE_I2C)
732 request_module("ir-kbd-i2c");
702 733
703 saa_writel(SAA7134_IRQ1, 0); 734 saa_writel(SAA7134_IRQ1, 0);
704 saa_writel(SAA7134_IRQ2, irq2_mask); 735 saa_writel(SAA7134_IRQ2, irq2_mask);
@@ -872,8 +903,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
872 903
873 /* print pci info */ 904 /* print pci info */
874 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 905 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
875 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 906 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
876 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " 907 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
877 "latency: %d, mmio: 0x%lx\n", dev->name, 908 "latency: %d, mmio: 0x%lx\n", dev->name,
878 pci_name(pci_dev), dev->pci_rev, pci_dev->irq, 909 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
879 dev->pci_lat,pci_resource_start(pci_dev,0)); 910 dev->pci_lat,pci_resource_start(pci_dev,0));
@@ -897,7 +928,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
897 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; 928 dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
898 if (UNSET != tuner[dev->nr]) 929 if (UNSET != tuner[dev->nr])
899 dev->tuner_type = tuner[dev->nr]; 930 dev->tuner_type = tuner[dev->nr];
900 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", 931 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
901 dev->name,pci_dev->subsystem_vendor, 932 dev->name,pci_dev->subsystem_vendor,
902 pci_dev->subsystem_device,saa7134_boards[dev->board].name, 933 pci_dev->subsystem_device,saa7134_boards[dev->board].name,
903 dev->board, card[dev->nr] == dev->board ? 934 dev->board, card[dev->nr] == dev->board ?
@@ -947,14 +978,20 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
947 request_module("tuner"); 978 request_module("tuner");
948 if (dev->tda9887_conf) 979 if (dev->tda9887_conf)
949 request_module("tda9887"); 980 request_module("tda9887");
950 if (card_is_empress(dev)) { 981 if (card_is_empress(dev)) {
951 request_module("saa6752hs"); 982 request_module("saa6752hs");
952 request_module_depend("saa7134-empress",&need_empress); 983 request_module_depend("saa7134-empress",&need_empress);
953 } 984 }
954 985
955 if (card_is_dvb(dev)) 986 if (card_is_dvb(dev))
956 request_module_depend("saa7134-dvb",&need_dvb); 987 request_module_depend("saa7134-dvb",&need_dvb);
957 988
989 if (!oss && alsa) {
990 dprintk("Requesting ALSA module\n");
991 request_module_depend("saa7134-alsa",&need_alsa);
992 }
993
994
958 v4l2_prio_init(&dev->prio); 995 v4l2_prio_init(&dev->prio);
959 996
960 /* register v4l devices */ 997 /* register v4l devices */
@@ -993,22 +1030,22 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
993 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1030 case PCI_DEVICE_ID_PHILIPS_SAA7133:
994 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1031 case PCI_DEVICE_ID_PHILIPS_SAA7135:
995 if (oss) { 1032 if (oss) {
996 err = dev->oss.minor_dsp = 1033 err = dev->dmasound.minor_dsp =
997 register_sound_dsp(&saa7134_dsp_fops, 1034 register_sound_dsp(&saa7134_dsp_fops,
998 dsp_nr[dev->nr]); 1035 dsp_nr[dev->nr]);
999 if (err < 0) { 1036 if (err < 0) {
1000 goto fail4; 1037 goto fail4;
1001 } 1038 }
1002 printk(KERN_INFO "%s: registered device dsp%d\n", 1039 printk(KERN_INFO "%s: registered device dsp%d\n",
1003 dev->name,dev->oss.minor_dsp >> 4); 1040 dev->name,dev->dmasound.minor_dsp >> 4);
1004 1041
1005 err = dev->oss.minor_mixer = 1042 err = dev->dmasound.minor_mixer =
1006 register_sound_mixer(&saa7134_mixer_fops, 1043 register_sound_mixer(&saa7134_mixer_fops,
1007 mixer_nr[dev->nr]); 1044 mixer_nr[dev->nr]);
1008 if (err < 0) 1045 if (err < 0)
1009 goto fail5; 1046 goto fail5;
1010 printk(KERN_INFO "%s: registered device mixer%d\n", 1047 printk(KERN_INFO "%s: registered device mixer%d\n",
1011 dev->name,dev->oss.minor_mixer >> 4); 1048 dev->name,dev->dmasound.minor_mixer >> 4);
1012 } 1049 }
1013 break; 1050 break;
1014 } 1051 }
@@ -1035,7 +1072,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1035 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1072 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1036 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1073 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1037 if (oss) 1074 if (oss)
1038 unregister_sound_dsp(dev->oss.minor_dsp); 1075 unregister_sound_dsp(dev->dmasound.minor_dsp);
1039 break; 1076 break;
1040 } 1077 }
1041 fail4: 1078 fail4:
@@ -1055,7 +1092,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1055 1092
1056static void __devexit saa7134_finidev(struct pci_dev *pci_dev) 1093static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1057{ 1094{
1058 struct saa7134_dev *dev = pci_get_drvdata(pci_dev); 1095 struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
1059 struct list_head *item; 1096 struct list_head *item;
1060 struct saa7134_mpeg_ops *mops; 1097 struct saa7134_mpeg_ops *mops;
1061 1098
@@ -1093,8 +1130,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
1093 case PCI_DEVICE_ID_PHILIPS_SAA7133: 1130 case PCI_DEVICE_ID_PHILIPS_SAA7133:
1094 case PCI_DEVICE_ID_PHILIPS_SAA7135: 1131 case PCI_DEVICE_ID_PHILIPS_SAA7135:
1095 if (oss) { 1132 if (oss) {
1096 unregister_sound_mixer(dev->oss.minor_mixer); 1133 unregister_sound_mixer(dev->dmasound.minor_mixer);
1097 unregister_sound_dsp(dev->oss.minor_dsp); 1134 unregister_sound_dsp(dev->dmasound.minor_dsp);
1098 } 1135 }
1099 break; 1136 break;
1100 } 1137 }
@@ -1149,10 +1186,10 @@ EXPORT_SYMBOL(saa7134_ts_unregister);
1149/* ----------------------------------------------------------- */ 1186/* ----------------------------------------------------------- */
1150 1187
1151static struct pci_driver saa7134_pci_driver = { 1188static struct pci_driver saa7134_pci_driver = {
1152 .name = "saa7134", 1189 .name = "saa7134",
1153 .id_table = saa7134_pci_tbl, 1190 .id_table = saa7134_pci_tbl,
1154 .probe = saa7134_initdev, 1191 .probe = saa7134_initdev,
1155 .remove = __devexit_p(saa7134_finidev), 1192 .remove = __devexit_p(saa7134_finidev),
1156}; 1193};
1157 1194
1158static int saa7134_init(void) 1195static int saa7134_init(void)
@@ -1188,6 +1225,13 @@ EXPORT_SYMBOL(saa7134_i2c_call_clients);
1188EXPORT_SYMBOL(saa7134_devlist); 1225EXPORT_SYMBOL(saa7134_devlist);
1189EXPORT_SYMBOL(saa7134_boards); 1226EXPORT_SYMBOL(saa7134_boards);
1190 1227
1228/* ----------------- For ALSA -------------------------------- */
1229
1230EXPORT_SYMBOL(saa7134_pgtable_free);
1231EXPORT_SYMBOL(saa7134_pgtable_build);
1232EXPORT_SYMBOL(saa7134_pgtable_alloc);
1233EXPORT_SYMBOL(saa7134_set_dmabits);
1234
1191/* ----------------------------------------------------------- */ 1235/* ----------------------------------------------------------- */
1192/* 1236/*
1193 * Local variables: 1237 * Local variables:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 639ae51a052d..e016480c3468 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -29,7 +29,6 @@
29#include <linux/kthread.h> 29#include <linux/kthread.h>
30#include <linux/suspend.h> 30#include <linux/suspend.h>
31 31
32
33#include "saa7134-reg.h" 32#include "saa7134-reg.h"
34#include "saa7134.h" 33#include "saa7134.h"
35 34
@@ -40,6 +39,10 @@
40#ifdef HAVE_TDA1004X 39#ifdef HAVE_TDA1004X
41# include "tda1004x.h" 40# include "tda1004x.h"
42#endif 41#endif
42#ifdef HAVE_NXT200X
43# include "nxt200x.h"
44# include "dvb-pll.h"
45#endif
43 46
44MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 47MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
45MODULE_LICENSE("GPL"); 48MODULE_LICENSE("GPL");
@@ -151,25 +154,12 @@ static struct mt352_config pinnacle_300i = {
151/* ------------------------------------------------------------------ */ 154/* ------------------------------------------------------------------ */
152 155
153#ifdef HAVE_TDA1004X 156#ifdef HAVE_TDA1004X
154static int philips_tu1216_pll_init(struct dvb_frontend *fe)
155{
156 struct saa7134_dev *dev = fe->dvb->priv;
157 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
158 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
159
160 /* setup PLL configuration */
161 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
162 return -EIO;
163 msleep(1);
164 157
165 return 0; 158static int philips_tda6651_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
166}
167
168static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
169{ 159{
170 struct saa7134_dev *dev = fe->dvb->priv; 160 struct saa7134_dev *dev = fe->dvb->priv;
171 u8 tuner_buf[4]; 161 u8 tuner_buf[4];
172 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = 162 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tuner_buf,.len =
173 sizeof(tuner_buf) }; 163 sizeof(tuner_buf) };
174 int tuner_frequency = 0; 164 int tuner_frequency = 0;
175 u8 band, cp, filter; 165 u8 band, cp, filter;
@@ -242,11 +232,36 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
242 232
243 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1) 233 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
244 return -EIO; 234 return -EIO;
235 msleep(1);
236 return 0;
237}
245 238
239static int philips_tda6651_pll_init(u8 addr, struct dvb_frontend *fe)
240{
241 struct saa7134_dev *dev = fe->dvb->priv;
242 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
243 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
244
245 /* setup PLL configuration */
246 if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
247 return -EIO;
246 msleep(1); 248 msleep(1);
249
247 return 0; 250 return 0;
248} 251}
249 252
253/* ------------------------------------------------------------------ */
254
255static int philips_tu1216_pll_60_init(struct dvb_frontend *fe)
256{
257 return philips_tda6651_pll_init(0x60, fe);
258}
259
260static int philips_tu1216_pll_60_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
261{
262 return philips_tda6651_pll_set(0x60, fe, params);
263}
264
250static int philips_tu1216_request_firmware(struct dvb_frontend *fe, 265static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
251 const struct firmware **fw, char *name) 266 const struct firmware **fw, char *name)
252{ 267{
@@ -254,22 +269,108 @@ static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
254 return request_firmware(fw, name, &dev->pci->dev); 269 return request_firmware(fw, name, &dev->pci->dev);
255} 270}
256 271
257static struct tda1004x_config philips_tu1216_config = { 272static struct tda1004x_config philips_tu1216_60_config = {
273
274 .demod_address = 0x8,
275 .invert = 1,
276 .invert_oclk = 0,
277 .xtal_freq = TDA10046_XTAL_4M,
278 .agc_config = TDA10046_AGC_DEFAULT,
279 .if_freq = TDA10046_FREQ_3617,
280 .pll_init = philips_tu1216_pll_60_init,
281 .pll_set = philips_tu1216_pll_60_set,
282 .pll_sleep = NULL,
283 .request_firmware = philips_tu1216_request_firmware,
284};
285
286/* ------------------------------------------------------------------ */
287
288static int philips_tu1216_pll_61_init(struct dvb_frontend *fe)
289{
290 return philips_tda6651_pll_init(0x61, fe);
291}
292
293static int philips_tu1216_pll_61_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
294{
295 return philips_tda6651_pll_set(0x61, fe, params);
296}
297
298static struct tda1004x_config philips_tu1216_61_config = {
258 299
259 .demod_address = 0x8, 300 .demod_address = 0x8,
260 .invert = 1, 301 .invert = 1,
261 .invert_oclk = 1, 302 .invert_oclk = 0,
262 .xtal_freq = TDA10046_XTAL_4M, 303 .xtal_freq = TDA10046_XTAL_4M,
263 .agc_config = TDA10046_AGC_DEFAULT, 304 .agc_config = TDA10046_AGC_DEFAULT,
264 .if_freq = TDA10046_FREQ_3617, 305 .if_freq = TDA10046_FREQ_3617,
265 .pll_init = philips_tu1216_pll_init, 306 .pll_init = philips_tu1216_pll_61_init,
266 .pll_set = philips_tu1216_pll_set, 307 .pll_set = philips_tu1216_pll_61_set,
267 .pll_sleep = NULL, 308 .pll_sleep = NULL,
268 .request_firmware = philips_tu1216_request_firmware, 309 .request_firmware = philips_tu1216_request_firmware,
269}; 310};
270 311
271/* ------------------------------------------------------------------ */ 312/* ------------------------------------------------------------------ */
272 313
314static int philips_europa_pll_init(struct dvb_frontend *fe)
315{
316 struct saa7134_dev *dev = fe->dvb->priv;
317 static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab };
318 struct i2c_msg init_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
319
320 /* setup PLL configuration */
321 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
322 return -EIO;
323 msleep(1);
324
325 /* switch the board to dvb mode */
326 init_msg.addr = 0x43;
327 init_msg.len = 0x02;
328 msg[0] = 0x00;
329 msg[1] = 0x40;
330 if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1)
331 return -EIO;
332
333 return 0;
334}
335
336static int philips_td1316_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
337{
338 return philips_tda6651_pll_set(0x61, fe, params);
339}
340
341static void philips_europa_analog(struct dvb_frontend *fe)
342{
343 struct saa7134_dev *dev = fe->dvb->priv;
344 /* this message actually turns the tuner back to analog mode */
345 static u8 msg[] = { 0x0b, 0xdc, 0x86, 0xa4 };
346 struct i2c_msg analog_msg = {.addr = 0x61,.flags = 0,.buf = msg,.len = sizeof(msg) };
347
348 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
349 msleep(1);
350
351 /* switch the board to analog mode */
352 analog_msg.addr = 0x43;
353 analog_msg.len = 0x02;
354 msg[0] = 0x00;
355 msg[1] = 0x14;
356 i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
357}
358
359static struct tda1004x_config philips_europa_config = {
360
361 .demod_address = 0x8,
362 .invert = 0,
363 .invert_oclk = 0,
364 .xtal_freq = TDA10046_XTAL_4M,
365 .agc_config = TDA10046_AGC_IFO_AUTO_POS,
366 .if_freq = TDA10046_FREQ_052,
367 .pll_init = philips_europa_pll_init,
368 .pll_set = philips_td1316_pll_set,
369 .pll_sleep = philips_europa_analog,
370 .request_firmware = NULL,
371};
372
373/* ------------------------------------------------------------------ */
273 374
274static int philips_fmd1216_pll_init(struct dvb_frontend *fe) 375static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
275{ 376{
@@ -382,7 +483,6 @@ static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
382 return 0; 483 return 0;
383} 484}
384 485
385#ifdef HAVE_TDA1004X
386static struct tda1004x_config medion_cardbus = { 486static struct tda1004x_config medion_cardbus = {
387 .demod_address = 0x08, 487 .demod_address = 0x08,
388 .invert = 1, 488 .invert = 1,
@@ -395,7 +495,6 @@ static struct tda1004x_config medion_cardbus = {
395 .pll_sleep = philips_fmd1216_analog, 495 .pll_sleep = philips_fmd1216_analog,
396 .request_firmware = NULL, 496 .request_firmware = NULL,
397}; 497};
398#endif
399 498
400/* ------------------------------------------------------------------ */ 499/* ------------------------------------------------------------------ */
401 500
@@ -452,7 +551,7 @@ static int philips_tda827x_pll_set(struct dvb_frontend *fe, struct dvb_frontend_
452 u8 tuner_buf[14]; 551 u8 tuner_buf[14];
453 552
454 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf, 553 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,
455 .len = sizeof(tuner_buf) }; 554 .len = sizeof(tuner_buf) };
456 int i, tuner_freq, if_freq; 555 int i, tuner_freq, if_freq;
457 u32 N; 556 u32 N;
458 switch (params->u.ofdm.bandwidth) { 557 switch (params->u.ofdm.bandwidth) {
@@ -511,7 +610,7 @@ static void philips_tda827x_pll_sleep(struct dvb_frontend *fe)
511 struct saa7134_dev *dev = fe->dvb->priv; 610 struct saa7134_dev *dev = fe->dvb->priv;
512 static u8 tda827x_sleep[] = { 0x30, 0xd0}; 611 static u8 tda827x_sleep[] = { 0x30, 0xd0};
513 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep, 612 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tda827x_sleep,
514 .len = sizeof(tda827x_sleep) }; 613 .len = sizeof(tda827x_sleep) };
515 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); 614 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
516} 615}
517 616
@@ -527,6 +626,202 @@ static struct tda1004x_config tda827x_lifeview_config = {
527 .pll_sleep = philips_tda827x_pll_sleep, 626 .pll_sleep = philips_tda827x_pll_sleep,
528 .request_firmware = NULL, 627 .request_firmware = NULL,
529}; 628};
629
630/* ------------------------------------------------------------------ */
631
632struct tda827xa_data {
633 u32 lomax;
634 u8 svco;
635 u8 spd;
636 u8 scr;
637 u8 sbs;
638 u8 gc3;
639};
640
641static struct tda827xa_data tda827xa_dvbt[] = {
642 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
643 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
644 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
645 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
646 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
647 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
648 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
649 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
650 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
651 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
652 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
653 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
654 { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
655 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
656 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
657 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
658 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
659 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
660 { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
661 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
662 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
663 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
664 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
665 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
666 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
667 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
668 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}};
669
670
671static int philips_tda827xa_pll_set(u8 addr, struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
672{
673 struct saa7134_dev *dev = fe->dvb->priv;
674 u8 tuner_buf[14];
675 unsigned char reg2[2];
676
677 struct i2c_msg msg = {.addr = addr,.flags = 0,.buf = tuner_buf};
678 int i, tuner_freq, if_freq;
679 u32 N;
680
681 switch (params->u.ofdm.bandwidth) {
682 case BANDWIDTH_6_MHZ:
683 if_freq = 4000000;
684 break;
685 case BANDWIDTH_7_MHZ:
686 if_freq = 4500000;
687 break;
688 default: /* 8 MHz or Auto */
689 if_freq = 5000000;
690 break;
691 }
692 tuner_freq = params->frequency + if_freq;
693
694 i = 0;
695 while (tda827xa_dvbt[i].lomax < tuner_freq) {
696 if(tda827xa_dvbt[i + 1].lomax == 0)
697 break;
698 i++;
699 }
700
701 N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
702 tuner_buf[0] = 0; // subaddress
703 tuner_buf[1] = N >> 8;
704 tuner_buf[2] = N & 0xff;
705 tuner_buf[3] = 0;
706 tuner_buf[4] = 0x16;
707 tuner_buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
708 tda827xa_dvbt[i].sbs;
709 tuner_buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
710 tuner_buf[7] = 0x0c;
711 tuner_buf[8] = 0x06;
712 tuner_buf[9] = 0x24;
713 tuner_buf[10] = 0xff;
714 tuner_buf[11] = 0x60;
715 tuner_buf[12] = 0x00;
716 tuner_buf[13] = 0x39; // lpsel
717 msg.len = 14;
718 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
719 return -EIO;
720
721 msg.buf= reg2;
722 msg.len = 2;
723 reg2[0] = 0x60;
724 reg2[1] = 0x3c;
725 i2c_transfer(&dev->i2c_adap, &msg, 1);
726
727 reg2[0] = 0xa0;
728 reg2[1] = 0x40;
729 i2c_transfer(&dev->i2c_adap, &msg, 1);
730
731 msleep(2);
732 /* correct CP value */
733 reg2[0] = 0x30;
734 reg2[1] = 0x10 + tda827xa_dvbt[i].scr;
735 msg.len = 2;
736 i2c_transfer(&dev->i2c_adap, &msg, 1);
737
738 msleep(550);
739 reg2[0] = 0x50;
740 reg2[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
741 i2c_transfer(&dev->i2c_adap, &msg, 1);
742
743 return 0;
744
745}
746
747static void philips_tda827xa_pll_sleep(u8 addr, struct dvb_frontend *fe)
748{
749 struct saa7134_dev *dev = fe->dvb->priv;
750 static u8 tda827xa_sleep[] = { 0x30, 0x90};
751 struct i2c_msg tuner_msg = {.addr = addr,.flags = 0,.buf = tda827xa_sleep,
752 .len = sizeof(tda827xa_sleep) };
753 i2c_transfer(&dev->i2c_adap, &tuner_msg, 1);
754
755}
756
757/* ------------------------------------------------------------------ */
758
759static int philips_tiger_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
760{
761 int ret;
762 struct saa7134_dev *dev = fe->dvb->priv;
763 static u8 tda8290_close[] = { 0x21, 0xc0};
764 static u8 tda8290_open[] = { 0x21, 0x80};
765 struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2};
766 /* close tda8290 i2c bridge */
767 tda8290_msg.buf = tda8290_close;
768 ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
769 if (ret != 1)
770 return -EIO;
771 msleep(20);
772 ret = philips_tda827xa_pll_set(0x61, fe, params);
773 if (ret != 0)
774 return ret;
775 /* open tda8290 i2c bridge */
776 tda8290_msg.buf = tda8290_open;
777 i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1);
778 return ret;
779};
780
781static int philips_tiger_dvb_mode(struct dvb_frontend *fe)
782{
783 struct saa7134_dev *dev = fe->dvb->priv;
784 static u8 data[] = { 0x3c, 0x33, 0x6a};
785 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
786
787 if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
788 return -EIO;
789 return 0;
790}
791
792static void philips_tiger_analog_mode(struct dvb_frontend *fe)
793{
794 struct saa7134_dev *dev = fe->dvb->priv;
795 static u8 data[] = { 0x3c, 0x33, 0x68};
796 struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
797
798 i2c_transfer(&dev->i2c_adap, &msg, 1);
799 philips_tda827xa_pll_sleep( 0x61, fe);
800}
801
802static struct tda1004x_config philips_tiger_config = {
803 .demod_address = 0x08,
804 .invert = 1,
805 .invert_oclk = 0,
806 .xtal_freq = TDA10046_XTAL_16M,
807 .agc_config = TDA10046_AGC_TDA827X,
808 .if_freq = TDA10046_FREQ_045,
809 .pll_init = philips_tiger_dvb_mode,
810 .pll_set = philips_tiger_pll_set,
811 .pll_sleep = philips_tiger_analog_mode,
812 .request_firmware = NULL,
813};
814
815#endif
816
817/* ------------------------------------------------------------------ */
818
819#ifdef HAVE_NXT200X
820static struct nxt200x_config avertvhda180 = {
821 .demod_address = 0x0a,
822 .pll_address = 0x61,
823 .pll_desc = &dvb_pll_tdhu2,
824};
530#endif 825#endif
531 826
532/* ------------------------------------------------------------------ */ 827/* ------------------------------------------------------------------ */
@@ -558,7 +853,7 @@ static int dvb_init(struct saa7134_dev *dev)
558 &dev->i2c_adap); 853 &dev->i2c_adap);
559 break; 854 break;
560 case SAA7134_BOARD_PHILIPS_TOUGH: 855 case SAA7134_BOARD_PHILIPS_TOUGH:
561 dev->dvb.frontend = tda10046_attach(&philips_tu1216_config, 856 dev->dvb.frontend = tda10046_attach(&philips_tu1216_60_config,
562 &dev->i2c_adap); 857 &dev->i2c_adap);
563 break; 858 break;
564 case SAA7134_BOARD_FLYDVBTDUO: 859 case SAA7134_BOARD_FLYDVBTDUO:
@@ -569,6 +864,31 @@ static int dvb_init(struct saa7134_dev *dev)
569 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, 864 dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config,
570 &dev->i2c_adap); 865 &dev->i2c_adap);
571 break; 866 break;
867 case SAA7134_BOARD_PHILIPS_EUROPA:
868 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
869 &dev->i2c_adap);
870 break;
871 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
872 dev->dvb.frontend = tda10046_attach(&philips_europa_config,
873 &dev->i2c_adap);
874 break;
875 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
876 dev->dvb.frontend = tda10046_attach(&philips_tu1216_61_config,
877 &dev->i2c_adap);
878 break;
879 case SAA7134_BOARD_PHILIPS_TIGER:
880 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
881 &dev->i2c_adap);
882 break;
883 case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
884 dev->dvb.frontend = tda10046_attach(&philips_tiger_config,
885 &dev->i2c_adap);
886 break;
887#endif
888#ifdef HAVE_NXT200X
889 case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
890 dev->dvb.frontend = nxt200x_attach(&avertvhda180, &dev->i2c_adap);
891 break;
572#endif 892#endif
573 default: 893 default:
574 printk("%s: Huh? unknown DVB card?\n",dev->name); 894 printk("%s: Huh? unknown DVB card?\n",dev->name);
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 77b627eb6483..e9ec69efb4c9 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -55,7 +55,7 @@ static void ts_reset_encoder(struct saa7134_dev* dev)
55 55
56 saa_writeb(SAA7134_SPECIAL_MODE, 0x00); 56 saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
57 msleep(10); 57 msleep(10);
58 saa_writeb(SAA7134_SPECIAL_MODE, 0x01); 58 saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
59 msleep(100); 59 msleep(100);
60 dev->empress_started = 0; 60 dev->empress_started = 0;
61} 61}
@@ -65,7 +65,7 @@ static int ts_init_encoder(struct saa7134_dev* dev)
65 ts_reset_encoder(dev); 65 ts_reset_encoder(dev);
66 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL); 66 saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
67 dev->empress_started = 1; 67 dev->empress_started = 1;
68 return 0; 68 return 0;
69} 69}
70 70
71/* ------------------------------------------------------------------ */ 71/* ------------------------------------------------------------------ */
@@ -169,7 +169,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
169 struct v4l2_capability *cap = arg; 169 struct v4l2_capability *cap = arg;
170 170
171 memset(cap,0,sizeof(*cap)); 171 memset(cap,0,sizeof(*cap));
172 strcpy(cap->driver, "saa7134"); 172 strcpy(cap->driver, "saa7134");
173 strlcpy(cap->card, saa7134_boards[dev->board].name, 173 strlcpy(cap->card, saa7134_boards[dev->board].name,
174 sizeof(cap->card)); 174 sizeof(cap->card));
175 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 175 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 711aa8e85fac..7575043f0874 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -239,7 +239,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
239 unsigned char data; 239 unsigned char data;
240 int addr,rc,i,byte; 240 int addr,rc,i,byte;
241 241
242 status = i2c_get_status(dev); 242 status = i2c_get_status(dev);
243 if (!i2c_is_idle(status)) 243 if (!i2c_is_idle(status))
244 if (!i2c_reset(dev)) 244 if (!i2c_reset(dev))
245 return -EIO; 245 return -EIO;
@@ -296,7 +296,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
296 rc = -EIO; 296 rc = -EIO;
297 if (!i2c_is_busy_wait(dev)) 297 if (!i2c_is_busy_wait(dev))
298 goto err; 298 goto err;
299 status = i2c_get_status(dev); 299 status = i2c_get_status(dev);
300 if (i2c_is_error(status)) 300 if (i2c_is_error(status))
301 goto err; 301 goto err;
302 /* ensure that the bus is idle for at least one bit slot */ 302 /* ensure that the bus is idle for at least one bit slot */
@@ -335,6 +335,20 @@ static int attach_inform(struct i2c_client *client)
335 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", 335 d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
336 client->driver->name, client->addr, client->name); 336 client->driver->name, client->addr, client->name);
337 337
338 /* Am I an i2c remote control? */
339
340 switch (client->addr) {
341 case 0x7a:
342 case 0x47:
343 {
344 struct IR_i2c *ir = i2c_get_clientdata(client);
345 d1printk("%s i2c IR detected (%s).\n",
346 client->driver->name,ir->phys);
347 saa7134_set_i2c_ir(dev,ir);
348 break;
349 }
350 }
351
338 if (!client->driver->command) 352 if (!client->driver->command)
339 return 0; 353 return 0;
340 354
@@ -348,12 +362,12 @@ static int attach_inform(struct i2c_client *client)
348 362
349 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup); 363 client->driver->command(client, TUNER_SET_TYPE_ADDR, &tun_setup);
350 } 364 }
351 } 365 }
352 366
353 if (tuner != UNSET) { 367 if (tuner != UNSET) {
354 368
355 tun_setup.type = tuner; 369 tun_setup.type = tuner;
356 tun_setup.addr = saa7134_boards[dev->board].tuner_addr; 370 tun_setup.addr = saa7134_boards[dev->board].tuner_addr;
357 371
358 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) { 372 if ((tun_setup.addr == ADDR_UNSET)||(tun_setup.addr == client->addr)) {
359 373
@@ -361,11 +375,11 @@ static int attach_inform(struct i2c_client *client)
361 375
362 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup); 376 client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_setup);
363 } 377 }
364 } 378 }
365 379
366 client->driver->command(client, TDA9887_SET_CONFIG, &conf); 380 client->driver->command(client, TDA9887_SET_CONFIG, &conf);
367 381
368 return 0; 382 return 0;
369} 383}
370 384
371static struct i2c_algorithm saa7134_algo = { 385static struct i2c_algorithm saa7134_algo = {
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 242cb235cf92..329accda6d45 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -39,6 +39,8 @@ MODULE_PARM_DESC(ir_debug,"enable debug messages [IR]");
39 39
40#define dprintk(fmt, arg...) if (ir_debug) \ 40#define dprintk(fmt, arg...) if (ir_debug) \
41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg) 41 printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
42#define i2cdprintk(fmt, arg...) if (ir_debug) \
43 printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
42 44
43/* ---------------------------------------------------------------------- */ 45/* ---------------------------------------------------------------------- */
44 46
@@ -114,24 +116,24 @@ static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = {
114/* Alfons Geser <a.geser@cox.net> 116/* Alfons Geser <a.geser@cox.net>
115 * updates from Job D. R. Borges <jobdrb@ig.com.br> */ 117 * updates from Job D. R. Borges <jobdrb@ig.com.br> */
116static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = { 118static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
117 [ 18 ] = KEY_POWER, 119 [ 18 ] = KEY_POWER,
118 [ 1 ] = KEY_TV, // DVR 120 [ 1 ] = KEY_TV, // DVR
119 [ 21 ] = KEY_DVD, // DVD 121 [ 21 ] = KEY_DVD, // DVD
120 [ 23 ] = KEY_AUDIO, // music 122 [ 23 ] = KEY_AUDIO, // music
121 // DVR mode / DVD mode / music mode 123 // DVR mode / DVD mode / music mode
122 124
123 [ 27 ] = KEY_MUTE, // mute 125 [ 27 ] = KEY_MUTE, // mute
124 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek 126 [ 2 ] = KEY_LANGUAGE, // MTS/SAP / audio / autoseek
125 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek 127 [ 30 ] = KEY_SUBTITLE, // closed captioning / subtitle / seek
126 [ 22 ] = KEY_ZOOM, // full screen 128 [ 22 ] = KEY_ZOOM, // full screen
127 [ 28 ] = KEY_VIDEO, // video source / eject / delall 129 [ 28 ] = KEY_VIDEO, // video source / eject / delall
128 [ 29 ] = KEY_RESTART, // playback / angle / del 130 [ 29 ] = KEY_RESTART, // playback / angle / del
129 [ 47 ] = KEY_SEARCH, // scan / menu / playlist 131 [ 47 ] = KEY_SEARCH, // scan / menu / playlist
130 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo 132 [ 48 ] = KEY_CHANNEL, // CH surfing / bookmark / memo
131 133
132 [ 49 ] = KEY_HELP, // help 134 [ 49 ] = KEY_HELP, // help
133 [ 50 ] = KEY_MODE, // num/memo 135 [ 50 ] = KEY_MODE, // num/memo
134 [ 51 ] = KEY_ESC, // cancel 136 [ 51 ] = KEY_ESC, // cancel
135 137
136 [ 12 ] = KEY_UP, // up 138 [ 12 ] = KEY_UP, // up
137 [ 16 ] = KEY_DOWN, // down 139 [ 16 ] = KEY_DOWN, // down
@@ -148,24 +150,24 @@ static IR_KEYTAB_TYPE eztv_codes[IR_KEYTAB_SIZE] = {
148 [ 45 ] = KEY_PLAY, // play 150 [ 45 ] = KEY_PLAY, // play
149 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle 151 [ 46 ] = KEY_SHUFFLE, // snapshot / shuffle
150 152
151 [ 0 ] = KEY_KP0, 153 [ 0 ] = KEY_KP0,
152 [ 5 ] = KEY_KP1, 154 [ 5 ] = KEY_KP1,
153 [ 6 ] = KEY_KP2, 155 [ 6 ] = KEY_KP2,
154 [ 7 ] = KEY_KP3, 156 [ 7 ] = KEY_KP3,
155 [ 9 ] = KEY_KP4, 157 [ 9 ] = KEY_KP4,
156 [ 10 ] = KEY_KP5, 158 [ 10 ] = KEY_KP5,
157 [ 11 ] = KEY_KP6, 159 [ 11 ] = KEY_KP6,
158 [ 13 ] = KEY_KP7, 160 [ 13 ] = KEY_KP7,
159 [ 14 ] = KEY_KP8, 161 [ 14 ] = KEY_KP8,
160 [ 15 ] = KEY_KP9, 162 [ 15 ] = KEY_KP9,
161 163
162 [ 42 ] = KEY_VOLUMEUP, 164 [ 42 ] = KEY_VOLUMEUP,
163 [ 17 ] = KEY_VOLUMEDOWN, 165 [ 17 ] = KEY_VOLUMEDOWN,
164 [ 24 ] = KEY_CHANNELUP, // CH.tracking up 166 [ 24 ] = KEY_CHANNELUP, // CH.tracking up
165 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down 167 [ 25 ] = KEY_CHANNELDOWN, // CH.tracking down
166 168
167 [ 19 ] = KEY_KPENTER, // enter 169 [ 19 ] = KEY_KPENTER, // enter
168 [ 33 ] = KEY_KPDOT, // . (decimal dot) 170 [ 33 ] = KEY_KPDOT, // . (decimal dot)
169}; 171};
170 172
171static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = { 173static IR_KEYTAB_TYPE avacssmart_codes[IR_KEYTAB_SIZE] = {
@@ -401,7 +403,183 @@ static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
401 403
402 // 0x1d unused ? 404 // 0x1d unused ?
403}; 405};
404/* ---------------------------------------------------------------------- */ 406
407
408/* Mike Baikov <mike@baikov.com> */
409static IR_KEYTAB_TYPE gotview7135_codes[IR_KEYTAB_SIZE] = {
410
411 [ 33 ] = KEY_POWER,
412 [ 105] = KEY_TV,
413 [ 51 ] = KEY_KP0,
414 [ 81 ] = KEY_KP1,
415 [ 49 ] = KEY_KP2,
416 [ 113] = KEY_KP3,
417 [ 59 ] = KEY_KP4,
418 [ 88 ] = KEY_KP5,
419 [ 65 ] = KEY_KP6,
420 [ 72 ] = KEY_KP7,
421 [ 48 ] = KEY_KP8,
422 [ 83 ] = KEY_KP9,
423 [ 115] = KEY_AGAIN, /* LOOP */
424 [ 10 ] = KEY_AUDIO,
425 [ 97 ] = KEY_PRINT, /* PREVIEW */
426 [ 122] = KEY_VIDEO,
427 [ 32 ] = KEY_CHANNELUP,
428 [ 64 ] = KEY_CHANNELDOWN,
429 [ 24 ] = KEY_VOLUMEDOWN,
430 [ 80 ] = KEY_VOLUMEUP,
431 [ 16 ] = KEY_MUTE,
432 [ 74 ] = KEY_SEARCH,
433 [ 123] = KEY_SHUFFLE, /* SNAPSHOT */
434 [ 34 ] = KEY_RECORD,
435 [ 98 ] = KEY_STOP,
436 [ 120] = KEY_PLAY,
437 [ 57 ] = KEY_REWIND,
438 [ 89 ] = KEY_PAUSE,
439 [ 25 ] = KEY_FORWARD,
440 [ 9 ] = KEY_ZOOM,
441
442 [ 82 ] = KEY_F21, /* LIVE TIMESHIFT */
443 [ 26 ] = KEY_F22, /* MIN TIMESHIFT */
444 [ 58 ] = KEY_F23, /* TIMESHIFT */
445 [ 112] = KEY_F24, /* NORMAL TIMESHIFT */
446};
447
448static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
449 [ 0x3 ] = KEY_POWER,
450 [ 0x6f ] = KEY_MUTE,
451 [ 0x10 ] = KEY_BACKSPACE, /* Recall */
452
453 [ 0x11 ] = KEY_KP0,
454 [ 0x4 ] = KEY_KP1,
455 [ 0x5 ] = KEY_KP2,
456 [ 0x6 ] = KEY_KP3,
457 [ 0x8 ] = KEY_KP4,
458 [ 0x9 ] = KEY_KP5,
459 [ 0xa ] = KEY_KP6,
460 [ 0xc ] = KEY_KP7,
461 [ 0xd ] = KEY_KP8,
462 [ 0xe ] = KEY_KP9,
463 [ 0x12 ] = KEY_KPDOT, /* 100+ */
464
465 [ 0x7 ] = KEY_VOLUMEUP,
466 [ 0xb ] = KEY_VOLUMEDOWN,
467 [ 0x1a ] = KEY_KPPLUS,
468 [ 0x18 ] = KEY_KPMINUS,
469 [ 0x15 ] = KEY_UP,
470 [ 0x1d ] = KEY_DOWN,
471 [ 0xf ] = KEY_CHANNELUP,
472 [ 0x13 ] = KEY_CHANNELDOWN,
473 [ 0x48 ] = KEY_ZOOM,
474
475 [ 0x1b ] = KEY_VIDEO, /* Video source */
476 [ 0x49 ] = KEY_LANGUAGE, /* MTS Select */
477 [ 0x19 ] = KEY_SEARCH, /* Auto Scan */
478
479 [ 0x4b ] = KEY_RECORD,
480 [ 0x46 ] = KEY_PLAY,
481 [ 0x45 ] = KEY_PAUSE, /* Pause */
482 [ 0x44 ] = KEY_STOP,
483 [ 0x40 ] = KEY_FORWARD, /* Forward ? */
484 [ 0x42 ] = KEY_REWIND, /* Backward ? */
485
486};
487
488static IR_KEYTAB_TYPE ir_codes_pinnacle[IR_KEYTAB_SIZE] = {
489 [ 0x59 ] = KEY_MUTE,
490 [ 0x4a ] = KEY_POWER,
491
492 [ 0x18 ] = KEY_TEXT,
493 [ 0x26 ] = KEY_TV,
494 [ 0x3d ] = KEY_PRINT,
495
496 [ 0x48 ] = KEY_RED,
497 [ 0x04 ] = KEY_GREEN,
498 [ 0x11 ] = KEY_YELLOW,
499 [ 0x00 ] = KEY_BLUE,
500
501 [ 0x2d ] = KEY_VOLUMEUP,
502 [ 0x1e ] = KEY_VOLUMEDOWN,
503
504 [ 0x49 ] = KEY_MENU,
505
506 [ 0x16 ] = KEY_CHANNELUP,
507 [ 0x17 ] = KEY_CHANNELDOWN,
508
509 [ 0x20 ] = KEY_UP,
510 [ 0x21 ] = KEY_DOWN,
511 [ 0x22 ] = KEY_LEFT,
512 [ 0x23 ] = KEY_RIGHT,
513 [ 0x0d ] = KEY_SELECT,
514
515
516
517 [ 0x08 ] = KEY_BACK,
518 [ 0x07 ] = KEY_REFRESH,
519
520 [ 0x2f ] = KEY_ZOOM,
521 [ 0x29 ] = KEY_RECORD,
522
523 [ 0x4b ] = KEY_PAUSE,
524 [ 0x4d ] = KEY_REWIND,
525 [ 0x2e ] = KEY_PLAY,
526 [ 0x4e ] = KEY_FORWARD,
527 [ 0x53 ] = KEY_PREVIOUS,
528 [ 0x4c ] = KEY_STOP,
529 [ 0x54 ] = KEY_NEXT,
530
531 [ 0x69 ] = KEY_KP0,
532 [ 0x6a ] = KEY_KP1,
533 [ 0x6b ] = KEY_KP2,
534 [ 0x6c ] = KEY_KP3,
535 [ 0x6d ] = KEY_KP4,
536 [ 0x6e ] = KEY_KP5,
537 [ 0x6f ] = KEY_KP6,
538 [ 0x70 ] = KEY_KP7,
539 [ 0x71 ] = KEY_KP8,
540 [ 0x72 ] = KEY_KP9,
541
542 [ 0x74 ] = KEY_CHANNEL,
543 [ 0x0a ] = KEY_BACKSPACE,
544};
545
546/* Mapping for the 28 key remote control as seen at
547 http://www.sednacomputer.com/photo/cardbus-tv.jpg
548 Pavel Mihaylov <bin@bash.info> */
549static IR_KEYTAB_TYPE pctv_sedna_codes[IR_KEYTAB_SIZE] = {
550 [ 0 ] = KEY_KP0,
551 [ 1 ] = KEY_KP1,
552 [ 2 ] = KEY_KP2,
553 [ 3 ] = KEY_KP3,
554 [ 4 ] = KEY_KP4,
555 [ 5 ] = KEY_KP5,
556 [ 6 ] = KEY_KP6,
557 [ 7 ] = KEY_KP7,
558 [ 8 ] = KEY_KP8,
559 [ 9 ] = KEY_KP9,
560
561 [ 0x0a ] = KEY_AGAIN, /* Recall */
562 [ 0x0b ] = KEY_CHANNELUP,
563 [ 0x0c ] = KEY_VOLUMEUP,
564 [ 0x0d ] = KEY_MODE, /* Stereo */
565 [ 0x0e ] = KEY_STOP,
566 [ 0x0f ] = KEY_PREVIOUSSONG,
567 [ 0x10 ] = KEY_ZOOM,
568 [ 0x11 ] = KEY_TUNER, /* Source */
569 [ 0x12 ] = KEY_POWER,
570 [ 0x13 ] = KEY_MUTE,
571 [ 0x15 ] = KEY_CHANNELDOWN,
572 [ 0x18 ] = KEY_VOLUMEDOWN,
573 [ 0x19 ] = KEY_SHUFFLE, /* Snapshot */
574 [ 0x1a ] = KEY_NEXTSONG,
575 [ 0x1b ] = KEY_TEXT, /* Time Shift */
576 [ 0x1c ] = KEY_RADIO, /* FM Radio */
577 [ 0x1d ] = KEY_RECORD,
578 [ 0x1e ] = KEY_PAUSE,
579};
580
581
582/* -------------------- GPIO generic keycode builder -------------------- */
405 583
406static int build_key(struct saa7134_dev *dev) 584static int build_key(struct saa7134_dev *dev)
407{ 585{
@@ -413,13 +591,13 @@ static int build_key(struct saa7134_dev *dev)
413 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN); 591 saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
414 592
415 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2); 593 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
416 if (ir->polling) { 594 if (ir->polling) {
417 if (ir->last_gpio == gpio) 595 if (ir->last_gpio == gpio)
418 return 0; 596 return 0;
419 ir->last_gpio = gpio; 597 ir->last_gpio = gpio;
420 } 598 }
421 599
422 data = ir_extract_bits(gpio, ir->mask_keycode); 600 data = ir_extract_bits(gpio, ir->mask_keycode);
423 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", 601 dprintk("build_key gpio=0x%x mask=0x%x data=%d\n",
424 gpio, ir->mask_keycode, data); 602 gpio, ir->mask_keycode, data);
425 603
@@ -432,13 +610,87 @@ static int build_key(struct saa7134_dev *dev)
432 return 0; 610 return 0;
433} 611}
434 612
435/* ---------------------------------------------------------------------- */ 613/* --------------------- Chip specific I2C key builders ----------------- */
614
615static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
616{
617 unsigned char b;
618
619 /* poll IR chip */
620 if (1 != i2c_master_recv(&ir->c,&b,1)) {
621 i2cdprintk("read error\n");
622 return -EIO;
623 }
624
625 /* no button press */
626 if (b==0)
627 return 0;
628
629 /* repeating */
630 if (b & 0x80)
631 return 1;
632
633 *ir_key = b;
634 *ir_raw = b;
635 return 1;
636}
637
638/* The new pinnacle PCTV remote (with the colored buttons)
639 *
640 * Ricardo Cerqueira <v4l@cerqueira.org>
641 */
642
643static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
644{
645 unsigned char b[4];
646 unsigned int start = 0,parity = 0,code = 0;
647
648 /* poll IR chip */
649 if (4 != i2c_master_recv(&ir->c,b,4)) {
650 i2cdprintk("read error\n");
651 return -EIO;
652 }
653
654 for (start = 0; start<4; start++) {
655 if (b[start] == 0x80) {
656 code=b[(start+3)%4];
657 parity=b[(start+2)%4];
658 }
659 }
660
661 /* Empty Request */
662 if (parity==0)
663 return 0;
664
665 /* Repeating... */
666 if (ir->old == parity)
667 return 0;
668
669
670 ir->old = parity;
671
672 /* Reduce code value to fit inside IR_KEYTAB_SIZE
673 *
674 * this is the only value that results in 42 unique
675 * codes < 128
676 */
677
678 code %= 0x88;
679
680 *ir_raw = code;
681 *ir_key = code;
682
683 i2cdprintk("Pinnacle PCTV key %02x\n", code);
684
685 return 1;
686}
687
436 688
437void saa7134_input_irq(struct saa7134_dev *dev) 689void saa7134_input_irq(struct saa7134_dev *dev)
438{ 690{
439 struct saa7134_ir *ir = dev->remote; 691 struct saa7134_ir *ir = dev->remote;
440 692
441 if (!ir->polling) 693 if (!ir->polling)
442 build_key(dev); 694 build_key(dev);
443} 695}
444 696
@@ -464,7 +716,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
464 int polling = 0; 716 int polling = 0;
465 int ir_type = IR_TYPE_OTHER; 717 int ir_type = IR_TYPE_OTHER;
466 718
467 if (!dev->has_remote) 719 if (dev->has_remote != SAA7134_REMOTE_GPIO)
468 return -ENODEV; 720 return -ENODEV;
469 if (disable_ir) 721 if (disable_ir)
470 return -ENODEV; 722 return -ENODEV;
@@ -473,7 +725,8 @@ int saa7134_input_init1(struct saa7134_dev *dev)
473 switch (dev->board) { 725 switch (dev->board) {
474 case SAA7134_BOARD_FLYVIDEO2000: 726 case SAA7134_BOARD_FLYVIDEO2000:
475 case SAA7134_BOARD_FLYVIDEO3000: 727 case SAA7134_BOARD_FLYVIDEO3000:
476 case SAA7134_BOARD_FLYTVPLATINUM_FM: 728 case SAA7134_BOARD_FLYTVPLATINUM_FM:
729 case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
477 ir_codes = flyvideo_codes; 730 ir_codes = flyvideo_codes;
478 mask_keycode = 0xEC00000; 731 mask_keycode = 0xEC00000;
479 mask_keydown = 0x0040000; 732 mask_keydown = 0x0040000;
@@ -514,14 +767,33 @@ int saa7134_input_init1(struct saa7134_dev *dev)
514 saa_setb(SAA7134_GPIO_GPMODE0, 0x4); 767 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
515 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); 768 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
516 break; 769 break;
770 case SAA7134_BOARD_KWORLD_TERMINATOR:
771 ir_codes = avacssmart_codes;
772 mask_keycode = 0x00001f;
773 mask_keyup = 0x000060;
774 polling = 50; // ms
775 break;
517 case SAA7134_BOARD_MANLI_MTV001: 776 case SAA7134_BOARD_MANLI_MTV001:
518 case SAA7134_BOARD_MANLI_MTV002: 777 case SAA7134_BOARD_MANLI_MTV002:
778 case SAA7134_BOARD_BEHOLD_409FM:
519 ir_codes = manli_codes; 779 ir_codes = manli_codes;
520 mask_keycode = 0x001f00; 780 mask_keycode = 0x001f00;
521 mask_keyup = 0x004000; 781 mask_keyup = 0x004000;
522 mask_keydown = 0x002000;
523 polling = 50; // ms 782 polling = 50; // ms
524 break; 783 break;
784 case SAA7134_BOARD_SEDNA_PC_TV_CARDBUS:
785 ir_codes = pctv_sedna_codes;
786 mask_keycode = 0x001f00;
787 mask_keyup = 0x004000;
788 polling = 50; // ms
789 break;
790 case SAA7134_BOARD_GOTVIEW_7135:
791 ir_codes = gotview7135_codes;
792 mask_keycode = 0x0003EC;
793 mask_keyup = 0x008000;
794 mask_keydown = 0x000010;
795 polling = 50; // ms
796 break;
525 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 797 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
526 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: 798 case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII:
527 ir_codes = videomate_tv_pvr_codes; 799 ir_codes = videomate_tv_pvr_codes;
@@ -529,6 +801,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
529 mask_keyup = 0x400000; 801 mask_keyup = 0x400000;
530 polling = 50; // ms 802 polling = 50; // ms
531 break; 803 break;
804 case SAA7134_BOARD_VIDEOMATE_DVBT_300:
805 case SAA7134_BOARD_VIDEOMATE_DVBT_200:
806 ir_codes = videomate_tv_pvr_codes;
807 mask_keycode = 0x003F00;
808 mask_keyup = 0x040000;
809 break;
532 } 810 }
533 if (NULL == ir_codes) { 811 if (NULL == ir_codes) {
534 printk("%s: Oops: IR config error [card=%d]\n", 812 printk("%s: Oops: IR config error [card=%d]\n",
@@ -548,7 +826,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
548 ir->mask_keycode = mask_keycode; 826 ir->mask_keycode = mask_keycode;
549 ir->mask_keydown = mask_keydown; 827 ir->mask_keydown = mask_keydown;
550 ir->mask_keyup = mask_keyup; 828 ir->mask_keyup = mask_keyup;
551 ir->polling = polling; 829 ir->polling = polling;
552 830
553 /* init input device */ 831 /* init input device */
554 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)", 832 snprintf(ir->name, sizeof(ir->name), "saa7134 IR (%s)",
@@ -596,6 +874,31 @@ void saa7134_input_fini(struct saa7134_dev *dev)
596 dev->remote = NULL; 874 dev->remote = NULL;
597} 875}
598 876
877void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
878{
879 if (disable_ir) {
880 dprintk("Found supported i2c remote, but IR has been disabled\n");
881 ir->get_key=NULL;
882 return;
883 }
884
885 switch (dev->board) {
886 case SAA7134_BOARD_PINNACLE_PCTV_110i:
887 snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
888 ir->get_key = get_key_pinnacle;
889 ir->ir_codes = ir_codes_pinnacle;
890 break;
891 case SAA7134_BOARD_UPMOST_PURPLE_TV:
892 snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
893 ir->get_key = get_key_purpletv;
894 ir->ir_codes = ir_codes_purpletv;
895 break;
896 default:
897 dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
898 break;
899 }
900
901}
599/* ---------------------------------------------------------------------- 902/* ----------------------------------------------------------------------
600 * Local variables: 903 * Local variables:
601 * c-basic-offset: 8 904 * c-basic-offset: 8
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index c20630c82f1c..fd53dfcc1644 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -44,6 +44,7 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
44#define dprintk(fmt, arg...) if (oss_debug) \ 44#define dprintk(fmt, arg...) if (oss_debug) \
45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg) 45 printk(KERN_DEBUG "%s/oss: " fmt, dev->name , ## arg)
46 46
47
47/* ------------------------------------------------------------------ */ 48/* ------------------------------------------------------------------ */
48 49
49static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks) 50static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
@@ -58,12 +59,12 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
58 if ((blksize * blocks) > 1024*1024) 59 if ((blksize * blocks) > 1024*1024)
59 blocks = 1024*1024 / blksize; 60 blocks = 1024*1024 / blksize;
60 61
61 dev->oss.blocks = blocks; 62 dev->dmasound.blocks = blocks;
62 dev->oss.blksize = blksize; 63 dev->dmasound.blksize = blksize;
63 dev->oss.bufsize = blksize * blocks; 64 dev->dmasound.bufsize = blksize * blocks;
64 65
65 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n", 66 dprintk("buffer config: %d blocks / %d bytes, %d kB total\n",
66 blocks,blksize,blksize * blocks / 1024); 67 blocks,blksize,blksize * blocks / 1024);
67 return 0; 68 return 0;
68} 69}
69 70
@@ -71,11 +72,11 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
71{ 72{
72 int err; 73 int err;
73 74
74 if (!dev->oss.bufsize) 75 if (!dev->dmasound.bufsize)
75 BUG(); 76 BUG();
76 videobuf_dma_init(&dev->oss.dma); 77 videobuf_dma_init(&dev->dmasound.dma);
77 err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE, 78 err = videobuf_dma_init_kernel(&dev->dmasound.dma, PCI_DMA_FROMDEVICE,
78 (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT); 79 (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
79 if (0 != err) 80 if (0 != err)
80 return err; 81 return err;
81 return 0; 82 return 0;
@@ -83,26 +84,26 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
83 84
84static int dsp_buffer_free(struct saa7134_dev *dev) 85static int dsp_buffer_free(struct saa7134_dev *dev)
85{ 86{
86 if (!dev->oss.blksize) 87 if (!dev->dmasound.blksize)
87 BUG(); 88 BUG();
88 videobuf_dma_free(&dev->oss.dma); 89 videobuf_dma_free(&dev->dmasound.dma);
89 dev->oss.blocks = 0; 90 dev->dmasound.blocks = 0;
90 dev->oss.blksize = 0; 91 dev->dmasound.blksize = 0;
91 dev->oss.bufsize = 0; 92 dev->dmasound.bufsize = 0;
92 return 0; 93 return 0;
93} 94}
94 95
95static void dsp_dma_start(struct saa7134_dev *dev) 96static void dsp_dma_start(struct saa7134_dev *dev)
96{ 97{
97 dev->oss.dma_blk = 0; 98 dev->dmasound.dma_blk = 0;
98 dev->oss.dma_running = 1; 99 dev->dmasound.dma_running = 1;
99 saa7134_set_dmabits(dev); 100 saa7134_set_dmabits(dev);
100} 101}
101 102
102static void dsp_dma_stop(struct saa7134_dev *dev) 103static void dsp_dma_stop(struct saa7134_dev *dev)
103{ 104{
104 dev->oss.dma_blk = -1; 105 dev->dmasound.dma_blk = -1;
105 dev->oss.dma_running = 0; 106 dev->dmasound.dma_running = 0;
106 saa7134_set_dmabits(dev); 107 saa7134_set_dmabits(dev);
107} 108}
108 109
@@ -113,18 +114,18 @@ static int dsp_rec_start(struct saa7134_dev *dev)
113 unsigned long flags; 114 unsigned long flags;
114 115
115 /* prepare buffer */ 116 /* prepare buffer */
116 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->oss.dma))) 117 if (0 != (err = videobuf_dma_pci_map(dev->pci,&dev->dmasound.dma)))
117 return err; 118 return err;
118 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->oss.pt))) 119 if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt)))
119 goto fail1; 120 goto fail1;
120 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->oss.pt, 121 if (0 != (err = saa7134_pgtable_build(dev->pci,&dev->dmasound.pt,
121 dev->oss.dma.sglist, 122 dev->dmasound.dma.sglist,
122 dev->oss.dma.sglen, 123 dev->dmasound.dma.sglen,
123 0))) 124 0)))
124 goto fail2; 125 goto fail2;
125 126
126 /* sample format */ 127 /* sample format */
127 switch (dev->oss.afmt) { 128 switch (dev->dmasound.afmt) {
128 case AFMT_U8: 129 case AFMT_U8:
129 case AFMT_S8: fmt = 0x00; break; 130 case AFMT_S8: fmt = 0x00; break;
130 case AFMT_U16_LE: 131 case AFMT_U16_LE:
@@ -136,14 +137,14 @@ static int dsp_rec_start(struct saa7134_dev *dev)
136 goto fail2; 137 goto fail2;
137 } 138 }
138 139
139 switch (dev->oss.afmt) { 140 switch (dev->dmasound.afmt) {
140 case AFMT_S8: 141 case AFMT_S8:
141 case AFMT_S16_LE: 142 case AFMT_S16_LE:
142 case AFMT_S16_BE: sign = 1; break; 143 case AFMT_S16_BE: sign = 1; break;
143 default: sign = 0; break; 144 default: sign = 0; break;
144 } 145 }
145 146
146 switch (dev->oss.afmt) { 147 switch (dev->dmasound.afmt) {
147 case AFMT_U16_BE: 148 case AFMT_U16_BE:
148 case AFMT_S16_BE: bswap = 1; break; 149 case AFMT_S16_BE: bswap = 1; break;
149 default: bswap = 0; break; 150 default: bswap = 0; break;
@@ -151,58 +152,58 @@ static int dsp_rec_start(struct saa7134_dev *dev)
151 152
152 switch (dev->pci->device) { 153 switch (dev->pci->device) {
153 case PCI_DEVICE_ID_PHILIPS_SAA7134: 154 case PCI_DEVICE_ID_PHILIPS_SAA7134:
154 if (1 == dev->oss.channels) 155 if (1 == dev->dmasound.channels)
155 fmt |= (1 << 3); 156 fmt |= (1 << 3);
156 if (2 == dev->oss.channels) 157 if (2 == dev->dmasound.channels)
157 fmt |= (3 << 3); 158 fmt |= (3 << 3);
158 if (sign) 159 if (sign)
159 fmt |= 0x04; 160 fmt |= 0x04;
160 fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80; 161 fmt |= (TV == dev->dmasound.input) ? 0xc0 : 0x80;
161 162
162 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff)); 163 saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
163 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8); 164 saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >> 8);
164 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16); 165 saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
165 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt); 166 saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
166 167
167 break; 168 break;
168 case PCI_DEVICE_ID_PHILIPS_SAA7133: 169 case PCI_DEVICE_ID_PHILIPS_SAA7133:
169 case PCI_DEVICE_ID_PHILIPS_SAA7135: 170 case PCI_DEVICE_ID_PHILIPS_SAA7135:
170 if (1 == dev->oss.channels) 171 if (1 == dev->dmasound.channels)
171 fmt |= (1 << 4); 172 fmt |= (1 << 4);
172 if (2 == dev->oss.channels) 173 if (2 == dev->dmasound.channels)
173 fmt |= (2 << 4); 174 fmt |= (2 << 4);
174 if (!sign) 175 if (!sign)
175 fmt |= 0x04; 176 fmt |= 0x04;
176 saa_writel(0x588 >> 2, dev->oss.blksize -4); 177 saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -4);
177 saa_writel(0x58c >> 2, 0x543210 | (fmt << 24)); 178 saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
178 break; 179 break;
179 } 180 }
180 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n", 181 dprintk("rec_start: afmt=%d ch=%d => fmt=0x%x swap=%c\n",
181 dev->oss.afmt, dev->oss.channels, fmt, 182 dev->dmasound.afmt, dev->dmasound.channels, fmt,
182 bswap ? 'b' : '-'); 183 bswap ? 'b' : '-');
183 184
184 /* dma: setup channel 6 (= AUDIO) */ 185 /* dma: setup channel 6 (= AUDIO) */
185 control = SAA7134_RS_CONTROL_BURST_16 | 186 control = SAA7134_RS_CONTROL_BURST_16 |
186 SAA7134_RS_CONTROL_ME | 187 SAA7134_RS_CONTROL_ME |
187 (dev->oss.pt.dma >> 12); 188 (dev->dmasound.pt.dma >> 12);
188 if (bswap) 189 if (bswap)
189 control |= SAA7134_RS_CONTROL_BSWAP; 190 control |= SAA7134_RS_CONTROL_BSWAP;
190 saa_writel(SAA7134_RS_BA1(6),0); 191 saa_writel(SAA7134_RS_BA1(6),0);
191 saa_writel(SAA7134_RS_BA2(6),dev->oss.blksize); 192 saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
192 saa_writel(SAA7134_RS_PITCH(6),0); 193 saa_writel(SAA7134_RS_PITCH(6),0);
193 saa_writel(SAA7134_RS_CONTROL(6),control); 194 saa_writel(SAA7134_RS_CONTROL(6),control);
194 195
195 /* start dma */ 196 /* start dma */
196 dev->oss.recording_on = 1; 197 dev->dmasound.recording_on = 1;
197 spin_lock_irqsave(&dev->slock,flags); 198 spin_lock_irqsave(&dev->slock,flags);
198 dsp_dma_start(dev); 199 dsp_dma_start(dev);
199 spin_unlock_irqrestore(&dev->slock,flags); 200 spin_unlock_irqrestore(&dev->slock,flags);
200 return 0; 201 return 0;
201 202
202 fail2: 203 fail2:
203 saa7134_pgtable_free(dev->pci,&dev->oss.pt); 204 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
204 fail1: 205 fail1:
205 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); 206 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
206 return err; 207 return err;
207} 208}
208 209
@@ -210,17 +211,17 @@ static int dsp_rec_stop(struct saa7134_dev *dev)
210{ 211{
211 unsigned long flags; 212 unsigned long flags;
212 213
213 dprintk("rec_stop dma_blk=%d\n",dev->oss.dma_blk); 214 dprintk("rec_stop dma_blk=%d\n",dev->dmasound.dma_blk);
214 215
215 /* stop dma */ 216 /* stop dma */
216 dev->oss.recording_on = 0; 217 dev->dmasound.recording_on = 0;
217 spin_lock_irqsave(&dev->slock,flags); 218 spin_lock_irqsave(&dev->slock,flags);
218 dsp_dma_stop(dev); 219 dsp_dma_stop(dev);
219 spin_unlock_irqrestore(&dev->slock,flags); 220 spin_unlock_irqrestore(&dev->slock,flags);
220 221
221 /* unlock buffer */ 222 /* unlock buffer */
222 saa7134_pgtable_free(dev->pci,&dev->oss.pt); 223 saa7134_pgtable_free(dev->pci,&dev->dmasound.pt);
223 videobuf_dma_pci_unmap(dev->pci,&dev->oss.dma); 224 videobuf_dma_pci_unmap(dev->pci,&dev->dmasound.dma);
224 return 0; 225 return 0;
225} 226}
226 227
@@ -235,35 +236,35 @@ static int dsp_open(struct inode *inode, struct file *file)
235 236
236 list_for_each(list,&saa7134_devlist) { 237 list_for_each(list,&saa7134_devlist) {
237 h = list_entry(list, struct saa7134_dev, devlist); 238 h = list_entry(list, struct saa7134_dev, devlist);
238 if (h->oss.minor_dsp == minor) 239 if (h->dmasound.minor_dsp == minor)
239 dev = h; 240 dev = h;
240 } 241 }
241 if (NULL == dev) 242 if (NULL == dev)
242 return -ENODEV; 243 return -ENODEV;
243 244
244 down(&dev->oss.lock); 245 down(&dev->dmasound.lock);
245 err = -EBUSY; 246 err = -EBUSY;
246 if (dev->oss.users_dsp) 247 if (dev->dmasound.users_dsp)
247 goto fail1; 248 goto fail1;
248 dev->oss.users_dsp++; 249 dev->dmasound.users_dsp++;
249 file->private_data = dev; 250 file->private_data = dev;
250 251
251 dev->oss.afmt = AFMT_U8; 252 dev->dmasound.afmt = AFMT_U8;
252 dev->oss.channels = 1; 253 dev->dmasound.channels = 1;
253 dev->oss.read_count = 0; 254 dev->dmasound.read_count = 0;
254 dev->oss.read_offset = 0; 255 dev->dmasound.read_offset = 0;
255 dsp_buffer_conf(dev,PAGE_SIZE,64); 256 dsp_buffer_conf(dev,PAGE_SIZE,64);
256 err = dsp_buffer_init(dev); 257 err = dsp_buffer_init(dev);
257 if (0 != err) 258 if (0 != err)
258 goto fail2; 259 goto fail2;
259 260
260 up(&dev->oss.lock); 261 up(&dev->dmasound.lock);
261 return 0; 262 return 0;
262 263
263 fail2: 264 fail2:
264 dev->oss.users_dsp--; 265 dev->dmasound.users_dsp--;
265 fail1: 266 fail1:
266 up(&dev->oss.lock); 267 up(&dev->dmasound.lock);
267 return err; 268 return err;
268} 269}
269 270
@@ -271,13 +272,13 @@ static int dsp_release(struct inode *inode, struct file *file)
271{ 272{
272 struct saa7134_dev *dev = file->private_data; 273 struct saa7134_dev *dev = file->private_data;
273 274
274 down(&dev->oss.lock); 275 down(&dev->dmasound.lock);
275 if (dev->oss.recording_on) 276 if (dev->dmasound.recording_on)
276 dsp_rec_stop(dev); 277 dsp_rec_stop(dev);
277 dsp_buffer_free(dev); 278 dsp_buffer_free(dev);
278 dev->oss.users_dsp--; 279 dev->dmasound.users_dsp--;
279 file->private_data = NULL; 280 file->private_data = NULL;
280 up(&dev->oss.lock); 281 up(&dev->dmasound.lock);
281 return 0; 282 return 0;
282} 283}
283 284
@@ -290,12 +291,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
290 unsigned long flags; 291 unsigned long flags;
291 int err,ret = 0; 292 int err,ret = 0;
292 293
293 add_wait_queue(&dev->oss.wq, &wait); 294 add_wait_queue(&dev->dmasound.wq, &wait);
294 down(&dev->oss.lock); 295 down(&dev->dmasound.lock);
295 while (count > 0) { 296 while (count > 0) {
296 /* wait for data if needed */ 297 /* wait for data if needed */
297 if (0 == dev->oss.read_count) { 298 if (0 == dev->dmasound.read_count) {
298 if (!dev->oss.recording_on) { 299 if (!dev->dmasound.recording_on) {
299 err = dsp_rec_start(dev); 300 err = dsp_rec_start(dev);
300 if (err < 0) { 301 if (err < 0) {
301 if (0 == ret) 302 if (0 == ret)
@@ -303,8 +304,8 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
303 break; 304 break;
304 } 305 }
305 } 306 }
306 if (dev->oss.recording_on && 307 if (dev->dmasound.recording_on &&
307 !dev->oss.dma_running) { 308 !dev->dmasound.dma_running) {
308 /* recover from overruns */ 309 /* recover from overruns */
309 spin_lock_irqsave(&dev->slock,flags); 310 spin_lock_irqsave(&dev->slock,flags);
310 dsp_dma_start(dev); 311 dsp_dma_start(dev);
@@ -315,12 +316,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
315 ret = -EAGAIN; 316 ret = -EAGAIN;
316 break; 317 break;
317 } 318 }
318 up(&dev->oss.lock); 319 up(&dev->dmasound.lock);
319 set_current_state(TASK_INTERRUPTIBLE); 320 set_current_state(TASK_INTERRUPTIBLE);
320 if (0 == dev->oss.read_count) 321 if (0 == dev->dmasound.read_count)
321 schedule(); 322 schedule();
322 set_current_state(TASK_RUNNING); 323 set_current_state(TASK_RUNNING);
323 down(&dev->oss.lock); 324 down(&dev->dmasound.lock);
324 if (signal_pending(current)) { 325 if (signal_pending(current)) {
325 if (0 == ret) 326 if (0 == ret)
326 ret = -EINTR; 327 ret = -EINTR;
@@ -330,12 +331,12 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
330 331
331 /* copy data to userspace */ 332 /* copy data to userspace */
332 bytes = count; 333 bytes = count;
333 if (bytes > dev->oss.read_count) 334 if (bytes > dev->dmasound.read_count)
334 bytes = dev->oss.read_count; 335 bytes = dev->dmasound.read_count;
335 if (bytes > dev->oss.bufsize - dev->oss.read_offset) 336 if (bytes > dev->dmasound.bufsize - dev->dmasound.read_offset)
336 bytes = dev->oss.bufsize - dev->oss.read_offset; 337 bytes = dev->dmasound.bufsize - dev->dmasound.read_offset;
337 if (copy_to_user(buffer + ret, 338 if (copy_to_user(buffer + ret,
338 dev->oss.dma.vmalloc + dev->oss.read_offset, 339 dev->dmasound.dma.vmalloc + dev->dmasound.read_offset,
339 bytes)) { 340 bytes)) {
340 if (0 == ret) 341 if (0 == ret)
341 ret = -EFAULT; 342 ret = -EFAULT;
@@ -344,13 +345,13 @@ static ssize_t dsp_read(struct file *file, char __user *buffer,
344 345
345 ret += bytes; 346 ret += bytes;
346 count -= bytes; 347 count -= bytes;
347 dev->oss.read_count -= bytes; 348 dev->dmasound.read_count -= bytes;
348 dev->oss.read_offset += bytes; 349 dev->dmasound.read_offset += bytes;
349 if (dev->oss.read_offset == dev->oss.bufsize) 350 if (dev->dmasound.read_offset == dev->dmasound.bufsize)
350 dev->oss.read_offset = 0; 351 dev->dmasound.read_offset = 0;
351 } 352 }
352 up(&dev->oss.lock); 353 up(&dev->dmasound.lock);
353 remove_wait_queue(&dev->oss.wq, &wait); 354 remove_wait_queue(&dev->dmasound.wq, &wait);
354 return ret; 355 return ret;
355} 356}
356 357
@@ -370,53 +371,53 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
370 371
371 if (oss_debug > 1) 372 if (oss_debug > 1)
372 saa7134_print_ioctl(dev->name,cmd); 373 saa7134_print_ioctl(dev->name,cmd);
373 switch (cmd) { 374 switch (cmd) {
374 case OSS_GETVERSION: 375 case OSS_GETVERSION:
375 return put_user(SOUND_VERSION, p); 376 return put_user(SOUND_VERSION, p);
376 case SNDCTL_DSP_GETCAPS: 377 case SNDCTL_DSP_GETCAPS:
377 return 0; 378 return 0;
378 379
379 case SNDCTL_DSP_SPEED: 380 case SNDCTL_DSP_SPEED:
380 if (get_user(val, p)) 381 if (get_user(val, p))
381 return -EFAULT; 382 return -EFAULT;
382 /* fall through */ 383 /* fall through */
383 case SOUND_PCM_READ_RATE: 384 case SOUND_PCM_READ_RATE:
384 return put_user(dev->oss.rate, p); 385 return put_user(dev->dmasound.rate, p);
385 386
386 case SNDCTL_DSP_STEREO: 387 case SNDCTL_DSP_STEREO:
387 if (get_user(val, p)) 388 if (get_user(val, p))
388 return -EFAULT; 389 return -EFAULT;
389 down(&dev->oss.lock); 390 down(&dev->dmasound.lock);
390 dev->oss.channels = val ? 2 : 1; 391 dev->dmasound.channels = val ? 2 : 1;
391 if (dev->oss.recording_on) { 392 if (dev->dmasound.recording_on) {
392 dsp_rec_stop(dev); 393 dsp_rec_stop(dev);
393 dsp_rec_start(dev); 394 dsp_rec_start(dev);
394 } 395 }
395 up(&dev->oss.lock); 396 up(&dev->dmasound.lock);
396 return put_user(dev->oss.channels-1, p); 397 return put_user(dev->dmasound.channels-1, p);
397 398
398 case SNDCTL_DSP_CHANNELS: 399 case SNDCTL_DSP_CHANNELS:
399 if (get_user(val, p)) 400 if (get_user(val, p))
400 return -EFAULT; 401 return -EFAULT;
401 if (val != 1 && val != 2) 402 if (val != 1 && val != 2)
402 return -EINVAL; 403 return -EINVAL;
403 down(&dev->oss.lock); 404 down(&dev->dmasound.lock);
404 dev->oss.channels = val; 405 dev->dmasound.channels = val;
405 if (dev->oss.recording_on) { 406 if (dev->dmasound.recording_on) {
406 dsp_rec_stop(dev); 407 dsp_rec_stop(dev);
407 dsp_rec_start(dev); 408 dsp_rec_start(dev);
408 } 409 }
409 up(&dev->oss.lock); 410 up(&dev->dmasound.lock);
410 /* fall through */ 411 /* fall through */
411 case SOUND_PCM_READ_CHANNELS: 412 case SOUND_PCM_READ_CHANNELS:
412 return put_user(dev->oss.channels, p); 413 return put_user(dev->dmasound.channels, p);
413 414
414 case SNDCTL_DSP_GETFMTS: /* Returns a mask */ 415 case SNDCTL_DSP_GETFMTS: /* Returns a mask */
415 return put_user(AFMT_U8 | AFMT_S8 | 416 return put_user(AFMT_U8 | AFMT_S8 |
416 AFMT_U16_LE | AFMT_U16_BE | 417 AFMT_U16_LE | AFMT_U16_BE |
417 AFMT_S16_LE | AFMT_S16_BE, p); 418 AFMT_S16_LE | AFMT_S16_BE, p);
418 419
419 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */ 420 case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */
420 if (get_user(val, p)) 421 if (get_user(val, p))
421 return -EFAULT; 422 return -EFAULT;
422 switch (val) { 423 switch (val) {
@@ -429,20 +430,20 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
429 case AFMT_U16_BE: 430 case AFMT_U16_BE:
430 case AFMT_S16_LE: 431 case AFMT_S16_LE:
431 case AFMT_S16_BE: 432 case AFMT_S16_BE:
432 down(&dev->oss.lock); 433 down(&dev->dmasound.lock);
433 dev->oss.afmt = val; 434 dev->dmasound.afmt = val;
434 if (dev->oss.recording_on) { 435 if (dev->dmasound.recording_on) {
435 dsp_rec_stop(dev); 436 dsp_rec_stop(dev);
436 dsp_rec_start(dev); 437 dsp_rec_start(dev);
437 } 438 }
438 up(&dev->oss.lock); 439 up(&dev->dmasound.lock);
439 return put_user(dev->oss.afmt, p); 440 return put_user(dev->dmasound.afmt, p);
440 default: 441 default:
441 return -EINVAL; 442 return -EINVAL;
442 } 443 }
443 444
444 case SOUND_PCM_READ_BITS: 445 case SOUND_PCM_READ_BITS:
445 switch (dev->oss.afmt) { 446 switch (dev->dmasound.afmt) {
446 case AFMT_U8: 447 case AFMT_U8:
447 case AFMT_S8: 448 case AFMT_S8:
448 return put_user(8, p); 449 return put_user(8, p);
@@ -455,23 +456,23 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
455 return -EINVAL; 456 return -EINVAL;
456 } 457 }
457 458
458 case SNDCTL_DSP_NONBLOCK: 459 case SNDCTL_DSP_NONBLOCK:
459 file->f_flags |= O_NONBLOCK; 460 file->f_flags |= O_NONBLOCK;
460 return 0; 461 return 0;
461 462
462 case SNDCTL_DSP_RESET: 463 case SNDCTL_DSP_RESET:
463 down(&dev->oss.lock); 464 down(&dev->dmasound.lock);
464 if (dev->oss.recording_on) 465 if (dev->dmasound.recording_on)
465 dsp_rec_stop(dev); 466 dsp_rec_stop(dev);
466 up(&dev->oss.lock); 467 up(&dev->dmasound.lock);
467 return 0; 468 return 0;
468 case SNDCTL_DSP_GETBLKSIZE: 469 case SNDCTL_DSP_GETBLKSIZE:
469 return put_user(dev->oss.blksize, p); 470 return put_user(dev->dmasound.blksize, p);
470 471
471 case SNDCTL_DSP_SETFRAGMENT: 472 case SNDCTL_DSP_SETFRAGMENT:
472 if (get_user(val, p)) 473 if (get_user(val, p))
473 return -EFAULT; 474 return -EFAULT;
474 if (dev->oss.recording_on) 475 if (dev->dmasound.recording_on)
475 return -EBUSY; 476 return -EBUSY;
476 dsp_buffer_free(dev); 477 dsp_buffer_free(dev);
477 /* used to be arg >> 16 instead of val >> 16; fixed */ 478 /* used to be arg >> 16 instead of val >> 16; fixed */
@@ -479,16 +480,16 @@ static int dsp_ioctl(struct inode *inode, struct file *file,
479 dsp_buffer_init(dev); 480 dsp_buffer_init(dev);
480 return 0; 481 return 0;
481 482
482 case SNDCTL_DSP_SYNC: 483 case SNDCTL_DSP_SYNC:
483 /* NOP */ 484 /* NOP */
484 return 0; 485 return 0;
485 486
486 case SNDCTL_DSP_GETISPACE: 487 case SNDCTL_DSP_GETISPACE:
487 { 488 {
488 audio_buf_info info; 489 audio_buf_info info;
489 info.fragsize = dev->oss.blksize; 490 info.fragsize = dev->dmasound.blksize;
490 info.fragstotal = dev->oss.blocks; 491 info.fragstotal = dev->dmasound.blocks;
491 info.bytes = dev->oss.read_count; 492 info.bytes = dev->dmasound.read_count;
492 info.fragments = info.bytes / info.fragsize; 493 info.fragments = info.bytes / info.fragsize;
493 if (copy_to_user(argp, &info, sizeof(info))) 494 if (copy_to_user(argp, &info, sizeof(info)))
494 return -EFAULT; 495 return -EFAULT;
@@ -504,13 +505,13 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
504 struct saa7134_dev *dev = file->private_data; 505 struct saa7134_dev *dev = file->private_data;
505 unsigned int mask = 0; 506 unsigned int mask = 0;
506 507
507 poll_wait(file, &dev->oss.wq, wait); 508 poll_wait(file, &dev->dmasound.wq, wait);
508 509
509 if (0 == dev->oss.read_count) { 510 if (0 == dev->dmasound.read_count) {
510 down(&dev->oss.lock); 511 down(&dev->dmasound.lock);
511 if (!dev->oss.recording_on) 512 if (!dev->dmasound.recording_on)
512 dsp_rec_start(dev); 513 dsp_rec_start(dev);
513 up(&dev->oss.lock); 514 up(&dev->dmasound.lock);
514 } else 515 } else
515 mask |= (POLLIN | POLLRDNORM); 516 mask |= (POLLIN | POLLRDNORM);
516 return mask; 517 return mask;
@@ -534,7 +535,7 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
534{ 535{
535 int analog_io,rate; 536 int analog_io,rate;
536 537
537 switch (dev->oss.input) { 538 switch (dev->dmasound.input) {
538 case TV: 539 case TV:
539 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0); 540 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0xc0);
540 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00); 541 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
@@ -542,8 +543,8 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
542 case LINE1: 543 case LINE1:
543 case LINE2: 544 case LINE2:
544 case LINE2_LEFT: 545 case LINE2_LEFT:
545 analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08; 546 analog_io = (LINE1 == dev->dmasound.input) ? 0x00 : 0x08;
546 rate = (32000 == dev->oss.rate) ? 0x01 : 0x03; 547 rate = (32000 == dev->dmasound.rate) ? 0x01 : 0x03;
547 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io); 548 saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
548 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80); 549 saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, 0x80);
549 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate); 550 saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, rate);
@@ -559,10 +560,10 @@ mixer_recsrc_7133(struct saa7134_dev *dev)
559 560
560 xbarin = 0x03; // adc 561 xbarin = 0x03; // adc
561 anabar = 0; 562 anabar = 0;
562 switch (dev->oss.input) { 563 switch (dev->dmasound.input) {
563 case TV: 564 case TV:
564 xbarin = 0; // Demodulator 565 xbarin = 0; // Demodulator
565 anabar = 2; // DACs 566 anabar = 2; // DACs
566 break; 567 break;
567 case LINE1: 568 case LINE1:
568 anabar = 0; // aux1, aux1 569 anabar = 0; // aux1, aux1
@@ -585,9 +586,9 @@ mixer_recsrc(struct saa7134_dev *dev, enum saa7134_audio_in src)
585{ 586{
586 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" }; 587 static const char *iname[] = { "Oops", "TV", "LINE1", "LINE2" };
587 588
588 dev->oss.count++; 589 dev->dmasound.count++;
589 dev->oss.input = src; 590 dev->dmasound.input = src;
590 dprintk("mixer input = %s\n",iname[dev->oss.input]); 591 dprintk("mixer input = %s\n",iname[dev->dmasound.input]);
591 592
592 switch (dev->pci->device) { 593 switch (dev->pci->device) {
593 case PCI_DEVICE_ID_PHILIPS_SAA7134: 594 case PCI_DEVICE_ID_PHILIPS_SAA7134:
@@ -639,7 +640,7 @@ static int mixer_open(struct inode *inode, struct file *file)
639 640
640 list_for_each(list,&saa7134_devlist) { 641 list_for_each(list,&saa7134_devlist) {
641 h = list_entry(list, struct saa7134_dev, devlist); 642 h = list_entry(list, struct saa7134_dev, devlist);
642 if (h->oss.minor_mixer == minor) 643 if (h->dmasound.minor_mixer == minor)
643 dev = h; 644 dev = h;
644 } 645 }
645 if (NULL == dev) 646 if (NULL == dev)
@@ -666,28 +667,28 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
666 667
667 if (oss_debug > 1) 668 if (oss_debug > 1)
668 saa7134_print_ioctl(dev->name,cmd); 669 saa7134_print_ioctl(dev->name,cmd);
669 switch (cmd) { 670 switch (cmd) {
670 case OSS_GETVERSION: 671 case OSS_GETVERSION:
671 return put_user(SOUND_VERSION, p); 672 return put_user(SOUND_VERSION, p);
672 case SOUND_MIXER_INFO: 673 case SOUND_MIXER_INFO:
673 { 674 {
674 mixer_info info; 675 mixer_info info;
675 memset(&info,0,sizeof(info)); 676 memset(&info,0,sizeof(info));
676 strlcpy(info.id, "TV audio", sizeof(info.id)); 677 strlcpy(info.id, "TV audio", sizeof(info.id));
677 strlcpy(info.name, dev->name, sizeof(info.name)); 678 strlcpy(info.name, dev->name, sizeof(info.name));
678 info.modify_counter = dev->oss.count; 679 info.modify_counter = dev->dmasound.count;
679 if (copy_to_user(argp, &info, sizeof(info))) 680 if (copy_to_user(argp, &info, sizeof(info)))
680 return -EFAULT; 681 return -EFAULT;
681 return 0; 682 return 0;
682 } 683 }
683 case SOUND_OLD_MIXER_INFO: 684 case SOUND_OLD_MIXER_INFO:
684 { 685 {
685 _old_mixer_info info; 686 _old_mixer_info info;
686 memset(&info,0,sizeof(info)); 687 memset(&info,0,sizeof(info));
687 strlcpy(info.id, "TV audio", sizeof(info.id)); 688 strlcpy(info.id, "TV audio", sizeof(info.id));
688 strlcpy(info.name, dev->name, sizeof(info.name)); 689 strlcpy(info.name, dev->name, sizeof(info.name));
689 if (copy_to_user(argp, &info, sizeof(info))) 690 if (copy_to_user(argp, &info, sizeof(info)))
690 return -EFAULT; 691 return -EFAULT;
691 return 0; 692 return 0;
692 } 693 }
693 case MIXER_READ(SOUND_MIXER_CAPS): 694 case MIXER_READ(SOUND_MIXER_CAPS):
@@ -697,26 +698,26 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
697 case MIXER_READ(SOUND_MIXER_RECMASK): 698 case MIXER_READ(SOUND_MIXER_RECMASK):
698 case MIXER_READ(SOUND_MIXER_DEVMASK): 699 case MIXER_READ(SOUND_MIXER_DEVMASK):
699 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2; 700 val = SOUND_MASK_LINE1 | SOUND_MASK_LINE2;
700 if (32000 == dev->oss.rate) 701 if (32000 == dev->dmasound.rate)
701 val |= SOUND_MASK_VIDEO; 702 val |= SOUND_MASK_VIDEO;
702 return put_user(val, p); 703 return put_user(val, p);
703 704
704 case MIXER_WRITE(SOUND_MIXER_RECSRC): 705 case MIXER_WRITE(SOUND_MIXER_RECSRC):
705 if (get_user(val, p)) 706 if (get_user(val, p))
706 return -EFAULT; 707 return -EFAULT;
707 input = dev->oss.input; 708 input = dev->dmasound.input;
708 if (32000 == dev->oss.rate && 709 if (32000 == dev->dmasound.rate &&
709 val & SOUND_MASK_VIDEO && dev->oss.input != TV) 710 val & SOUND_MASK_VIDEO && dev->dmasound.input != TV)
710 input = TV; 711 input = TV;
711 if (val & SOUND_MASK_LINE1 && dev->oss.input != LINE1) 712 if (val & SOUND_MASK_LINE1 && dev->dmasound.input != LINE1)
712 input = LINE1; 713 input = LINE1;
713 if (val & SOUND_MASK_LINE2 && dev->oss.input != LINE2) 714 if (val & SOUND_MASK_LINE2 && dev->dmasound.input != LINE2)
714 input = LINE2; 715 input = LINE2;
715 if (input != dev->oss.input) 716 if (input != dev->dmasound.input)
716 mixer_recsrc(dev,input); 717 mixer_recsrc(dev,input);
717 /* fall throuth */ 718 /* fall throuth */
718 case MIXER_READ(SOUND_MIXER_RECSRC): 719 case MIXER_READ(SOUND_MIXER_RECSRC):
719 switch (dev->oss.input) { 720 switch (dev->dmasound.input) {
720 case TV: ret = SOUND_MASK_VIDEO; break; 721 case TV: ret = SOUND_MASK_VIDEO; break;
721 case LINE1: ret = SOUND_MASK_LINE1; break; 722 case LINE1: ret = SOUND_MASK_LINE1; break;
722 case LINE2: ret = SOUND_MASK_LINE2; break; 723 case LINE2: ret = SOUND_MASK_LINE2; break;
@@ -726,7 +727,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
726 727
727 case MIXER_WRITE(SOUND_MIXER_VIDEO): 728 case MIXER_WRITE(SOUND_MIXER_VIDEO):
728 case MIXER_READ(SOUND_MIXER_VIDEO): 729 case MIXER_READ(SOUND_MIXER_VIDEO):
729 if (32000 != dev->oss.rate) 730 if (32000 != dev->dmasound.rate)
730 return -EINVAL; 731 return -EINVAL;
731 return put_user(100 | 100 << 8, p); 732 return put_user(100 | 100 << 8, p);
732 733
@@ -735,22 +736,22 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
735 return -EFAULT; 736 return -EFAULT;
736 val &= 0xff; 737 val &= 0xff;
737 val = (val <= 50) ? 50 : 100; 738 val = (val <= 50) ? 50 : 100;
738 dev->oss.line1 = val; 739 dev->dmasound.line1 = val;
739 mixer_level(dev,LINE1,dev->oss.line1); 740 mixer_level(dev,LINE1,dev->dmasound.line1);
740 /* fall throuth */ 741 /* fall throuth */
741 case MIXER_READ(SOUND_MIXER_LINE1): 742 case MIXER_READ(SOUND_MIXER_LINE1):
742 return put_user(dev->oss.line1 | dev->oss.line1 << 8, p); 743 return put_user(dev->dmasound.line1 | dev->dmasound.line1 << 8, p);
743 744
744 case MIXER_WRITE(SOUND_MIXER_LINE2): 745 case MIXER_WRITE(SOUND_MIXER_LINE2):
745 if (get_user(val, p)) 746 if (get_user(val, p))
746 return -EFAULT; 747 return -EFAULT;
747 val &= 0xff; 748 val &= 0xff;
748 val = (val <= 50) ? 50 : 100; 749 val = (val <= 50) ? 50 : 100;
749 dev->oss.line2 = val; 750 dev->dmasound.line2 = val;
750 mixer_level(dev,LINE2,dev->oss.line2); 751 mixer_level(dev,LINE2,dev->dmasound.line2);
751 /* fall throuth */ 752 /* fall throuth */
752 case MIXER_READ(SOUND_MIXER_LINE2): 753 case MIXER_READ(SOUND_MIXER_LINE2):
753 return put_user(dev->oss.line2 | dev->oss.line2 << 8, p); 754 return put_user(dev->dmasound.line2 | dev->dmasound.line2 << 8, p);
754 755
755 default: 756 default:
756 return -EINVAL; 757 return -EINVAL;
@@ -770,8 +771,8 @@ struct file_operations saa7134_mixer_fops = {
770int saa7134_oss_init1(struct saa7134_dev *dev) 771int saa7134_oss_init1(struct saa7134_dev *dev)
771{ 772{
772 /* general */ 773 /* general */
773 init_MUTEX(&dev->oss.lock); 774 init_MUTEX(&dev->dmasound.lock);
774 init_waitqueue_head(&dev->oss.wq); 775 init_waitqueue_head(&dev->dmasound.wq);
775 776
776 switch (dev->pci->device) { 777 switch (dev->pci->device) {
777 case PCI_DEVICE_ID_PHILIPS_SAA7133: 778 case PCI_DEVICE_ID_PHILIPS_SAA7133:
@@ -783,17 +784,17 @@ int saa7134_oss_init1(struct saa7134_dev *dev)
783 } 784 }
784 785
785 /* dsp */ 786 /* dsp */
786 dev->oss.rate = 32000; 787 dev->dmasound.rate = 32000;
787 if (oss_rate) 788 if (oss_rate)
788 dev->oss.rate = oss_rate; 789 dev->dmasound.rate = oss_rate;
789 dev->oss.rate = (dev->oss.rate > 40000) ? 48000 : 32000; 790 dev->dmasound.rate = (dev->dmasound.rate > 40000) ? 48000 : 32000;
790 791
791 /* mixer */ 792 /* mixer */
792 dev->oss.line1 = 50; 793 dev->dmasound.line1 = 50;
793 dev->oss.line2 = 50; 794 dev->dmasound.line2 = 50;
794 mixer_level(dev,LINE1,dev->oss.line1); 795 mixer_level(dev,LINE1,dev->dmasound.line1);
795 mixer_level(dev,LINE2,dev->oss.line2); 796 mixer_level(dev,LINE2,dev->dmasound.line2);
796 mixer_recsrc(dev, (dev->oss.rate == 32000) ? TV : LINE2); 797 mixer_recsrc(dev, (dev->dmasound.rate == 32000) ? TV : LINE2);
797 798
798 return 0; 799 return 0;
799} 800}
@@ -809,7 +810,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
809 int next_blk, reg = 0; 810 int next_blk, reg = 0;
810 811
811 spin_lock(&dev->slock); 812 spin_lock(&dev->slock);
812 if (UNSET == dev->oss.dma_blk) { 813 if (UNSET == dev->dmasound.dma_blk) {
813 dprintk("irq: recording stopped\n"); 814 dprintk("irq: recording stopped\n");
814 goto done; 815 goto done;
815 } 816 }
@@ -817,11 +818,11 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
817 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f); 818 dprintk("irq: lost %ld\n", (status >> 24) & 0x0f);
818 if (0 == (status & 0x10000000)) { 819 if (0 == (status & 0x10000000)) {
819 /* odd */ 820 /* odd */
820 if (0 == (dev->oss.dma_blk & 0x01)) 821 if (0 == (dev->dmasound.dma_blk & 0x01))
821 reg = SAA7134_RS_BA1(6); 822 reg = SAA7134_RS_BA1(6);
822 } else { 823 } else {
823 /* even */ 824 /* even */
824 if (1 == (dev->oss.dma_blk & 0x01)) 825 if (1 == (dev->dmasound.dma_blk & 0x01))
825 reg = SAA7134_RS_BA2(6); 826 reg = SAA7134_RS_BA2(6);
826 } 827 }
827 if (0 == reg) { 828 if (0 == reg) {
@@ -829,25 +830,25 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
829 (status & 0x10000000) ? "even" : "odd"); 830 (status & 0x10000000) ? "even" : "odd");
830 goto done; 831 goto done;
831 } 832 }
832 if (dev->oss.read_count >= dev->oss.blksize * (dev->oss.blocks-2)) { 833 if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
833 dprintk("irq: overrun [full=%d/%d]\n",dev->oss.read_count, 834 dprintk("irq: overrun [full=%d/%d]\n",dev->dmasound.read_count,
834 dev->oss.bufsize); 835 dev->dmasound.bufsize);
835 dsp_dma_stop(dev); 836 dsp_dma_stop(dev);
836 goto done; 837 goto done;
837 } 838 }
838 839
839 /* next block addr */ 840 /* next block addr */
840 next_blk = (dev->oss.dma_blk + 2) % dev->oss.blocks; 841 next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
841 saa_writel(reg,next_blk * dev->oss.blksize); 842 saa_writel(reg,next_blk * dev->dmasound.blksize);
842 if (oss_debug > 2) 843 if (oss_debug > 2)
843 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n", 844 dprintk("irq: ok, %s, next_blk=%d, addr=%x\n",
844 (status & 0x10000000) ? "even" : "odd ", next_blk, 845 (status & 0x10000000) ? "even" : "odd ", next_blk,
845 next_blk * dev->oss.blksize); 846 next_blk * dev->dmasound.blksize);
846 847
847 /* update status & wake waiting readers */ 848 /* update status & wake waiting readers */
848 dev->oss.dma_blk = (dev->oss.dma_blk + 1) % dev->oss.blocks; 849 dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
849 dev->oss.read_count += dev->oss.blksize; 850 dev->dmasound.read_count += dev->dmasound.blksize;
850 wake_up(&dev->oss.wq); 851 wake_up(&dev->dmasound.wq);
851 852
852 done: 853 done:
853 spin_unlock(&dev->slock); 854 spin_unlock(&dev->slock);
diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h
index ae0c7a165390..ac6431ba4fc3 100644
--- a/drivers/media/video/saa7134/saa7134-reg.h
+++ b/drivers/media/video/saa7134/saa7134-reg.h
@@ -27,7 +27,7 @@
27 27
28/* DMA channels, n = 0 ... 6 */ 28/* DMA channels, n = 0 ... 6 */
29#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n) 29#define SAA7134_RS_BA1(n) ((0x200 >> 2) + 4*n)
30#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n) 30#define SAA7134_RS_BA2(n) ((0x204 >> 2) + 4*n)
31#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n) 31#define SAA7134_RS_PITCH(n) ((0x208 >> 2) + 4*n)
32#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n) 32#define SAA7134_RS_CONTROL(n) ((0x20c >> 2) + 4*n)
33#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25) 33#define SAA7134_RS_CONTROL_WSWAP (0x01 << 25)
@@ -43,16 +43,24 @@
43#define SAA7134_FIFO_SIZE (0x2a0 >> 2) 43#define SAA7134_FIFO_SIZE (0x2a0 >> 2)
44#define SAA7134_THRESHOULD (0x2a4 >> 2) 44#define SAA7134_THRESHOULD (0x2a4 >> 2)
45 45
46#define SAA7133_NUM_SAMPLES (0x588 >> 2)
47#define SAA7133_AUDIO_CHANNEL (0x58c >> 2)
48#define SAA7133_AUDIO_FORMAT (0x58f >> 2)
49#define SAA7133_DIGITAL_OUTPUT_SEL1 (0x46c >> 2)
50#define SAA7133_DIGITAL_OUTPUT_SEL2 (0x470 >> 2)
51#define SAA7133_DIGITAL_INPUT_XBAR1 (0x464 >> 2)
52#define SAA7133_ANALOG_IO_SELECT (0x594 >> 2)
53
46/* main control */ 54/* main control */
47#define SAA7134_MAIN_CTRL (0x2a8 >> 2) 55#define SAA7134_MAIN_CTRL (0x2a8 >> 2)
48#define SAA7134_MAIN_CTRL_VPLLE (1 << 15) 56#define SAA7134_MAIN_CTRL_VPLLE (1 << 15)
49#define SAA7134_MAIN_CTRL_APLLE (1 << 14) 57#define SAA7134_MAIN_CTRL_APLLE (1 << 14)
50#define SAA7134_MAIN_CTRL_EXOSC (1 << 13) 58#define SAA7134_MAIN_CTRL_EXOSC (1 << 13)
51#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12) 59#define SAA7134_MAIN_CTRL_EVFE1 (1 << 12)
52#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11) 60#define SAA7134_MAIN_CTRL_EVFE2 (1 << 11)
53#define SAA7134_MAIN_CTRL_ESFE (1 << 10) 61#define SAA7134_MAIN_CTRL_ESFE (1 << 10)
54#define SAA7134_MAIN_CTRL_EBADC (1 << 9) 62#define SAA7134_MAIN_CTRL_EBADC (1 << 9)
55#define SAA7134_MAIN_CTRL_EBDAC (1 << 8) 63#define SAA7134_MAIN_CTRL_EBDAC (1 << 8)
56#define SAA7134_MAIN_CTRL_TE6 (1 << 6) 64#define SAA7134_MAIN_CTRL_TE6 (1 << 6)
57#define SAA7134_MAIN_CTRL_TE5 (1 << 5) 65#define SAA7134_MAIN_CTRL_TE5 (1 << 5)
58#define SAA7134_MAIN_CTRL_TE4 (1 << 4) 66#define SAA7134_MAIN_CTRL_TE4 (1 << 4)
@@ -348,6 +356,7 @@
348 356
349/* test modes */ 357/* test modes */
350#define SAA7134_SPECIAL_MODE 0x1d0 358#define SAA7134_SPECIAL_MODE 0x1d0
359#define SAA7134_PRODUCTION_TEST_MODE 0x1d1
351 360
352/* audio -- saa7133 + saa7135 only */ 361/* audio -- saa7133 + saa7135 only */
353#define SAA7135_DSP_RWSTATE 0x580 362#define SAA7135_DSP_RWSTATE 0x580
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index 463885601ab4..470903e2f5e5 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -46,17 +46,11 @@ static int buffer_activate(struct saa7134_dev *dev,
46 struct saa7134_buf *buf, 46 struct saa7134_buf *buf,
47 struct saa7134_buf *next) 47 struct saa7134_buf *next)
48{ 48{
49 u32 control;
50 49
51 dprintk("buffer_activate [%p]",buf); 50 dprintk("buffer_activate [%p]",buf);
52 buf->vb.state = STATE_ACTIVE; 51 buf->vb.state = STATE_ACTIVE;
53 buf->top_seen = 0; 52 buf->top_seen = 0;
54 53
55 /* dma: setup channel 5 (= TS) */
56 control = SAA7134_RS_CONTROL_BURST_16 |
57 SAA7134_RS_CONTROL_ME |
58 (buf->pt->dma >> 12);
59
60 if (NULL == next) 54 if (NULL == next)
61 next = buf; 55 next = buf;
62 if (V4L2_FIELD_TOP == buf->vb.field) { 56 if (V4L2_FIELD_TOP == buf->vb.field) {
@@ -68,8 +62,6 @@ static int buffer_activate(struct saa7134_dev *dev,
68 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next)); 62 saa_writel(SAA7134_RS_BA1(5),saa7134_buffer_base(next));
69 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf)); 63 saa_writel(SAA7134_RS_BA2(5),saa7134_buffer_base(buf));
70 } 64 }
71 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
72 saa_writel(SAA7134_RS_CONTROL(5),control);
73 65
74 /* start DMA */ 66 /* start DMA */
75 saa7134_set_dmabits(dev); 67 saa7134_set_dmabits(dev);
@@ -84,6 +76,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
84 struct saa7134_dev *dev = q->priv_data; 76 struct saa7134_dev *dev = q->priv_data;
85 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb); 77 struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
86 unsigned int lines, llength, size; 78 unsigned int lines, llength, size;
79 u32 control;
87 int err; 80 int err;
88 81
89 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]); 82 dprintk("buffer_prepare [%p,%s]\n",buf,v4l2_field_names[field]);
@@ -115,6 +108,18 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
115 if (err) 108 if (err)
116 goto oops; 109 goto oops;
117 } 110 }
111
112 /* dma: setup channel 5 (= TS) */
113 control = SAA7134_RS_CONTROL_BURST_16 |
114 SAA7134_RS_CONTROL_ME |
115 (buf->pt->dma >> 12);
116
117 saa_writeb(SAA7134_TS_DMA0, ((lines-1)&0xff));
118 saa_writeb(SAA7134_TS_DMA1, (((lines-1)>>8)&0xff));
119 saa_writeb(SAA7134_TS_DMA2, ((((lines-1)>>16)&0x3f) | 0x00)); /* TSNOPIT=0, TSCOLAP=0 */
120 saa_writel(SAA7134_RS_PITCH(5),TS_PACKET_SIZE);
121 saa_writel(SAA7134_RS_CONTROL(5),control);
122
118 buf->vb.state = STATE_PREPARED; 123 buf->vb.state = STATE_PREPARED;
119 buf->activate = buffer_activate; 124 buf->activate = buffer_activate;
120 buf->vb.field = field; 125 buf->vb.field = field;
@@ -164,11 +169,11 @@ EXPORT_SYMBOL_GPL(saa7134_ts_qops);
164/* ----------------------------------------------------------- */ 169/* ----------------------------------------------------------- */
165/* exported stuff */ 170/* exported stuff */
166 171
167static unsigned int tsbufs = 4; 172static unsigned int tsbufs = 8;
168module_param(tsbufs, int, 0444); 173module_param(tsbufs, int, 0444);
169MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32"); 174MODULE_PARM_DESC(tsbufs,"number of ts buffers, range 2-32");
170 175
171static unsigned int ts_nr_packets = 30; 176static unsigned int ts_nr_packets = 64;
172module_param(ts_nr_packets, int, 0444); 177module_param(ts_nr_packets, int, 0444);
173MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)"); 178MODULE_PARM_DESC(ts_nr_packets,"size of a ts buffers (in ts packets)");
174 179
@@ -220,10 +225,10 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
220 if (dev->ts_q.curr) { 225 if (dev->ts_q.curr) {
221 field = dev->ts_q.curr->vb.field; 226 field = dev->ts_q.curr->vb.field;
222 if (field == V4L2_FIELD_TOP) { 227 if (field == V4L2_FIELD_TOP) {
223 if ((status & 0x100000) != 0x100000) 228 if ((status & 0x100000) != 0x000000)
224 goto done; 229 goto done;
225 } else { 230 } else {
226 if ((status & 0x100000) != 0x000000) 231 if ((status & 0x100000) != 0x100000)
227 goto done; 232 goto done;
228 } 233 }
229 saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); 234 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 badf2f9e3072..93268427750d 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -207,6 +207,10 @@ static void tvaudio_setcarrier(struct saa7134_dev *dev,
207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary)); 207 saa_writel(SAA7134_CARRIER2_FREQ0 >> 2, tvaudio_carr2reg(secondary));
208} 208}
209 209
210#define SAA7134_MUTE_MASK 0xbb
211#define SAA7134_MUTE_ANALOG 0x04
212#define SAA7134_MUTE_I2S 0x40
213
210static void mute_input_7134(struct saa7134_dev *dev) 214static void mute_input_7134(struct saa7134_dev *dev)
211{ 215{
212 unsigned int mute; 216 unsigned int mute;
@@ -241,7 +245,11 @@ static void mute_input_7134(struct saa7134_dev *dev)
241 245
242 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device) 246 if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
243 /* 7134 mute */ 247 /* 7134 mute */
244 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb); 248 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ?
249 SAA7134_MUTE_MASK |
250 SAA7134_MUTE_ANALOG |
251 SAA7134_MUTE_I2S :
252 SAA7134_MUTE_MASK);
245 253
246 /* switch internal audio mux */ 254 /* switch internal audio mux */
247 switch (in->amux) { 255 switch (in->amux) {
@@ -342,8 +350,8 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
342 set_current_state(TASK_INTERRUPTIBLE); 350 set_current_state(TASK_INTERRUPTIBLE);
343 schedule(); 351 schedule();
344 } else { 352 } else {
345 set_current_state(TASK_INTERRUPTIBLE); 353 schedule_timeout_interruptible
346 schedule_timeout(msecs_to_jiffies(timeout)); 354 (msecs_to_jiffies(timeout));
347 } 355 }
348 } 356 }
349 remove_wait_queue(&dev->thread.wq, &wait); 357 remove_wait_queue(&dev->thread.wq, &wait);
@@ -753,17 +761,17 @@ static int mute_input_7133(struct saa7134_dev *dev)
753 761
754 762
755 /* switch gpio-connected external audio mux */ 763 /* switch gpio-connected external audio mux */
756 if (0 != card(dev).gpiomask) { 764 if (0 != card(dev).gpiomask) {
757 mask = card(dev).gpiomask; 765 mask = card(dev).gpiomask;
758 766
759 if (card(dev).mute.name && dev->ctl_mute) 767 if (card(dev).mute.name && dev->ctl_mute)
760 in = &card(dev).mute; 768 in = &card(dev).mute;
761 else 769 else
762 in = dev->input; 770 in = dev->input;
763 771
764 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask); 772 saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, mask, mask);
765 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio); 773 saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, mask, in->gpio);
766 saa7134_track_gpio(dev,in->name); 774 saa7134_track_gpio(dev,in->name);
767 } 775 }
768 776
769 return 0; 777 return 0;
@@ -1016,9 +1024,12 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
1016 return 0; 1024 return 0;
1017} 1025}
1018 1026
1027EXPORT_SYMBOL(saa_dsp_writel);
1028
1019/* ----------------------------------------------------------- */ 1029/* ----------------------------------------------------------- */
1020/* 1030/*
1021 * Local variables: 1031 * Local variables:
1022 * c-basic-offset: 8 1032 * c-basic-offset: 8
1023 * End: 1033 * End:
1024 */ 1034 */
1035
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 35e5e85f669a..45c852df13ed 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -30,6 +30,9 @@
30#include "saa7134-reg.h" 30#include "saa7134-reg.h"
31#include "saa7134.h" 31#include "saa7134.h"
32 32
33/* Include V4L1 specific functions. Should be removed soon */
34#include <linux/videodev.h>
35
33/* ------------------------------------------------------------------ */ 36/* ------------------------------------------------------------------ */
34 37
35static unsigned int video_debug = 0; 38static unsigned int video_debug = 0;
@@ -48,6 +51,43 @@ MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");
48 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg) 51 printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
49 52
50/* ------------------------------------------------------------------ */ 53/* ------------------------------------------------------------------ */
54/* Defines for Video Output Port Register at address 0x191 */
55
56/* Bit 0: VIP code T bit polarity */
57
58#define VP_T_CODE_P_NON_INVERTED 0x00
59#define VP_T_CODE_P_INVERTED 0x01
60
61/* ------------------------------------------------------------------ */
62/* Defines for Video Output Port Register at address 0x195 */
63
64/* Bit 2: Video output clock delay control */
65
66#define VP_CLK_CTRL2_NOT_DELAYED 0x00
67#define VP_CLK_CTRL2_DELAYED 0x04
68
69/* Bit 1: Video output clock invert control */
70
71#define VP_CLK_CTRL1_NON_INVERTED 0x00
72#define VP_CLK_CTRL1_INVERTED 0x02
73
74/* ------------------------------------------------------------------ */
75/* Defines for Video Output Port Register at address 0x196 */
76
77/* Bits 2 to 0: VSYNC pin video vertical sync type */
78
79#define VP_VS_TYPE_MASK 0x07
80
81#define VP_VS_TYPE_OFF 0x00
82#define VP_VS_TYPE_V123 0x01
83#define VP_VS_TYPE_V_ITU 0x02
84#define VP_VS_TYPE_VGATE_L 0x03
85#define VP_VS_TYPE_RESERVED1 0x04
86#define VP_VS_TYPE_RESERVED2 0x05
87#define VP_VS_TYPE_F_ITU 0x06
88#define VP_VS_TYPE_SC_FID 0x07
89
90/* ------------------------------------------------------------------ */
51/* data structs for video */ 91/* data structs for video */
52 92
53static int video_out[][9] = { 93static int video_out[][9] = {
@@ -273,12 +313,12 @@ static struct saa7134_tvnorm tvnorms[] = {
273 313
274 .h_start = 0, 314 .h_start = 0,
275 .h_stop = 719, 315 .h_stop = 719,
276 .video_v_start = 23, 316 .video_v_start = 23,
277 .video_v_stop = 262, 317 .video_v_stop = 262,
278 .vbi_v_start_0 = 10, 318 .vbi_v_start_0 = 10,
279 .vbi_v_stop_0 = 21, 319 .vbi_v_stop_0 = 21,
280 .vbi_v_start_1 = 273, 320 .vbi_v_start_1 = 273,
281 .src_timing = 7, 321 .src_timing = 7,
282 322
283 .sync_control = 0x18, 323 .sync_control = 0x18,
284 .luma_control = 0x40, 324 .luma_control = 0x40,
@@ -622,7 +662,7 @@ static void set_size(struct saa7134_dev *dev, int task,
622 prescale = 1; 662 prescale = 1;
623 xscale = 1024 * dev->crop_current.width / prescale / width; 663 xscale = 1024 * dev->crop_current.width / prescale / width;
624 yscale = 512 * div * dev->crop_current.height / height; 664 yscale = 512 * div * dev->crop_current.height / height;
625 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale); 665 dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
626 set_h_prescale(dev,task,prescale); 666 set_h_prescale(dev,task,prescale);
627 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff); 667 saa_writeb(SAA7134_H_SCALE_INC1(task), xscale & 0xff);
628 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8); 668 saa_writeb(SAA7134_H_SCALE_INC2(task), xscale >> 8);
@@ -752,20 +792,20 @@ static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
752 maxh = dev->crop_current.height; 792 maxh = dev->crop_current.height;
753 793
754 if (V4L2_FIELD_ANY == field) { 794 if (V4L2_FIELD_ANY == field) {
755 field = (win->w.height > maxh/2) 795 field = (win->w.height > maxh/2)
756 ? V4L2_FIELD_INTERLACED 796 ? V4L2_FIELD_INTERLACED
757 : V4L2_FIELD_TOP; 797 : V4L2_FIELD_TOP;
758 } 798 }
759 switch (field) { 799 switch (field) {
760 case V4L2_FIELD_TOP: 800 case V4L2_FIELD_TOP:
761 case V4L2_FIELD_BOTTOM: 801 case V4L2_FIELD_BOTTOM:
762 maxh = maxh / 2; 802 maxh = maxh / 2;
763 break; 803 break;
764 case V4L2_FIELD_INTERLACED: 804 case V4L2_FIELD_INTERLACED:
765 break; 805 break;
766 default: 806 default:
767 return -EINVAL; 807 return -EINVAL;
768 } 808 }
769 809
770 win->field = field; 810 win->field = field;
771 if (win->w.width > maxw) 811 if (win->w.width > maxw)
@@ -1306,13 +1346,13 @@ video_poll(struct file *file, struct poll_table_struct *wait)
1306 if (res_locked(fh->dev,RESOURCE_VIDEO)) { 1346 if (res_locked(fh->dev,RESOURCE_VIDEO)) {
1307 up(&fh->cap.lock); 1347 up(&fh->cap.lock);
1308 return POLLERR; 1348 return POLLERR;
1309 } 1349 }
1310 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) { 1350 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
1311 up(&fh->cap.lock); 1351 up(&fh->cap.lock);
1312 return POLLERR; 1352 return POLLERR;
1313 } 1353 }
1314 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); 1354 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
1315 fh->cap.read_off = 0; 1355 fh->cap.read_off = 0;
1316 } 1356 }
1317 up(&fh->cap.lock); 1357 up(&fh->cap.lock);
1318 buf = fh->cap.read_buf; 1358 buf = fh->cap.read_buf;
@@ -1666,9 +1706,10 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1666 case VIDIOC_QUERYCAP: 1706 case VIDIOC_QUERYCAP:
1667 { 1707 {
1668 struct v4l2_capability *cap = arg; 1708 struct v4l2_capability *cap = arg;
1709 unsigned int tuner_type = dev->tuner_type;
1669 1710
1670 memset(cap,0,sizeof(*cap)); 1711 memset(cap,0,sizeof(*cap));
1671 strcpy(cap->driver, "saa7134"); 1712 strcpy(cap->driver, "saa7134");
1672 strlcpy(cap->card, saa7134_boards[dev->board].name, 1713 strlcpy(cap->card, saa7134_boards[dev->board].name,
1673 sizeof(cap->card)); 1714 sizeof(cap->card));
1674 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 1715 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -1677,9 +1718,13 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1677 V4L2_CAP_VIDEO_CAPTURE | 1718 V4L2_CAP_VIDEO_CAPTURE |
1678 V4L2_CAP_VIDEO_OVERLAY | 1719 V4L2_CAP_VIDEO_OVERLAY |
1679 V4L2_CAP_VBI_CAPTURE | 1720 V4L2_CAP_VBI_CAPTURE |
1680 V4L2_CAP_TUNER |
1681 V4L2_CAP_READWRITE | 1721 V4L2_CAP_READWRITE |
1682 V4L2_CAP_STREAMING; 1722 V4L2_CAP_STREAMING |
1723 V4L2_CAP_TUNER;
1724
1725 if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
1726 cap->capabilities &= ~V4L2_CAP_TUNER;
1727
1683 return 0; 1728 return 0;
1684 } 1729 }
1685 1730
@@ -1793,9 +1838,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1793 crop->c.height = b->top - crop->c.top + b->height; 1838 crop->c.height = b->top - crop->c.top + b->height;
1794 1839
1795 if (crop->c.left < b->left) 1840 if (crop->c.left < b->left)
1796 crop->c.top = b->left; 1841 crop->c.left = b->left;
1797 if (crop->c.left > b->left + b->width) 1842 if (crop->c.left > b->left + b->width)
1798 crop->c.top = b->left + b->width; 1843 crop->c.left = b->left + b->width;
1799 if (crop->c.width > b->left - crop->c.left + b->width) 1844 if (crop->c.width > b->left - crop->c.left + b->width)
1800 crop->c.width = b->left - crop->c.left + b->width; 1845 crop->c.width = b->left - crop->c.left + b->width;
1801 1846
@@ -1817,6 +1862,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1817 break; 1862 break;
1818 if (NULL != card_in(dev,n).name) { 1863 if (NULL != card_in(dev,n).name) {
1819 strcpy(t->name, "Television"); 1864 strcpy(t->name, "Television");
1865 t->type = V4L2_TUNER_ANALOG_TV;
1820 t->capability = V4L2_TUNER_CAP_NORM | 1866 t->capability = V4L2_TUNER_CAP_NORM |
1821 V4L2_TUNER_CAP_STEREO | 1867 V4L2_TUNER_CAP_STEREO |
1822 V4L2_TUNER_CAP_LANG1 | 1868 V4L2_TUNER_CAP_LANG1 |
@@ -1892,26 +1938,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1892 } 1938 }
1893 case VIDIOC_S_AUDIO: 1939 case VIDIOC_S_AUDIO:
1894 return 0; 1940 return 0;
1895 case VIDIOC_G_PARM: 1941 case VIDIOC_G_PARM:
1896 { 1942 {
1897 struct v4l2_captureparm *parm = arg; 1943 struct v4l2_captureparm *parm = arg;
1898 memset(parm,0,sizeof(*parm)); 1944 memset(parm,0,sizeof(*parm));
1899 return 0; 1945 return 0;
1900 } 1946 }
1901 1947
1902 case VIDIOC_G_PRIORITY: 1948 case VIDIOC_G_PRIORITY:
1903 { 1949 {
1904 enum v4l2_priority *p = arg; 1950 enum v4l2_priority *p = arg;
1905 1951
1906 *p = v4l2_prio_max(&dev->prio); 1952 *p = v4l2_prio_max(&dev->prio);
1907 return 0; 1953 return 0;
1908 } 1954 }
1909 case VIDIOC_S_PRIORITY: 1955 case VIDIOC_S_PRIORITY:
1910 { 1956 {
1911 enum v4l2_priority *prio = arg; 1957 enum v4l2_priority *prio = arg;
1912 1958
1913 return v4l2_prio_change(&dev->prio, &fh->prio, *prio); 1959 return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
1914 } 1960 }
1915 1961
1916 /* --- preview ioctls ---------------------------------------- */ 1962 /* --- preview ioctls ---------------------------------------- */
1917 case VIDIOC_ENUM_FMT: 1963 case VIDIOC_ENUM_FMT:
@@ -2018,7 +2064,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2018 struct v4l2_format *f = arg; 2064 struct v4l2_format *f = arg;
2019 return saa7134_try_fmt(dev,fh,f); 2065 return saa7134_try_fmt(dev,fh,f);
2020 } 2066 }
2021 2067#ifdef HAVE_V4L1
2022 case VIDIOCGMBUF: 2068 case VIDIOCGMBUF:
2023 { 2069 {
2024 struct video_mbuf *mbuf = arg; 2070 struct video_mbuf *mbuf = arg;
@@ -2043,6 +2089,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2043 } 2089 }
2044 return 0; 2090 return 0;
2045 } 2091 }
2092#endif
2046 case VIDIOC_REQBUFS: 2093 case VIDIOC_REQBUFS:
2047 return videobuf_reqbufs(saa7134_queue(fh),arg); 2094 return videobuf_reqbufs(saa7134_queue(fh),arg);
2048 2095
@@ -2060,7 +2107,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
2060 { 2107 {
2061 int res = saa7134_resource(fh); 2108 int res = saa7134_resource(fh);
2062 2109
2063 if (!res_get(dev,fh,res)) 2110 if (!res_get(dev,fh,res))
2064 return -EBUSY; 2111 return -EBUSY;
2065 return videobuf_streamon(saa7134_queue(fh)); 2112 return videobuf_streamon(saa7134_queue(fh));
2066 } 2113 }
@@ -2102,7 +2149,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2102 struct v4l2_capability *cap = arg; 2149 struct v4l2_capability *cap = arg;
2103 2150
2104 memset(cap,0,sizeof(*cap)); 2151 memset(cap,0,sizeof(*cap));
2105 strcpy(cap->driver, "saa7134"); 2152 strcpy(cap->driver, "saa7134");
2106 strlcpy(cap->card, saa7134_boards[dev->board].name, 2153 strlcpy(cap->card, saa7134_boards[dev->board].name,
2107 sizeof(cap->card)); 2154 sizeof(cap->card));
2108 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 2155 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -2119,6 +2166,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
2119 2166
2120 memset(t,0,sizeof(*t)); 2167 memset(t,0,sizeof(*t));
2121 strcpy(t->name, "Radio"); 2168 strcpy(t->name, "Radio");
2169 t->type = V4L2_TUNER_RADIO;
2122 2170
2123 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t); 2171 saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
2124 2172
@@ -2233,7 +2281,7 @@ struct video_device saa7134_video_template =
2233{ 2281{
2234 .name = "saa7134-video", 2282 .name = "saa7134-video",
2235 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY| 2283 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_OVERLAY|
2236 VID_TYPE_CLIPPING|VID_TYPE_SCALES, 2284 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
2237 .hardware = 0, 2285 .hardware = 0,
2238 .fops = &video_fops, 2286 .fops = &video_fops,
2239 .minor = -1, 2287 .minor = -1,
@@ -2280,7 +2328,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2280 dev->tda9887_conf |= TDA9887_AUTOMUTE; 2328 dev->tda9887_conf |= TDA9887_AUTOMUTE;
2281 dev->automute = 0; 2329 dev->automute = 0;
2282 2330
2283 INIT_LIST_HEAD(&dev->video_q.queue); 2331 INIT_LIST_HEAD(&dev->video_q.queue);
2284 init_timer(&dev->video_q.timeout); 2332 init_timer(&dev->video_q.timeout);
2285 dev->video_q.timeout.function = saa7134_buffer_timeout; 2333 dev->video_q.timeout.function = saa7134_buffer_timeout;
2286 dev->video_q.timeout.data = (unsigned long)(&dev->video_q); 2334 dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
@@ -2289,13 +2337,28 @@ int saa7134_video_init1(struct saa7134_dev *dev)
2289 if (saa7134_boards[dev->board].video_out) { 2337 if (saa7134_boards[dev->board].video_out) {
2290 /* enable video output */ 2338 /* enable video output */
2291 int vo = saa7134_boards[dev->board].video_out; 2339 int vo = saa7134_boards[dev->board].video_out;
2340 int video_reg;
2341 unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
2292 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]); 2342 saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
2293 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_out[vo][1]); 2343 video_reg = video_out[vo][1];
2344 if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
2345 video_reg &= ~VP_T_CODE_P_INVERTED;
2346 saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
2294 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]); 2347 saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
2295 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); 2348 saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
2296 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]); 2349 saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
2297 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_out[vo][5]); 2350 video_reg = video_out[vo][5];
2298 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_out[vo][6]); 2351 if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
2352 video_reg &= ~VP_CLK_CTRL2_DELAYED;
2353 if (vid_port_opts & SET_CLOCK_INVERTED)
2354 video_reg |= VP_CLK_CTRL1_INVERTED;
2355 saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
2356 video_reg = video_out[vo][6];
2357 if (vid_port_opts & SET_VSYNC_OFF) {
2358 video_reg &= ~VP_VS_TYPE_MASK;
2359 video_reg |= VP_VS_TYPE_OFF;
2360 }
2361 saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
2299 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]); 2362 saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
2300 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]); 2363 saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
2301 } 2364 }
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 860b89530e2a..fb9727471661 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -24,16 +24,18 @@
24 24
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/videodev.h> 27#include <linux/videodev2.h>
28#include <linux/kdev_t.h> 28#include <linux/kdev_t.h>
29#include <linux/input.h> 29#include <linux/input.h>
30#include <linux/notifier.h>
31#include <linux/delay.h>
30 32
31#include <asm/io.h> 33#include <asm/io.h>
32 34
33#include <media/tuner.h> 35#include <media/tuner.h>
34#include <media/audiochip.h> 36#include <media/audiochip.h>
35#include <media/id.h>
36#include <media/ir-common.h> 37#include <media/ir-common.h>
38#include <media/ir-kbd-i2c.h>
37#include <media/video-buf.h> 39#include <media/video-buf.h>
38#include <media/video-buf-dvb.h> 40#include <media/video-buf-dvb.h>
39 41
@@ -45,6 +47,10 @@
45#endif 47#endif
46#define UNSET (-1U) 48#define UNSET (-1U)
47 49
50#include <sound/driver.h>
51#include <sound/core.h>
52#include <sound/pcm.h>
53
48/* ----------------------------------------------------------- */ 54/* ----------------------------------------------------------- */
49/* enums */ 55/* enums */
50 56
@@ -187,10 +193,39 @@ struct saa7134_format {
187#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64 193#define SAA7134_BOARD_FLYTV_DIGIMATRIX 64
188#define SAA7134_BOARD_KWORLD_TERMINATOR 65 194#define SAA7134_BOARD_KWORLD_TERMINATOR 65
189#define SAA7134_BOARD_YUAN_TUN900 66 195#define SAA7134_BOARD_YUAN_TUN900 66
196#define SAA7134_BOARD_BEHOLD_409FM 67
197#define SAA7134_BOARD_GOTVIEW_7135 68
198#define SAA7134_BOARD_PHILIPS_EUROPA 69
199#define SAA7134_BOARD_VIDEOMATE_DVBT_300 70
200#define SAA7134_BOARD_VIDEOMATE_DVBT_200 71
201#define SAA7134_BOARD_RTD_VFG7350 72
202#define SAA7134_BOARD_RTD_VFG7330 73
203#define SAA7134_BOARD_FLYTVPLATINUM_MINI2 74
204#define SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180 75
205#define SAA7134_BOARD_MONSTERTV_MOBILE 76
206#define SAA7134_BOARD_PINNACLE_PCTV_110i 77
207#define SAA7134_BOARD_ASUSTeK_P7131_DUAL 78
208#define SAA7134_BOARD_SEDNA_PC_TV_CARDBUS 79
209#define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80
210#define SAA7134_BOARD_PHILIPS_TIGER 81
190 211
191#define SAA7134_MAXBOARDS 8 212#define SAA7134_MAXBOARDS 8
192#define SAA7134_INPUT_MAX 8 213#define SAA7134_INPUT_MAX 8
193 214
215/* ----------------------------------------------------------- */
216/* Since we support 2 remote types, lets tell them apart */
217
218#define SAA7134_REMOTE_GPIO 1
219#define SAA7134_REMOTE_I2C 2
220
221/* ----------------------------------------------------------- */
222/* Video Output Port Register Initialization Options */
223
224#define SET_T_CODE_POLARITY_NON_INVERTED (1 << 0)
225#define SET_CLOCK_NOT_DELAYED (1 << 1)
226#define SET_CLOCK_INVERTED (1 << 2)
227#define SET_VSYNC_OFF (1 << 3)
228
194struct saa7134_input { 229struct saa7134_input {
195 char *name; 230 char *name;
196 unsigned int vmux; 231 unsigned int vmux;
@@ -226,6 +261,7 @@ struct saa7134_board {
226 /* peripheral I/O */ 261 /* peripheral I/O */
227 enum saa7134_video_out video_out; 262 enum saa7134_video_out video_out;
228 enum saa7134_mpeg_type mpeg; 263 enum saa7134_mpeg_type mpeg;
264 unsigned int vid_port_opts;
229}; 265};
230 266
231#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name) 267#define card_has_radio(dev) (NULL != saa7134_boards[dev->board].radio.name)
@@ -319,9 +355,9 @@ struct saa7134_fh {
319 struct saa7134_pgtable pt_vbi; 355 struct saa7134_pgtable pt_vbi;
320}; 356};
321 357
322/* oss dsp status */ 358/* dmasound dsp status */
323struct saa7134_oss { 359struct saa7134_dmasound {
324 struct semaphore lock; 360 struct semaphore lock;
325 int minor_mixer; 361 int minor_mixer;
326 int minor_dsp; 362 int minor_dsp;
327 unsigned int users_dsp; 363 unsigned int users_dsp;
@@ -347,6 +383,7 @@ struct saa7134_oss {
347 unsigned int dma_blk; 383 unsigned int dma_blk;
348 unsigned int read_offset; 384 unsigned int read_offset;
349 unsigned int read_count; 385 unsigned int read_count;
386 snd_pcm_substream_t *substream;
350}; 387};
351 388
352/* IR input */ 389/* IR input */
@@ -358,9 +395,9 @@ struct saa7134_ir {
358 u32 mask_keycode; 395 u32 mask_keycode;
359 u32 mask_keydown; 396 u32 mask_keydown;
360 u32 mask_keyup; 397 u32 mask_keyup;
361 int polling; 398 int polling;
362 u32 last_gpio; 399 u32 last_gpio;
363 struct timer_list timer; 400 struct timer_list timer;
364}; 401};
365 402
366/* ts/mpeg status */ 403/* ts/mpeg status */
@@ -383,8 +420,8 @@ struct saa7134_mpeg_ops {
383/* global device status */ 420/* global device status */
384struct saa7134_dev { 421struct saa7134_dev {
385 struct list_head devlist; 422 struct list_head devlist;
386 struct semaphore lock; 423 struct semaphore lock;
387 spinlock_t slock; 424 spinlock_t slock;
388#ifdef VIDIOC_G_PRIORITY 425#ifdef VIDIOC_G_PRIORITY
389 struct v4l2_prio_state prio; 426 struct v4l2_prio_state prio;
390#endif 427#endif
@@ -394,7 +431,7 @@ struct saa7134_dev {
394 struct video_device *video_dev; 431 struct video_device *video_dev;
395 struct video_device *radio_dev; 432 struct video_device *radio_dev;
396 struct video_device *vbi_dev; 433 struct video_device *vbi_dev;
397 struct saa7134_oss oss; 434 struct saa7134_dmasound dmasound;
398 435
399 /* infrared remote */ 436 /* infrared remote */
400 int has_remote; 437 int has_remote;
@@ -421,7 +458,7 @@ struct saa7134_dev {
421 /* i2c i/o */ 458 /* i2c i/o */
422 struct i2c_adapter i2c_adap; 459 struct i2c_adapter i2c_adap;
423 struct i2c_client i2c_client; 460 struct i2c_client i2c_client;
424 unsigned char eedata[64]; 461 unsigned char eedata[128];
425 462
426 /* video overlay */ 463 /* video overlay */
427 struct v4l2_framebuffer ovbuf; 464 struct v4l2_framebuffer ovbuf;
@@ -626,6 +663,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
626int saa7134_input_init1(struct saa7134_dev *dev); 663int saa7134_input_init1(struct saa7134_dev *dev);
627void saa7134_input_fini(struct saa7134_dev *dev); 664void saa7134_input_fini(struct saa7134_dev *dev);
628void saa7134_input_irq(struct saa7134_dev *dev); 665void saa7134_input_irq(struct saa7134_dev *dev);
666void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
629 667
630/* 668/*
631 * Local variables: 669 * Local variables:
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index 3ddbb62312be..cbca896e8cfa 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -26,71 +26,95 @@
26 26
27#include "saa7191.h" 27#include "saa7191.h"
28 28
29#define SAA7191_MODULE_VERSION "0.0.3" 29#define SAA7191_MODULE_VERSION "0.0.5"
30 30
31MODULE_DESCRIPTION("Philips SAA7191 video decoder driver"); 31MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
32MODULE_VERSION(SAA7191_MODULE_VERSION); 32MODULE_VERSION(SAA7191_MODULE_VERSION);
33MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>"); 33MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
34MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
35 35
36// #define SAA7191_DEBUG
37
38#ifdef SAA7191_DEBUG
39#define dprintk(x...) printk("SAA7191: " x);
40#else
41#define dprintk(x...)
42#endif
43
44#define SAA7191_SYNC_COUNT 30
45#define SAA7191_SYNC_DELAY 100 /* milliseconds */
46
36struct saa7191 { 47struct saa7191 {
37 struct i2c_client *client; 48 struct i2c_client *client;
38 49
39 /* the register values are stored here as the actual 50 /* the register values are stored here as the actual
40 * I2C-registers are write-only */ 51 * I2C-registers are write-only */
41 unsigned char reg[25]; 52 u8 reg[25];
42 53
43 unsigned char norm; 54 int input;
44 unsigned char input; 55 int norm;
45}; 56};
46 57
47static struct i2c_driver i2c_driver_saa7191; 58static struct i2c_driver i2c_driver_saa7191;
48 59
49static const unsigned char initseq[] = { 60static const u8 initseq[] = {
50 0, /* Subaddress */ 61 0, /* Subaddress */
51 0x50, /* SAA7191_REG_IDEL */ 62
52 0x30, /* SAA7191_REG_HSYB */ 63 0x50, /* (0x50) SAA7191_REG_IDEL */
53 0x00, /* SAA7191_REG_HSYS */ 64
54 0xe8, /* SAA7191_REG_HCLB */ 65 /* 50 Hz signal timing */
55 0xb6, /* SAA7191_REG_HCLS */ 66 0x30, /* (0x30) SAA7191_REG_HSYB */
56 0xf4, /* SAA7191_REG_HPHI */ 67 0x00, /* (0x00) SAA7191_REG_HSYS */
57 0x01, /* SAA7191_REG_LUMA - chrominance trap active (CVBS) */ 68 0xe8, /* (0xe8) SAA7191_REG_HCLB */
58 0x00, /* SAA7191_REG_HUEC */ 69 0xb6, /* (0xb6) SAA7191_REG_HCLS */
59 0xf8, /* SAA7191_REG_CKTQ */ 70 0xf4, /* (0xf4) SAA7191_REG_HPHI */
60 0xf8, /* SAA7191_REG_CKTS */ 71
61 0x90, /* SAA7191_REG_PLSE */ 72 /* control */
62 0x90, /* SAA7191_REG_SESE */ 73 SAA7191_LUMA_APER_1, /* (0x01) SAA7191_REG_LUMA - CVBS mode */
63 0x00, /* SAA7191_REG_GAIN */ 74 0x00, /* (0x00) SAA7191_REG_HUEC */
64 0x0c, /* SAA7191_REG_STDC - not SECAM, slow time constant */ 75 0xf8, /* (0xf8) SAA7191_REG_CKTQ */
65 0x78, /* SAA7191_REG_IOCK - chrominance from CVBS, GPSW1 & 2 off */ 76 0xf8, /* (0xf8) SAA7191_REG_CKTS */
66 0x99, /* SAA7191_REG_CTL3 - automatic field detection */ 77 0x90, /* (0x90) SAA7191_REG_PLSE */
67 0x00, /* SAA7191_REG_CTL4 */ 78 0x90, /* (0x90) SAA7191_REG_SESE */
68 0x2c, /* SAA7191_REG_CHCV */ 79 0x00, /* (0x00) SAA7191_REG_GAIN */
80 SAA7191_STDC_NFEN | SAA7191_STDC_HRMV, /* (0x0c) SAA7191_REG_STDC
81 * - not SECAM,
82 * slow time constant */
83 SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
84 | SAA7191_IOCK_OEDY, /* (0x78) SAA7191_REG_IOCK
85 * - chroma from CVBS, GPSW1 & 2 off */
86 SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
87 | SAA7191_CTL3_YDEL0, /* (0x99) SAA7191_REG_CTL3
88 * - automatic field detection */
89 0x00, /* (0x00) SAA7191_REG_CTL4 */
90 0x2c, /* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
69 0x00, /* unused */ 91 0x00, /* unused */
70 0x00, /* unused */ 92 0x00, /* unused */
71 0x34, /* SAA7191_REG_HS6B */ 93
72 0x0a, /* SAA7191_REG_HS6S */ 94 /* 60 Hz signal timing */
73 0xf4, /* SAA7191_REG_HC6B */ 95 0x34, /* (0x34) SAA7191_REG_HS6B */
74 0xce, /* SAA7191_REG_HC6S */ 96 0x0a, /* (0x0a) SAA7191_REG_HS6S */
75 0xf4, /* SAA7191_REG_HP6I */ 97 0xf4, /* (0xf4) SAA7191_REG_HC6B */
98 0xce, /* (0xce) SAA7191_REG_HC6S */
99 0xf4, /* (0xf4) SAA7191_REG_HP6I */
76}; 100};
77 101
78/* SAA7191 register handling */ 102/* SAA7191 register handling */
79 103
80static unsigned char saa7191_read_reg(struct i2c_client *client, 104static u8 saa7191_read_reg(struct i2c_client *client,
81 unsigned char reg) 105 u8 reg)
82{ 106{
83 return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg]; 107 return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
84} 108}
85 109
86static int saa7191_read_status(struct i2c_client *client, 110static int saa7191_read_status(struct i2c_client *client,
87 unsigned char *value) 111 u8 *value)
88{ 112{
89 int ret; 113 int ret;
90 114
91 ret = i2c_master_recv(client, value, 1); 115 ret = i2c_master_recv(client, value, 1);
92 if (ret < 0) { 116 if (ret < 0) {
93 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed"); 117 printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
94 return ret; 118 return ret;
95 } 119 }
96 120
@@ -98,17 +122,16 @@ static int saa7191_read_status(struct i2c_client *client,
98} 122}
99 123
100 124
101static int saa7191_write_reg(struct i2c_client *client, unsigned char reg, 125static int saa7191_write_reg(struct i2c_client *client, u8 reg,
102 unsigned char value) 126 u8 value)
103{ 127{
104
105 ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value; 128 ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
106 return i2c_smbus_write_byte_data(client, reg, value); 129 return i2c_smbus_write_byte_data(client, reg, value);
107} 130}
108 131
109/* the first byte of data must be the first subaddress number (register) */ 132/* the first byte of data must be the first subaddress number (register) */
110static int saa7191_write_block(struct i2c_client *client, 133static int saa7191_write_block(struct i2c_client *client,
111 unsigned char length, unsigned char *data) 134 u8 length, u8 *data)
112{ 135{
113 int i; 136 int i;
114 int ret; 137 int ret;
@@ -121,7 +144,7 @@ static int saa7191_write_block(struct i2c_client *client,
121 ret = i2c_master_send(client, data, length); 144 ret = i2c_master_send(client, data, length);
122 if (ret < 0) { 145 if (ret < 0) {
123 printk(KERN_ERR "SAA7191: saa7191_write_block(): " 146 printk(KERN_ERR "SAA7191: saa7191_write_block(): "
124 "write failed"); 147 "write failed\n");
125 return ret; 148 return ret;
126 } 149 }
127 150
@@ -132,8 +155,9 @@ static int saa7191_write_block(struct i2c_client *client,
132 155
133static int saa7191_set_input(struct i2c_client *client, int input) 156static int saa7191_set_input(struct i2c_client *client, int input)
134{ 157{
135 unsigned char luma = saa7191_read_reg(client, SAA7191_REG_LUMA); 158 struct saa7191 *decoder = i2c_get_clientdata(client);
136 unsigned char iock = saa7191_read_reg(client, SAA7191_REG_IOCK); 159 u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
160 u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
137 int err; 161 int err;
138 162
139 switch (input) { 163 switch (input) {
@@ -159,32 +183,20 @@ static int saa7191_set_input(struct i2c_client *client, int input)
159 if (err) 183 if (err)
160 return -EIO; 184 return -EIO;
161 185
186 decoder->input = input;
187
162 return 0; 188 return 0;
163} 189}
164 190
165static int saa7191_set_norm(struct i2c_client *client, int norm) 191static int saa7191_set_norm(struct i2c_client *client, int norm)
166{ 192{
167 struct saa7191 *decoder = i2c_get_clientdata(client); 193 struct saa7191 *decoder = i2c_get_clientdata(client);
168 unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC); 194 u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
169 unsigned char ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); 195 u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
170 unsigned char chcv = saa7191_read_reg(client, SAA7191_REG_CHCV); 196 u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
171 int err; 197 int err;
172 198
173 switch(norm) { 199 switch(norm) {
174 case SAA7191_NORM_AUTO: {
175 unsigned char status;
176
177 // does status depend on current norm ?
178 if (saa7191_read_status(client, &status))
179 return -EIO;
180
181 stdc &= ~SAA7191_STDC_SECS;
182 ctl3 &= ~SAA7191_CTL3_FSEL;
183 ctl3 |= SAA7191_CTL3_AUFD;
184 chcv = (status & SAA7191_STATUS_FIDT)
185 ? SAA7191_CHCV_NTSC : SAA7191_CHCV_PAL;
186 break;
187 }
188 case SAA7191_NORM_PAL: 200 case SAA7191_NORM_PAL:
189 stdc &= ~SAA7191_STDC_SECS; 201 stdc &= ~SAA7191_STDC_SECS;
190 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); 202 ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
@@ -217,60 +229,335 @@ static int saa7191_set_norm(struct i2c_client *client, int norm)
217 229
218 decoder->norm = norm; 230 decoder->norm = norm;
219 231
232 dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
233 stdc, chcv);
234 dprintk("norm: %d\n", norm);
235
220 return 0; 236 return 0;
221} 237}
222 238
223static int saa7191_get_controls(struct i2c_client *client, 239static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
224 struct saa7191_control *ctrl)
225{ 240{
226 unsigned char hue = saa7191_read_reg(client, SAA7191_REG_HUEC); 241 int i = 0;
227 unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
228 242
229 if (hue < 0x80) { 243 dprintk("Checking for signal...\n");
230 hue += 0x80; 244
231 } else { 245 for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
232 hue -= 0x80; 246 if (saa7191_read_status(client, status))
247 return -EIO;
248
249 if (((*status) & SAA7191_STATUS_HLCK) == 0) {
250 dprintk("Signal found\n");
251 return 0;
252 }
253
254 msleep(SAA7191_SYNC_DELAY);
233 } 255 }
234 ctrl->hue = hue;
235 256
236 ctrl->vtrc = (stdc & SAA7191_STDC_VTRC) 257 dprintk("No signal\n");
237 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
238 258
239 return 0; 259 return -EBUSY;
240} 260}
241 261
242static int saa7191_set_controls(struct i2c_client *client, 262static int saa7191_autodetect_norm_extended(struct i2c_client *client)
243 struct saa7191_control *ctrl)
244{ 263{
245 int err; 264 u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
265 u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
266 u8 status;
267 int err = 0;
246 268
247 if (ctrl->hue >= 0) { 269 dprintk("SAA7191 extended signal auto-detection...\n");
248 unsigned char hue = ctrl->hue & 0xff; 270
249 if (hue < 0x80) { 271 stdc &= ~SAA7191_STDC_SECS;
250 hue += 0x80; 272 ctl3 &= ~(SAA7191_CTL3_FSEL);
251 } else { 273
252 hue -= 0x80; 274 err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
275 if (err) {
276 err = -EIO;
277 goto out;
278 }
279 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
280 if (err) {
281 err = -EIO;
282 goto out;
283 }
284
285 ctl3 |= SAA7191_CTL3_AUFD;
286 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
287 if (err) {
288 err = -EIO;
289 goto out;
290 }
291
292 msleep(SAA7191_SYNC_DELAY);
293
294 err = saa7191_wait_for_signal(client, &status);
295 if (err)
296 goto out;
297
298 if (status & SAA7191_STATUS_FIDT) {
299 /* 60Hz signal -> NTSC */
300 dprintk("60Hz signal: NTSC\n");
301 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
302 }
303
304 /* 50Hz signal */
305 dprintk("50Hz signal: Trying PAL...\n");
306
307 /* try PAL first */
308 err = saa7191_set_norm(client, SAA7191_NORM_PAL);
309 if (err)
310 goto out;
311
312 msleep(SAA7191_SYNC_DELAY);
313
314 err = saa7191_wait_for_signal(client, &status);
315 if (err)
316 goto out;
317
318 /* not 50Hz ? */
319 if (status & SAA7191_STATUS_FIDT) {
320 dprintk("No 50Hz signal\n");
321 err = -EAGAIN;
322 goto out;
323 }
324
325 if (status & SAA7191_STATUS_CODE) {
326 dprintk("PAL\n");
327 return 0;
328 }
329
330 dprintk("No color detected with PAL - Trying SECAM...\n");
331
332 /* no color detected ? -> try SECAM */
333 err = saa7191_set_norm(client,
334 SAA7191_NORM_SECAM);
335 if (err)
336 goto out;
337
338 msleep(SAA7191_SYNC_DELAY);
339
340 err = saa7191_wait_for_signal(client, &status);
341 if (err)
342 goto out;
343
344 /* not 50Hz ? */
345 if (status & SAA7191_STATUS_FIDT) {
346 dprintk("No 50Hz signal\n");
347 err = -EAGAIN;
348 goto out;
349 }
350
351 if (status & SAA7191_STATUS_CODE) {
352 /* Color detected -> SECAM */
353 dprintk("SECAM\n");
354 return 0;
355 }
356
357 dprintk("No color detected with SECAM - Going back to PAL.\n");
358
359 /* still no color detected ?
360 * -> set norm back to PAL */
361 err = saa7191_set_norm(client,
362 SAA7191_NORM_PAL);
363 if (err)
364 goto out;
365
366out:
367 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
368 if (ctl3 & SAA7191_CTL3_AUFD) {
369 ctl3 &= ~(SAA7191_CTL3_AUFD);
370 err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
371 if (err) {
372 err = -EIO;
253 } 373 }
254 err = saa7191_write_reg(client, SAA7191_REG_HUEC, hue);
255 if (err)
256 return -EIO;
257 } 374 }
258 if (ctrl->vtrc >= 0) {
259 unsigned char stdc =
260 saa7191_read_reg(client, SAA7191_REG_STDC);
261 375
262 if (ctrl->vtrc) { 376 return err;
263 stdc |= SAA7191_STDC_VTRC; 377}
264 } else { 378
265 stdc &= ~SAA7191_STDC_VTRC; 379static int saa7191_autodetect_norm(struct i2c_client *client)
380{
381 u8 status;
382
383 dprintk("SAA7191 signal auto-detection...\n");
384
385 dprintk("Reading status...\n");
386
387 if (saa7191_read_status(client, &status))
388 return -EIO;
389
390 dprintk("Checking for signal...\n");
391
392 /* no signal ? */
393 if (status & SAA7191_STATUS_HLCK) {
394 dprintk("No signal\n");
395 return -EBUSY;
396 }
397
398 dprintk("Signal found\n");
399
400 if (status & SAA7191_STATUS_FIDT) {
401 /* 60hz signal -> NTSC */
402 dprintk("NTSC\n");
403 return saa7191_set_norm(client, SAA7191_NORM_NTSC);
404 } else {
405 /* 50hz signal -> PAL */
406 dprintk("PAL\n");
407 return saa7191_set_norm(client, SAA7191_NORM_PAL);
408 }
409}
410
411static int saa7191_get_control(struct i2c_client *client,
412 struct saa7191_control *ctrl)
413{
414 u8 reg;
415 int ret = 0;
416
417 switch (ctrl->type) {
418 case SAA7191_CONTROL_BANDPASS:
419 case SAA7191_CONTROL_BANDPASS_WEIGHT:
420 case SAA7191_CONTROL_CORING:
421 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
422 switch (ctrl->type) {
423 case SAA7191_CONTROL_BANDPASS:
424 ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
425 >> SAA7191_LUMA_BPSS_SHIFT;
426 break;
427 case SAA7191_CONTROL_BANDPASS_WEIGHT:
428 ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
429 >> SAA7191_LUMA_APER_SHIFT;
430 break;
431 case SAA7191_CONTROL_CORING:
432 ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
433 >> SAA7191_LUMA_CORI_SHIFT;
434 break;
266 } 435 }
436 break;
437 case SAA7191_CONTROL_FORCE_COLOUR:
438 case SAA7191_CONTROL_CHROMA_GAIN:
439 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
440 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
441 ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
442 else
443 ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
444 >> SAA7191_GAIN_LFIS_SHIFT;
445 break;
446 case SAA7191_CONTROL_HUE:
447 reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
448 if (reg < 0x80)
449 reg += 0x80;
450 else
451 reg -= 0x80;
452 ctrl->value = (s32)reg;
453 break;
454 case SAA7191_CONTROL_VTRC:
455 reg = saa7191_read_reg(client, SAA7191_REG_STDC);
456 ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
457 break;
458 case SAA7191_CONTROL_LUMA_DELAY:
459 reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
460 ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
461 >> SAA7191_CTL3_YDEL_SHIFT;
462 if (ctrl->value >= 4)
463 ctrl->value -= 8;
464 break;
465 case SAA7191_CONTROL_VNR:
466 reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
467 ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
468 >> SAA7191_CTL4_VNOI_SHIFT;
469 break;
470 default:
471 ret = -EINVAL;
472 }
267 473
268 err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); 474 return ret;
269 if (err) 475}
270 return -EIO; 476
477static int saa7191_set_control(struct i2c_client *client,
478 struct saa7191_control *ctrl)
479{
480 u8 reg;
481 int ret = 0;
482
483 switch (ctrl->type) {
484 case SAA7191_CONTROL_BANDPASS:
485 case SAA7191_CONTROL_BANDPASS_WEIGHT:
486 case SAA7191_CONTROL_CORING:
487 reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
488 switch (ctrl->type) {
489 case SAA7191_CONTROL_BANDPASS:
490 reg &= ~SAA7191_LUMA_BPSS_MASK;
491 reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
492 & SAA7191_LUMA_BPSS_MASK;
493 break;
494 case SAA7191_CONTROL_BANDPASS_WEIGHT:
495 reg &= ~SAA7191_LUMA_APER_MASK;
496 reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
497 & SAA7191_LUMA_APER_MASK;
498 break;
499 case SAA7191_CONTROL_CORING:
500 reg &= ~SAA7191_LUMA_CORI_MASK;
501 reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
502 & SAA7191_LUMA_CORI_MASK;
503 break;
504 }
505 ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
506 break;
507 case SAA7191_CONTROL_FORCE_COLOUR:
508 case SAA7191_CONTROL_CHROMA_GAIN:
509 reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
510 if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
511 if (ctrl->value)
512 reg |= SAA7191_GAIN_COLO;
513 else
514 reg &= ~SAA7191_GAIN_COLO;
515 } else {
516 reg &= ~SAA7191_GAIN_LFIS_MASK;
517 reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
518 & SAA7191_GAIN_LFIS_MASK;
519 }
520 ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
521 break;
522 case SAA7191_CONTROL_HUE:
523 reg = ctrl->value & 0xff;
524 if (reg < 0x80)
525 reg += 0x80;
526 else
527 reg -= 0x80;
528 ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
529 break;
530 case SAA7191_CONTROL_VTRC:
531 reg = saa7191_read_reg(client, SAA7191_REG_STDC);
532 if (ctrl->value)
533 reg |= SAA7191_STDC_VTRC;
534 else
535 reg &= ~SAA7191_STDC_VTRC;
536 ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
537 break;
538 case SAA7191_CONTROL_LUMA_DELAY: {
539 s32 value = ctrl->value;
540 if (value < 0)
541 value += 8;
542 reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
543 reg &= ~SAA7191_CTL3_YDEL_MASK;
544 reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
545 & SAA7191_CTL3_YDEL_MASK;
546 ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
547 break;
548 }
549 case SAA7191_CONTROL_VNR:
550 reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
551 reg &= ~SAA7191_CTL4_VNOI_MASK;
552 reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
553 & SAA7191_CTL4_VNOI_MASK;
554 ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
555 break;
556 default:
557 ret = -EINVAL;
271 } 558 }
272 559
273 return 0; 560 return ret;
274} 561}
275 562
276/* I2C-interface */ 563/* I2C-interface */
@@ -309,11 +596,7 @@ static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
309 if (err) 596 if (err)
310 goto out_free_decoder; 597 goto out_free_decoder;
311 598
312 decoder->input = SAA7191_INPUT_COMPOSITE; 599 err = saa7191_write_block(client, sizeof(initseq), (u8 *)initseq);
313 decoder->norm = SAA7191_NORM_AUTO;
314
315 err = saa7191_write_block(client, sizeof(initseq),
316 (unsigned char *)initseq);
317 if (err) { 600 if (err) {
318 printk(KERN_ERR "SAA7191 initialization failed\n"); 601 printk(KERN_ERR "SAA7191 initialization failed\n");
319 goto out_detach_client; 602 goto out_detach_client;
@@ -321,6 +604,14 @@ static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
321 604
322 printk(KERN_INFO "SAA7191 initialized\n"); 605 printk(KERN_INFO "SAA7191 initialized\n");
323 606
607 decoder->input = SAA7191_INPUT_COMPOSITE;
608 decoder->norm = SAA7191_NORM_PAL;
609
610 err = saa7191_autodetect_norm(client);
611 if (err && (err != -EBUSY)) {
612 printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
613 }
614
324 return 0; 615 return 0;
325 616
326out_detach_client: 617out_detach_client:
@@ -368,7 +659,7 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
368 } 659 }
369 case DECODER_GET_STATUS: { 660 case DECODER_GET_STATUS: {
370 int *iarg = arg; 661 int *iarg = arg;
371 unsigned char status; 662 u8 status;
372 int res = 0; 663 int res = 0;
373 664
374 if (saa7191_read_status(client, &status)) { 665 if (saa7191_read_status(client, &status)) {
@@ -404,7 +695,7 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
404 695
405 switch (*iarg) { 696 switch (*iarg) {
406 case VIDEO_MODE_AUTO: 697 case VIDEO_MODE_AUTO:
407 return saa7191_set_norm(client, SAA7191_NORM_AUTO); 698 return saa7191_autodetect_norm(client);
408 case VIDEO_MODE_PAL: 699 case VIDEO_MODE_PAL:
409 return saa7191_set_norm(client, SAA7191_NORM_PAL); 700 return saa7191_set_norm(client, SAA7191_NORM_PAL);
410 case VIDEO_MODE_NTSC: 701 case VIDEO_MODE_NTSC:
@@ -446,38 +737,48 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
446 int err; 737 int err;
447 738
448 val = (pic->hue >> 8) - 0x80; 739 val = (pic->hue >> 8) - 0x80;
740
449 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val); 741 err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
450 if (err) 742 if (err)
451 return -EIO; 743 return -EIO;
744
452 break; 745 break;
453 } 746 }
454 case DECODER_SAA7191_GET_STATUS: { 747 case DECODER_SAA7191_GET_STATUS: {
455 struct saa7191_status *status = arg; 748 struct saa7191_status *status = arg;
456 unsigned char status_reg; 749 u8 status_reg;
457 750
458 if (saa7191_read_status(client, &status_reg)) 751 if (saa7191_read_status(client, &status_reg))
459 return -EIO; 752 return -EIO;
753
460 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0) 754 status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
461 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED; 755 ? 1 : 0;
462 status->ntsc = (status_reg & SAA7191_STATUS_FIDT) 756 status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
463 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED; 757 ? 1 : 0;
464 status->color = (status_reg & SAA7191_STATUS_CODE) 758 status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
465 ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED;
466 759
467 status->input = decoder->input; 760 status->input = decoder->input;
468 status->norm = decoder->norm; 761 status->norm = decoder->norm;
762
763 break;
469 } 764 }
470 case DECODER_SAA7191_SET_NORM: { 765 case DECODER_SAA7191_SET_NORM: {
471 int *norm = arg; 766 int *norm = arg;
472 return saa7191_set_norm(client, *norm); 767
768 switch (*norm) {
769 case SAA7191_NORM_AUTO:
770 return saa7191_autodetect_norm(client);
771 case SAA7191_NORM_AUTO_EXT:
772 return saa7191_autodetect_norm_extended(client);
773 default:
774 return saa7191_set_norm(client, *norm);
775 }
473 } 776 }
474 case DECODER_SAA7191_GET_CONTROLS: { 777 case DECODER_SAA7191_GET_CONTROL: {
475 struct saa7191_control *ctrl = arg; 778 return saa7191_get_control(client, arg);
476 return saa7191_get_controls(client, ctrl);
477 } 779 }
478 case DECODER_SAA7191_SET_CONTROLS: { 780 case DECODER_SAA7191_SET_CONTROL: {
479 struct saa7191_control *ctrl = arg; 781 return saa7191_set_control(client, arg);
480 return saa7191_set_controls(client, ctrl);
481 } 782 }
482 default: 783 default:
483 return -EINVAL; 784 return -EINVAL;
@@ -488,12 +789,12 @@ static int saa7191_command(struct i2c_client *client, unsigned int cmd,
488 789
489static struct i2c_driver i2c_driver_saa7191 = { 790static struct i2c_driver i2c_driver_saa7191 = {
490 .owner = THIS_MODULE, 791 .owner = THIS_MODULE,
491 .name = "saa7191", 792 .name = "saa7191",
492 .id = I2C_DRIVERID_SAA7191, 793 .id = I2C_DRIVERID_SAA7191,
493 .flags = I2C_DF_NOTIFY, 794 .flags = I2C_DF_NOTIFY,
494 .attach_adapter = saa7191_probe, 795 .attach_adapter = saa7191_probe,
495 .detach_client = saa7191_detach, 796 .detach_client = saa7191_detach,
496 .command = saa7191_command 797 .command = saa7191_command
497}; 798};
498 799
499static int saa7191_init(void) 800static int saa7191_init(void)
diff --git a/drivers/media/video/saa7191.h b/drivers/media/video/saa7191.h
index 272045031435..a2310da1940d 100644
--- a/drivers/media/video/saa7191.h
+++ b/drivers/media/video/saa7191.h
@@ -24,8 +24,8 @@
24#define SAA7191_REG_HPHI 0x05 24#define SAA7191_REG_HPHI 0x05
25#define SAA7191_REG_LUMA 0x06 25#define SAA7191_REG_LUMA 0x06
26#define SAA7191_REG_HUEC 0x07 26#define SAA7191_REG_HUEC 0x07
27#define SAA7191_REG_CKTQ 0x08 27#define SAA7191_REG_CKTQ 0x08 /* bits 3-7 */
28#define SAA7191_REG_CKTS 0x09 28#define SAA7191_REG_CKTS 0x09 /* bits 3-7 */
29#define SAA7191_REG_PLSE 0x0a 29#define SAA7191_REG_PLSE 0x0a
30#define SAA7191_REG_SESE 0x0b 30#define SAA7191_REG_SESE 0x0b
31#define SAA7191_REG_GAIN 0x0c 31#define SAA7191_REG_GAIN 0x0c
@@ -43,30 +43,82 @@
43 43
44/* Status Register definitions */ 44/* Status Register definitions */
45#define SAA7191_STATUS_CODE 0x01 /* color detected flag */ 45#define SAA7191_STATUS_CODE 0x01 /* color detected flag */
46#define SAA7191_STATUS_FIDT 0x20 /* format type NTSC/PAL */ 46#define SAA7191_STATUS_FIDT 0x20 /* signal type 50/60 Hz */
47#define SAA7191_STATUS_HLCK 0x40 /* PLL unlocked/locked */ 47#define SAA7191_STATUS_HLCK 0x40 /* PLL unlocked(1)/locked(0) */
48#define SAA7191_STATUS_STTC 0x80 /* tv/vtr time constant */ 48#define SAA7191_STATUS_STTC 0x80 /* tv/vtr time constant */
49 49
50/* Luminance Control Register definitions */ 50/* Luminance Control Register definitions */
51/* input mode select bit:
52 * 0=CVBS (chrominance trap active), 1=S-Video (trap bypassed) */
51#define SAA7191_LUMA_BYPS 0x80 53#define SAA7191_LUMA_BYPS 0x80
52 54/* pre-filter (only when chrominance trap is active) */
53/* Chroma Gain Control Settings Register definitions */ 55#define SAA7191_LUMA_PREF 0x40
54/* 0=automatic colour-killer enabled, 1=forced colour on */ 56/* aperture bandpass to select different characteristics with maximums
57 * (bits 4-5) */
58#define SAA7191_LUMA_BPSS_MASK 0x30
59#define SAA7191_LUMA_BPSS_SHIFT 4
60#define SAA7191_LUMA_BPSS_3 0x30
61#define SAA7191_LUMA_BPSS_2 0x20
62#define SAA7191_LUMA_BPSS_1 0x10
63#define SAA7191_LUMA_BPSS_0 0x00
64/* coring range for high frequency components according to 8-bit luminance
65 * (bits 2-3)
66 * 0=coring off, n= (+-)n LSB */
67#define SAA7191_LUMA_CORI_MASK 0x0c
68#define SAA7191_LUMA_CORI_SHIFT 2
69#define SAA7191_LUMA_CORI_3 0x0c
70#define SAA7191_LUMA_CORI_2 0x08
71#define SAA7191_LUMA_CORI_1 0x04
72#define SAA7191_LUMA_CORI_0 0x00
73/* aperture bandpass filter weights high frequency components of luminance
74 * signal (bits 0-1)
75 * 0=factor 0, 1=0.25, 2=0.5, 3=1 */
76#define SAA7191_LUMA_APER_MASK 0x03
77#define SAA7191_LUMA_APER_SHIFT 0
78#define SAA7191_LUMA_APER_3 0x03
79#define SAA7191_LUMA_APER_2 0x02
80#define SAA7191_LUMA_APER_1 0x01
81#define SAA7191_LUMA_APER_0 0x00
82
83/* Chrominance Gain Control Settings Register definitions */
84/* colour on: 0=automatic colour-killer enabled, 1=forced colour on */
55#define SAA7191_GAIN_COLO 0x80 85#define SAA7191_GAIN_COLO 0x80
86/* chrominance gain control (AGC filter)
87 * 0=loop filter time constant slow, 1=medium, 2=fast, 3=actual gain */
88#define SAA7191_GAIN_LFIS_MASK 0x60
89#define SAA7191_GAIN_LFIS_SHIFT 5
90#define SAA7191_GAIN_LFIS_3 0x60
91#define SAA7191_GAIN_LFIS_2 0x40
92#define SAA7191_GAIN_LFIS_1 0x20
93#define SAA7191_GAIN_LFIS_0 0x00
56 94
57/* Standard/Mode Control Register definitions */ 95/* Standard/Mode Control Register definitions */
58/* tv/vtr mode bit: 0=TV mode (slow time constant), 96/* tv/vtr mode bit: 0=TV mode (slow time constant),
59 * 1=VTR mode (fast time constant) */ 97 * 1=VTR mode (fast time constant) */
60#define SAA7191_STDC_VTRC 0x80 98#define SAA7191_STDC_VTRC 0x80
99/* SAA7191B-specific functions enable (RTCO, ODD and GPSW0 outputs)
100 * 0=outputs set to high-impedance (circuit equals SAA7191), 1=enabled */
101#define SAA7191_STDC_NFEN 0x08
102/* HREF generation: 0=like SAA7191, 1=HREF is 8xLLC2 clocks earlier */
103#define SAA7191_STDC_HRMV 0x04
104/* general purpose switch 0
105 * (not used with VINO afaik) */
106#define SAA7191_STDC_GPSW0 0x02
61/* SECAM mode bit: 0=other standards, 1=SECAM */ 107/* SECAM mode bit: 0=other standards, 1=SECAM */
62#define SAA7191_STDC_SECS 0x01 108#define SAA7191_STDC_SECS 0x01
63/* the bit fields above must be or'd with this value */
64#define SAA7191_STDC_VALUE 0x0c
65 109
66/* I/O and Clock Control Register definitions */ 110/* I/O and Clock Control Register definitions */
67/* horizontal clock PLL: 0=PLL closed, 111/* horizontal clock PLL: 0=PLL closed,
68 * 1=PLL circuit open and horizontal freq fixed */ 112 * 1=PLL circuit open and horizontal freq fixed */
69#define SAA7191_IOCK_HPLL 0x80 113#define SAA7191_IOCK_HPLL 0x80
114/* colour-difference output enable (outputs UV0-UV7) */
115#define SAA7191_IOCK_OEDC 0x40
116/* H-sync output enable */
117#define SAA7191_IOCK_OEHS 0x20
118/* V-sync output enable */
119#define SAA7191_IOCK_OEVS 0x10
120/* luminance output enable (outputs Y0-Y7) */
121#define SAA7191_IOCK_OEDY 0x08
70/* S-VHS bit (chrominance from CVBS or from chrominance input): 122/* S-VHS bit (chrominance from CVBS or from chrominance input):
71 * 0=controlled by BYPS-bit, 1=from chrominance input */ 123 * 0=controlled by BYPS-bit, 1=from chrominance input */
72#define SAA7191_IOCK_CHRS 0x04 124#define SAA7191_IOCK_CHRS 0x04
@@ -83,11 +135,40 @@
83/* field select: (if AUFD=0) 135/* field select: (if AUFD=0)
84 * 0=50Hz (625 lines), 1=60Hz (525 lines) */ 136 * 0=50Hz (625 lines), 1=60Hz (525 lines) */
85#define SAA7191_CTL3_FSEL 0x40 137#define SAA7191_CTL3_FSEL 0x40
86/* the bit fields above must be or'd with this value */ 138/* SECAM cross-colour reduction enable */
87#define SAA7191_CTL3_VALUE 0x19 139#define SAA7191_CTL3_SXCR 0x20
140/* sync and clamping pulse enable (HCL and HSY outputs) */
141#define SAA7191_CTL3_SCEN 0x10
142/* output format: 0=4:1:1, 1=4:2:2 (4:2:2 for VINO) */
143#define SAA7191_CTL3_OFTS 0x08
144/* luminance delay compensation
145 * 0=0*2/LLC, 1=+1*2/LLC, 2=+2*2/LLC, 3=+3*2/LLC,
146 * 4=-4*2/LLC, 5=-3*2/LLC, 6=-2*2/LLC, 7=-1*2/LLC
147 * step size = 2/LLC = 67.8ns for 50Hz, 81.5ns for 60Hz */
148#define SAA7191_CTL3_YDEL_MASK 0x07
149#define SAA7191_CTL3_YDEL_SHIFT 0
150#define SAA7191_CTL3_YDEL2 0x04
151#define SAA7191_CTL3_YDEL1 0x02
152#define SAA7191_CTL3_YDEL0 0x01
153
154/* Miscellaneous Control #2 Register definitions */
155/* select HREF position
156 * 0=normal, HREF is matched to YUV output port,
157 * 1=HREF is matched to CVBS input port */
158#define SAA7191_CTL4_HRFS 0x04
159/* vertical noise reduction
160 * 0=normal, 1=searching window, 2=auto-deflection, 3=reduction bypassed */
161#define SAA7191_CTL4_VNOI_MASK 0x03
162#define SAA7191_CTL4_VNOI_SHIFT 0
163#define SAA7191_CTL4_VNOI_3 0x03
164#define SAA7191_CTL4_VNOI_2 0x02
165#define SAA7191_CTL4_VNOI_1 0x01
166#define SAA7191_CTL4_VNOI_0 0x00
88 167
89/* Chrominance Gain Control Register definitions 168/* Chrominance Gain Control Register definitions
90 * (nominal value for UV CCIR level) */ 169 * - for QAM-modulated input signals, effects output amplitude
170 * (SECAM gain fixed)
171 * (nominal values for UV CCIR level) */
91#define SAA7191_CHCV_NTSC 0x2c 172#define SAA7191_CHCV_NTSC 0x2c
92#define SAA7191_CHCV_PAL 0x59 173#define SAA7191_CHCV_PAL 0x59
93 174
@@ -99,16 +180,13 @@
99#define SAA7191_NORM_PAL 1 180#define SAA7191_NORM_PAL 1
100#define SAA7191_NORM_NTSC 2 181#define SAA7191_NORM_NTSC 2
101#define SAA7191_NORM_SECAM 3 182#define SAA7191_NORM_SECAM 3
102 183#define SAA7191_NORM_AUTO_EXT 4 /* extended auto-detection */
103#define SAA7191_VALUE_ENABLED 1
104#define SAA7191_VALUE_DISABLED 0
105#define SAA7191_VALUE_UNCHANGED -1
106 184
107struct saa7191_status { 185struct saa7191_status {
108 /* 0=no signal, 1=signal active*/ 186 /* 0=no signal, 1=signal detected */
109 int signal; 187 int signal;
110 /* 0=50hz (pal) signal, 1=60hz (ntsc) signal */ 188 /* 0=50hz (pal) signal, 1=60hz (ntsc) signal */
111 int ntsc; 189 int signal_60hz;
112 /* 0=no color detected, 1=color detected */ 190 /* 0=no color detected, 1=color detected */
113 int color; 191 int color;
114 192
@@ -118,22 +196,60 @@ struct saa7191_status {
118 int norm; 196 int norm;
119}; 197};
120 198
121#define SAA7191_HUE_MIN 0x00 199#define SAA7191_BANDPASS_MIN 0x00
122#define SAA7191_HUE_MAX 0xff 200#define SAA7191_BANDPASS_MAX 0x03
123#define SAA7191_HUE_DEFAULT 0x80 201#define SAA7191_BANDPASS_DEFAULT 0x00
202
203#define SAA7191_BANDPASS_WEIGHT_MIN 0x00
204#define SAA7191_BANDPASS_WEIGHT_MAX 0x03
205#define SAA7191_BANDPASS_WEIGHT_DEFAULT 0x01
206
207#define SAA7191_CORING_MIN 0x00
208#define SAA7191_CORING_MAX 0x03
209#define SAA7191_CORING_DEFAULT 0x00
210
211#define SAA7191_HUE_MIN 0x00
212#define SAA7191_HUE_MAX 0xff
213#define SAA7191_HUE_DEFAULT 0x80
214
215#define SAA7191_VTRC_MIN 0x00
216#define SAA7191_VTRC_MAX 0x01
217#define SAA7191_VTRC_DEFAULT 0x00
218
219#define SAA7191_FORCE_COLOUR_MIN 0x00
220#define SAA7191_FORCE_COLOUR_MAX 0x01
221#define SAA7191_FORCE_COLOUR_DEFAULT 0x00
222
223#define SAA7191_CHROMA_GAIN_MIN 0x00
224#define SAA7191_CHROMA_GAIN_MAX 0x03
225#define SAA7191_CHROMA_GAIN_DEFAULT 0x00
226
227#define SAA7191_LUMA_DELAY_MIN -0x04
228#define SAA7191_LUMA_DELAY_MAX 0x03
229#define SAA7191_LUMA_DELAY_DEFAULT 0x01
230
231#define SAA7191_VNR_MIN 0x00
232#define SAA7191_VNR_MAX 0x03
233#define SAA7191_VNR_DEFAULT 0x00
124 234
125#define SAA7191_VTRC_MIN 0x00 235#define SAA7191_CONTROL_BANDPASS 0
126#define SAA7191_VTRC_MAX 0x01 236#define SAA7191_CONTROL_BANDPASS_WEIGHT 1
127#define SAA7191_VTRC_DEFAULT 0x00 237#define SAA7191_CONTROL_CORING 2
238#define SAA7191_CONTROL_FORCE_COLOUR 3 /* boolean */
239#define SAA7191_CONTROL_CHROMA_GAIN 4
240#define SAA7191_CONTROL_HUE 5
241#define SAA7191_CONTROL_VTRC 6 /* boolean */
242#define SAA7191_CONTROL_LUMA_DELAY 7
243#define SAA7191_CONTROL_VNR 8
128 244
129struct saa7191_control { 245struct saa7191_control {
130 int hue; 246 u8 type;
131 int vtrc; 247 s32 value;
132}; 248};
133 249
134#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status) 250#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status)
135#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int) 251#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int)
136#define DECODER_SAA7191_GET_CONTROLS _IOR('d', 197, struct saa7191_control) 252#define DECODER_SAA7191_GET_CONTROL _IOR('d', 197, struct saa7191_control)
137#define DECODER_SAA7191_SET_CONTROLS _IOW('d', 198, struct saa7191_control) 253#define DECODER_SAA7191_SET_CONTROL _IOW('d', 198, struct saa7191_control)
138 254
139#endif 255#endif
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 255b6088ebf9..d32737dd2142 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -50,7 +50,6 @@
50 50
51#include "bttv.h" 51#include "bttv.h"
52#include <media/audiochip.h> 52#include <media/audiochip.h>
53#include <media/id.h>
54 53
55#ifndef VIDEO_AUDIO_BALANCE 54#ifndef VIDEO_AUDIO_BALANCE
56# define VIDEO_AUDIO_BALANCE 32 55# define VIDEO_AUDIO_BALANCE 32
@@ -310,9 +309,9 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind)
310 memset(t,0,sizeof *t); 309 memset(t,0,sizeof *t);
311 310
312 client = &t->c; 311 client = &t->c;
313 memcpy(client,&client_template,sizeof(struct i2c_client)); 312 memcpy(client,&client_template,sizeof(struct i2c_client));
314 client->adapter = adap; 313 client->adapter = adap;
315 client->addr = addr; 314 client->addr = addr;
316 i2c_set_clientdata(client, t); 315 i2c_set_clientdata(client, t);
317 316
318 do_tda7432_init(client); 317 do_tda7432_init(client);
@@ -472,7 +471,7 @@ static int tda7432_command(struct i2c_client *client,
472 } 471 }
473 } 472 }
474 473
475 t->muted=(va->flags & VIDEO_AUDIO_MUTE); 474 t->muted=(va->flags & VIDEO_AUDIO_MUTE);
476 if (t->muted) 475 if (t->muted)
477 { 476 {
478 /* Mute & update balance*/ 477 /* Mute & update balance*/
@@ -503,12 +502,12 @@ static int tda7432_command(struct i2c_client *client,
503 502
504static struct i2c_driver driver = { 503static struct i2c_driver driver = {
505 .owner = THIS_MODULE, 504 .owner = THIS_MODULE,
506 .name = "i2c tda7432 driver", 505 .name = "i2c tda7432 driver",
507 .id = I2C_DRIVERID_TDA7432, 506 .id = I2C_DRIVERID_TDA7432,
508 .flags = I2C_DF_NOTIFY, 507 .flags = I2C_DF_NOTIFY,
509 .attach_adapter = tda7432_probe, 508 .attach_adapter = tda7432_probe,
510 .detach_client = tda7432_detach, 509 .detach_client = tda7432_detach,
511 .command = tda7432_command, 510 .command = tda7432_command,
512}; 511};
513 512
514static struct i2c_client client_template = 513static struct i2c_client client_template =
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index c65f0c7680a2..b2dfe07e9f9d 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -1,172 +1,406 @@
1/* 1/*
2 * 2
3 * i2c tv tuner chip device driver 3 i2c tv tuner chip device driver
4 * controls the philips tda8290+75 tuner chip combo. 4 controls the philips tda8290+75 tuner chip combo.
5 */ 5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
6#include <linux/i2c.h> 21#include <linux/i2c.h>
7#include <linux/videodev.h> 22#include <linux/videodev.h>
8#include <linux/delay.h> 23#include <linux/delay.h>
9#include <media/tuner.h> 24#include <media/tuner.h>
10 25
11#define I2C_ADDR_TDA8290 0x4b
12#define I2C_ADDR_TDA8275 0x61
13
14/* ---------------------------------------------------------------------- */ 26/* ---------------------------------------------------------------------- */
15 27
16struct freq_entry { 28struct tda827x_data {
17 u16 freq; 29 u32 lomax;
18 u8 value; 30 u8 spd;
31 u8 bs;
32 u8 bp;
33 u8 cp;
34 u8 gc3;
35 u8 div1p5;
19}; 36};
20 37
21static struct freq_entry band_table[] = { 38 /* Note lomax entry is lo / 62500 */
22 { 0x2DF4, 0x1C }, 39
23 { 0x2574, 0x14 }, 40static struct tda827x_data tda827x_analog[] = {
24 { 0x22B4, 0x0C }, 41 { .lomax = 992, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 62 MHz */
25 { 0x20D4, 0x0B }, 42 { .lomax = 1056, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, /* 66 MHz */
26 { 0x1E74, 0x3B }, 43 { .lomax = 1216, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 76 MHz */
27 { 0x1C34, 0x33 }, 44 { .lomax = 1344, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, /* 84 MHz */
28 { 0x16F4, 0x5B }, 45 { .lomax = 1488, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 93 MHz */
29 { 0x1454, 0x53 }, 46 { .lomax = 1568, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 98 MHz */
30 { 0x12D4, 0x52 }, 47 { .lomax = 1744, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 109 MHz */
31 { 0x1034, 0x4A }, 48 { .lomax = 1968, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 123 MHz */
32 { 0x0EE4, 0x7A }, 49 { .lomax = 2128, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 133 MHz */
33 { 0x0D34, 0x72 }, 50 { .lomax = 2416, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 151 MHz */
34 { 0x0B54, 0x9A }, 51 { .lomax = 2464, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 154 MHz */
35 { 0x0914, 0x91 }, 52 { .lomax = 2896, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 181 MHz */
36 { 0x07F4, 0x89 }, 53 { .lomax = 2960, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 185 MHz */
37 { 0x0774, 0xB9 }, 54 { .lomax = 3472, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 217 MHz */
38 { 0x067B, 0xB1 }, 55 { .lomax = 3904, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 244 MHz */
39 { 0x0634, 0xD9 }, 56 { .lomax = 4240, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 265 MHz */
40 { 0x05A4, 0xD8 }, // FM radio 57 { .lomax = 4832, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 302 MHz */
41 { 0x0494, 0xD0 }, 58 { .lomax = 5184, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 324 MHz */
42 { 0x03BC, 0xC8 }, 59 { .lomax = 5920, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 370 MHz */
43 { 0x0394, 0xF8 }, // 57250000 Hz 60 { .lomax = 7264, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 454 MHz */
44 { 0x0000, 0xF0 }, // 0 61 { .lomax = 7888, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 493 MHz */
62 { .lomax = 8480, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, /* 530 MHz */
63 { .lomax = 8864, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, /* 554 MHz */
64 { .lomax = 9664, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 604 MHz */
65 { .lomax = 11088, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 696 MHz */
66 { .lomax = 11840, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 740 MHz */
67 { .lomax = 13120, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, /* 820 MHz */
68 { .lomax = 13840, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, /* 865 MHz */
69 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */
45}; 70};
46 71
47static struct freq_entry div_table[] = { 72static void tda827x_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
48 { 0x1C34, 3 }, 73{
49 { 0x0D34, 2 }, 74 unsigned char tuner_reg[8];
50 { 0x067B, 1 }, 75 unsigned char reg2[2];
51 { 0x0000, 0 }, 76 u32 N;
52}; 77 int i;
78 struct tuner *t = i2c_get_clientdata(c);
79 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
53 80
54static struct freq_entry agc_table[] = { 81 if (t->mode == V4L2_TUNER_RADIO)
55 { 0x22B4, 0x8F }, 82 freq = freq / 1000;
56 { 0x0B54, 0x9F },
57 { 0x09A4, 0x8F },
58 { 0x0554, 0x9F },
59 { 0x0000, 0xBF },
60};
61 83
62static __u8 get_freq_entry( struct freq_entry* table, __u16 freq) 84 N = freq + ifc;
63{ 85 i = 0;
64 while(table->freq && table->freq > freq) 86 while (tda827x_analog[i].lomax < N) {
65 table++; 87 if(tda827x_analog[i + 1].lomax == 0)
66 return table->value; 88 break;
67} 89 i++;
90 }
91
92 N = N << tda827x_analog[i].spd;
93
94 tuner_reg[0] = 0;
95 tuner_reg[1] = (unsigned char)(N>>8);
96 tuner_reg[2] = (unsigned char) N;
97 tuner_reg[3] = 0x40;
98 tuner_reg[4] = 0x52 + (t->tda827x_lpsel << 5);
99 tuner_reg[5] = (tda827x_analog[i].spd << 6) + (tda827x_analog[i].div1p5 <<5) +
100 (tda827x_analog[i].bs <<3) + tda827x_analog[i].bp;
101 tuner_reg[6] = 0x8f + (tda827x_analog[i].gc3 << 4);
102 tuner_reg[7] = 0x8f;
103
104 msg.buf = tuner_reg;
105 msg.len = 8;
106 i2c_transfer(c->adapter, &msg, 1);
107
108 msg.buf= reg2;
109 msg.len = 2;
110 reg2[0] = 0x80;
111 reg2[1] = 0;
112 i2c_transfer(c->adapter, &msg, 1);
113
114 reg2[0] = 0x60;
115 reg2[1] = 0xbf;
116 i2c_transfer(c->adapter, &msg, 1);
117
118 reg2[0] = 0x30;
119 reg2[1] = tuner_reg[4] + 0x80;
120 i2c_transfer(c->adapter, &msg, 1);
121
122 msleep(1);
123 reg2[0] = 0x30;
124 reg2[1] = tuner_reg[4] + 4;
125 i2c_transfer(c->adapter, &msg, 1);
126
127 msleep(1);
128 reg2[0] = 0x30;
129 reg2[1] = tuner_reg[4];
130 i2c_transfer(c->adapter, &msg, 1);
68 131
69/* ---------------------------------------------------------------------- */ 132 msleep(550);
133 reg2[0] = 0x30;
134 reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_analog[i].cp ;
135 i2c_transfer(c->adapter, &msg, 1);
70 136
71static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; 137 reg2[0] = 0x60;
72static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; 138 reg2[1] = 0x3f;
73static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, 139 i2c_transfer(c->adapter, &msg, 1);
74 0xfC, 0x04, 0xA3, 0x3F,
75 0x2A, 0x04, 0xFF, 0x00,
76 0x00, 0x40 };
77static unsigned char i2c_set_VS[2] = { 0x30, 0x6F };
78static unsigned char i2c_set_GP01_CF[2] = { 0x20, 0x0B };
79static unsigned char i2c_tda8290_reset[2] = { 0x00, 0x00 };
80static unsigned char i2c_tda8290_standby[2] = { 0x00, 0x02 };
81static unsigned char i2c_gainset_off[2] = { 0x28, 0x14 };
82static unsigned char i2c_gainset_on[2] = { 0x28, 0x54 };
83static unsigned char i2c_agc3_00[2] = { 0x80, 0x00 };
84static unsigned char i2c_agc2_BF[2] = { 0x60, 0xBF };
85static unsigned char i2c_cb1_D0[2] = { 0x30, 0xD0 };
86static unsigned char i2c_cb1_D2[2] = { 0x30, 0xD2 };
87static unsigned char i2c_cb1_56[2] = { 0x30, 0x56 };
88static unsigned char i2c_cb1_52[2] = { 0x30, 0x52 };
89static unsigned char i2c_cb1_50[2] = { 0x30, 0x50 };
90static unsigned char i2c_agc2_7F[2] = { 0x60, 0x7F };
91static unsigned char i2c_agc3_08[2] = { 0x80, 0x08 };
92
93static struct i2c_msg i2c_msg_init[] = {
94 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_init_tda8275), i2c_init_tda8275 },
95 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge },
96 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_VS), i2c_set_VS },
97 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_set_GP01_CF), i2c_set_GP01_CF },
98};
99 140
100static struct i2c_msg i2c_msg_prolog[] = { 141 reg2[0] = 0x80;
101// { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_easy_mode), i2c_easy_mode }, 142 reg2[1] = 0x08; // Vsync en
102 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_off), i2c_gainset_off }, 143 i2c_transfer(c->adapter, &msg, 1);
103 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_reset), i2c_tda8290_reset }, 144}
104 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge },
105};
106 145
107static struct i2c_msg i2c_msg_config[] = { 146static void tda827x_agcf(struct i2c_client *c)
108// { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_set_freq), i2c_set_freq }, 147{
109 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_00), i2c_agc3_00 }, 148 struct tuner *t = i2c_get_clientdata(c);
110 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_BF), i2c_agc2_BF }, 149 unsigned char data[] = {0x80, 0x0c};
111 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D2), i2c_cb1_D2 }, 150 struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
112 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_56), i2c_cb1_56 }, 151 .flags = 0, .len = 2};
113 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_52), i2c_cb1_52 }, 152 i2c_transfer(c->adapter, &msg, 1);
114}; 153}
115 154
116static struct i2c_msg i2c_msg_epilog[] = { 155/* ---------------------------------------------------------------------- */
117 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_50), i2c_cb1_50 }, 156
118 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc2_7F), i2c_agc2_7F }, 157struct tda827xa_data {
119 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_agc3_08), i2c_agc3_08 }, 158 u32 lomax;
120 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, 159 u8 svco;
121 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_gainset_on), i2c_gainset_on }, 160 u8 spd;
161 u8 scr;
162 u8 sbs;
163 u8 gc3;
122}; 164};
123 165
124static struct i2c_msg i2c_msg_standby[] = { 166static struct tda827xa_data tda827xa_analog[] = {
125 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_enable_bridge), i2c_enable_bridge }, 167 { .lomax = 910, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, /* 56.875 MHz */
126 { I2C_ADDR_TDA8275, 0, ARRAY_SIZE(i2c_cb1_D0), i2c_cb1_D0 }, 168 { .lomax = 1076, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 67.25 MHz */
127 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_disable_bridge), i2c_disable_bridge }, 169 { .lomax = 1300, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 81.25 MHz */
128 { I2C_ADDR_TDA8290, 0, ARRAY_SIZE(i2c_tda8290_standby), i2c_tda8290_standby }, 170 { .lomax = 1560, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, /* 97.5 MHz */
171 { .lomax = 1820, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, /* 113.75 MHz */
172 { .lomax = 2152, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 134.5 MHz */
173 { .lomax = 2464, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 154 MHz */
174 { .lomax = 2600, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 162.5 MHz */
175 { .lomax = 2928, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, /* 183 MHz */
176 { .lomax = 3120, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, /* 195 MHz */
177 { .lomax = 3640, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3}, /* 227.5 MHz */
178 { .lomax = 4304, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3}, /* 269 MHz */
179 { .lomax = 5200, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, /* 325 MHz */
180 { .lomax = 6240, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 390 MHz */
181 { .lomax = 7280, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3}, /* 455 MHz */
182 { .lomax = 8320, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 520 MHz */
183 { .lomax = 8608, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, /* 538 MHz */
184 { .lomax = 8864, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, /* 554 MHz */
185 { .lomax = 9920, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 620 MHz */
186 { .lomax = 10400, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 650 MHz */
187 { .lomax = 11200, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 700 MHz */
188 { .lomax = 12480, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 780 MHz */
189 { .lomax = 13120, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, /* 820 MHz */
190 { .lomax = 13920, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, /* 870 MHz */
191 { .lomax = 14576, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, /* 911 MHz */
192 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */
129}; 193};
130 194
131static int tda8290_tune(struct i2c_client *c) 195static void tda827xa_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
132{ 196{
197 unsigned char tuner_reg[14];
198 unsigned char reg2[2];
199 u32 N;
200 int i;
133 struct tuner *t = i2c_get_clientdata(c); 201 struct tuner *t = i2c_get_clientdata(c);
134 struct i2c_msg easy_mode = 202 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags = 0};
135 { I2C_ADDR_TDA8290, 0, 2, t->i2c_easy_mode };
136 struct i2c_msg set_freq =
137 { I2C_ADDR_TDA8275, 0, 8, t->i2c_set_freq };
138 203
139 i2c_transfer(c->adapter, &easy_mode, 1); 204 if (t->mode == V4L2_TUNER_RADIO)
140 i2c_transfer(c->adapter, i2c_msg_prolog, ARRAY_SIZE(i2c_msg_prolog)); 205 freq = freq / 1000;
141 206
142 i2c_transfer(c->adapter, &set_freq, 1); 207 N = freq + ifc;
143 i2c_transfer(c->adapter, i2c_msg_config, ARRAY_SIZE(i2c_msg_config)); 208 i = 0;
209 while (tda827xa_analog[i].lomax < N) {
210 if(tda827xa_analog[i + 1].lomax == 0)
211 break;
212 i++;
213 }
214
215 N = N << tda827xa_analog[i].spd;
216
217 tuner_reg[0] = 0;
218 tuner_reg[1] = (unsigned char)(N>>8);
219 tuner_reg[2] = (unsigned char) N;
220 tuner_reg[3] = 0;
221 tuner_reg[4] = 0x16;
222 tuner_reg[5] = (tda827xa_analog[i].spd << 5) + (tda827xa_analog[i].svco << 3) +
223 tda827xa_analog[i].sbs;
224 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
225 tuner_reg[7] = 0x0c;
226 tuner_reg[8] = 4;
227 tuner_reg[9] = 0x20;
228 tuner_reg[10] = 0xff;
229 tuner_reg[11] = 0xe0;
230 tuner_reg[12] = 0;
231 tuner_reg[13] = 0x39 + (t->tda827x_lpsel << 1);
232
233 msg.buf = tuner_reg;
234 msg.len = 14;
235 i2c_transfer(c->adapter, &msg, 1);
236
237 msg.buf= reg2;
238 msg.len = 2;
239 reg2[0] = 0x60;
240 reg2[1] = 0x3c;
241 i2c_transfer(c->adapter, &msg, 1);
242
243 reg2[0] = 0xa0;
244 reg2[1] = 0xc0;
245 i2c_transfer(c->adapter, &msg, 1);
246
247 msleep(2);
248 reg2[0] = 0x30;
249 reg2[1] = 0x10 + tda827xa_analog[i].scr;
250 i2c_transfer(c->adapter, &msg, 1);
144 251
145 msleep(550); 252 msleep(550);
146 i2c_transfer(c->adapter, i2c_msg_epilog, ARRAY_SIZE(i2c_msg_epilog)); 253 reg2[0] = 0x50;
147 return 0; 254 reg2[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
255 i2c_transfer(c->adapter, &msg, 1);
256
257 reg2[0] = 0x80;
258 reg2[1] = 0x28;
259 i2c_transfer(c->adapter, &msg, 1);
260
261 reg2[0] = 0xb0;
262 reg2[1] = 0x01;
263 i2c_transfer(c->adapter, &msg, 1);
264
265 reg2[0] = 0xc0;
266 reg2[1] = 0x19 + (t->tda827x_lpsel << 1);
267 i2c_transfer(c->adapter, &msg, 1);
148} 268}
149 269
150static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq) 270static void tda827xa_agcf(struct i2c_client *c)
151{ 271{
152 u32 N; 272 struct tuner *t = i2c_get_clientdata(c);
273 unsigned char data[] = {0x80, 0x2c};
274 struct i2c_msg msg = {.addr = t->tda827x_addr, .buf = data,
275 .flags = 0, .len = 2};
276 i2c_transfer(c->adapter, &msg, 1);
277}
153 278
154 if (t->mode == V4L2_TUNER_RADIO) 279/*---------------------------------------------------------------------*/
155 freq = freq / 1000;
156 280
157 N = (((freq<<3)+ifc)&0x3fffc); 281static void tda8290_i2c_bridge(struct i2c_client *c, int close)
158 282{
159 N = N >> get_freq_entry(div_table, freq); 283 unsigned char enable[2] = { 0x21, 0xC0 };
160 t->i2c_set_freq[0] = 0; 284 unsigned char disable[2] = { 0x21, 0x80 };
161 t->i2c_set_freq[1] = (unsigned char)(N>>8); 285 unsigned char *msg;
162 t->i2c_set_freq[2] = (unsigned char) N; 286 if(close) {
163 t->i2c_set_freq[3] = 0x40; 287 msg = enable;
164 t->i2c_set_freq[4] = 0x52; 288 i2c_master_send(c, msg, 2);
165 t->i2c_set_freq[5] = get_freq_entry(band_table, freq); 289 /* let the bridge stabilize */
166 t->i2c_set_freq[6] = get_freq_entry(agc_table, freq); 290 msleep(20);
167 t->i2c_set_freq[7] = 0x8f; 291 } else {
292 msg = disable;
293 i2c_master_send(c, msg, 2);
294 }
168} 295}
169 296
297/*---------------------------------------------------------------------*/
298
299static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq)
300{
301 struct tuner *t = i2c_get_clientdata(c);
302 unsigned char soft_reset[] = { 0x00, 0x00 };
303 unsigned char easy_mode[] = { 0x01, t->tda8290_easy_mode };
304 unsigned char expert_mode[] = { 0x01, 0x80 };
305 unsigned char gainset_off[] = { 0x28, 0x14 };
306 unsigned char if_agc_spd[] = { 0x0f, 0x88 };
307 unsigned char adc_head_6[] = { 0x05, 0x04 };
308 unsigned char adc_head_9[] = { 0x05, 0x02 };
309 unsigned char adc_head_12[] = { 0x05, 0x01 };
310 unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
311 unsigned char pll_bw_low[] = { 0x0d, 0x27 };
312 unsigned char gainset_2[] = { 0x28, 0x64 };
313 unsigned char agc_rst_on[] = { 0x0e, 0x0b };
314 unsigned char agc_rst_off[] = { 0x0e, 0x09 };
315 unsigned char if_agc_set[] = { 0x0f, 0x81 };
316 unsigned char addr_adc_sat = 0x1a;
317 unsigned char addr_agc_stat = 0x1d;
318 unsigned char addr_pll_stat = 0x1b;
319 unsigned char adc_sat, agc_stat,
320 pll_stat;
321
322 i2c_master_send(c, easy_mode, 2);
323 i2c_master_send(c, soft_reset, 2);
324 msleep(1);
325
326 expert_mode[1] = t->tda8290_easy_mode + 0x80;
327 i2c_master_send(c, expert_mode, 2);
328 i2c_master_send(c, gainset_off, 2);
329 i2c_master_send(c, if_agc_spd, 2);
330 if (t->tda8290_easy_mode & 0x60)
331 i2c_master_send(c, adc_head_9, 2);
332 else
333 i2c_master_send(c, adc_head_6, 2);
334 i2c_master_send(c, pll_bw_nom, 2);
335
336 tda8290_i2c_bridge(c, 1);
337 if (t->tda827x_ver != 0)
338 tda827xa_tune(c, ifc, freq);
339 else
340 tda827x_tune(c, ifc, freq);
341 /* adjust headroom resp. gain */
342 i2c_master_send(c, &addr_adc_sat, 1);
343 i2c_master_recv(c, &adc_sat, 1);
344 i2c_master_send(c, &addr_agc_stat, 1);
345 i2c_master_recv(c, &agc_stat, 1);
346 i2c_master_send(c, &addr_pll_stat, 1);
347 i2c_master_recv(c, &pll_stat, 1);
348 if (pll_stat & 0x80)
349 tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
350 else
351 tuner_dbg("tda8290 not locked, no signal?\n");
352 if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
353 tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
354 agc_stat, adc_sat, pll_stat & 0x80);
355 i2c_master_send(c, gainset_2, 2);
356 msleep(100);
357 i2c_master_send(c, &addr_agc_stat, 1);
358 i2c_master_recv(c, &agc_stat, 1);
359 i2c_master_send(c, &addr_pll_stat, 1);
360 i2c_master_recv(c, &pll_stat, 1);
361 if ((agc_stat > 115) || !(pll_stat & 0x80)) {
362 tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
363 agc_stat, pll_stat & 0x80);
364 if (t->tda827x_ver != 0)
365 tda827xa_agcf(c);
366 else
367 tda827x_agcf(c);
368 msleep(100);
369 i2c_master_send(c, &addr_agc_stat, 1);
370 i2c_master_recv(c, &agc_stat, 1);
371 i2c_master_send(c, &addr_pll_stat, 1);
372 i2c_master_recv(c, &pll_stat, 1);
373 if((agc_stat > 115) || !(pll_stat & 0x80)) {
374 tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
375 i2c_master_send(c, adc_head_12, 2);
376 i2c_master_send(c, pll_bw_low, 2);
377 msleep(100);
378 }
379 }
380 }
381
382 /* l/ l' deadlock? */
383 if(t->tda8290_easy_mode & 0x60) {
384 i2c_master_send(c, &addr_adc_sat, 1);
385 i2c_master_recv(c, &adc_sat, 1);
386 i2c_master_send(c, &addr_pll_stat, 1);
387 i2c_master_recv(c, &pll_stat, 1);
388 if ((adc_sat > 20) || !(pll_stat & 0x80)) {
389 tuner_dbg("trying to resolve SECAM L deadlock\n");
390 i2c_master_send(c, agc_rst_on, 2);
391 msleep(40);
392 i2c_master_send(c, agc_rst_off, 2);
393 }
394 }
395
396 tda8290_i2c_bridge(c, 0);
397 i2c_master_send(c, if_agc_set, 2);
398 return 0;
399}
400
401
402/*---------------------------------------------------------------------*/
403
170#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) 404#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
171#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) 405#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
172#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) 406#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
@@ -174,20 +408,37 @@ static void set_frequency(struct tuner *t, u16 ifc, unsigned int freq)
174 408
175static void set_audio(struct tuner *t) 409static void set_audio(struct tuner *t)
176{ 410{
177 t->i2c_easy_mode[0] = 0x01; 411 char* mode;
178 412
179 if (t->std & V4L2_STD_MN) 413 t->tda827x_lpsel = 0;
180 t->i2c_easy_mode[1] = 0x01; 414 mode = "xx";
181 else if (t->std & V4L2_STD_B) 415 if (t->std & V4L2_STD_MN) {
182 t->i2c_easy_mode[1] = 0x02; 416 t->sgIF = 92;
183 else if (t->std & V4L2_STD_GH) 417 t->tda8290_easy_mode = 0x01;
184 t->i2c_easy_mode[1] = 0x04; 418 t->tda827x_lpsel = 1;
185 else if (t->std & V4L2_STD_PAL_I) 419 mode = "MN";
186 t->i2c_easy_mode[1] = 0x08; 420 } else if (t->std & V4L2_STD_B) {
187 else if (t->std & V4L2_STD_DK) 421 t->sgIF = 108;
188 t->i2c_easy_mode[1] = 0x10; 422 t->tda8290_easy_mode = 0x02;
189 else if (t->std & V4L2_STD_SECAM_L) 423 mode = "B";
190 t->i2c_easy_mode[1] = 0x20; 424 } else if (t->std & V4L2_STD_GH) {
425 t->sgIF = 124;
426 t->tda8290_easy_mode = 0x04;
427 mode = "GH";
428 } else if (t->std & V4L2_STD_PAL_I) {
429 t->sgIF = 124;
430 t->tda8290_easy_mode = 0x08;
431 mode = "I";
432 } else if (t->std & V4L2_STD_DK) {
433 t->sgIF = 124;
434 t->tda8290_easy_mode = 0x10;
435 mode = "DK";
436 } else if (t->std & V4L2_STD_SECAM_L) {
437 t->sgIF = 124;
438 t->tda8290_easy_mode = 0x20;
439 mode = "L";
440 }
441 tuner_dbg("setting tda8290 to system %s\n", mode);
191} 442}
192 443
193static void set_tv_freq(struct i2c_client *c, unsigned int freq) 444static void set_tv_freq(struct i2c_client *c, unsigned int freq)
@@ -195,15 +446,13 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
195 struct tuner *t = i2c_get_clientdata(c); 446 struct tuner *t = i2c_get_clientdata(c);
196 447
197 set_audio(t); 448 set_audio(t);
198 set_frequency(t, 864, freq); 449 tda8290_tune(c, t->sgIF, freq);
199 tda8290_tune(c);
200} 450}
201 451
202static void set_radio_freq(struct i2c_client *c, unsigned int freq) 452static void set_radio_freq(struct i2c_client *c, unsigned int freq)
203{ 453{
204 struct tuner *t = i2c_get_clientdata(c); 454 /* if frequency is 5.5 MHz */
205 set_frequency(t, 704, freq); 455 tda8290_tune(c, 88, freq);
206 tda8290_tune(c);
207} 456}
208 457
209static int has_signal(struct i2c_client *c) 458static int has_signal(struct i2c_client *c)
@@ -216,27 +465,145 @@ static int has_signal(struct i2c_client *c)
216 return (afc & 0x80)? 65535:0; 465 return (afc & 0x80)? 65535:0;
217} 466}
218 467
468/*---------------------------------------------------------------------*/
469
219static void standby(struct i2c_client *c) 470static void standby(struct i2c_client *c)
220{ 471{
221 i2c_transfer(c->adapter, i2c_msg_standby, ARRAY_SIZE(i2c_msg_standby)); 472 struct tuner *t = i2c_get_clientdata(c);
473 unsigned char cb1[] = { 0x30, 0xD0 };
474 unsigned char tda8290_standby[] = { 0x00, 0x02 };
475 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
476
477 tda8290_i2c_bridge(c, 1);
478 if (t->tda827x_ver != 0)
479 cb1[1] = 0x90;
480 i2c_transfer(c->adapter, &msg, 1);
481 tda8290_i2c_bridge(c, 0);
482 i2c_master_send(c, tda8290_standby, 2);
222} 483}
223 484
224int tda8290_init(struct i2c_client *c) 485
486static void tda8290_init_if(struct i2c_client *c)
487{
488 unsigned char set_VS[] = { 0x30, 0x6F };
489 unsigned char set_GP01_CF[] = { 0x20, 0x0B };
490
491 i2c_master_send(c, set_VS, 2);
492 i2c_master_send(c, set_GP01_CF, 2);
493}
494
495static void tda8290_init_tuner(struct i2c_client *c)
225{ 496{
226 struct tuner *t = i2c_get_clientdata(c); 497 struct tuner *t = i2c_get_clientdata(c);
498 unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
499 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
500 unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
501 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
502 struct i2c_msg msg = {.addr = t->tda827x_addr, .flags=0,
503 .buf=tda8275_init, .len = 14};
504 if (t->tda827x_ver != 0)
505 msg.buf = tda8275a_init;
506
507 tda8290_i2c_bridge(c, 1);
508 i2c_transfer(c->adapter, &msg, 1);
509 tda8290_i2c_bridge(c, 0);
510}
227 511
228 strlcpy(c->name, "tda8290+75", sizeof(c->name)); 512/*---------------------------------------------------------------------*/
513
514int tda8290_init(struct i2c_client *c)
515{
516 struct tuner *t = i2c_get_clientdata(c);
517 u8 data;
518 int i, ret, tuners_found;
519 u32 tuner_addrs;
520 struct i2c_msg msg = {.flags=I2C_M_RD, .buf=&data, .len = 1};
521
522 tda8290_i2c_bridge(c, 1);
523 /* probe for tuner chip */
524 tuners_found = 0;
525 tuner_addrs = 0;
526 for (i=0x60; i<= 0x63; i++) {
527 msg.addr = i;
528 ret = i2c_transfer(c->adapter, &msg, 1);
529 if (ret == 1) {
530 tuners_found++;
531 tuner_addrs = (tuner_addrs << 8) + i;
532 }
533 }
534 /* if there is more than one tuner, we expect the right one is
535 behind the bridge and we choose the highest address that doesn't
536 give a response now
537 */
538 tda8290_i2c_bridge(c, 0);
539 if(tuners_found > 1)
540 for (i = 0; i < tuners_found; i++) {
541 msg.addr = tuner_addrs & 0xff;
542 ret = i2c_transfer(c->adapter, &msg, 1);
543 if(ret == 1)
544 tuner_addrs = tuner_addrs >> 8;
545 else
546 break;
547 }
548 if (tuner_addrs == 0) {
549 tuner_addrs = 0x61;
550 tuner_info ("could not clearly identify tuner address, defaulting to %x\n",
551 tuner_addrs);
552 } else {
553 tuner_addrs = tuner_addrs & 0xff;
554 tuner_info ("setting tuner address to %x\n", tuner_addrs);
555 }
556 t->tda827x_addr = tuner_addrs;
557 msg.addr = tuner_addrs;
558
559 tda8290_i2c_bridge(c, 1);
560 ret = i2c_transfer(c->adapter, &msg, 1);
561 if( ret != 1)
562 tuner_warn ("TDA827x access failed!\n");
563 if ((data & 0x3c) == 0) {
564 strlcpy(c->name, "tda8290+75", sizeof(c->name));
565 t->tda827x_ver = 0;
566 } else {
567 strlcpy(c->name, "tda8290+75a", sizeof(c->name));
568 t->tda827x_ver = 2;
569 }
229 tuner_info("tuner: type set to %s\n", c->name); 570 tuner_info("tuner: type set to %s\n", c->name);
571
230 t->tv_freq = set_tv_freq; 572 t->tv_freq = set_tv_freq;
231 t->radio_freq = set_radio_freq; 573 t->radio_freq = set_radio_freq;
232 t->has_signal = has_signal; 574 t->has_signal = has_signal;
233 t->standby = standby; 575 t->standby = standby;
576 t->tda827x_lpsel = 0;
234 577
235 i2c_master_send(c, i2c_enable_bridge, ARRAY_SIZE(i2c_enable_bridge)); 578 tda8290_init_tuner(c);
236 i2c_transfer(c->adapter, i2c_msg_init, ARRAY_SIZE(i2c_msg_init)); 579 tda8290_init_if(c);
237 return 0; 580 return 0;
238} 581}
239 582
583int tda8290_probe(struct i2c_client *c)
584{
585 unsigned char soft_reset[] = { 0x00, 0x00 };
586 unsigned char easy_mode_b[] = { 0x01, 0x02 };
587 unsigned char easy_mode_g[] = { 0x01, 0x04 };
588 unsigned char addr_dto_lsb = 0x07;
589 unsigned char data;
590
591 i2c_master_send(c, easy_mode_b, 2);
592 i2c_master_send(c, soft_reset, 2);
593 i2c_master_send(c, &addr_dto_lsb, 1);
594 i2c_master_recv(c, &data, 1);
595 if (data == 0) {
596 i2c_master_send(c, easy_mode_g, 2);
597 i2c_master_send(c, soft_reset, 2);
598 i2c_master_send(c, &addr_dto_lsb, 1);
599 i2c_master_recv(c, &data, 1);
600 if (data == 0x7b) {
601 return 0;
602 }
603 }
604 return -1;
605}
606
240/* 607/*
241 * Overrides for Emacs so that we follow Linus's tabbing style. 608 * Overrides for Emacs so that we follow Linus's tabbing style.
242 * --------------------------------------------------------------------------- 609 * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 7e3dcdb262b0..a5e37dc91f39 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -32,7 +32,6 @@
32 32
33#include "bttv.h" 33#include "bttv.h"
34#include <media/audiochip.h> 34#include <media/audiochip.h>
35#include <media/id.h>
36 35
37static int debug; /* insmod parameter */ 36static int debug; /* insmod parameter */
38module_param(debug, int, S_IRUGO | S_IWUSR); 37module_param(debug, int, S_IRUGO | S_IWUSR);
@@ -126,20 +125,20 @@ static int tda9875_write(struct i2c_client *client, int subaddr, unsigned char v
126 125
127static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg) 126static int i2c_read_register(struct i2c_adapter *adap, int addr, int reg)
128{ 127{
129 unsigned char write[1]; 128 unsigned char write[1];
130 unsigned char read[1]; 129 unsigned char read[1];
131 struct i2c_msg msgs[2] = { 130 struct i2c_msg msgs[2] = {
132 { addr, 0, 1, write }, 131 { addr, 0, 1, write },
133 { addr, I2C_M_RD, 1, read } 132 { addr, I2C_M_RD, 1, read }
134 }; 133 };
135 write[0] = reg; 134 write[0] = reg;
136 135
137 if (2 != i2c_transfer(adap,msgs,2)) { 136 if (2 != i2c_transfer(adap,msgs,2)) {
138 printk(KERN_WARNING "tda9875: I/O error (read2)\n"); 137 printk(KERN_WARNING "tda9875: I/O error (read2)\n");
139 return -1; 138 return -1;
140 } 139 }
141 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]); 140 dprintk("tda9875: chip_read2: reg%d=0x%x\n",reg,read[0]);
142 return read[0]; 141 return read[0];
143} 142}
144 143
145static void tda9875_set(struct i2c_client *client) 144static void tda9875_set(struct i2c_client *client)
@@ -184,7 +183,7 @@ static void do_tda9875_init(struct i2c_client *client)
184 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/ 183 tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/
185 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/ 184 tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/
186 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/ 185 tda9875_write(client, TDA9875_LOSR, 0x00 ); /* line out (in:mono)*/
187 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */ 186 tda9875_write(client, TDA9875_AER, 0x00 ); /*06 Effect (AVL+PSEUDO) */
188 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */ 187 tda9875_write(client, TDA9875_MCS, 0x44 ); /* Main ch select (DAC) */
189 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */ 188 tda9875_write(client, TDA9875_MVL, 0x03 ); /* Vol Main left 10dB */
190 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/ 189 tda9875_write(client, TDA9875_MVR, 0x03 ); /* Vol Main right 10dB*/
@@ -200,7 +199,7 @@ static void do_tda9875_init(struct i2c_client *client)
200 199
201 t->mode=AUDIO_UNMUTE; 200 t->mode=AUDIO_UNMUTE;
202 t->lvol=t->rvol =0; /* 0dB */ 201 t->lvol=t->rvol =0; /* 0dB */
203 t->bass=0; /* 0dB */ 202 t->bass=0; /* 0dB */
204 t->treble=0; /* 0dB */ 203 t->treble=0; /* 0dB */
205 tda9875_set(client); 204 tda9875_set(client);
206 205
@@ -239,9 +238,9 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind)
239 memset(t,0,sizeof *t); 238 memset(t,0,sizeof *t);
240 239
241 client = &t->c; 240 client = &t->c;
242 memcpy(client,&client_template,sizeof(struct i2c_client)); 241 memcpy(client,&client_template,sizeof(struct i2c_client));
243 client->adapter = adap; 242 client->adapter = adap;
244 client->addr = addr; 243 client->addr = addr;
245 i2c_set_clientdata(client, t); 244 i2c_set_clientdata(client, t);
246 245
247 if(!tda9875_checkit(adap,addr)) { 246 if(!tda9875_checkit(adap,addr)) {
@@ -287,7 +286,7 @@ static int tda9875_command(struct i2c_client *client,
287 dprintk("In tda9875_command...\n"); 286 dprintk("In tda9875_command...\n");
288 287
289 switch (cmd) { 288 switch (cmd) {
290 /* --- v4l ioctls --- */ 289 /* --- v4l ioctls --- */
291 /* take care: bttv does userspace copying, we'll get a 290 /* take care: bttv does userspace copying, we'll get a
292 kernel pointer here... */ 291 kernel pointer here... */
293 case VIDIOCGAUDIO: 292 case VIDIOCGAUDIO:
@@ -355,7 +354,7 @@ static int tda9875_command(struct i2c_client *client,
355//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble); 354//printk("tda9875 bal:%04x vol:%04x bass:%04x treble:%04x\n",va->balance,va->volume,va->bass,va->treble);
356 355
357 356
358 tda9875_set(client); 357 tda9875_set(client);
359 358
360 break; 359 break;
361 360
@@ -374,18 +373,18 @@ static int tda9875_command(struct i2c_client *client,
374 373
375static struct i2c_driver driver = { 374static struct i2c_driver driver = {
376 .owner = THIS_MODULE, 375 .owner = THIS_MODULE,
377 .name = "i2c tda9875 driver", 376 .name = "i2c tda9875 driver",
378 .id = I2C_DRIVERID_TDA9875, 377 .id = I2C_DRIVERID_TDA9875,
379 .flags = I2C_DF_NOTIFY, 378 .flags = I2C_DF_NOTIFY,
380 .attach_adapter = tda9875_probe, 379 .attach_adapter = tda9875_probe,
381 .detach_client = tda9875_detach, 380 .detach_client = tda9875_detach,
382 .command = tda9875_command, 381 .command = tda9875_command,
383}; 382};
384 383
385static struct i2c_client client_template = 384static struct i2c_client client_template =
386{ 385{
387 .name = "tda9875", 386 .name = "tda9875",
388 .driver = &driver, 387 .driver = &driver,
389}; 388};
390 389
391static int __init tda9875_init(void) 390static int __init tda9875_init(void)
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 94053f149ddf..4249127c0a1d 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -11,7 +11,6 @@
11 11
12#include <media/audiochip.h> 12#include <media/audiochip.h>
13#include <media/tuner.h> 13#include <media/tuner.h>
14#include <media/id.h>
15 14
16/* Chips: 15/* Chips:
17 TDA9885 (PAL, NTSC) 16 TDA9885 (PAL, NTSC)
@@ -44,8 +43,13 @@ MODULE_LICENSE("GPL");
44/* ---------------------------------------------------------------------- */ 43/* ---------------------------------------------------------------------- */
45 44
46#define UNSET (-1U) 45#define UNSET (-1U)
47#define PREFIX "tda9885/6/7: " 46#define tda9887_info(fmt, arg...) do {\
48#define dprintk if (debug) printk 47 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
48 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
49#define tda9887_dbg(fmt, arg...) do {\
50 if (debug) \
51 printk(KERN_INFO "%s %d-%04x: " fmt, t->client.name, \
52 i2c_adapter_id(t->client.adapter), t->client.addr , ##arg); } while (0)
49 53
50struct tda9887 { 54struct tda9887 {
51 struct i2c_client client; 55 struct i2c_client client;
@@ -55,6 +59,7 @@ struct tda9887 {
55 unsigned int pinnacle_id; 59 unsigned int pinnacle_id;
56 unsigned int using_v4l2; 60 unsigned int using_v4l2;
57 unsigned int radio_mode; 61 unsigned int radio_mode;
62 unsigned char data[4];
58}; 63};
59 64
60struct tvnorm { 65struct tvnorm {
@@ -180,7 +185,8 @@ static struct tvnorm tvnorms[] = {
180 .name = "SECAM-L", 185 .name = "SECAM-L",
181 .b = ( cPositiveAmTV | 186 .b = ( cPositiveAmTV |
182 cQSS ), 187 cQSS ),
183 .e = ( cAudioIF_6_5 | 188 .e = ( cGating_36 |
189 cAudioIF_6_5 |
184 cVideoIF_38_90 ), 190 cVideoIF_38_90 ),
185 },{ 191 },{
186 .std = V4L2_STD_SECAM_DK, 192 .std = V4L2_STD_SECAM_DK,
@@ -236,7 +242,7 @@ static struct tvnorm radio_mono = {
236 242
237/* ---------------------------------------------------------------------- */ 243/* ---------------------------------------------------------------------- */
238 244
239static void dump_read_message(unsigned char *buf) 245static void dump_read_message(struct tda9887 *t, unsigned char *buf)
240{ 246{
241 static char *afc[16] = { 247 static char *afc[16] = {
242 "- 12.5 kHz", 248 "- 12.5 kHz",
@@ -256,15 +262,15 @@ static void dump_read_message(unsigned char *buf)
256 "+ 37.5 kHz", 262 "+ 37.5 kHz",
257 "+ 12.5 kHz", 263 "+ 12.5 kHz",
258 }; 264 };
259 printk(PREFIX "read: 0x%2x\n", buf[0]); 265 tda9887_info("read: 0x%2x\n", buf[0]);
260 printk(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no"); 266 tda9887_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
261 printk(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]); 267 tda9887_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
262 printk(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low"); 268 tda9887_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
263 printk(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out"); 269 tda9887_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
264 printk(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low"); 270 tda9887_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
265} 271}
266 272
267static void dump_write_message(unsigned char *buf) 273static void dump_write_message(struct tda9887 *t, unsigned char *buf)
268{ 274{
269 static char *sound[4] = { 275 static char *sound[4] = {
270 "AM/TV", 276 "AM/TV",
@@ -304,58 +310,58 @@ static void dump_write_message(unsigned char *buf)
304 "44 MHz", 310 "44 MHz",
305 }; 311 };
306 312
307 printk(PREFIX "write: byte B 0x%02x\n",buf[1]); 313 tda9887_info("write: byte B 0x%02x\n",buf[1]);
308 printk(" B0 video mode : %s\n", 314 tda9887_info(" B0 video mode : %s\n",
309 (buf[1] & 0x01) ? "video trap" : "sound trap"); 315 (buf[1] & 0x01) ? "video trap" : "sound trap");
310 printk(" B1 auto mute fm : %s\n", 316 tda9887_info(" B1 auto mute fm : %s\n",
311 (buf[1] & 0x02) ? "yes" : "no"); 317 (buf[1] & 0x02) ? "yes" : "no");
312 printk(" B2 carrier mode : %s\n", 318 tda9887_info(" B2 carrier mode : %s\n",
313 (buf[1] & 0x04) ? "QSS" : "Intercarrier"); 319 (buf[1] & 0x04) ? "QSS" : "Intercarrier");
314 printk(" B3-4 tv sound/radio : %s\n", 320 tda9887_info(" B3-4 tv sound/radio : %s\n",
315 sound[(buf[1] & 0x18) >> 3]); 321 sound[(buf[1] & 0x18) >> 3]);
316 printk(" B5 force mute audio: %s\n", 322 tda9887_info(" B5 force mute audio: %s\n",
317 (buf[1] & 0x20) ? "yes" : "no"); 323 (buf[1] & 0x20) ? "yes" : "no");
318 printk(" B6 output port 1 : %s\n", 324 tda9887_info(" B6 output port 1 : %s\n",
319 (buf[1] & 0x40) ? "high (inactive)" : "low (active)"); 325 (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
320 printk(" B7 output port 2 : %s\n", 326 tda9887_info(" B7 output port 2 : %s\n",
321 (buf[1] & 0x80) ? "high (inactive)" : "low (active)"); 327 (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
322 328
323 printk(PREFIX "write: byte C 0x%02x\n",buf[2]); 329 tda9887_info("write: byte C 0x%02x\n",buf[2]);
324 printk(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]); 330 tda9887_info(" C0-4 top adjustment : %s dB\n", adjust[buf[2] & 0x1f]);
325 printk(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]); 331 tda9887_info(" C5-6 de-emphasis : %s\n", deemph[(buf[2] & 0x60) >> 5]);
326 printk(" C7 audio gain : %s\n", 332 tda9887_info(" C7 audio gain : %s\n",
327 (buf[2] & 0x80) ? "-6" : "0"); 333 (buf[2] & 0x80) ? "-6" : "0");
328 334
329 printk(PREFIX "write: byte E 0x%02x\n",buf[3]); 335 tda9887_info("write: byte E 0x%02x\n",buf[3]);
330 printk(" E0-1 sound carrier : %s\n", 336 tda9887_info(" E0-1 sound carrier : %s\n",
331 carrier[(buf[3] & 0x03)]); 337 carrier[(buf[3] & 0x03)]);
332 printk(" E6 l pll ganting : %s\n", 338 tda9887_info(" E6 l pll gating : %s\n",
333 (buf[3] & 0x40) ? "36" : "13"); 339 (buf[3] & 0x40) ? "36" : "13");
334 340
335 if (buf[1] & 0x08) { 341 if (buf[1] & 0x08) {
336 /* radio */ 342 /* radio */
337 printk(" E2-4 video if : %s\n", 343 tda9887_info(" E2-4 video if : %s\n",
338 rif[(buf[3] & 0x0c) >> 2]); 344 rif[(buf[3] & 0x0c) >> 2]);
339 printk(" E7 vif agc output : %s\n", 345 tda9887_info(" E7 vif agc output : %s\n",
340 (buf[3] & 0x80) 346 (buf[3] & 0x80)
341 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio") 347 ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
342 : "fm radio carrier afc"); 348 : "fm radio carrier afc");
343 } else { 349 } else {
344 /* video */ 350 /* video */
345 printk(" E2-4 video if : %s\n", 351 tda9887_info(" E2-4 video if : %s\n",
346 vif[(buf[3] & 0x1c) >> 2]); 352 vif[(buf[3] & 0x1c) >> 2]);
347 printk(" E5 tuner gain : %s\n", 353 tda9887_info(" E5 tuner gain : %s\n",
348 (buf[3] & 0x80) 354 (buf[3] & 0x80)
349 ? ((buf[3] & 0x20) ? "external" : "normal") 355 ? ((buf[3] & 0x20) ? "external" : "normal")
350 : ((buf[3] & 0x20) ? "minimum" : "normal")); 356 : ((buf[3] & 0x20) ? "minimum" : "normal"));
351 printk(" E7 vif agc output : %s\n", 357 tda9887_info(" E7 vif agc output : %s\n",
352 (buf[3] & 0x80) 358 (buf[3] & 0x80)
353 ? ((buf[3] & 0x20) 359 ? ((buf[3] & 0x20)
354 ? "pin3 port, pin22 vif agc out" 360 ? "pin3 port, pin22 vif agc out"
355 : "pin22 port, pin3 vif acg ext in") 361 : "pin22 port, pin3 vif acg ext in")
356 : "pin3+pin22 port"); 362 : "pin3+pin22 port");
357 } 363 }
358 printk("--\n"); 364 tda9887_info("--\n");
359} 365}
360 366
361/* ---------------------------------------------------------------------- */ 367/* ---------------------------------------------------------------------- */
@@ -379,11 +385,11 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
379 } 385 }
380 } 386 }
381 if (NULL == norm) { 387 if (NULL == norm) {
382 dprintk(PREFIX "Unsupported tvnorm entry - audio muted\n"); 388 tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
383 return -1; 389 return -1;
384 } 390 }
385 391
386 dprintk(PREFIX "configure for: %s\n",norm->name); 392 tda9887_dbg("configure for: %s\n",norm->name);
387 buf[1] = norm->b; 393 buf[1] = norm->b;
388 buf[2] = norm->c; 394 buf[2] = norm->c;
389 buf[3] = norm->e; 395 buf[3] = norm->e;
@@ -458,6 +464,8 @@ static int tda9887_set_config(struct tda9887 *t, char *buf)
458 break; 464 break;
459 } 465 }
460 } 466 }
467 if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
468 buf[1] &= ~cQSS;
461 return 0; 469 return 0;
462} 470}
463 471
@@ -475,11 +483,11 @@ static int tda9887_set_pinnacle(struct tda9887 *t, char *buf)
475 } 483 }
476 } 484 }
477 if (t->std & V4L2_STD_525_60) { 485 if (t->std & V4L2_STD_525_60) {
478 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { 486 if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) {
479 bCarrierMode = cIntercarrier; 487 bCarrierMode = cIntercarrier;
480 } else { 488 } else {
481 bCarrierMode = cQSS; 489 bCarrierMode = cQSS;
482 } 490 }
483 } 491 }
484 492
485 if (bCarrierMode != UNSET) { 493 if (bCarrierMode != UNSET) {
@@ -505,26 +513,26 @@ static int tda9887_fixup_std(struct tda9887 *t)
505 case 'B': 513 case 'B':
506 case 'g': 514 case 'g':
507 case 'G': 515 case 'G':
508 dprintk(PREFIX "insmod fixup: PAL => PAL-BG\n"); 516 tda9887_dbg("insmod fixup: PAL => PAL-BG\n");
509 t->std = V4L2_STD_PAL_BG; 517 t->std = V4L2_STD_PAL_BG;
510 break; 518 break;
511 case 'i': 519 case 'i':
512 case 'I': 520 case 'I':
513 dprintk(PREFIX "insmod fixup: PAL => PAL-I\n"); 521 tda9887_dbg("insmod fixup: PAL => PAL-I\n");
514 t->std = V4L2_STD_PAL_I; 522 t->std = V4L2_STD_PAL_I;
515 break; 523 break;
516 case 'd': 524 case 'd':
517 case 'D': 525 case 'D':
518 case 'k': 526 case 'k':
519 case 'K': 527 case 'K':
520 dprintk(PREFIX "insmod fixup: PAL => PAL-DK\n"); 528 tda9887_dbg("insmod fixup: PAL => PAL-DK\n");
521 t->std = V4L2_STD_PAL_DK; 529 t->std = V4L2_STD_PAL_DK;
522 break; 530 break;
523 case '-': 531 case '-':
524 /* default parameter, do nothing */ 532 /* default parameter, do nothing */
525 break; 533 break;
526 default: 534 default:
527 printk(PREFIX "pal= argument not recognised\n"); 535 tda9887_info("pal= argument not recognised\n");
528 break; 536 break;
529 } 537 }
530 } 538 }
@@ -534,19 +542,19 @@ static int tda9887_fixup_std(struct tda9887 *t)
534 case 'D': 542 case 'D':
535 case 'k': 543 case 'k':
536 case 'K': 544 case 'K':
537 dprintk(PREFIX "insmod fixup: SECAM => SECAM-DK\n"); 545 tda9887_dbg("insmod fixup: SECAM => SECAM-DK\n");
538 t->std = V4L2_STD_SECAM_DK; 546 t->std = V4L2_STD_SECAM_DK;
539 break; 547 break;
540 case 'l': 548 case 'l':
541 case 'L': 549 case 'L':
542 dprintk(PREFIX "insmod fixup: SECAM => SECAM-L\n"); 550 tda9887_dbg("insmod fixup: SECAM => SECAM-L\n");
543 t->std = V4L2_STD_SECAM_L; 551 t->std = V4L2_STD_SECAM_L;
544 break; 552 break;
545 case '-': 553 case '-':
546 /* default parameter, do nothing */ 554 /* default parameter, do nothing */
547 break; 555 break;
548 default: 556 default:
549 printk(PREFIX "secam= argument not recognised\n"); 557 tda9887_info("secam= argument not recognised\n");
550 break; 558 break;
551 } 559 }
552 } 560 }
@@ -559,41 +567,40 @@ static int tda9887_status(struct tda9887 *t)
559 int rc; 567 int rc;
560 568
561 memset(buf,0,sizeof(buf)); 569 memset(buf,0,sizeof(buf));
562 if (1 != (rc = i2c_master_recv(&t->client,buf,1))) 570 if (1 != (rc = i2c_master_recv(&t->client,buf,1)))
563 printk(PREFIX "i2c i/o error: rc == %d (should be 1)\n",rc); 571 tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
564 dump_read_message(buf); 572 dump_read_message(t, buf);
565 return 0; 573 return 0;
566} 574}
567 575
568static int tda9887_configure(struct tda9887 *t) 576static int tda9887_configure(struct tda9887 *t)
569{ 577{
570 unsigned char buf[4];
571 int rc; 578 int rc;
572 579
573 memset(buf,0,sizeof(buf)); 580 memset(t->data,0,sizeof(t->data));
574 tda9887_set_tvnorm(t,buf); 581 tda9887_set_tvnorm(t,t->data);
575 582
576 buf[1] |= cOutputPort1Inactive; 583 t->data[1] |= cOutputPort1Inactive;
577 buf[1] |= cOutputPort2Inactive; 584 t->data[1] |= cOutputPort2Inactive;
578 585
579 if (UNSET != t->pinnacle_id) { 586 if (UNSET != t->pinnacle_id) {
580 tda9887_set_pinnacle(t,buf); 587 tda9887_set_pinnacle(t,t->data);
581 } 588 }
582 tda9887_set_config(t,buf); 589 tda9887_set_config(t,t->data);
583 tda9887_set_insmod(t,buf); 590 tda9887_set_insmod(t,t->data);
584 591
585 if (t->mode == T_STANDBY) { 592 if (t->mode == T_STANDBY) {
586 buf[1] |= cForcedMuteAudioON; 593 t->data[1] |= cForcedMuteAudioON;
587 } 594 }
588 595
589 596
590 dprintk(PREFIX "writing: b=0x%02x c=0x%02x e=0x%02x\n", 597 tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
591 buf[1],buf[2],buf[3]); 598 t->data[1],t->data[2],t->data[3]);
592 if (debug > 1) 599 if (debug > 1)
593 dump_write_message(buf); 600 dump_write_message(t, t->data);
594 601
595 if (4 != (rc = i2c_master_send(&t->client,buf,4))) 602 if (4 != (rc = i2c_master_send(&t->client,t->data,4)))
596 printk(PREFIX "i2c i/o error: rc == %d (should be 4)\n",rc); 603 tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
597 604
598 if (debug > 2) { 605 if (debug > 2) {
599 msleep_interruptible(1000); 606 msleep_interruptible(1000);
@@ -608,13 +615,11 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
608{ 615{
609 struct tda9887 *t; 616 struct tda9887 *t;
610 617
611 client_template.adapter = adap; 618 client_template.adapter = adap;
612 client_template.addr = addr; 619 client_template.addr = addr;
613
614 printk(PREFIX "chip found @ 0x%x\n", addr<<1);
615 620
616 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) 621 if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
617 return -ENOMEM; 622 return -ENOMEM;
618 memset(t,0,sizeof(*t)); 623 memset(t,0,sizeof(*t));
619 624
620 t->client = client_template; 625 t->client = client_template;
@@ -622,6 +627,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
622 t->pinnacle_id = UNSET; 627 t->pinnacle_id = UNSET;
623 t->radio_mode = V4L2_TUNER_MODE_STEREO; 628 t->radio_mode = V4L2_TUNER_MODE_STEREO;
624 629
630 tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name);
631
625 i2c_set_clientdata(&t->client, t); 632 i2c_set_clientdata(&t->client, t);
626 i2c_attach_client(&t->client); 633 i2c_attach_client(&t->client);
627 634
@@ -655,18 +662,18 @@ static int tda9887_detach(struct i2c_client *client)
655} 662}
656 663
657#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \ 664#define SWITCH_V4L2 if (!t->using_v4l2 && debug) \
658 printk(PREFIX "switching to v4l2\n"); \ 665 tda9887_info("switching to v4l2\n"); \
659 t->using_v4l2 = 1; 666 t->using_v4l2 = 1;
660#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \ 667#define CHECK_V4L2 if (t->using_v4l2) { if (debug) \
661 printk(PREFIX "ignore v4l1 call\n"); \ 668 tda9887_info("ignore v4l1 call\n"); \
662 return 0; } 669 return 0; }
663 670
664static int 671static int
665tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) 672tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
666{ 673{
667 struct tda9887 *t = i2c_get_clientdata(client); 674 struct tda9887 *t = i2c_get_clientdata(client);
668 675
669 switch (cmd) { 676 switch (cmd) {
670 677
671 /* --- configuration --- */ 678 /* --- configuration --- */
672 case AUDC_SET_RADIO: 679 case AUDC_SET_RADIO:
@@ -777,6 +784,11 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
777 } 784 }
778 break; 785 break;
779 } 786 }
787 case VIDIOC_LOG_STATUS:
788 {
789 tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]);
790 break;
791 }
780 default: 792 default:
781 /* nothing */ 793 /* nothing */
782 break; 794 break;
@@ -786,7 +798,10 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
786 798
787static int tda9887_suspend(struct device * dev, pm_message_t state) 799static int tda9887_suspend(struct device * dev, pm_message_t state)
788{ 800{
789 dprintk("tda9887: suspend\n"); 801 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
802 struct tda9887 *t = i2c_get_clientdata(c);
803
804 tda9887_dbg("suspend\n");
790 return 0; 805 return 0;
791} 806}
792 807
@@ -795,7 +810,7 @@ static int tda9887_resume(struct device * dev)
795 struct i2c_client *c = container_of(dev, struct i2c_client, dev); 810 struct i2c_client *c = container_of(dev, struct i2c_client, dev);
796 struct tda9887 *t = i2c_get_clientdata(c); 811 struct tda9887 *t = i2c_get_clientdata(c);
797 812
798 dprintk("tda9887: resume\n"); 813 tda9887_dbg("resume\n");
799 tda9887_configure(t); 814 tda9887_configure(t);
800 return 0; 815 return 0;
801} 816}
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index 38bf50943798..a9375ef05de1 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -117,10 +117,10 @@
117#define TEA5767_RESERVED_MASK 0xff 117#define TEA5767_RESERVED_MASK 0xff
118 118
119enum tea5767_xtal_freq { 119enum tea5767_xtal_freq {
120 TEA5767_LOW_LO_32768 = 0, 120 TEA5767_LOW_LO_32768 = 0,
121 TEA5767_HIGH_LO_32768 = 1, 121 TEA5767_HIGH_LO_32768 = 1,
122 TEA5767_LOW_LO_13MHz = 2, 122 TEA5767_LOW_LO_13MHz = 2,
123 TEA5767_HIGH_LO_13MHz = 3, 123 TEA5767_HIGH_LO_13MHz = 3,
124}; 124};
125 125
126 126
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index ad85bef1c3d5..73c4041c35d7 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -28,7 +28,7 @@
28 28
29/* standard i2c insmod options */ 29/* standard i2c insmod options */
30static unsigned short normal_i2c[] = { 30static unsigned short normal_i2c[] = {
31 0x4b, /* tda8290 */ 31 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
32 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 32 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
33 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 33 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
34 I2C_CLIENT_END 34 I2C_CLIENT_END
@@ -189,6 +189,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
189 i2c_master_send(c, buffer, 4); 189 i2c_master_send(c, buffer, 4);
190 default_tuner_init(c); 190 default_tuner_init(c);
191 break; 191 break;
192 case TUNER_PHILIPS_TD1316:
193 buffer[0] = 0x0b;
194 buffer[1] = 0xdc;
195 buffer[2] = 0x86;
196 buffer[3] = 0xa4;
197 i2c_master_send(c,buffer,4);
198 default_tuner_init(c);
192 default: 199 default:
193 default_tuner_init(c); 200 default_tuner_init(c);
194 break; 201 break;
@@ -215,9 +222,9 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
215{ 222{
216 struct tuner *t = i2c_get_clientdata(c); 223 struct tuner *t = i2c_get_clientdata(c);
217 224
218 if ((tun_setup->addr == ADDR_UNSET && 225 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET &&
219 (t->mode_mask & tun_setup->mode_mask)) || 226 (t->mode_mask & tun_setup->mode_mask)) ||
220 tun_setup->addr == c->addr) { 227 tun_setup->addr == c->addr)) {
221 set_type(c, tun_setup->type, tun_setup->mode_mask); 228 set_type(c, tun_setup->type, tun_setup->mode_mask);
222 } 229 }
223} 230}
@@ -341,23 +348,33 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
341 t->audmode = V4L2_TUNER_MODE_STEREO; 348 t->audmode = V4L2_TUNER_MODE_STEREO;
342 t->mode_mask = T_UNINITIALIZED; 349 t->mode_mask = T_UNINITIALIZED;
343 350
344
345 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
346
347 if (show_i2c) { 351 if (show_i2c) {
348 unsigned char buffer[16]; 352 unsigned char buffer[16];
349 int i,rc; 353 int i,rc;
350 354
351 memset(buffer, 0, sizeof(buffer)); 355 memset(buffer, 0, sizeof(buffer));
352 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer)); 356 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer));
353 printk("tuner-%04x I2C RECV = ",addr); 357 tuner_info("I2C RECV = ");
354 for (i=0;i<rc;i++) 358 for (i=0;i<rc;i++)
355 printk("%02x ",buffer[i]); 359 printk("%02x ",buffer[i]);
356 printk("\n"); 360 printk("\n");
357 } 361 }
358 /* TEA5767 autodetection code - only for addr = 0xc0 */ 362 /* TEA5767 autodetection code - only for addr = 0xc0 */
359 if (!no_autodetect) { 363 if (!no_autodetect) {
360 if (addr == 0x60) { 364 switch (addr) {
365 case 0x42:
366 case 0x43:
367 case 0x4a:
368 case 0x4b:
369 /* If chip is not tda8290, don't register.
370 since it can be tda9887*/
371 if (tda8290_probe(&t->i2c) != 0) {
372 tuner_dbg("chip at addr %x is not a tda8290\n", addr);
373 kfree(t);
374 return 0;
375 }
376 break;
377 case 0x60:
361 if (tea5767_autodetection(&t->i2c) != EINVAL) { 378 if (tea5767_autodetection(&t->i2c) != EINVAL) {
362 t->type = TUNER_TEA5767; 379 t->type = TUNER_TEA5767;
363 t->mode_mask = T_RADIO; 380 t->mode_mask = T_RADIO;
@@ -365,10 +382,9 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
365 t->freq = 87.5 * 16; /* Sets freq to FM range */ 382 t->freq = 87.5 * 16; /* Sets freq to FM range */
366 default_mode_mask &= ~T_RADIO; 383 default_mode_mask &= ~T_RADIO;
367 384
368 i2c_attach_client (&t->i2c); 385 goto register_client;
369 set_type(&t->i2c,t->type, t->mode_mask);
370 return 0;
371 } 386 }
387 break;
372 } 388 }
373 } 389 }
374 390
@@ -381,6 +397,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
381 } 397 }
382 398
383 /* Should be just before return */ 399 /* Should be just before return */
400register_client:
401 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
384 i2c_attach_client (&t->i2c); 402 i2c_attach_client (&t->i2c);
385 set_type (&t->i2c,t->type, t->mode_mask); 403 set_type (&t->i2c,t->type, t->mode_mask);
386 return 0; 404 return 0;
@@ -425,23 +443,23 @@ static int tuner_detach(struct i2c_client *client)
425 443
426static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd) 444static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
427{ 445{
428 if (mode == t->mode) 446 if (mode == t->mode)
429 return 0; 447 return 0;
430 448
431 t->mode = mode; 449 t->mode = mode;
432 450
433 if (check_mode(t, cmd) == EINVAL) { 451 if (check_mode(t, cmd) == EINVAL) {
434 t->mode = T_STANDBY; 452 t->mode = T_STANDBY;
435 if (t->standby) 453 if (t->standby)
436 t->standby (client); 454 t->standby (client);
437 return EINVAL; 455 return EINVAL;
438 } 456 }
439 return 0; 457 return 0;
440} 458}
441 459
442#define switch_v4l2() if (!t->using_v4l2) \ 460#define switch_v4l2() if (!t->using_v4l2) \
443 tuner_dbg("switching to v4l2\n"); \ 461 tuner_dbg("switching to v4l2\n"); \
444 t->using_v4l2 = 1; 462 t->using_v4l2 = 1;
445 463
446static inline int check_v4l2(struct tuner *t) 464static inline int check_v4l2(struct tuner *t)
447{ 465{
@@ -479,8 +497,6 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
479 break; 497 break;
480 } 498 }
481 case AUDC_CONFIG_PINNACLE: 499 case AUDC_CONFIG_PINNACLE:
482 if (check_mode(t, "AUDC_CONFIG_PINNACLE") == EINVAL)
483 return 0;
484 switch (*iarg) { 500 switch (*iarg) {
485 case 2: 501 case 2:
486 tuner_dbg("pinnacle pal\n"); 502 tuner_dbg("pinnacle pal\n");
@@ -616,7 +632,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
616 switch_v4l2(); 632 switch_v4l2();
617 if (V4L2_TUNER_RADIO == f->type && 633 if (V4L2_TUNER_RADIO == f->type &&
618 V4L2_TUNER_RADIO != t->mode) { 634 V4L2_TUNER_RADIO != t->mode) {
619 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") 635 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
620 == EINVAL) 636 == EINVAL)
621 return 0; 637 return 0;
622 } 638 }
@@ -688,7 +704,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
688 break; 704 break;
689 } 705 }
690 default: 706 default:
691 tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n", 707 tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n",
692 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), 708 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
693 _IOC_NR(cmd), _IOC_SIZE(cmd)); 709 _IOC_NR(cmd), _IOC_SIZE(cmd));
694 break; 710 break;
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 8edd73abe1d8..d832205818f2 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -102,7 +102,7 @@ struct tunertype
102 */ 102 */
103static struct tunertype tuners[] = { 103static struct tunertype tuners[] = {
104 /* 0-9 */ 104 /* 0-9 */
105 { "Temic PAL (4002 FH5)", TEMIC, PAL, 105 { "Temic PAL (4002 FH5)", TEMIC, PAL,
106 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, 106 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
107 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, 107 { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I,
108 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 108 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
@@ -118,41 +118,41 @@ static struct tunertype tuners[] = {
118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, 118 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, 119 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, 120 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC, 121 { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, 122 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
123 { "Alps HSBH1", TEMIC, NTSC, 123 { "Alps HSBH1", TEMIC, NTSC,
124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 124 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
125 125
126 /* 10-19 */ 126 /* 10-19 */
127 { "Alps TSBE1", TEMIC, PAL, 127 { "Alps TSBE1", TEMIC, PAL,
128 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, 128 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
129 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ 129 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */
130 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, 130 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 131 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, 132 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ 133 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, 134 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL, 135 { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 136 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
137 { "Alps TSCH6", Alps, NTSC, 137 { "Alps TSCH6", Alps, NTSC,
138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, 138 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL, 139 { "Temic PAL_DK (4016 FY5)", TEMIC, PAL,
140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, 140 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
141 { "Philips NTSC_M (MK2)", Philips, NTSC, 141 { "Philips NTSC_M (MK2)", Philips, NTSC,
142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, 142 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, 143 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 144 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, 145 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 146 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
147 147
148 /* 20-29 */ 148 /* 20-29 */
149 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, 149 { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL,
150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 150 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC, 151 { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
152 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 152 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
153 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, 153 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, 154 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, 155 { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL,
156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 156 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, 157 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 158 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
@@ -173,21 +173,21 @@ static struct tunertype tuners[] = {
173 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ 173 { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */
174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, 174 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 },
175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ 175 { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */
176 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, 176 16*169,16*464,0xA0,0x90,0x30,0x8e,623},
177 { "MT20xx universal", Microtune, PAL|NTSC, 177 { "MT20xx universal", Microtune, PAL|NTSC,
178 /* see mt20xx.c for details */ }, 178 /* see mt20xx.c for details */ },
179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, 179 { "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, 180 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, 181 { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL,
182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, 182 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623},
183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC, 183 { "Temic NTSC (4136 FY5)", TEMIC, NTSC,
184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, 184 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, 185 { "LG PAL (newer TAPC series)", LGINNOTEK, PAL,
186 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, 186 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623},
187 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, 187 { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL,
188 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 188 16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, 189 { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC,
190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, 190 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732},
191 191
192 /* 40-49 */ 192 /* 40-49 */
193 { "HITACHI V7-J180AT", HITACHI, NTSC, 193 { "HITACHI V7-J180AT", HITACHI, NTSC,
@@ -196,24 +196,24 @@ static struct tunertype tuners[] = {
196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, 196 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC, 197 { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC,
198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, 198 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, 199 { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 200 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, 201 { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC,
202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, 202 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732},
203 { "Microtune 4049 FM5", Microtune, PAL, 203 { "Microtune 4049 FM5", Microtune, PAL,
204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, 204 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623},
205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, 205 { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, 206 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, 207 { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, 208 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
209 { "Tenna TNF 8831 BGFF)", Philips, PAL, 209 { "Tenna TNF 8831 BGFF)", Philips, PAL,
210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, 210 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, 211 { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, 212 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
213 213
214 /* 50-59 */ 214 /* 50-59 */
215 { "TCL 2002N", TCL, NTSC, 215 { "TCL 2002N", TCL, NTSC,
216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, 216 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, 217 { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, 218 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, 219 { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC,
@@ -222,8 +222,8 @@ static struct tunertype tuners[] = {
222 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */ 222 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */
223 { "tda8290+75", Philips, PAL|NTSC, 223 { "tda8290+75", Philips, PAL|NTSC,
224 /* see tda8290.c for details */ }, 224 /* see tda8290.c for details */ },
225 { "LG PAL (TAPE series)", LGINNOTEK, PAL, 225 { "TCL 2002MB", TCL, PAL,
226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, 226 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623},
227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, 227 { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL,
228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, 228 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
229 { "Philips FQ1236A MK4", Philips, NTSC, 229 { "Philips FQ1236A MK4", Philips, NTSC,
@@ -233,21 +233,25 @@ static struct tunertype tuners[] = {
233 { "Ymec TVision TVF-5533MF", Philips, NTSC, 233 { "Ymec TVision TVF-5533MF", Philips, NTSC,
234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, 234 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
235 235
236 /* 60-66 */ 236 /* 60-68 */
237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 237 { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, 238 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, 239 { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL,
240 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, 240 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623},
241 { "Philips TEA5767HN FM Radio", Philips, RADIO, 241 { "Philips TEA5767HN FM Radio", Philips, RADIO,
242 /* see tea5767.c for details */}, 242 /* see tea5767.c for details */},
243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, 243 { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, 244 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },
245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC, 245 { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC,
246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, 246 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732},
247 { "Ymec TVF66T5-B/DFF", Philips, PAL, 247 { "Ymec TVF66T5-B/DFF", Philips, PAL,
248 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, 248 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623},
249 { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC, 249 { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC,
250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 }, 250 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 },
251 { "Philips TD1316 Hybrid Tuner", Philips, PAL,
252 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 },
253 { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC,
254 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 },
251}; 255};
252 256
253unsigned const int tuner_count = ARRAY_SIZE(tuners); 257unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -277,7 +281,7 @@ static int tuner_stereo(struct i2c_client *c)
277 status = tuner_getstatus (c); 281 status = tuner_getstatus (c);
278 282
279 switch (t->type) { 283 switch (t->type) {
280 case TUNER_PHILIPS_FM1216ME_MK3: 284 case TUNER_PHILIPS_FM1216ME_MK3:
281 case TUNER_PHILIPS_FM1236_MK3: 285 case TUNER_PHILIPS_FM1236_MK3:
282 case TUNER_PHILIPS_FM1256_IH3: 286 case TUNER_PHILIPS_FM1256_IH3:
283 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); 287 stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
@@ -295,10 +299,10 @@ static int tuner_stereo(struct i2c_client *c)
295static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) 299static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
296{ 300{
297 struct tuner *t = i2c_get_clientdata(c); 301 struct tuner *t = i2c_get_clientdata(c);
298 u8 config; 302 u8 config, tuneraddr;
299 u16 div; 303 u16 div;
300 struct tunertype *tun; 304 struct tunertype *tun;
301 unsigned char buffer[4]; 305 unsigned char buffer[4];
302 int rc; 306 int rc;
303 307
304 tun = &tuners[t->type]; 308 tun = &tuners[t->type];
@@ -373,6 +377,31 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
373 /* Set the charge pump for fast tuning */ 377 /* Set the charge pump for fast tuning */
374 tun->config |= TUNER_CHARGE_PUMP; 378 tun->config |= TUNER_CHARGE_PUMP;
375 break; 379 break;
380
381 case TUNER_PHILIPS_TUV1236D:
382 /* 0x40 -> ATSC antenna input 1 */
383 /* 0x48 -> ATSC antenna input 2 */
384 /* 0x00 -> NTSC antenna input 1 */
385 /* 0x08 -> NTSC antenna input 2 */
386 buffer[0] = 0x14;
387 buffer[1] = 0x00;
388 buffer[2] = 0x17;
389 buffer[3] = 0x00;
390 config &= ~0x40;
391 if (t->std & V4L2_STD_ATSC) {
392 config |= 0x40;
393 buffer[1] = 0x04;
394 }
395 /* set to the correct mode (analog or digital) */
396 tuneraddr = c->addr;
397 c->addr = 0x0a;
398 if (2 != (rc = i2c_master_send(c,&buffer[0],2)))
399 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
400 if (2 != (rc = i2c_master_send(c,&buffer[2],2)))
401 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
402 c->addr = tuneraddr;
403 /* FIXME: input */
404 break;
376 } 405 }
377 406
378 /* 407 /*
@@ -404,7 +433,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
404 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", 433 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
405 buffer[0],buffer[1],buffer[2],buffer[3]); 434 buffer[0],buffer[1],buffer[2],buffer[3]);
406 435
407 if (4 != (rc = i2c_master_send(c,buffer,4))) 436 if (4 != (rc = i2c_master_send(c,buffer,4)))
408 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 437 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
409 438
410 if (t->type == TUNER_MICROTUNE_4042FI5) { 439 if (t->type == TUNER_MICROTUNE_4042FI5) {
@@ -443,7 +472,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
443{ 472{
444 struct tunertype *tun; 473 struct tunertype *tun;
445 struct tuner *t = i2c_get_clientdata(c); 474 struct tuner *t = i2c_get_clientdata(c);
446 unsigned char buffer[4]; 475 unsigned char buffer[4];
447 unsigned div; 476 unsigned div;
448 int rc; 477 int rc;
449 478
@@ -476,13 +505,13 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
476 buffer[3] = 0xa4; 505 buffer[3] = 0xa4;
477 break; 506 break;
478 } 507 }
479 buffer[0] = (div>>8) & 0x7f; 508 buffer[0] = (div>>8) & 0x7f;
480 buffer[1] = div & 0xff; 509 buffer[1] = div & 0xff;
481 510
482 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", 511 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
483 buffer[0],buffer[1],buffer[2],buffer[3]); 512 buffer[0],buffer[1],buffer[2],buffer[3]);
484 513
485 if (4 != (rc = i2c_master_send(c,buffer,4))) 514 if (4 != (rc = i2c_master_send(c,buffer,4)))
486 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 515 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
487} 516}
488 517
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 1c31ef52f863..c31bf28b73fe 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -31,7 +31,6 @@
31#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
32 32
33#include <media/audiochip.h> 33#include <media/audiochip.h>
34#include <media/id.h>
35 34
36#include "tvaudio.h" 35#include "tvaudio.h"
37 36
@@ -458,8 +457,8 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode)
458#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */ 457#define TDA9855_LOUD 1<<5 /* Loudness, 1==off */
459#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */ 458#define TDA9855_SUR 1<<3 /* Surround / Subwoofer 1==.5(L-R) 0==.5(L+R) */
460 /* Bits 0 to 3 select various combinations 459 /* Bits 0 to 3 select various combinations
461 * of line in and line out, only the 460 * of line in and line out, only the
462 * interesting ones are defined */ 461 * interesting ones are defined */
463#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */ 462#define TDA9855_EXT 1<<2 /* Selects inputs LIR and LIL. Pins 41 & 12 */
464#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */ 463#define TDA9855_INT 0 /* Selects inputs LOR and LOL. (internal) */
465 464
@@ -1028,7 +1027,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
1028#define TEA6300_TR 0x03 /* treble */ 1027#define TEA6300_TR 0x03 /* treble */
1029#define TEA6300_FA 0x04 /* fader control */ 1028#define TEA6300_FA 0x04 /* fader control */
1030#define TEA6300_S 0x05 /* switch register */ 1029#define TEA6300_S 0x05 /* switch register */
1031 /* values for those registers: */ 1030 /* values for those registers: */
1032#define TEA6300_S_SA 0x01 /* stereo A input */ 1031#define TEA6300_S_SA 0x01 /* stereo A input */
1033#define TEA6300_S_SB 0x02 /* stereo B */ 1032#define TEA6300_S_SB 0x02 /* stereo B */
1034#define TEA6300_S_SC 0x04 /* stereo C */ 1033#define TEA6300_S_SC 0x04 /* stereo C */
@@ -1042,7 +1041,7 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
1042#define TEA6320_BA 0x05 /* bass (0-4) */ 1041#define TEA6320_BA 0x05 /* bass (0-4) */
1043#define TEA6320_TR 0x06 /* treble (0-4) */ 1042#define TEA6320_TR 0x06 /* treble (0-4) */
1044#define TEA6320_S 0x07 /* switch register */ 1043#define TEA6320_S 0x07 /* switch register */
1045 /* values for those registers: */ 1044 /* values for those registers: */
1046#define TEA6320_S_SA 0x07 /* stereo A input */ 1045#define TEA6320_S_SA 0x07 /* stereo A input */
1047#define TEA6320_S_SB 0x06 /* stereo B */ 1046#define TEA6320_S_SB 0x06 /* stereo B */
1048#define TEA6320_S_SC 0x05 /* stereo C */ 1047#define TEA6320_S_SC 0x05 /* stereo C */
@@ -1082,7 +1081,7 @@ static int tea6320_initialize(struct CHIPSTATE * chip)
1082#define TDA8425_BA 0x02 /* bass */ 1081#define TDA8425_BA 0x02 /* bass */
1083#define TDA8425_TR 0x03 /* treble */ 1082#define TDA8425_TR 0x03 /* treble */
1084#define TDA8425_S1 0x08 /* switch functions */ 1083#define TDA8425_S1 0x08 /* switch functions */
1085 /* values for those registers: */ 1084 /* values for those registers: */
1086#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */ 1085#define TDA8425_S1_OFF 0xEE /* audio off (mute on) */
1087#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */ 1086#define TDA8425_S1_CH1 0xCE /* audio channel 1 (mute off) - "linear stereo" mode */
1088#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */ 1087#define TDA8425_S1_CH2 0xCF /* audio channel 2 (mute off) - "linear stereo" mode */
@@ -1148,7 +1147,7 @@ static void tda8425_setmode(struct CHIPSTATE *chip, int mode)
1148 1147
1149/* bit definition of the RESET register, I2C data. */ 1148/* bit definition of the RESET register, I2C data. */
1150#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */ 1149#define PIC16C54_MISC_RESET_REMOTE_CTL 0x01 /* bit 0, Reset to receive the key */
1151 /* code of remote controller */ 1150 /* code of remote controller */
1152#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */ 1151#define PIC16C54_MISC_MTS_MAIN 0x02 /* bit 1 */
1153#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */ 1152#define PIC16C54_MISC_MTS_SAP 0x04 /* bit 2 */
1154#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */ 1153#define PIC16C54_MISC_MTS_BOTH 0x08 /* bit 3 */
@@ -1281,7 +1280,7 @@ static struct CHIPDESC chiplist[] = {
1281 .setmode = tda9840_setmode, 1280 .setmode = tda9840_setmode,
1282 .checkmode = generic_checkmode, 1281 .checkmode = generic_checkmode,
1283 1282
1284 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN 1283 .init = { 2, { TDA9840_TEST, TDA9840_TEST_INT1SN
1285 /* ,TDA9840_SW, TDA9840_MONO */} } 1284 /* ,TDA9840_SW, TDA9840_MONO */} }
1286 }, 1285 },
1287 { 1286 {
@@ -1438,7 +1437,7 @@ static struct CHIPDESC chiplist[] = {
1438 }, 1437 },
1439 { 1438 {
1440 .name = "pic16c54 (PV951)", 1439 .name = "pic16c54 (PV951)",
1441 .id = I2C_DRIVERID_PIC16C54_PV951, 1440 .id = I2C_DRIVERID_PIC16C54_PV9,
1442 .insmodopt = &pic16c54, 1441 .insmodopt = &pic16c54,
1443 .addr_lo = I2C_PIC16C54 >> 1, 1442 .addr_lo = I2C_PIC16C54 >> 1,
1444 .addr_hi = I2C_PIC16C54>> 1, 1443 .addr_hi = I2C_PIC16C54>> 1,
@@ -1467,7 +1466,7 @@ static struct CHIPDESC chiplist[] = {
1467 .setmode = ta8874z_setmode, 1466 .setmode = ta8874z_setmode,
1468 .checkmode = generic_checkmode, 1467 .checkmode = generic_checkmode,
1469 1468
1470 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}}, 1469 .init = {2, { TA8874Z_MONO_SET, TA8874Z_SEPARATION_DEFAULT}},
1471 }, 1470 },
1472 { .name = NULL } /* EOF */ 1471 { .name = NULL } /* EOF */
1473}; 1472};
@@ -1486,8 +1485,8 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind)
1486 return -ENOMEM; 1485 return -ENOMEM;
1487 memset(chip,0,sizeof(*chip)); 1486 memset(chip,0,sizeof(*chip));
1488 memcpy(&chip->c,&client_template,sizeof(struct i2c_client)); 1487 memcpy(&chip->c,&client_template,sizeof(struct i2c_client));
1489 chip->c.adapter = adap; 1488 chip->c.adapter = adap;
1490 chip->c.addr = addr; 1489 chip->c.addr = addr;
1491 i2c_set_clientdata(&chip->c, chip); 1490 i2c_set_clientdata(&chip->c, chip);
1492 1491
1493 /* find description for the chip */ 1492 /* find description for the chip */
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 5344d5592199..72e8741e8b59 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -6,12 +6,12 @@
6 * which are: 6 * which are:
7 7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) 8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de) 9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de> 10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11 11
12 * Adjustments to fit a more general model and all bugs: 12 * Adjustments to fit a more general model and all bugs:
13 13
14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com> 14 Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
15 15
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@
40 40
41#include <media/tuner.h> 41#include <media/tuner.h>
42#include <media/tveeprom.h> 42#include <media/tveeprom.h>
43#include <media/audiochip.h>
43 44
44MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); 45MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
45MODULE_AUTHOR("John Klar"); 46MODULE_AUTHOR("John Klar");
@@ -53,14 +54,14 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
53 54
54#define tveeprom_info(fmt, arg...) do {\ 55#define tveeprom_info(fmt, arg...) do {\
55 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 56 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
56 c->adapter->nr, c->addr , ##arg); } while (0) 57 c->adapter->nr, c->addr , ##arg); } while (0)
57#define tveeprom_warn(fmt, arg...) do {\ 58#define tveeprom_warn(fmt, arg...) do {\
58 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \ 59 printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \
59 c->adapter->nr, c->addr , ##arg); } while (0) 60 c->adapter->nr, c->addr , ##arg); } while (0)
60#define tveeprom_dbg(fmt, arg...) do {\ 61#define tveeprom_dbg(fmt, arg...) do {\
61 if (debug) \ 62 if (debug) \
62 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ 63 printk(KERN_INFO "tveeprom %d-%04x: " fmt, \
63 c->adapter->nr, c->addr , ##arg); } while (0) 64 c->adapter->nr, c->addr , ##arg); } while (0)
64 65
65 66
66/* ----------------------------------------------------------------------- */ 67/* ----------------------------------------------------------------------- */
@@ -134,8 +135,8 @@ hauppauge_tuner[] =
134 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" }, 135 { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
135 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" }, 136 { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" },
136 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" }, 137 { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
137 { TUNER_PHILIPS_NTSC, "Philips TD1536" }, 138 { TUNER_PHILIPS_NTSC, "Philips TD1536" },
138 { TUNER_PHILIPS_NTSC, "Philips TD1536D" }, 139 { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
139 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */ 140 { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */
140 { TUNER_ABSENT, "Philips FI1256MP" }, 141 { TUNER_ABSENT, "Philips FI1256MP" },
141 /* 40-49 */ 142 /* 40-49 */
@@ -189,7 +190,7 @@ hauppauge_tuner[] =
189 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, 190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
190 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"}, 191 { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
191 { TUNER_TCL_2002N, "TCL 2002N 6A"}, 192 { TUNER_TCL_2002N, "TCL 2002N 6A"},
192 { TUNER_ABSENT, "Philips FQ1236 MK3"}, 193 { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
193 { TUNER_ABSENT, "Samsung TCPN 2121P30A"}, 194 { TUNER_ABSENT, "Samsung TCPN 2121P30A"},
194 { TUNER_ABSENT, "Samsung TCPE 4121P30A"}, 195 { TUNER_ABSENT, "Samsung TCPE 4121P30A"},
195 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"}, 196 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
@@ -200,95 +201,137 @@ hauppauge_tuner[] =
200 { TUNER_ABSENT, "Philips FQ1286A MK4"}, 201 { TUNER_ABSENT, "Philips FQ1286A MK4"},
201 { TUNER_ABSENT, "Philips FQ1216ME MK5"}, 202 { TUNER_ABSENT, "Philips FQ1216ME MK5"},
202 { TUNER_ABSENT, "Philips FQ1236 MK5"}, 203 { TUNER_ABSENT, "Philips FQ1236 MK5"},
203 { TUNER_ABSENT, "Unspecified"}, 204 { TUNER_ABSENT, "Samsung TCPG_6121P30A"},
204 { TUNER_LG_PAL_TAPE, "LG PAL (TAPE Series)"}, 205 { TUNER_TCL_2002MB, "TCL 2002MB_3H"},
205 { TUNER_ABSENT, "Unspecified"}, 206 { TUNER_ABSENT, "TCL 2002MI_3H"},
206 { TUNER_TCL_2002N, "TCL 2002N 5H"}, 207 { TUNER_TCL_2002N, "TCL 2002N 5H"},
207 /* 100-103 */ 208 /* 100-109 */
208 { TUNER_ABSENT, "Unspecified"}, 209 { TUNER_ABSENT, "Philips FMD1216ME"},
209 { TUNER_TEA5767, "Philips TEA5767HN FM Radio"}, 210 { TUNER_TEA5767, "Philips TEA5768HL FM Radio"},
210 { TUNER_ABSENT, "Unspecified"}, 211 { TUNER_ABSENT, "Panasonic ENV57H12D5"},
211 { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05 4"}, 212 { TUNER_ABSENT, "TCL MFNM05-4"},
213 { TUNER_ABSENT, "TCL MNM05-4"},
214 { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
215 { TUNER_ABSENT, "TCL MQNM05-4"},
216 { TUNER_ABSENT, "LG TAPC-W701D"},
217 { TUNER_ABSENT, "TCL 9886P-WM"},
218 { TUNER_ABSENT, "TCL 1676NM-WM"},
212}; 219};
213 220
214/* This list is supplied by Hauppauge. Thanks! */ 221static struct HAUPPAUGE_AUDIOIC
215static const char *audioIC[] = { 222{
216 /* 0-4 */ 223 enum audiochip id;
217 "None", "TEA6300", "TEA6320", "TDA9850", "MSP3400C", 224 char *name;
218 /* 5-9 */ 225}
219 "MSP3410D", "MSP3415", "MSP3430", "MSP3438", "CS5331", 226audioIC[] =
220 /* 10-14 */ 227{
221 "MSP3435", "MSP3440", "MSP3445", "MSP3411", "MSP3416", 228 /* 0-4 */
222 /* 15-19 */ 229 {AUDIO_CHIP_NONE, "None"},
223 "MSP3425", "MSP3451", "MSP3418", "Type 0x12", "OKI7716", 230 {AUDIO_CHIP_TEA6300, "TEA6300"},
224 /* 20-24 */ 231 {AUDIO_CHIP_TEA6300, "TEA6320"},
225 "MSP4410", "MSP4420", "MSP4440", "MSP4450", "MSP4408", 232 {AUDIO_CHIP_TDA985X, "TDA9850"},
226 /* 25-29 */ 233 {AUDIO_CHIP_MSP34XX, "MSP3400C"},
227 "MSP4418", "MSP4428", "MSP4448", "MSP4458", "Type 0x1d", 234 /* 5-9 */
228 /* 30-34 */ 235 {AUDIO_CHIP_MSP34XX, "MSP3410D"},
229 "CX880", "CX881", "CX883", "CX882", "CX25840", 236 {AUDIO_CHIP_MSP34XX, "MSP3415"},
230 /* 35-38 */ 237 {AUDIO_CHIP_MSP34XX, "MSP3430"},
231 "CX25841", "CX25842", "CX25843", "CX23418", 238 {AUDIO_CHIP_UNKNOWN, "MSP3438"},
239 {AUDIO_CHIP_UNKNOWN, "CS5331"},
240 /* 10-14 */
241 {AUDIO_CHIP_MSP34XX, "MSP3435"},
242 {AUDIO_CHIP_MSP34XX, "MSP3440"},
243 {AUDIO_CHIP_MSP34XX, "MSP3445"},
244 {AUDIO_CHIP_UNKNOWN, "MSP3411"},
245 {AUDIO_CHIP_UNKNOWN, "MSP3416"},
246 /* 15-19 */
247 {AUDIO_CHIP_MSP34XX, "MSP3425"},
248 {AUDIO_CHIP_UNKNOWN, "MSP3451"},
249 {AUDIO_CHIP_UNKNOWN, "MSP3418"},
250 {AUDIO_CHIP_UNKNOWN, "Type 0x12"},
251 {AUDIO_CHIP_UNKNOWN, "OKI7716"},
252 /* 20-24 */
253 {AUDIO_CHIP_UNKNOWN, "MSP4410"},
254 {AUDIO_CHIP_UNKNOWN, "MSP4420"},
255 {AUDIO_CHIP_UNKNOWN, "MSP4440"},
256 {AUDIO_CHIP_UNKNOWN, "MSP4450"},
257 {AUDIO_CHIP_UNKNOWN, "MSP4408"},
258 /* 25-29 */
259 {AUDIO_CHIP_UNKNOWN, "MSP4418"},
260 {AUDIO_CHIP_UNKNOWN, "MSP4428"},
261 {AUDIO_CHIP_UNKNOWN, "MSP4448"},
262 {AUDIO_CHIP_UNKNOWN, "MSP4458"},
263 {AUDIO_CHIP_UNKNOWN, "Type 0x1d"},
264 /* 30-34 */
265 {AUDIO_CHIP_INTERNAL, "CX880"},
266 {AUDIO_CHIP_INTERNAL, "CX881"},
267 {AUDIO_CHIP_INTERNAL, "CX883"},
268 {AUDIO_CHIP_INTERNAL, "CX882"},
269 {AUDIO_CHIP_INTERNAL, "CX25840"},
270 /* 35-38 */
271 {AUDIO_CHIP_INTERNAL, "CX25841"},
272 {AUDIO_CHIP_INTERNAL, "CX25842"},
273 {AUDIO_CHIP_INTERNAL, "CX25843"},
274 {AUDIO_CHIP_INTERNAL, "CX23418"},
232}; 275};
233 276
234/* This list is supplied by Hauppauge. Thanks! */ 277/* This list is supplied by Hauppauge. Thanks! */
235static const char *decoderIC[] = { 278static const char *decoderIC[] = {
236 /* 0-4 */ 279 /* 0-4 */
237 "None", "BT815", "BT817", "BT819", "BT815A", 280 "None", "BT815", "BT817", "BT819", "BT815A",
238 /* 5-9 */ 281 /* 5-9 */
239 "BT817A", "BT819A", "BT827", "BT829", "BT848", 282 "BT817A", "BT819A", "BT827", "BT829", "BT848",
240 /* 10-14 */ 283 /* 10-14 */
241 "BT848A", "BT849A", "BT829A", "BT827A", "BT878", 284 "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
242 /* 15-19 */ 285 /* 15-19 */
243 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115", 286 "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
244 /* 20-24 */ 287 /* 20-24 */
245 "CX880", "CX881", "CX883", "SAA7111", "SAA7113", 288 "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
246 /* 25-29 */ 289 /* 25-29 */
247 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842", 290 "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
248 /* 30-31 */ 291 /* 30-31 */
249 "CX25843", "CX23418", 292 "CX25843", "CX23418",
250}; 293};
251 294
252static int hasRadioTuner(int tunerType) 295static int hasRadioTuner(int tunerType)
253{ 296{
254 switch (tunerType) { 297 switch (tunerType) {
255 case 18: //PNPEnv_TUNER_FR1236_MK2: 298 case 18: //PNPEnv_TUNER_FR1236_MK2:
256 case 23: //PNPEnv_TUNER_FM1236: 299 case 23: //PNPEnv_TUNER_FM1236:
257 case 38: //PNPEnv_TUNER_FMR1236: 300 case 38: //PNPEnv_TUNER_FMR1236:
258 case 16: //PNPEnv_TUNER_FR1216_MK2: 301 case 16: //PNPEnv_TUNER_FR1216_MK2:
259 case 19: //PNPEnv_TUNER_FR1246_MK2: 302 case 19: //PNPEnv_TUNER_FR1246_MK2:
260 case 21: //PNPEnv_TUNER_FM1216: 303 case 21: //PNPEnv_TUNER_FM1216:
261 case 24: //PNPEnv_TUNER_FM1246: 304 case 24: //PNPEnv_TUNER_FM1246:
262 case 17: //PNPEnv_TUNER_FR1216MF_MK2: 305 case 17: //PNPEnv_TUNER_FR1216MF_MK2:
263 case 22: //PNPEnv_TUNER_FM1216MF: 306 case 22: //PNPEnv_TUNER_FM1216MF:
264 case 20: //PNPEnv_TUNER_FR1256_MK2: 307 case 20: //PNPEnv_TUNER_FR1256_MK2:
265 case 25: //PNPEnv_TUNER_FM1256: 308 case 25: //PNPEnv_TUNER_FM1256:
266 case 33: //PNPEnv_TUNER_4039FR5: 309 case 33: //PNPEnv_TUNER_4039FR5:
267 case 42: //PNPEnv_TUNER_4009FR5: 310 case 42: //PNPEnv_TUNER_4009FR5:
268 case 52: //PNPEnv_TUNER_4049FM5: 311 case 52: //PNPEnv_TUNER_4049FM5:
269 case 54: //PNPEnv_TUNER_4049FM5_AltI2C: 312 case 54: //PNPEnv_TUNER_4049FM5_AltI2C:
270 case 44: //PNPEnv_TUNER_4009FN5: 313 case 44: //PNPEnv_TUNER_4009FN5:
271 case 31: //PNPEnv_TUNER_TCPB9085P: 314 case 31: //PNPEnv_TUNER_TCPB9085P:
272 case 30: //PNPEnv_TUNER_TCPN9085D: 315 case 30: //PNPEnv_TUNER_TCPN9085D:
273 case 46: //PNPEnv_TUNER_TP18NSR01F: 316 case 46: //PNPEnv_TUNER_TP18NSR01F:
274 case 47: //PNPEnv_TUNER_TP18PSB01D: 317 case 47: //PNPEnv_TUNER_TP18PSB01D:
275 case 49: //PNPEnv_TUNER_TAPC_I001D: 318 case 49: //PNPEnv_TUNER_TAPC_I001D:
276 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3: 319 case 60: //PNPEnv_TUNER_TAPE_S001D_MK3:
277 case 57: //PNPEnv_TUNER_FM1216ME_MK3: 320 case 57: //PNPEnv_TUNER_FM1216ME_MK3:
278 case 59: //PNPEnv_TUNER_FM1216MP_MK3: 321 case 59: //PNPEnv_TUNER_FM1216MP_MK3:
279 case 58: //PNPEnv_TUNER_FM1236_MK3: 322 case 58: //PNPEnv_TUNER_FM1236_MK3:
280 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3: 323 case 68: //PNPEnv_TUNER_TAPE_H001F_MK3:
281 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3: 324 case 61: //PNPEnv_TUNER_TAPE_M001D_MK3:
282 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM: 325 case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
283 case 89: //PNPEnv_TUNER_TCL_MFPE05_2: 326 case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
284 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4: 327 case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
285 return 1; 328 return 1;
286 } 329 }
287 return 0; 330 return 0;
288} 331}
289 332
290void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, 333void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
291 unsigned char *eeprom_data) 334 unsigned char *eeprom_data)
292{ 335{
293 /* ---------------------------------------------- 336 /* ----------------------------------------------
294 ** The hauppauge eeprom format is tagged 337 ** The hauppauge eeprom format is tagged
@@ -312,19 +355,27 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
312 ** # of inputs/outputs ??? 355 ** # of inputs/outputs ???
313 */ 356 */
314 357
315 int i, j, len, done, beenhere, tag; 358 int i, j, len, done, beenhere, tag,start;
316 359
317 int tuner1 = 0, t_format1 = 0; 360 int tuner1 = 0, t_format1 = 0, audioic=-1;
318 char *t_name1 = NULL; 361 char *t_name1 = NULL;
319 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" }; 362 const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
320 363
321 int tuner2 = 0, t_format2 = 0; 364 int tuner2 = 0, t_format2 = 0;
322 char *t_name2 = NULL; 365 char *t_name2 = NULL;
323 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" }; 366 const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
324 367
325 memset(tvee, 0, sizeof(*tvee)); 368 memset(tvee, 0, sizeof(*tvee));
326 done = len = beenhere = 0; 369 done = len = beenhere = 0;
327 for (i = 0; !done && i < 256; i += len) { 370
371 /* Hack for processing eeprom for em28xx */
372 if ((eeprom_data[0]==0x1a)&&(eeprom_data[1]==0xeb)&&
373 (eeprom_data[2]==0x67)&&(eeprom_data[3]==0x95))
374 start=0xa0;
375 else
376 start=0;
377
378 for (i = start; !done && i < 256; i += len) {
328 if (eeprom_data[i] == 0x84) { 379 if (eeprom_data[i] == 0x84) {
329 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8); 380 len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
330 i += 3; 381 i += 3;
@@ -338,28 +389,28 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
338 ++i; 389 ++i;
339 } else { 390 } else {
340 tveeprom_warn("Encountered bad packet header [%02x]. " 391 tveeprom_warn("Encountered bad packet header [%02x]. "
341 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]); 392 "Corrupt or not a Hauppauge eeprom.\n", eeprom_data[i]);
342 return; 393 return;
343 } 394 }
344 395
345 if (debug) { 396 if (debug) {
346 tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1); 397 tveeprom_info("Tag [%02x] + %d bytes:", eeprom_data[i], len - 1);
347 for(j = 1; j < len; j++) { 398 for(j = 1; j < len; j++) {
348 printk(" %02x", eeprom_data[i + j]); 399 printk(" %02x", eeprom_data[i + j]);
349 } 400 }
350 printk("\n"); 401 printk("\n");
351 } 402 }
352 403
353 /* process by tag */ 404 /* process by tag */
354 tag = eeprom_data[i]; 405 tag = eeprom_data[i];
355 switch (tag) { 406 switch (tag) {
356 case 0x00: 407 case 0x00:
357 /* tag: 'Comprehensive' */ 408 /* tag: 'Comprehensive' */
358 tuner1 = eeprom_data[i+6]; 409 tuner1 = eeprom_data[i+6];
359 t_format1 = eeprom_data[i+5]; 410 t_format1 = eeprom_data[i+5];
360 tvee->has_radio = eeprom_data[i+len-1]; 411 tvee->has_radio = eeprom_data[i+len-1];
361 /* old style tag, don't know how to detect 412 /* old style tag, don't know how to detect
362 IR presence, mark as unknown. */ 413 IR presence, mark as unknown. */
363 tvee->has_ir = 2; 414 tvee->has_ir = 2;
364 tvee->model = 415 tvee->model =
365 eeprom_data[i+8] + 416 eeprom_data[i+8] +
@@ -370,7 +421,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
370 break; 421 break;
371 422
372 case 0x01: 423 case 0x01:
373 /* tag: 'SerialID' */ 424 /* tag: 'SerialID' */
374 tvee->serial_number = 425 tvee->serial_number =
375 eeprom_data[i+6] + 426 eeprom_data[i+6] +
376 (eeprom_data[i+7] << 8) + 427 (eeprom_data[i+7] << 8) +
@@ -378,17 +429,21 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
378 break; 429 break;
379 430
380 case 0x02: 431 case 0x02:
381 /* tag 'AudioInfo' 432 /* tag 'AudioInfo'
382 Note mask with 0x7F, high bit used on some older models 433 Note mask with 0x7F, high bit used on some older models
383 to indicate 4052 mux was removed in favor of using MSP 434 to indicate 4052 mux was removed in favor of using MSP
384 inputs directly. */ 435 inputs directly. */
385 tvee->audio_processor = eeprom_data[i+2] & 0x7f; 436 audioic = eeprom_data[i+2] & 0x7f;
437 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
438 tvee->audio_processor = audioIC[audioic].id;
439 else
440 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
386 break; 441 break;
387 442
388 /* case 0x03: tag 'EEInfo' */ 443 /* case 0x03: tag 'EEInfo' */
389 444
390 case 0x04: 445 case 0x04:
391 /* tag 'SerialID2' */ 446 /* tag 'SerialID2' */
392 tvee->serial_number = 447 tvee->serial_number =
393 eeprom_data[i+5] + 448 eeprom_data[i+5] +
394 (eeprom_data[i+6] << 8) + 449 (eeprom_data[i+6] << 8) +
@@ -396,15 +451,20 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
396 break; 451 break;
397 452
398 case 0x05: 453 case 0x05:
399 /* tag 'Audio2' 454 /* tag 'Audio2'
400 Note mask with 0x7F, high bit used on some older models 455 Note mask with 0x7F, high bit used on some older models
401 to indicate 4052 mux was removed in favor of using MSP 456 to indicate 4052 mux was removed in favor of using MSP
402 inputs directly. */ 457 inputs directly. */
403 tvee->audio_processor = eeprom_data[i+1] & 0x7f; 458 audioic = eeprom_data[i+1] & 0x7f;
459 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
460 tvee->audio_processor = audioIC[audioic].id;
461 else
462 tvee->audio_processor = AUDIO_CHIP_UNKNOWN;
463
404 break; 464 break;
405 465
406 case 0x06: 466 case 0x06:
407 /* tag 'ModelRev' */ 467 /* tag 'ModelRev' */
408 tvee->model = 468 tvee->model =
409 eeprom_data[i+1] + 469 eeprom_data[i+1] +
410 (eeprom_data[i+2] << 8); 470 (eeprom_data[i+2] << 8);
@@ -414,55 +474,55 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
414 break; 474 break;
415 475
416 case 0x07: 476 case 0x07:
417 /* tag 'Details': according to Hauppauge not interesting 477 /* tag 'Details': according to Hauppauge not interesting
418 on any PCI-era or later boards. */ 478 on any PCI-era or later boards. */
419 break; 479 break;
420 480
421 /* there is no tag 0x08 defined */ 481 /* there is no tag 0x08 defined */
422 482
423 case 0x09: 483 case 0x09:
424 /* tag 'Video' */ 484 /* tag 'Video' */
425 tvee->decoder_processor = eeprom_data[i + 1]; 485 tvee->decoder_processor = eeprom_data[i + 1];
426 break; 486 break;
427 487
428 case 0x0a: 488 case 0x0a:
429 /* tag 'Tuner' */ 489 /* tag 'Tuner' */
430 if (beenhere == 0) { 490 if (beenhere == 0) {
431 tuner1 = eeprom_data[i+2]; 491 tuner1 = eeprom_data[i+2];
432 t_format1 = eeprom_data[i+1]; 492 t_format1 = eeprom_data[i+1];
433 beenhere = 1; 493 beenhere = 1;
434 } else { 494 } else {
435 /* a second (radio) tuner may be present */ 495 /* a second (radio) tuner may be present */
436 tuner2 = eeprom_data[i+2]; 496 tuner2 = eeprom_data[i+2];
437 t_format2 = eeprom_data[i+1]; 497 t_format2 = eeprom_data[i+1];
438 if (t_format2 == 0) { /* not a TV tuner? */ 498 if (t_format2 == 0) { /* not a TV tuner? */
439 tvee->has_radio = 1; /* must be radio */ 499 tvee->has_radio = 1; /* must be radio */
440 } 500 }
441 } 501 }
442 break; 502 break;
443 503
444 case 0x0b: 504 case 0x0b:
445 /* tag 'Inputs': according to Hauppauge this is specific 505 /* tag 'Inputs': according to Hauppauge this is specific
446 to each driver family, so no good assumptions can be 506 to each driver family, so no good assumptions can be
447 made. */ 507 made. */
448 break; 508 break;
449 509
450 /* case 0x0c: tag 'Balun' */ 510 /* case 0x0c: tag 'Balun' */
451 /* case 0x0d: tag 'Teletext' */ 511 /* case 0x0d: tag 'Teletext' */
452 512
453 case 0x0e: 513 case 0x0e:
454 /* tag: 'Radio' */ 514 /* tag: 'Radio' */
455 tvee->has_radio = eeprom_data[i+1]; 515 tvee->has_radio = eeprom_data[i+1];
456 break; 516 break;
457 517
458 case 0x0f: 518 case 0x0f:
459 /* tag 'IRInfo' */ 519 /* tag 'IRInfo' */
460 tvee->has_ir = eeprom_data[i+1]; 520 tvee->has_ir = eeprom_data[i+1];
461 break; 521 break;
462 522
463 /* case 0x10: tag 'VBIInfo' */ 523 /* case 0x10: tag 'VBIInfo' */
464 /* case 0x11: tag 'QCInfo' */ 524 /* case 0x11: tag 'QCInfo' */
465 /* case 0x12: tag 'InfoBits' */ 525 /* case 0x12: tag 'InfoBits' */
466 526
467 default: 527 default:
468 tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag); 528 tveeprom_dbg("Not sure what to do with tag [%02x]\n", tag);
@@ -483,11 +543,11 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
483 tvee->rev_str[4] = 0; 543 tvee->rev_str[4] = 0;
484 } 544 }
485 545
486 if (hasRadioTuner(tuner1) && !tvee->has_radio) { 546 if (hasRadioTuner(tuner1) && !tvee->has_radio) {
487 tveeprom_info("The eeprom says no radio is present, but the tuner type\n"); 547 tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
488 tveeprom_info("indicates otherwise. I will assume that radio is present.\n"); 548 tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
489 tvee->has_radio = 1; 549 tvee->has_radio = 1;
490 } 550 }
491 551
492 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) { 552 if (tuner1 < sizeof(hauppauge_tuner)/sizeof(struct HAUPPAUGE_TUNER)) {
493 tvee->tuner_type = hauppauge_tuner[tuner1].id; 553 tvee->tuner_type = hauppauge_tuner[tuner1].id;
@@ -510,45 +570,53 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
510 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id; 570 tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
511 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name; 571 t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
512 } 572 }
513 if (t_format2 & (1 << i)) { 573 if (t_format2 & (1 << i)) {
514 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id; 574 tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
515 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name; 575 t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
516 } 576 }
517 } 577 }
518 578
519 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n", 579 tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
520 tvee->model, tvee->rev_str, tvee->serial_number); 580 tvee->model, tvee->rev_str, tvee->serial_number);
521 tveeprom_info("tuner model is %s (idx %d, type %d)\n", 581 tveeprom_info("tuner model is %s (idx %d, type %d)\n",
522 t_name1, tuner1, tvee->tuner_type); 582 t_name1, tuner1, tvee->tuner_type);
523 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 583 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
524 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3], 584 t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2], t_fmt_name1[3],
525 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7], 585 t_fmt_name1[4], t_fmt_name1[5], t_fmt_name1[6], t_fmt_name1[7],
526 t_format1); 586 t_format1);
527 if (tuner2) { 587 if (tuner2) {
528 tveeprom_info("second tuner model is %s (idx %d, type %d)\n", 588 tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
529 t_name2, tuner2, tvee->tuner2_type); 589 t_name2, tuner2, tvee->tuner2_type);
530 } 590 }
531 if (t_format2) { 591 if (t_format2) {
532 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n", 592 tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
533 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3], 593 t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2], t_fmt_name2[3],
534 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7], 594 t_fmt_name2[4], t_fmt_name2[5], t_fmt_name2[6], t_fmt_name2[7],
535 t_format2); 595 t_format2);
536 } 596 }
537 tveeprom_info("audio processor is %s (idx %d)\n", 597 if (audioic<0) {
538 STRM(audioIC, tvee->audio_processor), 598 tveeprom_info("audio processor is unknown (no idx)\n");
539 tvee->audio_processor); 599 tvee->audio_processor=AUDIO_CHIP_UNKNOWN;
540 if (tvee->decoder_processor) { 600 } else {
541 tveeprom_info("decoder processor is %s (idx %d)\n", 601 if (audioic < sizeof(audioIC)/sizeof(*audioIC))
542 STRM(decoderIC, tvee->decoder_processor), 602 tveeprom_info("audio processor is %s (idx %d)\n",
543 tvee->decoder_processor); 603 audioIC[audioic].name,audioic);
544 } 604 else
545 if (tvee->has_ir == 2) 605 tveeprom_info("audio processor is unknown (idx %d)\n",
546 tveeprom_info("has %sradio\n", 606 audioic);
547 tvee->has_radio ? "" : "no "); 607 }
548 else 608 if (tvee->decoder_processor) {
549 tveeprom_info("has %sradio, has %sIR remote\n", 609 tveeprom_info("decoder processor is %s (idx %d)\n",
550 tvee->has_radio ? "" : "no ", 610 STRM(decoderIC, tvee->decoder_processor),
551 tvee->has_ir ? "" : "no "); 611 tvee->decoder_processor);
612 }
613 if (tvee->has_ir == 2)
614 tveeprom_info("has %sradio\n",
615 tvee->has_radio ? "" : "no ");
616 else
617 tveeprom_info("has %sradio, has %sIR remote\n",
618 tvee->has_radio ? "" : "no ",
619 tvee->has_ir ? "" : "no ");
552} 620}
553EXPORT_SYMBOL(tveeprom_hauppauge_analog); 621EXPORT_SYMBOL(tveeprom_hauppauge_analog);
554 622
@@ -569,18 +637,18 @@ int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
569 tveeprom_warn("i2c eeprom read error (err=%d)\n", err); 637 tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
570 return -1; 638 return -1;
571 } 639 }
572 if (debug) { 640 if (debug) {
573 int i; 641 int i;
574 642
575 tveeprom_info("full 256-byte eeprom dump:\n"); 643 tveeprom_info("full 256-byte eeprom dump:\n");
576 for (i = 0; i < len; i++) { 644 for (i = 0; i < len; i++) {
577 if (0 == (i % 16)) 645 if (0 == (i % 16))
578 tveeprom_info("%02x:", i); 646 tveeprom_info("%02x:", i);
579 printk(" %02x", eedata[i]); 647 printk(" %02x", eedata[i]);
580 if (15 == (i % 16)) 648 if (15 == (i % 16))
581 printk("\n"); 649 printk("\n");
582 } 650 }
583 } 651 }
584 return 0; 652 return 0;
585} 653}
586EXPORT_SYMBOL(tveeprom_read); 654EXPORT_SYMBOL(tveeprom_read);
@@ -590,10 +658,6 @@ EXPORT_SYMBOL(tveeprom_read);
590/* run, just call the exported tveeprom_* directly, there is no point in */ 658/* run, just call the exported tveeprom_* directly, there is no point in */
591/* using the indirect way via i2c_driver->command() */ 659/* using the indirect way via i2c_driver->command() */
592 660
593#ifndef I2C_DRIVERID_TVEEPROM
594# define I2C_DRIVERID_TVEEPROM I2C_DRIVERID_EXP2
595#endif
596
597static unsigned short normal_i2c[] = { 661static unsigned short normal_i2c[] = {
598 0xa0 >> 1, 662 0xa0 >> 1,
599 I2C_CLIENT_END, 663 I2C_CLIENT_END,
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index d86e08ebddfc..8318bd1aad00 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -79,7 +79,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
79{ 79{
80 struct video_audio va; 80 struct video_audio va;
81 int left,right,ret,val = 0; 81 int left,right,ret,val = 0;
82 struct TVMIXER *mix = file->private_data; 82 struct TVMIXER *mix = file->private_data;
83 struct i2c_client *client = mix->dev; 83 struct i2c_client *client = mix->dev;
84 void __user *argp = (void __user *)arg; 84 void __user *argp = (void __user *)arg;
85 int __user *p = argp; 85 int __user *p = argp;
@@ -87,25 +87,25 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
87 if (NULL == client) 87 if (NULL == client)
88 return -ENODEV; 88 return -ENODEV;
89 89
90 if (cmd == SOUND_MIXER_INFO) { 90 if (cmd == SOUND_MIXER_INFO) {
91 mixer_info info; 91 mixer_info info;
92 strlcpy(info.id, "tv card", sizeof(info.id)); 92 strlcpy(info.id, "tv card", sizeof(info.id));
93 strlcpy(info.name, client->name, sizeof(info.name)); 93 strlcpy(info.name, client->name, sizeof(info.name));
94 info.modify_counter = 42 /* FIXME */; 94 info.modify_counter = 42 /* FIXME */;
95 if (copy_to_user(argp, &info, sizeof(info))) 95 if (copy_to_user(argp, &info, sizeof(info)))
96 return -EFAULT; 96 return -EFAULT;
97 return 0; 97 return 0;
98 } 98 }
99 if (cmd == SOUND_OLD_MIXER_INFO) { 99 if (cmd == SOUND_OLD_MIXER_INFO) {
100 _old_mixer_info info; 100 _old_mixer_info info;
101 strlcpy(info.id, "tv card", sizeof(info.id)); 101 strlcpy(info.id, "tv card", sizeof(info.id));
102 strlcpy(info.name, client->name, sizeof(info.name)); 102 strlcpy(info.name, client->name, sizeof(info.name));
103 if (copy_to_user(argp, &info, sizeof(info))) 103 if (copy_to_user(argp, &info, sizeof(info)))
104 return -EFAULT; 104 return -EFAULT;
105 return 0; 105 return 0;
106 } 106 }
107 if (cmd == OSS_GETVERSION) 107 if (cmd == OSS_GETVERSION)
108 return put_user(SOUND_VERSION, p); 108 return put_user(SOUND_VERSION, p);
109 109
110 if (_SIOC_DIR(cmd) & _SIOC_WRITE) 110 if (_SIOC_DIR(cmd) & _SIOC_WRITE)
111 if (get_user(val, p)) 111 if (get_user(val, p))
@@ -181,8 +181,8 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm
181 181
182static int tvmixer_open(struct inode *inode, struct file *file) 182static int tvmixer_open(struct inode *inode, struct file *file)
183{ 183{
184 int i, minor = iminor(inode); 184 int i, minor = iminor(inode);
185 struct TVMIXER *mix = NULL; 185 struct TVMIXER *mix = NULL;
186 struct i2c_client *client = NULL; 186 struct i2c_client *client = NULL;
187 187
188 for (i = 0; i < DEV_MAX; i++) { 188 for (i = 0; i < DEV_MAX; i++) {
@@ -204,7 +204,7 @@ static int tvmixer_open(struct inode *inode, struct file *file)
204#endif 204#endif
205 if (client->adapter->owner) 205 if (client->adapter->owner)
206 try_module_get(client->adapter->owner); 206 try_module_get(client->adapter->owner);
207 return 0; 207 return 0;
208} 208}
209 209
210static int tvmixer_release(struct inode *inode, struct file *file) 210static int tvmixer_release(struct inode *inode, struct file *file)
@@ -231,15 +231,15 @@ static struct i2c_driver driver = {
231 .owner = THIS_MODULE, 231 .owner = THIS_MODULE,
232#endif 232#endif
233 .name = "tv card mixer driver", 233 .name = "tv card mixer driver",
234 .id = I2C_DRIVERID_TVMIXER, 234 .id = I2C_DRIVERID_TVMIXER,
235#ifdef I2C_DF_DUMMY 235#ifdef I2C_DF_DUMMY
236 .flags = I2C_DF_DUMMY, 236 .flags = I2C_DF_DUMMY,
237#else 237#else
238 .flags = I2C_DF_NOTIFY, 238 .flags = I2C_DF_NOTIFY,
239 .detach_adapter = tvmixer_adapters, 239 .detach_adapter = tvmixer_adapters,
240#endif 240#endif
241 .attach_adapter = tvmixer_adapters, 241 .attach_adapter = tvmixer_adapters,
242 .detach_client = tvmixer_clients, 242 .detach_client = tvmixer_clients,
243}; 243};
244 244
245static struct file_operations tvmixer_fops = { 245static struct file_operations tvmixer_fops = {
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
new file mode 100644
index 000000000000..81e6d4494e7d
--- /dev/null
+++ b/drivers/media/video/tvp5150.c
@@ -0,0 +1,829 @@
1/*
2 * tvp5150 - Texas Instruments TVP5150A(M) video decoder driver
3 *
4 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
5 * This code is placed under the terms of the GNU General Public License
6 */
7
8#include <linux/i2c.h>
9#include <linux/videodev.h>
10#include <linux/delay.h>
11#include <linux/video_decoder.h>
12
13#include "tvp5150_reg.h"
14
15MODULE_DESCRIPTION("Texas Instruments TVP5150A video decoder driver"); /* standard i2c insmod options */
16MODULE_AUTHOR("Mauro Carvalho Chehab");
17MODULE_LICENSE("GPL");
18
19static unsigned short normal_i2c[] = {
20 0xb8 >> 1,
21 0xba >> 1,
22 I2C_CLIENT_END
23};
24
25I2C_CLIENT_INSMOD;
26
27static int debug = 0;
28module_param(debug, int, 0);
29MODULE_PARM_DESC(debug, "Debug level (0-1)");
30
31#define dprintk(num, format, args...) \
32 do { \
33 if (debug >= num) \
34 printk(format , ##args); \
35 } while (0)
36
37/* supported controls */
38static struct v4l2_queryctrl tvp5150_qctrl[] = {
39 {
40 .id = V4L2_CID_BRIGHTNESS,
41 .type = V4L2_CTRL_TYPE_INTEGER,
42 .name = "Brightness",
43 .minimum = 0,
44 .maximum = 255,
45 .step = 1,
46 .default_value = 0,
47 .flags = 0,
48 }, {
49 .id = V4L2_CID_CONTRAST,
50 .type = V4L2_CTRL_TYPE_INTEGER,
51 .name = "Contrast",
52 .minimum = 0,
53 .maximum = 255,
54 .step = 0x1,
55 .default_value = 0x10,
56 .flags = 0,
57 }, {
58 .id = V4L2_CID_SATURATION,
59 .type = V4L2_CTRL_TYPE_INTEGER,
60 .name = "Saturation",
61 .minimum = 0,
62 .maximum = 255,
63 .step = 0x1,
64 .default_value = 0x10,
65 .flags = 0,
66 }, {
67 .id = V4L2_CID_HUE,
68 .type = V4L2_CTRL_TYPE_INTEGER,
69 .name = "Hue",
70 .minimum = -128,
71 .maximum = 127,
72 .step = 0x1,
73 .default_value = 0x10,
74 .flags = 0,
75 }
76};
77
78struct tvp5150 {
79 struct i2c_client *client;
80
81 int norm;
82 int input;
83 int enable;
84 int bright;
85 int contrast;
86 int hue;
87 int sat;
88};
89
90static inline int tvp5150_read(struct i2c_client *c, unsigned char addr)
91{
92 unsigned char buffer[1];
93 int rc;
94
95 buffer[0] = addr;
96 if (1 != (rc = i2c_master_send(c, buffer, 1)))
97 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
98
99 msleep(10);
100
101 if (1 != (rc = i2c_master_recv(c, buffer, 1)))
102 dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc);
103
104 return (buffer[0]);
105}
106
107static inline void tvp5150_write(struct i2c_client *c, unsigned char addr,
108 unsigned char value)
109{
110 unsigned char buffer[2];
111 int rc;
112/* struct tvp5150 *core = i2c_get_clientdata(c); */
113
114 buffer[0] = addr;
115 buffer[1] = value;
116 dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]);
117 if (2 != (rc = i2c_master_send(c, buffer, 2)))
118 dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc);
119}
120
121static void dump_reg(struct i2c_client *c)
122{
123 printk("tvp5150: Video input source selection #1 = 0x%02x\n",
124 tvp5150_read(c, TVP5150_VD_IN_SRC_SEL_1));
125 printk("tvp5150: Analog channel controls = 0x%02x\n",
126 tvp5150_read(c, TVP5150_ANAL_CHL_CTL));
127 printk("tvp5150: Operation mode controls = 0x%02x\n",
128 tvp5150_read(c, TVP5150_OP_MODE_CTL));
129 printk("tvp5150: Miscellaneous controls = 0x%02x\n",
130 tvp5150_read(c, TVP5150_MISC_CTL));
131 printk("tvp5150: Autoswitch mask: TVP5150A / TVP5150AM = 0x%02x\n",
132 tvp5150_read(c, TVP5150_AUTOSW_MSK));
133 printk("tvp5150: Color killer threshold control = 0x%02x\n",
134 tvp5150_read(c, TVP5150_COLOR_KIL_THSH_CTL));
135 printk("tvp5150: Luminance processing control #1 = 0x%02x\n",
136 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_1));
137 printk("tvp5150: Luminance processing control #2 = 0x%02x\n",
138 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_2));
139 printk("tvp5150: Brightness control = 0x%02x\n",
140 tvp5150_read(c, TVP5150_BRIGHT_CTL));
141 printk("tvp5150: Color saturation control = 0x%02x\n",
142 tvp5150_read(c, TVP5150_SATURATION_CTL));
143 printk("tvp5150: Hue control = 0x%02x\n",
144 tvp5150_read(c, TVP5150_HUE_CTL));
145 printk("tvp5150: Contrast control = 0x%02x\n",
146 tvp5150_read(c, TVP5150_CONTRAST_CTL));
147 printk("tvp5150: Outputs and data rates select = 0x%02x\n",
148 tvp5150_read(c, TVP5150_DATA_RATE_SEL));
149 printk("tvp5150: Luminance processing control #3 = 0x%02x\n",
150 tvp5150_read(c, TVP5150_LUMA_PROC_CTL_3));
151 printk("tvp5150: Configuration shared pins = 0x%02x\n",
152 tvp5150_read(c, TVP5150_CONF_SHARED_PIN));
153 printk("tvp5150: Active video cropping start MSB = 0x%02x\n",
154 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_MSB));
155 printk("tvp5150: Active video cropping start LSB = 0x%02x\n",
156 tvp5150_read(c, TVP5150_ACT_VD_CROP_ST_LSB));
157 printk("tvp5150: Active video cropping stop MSB = 0x%02x\n",
158 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_MSB));
159 printk("tvp5150: Active video cropping stop LSB = 0x%02x\n",
160 tvp5150_read(c, TVP5150_ACT_VD_CROP_STP_LSB));
161 printk("tvp5150: Genlock/RTC = 0x%02x\n",
162 tvp5150_read(c, TVP5150_GENLOCK));
163 printk("tvp5150: Horizontal sync start = 0x%02x\n",
164 tvp5150_read(c, TVP5150_HORIZ_SYNC_START));
165 printk("tvp5150: Vertical blanking start = 0x%02x\n",
166 tvp5150_read(c, TVP5150_VERT_BLANKING_START));
167 printk("tvp5150: Vertical blanking stop = 0x%02x\n",
168 tvp5150_read(c, TVP5150_VERT_BLANKING_STOP));
169 printk("tvp5150: Chrominance processing control #1 = 0x%02x\n",
170 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_1));
171 printk("tvp5150: Chrominance processing control #2 = 0x%02x\n",
172 tvp5150_read(c, TVP5150_CHROMA_PROC_CTL_2));
173 printk("tvp5150: Interrupt reset register B = 0x%02x\n",
174 tvp5150_read(c, TVP5150_INT_RESET_REG_B));
175 printk("tvp5150: Interrupt enable register B = 0x%02x\n",
176 tvp5150_read(c, TVP5150_INT_ENABLE_REG_B));
177 printk("tvp5150: Interrupt configuration register B = 0x%02x\n",
178 tvp5150_read(c, TVP5150_INTT_CONFIG_REG_B));
179 printk("tvp5150: Video standard = 0x%02x\n",
180 tvp5150_read(c, TVP5150_VIDEO_STD));
181 printk("tvp5150: Cb gain factor = 0x%02x\n",
182 tvp5150_read(c, TVP5150_CB_GAIN_FACT));
183 printk("tvp5150: Cr gain factor = 0x%02x\n",
184 tvp5150_read(c, TVP5150_CR_GAIN_FACTOR));
185 printk("tvp5150: Macrovision on counter = 0x%02x\n",
186 tvp5150_read(c, TVP5150_MACROVISION_ON_CTR));
187 printk("tvp5150: Macrovision off counter = 0x%02x\n",
188 tvp5150_read(c, TVP5150_MACROVISION_OFF_CTR));
189 printk("tvp5150: revision select (TVP5150AM1 only) = 0x%02x\n",
190 tvp5150_read(c, TVP5150_REV_SELECT));
191 printk("tvp5150: MSB of device ID = 0x%02x\n",
192 tvp5150_read(c, TVP5150_MSB_DEV_ID));
193 printk("tvp5150: LSB of device ID = 0x%02x\n",
194 tvp5150_read(c, TVP5150_LSB_DEV_ID));
195 printk("tvp5150: ROM major version = 0x%02x\n",
196 tvp5150_read(c, TVP5150_ROM_MAJOR_VER));
197 printk("tvp5150: ROM minor version = 0x%02x\n",
198 tvp5150_read(c, TVP5150_ROM_MINOR_VER));
199 printk("tvp5150: Vertical line count MSB = 0x%02x\n",
200 tvp5150_read(c, TVP5150_VERT_LN_COUNT_MSB));
201 printk("tvp5150: Vertical line count LSB = 0x%02x\n",
202 tvp5150_read(c, TVP5150_VERT_LN_COUNT_LSB));
203 printk("tvp5150: Interrupt status register B = 0x%02x\n",
204 tvp5150_read(c, TVP5150_INT_STATUS_REG_B));
205 printk("tvp5150: Interrupt active register B = 0x%02x\n",
206 tvp5150_read(c, TVP5150_INT_ACTIVE_REG_B));
207 printk("tvp5150: Status register #1 = 0x%02x\n",
208 tvp5150_read(c, TVP5150_STATUS_REG_1));
209 printk("tvp5150: Status register #2 = 0x%02x\n",
210 tvp5150_read(c, TVP5150_STATUS_REG_2));
211 printk("tvp5150: Status register #3 = 0x%02x\n",
212 tvp5150_read(c, TVP5150_STATUS_REG_3));
213 printk("tvp5150: Status register #4 = 0x%02x\n",
214 tvp5150_read(c, TVP5150_STATUS_REG_4));
215 printk("tvp5150: Status register #5 = 0x%02x\n",
216 tvp5150_read(c, TVP5150_STATUS_REG_5));
217 printk("tvp5150: Closed caption data registers = 0x%02x\n",
218 tvp5150_read(c, TVP5150_CC_DATA_REG1));
219 printk("tvp5150: Closed caption data registers = 0x%02x\n",
220 tvp5150_read(c, TVP5150_CC_DATA_REG2));
221 printk("tvp5150: Closed caption data registers = 0x%02x\n",
222 tvp5150_read(c, TVP5150_CC_DATA_REG3));
223 printk("tvp5150: Closed caption data registers = 0x%02x\n",
224 tvp5150_read(c, TVP5150_CC_DATA_REG4));
225 printk("tvp5150: WSS data registers = 0x%02x\n",
226 tvp5150_read(c, TVP5150_WSS_DATA_REG1));
227 printk("tvp5150: WSS data registers = 0x%02x\n",
228 tvp5150_read(c, TVP5150_WSS_DATA_REG2));
229 printk("tvp5150: WSS data registers = 0x%02x\n",
230 tvp5150_read(c, TVP5150_WSS_DATA_REG3));
231 printk("tvp5150: WSS data registers = 0x%02x\n",
232 tvp5150_read(c, TVP5150_WSS_DATA_REG4));
233 printk("tvp5150: WSS data registers = 0x%02x\n",
234 tvp5150_read(c, TVP5150_WSS_DATA_REG5));
235 printk("tvp5150: WSS data registers = 0x%02x\n",
236 tvp5150_read(c, TVP5150_WSS_DATA_REG6));
237 printk("tvp5150: VPS data registers = 0x%02x\n",
238 tvp5150_read(c, TVP5150_VPS_DATA_REG1));
239 printk("tvp5150: VPS data registers = 0x%02x\n",
240 tvp5150_read(c, TVP5150_VPS_DATA_REG2));
241 printk("tvp5150: VPS data registers = 0x%02x\n",
242 tvp5150_read(c, TVP5150_VPS_DATA_REG3));
243 printk("tvp5150: VPS data registers = 0x%02x\n",
244 tvp5150_read(c, TVP5150_VPS_DATA_REG4));
245 printk("tvp5150: VPS data registers = 0x%02x\n",
246 tvp5150_read(c, TVP5150_VPS_DATA_REG5));
247 printk("tvp5150: VPS data registers = 0x%02x\n",
248 tvp5150_read(c, TVP5150_VPS_DATA_REG6));
249 printk("tvp5150: VPS data registers = 0x%02x\n",
250 tvp5150_read(c, TVP5150_VPS_DATA_REG7));
251 printk("tvp5150: VPS data registers = 0x%02x\n",
252 tvp5150_read(c, TVP5150_VPS_DATA_REG8));
253 printk("tvp5150: VPS data registers = 0x%02x\n",
254 tvp5150_read(c, TVP5150_VPS_DATA_REG9));
255 printk("tvp5150: VPS data registers = 0x%02x\n",
256 tvp5150_read(c, TVP5150_VPS_DATA_REG10));
257 printk("tvp5150: VPS data registers = 0x%02x\n",
258 tvp5150_read(c, TVP5150_VPS_DATA_REG11));
259 printk("tvp5150: VPS data registers = 0x%02x\n",
260 tvp5150_read(c, TVP5150_VPS_DATA_REG12));
261 printk("tvp5150: VPS data registers = 0x%02x\n",
262 tvp5150_read(c, TVP5150_VPS_DATA_REG13));
263 printk("tvp5150: VITC data registers = 0x%02x\n",
264 tvp5150_read(c, TVP5150_VITC_DATA_REG1));
265 printk("tvp5150: VITC data registers = 0x%02x\n",
266 tvp5150_read(c, TVP5150_VITC_DATA_REG2));
267 printk("tvp5150: VITC data registers = 0x%02x\n",
268 tvp5150_read(c, TVP5150_VITC_DATA_REG3));
269 printk("tvp5150: VITC data registers = 0x%02x\n",
270 tvp5150_read(c, TVP5150_VITC_DATA_REG4));
271 printk("tvp5150: VITC data registers = 0x%02x\n",
272 tvp5150_read(c, TVP5150_VITC_DATA_REG5));
273 printk("tvp5150: VITC data registers = 0x%02x\n",
274 tvp5150_read(c, TVP5150_VITC_DATA_REG6));
275 printk("tvp5150: VITC data registers = 0x%02x\n",
276 tvp5150_read(c, TVP5150_VITC_DATA_REG7));
277 printk("tvp5150: VITC data registers = 0x%02x\n",
278 tvp5150_read(c, TVP5150_VITC_DATA_REG8));
279 printk("tvp5150: VITC data registers = 0x%02x\n",
280 tvp5150_read(c, TVP5150_VITC_DATA_REG9));
281 printk("tvp5150: VBI FIFO read data = 0x%02x\n",
282 tvp5150_read(c, TVP5150_VBI_FIFO_READ_DATA));
283 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
284 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_1));
285 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
286 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_2));
287 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
288 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_3));
289 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
290 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_4));
291 printk("tvp5150: Teletext filter 1 = 0x%02x\n",
292 tvp5150_read(c, TVP5150_TELETEXT_FIL_1_5));
293 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
294 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_1));
295 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
296 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_2));
297 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
298 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_3));
299 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
300 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_4));
301 printk("tvp5150: Teletext filter 2 = 0x%02x\n",
302 tvp5150_read(c, TVP5150_TELETEXT_FIL_2_5));
303 printk("tvp5150: Teletext filter enable = 0x%02x\n",
304 tvp5150_read(c, TVP5150_TELETEXT_FIL_ENA));
305 printk("tvp5150: Interrupt status register A = 0x%02x\n",
306 tvp5150_read(c, TVP5150_INT_STATUS_REG_A));
307 printk("tvp5150: Interrupt enable register A = 0x%02x\n",
308 tvp5150_read(c, TVP5150_INT_ENABLE_REG_A));
309 printk("tvp5150: Interrupt configuration = 0x%02x\n",
310 tvp5150_read(c, TVP5150_INT_CONF));
311 printk("tvp5150: VDP configuration RAM data = 0x%02x\n",
312 tvp5150_read(c, TVP5150_VDP_CONF_RAM_DATA));
313 printk("tvp5150: Configuration RAM address low byte = 0x%02x\n",
314 tvp5150_read(c, TVP5150_CONF_RAM_ADDR_LOW));
315 printk("tvp5150: Configuration RAM address high byte = 0x%02x\n",
316 tvp5150_read(c, TVP5150_CONF_RAM_ADDR_HIGH));
317 printk("tvp5150: VDP status register = 0x%02x\n",
318 tvp5150_read(c, TVP5150_VDP_STATUS_REG));
319 printk("tvp5150: FIFO word count = 0x%02x\n",
320 tvp5150_read(c, TVP5150_FIFO_WORD_COUNT));
321 printk("tvp5150: FIFO interrupt threshold = 0x%02x\n",
322 tvp5150_read(c, TVP5150_FIFO_INT_THRESHOLD));
323 printk("tvp5150: FIFO reset = 0x%02x\n",
324 tvp5150_read(c, TVP5150_FIFO_RESET));
325 printk("tvp5150: Line number interrupt = 0x%02x\n",
326 tvp5150_read(c, TVP5150_LINE_NUMBER_INT));
327 printk("tvp5150: Pixel alignment register low byte = 0x%02x\n",
328 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_LOW));
329 printk("tvp5150: Pixel alignment register high byte = 0x%02x\n",
330 tvp5150_read(c, TVP5150_PIX_ALIGN_REG_HIGH));
331 printk("tvp5150: FIFO output control = 0x%02x\n",
332 tvp5150_read(c, TVP5150_FIFO_OUT_CTRL));
333 printk("tvp5150: Full field enable 1 = 0x%02x\n",
334 tvp5150_read(c, TVP5150_FULL_FIELD_ENA_1));
335 printk("tvp5150: Full field enable 2 = 0x%02x\n",
336 tvp5150_read(c, TVP5150_FULL_FIELD_ENA_2));
337 printk("tvp5150: Line mode registers = 0x%02x\n",
338 tvp5150_read(c, TVP5150_LINE_MODE_REG_1));
339 printk("tvp5150: Line mode registers = 0x%02x\n",
340 tvp5150_read(c, TVP5150_LINE_MODE_REG_2));
341 printk("tvp5150: Line mode registers = 0x%02x\n",
342 tvp5150_read(c, TVP5150_LINE_MODE_REG_3));
343 printk("tvp5150: Line mode registers = 0x%02x\n",
344 tvp5150_read(c, TVP5150_LINE_MODE_REG_4));
345 printk("tvp5150: Line mode registers = 0x%02x\n",
346 tvp5150_read(c, TVP5150_LINE_MODE_REG_5));
347 printk("tvp5150: Line mode registers = 0x%02x\n",
348 tvp5150_read(c, TVP5150_LINE_MODE_REG_6));
349 printk("tvp5150: Line mode registers = 0x%02x\n",
350 tvp5150_read(c, TVP5150_LINE_MODE_REG_7));
351 printk("tvp5150: Line mode registers = 0x%02x\n",
352 tvp5150_read(c, TVP5150_LINE_MODE_REG_8));
353 printk("tvp5150: Line mode registers = 0x%02x\n",
354 tvp5150_read(c, TVP5150_LINE_MODE_REG_9));
355 printk("tvp5150: Line mode registers = 0x%02x\n",
356 tvp5150_read(c, TVP5150_LINE_MODE_REG_10));
357 printk("tvp5150: Line mode registers = 0x%02x\n",
358 tvp5150_read(c, TVP5150_LINE_MODE_REG_11));
359 printk("tvp5150: Line mode registers = 0x%02x\n",
360 tvp5150_read(c, TVP5150_LINE_MODE_REG_12));
361 printk("tvp5150: Line mode registers = 0x%02x\n",
362 tvp5150_read(c, TVP5150_LINE_MODE_REG_13));
363 printk("tvp5150: Line mode registers = 0x%02x\n",
364 tvp5150_read(c, TVP5150_LINE_MODE_REG_14));
365 printk("tvp5150: Line mode registers = 0x%02x\n",
366 tvp5150_read(c, TVP5150_LINE_MODE_REG_15));
367 printk("tvp5150: Line mode registers = 0x%02x\n",
368 tvp5150_read(c, TVP5150_LINE_MODE_REG_16));
369 printk("tvp5150: Line mode registers = 0x%02x\n",
370 tvp5150_read(c, TVP5150_LINE_MODE_REG_17));
371 printk("tvp5150: Line mode registers = 0x%02x\n",
372 tvp5150_read(c, TVP5150_LINE_MODE_REG_18));
373 printk("tvp5150: Line mode registers = 0x%02x\n",
374 tvp5150_read(c, TVP5150_LINE_MODE_REG_19));
375 printk("tvp5150: Line mode registers = 0x%02x\n",
376 tvp5150_read(c, TVP5150_LINE_MODE_REG_20));
377 printk("tvp5150: Line mode registers = 0x%02x\n",
378 tvp5150_read(c, TVP5150_LINE_MODE_REG_21));
379 printk("tvp5150: Line mode registers = 0x%02x\n",
380 tvp5150_read(c, TVP5150_LINE_MODE_REG_22));
381 printk("tvp5150: Line mode registers = 0x%02x\n",
382 tvp5150_read(c, TVP5150_LINE_MODE_REG_23));
383 printk("tvp5150: Line mode registers = 0x%02x\n",
384 tvp5150_read(c, TVP5150_LINE_MODE_REG_24));
385 printk("tvp5150: Line mode registers = 0x%02x\n",
386 tvp5150_read(c, TVP5150_LINE_MODE_REG_25));
387 printk("tvp5150: Line mode registers = 0x%02x\n",
388 tvp5150_read(c, TVP5150_LINE_MODE_REG_27));
389 printk("tvp5150: Line mode registers = 0x%02x\n",
390 tvp5150_read(c, TVP5150_LINE_MODE_REG_28));
391 printk("tvp5150: Line mode registers = 0x%02x\n",
392 tvp5150_read(c, TVP5150_LINE_MODE_REG_29));
393 printk("tvp5150: Line mode registers = 0x%02x\n",
394 tvp5150_read(c, TVP5150_LINE_MODE_REG_30));
395 printk("tvp5150: Line mode registers = 0x%02x\n",
396 tvp5150_read(c, TVP5150_LINE_MODE_REG_31));
397 printk("tvp5150: Line mode registers = 0x%02x\n",
398 tvp5150_read(c, TVP5150_LINE_MODE_REG_32));
399 printk("tvp5150: Line mode registers = 0x%02x\n",
400 tvp5150_read(c, TVP5150_LINE_MODE_REG_33));
401 printk("tvp5150: Line mode registers = 0x%02x\n",
402 tvp5150_read(c, TVP5150_LINE_MODE_REG_34));
403 printk("tvp5150: Line mode registers = 0x%02x\n",
404 tvp5150_read(c, TVP5150_LINE_MODE_REG_35));
405 printk("tvp5150: Line mode registers = 0x%02x\n",
406 tvp5150_read(c, TVP5150_LINE_MODE_REG_36));
407 printk("tvp5150: Line mode registers = 0x%02x\n",
408 tvp5150_read(c, TVP5150_LINE_MODE_REG_37));
409 printk("tvp5150: Line mode registers = 0x%02x\n",
410 tvp5150_read(c, TVP5150_LINE_MODE_REG_38));
411 printk("tvp5150: Line mode registers = 0x%02x\n",
412 tvp5150_read(c, TVP5150_LINE_MODE_REG_39));
413 printk("tvp5150: Line mode registers = 0x%02x\n",
414 tvp5150_read(c, TVP5150_LINE_MODE_REG_40));
415 printk("tvp5150: Line mode registers = 0x%02x\n",
416 tvp5150_read(c, TVP5150_LINE_MODE_REG_41));
417 printk("tvp5150: Line mode registers = 0x%02x\n",
418 tvp5150_read(c, TVP5150_LINE_MODE_REG_42));
419 printk("tvp5150: Line mode registers = 0x%02x\n",
420 tvp5150_read(c, TVP5150_LINE_MODE_REG_43));
421 printk("tvp5150: Line mode registers = 0x%02x\n",
422 tvp5150_read(c, TVP5150_LINE_MODE_REG_44));
423 printk("tvp5150: Full field mode register = 0x%02x\n",
424 tvp5150_read(c, TVP5150_FULL_FIELD_MODE_REG));
425}
426
427/****************************************************************************
428 Basic functions
429 ****************************************************************************/
430enum tvp5150_input {
431 TVP5150_ANALOG_CH0 = 0,
432 TVP5150_SVIDEO = 1,
433 TVP5150_ANALOG_CH1 = 2,
434 TVP5150_BLACK_SCREEN = 8
435};
436
437static inline void tvp5150_selmux(struct i2c_client *c,
438 enum tvp5150_input input)
439{
440 struct tvp5150 *decoder = i2c_get_clientdata(c);
441
442 if (!decoder->enable)
443 input |= TVP5150_BLACK_SCREEN;
444
445 tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input);
446};
447
448static inline void tvp5150_reset(struct i2c_client *c)
449{
450 struct tvp5150 *decoder = i2c_get_clientdata(c);
451
452 tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2);
453
454 /* Automatic offset and AGC enabled */
455 tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15);
456
457 /* Normal Operation */
458// tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00);
459
460 /* Activate YCrCb output 0x9 or 0xd ? */
461 tvp5150_write(c, TVP5150_MISC_CTL, 0x6f);
462
463 /* Activates video std autodetection for all standards */
464 tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0);
465
466 /* Default format: 0x47, 4:2:2: 0x40 */
467 tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47);
468
469 tvp5150_selmux(c, decoder->input);
470
471 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c);
472 tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54);
473
474 tvp5150_write(c, 0x27, 0x20); /* ?????????? */
475
476 tvp5150_write(c, TVP5150_VIDEO_STD, 0x0); /* Auto switch */
477
478 tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8);
479 tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8);
480 tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8);
481 tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8);
482};
483
484static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
485{
486/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
487
488 switch (ctrl->id) {
489 case V4L2_CID_BRIGHTNESS:
490 ctrl->value = tvp5150_read(c, TVP5150_BRIGHT_CTL);
491 return 0;
492 case V4L2_CID_CONTRAST:
493 ctrl->value = tvp5150_read(c, TVP5150_CONTRAST_CTL);
494 return 0;
495 case V4L2_CID_SATURATION:
496 ctrl->value = tvp5150_read(c, TVP5150_SATURATION_CTL);
497 return 0;
498 case V4L2_CID_HUE:
499 ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL);
500 return 0;
501 default:
502 return -EINVAL;
503 }
504}
505
506static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl)
507{
508/* struct tvp5150 *decoder = i2c_get_clientdata(c); */
509
510 switch (ctrl->id) {
511 case V4L2_CID_BRIGHTNESS:
512 tvp5150_write(c, TVP5150_BRIGHT_CTL, ctrl->value);
513 return 0;
514 case V4L2_CID_CONTRAST:
515 tvp5150_write(c, TVP5150_CONTRAST_CTL, ctrl->value);
516 return 0;
517 case V4L2_CID_SATURATION:
518 tvp5150_write(c, TVP5150_SATURATION_CTL, ctrl->value);
519 return 0;
520 case V4L2_CID_HUE:
521 tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value);
522 return 0;
523 default:
524 return -EINVAL;
525 }
526}
527
528/****************************************************************************
529 I2C Command
530 ****************************************************************************/
531static int tvp5150_command(struct i2c_client *client,
532 unsigned int cmd, void *arg)
533{
534 struct tvp5150 *decoder = i2c_get_clientdata(client);
535
536 switch (cmd) {
537
538 case 0:
539 case DECODER_INIT:
540 tvp5150_reset(client);
541 break;
542
543 case DECODER_DUMP:
544 dump_reg(client);
545 break;
546
547 case DECODER_GET_CAPABILITIES:
548 {
549 struct video_decoder_capability *cap = arg;
550
551 cap->flags = VIDEO_DECODER_PAL |
552 VIDEO_DECODER_NTSC |
553 VIDEO_DECODER_SECAM |
554 VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
555 cap->inputs = 3;
556 cap->outputs = 1;
557 break;
558 }
559 case DECODER_GET_STATUS:
560 {
561 break;
562 }
563
564 case DECODER_SET_GPIO:
565 break;
566
567 case DECODER_SET_VBI_BYPASS:
568 break;
569
570 case DECODER_SET_NORM:
571 {
572 int *iarg = arg;
573
574 switch (*iarg) {
575
576 case VIDEO_MODE_NTSC:
577 break;
578
579 case VIDEO_MODE_PAL:
580 break;
581
582 case VIDEO_MODE_SECAM:
583 break;
584
585 case VIDEO_MODE_AUTO:
586 break;
587
588 default:
589 return -EINVAL;
590
591 }
592 decoder->norm = *iarg;
593 break;
594 }
595 case DECODER_SET_INPUT:
596 {
597 int *iarg = arg;
598 if (*iarg < 0 || *iarg > 3) {
599 return -EINVAL;
600 }
601
602 decoder->input = *iarg;
603 tvp5150_selmux(client, decoder->input);
604
605 break;
606 }
607 case DECODER_SET_OUTPUT:
608 {
609 int *iarg = arg;
610
611 /* not much choice of outputs */
612 if (*iarg != 0) {
613 return -EINVAL;
614 }
615 break;
616 }
617 case DECODER_ENABLE_OUTPUT:
618 {
619 int *iarg = arg;
620
621 decoder->enable = (*iarg != 0);
622
623 tvp5150_selmux(client, decoder->input);
624
625 break;
626 }
627 case VIDIOC_QUERYCTRL:
628 {
629 struct v4l2_queryctrl *qc = arg;
630 u8 i, n;
631
632 dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL");
633
634 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
635 for (i = 0; i < n; i++)
636 if (qc->id && qc->id == tvp5150_qctrl[i].id) {
637 memcpy(qc, &(tvp5150_qctrl[i]),
638 sizeof(*qc));
639 return 0;
640 }
641
642 return -EINVAL;
643 }
644 case VIDIOC_G_CTRL:
645 {
646 struct v4l2_control *ctrl = arg;
647 dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL");
648
649 return tvp5150_get_ctrl(client, ctrl);
650 }
651 case VIDIOC_S_CTRL_OLD: /* ??? */
652 case VIDIOC_S_CTRL:
653 {
654 struct v4l2_control *ctrl = arg;
655 u8 i, n;
656 dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL");
657 n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]);
658 for (i = 0; i < n; i++)
659 if (ctrl->id == tvp5150_qctrl[i].id) {
660 if (ctrl->value <
661 tvp5150_qctrl[i].minimum
662 || ctrl->value >
663 tvp5150_qctrl[i].maximum)
664 return -ERANGE;
665 dprintk(1,
666 KERN_DEBUG
667 "VIDIOC_S_CTRL: id=%d, value=%d",
668 ctrl->id, ctrl->value);
669 return tvp5150_set_ctrl(client, ctrl);
670 }
671 return -EINVAL;
672 }
673
674 case DECODER_SET_PICTURE:
675 {
676 struct video_picture *pic = arg;
677 if (decoder->bright != pic->brightness) {
678 /* We want 0 to 255 we get 0-65535 */
679 decoder->bright = pic->brightness;
680 tvp5150_write(client, TVP5150_BRIGHT_CTL,
681 decoder->bright >> 8);
682 }
683 if (decoder->contrast != pic->contrast) {
684 /* We want 0 to 255 we get 0-65535 */
685 decoder->contrast = pic->contrast;
686 tvp5150_write(client, TVP5150_CONTRAST_CTL,
687 decoder->contrast >> 8);
688 }
689 if (decoder->sat != pic->colour) {
690 /* We want 0 to 255 we get 0-65535 */
691 decoder->sat = pic->colour;
692 tvp5150_write(client, TVP5150_SATURATION_CTL,
693 decoder->contrast >> 8);
694 }
695 if (decoder->hue != pic->hue) {
696 /* We want -128 to 127 we get 0-65535 */
697 decoder->hue = pic->hue;
698 tvp5150_write(client, TVP5150_HUE_CTL,
699 (decoder->hue - 32768) >> 8);
700 }
701 break;
702 }
703 default:
704 return -EINVAL;
705 }
706
707 return 0;
708}
709
710/****************************************************************************
711 I2C Client & Driver
712 ****************************************************************************/
713static struct i2c_driver driver;
714
715static struct i2c_client client_template = {
716 .name = "(unset)",
717 .flags = I2C_CLIENT_ALLOW_USE,
718 .driver = &driver,
719};
720
721static int tvp5150_detect_client(struct i2c_adapter *adapter,
722 int address, int kind)
723{
724 struct i2c_client *client;
725 struct tvp5150 *core;
726 int rv;
727
728 dprintk(1,
729 KERN_INFO
730 "tvp5150.c: detecting tvp5150 client on address 0x%x\n",
731 address << 1);
732
733 client_template.adapter = adapter;
734 client_template.addr = address;
735
736 /* Check if the adapter supports the needed features */
737 if (!i2c_check_functionality
738 (adapter,
739 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
740 return 0;
741
742 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
743 if (client == 0)
744 return -ENOMEM;
745 memcpy(client, &client_template, sizeof(struct i2c_client));
746
747 core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL);
748 if (core == 0) {
749 kfree(client);
750 return -ENOMEM;
751 }
752 memset(core, 0, sizeof(struct tvp5150));
753 i2c_set_clientdata(client, core);
754
755 rv = i2c_attach_client(client);
756
757 core->norm = VIDEO_MODE_AUTO;
758 core->input = 2;
759 core->enable = 1;
760 core->bright = 32768;
761 core->contrast = 32768;
762 core->hue = 32768;
763 core->sat = 32768;
764
765 if (rv) {
766 kfree(client);
767 kfree(core);
768 return rv;
769 }
770
771 if (debug > 1)
772 dump_reg(client);
773
774 return 0;
775}
776
777static int tvp5150_attach_adapter(struct i2c_adapter *adapter)
778{
779 dprintk(1,
780 KERN_INFO
781 "tvp5150.c: starting probe for adapter %s (0x%x)\n",
782 adapter->name, adapter->id);
783 return i2c_probe(adapter, &addr_data, &tvp5150_detect_client);
784}
785
786static int tvp5150_detach_client(struct i2c_client *client)
787{
788 struct tvp5150 *decoder = i2c_get_clientdata(client);
789 int err;
790
791 err = i2c_detach_client(client);
792 if (err) {
793 return err;
794 }
795
796 kfree(decoder);
797 kfree(client);
798
799 return 0;
800}
801
802/* ----------------------------------------------------------------------- */
803
804static struct i2c_driver driver = {
805 .owner = THIS_MODULE,
806 .name = "tvp5150",
807
808 /* FIXME */
809 .id = I2C_DRIVERID_SAA7110,
810 .flags = I2C_DF_NOTIFY,
811
812 .attach_adapter = tvp5150_attach_adapter,
813 .detach_client = tvp5150_detach_client,
814
815 .command = tvp5150_command,
816};
817
818static int __init tvp5150_init(void)
819{
820 return i2c_add_driver(&driver);
821}
822
823static void __exit tvp5150_exit(void)
824{
825 i2c_del_driver(&driver);
826}
827
828module_init(tvp5150_init);
829module_exit(tvp5150_exit);
diff --git a/drivers/media/video/tvp5150_reg.h b/drivers/media/video/tvp5150_reg.h
new file mode 100644
index 000000000000..cd45c1ded786
--- /dev/null
+++ b/drivers/media/video/tvp5150_reg.h
@@ -0,0 +1,173 @@
1#define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */
2#define TVP5150_ANAL_CHL_CTL 0x01 /* Analog channel controls */
3#define TVP5150_OP_MODE_CTL 0x02 /* Operation mode controls */
4#define TVP5150_MISC_CTL 0x03 /* Miscellaneous controls */
5#define TVP5150_AUTOSW_MSK 0x04 /* Autoswitch mask: TVP5150A / TVP5150AM */
6
7/* Reserved 05h */
8
9#define TVP5150_COLOR_KIL_THSH_CTL 0x06 /* Color killer threshold control */
10#define TVP5150_LUMA_PROC_CTL_1 0x07 /* Luminance processing control #1 */
11#define TVP5150_LUMA_PROC_CTL_2 0x08 /* Luminance processing control #2 */
12#define TVP5150_BRIGHT_CTL 0x09 /* Brightness control */
13#define TVP5150_SATURATION_CTL 0x0a /* Color saturation control */
14#define TVP5150_HUE_CTL 0x0b /* Hue control */
15#define TVP5150_CONTRAST_CTL 0x0c /* Contrast control */
16#define TVP5150_DATA_RATE_SEL 0x0d /* Outputs and data rates select */
17#define TVP5150_LUMA_PROC_CTL_3 0x0e /* Luminance processing control #3 */
18#define TVP5150_CONF_SHARED_PIN 0x0f /* Configuration shared pins */
19
20/* Reserved 10h */
21
22#define TVP5150_ACT_VD_CROP_ST_MSB 0x11 /* Active video cropping start MSB */
23#define TVP5150_ACT_VD_CROP_ST_LSB 0x12 /* Active video cropping start LSB */
24#define TVP5150_ACT_VD_CROP_STP_MSB 0x13 /* Active video cropping stop MSB */
25#define TVP5150_ACT_VD_CROP_STP_LSB 0x14 /* Active video cropping stop LSB */
26#define TVP5150_GENLOCK 0x15 /* Genlock/RTC */
27#define TVP5150_HORIZ_SYNC_START 0x16 /* Horizontal sync start */
28
29/* Reserved 17h */
30
31#define TVP5150_VERT_BLANKING_START 0x18 /* Vertical blanking start */
32#define TVP5150_VERT_BLANKING_STOP 0x19 /* Vertical blanking stop */
33#define TVP5150_CHROMA_PROC_CTL_1 0x1a /* Chrominance processing control #1 */
34#define TVP5150_CHROMA_PROC_CTL_2 0x1b /* Chrominance processing control #2 */
35#define TVP5150_INT_RESET_REG_B 0x1c /* Interrupt reset register B */
36#define TVP5150_INT_ENABLE_REG_B 0x1d /* Interrupt enable register B */
37#define TVP5150_INTT_CONFIG_REG_B 0x1e /* Interrupt configuration register B */
38
39/* Reserved 1Fh-27h */
40
41#define TVP5150_VIDEO_STD 0x28 /* Video standard */
42
43/* Reserved 29h-2bh */
44
45#define TVP5150_CB_GAIN_FACT 0x2c /* Cb gain factor */
46#define TVP5150_CR_GAIN_FACTOR 0x2d /* Cr gain factor */
47#define TVP5150_MACROVISION_ON_CTR 0x2e /* Macrovision on counter */
48#define TVP5150_MACROVISION_OFF_CTR 0x2f /* Macrovision off counter */
49#define TVP5150_REV_SELECT 0x30 /* revision select (TVP5150AM1 only) */
50
51/* Reserved 31h-7Fh */
52
53#define TVP5150_MSB_DEV_ID 0x80 /* MSB of device ID */
54#define TVP5150_LSB_DEV_ID 0x81 /* LSB of device ID */
55#define TVP5150_ROM_MAJOR_VER 0x82 /* ROM major version */
56#define TVP5150_ROM_MINOR_VER 0x83 /* ROM minor version */
57#define TVP5150_VERT_LN_COUNT_MSB 0x84 /* Vertical line count MSB */
58#define TVP5150_VERT_LN_COUNT_LSB 0x85 /* Vertical line count LSB */
59#define TVP5150_INT_STATUS_REG_B 0x86 /* Interrupt status register B */
60#define TVP5150_INT_ACTIVE_REG_B 0x87 /* Interrupt active register B */
61#define TVP5150_STATUS_REG_1 0x88 /* Status register #1 */
62#define TVP5150_STATUS_REG_2 0x89 /* Status register #2 */
63#define TVP5150_STATUS_REG_3 0x8a /* Status register #3 */
64#define TVP5150_STATUS_REG_4 0x8b /* Status register #4 */
65#define TVP5150_STATUS_REG_5 0x8c /* Status register #5 */
66/* Reserved 8Dh-8Fh */
67#define TVP5150_CC_DATA_REG1 0x90 /* Closed caption data registers */
68#define TVP5150_CC_DATA_REG2 0x91 /* Closed caption data registers */
69#define TVP5150_CC_DATA_REG3 0x92 /* Closed caption data registers */
70#define TVP5150_CC_DATA_REG4 0x93 /* Closed caption data registers */
71#define TVP5150_WSS_DATA_REG1 0X94 /* WSS data registers */
72#define TVP5150_WSS_DATA_REG2 0X95 /* WSS data registers */
73#define TVP5150_WSS_DATA_REG3 0X96 /* WSS data registers */
74#define TVP5150_WSS_DATA_REG4 0X97 /* WSS data registers */
75#define TVP5150_WSS_DATA_REG5 0X98 /* WSS data registers */
76#define TVP5150_WSS_DATA_REG6 0X99 /* WSS data registers */
77#define TVP5150_VPS_DATA_REG1 0x9a /* VPS data registers */
78#define TVP5150_VPS_DATA_REG2 0x9b /* VPS data registers */
79#define TVP5150_VPS_DATA_REG3 0x9c /* VPS data registers */
80#define TVP5150_VPS_DATA_REG4 0x9d /* VPS data registers */
81#define TVP5150_VPS_DATA_REG5 0x9e /* VPS data registers */
82#define TVP5150_VPS_DATA_REG6 0x9f /* VPS data registers */
83#define TVP5150_VPS_DATA_REG7 0xa0 /* VPS data registers */
84#define TVP5150_VPS_DATA_REG8 0xa1 /* VPS data registers */
85#define TVP5150_VPS_DATA_REG9 0xa2 /* VPS data registers */
86#define TVP5150_VPS_DATA_REG10 0xa3 /* VPS data registers */
87#define TVP5150_VPS_DATA_REG11 0xa4 /* VPS data registers */
88#define TVP5150_VPS_DATA_REG12 0xa5 /* VPS data registers */
89#define TVP5150_VPS_DATA_REG13 0xa6 /* VPS data registers */
90#define TVP5150_VITC_DATA_REG1 0xa7 /* VITC data registers */
91#define TVP5150_VITC_DATA_REG2 0xa8 /* VITC data registers */
92#define TVP5150_VITC_DATA_REG3 0xa9 /* VITC data registers */
93#define TVP5150_VITC_DATA_REG4 0xaa /* VITC data registers */
94#define TVP5150_VITC_DATA_REG5 0xab /* VITC data registers */
95#define TVP5150_VITC_DATA_REG6 0xac /* VITC data registers */
96#define TVP5150_VITC_DATA_REG7 0xad /* VITC data registers */
97#define TVP5150_VITC_DATA_REG8 0xae /* VITC data registers */
98#define TVP5150_VITC_DATA_REG9 0xaf /* VITC data registers */
99#define TVP5150_VBI_FIFO_READ_DATA 0xb0 /* VBI FIFO read data */
100#define TVP5150_TELETEXT_FIL_1_1 0xb1 /* Teletext filter 1 */
101#define TVP5150_TELETEXT_FIL_1_2 0xb2 /* Teletext filter 1 */
102#define TVP5150_TELETEXT_FIL_1_3 0xb3 /* Teletext filter 1 */
103#define TVP5150_TELETEXT_FIL_1_4 0xb4 /* Teletext filter 1 */
104#define TVP5150_TELETEXT_FIL_1_5 0xb5 /* Teletext filter 1 */
105#define TVP5150_TELETEXT_FIL_2_1 0xb6 /* Teletext filter 2 */
106#define TVP5150_TELETEXT_FIL_2_2 0xb7 /* Teletext filter 2 */
107#define TVP5150_TELETEXT_FIL_2_3 0xb8 /* Teletext filter 2 */
108#define TVP5150_TELETEXT_FIL_2_4 0xb9 /* Teletext filter 2 */
109#define TVP5150_TELETEXT_FIL_2_5 0xba /* Teletext filter 2 */
110#define TVP5150_TELETEXT_FIL_ENA 0xbb /* Teletext filter enable */
111/* Reserved BCh-BFh */
112#define TVP5150_INT_STATUS_REG_A 0xc0 /* Interrupt status register A */
113#define TVP5150_INT_ENABLE_REG_A 0xc1 /* Interrupt enable register A */
114#define TVP5150_INT_CONF 0xc2 /* Interrupt configuration */
115#define TVP5150_VDP_CONF_RAM_DATA 0xc3 /* VDP configuration RAM data */
116#define TVP5150_CONF_RAM_ADDR_LOW 0xc4 /* Configuration RAM address low byte */
117#define TVP5150_CONF_RAM_ADDR_HIGH 0xc5 /* Configuration RAM address high byte */
118#define TVP5150_VDP_STATUS_REG 0xc6 /* VDP status register */
119#define TVP5150_FIFO_WORD_COUNT 0xc7 /* FIFO word count */
120#define TVP5150_FIFO_INT_THRESHOLD 0xc8 /* FIFO interrupt threshold */
121#define TVP5150_FIFO_RESET 0xc9 /* FIFO reset */
122#define TVP5150_LINE_NUMBER_INT 0xca /* Line number interrupt */
123#define TVP5150_PIX_ALIGN_REG_LOW 0xcb /* Pixel alignment register low byte */
124#define TVP5150_PIX_ALIGN_REG_HIGH 0xcc /* Pixel alignment register high byte */
125#define TVP5150_FIFO_OUT_CTRL 0xcd /* FIFO output control */
126/* Reserved CEh */
127#define TVP5150_FULL_FIELD_ENA_1 0xcf /* Full field enable 1 */
128#define TVP5150_FULL_FIELD_ENA_2 0xd0 /* Full field enable 2 */
129#define TVP5150_LINE_MODE_REG_1 0xd1 /* Line mode registers */
130#define TVP5150_LINE_MODE_REG_2 0xd2 /* Line mode registers */
131#define TVP5150_LINE_MODE_REG_3 0xd3 /* Line mode registers */
132#define TVP5150_LINE_MODE_REG_4 0xd4 /* Line mode registers */
133#define TVP5150_LINE_MODE_REG_5 0xd5 /* Line mode registers */
134#define TVP5150_LINE_MODE_REG_6 0xd6 /* Line mode registers */
135#define TVP5150_LINE_MODE_REG_7 0xd7 /* Line mode registers */
136#define TVP5150_LINE_MODE_REG_8 0xd8 /* Line mode registers */
137#define TVP5150_LINE_MODE_REG_9 0xd9 /* Line mode registers */
138#define TVP5150_LINE_MODE_REG_10 0xda /* Line mode registers */
139#define TVP5150_LINE_MODE_REG_11 0xdb /* Line mode registers */
140#define TVP5150_LINE_MODE_REG_12 0xdc /* Line mode registers */
141#define TVP5150_LINE_MODE_REG_13 0xdd /* Line mode registers */
142#define TVP5150_LINE_MODE_REG_14 0xde /* Line mode registers */
143#define TVP5150_LINE_MODE_REG_15 0xdf /* Line mode registers */
144#define TVP5150_LINE_MODE_REG_16 0xe0 /* Line mode registers */
145#define TVP5150_LINE_MODE_REG_17 0xe1 /* Line mode registers */
146#define TVP5150_LINE_MODE_REG_18 0xe2 /* Line mode registers */
147#define TVP5150_LINE_MODE_REG_19 0xe3 /* Line mode registers */
148#define TVP5150_LINE_MODE_REG_20 0xe4 /* Line mode registers */
149#define TVP5150_LINE_MODE_REG_21 0xe5 /* Line mode registers */
150#define TVP5150_LINE_MODE_REG_22 0xe6 /* Line mode registers */
151#define TVP5150_LINE_MODE_REG_23 0xe7 /* Line mode registers */
152#define TVP5150_LINE_MODE_REG_24 0xe8 /* Line mode registers */
153#define TVP5150_LINE_MODE_REG_25 0xe9 /* Line mode registers */
154#define TVP5150_LINE_MODE_REG_27 0xea /* Line mode registers */
155#define TVP5150_LINE_MODE_REG_28 0xeb /* Line mode registers */
156#define TVP5150_LINE_MODE_REG_29 0xec /* Line mode registers */
157#define TVP5150_LINE_MODE_REG_30 0xed /* Line mode registers */
158#define TVP5150_LINE_MODE_REG_31 0xee /* Line mode registers */
159#define TVP5150_LINE_MODE_REG_32 0xef /* Line mode registers */
160#define TVP5150_LINE_MODE_REG_33 0xf0 /* Line mode registers */
161#define TVP5150_LINE_MODE_REG_34 0xf1 /* Line mode registers */
162#define TVP5150_LINE_MODE_REG_35 0xf2 /* Line mode registers */
163#define TVP5150_LINE_MODE_REG_36 0xf3 /* Line mode registers */
164#define TVP5150_LINE_MODE_REG_37 0xf4 /* Line mode registers */
165#define TVP5150_LINE_MODE_REG_38 0xf5 /* Line mode registers */
166#define TVP5150_LINE_MODE_REG_39 0xf6 /* Line mode registers */
167#define TVP5150_LINE_MODE_REG_40 0xf7 /* Line mode registers */
168#define TVP5150_LINE_MODE_REG_41 0xf8 /* Line mode registers */
169#define TVP5150_LINE_MODE_REG_42 0xf9 /* Line mode registers */
170#define TVP5150_LINE_MODE_REG_43 0xfa /* Line mode registers */
171#define TVP5150_LINE_MODE_REG_44 0xfb /* Line mode registers */
172#define TVP5150_FULL_FIELD_MODE_REG 0xfc /* Full field mode register */
173/* Reserved FDh-FFh */
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 59bb71381a1b..4134549d11a8 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -708,7 +708,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
708 } 708 }
709 case VIDIOCGFREQ: /* get frequency */ 709 case VIDIOCGFREQ: /* get frequency */
710 { 710 {
711 int *freq = arg; 711 unsigned long *freq = arg;
712 712
713 freq2.tuner = 0; 713 freq2.tuner = 0;
714 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); 714 err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -720,7 +720,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
720 } 720 }
721 case VIDIOCSFREQ: /* set frequency */ 721 case VIDIOCSFREQ: /* set frequency */
722 { 722 {
723 int *freq = arg; 723 unsigned long *freq = arg;
724 724
725 freq2.tuner = 0; 725 freq2.tuner = 0;
726 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2); 726 drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
@@ -960,7 +960,7 @@ v4l_compat_translate_ioctl(struct inode *inode,
960 fmt->start[1] = fmt2->fmt.vbi.start[1]; 960 fmt->start[1] = fmt2->fmt.vbi.start[1];
961 fmt->count[1] = fmt2->fmt.vbi.count[1]; 961 fmt->count[1] = fmt2->fmt.vbi.count[1];
962 fmt->flags = fmt2->fmt.vbi.flags & 0x03; 962 fmt->flags = fmt2->fmt.vbi.flags & 0x03;
963 break; 963 break;
964 } 964 }
965 case VIDIOCSVBIFMT: 965 case VIDIOCSVBIFMT:
966 { 966 {
@@ -1006,10 +1006,8 @@ v4l_compat_translate_ioctl(struct inode *inode,
1006 break; 1006 break;
1007 } 1007 }
1008 1008
1009 if (cap2) 1009 kfree(cap2);
1010 kfree(cap2); 1010 kfree(fmt2);
1011 if (fmt2)
1012 kfree(fmt2);
1013 return err; 1011 return err;
1014} 1012}
1015 1013
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
index 574b8e36f3c6..acfd3a103f35 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -147,7 +147,7 @@ int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
147 data,size,dma->nr_pages); 147 data,size,dma->nr_pages);
148 148
149 down_read(&current->mm->mmap_sem); 149 down_read(&current->mm->mmap_sem);
150 err = get_user_pages(current,current->mm, 150 err = get_user_pages(current,current->mm,
151 data & PAGE_MASK, dma->nr_pages, 151 data & PAGE_MASK, dma->nr_pages,
152 rw == READ, 1, /* force */ 152 rw == READ, 1, /* force */
153 dma->pages, NULL); 153 dma->pages, NULL);
@@ -750,9 +750,9 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
750{ 750{
751 enum v4l2_field field; 751 enum v4l2_field field;
752 unsigned long flags; 752 unsigned long flags;
753 int retval; 753 int retval;
754 754
755 /* setup stuff */ 755 /* setup stuff */
756 retval = -ENOMEM; 756 retval = -ENOMEM;
757 q->read_buf = videobuf_alloc(q->msize); 757 q->read_buf = videobuf_alloc(q->msize);
758 if (NULL == q->read_buf) 758 if (NULL == q->read_buf)
@@ -760,18 +760,18 @@ videobuf_read_zerocopy(struct videobuf_queue *q, char __user *data,
760 760
761 q->read_buf->memory = V4L2_MEMORY_USERPTR; 761 q->read_buf->memory = V4L2_MEMORY_USERPTR;
762 q->read_buf->baddr = (unsigned long)data; 762 q->read_buf->baddr = (unsigned long)data;
763 q->read_buf->bsize = count; 763 q->read_buf->bsize = count;
764 field = videobuf_next_field(q); 764 field = videobuf_next_field(q);
765 retval = q->ops->buf_prepare(q,q->read_buf,field); 765 retval = q->ops->buf_prepare(q,q->read_buf,field);
766 if (0 != retval) 766 if (0 != retval)
767 goto done; 767 goto done;
768 768
769 /* start capture & wait */ 769 /* start capture & wait */
770 spin_lock_irqsave(q->irqlock,flags); 770 spin_lock_irqsave(q->irqlock,flags);
771 q->ops->buf_queue(q,q->read_buf); 771 q->ops->buf_queue(q,q->read_buf);
772 spin_unlock_irqrestore(q->irqlock,flags); 772 spin_unlock_irqrestore(q->irqlock,flags);
773 retval = videobuf_waiton(q->read_buf,0,0); 773 retval = videobuf_waiton(q->read_buf,0,0);
774 if (0 == retval) { 774 if (0 == retval) {
775 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); 775 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
776 if (STATE_ERROR == q->read_buf->state) 776 if (STATE_ERROR == q->read_buf->state)
777 retval = -EIO; 777 retval = -EIO;
@@ -828,7 +828,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
828 } 828 }
829 829
830 /* wait until capture is done */ 830 /* wait until capture is done */
831 retval = videobuf_waiton(q->read_buf, nonblocking, 1); 831 retval = videobuf_waiton(q->read_buf, nonblocking, 1);
832 if (0 != retval) 832 if (0 != retval)
833 goto done; 833 goto done;
834 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); 834 videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
@@ -1096,7 +1096,7 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
1096 1096
1097 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n", 1097 dprintk(3,"nopage: fault @ %08lx [vma %08lx-%08lx]\n",
1098 vaddr,vma->vm_start,vma->vm_end); 1098 vaddr,vma->vm_start,vma->vm_end);
1099 if (vaddr > vma->vm_end) 1099 if (vaddr > vma->vm_end)
1100 return NOPAGE_SIGBUS; 1100 return NOPAGE_SIGBUS;
1101 page = alloc_page(GFP_USER); 1101 page = alloc_page(GFP_USER);
1102 if (!page) 1102 if (!page)
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
index c9d5f1a873cc..839db622040d 100644
--- a/drivers/media/video/videocodec.c
+++ b/drivers/media/video/videocodec.c
@@ -353,8 +353,7 @@ videocodec_build_table (void)
353 dprintk(3, "videocodec_build table: %d entries, %d bytes\n", i, 353 dprintk(3, "videocodec_build table: %d entries, %d bytes\n", i,
354 size); 354 size);
355 355
356 if (videocodec_buf) 356 kfree(videocodec_buf);
357 kfree(videocodec_buf);
358 videocodec_buf = (char *) kmalloc(size, GFP_KERNEL); 357 videocodec_buf = (char *) kmalloc(size, GFP_KERNEL);
359 358
360 i = 0; 359 i = 0;
@@ -471,8 +470,7 @@ videocodec_exit (void)
471{ 470{
472#ifdef CONFIG_PROC_FS 471#ifdef CONFIG_PROC_FS
473 remove_proc_entry("videocodecs", NULL); 472 remove_proc_entry("videocodecs", NULL);
474 if (videocodec_buf) 473 kfree(videocodec_buf);
475 kfree(videocodec_buf);
476#endif 474#endif
477} 475}
478 476
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 06df15f75de9..83c49f9610d0 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -215,8 +215,7 @@ video_usercopy(struct inode *inode, struct file *file,
215 } 215 }
216 216
217out: 217out:
218 if (mbuf) 218 kfree(mbuf);
219 kfree(mbuf);
220 return err; 219 return err;
221} 220}
222 221
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index ed4394e854ab..71b28e9e0850 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -12,15 +12,11 @@
12 12
13/* 13/*
14 * TODO: 14 * TODO:
15 * - remove "hacks" from memory allocation code and implement nopage() 15 * - remove "mark pages reserved-hacks" from memory allocation code
16 * and implement nopage()
16 * - check decimation, calculating and reporting image size when 17 * - check decimation, calculating and reporting image size when
17 * using decimation 18 * using decimation
18 * - check vino_acquire_input(), vino_set_input() and channel 19 * - implement read(), user mode buffers and overlay (?)
19 * ownership handling
20 * - report VINO error-interrupts via ioctls ?
21 * - implement picture controls (all implemented?)
22 * - use macros for boolean values (?)
23 * - implement user mode buffers and overlay (?)
24 */ 20 */
25 21
26#include <linux/init.h> 22#include <linux/init.h>
@@ -60,18 +56,16 @@
60 * debug info. 56 * debug info.
61 * Note that the debug output also slows down the driver significantly */ 57 * Note that the debug output also slows down the driver significantly */
62// #define VINO_DEBUG 58// #define VINO_DEBUG
59// #define VINO_DEBUG_INT
63 60
64#define VINO_MODULE_VERSION "0.0.3" 61#define VINO_MODULE_VERSION "0.0.5"
65#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 3) 62#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 5)
66 63
67MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver"); 64MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver");
68MODULE_VERSION(VINO_MODULE_VERSION); 65MODULE_VERSION(VINO_MODULE_VERSION);
69MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>"); 66MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
70MODULE_LICENSE("GPL"); 67MODULE_LICENSE("GPL");
71 68
72#define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags))
73#define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags))
74
75#ifdef VINO_DEBUG 69#ifdef VINO_DEBUG
76#define dprintk(x...) printk("VINO: " x); 70#define dprintk(x...) printk("VINO: " x);
77#else 71#else
@@ -91,15 +85,16 @@ MODULE_LICENSE("GPL");
91#define VINO_MIN_HEIGHT 32 85#define VINO_MIN_HEIGHT 32
92 86
93#define VINO_CLIPPING_START_ODD_D1 1 87#define VINO_CLIPPING_START_ODD_D1 1
94#define VINO_CLIPPING_START_ODD_PAL 1 88#define VINO_CLIPPING_START_ODD_PAL 15
95#define VINO_CLIPPING_START_ODD_NTSC 1 89#define VINO_CLIPPING_START_ODD_NTSC 12
96 90
97#define VINO_CLIPPING_START_EVEN_D1 2 91#define VINO_CLIPPING_START_EVEN_D1 2
98#define VINO_CLIPPING_START_EVEN_PAL 2 92#define VINO_CLIPPING_START_EVEN_PAL 15
99#define VINO_CLIPPING_START_EVEN_NTSC 2 93#define VINO_CLIPPING_START_EVEN_NTSC 12
100 94
101#define VINO_INPUT_CHANNEL_COUNT 3 95#define VINO_INPUT_CHANNEL_COUNT 3
102 96
97/* the number is the index for vino_inputs */
103#define VINO_INPUT_NONE -1 98#define VINO_INPUT_NONE -1
104#define VINO_INPUT_COMPOSITE 0 99#define VINO_INPUT_COMPOSITE 0
105#define VINO_INPUT_SVIDEO 1 100#define VINO_INPUT_SVIDEO 1
@@ -107,15 +102,13 @@ MODULE_LICENSE("GPL");
107 102
108#define VINO_PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE) 103#define VINO_PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE)
109 104
110#define VINO_FIFO_THRESHOLD_DEFAULT 512 105#define VINO_FIFO_THRESHOLD_DEFAULT 16
111 106
112/*#define VINO_FRAMEBUFFER_SIZE (VINO_PAL_WIDTH * VINO_PAL_HEIGHT * 4 \
113 + 2 * PAGE_SIZE)*/
114#define VINO_FRAMEBUFFER_SIZE ((VINO_PAL_WIDTH \ 107#define VINO_FRAMEBUFFER_SIZE ((VINO_PAL_WIDTH \
115 * VINO_PAL_HEIGHT * 4 \ 108 * VINO_PAL_HEIGHT * 4 \
116 + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1)) 109 + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1))
117 110
118#define VINO_FRAMEBUFFER_MAX_COUNT 8 111#define VINO_FRAMEBUFFER_COUNT_MAX 8
119 112
120#define VINO_FRAMEBUFFER_UNUSED 0 113#define VINO_FRAMEBUFFER_UNUSED 0
121#define VINO_FRAMEBUFFER_IN_USE 1 114#define VINO_FRAMEBUFFER_IN_USE 1
@@ -131,24 +124,27 @@ MODULE_LICENSE("GPL");
131#define VINO_DUMMY_DESC_COUNT 4 124#define VINO_DUMMY_DESC_COUNT 4
132#define VINO_DESC_FETCH_DELAY 5 /* microseconds */ 125#define VINO_DESC_FETCH_DELAY 5 /* microseconds */
133 126
127#define VINO_MAX_FRAME_SKIP_COUNT 128
128
134/* the number is the index for vino_data_formats */ 129/* the number is the index for vino_data_formats */
135#define VINO_DATA_FMT_NONE -1 130#define VINO_DATA_FMT_NONE -1
136#define VINO_DATA_FMT_GREY 0 131#define VINO_DATA_FMT_GREY 0
137#define VINO_DATA_FMT_RGB332 1 132#define VINO_DATA_FMT_RGB332 1
138#define VINO_DATA_FMT_RGB32 2 133#define VINO_DATA_FMT_RGB32 2
139#define VINO_DATA_FMT_YUV 3 134#define VINO_DATA_FMT_YUV 3
140//#define VINO_DATA_FMT_RGB24 4
141 135
142#define VINO_DATA_FMT_COUNT 4 136#define VINO_DATA_FMT_COUNT 4
143 137
138/* the number is the index for vino_data_norms */
144#define VINO_DATA_NORM_NONE -1 139#define VINO_DATA_NORM_NONE -1
145#define VINO_DATA_NORM_NTSC 0 140#define VINO_DATA_NORM_NTSC 0
146#define VINO_DATA_NORM_PAL 1 141#define VINO_DATA_NORM_PAL 1
147#define VINO_DATA_NORM_SECAM 2 142#define VINO_DATA_NORM_SECAM 2
148#define VINO_DATA_NORM_D1 3 143#define VINO_DATA_NORM_D1 3
149/* The following is a special entry that can be used to 144/* The following are special entries that can be used to
150 * autodetect the norm. */ 145 * autodetect the norm. */
151#define VINO_DATA_NORM_AUTO 0xff 146#define VINO_DATA_NORM_AUTO 0xfe
147#define VINO_DATA_NORM_AUTO_EXT 0xff
152 148
153#define VINO_DATA_NORM_COUNT 4 149#define VINO_DATA_NORM_COUNT 4
154 150
@@ -232,7 +228,7 @@ struct vino_framebuffer_fifo {
232 unsigned int head; 228 unsigned int head;
233 unsigned int tail; 229 unsigned int tail;
234 230
235 unsigned int data[VINO_FRAMEBUFFER_MAX_COUNT]; 231 unsigned int data[VINO_FRAMEBUFFER_COUNT_MAX];
236}; 232};
237 233
238struct vino_framebuffer_queue { 234struct vino_framebuffer_queue {
@@ -246,13 +242,20 @@ struct vino_framebuffer_queue {
246 struct vino_framebuffer_fifo in; 242 struct vino_framebuffer_fifo in;
247 struct vino_framebuffer_fifo out; 243 struct vino_framebuffer_fifo out;
248 244
249 struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_MAX_COUNT]; 245 struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_COUNT_MAX];
250 246
251 spinlock_t queue_lock; 247 spinlock_t queue_lock;
252 struct semaphore queue_sem; 248 struct semaphore queue_sem;
253 wait_queue_head_t frame_wait_queue; 249 wait_queue_head_t frame_wait_queue;
254}; 250};
255 251
252struct vino_interrupt_data {
253 struct timeval timestamp;
254 unsigned int frame_counter;
255 unsigned int skip_count;
256 unsigned int skip;
257};
258
256struct vino_channel_settings { 259struct vino_channel_settings {
257 unsigned int channel; 260 unsigned int channel;
258 261
@@ -285,6 +288,8 @@ struct vino_channel_settings {
285 288
286 unsigned int users; 289 unsigned int users;
287 290
291 struct vino_interrupt_data int_data;
292
288 /* V4L support */ 293 /* V4L support */
289 struct video_device *v4l_device; 294 struct video_device *v4l_device;
290}; 295};
@@ -315,7 +320,7 @@ struct vino_settings {
315/* Module parameters */ 320/* Module parameters */
316 321
317/* 322/*
318 * Using vino_pixel_conversion the ARGB32-format pixels supplied 323 * Using vino_pixel_conversion the ABGR32-format pixels supplied
319 * by the VINO chip can be converted to more common formats 324 * by the VINO chip can be converted to more common formats
320 * like RGBA32 (or probably RGB24 in the future). This way we 325 * like RGBA32 (or probably RGB24 in the future). This way we
321 * can give out data that can be specified correctly with 326 * can give out data that can be specified correctly with
@@ -329,7 +334,9 @@ struct vino_settings {
329 * Use non-zero value to enable conversion. 334 * Use non-zero value to enable conversion.
330 */ 335 */
331static int vino_pixel_conversion = 0; 336static int vino_pixel_conversion = 0;
337
332module_param_named(pixelconv, vino_pixel_conversion, int, 0); 338module_param_named(pixelconv, vino_pixel_conversion, int, 0);
339
333MODULE_PARM_DESC(pixelconv, 340MODULE_PARM_DESC(pixelconv,
334 "enable pixel conversion (non-zero value enables)"); 341 "enable pixel conversion (non-zero value enables)");
335 342
@@ -345,15 +352,22 @@ static const char *vino_bus_name = "GIO64 bus";
345static const char *vino_v4l_device_name_a = "SGI VINO Channel A"; 352static const char *vino_v4l_device_name_a = "SGI VINO Channel A";
346static const char *vino_v4l_device_name_b = "SGI VINO Channel B"; 353static const char *vino_v4l_device_name_b = "SGI VINO Channel B";
347 354
355static void vino_capture_tasklet(unsigned long channel);
356
357DECLARE_TASKLET(vino_tasklet_a, vino_capture_tasklet, VINO_CHANNEL_A);
358DECLARE_TASKLET(vino_tasklet_b, vino_capture_tasklet, VINO_CHANNEL_B);
359
348static const struct vino_input vino_inputs[] = { 360static const struct vino_input vino_inputs[] = {
349 { 361 {
350 .name = "Composite", 362 .name = "Composite",
351 .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, 363 .std = V4L2_STD_NTSC | V4L2_STD_PAL
364 | V4L2_STD_SECAM,
352 },{ 365 },{
353 .name = "S-Video", 366 .name = "S-Video",
354 .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, 367 .std = V4L2_STD_NTSC | V4L2_STD_PAL
368 | V4L2_STD_SECAM,
355 },{ 369 },{
356 .name = "D1 (IndyCam)", 370 .name = "D1/IndyCam",
357 .std = V4L2_STD_NTSC, 371 .std = V4L2_STD_NTSC,
358 } 372 }
359}; 373};
@@ -376,15 +390,10 @@ static const struct vino_data_format vino_data_formats[] = {
376 .colorspace = V4L2_COLORSPACE_SRGB, 390 .colorspace = V4L2_COLORSPACE_SRGB,
377 },{ 391 },{
378 .description = "YUV 4:2:2", 392 .description = "YUV 4:2:2",
379 .bpp = 4, 393 .bpp = 2,
380 .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped? 394 .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
381 .colorspace = V4L2_COLORSPACE_SMPTE170M, 395 .colorspace = V4L2_COLORSPACE_SMPTE170M,
382 }/*,{ 396 }
383 .description = "24-bit RGB",
384 .bpp = 3,
385 .pixelformat = V4L2_PIX_FMT_RGB24,
386 .colorspace = V4L2_COLORSPACE_SRGB,
387 }*/
388}; 397};
389 398
390static const struct vino_data_norm vino_data_norms[] = { 399static const struct vino_data_norm vino_data_norms[] = {
@@ -397,18 +406,18 @@ static const struct vino_data_norm vino_data_norms[] = {
397 .width = VINO_NTSC_WIDTH, 406 .width = VINO_NTSC_WIDTH,
398 .height = VINO_NTSC_HEIGHT, 407 .height = VINO_NTSC_HEIGHT,
399 .odd = { 408 .odd = {
400 .top = VINO_CLIPPING_START_ODD_NTSC, 409 .top = VINO_CLIPPING_START_ODD_NTSC,
401 .left = 0, 410 .left = 0,
402 .bottom = VINO_CLIPPING_START_ODD_NTSC 411 .bottom = VINO_CLIPPING_START_ODD_NTSC
403 + VINO_NTSC_HEIGHT / 2 - 1, 412 + VINO_NTSC_HEIGHT / 2 - 1,
404 .right = VINO_NTSC_WIDTH, 413 .right = VINO_NTSC_WIDTH,
405 }, 414 },
406 .even = { 415 .even = {
407 .top = VINO_CLIPPING_START_EVEN_NTSC, 416 .top = VINO_CLIPPING_START_EVEN_NTSC,
408 .left = 0, 417 .left = 0,
409 .bottom = VINO_CLIPPING_START_EVEN_NTSC 418 .bottom = VINO_CLIPPING_START_EVEN_NTSC
410 + VINO_NTSC_HEIGHT / 2 - 1, 419 + VINO_NTSC_HEIGHT / 2 - 1,
411 .right = VINO_NTSC_WIDTH, 420 .right = VINO_NTSC_WIDTH,
412 }, 421 },
413 },{ 422 },{
414 .description = "PAL", 423 .description = "PAL",
@@ -419,18 +428,18 @@ static const struct vino_data_norm vino_data_norms[] = {
419 .width = VINO_PAL_WIDTH, 428 .width = VINO_PAL_WIDTH,
420 .height = VINO_PAL_HEIGHT, 429 .height = VINO_PAL_HEIGHT,
421 .odd = { 430 .odd = {
422 .top = VINO_CLIPPING_START_ODD_PAL, 431 .top = VINO_CLIPPING_START_ODD_PAL,
423 .left = 0, 432 .left = 0,
424 .bottom = VINO_CLIPPING_START_ODD_PAL 433 .bottom = VINO_CLIPPING_START_ODD_PAL
425 + VINO_PAL_HEIGHT / 2 - 1, 434 + VINO_PAL_HEIGHT / 2 - 1,
426 .right = VINO_PAL_WIDTH, 435 .right = VINO_PAL_WIDTH,
427 }, 436 },
428 .even = { 437 .even = {
429 .top = VINO_CLIPPING_START_EVEN_PAL, 438 .top = VINO_CLIPPING_START_EVEN_PAL,
430 .left = 0, 439 .left = 0,
431 .bottom = VINO_CLIPPING_START_EVEN_PAL 440 .bottom = VINO_CLIPPING_START_EVEN_PAL
432 + VINO_PAL_HEIGHT / 2 - 1, 441 + VINO_PAL_HEIGHT / 2 - 1,
433 .right = VINO_PAL_WIDTH, 442 .right = VINO_PAL_WIDTH,
434 }, 443 },
435 },{ 444 },{
436 .description = "SECAM", 445 .description = "SECAM",
@@ -441,21 +450,21 @@ static const struct vino_data_norm vino_data_norms[] = {
441 .width = VINO_PAL_WIDTH, 450 .width = VINO_PAL_WIDTH,
442 .height = VINO_PAL_HEIGHT, 451 .height = VINO_PAL_HEIGHT,
443 .odd = { 452 .odd = {
444 .top = VINO_CLIPPING_START_ODD_PAL, 453 .top = VINO_CLIPPING_START_ODD_PAL,
445 .left = 0, 454 .left = 0,
446 .bottom = VINO_CLIPPING_START_ODD_PAL 455 .bottom = VINO_CLIPPING_START_ODD_PAL
447 + VINO_PAL_HEIGHT / 2 - 1, 456 + VINO_PAL_HEIGHT / 2 - 1,
448 .right = VINO_PAL_WIDTH, 457 .right = VINO_PAL_WIDTH,
449 }, 458 },
450 .even = { 459 .even = {
451 .top = VINO_CLIPPING_START_EVEN_PAL, 460 .top = VINO_CLIPPING_START_EVEN_PAL,
452 .left = 0, 461 .left = 0,
453 .bottom = VINO_CLIPPING_START_EVEN_PAL 462 .bottom = VINO_CLIPPING_START_EVEN_PAL
454 + VINO_PAL_HEIGHT / 2 - 1, 463 + VINO_PAL_HEIGHT / 2 - 1,
455 .right = VINO_PAL_WIDTH, 464 .right = VINO_PAL_WIDTH,
456 }, 465 },
457 },{ 466 },{
458 .description = "NTSC (D1 input)", 467 .description = "NTSC/D1",
459 .std = V4L2_STD_NTSC, 468 .std = V4L2_STD_NTSC,
460 .fps_min = 6, 469 .fps_min = 6,
461 .fps_max = 30, 470 .fps_max = 30,
@@ -463,18 +472,18 @@ static const struct vino_data_norm vino_data_norms[] = {
463 .width = VINO_NTSC_WIDTH, 472 .width = VINO_NTSC_WIDTH,
464 .height = VINO_NTSC_HEIGHT, 473 .height = VINO_NTSC_HEIGHT,
465 .odd = { 474 .odd = {
466 .top = VINO_CLIPPING_START_ODD_D1, 475 .top = VINO_CLIPPING_START_ODD_D1,
467 .left = 0, 476 .left = 0,
468 .bottom = VINO_CLIPPING_START_ODD_D1 477 .bottom = VINO_CLIPPING_START_ODD_D1
469 + VINO_NTSC_HEIGHT / 2 - 1, 478 + VINO_NTSC_HEIGHT / 2 - 1,
470 .right = VINO_NTSC_WIDTH, 479 .right = VINO_NTSC_WIDTH,
471 }, 480 },
472 .even = { 481 .even = {
473 .top = VINO_CLIPPING_START_EVEN_D1, 482 .top = VINO_CLIPPING_START_EVEN_D1,
474 .left = 0, 483 .left = 0,
475 .bottom = VINO_CLIPPING_START_EVEN_D1 484 .bottom = VINO_CLIPPING_START_EVEN_D1
476 + VINO_NTSC_HEIGHT / 2 - 1, 485 + VINO_NTSC_HEIGHT / 2 - 1,
477 .right = VINO_NTSC_WIDTH, 486 .right = VINO_NTSC_WIDTH,
478 }, 487 },
479 } 488 }
480}; 489};
@@ -491,7 +500,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
491 .step = 1, 500 .step = 1,
492 .default_value = INDYCAM_AGC_DEFAULT, 501 .default_value = INDYCAM_AGC_DEFAULT,
493 .flags = 0, 502 .flags = 0,
494 .reserved = { 0, 0 }, 503 .reserved = { INDYCAM_CONTROL_AGC, 0 },
495 },{ 504 },{
496 .id = V4L2_CID_AUTO_WHITE_BALANCE, 505 .id = V4L2_CID_AUTO_WHITE_BALANCE,
497 .type = V4L2_CTRL_TYPE_BOOLEAN, 506 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -501,7 +510,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
501 .step = 1, 510 .step = 1,
502 .default_value = INDYCAM_AWB_DEFAULT, 511 .default_value = INDYCAM_AWB_DEFAULT,
503 .flags = 0, 512 .flags = 0,
504 .reserved = { 0, 0 }, 513 .reserved = { INDYCAM_CONTROL_AWB, 0 },
505 },{ 514 },{
506 .id = V4L2_CID_GAIN, 515 .id = V4L2_CID_GAIN,
507 .type = V4L2_CTRL_TYPE_INTEGER, 516 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -511,7 +520,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
511 .step = 1, 520 .step = 1,
512 .default_value = INDYCAM_GAIN_DEFAULT, 521 .default_value = INDYCAM_GAIN_DEFAULT,
513 .flags = 0, 522 .flags = 0,
514 .reserved = { 0, 0 }, 523 .reserved = { INDYCAM_CONTROL_GAIN, 0 },
515 },{ 524 },{
516 .id = V4L2_CID_PRIVATE_BASE, 525 .id = V4L2_CID_PRIVATE_BASE,
517 .type = V4L2_CTRL_TYPE_INTEGER, 526 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -521,7 +530,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
521 .step = 1, 530 .step = 1,
522 .default_value = INDYCAM_RED_SATURATION_DEFAULT, 531 .default_value = INDYCAM_RED_SATURATION_DEFAULT,
523 .flags = 0, 532 .flags = 0,
524 .reserved = { 0, 0 }, 533 .reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 },
525 },{ 534 },{
526 .id = V4L2_CID_PRIVATE_BASE + 1, 535 .id = V4L2_CID_PRIVATE_BASE + 1,
527 .type = V4L2_CTRL_TYPE_INTEGER, 536 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -531,7 +540,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
531 .step = 1, 540 .step = 1,
532 .default_value = INDYCAM_BLUE_SATURATION_DEFAULT, 541 .default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
533 .flags = 0, 542 .flags = 0,
534 .reserved = { 0, 0 }, 543 .reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 },
535 },{ 544 },{
536 .id = V4L2_CID_RED_BALANCE, 545 .id = V4L2_CID_RED_BALANCE,
537 .type = V4L2_CTRL_TYPE_INTEGER, 546 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -541,7 +550,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
541 .step = 1, 550 .step = 1,
542 .default_value = INDYCAM_RED_BALANCE_DEFAULT, 551 .default_value = INDYCAM_RED_BALANCE_DEFAULT,
543 .flags = 0, 552 .flags = 0,
544 .reserved = { 0, 0 }, 553 .reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 },
545 },{ 554 },{
546 .id = V4L2_CID_BLUE_BALANCE, 555 .id = V4L2_CID_BLUE_BALANCE,
547 .type = V4L2_CTRL_TYPE_INTEGER, 556 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -551,7 +560,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
551 .step = 1, 560 .step = 1,
552 .default_value = INDYCAM_BLUE_BALANCE_DEFAULT, 561 .default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
553 .flags = 0, 562 .flags = 0,
554 .reserved = { 0, 0 }, 563 .reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 },
555 },{ 564 },{
556 .id = V4L2_CID_EXPOSURE, 565 .id = V4L2_CID_EXPOSURE,
557 .type = V4L2_CTRL_TYPE_INTEGER, 566 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -561,7 +570,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
561 .step = 1, 570 .step = 1,
562 .default_value = INDYCAM_SHUTTER_DEFAULT, 571 .default_value = INDYCAM_SHUTTER_DEFAULT,
563 .flags = 0, 572 .flags = 0,
564 .reserved = { 0, 0 }, 573 .reserved = { INDYCAM_CONTROL_SHUTTER, 0 },
565 },{ 574 },{
566 .id = V4L2_CID_GAMMA, 575 .id = V4L2_CID_GAMMA,
567 .type = V4L2_CTRL_TYPE_INTEGER, 576 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -571,11 +580,11 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
571 .step = 1, 580 .step = 1,
572 .default_value = INDYCAM_GAMMA_DEFAULT, 581 .default_value = INDYCAM_GAMMA_DEFAULT,
573 .flags = 0, 582 .flags = 0,
574 .reserved = { 0, 0 }, 583 .reserved = { INDYCAM_CONTROL_GAMMA, 0 },
575 } 584 }
576}; 585};
577 586
578#define VINO_SAA7191_V4L2_CONTROL_COUNT 2 587#define VINO_SAA7191_V4L2_CONTROL_COUNT 9
579 588
580struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = { 589struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
581 { 590 {
@@ -587,9 +596,59 @@ struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
587 .step = 1, 596 .step = 1,
588 .default_value = SAA7191_HUE_DEFAULT, 597 .default_value = SAA7191_HUE_DEFAULT,
589 .flags = 0, 598 .flags = 0,
590 .reserved = { 0, 0 }, 599 .reserved = { SAA7191_CONTROL_HUE, 0 },
591 },{ 600 },{
592 .id = V4L2_CID_PRIVATE_BASE, 601 .id = V4L2_CID_PRIVATE_BASE,
602 .type = V4L2_CTRL_TYPE_INTEGER,
603 .name = "Luminance Bandpass",
604 .minimum = SAA7191_BANDPASS_MIN,
605 .maximum = SAA7191_BANDPASS_MAX,
606 .step = 1,
607 .default_value = SAA7191_BANDPASS_DEFAULT,
608 .flags = 0,
609 .reserved = { SAA7191_CONTROL_BANDPASS, 0 },
610 },{
611 .id = V4L2_CID_PRIVATE_BASE + 1,
612 .type = V4L2_CTRL_TYPE_INTEGER,
613 .name = "Luminance Bandpass Weight",
614 .minimum = SAA7191_BANDPASS_WEIGHT_MIN,
615 .maximum = SAA7191_BANDPASS_WEIGHT_MAX,
616 .step = 1,
617 .default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
618 .flags = 0,
619 .reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 },
620 },{
621 .id = V4L2_CID_PRIVATE_BASE + 2,
622 .type = V4L2_CTRL_TYPE_INTEGER,
623 .name = "HF Luminance Coring",
624 .minimum = SAA7191_CORING_MIN,
625 .maximum = SAA7191_CORING_MAX,
626 .step = 1,
627 .default_value = SAA7191_CORING_DEFAULT,
628 .flags = 0,
629 .reserved = { SAA7191_CONTROL_CORING, 0 },
630 },{
631 .id = V4L2_CID_PRIVATE_BASE + 3,
632 .type = V4L2_CTRL_TYPE_BOOLEAN,
633 .name = "Force Colour",
634 .minimum = SAA7191_FORCE_COLOUR_MIN,
635 .maximum = SAA7191_FORCE_COLOUR_MAX,
636 .step = 1,
637 .default_value = SAA7191_FORCE_COLOUR_DEFAULT,
638 .flags = 0,
639 .reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 },
640 },{
641 .id = V4L2_CID_PRIVATE_BASE + 4,
642 .type = V4L2_CTRL_TYPE_INTEGER,
643 .name = "Chrominance Gain Control",
644 .minimum = SAA7191_CHROMA_GAIN_MIN,
645 .maximum = SAA7191_CHROMA_GAIN_MAX,
646 .step = 1,
647 .default_value = SAA7191_CHROMA_GAIN_DEFAULT,
648 .flags = 0,
649 .reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 },
650 },{
651 .id = V4L2_CID_PRIVATE_BASE + 5,
593 .type = V4L2_CTRL_TYPE_BOOLEAN, 652 .type = V4L2_CTRL_TYPE_BOOLEAN,
594 .name = "VTR Time Constant", 653 .name = "VTR Time Constant",
595 .minimum = SAA7191_VTRC_MIN, 654 .minimum = SAA7191_VTRC_MIN,
@@ -597,7 +656,27 @@ struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
597 .step = 1, 656 .step = 1,
598 .default_value = SAA7191_VTRC_DEFAULT, 657 .default_value = SAA7191_VTRC_DEFAULT,
599 .flags = 0, 658 .flags = 0,
600 .reserved = { 0, 0 }, 659 .reserved = { SAA7191_CONTROL_VTRC, 0 },
660 },{
661 .id = V4L2_CID_PRIVATE_BASE + 6,
662 .type = V4L2_CTRL_TYPE_INTEGER,
663 .name = "Luminance Delay Compensation",
664 .minimum = SAA7191_LUMA_DELAY_MIN,
665 .maximum = SAA7191_LUMA_DELAY_MAX,
666 .step = 1,
667 .default_value = SAA7191_LUMA_DELAY_DEFAULT,
668 .flags = 0,
669 .reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 },
670 },{
671 .id = V4L2_CID_PRIVATE_BASE + 7,
672 .type = V4L2_CTRL_TYPE_INTEGER,
673 .name = "Vertical Noise Reduction",
674 .minimum = SAA7191_VNR_MIN,
675 .maximum = SAA7191_VNR_MAX,
676 .step = 1,
677 .default_value = SAA7191_VNR_DEFAULT,
678 .flags = 0,
679 .reserved = { SAA7191_CONTROL_VNR, 0 },
601 } 680 }
602}; 681};
603 682
@@ -639,9 +718,10 @@ static struct i2c_algo_sgi_data i2c_sgi_vino_data =
639 */ 718 */
640static int i2c_vino_client_reg(struct i2c_client *client) 719static int i2c_vino_client_reg(struct i2c_client *client)
641{ 720{
721 unsigned long flags;
642 int ret = 0; 722 int ret = 0;
643 723
644 spin_lock(&vino_drvdata->input_lock); 724 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
645 switch (client->driver->id) { 725 switch (client->driver->id) {
646 case I2C_DRIVERID_SAA7191: 726 case I2C_DRIVERID_SAA7191:
647 if (vino_drvdata->decoder.driver) 727 if (vino_drvdata->decoder.driver)
@@ -658,16 +738,17 @@ static int i2c_vino_client_reg(struct i2c_client *client)
658 default: 738 default:
659 ret = -ENODEV; 739 ret = -ENODEV;
660 } 740 }
661 spin_unlock(&vino_drvdata->input_lock); 741 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
662 742
663 return ret; 743 return ret;
664} 744}
665 745
666static int i2c_vino_client_unreg(struct i2c_client *client) 746static int i2c_vino_client_unreg(struct i2c_client *client)
667{ 747{
748 unsigned long flags;
668 int ret = 0; 749 int ret = 0;
669 750
670 spin_lock(&vino_drvdata->input_lock); 751 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
671 if (client == vino_drvdata->decoder.driver) { 752 if (client == vino_drvdata->decoder.driver) {
672 if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL) 753 if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
673 ret = -EBUSY; 754 ret = -EBUSY;
@@ -679,7 +760,7 @@ static int i2c_vino_client_unreg(struct i2c_client *client)
679 else 760 else
680 vino_drvdata->camera.driver = NULL; 761 vino_drvdata->camera.driver = NULL;
681 } 762 }
682 spin_unlock(&vino_drvdata->input_lock); 763 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
683 764
684 return ret; 765 return ret;
685} 766}
@@ -727,7 +808,7 @@ static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
727 dprintk("vino_free_buffer_with_count(): count = %d\n", count); 808 dprintk("vino_free_buffer_with_count(): count = %d\n", count);
728 809
729 for (i = 0; i < count; i++) { 810 for (i = 0; i < count; i++) {
730 mem_map_unreserve(virt_to_page(fb->desc_table.virtual[i])); 811 ClearPageReserved(virt_to_page(fb->desc_table.virtual[i]));
731 dma_unmap_single(NULL, 812 dma_unmap_single(NULL,
732 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], 813 fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i],
733 PAGE_SIZE, DMA_FROM_DEVICE); 814 PAGE_SIZE, DMA_FROM_DEVICE);
@@ -805,7 +886,7 @@ static int vino_allocate_buffer(struct vino_framebuffer *fb,
805 dma_data_addr + VINO_PAGE_SIZE * j; 886 dma_data_addr + VINO_PAGE_SIZE * j;
806 } 887 }
807 888
808 mem_map_reserve(virt_to_page(fb->desc_table.virtual[i])); 889 SetPageReserved(virt_to_page(fb->desc_table.virtual[i]));
809 } 890 }
810 891
811 /* page_count needs to be set anyway, because the descriptor table has 892 /* page_count needs to be set anyway, because the descriptor table has
@@ -892,7 +973,7 @@ static int vino_prepare_user_buffer(struct vino_framebuffer *fb,
892 dma_data_addr + VINO_PAGE_SIZE * j; 973 dma_data_addr + VINO_PAGE_SIZE * j;
893 } 974 }
894 975
895 mem_map_reserve(virt_to_page(fb->desc_table.virtual[i])); 976 SetPageReserved(virt_to_page(fb->desc_table.virtual[i]));
896 } 977 }
897 978
898 /* page_count needs to be set anyway, because the descriptor table has 979 /* page_count needs to be set anyway, because the descriptor table has
@@ -933,7 +1014,7 @@ static void vino_sync_buffer(struct vino_framebuffer *fb)
933 1014
934/* Framebuffer fifo functions (need to be locked externally) */ 1015/* Framebuffer fifo functions (need to be locked externally) */
935 1016
936static void vino_fifo_init(struct vino_framebuffer_fifo *f, 1017static inline void vino_fifo_init(struct vino_framebuffer_fifo *f,
937 unsigned int length) 1018 unsigned int length)
938{ 1019{
939 f->length = 0; 1020 f->length = 0;
@@ -941,16 +1022,18 @@ static void vino_fifo_init(struct vino_framebuffer_fifo *f,
941 f->head = 0; 1022 f->head = 0;
942 f->tail = 0; 1023 f->tail = 0;
943 1024
944 if (length > VINO_FRAMEBUFFER_MAX_COUNT) 1025 if (length > VINO_FRAMEBUFFER_COUNT_MAX)
945 length = VINO_FRAMEBUFFER_MAX_COUNT; 1026 length = VINO_FRAMEBUFFER_COUNT_MAX;
946 1027
947 f->length = length; 1028 f->length = length;
948} 1029}
949 1030
950/* returns true/false */ 1031/* returns true/false */
951static int vino_fifo_has_id(struct vino_framebuffer_fifo *f, unsigned int id) 1032static inline int vino_fifo_has_id(struct vino_framebuffer_fifo *f,
1033 unsigned int id)
952{ 1034{
953 unsigned int i; 1035 unsigned int i;
1036
954 for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) { 1037 for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) {
955 if (f->data[i] == id) 1038 if (f->data[i] == id)
956 return 1; 1039 return 1;
@@ -959,13 +1042,15 @@ static int vino_fifo_has_id(struct vino_framebuffer_fifo *f, unsigned int id)
959 return 0; 1042 return 0;
960} 1043}
961 1044
1045#if 0
962/* returns true/false */ 1046/* returns true/false */
963static int vino_fifo_full(struct vino_framebuffer_fifo *f) 1047static inline int vino_fifo_full(struct vino_framebuffer_fifo *f)
964{ 1048{
965 return (f->used == f->length); 1049 return (f->used == f->length);
966} 1050}
1051#endif
967 1052
968static unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f) 1053static inline unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f)
969{ 1054{
970 return f->used; 1055 return f->used;
971} 1056}
@@ -1076,8 +1161,8 @@ static int vino_queue_init(struct vino_framebuffer_queue *q,
1076 1161
1077 down(&q->queue_sem); 1162 down(&q->queue_sem);
1078 1163
1079 if (*length > VINO_FRAMEBUFFER_MAX_COUNT) 1164 if (*length > VINO_FRAMEBUFFER_COUNT_MAX)
1080 *length = VINO_FRAMEBUFFER_MAX_COUNT; 1165 *length = VINO_FRAMEBUFFER_COUNT_MAX;
1081 1166
1082 q->length = 0; 1167 q->length = 0;
1083 1168
@@ -1313,6 +1398,7 @@ out:
1313 return ret; 1398 return ret;
1314} 1399}
1315 1400
1401#if 0
1316static int vino_queue_get_total(struct vino_framebuffer_queue *q, 1402static int vino_queue_get_total(struct vino_framebuffer_queue *q,
1317 unsigned int *total) 1403 unsigned int *total)
1318{ 1404{
@@ -1338,6 +1424,7 @@ out:
1338 1424
1339 return ret; 1425 return ret;
1340} 1426}
1427#endif
1341 1428
1342static struct vino_framebuffer *vino_queue_peek(struct 1429static struct vino_framebuffer *vino_queue_peek(struct
1343 vino_framebuffer_queue *q, 1430 vino_framebuffer_queue *q,
@@ -1471,12 +1558,14 @@ static void vino_update_line_size(struct vino_channel_settings *vcs)
1471 1558
1472 dprintk("update_line_size(): before: w = %d, d = %d, " 1559 dprintk("update_line_size(): before: w = %d, d = %d, "
1473 "line_size = %d\n", w, d, vcs->line_size); 1560 "line_size = %d\n", w, d, vcs->line_size);
1561
1474 /* line size must be multiple of 8 bytes */ 1562 /* line size must be multiple of 8 bytes */
1475 lsize = (bpp * (w / d)) & ~7; 1563 lsize = (bpp * (w / d)) & ~7;
1476 w = (lsize / bpp) * d; 1564 w = (lsize / bpp) * d;
1477 1565
1478 vcs->clipping.right = vcs->clipping.left + w; 1566 vcs->clipping.right = vcs->clipping.left + w;
1479 vcs->line_size = lsize; 1567 vcs->line_size = lsize;
1568
1480 dprintk("update_line_size(): after: w = %d, d = %d, " 1569 dprintk("update_line_size(): after: w = %d, d = %d, "
1481 "line_size = %d\n", w, d, vcs->line_size); 1570 "line_size = %d\n", w, d, vcs->line_size);
1482} 1571}
@@ -1532,7 +1621,7 @@ static void vino_set_clipping(struct vino_channel_settings *vcs,
1532} 1621}
1533 1622
1534/* execute with input_lock locked */ 1623/* execute with input_lock locked */
1535static void vino_set_default_clipping(struct vino_channel_settings *vcs) 1624static inline void vino_set_default_clipping(struct vino_channel_settings *vcs)
1536{ 1625{
1537 vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width, 1626 vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width,
1538 vino_data_norms[vcs->data_norm].height); 1627 vino_data_norms[vcs->data_norm].height);
@@ -1556,8 +1645,7 @@ static void vino_set_scaling(struct vino_channel_settings *vcs,
1556 1645
1557 if (d < 1) { 1646 if (d < 1) {
1558 d = 1; 1647 d = 1;
1559 } 1648 } else if (d > 8) {
1560 if (d > 8) {
1561 d = 8; 1649 d = 8;
1562 } 1650 }
1563 1651
@@ -1570,7 +1658,7 @@ static void vino_set_scaling(struct vino_channel_settings *vcs,
1570} 1658}
1571 1659
1572/* execute with input_lock locked */ 1660/* execute with input_lock locked */
1573static void vino_reset_scaling(struct vino_channel_settings *vcs) 1661static inline void vino_set_default_scaling(struct vino_channel_settings *vcs)
1574{ 1662{
1575 vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left, 1663 vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left,
1576 vcs->clipping.bottom - vcs->clipping.top); 1664 vcs->clipping.bottom - vcs->clipping.top);
@@ -1649,7 +1737,8 @@ static void vino_set_framerate(struct vino_channel_settings *vcs,
1649} 1737}
1650 1738
1651/* execute with input_lock locked */ 1739/* execute with input_lock locked */
1652static void vino_set_default_framerate(struct vino_channel_settings *vcs) 1740static inline void vino_set_default_framerate(struct
1741 vino_channel_settings *vcs)
1653{ 1742{
1654 vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max); 1743 vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
1655} 1744}
@@ -1687,6 +1776,9 @@ static int vino_dma_setup(struct vino_channel_settings *vcs,
1687 * should be more than enough time */ 1776 * should be more than enough time */
1688 udelay(VINO_DESC_FETCH_DELAY); 1777 udelay(VINO_DESC_FETCH_DELAY);
1689 1778
1779 dprintk("vino_dma_setup(): start desc = %08x, next 4 desc = %08x\n",
1780 ch->start_desc_tbl, ch->next_4_desc);
1781
1690 /* set the alpha register */ 1782 /* set the alpha register */
1691 ch->alpha = vcs->alpha; 1783 ch->alpha = vcs->alpha;
1692 1784
@@ -1700,9 +1792,6 @@ static int vino_dma_setup(struct vino_channel_settings *vcs,
1700 VINO_CLIP_EVEN(norm->even.top + 1792 VINO_CLIP_EVEN(norm->even.top +
1701 vcs->clipping.bottom / 2 - 1) | 1793 vcs->clipping.bottom / 2 - 1) |
1702 VINO_CLIP_X(vcs->clipping.right); 1794 VINO_CLIP_X(vcs->clipping.right);
1703 /* FIXME: end-of-field bug workaround
1704 VINO_CLIP_X(VINO_PAL_WIDTH);
1705 */
1706 1795
1707 /* set the size of actual content in the buffer (DECIMATION !) */ 1796 /* set the size of actual content in the buffer (DECIMATION !) */
1708 fb->data_size = ((vcs->clipping.right - vcs->clipping.left) / 1797 fb->data_size = ((vcs->clipping.right - vcs->clipping.left) /
@@ -1802,7 +1891,7 @@ static int vino_dma_setup(struct vino_channel_settings *vcs,
1802} 1891}
1803 1892
1804/* (execute only with vino_lock locked) */ 1893/* (execute only with vino_lock locked) */
1805static void vino_dma_start(struct vino_channel_settings *vcs) 1894static inline void vino_dma_start(struct vino_channel_settings *vcs)
1806{ 1895{
1807 u32 ctrl = vino->control; 1896 u32 ctrl = vino->control;
1808 1897
@@ -1813,12 +1902,14 @@ static void vino_dma_start(struct vino_channel_settings *vcs)
1813} 1902}
1814 1903
1815/* (execute only with vino_lock locked) */ 1904/* (execute only with vino_lock locked) */
1816static void vino_dma_stop(struct vino_channel_settings *vcs) 1905static inline void vino_dma_stop(struct vino_channel_settings *vcs)
1817{ 1906{
1818 u32 ctrl = vino->control; 1907 u32 ctrl = vino->control;
1819 1908
1820 ctrl &= (vcs->channel == VINO_CHANNEL_A) ? 1909 ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1821 ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL; 1910 ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL;
1911 ctrl &= (vcs->channel == VINO_CHANNEL_A) ?
1912 ~VINO_CTRL_A_INT : ~VINO_CTRL_B_INT;
1822 vino->control = ctrl; 1913 vino->control = ctrl;
1823 dprintk("vino_dma_stop():\n"); 1914 dprintk("vino_dma_stop():\n");
1824} 1915}
@@ -1902,7 +1993,7 @@ static int vino_capture_next(struct vino_channel_settings *vcs, int start)
1902 struct vino_framebuffer *fb; 1993 struct vino_framebuffer *fb;
1903 unsigned int incoming, id; 1994 unsigned int incoming, id;
1904 int err = 0; 1995 int err = 0;
1905 unsigned long flags, flags2; 1996 unsigned long flags;
1906 1997
1907 dprintk("vino_capture_next():\n"); 1998 dprintk("vino_capture_next():\n");
1908 1999
@@ -1943,10 +2034,6 @@ static int vino_capture_next(struct vino_channel_settings *vcs, int start)
1943 goto out; 2034 goto out;
1944 } 2035 }
1945 2036
1946 spin_lock_irqsave(&fb->state_lock, flags2);
1947 fb->state = VINO_FRAMEBUFFER_UNUSED;
1948 spin_unlock_irqrestore(&fb->state_lock, flags2);
1949
1950 if (start) { 2037 if (start) {
1951 vcs->capturing = 1; 2038 vcs->capturing = 1;
1952 } 2039 }
@@ -1964,7 +2051,7 @@ out:
1964 return err; 2051 return err;
1965} 2052}
1966 2053
1967static int vino_is_capturing(struct vino_channel_settings *vcs) 2054static inline int vino_is_capturing(struct vino_channel_settings *vcs)
1968{ 2055{
1969 int ret; 2056 int ret;
1970 unsigned long flags; 2057 unsigned long flags;
@@ -2076,6 +2163,7 @@ static void vino_capture_stop(struct vino_channel_settings *vcs)
2076 dprintk("vino_capture_stop():\n"); 2163 dprintk("vino_capture_stop():\n");
2077 2164
2078 spin_lock_irqsave(&vcs->capture_lock, flags); 2165 spin_lock_irqsave(&vcs->capture_lock, flags);
2166
2079 /* unset capturing to stop queue processing */ 2167 /* unset capturing to stop queue processing */
2080 vcs->capturing = 0; 2168 vcs->capturing = 0;
2081 2169
@@ -2121,6 +2209,7 @@ out:
2121 spin_unlock_irqrestore(&vcs->capture_lock, flags); 2209 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2122} 2210}
2123 2211
2212#if 0
2124static int vino_capture_failed(struct vino_channel_settings *vcs) 2213static int vino_capture_failed(struct vino_channel_settings *vcs)
2125{ 2214{
2126 struct vino_framebuffer *fb; 2215 struct vino_framebuffer *fb;
@@ -2165,9 +2254,31 @@ static int vino_capture_failed(struct vino_channel_settings *vcs)
2165 2254
2166 return 0; 2255 return 0;
2167} 2256}
2257#endif
2258
2259static void vino_skip_frame(struct vino_channel_settings *vcs)
2260{
2261 struct vino_framebuffer *fb;
2262 unsigned long flags;
2263 unsigned int id;
2264
2265 spin_lock_irqsave(&vcs->capture_lock, flags);
2266 fb = vino_queue_peek(&vcs->fb_queue, &id);
2267 if (!fb) {
2268 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2269 dprintk("vino_skip_frame(): vino_queue_peek() failed!\n");
2270 return;
2271 }
2272 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2273
2274 spin_lock_irqsave(&fb->state_lock, flags);
2275 fb->state = VINO_FRAMEBUFFER_UNUSED;
2276 spin_unlock_irqrestore(&fb->state_lock, flags);
2277
2278 vino_capture_next(vcs, 0);
2279}
2168 2280
2169static void vino_frame_done(struct vino_channel_settings *vcs, 2281static void vino_frame_done(struct vino_channel_settings *vcs)
2170 unsigned int fc)
2171{ 2282{
2172 struct vino_framebuffer *fb; 2283 struct vino_framebuffer *fb;
2173 unsigned long flags; 2284 unsigned long flags;
@@ -2181,8 +2292,9 @@ static void vino_frame_done(struct vino_channel_settings *vcs,
2181 } 2292 }
2182 spin_unlock_irqrestore(&vcs->capture_lock, flags); 2293 spin_unlock_irqrestore(&vcs->capture_lock, flags);
2183 2294
2184 fb->frame_counter = fc; 2295 fb->frame_counter = vcs->int_data.frame_counter;
2185 do_gettimeofday(&fb->timestamp); 2296 memcpy(&fb->timestamp, &vcs->int_data.timestamp,
2297 sizeof(struct timeval));
2186 2298
2187 spin_lock_irqsave(&fb->state_lock, flags); 2299 spin_lock_irqsave(&fb->state_lock, flags);
2188 if (fb->state == VINO_FRAMEBUFFER_IN_USE) 2300 if (fb->state == VINO_FRAMEBUFFER_IN_USE)
@@ -2194,72 +2306,175 @@ static void vino_frame_done(struct vino_channel_settings *vcs,
2194 vino_capture_next(vcs, 0); 2306 vino_capture_next(vcs, 0);
2195} 2307}
2196 2308
2309static void vino_capture_tasklet(unsigned long channel) {
2310 struct vino_channel_settings *vcs;
2311
2312 vcs = (channel == VINO_CHANNEL_A)
2313 ? &vino_drvdata->a : &vino_drvdata->b;
2314
2315 if (vcs->int_data.skip)
2316 vcs->int_data.skip_count++;
2317
2318 if (vcs->int_data.skip && (vcs->int_data.skip_count
2319 <= VINO_MAX_FRAME_SKIP_COUNT)) {
2320 vino_skip_frame(vcs);
2321 } else {
2322 vcs->int_data.skip_count = 0;
2323 vino_frame_done(vcs);
2324 }
2325}
2326
2197static irqreturn_t vino_interrupt(int irq, void *dev_id, struct pt_regs *regs) 2327static irqreturn_t vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2198{ 2328{
2199 u32 intr; 2329 u32 ctrl, intr;
2200 unsigned int fc_a, fc_b; 2330 unsigned int fc_a, fc_b;
2201 int done_a = 0; 2331 int handled_a = 0, skip_a = 0, done_a = 0;
2202 int done_b = 0; 2332 int handled_b = 0, skip_b = 0, done_b = 0;
2333
2334#ifdef VINO_DEBUG_INT
2335 int loop = 0;
2336 unsigned int line_count = vino->a.line_count,
2337 page_index = vino->a.page_index,
2338 field_counter = vino->a.field_counter,
2339 start_desc_tbl = vino->a.start_desc_tbl,
2340 next_4_desc = vino->a.next_4_desc;
2341 unsigned int line_count_2,
2342 page_index_2,
2343 field_counter_2,
2344 start_desc_tbl_2,
2345 next_4_desc_2;
2346#endif
2203 2347
2204 spin_lock(&vino_drvdata->vino_lock); 2348 spin_lock(&vino_drvdata->vino_lock);
2205 2349
2206 intr = vino->intr_status; 2350 while ((intr = vino->intr_status)) {
2207 fc_a = vino->a.field_counter / 2; 2351 fc_a = vino->a.field_counter >> 1;
2208 fc_b = vino->b.field_counter / 2; 2352 fc_b = vino->b.field_counter >> 1;
2209 2353
2210 // TODO: handle error-interrupts in some special way ? 2354 /* handle error-interrupts in some special way ?
2211 2355 * --> skips frames */
2212 if (intr & VINO_INTSTAT_A) { 2356 if (intr & VINO_INTSTAT_A) {
2213 if (intr & VINO_INTSTAT_A_EOF) { 2357 if (intr & VINO_INTSTAT_A_EOF) {
2214 vino_drvdata->a.field++; 2358 vino_drvdata->a.field++;
2215 if (vino_drvdata->a.field > 1) { 2359 if (vino_drvdata->a.field > 1) {
2360 vino_dma_stop(&vino_drvdata->a);
2361 vino_clear_interrupt(&vino_drvdata->a);
2362 vino_drvdata->a.field = 0;
2363 done_a = 1;
2364 } else {
2365 if (vino->a.page_index
2366 != vino_drvdata->a.line_size) {
2367 vino->a.line_count = 0;
2368 vino->a.page_index =
2369 vino_drvdata->
2370 a.line_size;
2371 vino->a.next_4_desc =
2372 vino->a.start_desc_tbl;
2373 }
2374 }
2375 dprintk("channel A end-of-field "
2376 "interrupt: %04x\n", intr);
2377 } else {
2216 vino_dma_stop(&vino_drvdata->a); 2378 vino_dma_stop(&vino_drvdata->a);
2217 vino_clear_interrupt(&vino_drvdata->a); 2379 vino_clear_interrupt(&vino_drvdata->a);
2218 vino_drvdata->a.field = 0; 2380 vino_drvdata->a.field = 0;
2219 done_a = 1; 2381 skip_a = 1;
2382 dprintk("channel A error interrupt: %04x\n",
2383 intr);
2220 } 2384 }
2221 dprintk("intr: channel A end-of-field interrupt: " 2385
2222 "%04x\n", intr); 2386#ifdef VINO_DEBUG_INT
2223 } else { 2387 line_count_2 = vino->a.line_count;
2224 vino_dma_stop(&vino_drvdata->a); 2388 page_index_2 = vino->a.page_index;
2225 vino_clear_interrupt(&vino_drvdata->a); 2389 field_counter_2 = vino->a.field_counter;
2226 done_a = 1; 2390 start_desc_tbl_2 = vino->a.start_desc_tbl;
2227 dprintk("channel A error interrupt: %04x\n", intr); 2391 next_4_desc_2 = vino->a.next_4_desc;
2392
2393 printk("intr = %04x, loop = %d, field = %d\n",
2394 intr, loop, vino_drvdata->a.field);
2395 printk("1- line count = %04d, page index = %04d, "
2396 "start = %08x, next = %08x\n"
2397 " fieldc = %d, framec = %d\n",
2398 line_count, page_index, start_desc_tbl,
2399 next_4_desc, field_counter, fc_a);
2400 printk("12-line count = %04d, page index = %04d, "
2401 " start = %08x, next = %08x\n",
2402 line_count_2, page_index_2, start_desc_tbl_2,
2403 next_4_desc_2);
2404
2405 if (done_a)
2406 printk("\n");
2407#endif
2228 } 2408 }
2229 } 2409
2230 if (intr & VINO_INTSTAT_B) { 2410 if (intr & VINO_INTSTAT_B) {
2231 if (intr & VINO_INTSTAT_B_EOF) { 2411 if (intr & VINO_INTSTAT_B_EOF) {
2232 vino_drvdata->b.field++; 2412 vino_drvdata->b.field++;
2233 if (vino_drvdata->b.field > 1) { 2413 if (vino_drvdata->b.field > 1) {
2414 vino_dma_stop(&vino_drvdata->b);
2415 vino_clear_interrupt(&vino_drvdata->b);
2416 vino_drvdata->b.field = 0;
2417 done_b = 1;
2418 }
2419 dprintk("channel B end-of-field "
2420 "interrupt: %04x\n", intr);
2421 } else {
2234 vino_dma_stop(&vino_drvdata->b); 2422 vino_dma_stop(&vino_drvdata->b);
2235 vino_clear_interrupt(&vino_drvdata->b); 2423 vino_clear_interrupt(&vino_drvdata->b);
2236 vino_drvdata->b.field = 0; 2424 vino_drvdata->b.field = 0;
2237 done_b = 1; 2425 skip_b = 1;
2426 dprintk("channel B error interrupt: %04x\n",
2427 intr);
2238 } 2428 }
2239 dprintk("intr: channel B end-of-field interrupt: "
2240 "%04x\n", intr);
2241 } else {
2242 vino_dma_stop(&vino_drvdata->b);
2243 vino_clear_interrupt(&vino_drvdata->b);
2244 done_b = 1;
2245 dprintk("channel B error interrupt: %04x\n", intr);
2246 } 2429 }
2247 }
2248 2430
2249 /* always remember to clear interrupt status */ 2431 /* Always remember to clear interrupt status.
2250 vino->intr_status = ~intr; 2432 * Disable VINO interrupts while we do this. */
2433 ctrl = vino->control;
2434 vino->control = ctrl & ~(VINO_CTRL_A_INT | VINO_CTRL_B_INT);
2435 vino->intr_status = ~intr;
2436 vino->control = ctrl;
2251 2437
2252 spin_unlock(&vino_drvdata->vino_lock); 2438 spin_unlock(&vino_drvdata->vino_lock);
2253 2439
2254 if (done_a) { 2440 if ((!handled_a) && (done_a || skip_a)) {
2255 vino_frame_done(&vino_drvdata->a, fc_a); 2441 if (!skip_a) {
2256 dprintk("channel A frame done, interrupt: %d\n", intr); 2442 do_gettimeofday(&vino_drvdata->
2257 } 2443 a.int_data.timestamp);
2258 if (done_b) { 2444 vino_drvdata->a.int_data.frame_counter = fc_a;
2259 vino_frame_done(&vino_drvdata->b, fc_b); 2445 }
2260 dprintk("channel B frame done, interrupt: %d\n", intr); 2446 vino_drvdata->a.int_data.skip = skip_a;
2447
2448 dprintk("channel A %s, interrupt: %d\n",
2449 skip_a ? "skipping frame" : "frame done",
2450 intr);
2451 tasklet_hi_schedule(&vino_tasklet_a);
2452 handled_a = 1;
2453 }
2454
2455 if ((!handled_b) && (done_b || skip_b)) {
2456 if (!skip_b) {
2457 do_gettimeofday(&vino_drvdata->
2458 b.int_data.timestamp);
2459 vino_drvdata->b.int_data.frame_counter = fc_b;
2460 }
2461 vino_drvdata->b.int_data.skip = skip_b;
2462
2463 dprintk("channel B %s, interrupt: %d\n",
2464 skip_b ? "skipping frame" : "frame done",
2465 intr);
2466 tasklet_hi_schedule(&vino_tasklet_b);
2467 handled_b = 1;
2468 }
2469
2470#ifdef VINO_DEBUG_INT
2471 loop++;
2472#endif
2473 spin_lock(&vino_drvdata->vino_lock);
2261 } 2474 }
2262 2475
2476 spin_unlock(&vino_drvdata->vino_lock);
2477
2263 return IRQ_HANDLED; 2478 return IRQ_HANDLED;
2264} 2479}
2265 2480
@@ -2279,11 +2494,13 @@ static int vino_get_saa7191_input(int input)
2279 } 2494 }
2280} 2495}
2281 2496
2282static int vino_get_saa7191_norm(int norm) 2497static int vino_get_saa7191_norm(unsigned int data_norm)
2283{ 2498{
2284 switch (norm) { 2499 switch (data_norm) {
2285 case VINO_DATA_NORM_AUTO: 2500 case VINO_DATA_NORM_AUTO:
2286 return SAA7191_NORM_AUTO; 2501 return SAA7191_NORM_AUTO;
2502 case VINO_DATA_NORM_AUTO_EXT:
2503 return SAA7191_NORM_AUTO_EXT;
2287 case VINO_DATA_NORM_PAL: 2504 case VINO_DATA_NORM_PAL:
2288 return SAA7191_NORM_PAL; 2505 return SAA7191_NORM_PAL;
2289 case VINO_DATA_NORM_NTSC: 2506 case VINO_DATA_NORM_NTSC:
@@ -2297,6 +2514,57 @@ static int vino_get_saa7191_norm(int norm)
2297 } 2514 }
2298} 2515}
2299 2516
2517static int vino_get_from_saa7191_norm(int saa7191_norm)
2518{
2519 switch (saa7191_norm) {
2520 case SAA7191_NORM_PAL:
2521 return VINO_DATA_NORM_PAL;
2522 case SAA7191_NORM_NTSC:
2523 return VINO_DATA_NORM_NTSC;
2524 case SAA7191_NORM_SECAM:
2525 return VINO_DATA_NORM_SECAM;
2526 default:
2527 printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): "
2528 "invalid norm!\n");
2529 return VINO_DATA_NORM_NONE;
2530 }
2531}
2532
2533static int vino_saa7191_set_norm(unsigned int *data_norm)
2534{
2535 int saa7191_norm, new_data_norm;
2536 int err = 0;
2537
2538 saa7191_norm = vino_get_saa7191_norm(*data_norm);
2539
2540 err = i2c_decoder_command(DECODER_SAA7191_SET_NORM,
2541 &saa7191_norm);
2542 if (err)
2543 goto out;
2544
2545 if ((*data_norm == VINO_DATA_NORM_AUTO)
2546 || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) {
2547 struct saa7191_status status;
2548
2549 err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS,
2550 &status);
2551 if (err)
2552 goto out;
2553
2554 new_data_norm =
2555 vino_get_from_saa7191_norm(status.norm);
2556 if (new_data_norm == VINO_DATA_NORM_NONE) {
2557 err = -EINVAL;
2558 goto out;
2559 }
2560
2561 *data_norm = (unsigned int)new_data_norm;
2562 }
2563
2564out:
2565 return err;
2566}
2567
2300/* execute with input_lock locked */ 2568/* execute with input_lock locked */
2301static int vino_is_input_owner(struct vino_channel_settings *vcs) 2569static int vino_is_input_owner(struct vino_channel_settings *vcs)
2302{ 2570{
@@ -2313,11 +2581,12 @@ static int vino_is_input_owner(struct vino_channel_settings *vcs)
2313 2581
2314static int vino_acquire_input(struct vino_channel_settings *vcs) 2582static int vino_acquire_input(struct vino_channel_settings *vcs)
2315{ 2583{
2584 unsigned long flags;
2316 int ret = 0; 2585 int ret = 0;
2317 2586
2318 dprintk("vino_acquire_input():\n"); 2587 dprintk("vino_acquire_input():\n");
2319 2588
2320 spin_lock(&vino_drvdata->input_lock); 2589 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2321 2590
2322 /* First try D1 and then SAA7191 */ 2591 /* First try D1 and then SAA7191 */
2323 if (vino_drvdata->camera.driver 2592 if (vino_drvdata->camera.driver
@@ -2332,23 +2601,48 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
2332 vcs->data_norm = VINO_DATA_NORM_D1; 2601 vcs->data_norm = VINO_DATA_NORM_D1;
2333 } else if (vino_drvdata->decoder.driver 2602 } else if (vino_drvdata->decoder.driver
2334 && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) { 2603 && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
2604 int input, data_norm;
2335 int saa7191_input; 2605 int saa7191_input;
2336 int saa7191_norm;
2337 2606
2338 if (i2c_use_client(vino_drvdata->decoder.driver)) { 2607 if (i2c_use_client(vino_drvdata->decoder.driver)) {
2339 ret = -ENODEV; 2608 ret = -ENODEV;
2340 goto out; 2609 goto out;
2341 } 2610 }
2342 2611
2343 vino_drvdata->decoder.owner = vcs->channel; 2612 input = VINO_INPUT_COMPOSITE;
2344 vcs->input = VINO_INPUT_COMPOSITE; 2613
2345 vcs->data_norm = VINO_DATA_NORM_PAL; 2614 saa7191_input = vino_get_saa7191_input(input);
2615 ret = i2c_decoder_command(DECODER_SET_INPUT,
2616 &saa7191_input);
2617 if (ret) {
2618 ret = -EINVAL;
2619 goto out;
2620 }
2621
2622 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2346 2623
2347 saa7191_input = vino_get_saa7191_input(vcs->input); 2624 /* Don't hold spinlocks while auto-detecting norm
2348 i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input); 2625 * as it may take a while... */
2349 2626
2350 saa7191_norm = vino_get_saa7191_norm(vcs->data_norm); 2627 data_norm = VINO_DATA_NORM_AUTO_EXT;
2351 i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm); 2628
2629 ret = vino_saa7191_set_norm(&data_norm);
2630 if ((ret == -EBUSY) || (ret == -EAGAIN)) {
2631 data_norm = VINO_DATA_NORM_PAL;
2632 ret = vino_saa7191_set_norm(&data_norm);
2633 }
2634
2635 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2636
2637 if (ret) {
2638 ret = -EINVAL;
2639 goto out;
2640 }
2641
2642 vino_drvdata->decoder.owner = vcs->channel;
2643
2644 vcs->input = input;
2645 vcs->data_norm = data_norm;
2352 } else { 2646 } else {
2353 vcs->input = (vcs->channel == VINO_CHANNEL_A) ? 2647 vcs->input = (vcs->channel == VINO_CHANNEL_A) ?
2354 vino_drvdata->b.input : vino_drvdata->a.input; 2648 vino_drvdata->b.input : vino_drvdata->a.input;
@@ -2361,15 +2655,14 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
2361 goto out; 2655 goto out;
2362 } 2656 }
2363 2657
2364 if (vino_is_input_owner(vcs)) { 2658 vino_set_default_clipping(vcs);
2365 vino_set_default_clipping(vcs); 2659 vino_set_default_scaling(vcs);
2366 vino_set_default_framerate(vcs); 2660 vino_set_default_framerate(vcs);
2367 }
2368 2661
2369 dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name); 2662 dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name);
2370 2663
2371out: 2664out:
2372 spin_unlock(&vino_drvdata->input_lock); 2665 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2373 2666
2374 return ret; 2667 return ret;
2375} 2668}
@@ -2378,16 +2671,17 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
2378{ 2671{
2379 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ? 2672 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2380 &vino_drvdata->b : &vino_drvdata->a; 2673 &vino_drvdata->b : &vino_drvdata->a;
2674 unsigned long flags;
2381 int ret = 0; 2675 int ret = 0;
2382 2676
2383 dprintk("vino_set_input():\n"); 2677 dprintk("vino_set_input():\n");
2384 2678
2385 spin_lock(&vino_drvdata->input_lock); 2679 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2386 2680
2387 if (vcs->input == input) 2681 if (vcs->input == input)
2388 goto out; 2682 goto out;
2389 2683
2390 switch(input) { 2684 switch (input) {
2391 case VINO_INPUT_COMPOSITE: 2685 case VINO_INPUT_COMPOSITE:
2392 case VINO_INPUT_SVIDEO: 2686 case VINO_INPUT_SVIDEO:
2393 if (!vino_drvdata->decoder.driver) { 2687 if (!vino_drvdata->decoder.driver) {
@@ -2404,19 +2698,43 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
2404 } 2698 }
2405 2699
2406 if (vino_drvdata->decoder.owner == vcs->channel) { 2700 if (vino_drvdata->decoder.owner == vcs->channel) {
2701 int data_norm;
2407 int saa7191_input; 2702 int saa7191_input;
2408 int saa7191_norm;
2409 2703
2410 vcs->input = input; 2704 saa7191_input = vino_get_saa7191_input(input);
2411 vcs->data_norm = VINO_DATA_NORM_PAL; 2705 ret = i2c_decoder_command(DECODER_SET_INPUT,
2706 &saa7191_input);
2707 if (ret) {
2708 vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2709 ret = -EINVAL;
2710 goto out;
2711 }
2712
2713 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2714
2715 /* Don't hold spinlocks while auto-detecting norm
2716 * as it may take a while... */
2717
2718 data_norm = VINO_DATA_NORM_AUTO_EXT;
2719
2720 ret = vino_saa7191_set_norm(&data_norm);
2721 if ((ret == -EBUSY) || (ret == -EAGAIN)) {
2722 data_norm = VINO_DATA_NORM_PAL;
2723 ret = vino_saa7191_set_norm(&data_norm);
2724 }
2412 2725
2413 saa7191_input = vino_get_saa7191_input(vcs->input); 2726 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2414 i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input); 2727
2415 saa7191_norm = vino_get_saa7191_norm(vcs->data_norm); 2728 if (ret) {
2416 i2c_decoder_command(DECODER_SAA7191_SET_NORM, 2729 vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
2417 &saa7191_norm); 2730 ret = -EINVAL;
2731 goto out;
2732 }
2733
2734 vcs->input = input;
2735 vcs->data_norm = data_norm;
2418 } else { 2736 } else {
2419 if (vcs2->input != input) { 2737 if (input != vcs2->input) {
2420 ret = -EBUSY; 2738 ret = -EBUSY;
2421 goto out; 2739 goto out;
2422 } 2740 }
@@ -2471,12 +2789,13 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
2471 } 2789 }
2472 2790
2473 vino_set_default_clipping(vcs); 2791 vino_set_default_clipping(vcs);
2792 vino_set_default_scaling(vcs);
2474 vino_set_default_framerate(vcs); 2793 vino_set_default_framerate(vcs);
2475 2794
2476 dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name); 2795 dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name);
2477 2796
2478out: 2797out:
2479 spin_unlock(&vino_drvdata->input_lock); 2798 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2480 2799
2481 return ret; 2800 return ret;
2482} 2801}
@@ -2485,10 +2804,11 @@ static void vino_release_input(struct vino_channel_settings *vcs)
2485{ 2804{
2486 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ? 2805 struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ?
2487 &vino_drvdata->b : &vino_drvdata->a; 2806 &vino_drvdata->b : &vino_drvdata->a;
2807 unsigned long flags;
2488 2808
2489 dprintk("vino_release_input():\n"); 2809 dprintk("vino_release_input():\n");
2490 2810
2491 spin_lock(&vino_drvdata->input_lock); 2811 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2492 2812
2493 /* Release ownership of the channel 2813 /* Release ownership of the channel
2494 * and if the other channel takes input from 2814 * and if the other channel takes input from
@@ -2511,34 +2831,61 @@ static void vino_release_input(struct vino_channel_settings *vcs)
2511 } 2831 }
2512 vcs->input = VINO_INPUT_NONE; 2832 vcs->input = VINO_INPUT_NONE;
2513 2833
2514 spin_unlock(&vino_drvdata->input_lock); 2834 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2515} 2835}
2516 2836
2517/* execute with input_lock locked */ 2837/* execute with input_lock locked */
2518static int vino_set_data_norm(struct vino_channel_settings *vcs, 2838static int vino_set_data_norm(struct vino_channel_settings *vcs,
2519 unsigned int data_norm) 2839 unsigned int data_norm,
2840 unsigned long *flags)
2520{ 2841{
2521 int saa7191_norm; 2842 int err = 0;
2843
2844 if (data_norm == vcs->data_norm)
2845 return 0;
2522 2846
2523 switch (vcs->input) { 2847 switch (vcs->input) {
2524 case VINO_INPUT_D1: 2848 case VINO_INPUT_D1:
2525 /* only one "norm" supported */ 2849 /* only one "norm" supported */
2526 if (data_norm != VINO_DATA_NORM_D1) 2850 if ((data_norm != VINO_DATA_NORM_D1)
2851 && (data_norm != VINO_DATA_NORM_AUTO)
2852 && (data_norm != VINO_DATA_NORM_AUTO_EXT))
2527 return -EINVAL; 2853 return -EINVAL;
2528 break; 2854 break;
2529 case VINO_INPUT_COMPOSITE: 2855 case VINO_INPUT_COMPOSITE:
2530 case VINO_INPUT_SVIDEO: 2856 case VINO_INPUT_SVIDEO: {
2857 if ((data_norm != VINO_DATA_NORM_PAL)
2858 && (data_norm != VINO_DATA_NORM_NTSC)
2859 && (data_norm != VINO_DATA_NORM_SECAM)
2860 && (data_norm != VINO_DATA_NORM_AUTO)
2861 && (data_norm != VINO_DATA_NORM_AUTO_EXT))
2862 return -EINVAL;
2531 2863
2532 saa7191_norm = vino_get_saa7191_norm(data_norm); 2864 spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
2865
2866 /* Don't hold spinlocks while setting norm
2867 * as it may take a while... */
2868
2869 err = vino_saa7191_set_norm(&data_norm);
2870
2871 spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
2872
2873 if (err)
2874 goto out;
2533 2875
2534 i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm);
2535 vcs->data_norm = data_norm; 2876 vcs->data_norm = data_norm;
2877
2878 vino_set_default_clipping(vcs);
2879 vino_set_default_scaling(vcs);
2880 vino_set_default_framerate(vcs);
2536 break; 2881 break;
2882 }
2537 default: 2883 default:
2538 return -EINVAL; 2884 return -EINVAL;
2539 } 2885 }
2540 2886
2541 return 0; 2887out:
2888 return err;
2542} 2889}
2543 2890
2544/* V4L2 helper functions */ 2891/* V4L2 helper functions */
@@ -2558,8 +2905,9 @@ static int vino_find_data_format(__u32 pixelformat)
2558static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index) 2905static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
2559{ 2906{
2560 int data_norm = VINO_DATA_NORM_NONE; 2907 int data_norm = VINO_DATA_NORM_NONE;
2908 unsigned long flags;
2561 2909
2562 spin_lock(&vino_drvdata->input_lock); 2910 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2563 switch(vcs->input) { 2911 switch(vcs->input) {
2564 case VINO_INPUT_COMPOSITE: 2912 case VINO_INPUT_COMPOSITE:
2565 case VINO_INPUT_SVIDEO: 2913 case VINO_INPUT_SVIDEO:
@@ -2577,7 +2925,7 @@ static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
2577 } 2925 }
2578 break; 2926 break;
2579 } 2927 }
2580 spin_unlock(&vino_drvdata->input_lock); 2928 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2581 2929
2582 return data_norm; 2930 return data_norm;
2583} 2931}
@@ -2585,8 +2933,9 @@ static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
2585static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index) 2933static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
2586{ 2934{
2587 int input = VINO_INPUT_NONE; 2935 int input = VINO_INPUT_NONE;
2936 unsigned long flags;
2588 2937
2589 spin_lock(&vino_drvdata->input_lock); 2938 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2590 if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) { 2939 if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
2591 switch (index) { 2940 switch (index) {
2592 case 0: 2941 case 0:
@@ -2615,7 +2964,7 @@ static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
2615 break; 2964 break;
2616 } 2965 }
2617 } 2966 }
2618 spin_unlock(&vino_drvdata->input_lock); 2967 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2619 2968
2620 return input; 2969 return input;
2621} 2970}
@@ -2704,15 +3053,16 @@ static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
2704} 3053}
2705 3054
2706static int vino_v4l2_g_input(struct vino_channel_settings *vcs, 3055static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
2707 struct v4l2_input *i) 3056 unsigned int *i)
2708{ 3057{
2709 __u32 index; 3058 __u32 index;
2710 int input; 3059 int input;
3060 unsigned long flags;
2711 3061
2712 spin_lock(&vino_drvdata->input_lock); 3062 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2713 input = vcs->input; 3063 input = vcs->input;
2714 index = vino_find_input_index(vcs); 3064 index = vino_find_input_index(vcs);
2715 spin_unlock(&vino_drvdata->input_lock); 3065 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2716 3066
2717 dprintk("input = %d\n", input); 3067 dprintk("input = %d\n", input);
2718 3068
@@ -2720,23 +3070,18 @@ static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
2720 return -EINVAL; 3070 return -EINVAL;
2721 } 3071 }
2722 3072
2723 memset(i, 0, sizeof(struct v4l2_input)); 3073 *i = index;
2724
2725 i->index = index;
2726 i->type = V4L2_INPUT_TYPE_CAMERA;
2727 i->std = vino_inputs[input].std;
2728 strcpy(i->name, vino_inputs[input].name);
2729 3074
2730 return 0; 3075 return 0;
2731} 3076}
2732 3077
2733static int vino_v4l2_s_input(struct vino_channel_settings *vcs, 3078static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
2734 struct v4l2_input *i) 3079 unsigned int *i)
2735{ 3080{
2736 int input; 3081 int input;
2737 dprintk("requested input = %d\n", i->index); 3082 dprintk("requested input = %d\n", *i);
2738 3083
2739 input = vino_enum_input(vcs, i->index); 3084 input = vino_enum_input(vcs, *i);
2740 if (input == VINO_INPUT_NONE) 3085 if (input == VINO_INPUT_NONE)
2741 return -EINVAL; 3086 return -EINVAL;
2742 3087
@@ -2747,7 +3092,9 @@ static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
2747 struct v4l2_standard *s) 3092 struct v4l2_standard *s)
2748{ 3093{
2749 int index = s->index; 3094 int index = s->index;
2750 int data_norm = vino_enum_data_norm(vcs, index); 3095 int data_norm;
3096
3097 data_norm = vino_enum_data_norm(vcs, index);
2751 dprintk("standard index = %d\n", index); 3098 dprintk("standard index = %d\n", index);
2752 3099
2753 if (data_norm == VINO_DATA_NORM_NONE) 3100 if (data_norm == VINO_DATA_NORM_NONE)
@@ -2771,13 +3118,55 @@ static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
2771 return 0; 3118 return 0;
2772} 3119}
2773 3120
3121static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
3122 v4l2_std_id *std)
3123{
3124 unsigned long flags;
3125 int err = 0;
3126
3127 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3128
3129 switch (vcs->input) {
3130 case VINO_INPUT_D1:
3131 *std = vino_inputs[vcs->input].std;
3132 break;
3133 case VINO_INPUT_COMPOSITE:
3134 case VINO_INPUT_SVIDEO: {
3135 struct saa7191_status status;
3136
3137 i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
3138
3139 if (status.signal) {
3140 if (status.signal_60hz) {
3141 *std = V4L2_STD_NTSC;
3142 } else {
3143 *std = V4L2_STD_PAL | V4L2_STD_SECAM;
3144 }
3145 } else {
3146 *std = vino_inputs[vcs->input].std;
3147 }
3148 break;
3149 }
3150 default:
3151 err = -EINVAL;
3152 }
3153
3154 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3155
3156 return err;
3157}
3158
2774static int vino_v4l2_g_std(struct vino_channel_settings *vcs, 3159static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
2775 v4l2_std_id *std) 3160 v4l2_std_id *std)
2776{ 3161{
2777 spin_lock(&vino_drvdata->input_lock); 3162 unsigned long flags;
2778 dprintk("current standard = %d\n", vcs->data_norm); 3163
3164 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3165
2779 *std = vino_data_norms[vcs->data_norm].std; 3166 *std = vino_data_norms[vcs->data_norm].std;
2780 spin_unlock(&vino_drvdata->input_lock); 3167 dprintk("current standard = %d\n", vcs->data_norm);
3168
3169 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2781 3170
2782 return 0; 3171 return 0;
2783} 3172}
@@ -2785,13 +3174,18 @@ static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
2785static int vino_v4l2_s_std(struct vino_channel_settings *vcs, 3174static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
2786 v4l2_std_id *std) 3175 v4l2_std_id *std)
2787{ 3176{
3177 unsigned long flags;
2788 int ret = 0; 3178 int ret = 0;
2789 3179
2790 spin_lock(&vino_drvdata->input_lock); 3180 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3181
3182 if (!vino_is_input_owner(vcs)) {
3183 ret = -EBUSY;
3184 goto out;
3185 }
2791 3186
2792 /* check if the standard is valid for the current input */ 3187 /* check if the standard is valid for the current input */
2793 if (vino_is_input_owner(vcs) 3188 if ((*std) & vino_inputs[vcs->input].std) {
2794 && (vino_inputs[vcs->input].std & (*std))) {
2795 dprintk("standard accepted\n"); 3189 dprintk("standard accepted\n");
2796 3190
2797 /* change the video norm for SAA7191 3191 /* change the video norm for SAA7191
@@ -2800,24 +3194,33 @@ static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
2800 if (vcs->input == VINO_INPUT_D1) 3194 if (vcs->input == VINO_INPUT_D1)
2801 goto out; 3195 goto out;
2802 3196
2803 if ((*std) & V4L2_STD_PAL) { 3197 if (((*std) & V4L2_STD_PAL)
2804 vino_set_data_norm(vcs, VINO_DATA_NORM_PAL); 3198 && ((*std) & V4L2_STD_NTSC)
2805 vcs->data_norm = VINO_DATA_NORM_PAL; 3199 && ((*std) & V4L2_STD_SECAM)) {
3200 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT,
3201 &flags);
3202 } else if ((*std) & V4L2_STD_PAL) {
3203 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
3204 &flags);
2806 } else if ((*std) & V4L2_STD_NTSC) { 3205 } else if ((*std) & V4L2_STD_NTSC) {
2807 vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC); 3206 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC,
2808 vcs->data_norm = VINO_DATA_NORM_NTSC; 3207 &flags);
2809 } else if ((*std) & V4L2_STD_SECAM) { 3208 } else if ((*std) & V4L2_STD_SECAM) {
2810 vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM); 3209 ret = vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM,
2811 vcs->data_norm = VINO_DATA_NORM_SECAM; 3210 &flags);
2812 } else { 3211 } else {
2813 ret = -EINVAL; 3212 ret = -EINVAL;
2814 } 3213 }
3214
3215 if (ret) {
3216 ret = -EINVAL;
3217 }
2815 } else { 3218 } else {
2816 ret = -EINVAL; 3219 ret = -EINVAL;
2817 } 3220 }
2818 3221
2819out: 3222out:
2820 spin_unlock(&vino_drvdata->input_lock); 3223 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2821 3224
2822 return ret; 3225 return ret;
2823} 3226}
@@ -2855,6 +3258,7 @@ static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
2855 struct v4l2_format *f) 3258 struct v4l2_format *f)
2856{ 3259{
2857 struct vino_channel_settings tempvcs; 3260 struct vino_channel_settings tempvcs;
3261 unsigned long flags;
2858 3262
2859 switch (f->type) { 3263 switch (f->type) {
2860 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3264 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
@@ -2863,13 +3267,13 @@ static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
2863 dprintk("requested: w = %d, h = %d\n", 3267 dprintk("requested: w = %d, h = %d\n",
2864 pf->width, pf->height); 3268 pf->width, pf->height);
2865 3269
2866 spin_lock(&vino_drvdata->input_lock); 3270 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2867 memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings)); 3271 memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
2868 spin_unlock(&vino_drvdata->input_lock); 3272 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2869 3273
2870 tempvcs.data_format = vino_find_data_format(pf->pixelformat); 3274 tempvcs.data_format = vino_find_data_format(pf->pixelformat);
2871 if (tempvcs.data_format == VINO_DATA_FMT_NONE) { 3275 if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
2872 tempvcs.data_format = VINO_DATA_FMT_RGB32; 3276 tempvcs.data_format = VINO_DATA_FMT_GREY;
2873 pf->pixelformat = 3277 pf->pixelformat =
2874 vino_data_formats[tempvcs.data_format]. 3278 vino_data_formats[tempvcs.data_format].
2875 pixelformat; 3279 pixelformat;
@@ -2908,10 +3312,13 @@ static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
2908static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs, 3312static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
2909 struct v4l2_format *f) 3313 struct v4l2_format *f)
2910{ 3314{
3315 unsigned long flags;
3316
2911 switch (f->type) { 3317 switch (f->type) {
2912 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3318 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
2913 struct v4l2_pix_format *pf = &f->fmt.pix; 3319 struct v4l2_pix_format *pf = &f->fmt.pix;
2914 spin_lock(&vino_drvdata->input_lock); 3320
3321 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2915 3322
2916 pf->width = (vcs->clipping.right - vcs->clipping.left) / 3323 pf->width = (vcs->clipping.right - vcs->clipping.left) /
2917 vcs->decimation; 3324 vcs->decimation;
@@ -2930,7 +3337,7 @@ static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
2930 3337
2931 pf->priv = 0; 3338 pf->priv = 0;
2932 3339
2933 spin_unlock(&vino_drvdata->input_lock); 3340 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2934 break; 3341 break;
2935 } 3342 }
2936 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3343 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
@@ -2945,20 +3352,18 @@ static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
2945 struct v4l2_format *f) 3352 struct v4l2_format *f)
2946{ 3353{
2947 int data_format; 3354 int data_format;
3355 unsigned long flags;
2948 3356
2949 switch (f->type) { 3357 switch (f->type) {
2950 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3358 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
2951 struct v4l2_pix_format *pf = &f->fmt.pix; 3359 struct v4l2_pix_format *pf = &f->fmt.pix;
2952 spin_lock(&vino_drvdata->input_lock);
2953 3360
2954 if (!vino_is_input_owner(vcs)) { 3361 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
2955 spin_unlock(&vino_drvdata->input_lock);
2956 return -EINVAL;
2957 }
2958 3362
2959 data_format = vino_find_data_format(pf->pixelformat); 3363 data_format = vino_find_data_format(pf->pixelformat);
3364
2960 if (data_format == VINO_DATA_FMT_NONE) { 3365 if (data_format == VINO_DATA_FMT_NONE) {
2961 vcs->data_format = VINO_DATA_FMT_RGB32; 3366 vcs->data_format = VINO_DATA_FMT_GREY;
2962 pf->pixelformat = 3367 pf->pixelformat =
2963 vino_data_formats[vcs->data_format]. 3368 vino_data_formats[vcs->data_format].
2964 pixelformat; 3369 pixelformat;
@@ -2985,7 +3390,7 @@ static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
2985 3390
2986 pf->priv = 0; 3391 pf->priv = 0;
2987 3392
2988 spin_unlock(&vino_drvdata->input_lock); 3393 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
2989 break; 3394 break;
2990 } 3395 }
2991 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3396 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
@@ -3000,12 +3405,15 @@ static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
3000 struct v4l2_cropcap *ccap) 3405 struct v4l2_cropcap *ccap)
3001{ 3406{
3002 const struct vino_data_norm *norm; 3407 const struct vino_data_norm *norm;
3408 unsigned long flags;
3003 3409
3004 switch (ccap->type) { 3410 switch (ccap->type) {
3005 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 3411 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3006 spin_lock(&vino_drvdata->input_lock); 3412 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3413
3007 norm = &vino_data_norms[vcs->data_norm]; 3414 norm = &vino_data_norms[vcs->data_norm];
3008 spin_unlock(&vino_drvdata->input_lock); 3415
3416 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3009 3417
3010 ccap->bounds.left = 0; 3418 ccap->bounds.left = 0;
3011 ccap->bounds.top = 0; 3419 ccap->bounds.top = 0;
@@ -3028,16 +3436,18 @@ static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
3028static int vino_v4l2_g_crop(struct vino_channel_settings *vcs, 3436static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
3029 struct v4l2_crop *c) 3437 struct v4l2_crop *c)
3030{ 3438{
3439 unsigned long flags;
3440
3031 switch (c->type) { 3441 switch (c->type) {
3032 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 3442 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3033 spin_lock(&vino_drvdata->input_lock); 3443 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3034 3444
3035 c->c.left = vcs->clipping.left; 3445 c->c.left = vcs->clipping.left;
3036 c->c.top = vcs->clipping.top; 3446 c->c.top = vcs->clipping.top;
3037 c->c.width = vcs->clipping.right - vcs->clipping.left; 3447 c->c.width = vcs->clipping.right - vcs->clipping.left;
3038 c->c.height = vcs->clipping.bottom - vcs->clipping.top; 3448 c->c.height = vcs->clipping.bottom - vcs->clipping.top;
3039 3449
3040 spin_unlock(&vino_drvdata->input_lock); 3450 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3041 break; 3451 break;
3042 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3452 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3043 default: 3453 default:
@@ -3050,18 +3460,16 @@ static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
3050static int vino_v4l2_s_crop(struct vino_channel_settings *vcs, 3460static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
3051 struct v4l2_crop *c) 3461 struct v4l2_crop *c)
3052{ 3462{
3463 unsigned long flags;
3464
3053 switch (c->type) { 3465 switch (c->type) {
3054 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 3466 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
3055 spin_lock(&vino_drvdata->input_lock); 3467 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3056 3468
3057 if (!vino_is_input_owner(vcs)) {
3058 spin_unlock(&vino_drvdata->input_lock);
3059 return -EINVAL;
3060 }
3061 vino_set_clipping(vcs, c->c.left, c->c.top, 3469 vino_set_clipping(vcs, c->c.left, c->c.top,
3062 c->c.width, c->c.height); 3470 c->c.width, c->c.height);
3063 3471
3064 spin_unlock(&vino_drvdata->input_lock); 3472 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3065 break; 3473 break;
3066 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3474 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
3067 default: 3475 default:
@@ -3074,6 +3482,8 @@ static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
3074static int vino_v4l2_g_parm(struct vino_channel_settings *vcs, 3482static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
3075 struct v4l2_streamparm *sp) 3483 struct v4l2_streamparm *sp)
3076{ 3484{
3485 unsigned long flags;
3486
3077 switch (sp->type) { 3487 switch (sp->type) {
3078 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3488 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3079 struct v4l2_captureparm *cp = &sp->parm.capture; 3489 struct v4l2_captureparm *cp = &sp->parm.capture;
@@ -3082,9 +3492,11 @@ static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
3082 cp->capability = V4L2_CAP_TIMEPERFRAME; 3492 cp->capability = V4L2_CAP_TIMEPERFRAME;
3083 cp->timeperframe.numerator = 1; 3493 cp->timeperframe.numerator = 1;
3084 3494
3085 spin_lock(&vino_drvdata->input_lock); 3495 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3496
3086 cp->timeperframe.denominator = vcs->fps; 3497 cp->timeperframe.denominator = vcs->fps;
3087 spin_unlock(&vino_drvdata->input_lock); 3498
3499 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3088 3500
3089 // TODO: cp->readbuffers = xxx; 3501 // TODO: cp->readbuffers = xxx;
3090 break; 3502 break;
@@ -3100,15 +3512,13 @@ static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
3100static int vino_v4l2_s_parm(struct vino_channel_settings *vcs, 3512static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
3101 struct v4l2_streamparm *sp) 3513 struct v4l2_streamparm *sp)
3102{ 3514{
3515 unsigned long flags;
3516
3103 switch (sp->type) { 3517 switch (sp->type) {
3104 case V4L2_BUF_TYPE_VIDEO_CAPTURE: { 3518 case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
3105 struct v4l2_captureparm *cp = &sp->parm.capture; 3519 struct v4l2_captureparm *cp = &sp->parm.capture;
3106 3520
3107 spin_lock(&vino_drvdata->input_lock); 3521 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3108 if (!vino_is_input_owner(vcs)) {
3109 spin_unlock(&vino_drvdata->input_lock);
3110 return -EINVAL;
3111 }
3112 3522
3113 if ((cp->timeperframe.numerator == 0) || 3523 if ((cp->timeperframe.numerator == 0) ||
3114 (cp->timeperframe.denominator == 0)) { 3524 (cp->timeperframe.denominator == 0)) {
@@ -3118,7 +3528,8 @@ static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
3118 vino_set_framerate(vcs, cp->timeperframe.denominator / 3528 vino_set_framerate(vcs, cp->timeperframe.denominator /
3119 cp->timeperframe.numerator); 3529 cp->timeperframe.numerator);
3120 } 3530 }
3121 spin_unlock(&vino_drvdata->input_lock); 3531
3532 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3122 3533
3123 // TODO: set buffers according to cp->readbuffers 3534 // TODO: set buffers according to cp->readbuffers
3124 break; 3535 break;
@@ -3145,21 +3556,23 @@ static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
3145 return -EINVAL; 3556 return -EINVAL;
3146 } 3557 }
3147 3558
3148 if (vino_is_capturing(vcs)) {
3149 dprintk("busy, capturing\n");
3150 return -EBUSY;
3151 }
3152
3153 dprintk("count = %d\n", rb->count); 3559 dprintk("count = %d\n", rb->count);
3154 if (rb->count > 0) { 3560 if (rb->count > 0) {
3561 if (vino_is_capturing(vcs)) {
3562 dprintk("busy, capturing\n");
3563 return -EBUSY;
3564 }
3565
3155 if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) { 3566 if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
3156 dprintk("busy, buffers still mapped\n"); 3567 dprintk("busy, buffers still mapped\n");
3157 return -EBUSY; 3568 return -EBUSY;
3158 } else { 3569 } else {
3570 vcs->streaming = 0;
3159 vino_queue_free(&vcs->fb_queue); 3571 vino_queue_free(&vcs->fb_queue);
3160 vino_queue_init(&vcs->fb_queue, &rb->count); 3572 vino_queue_init(&vcs->fb_queue, &rb->count);
3161 } 3573 }
3162 } else { 3574 } else {
3575 vcs->streaming = 0;
3163 vino_capture_stop(vcs); 3576 vino_capture_stop(vcs);
3164 vino_queue_free(&vcs->fb_queue); 3577 vino_queue_free(&vcs->fb_queue);
3165 } 3578 }
@@ -3302,12 +3715,12 @@ static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
3302 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming); 3715 err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
3303 if (err) { 3716 if (err) {
3304 dprintk("vino_queue_get_incoming() failed\n"); 3717 dprintk("vino_queue_get_incoming() failed\n");
3305 return -EIO; 3718 return -EINVAL;
3306 } 3719 }
3307 err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing); 3720 err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
3308 if (err) { 3721 if (err) {
3309 dprintk("vino_queue_get_outgoing() failed\n"); 3722 dprintk("vino_queue_get_outgoing() failed\n");
3310 return -EIO; 3723 return -EINVAL;
3311 } 3724 }
3312 3725
3313 dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing); 3726 dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
@@ -3327,8 +3740,10 @@ static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
3327 if (err) { 3740 if (err) {
3328 err = vino_wait_for_frame(vcs); 3741 err = vino_wait_for_frame(vcs);
3329 if (err) { 3742 if (err) {
3330 /* interrupted */ 3743 /* interrupted or
3331 vino_capture_failed(vcs); 3744 * no frames captured because
3745 * of frame skipping */
3746 // vino_capture_failed(vcs);
3332 return -EIO; 3747 return -EIO;
3333 } 3748 }
3334 } 3749 }
@@ -3341,10 +3756,12 @@ static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
3341 } 3756 }
3342 3757
3343 err = vino_check_buffer(vcs, fb); 3758 err = vino_check_buffer(vcs, fb);
3759
3760 vino_v4l2_get_buffer_status(vcs, fb, b);
3761
3344 if (err) 3762 if (err)
3345 return -EIO; 3763 return -EIO;
3346 3764
3347 vino_v4l2_get_buffer_status(vcs, fb, b);
3348 break; 3765 break;
3349 } 3766 }
3350 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 3767 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
@@ -3401,8 +3818,8 @@ static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
3401 if (!vcs->streaming) 3818 if (!vcs->streaming)
3402 return 0; 3819 return 0;
3403 3820
3404 vino_capture_stop(vcs);
3405 vcs->streaming = 0; 3821 vcs->streaming = 0;
3822 vino_capture_stop(vcs);
3406 3823
3407 return 0; 3824 return 0;
3408} 3825}
@@ -3410,10 +3827,11 @@ static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
3410static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs, 3827static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
3411 struct v4l2_queryctrl *queryctrl) 3828 struct v4l2_queryctrl *queryctrl)
3412{ 3829{
3830 unsigned long flags;
3413 int i; 3831 int i;
3414 int err = 0; 3832 int err = 0;
3415 3833
3416 spin_lock(&vino_drvdata->input_lock); 3834 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3417 3835
3418 switch (vcs->input) { 3836 switch (vcs->input) {
3419 case VINO_INPUT_D1: 3837 case VINO_INPUT_D1:
@@ -3423,6 +3841,7 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
3423 memcpy(queryctrl, 3841 memcpy(queryctrl,
3424 &vino_indycam_v4l2_controls[i], 3842 &vino_indycam_v4l2_controls[i],
3425 sizeof(struct v4l2_queryctrl)); 3843 sizeof(struct v4l2_queryctrl));
3844 queryctrl->reserved[0] = 0;
3426 goto found; 3845 goto found;
3427 } 3846 }
3428 } 3847 }
@@ -3437,6 +3856,7 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
3437 memcpy(queryctrl, 3856 memcpy(queryctrl,
3438 &vino_saa7191_v4l2_controls[i], 3857 &vino_saa7191_v4l2_controls[i],
3439 sizeof(struct v4l2_queryctrl)); 3858 sizeof(struct v4l2_queryctrl));
3859 queryctrl->reserved[0] = 0;
3440 goto found; 3860 goto found;
3441 } 3861 }
3442 } 3862 }
@@ -3448,7 +3868,7 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
3448 } 3868 }
3449 3869
3450 found: 3870 found:
3451 spin_unlock(&vino_drvdata->input_lock); 3871 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3452 3872
3453 return err; 3873 return err;
3454} 3874}
@@ -3456,70 +3876,72 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
3456static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs, 3876static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
3457 struct v4l2_control *control) 3877 struct v4l2_control *control)
3458{ 3878{
3459 struct indycam_control indycam_ctrl; 3879 unsigned long flags;
3460 struct saa7191_control saa7191_ctrl; 3880 int i;
3461 int err = 0; 3881 int err = 0;
3462 3882
3463 spin_lock(&vino_drvdata->input_lock); 3883 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3464 3884
3465 switch (vcs->input) { 3885 switch (vcs->input) {
3466 case VINO_INPUT_D1: 3886 case VINO_INPUT_D1: {
3467 i2c_camera_command(DECODER_INDYCAM_GET_CONTROLS, 3887 struct indycam_control indycam_ctrl;
3468 &indycam_ctrl);
3469 3888
3470 switch(control->id) { 3889 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3471 case V4L2_CID_AUTOGAIN: 3890 if (vino_indycam_v4l2_controls[i].id ==
3472 control->value = indycam_ctrl.agc; 3891 control->id) {
3473 break; 3892 goto found1;
3474 case V4L2_CID_AUTO_WHITE_BALANCE: 3893 }
3475 control->value = indycam_ctrl.awb; 3894 }
3476 break; 3895
3477 case V4L2_CID_GAIN: 3896 err = -EINVAL;
3478 control->value = indycam_ctrl.gain; 3897 goto out;
3479 break; 3898
3480 case V4L2_CID_PRIVATE_BASE: 3899found1:
3481 control->value = indycam_ctrl.red_saturation; 3900 indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
3482 break; 3901
3483 case V4L2_CID_PRIVATE_BASE + 1: 3902 err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL,
3484 control->value = indycam_ctrl.blue_saturation; 3903 &indycam_ctrl);
3485 break; 3904 if (err) {
3486 case V4L2_CID_RED_BALANCE:
3487 control->value = indycam_ctrl.red_balance;
3488 break;
3489 case V4L2_CID_BLUE_BALANCE:
3490 control->value = indycam_ctrl.blue_balance;
3491 break;
3492 case V4L2_CID_EXPOSURE:
3493 control->value = indycam_ctrl.shutter;
3494 break;
3495 case V4L2_CID_GAMMA:
3496 control->value = indycam_ctrl.gamma;
3497 break;
3498 default:
3499 err = -EINVAL; 3905 err = -EINVAL;
3906 goto out;
3500 } 3907 }
3908
3909 control->value = indycam_ctrl.value;
3501 break; 3910 break;
3911 }
3502 case VINO_INPUT_COMPOSITE: 3912 case VINO_INPUT_COMPOSITE:
3503 case VINO_INPUT_SVIDEO: 3913 case VINO_INPUT_SVIDEO: {
3504 i2c_decoder_command(DECODER_SAA7191_GET_CONTROLS, 3914 struct saa7191_control saa7191_ctrl;
3505 &saa7191_ctrl);
3506 3915
3507 switch(control->id) { 3916 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3508 case V4L2_CID_HUE: 3917 if (vino_saa7191_v4l2_controls[i].id ==
3509 control->value = saa7191_ctrl.hue; 3918 control->id) {
3510 break; 3919 goto found2;
3511 case V4L2_CID_PRIVATE_BASE: 3920 }
3512 control->value = saa7191_ctrl.vtrc; 3921 }
3513 break; 3922
3514 default: 3923 err = -EINVAL;
3924 goto out;
3925
3926found2:
3927 saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
3928
3929 err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL,
3930 &saa7191_ctrl);
3931 if (err) {
3515 err = -EINVAL; 3932 err = -EINVAL;
3933 goto out;
3516 } 3934 }
3935
3936 control->value = saa7191_ctrl.value;
3517 break; 3937 break;
3938 }
3518 default: 3939 default:
3519 err = -EINVAL; 3940 err = -EINVAL;
3520 } 3941 }
3521 3942
3522 spin_unlock(&vino_drvdata->input_lock); 3943out:
3944 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3523 3945
3524 return err; 3946 return err;
3525} 3947}
@@ -3527,15 +3949,21 @@ static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
3527static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs, 3949static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
3528 struct v4l2_control *control) 3950 struct v4l2_control *control)
3529{ 3951{
3530 struct indycam_control indycam_ctrl; 3952 unsigned long flags;
3531 struct saa7191_control saa7191_ctrl;
3532 int i; 3953 int i;
3533 int err = 0; 3954 int err = 0;
3534 3955
3535 spin_lock(&vino_drvdata->input_lock); 3956 spin_lock_irqsave(&vino_drvdata->input_lock, flags);
3957
3958 if (!vino_is_input_owner(vcs)) {
3959 err = -EBUSY;
3960 goto out;
3961 }
3536 3962
3537 switch (vcs->input) { 3963 switch (vcs->input) {
3538 case VINO_INPUT_D1: 3964 case VINO_INPUT_D1: {
3965 struct indycam_control indycam_ctrl;
3966
3539 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { 3967 for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
3540 if (vino_indycam_v4l2_controls[i].id == 3968 if (vino_indycam_v4l2_controls[i].id ==
3541 control->id) { 3969 control->id) {
@@ -3544,65 +3972,31 @@ static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
3544 && (control->value <= 3972 && (control->value <=
3545 vino_indycam_v4l2_controls[i]. 3973 vino_indycam_v4l2_controls[i].
3546 maximum)) { 3974 maximum)) {
3547 goto ok1; 3975 goto found1;
3548 } else { 3976 } else {
3549 err = -ERANGE; 3977 err = -ERANGE;
3550 goto error; 3978 goto out;
3551 } 3979 }
3552 } 3980 }
3553 } 3981 }
3982
3554 err = -EINVAL; 3983 err = -EINVAL;
3555 goto error; 3984 goto out;
3556 3985
3557ok1: 3986found1:
3558 indycam_ctrl.agc = INDYCAM_VALUE_UNCHANGED; 3987 indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
3559 indycam_ctrl.awb = INDYCAM_VALUE_UNCHANGED; 3988 indycam_ctrl.value = control->value;
3560 indycam_ctrl.shutter = INDYCAM_VALUE_UNCHANGED;
3561 indycam_ctrl.gain = INDYCAM_VALUE_UNCHANGED;
3562 indycam_ctrl.red_balance = INDYCAM_VALUE_UNCHANGED;
3563 indycam_ctrl.blue_balance = INDYCAM_VALUE_UNCHANGED;
3564 indycam_ctrl.red_saturation = INDYCAM_VALUE_UNCHANGED;
3565 indycam_ctrl.blue_saturation = INDYCAM_VALUE_UNCHANGED;
3566 indycam_ctrl.gamma = INDYCAM_VALUE_UNCHANGED;
3567
3568 switch(control->id) {
3569 case V4L2_CID_AUTOGAIN:
3570 indycam_ctrl.agc = control->value;
3571 break;
3572 case V4L2_CID_AUTO_WHITE_BALANCE:
3573 indycam_ctrl.awb = control->value;
3574 break;
3575 case V4L2_CID_GAIN:
3576 indycam_ctrl.gain = control->value;
3577 break;
3578 case V4L2_CID_PRIVATE_BASE:
3579 indycam_ctrl.red_saturation = control->value;
3580 break;
3581 case V4L2_CID_PRIVATE_BASE + 1:
3582 indycam_ctrl.blue_saturation = control->value;
3583 break;
3584 case V4L2_CID_RED_BALANCE:
3585 indycam_ctrl.red_balance = control->value;
3586 break;
3587 case V4L2_CID_BLUE_BALANCE:
3588 indycam_ctrl.blue_balance = control->value;
3589 break;
3590 case V4L2_CID_EXPOSURE:
3591 indycam_ctrl.shutter = control->value;
3592 break;
3593 case V4L2_CID_GAMMA:
3594 indycam_ctrl.gamma = control->value;
3595 break;
3596 default:
3597 err = -EINVAL;
3598 }
3599 3989
3600 if (!err) 3990 err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL,
3601 i2c_camera_command(DECODER_INDYCAM_SET_CONTROLS, 3991 &indycam_ctrl);
3602 &indycam_ctrl); 3992 if (err)
3993 err = -EINVAL;
3603 break; 3994 break;
3995 }
3604 case VINO_INPUT_COMPOSITE: 3996 case VINO_INPUT_COMPOSITE:
3605 case VINO_INPUT_SVIDEO: 3997 case VINO_INPUT_SVIDEO: {
3998 struct saa7191_control saa7191_ctrl;
3999
3606 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { 4000 for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
3607 if (vino_saa7191_v4l2_controls[i].id == 4001 if (vino_saa7191_v4l2_controls[i].id ==
3608 control->id) { 4002 control->id) {
@@ -3611,41 +4005,32 @@ ok1:
3611 && (control->value <= 4005 && (control->value <=
3612 vino_saa7191_v4l2_controls[i]. 4006 vino_saa7191_v4l2_controls[i].
3613 maximum)) { 4007 maximum)) {
3614 goto ok2; 4008 goto found2;
3615 } else { 4009 } else {
3616 err = -ERANGE; 4010 err = -ERANGE;
3617 goto error; 4011 goto out;
3618 } 4012 }
3619 } 4013 }
3620 } 4014 }
3621 err = -EINVAL; 4015 err = -EINVAL;
3622 goto error; 4016 goto out;
3623
3624ok2:
3625 saa7191_ctrl.hue = SAA7191_VALUE_UNCHANGED;
3626 saa7191_ctrl.vtrc = SAA7191_VALUE_UNCHANGED;
3627 4017
3628 switch(control->id) { 4018found2:
3629 case V4L2_CID_HUE: 4019 saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
3630 saa7191_ctrl.hue = control->value; 4020 saa7191_ctrl.value = control->value;
3631 break;
3632 case V4L2_CID_PRIVATE_BASE:
3633 saa7191_ctrl.vtrc = control->value;
3634 break;
3635 default:
3636 err = -EINVAL;
3637 }
3638 4021
3639 if (!err) 4022 err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL,
3640 i2c_decoder_command(DECODER_SAA7191_SET_CONTROLS, 4023 &saa7191_ctrl);
3641 &saa7191_ctrl); 4024 if (err)
4025 err = -EINVAL;
3642 break; 4026 break;
4027 }
3643 default: 4028 default:
3644 err = -EINVAL; 4029 err = -EINVAL;
3645 } 4030 }
3646 4031
3647error: 4032out:
3648 spin_unlock(&vino_drvdata->input_lock); 4033 spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
3649 4034
3650 return err; 4035 return err;
3651} 4036}
@@ -3865,9 +4250,9 @@ static unsigned int vino_poll(struct file *file, poll_table *pt)
3865over: 4250over:
3866 dprintk("poll(): data %savailable\n", 4251 dprintk("poll(): data %savailable\n",
3867 (outgoing > 0) ? "" : "not "); 4252 (outgoing > 0) ? "" : "not ");
3868 if (outgoing > 0) { 4253
4254 if (outgoing > 0)
3869 ret = POLLIN | POLLRDNORM; 4255 ret = POLLIN | POLLRDNORM;
3870 }
3871 4256
3872error: 4257error:
3873 4258
@@ -3880,6 +4265,7 @@ static int vino_do_ioctl(struct inode *inode, struct file *file,
3880 struct video_device *dev = video_devdata(file); 4265 struct video_device *dev = video_devdata(file);
3881 struct vino_channel_settings *vcs = video_get_drvdata(dev); 4266 struct vino_channel_settings *vcs = video_get_drvdata(dev);
3882 4267
4268#ifdef VINO_DEBUG
3883 switch (_IOC_TYPE(cmd)) { 4269 switch (_IOC_TYPE(cmd)) {
3884 case 'v': 4270 case 'v':
3885 dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd); 4271 dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
@@ -3891,9 +4277,9 @@ static int vino_do_ioctl(struct inode *inode, struct file *file,
3891 default: 4277 default:
3892 dprintk("ioctl(): unsupported command 0x%08x\n", cmd); 4278 dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
3893 } 4279 }
4280#endif
3894 4281
3895 switch (cmd) { 4282 switch (cmd) {
3896 /* TODO: V4L1 interface (use compatibility layer?) */
3897 /* V4L2 interface */ 4283 /* V4L2 interface */
3898 case VIDIOC_QUERYCAP: { 4284 case VIDIOC_QUERYCAP: {
3899 vino_v4l2_querycap(arg); 4285 vino_v4l2_querycap(arg);
@@ -3911,6 +4297,9 @@ static int vino_do_ioctl(struct inode *inode, struct file *file,
3911 case VIDIOC_ENUMSTD: { 4297 case VIDIOC_ENUMSTD: {
3912 return vino_v4l2_enumstd(vcs, arg); 4298 return vino_v4l2_enumstd(vcs, arg);
3913 } 4299 }
4300 case VIDIOC_QUERYSTD: {
4301 return vino_v4l2_querystd(vcs, arg);
4302 }
3914 case VIDIOC_G_STD: { 4303 case VIDIOC_G_STD: {
3915 return vino_v4l2_g_std(vcs, arg); 4304 return vino_v4l2_g_std(vcs, arg);
3916 } 4305 }
@@ -4100,8 +4489,7 @@ static int vino_probe(void)
4100 return -ENODEV; 4489 return -ENODEV;
4101 } 4490 }
4102 4491
4103 printk(KERN_INFO "VINO with chip ID %ld, revision %ld found\n", 4492 printk(KERN_INFO "VINO revision %ld found\n", VINO_REV_NUM(rev_id));
4104 VINO_ID_VALUE(rev_id), VINO_REV_NUM(rev_id));
4105 4493
4106 return 0; 4494 return 0;
4107} 4495}
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
new file mode 100644
index 000000000000..22f286222004
--- /dev/null
+++ b/drivers/media/video/wm8775.c
@@ -0,0 +1,254 @@
1/*
2 * wm8775 - driver version 0.0.1
3 *
4 * Copyright (C) 2004 Ulf Eklund <ivtv at eklund.to>
5 *
6 * Based on saa7115 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23
24#include <linux/module.h>
25#include <linux/types.h>
26#include <linux/ioctl.h>
27#include <asm/uaccess.h>
28#include <linux/i2c.h>
29#include <linux/i2c-id.h>
30#include <linux/videodev.h>
31#include <media/audiochip.h>
32
33MODULE_DESCRIPTION("wm8775 driver");
34MODULE_AUTHOR("Ulf Eklund");
35MODULE_LICENSE("GPL");
36
37#define wm8775_err(fmt, arg...) do { \
38 printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
39 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
40#define wm8775_info(fmt, arg...) do { \
41 printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
42 i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
43
44
45static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
46
47
48I2C_CLIENT_INSMOD;
49
50/* ----------------------------------------------------------------------- */
51
52enum {
53 R7 = 7, R11 = 11,
54 R12, R13, R14, R15, R16, R17, R18, R19, R20, R21, R23 = 23,
55 TOT_REGS
56};
57
58struct wm8775_state {
59 u8 input; /* Last selected input (0-0xf) */
60 u8 muted;
61};
62
63static int wm8775_write(struct i2c_client *client, int reg, u16 val)
64{
65 int i;
66
67 if (reg < 0 || reg >= TOT_REGS) {
68 wm8775_err("Invalid register R%d\n", reg);
69 return -1;
70 }
71
72 for (i = 0; i < 3; i++) {
73 if (i2c_smbus_write_byte_data(client, (reg << 1) |
74 (val >> 8), val & 0xff) == 0) {
75 return 0;
76 }
77 }
78 wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg);
79 return -1;
80}
81
82static int wm8775_command(struct i2c_client *client, unsigned int cmd,
83 void *arg)
84{
85 struct wm8775_state *state = i2c_get_clientdata(client);
86 int *input = arg;
87
88 switch (cmd) {
89 case AUDC_SET_INPUT:
90 wm8775_write(client, R21, 0x0c0);
91 wm8775_write(client, R14, 0x1d4);
92 wm8775_write(client, R15, 0x1d4);
93
94 if (*input == AUDIO_RADIO) {
95 wm8775_write(client, R21, 0x108);
96 state->input = 8;
97 state->muted = 0;
98 break;
99 }
100 if (*input == AUDIO_MUTE) {
101 state->muted = 1;
102 break;
103 }
104 if (*input == AUDIO_UNMUTE) {
105 wm8775_write(client, R21, 0x100 + state->input);
106 state->muted = 0;
107 break;
108 }
109 /* All other inputs... */
110 wm8775_write(client, R21, 0x102);
111 state->input = 2;
112 state->muted = 0;
113 break;
114
115 case VIDIOC_LOG_STATUS:
116 wm8775_info("Input: %s%s\n",
117 state->input == 8 ? "radio" : "default",
118 state->muted ? " (muted)" : "");
119 break;
120
121 case VIDIOC_S_FREQUENCY:
122 /* If I remove this, then it can happen that I have no
123 sound the first time I tune from static to a valid channel.
124 It's difficult to reproduce and is almost certainly related
125 to the zero cross detect circuit. */
126 wm8775_write(client, R21, 0x0c0);
127 wm8775_write(client, R14, 0x1d4);
128 wm8775_write(client, R15, 0x1d4);
129 wm8775_write(client, R21, 0x100 + state->input);
130 break;
131
132 default:
133 return -EINVAL;
134 }
135 return 0;
136}
137
138/* ----------------------------------------------------------------------- */
139
140/* i2c implementation */
141
142/*
143 * Generic i2c probe
144 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
145 */
146
147static struct i2c_driver i2c_driver;
148
149static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind)
150{
151 struct i2c_client *client;
152 struct wm8775_state *state;
153
154 /* Check if the adapter supports the needed features */
155 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
156 return 0;
157
158 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
159 if (client == 0)
160 return -ENOMEM;
161
162 memset(client, 0, sizeof(struct i2c_client));
163 client->addr = address;
164 client->adapter = adapter;
165 client->driver = &i2c_driver;
166 client->flags = I2C_CLIENT_ALLOW_USE;
167 snprintf(client->name, sizeof(client->name) - 1, "wm8775");
168
169 wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
170
171 state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL);
172 if (state == NULL) {
173 kfree(client);
174 return -ENOMEM;
175 }
176 state->input = 2;
177 state->muted = 0;
178 i2c_set_clientdata(client, state);
179
180 /* initialize wm8775 */
181 wm8775_write(client, R23, 0x000); /* RESET */
182 wm8775_write(client, R7, 0x000); /* Disable zero cross detect timeout */
183 wm8775_write(client, R11, 0x021); /* Left justified, 24-bit mode */
184 wm8775_write(client, R12, 0x102); /* Master mode, clock ratio 256fs */
185 wm8775_write(client, R13, 0x000); /* Powered up */
186 wm8775_write(client, R14, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
187 wm8775_write(client, R15, 0x1d4); /* ADC gain +2.5dB, enable zero cross */
188 wm8775_write(client, R16, 0x1bf); /* ALC Stereo, ALC target level -1dB FS */
189 /* max gain +8dB */
190 wm8775_write(client, R17, 0x185); /* Enable gain control, use zero cross */
191 /* detection, ALC hold time 42.6 ms */
192 wm8775_write(client, R18, 0x0a2); /* ALC gain ramp up delay 34 s, */
193 /* ALC gain ramp down delay 33 ms */
194 wm8775_write(client, R19, 0x005); /* Enable noise gate, threshold -72dBfs */
195 wm8775_write(client, R20, 0x07a); /* Transient window 4ms, lower PGA gain */
196 /* limit -1dB */
197 wm8775_write(client, R21, 0x102); /* LRBOTH = 1, use input 2. */
198 i2c_attach_client(client);
199
200 return 0;
201}
202
203static int wm8775_probe(struct i2c_adapter *adapter)
204{
205#ifdef I2C_CLASS_TV_ANALOG
206 if (adapter->class & I2C_CLASS_TV_ANALOG)
207#else
208 if (adapter->id == I2C_HW_B_BT848)
209#endif
210 return i2c_probe(adapter, &addr_data, wm8775_attach);
211 return 0;
212}
213
214static int wm8775_detach(struct i2c_client *client)
215{
216 int err;
217
218 err = i2c_detach_client(client);
219 if (err) {
220 return err;
221 }
222 kfree(client);
223
224 return 0;
225}
226
227/* ----------------------------------------------------------------------- */
228
229/* i2c implementation */
230static struct i2c_driver i2c_driver = {
231 .name = "wm8775",
232
233 .id = I2C_DRIVERID_WM8775,
234 .flags = I2C_DF_NOTIFY,
235
236 .attach_adapter = wm8775_probe,
237 .detach_client = wm8775_detach,
238 .command = wm8775_command,
239 .owner = THIS_MODULE,
240};
241
242
243static int __init wm8775_init_module(void)
244{
245 return i2c_add_driver(&i2c_driver);
246}
247
248static void __exit wm8775_cleanup_module(void)
249{
250 i2c_del_driver(&i2c_driver);
251}
252
253module_init(wm8775_init_module);
254module_exit(wm8775_cleanup_module);
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index eed2acea1779..39a0d238900e 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -1057,10 +1057,8 @@ zr36057_init (struct zoran *zr)
1057 KERN_ERR 1057 KERN_ERR
1058 "%s: zr36057_init() - kmalloc (STAT_COM) failed\n", 1058 "%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
1059 ZR_DEVNAME(zr)); 1059 ZR_DEVNAME(zr));
1060 if (vdev) 1060 kfree(vdev);
1061 kfree(vdev); 1061 kfree((void *)mem);
1062 if (mem)
1063 kfree((void *)mem);
1064 return -ENOMEM; 1062 return -ENOMEM;
1065 } 1063 }
1066 memset((void *) mem, 0, mem_needed); 1064 memset((void *) mem, 0, mem_needed);
@@ -1105,15 +1103,15 @@ zoran_release (struct zoran *zr)
1105 /* unregister videocodec bus */ 1103 /* unregister videocodec bus */
1106 if (zr->codec) { 1104 if (zr->codec) {
1107 struct videocodec_master *master = zr->codec->master_data; 1105 struct videocodec_master *master = zr->codec->master_data;
1106
1108 videocodec_detach(zr->codec); 1107 videocodec_detach(zr->codec);
1109 if (master) 1108 kfree(master);
1110 kfree(master);
1111 } 1109 }
1112 if (zr->vfe) { 1110 if (zr->vfe) {
1113 struct videocodec_master *master = zr->vfe->master_data; 1111 struct videocodec_master *master = zr->vfe->master_data;
1112
1114 videocodec_detach(zr->vfe); 1113 videocodec_detach(zr->vfe);
1115 if (master) 1114 kfree(master);
1116 kfree(master);
1117 } 1115 }
1118 1116
1119 /* unregister i2c bus */ 1117 /* unregister i2c bus */
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 53adeb70f2ca..07bde9acd672 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -996,8 +996,6 @@ zoran_jpg_queue_frame (struct file *file,
996 return -EINVAL; 996 return -EINVAL;
997 } 997 }
998 998
999 spin_lock_irqsave(&zr->spinlock, flags);
1000
1001 if (fh->jpg_buffers.active == ZORAN_FREE) { 999 if (fh->jpg_buffers.active == ZORAN_FREE) {
1002 if (zr->jpg_buffers.active == ZORAN_FREE) { 1000 if (zr->jpg_buffers.active == ZORAN_FREE) {
1003 zr->jpg_buffers = fh->jpg_buffers; 1001 zr->jpg_buffers = fh->jpg_buffers;
@@ -1016,6 +1014,8 @@ zoran_jpg_queue_frame (struct file *file,
1016 zr36057_enable_jpg(zr, mode); 1014 zr36057_enable_jpg(zr, mode);
1017 } 1015 }
1018 1016
1017 spin_lock_irqsave(&zr->spinlock, flags);
1018
1019 if (!res) { 1019 if (!res) {
1020 switch (zr->jpg_buffers.buffer[num].state) { 1020 switch (zr->jpg_buffers.buffer[num].state) {
1021 case BUZ_STATE_DONE: 1021 case BUZ_STATE_DONE:
diff --git a/drivers/media/video/zr36016.c b/drivers/media/video/zr36016.c
index d4740a89cea1..4ed898585c70 100644
--- a/drivers/media/video/zr36016.c
+++ b/drivers/media/video/zr36016.c
@@ -26,7 +26,6 @@
26 26
27#define ZR016_VERSION "v0.7" 27#define ZR016_VERSION "v0.7"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/media/video/zr36050.c b/drivers/media/video/zr36050.c
index 13b1e7b6fd6e..0144576a6123 100644
--- a/drivers/media/video/zr36050.c
+++ b/drivers/media/video/zr36050.c
@@ -26,7 +26,6 @@
26 26
27#define ZR050_VERSION "v0.7.1" 27#define ZR050_VERSION "v0.7.1"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/media/video/zr36060.c b/drivers/media/video/zr36060.c
index b50dc403e6db..129744a07abd 100644
--- a/drivers/media/video/zr36060.c
+++ b/drivers/media/video/zr36060.c
@@ -26,7 +26,6 @@
26 26
27#define ZR060_VERSION "v0.7" 27#define ZR060_VERSION "v0.7"
28 28
29#include <linux/version.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/slab.h> 31#include <linux/slab.h>
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 790a2932ded9..74022316fc63 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -47,7 +47,6 @@
47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48 48
49#include <linux/config.h> 49#include <linux/config.h>
50#include <linux/version.h>
51#include <linux/kernel.h> 50#include <linux/kernel.h>
52#include <linux/module.h> 51#include <linux/module.h>
53#include <linux/errno.h> 52#include <linux/errno.h>
@@ -92,9 +91,9 @@ static int mfcounter = 0;
92 * Public data... 91 * Public data...
93 */ 92 */
94int mpt_lan_index = -1; 93int mpt_lan_index = -1;
95int mpt_stm_index = -1; 94static int mpt_stm_index = -1;
96 95
97struct proc_dir_entry *mpt_proc_root_dir; 96static struct proc_dir_entry *mpt_proc_root_dir;
98 97
99#define WHOINIT_UNKNOWN 0xAA 98#define WHOINIT_UNKNOWN 0xAA
100 99
@@ -6272,7 +6271,6 @@ EXPORT_SYMBOL(mpt_resume);
6272EXPORT_SYMBOL(mpt_suspend); 6271EXPORT_SYMBOL(mpt_suspend);
6273#endif 6272#endif
6274EXPORT_SYMBOL(ioc_list); 6273EXPORT_SYMBOL(ioc_list);
6275EXPORT_SYMBOL(mpt_proc_root_dir);
6276EXPORT_SYMBOL(mpt_register); 6274EXPORT_SYMBOL(mpt_register);
6277EXPORT_SYMBOL(mpt_deregister); 6275EXPORT_SYMBOL(mpt_deregister);
6278EXPORT_SYMBOL(mpt_event_register); 6276EXPORT_SYMBOL(mpt_event_register);
@@ -6290,7 +6288,6 @@ EXPORT_SYMBOL(mpt_verify_adapter);
6290EXPORT_SYMBOL(mpt_GetIocState); 6288EXPORT_SYMBOL(mpt_GetIocState);
6291EXPORT_SYMBOL(mpt_print_ioc_summary); 6289EXPORT_SYMBOL(mpt_print_ioc_summary);
6292EXPORT_SYMBOL(mpt_lan_index); 6290EXPORT_SYMBOL(mpt_lan_index);
6293EXPORT_SYMBOL(mpt_stm_index);
6294EXPORT_SYMBOL(mpt_HardResetHandler); 6291EXPORT_SYMBOL(mpt_HardResetHandler);
6295EXPORT_SYMBOL(mpt_config); 6292EXPORT_SYMBOL(mpt_config);
6296EXPORT_SYMBOL(mpt_toolbox); 6293EXPORT_SYMBOL(mpt_toolbox);
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index e7efeb7740b9..8ad277a9afa1 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -49,7 +49,6 @@
49#define MPTBASE_H_INCLUDED 49#define MPTBASE_H_INCLUDED
50/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 50/*{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
51 51
52#include <linux/version.h>
53#include <linux/config.h> 52#include <linux/config.h>
54#include <linux/kernel.h> 53#include <linux/kernel.h>
55#include <linux/pci.h> 54#include <linux/pci.h>
@@ -1007,10 +1006,8 @@ extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1007 * Public data decl's... 1006 * Public data decl's...
1008 */ 1007 */
1009extern struct list_head ioc_list; 1008extern struct list_head ioc_list;
1010extern struct proc_dir_entry *mpt_proc_root_dir;
1011 1009
1012extern int mpt_lan_index; /* needed by mptlan.c */ 1010extern int mpt_lan_index; /* needed by mptlan.c */
1013extern int mpt_stm_index; /* needed by mptstm.c */
1014 1011
1015/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1012/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1016#endif /* } __KERNEL__ */ 1013#endif /* } __KERNEL__ */
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index cb2d59d5f5af..602138f8544d 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -45,7 +45,6 @@
45*/ 45*/
46/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 46/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
47 47
48#include <linux/version.h>
49#include <linux/kernel.h> 48#include <linux/kernel.h>
50#include <linux/module.h> 49#include <linux/module.h>
51#include <linux/errno.h> 50#include <linux/errno.h>
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index 28754a9cb803..518996e03481 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -49,7 +49,6 @@
49#define MPTCTL_H_INCLUDED 49#define MPTCTL_H_INCLUDED
50/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 50/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
51 51
52#include "linux/version.h"
53 52
54 53
55/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 54/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index ed3c891e388f..014085d8ec85 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -511,7 +511,7 @@ mpt_lan_close(struct net_device *dev)
511{ 511{
512 struct mpt_lan_priv *priv = netdev_priv(dev); 512 struct mpt_lan_priv *priv = netdev_priv(dev);
513 MPT_ADAPTER *mpt_dev = priv->mpt_dev; 513 MPT_ADAPTER *mpt_dev = priv->mpt_dev;
514 unsigned int timeout; 514 unsigned long timeout;
515 int i; 515 int i;
516 516
517 dlprintk((KERN_INFO MYNAM ": mpt_lan_close called\n")); 517 dlprintk((KERN_INFO MYNAM ": mpt_lan_close called\n"));
@@ -526,11 +526,9 @@ mpt_lan_close(struct net_device *dev)
526 526
527 mpt_lan_reset(dev); 527 mpt_lan_reset(dev);
528 528
529 timeout = 2 * HZ; 529 timeout = jiffies + 2 * HZ;
530 while (atomic_read(&priv->buckets_out) && --timeout) { 530 while (atomic_read(&priv->buckets_out) && time_before(jiffies, timeout))
531 set_current_state(TASK_INTERRUPTIBLE); 531 schedule_timeout_interruptible(1);
532 schedule_timeout(1);
533 }
534 532
535 for (i = 0; i < priv->max_buckets_out; i++) { 533 for (i = 0; i < priv->max_buckets_out; i++) {
536 if (priv->RcvCtl[i].skb != NULL) { 534 if (priv->RcvCtl[i].skb != NULL) {
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
index 750e343eb981..3726ecba5707 100644
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -66,7 +66,6 @@
66#include <linux/slab.h> 66#include <linux/slab.h>
67#include <linux/miscdevice.h> 67#include <linux/miscdevice.h>
68#include <linux/spinlock.h> 68#include <linux/spinlock.h>
69#include <linux/version.h>
70#include <linux/workqueue.h> 69#include <linux/workqueue.h>
71#include <linux/delay.h> 70#include <linux/delay.h>
72// #include <linux/trdevice.h> 71// #include <linux/trdevice.h>
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 5cb07eb224d7..4330ed0cedaa 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1013,10 +1013,8 @@ mptscsih_remove(struct pci_dev *pdev)
1013 spin_lock_irqsave(&dvtaskQ_lock, flags); 1013 spin_lock_irqsave(&dvtaskQ_lock, flags);
1014 if (dvtaskQ_active) { 1014 if (dvtaskQ_active) {
1015 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 1015 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1016 while(dvtaskQ_active && --count) { 1016 while(dvtaskQ_active && --count)
1017 set_current_state(TASK_INTERRUPTIBLE); 1017 schedule_timeout_interruptible(1);
1018 schedule_timeout(1);
1019 }
1020 } else { 1018 } else {
1021 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 1019 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1022 } 1020 }
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index b675b4ebbebd..9c339a2505b0 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -33,6 +33,7 @@
33#include <linux/workqueue.h> 33#include <linux/workqueue.h>
34#include <linux/string.h> 34#include <linux/string.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/sched.h> /* wait_event_interruptible_timeout() needs this */
36#include <asm/param.h> /* HZ */ 37#include <asm/param.h> /* HZ */
37#include "core.h" 38#include "core.h"
38 39
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 61b837de4b6a..4eb53258842e 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -93,8 +93,7 @@ u32 i2o_msg_get_wait(struct i2o_controller *c,
93 c->name); 93 c->name);
94 return I2O_QUEUE_EMPTY; 94 return I2O_QUEUE_EMPTY;
95 } 95 }
96 set_current_state(TASK_UNINTERRUPTIBLE); 96 schedule_timeout_uninterruptible(1);
97 schedule_timeout(1);
98 } 97 }
99 98
100 return m; 99 return m;
@@ -485,8 +484,7 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
485 osm_warn("%s: Timeout Initializing\n", c->name); 484 osm_warn("%s: Timeout Initializing\n", c->name);
486 return -ETIMEDOUT; 485 return -ETIMEDOUT;
487 } 486 }
488 set_current_state(TASK_UNINTERRUPTIBLE); 487 schedule_timeout_uninterruptible(1);
489 schedule_timeout(1);
490 } 488 }
491 489
492 m = c->out_queue.phys; 490 m = c->out_queue.phys;
@@ -548,8 +546,7 @@ static int i2o_iop_reset(struct i2o_controller *c)
548 if (time_after(jiffies, timeout)) 546 if (time_after(jiffies, timeout))
549 break; 547 break;
550 548
551 set_current_state(TASK_UNINTERRUPTIBLE); 549 schedule_timeout_uninterruptible(1);
552 schedule_timeout(1);
553 } 550 }
554 551
555 switch (*status) { 552 switch (*status) {
@@ -577,8 +574,7 @@ static int i2o_iop_reset(struct i2o_controller *c)
577 rc = -ETIMEDOUT; 574 rc = -ETIMEDOUT;
578 goto exit; 575 goto exit;
579 } 576 }
580 set_current_state(TASK_UNINTERRUPTIBLE); 577 schedule_timeout_uninterruptible(1);
581 schedule_timeout(1);
582 578
583 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET); 579 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
584 } 580 }
@@ -989,8 +985,7 @@ int i2o_status_get(struct i2o_controller *c)
989 return -ETIMEDOUT; 985 return -ETIMEDOUT;
990 } 986 }
991 987
992 set_current_state(TASK_UNINTERRUPTIBLE); 988 schedule_timeout_uninterruptible(1);
993 schedule_timeout(1);
994 } 989 }
995 990
996#ifdef DEBUG 991#ifdef DEBUG
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index c75d713c01e4..55ba23075c90 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -15,6 +15,8 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/smp.h> 16#include <linux/smp.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/slab.h>
19#include <linux/string.h>
18 20
19#include <asm/dma.h> 21#include <asm/dma.h>
20#include <asm/system.h> 22#include <asm/system.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index 9c4dd682ac74..bc2b72b32905 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/spinlock.h> 19#include <linux/spinlock.h>
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
index 165f3405df27..4bb461793851 100644
--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
+++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/version.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
index ecce4ffd3e23..d7e20a34f88d 100644
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -31,7 +31,6 @@
31#include <linux/slab.h> 31#include <linux/slab.h>
32#include <linux/config.h> 32#include <linux/config.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/version.h>
35#include <linux/interrupt.h> 34#include <linux/interrupt.h>
36#include <linux/device.h> 35#include <linux/device.h>
37#include <linux/input.h> 36#include <linux/input.h>
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index ceae379a4d4c..da528390acf8 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1263,7 +1263,7 @@ EXPORT_SYMBOL(mmc_suspend_host);
1263 */ 1263 */
1264int mmc_resume_host(struct mmc_host *host) 1264int mmc_resume_host(struct mmc_host *host)
1265{ 1265{
1266 mmc_detect_change(host, 0); 1266 mmc_rescan(host);
1267 1267
1268 return 0; 1268 return 0;
1269} 1269}
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 4ff67e7363d9..e954b8354fef 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1602,8 +1602,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
1602 if (host->dma_addr) 1602 if (host->dma_addr)
1603 dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, 1603 dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
1604 DMA_BIDIRECTIONAL); 1604 DMA_BIDIRECTIONAL);
1605 if (host->dma_buffer) 1605 kfree(host->dma_buffer);
1606 kfree(host->dma_buffer);
1607 if (host->dma >= 0) 1606 if (host->dma >= 0)
1608 free_dma(host->dma); 1607 free_dma(host->dma);
1609 1608
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 027054dea032..f6b775e63ac8 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -1,4 +1,4 @@
1# $Id: Kconfig,v 1.7 2004/11/22 11:33:56 ijc Exp $ 1# $Id: Kconfig,v 1.11 2005/11/07 11:14:19 gleixner Exp $
2 2
3menu "Memory Technology Devices (MTD)" 3menu "Memory Technology Devices (MTD)"
4 4
@@ -10,7 +10,7 @@ config MTD
10 will provide the generic support for MTD drivers to register 10 will provide the generic support for MTD drivers to register
11 themselves with the kernel and for potential users of MTD devices 11 themselves with the kernel and for potential users of MTD devices
12 to enumerate the devices which are present and obtain a handle on 12 to enumerate the devices which are present and obtain a handle on
13 them. It will also allow you to select individual drivers for 13 them. It will also allow you to select individual drivers for
14 particular hardware and users of MTD devices. If unsure, say N. 14 particular hardware and users of MTD devices. If unsure, say N.
15 15
16config MTD_DEBUG 16config MTD_DEBUG
@@ -61,11 +61,11 @@ config MTD_REDBOOT_PARTS
61 61
62 If you need code which can detect and parse this table, and register 62 If you need code which can detect and parse this table, and register
63 MTD 'partitions' corresponding to each image in the table, enable 63 MTD 'partitions' corresponding to each image in the table, enable
64 this option. 64 this option.
65 65
66 You will still need the parsing functions to be called by the driver 66 You will still need the parsing functions to be called by the driver
67 for your particular device. It won't happen automatically. The 67 for your particular device. It won't happen automatically. The
68 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 68 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
69 example. 69 example.
70 70
71config MTD_REDBOOT_DIRECTORY_BLOCK 71config MTD_REDBOOT_DIRECTORY_BLOCK
@@ -81,10 +81,10 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
81 partition table. A zero or positive value gives an absolete 81 partition table. A zero or positive value gives an absolete
82 erase block number. A negative value specifies a number of 82 erase block number. A negative value specifies a number of
83 sectors before the end of the device. 83 sectors before the end of the device.
84 84
85 For example "2" means block number 2, "-1" means the last 85 For example "2" means block number 2, "-1" means the last
86 block and "-2" means the penultimate block. 86 block and "-2" means the penultimate block.
87 87
88config MTD_REDBOOT_PARTS_UNALLOCATED 88config MTD_REDBOOT_PARTS_UNALLOCATED
89 bool " Include unallocated flash regions" 89 bool " Include unallocated flash regions"
90 depends on MTD_REDBOOT_PARTS 90 depends on MTD_REDBOOT_PARTS
@@ -105,11 +105,11 @@ config MTD_CMDLINE_PARTS
105 ---help--- 105 ---help---
106 Allow generic configuration of the MTD paritition tables via the kernel 106 Allow generic configuration of the MTD paritition tables via the kernel
107 command line. Multiple flash resources are supported for hardware where 107 command line. Multiple flash resources are supported for hardware where
108 different kinds of flash memory are available. 108 different kinds of flash memory are available.
109 109
110 You will still need the parsing functions to be called by the driver 110 You will still need the parsing functions to be called by the driver
111 for your particular device. It won't happen automatically. The 111 for your particular device. It won't happen automatically. The
112 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for 112 SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for
113 example. 113 example.
114 114
115 The format for the command line is as follows: 115 The format for the command line is as follows:
@@ -118,12 +118,12 @@ config MTD_CMDLINE_PARTS
118 <mtddef> := <mtd-id>:<partdef>[,<partdef>] 118 <mtddef> := <mtd-id>:<partdef>[,<partdef>]
119 <partdef> := <size>[@offset][<name>][ro] 119 <partdef> := <size>[@offset][<name>][ro]
120 <mtd-id> := unique id used in mapping driver/device 120 <mtd-id> := unique id used in mapping driver/device
121 <size> := standard linux memsize OR "-" to denote all 121 <size> := standard linux memsize OR "-" to denote all
122 remaining space 122 remaining space
123 <name> := (NAME) 123 <name> := (NAME)
124 124
125 Due to the way Linux handles the command line, no spaces are 125 Due to the way Linux handles the command line, no spaces are
126 allowed in the partition definition, including mtd id's and partition 126 allowed in the partition definition, including mtd id's and partition
127 names. 127 names.
128 128
129 Examples: 129 Examples:
@@ -240,7 +240,7 @@ config INFTL
240 tristate "INFTL (Inverse NAND Flash Translation Layer) support" 240 tristate "INFTL (Inverse NAND Flash Translation Layer) support"
241 depends on MTD 241 depends on MTD
242 ---help--- 242 ---help---
243 This provides support for the Inverse NAND Flash Translation 243 This provides support for the Inverse NAND Flash Translation
244 Layer which is used on M-Systems' newer DiskOnChip devices. It 244 Layer which is used on M-Systems' newer DiskOnChip devices. It
245 uses a kind of pseudo-file system on a flash device to emulate 245 uses a kind of pseudo-file system on a flash device to emulate
246 a block device with 512-byte sectors, on top of which you put 246 a block device with 512-byte sectors, on top of which you put
@@ -253,6 +253,16 @@ config INFTL
253 permitted to copy, modify and distribute the code as you wish. Just 253 permitted to copy, modify and distribute the code as you wish. Just
254 not use it. 254 not use it.
255 255
256config RFD_FTL
257 tristate "Resident Flash Disk (Flash Translation Layer) support"
258 depends on MTD
259 ---help---
260 This provides support for the flash translation layer known
261 as the Resident Flash Disk (RFD), as used by the Embedded BIOS
262 of General Software. There is a blurb at:
263
264 http://www.gensw.com/pages/prod/bios/rfd.htm
265
256source "drivers/mtd/chips/Kconfig" 266source "drivers/mtd/chips/Kconfig"
257 267
258source "drivers/mtd/maps/Kconfig" 268source "drivers/mtd/maps/Kconfig"
@@ -261,5 +271,7 @@ source "drivers/mtd/devices/Kconfig"
261 271
262source "drivers/mtd/nand/Kconfig" 272source "drivers/mtd/nand/Kconfig"
263 273
274source "drivers/mtd/onenand/Kconfig"
275
264endmenu 276endmenu
265 277
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index e4ad588327f7..fc9374407c2b 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the memory technology device drivers. 2# Makefile for the memory technology device drivers.
3# 3#
4# $Id: Makefile.common,v 1.5 2004/08/10 20:51:49 dwmw2 Exp $ 4# $Id: Makefile.common,v 1.7 2005/07/11 10:39:27 gleixner Exp $
5 5
6# Core functionality. 6# Core functionality.
7mtd-y := mtdcore.o 7mtd-y := mtdcore.o
@@ -20,8 +20,9 @@ obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs.o
20obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o 20obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o
21obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o 21obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o
22obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o 22obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o
23obj-$(CONFIG_RFD_FTL) += rfd_ftl.o mtd_blkdevs.o
23 24
24nftl-objs := nftlcore.o nftlmount.o 25nftl-objs := nftlcore.o nftlmount.o
25inftl-objs := inftlcore.o inftlmount.o 26inftl-objs := inftlcore.o inftlmount.o
26 27
27obj-y += chips/ maps/ devices/ nand/ 28obj-y += chips/ maps/ devices/ nand/ onenand/
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c
index 7363e101eb0f..6a45be04564b 100644
--- a/drivers/mtd/afs.c
+++ b/drivers/mtd/afs.c
@@ -1,27 +1,27 @@
1/*====================================================================== 1/*======================================================================
2 2
3 drivers/mtd/afs.c: ARM Flash Layout/Partitioning 3 drivers/mtd/afs.c: ARM Flash Layout/Partitioning
4 4
5 Copyright (C) 2000 ARM Limited 5 Copyright (C) 2000 ARM Limited
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 10 (at your option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 20
21 This is access code for flashes using ARM's flash partitioning 21 This is access code for flashes using ARM's flash partitioning
22 standards. 22 standards.
23 23
24 $Id: afs.c,v 1.13 2004/02/27 22:09:59 rmk Exp $ 24 $Id: afs.c,v 1.15 2005/11/07 11:14:19 gleixner Exp $
25 25
26======================================================================*/ 26======================================================================*/
27 27
@@ -163,7 +163,7 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr)
163 return ret; 163 return ret;
164} 164}
165 165
166static int parse_afs_partitions(struct mtd_info *mtd, 166static int parse_afs_partitions(struct mtd_info *mtd,
167 struct mtd_partition **pparts, 167 struct mtd_partition **pparts,
168 unsigned long origin) 168 unsigned long origin)
169{ 169{
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index df95d2158b16..eafa23f5cbd6 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/chips/Kconfig 1# drivers/mtd/chips/Kconfig
2# $Id: Kconfig,v 1.15 2005/06/06 23:04:35 tpoynor Exp $ 2# $Id: Kconfig,v 1.18 2005/11/07 11:14:22 gleixner Exp $
3 3
4menu "RAM/ROM/Flash chip drivers" 4menu "RAM/ROM/Flash chip drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -39,7 +39,7 @@ config MTD_CFI_ADV_OPTIONS
39 If you need to specify a specific endianness for access to flash 39 If you need to specify a specific endianness for access to flash
40 chips, or if you wish to reduce the size of the kernel by including 40 chips, or if you wish to reduce the size of the kernel by including
41 support for only specific arrangements of flash chips, say 'Y'. This 41 support for only specific arrangements of flash chips, say 'Y'. This
42 option does not directly affect the code, but will enable other 42 option does not directly affect the code, but will enable other
43 configuration options which allow you to do so. 43 configuration options which allow you to do so.
44 44
45 If unsure, say 'N'. 45 If unsure, say 'N'.
@@ -56,7 +56,7 @@ config MTD_CFI_NOSWAP
56 data bits when writing the 'magic' commands to the chips. Saying 56 data bits when writing the 'magic' commands to the chips. Saying
57 'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't 57 'NO', which is the default when CONFIG_MTD_CFI_ADV_OPTIONS isn't
58 enabled, means that the CPU will not do any swapping; the chips 58 enabled, means that the CPU will not do any swapping; the chips
59 are expected to be wired to the CPU in 'host-endian' form. 59 are expected to be wired to the CPU in 'host-endian' form.
60 Specific arrangements are possible with the BIG_ENDIAN_BYTE and 60 Specific arrangements are possible with the BIG_ENDIAN_BYTE and
61 LITTLE_ENDIAN_BYTE, if the bytes are reversed. 61 LITTLE_ENDIAN_BYTE, if the bytes are reversed.
62 62
@@ -79,10 +79,10 @@ config MTD_CFI_GEOMETRY
79 bool "Specific CFI Flash geometry selection" 79 bool "Specific CFI Flash geometry selection"
80 depends on MTD_CFI_ADV_OPTIONS 80 depends on MTD_CFI_ADV_OPTIONS
81 help 81 help
82 This option does not affect the code directly, but will enable 82 This option does not affect the code directly, but will enable
83 some other configuration options which would allow you to reduce 83 some other configuration options which would allow you to reduce
84 the size of the kernel by including support for only certain 84 the size of the kernel by including support for only certain
85 arrangements of CFI chips. If unsure, say 'N' and all options 85 arrangements of CFI chips. If unsure, say 'N' and all options
86 which are supported by the current code will be enabled. 86 which are supported by the current code will be enabled.
87 87
88config MTD_MAP_BANK_WIDTH_1 88config MTD_MAP_BANK_WIDTH_1
@@ -197,7 +197,7 @@ config MTD_CFI_AMDSTD
197 help 197 help
198 The Common Flash Interface defines a number of different command 198 The Common Flash Interface defines a number of different command
199 sets which a CFI-compliant chip may claim to implement. This code 199 sets which a CFI-compliant chip may claim to implement. This code
200 provides support for one of those command sets, used on chips 200 provides support for one of those command sets, used on chips
201 including the AMD Am29LV320. 201 including the AMD Am29LV320.
202 202
203config MTD_CFI_AMDSTD_RETRY 203config MTD_CFI_AMDSTD_RETRY
@@ -237,14 +237,14 @@ config MTD_RAM
237 tristate "Support for RAM chips in bus mapping" 237 tristate "Support for RAM chips in bus mapping"
238 depends on MTD 238 depends on MTD
239 help 239 help
240 This option enables basic support for RAM chips accessed through 240 This option enables basic support for RAM chips accessed through
241 a bus mapping driver. 241 a bus mapping driver.
242 242
243config MTD_ROM 243config MTD_ROM
244 tristate "Support for ROM chips in bus mapping" 244 tristate "Support for ROM chips in bus mapping"
245 depends on MTD 245 depends on MTD
246 help 246 help
247 This option enables basic support for ROM chips accessed through 247 This option enables basic support for ROM chips accessed through
248 a bus mapping driver. 248 a bus mapping driver.
249 249
250config MTD_ABSENT 250config MTD_ABSENT
@@ -275,7 +275,7 @@ config MTD_AMDSTD
275 depends on MTD && MTD_OBSOLETE_CHIPS 275 depends on MTD && MTD_OBSOLETE_CHIPS
276 help 276 help
277 This option enables support for flash chips using AMD-compatible 277 This option enables support for flash chips using AMD-compatible
278 commands, including some which are not CFI-compatible and hence 278 commands, including some which are not CFI-compatible and hence
279 cannot be used with the CONFIG_MTD_CFI_AMDSTD option. 279 cannot be used with the CONFIG_MTD_CFI_AMDSTD option.
280 280
281 It also works on AMD compatible chips that do conform to CFI. 281 It also works on AMD compatible chips that do conform to CFI.
@@ -285,7 +285,7 @@ config MTD_SHARP
285 depends on MTD && MTD_OBSOLETE_CHIPS 285 depends on MTD && MTD_OBSOLETE_CHIPS
286 help 286 help
287 This option enables support for flash chips using Sharp-compatible 287 This option enables support for flash chips using Sharp-compatible
288 commands, including some which are not CFI-compatible and hence 288 commands, including some which are not CFI-compatible and hence
289 cannot be used with the CONFIG_MTD_CFI_INTELxxx options. 289 cannot be used with the CONFIG_MTD_CFI_INTELxxx options.
290 290
291config MTD_JEDEC 291config MTD_JEDEC
diff --git a/drivers/mtd/chips/Makefile b/drivers/mtd/chips/Makefile
index 6830489828c6..8afe3092c4e3 100644
--- a/drivers/mtd/chips/Makefile
+++ b/drivers/mtd/chips/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# linux/drivers/chips/Makefile 2# linux/drivers/chips/Makefile
3# 3#
4# $Id: Makefile.common,v 1.4 2004/07/12 16:07:30 dwmw2 Exp $ 4# $Id: Makefile.common,v 1.5 2005/11/07 11:14:22 gleixner Exp $
5 5
6# *** BIG UGLY NOTE *** 6# *** BIG UGLY NOTE ***
7# 7#
@@ -11,7 +11,7 @@
11# the CFI command set drivers are linked before gen_probe.o 11# the CFI command set drivers are linked before gen_probe.o
12 12
13obj-$(CONFIG_MTD) += chipreg.o 13obj-$(CONFIG_MTD) += chipreg.o
14obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o 14obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
15obj-$(CONFIG_MTD_CFI) += cfi_probe.o 15obj-$(CONFIG_MTD_CFI) += cfi_probe.o
16obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o 16obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
17obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o 17obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
diff --git a/drivers/mtd/chips/amd_flash.c b/drivers/mtd/chips/amd_flash.c
index 2dafeba3f3d5..fdb91b6f1d97 100644
--- a/drivers/mtd/chips/amd_flash.c
+++ b/drivers/mtd/chips/amd_flash.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Jonas Holmberg <jonas.holmberg@axis.com> 4 * Author: Jonas Holmberg <jonas.holmberg@axis.com>
5 * 5 *
6 * $Id: amd_flash.c,v 1.27 2005/02/04 07:43:09 jonashg Exp $ 6 * $Id: amd_flash.c,v 1.28 2005/11/07 11:14:22 gleixner Exp $
7 * 7 *
8 * Copyright (c) 2001 Axis Communications AB 8 * Copyright (c) 2001 Axis Communications AB
9 * 9 *
@@ -93,9 +93,9 @@
93#define D6_MASK 0x40 93#define D6_MASK 0x40
94 94
95struct amd_flash_private { 95struct amd_flash_private {
96 int device_type; 96 int device_type;
97 int interleave; 97 int interleave;
98 int numchips; 98 int numchips;
99 unsigned long chipshift; 99 unsigned long chipshift;
100// const char *im_name; 100// const char *im_name;
101 struct flchip chips[0]; 101 struct flchip chips[0];
@@ -253,7 +253,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
253 int i; 253 int i;
254 int retval = 0; 254 int retval = 0;
255 int lock_status; 255 int lock_status;
256 256
257 map = mtd->priv; 257 map = mtd->priv;
258 258
259 /* Pass the whole chip through sector by sector and check for each 259 /* Pass the whole chip through sector by sector and check for each
@@ -273,7 +273,7 @@ static int amd_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, size_t len,
273 unlock_sector(map, eraseoffset, is_unlock); 273 unlock_sector(map, eraseoffset, is_unlock);
274 274
275 lock_status = is_sector_locked(map, eraseoffset); 275 lock_status = is_sector_locked(map, eraseoffset);
276 276
277 if (is_unlock && lock_status) { 277 if (is_unlock && lock_status) {
278 printk("Cannot unlock sector at address %x length %xx\n", 278 printk("Cannot unlock sector at address %x length %xx\n",
279 eraseoffset, merip->erasesize); 279 eraseoffset, merip->erasesize);
@@ -305,7 +305,7 @@ static int amd_flash_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
305/* 305/*
306 * Reads JEDEC manufacturer ID and device ID and returns the index of the first 306 * Reads JEDEC manufacturer ID and device ID and returns the index of the first
307 * matching table entry (-1 if not found or alias for already found chip). 307 * matching table entry (-1 if not found or alias for already found chip).
308 */ 308 */
309static int probe_new_chip(struct mtd_info *mtd, __u32 base, 309static int probe_new_chip(struct mtd_info *mtd, __u32 base,
310 struct flchip *chips, 310 struct flchip *chips,
311 struct amd_flash_private *private, 311 struct amd_flash_private *private,
@@ -636,7 +636,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
636 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 }, 636 { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
637 { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 } 637 { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 }
638 } 638 }
639 } 639 }
640 }; 640 };
641 641
642 struct mtd_info *mtd; 642 struct mtd_info *mtd;
@@ -701,7 +701,7 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
701 701
702 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * 702 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
703 mtd->numeraseregions, GFP_KERNEL); 703 mtd->numeraseregions, GFP_KERNEL);
704 if (!mtd->eraseregions) { 704 if (!mtd->eraseregions) {
705 printk(KERN_WARNING "%s: Failed to allocate " 705 printk(KERN_WARNING "%s: Failed to allocate "
706 "memory for MTD erase region info\n", map->name); 706 "memory for MTD erase region info\n", map->name);
707 kfree(mtd); 707 kfree(mtd);
@@ -739,12 +739,12 @@ static struct mtd_info *amd_flash_probe(struct map_info *map)
739 mtd->type = MTD_NORFLASH; 739 mtd->type = MTD_NORFLASH;
740 mtd->flags = MTD_CAP_NORFLASH; 740 mtd->flags = MTD_CAP_NORFLASH;
741 mtd->name = map->name; 741 mtd->name = map->name;
742 mtd->erase = amd_flash_erase; 742 mtd->erase = amd_flash_erase;
743 mtd->read = amd_flash_read; 743 mtd->read = amd_flash_read;
744 mtd->write = amd_flash_write; 744 mtd->write = amd_flash_write;
745 mtd->sync = amd_flash_sync; 745 mtd->sync = amd_flash_sync;
746 mtd->suspend = amd_flash_suspend; 746 mtd->suspend = amd_flash_suspend;
747 mtd->resume = amd_flash_resume; 747 mtd->resume = amd_flash_resume;
748 mtd->lock = amd_flash_lock; 748 mtd->lock = amd_flash_lock;
749 mtd->unlock = amd_flash_unlock; 749 mtd->unlock = amd_flash_unlock;
750 750
@@ -789,7 +789,7 @@ retry:
789 map->name, chip->state); 789 map->name, chip->state);
790 set_current_state(TASK_UNINTERRUPTIBLE); 790 set_current_state(TASK_UNINTERRUPTIBLE);
791 add_wait_queue(&chip->wq, &wait); 791 add_wait_queue(&chip->wq, &wait);
792 792
793 spin_unlock_bh(chip->mutex); 793 spin_unlock_bh(chip->mutex);
794 794
795 schedule(); 795 schedule();
@@ -802,7 +802,7 @@ retry:
802 timeo = jiffies + HZ; 802 timeo = jiffies + HZ;
803 803
804 goto retry; 804 goto retry;
805 } 805 }
806 806
807 adr += chip->start; 807 adr += chip->start;
808 808
@@ -889,7 +889,7 @@ retry:
889 map->name, chip->state); 889 map->name, chip->state);
890 set_current_state(TASK_UNINTERRUPTIBLE); 890 set_current_state(TASK_UNINTERRUPTIBLE);
891 add_wait_queue(&chip->wq, &wait); 891 add_wait_queue(&chip->wq, &wait);
892 892
893 spin_unlock_bh(chip->mutex); 893 spin_unlock_bh(chip->mutex);
894 894
895 schedule(); 895 schedule();
@@ -901,7 +901,7 @@ retry:
901 timeo = jiffies + HZ; 901 timeo = jiffies + HZ;
902 902
903 goto retry; 903 goto retry;
904 } 904 }
905 905
906 chip->state = FL_WRITING; 906 chip->state = FL_WRITING;
907 907
@@ -911,7 +911,7 @@ retry:
911 wide_write(map, datum, adr); 911 wide_write(map, datum, adr);
912 912
913 times_left = 500000; 913 times_left = 500000;
914 while (times_left-- && flash_is_busy(map, adr, private->interleave)) { 914 while (times_left-- && flash_is_busy(map, adr, private->interleave)) {
915 if (need_resched()) { 915 if (need_resched()) {
916 spin_unlock_bh(chip->mutex); 916 spin_unlock_bh(chip->mutex);
917 schedule(); 917 schedule();
@@ -989,7 +989,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
989 if (ret) { 989 if (ret) {
990 return ret; 990 return ret;
991 } 991 }
992 992
993 ofs += n; 993 ofs += n;
994 buf += n; 994 buf += n;
995 (*retlen) += n; 995 (*retlen) += n;
@@ -1002,7 +1002,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
1002 } 1002 }
1003 } 1003 }
1004 } 1004 }
1005 1005
1006 /* We are now aligned, write as much as possible. */ 1006 /* We are now aligned, write as much as possible. */
1007 while(len >= map->buswidth) { 1007 while(len >= map->buswidth) {
1008 __u32 datum; 1008 __u32 datum;
@@ -1063,7 +1063,7 @@ static int amd_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
1063 if (ret) { 1063 if (ret) {
1064 return ret; 1064 return ret;
1065 } 1065 }
1066 1066
1067 (*retlen) += n; 1067 (*retlen) += n;
1068 } 1068 }
1069 1069
@@ -1085,7 +1085,7 @@ retry:
1085 if (chip->state != FL_READY){ 1085 if (chip->state != FL_READY){
1086 set_current_state(TASK_UNINTERRUPTIBLE); 1086 set_current_state(TASK_UNINTERRUPTIBLE);
1087 add_wait_queue(&chip->wq, &wait); 1087 add_wait_queue(&chip->wq, &wait);
1088 1088
1089 spin_unlock_bh(chip->mutex); 1089 spin_unlock_bh(chip->mutex);
1090 1090
1091 schedule(); 1091 schedule();
@@ -1098,7 +1098,7 @@ retry:
1098 timeo = jiffies + HZ; 1098 timeo = jiffies + HZ;
1099 1099
1100 goto retry; 1100 goto retry;
1101 } 1101 }
1102 1102
1103 chip->state = FL_ERASING; 1103 chip->state = FL_ERASING;
1104 1104
@@ -1106,30 +1106,30 @@ retry:
1106 ENABLE_VPP(map); 1106 ENABLE_VPP(map);
1107 send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA); 1107 send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA);
1108 send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr); 1108 send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, adr);
1109 1109
1110 timeo = jiffies + (HZ * 20); 1110 timeo = jiffies + (HZ * 20);
1111 1111
1112 spin_unlock_bh(chip->mutex); 1112 spin_unlock_bh(chip->mutex);
1113 msleep(1000); 1113 msleep(1000);
1114 spin_lock_bh(chip->mutex); 1114 spin_lock_bh(chip->mutex);
1115 1115
1116 while (flash_is_busy(map, adr, private->interleave)) { 1116 while (flash_is_busy(map, adr, private->interleave)) {
1117 1117
1118 if (chip->state != FL_ERASING) { 1118 if (chip->state != FL_ERASING) {
1119 /* Someone's suspended the erase. Sleep */ 1119 /* Someone's suspended the erase. Sleep */
1120 set_current_state(TASK_UNINTERRUPTIBLE); 1120 set_current_state(TASK_UNINTERRUPTIBLE);
1121 add_wait_queue(&chip->wq, &wait); 1121 add_wait_queue(&chip->wq, &wait);
1122 1122
1123 spin_unlock_bh(chip->mutex); 1123 spin_unlock_bh(chip->mutex);
1124 printk(KERN_INFO "%s: erase suspended. Sleeping\n", 1124 printk(KERN_INFO "%s: erase suspended. Sleeping\n",
1125 map->name); 1125 map->name);
1126 schedule(); 1126 schedule();
1127 remove_wait_queue(&chip->wq, &wait); 1127 remove_wait_queue(&chip->wq, &wait);
1128 1128
1129 if (signal_pending(current)) { 1129 if (signal_pending(current)) {
1130 return -EINTR; 1130 return -EINTR;
1131 } 1131 }
1132 1132
1133 timeo = jiffies + (HZ*2); /* FIXME */ 1133 timeo = jiffies + (HZ*2); /* FIXME */
1134 spin_lock_bh(chip->mutex); 1134 spin_lock_bh(chip->mutex);
1135 continue; 1135 continue;
@@ -1145,7 +1145,7 @@ retry:
1145 1145
1146 return -EIO; 1146 return -EIO;
1147 } 1147 }
1148 1148
1149 /* Latency issues. Drop the lock, wait a while and retry */ 1149 /* Latency issues. Drop the lock, wait a while and retry */
1150 spin_unlock_bh(chip->mutex); 1150 spin_unlock_bh(chip->mutex);
1151 1151
@@ -1153,7 +1153,7 @@ retry:
1153 schedule(); 1153 schedule();
1154 else 1154 else
1155 udelay(1); 1155 udelay(1);
1156 1156
1157 spin_lock_bh(chip->mutex); 1157 spin_lock_bh(chip->mutex);
1158 } 1158 }
1159 1159
@@ -1180,7 +1180,7 @@ retry:
1180 return -EIO; 1180 return -EIO;
1181 } 1181 }
1182 } 1182 }
1183 1183
1184 DISABLE_VPP(map); 1184 DISABLE_VPP(map);
1185 chip->state = FL_READY; 1185 chip->state = FL_READY;
1186 wake_up(&chip->wq); 1186 wake_up(&chip->wq);
@@ -1246,7 +1246,7 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
1246 * with the erase region at that address. 1246 * with the erase region at that address.
1247 */ 1247 */
1248 1248
1249 while ((i < mtd->numeraseregions) && 1249 while ((i < mtd->numeraseregions) &&
1250 ((instr->addr + instr->len) >= regions[i].offset)) { 1250 ((instr->addr + instr->len) >= regions[i].offset)) {
1251 i++; 1251 i++;
1252 } 1252 }
@@ -1293,10 +1293,10 @@ static int amd_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
1293 } 1293 }
1294 } 1294 }
1295 } 1295 }
1296 1296
1297 instr->state = MTD_ERASE_DONE; 1297 instr->state = MTD_ERASE_DONE;
1298 mtd_erase_callback(instr); 1298 mtd_erase_callback(instr);
1299 1299
1300 return 0; 1300 return 0;
1301} 1301}
1302 1302
@@ -1324,7 +1324,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
1324 case FL_JEDEC_QUERY: 1324 case FL_JEDEC_QUERY:
1325 chip->oldstate = chip->state; 1325 chip->oldstate = chip->state;
1326 chip->state = FL_SYNCING; 1326 chip->state = FL_SYNCING;
1327 /* No need to wake_up() on this state change - 1327 /* No need to wake_up() on this state change -
1328 * as the whole point is that nobody can do anything 1328 * as the whole point is that nobody can do anything
1329 * with the chip now anyway. 1329 * with the chip now anyway.
1330 */ 1330 */
@@ -1335,13 +1335,13 @@ static void amd_flash_sync(struct mtd_info *mtd)
1335 default: 1335 default:
1336 /* Not an idle state */ 1336 /* Not an idle state */
1337 add_wait_queue(&chip->wq, &wait); 1337 add_wait_queue(&chip->wq, &wait);
1338 1338
1339 spin_unlock_bh(chip->mutex); 1339 spin_unlock_bh(chip->mutex);
1340 1340
1341 schedule(); 1341 schedule();
1342 1342
1343 remove_wait_queue(&chip->wq, &wait); 1343 remove_wait_queue(&chip->wq, &wait);
1344 1344
1345 goto retry; 1345 goto retry;
1346 } 1346 }
1347 } 1347 }
@@ -1351,7 +1351,7 @@ static void amd_flash_sync(struct mtd_info *mtd)
1351 chip = &private->chips[i]; 1351 chip = &private->chips[i];
1352 1352
1353 spin_lock_bh(chip->mutex); 1353 spin_lock_bh(chip->mutex);
1354 1354
1355 if (chip->state == FL_SYNCING) { 1355 if (chip->state == FL_SYNCING) {
1356 chip->state = chip->oldstate; 1356 chip->state = chip->oldstate;
1357 wake_up(&chip->wq); 1357 wake_up(&chip->wq);
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 0cfcd88468e0..143f01a4c170 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -4,9 +4,9 @@
4 * 4 *
5 * (C) 2000 Red Hat. GPL'd 5 * (C) 2000 Red Hat. GPL'd
6 * 6 *
7 * $Id: cfi_cmdset_0001.c,v 1.178 2005/05/19 17:05:43 nico Exp $ 7 * $Id: cfi_cmdset_0001.c,v 1.185 2005/11/07 11:14:22 gleixner Exp $
8 *
8 * 9 *
9 *
10 * 10/10/2000 Nicolas Pitre <nico@cam.org> 10 * 10/10/2000 Nicolas Pitre <nico@cam.org>
11 * - completely revamped method functions so they are aware and 11 * - completely revamped method functions so they are aware and
12 * independent of the flash geometry (buswidth, interleave, etc.) 12 * independent of the flash geometry (buswidth, interleave, etc.)
@@ -51,6 +51,7 @@
51static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); 51static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
52static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 52static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
53static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); 53static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
54static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *);
54static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *); 55static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
55static void cfi_intelext_sync (struct mtd_info *); 56static void cfi_intelext_sync (struct mtd_info *);
56static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len); 57static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len);
@@ -105,6 +106,7 @@ static struct mtd_chip_driver cfi_intelext_chipdrv = {
105static void cfi_tell_features(struct cfi_pri_intelext *extp) 106static void cfi_tell_features(struct cfi_pri_intelext *extp)
106{ 107{
107 int i; 108 int i;
109 printk(" Extended Query version %c.%c\n", extp->MajorVersion, extp->MinorVersion);
108 printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport); 110 printk(" Feature/Command Support: %4.4X\n", extp->FeatureSupport);
109 printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported"); 111 printk(" - Chip Erase: %s\n", extp->FeatureSupport&1?"supported":"unsupported");
110 printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported"); 112 printk(" - Suspend Erase: %s\n", extp->FeatureSupport&2?"supported":"unsupported");
@@ -116,36 +118,43 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
116 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); 118 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported");
117 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); 119 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported");
118 printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported"); 120 printk(" - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported");
119 for (i=10; i<32; i++) { 121 printk(" - Extended Flash Array: %s\n", extp->FeatureSupport&1024?"supported":"unsupported");
120 if (extp->FeatureSupport & (1<<i)) 122 for (i=11; i<32; i++) {
123 if (extp->FeatureSupport & (1<<i))
121 printk(" - Unknown Bit %X: supported\n", i); 124 printk(" - Unknown Bit %X: supported\n", i);
122 } 125 }
123 126
124 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); 127 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
125 printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); 128 printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
126 for (i=1; i<8; i++) { 129 for (i=1; i<8; i++) {
127 if (extp->SuspendCmdSupport & (1<<i)) 130 if (extp->SuspendCmdSupport & (1<<i))
128 printk(" - Unknown Bit %X: supported\n", i); 131 printk(" - Unknown Bit %X: supported\n", i);
129 } 132 }
130 133
131 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); 134 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
132 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); 135 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
133 printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); 136 printk(" - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
134 for (i=2; i<16; i++) { 137 for (i=2; i<3; i++) {
135 if (extp->BlkStatusRegMask & (1<<i)) 138 if (extp->BlkStatusRegMask & (1<<i))
136 printk(" - Unknown Bit %X Active: yes\n",i); 139 printk(" - Unknown Bit %X Active: yes\n",i);
137 } 140 }
138 141 printk(" - EFA Lock Bit: %s\n", extp->BlkStatusRegMask&16?"yes":"no");
139 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 142 printk(" - EFA Lock-Down Bit: %s\n", extp->BlkStatusRegMask&32?"yes":"no");
143 for (i=6; i<16; i++) {
144 if (extp->BlkStatusRegMask & (1<<i))
145 printk(" - Unknown Bit %X Active: yes\n",i);
146 }
147
148 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
140 extp->VccOptimal >> 4, extp->VccOptimal & 0xf); 149 extp->VccOptimal >> 4, extp->VccOptimal & 0xf);
141 if (extp->VppOptimal) 150 if (extp->VppOptimal)
142 printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", 151 printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
143 extp->VppOptimal >> 4, extp->VppOptimal & 0xf); 152 extp->VppOptimal >> 4, extp->VppOptimal & 0xf);
144} 153}
145#endif 154#endif
146 155
147#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE 156#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
148/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ 157/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
149static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) 158static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
150{ 159{
151 struct map_info *map = mtd->priv; 160 struct map_info *map = mtd->priv;
@@ -176,7 +185,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param)
176{ 185{
177 struct map_info *map = mtd->priv; 186 struct map_info *map = mtd->priv;
178 struct cfi_private *cfi = map->fldrv_priv; 187 struct cfi_private *cfi = map->fldrv_priv;
179 188
180 cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */ 189 cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */
181 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ 190 cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */
182} 191}
@@ -185,7 +194,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param)
185{ 194{
186 struct map_info *map = mtd->priv; 195 struct map_info *map = mtd->priv;
187 struct cfi_private *cfi = map->fldrv_priv; 196 struct cfi_private *cfi = map->fldrv_priv;
188 197
189 /* Note this is done after the region info is endian swapped */ 198 /* Note this is done after the region info is endian swapped */
190 cfi->cfiq->EraseRegionInfo[1] = 199 cfi->cfiq->EraseRegionInfo[1] =
191 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; 200 (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
@@ -207,12 +216,13 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
207 if (cfi->cfiq->BufWriteTimeoutTyp) { 216 if (cfi->cfiq->BufWriteTimeoutTyp) {
208 printk(KERN_INFO "Using buffer write method\n" ); 217 printk(KERN_INFO "Using buffer write method\n" );
209 mtd->write = cfi_intelext_write_buffers; 218 mtd->write = cfi_intelext_write_buffers;
219 mtd->writev = cfi_intelext_writev;
210 } 220 }
211} 221}
212 222
213static struct cfi_fixup cfi_fixup_table[] = { 223static struct cfi_fixup cfi_fixup_table[] = {
214#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE 224#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
215 { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, 225 { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL },
216#endif 226#endif
217#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND 227#ifdef CMDSET0001_DISABLE_WRITE_SUSPEND
218 { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, 228 { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL },
@@ -252,12 +262,21 @@ read_pri_intelext(struct map_info *map, __u16 adr)
252 if (!extp) 262 if (!extp)
253 return NULL; 263 return NULL;
254 264
265 if (extp->MajorVersion != '1' ||
266 (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
267 printk(KERN_ERR " Unknown Intel/Sharp Extended Query "
268 "version %c.%c.\n", extp->MajorVersion,
269 extp->MinorVersion);
270 kfree(extp);
271 return NULL;
272 }
273
255 /* Do some byteswapping if necessary */ 274 /* Do some byteswapping if necessary */
256 extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport); 275 extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport);
257 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask); 276 extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask);
258 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr); 277 extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr);
259 278
260 if (extp->MajorVersion == '1' && extp->MinorVersion == '3') { 279 if (extp->MajorVersion == '1' && extp->MinorVersion >= '3') {
261 unsigned int extra_size = 0; 280 unsigned int extra_size = 0;
262 int nb_parts, i; 281 int nb_parts, i;
263 282
@@ -266,7 +285,10 @@ read_pri_intelext(struct map_info *map, __u16 adr)
266 sizeof(struct cfi_intelext_otpinfo); 285 sizeof(struct cfi_intelext_otpinfo);
267 286
268 /* Burst Read info */ 287 /* Burst Read info */
269 extra_size += 6; 288 extra_size += 2;
289 if (extp_size < sizeof(*extp) + extra_size)
290 goto need_more;
291 extra_size += extp->extra[extra_size-1];
270 292
271 /* Number of hardware-partitions */ 293 /* Number of hardware-partitions */
272 extra_size += 1; 294 extra_size += 1;
@@ -274,6 +296,10 @@ read_pri_intelext(struct map_info *map, __u16 adr)
274 goto need_more; 296 goto need_more;
275 nb_parts = extp->extra[extra_size - 1]; 297 nb_parts = extp->extra[extra_size - 1];
276 298
299 /* skip the sizeof(partregion) field in CFI 1.4 */
300 if (extp->MinorVersion >= '4')
301 extra_size += 2;
302
277 for (i = 0; i < nb_parts; i++) { 303 for (i = 0; i < nb_parts; i++) {
278 struct cfi_intelext_regioninfo *rinfo; 304 struct cfi_intelext_regioninfo *rinfo;
279 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size]; 305 rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size];
@@ -285,6 +311,9 @@ read_pri_intelext(struct map_info *map, __u16 adr)
285 * sizeof(struct cfi_intelext_blockinfo); 311 * sizeof(struct cfi_intelext_blockinfo);
286 } 312 }
287 313
314 if (extp->MinorVersion >= '4')
315 extra_size += sizeof(struct cfi_intelext_programming_regioninfo);
316
288 if (extp_size < sizeof(*extp) + extra_size) { 317 if (extp_size < sizeof(*extp) + extra_size) {
289 need_more: 318 need_more:
290 extp_size = sizeof(*extp) + extra_size; 319 extp_size = sizeof(*extp) + extra_size;
@@ -298,7 +327,7 @@ read_pri_intelext(struct map_info *map, __u16 adr)
298 goto again; 327 goto again;
299 } 328 }
300 } 329 }
301 330
302 return extp; 331 return extp;
303} 332}
304 333
@@ -339,7 +368,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
339 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; 368 mtd->reboot_notifier.notifier_call = cfi_intelext_reboot;
340 369
341 if (cfi->cfi_mode == CFI_MODE_CFI) { 370 if (cfi->cfi_mode == CFI_MODE_CFI) {
342 /* 371 /*
343 * It's a real CFI chip, not one for which the probe 372 * It's a real CFI chip, not one for which the probe
344 * routine faked a CFI structure. So we read the feature 373 * routine faked a CFI structure. So we read the feature
345 * table from it. 374 * table from it.
@@ -354,14 +383,14 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
354 } 383 }
355 384
356 /* Install our own private info structure */ 385 /* Install our own private info structure */
357 cfi->cmdset_priv = extp; 386 cfi->cmdset_priv = extp;
358 387
359 cfi_fixup(mtd, cfi_fixup_table); 388 cfi_fixup(mtd, cfi_fixup_table);
360 389
361#ifdef DEBUG_CFI_FEATURES 390#ifdef DEBUG_CFI_FEATURES
362 /* Tell the user about it in lots of lovely detail */ 391 /* Tell the user about it in lots of lovely detail */
363 cfi_tell_features(extp); 392 cfi_tell_features(extp);
364#endif 393#endif
365 394
366 if(extp->SuspendCmdSupport & 1) { 395 if(extp->SuspendCmdSupport & 1) {
367 printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n"); 396 printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n");
@@ -379,10 +408,10 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
379 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; 408 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
380 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; 409 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
381 cfi->chips[i].ref_point_counter = 0; 410 cfi->chips[i].ref_point_counter = 0;
382 } 411 }
383 412
384 map->fldrv = &cfi_intelext_chipdrv; 413 map->fldrv = &cfi_intelext_chipdrv;
385 414
386 return cfi_intelext_setup(mtd); 415 return cfi_intelext_setup(mtd);
387} 416}
388 417
@@ -399,13 +428,13 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
399 mtd->size = devsize * cfi->numchips; 428 mtd->size = devsize * cfi->numchips;
400 429
401 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; 430 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
402 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 431 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
403 * mtd->numeraseregions, GFP_KERNEL); 432 * mtd->numeraseregions, GFP_KERNEL);
404 if (!mtd->eraseregions) { 433 if (!mtd->eraseregions) {
405 printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); 434 printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
406 goto setup_err; 435 goto setup_err;
407 } 436 }
408 437
409 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 438 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
410 unsigned long ernum, ersize; 439 unsigned long ernum, ersize;
411 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; 440 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@@ -429,7 +458,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
429 } 458 }
430 459
431 for (i=0; i<mtd->numeraseregions;i++){ 460 for (i=0; i<mtd->numeraseregions;i++){
432 printk(KERN_DEBUG "%d: offset=0x%x,size=0x%x,blocks=%d\n", 461 printk(KERN_DEBUG "erase region %d: offset=0x%x,size=0x%x,blocks=%d\n",
433 i,mtd->eraseregions[i].offset, 462 i,mtd->eraseregions[i].offset,
434 mtd->eraseregions[i].erasesize, 463 mtd->eraseregions[i].erasesize,
435 mtd->eraseregions[i].numblocks); 464 mtd->eraseregions[i].numblocks);
@@ -455,8 +484,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
455 484
456 setup_err: 485 setup_err:
457 if(mtd) { 486 if(mtd) {
458 if(mtd->eraseregions) 487 kfree(mtd->eraseregions);
459 kfree(mtd->eraseregions);
460 kfree(mtd); 488 kfree(mtd);
461 } 489 }
462 kfree(cfi->cmdset_priv); 490 kfree(cfi->cmdset_priv);
@@ -481,7 +509,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
481 * arrangement at this point. This can be rearranged in the future 509 * arrangement at this point. This can be rearranged in the future
482 * if someone feels motivated enough. --nico 510 * if someone feels motivated enough. --nico
483 */ 511 */
484 if (extp && extp->MajorVersion == '1' && extp->MinorVersion == '3' 512 if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3'
485 && extp->FeatureSupport & (1 << 9)) { 513 && extp->FeatureSupport & (1 << 9)) {
486 struct cfi_private *newcfi; 514 struct cfi_private *newcfi;
487 struct flchip *chip; 515 struct flchip *chip;
@@ -493,12 +521,16 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
493 sizeof(struct cfi_intelext_otpinfo); 521 sizeof(struct cfi_intelext_otpinfo);
494 522
495 /* Burst Read info */ 523 /* Burst Read info */
496 offs += 6; 524 offs += extp->extra[offs+1]+2;
497 525
498 /* Number of partition regions */ 526 /* Number of partition regions */
499 numregions = extp->extra[offs]; 527 numregions = extp->extra[offs];
500 offs += 1; 528 offs += 1;
501 529
530 /* skip the sizeof(partregion) field in CFI 1.4 */
531 if (extp->MinorVersion >= '4')
532 offs += 2;
533
502 /* Number of hardware partitions */ 534 /* Number of hardware partitions */
503 numparts = 0; 535 numparts = 0;
504 for (i = 0; i < numregions; i++) { 536 for (i = 0; i < numregions; i++) {
@@ -510,6 +542,20 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
510 sizeof(struct cfi_intelext_blockinfo); 542 sizeof(struct cfi_intelext_blockinfo);
511 } 543 }
512 544
545 /* Programming Region info */
546 if (extp->MinorVersion >= '4') {
547 struct cfi_intelext_programming_regioninfo *prinfo;
548 prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];
549 MTD_PROGREGION_SIZE(mtd) = cfi->interleave << prinfo->ProgRegShift;
550 MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;
551 MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;
552 mtd->flags |= MTD_PROGRAM_REGIONS;
553 printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",
554 map->name, MTD_PROGREGION_SIZE(mtd),
555 MTD_PROGREGION_CTRLMODE_VALID(mtd),
556 MTD_PROGREGION_CTRLMODE_INVALID(mtd));
557 }
558
513 /* 559 /*
514 * All functions below currently rely on all chips having 560 * All functions below currently rely on all chips having
515 * the same geometry so we'll just assume that all hardware 561 * the same geometry so we'll just assume that all hardware
@@ -654,8 +700,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
654 break; 700 break;
655 701
656 if (time_after(jiffies, timeo)) { 702 if (time_after(jiffies, timeo)) {
657 printk(KERN_ERR "Waiting for chip to be ready timed out. Status %lx\n", 703 printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n",
658 status.x[0]); 704 map->name, status.x[0]);
659 return -EIO; 705 return -EIO;
660 } 706 }
661 spin_unlock(chip->mutex); 707 spin_unlock(chip->mutex);
@@ -664,7 +710,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
664 /* Someone else might have been playing with it. */ 710 /* Someone else might have been playing with it. */
665 goto retry; 711 goto retry;
666 } 712 }
667 713
668 case FL_READY: 714 case FL_READY:
669 case FL_CFI_QUERY: 715 case FL_CFI_QUERY:
670 case FL_JEDEC_QUERY: 716 case FL_JEDEC_QUERY:
@@ -702,8 +748,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
702 map_write(map, CMD(0x70), adr); 748 map_write(map, CMD(0x70), adr);
703 chip->state = FL_ERASING; 749 chip->state = FL_ERASING;
704 chip->oldstate = FL_READY; 750 chip->oldstate = FL_READY;
705 printk(KERN_ERR "Chip not ready after erase " 751 printk(KERN_ERR "%s: Chip not ready after erase "
706 "suspended: status = 0x%lx\n", status.x[0]); 752 "suspended: status = 0x%lx\n", map->name, status.x[0]);
707 return -EIO; 753 return -EIO;
708 } 754 }
709 755
@@ -783,14 +829,14 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
783 switch(chip->oldstate) { 829 switch(chip->oldstate) {
784 case FL_ERASING: 830 case FL_ERASING:
785 chip->state = chip->oldstate; 831 chip->state = chip->oldstate;
786 /* What if one interleaved chip has finished and the 832 /* What if one interleaved chip has finished and the
787 other hasn't? The old code would leave the finished 833 other hasn't? The old code would leave the finished
788 one in READY mode. That's bad, and caused -EROFS 834 one in READY mode. That's bad, and caused -EROFS
789 errors to be returned from do_erase_oneblock because 835 errors to be returned from do_erase_oneblock because
790 that's the only bit it checked for at the time. 836 that's the only bit it checked for at the time.
791 As the state machine appears to explicitly allow 837 As the state machine appears to explicitly allow
792 sending the 0x70 (Read Status) command to an erasing 838 sending the 0x70 (Read Status) command to an erasing
793 chip and expecting it to be ignored, that's what we 839 chip and expecting it to be ignored, that's what we
794 do. */ 840 do. */
795 map_write(map, CMD(0xd0), adr); 841 map_write(map, CMD(0xd0), adr);
796 map_write(map, CMD(0x70), adr); 842 map_write(map, CMD(0x70), adr);
@@ -810,7 +856,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
810 DISABLE_VPP(map); 856 DISABLE_VPP(map);
811 break; 857 break;
812 default: 858 default:
813 printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate); 859 printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate);
814 } 860 }
815 wake_up(&chip->wq); 861 wake_up(&chip->wq);
816} 862}
@@ -1026,8 +1072,8 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
1026 1072
1027 adr += chip->start; 1073 adr += chip->start;
1028 1074
1029 /* Ensure cmd read/writes are aligned. */ 1075 /* Ensure cmd read/writes are aligned. */
1030 cmd_addr = adr & ~(map_bankwidth(map)-1); 1076 cmd_addr = adr & ~(map_bankwidth(map)-1);
1031 1077
1032 spin_lock(chip->mutex); 1078 spin_lock(chip->mutex);
1033 1079
@@ -1055,7 +1101,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
1055 1101
1056 if (!map->virt || (from + len > mtd->size)) 1102 if (!map->virt || (from + len > mtd->size))
1057 return -EINVAL; 1103 return -EINVAL;
1058 1104
1059 *mtdbuf = (void *)map->virt + from; 1105 *mtdbuf = (void *)map->virt + from;
1060 *retlen = 0; 1106 *retlen = 0;
1061 1107
@@ -1082,7 +1128,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, si
1082 1128
1083 *retlen += thislen; 1129 *retlen += thislen;
1084 len -= thislen; 1130 len -= thislen;
1085 1131
1086 ofs = 0; 1132 ofs = 0;
1087 chipnum++; 1133 chipnum++;
1088 } 1134 }
@@ -1121,7 +1167,7 @@ static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t fro
1121 if(chip->ref_point_counter == 0) 1167 if(chip->ref_point_counter == 0)
1122 chip->state = FL_READY; 1168 chip->state = FL_READY;
1123 } else 1169 } else
1124 printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */ 1170 printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */
1125 1171
1126 put_chip(map, chip, chip->start); 1172 put_chip(map, chip, chip->start);
1127 spin_unlock(chip->mutex); 1173 spin_unlock(chip->mutex);
@@ -1140,8 +1186,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
1140 1186
1141 adr += chip->start; 1187 adr += chip->start;
1142 1188
1143 /* Ensure cmd read/writes are aligned. */ 1189 /* Ensure cmd read/writes are aligned. */
1144 cmd_addr = adr & ~(map_bankwidth(map)-1); 1190 cmd_addr = adr & ~(map_bankwidth(map)-1);
1145 1191
1146 spin_lock(chip->mutex); 1192 spin_lock(chip->mutex);
1147 ret = get_chip(map, chip, cmd_addr, FL_READY); 1193 ret = get_chip(map, chip, cmd_addr, FL_READY);
@@ -1196,7 +1242,7 @@ static int cfi_intelext_read (struct mtd_info *mtd, loff_t from, size_t len, siz
1196 *retlen += thislen; 1242 *retlen += thislen;
1197 len -= thislen; 1243 len -= thislen;
1198 buf += thislen; 1244 buf += thislen;
1199 1245
1200 ofs = 0; 1246 ofs = 0;
1201 chipnum++; 1247 chipnum++;
1202 } 1248 }
@@ -1213,12 +1259,17 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1213 1259
1214 adr += chip->start; 1260 adr += chip->start;
1215 1261
1216 /* Let's determine this according to the interleave only once */ 1262 /* Let's determine those according to the interleave only once */
1217 status_OK = CMD(0x80); 1263 status_OK = CMD(0x80);
1218 switch (mode) { 1264 switch (mode) {
1219 case FL_WRITING: write_cmd = CMD(0x40); break; 1265 case FL_WRITING:
1220 case FL_OTP_WRITE: write_cmd = CMD(0xc0); break; 1266 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41);
1221 default: return -EINVAL; 1267 break;
1268 case FL_OTP_WRITE:
1269 write_cmd = CMD(0xc0);
1270 break;
1271 default:
1272 return -EINVAL;
1222 } 1273 }
1223 1274
1224 spin_lock(chip->mutex); 1275 spin_lock(chip->mutex);
@@ -1259,12 +1310,13 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1259 status = map_read(map, adr); 1310 status = map_read(map, adr);
1260 if (map_word_andequal(map, status, status_OK, status_OK)) 1311 if (map_word_andequal(map, status, status_OK, status_OK))
1261 break; 1312 break;
1262 1313
1263 /* OK Still waiting */ 1314 /* OK Still waiting */
1264 if (time_after(jiffies, timeo)) { 1315 if (time_after(jiffies, timeo)) {
1316 map_write(map, CMD(0x70), adr);
1265 chip->state = FL_STATUS; 1317 chip->state = FL_STATUS;
1266 xip_enable(map, chip, adr); 1318 xip_enable(map, chip, adr);
1267 printk(KERN_ERR "waiting for chip to be ready timed out in word write\n"); 1319 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
1268 ret = -EIO; 1320 ret = -EIO;
1269 goto out; 1321 goto out;
1270 } 1322 }
@@ -1276,27 +1328,39 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1276 if (!z) { 1328 if (!z) {
1277 chip->word_write_time--; 1329 chip->word_write_time--;
1278 if (!chip->word_write_time) 1330 if (!chip->word_write_time)
1279 chip->word_write_time++; 1331 chip->word_write_time = 1;
1280 } 1332 }
1281 if (z > 1) 1333 if (z > 1)
1282 chip->word_write_time++; 1334 chip->word_write_time++;
1283 1335
1284 /* Done and happy. */ 1336 /* Done and happy. */
1285 chip->state = FL_STATUS; 1337 chip->state = FL_STATUS;
1286 1338
1287 /* check for lock bit */ 1339 /* check for errors */
1288 if (map_word_bitsset(map, status, CMD(0x02))) { 1340 if (map_word_bitsset(map, status, CMD(0x1a))) {
1289 /* clear status */ 1341 unsigned long chipstatus = MERGESTATUS(status);
1342
1343 /* reset status */
1290 map_write(map, CMD(0x50), adr); 1344 map_write(map, CMD(0x50), adr);
1291 /* put back into read status register mode */
1292 map_write(map, CMD(0x70), adr); 1345 map_write(map, CMD(0x70), adr);
1293 ret = -EROFS; 1346 xip_enable(map, chip, adr);
1347
1348 if (chipstatus & 0x02) {
1349 ret = -EROFS;
1350 } else if (chipstatus & 0x08) {
1351 printk(KERN_ERR "%s: word write error (bad VPP)\n", map->name);
1352 ret = -EIO;
1353 } else {
1354 printk(KERN_ERR "%s: word write error (status 0x%lx)\n", map->name, chipstatus);
1355 ret = -EINVAL;
1356 }
1357
1358 goto out;
1294 } 1359 }
1295 1360
1296 xip_enable(map, chip, adr); 1361 xip_enable(map, chip, adr);
1297 out: put_chip(map, chip, adr); 1362 out: put_chip(map, chip, adr);
1298 spin_unlock(chip->mutex); 1363 spin_unlock(chip->mutex);
1299
1300 return ret; 1364 return ret;
1301} 1365}
1302 1366
@@ -1329,7 +1393,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1329 1393
1330 ret = do_write_oneword(map, &cfi->chips[chipnum], 1394 ret = do_write_oneword(map, &cfi->chips[chipnum],
1331 bus_ofs, datum, FL_WRITING); 1395 bus_ofs, datum, FL_WRITING);
1332 if (ret) 1396 if (ret)
1333 return ret; 1397 return ret;
1334 1398
1335 len -= n; 1399 len -= n;
@@ -1338,13 +1402,13 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1338 (*retlen) += n; 1402 (*retlen) += n;
1339 1403
1340 if (ofs >> cfi->chipshift) { 1404 if (ofs >> cfi->chipshift) {
1341 chipnum ++; 1405 chipnum ++;
1342 ofs = 0; 1406 ofs = 0;
1343 if (chipnum == cfi->numchips) 1407 if (chipnum == cfi->numchips)
1344 return 0; 1408 return 0;
1345 } 1409 }
1346 } 1410 }
1347 1411
1348 while(len >= map_bankwidth(map)) { 1412 while(len >= map_bankwidth(map)) {
1349 map_word datum = map_word_load(map, buf); 1413 map_word datum = map_word_load(map, buf);
1350 1414
@@ -1359,7 +1423,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1359 len -= map_bankwidth(map); 1423 len -= map_bankwidth(map);
1360 1424
1361 if (ofs >> cfi->chipshift) { 1425 if (ofs >> cfi->chipshift) {
1362 chipnum ++; 1426 chipnum ++;
1363 ofs = 0; 1427 ofs = 0;
1364 if (chipnum == cfi->numchips) 1428 if (chipnum == cfi->numchips)
1365 return 0; 1429 return 0;
@@ -1374,9 +1438,9 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1374 1438
1375 ret = do_write_oneword(map, &cfi->chips[chipnum], 1439 ret = do_write_oneword(map, &cfi->chips[chipnum],
1376 ofs, datum, FL_WRITING); 1440 ofs, datum, FL_WRITING);
1377 if (ret) 1441 if (ret)
1378 return ret; 1442 return ret;
1379 1443
1380 (*retlen) += len; 1444 (*retlen) += len;
1381 } 1445 }
1382 1446
@@ -1384,20 +1448,24 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
1384} 1448}
1385 1449
1386 1450
1387static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, 1451static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1388 unsigned long adr, const u_char *buf, int len) 1452 unsigned long adr, const struct kvec **pvec,
1453 unsigned long *pvec_seek, int len)
1389{ 1454{
1390 struct cfi_private *cfi = map->fldrv_priv; 1455 struct cfi_private *cfi = map->fldrv_priv;
1391 map_word status, status_OK; 1456 map_word status, status_OK, write_cmd, datum;
1392 unsigned long cmd_adr, timeo; 1457 unsigned long cmd_adr, timeo;
1393 int wbufsize, z, ret=0, bytes, words; 1458 int wbufsize, z, ret=0, word_gap, words;
1459 const struct kvec *vec;
1460 unsigned long vec_seek;
1394 1461
1395 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; 1462 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
1396 adr += chip->start; 1463 adr += chip->start;
1397 cmd_adr = adr & ~(wbufsize-1); 1464 cmd_adr = adr & ~(wbufsize-1);
1398 1465
1399 /* Let's determine this according to the interleave only once */ 1466 /* Let's determine this according to the interleave only once */
1400 status_OK = CMD(0x80); 1467 status_OK = CMD(0x80);
1468 write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
1401 1469
1402 spin_lock(chip->mutex); 1470 spin_lock(chip->mutex);
1403 ret = get_chip(map, chip, cmd_adr, FL_WRITING); 1471 ret = get_chip(map, chip, cmd_adr, FL_WRITING);
@@ -1411,7 +1479,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1411 xip_disable(map, chip, cmd_adr); 1479 xip_disable(map, chip, cmd_adr);
1412 1480
1413 /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set 1481 /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
1414 [...], the device will not accept any more Write to Buffer commands". 1482 [...], the device will not accept any more Write to Buffer commands".
1415 So we must check here and reset those bits if they're set. Otherwise 1483 So we must check here and reset those bits if they're set. Otherwise
1416 we're just pissing in the wind */ 1484 we're just pissing in the wind */
1417 if (chip->state != FL_STATUS) 1485 if (chip->state != FL_STATUS)
@@ -1429,7 +1497,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1429 1497
1430 z = 0; 1498 z = 0;
1431 for (;;) { 1499 for (;;) {
1432 map_write(map, CMD(0xe8), cmd_adr); 1500 map_write(map, write_cmd, cmd_adr);
1433 1501
1434 status = map_read(map, cmd_adr); 1502 status = map_read(map, cmd_adr);
1435 if (map_word_andequal(map, status, status_OK, status_OK)) 1503 if (map_word_andequal(map, status, status_OK, status_OK))
@@ -1447,41 +1515,66 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1447 map_write(map, CMD(0x50), cmd_adr); 1515 map_write(map, CMD(0x50), cmd_adr);
1448 map_write(map, CMD(0x70), cmd_adr); 1516 map_write(map, CMD(0x70), cmd_adr);
1449 xip_enable(map, chip, cmd_adr); 1517 xip_enable(map, chip, cmd_adr);
1450 printk(KERN_ERR "Chip not ready for buffer write. status = %lx, Xstatus = %lx\n", 1518 printk(KERN_ERR "%s: Chip not ready for buffer write. status = %lx, Xstatus = %lx\n",
1451 status.x[0], Xstatus.x[0]); 1519 map->name, status.x[0], Xstatus.x[0]);
1452 ret = -EIO; 1520 ret = -EIO;
1453 goto out; 1521 goto out;
1454 } 1522 }
1455 } 1523 }
1456 1524
1525 /* Figure out the number of words to write */
1526 word_gap = (-adr & (map_bankwidth(map)-1));
1527 words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map);
1528 if (!word_gap) {
1529 words--;
1530 } else {
1531 word_gap = map_bankwidth(map) - word_gap;
1532 adr -= word_gap;
1533 datum = map_word_ff(map);
1534 }
1535
1457 /* Write length of data to come */ 1536 /* Write length of data to come */
1458 bytes = len & (map_bankwidth(map)-1); 1537 map_write(map, CMD(words), cmd_adr );
1459 words = len / map_bankwidth(map);
1460 map_write(map, CMD(words - !bytes), cmd_adr );
1461 1538
1462 /* Write data */ 1539 /* Write data */
1463 z = 0; 1540 vec = *pvec;
1464 while(z < words * map_bankwidth(map)) { 1541 vec_seek = *pvec_seek;
1465 map_word datum = map_word_load(map, buf); 1542 do {
1466 map_write(map, datum, adr+z); 1543 int n = map_bankwidth(map) - word_gap;
1544 if (n > vec->iov_len - vec_seek)
1545 n = vec->iov_len - vec_seek;
1546 if (n > len)
1547 n = len;
1467 1548
1468 z += map_bankwidth(map); 1549 if (!word_gap && len < map_bankwidth(map))
1469 buf += map_bankwidth(map); 1550 datum = map_word_ff(map);
1470 }
1471 1551
1472 if (bytes) { 1552 datum = map_word_load_partial(map, datum,
1473 map_word datum; 1553 vec->iov_base + vec_seek,
1554 word_gap, n);
1474 1555
1475 datum = map_word_ff(map); 1556 len -= n;
1476 datum = map_word_load_partial(map, datum, buf, 0, bytes); 1557 word_gap += n;
1477 map_write(map, datum, adr+z); 1558 if (!len || word_gap == map_bankwidth(map)) {
1478 } 1559 map_write(map, datum, adr);
1560 adr += map_bankwidth(map);
1561 word_gap = 0;
1562 }
1563
1564 vec_seek += n;
1565 if (vec_seek == vec->iov_len) {
1566 vec++;
1567 vec_seek = 0;
1568 }
1569 } while (len);
1570 *pvec = vec;
1571 *pvec_seek = vec_seek;
1479 1572
1480 /* GO GO GO */ 1573 /* GO GO GO */
1481 map_write(map, CMD(0xd0), cmd_adr); 1574 map_write(map, CMD(0xd0), cmd_adr);
1482 chip->state = FL_WRITING; 1575 chip->state = FL_WRITING;
1483 1576
1484 INVALIDATE_CACHE_UDELAY(map, chip, 1577 INVALIDATE_CACHE_UDELAY(map, chip,
1485 cmd_adr, len, 1578 cmd_adr, len,
1486 chip->buffer_write_time); 1579 chip->buffer_write_time);
1487 1580
@@ -1507,13 +1600,14 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1507 1600
1508 /* OK Still waiting */ 1601 /* OK Still waiting */
1509 if (time_after(jiffies, timeo)) { 1602 if (time_after(jiffies, timeo)) {
1603 map_write(map, CMD(0x70), cmd_adr);
1510 chip->state = FL_STATUS; 1604 chip->state = FL_STATUS;
1511 xip_enable(map, chip, cmd_adr); 1605 xip_enable(map, chip, cmd_adr);
1512 printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); 1606 printk(KERN_ERR "%s: buffer write error (status timeout)\n", map->name);
1513 ret = -EIO; 1607 ret = -EIO;
1514 goto out; 1608 goto out;
1515 } 1609 }
1516 1610
1517 /* Latency issues. Drop the lock, wait a while and retry */ 1611 /* Latency issues. Drop the lock, wait a while and retry */
1518 z++; 1612 z++;
1519 UDELAY(map, chip, cmd_adr, 1); 1613 UDELAY(map, chip, cmd_adr, 1);
@@ -1521,21 +1615,34 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1521 if (!z) { 1615 if (!z) {
1522 chip->buffer_write_time--; 1616 chip->buffer_write_time--;
1523 if (!chip->buffer_write_time) 1617 if (!chip->buffer_write_time)
1524 chip->buffer_write_time++; 1618 chip->buffer_write_time = 1;
1525 } 1619 }
1526 if (z > 1) 1620 if (z > 1)
1527 chip->buffer_write_time++; 1621 chip->buffer_write_time++;
1528 1622
1529 /* Done and happy. */ 1623 /* Done and happy. */
1530 chip->state = FL_STATUS; 1624 chip->state = FL_STATUS;
1531 1625
1532 /* check for lock bit */ 1626 /* check for errors */
1533 if (map_word_bitsset(map, status, CMD(0x02))) { 1627 if (map_word_bitsset(map, status, CMD(0x1a))) {
1534 /* clear status */ 1628 unsigned long chipstatus = MERGESTATUS(status);
1629
1630 /* reset status */
1535 map_write(map, CMD(0x50), cmd_adr); 1631 map_write(map, CMD(0x50), cmd_adr);
1536 /* put back into read status register mode */ 1632 map_write(map, CMD(0x70), cmd_adr);
1537 map_write(map, CMD(0x70), adr); 1633 xip_enable(map, chip, cmd_adr);
1538 ret = -EROFS; 1634
1635 if (chipstatus & 0x02) {
1636 ret = -EROFS;
1637 } else if (chipstatus & 0x08) {
1638 printk(KERN_ERR "%s: buffer write error (bad VPP)\n", map->name);
1639 ret = -EIO;
1640 } else {
1641 printk(KERN_ERR "%s: buffer write error (status 0x%lx)\n", map->name, chipstatus);
1642 ret = -EINVAL;
1643 }
1644
1645 goto out;
1539 } 1646 }
1540 1647
1541 xip_enable(map, chip, cmd_adr); 1648 xip_enable(map, chip, cmd_adr);
@@ -1544,70 +1651,65 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1544 return ret; 1651 return ret;
1545} 1652}
1546 1653
1547static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to, 1654static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
1548 size_t len, size_t *retlen, const u_char *buf) 1655 unsigned long count, loff_t to, size_t *retlen)
1549{ 1656{
1550 struct map_info *map = mtd->priv; 1657 struct map_info *map = mtd->priv;
1551 struct cfi_private *cfi = map->fldrv_priv; 1658 struct cfi_private *cfi = map->fldrv_priv;
1552 int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; 1659 int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
1553 int ret = 0; 1660 int ret = 0;
1554 int chipnum; 1661 int chipnum;
1555 unsigned long ofs; 1662 unsigned long ofs, vec_seek, i;
1663 size_t len = 0;
1664
1665 for (i = 0; i < count; i++)
1666 len += vecs[i].iov_len;
1556 1667
1557 *retlen = 0; 1668 *retlen = 0;
1558 if (!len) 1669 if (!len)
1559 return 0; 1670 return 0;
1560 1671
1561 chipnum = to >> cfi->chipshift; 1672 chipnum = to >> cfi->chipshift;
1562 ofs = to - (chipnum << cfi->chipshift); 1673 ofs = to - (chipnum << cfi->chipshift);
1563 1674 vec_seek = 0;
1564 /* If it's not bus-aligned, do the first word write */
1565 if (ofs & (map_bankwidth(map)-1)) {
1566 size_t local_len = (-ofs)&(map_bankwidth(map)-1);
1567 if (local_len > len)
1568 local_len = len;
1569 ret = cfi_intelext_write_words(mtd, to, local_len,
1570 retlen, buf);
1571 if (ret)
1572 return ret;
1573 ofs += local_len;
1574 buf += local_len;
1575 len -= local_len;
1576
1577 if (ofs >> cfi->chipshift) {
1578 chipnum ++;
1579 ofs = 0;
1580 if (chipnum == cfi->numchips)
1581 return 0;
1582 }
1583 }
1584 1675
1585 while(len) { 1676 do {
1586 /* We must not cross write block boundaries */ 1677 /* We must not cross write block boundaries */
1587 int size = wbufsize - (ofs & (wbufsize-1)); 1678 int size = wbufsize - (ofs & (wbufsize-1));
1588 1679
1589 if (size > len) 1680 if (size > len)
1590 size = len; 1681 size = len;
1591 ret = do_write_buffer(map, &cfi->chips[chipnum], 1682 ret = do_write_buffer(map, &cfi->chips[chipnum],
1592 ofs, buf, size); 1683 ofs, &vecs, &vec_seek, size);
1593 if (ret) 1684 if (ret)
1594 return ret; 1685 return ret;
1595 1686
1596 ofs += size; 1687 ofs += size;
1597 buf += size;
1598 (*retlen) += size; 1688 (*retlen) += size;
1599 len -= size; 1689 len -= size;
1600 1690
1601 if (ofs >> cfi->chipshift) { 1691 if (ofs >> cfi->chipshift) {
1602 chipnum ++; 1692 chipnum ++;
1603 ofs = 0; 1693 ofs = 0;
1604 if (chipnum == cfi->numchips) 1694 if (chipnum == cfi->numchips)
1605 return 0; 1695 return 0;
1606 } 1696 }
1607 } 1697 } while (len);
1698
1608 return 0; 1699 return 0;
1609} 1700}
1610 1701
1702static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to,
1703 size_t len, size_t *retlen, const u_char *buf)
1704{
1705 struct kvec vec;
1706
1707 vec.iov_base = (void *) buf;
1708 vec.iov_len = len;
1709
1710 return cfi_intelext_writev(mtd, &vec, 1, to, retlen);
1711}
1712
1611static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, 1713static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1612 unsigned long adr, int len, void *thunk) 1714 unsigned long adr, int len, void *thunk)
1613{ 1715{
@@ -1673,23 +1775,17 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1673 status = map_read(map, adr); 1775 status = map_read(map, adr);
1674 if (map_word_andequal(map, status, status_OK, status_OK)) 1776 if (map_word_andequal(map, status, status_OK, status_OK))
1675 break; 1777 break;
1676 1778
1677 /* OK Still waiting */ 1779 /* OK Still waiting */
1678 if (time_after(jiffies, timeo)) { 1780 if (time_after(jiffies, timeo)) {
1679 map_word Xstatus;
1680 map_write(map, CMD(0x70), adr); 1781 map_write(map, CMD(0x70), adr);
1681 chip->state = FL_STATUS; 1782 chip->state = FL_STATUS;
1682 Xstatus = map_read(map, adr);
1683 /* Clear status bits */
1684 map_write(map, CMD(0x50), adr);
1685 map_write(map, CMD(0x70), adr);
1686 xip_enable(map, chip, adr); 1783 xip_enable(map, chip, adr);
1687 printk(KERN_ERR "waiting for erase at %08lx to complete timed out. status = %lx, Xstatus = %lx.\n", 1784 printk(KERN_ERR "%s: block erase error: (status timeout)\n", map->name);
1688 adr, status.x[0], Xstatus.x[0]);
1689 ret = -EIO; 1785 ret = -EIO;
1690 goto out; 1786 goto out;
1691 } 1787 }
1692 1788
1693 /* Latency issues. Drop the lock, wait a while and retry */ 1789 /* Latency issues. Drop the lock, wait a while and retry */
1694 UDELAY(map, chip, adr, 1000000/HZ); 1790 UDELAY(map, chip, adr, 1000000/HZ);
1695 } 1791 }
@@ -1699,43 +1795,40 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
1699 chip->state = FL_STATUS; 1795 chip->state = FL_STATUS;
1700 status = map_read(map, adr); 1796 status = map_read(map, adr);
1701 1797
1702 /* check for lock bit */ 1798 /* check for errors */
1703 if (map_word_bitsset(map, status, CMD(0x3a))) { 1799 if (map_word_bitsset(map, status, CMD(0x3a))) {
1704 unsigned long chipstatus; 1800 unsigned long chipstatus = MERGESTATUS(status);
1705 1801
1706 /* Reset the error bits */ 1802 /* Reset the error bits */
1707 map_write(map, CMD(0x50), adr); 1803 map_write(map, CMD(0x50), adr);
1708 map_write(map, CMD(0x70), adr); 1804 map_write(map, CMD(0x70), adr);
1709 xip_enable(map, chip, adr); 1805 xip_enable(map, chip, adr);
1710 1806
1711 chipstatus = MERGESTATUS(status);
1712
1713 if ((chipstatus & 0x30) == 0x30) { 1807 if ((chipstatus & 0x30) == 0x30) {
1714 printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%lx\n", chipstatus); 1808 printk(KERN_ERR "%s: block erase error: (bad command sequence, status 0x%lx)\n", map->name, chipstatus);
1715 ret = -EIO; 1809 ret = -EINVAL;
1716 } else if (chipstatus & 0x02) { 1810 } else if (chipstatus & 0x02) {
1717 /* Protection bit set */ 1811 /* Protection bit set */
1718 ret = -EROFS; 1812 ret = -EROFS;
1719 } else if (chipstatus & 0x8) { 1813 } else if (chipstatus & 0x8) {
1720 /* Voltage */ 1814 /* Voltage */
1721 printk(KERN_WARNING "Chip reports voltage low on erase: status 0x%lx\n", chipstatus); 1815 printk(KERN_ERR "%s: block erase error: (bad VPP)\n", map->name);
1722 ret = -EIO; 1816 ret = -EIO;
1723 } else if (chipstatus & 0x20) { 1817 } else if (chipstatus & 0x20 && retries--) {
1724 if (retries--) { 1818 printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
1725 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus); 1819 timeo = jiffies + HZ;
1726 timeo = jiffies + HZ; 1820 put_chip(map, chip, adr);
1727 put_chip(map, chip, adr); 1821 spin_unlock(chip->mutex);
1728 spin_unlock(chip->mutex); 1822 goto retry;
1729 goto retry; 1823 } else {
1730 } 1824 printk(KERN_ERR "%s: block erase failed at 0x%08lx (status 0x%lx)\n", map->name, adr, chipstatus);
1731 printk(KERN_DEBUG "Chip erase failed at 0x%08lx: status 0x%lx\n", adr, chipstatus);
1732 ret = -EIO; 1825 ret = -EIO;
1733 } 1826 }
1734 } else { 1827
1735 xip_enable(map, chip, adr); 1828 goto out;
1736 ret = 0;
1737 } 1829 }
1738 1830
1831 xip_enable(map, chip, adr);
1739 out: put_chip(map, chip, adr); 1832 out: put_chip(map, chip, adr);
1740 spin_unlock(chip->mutex); 1833 spin_unlock(chip->mutex);
1741 return ret; 1834 return ret;
@@ -1755,7 +1848,7 @@ int cfi_intelext_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1755 1848
1756 instr->state = MTD_ERASE_DONE; 1849 instr->state = MTD_ERASE_DONE;
1757 mtd_erase_callback(instr); 1850 mtd_erase_callback(instr);
1758 1851
1759 return 0; 1852 return 0;
1760} 1853}
1761 1854
@@ -1776,7 +1869,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
1776 if (!ret) { 1869 if (!ret) {
1777 chip->oldstate = chip->state; 1870 chip->oldstate = chip->state;
1778 chip->state = FL_SYNCING; 1871 chip->state = FL_SYNCING;
1779 /* No need to wake_up() on this state change - 1872 /* No need to wake_up() on this state change -
1780 * as the whole point is that nobody can do anything 1873 * as the whole point is that nobody can do anything
1781 * with the chip now anyway. 1874 * with the chip now anyway.
1782 */ 1875 */
@@ -1790,7 +1883,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
1790 chip = &cfi->chips[i]; 1883 chip = &cfi->chips[i];
1791 1884
1792 spin_lock(chip->mutex); 1885 spin_lock(chip->mutex);
1793 1886
1794 if (chip->state == FL_SYNCING) { 1887 if (chip->state == FL_SYNCING) {
1795 chip->state = chip->oldstate; 1888 chip->state = chip->oldstate;
1796 chip->oldstate = FL_READY; 1889 chip->oldstate = FL_READY;
@@ -1847,7 +1940,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1847 1940
1848 ENABLE_VPP(map); 1941 ENABLE_VPP(map);
1849 xip_disable(map, chip, adr); 1942 xip_disable(map, chip, adr);
1850 1943
1851 map_write(map, CMD(0x60), adr); 1944 map_write(map, CMD(0x60), adr);
1852 if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) { 1945 if (thunk == DO_XXLOCK_ONEBLOCK_LOCK) {
1853 map_write(map, CMD(0x01), adr); 1946 map_write(map, CMD(0x01), adr);
@@ -1875,25 +1968,22 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
1875 status = map_read(map, adr); 1968 status = map_read(map, adr);
1876 if (map_word_andequal(map, status, status_OK, status_OK)) 1969 if (map_word_andequal(map, status, status_OK, status_OK))
1877 break; 1970 break;
1878 1971
1879 /* OK Still waiting */ 1972 /* OK Still waiting */
1880 if (time_after(jiffies, timeo)) { 1973 if (time_after(jiffies, timeo)) {
1881 map_word Xstatus;
1882 map_write(map, CMD(0x70), adr); 1974 map_write(map, CMD(0x70), adr);
1883 chip->state = FL_STATUS; 1975 chip->state = FL_STATUS;
1884 Xstatus = map_read(map, adr);
1885 xip_enable(map, chip, adr); 1976 xip_enable(map, chip, adr);
1886 printk(KERN_ERR "waiting for unlock to complete timed out. status = %lx, Xstatus = %lx.\n", 1977 printk(KERN_ERR "%s: block unlock error: (status timeout)\n", map->name);
1887 status.x[0], Xstatus.x[0]);
1888 put_chip(map, chip, adr); 1978 put_chip(map, chip, adr);
1889 spin_unlock(chip->mutex); 1979 spin_unlock(chip->mutex);
1890 return -EIO; 1980 return -EIO;
1891 } 1981 }
1892 1982
1893 /* Latency issues. Drop the lock, wait a while and retry */ 1983 /* Latency issues. Drop the lock, wait a while and retry */
1894 UDELAY(map, chip, adr, 1); 1984 UDELAY(map, chip, adr, 1);
1895 } 1985 }
1896 1986
1897 /* Done and happy. */ 1987 /* Done and happy. */
1898 chip->state = FL_STATUS; 1988 chip->state = FL_STATUS;
1899 xip_enable(map, chip, adr); 1989 xip_enable(map, chip, adr);
@@ -1913,9 +2003,9 @@ static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1913 ofs, len, 0); 2003 ofs, len, 0);
1914#endif 2004#endif
1915 2005
1916 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 2006 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
1917 ofs, len, DO_XXLOCK_ONEBLOCK_LOCK); 2007 ofs, len, DO_XXLOCK_ONEBLOCK_LOCK);
1918 2008
1919#ifdef DEBUG_LOCK_BITS 2009#ifdef DEBUG_LOCK_BITS
1920 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 2010 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1921 __FUNCTION__, ret); 2011 __FUNCTION__, ret);
@@ -1939,20 +2029,20 @@ static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1939 2029
1940 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock, 2030 ret = cfi_varsize_frob(mtd, do_xxlock_oneblock,
1941 ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK); 2031 ofs, len, DO_XXLOCK_ONEBLOCK_UNLOCK);
1942 2032
1943#ifdef DEBUG_LOCK_BITS 2033#ifdef DEBUG_LOCK_BITS
1944 printk(KERN_DEBUG "%s: lock status after, ret=%d\n", 2034 printk(KERN_DEBUG "%s: lock status after, ret=%d\n",
1945 __FUNCTION__, ret); 2035 __FUNCTION__, ret);
1946 cfi_varsize_frob(mtd, do_printlockstatus_oneblock, 2036 cfi_varsize_frob(mtd, do_printlockstatus_oneblock,
1947 ofs, len, 0); 2037 ofs, len, 0);
1948#endif 2038#endif
1949 2039
1950 return ret; 2040 return ret;
1951} 2041}
1952 2042
1953#ifdef CONFIG_MTD_OTP 2043#ifdef CONFIG_MTD_OTP
1954 2044
1955typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip, 2045typedef int (*otp_op_t)(struct map_info *map, struct flchip *chip,
1956 u_long data_offset, u_char *buf, u_int size, 2046 u_long data_offset, u_char *buf, u_int size,
1957 u_long prot_offset, u_int groupno, u_int groupsize); 2047 u_long prot_offset, u_int groupno, u_int groupsize);
1958 2048
@@ -2003,7 +2093,7 @@ do_otp_write(struct map_info *map, struct flchip *chip, u_long offset,
2003 2093
2004 datum = map_word_load_partial(map, datum, buf, gap, n); 2094 datum = map_word_load_partial(map, datum, buf, gap, n);
2005 ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE); 2095 ret = do_write_oneword(map, chip, bus_ofs, datum, FL_OTP_WRITE);
2006 if (ret) 2096 if (ret)
2007 return ret; 2097 return ret;
2008 2098
2009 offset += n; 2099 offset += n;
@@ -2196,7 +2286,7 @@ static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
2196 NULL, do_otp_lock, 1); 2286 NULL, do_otp_lock, 1);
2197} 2287}
2198 2288
2199static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd, 2289static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
2200 struct otp_info *buf, size_t len) 2290 struct otp_info *buf, size_t len)
2201{ 2291{
2202 size_t retlen; 2292 size_t retlen;
@@ -2239,7 +2329,7 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
2239 if (chip->oldstate == FL_READY) { 2329 if (chip->oldstate == FL_READY) {
2240 chip->oldstate = chip->state; 2330 chip->oldstate = chip->state;
2241 chip->state = FL_PM_SUSPENDED; 2331 chip->state = FL_PM_SUSPENDED;
2242 /* No need to wake_up() on this state change - 2332 /* No need to wake_up() on this state change -
2243 * as the whole point is that nobody can do anything 2333 * as the whole point is that nobody can do anything
2244 * with the chip now anyway. 2334 * with the chip now anyway.
2245 */ 2335 */
@@ -2267,9 +2357,9 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
2267 if (ret) { 2357 if (ret) {
2268 for (i--; i >=0; i--) { 2358 for (i--; i >=0; i--) {
2269 chip = &cfi->chips[i]; 2359 chip = &cfi->chips[i];
2270 2360
2271 spin_lock(chip->mutex); 2361 spin_lock(chip->mutex);
2272 2362
2273 if (chip->state == FL_PM_SUSPENDED) { 2363 if (chip->state == FL_PM_SUSPENDED) {
2274 /* No need to force it into a known state here, 2364 /* No need to force it into a known state here,
2275 because we're returning failure, and it didn't 2365 because we're returning failure, and it didn't
@@ -2280,8 +2370,8 @@ static int cfi_intelext_suspend(struct mtd_info *mtd)
2280 } 2370 }
2281 spin_unlock(chip->mutex); 2371 spin_unlock(chip->mutex);
2282 } 2372 }
2283 } 2373 }
2284 2374
2285 return ret; 2375 return ret;
2286} 2376}
2287 2377
@@ -2293,11 +2383,11 @@ static void cfi_intelext_resume(struct mtd_info *mtd)
2293 struct flchip *chip; 2383 struct flchip *chip;
2294 2384
2295 for (i=0; i<cfi->numchips; i++) { 2385 for (i=0; i<cfi->numchips; i++) {
2296 2386
2297 chip = &cfi->chips[i]; 2387 chip = &cfi->chips[i];
2298 2388
2299 spin_lock(chip->mutex); 2389 spin_lock(chip->mutex);
2300 2390
2301 /* Go to known state. Chip may have been power cycled */ 2391 /* Go to known state. Chip may have been power cycled */
2302 if (chip->state == FL_PM_SUSPENDED) { 2392 if (chip->state == FL_PM_SUSPENDED) {
2303 map_write(map, CMD(0xFF), cfi->chips[i].start); 2393 map_write(map, CMD(0xFF), cfi->chips[i].start);
@@ -2319,7 +2409,7 @@ static int cfi_intelext_reset(struct mtd_info *mtd)
2319 struct flchip *chip = &cfi->chips[i]; 2409 struct flchip *chip = &cfi->chips[i];
2320 2410
2321 /* force the completion of any ongoing operation 2411 /* force the completion of any ongoing operation
2322 and switch to array mode so any bootloader in 2412 and switch to array mode so any bootloader in
2323 flash is accessible for soft reboot. */ 2413 flash is accessible for soft reboot. */
2324 spin_lock(chip->mutex); 2414 spin_lock(chip->mutex);
2325 ret = get_chip(map, chip, chip->start, FL_SYNCING); 2415 ret = get_chip(map, chip, chip->start, FL_SYNCING);
@@ -2356,20 +2446,23 @@ static void cfi_intelext_destroy(struct mtd_info *mtd)
2356 kfree(mtd->eraseregions); 2446 kfree(mtd->eraseregions);
2357} 2447}
2358 2448
2359static char im_name_1[]="cfi_cmdset_0001"; 2449static char im_name_0001[] = "cfi_cmdset_0001";
2360static char im_name_3[]="cfi_cmdset_0003"; 2450static char im_name_0003[] = "cfi_cmdset_0003";
2451static char im_name_0200[] = "cfi_cmdset_0200";
2361 2452
2362static int __init cfi_intelext_init(void) 2453static int __init cfi_intelext_init(void)
2363{ 2454{
2364 inter_module_register(im_name_1, THIS_MODULE, &cfi_cmdset_0001); 2455 inter_module_register(im_name_0001, THIS_MODULE, &cfi_cmdset_0001);
2365 inter_module_register(im_name_3, THIS_MODULE, &cfi_cmdset_0001); 2456 inter_module_register(im_name_0003, THIS_MODULE, &cfi_cmdset_0001);
2457 inter_module_register(im_name_0200, THIS_MODULE, &cfi_cmdset_0001);
2366 return 0; 2458 return 0;
2367} 2459}
2368 2460
2369static void __exit cfi_intelext_exit(void) 2461static void __exit cfi_intelext_exit(void)
2370{ 2462{
2371 inter_module_unregister(im_name_1); 2463 inter_module_unregister(im_name_0001);
2372 inter_module_unregister(im_name_3); 2464 inter_module_unregister(im_name_0003);
2465 inter_module_unregister(im_name_0200);
2373} 2466}
2374 2467
2375module_init(cfi_intelext_init); 2468module_init(cfi_intelext_init);
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 8505f118f2db..aed10bd5c3c3 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -10,14 +10,14 @@
10 * 10 *
11 * 4_by_16 work by Carolyn J. Smith 11 * 4_by_16 work by Carolyn J. Smith
12 * 12 *
13 * XIP support hooks by Vitaly Wool (based on code for Intel flash 13 * XIP support hooks by Vitaly Wool (based on code for Intel flash
14 * by Nicolas Pitre) 14 * by Nicolas Pitre)
15 * 15 *
16 * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com 16 * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
17 * 17 *
18 * This code is GPL 18 * This code is GPL
19 * 19 *
20 * $Id: cfi_cmdset_0002.c,v 1.118 2005/07/04 22:34:29 gleixner Exp $ 20 * $Id: cfi_cmdset_0002.c,v 1.122 2005/11/07 11:14:22 gleixner Exp $
21 * 21 *
22 */ 22 */
23 23
@@ -93,7 +93,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
93 }; 93 };
94 94
95 printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1); 95 printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1);
96 printk(" Address sensitive unlock: %s\n", 96 printk(" Address sensitive unlock: %s\n",
97 (extp->SiliconRevision & 1) ? "Not required" : "Required"); 97 (extp->SiliconRevision & 1) ? "Not required" : "Required");
98 98
99 if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend)) 99 if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend))
@@ -118,9 +118,9 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp)
118 else 118 else
119 printk(" Page mode: %d word page\n", extp->PageMode << 2); 119 printk(" Page mode: %d word page\n", extp->PageMode << 2);
120 120
121 printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n", 121 printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n",
122 extp->VppMin >> 4, extp->VppMin & 0xf); 122 extp->VppMin >> 4, extp->VppMin & 0xf);
123 printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n", 123 printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n",
124 extp->VppMax >> 4, extp->VppMax & 0xf); 124 extp->VppMax >> 4, extp->VppMax & 0xf);
125 125
126 if (extp->TopBottom < ARRAY_SIZE(top_bottom)) 126 if (extp->TopBottom < ARRAY_SIZE(top_bottom))
@@ -177,7 +177,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param)
177 ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) { 177 ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) == 0)) {
178 mtd->erase = cfi_amdstd_erase_chip; 178 mtd->erase = cfi_amdstd_erase_chip;
179 } 179 }
180 180
181} 181}
182 182
183static struct cfi_fixup cfi_fixup_table[] = { 183static struct cfi_fixup cfi_fixup_table[] = {
@@ -239,7 +239,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
239 239
240 if (cfi->cfi_mode==CFI_MODE_CFI){ 240 if (cfi->cfi_mode==CFI_MODE_CFI){
241 unsigned char bootloc; 241 unsigned char bootloc;
242 /* 242 /*
243 * It's a real CFI chip, not one for which the probe 243 * It's a real CFI chip, not one for which the probe
244 * routine faked a CFI structure. So we read the feature 244 * routine faked a CFI structure. So we read the feature
245 * table from it. 245 * table from it.
@@ -253,8 +253,18 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
253 return NULL; 253 return NULL;
254 } 254 }
255 255
256 if (extp->MajorVersion != '1' ||
257 (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
258 printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
259 "version %c.%c.\n", extp->MajorVersion,
260 extp->MinorVersion);
261 kfree(extp);
262 kfree(mtd);
263 return NULL;
264 }
265
256 /* Install our own private info structure */ 266 /* Install our own private info structure */
257 cfi->cmdset_priv = extp; 267 cfi->cmdset_priv = extp;
258 268
259 /* Apply cfi device specific fixups */ 269 /* Apply cfi device specific fixups */
260 cfi_fixup(mtd, cfi_fixup_table); 270 cfi_fixup(mtd, cfi_fixup_table);
@@ -262,7 +272,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
262#ifdef DEBUG_CFI_FEATURES 272#ifdef DEBUG_CFI_FEATURES
263 /* Tell the user about it in lots of lovely detail */ 273 /* Tell the user about it in lots of lovely detail */
264 cfi_tell_features(extp); 274 cfi_tell_features(extp);
265#endif 275#endif
266 276
267 bootloc = extp->TopBottom; 277 bootloc = extp->TopBottom;
268 if ((bootloc != 2) && (bootloc != 3)) { 278 if ((bootloc != 2) && (bootloc != 3)) {
@@ -273,11 +283,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
273 283
274 if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) { 284 if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
275 printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name); 285 printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
276 286
277 for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) { 287 for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) {
278 int j = (cfi->cfiq->NumEraseRegions-1)-i; 288 int j = (cfi->cfiq->NumEraseRegions-1)-i;
279 __u32 swap; 289 __u32 swap;
280 290
281 swap = cfi->cfiq->EraseRegionInfo[i]; 291 swap = cfi->cfiq->EraseRegionInfo[i];
282 cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j]; 292 cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j];
283 cfi->cfiq->EraseRegionInfo[j] = swap; 293 cfi->cfiq->EraseRegionInfo[j] = swap;
@@ -288,11 +298,11 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
288 cfi->addr_unlock2 = 0x2aa; 298 cfi->addr_unlock2 = 0x2aa;
289 /* Modify the unlock address if we are in compatibility mode */ 299 /* Modify the unlock address if we are in compatibility mode */
290 if ( /* x16 in x8 mode */ 300 if ( /* x16 in x8 mode */
291 ((cfi->device_type == CFI_DEVICETYPE_X8) && 301 ((cfi->device_type == CFI_DEVICETYPE_X8) &&
292 (cfi->cfiq->InterfaceDesc == 2)) || 302 (cfi->cfiq->InterfaceDesc == 2)) ||
293 /* x32 in x16 mode */ 303 /* x32 in x16 mode */
294 ((cfi->device_type == CFI_DEVICETYPE_X16) && 304 ((cfi->device_type == CFI_DEVICETYPE_X16) &&
295 (cfi->cfiq->InterfaceDesc == 4))) 305 (cfi->cfiq->InterfaceDesc == 4)))
296 { 306 {
297 cfi->addr_unlock1 = 0xaaa; 307 cfi->addr_unlock1 = 0xaaa;
298 cfi->addr_unlock2 = 0x555; 308 cfi->addr_unlock2 = 0x555;
@@ -310,10 +320,10 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
310 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp; 320 cfi->chips[i].word_write_time = 1<<cfi->cfiq->WordWriteTimeoutTyp;
311 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp; 321 cfi->chips[i].buffer_write_time = 1<<cfi->cfiq->BufWriteTimeoutTyp;
312 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp; 322 cfi->chips[i].erase_time = 1<<cfi->cfiq->BlockEraseTimeoutTyp;
313 } 323 }
314 324
315 map->fldrv = &cfi_amdstd_chipdrv; 325 map->fldrv = &cfi_amdstd_chipdrv;
316 326
317 return cfi_amdstd_setup(mtd); 327 return cfi_amdstd_setup(mtd);
318} 328}
319 329
@@ -326,24 +336,24 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
326 unsigned long offset = 0; 336 unsigned long offset = 0;
327 int i,j; 337 int i,j;
328 338
329 printk(KERN_NOTICE "number of %s chips: %d\n", 339 printk(KERN_NOTICE "number of %s chips: %d\n",
330 (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips); 340 (cfi->cfi_mode == CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips);
331 /* Select the correct geometry setup */ 341 /* Select the correct geometry setup */
332 mtd->size = devsize * cfi->numchips; 342 mtd->size = devsize * cfi->numchips;
333 343
334 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; 344 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
335 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 345 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
336 * mtd->numeraseregions, GFP_KERNEL); 346 * mtd->numeraseregions, GFP_KERNEL);
337 if (!mtd->eraseregions) { 347 if (!mtd->eraseregions) {
338 printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n"); 348 printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
339 goto setup_err; 349 goto setup_err;
340 } 350 }
341 351
342 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 352 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
343 unsigned long ernum, ersize; 353 unsigned long ernum, ersize;
344 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; 354 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
345 ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; 355 ernum = (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1;
346 356
347 if (mtd->erasesize < ersize) { 357 if (mtd->erasesize < ersize) {
348 mtd->erasesize = ersize; 358 mtd->erasesize = ersize;
349 } 359 }
@@ -378,8 +388,7 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
378 388
379 setup_err: 389 setup_err:
380 if(mtd) { 390 if(mtd) {
381 if(mtd->eraseregions) 391 kfree(mtd->eraseregions);
382 kfree(mtd->eraseregions);
383 kfree(mtd); 392 kfree(mtd);
384 } 393 }
385 kfree(cfi->cmdset_priv); 394 kfree(cfi->cmdset_priv);
@@ -430,7 +439,7 @@ static int __xipram chip_good(struct map_info *map, unsigned long addr, map_word
430 oldd = map_read(map, addr); 439 oldd = map_read(map, addr);
431 curd = map_read(map, addr); 440 curd = map_read(map, addr);
432 441
433 return map_word_equal(map, oldd, curd) && 442 return map_word_equal(map, oldd, curd) &&
434 map_word_equal(map, curd, expected); 443 map_word_equal(map, curd, expected);
435} 444}
436 445
@@ -462,7 +471,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
462 /* Someone else might have been playing with it. */ 471 /* Someone else might have been playing with it. */
463 goto retry; 472 goto retry;
464 } 473 }
465 474
466 case FL_READY: 475 case FL_READY:
467 case FL_CFI_QUERY: 476 case FL_CFI_QUERY:
468 case FL_JEDEC_QUERY: 477 case FL_JEDEC_QUERY:
@@ -505,7 +514,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
505 printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__); 514 printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
506 return -EIO; 515 return -EIO;
507 } 516 }
508 517
509 spin_unlock(chip->mutex); 518 spin_unlock(chip->mutex);
510 cfi_udelay(1); 519 cfi_udelay(1);
511 spin_lock(chip->mutex); 520 spin_lock(chip->mutex);
@@ -608,7 +617,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
608 * When a delay is required for the flash operation to complete, the 617 * When a delay is required for the flash operation to complete, the
609 * xip_udelay() function is polling for both the given timeout and pending 618 * xip_udelay() function is polling for both the given timeout and pending
610 * (but still masked) hardware interrupts. Whenever there is an interrupt 619 * (but still masked) hardware interrupts. Whenever there is an interrupt
611 * pending then the flash erase operation is suspended, array mode restored 620 * pending then the flash erase operation is suspended, array mode restored
612 * and interrupts unmasked. Task scheduling might also happen at that 621 * and interrupts unmasked. Task scheduling might also happen at that
613 * point. The CPU eventually returns from the interrupt or the call to 622 * point. The CPU eventually returns from the interrupt or the call to
614 * schedule() and the suspended flash operation is resumed for the remaining 623 * schedule() and the suspended flash operation is resumed for the remaining
@@ -632,9 +641,9 @@ static void __xipram xip_udelay(struct map_info *map, struct flchip *chip,
632 ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) && 641 ((chip->state == FL_ERASING && (extp->EraseSuspend & 2))) &&
633 (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) { 642 (cfi_interleave_is_1(cfi) || chip->oldstate == FL_READY)) {
634 /* 643 /*
635 * Let's suspend the erase operation when supported. 644 * Let's suspend the erase operation when supported.
636 * Note that we currently don't try to suspend 645 * Note that we currently don't try to suspend
637 * interleaved chips if there is already another 646 * interleaved chips if there is already another
638 * operation suspended (imagine what happens 647 * operation suspended (imagine what happens
639 * when one chip was already done with the current 648 * when one chip was already done with the current
640 * operation while another chip suspended it, then 649 * operation while another chip suspended it, then
@@ -770,8 +779,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
770 779
771 adr += chip->start; 780 adr += chip->start;
772 781
773 /* Ensure cmd read/writes are aligned. */ 782 /* Ensure cmd read/writes are aligned. */
774 cmd_addr = adr & ~(map_bankwidth(map)-1); 783 cmd_addr = adr & ~(map_bankwidth(map)-1);
775 784
776 spin_lock(chip->mutex); 785 spin_lock(chip->mutex);
777 ret = get_chip(map, chip, cmd_addr, FL_READY); 786 ret = get_chip(map, chip, cmd_addr, FL_READY);
@@ -851,7 +860,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
851#endif 860#endif
852 set_current_state(TASK_UNINTERRUPTIBLE); 861 set_current_state(TASK_UNINTERRUPTIBLE);
853 add_wait_queue(&chip->wq, &wait); 862 add_wait_queue(&chip->wq, &wait);
854 863
855 spin_unlock(chip->mutex); 864 spin_unlock(chip->mutex);
856 865
857 schedule(); 866 schedule();
@@ -863,7 +872,7 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
863 timeo = jiffies + HZ; 872 timeo = jiffies + HZ;
864 873
865 goto retry; 874 goto retry;
866 } 875 }
867 876
868 adr += chip->start; 877 adr += chip->start;
869 878
@@ -872,14 +881,14 @@ static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chi
872 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 881 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
873 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 882 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
874 cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 883 cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
875 884
876 map_copy_from(map, buf, adr, len); 885 map_copy_from(map, buf, adr, len);
877 886
878 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 887 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
879 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 888 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
880 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 889 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
881 cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 890 cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
882 891
883 wake_up(&chip->wq); 892 wake_up(&chip->wq);
884 spin_unlock(chip->mutex); 893 spin_unlock(chip->mutex);
885 894
@@ -988,7 +997,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
988 chip->word_write_time); 997 chip->word_write_time);
989 998
990 /* See comment above for timeout value. */ 999 /* See comment above for timeout value. */
991 timeo = jiffies + uWriteTimeout; 1000 timeo = jiffies + uWriteTimeout;
992 for (;;) { 1001 for (;;) {
993 if (chip->state != FL_WRITING) { 1002 if (chip->state != FL_WRITING) {
994 /* Someone's suspended the write. Sleep */ 1003 /* Someone's suspended the write. Sleep */
@@ -1004,16 +1013,16 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1004 continue; 1013 continue;
1005 } 1014 }
1006 1015
1007 if (chip_ready(map, adr)) 1016 if (time_after(jiffies, timeo) && !chip_ready(map, adr)){
1008 break;
1009
1010 if (time_after(jiffies, timeo)) {
1011 xip_enable(map, chip, adr); 1017 xip_enable(map, chip, adr);
1012 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__); 1018 printk(KERN_WARNING "MTD %s(): software timeout\n", __func__);
1013 xip_disable(map, chip, adr); 1019 xip_disable(map, chip, adr);
1014 break; 1020 break;
1015 } 1021 }
1016 1022
1023 if (chip_ready(map, adr))
1024 break;
1025
1017 /* Latency issues. Drop the lock, wait a while and retry */ 1026 /* Latency issues. Drop the lock, wait a while and retry */
1018 UDELAY(map, chip, adr, 1); 1027 UDELAY(map, chip, adr, 1);
1019 } 1028 }
@@ -1023,7 +1032,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
1023 map_write( map, CMD(0xF0), chip->start ); 1032 map_write( map, CMD(0xF0), chip->start );
1024 /* FIXME - should have reset delay before continuing */ 1033 /* FIXME - should have reset delay before continuing */
1025 1034
1026 if (++retry_cnt <= MAX_WORD_RETRIES) 1035 if (++retry_cnt <= MAX_WORD_RETRIES)
1027 goto retry; 1036 goto retry;
1028 1037
1029 ret = -EIO; 1038 ret = -EIO;
@@ -1091,27 +1100,27 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1091 1100
1092 /* Number of bytes to copy from buffer */ 1101 /* Number of bytes to copy from buffer */
1093 n = min_t(int, len, map_bankwidth(map)-i); 1102 n = min_t(int, len, map_bankwidth(map)-i);
1094 1103
1095 tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n); 1104 tmp_buf = map_word_load_partial(map, tmp_buf, buf, i, n);
1096 1105
1097 ret = do_write_oneword(map, &cfi->chips[chipnum], 1106 ret = do_write_oneword(map, &cfi->chips[chipnum],
1098 bus_ofs, tmp_buf); 1107 bus_ofs, tmp_buf);
1099 if (ret) 1108 if (ret)
1100 return ret; 1109 return ret;
1101 1110
1102 ofs += n; 1111 ofs += n;
1103 buf += n; 1112 buf += n;
1104 (*retlen) += n; 1113 (*retlen) += n;
1105 len -= n; 1114 len -= n;
1106 1115
1107 if (ofs >> cfi->chipshift) { 1116 if (ofs >> cfi->chipshift) {
1108 chipnum ++; 1117 chipnum ++;
1109 ofs = 0; 1118 ofs = 0;
1110 if (chipnum == cfi->numchips) 1119 if (chipnum == cfi->numchips)
1111 return 0; 1120 return 0;
1112 } 1121 }
1113 } 1122 }
1114 1123
1115 /* We are now aligned, write as much as possible */ 1124 /* We are now aligned, write as much as possible */
1116 while(len >= map_bankwidth(map)) { 1125 while(len >= map_bankwidth(map)) {
1117 map_word datum; 1126 map_word datum;
@@ -1129,7 +1138,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1129 len -= map_bankwidth(map); 1138 len -= map_bankwidth(map);
1130 1139
1131 if (ofs >> cfi->chipshift) { 1140 if (ofs >> cfi->chipshift) {
1132 chipnum ++; 1141 chipnum ++;
1133 ofs = 0; 1142 ofs = 0;
1134 if (chipnum == cfi->numchips) 1143 if (chipnum == cfi->numchips)
1135 return 0; 1144 return 0;
@@ -1167,12 +1176,12 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1167 spin_unlock(cfi->chips[chipnum].mutex); 1176 spin_unlock(cfi->chips[chipnum].mutex);
1168 1177
1169 tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len); 1178 tmp_buf = map_word_load_partial(map, tmp_buf, buf, 0, len);
1170 1179
1171 ret = do_write_oneword(map, &cfi->chips[chipnum], 1180 ret = do_write_oneword(map, &cfi->chips[chipnum],
1172 ofs, tmp_buf); 1181 ofs, tmp_buf);
1173 if (ret) 1182 if (ret)
1174 return ret; 1183 return ret;
1175 1184
1176 (*retlen) += len; 1185 (*retlen) += len;
1177 } 1186 }
1178 1187
@@ -1184,7 +1193,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
1184 * FIXME: interleaved mode not tested, and probably not supported! 1193 * FIXME: interleaved mode not tested, and probably not supported!
1185 */ 1194 */
1186static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, 1195static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1187 unsigned long adr, const u_char *buf, 1196 unsigned long adr, const u_char *buf,
1188 int len) 1197 int len)
1189{ 1198{
1190 struct cfi_private *cfi = map->fldrv_priv; 1199 struct cfi_private *cfi = map->fldrv_priv;
@@ -1214,7 +1223,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1214 XIP_INVAL_CACHED_RANGE(map, adr, len); 1223 XIP_INVAL_CACHED_RANGE(map, adr, len);
1215 ENABLE_VPP(map); 1224 ENABLE_VPP(map);
1216 xip_disable(map, chip, cmd_adr); 1225 xip_disable(map, chip, cmd_adr);
1217 1226
1218 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1227 cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
1219 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); 1228 cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
1220 //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); 1229 //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
@@ -1248,8 +1257,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1248 adr, map_bankwidth(map), 1257 adr, map_bankwidth(map),
1249 chip->word_write_time); 1258 chip->word_write_time);
1250 1259
1251 timeo = jiffies + uWriteTimeout; 1260 timeo = jiffies + uWriteTimeout;
1252 1261
1253 for (;;) { 1262 for (;;) {
1254 if (chip->state != FL_WRITING) { 1263 if (chip->state != FL_WRITING) {
1255 /* Someone's suspended the write. Sleep */ 1264 /* Someone's suspended the write. Sleep */
@@ -1265,13 +1274,13 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
1265 continue; 1274 continue;
1266 } 1275 }
1267 1276
1277 if (time_after(jiffies, timeo) && !chip_ready(map, adr))
1278 break;
1279
1268 if (chip_ready(map, adr)) { 1280 if (chip_ready(map, adr)) {
1269 xip_enable(map, chip, adr); 1281 xip_enable(map, chip, adr);
1270 goto op_done; 1282 goto op_done;
1271 } 1283 }
1272
1273 if( time_after(jiffies, timeo))
1274 break;
1275 1284
1276 /* Latency issues. Drop the lock, wait a while and retry */ 1285 /* Latency issues. Drop the lock, wait a while and retry */
1277 UDELAY(map, chip, adr, 1); 1286 UDELAY(map, chip, adr, 1);
@@ -1343,7 +1352,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
1343 if (size % map_bankwidth(map)) 1352 if (size % map_bankwidth(map))
1344 size -= size % map_bankwidth(map); 1353 size -= size % map_bankwidth(map);
1345 1354
1346 ret = do_write_buffer(map, &cfi->chips[chipnum], 1355 ret = do_write_buffer(map, &cfi->chips[chipnum],
1347 ofs, buf, size); 1356 ofs, buf, size);
1348 if (ret) 1357 if (ret)
1349 return ret; 1358 return ret;
@@ -1354,7 +1363,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
1354 len -= size; 1363 len -= size;
1355 1364
1356 if (ofs >> cfi->chipshift) { 1365 if (ofs >> cfi->chipshift) {
1357 chipnum ++; 1366 chipnum ++;
1358 ofs = 0; 1367 ofs = 0;
1359 if (chipnum == cfi->numchips) 1368 if (chipnum == cfi->numchips)
1360 return 0; 1369 return 0;
@@ -1571,7 +1580,7 @@ int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
1571 1580
1572 instr->state = MTD_ERASE_DONE; 1581 instr->state = MTD_ERASE_DONE;
1573 mtd_erase_callback(instr); 1582 mtd_erase_callback(instr);
1574 1583
1575 return 0; 1584 return 0;
1576} 1585}
1577 1586
@@ -1594,7 +1603,7 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
1594 1603
1595 instr->state = MTD_ERASE_DONE; 1604 instr->state = MTD_ERASE_DONE;
1596 mtd_erase_callback(instr); 1605 mtd_erase_callback(instr);
1597 1606
1598 return 0; 1607 return 0;
1599} 1608}
1600 1609
@@ -1621,7 +1630,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1621 case FL_JEDEC_QUERY: 1630 case FL_JEDEC_QUERY:
1622 chip->oldstate = chip->state; 1631 chip->oldstate = chip->state;
1623 chip->state = FL_SYNCING; 1632 chip->state = FL_SYNCING;
1624 /* No need to wake_up() on this state change - 1633 /* No need to wake_up() on this state change -
1625 * as the whole point is that nobody can do anything 1634 * as the whole point is that nobody can do anything
1626 * with the chip now anyway. 1635 * with the chip now anyway.
1627 */ 1636 */
@@ -1632,13 +1641,13 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1632 default: 1641 default:
1633 /* Not an idle state */ 1642 /* Not an idle state */
1634 add_wait_queue(&chip->wq, &wait); 1643 add_wait_queue(&chip->wq, &wait);
1635 1644
1636 spin_unlock(chip->mutex); 1645 spin_unlock(chip->mutex);
1637 1646
1638 schedule(); 1647 schedule();
1639 1648
1640 remove_wait_queue(&chip->wq, &wait); 1649 remove_wait_queue(&chip->wq, &wait);
1641 1650
1642 goto retry; 1651 goto retry;
1643 } 1652 }
1644 } 1653 }
@@ -1649,7 +1658,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
1649 chip = &cfi->chips[i]; 1658 chip = &cfi->chips[i];
1650 1659
1651 spin_lock(chip->mutex); 1660 spin_lock(chip->mutex);
1652 1661
1653 if (chip->state == FL_SYNCING) { 1662 if (chip->state == FL_SYNCING) {
1654 chip->state = chip->oldstate; 1663 chip->state = chip->oldstate;
1655 wake_up(&chip->wq); 1664 wake_up(&chip->wq);
@@ -1679,7 +1688,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1679 case FL_JEDEC_QUERY: 1688 case FL_JEDEC_QUERY:
1680 chip->oldstate = chip->state; 1689 chip->oldstate = chip->state;
1681 chip->state = FL_PM_SUSPENDED; 1690 chip->state = FL_PM_SUSPENDED;
1682 /* No need to wake_up() on this state change - 1691 /* No need to wake_up() on this state change -
1683 * as the whole point is that nobody can do anything 1692 * as the whole point is that nobody can do anything
1684 * with the chip now anyway. 1693 * with the chip now anyway.
1685 */ 1694 */
@@ -1700,7 +1709,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1700 chip = &cfi->chips[i]; 1709 chip = &cfi->chips[i];
1701 1710
1702 spin_lock(chip->mutex); 1711 spin_lock(chip->mutex);
1703 1712
1704 if (chip->state == FL_PM_SUSPENDED) { 1713 if (chip->state == FL_PM_SUSPENDED) {
1705 chip->state = chip->oldstate; 1714 chip->state = chip->oldstate;
1706 wake_up(&chip->wq); 1715 wake_up(&chip->wq);
@@ -1708,7 +1717,7 @@ static int cfi_amdstd_suspend(struct mtd_info *mtd)
1708 spin_unlock(chip->mutex); 1717 spin_unlock(chip->mutex);
1709 } 1718 }
1710 } 1719 }
1711 1720
1712 return ret; 1721 return ret;
1713} 1722}
1714 1723
@@ -1721,11 +1730,11 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
1721 struct flchip *chip; 1730 struct flchip *chip;
1722 1731
1723 for (i=0; i<cfi->numchips; i++) { 1732 for (i=0; i<cfi->numchips; i++) {
1724 1733
1725 chip = &cfi->chips[i]; 1734 chip = &cfi->chips[i];
1726 1735
1727 spin_lock(chip->mutex); 1736 spin_lock(chip->mutex);
1728 1737
1729 if (chip->state == FL_PM_SUSPENDED) { 1738 if (chip->state == FL_PM_SUSPENDED) {
1730 chip->state = FL_READY; 1739 chip->state = FL_READY;
1731 map_write(map, CMD(0xF0), chip->start); 1740 map_write(map, CMD(0xF0), chip->start);
@@ -1742,6 +1751,7 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
1742{ 1751{
1743 struct map_info *map = mtd->priv; 1752 struct map_info *map = mtd->priv;
1744 struct cfi_private *cfi = map->fldrv_priv; 1753 struct cfi_private *cfi = map->fldrv_priv;
1754
1745 kfree(cfi->cmdset_priv); 1755 kfree(cfi->cmdset_priv);
1746 kfree(cfi->cfiq); 1756 kfree(cfi->cfiq);
1747 kfree(cfi); 1757 kfree(cfi);
diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c
index c894f8801578..0807c1c91e55 100644
--- a/drivers/mtd/chips/cfi_cmdset_0020.c
+++ b/drivers/mtd/chips/cfi_cmdset_0020.c
@@ -4,8 +4,8 @@
4 * 4 *
5 * (C) 2000 Red Hat. GPL'd 5 * (C) 2000 Red Hat. GPL'd
6 * 6 *
7 * $Id: cfi_cmdset_0020.c,v 1.19 2005/07/13 15:52:45 dwmw2 Exp $ 7 * $Id: cfi_cmdset_0020.c,v 1.22 2005/11/07 11:14:22 gleixner Exp $
8 * 8 *
9 * 10/10/2000 Nicolas Pitre <nico@cam.org> 9 * 10/10/2000 Nicolas Pitre <nico@cam.org>
10 * - completely revamped method functions so they are aware and 10 * - completely revamped method functions so they are aware and
11 * independent of the flash geometry (buswidth, interleave, etc.) 11 * independent of the flash geometry (buswidth, interleave, etc.)
@@ -20,7 +20,6 @@
20 * - Plugged memory leak in cfi_staa_writev(). 20 * - Plugged memory leak in cfi_staa_writev().
21 */ 21 */
22 22
23#include <linux/version.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/types.h> 24#include <linux/types.h>
26#include <linux/kernel.h> 25#include <linux/kernel.h>
@@ -81,17 +80,17 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
81 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported"); 80 printk(" - Page-mode read: %s\n", extp->FeatureSupport&128?"supported":"unsupported");
82 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported"); 81 printk(" - Synchronous read: %s\n", extp->FeatureSupport&256?"supported":"unsupported");
83 for (i=9; i<32; i++) { 82 for (i=9; i<32; i++) {
84 if (extp->FeatureSupport & (1<<i)) 83 if (extp->FeatureSupport & (1<<i))
85 printk(" - Unknown Bit %X: supported\n", i); 84 printk(" - Unknown Bit %X: supported\n", i);
86 } 85 }
87 86
88 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport); 87 printk(" Supported functions after Suspend: %2.2X\n", extp->SuspendCmdSupport);
89 printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported"); 88 printk(" - Program after Erase Suspend: %s\n", extp->SuspendCmdSupport&1?"supported":"unsupported");
90 for (i=1; i<8; i++) { 89 for (i=1; i<8; i++) {
91 if (extp->SuspendCmdSupport & (1<<i)) 90 if (extp->SuspendCmdSupport & (1<<i))
92 printk(" - Unknown Bit %X: supported\n", i); 91 printk(" - Unknown Bit %X: supported\n", i);
93 } 92 }
94 93
95 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask); 94 printk(" Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
96 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no"); 95 printk(" - Lock Bit Active: %s\n", extp->BlkStatusRegMask&1?"yes":"no");
97 printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no"); 96 printk(" - Valid Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
@@ -99,11 +98,11 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp)
99 if (extp->BlkStatusRegMask & (1<<i)) 98 if (extp->BlkStatusRegMask & (1<<i))
100 printk(" - Unknown Bit %X Active: yes\n",i); 99 printk(" - Unknown Bit %X Active: yes\n",i);
101 } 100 }
102 101
103 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 102 printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
104 extp->VccOptimal >> 8, extp->VccOptimal & 0xf); 103 extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
105 if (extp->VppOptimal) 104 if (extp->VppOptimal)
106 printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n", 105 printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
107 extp->VppOptimal >> 8, extp->VppOptimal & 0xf); 106 extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
108} 107}
109#endif 108#endif
@@ -121,7 +120,7 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
121 int i; 120 int i;
122 121
123 if (cfi->cfi_mode) { 122 if (cfi->cfi_mode) {
124 /* 123 /*
125 * It's a real CFI chip, not one for which the probe 124 * It's a real CFI chip, not one for which the probe
126 * routine faked a CFI structure. So we read the feature 125 * routine faked a CFI structure. So we read the feature
127 * table from it. 126 * table from it.
@@ -133,24 +132,33 @@ struct mtd_info *cfi_cmdset_0020(struct map_info *map, int primary)
133 if (!extp) 132 if (!extp)
134 return NULL; 133 return NULL;
135 134
135 if (extp->MajorVersion != '1' ||
136 (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
137 printk(KERN_ERR " Unknown ST Microelectronics"
138 " Extended Query version %c.%c.\n",
139 extp->MajorVersion, extp->MinorVersion);
140 kfree(extp);
141 return NULL;
142 }
143
136 /* Do some byteswapping if necessary */ 144 /* Do some byteswapping if necessary */
137 extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport); 145 extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
138 extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask); 146 extp->BlkStatusRegMask = cfi32_to_cpu(extp->BlkStatusRegMask);
139 147
140#ifdef DEBUG_CFI_FEATURES 148#ifdef DEBUG_CFI_FEATURES
141 /* Tell the user about it in lots of lovely detail */ 149 /* Tell the user about it in lots of lovely detail */
142 cfi_tell_features(extp); 150 cfi_tell_features(extp);
143#endif 151#endif
144 152
145 /* Install our own private info structure */ 153 /* Install our own private info structure */
146 cfi->cmdset_priv = extp; 154 cfi->cmdset_priv = extp;
147 } 155 }
148 156
149 for (i=0; i< cfi->numchips; i++) { 157 for (i=0; i< cfi->numchips; i++) {
150 cfi->chips[i].word_write_time = 128; 158 cfi->chips[i].word_write_time = 128;
151 cfi->chips[i].buffer_write_time = 128; 159 cfi->chips[i].buffer_write_time = 128;
152 cfi->chips[i].erase_time = 1024; 160 cfi->chips[i].erase_time = 1024;
153 } 161 }
154 162
155 return cfi_staa_setup(map); 163 return cfi_staa_setup(map);
156} 164}
@@ -178,15 +186,15 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
178 mtd->size = devsize * cfi->numchips; 186 mtd->size = devsize * cfi->numchips;
179 187
180 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; 188 mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
181 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) 189 mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
182 * mtd->numeraseregions, GFP_KERNEL); 190 * mtd->numeraseregions, GFP_KERNEL);
183 if (!mtd->eraseregions) { 191 if (!mtd->eraseregions) {
184 printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n"); 192 printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
185 kfree(cfi->cmdset_priv); 193 kfree(cfi->cmdset_priv);
186 kfree(mtd); 194 kfree(mtd);
187 return NULL; 195 return NULL;
188 } 196 }
189 197
190 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 198 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
191 unsigned long ernum, ersize; 199 unsigned long ernum, ersize;
192 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave; 200 ersize = ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interleave;
@@ -219,7 +227,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map)
219 mtd->eraseregions[i].numblocks); 227 mtd->eraseregions[i].numblocks);
220 } 228 }
221 229
222 /* Also select the correct geometry setup too */ 230 /* Also select the correct geometry setup too */
223 mtd->erase = cfi_staa_erase_varsize; 231 mtd->erase = cfi_staa_erase_varsize;
224 mtd->read = cfi_staa_read; 232 mtd->read = cfi_staa_read;
225 mtd->write = cfi_staa_write_buffers; 233 mtd->write = cfi_staa_write_buffers;
@@ -250,8 +258,8 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
250 258
251 adr += chip->start; 259 adr += chip->start;
252 260
253 /* Ensure cmd read/writes are aligned. */ 261 /* Ensure cmd read/writes are aligned. */
254 cmd_addr = adr & ~(map_bankwidth(map)-1); 262 cmd_addr = adr & ~(map_bankwidth(map)-1);
255 263
256 /* Let's determine this according to the interleave only once */ 264 /* Let's determine this according to the interleave only once */
257 status_OK = CMD(0x80); 265 status_OK = CMD(0x80);
@@ -267,7 +275,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
267 case FL_ERASING: 275 case FL_ERASING:
268 if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)) 276 if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
269 goto sleep; /* We don't support erase suspend */ 277 goto sleep; /* We don't support erase suspend */
270 278
271 map_write (map, CMD(0xb0), cmd_addr); 279 map_write (map, CMD(0xb0), cmd_addr);
272 /* If the flash has finished erasing, then 'erase suspend' 280 /* If the flash has finished erasing, then 'erase suspend'
273 * appears to make some (28F320) flash devices switch to 281 * appears to make some (28F320) flash devices switch to
@@ -282,7 +290,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
282 status = map_read(map, cmd_addr); 290 status = map_read(map, cmd_addr);
283 if (map_word_andequal(map, status, status_OK, status_OK)) 291 if (map_word_andequal(map, status, status_OK, status_OK))
284 break; 292 break;
285 293
286 if (time_after(jiffies, timeo)) { 294 if (time_after(jiffies, timeo)) {
287 /* Urgh */ 295 /* Urgh */
288 map_write(map, CMD(0xd0), cmd_addr); 296 map_write(map, CMD(0xd0), cmd_addr);
@@ -294,17 +302,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
294 "suspended: status = 0x%lx\n", status.x[0]); 302 "suspended: status = 0x%lx\n", status.x[0]);
295 return -EIO; 303 return -EIO;
296 } 304 }
297 305
298 spin_unlock_bh(chip->mutex); 306 spin_unlock_bh(chip->mutex);
299 cfi_udelay(1); 307 cfi_udelay(1);
300 spin_lock_bh(chip->mutex); 308 spin_lock_bh(chip->mutex);
301 } 309 }
302 310
303 suspended = 1; 311 suspended = 1;
304 map_write(map, CMD(0xff), cmd_addr); 312 map_write(map, CMD(0xff), cmd_addr);
305 chip->state = FL_READY; 313 chip->state = FL_READY;
306 break; 314 break;
307 315
308#if 0 316#if 0
309 case FL_WRITING: 317 case FL_WRITING:
310 /* Not quite yet */ 318 /* Not quite yet */
@@ -325,7 +333,7 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
325 chip->state = FL_READY; 333 chip->state = FL_READY;
326 break; 334 break;
327 } 335 }
328 336
329 /* Urgh. Chip not yet ready to talk to us. */ 337 /* Urgh. Chip not yet ready to talk to us. */
330 if (time_after(jiffies, timeo)) { 338 if (time_after(jiffies, timeo)) {
331 spin_unlock_bh(chip->mutex); 339 spin_unlock_bh(chip->mutex);
@@ -355,17 +363,17 @@ static inline int do_read_onechip(struct map_info *map, struct flchip *chip, lof
355 363
356 if (suspended) { 364 if (suspended) {
357 chip->state = chip->oldstate; 365 chip->state = chip->oldstate;
358 /* What if one interleaved chip has finished and the 366 /* What if one interleaved chip has finished and the
359 other hasn't? The old code would leave the finished 367 other hasn't? The old code would leave the finished
360 one in READY mode. That's bad, and caused -EROFS 368 one in READY mode. That's bad, and caused -EROFS
361 errors to be returned from do_erase_oneblock because 369 errors to be returned from do_erase_oneblock because
362 that's the only bit it checked for at the time. 370 that's the only bit it checked for at the time.
363 As the state machine appears to explicitly allow 371 As the state machine appears to explicitly allow
364 sending the 0x70 (Read Status) command to an erasing 372 sending the 0x70 (Read Status) command to an erasing
365 chip and expecting it to be ignored, that's what we 373 chip and expecting it to be ignored, that's what we
366 do. */ 374 do. */
367 map_write(map, CMD(0xd0), cmd_addr); 375 map_write(map, CMD(0xd0), cmd_addr);
368 map_write(map, CMD(0x70), cmd_addr); 376 map_write(map, CMD(0x70), cmd_addr);
369 } 377 }
370 378
371 wake_up(&chip->wq); 379 wake_up(&chip->wq);
@@ -405,14 +413,14 @@ static int cfi_staa_read (struct mtd_info *mtd, loff_t from, size_t len, size_t
405 *retlen += thislen; 413 *retlen += thislen;
406 len -= thislen; 414 len -= thislen;
407 buf += thislen; 415 buf += thislen;
408 416
409 ofs = 0; 417 ofs = 0;
410 chipnum++; 418 chipnum++;
411 } 419 }
412 return ret; 420 return ret;
413} 421}
414 422
415static inline int do_write_buffer(struct map_info *map, struct flchip *chip, 423static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
416 unsigned long adr, const u_char *buf, int len) 424 unsigned long adr, const u_char *buf, int len)
417{ 425{
418 struct cfi_private *cfi = map->fldrv_priv; 426 struct cfi_private *cfi = map->fldrv_priv;
@@ -420,7 +428,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
420 unsigned long cmd_adr, timeo; 428 unsigned long cmd_adr, timeo;
421 DECLARE_WAITQUEUE(wait, current); 429 DECLARE_WAITQUEUE(wait, current);
422 int wbufsize, z; 430 int wbufsize, z;
423 431
424 /* M58LW064A requires bus alignment for buffer wriets -- saw */ 432 /* M58LW064A requires bus alignment for buffer wriets -- saw */
425 if (adr & (map_bankwidth(map)-1)) 433 if (adr & (map_bankwidth(map)-1))
426 return -EINVAL; 434 return -EINVAL;
@@ -428,10 +436,10 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
428 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize; 436 wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
429 adr += chip->start; 437 adr += chip->start;
430 cmd_adr = adr & ~(wbufsize-1); 438 cmd_adr = adr & ~(wbufsize-1);
431 439
432 /* Let's determine this according to the interleave only once */ 440 /* Let's determine this according to the interleave only once */
433 status_OK = CMD(0x80); 441 status_OK = CMD(0x80);
434 442
435 timeo = jiffies + HZ; 443 timeo = jiffies + HZ;
436 retry: 444 retry:
437 445
@@ -439,7 +447,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
439 printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state); 447 printk("%s: chip->state[%d]\n", __FUNCTION__, chip->state);
440#endif 448#endif
441 spin_lock_bh(chip->mutex); 449 spin_lock_bh(chip->mutex);
442 450
443 /* Check that the chip's ready to talk to us. 451 /* Check that the chip's ready to talk to us.
444 * Later, we can actually think about interrupting it 452 * Later, we can actually think about interrupting it
445 * if it's in FL_ERASING state. 453 * if it's in FL_ERASING state.
@@ -448,7 +456,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
448 switch (chip->state) { 456 switch (chip->state) {
449 case FL_READY: 457 case FL_READY:
450 break; 458 break;
451 459
452 case FL_CFI_QUERY: 460 case FL_CFI_QUERY:
453 case FL_JEDEC_QUERY: 461 case FL_JEDEC_QUERY:
454 map_write(map, CMD(0x70), cmd_adr); 462 map_write(map, CMD(0x70), cmd_adr);
@@ -513,7 +521,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
513 521
514 /* Write length of data to come */ 522 /* Write length of data to come */
515 map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr ); 523 map_write(map, CMD(len/map_bankwidth(map)-1), cmd_adr );
516 524
517 /* Write data */ 525 /* Write data */
518 for (z = 0; z < len; 526 for (z = 0; z < len;
519 z += map_bankwidth(map), buf += map_bankwidth(map)) { 527 z += map_bankwidth(map), buf += map_bankwidth(map)) {
@@ -560,7 +568,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
560 printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n"); 568 printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
561 return -EIO; 569 return -EIO;
562 } 570 }
563 571
564 /* Latency issues. Drop the lock, wait a while and retry */ 572 /* Latency issues. Drop the lock, wait a while and retry */
565 spin_unlock_bh(chip->mutex); 573 spin_unlock_bh(chip->mutex);
566 cfi_udelay(1); 574 cfi_udelay(1);
@@ -572,9 +580,9 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
572 if (!chip->buffer_write_time) 580 if (!chip->buffer_write_time)
573 chip->buffer_write_time++; 581 chip->buffer_write_time++;
574 } 582 }
575 if (z > 1) 583 if (z > 1)
576 chip->buffer_write_time++; 584 chip->buffer_write_time++;
577 585
578 /* Done and happy. */ 586 /* Done and happy. */
579 DISABLE_VPP(map); 587 DISABLE_VPP(map);
580 chip->state = FL_STATUS; 588 chip->state = FL_STATUS;
@@ -598,7 +606,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
598 return 0; 606 return 0;
599} 607}
600 608
601static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to, 609static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
602 size_t len, size_t *retlen, const u_char *buf) 610 size_t len, size_t *retlen, const u_char *buf)
603{ 611{
604 struct map_info *map = mtd->priv; 612 struct map_info *map = mtd->priv;
@@ -620,7 +628,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
620 printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize); 628 printk("%s: chipnum[%x] wbufsize[%x]\n", __FUNCTION__, chipnum, wbufsize);
621 printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len); 629 printk("%s: ofs[%x] len[%x]\n", __FUNCTION__, ofs, len);
622#endif 630#endif
623 631
624 /* Write buffer is worth it only if more than one word to write... */ 632 /* Write buffer is worth it only if more than one word to write... */
625 while (len > 0) { 633 while (len > 0) {
626 /* We must not cross write block boundaries */ 634 /* We must not cross write block boundaries */
@@ -629,7 +637,7 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
629 if (size > len) 637 if (size > len)
630 size = len; 638 size = len;
631 639
632 ret = do_write_buffer(map, &cfi->chips[chipnum], 640 ret = do_write_buffer(map, &cfi->chips[chipnum],
633 ofs, buf, size); 641 ofs, buf, size);
634 if (ret) 642 if (ret)
635 return ret; 643 return ret;
@@ -640,13 +648,13 @@ static int cfi_staa_write_buffers (struct mtd_info *mtd, loff_t to,
640 len -= size; 648 len -= size;
641 649
642 if (ofs >> cfi->chipshift) { 650 if (ofs >> cfi->chipshift) {
643 chipnum ++; 651 chipnum ++;
644 ofs = 0; 652 ofs = 0;
645 if (chipnum == cfi->numchips) 653 if (chipnum == cfi->numchips)
646 return 0; 654 return 0;
647 } 655 }
648 } 656 }
649 657
650 return 0; 658 return 0;
651} 659}
652 660
@@ -756,7 +764,7 @@ retry:
756 status = map_read(map, adr); 764 status = map_read(map, adr);
757 if (map_word_andequal(map, status, status_OK, status_OK)) 765 if (map_word_andequal(map, status, status_OK, status_OK))
758 break; 766 break;
759 767
760 /* Urgh. Chip not yet ready to talk to us. */ 768 /* Urgh. Chip not yet ready to talk to us. */
761 if (time_after(jiffies, timeo)) { 769 if (time_after(jiffies, timeo)) {
762 spin_unlock_bh(chip->mutex); 770 spin_unlock_bh(chip->mutex);
@@ -789,7 +797,7 @@ retry:
789 map_write(map, CMD(0x20), adr); 797 map_write(map, CMD(0x20), adr);
790 map_write(map, CMD(0xD0), adr); 798 map_write(map, CMD(0xD0), adr);
791 chip->state = FL_ERASING; 799 chip->state = FL_ERASING;
792 800
793 spin_unlock_bh(chip->mutex); 801 spin_unlock_bh(chip->mutex);
794 msleep(1000); 802 msleep(1000);
795 spin_lock_bh(chip->mutex); 803 spin_lock_bh(chip->mutex);
@@ -814,7 +822,7 @@ retry:
814 status = map_read(map, adr); 822 status = map_read(map, adr);
815 if (map_word_andequal(map, status, status_OK, status_OK)) 823 if (map_word_andequal(map, status, status_OK, status_OK))
816 break; 824 break;
817 825
818 /* OK Still waiting */ 826 /* OK Still waiting */
819 if (time_after(jiffies, timeo)) { 827 if (time_after(jiffies, timeo)) {
820 map_write(map, CMD(0x70), adr); 828 map_write(map, CMD(0x70), adr);
@@ -824,13 +832,13 @@ retry:
824 spin_unlock_bh(chip->mutex); 832 spin_unlock_bh(chip->mutex);
825 return -EIO; 833 return -EIO;
826 } 834 }
827 835
828 /* Latency issues. Drop the lock, wait a while and retry */ 836 /* Latency issues. Drop the lock, wait a while and retry */
829 spin_unlock_bh(chip->mutex); 837 spin_unlock_bh(chip->mutex);
830 cfi_udelay(1); 838 cfi_udelay(1);
831 spin_lock_bh(chip->mutex); 839 spin_lock_bh(chip->mutex);
832 } 840 }
833 841
834 DISABLE_VPP(map); 842 DISABLE_VPP(map);
835 ret = 0; 843 ret = 0;
836 844
@@ -855,7 +863,7 @@ retry:
855 /* Reset the error bits */ 863 /* Reset the error bits */
856 map_write(map, CMD(0x50), adr); 864 map_write(map, CMD(0x50), adr);
857 map_write(map, CMD(0x70), adr); 865 map_write(map, CMD(0x70), adr);
858 866
859 if ((chipstatus & 0x30) == 0x30) { 867 if ((chipstatus & 0x30) == 0x30) {
860 printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus); 868 printk(KERN_NOTICE "Chip reports improper command sequence: status 0x%x\n", chipstatus);
861 ret = -EIO; 869 ret = -EIO;
@@ -904,17 +912,17 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
904 912
905 i = 0; 913 i = 0;
906 914
907 /* Skip all erase regions which are ended before the start of 915 /* Skip all erase regions which are ended before the start of
908 the requested erase. Actually, to save on the calculations, 916 the requested erase. Actually, to save on the calculations,
909 we skip to the first erase region which starts after the 917 we skip to the first erase region which starts after the
910 start of the requested erase, and then go back one. 918 start of the requested erase, and then go back one.
911 */ 919 */
912 920
913 while (i < mtd->numeraseregions && instr->addr >= regions[i].offset) 921 while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
914 i++; 922 i++;
915 i--; 923 i--;
916 924
917 /* OK, now i is pointing at the erase region in which this 925 /* OK, now i is pointing at the erase region in which this
918 erase request starts. Check the start of the requested 926 erase request starts. Check the start of the requested
919 erase range is aligned with the erase size which is in 927 erase range is aligned with the erase size which is in
920 effect here. 928 effect here.
@@ -937,7 +945,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
937 the address actually falls 945 the address actually falls
938 */ 946 */
939 i--; 947 i--;
940 948
941 if ((instr->addr + instr->len) & (regions[i].erasesize-1)) 949 if ((instr->addr + instr->len) & (regions[i].erasesize-1))
942 return -EINVAL; 950 return -EINVAL;
943 951
@@ -949,7 +957,7 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
949 957
950 while(len) { 958 while(len) {
951 ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr); 959 ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
952 960
953 if (ret) 961 if (ret)
954 return ret; 962 return ret;
955 963
@@ -962,15 +970,15 @@ int cfi_staa_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
962 if (adr >> cfi->chipshift) { 970 if (adr >> cfi->chipshift) {
963 adr = 0; 971 adr = 0;
964 chipnum++; 972 chipnum++;
965 973
966 if (chipnum >= cfi->numchips) 974 if (chipnum >= cfi->numchips)
967 break; 975 break;
968 } 976 }
969 } 977 }
970 978
971 instr->state = MTD_ERASE_DONE; 979 instr->state = MTD_ERASE_DONE;
972 mtd_erase_callback(instr); 980 mtd_erase_callback(instr);
973 981
974 return 0; 982 return 0;
975} 983}
976 984
@@ -996,7 +1004,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
996 case FL_JEDEC_QUERY: 1004 case FL_JEDEC_QUERY:
997 chip->oldstate = chip->state; 1005 chip->oldstate = chip->state;
998 chip->state = FL_SYNCING; 1006 chip->state = FL_SYNCING;
999 /* No need to wake_up() on this state change - 1007 /* No need to wake_up() on this state change -
1000 * as the whole point is that nobody can do anything 1008 * as the whole point is that nobody can do anything
1001 * with the chip now anyway. 1009 * with the chip now anyway.
1002 */ 1010 */
@@ -1007,11 +1015,11 @@ static void cfi_staa_sync (struct mtd_info *mtd)
1007 default: 1015 default:
1008 /* Not an idle state */ 1016 /* Not an idle state */
1009 add_wait_queue(&chip->wq, &wait); 1017 add_wait_queue(&chip->wq, &wait);
1010 1018
1011 spin_unlock_bh(chip->mutex); 1019 spin_unlock_bh(chip->mutex);
1012 schedule(); 1020 schedule();
1013 remove_wait_queue(&chip->wq, &wait); 1021 remove_wait_queue(&chip->wq, &wait);
1014 1022
1015 goto retry; 1023 goto retry;
1016 } 1024 }
1017 } 1025 }
@@ -1022,7 +1030,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
1022 chip = &cfi->chips[i]; 1030 chip = &cfi->chips[i];
1023 1031
1024 spin_lock_bh(chip->mutex); 1032 spin_lock_bh(chip->mutex);
1025 1033
1026 if (chip->state == FL_SYNCING) { 1034 if (chip->state == FL_SYNCING) {
1027 chip->state = chip->oldstate; 1035 chip->state = chip->oldstate;
1028 wake_up(&chip->wq); 1036 wake_up(&chip->wq);
@@ -1057,9 +1065,9 @@ retry:
1057 1065
1058 case FL_STATUS: 1066 case FL_STATUS:
1059 status = map_read(map, adr); 1067 status = map_read(map, adr);
1060 if (map_word_andequal(map, status, status_OK, status_OK)) 1068 if (map_word_andequal(map, status, status_OK, status_OK))
1061 break; 1069 break;
1062 1070
1063 /* Urgh. Chip not yet ready to talk to us. */ 1071 /* Urgh. Chip not yet ready to talk to us. */
1064 if (time_after(jiffies, timeo)) { 1072 if (time_after(jiffies, timeo)) {
1065 spin_unlock_bh(chip->mutex); 1073 spin_unlock_bh(chip->mutex);
@@ -1088,7 +1096,7 @@ retry:
1088 map_write(map, CMD(0x60), adr); 1096 map_write(map, CMD(0x60), adr);
1089 map_write(map, CMD(0x01), adr); 1097 map_write(map, CMD(0x01), adr);
1090 chip->state = FL_LOCKING; 1098 chip->state = FL_LOCKING;
1091 1099
1092 spin_unlock_bh(chip->mutex); 1100 spin_unlock_bh(chip->mutex);
1093 msleep(1000); 1101 msleep(1000);
1094 spin_lock_bh(chip->mutex); 1102 spin_lock_bh(chip->mutex);
@@ -1102,7 +1110,7 @@ retry:
1102 status = map_read(map, adr); 1110 status = map_read(map, adr);
1103 if (map_word_andequal(map, status, status_OK, status_OK)) 1111 if (map_word_andequal(map, status, status_OK, status_OK))
1104 break; 1112 break;
1105 1113
1106 /* OK Still waiting */ 1114 /* OK Still waiting */
1107 if (time_after(jiffies, timeo)) { 1115 if (time_after(jiffies, timeo)) {
1108 map_write(map, CMD(0x70), adr); 1116 map_write(map, CMD(0x70), adr);
@@ -1112,13 +1120,13 @@ retry:
1112 spin_unlock_bh(chip->mutex); 1120 spin_unlock_bh(chip->mutex);
1113 return -EIO; 1121 return -EIO;
1114 } 1122 }
1115 1123
1116 /* Latency issues. Drop the lock, wait a while and retry */ 1124 /* Latency issues. Drop the lock, wait a while and retry */
1117 spin_unlock_bh(chip->mutex); 1125 spin_unlock_bh(chip->mutex);
1118 cfi_udelay(1); 1126 cfi_udelay(1);
1119 spin_lock_bh(chip->mutex); 1127 spin_lock_bh(chip->mutex);
1120 } 1128 }
1121 1129
1122 /* Done and happy. */ 1130 /* Done and happy. */
1123 chip->state = FL_STATUS; 1131 chip->state = FL_STATUS;
1124 DISABLE_VPP(map); 1132 DISABLE_VPP(map);
@@ -1162,8 +1170,8 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1162 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); 1170 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
1163 printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); 1171 printk("after lock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
1164 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); 1172 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
1165#endif 1173#endif
1166 1174
1167 if (ret) 1175 if (ret)
1168 return ret; 1176 return ret;
1169 1177
@@ -1173,7 +1181,7 @@ static int cfi_staa_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
1173 if (adr >> cfi->chipshift) { 1181 if (adr >> cfi->chipshift) {
1174 adr = 0; 1182 adr = 0;
1175 chipnum++; 1183 chipnum++;
1176 1184
1177 if (chipnum >= cfi->numchips) 1185 if (chipnum >= cfi->numchips)
1178 break; 1186 break;
1179 } 1187 }
@@ -1208,7 +1216,7 @@ retry:
1208 status = map_read(map, adr); 1216 status = map_read(map, adr);
1209 if (map_word_andequal(map, status, status_OK, status_OK)) 1217 if (map_word_andequal(map, status, status_OK, status_OK))
1210 break; 1218 break;
1211 1219
1212 /* Urgh. Chip not yet ready to talk to us. */ 1220 /* Urgh. Chip not yet ready to talk to us. */
1213 if (time_after(jiffies, timeo)) { 1221 if (time_after(jiffies, timeo)) {
1214 spin_unlock_bh(chip->mutex); 1222 spin_unlock_bh(chip->mutex);
@@ -1237,7 +1245,7 @@ retry:
1237 map_write(map, CMD(0x60), adr); 1245 map_write(map, CMD(0x60), adr);
1238 map_write(map, CMD(0xD0), adr); 1246 map_write(map, CMD(0xD0), adr);
1239 chip->state = FL_UNLOCKING; 1247 chip->state = FL_UNLOCKING;
1240 1248
1241 spin_unlock_bh(chip->mutex); 1249 spin_unlock_bh(chip->mutex);
1242 msleep(1000); 1250 msleep(1000);
1243 spin_lock_bh(chip->mutex); 1251 spin_lock_bh(chip->mutex);
@@ -1251,7 +1259,7 @@ retry:
1251 status = map_read(map, adr); 1259 status = map_read(map, adr);
1252 if (map_word_andequal(map, status, status_OK, status_OK)) 1260 if (map_word_andequal(map, status, status_OK, status_OK))
1253 break; 1261 break;
1254 1262
1255 /* OK Still waiting */ 1263 /* OK Still waiting */
1256 if (time_after(jiffies, timeo)) { 1264 if (time_after(jiffies, timeo)) {
1257 map_write(map, CMD(0x70), adr); 1265 map_write(map, CMD(0x70), adr);
@@ -1261,13 +1269,13 @@ retry:
1261 spin_unlock_bh(chip->mutex); 1269 spin_unlock_bh(chip->mutex);
1262 return -EIO; 1270 return -EIO;
1263 } 1271 }
1264 1272
1265 /* Latency issues. Drop the unlock, wait a while and retry */ 1273 /* Latency issues. Drop the unlock, wait a while and retry */
1266 spin_unlock_bh(chip->mutex); 1274 spin_unlock_bh(chip->mutex);
1267 cfi_udelay(1); 1275 cfi_udelay(1);
1268 spin_lock_bh(chip->mutex); 1276 spin_lock_bh(chip->mutex);
1269 } 1277 }
1270 1278
1271 /* Done and happy. */ 1279 /* Done and happy. */
1272 chip->state = FL_STATUS; 1280 chip->state = FL_STATUS;
1273 DISABLE_VPP(map); 1281 DISABLE_VPP(map);
@@ -1292,7 +1300,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1292 { 1300 {
1293 unsigned long temp_adr = adr; 1301 unsigned long temp_adr = adr;
1294 unsigned long temp_len = len; 1302 unsigned long temp_len = len;
1295 1303
1296 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL); 1304 cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
1297 while (temp_len) { 1305 while (temp_len) {
1298 printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor))); 1306 printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
@@ -1310,7 +1318,7 @@ static int cfi_staa_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1310 printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor))); 1318 printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
1311 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL); 1319 cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
1312#endif 1320#endif
1313 1321
1314 return ret; 1322 return ret;
1315} 1323}
1316 1324
@@ -1334,7 +1342,7 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
1334 case FL_JEDEC_QUERY: 1342 case FL_JEDEC_QUERY:
1335 chip->oldstate = chip->state; 1343 chip->oldstate = chip->state;
1336 chip->state = FL_PM_SUSPENDED; 1344 chip->state = FL_PM_SUSPENDED;
1337 /* No need to wake_up() on this state change - 1345 /* No need to wake_up() on this state change -
1338 * as the whole point is that nobody can do anything 1346 * as the whole point is that nobody can do anything
1339 * with the chip now anyway. 1347 * with the chip now anyway.
1340 */ 1348 */
@@ -1353,9 +1361,9 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
1353 if (ret) { 1361 if (ret) {
1354 for (i--; i >=0; i--) { 1362 for (i--; i >=0; i--) {
1355 chip = &cfi->chips[i]; 1363 chip = &cfi->chips[i];
1356 1364
1357 spin_lock_bh(chip->mutex); 1365 spin_lock_bh(chip->mutex);
1358 1366
1359 if (chip->state == FL_PM_SUSPENDED) { 1367 if (chip->state == FL_PM_SUSPENDED) {
1360 /* No need to force it into a known state here, 1368 /* No need to force it into a known state here,
1361 because we're returning failure, and it didn't 1369 because we're returning failure, and it didn't
@@ -1365,8 +1373,8 @@ static int cfi_staa_suspend(struct mtd_info *mtd)
1365 } 1373 }
1366 spin_unlock_bh(chip->mutex); 1374 spin_unlock_bh(chip->mutex);
1367 } 1375 }
1368 } 1376 }
1369 1377
1370 return ret; 1378 return ret;
1371} 1379}
1372 1380
@@ -1378,11 +1386,11 @@ static void cfi_staa_resume(struct mtd_info *mtd)
1378 struct flchip *chip; 1386 struct flchip *chip;
1379 1387
1380 for (i=0; i<cfi->numchips; i++) { 1388 for (i=0; i<cfi->numchips; i++) {
1381 1389
1382 chip = &cfi->chips[i]; 1390 chip = &cfi->chips[i];
1383 1391
1384 spin_lock_bh(chip->mutex); 1392 spin_lock_bh(chip->mutex);
1385 1393
1386 /* Go to known state. Chip may have been power cycled */ 1394 /* Go to known state. Chip may have been power cycled */
1387 if (chip->state == FL_PM_SUSPENDED) { 1395 if (chip->state == FL_PM_SUSPENDED) {
1388 map_write(map, CMD(0xFF), 0); 1396 map_write(map, CMD(0xFF), 0);
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
index cf750038ce6a..90eb30e06b7c 100644
--- a/drivers/mtd/chips/cfi_probe.c
+++ b/drivers/mtd/chips/cfi_probe.c
@@ -1,7 +1,7 @@
1/* 1/*
2 Common Flash Interface probe code. 2 Common Flash Interface probe code.
3 (C) 2000 Red Hat. GPL'd. 3 (C) 2000 Red Hat. GPL'd.
4 $Id: cfi_probe.c,v 1.83 2004/11/16 18:19:02 nico Exp $ 4 $Id: cfi_probe.c,v 1.84 2005/11/07 11:14:23 gleixner Exp $
5*/ 5*/
6 6
7#include <linux/config.h> 7#include <linux/config.h>
@@ -20,7 +20,7 @@
20#include <linux/mtd/cfi.h> 20#include <linux/mtd/cfi.h>
21#include <linux/mtd/gen_probe.h> 21#include <linux/mtd/gen_probe.h>
22 22
23//#define DEBUG_CFI 23//#define DEBUG_CFI
24 24
25#ifdef DEBUG_CFI 25#ifdef DEBUG_CFI
26static void print_cfi_ident(struct cfi_ident *); 26static void print_cfi_ident(struct cfi_ident *);
@@ -103,7 +103,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
103 unsigned long *chip_map, struct cfi_private *cfi) 103 unsigned long *chip_map, struct cfi_private *cfi)
104{ 104{
105 int i; 105 int i;
106 106
107 if ((base + 0) >= map->size) { 107 if ((base + 0) >= map->size) {
108 printk(KERN_NOTICE 108 printk(KERN_NOTICE
109 "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n", 109 "Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n",
@@ -128,7 +128,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
128 } 128 }
129 129
130 if (!cfi->numchips) { 130 if (!cfi->numchips) {
131 /* This is the first time we're called. Set up the CFI 131 /* This is the first time we're called. Set up the CFI
132 stuff accordingly and return */ 132 stuff accordingly and return */
133 return cfi_chip_setup(map, cfi); 133 return cfi_chip_setup(map, cfi);
134 } 134 }
@@ -138,13 +138,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
138 unsigned long start; 138 unsigned long start;
139 if(!test_bit(i, chip_map)) { 139 if(!test_bit(i, chip_map)) {
140 /* Skip location; no valid chip at this address */ 140 /* Skip location; no valid chip at this address */
141 continue; 141 continue;
142 } 142 }
143 start = i << cfi->chipshift; 143 start = i << cfi->chipshift;
144 /* This chip should be in read mode if it's one 144 /* This chip should be in read mode if it's one
145 we've already touched. */ 145 we've already touched. */
146 if (qry_present(map, start, cfi)) { 146 if (qry_present(map, start, cfi)) {
147 /* Eep. This chip also had the QRY marker. 147 /* Eep. This chip also had the QRY marker.
148 * Is it an alias for the new one? */ 148 * Is it an alias for the new one? */
149 cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); 149 cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL);
150 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); 150 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
@@ -156,13 +156,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
156 map->name, base, start); 156 map->name, base, start);
157 return 0; 157 return 0;
158 } 158 }
159 /* Yes, it's actually got QRY for data. Most 159 /* Yes, it's actually got QRY for data. Most
160 * unfortunate. Stick the new chip in read mode 160 * unfortunate. Stick the new chip in read mode
161 * too and if it's the same, assume it's an alias. */ 161 * too and if it's the same, assume it's an alias. */
162 /* FIXME: Use other modes to do a proper check */ 162 /* FIXME: Use other modes to do a proper check */
163 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 163 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
164 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); 164 cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
165 165
166 if (qry_present(map, base, cfi)) { 166 if (qry_present(map, base, cfi)) {
167 xip_allowed(base, map); 167 xip_allowed(base, map);
168 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", 168 printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
@@ -171,12 +171,12 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
171 } 171 }
172 } 172 }
173 } 173 }
174 174
175 /* OK, if we got to here, then none of the previous chips appear to 175 /* OK, if we got to here, then none of the previous chips appear to
176 be aliases for the current one. */ 176 be aliases for the current one. */
177 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ 177 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
178 cfi->numchips++; 178 cfi->numchips++;
179 179
180 /* Put it back into Read Mode */ 180 /* Put it back into Read Mode */
181 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 181 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
182 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); 182 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
@@ -185,11 +185,11 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
185 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", 185 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
186 map->name, cfi->interleave, cfi->device_type*8, base, 186 map->name, cfi->interleave, cfi->device_type*8, base,
187 map->bankwidth*8); 187 map->bankwidth*8);
188 188
189 return 1; 189 return 1;
190} 190}
191 191
192static int __xipram cfi_chip_setup(struct map_info *map, 192static int __xipram cfi_chip_setup(struct map_info *map,
193 struct cfi_private *cfi) 193 struct cfi_private *cfi)
194{ 194{
195 int ofs_factor = cfi->interleave*cfi->device_type; 195 int ofs_factor = cfi->interleave*cfi->device_type;
@@ -209,11 +209,11 @@ static int __xipram cfi_chip_setup(struct map_info *map,
209 printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); 209 printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
210 return 0; 210 return 0;
211 } 211 }
212 212
213 memset(cfi->cfiq,0,sizeof(struct cfi_ident)); 213 memset(cfi->cfiq,0,sizeof(struct cfi_ident));
214 214
215 cfi->cfi_mode = CFI_MODE_CFI; 215 cfi->cfi_mode = CFI_MODE_CFI;
216 216
217 /* Read the CFI info structure */ 217 /* Read the CFI info structure */
218 xip_disable_qry(base, map, cfi); 218 xip_disable_qry(base, map, cfi);
219 for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) 219 for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++)
@@ -231,7 +231,7 @@ static int __xipram cfi_chip_setup(struct map_info *map,
231 cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); 231 cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
232 cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); 232 cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
233 cfi->mfr = cfi_read_query(map, base); 233 cfi->mfr = cfi_read_query(map, base);
234 cfi->id = cfi_read_query(map, base + ofs_factor); 234 cfi->id = cfi_read_query(map, base + ofs_factor);
235 235
236 /* Put it back into Read Mode */ 236 /* Put it back into Read Mode */
237 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); 237 cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
@@ -255,10 +255,10 @@ static int __xipram cfi_chip_setup(struct map_info *map,
255 255
256 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { 256 for (i=0; i<cfi->cfiq->NumEraseRegions; i++) {
257 cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]); 257 cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]);
258 258
259#ifdef DEBUG_CFI 259#ifdef DEBUG_CFI
260 printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n", 260 printk(" Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",
261 i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, 261 i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff,
262 (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1); 262 (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
263#endif 263#endif
264 } 264 }
@@ -271,33 +271,33 @@ static int __xipram cfi_chip_setup(struct map_info *map,
271} 271}
272 272
273#ifdef DEBUG_CFI 273#ifdef DEBUG_CFI
274static char *vendorname(__u16 vendor) 274static char *vendorname(__u16 vendor)
275{ 275{
276 switch (vendor) { 276 switch (vendor) {
277 case P_ID_NONE: 277 case P_ID_NONE:
278 return "None"; 278 return "None";
279 279
280 case P_ID_INTEL_EXT: 280 case P_ID_INTEL_EXT:
281 return "Intel/Sharp Extended"; 281 return "Intel/Sharp Extended";
282 282
283 case P_ID_AMD_STD: 283 case P_ID_AMD_STD:
284 return "AMD/Fujitsu Standard"; 284 return "AMD/Fujitsu Standard";
285 285
286 case P_ID_INTEL_STD: 286 case P_ID_INTEL_STD:
287 return "Intel/Sharp Standard"; 287 return "Intel/Sharp Standard";
288 288
289 case P_ID_AMD_EXT: 289 case P_ID_AMD_EXT:
290 return "AMD/Fujitsu Extended"; 290 return "AMD/Fujitsu Extended";
291 291
292 case P_ID_WINBOND: 292 case P_ID_WINBOND:
293 return "Winbond Standard"; 293 return "Winbond Standard";
294 294
295 case P_ID_ST_ADV: 295 case P_ID_ST_ADV:
296 return "ST Advanced"; 296 return "ST Advanced";
297 297
298 case P_ID_MITSUBISHI_STD: 298 case P_ID_MITSUBISHI_STD:
299 return "Mitsubishi Standard"; 299 return "Mitsubishi Standard";
300 300
301 case P_ID_MITSUBISHI_EXT: 301 case P_ID_MITSUBISHI_EXT:
302 return "Mitsubishi Extended"; 302 return "Mitsubishi Extended";
303 303
@@ -306,13 +306,13 @@ static char *vendorname(__u16 vendor)
306 306
307 case P_ID_INTEL_PERFORMANCE: 307 case P_ID_INTEL_PERFORMANCE:
308 return "Intel Performance Code"; 308 return "Intel Performance Code";
309 309
310 case P_ID_INTEL_DATA: 310 case P_ID_INTEL_DATA:
311 return "Intel Data"; 311 return "Intel Data";
312 312
313 case P_ID_RESERVED: 313 case P_ID_RESERVED:
314 return "Not Allowed / Reserved for Future Use"; 314 return "Not Allowed / Reserved for Future Use";
315 315
316 default: 316 default:
317 return "Unknown"; 317 return "Unknown";
318 } 318 }
@@ -325,21 +325,21 @@ static void print_cfi_ident(struct cfi_ident *cfip)
325 if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') { 325 if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {
326 printk("Invalid CFI ident structure.\n"); 326 printk("Invalid CFI ident structure.\n");
327 return; 327 return;
328 } 328 }
329#endif 329#endif
330 printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID)); 330 printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));
331 if (cfip->P_ADR) 331 if (cfip->P_ADR)
332 printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR); 332 printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);
333 else 333 else
334 printk("No Primary Algorithm Table\n"); 334 printk("No Primary Algorithm Table\n");
335 335
336 printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID)); 336 printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID));
337 if (cfip->A_ADR) 337 if (cfip->A_ADR)
338 printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR); 338 printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR);
339 else 339 else
340 printk("No Alternate Algorithm Table\n"); 340 printk("No Alternate Algorithm Table\n");
341 341
342 342
343 printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); 343 printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
344 printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); 344 printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
345 if (cfip->VppMin) { 345 if (cfip->VppMin) {
@@ -348,61 +348,61 @@ static void print_cfi_ident(struct cfi_ident *cfip)
348 } 348 }
349 else 349 else
350 printk("No Vpp line\n"); 350 printk("No Vpp line\n");
351 351
352 printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp); 352 printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp);
353 printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp)); 353 printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));
354 354
355 if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) { 355 if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {
356 printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp); 356 printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp);
357 printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp)); 357 printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));
358 } 358 }
359 else 359 else
360 printk("Full buffer write not supported\n"); 360 printk("Full buffer write not supported\n");
361 361
362 printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp); 362 printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp);
363 printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp)); 363 printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));
364 if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) { 364 if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {
365 printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp); 365 printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp);
366 printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp)); 366 printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp));
367 } 367 }
368 else 368 else
369 printk("Chip erase not supported\n"); 369 printk("Chip erase not supported\n");
370 370
371 printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20)); 371 printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20));
372 printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc); 372 printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc);
373 switch(cfip->InterfaceDesc) { 373 switch(cfip->InterfaceDesc) {
374 case 0: 374 case 0:
375 printk(" - x8-only asynchronous interface\n"); 375 printk(" - x8-only asynchronous interface\n");
376 break; 376 break;
377 377
378 case 1: 378 case 1:
379 printk(" - x16-only asynchronous interface\n"); 379 printk(" - x16-only asynchronous interface\n");
380 break; 380 break;
381 381
382 case 2: 382 case 2:
383 printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n"); 383 printk(" - supports x8 and x16 via BYTE# with asynchronous interface\n");
384 break; 384 break;
385 385
386 case 3: 386 case 3:
387 printk(" - x32-only asynchronous interface\n"); 387 printk(" - x32-only asynchronous interface\n");
388 break; 388 break;
389 389
390 case 4: 390 case 4:
391 printk(" - supports x16 and x32 via Word# with asynchronous interface\n"); 391 printk(" - supports x16 and x32 via Word# with asynchronous interface\n");
392 break; 392 break;
393 393
394 case 65535: 394 case 65535:
395 printk(" - Not Allowed / Reserved\n"); 395 printk(" - Not Allowed / Reserved\n");
396 break; 396 break;
397 397
398 default: 398 default:
399 printk(" - Unknown\n"); 399 printk(" - Unknown\n");
400 break; 400 break;
401 } 401 }
402 402
403 printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize); 403 printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize);
404 printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions); 404 printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions);
405 405
406} 406}
407#endif /* DEBUG_CFI */ 407#endif /* DEBUG_CFI */
408 408
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index 2b2ede2bfcca..d8e7a026ba5a 100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * This code is covered by the GPL. 8 * This code is covered by the GPL.
9 * 9 *
10 * $Id: cfi_util.c,v 1.8 2004/12/14 19:55:56 nico Exp $ 10 * $Id: cfi_util.c,v 1.10 2005/11/07 11:14:23 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -56,7 +56,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
56 56
57 /* Read in the Extended Query Table */ 57 /* Read in the Extended Query Table */
58 for (i=0; i<size; i++) { 58 for (i=0; i<size; i++) {
59 ((unsigned char *)extp)[i] = 59 ((unsigned char *)extp)[i] =
60 cfi_read_query(map, base+((adr+i)*ofs_factor)); 60 cfi_read_query(map, base+((adr+i)*ofs_factor));
61 } 61 }
62 62
@@ -70,15 +70,6 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
70 local_irq_enable(); 70 local_irq_enable();
71#endif 71#endif
72 72
73 if (extp->MajorVersion != '1' ||
74 (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
75 printk(KERN_WARNING " Unknown %s Extended Query "
76 "version %c.%c.\n", name, extp->MajorVersion,
77 extp->MinorVersion);
78 kfree(extp);
79 extp = NULL;
80 }
81
82 out: return extp; 73 out: return extp;
83} 74}
84 75
@@ -122,17 +113,17 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
122 113
123 i = 0; 114 i = 0;
124 115
125 /* Skip all erase regions which are ended before the start of 116 /* Skip all erase regions which are ended before the start of
126 the requested erase. Actually, to save on the calculations, 117 the requested erase. Actually, to save on the calculations,
127 we skip to the first erase region which starts after the 118 we skip to the first erase region which starts after the
128 start of the requested erase, and then go back one. 119 start of the requested erase, and then go back one.
129 */ 120 */
130 121
131 while (i < mtd->numeraseregions && ofs >= regions[i].offset) 122 while (i < mtd->numeraseregions && ofs >= regions[i].offset)
132 i++; 123 i++;
133 i--; 124 i--;
134 125
135 /* OK, now i is pointing at the erase region in which this 126 /* OK, now i is pointing at the erase region in which this
136 erase request starts. Check the start of the requested 127 erase request starts. Check the start of the requested
137 erase range is aligned with the erase size which is in 128 erase range is aligned with the erase size which is in
138 effect here. 129 effect here.
@@ -155,7 +146,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
155 the address actually falls 146 the address actually falls
156 */ 147 */
157 i--; 148 i--;
158 149
159 if ((ofs + len) & (regions[i].erasesize-1)) 150 if ((ofs + len) & (regions[i].erasesize-1))
160 return -EINVAL; 151 return -EINVAL;
161 152
@@ -168,7 +159,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
168 int size = regions[i].erasesize; 159 int size = regions[i].erasesize;
169 160
170 ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk); 161 ret = (*frob)(map, &cfi->chips[chipnum], adr, size, thunk);
171 162
172 if (ret) 163 if (ret)
173 return ret; 164 return ret;
174 165
@@ -182,7 +173,7 @@ int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
182 if (adr >> cfi->chipshift) { 173 if (adr >> cfi->chipshift) {
183 adr = 0; 174 adr = 0;
184 chipnum++; 175 chipnum++;
185 176
186 if (chipnum >= cfi->numchips) 177 if (chipnum >= cfi->numchips)
187 break; 178 break;
188 } 179 }
diff --git a/drivers/mtd/chips/chipreg.c b/drivers/mtd/chips/chipreg.c
index d7d739a108ae..c2127840a183 100644
--- a/drivers/mtd/chips/chipreg.c
+++ b/drivers/mtd/chips/chipreg.c
@@ -41,7 +41,7 @@ static struct mtd_chip_driver *get_mtd_chip_driver (const char *name)
41 41
42 list_for_each(pos, &chip_drvs_list) { 42 list_for_each(pos, &chip_drvs_list) {
43 this = list_entry(pos, typeof(*this), list); 43 this = list_entry(pos, typeof(*this), list);
44 44
45 if (!strcmp(this->name, name)) { 45 if (!strcmp(this->name, name)) {
46 ret = this; 46 ret = this;
47 break; 47 break;
@@ -73,7 +73,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
73 73
74 ret = drv->probe(map); 74 ret = drv->probe(map);
75 75
76 /* We decrease the use count here. It may have been a 76 /* We decrease the use count here. It may have been a
77 probe-only module, which is no longer required from this 77 probe-only module, which is no longer required from this
78 point, having given us a handle on (and increased the use 78 point, having given us a handle on (and increased the use
79 count of) the actual driver code. 79 count of) the actual driver code.
@@ -82,7 +82,7 @@ struct mtd_info *do_map_probe(const char *name, struct map_info *map)
82 82
83 if (ret) 83 if (ret)
84 return ret; 84 return ret;
85 85
86 return NULL; 86 return NULL;
87} 87}
88/* 88/*
diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h
index e1a5b76596c5..77303ce5dcf1 100644
--- a/drivers/mtd/chips/fwh_lock.h
+++ b/drivers/mtd/chips/fwh_lock.h
@@ -25,7 +25,7 @@ struct fwh_xxlock_thunk {
25 * so this code has not been tested with interleaved chips, 25 * so this code has not been tested with interleaved chips,
26 * and will likely fail in that context. 26 * and will likely fail in that context.
27 */ 27 */
28static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip, 28static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
29 unsigned long adr, int len, void *thunk) 29 unsigned long adr, int len, void *thunk)
30{ 30{
31 struct cfi_private *cfi = map->fldrv_priv; 31 struct cfi_private *cfi = map->fldrv_priv;
@@ -44,7 +44,7 @@ static int fwh_xxlock_oneblock(struct map_info *map, struct flchip *chip,
44 * - on 64k boundariesand 44 * - on 64k boundariesand
45 * - bit 1 set high 45 * - bit 1 set high
46 * - block lock registers are 4MiB lower - overflow subtract (danger) 46 * - block lock registers are 4MiB lower - overflow subtract (danger)
47 * 47 *
48 * The address manipulation is first done on the logical address 48 * The address manipulation is first done on the logical address
49 * which is 0 at the start of the chip, and then the offset of 49 * which is 0 at the start of the chip, and then the offset of
50 * the individual chip is addted to it. Any other order a weird 50 * the individual chip is addted to it. Any other order a weird
@@ -93,7 +93,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, size_t len)
93 93
94 ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len, 94 ret = cfi_varsize_frob(mtd, fwh_xxlock_oneblock, ofs, len,
95 (void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK); 95 (void *)&FWH_XXLOCK_ONEBLOCK_UNLOCK);
96 96
97 return ret; 97 return ret;
98} 98}
99 99
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index dc065b22f79e..41bd59d20d85 100644
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -2,7 +2,7 @@
2 * Routines common to all CFI-type probes. 2 * Routines common to all CFI-type probes.
3 * (C) 2001-2003 Red Hat, Inc. 3 * (C) 2001-2003 Red Hat, Inc.
4 * GPL'd 4 * GPL'd
5 * $Id: gen_probe.c,v 1.22 2005/01/24 23:49:50 rmk Exp $ 5 * $Id: gen_probe.c,v 1.24 2005/11/07 11:14:23 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/kernel.h> 8#include <linux/kernel.h>
@@ -26,7 +26,7 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
26 26
27 /* First probe the map to see if we have CFI stuff there. */ 27 /* First probe the map to see if we have CFI stuff there. */
28 cfi = genprobe_ident_chips(map, cp); 28 cfi = genprobe_ident_chips(map, cp);
29 29
30 if (!cfi) 30 if (!cfi)
31 return NULL; 31 return NULL;
32 32
@@ -36,12 +36,12 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
36 mtd = check_cmd_set(map, 1); /* First the primary cmdset */ 36 mtd = check_cmd_set(map, 1); /* First the primary cmdset */
37 if (!mtd) 37 if (!mtd)
38 mtd = check_cmd_set(map, 0); /* Then the secondary */ 38 mtd = check_cmd_set(map, 0); /* Then the secondary */
39 39
40 if (mtd) 40 if (mtd)
41 return mtd; 41 return mtd;
42 42
43 printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n"); 43 printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
44 44
45 kfree(cfi->cfiq); 45 kfree(cfi->cfiq);
46 kfree(cfi); 46 kfree(cfi);
47 map->fldrv_priv = NULL; 47 map->fldrv_priv = NULL;
@@ -60,14 +60,14 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
60 60
61 memset(&cfi, 0, sizeof(cfi)); 61 memset(&cfi, 0, sizeof(cfi));
62 62
63 /* Call the probetype-specific code with all permutations of 63 /* Call the probetype-specific code with all permutations of
64 interleave and device type, etc. */ 64 interleave and device type, etc. */
65 if (!genprobe_new_chip(map, cp, &cfi)) { 65 if (!genprobe_new_chip(map, cp, &cfi)) {
66 /* The probe didn't like it */ 66 /* The probe didn't like it */
67 printk(KERN_DEBUG "%s: Found no %s device at location zero\n", 67 printk(KERN_DEBUG "%s: Found no %s device at location zero\n",
68 cp->name, map->name); 68 cp->name, map->name);
69 return NULL; 69 return NULL;
70 } 70 }
71 71
72#if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD 72#if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD
73 probe routines won't ever return a broken CFI structure anyway, 73 probe routines won't ever return a broken CFI structure anyway,
@@ -92,13 +92,13 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
92 } else { 92 } else {
93 BUG(); 93 BUG();
94 } 94 }
95 95
96 cfi.numchips = 1; 96 cfi.numchips = 1;
97 97
98 /* 98 /*
99 * Allocate memory for bitmap of valid chips. 99 * Allocate memory for bitmap of valid chips.
100 * Align bitmap storage size to full byte. 100 * Align bitmap storage size to full byte.
101 */ 101 */
102 max_chips = map->size >> cfi.chipshift; 102 max_chips = map->size >> cfi.chipshift;
103 mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0); 103 mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0);
104 chip_map = kmalloc(mapsize, GFP_KERNEL); 104 chip_map = kmalloc(mapsize, GFP_KERNEL);
@@ -122,7 +122,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
122 } 122 }
123 123
124 /* 124 /*
125 * Now allocate the space for the structures we need to return to 125 * Now allocate the space for the structures we need to return to
126 * our caller, and copy the appropriate data into them. 126 * our caller, and copy the appropriate data into them.
127 */ 127 */
128 128
@@ -154,7 +154,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
154 return retcfi; 154 return retcfi;
155} 155}
156 156
157 157
158static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp, 158static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
159 struct cfi_private *cfi) 159 struct cfi_private *cfi)
160{ 160{
@@ -189,7 +189,7 @@ extern cfi_cmdset_fn_t cfi_cmdset_0001;
189extern cfi_cmdset_fn_t cfi_cmdset_0002; 189extern cfi_cmdset_fn_t cfi_cmdset_0002;
190extern cfi_cmdset_fn_t cfi_cmdset_0020; 190extern cfi_cmdset_fn_t cfi_cmdset_0020;
191 191
192static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, 192static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
193 int primary) 193 int primary)
194{ 194{
195 struct cfi_private *cfi = map->fldrv_priv; 195 struct cfi_private *cfi = map->fldrv_priv;
@@ -199,7 +199,7 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
199 cfi_cmdset_fn_t *probe_function; 199 cfi_cmdset_fn_t *probe_function;
200 200
201 sprintf(probename, "cfi_cmdset_%4.4X", type); 201 sprintf(probename, "cfi_cmdset_%4.4X", type);
202 202
203 probe_function = inter_module_get_request(probename, probename); 203 probe_function = inter_module_get_request(probename, probename);
204 204
205 if (probe_function) { 205 if (probe_function) {
@@ -221,7 +221,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
221{ 221{
222 struct cfi_private *cfi = map->fldrv_priv; 222 struct cfi_private *cfi = map->fldrv_priv;
223 __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; 223 __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
224 224
225 if (type == P_ID_NONE || type == P_ID_RESERVED) 225 if (type == P_ID_NONE || type == P_ID_RESERVED)
226 return NULL; 226 return NULL;
227 227
@@ -235,6 +235,7 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
235#ifdef CONFIG_MTD_CFI_INTELEXT 235#ifdef CONFIG_MTD_CFI_INTELEXT
236 case 0x0001: 236 case 0x0001:
237 case 0x0003: 237 case 0x0003:
238 case 0x0200:
238 return cfi_cmdset_0001(map, primary); 239 return cfi_cmdset_0001(map, primary);
239#endif 240#endif
240#ifdef CONFIG_MTD_CFI_AMDSTD 241#ifdef CONFIG_MTD_CFI_AMDSTD
diff --git a/drivers/mtd/chips/jedec.c b/drivers/mtd/chips/jedec.c
index 4f6778f3ee3e..c40b48dabed3 100644
--- a/drivers/mtd/chips/jedec.c
+++ b/drivers/mtd/chips/jedec.c
@@ -1,6 +1,6 @@
1 1
2/* JEDEC Flash Interface. 2/* JEDEC Flash Interface.
3 * This is an older type of interface for self programming flash. It is 3 * This is an older type of interface for self programming flash. It is
4 * commonly use in older AMD chips and is obsolete compared with CFI. 4 * commonly use in older AMD chips and is obsolete compared with CFI.
5 * It is called JEDEC because the JEDEC association distributes the ID codes 5 * It is called JEDEC because the JEDEC association distributes the ID codes
6 * for the chips. 6 * for the chips.
@@ -88,9 +88,9 @@ static const struct JEDECTable JEDEC_table[] = {
88 88
89static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id); 89static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
90static void jedec_sync(struct mtd_info *mtd) {}; 90static void jedec_sync(struct mtd_info *mtd) {};
91static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 91static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
92 size_t *retlen, u_char *buf); 92 size_t *retlen, u_char *buf);
93static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 93static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
94 size_t *retlen, u_char *buf); 94 size_t *retlen, u_char *buf);
95 95
96static struct mtd_info *jedec_probe(struct map_info *map); 96static struct mtd_info *jedec_probe(struct map_info *map);
@@ -122,7 +122,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
122 122
123 memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private)); 123 memset(MTD, 0, sizeof(struct mtd_info) + sizeof(struct jedec_private));
124 priv = (struct jedec_private *)&MTD[1]; 124 priv = (struct jedec_private *)&MTD[1];
125 125
126 my_bank_size = map->size; 126 my_bank_size = map->size;
127 127
128 if (map->size/my_bank_size > MAX_JEDEC_CHIPS) 128 if (map->size/my_bank_size > MAX_JEDEC_CHIPS)
@@ -131,13 +131,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
131 kfree(MTD); 131 kfree(MTD);
132 return NULL; 132 return NULL;
133 } 133 }
134 134
135 for (Base = 0; Base < map->size; Base += my_bank_size) 135 for (Base = 0; Base < map->size; Base += my_bank_size)
136 { 136 {
137 // Perhaps zero could designate all tests? 137 // Perhaps zero could designate all tests?
138 if (map->buswidth == 0) 138 if (map->buswidth == 0)
139 map->buswidth = 1; 139 map->buswidth = 1;
140 140
141 if (map->buswidth == 1){ 141 if (map->buswidth == 1){
142 if (jedec_probe8(map,Base,priv) == 0) { 142 if (jedec_probe8(map,Base,priv) == 0) {
143 printk("did recognize jedec chip\n"); 143 printk("did recognize jedec chip\n");
@@ -150,7 +150,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
150 if (map->buswidth == 4) 150 if (map->buswidth == 4)
151 jedec_probe32(map,Base,priv); 151 jedec_probe32(map,Base,priv);
152 } 152 }
153 153
154 // Get the biggest sector size 154 // Get the biggest sector size
155 SectorSize = 0; 155 SectorSize = 0;
156 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 156 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
@@ -160,7 +160,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
160 if (priv->chips[I].sectorsize > SectorSize) 160 if (priv->chips[I].sectorsize > SectorSize)
161 SectorSize = priv->chips[I].sectorsize; 161 SectorSize = priv->chips[I].sectorsize;
162 } 162 }
163 163
164 // Quickly ensure that the other sector sizes are factors of the largest 164 // Quickly ensure that the other sector sizes are factors of the largest
165 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 165 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
166 { 166 {
@@ -169,9 +169,9 @@ static struct mtd_info *jedec_probe(struct map_info *map)
169 printk("mtd: Failed. Device has incompatible mixed sector sizes\n"); 169 printk("mtd: Failed. Device has incompatible mixed sector sizes\n");
170 kfree(MTD); 170 kfree(MTD);
171 return NULL; 171 return NULL;
172 } 172 }
173 } 173 }
174 174
175 /* Generate a part name that includes the number of different chips and 175 /* Generate a part name that includes the number of different chips and
176 other configuration information */ 176 other configuration information */
177 count = 1; 177 count = 1;
@@ -181,13 +181,13 @@ static struct mtd_info *jedec_probe(struct map_info *map)
181 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 181 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
182 { 182 {
183 const struct JEDECTable *JEDEC; 183 const struct JEDECTable *JEDEC;
184 184
185 if (priv->chips[I+1].jedec == priv->chips[I].jedec) 185 if (priv->chips[I+1].jedec == priv->chips[I].jedec)
186 { 186 {
187 count++; 187 count++;
188 continue; 188 continue;
189 } 189 }
190 190
191 // Locate the chip in the jedec table 191 // Locate the chip in the jedec table
192 JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec); 192 JEDEC = jedec_idtoinf(priv->chips[I].jedec >> 8,priv->chips[I].jedec);
193 if (JEDEC == 0) 193 if (JEDEC == 0)
@@ -196,11 +196,11 @@ static struct mtd_info *jedec_probe(struct map_info *map)
196 kfree(MTD); 196 kfree(MTD);
197 return NULL; 197 return NULL;
198 } 198 }
199 199
200 if (Uniq != 0) 200 if (Uniq != 0)
201 strcat(Part,","); 201 strcat(Part,",");
202 Uniq++; 202 Uniq++;
203 203
204 if (count != 1) 204 if (count != 1)
205 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name); 205 sprintf(Part+strlen(Part),"%x*[%s]",count,JEDEC->name);
206 else 206 else
@@ -208,7 +208,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
208 if (strlen(Part) > sizeof(Part)*2/3) 208 if (strlen(Part) > sizeof(Part)*2/3)
209 break; 209 break;
210 count = 1; 210 count = 1;
211 } 211 }
212 212
213 /* Determine if the chips are organized in a linear fashion, or if there 213 /* Determine if the chips are organized in a linear fashion, or if there
214 are empty banks. Note, the last bank does not count here, only the 214 are empty banks. Note, the last bank does not count here, only the
@@ -233,7 +233,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
233 { 233 {
234 if (priv->bank_fill[I] != my_bank_size) 234 if (priv->bank_fill[I] != my_bank_size)
235 priv->is_banked = 1; 235 priv->is_banked = 1;
236 236
237 /* This even could be eliminated, but new de-optimized read/write 237 /* This even could be eliminated, but new de-optimized read/write
238 functions have to be written */ 238 functions have to be written */
239 printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]); 239 printk("priv->bank_fill[%d] is %lx, priv->bank_fill[0] is %lx\n",I,priv->bank_fill[I],priv->bank_fill[0]);
@@ -242,7 +242,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
242 printk("mtd: Failed. Cannot handle unsymmetric banking\n"); 242 printk("mtd: Failed. Cannot handle unsymmetric banking\n");
243 kfree(MTD); 243 kfree(MTD);
244 return NULL; 244 return NULL;
245 } 245 }
246 } 246 }
247 } 247 }
248 } 248 }
@@ -250,7 +250,7 @@ static struct mtd_info *jedec_probe(struct map_info *map)
250 strcat(Part,", banked"); 250 strcat(Part,", banked");
251 251
252 // printk("Part: '%s'\n",Part); 252 // printk("Part: '%s'\n",Part);
253 253
254 memset(MTD,0,sizeof(*MTD)); 254 memset(MTD,0,sizeof(*MTD));
255 // strlcpy(MTD->name,Part,sizeof(MTD->name)); 255 // strlcpy(MTD->name,Part,sizeof(MTD->name));
256 MTD->name = map->name; 256 MTD->name = map->name;
@@ -291,7 +291,7 @@ static int checkparity(u_char C)
291 291
292/* Take an array of JEDEC numbers that represent interleved flash chips 292/* Take an array of JEDEC numbers that represent interleved flash chips
293 and process them. Check to make sure they are good JEDEC numbers, look 293 and process them. Check to make sure they are good JEDEC numbers, look
294 them up and then add them to the chip list */ 294 them up and then add them to the chip list */
295static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count, 295static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
296 unsigned long base,struct jedec_private *priv) 296 unsigned long base,struct jedec_private *priv)
297{ 297{
@@ -306,16 +306,16 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
306 if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0) 306 if (checkparity(Mfg[I]) == 0 || checkparity(Id[I]) == 0)
307 return 0; 307 return 0;
308 } 308 }
309 309
310 // Finally, just make sure all the chip sizes are the same 310 // Finally, just make sure all the chip sizes are the same
311 JEDEC = jedec_idtoinf(Mfg[0],Id[0]); 311 JEDEC = jedec_idtoinf(Mfg[0],Id[0]);
312 312
313 if (JEDEC == 0) 313 if (JEDEC == 0)
314 { 314 {
315 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]); 315 printk("mtd: Found JEDEC flash chip, but do not have a table entry for %x:%x\n",Mfg[0],Mfg[1]);
316 return 0; 316 return 0;
317 } 317 }
318 318
319 Size = JEDEC->size; 319 Size = JEDEC->size;
320 SectorSize = JEDEC->sectorsize; 320 SectorSize = JEDEC->sectorsize;
321 for (I = 0; I != Count; I++) 321 for (I = 0; I != Count; I++)
@@ -331,7 +331,7 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
331 { 331 {
332 printk("mtd: Failed. Interleved flash does not have matching characteristics\n"); 332 printk("mtd: Failed. Interleved flash does not have matching characteristics\n");
333 return 0; 333 return 0;
334 } 334 }
335 } 335 }
336 336
337 // Load the Chips 337 // Load the Chips
@@ -345,13 +345,13 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
345 { 345 {
346 printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n"); 346 printk("mtd: Device has too many chips. Increase MAX_JEDEC_CHIPS\n");
347 return 0; 347 return 0;
348 } 348 }
349 349
350 // Add them to the table 350 // Add them to the table
351 for (J = 0; J != Count; J++) 351 for (J = 0; J != Count; J++)
352 { 352 {
353 unsigned long Bank; 353 unsigned long Bank;
354 354
355 JEDEC = jedec_idtoinf(Mfg[J],Id[J]); 355 JEDEC = jedec_idtoinf(Mfg[J],Id[J]);
356 priv->chips[I].jedec = (Mfg[J] << 8) | Id[J]; 356 priv->chips[I].jedec = (Mfg[J] << 8) | Id[J];
357 priv->chips[I].size = JEDEC->size; 357 priv->chips[I].size = JEDEC->size;
@@ -364,17 +364,17 @@ static int handle_jedecs(struct map_info *map,__u8 *Mfg,__u8 *Id,unsigned Count,
364 // log2 n :| 364 // log2 n :|
365 priv->chips[I].addrshift = 0; 365 priv->chips[I].addrshift = 0;
366 for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++); 366 for (Bank = Count; Bank != 1; Bank >>= 1, priv->chips[I].addrshift++);
367 367
368 // Determine how filled this bank is. 368 // Determine how filled this bank is.
369 Bank = base & (~(my_bank_size-1)); 369 Bank = base & (~(my_bank_size-1));
370 if (priv->bank_fill[Bank/my_bank_size] < base + 370 if (priv->bank_fill[Bank/my_bank_size] < base +
371 (JEDEC->size << priv->chips[I].addrshift) - Bank) 371 (JEDEC->size << priv->chips[I].addrshift) - Bank)
372 priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank; 372 priv->bank_fill[Bank/my_bank_size] = base + (JEDEC->size << priv->chips[I].addrshift) - Bank;
373 I++; 373 I++;
374 } 374 }
375 375
376 priv->size += priv->chips[I-1].size*Count; 376 priv->size += priv->chips[I-1].size*Count;
377 377
378 return priv->chips[I-1].size; 378 return priv->chips[I-1].size;
379} 379}
380 380
@@ -392,7 +392,7 @@ static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id)
392// Look for flash using an 8 bit bus interface 392// Look for flash using an 8 bit bus interface
393static int jedec_probe8(struct map_info *map,unsigned long base, 393static int jedec_probe8(struct map_info *map,unsigned long base,
394 struct jedec_private *priv) 394 struct jedec_private *priv)
395{ 395{
396 #define flread(x) map_read8(map,base+x) 396 #define flread(x) map_read8(map,base+x)
397 #define flwrite(v,x) map_write8(map,v,base+x) 397 #define flwrite(v,x) map_write8(map,v,base+x)
398 398
@@ -410,20 +410,20 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
410 OldVal = flread(base); 410 OldVal = flread(base);
411 for (I = 0; OldVal != flread(base) && I < 10000; I++) 411 for (I = 0; OldVal != flread(base) && I < 10000; I++)
412 OldVal = flread(base); 412 OldVal = flread(base);
413 413
414 // Reset the chip 414 // Reset the chip
415 flwrite(Reset,0x555); 415 flwrite(Reset,0x555);
416 416
417 // Send the sequence 417 // Send the sequence
418 flwrite(AutoSel1,0x555); 418 flwrite(AutoSel1,0x555);
419 flwrite(AutoSel2,0x2AA); 419 flwrite(AutoSel2,0x2AA);
420 flwrite(AutoSel3,0x555); 420 flwrite(AutoSel3,0x555);
421 421
422 // Get the JEDEC numbers 422 // Get the JEDEC numbers
423 Mfg[0] = flread(0); 423 Mfg[0] = flread(0);
424 Id[0] = flread(1); 424 Id[0] = flread(1);
425 // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]); 425 // printk("Mfg is %x, Id is %x\n",Mfg[0],Id[0]);
426 426
427 Size = handle_jedecs(map,Mfg,Id,1,base,priv); 427 Size = handle_jedecs(map,Mfg,Id,1,base,priv);
428 // printk("handle_jedecs Size is %x\n",(unsigned int)Size); 428 // printk("handle_jedecs Size is %x\n",(unsigned int)Size);
429 if (Size == 0) 429 if (Size == 0)
@@ -431,13 +431,13 @@ static int jedec_probe8(struct map_info *map,unsigned long base,
431 flwrite(Reset,0x555); 431 flwrite(Reset,0x555);
432 return 0; 432 return 0;
433 } 433 }
434 434
435 435
436 // Reset. 436 // Reset.
437 flwrite(Reset,0x555); 437 flwrite(Reset,0x555);
438 438
439 return 1; 439 return 1;
440 440
441 #undef flread 441 #undef flread
442 #undef flwrite 442 #undef flwrite
443} 443}
@@ -470,17 +470,17 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
470 OldVal = flread(base); 470 OldVal = flread(base);
471 for (I = 0; OldVal != flread(base) && I < 10000; I++) 471 for (I = 0; OldVal != flread(base) && I < 10000; I++)
472 OldVal = flread(base); 472 OldVal = flread(base);
473 473
474 // Reset the chip 474 // Reset the chip
475 flwrite(Reset,0x555); 475 flwrite(Reset,0x555);
476 476
477 // Send the sequence 477 // Send the sequence
478 flwrite(AutoSel1,0x555); 478 flwrite(AutoSel1,0x555);
479 flwrite(AutoSel2,0x2AA); 479 flwrite(AutoSel2,0x2AA);
480 flwrite(AutoSel3,0x555); 480 flwrite(AutoSel3,0x555);
481 481
482 // Test #1, JEDEC numbers are readable from 0x??00/0x??01 482 // Test #1, JEDEC numbers are readable from 0x??00/0x??01
483 if (flread(0) != flread(0x100) || 483 if (flread(0) != flread(0x100) ||
484 flread(1) != flread(0x101)) 484 flread(1) != flread(0x101))
485 { 485 {
486 flwrite(Reset,0x555); 486 flwrite(Reset,0x555);
@@ -494,14 +494,14 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
494 OldVal = flread(1); 494 OldVal = flread(1);
495 for (I = 0; I != 4; I++) 495 for (I = 0; I != 4; I++)
496 Id[I] = (OldVal >> (I*8)); 496 Id[I] = (OldVal >> (I*8));
497 497
498 Size = handle_jedecs(map,Mfg,Id,4,base,priv); 498 Size = handle_jedecs(map,Mfg,Id,4,base,priv);
499 if (Size == 0) 499 if (Size == 0)
500 { 500 {
501 flwrite(Reset,0x555); 501 flwrite(Reset,0x555);
502 return 0; 502 return 0;
503 } 503 }
504 504
505 /* Check if there is address wrap around within a single bank, if this 505 /* Check if there is address wrap around within a single bank, if this
506 returns JEDEC numbers then we assume that it is wrap around. Notice 506 returns JEDEC numbers then we assume that it is wrap around. Notice
507 we call this routine with the JEDEC return still enabled, if two or 507 we call this routine with the JEDEC return still enabled, if two or
@@ -519,27 +519,27 @@ static int jedec_probe32(struct map_info *map,unsigned long base,
519 519
520 // Reset. 520 // Reset.
521 flwrite(0xF0F0F0F0,0x555); 521 flwrite(0xF0F0F0F0,0x555);
522 522
523 return 1; 523 return 1;
524 524
525 #undef flread 525 #undef flread
526 #undef flwrite 526 #undef flwrite
527} 527}
528 528
529/* Linear read. */ 529/* Linear read. */
530static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len, 530static int jedec_read(struct mtd_info *mtd, loff_t from, size_t len,
531 size_t *retlen, u_char *buf) 531 size_t *retlen, u_char *buf)
532{ 532{
533 struct map_info *map = mtd->priv; 533 struct map_info *map = mtd->priv;
534 534
535 map_copy_from(map, buf, from, len); 535 map_copy_from(map, buf, from, len);
536 *retlen = len; 536 *retlen = len;
537 return 0; 537 return 0;
538} 538}
539 539
540/* Banked read. Take special care to jump past the holes in the bank 540/* Banked read. Take special care to jump past the holes in the bank
541 mapping. This version assumes symetry in the holes.. */ 541 mapping. This version assumes symetry in the holes.. */
542static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len, 542static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
543 size_t *retlen, u_char *buf) 543 size_t *retlen, u_char *buf)
544{ 544{
545 struct map_info *map = mtd->priv; 545 struct map_info *map = mtd->priv;
@@ -555,17 +555,17 @@ static int jedec_read_banked(struct mtd_info *mtd, loff_t from, size_t len,
555 if (priv->bank_fill[0] - offset < len) 555 if (priv->bank_fill[0] - offset < len)
556 get = priv->bank_fill[0] - offset; 556 get = priv->bank_fill[0] - offset;
557 557
558 bank /= priv->bank_fill[0]; 558 bank /= priv->bank_fill[0];
559 map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get); 559 map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
560 560
561 len -= get; 561 len -= get;
562 *retlen += get; 562 *retlen += get;
563 from += get; 563 from += get;
564 } 564 }
565 return 0; 565 return 0;
566} 566}
567 567
568/* Pass the flags value that the flash return before it re-entered read 568/* Pass the flags value that the flash return before it re-entered read
569 mode. */ 569 mode. */
570static void jedec_flash_failed(unsigned char code) 570static void jedec_flash_failed(unsigned char code)
571{ 571{
@@ -579,17 +579,17 @@ static void jedec_flash_failed(unsigned char code)
579 printk("mtd: Programming didn't take\n"); 579 printk("mtd: Programming didn't take\n");
580} 580}
581 581
582/* This uses the erasure function described in the AMD Flash Handbook, 582/* This uses the erasure function described in the AMD Flash Handbook,
583 it will work for flashes with a fixed sector size only. Flashes with 583 it will work for flashes with a fixed sector size only. Flashes with
584 a selection of sector sizes (ie the AMD Am29F800B) will need a different 584 a selection of sector sizes (ie the AMD Am29F800B) will need a different
585 routine. This routine tries to parallize erasing multiple chips/sectors 585 routine. This routine tries to parallize erasing multiple chips/sectors
586 where possible */ 586 where possible */
587static int flash_erase(struct mtd_info *mtd, struct erase_info *instr) 587static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
588{ 588{
589 // Does IO to the currently selected chip 589 // Does IO to the currently selected chip
590 #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift)) 590 #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift))
591 #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift)) 591 #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
592 592
593 unsigned long Time = 0; 593 unsigned long Time = 0;
594 unsigned long NoTime = 0; 594 unsigned long NoTime = 0;
595 unsigned long start = instr->addr, len = instr->len; 595 unsigned long start = instr->addr, len = instr->len;
@@ -603,7 +603,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
603 (len % mtd->erasesize) != 0 || 603 (len % mtd->erasesize) != 0 ||
604 (len/mtd->erasesize) == 0) 604 (len/mtd->erasesize) == 0)
605 return -EINVAL; 605 return -EINVAL;
606 606
607 jedec_flash_chip_scan(priv,start,len); 607 jedec_flash_chip_scan(priv,start,len);
608 608
609 // Start the erase sequence on each chip 609 // Start the erase sequence on each chip
@@ -611,16 +611,16 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
611 { 611 {
612 unsigned long off; 612 unsigned long off;
613 struct jedec_flash_chip *chip = priv->chips + I; 613 struct jedec_flash_chip *chip = priv->chips + I;
614 614
615 if (chip->length == 0) 615 if (chip->length == 0)
616 continue; 616 continue;
617 617
618 if (chip->start + chip->length > chip->size) 618 if (chip->start + chip->length > chip->size)
619 { 619 {
620 printk("DIE\n"); 620 printk("DIE\n");
621 return -EIO; 621 return -EIO;
622 } 622 }
623 623
624 flwrite(0xF0,chip->start + 0x555); 624 flwrite(0xF0,chip->start + 0x555);
625 flwrite(0xAA,chip->start + 0x555); 625 flwrite(0xAA,chip->start + 0x555);
626 flwrite(0x55,chip->start + 0x2AA); 626 flwrite(0x55,chip->start + 0x2AA);
@@ -628,8 +628,8 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
628 flwrite(0xAA,chip->start + 0x555); 628 flwrite(0xAA,chip->start + 0x555);
629 flwrite(0x55,chip->start + 0x2AA); 629 flwrite(0x55,chip->start + 0x2AA);
630 630
631 /* Once we start selecting the erase sectors the delay between each 631 /* Once we start selecting the erase sectors the delay between each
632 command must not exceed 50us or it will immediately start erasing 632 command must not exceed 50us or it will immediately start erasing
633 and ignore the other sectors */ 633 and ignore the other sectors */
634 for (off = 0; off < len; off += chip->sectorsize) 634 for (off = 0; off < len; off += chip->sectorsize)
635 { 635 {
@@ -641,19 +641,19 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
641 { 641 {
642 printk("mtd: Ack! We timed out the erase timer!\n"); 642 printk("mtd: Ack! We timed out the erase timer!\n");
643 return -EIO; 643 return -EIO;
644 } 644 }
645 } 645 }
646 } 646 }
647 647
648 /* We could split this into a timer routine and return early, performing 648 /* We could split this into a timer routine and return early, performing
649 background erasure.. Maybe later if the need warrents */ 649 background erasure.. Maybe later if the need warrents */
650 650
651 /* Poll the flash for erasure completion, specs say this can take as long 651 /* Poll the flash for erasure completion, specs say this can take as long
652 as 480 seconds to do all the sectors (for a 2 meg flash). 652 as 480 seconds to do all the sectors (for a 2 meg flash).
653 Erasure time is dependent on chip age, temp and wear.. */ 653 Erasure time is dependent on chip age, temp and wear.. */
654 654
655 /* This being a generic routine assumes a 32 bit bus. It does read32s 655 /* This being a generic routine assumes a 32 bit bus. It does read32s
656 and bundles interleved chips into the same grouping. This will work 656 and bundles interleved chips into the same grouping. This will work
657 for all bus widths */ 657 for all bus widths */
658 Time = 0; 658 Time = 0;
659 NoTime = 0; 659 NoTime = 0;
@@ -664,20 +664,20 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
664 unsigned todo[4] = {0,0,0,0}; 664 unsigned todo[4] = {0,0,0,0};
665 unsigned todo_left = 0; 665 unsigned todo_left = 0;
666 unsigned J; 666 unsigned J;
667 667
668 if (chip->length == 0) 668 if (chip->length == 0)
669 continue; 669 continue;
670 670
671 /* Find all chips in this data line, realistically this is all 671 /* Find all chips in this data line, realistically this is all
672 or nothing up to the interleve count */ 672 or nothing up to the interleve count */
673 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) 673 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
674 { 674 {
675 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == 675 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
676 (chip->base & (~((1<<chip->addrshift)-1)))) 676 (chip->base & (~((1<<chip->addrshift)-1))))
677 { 677 {
678 todo_left++; 678 todo_left++;
679 todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1; 679 todo[priv->chips[J].base & ((1<<chip->addrshift)-1)] = 1;
680 } 680 }
681 } 681 }
682 682
683 /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1], 683 /* printk("todo: %x %x %x %x\n",(short)todo[0],(short)todo[1],
@@ -687,7 +687,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
687 { 687 {
688 __u32 Last[4]; 688 __u32 Last[4];
689 unsigned long Count = 0; 689 unsigned long Count = 0;
690 690
691 /* During erase bit 7 is held low and bit 6 toggles, we watch this, 691 /* During erase bit 7 is held low and bit 6 toggles, we watch this,
692 should it stop toggling or go high then the erase is completed, 692 should it stop toggling or go high then the erase is completed,
693 or this is not really flash ;> */ 693 or this is not really flash ;> */
@@ -718,23 +718,23 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
718 __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF; 718 __u8 Byte3 = (Last[(Count-3)%4] >> (J*8)) & 0xFF;
719 if (todo[J] == 0) 719 if (todo[J] == 0)
720 continue; 720 continue;
721 721
722 if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2) 722 if ((Byte1 & (1 << 7)) == 0 && Byte1 != Byte2)
723 { 723 {
724// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2); 724// printk("Check %x %x %x\n",(short)J,(short)Byte1,(short)Byte2);
725 continue; 725 continue;
726 } 726 }
727 727
728 if (Byte1 == Byte2) 728 if (Byte1 == Byte2)
729 { 729 {
730 jedec_flash_failed(Byte3); 730 jedec_flash_failed(Byte3);
731 return -EIO; 731 return -EIO;
732 } 732 }
733 733
734 todo[J] = 0; 734 todo[J] = 0;
735 todo_left--; 735 todo_left--;
736 } 736 }
737 737
738/* if (NoTime == 0) 738/* if (NoTime == 0)
739 Time += HZ/10 - schedule_timeout(HZ/10);*/ 739 Time += HZ/10 - schedule_timeout(HZ/10);*/
740 NoTime = 0; 740 NoTime = 0;
@@ -751,7 +751,7 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
751 break; 751 break;
752 } 752 }
753 Count++; 753 Count++;
754 754
755/* // Count time, max of 15s per sector (according to AMD) 755/* // Count time, max of 15s per sector (according to AMD)
756 if (Time > 15*len/mtd->erasesize*HZ) 756 if (Time > 15*len/mtd->erasesize*HZ)
757 { 757 {
@@ -759,38 +759,38 @@ static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
759 return -EIO; 759 return -EIO;
760 } */ 760 } */
761 } 761 }
762 762
763 // Skip to the next chip if we used chip erase 763 // Skip to the next chip if we used chip erase
764 if (chip->length == chip->size) 764 if (chip->length == chip->size)
765 off = chip->size; 765 off = chip->size;
766 else 766 else
767 off += chip->sectorsize; 767 off += chip->sectorsize;
768 768
769 if (off >= chip->length) 769 if (off >= chip->length)
770 break; 770 break;
771 NoTime = 1; 771 NoTime = 1;
772 } 772 }
773 773
774 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++) 774 for (J = 0; priv->chips[J].jedec != 0 && J < MAX_JEDEC_CHIPS; J++)
775 { 775 {
776 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) == 776 if ((priv->chips[J].base & (~((1<<chip->addrshift)-1))) ==
777 (chip->base & (~((1<<chip->addrshift)-1)))) 777 (chip->base & (~((1<<chip->addrshift)-1))))
778 priv->chips[J].length = 0; 778 priv->chips[J].length = 0;
779 } 779 }
780 } 780 }
781 781
782 //printk("done\n"); 782 //printk("done\n");
783 instr->state = MTD_ERASE_DONE; 783 instr->state = MTD_ERASE_DONE;
784 mtd_erase_callback(instr); 784 mtd_erase_callback(instr);
785 return 0; 785 return 0;
786 786
787 #undef flread 787 #undef flread
788 #undef flwrite 788 #undef flwrite
789} 789}
790 790
791/* This is the simple flash writing function. It writes to every byte, in 791/* This is the simple flash writing function. It writes to every byte, in
792 sequence. It takes care of how to properly address the flash if 792 sequence. It takes care of how to properly address the flash if
793 the flash is interleved. It can only be used if all the chips in the 793 the flash is interleved. It can only be used if all the chips in the
794 array are identical!*/ 794 array are identical!*/
795static int flash_write(struct mtd_info *mtd, loff_t start, size_t len, 795static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
796 size_t *retlen, const u_char *buf) 796 size_t *retlen, const u_char *buf)
@@ -800,25 +800,25 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
800 of addrshift (interleave index) and then adds the control register index. */ 800 of addrshift (interleave index) and then adds the control register index. */
801 #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) 801 #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
802 #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift)) 802 #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
803 803
804 struct map_info *map = mtd->priv; 804 struct map_info *map = mtd->priv;
805 struct jedec_private *priv = map->fldrv_priv; 805 struct jedec_private *priv = map->fldrv_priv;
806 unsigned long base; 806 unsigned long base;
807 unsigned long off; 807 unsigned long off;
808 size_t save_len = len; 808 size_t save_len = len;
809 809
810 if (start + len > mtd->size) 810 if (start + len > mtd->size)
811 return -EIO; 811 return -EIO;
812 812
813 //printk("Here"); 813 //printk("Here");
814 814
815 //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len); 815 //printk("flash_write: start is %x, len is %x\n",start,(unsigned long)len);
816 while (len != 0) 816 while (len != 0)
817 { 817 {
818 struct jedec_flash_chip *chip = priv->chips; 818 struct jedec_flash_chip *chip = priv->chips;
819 unsigned long bank; 819 unsigned long bank;
820 unsigned long boffset; 820 unsigned long boffset;
821 821
822 // Compute the base of the flash. 822 // Compute the base of the flash.
823 off = ((unsigned long)start) % (chip->size << chip->addrshift); 823 off = ((unsigned long)start) % (chip->size << chip->addrshift);
824 base = start - off; 824 base = start - off;
@@ -828,10 +828,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
828 boffset = base & (priv->bank_fill[0]-1); 828 boffset = base & (priv->bank_fill[0]-1);
829 bank = (bank/priv->bank_fill[0])*my_bank_size; 829 bank = (bank/priv->bank_fill[0])*my_bank_size;
830 base = bank + boffset; 830 base = bank + boffset;
831 831
832 // printk("Flasing %X %X %X\n",base,chip->size,len); 832 // printk("Flasing %X %X %X\n",base,chip->size,len);
833 // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift); 833 // printk("off is %x, compare with %x\n",off,chip->size << chip->addrshift);
834 834
835 // Loop over this page 835 // Loop over this page
836 for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++) 836 for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
837 { 837 {
@@ -845,7 +845,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
845 } 845 }
846 if (((~oldbyte) & *buf) != 0) 846 if (((~oldbyte) & *buf) != 0)
847 printk("mtd: warn: Trying to set a 0 to a 1\n"); 847 printk("mtd: warn: Trying to set a 0 to a 1\n");
848 848
849 // Write 849 // Write
850 flwrite(0xAA,0x555); 850 flwrite(0xAA,0x555);
851 flwrite(0x55,0x2AA); 851 flwrite(0x55,0x2AA);
@@ -854,10 +854,10 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
854 Last[0] = map_read8(map,base + off); 854 Last[0] = map_read8(map,base + off);
855 Last[1] = map_read8(map,base + off); 855 Last[1] = map_read8(map,base + off);
856 Last[2] = map_read8(map,base + off); 856 Last[2] = map_read8(map,base + off);
857 857
858 /* Wait for the flash to finish the operation. We store the last 4 858 /* Wait for the flash to finish the operation. We store the last 4
859 status bytes that have been retrieved so we can determine why 859 status bytes that have been retrieved so we can determine why
860 it failed. The toggle bits keep toggling when there is a 860 it failed. The toggle bits keep toggling when there is a
861 failure */ 861 failure */
862 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] && 862 for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
863 Count < 10000; Count++) 863 Count < 10000; Count++)
@@ -866,7 +866,7 @@ static int flash_write(struct mtd_info *mtd, loff_t start, size_t len,
866 { 866 {
867 jedec_flash_failed(Last[(Count - 3) % 4]); 867 jedec_flash_failed(Last[(Count - 3) % 4]);
868 return -EIO; 868 return -EIO;
869 } 869 }
870 } 870 }
871 } 871 }
872 *retlen = save_len; 872 *retlen = save_len;
@@ -885,24 +885,24 @@ static void jedec_flash_chip_scan(struct jedec_private *priv,unsigned long start
885 // Zero the records 885 // Zero the records
886 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 886 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
887 priv->chips[I].start = priv->chips[I].length = 0; 887 priv->chips[I].start = priv->chips[I].length = 0;
888 888
889 // Intersect the region with each chip 889 // Intersect the region with each chip
890 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++) 890 for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
891 { 891 {
892 struct jedec_flash_chip *chip = priv->chips + I; 892 struct jedec_flash_chip *chip = priv->chips + I;
893 unsigned long ByteStart; 893 unsigned long ByteStart;
894 unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift); 894 unsigned long ChipEndByte = chip->offset + (chip->size << chip->addrshift);
895 895
896 // End is before this chip or the start is after it 896 // End is before this chip or the start is after it
897 if (start+len < chip->offset || 897 if (start+len < chip->offset ||
898 ChipEndByte - (1 << chip->addrshift) < start) 898 ChipEndByte - (1 << chip->addrshift) < start)
899 continue; 899 continue;
900 900
901 if (start < chip->offset) 901 if (start < chip->offset)
902 { 902 {
903 ByteStart = chip->offset; 903 ByteStart = chip->offset;
904 chip->start = 0; 904 chip->start = 0;
905 } 905 }
906 else 906 else
907 { 907 {
908 chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift; 908 chip->start = (start - chip->offset + (1 << chip->addrshift)-1) >> chip->addrshift;
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 30da428eb7b9..edb306c03c0a 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -1,7 +1,7 @@
1/* 1/*
2 Common Flash Interface probe code. 2 Common Flash Interface probe code.
3 (C) 2000 Red Hat. GPL'd. 3 (C) 2000 Red Hat. GPL'd.
4 $Id: jedec_probe.c,v 1.63 2005/02/14 16:30:32 bjd Exp $ 4 $Id: jedec_probe.c,v 1.66 2005/11/07 11:14:23 gleixner Exp $
5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5) 5 See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
6 for the standard this probe goes back to. 6 for the standard this probe goes back to.
7 7
@@ -1719,7 +1719,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
1719 1719
1720static struct mtd_info *jedec_probe(struct map_info *map); 1720static struct mtd_info *jedec_probe(struct map_info *map);
1721 1721
1722static inline u32 jedec_read_mfr(struct map_info *map, __u32 base, 1722static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
1723 struct cfi_private *cfi) 1723 struct cfi_private *cfi)
1724{ 1724{
1725 map_word result; 1725 map_word result;
@@ -1730,7 +1730,7 @@ static inline u32 jedec_read_mfr(struct map_info *map, __u32 base,
1730 return result.x[0] & mask; 1730 return result.x[0] & mask;
1731} 1731}
1732 1732
1733static inline u32 jedec_read_id(struct map_info *map, __u32 base, 1733static inline u32 jedec_read_id(struct map_info *map, __u32 base,
1734 struct cfi_private *cfi) 1734 struct cfi_private *cfi)
1735{ 1735{
1736 map_word result; 1736 map_word result;
@@ -1741,7 +1741,7 @@ static inline u32 jedec_read_id(struct map_info *map, __u32 base,
1741 return result.x[0] & mask; 1741 return result.x[0] & mask;
1742} 1742}
1743 1743
1744static inline void jedec_reset(u32 base, struct map_info *map, 1744static inline void jedec_reset(u32 base, struct map_info *map,
1745 struct cfi_private *cfi) 1745 struct cfi_private *cfi)
1746{ 1746{
1747 /* Reset */ 1747 /* Reset */
@@ -1765,7 +1765,7 @@ static inline void jedec_reset(u32 base, struct map_info *map,
1765 * so ensure we're in read mode. Send both the Intel and the AMD command 1765 * so ensure we're in read mode. Send both the Intel and the AMD command
1766 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so 1766 * for this. Intel uses 0xff for this, AMD uses 0xff for NOP, so
1767 * this should be safe. 1767 * this should be safe.
1768 */ 1768 */
1769 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); 1769 cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
1770 /* FIXME - should have reset delay before continuing */ 1770 /* FIXME - should have reset delay before continuing */
1771} 1771}
@@ -1807,14 +1807,14 @@ static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
1807 printk("Found: %s\n",jedec_table[index].name); 1807 printk("Found: %s\n",jedec_table[index].name);
1808 1808
1809 num_erase_regions = jedec_table[index].NumEraseRegions; 1809 num_erase_regions = jedec_table[index].NumEraseRegions;
1810 1810
1811 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); 1811 p_cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL);
1812 if (!p_cfi->cfiq) { 1812 if (!p_cfi->cfiq) {
1813 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); 1813 //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name);
1814 return 0; 1814 return 0;
1815 } 1815 }
1816 1816
1817 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident)); 1817 memset(p_cfi->cfiq,0,sizeof(struct cfi_ident));
1818 1818
1819 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet; 1819 p_cfi->cfiq->P_ID = jedec_table[index].CmdSet;
1820 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions; 1820 p_cfi->cfiq->NumEraseRegions = jedec_table[index].NumEraseRegions;
@@ -1969,7 +1969,7 @@ static inline int jedec_match( __u32 base,
1969 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL); 1969 cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, cfi->device_type, NULL);
1970 /* FIXME - should have a delay before continuing */ 1970 /* FIXME - should have a delay before continuing */
1971 1971
1972 match_done: 1972 match_done:
1973 return rc; 1973 return rc;
1974} 1974}
1975 1975
@@ -1998,23 +1998,23 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
1998 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n", 1998 "Probe at base(0x%08x) past the end of the map(0x%08lx)\n",
1999 base, map->size -1); 1999 base, map->size -1);
2000 return 0; 2000 return 0;
2001 2001
2002 } 2002 }
2003 /* Ensure the unlock addresses we try stay inside the map */ 2003 /* Ensure the unlock addresses we try stay inside the map */
2004 probe_offset1 = cfi_build_cmd_addr( 2004 probe_offset1 = cfi_build_cmd_addr(
2005 cfi->addr_unlock1, 2005 cfi->addr_unlock1,
2006 cfi_interleave(cfi), 2006 cfi_interleave(cfi),
2007 cfi->device_type); 2007 cfi->device_type);
2008 probe_offset2 = cfi_build_cmd_addr( 2008 probe_offset2 = cfi_build_cmd_addr(
2009 cfi->addr_unlock1, 2009 cfi->addr_unlock1,
2010 cfi_interleave(cfi), 2010 cfi_interleave(cfi),
2011 cfi->device_type); 2011 cfi->device_type);
2012 if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) || 2012 if ( ((base + probe_offset1 + map_bankwidth(map)) >= map->size) ||
2013 ((base + probe_offset2 + map_bankwidth(map)) >= map->size)) 2013 ((base + probe_offset2 + map_bankwidth(map)) >= map->size))
2014 { 2014 {
2015 goto retry; 2015 goto retry;
2016 } 2016 }
2017 2017
2018 /* Reset */ 2018 /* Reset */
2019 jedec_reset(base, map, cfi); 2019 jedec_reset(base, map, cfi);
2020 2020
@@ -2027,13 +2027,13 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2027 /* FIXME - should have a delay before continuing */ 2027 /* FIXME - should have a delay before continuing */
2028 2028
2029 if (!cfi->numchips) { 2029 if (!cfi->numchips) {
2030 /* This is the first time we're called. Set up the CFI 2030 /* This is the first time we're called. Set up the CFI
2031 stuff accordingly and return */ 2031 stuff accordingly and return */
2032 2032
2033 cfi->mfr = jedec_read_mfr(map, base, cfi); 2033 cfi->mfr = jedec_read_mfr(map, base, cfi);
2034 cfi->id = jedec_read_id(map, base, cfi); 2034 cfi->id = jedec_read_id(map, base, cfi);
2035 DEBUG(MTD_DEBUG_LEVEL3, 2035 DEBUG(MTD_DEBUG_LEVEL3,
2036 "Search for id:(%02x %02x) interleave(%d) type(%d)\n", 2036 "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
2037 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type); 2037 cfi->mfr, cfi->id, cfi_interleave(cfi), cfi->device_type);
2038 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) { 2038 for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
2039 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) { 2039 if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
@@ -2062,7 +2062,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2062 return 0; 2062 return 0;
2063 } 2063 }
2064 } 2064 }
2065 2065
2066 /* Check each previous chip locations to see if it's an alias */ 2066 /* Check each previous chip locations to see if it's an alias */
2067 for (i=0; i < (base >> cfi->chipshift); i++) { 2067 for (i=0; i < (base >> cfi->chipshift); i++) {
2068 unsigned long start; 2068 unsigned long start;
@@ -2083,7 +2083,7 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2083 map->name, base, start); 2083 map->name, base, start);
2084 return 0; 2084 return 0;
2085 } 2085 }
2086 2086
2087 /* Yes, it's actually got the device IDs as data. Most 2087 /* Yes, it's actually got the device IDs as data. Most
2088 * unfortunate. Stick the new chip in read mode 2088 * unfortunate. Stick the new chip in read mode
2089 * too and if it's the same, assume it's an alias. */ 2089 * too and if it's the same, assume it's an alias. */
@@ -2097,20 +2097,20 @@ static int jedec_probe_chip(struct map_info *map, __u32 base,
2097 } 2097 }
2098 } 2098 }
2099 } 2099 }
2100 2100
2101 /* OK, if we got to here, then none of the previous chips appear to 2101 /* OK, if we got to here, then none of the previous chips appear to
2102 be aliases for the current one. */ 2102 be aliases for the current one. */
2103 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ 2103 set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
2104 cfi->numchips++; 2104 cfi->numchips++;
2105 2105
2106ok_out: 2106ok_out:
2107 /* Put it back into Read Mode */ 2107 /* Put it back into Read Mode */
2108 jedec_reset(base, map, cfi); 2108 jedec_reset(base, map, cfi);
2109 2109
2110 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", 2110 printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
2111 map->name, cfi_interleave(cfi), cfi->device_type*8, base, 2111 map->name, cfi_interleave(cfi), cfi->device_type*8, base,
2112 map->bankwidth*8); 2112 map->bankwidth*8);
2113 2113
2114 return 1; 2114 return 1;
2115} 2115}
2116 2116
diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c
index c6c83833cc32..a611de9b1515 100644
--- a/drivers/mtd/chips/map_absent.c
+++ b/drivers/mtd/chips/map_absent.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * Common code to handle absent "placeholder" devices 2 * Common code to handle absent "placeholder" devices
3 * Copyright 2001 Resilience Corporation <ebrower@resilience.com> 3 * Copyright 2001 Resilience Corporation <ebrower@resilience.com>
4 * $Id: map_absent.c,v 1.5 2004/11/16 18:29:00 dwmw2 Exp $ 4 * $Id: map_absent.c,v 1.6 2005/11/07 11:14:23 gleixner Exp $
5 * 5 *
6 * This map driver is used to allocate "placeholder" MTD 6 * This map driver is used to allocate "placeholder" MTD
7 * devices on systems that have socketed/removable media. 7 * devices on systems that have socketed/removable media.
8 * Use of this driver as a fallback preserves the expected 8 * Use of this driver as a fallback preserves the expected
9 * registration of MTD device nodes regardless of probe outcome. 9 * registration of MTD device nodes regardless of probe outcome.
10 * A usage example is as follows: 10 * A usage example is as follows:
11 * 11 *
@@ -80,7 +80,7 @@ static int map_absent_read(struct mtd_info *mtd, loff_t from, size_t len, size_t
80static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) 80static int map_absent_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
81{ 81{
82 *retlen = 0; 82 *retlen = 0;
83 return -ENODEV; 83 return -ENODEV;
84} 84}
85 85
86static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr) 86static int map_absent_erase(struct mtd_info *mtd, struct erase_info *instr)
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
index c3cf0f63bc93..2d26bdef82d5 100644
--- a/drivers/mtd/chips/sharp.c
+++ b/drivers/mtd/chips/sharp.c
@@ -4,7 +4,7 @@
4 * Copyright 2000,2001 David A. Schleef <ds@schleef.org> 4 * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
5 * 2000,2001 Lineo, Inc. 5 * 2000,2001 Lineo, Inc.
6 * 6 *
7 * $Id: sharp.c,v 1.14 2004/08/09 13:19:43 dwmw2 Exp $ 7 * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $
8 * 8 *
9 * Devices supported: 9 * Devices supported:
10 * LH28F016SCT Symmetrical block flash memory, 2Mx8 10 * LH28F016SCT Symmetrical block flash memory, 2Mx8
@@ -31,6 +31,7 @@
31#include <linux/mtd/cfi.h> 31#include <linux/mtd/cfi.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/slab.h>
34 35
35#define CMD_RESET 0xffffffff 36#define CMD_RESET 0xffffffff
36#define CMD_READ_ID 0x90909090 37#define CMD_READ_ID 0x90909090
@@ -214,7 +215,7 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
214/* This function returns with the chip->mutex lock held. */ 215/* This function returns with the chip->mutex lock held. */
215static int sharp_wait(struct map_info *map, struct flchip *chip) 216static int sharp_wait(struct map_info *map, struct flchip *chip)
216{ 217{
217 __u16 status; 218 int status, i;
218 unsigned long timeo = jiffies + HZ; 219 unsigned long timeo = jiffies + HZ;
219 DECLARE_WAITQUEUE(wait, current); 220 DECLARE_WAITQUEUE(wait, current);
220 int adr = 0; 221 int adr = 0;
@@ -227,13 +228,11 @@ retry:
227 map_write32(map,CMD_READ_STATUS,adr); 228 map_write32(map,CMD_READ_STATUS,adr);
228 chip->state = FL_STATUS; 229 chip->state = FL_STATUS;
229 case FL_STATUS: 230 case FL_STATUS:
230 status = map_read32(map,adr); 231 for(i=0;i<100;i++){
231//printk("status=%08x\n",status); 232 status = map_read32(map,adr);
232 233 if((status & SR_READY)==SR_READY)
233 udelay(100); 234 break;
234 if((status & SR_READY)!=SR_READY){ 235 udelay(1);
235//printk(".status=%08x\n",status);
236 udelay(100);
237 } 236 }
238 break; 237 break;
239 default: 238 default:
@@ -460,12 +459,12 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip,
460 remove_wait_queue(&chip->wq, &wait); 459 remove_wait_queue(&chip->wq, &wait);
461 460
462 //spin_lock_bh(chip->mutex); 461 //spin_lock_bh(chip->mutex);
463 462
464 if (signal_pending(current)){ 463 if (signal_pending(current)){
465 ret = -EINTR; 464 ret = -EINTR;
466 goto out; 465 goto out;
467 } 466 }
468 467
469 } 468 }
470 ret = -ETIME; 469 ret = -ETIME;
471out: 470out:
@@ -564,7 +563,7 @@ static int sharp_suspend(struct mtd_info *mtd)
564static void sharp_resume(struct mtd_info *mtd) 563static void sharp_resume(struct mtd_info *mtd)
565{ 564{
566 printk("sharp_resume()\n"); 565 printk("sharp_resume()\n");
567 566
568} 567}
569 568
570static void sharp_destroy(struct mtd_info *mtd) 569static void sharp_destroy(struct mtd_info *mtd)
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index ef24837019d3..6b8bb2e4dcfd 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -1,24 +1,24 @@
1/* 1/*
2 * $Id: cmdlinepart.c,v 1.18 2005/06/07 15:04:26 joern Exp $ 2 * $Id: cmdlinepart.c,v 1.19 2005/11/07 11:14:19 gleixner Exp $
3 * 3 *
4 * Read flash partition table from command line 4 * Read flash partition table from command line
5 * 5 *
6 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 * Copyright 2002 SYSGO Real-Time Solutions GmbH
7 * 7 *
8 * The format for the command line is as follows: 8 * The format for the command line is as follows:
9 * 9 *
10 * mtdparts=<mtddef>[;<mtddef] 10 * mtdparts=<mtddef>[;<mtddef]
11 * <mtddef> := <mtd-id>:<partdef>[,<partdef>] 11 * <mtddef> := <mtd-id>:<partdef>[,<partdef>]
12 * <partdef> := <size>[@offset][<name>][ro] 12 * <partdef> := <size>[@offset][<name>][ro]
13 * <mtd-id> := unique name used in mapping driver/device (mtd->name) 13 * <mtd-id> := unique name used in mapping driver/device (mtd->name)
14 * <size> := standard linux memsize OR "-" to denote all remaining space 14 * <size> := standard linux memsize OR "-" to denote all remaining space
15 * <name> := '(' NAME ')' 15 * <name> := '(' NAME ')'
16 * 16 *
17 * Examples: 17 * Examples:
18 * 18 *
19 * 1 NOR Flash, with 1 single writable partition: 19 * 1 NOR Flash, with 1 single writable partition:
20 * edb7312-nor:- 20 * edb7312-nor:-
21 * 21 *
22 * 1 NOR Flash with 2 partitions, 1 NAND with one 22 * 1 NOR Flash with 2 partitions, 1 NAND with one
23 * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home) 23 * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
24 */ 24 */
@@ -60,17 +60,17 @@ static int cmdline_parsed = 0;
60 60
61/* 61/*
62 * Parse one partition definition for an MTD. Since there can be many 62 * Parse one partition definition for an MTD. Since there can be many
63 * comma separated partition definitions, this function calls itself 63 * comma separated partition definitions, this function calls itself
64 * recursively until no more partition definitions are found. Nice side 64 * recursively until no more partition definitions are found. Nice side
65 * effect: the memory to keep the mtd_partition structs and the names 65 * effect: the memory to keep the mtd_partition structs and the names
66 * is allocated upon the last definition being found. At that point the 66 * is allocated upon the last definition being found. At that point the
67 * syntax has been verified ok. 67 * syntax has been verified ok.
68 */ 68 */
69static struct mtd_partition * newpart(char *s, 69static struct mtd_partition * newpart(char *s,
70 char **retptr, 70 char **retptr,
71 int *num_parts, 71 int *num_parts,
72 int this_part, 72 int this_part,
73 unsigned char **extra_mem_ptr, 73 unsigned char **extra_mem_ptr,
74 int extra_mem_size) 74 int extra_mem_size)
75{ 75{
76 struct mtd_partition *parts; 76 struct mtd_partition *parts;
@@ -102,7 +102,7 @@ static struct mtd_partition * newpart(char *s,
102 mask_flags = 0; /* this is going to be a regular partition */ 102 mask_flags = 0; /* this is going to be a regular partition */
103 delim = 0; 103 delim = 0;
104 /* check for offset */ 104 /* check for offset */
105 if (*s == '@') 105 if (*s == '@')
106 { 106 {
107 s++; 107 s++;
108 offset = memparse(s, &s); 108 offset = memparse(s, &s);
@@ -112,7 +112,7 @@ static struct mtd_partition * newpart(char *s,
112 { 112 {
113 delim = ')'; 113 delim = ')';
114 } 114 }
115 115
116 if (delim) 116 if (delim)
117 { 117 {
118 char *p; 118 char *p;
@@ -131,12 +131,12 @@ static struct mtd_partition * newpart(char *s,
131 name = NULL; 131 name = NULL;
132 name_len = 13; /* Partition_000 */ 132 name_len = 13; /* Partition_000 */
133 } 133 }
134 134
135 /* record name length for memory allocation later */ 135 /* record name length for memory allocation later */
136 extra_mem_size += name_len + 1; 136 extra_mem_size += name_len + 1;
137 137
138 /* test for options */ 138 /* test for options */
139 if (strncmp(s, "ro", 2) == 0) 139 if (strncmp(s, "ro", 2) == 0)
140 { 140 {
141 mask_flags |= MTD_WRITEABLE; 141 mask_flags |= MTD_WRITEABLE;
142 s += 2; 142 s += 2;
@@ -151,7 +151,7 @@ static struct mtd_partition * newpart(char *s,
151 return NULL; 151 return NULL;
152 } 152 }
153 /* more partitions follow, parse them */ 153 /* more partitions follow, parse them */
154 if ((parts = newpart(s + 1, &s, num_parts, 154 if ((parts = newpart(s + 1, &s, num_parts,
155 this_part + 1, &extra_mem, extra_mem_size)) == 0) 155 this_part + 1, &extra_mem, extra_mem_size)) == 0)
156 return NULL; 156 return NULL;
157 } 157 }
@@ -187,7 +187,7 @@ static struct mtd_partition * newpart(char *s,
187 extra_mem += name_len + 1; 187 extra_mem += name_len + 1;
188 188
189 dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n", 189 dbg(("partition %d: name <%s>, offset %x, size %x, mask flags %x\n",
190 this_part, 190 this_part,
191 parts[this_part].name, 191 parts[this_part].name,
192 parts[this_part].offset, 192 parts[this_part].offset,
193 parts[this_part].size, 193 parts[this_part].size,
@@ -204,8 +204,8 @@ static struct mtd_partition * newpart(char *s,
204 return parts; 204 return parts;
205} 205}
206 206
207/* 207/*
208 * Parse the command line. 208 * Parse the command line.
209 */ 209 */
210static int mtdpart_setup_real(char *s) 210static int mtdpart_setup_real(char *s)
211{ 211{
@@ -230,7 +230,7 @@ static int mtdpart_setup_real(char *s)
230 230
231 dbg(("parsing <%s>\n", p+1)); 231 dbg(("parsing <%s>\n", p+1));
232 232
233 /* 233 /*
234 * parse one mtd. have it reserve memory for the 234 * parse one mtd. have it reserve memory for the
235 * struct cmdline_mtd_partition and the mtd-id string. 235 * struct cmdline_mtd_partition and the mtd-id string.
236 */ 236 */
@@ -239,7 +239,7 @@ static int mtdpart_setup_real(char *s)
239 &num_parts, /* out: number of parts */ 239 &num_parts, /* out: number of parts */
240 0, /* first partition */ 240 0, /* first partition */
241 (unsigned char**)&this_mtd, /* out: extra mem */ 241 (unsigned char**)&this_mtd, /* out: extra mem */
242 mtd_id_len + 1 + sizeof(*this_mtd) + 242 mtd_id_len + 1 + sizeof(*this_mtd) +
243 sizeof(void*)-1 /*alignment*/); 243 sizeof(void*)-1 /*alignment*/);
244 if(!parts) 244 if(!parts)
245 { 245 {
@@ -254,21 +254,21 @@ static int mtdpart_setup_real(char *s)
254 } 254 }
255 255
256 /* align this_mtd */ 256 /* align this_mtd */
257 this_mtd = (struct cmdline_mtd_partition *) 257 this_mtd = (struct cmdline_mtd_partition *)
258 ALIGN((unsigned long)this_mtd, sizeof(void*)); 258 ALIGN((unsigned long)this_mtd, sizeof(void*));
259 /* enter results */ 259 /* enter results */
260 this_mtd->parts = parts; 260 this_mtd->parts = parts;
261 this_mtd->num_parts = num_parts; 261 this_mtd->num_parts = num_parts;
262 this_mtd->mtd_id = (char*)(this_mtd + 1); 262 this_mtd->mtd_id = (char*)(this_mtd + 1);
263 strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1); 263 strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
264 264
265 /* link into chain */ 265 /* link into chain */
266 this_mtd->next = partitions; 266 this_mtd->next = partitions;
267 partitions = this_mtd; 267 partitions = this_mtd;
268 268
269 dbg(("mtdid=<%s> num_parts=<%d>\n", 269 dbg(("mtdid=<%s> num_parts=<%d>\n",
270 this_mtd->mtd_id, this_mtd->num_parts)); 270 this_mtd->mtd_id, this_mtd->num_parts));
271 271
272 272
273 /* EOS - we're done */ 273 /* EOS - we're done */
274 if (*s == 0) 274 if (*s == 0)
@@ -292,7 +292,7 @@ static int mtdpart_setup_real(char *s)
292 * information. It returns partitions for the requested mtd device, or 292 * information. It returns partitions for the requested mtd device, or
293 * the first one in the chain if a NULL mtd_id is passed in. 293 * the first one in the chain if a NULL mtd_id is passed in.
294 */ 294 */
295static int parse_cmdline_partitions(struct mtd_info *master, 295static int parse_cmdline_partitions(struct mtd_info *master,
296 struct mtd_partition **pparts, 296 struct mtd_partition **pparts,
297 unsigned long origin) 297 unsigned long origin)
298{ 298{
@@ -322,7 +322,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,
322 part->parts[i].size = master->size - offset; 322 part->parts[i].size = master->size - offset;
323 if (offset + part->parts[i].size > master->size) 323 if (offset + part->parts[i].size > master->size)
324 { 324 {
325 printk(KERN_WARNING ERRP 325 printk(KERN_WARNING ERRP
326 "%s: partitioning exceeds flash size, truncating\n", 326 "%s: partitioning exceeds flash size, truncating\n",
327 part->mtd_id); 327 part->mtd_id);
328 part->parts[i].size = master->size - offset; 328 part->parts[i].size = master->size - offset;
@@ -338,8 +338,8 @@ static int parse_cmdline_partitions(struct mtd_info *master,
338} 338}
339 339
340 340
341/* 341/*
342 * This is the handler for our kernel parameter, called from 342 * This is the handler for our kernel parameter, called from
343 * main.c::checksetup(). Note that we can not yet kmalloc() anything, 343 * main.c::checksetup(). Note that we can not yet kmalloc() anything,
344 * so we only save the commandline for later processing. 344 * so we only save the commandline for later processing.
345 * 345 *
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index c4a56a4ac5e2..9a2aa4033c6a 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/maps/Kconfig 1# drivers/mtd/maps/Kconfig
2# $Id: Kconfig,v 1.15 2004/12/22 17:51:15 joern Exp $ 2# $Id: Kconfig,v 1.18 2005/11/07 11:14:24 gleixner Exp $
3 3
4menu "Self-contained MTD device drivers" 4menu "Self-contained MTD device drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -110,7 +110,7 @@ config MTDRAM_ABS_POS
110 If you have system RAM accessible by the CPU but not used by Linux 110 If you have system RAM accessible by the CPU but not used by Linux
111 in normal operation, you can give the physical address at which the 111 in normal operation, you can give the physical address at which the
112 available RAM starts, and the MTDRAM driver will use it instead of 112 available RAM starts, and the MTDRAM driver will use it instead of
113 allocating space from Linux's available memory. Otherwise, leave 113 allocating space from Linux's available memory. Otherwise, leave
114 this set to zero. Most people will want to leave this as zero. 114 this set to zero. Most people will want to leave this as zero.
115 115
116config MTD_BLKMTD 116config MTD_BLKMTD
@@ -165,7 +165,7 @@ config MTD_DOC2001
165 select MTD_DOCPROBE 165 select MTD_DOCPROBE
166 select MTD_NAND_IDS 166 select MTD_NAND_IDS
167 ---help--- 167 ---help---
168 This provides an alternative MTD device driver for the M-Systems 168 This provides an alternative MTD device driver for the M-Systems
169 DiskOnChip Millennium devices. Use this if you have problems with 169 DiskOnChip Millennium devices. Use this if you have problems with
170 the combined DiskOnChip 2000 and Millennium driver above. To get 170 the combined DiskOnChip 2000 and Millennium driver above. To get
171 the DiskOnChip probe code to load and use this driver instead of 171 the DiskOnChip probe code to load and use this driver instead of
@@ -192,7 +192,7 @@ config MTD_DOC2001PLUS
192 192
193 If you use this device, you probably also want to enable the INFTL 193 If you use this device, you probably also want to enable the INFTL
194 'Inverse NAND Flash Translation Layer' option below, which is used 194 'Inverse NAND Flash Translation Layer' option below, which is used
195 to emulate a block device by using a kind of file system on the 195 to emulate a block device by using a kind of file system on the
196 flash chips. 196 flash chips.
197 197
198 NOTE: This driver will soon be replaced by the new DiskOnChip driver 198 NOTE: This driver will soon be replaced by the new DiskOnChip driver
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index 662e807801ed..f9db52f6bf00 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: blkmtd.c,v 1.24 2004/11/16 18:29:01 dwmw2 Exp $ 2 * $Id: blkmtd.c,v 1.27 2005/11/07 11:14:24 gleixner Exp $
3 * 3 *
4 * blkmtd.c - use a block device as a fake MTD 4 * blkmtd.c - use a block device as a fake MTD
5 * 5 *
@@ -39,7 +39,7 @@
39 39
40/* Default erase size in K, always make it a multiple of PAGE_SIZE */ 40/* Default erase size in K, always make it a multiple of PAGE_SIZE */
41#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */ 41#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */
42#define VERSION "$Revision: 1.24 $" 42#define VERSION "$Revision: 1.27 $"
43 43
44/* Info for the block device */ 44/* Info for the block device */
45struct blkmtd_dev { 45struct blkmtd_dev {
@@ -117,7 +117,7 @@ static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error
117 unlock_page(page); 117 unlock_page(page);
118 page_cache_release(page); 118 page_cache_release(page);
119 } while (bvec >= bio->bi_io_vec); 119 } while (bvec >= bio->bi_io_vec);
120 120
121 complete((struct completion*)bio->bi_private); 121 complete((struct completion*)bio->bi_private);
122 return 0; 122 return 0;
123} 123}
@@ -135,7 +135,7 @@ static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page)
135 unlock_page(page); 135 unlock_page(page);
136 return 0; 136 return 0;
137 } 137 }
138 138
139 ClearPageUptodate(page); 139 ClearPageUptodate(page);
140 ClearPageError(page); 140 ClearPageError(page);
141 141
@@ -539,11 +539,8 @@ static void free_device(struct blkmtd_dev *dev)
539{ 539{
540 DEBUG(2, "blkmtd: free_device() dev = %p\n", dev); 540 DEBUG(2, "blkmtd: free_device() dev = %p\n", dev);
541 if(dev) { 541 if(dev) {
542 if(dev->mtd_info.eraseregions) 542 kfree(dev->mtd_info.eraseregions);
543 kfree(dev->mtd_info.eraseregions); 543 kfree(dev->mtd_info.name);
544 if(dev->mtd_info.name)
545 kfree(dev->mtd_info.name);
546
547 if(dev->blkdev) { 544 if(dev->blkdev) {
548 invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping); 545 invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping);
549 close_bdev_excl(dev->blkdev); 546 close_bdev_excl(dev->blkdev);
@@ -710,7 +707,7 @@ static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size
710 dev->mtd_info.erasesize >> 10, 707 dev->mtd_info.erasesize >> 10,
711 readonly ? "(read-only)" : ""); 708 readonly ? "(read-only)" : "");
712 } 709 }
713 710
714 return dev; 711 return dev;
715 712
716 devinit_err: 713 devinit_err:
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 4a7a805e7564..0aaa0ced9aba 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: block2mtd.c,v 1.28 2005/03/19 22:40:44 gleixner Exp $ 2 * $Id: block2mtd.c,v 1.29 2005/11/07 11:14:24 gleixner Exp $
3 * 3 *
4 * block2mtd.c - create an mtd from a block device 4 * block2mtd.c - create an mtd from a block device
5 * 5 *
@@ -19,7 +19,7 @@
19#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
20#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
21 21
22#define VERSION "$Revision: 1.28 $" 22#define VERSION "$Revision: 1.29 $"
23 23
24 24
25#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) 25#define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
@@ -111,7 +111,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
111 return PTR_ERR(page); 111 return PTR_ERR(page);
112 112
113 max = (u_long*)page_address(page) + PAGE_SIZE; 113 max = (u_long*)page_address(page) + PAGE_SIZE;
114 for (p=(u_long*)page_address(page); p<max; p++) 114 for (p=(u_long*)page_address(page); p<max; p++)
115 if (*p != -1UL) { 115 if (*p != -1UL) {
116 lock_page(page); 116 lock_page(page);
117 memset(page_address(page), 0xff, PAGE_SIZE); 117 memset(page_address(page), 0xff, PAGE_SIZE);
@@ -206,7 +206,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
206 if (retlen) 206 if (retlen)
207 *retlen = 0; 207 *retlen = 0;
208 while (len) { 208 while (len) {
209 if ((offset+len) > PAGE_SIZE) 209 if ((offset+len) > PAGE_SIZE)
210 cpylen = PAGE_SIZE - offset; // multiple pages 210 cpylen = PAGE_SIZE - offset; // multiple pages
211 else 211 else
212 cpylen = len; // this page 212 cpylen = len; // this page
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 5fc532895a24..be5e88b3888d 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -4,7 +4,7 @@
4 * (c) 1999 Machine Vision Holdings, Inc. 4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6 * 6 *
7 * $Id: doc2000.c,v 1.66 2005/01/05 18:05:12 dwmw2 Exp $ 7 * $Id: doc2000.c,v 1.67 2005/11/07 11:14:24 gleixner Exp $
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -58,7 +58,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
58 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 58 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
59static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 59static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
60 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 60 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
61static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 61static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
62 unsigned long count, loff_t to, size_t *retlen, 62 unsigned long count, loff_t to, size_t *retlen,
63 u_char *eccbuf, struct nand_oobinfo *oobsel); 63 u_char *eccbuf, struct nand_oobinfo *oobsel);
64static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 64static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
@@ -76,14 +76,14 @@ static void DoC_Delay(struct DiskOnChip *doc, unsigned short cycles)
76{ 76{
77 volatile char dummy; 77 volatile char dummy;
78 int i; 78 int i;
79 79
80 for (i = 0; i < cycles; i++) { 80 for (i = 0; i < cycles; i++) {
81 if (DoC_is_Millennium(doc)) 81 if (DoC_is_Millennium(doc))
82 dummy = ReadDOC(doc->virtadr, NOP); 82 dummy = ReadDOC(doc->virtadr, NOP);
83 else 83 else
84 dummy = ReadDOC(doc->virtadr, DOCStatus); 84 dummy = ReadDOC(doc->virtadr, DOCStatus);
85 } 85 }
86 86
87} 87}
88 88
89/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */ 89/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
@@ -220,8 +220,8 @@ static int DoC_Address(struct DiskOnChip *doc, int numbytes, unsigned long ofs,
220 WriteDOC(ofs & 0xff, docptr, WritePipeTerm); 220 WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
221 221
222 DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */ 222 DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
223 223
224 /* FIXME: The SlowIO's for millennium could be replaced by 224 /* FIXME: The SlowIO's for millennium could be replaced by
225 a single WritePipeTerm here. mf. */ 225 a single WritePipeTerm here. mf. */
226 226
227 /* Lower the ALE line */ 227 /* Lower the ALE line */
@@ -377,9 +377,9 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
377 if (mfr == 0xff || mfr == 0) 377 if (mfr == 0xff || mfr == 0)
378 return 0; 378 return 0;
379 379
380 /* Check it's the same as the first chip we identified. 380 /* Check it's the same as the first chip we identified.
381 * M-Systems say that any given DiskOnChip device should only 381 * M-Systems say that any given DiskOnChip device should only
382 * contain _one_ type of flash part, although that's not a 382 * contain _one_ type of flash part, although that's not a
383 * hardware restriction. */ 383 * hardware restriction. */
384 if (doc->mfr) { 384 if (doc->mfr) {
385 if (doc->mfr == mfr && doc->id == id) 385 if (doc->mfr == mfr && doc->id == id)
@@ -397,7 +397,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
397 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { 397 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
398 if (nand_manuf_ids[j].id == mfr) 398 if (nand_manuf_ids[j].id == mfr)
399 break; 399 break;
400 } 400 }
401 printk(KERN_INFO 401 printk(KERN_INFO
402 "Flash chip found: Manufacturer ID: %2.2X, " 402 "Flash chip found: Manufacturer ID: %2.2X, "
403 "Chip ID: %2.2X (%s:%s)\n", mfr, id, 403 "Chip ID: %2.2X (%s:%s)\n", mfr, id,
@@ -405,7 +405,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
405 if (!doc->mfr) { 405 if (!doc->mfr) {
406 doc->mfr = mfr; 406 doc->mfr = mfr;
407 doc->id = id; 407 doc->id = id;
408 doc->chipshift = 408 doc->chipshift =
409 ffs((nand_flash_ids[i].chipsize << 20)) - 1; 409 ffs((nand_flash_ids[i].chipsize << 20)) - 1;
410 doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0; 410 doc->page256 = (nand_flash_ids[i].pagesize == 256) ? 1 : 0;
411 doc->pageadrlen = doc->chipshift > 25 ? 3 : 2; 411 doc->pageadrlen = doc->chipshift > 25 ? 3 : 2;
@@ -467,7 +467,7 @@ static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
467 467
468 ret = 0; 468 ret = 0;
469 469
470 /* Fill out the chip array with {floor, chipno} for each 470 /* Fill out the chip array with {floor, chipno} for each
471 * detected chip in the device. */ 471 * detected chip in the device. */
472 for (floor = 0; floor < MAX_FLOORS; floor++) { 472 for (floor = 0; floor < MAX_FLOORS; floor++) {
473 for (chip = 0; chip < numchips[floor]; chip++) { 473 for (chip = 0; chip < numchips[floor]; chip++) {
@@ -757,12 +757,12 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
757 (long)from, eccbuf[0], eccbuf[1], eccbuf[2], 757 (long)from, eccbuf[0], eccbuf[1], eccbuf[2],
758 eccbuf[3], eccbuf[4], eccbuf[5]); 758 eccbuf[3], eccbuf[4], eccbuf[5]);
759#endif 759#endif
760 760
761 /* disable the ECC engine */ 761 /* disable the ECC engine */
762 WriteDOC(DOC_ECC_DIS, docptr , ECCConf); 762 WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
763 } 763 }
764 764
765 /* according to 11.4.1, we need to wait for the busy line 765 /* according to 11.4.1, we need to wait for the busy line
766 * drop if we read to the end of the page. */ 766 * drop if we read to the end of the page. */
767 if(0 == ((from + len) & 0x1ff)) 767 if(0 == ((from + len) & 0x1ff))
768 { 768 {
@@ -941,7 +941,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
941 941
942 /* Let the caller know we completed it */ 942 /* Let the caller know we completed it */
943 *retlen += len; 943 *retlen += len;
944 944
945 if (eccbuf) { 945 if (eccbuf) {
946 unsigned char x[8]; 946 unsigned char x[8];
947 size_t dummy; 947 size_t dummy;
@@ -950,10 +950,10 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
950 /* Write the ECC data to flash */ 950 /* Write the ECC data to flash */
951 for (di=0; di<6; di++) 951 for (di=0; di<6; di++)
952 x[di] = eccbuf[di]; 952 x[di] = eccbuf[di];
953 953
954 x[6]=0x55; 954 x[6]=0x55;
955 x[7]=0x55; 955 x[7]=0x55;
956 956
957 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x); 957 ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
958 if (ret) { 958 if (ret) {
959 up(&this->lock); 959 up(&this->lock);
@@ -970,7 +970,7 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
970 return 0; 970 return 0;
971} 971}
972 972
973static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 973static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
974 unsigned long count, loff_t to, size_t *retlen, 974 unsigned long count, loff_t to, size_t *retlen,
975 u_char *eccbuf, struct nand_oobinfo *oobsel) 975 u_char *eccbuf, struct nand_oobinfo *oobsel)
976{ 976{
@@ -1022,7 +1022,7 @@ static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
1022 break; 1022 break;
1023 1023
1024 to += thislen; 1024 to += thislen;
1025 } 1025 }
1026 1026
1027 up(&writev_buf_sem); 1027 up(&writev_buf_sem);
1028 *retlen = totretlen; 1028 *retlen = totretlen;
@@ -1080,7 +1080,7 @@ static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1080 /* Reading the full OOB data drops us off of the end of the page, 1080 /* Reading the full OOB data drops us off of the end of the page,
1081 * causing the flash device to go into busy mode, so we need 1081 * causing the flash device to go into busy mode, so we need
1082 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */ 1082 * to wait until ready 11.4.1 and Toshiba TC58256FT docs */
1083 1083
1084 ret = DoC_WaitReady(this); 1084 ret = DoC_WaitReady(this);
1085 1085
1086 up(&this->lock); 1086 up(&this->lock);
@@ -1190,7 +1190,7 @@ static int doc_write_oob_nolock(struct mtd_info *mtd, loff_t ofs, size_t len,
1190 return 0; 1190 return 0;
1191 1191
1192} 1192}
1193 1193
1194static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 1194static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1195 size_t * retlen, const u_char * buf) 1195 size_t * retlen, const u_char * buf)
1196{ 1196{
@@ -1222,7 +1222,7 @@ static int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1222 } 1222 }
1223 1223
1224 instr->state = MTD_ERASING; 1224 instr->state = MTD_ERASING;
1225 1225
1226 /* FIXME: Do this in the background. Use timers or schedule_task() */ 1226 /* FIXME: Do this in the background. Use timers or schedule_task() */
1227 while(len) { 1227 while(len) {
1228 mychip = &this->chips[ofs >> this->chipshift]; 1228 mychip = &this->chips[ofs >> this->chipshift];
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index 1e704915ef08..fcb28a6fd89f 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -4,7 +4,7 @@
4 * (c) 1999 Machine Vision Holdings, Inc. 4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6 * 6 *
7 * $Id: doc2001.c,v 1.48 2005/01/05 18:05:12 dwmw2 Exp $ 7 * $Id: doc2001.c,v 1.49 2005/11/07 11:14:24 gleixner Exp $
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -196,10 +196,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
196 DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP); 196 DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
197 DoC_WaitReady(doc->virtadr); 197 DoC_WaitReady(doc->virtadr);
198 198
199 /* Read the NAND chip ID: 1. Send ReadID command */ 199 /* Read the NAND chip ID: 1. Send ReadID command */
200 DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP); 200 DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
201 201
202 /* Read the NAND chip ID: 2. Send address byte zero */ 202 /* Read the NAND chip ID: 2. Send address byte zero */
203 DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00); 203 DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
204 204
205 /* Read the manufacturer and device id codes of the flash device through 205 /* Read the manufacturer and device id codes of the flash device through
@@ -223,7 +223,7 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
223 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { 223 for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
224 if (nand_manuf_ids[j].id == mfr) 224 if (nand_manuf_ids[j].id == mfr)
225 break; 225 break;
226 } 226 }
227 printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, " 227 printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
228 "Chip ID: %2.2X (%s:%s)\n", 228 "Chip ID: %2.2X (%s:%s)\n",
229 mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name); 229 mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name);
@@ -275,7 +275,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
275 return; 275 return;
276 } 276 }
277 277
278 /* Fill out the chip array with {floor, chipno} for each 278 /* Fill out the chip array with {floor, chipno} for each
279 * detected chip in the device. */ 279 * detected chip in the device. */
280 for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) { 280 for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
281 for (chip = 0 ; chip < numchips[floor] ; chip++) { 281 for (chip = 0 ; chip < numchips[floor] ; chip++) {
@@ -309,7 +309,7 @@ static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
309 tmp2 = ReadDOC(doc2->virtadr, AliasResolution); 309 tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
310 if (tmp1 != tmp2) 310 if (tmp1 != tmp2)
311 return 0; 311 return 0;
312 312
313 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution); 313 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution);
314 tmp2 = ReadDOC(doc2->virtadr, AliasResolution); 314 tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
315 if (tmp2 == (tmp1+1) % 0xff) 315 if (tmp2 == (tmp1+1) % 0xff)
@@ -425,7 +425,7 @@ static int doc_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
425 return -EINVAL; 425 return -EINVAL;
426 426
427 /* Don't allow a single read to cross a 512-byte block boundary */ 427 /* Don't allow a single read to cross a 512-byte block boundary */
428 if (from + len > ((from | 0x1ff) + 1)) 428 if (from + len > ((from | 0x1ff) + 1))
429 len = ((from | 0x1ff) + 1) - from; 429 len = ((from | 0x1ff) + 1) - from;
430 430
431 /* Find the chip which is to be used and select it */ 431 /* Find the chip which is to be used and select it */
@@ -552,7 +552,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
552 552
553#if 0 553#if 0
554 /* Don't allow a single write to cross a 512-byte block boundary */ 554 /* Don't allow a single write to cross a 512-byte block boundary */
555 if (to + len > ( (to | 0x1ff) + 1)) 555 if (to + len > ( (to | 0x1ff) + 1))
556 len = ((to | 0x1ff) + 1) - to; 556 len = ((to | 0x1ff) + 1) - to;
557#else 557#else
558 /* Don't allow writes which aren't exactly one block */ 558 /* Don't allow writes which aren't exactly one block */
@@ -632,7 +632,7 @@ static int doc_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
632 632
633 /* write the block status BLOCK_USED (0x5555) at the end of ECC data 633 /* write the block status BLOCK_USED (0x5555) at the end of ECC data
634 FIXME: this is only a hack for programming the IPL area for LinuxBIOS 634 FIXME: this is only a hack for programming the IPL area for LinuxBIOS
635 and should be replace with proper codes in user space utilities */ 635 and should be replace with proper codes in user space utilities */
636 WriteDOC(0x55, docptr, Mil_CDSN_IO); 636 WriteDOC(0x55, docptr, Mil_CDSN_IO);
637 WriteDOC(0x55, docptr, Mil_CDSN_IO + 1); 637 WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
638 638
@@ -802,7 +802,7 @@ int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
802 void __iomem *docptr = this->virtadr; 802 void __iomem *docptr = this->virtadr;
803 struct Nand *mychip = &this->chips[ofs >> this->chipshift]; 803 struct Nand *mychip = &this->chips[ofs >> this->chipshift];
804 804
805 if (len != mtd->erasesize) 805 if (len != mtd->erasesize)
806 printk(KERN_WARNING "Erase not right size (%x != %x)n", 806 printk(KERN_WARNING "Erase not right size (%x != %x)n",
807 len, mtd->erasesize); 807 len, mtd->erasesize);
808 808
@@ -870,9 +870,9 @@ static void __exit cleanup_doc2001(void)
870 while ((mtd=docmillist)) { 870 while ((mtd=docmillist)) {
871 this = mtd->priv; 871 this = mtd->priv;
872 docmillist = this->nextdoc; 872 docmillist = this->nextdoc;
873 873
874 del_mtd_device(mtd); 874 del_mtd_device(mtd);
875 875
876 iounmap(this->virtadr); 876 iounmap(this->virtadr);
877 kfree(this->chips); 877 kfree(this->chips);
878 kfree(mtd); 878 kfree(mtd);
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index ed47bafb2ce2..0595cc7324b2 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -6,7 +6,7 @@
6 * (c) 1999 Machine Vision Holdings, Inc. 6 * (c) 1999 Machine Vision Holdings, Inc.
7 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> 7 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
8 * 8 *
9 * $Id: doc2001plus.c,v 1.13 2005/01/05 18:05:12 dwmw2 Exp $ 9 * $Id: doc2001plus.c,v 1.14 2005/11/07 11:14:24 gleixner Exp $
10 * 10 *
11 * Released under GPL 11 * Released under GPL
12 */ 12 */
@@ -293,10 +293,10 @@ static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
293 DoC_Command(docptr, NAND_CMD_RESET, 0); 293 DoC_Command(docptr, NAND_CMD_RESET, 0);
294 DoC_WaitReady(docptr); 294 DoC_WaitReady(docptr);
295 295
296 /* Read the NAND chip ID: 1. Send ReadID command */ 296 /* Read the NAND chip ID: 1. Send ReadID command */
297 DoC_Command(docptr, NAND_CMD_READID, 0); 297 DoC_Command(docptr, NAND_CMD_READID, 0);
298 298
299 /* Read the NAND chip ID: 2. Send address byte zero */ 299 /* Read the NAND chip ID: 2. Send address byte zero */
300 DoC_Address(doc, 1, 0x00, 0, 0x00); 300 DoC_Address(doc, 1, 0x00, 0, 0x00);
301 301
302 WriteDOC(0, docptr, Mplus_FlashControl); 302 WriteDOC(0, docptr, Mplus_FlashControl);
@@ -365,7 +365,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
365 this->interleave = 1; 365 this->interleave = 1;
366 366
367 /* Check the ASIC agrees */ 367 /* Check the ASIC agrees */
368 if ( (this->interleave << 2) != 368 if ( (this->interleave << 2) !=
369 (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) { 369 (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
370 u_char conf = ReadDOC(this->virtadr, Mplus_Configuration); 370 u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
371 printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n", 371 printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
@@ -398,7 +398,7 @@ static void DoC_ScanChips(struct DiskOnChip *this)
398 return; 398 return;
399 } 399 }
400 400
401 /* Fill out the chip array with {floor, chipno} for each 401 /* Fill out the chip array with {floor, chipno} for each
402 * detected chip in the device. */ 402 * detected chip in the device. */
403 for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) { 403 for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
404 for (chip = 0 ; chip < numchips[floor] ; chip++) { 404 for (chip = 0 ; chip < numchips[floor] ; chip++) {
@@ -432,7 +432,7 @@ static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
432 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); 432 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
433 if (tmp1 != tmp2) 433 if (tmp1 != tmp2)
434 return 0; 434 return 0;
435 435
436 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution); 436 WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
437 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution); 437 tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
438 if (tmp2 == (tmp1+1) % 0xff) 438 if (tmp2 == (tmp1+1) % 0xff)
@@ -624,7 +624,7 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
624 return -EINVAL; 624 return -EINVAL;
625 625
626 /* Don't allow a single read to cross a 512-byte block boundary */ 626 /* Don't allow a single read to cross a 512-byte block boundary */
627 if (from + len > ((from | 0x1ff) + 1)) 627 if (from + len > ((from | 0x1ff) + 1))
628 len = ((from | 0x1ff) + 1) - from; 628 len = ((from | 0x1ff) + 1) - from;
629 629
630 DoC_CheckASIC(docptr); 630 DoC_CheckASIC(docptr);
@@ -1066,7 +1066,7 @@ int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
1066 1066
1067 DoC_CheckASIC(docptr); 1067 DoC_CheckASIC(docptr);
1068 1068
1069 if (len != mtd->erasesize) 1069 if (len != mtd->erasesize)
1070 printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n", 1070 printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
1071 len, mtd->erasesize); 1071 len, mtd->erasesize);
1072 1072
@@ -1136,9 +1136,9 @@ static void __exit cleanup_doc2001plus(void)
1136 while ((mtd=docmilpluslist)) { 1136 while ((mtd=docmilpluslist)) {
1137 this = mtd->priv; 1137 this = mtd->priv;
1138 docmilpluslist = this->nextdoc; 1138 docmilpluslist = this->nextdoc;
1139 1139
1140 del_mtd_device(mtd); 1140 del_mtd_device(mtd);
1141 1141
1142 iounmap(this->virtadr); 1142 iounmap(this->virtadr);
1143 kfree(this->chips); 1143 kfree(this->chips);
1144 kfree(mtd); 1144 kfree(mtd);
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
index 24f670b5a4f3..cd3db72bef96 100644
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -4,10 +4,10 @@
4 * GNU GPL License. The rest is simply to convert the disk on chip 4 * GNU GPL License. The rest is simply to convert the disk on chip
5 * syndrom into a standard syndom. 5 * syndrom into a standard syndom.
6 * 6 *
7 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 7 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
8 * Copyright (C) 2000 Netgem S.A. 8 * Copyright (C) 2000 Netgem S.A.
9 * 9 *
10 * $Id: docecc.c,v 1.5 2003/05/21 15:15:06 dwmw2 Exp $ 10 * $Id: docecc.c,v 1.7 2005/11/07 11:14:25 gleixner Exp $
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
@@ -122,7 +122,7 @@ for(ci=(n)-1;ci >=0;ci--)\
122 a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1) 122 a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
123 we consider the integer "i" whose binary representation with a(0) being LSB 123 we consider the integer "i" whose binary representation with a(0) being LSB
124 and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry 124 and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
125 "index_of[i]". Now, @^index_of[i] is that element whose polynomial 125 "index_of[i]". Now, @^index_of[i] is that element whose polynomial
126 representation is (a(0),a(1),a(2),...,a(m-1)). 126 representation is (a(0),a(1),a(2),...,a(m-1)).
127 NOTE: 127 NOTE:
128 The element alpha_to[2^m-1] = 0 always signifying that the 128 The element alpha_to[2^m-1] = 0 always signifying that the
@@ -130,7 +130,7 @@ for(ci=(n)-1;ci >=0;ci--)\
130 Similarily, the element index_of[0] = A0 always signifying 130 Similarily, the element index_of[0] = A0 always signifying
131 that the power of alpha which has the polynomial representation 131 that the power of alpha which has the polynomial representation
132 (0,0,...,0) is "infinity". 132 (0,0,...,0) is "infinity".
133 133
134*/ 134*/
135 135
136static void 136static void
@@ -176,7 +176,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
176 * are written back. NOTE! This array must be at least NN-KK elements long. 176 * are written back. NOTE! This array must be at least NN-KK elements long.
177 * The corrected data are written in eras_val[]. They must be xor with the data 177 * The corrected data are written in eras_val[]. They must be xor with the data
178 * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] . 178 * to retrieve the correct data : data[erase_pos[i]] ^= erase_val[i] .
179 * 179 *
180 * First "no_eras" erasures are declared by the calling program. Then, the 180 * First "no_eras" erasures are declared by the calling program. Then, the
181 * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2). 181 * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
182 * If the number of channel errors is not greater than "t_after_eras" the 182 * If the number of channel errors is not greater than "t_after_eras" the
@@ -189,7 +189,7 @@ generate_gf(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1])
189 * */ 189 * */
190static int 190static int
191eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1], 191eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
192 gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK], 192 gf bb[NN - KK + 1], gf eras_val[NN-KK], int eras_pos[NN-KK],
193 int no_eras) 193 int no_eras)
194{ 194{
195 int deg_lambda, el, deg_omega; 195 int deg_lambda, el, deg_omega;
@@ -212,7 +212,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
212 count = 0; 212 count = 0;
213 goto finish; 213 goto finish;
214 } 214 }
215 215
216 for(i=1;i<=NN-KK;i++){ 216 for(i=1;i<=NN-KK;i++){
217 s[i] = bb[0]; 217 s[i] = bb[0];
218 } 218 }
@@ -220,7 +220,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
220 if(bb[j] == 0) 220 if(bb[j] == 0)
221 continue; 221 continue;
222 tmp = Index_of[bb[j]]; 222 tmp = Index_of[bb[j]];
223 223
224 for(i=1;i<=NN-KK;i++) 224 for(i=1;i<=NN-KK;i++)
225 s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)]; 225 s[i] ^= Alpha_to[modnn(tmp + (B0+i-1)*PRIM*j)];
226 } 226 }
@@ -234,7 +234,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
234 tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM); 234 tmp = modnn(tmp + 2 * KK * (B0+i-1)*PRIM);
235 s[i] = tmp; 235 s[i] = tmp;
236 } 236 }
237 237
238 CLEAR(&lambda[1],NN-KK); 238 CLEAR(&lambda[1],NN-KK);
239 lambda[0] = 1; 239 lambda[0] = 1;
240 240
@@ -252,7 +252,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
252#if DEBUG_ECC >= 1 252#if DEBUG_ECC >= 1
253 /* Test code that verifies the erasure locator polynomial just constructed 253 /* Test code that verifies the erasure locator polynomial just constructed
254 Needed only for decoder debugging. */ 254 Needed only for decoder debugging. */
255 255
256 /* find roots of the erasure location polynomial */ 256 /* find roots of the erasure location polynomial */
257 for(i=1;i<=no_eras;i++) 257 for(i=1;i<=no_eras;i++)
258 reg[i] = Index_of[lambda[i]]; 258 reg[i] = Index_of[lambda[i]];
@@ -286,7 +286,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
286 } 286 }
287 for(i=0;i<NN-KK+1;i++) 287 for(i=0;i<NN-KK+1;i++)
288 b[i] = Index_of[lambda[i]]; 288 b[i] = Index_of[lambda[i]];
289 289
290 /* 290 /*
291 * Begin Berlekamp-Massey algorithm to determine error+erasure 291 * Begin Berlekamp-Massey algorithm to determine error+erasure
292 * locator polynomial 292 * locator polynomial
@@ -389,7 +389,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
389 omega[i] = Index_of[tmp]; 389 omega[i] = Index_of[tmp];
390 } 390 }
391 omega[NN-KK] = A0; 391 omega[NN-KK] = A0;
392 392
393 /* 393 /*
394 * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = 394 * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
395 * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form 395 * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
@@ -402,7 +402,7 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
402 } 402 }
403 num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)]; 403 num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)];
404 den = 0; 404 den = 0;
405 405
406 /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ 406 /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
407 for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) { 407 for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) {
408 if(lambda[i+1] != A0) 408 if(lambda[i+1] != A0)
@@ -436,11 +436,11 @@ eras_dec_rs(dtype Alpha_to[NN + 1], dtype Index_of[NN + 1],
436/* The sector bytes are packed into NB_DATA MM bits words */ 436/* The sector bytes are packed into NB_DATA MM bits words */
437#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM) 437#define NB_DATA (((SECTOR_SIZE + 1) * 8 + 6) / MM)
438 438
439/* 439/*
440 * Correct the errors in 'sector[]' by using 'ecc1[]' which is the 440 * Correct the errors in 'sector[]' by using 'ecc1[]' which is the
441 * content of the feedback shift register applyied to the sector and 441 * content of the feedback shift register applyied to the sector and
442 * the ECC. Return the number of errors corrected (and correct them in 442 * the ECC. Return the number of errors corrected (and correct them in
443 * sector), or -1 if error 443 * sector), or -1 if error
444 */ 444 */
445int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6]) 445int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
446{ 446{
@@ -454,7 +454,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
454 Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL); 454 Alpha_to = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
455 if (!Alpha_to) 455 if (!Alpha_to)
456 return -1; 456 return -1;
457 457
458 Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL); 458 Index_of = kmalloc((NN + 1) * sizeof(dtype), GFP_KERNEL);
459 if (!Index_of) { 459 if (!Index_of) {
460 kfree(Alpha_to); 460 kfree(Alpha_to);
@@ -470,7 +470,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
470 bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4); 470 bb[2] = ((ecc1[2] & 0xf0) >> 4) | ((ecc1[3] & 0x3f) << 4);
471 bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2); 471 bb[3] = ((ecc1[3] & 0xc0) >> 6) | ((ecc1[0] & 0xff) << 2);
472 472
473 nb_errors = eras_dec_rs(Alpha_to, Index_of, bb, 473 nb_errors = eras_dec_rs(Alpha_to, Index_of, bb,
474 error_val, error_pos, 0); 474 error_val, error_pos, 0);
475 if (nb_errors <= 0) 475 if (nb_errors <= 0)
476 goto the_end; 476 goto the_end;
@@ -489,7 +489,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
489 can be modified since pos is even */ 489 can be modified since pos is even */
490 index = (pos >> 3) ^ 1; 490 index = (pos >> 3) ^ 1;
491 bitpos = pos & 7; 491 bitpos = pos & 7;
492 if ((index >= 0 && index < SECTOR_SIZE) || 492 if ((index >= 0 && index < SECTOR_SIZE) ||
493 index == (SECTOR_SIZE + 1)) { 493 index == (SECTOR_SIZE + 1)) {
494 val = error_val[i] >> (2 + bitpos); 494 val = error_val[i] >> (2 + bitpos);
495 parity ^= val; 495 parity ^= val;
@@ -500,7 +500,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
500 bitpos = (bitpos + 10) & 7; 500 bitpos = (bitpos + 10) & 7;
501 if (bitpos == 0) 501 if (bitpos == 0)
502 bitpos = 8; 502 bitpos = 8;
503 if ((index >= 0 && index < SECTOR_SIZE) || 503 if ((index >= 0 && index < SECTOR_SIZE) ||
504 index == (SECTOR_SIZE + 1)) { 504 index == (SECTOR_SIZE + 1)) {
505 val = error_val[i] << (8 - bitpos); 505 val = error_val[i] << (8 - bitpos);
506 parity ^= val; 506 parity ^= val;
@@ -509,7 +509,7 @@ int doc_decode_ecc(unsigned char sector[SECTOR_SIZE], unsigned char ecc1[6])
509 } 509 }
510 } 510 }
511 } 511 }
512 512
513 /* use parity to test extra errors */ 513 /* use parity to test extra errors */
514 if ((parity & 0xff) != 0) 514 if ((parity & 0xff) != 0)
515 nb_errors = -1; 515 nb_errors = -1;
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c
index 197d67045e1e..13178b9dd00a 100644
--- a/drivers/mtd/devices/docprobe.c
+++ b/drivers/mtd/devices/docprobe.c
@@ -4,22 +4,22 @@
4/* (C) 1999 Machine Vision Holdings, Inc. */ 4/* (C) 1999 Machine Vision Holdings, Inc. */
5/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */ 5/* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */
6 6
7/* $Id: docprobe.c,v 1.44 2005/01/05 12:40:36 dwmw2 Exp $ */ 7/* $Id: docprobe.c,v 1.46 2005/11/07 11:14:25 gleixner Exp $ */
8 8
9 9
10 10
11/* DOC_PASSIVE_PROBE: 11/* DOC_PASSIVE_PROBE:
12 In order to ensure that the BIOS checksum is correct at boot time, and 12 In order to ensure that the BIOS checksum is correct at boot time, and
13 hence that the onboard BIOS extension gets executed, the DiskOnChip 13 hence that the onboard BIOS extension gets executed, the DiskOnChip
14 goes into reset mode when it is read sequentially: all registers 14 goes into reset mode when it is read sequentially: all registers
15 return 0xff until the chip is woken up again by writing to the 15 return 0xff until the chip is woken up again by writing to the
16 DOCControl register. 16 DOCControl register.
17 17
18 Unfortunately, this means that the probe for the DiskOnChip is unsafe, 18 Unfortunately, this means that the probe for the DiskOnChip is unsafe,
19 because one of the first things it does is write to where it thinks 19 because one of the first things it does is write to where it thinks
20 the DOCControl register should be - which may well be shared memory 20 the DOCControl register should be - which may well be shared memory
21 for another device. I've had machines which lock up when this is 21 for another device. I've had machines which lock up when this is
22 attempted. Hence the possibility to do a passive probe, which will fail 22 attempted. Hence the possibility to do a passive probe, which will fail
23 to detect a chip in reset mode, but is at least guaranteed not to lock 23 to detect a chip in reset mode, but is at least guaranteed not to lock
24 the machine. 24 the machine.
25 25
@@ -33,9 +33,9 @@
33 33
34 The old Millennium-only driver has been retained just in case there 34 The old Millennium-only driver has been retained just in case there
35 are problems with the new code. If the combined driver doesn't work 35 are problems with the new code. If the combined driver doesn't work
36 for you, you can try the old one by undefining DOC_SINGLE_DRIVER 36 for you, you can try the old one by undefining DOC_SINGLE_DRIVER
37 below and also enabling it in your configuration. If this fixes the 37 below and also enabling it in your configuration. If this fixes the
38 problems, please send a report to the MTD mailing list at 38 problems, please send a report to the MTD mailing list at
39 <linux-mtd@lists.infradead.org>. 39 <linux-mtd@lists.infradead.org>.
40*/ 40*/
41#define DOC_SINGLE_DRIVER 41#define DOC_SINGLE_DRIVER
@@ -68,16 +68,16 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
68static unsigned long __initdata doc_locations[] = { 68static unsigned long __initdata doc_locations[] = {
69#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) 69#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
70#ifdef CONFIG_MTD_DOCPROBE_HIGH 70#ifdef CONFIG_MTD_DOCPROBE_HIGH
71 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 71 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
72 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, 72 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
73 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 73 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
74 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 74 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
75 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, 75 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
76#else /* CONFIG_MTD_DOCPROBE_HIGH */ 76#else /* CONFIG_MTD_DOCPROBE_HIGH */
77 0xc8000, 0xca000, 0xcc000, 0xce000, 77 0xc8000, 0xca000, 0xcc000, 0xce000,
78 0xd0000, 0xd2000, 0xd4000, 0xd6000, 78 0xd0000, 0xd2000, 0xd4000, 0xd6000,
79 0xd8000, 0xda000, 0xdc000, 0xde000, 79 0xd8000, 0xda000, 0xdc000, 0xde000,
80 0xe0000, 0xe2000, 0xe4000, 0xe6000, 80 0xe0000, 0xe2000, 0xe4000, 0xe6000,
81 0xe8000, 0xea000, 0xec000, 0xee000, 81 0xe8000, 0xea000, 0xec000, 0xee000,
82#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 82#endif /* CONFIG_MTD_DOCPROBE_HIGH */
83#elif defined(__PPC__) 83#elif defined(__PPC__)
@@ -111,35 +111,35 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
111 return 0; 111 return 0;
112#endif /* CONFIG_MTD_DOCPROBE_55AA */ 112#endif /* CONFIG_MTD_DOCPROBE_55AA */
113 113
114#ifndef DOC_PASSIVE_PROBE 114#ifndef DOC_PASSIVE_PROBE
115 /* It's not possible to cleanly detect the DiskOnChip - the 115 /* It's not possible to cleanly detect the DiskOnChip - the
116 * bootup procedure will put the device into reset mode, and 116 * bootup procedure will put the device into reset mode, and
117 * it's not possible to talk to it without actually writing 117 * it's not possible to talk to it without actually writing
118 * to the DOCControl register. So we store the current contents 118 * to the DOCControl register. So we store the current contents
119 * of the DOCControl register's location, in case we later decide 119 * of the DOCControl register's location, in case we later decide
120 * that it's not a DiskOnChip, and want to put it back how we 120 * that it's not a DiskOnChip, and want to put it back how we
121 * found it. 121 * found it.
122 */ 122 */
123 tmp2 = ReadDOC(window, DOCControl); 123 tmp2 = ReadDOC(window, DOCControl);
124 124
125 /* Reset the DiskOnChip ASIC */ 125 /* Reset the DiskOnChip ASIC */
126 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 126 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
127 window, DOCControl); 127 window, DOCControl);
128 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 128 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
129 window, DOCControl); 129 window, DOCControl);
130 130
131 /* Enable the DiskOnChip ASIC */ 131 /* Enable the DiskOnChip ASIC */
132 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 132 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
133 window, DOCControl); 133 window, DOCControl);
134 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 134 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
135 window, DOCControl); 135 window, DOCControl);
136#endif /* !DOC_PASSIVE_PROBE */ 136#endif /* !DOC_PASSIVE_PROBE */
137 137
138 /* We need to read the ChipID register four times. For some 138 /* We need to read the ChipID register four times. For some
139 newer DiskOnChip 2000 units, the first three reads will 139 newer DiskOnChip 2000 units, the first three reads will
140 return the DiskOnChip Millennium ident. Don't ask. */ 140 return the DiskOnChip Millennium ident. Don't ask. */
141 ChipID = ReadDOC(window, ChipID); 141 ChipID = ReadDOC(window, ChipID);
142 142
143 switch (ChipID) { 143 switch (ChipID) {
144 case DOC_ChipID_Doc2k: 144 case DOC_ChipID_Doc2k:
145 /* Check the TOGGLE bit in the ECC register */ 145 /* Check the TOGGLE bit in the ECC register */
@@ -149,7 +149,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
149 if (tmp != tmpb && tmp == tmpc) 149 if (tmp != tmpb && tmp == tmpc)
150 return ChipID; 150 return ChipID;
151 break; 151 break;
152 152
153 case DOC_ChipID_DocMil: 153 case DOC_ChipID_DocMil:
154 /* Check for the new 2000 with Millennium ASIC */ 154 /* Check for the new 2000 with Millennium ASIC */
155 ReadDOC(window, ChipID); 155 ReadDOC(window, ChipID);
@@ -164,7 +164,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
164 if (tmp != tmpb && tmp == tmpc) 164 if (tmp != tmpb && tmp == tmpc)
165 return ChipID; 165 return ChipID;
166 break; 166 break;
167 167
168 case DOC_ChipID_DocMilPlus16: 168 case DOC_ChipID_DocMilPlus16:
169 case DOC_ChipID_DocMilPlus32: 169 case DOC_ChipID_DocMilPlus32:
170 case 0: 170 case 0:
@@ -179,7 +179,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
179 DOC_MODE_BDECT; 179 DOC_MODE_BDECT;
180 WriteDOC(tmp, window, Mplus_DOCControl); 180 WriteDOC(tmp, window, Mplus_DOCControl);
181 WriteDOC(~tmp, window, Mplus_CtrlConfirm); 181 WriteDOC(~tmp, window, Mplus_CtrlConfirm);
182 182
183 mdelay(1); 183 mdelay(1);
184 /* Enable the DiskOnChip ASIC */ 184 /* Enable the DiskOnChip ASIC */
185 tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | 185 tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
@@ -187,7 +187,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
187 WriteDOC(tmp, window, Mplus_DOCControl); 187 WriteDOC(tmp, window, Mplus_DOCControl);
188 WriteDOC(~tmp, window, Mplus_CtrlConfirm); 188 WriteDOC(~tmp, window, Mplus_CtrlConfirm);
189 mdelay(1); 189 mdelay(1);
190#endif /* !DOC_PASSIVE_PROBE */ 190#endif /* !DOC_PASSIVE_PROBE */
191 191
192 ChipID = ReadDOC(window, ChipID); 192 ChipID = ReadDOC(window, ChipID);
193 193
@@ -227,7 +227,7 @@ static inline int __init doccheck(void __iomem *potential, unsigned long physadr
227 WriteDOC(tmp2, window, DOCControl); 227 WriteDOC(tmp2, window, DOCControl);
228#endif 228#endif
229 return 0; 229 return 0;
230} 230}
231 231
232static int docfound; 232static int docfound;
233 233
@@ -244,10 +244,10 @@ static void __init DoC_Probe(unsigned long physadr)
244 void (*initroutine)(struct mtd_info *) = NULL; 244 void (*initroutine)(struct mtd_info *) = NULL;
245 245
246 docptr = ioremap(physadr, DOC_IOREMAP_LEN); 246 docptr = ioremap(physadr, DOC_IOREMAP_LEN);
247 247
248 if (!docptr) 248 if (!docptr)
249 return; 249 return;
250 250
251 if ((ChipID = doccheck(docptr, physadr))) { 251 if ((ChipID = doccheck(docptr, physadr))) {
252 if (ChipID == DOC_ChipID_Doc2kTSOP) { 252 if (ChipID == DOC_ChipID_Doc2kTSOP) {
253 /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */ 253 /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
@@ -263,9 +263,9 @@ static void __init DoC_Probe(unsigned long physadr)
263 iounmap(docptr); 263 iounmap(docptr);
264 return; 264 return;
265 } 265 }
266 266
267 this = (struct DiskOnChip *)(&mtd[1]); 267 this = (struct DiskOnChip *)(&mtd[1]);
268 268
269 memset((char *)mtd,0, sizeof(struct mtd_info)); 269 memset((char *)mtd,0, sizeof(struct mtd_info));
270 memset((char *)this, 0, sizeof(struct DiskOnChip)); 270 memset((char *)this, 0, sizeof(struct DiskOnChip));
271 271
@@ -281,13 +281,13 @@ static void __init DoC_Probe(unsigned long physadr)
281 im_funcname = "DoC2k_init"; 281 im_funcname = "DoC2k_init";
282 im_modname = "doc2000"; 282 im_modname = "doc2000";
283 break; 283 break;
284 284
285 case DOC_ChipID_Doc2k: 285 case DOC_ChipID_Doc2k:
286 name="2000"; 286 name="2000";
287 im_funcname = "DoC2k_init"; 287 im_funcname = "DoC2k_init";
288 im_modname = "doc2000"; 288 im_modname = "doc2000";
289 break; 289 break;
290 290
291 case DOC_ChipID_DocMil: 291 case DOC_ChipID_DocMil:
292 name="Millennium"; 292 name="Millennium";
293#ifdef DOC_SINGLE_DRIVER 293#ifdef DOC_SINGLE_DRIVER
@@ -331,7 +331,7 @@ static void __init DoC_Probe(unsigned long physadr)
331static int __init init_doc(void) 331static int __init init_doc(void)
332{ 332{
333 int i; 333 int i;
334 334
335 if (doc_config_location) { 335 if (doc_config_location) {
336 printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location); 336 printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
337 DoC_Probe(doc_config_location); 337 DoC_Probe(doc_config_location);
diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c
index df987a53ed9c..1e876fcb0408 100644
--- a/drivers/mtd/devices/lart.c
+++ b/drivers/mtd/devices/lart.c
@@ -2,7 +2,7 @@
2/* 2/*
3 * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART. 3 * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
4 * 4 *
5 * $Id: lart.c,v 1.7 2004/08/09 13:19:44 dwmw2 Exp $ 5 * $Id: lart.c,v 1.9 2005/11/07 11:14:25 gleixner Exp $
6 * 6 *
7 * Author: Abraham vd Merwe <abraham@2d3d.co.za> 7 * Author: Abraham vd Merwe <abraham@2d3d.co.za>
8 * 8 *
@@ -122,7 +122,7 @@ static char module_name[] = "lart";
122 122
123/* 123/*
124 * The data line mapping on LART is as follows: 124 * The data line mapping on LART is as follows:
125 * 125 *
126 * U2 CPU | U3 CPU 126 * U2 CPU | U3 CPU
127 * ------------------- 127 * -------------------
128 * 0 20 | 0 12 128 * 0 20 | 0 12
@@ -181,7 +181,7 @@ static char module_name[] = "lart";
181 (((x) & 0x00004000) >> 13) \ 181 (((x) & 0x00004000) >> 13) \
182 ) 182 )
183 183
184/* 184/*
185 * The address line mapping on LART is as follows: 185 * The address line mapping on LART is as follows:
186 * 186 *
187 * U3 CPU | U2 CPU 187 * U3 CPU | U2 CPU
@@ -204,7 +204,7 @@ static char module_name[] = "lart";
204 * 12 15 | 12 15 204 * 12 15 | 12 15
205 * 13 14 | 13 14 205 * 13 14 | 13 14
206 * 14 16 | 14 16 206 * 14 16 | 14 16
207 * 207 *
208 * MAIN BLOCK BOUNDARY 208 * MAIN BLOCK BOUNDARY
209 * 209 *
210 * 15 17 | 15 18 210 * 15 17 | 15 18
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 765c0179c8df..e8685ee6c1e4 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * $Id: phram.c,v 1.14 2005/03/07 21:43:38 joern Exp $ 2 * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $
3 * 3 *
4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> 4 * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de>
5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de> 5 * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de>
@@ -41,10 +41,10 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
41 41
42 if (instr->addr + instr->len > mtd->size) 42 if (instr->addr + instr->len > mtd->size)
43 return -EINVAL; 43 return -EINVAL;
44 44
45 memset(start + instr->addr, 0xff, instr->len); 45 memset(start + instr->addr, 0xff, instr->len);
46 46
47 /* This'll catch a few races. Free the thing before returning :) 47 /* This'll catch a few races. Free the thing before returning :)
48 * I don't feel at all ashamed. This kind of thing is possible anyway 48 * I don't feel at all ashamed. This kind of thing is possible anyway
49 * with flash, but unlikely. 49 * with flash, but unlikely.
50 */ 50 */
@@ -63,7 +63,7 @@ static int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
63 63
64 if (from + len > mtd->size) 64 if (from + len > mtd->size)
65 return -EINVAL; 65 return -EINVAL;
66 66
67 *mtdbuf = start + from; 67 *mtdbuf = start + from;
68 *retlen = len; 68 *retlen = len;
69 return 0; 69 return 0;
@@ -84,7 +84,7 @@ static int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
84 84
85 if (len > mtd->size - from) 85 if (len > mtd->size - from)
86 len = mtd->size - from; 86 len = mtd->size - from;
87 87
88 memcpy(buf, start + from, len); 88 memcpy(buf, start + from, len);
89 89
90 *retlen = len; 90 *retlen = len;
@@ -101,7 +101,7 @@ static int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
101 101
102 if (len > mtd->size - to) 102 if (len > mtd->size - to)
103 len = mtd->size - to; 103 len = mtd->size - to;
104 104
105 memcpy(start + to, buf, len); 105 memcpy(start + to, buf, len);
106 106
107 *retlen = len; 107 *retlen = len;
@@ -159,7 +159,7 @@ static int register_device(char *name, unsigned long start, unsigned long len)
159 } 159 }
160 160
161 list_add_tail(&new->list, &phram_list); 161 list_add_tail(&new->list, &phram_list);
162 return 0; 162 return 0;
163 163
164out2: 164out2:
165 iounmap(new->mtd.priv); 165 iounmap(new->mtd.priv);
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c
index 5b3defadf884..666cce1bf60c 100644
--- a/drivers/mtd/devices/pmc551.c
+++ b/drivers/mtd/devices/pmc551.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: pmc551.c,v 1.30 2005/01/05 18:05:13 dwmw2 Exp $ 2 * $Id: pmc551.c,v 1.32 2005/11/07 11:14:25 gleixner Exp $
3 * 3 *
4 * PMC551 PCI Mezzanine Ram Device 4 * PMC551 PCI Mezzanine Ram Device
5 * 5 *
@@ -27,7 +27,7 @@
27 * it as high speed swap or for a high speed disk device of some 27 * it as high speed swap or for a high speed disk device of some
28 * sort. Which becomes very useful on diskless systems in the 28 * sort. Which becomes very useful on diskless systems in the
29 * embedded market I might add. 29 * embedded market I might add.
30 * 30 *
31 * Notes: 31 * Notes:
32 * Due to what I assume is more buggy SROM, the 64M PMC551 I 32 * Due to what I assume is more buggy SROM, the 64M PMC551 I
33 * have available claims that all 4 of it's DRAM banks have 64M 33 * have available claims that all 4 of it's DRAM banks have 64M
@@ -63,10 +63,10 @@
63 * Minyard set up the card to utilize a 1M sliding apature. 63 * Minyard set up the card to utilize a 1M sliding apature.
64 * 64 *
65 * Corey Minyard <minyard@nortelnetworks.com> 65 * Corey Minyard <minyard@nortelnetworks.com>
66 * * Modified driver to utilize a sliding aperture instead of 66 * * Modified driver to utilize a sliding aperture instead of
67 * mapping all memory into kernel space which turned out to 67 * mapping all memory into kernel space which turned out to
68 * be very wasteful. 68 * be very wasteful.
69 * * Located a bug in the SROM's initialization sequence that 69 * * Located a bug in the SROM's initialization sequence that
70 * made the memory unusable, added a fix to code to touch up 70 * made the memory unusable, added a fix to code to touch up
71 * the DRAM some. 71 * the DRAM some.
72 * 72 *
@@ -82,7 +82,6 @@
82 * * Comb the init routine. It's still a bit cludgy on a few things. 82 * * Comb the init routine. It's still a bit cludgy on a few things.
83 */ 83 */
84 84
85#include <linux/version.h>
86#include <linux/config.h> 85#include <linux/config.h>
87#include <linux/kernel.h> 86#include <linux/kernel.h>
88#include <linux/module.h> 87#include <linux/module.h>
@@ -390,7 +389,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
390 bcmd |= (0x40|0x20); 389 bcmd |= (0x40|0x20);
391 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd); 390 pci_write_config_byte(dev, PMC551_SYS_CTRL_REG, bcmd);
392 391
393 /* 392 /*
394 * Take care and turn off the memory on the device while we 393 * Take care and turn off the memory on the device while we
395 * tweak the configurations 394 * tweak the configurations
396 */ 395 */
@@ -408,7 +407,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
408 * Grab old BAR0 config so that we can figure out memory size 407 * Grab old BAR0 config so that we can figure out memory size
409 * This is another bit of kludge going on. The reason for the 408 * This is another bit of kludge going on. The reason for the
410 * redundancy is I am hoping to retain the original configuration 409 * redundancy is I am hoping to retain the original configuration
411 * previously assigned to the card by the BIOS or some previous 410 * previously assigned to the card by the BIOS or some previous
412 * fixup routine in the kernel. So we read the old config into cfg, 411 * fixup routine in the kernel. So we read the old config into cfg,
413 * then write all 1's to the memory space, read back the result into 412 * then write all 1's to the memory space, read back the result into
414 * "size", and then write back all the old config. 413 * "size", and then write back all the old config.
@@ -480,7 +479,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
480 } while ( (PCI_COMMAND_IO) & cmd ); 479 } while ( (PCI_COMMAND_IO) & cmd );
481 480
482 /* 481 /*
483 * Turn on auto refresh 482 * Turn on auto refresh
484 * The loop is taken directly from Ramix's example code. I assume that 483 * The loop is taken directly from Ramix's example code. I assume that
485 * this must be held high for some duration of time, but I can find no 484 * this must be held high for some duration of time, but I can find no
486 * documentation refrencing the reasons why. 485 * documentation refrencing the reasons why.
@@ -615,7 +614,7 @@ static u32 fixup_pmc551 (struct pci_dev *dev)
615 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd ); 614 pci_read_config_byte(dev, PMC551_SYS_CTRL_REG, &bcmd );
616 printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n" 615 printk( KERN_DEBUG "pmc551: EEPROM is under %s control\n"
617 "pmc551: System Control Register is %slocked to PCI access\n" 616 "pmc551: System Control Register is %slocked to PCI access\n"
618 "pmc551: System Control Register is %slocked to EEPROM access\n", 617 "pmc551: System Control Register is %slocked to EEPROM access\n",
619 (bcmd&0x1)?"software":"hardware", 618 (bcmd&0x1)?"software":"hardware",
620 (bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un"); 619 (bcmd&0x20)?"":"un", (bcmd&0x40)?"":"un");
621#endif 620#endif
@@ -744,7 +743,7 @@ static int __init init_pmc551(void)
744 priv->start = ioremap(((PCI_Device->resource[0].start) 743 priv->start = ioremap(((PCI_Device->resource[0].start)
745 & PCI_BASE_ADDRESS_MEM_MASK), 744 & PCI_BASE_ADDRESS_MEM_MASK),
746 priv->asize); 745 priv->asize);
747 746
748 if (!priv->start) { 747 if (!priv->start) {
749 printk(KERN_NOTICE "pmc551: Unable to map IO space\n"); 748 printk(KERN_NOTICE "pmc551: Unable to map IO space\n");
750 kfree(mtd->priv); 749 kfree(mtd->priv);
@@ -765,7 +764,7 @@ static int __init init_pmc551(void)
765 priv->curr_map0 ); 764 priv->curr_map0 );
766 765
767#ifdef CONFIG_MTD_PMC551_DEBUG 766#ifdef CONFIG_MTD_PMC551_DEBUG
768 printk( KERN_DEBUG "pmc551: aperture set to %d\n", 767 printk( KERN_DEBUG "pmc551: aperture set to %d\n",
769 (priv->base_map0 & 0xF0)>>4 ); 768 (priv->base_map0 & 0xF0)>>4 );
770#endif 769#endif
771 770
@@ -823,13 +822,13 @@ static void __exit cleanup_pmc551(void)
823 while((mtd=pmc551list)) { 822 while((mtd=pmc551list)) {
824 priv = mtd->priv; 823 priv = mtd->priv;
825 pmc551list = priv->nextpmc551; 824 pmc551list = priv->nextpmc551;
826 825
827 if(priv->start) { 826 if(priv->start) {
828 printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n", 827 printk (KERN_DEBUG "pmc551: unmapping %dM starting at 0x%p\n",
829 priv->asize>>20, priv->start); 828 priv->asize>>20, priv->start);
830 iounmap (priv->start); 829 iounmap (priv->start);
831 } 830 }
832 831
833 kfree (mtd->priv); 832 kfree (mtd->priv);
834 del_mtd_device (mtd); 833 del_mtd_device (mtd);
835 kfree (mtd); 834 kfree (mtd);
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 84fa91392a8c..6faee6c6958c 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -1,6 +1,6 @@
1/*====================================================================== 1/*======================================================================
2 2
3 $Id: slram.c,v 1.34 2005/01/06 21:16:42 jwboyer Exp $ 3 $Id: slram.c,v 1.36 2005/11/07 11:14:25 gleixner Exp $
4 4
5 This driver provides a method to access memory not used by the kernel 5 This driver provides a method to access memory not used by the kernel
6 itself (i.e. if the kernel commandline mem=xxx is used). To actually 6 itself (i.e. if the kernel commandline mem=xxx is used). To actually
@@ -18,14 +18,14 @@
18 <start>: start of the memory region, decimal or hex (0xabcdef) 18 <start>: start of the memory region, decimal or hex (0xabcdef)
19 <end/offset>: end of the memory region. It's possible to use +0x1234 19 <end/offset>: end of the memory region. It's possible to use +0x1234
20 to specify the offset instead of the absolute address 20 to specify the offset instead of the absolute address
21 21
22 NOTE: 22 NOTE:
23 With slram it's only possible to map a contigous memory region. Therfore 23 With slram it's only possible to map a contigous memory region. Therfore
24 if there's a device mapped somewhere in the region specified slram will 24 if there's a device mapped somewhere in the region specified slram will
25 fail to load (see kernel log if modprobe fails). 25 fail to load (see kernel log if modprobe fails).
26 26
27 - 27 -
28 28
29 Jochen Schaeuble <psionic@psionic.de> 29 Jochen Schaeuble <psionic@psionic.de>
30 30
31======================================================================*/ 31======================================================================*/
@@ -89,10 +89,10 @@ static int slram_erase(struct mtd_info *mtd, struct erase_info *instr)
89 if (instr->addr + instr->len > mtd->size) { 89 if (instr->addr + instr->len > mtd->size) {
90 return(-EINVAL); 90 return(-EINVAL);
91 } 91 }
92 92
93 memset(priv->start + instr->addr, 0xff, instr->len); 93 memset(priv->start + instr->addr, 0xff, instr->len);
94 94
95 /* This'll catch a few races. Free the thing before returning :) 95 /* This'll catch a few races. Free the thing before returning :)
96 * I don't feel at all ashamed. This kind of thing is possible anyway 96 * I don't feel at all ashamed. This kind of thing is possible anyway
97 * with flash, but unlikely. 97 * with flash, but unlikely.
98 */ 98 */
@@ -170,12 +170,12 @@ static int register_device(char *name, unsigned long start, unsigned long length
170 } 170 }
171 (*curmtd)->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); 171 (*curmtd)->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
172 (*curmtd)->next = NULL; 172 (*curmtd)->next = NULL;
173 173
174 if ((*curmtd)->mtdinfo) { 174 if ((*curmtd)->mtdinfo) {
175 memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info)); 175 memset((char *)(*curmtd)->mtdinfo, 0, sizeof(struct mtd_info));
176 (*curmtd)->mtdinfo->priv = 176 (*curmtd)->mtdinfo->priv =
177 kmalloc(sizeof(slram_priv_t), GFP_KERNEL); 177 kmalloc(sizeof(slram_priv_t), GFP_KERNEL);
178 178
179 if (!(*curmtd)->mtdinfo->priv) { 179 if (!(*curmtd)->mtdinfo->priv) {
180 kfree((*curmtd)->mtdinfo); 180 kfree((*curmtd)->mtdinfo);
181 (*curmtd)->mtdinfo = NULL; 181 (*curmtd)->mtdinfo = NULL;
@@ -188,7 +188,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
188 E("slram: Cannot allocate new MTD device.\n"); 188 E("slram: Cannot allocate new MTD device.\n");
189 return(-ENOMEM); 189 return(-ENOMEM);
190 } 190 }
191 191
192 if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start = 192 if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start =
193 ioremap(start, length))) { 193 ioremap(start, length))) {
194 E("slram: ioremap failed\n"); 194 E("slram: ioremap failed\n");
@@ -223,7 +223,7 @@ static int register_device(char *name, unsigned long start, unsigned long length
223 T("slram: Mapped from 0x%p to 0x%p\n", 223 T("slram: Mapped from 0x%p to 0x%p\n",
224 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start, 224 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start,
225 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end); 225 ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end);
226 return(0); 226 return(0);
227} 227}
228 228
229static void unregister_devices(void) 229static void unregister_devices(void)
@@ -256,7 +256,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
256 char *buffer; 256 char *buffer;
257 unsigned long devstart; 257 unsigned long devstart;
258 unsigned long devlength; 258 unsigned long devlength;
259 259
260 if ((!devname) || (!szstart) || (!szlength)) { 260 if ((!devname) || (!szstart) || (!szlength)) {
261 unregister_devices(); 261 unregister_devices();
262 return(-EINVAL); 262 return(-EINVAL);
@@ -264,7 +264,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
264 264
265 devstart = simple_strtoul(szstart, &buffer, 0); 265 devstart = simple_strtoul(szstart, &buffer, 0);
266 devstart = handle_unit(devstart, buffer); 266 devstart = handle_unit(devstart, buffer);
267 267
268 if (*(szlength) != '+') { 268 if (*(szlength) != '+') {
269 devlength = simple_strtoul(szlength, &buffer, 0); 269 devlength = simple_strtoul(szlength, &buffer, 0);
270 devlength = handle_unit(devlength, buffer) - devstart; 270 devlength = handle_unit(devlength, buffer) - devstart;
@@ -278,7 +278,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
278 E("slram: Illegal start / length parameter.\n"); 278 E("slram: Illegal start / length parameter.\n");
279 return(-EINVAL); 279 return(-EINVAL);
280 } 280 }
281 281
282 if ((devstart = register_device(devname, devstart, devlength))){ 282 if ((devstart = register_device(devname, devstart, devlength))){
283 unregister_devices(); 283 unregister_devices();
284 return((int)devstart); 284 return((int)devstart);
@@ -335,7 +335,7 @@ static int init_slram(void)
335 } 335 }
336#else 336#else
337 int count; 337 int count;
338 338
339 for (count = 0; (map[count]) && (count < SLRAM_MAX_DEVICES_PARAMS); 339 for (count = 0; (map[count]) && (count < SLRAM_MAX_DEVICES_PARAMS);
340 count++) { 340 count++) {
341 } 341 }
@@ -350,10 +350,10 @@ static int init_slram(void)
350 if (parse_cmdline(devname, map[i * 3 + 1], map[i * 3 + 2])!=0) { 350 if (parse_cmdline(devname, map[i * 3 + 1], map[i * 3 + 2])!=0) {
351 return(-EINVAL); 351 return(-EINVAL);
352 } 352 }
353 353
354 } 354 }
355#endif /* !MODULE */ 355#endif /* !MODULE */
356 356
357 return(0); 357 return(0);
358} 358}
359 359
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index d32c1b3a8ce3..de7e231d6d18 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
1/* This version ported to the Linux-MTD system by dwmw2@infradead.org 1/* This version ported to the Linux-MTD system by dwmw2@infradead.org
2 * $Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $ 2 * $Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $
3 * 3 *
4 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> 4 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5 * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups 5 * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -53,7 +53,7 @@
53 Use of the FTL format for non-PCMCIA applications may be an 53 Use of the FTL format for non-PCMCIA applications may be an
54 infringement of these patents. For additional information, 54 infringement of these patents. For additional information,
55 contact M-Systems (http://www.m-sys.com) directly. 55 contact M-Systems (http://www.m-sys.com) directly.
56 56
57======================================================================*/ 57======================================================================*/
58#include <linux/mtd/blktrans.h> 58#include <linux/mtd/blktrans.h>
59#include <linux/module.h> 59#include <linux/module.h>
@@ -160,7 +160,7 @@ static void ftl_erase_callback(struct erase_info *done);
160 Scan_header() checks to see if a memory region contains an FTL 160 Scan_header() checks to see if a memory region contains an FTL
161 partition. build_maps() reads all the erase unit headers, builds 161 partition. build_maps() reads all the erase unit headers, builds
162 the erase unit map, and then builds the virtual page map. 162 the erase unit map, and then builds the virtual page map.
163 163
164======================================================================*/ 164======================================================================*/
165 165
166static int scan_header(partition_t *part) 166static int scan_header(partition_t *part)
@@ -176,10 +176,10 @@ static int scan_header(partition_t *part)
176 (offset + sizeof(header)) < max_offset; 176 (offset + sizeof(header)) < max_offset;
177 offset += part->mbd.mtd->erasesize ? : 0x2000) { 177 offset += part->mbd.mtd->erasesize ? : 0x2000) {
178 178
179 err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret, 179 err = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
180 (unsigned char *)&header); 180 (unsigned char *)&header);
181 181
182 if (err) 182 if (err)
183 return err; 183 return err;
184 184
185 if (strcmp(header.DataOrgTuple+3, "FTL100") == 0) break; 185 if (strcmp(header.DataOrgTuple+3, "FTL100") == 0) break;
@@ -232,10 +232,10 @@ static int build_maps(partition_t *part)
232 for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) { 232 for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
233 offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN)) 233 offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
234 << part->header.EraseUnitSize); 234 << part->header.EraseUnitSize);
235 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval, 235 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
236 (unsigned char *)&header); 236 (unsigned char *)&header);
237 237
238 if (ret) 238 if (ret)
239 goto out_XferInfo; 239 goto out_XferInfo;
240 240
241 ret = -1; 241 ret = -1;
@@ -274,7 +274,7 @@ static int build_maps(partition_t *part)
274 "don't add up!\n"); 274 "don't add up!\n");
275 goto out_XferInfo; 275 goto out_XferInfo;
276 } 276 }
277 277
278 /* Set up virtual page map */ 278 /* Set up virtual page map */
279 blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize; 279 blocks = le32_to_cpu(header.FormattedSize) >> header.BlockSize;
280 part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t)); 280 part->VirtualBlockMap = vmalloc(blocks * sizeof(u_int32_t));
@@ -296,12 +296,12 @@ static int build_maps(partition_t *part)
296 part->EUNInfo[i].Free = 0; 296 part->EUNInfo[i].Free = 0;
297 part->EUNInfo[i].Deleted = 0; 297 part->EUNInfo[i].Deleted = 0;
298 offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset); 298 offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
299 299
300 ret = part->mbd.mtd->read(part->mbd.mtd, offset, 300 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
301 part->BlocksPerUnit * sizeof(u_int32_t), &retval, 301 part->BlocksPerUnit * sizeof(u_int32_t), &retval,
302 (unsigned char *)part->bam_cache); 302 (unsigned char *)part->bam_cache);
303 303
304 if (ret) 304 if (ret)
305 goto out_bam_cache; 305 goto out_bam_cache;
306 306
307 for (j = 0; j < part->BlocksPerUnit; j++) { 307 for (j = 0; j < part->BlocksPerUnit; j++) {
@@ -316,7 +316,7 @@ static int build_maps(partition_t *part)
316 part->EUNInfo[i].Deleted++; 316 part->EUNInfo[i].Deleted++;
317 } 317 }
318 } 318 }
319 319
320 ret = 0; 320 ret = 0;
321 goto out; 321 goto out;
322 322
@@ -336,7 +336,7 @@ out:
336 336
337 Erase_xfer() schedules an asynchronous erase operation for a 337 Erase_xfer() schedules an asynchronous erase operation for a
338 transfer unit. 338 transfer unit.
339 339
340======================================================================*/ 340======================================================================*/
341 341
342static int erase_xfer(partition_t *part, 342static int erase_xfer(partition_t *part,
@@ -351,10 +351,10 @@ static int erase_xfer(partition_t *part,
351 xfer->state = XFER_ERASING; 351 xfer->state = XFER_ERASING;
352 352
353 /* Is there a free erase slot? Always in MTD. */ 353 /* Is there a free erase slot? Always in MTD. */
354 354
355 355
356 erase=kmalloc(sizeof(struct erase_info), GFP_KERNEL); 356 erase=kmalloc(sizeof(struct erase_info), GFP_KERNEL);
357 if (!erase) 357 if (!erase)
358 return -ENOMEM; 358 return -ENOMEM;
359 359
360 erase->mtd = part->mbd.mtd; 360 erase->mtd = part->mbd.mtd;
@@ -362,7 +362,7 @@ static int erase_xfer(partition_t *part,
362 erase->addr = xfer->Offset; 362 erase->addr = xfer->Offset;
363 erase->len = 1 << part->header.EraseUnitSize; 363 erase->len = 1 << part->header.EraseUnitSize;
364 erase->priv = (u_long)part; 364 erase->priv = (u_long)part;
365 365
366 ret = part->mbd.mtd->erase(part->mbd.mtd, erase); 366 ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
367 367
368 if (!ret) 368 if (!ret)
@@ -377,7 +377,7 @@ static int erase_xfer(partition_t *part,
377 377
378 Prepare_xfer() takes a freshly erased transfer unit and gives 378 Prepare_xfer() takes a freshly erased transfer unit and gives
379 it an appropriate header. 379 it an appropriate header.
380 380
381======================================================================*/ 381======================================================================*/
382 382
383static void ftl_erase_callback(struct erase_info *erase) 383static void ftl_erase_callback(struct erase_info *erase)
@@ -385,7 +385,7 @@ static void ftl_erase_callback(struct erase_info *erase)
385 partition_t *part; 385 partition_t *part;
386 struct xfer_info_t *xfer; 386 struct xfer_info_t *xfer;
387 int i; 387 int i;
388 388
389 /* Look up the transfer unit */ 389 /* Look up the transfer unit */
390 part = (partition_t *)(erase->priv); 390 part = (partition_t *)(erase->priv);
391 391
@@ -422,7 +422,7 @@ static int prepare_xfer(partition_t *part, int i)
422 422
423 xfer = &part->XferInfo[i]; 423 xfer = &part->XferInfo[i];
424 xfer->state = XFER_FAILED; 424 xfer->state = XFER_FAILED;
425 425
426 DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset); 426 DEBUG(1, "ftl_cs: preparing xfer unit at 0x%x\n", xfer->Offset);
427 427
428 /* Write the transfer unit header */ 428 /* Write the transfer unit header */
@@ -446,7 +446,7 @@ static int prepare_xfer(partition_t *part, int i)
446 446
447 for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) { 447 for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) {
448 448
449 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t), 449 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
450 &retlen, (u_char *)&ctl); 450 &retlen, (u_char *)&ctl);
451 451
452 if (ret) 452 if (ret)
@@ -454,7 +454,7 @@ static int prepare_xfer(partition_t *part, int i)
454 } 454 }
455 xfer->state = XFER_PREPARED; 455 xfer->state = XFER_PREPARED;
456 return 0; 456 return 0;
457 457
458} /* prepare_xfer */ 458} /* prepare_xfer */
459 459
460/*====================================================================== 460/*======================================================================
@@ -466,7 +466,7 @@ static int prepare_xfer(partition_t *part, int i)
466 All data blocks are copied to the corresponding blocks in the 466 All data blocks are copied to the corresponding blocks in the
467 target unit, so the virtual block map does not need to be 467 target unit, so the virtual block map does not need to be
468 updated. 468 updated.
469 469
470======================================================================*/ 470======================================================================*/
471 471
472static int copy_erase_unit(partition_t *part, u_int16_t srcunit, 472static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
@@ -486,14 +486,14 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
486 xfer = &part->XferInfo[xferunit]; 486 xfer = &part->XferInfo[xferunit];
487 DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n", 487 DEBUG(2, "ftl_cs: copying block 0x%x to 0x%x\n",
488 eun->Offset, xfer->Offset); 488 eun->Offset, xfer->Offset);
489 489
490 490
491 /* Read current BAM */ 491 /* Read current BAM */
492 if (part->bam_index != srcunit) { 492 if (part->bam_index != srcunit) {
493 493
494 offset = eun->Offset + le32_to_cpu(part->header.BAMOffset); 494 offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
495 495
496 ret = part->mbd.mtd->read(part->mbd.mtd, offset, 496 ret = part->mbd.mtd->read(part->mbd.mtd, offset,
497 part->BlocksPerUnit * sizeof(u_int32_t), 497 part->BlocksPerUnit * sizeof(u_int32_t),
498 &retlen, (u_char *) (part->bam_cache)); 498 &retlen, (u_char *) (part->bam_cache));
499 499
@@ -501,11 +501,11 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
501 part->bam_index = 0xffff; 501 part->bam_index = 0xffff;
502 502
503 if (ret) { 503 if (ret) {
504 printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n"); 504 printk( KERN_WARNING "ftl: Failed to read BAM cache in copy_erase_unit()!\n");
505 return ret; 505 return ret;
506 } 506 }
507 } 507 }
508 508
509 /* Write the LogicalEUN for the transfer unit */ 509 /* Write the LogicalEUN for the transfer unit */
510 xfer->state = XFER_UNKNOWN; 510 xfer->state = XFER_UNKNOWN;
511 offset = xfer->Offset + 20; /* Bad! */ 511 offset = xfer->Offset + 20; /* Bad! */
@@ -513,12 +513,12 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
513 513
514 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t), 514 ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t),
515 &retlen, (u_char *) &unit); 515 &retlen, (u_char *) &unit);
516 516
517 if (ret) { 517 if (ret) {
518 printk( KERN_WARNING "ftl: Failed to write back to BAM cache in copy_erase_unit()!\n"); 518 printk( KERN_WARNING "ftl: Failed to write back to BAM cache in copy_erase_unit()!\n");
519 return ret; 519 return ret;
520 } 520 }
521 521
522 /* Copy all data blocks from source unit to transfer unit */ 522 /* Copy all data blocks from source unit to transfer unit */
523 src = eun->Offset; dest = xfer->Offset; 523 src = eun->Offset; dest = xfer->Offset;
524 524
@@ -558,15 +558,15 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
558 } 558 }
559 559
560 /* Write the BAM to the transfer unit */ 560 /* Write the BAM to the transfer unit */
561 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset), 561 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
562 part->BlocksPerUnit * sizeof(int32_t), &retlen, 562 part->BlocksPerUnit * sizeof(int32_t), &retlen,
563 (u_char *)part->bam_cache); 563 (u_char *)part->bam_cache);
564 if (ret) { 564 if (ret) {
565 printk( KERN_WARNING "ftl: Error writing BAM in copy_erase_unit\n"); 565 printk( KERN_WARNING "ftl: Error writing BAM in copy_erase_unit\n");
566 return ret; 566 return ret;
567 } 567 }
568 568
569 569
570 /* All clear? Then update the LogicalEUN again */ 570 /* All clear? Then update the LogicalEUN again */
571 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t), 571 ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t),
572 &retlen, (u_char *)&srcunitswap); 572 &retlen, (u_char *)&srcunitswap);
@@ -574,9 +574,9 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
574 if (ret) { 574 if (ret) {
575 printk(KERN_WARNING "ftl: Error writing new LogicalEUN in copy_erase_unit\n"); 575 printk(KERN_WARNING "ftl: Error writing new LogicalEUN in copy_erase_unit\n");
576 return ret; 576 return ret;
577 } 577 }
578 578
579 579
580 /* Update the maps and usage stats*/ 580 /* Update the maps and usage stats*/
581 i = xfer->EraseCount; 581 i = xfer->EraseCount;
582 xfer->EraseCount = eun->EraseCount; 582 xfer->EraseCount = eun->EraseCount;
@@ -588,10 +588,10 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
588 part->FreeTotal += free; 588 part->FreeTotal += free;
589 eun->Free = free; 589 eun->Free = free;
590 eun->Deleted = 0; 590 eun->Deleted = 0;
591 591
592 /* Now, the cache should be valid for the new block */ 592 /* Now, the cache should be valid for the new block */
593 part->bam_index = srcunit; 593 part->bam_index = srcunit;
594 594
595 return 0; 595 return 0;
596} /* copy_erase_unit */ 596} /* copy_erase_unit */
597 597
@@ -608,7 +608,7 @@ static int copy_erase_unit(partition_t *part, u_int16_t srcunit,
608 oldest data unit instead. This means that we generally postpone 608 oldest data unit instead. This means that we generally postpone
609 the next reclaimation as long as possible, but shuffle static 609 the next reclaimation as long as possible, but shuffle static
610 stuff around a bit for wear leveling. 610 stuff around a bit for wear leveling.
611 611
612======================================================================*/ 612======================================================================*/
613 613
614static int reclaim_block(partition_t *part) 614static int reclaim_block(partition_t *part)
@@ -666,7 +666,7 @@ static int reclaim_block(partition_t *part)
666 else 666 else
667 DEBUG(1, "ftl_cs: reclaim failed: no " 667 DEBUG(1, "ftl_cs: reclaim failed: no "
668 "suitable transfer units!\n"); 668 "suitable transfer units!\n");
669 669
670 return -EIO; 670 return -EIO;
671 } 671 }
672 } 672 }
@@ -715,7 +715,7 @@ static int reclaim_block(partition_t *part)
715 returns the block index -- the erase unit is just the currently 715 returns the block index -- the erase unit is just the currently
716 cached unit. If there are no free blocks, it returns 0 -- this 716 cached unit. If there are no free blocks, it returns 0 -- this
717 is never a valid data block because it contains the header. 717 is never a valid data block because it contains the header.
718 718
719======================================================================*/ 719======================================================================*/
720 720
721#ifdef PSYCHO_DEBUG 721#ifdef PSYCHO_DEBUG
@@ -737,7 +737,7 @@ static u_int32_t find_free(partition_t *part)
737 u_int32_t blk; 737 u_int32_t blk;
738 size_t retlen; 738 size_t retlen;
739 int ret; 739 int ret;
740 740
741 /* Find an erase unit with some free space */ 741 /* Find an erase unit with some free space */
742 stop = (part->bam_index == 0xffff) ? 0 : part->bam_index; 742 stop = (part->bam_index == 0xffff) ? 0 : part->bam_index;
743 eun = stop; 743 eun = stop;
@@ -749,17 +749,17 @@ static u_int32_t find_free(partition_t *part)
749 749
750 if (part->EUNInfo[eun].Free == 0) 750 if (part->EUNInfo[eun].Free == 0)
751 return 0; 751 return 0;
752 752
753 /* Is this unit's BAM cached? */ 753 /* Is this unit's BAM cached? */
754 if (eun != part->bam_index) { 754 if (eun != part->bam_index) {
755 /* Invalidate cache */ 755 /* Invalidate cache */
756 part->bam_index = 0xffff; 756 part->bam_index = 0xffff;
757 757
758 ret = part->mbd.mtd->read(part->mbd.mtd, 758 ret = part->mbd.mtd->read(part->mbd.mtd,
759 part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset), 759 part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
760 part->BlocksPerUnit * sizeof(u_int32_t), 760 part->BlocksPerUnit * sizeof(u_int32_t),
761 &retlen, (u_char *) (part->bam_cache)); 761 &retlen, (u_char *) (part->bam_cache));
762 762
763 if (ret) { 763 if (ret) {
764 printk(KERN_WARNING"ftl: Error reading BAM in find_free\n"); 764 printk(KERN_WARNING"ftl: Error reading BAM in find_free\n");
765 return 0; 765 return 0;
@@ -781,14 +781,14 @@ static u_int32_t find_free(partition_t *part)
781 } 781 }
782 DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun); 782 DEBUG(2, "ftl_cs: found free block at %d in %d\n", blk, eun);
783 return blk; 783 return blk;
784 784
785} /* find_free */ 785} /* find_free */
786 786
787 787
788/*====================================================================== 788/*======================================================================
789 789
790 Read a series of sectors from an FTL partition. 790 Read a series of sectors from an FTL partition.
791 791
792======================================================================*/ 792======================================================================*/
793 793
794static int ftl_read(partition_t *part, caddr_t buffer, 794static int ftl_read(partition_t *part, caddr_t buffer,
@@ -798,7 +798,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
798 u_long i; 798 u_long i;
799 int ret; 799 int ret;
800 size_t offset, retlen; 800 size_t offset, retlen;
801 801
802 DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n", 802 DEBUG(2, "ftl_cs: ftl_read(0x%p, 0x%lx, %ld)\n",
803 part, sector, nblocks); 803 part, sector, nblocks);
804 if (!(part->state & FTL_FORMATTED)) { 804 if (!(part->state & FTL_FORMATTED)) {
@@ -834,7 +834,7 @@ static int ftl_read(partition_t *part, caddr_t buffer,
834/*====================================================================== 834/*======================================================================
835 835
836 Write a series of sectors to an FTL partition 836 Write a series of sectors to an FTL partition
837 837
838======================================================================*/ 838======================================================================*/
839 839
840static int set_bam_entry(partition_t *part, u_int32_t log_addr, 840static int set_bam_entry(partition_t *part, u_int32_t log_addr,
@@ -855,7 +855,7 @@ static int set_bam_entry(partition_t *part, u_int32_t log_addr,
855 blk = (log_addr % bsize) / SECTOR_SIZE; 855 blk = (log_addr % bsize) / SECTOR_SIZE;
856 offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) + 856 offset = (part->EUNInfo[eun].Offset + blk * sizeof(u_int32_t) +
857 le32_to_cpu(part->header.BAMOffset)); 857 le32_to_cpu(part->header.BAMOffset));
858 858
859#ifdef PSYCHO_DEBUG 859#ifdef PSYCHO_DEBUG
860 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t), 860 ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t),
861 &retlen, (u_char *)&old_addr); 861 &retlen, (u_char *)&old_addr);
@@ -925,7 +925,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
925 if (ret) 925 if (ret)
926 return ret; 926 return ret;
927 } 927 }
928 928
929 bsize = 1 << part->header.EraseUnitSize; 929 bsize = 1 << part->header.EraseUnitSize;
930 930
931 virt_addr = sector * SECTOR_SIZE | BLOCK_DATA; 931 virt_addr = sector * SECTOR_SIZE | BLOCK_DATA;
@@ -949,12 +949,12 @@ static int ftl_write(partition_t *part, caddr_t buffer,
949 log_addr = part->bam_index * bsize + blk * SECTOR_SIZE; 949 log_addr = part->bam_index * bsize + blk * SECTOR_SIZE;
950 part->EUNInfo[part->bam_index].Free--; 950 part->EUNInfo[part->bam_index].Free--;
951 part->FreeTotal--; 951 part->FreeTotal--;
952 if (set_bam_entry(part, log_addr, 0xfffffffe)) 952 if (set_bam_entry(part, log_addr, 0xfffffffe))
953 return -EIO; 953 return -EIO;
954 part->EUNInfo[part->bam_index].Deleted++; 954 part->EUNInfo[part->bam_index].Deleted++;
955 offset = (part->EUNInfo[part->bam_index].Offset + 955 offset = (part->EUNInfo[part->bam_index].Offset +
956 blk * SECTOR_SIZE); 956 blk * SECTOR_SIZE);
957 ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen, 957 ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
958 buffer); 958 buffer);
959 959
960 if (ret) { 960 if (ret) {
@@ -964,7 +964,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
964 offset); 964 offset);
965 return -EIO; 965 return -EIO;
966 } 966 }
967 967
968 /* Only delete the old entry when the new entry is ready */ 968 /* Only delete the old entry when the new entry is ready */
969 old_addr = part->VirtualBlockMap[sector+i]; 969 old_addr = part->VirtualBlockMap[sector+i];
970 if (old_addr != 0xffffffff) { 970 if (old_addr != 0xffffffff) {
@@ -979,7 +979,7 @@ static int ftl_write(partition_t *part, caddr_t buffer,
979 return -EIO; 979 return -EIO;
980 part->VirtualBlockMap[sector+i] = log_addr; 980 part->VirtualBlockMap[sector+i] = log_addr;
981 part->EUNInfo[part->bam_index].Deleted--; 981 part->EUNInfo[part->bam_index].Deleted--;
982 982
983 buffer += SECTOR_SIZE; 983 buffer += SECTOR_SIZE;
984 virt_addr += SECTOR_SIZE; 984 virt_addr += SECTOR_SIZE;
985 } 985 }
@@ -1034,20 +1034,20 @@ static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
1034 partition_t *partition; 1034 partition_t *partition;
1035 1035
1036 partition = kmalloc(sizeof(partition_t), GFP_KERNEL); 1036 partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
1037 1037
1038 if (!partition) { 1038 if (!partition) {
1039 printk(KERN_WARNING "No memory to scan for FTL on %s\n", 1039 printk(KERN_WARNING "No memory to scan for FTL on %s\n",
1040 mtd->name); 1040 mtd->name);
1041 return; 1041 return;
1042 } 1042 }
1043 1043
1044 memset(partition, 0, sizeof(partition_t)); 1044 memset(partition, 0, sizeof(partition_t));
1045 1045
1046 partition->mbd.mtd = mtd; 1046 partition->mbd.mtd = mtd;
1047 1047
1048 if ((scan_header(partition) == 0) && 1048 if ((scan_header(partition) == 0) &&
1049 (build_maps(partition) == 0)) { 1049 (build_maps(partition) == 0)) {
1050 1050
1051 partition->state = FTL_FORMATTED; 1051 partition->state = FTL_FORMATTED;
1052#ifdef PCMCIA_DEBUG 1052#ifdef PCMCIA_DEBUG
1053 printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n", 1053 printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n",
@@ -1086,7 +1086,7 @@ struct mtd_blktrans_ops ftl_tr = {
1086 1086
1087int init_ftl(void) 1087int init_ftl(void)
1088{ 1088{
1089 DEBUG(0, "$Id: ftl.c,v 1.55 2005/01/17 13:47:21 hvr Exp $\n"); 1089 DEBUG(0, "$Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $\n");
1090 1090
1091 return register_mtd_blktrans(&ftl_tr); 1091 return register_mtd_blktrans(&ftl_tr);
1092} 1092}
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 39eb53f6551f..8a544890173d 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL) 2 * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
3 * 3 *
4 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) 4 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
@@ -7,7 +7,7 @@
7 * (c) 1999 Machine Vision Holdings, Inc. 7 * (c) 1999 Machine Vision Holdings, Inc.
8 * Author: David Woodhouse <dwmw2@infradead.org> 8 * Author: David Woodhouse <dwmw2@infradead.org>
9 * 9 *
10 * $Id: inftlcore.c,v 1.18 2004/11/16 18:28:59 dwmw2 Exp $ 10 * $Id: inftlcore.c,v 1.19 2005/11/07 11:14:20 gleixner Exp $
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
@@ -113,23 +113,21 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
113 113
114 if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) { 114 if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) {
115 /* 115 /*
116 Oh no we don't have 116 Oh no we don't have
117 mbd.size == heads * cylinders * sectors 117 mbd.size == heads * cylinders * sectors
118 */ 118 */
119 printk(KERN_WARNING "INFTL: cannot calculate a geometry to " 119 printk(KERN_WARNING "INFTL: cannot calculate a geometry to "
120 "match size of 0x%lx.\n", inftl->mbd.size); 120 "match size of 0x%lx.\n", inftl->mbd.size);
121 printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d " 121 printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d "
122 "(== 0x%lx sects)\n", 122 "(== 0x%lx sects)\n",
123 inftl->cylinders, inftl->heads , inftl->sectors, 123 inftl->cylinders, inftl->heads , inftl->sectors,
124 (long)inftl->cylinders * (long)inftl->heads * 124 (long)inftl->cylinders * (long)inftl->heads *
125 (long)inftl->sectors ); 125 (long)inftl->sectors );
126 } 126 }
127 127
128 if (add_mtd_blktrans_dev(&inftl->mbd)) { 128 if (add_mtd_blktrans_dev(&inftl->mbd)) {
129 if (inftl->PUtable) 129 kfree(inftl->PUtable);
130 kfree(inftl->PUtable); 130 kfree(inftl->VUtable);
131 if (inftl->VUtable)
132 kfree(inftl->VUtable);
133 kfree(inftl); 131 kfree(inftl);
134 return; 132 return;
135 } 133 }
@@ -147,10 +145,8 @@ static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
147 145
148 del_mtd_blktrans_dev(dev); 146 del_mtd_blktrans_dev(dev);
149 147
150 if (inftl->PUtable) 148 kfree(inftl->PUtable);
151 kfree(inftl->PUtable); 149 kfree(inftl->VUtable);
152 if (inftl->VUtable)
153 kfree(inftl->VUtable);
154 kfree(inftl); 150 kfree(inftl);
155} 151}
156 152
@@ -223,7 +219,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
223 "Virtual Unit Chain %d!\n", thisVUC); 219 "Virtual Unit Chain %d!\n", thisVUC);
224 return BLOCK_NIL; 220 return BLOCK_NIL;
225 } 221 }
226 222
227 /* 223 /*
228 * Scan to find the Erase Unit which holds the actual data for each 224 * Scan to find the Erase Unit which holds the actual data for each
229 * 512-byte block within the Chain. 225 * 512-byte block within the Chain.
@@ -264,7 +260,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
264 "Unit Chain 0x%x\n", thisVUC); 260 "Unit Chain 0x%x\n", thisVUC);
265 return BLOCK_NIL; 261 return BLOCK_NIL;
266 } 262 }
267 263
268 thisEUN = inftl->PUtable[thisEUN]; 264 thisEUN = inftl->PUtable[thisEUN];
269 } 265 }
270 266
@@ -295,15 +291,15 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
295 */ 291 */
296 if (BlockMap[block] == BLOCK_NIL) 292 if (BlockMap[block] == BLOCK_NIL)
297 continue; 293 continue;
298 294
299 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 295 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
300 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE, 296 BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
301 &retlen, movebuf); 297 &retlen, movebuf);
302 if (ret < 0) { 298 if (ret < 0) {
303 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize * 299 ret = MTD_READ(inftl->mbd.mtd, (inftl->EraseSize *
304 BlockMap[block]) + (block * SECTORSIZE), 300 BlockMap[block]) + (block * SECTORSIZE),
305 SECTORSIZE, &retlen, movebuf); 301 SECTORSIZE, &retlen, movebuf);
306 if (ret != -EIO) 302 if (ret != -EIO)
307 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went " 303 DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
308 "away on retry?\n"); 304 "away on retry?\n");
309 } 305 }
@@ -355,7 +351,7 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
355static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock) 351static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
356{ 352{
357 /* 353 /*
358 * This is the part that needs some cleverness applied. 354 * This is the part that needs some cleverness applied.
359 * For now, I'm doing the minimum applicable to actually 355 * For now, I'm doing the minimum applicable to actually
360 * get the thing to work. 356 * get the thing to work.
361 * Wear-levelling and other clever stuff needs to be implemented 357 * Wear-levelling and other clever stuff needs to be implemented
@@ -414,7 +410,7 @@ static int nrbits(unsigned int val, int bitcount)
414} 410}
415 411
416/* 412/*
417 * INFTL_findwriteunit: Return the unit number into which we can write 413 * INFTL_findwriteunit: Return the unit number into which we can write
418 * for this block. Make it available if it isn't already. 414 * for this block. Make it available if it isn't already.
419 */ 415 */
420static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block) 416static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
@@ -463,10 +459,10 @@ static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
463 * Invalid block. Don't use it any more. 459 * Invalid block. Don't use it any more.
464 * Must implement. 460 * Must implement.
465 */ 461 */
466 break; 462 break;
467 } 463 }
468 464
469 if (!silly--) { 465 if (!silly--) {
470 printk(KERN_WARNING "INFTL: infinite loop in " 466 printk(KERN_WARNING "INFTL: infinite loop in "
471 "Virtual Unit Chain 0x%x\n", thisVUC); 467 "Virtual Unit Chain 0x%x\n", thisVUC);
472 return 0xffff; 468 return 0xffff;
@@ -482,7 +478,7 @@ hitused:
482 478
483 479
484 /* 480 /*
485 * OK. We didn't find one in the existing chain, or there 481 * OK. We didn't find one in the existing chain, or there
486 * is no existing chain. Allocate a new one. 482 * is no existing chain. Allocate a new one.
487 */ 483 */
488 writeEUN = INFTL_findfreeblock(inftl, 0); 484 writeEUN = INFTL_findfreeblock(inftl, 0);
@@ -506,8 +502,8 @@ hitused:
506 if (writeEUN == BLOCK_NIL) { 502 if (writeEUN == BLOCK_NIL) {
507 /* 503 /*
508 * Ouch. This should never happen - we should 504 * Ouch. This should never happen - we should
509 * always be able to make some room somehow. 505 * always be able to make some room somehow.
510 * If we get here, we've allocated more storage 506 * If we get here, we've allocated more storage
511 * space than actual media, or our makefreeblock 507 * space than actual media, or our makefreeblock
512 * routine is missing something. 508 * routine is missing something.
513 */ 509 */
@@ -518,7 +514,7 @@ hitused:
518 INFTL_dumpVUchains(inftl); 514 INFTL_dumpVUchains(inftl);
519#endif 515#endif
520 return BLOCK_NIL; 516 return BLOCK_NIL;
521 } 517 }
522 } 518 }
523 519
524 /* 520 /*
@@ -543,7 +539,7 @@ hitused:
543 parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0; 539 parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
544 parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0; 540 parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
545 parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0; 541 parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
546 542
547 oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC); 543 oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
548 oob.u.a.prevUnitNo = cpu_to_le16(prev_block); 544 oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
549 oob.u.a.ANAC = anac; 545 oob.u.a.ANAC = anac;
@@ -562,7 +558,7 @@ hitused:
562 oob.u.b.parityPerField = parity; 558 oob.u.b.parityPerField = parity;
563 oob.u.b.discarded = 0xaa; 559 oob.u.b.discarded = 0xaa;
564 560
565 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + 561 MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
566 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u); 562 SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
567 563
568 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC]; 564 inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
@@ -602,7 +598,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
602 "Virtual Unit Chain %d!\n", thisVUC); 598 "Virtual Unit Chain %d!\n", thisVUC);
603 return; 599 return;
604 } 600 }
605 601
606 /* 602 /*
607 * Scan through the Erase Units to determine whether any data is in 603 * Scan through the Erase Units to determine whether any data is in
608 * each of the 512-byte blocks within the Chain. 604 * each of the 512-byte blocks within the Chain.
@@ -642,7 +638,7 @@ static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
642 "Unit Chain 0x%x\n", thisVUC); 638 "Unit Chain 0x%x\n", thisVUC);
643 return; 639 return;
644 } 640 }
645 641
646 thisEUN = inftl->PUtable[thisEUN]; 642 thisEUN = inftl->PUtable[thisEUN];
647 } 643 }
648 644
@@ -758,7 +754,7 @@ foundit:
758 return 0; 754 return 0;
759} 755}
760 756
761static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block, 757static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
762 char *buffer) 758 char *buffer)
763{ 759{
764 struct INFTLrecord *inftl = (void *)mbd; 760 struct INFTLrecord *inftl = (void *)mbd;
@@ -893,7 +889,7 @@ extern char inftlmountrev[];
893 889
894static int __init init_inftl(void) 890static int __init init_inftl(void)
895{ 891{
896 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.18 $, " 892 printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.19 $, "
897 "inftlmount.c %s\n", inftlmountrev); 893 "inftlmount.c %s\n", inftlmountrev);
898 894
899 return register_mtd_blktrans(&inftl_tr); 895 return register_mtd_blktrans(&inftl_tr);
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index b5dda47395a7..43fdc9433882 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -1,14 +1,14 @@
1/* 1/*
2 * inftlmount.c -- INFTL mount code with extensive checks. 2 * inftlmount.c -- INFTL mount code with extensive checks.
3 * 3 *
4 * Author: Greg Ungerer (gerg@snapgear.com) 4 * Author: Greg Ungerer (gerg@snapgear.com)
5 * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com) 5 * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com)
6 * 6 *
7 * Based heavily on the nftlmount.c code which is: 7 * Based heavily on the nftlmount.c code which is:
8 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 8 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
9 * Copyright (C) 2000 Netgem S.A. 9 * Copyright (C) 2000 Netgem S.A.
10 * 10 *
11 * $Id: inftlmount.c,v 1.16 2004/11/22 13:50:53 kalev Exp $ 11 * $Id: inftlmount.c,v 1.18 2005/11/07 11:14:20 gleixner Exp $
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@
41#include <linux/mtd/inftl.h> 41#include <linux/mtd/inftl.h>
42#include <linux/mtd/compatmac.h> 42#include <linux/mtd/compatmac.h>
43 43
44char inftlmountrev[]="$Revision: 1.16 $"; 44char inftlmountrev[]="$Revision: 1.18 $";
45 45
46/* 46/*
47 * find_boot_record: Find the INFTL Media Header and its Spare copy which 47 * find_boot_record: Find the INFTL Media Header and its Spare copy which
@@ -273,7 +273,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
273 inftl->nb_boot_blocks); 273 inftl->nb_boot_blocks);
274 return -1; 274 return -1;
275 } 275 }
276 276
277 inftl->mbd.size = inftl->numvunits * 277 inftl->mbd.size = inftl->numvunits *
278 (inftl->EraseSize / SECTORSIZE); 278 (inftl->EraseSize / SECTORSIZE);
279 279
@@ -302,7 +302,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
302 inftl->nb_blocks * sizeof(u16)); 302 inftl->nb_blocks * sizeof(u16));
303 return -ENOMEM; 303 return -ENOMEM;
304 } 304 }
305 305
306 /* Mark the blocks before INFTL MediaHeader as reserved */ 306 /* Mark the blocks before INFTL MediaHeader as reserved */
307 for (i = 0; i < inftl->nb_boot_blocks; i++) 307 for (i = 0; i < inftl->nb_boot_blocks; i++)
308 inftl->PUtable[i] = BLOCK_RESERVED; 308 inftl->PUtable[i] = BLOCK_RESERVED;
@@ -380,7 +380,7 @@ static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
380 * 380 *
381 * Return: 0 when succeed, -1 on error. 381 * Return: 0 when succeed, -1 on error.
382 * 382 *
383 * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? 383 * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
384 */ 384 */
385int INFTL_formatblock(struct INFTLrecord *inftl, int block) 385int INFTL_formatblock(struct INFTLrecord *inftl, int block)
386{ 386{
@@ -563,7 +563,7 @@ int INFTL_mount(struct INFTLrecord *s)
563 /* Search for INFTL MediaHeader and Spare INFTL Media Header */ 563 /* Search for INFTL MediaHeader and Spare INFTL Media Header */
564 if (find_boot_record(s) < 0) { 564 if (find_boot_record(s) < 0) {
565 printk(KERN_WARNING "INFTL: could not find valid boot record?\n"); 565 printk(KERN_WARNING "INFTL: could not find valid boot record?\n");
566 return -1; 566 return -ENXIO;
567 } 567 }
568 568
569 /* Init the logical to physical table */ 569 /* Init the logical to physical table */
@@ -574,6 +574,12 @@ int INFTL_mount(struct INFTLrecord *s)
574 574
575 /* Temporary buffer to store ANAC numbers. */ 575 /* Temporary buffer to store ANAC numbers. */
576 ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL); 576 ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL);
577 if (!ANACtable) {
578 printk(KERN_WARNING "INFTL: allocation of ANACtable "
579 "failed (%zd bytes)\n",
580 s->nb_blocks * sizeof(u8));
581 return -ENOMEM;
582 }
577 memset(ANACtable, 0, s->nb_blocks); 583 memset(ANACtable, 0, s->nb_blocks);
578 584
579 /* 585 /*
@@ -595,7 +601,7 @@ int INFTL_mount(struct INFTLrecord *s)
595 601
596 for (chain_length = 0; ; chain_length++) { 602 for (chain_length = 0; ; chain_length++) {
597 603
598 if ((chain_length == 0) && 604 if ((chain_length == 0) &&
599 (s->PUtable[block] != BLOCK_NOTEXPLORED)) { 605 (s->PUtable[block] != BLOCK_NOTEXPLORED)) {
600 /* Nothing to do here, onto next block */ 606 /* Nothing to do here, onto next block */
601 break; 607 break;
@@ -742,7 +748,7 @@ int INFTL_mount(struct INFTLrecord *s)
742 "in virtual chain %d\n", 748 "in virtual chain %d\n",
743 s->PUtable[block], logical_block); 749 s->PUtable[block], logical_block);
744 s->PUtable[block] = BLOCK_NIL; 750 s->PUtable[block] = BLOCK_NIL;
745 751
746 } 752 }
747 if (ANACtable[block] != ANAC) { 753 if (ANACtable[block] != ANAC) {
748 /* 754 /*
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 44781a83b2e7..48638c8097a5 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/maps/Kconfig 1# drivers/mtd/maps/Kconfig
2# $Id: Kconfig,v 1.55 2005/07/02 01:53:24 tpoynor Exp $ 2# $Id: Kconfig,v 1.61 2005/11/07 11:14:26 gleixner Exp $
3 3
4menu "Mapping drivers for chip access" 4menu "Mapping drivers for chip access"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -64,9 +64,9 @@ config MTD_SUN_UFLASH
64 tristate "Sun Microsystems userflash support" 64 tristate "Sun Microsystems userflash support"
65 depends on (SPARC32 || SPARC64) && MTD_CFI 65 depends on (SPARC32 || SPARC64) && MTD_CFI
66 help 66 help
67 This provides a 'mapping' driver which supports the way in 67 This provides a 'mapping' driver which supports the way in
68 which user-programmable flash chips are connected on various 68 which user-programmable flash chips are connected on various
69 Sun Microsystems boardsets. This driver will require CFI support 69 Sun Microsystems boardsets. This driver will require CFI support
70 in the kernel, so if you did not enable CFI previously, do that now. 70 in the kernel, so if you did not enable CFI previously, do that now.
71 71
72config MTD_PNC2000 72config MTD_PNC2000
@@ -89,22 +89,22 @@ config MTD_NETSC520
89 depends on X86 && MTD_CFI && MTD_PARTITIONS 89 depends on X86 && MTD_CFI && MTD_PARTITIONS
90 help 90 help
91 This enables access routines for the flash chips on the AMD NetSc520 91 This enables access routines for the flash chips on the AMD NetSc520
92 demonstration board. If you have one of these boards and would like 92 demonstration board. If you have one of these boards and would like
93 to use the flash chips on it, say 'Y'. 93 to use the flash chips on it, say 'Y'.
94 94
95config MTD_TS5500 95config MTD_TS5500
96 tristate "JEDEC Flash device mapped on Technologic Systems TS-5500" 96 tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
97 depends on X86 && MTD_JEDECPROBE && MTD_PARTITIONS 97 depends on ELAN
98 select MTD_PARTITIONS
99 select MTD_JEDECPROBE
100 select MTD_CFI_AMDSTD
98 help 101 help
99 This provides a driver for the on-board flash of the Technologic 102 This provides a driver for the on-board flash of the Technologic
100 System's TS-5500 board. The flash is split into 3 partitions 103 System's TS-5500 board. The 2MB flash is split into 3 partitions
101 which are accessed as separate MTD devices. 104 which are accessed as separate MTD devices.
102 105
103 mtd0 and mtd2 are the two BIOS drives. Unfortunately the BIOS 106 mtd0 and mtd2 are the two BIOS drives, which use the resident
104 uses a proprietary flash translation layer from General Software, 107 flash disk (RFD) flash translation layer.
105 which is not supported (the drives cannot be mounted). You can
106 create your own file system (jffs for example), but the BIOS
107 won't be able to boot from it.
108 108
109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL. 109 mtd1 allows you to reprogram your BIOS. BE VERY CAREFUL.
110 110
@@ -212,11 +212,18 @@ config MTD_NETtel
212 Support for flash chips on NETtel/SecureEdge/SnapGear boards. 212 Support for flash chips on NETtel/SecureEdge/SnapGear boards.
213 213
214config MTD_ALCHEMY 214config MTD_ALCHEMY
215 tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support' 215 tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
216 depends on MIPS && SOC_AU1X00 216 depends on SOC_AU1X00
217 help 217 help
218 Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards 218 Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
219 219
220config MTD_MTX1
221 tristate "4G Systems MTX-1 Flash device"
222 depends on MIPS && MIPS_MTX1
223 help
224 Flash memory access on 4G Systems MTX-1 Board. If you have one of
225 these boards and would like to use the flash chips on it, say 'Y'.
226
220config MTD_DILNETPC 227config MTD_DILNETPC
221 tristate "CFI Flash device mapped on DIL/Net PC" 228 tristate "CFI Flash device mapped on DIL/Net PC"
222 depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT 229 depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT
@@ -244,14 +251,14 @@ config MTD_L440GX
244 251
245config MTD_SBC8240 252config MTD_SBC8240
246 tristate "Flash device on SBC8240" 253 tristate "Flash device on SBC8240"
247 depends on PPC32 && MTD_JEDECPROBE && 6xx && 8260 254 depends on MTD_JEDECPROBE && 8260
248 help 255 help
249 Flash access on the SBC8240 board from Wind River. See 256 Flash access on the SBC8240 board from Wind River. See
250 <http://www.windriver.com/products/sbc8240/> 257 <http://www.windriver.com/products/sbc8240/>
251 258
252config MTD_TQM8XXL 259config MTD_TQM8XXL
253 tristate "CFI Flash device mapped on TQM8XXL" 260 tristate "CFI Flash device mapped on TQM8XXL"
254 depends on MTD_CFI && PPC32 && 8xx && TQM8xxL 261 depends on MTD_CFI && TQM8xxL
255 help 262 help
256 The TQM8xxL PowerPC board has up to two banks of CFI-compliant 263 The TQM8xxL PowerPC board has up to two banks of CFI-compliant
257 chips, currently uses AMD one. This 'mapping' driver supports 264 chips, currently uses AMD one. This 'mapping' driver supports
@@ -261,7 +268,7 @@ config MTD_TQM8XXL
261 268
262config MTD_RPXLITE 269config MTD_RPXLITE
263 tristate "CFI Flash device mapped on RPX Lite or CLLF" 270 tristate "CFI Flash device mapped on RPX Lite or CLLF"
264 depends on MTD_CFI && PPC32 && 8xx && (RPXCLASSIC || RPXLITE) 271 depends on MTD_CFI && (RPXCLASSIC || RPXLITE)
265 help 272 help
266 The RPXLite PowerPC board has CFI-compliant chips mapped in 273 The RPXLite PowerPC board has CFI-compliant chips mapped in
267 a strange sparse mapping. This 'mapping' driver supports that 274 a strange sparse mapping. This 'mapping' driver supports that
@@ -271,7 +278,7 @@ config MTD_RPXLITE
271 278
272config MTD_MBX860 279config MTD_MBX860
273 tristate "System flash on MBX860 board" 280 tristate "System flash on MBX860 board"
274 depends on MTD_CFI && PPC32 && 8xx && MBX 281 depends on MTD_CFI && MBX
275 help 282 help
276 This enables access routines for the flash chips on the Motorola 283 This enables access routines for the flash chips on the Motorola
277 MBX860 board. If you have one of these boards and would like 284 MBX860 board. If you have one of these boards and would like
@@ -279,7 +286,7 @@ config MTD_MBX860
279 286
280config MTD_DBOX2 287config MTD_DBOX2
281 tristate "CFI Flash device mapped on D-Box2" 288 tristate "CFI Flash device mapped on D-Box2"
282 depends on PPC32 && 8xx && DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD 289 depends on DBOX2 && MTD_CFI_INTELSTD && MTD_CFI_INTELEXT && MTD_CFI_AMDSTD
283 help 290 help
284 This enables access routines for the flash chips on the Nokia/Sagem 291 This enables access routines for the flash chips on the Nokia/Sagem
285 D-Box 2 board. If you have one of these boards and would like to use 292 D-Box 2 board. If you have one of these boards and would like to use
@@ -287,14 +294,14 @@ config MTD_DBOX2
287 294
288config MTD_CFI_FLAGADM 295config MTD_CFI_FLAGADM
289 tristate "CFI Flash device mapping on FlagaDM" 296 tristate "CFI Flash device mapping on FlagaDM"
290 depends on PPC32 && 8xx && MTD_CFI 297 depends on 8xx && MTD_CFI
291 help 298 help
292 Mapping for the Flaga digital module. If you don't have one, ignore 299 Mapping for the Flaga digital module. If you don't have one, ignore
293 this setting. 300 this setting.
294 301
295config MTD_BEECH 302config MTD_BEECH
296 tristate "CFI Flash device mapped on IBM 405LP Beech" 303 tristate "CFI Flash device mapped on IBM 405LP Beech"
297 depends on MTD_CFI && PPC32 && 40x && BEECH 304 depends on MTD_CFI && BEECH
298 help 305 help
299 This enables access routines for the flash chips on the IBM 306 This enables access routines for the flash chips on the IBM
300 405LP Beech board. If you have one of these boards and would like 307 405LP Beech board. If you have one of these boards and would like
@@ -302,7 +309,7 @@ config MTD_BEECH
302 309
303config MTD_ARCTIC 310config MTD_ARCTIC
304 tristate "CFI Flash device mapped on IBM 405LP Arctic" 311 tristate "CFI Flash device mapped on IBM 405LP Arctic"
305 depends on MTD_CFI && PPC32 && 40x && ARCTIC2 312 depends on MTD_CFI && ARCTIC2
306 help 313 help
307 This enables access routines for the flash chips on the IBM 405LP 314 This enables access routines for the flash chips on the IBM 405LP
308 Arctic board. If you have one of these boards and would like to 315 Arctic board. If you have one of these boards and would like to
@@ -310,7 +317,7 @@ config MTD_ARCTIC
310 317
311config MTD_WALNUT 318config MTD_WALNUT
312 tristate "Flash device mapped on IBM 405GP Walnut" 319 tristate "Flash device mapped on IBM 405GP Walnut"
313 depends on MTD_JEDECPROBE && PPC32 && 40x && WALNUT 320 depends on MTD_JEDECPROBE && WALNUT
314 help 321 help
315 This enables access routines for the flash chips on the IBM 405GP 322 This enables access routines for the flash chips on the IBM 405GP
316 Walnut board. If you have one of these boards and would like to 323 Walnut board. If you have one of these boards and would like to
@@ -318,7 +325,7 @@ config MTD_WALNUT
318 325
319config MTD_EBONY 326config MTD_EBONY
320 tristate "Flash devices mapped on IBM 440GP Ebony" 327 tristate "Flash devices mapped on IBM 440GP Ebony"
321 depends on MTD_JEDECPROBE && PPC32 && 44x && EBONY 328 depends on MTD_JEDECPROBE && EBONY
322 help 329 help
323 This enables access routines for the flash chips on the IBM 440GP 330 This enables access routines for the flash chips on the IBM 440GP
324 Ebony board. If you have one of these boards and would like to 331 Ebony board. If you have one of these boards and would like to
@@ -326,7 +333,7 @@ config MTD_EBONY
326 333
327config MTD_OCOTEA 334config MTD_OCOTEA
328 tristate "Flash devices mapped on IBM 440GX Ocotea" 335 tristate "Flash devices mapped on IBM 440GX Ocotea"
329 depends on MTD_CFI && PPC32 && 44x && OCOTEA 336 depends on MTD_CFI && OCOTEA
330 help 337 help
331 This enables access routines for the flash chips on the IBM 440GX 338 This enables access routines for the flash chips on the IBM 440GX
332 Ocotea board. If you have one of these boards and would like to 339 Ocotea board. If you have one of these boards and would like to
@@ -334,12 +341,20 @@ config MTD_OCOTEA
334 341
335config MTD_REDWOOD 342config MTD_REDWOOD
336 tristate "CFI Flash devices mapped on IBM Redwood" 343 tristate "CFI Flash devices mapped on IBM Redwood"
337 depends on MTD_CFI && PPC32 && 4xx && 40x && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 ) 344 depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
338 help 345 help
339 This enables access routines for the flash chips on the IBM 346 This enables access routines for the flash chips on the IBM
340 Redwood board. If you have one of these boards and would like to 347 Redwood board. If you have one of these boards and would like to
341 use the flash chips on it, say 'Y'. 348 use the flash chips on it, say 'Y'.
342 349
350config MTD_TQM834x
351 tristate "Flash device mapped on TQ Components TQM834x Boards"
352 depends on MTD_CFI && TQM834x
353 help
354 This enables access routines for the flash chips on the
355 TQ Components TQM834x boards. If you have one of these boards
356 and would like to use the flash chips on it, say 'Y'.
357
343config MTD_CSTM_MIPS_IXX 358config MTD_CSTM_MIPS_IXX
344 tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board" 359 tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board"
345 depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS 360 depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS
@@ -362,8 +377,8 @@ config MTD_CSTM_MIPS_IXX_START
362 default "0x8000000" 377 default "0x8000000"
363 help 378 help
364 This is the physical memory location that the MTD driver will 379 This is the physical memory location that the MTD driver will
365 use for the flash chips on your particular target board. 380 use for the flash chips on your particular target board.
366 Refer to the memory map which should hopefully be in the 381 Refer to the memory map which should hopefully be in the
367 documentation for your board. 382 documentation for your board.
368 383
369config MTD_CSTM_MIPS_IXX_LEN 384config MTD_CSTM_MIPS_IXX_LEN
@@ -371,7 +386,7 @@ config MTD_CSTM_MIPS_IXX_LEN
371 depends on MTD_CSTM_MIPS_IXX 386 depends on MTD_CSTM_MIPS_IXX
372 default "0x4000000" 387 default "0x4000000"
373 help 388 help
374 This is the total length that the MTD driver will use for the 389 This is the total length that the MTD driver will use for the
375 flash chips on your particular board. Refer to the memory 390 flash chips on your particular board. Refer to the memory
376 map which should hopefully be in the documentation for your 391 map which should hopefully be in the documentation for your
377 board. 392 board.
@@ -405,14 +420,14 @@ config MTD_ARM_INTEGRATOR
405 420
406config MTD_CDB89712 421config MTD_CDB89712
407 tristate "Cirrus CDB89712 evaluation board mappings" 422 tristate "Cirrus CDB89712 evaluation board mappings"
408 depends on ARM && MTD_CFI && ARCH_CDB89712 423 depends on MTD_CFI && ARCH_CDB89712
409 help 424 help
410 This enables access to the flash or ROM chips on the CDB89712 board. 425 This enables access to the flash or ROM chips on the CDB89712 board.
411 If you have such a board, say 'Y'. 426 If you have such a board, say 'Y'.
412 427
413config MTD_SA1100 428config MTD_SA1100
414 tristate "CFI Flash device mapped on StrongARM SA11x0" 429 tristate "CFI Flash device mapped on StrongARM SA11x0"
415 depends on ARM && MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS 430 depends on MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS
416 help 431 help
417 This enables access to the flash chips on most platforms based on 432 This enables access to the flash chips on most platforms based on
418 the SA1100 and SA1110, including the Assabet and the Compaq iPAQ. 433 the SA1100 and SA1110, including the Assabet and the Compaq iPAQ.
@@ -420,13 +435,13 @@ config MTD_SA1100
420 435
421config MTD_IPAQ 436config MTD_IPAQ
422 tristate "CFI Flash device mapped on Compaq/HP iPAQ" 437 tristate "CFI Flash device mapped on Compaq/HP iPAQ"
423 depends on ARM && IPAQ_HANDHELD && MTD_CFI 438 depends on IPAQ_HANDHELD && MTD_CFI
424 help 439 help
425 This provides a driver for the on-board flash of the iPAQ. 440 This provides a driver for the on-board flash of the iPAQ.
426 441
427config MTD_DC21285 442config MTD_DC21285
428 tristate "CFI Flash device mapped on DC21285 Footbridge" 443 tristate "CFI Flash device mapped on DC21285 Footbridge"
429 depends on ARM && MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS 444 depends on MTD_CFI && ARCH_FOOTBRIDGE && MTD_COMPLEX_MAPPINGS
430 help 445 help
431 This provides a driver for the flash accessed using Intel's 446 This provides a driver for the flash accessed using Intel's
432 21285 bridge used with Intel's StrongARM processors. More info at 447 21285 bridge used with Intel's StrongARM processors. More info at
@@ -434,33 +449,33 @@ config MTD_DC21285
434 449
435config MTD_IQ80310 450config MTD_IQ80310
436 tristate "CFI Flash device mapped on the XScale IQ80310 board" 451 tristate "CFI Flash device mapped on the XScale IQ80310 board"
437 depends on ARM && MTD_CFI && ARCH_IQ80310 452 depends on MTD_CFI && ARCH_IQ80310
438 help 453 help
439 This enables access routines for the flash chips on the Intel XScale 454 This enables access routines for the flash chips on the Intel XScale
440 IQ80310 evaluation board. If you have one of these boards and would 455 IQ80310 evaluation board. If you have one of these boards and would
441 like to use the flash chips on it, say 'Y'. 456 like to use the flash chips on it, say 'Y'.
442 457
443config MTD_IXP4XX 458config MTD_IXP4XX
444 tristate "CFI Flash device mapped on Intel IXP4xx based systems" 459 tristate "CFI Flash device mapped on Intel IXP4xx based systems"
445 depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX 460 depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
446 help 461 help
447 This enables MTD access to flash devices on platforms based 462 This enables MTD access to flash devices on platforms based
448 on Intel's IXP4xx family of network processors such as the 463 on Intel's IXP4xx family of network processors such as the
449 IXDP425 and Coyote. If you have an IXP4xx based board and 464 IXDP425 and Coyote. If you have an IXP4xx based board and
450 would like to use the flash chips on it, say 'Y'. 465 would like to use the flash chips on it, say 'Y'.
451 466
452config MTD_IXP2000 467config MTD_IXP2000
453 tristate "CFI Flash device mapped on Intel IXP2000 based systems" 468 tristate "CFI Flash device mapped on Intel IXP2000 based systems"
454 depends on ARM && MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000 469 depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP2000
455 help 470 help
456 This enables MTD access to flash devices on platforms based 471 This enables MTD access to flash devices on platforms based
457 on Intel's IXP2000 family of network processors such as the 472 on Intel's IXP2000 family of network processors such as the
458 IXDP425 and Coyote. If you have an IXP2000 based board and 473 IXDP425 and Coyote. If you have an IXP2000 based board and
459 would like to use the flash chips on it, say 'Y'. 474 would like to use the flash chips on it, say 'Y'.
460 475
461config MTD_EPXA10DB 476config MTD_EPXA10DB
462 tristate "CFI Flash device mapped on Epxa10db" 477 tristate "CFI Flash device mapped on Epxa10db"
463 depends on ARM && MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT 478 depends on MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT
464 help 479 help
465 This enables support for the flash devices on the Altera 480 This enables support for the flash devices on the Altera
466 Excalibur XA10 Development Board. If you are building a kernel 481 Excalibur XA10 Development Board. If you are building a kernel
@@ -468,21 +483,21 @@ config MTD_EPXA10DB
468 483
469config MTD_FORTUNET 484config MTD_FORTUNET
470 tristate "CFI Flash device mapped on the FortuNet board" 485 tristate "CFI Flash device mapped on the FortuNet board"
471 depends on ARM && MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET 486 depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET
472 help 487 help
473 This enables access to the Flash on the FortuNet board. If you 488 This enables access to the Flash on the FortuNet board. If you
474 have such a board, say 'Y'. 489 have such a board, say 'Y'.
475 490
476config MTD_AUTCPU12 491config MTD_AUTCPU12
477 tristate "NV-RAM mapping AUTCPU12 board" 492 tristate "NV-RAM mapping AUTCPU12 board"
478 depends on ARM && ARCH_AUTCPU12 493 depends on ARCH_AUTCPU12
479 help 494 help
480 This enables access to the NV-RAM on autronix autcpu12 board. 495 This enables access to the NV-RAM on autronix autcpu12 board.
481 If you have such a board, say 'Y'. 496 If you have such a board, say 'Y'.
482 497
483config MTD_EDB7312 498config MTD_EDB7312
484 tristate "CFI Flash device mapped on EDB7312" 499 tristate "CFI Flash device mapped on EDB7312"
485 depends on ARM && MTD_CFI 500 depends on ARCH_EDB7312 && MTD_CFI
486 help 501 help
487 This enables access to the CFI Flash on the Cogent EDB7312 board. 502 This enables access to the CFI Flash on the Cogent EDB7312 board.
488 If you have such a board, say 'Y' here. 503 If you have such a board, say 'Y' here.
@@ -496,7 +511,7 @@ config MTD_IMPA7
496 511
497config MTD_CEIVA 512config MTD_CEIVA
498 tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame" 513 tristate "JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame"
499 depends on ARM && MTD_JEDECPROBE && ARCH_CEIVA 514 depends on MTD_JEDECPROBE && ARCH_CEIVA
500 help 515 help
501 This enables access to the flash chips on the Ceiva/Polaroid 516 This enables access to the flash chips on the Ceiva/Polaroid
502 PhotoMax Digital Picture Frame. 517 PhotoMax Digital Picture Frame.
@@ -504,25 +519,31 @@ config MTD_CEIVA
504 519
505config MTD_NOR_TOTO 520config MTD_NOR_TOTO
506 tristate "NOR Flash device on TOTO board" 521 tristate "NOR Flash device on TOTO board"
507 depends on ARM && ARCH_OMAP && OMAP_TOTO 522 depends on ARCH_OMAP && OMAP_TOTO
508 help 523 help
509 This enables access to the NOR flash on the Texas Instruments 524 This enables access to the NOR flash on the Texas Instruments
510 TOTO board. 525 TOTO board.
511 526
512config MTD_H720X 527config MTD_H720X
513 tristate "Hynix evaluation board mappings" 528 tristate "Hynix evaluation board mappings"
514 depends on ARM && MTD_CFI && ( ARCH_H7201 || ARCH_H7202 ) 529 depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
515 help 530 help
516 This enables access to the flash chips on the Hynix evaluation boards. 531 This enables access to the flash chips on the Hynix evaluation boards.
517 If you have such a board, say 'Y'. 532 If you have such a board, say 'Y'.
518 533
519config MTD_MPC1211 534config MTD_MPC1211
520 tristate "CFI Flash device mapped on Interface MPC-1211" 535 tristate "CFI Flash device mapped on Interface MPC-1211"
521 depends on SUPERH && SH_MPC1211 && MTD_CFI 536 depends on SH_MPC1211 && MTD_CFI
522 help 537 help
523 This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02). 538 This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
524 If you have such a board, say 'Y'. 539 If you have such a board, say 'Y'.
525 540
541config MTD_PQ2FADS
542 tristate "JEDEC flash SIMM mapped on PQ2FADS and 8272ADS boards"
543 depends on (ADS8272 || PQ2FADS) && MTD_PARTITIONS && MTD_JEDECPROBE && MTD_PHYSMAP && MTD_CFI_GEOMETRY && MTD_CFI_INTELEXT
544 help
545 This enables access to flash SIMM on PQ2FADS-like boards
546
526config MTD_OMAP_NOR 547config MTD_OMAP_NOR
527 tristate "TI OMAP board mappings" 548 tristate "TI OMAP board mappings"
528 depends on MTD_CFI && ARCH_OMAP 549 depends on MTD_CFI && ARCH_OMAP
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 7bcbc49e329f..7d9e940a1dcd 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# linux/drivers/maps/Makefile 2# linux/drivers/maps/Makefile
3# 3#
4# $Id: Makefile.common,v 1.30 2005/07/02 01:53:24 tpoynor Exp $ 4# $Id: Makefile.common,v 1.34 2005/11/07 11:14:26 gleixner Exp $
5 5
6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y) 6ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
7obj-$(CONFIG_MTD) += map_funcs.o 7obj-$(CONFIG_MTD) += map_funcs.o
@@ -26,7 +26,7 @@ obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o
26obj-$(CONFIG_MTD_MBX860) += mbx860.o 26obj-$(CONFIG_MTD_MBX860) += mbx860.o
27obj-$(CONFIG_MTD_CEIVA) += ceiva.o 27obj-$(CONFIG_MTD_CEIVA) += ceiva.o
28obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o 28obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
29obj-$(CONFIG_MTD_PHYSMAP) += physmap.o 29obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
30obj-$(CONFIG_MTD_PNC2000) += pnc2000.o 30obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
31obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o 31obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
32obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o 32obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
@@ -70,3 +70,6 @@ obj-$(CONFIG_MTD_DMV182) += dmv182.o
70obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o 70obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
71obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o 71obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
72obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o 72obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
73obj-$(CONFIG_MTD_PQ2FADS) += pq2fads.o
74obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o
75obj-$(CONFIG_MTD_TQM834x) += tqm834x.o
diff --git a/drivers/mtd/maps/alchemy-flash.c b/drivers/mtd/maps/alchemy-flash.c
index 27fd2a3c3b60..a57791a6ce40 100644
--- a/drivers/mtd/maps/alchemy-flash.c
+++ b/drivers/mtd/maps/alchemy-flash.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * Flash memory access on AMD Alchemy evaluation boards 2 * Flash memory access on AMD Alchemy evaluation boards
3 * 3 *
4 * $Id: alchemy-flash.c,v 1.1 2005/02/27 21:50:21 ppopov Exp $ 4 * $Id: alchemy-flash.c,v 1.2 2005/11/07 11:14:26 gleixner Exp $
5 * 5 *
6 * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com> 6 * (C) 2003, 2004 Pete Popov <ppopov@embeddedalley.com>
7 * 7 *
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
@@ -22,7 +22,7 @@
22#ifdef DEBUG_RW 22#ifdef DEBUG_RW
23#define DBG(x...) printk(x) 23#define DBG(x...) printk(x)
24#else 24#else
25#define DBG(x...) 25#define DBG(x...)
26#endif 26#endif
27 27
28#ifdef CONFIG_MIPS_PB1000 28#ifdef CONFIG_MIPS_PB1000
@@ -136,7 +136,7 @@ int __init alchemy_mtd_init(void)
136 int nb_parts = 0; 136 int nb_parts = 0;
137 unsigned long window_addr; 137 unsigned long window_addr;
138 unsigned long window_size; 138 unsigned long window_size;
139 139
140 /* Default flash buswidth */ 140 /* Default flash buswidth */
141 alchemy_map.bankwidth = BOARD_FLASH_WIDTH; 141 alchemy_map.bankwidth = BOARD_FLASH_WIDTH;
142 142
@@ -161,7 +161,7 @@ int __init alchemy_mtd_init(void)
161 * Now let's probe for the actual flash. Do it here since 161 * Now let's probe for the actual flash. Do it here since
162 * specific machine settings might have been set above. 162 * specific machine settings might have been set above.
163 */ 163 */
164 printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n", 164 printk(KERN_NOTICE BOARD_MAP_NAME ": probing %d-bit flash bus\n",
165 alchemy_map.bankwidth*8); 165 alchemy_map.bankwidth*8);
166 alchemy_map.virt = ioremap(window_addr, window_size); 166 alchemy_map.virt = ioremap(window_addr, window_size);
167 mymtd = do_map_probe("cfi_probe", &alchemy_map); 167 mymtd = do_map_probe("cfi_probe", &alchemy_map);
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c
index e8a900a77685..c350878d4592 100644
--- a/drivers/mtd/maps/amd76xrom.c
+++ b/drivers/mtd/maps/amd76xrom.c
@@ -2,7 +2,7 @@
2 * amd76xrom.c 2 * amd76xrom.c
3 * 3 *
4 * Normal mappings of chips in physical memory 4 * Normal mappings of chips in physical memory
5 * $Id: amd76xrom.c,v 1.20 2005/03/18 14:04:35 gleixner Exp $ 5 * $Id: amd76xrom.c,v 1.21 2005/11/07 11:14:26 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
@@ -70,7 +70,7 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window)
70 list_del(&map->list); 70 list_del(&map->list);
71 kfree(map); 71 kfree(map);
72 } 72 }
73 if (window->rsrc.parent) 73 if (window->rsrc.parent)
74 release_resource(&window->rsrc); 74 release_resource(&window->rsrc);
75 75
76 if (window->virt) { 76 if (window->virt) {
@@ -107,7 +107,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
107 window->phys = 0xffff0000; /* 64KiB */ 107 window->phys = 0xffff0000; /* 64KiB */
108 } 108 }
109 window->size = 0xffffffffUL - window->phys + 1UL; 109 window->size = 0xffffffffUL - window->phys + 1UL;
110 110
111 /* 111 /*
112 * Try to reserve the window mem region. If this fails then 112 * Try to reserve the window mem region. If this fails then
113 * it is likely due to a fragment of the window being 113 * it is likely due to a fragment of the window being
@@ -138,7 +138,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
138 /* Enable writes through the rom window */ 138 /* Enable writes through the rom window */
139 pci_read_config_byte(pdev, 0x40, &byte); 139 pci_read_config_byte(pdev, 0x40, &byte);
140 pci_write_config_byte(pdev, 0x40, byte | 1); 140 pci_write_config_byte(pdev, 0x40, byte | 1);
141 141
142 /* FIXME handle registers 0x80 - 0x8C the bios region locks */ 142 /* FIXME handle registers 0x80 - 0x8C the bios region locks */
143 143
144 /* For write accesses caches are useless */ 144 /* For write accesses caches are useless */
@@ -186,7 +186,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
186 MOD_NAME, map->map.phys); 186 MOD_NAME, map->map.phys);
187 187
188 /* There is no generic VPP support */ 188 /* There is no generic VPP support */
189 for(map->map.bankwidth = 32; map->map.bankwidth; 189 for(map->map.bankwidth = 32; map->map.bankwidth;
190 map->map.bankwidth >>= 1) 190 map->map.bankwidth >>= 1)
191 { 191 {
192 char **probe_type; 192 char **probe_type;
@@ -239,7 +239,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
239 for(i = 0; i < cfi->numchips; i++) { 239 for(i = 0; i < cfi->numchips; i++) {
240 cfi->chips[i].start += offset; 240 cfi->chips[i].start += offset;
241 } 241 }
242 242
243 /* Now that the mtd devices is complete claim and export it */ 243 /* Now that the mtd devices is complete claim and export it */
244 map->mtd->owner = THIS_MODULE; 244 map->mtd->owner = THIS_MODULE;
245 if (add_mtd_device(map->mtd)) { 245 if (add_mtd_device(map->mtd)) {
@@ -259,9 +259,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
259 259
260 out: 260 out:
261 /* Free any left over map structures */ 261 /* Free any left over map structures */
262 if (map) { 262 kfree(map);
263 kfree(map);
264 }
265 /* See if I have any map structures */ 263 /* See if I have any map structures */
266 if (list_empty(&window->maps)) { 264 if (list_empty(&window->maps)) {
267 amd76xrom_cleanup(window); 265 amd76xrom_cleanup(window);
@@ -279,9 +277,9 @@ static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
279} 277}
280 278
281static struct pci_device_id amd76xrom_pci_tbl[] = { 279static struct pci_device_id amd76xrom_pci_tbl[] = {
282 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, 280 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410,
283 PCI_ANY_ID, PCI_ANY_ID, }, 281 PCI_ANY_ID, PCI_ANY_ID, },
284 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440, 282 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
285 PCI_ANY_ID, PCI_ANY_ID, }, 283 PCI_ANY_ID, PCI_ANY_ID, },
286 { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */ 284 { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */
287 { 0, } 285 { 0, }
diff --git a/drivers/mtd/maps/arctic-mtd.c b/drivers/mtd/maps/arctic-mtd.c
index 777276fd0e15..d95ae582fbe9 100644
--- a/drivers/mtd/maps/arctic-mtd.c
+++ b/drivers/mtd/maps/arctic-mtd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * $Id: arctic-mtd.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: arctic-mtd.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for 4 * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
5 * IBM 405LP Arctic boards. 5 * IBM 405LP Arctic boards.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c
index cf362ccc3c8e..7ed3424dd959 100644
--- a/drivers/mtd/maps/autcpu12-nvram.c
+++ b/drivers/mtd/maps/autcpu12-nvram.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * NV-RAM memory access on autcpu12 2 * NV-RAM memory access on autcpu12
3 * (C) 2002 Thomas Gleixner (gleixner@autronix.de) 3 * (C) 2002 Thomas Gleixner (gleixner@autronix.de)
4 * 4 *
5 * $Id: autcpu12-nvram.c,v 1.8 2004/11/04 13:24:14 gleixner Exp $ 5 * $Id: autcpu12-nvram.c,v 1.9 2005/11/07 11:14:26 gleixner Exp $
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
@@ -55,10 +55,10 @@ static int __init init_autcpu12_sram (void)
55 } 55 }
56 simple_map_init(&autcpu_sram_map); 56 simple_map_init(&autcpu_sram_map);
57 57
58 /* 58 /*
59 * Check for 32K/128K 59 * Check for 32K/128K
60 * read ofs 0 60 * read ofs 0
61 * read ofs 0x10000 61 * read ofs 0x10000
62 * Write complement to ofs 0x100000 62 * Write complement to ofs 0x100000
63 * Read and check result on ofs 0x0 63 * Read and check result on ofs 0x0
64 * Restore contents 64 * Restore contents
@@ -66,7 +66,7 @@ static int __init init_autcpu12_sram (void)
66 save0 = map_read32(&autcpu12_sram_map,0); 66 save0 = map_read32(&autcpu12_sram_map,0);
67 save1 = map_read32(&autcpu12_sram_map,0x10000); 67 save1 = map_read32(&autcpu12_sram_map,0x10000);
68 map_write32(&autcpu12_sram_map,~save0,0x10000); 68 map_write32(&autcpu12_sram_map,~save0,0x10000);
69 /* if we find this pattern on 0x0, we have 32K size 69 /* if we find this pattern on 0x0, we have 32K size
70 * restore contents and exit 70 * restore contents and exit
71 */ 71 */
72 if ( map_read32(&autcpu12_sram_map,0) != save0) { 72 if ( map_read32(&autcpu12_sram_map,0) != save0) {
@@ -89,7 +89,7 @@ map:
89 89
90 sram_mtd->owner = THIS_MODULE; 90 sram_mtd->owner = THIS_MODULE;
91 sram_mtd->erasesize = 16; 91 sram_mtd->erasesize = 16;
92 92
93 if (add_mtd_device(sram_mtd)) { 93 if (add_mtd_device(sram_mtd)) {
94 printk("NV-RAM device addition failed\n"); 94 printk("NV-RAM device addition failed\n");
95 err = -ENOMEM; 95 err = -ENOMEM;
@@ -97,7 +97,7 @@ map:
97 } 97 }
98 98
99 printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K); 99 printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
100 100
101 return 0; 101 return 0;
102 102
103out_probe: 103out_probe:
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c
index bfe994e59265..b7858eb93534 100644
--- a/drivers/mtd/maps/bast-flash.c
+++ b/drivers/mtd/maps/bast-flash.c
@@ -9,7 +9,7 @@
9 * 20-Sep-2004 BJD Initial version 9 * 20-Sep-2004 BJD Initial version
10 * 17-Jan-2005 BJD Add whole device if no partitions found 10 * 17-Jan-2005 BJD Add whole device if no partitions found
11 * 11 *
12 * $Id: bast-flash.c,v 1.2 2005/01/18 11:13:47 bjd Exp $ 12 * $Id: bast-flash.c,v 1.5 2005/11/07 11:14:26 gleixner Exp $
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License as published by
@@ -75,7 +75,7 @@ static void bast_flash_setrw(int to)
75 75
76 local_irq_save(flags); 76 local_irq_save(flags);
77 val = __raw_readb(BAST_VA_CTRL3); 77 val = __raw_readb(BAST_VA_CTRL3);
78 78
79 if (to) 79 if (to)
80 val |= BAST_CPLD_CTRL3_ROMWEN; 80 val |= BAST_CPLD_CTRL3_ROMWEN;
81 else 81 else
@@ -93,7 +93,7 @@ static int bast_flash_remove(struct device *dev)
93 93
94 dev_set_drvdata(dev, NULL); 94 dev_set_drvdata(dev, NULL);
95 95
96 if (info == NULL) 96 if (info == NULL)
97 return 0; 97 return 0;
98 98
99 if (info->map.virt != NULL) 99 if (info->map.virt != NULL)
@@ -104,14 +104,13 @@ static int bast_flash_remove(struct device *dev)
104 map_destroy(info->mtd); 104 map_destroy(info->mtd);
105 } 105 }
106 106
107 if (info->partitions) 107 kfree(info->partitions);
108 kfree(info->partitions);
109 108
110 if (info->area) { 109 if (info->area) {
111 release_resource(info->area); 110 release_resource(info->area);
112 kfree(info->area); 111 kfree(info->area);
113 } 112 }
114 113
115 kfree(info); 114 kfree(info);
116 115
117 return 0; 116 return 0;
@@ -138,15 +137,15 @@ static int bast_flash_probe(struct device *dev)
138 137
139 info->map.phys = res->start; 138 info->map.phys = res->start;
140 info->map.size = res->end - res->start + 1; 139 info->map.size = res->end - res->start + 1;
141 info->map.name = dev->bus_id; 140 info->map.name = dev->bus_id;
142 info->map.bankwidth = 2; 141 info->map.bankwidth = 2;
143 142
144 if (info->map.size > AREA_MAXSIZE) 143 if (info->map.size > AREA_MAXSIZE)
145 info->map.size = AREA_MAXSIZE; 144 info->map.size = AREA_MAXSIZE;
146 145
147 pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__, 146 pr_debug("%s: area %08lx, size %ld\n", __FUNCTION__,
148 info->map.phys, info->map.size); 147 info->map.phys, info->map.size);
149 148
150 info->area = request_mem_region(res->start, info->map.size, 149 info->area = request_mem_region(res->start, info->map.size,
151 pdev->name); 150 pdev->name);
152 if (info->area == NULL) { 151 if (info->area == NULL) {
@@ -163,7 +162,7 @@ static int bast_flash_probe(struct device *dev)
163 err = -EIO; 162 err = -EIO;
164 goto exit_error; 163 goto exit_error;
165 } 164 }
166 165
167 simple_map_init(&info->map); 166 simple_map_init(&info->map);
168 167
169 /* enable the write to the flash area */ 168 /* enable the write to the flash area */
@@ -188,7 +187,7 @@ static int bast_flash_probe(struct device *dev)
188 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0); 187 err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
189 if (err > 0) { 188 if (err > 0) {
190 err = add_mtd_partitions(info->mtd, info->partitions, err); 189 err = add_mtd_partitions(info->mtd, info->partitions, err);
191 if (err) 190 if (err)
192 printk(KERN_ERR PFX "cannot add/parse partitions\n"); 191 printk(KERN_ERR PFX "cannot add/parse partitions\n");
193 } else { 192 } else {
194 err = add_mtd_device(info->mtd); 193 err = add_mtd_device(info->mtd);
@@ -206,6 +205,7 @@ static int bast_flash_probe(struct device *dev)
206 205
207static struct device_driver bast_flash_driver = { 206static struct device_driver bast_flash_driver = {
208 .name = "bast-nor", 207 .name = "bast-nor",
208 .owner = THIS_MODULE,
209 .bus = &platform_bus_type, 209 .bus = &platform_bus_type,
210 .probe = bast_flash_probe, 210 .probe = bast_flash_probe,
211 .remove = bast_flash_remove, 211 .remove = bast_flash_remove,
diff --git a/drivers/mtd/maps/beech-mtd.c b/drivers/mtd/maps/beech-mtd.c
index 5e79c9d5da2b..5df7361d1407 100644
--- a/drivers/mtd/maps/beech-mtd.c
+++ b/drivers/mtd/maps/beech-mtd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * $Id: beech-mtd.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: beech-mtd.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for 4 * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
5 * IBM 405LP Beech boards. 5 * IBM 405LP Beech boards.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
diff --git a/drivers/mtd/maps/cdb89712.c b/drivers/mtd/maps/cdb89712.c
index ab15dac2f936..9f17bb6c5a9d 100644
--- a/drivers/mtd/maps/cdb89712.c
+++ b/drivers/mtd/maps/cdb89712.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Flash on Cirrus CDB89712 2 * Flash on Cirrus CDB89712
3 * 3 *
4 * $Id: cdb89712.c,v 1.10 2004/11/04 13:24:14 gleixner Exp $ 4 * $Id: cdb89712.c,v 1.11 2005/11/07 11:14:26 gleixner Exp $
5 */ 5 */
6 6
7#include <linux/module.h> 7#include <linux/module.h>
@@ -37,13 +37,13 @@ struct resource cdb89712_flash_resource = {
37static int __init init_cdb89712_flash (void) 37static int __init init_cdb89712_flash (void)
38{ 38{
39 int err; 39 int err;
40 40
41 if (request_resource (&ioport_resource, &cdb89712_flash_resource)) { 41 if (request_resource (&ioport_resource, &cdb89712_flash_resource)) {
42 printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n"); 42 printk(KERN_NOTICE "Failed to reserve Cdb89712 FLASH space\n");
43 err = -EBUSY; 43 err = -EBUSY;
44 goto out; 44 goto out;
45 } 45 }
46 46
47 cdb89712_flash_map.virt = ioremap(FLASH_START, FLASH_SIZE); 47 cdb89712_flash_map.virt = ioremap(FLASH_START, FLASH_SIZE);
48 if (!cdb89712_flash_map.virt) { 48 if (!cdb89712_flash_map.virt) {
49 printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n"); 49 printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
@@ -64,13 +64,13 @@ static int __init init_cdb89712_flash (void)
64 } 64 }
65 65
66 flash_mtd->owner = THIS_MODULE; 66 flash_mtd->owner = THIS_MODULE;
67 67
68 if (add_mtd_device(flash_mtd)) { 68 if (add_mtd_device(flash_mtd)) {
69 printk("FLASH device addition failed\n"); 69 printk("FLASH device addition failed\n");
70 err = -ENOMEM; 70 err = -ENOMEM;
71 goto out_probe; 71 goto out_probe;
72 } 72 }
73 73
74 return 0; 74 return 0;
75 75
76out_probe: 76out_probe:
@@ -107,13 +107,13 @@ struct resource cdb89712_sram_resource = {
107static int __init init_cdb89712_sram (void) 107static int __init init_cdb89712_sram (void)
108{ 108{
109 int err; 109 int err;
110 110
111 if (request_resource (&ioport_resource, &cdb89712_sram_resource)) { 111 if (request_resource (&ioport_resource, &cdb89712_sram_resource)) {
112 printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n"); 112 printk(KERN_NOTICE "Failed to reserve Cdb89712 SRAM space\n");
113 err = -EBUSY; 113 err = -EBUSY;
114 goto out; 114 goto out;
115 } 115 }
116 116
117 cdb89712_sram_map.virt = ioremap(SRAM_START, SRAM_SIZE); 117 cdb89712_sram_map.virt = ioremap(SRAM_START, SRAM_SIZE);
118 if (!cdb89712_sram_map.virt) { 118 if (!cdb89712_sram_map.virt) {
119 printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n"); 119 printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
@@ -130,13 +130,13 @@ static int __init init_cdb89712_sram (void)
130 130
131 sram_mtd->owner = THIS_MODULE; 131 sram_mtd->owner = THIS_MODULE;
132 sram_mtd->erasesize = 16; 132 sram_mtd->erasesize = 16;
133 133
134 if (add_mtd_device(sram_mtd)) { 134 if (add_mtd_device(sram_mtd)) {
135 printk("SRAM device addition failed\n"); 135 printk("SRAM device addition failed\n");
136 err = -ENOMEM; 136 err = -ENOMEM;
137 goto out_probe; 137 goto out_probe;
138 } 138 }
139 139
140 return 0; 140 return 0;
141 141
142out_probe: 142out_probe:
@@ -175,13 +175,13 @@ struct resource cdb89712_bootrom_resource = {
175static int __init init_cdb89712_bootrom (void) 175static int __init init_cdb89712_bootrom (void)
176{ 176{
177 int err; 177 int err;
178 178
179 if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) { 179 if (request_resource (&ioport_resource, &cdb89712_bootrom_resource)) {
180 printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n"); 180 printk(KERN_NOTICE "Failed to reserve Cdb89712 BOOTROM space\n");
181 err = -EBUSY; 181 err = -EBUSY;
182 goto out; 182 goto out;
183 } 183 }
184 184
185 cdb89712_bootrom_map.virt = ioremap(BOOTROM_START, BOOTROM_SIZE); 185 cdb89712_bootrom_map.virt = ioremap(BOOTROM_START, BOOTROM_SIZE);
186 if (!cdb89712_bootrom_map.virt) { 186 if (!cdb89712_bootrom_map.virt) {
187 printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n"); 187 printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
@@ -198,13 +198,13 @@ static int __init init_cdb89712_bootrom (void)
198 198
199 bootrom_mtd->owner = THIS_MODULE; 199 bootrom_mtd->owner = THIS_MODULE;
200 bootrom_mtd->erasesize = 0x10000; 200 bootrom_mtd->erasesize = 0x10000;
201 201
202 if (add_mtd_device(bootrom_mtd)) { 202 if (add_mtd_device(bootrom_mtd)) {
203 printk("BootROM device addition failed\n"); 203 printk("BootROM device addition failed\n");
204 err = -ENOMEM; 204 err = -ENOMEM;
205 goto out_probe; 205 goto out_probe;
206 } 206 }
207 207
208 return 0; 208 return 0;
209 209
210out_probe: 210out_probe:
@@ -225,16 +225,16 @@ out:
225static int __init init_cdb89712_maps(void) 225static int __init init_cdb89712_maps(void)
226{ 226{
227 227
228 printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n", 228 printk(KERN_INFO "Cirrus CDB89712 MTD mappings:\n Flash 0x%x at 0x%x\n SRAM 0x%x at 0x%x\n BootROM 0x%x at 0x%x\n",
229 FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START); 229 FLASH_SIZE, FLASH_START, SRAM_SIZE, SRAM_START, BOOTROM_SIZE, BOOTROM_START);
230 230
231 init_cdb89712_flash(); 231 init_cdb89712_flash();
232 init_cdb89712_sram(); 232 init_cdb89712_sram();
233 init_cdb89712_bootrom(); 233 init_cdb89712_bootrom();
234 234
235 return 0; 235 return 0;
236} 236}
237 237
238 238
239static void __exit cleanup_cdb89712_maps(void) 239static void __exit cleanup_cdb89712_maps(void)
240{ 240{
@@ -244,7 +244,7 @@ static void __exit cleanup_cdb89712_maps(void)
244 iounmap((void *)cdb89712_sram_map.virt); 244 iounmap((void *)cdb89712_sram_map.virt);
245 release_resource (&cdb89712_sram_resource); 245 release_resource (&cdb89712_sram_resource);
246 } 246 }
247 247
248 if (flash_mtd) { 248 if (flash_mtd) {
249 del_mtd_device(flash_mtd); 249 del_mtd_device(flash_mtd);
250 map_destroy(flash_mtd); 250 map_destroy(flash_mtd);
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c
index c68b31dc7e6d..5a95ab370a97 100644
--- a/drivers/mtd/maps/ceiva.c
+++ b/drivers/mtd/maps/ceiva.c
@@ -313,8 +313,7 @@ static void __init clps_locate_partitions(struct mtd_info *mtd)
313 313
314static void __exit clps_destroy_partitions(void) 314static void __exit clps_destroy_partitions(void)
315{ 315{
316 if (parsed_parts) 316 kfree(parsed_parts);
317 kfree(parsed_parts);
318} 317}
319 318
320static struct mtd_info *mymtd; 319static struct mtd_info *mymtd;
diff --git a/drivers/mtd/maps/cfi_flagadm.c b/drivers/mtd/maps/cfi_flagadm.c
index f72e4f894b32..6a8c0415bde8 100644
--- a/drivers/mtd/maps/cfi_flagadm.c
+++ b/drivers/mtd/maps/cfi_flagadm.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is> 2 * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
3 * 3 *
4 * $Id: cfi_flagadm.c,v 1.14 2004/11/04 13:24:14 gleixner Exp $ 4 * $Id: cfi_flagadm.c,v 1.15 2005/11/07 11:14:26 gleixner Exp $
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your 8 * Free Software Foundation; either version 2 of the License, or (at your
@@ -42,7 +42,7 @@
42 */ 42 */
43 43
44#define FLASH_PHYS_ADDR 0x40000000 44#define FLASH_PHYS_ADDR 0x40000000
45#define FLASH_SIZE 0x400000 45#define FLASH_SIZE 0x400000
46 46
47#define FLASH_PARTITION0_ADDR 0x00000000 47#define FLASH_PARTITION0_ADDR 0x00000000
48#define FLASH_PARTITION0_SIZE 0x00020000 48#define FLASH_PARTITION0_SIZE 0x00020000
@@ -79,7 +79,7 @@ struct mtd_partition flagadm_parts[] = {
79 .offset = FLASH_PARTITION2_ADDR, 79 .offset = FLASH_PARTITION2_ADDR,
80 .size = FLASH_PARTITION2_SIZE 80 .size = FLASH_PARTITION2_SIZE
81 }, 81 },
82 { 82 {
83 .name = "Persistant storage", 83 .name = "Persistant storage",
84 .offset = FLASH_PARTITION3_ADDR, 84 .offset = FLASH_PARTITION3_ADDR,
85 .size = FLASH_PARTITION3_SIZE 85 .size = FLASH_PARTITION3_SIZE
@@ -91,10 +91,10 @@ struct mtd_partition flagadm_parts[] = {
91static struct mtd_info *mymtd; 91static struct mtd_info *mymtd;
92 92
93int __init init_flagadm(void) 93int __init init_flagadm(void)
94{ 94{
95 printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n", 95 printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n",
96 FLASH_SIZE, FLASH_PHYS_ADDR); 96 FLASH_SIZE, FLASH_PHYS_ADDR);
97 97
98 flagadm_map.phys = FLASH_PHYS_ADDR; 98 flagadm_map.phys = FLASH_PHYS_ADDR;
99 flagadm_map.virt = ioremap(FLASH_PHYS_ADDR, 99 flagadm_map.virt = ioremap(FLASH_PHYS_ADDR,
100 FLASH_SIZE); 100 FLASH_SIZE);
diff --git a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c
index ae9252fbf176..a370953c1513 100644
--- a/drivers/mtd/maps/cstm_mips_ixx.c
+++ b/drivers/mtd/maps/cstm_mips_ixx.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * $Id: cstm_mips_ixx.c,v 1.12 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: cstm_mips_ixx.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions. 4 * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
5 * Config with both CFI and JEDEC device support. 5 * Config with both CFI and JEDEC device support.
6 * 6 *
7 * Basically physmap.c with the addition of partitions and 7 * Basically physmap.c with the addition of partitions and
8 * an array of mapping info to accomodate more than one flash type per board. 8 * an array of mapping info to accomodate more than one flash type per board.
9 * 9 *
10 * Copyright 2000 MontaVista Software Inc. 10 * Copyright 2000 MontaVista Software Inc.
@@ -69,7 +69,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
69 __u16 data; 69 __u16 data;
70 __u8 data1; 70 __u8 data1;
71 static u8 first = 1; 71 static u8 first = 1;
72 72
73 // Set GPIO port B pin3 to high 73 // Set GPIO port B pin3 to high
74 data = *(__u16 *)(CC_GPBCR); 74 data = *(__u16 *)(CC_GPBCR);
75 data = (data & 0xff0f) | 0x0040; 75 data = (data & 0xff0f) | 0x0040;
@@ -85,7 +85,7 @@ void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
85 } else { 85 } else {
86 if (!--vpp_count) { 86 if (!--vpp_count) {
87 __u16 data; 87 __u16 data;
88 88
89 // Set GPIO port B pin3 to high 89 // Set GPIO port B pin3 to high
90 data = *(__u16 *)(CC_GPBCR); 90 data = *(__u16 *)(CC_GPBCR);
91 data = (data & 0xff3f) | 0x0040; 91 data = (data & 0xff3f) | 0x0040;
@@ -109,8 +109,8 @@ struct cstm_mips_ixx_info {
109}; 109};
110 110
111#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) 111#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
112#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type 112#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
113const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = 113const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
114{ 114{
115 { // 28F128J3A in 2x16 configuration 115 { // 28F128J3A in 2x16 configuration
116 "big flash", // name 116 "big flash", // name
@@ -131,10 +131,10 @@ static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP
131}, 131},
132}; 132};
133#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ 133#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
134#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type 134#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type
135const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = 135const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
136{ 136{
137 { 137 {
138 "MTD flash", // name 138 "MTD flash", // name
139 CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr 139 CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr
140 CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size 140 CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size
@@ -144,7 +144,7 @@ const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =
144 144
145}; 145};
146static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = { 146static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
147{ 147{
148 { 148 {
149 .name = "main partition", 149 .name = "main partition",
150 .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN, 150 .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN,
@@ -165,7 +165,7 @@ int __init init_cstm_mips_ixx(void)
165 165
166 /* Initialize mapping */ 166 /* Initialize mapping */
167 for (i=0;i<PHYSMAP_NUMBER;i++) { 167 for (i=0;i<PHYSMAP_NUMBER;i++) {
168 printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n", 168 printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
169 cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr); 169 cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
170 170
171 171
@@ -235,7 +235,7 @@ void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32
235 235
236 offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ; 236 offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ;
237 237
238 *(__u32 *)CC_CONFADDR = offset; 238 *(__u32 *)CC_CONFADDR = offset;
239 *(__u32 *)CC_CONFDATA = data; 239 *(__u32 *)CC_CONFDATA = data;
240} 240}
241void setup_ITE_IVR_flash() 241void setup_ITE_IVR_flash()
diff --git a/drivers/mtd/maps/dbox2-flash.c b/drivers/mtd/maps/dbox2-flash.c
index d850a27a4b59..49d90542fc75 100644
--- a/drivers/mtd/maps/dbox2-flash.c
+++ b/drivers/mtd/maps/dbox2-flash.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: dbox2-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: dbox2-flash.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * D-Box 2 flash driver 4 * D-Box 2 flash driver
5 */ 5 */
@@ -21,38 +21,38 @@
21static struct mtd_partition partition_info[]= { 21static struct mtd_partition partition_info[]= {
22 { 22 {
23 .name = "BR bootloader", 23 .name = "BR bootloader",
24 .size = 128 * 1024, 24 .size = 128 * 1024,
25 .offset = 0, 25 .offset = 0,
26 .mask_flags = MTD_WRITEABLE 26 .mask_flags = MTD_WRITEABLE
27 }, 27 },
28 { 28 {
29 .name = "FLFS (U-Boot)", 29 .name = "FLFS (U-Boot)",
30 .size = 128 * 1024, 30 .size = 128 * 1024,
31 .offset = MTDPART_OFS_APPEND, 31 .offset = MTDPART_OFS_APPEND,
32 .mask_flags = 0 32 .mask_flags = 0
33 }, 33 },
34 { 34 {
35 .name = "Root (SquashFS)", 35 .name = "Root (SquashFS)",
36 .size = 7040 * 1024, 36 .size = 7040 * 1024,
37 .offset = MTDPART_OFS_APPEND, 37 .offset = MTDPART_OFS_APPEND,
38 .mask_flags = 0 38 .mask_flags = 0
39 }, 39 },
40 { 40 {
41 .name = "var (JFFS2)", 41 .name = "var (JFFS2)",
42 .size = 896 * 1024, 42 .size = 896 * 1024,
43 .offset = MTDPART_OFS_APPEND, 43 .offset = MTDPART_OFS_APPEND,
44 .mask_flags = 0 44 .mask_flags = 0
45 }, 45 },
46 { 46 {
47 .name = "Flash without bootloader", 47 .name = "Flash without bootloader",
48 .size = MTDPART_SIZ_FULL, 48 .size = MTDPART_SIZ_FULL,
49 .offset = 128 * 1024, 49 .offset = 128 * 1024,
50 .mask_flags = 0 50 .mask_flags = 0
51 }, 51 },
52 { 52 {
53 .name = "Complete Flash", 53 .name = "Complete Flash",
54 .size = MTDPART_SIZ_FULL, 54 .size = MTDPART_SIZ_FULL,
55 .offset = 0, 55 .offset = 0,
56 .mask_flags = MTD_WRITEABLE 56 .mask_flags = MTD_WRITEABLE
57 } 57 }
58}; 58};
@@ -88,16 +88,16 @@ int __init init_dbox2_flash(void)
88 if (!mymtd) { 88 if (!mymtd) {
89 // Probe for single Intel 28F640 89 // Probe for single Intel 28F640
90 dbox2_flash_map.bankwidth = 2; 90 dbox2_flash_map.bankwidth = 2;
91 91
92 mymtd = do_map_probe("cfi_probe", &dbox2_flash_map); 92 mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
93 } 93 }
94 94
95 if (mymtd) { 95 if (mymtd) {
96 mymtd->owner = THIS_MODULE; 96 mymtd->owner = THIS_MODULE;
97 97
98 /* Create MTD devices for each partition. */ 98 /* Create MTD devices for each partition. */
99 add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS); 99 add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
100 100
101 return 0; 101 return 0;
102 } 102 }
103 103
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c
index e5b74169fde6..701620b6baed 100644
--- a/drivers/mtd/maps/dc21285.c
+++ b/drivers/mtd/maps/dc21285.c
@@ -4,8 +4,8 @@
4 * (C) 2000 Nicolas Pitre <nico@cam.org> 4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: dc21285.c,v 1.22 2004/11/01 13:39:21 rmk Exp $ 8 * $Id: dc21285.c,v 1.24 2005/11/07 11:14:26 gleixner Exp $
9 */ 9 */
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/module.h> 11#include <linux/module.h>
@@ -27,9 +27,9 @@
27static struct mtd_info *dc21285_mtd; 27static struct mtd_info *dc21285_mtd;
28 28
29#ifdef CONFIG_ARCH_NETWINDER 29#ifdef CONFIG_ARCH_NETWINDER
30/* 30/*
31 * This is really ugly, but it seams to be the only 31 * This is really ugly, but it seams to be the only
32 * realiable way to do it, as the cpld state machine 32 * realiable way to do it, as the cpld state machine
33 * is unpredictible. So we have a 25us penalty per 33 * is unpredictible. So we have a 25us penalty per
34 * write access. 34 * write access.
35 */ 35 */
@@ -150,7 +150,7 @@ static struct map_info dc21285_map = {
150static struct mtd_partition *dc21285_parts; 150static struct mtd_partition *dc21285_parts;
151static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 151static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
152#endif 152#endif
153 153
154static int __init init_dc21285(void) 154static int __init init_dc21285(void)
155{ 155{
156 156
@@ -160,20 +160,20 @@ static int __init init_dc21285(void)
160 160
161 /* Determine bankwidth */ 161 /* Determine bankwidth */
162 switch (*CSR_SA110_CNTL & (3<<14)) { 162 switch (*CSR_SA110_CNTL & (3<<14)) {
163 case SA110_CNTL_ROMWIDTH_8: 163 case SA110_CNTL_ROMWIDTH_8:
164 dc21285_map.bankwidth = 1; 164 dc21285_map.bankwidth = 1;
165 dc21285_map.read = dc21285_read8; 165 dc21285_map.read = dc21285_read8;
166 dc21285_map.write = dc21285_write8; 166 dc21285_map.write = dc21285_write8;
167 dc21285_map.copy_to = dc21285_copy_to_8; 167 dc21285_map.copy_to = dc21285_copy_to_8;
168 break; 168 break;
169 case SA110_CNTL_ROMWIDTH_16: 169 case SA110_CNTL_ROMWIDTH_16:
170 dc21285_map.bankwidth = 2; 170 dc21285_map.bankwidth = 2;
171 dc21285_map.read = dc21285_read16; 171 dc21285_map.read = dc21285_read16;
172 dc21285_map.write = dc21285_write16; 172 dc21285_map.write = dc21285_write16;
173 dc21285_map.copy_to = dc21285_copy_to_16; 173 dc21285_map.copy_to = dc21285_copy_to_16;
174 break; 174 break;
175 case SA110_CNTL_ROMWIDTH_32: 175 case SA110_CNTL_ROMWIDTH_32:
176 dc21285_map.bankwidth = 4; 176 dc21285_map.bankwidth = 4;
177 dc21285_map.read = dc21285_read32; 177 dc21285_map.read = dc21285_read32;
178 dc21285_map.write = dc21285_write32; 178 dc21285_map.write = dc21285_write32;
179 dc21285_map.copy_to = dc21285_copy_to_32; 179 dc21285_map.copy_to = dc21285_copy_to_32;
@@ -201,20 +201,20 @@ static int __init init_dc21285(void)
201 if (!dc21285_mtd) { 201 if (!dc21285_mtd) {
202 iounmap(dc21285_map.virt); 202 iounmap(dc21285_map.virt);
203 return -ENXIO; 203 return -ENXIO;
204 } 204 }
205 205
206 dc21285_mtd->owner = THIS_MODULE; 206 dc21285_mtd->owner = THIS_MODULE;
207 207
208#ifdef CONFIG_MTD_PARTITIONS 208#ifdef CONFIG_MTD_PARTITIONS
209 nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0); 209 nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
210 if (nrparts > 0) 210 if (nrparts > 0)
211 add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts); 211 add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts);
212 else 212 else
213#endif 213#endif
214 add_mtd_device(dc21285_mtd); 214 add_mtd_device(dc21285_mtd);
215 215
216 if(machine_is_ebsa285()) { 216 if(machine_is_ebsa285()) {
217 /* 217 /*
218 * Flash timing is determined with bits 19-16 of the 218 * Flash timing is determined with bits 19-16 of the
219 * CSR_SA110_CNTL. The value is the number of wait cycles, or 219 * CSR_SA110_CNTL. The value is the number of wait cycles, or
220 * 0 for 16 cycles (the default). Cycles are 20 ns. 220 * 0 for 16 cycles (the default). Cycles are 20 ns.
@@ -227,7 +227,7 @@ static int __init init_dc21285(void)
227 /* tristate time */ 227 /* tristate time */
228 *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24)); 228 *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
229 } 229 }
230 230
231 return 0; 231 return 0;
232} 232}
233 233
diff --git a/drivers/mtd/maps/dilnetpc.c b/drivers/mtd/maps/dilnetpc.c
index f99519692cb7..b51c757817d8 100644
--- a/drivers/mtd/maps/dilnetpc.c
+++ b/drivers/mtd/maps/dilnetpc.c
@@ -14,7 +14,7 @@
14 * along with this program; if not, write to the Free Software 14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
16 * 16 *
17 * $Id: dilnetpc.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $ 17 * $Id: dilnetpc.c,v 1.20 2005/11/07 11:14:26 gleixner Exp $
18 * 18 *
19 * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems 19 * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
20 * featuring the AMD Elan SC410 processor. There are two variants of this 20 * featuring the AMD Elan SC410 processor. There are two variants of this
@@ -272,13 +272,13 @@ static struct map_info dnpc_map = {
272 272
273static struct mtd_partition partition_info[]= 273static struct mtd_partition partition_info[]=
274{ 274{
275 { 275 {
276 .name = "ADNP boot", 276 .name = "ADNP boot",
277 .offset = 0, 277 .offset = 0,
278 .size = 0xf0000, 278 .size = 0xf0000,
279 }, 279 },
280 { 280 {
281 .name = "ADNP system BIOS", 281 .name = "ADNP system BIOS",
282 .offset = MTDPART_OFS_NXTBLK, 282 .offset = MTDPART_OFS_NXTBLK,
283 .size = 0x10000, 283 .size = 0x10000,
284#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED 284#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -291,7 +291,7 @@ static struct mtd_partition partition_info[]=
291 .size = 0x2f0000, 291 .size = 0x2f0000,
292 }, 292 },
293 { 293 {
294 .name = "ADNP system BIOS entry", 294 .name = "ADNP system BIOS entry",
295 .offset = MTDPART_OFS_NXTBLK, 295 .offset = MTDPART_OFS_NXTBLK,
296 .size = MTDPART_SIZ_FULL, 296 .size = MTDPART_SIZ_FULL,
297#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED 297#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -325,9 +325,9 @@ static struct mtd_info *merged_mtd;
325 325
326static struct mtd_partition higlvl_partition_info[]= 326static struct mtd_partition higlvl_partition_info[]=
327{ 327{
328 { 328 {
329 .name = "ADNP boot block", 329 .name = "ADNP boot block",
330 .offset = 0, 330 .offset = 0,
331 .size = CONFIG_MTD_DILNETPC_BOOTSIZE, 331 .size = CONFIG_MTD_DILNETPC_BOOTSIZE,
332 }, 332 },
333 { 333 {
@@ -335,8 +335,8 @@ static struct mtd_partition higlvl_partition_info[]=
335 .offset = MTDPART_OFS_NXTBLK, 335 .offset = MTDPART_OFS_NXTBLK,
336 .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000, 336 .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
337 }, 337 },
338 { 338 {
339 .name = "ADNP system BIOS + BIOS Entry", 339 .name = "ADNP system BIOS + BIOS Entry",
340 .offset = MTDPART_OFS_NXTBLK, 340 .offset = MTDPART_OFS_NXTBLK,
341 .size = MTDPART_SIZ_FULL, 341 .size = MTDPART_SIZ_FULL,
342#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED 342#ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
@@ -371,7 +371,7 @@ static int __init init_dnpc(void)
371 371
372 /* 372 /*
373 ** determine hardware (DNP/ADNP/invalid) 373 ** determine hardware (DNP/ADNP/invalid)
374 */ 374 */
375 if((is_dnp = dnp_adnp_probe()) < 0) 375 if((is_dnp = dnp_adnp_probe()) < 0)
376 return -ENXIO; 376 return -ENXIO;
377 377
@@ -397,13 +397,13 @@ static int __init init_dnpc(void)
397 ++dnpc_map.name; 397 ++dnpc_map.name;
398 for(i = 0; i < NUM_PARTITIONS; i++) 398 for(i = 0; i < NUM_PARTITIONS; i++)
399 ++partition_info[i].name; 399 ++partition_info[i].name;
400 higlvl_partition_info[1].size = DNP_WINDOW_SIZE - 400 higlvl_partition_info[1].size = DNP_WINDOW_SIZE -
401 CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000; 401 CONFIG_MTD_DILNETPC_BOOTSIZE - 0x20000;
402 for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++) 402 for(i = 0; i < NUM_HIGHLVL_PARTITIONS; i++)
403 ++higlvl_partition_info[i].name; 403 ++higlvl_partition_info[i].name;
404 } 404 }
405 405
406 printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n", 406 printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
407 is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys); 407 is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys);
408 408
409 dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size); 409 dnpc_map.virt = ioremap_nocache(dnpc_map.phys, dnpc_map.size);
@@ -436,7 +436,7 @@ static int __init init_dnpc(void)
436 iounmap(dnpc_map.virt); 436 iounmap(dnpc_map.virt);
437 return -ENXIO; 437 return -ENXIO;
438 } 438 }
439 439
440 mymtd->owner = THIS_MODULE; 440 mymtd->owner = THIS_MODULE;
441 441
442 /* 442 /*
diff --git a/drivers/mtd/maps/dmv182.c b/drivers/mtd/maps/dmv182.c
index b9bc63503e26..b993ac01a9a5 100644
--- a/drivers/mtd/maps/dmv182.c
+++ b/drivers/mtd/maps/dmv182.c
@@ -1,10 +1,10 @@
1 1
2/* 2/*
3 * drivers/mtd/maps/svme182.c 3 * drivers/mtd/maps/svme182.c
4 * 4 *
5 * Flash map driver for the Dy4 SVME182 board 5 * Flash map driver for the Dy4 SVME182 board
6 * 6 *
7 * $Id: dmv182.c,v 1.5 2004/11/04 13:24:14 gleixner Exp $ 7 * $Id: dmv182.c,v 1.6 2005/11/07 11:14:26 gleixner Exp $
8 * 8 *
9 * Copyright 2003-2004, TimeSys Corporation 9 * Copyright 2003-2004, TimeSys Corporation
10 * 10 *
@@ -104,7 +104,7 @@ static int __init init_svme182(void)
104 partitions = svme182_partitions; 104 partitions = svme182_partitions;
105 105
106 svme182_map.virt = ioremap(FLASH_BASE_ADDR, svme182_map.size); 106 svme182_map.virt = ioremap(FLASH_BASE_ADDR, svme182_map.size);
107 107
108 if (svme182_map.virt == 0) { 108 if (svme182_map.virt == 0) {
109 printk("Failed to ioremap FLASH memory area.\n"); 109 printk("Failed to ioremap FLASH memory area.\n");
110 return -EIO; 110 return -EIO;
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
index b9d9cf4854b6..60a6e51d662f 100644
--- a/drivers/mtd/maps/ebony.c
+++ b/drivers/mtd/maps/ebony.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * $Id: ebony.c,v 1.15 2004/12/09 18:39:54 holindho Exp $ 2 * $Id: ebony.c,v 1.16 2005/11/07 11:14:26 gleixner Exp $
3 * 3 *
4 * Mapping for Ebony user flash 4 * Mapping for Ebony user flash
5 * 5 *
6 * Matt Porter <mporter@kernel.crashing.org> 6 * Matt Porter <mporter@kernel.crashing.org>
@@ -21,7 +21,6 @@
21#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/version.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <asm/ibm44x.h> 25#include <asm/ibm44x.h>
27#include <platforms/4xx/ebony.h> 26#include <platforms/4xx/ebony.h>
@@ -85,7 +84,7 @@ int __init init_ebony(void)
85 small_flash_base = EBONY_SMALL_FLASH_LOW2; 84 small_flash_base = EBONY_SMALL_FLASH_LOW2;
86 else 85 else
87 small_flash_base = EBONY_SMALL_FLASH_LOW1; 86 small_flash_base = EBONY_SMALL_FLASH_LOW1;
88 87
89 if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) && 88 if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
90 !EBONY_ONBRD_FLASH_EN(fpga0_reg)) 89 !EBONY_ONBRD_FLASH_EN(fpga0_reg))
91 large_flash_base = EBONY_LARGE_FLASH_LOW; 90 large_flash_base = EBONY_LARGE_FLASH_LOW;
diff --git a/drivers/mtd/maps/edb7312.c b/drivers/mtd/maps/edb7312.c
index 8b0da394f3fa..b48a3473ffc1 100644
--- a/drivers/mtd/maps/edb7312.c
+++ b/drivers/mtd/maps/edb7312.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * $Id: edb7312.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: edb7312.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Handle mapping of the NOR flash on Cogent EDB7312 boards 4 * Handle mapping of the NOR flash on Cogent EDB7312 boards
5 * 5 *
6 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 * Copyright 2002 SYSGO Real-Time Solutions GmbH
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
@@ -46,7 +46,7 @@ struct map_info edb7312nor_map = {
46#ifdef CONFIG_MTD_PARTITIONS 46#ifdef CONFIG_MTD_PARTITIONS
47 47
48/* 48/*
49 * MTD partitioning stuff 49 * MTD partitioning stuff
50 */ 50 */
51static struct mtd_partition static_partitions[3] = 51static struct mtd_partition static_partitions[3] =
52{ 52{
@@ -80,7 +80,7 @@ int __init init_edb7312nor(void)
80 const char **type; 80 const char **type;
81 const char *part_type = 0; 81 const char *part_type = 0;
82 82
83 printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n", 83 printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
84 WINDOW_SIZE, WINDOW_ADDR); 84 WINDOW_SIZE, WINDOW_ADDR);
85 edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); 85 edb7312nor_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
86 86
@@ -88,7 +88,7 @@ int __init init_edb7312nor(void)
88 printk(MSG_PREFIX "failed to ioremap\n"); 88 printk(MSG_PREFIX "failed to ioremap\n");
89 return -EIO; 89 return -EIO;
90 } 90 }
91 91
92 simple_map_init(&edb7312nor_map); 92 simple_map_init(&edb7312nor_map);
93 93
94 mymtd = 0; 94 mymtd = 0;
diff --git a/drivers/mtd/maps/epxa10db-flash.c b/drivers/mtd/maps/epxa10db-flash.c
index 1df6188926b3..265b079fe934 100644
--- a/drivers/mtd/maps/epxa10db-flash.c
+++ b/drivers/mtd/maps/epxa10db-flash.c
@@ -5,7 +5,7 @@
5 * Copyright (C) 2001 Altera Corporation 5 * Copyright (C) 2001 Altera Corporation
6 * Copyright (C) 2001 Red Hat, Inc. 6 * Copyright (C) 2001 Red Hat, Inc.
7 * 7 *
8 * $Id: epxa10db-flash.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 8 * $Id: epxa10db-flash.c,v 1.15 2005/11/07 11:14:27 gleixner Exp $
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ static const char *probes[] = { "RedBoot", "afs", NULL };
62static int __init epxa_mtd_init(void) 62static int __init epxa_mtd_init(void)
63{ 63{
64 int i; 64 int i;
65 65
66 printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START); 66 printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
67 67
68 epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE); 68 epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE);
@@ -126,8 +126,8 @@ static void __exit epxa_mtd_cleanup(void)
126} 126}
127 127
128 128
129/* 129/*
130 * This will do for now, once we decide which bootldr we're finally 130 * This will do for now, once we decide which bootldr we're finally
131 * going to use then we'll remove this function and do it properly 131 * going to use then we'll remove this function and do it properly
132 * 132 *
133 * Partions are currently (as offsets from base of flash): 133 * Partions are currently (as offsets from base of flash):
@@ -140,7 +140,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
140 struct mtd_partition *parts; 140 struct mtd_partition *parts;
141 int ret, i; 141 int ret, i;
142 int npartitions = 0; 142 int npartitions = 0;
143 char *names; 143 char *names;
144 const char *name = "jffs"; 144 const char *name = "jffs";
145 145
146 printk("Using default partitions for %s\n",BOARD_NAME); 146 printk("Using default partitions for %s\n",BOARD_NAME);
@@ -152,7 +152,7 @@ static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_pa
152 goto out; 152 goto out;
153 } 153 }
154 i=0; 154 i=0;
155 names = (char *)&parts[npartitions]; 155 names = (char *)&parts[npartitions];
156 parts[i].name = names; 156 parts[i].name = names;
157 names += strlen(name) + 1; 157 names += strlen(name) + 1;
158 strcpy(parts[i].name, name); 158 strcpy(parts[i].name, name);
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c
index 00f7bbe5479e..c6bf4e1219ef 100644
--- a/drivers/mtd/maps/fortunet.c
+++ b/drivers/mtd/maps/fortunet.c
@@ -1,6 +1,6 @@
1/* fortunet.c memory map 1/* fortunet.c memory map
2 * 2 *
3 * $Id: fortunet.c,v 1.9 2004/11/04 13:24:14 gleixner Exp $ 3 * $Id: fortunet.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
4 */ 4 */
5 5
6#include <linux/module.h> 6#include <linux/module.h>
@@ -212,7 +212,7 @@ int __init init_fortunet(void)
212 212
213 map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical, 213 map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
214 214
215 map_regions[ix].map_info.virt = 215 map_regions[ix].map_info.virt =
216 ioremap_nocache( 216 ioremap_nocache(
217 map_regions[ix].window_addr_physical, 217 map_regions[ix].window_addr_physical,
218 map_regions[ix].map_info.size); 218 map_regions[ix].map_info.size);
diff --git a/drivers/mtd/maps/h720x-flash.c b/drivers/mtd/maps/h720x-flash.c
index c73828171d9b..319094821101 100644
--- a/drivers/mtd/maps/h720x-flash.c
+++ b/drivers/mtd/maps/h720x-flash.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * Flash memory access on Hynix GMS30C7201/HMS30C7202 based 2 * Flash memory access on Hynix GMS30C7201/HMS30C7202 based
3 * evaluation boards 3 * evaluation boards
4 * 4 *
5 * $Id: h720x-flash.c,v 1.11 2004/11/04 13:24:14 gleixner Exp $ 5 * $Id: h720x-flash.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
6 * 6 *
7 * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com> 7 * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com>
8 * 2003 Thomas Gleixner <tglx@linutronix.de> 8 * 2003 Thomas Gleixner <tglx@linutronix.de>
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
@@ -72,7 +72,7 @@ int __init h720x_mtd_init(void)
72{ 72{
73 73
74 char *part_type = NULL; 74 char *part_type = NULL;
75 75
76 h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE); 76 h720x_map.virt = ioremap(FLASH_PHYS, FLASH_SIZE);
77 77
78 if (!h720x_map.virt) { 78 if (!h720x_map.virt) {
@@ -91,7 +91,7 @@ int __init h720x_mtd_init(void)
91 h720x_map.bankwidth = 2; 91 h720x_map.bankwidth = 2;
92 mymtd = do_map_probe("cfi_probe", &h720x_map); 92 mymtd = do_map_probe("cfi_probe", &h720x_map);
93 } 93 }
94 94
95 if (mymtd) { 95 if (mymtd) {
96 mymtd->owner = THIS_MODULE; 96 mymtd->owner = THIS_MODULE;
97 97
@@ -124,11 +124,11 @@ static void __exit h720x_mtd_cleanup(void)
124 del_mtd_partitions(mymtd); 124 del_mtd_partitions(mymtd);
125 map_destroy(mymtd); 125 map_destroy(mymtd);
126 } 126 }
127 127
128 /* Free partition info, if commandline partition was used */ 128 /* Free partition info, if commandline partition was used */
129 if (mtd_parts && (mtd_parts != h720x_partitions)) 129 if (mtd_parts && (mtd_parts != h720x_partitions))
130 kfree (mtd_parts); 130 kfree (mtd_parts);
131 131
132 if (h720x_map.virt) { 132 if (h720x_map.virt) {
133 iounmap((void *)h720x_map.virt); 133 iounmap((void *)h720x_map.virt);
134 h720x_map.virt = 0; 134 h720x_map.virt = 0;
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c
index e505207cd489..ea5073781b3a 100644
--- a/drivers/mtd/maps/ichxrom.c
+++ b/drivers/mtd/maps/ichxrom.c
@@ -2,7 +2,7 @@
2 * ichxrom.c 2 * ichxrom.c
3 * 3 *
4 * Normal mappings of chips in physical memory 4 * Normal mappings of chips in physical memory
5 * $Id: ichxrom.c,v 1.18 2005/07/07 10:26:20 dwmw2 Exp $ 5 * $Id: ichxrom.c,v 1.19 2005/11/07 11:14:27 gleixner Exp $
6 */ 6 */
7 7
8#include <linux/module.h> 8#include <linux/module.h>
@@ -101,7 +101,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
101 * you can only really attach a FWH to an ICHX there 101 * you can only really attach a FWH to an ICHX there
102 * a number of simplifications you can make. 102 * a number of simplifications you can make.
103 * 103 *
104 * Also you can page firmware hubs if an 8MB window isn't enough 104 * Also you can page firmware hubs if an 8MB window isn't enough
105 * but don't currently handle that case either. 105 * but don't currently handle that case either.
106 */ 106 */
107 window->pdev = pdev; 107 window->pdev = pdev;
@@ -144,7 +144,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
144 window->phys = 0xfff00000; 144 window->phys = 0xfff00000;
145 } 145 }
146 else if ((byte & 0x80) == 0x80) { 146 else if ((byte & 0x80) == 0x80) {
147 window->phys = 0xfff80000; 147 window->phys = 0xfff80000;
148 } 148 }
149 149
150 if (window->phys == 0) { 150 if (window->phys == 0) {
@@ -233,7 +233,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
233 * in a factory setting. So in-place programming 233 * in a factory setting. So in-place programming
234 * needs to use a different method. 234 * needs to use a different method.
235 */ 235 */
236 for(map->map.bankwidth = 32; map->map.bankwidth; 236 for(map->map.bankwidth = 32; map->map.bankwidth;
237 map->map.bankwidth >>= 1) 237 map->map.bankwidth >>= 1)
238 { 238 {
239 char **probe_type; 239 char **probe_type;
@@ -286,7 +286,7 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
286 for(i = 0; i < cfi->numchips; i++) { 286 for(i = 0; i < cfi->numchips; i++) {
287 cfi->chips[i].start += offset; 287 cfi->chips[i].start += offset;
288 } 288 }
289 289
290 /* Now that the mtd devices is complete claim and export it */ 290 /* Now that the mtd devices is complete claim and export it */
291 map->mtd->owner = THIS_MODULE; 291 map->mtd->owner = THIS_MODULE;
292 if (add_mtd_device(map->mtd)) { 292 if (add_mtd_device(map->mtd)) {
@@ -306,9 +306,8 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
306 306
307 out: 307 out:
308 /* Free any left over map structures */ 308 /* Free any left over map structures */
309 if (map) { 309 kfree(map);
310 kfree(map); 310
311 }
312 /* See if I have any map structures */ 311 /* See if I have any map structures */
313 if (list_empty(&window->maps)) { 312 if (list_empty(&window->maps)) {
314 ichxrom_cleanup(window); 313 ichxrom_cleanup(window);
@@ -325,11 +324,11 @@ static void __devexit ichxrom_remove_one (struct pci_dev *pdev)
325} 324}
326 325
327static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = { 326static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
328 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, 327 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
329 PCI_ANY_ID, PCI_ANY_ID, }, 328 PCI_ANY_ID, PCI_ANY_ID, },
330 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, 329 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
331 PCI_ANY_ID, PCI_ANY_ID, }, 330 PCI_ANY_ID, PCI_ANY_ID, },
332 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, 331 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
333 PCI_ANY_ID, PCI_ANY_ID, }, 332 PCI_ANY_ID, PCI_ANY_ID, },
334 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, 333 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
335 PCI_ANY_ID, PCI_ANY_ID, }, 334 PCI_ANY_ID, PCI_ANY_ID, },
diff --git a/drivers/mtd/maps/impa7.c b/drivers/mtd/maps/impa7.c
index cb39172c81d2..ba7f40311a7e 100644
--- a/drivers/mtd/maps/impa7.c
+++ b/drivers/mtd/maps/impa7.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * $Id: impa7.c,v 1.13 2004/11/04 13:24:14 gleixner Exp $ 2 * $Id: impa7.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Handle mapping of the NOR flash on implementa A7 boards 4 * Handle mapping of the NOR flash on implementa A7 boards
5 * 5 *
6 * Copyright 2002 SYSGO Real-Time Solutions GmbH 6 * Copyright 2002 SYSGO Real-Time Solutions GmbH
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
@@ -55,7 +55,7 @@ static struct map_info impa7_map[NUM_FLASHBANKS] = {
55#ifdef CONFIG_MTD_PARTITIONS 55#ifdef CONFIG_MTD_PARTITIONS
56 56
57/* 57/*
58 * MTD partitioning stuff 58 * MTD partitioning stuff
59 */ 59 */
60static struct mtd_partition static_partitions[] = 60static struct mtd_partition static_partitions[] =
61{ 61{
@@ -108,9 +108,9 @@ int __init init_impa7(void)
108 impa7_mtd[i]->owner = THIS_MODULE; 108 impa7_mtd[i]->owner = THIS_MODULE;
109 devicesfound++; 109 devicesfound++;
110#ifdef CONFIG_MTD_PARTITIONS 110#ifdef CONFIG_MTD_PARTITIONS
111 mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i], 111 mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
112 probes, 112 probes,
113 &mtd_parts[i], 113 &mtd_parts[i],
114 0); 114 0);
115 if (mtd_parts_nb[i] > 0) { 115 if (mtd_parts_nb[i] > 0) {
116 part_type = "command line"; 116 part_type = "command line";
@@ -121,16 +121,16 @@ int __init init_impa7(void)
121 } 121 }
122 122
123 printk(KERN_NOTICE MSG_PREFIX 123 printk(KERN_NOTICE MSG_PREFIX
124 "using %s partition definition\n", 124 "using %s partition definition\n",
125 part_type); 125 part_type);
126 add_mtd_partitions(impa7_mtd[i], 126 add_mtd_partitions(impa7_mtd[i],
127 mtd_parts[i], mtd_parts_nb[i]); 127 mtd_parts[i], mtd_parts_nb[i]);
128#else 128#else
129 add_mtd_device(impa7_mtd[i]); 129 add_mtd_device(impa7_mtd[i]);
130 130
131#endif 131#endif
132 } 132 }
133 else 133 else
134 iounmap((void *)impa7_map[i].virt); 134 iounmap((void *)impa7_map[i].virt);
135 } 135 }
136 return devicesfound == 0 ? -ENXIO : 0; 136 return devicesfound == 0 ? -ENXIO : 0;
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c
index d14a0185b8f4..fe738fd8d6f8 100644
--- a/drivers/mtd/maps/integrator-flash.c
+++ b/drivers/mtd/maps/integrator-flash.c
@@ -1,28 +1,28 @@
1/*====================================================================== 1/*======================================================================
2 2
3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver 3 drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
4 4
5 Copyright (C) 2000 ARM Limited 5 Copyright (C) 2000 ARM Limited
6 Copyright (C) 2003 Deep Blue Solutions Ltd. 6 Copyright (C) 2003 Deep Blue Solutions Ltd.
7 7
8 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or 10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version. 11 (at your option) any later version.
12 12
13 This program is distributed in the hope that it will be useful, 13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details. 16 GNU General Public License for more details.
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 21
22 This is access code for flashes using ARM's flash partitioning 22 This is access code for flashes using ARM's flash partitioning
23 standards. 23 standards.
24 24
25 $Id: integrator-flash.c,v 1.18 2004/11/01 13:26:15 rmk Exp $ 25 $Id: integrator-flash.c,v 1.20 2005/11/07 11:14:27 gleixner Exp $
26 26
27======================================================================*/ 27======================================================================*/
28 28
@@ -148,8 +148,7 @@ static int armflash_probe(struct device *_dev)
148 del_mtd_partitions(info->mtd); 148 del_mtd_partitions(info->mtd);
149 map_destroy(info->mtd); 149 map_destroy(info->mtd);
150 } 150 }
151 if (info->parts) 151 kfree(info->parts);
152 kfree(info->parts);
153 152
154 no_device: 153 no_device:
155 iounmap(base); 154 iounmap(base);
@@ -176,8 +175,7 @@ static int armflash_remove(struct device *_dev)
176 del_mtd_partitions(info->mtd); 175 del_mtd_partitions(info->mtd);
177 map_destroy(info->mtd); 176 map_destroy(info->mtd);
178 } 177 }
179 if (info->parts) 178 kfree(info->parts);
180 kfree(info->parts);
181 179
182 iounmap(info->map.virt); 180 iounmap(info->map.virt);
183 release_resource(info->res); 181 release_resource(info->res);
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c
index 712401810841..35097c9bbf50 100644
--- a/drivers/mtd/maps/ipaq-flash.c
+++ b/drivers/mtd/maps/ipaq-flash.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based) 2 * Flash memory access on iPAQ Handhelds (either SA1100 or PXA250 based)
3 * 3 *
4 * (C) 2000 Nicolas Pitre <nico@cam.org> 4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com> 5 * (C) 2002 Hewlett-Packard Company <jamey.hicks@hp.com>
6 * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes 6 * (C) 2003 Christian Pellegrin <chri@ascensit.com>, <chri@infis.univ.ts.it>: concatenation of multiple flashes
7 * 7 *
8 * $Id: ipaq-flash.c,v 1.3 2004/11/04 13:24:15 gleixner Exp $ 8 * $Id: ipaq-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
@@ -107,7 +107,7 @@ static struct mtd_partition h3xxx_partitions[] = {
107#ifndef CONFIG_LAB 107#ifndef CONFIG_LAB
108 mask_flags: MTD_WRITEABLE, /* force read-only */ 108 mask_flags: MTD_WRITEABLE, /* force read-only */
109#endif 109#endif
110 }, 110 },
111 { 111 {
112 name: "H3XXX root jffs2", 112 name: "H3XXX root jffs2",
113#ifndef CONFIG_LAB 113#ifndef CONFIG_LAB
@@ -148,7 +148,7 @@ static DEFINE_SPINLOCK(ipaq_vpp_lock);
148static void h3xxx_set_vpp(struct map_info *map, int vpp) 148static void h3xxx_set_vpp(struct map_info *map, int vpp)
149{ 149{
150 static int nest = 0; 150 static int nest = 0;
151 151
152 spin_lock(&ipaq_vpp_lock); 152 spin_lock(&ipaq_vpp_lock);
153 if (vpp) 153 if (vpp)
154 nest++; 154 nest++;
@@ -191,7 +191,7 @@ static unsigned long cs_phys[] = {
191 SA1100_CS3_PHYS, 191 SA1100_CS3_PHYS,
192 SA1100_CS4_PHYS, 192 SA1100_CS4_PHYS,
193 SA1100_CS5_PHYS, 193 SA1100_CS5_PHYS,
194#else 194#else
195 PXA_CS0_PHYS, 195 PXA_CS0_PHYS,
196 PXA_CS1_PHYS, 196 PXA_CS1_PHYS,
197 PXA_CS2_PHYS, 197 PXA_CS2_PHYS,
@@ -216,7 +216,7 @@ int __init ipaq_mtd_init(void)
216 216
217 /* Default flash bankwidth */ 217 /* Default flash bankwidth */
218 // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4; 218 // ipaq_map.bankwidth = (MSC0 & MSC_RBW) ? 2 : 4;
219 219
220 if (machine_is_h1900()) 220 if (machine_is_h1900())
221 { 221 {
222 /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */ 222 /* For our intents, the h1900 is not a real iPAQ, so we special-case it. */
@@ -229,7 +229,7 @@ int __init ipaq_mtd_init(void)
229 else 229 else
230 for(i=0; i<MAX_IPAQ_CS; i++) 230 for(i=0; i<MAX_IPAQ_CS; i++)
231 ipaq_map[i].bankwidth = 4; 231 ipaq_map[i].bankwidth = 4;
232 232
233 /* 233 /*
234 * Static partition definition selection 234 * Static partition definition selection
235 */ 235 */
@@ -309,7 +309,7 @@ int __init ipaq_mtd_init(void)
309 return -ENXIO; 309 return -ENXIO;
310 } else 310 } else
311 printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size); 311 printk(KERN_NOTICE "iPAQ flash: found %d bytes\n", my_sub_mtd[i]->size);
312 312
313 /* do we really need this debugging? --joshua 20030703 */ 313 /* do we really need this debugging? --joshua 20030703 */
314 // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]); 314 // printk("my_sub_mtd[%d]=%p\n", i, my_sub_mtd[i]);
315 my_sub_mtd[i]->owner = THIS_MODULE; 315 my_sub_mtd[i]->owner = THIS_MODULE;
@@ -333,11 +333,11 @@ int __init ipaq_mtd_init(void)
333#else 333#else
334 mymtd = my_sub_mtd[0]; 334 mymtd = my_sub_mtd[0];
335 335
336 /* 336 /*
337 *In the very near future, command line partition parsing 337 *In the very near future, command line partition parsing
338 * will use the device name as 'mtd-id' instead of a value 338 * will use the device name as 'mtd-id' instead of a value
339 * passed to the parse_cmdline_partitions() routine. Since 339 * passed to the parse_cmdline_partitions() routine. Since
340 * the bootldr says 'ipaq', make sure it continues to work. 340 * the bootldr says 'ipaq', make sure it continues to work.
341 */ 341 */
342 mymtd->name = "ipaq"; 342 mymtd->name = "ipaq";
343 343
@@ -385,7 +385,7 @@ int __init ipaq_mtd_init(void)
385 */ 385 */
386 386
387 i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0); 387 i = parse_mtd_partitions(mymtd, part_probes, &parsed_parts, 0);
388 388
389 if (i > 0) { 389 if (i > 0) {
390 nb_parts = parsed_nr_parts = i; 390 nb_parts = parsed_nr_parts = i;
391 parts = parsed_parts; 391 parts = parsed_parts;
@@ -423,16 +423,15 @@ static void __exit ipaq_mtd_cleanup(void)
423#endif 423#endif
424 map_destroy(mymtd); 424 map_destroy(mymtd);
425#ifdef CONFIG_MTD_CONCAT 425#ifdef CONFIG_MTD_CONCAT
426 for(i=0; i<MAX_IPAQ_CS; i++) 426 for(i=0; i<MAX_IPAQ_CS; i++)
427#else 427#else
428 for(i=1; i<MAX_IPAQ_CS; i++) 428 for(i=1; i<MAX_IPAQ_CS; i++)
429#endif 429#endif
430 { 430 {
431 if (my_sub_mtd[i]) 431 if (my_sub_mtd[i])
432 map_destroy(my_sub_mtd[i]); 432 map_destroy(my_sub_mtd[i]);
433 } 433 }
434 if (parsed_parts) 434 kfree(parsed_parts);
435 kfree(parsed_parts);
436 } 435 }
437} 436}
438 437
@@ -445,14 +444,14 @@ static int __init h1900_special_case(void)
445 ipaq_map[0].phys = 0x0; 444 ipaq_map[0].phys = 0x0;
446 ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1); 445 ipaq_map[0].virt = __ioremap(0x0, 0x04000000, 0, 1);
447 ipaq_map[0].bankwidth = 2; 446 ipaq_map[0].bankwidth = 2;
448 447
449 printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt); 448 printk(KERN_NOTICE "iPAQ flash: probing %d-bit flash bus, window=%lx with JEDEC.\n", ipaq_map[0].bankwidth*8, ipaq_map[0].virt);
450 mymtd = do_map_probe("jedec_probe", &ipaq_map[0]); 449 mymtd = do_map_probe("jedec_probe", &ipaq_map[0]);
451 if (!mymtd) 450 if (!mymtd)
452 return -ENODEV; 451 return -ENODEV;
453 add_mtd_device(mymtd); 452 add_mtd_device(mymtd);
454 printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n"); 453 printk(KERN_NOTICE "iPAQ flash: registered h1910 flash\n");
455 454
456 return 0; 455 return 0;
457} 456}
458 457
diff --git a/drivers/mtd/maps/iq80310.c b/drivers/mtd/maps/iq80310.c
index 558d014e7acc..62d9e87d84e2 100644
--- a/drivers/mtd/maps/iq80310.c
+++ b/drivers/mtd/maps/iq80310.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * $Id: iq80310.c,v 1.20 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: iq80310.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Mapping for the Intel XScale IQ80310 evaluation board 4 * Mapping for the Intel XScale IQ80310 evaluation board
5 * 5 *
6 * Author: Nicolas Pitre 6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc. 7 * Copyright: (C) 2001 MontaVista Software Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -103,8 +103,7 @@ static void __exit cleanup_iq80310(void)
103 if (mymtd) { 103 if (mymtd) {
104 del_mtd_partitions(mymtd); 104 del_mtd_partitions(mymtd);
105 map_destroy(mymtd); 105 map_destroy(mymtd);
106 if (parsed_parts) 106 kfree(parsed_parts);
107 kfree(parsed_parts);
108 } 107 }
109 if (iq80310_map.virt) 108 if (iq80310_map.virt)
110 iounmap((void *)iq80310_map.virt); 109 iounmap((void *)iq80310_map.virt);
diff --git a/drivers/mtd/maps/ixp2000.c b/drivers/mtd/maps/ixp2000.c
index 00b9f67580f1..641eb2b55e9f 100644
--- a/drivers/mtd/maps/ixp2000.c
+++ b/drivers/mtd/maps/ixp2000.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ixp2000.c,v 1.6 2005/03/18 14:07:46 gleixner Exp $ 2 * $Id: ixp2000.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/ixp2000.c 4 * drivers/mtd/maps/ixp2000.c
5 * 5 *
@@ -14,7 +14,7 @@
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as 15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 * 17 *
18 */ 18 */
19 19
20#include <linux/module.h> 20#include <linux/module.h>
@@ -46,8 +46,8 @@ struct ixp2000_flash_info {
46}; 46};
47 47
48static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs) 48static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs)
49{ 49{
50 unsigned long (*set_bank)(unsigned long) = 50 unsigned long (*set_bank)(unsigned long) =
51 (unsigned long(*)(unsigned long))map->map_priv_2; 51 (unsigned long(*)(unsigned long))map->map_priv_2;
52 52
53 return (set_bank ? set_bank(ofs) : ofs); 53 return (set_bank ? set_bank(ofs) : ofs);
@@ -55,8 +55,8 @@ static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long
55 55
56#ifdef __ARMEB__ 56#ifdef __ARMEB__
57/* 57/*
58 * Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which 58 * Rev A0 and A1 of IXP2400 silicon have a broken addressing unit which
59 * causes the lower address bits to be XORed with 0x11 on 8 bit accesses 59 * causes the lower address bits to be XORed with 0x11 on 8 bit accesses
60 * and XORed with 0x10 on 16 bit accesses. See the spec update, erratum 44. 60 * and XORed with 0x10 on 16 bit accesses. See the spec update, erratum 44.
61 */ 61 */
62static int erratum44_workaround = 0; 62static int erratum44_workaround = 0;
@@ -90,7 +90,7 @@ static void ixp2000_flash_copy_from(struct map_info *map, void *to,
90 unsigned long from, ssize_t len) 90 unsigned long from, ssize_t len)
91{ 91{
92 from = flash_bank_setup(map, from); 92 from = flash_bank_setup(map, from);
93 while(len--) 93 while(len--)
94 *(__u8 *) to++ = *(__u8 *)(map->map_priv_1 + from++); 94 *(__u8 *) to++ = *(__u8 *)(map->map_priv_1 + from++);
95} 95}
96 96
@@ -129,8 +129,7 @@ static int ixp2000_flash_remove(struct device *_dev)
129 if (info->map.map_priv_1) 129 if (info->map.map_priv_1)
130 iounmap((void *) info->map.map_priv_1); 130 iounmap((void *) info->map.map_priv_1);
131 131
132 if (info->partitions) { 132 kfree(info->partitions);
133 kfree(info->partitions); }
134 133
135 if (info->res) { 134 if (info->res) {
136 release_resource(info->res); 135 release_resource(info->res);
@@ -149,11 +148,11 @@ static int ixp2000_flash_probe(struct device *_dev)
149 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; 148 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
150 struct platform_device *dev = to_platform_device(_dev); 149 struct platform_device *dev = to_platform_device(_dev);
151 struct ixp2000_flash_data *ixp_data = dev->dev.platform_data; 150 struct ixp2000_flash_data *ixp_data = dev->dev.platform_data;
152 struct flash_platform_data *plat; 151 struct flash_platform_data *plat;
153 struct ixp2000_flash_info *info; 152 struct ixp2000_flash_info *info;
154 unsigned long window_size; 153 unsigned long window_size;
155 int err = -1; 154 int err = -1;
156 155
157 if (!ixp_data) 156 if (!ixp_data)
158 return -ENODEV; 157 return -ENODEV;
159 158
@@ -162,7 +161,7 @@ static int ixp2000_flash_probe(struct device *_dev)
162 return -ENODEV; 161 return -ENODEV;
163 162
164 window_size = dev->resource->end - dev->resource->start + 1; 163 window_size = dev->resource->end - dev->resource->start + 1;
165 dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n", 164 dev_info(_dev, "Probe of IXP2000 flash(%d banks x %dMiB)\n",
166 ixp_data->nr_banks, ((u32)window_size >> 20)); 165 ixp_data->nr_banks, ((u32)window_size >> 20));
167 166
168 if (plat->width != 1) { 167 if (plat->width != 1) {
@@ -175,7 +174,7 @@ static int ixp2000_flash_probe(struct device *_dev)
175 if(!info) { 174 if(!info) {
176 err = -ENOMEM; 175 err = -ENOMEM;
177 goto Error; 176 goto Error;
178 } 177 }
179 memzero(info, sizeof(struct ixp2000_flash_info)); 178 memzero(info, sizeof(struct ixp2000_flash_info));
180 179
181 dev_set_drvdata(&dev->dev, info); 180 dev_set_drvdata(&dev->dev, info);
@@ -185,7 +184,7 @@ static int ixp2000_flash_probe(struct device *_dev)
185 * not attempt to do a direct access on us. 184 * not attempt to do a direct access on us.
186 */ 185 */
187 info->map.phys = NO_XIP; 186 info->map.phys = NO_XIP;
188 187
189 info->nr_banks = ixp_data->nr_banks; 188 info->nr_banks = ixp_data->nr_banks;
190 info->map.size = ixp_data->nr_banks * window_size; 189 info->map.size = ixp_data->nr_banks * window_size;
191 info->map.bankwidth = 1; 190 info->map.bankwidth = 1;
@@ -193,7 +192,7 @@ static int ixp2000_flash_probe(struct device *_dev)
193 /* 192 /*
194 * map_priv_2 is used to store a ptr to to the bank_setup routine 193 * map_priv_2 is used to store a ptr to to the bank_setup routine
195 */ 194 */
196 info->map.map_priv_2 = (void __iomem *) ixp_data->bank_setup; 195 info->map.map_priv_2 = (unsigned long) ixp_data->bank_setup;
197 196
198 info->map.name = dev->dev.bus_id; 197 info->map.name = dev->dev.bus_id;
199 info->map.read = ixp2000_flash_read8; 198 info->map.read = ixp2000_flash_read8;
@@ -201,8 +200,8 @@ static int ixp2000_flash_probe(struct device *_dev)
201 info->map.copy_from = ixp2000_flash_copy_from; 200 info->map.copy_from = ixp2000_flash_copy_from;
202 info->map.copy_to = ixp2000_flash_copy_to; 201 info->map.copy_to = ixp2000_flash_copy_to;
203 202
204 info->res = request_mem_region(dev->resource->start, 203 info->res = request_mem_region(dev->resource->start,
205 dev->resource->end - dev->resource->start + 1, 204 dev->resource->end - dev->resource->start + 1,
206 dev->dev.bus_id); 205 dev->dev.bus_id);
207 if (!info->res) { 206 if (!info->res) {
208 dev_err(_dev, "Could not reserve memory region\n"); 207 dev_err(_dev, "Could not reserve memory region\n");
@@ -210,7 +209,7 @@ static int ixp2000_flash_probe(struct device *_dev)
210 goto Error; 209 goto Error;
211 } 210 }
212 211
213 info->map.map_priv_1 = ioremap(dev->resource->start, 212 info->map.map_priv_1 = (unsigned long) ioremap(dev->resource->start,
214 dev->resource->end - dev->resource->start + 1); 213 dev->resource->end - dev->resource->start + 1);
215 if (!info->map.map_priv_1) { 214 if (!info->map.map_priv_1) {
216 dev_err(_dev, "Failed to ioremap flash region\n"); 215 dev_err(_dev, "Failed to ioremap flash region\n");
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index 733a9297a562..56b3a355bf7b 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ixp4xx.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: ixp4xx.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/ixp4xx.c 4 * drivers/mtd/maps/ixp4xx.c
5 * 5 *
@@ -45,7 +45,7 @@
45static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs) 45static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
46{ 46{
47 map_word val; 47 map_word val;
48 val.x[0] = *(__u16 *) (map->map_priv_1 + ofs); 48 val.x[0] = le16_to_cpu(readw(map->virt + ofs));
49 return val; 49 return val;
50} 50}
51 51
@@ -59,35 +59,35 @@ static void ixp4xx_copy_from(struct map_info *map, void *to,
59{ 59{
60 int i; 60 int i;
61 u8 *dest = (u8 *) to; 61 u8 *dest = (u8 *) to;
62 u16 *src = (u16 *) (map->map_priv_1 + from); 62 void __iomem *src = map->virt + from;
63 u16 data; 63 u16 data;
64 64
65 for (i = 0; i < (len / 2); i++) { 65 for (i = 0; i < (len / 2); i++) {
66 data = src[i]; 66 data = le16_to_cpu(readw(src + 2*i));
67 dest[i * 2] = BYTE0(data); 67 dest[i * 2] = BYTE0(data);
68 dest[i * 2 + 1] = BYTE1(data); 68 dest[i * 2 + 1] = BYTE1(data);
69 } 69 }
70 70
71 if (len & 1) 71 if (len & 1)
72 dest[len - 1] = BYTE0(src[i]); 72 dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i)));
73} 73}
74 74
75/* 75/*
76 * Unaligned writes are ignored, causing the 8-bit 76 * Unaligned writes are ignored, causing the 8-bit
77 * probe to fail and proceed to the 16-bit probe (which succeeds). 77 * probe to fail and proceed to the 16-bit probe (which succeeds).
78 */ 78 */
79static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr) 79static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
80{ 80{
81 if (!(adr & 1)) 81 if (!(adr & 1))
82 *(__u16 *) (map->map_priv_1 + adr) = d.x[0]; 82 writew(cpu_to_le16(d.x[0]), map->virt + adr);
83} 83}
84 84
85/* 85/*
86 * Fast write16 function without the probing check above 86 * Fast write16 function without the probing check above
87 */ 87 */
88static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr) 88static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
89{ 89{
90 *(__u16 *) (map->map_priv_1 + adr) = d.x[0]; 90 writew(cpu_to_le16(d.x[0]), map->virt + adr);
91} 91}
92 92
93struct ixp4xx_flash_info { 93struct ixp4xx_flash_info {
@@ -104,28 +104,20 @@ static int ixp4xx_flash_remove(struct device *_dev)
104 struct platform_device *dev = to_platform_device(_dev); 104 struct platform_device *dev = to_platform_device(_dev);
105 struct flash_platform_data *plat = dev->dev.platform_data; 105 struct flash_platform_data *plat = dev->dev.platform_data;
106 struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev); 106 struct ixp4xx_flash_info *info = dev_get_drvdata(&dev->dev);
107 map_word d;
108 107
109 dev_set_drvdata(&dev->dev, NULL); 108 dev_set_drvdata(&dev->dev, NULL);
110 109
111 if(!info) 110 if(!info)
112 return 0; 111 return 0;
113 112
114 /*
115 * This is required for a soft reboot to work.
116 */
117 d.x[0] = 0xff;
118 ixp4xx_write16(&info->map, d, 0x55 * 0x2);
119
120 if (info->mtd) { 113 if (info->mtd) {
121 del_mtd_partitions(info->mtd); 114 del_mtd_partitions(info->mtd);
122 map_destroy(info->mtd); 115 map_destroy(info->mtd);
123 } 116 }
124 if (info->map.map_priv_1) 117 if (info->map.virt)
125 iounmap((void *) info->map.map_priv_1); 118 iounmap(info->map.virt);
126 119
127 if (info->partitions) 120 kfree(info->partitions);
128 kfree(info->partitions);
129 121
130 if (info->res) { 122 if (info->res) {
131 release_resource(info->res); 123 release_resource(info->res);
@@ -135,9 +127,6 @@ static int ixp4xx_flash_remove(struct device *_dev)
135 if (plat->exit) 127 if (plat->exit)
136 plat->exit(); 128 plat->exit();
137 129
138 /* Disable flash write */
139 *IXP4XX_EXP_CS0 &= ~IXP4XX_FLASH_WRITABLE;
140
141 return 0; 130 return 0;
142} 131}
143 132
@@ -161,17 +150,11 @@ static int ixp4xx_flash_probe(struct device *_dev)
161 if(!info) { 150 if(!info) {
162 err = -ENOMEM; 151 err = -ENOMEM;
163 goto Error; 152 goto Error;
164 } 153 }
165 memzero(info, sizeof(struct ixp4xx_flash_info)); 154 memzero(info, sizeof(struct ixp4xx_flash_info));
166 155
167 dev_set_drvdata(&dev->dev, info); 156 dev_set_drvdata(&dev->dev, info);
168 157
169 /*
170 * Enable flash write
171 * TODO: Move this out to board specific code
172 */
173 *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
174
175 /* 158 /*
176 * Tell the MTD layer we're not 1:1 mapped so that it does 159 * Tell the MTD layer we're not 1:1 mapped so that it does
177 * not attempt to do a direct access on us. 160 * not attempt to do a direct access on us.
@@ -190,8 +173,8 @@ static int ixp4xx_flash_probe(struct device *_dev)
190 info->map.write = ixp4xx_probe_write16, 173 info->map.write = ixp4xx_probe_write16,
191 info->map.copy_from = ixp4xx_copy_from, 174 info->map.copy_from = ixp4xx_copy_from,
192 175
193 info->res = request_mem_region(dev->resource->start, 176 info->res = request_mem_region(dev->resource->start,
194 dev->resource->end - dev->resource->start + 1, 177 dev->resource->end - dev->resource->start + 1,
195 "IXP4XXFlash"); 178 "IXP4XXFlash");
196 if (!info->res) { 179 if (!info->res) {
197 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n"); 180 printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
@@ -199,9 +182,9 @@ static int ixp4xx_flash_probe(struct device *_dev)
199 goto Error; 182 goto Error;
200 } 183 }
201 184
202 info->map.map_priv_1 = ioremap(dev->resource->start, 185 info->map.virt = ioremap(dev->resource->start,
203 dev->resource->end - dev->resource->start + 1); 186 dev->resource->end - dev->resource->start + 1);
204 if (!info->map.map_priv_1) { 187 if (!info->map.virt) {
205 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n"); 188 printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
206 err = -EIO; 189 err = -EIO;
207 goto Error; 190 goto Error;
@@ -214,7 +197,7 @@ static int ixp4xx_flash_probe(struct device *_dev)
214 goto Error; 197 goto Error;
215 } 198 }
216 info->mtd->owner = THIS_MODULE; 199 info->mtd->owner = THIS_MODULE;
217 200
218 /* Use the fast version */ 201 /* Use the fast version */
219 info->map.write = ixp4xx_write16, 202 info->map.write = ixp4xx_write16,
220 203
@@ -259,4 +242,3 @@ module_exit(ixp4xx_flash_exit);
259MODULE_LICENSE("GPL"); 242MODULE_LICENSE("GPL");
260MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems"); 243MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems");
261MODULE_AUTHOR("Deepak Saxena"); 244MODULE_AUTHOR("Deepak Saxena");
262
diff --git a/drivers/mtd/maps/l440gx.c b/drivers/mtd/maps/l440gx.c
index b08668212ab7..851bf9576052 100644
--- a/drivers/mtd/maps/l440gx.c
+++ b/drivers/mtd/maps/l440gx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: l440gx.c,v 1.17 2004/11/28 09:40:39 dwmw2 Exp $ 2 * $Id: l440gx.c,v 1.18 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * BIOS Flash chip on Intel 440GX board. 4 * BIOS Flash chip on Intel 440GX board.
5 * 5 *
@@ -49,7 +49,7 @@ static struct map_info l440gx_map = {
49 .bankwidth = BUSWIDTH, 49 .bankwidth = BUSWIDTH,
50 .phys = WINDOW_ADDR, 50 .phys = WINDOW_ADDR,
51#if 0 51#if 0
52 /* FIXME verify that this is the 52 /* FIXME verify that this is the
53 * appripriate code for vpp enable/disable 53 * appripriate code for vpp enable/disable
54 */ 54 */
55 .set_vpp = l440gx_set_vpp 55 .set_vpp = l440gx_set_vpp
@@ -62,10 +62,10 @@ static int __init init_l440gx(void)
62 struct resource *pm_iobase; 62 struct resource *pm_iobase;
63 __u16 word; 63 __u16 word;
64 64
65 dev = pci_find_device(PCI_VENDOR_ID_INTEL, 65 dev = pci_find_device(PCI_VENDOR_ID_INTEL,
66 PCI_DEVICE_ID_INTEL_82371AB_0, NULL); 66 PCI_DEVICE_ID_INTEL_82371AB_0, NULL);
67 67
68 pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL, 68 pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
69 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 69 PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
70 70
71 if (!dev || !pm_dev) { 71 if (!dev || !pm_dev) {
@@ -82,10 +82,10 @@ static int __init init_l440gx(void)
82 simple_map_init(&l440gx_map); 82 simple_map_init(&l440gx_map);
83 printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt); 83 printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt);
84 84
85 /* Setup the pm iobase resource 85 /* Setup the pm iobase resource
86 * This code should move into some kind of generic bridge 86 * This code should move into some kind of generic bridge
87 * driver but for the moment I'm content with getting the 87 * driver but for the moment I'm content with getting the
88 * allocation correct. 88 * allocation correct.
89 */ 89 */
90 pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE]; 90 pm_iobase = &pm_dev->resource[PIIXE_IOBASE_RESOURCE];
91 if (!(pm_iobase->flags & IORESOURCE_IO)) { 91 if (!(pm_iobase->flags & IORESOURCE_IO)) {
@@ -110,7 +110,7 @@ static int __init init_l440gx(void)
110 /* Set the iobase */ 110 /* Set the iobase */
111 iobase = pm_iobase->start; 111 iobase = pm_iobase->start;
112 pci_write_config_dword(pm_dev, 0x40, iobase | 1); 112 pci_write_config_dword(pm_dev, 0x40, iobase | 1);
113 113
114 114
115 /* Set XBCS# */ 115 /* Set XBCS# */
116 pci_read_config_word(dev, 0x4e, &word); 116 pci_read_config_word(dev, 0x4e, &word);
@@ -122,7 +122,7 @@ static int __init init_l440gx(void)
122 122
123 /* Enable the gate on the WE line */ 123 /* Enable the gate on the WE line */
124 outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT); 124 outb(inb(TRIBUF_PORT) & ~1, TRIBUF_PORT);
125 125
126 printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n"); 126 printk(KERN_NOTICE "Enabled WE line to L440GX BIOS flash chip.\n");
127 127
128 mymtd = do_map_probe("jedec_probe", &l440gx_map); 128 mymtd = do_map_probe("jedec_probe", &l440gx_map);
@@ -145,7 +145,7 @@ static void __exit cleanup_l440gx(void)
145{ 145{
146 del_mtd_device(mymtd); 146 del_mtd_device(mymtd);
147 map_destroy(mymtd); 147 map_destroy(mymtd);
148 148
149 iounmap(l440gx_map.virt); 149 iounmap(l440gx_map.virt);
150} 150}
151 151
diff --git a/drivers/mtd/maps/lubbock-flash.c b/drivers/mtd/maps/lubbock-flash.c
index 2337e0c46750..1aa0447c5e66 100644
--- a/drivers/mtd/maps/lubbock-flash.c
+++ b/drivers/mtd/maps/lubbock-flash.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * $Id: lubbock-flash.c,v 1.19 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: lubbock-flash.c,v 1.21 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Map driver for the Lubbock developer platform. 4 * Map driver for the Lubbock developer platform.
5 * 5 *
6 * Author: Nicolas Pitre 6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc. 7 * Copyright: (C) 2001 MontaVista Software Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -76,7 +76,7 @@ static int __init init_lubbock(void)
76 int flashboot = (LUB_CONF_SWITCHES & 1); 76 int flashboot = (LUB_CONF_SWITCHES & 1);
77 int ret = 0, i; 77 int ret = 0, i;
78 78
79 lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth = 79 lubbock_maps[0].bankwidth = lubbock_maps[1].bankwidth =
80 (BOOT_DEF & 1) ? 2 : 4; 80 (BOOT_DEF & 1) ? 2 : 4;
81 81
82 /* Compensate for the nROMBT switch which swaps the flash banks */ 82 /* Compensate for the nROMBT switch which swaps the flash banks */
@@ -100,11 +100,11 @@ static int __init init_lubbock(void)
100 simple_map_init(&lubbock_maps[i]); 100 simple_map_init(&lubbock_maps[i]);
101 101
102 printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n", 102 printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit bankwidth)\n",
103 lubbock_maps[i].name, lubbock_maps[i].phys, 103 lubbock_maps[i].name, lubbock_maps[i].phys,
104 lubbock_maps[i].bankwidth * 8); 104 lubbock_maps[i].bankwidth * 8);
105 105
106 mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]); 106 mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]);
107 107
108 if (!mymtds[i]) { 108 if (!mymtds[i]) {
109 iounmap((void *)lubbock_maps[i].virt); 109 iounmap((void *)lubbock_maps[i].virt);
110 if (lubbock_maps[i].cached) 110 if (lubbock_maps[i].cached)
@@ -124,7 +124,7 @@ static int __init init_lubbock(void)
124 124
125 if (!mymtds[0] && !mymtds[1]) 125 if (!mymtds[0] && !mymtds[1])
126 return ret; 126 return ret;
127 127
128 for (i = 0; i < 2; i++) { 128 for (i = 0; i < 2; i++) {
129 if (!mymtds[i]) { 129 if (!mymtds[i]) {
130 printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name); 130 printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name);
@@ -151,15 +151,14 @@ static void __exit cleanup_lubbock(void)
151 if (nr_parsed_parts[i] || !i) 151 if (nr_parsed_parts[i] || !i)
152 del_mtd_partitions(mymtds[i]); 152 del_mtd_partitions(mymtds[i]);
153 else 153 else
154 del_mtd_device(mymtds[i]); 154 del_mtd_device(mymtds[i]);
155 155
156 map_destroy(mymtds[i]); 156 map_destroy(mymtds[i]);
157 iounmap((void *)lubbock_maps[i].virt); 157 iounmap((void *)lubbock_maps[i].virt);
158 if (lubbock_maps[i].cached) 158 if (lubbock_maps[i].cached)
159 iounmap(lubbock_maps[i].cached); 159 iounmap(lubbock_maps[i].cached);
160 160
161 if (parsed_parts[i]) 161 kfree(parsed_parts[i]);
162 kfree(parsed_parts[i]);
163 } 162 }
164} 163}
165 164
diff --git a/drivers/mtd/maps/mainstone-flash.c b/drivers/mtd/maps/mainstone-flash.c
index da0f8a692628..eaa4bbb868a3 100644
--- a/drivers/mtd/maps/mainstone-flash.c
+++ b/drivers/mtd/maps/mainstone-flash.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * Author: Nicolas Pitre 6 * Author: Nicolas Pitre
7 * Copyright: (C) 2001 MontaVista Software Inc. 7 * Copyright: (C) 2001 MontaVista Software Inc.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -91,27 +91,27 @@ static int __init init_mainstone(void)
91 mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys, 91 mainstone_maps[i].virt = ioremap(mainstone_maps[i].phys,
92 WINDOW_SIZE); 92 WINDOW_SIZE);
93 if (!mainstone_maps[i].virt) { 93 if (!mainstone_maps[i].virt) {
94 printk(KERN_WARNING "Failed to ioremap %s\n", 94 printk(KERN_WARNING "Failed to ioremap %s\n",
95 mainstone_maps[i].name); 95 mainstone_maps[i].name);
96 if (!ret) 96 if (!ret)
97 ret = -ENOMEM; 97 ret = -ENOMEM;
98 continue; 98 continue;
99 } 99 }
100 mainstone_maps[i].cached = 100 mainstone_maps[i].cached =
101 ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE); 101 ioremap_cached(mainstone_maps[i].phys, WINDOW_SIZE);
102 if (!mainstone_maps[i].cached) 102 if (!mainstone_maps[i].cached)
103 printk(KERN_WARNING "Failed to ioremap cached %s\n", 103 printk(KERN_WARNING "Failed to ioremap cached %s\n",
104 mainstone_maps[i].name); 104 mainstone_maps[i].name);
105 simple_map_init(&mainstone_maps[i]); 105 simple_map_init(&mainstone_maps[i]);
106 106
107 printk(KERN_NOTICE 107 printk(KERN_NOTICE
108 "Probing %s at physical address 0x%08lx" 108 "Probing %s at physical address 0x%08lx"
109 " (%d-bit bankwidth)\n", 109 " (%d-bit bankwidth)\n",
110 mainstone_maps[i].name, mainstone_maps[i].phys, 110 mainstone_maps[i].name, mainstone_maps[i].phys,
111 mainstone_maps[i].bankwidth * 8); 111 mainstone_maps[i].bankwidth * 8);
112 112
113 mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]); 113 mymtds[i] = do_map_probe("cfi_probe", &mainstone_maps[i]);
114 114
115 if (!mymtds[i]) { 115 if (!mymtds[i]) {
116 iounmap((void *)mainstone_maps[i].virt); 116 iounmap((void *)mainstone_maps[i].virt);
117 if (mainstone_maps[i].cached) 117 if (mainstone_maps[i].cached)
@@ -131,21 +131,21 @@ static int __init init_mainstone(void)
131 131
132 if (!mymtds[0] && !mymtds[1]) 132 if (!mymtds[0] && !mymtds[1])
133 return ret; 133 return ret;
134 134
135 for (i = 0; i < 2; i++) { 135 for (i = 0; i < 2; i++) {
136 if (!mymtds[i]) { 136 if (!mymtds[i]) {
137 printk(KERN_WARNING "%s is absent. Skipping\n", 137 printk(KERN_WARNING "%s is absent. Skipping\n",
138 mainstone_maps[i].name); 138 mainstone_maps[i].name);
139 } else if (nr_parsed_parts[i]) { 139 } else if (nr_parsed_parts[i]) {
140 add_mtd_partitions(mymtds[i], parsed_parts[i], 140 add_mtd_partitions(mymtds[i], parsed_parts[i],
141 nr_parsed_parts[i]); 141 nr_parsed_parts[i]);
142 } else if (!i) { 142 } else if (!i) {
143 printk("Using static partitions on %s\n", 143 printk("Using static partitions on %s\n",
144 mainstone_maps[i].name); 144 mainstone_maps[i].name);
145 add_mtd_partitions(mymtds[i], mainstone_partitions, 145 add_mtd_partitions(mymtds[i], mainstone_partitions,
146 ARRAY_SIZE(mainstone_partitions)); 146 ARRAY_SIZE(mainstone_partitions));
147 } else { 147 } else {
148 printk("Registering %s as whole device\n", 148 printk("Registering %s as whole device\n",
149 mainstone_maps[i].name); 149 mainstone_maps[i].name);
150 add_mtd_device(mymtds[i]); 150 add_mtd_device(mymtds[i]);
151 } 151 }
diff --git a/drivers/mtd/maps/mbx860.c b/drivers/mtd/maps/mbx860.c
index c5c6901a4763..06b118727846 100644
--- a/drivers/mtd/maps/mbx860.c
+++ b/drivers/mtd/maps/mbx860.c
@@ -1,11 +1,11 @@
1/* 1/*
2 * $Id: mbx860.c,v 1.8 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: mbx860.c,v 1.9 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Handle mapping of the flash on MBX860 boards 4 * Handle mapping of the flash on MBX860 boards
5 * 5 *
6 * Author: Anton Todorov 6 * Author: Anton Todorov
7 * Copyright: (C) 2001 Emness Technology 7 * Copyright: (C) 2001 Emness Technology
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
@@ -46,7 +46,7 @@ static struct mtd_partition partition_info[]={
46 { .name = "MBX flash APPLICATION partition", 46 { .name = "MBX flash APPLICATION partition",
47 .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 } 47 .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
48}; 48};
49 49
50 50
51static struct mtd_info *mymtd; 51static struct mtd_info *mymtd;
52 52
diff --git a/drivers/mtd/maps/mtx-1_flash.c b/drivers/mtd/maps/mtx-1_flash.c
new file mode 100644
index 000000000000..d1e66e186746
--- /dev/null
+++ b/drivers/mtd/maps/mtx-1_flash.c
@@ -0,0 +1,96 @@
1/*
2 * Flash memory access on 4G Systems MTX-1 boards
3 *
4 * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $
5 *
6 * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz>
7 * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de>
8 *
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/types.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16
17#include <linux/mtd/mtd.h>
18#include <linux/mtd/map.h>
19#include <linux/mtd/partitions.h>
20
21#include <asm/io.h>
22
23static struct map_info mtx1_map = {
24 .name = "MTX-1 flash",
25 .bankwidth = 4,
26 .size = 0x2000000,
27 .phys = 0x1E000000,
28};
29
30static struct mtd_partition mtx1_partitions[] = {
31 {
32 .name = "filesystem",
33 .size = 0x01C00000,
34 .offset = 0,
35 },{
36 .name = "yamon",
37 .size = 0x00100000,
38 .offset = MTDPART_OFS_APPEND,
39 .mask_flags = MTD_WRITEABLE,
40 },{
41 .name = "kernel",
42 .size = 0x002c0000,
43 .offset = MTDPART_OFS_APPEND,
44 },{
45 .name = "yamon env",
46 .size = 0x00040000,
47 .offset = MTDPART_OFS_APPEND,
48 }
49};
50
51static struct mtd_info *mtx1_mtd;
52
53int __init mtx1_mtd_init(void)
54{
55 int ret = -ENXIO;
56
57 simple_map_init(&mtx1_map);
58
59 mtx1_map.virt = ioremap(mtx1_map.phys, mtx1_map.size);
60 if (!mtx1_map.virt)
61 return -EIO;
62
63 mtx1_mtd = do_map_probe("cfi_probe", &mtx1_map);
64 if (!mtx1_mtd)
65 goto err;
66
67 mtx1_mtd->owner = THIS_MODULE;
68
69 ret = add_mtd_partitions(mtx1_mtd, mtx1_partitions,
70 ARRAY_SIZE(mtx1_partitions));
71 if (ret)
72 goto err;
73
74 return 0;
75
76err:
77 iounmap(mtx1_map.virt);
78 return ret;
79}
80
81static void __exit mtx1_mtd_cleanup(void)
82{
83 if (mtx1_mtd) {
84 del_mtd_partitions(mtx1_mtd);
85 map_destroy(mtx1_mtd);
86 }
87 if (mtx1_map.virt)
88 iounmap(mtx1_map.virt);
89}
90
91module_init(mtx1_mtd_init);
92module_exit(mtx1_mtd_cleanup);
93
94MODULE_AUTHOR("Bruno Randolf <bruno.randolf@4g-systems.biz>");
95MODULE_DESCRIPTION("MTX-1 flash map");
96MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/netsc520.c b/drivers/mtd/maps/netsc520.c
index ab7e6358d281..33060a315722 100644
--- a/drivers/mtd/maps/netsc520.c
+++ b/drivers/mtd/maps/netsc520.c
@@ -3,7 +3,7 @@
3 * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com) 3 * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
4 * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH 4 * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
5 * 5 *
6 * $Id: netsc520.c,v 1.13 2004/11/28 09:40:40 dwmw2 Exp $ 6 * $Id: netsc520.c,v 1.14 2005/11/07 11:14:27 gleixner Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -38,7 +38,7 @@
38** The single, 16 megabyte flash bank is divided into four virtual 38** The single, 16 megabyte flash bank is divided into four virtual
39** partitions. The first partition is 768 KiB and is intended to 39** partitions. The first partition is 768 KiB and is intended to
40** store the kernel image loaded by the bootstrap loader. The second 40** store the kernel image loaded by the bootstrap loader. The second
41** partition is 256 KiB and holds the BIOS image. The third 41** partition is 256 KiB and holds the BIOS image. The third
42** partition is 14.5 MiB and is intended for the flash file system 42** partition is 14.5 MiB and is intended for the flash file system
43** image. The last partition is 512 KiB and contains another copy 43** image. The last partition is 512 KiB and contains another copy
44** of the BIOS image and the reset vector. 44** of the BIOS image and the reset vector.
@@ -51,28 +51,28 @@
51** recoverable afterwards. 51** recoverable afterwards.
52*/ 52*/
53 53
54/* partition_info gives details on the logical partitions that the split the 54/* partition_info gives details on the logical partitions that the split the
55 * single flash device into. If the size if zero we use up to the end of the 55 * single flash device into. If the size if zero we use up to the end of the
56 * device. */ 56 * device. */
57static struct mtd_partition partition_info[]={ 57static struct mtd_partition partition_info[]={
58 { 58 {
59 .name = "NetSc520 boot kernel", 59 .name = "NetSc520 boot kernel",
60 .offset = 0, 60 .offset = 0,
61 .size = 0xc0000 61 .size = 0xc0000
62 }, 62 },
63 { 63 {
64 .name = "NetSc520 Low BIOS", 64 .name = "NetSc520 Low BIOS",
65 .offset = 0xc0000, 65 .offset = 0xc0000,
66 .size = 0x40000 66 .size = 0x40000
67 }, 67 },
68 { 68 {
69 .name = "NetSc520 file system", 69 .name = "NetSc520 file system",
70 .offset = 0x100000, 70 .offset = 0x100000,
71 .size = 0xe80000 71 .size = 0xe80000
72 }, 72 },
73 { 73 {
74 .name = "NetSc520 High BIOS", 74 .name = "NetSc520 High BIOS",
75 .offset = 0xf80000, 75 .offset = 0xf80000,
76 .size = 0x80000 76 .size = 0x80000
77 }, 77 },
78}; 78};
@@ -114,7 +114,7 @@ static int __init init_netsc520(void)
114 iounmap(netsc520_map.virt); 114 iounmap(netsc520_map.virt);
115 return -ENXIO; 115 return -ENXIO;
116 } 116 }
117 117
118 mymtd->owner = THIS_MODULE; 118 mymtd->owner = THIS_MODULE;
119 add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS ); 119 add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS );
120 return 0; 120 return 0;
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index 61be5a4148c9..f00ee7e54dba 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -6,7 +6,7 @@
6 * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) 6 * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
7 * (C) Copyright 2001-2002, SnapGear (www.snapgear.com) 7 * (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
8 * 8 *
9 * $Id: nettel.c,v 1.10 2005/01/05 17:11:29 dwmw2 Exp $ 9 * $Id: nettel.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
10 */ 10 */
11 11
12/****************************************************************************/ 12/****************************************************************************/
@@ -143,7 +143,7 @@ static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val,
143{ 143{
144 struct cfi_private *cfi = nettel_intel_map.fldrv_priv; 144 struct cfi_private *cfi = nettel_intel_map.fldrv_priv;
145 unsigned long b; 145 unsigned long b;
146 146
147 /* Make sure all FLASH chips are put back into read mode */ 147 /* Make sure all FLASH chips are put back into read mode */
148 for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) { 148 for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {
149 cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi, 149 cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,
@@ -199,7 +199,7 @@ int nettel_eraseconfig(void)
199 199
200 schedule(); /* Wait for erase to finish. */ 200 schedule(); /* Wait for erase to finish. */
201 remove_wait_queue(&wait_q, &wait); 201 remove_wait_queue(&wait_q, &wait);
202 202
203 put_mtd_device(mtd); 203 put_mtd_device(mtd);
204 } 204 }
205 205
@@ -430,7 +430,7 @@ int __init nettel_init(void)
430 nettel_intel_partitions[1].size = (intel0size + intel1size) - 430 nettel_intel_partitions[1].size = (intel0size + intel1size) -
431 (1024*1024 + intel_mtd->erasesize); 431 (1024*1024 + intel_mtd->erasesize);
432 nettel_intel_partitions[3].size = intel0size + intel1size; 432 nettel_intel_partitions[3].size = intel0size + intel1size;
433 nettel_intel_partitions[4].offset = 433 nettel_intel_partitions[4].offset =
434 (intel0size + intel1size) - intel_mtd->erasesize; 434 (intel0size + intel1size) - intel_mtd->erasesize;
435 nettel_intel_partitions[4].size = intel_mtd->erasesize; 435 nettel_intel_partitions[4].size = intel_mtd->erasesize;
436 nettel_intel_partitions[5].offset = 436 nettel_intel_partitions[5].offset =
diff --git a/drivers/mtd/maps/ocelot.c b/drivers/mtd/maps/ocelot.c
index 82c3070678c5..6977963d7897 100644
--- a/drivers/mtd/maps/ocelot.c
+++ b/drivers/mtd/maps/ocelot.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: ocelot.c,v 1.16 2005/01/05 18:05:13 dwmw2 Exp $ 2 * $Id: ocelot.c,v 1.17 2005/11/07 11:14:27 gleixner Exp $
3 * 3 *
4 * Flash on Momenco Ocelot 4 * Flash on Momenco Ocelot
5 */ 5 */
@@ -31,7 +31,7 @@ static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t
31 struct map_info *map = mtd->priv; 31 struct map_info *map = mtd->priv;
32 size_t done = 0; 32 size_t done = 0;
33 33
34 /* If we use memcpy, it does word-wide writes. Even though we told the 34 /* If we use memcpy, it does word-wide writes. Even though we told the
35 GT64120A that it's an 8-bit wide region, word-wide writes don't work. 35 GT64120A that it's an 8-bit wide region, word-wide writes don't work.
36 We end up just writing the first byte of the four to all four bytes. 36 We end up just writing the first byte of the four to all four bytes.
37 So we have this loop instead */ 37 So we have this loop instead */
@@ -68,7 +68,7 @@ static int __init init_ocelot_maps(void)
68 int nr_parts; 68 int nr_parts;
69 unsigned char brd_status; 69 unsigned char brd_status;
70 70
71 printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n", 71 printk(KERN_INFO "Momenco Ocelot MTD mappings: Flash 0x%x at 0x%x, NVRAM 0x%x at 0x%x\n",
72 FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR); 72 FLASH_WINDOW_SIZE, FLASH_WINDOW_ADDR, NVRAM_WINDOW_SIZE, NVRAM_WINDOW_ADDR);
73 73
74 /* First check whether the flash jumper is present */ 74 /* First check whether the flash jumper is present */
@@ -138,8 +138,8 @@ static int __init init_ocelot_maps(void)
138 add_mtd_device(flash_mtd); 138 add_mtd_device(flash_mtd);
139 139
140 return 0; 140 return 0;
141 141
142 fail3: 142 fail3:
143 iounmap((void *)ocelot_flash_map.virt); 143 iounmap((void *)ocelot_flash_map.virt);
144 if (ocelot_flash_map.cached) 144 if (ocelot_flash_map.cached)
145 iounmap((void *)ocelot_flash_map.cached); 145 iounmap((void *)ocelot_flash_map.cached);
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
index 6e559bc14636..c223514ca2eb 100644
--- a/drivers/mtd/maps/ocotea.c
+++ b/drivers/mtd/maps/ocotea.c
@@ -19,7 +19,6 @@
19#include <linux/mtd/map.h> 19#include <linux/mtd/map.h>
20#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
21#include <linux/config.h> 21#include <linux/config.h>
22#include <linux/version.h>
23#include <asm/io.h> 22#include <asm/io.h>
24#include <asm/ibm44x.h> 23#include <asm/ibm44x.h>
25#include <platforms/4xx/ocotea.h> 24#include <platforms/4xx/ocotea.h>
diff --git a/drivers/mtd/maps/octagon-5066.c b/drivers/mtd/maps/octagon-5066.c
index e5ff83de420e..a6642db3d325 100644
--- a/drivers/mtd/maps/octagon-5066.c
+++ b/drivers/mtd/maps/octagon-5066.c
@@ -1,12 +1,12 @@
1// $Id: octagon-5066.c,v 1.26 2004/07/12 22:38:29 dwmw2 Exp $ 1// $Id: octagon-5066.c,v 1.28 2005/11/07 11:14:27 gleixner Exp $
2/* ###################################################################### 2/* ######################################################################
3 3
4 Octagon 5066 MTD Driver. 4 Octagon 5066 MTD Driver.
5 5
6 The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It 6 The Octagon 5066 is a SBC based on AMD's 586-WB running at 133 MHZ. It
7 comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that 7 comes with a builtin AMD 29F016 flash chip and a socketed EEPROM that
8 is replacable by flash. Both units are mapped through a multiplexer 8 is replacable by flash. Both units are mapped through a multiplexer
9 into a 32k memory window at 0xe8000. The control register for the 9 into a 32k memory window at 0xe8000. The control register for the
10 multiplexing unit is located at IO 0x208 with a bit map of 10 multiplexing unit is located at IO 0x208 with a bit map of
11 0-5 Page Selection in 32k increments 11 0-5 Page Selection in 32k increments
12 6-7 Device selection: 12 6-7 Device selection:
@@ -14,14 +14,14 @@
14 01 SSD 0 (Socket) 14 01 SSD 0 (Socket)
15 10 SSD 1 (Flash chip) 15 10 SSD 1 (Flash chip)
16 11 undefined 16 11 undefined
17 17
18 On each SSD, the first 128k is reserved for use by the bios 18 On each SSD, the first 128k is reserved for use by the bios
19 (actually it IS the bios..) This only matters if you are booting off the 19 (actually it IS the bios..) This only matters if you are booting off the
20 flash, you must not put a file system starting there. 20 flash, you must not put a file system starting there.
21 21
22 The driver tries to do a detection algorithm to guess what sort of devices 22 The driver tries to do a detection algorithm to guess what sort of devices
23 are plugged into the sockets. 23 are plugged into the sockets.
24 24
25 ##################################################################### */ 25 ##################################################################### */
26 26
27#include <linux/module.h> 27#include <linux/module.h>
@@ -56,7 +56,7 @@ static void __oct5066_page(struct map_info *map, __u8 byte)
56static inline void oct5066_page(struct map_info *map, unsigned long ofs) 56static inline void oct5066_page(struct map_info *map, unsigned long ofs)
57{ 57{
58 __u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT); 58 __u8 byte = map->map_priv_1 | (ofs >> WINDOW_SHIFT);
59 59
60 if (page_n_dev != byte) 60 if (page_n_dev != byte)
61 __oct5066_page(map, byte); 61 __oct5066_page(map, byte);
62} 62}
@@ -78,7 +78,7 @@ static void oct5066_copy_from(struct map_info *map, void *to, unsigned long from
78 unsigned long thislen = len; 78 unsigned long thislen = len;
79 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK))) 79 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
80 thislen = WINDOW_LENGTH-(from & WINDOW_MASK); 80 thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
81 81
82 spin_lock(&oct5066_spin); 82 spin_lock(&oct5066_spin);
83 oct5066_page(map, from); 83 oct5066_page(map, from);
84 memcpy_fromio(to, iomapadr + from, thislen); 84 memcpy_fromio(to, iomapadr + from, thislen);
@@ -103,7 +103,7 @@ static void oct5066_copy_to(struct map_info *map, unsigned long to, const void *
103 unsigned long thislen = len; 103 unsigned long thislen = len;
104 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK))) 104 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
105 thislen = WINDOW_LENGTH-(to & WINDOW_MASK); 105 thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
106 106
107 spin_lock(&oct5066_spin); 107 spin_lock(&oct5066_spin);
108 oct5066_page(map, to); 108 oct5066_page(map, to);
109 memcpy_toio(iomapadr + to, from, thislen); 109 memcpy_toio(iomapadr + to, from, thislen);
@@ -144,7 +144,7 @@ static struct mtd_info *oct5066_mtd[2] = {NULL, NULL};
144// OctProbe - Sense if this is an octagon card 144// OctProbe - Sense if this is an octagon card
145// --------------------------------------------------------------------- 145// ---------------------------------------------------------------------
146/* Perform a simple validity test, we map the window select SSD0 and 146/* Perform a simple validity test, we map the window select SSD0 and
147 change pages while monitoring the window. A change in the window, 147 change pages while monitoring the window. A change in the window,
148 controlled by the PAGE_IO port is a functioning 5066 board. This will 148 controlled by the PAGE_IO port is a functioning 5066 board. This will
149 fail if the thing in the socket is set to a uniform value. */ 149 fail if the thing in the socket is set to a uniform value. */
150static int __init OctProbe(void) 150static int __init OctProbe(void)
@@ -161,13 +161,13 @@ static int __init OctProbe(void)
161 Values[I%10] = readl(iomapadr); 161 Values[I%10] = readl(iomapadr);
162 if (I > 0 && Values[I%10] == Values[0]) 162 if (I > 0 && Values[I%10] == Values[0])
163 return -EAGAIN; 163 return -EAGAIN;
164 } 164 }
165 else 165 else
166 { 166 {
167 // Make sure we get the same values on the second pass 167 // Make sure we get the same values on the second pass
168 if (Values[I%10] != readl(iomapadr)) 168 if (Values[I%10] != readl(iomapadr))
169 return -EAGAIN; 169 return -EAGAIN;
170 } 170 }
171 } 171 }
172 return 0; 172 return 0;
173} 173}
@@ -207,11 +207,11 @@ int __init init_oct5066(void)
207 ret = -EAGAIN; 207 ret = -EAGAIN;
208 goto out_unmap; 208 goto out_unmap;
209 } 209 }
210 210
211 // Print out our little header.. 211 // Print out our little header..
212 printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START, 212 printk("Octagon 5066 SSD IO:0x%x MEM:0x%x-0x%x\n",PAGE_IO,WINDOW_START,
213 WINDOW_START+WINDOW_LENGTH); 213 WINDOW_START+WINDOW_LENGTH);
214 214
215 for (i=0; i<2; i++) { 215 for (i=0; i<2; i++) {
216 oct5066_mtd[i] = do_map_probe("cfi_probe", &oct5066_map[i]); 216 oct5066_mtd[i] = do_map_probe("cfi_probe", &oct5066_map[i]);
217 if (!oct5066_mtd[i]) 217 if (!oct5066_mtd[i])
@@ -225,11 +225,11 @@ int __init init_oct5066(void)
225 add_mtd_device(oct5066_mtd[i]); 225 add_mtd_device(oct5066_mtd[i]);
226 } 226 }
227 } 227 }
228 228
229 if (!oct5066_mtd[0] && !oct5066_mtd[1]) { 229 if (!oct5066_mtd[0] && !oct5066_mtd[1]) {
230 cleanup_oct5066(); 230 cleanup_oct5066();
231 return -ENXIO; 231 return -ENXIO;
232 } 232 }
233 233
234 return 0; 234 return 0;
235 235
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c
index da36e8dddd17..dc3765270057 100644
--- a/drivers/mtd/maps/omap-toto-flash.c
+++ b/drivers/mtd/maps/omap-toto-flash.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * (C) 2002 MontVista Software, Inc. 6 * (C) 2002 MontVista Software, Inc.
7 * 7 *
8 * $Id: omap-toto-flash.c,v 1.3 2004/09/16 23:27:13 gleixner Exp $ 8 * $Id: omap-toto-flash.c,v 1.5 2005/11/07 11:14:27 gleixner Exp $
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
@@ -38,7 +38,7 @@ static struct map_info omap_toto_map_flash = {
38 .virt = (void __iomem *)OMAP_TOTO_FLASH_BASE, 38 .virt = (void __iomem *)OMAP_TOTO_FLASH_BASE,
39}; 39};
40 40
41 41
42static struct mtd_partition toto_flash_partitions[] = { 42static struct mtd_partition toto_flash_partitions[] = {
43 { 43 {
44 .name = "BootLoader", 44 .name = "BootLoader",
@@ -54,21 +54,21 @@ static struct mtd_partition toto_flash_partitions[] = {
54 .name = "EnvArea", /* bottom 64KiB for env vars */ 54 .name = "EnvArea", /* bottom 64KiB for env vars */
55 .size = MTDPART_SIZ_FULL, 55 .size = MTDPART_SIZ_FULL,
56 .offset = MTDPART_OFS_APPEND, 56 .offset = MTDPART_OFS_APPEND,
57 } 57 }
58}; 58};
59 59
60static struct mtd_partition *parsed_parts; 60static struct mtd_partition *parsed_parts;
61 61
62static struct mtd_info *flash_mtd; 62static struct mtd_info *flash_mtd;
63 63
64static int __init init_flash (void) 64static int __init init_flash (void)
65{ 65{
66 66
67 struct mtd_partition *parts; 67 struct mtd_partition *parts;
68 int nb_parts = 0; 68 int nb_parts = 0;
69 int parsed_nr_parts = 0; 69 int parsed_nr_parts = 0;
70 const char *part_type; 70 const char *part_type;
71 71
72 /* 72 /*
73 * Static partition definition selection 73 * Static partition definition selection
74 */ 74 */
@@ -89,7 +89,7 @@ static int __init init_flash (void)
89 flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash); 89 flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash);
90 if (!flash_mtd) 90 if (!flash_mtd)
91 return -ENXIO; 91 return -ENXIO;
92 92
93 if (parsed_nr_parts > 0) { 93 if (parsed_nr_parts > 0) {
94 parts = parsed_parts; 94 parts = parsed_parts;
95 nb_parts = parsed_nr_parts; 95 nb_parts = parsed_nr_parts;
@@ -108,8 +108,8 @@ static int __init init_flash (void)
108 } 108 }
109 return 0; 109 return 0;
110} 110}
111 111
112int __init omap_toto_mtd_init(void) 112int __init omap_toto_mtd_init(void)
113{ 113{
114 int status; 114 int status;
115 115
@@ -119,13 +119,12 @@ int __init omap_toto_mtd_init(void)
119 return status; 119 return status;
120} 120}
121 121
122static void __exit omap_toto_mtd_cleanup(void) 122static void __exit omap_toto_mtd_cleanup(void)
123{ 123{
124 if (flash_mtd) { 124 if (flash_mtd) {
125 del_mtd_partitions(flash_mtd); 125 del_mtd_partitions(flash_mtd);
126 map_destroy(flash_mtd); 126 map_destroy(flash_mtd);
127 if (parsed_parts) 127 kfree(parsed_parts);
128 kfree(parsed_parts);
129 } 128 }
130} 129}
131 130
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 7f370bb794fe..fd3b4a5fc207 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2001-2002 MontaVista Software Inc. 4 * Copyright (C) 2001-2002 MontaVista Software Inc.
5 * Copyright (C) 2003-2004 Texas Instruments 5 * Copyright (C) 2003-2004 Texas Instruments
6 * Copyright (C) 2004 Nokia Corporation 6 * Copyright (C) 2004 Nokia Corporation
7 * 7 *
8 * Assembled using driver code copyright the companies above 8 * Assembled using driver code copyright the companies above
9 * and written by David Brownell, Jian Zhang <jzhang@ti.com>, 9 * and written by David Brownell, Jian Zhang <jzhang@ti.com>,
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index d9c64e99ee32..8b3570b09095 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -7,8 +7,8 @@
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 * $Id: pci.c,v 1.10 2005/03/18 14:04:35 gleixner Exp $ 10 * $Id: pci.c,v 1.13 2005/11/07 11:14:27 gleixner Exp $
11 * 11 *
12 * Generic PCI memory map driver. We support the following boards: 12 * Generic PCI memory map driver. We support the following boards:
13 * - Intel IQ80310 ATU. 13 * - Intel IQ80310 ATU.
14 * - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001 14 * - Intel EBSA285 (blank rom programming mode). Tested working 27/09/2001
@@ -38,7 +38,7 @@ struct map_pci_info {
38 void (*exit)(struct pci_dev *dev, struct map_pci_info *map); 38 void (*exit)(struct pci_dev *dev, struct map_pci_info *map);
39 unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs); 39 unsigned long (*translate)(struct map_pci_info *map, unsigned long ofs);
40 struct pci_dev *dev; 40 struct pci_dev *dev;
41}; 41};
42 42
43static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs) 43static map_word mtd_pci_read8(struct map_info *_map, unsigned long ofs)
44{ 44{
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index ff7c50d10180..af24216a0626 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: pcmciamtd.c,v 1.51 2004/07/12 22:38:29 dwmw2 Exp $ 2 * $Id: pcmciamtd.c,v 1.55 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * pcmciamtd.c - MTD driver for PCMCIA flash memory cards 4 * pcmciamtd.c - MTD driver for PCMCIA flash memory cards
5 * 5 *
@@ -48,7 +48,7 @@ static const int debug = 0;
48 48
49 49
50#define DRIVER_DESC "PCMCIA Flash memory card driver" 50#define DRIVER_DESC "PCMCIA Flash memory card driver"
51#define DRIVER_VERSION "$Revision: 1.51 $" 51#define DRIVER_VERSION "$Revision: 1.55 $"
52 52
53/* Size of the PCMCIA address space: 26 bits = 64 MB */ 53/* Size of the PCMCIA address space: 26 bits = 64 MB */
54#define MAX_PCMCIA_ADDR 0x4000000 54#define MAX_PCMCIA_ADDR 0x4000000
@@ -176,7 +176,7 @@ static void pcmcia_copy_from_remap(struct map_info *map, void *to, unsigned long
176 176
177 if(toread > len) 177 if(toread > len)
178 toread = len; 178 toread = len;
179 179
180 addr = remap_window(map, from); 180 addr = remap_window(map, from);
181 if(!addr) 181 if(!addr)
182 return; 182 return;
@@ -386,7 +386,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
386 cs_error(link->handle, ParseTuple, rc); 386 cs_error(link->handle, ParseTuple, rc);
387 break; 387 break;
388 } 388 }
389 389
390 switch(tuple.TupleCode) { 390 switch(tuple.TupleCode) {
391 case CISTPL_FORMAT: { 391 case CISTPL_FORMAT: {
392 cistpl_format_t *t = &parse.format; 392 cistpl_format_t *t = &parse.format;
@@ -394,9 +394,9 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
394 DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u", 394 DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
395 t->type, t->edc, t->offset, t->length); 395 t->type, t->edc, t->offset, t->length);
396 break; 396 break;
397 397
398 } 398 }
399 399
400 case CISTPL_DEVICE: { 400 case CISTPL_DEVICE: {
401 cistpl_device_t *t = &parse.device; 401 cistpl_device_t *t = &parse.device;
402 int i; 402 int i;
@@ -410,7 +410,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
410 } 410 }
411 break; 411 break;
412 } 412 }
413 413
414 case CISTPL_VERS_1: { 414 case CISTPL_VERS_1: {
415 cistpl_vers_1_t *t = &parse.version_1; 415 cistpl_vers_1_t *t = &parse.version_1;
416 int i; 416 int i;
@@ -425,7 +425,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
425 DEBUG(2, "Found name: %s", dev->mtd_name); 425 DEBUG(2, "Found name: %s", dev->mtd_name);
426 break; 426 break;
427 } 427 }
428 428
429 case CISTPL_JEDEC_C: { 429 case CISTPL_JEDEC_C: {
430 cistpl_jedec_t *t = &parse.jedec; 430 cistpl_jedec_t *t = &parse.jedec;
431 int i; 431 int i;
@@ -434,7 +434,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
434 } 434 }
435 break; 435 break;
436 } 436 }
437 437
438 case CISTPL_DEVICE_GEO: { 438 case CISTPL_DEVICE_GEO: {
439 cistpl_device_geo_t *t = &parse.device_geo; 439 cistpl_device_geo_t *t = &parse.device_geo;
440 int i; 440 int i;
@@ -449,11 +449,11 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
449 } 449 }
450 break; 450 break;
451 } 451 }
452 452
453 default: 453 default:
454 DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); 454 DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
455 } 455 }
456 456
457 rc = pcmcia_get_next_tuple(link->handle, &tuple); 457 rc = pcmcia_get_next_tuple(link->handle, &tuple);
458 } 458 }
459 if(!dev->pcmcia_map.size) 459 if(!dev->pcmcia_map.size)
@@ -470,7 +470,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
470 if(bankwidth) { 470 if(bankwidth) {
471 dev->pcmcia_map.bankwidth = bankwidth; 471 dev->pcmcia_map.bankwidth = bankwidth;
472 DEBUG(2, "bankwidth forced to %d", bankwidth); 472 DEBUG(2, "bankwidth forced to %d", bankwidth);
473 } 473 }
474 474
475 dev->pcmcia_map.name = dev->mtd_name; 475 dev->pcmcia_map.name = dev->mtd_name;
476 if(!dev->mtd_name[0]) { 476 if(!dev->mtd_name[0]) {
@@ -568,7 +568,7 @@ static void pcmciamtd_config(dev_link_t *link)
568 return; 568 return;
569 } 569 }
570 DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); 570 DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
571 571
572 /* Get write protect status */ 572 /* Get write protect status */
573 CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status)); 573 CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status));
574 DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", 574 DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
@@ -624,11 +624,11 @@ static void pcmciamtd_config(dev_link_t *link)
624 mtd = do_map_probe(probes[i], &dev->pcmcia_map); 624 mtd = do_map_probe(probes[i], &dev->pcmcia_map);
625 if(mtd) 625 if(mtd)
626 break; 626 break;
627 627
628 DEBUG(1, "FAILED: %s", probes[i]); 628 DEBUG(1, "FAILED: %s", probes[i]);
629 } 629 }
630 } 630 }
631 631
632 if(!mtd) { 632 if(!mtd) {
633 DEBUG(1, "Cant find an MTD"); 633 DEBUG(1, "Cant find an MTD");
634 pcmciamtd_release(link); 634 pcmciamtd_release(link);
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index b853670bfb81..9ee760f97bc6 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: physmap.c,v 1.37 2004/11/28 09:40:40 dwmw2 Exp $ 2 * $Id: physmap.c,v 1.38 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * Normal mappings of chips in physical memory 4 * Normal mappings of chips in physical memory
5 * 5 *
@@ -69,7 +69,7 @@ static int __init init_physmap(void)
69 mymtd->owner = THIS_MODULE; 69 mymtd->owner = THIS_MODULE;
70 70
71#ifdef CONFIG_MTD_PARTITIONS 71#ifdef CONFIG_MTD_PARTITIONS
72 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes, 72 mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
73 &mtd_parts, 0); 73 &mtd_parts, 0);
74 74
75 if (mtd_parts_nb > 0) 75 if (mtd_parts_nb > 0)
@@ -78,9 +78,9 @@ static int __init init_physmap(void)
78 return 0; 78 return 0;
79 } 79 }
80 80
81 if (num_physmap_partitions != 0) 81 if (num_physmap_partitions != 0)
82 { 82 {
83 printk(KERN_NOTICE 83 printk(KERN_NOTICE
84 "Using physmap partition definition\n"); 84 "Using physmap partition definition\n");
85 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions); 85 add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
86 return 0; 86 return 0;
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index 104576b5be34..a02eed94a231 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -6,7 +6,7 @@
6 * 6 *
7 * Generic platfrom device based RAM map 7 * Generic platfrom device based RAM map
8 * 8 *
9 * $Id: plat-ram.c,v 1.3 2005/03/19 22:41:27 gleixner Exp $ 9 * $Id: plat-ram.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -91,7 +91,7 @@ static int platram_remove(struct device *dev)
91 91
92 dev_dbg(dev, "removing device\n"); 92 dev_dbg(dev, "removing device\n");
93 93
94 if (info == NULL) 94 if (info == NULL)
95 return 0; 95 return 0;
96 96
97 if (info->mtd) { 97 if (info->mtd) {
@@ -118,7 +118,7 @@ static int platram_remove(struct device *dev)
118 118
119 if (info->map.virt != NULL) 119 if (info->map.virt != NULL)
120 iounmap(info->map.virt); 120 iounmap(info->map.virt);
121 121
122 kfree(info); 122 kfree(info);
123 123
124 return 0; 124 return 0;
@@ -139,7 +139,7 @@ static int platram_probe(struct device *dev)
139 int err = 0; 139 int err = 0;
140 140
141 dev_dbg(dev, "probe entered\n"); 141 dev_dbg(dev, "probe entered\n");
142 142
143 if (dev->platform_data == NULL) { 143 if (dev->platform_data == NULL) {
144 dev_err(dev, "no platform data supplied\n"); 144 dev_err(dev, "no platform data supplied\n");
145 err = -ENOENT; 145 err = -ENOENT;
@@ -177,7 +177,7 @@ static int platram_probe(struct device *dev)
177 177
178 info->map.phys = res->start; 178 info->map.phys = res->start;
179 info->map.size = (res->end - res->start) + 1; 179 info->map.size = (res->end - res->start) + 1;
180 info->map.name = pdata->mapname != NULL ? pdata->mapname : pd->name; 180 info->map.name = pdata->mapname != NULL ? pdata->mapname : (char *)pd->name;
181 info->map.bankwidth = pdata->bankwidth; 181 info->map.bankwidth = pdata->bankwidth;
182 182
183 /* register our usage of the memory area */ 183 /* register our usage of the memory area */
@@ -240,7 +240,7 @@ static int platram_probe(struct device *dev)
240 dev_err(dev, "add_mtd_device() failed\n"); 240 dev_err(dev, "add_mtd_device() failed\n");
241 err = -ENOMEM; 241 err = -ENOMEM;
242 } 242 }
243 243
244 dev_info(dev, "registered mtd device\n"); 244 dev_info(dev, "registered mtd device\n");
245 return err; 245 return err;
246 246
@@ -254,6 +254,7 @@ static int platram_probe(struct device *dev)
254 254
255static struct device_driver platram_driver = { 255static struct device_driver platram_driver = {
256 .name = "mtd-ram", 256 .name = "mtd-ram",
257 .owner = THIS_MODULE,
257 .bus = &platform_bus_type, 258 .bus = &platform_bus_type,
258 .probe = platram_probe, 259 .probe = platram_probe,
259 .remove = platram_remove, 260 .remove = platram_remove,
diff --git a/drivers/mtd/maps/pnc2000.c b/drivers/mtd/maps/pnc2000.c
index a0f43dad8985..d7e16c2d5c44 100644
--- a/drivers/mtd/maps/pnc2000.c
+++ b/drivers/mtd/maps/pnc2000.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: pnc2000.c,v 1.17 2004/11/16 18:29:02 dwmw2 Exp $ 8 * $Id: pnc2000.c,v 1.18 2005/11/07 11:14:28 gleixner Exp $
9 */ 9 */
10 10
11#include <linux/module.h> 11#include <linux/module.h>
@@ -21,7 +21,7 @@
21#define WINDOW_ADDR 0xbf000000 21#define WINDOW_ADDR 0xbf000000
22#define WINDOW_SIZE 0x00400000 22#define WINDOW_SIZE 0x00400000
23 23
24/* 24/*
25 * MAP DRIVER STUFF 25 * MAP DRIVER STUFF
26 */ 26 */
27 27
@@ -36,7 +36,7 @@ static struct map_info pnc_map = {
36 36
37 37
38/* 38/*
39 * MTD 'PARTITIONING' STUFF 39 * MTD 'PARTITIONING' STUFF
40 */ 40 */
41static struct mtd_partition pnc_partitions[3] = { 41static struct mtd_partition pnc_partitions[3] = {
42 { 42 {
@@ -56,7 +56,7 @@ static struct mtd_partition pnc_partitions[3] = {
56 } 56 }
57}; 57};
58 58
59/* 59/*
60 * This is the master MTD device for which all the others are just 60 * This is the master MTD device for which all the others are just
61 * auto-relocating aliases. 61 * auto-relocating aliases.
62 */ 62 */
diff --git a/drivers/mtd/maps/pq2fads.c b/drivers/mtd/maps/pq2fads.c
new file mode 100644
index 000000000000..fb78d87cc130
--- /dev/null
+++ b/drivers/mtd/maps/pq2fads.c
@@ -0,0 +1,88 @@
1/*
2 * drivers/mtd/maps/pq2fads.c
3 *
4 * Mapping for the flash SIMM on 8272ADS and PQ2FADS board
5 *
6 * Author: Vitaly Bordug <vbordug@ru.mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/module.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <asm/io.h>
19#include <asm/ppcboot.h>
20#include <linux/mtd/mtd.h>
21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h>
23#include <linux/mtd/physmap.h>
24
25/*
26 NOTE: bank width and interleave relative to the installed flash
27 should have been chosen within MTD_CFI_GEOMETRY options.
28 */
29#define PQ2FADS_BANK_WIDTH 4
30
31static struct mtd_partition pq2fads_partitions[] = {
32 {
33#ifdef CONFIG_ADS8272
34 .name = "HRCW",
35 .size = 0x40000,
36 .offset = 0,
37 .mask_flags = MTD_WRITEABLE, /* force read-only */
38 }, {
39 .name = "User FS",
40 .size = 0x5c0000,
41 .offset = 0x40000,
42#else
43 .name = "User FS",
44 .size = 0x600000,
45 .offset = 0,
46#endif
47 }, {
48 .name = "uImage",
49 .size = 0x100000,
50 .offset = 0x600000,
51 .mask_flags = MTD_WRITEABLE, /* force read-only */
52 }, {
53 .name = "bootloader",
54 .size = 0x40000,
55 .offset = 0x700000,
56 .mask_flags = MTD_WRITEABLE, /* force read-only */
57 }, {
58 .name = "bootloader env",
59 .size = 0x40000,
60 .offset = 0x740000,
61 .mask_flags = MTD_WRITEABLE, /* force read-only */
62 }
63};
64
65
66/* pointer to MPC885ADS board info data */
67extern unsigned char __res[];
68
69static int __init init_pq2fads_mtd(void)
70{
71 bd_t *bd = (bd_t *)__res;
72 physmap_configure(bd->bi_flashstart, bd->bi_flashsize, PQ2FADS_BANK_WIDTH, NULL);
73
74 physmap_set_partitions(pq2fads_partitions,
75 sizeof (pq2fads_partitions) /
76 sizeof (pq2fads_partitions[0]));
77 return 0;
78}
79
80static void __exit cleanup_pq2fads_mtd(void)
81{
82}
83
84module_init(init_pq2fads_mtd);
85module_exit(cleanup_pq2fads_mtd);
86
87MODULE_LICENSE("GPL");
88MODULE_DESCRIPTION("MTD map and partitions for MPC8272ADS boards");
diff --git a/drivers/mtd/maps/redwood.c b/drivers/mtd/maps/redwood.c
index edd01ee4f90b..5b76ed886185 100644
--- a/drivers/mtd/maps/redwood.c
+++ b/drivers/mtd/maps/redwood.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: redwood.c,v 1.10 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: redwood.c,v 1.11 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * drivers/mtd/maps/redwood.c 4 * drivers/mtd/maps/redwood.c
5 * 5 *
@@ -79,7 +79,7 @@ static struct mtd_partition redwood_flash_partitions[] = {
79 79
80#define RW_PART0_OF 0 80#define RW_PART0_OF 0
81#define RW_PART0_SZ 0x400000 /* 4 MiB data */ 81#define RW_PART0_SZ 0x400000 /* 4 MiB data */
82#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ 82#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
83#define RW_PART1_SZ 0x10000 /* 64K VPD */ 83#define RW_PART1_SZ 0x10000 /* 64K VPD */
84#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ 84#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ
85#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000) 85#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000)
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index c8d0da19d897..9e8bb1782be0 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * Flash memory access on SA11x0 based devices 2 * Flash memory access on SA11x0 based devices
3 * 3 *
4 * (C) 2000 Nicolas Pitre <nico@cam.org> 4 * (C) 2000 Nicolas Pitre <nico@cam.org>
5 * 5 *
6 * $Id: sa1100-flash.c,v 1.47 2004/11/01 13:44:36 rmk Exp $ 6 * $Id: sa1100-flash.c,v 1.51 2005/11/07 11:14:28 gleixner Exp $
7 */ 7 */
8#include <linux/config.h> 8#include <linux/config.h>
9#include <linux/module.h> 9#include <linux/module.h>
@@ -241,8 +241,7 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla
241#endif 241#endif
242 } 242 }
243 243
244 if (info->parts) 244 kfree(info->parts);
245 kfree(info->parts);
246 245
247 for (i = info->num_subdev - 1; i >= 0; i--) 246 for (i = info->num_subdev - 1; i >= 0; i--)
248 sa1100_destroy_subdev(&info->subdev[i]); 247 sa1100_destroy_subdev(&info->subdev[i]);
diff --git a/drivers/mtd/maps/sbc8240.c b/drivers/mtd/maps/sbc8240.c
index da684d3384e9..225cdd9ba5b2 100644
--- a/drivers/mtd/maps/sbc8240.c
+++ b/drivers/mtd/maps/sbc8240.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * This code is GPLed 6 * This code is GPLed
7 * 7 *
8 * $Id: sbc8240.c,v 1.4 2004/07/12 22:38:29 dwmw2 Exp $ 8 * $Id: sbc8240.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
9 * 9 *
10 */ 10 */
11 11
@@ -205,7 +205,7 @@ int __init init_sbc8240_mtd (void)
205 } else { 205 } else {
206 printk (KERN_NOTICE MSG_PREFIX 206 printk (KERN_NOTICE MSG_PREFIX
207 "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name); 207 "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
208 add_mtd_partitions (sbc8240_mtd[i], 208 add_mtd_partitions (sbc8240_mtd[i],
209 sbc8240_part_banks[i].mtd_part, 209 sbc8240_part_banks[i].mtd_part,
210 sbc8240_part_banks[i].nums); 210 sbc8240_part_banks[i].nums);
211 } 211 }
diff --git a/drivers/mtd/maps/sbc_gxx.c b/drivers/mtd/maps/sbc_gxx.c
index 65add28bde14..7cc4041d096d 100644
--- a/drivers/mtd/maps/sbc_gxx.c
+++ b/drivers/mtd/maps/sbc_gxx.c
@@ -1,35 +1,35 @@
1/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX, 1/* sbc_gxx.c -- MTD map driver for Arcom Control Systems SBC-MediaGX,
2 SBC-GXm and SBC-GX1 series boards. 2 SBC-GXm and SBC-GX1 series boards.
3 3
4 Copyright (C) 2001 Arcom Control System Ltd 4 Copyright (C) 2001 Arcom Control System Ltd
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or 8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version. 9 (at your option) any later version.
10 10
11 This program is distributed in the hope that it will be useful, 11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details. 14 GNU General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software 17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 19
20 $Id: sbc_gxx.c,v 1.33 2004/11/28 09:40:40 dwmw2 Exp $ 20 $Id: sbc_gxx.c,v 1.35 2005/11/07 11:14:28 gleixner Exp $
21 21
22The SBC-MediaGX / SBC-GXx has up to 16 MiB of 22The SBC-MediaGX / SBC-GXx has up to 16 MiB of
23Intel StrataFlash (28F320/28F640) in x8 mode. 23Intel StrataFlash (28F320/28F640) in x8 mode.
24 24
25This driver uses the CFI probe and Intel Extended Command Set drivers. 25This driver uses the CFI probe and Intel Extended Command Set drivers.
26 26
27The flash is accessed as follows: 27The flash is accessed as follows:
28 28
29 16 KiB memory window at 0xdc000-0xdffff 29 16 KiB memory window at 0xdc000-0xdffff
30 30
31 Two IO address locations for paging 31 Two IO address locations for paging
32 32
33 0x258 33 0x258
34 bit 0-7: address bit 14-21 34 bit 0-7: address bit 14-21
35 0x259 35 0x259
@@ -37,7 +37,7 @@ The flash is accessed as follows:
37 bit 7: 0 - reset/powered down 37 bit 7: 0 - reset/powered down
38 1 - device enabled 38 1 - device enabled
39 39
40The single flash device is divided into 3 partition which appear as 40The single flash device is divided into 3 partition which appear as
41separate MTD devices. 41separate MTD devices.
42 42
4325/04/2001 AJL (Arcom) Modified signon strings and partition sizes 4325/04/2001 AJL (Arcom) Modified signon strings and partition sizes
@@ -87,17 +87,17 @@ static volatile int page_in_window = -1; // Current page in window.
87static void __iomem *iomapadr; 87static void __iomem *iomapadr;
88static DEFINE_SPINLOCK(sbc_gxx_spin); 88static DEFINE_SPINLOCK(sbc_gxx_spin);
89 89
90/* partition_info gives details on the logical partitions that the split the 90/* partition_info gives details on the logical partitions that the split the
91 * single flash device into. If the size if zero we use up to the end of the 91 * single flash device into. If the size if zero we use up to the end of the
92 * device. */ 92 * device. */
93static struct mtd_partition partition_info[]={ 93static struct mtd_partition partition_info[]={
94 { .name = "SBC-GXx flash boot partition", 94 { .name = "SBC-GXx flash boot partition",
95 .offset = 0, 95 .offset = 0,
96 .size = BOOT_PARTITION_SIZE_KiB*1024 }, 96 .size = BOOT_PARTITION_SIZE_KiB*1024 },
97 { .name = "SBC-GXx flash data partition", 97 { .name = "SBC-GXx flash data partition",
98 .offset = BOOT_PARTITION_SIZE_KiB*1024, 98 .offset = BOOT_PARTITION_SIZE_KiB*1024,
99 .size = (DATA_PARTITION_SIZE_KiB)*1024 }, 99 .size = (DATA_PARTITION_SIZE_KiB)*1024 },
100 { .name = "SBC-GXx flash application partition", 100 { .name = "SBC-GXx flash application partition",
101 .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 } 101 .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
102}; 102};
103 103
@@ -130,7 +130,7 @@ static void sbc_gxx_copy_from(struct map_info *map, void *to, unsigned long from
130 unsigned long thislen = len; 130 unsigned long thislen = len;
131 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK))) 131 if (len > (WINDOW_LENGTH - (from & WINDOW_MASK)))
132 thislen = WINDOW_LENGTH-(from & WINDOW_MASK); 132 thislen = WINDOW_LENGTH-(from & WINDOW_MASK);
133 133
134 spin_lock(&sbc_gxx_spin); 134 spin_lock(&sbc_gxx_spin);
135 sbc_gxx_page(map, from); 135 sbc_gxx_page(map, from);
136 memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen); 136 memcpy_fromio(to, iomapadr + (from & WINDOW_MASK), thislen);
@@ -150,12 +150,12 @@ static void sbc_gxx_write8(struct map_info *map, map_word d, unsigned long adr)
150} 150}
151 151
152static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) 152static void sbc_gxx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
153{ 153{
154 while(len) { 154 while(len) {
155 unsigned long thislen = len; 155 unsigned long thislen = len;
156 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK))) 156 if (len > (WINDOW_LENGTH - (to & WINDOW_MASK)))
157 thislen = WINDOW_LENGTH-(to & WINDOW_MASK); 157 thislen = WINDOW_LENGTH-(to & WINDOW_MASK);
158 158
159 spin_lock(&sbc_gxx_spin); 159 spin_lock(&sbc_gxx_spin);
160 sbc_gxx_page(map, to); 160 sbc_gxx_page(map, to);
161 memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen); 161 memcpy_toio(iomapadr + (to & WINDOW_MASK), from, thislen);
@@ -201,7 +201,7 @@ static int __init init_sbc_gxx(void)
201 sbc_gxx_map.name ); 201 sbc_gxx_map.name );
202 return -EIO; 202 return -EIO;
203 } 203 }
204 204
205 if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) { 205 if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) {
206 printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n", 206 printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
207 sbc_gxx_map.name, 207 sbc_gxx_map.name,
@@ -209,8 +209,8 @@ static int __init init_sbc_gxx(void)
209 iounmap(iomapadr); 209 iounmap(iomapadr);
210 return -EAGAIN; 210 return -EAGAIN;
211 } 211 }
212 212
213 213
214 printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", 214 printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
215 sbc_gxx_map.name, 215 sbc_gxx_map.name,
216 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1, 216 PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
@@ -222,7 +222,7 @@ static int __init init_sbc_gxx(void)
222 cleanup_sbc_gxx(); 222 cleanup_sbc_gxx();
223 return -ENXIO; 223 return -ENXIO;
224 } 224 }
225 225
226 all_mtd->owner = THIS_MODULE; 226 all_mtd->owner = THIS_MODULE;
227 227
228 /* Create MTD devices for each partition. */ 228 /* Create MTD devices for each partition. */
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
index a06ed21e7ed1..6fb9f3c57aab 100644
--- a/drivers/mtd/maps/sc520cdp.c
+++ b/drivers/mtd/maps/sc520cdp.c
@@ -16,7 +16,7 @@
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18 * 18 *
19 * $Id: sc520cdp.c,v 1.21 2004/12/13 10:27:08 dedekind Exp $ 19 * $Id: sc520cdp.c,v 1.22 2005/11/07 11:14:28 gleixner Exp $
20 * 20 *
21 * 21 *
22 * The SC520CDP is an evaluation board for the Elan SC520 processor available 22 * The SC520CDP is an evaluation board for the Elan SC520 processor available
@@ -231,7 +231,7 @@ static void sc520cdp_setup_par(void)
231static int __init init_sc520cdp(void) 231static int __init init_sc520cdp(void)
232{ 232{
233 int i, devices_found = 0; 233 int i, devices_found = 0;
234 234
235#ifdef REPROGRAM_PAR 235#ifdef REPROGRAM_PAR
236 /* reprogram PAR registers so flash appears at the desired addresses */ 236 /* reprogram PAR registers so flash appears at the desired addresses */
237 sc520cdp_setup_par(); 237 sc520cdp_setup_par();
@@ -278,7 +278,7 @@ static int __init init_sc520cdp(void)
278static void __exit cleanup_sc520cdp(void) 278static void __exit cleanup_sc520cdp(void)
279{ 279{
280 int i; 280 int i;
281 281
282 if (merged_mtd) { 282 if (merged_mtd) {
283 del_mtd_device(merged_mtd); 283 del_mtd_device(merged_mtd);
284 mtd_concat_destroy(merged_mtd); 284 mtd_concat_destroy(merged_mtd);
diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c
index 0ece3786d6ea..2c91dff8bb60 100644
--- a/drivers/mtd/maps/scx200_docflash.c
+++ b/drivers/mtd/maps/scx200_docflash.c
@@ -1,8 +1,8 @@
1/* linux/drivers/mtd/maps/scx200_docflash.c 1/* linux/drivers/mtd/maps/scx200_docflash.c
2 2
3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> 3 Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
4 4
5 $Id: scx200_docflash.c,v 1.10 2004/11/28 09:40:40 dwmw2 Exp $ 5 $Id: scx200_docflash.c,v 1.12 2005/11/07 11:14:28 gleixner Exp $
6 6
7 National Semiconductor SCx200 flash mapped with DOCCS 7 National Semiconductor SCx200 flash mapped with DOCCS
8*/ 8*/
@@ -49,23 +49,23 @@ static struct mtd_info *mymtd;
49 49
50#ifdef CONFIG_MTD_PARTITIONS 50#ifdef CONFIG_MTD_PARTITIONS
51static struct mtd_partition partition_info[] = { 51static struct mtd_partition partition_info[] = {
52 { 52 {
53 .name = "DOCCS Boot kernel", 53 .name = "DOCCS Boot kernel",
54 .offset = 0, 54 .offset = 0,
55 .size = 0xc0000 55 .size = 0xc0000
56 }, 56 },
57 { 57 {
58 .name = "DOCCS Low BIOS", 58 .name = "DOCCS Low BIOS",
59 .offset = 0xc0000, 59 .offset = 0xc0000,
60 .size = 0x40000 60 .size = 0x40000
61 }, 61 },
62 { 62 {
63 .name = "DOCCS File system", 63 .name = "DOCCS File system",
64 .offset = 0x100000, 64 .offset = 0x100000,
65 .size = ~0 /* calculate from flash size */ 65 .size = ~0 /* calculate from flash size */
66 }, 66 },
67 { 67 {
68 .name = "DOCCS High BIOS", 68 .name = "DOCCS High BIOS",
69 .offset = ~0, /* calculate from flash size */ 69 .offset = ~0, /* calculate from flash size */
70 .size = 0x80000 70 .size = 0x80000
71 }, 71 },
@@ -88,7 +88,7 @@ static int __init init_scx200_docflash(void)
88 88
89 printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n"); 89 printk(KERN_DEBUG NAME ": NatSemi SCx200 DOCCS Flash Driver\n");
90 90
91 if ((bridge = pci_find_device(PCI_VENDOR_ID_NS, 91 if ((bridge = pci_find_device(PCI_VENDOR_ID_NS,
92 PCI_DEVICE_ID_NS_SCx200_BRIDGE, 92 PCI_DEVICE_ID_NS_SCx200_BRIDGE,
93 NULL)) == NULL) 93 NULL)) == NULL)
94 return -ENODEV; 94 return -ENODEV;
@@ -134,28 +134,28 @@ static int __init init_scx200_docflash(void)
134 printk(KERN_ERR NAME ": invalid size for flash mapping\n"); 134 printk(KERN_ERR NAME ": invalid size for flash mapping\n");
135 return -EINVAL; 135 return -EINVAL;
136 } 136 }
137 137
138 if (width != 8 && width != 16) { 138 if (width != 8 && width != 16) {
139 printk(KERN_ERR NAME ": invalid bus width for flash mapping\n"); 139 printk(KERN_ERR NAME ": invalid bus width for flash mapping\n");
140 return -EINVAL; 140 return -EINVAL;
141 } 141 }
142 142
143 if (allocate_resource(&iomem_resource, &docmem, 143 if (allocate_resource(&iomem_resource, &docmem,
144 size, 144 size,
145 0xc0000000, 0xffffffff, 145 0xc0000000, 0xffffffff,
146 size, NULL, NULL)) { 146 size, NULL, NULL)) {
147 printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n"); 147 printk(KERN_ERR NAME ": unable to allocate memory for flash mapping\n");
148 return -ENOMEM; 148 return -ENOMEM;
149 } 149 }
150 150
151 ctrl = 0x07000000 | ((size-1) >> 13); 151 ctrl = 0x07000000 | ((size-1) >> 13);
152 152
153 printk(KERN_INFO "DOCCS BASE=0x%08lx, CTRL=0x%08lx\n", (long)docmem.start, (long)ctrl); 153 printk(KERN_INFO "DOCCS BASE=0x%08lx, CTRL=0x%08lx\n", (long)docmem.start, (long)ctrl);
154 154
155 pci_write_config_dword(bridge, SCx200_DOCCS_BASE, docmem.start); 155 pci_write_config_dword(bridge, SCx200_DOCCS_BASE, docmem.start);
156 pci_write_config_dword(bridge, SCx200_DOCCS_CTRL, ctrl); 156 pci_write_config_dword(bridge, SCx200_DOCCS_CTRL, ctrl);
157 pmr = inl(scx200_cb_base + SCx200_PMR); 157 pmr = inl(scx200_cb_base + SCx200_PMR);
158 158
159 if (width == 8) { 159 if (width == 8) {
160 pmr &= ~(1<<6); 160 pmr &= ~(1<<6);
161 } else { 161 } else {
@@ -163,8 +163,8 @@ static int __init init_scx200_docflash(void)
163 } 163 }
164 outl(pmr, scx200_cb_base + SCx200_PMR); 164 outl(pmr, scx200_cb_base + SCx200_PMR);
165 } 165 }
166 166
167 printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n", 167 printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n",
168 docmem.start, docmem.end, width); 168 docmem.start, docmem.end, width);
169 169
170 scx200_docflash_map.size = size; 170 scx200_docflash_map.size = size;
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
index b7f093fbf9b0..999f4bb3d845 100644
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ b/drivers/mtd/maps/sharpsl-flash.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * sharpsl-flash.c 2 * sharpsl-flash.c
3 * 3 *
4 * Copyright (C) 2001 Lineo Japan, Inc. 4 * Copyright (C) 2001 Lineo Japan, Inc.
5 * Copyright (C) 2002 SHARP 5 * Copyright (C) 2002 SHARP
6 * 6 *
7 * $Id: sharpsl-flash.c,v 1.5 2005/03/21 08:42:11 rpurdie Exp $ 7 * $Id: sharpsl-flash.c,v 1.7 2005/11/07 11:14:28 gleixner Exp $
8 * 8 *
9 * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp 9 * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
10 * Handle mapping of the flash on the RPX Lite and CLLF boards 10 * Handle mapping of the flash on the RPX Lite and CLLF boards
@@ -57,7 +57,7 @@ int __init init_sharpsl(void)
57 int nb_parts = 0; 57 int nb_parts = 0;
58 char *part_type = "static"; 58 char *part_type = "static";
59 59
60 printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", 60 printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
61 WINDOW_SIZE, WINDOW_ADDR); 61 WINDOW_SIZE, WINDOW_ADDR);
62 sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE); 62 sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
63 if (!sharpsl_map.virt) { 63 if (!sharpsl_map.virt) {
@@ -75,7 +75,7 @@ int __init init_sharpsl(void)
75 75
76 mymtd->owner = THIS_MODULE; 76 mymtd->owner = THIS_MODULE;
77 77
78 if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky() 78 if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
79 || machine_is_poodle()) { 79 || machine_is_poodle()) {
80 sharpsl_partitions[0].size=0x006d0000; 80 sharpsl_partitions[0].size=0x006d0000;
81 sharpsl_partitions[0].offset=0x00120000; 81 sharpsl_partitions[0].offset=0x00120000;
@@ -87,10 +87,10 @@ int __init init_sharpsl(void)
87 sharpsl_partitions[0].offset=0x00140000; 87 sharpsl_partitions[0].offset=0x00140000;
88 } else { 88 } else {
89 map_destroy(mymtd); 89 map_destroy(mymtd);
90 iounmap(sharpsl_map.virt); 90 iounmap(sharpsl_map.virt);
91 return -ENODEV; 91 return -ENODEV;
92 } 92 }
93 93
94 parts = sharpsl_partitions; 94 parts = sharpsl_partitions;
95 nb_parts = NB_OF(sharpsl_partitions); 95 nb_parts = NB_OF(sharpsl_partitions);
96 96
diff --git a/drivers/mtd/maps/solutionengine.c b/drivers/mtd/maps/solutionengine.c
index 8ce5d897645c..c53c2c369c9d 100644
--- a/drivers/mtd/maps/solutionengine.c
+++ b/drivers/mtd/maps/solutionengine.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: solutionengine.c,v 1.14 2004/09/16 23:27:14 gleixner Exp $ 2 * $Id: solutionengine.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
3 * 3 *
4 * Flash and EPROM on Hitachi Solution Engine and similar boards. 4 * Flash and EPROM on Hitachi Solution Engine and similar boards.
5 * 5 *
@@ -67,7 +67,7 @@ static int __init init_soleng_maps(void)
67 soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000); 67 soleng_eprom_map.virt = (void __iomem *)P1SEGADDR(0x01000000);
68 simple_map_init(&soleng_eprom_map); 68 simple_map_init(&soleng_eprom_map);
69 simple_map_init(&soleng_flash_map); 69 simple_map_init(&soleng_flash_map);
70 70
71 printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n"); 71 printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
72 flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map); 72 flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
73 if (!flash_mtd) { 73 if (!flash_mtd) {
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c
index 29091d10030a..0758cb1d0105 100644
--- a/drivers/mtd/maps/sun_uflash.c
+++ b/drivers/mtd/maps/sun_uflash.c
@@ -1,4 +1,4 @@
1/* $Id: sun_uflash.c,v 1.11 2004/11/04 13:24:15 gleixner Exp $ 1/* $Id: sun_uflash.c,v 1.13 2005/11/07 11:14:28 gleixner Exp $
2 * 2 *
3 * sun_uflash - Driver implementation for user-programmable flash 3 * sun_uflash - Driver implementation for user-programmable flash
4 * present on many Sun Microsystems SME boardsets. 4 * present on many Sun Microsystems SME boardsets.
@@ -63,7 +63,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
63 iTmp = prom_getproperty( 63 iTmp = prom_getproperty(
64 edev->prom_node, "reg", (void *)regs, sizeof(regs)); 64 edev->prom_node, "reg", (void *)regs, sizeof(regs));
65 if ((iTmp % sizeof(regs[0])) != 0) { 65 if ((iTmp % sizeof(regs[0])) != 0) {
66 printk("%s: Strange reg property size %d\n", 66 printk("%s: Strange reg property size %d\n",
67 UFLASH_DEVNAME, iTmp); 67 UFLASH_DEVNAME, iTmp);
68 return -ENODEV; 68 return -ENODEV;
69 } 69 }
@@ -75,7 +75,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
75 * can work on supporting it. 75 * can work on supporting it.
76 */ 76 */
77 printk("%s: unsupported device at 0x%lx (%d regs): " \ 77 printk("%s: unsupported device at 0x%lx (%d regs): " \
78 "email ebrower@usa.net\n", 78 "email ebrower@usa.net\n",
79 UFLASH_DEVNAME, edev->resource[0].start, nregs); 79 UFLASH_DEVNAME, edev->resource[0].start, nregs);
80 return -ENODEV; 80 return -ENODEV;
81 } 81 }
@@ -84,7 +84,7 @@ int uflash_devinit(struct linux_ebus_device* edev)
84 printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME); 84 printk("%s: unable to kmalloc new device\n", UFLASH_DEVNAME);
85 return(-ENOMEM); 85 return(-ENOMEM);
86 } 86 }
87 87
88 /* copy defaults and tweak parameters */ 88 /* copy defaults and tweak parameters */
89 memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ)); 89 memcpy(&pdev->map, &uflash_map_templ, sizeof(uflash_map_templ));
90 pdev->map.size = regs[0].reg_size; 90 pdev->map.size = regs[0].reg_size;
@@ -155,7 +155,7 @@ static void __exit uflash_cleanup(void)
155 155
156 list_for_each(udevlist, &device_list) { 156 list_for_each(udevlist, &device_list) {
157 udev = list_entry(udevlist, struct uflash_dev, list); 157 udev = list_entry(udevlist, struct uflash_dev, list);
158 DEBUG(2, "%s: removing device %s\n", 158 DEBUG(2, "%s: removing device %s\n",
159 UFLASH_DEVNAME, udev->name); 159 UFLASH_DEVNAME, udev->name);
160 160
161 if(0 != udev->mtd) { 161 if(0 != udev->mtd) {
@@ -166,11 +166,9 @@ static void __exit uflash_cleanup(void)
166 iounmap(udev->map.virt); 166 iounmap(udev->map.virt);
167 udev->map.virt = NULL; 167 udev->map.virt = NULL;
168 } 168 }
169 if(0 != udev->name) { 169 kfree(udev->name);
170 kfree(udev->name);
171 }
172 kfree(udev); 170 kfree(udev);
173 } 171 }
174} 172}
175 173
176module_init(uflash_init); 174module_init(uflash_init);
diff --git a/drivers/mtd/maps/tqm834x.c b/drivers/mtd/maps/tqm834x.c
new file mode 100644
index 000000000000..c7ae9a515c1a
--- /dev/null
+++ b/drivers/mtd/maps/tqm834x.c
@@ -0,0 +1,291 @@
1/*
2 * drivers/mtd/maps/tqm834x.c
3 *
4 * MTD mapping driver for TQM834x boards
5 *
6 * Copyright 2005 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 *
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/types.h>
18#include <linux/kernel.h>
19#include <linux/slab.h>
20#include <asm/io.h>
21#include <asm/ppcboot.h>
22
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/map.h>
25#include <linux/mtd/partitions.h>
26
27#define FLASH_BANK_MAX 2
28
29extern unsigned char __res[];
30
31/* trivial struct to describe partition information */
32struct mtd_part_def
33{
34 int nums;
35 unsigned char *type;
36 struct mtd_partition* mtd_part;
37};
38
39static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
40static struct map_info* map_banks[FLASH_BANK_MAX];
41static struct mtd_part_def part_banks[FLASH_BANK_MAX];
42
43static unsigned long num_banks;
44static unsigned long start_scan_addr;
45
46#ifdef CONFIG_MTD_PARTITIONS
47/*
48 * The following defines the partition layout of TQM834x boards.
49 *
50 * See include/linux/mtd/partitions.h for definition of the
51 * mtd_partition structure.
52 *
53 * Assume minimal initial size of 4 MiB per bank, will be updated
54 * later in init_tqm834x_mtd() routine.
55 */
56
57/* Partition definition for the first flash bank which is always present. */
58static struct mtd_partition tqm834x_partitions_bank1[] = {
59 {
60 .name = "u-boot", /* u-boot firmware */
61 .offset = 0x00000000,
62 .size = 0x00040000, /* 256 KiB */
63 /*mask_flags: MTD_WRITEABLE, * force read-only */
64 },
65 {
66 .name = "env", /* u-boot environment */
67 .offset = 0x00040000,
68 .size = 0x00020000, /* 128 KiB */
69 /*mask_flags: MTD_WRITEABLE, * force read-only */
70 },
71 {
72 .name = "kernel", /* linux kernel image */
73 .offset = 0x00060000,
74 .size = 0x00100000, /* 1 MiB */
75 /*mask_flags: MTD_WRITEABLE, * force read-only */
76 },
77 {
78 .name = "initrd", /* ramdisk image */
79 .offset = 0x00160000,
80 .size = 0x00200000, /* 2 MiB */
81 },
82 {
83 .name = "user", /* user data */
84 .offset = 0x00360000,
85 .size = 0x000a0000, /* remaining space */
86 /* NOTE: this parttion size is re-calcated in */
87 /* init_tqm834x_mtd() to cover actual remaining space. */
88 },
89};
90
91/* Partition definition for the second flash bank which may be present on some
92 * TQM834x boards.
93 */
94static struct mtd_partition tqm834x_partitions_bank2[] = {
95 {
96 .name = "jffs2", /* jffs2 filesystem */
97 .offset = 0x00000000,
98 .size = 0x00400000, /* whole device */
99 /* NOTE: this parttion size is re-calcated in */
100 /* init_tqm834x_mtd() to cover actual device size. */
101 },
102};
103
104#endif /* CONFIG_MTD_PARTITIONS */
105
106static int __init init_tqm834x_mtd(void)
107{
108 int idx = 0, ret = 0;
109 unsigned long flash_addr, flash_size, mtd_size = 0;
110
111 /* pointer to TQM834x board info data */
112 bd_t *bd = (bd_t *)__res;
113#ifdef CONFIG_MTD_CMDLINE_PARTS
114 int n;
115 char mtdid[4];
116 const char *part_probes[] = { "cmdlinepart", NULL };
117#endif
118
119 flash_addr = bd->bi_flashstart;
120 flash_size = bd->bi_flashsize;
121
122 /* request maximum flash size address space */
123 start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
124 if (!start_scan_addr) {
125 printk("%s: Failed to ioremap address: 0x%lx\n",
126 __FUNCTION__, flash_addr);
127 return -EIO;
128 }
129
130 for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
131 if (mtd_size >= flash_size)
132 break;
133
134 pr_debug("%s: chip probing count %d\n", __FUNCTION__, idx);
135
136 map_banks[idx] =
137 (struct map_info *)kmalloc(sizeof(struct map_info),
138 GFP_KERNEL);
139 if (map_banks[idx] == NULL) {
140 ret = -ENOMEM;
141 goto error_mem;
142 }
143 memset((void *)map_banks[idx], 0, sizeof(struct map_info));
144 map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
145 if (map_banks[idx]->name == NULL) {
146 ret = -ENOMEM;
147 goto error_mem;
148 }
149 memset((void *)map_banks[idx]->name, 0, 16);
150
151 sprintf(map_banks[idx]->name, "TQM834x-%d", idx);
152 map_banks[idx]->size = flash_size;
153 map_banks[idx]->bankwidth = 4;
154
155 simple_map_init(map_banks[idx]);
156
157 map_banks[idx]->virt = (void __iomem *)
158 (start_scan_addr + ((idx > 0) ?
159 (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0));
160 map_banks[idx]->phys =
161 flash_addr + ((idx > 0) ?
162 (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
163
164 /* start to probe flash chips */
165 mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
166 if (mtd_banks[idx]) {
167 mtd_banks[idx]->owner = THIS_MODULE;
168 mtd_size += mtd_banks[idx]->size;
169 num_banks++;
170 pr_debug("%s: bank %ld, name: %s, size: %d bytes \n",
171 __FUNCTION__, num_banks,
172 mtd_banks[idx]->name, mtd_banks[idx]->size);
173 }
174 }
175
176 /* no supported flash chips found */
177 if (!num_banks) {
178 printk("TQM834x: No supported flash chips found!\n");
179 ret = -ENXIO;
180 goto error_mem;
181 }
182
183#ifdef CONFIG_MTD_PARTITIONS
184 /*
185 * Select static partition definitions
186 */
187 n = ARRAY_SIZE(tqm834x_partitions_bank1);
188 part_banks[0].mtd_part = tqm834x_partitions_bank1;
189 part_banks[0].type = "static image bank1";
190 part_banks[0].nums = n;
191
192 /* update last partition size to cover actual remaining space */
193 tqm834x_partitions_bank1[n - 1].size =
194 mtd_banks[0]->size -
195 tqm834x_partitions_bank1[n - 1].offset;
196
197 /* check if we have second bank? */
198 if (num_banks == 2) {
199 n = ARRAY_SIZE(tqm834x_partitions_bank2);
200 part_banks[1].mtd_part = tqm834x_partitions_bank2;
201 part_banks[1].type = "static image bank2";
202 part_banks[1].nums = n;
203
204 /* update last partition size to cover actual remaining space */
205 tqm834x_partitions_bank2[n - 1].size =
206 mtd_banks[1]->size -
207 tqm834x_partitions_bank2[n - 1].offset;
208 }
209
210 for(idx = 0; idx < num_banks ; idx++) {
211#ifdef CONFIG_MTD_CMDLINE_PARTS
212 sprintf(mtdid, "%d", idx);
213 n = parse_mtd_partitions(mtd_banks[idx],
214 part_probes,
215 &part_banks[idx].mtd_part,
216 0);
217 pr_debug("%s: %d command line partitions on bank %s\n",
218 __FUNCTION__, n, mtdid);
219 if (n > 0) {
220 part_banks[idx].type = "command line";
221 part_banks[idx].nums = n;
222 }
223#endif /* CONFIG_MTD_CMDLINE_PARTS */
224 if (part_banks[idx].nums == 0) {
225 printk(KERN_NOTICE
226 "TQM834x flash bank %d: no partition info "
227 "available, registering whole device\n", idx);
228 add_mtd_device(mtd_banks[idx]);
229 } else {
230 printk(KERN_NOTICE
231 "TQM834x flash bank %d: Using %s partition "
232 "definition\n", idx, part_banks[idx].type);
233 add_mtd_partitions(mtd_banks[idx],
234 part_banks[idx].mtd_part,
235 part_banks[idx].nums);
236 }
237 }
238#else /* ! CONFIG_MTD_PARTITIONS */
239 printk(KERN_NOTICE "TQM834x flash: registering %d flash banks "
240 "at once\n", num_banks);
241
242 for(idx = 0 ; idx < num_banks ; idx++)
243 add_mtd_device(mtd_banks[idx]);
244
245#endif /* CONFIG_MTD_PARTITIONS */
246
247 return 0;
248error_mem:
249 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
250 if (map_banks[idx] != NULL) {
251 if (map_banks[idx]->name != NULL) {
252 kfree(map_banks[idx]->name);
253 map_banks[idx]->name = NULL;
254 }
255 kfree(map_banks[idx]);
256 map_banks[idx] = NULL;
257 }
258 }
259
260 iounmap((void *)start_scan_addr);
261
262 return ret;
263}
264
265static void __exit cleanup_tqm834x_mtd(void)
266{
267 unsigned int idx = 0;
268 for(idx = 0 ; idx < num_banks ; idx++) {
269 /* destroy mtd_info previously allocated */
270 if (mtd_banks[idx]) {
271 del_mtd_partitions(mtd_banks[idx]);
272 map_destroy(mtd_banks[idx]);
273 }
274
275 /* release map_info not used anymore */
276 kfree(map_banks[idx]->name);
277 kfree(map_banks[idx]);
278 }
279
280 if (start_scan_addr) {
281 iounmap((void *)start_scan_addr);
282 start_scan_addr = 0;
283 }
284}
285
286module_init(init_tqm834x_mtd);
287module_exit(cleanup_tqm834x_mtd);
288
289MODULE_LICENSE("GPL");
290MODULE_AUTHOR("Wolfgang Denk <wd@denx.de>");
291MODULE_DESCRIPTION("MTD map driver for TQM834x boards");
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c
index 4e28b977f224..a43517053e7c 100644
--- a/drivers/mtd/maps/tqm8xxl.c
+++ b/drivers/mtd/maps/tqm8xxl.c
@@ -1,15 +1,15 @@
1/* 1/*
2 * Handle mapping of the flash memory access routines 2 * Handle mapping of the flash memory access routines
3 * on TQM8xxL based devices. 3 * on TQM8xxL based devices.
4 * 4 *
5 * $Id: tqm8xxl.c,v 1.13 2004/10/20 22:21:53 dwmw2 Exp $ 5 * $Id: tqm8xxl.c,v 1.15 2005/11/07 11:14:28 gleixner Exp $
6 * 6 *
7 * based on rpxlite.c 7 * based on rpxlite.c
8 * 8 *
9 * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw> 9 * Copyright(C) 2001 Kirk Lee <kirk@hpc.ee.ntu.edu.tw>
10 * 10 *
11 * This code is GPLed 11 * This code is GPLed
12 * 12 *
13 */ 13 */
14 14
15/* 15/*
@@ -19,7 +19,7 @@
19 * 2MiB 512Kx16 2MiB 0 19 * 2MiB 512Kx16 2MiB 0
20 * 4MiB 1Mx16 4MiB 0 20 * 4MiB 1Mx16 4MiB 0
21 * 8MiB 1Mx16 4MiB 4MiB 21 * 8MiB 1Mx16 4MiB 4MiB
22 * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at 22 * Thus, we choose CONFIG_MTD_CFI_I2 & CONFIG_MTD_CFI_B4 at
23 * kernel configuration. 23 * kernel configuration.
24 */ 24 */
25#include <linux/config.h> 25#include <linux/config.h>
@@ -58,9 +58,9 @@ static void __iomem *start_scan_addr;
58 * Here are partition information for all known TQM8xxL series devices. 58 * Here are partition information for all known TQM8xxL series devices.
59 * See include/linux/mtd/partitions.h for definition of the mtd_partition 59 * See include/linux/mtd/partitions.h for definition of the mtd_partition
60 * structure. 60 * structure.
61 * 61 *
62 * The *_max_flash_size is the maximum possible mapped flash size which 62 * The *_max_flash_size is the maximum possible mapped flash size which
63 * is not necessarily the actual flash size. It must correspond to the 63 * is not necessarily the actual flash size. It must correspond to the
64 * value specified in the mapping definition defined by the 64 * value specified in the mapping definition defined by the
65 * "struct map_desc *_io_desc" for the corresponding machine. 65 * "struct map_desc *_io_desc" for the corresponding machine.
66 */ 66 */
@@ -132,9 +132,9 @@ int __init init_tqm_mtd(void)
132 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { 132 for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
133 if(mtd_size >= flash_size) 133 if(mtd_size >= flash_size)
134 break; 134 break;
135 135
136 printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx); 136 printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx);
137 137
138 map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL); 138 map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL);
139 if(map_banks[idx] == NULL) { 139 if(map_banks[idx] == NULL) {
140 ret = -ENOMEM; 140 ret = -ENOMEM;
@@ -180,7 +180,7 @@ int __init init_tqm_mtd(void)
180 mtd_size += mtd_banks[idx]->size; 180 mtd_size += mtd_banks[idx]->size;
181 num_banks++; 181 num_banks++;
182 182
183 printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks, 183 printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
184 mtd_banks[idx]->name, mtd_banks[idx]->size); 184 mtd_banks[idx]->name, mtd_banks[idx]->size);
185 } 185 }
186 } 186 }
@@ -211,7 +211,7 @@ int __init init_tqm_mtd(void)
211 } else { 211 } else {
212 printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n", 212 printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n",
213 idx, part_banks[idx].type); 213 idx, part_banks[idx].type);
214 add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part, 214 add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part,
215 part_banks[idx].nums); 215 part_banks[idx].nums);
216 } 216 }
217 } 217 }
@@ -224,10 +224,8 @@ int __init init_tqm_mtd(void)
224error_mem: 224error_mem:
225 for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) { 225 for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
226 if(map_banks[idx] != NULL) { 226 if(map_banks[idx] != NULL) {
227 if(map_banks[idx]->name != NULL) { 227 kfree(map_banks[idx]->name);
228 kfree(map_banks[idx]->name); 228 map_banks[idx]->name = NULL;
229 map_banks[idx]->name = NULL;
230 }
231 kfree(map_banks[idx]); 229 kfree(map_banks[idx]);
232 map_banks[idx] = NULL; 230 map_banks[idx] = NULL;
233 } 231 }
diff --git a/drivers/mtd/maps/ts5500_flash.c b/drivers/mtd/maps/ts5500_flash.c
index 3ebd90f56503..4b372bcb17f1 100644
--- a/drivers/mtd/maps/ts5500_flash.c
+++ b/drivers/mtd/maps/ts5500_flash.c
@@ -19,26 +19,22 @@
19 * 19 *
20 * Note: 20 * Note:
21 * - In order for detection to work, jumper 3 must be set. 21 * - In order for detection to work, jumper 3 must be set.
22 * - Drive A and B use a proprietary FTL from General Software which isn't 22 * - Drive A and B use the resident flash disk (RFD) flash translation layer.
23 * supported as of yet so standard drives can't be mounted; you can create 23 * - If you have created your own jffs file system and the bios overwrites
24 * your own (e.g. jffs) file system.
25 * - If you have created your own jffs file system and the bios overwrites
26 * it during boot, try disabling Drive A: and B: in the boot order. 24 * it during boot, try disabling Drive A: and B: in the boot order.
27 * 25 *
28 * $Id: ts5500_flash.c,v 1.2 2004/11/28 09:40:40 dwmw2 Exp $ 26 * $Id: ts5500_flash.c,v 1.5 2005/11/07 11:14:28 gleixner Exp $
29 */ 27 */
30 28
31#include <linux/config.h> 29#include <linux/config.h>
30#include <linux/init.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/types.h>
34#include <linux/kernel.h> 32#include <linux/kernel.h>
35#include <linux/init.h>
36#include <linux/mtd/mtd.h>
37#include <linux/mtd/map.h> 33#include <linux/mtd/map.h>
38 34#include <linux/mtd/mtd.h>
39#ifdef CONFIG_MTD_PARTITIONS
40#include <linux/mtd/partitions.h> 35#include <linux/mtd/partitions.h>
41#endif 36#include <linux/types.h>
37
42 38
43#define WINDOW_ADDR 0x09400000 39#define WINDOW_ADDR 0x09400000
44#define WINDOW_SIZE 0x00200000 40#define WINDOW_SIZE 0x00200000
@@ -50,7 +46,6 @@ static struct map_info ts5500_map = {
50 .phys = WINDOW_ADDR 46 .phys = WINDOW_ADDR
51}; 47};
52 48
53#ifdef CONFIG_MTD_PARTITIONS
54static struct mtd_partition ts5500_partitions[] = { 49static struct mtd_partition ts5500_partitions[] = {
55 { 50 {
56 .name = "Drive A", 51 .name = "Drive A",
@@ -71,8 +66,6 @@ static struct mtd_partition ts5500_partitions[] = {
71 66
72#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition)) 67#define NUM_PARTITIONS (sizeof(ts5500_partitions)/sizeof(struct mtd_partition))
73 68
74#endif
75
76static struct mtd_info *mymtd; 69static struct mtd_info *mymtd;
77 70
78static int __init init_ts5500_map(void) 71static int __init init_ts5500_map(void)
@@ -81,48 +74,39 @@ static int __init init_ts5500_map(void)
81 74
82 ts5500_map.virt = ioremap_nocache(ts5500_map.phys, ts5500_map.size); 75 ts5500_map.virt = ioremap_nocache(ts5500_map.phys, ts5500_map.size);
83 76
84 if(!ts5500_map.virt) { 77 if (!ts5500_map.virt) {
85 printk(KERN_ERR "Failed to ioremap_nocache\n"); 78 printk(KERN_ERR "Failed to ioremap_nocache\n");
86 rc = -EIO; 79 rc = -EIO;
87 goto err_out_ioremap; 80 goto err2;
88 } 81 }
89 82
90 simple_map_init(&ts5500_map); 83 simple_map_init(&ts5500_map);
91 84
92 mymtd = do_map_probe("jedec_probe", &ts5500_map); 85 mymtd = do_map_probe("jedec_probe", &ts5500_map);
93 if(!mymtd) 86 if (!mymtd)
94 mymtd = do_map_probe("map_rom", &ts5500_map); 87 mymtd = do_map_probe("map_rom", &ts5500_map);
95 88
96 if(!mymtd) { 89 if (!mymtd) {
97 rc = -ENXIO; 90 rc = -ENXIO;
98 goto err_out_map; 91 goto err1;
99 } 92 }
100 93
101 mymtd->owner = THIS_MODULE; 94 mymtd->owner = THIS_MODULE;
102#ifdef CONFIG_MTD_PARTITIONS
103 add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS); 95 add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS);
104#else
105 add_mtd_device(mymtd);
106#endif
107 96
108 return 0; 97 return 0;
109 98
110err_out_map: 99err1:
111 map_destroy(mymtd); 100 map_destroy(mymtd);
112err_out_ioremap:
113 iounmap(ts5500_map.virt); 101 iounmap(ts5500_map.virt);
114 102err2:
115 return rc; 103 return rc;
116} 104}
117 105
118static void __exit cleanup_ts5500_map(void) 106static void __exit cleanup_ts5500_map(void)
119{ 107{
120 if (mymtd) { 108 if (mymtd) {
121#ifdef CONFIG_MTD_PARTITIONS
122 del_mtd_partitions(mymtd); 109 del_mtd_partitions(mymtd);
123#else
124 del_mtd_device(mymtd);
125#endif
126 map_destroy(mymtd); 110 map_destroy(mymtd);
127 } 111 }
128 112
diff --git a/drivers/mtd/maps/tsunami_flash.c b/drivers/mtd/maps/tsunami_flash.c
index 170d71239e5e..9e21e6c02f80 100644
--- a/drivers/mtd/maps/tsunami_flash.c
+++ b/drivers/mtd/maps/tsunami_flash.c
@@ -2,7 +2,7 @@
2 * tsunami_flash.c 2 * tsunami_flash.c
3 * 3 *
4 * flash chip on alpha ds10... 4 * flash chip on alpha ds10...
5 * $Id: tsunami_flash.c,v 1.9 2004/07/14 09:52:55 dwmw2 Exp $ 5 * $Id: tsunami_flash.c,v 1.10 2005/11/07 11:14:29 gleixner Exp $
6 */ 6 */
7#include <asm/io.h> 7#include <asm/io.h>
8#include <asm/core_tsunami.h> 8#include <asm/core_tsunami.h>
@@ -41,7 +41,7 @@ static void tsunami_flash_copy_from(
41} 41}
42 42
43static void tsunami_flash_copy_to( 43static void tsunami_flash_copy_to(
44 struct map_info *map, unsigned long offset, 44 struct map_info *map, unsigned long offset,
45 const void *addr, ssize_t len) 45 const void *addr, ssize_t len)
46{ 46{
47 const unsigned char *src; 47 const unsigned char *src;
@@ -90,7 +90,7 @@ static int __init init_tsunami_flash(void)
90 char **type; 90 char **type;
91 91
92 tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT); 92 tsunami_tig_writeb(FLASH_ENABLE_BYTE, FLASH_ENABLE_PORT);
93 93
94 tsunami_flash_mtd = 0; 94 tsunami_flash_mtd = 0;
95 type = rom_probe_types; 95 type = rom_probe_types;
96 for(; !tsunami_flash_mtd && *type; type++) { 96 for(; !tsunami_flash_mtd && *type; type++) {
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index cc372136e852..79d92808b766 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) 6 * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
7 * 7 *
8 * $Id: uclinux.c,v 1.10 2005/01/05 18:05:13 dwmw2 Exp $ 8 * $Id: uclinux.c,v 1.12 2005/11/07 11:14:29 gleixner Exp $
9 */ 9 */
10 10
11/****************************************************************************/ 11/****************************************************************************/
@@ -82,7 +82,7 @@ int __init uclinux_mtd_init(void)
82 iounmap(mapp->virt); 82 iounmap(mapp->virt);
83 return(-ENXIO); 83 return(-ENXIO);
84 } 84 }
85 85
86 mtd->owner = THIS_MODULE; 86 mtd->owner = THIS_MODULE;
87 mtd->point = uclinux_point; 87 mtd->point = uclinux_point;
88 mtd->priv = mapp; 88 mtd->priv = mapp;
diff --git a/drivers/mtd/maps/vmax301.c b/drivers/mtd/maps/vmax301.c
index c8c74110ed1b..e0063941c0df 100644
--- a/drivers/mtd/maps/vmax301.c
+++ b/drivers/mtd/maps/vmax301.c
@@ -1,19 +1,19 @@
1// $Id: vmax301.c,v 1.30 2004/07/12 22:38:29 dwmw2 Exp $ 1// $Id: vmax301.c,v 1.32 2005/11/07 11:14:29 gleixner Exp $
2/* ###################################################################### 2/* ######################################################################
3 3
4 Tempustech VMAX SBC301 MTD Driver. 4 Tempustech VMAX SBC301 MTD Driver.
5 5
6 The VMAx 301 is a SBC based on . It 6 The VMAx 301 is a SBC based on . It
7 comes with three builtin AMD 29F016B flash chips and a socket for SRAM or 7 comes with three builtin AMD 29F016B flash chips and a socket for SRAM or
8 more flash. Each unit has it's own 8k mapping into a settable region 8 more flash. Each unit has it's own 8k mapping into a settable region
9 (0xD8000). There are two 8k mappings for each MTD, the first is always set 9 (0xD8000). There are two 8k mappings for each MTD, the first is always set
10 to the lower 8k of the device the second is paged. Writing a 16 bit page 10 to the lower 8k of the device the second is paged. Writing a 16 bit page
11 value to anywhere in the first 8k will cause the second 8k to page around. 11 value to anywhere in the first 8k will cause the second 8k to page around.
12 12
13 To boot the device a bios extension must be installed into the first 8k 13 To boot the device a bios extension must be installed into the first 8k
14 of flash that is smart enough to copy itself down, page in the rest of 14 of flash that is smart enough to copy itself down, page in the rest of
15 itself and begin executing. 15 itself and begin executing.
16 16
17 ##################################################################### */ 17 ##################################################################### */
18 18
19#include <linux/module.h> 19#include <linux/module.h>
@@ -35,7 +35,7 @@
35/* Actually we could use two spinlocks, but we'd have to have 35/* Actually we could use two spinlocks, but we'd have to have
36 more private space in the struct map_info. We lose a little 36 more private space in the struct map_info. We lose a little
37 performance like this, but we'd probably lose more by having 37 performance like this, but we'd probably lose more by having
38 the extra indirection from having one of the map->map_priv 38 the extra indirection from having one of the map->map_priv
39 fields pointing to yet another private struct. 39 fields pointing to yet another private struct.
40*/ 40*/
41static DEFINE_SPINLOCK(vmax301_spin); 41static DEFINE_SPINLOCK(vmax301_spin);
@@ -98,7 +98,7 @@ static void vmax301_copy_to(struct map_info *map, unsigned long to, const void *
98 spin_lock(&vmax301_spin); 98 spin_lock(&vmax301_spin);
99 vmax301_page(map, to); 99 vmax301_page(map, to);
100 memcpy_toio(map->map_priv_2 + to, from, thislen); 100 memcpy_toio(map->map_priv_2 + to, from, thislen);
101 spin_unlock(&vmax301_spin); 101 spin_unlock(&vmax301_spin);
102 to += thislen; 102 to += thislen;
103 from += thislen; 103 from += thislen;
104 len -= thislen; 104 len -= thislen;
@@ -137,7 +137,7 @@ static struct mtd_info *vmax_mtd[2] = {NULL, NULL};
137static void __exit cleanup_vmax301(void) 137static void __exit cleanup_vmax301(void)
138{ 138{
139 int i; 139 int i;
140 140
141 for (i=0; i<2; i++) { 141 for (i=0; i<2; i++) {
142 if (vmax_mtd[i]) { 142 if (vmax_mtd[i]) {
143 del_mtd_device(vmax_mtd[i]); 143 del_mtd_device(vmax_mtd[i]);
@@ -161,13 +161,13 @@ int __init init_vmax301(void)
161 return -EIO; 161 return -EIO;
162 } 162 }
163 /* Put the address in the map's private data area. 163 /* Put the address in the map's private data area.
164 We store the actual MTD IO address rather than the 164 We store the actual MTD IO address rather than the
165 address of the first half, because it's used more 165 address of the first half, because it's used more
166 often. 166 often.
167 */ 167 */
168 vmax_map[0].map_priv_2 = iomapadr + WINDOW_START; 168 vmax_map[0].map_priv_2 = iomapadr + WINDOW_START;
169 vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START); 169 vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START);
170 170
171 for (i=0; i<2; i++) { 171 for (i=0; i<2; i++) {
172 vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]); 172 vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]);
173 if (!vmax_mtd[i]) 173 if (!vmax_mtd[i])
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
index d6137b1b5670..f46bec66150f 100644
--- a/drivers/mtd/maps/walnut.c
+++ b/drivers/mtd/maps/walnut.c
@@ -1,12 +1,12 @@
1/* 1/*
2 * $Id: walnut.c,v 1.2 2004/12/10 12:07:42 holindho Exp $ 2 * $Id: walnut.c,v 1.3 2005/11/07 11:14:29 gleixner Exp $
3 * 3 *
4 * Mapping for Walnut flash 4 * Mapping for Walnut flash
5 * (used ebony.c as a "framework") 5 * (used ebony.c as a "framework")
6 * 6 *
7 * Heikki Lindholm <holindho@infradead.org> 7 * Heikki Lindholm <holindho@infradead.org>
8 * 8 *
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
@@ -21,7 +21,6 @@
21#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
22#include <linux/mtd/partitions.h> 22#include <linux/mtd/partitions.h>
23#include <linux/config.h> 23#include <linux/config.h>
24#include <linux/version.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <asm/ibm4xx.h> 25#include <asm/ibm4xx.h>
27#include <platforms/4xx/walnut.h> 26#include <platforms/4xx/walnut.h>
@@ -48,7 +47,7 @@ static struct mtd_partition walnut_partitions[] = {
48 .name = "OpenBIOS", 47 .name = "OpenBIOS",
49 .offset = 0x0, 48 .offset = 0x0,
50 .size = WALNUT_FLASH_SIZE, 49 .size = WALNUT_FLASH_SIZE,
51 /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */ 50 /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
52 } 51 }
53}; 52};
54 53
@@ -72,11 +71,11 @@ int __init init_walnut(void)
72 printk("The on-board flash is disabled (U79 sw 5)!"); 71 printk("The on-board flash is disabled (U79 sw 5)!");
73 return -EIO; 72 return -EIO;
74 } 73 }
75 if (WALNUT_FLASH_SRAM_SEL(fpga_brds1)) 74 if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
76 flash_base = WALNUT_FLASH_LOW; 75 flash_base = WALNUT_FLASH_LOW;
77 else 76 else
78 flash_base = WALNUT_FLASH_HIGH; 77 flash_base = WALNUT_FLASH_HIGH;
79 78
80 walnut_map.phys = flash_base; 79 walnut_map.phys = flash_base;
81 walnut_map.virt = 80 walnut_map.virt =
82 (void __iomem *)ioremap(flash_base, walnut_map.size); 81 (void __iomem *)ioremap(flash_base, walnut_map.size);
diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c
index 82b887b05707..60c197ec455b 100644
--- a/drivers/mtd/maps/wr_sbc82xx_flash.c
+++ b/drivers/mtd/maps/wr_sbc82xx_flash.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: wr_sbc82xx_flash.c,v 1.7 2004/11/04 13:24:15 gleixner Exp $ 2 * $Id: wr_sbc82xx_flash.c,v 1.8 2005/11/07 11:14:29 gleixner Exp $
3 * 3 *
4 * Map for flash chips on Wind River PowerQUICC II SBC82xx board. 4 * Map for flash chips on Wind River PowerQUICC II SBC82xx board.
5 * 5 *
@@ -163,10 +163,10 @@ static void __exit cleanup_sbc82xx_flash(void)
163 del_mtd_partitions(sbcmtd[i]); 163 del_mtd_partitions(sbcmtd[i]);
164 else 164 else
165 del_mtd_device(sbcmtd[i]); 165 del_mtd_device(sbcmtd[i]);
166 166
167 kfree(sbcmtd_parts[i]); 167 kfree(sbcmtd_parts[i]);
168 map_destroy(sbcmtd[i]); 168 map_destroy(sbcmtd[i]);
169 169
170 iounmap((void *)sbc82xx_flash_map[i].virt); 170 iounmap((void *)sbc82xx_flash_map[i].virt);
171 sbc82xx_flash_map[i].virt = 0; 171 sbc82xx_flash_map[i].virt = 0;
172 } 172 }
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index f8d2185819e7..339cb1218eaa 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtd_blkdevs.c,v 1.24 2004/11/16 18:28:59 dwmw2 Exp $ 2 * $Id: mtd_blkdevs.c,v 1.27 2005/11/07 11:14:20 gleixner Exp $
3 * 3 *
4 * (C) 2003 David Woodhouse <dwmw2@infradead.org> 4 * (C) 2003 David Woodhouse <dwmw2@infradead.org>
5 * 5 *
@@ -21,7 +21,6 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <asm/semaphore.h> 22#include <asm/semaphore.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <linux/devfs_fs_kernel.h>
25 24
26static LIST_HEAD(blktrans_majors); 25static LIST_HEAD(blktrans_majors);
27 26
@@ -86,7 +85,7 @@ static int mtd_blktrans_thread(void *arg)
86 daemonize("%sd", tr->name); 85 daemonize("%sd", tr->name);
87 86
88 /* daemonize() doesn't do this for us since some kernel threads 87 /* daemonize() doesn't do this for us since some kernel threads
89 actually want to deal with signals. We can't just call 88 actually want to deal with signals. We can't just call
90 exit_sighand() since that'll cause an oops when we finally 89 exit_sighand() since that'll cause an oops when we finally
91 do exit. */ 90 do exit. */
92 spin_lock_irq(&current->sighand->siglock); 91 spin_lock_irq(&current->sighand->siglock);
@@ -95,7 +94,7 @@ static int mtd_blktrans_thread(void *arg)
95 spin_unlock_irq(&current->sighand->siglock); 94 spin_unlock_irq(&current->sighand->siglock);
96 95
97 spin_lock_irq(rq->queue_lock); 96 spin_lock_irq(rq->queue_lock);
98 97
99 while (!tr->blkcore_priv->exiting) { 98 while (!tr->blkcore_priv->exiting) {
100 struct request *req; 99 struct request *req;
101 struct mtd_blktrans_dev *dev; 100 struct mtd_blktrans_dev *dev;
@@ -158,7 +157,7 @@ static int blktrans_open(struct inode *i, struct file *f)
158 if (!try_module_get(tr->owner)) 157 if (!try_module_get(tr->owner))
159 goto out_tr; 158 goto out_tr;
160 159
161 /* FIXME: Locking. A hot pluggable device can go away 160 /* FIXME: Locking. A hot pluggable device can go away
162 (del_mtd_device can be called for it) without its module 161 (del_mtd_device can be called for it) without its module
163 being unloaded. */ 162 being unloaded. */
164 dev->mtd->usecount++; 163 dev->mtd->usecount++;
@@ -196,7 +195,7 @@ static int blktrans_release(struct inode *i, struct file *f)
196} 195}
197 196
198 197
199static int blktrans_ioctl(struct inode *inode, struct file *file, 198static int blktrans_ioctl(struct inode *inode, struct file *file,
200 unsigned int cmd, unsigned long arg) 199 unsigned int cmd, unsigned long arg)
201{ 200{
202 struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data; 201 struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
@@ -265,7 +264,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
265 /* Required number was free */ 264 /* Required number was free */
266 list_add_tail(&new->list, &d->list); 265 list_add_tail(&new->list, &d->list);
267 goto added; 266 goto added;
268 } 267 }
269 last_devnum = d->devnum; 268 last_devnum = d->devnum;
270 } 269 }
271 if (new->devnum == -1) 270 if (new->devnum == -1)
@@ -289,11 +288,19 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
289 gd->major = tr->major; 288 gd->major = tr->major;
290 gd->first_minor = (new->devnum) << tr->part_bits; 289 gd->first_minor = (new->devnum) << tr->part_bits;
291 gd->fops = &mtd_blktrans_ops; 290 gd->fops = &mtd_blktrans_ops;
292 291
293 snprintf(gd->disk_name, sizeof(gd->disk_name), 292 if (tr->part_bits)
294 "%s%c", tr->name, (tr->part_bits?'a':'0') + new->devnum); 293 if (new->devnum < 26)
295 snprintf(gd->devfs_name, sizeof(gd->devfs_name), 294 snprintf(gd->disk_name, sizeof(gd->disk_name),
296 "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum); 295 "%s%c", tr->name, 'a' + new->devnum);
296 else
297 snprintf(gd->disk_name, sizeof(gd->disk_name),
298 "%s%c%c", tr->name,
299 'a' - 1 + new->devnum / 26,
300 'a' + new->devnum % 26);
301 else
302 snprintf(gd->disk_name, sizeof(gd->disk_name),
303 "%s%d", tr->name, new->devnum);
297 304
298 /* 2.5 has capacity in units of 512 bytes while still 305 /* 2.5 has capacity in units of 512 bytes while still
299 having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */ 306 having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
@@ -307,7 +314,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
307 set_disk_ro(gd, 1); 314 set_disk_ro(gd, 1);
308 315
309 add_disk(gd); 316 add_disk(gd);
310 317
311 return 0; 318 return 0;
312} 319}
313 320
@@ -322,7 +329,7 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
322 329
323 del_gendisk(old->blkcore_priv); 330 del_gendisk(old->blkcore_priv);
324 put_disk(old->blkcore_priv); 331 put_disk(old->blkcore_priv);
325 332
326 return 0; 333 return 0;
327} 334}
328 335
@@ -361,12 +368,12 @@ static struct mtd_notifier blktrans_notifier = {
361 .add = blktrans_notify_add, 368 .add = blktrans_notify_add,
362 .remove = blktrans_notify_remove, 369 .remove = blktrans_notify_remove,
363}; 370};
364 371
365int register_mtd_blktrans(struct mtd_blktrans_ops *tr) 372int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
366{ 373{
367 int ret, i; 374 int ret, i;
368 375
369 /* Register the notifier if/when the first device type is 376 /* Register the notifier if/when the first device type is
370 registered, to prevent the link/init ordering from fucking 377 registered, to prevent the link/init ordering from fucking
371 us over. */ 378 us over. */
372 if (!blktrans_notifier.list.next) 379 if (!blktrans_notifier.list.next)
@@ -409,9 +416,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
409 kfree(tr->blkcore_priv); 416 kfree(tr->blkcore_priv);
410 up(&mtd_table_mutex); 417 up(&mtd_table_mutex);
411 return ret; 418 return ret;
412 } 419 }
413
414 devfs_mk_dir(tr->name);
415 420
416 INIT_LIST_HEAD(&tr->devs); 421 INIT_LIST_HEAD(&tr->devs);
417 list_add(&tr->list, &blktrans_majors); 422 list_add(&tr->list, &blktrans_majors);
@@ -445,7 +450,6 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
445 tr->remove_dev(dev); 450 tr->remove_dev(dev);
446 } 451 }
447 452
448 devfs_remove(tr->name);
449 blk_cleanup_queue(tr->blkcore_priv->rq); 453 blk_cleanup_queue(tr->blkcore_priv->rq);
450 unregister_blkdev(tr->major, tr->name); 454 unregister_blkdev(tr->major, tr->name);
451 455
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 400dd9c89883..e84756644fd1 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -1,21 +1,22 @@
1/* 1/*
2 * Direct MTD block device access 2 * Direct MTD block device access
3 * 3 *
4 * $Id: mtdblock.c,v 1.66 2004/11/25 13:52:52 joern Exp $ 4 * $Id: mtdblock.c,v 1.68 2005/11/07 11:14:20 gleixner Exp $
5 * 5 *
6 * (C) 2000-2003 Nicolas Pitre <nico@cam.org> 6 * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
7 * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> 7 * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
8 */ 8 */
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/fs.h> 11#include <linux/fs.h>
15#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/sched.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/types.h>
17#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
18#include <linux/sched.h> /* TASK_* */ 19
19#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
20#include <linux/mtd/blktrans.h> 21#include <linux/mtd/blktrans.h>
21 22
@@ -31,7 +32,7 @@ static struct mtdblk_dev {
31 32
32/* 33/*
33 * Cache stuff... 34 * Cache stuff...
34 * 35 *
35 * Since typical flash erasable sectors are much larger than what Linux's 36 * Since typical flash erasable sectors are much larger than what Linux's
36 * buffer cache can handle, we must implement read-modify-write on flash 37 * buffer cache can handle, we must implement read-modify-write on flash
37 * sectors for each block write requests. To avoid over-erasing flash sectors 38 * sectors for each block write requests. To avoid over-erasing flash sectors
@@ -45,7 +46,7 @@ static void erase_callback(struct erase_info *done)
45 wake_up(wait_q); 46 wake_up(wait_q);
46} 47}
47 48
48static int erase_write (struct mtd_info *mtd, unsigned long pos, 49static int erase_write (struct mtd_info *mtd, unsigned long pos,
49 int len, const char *buf) 50 int len, const char *buf)
50{ 51{
51 struct erase_info erase; 52 struct erase_info erase;
@@ -103,18 +104,18 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
103 return 0; 104 return 0;
104 105
105 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" " 106 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: writing cached data for \"%s\" "
106 "at 0x%lx, size 0x%x\n", mtd->name, 107 "at 0x%lx, size 0x%x\n", mtd->name,
107 mtdblk->cache_offset, mtdblk->cache_size); 108 mtdblk->cache_offset, mtdblk->cache_size);
108 109
109 ret = erase_write (mtd, mtdblk->cache_offset, 110 ret = erase_write (mtd, mtdblk->cache_offset,
110 mtdblk->cache_size, mtdblk->cache_data); 111 mtdblk->cache_size, mtdblk->cache_data);
111 if (ret) 112 if (ret)
112 return ret; 113 return ret;
113 114
114 /* 115 /*
115 * Here we could argubly set the cache state to STATE_CLEAN. 116 * Here we could argubly set the cache state to STATE_CLEAN.
116 * However this could lead to inconsistency since we will not 117 * However this could lead to inconsistency since we will not
117 * be notified if this content is altered on the flash by other 118 * be notified if this content is altered on the flash by other
118 * means. Let's declare it empty and leave buffering tasks to 119 * means. Let's declare it empty and leave buffering tasks to
119 * the buffer cache instead. 120 * the buffer cache instead.
120 */ 121 */
@@ -123,7 +124,7 @@ static int write_cached_data (struct mtdblk_dev *mtdblk)
123} 124}
124 125
125 126
126static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, 127static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
127 int len, const char *buf) 128 int len, const char *buf)
128{ 129{
129 struct mtd_info *mtd = mtdblk->mtd; 130 struct mtd_info *mtd = mtdblk->mtd;
@@ -133,7 +134,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
133 134
134 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", 135 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n",
135 mtd->name, pos, len); 136 mtd->name, pos, len);
136 137
137 if (!sect_size) 138 if (!sect_size)
138 return MTD_WRITE (mtd, pos, len, &retlen, buf); 139 return MTD_WRITE (mtd, pos, len, &retlen, buf);
139 140
@@ -141,11 +142,11 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
141 unsigned long sect_start = (pos/sect_size)*sect_size; 142 unsigned long sect_start = (pos/sect_size)*sect_size;
142 unsigned int offset = pos - sect_start; 143 unsigned int offset = pos - sect_start;
143 unsigned int size = sect_size - offset; 144 unsigned int size = sect_size - offset;
144 if( size > len ) 145 if( size > len )
145 size = len; 146 size = len;
146 147
147 if (size == sect_size) { 148 if (size == sect_size) {
148 /* 149 /*
149 * We are covering a whole sector. Thus there is no 150 * We are covering a whole sector. Thus there is no
150 * need to bother with the cache while it may still be 151 * need to bother with the cache while it may still be
151 * useful for other partial writes. 152 * useful for other partial writes.
@@ -159,7 +160,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
159 if (mtdblk->cache_state == STATE_DIRTY && 160 if (mtdblk->cache_state == STATE_DIRTY &&
160 mtdblk->cache_offset != sect_start) { 161 mtdblk->cache_offset != sect_start) {
161 ret = write_cached_data(mtdblk); 162 ret = write_cached_data(mtdblk);
162 if (ret) 163 if (ret)
163 return ret; 164 return ret;
164 } 165 }
165 166
@@ -192,7 +193,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos,
192} 193}
193 194
194 195
195static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, 196static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
196 int len, char *buf) 197 int len, char *buf)
197{ 198{
198 struct mtd_info *mtd = mtdblk->mtd; 199 struct mtd_info *mtd = mtdblk->mtd;
@@ -200,9 +201,9 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
200 size_t retlen; 201 size_t retlen;
201 int ret; 202 int ret;
202 203
203 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", 204 DEBUG(MTD_DEBUG_LEVEL2, "mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n",
204 mtd->name, pos, len); 205 mtd->name, pos, len);
205 206
206 if (!sect_size) 207 if (!sect_size)
207 return MTD_READ (mtd, pos, len, &retlen, buf); 208 return MTD_READ (mtd, pos, len, &retlen, buf);
208 209
@@ -210,7 +211,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos,
210 unsigned long sect_start = (pos/sect_size)*sect_size; 211 unsigned long sect_start = (pos/sect_size)*sect_size;
211 unsigned int offset = pos - sect_start; 212 unsigned int offset = pos - sect_start;
212 unsigned int size = sect_size - offset; 213 unsigned int size = sect_size - offset;
213 if (size > len) 214 if (size > len)
214 size = len; 215 size = len;
215 216
216 /* 217 /*
@@ -268,12 +269,12 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
268 int dev = mbd->devnum; 269 int dev = mbd->devnum;
269 270
270 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n"); 271 DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
271 272
272 if (mtdblks[dev]) { 273 if (mtdblks[dev]) {
273 mtdblks[dev]->count++; 274 mtdblks[dev]->count++;
274 return 0; 275 return 0;
275 } 276 }
276 277
277 /* OK, it's not open. Create cache info for it */ 278 /* OK, it's not open. Create cache info for it */
278 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL); 279 mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
279 if (!mtdblk) 280 if (!mtdblk)
@@ -292,7 +293,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
292 } 293 }
293 294
294 mtdblks[dev] = mtdblk; 295 mtdblks[dev] = mtdblk;
295 296
296 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 297 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
297 298
298 return 0; 299 return 0;
@@ -320,7 +321,7 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
320 DEBUG(MTD_DEBUG_LEVEL1, "ok\n"); 321 DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
321 322
322 return 0; 323 return 0;
323} 324}
324 325
325static int mtdblock_flush(struct mtd_blktrans_dev *dev) 326static int mtdblock_flush(struct mtd_blktrans_dev *dev)
326{ 327{
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 16df1e4fb0e9..6f044584bdc6 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1,22 +1,23 @@
1/* 1/*
2 * $Id: mtdchar.c,v 1.73 2005/07/04 17:36:41 gleixner Exp $ 2 * $Id: mtdchar.c,v 1.76 2005/11/07 11:14:20 gleixner Exp $
3 * 3 *
4 * Character-device access to raw MTD devices. 4 * Character-device access to raw MTD devices.
5 * 5 *
6 */ 6 */
7 7
8#include <linux/config.h> 8#include <linux/config.h>
9#include <linux/device.h>
10#include <linux/fs.h>
11#include <linux/init.h>
9#include <linux/kernel.h> 12#include <linux/kernel.h>
10#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/sched.h>
16
11#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
12#include <linux/mtd/compatmac.h> 18#include <linux/mtd/compatmac.h>
13#include <linux/slab.h>
14#include <linux/init.h>
15#include <linux/fs.h>
16#include <linux/sched.h> /* TASK_* */
17#include <asm/uaccess.h>
18 19
19#include <linux/device.h> 20#include <asm/uaccess.h>
20 21
21static struct class *mtd_class; 22static struct class *mtd_class;
22 23
@@ -27,7 +28,7 @@ static void mtd_notify_add(struct mtd_info* mtd)
27 28
28 class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), 29 class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
29 NULL, "mtd%d", mtd->index); 30 NULL, "mtd%d", mtd->index);
30 31
31 class_device_create(mtd_class, NULL, 32 class_device_create(mtd_class, NULL,
32 MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1), 33 MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
33 NULL, "mtd%dro", mtd->index); 34 NULL, "mtd%dro", mtd->index);
@@ -70,26 +71,23 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig)
70 switch (orig) { 71 switch (orig) {
71 case 0: 72 case 0:
72 /* SEEK_SET */ 73 /* SEEK_SET */
73 file->f_pos = offset;
74 break; 74 break;
75 case 1: 75 case 1:
76 /* SEEK_CUR */ 76 /* SEEK_CUR */
77 file->f_pos += offset; 77 offset += file->f_pos;
78 break; 78 break;
79 case 2: 79 case 2:
80 /* SEEK_END */ 80 /* SEEK_END */
81 file->f_pos =mtd->size + offset; 81 offset += mtd->size;
82 break; 82 break;
83 default: 83 default:
84 return -EINVAL; 84 return -EINVAL;
85 } 85 }
86 86
87 if (file->f_pos < 0) 87 if (offset >= 0 && offset < mtd->size)
88 file->f_pos = 0; 88 return file->f_pos = offset;
89 else if (file->f_pos >= mtd->size)
90 file->f_pos = mtd->size - 1;
91 89
92 return file->f_pos; 90 return -EINVAL;
93} 91}
94 92
95 93
@@ -110,23 +108,23 @@ static int mtd_open(struct inode *inode, struct file *file)
110 return -EACCES; 108 return -EACCES;
111 109
112 mtd = get_mtd_device(NULL, devnum); 110 mtd = get_mtd_device(NULL, devnum);
113 111
114 if (!mtd) 112 if (!mtd)
115 return -ENODEV; 113 return -ENODEV;
116 114
117 if (MTD_ABSENT == mtd->type) { 115 if (MTD_ABSENT == mtd->type) {
118 put_mtd_device(mtd); 116 put_mtd_device(mtd);
119 return -ENODEV; 117 return -ENODEV;
120 } 118 }
121 119
122 file->private_data = mtd; 120 file->private_data = mtd;
123 121
124 /* You can't open it RW if it's not a writeable device */ 122 /* You can't open it RW if it's not a writeable device */
125 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) { 123 if ((file->f_mode & 2) && !(mtd->flags & MTD_WRITEABLE)) {
126 put_mtd_device(mtd); 124 put_mtd_device(mtd);
127 return -EACCES; 125 return -EACCES;
128 } 126 }
129 127
130 return 0; 128 return 0;
131} /* mtd_open */ 129} /* mtd_open */
132 130
@@ -139,10 +137,10 @@ static int mtd_close(struct inode *inode, struct file *file)
139 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n"); 137 DEBUG(MTD_DEBUG_LEVEL0, "MTD_close\n");
140 138
141 mtd = TO_MTD(file); 139 mtd = TO_MTD(file);
142 140
143 if (mtd->sync) 141 if (mtd->sync)
144 mtd->sync(mtd); 142 mtd->sync(mtd);
145 143
146 put_mtd_device(mtd); 144 put_mtd_device(mtd);
147 145
148 return 0; 146 return 0;
@@ -161,7 +159,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
161 int ret=0; 159 int ret=0;
162 int len; 160 int len;
163 char *kbuf; 161 char *kbuf;
164 162
165 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n"); 163 DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
166 164
167 if (*ppos + count > mtd->size) 165 if (*ppos + count > mtd->size)
@@ -169,11 +167,11 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
169 167
170 if (!count) 168 if (!count)
171 return 0; 169 return 0;
172 170
173 /* FIXME: Use kiovec in 2.5 to lock down the user's buffers 171 /* FIXME: Use kiovec in 2.5 to lock down the user's buffers
174 and pass them directly to the MTD functions */ 172 and pass them directly to the MTD functions */
175 while (count) { 173 while (count) {
176 if (count > MAX_KMALLOC_SIZE) 174 if (count > MAX_KMALLOC_SIZE)
177 len = MAX_KMALLOC_SIZE; 175 len = MAX_KMALLOC_SIZE;
178 else 176 else
179 len = count; 177 len = count;
@@ -181,7 +179,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
181 kbuf=kmalloc(len,GFP_KERNEL); 179 kbuf=kmalloc(len,GFP_KERNEL);
182 if (!kbuf) 180 if (!kbuf)
183 return -ENOMEM; 181 return -ENOMEM;
184 182
185 switch (MTD_MODE(file)) { 183 switch (MTD_MODE(file)) {
186 case MTD_MODE_OTP_FACT: 184 case MTD_MODE_OTP_FACT:
187 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf); 185 ret = mtd->read_fact_prot_reg(mtd, *ppos, len, &retlen, kbuf);
@@ -194,7 +192,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
194 } 192 }
195 /* Nand returns -EBADMSG on ecc errors, but it returns 193 /* Nand returns -EBADMSG on ecc errors, but it returns
196 * the data. For our userspace tools it is important 194 * the data. For our userspace tools it is important
197 * to dump areas with ecc errors ! 195 * to dump areas with ecc errors !
198 * Userspace software which accesses NAND this way 196 * Userspace software which accesses NAND this way
199 * must be aware of the fact that it deals with NAND 197 * must be aware of the fact that it deals with NAND
200 */ 198 */
@@ -216,7 +214,7 @@ static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t
216 kfree(kbuf); 214 kfree(kbuf);
217 return ret; 215 return ret;
218 } 216 }
219 217
220 kfree(kbuf); 218 kfree(kbuf);
221 } 219 }
222 220
@@ -233,10 +231,10 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
233 int len; 231 int len;
234 232
235 DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n"); 233 DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
236 234
237 if (*ppos == mtd->size) 235 if (*ppos == mtd->size)
238 return -ENOSPC; 236 return -ENOSPC;
239 237
240 if (*ppos + count > mtd->size) 238 if (*ppos + count > mtd->size)
241 count = mtd->size - *ppos; 239 count = mtd->size - *ppos;
242 240
@@ -244,7 +242,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
244 return 0; 242 return 0;
245 243
246 while (count) { 244 while (count) {
247 if (count > MAX_KMALLOC_SIZE) 245 if (count > MAX_KMALLOC_SIZE)
248 len = MAX_KMALLOC_SIZE; 246 len = MAX_KMALLOC_SIZE;
249 else 247 else
250 len = count; 248 len = count;
@@ -259,7 +257,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
259 kfree(kbuf); 257 kfree(kbuf);
260 return -EFAULT; 258 return -EFAULT;
261 } 259 }
262 260
263 switch (MTD_MODE(file)) { 261 switch (MTD_MODE(file)) {
264 case MTD_MODE_OTP_FACT: 262 case MTD_MODE_OTP_FACT:
265 ret = -EROFS; 263 ret = -EROFS;
@@ -284,7 +282,7 @@ static ssize_t mtd_write(struct file *file, const char __user *buf, size_t count
284 kfree(kbuf); 282 kfree(kbuf);
285 return ret; 283 return ret;
286 } 284 }
287 285
288 kfree(kbuf); 286 kfree(kbuf);
289 } 287 }
290 288
@@ -308,7 +306,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
308 void __user *argp = (void __user *)arg; 306 void __user *argp = (void __user *)arg;
309 int ret = 0; 307 int ret = 0;
310 u_long size; 308 u_long size;
311 309
312 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n"); 310 DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");
313 311
314 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT; 312 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
@@ -320,7 +318,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
320 if (!access_ok(VERIFY_WRITE, argp, size)) 318 if (!access_ok(VERIFY_WRITE, argp, size))
321 return -EFAULT; 319 return -EFAULT;
322 } 320 }
323 321
324 switch (cmd) { 322 switch (cmd) {
325 case MEMGETREGIONCOUNT: 323 case MEMGETREGIONCOUNT:
326 if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int))) 324 if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
@@ -372,11 +370,11 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
372 erase->mtd = mtd; 370 erase->mtd = mtd;
373 erase->callback = mtdchar_erase_callback; 371 erase->callback = mtdchar_erase_callback;
374 erase->priv = (unsigned long)&waitq; 372 erase->priv = (unsigned long)&waitq;
375 373
376 /* 374 /*
377 FIXME: Allow INTERRUPTIBLE. Which means 375 FIXME: Allow INTERRUPTIBLE. Which means
378 not having the wait_queue head on the stack. 376 not having the wait_queue head on the stack.
379 377
380 If the wq_head is on the stack, and we 378 If the wq_head is on the stack, and we
381 leave because we got interrupted, then the 379 leave because we got interrupted, then the
382 wq_head is no longer there when the 380 wq_head is no longer there when the
@@ -404,13 +402,13 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
404 struct mtd_oob_buf buf; 402 struct mtd_oob_buf buf;
405 void *databuf; 403 void *databuf;
406 ssize_t retlen; 404 ssize_t retlen;
407 405
408 if(!(file->f_mode & 2)) 406 if(!(file->f_mode & 2))
409 return -EPERM; 407 return -EPERM;
410 408
411 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 409 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
412 return -EFAULT; 410 return -EFAULT;
413 411
414 if (buf.length > 0x4096) 412 if (buf.length > 0x4096)
415 return -EINVAL; 413 return -EINVAL;
416 414
@@ -426,7 +424,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
426 databuf = kmalloc(buf.length, GFP_KERNEL); 424 databuf = kmalloc(buf.length, GFP_KERNEL);
427 if (!databuf) 425 if (!databuf)
428 return -ENOMEM; 426 return -ENOMEM;
429 427
430 if (copy_from_user(databuf, buf.ptr, buf.length)) { 428 if (copy_from_user(databuf, buf.ptr, buf.length)) {
431 kfree(databuf); 429 kfree(databuf);
432 return -EFAULT; 430 return -EFAULT;
@@ -450,7 +448,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
450 448
451 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf))) 449 if (copy_from_user(&buf, argp, sizeof(struct mtd_oob_buf)))
452 return -EFAULT; 450 return -EFAULT;
453 451
454 if (buf.length > 0x4096) 452 if (buf.length > 0x4096)
455 return -EINVAL; 453 return -EINVAL;
456 454
@@ -466,14 +464,14 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
466 databuf = kmalloc(buf.length, GFP_KERNEL); 464 databuf = kmalloc(buf.length, GFP_KERNEL);
467 if (!databuf) 465 if (!databuf)
468 return -ENOMEM; 466 return -ENOMEM;
469 467
470 ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf); 468 ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf);
471 469
472 if (put_user(retlen, (uint32_t __user *)argp)) 470 if (put_user(retlen, (uint32_t __user *)argp))
473 ret = -EFAULT; 471 ret = -EFAULT;
474 else if (retlen && copy_to_user(buf.ptr, databuf, retlen)) 472 else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
475 ret = -EFAULT; 473 ret = -EFAULT;
476 474
477 kfree(databuf); 475 kfree(databuf);
478 break; 476 break;
479 } 477 }
@@ -523,7 +521,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
523 case MEMGETBADBLOCK: 521 case MEMGETBADBLOCK:
524 { 522 {
525 loff_t offs; 523 loff_t offs;
526 524
527 if (copy_from_user(&offs, argp, sizeof(loff_t))) 525 if (copy_from_user(&offs, argp, sizeof(loff_t)))
528 return -EFAULT; 526 return -EFAULT;
529 if (!mtd->block_isbad) 527 if (!mtd->block_isbad)
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index f3e65af33a9c..b1bf8c411de7 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -7,14 +7,15 @@
7 * 7 *
8 * This code is GPL 8 * This code is GPL
9 * 9 *
10 * $Id: mtdconcat.c,v 1.9 2004/06/30 15:17:41 dbrown Exp $ 10 * $Id: mtdconcat.c,v 1.11 2005/11/07 11:14:20 gleixner Exp $
11 */ 11 */
12 12
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/module.h>
16#include <linux/slab.h> 15#include <linux/slab.h>
17#include <linux/sched.h> /* TASK_* */ 16#include <linux/sched.h>
17#include <linux/types.h>
18
18#include <linux/mtd/mtd.h> 19#include <linux/mtd/mtd.h>
19#include <linux/mtd/concat.h> 20#include <linux/mtd/concat.h>
20 21
@@ -43,7 +44,7 @@ struct mtd_concat {
43 */ 44 */
44#define CONCAT(x) ((struct mtd_concat *)(x)) 45#define CONCAT(x) ((struct mtd_concat *)(x))
45 46
46/* 47/*
47 * MTD methods which look up the relevant subdevice, translate the 48 * MTD methods which look up the relevant subdevice, translate the
48 * effective address and pass through to the subdevice. 49 * effective address and pass through to the subdevice.
49 */ 50 */
@@ -877,7 +878,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
877 return &concat->mtd; 878 return &concat->mtd;
878} 879}
879 880
880/* 881/*
881 * This function destroys an MTD object obtained from concat_mtd_devs() 882 * This function destroys an MTD object obtained from concat_mtd_devs()
882 */ 883 */
883 884
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index dc86df18e94b..dade02ab0687 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: mtdcore.c,v 1.45 2005/02/18 14:34:50 dedekind Exp $ 2 * $Id: mtdcore.c,v 1.47 2005/11/07 11:14:20 gleixner Exp $
3 * 3 *
4 * Core registration and callback routines for MTD 4 * Core registration and callback routines for MTD
5 * drivers and users. 5 * drivers and users.
@@ -25,7 +25,7 @@
25 25
26#include <linux/mtd/mtd.h> 26#include <linux/mtd/mtd.h>
27 27
28/* These are exported solely for the purpose of mtd_blkdevs.c. You 28/* These are exported solely for the purpose of mtd_blkdevs.c. You
29 should not use them for _anything_ else */ 29 should not use them for _anything_ else */
30DECLARE_MUTEX(mtd_table_mutex); 30DECLARE_MUTEX(mtd_table_mutex);
31struct mtd_info *mtd_table[MAX_MTD_DEVICES]; 31struct mtd_info *mtd_table[MAX_MTD_DEVICES];
@@ -66,7 +66,7 @@ int add_mtd_device(struct mtd_info *mtd)
66 struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list); 66 struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
67 not->add(mtd); 67 not->add(mtd);
68 } 68 }
69 69
70 up(&mtd_table_mutex); 70 up(&mtd_table_mutex);
71 /* We _know_ we aren't being removed, because 71 /* We _know_ we aren't being removed, because
72 our caller is still holding us here. So none 72 our caller is still holding us here. So none
@@ -75,7 +75,7 @@ int add_mtd_device(struct mtd_info *mtd)
75 __module_get(THIS_MODULE); 75 __module_get(THIS_MODULE);
76 return 0; 76 return 0;
77 } 77 }
78 78
79 up(&mtd_table_mutex); 79 up(&mtd_table_mutex);
80 return 1; 80 return 1;
81} 81}
@@ -93,13 +93,13 @@ int add_mtd_device(struct mtd_info *mtd)
93int del_mtd_device (struct mtd_info *mtd) 93int del_mtd_device (struct mtd_info *mtd)
94{ 94{
95 int ret; 95 int ret;
96 96
97 down(&mtd_table_mutex); 97 down(&mtd_table_mutex);
98 98
99 if (mtd_table[mtd->index] != mtd) { 99 if (mtd_table[mtd->index] != mtd) {
100 ret = -ENODEV; 100 ret = -ENODEV;
101 } else if (mtd->usecount) { 101 } else if (mtd->usecount) {
102 printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n", 102 printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
103 mtd->index, mtd->name, mtd->usecount); 103 mtd->index, mtd->name, mtd->usecount);
104 ret = -EBUSY; 104 ret = -EBUSY;
105 } else { 105 } else {
@@ -140,7 +140,7 @@ void register_mtd_user (struct mtd_notifier *new)
140 list_add(&new->list, &mtd_notifiers); 140 list_add(&new->list, &mtd_notifiers);
141 141
142 __module_get(THIS_MODULE); 142 __module_get(THIS_MODULE);
143 143
144 for (i=0; i< MAX_MTD_DEVICES; i++) 144 for (i=0; i< MAX_MTD_DEVICES; i++)
145 if (mtd_table[i]) 145 if (mtd_table[i])
146 new->add(mtd_table[i]); 146 new->add(mtd_table[i]);
@@ -169,7 +169,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
169 for (i=0; i< MAX_MTD_DEVICES; i++) 169 for (i=0; i< MAX_MTD_DEVICES; i++)
170 if (mtd_table[i]) 170 if (mtd_table[i])
171 old->remove(mtd_table[i]); 171 old->remove(mtd_table[i]);
172 172
173 list_del(&old->list); 173 list_del(&old->list);
174 up(&mtd_table_mutex); 174 up(&mtd_table_mutex);
175 return 0; 175 return 0;
@@ -187,7 +187,7 @@ int unregister_mtd_user (struct mtd_notifier *old)
187 * both, return the num'th driver only if its address matches. Return NULL 187 * both, return the num'th driver only if its address matches. Return NULL
188 * if not. 188 * if not.
189 */ 189 */
190 190
191struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) 191struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
192{ 192{
193 struct mtd_info *ret = NULL; 193 struct mtd_info *ret = NULL;
@@ -297,39 +297,6 @@ EXPORT_SYMBOL(default_mtd_writev);
297EXPORT_SYMBOL(default_mtd_readv); 297EXPORT_SYMBOL(default_mtd_readv);
298 298
299/*====================================================================*/ 299/*====================================================================*/
300/* Power management code */
301
302#ifdef CONFIG_PM
303
304#include <linux/pm.h>
305
306static struct pm_dev *mtd_pm_dev = NULL;
307
308static int mtd_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
309{
310 int ret = 0, i;
311
312 if (down_trylock(&mtd_table_mutex))
313 return -EAGAIN;
314 if (rqst == PM_SUSPEND) {
315 for (i = 0; ret == 0 && i < MAX_MTD_DEVICES; i++) {
316 if (mtd_table[i] && mtd_table[i]->suspend)
317 ret = mtd_table[i]->suspend(mtd_table[i]);
318 }
319 } else i = MAX_MTD_DEVICES-1;
320
321 if (rqst == PM_RESUME || ret) {
322 for ( ; i >= 0; i--) {
323 if (mtd_table[i] && mtd_table[i]->resume)
324 mtd_table[i]->resume(mtd_table[i]);
325 }
326 }
327 up(&mtd_table_mutex);
328 return ret;
329}
330#endif
331
332/*====================================================================*/
333/* Support for /proc/mtd */ 300/* Support for /proc/mtd */
334 301
335#ifdef CONFIG_PROC_FS 302#ifdef CONFIG_PROC_FS
@@ -388,22 +355,11 @@ static int __init init_mtd(void)
388 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) 355 if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
389 proc_mtd->read_proc = mtd_read_proc; 356 proc_mtd->read_proc = mtd_read_proc;
390#endif 357#endif
391
392#ifdef CONFIG_PM
393 mtd_pm_dev = pm_register(PM_UNKNOWN_DEV, 0, mtd_pm_callback);
394#endif
395 return 0; 358 return 0;
396} 359}
397 360
398static void __exit cleanup_mtd(void) 361static void __exit cleanup_mtd(void)
399{ 362{
400#ifdef CONFIG_PM
401 if (mtd_pm_dev) {
402 pm_unregister(mtd_pm_dev);
403 mtd_pm_dev = NULL;
404 }
405#endif
406
407#ifdef CONFIG_PROC_FS 363#ifdef CONFIG_PROC_FS
408 if (proc_mtd) 364 if (proc_mtd)
409 remove_proc_entry( "mtd", NULL); 365 remove_proc_entry( "mtd", NULL);
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index b92e6bfffaf2..99395911d26f 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -5,11 +5,11 @@
5 * 5 *
6 * This code is GPL 6 * This code is GPL
7 * 7 *
8 * $Id: mtdpart.c,v 1.53 2005/02/08 17:11:13 nico Exp $ 8 * $Id: mtdpart.c,v 1.55 2005/11/07 11:14:20 gleixner Exp $
9 * 9 *
10 * 02-21-2002 Thomas Gleixner <gleixner@autronix.de> 10 * 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
11 * added support for read_oob, write_oob 11 * added support for read_oob, write_oob
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/types.h> 15#include <linux/types.h>
@@ -41,13 +41,13 @@ struct mtd_part {
41 */ 41 */
42#define PART(x) ((struct mtd_part *)(x)) 42#define PART(x) ((struct mtd_part *)(x))
43 43
44 44
45/* 45/*
46 * MTD methods which simply translate the effective address and pass through 46 * MTD methods which simply translate the effective address and pass through
47 * to the _real_ device. 47 * to the _real_ device.
48 */ 48 */
49 49
50static int part_read (struct mtd_info *mtd, loff_t from, size_t len, 50static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
51 size_t *retlen, u_char *buf) 51 size_t *retlen, u_char *buf)
52{ 52{
53 struct mtd_part *part = PART(mtd); 53 struct mtd_part *part = PART(mtd);
@@ -55,15 +55,15 @@ static int part_read (struct mtd_info *mtd, loff_t from, size_t len,
55 len = 0; 55 len = 0;
56 else if (from + len > mtd->size) 56 else if (from + len > mtd->size)
57 len = mtd->size - from; 57 len = mtd->size - from;
58 if (part->master->read_ecc == NULL) 58 if (part->master->read_ecc == NULL)
59 return part->master->read (part->master, from + part->offset, 59 return part->master->read (part->master, from + part->offset,
60 len, retlen, buf); 60 len, retlen, buf);
61 else 61 else
62 return part->master->read_ecc (part->master, from + part->offset, 62 return part->master->read_ecc (part->master, from + part->offset,
63 len, retlen, buf, NULL, &mtd->oobinfo); 63 len, retlen, buf, NULL, &mtd->oobinfo);
64} 64}
65 65
66static int part_point (struct mtd_info *mtd, loff_t from, size_t len, 66static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
67 size_t *retlen, u_char **buf) 67 size_t *retlen, u_char **buf)
68{ 68{
69 struct mtd_part *part = PART(mtd); 69 struct mtd_part *part = PART(mtd);
@@ -71,7 +71,7 @@ static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
71 len = 0; 71 len = 0;
72 else if (from + len > mtd->size) 72 else if (from + len > mtd->size)
73 len = mtd->size - from; 73 len = mtd->size - from;
74 return part->master->point (part->master, from + part->offset, 74 return part->master->point (part->master, from + part->offset,
75 len, retlen, buf); 75 len, retlen, buf);
76} 76}
77static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len) 77static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
@@ -82,7 +82,7 @@ static void part_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_
82} 82}
83 83
84 84
85static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 85static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
86 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel) 86 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
87{ 87{
88 struct mtd_part *part = PART(mtd); 88 struct mtd_part *part = PART(mtd);
@@ -92,11 +92,11 @@ static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
92 len = 0; 92 len = 0;
93 else if (from + len > mtd->size) 93 else if (from + len > mtd->size)
94 len = mtd->size - from; 94 len = mtd->size - from;
95 return part->master->read_ecc (part->master, from + part->offset, 95 return part->master->read_ecc (part->master, from + part->offset,
96 len, retlen, buf, eccbuf, oobsel); 96 len, retlen, buf, eccbuf, oobsel);
97} 97}
98 98
99static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len, 99static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
100 size_t *retlen, u_char *buf) 100 size_t *retlen, u_char *buf)
101{ 101{
102 struct mtd_part *part = PART(mtd); 102 struct mtd_part *part = PART(mtd);
@@ -104,15 +104,15 @@ static int part_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
104 len = 0; 104 len = 0;
105 else if (from + len > mtd->size) 105 else if (from + len > mtd->size)
106 len = mtd->size - from; 106 len = mtd->size - from;
107 return part->master->read_oob (part->master, from + part->offset, 107 return part->master->read_oob (part->master, from + part->offset,
108 len, retlen, buf); 108 len, retlen, buf);
109} 109}
110 110
111static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 111static int part_read_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
112 size_t *retlen, u_char *buf) 112 size_t *retlen, u_char *buf)
113{ 113{
114 struct mtd_part *part = PART(mtd); 114 struct mtd_part *part = PART(mtd);
115 return part->master->read_user_prot_reg (part->master, from, 115 return part->master->read_user_prot_reg (part->master, from,
116 len, retlen, buf); 116 len, retlen, buf);
117} 117}
118 118
@@ -123,11 +123,11 @@ static int part_get_user_prot_info (struct mtd_info *mtd,
123 return part->master->get_user_prot_info (part->master, buf, len); 123 return part->master->get_user_prot_info (part->master, buf, len);
124} 124}
125 125
126static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 126static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
127 size_t *retlen, u_char *buf) 127 size_t *retlen, u_char *buf)
128{ 128{
129 struct mtd_part *part = PART(mtd); 129 struct mtd_part *part = PART(mtd);
130 return part->master->read_fact_prot_reg (part->master, from, 130 return part->master->read_fact_prot_reg (part->master, from,
131 len, retlen, buf); 131 len, retlen, buf);
132} 132}
133 133
@@ -148,13 +148,13 @@ static int part_write (struct mtd_info *mtd, loff_t to, size_t len,
148 len = 0; 148 len = 0;
149 else if (to + len > mtd->size) 149 else if (to + len > mtd->size)
150 len = mtd->size - to; 150 len = mtd->size - to;
151 if (part->master->write_ecc == NULL) 151 if (part->master->write_ecc == NULL)
152 return part->master->write (part->master, to + part->offset, 152 return part->master->write (part->master, to + part->offset,
153 len, retlen, buf); 153 len, retlen, buf);
154 else 154 else
155 return part->master->write_ecc (part->master, to + part->offset, 155 return part->master->write_ecc (part->master, to + part->offset,
156 len, retlen, buf, NULL, &mtd->oobinfo); 156 len, retlen, buf, NULL, &mtd->oobinfo);
157 157
158} 158}
159 159
160static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, 160static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
@@ -170,7 +170,7 @@ static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
170 len = 0; 170 len = 0;
171 else if (to + len > mtd->size) 171 else if (to + len > mtd->size)
172 len = mtd->size - to; 172 len = mtd->size - to;
173 return part->master->write_ecc (part->master, to + part->offset, 173 return part->master->write_ecc (part->master, to + part->offset,
174 len, retlen, buf, eccbuf, oobsel); 174 len, retlen, buf, eccbuf, oobsel);
175} 175}
176 176
@@ -184,19 +184,19 @@ static int part_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
184 len = 0; 184 len = 0;
185 else if (to + len > mtd->size) 185 else if (to + len > mtd->size)
186 len = mtd->size - to; 186 len = mtd->size - to;
187 return part->master->write_oob (part->master, to + part->offset, 187 return part->master->write_oob (part->master, to + part->offset,
188 len, retlen, buf); 188 len, retlen, buf);
189} 189}
190 190
191static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len, 191static int part_write_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len,
192 size_t *retlen, u_char *buf) 192 size_t *retlen, u_char *buf)
193{ 193{
194 struct mtd_part *part = PART(mtd); 194 struct mtd_part *part = PART(mtd);
195 return part->master->write_user_prot_reg (part->master, from, 195 return part->master->write_user_prot_reg (part->master, from,
196 len, retlen, buf); 196 len, retlen, buf);
197} 197}
198 198
199static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len) 199static int part_lock_user_prot_reg (struct mtd_info *mtd, loff_t from, size_t len)
200{ 200{
201 struct mtd_part *part = PART(mtd); 201 struct mtd_part *part = PART(mtd);
202 return part->master->lock_user_prot_reg (part->master, from, len); 202 return part->master->lock_user_prot_reg (part->master, from, len);
@@ -208,7 +208,7 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
208 struct mtd_part *part = PART(mtd); 208 struct mtd_part *part = PART(mtd);
209 if (!(mtd->flags & MTD_WRITEABLE)) 209 if (!(mtd->flags & MTD_WRITEABLE))
210 return -EROFS; 210 return -EROFS;
211 if (part->master->writev_ecc == NULL) 211 if (part->master->writev_ecc == NULL)
212 return part->master->writev (part->master, vecs, count, 212 return part->master->writev (part->master, vecs, count,
213 to + part->offset, retlen); 213 to + part->offset, retlen);
214 else 214 else
@@ -221,12 +221,12 @@ static int part_readv (struct mtd_info *mtd, struct kvec *vecs,
221 unsigned long count, loff_t from, size_t *retlen) 221 unsigned long count, loff_t from, size_t *retlen)
222{ 222{
223 struct mtd_part *part = PART(mtd); 223 struct mtd_part *part = PART(mtd);
224 if (part->master->readv_ecc == NULL) 224 if (part->master->readv_ecc == NULL)
225 return part->master->readv (part->master, vecs, count, 225 return part->master->readv (part->master, vecs, count,
226 from + part->offset, retlen); 226 from + part->offset, retlen);
227 else 227 else
228 return part->master->readv_ecc (part->master, vecs, count, 228 return part->master->readv_ecc (part->master, vecs, count,
229 from + part->offset, retlen, 229 from + part->offset, retlen,
230 NULL, &mtd->oobinfo); 230 NULL, &mtd->oobinfo);
231} 231}
232 232
@@ -252,7 +252,7 @@ static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs,
252 if (oobsel == NULL) 252 if (oobsel == NULL)
253 oobsel = &mtd->oobinfo; 253 oobsel = &mtd->oobinfo;
254 return part->master->readv_ecc (part->master, vecs, count, 254 return part->master->readv_ecc (part->master, vecs, count,
255 from + part->offset, retlen, 255 from + part->offset, retlen,
256 eccbuf, oobsel); 256 eccbuf, oobsel);
257} 257}
258 258
@@ -286,7 +286,7 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback);
286static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len) 286static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
287{ 287{
288 struct mtd_part *part = PART(mtd); 288 struct mtd_part *part = PART(mtd);
289 if ((len + ofs) > mtd->size) 289 if ((len + ofs) > mtd->size)
290 return -EINVAL; 290 return -EINVAL;
291 return part->master->lock(part->master, ofs + part->offset, len); 291 return part->master->lock(part->master, ofs + part->offset, len);
292} 292}
@@ -294,7 +294,7 @@ static int part_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
294static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len) 294static int part_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
295{ 295{
296 struct mtd_part *part = PART(mtd); 296 struct mtd_part *part = PART(mtd);
297 if ((len + ofs) > mtd->size) 297 if ((len + ofs) > mtd->size)
298 return -EINVAL; 298 return -EINVAL;
299 return part->master->unlock(part->master, ofs + part->offset, len); 299 return part->master->unlock(part->master, ofs + part->offset, len);
300} 300}
@@ -337,8 +337,8 @@ static int part_block_markbad (struct mtd_info *mtd, loff_t ofs)
337 return part->master->block_markbad(part->master, ofs); 337 return part->master->block_markbad(part->master, ofs);
338} 338}
339 339
340/* 340/*
341 * This function unregisters and destroy all slave MTD objects which are 341 * This function unregisters and destroy all slave MTD objects which are
342 * attached to the given master MTD object. 342 * attached to the given master MTD object.
343 */ 343 */
344 344
@@ -371,7 +371,7 @@ int del_mtd_partitions(struct mtd_info *master)
371 * (Q: should we register the master MTD object as well?) 371 * (Q: should we register the master MTD object as well?)
372 */ 372 */
373 373
374int add_mtd_partitions(struct mtd_info *master, 374int add_mtd_partitions(struct mtd_info *master,
375 const struct mtd_partition *parts, 375 const struct mtd_partition *parts,
376 int nbparts) 376 int nbparts)
377{ 377{
@@ -414,7 +414,7 @@ int add_mtd_partitions(struct mtd_info *master,
414 slave->mtd.point = part_point; 414 slave->mtd.point = part_point;
415 slave->mtd.unpoint = part_unpoint; 415 slave->mtd.unpoint = part_unpoint;
416 } 416 }
417 417
418 if (master->read_ecc) 418 if (master->read_ecc)
419 slave->mtd.read_ecc = part_read_ecc; 419 slave->mtd.read_ecc = part_read_ecc;
420 if (master->write_ecc) 420 if (master->write_ecc)
@@ -465,9 +465,10 @@ int add_mtd_partitions(struct mtd_info *master,
465 if (slave->offset == MTDPART_OFS_APPEND) 465 if (slave->offset == MTDPART_OFS_APPEND)
466 slave->offset = cur_offset; 466 slave->offset = cur_offset;
467 if (slave->offset == MTDPART_OFS_NXTBLK) { 467 if (slave->offset == MTDPART_OFS_NXTBLK) {
468 u_int32_t emask = master->erasesize-1; 468 slave->offset = cur_offset;
469 slave->offset = (cur_offset + emask) & ~emask; 469 if ((cur_offset % master->erasesize) != 0) {
470 if (slave->offset != cur_offset) { 470 /* Round up to next erasesize */
471 slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize;
471 printk(KERN_NOTICE "Moving partition %d: " 472 printk(KERN_NOTICE "Moving partition %d: "
472 "0x%08x -> 0x%08x\n", i, 473 "0x%08x -> 0x%08x\n", i,
473 cur_offset, slave->offset); 474 cur_offset, slave->offset);
@@ -476,8 +477,8 @@ int add_mtd_partitions(struct mtd_info *master,
476 if (slave->mtd.size == MTDPART_SIZ_FULL) 477 if (slave->mtd.size == MTDPART_SIZ_FULL)
477 slave->mtd.size = master->size - slave->offset; 478 slave->mtd.size = master->size - slave->offset;
478 cur_offset = slave->offset + slave->mtd.size; 479 cur_offset = slave->offset + slave->mtd.size;
479 480
480 printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, 481 printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset,
481 slave->offset + slave->mtd.size, slave->mtd.name); 482 slave->offset + slave->mtd.size, slave->mtd.name);
482 483
483 /* let's do some sanity checks */ 484 /* let's do some sanity checks */
@@ -497,7 +498,7 @@ int add_mtd_partitions(struct mtd_info *master,
497 /* Deal with variable erase size stuff */ 498 /* Deal with variable erase size stuff */
498 int i; 499 int i;
499 struct mtd_erase_region_info *regions = master->eraseregions; 500 struct mtd_erase_region_info *regions = master->eraseregions;
500 501
501 /* Find the first erase regions which is part of this partition. */ 502 /* Find the first erase regions which is part of this partition. */
502 for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) 503 for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
503 ; 504 ;
@@ -512,7 +513,7 @@ int add_mtd_partitions(struct mtd_info *master,
512 slave->mtd.erasesize = master->erasesize; 513 slave->mtd.erasesize = master->erasesize;
513 } 514 }
514 515
515 if ((slave->mtd.flags & MTD_WRITEABLE) && 516 if ((slave->mtd.flags & MTD_WRITEABLE) &&
516 (slave->offset % slave->mtd.erasesize)) { 517 (slave->offset % slave->mtd.erasesize)) {
517 /* Doesn't start on a boundary of major erase size */ 518 /* Doesn't start on a boundary of major erase size */
518 /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ 519 /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */
@@ -520,14 +521,14 @@ int add_mtd_partitions(struct mtd_info *master,
520 printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", 521 printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
521 parts[i].name); 522 parts[i].name);
522 } 523 }
523 if ((slave->mtd.flags & MTD_WRITEABLE) && 524 if ((slave->mtd.flags & MTD_WRITEABLE) &&
524 (slave->mtd.size % slave->mtd.erasesize)) { 525 (slave->mtd.size % slave->mtd.erasesize)) {
525 slave->mtd.flags &= ~MTD_WRITEABLE; 526 slave->mtd.flags &= ~MTD_WRITEABLE;
526 printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", 527 printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
527 parts[i].name); 528 parts[i].name);
528 } 529 }
529 530
530 /* copy oobinfo from master */ 531 /* copy oobinfo from master */
531 memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo)); 532 memcpy(&slave->mtd.oobinfo, &master->oobinfo, sizeof(slave->mtd.oobinfo));
532 533
533 if(parts[i].mtdp) 534 if(parts[i].mtdp)
@@ -588,12 +589,12 @@ int deregister_mtd_parser(struct mtd_part_parser *p)
588 return 0; 589 return 0;
589} 590}
590 591
591int parse_mtd_partitions(struct mtd_info *master, const char **types, 592int parse_mtd_partitions(struct mtd_info *master, const char **types,
592 struct mtd_partition **pparts, unsigned long origin) 593 struct mtd_partition **pparts, unsigned long origin)
593{ 594{
594 struct mtd_part_parser *parser; 595 struct mtd_part_parser *parser;
595 int ret = 0; 596 int ret = 0;
596 597
597 for ( ; ret <= 0 && *types; types++) { 598 for ( ; ret <= 0 && *types; types++) {
598 parser = get_partition_parser(*types); 599 parser = get_partition_parser(*types);
599#ifdef CONFIG_KMOD 600#ifdef CONFIG_KMOD
@@ -607,7 +608,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
607 } 608 }
608 ret = (*parser->parse_fn)(master, pparts, origin); 609 ret = (*parser->parse_fn)(master, pparts, origin);
609 if (ret > 0) { 610 if (ret > 0) {
610 printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", 611 printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
611 ret, parser->name, master->name); 612 ret, parser->name, master->name);
612 } 613 }
613 put_partition_parser(parser); 614 put_partition_parser(parser);
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 36d34e5e5a5a..1fc4c134d939 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -1,5 +1,5 @@
1# drivers/mtd/nand/Kconfig 1# drivers/mtd/nand/Kconfig
2# $Id: Kconfig,v 1.31 2005/06/20 12:03:21 bjd Exp $ 2# $Id: Kconfig,v 1.35 2005/11/07 11:14:30 gleixner Exp $
3 3
4menu "NAND Flash Device Drivers" 4menu "NAND Flash Device Drivers"
5 depends on MTD!=n 5 depends on MTD!=n
@@ -25,33 +25,33 @@ config MTD_NAND_VERIFY_WRITE
25 25
26config MTD_NAND_AUTCPU12 26config MTD_NAND_AUTCPU12
27 tristate "SmartMediaCard on autronix autcpu12 board" 27 tristate "SmartMediaCard on autronix autcpu12 board"
28 depends on ARM && MTD_NAND && ARCH_AUTCPU12 28 depends on MTD_NAND && ARCH_AUTCPU12
29 help 29 help
30 This enables the driver for the autronix autcpu12 board to 30 This enables the driver for the autronix autcpu12 board to
31 access the SmartMediaCard. 31 access the SmartMediaCard.
32 32
33config MTD_NAND_EDB7312 33config MTD_NAND_EDB7312
34 tristate "Support for Cirrus Logic EBD7312 evaluation board" 34 tristate "Support for Cirrus Logic EBD7312 evaluation board"
35 depends on ARM && MTD_NAND && ARCH_EDB7312 35 depends on MTD_NAND && ARCH_EDB7312
36 help 36 help
37 This enables the driver for the Cirrus Logic EBD7312 evaluation 37 This enables the driver for the Cirrus Logic EBD7312 evaluation
38 board to access the onboard NAND Flash. 38 board to access the onboard NAND Flash.
39 39
40config MTD_NAND_H1900 40config MTD_NAND_H1900
41 tristate "iPAQ H1900 flash" 41 tristate "iPAQ H1900 flash"
42 depends on ARM && MTD_NAND && ARCH_PXA && MTD_PARTITIONS 42 depends on MTD_NAND && ARCH_PXA && MTD_PARTITIONS
43 help 43 help
44 This enables the driver for the iPAQ h1900 flash. 44 This enables the driver for the iPAQ h1900 flash.
45 45
46config MTD_NAND_SPIA 46config MTD_NAND_SPIA
47 tristate "NAND Flash device on SPIA board" 47 tristate "NAND Flash device on SPIA board"
48 depends on ARM && ARCH_P720T && MTD_NAND 48 depends on ARCH_P720T && MTD_NAND
49 help 49 help
50 If you had to ask, you don't have one. Say 'N'. 50 If you had to ask, you don't have one. Say 'N'.
51 51
52config MTD_NAND_TOTO 52config MTD_NAND_TOTO
53 tristate "NAND Flash device on TOTO board" 53 tristate "NAND Flash device on TOTO board"
54 depends on ARM && ARCH_OMAP && MTD_NAND 54 depends on ARCH_OMAP && MTD_NAND
55 help 55 help
56 Support for NAND flash on Texas Instruments Toto platform. 56 Support for NAND flash on Texas Instruments Toto platform.
57 57
@@ -59,8 +59,8 @@ config MTD_NAND_IDS
59 tristate 59 tristate
60 60
61config MTD_NAND_AU1550 61config MTD_NAND_AU1550
62 tristate "Au1550 NAND support" 62 tristate "Au1550/1200 NAND support"
63 depends on SOC_AU1550 && MTD_NAND 63 depends on (SOC_AU1200 || SOC_AU1550) && MTD_NAND
64 help 64 help
65 This enables the driver for the NAND flash controller on the 65 This enables the driver for the NAND flash controller on the
66 AMD/Alchemy 1550 SOC. 66 AMD/Alchemy 1550 SOC.
@@ -71,7 +71,7 @@ config MTD_NAND_RTC_FROM4
71 select REED_SOLOMON 71 select REED_SOLOMON
72 select REED_SOLOMON_DEC8 72 select REED_SOLOMON_DEC8
73 help 73 help
74 This enables the driver for the Renesas Technology AG-AND 74 This enables the driver for the Renesas Technology AG-AND
75 flash interface board (FROM_BOARD4) 75 flash interface board (FROM_BOARD4)
76 76
77config MTD_NAND_PPCHAMELEONEVB 77config MTD_NAND_PPCHAMELEONEVB
@@ -88,7 +88,7 @@ config MTD_NAND_S3C2410
88 SoCs 88 SoCs
89 89
90 No board specfic support is done by this driver, each board 90 No board specfic support is done by this driver, each board
91 must advertise a platform_device for the driver to attach. 91 must advertise a platform_device for the driver to attach.
92 92
93config MTD_NAND_S3C2410_DEBUG 93config MTD_NAND_S3C2410_DEBUG
94 bool "S3C2410 NAND driver debug" 94 bool "S3C2410 NAND driver debug"
@@ -181,7 +181,7 @@ config MTD_NAND_DISKONCHIP_BBTWRITE
181 181
182 config MTD_NAND_SHARPSL 182 config MTD_NAND_SHARPSL
183 bool "Support for NAND Flash on Sharp SL Series (C7xx + others)" 183 bool "Support for NAND Flash on Sharp SL Series (C7xx + others)"
184 depends on MTD_NAND && ARCH_PXA 184 depends on MTD_NAND && ARCH_PXA
185 185
186 config MTD_NAND_NANDSIM 186 config MTD_NAND_NANDSIM
187 bool "Support for NAND Flash Simulator" 187 bool "Support for NAND Flash Simulator"
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 4c7719ce3f48..9c5945d6df88 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2004 Embedded Edge, LLC 4 * Copyright (C) 2004 Embedded Edge, LLC
5 * 5 *
6 * $Id: au1550nd.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $ 6 * $Id: au1550nd.c,v 1.13 2005/11/07 11:14:30 gleixner Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -17,24 +17,19 @@
17#include <linux/mtd/mtd.h> 17#include <linux/mtd/mtd.h>
18#include <linux/mtd/nand.h> 18#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h> 19#include <linux/mtd/partitions.h>
20#include <linux/version.h>
20#include <asm/io.h> 21#include <asm/io.h>
21 22
22/* fixme: this is ugly */ 23/* fixme: this is ugly */
23#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0) 24#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
24#include <asm/mach-au1x00/au1000.h> 25#include <asm/mach-au1x00/au1xxx.h>
25#ifdef CONFIG_MIPS_PB1550
26#include <asm/mach-pb1x00/pb1550.h>
27#endif
28#ifdef CONFIG_MIPS_DB1550
29#include <asm/mach-db1x00/db1x00.h>
30#endif
31#else 26#else
32#include <asm/au1000.h> 27#include <asm/au1000.h>
33#ifdef CONFIG_MIPS_PB1550 28#ifdef CONFIG_MIPS_PB1550
34#include <asm/pb1550.h> 29#include <asm/pb1550.h>
35#endif 30#endif
36#ifdef CONFIG_MIPS_DB1550 31#ifdef CONFIG_MIPS_DB1550
37#include <asm/db1x00.h> 32#include <asm/db1x00.h>
38#endif 33#endif
39#endif 34#endif
40 35
@@ -45,39 +40,22 @@ static struct mtd_info *au1550_mtd = NULL;
45static void __iomem *p_nand; 40static void __iomem *p_nand;
46static int nand_width = 1; /* default x8*/ 41static int nand_width = 1; /* default x8*/
47 42
48#define NAND_CS 1
49
50/* 43/*
51 * Define partitions for flash device 44 * Define partitions for flash device
52 */ 45 */
53const static struct mtd_partition partition_info[] = { 46const static struct mtd_partition partition_info[] = {
54#ifdef CONFIG_MIPS_PB1550 47 {
55#define NUM_PARTITIONS 2 48 .name = "NAND FS 0",
56 {
57 .name = "Pb1550 NAND FS 0",
58 .offset = 0, 49 .offset = 0,
59 .size = 8*1024*1024 50 .size = 8*1024*1024
60 }, 51 },
61 { 52 {
62 .name = "Pb1550 NAND FS 1", 53 .name = "NAND FS 1",
63 .offset = MTDPART_OFS_APPEND, 54 .offset = MTDPART_OFS_APPEND,
64 .size = MTDPART_SIZ_FULL 55 .size = MTDPART_SIZ_FULL
65 } 56 }
66#endif
67#ifdef CONFIG_MIPS_DB1550
68#define NUM_PARTITIONS 2
69 {
70 .name = "Db1550 NAND FS 0",
71 .offset = 0,
72 .size = 8*1024*1024
73 },
74 {
75 .name = "Db1550 NAND FS 1",
76 .offset = MTDPART_OFS_APPEND,
77 .size = MTDPART_SIZ_FULL
78 }
79#endif
80}; 57};
58#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
81 59
82 60
83/** 61/**
@@ -112,7 +90,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte)
112 * au_read_byte16 - read one byte endianess aware from the chip 90 * au_read_byte16 - read one byte endianess aware from the chip
113 * @mtd: MTD device structure 91 * @mtd: MTD device structure
114 * 92 *
115 * read function for 16bit buswith with 93 * read function for 16bit buswith with
116 * endianess conversion 94 * endianess conversion
117 */ 95 */
118static u_char au_read_byte16(struct mtd_info *mtd) 96static u_char au_read_byte16(struct mtd_info *mtd)
@@ -142,7 +120,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte)
142 * au_read_word - read one word from the chip 120 * au_read_word - read one word from the chip
143 * @mtd: MTD device structure 121 * @mtd: MTD device structure
144 * 122 *
145 * read function for 16bit buswith without 123 * read function for 16bit buswith without
146 * endianess conversion 124 * endianess conversion
147 */ 125 */
148static u16 au_read_word(struct mtd_info *mtd) 126static u16 au_read_word(struct mtd_info *mtd)
@@ -158,7 +136,7 @@ static u16 au_read_word(struct mtd_info *mtd)
158 * @mtd: MTD device structure 136 * @mtd: MTD device structure
159 * @word: data word to write 137 * @word: data word to write
160 * 138 *
161 * write function for 16bit buswith without 139 * write function for 16bit buswith without
162 * endianess conversion 140 * endianess conversion
163 */ 141 */
164static void au_write_word(struct mtd_info *mtd, u16 word) 142static void au_write_word(struct mtd_info *mtd, u16 word)
@@ -188,7 +166,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
188} 166}
189 167
190/** 168/**
191 * au_read_buf - read chip data into buffer 169 * au_read_buf - read chip data into buffer
192 * @mtd: MTD device structure 170 * @mtd: MTD device structure
193 * @buf: buffer to store date 171 * @buf: buffer to store date
194 * @len: number of bytes to read 172 * @len: number of bytes to read
@@ -202,12 +180,12 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
202 180
203 for (i=0; i<len; i++) { 181 for (i=0; i<len; i++) {
204 buf[i] = readb(this->IO_ADDR_R); 182 buf[i] = readb(this->IO_ADDR_R);
205 au_sync(); 183 au_sync();
206 } 184 }
207} 185}
208 186
209/** 187/**
210 * au_verify_buf - Verify chip data against buffer 188 * au_verify_buf - Verify chip data against buffer
211 * @mtd: MTD device structure 189 * @mtd: MTD device structure
212 * @buf: buffer containing the data to compare 190 * @buf: buffer containing the data to compare
213 * @len: number of bytes to compare 191 * @len: number of bytes to compare
@@ -242,16 +220,16 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
242 struct nand_chip *this = mtd->priv; 220 struct nand_chip *this = mtd->priv;
243 u16 *p = (u16 *) buf; 221 u16 *p = (u16 *) buf;
244 len >>= 1; 222 len >>= 1;
245 223
246 for (i=0; i<len; i++) { 224 for (i=0; i<len; i++) {
247 writew(p[i], this->IO_ADDR_W); 225 writew(p[i], this->IO_ADDR_W);
248 au_sync(); 226 au_sync();
249 } 227 }
250 228
251} 229}
252 230
253/** 231/**
254 * au_read_buf16 - read chip data into buffer 232 * au_read_buf16 - read chip data into buffer
255 * @mtd: MTD device structure 233 * @mtd: MTD device structure
256 * @buf: buffer to store date 234 * @buf: buffer to store date
257 * @len: number of bytes to read 235 * @len: number of bytes to read
@@ -272,7 +250,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
272} 250}
273 251
274/** 252/**
275 * au_verify_buf16 - Verify chip data against buffer 253 * au_verify_buf16 - Verify chip data against buffer
276 * @mtd: MTD device structure 254 * @mtd: MTD device structure
277 * @buf: buffer containing the data to compare 255 * @buf: buffer containing the data to compare
278 * @len: number of bytes to compare 256 * @len: number of bytes to compare
@@ -305,26 +283,26 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
305 case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break; 283 case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break;
306 284
307 case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break; 285 case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
308 case NAND_CTL_CLRALE: 286 case NAND_CTL_CLRALE:
309 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; 287 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
310 /* FIXME: Nobody knows why this is neccecary, 288 /* FIXME: Nobody knows why this is neccecary,
311 * but it works only that way */ 289 * but it works only that way */
312 udelay(1); 290 udelay(1);
313 break; 291 break;
314 292
315 case NAND_CTL_SETNCE: 293 case NAND_CTL_SETNCE:
316 /* assert (force assert) chip enable */ 294 /* assert (force assert) chip enable */
317 au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break; 295 au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break;
318 break; 296 break;
319 297
320 case NAND_CTL_CLRNCE: 298 case NAND_CTL_CLRNCE:
321 /* deassert chip enable */ 299 /* deassert chip enable */
322 au_writel(0, MEM_STNDCTL); break; 300 au_writel(0, MEM_STNDCTL); break;
323 break; 301 break;
324 } 302 }
325 303
326 this->IO_ADDR_R = this->IO_ADDR_W; 304 this->IO_ADDR_R = this->IO_ADDR_W;
327 305
328 /* Drain the writebuffer */ 306 /* Drain the writebuffer */
329 au_sync(); 307 au_sync();
330} 308}
@@ -339,14 +317,16 @@ int au1550_device_ready(struct mtd_info *mtd)
339/* 317/*
340 * Main initialization routine 318 * Main initialization routine
341 */ 319 */
342int __init au1550_init (void) 320int __init au1xxx_nand_init (void)
343{ 321{
344 struct nand_chip *this; 322 struct nand_chip *this;
345 u16 boot_swapboot = 0; /* default value */ 323 u16 boot_swapboot = 0; /* default value */
346 int retval; 324 int retval;
325 u32 mem_staddr;
326 u32 nand_phys;
347 327
348 /* Allocate memory for MTD device structure and private data */ 328 /* Allocate memory for MTD device structure and private data */
349 au1550_mtd = kmalloc (sizeof(struct mtd_info) + 329 au1550_mtd = kmalloc (sizeof(struct mtd_info) +
350 sizeof (struct nand_chip), GFP_KERNEL); 330 sizeof (struct nand_chip), GFP_KERNEL);
351 if (!au1550_mtd) { 331 if (!au1550_mtd) {
352 printk ("Unable to allocate NAND MTD dev structure.\n"); 332 printk ("Unable to allocate NAND MTD dev structure.\n");
@@ -364,14 +344,17 @@ int __init au1550_init (void)
364 au1550_mtd->priv = this; 344 au1550_mtd->priv = this;
365 345
366 346
367 /* MEM_STNDCTL: disable ints, disable nand boot */ 347 /* disable interrupts */
368 au_writel(0, MEM_STNDCTL); 348 au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL);
349
350 /* disable NAND boot */
351 au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
369 352
370#ifdef CONFIG_MIPS_PB1550 353#ifdef CONFIG_MIPS_PB1550
371 /* set gpio206 high */ 354 /* set gpio206 high */
372 au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR); 355 au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR);
373 356
374 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | 357 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
375 ((bcsr->status >> 6) & 0x1); 358 ((bcsr->status >> 6) & 0x1);
376 switch (boot_swapboot) { 359 switch (boot_swapboot) {
377 case 0: 360 case 0:
@@ -397,25 +380,66 @@ int __init au1550_init (void)
397 } 380 }
398#endif 381#endif
399 382
400 /* Configure RCE1 - should be done by YAMON */ 383 /* Configure chip-select; normally done by boot code, e.g. YAMON */
401 au_writel(0x5 | (nand_width << 22), 0xB4001010); /* MEM_STCFG1 */ 384#ifdef NAND_STCFG
402 au_writel(NAND_TIMING, 0xB4001014); /* MEM_STTIME1 */ 385 if (NAND_CS == 0) {
403 au_sync(); 386 au_writel(NAND_STCFG, MEM_STCFG0);
387 au_writel(NAND_STTIME, MEM_STTIME0);
388 au_writel(NAND_STADDR, MEM_STADDR0);
389 }
390 if (NAND_CS == 1) {
391 au_writel(NAND_STCFG, MEM_STCFG1);
392 au_writel(NAND_STTIME, MEM_STTIME1);
393 au_writel(NAND_STADDR, MEM_STADDR1);
394 }
395 if (NAND_CS == 2) {
396 au_writel(NAND_STCFG, MEM_STCFG2);
397 au_writel(NAND_STTIME, MEM_STTIME2);
398 au_writel(NAND_STADDR, MEM_STADDR2);
399 }
400 if (NAND_CS == 3) {
401 au_writel(NAND_STCFG, MEM_STCFG3);
402 au_writel(NAND_STTIME, MEM_STTIME3);
403 au_writel(NAND_STADDR, MEM_STADDR3);
404 }
405#endif
404 406
405 /* setup and enable chip select, MEM_STADDR1 */ 407 /* Locate NAND chip-select in order to determine NAND phys address */
406 /* we really need to decode offsets only up till 0x20 */ 408 mem_staddr = 0x00000000;
407 au_writel((1<<28) | (NAND_PHYS_ADDR>>4) | 409 if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0))
408 (((NAND_PHYS_ADDR + 0x1000)-1) & (0x3fff<<18)>>18), 410 mem_staddr = au_readl(MEM_STADDR0);
409 MEM_STADDR1); 411 else if (((au_readl(MEM_STCFG1) & 0x7) == 0x5) && (NAND_CS == 1))
410 au_sync(); 412 mem_staddr = au_readl(MEM_STADDR1);
413 else if (((au_readl(MEM_STCFG2) & 0x7) == 0x5) && (NAND_CS == 2))
414 mem_staddr = au_readl(MEM_STADDR2);
415 else if (((au_readl(MEM_STCFG3) & 0x7) == 0x5) && (NAND_CS == 3))
416 mem_staddr = au_readl(MEM_STADDR3);
417
418 if (mem_staddr == 0x00000000) {
419 printk("Au1xxx NAND: ERROR WITH NAND CHIP-SELECT\n");
420 kfree(au1550_mtd);
421 return 1;
422 }
423 nand_phys = (mem_staddr << 4) & 0xFFFC0000;
424
425 p_nand = (void __iomem *)ioremap(nand_phys, 0x1000);
426
427 /* make controller and MTD agree */
428 if (NAND_CS == 0)
429 nand_width = au_readl(MEM_STCFG0) & (1<<22);
430 if (NAND_CS == 1)
431 nand_width = au_readl(MEM_STCFG1) & (1<<22);
432 if (NAND_CS == 2)
433 nand_width = au_readl(MEM_STCFG2) & (1<<22);
434 if (NAND_CS == 3)
435 nand_width = au_readl(MEM_STCFG3) & (1<<22);
411 436
412 p_nand = ioremap(NAND_PHYS_ADDR, 0x1000);
413 437
414 /* Set address of hardware control function */ 438 /* Set address of hardware control function */
415 this->hwcontrol = au1550_hwcontrol; 439 this->hwcontrol = au1550_hwcontrol;
416 this->dev_ready = au1550_device_ready; 440 this->dev_ready = au1550_device_ready;
417 /* 30 us command delay time */ 441 /* 30 us command delay time */
418 this->chip_delay = 30; 442 this->chip_delay = 30;
419 this->eccmode = NAND_ECC_SOFT; 443 this->eccmode = NAND_ECC_SOFT;
420 444
421 this->options = NAND_NO_AUTOINCR; 445 this->options = NAND_NO_AUTOINCR;
@@ -438,19 +462,19 @@ int __init au1550_init (void)
438 } 462 }
439 463
440 /* Register the partitions */ 464 /* Register the partitions */
441 add_mtd_partitions(au1550_mtd, partition_info, NUM_PARTITIONS); 465 add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info));
442 466
443 return 0; 467 return 0;
444 468
445 outio: 469 outio:
446 iounmap ((void *)p_nand); 470 iounmap ((void *)p_nand);
447 471
448 outmem: 472 outmem:
449 kfree (au1550_mtd); 473 kfree (au1550_mtd);
450 return retval; 474 return retval;
451} 475}
452 476
453module_init(au1550_init); 477module_init(au1xxx_nand_init);
454 478
455/* 479/*
456 * Clean up routine 480 * Clean up routine
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 4afa8ced05ad..a3c7fea404d0 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -5,8 +5,8 @@
5 * 5 *
6 * Derived from drivers/mtd/spia.c 6 * Derived from drivers/mtd/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 * 8 *
9 * $Id: autcpu12.c,v 1.22 2004/11/04 12:53:10 gleixner Exp $ 9 * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -14,7 +14,7 @@
14 * 14 *
15 * Overview: 15 * Overview:
16 * This is a device driver for the NAND flash device found on the 16 * This is a device driver for the NAND flash device found on the
17 * autronix autcpu12 board, which is a SmartMediaCard. It supports 17 * autronix autcpu12 board, which is a SmartMediaCard. It supports
18 * 16MiB, 32MiB and 64MiB cards. 18 * 16MiB, 32MiB and 64MiB cards.
19 * 19 *
20 * 20 *
@@ -27,7 +27,6 @@
27 * 10-06-2002 TG 128K card support added 27 * 10-06-2002 TG 128K card support added
28 */ 28 */
29 29
30#include <linux/version.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/module.h> 32#include <linux/module.h>
@@ -93,7 +92,7 @@ static struct mtd_partition partition_info128k[] = {
93#define NUM_PARTITIONS32K 2 92#define NUM_PARTITIONS32K 2
94#define NUM_PARTITIONS64K 2 93#define NUM_PARTITIONS64K 2
95#define NUM_PARTITIONS128K 2 94#define NUM_PARTITIONS128K 2
96/* 95/*
97 * hardware specific access to control-lines 96 * hardware specific access to control-lines
98*/ 97*/
99static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) 98static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
@@ -163,7 +162,7 @@ int __init autcpu12_init (void)
163 this->hwcontrol = autcpu12_hwcontrol; 162 this->hwcontrol = autcpu12_hwcontrol;
164 this->dev_ready = autcpu12_device_ready; 163 this->dev_ready = autcpu12_device_ready;
165 /* 20 us command delay time */ 164 /* 20 us command delay time */
166 this->chip_delay = 20; 165 this->chip_delay = 20;
167 this->eccmode = NAND_ECC_SOFT; 166 this->eccmode = NAND_ECC_SOFT;
168 167
169 /* Enable the following for a flash based bad block table */ 168 /* Enable the following for a flash based bad block table */
@@ -171,21 +170,21 @@ int __init autcpu12_init (void)
171 this->options = NAND_USE_FLASH_BBT; 170 this->options = NAND_USE_FLASH_BBT;
172 */ 171 */
173 this->options = NAND_USE_FLASH_BBT; 172 this->options = NAND_USE_FLASH_BBT;
174 173
175 /* Scan to find existance of the device */ 174 /* Scan to find existance of the device */
176 if (nand_scan (autcpu12_mtd, 1)) { 175 if (nand_scan (autcpu12_mtd, 1)) {
177 err = -ENXIO; 176 err = -ENXIO;
178 goto out_ior; 177 goto out_ior;
179 } 178 }
180 179
181 /* Register the partitions */ 180 /* Register the partitions */
182 switch(autcpu12_mtd->size){ 181 switch(autcpu12_mtd->size){
183 case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; 182 case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break;
184 case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; 183 case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break;
185 case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; 184 case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break;
186 case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; 185 case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break;
187 default: { 186 default: {
188 printk ("Unsupported SmartMedia device\n"); 187 printk ("Unsupported SmartMedia device\n");
189 err = -ENXIO; 188 err = -ENXIO;
190 goto out_ior; 189 goto out_ior;
191 } 190 }
@@ -213,7 +212,7 @@ static void __exit autcpu12_cleanup (void)
213 212
214 /* unmap physical adress */ 213 /* unmap physical adress */
215 iounmap((void *)autcpu12_fio_base); 214 iounmap((void *)autcpu12_fio_base);
216 215
217 /* Free the MTD device structure */ 216 /* Free the MTD device structure */
218 kfree (autcpu12_mtd); 217 kfree (autcpu12_mtd);
219} 218}
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index fdb5d4ad3d52..21d4e8f4b7af 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * drivers/mtd/nand/diskonchip.c 2 * drivers/mtd/nand/diskonchip.c
3 * 3 *
4 * (C) 2003 Red Hat, Inc. 4 * (C) 2003 Red Hat, Inc.
@@ -8,15 +8,15 @@
8 * Author: David Woodhouse <dwmw2@infradead.org> 8 * Author: David Woodhouse <dwmw2@infradead.org>
9 * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org> 9 * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
10 * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee> 10 * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
11 * 11 *
12 * Error correction code lifted from the old docecc code 12 * Error correction code lifted from the old docecc code
13 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 13 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
14 * Copyright (C) 2000 Netgem S.A. 14 * Copyright (C) 2000 Netgem S.A.
15 * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de> 15 * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de>
16 * 16 *
17 * Interface to generic NAND code for M-Systems DiskOnChip devices 17 * Interface to generic NAND code for M-Systems DiskOnChip devices
18 * 18 *
19 * $Id: diskonchip.c,v 1.54 2005/04/07 14:22:55 dbrown Exp $ 19 * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $
20 */ 20 */
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
@@ -42,16 +42,16 @@
42static unsigned long __initdata doc_locations[] = { 42static unsigned long __initdata doc_locations[] = {
43#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) 43#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
44#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH 44#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
45 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 45 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
46 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, 46 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
47 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 47 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
48 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 48 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
49 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, 49 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
50#else /* CONFIG_MTD_DOCPROBE_HIGH */ 50#else /* CONFIG_MTD_DOCPROBE_HIGH */
51 0xc8000, 0xca000, 0xcc000, 0xce000, 51 0xc8000, 0xca000, 0xcc000, 0xce000,
52 0xd0000, 0xd2000, 0xd4000, 0xd6000, 52 0xd0000, 0xd2000, 0xd4000, 0xd6000,
53 0xd8000, 0xda000, 0xdc000, 0xde000, 53 0xd8000, 0xda000, 0xdc000, 0xde000,
54 0xe0000, 0xe2000, 0xe4000, 0xe6000, 54 0xe0000, 0xe2000, 0xe4000, 0xe6000,
55 0xe8000, 0xea000, 0xec000, 0xee000, 55 0xe8000, 0xea000, 0xec000, 0xee000,
56#endif /* CONFIG_MTD_DOCPROBE_HIGH */ 56#endif /* CONFIG_MTD_DOCPROBE_HIGH */
57#elif defined(__PPC__) 57#elif defined(__PPC__)
@@ -138,7 +138,7 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
138/* the Reed Solomon control structure */ 138/* the Reed Solomon control structure */
139static struct rs_control *rs_decoder; 139static struct rs_control *rs_decoder;
140 140
141/* 141/*
142 * The HW decoder in the DoC ASIC's provides us a error syndrome, 142 * The HW decoder in the DoC ASIC's provides us a error syndrome,
143 * which we must convert to a standard syndrom usable by the generic 143 * which we must convert to a standard syndrom usable by the generic
144 * Reed-Solomon library code. 144 * Reed-Solomon library code.
@@ -163,8 +163,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
163 /* Initialize the syndrom buffer */ 163 /* Initialize the syndrom buffer */
164 for (i = 0; i < NROOTS; i++) 164 for (i = 0; i < NROOTS; i++)
165 s[i] = ds[0]; 165 s[i] = ds[0];
166 /* 166 /*
167 * Evaluate 167 * Evaluate
168 * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] 168 * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
169 * where x = alpha^(FCR + i) 169 * where x = alpha^(FCR + i)
170 */ 170 */
@@ -188,7 +188,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
188 if (nerr < 0) 188 if (nerr < 0)
189 return nerr; 189 return nerr;
190 190
191 /* 191 /*
192 * Correct the errors. The bitpositions are a bit of magic, 192 * Correct the errors. The bitpositions are a bit of magic,
193 * but they are given by the design of the de/encoder circuit 193 * but they are given by the design of the de/encoder circuit
194 * in the DoC ASIC's. 194 * in the DoC ASIC's.
@@ -205,7 +205,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
205 can be modified since pos is even */ 205 can be modified since pos is even */
206 index = (pos >> 3) ^ 1; 206 index = (pos >> 3) ^ 1;
207 bitpos = pos & 7; 207 bitpos = pos & 7;
208 if ((index >= 0 && index < SECTOR_SIZE) || 208 if ((index >= 0 && index < SECTOR_SIZE) ||
209 index == (SECTOR_SIZE + 1)) { 209 index == (SECTOR_SIZE + 1)) {
210 val = (uint8_t) (errval[i] >> (2 + bitpos)); 210 val = (uint8_t) (errval[i] >> (2 + bitpos));
211 parity ^= val; 211 parity ^= val;
@@ -216,7 +216,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
216 bitpos = (bitpos + 10) & 7; 216 bitpos = (bitpos + 10) & 7;
217 if (bitpos == 0) 217 if (bitpos == 0)
218 bitpos = 8; 218 bitpos = 8;
219 if ((index >= 0 && index < SECTOR_SIZE) || 219 if ((index >= 0 && index < SECTOR_SIZE) ||
220 index == (SECTOR_SIZE + 1)) { 220 index == (SECTOR_SIZE + 1)) {
221 val = (uint8_t)(errval[i] << (8 - bitpos)); 221 val = (uint8_t)(errval[i] << (8 - bitpos));
222 parity ^= val; 222 parity ^= val;
@@ -233,7 +233,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
233{ 233{
234 volatile char dummy; 234 volatile char dummy;
235 int i; 235 int i;
236 236
237 for (i = 0; i < cycles; i++) { 237 for (i = 0; i < cycles; i++) {
238 if (DoC_is_Millennium(doc)) 238 if (DoC_is_Millennium(doc))
239 dummy = ReadDOC(doc->virtadr, NOP); 239 dummy = ReadDOC(doc->virtadr, NOP);
@@ -242,7 +242,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
242 else 242 else
243 dummy = ReadDOC(doc->virtadr, DOCStatus); 243 dummy = ReadDOC(doc->virtadr, DOCStatus);
244 } 244 }
245 245
246} 246}
247 247
248#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) 248#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
@@ -327,7 +327,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)
327 return ret; 327 return ret;
328} 328}
329 329
330static void doc2000_writebuf(struct mtd_info *mtd, 330static void doc2000_writebuf(struct mtd_info *mtd,
331 const u_char *buf, int len) 331 const u_char *buf, int len)
332{ 332{
333 struct nand_chip *this = mtd->priv; 333 struct nand_chip *this = mtd->priv;
@@ -343,7 +343,7 @@ static void doc2000_writebuf(struct mtd_info *mtd,
343 if (debug) printk("\n"); 343 if (debug) printk("\n");
344} 344}
345 345
346static void doc2000_readbuf(struct mtd_info *mtd, 346static void doc2000_readbuf(struct mtd_info *mtd,
347 u_char *buf, int len) 347 u_char *buf, int len)
348{ 348{
349 struct nand_chip *this = mtd->priv; 349 struct nand_chip *this = mtd->priv;
@@ -358,7 +358,7 @@ static void doc2000_readbuf(struct mtd_info *mtd,
358 } 358 }
359} 359}
360 360
361static void doc2000_readbuf_dword(struct mtd_info *mtd, 361static void doc2000_readbuf_dword(struct mtd_info *mtd,
362 u_char *buf, int len) 362 u_char *buf, int len)
363{ 363{
364 struct nand_chip *this = mtd->priv; 364 struct nand_chip *this = mtd->priv;
@@ -379,7 +379,7 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd,
379 } 379 }
380} 380}
381 381
382static int doc2000_verifybuf(struct mtd_info *mtd, 382static int doc2000_verifybuf(struct mtd_info *mtd,
383 const u_char *buf, int len) 383 const u_char *buf, int len)
384{ 384{
385 struct nand_chip *this = mtd->priv; 385 struct nand_chip *this = mtd->priv;
@@ -406,12 +406,12 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
406 doc200x_hwcontrol(mtd, NAND_CTL_SETALE); 406 doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
407 this->write_byte(mtd, 0); 407 this->write_byte(mtd, 0);
408 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); 408 doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
409 409
410 /* We cant' use dev_ready here, but at least we wait for the 410 /* We cant' use dev_ready here, but at least we wait for the
411 * command to complete 411 * command to complete
412 */ 412 */
413 udelay(50); 413 udelay(50);
414 414
415 ret = this->read_byte(mtd) << 8; 415 ret = this->read_byte(mtd) << 8;
416 ret |= this->read_byte(mtd); 416 ret |= this->read_byte(mtd);
417 417
@@ -438,7 +438,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
438 this->read_buf = &doc2000_readbuf_dword; 438 this->read_buf = &doc2000_readbuf_dword;
439 } 439 }
440 } 440 }
441 441
442 return ret; 442 return ret;
443} 443}
444 444
@@ -469,7 +469,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
469 struct doc_priv *doc = this->priv; 469 struct doc_priv *doc = this->priv;
470 470
471 int status; 471 int status;
472 472
473 DoC_WaitReady(doc); 473 DoC_WaitReady(doc);
474 this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); 474 this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
475 DoC_WaitReady(doc); 475 DoC_WaitReady(doc);
@@ -503,7 +503,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
503 return ReadDOC(docptr, LastDataRead); 503 return ReadDOC(docptr, LastDataRead);
504} 504}
505 505
506static void doc2001_writebuf(struct mtd_info *mtd, 506static void doc2001_writebuf(struct mtd_info *mtd,
507 const u_char *buf, int len) 507 const u_char *buf, int len)
508{ 508{
509 struct nand_chip *this = mtd->priv; 509 struct nand_chip *this = mtd->priv;
@@ -517,7 +517,7 @@ static void doc2001_writebuf(struct mtd_info *mtd,
517 WriteDOC(0x00, docptr, WritePipeTerm); 517 WriteDOC(0x00, docptr, WritePipeTerm);
518} 518}
519 519
520static void doc2001_readbuf(struct mtd_info *mtd, 520static void doc2001_readbuf(struct mtd_info *mtd,
521 u_char *buf, int len) 521 u_char *buf, int len)
522{ 522{
523 struct nand_chip *this = mtd->priv; 523 struct nand_chip *this = mtd->priv;
@@ -535,7 +535,7 @@ static void doc2001_readbuf(struct mtd_info *mtd,
535 buf[i] = ReadDOC(docptr, LastDataRead); 535 buf[i] = ReadDOC(docptr, LastDataRead);
536} 536}
537 537
538static int doc2001_verifybuf(struct mtd_info *mtd, 538static int doc2001_verifybuf(struct mtd_info *mtd,
539 const u_char *buf, int len) 539 const u_char *buf, int len)
540{ 540{
541 struct nand_chip *this = mtd->priv; 541 struct nand_chip *this = mtd->priv;
@@ -570,7 +570,7 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)
570 return ret; 570 return ret;
571} 571}
572 572
573static void doc2001plus_writebuf(struct mtd_info *mtd, 573static void doc2001plus_writebuf(struct mtd_info *mtd,
574 const u_char *buf, int len) 574 const u_char *buf, int len)
575{ 575{
576 struct nand_chip *this = mtd->priv; 576 struct nand_chip *this = mtd->priv;
@@ -587,7 +587,7 @@ static void doc2001plus_writebuf(struct mtd_info *mtd,
587 if (debug) printk("\n"); 587 if (debug) printk("\n");
588} 588}
589 589
590static void doc2001plus_readbuf(struct mtd_info *mtd, 590static void doc2001plus_readbuf(struct mtd_info *mtd,
591 u_char *buf, int len) 591 u_char *buf, int len)
592{ 592{
593 struct nand_chip *this = mtd->priv; 593 struct nand_chip *this = mtd->priv;
@@ -617,7 +617,7 @@ static void doc2001plus_readbuf(struct mtd_info *mtd,
617 if (debug) printk("\n"); 617 if (debug) printk("\n");
618} 618}
619 619
620static int doc2001plus_verifybuf(struct mtd_info *mtd, 620static int doc2001plus_verifybuf(struct mtd_info *mtd,
621 const u_char *buf, int len) 621 const u_char *buf, int len)
622{ 622{
623 struct nand_chip *this = mtd->priv; 623 struct nand_chip *this = mtd->priv;
@@ -797,7 +797,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
797 WriteDOC(0, docptr, Mplus_FlashControl); 797 WriteDOC(0, docptr, Mplus_FlashControl);
798 } 798 }
799 799
800 /* 800 /*
801 * program and erase have their own busy handlers 801 * program and erase have their own busy handlers
802 * status and sequential in needs no delay 802 * status and sequential in needs no delay
803 */ 803 */
@@ -822,7 +822,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
822 822
823 /* This applies to read commands */ 823 /* This applies to read commands */
824 default: 824 default:
825 /* 825 /*
826 * If we don't have access to the busy pin, we apply the given 826 * If we don't have access to the busy pin, we apply the given
827 * command delay 827 * command delay
828 */ 828 */
@@ -945,7 +945,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
945 for (i = 0; i < 6; i++) { 945 for (i = 0; i < 6; i++) {
946 if (DoC_is_MillenniumPlus(doc)) 946 if (DoC_is_MillenniumPlus(doc))
947 ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); 947 ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
948 else 948 else
949 ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); 949 ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
950 if (ecc_code[i] != empty_write_ecc[i]) 950 if (ecc_code[i] != empty_write_ecc[i])
951 emptymatch = 0; 951 emptymatch = 0;
@@ -982,7 +982,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
982 void __iomem *docptr = doc->virtadr; 982 void __iomem *docptr = doc->virtadr;
983 volatile u_char dummy; 983 volatile u_char dummy;
984 int emptymatch = 1; 984 int emptymatch = 1;
985 985
986 /* flush the pipeline */ 986 /* flush the pipeline */
987 if (DoC_is_2000(doc)) { 987 if (DoC_is_2000(doc)) {
988 dummy = ReadDOC(docptr, 2k_ECCStatus); 988 dummy = ReadDOC(docptr, 2k_ECCStatus);
@@ -997,7 +997,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
997 dummy = ReadDOC(docptr, ECCConf); 997 dummy = ReadDOC(docptr, ECCConf);
998 dummy = ReadDOC(docptr, ECCConf); 998 dummy = ReadDOC(docptr, ECCConf);
999 } 999 }
1000 1000
1001 /* Error occured ? */ 1001 /* Error occured ? */
1002 if (dummy & 0x80) { 1002 if (dummy & 0x80) {
1003 for (i = 0; i < 6; i++) { 1003 for (i = 0; i < 6; i++) {
@@ -1035,7 +1035,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1035 if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); 1035 if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);
1036 if (ret > 0) 1036 if (ret > 0)
1037 printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); 1037 printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
1038 } 1038 }
1039 if (DoC_is_MillenniumPlus(doc)) 1039 if (DoC_is_MillenniumPlus(doc))
1040 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); 1040 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
1041 else 1041 else
@@ -1046,7 +1046,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
1046 } 1046 }
1047 return ret; 1047 return ret;
1048} 1048}
1049 1049
1050//u_char mydatabuf[528]; 1050//u_char mydatabuf[528];
1051 1051
1052/* The strange out-of-order .oobfree list below is a (possibly unneeded) 1052/* The strange out-of-order .oobfree list below is a (possibly unneeded)
@@ -1065,7 +1065,7 @@ static struct nand_oobinfo doc200x_oobinfo = {
1065 .eccpos = {0, 1, 2, 3, 4, 5}, 1065 .eccpos = {0, 1, 2, 3, 4, 5},
1066 .oobfree = { {8, 8}, {6, 2} } 1066 .oobfree = { {8, 8}, {6, 2} }
1067}; 1067};
1068 1068
1069/* Find the (I)NFTL Media Header, and optionally also the mirror media header. 1069/* Find the (I)NFTL Media Header, and optionally also the mirror media header.
1070 On sucessful return, buf will contain a copy of the media header for 1070 On sucessful return, buf will contain a copy of the media header for
1071 further processing. id is the string to scan for, and will presumably be 1071 further processing. id is the string to scan for, and will presumably be
@@ -1251,7 +1251,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
1251 mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits); 1251 mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
1252 mh->FormatFlags = le32_to_cpu(mh->FormatFlags); 1252 mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
1253 mh->PercentUsed = le32_to_cpu(mh->PercentUsed); 1253 mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
1254 1254
1255 printk(KERN_INFO " bootRecordID = %s\n" 1255 printk(KERN_INFO " bootRecordID = %s\n"
1256 " NoOfBootImageBlocks = %d\n" 1256 " NoOfBootImageBlocks = %d\n"
1257 " NoOfBinaryPartitions = %d\n" 1257 " NoOfBinaryPartitions = %d\n"
@@ -1468,7 +1468,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
1468 ReadDOC(doc->virtadr, ChipID); 1468 ReadDOC(doc->virtadr, ChipID);
1469 if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) { 1469 if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) {
1470 /* It's not a Millennium; it's one of the newer 1470 /* It's not a Millennium; it's one of the newer
1471 DiskOnChip 2000 units with a similar ASIC. 1471 DiskOnChip 2000 units with a similar ASIC.
1472 Treat it like a Millennium, except that it 1472 Treat it like a Millennium, except that it
1473 can have multiple chips. */ 1473 can have multiple chips. */
1474 doc2000_count_chips(mtd); 1474 doc2000_count_chips(mtd);
@@ -1530,20 +1530,20 @@ static inline int __init doc_probe(unsigned long physadr)
1530 * to the DOCControl register. So we store the current contents 1530 * to the DOCControl register. So we store the current contents
1531 * of the DOCControl register's location, in case we later decide 1531 * of the DOCControl register's location, in case we later decide
1532 * that it's not a DiskOnChip, and want to put it back how we 1532 * that it's not a DiskOnChip, and want to put it back how we
1533 * found it. 1533 * found it.
1534 */ 1534 */
1535 save_control = ReadDOC(virtadr, DOCControl); 1535 save_control = ReadDOC(virtadr, DOCControl);
1536 1536
1537 /* Reset the DiskOnChip ASIC */ 1537 /* Reset the DiskOnChip ASIC */
1538 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 1538 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1539 virtadr, DOCControl); 1539 virtadr, DOCControl);
1540 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, 1540 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
1541 virtadr, DOCControl); 1541 virtadr, DOCControl);
1542 1542
1543 /* Enable the DiskOnChip ASIC */ 1543 /* Enable the DiskOnChip ASIC */
1544 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 1544 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1545 virtadr, DOCControl); 1545 virtadr, DOCControl);
1546 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, 1546 WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
1547 virtadr, DOCControl); 1547 virtadr, DOCControl);
1548 1548
1549 ChipID = ReadDOC(virtadr, ChipID); 1549 ChipID = ReadDOC(virtadr, ChipID);
@@ -1738,7 +1738,7 @@ static int __init init_nanddoc(void)
1738 int i, ret = 0; 1738 int i, ret = 0;
1739 1739
1740 /* We could create the decoder on demand, if memory is a concern. 1740 /* We could create the decoder on demand, if memory is a concern.
1741 * This way we have it handy, if an error happens 1741 * This way we have it handy, if an error happens
1742 * 1742 *
1743 * Symbolsize is 10 (bits) 1743 * Symbolsize is 10 (bits)
1744 * Primitve polynomial is x^10+x^3+1 1744 * Primitve polynomial is x^10+x^3+1
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c
index 5549681ccdce..9b1fd2f387fa 100644
--- a/drivers/mtd/nand/edb7312.c
+++ b/drivers/mtd/nand/edb7312.c
@@ -6,7 +6,7 @@
6 * Derived from drivers/mtd/nand/autcpu12.c 6 * Derived from drivers/mtd/nand/autcpu12.c
7 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) 7 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
8 * 8 *
9 * $Id: edb7312.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $ 9 * $Id: edb7312.c,v 1.12 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -71,27 +71,27 @@ static struct mtd_partition partition_info[] = {
71#endif 71#endif
72 72
73 73
74/* 74/*
75 * hardware specific access to control-lines 75 * hardware specific access to control-lines
76 */ 76 */
77static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) 77static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
78{ 78{
79 switch(cmd) { 79 switch(cmd) {
80 80
81 case NAND_CTL_SETCLE: 81 case NAND_CTL_SETCLE:
82 clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr); 82 clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr);
83 break; 83 break;
84 case NAND_CTL_CLRCLE: 84 case NAND_CTL_CLRCLE:
85 clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr); 85 clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr);
86 break; 86 break;
87 87
88 case NAND_CTL_SETALE: 88 case NAND_CTL_SETALE:
89 clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr); 89 clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr);
90 break; 90 break;
91 case NAND_CTL_CLRALE: 91 case NAND_CTL_CLRALE:
92 clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr); 92 clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr);
93 break; 93 break;
94 94
95 case NAND_CTL_SETNCE: 95 case NAND_CTL_SETNCE:
96 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr); 96 clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr);
97 break; 97 break;
@@ -122,16 +122,16 @@ static int __init ep7312_init (void)
122 int mtd_parts_nb = 0; 122 int mtd_parts_nb = 0;
123 struct mtd_partition *mtd_parts = 0; 123 struct mtd_partition *mtd_parts = 0;
124 void __iomem * ep7312_fio_base; 124 void __iomem * ep7312_fio_base;
125 125
126 /* Allocate memory for MTD device structure and private data */ 126 /* Allocate memory for MTD device structure and private data */
127 ep7312_mtd = kmalloc(sizeof(struct mtd_info) + 127 ep7312_mtd = kmalloc(sizeof(struct mtd_info) +
128 sizeof(struct nand_chip), 128 sizeof(struct nand_chip),
129 GFP_KERNEL); 129 GFP_KERNEL);
130 if (!ep7312_mtd) { 130 if (!ep7312_mtd) {
131 printk("Unable to allocate EDB7312 NAND MTD device structure.\n"); 131 printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
132 return -ENOMEM; 132 return -ENOMEM;
133 } 133 }
134 134
135 /* map physical adress */ 135 /* map physical adress */
136 ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K); 136 ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
137 if(!ep7312_fio_base) { 137 if(!ep7312_fio_base) {
@@ -139,23 +139,23 @@ static int __init ep7312_init (void)
139 kfree(ep7312_mtd); 139 kfree(ep7312_mtd);
140 return -EIO; 140 return -EIO;
141 } 141 }
142 142
143 /* Get pointer to private data */ 143 /* Get pointer to private data */
144 this = (struct nand_chip *) (&ep7312_mtd[1]); 144 this = (struct nand_chip *) (&ep7312_mtd[1]);
145 145
146 /* Initialize structures */ 146 /* Initialize structures */
147 memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info)); 147 memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info));
148 memset((char *) this, 0, sizeof(struct nand_chip)); 148 memset((char *) this, 0, sizeof(struct nand_chip));
149 149
150 /* Link the private data with the MTD structure */ 150 /* Link the private data with the MTD structure */
151 ep7312_mtd->priv = this; 151 ep7312_mtd->priv = this;
152 152
153 /* 153 /*
154 * Set GPIO Port B control register so that the pins are configured 154 * Set GPIO Port B control register so that the pins are configured
155 * to be outputs for controlling the NAND flash. 155 * to be outputs for controlling the NAND flash.
156 */ 156 */
157 clps_writeb(0xf0, ep7312_pxddr); 157 clps_writeb(0xf0, ep7312_pxddr);
158 158
159 /* insert callbacks */ 159 /* insert callbacks */
160 this->IO_ADDR_R = ep7312_fio_base; 160 this->IO_ADDR_R = ep7312_fio_base;
161 this->IO_ADDR_W = ep7312_fio_base; 161 this->IO_ADDR_W = ep7312_fio_base;
@@ -163,14 +163,14 @@ static int __init ep7312_init (void)
163 this->dev_ready = ep7312_device_ready; 163 this->dev_ready = ep7312_device_ready;
164 /* 15 us command delay time */ 164 /* 15 us command delay time */
165 this->chip_delay = 15; 165 this->chip_delay = 15;
166 166
167 /* Scan to find existence of the device */ 167 /* Scan to find existence of the device */
168 if (nand_scan (ep7312_mtd, 1)) { 168 if (nand_scan (ep7312_mtd, 1)) {
169 iounmap((void *)ep7312_fio_base); 169 iounmap((void *)ep7312_fio_base);
170 kfree (ep7312_mtd); 170 kfree (ep7312_mtd);
171 return -ENXIO; 171 return -ENXIO;
172 } 172 }
173 173
174#ifdef CONFIG_MTD_PARTITIONS 174#ifdef CONFIG_MTD_PARTITIONS
175 ep7312_mtd->name = "edb7312-nand"; 175 ep7312_mtd->name = "edb7312-nand";
176 mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, 176 mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes,
@@ -185,11 +185,11 @@ static int __init ep7312_init (void)
185 mtd_parts_nb = NUM_PARTITIONS; 185 mtd_parts_nb = NUM_PARTITIONS;
186 part_type = "static"; 186 part_type = "static";
187 } 187 }
188 188
189 /* Register the partitions */ 189 /* Register the partitions */
190 printk(KERN_NOTICE "Using %s partition definition\n", part_type); 190 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
191 add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb); 191 add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb);
192 192
193 /* Return happy */ 193 /* Return happy */
194 return 0; 194 return 0;
195} 195}
@@ -201,13 +201,13 @@ module_init(ep7312_init);
201static void __exit ep7312_cleanup (void) 201static void __exit ep7312_cleanup (void)
202{ 202{
203 struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1]; 203 struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1];
204 204
205 /* Release resources, unregister device */ 205 /* Release resources, unregister device */
206 nand_release (ap7312_mtd); 206 nand_release (ap7312_mtd);
207 207
208 /* Free internal data buffer */ 208 /* Free internal data buffer */
209 kfree (this->data_buf); 209 kfree (this->data_buf);
210 210
211 /* Free the MTD device structure */ 211 /* Free the MTD device structure */
212 kfree (ep7312_mtd); 212 kfree (ep7312_mtd);
213} 213}
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
index 3825a7a0900c..041e4b3358fb 100644
--- a/drivers/mtd/nand/h1910.c
+++ b/drivers/mtd/nand/h1910.c
@@ -7,7 +7,7 @@
7 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) 7 * Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
8 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) 8 * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
9 * 9 *
10 * $Id: h1910.c,v 1.5 2004/11/04 12:53:10 gleixner Exp $ 10 * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as 13 * it under the terms of the GNU General Public License version 2 as
@@ -54,24 +54,24 @@ static struct mtd_partition partition_info[] = {
54#endif 54#endif
55 55
56 56
57/* 57/*
58 * hardware specific access to control-lines 58 * hardware specific access to control-lines
59 */ 59 */
60static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) 60static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
61{ 61{
62 struct nand_chip* this = (struct nand_chip *) (mtd->priv); 62 struct nand_chip* this = (struct nand_chip *) (mtd->priv);
63 63
64 switch(cmd) { 64 switch(cmd) {
65 65
66 case NAND_CTL_SETCLE: 66 case NAND_CTL_SETCLE:
67 this->IO_ADDR_R |= (1 << 2); 67 this->IO_ADDR_R |= (1 << 2);
68 this->IO_ADDR_W |= (1 << 2); 68 this->IO_ADDR_W |= (1 << 2);
69 break; 69 break;
70 case NAND_CTL_CLRCLE: 70 case NAND_CTL_CLRCLE:
71 this->IO_ADDR_R &= ~(1 << 2); 71 this->IO_ADDR_R &= ~(1 << 2);
72 this->IO_ADDR_W &= ~(1 << 2); 72 this->IO_ADDR_W &= ~(1 << 2);
73 break; 73 break;
74 74
75 case NAND_CTL_SETALE: 75 case NAND_CTL_SETALE:
76 this->IO_ADDR_R |= (1 << 3); 76 this->IO_ADDR_R |= (1 << 3);
77 this->IO_ADDR_W |= (1 << 3); 77 this->IO_ADDR_W |= (1 << 3);
@@ -80,7 +80,7 @@ static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
80 this->IO_ADDR_R &= ~(1 << 3); 80 this->IO_ADDR_R &= ~(1 << 3);
81 this->IO_ADDR_W &= ~(1 << 3); 81 this->IO_ADDR_W &= ~(1 << 3);
82 break; 82 break;
83 83
84 case NAND_CTL_SETNCE: 84 case NAND_CTL_SETNCE:
85 break; 85 break;
86 case NAND_CTL_CLRNCE: 86 case NAND_CTL_CLRNCE:
@@ -108,18 +108,18 @@ static int __init h1910_init (void)
108 int mtd_parts_nb = 0; 108 int mtd_parts_nb = 0;
109 struct mtd_partition *mtd_parts = 0; 109 struct mtd_partition *mtd_parts = 0;
110 void __iomem *nandaddr; 110 void __iomem *nandaddr;
111 111
112 if (!machine_is_h1900()) 112 if (!machine_is_h1900())
113 return -ENODEV; 113 return -ENODEV;
114 114
115 nandaddr = __ioremap(0x08000000, 0x1000, 0, 1); 115 nandaddr = __ioremap(0x08000000, 0x1000, 0, 1);
116 if (!nandaddr) { 116 if (!nandaddr) {
117 printk("Failed to ioremap nand flash.\n"); 117 printk("Failed to ioremap nand flash.\n");
118 return -ENOMEM; 118 return -ENOMEM;
119 } 119 }
120 120
121 /* Allocate memory for MTD device structure and private data */ 121 /* Allocate memory for MTD device structure and private data */
122 h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + 122 h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) +
123 sizeof(struct nand_chip), 123 sizeof(struct nand_chip),
124 GFP_KERNEL); 124 GFP_KERNEL);
125 if (!h1910_nand_mtd) { 125 if (!h1910_nand_mtd) {
@@ -127,22 +127,22 @@ static int __init h1910_init (void)
127 iounmap ((void *) nandaddr); 127 iounmap ((void *) nandaddr);
128 return -ENOMEM; 128 return -ENOMEM;
129 } 129 }
130 130
131 /* Get pointer to private data */ 131 /* Get pointer to private data */
132 this = (struct nand_chip *) (&h1910_nand_mtd[1]); 132 this = (struct nand_chip *) (&h1910_nand_mtd[1]);
133 133
134 /* Initialize structures */ 134 /* Initialize structures */
135 memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info)); 135 memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info));
136 memset((char *) this, 0, sizeof(struct nand_chip)); 136 memset((char *) this, 0, sizeof(struct nand_chip));
137 137
138 /* Link the private data with the MTD structure */ 138 /* Link the private data with the MTD structure */
139 h1910_nand_mtd->priv = this; 139 h1910_nand_mtd->priv = this;
140 140
141 /* 141 /*
142 * Enable VPEN 142 * Enable VPEN
143 */ 143 */
144 GPSR(37) = GPIO_bit(37); 144 GPSR(37) = GPIO_bit(37);
145 145
146 /* insert callbacks */ 146 /* insert callbacks */
147 this->IO_ADDR_R = nandaddr; 147 this->IO_ADDR_R = nandaddr;
148 this->IO_ADDR_W = nandaddr; 148 this->IO_ADDR_W = nandaddr;
@@ -152,7 +152,7 @@ static int __init h1910_init (void)
152 this->chip_delay = 50; 152 this->chip_delay = 50;
153 this->eccmode = NAND_ECC_SOFT; 153 this->eccmode = NAND_ECC_SOFT;
154 this->options = NAND_NO_AUTOINCR; 154 this->options = NAND_NO_AUTOINCR;
155 155
156 /* Scan to find existence of the device */ 156 /* Scan to find existence of the device */
157 if (nand_scan (h1910_nand_mtd, 1)) { 157 if (nand_scan (h1910_nand_mtd, 1)) {
158 printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); 158 printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
@@ -160,9 +160,9 @@ static int __init h1910_init (void)
160 iounmap ((void *) nandaddr); 160 iounmap ((void *) nandaddr);
161 return -ENXIO; 161 return -ENXIO;
162 } 162 }
163 163
164#ifdef CONFIG_MTD_CMDLINE_PARTS 164#ifdef CONFIG_MTD_CMDLINE_PARTS
165 mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, 165 mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts,
166 "h1910-nand"); 166 "h1910-nand");
167 if (mtd_parts_nb > 0) 167 if (mtd_parts_nb > 0)
168 part_type = "command line"; 168 part_type = "command line";
@@ -175,11 +175,11 @@ static int __init h1910_init (void)
175 mtd_parts_nb = NUM_PARTITIONS; 175 mtd_parts_nb = NUM_PARTITIONS;
176 part_type = "static"; 176 part_type = "static";
177 } 177 }
178 178
179 /* Register the partitions */ 179 /* Register the partitions */
180 printk(KERN_NOTICE "Using %s partition definition\n", part_type); 180 printk(KERN_NOTICE "Using %s partition definition\n", part_type);
181 add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb); 181 add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
182 182
183 /* Return happy */ 183 /* Return happy */
184 return 0; 184 return 0;
185} 185}
@@ -191,7 +191,7 @@ module_init(h1910_init);
191static void __exit h1910_cleanup (void) 191static void __exit h1910_cleanup (void)
192{ 192{
193 struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1]; 193 struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1];
194 194
195 /* Release resources, unregister device */ 195 /* Release resources, unregister device */
196 nand_release (h1910_nand_mtd); 196 nand_release (h1910_nand_mtd);
197 197
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 04e54318bc6a..5d222460b42a 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -5,14 +5,14 @@
5 * This is the generic MTD driver for NAND flash devices. It should be 5 * This is the generic MTD driver for NAND flash devices. It should be
6 * capable of working with almost all NAND chips currently available. 6 * capable of working with almost all NAND chips currently available.
7 * Basic support for AG-AND chips is provided. 7 * Basic support for AG-AND chips is provided.
8 * 8 *
9 * Additional technical information is available on 9 * Additional technical information is available on
10 * http://www.linux-mtd.infradead.org/tech/nand.html 10 * http://www.linux-mtd.infradead.org/tech/nand.html
11 * 11 *
12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 12 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
13 * 2002 Thomas Gleixner (tglx@linutronix.de) 13 * 2002 Thomas Gleixner (tglx@linutronix.de)
14 * 14 *
15 * 02-08-2004 tglx: support for strange chips, which cannot auto increment 15 * 02-08-2004 tglx: support for strange chips, which cannot auto increment
16 * pages on read / read_oob 16 * pages on read / read_oob
17 * 17 *
18 * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes 18 * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes
@@ -21,7 +21,7 @@
21 * Make reads over block boundaries work too 21 * Make reads over block boundaries work too
22 * 22 *
23 * 04-14-2004 tglx: first working version for 2k page size chips 23 * 04-14-2004 tglx: first working version for 2k page size chips
24 * 24 *
25 * 05-19-2004 tglx: Basic support for Renesas AG-AND chips 25 * 05-19-2004 tglx: Basic support for Renesas AG-AND chips
26 * 26 *
27 * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared 27 * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared
@@ -30,25 +30,27 @@
30 * 30 *
31 * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue. 31 * 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
32 * Basically, any block not rewritten may lose data when surrounding blocks 32 * Basically, any block not rewritten may lose data when surrounding blocks
33 * are rewritten many times. JFFS2 ensures this doesn't happen for blocks 33 * are rewritten many times. JFFS2 ensures this doesn't happen for blocks
34 * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they 34 * it uses, but the Bad Block Table(s) may not be rewritten. To ensure they
35 * do not lose data, force them to be rewritten when some of the surrounding 35 * do not lose data, force them to be rewritten when some of the surrounding
36 * blocks are erased. Rather than tracking a specific nearby block (which 36 * blocks are erased. Rather than tracking a specific nearby block (which
37 * could itself go bad), use a page address 'mask' to select several blocks 37 * could itself go bad), use a page address 'mask' to select several blocks
38 * in the same area, and rewrite the BBT when any of them are erased. 38 * in the same area, and rewrite the BBT when any of them are erased.
39 * 39 *
40 * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas 40 * 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
41 * AG-AND chips. If there was a sudden loss of power during an erase operation, 41 * AG-AND chips. If there was a sudden loss of power during an erase operation,
42 * a "device recovery" operation must be performed when power is restored 42 * a "device recovery" operation must be performed when power is restored
43 * to ensure correct operation. 43 * to ensure correct operation.
44 * 44 *
45 * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to 45 * 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
46 * perform extra error status checks on erase and write failures. This required 46 * perform extra error status checks on erase and write failures. This required
47 * adding a wrapper function for nand_read_ecc. 47 * adding a wrapper function for nand_read_ecc.
48 * 48 *
49 * 08-20-2005 vwool: suspend/resume added
50 *
49 * Credits: 51 * Credits:
50 * David Woodhouse for adding multichip support 52 * David Woodhouse for adding multichip support
51 * 53 *
52 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the 54 * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
53 * rework for 2K page size chips 55 * rework for 2K page size chips
54 * 56 *
@@ -59,7 +61,7 @@
59 * The AG-AND chips have nice features for speed improvement, 61 * The AG-AND chips have nice features for speed improvement,
60 * which are not supported yet. Read / program 4 pages in one go. 62 * which are not supported yet. Read / program 4 pages in one go.
61 * 63 *
62 * $Id: nand_base.c,v 1.147 2005/07/15 07:18:06 gleixner Exp $ 64 * $Id: nand_base.c,v 1.150 2005/09/15 13:58:48 vwool Exp $
63 * 65 *
64 * This program is free software; you can redistribute it and/or modify 66 * This program is free software; you can redistribute it and/or modify
65 * it under the terms of the GNU General Public License version 2 as 67 * it under the terms of the GNU General Public License version 2 as
@@ -103,8 +105,8 @@ static struct nand_oobinfo nand_oob_64 = {
103 .useecc = MTD_NANDECC_AUTOPLACE, 105 .useecc = MTD_NANDECC_AUTOPLACE,
104 .eccbytes = 24, 106 .eccbytes = 24,
105 .eccpos = { 107 .eccpos = {
106 40, 41, 42, 43, 44, 45, 46, 47, 108 40, 41, 42, 43, 44, 45, 46, 47,
107 48, 49, 50, 51, 52, 53, 54, 55, 109 48, 49, 50, 51, 52, 53, 54, 55,
108 56, 57, 58, 59, 60, 61, 62, 63}, 110 56, 57, 58, 59, 60, 61, 62, 63},
109 .oobfree = { {2, 38} } 111 .oobfree = { {2, 38} }
110}; 112};
@@ -147,19 +149,19 @@ static void nand_sync (struct mtd_info *mtd);
147static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, 149static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf,
148 struct nand_oobinfo *oobsel, int mode); 150 struct nand_oobinfo *oobsel, int mode);
149#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 151#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
150static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, 152static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
151 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); 153 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode);
152#else 154#else
153#define nand_verify_pages(...) (0) 155#define nand_verify_pages(...) (0)
154#endif 156#endif
155 157
156static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); 158static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state);
157 159
158/** 160/**
159 * nand_release_device - [GENERIC] release chip 161 * nand_release_device - [GENERIC] release chip
160 * @mtd: MTD device structure 162 * @mtd: MTD device structure
161 * 163 *
162 * Deselect, release chip lock and wake up anyone waiting on the device 164 * Deselect, release chip lock and wake up anyone waiting on the device
163 */ 165 */
164static void nand_release_device (struct mtd_info *mtd) 166static void nand_release_device (struct mtd_info *mtd)
165{ 167{
@@ -213,7 +215,7 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte)
213 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip 215 * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
214 * @mtd: MTD device structure 216 * @mtd: MTD device structure
215 * 217 *
216 * Default read function for 16bit buswith with 218 * Default read function for 16bit buswith with
217 * endianess conversion 219 * endianess conversion
218 */ 220 */
219static u_char nand_read_byte16(struct mtd_info *mtd) 221static u_char nand_read_byte16(struct mtd_info *mtd)
@@ -240,7 +242,7 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
240 * nand_read_word - [DEFAULT] read one word from the chip 242 * nand_read_word - [DEFAULT] read one word from the chip
241 * @mtd: MTD device structure 243 * @mtd: MTD device structure
242 * 244 *
243 * Default read function for 16bit buswith without 245 * Default read function for 16bit buswith without
244 * endianess conversion 246 * endianess conversion
245 */ 247 */
246static u16 nand_read_word(struct mtd_info *mtd) 248static u16 nand_read_word(struct mtd_info *mtd)
@@ -254,7 +256,7 @@ static u16 nand_read_word(struct mtd_info *mtd)
254 * @mtd: MTD device structure 256 * @mtd: MTD device structure
255 * @word: data word to write 257 * @word: data word to write
256 * 258 *
257 * Default write function for 16bit buswith without 259 * Default write function for 16bit buswith without
258 * endianess conversion 260 * endianess conversion
259 */ 261 */
260static void nand_write_word(struct mtd_info *mtd, u16 word) 262static void nand_write_word(struct mtd_info *mtd, u16 word)
@@ -275,7 +277,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chip)
275 struct nand_chip *this = mtd->priv; 277 struct nand_chip *this = mtd->priv;
276 switch(chip) { 278 switch(chip) {
277 case -1: 279 case -1:
278 this->hwcontrol(mtd, NAND_CTL_CLRNCE); 280 this->hwcontrol(mtd, NAND_CTL_CLRNCE);
279 break; 281 break;
280 case 0: 282 case 0:
281 this->hwcontrol(mtd, NAND_CTL_SETNCE); 283 this->hwcontrol(mtd, NAND_CTL_SETNCE);
@@ -304,7 +306,7 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
304} 306}
305 307
306/** 308/**
307 * nand_read_buf - [DEFAULT] read chip data into buffer 309 * nand_read_buf - [DEFAULT] read chip data into buffer
308 * @mtd: MTD device structure 310 * @mtd: MTD device structure
309 * @buf: buffer to store date 311 * @buf: buffer to store date
310 * @len: number of bytes to read 312 * @len: number of bytes to read
@@ -321,7 +323,7 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
321} 323}
322 324
323/** 325/**
324 * nand_verify_buf - [DEFAULT] Verify chip data against buffer 326 * nand_verify_buf - [DEFAULT] Verify chip data against buffer
325 * @mtd: MTD device structure 327 * @mtd: MTD device structure
326 * @buf: buffer containing the data to compare 328 * @buf: buffer containing the data to compare
327 * @len: number of bytes to compare 329 * @len: number of bytes to compare
@@ -354,14 +356,14 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
354 struct nand_chip *this = mtd->priv; 356 struct nand_chip *this = mtd->priv;
355 u16 *p = (u16 *) buf; 357 u16 *p = (u16 *) buf;
356 len >>= 1; 358 len >>= 1;
357 359
358 for (i=0; i<len; i++) 360 for (i=0; i<len; i++)
359 writew(p[i], this->IO_ADDR_W); 361 writew(p[i], this->IO_ADDR_W);
360 362
361} 363}
362 364
363/** 365/**
364 * nand_read_buf16 - [DEFAULT] read chip data into buffer 366 * nand_read_buf16 - [DEFAULT] read chip data into buffer
365 * @mtd: MTD device structure 367 * @mtd: MTD device structure
366 * @buf: buffer to store date 368 * @buf: buffer to store date
367 * @len: number of bytes to read 369 * @len: number of bytes to read
@@ -380,7 +382,7 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
380} 382}
381 383
382/** 384/**
383 * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer 385 * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
384 * @mtd: MTD device structure 386 * @mtd: MTD device structure
385 * @buf: buffer containing the data to compare 387 * @buf: buffer containing the data to compare
386 * @len: number of bytes to compare 388 * @len: number of bytes to compare
@@ -407,7 +409,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
407 * @ofs: offset from device start 409 * @ofs: offset from device start
408 * @getchip: 0, if the chip is already selected 410 * @getchip: 0, if the chip is already selected
409 * 411 *
410 * Check, if the block is bad. 412 * Check, if the block is bad.
411 */ 413 */
412static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) 414static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
413{ 415{
@@ -424,14 +426,14 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
424 426
425 /* Select the NAND device */ 427 /* Select the NAND device */
426 this->select_chip(mtd, chipnr); 428 this->select_chip(mtd, chipnr);
427 } else 429 } else
428 page = (int) ofs; 430 page = (int) ofs;
429 431
430 if (this->options & NAND_BUSWIDTH_16) { 432 if (this->options & NAND_BUSWIDTH_16) {
431 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask); 433 this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page & this->pagemask);
432 bad = cpu_to_le16(this->read_word(mtd)); 434 bad = cpu_to_le16(this->read_word(mtd));
433 if (this->badblockpos & 0x1) 435 if (this->badblockpos & 0x1)
434 bad >>= 1; 436 bad >>= 8;
435 if ((bad & 0xFF) != 0xff) 437 if ((bad & 0xFF) != 0xff)
436 res = 1; 438 res = 1;
437 } else { 439 } else {
@@ -439,12 +441,12 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
439 if (this->read_byte(mtd) != 0xff) 441 if (this->read_byte(mtd) != 0xff)
440 res = 1; 442 res = 1;
441 } 443 }
442 444
443 if (getchip) { 445 if (getchip) {
444 /* Deselect and wake up anyone waiting on the device */ 446 /* Deselect and wake up anyone waiting on the device */
445 nand_release_device(mtd); 447 nand_release_device(mtd);
446 } 448 }
447 449
448 return res; 450 return res;
449} 451}
450 452
@@ -462,7 +464,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
462 u_char buf[2] = {0, 0}; 464 u_char buf[2] = {0, 0};
463 size_t retlen; 465 size_t retlen;
464 int block; 466 int block;
465 467
466 /* Get block number */ 468 /* Get block number */
467 block = ((int) ofs) >> this->bbt_erase_shift; 469 block = ((int) ofs) >> this->bbt_erase_shift;
468 if (this->bbt) 470 if (this->bbt)
@@ -471,25 +473,25 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
471 /* Do we have a flash based bad block table ? */ 473 /* Do we have a flash based bad block table ? */
472 if (this->options & NAND_USE_FLASH_BBT) 474 if (this->options & NAND_USE_FLASH_BBT)
473 return nand_update_bbt (mtd, ofs); 475 return nand_update_bbt (mtd, ofs);
474 476
475 /* We write two bytes, so we dont have to mess with 16 bit access */ 477 /* We write two bytes, so we dont have to mess with 16 bit access */
476 ofs += mtd->oobsize + (this->badblockpos & ~0x01); 478 ofs += mtd->oobsize + (this->badblockpos & ~0x01);
477 return nand_write_oob (mtd, ofs , 2, &retlen, buf); 479 return nand_write_oob (mtd, ofs , 2, &retlen, buf);
478} 480}
479 481
480/** 482/**
481 * nand_check_wp - [GENERIC] check if the chip is write protected 483 * nand_check_wp - [GENERIC] check if the chip is write protected
482 * @mtd: MTD device structure 484 * @mtd: MTD device structure
483 * Check, if the device is write protected 485 * Check, if the device is write protected
484 * 486 *
485 * The function expects, that the device is already selected 487 * The function expects, that the device is already selected
486 */ 488 */
487static int nand_check_wp (struct mtd_info *mtd) 489static int nand_check_wp (struct mtd_info *mtd)
488{ 490{
489 struct nand_chip *this = mtd->priv; 491 struct nand_chip *this = mtd->priv;
490 /* Check the WP bit */ 492 /* Check the WP bit */
491 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); 493 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
492 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; 494 return (this->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1;
493} 495}
494 496
495/** 497/**
@@ -505,15 +507,15 @@ static int nand_check_wp (struct mtd_info *mtd)
505static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) 507static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
506{ 508{
507 struct nand_chip *this = mtd->priv; 509 struct nand_chip *this = mtd->priv;
508 510
509 if (!this->bbt) 511 if (!this->bbt)
510 return this->block_bad(mtd, ofs, getchip); 512 return this->block_bad(mtd, ofs, getchip);
511 513
512 /* Return info from the table */ 514 /* Return info from the table */
513 return nand_isbad_bbt (mtd, ofs, allowbbt); 515 return nand_isbad_bbt (mtd, ofs, allowbbt);
514} 516}
515 517
516/* 518/*
517 * Wait for the ready pin, after a command 519 * Wait for the ready pin, after a command
518 * The timeout is catched later. 520 * The timeout is catched later.
519 */ 521 */
@@ -527,7 +529,7 @@ static void nand_wait_ready(struct mtd_info *mtd)
527 if (this->dev_ready(mtd)) 529 if (this->dev_ready(mtd))
528 return; 530 return;
529 touch_softlockup_watchdog(); 531 touch_softlockup_watchdog();
530 } while (time_before(jiffies, timeo)); 532 } while (time_before(jiffies, timeo));
531} 533}
532 534
533/** 535/**
@@ -590,13 +592,13 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
590 /* Latch in address */ 592 /* Latch in address */
591 this->hwcontrol(mtd, NAND_CTL_CLRALE); 593 this->hwcontrol(mtd, NAND_CTL_CLRALE);
592 } 594 }
593 595
594 /* 596 /*
595 * program and erase have their own busy handlers 597 * program and erase have their own busy handlers
596 * status and sequential in needs no delay 598 * status and sequential in needs no delay
597 */ 599 */
598 switch (command) { 600 switch (command) {
599 601
600 case NAND_CMD_PAGEPROG: 602 case NAND_CMD_PAGEPROG:
601 case NAND_CMD_ERASE1: 603 case NAND_CMD_ERASE1:
602 case NAND_CMD_ERASE2: 604 case NAND_CMD_ERASE2:
@@ -605,7 +607,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
605 return; 607 return;
606 608
607 case NAND_CMD_RESET: 609 case NAND_CMD_RESET:
608 if (this->dev_ready) 610 if (this->dev_ready)
609 break; 611 break;
610 udelay(this->chip_delay); 612 udelay(this->chip_delay);
611 this->hwcontrol(mtd, NAND_CTL_SETCLE); 613 this->hwcontrol(mtd, NAND_CTL_SETCLE);
@@ -614,16 +616,16 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
614 while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); 616 while ( !(this->read_byte(mtd) & NAND_STATUS_READY));
615 return; 617 return;
616 618
617 /* This applies to read commands */ 619 /* This applies to read commands */
618 default: 620 default:
619 /* 621 /*
620 * If we don't have access to the busy pin, we apply the given 622 * If we don't have access to the busy pin, we apply the given
621 * command delay 623 * command delay
622 */ 624 */
623 if (!this->dev_ready) { 625 if (!this->dev_ready) {
624 udelay (this->chip_delay); 626 udelay (this->chip_delay);
625 return; 627 return;
626 } 628 }
627 } 629 }
628 /* Apply this short delay always to ensure that we do wait tWB in 630 /* Apply this short delay always to ensure that we do wait tWB in
629 * any case on any machine. */ 631 * any case on any machine. */
@@ -653,8 +655,8 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
653 column += mtd->oobblock; 655 column += mtd->oobblock;
654 command = NAND_CMD_READ0; 656 command = NAND_CMD_READ0;
655 } 657 }
656 658
657 659
658 /* Begin command latch cycle */ 660 /* Begin command latch cycle */
659 this->hwcontrol(mtd, NAND_CTL_SETCLE); 661 this->hwcontrol(mtd, NAND_CTL_SETCLE);
660 /* Write out the command to the device. */ 662 /* Write out the command to the device. */
@@ -672,7 +674,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
672 column >>= 1; 674 column >>= 1;
673 this->write_byte(mtd, column & 0xff); 675 this->write_byte(mtd, column & 0xff);
674 this->write_byte(mtd, column >> 8); 676 this->write_byte(mtd, column >> 8);
675 } 677 }
676 if (page_addr != -1) { 678 if (page_addr != -1) {
677 this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); 679 this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
678 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); 680 this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
@@ -683,13 +685,13 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
683 /* Latch in address */ 685 /* Latch in address */
684 this->hwcontrol(mtd, NAND_CTL_CLRALE); 686 this->hwcontrol(mtd, NAND_CTL_CLRALE);
685 } 687 }
686 688
687 /* 689 /*
688 * program and erase have their own busy handlers 690 * program and erase have their own busy handlers
689 * status, sequential in, and deplete1 need no delay 691 * status, sequential in, and deplete1 need no delay
690 */ 692 */
691 switch (command) { 693 switch (command) {
692 694
693 case NAND_CMD_CACHEDPROG: 695 case NAND_CMD_CACHEDPROG:
694 case NAND_CMD_PAGEPROG: 696 case NAND_CMD_PAGEPROG:
695 case NAND_CMD_ERASE1: 697 case NAND_CMD_ERASE1:
@@ -699,7 +701,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
699 case NAND_CMD_DEPLETE1: 701 case NAND_CMD_DEPLETE1:
700 return; 702 return;
701 703
702 /* 704 /*
703 * read error status commands require only a short delay 705 * read error status commands require only a short delay
704 */ 706 */
705 case NAND_CMD_STATUS_ERROR: 707 case NAND_CMD_STATUS_ERROR:
@@ -711,7 +713,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
711 return; 713 return;
712 714
713 case NAND_CMD_RESET: 715 case NAND_CMD_RESET:
714 if (this->dev_ready) 716 if (this->dev_ready)
715 break; 717 break;
716 udelay(this->chip_delay); 718 udelay(this->chip_delay);
717 this->hwcontrol(mtd, NAND_CTL_SETCLE); 719 this->hwcontrol(mtd, NAND_CTL_SETCLE);
@@ -728,17 +730,17 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
728 /* End command latch cycle */ 730 /* End command latch cycle */
729 this->hwcontrol(mtd, NAND_CTL_CLRCLE); 731 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
730 /* Fall through into ready check */ 732 /* Fall through into ready check */
731 733
732 /* This applies to read commands */ 734 /* This applies to read commands */
733 default: 735 default:
734 /* 736 /*
735 * If we don't have access to the busy pin, we apply the given 737 * If we don't have access to the busy pin, we apply the given
736 * command delay 738 * command delay
737 */ 739 */
738 if (!this->dev_ready) { 740 if (!this->dev_ready) {
739 udelay (this->chip_delay); 741 udelay (this->chip_delay);
740 return; 742 return;
741 } 743 }
742 } 744 }
743 745
744 /* Apply this short delay always to ensure that we do wait tWB in 746 /* Apply this short delay always to ensure that we do wait tWB in
@@ -752,11 +754,11 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
752 * nand_get_device - [GENERIC] Get chip for selected access 754 * nand_get_device - [GENERIC] Get chip for selected access
753 * @this: the nand chip descriptor 755 * @this: the nand chip descriptor
754 * @mtd: MTD device structure 756 * @mtd: MTD device structure
755 * @new_state: the state which is requested 757 * @new_state: the state which is requested
756 * 758 *
757 * Get the device and lock it for exclusive access 759 * Get the device and lock it for exclusive access
758 */ 760 */
759static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) 761static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state)
760{ 762{
761 struct nand_chip *active; 763 struct nand_chip *active;
762 spinlock_t *lock; 764 spinlock_t *lock;
@@ -779,7 +781,11 @@ retry:
779 if (active == this && this->state == FL_READY) { 781 if (active == this && this->state == FL_READY) {
780 this->state = new_state; 782 this->state = new_state;
781 spin_unlock(lock); 783 spin_unlock(lock);
782 return; 784 return 0;
785 }
786 if (new_state == FL_PM_SUSPENDED) {
787 spin_unlock(lock);
788 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
783 } 789 }
784 set_current_state(TASK_UNINTERRUPTIBLE); 790 set_current_state(TASK_UNINTERRUPTIBLE);
785 add_wait_queue(wq, &wait); 791 add_wait_queue(wq, &wait);
@@ -796,7 +802,7 @@ retry:
796 * @state: state to select the max. timeout value 802 * @state: state to select the max. timeout value
797 * 803 *
798 * Wait for command done. This applies to erase and program only 804 * Wait for command done. This applies to erase and program only
799 * Erase can take up to 400ms and program up to 20ms according to 805 * Erase can take up to 400ms and program up to 20ms according to
800 * general NAND and SmartMedia specs 806 * general NAND and SmartMedia specs
801 * 807 *
802*/ 808*/
@@ -805,7 +811,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
805 811
806 unsigned long timeo = jiffies; 812 unsigned long timeo = jiffies;
807 int status; 813 int status;
808 814
809 if (state == FL_ERASING) 815 if (state == FL_ERASING)
810 timeo += (HZ * 400) / 1000; 816 timeo += (HZ * 400) / 1000;
811 else 817 else
@@ -817,17 +823,17 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
817 823
818 if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) 824 if ((state == FL_ERASING) && (this->options & NAND_IS_AND))
819 this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); 825 this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1);
820 else 826 else
821 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); 827 this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
822 828
823 while (time_before(jiffies, timeo)) { 829 while (time_before(jiffies, timeo)) {
824 /* Check, if we were interrupted */ 830 /* Check, if we were interrupted */
825 if (this->state != state) 831 if (this->state != state)
826 return 0; 832 return 0;
827 833
828 if (this->dev_ready) { 834 if (this->dev_ready) {
829 if (this->dev_ready(mtd)) 835 if (this->dev_ready(mtd))
830 break; 836 break;
831 } else { 837 } else {
832 if (this->read_byte(mtd) & NAND_STATUS_READY) 838 if (this->read_byte(mtd) & NAND_STATUS_READY)
833 break; 839 break;
@@ -853,7 +859,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
853 * 859 *
854 * Cached programming is not supported yet. 860 * Cached programming is not supported yet.
855 */ 861 */
856static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, 862static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
857 u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) 863 u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
858{ 864{
859 int i, status; 865 int i, status;
@@ -862,10 +868,10 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
862 int *oob_config = oobsel->eccpos; 868 int *oob_config = oobsel->eccpos;
863 int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; 869 int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
864 int eccbytes = 0; 870 int eccbytes = 0;
865 871
866 /* FIXME: Enable cached programming */ 872 /* FIXME: Enable cached programming */
867 cached = 0; 873 cached = 0;
868 874
869 /* Send command to begin auto page programming */ 875 /* Send command to begin auto page programming */
870 this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); 876 this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
871 877
@@ -876,7 +882,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
876 printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); 882 printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
877 this->write_buf(mtd, this->data_poi, mtd->oobblock); 883 this->write_buf(mtd, this->data_poi, mtd->oobblock);
878 break; 884 break;
879 885
880 /* Software ecc 3/256, write all */ 886 /* Software ecc 3/256, write all */
881 case NAND_ECC_SOFT: 887 case NAND_ECC_SOFT:
882 for (; eccsteps; eccsteps--) { 888 for (; eccsteps; eccsteps--) {
@@ -905,11 +911,11 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
905 } 911 }
906 break; 912 break;
907 } 913 }
908 914
909 /* Write out OOB data */ 915 /* Write out OOB data */
910 if (this->options & NAND_HWECC_SYNDROME) 916 if (this->options & NAND_HWECC_SYNDROME)
911 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); 917 this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes);
912 else 918 else
913 this->write_buf(mtd, oob_buf, mtd->oobsize); 919 this->write_buf(mtd, oob_buf, mtd->oobsize);
914 920
915 /* Send command to actually program the data */ 921 /* Send command to actually program the data */
@@ -934,7 +940,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
934 /* wait until cache is ready*/ 940 /* wait until cache is ready*/
935 // status = this->waitfunc (mtd, this, FL_CACHEDRPG); 941 // status = this->waitfunc (mtd, this, FL_CACHEDRPG);
936 } 942 }
937 return 0; 943 return 0;
938} 944}
939 945
940#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 946#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
@@ -950,19 +956,19 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
950 * @oobmode: 1 = full buffer verify, 0 = ecc only 956 * @oobmode: 1 = full buffer verify, 0 = ecc only
951 * 957 *
952 * The NAND device assumes that it is always writing to a cleanly erased page. 958 * The NAND device assumes that it is always writing to a cleanly erased page.
953 * Hence, it performs its internal write verification only on bits that 959 * Hence, it performs its internal write verification only on bits that
954 * transitioned from 1 to 0. The device does NOT verify the whole page on a 960 * transitioned from 1 to 0. The device does NOT verify the whole page on a
955 * byte by byte basis. It is possible that the page was not completely erased 961 * byte by byte basis. It is possible that the page was not completely erased
956 * or the page is becoming unusable due to wear. The read with ECC would catch 962 * or the page is becoming unusable due to wear. The read with ECC would catch
957 * the error later when the ECC page check fails, but we would rather catch 963 * the error later when the ECC page check fails, but we would rather catch
958 * it early in the page write stage. Better to write no data than invalid data. 964 * it early in the page write stage. Better to write no data than invalid data.
959 */ 965 */
960static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, 966static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
961 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) 967 u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
962{ 968{
963 int i, j, datidx = 0, oobofs = 0, res = -EIO; 969 int i, j, datidx = 0, oobofs = 0, res = -EIO;
964 int eccsteps = this->eccsteps; 970 int eccsteps = this->eccsteps;
965 int hweccbytes; 971 int hweccbytes;
966 u_char oobdata[64]; 972 u_char oobdata[64];
967 973
968 hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; 974 hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0;
@@ -1002,7 +1008,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1002 1008
1003 if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) { 1009 if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
1004 int ecccnt = oobsel->eccbytes; 1010 int ecccnt = oobsel->eccbytes;
1005 1011
1006 for (i = 0; i < ecccnt; i++) { 1012 for (i = 0; i < ecccnt; i++) {
1007 int idx = oobsel->eccpos[i]; 1013 int idx = oobsel->eccpos[i];
1008 if (oobdata[idx] != oob_buf[oobofs + idx] ) { 1014 if (oobdata[idx] != oob_buf[oobofs + idx] ) {
@@ -1012,20 +1018,20 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1012 goto out; 1018 goto out;
1013 } 1019 }
1014 } 1020 }
1015 } 1021 }
1016 } 1022 }
1017 oobofs += mtd->oobsize - hweccbytes * eccsteps; 1023 oobofs += mtd->oobsize - hweccbytes * eccsteps;
1018 page++; 1024 page++;
1019 numpages--; 1025 numpages--;
1020 1026
1021 /* Apply delay or wait for ready/busy pin 1027 /* Apply delay or wait for ready/busy pin
1022 * Do this before the AUTOINCR check, so no problems 1028 * Do this before the AUTOINCR check, so no problems
1023 * arise if a chip which does auto increment 1029 * arise if a chip which does auto increment
1024 * is marked as NOAUTOINCR by the board driver. 1030 * is marked as NOAUTOINCR by the board driver.
1025 * Do this also before returning, so the chip is 1031 * Do this also before returning, so the chip is
1026 * ready for the next command. 1032 * ready for the next command.
1027 */ 1033 */
1028 if (!this->dev_ready) 1034 if (!this->dev_ready)
1029 udelay (this->chip_delay); 1035 udelay (this->chip_delay);
1030 else 1036 else
1031 nand_wait_ready(mtd); 1037 nand_wait_ready(mtd);
@@ -1033,17 +1039,17 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
1033 /* All done, return happy */ 1039 /* All done, return happy */
1034 if (!numpages) 1040 if (!numpages)
1035 return 0; 1041 return 0;
1036 1042
1037 1043
1038 /* Check, if the chip supports auto page increment */ 1044 /* Check, if the chip supports auto page increment */
1039 if (!NAND_CANAUTOINCR(this)) 1045 if (!NAND_CANAUTOINCR(this))
1040 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); 1046 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
1041 } 1047 }
1042 /* 1048 /*
1043 * Terminate the read command. We come here in case of an error 1049 * Terminate the read command. We come here in case of an error
1044 * So we must issue a reset command. 1050 * So we must issue a reset command.
1045 */ 1051 */
1046out: 1052out:
1047 this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1); 1053 this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
1048 return res; 1054 return res;
1049} 1055}
@@ -1105,7 +1111,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1105 * NAND read with ECC 1111 * NAND read with ECC
1106 */ 1112 */
1107int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, 1113int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1108 size_t * retlen, u_char * buf, u_char * oob_buf, 1114 size_t * retlen, u_char * buf, u_char * oob_buf,
1109 struct nand_oobinfo *oobsel, int flags) 1115 struct nand_oobinfo *oobsel, int flags)
1110{ 1116{
1111 1117
@@ -1139,7 +1145,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1139 /* Autoplace of oob data ? Use the default placement scheme */ 1145 /* Autoplace of oob data ? Use the default placement scheme */
1140 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) 1146 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE)
1141 oobsel = this->autooob; 1147 oobsel = this->autooob;
1142 1148
1143 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; 1149 eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
1144 oob_config = oobsel->eccpos; 1150 oob_config = oobsel->eccpos;
1145 1151
@@ -1157,28 +1163,28 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1157 end = mtd->oobblock; 1163 end = mtd->oobblock;
1158 ecc = this->eccsize; 1164 ecc = this->eccsize;
1159 eccbytes = this->eccbytes; 1165 eccbytes = this->eccbytes;
1160 1166
1161 if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME)) 1167 if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME))
1162 compareecc = 0; 1168 compareecc = 0;
1163 1169
1164 oobreadlen = mtd->oobsize; 1170 oobreadlen = mtd->oobsize;
1165 if (this->options & NAND_HWECC_SYNDROME) 1171 if (this->options & NAND_HWECC_SYNDROME)
1166 oobreadlen -= oobsel->eccbytes; 1172 oobreadlen -= oobsel->eccbytes;
1167 1173
1168 /* Loop until all data read */ 1174 /* Loop until all data read */
1169 while (read < len) { 1175 while (read < len) {
1170 1176
1171 int aligned = (!col && (len - read) >= end); 1177 int aligned = (!col && (len - read) >= end);
1172 /* 1178 /*
1173 * If the read is not page aligned, we have to read into data buffer 1179 * If the read is not page aligned, we have to read into data buffer
1174 * due to ecc, else we read into return buffer direct 1180 * due to ecc, else we read into return buffer direct
1175 */ 1181 */
1176 if (aligned) 1182 if (aligned)
1177 data_poi = &buf[read]; 1183 data_poi = &buf[read];
1178 else 1184 else
1179 data_poi = this->data_buf; 1185 data_poi = this->data_buf;
1180 1186
1181 /* Check, if we have this page in the buffer 1187 /* Check, if we have this page in the buffer
1182 * 1188 *
1183 * FIXME: Make it work when we must provide oob data too, 1189 * FIXME: Make it work when we must provide oob data too,
1184 * check the usage of data_buf oob field 1190 * check the usage of data_buf oob field
@@ -1194,7 +1200,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1194 if (sndcmd) { 1200 if (sndcmd) {
1195 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); 1201 this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page);
1196 sndcmd = 0; 1202 sndcmd = 0;
1197 } 1203 }
1198 1204
1199 /* get oob area, if we have no oob buffer from fs-driver */ 1205 /* get oob area, if we have no oob buffer from fs-driver */
1200 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || 1206 if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
@@ -1202,7 +1208,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1202 oob_data = &this->data_buf[end]; 1208 oob_data = &this->data_buf[end];
1203 1209
1204 eccsteps = this->eccsteps; 1210 eccsteps = this->eccsteps;
1205 1211
1206 switch (eccmode) { 1212 switch (eccmode) {
1207 case NAND_ECC_NONE: { /* No ECC, Read in a page */ 1213 case NAND_ECC_NONE: { /* No ECC, Read in a page */
1208 static unsigned long lastwhinge = 0; 1214 static unsigned long lastwhinge = 0;
@@ -1213,12 +1219,12 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1213 this->read_buf(mtd, data_poi, end); 1219 this->read_buf(mtd, data_poi, end);
1214 break; 1220 break;
1215 } 1221 }
1216 1222
1217 case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ 1223 case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */
1218 this->read_buf(mtd, data_poi, end); 1224 this->read_buf(mtd, data_poi, end);
1219 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) 1225 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
1220 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); 1226 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
1221 break; 1227 break;
1222 1228
1223 default: 1229 default:
1224 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { 1230 for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) {
@@ -1237,15 +1243,15 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1237 * does the error correction on the fly */ 1243 * does the error correction on the fly */
1238 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]); 1244 ecc_status = this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]);
1239 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { 1245 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1240 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " 1246 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
1241 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); 1247 "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
1242 ecc_failed++; 1248 ecc_failed++;
1243 } 1249 }
1244 } else { 1250 } else {
1245 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); 1251 this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
1246 } 1252 }
1247 } 1253 }
1248 break; 1254 break;
1249 } 1255 }
1250 1256
1251 /* read oobdata */ 1257 /* read oobdata */
@@ -1253,8 +1259,8 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1253 1259
1254 /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ 1260 /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
1255 if (!compareecc) 1261 if (!compareecc)
1256 goto readoob; 1262 goto readoob;
1257 1263
1258 /* Pick the ECC bytes out of the oob data */ 1264 /* Pick the ECC bytes out of the oob data */
1259 for (j = 0; j < oobsel->eccbytes; j++) 1265 for (j = 0; j < oobsel->eccbytes; j++)
1260 ecc_code[j] = oob_data[oob_config[j]]; 1266 ecc_code[j] = oob_data[oob_config[j]];
@@ -1262,24 +1268,24 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1262 /* correct data, if neccecary */ 1268 /* correct data, if neccecary */
1263 for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { 1269 for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
1264 ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]); 1270 ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]);
1265 1271
1266 /* Get next chunk of ecc bytes */ 1272 /* Get next chunk of ecc bytes */
1267 j += eccbytes; 1273 j += eccbytes;
1268 1274
1269 /* Check, if we have a fs supplied oob-buffer, 1275 /* Check, if we have a fs supplied oob-buffer,
1270 * This is the legacy mode. Used by YAFFS1 1276 * This is the legacy mode. Used by YAFFS1
1271 * Should go away some day 1277 * Should go away some day
1272 */ 1278 */
1273 if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { 1279 if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
1274 int *p = (int *)(&oob_data[mtd->oobsize]); 1280 int *p = (int *)(&oob_data[mtd->oobsize]);
1275 p[i] = ecc_status; 1281 p[i] = ecc_status;
1276 } 1282 }
1277 1283
1278 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) { 1284 if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
1279 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page); 1285 DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
1280 ecc_failed++; 1286 ecc_failed++;
1281 } 1287 }
1282 } 1288 }
1283 1289
1284 readoob: 1290 readoob:
1285 /* check, if we have a fs supplied oob-buffer */ 1291 /* check, if we have a fs supplied oob-buffer */
@@ -1305,25 +1311,25 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1305 } 1311 }
1306 readdata: 1312 readdata:
1307 /* Partial page read, transfer data into fs buffer */ 1313 /* Partial page read, transfer data into fs buffer */
1308 if (!aligned) { 1314 if (!aligned) {
1309 for (j = col; j < end && read < len; j++) 1315 for (j = col; j < end && read < len; j++)
1310 buf[read++] = data_poi[j]; 1316 buf[read++] = data_poi[j];
1311 this->pagebuf = realpage; 1317 this->pagebuf = realpage;
1312 } else 1318 } else
1313 read += mtd->oobblock; 1319 read += mtd->oobblock;
1314 1320
1315 /* Apply delay or wait for ready/busy pin 1321 /* Apply delay or wait for ready/busy pin
1316 * Do this before the AUTOINCR check, so no problems 1322 * Do this before the AUTOINCR check, so no problems
1317 * arise if a chip which does auto increment 1323 * arise if a chip which does auto increment
1318 * is marked as NOAUTOINCR by the board driver. 1324 * is marked as NOAUTOINCR by the board driver.
1319 */ 1325 */
1320 if (!this->dev_ready) 1326 if (!this->dev_ready)
1321 udelay (this->chip_delay); 1327 udelay (this->chip_delay);
1322 else 1328 else
1323 nand_wait_ready(mtd); 1329 nand_wait_ready(mtd);
1324 1330
1325 if (read == len) 1331 if (read == len)
1326 break; 1332 break;
1327 1333
1328 /* For subsequent reads align to page boundary. */ 1334 /* For subsequent reads align to page boundary. */
1329 col = 0; 1335 col = 0;
@@ -1337,11 +1343,11 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
1337 this->select_chip(mtd, -1); 1343 this->select_chip(mtd, -1);
1338 this->select_chip(mtd, chipnr); 1344 this->select_chip(mtd, chipnr);
1339 } 1345 }
1340 /* Check, if the chip supports auto page increment 1346 /* Check, if the chip supports auto page increment
1341 * or if we have hit a block boundary. 1347 * or if we have hit a block boundary.
1342 */ 1348 */
1343 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1349 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
1344 sndcmd = 1; 1350 sndcmd = 1;
1345 } 1351 }
1346 1352
1347 /* Deselect and wake up anyone waiting on the device */ 1353 /* Deselect and wake up anyone waiting on the device */
@@ -1378,7 +1384,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1378 /* Shift to get page */ 1384 /* Shift to get page */
1379 page = (int)(from >> this->page_shift); 1385 page = (int)(from >> this->page_shift);
1380 chipnr = (int)(from >> this->chip_shift); 1386 chipnr = (int)(from >> this->chip_shift);
1381 1387
1382 /* Mask to get column */ 1388 /* Mask to get column */
1383 col = from & (mtd->oobsize - 1); 1389 col = from & (mtd->oobsize - 1);
1384 1390
@@ -1400,7 +1406,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1400 1406
1401 /* Send the read command */ 1407 /* Send the read command */
1402 this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask); 1408 this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask);
1403 /* 1409 /*
1404 * Read the data, if we read more than one page 1410 * Read the data, if we read more than one page
1405 * oob data, let the device transfer the data ! 1411 * oob data, let the device transfer the data !
1406 */ 1412 */
@@ -1422,20 +1428,20 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
1422 this->select_chip(mtd, -1); 1428 this->select_chip(mtd, -1);
1423 this->select_chip(mtd, chipnr); 1429 this->select_chip(mtd, chipnr);
1424 } 1430 }
1425 1431
1426 /* Apply delay or wait for ready/busy pin 1432 /* Apply delay or wait for ready/busy pin
1427 * Do this before the AUTOINCR check, so no problems 1433 * Do this before the AUTOINCR check, so no problems
1428 * arise if a chip which does auto increment 1434 * arise if a chip which does auto increment
1429 * is marked as NOAUTOINCR by the board driver. 1435 * is marked as NOAUTOINCR by the board driver.
1430 */ 1436 */
1431 if (!this->dev_ready) 1437 if (!this->dev_ready)
1432 udelay (this->chip_delay); 1438 udelay (this->chip_delay);
1433 else 1439 else
1434 nand_wait_ready(mtd); 1440 nand_wait_ready(mtd);
1435 1441
1436 /* Check, if the chip supports auto page increment 1442 /* Check, if the chip supports auto page increment
1437 * or if we have hit a block boundary. 1443 * or if we have hit a block boundary.
1438 */ 1444 */
1439 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { 1445 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) {
1440 /* For subsequent page reads set offset to 0 */ 1446 /* For subsequent page reads set offset to 0 */
1441 this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); 1447 this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask);
@@ -1481,27 +1487,27 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
1481 nand_get_device (this, mtd , FL_READING); 1487 nand_get_device (this, mtd , FL_READING);
1482 1488
1483 this->select_chip (mtd, chip); 1489 this->select_chip (mtd, chip);
1484 1490
1485 /* Add requested oob length */ 1491 /* Add requested oob length */
1486 len += ooblen; 1492 len += ooblen;
1487 1493
1488 while (len) { 1494 while (len) {
1489 if (sndcmd) 1495 if (sndcmd)
1490 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); 1496 this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
1491 sndcmd = 0; 1497 sndcmd = 0;
1492 1498
1493 this->read_buf (mtd, &buf[cnt], pagesize); 1499 this->read_buf (mtd, &buf[cnt], pagesize);
1494 1500
1495 len -= pagesize; 1501 len -= pagesize;
1496 cnt += pagesize; 1502 cnt += pagesize;
1497 page++; 1503 page++;
1498 1504
1499 if (!this->dev_ready) 1505 if (!this->dev_ready)
1500 udelay (this->chip_delay); 1506 udelay (this->chip_delay);
1501 else 1507 else
1502 nand_wait_ready(mtd); 1508 nand_wait_ready(mtd);
1503 1509
1504 /* Check, if the chip supports auto page increment */ 1510 /* Check, if the chip supports auto page increment */
1505 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) 1511 if (!NAND_CANAUTOINCR(this) || !(page & blockcheck))
1506 sndcmd = 1; 1512 sndcmd = 1;
1507 } 1513 }
@@ -1512,8 +1518,8 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
1512} 1518}
1513 1519
1514 1520
1515/** 1521/**
1516 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer 1522 * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
1517 * @mtd: MTD device structure 1523 * @mtd: MTD device structure
1518 * @fsbuf: buffer given by fs driver 1524 * @fsbuf: buffer given by fs driver
1519 * @oobsel: out of band selection structre 1525 * @oobsel: out of band selection structre
@@ -1542,20 +1548,20 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct
1542 int i, len, ofs; 1548 int i, len, ofs;
1543 1549
1544 /* Zero copy fs supplied buffer */ 1550 /* Zero copy fs supplied buffer */
1545 if (fsbuf && !autoplace) 1551 if (fsbuf && !autoplace)
1546 return fsbuf; 1552 return fsbuf;
1547 1553
1548 /* Check, if the buffer must be filled with ff again */ 1554 /* Check, if the buffer must be filled with ff again */
1549 if (this->oobdirty) { 1555 if (this->oobdirty) {
1550 memset (this->oob_buf, 0xff, 1556 memset (this->oob_buf, 0xff,
1551 mtd->oobsize << (this->phys_erase_shift - this->page_shift)); 1557 mtd->oobsize << (this->phys_erase_shift - this->page_shift));
1552 this->oobdirty = 0; 1558 this->oobdirty = 0;
1553 } 1559 }
1554 1560
1555 /* If we have no autoplacement or no fs buffer use the internal one */ 1561 /* If we have no autoplacement or no fs buffer use the internal one */
1556 if (!autoplace || !fsbuf) 1562 if (!autoplace || !fsbuf)
1557 return this->oob_buf; 1563 return this->oob_buf;
1558 1564
1559 /* Walk through the pages and place the data */ 1565 /* Walk through the pages and place the data */
1560 this->oobdirty = 1; 1566 this->oobdirty = 1;
1561 ofs = 0; 1567 ofs = 0;
@@ -1589,7 +1595,7 @@ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * ret
1589{ 1595{
1590 return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); 1596 return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
1591} 1597}
1592 1598
1593/** 1599/**
1594 * nand_write_ecc - [MTD Interface] NAND write with ECC 1600 * nand_write_ecc - [MTD Interface] NAND write with ECC
1595 * @mtd: MTD device structure 1601 * @mtd: MTD device structure
@@ -1622,7 +1628,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1622 return -EINVAL; 1628 return -EINVAL;
1623 } 1629 }
1624 1630
1625 /* reject writes, which are not page aligned */ 1631 /* reject writes, which are not page aligned */
1626 if (NOTALIGNED (to) || NOTALIGNED(len)) { 1632 if (NOTALIGNED (to) || NOTALIGNED(len)) {
1627 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); 1633 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
1628 return -EINVAL; 1634 return -EINVAL;
@@ -1641,14 +1647,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1641 goto out; 1647 goto out;
1642 1648
1643 /* if oobsel is NULL, use chip defaults */ 1649 /* if oobsel is NULL, use chip defaults */
1644 if (oobsel == NULL) 1650 if (oobsel == NULL)
1645 oobsel = &mtd->oobinfo; 1651 oobsel = &mtd->oobinfo;
1646 1652
1647 /* Autoplace of oob data ? Use the default placement scheme */ 1653 /* Autoplace of oob data ? Use the default placement scheme */
1648 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { 1654 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
1649 oobsel = this->autooob; 1655 oobsel = this->autooob;
1650 autoplace = 1; 1656 autoplace = 1;
1651 } 1657 }
1652 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) 1658 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1653 autoplace = 1; 1659 autoplace = 1;
1654 1660
@@ -1656,9 +1662,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1656 totalpages = len >> this->page_shift; 1662 totalpages = len >> this->page_shift;
1657 page = (int) (to >> this->page_shift); 1663 page = (int) (to >> this->page_shift);
1658 /* Invalidate the page cache, if we write to the cached page */ 1664 /* Invalidate the page cache, if we write to the cached page */
1659 if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) 1665 if (page <= this->pagebuf && this->pagebuf < (page + totalpages))
1660 this->pagebuf = -1; 1666 this->pagebuf = -1;
1661 1667
1662 /* Set it relative to chip */ 1668 /* Set it relative to chip */
1663 page &= this->pagemask; 1669 page &= this->pagemask;
1664 startpage = page; 1670 startpage = page;
@@ -1680,14 +1686,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1680 if (ret) { 1686 if (ret) {
1681 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret); 1687 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: write_page failed %d\n", ret);
1682 goto out; 1688 goto out;
1683 } 1689 }
1684 /* Next oob page */ 1690 /* Next oob page */
1685 oob += mtd->oobsize; 1691 oob += mtd->oobsize;
1686 /* Update written bytes count */ 1692 /* Update written bytes count */
1687 written += mtd->oobblock; 1693 written += mtd->oobblock;
1688 if (written == len) 1694 if (written == len)
1689 goto cmp; 1695 goto cmp;
1690 1696
1691 /* Increment page address */ 1697 /* Increment page address */
1692 page++; 1698 page++;
1693 1699
@@ -1698,13 +1704,13 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1698 if (!(page & (ppblock - 1))){ 1704 if (!(page & (ppblock - 1))){
1699 int ofs; 1705 int ofs;
1700 this->data_poi = bufstart; 1706 this->data_poi = bufstart;
1701 ret = nand_verify_pages (mtd, this, startpage, 1707 ret = nand_verify_pages (mtd, this, startpage,
1702 page - startpage, 1708 page - startpage,
1703 oobbuf, oobsel, chipnr, (eccbuf != NULL)); 1709 oobbuf, oobsel, chipnr, (eccbuf != NULL));
1704 if (ret) { 1710 if (ret) {
1705 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); 1711 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
1706 goto out; 1712 goto out;
1707 } 1713 }
1708 *retlen = written; 1714 *retlen = written;
1709 1715
1710 ofs = autoplace ? mtd->oobavail : mtd->oobsize; 1716 ofs = autoplace ? mtd->oobavail : mtd->oobsize;
@@ -1714,8 +1720,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
1714 numpages = min (totalpages, ppblock); 1720 numpages = min (totalpages, ppblock);
1715 page &= this->pagemask; 1721 page &= this->pagemask;
1716 startpage = page; 1722 startpage = page;
1717 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, 1723 oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
1718 autoplace, numpages); 1724 autoplace, numpages);
1725 oob = 0;
1719 /* Check, if we cross a chip boundary */ 1726 /* Check, if we cross a chip boundary */
1720 if (!page) { 1727 if (!page) {
1721 chipnr++; 1728 chipnr++;
@@ -1731,7 +1738,7 @@ cmp:
1731 oobbuf, oobsel, chipnr, (eccbuf != NULL)); 1738 oobbuf, oobsel, chipnr, (eccbuf != NULL));
1732 if (!ret) 1739 if (!ret)
1733 *retlen = written; 1740 *retlen = written;
1734 else 1741 else
1735 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret); 1742 DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: verify_pages failed %d\n", ret);
1736 1743
1737out: 1744out:
@@ -1791,7 +1798,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
1791 /* Check, if it is write protected */ 1798 /* Check, if it is write protected */
1792 if (nand_check_wp(mtd)) 1799 if (nand_check_wp(mtd))
1793 goto out; 1800 goto out;
1794 1801
1795 /* Invalidate the page cache, if we write to the cached page */ 1802 /* Invalidate the page cache, if we write to the cached page */
1796 if (page == this->pagebuf) 1803 if (page == this->pagebuf)
1797 this->pagebuf = -1; 1804 this->pagebuf = -1;
@@ -1854,10 +1861,10 @@ out:
1854 * 1861 *
1855 * NAND write with kvec. This just calls the ecc function 1862 * NAND write with kvec. This just calls the ecc function
1856 */ 1863 */
1857static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, 1864static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1858 loff_t to, size_t * retlen) 1865 loff_t to, size_t * retlen)
1859{ 1866{
1860 return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); 1867 return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL));
1861} 1868}
1862 1869
1863/** 1870/**
@@ -1872,7 +1879,7 @@ static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned
1872 * 1879 *
1873 * NAND write with iovec with ecc 1880 * NAND write with iovec with ecc
1874 */ 1881 */
1875static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, 1882static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1876 loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) 1883 loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
1877{ 1884{
1878 int i, page, len, total_len, ret = -EIO, written = 0, chipnr; 1885 int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
@@ -1898,7 +1905,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1898 return -EINVAL; 1905 return -EINVAL;
1899 } 1906 }
1900 1907
1901 /* reject writes, which are not page aligned */ 1908 /* reject writes, which are not page aligned */
1902 if (NOTALIGNED (to) || NOTALIGNED(total_len)) { 1909 if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
1903 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); 1910 printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
1904 return -EINVAL; 1911 return -EINVAL;
@@ -1917,21 +1924,21 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1917 goto out; 1924 goto out;
1918 1925
1919 /* if oobsel is NULL, use chip defaults */ 1926 /* if oobsel is NULL, use chip defaults */
1920 if (oobsel == NULL) 1927 if (oobsel == NULL)
1921 oobsel = &mtd->oobinfo; 1928 oobsel = &mtd->oobinfo;
1922 1929
1923 /* Autoplace of oob data ? Use the default placement scheme */ 1930 /* Autoplace of oob data ? Use the default placement scheme */
1924 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { 1931 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
1925 oobsel = this->autooob; 1932 oobsel = this->autooob;
1926 autoplace = 1; 1933 autoplace = 1;
1927 } 1934 }
1928 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) 1935 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1929 autoplace = 1; 1936 autoplace = 1;
1930 1937
1931 /* Setup start page */ 1938 /* Setup start page */
1932 page = (int) (to >> this->page_shift); 1939 page = (int) (to >> this->page_shift);
1933 /* Invalidate the page cache, if we write to the cached page */ 1940 /* Invalidate the page cache, if we write to the cached page */
1934 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) 1941 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
1935 this->pagebuf = -1; 1942 this->pagebuf = -1;
1936 1943
1937 startpage = page & this->pagemask; 1944 startpage = page & this->pagemask;
@@ -1955,10 +1962,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1955 oob = 0; 1962 oob = 0;
1956 for (i = 1; i <= numpages; i++) { 1963 for (i = 1; i <= numpages; i++) {
1957 /* Write one page. If this is the last page to write 1964 /* Write one page. If this is the last page to write
1958 * then use the real pageprogram command, else select 1965 * then use the real pageprogram command, else select
1959 * cached programming if supported by the chip. 1966 * cached programming if supported by the chip.
1960 */ 1967 */
1961 ret = nand_write_page (mtd, this, page & this->pagemask, 1968 ret = nand_write_page (mtd, this, page & this->pagemask,
1962 &oobbuf[oob], oobsel, i != numpages); 1969 &oobbuf[oob], oobsel, i != numpages);
1963 if (ret) 1970 if (ret)
1964 goto out; 1971 goto out;
@@ -1974,12 +1981,12 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1974 count--; 1981 count--;
1975 } 1982 }
1976 } else { 1983 } else {
1977 /* We must use the internal buffer, read data out of each 1984 /* We must use the internal buffer, read data out of each
1978 * tuple until we have a full page to write 1985 * tuple until we have a full page to write
1979 */ 1986 */
1980 int cnt = 0; 1987 int cnt = 0;
1981 while (cnt < mtd->oobblock) { 1988 while (cnt < mtd->oobblock) {
1982 if (vecs->iov_base != NULL && vecs->iov_len) 1989 if (vecs->iov_base != NULL && vecs->iov_len)
1983 this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; 1990 this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
1984 /* Check, if we have to switch to the next tuple */ 1991 /* Check, if we have to switch to the next tuple */
1985 if (len >= (int) vecs->iov_len) { 1992 if (len >= (int) vecs->iov_len) {
@@ -1988,10 +1995,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
1988 count--; 1995 count--;
1989 } 1996 }
1990 } 1997 }
1991 this->pagebuf = page; 1998 this->pagebuf = page;
1992 this->data_poi = this->data_buf; 1999 this->data_poi = this->data_buf;
1993 bufstart = this->data_poi; 2000 bufstart = this->data_poi;
1994 numpages = 1; 2001 numpages = 1;
1995 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); 2002 oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
1996 ret = nand_write_page (mtd, this, page & this->pagemask, 2003 ret = nand_write_page (mtd, this, page & this->pagemask,
1997 oobbuf, oobsel, 0); 2004 oobbuf, oobsel, 0);
@@ -2004,7 +2011,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
2004 ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); 2011 ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
2005 if (ret) 2012 if (ret)
2006 goto out; 2013 goto out;
2007 2014
2008 written += mtd->oobblock * numpages; 2015 written += mtd->oobblock * numpages;
2009 /* All done ? */ 2016 /* All done ? */
2010 if (!count) 2017 if (!count)
@@ -2072,7 +2079,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
2072{ 2079{
2073 return nand_erase_nand (mtd, instr, 0); 2080 return nand_erase_nand (mtd, instr, 0);
2074} 2081}
2075 2082
2076#define BBT_PAGE_MASK 0xffffff3f 2083#define BBT_PAGE_MASK 0xffffff3f
2077/** 2084/**
2078 * nand_erase_intern - [NAND Interface] erase block(s) 2085 * nand_erase_intern - [NAND Interface] erase block(s)
@@ -2154,14 +2161,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2154 instr->state = MTD_ERASE_FAILED; 2161 instr->state = MTD_ERASE_FAILED;
2155 goto erase_exit; 2162 goto erase_exit;
2156 } 2163 }
2157 2164
2158 /* Invalidate the page cache, if we erase the block which contains 2165 /* Invalidate the page cache, if we erase the block which contains
2159 the current cached page */ 2166 the current cached page */
2160 if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) 2167 if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block))
2161 this->pagebuf = -1; 2168 this->pagebuf = -1;
2162 2169
2163 this->erase_cmd (mtd, page & this->pagemask); 2170 this->erase_cmd (mtd, page & this->pagemask);
2164 2171
2165 status = this->waitfunc (mtd, this, FL_ERASING); 2172 status = this->waitfunc (mtd, this, FL_ERASING);
2166 2173
2167 /* See if operation failed and additional status checks are available */ 2174 /* See if operation failed and additional status checks are available */
@@ -2179,12 +2186,12 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2179 2186
2180 /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */ 2187 /* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
2181 if (this->options & BBT_AUTO_REFRESH) { 2188 if (this->options & BBT_AUTO_REFRESH) {
2182 if (((page & BBT_PAGE_MASK) == bbt_masked_page) && 2189 if (((page & BBT_PAGE_MASK) == bbt_masked_page) &&
2183 (page != this->bbt_td->pages[chipnr])) { 2190 (page != this->bbt_td->pages[chipnr])) {
2184 rewrite_bbt[chipnr] = (page << this->page_shift); 2191 rewrite_bbt[chipnr] = (page << this->page_shift);
2185 } 2192 }
2186 } 2193 }
2187 2194
2188 /* Increment page address and decrement length */ 2195 /* Increment page address and decrement length */
2189 len -= (1 << this->phys_erase_shift); 2196 len -= (1 << this->phys_erase_shift);
2190 page += pages_per_block; 2197 page += pages_per_block;
@@ -2195,7 +2202,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
2195 this->select_chip(mtd, -1); 2202 this->select_chip(mtd, -1);
2196 this->select_chip(mtd, chipnr); 2203 this->select_chip(mtd, chipnr);
2197 2204
2198 /* if BBT requires refresh and BBT-PERCHIP, 2205 /* if BBT requires refresh and BBT-PERCHIP,
2199 * set the BBT page mask to see if this BBT should be rewritten */ 2206 * set the BBT page mask to see if this BBT should be rewritten */
2200 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) { 2207 if ((this->options & BBT_AUTO_REFRESH) && (this->bbt_td->options & NAND_BBT_PERCHIP)) {
2201 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK; 2208 bbt_masked_page = this->bbt_td->pages[chipnr] & BBT_PAGE_MASK;
@@ -2220,7 +2227,7 @@ erase_exit:
2220 for (chipnr = 0; chipnr < this->numchips; chipnr++) { 2227 for (chipnr = 0; chipnr < this->numchips; chipnr++) {
2221 if (rewrite_bbt[chipnr]) { 2228 if (rewrite_bbt[chipnr]) {
2222 /* update the BBT for chip */ 2229 /* update the BBT for chip */
2223 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n", 2230 DEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)\n",
2224 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]); 2231 chipnr, rewrite_bbt[chipnr], this->bbt_td->pages[chipnr]);
2225 nand_update_bbt (mtd, rewrite_bbt[chipnr]); 2232 nand_update_bbt (mtd, rewrite_bbt[chipnr]);
2226 } 2233 }
@@ -2258,9 +2265,9 @@ static void nand_sync (struct mtd_info *mtd)
2258static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) 2265static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs)
2259{ 2266{
2260 /* Check for invalid offset */ 2267 /* Check for invalid offset */
2261 if (ofs > mtd->size) 2268 if (ofs > mtd->size)
2262 return -EINVAL; 2269 return -EINVAL;
2263 2270
2264 return nand_block_checkbad (mtd, ofs, 1, 0); 2271 return nand_block_checkbad (mtd, ofs, 1, 0);
2265} 2272}
2266 2273
@@ -2285,6 +2292,34 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs)
2285} 2292}
2286 2293
2287/** 2294/**
2295 * nand_suspend - [MTD Interface] Suspend the NAND flash
2296 * @mtd: MTD device structure
2297 */
2298static int nand_suspend(struct mtd_info *mtd)
2299{
2300 struct nand_chip *this = mtd->priv;
2301
2302 return nand_get_device (this, mtd, FL_PM_SUSPENDED);
2303}
2304
2305/**
2306 * nand_resume - [MTD Interface] Resume the NAND flash
2307 * @mtd: MTD device structure
2308 */
2309static void nand_resume(struct mtd_info *mtd)
2310{
2311 struct nand_chip *this = mtd->priv;
2312
2313 if (this->state == FL_PM_SUSPENDED)
2314 nand_release_device(mtd);
2315 else
2316 printk(KERN_ERR "resume() called for the chip which is not "
2317 "in suspended state\n");
2318
2319}
2320
2321
2322/**
2288 * nand_scan - [NAND Interface] Scan for the NAND device 2323 * nand_scan - [NAND Interface] Scan for the NAND device
2289 * @mtd: MTD device structure 2324 * @mtd: MTD device structure
2290 * @maxchips: Number of chips to scan for 2325 * @maxchips: Number of chips to scan for
@@ -2351,13 +2386,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2351 2386
2352 /* Print and store flash device information */ 2387 /* Print and store flash device information */
2353 for (i = 0; nand_flash_ids[i].name != NULL; i++) { 2388 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
2354 2389
2355 if (nand_dev_id != nand_flash_ids[i].id) 2390 if (nand_dev_id != nand_flash_ids[i].id)
2356 continue; 2391 continue;
2357 2392
2358 if (!mtd->name) mtd->name = nand_flash_ids[i].name; 2393 if (!mtd->name) mtd->name = nand_flash_ids[i].name;
2359 this->chipsize = nand_flash_ids[i].chipsize << 20; 2394 this->chipsize = nand_flash_ids[i].chipsize << 20;
2360 2395
2361 /* New devices have all the information in additional id bytes */ 2396 /* New devices have all the information in additional id bytes */
2362 if (!nand_flash_ids[i].pagesize) { 2397 if (!nand_flash_ids[i].pagesize) {
2363 int extid; 2398 int extid;
@@ -2369,14 +2404,14 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2369 mtd->oobblock = 1024 << (extid & 0x3); 2404 mtd->oobblock = 1024 << (extid & 0x3);
2370 extid >>= 2; 2405 extid >>= 2;
2371 /* Calc oobsize */ 2406 /* Calc oobsize */
2372 mtd->oobsize = (8 << (extid & 0x03)) * (mtd->oobblock / 512); 2407 mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock >> 9);
2373 extid >>= 2; 2408 extid >>= 2;
2374 /* Calc blocksize. Blocksize is multiples of 64KiB */ 2409 /* Calc blocksize. Blocksize is multiples of 64KiB */
2375 mtd->erasesize = (64 * 1024) << (extid & 0x03); 2410 mtd->erasesize = (64 * 1024) << (extid & 0x03);
2376 extid >>= 2; 2411 extid >>= 2;
2377 /* Get buswidth information */ 2412 /* Get buswidth information */
2378 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; 2413 busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
2379 2414
2380 } else { 2415 } else {
2381 /* Old devices have this data hardcoded in the 2416 /* Old devices have this data hardcoded in the
2382 * device id table */ 2417 * device id table */
@@ -2396,23 +2431,23 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2396 * this correct ! */ 2431 * this correct ! */
2397 if (busw != (this->options & NAND_BUSWIDTH_16)) { 2432 if (busw != (this->options & NAND_BUSWIDTH_16)) {
2398 printk (KERN_INFO "NAND device: Manufacturer ID:" 2433 printk (KERN_INFO "NAND device: Manufacturer ID:"
2399 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 2434 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
2400 nand_manuf_ids[maf_id].name , mtd->name); 2435 nand_manuf_ids[maf_id].name , mtd->name);
2401 printk (KERN_WARNING 2436 printk (KERN_WARNING
2402 "NAND bus width %d instead %d bit\n", 2437 "NAND bus width %d instead %d bit\n",
2403 (this->options & NAND_BUSWIDTH_16) ? 16 : 8, 2438 (this->options & NAND_BUSWIDTH_16) ? 16 : 8,
2404 busw ? 16 : 8); 2439 busw ? 16 : 8);
2405 this->select_chip(mtd, -1); 2440 this->select_chip(mtd, -1);
2406 return 1; 2441 return 1;
2407 } 2442 }
2408 2443
2409 /* Calculate the address shift from the page size */ 2444 /* Calculate the address shift from the page size */
2410 this->page_shift = ffs(mtd->oobblock) - 1; 2445 this->page_shift = ffs(mtd->oobblock) - 1;
2411 this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; 2446 this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1;
2412 this->chip_shift = ffs(this->chipsize) - 1; 2447 this->chip_shift = ffs(this->chipsize) - 1;
2413 2448
2414 /* Set the bad block position */ 2449 /* Set the bad block position */
2415 this->badblockpos = mtd->oobblock > 512 ? 2450 this->badblockpos = mtd->oobblock > 512 ?
2416 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; 2451 NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS;
2417 2452
2418 /* Get chip options, preserve non chip based options */ 2453 /* Get chip options, preserve non chip based options */
@@ -2422,10 +2457,10 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2422 this->options |= NAND_NO_AUTOINCR; 2457 this->options |= NAND_NO_AUTOINCR;
2423 /* Check if this is a not a samsung device. Do not clear the options 2458 /* Check if this is a not a samsung device. Do not clear the options
2424 * for chips which are not having an extended id. 2459 * for chips which are not having an extended id.
2425 */ 2460 */
2426 if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) 2461 if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize)
2427 this->options &= ~NAND_SAMSUNG_LP_OPTIONS; 2462 this->options &= ~NAND_SAMSUNG_LP_OPTIONS;
2428 2463
2429 /* Check for AND chips with 4 page planes */ 2464 /* Check for AND chips with 4 page planes */
2430 if (this->options & NAND_4PAGE_ARRAY) 2465 if (this->options & NAND_4PAGE_ARRAY)
2431 this->erase_cmd = multi_erase_cmd; 2466 this->erase_cmd = multi_erase_cmd;
@@ -2435,9 +2470,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2435 /* Do not replace user supplied command function ! */ 2470 /* Do not replace user supplied command function ! */
2436 if (mtd->oobblock > 512 && this->cmdfunc == nand_command) 2471 if (mtd->oobblock > 512 && this->cmdfunc == nand_command)
2437 this->cmdfunc = nand_command_lp; 2472 this->cmdfunc = nand_command_lp;
2438 2473
2439 printk (KERN_INFO "NAND device: Manufacturer ID:" 2474 printk (KERN_INFO "NAND device: Manufacturer ID:"
2440 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, 2475 " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
2441 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name); 2476 nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);
2442 break; 2477 break;
2443 } 2478 }
@@ -2461,7 +2496,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2461 } 2496 }
2462 if (i > 1) 2497 if (i > 1)
2463 printk(KERN_INFO "%d NAND chips detected\n", i); 2498 printk(KERN_INFO "%d NAND chips detected\n", i);
2464 2499
2465 /* Allocate buffers, if neccecary */ 2500 /* Allocate buffers, if neccecary */
2466 if (!this->oob_buf) { 2501 if (!this->oob_buf) {
2467 size_t len; 2502 size_t len;
@@ -2473,7 +2508,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2473 } 2508 }
2474 this->options |= NAND_OOBBUF_ALLOC; 2509 this->options |= NAND_OOBBUF_ALLOC;
2475 } 2510 }
2476 2511
2477 if (!this->data_buf) { 2512 if (!this->data_buf) {
2478 size_t len; 2513 size_t len;
2479 len = mtd->oobblock + mtd->oobsize; 2514 len = mtd->oobblock + mtd->oobsize;
@@ -2500,7 +2535,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2500 if (!this->autooob) { 2535 if (!this->autooob) {
2501 /* Select the appropriate default oob placement scheme for 2536 /* Select the appropriate default oob placement scheme for
2502 * placement agnostic filesystems */ 2537 * placement agnostic filesystems */
2503 switch (mtd->oobsize) { 2538 switch (mtd->oobsize) {
2504 case 8: 2539 case 8:
2505 this->autooob = &nand_oob_8; 2540 this->autooob = &nand_oob_8;
2506 break; 2541 break;
@@ -2516,19 +2551,19 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2516 BUG(); 2551 BUG();
2517 } 2552 }
2518 } 2553 }
2519 2554
2520 /* The number of bytes available for the filesystem to place fs dependend 2555 /* The number of bytes available for the filesystem to place fs dependend
2521 * oob data */ 2556 * oob data */
2522 mtd->oobavail = 0; 2557 mtd->oobavail = 0;
2523 for (i = 0; this->autooob->oobfree[i][1]; i++) 2558 for (i = 0; this->autooob->oobfree[i][1]; i++)
2524 mtd->oobavail += this->autooob->oobfree[i][1]; 2559 mtd->oobavail += this->autooob->oobfree[i][1];
2525 2560
2526 /* 2561 /*
2527 * check ECC mode, default to software 2562 * check ECC mode, default to software
2528 * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize 2563 * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
2529 * fallback to software ECC 2564 * fallback to software ECC
2530 */ 2565 */
2531 this->eccsize = 256; /* set default eccsize */ 2566 this->eccsize = 256; /* set default eccsize */
2532 this->eccbytes = 3; 2567 this->eccbytes = 3;
2533 2568
2534 switch (this->eccmode) { 2569 switch (this->eccmode) {
@@ -2543,56 +2578,56 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2543 this->eccsize = 2048; 2578 this->eccsize = 2048;
2544 break; 2579 break;
2545 2580
2546 case NAND_ECC_HW3_512: 2581 case NAND_ECC_HW3_512:
2547 case NAND_ECC_HW6_512: 2582 case NAND_ECC_HW6_512:
2548 case NAND_ECC_HW8_512: 2583 case NAND_ECC_HW8_512:
2549 if (mtd->oobblock == 256) { 2584 if (mtd->oobblock == 256) {
2550 printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); 2585 printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
2551 this->eccmode = NAND_ECC_SOFT; 2586 this->eccmode = NAND_ECC_SOFT;
2552 this->calculate_ecc = nand_calculate_ecc; 2587 this->calculate_ecc = nand_calculate_ecc;
2553 this->correct_data = nand_correct_data; 2588 this->correct_data = nand_correct_data;
2554 } else 2589 } else
2555 this->eccsize = 512; /* set eccsize to 512 */ 2590 this->eccsize = 512; /* set eccsize to 512 */
2556 break; 2591 break;
2557 2592
2558 case NAND_ECC_HW3_256: 2593 case NAND_ECC_HW3_256:
2559 break; 2594 break;
2560 2595
2561 case NAND_ECC_NONE: 2596 case NAND_ECC_NONE:
2562 printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); 2597 printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
2563 this->eccmode = NAND_ECC_NONE; 2598 this->eccmode = NAND_ECC_NONE;
2564 break; 2599 break;
2565 2600
2566 case NAND_ECC_SOFT: 2601 case NAND_ECC_SOFT:
2567 this->calculate_ecc = nand_calculate_ecc; 2602 this->calculate_ecc = nand_calculate_ecc;
2568 this->correct_data = nand_correct_data; 2603 this->correct_data = nand_correct_data;
2569 break; 2604 break;
2570 2605
2571 default: 2606 default:
2572 printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); 2607 printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode);
2573 BUG(); 2608 BUG();
2574 } 2609 }
2575 2610
2576 /* Check hardware ecc function availability and adjust number of ecc bytes per 2611 /* Check hardware ecc function availability and adjust number of ecc bytes per
2577 * calculation step 2612 * calculation step
2578 */ 2613 */
2579 switch (this->eccmode) { 2614 switch (this->eccmode) {
2580 case NAND_ECC_HW12_2048: 2615 case NAND_ECC_HW12_2048:
2581 this->eccbytes += 4; 2616 this->eccbytes += 4;
2582 case NAND_ECC_HW8_512: 2617 case NAND_ECC_HW8_512:
2583 this->eccbytes += 2; 2618 this->eccbytes += 2;
2584 case NAND_ECC_HW6_512: 2619 case NAND_ECC_HW6_512:
2585 this->eccbytes += 3; 2620 this->eccbytes += 3;
2586 case NAND_ECC_HW3_512: 2621 case NAND_ECC_HW3_512:
2587 case NAND_ECC_HW3_256: 2622 case NAND_ECC_HW3_256:
2588 if (this->calculate_ecc && this->correct_data && this->enable_hwecc) 2623 if (this->calculate_ecc && this->correct_data && this->enable_hwecc)
2589 break; 2624 break;
2590 printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); 2625 printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n");
2591 BUG(); 2626 BUG();
2592 } 2627 }
2593 2628
2594 mtd->eccsize = this->eccsize; 2629 mtd->eccsize = this->eccsize;
2595 2630
2596 /* Set the number of read / write steps for one page to ensure ECC generation */ 2631 /* Set the number of read / write steps for one page to ensure ECC generation */
2597 switch (this->eccmode) { 2632 switch (this->eccmode) {
2598 case NAND_ECC_HW12_2048: 2633 case NAND_ECC_HW12_2048:
@@ -2604,15 +2639,15 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2604 this->eccsteps = mtd->oobblock / 512; 2639 this->eccsteps = mtd->oobblock / 512;
2605 break; 2640 break;
2606 case NAND_ECC_HW3_256: 2641 case NAND_ECC_HW3_256:
2607 case NAND_ECC_SOFT: 2642 case NAND_ECC_SOFT:
2608 this->eccsteps = mtd->oobblock / 256; 2643 this->eccsteps = mtd->oobblock / 256;
2609 break; 2644 break;
2610 2645
2611 case NAND_ECC_NONE: 2646 case NAND_ECC_NONE:
2612 this->eccsteps = 1; 2647 this->eccsteps = 1;
2613 break; 2648 break;
2614 } 2649 }
2615 2650
2616 /* Initialize state, waitqueue and spinlock */ 2651 /* Initialize state, waitqueue and spinlock */
2617 this->state = FL_READY; 2652 this->state = FL_READY;
2618 init_waitqueue_head (&this->wq); 2653 init_waitqueue_head (&this->wq);
@@ -2643,8 +2678,8 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2643 mtd->sync = nand_sync; 2678 mtd->sync = nand_sync;
2644 mtd->lock = NULL; 2679 mtd->lock = NULL;
2645 mtd->unlock = NULL; 2680 mtd->unlock = NULL;
2646 mtd->suspend = NULL; 2681 mtd->suspend = nand_suspend;
2647 mtd->resume = NULL; 2682 mtd->resume = nand_resume;
2648 mtd->block_isbad = nand_block_isbad; 2683 mtd->block_isbad = nand_block_isbad;
2649 mtd->block_markbad = nand_block_markbad; 2684 mtd->block_markbad = nand_block_markbad;
2650 2685
@@ -2652,7 +2687,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2652 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); 2687 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
2653 2688
2654 mtd->owner = THIS_MODULE; 2689 mtd->owner = THIS_MODULE;
2655 2690
2656 /* Check, if we should skip the bad block table scan */ 2691 /* Check, if we should skip the bad block table scan */
2657 if (this->options & NAND_SKIP_BBTSCAN) 2692 if (this->options & NAND_SKIP_BBTSCAN)
2658 return 0; 2693 return 0;
@@ -2662,7 +2697,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
2662} 2697}
2663 2698
2664/** 2699/**
2665 * nand_release - [NAND Interface] Free resources held by the NAND device 2700 * nand_release - [NAND Interface] Free resources held by the NAND device
2666 * @mtd: MTD device structure 2701 * @mtd: MTD device structure
2667*/ 2702*/
2668void nand_release (struct mtd_info *mtd) 2703void nand_release (struct mtd_info *mtd)
@@ -2676,9 +2711,8 @@ void nand_release (struct mtd_info *mtd)
2676 /* Deregister the device */ 2711 /* Deregister the device */
2677 del_mtd_device (mtd); 2712 del_mtd_device (mtd);
2678 2713
2679 /* Free bad block table memory, if allocated */ 2714 /* Free bad block table memory */
2680 if (this->bbt) 2715 kfree (this->bbt);
2681 kfree (this->bbt);
2682 /* Buffer allocated by nand_scan ? */ 2716 /* Buffer allocated by nand_scan ? */
2683 if (this->options & NAND_OOBBUF_ALLOC) 2717 if (this->options & NAND_OOBBUF_ALLOC)
2684 kfree (this->oob_buf); 2718 kfree (this->oob_buf);
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 7535ef53685e..ca286999fe08 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -3,10 +3,10 @@
3 * 3 *
4 * Overview: 4 * Overview:
5 * Bad block table support for the NAND driver 5 * Bad block table support for the NAND driver
6 * 6 *
7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) 7 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
8 * 8 *
9 * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $ 9 * $Id: nand_bbt.c,v 1.36 2005/11/07 11:14:30 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -14,23 +14,23 @@
14 * 14 *
15 * Description: 15 * Description:
16 * 16 *
17 * When nand_scan_bbt is called, then it tries to find the bad block table 17 * When nand_scan_bbt is called, then it tries to find the bad block table
18 * depending on the options in the bbt descriptor(s). If a bbt is found 18 * depending on the options in the bbt descriptor(s). If a bbt is found
19 * then the contents are read and the memory based bbt is created. If a 19 * then the contents are read and the memory based bbt is created. If a
20 * mirrored bbt is selected then the mirror is searched too and the 20 * mirrored bbt is selected then the mirror is searched too and the
21 * versions are compared. If the mirror has a greater version number 21 * versions are compared. If the mirror has a greater version number
22 * than the mirror bbt is used to build the memory based bbt. 22 * than the mirror bbt is used to build the memory based bbt.
23 * If the tables are not versioned, then we "or" the bad block information. 23 * If the tables are not versioned, then we "or" the bad block information.
24 * If one of the bbt's is out of date or does not exist it is (re)created. 24 * If one of the bbt's is out of date or does not exist it is (re)created.
25 * If no bbt exists at all then the device is scanned for factory marked 25 * If no bbt exists at all then the device is scanned for factory marked
26 * good / bad blocks and the bad block tables are created. 26 * good / bad blocks and the bad block tables are created.
27 * 27 *
28 * For manufacturer created bbts like the one found on M-SYS DOC devices 28 * For manufacturer created bbts like the one found on M-SYS DOC devices
29 * the bbt is searched and read but never created 29 * the bbt is searched and read but never created
30 * 30 *
31 * The autogenerated bad block table is located in the last good blocks 31 * The autogenerated bad block table is located in the last good blocks
32 * of the device. The table is mirrored, so it can be updated eventually. 32 * of the device. The table is mirrored, so it can be updated eventually.
33 * The table is marked in the oob area with an ident pattern and a version 33 * The table is marked in the oob area with an ident pattern and a version
34 * number which indicates which of both tables is more up to date. 34 * number which indicates which of both tables is more up to date.
35 * 35 *
36 * The table uses 2 bits per block 36 * The table uses 2 bits per block
@@ -43,13 +43,13 @@
43 * 01b: block is marked bad due to wear 43 * 01b: block is marked bad due to wear
44 * 10b: block is reserved (to protect the bbt area) 44 * 10b: block is reserved (to protect the bbt area)
45 * 11b: block is factory marked bad 45 * 11b: block is factory marked bad
46 * 46 *
47 * Multichip devices like DOC store the bad block info per floor. 47 * Multichip devices like DOC store the bad block info per floor.
48 * 48 *
49 * Following assumptions are made: 49 * Following assumptions are made:
50 * - bbts start at a page boundary, if autolocated on a block boundary 50 * - bbts start at a page boundary, if autolocated on a block boundary
51 * - the space neccecary for a bbt in FLASH does not exceed a block boundary 51 * - the space neccecary for a bbt in FLASH does not exceed a block boundary
52 * 52 *
53 */ 53 */
54 54
55#include <linux/slab.h> 55#include <linux/slab.h>
@@ -62,7 +62,7 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63 63
64 64
65/** 65/**
66 * check_pattern - [GENERIC] check if a pattern is in the buffer 66 * check_pattern - [GENERIC] check if a pattern is in the buffer
67 * @buf: the buffer to search 67 * @buf: the buffer to search
68 * @len: the length of buffer to search 68 * @len: the length of buffer to search
@@ -86,9 +86,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
86 if (p[i] != 0xff) 86 if (p[i] != 0xff)
87 return -1; 87 return -1;
88 } 88 }
89 } 89 }
90 p += end; 90 p += end;
91 91
92 /* Compare the pattern */ 92 /* Compare the pattern */
93 for (i = 0; i < td->len; i++) { 93 for (i = 0; i < td->len; i++) {
94 if (p[i] != td->pattern[i]) 94 if (p[i] != td->pattern[i])
@@ -106,13 +106,13 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
106 return 0; 106 return 0;
107} 107}
108 108
109/** 109/**
110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer 110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
111 * @buf: the buffer to search 111 * @buf: the buffer to search
112 * @td: search pattern descriptor 112 * @td: search pattern descriptor
113 * 113 *
114 * Check for a pattern at the given place. Used to search bad block 114 * Check for a pattern at the given place. Used to search bad block
115 * tables and good / bad block identifiers. Same as check_pattern, but 115 * tables and good / bad block identifiers. Same as check_pattern, but
116 * no optional empty check 116 * no optional empty check
117 * 117 *
118*/ 118*/
@@ -142,7 +142,7 @@ static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
142 * Read the bad block table starting from page. 142 * Read the bad block table starting from page.
143 * 143 *
144 */ 144 */
145static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, 145static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
146 int bits, int offs, int reserved_block_code) 146 int bits, int offs, int reserved_block_code)
147{ 147{
148 int res, i, j, act = 0; 148 int res, i, j, act = 0;
@@ -153,7 +153,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
153 153
154 totlen = (num * bits) >> 3; 154 totlen = (num * bits) >> 3;
155 from = ((loff_t)page) << this->page_shift; 155 from = ((loff_t)page) << this->page_shift;
156 156
157 while (totlen) { 157 while (totlen) {
158 len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); 158 len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
159 res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); 159 res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
@@ -163,7 +163,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
163 return res; 163 return res;
164 } 164 }
165 printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); 165 printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
166 } 166 }
167 167
168 /* Analyse data */ 168 /* Analyse data */
169 for (i = 0; i < len; i++) { 169 for (i = 0; i < len; i++) {
@@ -183,12 +183,12 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
183 * message to MTD_DEBUG_LEVEL0 */ 183 * message to MTD_DEBUG_LEVEL0 */
184 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", 184 printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
185 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); 185 ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
186 /* Factory marked bad or worn out ? */ 186 /* Factory marked bad or worn out ? */
187 if (tmp == 0) 187 if (tmp == 0)
188 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); 188 this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
189 else 189 else
190 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); 190 this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
191 } 191 }
192 } 192 }
193 totlen -= len; 193 totlen -= len;
194 from += len; 194 from += len;
@@ -200,7 +200,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
200 * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page 200 * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
201 * @mtd: MTD device structure 201 * @mtd: MTD device structure
202 * @buf: temporary buffer 202 * @buf: temporary buffer
203 * @td: descriptor for the bad block table 203 * @td: descriptor for the bad block table
204 * @chip: read the table for a specific chip, -1 read all chips. 204 * @chip: read the table for a specific chip, -1 read all chips.
205 * Applies only if NAND_BBT_PERCHIP option is set 205 * Applies only if NAND_BBT_PERCHIP option is set
206 * 206 *
@@ -235,7 +235,7 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
235 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page 235 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
236 * @mtd: MTD device structure 236 * @mtd: MTD device structure
237 * @buf: temporary buffer 237 * @buf: temporary buffer
238 * @td: descriptor for the bad block table 238 * @td: descriptor for the bad block table
239 * @md: descriptor for the bad block table mirror 239 * @md: descriptor for the bad block table mirror
240 * 240 *
241 * Read the bad block table(s) for all chips starting at a given page 241 * Read the bad block table(s) for all chips starting at a given page
@@ -247,16 +247,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
247{ 247{
248 struct nand_chip *this = mtd->priv; 248 struct nand_chip *this = mtd->priv;
249 249
250 /* Read the primary version, if available */ 250 /* Read the primary version, if available */
251 if (td->options & NAND_BBT_VERSION) { 251 if (td->options & NAND_BBT_VERSION) {
252 nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); 252 nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
253 td->version[0] = buf[mtd->oobblock + td->veroffs]; 253 td->version[0] = buf[mtd->oobblock + td->veroffs];
254 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); 254 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
255 } 255 }
256 256
257 /* Read the mirror version, if available */ 257 /* Read the mirror version, if available */
258 if (md && (md->options & NAND_BBT_VERSION)) { 258 if (md && (md->options & NAND_BBT_VERSION)) {
259 nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); 259 nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
260 md->version[0] = buf[mtd->oobblock + md->veroffs]; 260 md->version[0] = buf[mtd->oobblock + md->veroffs];
261 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); 261 printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
262 } 262 }
@@ -290,7 +290,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
290 else { 290 else {
291 if (bd->options & NAND_BBT_SCAN2NDPAGE) 291 if (bd->options & NAND_BBT_SCAN2NDPAGE)
292 len = 2; 292 len = 2;
293 else 293 else
294 len = 1; 294 len = 1;
295 } 295 }
296 296
@@ -322,10 +322,10 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
322 numblocks += startblock; 322 numblocks += startblock;
323 from = startblock << (this->bbt_erase_shift - 1); 323 from = startblock << (this->bbt_erase_shift - 1);
324 } 324 }
325 325
326 for (i = startblock; i < numblocks;) { 326 for (i = startblock; i < numblocks;) {
327 int ret; 327 int ret;
328 328
329 if (bd->options & NAND_BBT_SCANEMPTY) 329 if (bd->options & NAND_BBT_SCANEMPTY)
330 if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen))) 330 if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
331 return ret; 331 return ret;
@@ -333,8 +333,8 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
333 for (j = 0; j < len; j++) { 333 for (j = 0; j < len; j++) {
334 if (!(bd->options & NAND_BBT_SCANEMPTY)) { 334 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
335 size_t retlen; 335 size_t retlen;
336 336
337 /* Read the full oob until read_oob is fixed to 337 /* Read the full oob until read_oob is fixed to
338 * handle single byte reads for 16 bit buswidth */ 338 * handle single byte reads for 16 bit buswidth */
339 ret = mtd->read_oob(mtd, from + j * mtd->oobblock, 339 ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
340 mtd->oobsize, &retlen, buf); 340 mtd->oobsize, &retlen, buf);
@@ -343,14 +343,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
343 343
344 if (check_short_pattern (buf, bd)) { 344 if (check_short_pattern (buf, bd)) {
345 this->bbt[i >> 3] |= 0x03 << (i & 0x6); 345 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
346 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 346 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
347 i >> 1, (unsigned int) from); 347 i >> 1, (unsigned int) from);
348 break; 348 break;
349 } 349 }
350 } else { 350 } else {
351 if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { 351 if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
352 this->bbt[i >> 3] |= 0x03 << (i & 0x6); 352 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
353 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 353 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
354 i >> 1, (unsigned int) from); 354 i >> 1, (unsigned int) from);
355 break; 355 break;
356 } 356 }
@@ -369,15 +369,15 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
369 * @td: descriptor for the bad block table 369 * @td: descriptor for the bad block table
370 * 370 *
371 * Read the bad block table by searching for a given ident pattern. 371 * Read the bad block table by searching for a given ident pattern.
372 * Search is preformed either from the beginning up or from the end of 372 * Search is preformed either from the beginning up or from the end of
373 * the device downwards. The search starts always at the start of a 373 * the device downwards. The search starts always at the start of a
374 * block. 374 * block.
375 * If the option NAND_BBT_PERCHIP is given, each chip is searched 375 * If the option NAND_BBT_PERCHIP is given, each chip is searched
376 * for a bbt, which contains the bad block information of this chip. 376 * for a bbt, which contains the bad block information of this chip.
377 * This is neccecary to provide support for certain DOC devices. 377 * This is neccecary to provide support for certain DOC devices.
378 * 378 *
379 * The bbt ident pattern resides in the oob area of the first page 379 * The bbt ident pattern resides in the oob area of the first page
380 * in a block. 380 * in a block.
381 */ 381 */
382static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) 382static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
383{ 383{
@@ -392,10 +392,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
392 startblock = (mtd->size >> this->bbt_erase_shift) -1; 392 startblock = (mtd->size >> this->bbt_erase_shift) -1;
393 dir = -1; 393 dir = -1;
394 } else { 394 } else {
395 startblock = 0; 395 startblock = 0;
396 dir = 1; 396 dir = 1;
397 } 397 }
398 398
399 /* Do we have a bbt per chip ? */ 399 /* Do we have a bbt per chip ? */
400 if (td->options & NAND_BBT_PERCHIP) { 400 if (td->options & NAND_BBT_PERCHIP) {
401 chips = this->numchips; 401 chips = this->numchips;
@@ -405,19 +405,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
405 chips = 1; 405 chips = 1;
406 bbtblocks = mtd->size >> this->bbt_erase_shift; 406 bbtblocks = mtd->size >> this->bbt_erase_shift;
407 } 407 }
408 408
409 /* Number of bits for each erase block in the bbt */ 409 /* Number of bits for each erase block in the bbt */
410 bits = td->options & NAND_BBT_NRBITS_MSK; 410 bits = td->options & NAND_BBT_NRBITS_MSK;
411 411
412 for (i = 0; i < chips; i++) { 412 for (i = 0; i < chips; i++) {
413 /* Reset version information */ 413 /* Reset version information */
414 td->version[i] = 0; 414 td->version[i] = 0;
415 td->pages[i] = -1; 415 td->pages[i] = -1;
416 /* Scan the maximum number of blocks */ 416 /* Scan the maximum number of blocks */
417 for (block = 0; block < td->maxblocks; block++) { 417 for (block = 0; block < td->maxblocks; block++) {
418 int actblock = startblock + dir * block; 418 int actblock = startblock + dir * block;
419 /* Read first page */ 419 /* Read first page */
420 nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); 420 nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
421 if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { 421 if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
422 td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); 422 td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
423 if (td->options & NAND_BBT_VERSION) { 423 if (td->options & NAND_BBT_VERSION) {
@@ -435,46 +435,46 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
435 else 435 else
436 printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); 436 printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
437 } 437 }
438 return 0; 438 return 0;
439} 439}
440 440
441/** 441/**
442 * search_read_bbts - [GENERIC] scan the device for bad block table(s) 442 * search_read_bbts - [GENERIC] scan the device for bad block table(s)
443 * @mtd: MTD device structure 443 * @mtd: MTD device structure
444 * @buf: temporary buffer 444 * @buf: temporary buffer
445 * @td: descriptor for the bad block table 445 * @td: descriptor for the bad block table
446 * @md: descriptor for the bad block table mirror 446 * @md: descriptor for the bad block table mirror
447 * 447 *
448 * Search and read the bad block table(s) 448 * Search and read the bad block table(s)
449*/ 449*/
450static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, 450static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
451 struct nand_bbt_descr *td, struct nand_bbt_descr *md) 451 struct nand_bbt_descr *td, struct nand_bbt_descr *md)
452{ 452{
453 /* Search the primary table */ 453 /* Search the primary table */
454 search_bbt (mtd, buf, td); 454 search_bbt (mtd, buf, td);
455 455
456 /* Search the mirror table */ 456 /* Search the mirror table */
457 if (md) 457 if (md)
458 search_bbt (mtd, buf, md); 458 search_bbt (mtd, buf, md);
459 459
460 /* Force result check */ 460 /* Force result check */
461 return 1; 461 return 1;
462} 462}
463
464 463
465/** 464
465/**
466 * write_bbt - [GENERIC] (Re)write the bad block table 466 * write_bbt - [GENERIC] (Re)write the bad block table
467 * 467 *
468 * @mtd: MTD device structure 468 * @mtd: MTD device structure
469 * @buf: temporary buffer 469 * @buf: temporary buffer
470 * @td: descriptor for the bad block table 470 * @td: descriptor for the bad block table
471 * @md: descriptor for the bad block table mirror 471 * @md: descriptor for the bad block table mirror
472 * @chipsel: selector for a specific chip, -1 for all 472 * @chipsel: selector for a specific chip, -1 for all
473 * 473 *
474 * (Re)write the bad block table 474 * (Re)write the bad block table
475 * 475 *
476*/ 476*/
477static int write_bbt (struct mtd_info *mtd, uint8_t *buf, 477static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
478 struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) 478 struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
479{ 479{
480 struct nand_chip *this = mtd->priv; 480 struct nand_chip *this = mtd->priv;
@@ -493,7 +493,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
493 /* Write bad block table per chip rather than per device ? */ 493 /* Write bad block table per chip rather than per device ? */
494 if (td->options & NAND_BBT_PERCHIP) { 494 if (td->options & NAND_BBT_PERCHIP) {
495 numblocks = (int) (this->chipsize >> this->bbt_erase_shift); 495 numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
496 /* Full device write or specific chip ? */ 496 /* Full device write or specific chip ? */
497 if (chipsel == -1) { 497 if (chipsel == -1) {
498 nrchips = this->numchips; 498 nrchips = this->numchips;
499 } else { 499 } else {
@@ -503,19 +503,19 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
503 } else { 503 } else {
504 numblocks = (int) (mtd->size >> this->bbt_erase_shift); 504 numblocks = (int) (mtd->size >> this->bbt_erase_shift);
505 nrchips = 1; 505 nrchips = 1;
506 } 506 }
507 507
508 /* Loop through the chips */ 508 /* Loop through the chips */
509 for (; chip < nrchips; chip++) { 509 for (; chip < nrchips; chip++) {
510 510
511 /* There was already a version of the table, reuse the page 511 /* There was already a version of the table, reuse the page
512 * This applies for absolute placement too, as we have the 512 * This applies for absolute placement too, as we have the
513 * page nr. in td->pages. 513 * page nr. in td->pages.
514 */ 514 */
515 if (td->pages[chip] != -1) { 515 if (td->pages[chip] != -1) {
516 page = td->pages[chip]; 516 page = td->pages[chip];
517 goto write; 517 goto write;
518 } 518 }
519 519
520 /* Automatic placement of the bad block table */ 520 /* Automatic placement of the bad block table */
521 /* Search direction top -> down ? */ 521 /* Search direction top -> down ? */
@@ -525,7 +525,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
525 } else { 525 } else {
526 startblock = chip * numblocks; 526 startblock = chip * numblocks;
527 dir = 1; 527 dir = 1;
528 } 528 }
529 529
530 for (i = 0; i < td->maxblocks; i++) { 530 for (i = 0; i < td->maxblocks; i++) {
531 int block = startblock + dir * i; 531 int block = startblock + dir * i;
@@ -542,7 +542,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
542 } 542 }
543 printk (KERN_ERR "No space left to write bad block table\n"); 543 printk (KERN_ERR "No space left to write bad block table\n");
544 return -ENOSPC; 544 return -ENOSPC;
545write: 545write:
546 546
547 /* Set up shift count and masks for the flash table */ 547 /* Set up shift count and masks for the flash table */
548 bits = td->options & NAND_BBT_NRBITS_MSK; 548 bits = td->options & NAND_BBT_NRBITS_MSK;
@@ -553,14 +553,14 @@ write:
553 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; 553 case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
554 default: return -EINVAL; 554 default: return -EINVAL;
555 } 555 }
556 556
557 bbtoffs = chip * (numblocks >> 2); 557 bbtoffs = chip * (numblocks >> 2);
558 558
559 to = ((loff_t) page) << this->page_shift; 559 to = ((loff_t) page) << this->page_shift;
560 560
561 memcpy (&oobinfo, this->autooob, sizeof(oobinfo)); 561 memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
562 oobinfo.useecc = MTD_NANDECC_PLACEONLY; 562 oobinfo.useecc = MTD_NANDECC_PLACEONLY;
563 563
564 /* Must we save the block contents ? */ 564 /* Must we save the block contents ? */
565 if (td->options & NAND_BBT_SAVECONTENT) { 565 if (td->options & NAND_BBT_SAVECONTENT) {
566 /* Make it block aligned */ 566 /* Make it block aligned */
@@ -599,7 +599,7 @@ write:
599 buf[len + td->veroffs] = td->version[chip]; 599 buf[len + td->veroffs] = td->version[chip];
600 } 600 }
601 } 601 }
602 602
603 /* walk through the memory table */ 603 /* walk through the memory table */
604 for (i = 0; i < numblocks; ) { 604 for (i = 0; i < numblocks; ) {
605 uint8_t dat; 605 uint8_t dat;
@@ -611,7 +611,7 @@ write:
611 dat >>= 2; 611 dat >>= 2;
612 } 612 }
613 } 613 }
614 614
615 memset (&einfo, 0, sizeof (einfo)); 615 memset (&einfo, 0, sizeof (einfo));
616 einfo.mtd = mtd; 616 einfo.mtd = mtd;
617 einfo.addr = (unsigned long) to; 617 einfo.addr = (unsigned long) to;
@@ -621,18 +621,18 @@ write:
621 printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); 621 printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
622 return res; 622 return res;
623 } 623 }
624 624
625 res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); 625 res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
626 if (res < 0) { 626 if (res < 0) {
627 printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); 627 printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
628 return res; 628 return res;
629 } 629 }
630 printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", 630 printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
631 (unsigned int) to, td->version[chip]); 631 (unsigned int) to, td->version[chip]);
632 632
633 /* Mark it as used */ 633 /* Mark it as used */
634 td->pages[chip] = page; 634 td->pages[chip] = page;
635 } 635 }
636 return 0; 636 return 0;
637} 637}
638 638
@@ -641,7 +641,7 @@ write:
641 * @mtd: MTD device structure 641 * @mtd: MTD device structure
642 * @bd: descriptor for the good/bad block search pattern 642 * @bd: descriptor for the good/bad block search pattern
643 * 643 *
644 * The function creates a memory based bbt by scanning the device 644 * The function creates a memory based bbt by scanning the device
645 * for manufacturer / software marked good / bad blocks 645 * for manufacturer / software marked good / bad blocks
646*/ 646*/
647static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) 647static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
@@ -673,11 +673,11 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
673 struct nand_bbt_descr *rd, *rd2; 673 struct nand_bbt_descr *rd, *rd2;
674 674
675 /* Do we have a bbt per chip ? */ 675 /* Do we have a bbt per chip ? */
676 if (td->options & NAND_BBT_PERCHIP) 676 if (td->options & NAND_BBT_PERCHIP)
677 chips = this->numchips; 677 chips = this->numchips;
678 else 678 else
679 chips = 1; 679 chips = 1;
680 680
681 for (i = 0; i < chips; i++) { 681 for (i = 0; i < chips; i++) {
682 writeops = 0; 682 writeops = 0;
683 rd = NULL; 683 rd = NULL;
@@ -692,7 +692,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
692 } 692 }
693 693
694 if (td->pages[i] == -1) { 694 if (td->pages[i] == -1) {
695 rd = md; 695 rd = md;
696 td->version[i] = md->version[i]; 696 td->version[i] = md->version[i];
697 writeops = 1; 697 writeops = 1;
698 goto writecheck; 698 goto writecheck;
@@ -710,7 +710,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
710 if (!(td->options & NAND_BBT_VERSION)) 710 if (!(td->options & NAND_BBT_VERSION))
711 rd2 = md; 711 rd2 = md;
712 goto writecheck; 712 goto writecheck;
713 } 713 }
714 714
715 if (((int8_t) (td->version[i] - md->version[i])) > 0) { 715 if (((int8_t) (td->version[i] - md->version[i])) > 0) {
716 rd = td; 716 rd = td;
@@ -735,15 +735,15 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
735create: 735create:
736 /* Create the bad block table by scanning the device ? */ 736 /* Create the bad block table by scanning the device ? */
737 if (!(td->options & NAND_BBT_CREATE)) 737 if (!(td->options & NAND_BBT_CREATE))
738 continue; 738 continue;
739 739
740 /* Create the table in memory by scanning the chip(s) */ 740 /* Create the table in memory by scanning the chip(s) */
741 create_bbt (mtd, buf, bd, chipsel); 741 create_bbt (mtd, buf, bd, chipsel);
742 742
743 td->version[i] = 1; 743 td->version[i] = 1;
744 if (md) 744 if (md)
745 md->version[i] = 1; 745 md->version[i] = 1;
746writecheck: 746writecheck:
747 /* read back first ? */ 747 /* read back first ? */
748 if (rd) 748 if (rd)
749 read_abs_bbt (mtd, buf, rd, chipsel); 749 read_abs_bbt (mtd, buf, rd, chipsel);
@@ -757,7 +757,7 @@ writecheck:
757 if (res < 0) 757 if (res < 0)
758 return res; 758 return res;
759 } 759 }
760 760
761 /* Write the mirror bad block table to the device ? */ 761 /* Write the mirror bad block table to the device ? */
762 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { 762 if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
763 res = write_bbt (mtd, buf, md, td, chipsel); 763 res = write_bbt (mtd, buf, md, td, chipsel);
@@ -765,11 +765,11 @@ writecheck:
765 return res; 765 return res;
766 } 766 }
767 } 767 }
768 return 0; 768 return 0;
769} 769}
770 770
771/** 771/**
772 * mark_bbt_regions - [GENERIC] mark the bad block table regions 772 * mark_bbt_regions - [GENERIC] mark the bad block table regions
773 * @mtd: MTD device structure 773 * @mtd: MTD device structure
774 * @td: bad block table descriptor 774 * @td: bad block table descriptor
775 * 775 *
@@ -790,14 +790,14 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
790 } else { 790 } else {
791 chips = 1; 791 chips = 1;
792 nrblocks = (int)(mtd->size >> this->bbt_erase_shift); 792 nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
793 } 793 }
794 794
795 for (i = 0; i < chips; i++) { 795 for (i = 0; i < chips; i++) {
796 if ((td->options & NAND_BBT_ABSPAGE) || 796 if ((td->options & NAND_BBT_ABSPAGE) ||
797 !(td->options & NAND_BBT_WRITE)) { 797 !(td->options & NAND_BBT_WRITE)) {
798 if (td->pages[i] == -1) continue; 798 if (td->pages[i] == -1) continue;
799 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); 799 block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
800 block <<= 1; 800 block <<= 1;
801 oldval = this->bbt[(block >> 3)]; 801 oldval = this->bbt[(block >> 3)];
802 newval = oldval | (0x2 << (block & 0x06)); 802 newval = oldval | (0x2 << (block & 0x06));
803 this->bbt[(block >> 3)] = newval; 803 this->bbt[(block >> 3)] = newval;
@@ -808,16 +808,16 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
808 update = 0; 808 update = 0;
809 if (td->options & NAND_BBT_LASTBLOCK) 809 if (td->options & NAND_BBT_LASTBLOCK)
810 block = ((i + 1) * nrblocks) - td->maxblocks; 810 block = ((i + 1) * nrblocks) - td->maxblocks;
811 else 811 else
812 block = i * nrblocks; 812 block = i * nrblocks;
813 block <<= 1; 813 block <<= 1;
814 for (j = 0; j < td->maxblocks; j++) { 814 for (j = 0; j < td->maxblocks; j++) {
815 oldval = this->bbt[(block >> 3)]; 815 oldval = this->bbt[(block >> 3)];
816 newval = oldval | (0x2 << (block & 0x06)); 816 newval = oldval | (0x2 << (block & 0x06));
817 this->bbt[(block >> 3)] = newval; 817 this->bbt[(block >> 3)] = newval;
818 if (oldval != newval) update = 1; 818 if (oldval != newval) update = 1;
819 block += 2; 819 block += 2;
820 } 820 }
821 /* If we want reserved blocks to be recorded to flash, and some 821 /* If we want reserved blocks to be recorded to flash, and some
822 new ones have been marked, then we need to update the stored 822 new ones have been marked, then we need to update the stored
823 bbts. This should only happen once. */ 823 bbts. This should only happen once. */
@@ -831,7 +831,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
831 * @mtd: MTD device structure 831 * @mtd: MTD device structure
832 * @bd: descriptor for the good/bad block search pattern 832 * @bd: descriptor for the good/bad block search pattern
833 * 833 *
834 * The function checks, if a bad block table(s) is/are already 834 * The function checks, if a bad block table(s) is/are already
835 * available. If not it scans the device for manufacturer 835 * available. If not it scans the device for manufacturer
836 * marked good / bad blocks and writes the bad block table(s) to 836 * marked good / bad blocks and writes the bad block table(s) to
837 * the selected place. 837 * the selected place.
@@ -880,30 +880,30 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
880 this->bbt = NULL; 880 this->bbt = NULL;
881 return -ENOMEM; 881 return -ENOMEM;
882 } 882 }
883 883
884 /* Is the bbt at a given page ? */ 884 /* Is the bbt at a given page ? */
885 if (td->options & NAND_BBT_ABSPAGE) { 885 if (td->options & NAND_BBT_ABSPAGE) {
886 res = read_abs_bbts (mtd, buf, td, md); 886 res = read_abs_bbts (mtd, buf, td, md);
887 } else { 887 } else {
888 /* Search the bad block table using a pattern in oob */ 888 /* Search the bad block table using a pattern in oob */
889 res = search_read_bbts (mtd, buf, td, md); 889 res = search_read_bbts (mtd, buf, td, md);
890 } 890 }
891 891
892 if (res) 892 if (res)
893 res = check_create (mtd, buf, bd); 893 res = check_create (mtd, buf, bd);
894 894
895 /* Prevent the bbt regions from erasing / writing */ 895 /* Prevent the bbt regions from erasing / writing */
896 mark_bbt_region (mtd, td); 896 mark_bbt_region (mtd, td);
897 if (md) 897 if (md)
898 mark_bbt_region (mtd, md); 898 mark_bbt_region (mtd, md);
899 899
900 kfree (buf); 900 kfree (buf);
901 return res; 901 return res;
902} 902}
903 903
904 904
905/** 905/**
906 * nand_update_bbt - [NAND Interface] update bad block table(s) 906 * nand_update_bbt - [NAND Interface] update bad block table(s)
907 * @mtd: MTD device structure 907 * @mtd: MTD device structure
908 * @offs: the offset of the newly marked block 908 * @offs: the offset of the newly marked block
909 * 909 *
@@ -930,7 +930,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
930 printk (KERN_ERR "nand_update_bbt: Out of memory\n"); 930 printk (KERN_ERR "nand_update_bbt: Out of memory\n");
931 return -ENOMEM; 931 return -ENOMEM;
932 } 932 }
933 933
934 writeops = md != NULL ? 0x03 : 0x01; 934 writeops = md != NULL ? 0x03 : 0x01;
935 935
936 /* Do we have a bbt per chip ? */ 936 /* Do we have a bbt per chip ? */
@@ -944,7 +944,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
944 944
945 td->version[chip]++; 945 td->version[chip]++;
946 if (md) 946 if (md)
947 md->version[chip]++; 947 md->version[chip]++;
948 948
949 /* Write the bad block table to the device ? */ 949 /* Write the bad block table to the device ? */
950 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { 950 if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
@@ -957,12 +957,12 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
957 res = write_bbt (mtd, buf, md, td, chipsel); 957 res = write_bbt (mtd, buf, md, td, chipsel);
958 } 958 }
959 959
960out: 960out:
961 kfree (buf); 961 kfree (buf);
962 return res; 962 return res;
963} 963}
964 964
965/* Define some generic bad / good block scan pattern which are used 965/* Define some generic bad / good block scan pattern which are used
966 * while scanning a device for factory marked good / bad blocks. */ 966 * while scanning a device for factory marked good / bad blocks. */
967static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; 967static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
968 968
@@ -1009,7 +1009,7 @@ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
1009static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; 1009static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
1010 1010
1011static struct nand_bbt_descr bbt_main_descr = { 1011static struct nand_bbt_descr bbt_main_descr = {
1012 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 1012 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1013 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 1013 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1014 .offs = 8, 1014 .offs = 8,
1015 .len = 4, 1015 .len = 4,
@@ -1019,7 +1019,7 @@ static struct nand_bbt_descr bbt_main_descr = {
1019}; 1019};
1020 1020
1021static struct nand_bbt_descr bbt_mirror_descr = { 1021static struct nand_bbt_descr bbt_mirror_descr = {
1022 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE 1022 .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
1023 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, 1023 | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
1024 .offs = 8, 1024 .offs = 8,
1025 .len = 4, 1025 .len = 4,
@@ -1029,7 +1029,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
1029}; 1029};
1030 1030
1031/** 1031/**
1032 * nand_default_bbt - [NAND Interface] Select a default bad block table for the device 1032 * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
1033 * @mtd: MTD device structure 1033 * @mtd: MTD device structure
1034 * 1034 *
1035 * This function selects the default bad block table 1035 * This function selects the default bad block table
@@ -1039,29 +1039,29 @@ static struct nand_bbt_descr bbt_mirror_descr = {
1039int nand_default_bbt (struct mtd_info *mtd) 1039int nand_default_bbt (struct mtd_info *mtd)
1040{ 1040{
1041 struct nand_chip *this = mtd->priv; 1041 struct nand_chip *this = mtd->priv;
1042 1042
1043 /* Default for AG-AND. We must use a flash based 1043 /* Default for AG-AND. We must use a flash based
1044 * bad block table as the devices have factory marked 1044 * bad block table as the devices have factory marked
1045 * _good_ blocks. Erasing those blocks leads to loss 1045 * _good_ blocks. Erasing those blocks leads to loss
1046 * of the good / bad information, so we _must_ store 1046 * of the good / bad information, so we _must_ store
1047 * this information in a good / bad table during 1047 * this information in a good / bad table during
1048 * startup 1048 * startup
1049 */ 1049 */
1050 if (this->options & NAND_IS_AND) { 1050 if (this->options & NAND_IS_AND) {
1051 /* Use the default pattern descriptors */ 1051 /* Use the default pattern descriptors */
1052 if (!this->bbt_td) { 1052 if (!this->bbt_td) {
1053 this->bbt_td = &bbt_main_descr; 1053 this->bbt_td = &bbt_main_descr;
1054 this->bbt_md = &bbt_mirror_descr; 1054 this->bbt_md = &bbt_mirror_descr;
1055 } 1055 }
1056 this->options |= NAND_USE_FLASH_BBT; 1056 this->options |= NAND_USE_FLASH_BBT;
1057 return nand_scan_bbt (mtd, &agand_flashbased); 1057 return nand_scan_bbt (mtd, &agand_flashbased);
1058 } 1058 }
1059 1059
1060 1060
1061 /* Is a flash based bad block table requested ? */ 1061 /* Is a flash based bad block table requested ? */
1062 if (this->options & NAND_USE_FLASH_BBT) { 1062 if (this->options & NAND_USE_FLASH_BBT) {
1063 /* Use the default pattern descriptors */ 1063 /* Use the default pattern descriptors */
1064 if (!this->bbt_td) { 1064 if (!this->bbt_td) {
1065 this->bbt_td = &bbt_main_descr; 1065 this->bbt_td = &bbt_main_descr;
1066 this->bbt_md = &bbt_mirror_descr; 1066 this->bbt_md = &bbt_mirror_descr;
1067 } 1067 }
@@ -1081,7 +1081,7 @@ int nand_default_bbt (struct mtd_info *mtd)
1081} 1081}
1082 1082
1083/** 1083/**
1084 * nand_isbad_bbt - [NAND Interface] Check if a block is bad 1084 * nand_isbad_bbt - [NAND Interface] Check if a block is bad
1085 * @mtd: MTD device structure 1085 * @mtd: MTD device structure
1086 * @offs: offset in the device 1086 * @offs: offset in the device
1087 * @allowbbt: allow access to bad block table region 1087 * @allowbbt: allow access to bad block table region
@@ -1092,12 +1092,12 @@ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
1092 struct nand_chip *this = mtd->priv; 1092 struct nand_chip *this = mtd->priv;
1093 int block; 1093 int block;
1094 uint8_t res; 1094 uint8_t res;
1095 1095
1096 /* Get block number * 2 */ 1096 /* Get block number * 2 */
1097 block = (int) (offs >> (this->bbt_erase_shift - 1)); 1097 block = (int) (offs >> (this->bbt_erase_shift - 1));
1098 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; 1098 res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
1099 1099
1100 DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", 1100 DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
1101 (unsigned int)offs, block >> 1, res); 1101 (unsigned int)offs, block >> 1, res);
1102 1102
1103 switch ((int)res) { 1103 switch ((int)res) {
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 2e341b75437a..40ac909150a3 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -7,22 +7,22 @@
7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
8 * Toshiba America Electronics Components, Inc. 8 * Toshiba America Electronics Components, Inc.
9 * 9 *
10 * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $ 10 * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $
11 * 11 *
12 * This file is free software; you can redistribute it and/or modify it 12 * This file is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the 13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 or (at your option) any 14 * Free Software Foundation; either version 2 or (at your option) any
15 * later version. 15 * later version.
16 * 16 *
17 * This file is distributed in the hope that it will be useful, but WITHOUT 17 * This file is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details. 20 * for more details.
21 * 21 *
22 * You should have received a copy of the GNU General Public License along 22 * You should have received a copy of the GNU General Public License along
23 * with this file; if not, write to the Free Software Foundation, Inc., 23 * with this file; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 * 25 *
26 * As a special exception, if other files instantiate templates or use 26 * As a special exception, if other files instantiate templates or use
27 * macros or inline functions from these files, or you compile these 27 * macros or inline functions from these files, or you compile these
28 * files and link them with other works to produce a work based on these 28 * files and link them with other works to produce a work based on these
@@ -30,7 +30,7 @@
30 * covered by the GNU General Public License. However the source code for 30 * covered by the GNU General Public License. However the source code for
31 * these files must still be made available in accordance with section (3) 31 * these files must still be made available in accordance with section (3)
32 * of the GNU General Public License. 32 * of the GNU General Public License.
33 * 33 *
34 * This exception does not invalidate any other reasons why a work based on 34 * This exception does not invalidate any other reasons why a work based on
35 * this file might be covered by the GNU General Public License. 35 * this file might be covered by the GNU General Public License.
36 */ 36 */
@@ -67,7 +67,7 @@ static const u_char nand_ecc_precalc_table[] = {
67 * nand_trans_result - [GENERIC] create non-inverted ECC 67 * nand_trans_result - [GENERIC] create non-inverted ECC
68 * @reg2: line parity reg 2 68 * @reg2: line parity reg 2
69 * @reg3: line parity reg 3 69 * @reg3: line parity reg 3
70 * @ecc_code: ecc 70 * @ecc_code: ecc
71 * 71 *
72 * Creates non-inverted ECC code from line parity 72 * Creates non-inverted ECC code from line parity
73 */ 73 */
@@ -75,11 +75,11 @@ static void nand_trans_result(u_char reg2, u_char reg3,
75 u_char *ecc_code) 75 u_char *ecc_code)
76{ 76{
77 u_char a, b, i, tmp1, tmp2; 77 u_char a, b, i, tmp1, tmp2;
78 78
79 /* Initialize variables */ 79 /* Initialize variables */
80 a = b = 0x80; 80 a = b = 0x80;
81 tmp1 = tmp2 = 0; 81 tmp1 = tmp2 = 0;
82 82
83 /* Calculate first ECC byte */ 83 /* Calculate first ECC byte */
84 for (i = 0; i < 4; i++) { 84 for (i = 0; i < 4; i++) {
85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ 85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
@@ -90,7 +90,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
90 b >>= 1; 90 b >>= 1;
91 a >>= 1; 91 a >>= 1;
92 } 92 }
93 93
94 /* Calculate second ECC byte */ 94 /* Calculate second ECC byte */
95 b = 0x80; 95 b = 0x80;
96 for (i = 0; i < 4; i++) { 96 for (i = 0; i < 4; i++) {
@@ -102,7 +102,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
102 b >>= 1; 102 b >>= 1;
103 a >>= 1; 103 a >>= 1;
104 } 104 }
105 105
106 /* Store two of the ECC bytes */ 106 /* Store two of the ECC bytes */
107 ecc_code[0] = tmp1; 107 ecc_code[0] = tmp1;
108 ecc_code[1] = tmp2; 108 ecc_code[1] = tmp2;
@@ -118,28 +118,28 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
118{ 118{
119 u_char idx, reg1, reg2, reg3; 119 u_char idx, reg1, reg2, reg3;
120 int j; 120 int j;
121 121
122 /* Initialize variables */ 122 /* Initialize variables */
123 reg1 = reg2 = reg3 = 0; 123 reg1 = reg2 = reg3 = 0;
124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; 124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
125 125
126 /* Build up column parity */ 126 /* Build up column parity */
127 for(j = 0; j < 256; j++) { 127 for(j = 0; j < 256; j++) {
128 128
129 /* Get CP0 - CP5 from table */ 129 /* Get CP0 - CP5 from table */
130 idx = nand_ecc_precalc_table[dat[j]]; 130 idx = nand_ecc_precalc_table[dat[j]];
131 reg1 ^= (idx & 0x3f); 131 reg1 ^= (idx & 0x3f);
132 132
133 /* All bit XOR = 1 ? */ 133 /* All bit XOR = 1 ? */
134 if (idx & 0x40) { 134 if (idx & 0x40) {
135 reg3 ^= (u_char) j; 135 reg3 ^= (u_char) j;
136 reg2 ^= ~((u_char) j); 136 reg2 ^= ~((u_char) j);
137 } 137 }
138 } 138 }
139 139
140 /* Create non-inverted ECC code from line parity */ 140 /* Create non-inverted ECC code from line parity */
141 nand_trans_result(reg2, reg3, ecc_code); 141 nand_trans_result(reg2, reg3, ecc_code);
142 142
143 /* Calculate final ECC code */ 143 /* Calculate final ECC code */
144 ecc_code[0] = ~ecc_code[0]; 144 ecc_code[0] = ~ecc_code[0];
145 ecc_code[1] = ~ecc_code[1]; 145 ecc_code[1] = ~ecc_code[1];
@@ -159,12 +159,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
159int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) 159int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
160{ 160{
161 u_char a, b, c, d1, d2, d3, add, bit, i; 161 u_char a, b, c, d1, d2, d3, add, bit, i;
162 162
163 /* Do error detection */ 163 /* Do error detection */
164 d1 = calc_ecc[0] ^ read_ecc[0]; 164 d1 = calc_ecc[0] ^ read_ecc[0];
165 d2 = calc_ecc[1] ^ read_ecc[1]; 165 d2 = calc_ecc[1] ^ read_ecc[1];
166 d3 = calc_ecc[2] ^ read_ecc[2]; 166 d3 = calc_ecc[2] ^ read_ecc[2];
167 167
168 if ((d1 | d2 | d3) == 0) { 168 if ((d1 | d2 | d3) == 0) {
169 /* No errors */ 169 /* No errors */
170 return 0; 170 return 0;
@@ -173,7 +173,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
173 a = (d1 ^ (d1 >> 1)) & 0x55; 173 a = (d1 ^ (d1 >> 1)) & 0x55;
174 b = (d2 ^ (d2 >> 1)) & 0x55; 174 b = (d2 ^ (d2 >> 1)) & 0x55;
175 c = (d3 ^ (d3 >> 1)) & 0x54; 175 c = (d3 ^ (d3 >> 1)) & 0x54;
176 176
177 /* Found and will correct single bit error in the data */ 177 /* Found and will correct single bit error in the data */
178 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { 178 if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
179 c = 0x80; 179 c = 0x80;
@@ -237,7 +237,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
237 } 237 }
238 } 238 }
239 } 239 }
240 240
241 /* Should never happen */ 241 /* Should never happen */
242 return -1; 242 return -1;
243} 243}
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index efe246961b69..dbc7e55a4247 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) 4 * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
5 * 5 *
6 * $Id: nand_ids.c,v 1.14 2005/06/23 09:38:50 gleixner Exp $ 6 * $Id: nand_ids.c,v 1.16 2005/11/07 11:14:31 gleixner Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -14,14 +14,14 @@
14#include <linux/mtd/nand.h> 14#include <linux/mtd/nand.h>
15/* 15/*
16* Chip ID list 16* Chip ID list
17* 17*
18* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, 18* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
19* options 19* options
20* 20*
21* Pagesize; 0, 256, 512 21* Pagesize; 0, 256, 512
22* 0 get this information from the extended chip ID 22* 0 get this information from the extended chip ID
23+ 256 256 Byte page size 23+ 256 256 Byte page size
24* 512 512 Byte page size 24* 512 512 Byte page size
25*/ 25*/
26struct nand_flash_dev nand_flash_ids[] = { 26struct nand_flash_dev nand_flash_ids[] = {
27 {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, 27 {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
@@ -34,27 +34,27 @@ struct nand_flash_dev nand_flash_ids[] = {
34 {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, 34 {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
35 {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, 35 {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
36 {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, 36 {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
37 37
38 {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, 38 {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
39 {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, 39 {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
40 {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, 40 {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
41 {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, 41 {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
42 42
43 {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, 43 {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
44 {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, 44 {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
45 {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, 45 {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
46 {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, 46 {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
47 47
48 {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, 48 {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
49 {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, 49 {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
50 {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, 50 {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
51 {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, 51 {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
52 52
53 {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, 53 {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
54 {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, 54 {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
55 {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, 55 {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, 56 {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
57 57
58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, 58 {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
59 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, 59 {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
60 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, 60 {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
@@ -62,7 +62,7 @@ struct nand_flash_dev nand_flash_ids[] = {
62 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 62 {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
63 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 63 {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
64 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, 64 {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
65 65
66 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, 66 {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
67 67
68 /* These are the new chips with large page size. The pagesize 68 /* These are the new chips with large page size. The pagesize
@@ -73,7 +73,7 @@ struct nand_flash_dev nand_flash_ids[] = {
73 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 73 {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
74 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 74 {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
75 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 75 {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
76 76
77 /* 1 Gigabit */ 77 /* 1 Gigabit */
78 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 78 {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
79 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 79 {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -85,13 +85,13 @@ struct nand_flash_dev nand_flash_ids[] = {
85 {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 85 {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
86 {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 86 {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
87 {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 87 {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
88 88
89 /* 4 Gigabit */ 89 /* 4 Gigabit */
90 {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 90 {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
91 {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 91 {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
92 {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 92 {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
93 {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 93 {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
94 94
95 /* 8 Gigabit */ 95 /* 8 Gigabit */
96 {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 96 {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
97 {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, 97 {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@@ -104,11 +104,11 @@ struct nand_flash_dev nand_flash_ids[] = {
104 {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 104 {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
105 {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, 105 {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
106 106
107 /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! 107 /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
108 * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes 108 * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
109 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 109 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
110 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go 110 * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
111 * There are more speed improvements for reads and writes possible, but not implemented now 111 * There are more speed improvements for reads and writes possible, but not implemented now
112 */ 112 */
113 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH}, 113 {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
114 114
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 754b6ed7ce14..de4500395300 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org> 4 * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org>
5 * 5 *
6 * Copyright (C) 2004 Nokia Corporation 6 * Copyright (C) 2004 Nokia Corporation
7 * 7 *
8 * Note: NS means "NAND Simulator". 8 * Note: NS means "NAND Simulator".
9 * Note: Input means input TO flash chip, output means output FROM chip. 9 * Note: Input means input TO flash chip, output means output FROM chip.
@@ -126,7 +126,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
126 126
127/* The largest possible page size */ 127/* The largest possible page size */
128#define NS_LARGEST_PAGE_SIZE 2048 128#define NS_LARGEST_PAGE_SIZE 2048
129 129
130/* The prefix for simulator output */ 130/* The prefix for simulator output */
131#define NS_OUTPUT_PREFIX "[nandsim]" 131#define NS_OUTPUT_PREFIX "[nandsim]"
132 132
@@ -145,7 +145,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
145 do { if (do_delays) udelay(us); } while(0) 145 do { if (do_delays) udelay(us); } while(0)
146#define NS_MDELAY(us) \ 146#define NS_MDELAY(us) \
147 do { if (do_delays) mdelay(us); } while(0) 147 do { if (do_delays) mdelay(us); } while(0)
148 148
149/* Is the nandsim structure initialized ? */ 149/* Is the nandsim structure initialized ? */
150#define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0) 150#define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0)
151 151
@@ -153,12 +153,12 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
153#define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0))) 153#define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0)))
154 154
155/* Operation failed completion status */ 155/* Operation failed completion status */
156#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns)) 156#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns))
157 157
158/* Calculate the page offset in flash RAM image by (row, column) address */ 158/* Calculate the page offset in flash RAM image by (row, column) address */
159#define NS_RAW_OFFSET(ns) \ 159#define NS_RAW_OFFSET(ns) \
160 (((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column) 160 (((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column)
161 161
162/* Calculate the OOB offset in flash RAM image by (row, column) address */ 162/* Calculate the OOB offset in flash RAM image by (row, column) address */
163#define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz) 163#define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz)
164 164
@@ -223,15 +223,15 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
223 223
224/* Remove action bits ftom state */ 224/* Remove action bits ftom state */
225#define NS_STATE(x) ((x) & ~ACTION_MASK) 225#define NS_STATE(x) ((x) & ~ACTION_MASK)
226 226
227/* 227/*
228 * Maximum previous states which need to be saved. Currently saving is 228 * Maximum previous states which need to be saved. Currently saving is
229 * only needed for page programm operation with preceeded read command 229 * only needed for page programm operation with preceeded read command
230 * (which is only valid for 512-byte pages). 230 * (which is only valid for 512-byte pages).
231 */ 231 */
232#define NS_MAX_PREVSTATES 1 232#define NS_MAX_PREVSTATES 1
233 233
234/* 234/*
235 * The structure which describes all the internal simulator data. 235 * The structure which describes all the internal simulator data.
236 */ 236 */
237struct nandsim { 237struct nandsim {
@@ -242,7 +242,7 @@ struct nandsim {
242 uint32_t options; /* chip's characteristic bits */ 242 uint32_t options; /* chip's characteristic bits */
243 uint32_t state; /* current chip state */ 243 uint32_t state; /* current chip state */
244 uint32_t nxstate; /* next expected state */ 244 uint32_t nxstate; /* next expected state */
245 245
246 uint32_t *op; /* current operation, NULL operations isn't known yet */ 246 uint32_t *op; /* current operation, NULL operations isn't known yet */
247 uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */ 247 uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */
248 uint16_t npstates; /* number of previous states saved */ 248 uint16_t npstates; /* number of previous states saved */
@@ -413,7 +413,7 @@ init_nandsim(struct mtd_info *mtd)
413 ns->geom.secaddrbytes = 3; 413 ns->geom.secaddrbytes = 3;
414 } 414 }
415 } 415 }
416 416
417 /* Detect how many ID bytes the NAND chip outputs */ 417 /* Detect how many ID bytes the NAND chip outputs */
418 for (i = 0; nand_flash_ids[i].name != NULL; i++) { 418 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
419 if (second_id_byte != nand_flash_ids[i].id) 419 if (second_id_byte != nand_flash_ids[i].id)
@@ -444,7 +444,7 @@ init_nandsim(struct mtd_info *mtd)
444#ifdef CONFIG_NS_ABS_POS 444#ifdef CONFIG_NS_ABS_POS
445 ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob); 445 ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob);
446 if (!ns->mem.byte) { 446 if (!ns->mem.byte) {
447 NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n", 447 NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n",
448 (void *)CONFIG_NS_ABS_POS); 448 (void *)CONFIG_NS_ABS_POS);
449 return -ENOMEM; 449 return -ENOMEM;
450 } 450 }
@@ -567,7 +567,7 @@ static int
567check_command(int cmd) 567check_command(int cmd)
568{ 568{
569 switch (cmd) { 569 switch (cmd) {
570 570
571 case NAND_CMD_READ0: 571 case NAND_CMD_READ0:
572 case NAND_CMD_READSTART: 572 case NAND_CMD_READSTART:
573 case NAND_CMD_PAGEPROG: 573 case NAND_CMD_PAGEPROG:
@@ -580,7 +580,7 @@ check_command(int cmd)
580 case NAND_CMD_RESET: 580 case NAND_CMD_RESET:
581 case NAND_CMD_READ1: 581 case NAND_CMD_READ1:
582 return 0; 582 return 0;
583 583
584 case NAND_CMD_STATUS_MULTI: 584 case NAND_CMD_STATUS_MULTI:
585 default: 585 default:
586 return 1; 586 return 1;
@@ -631,7 +631,7 @@ static inline void
631accept_addr_byte(struct nandsim *ns, u_char bt) 631accept_addr_byte(struct nandsim *ns, u_char bt)
632{ 632{
633 uint byte = (uint)bt; 633 uint byte = (uint)bt;
634 634
635 if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) 635 if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes))
636 ns->regs.column |= (byte << 8 * ns->regs.count); 636 ns->regs.column |= (byte << 8 * ns->regs.count);
637 else { 637 else {
@@ -642,11 +642,11 @@ accept_addr_byte(struct nandsim *ns, u_char bt)
642 642
643 return; 643 return;
644} 644}
645 645
646/* 646/*
647 * Switch to STATE_READY state. 647 * Switch to STATE_READY state.
648 */ 648 */
649static inline void 649static inline void
650switch_to_ready_state(struct nandsim *ns, u_char status) 650switch_to_ready_state(struct nandsim *ns, u_char status)
651{ 651{
652 NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY)); 652 NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY));
@@ -675,7 +675,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
675 * (for example program from the second half and read from the 675 * (for example program from the second half and read from the
676 * second half operations both begin with the READ1 command). In this 676 * second half operations both begin with the READ1 command). In this
677 * case the ns->pstates[] array contains previous states. 677 * case the ns->pstates[] array contains previous states.
678 * 678 *
679 * Thus, the function tries to find operation containing the following 679 * Thus, the function tries to find operation containing the following
680 * states (if the 'flag' parameter is 0): 680 * states (if the 'flag' parameter is 0):
681 * ns->pstates[0], ... ns->pstates[ns->npstates], ns->state 681 * ns->pstates[0], ... ns->pstates[ns->npstates], ns->state
@@ -683,7 +683,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
683 * If (one and only one) matching operation is found, it is accepted ( 683 * If (one and only one) matching operation is found, it is accepted (
684 * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is 684 * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is
685 * zeroed). 685 * zeroed).
686 * 686 *
687 * If there are several maches, the current state is pushed to the 687 * If there are several maches, the current state is pushed to the
688 * ns->pstates. 688 * ns->pstates.
689 * 689 *
@@ -692,7 +692,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
692 * In such situation the function is called with 'flag' != 0, and the 692 * In such situation the function is called with 'flag' != 0, and the
693 * operation is searched using the following pattern: 693 * operation is searched using the following pattern:
694 * ns->pstates[0], ... ns->pstates[ns->npstates], <address input> 694 * ns->pstates[0], ... ns->pstates[ns->npstates], <address input>
695 * 695 *
696 * It is supposed that this pattern must either match one operation on 696 * It is supposed that this pattern must either match one operation on
697 * none. There can't be ambiguity in that case. 697 * none. There can't be ambiguity in that case.
698 * 698 *
@@ -711,15 +711,15 @@ find_operation(struct nandsim *ns, uint32_t flag)
711{ 711{
712 int opsfound = 0; 712 int opsfound = 0;
713 int i, j, idx = 0; 713 int i, j, idx = 0;
714 714
715 for (i = 0; i < NS_OPER_NUM; i++) { 715 for (i = 0; i < NS_OPER_NUM; i++) {
716 716
717 int found = 1; 717 int found = 1;
718 718
719 if (!(ns->options & ops[i].reqopts)) 719 if (!(ns->options & ops[i].reqopts))
720 /* Ignore operations we can't perform */ 720 /* Ignore operations we can't perform */
721 continue; 721 continue;
722 722
723 if (flag) { 723 if (flag) {
724 if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK)) 724 if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK))
725 continue; 725 continue;
@@ -728,7 +728,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
728 continue; 728 continue;
729 } 729 }
730 730
731 for (j = 0; j < ns->npstates; j++) 731 for (j = 0; j < ns->npstates; j++)
732 if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j]) 732 if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j])
733 && (ns->options & ops[idx].reqopts)) { 733 && (ns->options & ops[idx].reqopts)) {
734 found = 0; 734 found = 0;
@@ -745,7 +745,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
745 /* Exact match */ 745 /* Exact match */
746 ns->op = &ops[idx].states[0]; 746 ns->op = &ops[idx].states[0];
747 if (flag) { 747 if (flag) {
748 /* 748 /*
749 * In this case the find_operation function was 749 * In this case the find_operation function was
750 * called when address has just began input. But it isn't 750 * called when address has just began input. But it isn't
751 * yet fully input and the current state must 751 * yet fully input and the current state must
@@ -763,7 +763,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
763 idx, get_state_name(ns->state), get_state_name(ns->nxstate)); 763 idx, get_state_name(ns->state), get_state_name(ns->nxstate));
764 return 0; 764 return 0;
765 } 765 }
766 766
767 if (opsfound == 0) { 767 if (opsfound == 0) {
768 /* Nothing was found. Try to ignore previous commands (if any) and search again */ 768 /* Nothing was found. Try to ignore previous commands (if any) and search again */
769 if (ns->npstates != 0) { 769 if (ns->npstates != 0) {
@@ -777,13 +777,13 @@ find_operation(struct nandsim *ns, uint32_t flag)
777 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 777 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
778 return -2; 778 return -2;
779 } 779 }
780 780
781 if (flag) { 781 if (flag) {
782 /* This shouldn't happen */ 782 /* This shouldn't happen */
783 NS_DBG("find_operation: BUG, operation must be known if address is input\n"); 783 NS_DBG("find_operation: BUG, operation must be known if address is input\n");
784 return -2; 784 return -2;
785 } 785 }
786 786
787 NS_DBG("find_operation: there is still ambiguity\n"); 787 NS_DBG("find_operation: there is still ambiguity\n");
788 788
789 ns->pstates[ns->npstates++] = ns->state; 789 ns->pstates[ns->npstates++] = ns->state;
@@ -803,7 +803,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
803 int busdiv = ns->busw == 8 ? 1 : 2; 803 int busdiv = ns->busw == 8 ? 1 : 2;
804 804
805 action &= ACTION_MASK; 805 action &= ACTION_MASK;
806 806
807 /* Check that page address input is correct */ 807 /* Check that page address input is correct */
808 if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) { 808 if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) {
809 NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row); 809 NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row);
@@ -827,14 +827,14 @@ do_state_action(struct nandsim *ns, uint32_t action)
827 827
828 NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n", 828 NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n",
829 num, NS_RAW_OFFSET(ns) + ns->regs.off); 829 num, NS_RAW_OFFSET(ns) + ns->regs.off);
830 830
831 if (ns->regs.off == 0) 831 if (ns->regs.off == 0)
832 NS_LOG("read page %d\n", ns->regs.row); 832 NS_LOG("read page %d\n", ns->regs.row);
833 else if (ns->regs.off < ns->geom.pgsz) 833 else if (ns->regs.off < ns->geom.pgsz)
834 NS_LOG("read page %d (second half)\n", ns->regs.row); 834 NS_LOG("read page %d (second half)\n", ns->regs.row);
835 else 835 else
836 NS_LOG("read OOB of page %d\n", ns->regs.row); 836 NS_LOG("read OOB of page %d\n", ns->regs.row);
837 837
838 NS_UDELAY(access_delay); 838 NS_UDELAY(access_delay);
839 NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv); 839 NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv);
840 840
@@ -844,30 +844,30 @@ do_state_action(struct nandsim *ns, uint32_t action)
844 /* 844 /*
845 * Erase sector. 845 * Erase sector.
846 */ 846 */
847 847
848 if (ns->lines.wp) { 848 if (ns->lines.wp) {
849 NS_ERR("do_state_action: device is write-protected, ignore sector erase\n"); 849 NS_ERR("do_state_action: device is write-protected, ignore sector erase\n");
850 return -1; 850 return -1;
851 } 851 }
852 852
853 if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec 853 if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec
854 || (ns->regs.row & ~(ns->geom.secsz - 1))) { 854 || (ns->regs.row & ~(ns->geom.secsz - 1))) {
855 NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row); 855 NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row);
856 return -1; 856 return -1;
857 } 857 }
858 858
859 ns->regs.row = (ns->regs.row << 859 ns->regs.row = (ns->regs.row <<
860 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column; 860 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column;
861 ns->regs.column = 0; 861 ns->regs.column = 0;
862 862
863 NS_DBG("do_state_action: erase sector at address %#x, off = %d\n", 863 NS_DBG("do_state_action: erase sector at address %#x, off = %d\n",
864 ns->regs.row, NS_RAW_OFFSET(ns)); 864 ns->regs.row, NS_RAW_OFFSET(ns));
865 NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift)); 865 NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift));
866 866
867 memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob); 867 memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob);
868 868
869 NS_MDELAY(erase_delay); 869 NS_MDELAY(erase_delay);
870 870
871 break; 871 break;
872 872
873 case ACTION_PRGPAGE: 873 case ACTION_PRGPAGE:
@@ -893,12 +893,12 @@ do_state_action(struct nandsim *ns, uint32_t action)
893 NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n", 893 NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n",
894 num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off); 894 num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off);
895 NS_LOG("programm page %d\n", ns->regs.row); 895 NS_LOG("programm page %d\n", ns->regs.row);
896 896
897 NS_UDELAY(programm_delay); 897 NS_UDELAY(programm_delay);
898 NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv); 898 NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv);
899 899
900 break; 900 break;
901 901
902 case ACTION_ZEROOFF: 902 case ACTION_ZEROOFF:
903 NS_DBG("do_state_action: set internal offset to 0\n"); 903 NS_DBG("do_state_action: set internal offset to 0\n");
904 ns->regs.off = 0; 904 ns->regs.off = 0;
@@ -918,7 +918,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
918 NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz); 918 NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz);
919 ns->regs.off = ns->geom.pgsz; 919 ns->regs.off = ns->geom.pgsz;
920 break; 920 break;
921 921
922 default: 922 default:
923 NS_DBG("do_state_action: BUG! unknown action\n"); 923 NS_DBG("do_state_action: BUG! unknown action\n");
924 } 924 }
@@ -937,7 +937,7 @@ switch_state(struct nandsim *ns)
937 * The current operation have already been identified. 937 * The current operation have already been identified.
938 * Just follow the states chain. 938 * Just follow the states chain.
939 */ 939 */
940 940
941 ns->stateidx += 1; 941 ns->stateidx += 1;
942 ns->state = ns->nxstate; 942 ns->state = ns->nxstate;
943 ns->nxstate = ns->op[ns->stateidx + 1]; 943 ns->nxstate = ns->op[ns->stateidx + 1];
@@ -951,14 +951,14 @@ switch_state(struct nandsim *ns)
951 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 951 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
952 return; 952 return;
953 } 953 }
954 954
955 } else { 955 } else {
956 /* 956 /*
957 * We don't yet know which operation we perform. 957 * We don't yet know which operation we perform.
958 * Try to identify it. 958 * Try to identify it.
959 */ 959 */
960 960
961 /* 961 /*
962 * The only event causing the switch_state function to 962 * The only event causing the switch_state function to
963 * be called with yet unknown operation is new command. 963 * be called with yet unknown operation is new command.
964 */ 964 */
@@ -987,7 +987,7 @@ switch_state(struct nandsim *ns)
987 */ 987 */
988 988
989 u_char status = NS_STATUS_OK(ns); 989 u_char status = NS_STATUS_OK(ns);
990 990
991 /* In case of data states, see if all bytes were input/output */ 991 /* In case of data states, see if all bytes were input/output */
992 if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) 992 if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK))
993 && ns->regs.count != ns->regs.num) { 993 && ns->regs.count != ns->regs.num) {
@@ -995,17 +995,17 @@ switch_state(struct nandsim *ns)
995 ns->regs.num - ns->regs.count); 995 ns->regs.num - ns->regs.count);
996 status = NS_STATUS_FAILED(ns); 996 status = NS_STATUS_FAILED(ns);
997 } 997 }
998 998
999 NS_DBG("switch_state: operation complete, switch to STATE_READY state\n"); 999 NS_DBG("switch_state: operation complete, switch to STATE_READY state\n");
1000 1000
1001 switch_to_ready_state(ns, status); 1001 switch_to_ready_state(ns, status);
1002 1002
1003 return; 1003 return;
1004 } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) { 1004 } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) {
1005 /* 1005 /*
1006 * If the next state is data input/output, switch to it now 1006 * If the next state is data input/output, switch to it now
1007 */ 1007 */
1008 1008
1009 ns->state = ns->nxstate; 1009 ns->state = ns->nxstate;
1010 ns->nxstate = ns->op[++ns->stateidx + 1]; 1010 ns->nxstate = ns->op[++ns->stateidx + 1];
1011 ns->regs.num = ns->regs.count = 0; 1011 ns->regs.num = ns->regs.count = 0;
@@ -1023,16 +1023,16 @@ switch_state(struct nandsim *ns)
1023 case STATE_DATAOUT: 1023 case STATE_DATAOUT:
1024 ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; 1024 ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
1025 break; 1025 break;
1026 1026
1027 case STATE_DATAOUT_ID: 1027 case STATE_DATAOUT_ID:
1028 ns->regs.num = ns->geom.idbytes; 1028 ns->regs.num = ns->geom.idbytes;
1029 break; 1029 break;
1030 1030
1031 case STATE_DATAOUT_STATUS: 1031 case STATE_DATAOUT_STATUS:
1032 case STATE_DATAOUT_STATUS_M: 1032 case STATE_DATAOUT_STATUS_M:
1033 ns->regs.count = ns->regs.num = 0; 1033 ns->regs.count = ns->regs.num = 0;
1034 break; 1034 break;
1035 1035
1036 default: 1036 default:
1037 NS_ERR("switch_state: BUG! unknown data state\n"); 1037 NS_ERR("switch_state: BUG! unknown data state\n");
1038 } 1038 }
@@ -1044,16 +1044,16 @@ switch_state(struct nandsim *ns)
1044 */ 1044 */
1045 1045
1046 ns->regs.count = 0; 1046 ns->regs.count = 0;
1047 1047
1048 switch (NS_STATE(ns->nxstate)) { 1048 switch (NS_STATE(ns->nxstate)) {
1049 case STATE_ADDR_PAGE: 1049 case STATE_ADDR_PAGE:
1050 ns->regs.num = ns->geom.pgaddrbytes; 1050 ns->regs.num = ns->geom.pgaddrbytes;
1051 1051
1052 break; 1052 break;
1053 case STATE_ADDR_SEC: 1053 case STATE_ADDR_SEC:
1054 ns->regs.num = ns->geom.secaddrbytes; 1054 ns->regs.num = ns->geom.secaddrbytes;
1055 break; 1055 break;
1056 1056
1057 case STATE_ADDR_ZERO: 1057 case STATE_ADDR_ZERO:
1058 ns->regs.num = 1; 1058 ns->regs.num = 1;
1059 break; 1059 break;
@@ -1062,7 +1062,7 @@ switch_state(struct nandsim *ns)
1062 NS_ERR("switch_state: BUG! unknown address state\n"); 1062 NS_ERR("switch_state: BUG! unknown address state\n");
1063 } 1063 }
1064 } else { 1064 } else {
1065 /* 1065 /*
1066 * Just reset internal counters. 1066 * Just reset internal counters.
1067 */ 1067 */
1068 1068
@@ -1184,7 +1184,7 @@ ns_nand_read_byte(struct mtd_info *mtd)
1184 default: 1184 default:
1185 BUG(); 1185 BUG();
1186 } 1186 }
1187 1187
1188 if (ns->regs.count == ns->regs.num) { 1188 if (ns->regs.count == ns->regs.num) {
1189 NS_DBG("read_byte: all bytes were read\n"); 1189 NS_DBG("read_byte: all bytes were read\n");
1190 1190
@@ -1201,9 +1201,9 @@ ns_nand_read_byte(struct mtd_info *mtd)
1201 } 1201 }
1202 else if (NS_STATE(ns->nxstate) == STATE_READY) 1202 else if (NS_STATE(ns->nxstate) == STATE_READY)
1203 switch_state(ns); 1203 switch_state(ns);
1204 1204
1205 } 1205 }
1206 1206
1207 return outb; 1207 return outb;
1208} 1208}
1209 1209
@@ -1211,7 +1211,7 @@ static void
1211ns_nand_write_byte(struct mtd_info *mtd, u_char byte) 1211ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1212{ 1212{
1213 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1213 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
1214 1214
1215 /* Sanity and correctness checks */ 1215 /* Sanity and correctness checks */
1216 if (!ns->lines.ce) { 1216 if (!ns->lines.ce) {
1217 NS_ERR("write_byte: chip is disabled, ignore write\n"); 1217 NS_ERR("write_byte: chip is disabled, ignore write\n");
@@ -1221,7 +1221,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1221 NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n"); 1221 NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n");
1222 return; 1222 return;
1223 } 1223 }
1224 1224
1225 if (ns->lines.cle == 1) { 1225 if (ns->lines.cle == 1) {
1226 /* 1226 /*
1227 * The byte written is a command. 1227 * The byte written is a command.
@@ -1233,7 +1233,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1233 return; 1233 return;
1234 } 1234 }
1235 1235
1236 /* 1236 /*
1237 * Chip might still be in STATE_DATAOUT 1237 * Chip might still be in STATE_DATAOUT
1238 * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or 1238 * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or
1239 * STATE_DATAOUT_STATUS_M state. If so, switch state. 1239 * STATE_DATAOUT_STATUS_M state. If so, switch state.
@@ -1254,13 +1254,13 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1254 "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate)); 1254 "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate));
1255 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1255 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1256 } 1256 }
1257 1257
1258 /* Check that the command byte is correct */ 1258 /* Check that the command byte is correct */
1259 if (check_command(byte)) { 1259 if (check_command(byte)) {
1260 NS_ERR("write_byte: unknown command %#x\n", (uint)byte); 1260 NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
1261 return; 1261 return;
1262 } 1262 }
1263 1263
1264 NS_DBG("command byte corresponding to %s state accepted\n", 1264 NS_DBG("command byte corresponding to %s state accepted\n",
1265 get_state_name(get_state_by_command(byte))); 1265 get_state_name(get_state_by_command(byte)));
1266 ns->regs.command = byte; 1266 ns->regs.command = byte;
@@ -1277,12 +1277,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1277 1277
1278 if (find_operation(ns, 1) < 0) 1278 if (find_operation(ns, 1) < 0)
1279 return; 1279 return;
1280 1280
1281 if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) { 1281 if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
1282 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1282 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1283 return; 1283 return;
1284 } 1284 }
1285 1285
1286 ns->regs.count = 0; 1286 ns->regs.count = 0;
1287 switch (NS_STATE(ns->nxstate)) { 1287 switch (NS_STATE(ns->nxstate)) {
1288 case STATE_ADDR_PAGE: 1288 case STATE_ADDR_PAGE:
@@ -1306,7 +1306,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1306 switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); 1306 switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
1307 return; 1307 return;
1308 } 1308 }
1309 1309
1310 /* Check if this is expected byte */ 1310 /* Check if this is expected byte */
1311 if (ns->regs.count == ns->regs.num) { 1311 if (ns->regs.count == ns->regs.num) {
1312 NS_ERR("write_byte: no more address bytes expected\n"); 1312 NS_ERR("write_byte: no more address bytes expected\n");
@@ -1325,12 +1325,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
1325 NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column); 1325 NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column);
1326 switch_state(ns); 1326 switch_state(ns);
1327 } 1327 }
1328 1328
1329 } else { 1329 } else {
1330 /* 1330 /*
1331 * The byte written is an input data. 1331 * The byte written is an input data.
1332 */ 1332 */
1333 1333
1334 /* Check that chip is expecting data input */ 1334 /* Check that chip is expecting data input */
1335 if (!(ns->state & STATE_DATAIN_MASK)) { 1335 if (!(ns->state & STATE_DATAIN_MASK)) {
1336 NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, " 1336 NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, "
@@ -1372,7 +1372,7 @@ ns_nand_read_word(struct mtd_info *mtd)
1372 struct nand_chip *chip = (struct nand_chip *)mtd->priv; 1372 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
1373 1373
1374 NS_DBG("read_word\n"); 1374 NS_DBG("read_word\n");
1375 1375
1376 return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8); 1376 return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8);
1377} 1377}
1378 1378
@@ -1380,14 +1380,14 @@ static void
1380ns_nand_write_word(struct mtd_info *mtd, uint16_t word) 1380ns_nand_write_word(struct mtd_info *mtd, uint16_t word)
1381{ 1381{
1382 struct nand_chip *chip = (struct nand_chip *)mtd->priv; 1382 struct nand_chip *chip = (struct nand_chip *)mtd->priv;
1383 1383
1384 NS_DBG("write_word\n"); 1384 NS_DBG("write_word\n");
1385 1385
1386 chip->write_byte(mtd, word & 0xFF); 1386 chip->write_byte(mtd, word & 0xFF);
1387 chip->write_byte(mtd, word >> 8); 1387 chip->write_byte(mtd, word >> 8);
1388} 1388}
1389 1389
1390static void 1390static void
1391ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 1391ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
1392{ 1392{
1393 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1393 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1409,13 +1409,13 @@ ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
1409 1409
1410 memcpy(ns->buf.byte + ns->regs.count, buf, len); 1410 memcpy(ns->buf.byte + ns->regs.count, buf, len);
1411 ns->regs.count += len; 1411 ns->regs.count += len;
1412 1412
1413 if (ns->regs.count == ns->regs.num) { 1413 if (ns->regs.count == ns->regs.num) {
1414 NS_DBG("write_buf: %d bytes were written\n", ns->regs.count); 1414 NS_DBG("write_buf: %d bytes were written\n", ns->regs.count);
1415 } 1415 }
1416} 1416}
1417 1417
1418static void 1418static void
1419ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) 1419ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1420{ 1420{
1421 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; 1421 struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@@ -1453,7 +1453,7 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1453 1453
1454 memcpy(buf, ns->buf.byte + ns->regs.count, len); 1454 memcpy(buf, ns->buf.byte + ns->regs.count, len);
1455 ns->regs.count += len; 1455 ns->regs.count += len;
1456 1456
1457 if (ns->regs.count == ns->regs.num) { 1457 if (ns->regs.count == ns->regs.num) {
1458 if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) { 1458 if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) {
1459 ns->regs.count = 0; 1459 ns->regs.count = 0;
@@ -1465,11 +1465,11 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
1465 else if (NS_STATE(ns->nxstate) == STATE_READY) 1465 else if (NS_STATE(ns->nxstate) == STATE_READY)
1466 switch_state(ns); 1466 switch_state(ns);
1467 } 1467 }
1468 1468
1469 return; 1469 return;
1470} 1470}
1471 1471
1472static int 1472static int
1473ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) 1473ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
1474{ 1474{
1475 ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len); 1475 ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len);
@@ -1496,7 +1496,7 @@ int __init ns_init_module(void)
1496 NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width); 1496 NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width);
1497 return -EINVAL; 1497 return -EINVAL;
1498 } 1498 }
1499 1499
1500 /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ 1500 /* Allocate and initialize mtd_info, nand_chip and nandsim structures */
1501 nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) 1501 nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip)
1502 + sizeof(struct nandsim), GFP_KERNEL); 1502 + sizeof(struct nandsim), GFP_KERNEL);
@@ -1509,7 +1509,7 @@ int __init ns_init_module(void)
1509 chip = (struct nand_chip *)(nsmtd + 1); 1509 chip = (struct nand_chip *)(nsmtd + 1);
1510 nsmtd->priv = (void *)chip; 1510 nsmtd->priv = (void *)chip;
1511 nand = (struct nandsim *)(chip + 1); 1511 nand = (struct nandsim *)(chip + 1);
1512 chip->priv = (void *)nand; 1512 chip->priv = (void *)nand;
1513 1513
1514 /* 1514 /*
1515 * Register simulator's callbacks. 1515 * Register simulator's callbacks.
@@ -1526,9 +1526,9 @@ int __init ns_init_module(void)
1526 chip->eccmode = NAND_ECC_SOFT; 1526 chip->eccmode = NAND_ECC_SOFT;
1527 chip->options |= NAND_SKIP_BBTSCAN; 1527 chip->options |= NAND_SKIP_BBTSCAN;
1528 1528
1529 /* 1529 /*
1530 * Perform minimum nandsim structure initialization to handle 1530 * Perform minimum nandsim structure initialization to handle
1531 * the initial ID read command correctly 1531 * the initial ID read command correctly
1532 */ 1532 */
1533 if (third_id_byte != 0xFF || fourth_id_byte != 0xFF) 1533 if (third_id_byte != 0xFF || fourth_id_byte != 0xFF)
1534 nand->geom.idbytes = 4; 1534 nand->geom.idbytes = 4;
@@ -1557,7 +1557,7 @@ int __init ns_init_module(void)
1557 NS_ERR("scan_bbt: can't initialize the nandsim structure\n"); 1557 NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
1558 goto error; 1558 goto error;
1559 } 1559 }
1560 1560
1561 if ((retval = nand_default_bbt(nsmtd)) != 0) { 1561 if ((retval = nand_default_bbt(nsmtd)) != 0) {
1562 free_nandsim(nand); 1562 free_nandsim(nand);
1563 goto error; 1563 goto error;
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c
index e510a83d7bdb..91a95f34a6ee 100644
--- a/drivers/mtd/nand/ppchameleonevb.c
+++ b/drivers/mtd/nand/ppchameleonevb.c
@@ -6,7 +6,7 @@
6 * Derived from drivers/mtd/nand/edb7312.c 6 * Derived from drivers/mtd/nand/edb7312.c
7 * 7 *
8 * 8 *
9 * $Id: ppchameleonevb.c,v 1.6 2004/11/05 16:07:16 kalev Exp $ 9 * $Id: ppchameleonevb.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -338,7 +338,7 @@ nand_evb_init:
338 out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0); 338 out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0);
339 out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF); 339 out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF);
340 /* enable output driver */ 340 /* enable output driver */
341 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN | 341 out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
342 NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN); 342 NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN);
343#ifdef USE_READY_BUSY_PIN 343#ifdef USE_READY_BUSY_PIN
344 /* three-state select */ 344 /* three-state select */
@@ -402,7 +402,7 @@ static void __exit ppchameleonevb_cleanup (void)
402 /* Release resources, unregister device(s) */ 402 /* Release resources, unregister device(s) */
403 nand_release (ppchameleon_mtd); 403 nand_release (ppchameleon_mtd);
404 nand_release (ppchameleonevb_mtd); 404 nand_release (ppchameleonevb_mtd);
405 405
406 /* Release iomaps */ 406 /* Release iomaps */
407 this = (struct nand_chip *) &ppchameleon_mtd[1]; 407 this = (struct nand_chip *) &ppchameleon_mtd[1];
408 iounmap((void *) this->IO_ADDR_R; 408 iounmap((void *) this->IO_ADDR_R;
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index 031051cbde76..3a5841c9d950 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -2,11 +2,11 @@
2 * drivers/mtd/nand/rtc_from4.c 2 * drivers/mtd/nand/rtc_from4.c
3 * 3 *
4 * Copyright (C) 2004 Red Hat, Inc. 4 * Copyright (C) 2004 Red Hat, Inc.
5 * 5 *
6 * Derived from drivers/mtd/nand/spia.c 6 * Derived from drivers/mtd/nand/spia.c
7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) 7 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
8 * 8 *
9 * $Id: rtc_from4.c,v 1.9 2005/01/24 20:40:11 dmarlin Exp $ 9 * $Id: rtc_from4.c,v 1.10 2005/11/07 11:14:31 gleixner Exp $
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -14,8 +14,8 @@
14 * 14 *
15 * Overview: 15 * Overview:
16 * This is a device driver for the AG-AND flash device found on the 16 * This is a device driver for the AG-AND flash device found on the
17 * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4), 17 * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4),
18 * which utilizes the Renesas HN29V1G91T-30 part. 18 * which utilizes the Renesas HN29V1G91T-30 part.
19 * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device. 19 * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device.
20 */ 20 */
21 21
@@ -105,9 +105,9 @@ const static struct mtd_partition partition_info[] = {
105}; 105};
106#define NUM_PARTITIONS 1 106#define NUM_PARTITIONS 1
107 107
108/* 108/*
109 * hardware specific flash bbt decriptors 109 * hardware specific flash bbt decriptors
110 * Note: this is to allow debugging by disabling 110 * Note: this is to allow debugging by disabling
111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE 111 * NAND_BBT_CREATE and/or NAND_BBT_WRITE
112 * 112 *
113 */ 113 */
@@ -141,7 +141,7 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
141/* the Reed Solomon control structure */ 141/* the Reed Solomon control structure */
142static struct rs_control *rs_decoder; 142static struct rs_control *rs_decoder;
143 143
144/* 144/*
145 * hardware specific Out Of Band information 145 * hardware specific Out Of Band information
146 */ 146 */
147static struct nand_oobinfo rtc_from4_nand_oobinfo = { 147static struct nand_oobinfo rtc_from4_nand_oobinfo = {
@@ -200,38 +200,38 @@ static uint8_t revbits[256] = {
200 200
201 201
202 202
203/* 203/*
204 * rtc_from4_hwcontrol - hardware specific access to control-lines 204 * rtc_from4_hwcontrol - hardware specific access to control-lines
205 * @mtd: MTD device structure 205 * @mtd: MTD device structure
206 * @cmd: hardware control command 206 * @cmd: hardware control command
207 * 207 *
208 * Address lines (A5 and A4) are used to control Command and Address Latch 208 * Address lines (A5 and A4) are used to control Command and Address Latch
209 * Enable on this board, so set the read/write address appropriately. 209 * Enable on this board, so set the read/write address appropriately.
210 * 210 *
211 * Chip Enable is also controlled by the Chip Select (CS5) and 211 * Chip Enable is also controlled by the Chip Select (CS5) and
212 * Address lines (A24-A22), so no action is required here. 212 * Address lines (A24-A22), so no action is required here.
213 * 213 *
214 */ 214 */
215static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) 215static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
216{ 216{
217 struct nand_chip* this = (struct nand_chip *) (mtd->priv); 217 struct nand_chip* this = (struct nand_chip *) (mtd->priv);
218 218
219 switch(cmd) { 219 switch(cmd) {
220 220
221 case NAND_CTL_SETCLE: 221 case NAND_CTL_SETCLE:
222 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); 222 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE);
223 break; 223 break;
224 case NAND_CTL_CLRCLE: 224 case NAND_CTL_CLRCLE:
225 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE); 225 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE);
226 break; 226 break;
227 227
228 case NAND_CTL_SETALE: 228 case NAND_CTL_SETALE:
229 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE); 229 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE);
230 break; 230 break;
231 case NAND_CTL_CLRALE: 231 case NAND_CTL_CLRALE:
232 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE); 232 this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE);
233 break; 233 break;
234 234
235 case NAND_CTL_SETNCE: 235 case NAND_CTL_SETNCE:
236 break; 236 break;
237 case NAND_CTL_CLRNCE: 237 case NAND_CTL_CLRNCE:
@@ -296,7 +296,7 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
296 * @mtd: MTD device structure 296 * @mtd: MTD device structure
297 * @chip: Chip to select (0 == slot 3, 1 == slot 4) 297 * @chip: Chip to select (0 == slot 3, 1 == slot 4)
298 * 298 *
299 * If there was a sudden loss of power during an erase operation, a 299 * If there was a sudden loss of power during an erase operation, a
300 * "device recovery" operation must be performed when power is restored 300 * "device recovery" operation must be performed when power is restored
301 * to ensure correct operation. This routine performs the required steps 301 * to ensure correct operation. This routine performs the required steps
302 * for the requested chip. 302 * for the requested chip.
@@ -312,7 +312,7 @@ static void deplete(struct mtd_info *mtd, int chip)
312 while (!this->dev_ready(mtd)); 312 while (!this->dev_ready(mtd));
313 313
314 this->select_chip(mtd, chip); 314 this->select_chip(mtd, chip);
315 315
316 /* Send the commands for device recovery, phase 1 */ 316 /* Send the commands for device recovery, phase 1 */
317 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); 317 this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
318 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); 318 this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
@@ -330,7 +330,7 @@ static void deplete(struct mtd_info *mtd, int chip)
330 * @mtd: MTD device structure 330 * @mtd: MTD device structure
331 * @mode: I/O mode; read or write 331 * @mode: I/O mode; read or write
332 * 332 *
333 * enable hardware ECC for data read or write 333 * enable hardware ECC for data read or write
334 * 334 *
335 */ 335 */
336static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) 336static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
@@ -340,7 +340,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
340 340
341 switch (mode) { 341 switch (mode) {
342 case NAND_ECC_READ : 342 case NAND_ECC_READ :
343 status = RTC_FROM4_RS_ECC_CTL_CLR 343 status = RTC_FROM4_RS_ECC_CTL_CLR
344 | RTC_FROM4_RS_ECC_CTL_FD_E; 344 | RTC_FROM4_RS_ECC_CTL_FD_E;
345 345
346 *rs_ecc_ctl = status; 346 *rs_ecc_ctl = status;
@@ -353,8 +353,8 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
353 break; 353 break;
354 354
355 case NAND_ECC_WRITE : 355 case NAND_ECC_WRITE :
356 status = RTC_FROM4_RS_ECC_CTL_CLR 356 status = RTC_FROM4_RS_ECC_CTL_CLR
357 | RTC_FROM4_RS_ECC_CTL_GEN 357 | RTC_FROM4_RS_ECC_CTL_GEN
358 | RTC_FROM4_RS_ECC_CTL_FD_E; 358 | RTC_FROM4_RS_ECC_CTL_FD_E;
359 359
360 *rs_ecc_ctl = status; 360 *rs_ecc_ctl = status;
@@ -411,7 +411,7 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
411static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2) 411static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2)
412{ 412{
413 int i, j, res; 413 int i, j, res;
414 unsigned short status; 414 unsigned short status;
415 uint16_t par[6], syn[6]; 415 uint16_t par[6], syn[6];
416 uint8_t ecc[8]; 416 uint8_t ecc[8];
417 volatile unsigned short *rs_ecc; 417 volatile unsigned short *rs_ecc;
@@ -430,7 +430,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
430 } 430 }
431 431
432 /* convert into 6 10bit syndrome fields */ 432 /* convert into 6 10bit syndrome fields */
433 par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) | 433 par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) |
434 (((uint16_t)ecc[1] << 8) & 0x300)]; 434 (((uint16_t)ecc[1] << 8) & 0x300)];
435 par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) | 435 par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) |
436 (((uint16_t)ecc[2] << 6) & 0x3c0)]; 436 (((uint16_t)ecc[2] << 6) & 0x3c0)];
@@ -456,7 +456,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
456 /* Let the library code do its magic.*/ 456 /* Let the library code do its magic.*/
457 res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL); 457 res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
458 if (res > 0) { 458 if (res > 0) {
459 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " 459 DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
460 "ECC corrected %d errors on read\n", res); 460 "ECC corrected %d errors on read\n", res);
461 } 461 }
462 return res; 462 return res;
@@ -470,9 +470,9 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
470 * @state: state or the operation 470 * @state: state or the operation
471 * @status: status code returned from read status 471 * @status: status code returned from read status
472 * @page: startpage inside the chip, must be called with (page & this->pagemask) 472 * @page: startpage inside the chip, must be called with (page & this->pagemask)
473 * 473 *
474 * Perform additional error status checks on erase and write failures 474 * Perform additional error status checks on erase and write failures
475 * to determine if errors are correctable. For this device, correctable 475 * to determine if errors are correctable. For this device, correctable
476 * 1-bit errors on erase and write are considered acceptable. 476 * 1-bit errors on erase and write are considered acceptable.
477 * 477 *
478 * note: see pages 34..37 of data sheet for details. 478 * note: see pages 34..37 of data sheet for details.
@@ -633,7 +633,7 @@ int __init rtc_from4_init (void)
633 633
634#ifdef RTC_FROM4_HWECC 634#ifdef RTC_FROM4_HWECC
635 /* We could create the decoder on demand, if memory is a concern. 635 /* We could create the decoder on demand, if memory is a concern.
636 * This way we have it handy, if an error happens 636 * This way we have it handy, if an error happens
637 * 637 *
638 * Symbolsize is 10 (bits) 638 * Symbolsize is 10 (bits)
639 * Primitve polynomial is x^10+x^3+1 639 * Primitve polynomial is x^10+x^3+1
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 2df5e47d1f5c..97e9b7892d29 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -17,8 +17,9 @@
17 * 02-May-2005 BJD Reduced hwcontrol decode 17 * 02-May-2005 BJD Reduced hwcontrol decode
18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug 18 * 20-Jun-2005 BJD Updated s3c2440 support, fixed timing bug
19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied 19 * 08-Jul-2005 BJD Fix OOPS when no platform data supplied
20 * 20-Oct-2005 BJD Fix timing calculation bug
20 * 21 *
21 * $Id: s3c2410.c,v 1.14 2005/07/06 20:05:06 bjd Exp $ 22 * $Id: s3c2410.c,v 1.20 2005/11/07 11:14:31 gleixner Exp $
22 * 23 *
23 * This program is free software; you can redistribute it and/or modify 24 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by 25 * it under the terms of the GNU General Public License as published by
@@ -136,13 +137,13 @@ static struct s3c2410_platform_nand *to_nand_plat(struct device *dev)
136 137
137/* timing calculations */ 138/* timing calculations */
138 139
139#define NS_IN_KHZ 10000000 140#define NS_IN_KHZ 1000000
140 141
141static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) 142static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
142{ 143{
143 int result; 144 int result;
144 145
145 result = (wanted * NS_IN_KHZ) / clk; 146 result = (wanted * clk) / NS_IN_KHZ;
146 result++; 147 result++;
147 148
148 pr_debug("result %d from %ld, %d\n", result, clk, wanted); 149 pr_debug("result %d from %ld, %d\n", result, clk, wanted);
@@ -159,20 +160,22 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
159 return result; 160 return result;
160} 161}
161 162
162#define to_ns(ticks,clk) (((clk) * (ticks)) / NS_IN_KHZ) 163#define to_ns(ticks,clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk))
163 164
164/* controller setup */ 165/* controller setup */
165 166
166static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, 167static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
167 struct device *dev) 168 struct device *dev)
168{ 169{
169 struct s3c2410_platform_nand *plat = to_nand_plat(dev); 170 struct s3c2410_platform_nand *plat = to_nand_plat(dev);
170 unsigned int tacls, twrph0, twrph1;
171 unsigned long clkrate = clk_get_rate(info->clk); 171 unsigned long clkrate = clk_get_rate(info->clk);
172 int tacls, twrph0, twrph1;
172 unsigned long cfg; 173 unsigned long cfg;
173 174
174 /* calculate the timing information for the controller */ 175 /* calculate the timing information for the controller */
175 176
177 clkrate /= 1000; /* turn clock into kHz for ease of use */
178
176 if (plat != NULL) { 179 if (plat != NULL) {
177 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4); 180 tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
178 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); 181 twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
@@ -183,16 +186,16 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
183 twrph0 = 8; 186 twrph0 = 8;
184 twrph1 = 8; 187 twrph1 = 8;
185 } 188 }
186 189
187 if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { 190 if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
188 printk(KERN_ERR PFX "cannot get timings suitable for board\n"); 191 printk(KERN_ERR PFX "cannot get timings suitable for board\n");
189 return -EINVAL; 192 return -EINVAL;
190 } 193 }
191 194
192 printk(KERN_INFO PFX "timing: Tacls %ldns, Twrph0 %ldns, Twrph1 %ldns\n", 195 printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
193 to_ns(tacls, clkrate), 196 tacls, to_ns(tacls, clkrate),
194 to_ns(twrph0, clkrate), 197 twrph0, to_ns(twrph0, clkrate),
195 to_ns(twrph1, clkrate)); 198 twrph1, to_ns(twrph1, clkrate));
196 199
197 if (!info->is_s3c2440) { 200 if (!info->is_s3c2440) {
198 cfg = S3C2410_NFCONF_EN; 201 cfg = S3C2410_NFCONF_EN;
@@ -216,7 +219,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
216static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) 219static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
217{ 220{
218 struct s3c2410_nand_info *info; 221 struct s3c2410_nand_info *info;
219 struct s3c2410_nand_mtd *nmtd; 222 struct s3c2410_nand_mtd *nmtd;
220 struct nand_chip *this = mtd->priv; 223 struct nand_chip *this = mtd->priv;
221 void __iomem *reg; 224 void __iomem *reg;
222 unsigned long cur; 225 unsigned long cur;
@@ -249,7 +252,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
249 writel(cur, reg); 252 writel(cur, reg);
250} 253}
251 254
252/* command and control functions 255/* command and control functions
253 * 256 *
254 * Note, these all use tglx's method of changing the IO_ADDR_W field 257 * Note, these all use tglx's method of changing the IO_ADDR_W field
255 * to make the code simpler, and use the nand layer's code to issue the 258 * to make the code simpler, and use the nand layer's code to issue the
@@ -321,7 +324,7 @@ static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
321static int s3c2410_nand_devready(struct mtd_info *mtd) 324static int s3c2410_nand_devready(struct mtd_info *mtd)
322{ 325{
323 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); 326 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
324 327
325 if (info->is_s3c2440) 328 if (info->is_s3c2440)
326 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; 329 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
327 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; 330 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
@@ -342,7 +345,7 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
342 345
343 if (read_ecc[0] == calc_ecc[0] && 346 if (read_ecc[0] == calc_ecc[0] &&
344 read_ecc[1] == calc_ecc[1] && 347 read_ecc[1] == calc_ecc[1] &&
345 read_ecc[2] == calc_ecc[2]) 348 read_ecc[2] == calc_ecc[2])
346 return 0; 349 return 0;
347 350
348 /* we curently have no method for correcting the error */ 351 /* we curently have no method for correcting the error */
@@ -433,14 +436,14 @@ static int s3c2410_nand_remove(struct device *dev)
433 436
434 dev_set_drvdata(dev, NULL); 437 dev_set_drvdata(dev, NULL);
435 438
436 if (info == NULL) 439 if (info == NULL)
437 return 0; 440 return 0;
438 441
439 /* first thing we need to do is release all our mtds 442 /* first thing we need to do is release all our mtds
440 * and their partitions, then go through freeing the 443 * and their partitions, then go through freeing the
441 * resources used 444 * resources used
442 */ 445 */
443 446
444 if (info->mtds != NULL) { 447 if (info->mtds != NULL) {
445 struct s3c2410_nand_mtd *ptr = info->mtds; 448 struct s3c2410_nand_mtd *ptr = info->mtds;
446 int mtdno; 449 int mtdno;
@@ -504,7 +507,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
504 507
505/* s3c2410_nand_init_chip 508/* s3c2410_nand_init_chip
506 * 509 *
507 * init a single instance of an chip 510 * init a single instance of an chip
508*/ 511*/
509 512
510static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, 513static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
@@ -576,7 +579,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
576 579
577 info = kmalloc(sizeof(*info), GFP_KERNEL); 580 info = kmalloc(sizeof(*info), GFP_KERNEL);
578 if (info == NULL) { 581 if (info == NULL) {
579 printk(KERN_ERR PFX "no memory for flash info\n"); 582 dev_err(dev, "no memory for flash info\n");
580 err = -ENOMEM; 583 err = -ENOMEM;
581 goto exit_error; 584 goto exit_error;
582 } 585 }
@@ -591,7 +594,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
591 594
592 info->clk = clk_get(dev, "nand"); 595 info->clk = clk_get(dev, "nand");
593 if (IS_ERR(info->clk)) { 596 if (IS_ERR(info->clk)) {
594 printk(KERN_ERR PFX "failed to get clock"); 597 dev_err(dev, "failed to get clock");
595 err = -ENOENT; 598 err = -ENOENT;
596 goto exit_error; 599 goto exit_error;
597 } 600 }
@@ -608,7 +611,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
608 info->area = request_mem_region(res->start, size, pdev->name); 611 info->area = request_mem_region(res->start, size, pdev->name);
609 612
610 if (info->area == NULL) { 613 if (info->area == NULL) {
611 printk(KERN_ERR PFX "cannot reserve register region\n"); 614 dev_err(dev, "cannot reserve register region\n");
612 err = -ENOENT; 615 err = -ENOENT;
613 goto exit_error; 616 goto exit_error;
614 } 617 }
@@ -619,12 +622,12 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
619 info->is_s3c2440 = is_s3c2440; 622 info->is_s3c2440 = is_s3c2440;
620 623
621 if (info->regs == NULL) { 624 if (info->regs == NULL) {
622 printk(KERN_ERR PFX "cannot reserve register region\n"); 625 dev_err(dev, "cannot reserve register region\n");
623 err = -EIO; 626 err = -EIO;
624 goto exit_error; 627 goto exit_error;
625 } 628 }
626 629
627 printk(KERN_INFO PFX "mapped registers at %p\n", info->regs); 630 dev_dbg(dev, "mapped registers at %p\n", info->regs);
628 631
629 /* initialise the hardware */ 632 /* initialise the hardware */
630 633
@@ -642,7 +645,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
642 size = nr_sets * sizeof(*info->mtds); 645 size = nr_sets * sizeof(*info->mtds);
643 info->mtds = kmalloc(size, GFP_KERNEL); 646 info->mtds = kmalloc(size, GFP_KERNEL);
644 if (info->mtds == NULL) { 647 if (info->mtds == NULL) {
645 printk(KERN_ERR PFX "failed to allocate mtd storage\n"); 648 dev_err(dev, "failed to allocate mtd storage\n");
646 err = -ENOMEM; 649 err = -ENOMEM;
647 goto exit_error; 650 goto exit_error;
648 } 651 }
@@ -656,7 +659,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
656 for (setno = 0; setno < nr_sets; setno++, nmtd++) { 659 for (setno = 0; setno < nr_sets; setno++, nmtd++) {
657 pr_debug("initialising set %d (%p, info %p)\n", 660 pr_debug("initialising set %d (%p, info %p)\n",
658 setno, nmtd, info); 661 setno, nmtd, info);
659 662
660 s3c2410_nand_init_chip(info, nmtd, sets); 663 s3c2410_nand_init_chip(info, nmtd, sets);
661 664
662 nmtd->scan_res = nand_scan(&nmtd->mtd, 665 nmtd->scan_res = nand_scan(&nmtd->mtd,
@@ -669,7 +672,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
669 if (sets != NULL) 672 if (sets != NULL)
670 sets++; 673 sets++;
671 } 674 }
672 675
673 pr_debug("initialised ok\n"); 676 pr_debug("initialised ok\n");
674 return 0; 677 return 0;
675 678
@@ -695,6 +698,7 @@ static int s3c2440_nand_probe(struct device *dev)
695 698
696static struct device_driver s3c2410_nand_driver = { 699static struct device_driver s3c2410_nand_driver = {
697 .name = "s3c2410-nand", 700 .name = "s3c2410-nand",
701 .owner = THIS_MODULE,
698 .bus = &platform_bus_type, 702 .bus = &platform_bus_type,
699 .probe = s3c2410_nand_probe, 703 .probe = s3c2410_nand_probe,
700 .remove = s3c2410_nand_remove, 704 .remove = s3c2410_nand_remove,
@@ -702,6 +706,7 @@ static struct device_driver s3c2410_nand_driver = {
702 706
703static struct device_driver s3c2440_nand_driver = { 707static struct device_driver s3c2440_nand_driver = {
704 .name = "s3c2440-nand", 708 .name = "s3c2440-nand",
709 .owner = THIS_MODULE,
705 .bus = &platform_bus_type, 710 .bus = &platform_bus_type,
706 .probe = s3c2440_nand_probe, 711 .probe = s3c2440_nand_probe,
707 .remove = s3c2410_nand_remove, 712 .remove = s3c2410_nand_remove,
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c
index 88b5b5b40b43..1924a4f137c7 100644
--- a/drivers/mtd/nand/sharpsl.c
+++ b/drivers/mtd/nand/sharpsl.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2004 Richard Purdie 4 * Copyright (C) 2004 Richard Purdie
5 * 5 *
6 * $Id: sharpsl.c,v 1.4 2005/01/23 11:09:19 rpurdie Exp $ 6 * $Id: sharpsl.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
7 * 7 *
8 * Based on Sharp's NAND driver sharp_sl.c 8 * Based on Sharp's NAND driver sharp_sl.c
9 * 9 *
@@ -76,14 +76,14 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = {
76 }, 76 },
77}; 77};
78 78
79/* 79/*
80 * hardware specific access to control-lines 80 * hardware specific access to control-lines
81 */ 81 */
82static void 82static void
83sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd) 83sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
84{ 84{
85 switch (cmd) { 85 switch (cmd) {
86 case NAND_CTL_SETCLE: 86 case NAND_CTL_SETCLE:
87 writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); 87 writeb(readb(FLASHCTL) | FLCLE, FLASHCTL);
88 break; 88 break;
89 case NAND_CTL_CLRCLE: 89 case NAND_CTL_CLRCLE:
@@ -97,10 +97,10 @@ sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
97 writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL); 97 writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
98 break; 98 break;
99 99
100 case NAND_CTL_SETNCE: 100 case NAND_CTL_SETNCE:
101 writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL); 101 writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
102 break; 102 break;
103 case NAND_CTL_CLRNCE: 103 case NAND_CTL_CLRNCE:
104 writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL); 104 writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
105 break; 105 break;
106 } 106 }
@@ -115,6 +115,23 @@ static struct nand_bbt_descr sharpsl_bbt = {
115 .pattern = scan_ff_pattern 115 .pattern = scan_ff_pattern
116}; 116};
117 117
118static struct nand_bbt_descr sharpsl_akita_bbt = {
119 .options = 0,
120 .offs = 4,
121 .len = 1,
122 .pattern = scan_ff_pattern
123};
124
125static struct nand_oobinfo akita_oobinfo = {
126 .useecc = MTD_NANDECC_AUTOPLACE,
127 .eccbytes = 24,
128 .eccpos = {
129 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
130 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
131 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
132 .oobfree = { {0x08, 0x09} }
133};
134
118static int 135static int
119sharpsl_nand_dev_ready(struct mtd_info* mtd) 136sharpsl_nand_dev_ready(struct mtd_info* mtd)
120{ 137{
@@ -160,7 +177,7 @@ sharpsl_nand_init(void)
160 printk ("Unable to allocate SharpSL NAND MTD device structure.\n"); 177 printk ("Unable to allocate SharpSL NAND MTD device structure.\n");
161 return -ENOMEM; 178 return -ENOMEM;
162 } 179 }
163 180
164 /* map physical adress */ 181 /* map physical adress */
165 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000); 182 sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
166 if(!sharpsl_io_base){ 183 if(!sharpsl_io_base){
@@ -168,7 +185,7 @@ sharpsl_nand_init(void)
168 kfree(sharpsl_mtd); 185 kfree(sharpsl_mtd);
169 return -EIO; 186 return -EIO;
170 } 187 }
171 188
172 /* Get pointer to private data */ 189 /* Get pointer to private data */
173 this = (struct nand_chip *) (&sharpsl_mtd[1]); 190 this = (struct nand_chip *) (&sharpsl_mtd[1]);
174 191
@@ -194,10 +211,14 @@ sharpsl_nand_init(void)
194 this->chip_delay = 15; 211 this->chip_delay = 15;
195 /* set eccmode using hardware ECC */ 212 /* set eccmode using hardware ECC */
196 this->eccmode = NAND_ECC_HW3_256; 213 this->eccmode = NAND_ECC_HW3_256;
214 this->badblock_pattern = &sharpsl_bbt;
215 if (machine_is_akita() || machine_is_borzoi()) {
216 this->badblock_pattern = &sharpsl_akita_bbt;
217 this->autooob = &akita_oobinfo;
218 }
197 this->enable_hwecc = sharpsl_nand_enable_hwecc; 219 this->enable_hwecc = sharpsl_nand_enable_hwecc;
198 this->calculate_ecc = sharpsl_nand_calculate_ecc; 220 this->calculate_ecc = sharpsl_nand_calculate_ecc;
199 this->correct_data = nand_correct_data; 221 this->correct_data = nand_correct_data;
200 this->badblock_pattern = &sharpsl_bbt;
201 222
202 /* Scan to find existence of the device */ 223 /* Scan to find existence of the device */
203 err=nand_scan(sharpsl_mtd,1); 224 err=nand_scan(sharpsl_mtd,1);
@@ -211,7 +232,7 @@ sharpsl_nand_init(void)
211 sharpsl_mtd->name = "sharpsl-nand"; 232 sharpsl_mtd->name = "sharpsl-nand";
212 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, 233 nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes,
213 &sharpsl_partition_info, 0); 234 &sharpsl_partition_info, 0);
214 235
215 if (nr_partitions <= 0) { 236 if (nr_partitions <= 0) {
216 nr_partitions = DEFAULT_NUM_PARTITIONS; 237 nr_partitions = DEFAULT_NUM_PARTITIONS;
217 sharpsl_partition_info = sharpsl_nand_default_partition_info; 238 sharpsl_partition_info = sharpsl_nand_default_partition_info;
@@ -230,7 +251,7 @@ sharpsl_nand_init(void)
230 } 251 }
231 } 252 }
232 253
233 if (machine_is_husky() || machine_is_borzoi()) { 254 if (machine_is_husky() || machine_is_borzoi() || machine_is_akita()) {
234 /* Need to use small eraseblock size for backward compatibility */ 255 /* Need to use small eraseblock size for backward compatibility */
235 sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS; 256 sharpsl_mtd->flags |= MTD_NO_VIRTBLOCKS;
236 } 257 }
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c
index b777c412b758..32541cbb0103 100644
--- a/drivers/mtd/nand/spia.c
+++ b/drivers/mtd/nand/spia.c
@@ -8,7 +8,7 @@
8 * to controllines (due to change in nand.c) 8 * to controllines (due to change in nand.c)
9 * page_cache added 9 * page_cache added
10 * 10 *
11 * $Id: spia.c,v 1.24 2004/11/04 12:53:10 gleixner Exp $ 11 * $Id: spia.c,v 1.25 2005/11/07 11:14:31 gleixner Exp $
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as 14 * it under the terms of the GNU General Public License version 2 as
@@ -82,7 +82,7 @@ const static struct mtd_partition partition_info[] = {
82#define NUM_PARTITIONS 2 82#define NUM_PARTITIONS 2
83 83
84 84
85/* 85/*
86 * hardware specific access to control-lines 86 * hardware specific access to control-lines
87*/ 87*/
88static void spia_hwcontrol(struct mtd_info *mtd, int cmd){ 88static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
@@ -137,7 +137,7 @@ int __init spia_init (void)
137 /* Set address of hardware control function */ 137 /* Set address of hardware control function */
138 this->hwcontrol = spia_hwcontrol; 138 this->hwcontrol = spia_hwcontrol;
139 /* 15 us command delay time */ 139 /* 15 us command delay time */
140 this->chip_delay = 15; 140 this->chip_delay = 15;
141 141
142 /* Scan to find existence of the device */ 142 /* Scan to find existence of the device */
143 if (nand_scan (spia_mtd, 1)) { 143 if (nand_scan (spia_mtd, 1)) {
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c
index 52c808fb5fa9..7609c43cb3ec 100644
--- a/drivers/mtd/nand/toto.c
+++ b/drivers/mtd/nand/toto.c
@@ -15,7 +15,7 @@
15 * This is a device driver for the NAND flash device found on the 15 * This is a device driver for the NAND flash device found on the
16 * TI fido board. It supports 32MiB and 64MiB cards 16 * TI fido board. It supports 32MiB and 64MiB cards
17 * 17 *
18 * $Id: toto.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $ 18 * $Id: toto.c,v 1.5 2005/11/07 11:14:31 gleixner Exp $
19 */ 19 */
20 20
21#include <linux/slab.h> 21#include <linux/slab.h>
@@ -57,7 +57,7 @@ static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
57#endif 57#endif
58#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0) 58#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
59#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE) 59#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
60 60
61/* 61/*
62 * Define partitions for flash devices 62 * Define partitions for flash devices
63 */ 63 */
@@ -91,7 +91,7 @@ static struct mtd_partition partition_info32M[] = {
91 91
92#define NUM_PARTITIONS32M 3 92#define NUM_PARTITIONS32M 3
93#define NUM_PARTITIONS64M 4 93#define NUM_PARTITIONS64M 4
94/* 94/*
95 * hardware specific access to control-lines 95 * hardware specific access to control-lines
96*/ 96*/
97 97
@@ -146,7 +146,7 @@ int __init toto_init (void)
146 this->hwcontrol = toto_hwcontrol; 146 this->hwcontrol = toto_hwcontrol;
147 this->dev_ready = NULL; 147 this->dev_ready = NULL;
148 /* 25 us command delay time */ 148 /* 25 us command delay time */
149 this->chip_delay = 30; 149 this->chip_delay = 30;
150 this->eccmode = NAND_ECC_SOFT; 150 this->eccmode = NAND_ECC_SOFT;
151 151
152 /* Scan to find existance of the device */ 152 /* Scan to find existance of the device */
@@ -157,10 +157,10 @@ int __init toto_init (void)
157 157
158 /* Register the partitions */ 158 /* Register the partitions */
159 switch(toto_mtd->size){ 159 switch(toto_mtd->size){
160 case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; 160 case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
161 case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; 161 case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
162 default: { 162 default: {
163 printk (KERN_WARNING "Unsupported Nand device\n"); 163 printk (KERN_WARNING "Unsupported Nand device\n");
164 err = -ENXIO; 164 err = -ENXIO;
165 goto out_buf; 165 goto out_buf;
166 } 166 }
@@ -170,9 +170,9 @@ int __init toto_init (void)
170 archflashwp(0,0); /* open up flash for writing */ 170 archflashwp(0,0); /* open up flash for writing */
171 171
172 goto out; 172 goto out;
173 173
174out_buf: 174out_buf:
175 kfree (this->data_buf); 175 kfree (this->data_buf);
176out_mtd: 176out_mtd:
177 kfree (toto_mtd); 177 kfree (toto_mtd);
178out: 178out:
@@ -194,7 +194,7 @@ static void __exit toto_cleanup (void)
194 194
195 /* stop flash writes */ 195 /* stop flash writes */
196 archflashwp(0,1); 196 archflashwp(0,1);
197 197
198 /* release gpios to system */ 198 /* release gpios to system */
199 gpiorelease(NAND_MASK); 199 gpiorelease(NAND_MASK);
200} 200}
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index b2014043634f..d7cd5fa16ba4 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -1,7 +1,7 @@
1/* Linux driver for NAND Flash Translation Layer */ 1/* Linux driver for NAND Flash Translation Layer */
2/* (c) 1999 Machine Vision Holdings, Inc. */ 2/* (c) 1999 Machine Vision Holdings, Inc. */
3/* Author: David Woodhouse <dwmw2@infradead.org> */ 3/* Author: David Woodhouse <dwmw2@infradead.org> */
4/* $Id: nftlcore.c,v 1.97 2004/11/16 18:28:59 dwmw2 Exp $ */ 4/* $Id: nftlcore.c,v 1.98 2005/11/07 11:14:21 gleixner Exp $ */
5 5
6/* 6/*
7 The contents of this file are distributed under the GNU General 7 The contents of this file are distributed under the GNU General
@@ -101,23 +101,21 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
101 101
102 if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) { 102 if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
103 /* 103 /*
104 Oh no we don't have 104 Oh no we don't have
105 mbd.size == heads * cylinders * sectors 105 mbd.size == heads * cylinders * sectors
106 */ 106 */
107 printk(KERN_WARNING "NFTL: cannot calculate a geometry to " 107 printk(KERN_WARNING "NFTL: cannot calculate a geometry to "
108 "match size of 0x%lx.\n", nftl->mbd.size); 108 "match size of 0x%lx.\n", nftl->mbd.size);
109 printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d " 109 printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "
110 "(== 0x%lx sects)\n", 110 "(== 0x%lx sects)\n",
111 nftl->cylinders, nftl->heads , nftl->sectors, 111 nftl->cylinders, nftl->heads , nftl->sectors,
112 (long)nftl->cylinders * (long)nftl->heads * 112 (long)nftl->cylinders * (long)nftl->heads *
113 (long)nftl->sectors ); 113 (long)nftl->sectors );
114 } 114 }
115 115
116 if (add_mtd_blktrans_dev(&nftl->mbd)) { 116 if (add_mtd_blktrans_dev(&nftl->mbd)) {
117 if (nftl->ReplUnitTable) 117 kfree(nftl->ReplUnitTable);
118 kfree(nftl->ReplUnitTable); 118 kfree(nftl->EUNtable);
119 if (nftl->EUNtable)
120 kfree(nftl->EUNtable);
121 kfree(nftl); 119 kfree(nftl);
122 return; 120 return;
123 } 121 }
@@ -133,10 +131,8 @@ static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
133 DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum); 131 DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);
134 132
135 del_mtd_blktrans_dev(dev); 133 del_mtd_blktrans_dev(dev);
136 if (nftl->ReplUnitTable) 134 kfree(nftl->ReplUnitTable);
137 kfree(nftl->ReplUnitTable); 135 kfree(nftl->EUNtable);
138 if (nftl->EUNtable)
139 kfree(nftl->EUNtable);
140 kfree(nftl); 136 kfree(nftl);
141} 137}
142 138
@@ -178,7 +174,7 @@ static u16 NFTL_findfreeblock(struct NFTLrecord *nftl, int desperate )
178 174
179 if (!silly--) { 175 if (!silly--) {
180 printk("Argh! No free blocks found! LastFreeEUN = %d, " 176 printk("Argh! No free blocks found! LastFreeEUN = %d, "
181 "FirstEUN = %d\n", nftl->LastFreeEUN, 177 "FirstEUN = %d\n", nftl->LastFreeEUN,
182 le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN)); 178 le16_to_cpu(nftl->MediaHdr.FirstPhysicalEUN));
183 return 0xffff; 179 return 0xffff;
184 } 180 }
@@ -210,7 +206,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
210 "Virtual Unit Chain %d!\n", thisVUC); 206 "Virtual Unit Chain %d!\n", thisVUC);
211 return BLOCK_NIL; 207 return BLOCK_NIL;
212 } 208 }
213 209
214 /* Scan to find the Erase Unit which holds the actual data for each 210 /* Scan to find the Erase Unit which holds the actual data for each
215 512-byte block within the Chain. 211 512-byte block within the Chain.
216 */ 212 */
@@ -227,7 +223,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
227 if (block == 2) { 223 if (block == 2) {
228 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1; 224 foldmark = oob.u.c.FoldMark | oob.u.c.FoldMark1;
229 if (foldmark == FOLD_MARK_IN_PROGRESS) { 225 if (foldmark == FOLD_MARK_IN_PROGRESS) {
230 DEBUG(MTD_DEBUG_LEVEL1, 226 DEBUG(MTD_DEBUG_LEVEL1,
231 "Write Inhibited on EUN %d\n", thisEUN); 227 "Write Inhibited on EUN %d\n", thisEUN);
232 inplace = 0; 228 inplace = 0;
233 } else { 229 } else {
@@ -249,7 +245,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
249 if (!BlockFreeFound[block]) 245 if (!BlockFreeFound[block])
250 BlockMap[block] = thisEUN; 246 BlockMap[block] = thisEUN;
251 else 247 else
252 printk(KERN_WARNING 248 printk(KERN_WARNING
253 "SECTOR_USED found after SECTOR_FREE " 249 "SECTOR_USED found after SECTOR_FREE "
254 "in Virtual Unit Chain %d for block %d\n", 250 "in Virtual Unit Chain %d for block %d\n",
255 thisVUC, block); 251 thisVUC, block);
@@ -258,7 +254,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
258 if (!BlockFreeFound[block]) 254 if (!BlockFreeFound[block])
259 BlockMap[block] = BLOCK_NIL; 255 BlockMap[block] = BLOCK_NIL;
260 else 256 else
261 printk(KERN_WARNING 257 printk(KERN_WARNING
262 "SECTOR_DELETED found after SECTOR_FREE " 258 "SECTOR_DELETED found after SECTOR_FREE "
263 "in Virtual Unit Chain %d for block %d\n", 259 "in Virtual Unit Chain %d for block %d\n",
264 thisVUC, block); 260 thisVUC, block);
@@ -277,14 +273,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
277 thisVUC); 273 thisVUC);
278 return BLOCK_NIL; 274 return BLOCK_NIL;
279 } 275 }
280 276
281 thisEUN = nftl->ReplUnitTable[thisEUN]; 277 thisEUN = nftl->ReplUnitTable[thisEUN];
282 } 278 }
283 279
284 if (inplace) { 280 if (inplace) {
285 /* We're being asked to be a fold-in-place. Check 281 /* We're being asked to be a fold-in-place. Check
286 that all blocks which actually have data associated 282 that all blocks which actually have data associated
287 with them (i.e. BlockMap[block] != BLOCK_NIL) are 283 with them (i.e. BlockMap[block] != BLOCK_NIL) are
288 either already present or SECTOR_FREE in the target 284 either already present or SECTOR_FREE in the target
289 block. If not, we're going to have to fold out-of-place 285 block. If not, we're going to have to fold out-of-place
290 anyway. 286 anyway.
@@ -297,7 +293,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
297 "block %d was %x lastEUN, " 293 "block %d was %x lastEUN, "
298 "and is in EUN %d (%s) %d\n", 294 "and is in EUN %d (%s) %d\n",
299 thisVUC, block, BlockLastState[block], 295 thisVUC, block, BlockLastState[block],
300 BlockMap[block], 296 BlockMap[block],
301 BlockMap[block]== targetEUN ? "==" : "!=", 297 BlockMap[block]== targetEUN ? "==" : "!=",
302 targetEUN); 298 targetEUN);
303 inplace = 0; 299 inplace = 0;
@@ -314,17 +310,17 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
314 inplace = 0; 310 inplace = 0;
315 } 311 }
316 } 312 }
317 313
318 if (!inplace) { 314 if (!inplace) {
319 DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. " 315 DEBUG(MTD_DEBUG_LEVEL1, "Cannot fold Virtual Unit Chain %d in place. "
320 "Trying out-of-place\n", thisVUC); 316 "Trying out-of-place\n", thisVUC);
321 /* We need to find a targetEUN to fold into. */ 317 /* We need to find a targetEUN to fold into. */
322 targetEUN = NFTL_findfreeblock(nftl, 1); 318 targetEUN = NFTL_findfreeblock(nftl, 1);
323 if (targetEUN == BLOCK_NIL) { 319 if (targetEUN == BLOCK_NIL) {
324 /* Ouch. Now we're screwed. We need to do a 320 /* Ouch. Now we're screwed. We need to do a
325 fold-in-place of another chain to make room 321 fold-in-place of another chain to make room
326 for this one. We need a better way of selecting 322 for this one. We need a better way of selecting
327 which chain to fold, because makefreeblock will 323 which chain to fold, because makefreeblock will
328 only ask us to fold the same one again. 324 only ask us to fold the same one again.
329 */ 325 */
330 printk(KERN_WARNING 326 printk(KERN_WARNING
@@ -338,7 +334,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
338 chain by selecting the longer one */ 334 chain by selecting the longer one */
339 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS); 335 oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
340 oob.u.c.unused = 0xffffffff; 336 oob.u.c.unused = 0xffffffff;
341 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 337 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
342 8, &retlen, (char *)&oob.u); 338 8, &retlen, (char *)&oob.u);
343 } 339 }
344 340
@@ -361,14 +357,14 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
361 happen in case of media errors or deleted blocks) */ 357 happen in case of media errors or deleted blocks) */
362 if (BlockMap[block] == BLOCK_NIL) 358 if (BlockMap[block] == BLOCK_NIL)
363 continue; 359 continue;
364 360
365 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512), 361 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
366 512, &retlen, movebuf); 362 512, &retlen, movebuf);
367 if (ret < 0) { 363 if (ret < 0) {
368 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) 364 ret = MTD_READ(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block])
369 + (block * 512), 512, &retlen, 365 + (block * 512), 512, &retlen,
370 movebuf); 366 movebuf);
371 if (ret != -EIO) 367 if (ret != -EIO)
372 printk("Error went away on retry.\n"); 368 printk("Error went away on retry.\n");
373 } 369 }
374 memset(&oob, 0xff, sizeof(struct nftl_oob)); 370 memset(&oob, 0xff, sizeof(struct nftl_oob));
@@ -376,18 +372,18 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
376 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512), 372 MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512),
377 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo); 373 512, &retlen, movebuf, (char *)&oob, &nftl->oobinfo);
378 } 374 }
379 375
380 /* add the header so that it is now a valid chain */ 376 /* add the header so that it is now a valid chain */
381 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum 377 oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum
382 = cpu_to_le16(thisVUC); 378 = cpu_to_le16(thisVUC);
383 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff; 379 oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
384 380
385 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8, 381 MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8,
386 8, &retlen, (char *)&oob.u); 382 8, &retlen, (char *)&oob.u);
387 383
388 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */ 384 /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
389 385
390 /* At this point, we have two different chains for this Virtual Unit, and no way to tell 386 /* At this point, we have two different chains for this Virtual Unit, and no way to tell
391 them apart. If we crash now, we get confused. However, both contain the same data, so we 387 them apart. If we crash now, we get confused. However, both contain the same data, so we
392 shouldn't actually lose data in this case. It's just that when we load up on a medium which 388 shouldn't actually lose data in this case. It's just that when we load up on a medium which
393 has duplicate chains, we need to free one of the chains because it's not necessary any more. 389 has duplicate chains, we need to free one of the chains because it's not necessary any more.
@@ -395,7 +391,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
395 thisEUN = nftl->EUNtable[thisVUC]; 391 thisEUN = nftl->EUNtable[thisVUC];
396 DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n"); 392 DEBUG(MTD_DEBUG_LEVEL1,"Want to erase\n");
397 393
398 /* For each block in the old chain (except the targetEUN of course), 394 /* For each block in the old chain (except the targetEUN of course),
399 free it and make it available for future use */ 395 free it and make it available for future use */
400 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) { 396 while (thisEUN <= nftl->lastEUN && thisEUN != targetEUN) {
401 unsigned int EUNtmp; 397 unsigned int EUNtmp;
@@ -413,7 +409,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
413 } 409 }
414 thisEUN = EUNtmp; 410 thisEUN = EUNtmp;
415 } 411 }
416 412
417 /* Make this the new start of chain for thisVUC */ 413 /* Make this the new start of chain for thisVUC */
418 nftl->ReplUnitTable[targetEUN] = BLOCK_NIL; 414 nftl->ReplUnitTable[targetEUN] = BLOCK_NIL;
419 nftl->EUNtable[thisVUC] = targetEUN; 415 nftl->EUNtable[thisVUC] = targetEUN;
@@ -423,7 +419,7 @@ static u16 NFTL_foldchain (struct NFTLrecord *nftl, unsigned thisVUC, unsigned p
423 419
424static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock) 420static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
425{ 421{
426 /* This is the part that needs some cleverness applied. 422 /* This is the part that needs some cleverness applied.
427 For now, I'm doing the minimum applicable to actually 423 For now, I'm doing the minimum applicable to actually
428 get the thing to work. 424 get the thing to work.
429 Wear-levelling and other clever stuff needs to be implemented 425 Wear-levelling and other clever stuff needs to be implemented
@@ -470,7 +466,7 @@ static u16 NFTL_makefreeblock( struct NFTLrecord *nftl , unsigned pendingblock)
470 return NFTL_foldchain (nftl, LongestChain, pendingblock); 466 return NFTL_foldchain (nftl, LongestChain, pendingblock);
471} 467}
472 468
473/* NFTL_findwriteunit: Return the unit number into which we can write 469/* NFTL_findwriteunit: Return the unit number into which we can write
474 for this block. Make it available if it isn't already 470 for this block. Make it available if it isn't already
475*/ 471*/
476static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block) 472static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
@@ -488,7 +484,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
488 a free space for the block in question. 484 a free space for the block in question.
489 */ 485 */
490 486
491 /* This condition catches the 0x[7f]fff cases, as well as 487 /* This condition catches the 0x[7f]fff cases, as well as
492 being a sanity check for past-end-of-media access 488 being a sanity check for past-end-of-media access
493 */ 489 */
494 lastEUN = BLOCK_NIL; 490 lastEUN = BLOCK_NIL;
@@ -503,7 +499,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
503 499
504 MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs, 500 MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
505 8, &retlen, (char *)&bci); 501 8, &retlen, (char *)&bci);
506 502
507 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n", 503 DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
508 block , writeEUN, le16_to_cpu(bci.Status)); 504 block , writeEUN, le16_to_cpu(bci.Status));
509 505
@@ -518,10 +514,10 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
518 break; 514 break;
519 default: 515 default:
520 // Invalid block. Don't use it any more. Must implement. 516 // Invalid block. Don't use it any more. Must implement.
521 break; 517 break;
522 } 518 }
523 519
524 if (!silly--) { 520 if (!silly--) {
525 printk(KERN_WARNING 521 printk(KERN_WARNING
526 "Infinite loop in Virtual Unit Chain 0x%x\n", 522 "Infinite loop in Virtual Unit Chain 0x%x\n",
527 thisVUC); 523 thisVUC);
@@ -532,7 +528,7 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
532 writeEUN = nftl->ReplUnitTable[writeEUN]; 528 writeEUN = nftl->ReplUnitTable[writeEUN];
533 } 529 }
534 530
535 /* OK. We didn't find one in the existing chain, or there 531 /* OK. We didn't find one in the existing chain, or there
536 is no existing chain. */ 532 is no existing chain. */
537 533
538 /* Try to find an already-free block */ 534 /* Try to find an already-free block */
@@ -546,12 +542,12 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
546 542
547 /* First remember the start of this chain */ 543 /* First remember the start of this chain */
548 //u16 startEUN = nftl->EUNtable[thisVUC]; 544 //u16 startEUN = nftl->EUNtable[thisVUC];
549 545
550 //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC); 546 //printk("Write to VirtualUnitChain %d, calling makefreeblock()\n", thisVUC);
551 writeEUN = NFTL_makefreeblock(nftl, 0xffff); 547 writeEUN = NFTL_makefreeblock(nftl, 0xffff);
552 548
553 if (writeEUN == BLOCK_NIL) { 549 if (writeEUN == BLOCK_NIL) {
554 /* OK, we accept that the above comment is 550 /* OK, we accept that the above comment is
555 lying - there may have been free blocks 551 lying - there may have been free blocks
556 last time we called NFTL_findfreeblock(), 552 last time we called NFTL_findfreeblock(),
557 but they are reserved for when we're 553 but they are reserved for when we're
@@ -562,21 +558,21 @@ static inline u16 NFTL_findwriteunit(struct NFTLrecord *nftl, unsigned block)
562 } 558 }
563 if (writeEUN == BLOCK_NIL) { 559 if (writeEUN == BLOCK_NIL) {
564 /* Ouch. This should never happen - we should 560 /* Ouch. This should never happen - we should
565 always be able to make some room somehow. 561 always be able to make some room somehow.
566 If we get here, we've allocated more storage 562 If we get here, we've allocated more storage
567 space than actual media, or our makefreeblock 563 space than actual media, or our makefreeblock
568 routine is missing something. 564 routine is missing something.
569 */ 565 */
570 printk(KERN_WARNING "Cannot make free space.\n"); 566 printk(KERN_WARNING "Cannot make free space.\n");
571 return BLOCK_NIL; 567 return BLOCK_NIL;
572 } 568 }
573 //printk("Restarting scan\n"); 569 //printk("Restarting scan\n");
574 lastEUN = BLOCK_NIL; 570 lastEUN = BLOCK_NIL;
575 continue; 571 continue;
576 } 572 }
577 573
578 /* We've found a free block. Insert it into the chain. */ 574 /* We've found a free block. Insert it into the chain. */
579 575
580 if (lastEUN != BLOCK_NIL) { 576 if (lastEUN != BLOCK_NIL) {
581 thisVUC |= 0x8000; /* It's a replacement block */ 577 thisVUC |= 0x8000; /* It's a replacement block */
582 } else { 578 } else {
@@ -749,7 +745,7 @@ extern char nftlmountrev[];
749 745
750static int __init init_nftl(void) 746static int __init init_nftl(void)
751{ 747{
752 printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.97 $, nftlmount.c %s\n", nftlmountrev); 748 printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.98 $, nftlmount.c %s\n", nftlmountrev);
753 749
754 return register_mtd_blktrans(&nftl_tr); 750 return register_mtd_blktrans(&nftl_tr);
755} 751}
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c
index 84afd9029f53..3b104ebb219a 100644
--- a/drivers/mtd/nftlmount.c
+++ b/drivers/mtd/nftlmount.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * NFTL mount code with extensive checks 2 * NFTL mount code with extensive checks
3 * 3 *
4 * Author: Fabrice Bellard (fabrice.bellard@netgem.com) 4 * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
5 * Copyright (C) 2000 Netgem S.A. 5 * Copyright (C) 2000 Netgem S.A.
6 * 6 *
7 * $Id: nftlmount.c,v 1.40 2004/11/22 14:38:29 kalev Exp $ 7 * $Id: nftlmount.c,v 1.41 2005/11/07 11:14:21 gleixner Exp $
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
31 31
32#define SECTORSIZE 512 32#define SECTORSIZE 512
33 33
34char nftlmountrev[]="$Revision: 1.40 $"; 34char nftlmountrev[]="$Revision: 1.41 $";
35 35
36/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the 36/* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
37 * various device information of the NFTL partition and Bad Unit Table. Update 37 * various device information of the NFTL partition and Bad Unit Table. Update
@@ -47,7 +47,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
47 struct NFTLMediaHeader *mh = &nftl->MediaHdr; 47 struct NFTLMediaHeader *mh = &nftl->MediaHdr;
48 unsigned int i; 48 unsigned int i;
49 49
50 /* Assume logical EraseSize == physical erasesize for starting the scan. 50 /* Assume logical EraseSize == physical erasesize for starting the scan.
51 We'll sort it out later if we find a MediaHeader which says otherwise */ 51 We'll sort it out later if we find a MediaHeader which says otherwise */
52 /* Actually, we won't. The new DiskOnChip driver has already scanned 52 /* Actually, we won't. The new DiskOnChip driver has already scanned
53 the MediaHeader and adjusted the virtual erasesize it presents in 53 the MediaHeader and adjusted the virtual erasesize it presents in
@@ -83,9 +83,9 @@ static int find_boot_record(struct NFTLrecord *nftl)
83 if (retlen < 6 || memcmp(buf, "ANAND", 6)) { 83 if (retlen < 6 || memcmp(buf, "ANAND", 6)) {
84 /* ANAND\0 not found. Continue */ 84 /* ANAND\0 not found. Continue */
85#if 0 85#if 0
86 printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n", 86 printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n",
87 block * nftl->EraseSize, nftl->mbd.mtd->index); 87 block * nftl->EraseSize, nftl->mbd.mtd->index);
88#endif 88#endif
89 continue; 89 continue;
90 } 90 }
91 91
@@ -103,7 +103,7 @@ static int find_boot_record(struct NFTLrecord *nftl)
103 */ 103 */
104 if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) { 104 if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) {
105 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n", 105 printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
106 block * nftl->EraseSize, nftl->mbd.mtd->index, 106 block * nftl->EraseSize, nftl->mbd.mtd->index,
107 le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1)); 107 le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1));
108 continue; 108 continue;
109 } 109 }
@@ -175,7 +175,7 @@ device is already correct.
175 nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN); 175 nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
176 if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) { 176 if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
177 printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n"); 177 printk(KERN_NOTICE "NFTL Media Header sanity check failed:\n");
178 printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n", 178 printk(KERN_NOTICE "nb_boot_blocks (%d) + 2 > nb_blocks (%d)\n",
179 nftl->nb_boot_blocks, nftl->nb_blocks); 179 nftl->nb_boot_blocks, nftl->nb_blocks);
180 return -1; 180 return -1;
181 } 181 }
@@ -187,7 +187,7 @@ device is already correct.
187 nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks); 187 nftl->numvunits, nftl->nb_blocks, nftl->nb_boot_blocks);
188 return -1; 188 return -1;
189 } 189 }
190 190
191 nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE); 191 nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
192 192
193 /* If we're not using the last sectors in the device for some reason, 193 /* If we're not using the last sectors in the device for some reason,
@@ -210,12 +210,12 @@ device is already correct.
210 printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n"); 210 printk(KERN_NOTICE "NFTL: allocation of ReplUnitTable failed\n");
211 return -ENOMEM; 211 return -ENOMEM;
212 } 212 }
213 213
214 /* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */ 214 /* mark the bios blocks (blocks before NFTL MediaHeader) as reserved */
215 for (i = 0; i < nftl->nb_boot_blocks; i++) 215 for (i = 0; i < nftl->nb_boot_blocks; i++)
216 nftl->ReplUnitTable[i] = BLOCK_RESERVED; 216 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
217 /* mark all remaining blocks as potentially containing data */ 217 /* mark all remaining blocks as potentially containing data */
218 for (; i < nftl->nb_blocks; i++) { 218 for (; i < nftl->nb_blocks; i++) {
219 nftl->ReplUnitTable[i] = BLOCK_NOTEXPLORED; 219 nftl->ReplUnitTable[i] = BLOCK_NOTEXPLORED;
220 } 220 }
221 221
@@ -245,12 +245,12 @@ The new DiskOnChip driver already scanned the bad block table. Just query it.
245 if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize)) 245 if (nftl->mbd.mtd->block_isbad(nftl->mbd.mtd, i * nftl->EraseSize))
246 nftl->ReplUnitTable[i] = BLOCK_RESERVED; 246 nftl->ReplUnitTable[i] = BLOCK_RESERVED;
247 } 247 }
248 248
249 nftl->MediaUnit = block; 249 nftl->MediaUnit = block;
250 boot_record_count++; 250 boot_record_count++;
251 251
252 } /* foreach (block) */ 252 } /* foreach (block) */
253 253
254 return boot_record_count?0:-1; 254 return boot_record_count?0:-1;
255} 255}
256 256
@@ -265,7 +265,7 @@ static int memcmpb(void *a, int c, int n)
265} 265}
266 266
267/* check_free_sector: check if a free sector is actually FREE, i.e. All 0xff in data and oob area */ 267/* check_free_sector: check if a free sector is actually FREE, i.e. All 0xff in data and oob area */
268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, 268static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len,
269 int check_oob) 269 int check_oob)
270{ 270{
271 int i; 271 int i;
@@ -293,7 +293,7 @@ static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int
293 * 293 *
294 * Return: 0 when succeed, -1 on error. 294 * Return: 0 when succeed, -1 on error.
295 * 295 *
296 * ToDo: 1. Is it neceressary to check_free_sector after erasing ?? 296 * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
297 */ 297 */
298int NFTL_formatblock(struct NFTLrecord *nftl, int block) 298int NFTL_formatblock(struct NFTLrecord *nftl, int block)
299{ 299{
@@ -385,7 +385,7 @@ static void check_sectors_in_chain(struct NFTLrecord *nftl, unsigned int first_b
385 /* verify that the sector is really free. If not, mark 385 /* verify that the sector is really free. If not, mark
386 as ignore */ 386 as ignore */
387 if (memcmpb(&bci, 0xff, 8) != 0 || 387 if (memcmpb(&bci, 0xff, 8) != 0 ||
388 check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE, 388 check_free_sectors(nftl, block * nftl->EraseSize + i * SECTORSIZE,
389 SECTORSIZE, 0) != 0) { 389 SECTORSIZE, 0) != 0) {
390 printk("Incorrect free sector %d in block %d: " 390 printk("Incorrect free sector %d in block %d: "
391 "marking it as ignored\n", 391 "marking it as ignored\n",
@@ -486,7 +486,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
486 size_t retlen; 486 size_t retlen;
487 487
488 /* check erase mark. */ 488 /* check erase mark. */
489 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 489 if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
490 &retlen, (char *)&h1) < 0) 490 &retlen, (char *)&h1) < 0)
491 return -1; 491 return -1;
492 492
@@ -501,7 +501,7 @@ static int check_and_mark_free_block(struct NFTLrecord *nftl, int block)
501 h1.EraseMark = cpu_to_le16(ERASE_MARK); 501 h1.EraseMark = cpu_to_le16(ERASE_MARK);
502 h1.EraseMark1 = cpu_to_le16(ERASE_MARK); 502 h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
503 h1.WearInfo = cpu_to_le32(0); 503 h1.WearInfo = cpu_to_le32(0);
504 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 504 if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
505 &retlen, (char *)&h1) < 0) 505 &retlen, (char *)&h1) < 0)
506 return -1; 506 return -1;
507 } else { 507 } else {
@@ -582,9 +582,9 @@ int NFTL_mount(struct NFTLrecord *s)
582 582
583 for (;;) { 583 for (;;) {
584 /* read the block header. If error, we format the chain */ 584 /* read the block header. If error, we format the chain */
585 if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8, 585 if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8,
586 &retlen, (char *)&h0) < 0 || 586 &retlen, (char *)&h0) < 0 ||
587 MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8, 587 MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
588 &retlen, (char *)&h1) < 0) { 588 &retlen, (char *)&h1) < 0) {
589 s->ReplUnitTable[block] = BLOCK_NIL; 589 s->ReplUnitTable[block] = BLOCK_NIL;
590 do_format_chain = 1; 590 do_format_chain = 1;
@@ -639,7 +639,7 @@ int NFTL_mount(struct NFTLrecord *s)
639 first_logical_block = logical_block; 639 first_logical_block = logical_block;
640 } else { 640 } else {
641 if (logical_block != first_logical_block) { 641 if (logical_block != first_logical_block) {
642 printk("Block %d: incorrect logical block: %d expected: %d\n", 642 printk("Block %d: incorrect logical block: %d expected: %d\n",
643 block, logical_block, first_logical_block); 643 block, logical_block, first_logical_block);
644 /* the chain is incorrect : we must format it, 644 /* the chain is incorrect : we must format it,
645 but we need to read it completly */ 645 but we need to read it completly */
@@ -668,7 +668,7 @@ int NFTL_mount(struct NFTLrecord *s)
668 s->ReplUnitTable[block] = BLOCK_NIL; 668 s->ReplUnitTable[block] = BLOCK_NIL;
669 break; 669 break;
670 } else if (rep_block >= s->nb_blocks) { 670 } else if (rep_block >= s->nb_blocks) {
671 printk("Block %d: referencing invalid block %d\n", 671 printk("Block %d: referencing invalid block %d\n",
672 block, rep_block); 672 block, rep_block);
673 do_format_chain = 1; 673 do_format_chain = 1;
674 s->ReplUnitTable[block] = BLOCK_NIL; 674 s->ReplUnitTable[block] = BLOCK_NIL;
@@ -688,7 +688,7 @@ int NFTL_mount(struct NFTLrecord *s)
688 s->ReplUnitTable[block] = rep_block; 688 s->ReplUnitTable[block] = rep_block;
689 s->EUNtable[first_logical_block] = BLOCK_NIL; 689 s->EUNtable[first_logical_block] = BLOCK_NIL;
690 } else { 690 } else {
691 printk("Block %d: referencing block %d already in another chain\n", 691 printk("Block %d: referencing block %d already in another chain\n",
692 block, rep_block); 692 block, rep_block);
693 /* XXX: should handle correctly fold in progress chains */ 693 /* XXX: should handle correctly fold in progress chains */
694 do_format_chain = 1; 694 do_format_chain = 1;
@@ -710,7 +710,7 @@ int NFTL_mount(struct NFTLrecord *s)
710 } else { 710 } else {
711 unsigned int first_block1, chain_to_format, chain_length1; 711 unsigned int first_block1, chain_to_format, chain_length1;
712 int fold_mark; 712 int fold_mark;
713 713
714 /* valid chain : get foldmark */ 714 /* valid chain : get foldmark */
715 fold_mark = get_fold_mark(s, first_block); 715 fold_mark = get_fold_mark(s, first_block);
716 if (fold_mark == 0) { 716 if (fold_mark == 0) {
@@ -729,9 +729,9 @@ int NFTL_mount(struct NFTLrecord *s)
729 if (first_block1 != BLOCK_NIL) { 729 if (first_block1 != BLOCK_NIL) {
730 /* XXX: what to do if same length ? */ 730 /* XXX: what to do if same length ? */
731 chain_length1 = calc_chain_length(s, first_block1); 731 chain_length1 = calc_chain_length(s, first_block1);
732 printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n", 732 printk("Two chains at blocks %d (len=%d) and %d (len=%d)\n",
733 first_block1, chain_length1, first_block, chain_length); 733 first_block1, chain_length1, first_block, chain_length);
734 734
735 if (chain_length >= chain_length1) { 735 if (chain_length >= chain_length1) {
736 chain_to_format = first_block1; 736 chain_to_format = first_block1;
737 s->EUNtable[first_logical_block] = first_block; 737 s->EUNtable[first_logical_block] = first_block;
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
new file mode 100644
index 000000000000..126ff6bf63d5
--- /dev/null
+++ b/drivers/mtd/onenand/Kconfig
@@ -0,0 +1,38 @@
1#
2# linux/drivers/mtd/onenand/Kconfig
3#
4
5menu "OneNAND Flash Device Drivers"
6 depends on MTD != n
7
8config MTD_ONENAND
9 tristate "OneNAND Device Support"
10 depends on MTD
11 help
12 This enables support for accessing all type of OneNAND flash
13 devices. For further information see
14 <http://www.samsung.com/Products/Semiconductor/Flash/OneNAND_TM/index.htm>.
15
16config MTD_ONENAND_VERIFY_WRITE
17 bool "Verify OneNAND page writes"
18 depends on MTD_ONENAND
19 help
20 This adds an extra check when data is written to the flash. The
21 OneNAND flash device internally checks only bits transitioning
22 from 1 to 0. There is a rare possibility that even though the
23 device thinks the write was successful, a bit could have been
24 flipped accidentaly due to device wear or something else.
25
26config MTD_ONENAND_GENERIC
27 tristate "OneNAND Flash device via platform device driver"
28 depends on MTD_ONENAND && ARM
29 help
30 Support for OneNAND flash via platform device driver.
31
32config MTD_ONENAND_SYNC_READ
33 bool "OneNAND Sync. Burst Read Support"
34 depends on ARCH_OMAP
35 help
36 This enables support for Sync. Burst Read.
37
38endmenu
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
new file mode 100644
index 000000000000..269cfe467345
--- /dev/null
+++ b/drivers/mtd/onenand/Makefile
@@ -0,0 +1,11 @@
1#
2# Makefile for the OneNAND MTD
3#
4
5# Core functionality.
6obj-$(CONFIG_MTD_ONENAND) += onenand.o
7
8# Board specific.
9obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
10
11onenand-objs = onenand_base.o onenand_bbt.o
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
new file mode 100644
index 000000000000..48cce431f89f
--- /dev/null
+++ b/drivers/mtd/onenand/generic.c
@@ -0,0 +1,147 @@
1/*
2 * linux/drivers/mtd/onenand/generic.c
3 *
4 * Copyright (c) 2005 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Overview:
12 * This is a device driver for the OneNAND flash for generic boards.
13 */
14
15#include <linux/device.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/mtd/mtd.h>
19#include <linux/mtd/onenand.h>
20#include <linux/mtd/partitions.h>
21
22#include <asm/io.h>
23#include <asm/mach/flash.h>
24
25#define DRIVER_NAME "onenand"
26
27
28#ifdef CONFIG_MTD_PARTITIONS
29static const char *part_probes[] = { "cmdlinepart", NULL, };
30#endif
31
32struct onenand_info {
33 struct mtd_info mtd;
34 struct mtd_partition *parts;
35 struct onenand_chip onenand;
36};
37
38static int __devinit generic_onenand_probe(struct device *dev)
39{
40 struct onenand_info *info;
41 struct platform_device *pdev = to_platform_device(dev);
42 struct onenand_platform_data *pdata = pdev->dev.platform_data;
43 struct resource *res = pdev->resource;
44 unsigned long size = res->end - res->start + 1;
45 int err;
46
47 info = kmalloc(sizeof(struct onenand_info), GFP_KERNEL);
48 if (!info)
49 return -ENOMEM;
50
51 memset(info, 0, sizeof(struct onenand_info));
52
53 if (!request_mem_region(res->start, size, dev->driver->name)) {
54 err = -EBUSY;
55 goto out_free_info;
56 }
57
58 info->onenand.base = ioremap(res->start, size);
59 if (!info->onenand.base) {
60 err = -ENOMEM;
61 goto out_release_mem_region;
62 }
63
64 info->onenand.mmcontrol = pdata->mmcontrol;
65
66 info->mtd.name = pdev->dev.bus_id;
67 info->mtd.priv = &info->onenand;
68 info->mtd.owner = THIS_MODULE;
69
70 if (onenand_scan(&info->mtd, 1)) {
71 err = -ENXIO;
72 goto out_iounmap;
73 }
74
75#ifdef CONFIG_MTD_PARTITIONS
76 err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
77 if (err > 0)
78 add_mtd_partitions(&info->mtd, info->parts, err);
79 else if (err < 0 && pdata->parts)
80 add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
81 else
82#endif
83 err = add_mtd_device(&info->mtd);
84
85 dev_set_drvdata(&pdev->dev, info);
86
87 return 0;
88
89out_iounmap:
90 iounmap(info->onenand.base);
91out_release_mem_region:
92 release_mem_region(res->start, size);
93out_free_info:
94 kfree(info);
95
96 return err;
97}
98
99static int __devexit generic_onenand_remove(struct device *dev)
100{
101 struct platform_device *pdev = to_platform_device(dev);
102 struct onenand_info *info = dev_get_drvdata(&pdev->dev);
103 struct resource *res = pdev->resource;
104 unsigned long size = res->end - res->start + 1;
105
106 dev_set_drvdata(&pdev->dev, NULL);
107
108 if (info) {
109 if (info->parts)
110 del_mtd_partitions(&info->mtd);
111 else
112 del_mtd_device(&info->mtd);
113
114 onenand_release(&info->mtd);
115 release_mem_region(res->start, size);
116 iounmap(info->onenand.base);
117 kfree(info);
118 }
119
120 return 0;
121}
122
123static struct device_driver generic_onenand_driver = {
124 .name = DRIVER_NAME,
125 .bus = &platform_bus_type,
126 .probe = generic_onenand_probe,
127 .remove = __devexit_p(generic_onenand_remove),
128};
129
130MODULE_ALIAS(DRIVER_NAME);
131
132static int __init generic_onenand_init(void)
133{
134 return driver_register(&generic_onenand_driver);
135}
136
137static void __exit generic_onenand_exit(void)
138{
139 driver_unregister(&generic_onenand_driver);
140}
141
142module_init(generic_onenand_init);
143module_exit(generic_onenand_exit);
144
145MODULE_LICENSE("GPL");
146MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
147MODULE_DESCRIPTION("Glue layer for OneNAND flash on generic boards");
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
new file mode 100644
index 000000000000..f67d5d6eb9a6
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -0,0 +1,1590 @@
1/*
2 * linux/drivers/mtd/onenand/onenand_base.c
3 *
4 * Copyright (C) 2005 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/sched.h>
16#include <linux/jiffies.h>
17#include <linux/mtd/mtd.h>
18#include <linux/mtd/onenand.h>
19#include <linux/mtd/partitions.h>
20
21#include <asm/io.h>
22
23/**
24 * onenand_oob_64 - oob info for large (2KB) page
25 */
26static struct nand_oobinfo onenand_oob_64 = {
27 .useecc = MTD_NANDECC_AUTOPLACE,
28 .eccbytes = 20,
29 .eccpos = {
30 8, 9, 10, 11, 12,
31 24, 25, 26, 27, 28,
32 40, 41, 42, 43, 44,
33 56, 57, 58, 59, 60,
34 },
35 .oobfree = {
36 {2, 3}, {14, 2}, {18, 3}, {30, 2},
37 {24, 3}, {46, 2}, {40, 3}, {62, 2} }
38};
39
40/**
41 * onenand_oob_32 - oob info for middle (1KB) page
42 */
43static struct nand_oobinfo onenand_oob_32 = {
44 .useecc = MTD_NANDECC_AUTOPLACE,
45 .eccbytes = 10,
46 .eccpos = {
47 8, 9, 10, 11, 12,
48 24, 25, 26, 27, 28,
49 },
50 .oobfree = { {2, 3}, {14, 2}, {18, 3}, {30, 2} }
51};
52
53static const unsigned char ffchars[] = {
54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
55 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
56 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
57 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 */
58 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
59 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 48 */
60 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
61 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 64 */
62};
63
64/**
65 * onenand_readw - [OneNAND Interface] Read OneNAND register
66 * @param addr address to read
67 *
68 * Read OneNAND register
69 */
70static unsigned short onenand_readw(void __iomem *addr)
71{
72 return readw(addr);
73}
74
75/**
76 * onenand_writew - [OneNAND Interface] Write OneNAND register with value
77 * @param value value to write
78 * @param addr address to write
79 *
80 * Write OneNAND register with value
81 */
82static void onenand_writew(unsigned short value, void __iomem *addr)
83{
84 writew(value, addr);
85}
86
87/**
88 * onenand_block_address - [DEFAULT] Get block address
89 * @param this onenand chip data structure
90 * @param block the block
91 * @return translated block address if DDP, otherwise same
92 *
93 * Setup Start Address 1 Register (F100h)
94 */
95static int onenand_block_address(struct onenand_chip *this, int block)
96{
97 if (this->device_id & ONENAND_DEVICE_IS_DDP) {
98 /* Device Flash Core select, NAND Flash Block Address */
99 int dfs = 0;
100
101 if (block & this->density_mask)
102 dfs = 1;
103
104 return (dfs << ONENAND_DDP_SHIFT) |
105 (block & (this->density_mask - 1));
106 }
107
108 return block;
109}
110
111/**
112 * onenand_bufferram_address - [DEFAULT] Get bufferram address
113 * @param this onenand chip data structure
114 * @param block the block
115 * @return set DBS value if DDP, otherwise 0
116 *
117 * Setup Start Address 2 Register (F101h) for DDP
118 */
119static int onenand_bufferram_address(struct onenand_chip *this, int block)
120{
121 if (this->device_id & ONENAND_DEVICE_IS_DDP) {
122 /* Device BufferRAM Select */
123 int dbs = 0;
124
125 if (block & this->density_mask)
126 dbs = 1;
127
128 return (dbs << ONENAND_DDP_SHIFT);
129 }
130
131 return 0;
132}
133
134/**
135 * onenand_page_address - [DEFAULT] Get page address
136 * @param page the page address
137 * @param sector the sector address
138 * @return combined page and sector address
139 *
140 * Setup Start Address 8 Register (F107h)
141 */
142static int onenand_page_address(int page, int sector)
143{
144 /* Flash Page Address, Flash Sector Address */
145 int fpa, fsa;
146
147 fpa = page & ONENAND_FPA_MASK;
148 fsa = sector & ONENAND_FSA_MASK;
149
150 return ((fpa << ONENAND_FPA_SHIFT) | fsa);
151}
152
153/**
154 * onenand_buffer_address - [DEFAULT] Get buffer address
155 * @param dataram1 DataRAM index
156 * @param sectors the sector address
157 * @param count the number of sectors
158 * @return the start buffer value
159 *
160 * Setup Start Buffer Register (F200h)
161 */
162static int onenand_buffer_address(int dataram1, int sectors, int count)
163{
164 int bsa, bsc;
165
166 /* BufferRAM Sector Address */
167 bsa = sectors & ONENAND_BSA_MASK;
168
169 if (dataram1)
170 bsa |= ONENAND_BSA_DATARAM1; /* DataRAM1 */
171 else
172 bsa |= ONENAND_BSA_DATARAM0; /* DataRAM0 */
173
174 /* BufferRAM Sector Count */
175 bsc = count & ONENAND_BSC_MASK;
176
177 return ((bsa << ONENAND_BSA_SHIFT) | bsc);
178}
179
180/**
181 * onenand_command - [DEFAULT] Send command to OneNAND device
182 * @param mtd MTD device structure
183 * @param cmd the command to be sent
184 * @param addr offset to read from or write to
185 * @param len number of bytes to read or write
186 *
187 * Send command to OneNAND device. This function is used for middle/large page
188 * devices (1KB/2KB Bytes per page)
189 */
190static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t len)
191{
192 struct onenand_chip *this = mtd->priv;
193 int value, readcmd = 0;
194 int block, page;
195 /* Now we use page size operation */
196 int sectors = 4, count = 4;
197
198 /* Address translation */
199 switch (cmd) {
200 case ONENAND_CMD_UNLOCK:
201 case ONENAND_CMD_LOCK:
202 case ONENAND_CMD_LOCK_TIGHT:
203 block = -1;
204 page = -1;
205 break;
206
207 case ONENAND_CMD_ERASE:
208 case ONENAND_CMD_BUFFERRAM:
209 block = (int) (addr >> this->erase_shift);
210 page = -1;
211 break;
212
213 default:
214 block = (int) (addr >> this->erase_shift);
215 page = (int) (addr >> this->page_shift);
216 page &= this->page_mask;
217 break;
218 }
219
220 /* NOTE: The setting order of the registers is very important! */
221 if (cmd == ONENAND_CMD_BUFFERRAM) {
222 /* Select DataRAM for DDP */
223 value = onenand_bufferram_address(this, block);
224 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
225
226 /* Switch to the next data buffer */
227 ONENAND_SET_NEXT_BUFFERRAM(this);
228
229 return 0;
230 }
231
232 if (block != -1) {
233 /* Write 'DFS, FBA' of Flash */
234 value = onenand_block_address(this, block);
235 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
236 }
237
238 if (page != -1) {
239 int dataram;
240
241 switch (cmd) {
242 case ONENAND_CMD_READ:
243 case ONENAND_CMD_READOOB:
244 dataram = ONENAND_SET_NEXT_BUFFERRAM(this);
245 readcmd = 1;
246 break;
247
248 default:
249 dataram = ONENAND_CURRENT_BUFFERRAM(this);
250 break;
251 }
252
253 /* Write 'FPA, FSA' of Flash */
254 value = onenand_page_address(page, sectors);
255 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS8);
256
257 /* Write 'BSA, BSC' of DataRAM */
258 value = onenand_buffer_address(dataram, sectors, count);
259 this->write_word(value, this->base + ONENAND_REG_START_BUFFER);
260
261 if (readcmd) {
262 /* Select DataRAM for DDP */
263 value = onenand_bufferram_address(this, block);
264 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
265 }
266 }
267
268 /* Interrupt clear */
269 this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT);
270
271 /* Write command */
272 this->write_word(cmd, this->base + ONENAND_REG_COMMAND);
273
274 return 0;
275}
276
277/**
278 * onenand_wait - [DEFAULT] wait until the command is done
279 * @param mtd MTD device structure
280 * @param state state to select the max. timeout value
281 *
282 * Wait for command done. This applies to all OneNAND command
283 * Read can take up to 30us, erase up to 2ms and program up to 350us
284 * according to general OneNAND specs
285 */
286static int onenand_wait(struct mtd_info *mtd, int state)
287{
288 struct onenand_chip * this = mtd->priv;
289 unsigned long timeout;
290 unsigned int flags = ONENAND_INT_MASTER;
291 unsigned int interrupt = 0;
292 unsigned int ctrl, ecc;
293
294 /* The 20 msec is enough */
295 timeout = jiffies + msecs_to_jiffies(20);
296 while (time_before(jiffies, timeout)) {
297 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
298
299 if (interrupt & flags)
300 break;
301
302 if (state != FL_READING)
303 cond_resched();
304 }
305 /* To get correct interrupt status in timeout case */
306 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);
307
308 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
309
310 if (ctrl & ONENAND_CTRL_ERROR) {
311 /* It maybe occur at initial bad block */
312 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);
313 /* Clear other interrupt bits for preventing ECC error */
314 interrupt &= ONENAND_INT_MASTER;
315 }
316
317 if (ctrl & ONENAND_CTRL_LOCK) {
318 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl);
319 return -EACCES;
320 }
321
322 if (interrupt & ONENAND_INT_READ) {
323 ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
324 if (ecc & ONENAND_ECC_2BIT_ALL) {
325 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);
326 return -EBADMSG;
327 }
328 }
329
330 return 0;
331}
332
333/**
334 * onenand_bufferram_offset - [DEFAULT] BufferRAM offset
335 * @param mtd MTD data structure
336 * @param area BufferRAM area
337 * @return offset given area
338 *
339 * Return BufferRAM offset given area
340 */
341static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
342{
343 struct onenand_chip *this = mtd->priv;
344
345 if (ONENAND_CURRENT_BUFFERRAM(this)) {
346 if (area == ONENAND_DATARAM)
347 return mtd->oobblock;
348 if (area == ONENAND_SPARERAM)
349 return mtd->oobsize;
350 }
351
352 return 0;
353}
354
355/**
356 * onenand_read_bufferram - [OneNAND Interface] Read the bufferram area
357 * @param mtd MTD data structure
358 * @param area BufferRAM area
359 * @param buffer the databuffer to put/get data
360 * @param offset offset to read from or write to
361 * @param count number of bytes to read/write
362 *
363 * Read the BufferRAM area
364 */
365static int onenand_read_bufferram(struct mtd_info *mtd, int area,
366 unsigned char *buffer, int offset, size_t count)
367{
368 struct onenand_chip *this = mtd->priv;
369 void __iomem *bufferram;
370
371 bufferram = this->base + area;
372
373 bufferram += onenand_bufferram_offset(mtd, area);
374
375 memcpy(buffer, bufferram + offset, count);
376
377 return 0;
378}
379
380/**
381 * onenand_sync_read_bufferram - [OneNAND Interface] Read the bufferram area with Sync. Burst mode
382 * @param mtd MTD data structure
383 * @param area BufferRAM area
384 * @param buffer the databuffer to put/get data
385 * @param offset offset to read from or write to
386 * @param count number of bytes to read/write
387 *
388 * Read the BufferRAM area with Sync. Burst Mode
389 */
390static int onenand_sync_read_bufferram(struct mtd_info *mtd, int area,
391 unsigned char *buffer, int offset, size_t count)
392{
393 struct onenand_chip *this = mtd->priv;
394 void __iomem *bufferram;
395
396 bufferram = this->base + area;
397
398 bufferram += onenand_bufferram_offset(mtd, area);
399
400 this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
401
402 memcpy(buffer, bufferram + offset, count);
403
404 this->mmcontrol(mtd, 0);
405
406 return 0;
407}
408
409/**
410 * onenand_write_bufferram - [OneNAND Interface] Write the bufferram area
411 * @param mtd MTD data structure
412 * @param area BufferRAM area
413 * @param buffer the databuffer to put/get data
414 * @param offset offset to read from or write to
415 * @param count number of bytes to read/write
416 *
417 * Write the BufferRAM area
418 */
419static int onenand_write_bufferram(struct mtd_info *mtd, int area,
420 const unsigned char *buffer, int offset, size_t count)
421{
422 struct onenand_chip *this = mtd->priv;
423 void __iomem *bufferram;
424
425 bufferram = this->base + area;
426
427 bufferram += onenand_bufferram_offset(mtd, area);
428
429 memcpy(bufferram + offset, buffer, count);
430
431 return 0;
432}
433
434/**
435 * onenand_check_bufferram - [GENERIC] Check BufferRAM information
436 * @param mtd MTD data structure
437 * @param addr address to check
438 * @return 1 if there are valid data, otherwise 0
439 *
440 * Check bufferram if there is data we required
441 */
442static int onenand_check_bufferram(struct mtd_info *mtd, loff_t addr)
443{
444 struct onenand_chip *this = mtd->priv;
445 int block, page;
446 int i;
447
448 block = (int) (addr >> this->erase_shift);
449 page = (int) (addr >> this->page_shift);
450 page &= this->page_mask;
451
452 i = ONENAND_CURRENT_BUFFERRAM(this);
453
454 /* Is there valid data? */
455 if (this->bufferram[i].block == block &&
456 this->bufferram[i].page == page &&
457 this->bufferram[i].valid)
458 return 1;
459
460 return 0;
461}
462
463/**
464 * onenand_update_bufferram - [GENERIC] Update BufferRAM information
465 * @param mtd MTD data structure
466 * @param addr address to update
467 * @param valid valid flag
468 *
469 * Update BufferRAM information
470 */
471static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
472 int valid)
473{
474 struct onenand_chip *this = mtd->priv;
475 int block, page;
476 int i;
477
478 block = (int) (addr >> this->erase_shift);
479 page = (int) (addr >> this->page_shift);
480 page &= this->page_mask;
481
482 /* Invalidate BufferRAM */
483 for (i = 0; i < MAX_BUFFERRAM; i++) {
484 if (this->bufferram[i].block == block &&
485 this->bufferram[i].page == page)
486 this->bufferram[i].valid = 0;
487 }
488
489 /* Update BufferRAM */
490 i = ONENAND_CURRENT_BUFFERRAM(this);
491 this->bufferram[i].block = block;
492 this->bufferram[i].page = page;
493 this->bufferram[i].valid = valid;
494
495 return 0;
496}
497
498/**
499 * onenand_get_device - [GENERIC] Get chip for selected access
500 * @param mtd MTD device structure
501 * @param new_state the state which is requested
502 *
503 * Get the device and lock it for exclusive access
504 */
505static int onenand_get_device(struct mtd_info *mtd, int new_state)
506{
507 struct onenand_chip *this = mtd->priv;
508 DECLARE_WAITQUEUE(wait, current);
509
510 /*
511 * Grab the lock and see if the device is available
512 */
513 while (1) {
514 spin_lock(&this->chip_lock);
515 if (this->state == FL_READY) {
516 this->state = new_state;
517 spin_unlock(&this->chip_lock);
518 break;
519 }
520 if (new_state == FL_PM_SUSPENDED) {
521 spin_unlock(&this->chip_lock);
522 return (this->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN;
523 }
524 set_current_state(TASK_UNINTERRUPTIBLE);
525 add_wait_queue(&this->wq, &wait);
526 spin_unlock(&this->chip_lock);
527 schedule();
528 remove_wait_queue(&this->wq, &wait);
529 }
530
531 return 0;
532}
533
534/**
535 * onenand_release_device - [GENERIC] release chip
536 * @param mtd MTD device structure
537 *
538 * Deselect, release chip lock and wake up anyone waiting on the device
539 */
540static void onenand_release_device(struct mtd_info *mtd)
541{
542 struct onenand_chip *this = mtd->priv;
543
544 /* Release the chip */
545 spin_lock(&this->chip_lock);
546 this->state = FL_READY;
547 wake_up(&this->wq);
548 spin_unlock(&this->chip_lock);
549}
550
551/**
552 * onenand_read_ecc - [MTD Interface] Read data with ECC
553 * @param mtd MTD device structure
554 * @param from offset to read from
555 * @param len number of bytes to read
556 * @param retlen pointer to variable to store the number of read bytes
557 * @param buf the databuffer to put data
558 * @param oob_buf filesystem supplied oob data buffer
559 * @param oobsel oob selection structure
560 *
561 * OneNAND read with ECC
562 */
563static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
564 size_t *retlen, u_char *buf,
565 u_char *oob_buf, struct nand_oobinfo *oobsel)
566{
567 struct onenand_chip *this = mtd->priv;
568 int read = 0, column;
569 int thislen;
570 int ret = 0;
571
572 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
573
574 /* Do not allow reads past end of device */
575 if ((from + len) > mtd->size) {
576 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: Attempt read beyond end of device\n");
577 *retlen = 0;
578 return -EINVAL;
579 }
580
581 /* Grab the lock and see if the device is available */
582 onenand_get_device(mtd, FL_READING);
583
584 /* TODO handling oob */
585
586 while (read < len) {
587 thislen = min_t(int, mtd->oobblock, len - read);
588
589 column = from & (mtd->oobblock - 1);
590 if (column + thislen > mtd->oobblock)
591 thislen = mtd->oobblock - column;
592
593 if (!onenand_check_bufferram(mtd, from)) {
594 this->command(mtd, ONENAND_CMD_READ, from, mtd->oobblock);
595
596 ret = this->wait(mtd, FL_READING);
597 /* First copy data and check return value for ECC handling */
598 onenand_update_bufferram(mtd, from, 1);
599 }
600
601 this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);
602
603 read += thislen;
604
605 if (read == len)
606 break;
607
608 if (ret) {
609 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_ecc: read failed = %d\n", ret);
610 goto out;
611 }
612
613 from += thislen;
614 buf += thislen;
615 }
616
617out:
618 /* Deselect and wake up anyone waiting on the device */
619 onenand_release_device(mtd);
620
621 /*
622 * Return success, if no ECC failures, else -EBADMSG
623 * fs driver will take care of that, because
624 * retlen == desired len and result == -EBADMSG
625 */
626 *retlen = read;
627 return ret;
628}
629
630/**
631 * onenand_read - [MTD Interface] MTD compability function for onenand_read_ecc
632 * @param mtd MTD device structure
633 * @param from offset to read from
634 * @param len number of bytes to read
635 * @param retlen pointer to variable to store the number of read bytes
636 * @param buf the databuffer to put data
637 *
638 * This function simply calls onenand_read_ecc with oob buffer and oobsel = NULL
639*/
640static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
641 size_t *retlen, u_char *buf)
642{
643 return onenand_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
644}
645
646/**
647 * onenand_read_oob - [MTD Interface] OneNAND read out-of-band
648 * @param mtd MTD device structure
649 * @param from offset to read from
650 * @param len number of bytes to read
651 * @param retlen pointer to variable to store the number of read bytes
652 * @param buf the databuffer to put data
653 *
654 * OneNAND read out-of-band data from the spare area
655 */
656static int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
657 size_t *retlen, u_char *buf)
658{
659 struct onenand_chip *this = mtd->priv;
660 int read = 0, thislen, column;
661 int ret = 0;
662
663 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
664
665 /* Initialize return length value */
666 *retlen = 0;
667
668 /* Do not allow reads past end of device */
669 if (unlikely((from + len) > mtd->size)) {
670 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: Attempt read beyond end of device\n");
671 return -EINVAL;
672 }
673
674 /* Grab the lock and see if the device is available */
675 onenand_get_device(mtd, FL_READING);
676
677 column = from & (mtd->oobsize - 1);
678
679 while (read < len) {
680 thislen = mtd->oobsize - column;
681 thislen = min_t(int, thislen, len);
682
683 this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize);
684
685 onenand_update_bufferram(mtd, from, 0);
686
687 ret = this->wait(mtd, FL_READING);
688 /* First copy data and check return value for ECC handling */
689
690 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
691
692 read += thislen;
693
694 if (read == len)
695 break;
696
697 if (ret) {
698 DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);
699 goto out;
700 }
701
702 buf += thislen;
703
704 /* Read more? */
705 if (read < len) {
706 /* Page size */
707 from += mtd->oobblock;
708 column = 0;
709 }
710 }
711
712out:
713 /* Deselect and wake up anyone waiting on the device */
714 onenand_release_device(mtd);
715
716 *retlen = read;
717 return ret;
718}
719
720#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE
721/**
722 * onenand_verify_page - [GENERIC] verify the chip contents after a write
723 * @param mtd MTD device structure
724 * @param buf the databuffer to verify
725 *
726 * Check DataRAM area directly
727 */
728static int onenand_verify_page(struct mtd_info *mtd, u_char *buf, loff_t addr)
729{
730 struct onenand_chip *this = mtd->priv;
731 void __iomem *dataram0, *dataram1;
732 int ret = 0;
733
734 this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
735
736 ret = this->wait(mtd, FL_READING);
737 if (ret)
738 return ret;
739
740 onenand_update_bufferram(mtd, addr, 1);
741
742 /* Check, if the two dataram areas are same */
743 dataram0 = this->base + ONENAND_DATARAM;
744 dataram1 = dataram0 + mtd->oobblock;
745
746 if (memcmp(dataram0, dataram1, mtd->oobblock))
747 return -EBADMSG;
748
749 return 0;
750}
751#else
752#define onenand_verify_page(...) (0)
753#endif
754
755#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0)
756
757/**
758 * onenand_write_ecc - [MTD Interface] OneNAND write with ECC
759 * @param mtd MTD device structure
760 * @param to offset to write to
761 * @param len number of bytes to write
762 * @param retlen pointer to variable to store the number of written bytes
763 * @param buf the data to write
764 * @param eccbuf filesystem supplied oob data buffer
765 * @param oobsel oob selection structure
766 *
767 * OneNAND write with ECC
768 */
769static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
770 size_t *retlen, const u_char *buf,
771 u_char *eccbuf, struct nand_oobinfo *oobsel)
772{
773 struct onenand_chip *this = mtd->priv;
774 int written = 0;
775 int ret = 0;
776
777 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
778
779 /* Initialize retlen, in case of early exit */
780 *retlen = 0;
781
782 /* Do not allow writes past end of device */
783 if (unlikely((to + len) > mtd->size)) {
784 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt write to past end of device\n");
785 return -EINVAL;
786 }
787
788 /* Reject writes, which are not page aligned */
789 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
790 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: Attempt to write not page aligned data\n");
791 return -EINVAL;
792 }
793
794 /* Grab the lock and see if the device is available */
795 onenand_get_device(mtd, FL_WRITING);
796
797 /* Loop until all data write */
798 while (written < len) {
799 int thislen = min_t(int, mtd->oobblock, len - written);
800
801 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
802
803 this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
804 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
805
806 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
807
808 onenand_update_bufferram(mtd, to, 1);
809
810 ret = this->wait(mtd, FL_WRITING);
811 if (ret) {
812 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: write filaed %d\n", ret);
813 goto out;
814 }
815
816 written += thislen;
817
818 /* Only check verify write turn on */
819 ret = onenand_verify_page(mtd, (u_char *) buf, to);
820 if (ret) {
821 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret);
822 goto out;
823 }
824
825 if (written == len)
826 break;
827
828 to += thislen;
829 buf += thislen;
830 }
831
832out:
833 /* Deselect and wake up anyone waiting on the device */
834 onenand_release_device(mtd);
835
836 *retlen = written;
837
838 return ret;
839}
840
841/**
842 * onenand_write - [MTD Interface] compability function for onenand_write_ecc
843 * @param mtd MTD device structure
844 * @param to offset to write to
845 * @param len number of bytes to write
846 * @param retlen pointer to variable to store the number of written bytes
847 * @param buf the data to write
848 *
849 * This function simply calls onenand_write_ecc
850 * with oob buffer and oobsel = NULL
851 */
852static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
853 size_t *retlen, const u_char *buf)
854{
855 return onenand_write_ecc(mtd, to, len, retlen, buf, NULL, NULL);
856}
857
858/**
859 * onenand_write_oob - [MTD Interface] OneNAND write out-of-band
860 * @param mtd MTD device structure
861 * @param to offset to write to
862 * @param len number of bytes to write
863 * @param retlen pointer to variable to store the number of written bytes
864 * @param buf the data to write
865 *
866 * OneNAND write out-of-band
867 */
868static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
869 size_t *retlen, const u_char *buf)
870{
871 struct onenand_chip *this = mtd->priv;
872 int column, status;
873 int written = 0;
874
875 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
876
877 /* Initialize retlen, in case of early exit */
878 *retlen = 0;
879
880 /* Do not allow writes past end of device */
881 if (unlikely((to + len) > mtd->size)) {
882 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write_oob: Attempt write to past end of device\n");
883 return -EINVAL;
884 }
885
886 /* Grab the lock and see if the device is available */
887 onenand_get_device(mtd, FL_WRITING);
888
889 /* Loop until all data write */
890 while (written < len) {
891 int thislen = min_t(int, mtd->oobsize, len - written);
892
893 column = to & (mtd->oobsize - 1);
894
895 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobsize);
896
897 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
898 this->write_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);
899
900 this->command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize);
901
902 onenand_update_bufferram(mtd, to, 0);
903
904 status = this->wait(mtd, FL_WRITING);
905 if (status)
906 goto out;
907
908 written += thislen;
909
910 if (written == len)
911 break;
912
913 to += thislen;
914 buf += thislen;
915 }
916
917out:
918 /* Deselect and wake up anyone waiting on the device */
919 onenand_release_device(mtd);
920
921 *retlen = written;
922
923 return 0;
924}
925
926/**
927 * onenand_writev_ecc - [MTD Interface] write with iovec with ecc
928 * @param mtd MTD device structure
929 * @param vecs the iovectors to write
930 * @param count number of vectors
931 * @param to offset to write to
932 * @param retlen pointer to variable to store the number of written bytes
933 * @param eccbuf filesystem supplied oob data buffer
934 * @param oobsel oob selection structure
935 *
936 * OneNAND write with iovec with ecc
937 */
938static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
939 unsigned long count, loff_t to, size_t *retlen,
940 u_char *eccbuf, struct nand_oobinfo *oobsel)
941{
942 struct onenand_chip *this = mtd->priv;
943 unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf;
944 size_t total_len, len;
945 int i, written = 0;
946 int ret = 0;
947
948 /* Preset written len for early exit */
949 *retlen = 0;
950
951 /* Calculate total length of data */
952 total_len = 0;
953 for (i = 0; i < count; i++)
954 total_len += vecs[i].iov_len;
955
956 DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
957
958 /* Do not allow write past end of the device */
959 if (unlikely((to + total_len) > mtd->size)) {
960 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
961 return -EINVAL;
962 }
963
964 /* Reject writes, which are not page aligned */
965 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
966 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
967 return -EINVAL;
968 }
969
970 /* Grab the lock and see if the device is available */
971 onenand_get_device(mtd, FL_WRITING);
972
973 /* TODO handling oob */
974
975 /* Loop until all keve's data has been written */
976 len = 0;
977 while (count) {
978 pbuf = buffer;
979 /*
980 * If the given tuple is >= pagesize then
981 * write it out from the iov
982 */
983 if ((vecs->iov_len - len) >= mtd->oobblock) {
984 pbuf = vecs->iov_base + len;
985
986 len += mtd->oobblock;
987
988 /* Check, if we have to switch to the next tuple */
989 if (len >= (int) vecs->iov_len) {
990 vecs++;
991 len = 0;
992 count--;
993 }
994 } else {
995 int cnt = 0, thislen;
996 while (cnt < mtd->oobblock) {
997 thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
998 memcpy(buffer + cnt, vecs->iov_base + len, thislen);
999 cnt += thislen;
1000 len += thislen;
1001
1002 /* Check, if we have to switch to the next tuple */
1003 if (len >= (int) vecs->iov_len) {
1004 vecs++;
1005 len = 0;
1006 count--;
1007 }
1008 }
1009 }
1010
1011 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
1012
1013 this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->oobblock);
1014 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1015
1016 this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
1017
1018 onenand_update_bufferram(mtd, to, 1);
1019
1020 ret = this->wait(mtd, FL_WRITING);
1021 if (ret) {
1022 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
1023 goto out;
1024 }
1025
1026
1027 /* Only check verify write turn on */
1028 ret = onenand_verify_page(mtd, (u_char *) pbuf, to);
1029 if (ret) {
1030 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
1031 goto out;
1032 }
1033
1034 written += mtd->oobblock;
1035
1036 to += mtd->oobblock;
1037 }
1038
1039out:
1040 /* Deselect and wakt up anyone waiting on the device */
1041 onenand_release_device(mtd);
1042
1043 *retlen = written;
1044
1045 return 0;
1046}
1047
1048/**
1049 * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
1050 * @param mtd MTD device structure
1051 * @param vecs the iovectors to write
1052 * @param count number of vectors
1053 * @param to offset to write to
1054 * @param retlen pointer to variable to store the number of written bytes
1055 *
1056 * OneNAND write with kvec. This just calls the ecc function
1057 */
1058static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
1059 unsigned long count, loff_t to, size_t *retlen)
1060{
1061 return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
1062}
1063
1064/**
1065 * onenand_block_checkbad - [GENERIC] Check if a block is marked bad
1066 * @param mtd MTD device structure
1067 * @param ofs offset from device start
1068 * @param getchip 0, if the chip is already selected
1069 * @param allowbbt 1, if its allowed to access the bbt area
1070 *
1071 * Check, if the block is bad. Either by reading the bad block table or
1072 * calling of the scan function.
1073 */
1074static int onenand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt)
1075{
1076 struct onenand_chip *this = mtd->priv;
1077 struct bbm_info *bbm = this->bbm;
1078
1079 /* Return info from the table */
1080 return bbm->isbad_bbt(mtd, ofs, allowbbt);
1081}
1082
1083/**
1084 * onenand_erase - [MTD Interface] erase block(s)
1085 * @param mtd MTD device structure
1086 * @param instr erase instruction
1087 *
1088 * Erase one ore more blocks
1089 */
1090static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
1091{
1092 struct onenand_chip *this = mtd->priv;
1093 unsigned int block_size;
1094 loff_t addr;
1095 int len;
1096 int ret = 0;
1097
1098 DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len);
1099
1100 block_size = (1 << this->erase_shift);
1101
1102 /* Start address must align on block boundary */
1103 if (unlikely(instr->addr & (block_size - 1))) {
1104 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
1105 return -EINVAL;
1106 }
1107
1108 /* Length must align on block boundary */
1109 if (unlikely(instr->len & (block_size - 1))) {
1110 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Length not block aligned\n");
1111 return -EINVAL;
1112 }
1113
1114 /* Do not allow erase past end of device */
1115 if (unlikely((instr->len + instr->addr) > mtd->size)) {
1116 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Erase past end of device\n");
1117 return -EINVAL;
1118 }
1119
1120 instr->fail_addr = 0xffffffff;
1121
1122 /* Grab the lock and see if the device is available */
1123 onenand_get_device(mtd, FL_ERASING);
1124
1125 /* Loop throught the pages */
1126 len = instr->len;
1127 addr = instr->addr;
1128
1129 instr->state = MTD_ERASING;
1130
1131 while (len) {
1132
1133 /* Check if we have a bad block, we do not erase bad blocks */
1134 if (onenand_block_checkbad(mtd, addr, 0, 0)) {
1135 printk (KERN_WARNING "onenand_erase: attempt to erase a bad block at addr 0x%08x\n", (unsigned int) addr);
1136 instr->state = MTD_ERASE_FAILED;
1137 goto erase_exit;
1138 }
1139
1140 this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
1141
1142 ret = this->wait(mtd, FL_ERASING);
1143 /* Check, if it is write protected */
1144 if (ret) {
1145 if (ret == -EPERM)
1146 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");
1147 else
1148 DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));
1149 instr->state = MTD_ERASE_FAILED;
1150 instr->fail_addr = addr;
1151 goto erase_exit;
1152 }
1153
1154 len -= block_size;
1155 addr += block_size;
1156 }
1157
1158 instr->state = MTD_ERASE_DONE;
1159
1160erase_exit:
1161
1162 ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;
1163 /* Do call back function */
1164 if (!ret)
1165 mtd_erase_callback(instr);
1166
1167 /* Deselect and wake up anyone waiting on the device */
1168 onenand_release_device(mtd);
1169
1170 return ret;
1171}
1172
1173/**
1174 * onenand_sync - [MTD Interface] sync
1175 * @param mtd MTD device structure
1176 *
1177 * Sync is actually a wait for chip ready function
1178 */
1179static void onenand_sync(struct mtd_info *mtd)
1180{
1181 DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
1182
1183 /* Grab the lock and see if the device is available */
1184 onenand_get_device(mtd, FL_SYNCING);
1185
1186 /* Release it and go back */
1187 onenand_release_device(mtd);
1188}
1189
1190
1191/**
1192 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
1193 * @param mtd MTD device structure
1194 * @param ofs offset relative to mtd start
1195 *
1196 * Check whether the block is bad
1197 */
1198static int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
1199{
1200 /* Check for invalid offset */
1201 if (ofs > mtd->size)
1202 return -EINVAL;
1203
1204 return onenand_block_checkbad(mtd, ofs, 1, 0);
1205}
1206
1207/**
1208 * onenand_default_block_markbad - [DEFAULT] mark a block bad
1209 * @param mtd MTD device structure
1210 * @param ofs offset from device start
1211 *
1212 * This is the default implementation, which can be overridden by
1213 * a hardware specific driver.
1214 */
1215static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
1216{
1217 struct onenand_chip *this = mtd->priv;
1218 struct bbm_info *bbm = this->bbm;
1219 u_char buf[2] = {0, 0};
1220 size_t retlen;
1221 int block;
1222
1223 /* Get block number */
1224 block = ((int) ofs) >> bbm->bbt_erase_shift;
1225 if (bbm->bbt)
1226 bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1);
1227
1228 /* We write two bytes, so we dont have to mess with 16 bit access */
1229 ofs += mtd->oobsize + (bbm->badblockpos & ~0x01);
1230 return mtd->write_oob(mtd, ofs , 2, &retlen, buf);
1231}
1232
1233/**
1234 * onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
1235 * @param mtd MTD device structure
1236 * @param ofs offset relative to mtd start
1237 *
1238 * Mark the block as bad
1239 */
1240static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
1241{
1242 struct onenand_chip *this = mtd->priv;
1243 int ret;
1244
1245 ret = onenand_block_isbad(mtd, ofs);
1246 if (ret) {
1247 /* If it was bad already, return success and do nothing */
1248 if (ret > 0)
1249 return 0;
1250 return ret;
1251 }
1252
1253 return this->block_markbad(mtd, ofs);
1254}
1255
1256/**
1257 * onenand_unlock - [MTD Interface] Unlock block(s)
1258 * @param mtd MTD device structure
1259 * @param ofs offset relative to mtd start
1260 * @param len number of bytes to unlock
1261 *
1262 * Unlock one or more blocks
1263 */
1264static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
1265{
1266 struct onenand_chip *this = mtd->priv;
1267 int start, end, block, value, status;
1268
1269 start = ofs >> this->erase_shift;
1270 end = len >> this->erase_shift;
1271
1272 /* Continuous lock scheme */
1273 if (this->options & ONENAND_CONT_LOCK) {
1274 /* Set start block address */
1275 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1276 /* Set end block address */
1277 this->write_word(end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
1278 /* Write unlock command */
1279 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1280
1281 /* There's no return value */
1282 this->wait(mtd, FL_UNLOCKING);
1283
1284 /* Sanity check */
1285 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1286 & ONENAND_CTRL_ONGO)
1287 continue;
1288
1289 /* Check lock status */
1290 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1291 if (!(status & ONENAND_WP_US))
1292 printk(KERN_ERR "wp status = 0x%x\n", status);
1293
1294 return 0;
1295 }
1296
1297 /* Block lock scheme */
1298 for (block = start; block < end; block++) {
1299 /* Set start block address */
1300 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
1301 /* Write unlock command */
1302 this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
1303
1304 /* There's no return value */
1305 this->wait(mtd, FL_UNLOCKING);
1306
1307 /* Sanity check */
1308 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
1309 & ONENAND_CTRL_ONGO)
1310 continue;
1311
1312 /* Set block address for read block status */
1313 value = onenand_block_address(this, block);
1314 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
1315
1316 /* Check lock status */
1317 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
1318 if (!(status & ONENAND_WP_US))
1319 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
1320 }
1321
1322 return 0;
1323}
1324
1325/**
1326 * onenand_print_device_info - Print device ID
1327 * @param device device ID
1328 *
1329 * Print device ID
1330 */
1331static void onenand_print_device_info(int device)
1332{
1333 int vcc, demuxed, ddp, density;
1334
1335 vcc = device & ONENAND_DEVICE_VCC_MASK;
1336 demuxed = device & ONENAND_DEVICE_IS_DEMUX;
1337 ddp = device & ONENAND_DEVICE_IS_DDP;
1338 density = device >> ONENAND_DEVICE_DENSITY_SHIFT;
1339 printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n",
1340 demuxed ? "" : "Muxed ",
1341 ddp ? "(DDP)" : "",
1342 (16 << density),
1343 vcc ? "2.65/3.3" : "1.8",
1344 device);
1345}
1346
1347static const struct onenand_manufacturers onenand_manuf_ids[] = {
1348 {ONENAND_MFR_SAMSUNG, "Samsung"},
1349 {ONENAND_MFR_UNKNOWN, "Unknown"}
1350};
1351
1352/**
1353 * onenand_check_maf - Check manufacturer ID
1354 * @param manuf manufacturer ID
1355 *
1356 * Check manufacturer ID
1357 */
1358static int onenand_check_maf(int manuf)
1359{
1360 int i;
1361
1362 for (i = 0; onenand_manuf_ids[i].id; i++) {
1363 if (manuf == onenand_manuf_ids[i].id)
1364 break;
1365 }
1366
1367 printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
1368 onenand_manuf_ids[i].name, manuf);
1369
1370 return (i != ONENAND_MFR_UNKNOWN);
1371}
1372
1373/**
1374 * onenand_probe - [OneNAND Interface] Probe the OneNAND device
1375 * @param mtd MTD device structure
1376 *
1377 * OneNAND detection method:
1378 * Compare the the values from command with ones from register
1379 */
1380static int onenand_probe(struct mtd_info *mtd)
1381{
1382 struct onenand_chip *this = mtd->priv;
1383 int bram_maf_id, bram_dev_id, maf_id, dev_id;
1384 int version_id;
1385 int density;
1386
1387 /* Send the command for reading device ID from BootRAM */
1388 this->write_word(ONENAND_CMD_READID, this->base + ONENAND_BOOTRAM);
1389
1390 /* Read manufacturer and device IDs from BootRAM */
1391 bram_maf_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x0);
1392 bram_dev_id = this->read_word(this->base + ONENAND_BOOTRAM + 0x2);
1393
1394 /* Check manufacturer ID */
1395 if (onenand_check_maf(bram_maf_id))
1396 return -ENXIO;
1397
1398 /* Reset OneNAND to read default register values */
1399 this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
1400
1401 /* Read manufacturer and device IDs from Register */
1402 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
1403 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);
1404
1405 /* Check OneNAND device */
1406 if (maf_id != bram_maf_id || dev_id != bram_dev_id)
1407 return -ENXIO;
1408
1409 /* Flash device information */
1410 onenand_print_device_info(dev_id);
1411 this->device_id = dev_id;
1412
1413 density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT;
1414 this->chipsize = (16 << density) << 20;
1415 /* Set density mask. it is used for DDP */
1416 this->density_mask = (1 << (density + 6));
1417
1418 /* OneNAND page size & block size */
1419 /* The data buffer size is equal to page size */
1420 mtd->oobblock = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
1421 mtd->oobsize = mtd->oobblock >> 5;
1422 /* Pagers per block is always 64 in OneNAND */
1423 mtd->erasesize = mtd->oobblock << 6;
1424
1425 this->erase_shift = ffs(mtd->erasesize) - 1;
1426 this->page_shift = ffs(mtd->oobblock) - 1;
1427 this->ppb_shift = (this->erase_shift - this->page_shift);
1428 this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
1429
1430 /* REVIST: Multichip handling */
1431
1432 mtd->size = this->chipsize;
1433
1434 /* Version ID */
1435 version_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);
1436 printk(KERN_DEBUG "OneNAND version = 0x%04x\n", version_id);
1437
1438 /* Lock scheme */
1439 if (density <= ONENAND_DEVICE_DENSITY_512Mb &&
1440 !(version_id >> ONENAND_VERSION_PROCESS_SHIFT)) {
1441 printk(KERN_INFO "Lock scheme is Continues Lock\n");
1442 this->options |= ONENAND_CONT_LOCK;
1443 }
1444
1445 return 0;
1446}
1447
1448/**
1449 * onenand_suspend - [MTD Interface] Suspend the OneNAND flash
1450 * @param mtd MTD device structure
1451 */
1452static int onenand_suspend(struct mtd_info *mtd)
1453{
1454 return onenand_get_device(mtd, FL_PM_SUSPENDED);
1455}
1456
1457/**
1458 * onenand_resume - [MTD Interface] Resume the OneNAND flash
1459 * @param mtd MTD device structure
1460 */
1461static void onenand_resume(struct mtd_info *mtd)
1462{
1463 struct onenand_chip *this = mtd->priv;
1464
1465 if (this->state == FL_PM_SUSPENDED)
1466 onenand_release_device(mtd);
1467 else
1468 printk(KERN_ERR "resume() called for the chip which is not"
1469 "in suspended state\n");
1470}
1471
1472
1473/**
1474 * onenand_scan - [OneNAND Interface] Scan for the OneNAND device
1475 * @param mtd MTD device structure
1476 * @param maxchips Number of chips to scan for
1477 *
1478 * This fills out all the not initialized function pointers
1479 * with the defaults.
1480 * The flash ID is read and the mtd/chip structures are
1481 * filled with the appropriate values.
1482 */
1483int onenand_scan(struct mtd_info *mtd, int maxchips)
1484{
1485 struct onenand_chip *this = mtd->priv;
1486
1487 if (!this->read_word)
1488 this->read_word = onenand_readw;
1489 if (!this->write_word)
1490 this->write_word = onenand_writew;
1491
1492 if (!this->command)
1493 this->command = onenand_command;
1494 if (!this->wait)
1495 this->wait = onenand_wait;
1496
1497 if (!this->read_bufferram)
1498 this->read_bufferram = onenand_read_bufferram;
1499 if (!this->write_bufferram)
1500 this->write_bufferram = onenand_write_bufferram;
1501
1502 if (!this->block_markbad)
1503 this->block_markbad = onenand_default_block_markbad;
1504 if (!this->scan_bbt)
1505 this->scan_bbt = onenand_default_bbt;
1506
1507 if (onenand_probe(mtd))
1508 return -ENXIO;
1509
1510 /* Set Sync. Burst Read after probing */
1511 if (this->mmcontrol) {
1512 printk(KERN_INFO "OneNAND Sync. Burst Read support\n");
1513 this->read_bufferram = onenand_sync_read_bufferram;
1514 }
1515
1516 this->state = FL_READY;
1517 init_waitqueue_head(&this->wq);
1518 spin_lock_init(&this->chip_lock);
1519
1520 switch (mtd->oobsize) {
1521 case 64:
1522 this->autooob = &onenand_oob_64;
1523 break;
1524
1525 case 32:
1526 this->autooob = &onenand_oob_32;
1527 break;
1528
1529 default:
1530 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",
1531 mtd->oobsize);
1532 /* To prevent kernel oops */
1533 this->autooob = &onenand_oob_32;
1534 break;
1535 }
1536
1537 memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo));
1538
1539 /* Fill in remaining MTD driver data */
1540 mtd->type = MTD_NANDFLASH;
1541 mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
1542 mtd->ecctype = MTD_ECC_SW;
1543 mtd->erase = onenand_erase;
1544 mtd->point = NULL;
1545 mtd->unpoint = NULL;
1546 mtd->read = onenand_read;
1547 mtd->write = onenand_write;
1548 mtd->read_ecc = onenand_read_ecc;
1549 mtd->write_ecc = onenand_write_ecc;
1550 mtd->read_oob = onenand_read_oob;
1551 mtd->write_oob = onenand_write_oob;
1552 mtd->readv = NULL;
1553 mtd->readv_ecc = NULL;
1554 mtd->writev = onenand_writev;
1555 mtd->writev_ecc = onenand_writev_ecc;
1556 mtd->sync = onenand_sync;
1557 mtd->lock = NULL;
1558 mtd->unlock = onenand_unlock;
1559 mtd->suspend = onenand_suspend;
1560 mtd->resume = onenand_resume;
1561 mtd->block_isbad = onenand_block_isbad;
1562 mtd->block_markbad = onenand_block_markbad;
1563 mtd->owner = THIS_MODULE;
1564
1565 /* Unlock whole block */
1566 mtd->unlock(mtd, 0x0, this->chipsize);
1567
1568 return this->scan_bbt(mtd);
1569}
1570
1571/**
1572 * onenand_release - [OneNAND Interface] Free resources held by the OneNAND device
1573 * @param mtd MTD device structure
1574 */
1575void onenand_release(struct mtd_info *mtd)
1576{
1577#ifdef CONFIG_MTD_PARTITIONS
1578 /* Deregister partitions */
1579 del_mtd_partitions (mtd);
1580#endif
1581 /* Deregister the device */
1582 del_mtd_device (mtd);
1583}
1584
1585EXPORT_SYMBOL_GPL(onenand_scan);
1586EXPORT_SYMBOL_GPL(onenand_release);
1587
1588MODULE_LICENSE("GPL");
1589MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
1590MODULE_DESCRIPTION("Generic OneNAND flash driver code");
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
new file mode 100644
index 000000000000..f40190f499e1
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -0,0 +1,246 @@
1/*
2 * linux/drivers/mtd/onenand/onenand_bbt.c
3 *
4 * Bad Block Table support for the OneNAND driver
5 *
6 * Copyright(c) 2005 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com>
8 *
9 * Derived from nand_bbt.c
10 *
11 * TODO:
12 * Split BBT core and chip specific BBT.
13 */
14
15#include <linux/slab.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/onenand.h>
18#include <linux/mtd/compatmac.h>
19
20/**
21 * check_short_pattern - [GENERIC] check if a pattern is in the buffer
22 * @param buf the buffer to search
23 * @param len the length of buffer to search
24 * @param paglen the pagelength
25 * @param td search pattern descriptor
26 *
27 * Check for a pattern at the given place. Used to search bad block
28 * tables and good / bad block identifiers. Same as check_pattern, but
29 * no optional empty check and the pattern is expected to start
30 * at offset 0.
31 *
32 */
33static int check_short_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
34{
35 int i;
36 uint8_t *p = buf;
37
38 /* Compare the pattern */
39 for (i = 0; i < td->len; i++) {
40 if (p[i] != td->pattern[i])
41 return -1;
42 }
43 return 0;
44}
45
46/**
47 * create_bbt - [GENERIC] Create a bad block table by scanning the device
48 * @param mtd MTD device structure
49 * @param buf temporary buffer
50 * @param bd descriptor for the good/bad block search pattern
51 * @param chip create the table for a specific chip, -1 read all chips.
52 * Applies only if NAND_BBT_PERCHIP option is set
53 *
54 * Create a bad block table by scanning the device
55 * for the given good/bad block identify pattern
56 */
57static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip)
58{
59 struct onenand_chip *this = mtd->priv;
60 struct bbm_info *bbm = this->bbm;
61 int i, j, numblocks, len, scanlen;
62 int startblock;
63 loff_t from;
64 size_t readlen, ooblen;
65
66 printk(KERN_INFO "Scanning device for bad blocks\n");
67
68 len = 1;
69
70 /* We need only read few bytes from the OOB area */
71 scanlen = ooblen = 0;
72 readlen = bd->len;
73
74 /* chip == -1 case only */
75 /* Note that numblocks is 2 * (real numblocks) here;
76 * see i += 2 below as it makses shifting and masking less painful
77 */
78 numblocks = mtd->size >> (bbm->bbt_erase_shift - 1);
79 startblock = 0;
80 from = 0;
81
82 for (i = startblock; i < numblocks; ) {
83 int ret;
84
85 for (j = 0; j < len; j++) {
86 size_t retlen;
87
88 /* No need to read pages fully,
89 * just read required OOB bytes */
90 ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs,
91 readlen, &retlen, &buf[0]);
92
93 if (ret)
94 return ret;
95
96 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
97 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
98 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
99 i >> 1, (unsigned int) from);
100 break;
101 }
102 }
103 i += 2;
104 from += (1 << bbm->bbt_erase_shift);
105 }
106
107 return 0;
108}
109
110
111/**
112 * onenand_memory_bbt - [GENERIC] create a memory based bad block table
113 * @param mtd MTD device structure
114 * @param bd descriptor for the good/bad block search pattern
115 *
116 * The function creates a memory based bbt by scanning the device
117 * for manufacturer / software marked good / bad blocks
118 */
119static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
120{
121 unsigned char data_buf[MAX_ONENAND_PAGESIZE];
122
123 bd->options &= ~NAND_BBT_SCANEMPTY;
124 return create_bbt(mtd, data_buf, bd, -1);
125}
126
127/**
128 * onenand_isbad_bbt - [OneNAND Interface] Check if a block is bad
129 * @param mtd MTD device structure
130 * @param offs offset in the device
131 * @param allowbbt allow access to bad block table region
132 */
133static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
134{
135 struct onenand_chip *this = mtd->priv;
136 struct bbm_info *bbm = this->bbm;
137 int block;
138 uint8_t res;
139
140 /* Get block number * 2 */
141 block = (int) (offs >> (bbm->bbt_erase_shift - 1));
142 res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03;
143
144 DEBUG(MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n",
145 (unsigned int) offs, block >> 1, res);
146
147 switch ((int) res) {
148 case 0x00: return 0;
149 case 0x01: return 1;
150 case 0x02: return allowbbt ? 0 : 1;
151 }
152
153 return 1;
154}
155
156/**
157 * onenand_scan_bbt - [OneNAND Interface] scan, find, read and maybe create bad block table(s)
158 * @param mtd MTD device structure
159 * @param bd descriptor for the good/bad block search pattern
160 *
161 * The function checks, if a bad block table(s) is/are already
162 * available. If not it scans the device for manufacturer
163 * marked good / bad blocks and writes the bad block table(s) to
164 * the selected place.
165 *
166 * The bad block table memory is allocated here. It must be freed
167 * by calling the onenand_free_bbt function.
168 *
169 */
170int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
171{
172 struct onenand_chip *this = mtd->priv;
173 struct bbm_info *bbm = this->bbm;
174 int len, ret = 0;
175
176 len = mtd->size >> (this->erase_shift + 2);
177 /* Allocate memory (2bit per block) */
178 bbm->bbt = kmalloc(len, GFP_KERNEL);
179 if (!bbm->bbt) {
180 printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");
181 return -ENOMEM;
182 }
183 /* Clear the memory bad block table */
184 memset(bbm->bbt, 0x00, len);
185
186 /* Set the bad block position */
187 bbm->badblockpos = ONENAND_BADBLOCK_POS;
188
189 /* Set erase shift */
190 bbm->bbt_erase_shift = this->erase_shift;
191
192 if (!bbm->isbad_bbt)
193 bbm->isbad_bbt = onenand_isbad_bbt;
194
195 /* Scan the device to build a memory based bad block table */
196 if ((ret = onenand_memory_bbt(mtd, bd))) {
197 printk(KERN_ERR "onenand_scan_bbt: Can't scan flash and build the RAM-based BBT\n");
198 kfree(bbm->bbt);
199 bbm->bbt = NULL;
200 }
201
202 return ret;
203}
204
205/*
206 * Define some generic bad / good block scan pattern which are used
207 * while scanning a device for factory marked good / bad blocks.
208 */
209static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
210
211static struct nand_bbt_descr largepage_memorybased = {
212 .options = 0,
213 .offs = 0,
214 .len = 2,
215 .pattern = scan_ff_pattern,
216};
217
218/**
219 * onenand_default_bbt - [OneNAND Interface] Select a default bad block table for the device
220 * @param mtd MTD device structure
221 *
222 * This function selects the default bad block table
223 * support for the device and calls the onenand_scan_bbt function
224 */
225int onenand_default_bbt(struct mtd_info *mtd)
226{
227 struct onenand_chip *this = mtd->priv;
228 struct bbm_info *bbm;
229
230 this->bbm = kmalloc(sizeof(struct bbm_info), GFP_KERNEL);
231 if (!this->bbm)
232 return -ENOMEM;
233
234 bbm = this->bbm;
235
236 memset(bbm, 0, sizeof(struct bbm_info));
237
238 /* 1KB page has same configuration as 2KB page */
239 if (!bbm->badblock_pattern)
240 bbm->badblock_pattern = &largepage_memorybased;
241
242 return onenand_scan_bbt(mtd, bbm->badblock_pattern);
243}
244
245EXPORT_SYMBOL(onenand_scan_bbt);
246EXPORT_SYMBOL(onenand_default_bbt);
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c
index 13f9e992bef8..7b7ca5ab5ae4 100644
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: redboot.c,v 1.17 2004/11/22 11:33:56 ijc Exp $ 2 * $Id: redboot.c,v 1.18 2005/11/07 11:14:21 gleixner Exp $
3 * 3 *
4 * Parse RedBoot-style Flash Image System (FIS) tables and 4 * Parse RedBoot-style Flash Image System (FIS) tables and
5 * produce a Linux partition array to match. 5 * produce a Linux partition array to match.
@@ -39,7 +39,7 @@ static inline int redboot_checksum(struct fis_image_desc *img)
39 return 1; 39 return 1;
40} 40}
41 41
42static int parse_redboot_partitions(struct mtd_info *master, 42static int parse_redboot_partitions(struct mtd_info *master,
43 struct mtd_partition **pparts, 43 struct mtd_partition **pparts,
44 unsigned long fis_origin) 44 unsigned long fis_origin)
45{ 45{
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
new file mode 100644
index 000000000000..0ab8d29caeea
--- /dev/null
+++ b/drivers/mtd/rfd_ftl.c
@@ -0,0 +1,856 @@
1/*
2 * rfd_ftl.c -- resident flash disk (flash translation layer)
3 *
4 * Copyright (C) 2005 Sean Young <sean@mess.org>
5 *
6 * $Id: rfd_ftl.c,v 1.5 2005/11/07 11:14:21 gleixner Exp $
7 *
8 * This type of flash translation layer (FTL) is used by the Embedded BIOS
9 * by General Software. It is known as the Resident Flash Disk (RFD), see:
10 *
11 * http://www.gensw.com/pages/prod/bios/rfd.htm
12 *
13 * based on ftl.c
14 */
15
16#include <linux/hdreg.h>
17#include <linux/init.h>
18#include <linux/mtd/blktrans.h>
19#include <linux/mtd/mtd.h>
20#include <linux/vmalloc.h>
21#include <linux/jiffies.h>
22
23#include <asm/types.h>
24
25#define const_cpu_to_le16 __constant_cpu_to_le16
26
27static int block_size = 0;
28module_param(block_size, int, 0);
29MODULE_PARM_DESC(block_size, "Block size to use by RFD, defaults to erase unit size");
30
31#define PREFIX "rfd_ftl: "
32
33/* Major device # for FTL device */
34
35/* A request for this major has been sent to device@lanana.org */
36#ifndef RFD_FTL_MAJOR
37#define RFD_FTL_MAJOR 95
38#endif
39
40/* Maximum number of partitions in an FTL region */
41#define PART_BITS 4
42
43/* An erase unit should start with this value */
44#define RFD_MAGIC 0x9193
45
46/* the second value is 0xffff or 0xffc8; function unknown */
47
48/* the third value is always 0xffff, ignored */
49
50/* next is an array of mapping for each corresponding sector */
51#define HEADER_MAP_OFFSET 3
52#define SECTOR_DELETED 0x0000
53#define SECTOR_ZERO 0xfffe
54#define SECTOR_FREE 0xffff
55
56#define SECTOR_SIZE 512
57
58#define SECTORS_PER_TRACK 63
59
60struct block {
61 enum {
62 BLOCK_OK,
63 BLOCK_ERASING,
64 BLOCK_ERASED,
65 BLOCK_FAILED
66 } state;
67 int free_sectors;
68 int used_sectors;
69 int erases;
70 u_long offset;
71};
72
73struct partition {
74 struct mtd_blktrans_dev mbd;
75
76 u_int block_size; /* size of erase unit */
77 u_int total_blocks; /* number of erase units */
78 u_int header_sectors_per_block; /* header sectors in erase unit */
79 u_int data_sectors_per_block; /* data sectors in erase unit */
80 u_int sector_count; /* sectors in translated disk */
81 u_int header_size; /* bytes in header sector */
82 int reserved_block; /* block next up for reclaim */
83 int current_block; /* block to write to */
84 u16 *header_cache; /* cached header */
85
86 int is_reclaiming;
87 int cylinders;
88 int errors;
89 u_long *sector_map;
90 struct block *blocks;
91};
92
93static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf);
94
95static int build_block_map(struct partition *part, int block_no)
96{
97 struct block *block = &part->blocks[block_no];
98 int i;
99
100 block->offset = part->block_size * block_no;
101
102 if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) {
103 block->state = BLOCK_ERASED; /* assumption */
104 block->free_sectors = part->data_sectors_per_block;
105 part->reserved_block = block_no;
106 return 1;
107 }
108
109 block->state = BLOCK_OK;
110
111 for (i=0; i<part->data_sectors_per_block; i++) {
112 u16 entry;
113
114 entry = le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i]);
115
116 if (entry == SECTOR_DELETED)
117 continue;
118
119 if (entry == SECTOR_FREE) {
120 block->free_sectors++;
121 continue;
122 }
123
124 if (entry == SECTOR_ZERO)
125 entry = 0;
126
127 if (entry >= part->sector_count) {
128 printk(KERN_NOTICE PREFIX
129 "'%s': unit #%d: entry %d corrupt, "
130 "sector %d out of range\n",
131 part->mbd.mtd->name, block_no, i, entry);
132 continue;
133 }
134
135 if (part->sector_map[entry] != -1) {
136 printk(KERN_NOTICE PREFIX
137 "'%s': more than one entry for sector %d\n",
138 part->mbd.mtd->name, entry);
139 part->errors = 1;
140 continue;
141 }
142
143 part->sector_map[entry] = block->offset +
144 (i + part->header_sectors_per_block) * SECTOR_SIZE;
145
146 block->used_sectors++;
147 }
148
149 if (block->free_sectors == part->data_sectors_per_block)
150 part->reserved_block = block_no;
151
152 return 0;
153}
154
155static int scan_header(struct partition *part)
156{
157 int sectors_per_block;
158 int i, rc = -ENOMEM;
159 int blocks_found;
160 size_t retlen;
161
162 sectors_per_block = part->block_size / SECTOR_SIZE;
163 part->total_blocks = part->mbd.mtd->size / part->block_size;
164
165 if (part->total_blocks < 2)
166 return -ENOENT;
167
168 /* each erase block has three bytes header, followed by the map */
169 part->header_sectors_per_block =
170 ((HEADER_MAP_OFFSET + sectors_per_block) *
171 sizeof(u16) + SECTOR_SIZE - 1) / SECTOR_SIZE;
172
173 part->data_sectors_per_block = sectors_per_block -
174 part->header_sectors_per_block;
175
176 part->header_size = (HEADER_MAP_OFFSET +
177 part->data_sectors_per_block) * sizeof(u16);
178
179 part->cylinders = (part->data_sectors_per_block *
180 (part->total_blocks - 1) - 1) / SECTORS_PER_TRACK;
181
182 part->sector_count = part->cylinders * SECTORS_PER_TRACK;
183
184 part->current_block = -1;
185 part->reserved_block = -1;
186 part->is_reclaiming = 0;
187
188 part->header_cache = kmalloc(part->header_size, GFP_KERNEL);
189 if (!part->header_cache)
190 goto err;
191
192 part->blocks = kcalloc(part->total_blocks, sizeof(struct block),
193 GFP_KERNEL);
194 if (!part->blocks)
195 goto err;
196
197 part->sector_map = vmalloc(part->sector_count * sizeof(u_long));
198 if (!part->sector_map) {
199 printk(KERN_ERR PREFIX "'%s': unable to allocate memory for "
200 "sector map", part->mbd.mtd->name);
201 goto err;
202 }
203
204 for (i=0; i<part->sector_count; i++)
205 part->sector_map[i] = -1;
206
207 for (i=0, blocks_found=0; i<part->total_blocks; i++) {
208 rc = part->mbd.mtd->read(part->mbd.mtd,
209 i * part->block_size, part->header_size,
210 &retlen, (u_char*)part->header_cache);
211
212 if (!rc && retlen != part->header_size)
213 rc = -EIO;
214
215 if (rc)
216 goto err;
217
218 if (!build_block_map(part, i))
219 blocks_found++;
220 }
221
222 if (blocks_found == 0) {
223 printk(KERN_NOTICE PREFIX "no RFD magic found in '%s'\n",
224 part->mbd.mtd->name);
225 rc = -ENOENT;
226 goto err;
227 }
228
229 if (part->reserved_block == -1) {
230 printk(KERN_NOTICE PREFIX "'%s': no empty erase unit found\n",
231 part->mbd.mtd->name);
232
233 part->errors = 1;
234 }
235
236 return 0;
237
238err:
239 vfree(part->sector_map);
240 kfree(part->header_cache);
241 kfree(part->blocks);
242
243 return rc;
244}
245
246static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
247{
248 struct partition *part = (struct partition*)dev;
249 u_long addr;
250 size_t retlen;
251 int rc;
252
253 if (sector >= part->sector_count)
254 return -EIO;
255
256 addr = part->sector_map[sector];
257 if (addr != -1) {
258 rc = part->mbd.mtd->read(part->mbd.mtd, addr, SECTOR_SIZE,
259 &retlen, (u_char*)buf);
260 if (!rc && retlen != SECTOR_SIZE)
261 rc = -EIO;
262
263 if (rc) {
264 printk(KERN_WARNING PREFIX "error reading '%s' at "
265 "0x%lx\n", part->mbd.mtd->name, addr);
266 return rc;
267 }
268 } else
269 memset(buf, 0, SECTOR_SIZE);
270
271 return 0;
272}
273
274static void erase_callback(struct erase_info *erase)
275{
276 struct partition *part;
277 u16 magic;
278 int i, rc;
279 size_t retlen;
280
281 part = (struct partition*)erase->priv;
282
283 i = erase->addr / part->block_size;
284 if (i >= part->total_blocks || part->blocks[i].offset != erase->addr) {
285 printk(KERN_ERR PREFIX "erase callback for unknown offset %x "
286 "on '%s'\n", erase->addr, part->mbd.mtd->name);
287 return;
288 }
289
290 if (erase->state != MTD_ERASE_DONE) {
291 printk(KERN_WARNING PREFIX "erase failed at 0x%x on '%s', "
292 "state %d\n", erase->addr,
293 part->mbd.mtd->name, erase->state);
294
295 part->blocks[i].state = BLOCK_FAILED;
296 part->blocks[i].free_sectors = 0;
297 part->blocks[i].used_sectors = 0;
298
299 kfree(erase);
300
301 return;
302 }
303
304 magic = const_cpu_to_le16(RFD_MAGIC);
305
306 part->blocks[i].state = BLOCK_ERASED;
307 part->blocks[i].free_sectors = part->data_sectors_per_block;
308 part->blocks[i].used_sectors = 0;
309 part->blocks[i].erases++;
310
311 rc = part->mbd.mtd->write(part->mbd.mtd,
312 part->blocks[i].offset, sizeof(magic), &retlen,
313 (u_char*)&magic);
314
315 if (!rc && retlen != sizeof(magic))
316 rc = -EIO;
317
318 if (rc) {
319 printk(KERN_NOTICE PREFIX "'%s': unable to write RFD "
320 "header at 0x%lx\n",
321 part->mbd.mtd->name,
322 part->blocks[i].offset);
323 part->blocks[i].state = BLOCK_FAILED;
324 }
325 else
326 part->blocks[i].state = BLOCK_OK;
327
328 kfree(erase);
329}
330
331static int erase_block(struct partition *part, int block)
332{
333 struct erase_info *erase;
334 int rc = -ENOMEM;
335
336 erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL);
337 if (!erase)
338 goto err;
339
340 erase->mtd = part->mbd.mtd;
341 erase->callback = erase_callback;
342 erase->addr = part->blocks[block].offset;
343 erase->len = part->block_size;
344 erase->priv = (u_long)part;
345
346 part->blocks[block].state = BLOCK_ERASING;
347 part->blocks[block].free_sectors = 0;
348
349 rc = part->mbd.mtd->erase(part->mbd.mtd, erase);
350
351 if (rc) {
352 printk(KERN_WARNING PREFIX "erase of region %x,%x on '%s' "
353 "failed\n", erase->addr, erase->len,
354 part->mbd.mtd->name);
355 kfree(erase);
356 }
357
358err:
359 return rc;
360}
361
362static int move_block_contents(struct partition *part, int block_no, u_long *old_sector)
363{
364 void *sector_data;
365 u16 *map;
366 size_t retlen;
367 int i, rc = -ENOMEM;
368
369 part->is_reclaiming = 1;
370
371 sector_data = kmalloc(SECTOR_SIZE, GFP_KERNEL);
372 if (!sector_data)
373 goto err3;
374
375 map = kmalloc(part->header_size, GFP_KERNEL);
376 if (!map)
377 goto err2;
378
379 rc = part->mbd.mtd->read(part->mbd.mtd,
380 part->blocks[block_no].offset, part->header_size,
381 &retlen, (u_char*)map);
382
383 if (!rc && retlen != part->header_size)
384 rc = -EIO;
385
386 if (rc) {
387 printk(KERN_NOTICE PREFIX "error reading '%s' at "
388 "0x%lx\n", part->mbd.mtd->name,
389 part->blocks[block_no].offset);
390
391 goto err;
392 }
393
394 for (i=0; i<part->data_sectors_per_block; i++) {
395 u16 entry = le16_to_cpu(map[HEADER_MAP_OFFSET + i]);
396 u_long addr;
397
398
399 if (entry == SECTOR_FREE || entry == SECTOR_DELETED)
400 continue;
401
402 if (entry == SECTOR_ZERO)
403 entry = 0;
404
405 /* already warned about and ignored in build_block_map() */
406 if (entry >= part->sector_count)
407 continue;
408
409 addr = part->blocks[block_no].offset +
410 (i + part->header_sectors_per_block) * SECTOR_SIZE;
411
412 if (*old_sector == addr) {
413 *old_sector = -1;
414 if (!part->blocks[block_no].used_sectors--) {
415 rc = erase_block(part, block_no);
416 break;
417 }
418 continue;
419 }
420 rc = part->mbd.mtd->read(part->mbd.mtd, addr,
421 SECTOR_SIZE, &retlen, sector_data);
422
423 if (!rc && retlen != SECTOR_SIZE)
424 rc = -EIO;
425
426 if (rc) {
427 printk(KERN_NOTICE PREFIX "'%s': Unable to "
428 "read sector for relocation\n",
429 part->mbd.mtd->name);
430
431 goto err;
432 }
433
434 rc = rfd_ftl_writesect((struct mtd_blktrans_dev*)part,
435 entry, sector_data);
436
437 if (rc)
438 goto err;
439 }
440
441err:
442 kfree(map);
443err2:
444 kfree(sector_data);
445err3:
446 part->is_reclaiming = 0;
447
448 return rc;
449}
450
451static int reclaim_block(struct partition *part, u_long *old_sector)
452{
453 int block, best_block, score, old_sector_block;
454 int rc;
455
456 /* we have a race if sync doesn't exist */
457 if (part->mbd.mtd->sync)
458 part->mbd.mtd->sync(part->mbd.mtd);
459
460 score = 0x7fffffff; /* MAX_INT */
461 best_block = -1;
462 if (*old_sector != -1)
463 old_sector_block = *old_sector / part->block_size;
464 else
465 old_sector_block = -1;
466
467 for (block=0; block<part->total_blocks; block++) {
468 int this_score;
469
470 if (block == part->reserved_block)
471 continue;
472
473 /*
474 * Postpone reclaiming if there is a free sector as
475 * more removed sectors is more efficient (have to move
476 * less).
477 */
478 if (part->blocks[block].free_sectors)
479 return 0;
480
481 this_score = part->blocks[block].used_sectors;
482
483 if (block == old_sector_block)
484 this_score--;
485 else {
486 /* no point in moving a full block */
487 if (part->blocks[block].used_sectors ==
488 part->data_sectors_per_block)
489 continue;
490 }
491
492 this_score += part->blocks[block].erases;
493
494 if (this_score < score) {
495 best_block = block;
496 score = this_score;
497 }
498 }
499
500 if (best_block == -1)
501 return -ENOSPC;
502
503 part->current_block = -1;
504 part->reserved_block = best_block;
505
506 pr_debug("reclaim_block: reclaiming block #%d with %d used "
507 "%d free sectors\n", best_block,
508 part->blocks[best_block].used_sectors,
509 part->blocks[best_block].free_sectors);
510
511 if (part->blocks[best_block].used_sectors)
512 rc = move_block_contents(part, best_block, old_sector);
513 else
514 rc = erase_block(part, best_block);
515
516 return rc;
517}
518
519/*
520 * IMPROVE: It would be best to choose the block with the most deleted sectors,
521 * because if we fill that one up first it'll have the most chance of having
522 * the least live sectors at reclaim.
523 */
524static int find_free_block(const struct partition *part)
525{
526 int block, stop;
527
528 block = part->current_block == -1 ?
529 jiffies % part->total_blocks : part->current_block;
530 stop = block;
531
532 do {
533 if (part->blocks[block].free_sectors &&
534 block != part->reserved_block)
535 return block;
536
537 if (++block >= part->total_blocks)
538 block = 0;
539
540 } while (block != stop);
541
542 return -1;
543}
544
545static int find_writeable_block(struct partition *part, u_long *old_sector)
546{
547 int rc, block;
548 size_t retlen;
549
550 block = find_free_block(part);
551
552 if (block == -1) {
553 if (!part->is_reclaiming) {
554 rc = reclaim_block(part, old_sector);
555 if (rc)
556 goto err;
557
558 block = find_free_block(part);
559 }
560
561 if (block == -1) {
562 rc = -ENOSPC;
563 goto err;
564 }
565 }
566
567 rc = part->mbd.mtd->read(part->mbd.mtd, part->blocks[block].offset,
568 part->header_size, &retlen, (u_char*)part->header_cache);
569
570 if (!rc && retlen != part->header_size)
571 rc = -EIO;
572
573 if (rc) {
574 printk(KERN_NOTICE PREFIX "'%s': unable to read header at "
575 "0x%lx\n", part->mbd.mtd->name,
576 part->blocks[block].offset);
577 goto err;
578 }
579
580 part->current_block = block;
581
582err:
583 return rc;
584}
585
586static int mark_sector_deleted(struct partition *part, u_long old_addr)
587{
588 int block, offset, rc;
589 u_long addr;
590 size_t retlen;
591 u16 del = const_cpu_to_le16(SECTOR_DELETED);
592
593 block = old_addr / part->block_size;
594 offset = (old_addr % part->block_size) / SECTOR_SIZE -
595 part->header_sectors_per_block;
596
597 addr = part->blocks[block].offset +
598 (HEADER_MAP_OFFSET + offset) * sizeof(u16);
599 rc = part->mbd.mtd->write(part->mbd.mtd, addr,
600 sizeof(del), &retlen, (u_char*)&del);
601
602 if (!rc && retlen != sizeof(del))
603 rc = -EIO;
604
605 if (rc) {
606 printk(KERN_WARNING PREFIX "error writing '%s' at "
607 "0x%lx\n", part->mbd.mtd->name, addr);
608 if (rc)
609 goto err;
610 }
611 if (block == part->current_block)
612 part->header_cache[offset + HEADER_MAP_OFFSET] = del;
613
614 part->blocks[block].used_sectors--;
615
616 if (!part->blocks[block].used_sectors &&
617 !part->blocks[block].free_sectors)
618 rc = erase_block(part, block);
619
620err:
621 return rc;
622}
623
624static int find_free_sector(const struct partition *part, const struct block *block)
625{
626 int i, stop;
627
628 i = stop = part->data_sectors_per_block - block->free_sectors;
629
630 do {
631 if (le16_to_cpu(part->header_cache[HEADER_MAP_OFFSET + i])
632 == SECTOR_FREE)
633 return i;
634
635 if (++i == part->data_sectors_per_block)
636 i = 0;
637 }
638 while(i != stop);
639
640 return -1;
641}
642
643static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ulong *old_addr)
644{
645 struct partition *part = (struct partition*)dev;
646 struct block *block;
647 u_long addr;
648 int i;
649 int rc;
650 size_t retlen;
651 u16 entry;
652
653 if (part->current_block == -1 ||
654 !part->blocks[part->current_block].free_sectors) {
655
656 rc = find_writeable_block(part, old_addr);
657 if (rc)
658 goto err;
659 }
660
661 block = &part->blocks[part->current_block];
662
663 i = find_free_sector(part, block);
664
665 if (i < 0) {
666 rc = -ENOSPC;
667 goto err;
668 }
669
670 addr = (i + part->header_sectors_per_block) * SECTOR_SIZE +
671 block->offset;
672 rc = part->mbd.mtd->write(part->mbd.mtd,
673 addr, SECTOR_SIZE, &retlen, (u_char*)buf);
674
675 if (!rc && retlen != SECTOR_SIZE)
676 rc = -EIO;
677
678 if (rc) {
679 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
680 part->mbd.mtd->name, addr);
681 if (rc)
682 goto err;
683 }
684
685 part->sector_map[sector] = addr;
686
687 entry = cpu_to_le16(sector == 0 ? SECTOR_ZERO : sector);
688
689 part->header_cache[i + HEADER_MAP_OFFSET] = entry;
690
691 addr = block->offset + (HEADER_MAP_OFFSET + i) * sizeof(u16);
692 rc = part->mbd.mtd->write(part->mbd.mtd, addr,
693 sizeof(entry), &retlen, (u_char*)&entry);
694
695 if (!rc && retlen != sizeof(entry))
696 rc = -EIO;
697
698 if (rc) {
699 printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n",
700 part->mbd.mtd->name, addr);
701 if (rc)
702 goto err;
703 }
704 block->used_sectors++;
705 block->free_sectors--;
706
707err:
708 return rc;
709}
710
711static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
712{
713 struct partition *part = (struct partition*)dev;
714 u_long old_addr;
715 int i;
716 int rc = 0;
717
718 pr_debug("rfd_ftl_writesect(sector=0x%lx)\n", sector);
719
720 if (part->reserved_block == -1) {
721 rc = -EACCES;
722 goto err;
723 }
724
725 if (sector >= part->sector_count) {
726 rc = -EIO;
727 goto err;
728 }
729
730 old_addr = part->sector_map[sector];
731
732 for (i=0; i<SECTOR_SIZE; i++) {
733 if (!buf[i])
734 continue;
735
736 rc = do_writesect(dev, sector, buf, &old_addr);
737 if (rc)
738 goto err;
739 break;
740 }
741
742 if (i == SECTOR_SIZE)
743 part->sector_map[sector] = -1;
744
745 if (old_addr != -1)
746 rc = mark_sector_deleted(part, old_addr);
747
748err:
749 return rc;
750}
751
752static int rfd_ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
753{
754 struct partition *part = (struct partition*)dev;
755
756 geo->heads = 1;
757 geo->sectors = SECTORS_PER_TRACK;
758 geo->cylinders = part->cylinders;
759
760 return 0;
761}
762
763static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
764{
765 struct partition *part;
766
767 if (mtd->type != MTD_NORFLASH)
768 return;
769
770 part = kcalloc(1, sizeof(struct partition), GFP_KERNEL);
771 if (!part)
772 return;
773
774 part->mbd.mtd = mtd;
775
776 if (block_size)
777 part->block_size = block_size;
778 else {
779 if (!mtd->erasesize) {
780 printk(KERN_NOTICE PREFIX "please provide block_size");
781 return;
782 }
783 else
784 part->block_size = mtd->erasesize;
785 }
786
787 if (scan_header(part) == 0) {
788 part->mbd.size = part->sector_count;
789 part->mbd.blksize = SECTOR_SIZE;
790 part->mbd.tr = tr;
791 part->mbd.devnum = -1;
792 if (!(mtd->flags & MTD_WRITEABLE))
793 part->mbd.readonly = 1;
794 else if (part->errors) {
795 printk(KERN_NOTICE PREFIX "'%s': errors found, "
796 "setting read-only", mtd->name);
797 part->mbd.readonly = 1;
798 }
799
800 printk(KERN_INFO PREFIX "name: '%s' type: %d flags %x\n",
801 mtd->name, mtd->type, mtd->flags);
802
803 if (!add_mtd_blktrans_dev((void*)part))
804 return;
805 }
806
807 kfree(part);
808}
809
810static void rfd_ftl_remove_dev(struct mtd_blktrans_dev *dev)
811{
812 struct partition *part = (struct partition*)dev;
813 int i;
814
815 for (i=0; i<part->total_blocks; i++) {
816 pr_debug("rfd_ftl_remove_dev:'%s': erase unit #%02d: %d erases\n",
817 part->mbd.mtd->name, i, part->blocks[i].erases);
818 }
819
820 del_mtd_blktrans_dev(dev);
821 vfree(part->sector_map);
822 kfree(part->header_cache);
823 kfree(part->blocks);
824 kfree(part);
825}
826
827struct mtd_blktrans_ops rfd_ftl_tr = {
828 .name = "rfd",
829 .major = RFD_FTL_MAJOR,
830 .part_bits = PART_BITS,
831 .readsect = rfd_ftl_readsect,
832 .writesect = rfd_ftl_writesect,
833 .getgeo = rfd_ftl_getgeo,
834 .add_mtd = rfd_ftl_add_mtd,
835 .remove_dev = rfd_ftl_remove_dev,
836 .owner = THIS_MODULE,
837};
838
839static int __init init_rfd_ftl(void)
840{
841 return register_mtd_blktrans(&rfd_ftl_tr);
842}
843
844static void __exit cleanup_rfd_ftl(void)
845{
846 deregister_mtd_blktrans(&rfd_ftl_tr);
847}
848
849module_init(init_rfd_ftl);
850module_exit(cleanup_rfd_ftl);
851
852MODULE_LICENSE("GPL");
853MODULE_AUTHOR("Sean Young <sean@mess.org>");
854MODULE_DESCRIPTION("Support code for RFD Flash Translation Layer, "
855 "used by General Software's Embedded BIOS");
856
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 455ba915ede7..7488ee7f7caf 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -602,7 +602,7 @@ MODULE_DEVICE_TABLE(pci, vortex_pci_tbl);
602 First the windows. There are eight register windows, with the command 602 First the windows. There are eight register windows, with the command
603 and status registers available in each. 603 and status registers available in each.
604 */ 604 */
605#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD) 605#define EL3WINDOW(win_num) iowrite16(SelectWindow + (win_num), ioaddr + EL3_CMD)
606#define EL3_CMD 0x0e 606#define EL3_CMD 0x0e
607#define EL3_STATUS 0x0e 607#define EL3_STATUS 0x0e
608 608
@@ -776,7 +776,8 @@ struct vortex_private {
776 776
777 /* PCI configuration space information. */ 777 /* PCI configuration space information. */
778 struct device *gendev; 778 struct device *gendev;
779 char __iomem *cb_fn_base; /* CardBus function status addr space. */ 779 void __iomem *ioaddr; /* IO address space */
780 void __iomem *cb_fn_base; /* CardBus function status addr space. */
780 781
781 /* Some values here only for performance evaluation and path-coverage */ 782 /* Some values here only for performance evaluation and path-coverage */
782 int rx_nocopy, rx_copy, queued_packet, rx_csumhits; 783 int rx_nocopy, rx_copy, queued_packet, rx_csumhits;
@@ -869,12 +870,12 @@ static struct {
869/* number of ETHTOOL_GSTATS u64's */ 870/* number of ETHTOOL_GSTATS u64's */
870#define VORTEX_NUM_STATS 3 871#define VORTEX_NUM_STATS 3
871 872
872static int vortex_probe1(struct device *gendev, long ioaddr, int irq, 873static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
873 int chip_idx, int card_idx); 874 int chip_idx, int card_idx);
874static void vortex_up(struct net_device *dev); 875static void vortex_up(struct net_device *dev);
875static void vortex_down(struct net_device *dev, int final); 876static void vortex_down(struct net_device *dev, int final);
876static int vortex_open(struct net_device *dev); 877static int vortex_open(struct net_device *dev);
877static void mdio_sync(long ioaddr, int bits); 878static void mdio_sync(void __iomem *ioaddr, int bits);
878static int mdio_read(struct net_device *dev, int phy_id, int location); 879static int mdio_read(struct net_device *dev, int phy_id, int location);
879static void mdio_write(struct net_device *vp, int phy_id, int location, int value); 880static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
880static void vortex_timer(unsigned long arg); 881static void vortex_timer(unsigned long arg);
@@ -887,7 +888,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
887static irqreturn_t boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs); 888static irqreturn_t boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);
888static int vortex_close(struct net_device *dev); 889static int vortex_close(struct net_device *dev);
889static void dump_tx_ring(struct net_device *dev); 890static void dump_tx_ring(struct net_device *dev);
890static void update_stats(long ioaddr, struct net_device *dev); 891static void update_stats(void __iomem *ioaddr, struct net_device *dev);
891static struct net_device_stats *vortex_get_stats(struct net_device *dev); 892static struct net_device_stats *vortex_get_stats(struct net_device *dev);
892static void set_rx_mode(struct net_device *dev); 893static void set_rx_mode(struct net_device *dev);
893#ifdef CONFIG_PCI 894#ifdef CONFIG_PCI
@@ -902,14 +903,16 @@ static void set_8021q_mode(struct net_device *dev, int enable);
902/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ 903/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
903/* Option count limit only -- unlimited interfaces are supported. */ 904/* Option count limit only -- unlimited interfaces are supported. */
904#define MAX_UNITS 8 905#define MAX_UNITS 8
905static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,}; 906static int options[MAX_UNITS] = { [0 ... MAX_UNITS-1] = -1 };
906static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; 907static int full_duplex[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
907static int hw_checksums[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; 908static int hw_checksums[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
908static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; 909static int flow_ctrl[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
909static int enable_wol[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; 910static int enable_wol[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
911static int use_mmio[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
910static int global_options = -1; 912static int global_options = -1;
911static int global_full_duplex = -1; 913static int global_full_duplex = -1;
912static int global_enable_wol = -1; 914static int global_enable_wol = -1;
915static int global_use_mmio = -1;
913 916
914/* #define dev_alloc_skb dev_alloc_skb_debug */ 917/* #define dev_alloc_skb dev_alloc_skb_debug */
915 918
@@ -934,21 +937,25 @@ module_param(compaq_ioaddr, int, 0);
934module_param(compaq_irq, int, 0); 937module_param(compaq_irq, int, 0);
935module_param(compaq_device_id, int, 0); 938module_param(compaq_device_id, int, 0);
936module_param(watchdog, int, 0); 939module_param(watchdog, int, 0);
940module_param(global_use_mmio, int, 0);
941module_param_array(use_mmio, int, NULL, 0);
937MODULE_PARM_DESC(debug, "3c59x debug level (0-6)"); 942MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
938MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex"); 943MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
939MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset"); 944MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
940MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)"); 945MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
941MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset"); 946MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if full_duplex is unset");
942MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)"); 947MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
943MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)"); 948MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
944MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)"); 949MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
945MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset"); 950MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if enable_wol is unset");
946MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames"); 951MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
947MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt"); 952MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
948MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)"); 953MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
949MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)"); 954MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");
950MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)"); 955MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");
951MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds"); 956MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
957MODULE_PARM_DESC(global_use_mmio, "3c59x: same as use_mmio, but applies to all NICs if options is unset");
958MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");
952 959
953#ifdef CONFIG_NET_POLL_CONTROLLER 960#ifdef CONFIG_NET_POLL_CONTROLLER
954static void poll_vortex(struct net_device *dev) 961static void poll_vortex(struct net_device *dev)
@@ -1029,18 +1036,19 @@ static struct eisa_driver vortex_eisa_driver = {
1029 1036
1030static int vortex_eisa_probe (struct device *device) 1037static int vortex_eisa_probe (struct device *device)
1031{ 1038{
1032 long ioaddr; 1039 void __iomem *ioaddr;
1033 struct eisa_device *edev; 1040 struct eisa_device *edev;
1034 1041
1035 edev = to_eisa_device (device); 1042 edev = to_eisa_device (device);
1036 ioaddr = edev->base_addr;
1037 1043
1038 if (!request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME)) 1044 if (!request_region(edev->base_addr, VORTEX_TOTAL_SIZE, DRV_NAME))
1039 return -EBUSY; 1045 return -EBUSY;
1040 1046
1041 if (vortex_probe1(device, ioaddr, inw(ioaddr + 0xC88) >> 12, 1047 ioaddr = ioport_map(edev->base_addr, VORTEX_TOTAL_SIZE);
1048
1049 if (vortex_probe1(device, ioaddr, ioread16(ioaddr + 0xC88) >> 12,
1042 edev->id.driver_data, vortex_cards_found)) { 1050 edev->id.driver_data, vortex_cards_found)) {
1043 release_region (ioaddr, VORTEX_TOTAL_SIZE); 1051 release_region (edev->base_addr, VORTEX_TOTAL_SIZE);
1044 return -ENODEV; 1052 return -ENODEV;
1045 } 1053 }
1046 1054
@@ -1054,7 +1062,7 @@ static int vortex_eisa_remove (struct device *device)
1054 struct eisa_device *edev; 1062 struct eisa_device *edev;
1055 struct net_device *dev; 1063 struct net_device *dev;
1056 struct vortex_private *vp; 1064 struct vortex_private *vp;
1057 long ioaddr; 1065 void __iomem *ioaddr;
1058 1066
1059 edev = to_eisa_device (device); 1067 edev = to_eisa_device (device);
1060 dev = eisa_get_drvdata (edev); 1068 dev = eisa_get_drvdata (edev);
@@ -1065,11 +1073,11 @@ static int vortex_eisa_remove (struct device *device)
1065 } 1073 }
1066 1074
1067 vp = netdev_priv(dev); 1075 vp = netdev_priv(dev);
1068 ioaddr = dev->base_addr; 1076 ioaddr = vp->ioaddr;
1069 1077
1070 unregister_netdev (dev); 1078 unregister_netdev (dev);
1071 outw (TotalReset|0x14, ioaddr + EL3_CMD); 1079 iowrite16 (TotalReset|0x14, ioaddr + EL3_CMD);
1072 release_region (ioaddr, VORTEX_TOTAL_SIZE); 1080 release_region (dev->base_addr, VORTEX_TOTAL_SIZE);
1073 1081
1074 free_netdev (dev); 1082 free_netdev (dev);
1075 return 0; 1083 return 0;
@@ -1096,8 +1104,8 @@ static int __init vortex_eisa_init (void)
1096 1104
1097 /* Special code to work-around the Compaq PCI BIOS32 problem. */ 1105 /* Special code to work-around the Compaq PCI BIOS32 problem. */
1098 if (compaq_ioaddr) { 1106 if (compaq_ioaddr) {
1099 vortex_probe1(NULL, compaq_ioaddr, compaq_irq, 1107 vortex_probe1(NULL, ioport_map(compaq_ioaddr, VORTEX_TOTAL_SIZE),
1100 compaq_device_id, vortex_cards_found++); 1108 compaq_irq, compaq_device_id, vortex_cards_found++);
1101 } 1109 }
1102 1110
1103 return vortex_cards_found - orig_cards_found + eisa_found; 1111 return vortex_cards_found - orig_cards_found + eisa_found;
@@ -1107,15 +1115,32 @@ static int __init vortex_eisa_init (void)
1107static int __devinit vortex_init_one (struct pci_dev *pdev, 1115static int __devinit vortex_init_one (struct pci_dev *pdev,
1108 const struct pci_device_id *ent) 1116 const struct pci_device_id *ent)
1109{ 1117{
1110 int rc; 1118 int rc, unit, pci_bar;
1119 struct vortex_chip_info *vci;
1120 void __iomem *ioaddr;
1111 1121
1112 /* wake up and enable device */ 1122 /* wake up and enable device */
1113 rc = pci_enable_device (pdev); 1123 rc = pci_enable_device (pdev);
1114 if (rc < 0) 1124 if (rc < 0)
1115 goto out; 1125 goto out;
1116 1126
1117 rc = vortex_probe1 (&pdev->dev, pci_resource_start (pdev, 0), 1127 unit = vortex_cards_found;
1118 pdev->irq, ent->driver_data, vortex_cards_found); 1128
1129 if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
1130 /* Determine the default if the user didn't override us */
1131 vci = &vortex_info_tbl[ent->driver_data];
1132 pci_bar = vci->drv_flags & (IS_CYCLONE | IS_TORNADO) ? 1 : 0;
1133 } else if (unit < MAX_UNITS && use_mmio[unit] >= 0)
1134 pci_bar = use_mmio[unit] ? 1 : 0;
1135 else
1136 pci_bar = global_use_mmio ? 1 : 0;
1137
1138 ioaddr = pci_iomap(pdev, pci_bar, 0);
1139 if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
1140 ioaddr = pci_iomap(pdev, 0, 0);
1141
1142 rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
1143 ent->driver_data, unit);
1119 if (rc < 0) { 1144 if (rc < 0) {
1120 pci_disable_device (pdev); 1145 pci_disable_device (pdev);
1121 goto out; 1146 goto out;
@@ -1134,7 +1159,7 @@ out:
1134 * NOTE: pdev can be NULL, for the case of a Compaq device 1159 * NOTE: pdev can be NULL, for the case of a Compaq device
1135 */ 1160 */
1136static int __devinit vortex_probe1(struct device *gendev, 1161static int __devinit vortex_probe1(struct device *gendev,
1137 long ioaddr, int irq, 1162 void __iomem *ioaddr, int irq,
1138 int chip_idx, int card_idx) 1163 int chip_idx, int card_idx)
1139{ 1164{
1140 struct vortex_private *vp; 1165 struct vortex_private *vp;
@@ -1202,15 +1227,16 @@ static int __devinit vortex_probe1(struct device *gendev,
1202 if (print_info) 1227 if (print_info)
1203 printk (KERN_INFO "See Documentation/networking/vortex.txt\n"); 1228 printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
1204 1229
1205 printk(KERN_INFO "%s: 3Com %s %s at 0x%lx. Vers " DRV_VERSION "\n", 1230 printk(KERN_INFO "%s: 3Com %s %s at %p. Vers " DRV_VERSION "\n",
1206 print_name, 1231 print_name,
1207 pdev ? "PCI" : "EISA", 1232 pdev ? "PCI" : "EISA",
1208 vci->name, 1233 vci->name,
1209 ioaddr); 1234 ioaddr);
1210 1235
1211 dev->base_addr = ioaddr; 1236 dev->base_addr = (unsigned long)ioaddr;
1212 dev->irq = irq; 1237 dev->irq = irq;
1213 dev->mtu = mtu; 1238 dev->mtu = mtu;
1239 vp->ioaddr = ioaddr;
1214 vp->large_frames = mtu > 1500; 1240 vp->large_frames = mtu > 1500;
1215 vp->drv_flags = vci->drv_flags; 1241 vp->drv_flags = vci->drv_flags;
1216 vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0; 1242 vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
@@ -1226,7 +1252,7 @@ static int __devinit vortex_probe1(struct device *gendev,
1226 if (pdev) { 1252 if (pdev) {
1227 /* EISA resources already marked, so only PCI needs to do this here */ 1253 /* EISA resources already marked, so only PCI needs to do this here */
1228 /* Ignore return value, because Cardbus drivers already allocate for us */ 1254 /* Ignore return value, because Cardbus drivers already allocate for us */
1229 if (request_region(ioaddr, vci->io_size, print_name) != NULL) 1255 if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
1230 vp->must_free_region = 1; 1256 vp->must_free_region = 1;
1231 1257
1232 /* enable bus-mastering if necessary */ 1258 /* enable bus-mastering if necessary */
@@ -1316,14 +1342,14 @@ static int __devinit vortex_probe1(struct device *gendev,
1316 1342
1317 for (i = 0; i < 0x40; i++) { 1343 for (i = 0; i < 0x40; i++) {
1318 int timer; 1344 int timer;
1319 outw(base + i, ioaddr + Wn0EepromCmd); 1345 iowrite16(base + i, ioaddr + Wn0EepromCmd);
1320 /* Pause for at least 162 us. for the read to take place. */ 1346 /* Pause for at least 162 us. for the read to take place. */
1321 for (timer = 10; timer >= 0; timer--) { 1347 for (timer = 10; timer >= 0; timer--) {
1322 udelay(162); 1348 udelay(162);
1323 if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0) 1349 if ((ioread16(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
1324 break; 1350 break;
1325 } 1351 }
1326 eeprom[i] = inw(ioaddr + Wn0EepromData); 1352 eeprom[i] = ioread16(ioaddr + Wn0EepromData);
1327 } 1353 }
1328 } 1354 }
1329 for (i = 0; i < 0x18; i++) 1355 for (i = 0; i < 0x18; i++)
@@ -1338,6 +1364,7 @@ static int __devinit vortex_probe1(struct device *gendev,
1338 printk(" ***INVALID CHECKSUM %4.4x*** ", checksum); 1364 printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
1339 for (i = 0; i < 3; i++) 1365 for (i = 0; i < 3; i++)
1340 ((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]); 1366 ((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
1367 memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
1341 if (print_info) { 1368 if (print_info) {
1342 for (i = 0; i < 6; i++) 1369 for (i = 0; i < 6; i++)
1343 printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); 1370 printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
@@ -1351,7 +1378,7 @@ static int __devinit vortex_probe1(struct device *gendev,
1351 } 1378 }
1352 EL3WINDOW(2); 1379 EL3WINDOW(2);
1353 for (i = 0; i < 6; i++) 1380 for (i = 0; i < 6; i++)
1354 outb(dev->dev_addr[i], ioaddr + i); 1381 iowrite8(dev->dev_addr[i], ioaddr + i);
1355 1382
1356#ifdef __sparc__ 1383#ifdef __sparc__
1357 if (print_info) 1384 if (print_info)
@@ -1366,7 +1393,7 @@ static int __devinit vortex_probe1(struct device *gendev,
1366#endif 1393#endif
1367 1394
1368 EL3WINDOW(4); 1395 EL3WINDOW(4);
1369 step = (inb(ioaddr + Wn4_NetDiag) & 0x1e) >> 1; 1396 step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
1370 if (print_info) { 1397 if (print_info) {
1371 printk(KERN_INFO " product code %02x%02x rev %02x.%d date %02d-" 1398 printk(KERN_INFO " product code %02x%02x rev %02x.%d date %02d-"
1372 "%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14], 1399 "%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
@@ -1375,31 +1402,30 @@ static int __devinit vortex_probe1(struct device *gendev,
1375 1402
1376 1403
1377 if (pdev && vci->drv_flags & HAS_CB_FNS) { 1404 if (pdev && vci->drv_flags & HAS_CB_FNS) {
1378 unsigned long fn_st_addr; /* Cardbus function status space */
1379 unsigned short n; 1405 unsigned short n;
1380 1406
1381 fn_st_addr = pci_resource_start (pdev, 2); 1407 vp->cb_fn_base = pci_iomap(pdev, 2, 0);
1382 if (fn_st_addr) { 1408 if (!vp->cb_fn_base) {
1383 vp->cb_fn_base = ioremap(fn_st_addr, 128);
1384 retval = -ENOMEM; 1409 retval = -ENOMEM;
1385 if (!vp->cb_fn_base) 1410 goto free_ring;
1386 goto free_ring;
1387 } 1411 }
1412
1388 if (print_info) { 1413 if (print_info) {
1389 printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n", 1414 printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
1390 print_name, fn_st_addr, vp->cb_fn_base); 1415 print_name, pci_resource_start(pdev, 2),
1416 vp->cb_fn_base);
1391 } 1417 }
1392 EL3WINDOW(2); 1418 EL3WINDOW(2);
1393 1419
1394 n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010; 1420 n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
1395 if (vp->drv_flags & INVERT_LED_PWR) 1421 if (vp->drv_flags & INVERT_LED_PWR)
1396 n |= 0x10; 1422 n |= 0x10;
1397 if (vp->drv_flags & INVERT_MII_PWR) 1423 if (vp->drv_flags & INVERT_MII_PWR)
1398 n |= 0x4000; 1424 n |= 0x4000;
1399 outw(n, ioaddr + Wn2_ResetOptions); 1425 iowrite16(n, ioaddr + Wn2_ResetOptions);
1400 if (vp->drv_flags & WNO_XCVR_PWR) { 1426 if (vp->drv_flags & WNO_XCVR_PWR) {
1401 EL3WINDOW(0); 1427 EL3WINDOW(0);
1402 outw(0x0800, ioaddr); 1428 iowrite16(0x0800, ioaddr);
1403 } 1429 }
1404 } 1430 }
1405 1431
@@ -1418,13 +1444,13 @@ static int __devinit vortex_probe1(struct device *gendev,
1418 static const char * ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; 1444 static const char * ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
1419 unsigned int config; 1445 unsigned int config;
1420 EL3WINDOW(3); 1446 EL3WINDOW(3);
1421 vp->available_media = inw(ioaddr + Wn3_Options); 1447 vp->available_media = ioread16(ioaddr + Wn3_Options);
1422 if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */ 1448 if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */
1423 vp->available_media = 0x40; 1449 vp->available_media = 0x40;
1424 config = inl(ioaddr + Wn3_Config); 1450 config = ioread32(ioaddr + Wn3_Config);
1425 if (print_info) { 1451 if (print_info) {
1426 printk(KERN_DEBUG " Internal config register is %4.4x, " 1452 printk(KERN_DEBUG " Internal config register is %4.4x, "
1427 "transceivers %#x.\n", config, inw(ioaddr + Wn3_Options)); 1453 "transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
1428 printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n", 1454 printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
1429 8 << RAM_SIZE(config), 1455 8 << RAM_SIZE(config),
1430 RAM_WIDTH(config) ? "word" : "byte", 1456 RAM_WIDTH(config) ? "word" : "byte",
@@ -1455,7 +1481,7 @@ static int __devinit vortex_probe1(struct device *gendev,
1455 if (vp->drv_flags & EXTRA_PREAMBLE) 1481 if (vp->drv_flags & EXTRA_PREAMBLE)
1456 mii_preamble_required++; 1482 mii_preamble_required++;
1457 mdio_sync(ioaddr, 32); 1483 mdio_sync(ioaddr, 32);
1458 mdio_read(dev, 24, 1); 1484 mdio_read(dev, 24, MII_BMSR);
1459 for (phy = 0; phy < 32 && phy_idx < 1; phy++) { 1485 for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
1460 int mii_status, phyx; 1486 int mii_status, phyx;
1461 1487
@@ -1469,7 +1495,7 @@ static int __devinit vortex_probe1(struct device *gendev,
1469 phyx = phy - 1; 1495 phyx = phy - 1;
1470 else 1496 else
1471 phyx = phy; 1497 phyx = phy;
1472 mii_status = mdio_read(dev, phyx, 1); 1498 mii_status = mdio_read(dev, phyx, MII_BMSR);
1473 if (mii_status && mii_status != 0xffff) { 1499 if (mii_status && mii_status != 0xffff) {
1474 vp->phys[phy_idx++] = phyx; 1500 vp->phys[phy_idx++] = phyx;
1475 if (print_info) { 1501 if (print_info) {
@@ -1485,7 +1511,7 @@ static int __devinit vortex_probe1(struct device *gendev,
1485 printk(KERN_WARNING" ***WARNING*** No MII transceivers found!\n"); 1511 printk(KERN_WARNING" ***WARNING*** No MII transceivers found!\n");
1486 vp->phys[0] = 24; 1512 vp->phys[0] = 24;
1487 } else { 1513 } else {
1488 vp->advertising = mdio_read(dev, vp->phys[0], 4); 1514 vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
1489 if (vp->full_duplex) { 1515 if (vp->full_duplex) {
1490 /* Only advertise the FD media types. */ 1516 /* Only advertise the FD media types. */
1491 vp->advertising &= ~0x02A0; 1517 vp->advertising &= ~0x02A0;
@@ -1510,10 +1536,10 @@ static int __devinit vortex_probe1(struct device *gendev,
1510 if (vp->full_bus_master_tx) { 1536 if (vp->full_bus_master_tx) {
1511 dev->hard_start_xmit = boomerang_start_xmit; 1537 dev->hard_start_xmit = boomerang_start_xmit;
1512 /* Actually, it still should work with iommu. */ 1538 /* Actually, it still should work with iommu. */
1513 dev->features |= NETIF_F_SG; 1539 if (card_idx < MAX_UNITS &&
1514 if (((hw_checksums[card_idx] == -1) && (vp->drv_flags & HAS_HWCKSM)) || 1540 ((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
1515 (hw_checksums[card_idx] == 1)) { 1541 hw_checksums[card_idx] == 1)) {
1516 dev->features |= NETIF_F_IP_CSUM; 1542 dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
1517 } 1543 }
1518 } else { 1544 } else {
1519 dev->hard_start_xmit = vortex_start_xmit; 1545 dev->hard_start_xmit = vortex_start_xmit;
@@ -1555,7 +1581,7 @@ free_ring:
1555 vp->rx_ring_dma); 1581 vp->rx_ring_dma);
1556free_region: 1582free_region:
1557 if (vp->must_free_region) 1583 if (vp->must_free_region)
1558 release_region(ioaddr, vci->io_size); 1584 release_region(dev->base_addr, vci->io_size);
1559 free_netdev(dev); 1585 free_netdev(dev);
1560 printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval); 1586 printk(KERN_ERR PFX "vortex_probe1 fails. Returns %d\n", retval);
1561out: 1587out:
@@ -1565,17 +1591,19 @@ out:
1565static void 1591static void
1566issue_and_wait(struct net_device *dev, int cmd) 1592issue_and_wait(struct net_device *dev, int cmd)
1567{ 1593{
1594 struct vortex_private *vp = netdev_priv(dev);
1595 void __iomem *ioaddr = vp->ioaddr;
1568 int i; 1596 int i;
1569 1597
1570 outw(cmd, dev->base_addr + EL3_CMD); 1598 iowrite16(cmd, ioaddr + EL3_CMD);
1571 for (i = 0; i < 2000; i++) { 1599 for (i = 0; i < 2000; i++) {
1572 if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress)) 1600 if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
1573 return; 1601 return;
1574 } 1602 }
1575 1603
1576 /* OK, that didn't work. Do it the slow way. One second */ 1604 /* OK, that didn't work. Do it the slow way. One second */
1577 for (i = 0; i < 100000; i++) { 1605 for (i = 0; i < 100000; i++) {
1578 if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress)) { 1606 if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
1579 if (vortex_debug > 1) 1607 if (vortex_debug > 1)
1580 printk(KERN_INFO "%s: command 0x%04x took %d usecs\n", 1608 printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
1581 dev->name, cmd, i * 10); 1609 dev->name, cmd, i * 10);
@@ -1584,14 +1612,14 @@ issue_and_wait(struct net_device *dev, int cmd)
1584 udelay(10); 1612 udelay(10);
1585 } 1613 }
1586 printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n", 1614 printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
1587 dev->name, cmd, inw(dev->base_addr + EL3_STATUS)); 1615 dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
1588} 1616}
1589 1617
1590static void 1618static void
1591vortex_up(struct net_device *dev) 1619vortex_up(struct net_device *dev)
1592{ 1620{
1593 long ioaddr = dev->base_addr;
1594 struct vortex_private *vp = netdev_priv(dev); 1621 struct vortex_private *vp = netdev_priv(dev);
1622 void __iomem *ioaddr = vp->ioaddr;
1595 unsigned int config; 1623 unsigned int config;
1596 int i; 1624 int i;
1597 1625
@@ -1604,7 +1632,7 @@ vortex_up(struct net_device *dev)
1604 1632
1605 /* Before initializing select the active media port. */ 1633 /* Before initializing select the active media port. */
1606 EL3WINDOW(3); 1634 EL3WINDOW(3);
1607 config = inl(ioaddr + Wn3_Config); 1635 config = ioread32(ioaddr + Wn3_Config);
1608 1636
1609 if (vp->media_override != 7) { 1637 if (vp->media_override != 7) {
1610 printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n", 1638 printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
@@ -1651,14 +1679,14 @@ vortex_up(struct net_device *dev)
1651 config = BFINS(config, dev->if_port, 20, 4); 1679 config = BFINS(config, dev->if_port, 20, 4);
1652 if (vortex_debug > 6) 1680 if (vortex_debug > 6)
1653 printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config); 1681 printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
1654 outl(config, ioaddr + Wn3_Config); 1682 iowrite32(config, ioaddr + Wn3_Config);
1655 1683
1656 if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) { 1684 if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
1657 int mii_reg1, mii_reg5; 1685 int mii_reg1, mii_reg5;
1658 EL3WINDOW(4); 1686 EL3WINDOW(4);
1659 /* Read BMSR (reg1) only to clear old status. */ 1687 /* Read BMSR (reg1) only to clear old status. */
1660 mii_reg1 = mdio_read(dev, vp->phys[0], 1); 1688 mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
1661 mii_reg5 = mdio_read(dev, vp->phys[0], 5); 1689 mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
1662 if (mii_reg5 == 0xffff || mii_reg5 == 0x0000) { 1690 if (mii_reg5 == 0xffff || mii_reg5 == 0x0000) {
1663 netif_carrier_off(dev); /* No MII device or no link partner report */ 1691 netif_carrier_off(dev); /* No MII device or no link partner report */
1664 } else { 1692 } else {
@@ -1679,7 +1707,7 @@ vortex_up(struct net_device *dev)
1679 } 1707 }
1680 1708
1681 /* Set the full-duplex bit. */ 1709 /* Set the full-duplex bit. */
1682 outw( ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) | 1710 iowrite16( ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
1683 (vp->large_frames ? 0x40 : 0) | 1711 (vp->large_frames ? 0x40 : 0) |
1684 ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), 1712 ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
1685 ioaddr + Wn3_MAC_Ctrl); 1713 ioaddr + Wn3_MAC_Ctrl);
@@ -1695,51 +1723,51 @@ vortex_up(struct net_device *dev)
1695 */ 1723 */
1696 issue_and_wait(dev, RxReset|0x04); 1724 issue_and_wait(dev, RxReset|0x04);
1697 1725
1698 outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD); 1726 iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
1699 1727
1700 if (vortex_debug > 1) { 1728 if (vortex_debug > 1) {
1701 EL3WINDOW(4); 1729 EL3WINDOW(4);
1702 printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n", 1730 printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
1703 dev->name, dev->irq, inw(ioaddr + Wn4_Media)); 1731 dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
1704 } 1732 }
1705 1733
1706 /* Set the station address and mask in window 2 each time opened. */ 1734 /* Set the station address and mask in window 2 each time opened. */
1707 EL3WINDOW(2); 1735 EL3WINDOW(2);
1708 for (i = 0; i < 6; i++) 1736 for (i = 0; i < 6; i++)
1709 outb(dev->dev_addr[i], ioaddr + i); 1737 iowrite8(dev->dev_addr[i], ioaddr + i);
1710 for (; i < 12; i+=2) 1738 for (; i < 12; i+=2)
1711 outw(0, ioaddr + i); 1739 iowrite16(0, ioaddr + i);
1712 1740
1713 if (vp->cb_fn_base) { 1741 if (vp->cb_fn_base) {
1714 unsigned short n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010; 1742 unsigned short n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
1715 if (vp->drv_flags & INVERT_LED_PWR) 1743 if (vp->drv_flags & INVERT_LED_PWR)
1716 n |= 0x10; 1744 n |= 0x10;
1717 if (vp->drv_flags & INVERT_MII_PWR) 1745 if (vp->drv_flags & INVERT_MII_PWR)
1718 n |= 0x4000; 1746 n |= 0x4000;
1719 outw(n, ioaddr + Wn2_ResetOptions); 1747 iowrite16(n, ioaddr + Wn2_ResetOptions);
1720 } 1748 }
1721 1749
1722 if (dev->if_port == XCVR_10base2) 1750 if (dev->if_port == XCVR_10base2)
1723 /* Start the thinnet transceiver. We should really wait 50ms...*/ 1751 /* Start the thinnet transceiver. We should really wait 50ms...*/
1724 outw(StartCoax, ioaddr + EL3_CMD); 1752 iowrite16(StartCoax, ioaddr + EL3_CMD);
1725 if (dev->if_port != XCVR_NWAY) { 1753 if (dev->if_port != XCVR_NWAY) {
1726 EL3WINDOW(4); 1754 EL3WINDOW(4);
1727 outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) | 1755 iowrite16((ioread16(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
1728 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media); 1756 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
1729 } 1757 }
1730 1758
1731 /* Switch to the stats window, and clear all stats by reading. */ 1759 /* Switch to the stats window, and clear all stats by reading. */
1732 outw(StatsDisable, ioaddr + EL3_CMD); 1760 iowrite16(StatsDisable, ioaddr + EL3_CMD);
1733 EL3WINDOW(6); 1761 EL3WINDOW(6);
1734 for (i = 0; i < 10; i++) 1762 for (i = 0; i < 10; i++)
1735 inb(ioaddr + i); 1763 ioread8(ioaddr + i);
1736 inw(ioaddr + 10); 1764 ioread16(ioaddr + 10);
1737 inw(ioaddr + 12); 1765 ioread16(ioaddr + 12);
1738 /* New: On the Vortex we must also clear the BadSSD counter. */ 1766 /* New: On the Vortex we must also clear the BadSSD counter. */
1739 EL3WINDOW(4); 1767 EL3WINDOW(4);
1740 inb(ioaddr + 12); 1768 ioread8(ioaddr + 12);
1741 /* ..and on the Boomerang we enable the extra statistics bits. */ 1769 /* ..and on the Boomerang we enable the extra statistics bits. */
1742 outw(0x0040, ioaddr + Wn4_NetDiag); 1770 iowrite16(0x0040, ioaddr + Wn4_NetDiag);
1743 1771
1744 /* Switch to register set 7 for normal use. */ 1772 /* Switch to register set 7 for normal use. */
1745 EL3WINDOW(7); 1773 EL3WINDOW(7);
@@ -1747,30 +1775,30 @@ vortex_up(struct net_device *dev)
1747 if (vp->full_bus_master_rx) { /* Boomerang bus master. */ 1775 if (vp->full_bus_master_rx) { /* Boomerang bus master. */
1748 vp->cur_rx = vp->dirty_rx = 0; 1776 vp->cur_rx = vp->dirty_rx = 0;
1749 /* Initialize the RxEarly register as recommended. */ 1777 /* Initialize the RxEarly register as recommended. */
1750 outw(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD); 1778 iowrite16(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
1751 outl(0x0020, ioaddr + PktStatus); 1779 iowrite32(0x0020, ioaddr + PktStatus);
1752 outl(vp->rx_ring_dma, ioaddr + UpListPtr); 1780 iowrite32(vp->rx_ring_dma, ioaddr + UpListPtr);
1753 } 1781 }
1754 if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */ 1782 if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */
1755 vp->cur_tx = vp->dirty_tx = 0; 1783 vp->cur_tx = vp->dirty_tx = 0;
1756 if (vp->drv_flags & IS_BOOMERANG) 1784 if (vp->drv_flags & IS_BOOMERANG)
1757 outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */ 1785 iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
1758 /* Clear the Rx, Tx rings. */ 1786 /* Clear the Rx, Tx rings. */
1759 for (i = 0; i < RX_RING_SIZE; i++) /* AKPM: this is done in vortex_open, too */ 1787 for (i = 0; i < RX_RING_SIZE; i++) /* AKPM: this is done in vortex_open, too */
1760 vp->rx_ring[i].status = 0; 1788 vp->rx_ring[i].status = 0;
1761 for (i = 0; i < TX_RING_SIZE; i++) 1789 for (i = 0; i < TX_RING_SIZE; i++)
1762 vp->tx_skbuff[i] = NULL; 1790 vp->tx_skbuff[i] = NULL;
1763 outl(0, ioaddr + DownListPtr); 1791 iowrite32(0, ioaddr + DownListPtr);
1764 } 1792 }
1765 /* Set receiver mode: presumably accept b-case and phys addr only. */ 1793 /* Set receiver mode: presumably accept b-case and phys addr only. */
1766 set_rx_mode(dev); 1794 set_rx_mode(dev);
1767 /* enable 802.1q tagged frames */ 1795 /* enable 802.1q tagged frames */
1768 set_8021q_mode(dev, 1); 1796 set_8021q_mode(dev, 1);
1769 outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ 1797 iowrite16(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
1770 1798
1771// issue_and_wait(dev, SetTxStart|0x07ff); 1799// issue_and_wait(dev, SetTxStart|0x07ff);
1772 outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */ 1800 iowrite16(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
1773 outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */ 1801 iowrite16(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
1774 /* Allow status bits to be seen. */ 1802 /* Allow status bits to be seen. */
1775 vp->status_enable = SetStatusEnb | HostError|IntReq|StatsFull|TxComplete| 1803 vp->status_enable = SetStatusEnb | HostError|IntReq|StatsFull|TxComplete|
1776 (vp->full_bus_master_tx ? DownComplete : TxAvailable) | 1804 (vp->full_bus_master_tx ? DownComplete : TxAvailable) |
@@ -1780,13 +1808,13 @@ vortex_up(struct net_device *dev)
1780 (vp->full_bus_master_rx ? 0 : RxComplete) | 1808 (vp->full_bus_master_rx ? 0 : RxComplete) |
1781 StatsFull | HostError | TxComplete | IntReq 1809 StatsFull | HostError | TxComplete | IntReq
1782 | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete; 1810 | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete;
1783 outw(vp->status_enable, ioaddr + EL3_CMD); 1811 iowrite16(vp->status_enable, ioaddr + EL3_CMD);
1784 /* Ack all pending events, and set active indicator mask. */ 1812 /* Ack all pending events, and set active indicator mask. */
1785 outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq, 1813 iowrite16(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
1786 ioaddr + EL3_CMD); 1814 ioaddr + EL3_CMD);
1787 outw(vp->intr_enable, ioaddr + EL3_CMD); 1815 iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
1788 if (vp->cb_fn_base) /* The PCMCIA people are idiots. */ 1816 if (vp->cb_fn_base) /* The PCMCIA people are idiots. */
1789 writel(0x8000, vp->cb_fn_base + 4); 1817 iowrite32(0x8000, vp->cb_fn_base + 4);
1790 netif_start_queue (dev); 1818 netif_start_queue (dev);
1791} 1819}
1792 1820
@@ -1852,7 +1880,7 @@ vortex_timer(unsigned long data)
1852{ 1880{
1853 struct net_device *dev = (struct net_device *)data; 1881 struct net_device *dev = (struct net_device *)data;
1854 struct vortex_private *vp = netdev_priv(dev); 1882 struct vortex_private *vp = netdev_priv(dev);
1855 long ioaddr = dev->base_addr; 1883 void __iomem *ioaddr = vp->ioaddr;
1856 int next_tick = 60*HZ; 1884 int next_tick = 60*HZ;
1857 int ok = 0; 1885 int ok = 0;
1858 int media_status, mii_status, old_window; 1886 int media_status, mii_status, old_window;
@@ -1866,9 +1894,9 @@ vortex_timer(unsigned long data)
1866 if (vp->medialock) 1894 if (vp->medialock)
1867 goto leave_media_alone; 1895 goto leave_media_alone;
1868 disable_irq(dev->irq); 1896 disable_irq(dev->irq);
1869 old_window = inw(ioaddr + EL3_CMD) >> 13; 1897 old_window = ioread16(ioaddr + EL3_CMD) >> 13;
1870 EL3WINDOW(4); 1898 EL3WINDOW(4);
1871 media_status = inw(ioaddr + Wn4_Media); 1899 media_status = ioread16(ioaddr + Wn4_Media);
1872 switch (dev->if_port) { 1900 switch (dev->if_port) {
1873 case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx: 1901 case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx:
1874 if (media_status & Media_LnkBeat) { 1902 if (media_status & Media_LnkBeat) {
@@ -1888,14 +1916,17 @@ vortex_timer(unsigned long data)
1888 case XCVR_MII: case XCVR_NWAY: 1916 case XCVR_MII: case XCVR_NWAY:
1889 { 1917 {
1890 spin_lock_bh(&vp->lock); 1918 spin_lock_bh(&vp->lock);
1891 mii_status = mdio_read(dev, vp->phys[0], 1); 1919 mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
1892 mii_status = mdio_read(dev, vp->phys[0], 1); 1920 if (!(mii_status & BMSR_LSTATUS)) {
1921 /* Re-read to get actual link status */
1922 mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
1923 }
1893 ok = 1; 1924 ok = 1;
1894 if (vortex_debug > 2) 1925 if (vortex_debug > 2)
1895 printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n", 1926 printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n",
1896 dev->name, mii_status); 1927 dev->name, mii_status);
1897 if (mii_status & BMSR_LSTATUS) { 1928 if (mii_status & BMSR_LSTATUS) {
1898 int mii_reg5 = mdio_read(dev, vp->phys[0], 5); 1929 int mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
1899 if (! vp->force_fd && mii_reg5 != 0xffff) { 1930 if (! vp->force_fd && mii_reg5 != 0xffff) {
1900 int duplex; 1931 int duplex;
1901 1932
@@ -1909,7 +1940,7 @@ vortex_timer(unsigned long data)
1909 vp->phys[0], mii_reg5); 1940 vp->phys[0], mii_reg5);
1910 /* Set the full-duplex bit. */ 1941 /* Set the full-duplex bit. */
1911 EL3WINDOW(3); 1942 EL3WINDOW(3);
1912 outw( (vp->full_duplex ? 0x20 : 0) | 1943 iowrite16( (vp->full_duplex ? 0x20 : 0) |
1913 (vp->large_frames ? 0x40 : 0) | 1944 (vp->large_frames ? 0x40 : 0) |
1914 ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0), 1945 ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
1915 ioaddr + Wn3_MAC_Ctrl); 1946 ioaddr + Wn3_MAC_Ctrl);
@@ -1950,15 +1981,15 @@ vortex_timer(unsigned long data)
1950 dev->name, media_tbl[dev->if_port].name); 1981 dev->name, media_tbl[dev->if_port].name);
1951 next_tick = media_tbl[dev->if_port].wait; 1982 next_tick = media_tbl[dev->if_port].wait;
1952 } 1983 }
1953 outw((media_status & ~(Media_10TP|Media_SQE)) | 1984 iowrite16((media_status & ~(Media_10TP|Media_SQE)) |
1954 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media); 1985 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
1955 1986
1956 EL3WINDOW(3); 1987 EL3WINDOW(3);
1957 config = inl(ioaddr + Wn3_Config); 1988 config = ioread32(ioaddr + Wn3_Config);
1958 config = BFINS(config, dev->if_port, 20, 4); 1989 config = BFINS(config, dev->if_port, 20, 4);
1959 outl(config, ioaddr + Wn3_Config); 1990 iowrite32(config, ioaddr + Wn3_Config);
1960 1991
1961 outw(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax, 1992 iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
1962 ioaddr + EL3_CMD); 1993 ioaddr + EL3_CMD);
1963 if (vortex_debug > 1) 1994 if (vortex_debug > 1)
1964 printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config); 1995 printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
@@ -1974,29 +2005,29 @@ leave_media_alone:
1974 2005
1975 mod_timer(&vp->timer, RUN_AT(next_tick)); 2006 mod_timer(&vp->timer, RUN_AT(next_tick));
1976 if (vp->deferred) 2007 if (vp->deferred)
1977 outw(FakeIntr, ioaddr + EL3_CMD); 2008 iowrite16(FakeIntr, ioaddr + EL3_CMD);
1978 return; 2009 return;
1979} 2010}
1980 2011
1981static void vortex_tx_timeout(struct net_device *dev) 2012static void vortex_tx_timeout(struct net_device *dev)
1982{ 2013{
1983 struct vortex_private *vp = netdev_priv(dev); 2014 struct vortex_private *vp = netdev_priv(dev);
1984 long ioaddr = dev->base_addr; 2015 void __iomem *ioaddr = vp->ioaddr;
1985 2016
1986 printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n", 2017 printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
1987 dev->name, inb(ioaddr + TxStatus), 2018 dev->name, ioread8(ioaddr + TxStatus),
1988 inw(ioaddr + EL3_STATUS)); 2019 ioread16(ioaddr + EL3_STATUS));
1989 EL3WINDOW(4); 2020 EL3WINDOW(4);
1990 printk(KERN_ERR " diagnostics: net %04x media %04x dma %08x fifo %04x\n", 2021 printk(KERN_ERR " diagnostics: net %04x media %04x dma %08x fifo %04x\n",
1991 inw(ioaddr + Wn4_NetDiag), 2022 ioread16(ioaddr + Wn4_NetDiag),
1992 inw(ioaddr + Wn4_Media), 2023 ioread16(ioaddr + Wn4_Media),
1993 inl(ioaddr + PktStatus), 2024 ioread32(ioaddr + PktStatus),
1994 inw(ioaddr + Wn4_FIFODiag)); 2025 ioread16(ioaddr + Wn4_FIFODiag));
1995 /* Slight code bloat to be user friendly. */ 2026 /* Slight code bloat to be user friendly. */
1996 if ((inb(ioaddr + TxStatus) & 0x88) == 0x88) 2027 if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
1997 printk(KERN_ERR "%s: Transmitter encountered 16 collisions --" 2028 printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
1998 " network cable problem?\n", dev->name); 2029 " network cable problem?\n", dev->name);
1999 if (inw(ioaddr + EL3_STATUS) & IntLatch) { 2030 if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
2000 printk(KERN_ERR "%s: Interrupt posted but not delivered --" 2031 printk(KERN_ERR "%s: Interrupt posted but not delivered --"
2001 " IRQ blocked by another device?\n", dev->name); 2032 " IRQ blocked by another device?\n", dev->name);
2002 /* Bad idea here.. but we might as well handle a few events. */ 2033 /* Bad idea here.. but we might as well handle a few events. */
@@ -2022,21 +2053,21 @@ static void vortex_tx_timeout(struct net_device *dev)
2022 vp->stats.tx_errors++; 2053 vp->stats.tx_errors++;
2023 if (vp->full_bus_master_tx) { 2054 if (vp->full_bus_master_tx) {
2024 printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name); 2055 printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
2025 if (vp->cur_tx - vp->dirty_tx > 0 && inl(ioaddr + DownListPtr) == 0) 2056 if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0)
2026 outl(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc), 2057 iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
2027 ioaddr + DownListPtr); 2058 ioaddr + DownListPtr);
2028 if (vp->cur_tx - vp->dirty_tx < TX_RING_SIZE) 2059 if (vp->cur_tx - vp->dirty_tx < TX_RING_SIZE)
2029 netif_wake_queue (dev); 2060 netif_wake_queue (dev);
2030 if (vp->drv_flags & IS_BOOMERANG) 2061 if (vp->drv_flags & IS_BOOMERANG)
2031 outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); 2062 iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
2032 outw(DownUnstall, ioaddr + EL3_CMD); 2063 iowrite16(DownUnstall, ioaddr + EL3_CMD);
2033 } else { 2064 } else {
2034 vp->stats.tx_dropped++; 2065 vp->stats.tx_dropped++;
2035 netif_wake_queue(dev); 2066 netif_wake_queue(dev);
2036 } 2067 }
2037 2068
2038 /* Issue Tx Enable */ 2069 /* Issue Tx Enable */
2039 outw(TxEnable, ioaddr + EL3_CMD); 2070 iowrite16(TxEnable, ioaddr + EL3_CMD);
2040 dev->trans_start = jiffies; 2071 dev->trans_start = jiffies;
2041 2072
2042 /* Switch to register set 7 for normal use. */ 2073 /* Switch to register set 7 for normal use. */
@@ -2051,7 +2082,7 @@ static void
2051vortex_error(struct net_device *dev, int status) 2082vortex_error(struct net_device *dev, int status)
2052{ 2083{
2053 struct vortex_private *vp = netdev_priv(dev); 2084 struct vortex_private *vp = netdev_priv(dev);
2054 long ioaddr = dev->base_addr; 2085 void __iomem *ioaddr = vp->ioaddr;
2055 int do_tx_reset = 0, reset_mask = 0; 2086 int do_tx_reset = 0, reset_mask = 0;
2056 unsigned char tx_status = 0; 2087 unsigned char tx_status = 0;
2057 2088
@@ -2060,7 +2091,7 @@ vortex_error(struct net_device *dev, int status)
2060 } 2091 }
2061 2092
2062 if (status & TxComplete) { /* Really "TxError" for us. */ 2093 if (status & TxComplete) { /* Really "TxError" for us. */
2063 tx_status = inb(ioaddr + TxStatus); 2094 tx_status = ioread8(ioaddr + TxStatus);
2064 /* Presumably a tx-timeout. We must merely re-enable. */ 2095 /* Presumably a tx-timeout. We must merely re-enable. */
2065 if (vortex_debug > 2 2096 if (vortex_debug > 2
2066 || (tx_status != 0x88 && vortex_debug > 0)) { 2097 || (tx_status != 0x88 && vortex_debug > 0)) {
@@ -2074,20 +2105,20 @@ vortex_error(struct net_device *dev, int status)
2074 } 2105 }
2075 if (tx_status & 0x14) vp->stats.tx_fifo_errors++; 2106 if (tx_status & 0x14) vp->stats.tx_fifo_errors++;
2076 if (tx_status & 0x38) vp->stats.tx_aborted_errors++; 2107 if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
2077 outb(0, ioaddr + TxStatus); 2108 iowrite8(0, ioaddr + TxStatus);
2078 if (tx_status & 0x30) { /* txJabber or txUnderrun */ 2109 if (tx_status & 0x30) { /* txJabber or txUnderrun */
2079 do_tx_reset = 1; 2110 do_tx_reset = 1;
2080 } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */ 2111 } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */
2081 do_tx_reset = 1; 2112 do_tx_reset = 1;
2082 reset_mask = 0x0108; /* Reset interface logic, but not download logic */ 2113 reset_mask = 0x0108; /* Reset interface logic, but not download logic */
2083 } else { /* Merely re-enable the transmitter. */ 2114 } else { /* Merely re-enable the transmitter. */
2084 outw(TxEnable, ioaddr + EL3_CMD); 2115 iowrite16(TxEnable, ioaddr + EL3_CMD);
2085 } 2116 }
2086 } 2117 }
2087 2118
2088 if (status & RxEarly) { /* Rx early is unused. */ 2119 if (status & RxEarly) { /* Rx early is unused. */
2089 vortex_rx(dev); 2120 vortex_rx(dev);
2090 outw(AckIntr | RxEarly, ioaddr + EL3_CMD); 2121 iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD);
2091 } 2122 }
2092 if (status & StatsFull) { /* Empty statistics. */ 2123 if (status & StatsFull) { /* Empty statistics. */
2093 static int DoneDidThat; 2124 static int DoneDidThat;
@@ -2097,29 +2128,29 @@ vortex_error(struct net_device *dev, int status)
2097 /* HACK: Disable statistics as an interrupt source. */ 2128 /* HACK: Disable statistics as an interrupt source. */
2098 /* This occurs when we have the wrong media type! */ 2129 /* This occurs when we have the wrong media type! */
2099 if (DoneDidThat == 0 && 2130 if (DoneDidThat == 0 &&
2100 inw(ioaddr + EL3_STATUS) & StatsFull) { 2131 ioread16(ioaddr + EL3_STATUS) & StatsFull) {
2101 printk(KERN_WARNING "%s: Updating statistics failed, disabling " 2132 printk(KERN_WARNING "%s: Updating statistics failed, disabling "
2102 "stats as an interrupt source.\n", dev->name); 2133 "stats as an interrupt source.\n", dev->name);
2103 EL3WINDOW(5); 2134 EL3WINDOW(5);
2104 outw(SetIntrEnb | (inw(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD); 2135 iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
2105 vp->intr_enable &= ~StatsFull; 2136 vp->intr_enable &= ~StatsFull;
2106 EL3WINDOW(7); 2137 EL3WINDOW(7);
2107 DoneDidThat++; 2138 DoneDidThat++;
2108 } 2139 }
2109 } 2140 }
2110 if (status & IntReq) { /* Restore all interrupt sources. */ 2141 if (status & IntReq) { /* Restore all interrupt sources. */
2111 outw(vp->status_enable, ioaddr + EL3_CMD); 2142 iowrite16(vp->status_enable, ioaddr + EL3_CMD);
2112 outw(vp->intr_enable, ioaddr + EL3_CMD); 2143 iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
2113 } 2144 }
2114 if (status & HostError) { 2145 if (status & HostError) {
2115 u16 fifo_diag; 2146 u16 fifo_diag;
2116 EL3WINDOW(4); 2147 EL3WINDOW(4);
2117 fifo_diag = inw(ioaddr + Wn4_FIFODiag); 2148 fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
2118 printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n", 2149 printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
2119 dev->name, fifo_diag); 2150 dev->name, fifo_diag);
2120 /* Adapter failure requires Tx/Rx reset and reinit. */ 2151 /* Adapter failure requires Tx/Rx reset and reinit. */
2121 if (vp->full_bus_master_tx) { 2152 if (vp->full_bus_master_tx) {
2122 int bus_status = inl(ioaddr + PktStatus); 2153 int bus_status = ioread32(ioaddr + PktStatus);
2123 /* 0x80000000 PCI master abort. */ 2154 /* 0x80000000 PCI master abort. */
2124 /* 0x40000000 PCI target abort. */ 2155 /* 0x40000000 PCI target abort. */
2125 if (vortex_debug) 2156 if (vortex_debug)
@@ -2139,14 +2170,14 @@ vortex_error(struct net_device *dev, int status)
2139 set_rx_mode(dev); 2170 set_rx_mode(dev);
2140 /* enable 802.1q VLAN tagged frames */ 2171 /* enable 802.1q VLAN tagged frames */
2141 set_8021q_mode(dev, 1); 2172 set_8021q_mode(dev, 1);
2142 outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */ 2173 iowrite16(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
2143 outw(AckIntr | HostError, ioaddr + EL3_CMD); 2174 iowrite16(AckIntr | HostError, ioaddr + EL3_CMD);
2144 } 2175 }
2145 } 2176 }
2146 2177
2147 if (do_tx_reset) { 2178 if (do_tx_reset) {
2148 issue_and_wait(dev, TxReset|reset_mask); 2179 issue_and_wait(dev, TxReset|reset_mask);
2149 outw(TxEnable, ioaddr + EL3_CMD); 2180 iowrite16(TxEnable, ioaddr + EL3_CMD);
2150 if (!vp->full_bus_master_tx) 2181 if (!vp->full_bus_master_tx)
2151 netif_wake_queue(dev); 2182 netif_wake_queue(dev);
2152 } 2183 }
@@ -2156,29 +2187,29 @@ static int
2156vortex_start_xmit(struct sk_buff *skb, struct net_device *dev) 2187vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
2157{ 2188{
2158 struct vortex_private *vp = netdev_priv(dev); 2189 struct vortex_private *vp = netdev_priv(dev);
2159 long ioaddr = dev->base_addr; 2190 void __iomem *ioaddr = vp->ioaddr;
2160 2191
2161 /* Put out the doubleword header... */ 2192 /* Put out the doubleword header... */
2162 outl(skb->len, ioaddr + TX_FIFO); 2193 iowrite32(skb->len, ioaddr + TX_FIFO);
2163 if (vp->bus_master) { 2194 if (vp->bus_master) {
2164 /* Set the bus-master controller to transfer the packet. */ 2195 /* Set the bus-master controller to transfer the packet. */
2165 int len = (skb->len + 3) & ~3; 2196 int len = (skb->len + 3) & ~3;
2166 outl( vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE), 2197 iowrite32( vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
2167 ioaddr + Wn7_MasterAddr); 2198 ioaddr + Wn7_MasterAddr);
2168 outw(len, ioaddr + Wn7_MasterLen); 2199 iowrite16(len, ioaddr + Wn7_MasterLen);
2169 vp->tx_skb = skb; 2200 vp->tx_skb = skb;
2170 outw(StartDMADown, ioaddr + EL3_CMD); 2201 iowrite16(StartDMADown, ioaddr + EL3_CMD);
2171 /* netif_wake_queue() will be called at the DMADone interrupt. */ 2202 /* netif_wake_queue() will be called at the DMADone interrupt. */
2172 } else { 2203 } else {
2173 /* ... and the packet rounded to a doubleword. */ 2204 /* ... and the packet rounded to a doubleword. */
2174 outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); 2205 iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
2175 dev_kfree_skb (skb); 2206 dev_kfree_skb (skb);
2176 if (inw(ioaddr + TxFree) > 1536) { 2207 if (ioread16(ioaddr + TxFree) > 1536) {
2177 netif_start_queue (dev); /* AKPM: redundant? */ 2208 netif_start_queue (dev); /* AKPM: redundant? */
2178 } else { 2209 } else {
2179 /* Interrupt us when the FIFO has room for max-sized packet. */ 2210 /* Interrupt us when the FIFO has room for max-sized packet. */
2180 netif_stop_queue(dev); 2211 netif_stop_queue(dev);
2181 outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD); 2212 iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
2182 } 2213 }
2183 } 2214 }
2184 2215
@@ -2189,7 +2220,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
2189 int tx_status; 2220 int tx_status;
2190 int i = 32; 2221 int i = 32;
2191 2222
2192 while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) { 2223 while (--i > 0 && (tx_status = ioread8(ioaddr + TxStatus)) > 0) {
2193 if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */ 2224 if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
2194 if (vortex_debug > 2) 2225 if (vortex_debug > 2)
2195 printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n", 2226 printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
@@ -2199,9 +2230,9 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
2199 if (tx_status & 0x30) { 2230 if (tx_status & 0x30) {
2200 issue_and_wait(dev, TxReset); 2231 issue_and_wait(dev, TxReset);
2201 } 2232 }
2202 outw(TxEnable, ioaddr + EL3_CMD); 2233 iowrite16(TxEnable, ioaddr + EL3_CMD);
2203 } 2234 }
2204 outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */ 2235 iowrite8(0x00, ioaddr + TxStatus); /* Pop the status stack. */
2205 } 2236 }
2206 } 2237 }
2207 return 0; 2238 return 0;
@@ -2211,7 +2242,7 @@ static int
2211boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) 2242boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
2212{ 2243{
2213 struct vortex_private *vp = netdev_priv(dev); 2244 struct vortex_private *vp = netdev_priv(dev);
2214 long ioaddr = dev->base_addr; 2245 void __iomem *ioaddr = vp->ioaddr;
2215 /* Calculate the next Tx descriptor entry. */ 2246 /* Calculate the next Tx descriptor entry. */
2216 int entry = vp->cur_tx % TX_RING_SIZE; 2247 int entry = vp->cur_tx % TX_RING_SIZE;
2217 struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE]; 2248 struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
@@ -2275,8 +2306,8 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
2275 /* Wait for the stall to complete. */ 2306 /* Wait for the stall to complete. */
2276 issue_and_wait(dev, DownStall); 2307 issue_and_wait(dev, DownStall);
2277 prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc)); 2308 prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc));
2278 if (inl(ioaddr + DownListPtr) == 0) { 2309 if (ioread32(ioaddr + DownListPtr) == 0) {
2279 outl(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr); 2310 iowrite32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
2280 vp->queued_packet++; 2311 vp->queued_packet++;
2281 } 2312 }
2282 2313
@@ -2291,7 +2322,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
2291 prev_entry->status &= cpu_to_le32(~TxIntrUploaded); 2322 prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
2292#endif 2323#endif
2293 } 2324 }
2294 outw(DownUnstall, ioaddr + EL3_CMD); 2325 iowrite16(DownUnstall, ioaddr + EL3_CMD);
2295 spin_unlock_irqrestore(&vp->lock, flags); 2326 spin_unlock_irqrestore(&vp->lock, flags);
2296 dev->trans_start = jiffies; 2327 dev->trans_start = jiffies;
2297 return 0; 2328 return 0;
@@ -2310,15 +2341,15 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2310{ 2341{
2311 struct net_device *dev = dev_id; 2342 struct net_device *dev = dev_id;
2312 struct vortex_private *vp = netdev_priv(dev); 2343 struct vortex_private *vp = netdev_priv(dev);
2313 long ioaddr; 2344 void __iomem *ioaddr;
2314 int status; 2345 int status;
2315 int work_done = max_interrupt_work; 2346 int work_done = max_interrupt_work;
2316 int handled = 0; 2347 int handled = 0;
2317 2348
2318 ioaddr = dev->base_addr; 2349 ioaddr = vp->ioaddr;
2319 spin_lock(&vp->lock); 2350 spin_lock(&vp->lock);
2320 2351
2321 status = inw(ioaddr + EL3_STATUS); 2352 status = ioread16(ioaddr + EL3_STATUS);
2322 2353
2323 if (vortex_debug > 6) 2354 if (vortex_debug > 6)
2324 printk("vortex_interrupt(). status=0x%4x\n", status); 2355 printk("vortex_interrupt(). status=0x%4x\n", status);
@@ -2337,7 +2368,7 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2337 2368
2338 if (vortex_debug > 4) 2369 if (vortex_debug > 4)
2339 printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n", 2370 printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
2340 dev->name, status, inb(ioaddr + Timer)); 2371 dev->name, status, ioread8(ioaddr + Timer));
2341 2372
2342 do { 2373 do {
2343 if (vortex_debug > 5) 2374 if (vortex_debug > 5)
@@ -2350,16 +2381,16 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2350 if (vortex_debug > 5) 2381 if (vortex_debug > 5)
2351 printk(KERN_DEBUG " TX room bit was handled.\n"); 2382 printk(KERN_DEBUG " TX room bit was handled.\n");
2352 /* There's room in the FIFO for a full-sized packet. */ 2383 /* There's room in the FIFO for a full-sized packet. */
2353 outw(AckIntr | TxAvailable, ioaddr + EL3_CMD); 2384 iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
2354 netif_wake_queue (dev); 2385 netif_wake_queue (dev);
2355 } 2386 }
2356 2387
2357 if (status & DMADone) { 2388 if (status & DMADone) {
2358 if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) { 2389 if (ioread16(ioaddr + Wn7_MasterStatus) & 0x1000) {
2359 outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */ 2390 iowrite16(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
2360 pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE); 2391 pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
2361 dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */ 2392 dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
2362 if (inw(ioaddr + TxFree) > 1536) { 2393 if (ioread16(ioaddr + TxFree) > 1536) {
2363 /* 2394 /*
2364 * AKPM: FIXME: I don't think we need this. If the queue was stopped due to 2395 * AKPM: FIXME: I don't think we need this. If the queue was stopped due to
2365 * insufficient FIFO room, the TxAvailable test will succeed and call 2396 * insufficient FIFO room, the TxAvailable test will succeed and call
@@ -2367,7 +2398,7 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2367 */ 2398 */
2368 netif_wake_queue(dev); 2399 netif_wake_queue(dev);
2369 } else { /* Interrupt when FIFO has room for max-sized packet. */ 2400 } else { /* Interrupt when FIFO has room for max-sized packet. */
2370 outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD); 2401 iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
2371 netif_stop_queue(dev); 2402 netif_stop_queue(dev);
2372 } 2403 }
2373 } 2404 }
@@ -2385,17 +2416,17 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2385 /* Disable all pending interrupts. */ 2416 /* Disable all pending interrupts. */
2386 do { 2417 do {
2387 vp->deferred |= status; 2418 vp->deferred |= status;
2388 outw(SetStatusEnb | (~vp->deferred & vp->status_enable), 2419 iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
2389 ioaddr + EL3_CMD); 2420 ioaddr + EL3_CMD);
2390 outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD); 2421 iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
2391 } while ((status = inw(ioaddr + EL3_CMD)) & IntLatch); 2422 } while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
2392 /* The timer will reenable interrupts. */ 2423 /* The timer will reenable interrupts. */
2393 mod_timer(&vp->timer, jiffies + 1*HZ); 2424 mod_timer(&vp->timer, jiffies + 1*HZ);
2394 break; 2425 break;
2395 } 2426 }
2396 /* Acknowledge the IRQ. */ 2427 /* Acknowledge the IRQ. */
2397 outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); 2428 iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
2398 } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete)); 2429 } while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
2399 2430
2400 if (vortex_debug > 4) 2431 if (vortex_debug > 4)
2401 printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", 2432 printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2415,11 +2446,11 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2415{ 2446{
2416 struct net_device *dev = dev_id; 2447 struct net_device *dev = dev_id;
2417 struct vortex_private *vp = netdev_priv(dev); 2448 struct vortex_private *vp = netdev_priv(dev);
2418 long ioaddr; 2449 void __iomem *ioaddr;
2419 int status; 2450 int status;
2420 int work_done = max_interrupt_work; 2451 int work_done = max_interrupt_work;
2421 2452
2422 ioaddr = dev->base_addr; 2453 ioaddr = vp->ioaddr;
2423 2454
2424 /* 2455 /*
2425 * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout 2456 * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
@@ -2427,7 +2458,7 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2427 */ 2458 */
2428 spin_lock(&vp->lock); 2459 spin_lock(&vp->lock);
2429 2460
2430 status = inw(ioaddr + EL3_STATUS); 2461 status = ioread16(ioaddr + EL3_STATUS);
2431 2462
2432 if (vortex_debug > 6) 2463 if (vortex_debug > 6)
2433 printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status); 2464 printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
@@ -2448,13 +2479,13 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2448 2479
2449 if (vortex_debug > 4) 2480 if (vortex_debug > 4)
2450 printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n", 2481 printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
2451 dev->name, status, inb(ioaddr + Timer)); 2482 dev->name, status, ioread8(ioaddr + Timer));
2452 do { 2483 do {
2453 if (vortex_debug > 5) 2484 if (vortex_debug > 5)
2454 printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n", 2485 printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
2455 dev->name, status); 2486 dev->name, status);
2456 if (status & UpComplete) { 2487 if (status & UpComplete) {
2457 outw(AckIntr | UpComplete, ioaddr + EL3_CMD); 2488 iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
2458 if (vortex_debug > 5) 2489 if (vortex_debug > 5)
2459 printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n"); 2490 printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
2460 boomerang_rx(dev); 2491 boomerang_rx(dev);
@@ -2463,11 +2494,11 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2463 if (status & DownComplete) { 2494 if (status & DownComplete) {
2464 unsigned int dirty_tx = vp->dirty_tx; 2495 unsigned int dirty_tx = vp->dirty_tx;
2465 2496
2466 outw(AckIntr | DownComplete, ioaddr + EL3_CMD); 2497 iowrite16(AckIntr | DownComplete, ioaddr + EL3_CMD);
2467 while (vp->cur_tx - dirty_tx > 0) { 2498 while (vp->cur_tx - dirty_tx > 0) {
2468 int entry = dirty_tx % TX_RING_SIZE; 2499 int entry = dirty_tx % TX_RING_SIZE;
2469#if 1 /* AKPM: the latter is faster, but cyclone-only */ 2500#if 1 /* AKPM: the latter is faster, but cyclone-only */
2470 if (inl(ioaddr + DownListPtr) == 2501 if (ioread32(ioaddr + DownListPtr) ==
2471 vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc)) 2502 vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc))
2472 break; /* It still hasn't been processed. */ 2503 break; /* It still hasn't been processed. */
2473#else 2504#else
@@ -2514,20 +2545,20 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2514 /* Disable all pending interrupts. */ 2545 /* Disable all pending interrupts. */
2515 do { 2546 do {
2516 vp->deferred |= status; 2547 vp->deferred |= status;
2517 outw(SetStatusEnb | (~vp->deferred & vp->status_enable), 2548 iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
2518 ioaddr + EL3_CMD); 2549 ioaddr + EL3_CMD);
2519 outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD); 2550 iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
2520 } while ((status = inw(ioaddr + EL3_CMD)) & IntLatch); 2551 } while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
2521 /* The timer will reenable interrupts. */ 2552 /* The timer will reenable interrupts. */
2522 mod_timer(&vp->timer, jiffies + 1*HZ); 2553 mod_timer(&vp->timer, jiffies + 1*HZ);
2523 break; 2554 break;
2524 } 2555 }
2525 /* Acknowledge the IRQ. */ 2556 /* Acknowledge the IRQ. */
2526 outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); 2557 iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
2527 if (vp->cb_fn_base) /* The PCMCIA people are idiots. */ 2558 if (vp->cb_fn_base) /* The PCMCIA people are idiots. */
2528 writel(0x8000, vp->cb_fn_base + 4); 2559 iowrite32(0x8000, vp->cb_fn_base + 4);
2529 2560
2530 } while ((status = inw(ioaddr + EL3_STATUS)) & IntLatch); 2561 } while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
2531 2562
2532 if (vortex_debug > 4) 2563 if (vortex_debug > 4)
2533 printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", 2564 printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2540,16 +2571,16 @@ handler_exit:
2540static int vortex_rx(struct net_device *dev) 2571static int vortex_rx(struct net_device *dev)
2541{ 2572{
2542 struct vortex_private *vp = netdev_priv(dev); 2573 struct vortex_private *vp = netdev_priv(dev);
2543 long ioaddr = dev->base_addr; 2574 void __iomem *ioaddr = vp->ioaddr;
2544 int i; 2575 int i;
2545 short rx_status; 2576 short rx_status;
2546 2577
2547 if (vortex_debug > 5) 2578 if (vortex_debug > 5)
2548 printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n", 2579 printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
2549 inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus)); 2580 ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
2550 while ((rx_status = inw(ioaddr + RxStatus)) > 0) { 2581 while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
2551 if (rx_status & 0x4000) { /* Error, update stats. */ 2582 if (rx_status & 0x4000) { /* Error, update stats. */
2552 unsigned char rx_error = inb(ioaddr + RxErrors); 2583 unsigned char rx_error = ioread8(ioaddr + RxErrors);
2553 if (vortex_debug > 2) 2584 if (vortex_debug > 2)
2554 printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error); 2585 printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
2555 vp->stats.rx_errors++; 2586 vp->stats.rx_errors++;
@@ -2572,34 +2603,35 @@ static int vortex_rx(struct net_device *dev)
2572 skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ 2603 skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
2573 /* 'skb_put()' points to the start of sk_buff data area. */ 2604 /* 'skb_put()' points to the start of sk_buff data area. */
2574 if (vp->bus_master && 2605 if (vp->bus_master &&
2575 ! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) { 2606 ! (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)) {
2576 dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len), 2607 dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len),
2577 pkt_len, PCI_DMA_FROMDEVICE); 2608 pkt_len, PCI_DMA_FROMDEVICE);
2578 outl(dma, ioaddr + Wn7_MasterAddr); 2609 iowrite32(dma, ioaddr + Wn7_MasterAddr);
2579 outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen); 2610 iowrite16((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
2580 outw(StartDMAUp, ioaddr + EL3_CMD); 2611 iowrite16(StartDMAUp, ioaddr + EL3_CMD);
2581 while (inw(ioaddr + Wn7_MasterStatus) & 0x8000) 2612 while (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)
2582 ; 2613 ;
2583 pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE); 2614 pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);
2584 } else { 2615 } else {
2585 insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len), 2616 ioread32_rep(ioaddr + RX_FIFO,
2586 (pkt_len + 3) >> 2); 2617 skb_put(skb, pkt_len),
2618 (pkt_len + 3) >> 2);
2587 } 2619 }
2588 outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */ 2620 iowrite16(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
2589 skb->protocol = eth_type_trans(skb, dev); 2621 skb->protocol = eth_type_trans(skb, dev);
2590 netif_rx(skb); 2622 netif_rx(skb);
2591 dev->last_rx = jiffies; 2623 dev->last_rx = jiffies;
2592 vp->stats.rx_packets++; 2624 vp->stats.rx_packets++;
2593 /* Wait a limited time to go to next packet. */ 2625 /* Wait a limited time to go to next packet. */
2594 for (i = 200; i >= 0; i--) 2626 for (i = 200; i >= 0; i--)
2595 if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress)) 2627 if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
2596 break; 2628 break;
2597 continue; 2629 continue;
2598 } else if (vortex_debug > 0) 2630 } else if (vortex_debug > 0)
2599 printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of " 2631 printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
2600 "size %d.\n", dev->name, pkt_len); 2632 "size %d.\n", dev->name, pkt_len);
2633 vp->stats.rx_dropped++;
2601 } 2634 }
2602 vp->stats.rx_dropped++;
2603 issue_and_wait(dev, RxDiscard); 2635 issue_and_wait(dev, RxDiscard);
2604 } 2636 }
2605 2637
@@ -2611,12 +2643,12 @@ boomerang_rx(struct net_device *dev)
2611{ 2643{
2612 struct vortex_private *vp = netdev_priv(dev); 2644 struct vortex_private *vp = netdev_priv(dev);
2613 int entry = vp->cur_rx % RX_RING_SIZE; 2645 int entry = vp->cur_rx % RX_RING_SIZE;
2614 long ioaddr = dev->base_addr; 2646 void __iomem *ioaddr = vp->ioaddr;
2615 int rx_status; 2647 int rx_status;
2616 int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx; 2648 int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
2617 2649
2618 if (vortex_debug > 5) 2650 if (vortex_debug > 5)
2619 printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", inw(ioaddr+EL3_STATUS)); 2651 printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
2620 2652
2621 while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){ 2653 while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
2622 if (--rx_work_limit < 0) 2654 if (--rx_work_limit < 0)
@@ -2699,7 +2731,7 @@ boomerang_rx(struct net_device *dev)
2699 vp->rx_skbuff[entry] = skb; 2731 vp->rx_skbuff[entry] = skb;
2700 } 2732 }
2701 vp->rx_ring[entry].status = 0; /* Clear complete bit. */ 2733 vp->rx_ring[entry].status = 0; /* Clear complete bit. */
2702 outw(UpUnstall, ioaddr + EL3_CMD); 2734 iowrite16(UpUnstall, ioaddr + EL3_CMD);
2703 } 2735 }
2704 return 0; 2736 return 0;
2705} 2737}
@@ -2728,7 +2760,7 @@ static void
2728vortex_down(struct net_device *dev, int final_down) 2760vortex_down(struct net_device *dev, int final_down)
2729{ 2761{
2730 struct vortex_private *vp = netdev_priv(dev); 2762 struct vortex_private *vp = netdev_priv(dev);
2731 long ioaddr = dev->base_addr; 2763 void __iomem *ioaddr = vp->ioaddr;
2732 2764
2733 netif_stop_queue (dev); 2765 netif_stop_queue (dev);
2734 2766
@@ -2736,26 +2768,26 @@ vortex_down(struct net_device *dev, int final_down)
2736 del_timer_sync(&vp->timer); 2768 del_timer_sync(&vp->timer);
2737 2769
2738 /* Turn off statistics ASAP. We update vp->stats below. */ 2770 /* Turn off statistics ASAP. We update vp->stats below. */
2739 outw(StatsDisable, ioaddr + EL3_CMD); 2771 iowrite16(StatsDisable, ioaddr + EL3_CMD);
2740 2772
2741 /* Disable the receiver and transmitter. */ 2773 /* Disable the receiver and transmitter. */
2742 outw(RxDisable, ioaddr + EL3_CMD); 2774 iowrite16(RxDisable, ioaddr + EL3_CMD);
2743 outw(TxDisable, ioaddr + EL3_CMD); 2775 iowrite16(TxDisable, ioaddr + EL3_CMD);
2744 2776
2745 /* Disable receiving 802.1q tagged frames */ 2777 /* Disable receiving 802.1q tagged frames */
2746 set_8021q_mode(dev, 0); 2778 set_8021q_mode(dev, 0);
2747 2779
2748 if (dev->if_port == XCVR_10base2) 2780 if (dev->if_port == XCVR_10base2)
2749 /* Turn off thinnet power. Green! */ 2781 /* Turn off thinnet power. Green! */
2750 outw(StopCoax, ioaddr + EL3_CMD); 2782 iowrite16(StopCoax, ioaddr + EL3_CMD);
2751 2783
2752 outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD); 2784 iowrite16(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
2753 2785
2754 update_stats(ioaddr, dev); 2786 update_stats(ioaddr, dev);
2755 if (vp->full_bus_master_rx) 2787 if (vp->full_bus_master_rx)
2756 outl(0, ioaddr + UpListPtr); 2788 iowrite32(0, ioaddr + UpListPtr);
2757 if (vp->full_bus_master_tx) 2789 if (vp->full_bus_master_tx)
2758 outl(0, ioaddr + DownListPtr); 2790 iowrite32(0, ioaddr + DownListPtr);
2759 2791
2760 if (final_down && VORTEX_PCI(vp)) { 2792 if (final_down && VORTEX_PCI(vp)) {
2761 vp->pm_state_valid = 1; 2793 vp->pm_state_valid = 1;
@@ -2768,7 +2800,7 @@ static int
2768vortex_close(struct net_device *dev) 2800vortex_close(struct net_device *dev)
2769{ 2801{
2770 struct vortex_private *vp = netdev_priv(dev); 2802 struct vortex_private *vp = netdev_priv(dev);
2771 long ioaddr = dev->base_addr; 2803 void __iomem *ioaddr = vp->ioaddr;
2772 int i; 2804 int i;
2773 2805
2774 if (netif_device_present(dev)) 2806 if (netif_device_present(dev))
@@ -2776,17 +2808,18 @@ vortex_close(struct net_device *dev)
2776 2808
2777 if (vortex_debug > 1) { 2809 if (vortex_debug > 1) {
2778 printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n", 2810 printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
2779 dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TxStatus)); 2811 dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
2780 printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d" 2812 printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
2781 " tx_queued %d Rx pre-checksummed %d.\n", 2813 " tx_queued %d Rx pre-checksummed %d.\n",
2782 dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits); 2814 dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
2783 } 2815 }
2784 2816
2785#if DO_ZEROCOPY 2817#if DO_ZEROCOPY
2786 if ( vp->rx_csumhits && 2818 if (vp->rx_csumhits &&
2787 ((vp->drv_flags & HAS_HWCKSM) == 0) && 2819 (vp->drv_flags & HAS_HWCKSM) == 0 &&
2788 (hw_checksums[vp->card_idx] == -1)) { 2820 (vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
2789 printk(KERN_WARNING "%s supports hardware checksums, and we're not using them!\n", dev->name); 2821 printk(KERN_WARNING "%s supports hardware checksums, and we're "
2822 "not using them!\n", dev->name);
2790 } 2823 }
2791#endif 2824#endif
2792 2825
@@ -2830,18 +2863,18 @@ dump_tx_ring(struct net_device *dev)
2830{ 2863{
2831 if (vortex_debug > 0) { 2864 if (vortex_debug > 0) {
2832 struct vortex_private *vp = netdev_priv(dev); 2865 struct vortex_private *vp = netdev_priv(dev);
2833 long ioaddr = dev->base_addr; 2866 void __iomem *ioaddr = vp->ioaddr;
2834 2867
2835 if (vp->full_bus_master_tx) { 2868 if (vp->full_bus_master_tx) {
2836 int i; 2869 int i;
2837 int stalled = inl(ioaddr + PktStatus) & 0x04; /* Possible racy. But it's only debug stuff */ 2870 int stalled = ioread32(ioaddr + PktStatus) & 0x04; /* Possible racy. But it's only debug stuff */
2838 2871
2839 printk(KERN_ERR " Flags; bus-master %d, dirty %d(%d) current %d(%d)\n", 2872 printk(KERN_ERR " Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
2840 vp->full_bus_master_tx, 2873 vp->full_bus_master_tx,
2841 vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE, 2874 vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
2842 vp->cur_tx, vp->cur_tx % TX_RING_SIZE); 2875 vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
2843 printk(KERN_ERR " Transmit list %8.8x vs. %p.\n", 2876 printk(KERN_ERR " Transmit list %8.8x vs. %p.\n",
2844 inl(ioaddr + DownListPtr), 2877 ioread32(ioaddr + DownListPtr),
2845 &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]); 2878 &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
2846 issue_and_wait(dev, DownStall); 2879 issue_and_wait(dev, DownStall);
2847 for (i = 0; i < TX_RING_SIZE; i++) { 2880 for (i = 0; i < TX_RING_SIZE; i++) {
@@ -2855,7 +2888,7 @@ dump_tx_ring(struct net_device *dev)
2855 le32_to_cpu(vp->tx_ring[i].status)); 2888 le32_to_cpu(vp->tx_ring[i].status));
2856 } 2889 }
2857 if (!stalled) 2890 if (!stalled)
2858 outw(DownUnstall, ioaddr + EL3_CMD); 2891 iowrite16(DownUnstall, ioaddr + EL3_CMD);
2859 } 2892 }
2860 } 2893 }
2861} 2894}
@@ -2863,11 +2896,12 @@ dump_tx_ring(struct net_device *dev)
2863static struct net_device_stats *vortex_get_stats(struct net_device *dev) 2896static struct net_device_stats *vortex_get_stats(struct net_device *dev)
2864{ 2897{
2865 struct vortex_private *vp = netdev_priv(dev); 2898 struct vortex_private *vp = netdev_priv(dev);
2899 void __iomem *ioaddr = vp->ioaddr;
2866 unsigned long flags; 2900 unsigned long flags;
2867 2901
2868 if (netif_device_present(dev)) { /* AKPM: Used to be netif_running */ 2902 if (netif_device_present(dev)) { /* AKPM: Used to be netif_running */
2869 spin_lock_irqsave (&vp->lock, flags); 2903 spin_lock_irqsave (&vp->lock, flags);
2870 update_stats(dev->base_addr, dev); 2904 update_stats(ioaddr, dev);
2871 spin_unlock_irqrestore (&vp->lock, flags); 2905 spin_unlock_irqrestore (&vp->lock, flags);
2872 } 2906 }
2873 return &vp->stats; 2907 return &vp->stats;
@@ -2880,37 +2914,37 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev)
2880 table. This is done by checking that the ASM (!) code generated uses 2914 table. This is done by checking that the ASM (!) code generated uses
2881 atomic updates with '+='. 2915 atomic updates with '+='.
2882 */ 2916 */
2883static void update_stats(long ioaddr, struct net_device *dev) 2917static void update_stats(void __iomem *ioaddr, struct net_device *dev)
2884{ 2918{
2885 struct vortex_private *vp = netdev_priv(dev); 2919 struct vortex_private *vp = netdev_priv(dev);
2886 int old_window = inw(ioaddr + EL3_CMD); 2920 int old_window = ioread16(ioaddr + EL3_CMD);
2887 2921
2888 if (old_window == 0xffff) /* Chip suspended or ejected. */ 2922 if (old_window == 0xffff) /* Chip suspended or ejected. */
2889 return; 2923 return;
2890 /* Unlike the 3c5x9 we need not turn off stats updates while reading. */ 2924 /* Unlike the 3c5x9 we need not turn off stats updates while reading. */
2891 /* Switch to the stats window, and read everything. */ 2925 /* Switch to the stats window, and read everything. */
2892 EL3WINDOW(6); 2926 EL3WINDOW(6);
2893 vp->stats.tx_carrier_errors += inb(ioaddr + 0); 2927 vp->stats.tx_carrier_errors += ioread8(ioaddr + 0);
2894 vp->stats.tx_heartbeat_errors += inb(ioaddr + 1); 2928 vp->stats.tx_heartbeat_errors += ioread8(ioaddr + 1);
2895 vp->stats.collisions += inb(ioaddr + 3); 2929 vp->stats.collisions += ioread8(ioaddr + 3);
2896 vp->stats.tx_window_errors += inb(ioaddr + 4); 2930 vp->stats.tx_window_errors += ioread8(ioaddr + 4);
2897 vp->stats.rx_fifo_errors += inb(ioaddr + 5); 2931 vp->stats.rx_fifo_errors += ioread8(ioaddr + 5);
2898 vp->stats.tx_packets += inb(ioaddr + 6); 2932 vp->stats.tx_packets += ioread8(ioaddr + 6);
2899 vp->stats.tx_packets += (inb(ioaddr + 9)&0x30) << 4; 2933 vp->stats.tx_packets += (ioread8(ioaddr + 9)&0x30) << 4;
2900 /* Rx packets */ inb(ioaddr + 7); /* Must read to clear */ 2934 /* Rx packets */ ioread8(ioaddr + 7); /* Must read to clear */
2901 /* Don't bother with register 9, an extension of registers 6&7. 2935 /* Don't bother with register 9, an extension of registers 6&7.
2902 If we do use the 6&7 values the atomic update assumption above 2936 If we do use the 6&7 values the atomic update assumption above
2903 is invalid. */ 2937 is invalid. */
2904 vp->stats.rx_bytes += inw(ioaddr + 10); 2938 vp->stats.rx_bytes += ioread16(ioaddr + 10);
2905 vp->stats.tx_bytes += inw(ioaddr + 12); 2939 vp->stats.tx_bytes += ioread16(ioaddr + 12);
2906 /* Extra stats for get_ethtool_stats() */ 2940 /* Extra stats for get_ethtool_stats() */
2907 vp->xstats.tx_multiple_collisions += inb(ioaddr + 2); 2941 vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2);
2908 vp->xstats.tx_deferred += inb(ioaddr + 8); 2942 vp->xstats.tx_deferred += ioread8(ioaddr + 8);
2909 EL3WINDOW(4); 2943 EL3WINDOW(4);
2910 vp->xstats.rx_bad_ssd += inb(ioaddr + 12); 2944 vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12);
2911 2945
2912 { 2946 {
2913 u8 up = inb(ioaddr + 13); 2947 u8 up = ioread8(ioaddr + 13);
2914 vp->stats.rx_bytes += (up & 0x0f) << 16; 2948 vp->stats.rx_bytes += (up & 0x0f) << 16;
2915 vp->stats.tx_bytes += (up & 0xf0) << 12; 2949 vp->stats.tx_bytes += (up & 0xf0) << 12;
2916 } 2950 }
@@ -2922,7 +2956,7 @@ static void update_stats(long ioaddr, struct net_device *dev)
2922static int vortex_nway_reset(struct net_device *dev) 2956static int vortex_nway_reset(struct net_device *dev)
2923{ 2957{
2924 struct vortex_private *vp = netdev_priv(dev); 2958 struct vortex_private *vp = netdev_priv(dev);
2925 long ioaddr = dev->base_addr; 2959 void __iomem *ioaddr = vp->ioaddr;
2926 unsigned long flags; 2960 unsigned long flags;
2927 int rc; 2961 int rc;
2928 2962
@@ -2936,7 +2970,7 @@ static int vortex_nway_reset(struct net_device *dev)
2936static u32 vortex_get_link(struct net_device *dev) 2970static u32 vortex_get_link(struct net_device *dev)
2937{ 2971{
2938 struct vortex_private *vp = netdev_priv(dev); 2972 struct vortex_private *vp = netdev_priv(dev);
2939 long ioaddr = dev->base_addr; 2973 void __iomem *ioaddr = vp->ioaddr;
2940 unsigned long flags; 2974 unsigned long flags;
2941 int rc; 2975 int rc;
2942 2976
@@ -2950,7 +2984,7 @@ static u32 vortex_get_link(struct net_device *dev)
2950static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 2984static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
2951{ 2985{
2952 struct vortex_private *vp = netdev_priv(dev); 2986 struct vortex_private *vp = netdev_priv(dev);
2953 long ioaddr = dev->base_addr; 2987 void __iomem *ioaddr = vp->ioaddr;
2954 unsigned long flags; 2988 unsigned long flags;
2955 int rc; 2989 int rc;
2956 2990
@@ -2964,7 +2998,7 @@ static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
2964static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 2998static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
2965{ 2999{
2966 struct vortex_private *vp = netdev_priv(dev); 3000 struct vortex_private *vp = netdev_priv(dev);
2967 long ioaddr = dev->base_addr; 3001 void __iomem *ioaddr = vp->ioaddr;
2968 unsigned long flags; 3002 unsigned long flags;
2969 int rc; 3003 int rc;
2970 3004
@@ -2994,10 +3028,11 @@ static void vortex_get_ethtool_stats(struct net_device *dev,
2994 struct ethtool_stats *stats, u64 *data) 3028 struct ethtool_stats *stats, u64 *data)
2995{ 3029{
2996 struct vortex_private *vp = netdev_priv(dev); 3030 struct vortex_private *vp = netdev_priv(dev);
3031 void __iomem *ioaddr = vp->ioaddr;
2997 unsigned long flags; 3032 unsigned long flags;
2998 3033
2999 spin_lock_irqsave(&vp->lock, flags); 3034 spin_lock_irqsave(&vp->lock, flags);
3000 update_stats(dev->base_addr, dev); 3035 update_stats(ioaddr, dev);
3001 spin_unlock_irqrestore(&vp->lock, flags); 3036 spin_unlock_irqrestore(&vp->lock, flags);
3002 3037
3003 data[0] = vp->xstats.tx_deferred; 3038 data[0] = vp->xstats.tx_deferred;
@@ -3047,6 +3082,7 @@ static struct ethtool_ops vortex_ethtool_ops = {
3047 .set_settings = vortex_set_settings, 3082 .set_settings = vortex_set_settings,
3048 .get_link = vortex_get_link, 3083 .get_link = vortex_get_link,
3049 .nway_reset = vortex_nway_reset, 3084 .nway_reset = vortex_nway_reset,
3085 .get_perm_addr = ethtool_op_get_perm_addr,
3050}; 3086};
3051 3087
3052#ifdef CONFIG_PCI 3088#ifdef CONFIG_PCI
@@ -3057,7 +3093,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3057{ 3093{
3058 int err; 3094 int err;
3059 struct vortex_private *vp = netdev_priv(dev); 3095 struct vortex_private *vp = netdev_priv(dev);
3060 long ioaddr = dev->base_addr; 3096 void __iomem *ioaddr = vp->ioaddr;
3061 unsigned long flags; 3097 unsigned long flags;
3062 int state = 0; 3098 int state = 0;
3063 3099
@@ -3085,7 +3121,8 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
3085 the chip has a very clean way to set the mode, unlike many others. */ 3121 the chip has a very clean way to set the mode, unlike many others. */
3086static void set_rx_mode(struct net_device *dev) 3122static void set_rx_mode(struct net_device *dev)
3087{ 3123{
3088 long ioaddr = dev->base_addr; 3124 struct vortex_private *vp = netdev_priv(dev);
3125 void __iomem *ioaddr = vp->ioaddr;
3089 int new_mode; 3126 int new_mode;
3090 3127
3091 if (dev->flags & IFF_PROMISC) { 3128 if (dev->flags & IFF_PROMISC) {
@@ -3097,7 +3134,7 @@ static void set_rx_mode(struct net_device *dev)
3097 } else 3134 } else
3098 new_mode = SetRxFilter | RxStation | RxBroadcast; 3135 new_mode = SetRxFilter | RxStation | RxBroadcast;
3099 3136
3100 outw(new_mode, ioaddr + EL3_CMD); 3137 iowrite16(new_mode, ioaddr + EL3_CMD);
3101} 3138}
3102 3139
3103#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 3140#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -3111,8 +3148,8 @@ static void set_rx_mode(struct net_device *dev)
3111static void set_8021q_mode(struct net_device *dev, int enable) 3148static void set_8021q_mode(struct net_device *dev, int enable)
3112{ 3149{
3113 struct vortex_private *vp = netdev_priv(dev); 3150 struct vortex_private *vp = netdev_priv(dev);
3114 long ioaddr = dev->base_addr; 3151 void __iomem *ioaddr = vp->ioaddr;
3115 int old_window = inw(ioaddr + EL3_CMD); 3152 int old_window = ioread16(ioaddr + EL3_CMD);
3116 int mac_ctrl; 3153 int mac_ctrl;
3117 3154
3118 if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) { 3155 if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) {
@@ -3124,24 +3161,24 @@ static void set_8021q_mode(struct net_device *dev, int enable)
3124 max_pkt_size += 4; /* 802.1Q VLAN tag */ 3161 max_pkt_size += 4; /* 802.1Q VLAN tag */
3125 3162
3126 EL3WINDOW(3); 3163 EL3WINDOW(3);
3127 outw(max_pkt_size, ioaddr+Wn3_MaxPktSize); 3164 iowrite16(max_pkt_size, ioaddr+Wn3_MaxPktSize);
3128 3165
3129 /* set VlanEtherType to let the hardware checksumming 3166 /* set VlanEtherType to let the hardware checksumming
3130 treat tagged frames correctly */ 3167 treat tagged frames correctly */
3131 EL3WINDOW(7); 3168 EL3WINDOW(7);
3132 outw(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType); 3169 iowrite16(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
3133 } else { 3170 } else {
3134 /* on older cards we have to enable large frames */ 3171 /* on older cards we have to enable large frames */
3135 3172
3136 vp->large_frames = dev->mtu > 1500 || enable; 3173 vp->large_frames = dev->mtu > 1500 || enable;
3137 3174
3138 EL3WINDOW(3); 3175 EL3WINDOW(3);
3139 mac_ctrl = inw(ioaddr+Wn3_MAC_Ctrl); 3176 mac_ctrl = ioread16(ioaddr+Wn3_MAC_Ctrl);
3140 if (vp->large_frames) 3177 if (vp->large_frames)
3141 mac_ctrl |= 0x40; 3178 mac_ctrl |= 0x40;
3142 else 3179 else
3143 mac_ctrl &= ~0x40; 3180 mac_ctrl &= ~0x40;
3144 outw(mac_ctrl, ioaddr+Wn3_MAC_Ctrl); 3181 iowrite16(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
3145 } 3182 }
3146 3183
3147 EL3WINDOW(old_window); 3184 EL3WINDOW(old_window);
@@ -3163,7 +3200,7 @@ static void set_8021q_mode(struct net_device *dev, int enable)
3163/* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually 3200/* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
3164 met by back-to-back PCI I/O cycles, but we insert a delay to avoid 3201 met by back-to-back PCI I/O cycles, but we insert a delay to avoid
3165 "overclocking" issues. */ 3202 "overclocking" issues. */
3166#define mdio_delay() inl(mdio_addr) 3203#define mdio_delay() ioread32(mdio_addr)
3167 3204
3168#define MDIO_SHIFT_CLK 0x01 3205#define MDIO_SHIFT_CLK 0x01
3169#define MDIO_DIR_WRITE 0x04 3206#define MDIO_DIR_WRITE 0x04
@@ -3174,15 +3211,15 @@ static void set_8021q_mode(struct net_device *dev, int enable)
3174 3211
3175/* Generate the preamble required for initial synchronization and 3212/* Generate the preamble required for initial synchronization and
3176 a few older transceivers. */ 3213 a few older transceivers. */
3177static void mdio_sync(long ioaddr, int bits) 3214static void mdio_sync(void __iomem *ioaddr, int bits)
3178{ 3215{
3179 long mdio_addr = ioaddr + Wn4_PhysicalMgmt; 3216 void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
3180 3217
3181 /* Establish sync by sending at least 32 logic ones. */ 3218 /* Establish sync by sending at least 32 logic ones. */
3182 while (-- bits >= 0) { 3219 while (-- bits >= 0) {
3183 outw(MDIO_DATA_WRITE1, mdio_addr); 3220 iowrite16(MDIO_DATA_WRITE1, mdio_addr);
3184 mdio_delay(); 3221 mdio_delay();
3185 outw(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr); 3222 iowrite16(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
3186 mdio_delay(); 3223 mdio_delay();
3187 } 3224 }
3188} 3225}
@@ -3190,10 +3227,11 @@ static void mdio_sync(long ioaddr, int bits)
3190static int mdio_read(struct net_device *dev, int phy_id, int location) 3227static int mdio_read(struct net_device *dev, int phy_id, int location)
3191{ 3228{
3192 int i; 3229 int i;
3193 long ioaddr = dev->base_addr; 3230 struct vortex_private *vp = netdev_priv(dev);
3231 void __iomem *ioaddr = vp->ioaddr;
3194 int read_cmd = (0xf6 << 10) | (phy_id << 5) | location; 3232 int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
3195 unsigned int retval = 0; 3233 unsigned int retval = 0;
3196 long mdio_addr = ioaddr + Wn4_PhysicalMgmt; 3234 void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
3197 3235
3198 if (mii_preamble_required) 3236 if (mii_preamble_required)
3199 mdio_sync(ioaddr, 32); 3237 mdio_sync(ioaddr, 32);
@@ -3201,17 +3239,17 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
3201 /* Shift the read command bits out. */ 3239 /* Shift the read command bits out. */
3202 for (i = 14; i >= 0; i--) { 3240 for (i = 14; i >= 0; i--) {
3203 int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; 3241 int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
3204 outw(dataval, mdio_addr); 3242 iowrite16(dataval, mdio_addr);
3205 mdio_delay(); 3243 mdio_delay();
3206 outw(dataval | MDIO_SHIFT_CLK, mdio_addr); 3244 iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
3207 mdio_delay(); 3245 mdio_delay();
3208 } 3246 }
3209 /* Read the two transition, 16 data, and wire-idle bits. */ 3247 /* Read the two transition, 16 data, and wire-idle bits. */
3210 for (i = 19; i > 0; i--) { 3248 for (i = 19; i > 0; i--) {
3211 outw(MDIO_ENB_IN, mdio_addr); 3249 iowrite16(MDIO_ENB_IN, mdio_addr);
3212 mdio_delay(); 3250 mdio_delay();
3213 retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0); 3251 retval = (retval << 1) | ((ioread16(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
3214 outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); 3252 iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
3215 mdio_delay(); 3253 mdio_delay();
3216 } 3254 }
3217 return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff; 3255 return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
@@ -3219,9 +3257,10 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
3219 3257
3220static void mdio_write(struct net_device *dev, int phy_id, int location, int value) 3258static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
3221{ 3259{
3222 long ioaddr = dev->base_addr; 3260 struct vortex_private *vp = netdev_priv(dev);
3261 void __iomem *ioaddr = vp->ioaddr;
3223 int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value; 3262 int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
3224 long mdio_addr = ioaddr + Wn4_PhysicalMgmt; 3263 void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
3225 int i; 3264 int i;
3226 3265
3227 if (mii_preamble_required) 3266 if (mii_preamble_required)
@@ -3230,16 +3269,16 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
3230 /* Shift the command bits out. */ 3269 /* Shift the command bits out. */
3231 for (i = 31; i >= 0; i--) { 3270 for (i = 31; i >= 0; i--) {
3232 int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; 3271 int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
3233 outw(dataval, mdio_addr); 3272 iowrite16(dataval, mdio_addr);
3234 mdio_delay(); 3273 mdio_delay();
3235 outw(dataval | MDIO_SHIFT_CLK, mdio_addr); 3274 iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
3236 mdio_delay(); 3275 mdio_delay();
3237 } 3276 }
3238 /* Leave the interface idle. */ 3277 /* Leave the interface idle. */
3239 for (i = 1; i >= 0; i--) { 3278 for (i = 1; i >= 0; i--) {
3240 outw(MDIO_ENB_IN, mdio_addr); 3279 iowrite16(MDIO_ENB_IN, mdio_addr);
3241 mdio_delay(); 3280 mdio_delay();
3242 outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr); 3281 iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
3243 mdio_delay(); 3282 mdio_delay();
3244 } 3283 }
3245 return; 3284 return;
@@ -3250,15 +3289,15 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
3250static void acpi_set_WOL(struct net_device *dev) 3289static void acpi_set_WOL(struct net_device *dev)
3251{ 3290{
3252 struct vortex_private *vp = netdev_priv(dev); 3291 struct vortex_private *vp = netdev_priv(dev);
3253 long ioaddr = dev->base_addr; 3292 void __iomem *ioaddr = vp->ioaddr;
3254 3293
3255 if (vp->enable_wol) { 3294 if (vp->enable_wol) {
3256 /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */ 3295 /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
3257 EL3WINDOW(7); 3296 EL3WINDOW(7);
3258 outw(2, ioaddr + 0x0c); 3297 iowrite16(2, ioaddr + 0x0c);
3259 /* The RxFilter must accept the WOL frames. */ 3298 /* The RxFilter must accept the WOL frames. */
3260 outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD); 3299 iowrite16(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
3261 outw(RxEnable, ioaddr + EL3_CMD); 3300 iowrite16(RxEnable, ioaddr + EL3_CMD);
3262 3301
3263 pci_enable_wake(VORTEX_PCI(vp), 0, 1); 3302 pci_enable_wake(VORTEX_PCI(vp), 0, 1);
3264 3303
@@ -3280,10 +3319,9 @@ static void __devexit vortex_remove_one (struct pci_dev *pdev)
3280 3319
3281 vp = netdev_priv(dev); 3320 vp = netdev_priv(dev);
3282 3321
3283 /* AKPM: FIXME: we should have 3322 if (vp->cb_fn_base)
3284 * if (vp->cb_fn_base) iounmap(vp->cb_fn_base); 3323 pci_iounmap(VORTEX_PCI(vp), vp->cb_fn_base);
3285 * here 3324
3286 */
3287 unregister_netdev(dev); 3325 unregister_netdev(dev);
3288 3326
3289 if (VORTEX_PCI(vp)) { 3327 if (VORTEX_PCI(vp)) {
@@ -3293,8 +3331,10 @@ static void __devexit vortex_remove_one (struct pci_dev *pdev)
3293 pci_disable_device(VORTEX_PCI(vp)); 3331 pci_disable_device(VORTEX_PCI(vp));
3294 } 3332 }
3295 /* Should really use issue_and_wait() here */ 3333 /* Should really use issue_and_wait() here */
3296 outw(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14), 3334 iowrite16(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
3297 dev->base_addr + EL3_CMD); 3335 vp->ioaddr + EL3_CMD);
3336
3337 pci_iounmap(VORTEX_PCI(vp), vp->ioaddr);
3298 3338
3299 pci_free_consistent(pdev, 3339 pci_free_consistent(pdev,
3300 sizeof(struct boom_rx_desc) * RX_RING_SIZE 3340 sizeof(struct boom_rx_desc) * RX_RING_SIZE
@@ -3342,7 +3382,7 @@ static int __init vortex_init (void)
3342static void __exit vortex_eisa_cleanup (void) 3382static void __exit vortex_eisa_cleanup (void)
3343{ 3383{
3344 struct vortex_private *vp; 3384 struct vortex_private *vp;
3345 long ioaddr; 3385 void __iomem *ioaddr;
3346 3386
3347#ifdef CONFIG_EISA 3387#ifdef CONFIG_EISA
3348 /* Take care of the EISA devices */ 3388 /* Take care of the EISA devices */
@@ -3351,11 +3391,13 @@ static void __exit vortex_eisa_cleanup (void)
3351 3391
3352 if (compaq_net_device) { 3392 if (compaq_net_device) {
3353 vp = compaq_net_device->priv; 3393 vp = compaq_net_device->priv;
3354 ioaddr = compaq_net_device->base_addr; 3394 ioaddr = ioport_map(compaq_net_device->base_addr,
3395 VORTEX_TOTAL_SIZE);
3355 3396
3356 unregister_netdev (compaq_net_device); 3397 unregister_netdev (compaq_net_device);
3357 outw (TotalReset, ioaddr + EL3_CMD); 3398 iowrite16 (TotalReset, ioaddr + EL3_CMD);
3358 release_region (ioaddr, VORTEX_TOTAL_SIZE); 3399 release_region(compaq_net_device->base_addr,
3400 VORTEX_TOTAL_SIZE);
3359 3401
3360 free_netdev (compaq_net_device); 3402 free_netdev (compaq_net_device);
3361 } 3403 }
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index e2d5b77764a2..1579041f73fc 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -447,7 +447,7 @@ config NET_SB1250_MAC
447 447
448config SGI_IOC3_ETH 448config SGI_IOC3_ETH
449 bool "SGI IOC3 Ethernet" 449 bool "SGI IOC3 Ethernet"
450 depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN 450 depends on NET_ETHERNET && PCI && SGI_IP27
451 select CRC32 451 select CRC32
452 select MII 452 select MII
453 help 453 help
@@ -2541,6 +2541,19 @@ config PPP_BSDCOMP
2541 module; it is called bsd_comp and will show up in the directory 2541 module; it is called bsd_comp and will show up in the directory
2542 modules once you have said "make modules". If unsure, say N. 2542 modules once you have said "make modules". If unsure, say N.
2543 2543
2544config PPP_MPPE
2545 tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
2546 depends on PPP && EXPERIMENTAL
2547 select CRYPTO
2548 select CRYPTO_SHA1
2549 select CRYPTO_ARC4
2550 ---help---
2551 Support for the MPPE Encryption protocol, as employed by the
2552 Microsoft Point-to-Point Tunneling Protocol.
2553
2554 See http://pptpclient.sourceforge.net/ for information on
2555 configuring PPTP clients and servers to utilize this method.
2556
2544config PPPOE 2557config PPPOE
2545 tristate "PPP over Ethernet (EXPERIMENTAL)" 2558 tristate "PPP over Ethernet (EXPERIMENTAL)"
2546 depends on EXPERIMENTAL && PPP 2559 depends on EXPERIMENTAL && PPP
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 5dccac434d48..27822a2f0683 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -113,6 +113,7 @@ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
113obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o 113obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
114obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o 114obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
115obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o 115obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
116obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o
116obj-$(CONFIG_PPPOE) += pppox.o pppoe.o 117obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
117 118
118obj-$(CONFIG_SLIP) += slip.o 119obj-$(CONFIG_SLIP) += slip.o
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 0ee3e27969c6..c53848f787eb 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -18,7 +18,6 @@
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/version.h>
22#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
23 22
24#include <asm/uaccess.h> 23#include <asm/uaccess.h>
@@ -29,8 +28,8 @@
29 28
30#define DRV_MODULE_NAME "b44" 29#define DRV_MODULE_NAME "b44"
31#define PFX DRV_MODULE_NAME ": " 30#define PFX DRV_MODULE_NAME ": "
32#define DRV_MODULE_VERSION "0.95" 31#define DRV_MODULE_VERSION "0.96"
33#define DRV_MODULE_RELDATE "Aug 3, 2004" 32#define DRV_MODULE_RELDATE "Nov 8, 2005"
34 33
35#define B44_DEF_MSG_ENABLE \ 34#define B44_DEF_MSG_ENABLE \
36 (NETIF_MSG_DRV | \ 35 (NETIF_MSG_DRV | \
@@ -102,14 +101,16 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
102static void b44_halt(struct b44 *); 101static void b44_halt(struct b44 *);
103static void b44_init_rings(struct b44 *); 102static void b44_init_rings(struct b44 *);
104static void b44_init_hw(struct b44 *); 103static void b44_init_hw(struct b44 *);
105static int b44_poll(struct net_device *dev, int *budget);
106#ifdef CONFIG_NET_POLL_CONTROLLER
107static void b44_poll_controller(struct net_device *dev);
108#endif
109 104
110static int dma_desc_align_mask; 105static int dma_desc_align_mask;
111static int dma_desc_sync_size; 106static int dma_desc_sync_size;
112 107
108static const char b44_gstrings[][ETH_GSTRING_LEN] = {
109#define _B44(x...) # x,
110B44_STAT_REG_DECLARE
111#undef _B44
112};
113
113static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev, 114static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
114 dma_addr_t dma_base, 115 dma_addr_t dma_base,
115 unsigned long offset, 116 unsigned long offset,
@@ -502,7 +503,10 @@ static void b44_stats_update(struct b44 *bp)
502 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { 503 for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) {
503 *val++ += br32(bp, reg); 504 *val++ += br32(bp, reg);
504 } 505 }
505 val = &bp->hw_stats.rx_good_octets; 506
507 /* Pad */
508 reg += 8*4UL;
509
506 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { 510 for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) {
507 *val++ += br32(bp, reg); 511 *val++ += br32(bp, reg);
508 } 512 }
@@ -653,7 +657,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
653 657
654 /* Hardware bug work-around, the chip is unable to do PCI DMA 658 /* Hardware bug work-around, the chip is unable to do PCI DMA
655 to/from anything above 1GB :-( */ 659 to/from anything above 1GB :-( */
656 if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { 660 if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
657 /* Sigh... */ 661 /* Sigh... */
658 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); 662 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
659 dev_kfree_skb_any(skb); 663 dev_kfree_skb_any(skb);
@@ -663,7 +667,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
663 mapping = pci_map_single(bp->pdev, skb->data, 667 mapping = pci_map_single(bp->pdev, skb->data,
664 RX_PKT_BUF_SZ, 668 RX_PKT_BUF_SZ,
665 PCI_DMA_FROMDEVICE); 669 PCI_DMA_FROMDEVICE);
666 if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { 670 if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
667 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); 671 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
668 dev_kfree_skb_any(skb); 672 dev_kfree_skb_any(skb);
669 return -ENOMEM; 673 return -ENOMEM;
@@ -890,11 +894,10 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
890{ 894{
891 struct net_device *dev = dev_id; 895 struct net_device *dev = dev_id;
892 struct b44 *bp = netdev_priv(dev); 896 struct b44 *bp = netdev_priv(dev);
893 unsigned long flags;
894 u32 istat, imask; 897 u32 istat, imask;
895 int handled = 0; 898 int handled = 0;
896 899
897 spin_lock_irqsave(&bp->lock, flags); 900 spin_lock(&bp->lock);
898 901
899 istat = br32(bp, B44_ISTAT); 902 istat = br32(bp, B44_ISTAT);
900 imask = br32(bp, B44_IMASK); 903 imask = br32(bp, B44_IMASK);
@@ -905,6 +908,12 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
905 istat &= imask; 908 istat &= imask;
906 if (istat) { 909 if (istat) {
907 handled = 1; 910 handled = 1;
911
912 if (unlikely(!netif_running(dev))) {
913 printk(KERN_INFO "%s: late interrupt.\n", dev->name);
914 goto irq_ack;
915 }
916
908 if (netif_rx_schedule_prep(dev)) { 917 if (netif_rx_schedule_prep(dev)) {
909 /* NOTE: These writes are posted by the readback of 918 /* NOTE: These writes are posted by the readback of
910 * the ISTAT register below. 919 * the ISTAT register below.
@@ -917,10 +926,11 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs)
917 dev->name); 926 dev->name);
918 } 927 }
919 928
929irq_ack:
920 bw32(bp, B44_ISTAT, istat); 930 bw32(bp, B44_ISTAT, istat);
921 br32(bp, B44_ISTAT); 931 br32(bp, B44_ISTAT);
922 } 932 }
923 spin_unlock_irqrestore(&bp->lock, flags); 933 spin_unlock(&bp->lock);
924 return IRQ_RETVAL(handled); 934 return IRQ_RETVAL(handled);
925} 935}
926 936
@@ -948,6 +958,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
948{ 958{
949 struct b44 *bp = netdev_priv(dev); 959 struct b44 *bp = netdev_priv(dev);
950 struct sk_buff *bounce_skb; 960 struct sk_buff *bounce_skb;
961 int rc = NETDEV_TX_OK;
951 dma_addr_t mapping; 962 dma_addr_t mapping;
952 u32 len, entry, ctrl; 963 u32 len, entry, ctrl;
953 964
@@ -957,29 +968,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
957 /* This is a hard error, log it. */ 968 /* This is a hard error, log it. */
958 if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { 969 if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
959 netif_stop_queue(dev); 970 netif_stop_queue(dev);
960 spin_unlock_irq(&bp->lock);
961 printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", 971 printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
962 dev->name); 972 dev->name);
963 return 1; 973 goto err_out;
964 } 974 }
965 975
966 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); 976 mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
967 if(mapping+len > B44_DMA_MASK) { 977 if (mapping + len > B44_DMA_MASK) {
968 /* Chip can't handle DMA to/from >1GB, use bounce buffer */ 978 /* Chip can't handle DMA to/from >1GB, use bounce buffer */
969 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); 979 pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
970 980
971 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, 981 bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
972 GFP_ATOMIC|GFP_DMA); 982 GFP_ATOMIC|GFP_DMA);
973 if (!bounce_skb) 983 if (!bounce_skb)
974 return NETDEV_TX_BUSY; 984 goto err_out;
975 985
976 mapping = pci_map_single(bp->pdev, bounce_skb->data, 986 mapping = pci_map_single(bp->pdev, bounce_skb->data,
977 len, PCI_DMA_TODEVICE); 987 len, PCI_DMA_TODEVICE);
978 if(mapping+len > B44_DMA_MASK) { 988 if (mapping + len > B44_DMA_MASK) {
979 pci_unmap_single(bp->pdev, mapping, 989 pci_unmap_single(bp->pdev, mapping,
980 len, PCI_DMA_TODEVICE); 990 len, PCI_DMA_TODEVICE);
981 dev_kfree_skb_any(bounce_skb); 991 dev_kfree_skb_any(bounce_skb);
982 return NETDEV_TX_BUSY; 992 goto err_out;
983 } 993 }
984 994
985 memcpy(skb_put(bounce_skb, len), skb->data, skb->len); 995 memcpy(skb_put(bounce_skb, len), skb->data, skb->len);
@@ -1019,11 +1029,16 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
1019 if (TX_BUFFS_AVAIL(bp) < 1) 1029 if (TX_BUFFS_AVAIL(bp) < 1)
1020 netif_stop_queue(dev); 1030 netif_stop_queue(dev);
1021 1031
1032 dev->trans_start = jiffies;
1033
1034out_unlock:
1022 spin_unlock_irq(&bp->lock); 1035 spin_unlock_irq(&bp->lock);
1023 1036
1024 dev->trans_start = jiffies; 1037 return rc;
1025 1038
1026 return 0; 1039err_out:
1040 rc = NETDEV_TX_BUSY;
1041 goto out_unlock;
1027} 1042}
1028 1043
1029static int b44_change_mtu(struct net_device *dev, int new_mtu) 1044static int b44_change_mtu(struct net_device *dev, int new_mtu)
@@ -1097,8 +1112,7 @@ static void b44_free_rings(struct b44 *bp)
1097 * 1112 *
1098 * The chip has been shut down and the driver detached from 1113 * The chip has been shut down and the driver detached from
1099 * the networking, so no interrupts or new tx packets will 1114 * the networking, so no interrupts or new tx packets will
1100 * end up in the driver. bp->lock is not held and we are not 1115 * end up in the driver.
1101 * in an interrupt context and thus may sleep.
1102 */ 1116 */
1103static void b44_init_rings(struct b44 *bp) 1117static void b44_init_rings(struct b44 *bp)
1104{ 1118{
@@ -1170,16 +1184,14 @@ static int b44_alloc_consistent(struct b44 *bp)
1170 int size; 1184 int size;
1171 1185
1172 size = B44_RX_RING_SIZE * sizeof(struct ring_info); 1186 size = B44_RX_RING_SIZE * sizeof(struct ring_info);
1173 bp->rx_buffers = kmalloc(size, GFP_KERNEL); 1187 bp->rx_buffers = kzalloc(size, GFP_KERNEL);
1174 if (!bp->rx_buffers) 1188 if (!bp->rx_buffers)
1175 goto out_err; 1189 goto out_err;
1176 memset(bp->rx_buffers, 0, size);
1177 1190
1178 size = B44_TX_RING_SIZE * sizeof(struct ring_info); 1191 size = B44_TX_RING_SIZE * sizeof(struct ring_info);
1179 bp->tx_buffers = kmalloc(size, GFP_KERNEL); 1192 bp->tx_buffers = kzalloc(size, GFP_KERNEL);
1180 if (!bp->tx_buffers) 1193 if (!bp->tx_buffers)
1181 goto out_err; 1194 goto out_err;
1182 memset(bp->tx_buffers, 0, size);
1183 1195
1184 size = DMA_TABLE_BYTES; 1196 size = DMA_TABLE_BYTES;
1185 bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); 1197 bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
@@ -1190,10 +1202,10 @@ static int b44_alloc_consistent(struct b44 *bp)
1190 struct dma_desc *rx_ring; 1202 struct dma_desc *rx_ring;
1191 dma_addr_t rx_ring_dma; 1203 dma_addr_t rx_ring_dma;
1192 1204
1193 if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) 1205 rx_ring = kzalloc(size, GFP_KERNEL);
1206 if (!rx_ring)
1194 goto out_err; 1207 goto out_err;
1195 1208
1196 memset(rx_ring, 0, size);
1197 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring, 1209 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
1198 DMA_TABLE_BYTES, 1210 DMA_TABLE_BYTES,
1199 DMA_BIDIRECTIONAL); 1211 DMA_BIDIRECTIONAL);
@@ -1216,10 +1228,10 @@ static int b44_alloc_consistent(struct b44 *bp)
1216 struct dma_desc *tx_ring; 1228 struct dma_desc *tx_ring;
1217 dma_addr_t tx_ring_dma; 1229 dma_addr_t tx_ring_dma;
1218 1230
1219 if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) 1231 tx_ring = kzalloc(size, GFP_KERNEL);
1232 if (!tx_ring)
1220 goto out_err; 1233 goto out_err;
1221 1234
1222 memset(tx_ring, 0, size);
1223 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring, 1235 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
1224 DMA_TABLE_BYTES, 1236 DMA_TABLE_BYTES,
1225 DMA_TO_DEVICE); 1237 DMA_TO_DEVICE);
@@ -1382,22 +1394,21 @@ static int b44_open(struct net_device *dev)
1382 1394
1383 err = b44_alloc_consistent(bp); 1395 err = b44_alloc_consistent(bp);
1384 if (err) 1396 if (err)
1385 return err; 1397 goto out;
1386
1387 err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
1388 if (err)
1389 goto err_out_free;
1390
1391 spin_lock_irq(&bp->lock);
1392 1398
1393 b44_init_rings(bp); 1399 b44_init_rings(bp);
1394 b44_init_hw(bp); 1400 b44_init_hw(bp);
1395 bp->flags |= B44_FLAG_INIT_COMPLETE;
1396 1401
1397 netif_carrier_off(dev); 1402 netif_carrier_off(dev);
1398 b44_check_phy(bp); 1403 b44_check_phy(bp);
1399 1404
1400 spin_unlock_irq(&bp->lock); 1405 err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
1406 if (unlikely(err < 0)) {
1407 b44_chip_reset(bp);
1408 b44_free_rings(bp);
1409 b44_free_consistent(bp);
1410 goto out;
1411 }
1401 1412
1402 init_timer(&bp->timer); 1413 init_timer(&bp->timer);
1403 bp->timer.expires = jiffies + HZ; 1414 bp->timer.expires = jiffies + HZ;
@@ -1406,11 +1417,7 @@ static int b44_open(struct net_device *dev)
1406 add_timer(&bp->timer); 1417 add_timer(&bp->timer);
1407 1418
1408 b44_enable_ints(bp); 1419 b44_enable_ints(bp);
1409 1420out:
1410 return 0;
1411
1412err_out_free:
1413 b44_free_consistent(bp);
1414 return err; 1421 return err;
1415} 1422}
1416 1423
@@ -1445,6 +1452,8 @@ static int b44_close(struct net_device *dev)
1445 1452
1446 netif_stop_queue(dev); 1453 netif_stop_queue(dev);
1447 1454
1455 netif_poll_disable(dev);
1456
1448 del_timer_sync(&bp->timer); 1457 del_timer_sync(&bp->timer);
1449 1458
1450 spin_lock_irq(&bp->lock); 1459 spin_lock_irq(&bp->lock);
@@ -1454,13 +1463,14 @@ static int b44_close(struct net_device *dev)
1454#endif 1463#endif
1455 b44_halt(bp); 1464 b44_halt(bp);
1456 b44_free_rings(bp); 1465 b44_free_rings(bp);
1457 bp->flags &= ~B44_FLAG_INIT_COMPLETE;
1458 netif_carrier_off(bp->dev); 1466 netif_carrier_off(bp->dev);
1459 1467
1460 spin_unlock_irq(&bp->lock); 1468 spin_unlock_irq(&bp->lock);
1461 1469
1462 free_irq(dev->irq, dev); 1470 free_irq(dev->irq, dev);
1463 1471
1472 netif_poll_enable(dev);
1473
1464 b44_free_consistent(bp); 1474 b44_free_consistent(bp);
1465 1475
1466 return 0; 1476 return 0;
@@ -1525,8 +1535,6 @@ static void __b44_set_rx_mode(struct net_device *dev)
1525{ 1535{
1526 struct b44 *bp = netdev_priv(dev); 1536 struct b44 *bp = netdev_priv(dev);
1527 u32 val; 1537 u32 val;
1528 int i=0;
1529 unsigned char zero[6] = {0,0,0,0,0,0};
1530 1538
1531 val = br32(bp, B44_RXCONFIG); 1539 val = br32(bp, B44_RXCONFIG);
1532 val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); 1540 val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
@@ -1534,14 +1542,17 @@ static void __b44_set_rx_mode(struct net_device *dev)
1534 val |= RXCONFIG_PROMISC; 1542 val |= RXCONFIG_PROMISC;
1535 bw32(bp, B44_RXCONFIG, val); 1543 bw32(bp, B44_RXCONFIG, val);
1536 } else { 1544 } else {
1545 unsigned char zero[6] = {0, 0, 0, 0, 0, 0};
1546 int i = 0;
1547
1537 __b44_set_mac_addr(bp); 1548 __b44_set_mac_addr(bp);
1538 1549
1539 if (dev->flags & IFF_ALLMULTI) 1550 if (dev->flags & IFF_ALLMULTI)
1540 val |= RXCONFIG_ALLMULTI; 1551 val |= RXCONFIG_ALLMULTI;
1541 else 1552 else
1542 i=__b44_load_mcast(bp, dev); 1553 i = __b44_load_mcast(bp, dev);
1543 1554
1544 for(;i<64;i++) { 1555 for (; i < 64; i++) {
1545 __b44_cam_write(bp, zero, i); 1556 __b44_cam_write(bp, zero, i);
1546 } 1557 }
1547 bw32(bp, B44_RXCONFIG, val); 1558 bw32(bp, B44_RXCONFIG, val);
@@ -1605,7 +1616,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1605{ 1616{
1606 struct b44 *bp = netdev_priv(dev); 1617 struct b44 *bp = netdev_priv(dev);
1607 1618
1608 if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) 1619 if (!netif_running(dev))
1609 return -EAGAIN; 1620 return -EAGAIN;
1610 cmd->supported = (SUPPORTED_Autoneg); 1621 cmd->supported = (SUPPORTED_Autoneg);
1611 cmd->supported |= (SUPPORTED_100baseT_Half | 1622 cmd->supported |= (SUPPORTED_100baseT_Half |
@@ -1643,7 +1654,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1643{ 1654{
1644 struct b44 *bp = netdev_priv(dev); 1655 struct b44 *bp = netdev_priv(dev);
1645 1656
1646 if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) 1657 if (!netif_running(dev))
1647 return -EAGAIN; 1658 return -EAGAIN;
1648 1659
1649 /* We do not support gigabit. */ 1660 /* We do not support gigabit. */
@@ -1773,6 +1784,37 @@ static int b44_set_pauseparam(struct net_device *dev,
1773 return 0; 1784 return 0;
1774} 1785}
1775 1786
1787static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1788{
1789 switch(stringset) {
1790 case ETH_SS_STATS:
1791 memcpy(data, *b44_gstrings, sizeof(b44_gstrings));
1792 break;
1793 }
1794}
1795
1796static int b44_get_stats_count(struct net_device *dev)
1797{
1798 return ARRAY_SIZE(b44_gstrings);
1799}
1800
1801static void b44_get_ethtool_stats(struct net_device *dev,
1802 struct ethtool_stats *stats, u64 *data)
1803{
1804 struct b44 *bp = netdev_priv(dev);
1805 u32 *val = &bp->hw_stats.tx_good_octets;
1806 u32 i;
1807
1808 spin_lock_irq(&bp->lock);
1809
1810 b44_stats_update(bp);
1811
1812 for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++)
1813 *data++ = *val++;
1814
1815 spin_unlock_irq(&bp->lock);
1816}
1817
1776static struct ethtool_ops b44_ethtool_ops = { 1818static struct ethtool_ops b44_ethtool_ops = {
1777 .get_drvinfo = b44_get_drvinfo, 1819 .get_drvinfo = b44_get_drvinfo,
1778 .get_settings = b44_get_settings, 1820 .get_settings = b44_get_settings,
@@ -1785,6 +1827,9 @@ static struct ethtool_ops b44_ethtool_ops = {
1785 .set_pauseparam = b44_set_pauseparam, 1827 .set_pauseparam = b44_set_pauseparam,
1786 .get_msglevel = b44_get_msglevel, 1828 .get_msglevel = b44_get_msglevel,
1787 .set_msglevel = b44_set_msglevel, 1829 .set_msglevel = b44_set_msglevel,
1830 .get_strings = b44_get_strings,
1831 .get_stats_count = b44_get_stats_count,
1832 .get_ethtool_stats = b44_get_ethtool_stats,
1788 .get_perm_addr = ethtool_op_get_perm_addr, 1833 .get_perm_addr = ethtool_op_get_perm_addr,
1789}; 1834};
1790 1835
@@ -1893,9 +1938,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
1893 1938
1894 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); 1939 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
1895 if (err) { 1940 if (err) {
1896 printk(KERN_ERR PFX "No usable DMA configuration, " 1941 printk(KERN_ERR PFX "No usable DMA configuration, "
1897 "aborting.\n"); 1942 "aborting.\n");
1898 goto err_out_free_res; 1943 goto err_out_free_res;
1899 } 1944 }
1900 1945
1901 b44reg_base = pci_resource_start(pdev, 0); 1946 b44reg_base = pci_resource_start(pdev, 0);
@@ -1917,10 +1962,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
1917 bp = netdev_priv(dev); 1962 bp = netdev_priv(dev);
1918 bp->pdev = pdev; 1963 bp->pdev = pdev;
1919 bp->dev = dev; 1964 bp->dev = dev;
1920 if (b44_debug >= 0) 1965
1921 bp->msg_enable = (1 << b44_debug) - 1; 1966 bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
1922 else
1923 bp->msg_enable = B44_DEF_MSG_ENABLE;
1924 1967
1925 spin_lock_init(&bp->lock); 1968 spin_lock_init(&bp->lock);
1926 1969
@@ -2010,17 +2053,14 @@ err_out_disable_pdev:
2010static void __devexit b44_remove_one(struct pci_dev *pdev) 2053static void __devexit b44_remove_one(struct pci_dev *pdev)
2011{ 2054{
2012 struct net_device *dev = pci_get_drvdata(pdev); 2055 struct net_device *dev = pci_get_drvdata(pdev);
2056 struct b44 *bp = netdev_priv(dev);
2013 2057
2014 if (dev) { 2058 unregister_netdev(dev);
2015 struct b44 *bp = netdev_priv(dev); 2059 iounmap(bp->regs);
2016 2060 free_netdev(dev);
2017 unregister_netdev(dev); 2061 pci_release_regions(pdev);
2018 iounmap(bp->regs); 2062 pci_disable_device(pdev);
2019 free_netdev(dev); 2063 pci_set_drvdata(pdev, NULL);
2020 pci_release_regions(pdev);
2021 pci_disable_device(pdev);
2022 pci_set_drvdata(pdev, NULL);
2023 }
2024} 2064}
2025 2065
2026static int b44_suspend(struct pci_dev *pdev, pm_message_t state) 2066static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 593cb0ad4100..b178662978f3 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -346,29 +346,63 @@ struct ring_info {
346 346
347#define B44_MCAST_TABLE_SIZE 32 347#define B44_MCAST_TABLE_SIZE 32
348 348
349#define B44_STAT_REG_DECLARE \
350 _B44(tx_good_octets) \
351 _B44(tx_good_pkts) \
352 _B44(tx_octets) \
353 _B44(tx_pkts) \
354 _B44(tx_broadcast_pkts) \
355 _B44(tx_multicast_pkts) \
356 _B44(tx_len_64) \
357 _B44(tx_len_65_to_127) \
358 _B44(tx_len_128_to_255) \
359 _B44(tx_len_256_to_511) \
360 _B44(tx_len_512_to_1023) \
361 _B44(tx_len_1024_to_max) \
362 _B44(tx_jabber_pkts) \
363 _B44(tx_oversize_pkts) \
364 _B44(tx_fragment_pkts) \
365 _B44(tx_underruns) \
366 _B44(tx_total_cols) \
367 _B44(tx_single_cols) \
368 _B44(tx_multiple_cols) \
369 _B44(tx_excessive_cols) \
370 _B44(tx_late_cols) \
371 _B44(tx_defered) \
372 _B44(tx_carrier_lost) \
373 _B44(tx_pause_pkts) \
374 _B44(rx_good_octets) \
375 _B44(rx_good_pkts) \
376 _B44(rx_octets) \
377 _B44(rx_pkts) \
378 _B44(rx_broadcast_pkts) \
379 _B44(rx_multicast_pkts) \
380 _B44(rx_len_64) \
381 _B44(rx_len_65_to_127) \
382 _B44(rx_len_128_to_255) \
383 _B44(rx_len_256_to_511) \
384 _B44(rx_len_512_to_1023) \
385 _B44(rx_len_1024_to_max) \
386 _B44(rx_jabber_pkts) \
387 _B44(rx_oversize_pkts) \
388 _B44(rx_fragment_pkts) \
389 _B44(rx_missed_pkts) \
390 _B44(rx_crc_align_errs) \
391 _B44(rx_undersize) \
392 _B44(rx_crc_errs) \
393 _B44(rx_align_errs) \
394 _B44(rx_symbol_errs) \
395 _B44(rx_pause_pkts) \
396 _B44(rx_nonpause_pkts)
397
349/* SW copy of device statistics, kept up to date by periodic timer 398/* SW copy of device statistics, kept up to date by periodic timer
350 * which probes HW values. Must have same relative layout as HW 399 * which probes HW values. Check b44_stats_update if you mess with
351 * register above, because b44_stats_update depends upon this. 400 * the layout
352 */ 401 */
353struct b44_hw_stats { 402struct b44_hw_stats {
354 u32 tx_good_octets, tx_good_pkts, tx_octets; 403#define _B44(x) u32 x;
355 u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts; 404B44_STAT_REG_DECLARE
356 u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255; 405#undef _B44
357 u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max;
358 u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts;
359 u32 tx_underruns, tx_total_cols, tx_single_cols;
360 u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols;
361 u32 tx_defered, tx_carrier_lost, tx_pause_pkts;
362 u32 __pad1[8];
363
364 u32 rx_good_octets, rx_good_pkts, rx_octets;
365 u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts;
366 u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255;
367 u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max;
368 u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts;
369 u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize;
370 u32 rx_crc_errs, rx_align_errs, rx_symbol_errs;
371 u32 rx_pause_pkts, rx_nonpause_pkts;
372}; 406};
373 407
374struct b44 { 408struct b44 {
@@ -386,7 +420,6 @@ struct b44 {
386 420
387 u32 dma_offset; 421 u32 dma_offset;
388 u32 flags; 422 u32 flags;
389#define B44_FLAG_INIT_COMPLETE 0x00000001
390#define B44_FLAG_BUGGY_TXPTR 0x00000002 423#define B44_FLAG_BUGGY_TXPTR 0x00000002
391#define B44_FLAG_REORDER_BUG 0x00000004 424#define B44_FLAG_REORDER_BUG 0x00000004
392#define B44_FLAG_PAUSE_AUTO 0x00008000 425#define B44_FLAG_PAUSE_AUTO 0x00008000
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 11d252318221..49fa1e4413fa 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -14,8 +14,8 @@
14 14
15#define DRV_MODULE_NAME "bnx2" 15#define DRV_MODULE_NAME "bnx2"
16#define PFX DRV_MODULE_NAME ": " 16#define PFX DRV_MODULE_NAME ": "
17#define DRV_MODULE_VERSION "1.2.21" 17#define DRV_MODULE_VERSION "1.4.30"
18#define DRV_MODULE_RELDATE "September 7, 2005" 18#define DRV_MODULE_RELDATE "October 11, 2005"
19 19
20#define RUN_AT(x) (jiffies + (x)) 20#define RUN_AT(x) (jiffies + (x))
21 21
@@ -26,7 +26,7 @@ static char version[] __devinitdata =
26 "Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; 26 "Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
27 27
28MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>"); 28MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>");
29MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706 Driver"); 29MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708 Driver");
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31MODULE_VERSION(DRV_MODULE_VERSION); 31MODULE_VERSION(DRV_MODULE_VERSION);
32 32
@@ -41,6 +41,8 @@ typedef enum {
41 NC370I, 41 NC370I,
42 BCM5706S, 42 BCM5706S,
43 NC370F, 43 NC370F,
44 BCM5708,
45 BCM5708S,
44} board_t; 46} board_t;
45 47
46/* indexed by board_t, above */ 48/* indexed by board_t, above */
@@ -52,6 +54,8 @@ static struct {
52 { "HP NC370i Multifunction Gigabit Server Adapter" }, 54 { "HP NC370i Multifunction Gigabit Server Adapter" },
53 { "Broadcom NetXtreme II BCM5706 1000Base-SX" }, 55 { "Broadcom NetXtreme II BCM5706 1000Base-SX" },
54 { "HP NC370F Multifunction Gigabit Server Adapter" }, 56 { "HP NC370F Multifunction Gigabit Server Adapter" },
57 { "Broadcom NetXtreme II BCM5708 1000Base-T" },
58 { "Broadcom NetXtreme II BCM5708 1000Base-SX" },
55 }; 59 };
56 60
57static struct pci_device_id bnx2_pci_tbl[] = { 61static struct pci_device_id bnx2_pci_tbl[] = {
@@ -61,48 +65,102 @@ static struct pci_device_id bnx2_pci_tbl[] = {
61 PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I }, 65 PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I },
62 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706, 66 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
63 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 }, 67 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 },
68 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708,
69 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708 },
64 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, 70 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
65 PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F }, 71 PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F },
66 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, 72 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
67 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S }, 73 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S },
74 { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S,
75 PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S },
68 { 0, } 76 { 0, }
69}; 77};
70 78
71static struct flash_spec flash_table[] = 79static struct flash_spec flash_table[] =
72{ 80{
73 /* Slow EEPROM */ 81 /* Slow EEPROM */
74 {0x00000000, 0x40030380, 0x009f0081, 0xa184a053, 0xaf000400, 82 {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
75 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, 83 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
76 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, 84 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
77 "EEPROM - slow"}, 85 "EEPROM - slow"},
78 /* Fast EEPROM */ 86 /* Expansion entry 0001 */
79 {0x02000000, 0x62008380, 0x009f0081, 0xa184a053, 0xaf000400, 87 {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
80 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
81 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
82 "EEPROM - fast"},
83 /* ATMEL AT45DB011B (buffered flash) */
84 {0x02000003, 0x6e008173, 0x00570081, 0x68848353, 0xaf000400,
85 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
86 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
87 "Buffered flash"},
88 /* Saifun SA25F005 (non-buffered flash) */
89 /* strap, cfg1, & write1 need updates */
90 {0x01000003, 0x5f008081, 0x00050081, 0x03840253, 0xaf020406,
91 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 88 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
92 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE, 89 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
93 "Non-buffered flash (64kB)"}, 90 "Entry 0001"},
94 /* Saifun SA25F010 (non-buffered flash) */ 91 /* Saifun SA25F010 (non-buffered flash) */
95 /* strap, cfg1, & write1 need updates */ 92 /* strap, cfg1, & write1 need updates */
96 {0x00000001, 0x47008081, 0x00050081, 0x03840253, 0xaf020406, 93 {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
97 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 94 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
98 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2, 95 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
99 "Non-buffered flash (128kB)"}, 96 "Non-buffered flash (128kB)"},
100 /* Saifun SA25F020 (non-buffered flash) */ 97 /* Saifun SA25F020 (non-buffered flash) */
101 /* strap, cfg1, & write1 need updates */ 98 /* strap, cfg1, & write1 need updates */
102 {0x00000003, 0x4f008081, 0x00050081, 0x03840253, 0xaf020406, 99 {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
103 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 100 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
104 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4, 101 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
105 "Non-buffered flash (256kB)"}, 102 "Non-buffered flash (256kB)"},
103 /* Expansion entry 0100 */
104 {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
105 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
106 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
107 "Entry 0100"},
108 /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
109 {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
110 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
111 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
112 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
113 /* Entry 0110: ST M45PE20 (non-buffered flash)*/
114 {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
115 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
116 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
117 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
118 /* Saifun SA25F005 (non-buffered flash) */
119 /* strap, cfg1, & write1 need updates */
120 {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
121 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
122 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
123 "Non-buffered flash (64kB)"},
124 /* Fast EEPROM */
125 {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
126 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
127 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
128 "EEPROM - fast"},
129 /* Expansion entry 1001 */
130 {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
131 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
132 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
133 "Entry 1001"},
134 /* Expansion entry 1010 */
135 {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
136 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
137 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
138 "Entry 1010"},
139 /* ATMEL AT45DB011B (buffered flash) */
140 {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
141 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
142 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
143 "Buffered flash (128kB)"},
144 /* Expansion entry 1100 */
145 {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
146 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
147 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
148 "Entry 1100"},
149 /* Expansion entry 1101 */
150 {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
151 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
152 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
153 "Entry 1101"},
154 /* Ateml Expansion entry 1110 */
155 {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
156 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
157 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
158 "Entry 1110 (Atmel)"},
159 /* ATMEL AT45DB021B (buffered flash) */
160 {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
161 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
162 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
163 "Buffered flash (256kB)"},
106}; 164};
107 165
108MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); 166MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
@@ -379,6 +437,62 @@ alloc_mem_err:
379} 437}
380 438
381static void 439static void
440bnx2_report_fw_link(struct bnx2 *bp)
441{
442 u32 fw_link_status = 0;
443
444 if (bp->link_up) {
445 u32 bmsr;
446
447 switch (bp->line_speed) {
448 case SPEED_10:
449 if (bp->duplex == DUPLEX_HALF)
450 fw_link_status = BNX2_LINK_STATUS_10HALF;
451 else
452 fw_link_status = BNX2_LINK_STATUS_10FULL;
453 break;
454 case SPEED_100:
455 if (bp->duplex == DUPLEX_HALF)
456 fw_link_status = BNX2_LINK_STATUS_100HALF;
457 else
458 fw_link_status = BNX2_LINK_STATUS_100FULL;
459 break;
460 case SPEED_1000:
461 if (bp->duplex == DUPLEX_HALF)
462 fw_link_status = BNX2_LINK_STATUS_1000HALF;
463 else
464 fw_link_status = BNX2_LINK_STATUS_1000FULL;
465 break;
466 case SPEED_2500:
467 if (bp->duplex == DUPLEX_HALF)
468 fw_link_status = BNX2_LINK_STATUS_2500HALF;
469 else
470 fw_link_status = BNX2_LINK_STATUS_2500FULL;
471 break;
472 }
473
474 fw_link_status |= BNX2_LINK_STATUS_LINK_UP;
475
476 if (bp->autoneg) {
477 fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED;
478
479 bnx2_read_phy(bp, MII_BMSR, &bmsr);
480 bnx2_read_phy(bp, MII_BMSR, &bmsr);
481
482 if (!(bmsr & BMSR_ANEGCOMPLETE) ||
483 bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)
484 fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
485 else
486 fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
487 }
488 }
489 else
490 fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
491
492 REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
493}
494
495static void
382bnx2_report_link(struct bnx2 *bp) 496bnx2_report_link(struct bnx2 *bp)
383{ 497{
384 if (bp->link_up) { 498 if (bp->link_up) {
@@ -409,6 +523,8 @@ bnx2_report_link(struct bnx2 *bp)
409 netif_carrier_off(bp->dev); 523 netif_carrier_off(bp->dev);
410 printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name); 524 printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
411 } 525 }
526
527 bnx2_report_fw_link(bp);
412} 528}
413 529
414static void 530static void
@@ -430,6 +546,18 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp)
430 return; 546 return;
431 } 547 }
432 548
549 if ((bp->phy_flags & PHY_SERDES_FLAG) &&
550 (CHIP_NUM(bp) == CHIP_NUM_5708)) {
551 u32 val;
552
553 bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
554 if (val & BCM5708S_1000X_STAT1_TX_PAUSE)
555 bp->flow_ctrl |= FLOW_CTRL_TX;
556 if (val & BCM5708S_1000X_STAT1_RX_PAUSE)
557 bp->flow_ctrl |= FLOW_CTRL_RX;
558 return;
559 }
560
433 bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); 561 bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
434 bnx2_read_phy(bp, MII_LPA, &remote_adv); 562 bnx2_read_phy(bp, MII_LPA, &remote_adv);
435 563
@@ -476,7 +604,36 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp)
476} 604}
477 605
478static int 606static int
479bnx2_serdes_linkup(struct bnx2 *bp) 607bnx2_5708s_linkup(struct bnx2 *bp)
608{
609 u32 val;
610
611 bp->link_up = 1;
612 bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
613 switch (val & BCM5708S_1000X_STAT1_SPEED_MASK) {
614 case BCM5708S_1000X_STAT1_SPEED_10:
615 bp->line_speed = SPEED_10;
616 break;
617 case BCM5708S_1000X_STAT1_SPEED_100:
618 bp->line_speed = SPEED_100;
619 break;
620 case BCM5708S_1000X_STAT1_SPEED_1G:
621 bp->line_speed = SPEED_1000;
622 break;
623 case BCM5708S_1000X_STAT1_SPEED_2G5:
624 bp->line_speed = SPEED_2500;
625 break;
626 }
627 if (val & BCM5708S_1000X_STAT1_FD)
628 bp->duplex = DUPLEX_FULL;
629 else
630 bp->duplex = DUPLEX_HALF;
631
632 return 0;
633}
634
635static int
636bnx2_5706s_linkup(struct bnx2 *bp)
480{ 637{
481 u32 bmcr, local_adv, remote_adv, common; 638 u32 bmcr, local_adv, remote_adv, common;
482 639
@@ -593,13 +750,27 @@ bnx2_set_mac_link(struct bnx2 *bp)
593 val = REG_RD(bp, BNX2_EMAC_MODE); 750 val = REG_RD(bp, BNX2_EMAC_MODE);
594 751
595 val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | 752 val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
596 BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK); 753 BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
754 BNX2_EMAC_MODE_25G);
597 755
598 if (bp->link_up) { 756 if (bp->link_up) {
599 if (bp->line_speed != SPEED_1000) 757 switch (bp->line_speed) {
600 val |= BNX2_EMAC_MODE_PORT_MII; 758 case SPEED_10:
601 else 759 if (CHIP_NUM(bp) == CHIP_NUM_5708) {
602 val |= BNX2_EMAC_MODE_PORT_GMII; 760 val |= BNX2_EMAC_MODE_PORT_MII_10;
761 break;
762 }
763 /* fall through */
764 case SPEED_100:
765 val |= BNX2_EMAC_MODE_PORT_MII;
766 break;
767 case SPEED_2500:
768 val |= BNX2_EMAC_MODE_25G;
769 /* fall through */
770 case SPEED_1000:
771 val |= BNX2_EMAC_MODE_PORT_GMII;
772 break;
773 }
603 } 774 }
604 else { 775 else {
605 val |= BNX2_EMAC_MODE_PORT_GMII; 776 val |= BNX2_EMAC_MODE_PORT_GMII;
@@ -662,7 +833,10 @@ bnx2_set_link(struct bnx2 *bp)
662 bp->link_up = 1; 833 bp->link_up = 1;
663 834
664 if (bp->phy_flags & PHY_SERDES_FLAG) { 835 if (bp->phy_flags & PHY_SERDES_FLAG) {
665 bnx2_serdes_linkup(bp); 836 if (CHIP_NUM(bp) == CHIP_NUM_5706)
837 bnx2_5706s_linkup(bp);
838 else if (CHIP_NUM(bp) == CHIP_NUM_5708)
839 bnx2_5708s_linkup(bp);
666 } 840 }
667 else { 841 else {
668 bnx2_copper_linkup(bp); 842 bnx2_copper_linkup(bp);
@@ -755,39 +929,61 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp)
755static int 929static int
756bnx2_setup_serdes_phy(struct bnx2 *bp) 930bnx2_setup_serdes_phy(struct bnx2 *bp)
757{ 931{
758 u32 adv, bmcr; 932 u32 adv, bmcr, up1;
759 u32 new_adv = 0; 933 u32 new_adv = 0;
760 934
761 if (!(bp->autoneg & AUTONEG_SPEED)) { 935 if (!(bp->autoneg & AUTONEG_SPEED)) {
762 u32 new_bmcr; 936 u32 new_bmcr;
937 int force_link_down = 0;
938
939 if (CHIP_NUM(bp) == CHIP_NUM_5708) {
940 bnx2_read_phy(bp, BCM5708S_UP1, &up1);
941 if (up1 & BCM5708S_UP1_2G5) {
942 up1 &= ~BCM5708S_UP1_2G5;
943 bnx2_write_phy(bp, BCM5708S_UP1, up1);
944 force_link_down = 1;
945 }
946 }
947
948 bnx2_read_phy(bp, MII_ADVERTISE, &adv);
949 adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
763 950
764 bnx2_read_phy(bp, MII_BMCR, &bmcr); 951 bnx2_read_phy(bp, MII_BMCR, &bmcr);
765 new_bmcr = bmcr & ~BMCR_ANENABLE; 952 new_bmcr = bmcr & ~BMCR_ANENABLE;
766 new_bmcr |= BMCR_SPEED1000; 953 new_bmcr |= BMCR_SPEED1000;
767 if (bp->req_duplex == DUPLEX_FULL) { 954 if (bp->req_duplex == DUPLEX_FULL) {
955 adv |= ADVERTISE_1000XFULL;
768 new_bmcr |= BMCR_FULLDPLX; 956 new_bmcr |= BMCR_FULLDPLX;
769 } 957 }
770 else { 958 else {
959 adv |= ADVERTISE_1000XHALF;
771 new_bmcr &= ~BMCR_FULLDPLX; 960 new_bmcr &= ~BMCR_FULLDPLX;
772 } 961 }
773 if (new_bmcr != bmcr) { 962 if ((new_bmcr != bmcr) || (force_link_down)) {
774 /* Force a link down visible on the other side */ 963 /* Force a link down visible on the other side */
775 if (bp->link_up) { 964 if (bp->link_up) {
776 bnx2_read_phy(bp, MII_ADVERTISE, &adv); 965 bnx2_write_phy(bp, MII_ADVERTISE, adv &
777 adv &= ~(ADVERTISE_1000XFULL | 966 ~(ADVERTISE_1000XFULL |
778 ADVERTISE_1000XHALF); 967 ADVERTISE_1000XHALF));
779 bnx2_write_phy(bp, MII_ADVERTISE, adv);
780 bnx2_write_phy(bp, MII_BMCR, bmcr | 968 bnx2_write_phy(bp, MII_BMCR, bmcr |
781 BMCR_ANRESTART | BMCR_ANENABLE); 969 BMCR_ANRESTART | BMCR_ANENABLE);
782 970
783 bp->link_up = 0; 971 bp->link_up = 0;
784 netif_carrier_off(bp->dev); 972 netif_carrier_off(bp->dev);
973 bnx2_write_phy(bp, MII_BMCR, new_bmcr);
785 } 974 }
975 bnx2_write_phy(bp, MII_ADVERTISE, adv);
786 bnx2_write_phy(bp, MII_BMCR, new_bmcr); 976 bnx2_write_phy(bp, MII_BMCR, new_bmcr);
787 } 977 }
788 return 0; 978 return 0;
789 } 979 }
790 980
981 if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
982 bnx2_read_phy(bp, BCM5708S_UP1, &up1);
983 up1 |= BCM5708S_UP1_2G5;
984 bnx2_write_phy(bp, BCM5708S_UP1, up1);
985 }
986
791 if (bp->advertising & ADVERTISED_1000baseT_Full) 987 if (bp->advertising & ADVERTISED_1000baseT_Full)
792 new_adv |= ADVERTISE_1000XFULL; 988 new_adv |= ADVERTISE_1000XFULL;
793 989
@@ -952,7 +1148,60 @@ bnx2_setup_phy(struct bnx2 *bp)
952} 1148}
953 1149
954static int 1150static int
955bnx2_init_serdes_phy(struct bnx2 *bp) 1151bnx2_init_5708s_phy(struct bnx2 *bp)
1152{
1153 u32 val;
1154
1155 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3);
1156 bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE);
1157 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
1158
1159 bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val);
1160 val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN;
1161 bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val);
1162
1163 bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val);
1164 val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN;
1165 bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val);
1166
1167 if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
1168 bnx2_read_phy(bp, BCM5708S_UP1, &val);
1169 val |= BCM5708S_UP1_2G5;
1170 bnx2_write_phy(bp, BCM5708S_UP1, val);
1171 }
1172
1173 if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
1174 (CHIP_ID(bp) == CHIP_ID_5708_B0)) {
1175 /* increase tx signal amplitude */
1176 bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
1177 BCM5708S_BLK_ADDR_TX_MISC);
1178 bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val);
1179 val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM;
1180 bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val);
1181 bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
1182 }
1183
1184 val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
1185 BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
1186
1187 if (val) {
1188 u32 is_backplane;
1189
1190 is_backplane = REG_RD_IND(bp, bp->shmem_base +
1191 BNX2_SHARED_HW_CFG_CONFIG);
1192 if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
1193 bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
1194 BCM5708S_BLK_ADDR_TX_MISC);
1195 bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val);
1196 bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
1197 BCM5708S_BLK_ADDR_DIG);
1198 }
1199 }
1200 return 0;
1201}
1202
1203static int
1204bnx2_init_5706s_phy(struct bnx2 *bp)
956{ 1205{
957 bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; 1206 bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
958 1207
@@ -990,6 +1239,8 @@ bnx2_init_serdes_phy(struct bnx2 *bp)
990static int 1239static int
991bnx2_init_copper_phy(struct bnx2 *bp) 1240bnx2_init_copper_phy(struct bnx2 *bp)
992{ 1241{
1242 u32 val;
1243
993 bp->phy_flags |= PHY_CRC_FIX_FLAG; 1244 bp->phy_flags |= PHY_CRC_FIX_FLAG;
994 1245
995 if (bp->phy_flags & PHY_CRC_FIX_FLAG) { 1246 if (bp->phy_flags & PHY_CRC_FIX_FLAG) {
@@ -1004,8 +1255,6 @@ bnx2_init_copper_phy(struct bnx2 *bp)
1004 } 1255 }
1005 1256
1006 if (bp->dev->mtu > 1500) { 1257 if (bp->dev->mtu > 1500) {
1007 u32 val;
1008
1009 /* Set extended packet length bit */ 1258 /* Set extended packet length bit */
1010 bnx2_write_phy(bp, 0x18, 0x7); 1259 bnx2_write_phy(bp, 0x18, 0x7);
1011 bnx2_read_phy(bp, 0x18, &val); 1260 bnx2_read_phy(bp, 0x18, &val);
@@ -1015,8 +1264,6 @@ bnx2_init_copper_phy(struct bnx2 *bp)
1015 bnx2_write_phy(bp, 0x10, val | 0x1); 1264 bnx2_write_phy(bp, 0x10, val | 0x1);
1016 } 1265 }
1017 else { 1266 else {
1018 u32 val;
1019
1020 bnx2_write_phy(bp, 0x18, 0x7); 1267 bnx2_write_phy(bp, 0x18, 0x7);
1021 bnx2_read_phy(bp, 0x18, &val); 1268 bnx2_read_phy(bp, 0x18, &val);
1022 bnx2_write_phy(bp, 0x18, val & ~0x4007); 1269 bnx2_write_phy(bp, 0x18, val & ~0x4007);
@@ -1025,6 +1272,10 @@ bnx2_init_copper_phy(struct bnx2 *bp)
1025 bnx2_write_phy(bp, 0x10, val & ~0x1); 1272 bnx2_write_phy(bp, 0x10, val & ~0x1);
1026 } 1273 }
1027 1274
1275 /* ethernet@wirespeed */
1276 bnx2_write_phy(bp, 0x18, 0x7007);
1277 bnx2_read_phy(bp, 0x18, &val);
1278 bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4));
1028 return 0; 1279 return 0;
1029} 1280}
1030 1281
@@ -1048,7 +1299,10 @@ bnx2_init_phy(struct bnx2 *bp)
1048 bp->phy_id |= val & 0xffff; 1299 bp->phy_id |= val & 0xffff;
1049 1300
1050 if (bp->phy_flags & PHY_SERDES_FLAG) { 1301 if (bp->phy_flags & PHY_SERDES_FLAG) {
1051 rc = bnx2_init_serdes_phy(bp); 1302 if (CHIP_NUM(bp) == CHIP_NUM_5706)
1303 rc = bnx2_init_5706s_phy(bp);
1304 else if (CHIP_NUM(bp) == CHIP_NUM_5708)
1305 rc = bnx2_init_5708s_phy(bp);
1052 } 1306 }
1053 else { 1307 else {
1054 rc = bnx2_init_copper_phy(bp); 1308 rc = bnx2_init_copper_phy(bp);
@@ -1084,13 +1338,13 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
1084 bp->fw_wr_seq++; 1338 bp->fw_wr_seq++;
1085 msg_data |= bp->fw_wr_seq; 1339 msg_data |= bp->fw_wr_seq;
1086 1340
1087 REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data); 1341 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
1088 1342
1089 /* wait for an acknowledgement. */ 1343 /* wait for an acknowledgement. */
1090 for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) { 1344 for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) {
1091 udelay(5); 1345 udelay(5);
1092 1346
1093 val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB); 1347 val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
1094 1348
1095 if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ)) 1349 if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
1096 break; 1350 break;
@@ -1103,7 +1357,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
1103 msg_data &= ~BNX2_DRV_MSG_CODE; 1357 msg_data &= ~BNX2_DRV_MSG_CODE;
1104 msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; 1358 msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
1105 1359
1106 REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data); 1360 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
1107 1361
1108 bp->fw_timed_out = 1; 1362 bp->fw_timed_out = 1;
1109 1363
@@ -1279,10 +1533,11 @@ bnx2_phy_int(struct bnx2 *bp)
1279static void 1533static void
1280bnx2_tx_int(struct bnx2 *bp) 1534bnx2_tx_int(struct bnx2 *bp)
1281{ 1535{
1536 struct status_block *sblk = bp->status_blk;
1282 u16 hw_cons, sw_cons, sw_ring_cons; 1537 u16 hw_cons, sw_cons, sw_ring_cons;
1283 int tx_free_bd = 0; 1538 int tx_free_bd = 0;
1284 1539
1285 hw_cons = bp->status_blk->status_tx_quick_consumer_index0; 1540 hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
1286 if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { 1541 if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
1287 hw_cons++; 1542 hw_cons++;
1288 } 1543 }
@@ -1337,7 +1592,9 @@ bnx2_tx_int(struct bnx2 *bp)
1337 1592
1338 dev_kfree_skb_irq(skb); 1593 dev_kfree_skb_irq(skb);
1339 1594
1340 hw_cons = bp->status_blk->status_tx_quick_consumer_index0; 1595 hw_cons = bp->hw_tx_cons =
1596 sblk->status_tx_quick_consumer_index0;
1597
1341 if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { 1598 if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
1342 hw_cons++; 1599 hw_cons++;
1343 } 1600 }
@@ -1382,11 +1639,12 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb,
1382static int 1639static int
1383bnx2_rx_int(struct bnx2 *bp, int budget) 1640bnx2_rx_int(struct bnx2 *bp, int budget)
1384{ 1641{
1642 struct status_block *sblk = bp->status_blk;
1385 u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod; 1643 u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
1386 struct l2_fhdr *rx_hdr; 1644 struct l2_fhdr *rx_hdr;
1387 int rx_pkt = 0; 1645 int rx_pkt = 0;
1388 1646
1389 hw_cons = bp->status_blk->status_rx_quick_consumer_index0; 1647 hw_cons = bp->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
1390 if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) { 1648 if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) {
1391 hw_cons++; 1649 hw_cons++;
1392 } 1650 }
@@ -1506,6 +1764,15 @@ next_rx:
1506 1764
1507 if ((rx_pkt == budget)) 1765 if ((rx_pkt == budget))
1508 break; 1766 break;
1767
1768 /* Refresh hw_cons to see if there is new work */
1769 if (sw_cons == hw_cons) {
1770 hw_cons = bp->hw_rx_cons =
1771 sblk->status_rx_quick_consumer_index0;
1772 if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)
1773 hw_cons++;
1774 rmb();
1775 }
1509 } 1776 }
1510 bp->rx_cons = sw_cons; 1777 bp->rx_cons = sw_cons;
1511 bp->rx_prod = sw_prod; 1778 bp->rx_prod = sw_prod;
@@ -1573,15 +1840,27 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1573 return IRQ_HANDLED; 1840 return IRQ_HANDLED;
1574} 1841}
1575 1842
1843static inline int
1844bnx2_has_work(struct bnx2 *bp)
1845{
1846 struct status_block *sblk = bp->status_blk;
1847
1848 if ((sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) ||
1849 (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons))
1850 return 1;
1851
1852 if (((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) !=
1853 bp->link_up)
1854 return 1;
1855
1856 return 0;
1857}
1858
1576static int 1859static int
1577bnx2_poll(struct net_device *dev, int *budget) 1860bnx2_poll(struct net_device *dev, int *budget)
1578{ 1861{
1579 struct bnx2 *bp = dev->priv; 1862 struct bnx2 *bp = dev->priv;
1580 int rx_done = 1;
1581 1863
1582 bp->last_status_idx = bp->status_blk->status_idx;
1583
1584 rmb();
1585 if ((bp->status_blk->status_attn_bits & 1864 if ((bp->status_blk->status_attn_bits &
1586 STATUS_ATTN_BITS_LINK_STATE) != 1865 STATUS_ATTN_BITS_LINK_STATE) !=
1587 (bp->status_blk->status_attn_bits_ack & 1866 (bp->status_blk->status_attn_bits_ack &
@@ -1592,11 +1871,10 @@ bnx2_poll(struct net_device *dev, int *budget)
1592 spin_unlock(&bp->phy_lock); 1871 spin_unlock(&bp->phy_lock);
1593 } 1872 }
1594 1873
1595 if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) { 1874 if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
1596 bnx2_tx_int(bp); 1875 bnx2_tx_int(bp);
1597 }
1598 1876
1599 if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) { 1877 if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) {
1600 int orig_budget = *budget; 1878 int orig_budget = *budget;
1601 int work_done; 1879 int work_done;
1602 1880
@@ -1606,13 +1884,12 @@ bnx2_poll(struct net_device *dev, int *budget)
1606 work_done = bnx2_rx_int(bp, orig_budget); 1884 work_done = bnx2_rx_int(bp, orig_budget);
1607 *budget -= work_done; 1885 *budget -= work_done;
1608 dev->quota -= work_done; 1886 dev->quota -= work_done;
1609
1610 if (work_done >= orig_budget) {
1611 rx_done = 0;
1612 }
1613 } 1887 }
1614 1888
1615 if (rx_done) { 1889 bp->last_status_idx = bp->status_blk->status_idx;
1890 rmb();
1891
1892 if (!bnx2_has_work(bp)) {
1616 netif_rx_complete(dev); 1893 netif_rx_complete(dev);
1617 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, 1894 REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
1618 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | 1895 BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
@@ -2383,21 +2660,27 @@ bnx2_init_nvram(struct bnx2 *bp)
2383 2660
2384 /* Flash interface has been reconfigured */ 2661 /* Flash interface has been reconfigured */
2385 for (j = 0, flash = &flash_table[0]; j < entry_count; 2662 for (j = 0, flash = &flash_table[0]; j < entry_count;
2386 j++, flash++) { 2663 j++, flash++) {
2387 2664 if ((val & FLASH_BACKUP_STRAP_MASK) ==
2388 if (val == flash->config1) { 2665 (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
2389 bp->flash_info = flash; 2666 bp->flash_info = flash;
2390 break; 2667 break;
2391 } 2668 }
2392 } 2669 }
2393 } 2670 }
2394 else { 2671 else {
2672 u32 mask;
2395 /* Not yet been reconfigured */ 2673 /* Not yet been reconfigured */
2396 2674
2675 if (val & (1 << 23))
2676 mask = FLASH_BACKUP_STRAP_MASK;
2677 else
2678 mask = FLASH_STRAP_MASK;
2679
2397 for (j = 0, flash = &flash_table[0]; j < entry_count; 2680 for (j = 0, flash = &flash_table[0]; j < entry_count;
2398 j++, flash++) { 2681 j++, flash++) {
2399 2682
2400 if ((val & FLASH_STRAP_MASK) == flash->strapping) { 2683 if ((val & mask) == (flash->strapping & mask)) {
2401 bp->flash_info = flash; 2684 bp->flash_info = flash;
2402 2685
2403 /* Request access to the flash interface. */ 2686 /* Request access to the flash interface. */
@@ -2424,7 +2707,7 @@ bnx2_init_nvram(struct bnx2 *bp)
2424 2707
2425 if (j == entry_count) { 2708 if (j == entry_count) {
2426 bp->flash_info = NULL; 2709 bp->flash_info = NULL;
2427 printk(KERN_ALERT "Unknown flash/EEPROM type.\n"); 2710 printk(KERN_ALERT PFX "Unknown flash/EEPROM type.\n");
2428 rc = -ENODEV; 2711 rc = -ENODEV;
2429 } 2712 }
2430 2713
@@ -2733,7 +3016,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
2733 3016
2734 /* Deposit a driver reset signature so the firmware knows that 3017 /* Deposit a driver reset signature so the firmware knows that
2735 * this is a soft reset. */ 3018 * this is a soft reset. */
2736 REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE, 3019 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
2737 BNX2_DRV_RESET_SIGNATURE_MAGIC); 3020 BNX2_DRV_RESET_SIGNATURE_MAGIC);
2738 3021
2739 bp->fw_timed_out = 0; 3022 bp->fw_timed_out = 0;
@@ -2962,6 +3245,7 @@ bnx2_init_tx_ring(struct bnx2 *bp)
2962 3245
2963 bp->tx_prod = 0; 3246 bp->tx_prod = 0;
2964 bp->tx_cons = 0; 3247 bp->tx_cons = 0;
3248 bp->hw_tx_cons = 0;
2965 bp->tx_prod_bseq = 0; 3249 bp->tx_prod_bseq = 0;
2966 3250
2967 val = BNX2_L2CTX_TYPE_TYPE_L2; 3251 val = BNX2_L2CTX_TYPE_TYPE_L2;
@@ -2994,6 +3278,7 @@ bnx2_init_rx_ring(struct bnx2 *bp)
2994 3278
2995 ring_prod = prod = bp->rx_prod = 0; 3279 ring_prod = prod = bp->rx_prod = 0;
2996 bp->rx_cons = 0; 3280 bp->rx_cons = 0;
3281 bp->hw_rx_cons = 0;
2997 bp->rx_prod_bseq = 0; 3282 bp->rx_prod_bseq = 0;
2998 3283
2999 rxbd = &bp->rx_desc_ring[0]; 3284 rxbd = &bp->rx_desc_ring[0];
@@ -3079,7 +3364,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
3079 struct sw_bd *rx_buf = &bp->rx_buf_ring[i]; 3364 struct sw_bd *rx_buf = &bp->rx_buf_ring[i];
3080 struct sk_buff *skb = rx_buf->skb; 3365 struct sk_buff *skb = rx_buf->skb;
3081 3366
3082 if (skb == 0) 3367 if (skb == NULL)
3083 continue; 3368 continue;
3084 3369
3085 pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping), 3370 pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
@@ -3234,7 +3519,7 @@ bnx2_test_registers(struct bnx2 *bp)
3234 { 0x1408, 0, 0x01c00800, 0x00000000 }, 3519 { 0x1408, 0, 0x01c00800, 0x00000000 },
3235 { 0x149c, 0, 0x8000ffff, 0x00000000 }, 3520 { 0x149c, 0, 0x8000ffff, 0x00000000 },
3236 { 0x14a8, 0, 0x00000000, 0x000001ff }, 3521 { 0x14a8, 0, 0x00000000, 0x000001ff },
3237 { 0x14ac, 0, 0x4fffffff, 0x10000000 }, 3522 { 0x14ac, 0, 0x0fffffff, 0x10000000 },
3238 { 0x14b0, 0, 0x00000002, 0x00000001 }, 3523 { 0x14b0, 0, 0x00000002, 0x00000001 },
3239 { 0x14b8, 0, 0x00000000, 0x00000000 }, 3524 { 0x14b8, 0, 0x00000000, 0x00000000 },
3240 { 0x14c0, 0, 0x00000000, 0x00000009 }, 3525 { 0x14c0, 0, 0x00000000, 0x00000009 },
@@ -3577,7 +3862,7 @@ bnx2_test_memory(struct bnx2 *bp)
3577 u32 len; 3862 u32 len;
3578 } mem_tbl[] = { 3863 } mem_tbl[] = {
3579 { 0x60000, 0x4000 }, 3864 { 0x60000, 0x4000 },
3580 { 0xa0000, 0x4000 }, 3865 { 0xa0000, 0x3000 },
3581 { 0xe0000, 0x4000 }, 3866 { 0xe0000, 0x4000 },
3582 { 0x120000, 0x4000 }, 3867 { 0x120000, 0x4000 },
3583 { 0x1a0000, 0x4000 }, 3868 { 0x1a0000, 0x4000 },
@@ -3618,6 +3903,8 @@ bnx2_test_loopback(struct bnx2 *bp)
3618 3903
3619 pkt_size = 1514; 3904 pkt_size = 1514;
3620 skb = dev_alloc_skb(pkt_size); 3905 skb = dev_alloc_skb(pkt_size);
3906 if (!skb)
3907 return -ENOMEM;
3621 packet = skb_put(skb, pkt_size); 3908 packet = skb_put(skb, pkt_size);
3622 memcpy(packet, bp->mac_addr, 6); 3909 memcpy(packet, bp->mac_addr, 6);
3623 memset(packet + 6, 0x0, 8); 3910 memset(packet + 6, 0x0, 8);
@@ -3810,7 +4097,7 @@ bnx2_timer(unsigned long data)
3810 goto bnx2_restart_timer; 4097 goto bnx2_restart_timer;
3811 4098
3812 msg = (u32) ++bp->fw_drv_pulse_wr_seq; 4099 msg = (u32) ++bp->fw_drv_pulse_wr_seq;
3813 REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg); 4100 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
3814 4101
3815 if ((bp->phy_flags & PHY_SERDES_FLAG) && 4102 if ((bp->phy_flags & PHY_SERDES_FLAG) &&
3816 (CHIP_NUM(bp) == CHIP_NUM_5706)) { 4103 (CHIP_NUM(bp) == CHIP_NUM_5706)) {
@@ -4264,7 +4551,8 @@ bnx2_get_stats(struct net_device *dev)
4264 (unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions + 4551 (unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions +
4265 stats_blk->stat_Dot3StatsLateCollisions); 4552 stats_blk->stat_Dot3StatsLateCollisions);
4266 4553
4267 if (CHIP_NUM(bp) == CHIP_NUM_5706) 4554 if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
4555 (CHIP_ID(bp) == CHIP_ID_5708_A0))
4268 net_stats->tx_carrier_errors = 0; 4556 net_stats->tx_carrier_errors = 0;
4269 else { 4557 else {
4270 net_stats->tx_carrier_errors = 4558 net_stats->tx_carrier_errors =
@@ -4512,11 +4800,7 @@ bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
4512 struct bnx2 *bp = dev->priv; 4800 struct bnx2 *bp = dev->priv;
4513 int rc; 4801 int rc;
4514 4802
4515 if (eeprom->offset > bp->flash_info->total_size) 4803 /* parameters already validated in ethtool_get_eeprom */
4516 return -EINVAL;
4517
4518 if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
4519 eeprom->len = bp->flash_info->total_size - eeprom->offset;
4520 4804
4521 rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len); 4805 rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len);
4522 4806
@@ -4530,11 +4814,7 @@ bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
4530 struct bnx2 *bp = dev->priv; 4814 struct bnx2 *bp = dev->priv;
4531 int rc; 4815 int rc;
4532 4816
4533 if (eeprom->offset > bp->flash_info->total_size) 4817 /* parameters already validated in ethtool_set_eeprom */
4534 return -EINVAL;
4535
4536 if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size)
4537 eeprom->len = bp->flash_info->total_size - eeprom->offset;
4538 4818
4539 rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); 4819 rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len);
4540 4820
@@ -4814,6 +5094,14 @@ static u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
4814 4,4,4,4,4, 5094 4,4,4,4,4,
4815}; 5095};
4816 5096
5097static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = {
5098 8,0,8,8,8,8,8,8,8,8,
5099 4,4,4,4,4,4,4,4,4,4,
5100 4,4,4,4,4,4,4,4,4,4,
5101 4,4,4,4,4,4,4,4,4,4,
5102 4,4,4,4,4,
5103};
5104
4817#define BNX2_NUM_TESTS 6 5105#define BNX2_NUM_TESTS 6
4818 5106
4819static struct { 5107static struct {
@@ -4922,8 +5210,13 @@ bnx2_get_ethtool_stats(struct net_device *dev,
4922 return; 5210 return;
4923 } 5211 }
4924 5212
4925 if (CHIP_NUM(bp) == CHIP_NUM_5706) 5213 if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
5214 (CHIP_ID(bp) == CHIP_ID_5706_A1) ||
5215 (CHIP_ID(bp) == CHIP_ID_5706_A2) ||
5216 (CHIP_ID(bp) == CHIP_ID_5708_A0))
4926 stats_len_arr = bnx2_5706_stats_len_arr; 5217 stats_len_arr = bnx2_5706_stats_len_arr;
5218 else
5219 stats_len_arr = bnx2_5708_stats_len_arr;
4927 5220
4928 for (i = 0; i < BNX2_NUM_STATS; i++) { 5221 for (i = 0; i < BNX2_NUM_STATS; i++) {
4929 if (stats_len_arr[i] == 0) { 5222 if (stats_len_arr[i] == 0) {
@@ -5205,8 +5498,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5205 5498
5206 bp->chip_id = REG_RD(bp, BNX2_MISC_ID); 5499 bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
5207 5500
5208 bp->phy_addr = 1;
5209
5210 /* Get bus information. */ 5501 /* Get bus information. */
5211 reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); 5502 reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
5212 if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { 5503 if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
@@ -5269,10 +5560,18 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5269 5560
5270 bnx2_init_nvram(bp); 5561 bnx2_init_nvram(bp);
5271 5562
5563 reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);
5564
5565 if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
5566 BNX2_SHM_HDR_SIGNATURE_SIG)
5567 bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0);
5568 else
5569 bp->shmem_base = HOST_VIEW_SHMEM_BASE;
5570
5272 /* Get the permanent MAC address. First we need to make sure the 5571 /* Get the permanent MAC address. First we need to make sure the
5273 * firmware is actually running. 5572 * firmware is actually running.
5274 */ 5573 */
5275 reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE); 5574 reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);
5276 5575
5277 if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) != 5576 if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
5278 BNX2_DEV_INFO_SIGNATURE_MAGIC) { 5577 BNX2_DEV_INFO_SIGNATURE_MAGIC) {
@@ -5281,14 +5580,13 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5281 goto err_out_unmap; 5580 goto err_out_unmap;
5282 } 5581 }
5283 5582
5284 bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + 5583 bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
5285 BNX2_DEV_INFO_BC_REV);
5286 5584
5287 reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER); 5585 reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
5288 bp->mac_addr[0] = (u8) (reg >> 8); 5586 bp->mac_addr[0] = (u8) (reg >> 8);
5289 bp->mac_addr[1] = (u8) reg; 5587 bp->mac_addr[1] = (u8) reg;
5290 5588
5291 reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER); 5589 reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
5292 bp->mac_addr[2] = (u8) (reg >> 24); 5590 bp->mac_addr[2] = (u8) (reg >> 24);
5293 bp->mac_addr[3] = (u8) (reg >> 16); 5591 bp->mac_addr[3] = (u8) (reg >> 16);
5294 bp->mac_addr[4] = (u8) (reg >> 8); 5592 bp->mac_addr[4] = (u8) (reg >> 8);
@@ -5316,10 +5614,19 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5316 bp->timer_interval = HZ; 5614 bp->timer_interval = HZ;
5317 bp->current_interval = HZ; 5615 bp->current_interval = HZ;
5318 5616
5617 bp->phy_addr = 1;
5618
5319 /* Disable WOL support if we are running on a SERDES chip. */ 5619 /* Disable WOL support if we are running on a SERDES chip. */
5320 if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { 5620 if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
5321 bp->phy_flags |= PHY_SERDES_FLAG; 5621 bp->phy_flags |= PHY_SERDES_FLAG;
5322 bp->flags |= NO_WOL_FLAG; 5622 bp->flags |= NO_WOL_FLAG;
5623 if (CHIP_NUM(bp) == CHIP_NUM_5708) {
5624 bp->phy_addr = 2;
5625 reg = REG_RD_IND(bp, bp->shmem_base +
5626 BNX2_SHARED_HW_CFG_CONFIG);
5627 if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
5628 bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
5629 }
5323 } 5630 }
5324 5631
5325 if (CHIP_ID(bp) == CHIP_ID_5706_A0) { 5632 if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
@@ -5339,8 +5646,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5339 if (bp->phy_flags & PHY_SERDES_FLAG) { 5646 if (bp->phy_flags & PHY_SERDES_FLAG) {
5340 bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; 5647 bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
5341 5648
5342 reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + 5649 reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
5343 BNX2_PORT_HW_CFG_CONFIG);
5344 reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK; 5650 reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
5345 if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) { 5651 if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
5346 bp->autoneg = 0; 5652 bp->autoneg = 0;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 62857b6a6ee4..76bb5f1a250b 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -1449,8 +1449,9 @@ struct l2_fhdr {
1449#define BNX2_EMAC_MODE_PORT_NONE (0L<<2) 1449#define BNX2_EMAC_MODE_PORT_NONE (0L<<2)
1450#define BNX2_EMAC_MODE_PORT_MII (1L<<2) 1450#define BNX2_EMAC_MODE_PORT_MII (1L<<2)
1451#define BNX2_EMAC_MODE_PORT_GMII (2L<<2) 1451#define BNX2_EMAC_MODE_PORT_GMII (2L<<2)
1452#define BNX2_EMAC_MODE_PORT_UNDEF (3L<<2) 1452#define BNX2_EMAC_MODE_PORT_MII_10 (3L<<2)
1453#define BNX2_EMAC_MODE_MAC_LOOP (1L<<4) 1453#define BNX2_EMAC_MODE_MAC_LOOP (1L<<4)
1454#define BNX2_EMAC_MODE_25G (1L<<5)
1454#define BNX2_EMAC_MODE_TAGGED_MAC_CTL (1L<<7) 1455#define BNX2_EMAC_MODE_TAGGED_MAC_CTL (1L<<7)
1455#define BNX2_EMAC_MODE_TX_BURST (1L<<8) 1456#define BNX2_EMAC_MODE_TX_BURST (1L<<8)
1456#define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA (1L<<9) 1457#define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA (1L<<9)
@@ -3714,6 +3715,15 @@ struct l2_fhdr {
3714#define BNX2_MCP_ROM 0x00150000 3715#define BNX2_MCP_ROM 0x00150000
3715#define BNX2_MCP_SCRATCH 0x00160000 3716#define BNX2_MCP_SCRATCH 0x00160000
3716 3717
3718#define BNX2_SHM_HDR_SIGNATURE BNX2_MCP_SCRATCH
3719#define BNX2_SHM_HDR_SIGNATURE_SIG_MASK 0xffff0000
3720#define BNX2_SHM_HDR_SIGNATURE_SIG 0x53530000
3721#define BNX2_SHM_HDR_SIGNATURE_VER_MASK 0x000000ff
3722#define BNX2_SHM_HDR_SIGNATURE_VER_ONE 0x00000001
3723
3724#define BNX2_SHM_HDR_ADDR_0 BNX2_MCP_SCRATCH + 4
3725#define BNX2_SHM_HDR_ADDR_1 BNX2_MCP_SCRATCH + 8
3726
3717 3727
3718#define NUM_MC_HASH_REGISTERS 8 3728#define NUM_MC_HASH_REGISTERS 8
3719 3729
@@ -3724,6 +3734,53 @@ struct l2_fhdr {
3724#define PHY_ID(id) ((id) & 0xfffffff0) 3734#define PHY_ID(id) ((id) & 0xfffffff0)
3725#define PHY_REV_ID(id) ((id) & 0xf) 3735#define PHY_REV_ID(id) ((id) & 0xf)
3726 3736
3737/* 5708 Serdes PHY registers */
3738
3739#define BCM5708S_UP1 0xb
3740
3741#define BCM5708S_UP1_2G5 0x1
3742
3743#define BCM5708S_BLK_ADDR 0x1f
3744
3745#define BCM5708S_BLK_ADDR_DIG 0x0000
3746#define BCM5708S_BLK_ADDR_DIG3 0x0002
3747#define BCM5708S_BLK_ADDR_TX_MISC 0x0005
3748
3749/* Digital Block */
3750#define BCM5708S_1000X_CTL1 0x10
3751
3752#define BCM5708S_1000X_CTL1_FIBER_MODE 0x0001
3753#define BCM5708S_1000X_CTL1_AUTODET_EN 0x0010
3754
3755#define BCM5708S_1000X_CTL2 0x11
3756
3757#define BCM5708S_1000X_CTL2_PLLEL_DET_EN 0x0001
3758
3759#define BCM5708S_1000X_STAT1 0x14
3760
3761#define BCM5708S_1000X_STAT1_SGMII 0x0001
3762#define BCM5708S_1000X_STAT1_LINK 0x0002
3763#define BCM5708S_1000X_STAT1_FD 0x0004
3764#define BCM5708S_1000X_STAT1_SPEED_MASK 0x0018
3765#define BCM5708S_1000X_STAT1_SPEED_10 0x0000
3766#define BCM5708S_1000X_STAT1_SPEED_100 0x0008
3767#define BCM5708S_1000X_STAT1_SPEED_1G 0x0010
3768#define BCM5708S_1000X_STAT1_SPEED_2G5 0x0018
3769#define BCM5708S_1000X_STAT1_TX_PAUSE 0x0020
3770#define BCM5708S_1000X_STAT1_RX_PAUSE 0x0040
3771
3772/* Digital3 Block */
3773#define BCM5708S_DIG_3_0 0x10
3774
3775#define BCM5708S_DIG_3_0_USE_IEEE 0x0001
3776
3777/* Tx/Misc Block */
3778#define BCM5708S_TX_ACTL1 0x15
3779
3780#define BCM5708S_TX_ACTL1_DRIVER_VCM 0x30
3781
3782#define BCM5708S_TX_ACTL3 0x17
3783
3727#define MIN_ETHERNET_PACKET_SIZE 60 3784#define MIN_ETHERNET_PACKET_SIZE 60
3728#define MAX_ETHERNET_PACKET_SIZE 1514 3785#define MAX_ETHERNET_PACKET_SIZE 1514
3729#define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014 3786#define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014
@@ -3799,7 +3856,7 @@ struct sw_bd {
3799#define BUFFERED_FLASH_PHY_PAGE_SIZE (1 << BUFFERED_FLASH_PAGE_BITS) 3856#define BUFFERED_FLASH_PHY_PAGE_SIZE (1 << BUFFERED_FLASH_PAGE_BITS)
3800#define BUFFERED_FLASH_BYTE_ADDR_MASK (BUFFERED_FLASH_PHY_PAGE_SIZE-1) 3857#define BUFFERED_FLASH_BYTE_ADDR_MASK (BUFFERED_FLASH_PHY_PAGE_SIZE-1)
3801#define BUFFERED_FLASH_PAGE_SIZE 264 3858#define BUFFERED_FLASH_PAGE_SIZE 264
3802#define BUFFERED_FLASH_TOTAL_SIZE 131072 3859#define BUFFERED_FLASH_TOTAL_SIZE 0x21000
3803 3860
3804#define SAIFUN_FLASH_PAGE_BITS 8 3861#define SAIFUN_FLASH_PAGE_BITS 8
3805#define SAIFUN_FLASH_PHY_PAGE_SIZE (1 << SAIFUN_FLASH_PAGE_BITS) 3862#define SAIFUN_FLASH_PHY_PAGE_SIZE (1 << SAIFUN_FLASH_PAGE_BITS)
@@ -3807,6 +3864,12 @@ struct sw_bd {
3807#define SAIFUN_FLASH_PAGE_SIZE 256 3864#define SAIFUN_FLASH_PAGE_SIZE 256
3808#define SAIFUN_FLASH_BASE_TOTAL_SIZE 65536 3865#define SAIFUN_FLASH_BASE_TOTAL_SIZE 65536
3809 3866
3867#define ST_MICRO_FLASH_PAGE_BITS 8
3868#define ST_MICRO_FLASH_PHY_PAGE_SIZE (1 << ST_MICRO_FLASH_PAGE_BITS)
3869#define ST_MICRO_FLASH_BYTE_ADDR_MASK (ST_MICRO_FLASH_PHY_PAGE_SIZE-1)
3870#define ST_MICRO_FLASH_PAGE_SIZE 256
3871#define ST_MICRO_FLASH_BASE_TOTAL_SIZE 65536
3872
3810#define NVRAM_TIMEOUT_COUNT 30000 3873#define NVRAM_TIMEOUT_COUNT 30000
3811 3874
3812 3875
@@ -3815,6 +3878,8 @@ struct sw_bd {
3815 BNX2_NVM_CFG1_PROTECT_MODE | \ 3878 BNX2_NVM_CFG1_PROTECT_MODE | \
3816 BNX2_NVM_CFG1_FLASH_SIZE) 3879 BNX2_NVM_CFG1_FLASH_SIZE)
3817 3880
3881#define FLASH_BACKUP_STRAP_MASK (0xf << 26)
3882
3818struct flash_spec { 3883struct flash_spec {
3819 u32 strapping; 3884 u32 strapping;
3820 u32 config1; 3885 u32 config1;
@@ -3849,6 +3914,9 @@ struct bnx2 {
3849 u16 tx_cons; 3914 u16 tx_cons;
3850 int tx_ring_size; 3915 int tx_ring_size;
3851 3916
3917 u16 hw_tx_cons;
3918 u16 hw_rx_cons;
3919
3852#ifdef BCM_VLAN 3920#ifdef BCM_VLAN
3853 struct vlan_group *vlgrp; 3921 struct vlan_group *vlgrp;
3854#endif 3922#endif
@@ -3893,6 +3961,7 @@ struct bnx2 {
3893#define PHY_SERDES_FLAG 1 3961#define PHY_SERDES_FLAG 1
3894#define PHY_CRC_FIX_FLAG 2 3962#define PHY_CRC_FIX_FLAG 2
3895#define PHY_PARALLEL_DETECT_FLAG 4 3963#define PHY_PARALLEL_DETECT_FLAG 4
3964#define PHY_2_5G_CAPABLE_FLAG 8
3896#define PHY_INT_MODE_MASK_FLAG 0x300 3965#define PHY_INT_MODE_MASK_FLAG 0x300
3897#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100 3966#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100
3898#define PHY_INT_MODE_LINK_READY_FLAG 0x200 3967#define PHY_INT_MODE_LINK_READY_FLAG 0x200
@@ -3901,6 +3970,7 @@ struct bnx2 {
3901 /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ 3970 /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
3902#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000) 3971#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000)
3903#define CHIP_NUM_5706 0x57060000 3972#define CHIP_NUM_5706 0x57060000
3973#define CHIP_NUM_5708 0x57080000
3904 3974
3905#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000) 3975#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000)
3906#define CHIP_REV_Ax 0x00000000 3976#define CHIP_REV_Ax 0x00000000
@@ -3913,6 +3983,9 @@ struct bnx2 {
3913#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0) 3983#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0)
3914#define CHIP_ID_5706_A0 0x57060000 3984#define CHIP_ID_5706_A0 0x57060000
3915#define CHIP_ID_5706_A1 0x57060010 3985#define CHIP_ID_5706_A1 0x57060010
3986#define CHIP_ID_5706_A2 0x57060020
3987#define CHIP_ID_5708_A0 0x57080000
3988#define CHIP_ID_5708_B0 0x57081000
3916 3989
3917#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf) 3990#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf)
3918 3991
@@ -3991,6 +4064,8 @@ struct bnx2 {
3991 4064
3992 u8 mac_addr[8]; 4065 u8 mac_addr[8];
3993 4066
4067 u32 shmem_base;
4068
3994 u32 fw_ver; 4069 u32 fw_ver;
3995 4070
3996 int pm_cap; 4071 int pm_cap;
@@ -4130,14 +4205,46 @@ struct fw_info {
4130#define BNX2_FW_MSG_STATUS_FAILURE 0x00ff0000 4205#define BNX2_FW_MSG_STATUS_FAILURE 0x00ff0000
4131 4206
4132#define BNX2_LINK_STATUS 0x0000000c 4207#define BNX2_LINK_STATUS 0x0000000c
4208#define BNX2_LINK_STATUS_INIT_VALUE 0xffffffff
4209#define BNX2_LINK_STATUS_LINK_UP 0x1
4210#define BNX2_LINK_STATUS_LINK_DOWN 0x0
4211#define BNX2_LINK_STATUS_SPEED_MASK 0x1e
4212#define BNX2_LINK_STATUS_AN_INCOMPLETE (0<<1)
4213#define BNX2_LINK_STATUS_10HALF (1<<1)
4214#define BNX2_LINK_STATUS_10FULL (2<<1)
4215#define BNX2_LINK_STATUS_100HALF (3<<1)
4216#define BNX2_LINK_STATUS_100BASE_T4 (4<<1)
4217#define BNX2_LINK_STATUS_100FULL (5<<1)
4218#define BNX2_LINK_STATUS_1000HALF (6<<1)
4219#define BNX2_LINK_STATUS_1000FULL (7<<1)
4220#define BNX2_LINK_STATUS_2500HALF (8<<1)
4221#define BNX2_LINK_STATUS_2500FULL (9<<1)
4222#define BNX2_LINK_STATUS_AN_ENABLED (1<<5)
4223#define BNX2_LINK_STATUS_AN_COMPLETE (1<<6)
4224#define BNX2_LINK_STATUS_PARALLEL_DET (1<<7)
4225#define BNX2_LINK_STATUS_RESERVED (1<<8)
4226#define BNX2_LINK_STATUS_PARTNER_AD_1000FULL (1<<9)
4227#define BNX2_LINK_STATUS_PARTNER_AD_1000HALF (1<<10)
4228#define BNX2_LINK_STATUS_PARTNER_AD_100BT4 (1<<11)
4229#define BNX2_LINK_STATUS_PARTNER_AD_100FULL (1<<12)
4230#define BNX2_LINK_STATUS_PARTNER_AD_100HALF (1<<13)
4231#define BNX2_LINK_STATUS_PARTNER_AD_10FULL (1<<14)
4232#define BNX2_LINK_STATUS_PARTNER_AD_10HALF (1<<15)
4233#define BNX2_LINK_STATUS_TX_FC_ENABLED (1<<16)
4234#define BNX2_LINK_STATUS_RX_FC_ENABLED (1<<17)
4235#define BNX2_LINK_STATUS_PARTNER_SYM_PAUSE_CAP (1<<18)
4236#define BNX2_LINK_STATUS_PARTNER_ASYM_PAUSE_CAP (1<<19)
4237#define BNX2_LINK_STATUS_SERDES_LINK (1<<20)
4238#define BNX2_LINK_STATUS_PARTNER_AD_2500FULL (1<<21)
4239#define BNX2_LINK_STATUS_PARTNER_AD_2500HALF (1<<22)
4133 4240
4134#define BNX2_DRV_PULSE_MB 0x00000010 4241#define BNX2_DRV_PULSE_MB 0x00000010
4135#define BNX2_DRV_PULSE_SEQ_MASK 0x0000ffff 4242#define BNX2_DRV_PULSE_SEQ_MASK 0x00007fff
4136 4243
4137/* Indicate to the firmware not to go into the 4244/* Indicate to the firmware not to go into the
4138 * OS absent when it is not getting driver pulse. 4245 * OS absent when it is not getting driver pulse.
4139 * This is used for debugging. */ 4246 * This is used for debugging. */
4140#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE 0x00010000 4247#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE 0x00080000
4141 4248
4142#define BNX2_DEV_INFO_SIGNATURE 0x00000020 4249#define BNX2_DEV_INFO_SIGNATURE 0x00000020
4143#define BNX2_DEV_INFO_SIGNATURE_MAGIC 0x44564900 4250#define BNX2_DEV_INFO_SIGNATURE_MAGIC 0x44564900
@@ -4160,6 +4267,8 @@ struct fw_info {
4160#define BNX2_SHARED_HW_CFG_DESIGN_LOM 0x1 4267#define BNX2_SHARED_HW_CFG_DESIGN_LOM 0x1
4161#define BNX2_SHARED_HW_CFG_PHY_COPPER 0 4268#define BNX2_SHARED_HW_CFG_PHY_COPPER 0
4162#define BNX2_SHARED_HW_CFG_PHY_FIBER 0x2 4269#define BNX2_SHARED_HW_CFG_PHY_FIBER 0x2
4270#define BNX2_SHARED_HW_CFG_PHY_2_5G 0x20
4271#define BNX2_SHARED_HW_CFG_PHY_BACKPLANE 0x40
4163#define BNX2_SHARED_HW_CFG_LED_MODE_SHIFT_BITS 8 4272#define BNX2_SHARED_HW_CFG_LED_MODE_SHIFT_BITS 8
4164#define BNX2_SHARED_HW_CFG_LED_MODE_MASK 0x300 4273#define BNX2_SHARED_HW_CFG_LED_MODE_MASK 0x300
4165#define BNX2_SHARED_HW_CFG_LED_MODE_MAC 0 4274#define BNX2_SHARED_HW_CFG_LED_MODE_MAC 0
@@ -4173,9 +4282,11 @@ struct fw_info {
4173 4282
4174#define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054 4283#define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054
4175#define BNX2_PORT_HW_CFG_CONFIG 0x00000058 4284#define BNX2_PORT_HW_CFG_CONFIG 0x00000058
4285#define BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK 0x0000ffff
4176#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000 4286#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000
4177#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000 4287#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000
4178#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000 4288#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000
4289#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_2_5G 0x00040000
4179 4290
4180#define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068 4291#define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068
4181#define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c 4292#define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index 35f3a2ae5ef1..ab07a4900e9a 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -14,24 +14,23 @@
14 * accompanying it. 14 * accompanying it.
15 */ 15 */
16 16
17 17static int bnx2_COM_b06FwReleaseMajor = 0x1;
18static int bnx2_COM_b06FwReleaseMajor = 0x0;
19static int bnx2_COM_b06FwReleaseMinor = 0x0; 18static int bnx2_COM_b06FwReleaseMinor = 0x0;
20static int bnx2_COM_b06FwReleaseFix = 0x0; 19static int bnx2_COM_b06FwReleaseFix = 0x0;
21static u32 bnx2_COM_b06FwStartAddr = 0x080004a0; 20static u32 bnx2_COM_b06FwStartAddr = 0x080008b4;
22static u32 bnx2_COM_b06FwTextAddr = 0x08000000; 21static u32 bnx2_COM_b06FwTextAddr = 0x08000000;
23static int bnx2_COM_b06FwTextLen = 0x4594; 22static int bnx2_COM_b06FwTextLen = 0x57bc;
24static u32 bnx2_COM_b06FwDataAddr = 0x080045e0; 23static u32 bnx2_COM_b06FwDataAddr = 0x08005840;
25static int bnx2_COM_b06FwDataLen = 0x0; 24static int bnx2_COM_b06FwDataLen = 0x0;
26static u32 bnx2_COM_b06FwRodataAddr = 0x08004598; 25static u32 bnx2_COM_b06FwRodataAddr = 0x080057c0;
27static int bnx2_COM_b06FwRodataLen = 0x18; 26static int bnx2_COM_b06FwRodataLen = 0x58;
28static u32 bnx2_COM_b06FwBssAddr = 0x08004600; 27static u32 bnx2_COM_b06FwBssAddr = 0x08005860;
29static int bnx2_COM_b06FwBssLen = 0x88; 28static int bnx2_COM_b06FwBssLen = 0x88;
30static u32 bnx2_COM_b06FwSbssAddr = 0x080045e0; 29static u32 bnx2_COM_b06FwSbssAddr = 0x08005840;
31static int bnx2_COM_b06FwSbssLen = 0x1c; 30static int bnx2_COM_b06FwSbssLen = 0x1c;
32static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = { 31static u32 bnx2_COM_b06FwText[(0x57bc/4) + 1] = {
33 0x0a000128, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x302e362e, 32 0x0a00022d, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x322e352e,
34 0x39000000, 0x00060902, 0x00000000, 0x00000003, 0x00000014, 0x00000032, 33 0x38000000, 0x02050802, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
35 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 34 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
36 0x00000010, 0x000003e8, 0x0000ea60, 0x00000001, 0x00000000, 0x00000000, 35 0x00000010, 0x000003e8, 0x0000ea60, 0x00000001, 0x00000000, 0x00000000,
37 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 36 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -79,70 +78,117 @@ static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = {
79 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 78 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
80 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 79 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
81 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 80 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
82 0x00000000, 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 81 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
83 0x0000000d, 0x3c020800, 0x244245e0, 0x3c030800, 0x24634688, 0xac400000, 82 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
84 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 83 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
85 0x3c100800, 0x261004a0, 0x3c1c0800, 0x279c45e0, 0x0e0001f2, 0x00000000, 84 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
86 0x0000000d, 0x27bdffe8, 0x3c1a8000, 0x3c020008, 0x0342d825, 0x3c036010, 85 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
87 0xafbf0010, 0x8c655000, 0x3c020800, 0x24470ac8, 0x3c040800, 0x24864600, 86 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
88 0x2402ff7f, 0x00a22824, 0x34a5380c, 0xac655000, 0x00002821, 0x24020037, 87 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
89 0x24030c80, 0xaf420008, 0xaf430024, 0xacc70000, 0x24a50001, 0x2ca20016, 88 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
90 0x1440fffc, 0x24c60004, 0x24844600, 0x3c020800, 0x24420ad4, 0x3c030800, 89 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
91 0x246309d4, 0xac820004, 0x3c020800, 0x24420618, 0x3c050800, 0x24a50ca0, 90 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
92 0xac82000c, 0x3c020800, 0x24423100, 0xac830008, 0x3c030800, 0x246325c8, 91 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
93 0xac820014, 0x3c020800, 0x24422b0c, 0xac830018, 0xac83001c, 0x3c030800, 92 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
94 0x24630adc, 0xac820024, 0x3c020800, 0x24423040, 0xac83002c, 0x3c030800, 93 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
95 0x24633060, 0xac820030, 0x3c020800, 0x24422f6c, 0xac830034, 0x3c030800, 94 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
96 0x24632c60, 0xac82003c, 0x3c020800, 0x24420b6c, 0xac850010, 0xac850020, 95 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
97 0xac830040, 0x0e000bd6, 0xac820050, 0x8fbf0010, 0x03e00008, 0x27bd0018, 96 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
98 0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014, 0x9203000b, 97 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
99 0x24020003, 0x1462005b, 0x96110008, 0x32220001, 0x10400009, 0x27430080, 98 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
100 0x8e020000, 0x96040014, 0x000211c2, 0x00021040, 0x00621821, 0xa4640000, 99 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
101 0x0a0001cb, 0x3c020800, 0x3c020800, 0x8c430020, 0x1060002a, 0x3c030800, 100 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
102 0x0e001006, 0x00000000, 0x97420108, 0x8f850018, 0x9743010c, 0x3042003e, 101 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
103 0x00021400, 0x00621825, 0xaca30000, 0x8f840018, 0x8f420100, 0xac820004, 102 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
104 0x97430116, 0x9742010e, 0x8f840018, 0x00031c00, 0x00431025, 0xac820008, 103 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
105 0x97430110, 0x97440112, 0x8f850018, 0x00031c00, 0x00832025, 0xaca4000c, 104 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
106 0x97420114, 0x8f840018, 0x3042ffff, 0xac820010, 0x8f830018, 0xac600014, 105 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
107 0x8f820018, 0x3c030800, 0xac400018, 0x9462466e, 0x8f840018, 0x3c032000, 106 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
108 0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x3c030800, 0x8c620040, 107 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
109 0x24420001, 0xac620040, 0x3c020800, 0x8c430044, 0x32240004, 0x24630001, 108 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
110 0x10800017, 0xac430044, 0x8f4202b8, 0x04430007, 0x8e020020, 0x3c040800, 109 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
111 0x8c830060, 0x24020001, 0x24630001, 0x0a0001ed, 0xac830060, 0x3c060800, 110 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
112 0x8cc4005c, 0xaf420280, 0x96030016, 0x00001021, 0xa7430284, 0x8e050004, 111 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
113 0x24840001, 0x3c031000, 0xaf450288, 0xaf4302b8, 0x0a0001ed, 0xacc4005c, 112 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
114 0x32220002, 0x0a0001ed, 0x0002102b, 0x3c026000, 0xac400808, 0x0000000d, 113 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
115 0x00001021, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 114 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
116 0x27bdffc8, 0xafbf0034, 0xafbe0030, 0xafb7002c, 0xafb60028, 0xafb50024, 115 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
117 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0x0e00013f, 0xafb00010, 116 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
118 0x24110020, 0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800, 117 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
119 0x3c170800, 0x3c160800, 0x8f820004, 0x3c040800, 0x8c830020, 0x10430004, 118 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
120 0x00000000, 0xaf830004, 0x0e00110b, 0x00000000, 0x8f500000, 0x32020007, 119 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
121 0x1040fff5, 0x32020001, 0x1040002b, 0x32020002, 0x8f420100, 0xaf420020, 120 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
122 0x8f430104, 0xaf4300a8, 0x9342010b, 0x93630000, 0x306300ff, 0x10710005, 121 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
123 0x304400ff, 0x10750006, 0x2c820016, 0x0a000227, 0x00000000, 0xaf940000, 122 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
124 0x0a000228, 0x2c820016, 0xaf930000, 0x0a000228, 0x00000000, 0xaf800000, 123 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
125 0x14400005, 0x00041880, 0x0e0002b2, 0x00000000, 0x0a000234, 0x00000000, 124 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
126 0x3c020800, 0x24424600, 0x00621821, 0x8c620000, 0x0040f809, 0x00000000, 125 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425840,
127 0x10400005, 0x8fc20034, 0x8f420104, 0x3c016020, 0xac220014, 0x8fc20034, 126 0x3c030800, 0x246358e8, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004,
128 0xaf520138, 0x24420001, 0xafc20034, 0x32020002, 0x10400019, 0x32020004, 127 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261008b4, 0x3c1c0800,
129 0x8f420140, 0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000, 128 0x279c5840, 0x0e0002f7, 0x00000000, 0x0000000d, 0x27bdffe8, 0x3c1a8000,
130 0x10750006, 0x00000000, 0x0a000250, 0x00000000, 0xaf940000, 0x0a000251, 129 0x3c020008, 0x0342d825, 0x3c036010, 0xafbf0010, 0x8c655000, 0x3c020800,
131 0x00000000, 0xaf930000, 0x0a000251, 0x00000000, 0xaf800000, 0x0e0008b9, 130 0x24470f30, 0x3c040800, 0x24865860, 0x2402ff7f, 0x00a22824, 0x34a5380c,
132 0x00000000, 0x8ee20038, 0xaf520178, 0x24420001, 0xaee20038, 0x32020004, 131 0xac655000, 0x00002821, 0x24020037, 0x24030c80, 0xaf420008, 0xaf430024,
133 0x1040ffad, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff, 132 0xacc70000, 0x24a50001, 0x2ca20016, 0x1440fffc, 0x24c60004, 0x24845860,
134 0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a00026a, 0x00000000, 133 0x3c020800, 0x24420f3c, 0x3c030800, 0x24630e2c, 0xac820004, 0x3c020800,
135 0xaf940000, 0x0a00026b, 0x00000000, 0xaf930000, 0x0a00026b, 0x00000000, 134 0x24420a2c, 0x3c050800, 0x24a51268, 0xac82000c, 0x3c020800, 0x244243dc,
136 0xaf800000, 0x93620000, 0x14510004, 0x8ec2003c, 0x0e000835, 0x00000000, 135 0xac830008, 0x3c030800, 0x24633698, 0xac820014, 0x3c020800, 0x24423c24,
137 0x8ec2003c, 0xaf5201b8, 0x24420001, 0x0a000206, 0xaec2003c, 0x27bdffe8, 136 0xac830018, 0xac83001c, 0x3c030800, 0x24630f44, 0xac820024, 0x3c020800,
138 0xafbf0010, 0x97420108, 0x24033000, 0x30447000, 0x10830012, 0x28823001, 137 0x244243ac, 0xac83002c, 0x3c030800, 0x246343cc, 0xac820030, 0x3c020800,
139 0x10400007, 0x24024000, 0x1080000b, 0x24022000, 0x1082001a, 0x24020001, 138 0x244242f0, 0xac830034, 0x3c030800, 0x24633d78, 0xac82003c, 0x3c020800,
140 0x0a000299, 0x00000000, 0x1082000c, 0x24025000, 0x1082000e, 0x00000000, 139 0x24420fd4, 0xac850010, 0xac850020, 0xac830040, 0x0e0010b7, 0xac820050,
141 0x0a000299, 0x00000000, 0x0000000d, 0x0a00029b, 0x00001021, 0x0e000300, 140 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafb00010, 0x27500100,
142 0x00000000, 0x0a00029b, 0x00001021, 0x0e00048f, 0x00000000, 0x0a00029b, 141 0xafbf0018, 0xafb10014, 0x9203000b, 0x24020003, 0x1462005b, 0x96110008,
143 0x00001021, 0x0e000fdf, 0x00000000, 0x0a00029b, 0x00001021, 0x0000000d, 142 0x32220001, 0x10400009, 0x27430080, 0x8e020000, 0x96040014, 0x000211c2,
143 0x00021040, 0x00621821, 0xa4640000, 0x0a0002d0, 0x3c020800, 0x3c020800,
144 0x8c430020, 0x1060002a, 0x3c030800, 0x0e00148e, 0x00000000, 0x97420108,
145 0x8f850018, 0x9743010c, 0x3042003e, 0x00021400, 0x00621825, 0xaca30000,
146 0x8f840018, 0x8f420100, 0xac820004, 0x97430116, 0x9742010e, 0x8f840018,
147 0x00031c00, 0x00431025, 0xac820008, 0x97430110, 0x97440112, 0x8f850018,
148 0x00031c00, 0x00832025, 0xaca4000c, 0x97420114, 0x8f840018, 0x3042ffff,
149 0xac820010, 0x8f830018, 0xac600014, 0x8f820018, 0x3c030800, 0xac400018,
150 0x946258ce, 0x8f840018, 0x3c032000, 0x00431025, 0xac82001c, 0x0e0014cc,
151 0x24040001, 0x3c030800, 0x8c620040, 0x24420001, 0xac620040, 0x3c020800,
152 0x8c430044, 0x32240004, 0x24630001, 0x10800017, 0xac430044, 0x8f4202b8,
153 0x04430007, 0x8e020020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001,
154 0x0a0002f2, 0xac830060, 0x3c060800, 0x8cc4005c, 0xaf420280, 0x96030016,
155 0x00001021, 0xa7430284, 0x8e050004, 0x24840001, 0x3c031000, 0xaf450288,
156 0xaf4302b8, 0x0a0002f2, 0xacc4005c, 0x32220002, 0x0a0002f2, 0x0002102b,
157 0x3c026000, 0xac400808, 0x0000000d, 0x00001021, 0x8fbf0018, 0x8fb10014,
158 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffc8, 0xafbf0034, 0xafbe0030,
159 0xafb7002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c, 0xafb20018,
160 0xafb10014, 0x0e000244, 0xafb00010, 0x3c170800, 0x3c160800, 0x24110020,
161 0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800, 0x8f820004,
162 0x3c040800, 0x8c830020, 0x10430005, 0x8ee200a4, 0xaf830004, 0x0e001593,
163 0x00000000, 0x8ee200a4, 0x8ec300a0, 0x10430004, 0x26c400a0, 0x94820002,
164 0xa742009e, 0xaee300a4, 0x8f500000, 0x32020007, 0x1040ffee, 0x32020001,
165 0x1040002c, 0x32020002, 0x8f420100, 0xaf420020, 0x8f430104, 0xaf4300a8,
166 0x9342010b, 0x93630000, 0x306300ff, 0x10710005, 0x304400ff, 0x10750006,
167 0x2c820016, 0x0a000333, 0x00000000, 0xaf940000, 0x0a000334, 0x2c820016,
168 0xaf930000, 0x0a000334, 0x00000000, 0xaf800000, 0x14400005, 0x00041880,
169 0x0e0003cc, 0x00000000, 0x0a000340, 0x00000000, 0x3c020800, 0x24425860,
170 0x00621821, 0x8c620000, 0x0040f809, 0x00000000, 0x10400005, 0x3c030800,
171 0x8f420104, 0x3c016020, 0xac220014, 0x3c030800, 0x8c620034, 0xaf520138,
172 0x24420001, 0xac620034, 0x32020002, 0x1040001a, 0x32020004, 0x8f420140,
173 0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000, 0x10750006,
174 0x00000000, 0x0a00035d, 0x00000000, 0xaf940000, 0x0a00035e, 0x00000000,
175 0xaf930000, 0x0a00035e, 0x00000000, 0xaf800000, 0x0e000c7b, 0x00000000,
176 0x3c040800, 0x8c820038, 0xaf520178, 0x24420001, 0xac820038, 0x32020004,
177 0x1040ffa4, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff,
178 0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a000378, 0x00000000,
179 0xaf940000, 0x0a000379, 0x00000000, 0xaf930000, 0x0a000379, 0x00000000,
180 0xaf800000, 0x8f430180, 0x24020f00, 0x14620005, 0x00000000, 0x8f420188,
181 0xa742009c, 0x0a000387, 0x8fc2003c, 0x93620000, 0x14510004, 0x8fc2003c,
182 0x0e000bad, 0x00000000, 0x8fc2003c, 0xaf5201b8, 0x24420001, 0x0a00030b,
183 0xafc2003c, 0x27bdffe8, 0xafbf0010, 0x97420108, 0x24033000, 0x30447000,
184 0x10830016, 0x28823001, 0x10400007, 0x24024000, 0x1080000b, 0x24022000,
185 0x1082000c, 0x00000000, 0x0a0003b3, 0x00000000, 0x10820010, 0x24025000,
186 0x10820012, 0x00000000, 0x0a0003b3, 0x00000000, 0x0000000d, 0x0a0003b5,
187 0x00001021, 0x0e000442, 0x00000000, 0x0a0003b6, 0x8fbf0010, 0x0e00041a,
188 0x00000000, 0x0a0003b5, 0x00001021, 0x0e000669, 0x00000000, 0x0a0003b5,
189 0x00001021, 0x0e001467, 0x00000000, 0x0a0003b5, 0x00001021, 0x0000000d,
144 0x00001021, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x93620000, 0x24030020, 190 0x00001021, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x93620000, 0x24030020,
145 0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0002af, 191 0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0003c9,
146 0x00000000, 0x2782000c, 0xaf820000, 0x03e00008, 0x00000000, 0x27820008, 192 0x00000000, 0x2782000c, 0xaf820000, 0x03e00008, 0x00000000, 0x27820008,
147 0xaf820000, 0x03e00008, 0x00000000, 0xaf800000, 0x03e00008, 0x00000000, 193 0xaf820000, 0x03e00008, 0x00000000, 0xaf800000, 0x03e00008, 0x00000000,
148 0x0000000d, 0x03e00008, 0x00001021, 0x03e00008, 0x00001021, 0x27440100, 194 0x0000000d, 0x03e00008, 0x00001021, 0x03e00008, 0x00001021, 0x27440100,
@@ -159,1000 +205,1716 @@ static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = {
159 0x3c020006, 0x34420001, 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 205 0x3c020006, 0x34420001, 0xaf420030, 0x00000000, 0x00000000, 0x00000000,
160 0x8f420000, 0x30420010, 0x1040fffd, 0x00001021, 0x03e00008, 0x00000000, 206 0x8f420000, 0x30420010, 0x1040fffd, 0x00001021, 0x03e00008, 0x00000000,
161 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x1060001e, 207 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x1060001e,
162 0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000, 208 0xafbf0014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000,
163 0x8f840018, 0x9602000c, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 209 0x8f840018, 0x9602000c, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018,
164 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 210 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018,
165 0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 211 0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce,
166 0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 212 0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c,
167 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffc8, 0xafb3001c, 213 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010,
168 0x00009821, 0xafb7002c, 0x0000b821, 0xafbe0030, 0x0000f021, 0xafb50024, 214 0x27500100, 0xafbf0014, 0x92020009, 0x14400003, 0x3c020800, 0x0a00046c,
169 0x27550100, 0xafbf0034, 0xafb60028, 0xafb40020, 0xafb20018, 0xafb10014, 215 0x24020001, 0x8c430020, 0x1060001f, 0x00001021, 0x0e00148e, 0x00000000,
170 0xafb00010, 0x96a20008, 0x8f540100, 0x8eb20018, 0x30420001, 0x10400037, 216 0x8f830018, 0x8e020018, 0xac620000, 0x8f840018, 0x9602000c, 0xac820004,
171 0x02a0b021, 0x8f630054, 0x2642ffff, 0x00431023, 0x18400006, 0x00000000, 217 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
172 0x0000000d, 0x00000000, 0x24000128, 0x0a000372, 0x00002021, 0x8f62004c, 218 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448, 0xac830018,
173 0x02421023, 0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800, 219 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018, 0x00021400, 0x00441025,
174 0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 220 0x24040001, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf0014, 0x8fb00010,
175 0xac62008c, 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 221 0x03e00008, 0x27bd0018, 0x3c0b0800, 0x8d6808b0, 0x3c070800, 0x24e700b0,
176 0x30420001, 0x00021023, 0x30420005, 0x0a000372, 0x34440004, 0x27660100, 222 0x00084900, 0x01271821, 0xac640000, 0x93620005, 0x97660008, 0x00e95021,
177 0x00041080, 0x00c21021, 0x8c430000, 0x02431823, 0x04600004, 0x24820001, 223 0x93630023, 0x9364003f, 0x25080001, 0x00021600, 0x00063400, 0x00461025,
178 0x30440007, 0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 224 0x00031a00, 0x00431025, 0x00822025, 0xad440004, 0x9362007e, 0x9366007f,
179 0x8c620094, 0x24040005, 0x24420001, 0x0a000372, 0xac620094, 0x24040004, 225 0x8f630178, 0x9364007a, 0x00021600, 0x00063400, 0x00461025, 0x00031a00,
180 0x00809821, 0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010, 226 0x00431025, 0x00822025, 0xad440008, 0x93620080, 0x9363007d, 0x3108007f,
181 0x2c420001, 0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001, 227 0x01403821, 0xad6808b0, 0x00021600, 0x00031c00, 0x00431025, 0x00451025,
182 0x38820014, 0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012, 228 0x03e00008, 0xace2000c, 0x27bdffb8, 0xafb3002c, 0x00009821, 0xafbe0040,
183 0x14820002, 0x00001021, 0x24020001, 0x50400007, 0x8eb10020, 0x8ea20020, 229 0x0000f021, 0xafb50034, 0x27550100, 0xafbf0044, 0xafb7003c, 0xafb60038,
184 0x8f630040, 0x00408821, 0x00431023, 0x5c400001, 0x8f710040, 0x9343010b, 230 0xafb40030, 0xafb20028, 0xafb10024, 0xafb00020, 0xafa00010, 0xafa00014,
185 0x24020004, 0x54620005, 0x36730080, 0x96a20008, 0x36730002, 0x24170001, 231 0x96a20008, 0x8f540100, 0x8eb10018, 0x30420001, 0x10400037, 0x02a0b821,
186 0x305e0020, 0x2402fffb, 0x02628024, 0x1200002a, 0x3c030800, 0x8c620030, 232 0x8f630054, 0x2622ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d,
187 0x02021024, 0x10400026, 0x3c020800, 0x8c430020, 0x10600024, 0x32620004, 233 0x00000000, 0x2400015c, 0x0a0004e5, 0x00002021, 0x8f62004c, 0x02221023,
188 0x0e001006, 0x00000000, 0x8f830018, 0x8f420100, 0xac620000, 0x8f840018, 234 0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c,
189 0x02201821, 0x32620002, 0xac900004, 0x8f840018, 0x50400001, 0x8ec30014, 235 0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c,
190 0xac830008, 0x8f830018, 0x8ec20020, 0xac62000c, 0x8f840018, 0x8f620040, 236 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001,
191 0xac820010, 0x8f830018, 0x8ec20018, 0xac620014, 0x8f840018, 0x3c026000, 237 0x00021023, 0x30420005, 0x0a0004e5, 0x34440004, 0x27660100, 0x00041080,
192 0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024010, 238 0x00c21021, 0x8c430000, 0x02231823, 0x04600004, 0x24820001, 0x30440007,
193 0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x32620004, 0x10400076, 239 0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094,
194 0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02821025, 0xa360007c, 240 0x24040005, 0x24420001, 0x0a0004e5, 0xac620094, 0x24040004, 0x00809821,
195 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 241 0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010, 0x2c420001,
196 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c, 242 0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001, 0x38820014,
197 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff, 243 0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012, 0x14820002,
198 0x93620023, 0x3042007f, 0xa3620023, 0xaf720064, 0x3c023fff, 0x0a0003f1, 244 0x00001021, 0x24020001, 0x10400009, 0x00000000, 0x8ea20020, 0x8f630040,
199 0x3442ffff, 0x8f62005c, 0x02421023, 0x04400011, 0x00000000, 0x8f65005c, 245 0x0040b021, 0x00431023, 0x5c400010, 0x8f760040, 0x0a000511, 0x00000000,
200 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf720064, 0x00a32823, 246 0x9343010b, 0x24020004, 0x1462000a, 0x8eb60020, 0x8f630040, 0x3c021000,
201 0x00852821, 0x0045102b, 0x10400004, 0x02451021, 0x3c053fff, 0x34a5ffff, 247 0x00761823, 0x0043102a, 0x10400004, 0x00000000, 0x0000000d, 0x00000000,
202 0x02451021, 0xaf62005c, 0x24070001, 0xaf72004c, 0x8f620054, 0x16420005, 248 0x240002fa, 0x9343010b, 0x24020004, 0x5462000b, 0x96a20008, 0x24020001,
249 0xafa20010, 0x96a20008, 0x24030001, 0xafa30018, 0x8eb2001c, 0x36730002,
250 0x30420020, 0x0a000526, 0xafa20014, 0x36730080, 0x30420002, 0x10400003,
251 0xafa00018, 0x0a000526, 0x8eb2001c, 0x8eb20014, 0x2402fffb, 0x02628024,
252 0x1200002a, 0x3c030800, 0x8c620030, 0x02021024, 0x10400026, 0x3c020800,
253 0x8c430020, 0x10600024, 0x32620004, 0x0e00148e, 0x00000000, 0x8f830018,
254 0x8f420100, 0xac620000, 0x8f840018, 0x02401821, 0x32620002, 0xac900004,
255 0x8f840018, 0x54400001, 0x02c01821, 0xac830008, 0x8f830018, 0x8ee20020,
256 0xac62000c, 0x8f840018, 0x8f620040, 0xac820010, 0x8f830018, 0x8ee20018,
257 0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
258 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc,
259 0xaca3001c, 0x32620004, 0x10400063, 0x00003821, 0x3c029000, 0x34420001,
260 0x3c038000, 0x02821025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024,
261 0x1440fffd, 0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000,
262 0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821,
263 0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023,
264 0xaf710064, 0x3c023fff, 0x0a000580, 0x3442ffff, 0x8f62005c, 0x02221023,
265 0x04400011, 0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff,
266 0x3442ffff, 0xaf710064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004,
267 0x02251021, 0x3c053fff, 0x34a5ffff, 0x02251021, 0xaf62005c, 0x24070001,
268 0xaf71004c, 0x8f620054, 0x16220005, 0x00000000, 0x93620023, 0x30420040,
269 0x10400017, 0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001,
270 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804,
271 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b,
272 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021,
273 0xaf62000c, 0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000,
274 0x34420001, 0x02821025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
275 0x00000000, 0x0e0013c4, 0x00000000, 0x00403821, 0x54e00001, 0x241e0001,
276 0x8f700040, 0x8f620040, 0x14520003, 0x00521023, 0x0a0005bf, 0x00001021,
277 0x28420001, 0x10400041, 0x8fa20010, 0x0e000fae, 0x02402021, 0xaf720040,
278 0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022, 0x24420001,
279 0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b, 0x14600027,
280 0x3c020800, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000,
281 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
282 0x34420001, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020,
283 0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050273, 0x0a0005f2,
284 0x24050001, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
285 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x24050001, 0x24020001, 0xa7620012,
286 0xa3600022, 0x0a0005fe, 0x2ca20001, 0x9743007a, 0x9444002a, 0x00002821,
287 0x00641821, 0x3063fffe, 0xa7630012, 0x2ca20001, 0x00021023, 0x03c2f024,
288 0x8fa20010, 0x10400004, 0x8fa30014, 0x0e0013c1, 0x00000000, 0x8fa30014,
289 0x10600003, 0x00000000, 0x0e0010eb, 0x00000000, 0x13c0001f, 0x3c029000,
290 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
291 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074,
292 0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000, 0x02802021,
293 0x0e000470, 0x2405036c, 0x0a00062b, 0x8fa20018, 0x8f4201f8, 0x00431024,
294 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8,
295 0x8fa20018, 0x5040002f, 0x96a20008, 0x8f620048, 0x8f630024, 0x00761821,
296 0xaf630048, 0x9764003c, 0x00501023, 0x0044102b, 0x10400025, 0x3c029000,
297 0x34420001, 0x3c040800, 0x8c830080, 0x8f450100, 0x3c068000, 0x24630001,
298 0x00a21025, 0xac830080, 0xaf420020, 0x8f420020, 0x00461024, 0x1440fffd,
299 0x00000000, 0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074,
300 0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021,
301 0x0e000470, 0x2405038a, 0x0a00065b, 0x96a20008, 0x8f4201f8, 0x00431024,
302 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8,
303 0x96a20008, 0x8fbf0044, 0x8fbe0040, 0x8fb7003c, 0x8fb60038, 0x8fb50034,
304 0x8fb40030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, 0x00021042,
305 0x30420001, 0x03e00008, 0x27bd0048, 0x27bdffe0, 0xafbf0018, 0x97420108,
306 0x24030019, 0x304400ff, 0x10830065, 0x2882001a, 0x1040001a, 0x2882000a,
307 0x1040000f, 0x28820008, 0x10400040, 0x24020001, 0x1082003a, 0x28820002,
308 0x50400005, 0x24020006, 0x10800032, 0x3c026000, 0x0a0006fb, 0x00000000,
309 0x1082003d, 0x00000000, 0x0a0006fb, 0x00000000, 0x2402000b, 0x10820044,
310 0x2882000b, 0x1440004b, 0x2402000e, 0x10820045, 0x00000000, 0x0a0006fb,
311 0x00000000, 0x24020020, 0x10820062, 0x28820021, 0x1040000e, 0x2402001c,
312 0x1082004c, 0x2882001d, 0x10400005, 0x2402001b, 0x10820043, 0x00000000,
313 0x0a0006fb, 0x00000000, 0x2402001f, 0x10820050, 0x00000000, 0x0a0006fb,
314 0x00000000, 0x240200c1, 0x10820042, 0x288200c2, 0x10400005, 0x24020080,
315 0x10820021, 0x00000000, 0x0a0006fb, 0x00000000, 0x240200c2, 0x1082003d,
316 0x240200c9, 0x50820049, 0xafa00010, 0x0a0006fb, 0x00000000, 0x0e001163,
317 0xac400808, 0x0a0006fd, 0x8fbf0018, 0x3c026000, 0x8c444448, 0x3c030800,
318 0xac640064, 0x0e001163, 0x00000000, 0x3c026000, 0x8c444448, 0x3c030800,
319 0x0a0006fc, 0xac640068, 0x8f440100, 0x0e0006ff, 0x00000000, 0x3c026000,
320 0x8c444448, 0x3c030800, 0x0a0006fc, 0xac64006c, 0x0e001191, 0x00000000,
321 0x0a0006fd, 0x8fbf0018, 0x8f440100, 0x0e0011bb, 0x00000000, 0x0a0006fd,
322 0x8fbf0018, 0x0e001202, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0000000d,
323 0x0a0006fd, 0x8fbf0018, 0x0e000826, 0x00000000, 0x0a0006fd, 0x8fbf0018,
324 0x8f440100, 0x0e001264, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00134e,
325 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e00087c, 0x27440100, 0x0a0006fd,
326 0x8fbf0018, 0x8f640040, 0x0e000fae, 0x00000000, 0x0a0006fd, 0x8fbf0018,
327 0x8f440100, 0x0e001059, 0x00000000, 0x0a0006fd, 0x8fbf0018, 0x0e001417,
328 0x00000000, 0x0a0006fd, 0x8fbf0018, 0xafa00014, 0x8f440100, 0x8f450118,
329 0x8f46011c, 0x0e001439, 0x8f470120, 0x0a0006fd, 0x8fbf0018, 0x0000000d,
330 0x8fbf0018, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x9742010c,
331 0x1440005e, 0x00803821, 0x3c029000, 0x34420001, 0x00e21025, 0xaf420020,
332 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
333 0x30420010, 0x14400026, 0x3c030800, 0x8f630074, 0x3c027fff, 0x3442ffff,
334 0x00621824, 0xaf630074, 0x93620005, 0x34420001, 0xa3620005, 0x8f63004c,
335 0x8f620054, 0x10620021, 0x24040001, 0x9762006a, 0x00022880, 0x50a00001,
336 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821,
337 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050,
338 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824,
339 0x00a21021, 0xaf62000c, 0x0a00073d, 0x24040001, 0x8c6200a8, 0x00002021,
340 0x24420001, 0xac6200a8, 0x0000000d, 0x00000000, 0x2400044d, 0x3c028000,
341 0x34420001, 0x00e21025, 0xaf420020, 0x1080001f, 0x3c029000, 0x34420001,
342 0x00e21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
343 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
344 0x00e31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00e02021, 0x0e000470,
345 0x24050455, 0x0a000761, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
346 0x24020002, 0x3c031000, 0xaf4701c0, 0xa34201c4, 0xaf4301f8, 0x0e001163,
347 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafbf0024,
348 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x93630005,
349 0x00809821, 0x24020030, 0x30630030, 0x146200ac, 0x00a0a021, 0x3c020800,
350 0x8c430020, 0x106000a6, 0x00000000, 0x0e00148e, 0x00000000, 0x8f830018,
351 0xac730000, 0x936200c4, 0x30420002, 0x10400004, 0x24020001, 0x8f830018,
352 0x0a000784, 0x00000000, 0x8f830018, 0x24020003, 0xac620004, 0x8f6200dc,
353 0x8f630040, 0x00431023, 0x18400004, 0x00000000, 0x0000000d, 0x00000000,
354 0x24000509, 0x8f840018, 0x8f6200dc, 0xac820008, 0x8f830018, 0xac60000c,
355 0x8f820018, 0xac400010, 0x8f830018, 0x8f62004c, 0x3c100800, 0xac620014,
356 0x8f850018, 0x3c026000, 0x8c434448, 0x261258c0, 0x00002021, 0xaca30018,
357 0x9642000e, 0x8f850018, 0x3c034010, 0x00431025, 0x0e0014cc, 0xaca2001c,
358 0x8f830018, 0xac730000, 0x9362003e, 0x9363003f, 0x8f840018, 0x00021200,
359 0x00621825, 0xac830004, 0x93620081, 0x93630082, 0x8f840018, 0x00021600,
360 0x00031c00, 0x00431025, 0xac820008, 0x8f830018, 0x8f620040, 0xac62000c,
361 0x8f840018, 0x8f620048, 0xac820010, 0x8f71004c, 0x8f820018, 0xac510014,
362 0x8f620050, 0x8f850018, 0x00401821, 0x02221023, 0x5c400001, 0x02201821,
363 0x00002021, 0xaca30018, 0x9642000e, 0x8f850018, 0x3c03c00b, 0x00431025,
364 0x0e0014cc, 0xaca2001c, 0x8f620054, 0x8f840018, 0x00401821, 0x02221023,
365 0x5c400001, 0x02201821, 0xac830000, 0x8f840018, 0x8f630058, 0xac830004,
366 0x93620023, 0x30420010, 0x10400004, 0x00000000, 0x8f830018, 0x0a0007dd,
367 0x8f620148, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f830018, 0x8f620060,
368 0xac62000c, 0x8f840018, 0x8f620064, 0xac820010, 0x97630068, 0x9762006a,
369 0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f850018, 0x00002021,
370 0x2402ffff, 0x260358c0, 0xaca20018, 0x9462000e, 0x8f850018, 0x3c03c00c,
371 0x00431025, 0x0e0014cc, 0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000,
372 0x936200c4, 0x30420002, 0x10400006, 0x00000000, 0x976200c8, 0x8f830018,
373 0x3042ffff, 0x0a000803, 0xac620004, 0x8f820018, 0xac400004, 0x8f830018,
374 0x8f62006c, 0xac620008, 0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018,
375 0xac600010, 0x93620005, 0x8f830018, 0x00021600, 0x00541025, 0xac620014,
376 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x260258c0, 0xaca30018,
377 0x9443000e, 0x8f850018, 0x3c02400d, 0x00621825, 0x0e0014cc, 0xaca3001c,
378 0x0e00122e, 0x02602021, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018,
379 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb00010,
380 0x27500100, 0xafbf0018, 0xafb10014, 0x9603000c, 0x240200c1, 0x54620024,
381 0x8e040000, 0x3c029000, 0x8f450100, 0x34420001, 0x3c038000, 0x00a21025,
382 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d,
383 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x00a31825,
384 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470, 0x240505b2,
385 0x0a000878, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002,
386 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x0a000878, 0x8fbf0018,
387 0x8f65004c, 0x24060001, 0x0e0012a3, 0x240705be, 0x3c020800, 0x8c430020,
388 0x9611000c, 0x1060001d, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018,
389 0xac500000, 0x8f840018, 0x00111400, 0xac820004, 0x8f830018, 0xac600008,
390 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018, 0x240205c1,
391 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
392 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc,
393 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
394 0x27bdffb0, 0xafb5003c, 0x0000a821, 0xafbe0048, 0x0000f021, 0xafb70044,
395 0x0000b821, 0xafb30034, 0x00009821, 0xafb60040, 0x0080b021, 0xafbf004c,
396 0xafb40038, 0xafb20030, 0xafb1002c, 0xafb00028, 0xafa00010, 0x8f620040,
397 0x8ec30014, 0x96d1000c, 0x00431023, 0x04410025, 0x8ed40000, 0x32220401,
398 0x1040030c, 0x3c029000, 0x34420001, 0x02821025, 0xaf420020, 0x3c038000,
399 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
400 0x34420004, 0xa362007d, 0x8f640074, 0x34630001, 0x02831825, 0xaf430020,
401 0x04810006, 0x3c038000, 0x02802021, 0x0e000470, 0x24050664, 0x0a000ba2,
402 0x8fbf004c, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
403 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x0a000ba2, 0x8fbf004c, 0x32220010,
404 0x1040006b, 0x00003021, 0x9362003f, 0x92c6000f, 0x304500ff, 0x24c3fff8,
405 0x2c62000f, 0x10400057, 0x3c020800, 0x244257c0, 0x00031880, 0x00621821,
406 0x8c640000, 0x00800008, 0x00000000, 0x38a20012, 0x0a000924, 0x0002a82b,
407 0x2402000e, 0x14a20004, 0x2402000c, 0x24150001, 0x0a000924, 0x24060010,
408 0x10a20049, 0x38a30010, 0x2c630001, 0x38a20016, 0x2c420001, 0x00621825,
409 0x1460004d, 0x0000a821, 0x24020014, 0x10a2004a, 0x00000000, 0x0000000d,
410 0x00000000, 0x2400069c, 0x0a000924, 0x0000a821, 0x24020016, 0x14a20005,
411 0x2402000c, 0x24150001, 0x24060010, 0x0a000924, 0x3231fffd, 0x10a20032,
412 0x38a30010, 0x2c630001, 0x38a2000e, 0x2c420001, 0x00621825, 0x14600036,
413 0x0000a821, 0x24020014, 0x14a20003, 0x24150001, 0x0a000924, 0x24060012,
414 0x0000000d, 0x00000000, 0x240006bc, 0x0a000924, 0x0000a821, 0x2402000e,
415 0x14a20004, 0x24020016, 0x24150001, 0x0a000924, 0x3231fffb, 0x14a20004,
416 0x24020014, 0x24150001, 0x0a000924, 0x3231fffd, 0x54a20013, 0x92c2000e,
417 0x24150001, 0x24060012, 0x0a000924, 0x3231fffd, 0x2402000c, 0x54a2000c,
418 0x92c2000e, 0x92c3000e, 0x2402000a, 0x10620005, 0x24150001, 0x0000000d,
419 0x00000000, 0x240006e8, 0x24150001, 0x0a000924, 0x24060014, 0x92c2000e,
420 0x14a20003, 0x00000000, 0x0a000924, 0x24150001, 0x10a6ffc1, 0x24020012,
421 0x10a20005, 0x0000a821, 0x0000000d, 0x00000000, 0x24000704, 0x0000a821,
422 0x12a00022, 0x32220004, 0x10400002, 0x24020001, 0xafa20010, 0x32230102,
423 0x24020002, 0x1462000f, 0x00000000, 0x92c2000a, 0x30420020, 0x1440000b,
424 0x00000000, 0x8f630048, 0x8f620040, 0x14620004, 0x00000000, 0x8f620048,
425 0x24420001, 0xaf620048, 0x8f620040, 0x24420001, 0xaf620040, 0xa366003f,
426 0x38c30012, 0x2c630001, 0x38c20010, 0x2c420001, 0x00621825, 0x10600005,
427 0x3c030800, 0x8c620074, 0x24420001, 0x0e00140d, 0xac620074, 0x32220040,
428 0x32230020, 0xafa30020, 0x32230080, 0xafa30024, 0x32230001, 0xafa30018,
429 0x32230008, 0xafa3001c, 0x32230100, 0x104000c4, 0xafa30014, 0x8ec60010,
430 0x8f630054, 0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d,
431 0x00000000, 0x2400015c, 0x0a000989, 0x00009021, 0x8f62004c, 0x00c21023,
432 0x18400028, 0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c,
433 0x308400ff, 0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c,
434 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001,
435 0x00021023, 0x30420005, 0x0a000989, 0x34520004, 0x27670100, 0x00041080,
436 0x00e21021, 0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007,
437 0x1485fff9, 0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094,
438 0x24120005, 0x24420001, 0x0a000989, 0xac620094, 0x24120004, 0x32420001,
439 0x10400021, 0x3c020800, 0x8c430020, 0x8ed00000, 0x1060001c, 0x8ed30010,
440 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001,
441 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
442 0xac600010, 0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448,
443 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010,
444 0x00621825, 0x0e0014cc, 0xaca3001c, 0x24130001, 0x32420004, 0x10400068,
445 0x00003821, 0x3c029000, 0x8ec60010, 0x34420001, 0x3c038000, 0x02821025,
446 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
447 0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c,
448 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006,
449 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff,
450 0x0a0009da, 0x3442ffff, 0x8f62005c, 0x00c21023, 0x04400011, 0x00000000,
451 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064,
452 0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff,
453 0x34a5ffff, 0x00c51021, 0xaf62005c, 0x24070001, 0xaf66004c, 0x8fa20010,
454 0x10400003, 0x00000000, 0xaf660050, 0xaf660054, 0x8f620054, 0x14c20005,
203 0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a, 455 0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a,
204 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 456 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800,
205 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 457 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021,
206 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 458 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074,
207 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001, 459 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x93620082, 0x30420080,
208 0x02821025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004, 460 0x50400001, 0xa3600081, 0x3c028000, 0x34420001, 0x02821025, 0xaf420020,
209 0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000, 461 0x9363007e, 0x9362007a, 0x10620005, 0x00e0b821, 0x0e0013c4, 0x00000000,
462 0x00403821, 0x00e0b821, 0x8fa30020, 0x10600009, 0x8fa20010, 0x8ec20018,
463 0xaf620018, 0x8ec3001c, 0xaf63001c, 0x8ec20020, 0x24170001, 0xaf620058,
464 0x8fa20010, 0x10400057, 0x8fa30024, 0x93620023, 0x30420040, 0x10400053,
465 0x00000000, 0x16600021, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040001e,
466 0x24130001, 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018,
467 0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
468 0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000,
469 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
470 0x3c024010, 0x00621825, 0xaca3001c, 0x0e0014cc, 0x24130001, 0x8e420020,
471 0x1040001c, 0x8ed00000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000,
472 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c,
473 0x8f820018, 0xac400010, 0x8f830018, 0x24020798, 0xac620014, 0x8f850018,
474 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce,
475 0x8f850018, 0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000,
210 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 476 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
211 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02821025, 477 0x1440fffd, 0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001,
212 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 478 0x02821025, 0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30024, 0x10600012,
213 0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x8ea30014, 0x8f620040, 479 0x8fa30018, 0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a,
214 0x14430003, 0x00431023, 0x0a000443, 0x00001021, 0x28420001, 0x10400034, 480 0x1462000b, 0x8fa30018, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b,
215 0x00000000, 0x8f620040, 0xaf630040, 0x9362003e, 0x30420001, 0x1440000b, 481 0x14400005, 0x8fa30018, 0x0e0013c4, 0x00000000, 0x02e2b825, 0x8fa30018,
216 0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022, 0x3c020800, 482 0x3062ffff, 0x10400003, 0x32220200, 0x0a000a94, 0x241e0004, 0x10400003,
217 0x8c440098, 0x0064182b, 0x1460001e, 0x3c020800, 0x3c029000, 0x34420001, 483 0x00000000, 0x241e0040, 0x24170001, 0x12a000d0, 0x32220002, 0x104000cf,
484 0x8fa2001c, 0x92c2000a, 0x30420002, 0x5040003b, 0x92c2000a, 0x93620023,
485 0x30420008, 0x54400037, 0x92c2000a, 0x3c020800, 0x8c430020, 0x10600023,
486 0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000,
487 0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040,
488 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018,
489 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018,
490 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
491 0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
218 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 492 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
219 0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02831825, 493 0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630008,
220 0x34420001, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 494 0xa3630023, 0xaf420020, 0x92c2000a, 0x30420020, 0x1040008e, 0x8fa2001c,
221 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0x24020001, 0xaf4301f8, 495 0x93620023, 0x30420001, 0x14400035, 0x3c020800, 0x8c430020, 0x10600023,
222 0xa7620012, 0x0a000476, 0xa3600022, 0x9743007a, 0x9444002a, 0x00641821, 496 0x3c029000, 0x0e00148e, 0x00000000, 0x8f840018, 0x8ec30000, 0xac830000,
223 0x3063fffe, 0xa7630012, 0x0e000b68, 0x00000000, 0x12e00003, 0x00000000, 497 0x92c2000a, 0x8f830018, 0x00021600, 0xac620004, 0x8f840018, 0x8f620040,
224 0x0e000f27, 0x00000000, 0x53c00004, 0x96a20008, 0x0e000c10, 0x00000000, 498 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, 0x9362003f, 0x8f840018,
225 0x96a20008, 0x8fbf0034, 0x8fbe0030, 0x8fb7002c, 0x8fb60028, 0x8fb50024, 499 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018,
226 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042, 500 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
227 0x30420001, 0x03e00008, 0x27bd0038, 0x27bdffe8, 0xafbf0010, 0x97420108, 501 0x3c02401a, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
228 0x2403000b, 0x304400ff, 0x1083004e, 0x2882000c, 0x10400011, 0x24020006, 502 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
229 0x1082003e, 0x28820007, 0x10400007, 0x28820008, 0x1080002b, 0x24020001, 503 0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x34630001,
230 0x1082002e, 0x3c026000, 0x0a000504, 0x00000000, 0x14400061, 0x2882000a, 504 0xa3630023, 0xaf420020, 0x93620023, 0x30420040, 0x10400052, 0x8fa2001c,
231 0x1440002b, 0x00000000, 0x0a0004ec, 0x00000000, 0x2402001c, 0x1082004e, 505 0x16600020, 0x3c120800, 0x8e420020, 0x8f70004c, 0x1040003c, 0x3c029000,
232 0x2882001d, 0x1040000e, 0x24020019, 0x10820041, 0x2882001a, 0x10400005, 506 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x24020001,
233 0x2402000e, 0x10820036, 0x00000000, 0x0a000504, 0x00000000, 0x2402001b, 507 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
234 0x1082003c, 0x00000000, 0x0a000504, 0x00000000, 0x240200c1, 0x10820040, 508 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448,
235 0x288200c2, 0x10400005, 0x24020080, 0x1082001f, 0x00000000, 0x0a000504, 509 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010,
236 0x00000000, 0x240200c2, 0x1082003b, 0x00000000, 0x0a000504, 0x00000000, 510 0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x3c029000,
237 0x3c026000, 0x0e000c7d, 0xac400808, 0x0a000506, 0x8fbf0010, 0x8c444448, 511 0x0e00148e, 0x00000000, 0x8f820018, 0xac540000, 0x8f840018, 0x3c02008d,
238 0x3c030800, 0xac640064, 0x0e000c7d, 0x00000000, 0x3c026000, 0x8c444448, 512 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
239 0x3c030800, 0x0a000505, 0xac640068, 0x8f440100, 0x0e000508, 0x00000000, 513 0xac600010, 0x8f840018, 0x240207ee, 0xac820014, 0x8f850018, 0x3c026000,
240 0x3c026000, 0x8c444448, 0x3c030800, 0x0a000505, 0xac64006c, 0x0e000cab, 514 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
241 0x00000000, 0x0a000506, 0x8fbf0010, 0x8f440100, 0x0e000cd5, 0x00000000, 515 0x3c024019, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x3c029000, 0x34420001,
242 0x0a000506, 0x8fbf0010, 0x0e000d1c, 0x00000000, 0x0a000506, 0x8fbf0010, 516 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
243 0x0000000d, 0x0a000506, 0x8fbf0010, 0x0e0005d7, 0x00000000, 0x0a000506, 517 0x00000000, 0x93630023, 0x3c028000, 0x34420001, 0x02821025, 0x306300bf,
244 0x8fbf0010, 0x8f440100, 0x0e000d7e, 0x00000000, 0x0a000506, 0x8fbf0010, 518 0xa3630023, 0xaf420020, 0x8fa2001c, 0x1040000e, 0x8fa20014, 0x92c2000a,
245 0x0e000e95, 0x00000000, 0x0a000506, 0x8fbf0010, 0x0e000626, 0x00000000, 519 0xa3620082, 0x57c00005, 0x37de0008, 0x8fa30014, 0x10600004, 0x00000000,
246 0x0a000506, 0x8fbf0010, 0x0e000b68, 0x00000000, 0x0a000506, 0x8fbf0010, 520 0x37de0008, 0x0a000b75, 0x24170001, 0x0e0012cf, 0x02802021, 0x8fa20014,
247 0x0000000d, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c029000, 521 0x10400003, 0x00000000, 0x37de0010, 0x24170001, 0x12e00020, 0x3c029000,
248 0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000, 0xafbf0014, 522 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
249 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 523 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x03c21025, 0xa362007d,
250 0x34420001, 0xa3620005, 0x8f63004c, 0x8f620054, 0x10620019, 0x3c028000, 524 0x8f640074, 0x34630001, 0x02831825, 0xaf430020, 0x04810006, 0x3c038000,
251 0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 525 0x02802021, 0x0e000470, 0x2405082a, 0x0a000b9b, 0x00000000, 0x8f4201f8,
252 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 526 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4,
253 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 527 0xaf4301f8, 0x9363003f, 0x24020012, 0x14620004, 0x8fbf004c, 0x0e00140d,
254 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 528 0x00000000, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c,
255 0x34420001, 0x02021025, 0x0e000c7d, 0xaf420020, 0x3c029000, 0x34420001,
256 0x3c038000, 0x02021025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
257 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02021025, 0xa363007d,
258 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x8fbf0014, 0xaf5001c0,
259 0x8fb00010, 0x24020002, 0x3c031000, 0xa34201c4, 0xaf4301f8, 0x03e00008,
260 0x27bd0018, 0x27bdffd8, 0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014,
261 0xafb00010, 0x93630005, 0x00809021, 0x24020030, 0x30630030, 0x14620072,
262 0x00a09821, 0x3c020800, 0x8c430020, 0x1060006c, 0x00000000, 0x0e001006,
263 0x00000000, 0x8f820018, 0xac520000, 0x9363003e, 0x9362003f, 0x8f840018,
264 0x00031a00, 0x00431025, 0xac820004, 0x93630081, 0x93620082, 0x8f850018,
265 0x00031e00, 0x00021400, 0x00621825, 0xaca30008, 0x8f840018, 0x8f620040,
266 0xac82000c, 0x8f830018, 0x8f620048, 0xac620010, 0x8f840018, 0x8f62004c,
267 0x3c110800, 0xac820014, 0x8f830018, 0x8f620050, 0x26304660, 0x00002021,
268 0xac620018, 0x9602000e, 0x8f850018, 0x3c03c00b, 0x00431025, 0x0e001044,
269 0xaca2001c, 0x8f830018, 0x8f620054, 0xac620000, 0x8f840018, 0x8f620058,
270 0xac820004, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f840018, 0x8f620060,
271 0xac82000c, 0x8f850018, 0x8f620064, 0xaca20010, 0x97630068, 0x9762006a,
272 0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f830018, 0x00002021,
273 0xac600018, 0x9602000e, 0x8f850018, 0x3c03c00c, 0x00431025, 0x0e001044,
274 0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000, 0x936200c4, 0x30420002,
275 0x10400006, 0x00000000, 0x976200c8, 0x8f830018, 0x3042ffff, 0x0a0005b5,
276 0xac620004, 0x8f820018, 0xac400004, 0x8f830018, 0x8f62006c, 0xac620008,
277 0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018, 0xac600010, 0x93620005,
278 0x8f830018, 0x00021600, 0x00531025, 0xac620014, 0x8f850018, 0x3c026000,
279 0x8c434448, 0x24040001, 0x26224660, 0xaca30018, 0x9443000e, 0x8f850018,
280 0x3c02400d, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x02402021,
281 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008,
282 0x27bd0028, 0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014,
283 0x9603000c, 0x240200c1, 0x5462001d, 0x8e040000, 0x3c029000, 0x8f440100,
284 0x34420001, 0x3c038000, 0x00821025, 0xaf420020, 0x8f420020, 0x00431024,
285 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c058000,
286 0x00831825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00451024,
287 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0, 0xa34201c4, 0xaf4301f8,
288 0x0a000622, 0x8fbf0018, 0x8f65004c, 0x24060001, 0x0e000db5, 0x2407049f,
289 0x3c020800, 0x8c430020, 0x9611000c, 0x1060001d, 0x8e100000, 0x0e001006,
290 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004,
291 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
292 0x8f840018, 0x240204a2, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
293 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019,
294 0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
295 0x03e00008, 0x27bd0020, 0x27bdffb0, 0xafb1002c, 0x27510100, 0xafbf004c,
296 0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038, 0xafb30034,
297 0xafb20030, 0xafb00028, 0x8e350000, 0x9634000c, 0x3c026000, 0x8c434448,
298 0x0000f021, 0xaf630170, 0x8f620040, 0x8e230014, 0x0000b821, 0x00431023,
299 0x044001ec, 0x0000b021, 0x32820010, 0x1040002e, 0x3c026000, 0x9363003f,
300 0x9222000e, 0x10430006, 0x2402000c, 0x9223000f, 0x10620003, 0x24020014,
301 0x14620025, 0x3c026000, 0x32820004, 0x10400007, 0x241e0001, 0x8f620050,
302 0x24420001, 0xaf620050, 0x8f630054, 0x24630001, 0xaf630054, 0x32830102,
303 0x24020002, 0x5462000d, 0x9222000f, 0x8f620040, 0x24420001, 0xaf620040,
304 0x8f630048, 0x8f620040, 0x24630001, 0x54620005, 0x9222000f, 0x8f620048,
305 0x24420001, 0xaf620048, 0x9222000f, 0xa362003f, 0x9223000f, 0x24020012,
306 0x14620007, 0x3c026000, 0x3c030800, 0x8c620074, 0x24420001, 0x0e000f6e,
307 0xac620074, 0x3c026000, 0x8c434448, 0x32820040, 0xaf630174, 0x32830020,
308 0xafa30010, 0x32830080, 0xafa30014, 0x32830001, 0xafa3001c, 0x32830008,
309 0xafa30020, 0x32830100, 0x104000bb, 0xafa30018, 0x8e260010, 0x8f630054,
310 0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000,
311 0x24000128, 0x0a0006b2, 0x00009021, 0x8f62004c, 0x00c21023, 0x18400028,
312 0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff,
313 0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c, 0x3c040800,
314 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023,
315 0x30420005, 0x0a0006b2, 0x34520004, 0x27670100, 0x00041080, 0x00e21021,
316 0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9,
317 0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24120005,
318 0x24420001, 0x0a0006b2, 0xac620094, 0x24120004, 0x32420001, 0x10400020,
319 0x3c020800, 0x8c430020, 0x8e300000, 0x1060001c, 0x8e330010, 0x0e001006,
320 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004,
321 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
322 0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
323 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024010, 0x00621825,
324 0x0e001044, 0xaca3001c, 0x32420004, 0x10400060, 0x00003821, 0x3c029000,
325 0x8e260010, 0x34420001, 0x3c038000, 0x02a21025, 0xa360007c, 0xaf420020,
326 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x30420080,
327 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064,
328 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023,
329 0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff, 0x0a000702, 0x3442ffff,
330 0x8f62005c, 0x00c21023, 0x04400011, 0x00000000, 0x8f65005c, 0x8f630064,
331 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064, 0x00a32823, 0x00852821,
332 0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff, 0x34a5ffff, 0x00c51021,
333 0xaf62005c, 0x24070001, 0xaf66004c, 0x8f620054, 0x14c20005, 0x00000000,
334 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a, 0x00022880,
335 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c,
336 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800,
337 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe,
338 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001, 0x02a21025,
339 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620005, 0x00e0b021,
340 0x0e000f2a, 0x00000000, 0x00403821, 0x00e0b021, 0x8fa20010, 0x10400008,
341 0x00000000, 0x8e220018, 0xaf620018, 0x8e23001c, 0xaf63001c, 0x8e220020,
342 0x24160001, 0xaf620058, 0x13c00036, 0x32820004, 0x10400035, 0x8fa30014,
343 0x93620023, 0x30420040, 0x10400031, 0x3c020800, 0x8c430020, 0x1060001c,
344 0x8e300000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018,
345 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018,
346 0xac400010, 0x8f830018, 0x24020587, 0xac620014, 0x8f850018, 0x3c026000,
347 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
348 0x3c024019, 0x00621825, 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001,
349 0x02a21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
350 0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001, 0x02a21025,
351 0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30014, 0x10600012, 0x8fa3001c,
352 0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a, 0x1462000b,
353 0x8fa3001c, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b, 0x14400005,
354 0x8fa3001c, 0x0e000f2a, 0x00000000, 0x02c2b025, 0x8fa3001c, 0x3062ffff,
355 0x10400003, 0x32820200, 0x0a000793, 0x24170004, 0x10400003, 0x00000000,
356 0x24170040, 0x24160001, 0x13c0005d, 0x32820002, 0x1040005c, 0x8fa20020,
357 0x9222000a, 0x30420020, 0x10400033, 0x3c100800, 0x93620023, 0x30420040,
358 0x1040002f, 0x8e020020, 0x1040001e, 0x3c029000, 0x0e001006, 0x00000000,
359 0x8f820018, 0xac550000, 0x8f840018, 0x3c02008d, 0xac820004, 0x8f830018,
360 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018,
361 0x240205bf, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
362 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825,
363 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02a21025, 0xaf420020,
364 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
365 0x3c028000, 0x34420001, 0x02a21025, 0x306300bf, 0xa3630023, 0xaf420020,
366 0x8e020020, 0x10400023, 0x8fa20020, 0x0e001006, 0x00000000, 0x8f840018,
367 0x8e230000, 0xac830000, 0x9222000a, 0x8f830018, 0x00021600, 0xac620004,
368 0x8f840018, 0x8f620040, 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c,
369 0x9362003f, 0x8f840018, 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000,
370 0xac600014, 0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
371 0x9443466e, 0x8f850018, 0x3c02401a, 0x00621825, 0x0e001044, 0xaca3001c,
372 0x8fa20020, 0x1040000e, 0x8fa20018, 0x9222000a, 0xa3620082, 0x56e00005,
373 0x36f70008, 0x8fa30018, 0x10600004, 0x00000000, 0x36f70008, 0x0a000801,
374 0x24160001, 0x0e000de1, 0x02a02021, 0x8fa20018, 0x10400003, 0x00000000,
375 0x36f70010, 0x24160001, 0x12c00019, 0x3c029000, 0x34420001, 0x02a21025,
376 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
377 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02a31825, 0x02e21025,
378 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002,
379 0x3c031000, 0xaf5501c0, 0xa34201c4, 0xaf4301f8, 0x9363003f, 0x24020012,
380 0x14620004, 0x3c026000, 0x0e000f6e, 0x00000000, 0x3c026000, 0x8c434448,
381 0xaf630178, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c,
382 0x8fb40038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x03e00008, 529 0x8fb40038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x03e00008,
383 0x27bd0050, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f500180, 0x97420184, 530 0x27bd0050, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f500180, 0x97420184,
384 0x30420200, 0x14400015, 0x00000000, 0x8f430188, 0x3c02ff00, 0x00621824, 531 0x30420200, 0x14400015, 0x00000000, 0x8f430188, 0x3c02ff00, 0x00621824,
385 0x3c020200, 0x10620031, 0x0043102b, 0x14400007, 0x3c020300, 0x1060000b, 532 0x3c020200, 0x10620031, 0x0043102b, 0x14400007, 0x3c020300, 0x1060000b,
386 0x3c020100, 0x1062000d, 0x00000000, 0x0a0008b4, 0x00000000, 0x10620027, 533 0x3c020100, 0x1062000d, 0x00000000, 0x0a000c2c, 0x00000000, 0x10620027,
387 0x3c020400, 0x1062003e, 0x02002021, 0x0a0008b4, 0x00000000, 0x0e000e1e, 534 0x3c020400, 0x1062003e, 0x02002021, 0x0a000c2c, 0x00000000, 0x0e000c31,
388 0x02002021, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e, 535 0x02002021, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e,
389 0x8fbf0014, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, 536 0x8fbf0014, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000,
390 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, 537 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000,
391 0x34630001, 0x02031825, 0x34420020, 0xa3620005, 0xaf430020, 0x93620005, 538 0x34630001, 0x02031825, 0x34420020, 0xa3620005, 0xaf430020, 0x93620005,
392 0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000553, 539 0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000766,
393 0x24055854, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f, 540 0x24055854, 0x0a000c2e, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f,
394 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020, 541 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020,
395 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c048000, 0x3c030800, 542 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x34420004, 0xa3620023,
396 0x304200fe, 0xa3620005, 0x8c620020, 0x34840001, 0x02042025, 0xaf440020, 543 0x93630005, 0x3c048000, 0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020,
397 0x1040002d, 0x8fbf0014, 0x0a000894, 0x00000000, 0x00002821, 0x00003021, 544 0x34840001, 0x02042025, 0x0a000c0a, 0xaf440020, 0x00002821, 0x00003021,
398 0x0e000f78, 0x240706a4, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014, 545 0x0e000fb1, 0x240708d9, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014,
399 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f, 546 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f,
400 0x8f840018, 0x00031a00, 0x00431025, 0xac820004, 0x8f830018, 0xac600008, 547 0x8f840018, 0x00031a00, 0x00431025, 0xac820004, 0x8f830018, 0xac600008,
401 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 548 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014,
402 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 549 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
403 0x9443466e, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e001044, 0xaca3001c, 550 0x944358ce, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e0014cc, 0xaca3001c,
404 0x0a0008b6, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008, 551 0x0a000c2e, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008,
405 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93420148, 0x2444ffff, 0x2c830005, 552 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021, 0x93640000,
406 0x10600047, 0x3c020800, 0x24424598, 0x00041880, 0x00621821, 0x8c640000, 553 0x24030020, 0x00021402, 0x10830008, 0x304500ff, 0x3c036018, 0x8c625000,
407 0x00800008, 0x00000000, 0x8f430144, 0x8f62000c, 0x14620006, 0x24020001, 554 0x34420400, 0xac625000, 0x0000000d, 0x00000000, 0x24000955, 0x9363003f,
408 0xaf62000c, 0x0e000909, 0x00000000, 0x0a000907, 0x8fbf0010, 0x8f62000c, 555 0x24020012, 0x14620023, 0x3c029000, 0x34420001, 0x3c038000, 0x00c21025,
409 0x0a000900, 0x00000000, 0x97630010, 0x8f420144, 0x14430006, 0x24020001, 556 0xaf650178, 0xa365007a, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
410 0xa7620010, 0x0e000eeb, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620010, 557 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
411 0x0a000900, 0x00000000, 0x97630012, 0x8f420144, 0x14430006, 0x24020001, 558 0x00c31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00c02021, 0x0e000470,
412 0xa7620012, 0x0e000f06, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620012, 559 0x24050963, 0x0a000c79, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd,
413 0x0a000900, 0x00000000, 0x97630014, 0x8f420144, 0x14430006, 0x24020001, 560 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a000c79,
414 0xa7620014, 0x0e000f21, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620014, 561 0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x8f620178, 0x1045000b,
415 0x0a000900, 0x00000000, 0x97630016, 0x8f420144, 0x14430006, 0x24020001, 562 0x00000000, 0x8f820000, 0xaf650178, 0x8f660178, 0x8f440180, 0x8f65004c,
416 0xa7620016, 0x0e000f24, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620016, 563 0x8c430000, 0x0060f809, 0x30c600ff, 0x0a000c79, 0x8fbf0010, 0xaf650178,
417 0x14400006, 0x8fbf0010, 0x3c030800, 0x8c620070, 0x24420001, 0xac620070, 564 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93630000,
418 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93620081, 565 0x24020020, 0x10620005, 0x00000000, 0x93630000, 0x24020030, 0x1462004d,
419 0x3c030800, 0x8c640048, 0x0044102b, 0x14400028, 0x3c029000, 0x8f460140, 566 0x8fbf0010, 0x93420148, 0x2444ffff, 0x2c830005, 0x10600047, 0x3c020800,
420 0x34420001, 0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024, 567 0x24425800, 0x00041880, 0x00621821, 0x8c640000, 0x00800008, 0x00000000,
421 0x1440fffd, 0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000, 568 0x8f430144, 0x8f62000c, 0x14620006, 0x24020001, 0xaf62000c, 0x0e000d59,
422 0x24020012, 0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082, 569 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x8f62000c, 0x0a000cca, 0x00000000,
423 0xaf440020, 0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000, 570 0x97630010, 0x8f420144, 0x14430006, 0x24020001, 0xa7620010, 0x0e00137a,
424 0x9362007d, 0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 571 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620010, 0x0a000cca, 0x00000000,
425 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 572 0x97630012, 0x8f420144, 0x14430006, 0x24020001, 0xa7620012, 0x0e001395,
426 0x0a00096d, 0xaf4601c0, 0x93620081, 0x24420001, 0x0e000f2a, 0xa3620081, 573 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620012, 0x0a000cca, 0x00000000,
427 0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001, 0x97630068, 574 0x97630014, 0x8f420144, 0x14430006, 0x24020001, 0xa7620014, 0x0e0013bb,
575 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620014, 0x0a000cca, 0x00000000,
576 0x97630016, 0x8f420144, 0x14430006, 0x24020001, 0xa7620016, 0x0e0013be,
577 0x00000000, 0x0a000cd1, 0x8fbf0010, 0x97620016, 0x14400006, 0x8fbf0010,
578 0x3c030800, 0x8c620070, 0x24420001, 0xac620070, 0x8fbf0010, 0x03e00008,
579 0x27bd0018, 0x27bdffe0, 0x3c029000, 0xafbf001c, 0xafb20018, 0xafb10014,
580 0xafb00010, 0x8f500140, 0x34420001, 0x3c038000, 0x02021025, 0xaf420020,
581 0x8f420020, 0x00431024, 0x1440fffd, 0x24020012, 0x24030080, 0xa362003f,
582 0xa3630082, 0x93620023, 0x30420040, 0x10400007, 0x00008821, 0x93620023,
583 0x24110001, 0x304200bf, 0xa3620023, 0x0a000cf0, 0x3c028000, 0x3c028000,
584 0x34420001, 0x3c039000, 0x34630001, 0x3c048000, 0x02021025, 0x02031825,
585 0xaf420020, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
586 0x9362007d, 0x3c038000, 0x34420020, 0xa362007d, 0x8f640074, 0x34630001,
587 0x02031825, 0xaf430020, 0x04810006, 0x3c038000, 0x02002021, 0x0e000470,
588 0x24050a63, 0x0a000d13, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
589 0x24020002, 0x3c031000, 0xaf5001c0, 0xa34201c4, 0xaf4301f8, 0x1220003f,
590 0x3c120800, 0x8e420020, 0x8f71004c, 0x1040003c, 0x8fbf001c, 0x0e00148e,
591 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004,
592 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
593 0x8f820018, 0xac510014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
594 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825,
595 0x0e0014cc, 0xaca3001c, 0x8e420020, 0x1040001e, 0x8fbf001c, 0x0e00148e,
596 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004,
597 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
598 0x8f840018, 0x24020a6a, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
599 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c024019,
600 0x00621825, 0x0e0014cc, 0xaca3001c, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
601 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 0x93620081,
602 0x3c030800, 0x8c640048, 0x0044102b, 0x14400005, 0x00000000, 0x0e000cd3,
603 0x00000000, 0x0a000da4, 0x8fbf0010, 0x93620081, 0x24420001, 0x0e0013c4,
604 0xa3620081, 0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001,
605 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804,
606 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b,
607 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021,
608 0xaf62000c, 0x10e00021, 0x3c029000, 0x8f450140, 0x34420001, 0x3c038000,
609 0x00a21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
610 0x9362007d, 0x3c038000, 0x34420004, 0xa362007d, 0x8f640074, 0x34630001,
611 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021, 0x0e000470,
612 0x24050a92, 0x0a000da4, 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd,
613 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010,
614 0x03e00008, 0x27bd0018, 0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024,
615 0xafb40020, 0xafb20018, 0xafb10014, 0xafb00010, 0x96620008, 0x3c140800,
616 0x8f520100, 0x30420001, 0x104000da, 0x00000000, 0x8e700018, 0x8f630054,
617 0x2602ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000,
618 0x2400015c, 0x0a000dea, 0x00008821, 0x8f62004c, 0x02021023, 0x18400028,
619 0x00008821, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff,
620 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, 0xac62008c, 0x3c040800,
621 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023,
622 0x30420005, 0x0a000dea, 0x34510004, 0x27660100, 0x00041080, 0x00c21021,
623 0x8c430000, 0x02031823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9,
624 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24110005,
625 0x24420001, 0x0a000dea, 0xac620094, 0x24110004, 0x32220001, 0x1040001e,
626 0x8e820020, 0x1040001d, 0x32220004, 0x0e00148e, 0x00000000, 0x8f820018,
627 0xac520000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018, 0xac600008,
628 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac500014,
629 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018,
630 0x944358ce, 0x8f850018, 0x3c024010, 0x00621825, 0x0e0014cc, 0xaca3001c,
631 0x32220004, 0x10400081, 0x00003821, 0x3c029000, 0x34420001, 0x3c038000,
632 0x02421025, 0xa360007c, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd,
633 0x00000000, 0x93620023, 0x30420080, 0x10400011, 0x00000000, 0x8f65005c,
634 0x8f63004c, 0x9764003c, 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b,
635 0x54400006, 0x3c023fff, 0x93620023, 0x3042007f, 0xa3620023, 0xaf700064,
636 0x3c023fff, 0x0a000e37, 0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011,
637 0x00000000, 0x8f65005c, 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff,
638 0xaf700064, 0x00a32823, 0x00852821, 0x0045102b, 0x10400004, 0x02051021,
639 0x3c053fff, 0x34a5ffff, 0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c,
640 0x8f620054, 0x16020005, 0x00000000, 0x93620023, 0x30420040, 0x10400017,
641 0x24020001, 0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068,
428 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 642 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b,
429 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 643 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001,
430 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 644 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c,
431 0x10e0001a, 0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025, 645 0x93620082, 0x30420080, 0x50400001, 0xa3600081, 0x3c028000, 0x34420001,
432 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 646 0x02421025, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004, 0x00000000,
433 0x9362007d, 0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d, 647 0x0e0013c4, 0x00000000, 0x00403821, 0x10e0001f, 0x3c029000, 0x34420001,
434 0xaf430020, 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 648 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
435 0xaf4401c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 649 0x00000000, 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001,
436 0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024, 0xafb40020, 0xafb20018, 650 0x02431825, 0xaf430020, 0x04810006, 0x3c038000, 0x02402021, 0x0e000470,
437 0xafb10014, 0xafb00010, 0x96620008, 0x3c140800, 0x8f520100, 0x30420001, 651 0x24050b3d, 0x0a000e8d, 0x00000000, 0x8f4201f8, 0x00431024, 0x1440fffd,
438 0x104000cf, 0x00000000, 0x8e700018, 0x8f630054, 0x2602ffff, 0x00431023, 652 0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b,
439 0x18400006, 0x00000000, 0x0000000d, 0x00000000, 0x24000128, 0x0a0009b6, 653 0x9343010b, 0x8e820020, 0x27500100, 0x38630006, 0x10400029, 0x2c710001,
440 0x00008821, 0x8f62004c, 0x02021023, 0x18400028, 0x00008821, 0x93650120, 654 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
441 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff, 655 0x96020008, 0xac820004, 0x8f830018, 0x8e020014, 0xac620008, 0x8f850018,
442 0x00803821, 0x1485000b, 0xac62008c, 0x3c040800, 0x8c830090, 0x24630001, 656 0x3c026000, 0x8c434448, 0xaca3000c, 0x8f840018, 0x96020012, 0xac820010,
443 0xac830090, 0x93620122, 0x30420001, 0x00021023, 0x30420005, 0x0a0009b6, 657 0x8f850018, 0x8e030020, 0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018,
444 0x34510004, 0x27660100, 0x00041080, 0x00c21021, 0x8c430000, 0x02031823, 658 0x00021400, 0x00431025, 0xac820018, 0x12200005, 0x3c020800, 0x944358ce,
445 0x04600004, 0x24820001, 0x30440007, 0x1485fff9, 0x00041080, 0x10870007, 659 0x8f840018, 0x0a000eb8, 0x3c024013, 0x944358ce, 0x8f840018, 0x3c024014,
446 0x3c030800, 0xa3640121, 0x8c620094, 0x24110005, 0x24420001, 0x0a0009b6, 660 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8e700014, 0x8f620040,
447 0xac620094, 0x24110004, 0x32220001, 0x1040001e, 0x8e820020, 0x1040001d, 661 0x14500003, 0x00501023, 0x0a000ec3, 0x00001021, 0x28420001, 0x1040003a,
448 0x32220004, 0x0e001006, 0x00000000, 0x8f820018, 0xac520000, 0x8f840018, 662 0x00000000, 0x0e000fae, 0x02002021, 0xaf700040, 0x9362003e, 0x30420001,
449 0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 663 0x1440000b, 0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022,
450 0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000, 664 0x3c020800, 0x8c440098, 0x0064182b, 0x14600025, 0x3c020800, 0x3c029000,
451 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018,
452 0x3c024010, 0x00621825, 0x0e001044, 0xaca3001c, 0x32220004, 0x10400076,
453 0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02421025, 0xa360007c,
454 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023,
455 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c,
456 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff,
457 0x93620023, 0x3042007f, 0xa3620023, 0xaf700064, 0x3c023fff, 0x0a000a03,
458 0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011, 0x00000000, 0x8f65005c,
459 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf700064, 0x00a32823,
460 0x00852821, 0x0045102b, 0x10400004, 0x02051021, 0x3c053fff, 0x34a5ffff,
461 0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c, 0x8f620054, 0x16020005,
462 0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a,
463 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800,
464 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021,
465 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074,
466 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001,
467 0x02421025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004,
468 0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000,
469 0x34420001, 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 665 0x34420001, 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
470 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02421025, 666 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d,
471 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 667 0x8f640074, 0x34630001, 0x02431825, 0xaf430020, 0x04810006, 0x3c038000,
472 0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b, 0x8e830020, 668 0x02402021, 0x0e000470, 0x24050273, 0x0a000ef6, 0x24020001, 0x8f4201f8,
473 0x27500100, 0x38420006, 0x10600029, 0x2c510001, 0x0e001006, 0x00000000, 669 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5201c0, 0xa34201c4,
474 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x96020008, 0xac820004, 670 0xaf4301f8, 0x24020001, 0xa7620012, 0x0a000efe, 0xa3600022, 0x9743007a,
475 0x8f830018, 0x8e020014, 0xac620008, 0x8f850018, 0x3c026000, 0x8c434448, 671 0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012, 0x97420108, 0x8fbf0024,
476 0xaca3000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f850018, 0x8e030020, 672 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042,
477 0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400, 0x00431025, 673 0x30420001, 0x03e00008, 0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800,
478 0xac820018, 0x12200005, 0x3c020800, 0x9443466e, 0x8f840018, 0x0a000a78, 674 0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400046, 0xafb10014,
479 0x3c024013, 0x9443466e, 0x8f840018, 0x3c024014, 0x00621825, 0xac83001c, 675 0x0e00148e, 0x00000000, 0x8f840018, 0x8e020000, 0xac820000, 0x936300b1,
480 0x0e001044, 0x24040001, 0x8e630014, 0x8f620040, 0x14430003, 0x00431023, 676 0x936200c5, 0x8f850018, 0x00031e00, 0x00021400, 0x34420100, 0x00621825,
481 0x0a000a83, 0x00001021, 0x28420001, 0x10400034, 0x00000000, 0x8f620040, 677 0xaca30004, 0x8f840018, 0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048,
482 0xaf630040, 0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022, 678 0xac62000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f830018, 0x8f620040,
483 0x24420001, 0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b, 679 0x24040001, 0xac620014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800,
484 0x1460001e, 0x3c020800, 0x3c029000, 0x34420001, 0x02421025, 0xaf420020, 680 0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024016, 0x00621825,
485 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 681 0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020,
486 0x9362007d, 0x34630001, 0x3c048000, 0x02431825, 0x34420001, 0xa362007d, 682 0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000,
487 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000,
488 0xaf5201c0, 0xa34201c4, 0x24020001, 0xaf4301f8, 0xa7620012, 0x0a000ab6,
489 0xa3600022, 0x9743007a, 0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012,
490 0x0e000b68, 0x00000000, 0x97420108, 0x8fbf0024, 0x8fb40020, 0x8fb3001c,
491 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042, 0x30420001, 0x03e00008,
492 0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020, 0xafb00010,
493 0x27500100, 0xafbf001c, 0x10400046, 0xafb10014, 0x0e001006, 0x00000000,
494 0x8f840018, 0x8e020000, 0xac820000, 0x936300b1, 0x936200c5, 0x8f850018,
495 0x00031e00, 0x00021400, 0x34420100, 0x00621825, 0xaca30004, 0x8f840018,
496 0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048, 0xac62000c, 0x8f840018,
497 0x96020012, 0xac820010, 0x8f830018, 0x8f620040, 0x24040001, 0xac620014,
498 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800, 0x24514660, 0xaca30018,
499 0x9623000e, 0x8f850018, 0x3c024016, 0x00621825, 0x0e001044, 0xaca3001c,
500 0x96030008, 0x30630010, 0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000,
501 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018, 0xac600004,
502 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
503 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001,
504 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015, 0x00431025, 0x0e001044,
505 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
506 0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020,
507 0xafb00010, 0x27500100, 0xafbf001c, 0x10400041, 0xafb10014, 0x0e001006,
508 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x24020100,
509 0xac820004, 0x8f830018, 0x8e02001c, 0xac620008, 0x8f840018, 0x8e020018,
510 0xac82000c, 0x8f830018, 0x96020012, 0xac620010, 0x8f840018, 0x96020008,
511 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
512 0x24514660, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024017, 0x00621825,
513 0x0e001044, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020,
514 0x1040001a, 0x8e100000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000,
515 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 683 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c,
516 0x8f820018, 0xac400010, 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000, 684 0x8f820018, 0xac400010, 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000,
517 0x8c634448, 0x24040001, 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015, 685 0x8c634448, 0x24040001, 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015,
518 0x00431025, 0x0e001044, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018, 686 0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018,
519 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, 687 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018,
520 0x936200c4, 0x30420002, 0x10400019, 0x00000000, 0x936200c5, 0x936300b1, 688 0x3c120800, 0x8e420020, 0xafb00010, 0x27500100, 0xafbf001c, 0x10400041,
521 0x00431023, 0x304400ff, 0x30830080, 0x10600004, 0x00000000, 0x0000000d, 689 0xafb10014, 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000,
522 0x00000000, 0x24000a6a, 0x93620004, 0x00441023, 0x304400ff, 0x30830080, 690 0x8f840018, 0x24020100, 0xac820004, 0x8f830018, 0x8e02001c, 0xac620008,
523 0x10600004, 0x2482ffff, 0x8f650024, 0x0a000b82, 0x00000000, 0x00022b00, 691 0x8f840018, 0x8e020018, 0xac82000c, 0x8f830018, 0x96020012, 0xac620010,
524 0x8f620024, 0x0045102b, 0x10400002, 0x00000000, 0x8f650024, 0x8f620048, 692 0x8f840018, 0x96020008, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448,
525 0x8f630040, 0x00431823, 0x0065202b, 0x10800004, 0x00000000, 0x8f620040, 693 0x24040001, 0x3c020800, 0x245158c0, 0xaca30018, 0x9623000e, 0x8f850018,
526 0x00451021, 0xaf620048, 0x9762003c, 0x0062102b, 0x10400041, 0x8fbf0010, 694 0x3c024017, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x96030008, 0x30630010,
527 0x10a0003f, 0x3c029000, 0x34420001, 0x3c040800, 0x8c830080, 0x8f450100, 695 0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000, 0x0e00148e, 0x00000000,
528 0x3c068000, 0x24630001, 0x00a21025, 0xac830080, 0xaf420020, 0x8f420020, 696 0x8f820018, 0xac500000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008,
529 0x00461024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 697 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0xac600014,
530 0x00a31825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 698 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001, 0xaca30018, 0x9622000e,
531 0x1440fffd, 0x24020002, 0x3c030800, 0xaf4501c0, 0xa34201c4, 0x8c640020, 699 0x8f850018, 0x3c034015, 0x00431025, 0x0e0014cc, 0xaca2001c, 0x00001021,
532 0x3c021000, 0xaf4201f8, 0x1080001f, 0x8fbf0010, 0x0e001006, 0x00000000, 700 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
533 0x8f830018, 0x8f420100, 0xac620000, 0x8f840018, 0x8f620040, 0xac820004, 701 0x27bdfff0, 0x03e00008, 0x27bd0010, 0x27bdffd0, 0xafb10014, 0x00808821,
534 0x8f850018, 0x8f620048, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018, 702 0xafb40020, 0x00c0a021, 0xafbf0028, 0xafb50024, 0xafb3001c, 0xafb20018,
535 0xac400010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448, 703 0xafb00010, 0x93620023, 0x00e0a821, 0x30420040, 0x1040003e, 0x30b3ffff,
536 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c0240c2, 0x00621825, 704 0x3c120800, 0x8e420020, 0x1040003a, 0x8f70004c, 0x0e00148e, 0x00000000,
537 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018, 705 0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018,
538 0x3c020800, 0x24423958, 0xaf82000c, 0x03e00008, 0x00000000, 0x27bdffe8, 706 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
539 0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003, 0x3c020800, 707 0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800,
540 0x0000000d, 0x3c020800, 0x8c430020, 0x10600026, 0x00001021, 0x0e001006, 708 0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010, 0x00621825,
541 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x8e02001c, 709 0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001b, 0x00000000, 0x0e00148e,
542 0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018, 0xac82000c, 710 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x3c02008d, 0xac820004,
543 0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c106000, 0xac600014, 711 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
544 0x8f840018, 0x8e024448, 0x3c030800, 0xac820018, 0x9462466e, 0x8f840018, 712 0x8f820018, 0xac550014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001,
545 0x3c034012, 0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x8e036800, 713 0xaca30018, 0x9602000e, 0x8f850018, 0x3c034019, 0x00431025, 0x0e0014cc,
546 0x00001021, 0x3c040001, 0x00641825, 0xae036800, 0x0a000c0d, 0x8fbf0014, 714 0xaca2001c, 0x93620023, 0x30420020, 0x14400003, 0x3c120800, 0x1280003f,
547 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x97430078, 715 0x3c029000, 0x8e420020, 0x8f70004c, 0x1040003b, 0x3c029000, 0x0e00148e,
548 0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008, 0xa7630010, 716 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x24020001, 0xac820004,
549 0x27450100, 0x8f640048, 0x8ca30018, 0x00641023, 0x18400021, 0x00000000, 717 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
550 0xaf630048, 0x8f620040, 0x9763003c, 0x00821023, 0x0043102a, 0x1040001a, 718 0x8f820018, 0x24040001, 0xac500014, 0x8f850018, 0x3c026000, 0x8c434448,
551 0x3c029000, 0x8ca40000, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020, 719 0x3c020800, 0x245058c0, 0xaca30018, 0x9603000e, 0x8f850018, 0x3c024010,
552 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d, 720 0x00621825, 0x0e0014cc, 0xaca3001c, 0x8e430020, 0x1060001c, 0x3c029000,
553 0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d, 0xaf430020, 721 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 0x00131400,
554 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0, 722 0xac820004, 0x8f830018, 0xac750008, 0x8f820018, 0xac40000c, 0x8f830018,
555 0xa34201c4, 0xaf4301f8, 0x03e00008, 0x00001021, 0x8f420100, 0x34420001, 723 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c036000, 0x8c634448,
556 0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018, 0xafb10014, 724 0x24040001, 0xaca30018, 0x9602000e, 0x8f850018, 0x3c03401b, 0x00431025,
557 0xafb00010, 0x9362007e, 0x30d000ff, 0x16020029, 0x00808821, 0x93620080, 725 0x0e0014cc, 0xaca2001c, 0x3c029000, 0x34420001, 0x02221025, 0xaf420020,
558 0x16020026, 0x00000000, 0x9362007f, 0x16020023, 0x00000000, 0x9362007a, 726 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023,
559 0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x24000771, 0x0e000f49, 727 0x3c028000, 0x34420001, 0x02221025, 0x8fbf0028, 0x8fb50024, 0x8fb40020,
560 0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825, 0xa370007a, 728 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023,
561 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x3c028000, 0x9363007d, 729 0xaf420020, 0x03e00008, 0x27bd0030, 0x27bdffe0, 0xafb10014, 0x27510100,
562 0x34420001, 0x3c048000, 0x02221025, 0xa363007d, 0xaf420020, 0x8f4201f8, 730 0x3c029000, 0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000,
563 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5101c0, 0xa34201c4, 731 0xafbf0018, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
564 0xaf4301f8, 0x0a000c79, 0x8fbf0018, 0x0000000d, 0x00000000, 0x24000781, 732 0xa7600008, 0x8f63005c, 0x3c028000, 0x34420001, 0xaf630148, 0x8f640050,
565 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 733 0x02021025, 0x3c039000, 0xaf64017c, 0xaf420020, 0x8f450100, 0x34630001,
734 0x3c048000, 0x00a31825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd,
735 0x00000000, 0x9362007d, 0x3c038000, 0x34420001, 0xa362007d, 0x8f640074,
736 0x34630001, 0x00a31825, 0xaf430020, 0x04810006, 0x3c038000, 0x00a02021,
737 0x0e000470, 0x24050de5, 0x0a001093, 0x3c020800, 0x8f4201f8, 0x00431024,
738 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0, 0xa34201c4, 0xaf4301f8,
739 0x3c020800, 0x8c430020, 0x1060001e, 0x8fbf0018, 0x0e00148e, 0x00000000,
740 0x8f830018, 0xac700000, 0x9622000c, 0x8f840018, 0x00021400, 0xac820004,
741 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010,
742 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001,
743 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401f, 0x00621825,
744 0x0e0014cc, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008,
745 0x27bd0020, 0x3c020800, 0x24424c3c, 0xaf82000c, 0x03e00008, 0x00000000,
746 0x27bdffe8, 0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003,
747 0x3c020800, 0x0000000d, 0x3c020800, 0x8c430020, 0x10600020, 0x00001021,
748 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
749 0x8e02001c, 0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018,
750 0xac82000c, 0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c026000,
751 0xac600014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce,
752 0x8f840018, 0x3c024012, 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001,
753 0x00001021, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800,
754 0x97430078, 0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008,
755 0xa7630010, 0x27bdfff0, 0x00001021, 0x03e00008, 0x27bd0010, 0x8f420100,
756 0x34420001, 0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018,
757 0xafb10014, 0xafb00010, 0x9362007e, 0x30d000ff, 0x16020031, 0x00808821,
758 0x8f620178, 0x1602002e, 0x00000000, 0x9362007f, 0x1602002b, 0x00000000,
759 0x9362007a, 0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x240009d2,
760 0x0e0013e6, 0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825,
761 0xa370007a, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000,
762 0x9362007d, 0x3c038000, 0xa362007d, 0x8f640074, 0x34630001, 0x02231825,
763 0xaf430020, 0x04810006, 0x3c038000, 0x02202021, 0x0e000470, 0x240509dd,
764 0x0a001138, 0x8fbf0018, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002,
765 0x3c031000, 0xaf5101c0, 0xa34201c4, 0xaf4301f8, 0x0a001138, 0x8fbf0018,
766 0x0000000d, 0x00000000, 0x240009e2, 0x8fbf0018, 0x8fb10014, 0x8fb00010,
767 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x30a500ff, 0x3c029000, 0x34420001,
768 0x00803821, 0x00e21025, 0x3c038000, 0xafbf0010, 0xaf420020, 0x8f420020,
769 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x00a21025,
770 0xa362007d, 0x8f640074, 0x34630001, 0x00e31825, 0xaf430020, 0x04810006,
771 0x3c038000, 0x00e02021, 0x0e000470, 0x00c02821, 0x0a001161, 0x8fbf0010,
772 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4701c0,
773 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
566 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x10600024, 0xafbf0014, 774 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x10600024, 0xafbf0014,
567 0x0e001006, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 775 0x0e00148e, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018,
568 0x8e020004, 0xac820004, 0x8f830018, 0x8e020018, 0xac620008, 0x8f840018, 776 0x8e020004, 0xac820004, 0x8f830018, 0x8e020018, 0xac620008, 0x8f840018,
569 0x8e03001c, 0xac83000c, 0x9602000c, 0x9203000a, 0x8f840018, 0x00021400, 777 0x8e03001c, 0xac83000c, 0x9602000c, 0x9203000a, 0x8f840018, 0x00021400,
570 0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 778 0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
571 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018, 779 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018,
572 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014, 780 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014,
573 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, 781 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8,
574 0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e001006, 0x00000000, 782 0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e00148e, 0x00000000,
575 0x8f820018, 0xac400000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 783 0x8f820018, 0xac400000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008,
576 0x8f830018, 0xac60000c, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400, 784 0x8f830018, 0xac60000c, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400,
577 0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 785 0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018,
578 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018, 786 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x946458ce, 0x8f850018,
579 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014, 787 0x00021400, 0x00441025, 0x24040001, 0x0e0014cc, 0xaca2001c, 0x8fbf0014,
580 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010, 0x27500100, 788 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010, 0x27500100,
581 0xafbf0014, 0x9602000c, 0x10400024, 0x00802821, 0x3c020800, 0x8c430020, 789 0xafbf0014, 0x9602000c, 0x10400024, 0x00802821, 0x3c020800, 0x8c430020,
582 0x1060003a, 0x8fbf0014, 0x0e001006, 0x00000000, 0x8f840018, 0x8e030000, 790 0x1060003a, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f840018, 0x8e030000,
583 0xac830000, 0x9602000c, 0x8f840018, 0x00021400, 0xac820004, 0x8f830018, 791 0xac830000, 0x9602000c, 0x8f840018, 0x00021400, 0xac820004, 0x8f830018,
584 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 792 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018,
585 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 793 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800,
586 0xaca30018, 0x9443466e, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e001044, 794 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e0014cc,
587 0xaca3001c, 0x0a000d19, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015, 795 0xaca3001c, 0x0a0011ff, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015,
588 0x3c029000, 0x34420001, 0x00a21025, 0xaf420020, 0x3c038000, 0x8f420020, 796 0x3c029000, 0x34420001, 0x00a21025, 0xaf420020, 0x3c038000, 0x8f420020,
589 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x93620005, 0x34630001, 797 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x93620005, 0x34630001,
590 0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000553, 798 0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000766,
591 0xaf430020, 0x0a000d19, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 799 0xaf430020, 0x0a0011ff, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010,
592 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 800 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010,
593 0x27500100, 0x10600022, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f840018, 801 0x27500100, 0x10600022, 0xafbf0014, 0x0e00148e, 0x00000000, 0x8f840018,
594 0x8e020004, 0xac820000, 0x9603000c, 0x9762002c, 0x8f840018, 0x00031c00, 802 0x8e020004, 0xac820000, 0x9603000c, 0x9762002c, 0x8f840018, 0x00031c00,
595 0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 803 0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
596 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 804 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000,
597 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 805 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018,
598 0x3c02400e, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x8e040000, 806 0x3c02400e, 0x00621825, 0x0e0014cc, 0xaca3001c, 0x0e00122e, 0x8e040000,
599 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c038000, 0x8f420278, 807 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c038000, 0x8f420278,
600 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf440240, 0xa3420244, 808 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf440240, 0xa3420244,
601 0x03e00008, 0xaf430278, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014, 809 0x03e00008, 0xaf430278, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014,
602 0x00808821, 0xafb20018, 0x00c09021, 0xafb00010, 0x30b0ffff, 0x1060001c, 810 0x00808821, 0xafb20018, 0x00c09021, 0xafb00010, 0x30b0ffff, 0x1060001c,
603 0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, 811 0xafbf001c, 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018,
604 0x00101400, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 812 0x00101400, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c,
605 0x8f830018, 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000, 813 0x8f830018, 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000,
606 0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024019, 814 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024019,
607 0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf001c, 0x8fb20018, 815 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018,
608 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x27450100, 816 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x27450100,
609 0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620029, 0x00803021, 0x3c029000, 817 0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620031, 0x00803021, 0x3c029000,
610 0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 818 0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024,
611 0x1440fffd, 0x3c028000, 0x34420001, 0x3c049000, 0x34840001, 0x3c058000, 819 0x1440fffd, 0x3c028000, 0x34420001, 0x3c049000, 0x34840001, 0x3c058000,
612 0x24030012, 0x00c21025, 0x00c42025, 0xa363003f, 0xaf420020, 0xaf440020, 820 0x24030012, 0x00c21025, 0x00c42025, 0xa363003f, 0xaf420020, 0xaf440020,
613 0x8f420020, 0x00451024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001, 821 0x8f420020, 0x00451024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000,
614 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020, 0x8f4201f8, 822 0x34420020, 0xa362007d, 0x8f640074, 0x34630001, 0x00c31825, 0xaf430020,
615 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 823 0x04810006, 0x3c038000, 0x00c02021, 0x0e000470, 0x24050906, 0x0a0012a1,
616 0xaf4301f8, 0x0a000db3, 0x8fbf0010, 0x00c02021, 0x94a5000c, 0x24060001, 824 0x8fbf0010, 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000,
617 0x0e000f78, 0x240706d8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800, 825 0xaf4601c0, 0xa34201c4, 0xaf4301f8, 0x0a0012a1, 0x8fbf0010, 0x00c02021,
618 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021, 0xafb20018, 0x00a09021, 826 0x94a5000c, 0x24060001, 0x0e000fb1, 0x2407090e, 0x8fbf0010, 0x03e00008,
619 0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c, 0x0e001006, 0x00000000, 827 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021,
620 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018, 828 0xafb20018, 0x00a09021, 0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c,
621 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 829 0x0e00148e, 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001,
622 0xac520014, 0x8f840018, 0x3c026000, 0x8c434448, 0x3c020800, 0xac830018, 830 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
623 0x9443466e, 0x8f840018, 0x3c024010, 0x00621825, 0xac83001c, 0x0e001044, 831 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000, 0x8c434448,
624 0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 832 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024010, 0x00621825,
625 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x93620005, 0x30420001, 833 0xac83001c, 0x0e0014cc, 0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
626 0x10400033, 0x00808021, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 834 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010,
627 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 835 0x93620005, 0x30420001, 0x10400036, 0x00808021, 0x3c029000, 0x34420001,
628 0x3c048000, 0x3c030800, 0x304200fe, 0xa3620005, 0x8c620020, 0x34840001, 836 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd,
629 0x02042025, 0xaf440020, 0x10400020, 0x8fbf0014, 0x0e001006, 0x00000000, 837 0x00000000, 0x93620023, 0x34420004, 0xa3620023, 0x93630005, 0x3c048000,
630 0x8f820018, 0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00, 838 0x3c020800, 0x306300fe, 0xa3630005, 0x8c430020, 0x34840001, 0x02042025,
631 0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 839 0xaf440020, 0x10600020, 0x8fbf0014, 0x0e00148e, 0x00000000, 0x8f820018,
632 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 840 0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00, 0x00431025,
633 0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c02400a, 841 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018,
634 0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0014, 0x8fb00010, 842 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, 0x8c434448,
635 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021, 843 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c02400a, 0x00621825,
636 0x9364003f, 0x24030012, 0x00021402, 0x1483001c, 0x304500ff, 0x3c029000, 844 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf0014, 0x8fb00010, 0x03e00008,
637 0x34420001, 0x3c038000, 0x00c21025, 0xa3650080, 0xa365007a, 0xaf420020, 845 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014, 0x00808821,
638 0x8f420020, 0x00431024, 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 846 0xafb20018, 0x00a09021, 0xafb00010, 0x30d000ff, 0x1060002f, 0xafbf001c,
639 0x3c048000, 0x00c21025, 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 847 0x0e00148e, 0x00000000, 0x8f820018, 0xac510000, 0x8f830018, 0xac700004,
640 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8, 848 0x8f820018, 0xac520008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
641 0x0a000e54, 0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x93620080, 849 0x9763006a, 0x00032880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081,
642 0x1045000b, 0x00000000, 0xa3650080, 0x8f820000, 0x93660080, 0x8f440180, 850 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
643 0x8f65004c, 0x8c430000, 0x0060f809, 0x00000000, 0x0a000e54, 0x8fbf0010, 851 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021,
644 0xa3650080, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 852 0x8f830018, 0x2402fffe, 0x00822824, 0x3c026000, 0xac650014, 0x8f840018,
645 0x27bdffe0, 0xafb10014, 0x00808821, 0xafb20018, 0x00a09021, 0xafb00010, 853 0x8c434448, 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c024011,
646 0x30d000ff, 0x1060002f, 0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018, 854 0x00621825, 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018,
647 0xac510000, 0x8f830018, 0xac700004, 0x8f820018, 0xac520008, 0x8f830018, 855 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0014,
648 0xac60000c, 0x8f820018, 0xac400010, 0x9763006a, 0x00032880, 0x50a00001, 856 0xafb00010, 0x8f440100, 0x27500100, 0x8f650050, 0x0e0010fc, 0x9206001b,
649 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 857 0x3c020800, 0x8c430020, 0x1060001d, 0x8e100018, 0x0e00148e, 0x00000000,
650 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 858 0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f840018,
651 0x00c4182b, 0x54600001, 0x00c02021, 0x8f830018, 0x2402fffe, 0x00822824, 859 0x8f620050, 0xac820008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
652 0x3c026000, 0xac650014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018, 860 0x8f830018, 0x3c026000, 0xac600014, 0x8f850018, 0x8c434448, 0x24040001,
653 0x9443466e, 0x8f840018, 0x3c024011, 0x00621825, 0xac83001c, 0x0e001044, 861 0x3c020800, 0xaca30018, 0x944358ce, 0x8f850018, 0x3c02401c, 0x00621825,
654 0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 862 0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
655 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f440100, 0x27500100, 863 0x8f430238, 0x3c020800, 0x04610013, 0x8c44009c, 0x2406fffe, 0x3c050800,
656 0x8f650050, 0x0e000c45, 0x9206001b, 0x3c020800, 0x8c430020, 0x1060001d, 864 0x3c038000, 0x2484ffff, 0x14800009, 0x00000000, 0x97420078, 0x8ca3007c,
657 0x8e100018, 0x0e001006, 0x00000000, 0x8f840018, 0x8f420100, 0xac820000, 865 0x24420001, 0x00461024, 0x24630001, 0xa7620010, 0x03e00008, 0xaca3007c,
658 0x8f830018, 0xac700004, 0x8f840018, 0x8f620050, 0xac820008, 0x8f830018, 866 0x8f420238, 0x00431024, 0x1440fff3, 0x2484ffff, 0x8f420140, 0x3c031000,
659 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0x3c026000, 0xac600014, 867 0xaf420200, 0x03e00008, 0xaf430238, 0x27bdffe8, 0x3c029000, 0xafbf0010,
660 0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 868 0x8f450140, 0x34420001, 0x3c038000, 0x00a21025, 0xaf420020, 0x8f420020,
661 0x8f850018, 0x3c02401c, 0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0014, 869 0x00431024, 0x1440fffd, 0x00000000, 0x9362007d, 0x3c038000, 0x34420001,
662 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c029000, 0x8f460140, 0x34420001, 870 0xa362007d, 0x8f640074, 0x34630001, 0x00a31825, 0xaf430020, 0x04810006,
663 0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 871 0x3c038000, 0x00a02021, 0x0e000470, 0x24050ac7, 0x0a0013b9, 0x8fbf0010,
664 0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000, 0x24020012, 872 0x8f4201f8, 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4501c0,
665 0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082, 0xaf440020, 873 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x0000000d,
666 0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000, 0x9362007d, 874 0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x24020001,
667 0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020, 875 0x03e00008, 0xa7620010, 0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001,
668 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 876 0x38820010, 0x2c420001, 0x00621825, 0x14600003, 0x24020012, 0x14820003,
669 0xa34201c4, 0x03e00008, 0xaf4301f8, 0x8f430238, 0x3c020800, 0x04610013, 877 0x00000000, 0x03e00008, 0x00001021, 0x9363007e, 0x9362007a, 0x14620006,
670 0x8c44009c, 0x2406fffe, 0x3c050800, 0x3c038000, 0x2484ffff, 0x14800009, 878 0x00000000, 0x9363007e, 0x24020001, 0x24630001, 0x03e00008, 0xa363007e,
671 0x00000000, 0x97420078, 0x8ca3007c, 0x24420001, 0x00461024, 0x24630001, 879 0x9362007e, 0x8f630178, 0x304200ff, 0x14430006, 0x00000000, 0x9363000b,
672 0xa7620010, 0x03e00008, 0xaca3007c, 0x8f420238, 0x00431024, 0x1440fff3, 880 0x24020001, 0x24630001, 0x03e00008, 0xa363000b, 0x03e00008, 0x00001021,
673 0x2484ffff, 0x8f420140, 0x3c031000, 0xaf420200, 0x03e00008, 0xaf430238, 881 0x9362000b, 0x10400023, 0x00001021, 0xa360000b, 0x9362003f, 0x304400ff,
674 0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020, 882 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825, 0x14600017,
675 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d, 883 0x00001821, 0x24020012, 0x10820014, 0x00000000, 0x9363007e, 0x9362007a,
676 0x34630001, 0x3c058000, 0x00831825, 0x34420001, 0xa362007d, 0xaf430020, 884 0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001, 0xa362007e,
677 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0, 885 0x03e00008, 0x00601021, 0x9362007e, 0x8f630178, 0x304200ff, 0x14430005,
678 0xa34201c4, 0x03e00008, 0xaf4301f8, 0x0000000d, 0x03e00008, 0x00000000, 886 0x00001821, 0x9362000b, 0x24030001, 0x24420001, 0xa362000b, 0x03e00008,
679 0x0000000d, 0x03e00008, 0x00000000, 0x24020001, 0x03e00008, 0xa7620010, 887 0x00601021, 0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc,
680 0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 888 0x8f6200cc, 0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008,
681 0x00621825, 0x14600003, 0x24020012, 0x14820003, 0x00000000, 0x03e00008, 889 0xa7640016, 0x3c020800, 0x8c430020, 0x27bdffe8, 0x1060001b, 0xafbf0010,
682 0x00001021, 0x9363007e, 0x9362007a, 0x14620006, 0x00000000, 0x9363007e, 890 0x0e00148e, 0x00000000, 0x8f820018, 0xac400000, 0x8f830018, 0xac600004,
683 0x24020001, 0x24630001, 0x03e00008, 0xa363007e, 0x9363007e, 0x93620080, 891 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010,
684 0x14620004, 0x24020001, 0xa362000b, 0x03e00008, 0x24020001, 0x03e00008, 892 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448, 0x3c020800,
685 0x00001021, 0x9362000b, 0x10400021, 0x00001021, 0xa360000b, 0x9362003f, 893 0xac830018, 0x944358ce, 0x8f840018, 0x3c024020, 0x00621825, 0xac83001c,
686 0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825, 894 0x0e0014cc, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800,
687 0x14600015, 0x00001821, 0x24020012, 0x10820012, 0x00000000, 0x9363007e, 895 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00a08021, 0xafb10014, 0x00c08821,
688 0x9362007a, 0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001, 896 0xafb20018, 0x00e09021, 0x1060001e, 0xafbf001c, 0x0e00148e, 0x00000000,
689 0xa362007e, 0x03e00008, 0x00601021, 0x9363007e, 0x93620080, 0x14620004, 897 0x8f840018, 0x8f420100, 0xac820000, 0x8f830018, 0xac700004, 0x8f820018,
690 0x00001821, 0x24020001, 0xa362000b, 0x24030001, 0x03e00008, 0x00601021, 898 0xac510008, 0x8f830018, 0xac72000c, 0x8f840018, 0x8fa20030, 0xac820010,
691 0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc, 0x8f6200cc, 899 0x8f830018, 0x8fa20034, 0xac620014, 0x8f840018, 0x3c026000, 0x8c434448,
692 0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008, 0xa7640016, 900 0x3c020800, 0xac830018, 0x944358ce, 0x8f840018, 0x3c0240c9, 0x00621825,
693 0x27bdffd8, 0xafb00010, 0x00808021, 0xafb3001c, 0x00c09821, 0xafbf0020, 901 0xac83001c, 0x0e0014cc, 0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014,
694 0xafb20018, 0xafb10014, 0x93620023, 0x00e09021, 0x30420040, 0x10400020, 902 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x8c430020, 0x27bdffe8,
695 0x30b1ffff, 0x3c020800, 0x8c430020, 0x1060001c, 0x00000000, 0x0e001006, 903 0xafb00010, 0x27500100, 0x1060001d, 0xafbf0014, 0x0e00148e, 0x00000000,
696 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004, 904 0x8f830018, 0x8e020004, 0xac620000, 0x8f840018, 0x8e020018, 0xac820004,
697 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 905 0x8f850018, 0x8e020000, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018,
698 0x8f820018, 0xac520014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 906 0xac400010, 0x8f830018, 0xac600014, 0x8f820018, 0xac400018, 0x96030008,
699 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825, 907 0x3c020800, 0x944458ce, 0x8f850018, 0x00031c00, 0x00641825, 0x24040001,
700 0x0e001044, 0xaca3001c, 0x93620023, 0x30420020, 0x14400003, 0x3c020800, 908 0x0e0014cc, 0xaca3001c, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
701 0x52600020, 0x3c029000, 0x8c430020, 0x1060001d, 0x3c029000, 0x0e001006, 909 0x3c060800, 0x24c558c0, 0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a,
702 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004, 910 0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d,
703 0x8f830018, 0xac720008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 911 0x00000000, 0x2400005a, 0x0a0014a3, 0x24020001, 0x8f820014, 0x0062102b,
704 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 912 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001c, 0x274a0400,
705 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c02401b, 0x00621825, 913 0x3c07000a, 0x3c020800, 0x244558c0, 0x94a9000a, 0x8f880014, 0x03471021,
706 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 914 0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023,
707 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023, 915 0x00021400, 0x00021403, 0x04410006, 0x0048102b, 0x0000000d, 0x00000000,
708 0x3c028000, 0x34420001, 0x02021025, 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 916 0x2400005a, 0x0a0014be, 0x24020001, 0x14400002, 0x00001021, 0x24020001,
709 0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023, 0xaf420020, 0x03e00008, 917 0x304200ff, 0x1440ffec, 0x03471021, 0x24c458c0, 0x8c820010, 0xaf420038,
710 0x27bd0028, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 918 0x8c830014, 0x3c020005, 0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018,
711 0x1060001d, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020004, 919 0x03e00008, 0x00000000, 0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800,
712 0xac620000, 0x8f840018, 0x8e020018, 0xac820004, 0x8f850018, 0x8e020000, 920 0x24e858c0, 0xafbf001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a,
713 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 921 0x8d060014, 0x00009021, 0x309000ff, 0x00e08821, 0x24420001, 0x24a50020,
714 0xac600014, 0x8f820018, 0xac400018, 0x96030008, 0x3c020800, 0x9444466e, 922 0x24630001, 0xaf820010, 0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000,
715 0x8f850018, 0x00031c00, 0x00641825, 0x24040001, 0x0e001044, 0xaca3001c, 923 0x04c10007, 0xad030014, 0x00621024, 0x14400005, 0x262258c0, 0x8d020010,
716 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c060800, 0x24c54660, 924 0x24420001, 0xad020010, 0x262258c0, 0x9444000a, 0x94450018, 0x0010102b,
717 0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a, 0x00441023, 0x00021400, 925 0x00a41826, 0x2c630001, 0x00621825, 0x1060001c, 0x3c030006, 0x8f820010,
718 0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d, 0x00000000, 0x2400005a, 926 0x24120001, 0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000,
719 0x0a00101b, 0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021, 927 0x00000000, 0x27450400, 0x8f420000, 0x30420010, 0x1040fffd, 0x262258c0,
720 0x24020001, 0x304200ff, 0x1040001c, 0x274a0400, 0x3c07000a, 0x3c020800, 928 0x9444000a, 0x94430018, 0xaf800010, 0xaf850018, 0x14830012, 0x262758c0,
721 0x24454660, 0x94a9000a, 0x8f880014, 0x03471021, 0x94430006, 0x00402021, 929 0x0e00155a, 0x00000000, 0x1600000e, 0x262758c0, 0x0e00148e, 0x00000000,
722 0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023, 0x00021400, 0x00021403, 930 0x0a001517, 0x262758c0, 0x00041c00, 0x00031c03, 0x00051400, 0x00021403,
723 0x04410006, 0x0048102b, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001036, 931 0x00621823, 0x18600002, 0x3c026000, 0xac400808, 0x262758c0, 0x94e2000e,
724 0x24020001, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1440ffec, 932 0x94e3000c, 0x24420001, 0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e,
725 0x03471021, 0x24c44660, 0x8c820010, 0xaf420038, 0x8c830014, 0x3c020005, 933 0x12000005, 0x3c02000a, 0x94e2000a, 0xa74200a2, 0x0a001554, 0x02401021,
726 0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018, 0x03e00008, 0x00000000, 934 0x03421821, 0x94640006, 0x94e2000a, 0x00441023, 0x00021400, 0x00021c03,
727 0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800, 0x24e84660, 0xafbf001c, 935 0x04610006, 0xa4e40006, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001536,
728 0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a, 0x8d060014, 0x00009021, 936 0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021, 0x24020001,
729 0x309000ff, 0x00e08821, 0x24420001, 0x24a50020, 0x24630001, 0xaf820010, 937 0x304200ff, 0x1040001b, 0x3c020800, 0x3c06000a, 0x244558c0, 0x94a8000a,
730 0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000, 0x04c10007, 0xad030014, 938 0x8f870014, 0x03461021, 0x94430006, 0x00402021, 0xa4a30006, 0x94820006,
731 0x00621024, 0x14400005, 0x26224660, 0x8d020010, 0x24420001, 0xad020010, 939 0xa4a20006, 0x01021023, 0x00021400, 0x00021403, 0x04410006, 0x0047102b,
732 0x26224660, 0x9444000a, 0x94450018, 0x0010102b, 0x00a41826, 0x2c630001, 940 0x0000000d, 0x00000000, 0x2400005a, 0x0a001550, 0x24020001, 0x14400002,
733 0x00621825, 0x1060001c, 0x3c030006, 0x8f820010, 0x24120001, 0x00021140, 941 0x00001021, 0x24020001, 0x304200ff, 0x1440ffec, 0x03461021, 0x02401021,
734 0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27450400, 942 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
735 0x8f420000, 0x30420010, 0x1040fffd, 0x26224660, 0x9444000a, 0x94430018, 943 0x3c020800, 0x244558c0, 0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0,
736 0xaf800010, 0xaf850018, 0x14830012, 0x26274660, 0x0e0010d2, 0x00000000, 944 0x00832021, 0xaf44003c, 0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008,
737 0x1600000e, 0x26274660, 0x0e001006, 0x00000000, 0x0a00108f, 0x26274660, 945 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x8f420000, 0x30420020,
738 0x00041c00, 0x00031c03, 0x00051400, 0x00021403, 0x00621823, 0x18600002, 946 0x1040fffd, 0x00000000, 0x8f430400, 0x24c658c0, 0xacc30010, 0x8f420404,
739 0x3c026000, 0xac400808, 0x26274660, 0x94e2000e, 0x94e3000c, 0x24420001, 947 0x3c030020, 0xacc20014, 0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a,
740 0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e, 0x12000005, 0x3c02000a, 948 0x94c5001e, 0x00832021, 0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002,
741 0x94e2000a, 0xa74200a2, 0x0a0010cc, 0x02401021, 0x03421821, 0x94640006, 949 0xa4c40018, 0xa4c0001a, 0x03e00008, 0x00000000, 0x8f820010, 0x3c030006,
742 0x94e2000a, 0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4e40006, 950 0x00021140, 0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000,
743 0x0000000d, 0x00000000, 0x2400005a, 0x0a0010ae, 0x24020001, 0x8f820014, 951 0x27430400, 0x8f420000, 0x30420010, 0x1040fffd, 0x00000000, 0xaf800010,
744 0x0062102b, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001b, 952 0xaf830018, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800,
745 0x3c020800, 0x3c06000a, 0x24454660, 0x94a8000a, 0x8f870014, 0x03461021, 953 0x261058c0, 0x3c05000a, 0x02002021, 0x03452821, 0xafbf0014, 0x0e0015b0,
746 0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01021023, 954 0x2406000a, 0x96020002, 0x9603001e, 0x3042000f, 0x24420003, 0x00431804,
747 0x00021400, 0x00021403, 0x04410006, 0x0047102b, 0x0000000d, 0x00000000, 955 0x24027fff, 0x0043102b, 0xaf830014, 0x10400004, 0x00000000, 0x0000000d,
748 0x2400005a, 0x0a0010c8, 0x24020001, 0x14400002, 0x00001021, 0x24020001, 956 0x00000000, 0x24000043, 0x0e00155a, 0x00000000, 0x8fbf0014, 0x8fb00010,
749 0x304200ff, 0x1440ffec, 0x03461021, 0x02401021, 0x8fbf001c, 0x8fb20018, 957 0x03e00008, 0x27bd0018, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff,
750 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x24454660, 958 0x24a50004, 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000,
751 0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0, 0x00832021, 0xaf44003c, 959 0x0a0015c1, 0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004,
752 0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008, 0xaf420030, 0x00000000, 960 0x00a01021, 0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c036000,
753 0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x00000000, 961 0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582, 0x00042302, 0x308403ff,
754 0x8f430400, 0x24c64660, 0xacc30010, 0x8f420404, 0x3c030020, 0xacc20014, 962 0x00052d82, 0x00441026, 0x0002102b, 0x0005282b, 0x00451025, 0x1440000d,
755 0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a, 0x94c5001e, 0x00832021, 963 0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c, 0xaf420030, 0x00000000,
756 0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002, 0xa4c40018, 0xa4c0001a, 964 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030,
757 0x03e00008, 0x00000000, 0x8f820010, 0x3c030006, 0x00021140, 0x00431025, 965 0x0000000d, 0x03e00008, 0x00000000, 0x3c020050, 0x34420004, 0xaf440038,
758 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27430400, 0x8f420000, 966 0xaf45003c, 0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020,
759 0x30420010, 0x1040fffd, 0x00000000, 0xaf800010, 0xaf830018, 0x03e00008, 967 0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008, 0x00000000, 0x00000000};
760 0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800, 0x26104660, 0x3c05000a,
761 0x02002021, 0x03452821, 0xafbf0014, 0x0e001128, 0x2406000a, 0x96020002,
762 0x9603001e, 0x3042000f, 0x24420003, 0x00431804, 0x24027fff, 0x0043102b,
763 0xaf830014, 0x10400004, 0x00000000, 0x0000000d, 0x00000000, 0x24000043,
764 0x0e0010d2, 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018,
765 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000,
766 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a001137, 0x00a01021,
767 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008,
768 0x00000000, 0x3c036000, 0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582,
769 0x00042302, 0x308403ff, 0x00052d82, 0x00441026, 0x0002102b, 0x0005282b,
770 0x00451025, 0x1440000d, 0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c,
771 0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd,
772 0x3c020020, 0xaf420030, 0x0000000d, 0x03e00008, 0x00000000, 0x3c020050,
773 0x34420004, 0xaf440038, 0xaf45003c, 0xaf420030, 0x00000000, 0x00000000,
774 0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008,
775 0x00000000, 0x00000000 };
776
777static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x00000000 };
778static u32 bnx2_COM_b06FwRodata[(0x18/4) + 1] = {
779 0x08002318, 0x08002348, 0x08002378, 0x080023a8, 0x080023d8, 0x00000000,
780 0x00000000 };
781 968
782static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x00000000 }; 969static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 };
783static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x00000000 }; 970static u32 bnx2_COM_b06FwRodata[(0x58/4) + 1] = {
971 0x08002428, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c,
972 0x08002380, 0x0800245c, 0x080023e4, 0x0800245c, 0x0800231c, 0x0800245c,
973 0x0800245c, 0x0800245c, 0x08002328, 0x00000000, 0x08003240, 0x08003270,
974 0x080032a0, 0x080032d0, 0x08003300, 0x00000000, 0x00000000 };
975static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x0 };
976static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x0 };
784 977
785static int bnx2_RXP_b06FwReleaseMajor = 0x0; 978static int bnx2_RXP_b06FwReleaseMajor = 0x1;
786static int bnx2_RXP_b06FwReleaseMinor = 0x0; 979static int bnx2_RXP_b06FwReleaseMinor = 0x0;
787static int bnx2_RXP_b06FwReleaseFix = 0x0; 980static int bnx2_RXP_b06FwReleaseFix = 0x0;
788static u32 bnx2_RXP_b06FwStartAddr = 0x08000060; 981static u32 bnx2_RXP_b06FwStartAddr = 0x08003104;
789static u32 bnx2_RXP_b06FwTextAddr = 0x08000000; 982static u32 bnx2_RXP_b06FwTextAddr = 0x08000000;
790static int bnx2_RXP_b06FwTextLen = 0x20b8; 983static int bnx2_RXP_b06FwTextLen = 0x562c;
791static u32 bnx2_RXP_b06FwDataAddr = 0x080020e0; 984static u32 bnx2_RXP_b06FwDataAddr = 0x08005660;
792static int bnx2_RXP_b06FwDataLen = 0x0; 985static int bnx2_RXP_b06FwDataLen = 0x0;
793static u32 bnx2_RXP_b06FwRodataAddr = 0x00000000; 986static u32 bnx2_RXP_b06FwRodataAddr = 0x00000000;
794static int bnx2_RXP_b06FwRodataLen = 0x0; 987static int bnx2_RXP_b06FwRodataLen = 0x0;
795static u32 bnx2_RXP_b06FwBssAddr = 0x08002100; 988static u32 bnx2_RXP_b06FwBssAddr = 0x08005680;
796static int bnx2_RXP_b06FwBssLen = 0x239c; 989static int bnx2_RXP_b06FwBssLen = 0x1394;
797static u32 bnx2_RXP_b06FwSbssAddr = 0x080020e0; 990static u32 bnx2_RXP_b06FwSbssAddr = 0x08005660;
798static int bnx2_RXP_b06FwSbssLen = 0x14; 991static int bnx2_RXP_b06FwSbssLen = 0x18;
799 992static u32 bnx2_RXP_b06FwText[(0x562c/4) + 1] = {
800static u32 bnx2_RXP_b06FwText[(0x20b8/4) + 1] = { 993 0x0a000c41, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x322e352e,
801 0x0a000018, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x302e362e, 994 0x38000000, 0x02050803, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
802 0x39000000, 0x00060903, 0x00000000, 0x0000000d, 0x00000000, 0x00000000,
803 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 995 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
804 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 996 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
805 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 997 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
806 0x244220e0, 0x3c030800, 0x2463449c, 0xac400000, 0x0043202b, 0x1480fffd, 998 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
807 0x24420004, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100060, 999 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
808 0x3c1c0800, 0x279c20e0, 0x0e000329, 0x00000000, 0x0000000d, 0x8f870008, 1000 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
809 0x2ce20080, 0x10400018, 0x3c030800, 0x24633490, 0x8f460100, 0x00072140, 1001 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
810 0x00831021, 0xac460000, 0x8f450104, 0x00641021, 0xac450004, 0x8f460108, 1002 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
811 0xac460008, 0x8f45010c, 0xac45000c, 0x8f460114, 0xac460010, 0x8f450118, 1003 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
812 0xac450014, 0x8f460124, 0xac460018, 0x8f450128, 0x00641821, 0x24e20001, 1004 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
813 0xaf820008, 0xac65001c, 0x03e00008, 0x00000000, 0x00804021, 0x8f830000, 1005 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
814 0x24070001, 0x3c020001, 0x00621024, 0x10400037, 0x00603021, 0x9742010e, 1006 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
815 0x3c038000, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 1007 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
816 0xa342018b, 0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 1008 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
817 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000069, 0x00021400, 1009 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
818 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 1010 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
819 0x24020003, 0x30838000, 0x1060000d, 0xa7420188, 0x93420116, 0x304200fc, 1011 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
820 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600005, 0x00000000, 1012 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
821 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 1013 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
822 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 1014 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
823 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x30c21000, 1015 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
824 0x1040000f, 0x00000000, 0x9742010c, 0x3042fc00, 0x5440000b, 0x24070005, 1016 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
825 0x3c021000, 0x00c21024, 0x10400007, 0x3c030dff, 0x3463ffff, 0x3c020e00, 1017 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
826 0x00c21024, 0x0062182b, 0x54600001, 0x24070005, 0x8f82000c, 0x30434000, 1018 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
827 0x10600016, 0x00404821, 0x3c020f00, 0x00c21024, 0x14400012, 0x00000000, 1019 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1020 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1021 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1022 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1023 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1024 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1025 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1026 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1027 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1028 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1029 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1030 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1031 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1032 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1033 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1034 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1035 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1036 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1037 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1038 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1039 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1040 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1041 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1042 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1043 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1044 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1045 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1046 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1047 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1048 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1049 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1050 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1051 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1052 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1053 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1054 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1055 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1056 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1057 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1058 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1059 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1060 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1061 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1062 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1063 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1064 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1065 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1066 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1067 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1068 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1069 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1070 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1071 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1072 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1073 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1074 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1075 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1076 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1077 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1078 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1079 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1080 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1081 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1082 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1083 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1084 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1085 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1086 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1087 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1088 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1089 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1090 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1091 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1092 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1093 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1094 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1095 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1096 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1097 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1098 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1099 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1100 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1101 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1102 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1103 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1104 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1105 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1106 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1107 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1108 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1109 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1110 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1111 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1112 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1113 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1114 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1115 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1116 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1117 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1118 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1119 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1120 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1121 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1122 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1123 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1124 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1125 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1126 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1127 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1128 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1129 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1130 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1131 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1132 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1133 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1134 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1135 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1136 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1137 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1138 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1139 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1140 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1141 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1142 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1143 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1144 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1145 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1146 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1147 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1148 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1149 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1150 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1151 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1152 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1153 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1154 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1155 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1156 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1157 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1158 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1159 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1160 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1161 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1162 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1163 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1164 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1165 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1166 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1167 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1168 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1169 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1170 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1171 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1172 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1173 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1174 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1175 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1176 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1177 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1178 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1179 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1180 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1181 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1182 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1183 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1184 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1185 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1186 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1187 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1188 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1189 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1190 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1191 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1192 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1193 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1194 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1195 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1196 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1197 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1198 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1199 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1200 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1201 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1202 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1203 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1204 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1205 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1206 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1207 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1208 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1209 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1210 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1211 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1212 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1213 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1214 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1215 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1216 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1217 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1218 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1219 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1220 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1221 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1222 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1223 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1224 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1225 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1226 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1227 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1228 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1229 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1230 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1231 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1232 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1233 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1234 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1235 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1236 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1237 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1238 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1239 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1240 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1241 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1242 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1243 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1244 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1245 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1246 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1247 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1248 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1249 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1250 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1251 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1252 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1253 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1254 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1255 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1256 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1257 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1258 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1259 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1260 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1261 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1262 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1263 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1264 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1265 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1266 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1267 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1268 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1269 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1270 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1271 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1272 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1273 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1274 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1275 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1276 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1277 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1278 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1279 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1280 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1281 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1282 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1283 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1284 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1285 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1286 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1287 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1288 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1289 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1290 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1291 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1292 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1293 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1294 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1295 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1296 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1297 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1298 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1299 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1300 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1301 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1302 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1303 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1304 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1305 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1306 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1307 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1308 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1309 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1310 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1311 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1312 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1313 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1314 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1315 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1316 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1317 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1318 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1319 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1320 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1321 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1322 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1323 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1324 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1325 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1326 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1327 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1328 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1329 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1330 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1331 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1332 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1333 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1334 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1335 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1336 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1337 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1338 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1339 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1340 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1341 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1342 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1343 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1344 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1345 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1346 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1347 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1348 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1349 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1350 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1351 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1352 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1353 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1354 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1355 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1356 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1357 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1358 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1359 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1360 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1361 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1362 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1363 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1364 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1365 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1366 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1367 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1368 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1369 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1370 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1371 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1372 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1373 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1374 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1375 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1376 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1377 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1378 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1379 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1380 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1381 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1382 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1383 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1384 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1385 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1386 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1387 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1388 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1389 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1390 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1391 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1392 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1393 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1394 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1395 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1396 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1397 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1398 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1399 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1400 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1401 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1402 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1403 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1404 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1405 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1406 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1407 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1408 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1409 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1410 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1411 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1412 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1413 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1414 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1415 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1416 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1417 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1418 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1419 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1420 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1421 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1422 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1423 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1424 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1425 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1426 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1427 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1428 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1429 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1430 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1431 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1432 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1433 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1434 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1435 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1436 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1437 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1438 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1439 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1440 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1441 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1442 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1443 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1444 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1445 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1446 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1447 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1448 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1449 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1450 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1451 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1452 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1453 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1454 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1455 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1456 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1457 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1458 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1459 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1460 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1461 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1462 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1463 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1464 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1465 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1466 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1467 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1468 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1469 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1470 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1471 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1472 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1473 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1474 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1475 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1476 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1477 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1478 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1479 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1480 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1481 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1482 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1483 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1484 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1485 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1486 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1487 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1488 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1489 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1490 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1491 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1492 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1493 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1494 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1495 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1496 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1497 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1498 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1499 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1500 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1501 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1502 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1503 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1504 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1505 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1506 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1507 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1508 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1509 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1510 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1511 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1512 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1513 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1514 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1515 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1516 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425660,
1517 0x3c030800, 0x24636a14, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004,
1518 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x26103104, 0x3c1c0800,
1519 0x279c5660, 0x0e001035, 0x00000000, 0x0000000d, 0x3c080800, 0x8d023100,
1520 0x2c420080, 0x50400001, 0xad003100, 0x8d073100, 0x3c040800, 0x24840100,
1521 0x8f460100, 0x00071840, 0x00671821, 0x00031940, 0x00641021, 0xac460000,
1522 0x8f450104, 0x00831021, 0xac450004, 0x8f460108, 0xac460008, 0x8f45010c,
1523 0xac45000c, 0x8f460114, 0xac460010, 0x8f450118, 0xac450014, 0x8f460124,
1524 0xac460018, 0x8f450128, 0xac45001c, 0x8f464010, 0xac460020, 0x8f454014,
1525 0xac450024, 0x8f464018, 0xac460028, 0x8f45401c, 0xac45002c, 0x8f464020,
1526 0xac460030, 0x8f454024, 0xac450034, 0x8f464028, 0xac460038, 0x8f45402c,
1527 0xac45003c, 0x8f464030, 0xac460040, 0x8f454034, 0xac450044, 0x8f464038,
1528 0xac460048, 0x8f45403c, 0xac45004c, 0x8f464040, 0xac460050, 0x8f454044,
1529 0xac450054, 0x8f464048, 0xac460058, 0x8f45404c, 0x24e70001, 0x00402021,
1530 0xad073100, 0x03e00008, 0xac85005c, 0x8f820004, 0x9743010c, 0x00804821,
1531 0x00403021, 0x30421000, 0x10400010, 0x306affff, 0x30c20020, 0x1440000e,
1532 0x24070005, 0x3c021000, 0x00c21024, 0x10400009, 0x3c030dff, 0x3463ffff,
1533 0x3c020e00, 0x00c21024, 0x0062182b, 0x50600004, 0x24070001, 0x0a000cb1,
1534 0x3c020800, 0x24070001, 0x3c020800, 0x8c430034, 0x1460001d, 0x00405821,
1535 0x8f820010, 0x30424000, 0x1440001a, 0x3c020001, 0x3c021f01, 0x00c24024,
1536 0x3c031000, 0x15030015, 0x3c020001, 0x31420200, 0x54400012, 0x3c020001,
1537 0x9744010e, 0x24020003, 0xa342018b, 0x97850012, 0x24020002, 0x34e30002,
1538 0xaf400180, 0xa742018c, 0xa7430188, 0x24840004, 0x30a5bfff, 0xa744018e,
1539 0xa74501a6, 0xaf4801b8, 0x03e00008, 0x00001021, 0x3c020001, 0x00c21024,
1540 0x10400039, 0x00000000, 0x9742010e, 0x3c038000, 0x3046ffff, 0x8f4201b8,
1541 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c,
1542 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005,
1543 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000cec, 0x00021400, 0x9743011e,
1544 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x24020003,
1545 0x30838000, 0x1060000d, 0xa7420188, 0x93420116, 0x304200fc, 0x005a1021,
1546 0x24424004, 0x8c430000, 0x3063ffff, 0x14600005, 0x00000000, 0x3c02ffff,
1547 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
1548 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
1549 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f820010, 0x30434000,
1550 0x10600016, 0x00404021, 0x3c020f00, 0x00c21024, 0x14400012, 0x00000000,
828 0x93420116, 0x34424000, 0x03421821, 0x94650002, 0x2ca21389, 0x1040000b, 1551 0x93420116, 0x34424000, 0x03421821, 0x94650002, 0x2ca21389, 0x1040000b,
829 0x3c020800, 0x24422100, 0x00051942, 0x00031880, 0x00621821, 0x30a5001f, 1552 0x3c020800, 0x24425680, 0x00051942, 0x00031880, 0x00621821, 0x30a5001f,
830 0x8c640000, 0x24020001, 0x00a21004, 0x00822024, 0x01044025, 0x11000037, 1553 0x8c640000, 0x24020001, 0x00a21004, 0x00822024, 0x01244825, 0x11200039,
831 0x3c021000, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, 0x3045ffff, 1554 0x3c021000, 0x9742010e, 0x34e70002, 0x3c038000, 0x24420004, 0x3046ffff,
832 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004, 1555 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006,
833 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005, 0xa745018e, 1556 0x8f85000c, 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e,
834 0x9743011c, 0x9742011e, 0x0a0000cd, 0x00021400, 0x9743011e, 0x9742011c, 1557 0x10a00005, 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000d41, 0x00021400,
835 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 1558 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010,
836 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000,
837 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c,
838 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff,
839 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008,
840 0x00001021, 0x00c21024, 0x104000ba, 0x3c020800, 0x8c430030, 0x1060003e,
841 0x31224000, 0x1040003c, 0x3c030f00, 0x00c31824, 0x3c020100, 0x0043102b,
842 0x14400038, 0x3c030800, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004,
843 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b,
844 0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005,
845 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000110, 0x00021400, 0x9743011e,
846 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000,
847 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
848 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
849 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
850 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
851 0x03e00008, 0x00001021, 0x3c030800, 0x8c620024, 0x30420008, 0x1040003d,
852 0x34e80002, 0x3c020f00, 0x00c21024, 0x5440003a, 0x3107ffff, 0x9742010c,
853 0x30420200, 0x50400036, 0x3107ffff, 0x9742010e, 0x30e6fffb, 0x3c038000,
854 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
855 0xa342018b, 0x8f840004, 0x24020180, 0x24030002, 0xaf420180, 0xa743018c,
856 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000153, 0x00021400,
857 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
858 0x30828000, 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021,
859 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
860 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
861 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
862 0xaf4201b8, 0x3107ffff, 0x8f820000, 0x3c068000, 0x9743010e, 0x00021442,
863 0x30440780, 0x24630004, 0x3065ffff, 0x8f4201b8, 0x00461024, 0x1440fffd,
864 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf440180, 0xa742018c,
865 0x10600005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000189, 0x00021400,
866 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c,
867 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 1559 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
868 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 1560 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
869 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 1561 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff,
870 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 1562 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
871 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f424000, 0x30420100, 0x104000ef, 1563 0xaf4201b8, 0x03e00008, 0x00001021, 0x00c21024, 0x104000e3, 0x3c020800,
872 0x3c020800, 0x8c440024, 0x24030001, 0x14830036, 0x00404021, 0x9742010e, 1564 0x8c430030, 0x10600040, 0x31024000, 0x1040003e, 0x3c030f00, 0x00c31824,
873 0x34e50002, 0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024, 1565 0x3c020100, 0x0043102b, 0x1440003a, 0x3c030800, 0x9742010e, 0x34e70002,
874 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180, 1566 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
875 0xa742018c, 0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0001c6, 1567 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c, 0x24020080, 0x24030002,
1568 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005, 0xa7440190, 0x9743011c,
1569 0x9742011e, 0x0a000d86, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400,
1570 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188,
1571 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff,
1572 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012,
1573 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825,
1574 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021,
1575 0x3c030800, 0x8c620024, 0x30420008, 0x1040003e, 0x34e80002, 0x3c020f00,
1576 0x00c21024, 0x1440003b, 0x8d620034, 0x31420200, 0x10400038, 0x8d620034,
1577 0x9742010e, 0x30e7fffb, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8,
1578 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c,
1579 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005,
1580 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000dca, 0x00021400, 0x9743011e,
1581 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000,
1582 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
1583 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
1584 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
1585 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
1586 0x8d620034, 0x8f860004, 0x1040001a, 0x30c20100, 0x10400018, 0x3c020f00,
1587 0x00c21024, 0x3c030200, 0x10430014, 0x00000000, 0x8f82000c, 0x10400004,
1588 0x00000000, 0x9742011c, 0x0a000df8, 0x3044ffff, 0x9742011e, 0x3044ffff,
1589 0x3c030800, 0x8c620038, 0x3c030800, 0x2463003c, 0x2442ffff, 0x00822024,
1590 0x00831821, 0x90620000, 0x24420004, 0x0a000e0d, 0x000229c0, 0x00000000,
1591 0x00061602, 0x3042000f, 0x000229c0, 0x3c04fc00, 0x00441021, 0x3c030300,
1592 0x0062182b, 0x50600001, 0x24050800, 0x9742010e, 0x3107ffff, 0x3c038000,
1593 0x24420004, 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
1594 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf450180, 0xa742018c,
1595 0xa746018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a000e26,
876 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 1596 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
877 0x8f84000c, 0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc, 1597 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc,
878 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 1598 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
879 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 1599 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
880 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 1600 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
881 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x30820001, 0x10400035, 1601 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f424000, 0x30420100,
882 0x30e90004, 0x9742010e, 0x30e6fffb, 0x3c038000, 0x24420004, 0x3044ffff, 1602 0x104000f9, 0x3c020800, 0x8c440024, 0x24030001, 0x14830038, 0x00404821,
883 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 1603 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8,
884 0x24020002, 0xaf400180, 0xa742018c, 0x10600005, 0xa744018e, 0x9743011c, 1604 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97830006, 0x8f84000c,
885 0x9742011e, 0x0a0001fe, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 1605 0x24020002, 0xaf400180, 0xa742018c, 0xa745018e, 0x10800005, 0xa7430190,
886 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188, 1606 0x9743011c, 0x9742011e, 0x0a000e65, 0x00021400, 0x9743011e, 0x9742011c,
887 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 1607 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c,
888 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 1608 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000,
889 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 1609 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010,
890 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x30c7ffff, 0x8d020024, 1610 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff,
891 0x30420004, 0x10400037, 0x8d020024, 0x9742010e, 0x30e6fffb, 0x3c038000, 1611 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008,
892 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 1612 0x00001021, 0x30820001, 0x10400037, 0x30ea0004, 0x9742010e, 0x30e8fffb,
893 0xa342018b, 0x8f840004, 0x24020100, 0x24030002, 0xaf420180, 0xa743018c, 1613 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd,
894 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000237, 0x00021400, 1614 0x24020003, 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf400180,
895 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 1615 0xa742018c, 0xa745018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e,
896 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 1616 0x0a000e9f, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825,
897 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 1617 0xaf4301a8, 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116,
898 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff,
899 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
900 0xaf4201b8, 0x30c7ffff, 0x8d020024, 0x30420008, 0x10400034, 0x00000000,
901 0x9742010e, 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024,
902 0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004, 0x24020180, 0x24030002,
903 0xaf420180, 0xa743018c, 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e,
904 0x0a00026f, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825,
905 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116,
906 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 1618 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004,
907 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 1619 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c,
908 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 1620 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6,
909 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x15200046, 0x00001021, 0x3c038000, 1621 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x3107ffff, 0x8d220024, 0x30420004,
910 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0x24032000, 0xa342018b, 1622 0x10400039, 0x8d220024, 0x9742010e, 0x30e8fffb, 0x3c038000, 0x24420004,
911 0xa7430188, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x3c030800, 1623 0x3046ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b,
912 0x8c620024, 0x30420001, 0x10400035, 0x00001021, 0x9742010e, 0x34e50002, 1624 0x97840006, 0x8f85000c, 0x24020100, 0x24030002, 0xaf420180, 0xa743018c,
913 0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 1625 0xa746018e, 0x10a00005, 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000eda,
914 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180, 0xa742018c, 1626 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
915 0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0002b5, 0x00021400, 1627 0x8f840010, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc,
916 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 1628 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
917 0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc, 0x005a1021, 1629 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
918 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 1630 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
919 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 1631 0x3c021000, 0xaf4201b8, 0x3107ffff, 0x8d220024, 0x30420008, 0x10400036,
920 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 1632 0x00000000, 0x9742010e, 0x3c038000, 0x24420004, 0x3046ffff, 0x8f4201b8,
921 0xaf4201b8, 0x00001021, 0x03e00008, 0x00000000, 0x27bdffe0, 0xafbf0018, 1633 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x97840006, 0x8f85000c,
922 0xafb10014, 0xafb00010, 0x8f420140, 0xaf420020, 0x8f430148, 0x3c027000, 1634 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0xa746018e, 0x10a00005,
923 0x00621824, 0x3c024000, 0x1062000c, 0x0043102b, 0x14400006, 0x3c025000, 1635 0xa7440190, 0x9743011c, 0x9742011e, 0x0a000f14, 0x00021400, 0x9743011e,
924 0x3c023000, 0x1062000b, 0x3c024000, 0x0a00031f, 0x00000000, 0x10620034, 1636 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010, 0x30828000,
925 0x3c024000, 0x0a00031f, 0x00000000, 0x0e00067c, 0x00000000, 0x0a00031f, 1637 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004,
1638 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024,
1639 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00,
1640 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8,
1641 0x1540004a, 0x00001021, 0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024,
1642 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b, 0xa4800010,
1643 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x3c030800, 0x8c620024,
1644 0x30420001, 0x10400037, 0x00001021, 0x9742010e, 0x34e60002, 0x3c038000,
1645 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
1646 0xa342018b, 0x97830006, 0x8f84000c, 0x24020002, 0xaf400180, 0xa742018c,
1647 0xa745018e, 0x10800005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a000f5e,
1648 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8,
1649 0x8f840010, 0x30828000, 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc,
1650 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff,
1651 0x34427fff, 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104,
1652 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac,
1653 0x3c021000, 0xaf4201b8, 0x00001021, 0x03e00008, 0x00000000, 0x27bdffe8,
1654 0xafbf0010, 0x8f460128, 0x8f84000c, 0xaf460020, 0x8f450104, 0x8f420100,
1655 0x24030800, 0xaf850004, 0xaf820010, 0xaf4301b8, 0x1080000a, 0x3c020800,
1656 0x8c430034, 0x10600007, 0x30a22000, 0x10400005, 0x34a30100, 0x8f820008,
1657 0xaf830004, 0x24420001, 0xaf820008, 0x3c020800, 0x8c4300c0, 0x10600006,
1658 0x3c030800, 0x8c6200c4, 0x24040001, 0x24420001, 0x0a000fc0, 0xac6200c4,
1659 0x8f820004, 0x3c030010, 0x00431024, 0x14400009, 0x3c02001f, 0x3c030800,
1660 0x8c620020, 0x00002021, 0x24420001, 0x0e000c99, 0xac620020, 0x0a000fc0,
1661 0x00402021, 0x3442ff00, 0x14c20009, 0x2403bfff, 0x3c030800, 0x8c620020,
1662 0x24040001, 0x24420001, 0x0e000c99, 0xac620020, 0x0a000fc0, 0x00402021,
1663 0x8f820010, 0x00431024, 0x14400006, 0x00000000, 0xaf400048, 0x0e001144,
1664 0xaf400040, 0x0a000fc0, 0x00402021, 0x0e0014c9, 0x00000000, 0x00402021,
1665 0x10800005, 0x3c024000, 0x8f430124, 0x3c026020, 0xac430014, 0x3c024000,
1666 0xaf420138, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0,
1667 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420140, 0xaf420020, 0x8f430148,
1668 0x3c027000, 0x00621824, 0x3c023000, 0x10620021, 0x0043102b, 0x14400006,
1669 0x3c024000, 0x3c022000, 0x10620009, 0x3c024000, 0x0a00102b, 0x00000000,
1670 0x10620045, 0x3c025000, 0x10620047, 0x3c024000, 0x0a00102b, 0x00000000,
1671 0x27440180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
1672 0x8f420148, 0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148,
1673 0xa4830010, 0x8f420144, 0x3c031000, 0xac820024, 0xaf4301b8, 0x0a00102b,
926 0x3c024000, 0x8f420148, 0x24030002, 0x3044ffff, 0x00021402, 0x305000ff, 1674 0x3c024000, 0x8f420148, 0x24030002, 0x3044ffff, 0x00021402, 0x305000ff,
927 0x1203000c, 0x27510180, 0x2a020003, 0x10400005, 0x24020003, 0x0600001d, 1675 0x1203000c, 0x27510180, 0x2a020003, 0x10400005, 0x24020003, 0x0600001d,
928 0x36053000, 0x0a00030a, 0x3c038000, 0x12020007, 0x00000000, 0x0a000317, 1676 0x36053000, 0x0a001012, 0x3c038000, 0x12020007, 0x00000000, 0x0a00101f,
929 0x00000000, 0x0e000423, 0x00000000, 0x0a000308, 0x00402021, 0x0e000435, 1677 0x00000000, 0x0e00111f, 0x00000000, 0x0a001010, 0x00402021, 0x0e001131,
930 0x00000000, 0x00402021, 0x36053000, 0x3c038000, 0x8f4201b8, 0x00431024, 1678 0x00000000, 0x00402021, 0x36053000, 0x3c038000, 0x8f4201b8, 0x00431024,
931 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, 0xa6240010, 0x8f420144, 1679 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, 0xa6240010, 0x8f420144,
932 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00031f, 0x3c024000, 0x0000000d, 1680 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00102b, 0x3c024000, 0x0000000d,
933 0x00000000, 0x240001c3, 0x0a00031f, 0x3c024000, 0x0e0007f7, 0x00000000, 1681 0x00000000, 0x24000295, 0x0a00102b, 0x3c024000, 0x0e0013a7, 0x00000000,
934 0x3c024000, 0xaf420178, 0x00000000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 1682 0x0a00102b, 0x3c024000, 0x0e001552, 0x00000000, 0x3c024000, 0xaf420178,
935 0x03e00008, 0x27bd0020, 0x24020800, 0x03e00008, 0xaf4201b8, 0x27bdffe8, 1683 0x00000000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
936 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 1684 0x24020800, 0x03e00008, 0xaf4201b8, 0x27bdffe8, 0x3c04600c, 0xafbf0014,
937 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008, 1685 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x3c106000, 0x00431024,
938 0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001, 1686 0x3442380c, 0x24030003, 0xac825000, 0x3c020008, 0xaf430008, 0x8e040808,
939 0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400, 1687 0x0342d825, 0x8e020808, 0x3c030800, 0xac600020, 0x3084fff0, 0x2c840001,
940 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 1688 0x3042fff0, 0x38420010, 0x2c420001, 0xaf84000c, 0xaf820000, 0x0e001574,
941 0x34420200, 0xae021980, 0x8f500000, 0x32020003, 0x1040fffd, 0x32020001, 1689 0x00000000, 0x0e0014c7, 0x00000000, 0x3c020400, 0x3442000c, 0x3c03ffff,
942 0x10400004, 0x32020002, 0x0e0003bd, 0x00000000, 0x32020002, 0x1040fff6, 1690 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 0x34420200, 0xae021980,
943 0x00000000, 0x0e0002d4, 0x00000000, 0x0a00034a, 0x00000000, 0x27bdffe8, 1691 0x8f500000, 0x32020003, 0x1040fffd, 0x32020001, 0x10400004, 0x32020002,
944 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 1692 0x0e000f7d, 0x00000000, 0x32020002, 0x1040fff6, 0x00000000, 0x0e000fcb,
945 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008, 1693 0x00000000, 0x0a00105c, 0x00000000, 0x27bdffe8, 0x3c04600c, 0xafbf0014,
946 0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001, 1694 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x3c106000, 0x00431024,
947 0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400, 1695 0x3442380c, 0x24030003, 0xac825000, 0x3c020008, 0xaf430008, 0x8e040808,
948 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 1696 0x0342d825, 0x8e020808, 0x3c030800, 0xac600020, 0x3084fff0, 0x2c840001,
949 0x8fbf0014, 0x34420200, 0xae021980, 0x8fb00010, 0x03e00008, 0x27bd0018, 1697 0x3042fff0, 0x38420010, 0x2c420001, 0xaf84000c, 0xaf820000, 0x0e001574,
950 0x30a5ffff, 0x30c6ffff, 0x30e7ffff, 0x3c038000, 0x8f4201b8, 0x00431024, 1698 0x00000000, 0x0e0014c7, 0x00000000, 0x3c020400, 0x3442000c, 0x3c03ffff,
951 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0xaf440180, 0xa745018c, 1699 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, 0x8fbf0014, 0x34420200,
952 0x10600005, 0xa746018e, 0x9743011c, 0x9742011e, 0x0a000393, 0x00021400, 1700 0xae021980, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x30a5ffff, 0x30c6ffff,
953 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 1701 0x30e7ffff, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003,
1702 0xa342018b, 0x97830006, 0x8f82000c, 0xaf440180, 0xa745018c, 0xa746018e,
1703 0x10400005, 0xa7430190, 0x9743011c, 0x9742011e, 0x0a0010ad, 0x00021400,
1704 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f840010,
954 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, 1705 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021,
955 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 1706 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff,
956 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 1707 0x00821024, 0xaf820010, 0x97820012, 0x9743010c, 0x8f440104, 0x3042bfff,
957 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 1708 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000,
958 0xaf4201b8, 0x03e00008, 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024, 1709 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180, 0x3c038000, 0x8f4201b8,
959 0x1440fffd, 0x24020002, 0x24032000, 0xa342018b, 0xa7430188, 0x3c021000, 1710 0x00431024, 0x1440fffd, 0x24022000, 0x24030002, 0xa4820008, 0xa083000b,
960 0xaf4201b8, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafbf0010, 0x8f460128, 1711 0xa4800010, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00000000, 0x27440180,
961 0xaf460020, 0x8f420104, 0x8f450100, 0x24030800, 0x3c040010, 0xaf820000, 1712 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420148,
962 0x00441024, 0xaf85000c, 0xaf4301b8, 0x14400005, 0x3c02001f, 0x3c030800, 1713 0x24030002, 0xa083000b, 0x00021402, 0xa4820008, 0x8f430148, 0xa4830010,
963 0x8c620020, 0x0a0003d5, 0x00002021, 0x3442ff00, 0x14c20009, 0x2402bfff, 1714 0x8f420144, 0x3c031000, 0xac820024, 0x03e00008, 0xaf4301b8, 0x27bdffe0,
964 0x3c030800, 0x8c620020, 0x24040001, 0x24420001, 0x0e00004c, 0xac620020,
965 0x0a0003e4, 0x00000000, 0x00a21024, 0x14400006, 0x00000000, 0xaf400048,
966 0x0e000448, 0xaf400040, 0x0a0003e4, 0x00000000, 0x0e000783, 0x00000000,
967 0x10400005, 0x3c024000, 0x8f430124, 0x3c026020, 0xac430014, 0x3c024000,
968 0xaf420138, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0,
969 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002, 0x3044ffff, 1715 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002, 0x3044ffff,
970 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, 0x10400005, 1716 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, 0x10400005,
971 0x24020003, 0x0600001d, 0x36053000, 0x0a00040e, 0x3c038000, 0x12020007, 1717 0x24020003, 0x0600001d, 0x36053000, 0x0a00110a, 0x3c038000, 0x12020007,
972 0x00000000, 0x0a00041b, 0x00000000, 0x0e000423, 0x00000000, 0x0a00040c, 1718 0x00000000, 0x0a001117, 0x00000000, 0x0e00111f, 0x00000000, 0x0a001108,
973 0x00402021, 0x0e000435, 0x00000000, 0x00402021, 0x36053000, 0x3c038000, 1719 0x00402021, 0x0e001131, 0x00000000, 0x00402021, 0x36053000, 0x3c038000,
974 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, 1720 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b,
975 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00041f, 1721 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00111b,
976 0x8fbf0018, 0x0000000d, 0x00000000, 0x240001c3, 0x8fbf0018, 0x8fb10014, 1722 0x8fbf0018, 0x0000000d, 0x00000000, 0x24000295, 0x8fbf0018, 0x8fb10014,
977 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, 0x1040000d, 1723 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, 0x1040000d,
978 0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821, 1724 0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821,
979 0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, 0x03e00008, 1725 0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, 0x03e00008,
980 0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, 0x1040000e, 1726 0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, 0x1040000e,
981 0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821, 1727 0x00001021, 0x3c030800, 0x24635680, 0x00042942, 0x00052880, 0x00a32821,
982 0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, 0x00832024, 1728 0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, 0x00832024,
983 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x27bdffb0, 0x3c026000, 1729 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x27bdffb0, 0xafbf0048,
984 0xafbf0048, 0x8c434448, 0xaf630140, 0x93620005, 0x30420001, 0x14400005, 1730 0x93620023, 0x30420010, 0x1440025b, 0x24020001, 0x93420116, 0x93630005,
985 0x00000000, 0x0e0007ed, 0x00000000, 0x0a00067a, 0x8fbf0048, 0x93420116, 1731 0x34424000, 0x30630001, 0x14600005, 0x03425821, 0x0e001548, 0x00000000,
986 0x93430112, 0x8f430104, 0x3c040020, 0x34424000, 0x00641824, 0x1060000d, 1732 0x0a0013a5, 0x8fbf0048, 0x93420112, 0x8f430104, 0x3c040020, 0x34424000,
987 0x03426021, 0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x24040008, 1733 0x00641824, 0x10600012, 0x03422821, 0x27450180, 0x3c038000, 0x8f4201b8,
988 0x240340c1, 0xa4430008, 0x24030002, 0xa043000b, 0x3c031000, 0x0a000563, 1734 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8f640040,
989 0xa044000a, 0x8f420104, 0x3c030040, 0x00431024, 0x10400007, 0x00000000, 1735 0x24030008, 0x240240c1, 0xa4a20008, 0x24020002, 0xa0a2000b, 0x3c021000,
990 0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x0a00055c, 0x24040010, 1736 0x0a001181, 0xa0a3000a, 0x8f420104, 0x3c030040, 0x00431024, 0x1040001d,
991 0xaf400048, 0xaf400054, 0xaf400040, 0x8f630048, 0x8f620040, 0x00624823, 1737 0x3c038000, 0x27450180, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
992 0x05210004, 0x00000000, 0x0000000d, 0x00000000, 0x24000132, 0x9742011a, 1738 0x8f420128, 0xaca20000, 0x8f640040, 0x24030010, 0x240240c1, 0xa4a20008,
993 0x3046ffff, 0x10c00004, 0x8d880004, 0x01061021, 0x0a000487, 0x2445ffff, 1739 0x24020002, 0xa0a3000a, 0x24030008, 0xa0a2000b, 0x3c021000, 0xa4a30010,
994 0x01002821, 0x918a000d, 0xa7a00020, 0xafa00028, 0x9364003f, 0x3c026000, 1740 0xa0a00012, 0xa0a00013, 0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c,
995 0x8c434448, 0x308700ff, 0x31420004, 0x10400033, 0xaf630144, 0x24090012, 1741 0xaca40018, 0x0e001548, 0xaf4201b8, 0x0a0013a5, 0x8fbf0048, 0x8f820000,
996 0x14e90006, 0x3c040800, 0x8c830028, 0x24020001, 0x24630001, 0x0a00054e, 1742 0x10400016, 0x00000000, 0x8f420104, 0x3c030001, 0x00431024, 0x10400011,
997 0xac830028, 0x8f620044, 0x15020012, 0x97a20020, 0x27a60010, 0x27450180, 1743 0x00000000, 0x8ca3000c, 0x8f620030, 0x1462020c, 0x24020001, 0x8ca30010,
998 0x3442001a, 0xa7a20020, 0x8f630040, 0x3c048000, 0x24020020, 0xa3a70022, 1744 0x8f62002c, 0x14620208, 0x24020001, 0x9763003a, 0x95620000, 0x14430204,
999 0xa3a90023, 0xa3a2001a, 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 1745 0x24020001, 0x97630038, 0x95620002, 0x14430200, 0x24020001, 0xaf400048,
1000 0x00000000, 0x0a000533, 0x00000000, 0x8f620044, 0x01021023, 0x0440009e, 1746 0xaf400054, 0xaf400040, 0x8f690040, 0x8f6a0048, 0x01497023, 0x05c10004,
1001 0x24020001, 0x8f620048, 0x01021023, 0x0441009a, 0x24020001, 0x97a20020, 1747 0x00000000, 0x0000000d, 0x00000000, 0x24000169, 0x9742011a, 0x3046ffff,
1002 0x27a60010, 0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 1748 0x10c00004, 0x8d680004, 0x01061021, 0x0a0011b8, 0x2445ffff, 0x01002821,
1003 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 1749 0x916c000d, 0xa7a00020, 0xa3a0001a, 0xafa00028, 0x9362003f, 0x31830004,
1004 0x00000000, 0x3c026000, 0x8c424448, 0xaf620148, 0x8f630040, 0x00685823, 1750 0x1060003a, 0x304700ff, 0x24040012, 0x14e40006, 0x24020001, 0x3c040800,
1005 0x19600013, 0x00cb102a, 0x54400007, 0x314a00fe, 0x5566000c, 0x010b4021, 1751 0x8c830028, 0x24630001, 0x0a00128d, 0xac830028, 0x8f620044, 0x15020010,
1006 0x31420001, 0x54400009, 0x010b4021, 0x314a00fe, 0x24020001, 0xa7a20020, 1752 0x27a60010, 0x27450180, 0x3c038000, 0x2402001a, 0xa7a20020, 0x24020020,
1007 0x8f630040, 0x00c05821, 0x00003021, 0x0a0004dd, 0xafa30028, 0x00cb1023, 1753 0xafa90028, 0xa3a70022, 0xa3a40023, 0xa3a2001a, 0x8f4201b8, 0x00431024,
1008 0x0a0004dd, 0x3046ffff, 0x00005821, 0x8f620048, 0x2442ffff, 0x00a21823, 1754 0x1440fffd, 0x00000000, 0x0a001272, 0x00000000, 0x8f620044, 0x01021023,
1009 0x18600019, 0x0066102a, 0x14400013, 0x24020001, 0xa7a20020, 0x8f630040, 1755 0x0440001a, 0x010a1023, 0x044100ae, 0x24020001, 0x3c020800, 0x8c4300d8,
1010 0xafa30028, 0x8f620040, 0x55020005, 0x27a60010, 0x55200003, 0x27a60010, 1756 0x10600004, 0x24020001, 0xa7a20020, 0x0a0011ee, 0xafa90028, 0x2402001a,
1011 0x0a0004f6, 0x00c01821, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 1757 0xa7a20020, 0x24020020, 0xafa90028, 0xa3a70022, 0xa3a40023, 0xa3a2001a,
1012 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x8f650048, 0x00c31023, 1758 0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd,
1013 0x3046ffff, 0x314a00f6, 0x3c046000, 0x8c824448, 0x31430002, 0x1060001e, 1759 0x00000000, 0x0a001272, 0x00000000, 0x0a00128d, 0x24020001, 0x01286823,
1014 0xaf62014c, 0x8f620044, 0x1502000e, 0x97a20020, 0x27a60010, 0x34420200, 1760 0x19a00016, 0x00cd102a, 0x54400007, 0x318c00fe, 0x55a6000f, 0x010d4021,
1015 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028, 0x8f4201b8, 1761 0x31820001, 0x5440000c, 0x010d4021, 0x318c00fe, 0x00c06821, 0x3c040800,
1016 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x27a60010, 1762 0x8c8300c8, 0x00003021, 0x24020001, 0xa7a20020, 0xafa90028, 0x24630001,
1017 0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028, 1763 0x0a001212, 0xac8300c8, 0x00cd1023, 0x0a001212, 0x3046ffff, 0x00006821,
1018 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 1764 0x2542ffff, 0x00a21823, 0x1860001e, 0x0066102a, 0x14400018, 0x01402821,
1019 0x3c026000, 0x8c424448, 0x31430010, 0xaf620150, 0x54600003, 0x8d890008, 1765 0x97a20020, 0x3c040800, 0x8c8300cc, 0xafa90028, 0x34420001, 0x24630001,
1020 0x0a00054e, 0x24020001, 0x8f630054, 0x2522ffff, 0x00431023, 0x1840002a, 1766 0xa7a20020, 0x01091026, 0x2c420001, 0xac8300cc, 0x2dc30001, 0x00431024,
1021 0x24020001, 0x27a60010, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 1767 0x1440000a, 0x00c01821, 0x27a60010, 0x27450180, 0x3c038000, 0x8f4201b8,
1022 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x8f420128, 1768 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272, 0x00000000, 0x00c31023,
1023 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, 0x90c4000a, 1769 0x3046ffff, 0x0a00123d, 0x318c00f6, 0x01091023, 0x18400008, 0x97a20020,
1024 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, 0x90c30012, 1770 0x3c040800, 0x8c8300d4, 0xafa80028, 0x34420400, 0x24630001, 0xa7a20020,
1025 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, 0x8cc20024, 1771 0xac8300d4, 0x31820002, 0x1040001c, 0x31820010, 0x8f620044, 0x1502000d,
1026 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001, 0x3c031000, 1772 0x27a60010, 0x97a20020, 0x27450180, 0x3c038000, 0xafa90028, 0x34420001,
1027 0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a00067a, 0x8fbf0048, 1773 0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272,
1028 0x3c026000, 0x8c424448, 0x31430020, 0x10600019, 0xaf620154, 0x8f430128, 1774 0x00000000, 0x97a20020, 0x27450180, 0x3c038000, 0xafa90028, 0x34420001,
1029 0x27420180, 0xac430000, 0x8f650040, 0x24040004, 0x240340c1, 0xa4430008, 1775 0xa7a20020, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x0a001272,
1030 0x24030002, 0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010, 1776 0x00000000, 0x54400003, 0x8d6a0008, 0x0a00128d, 0x24020001, 0x8f630054,
1031 0xa0400012, 0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c, 1777 0x2542ffff, 0x00431023, 0x1840002e, 0x97a20020, 0x27a60010, 0x3c040800,
1032 0xac450018, 0x0e0007ed, 0xaf4301b8, 0x0a00067a, 0x8fbf0048, 0x8f430104, 1778 0x8c8300d0, 0x27450180, 0x3c078000, 0xafa90028, 0x34420001, 0x24630001,
1033 0x8c824448, 0x38e3000a, 0x2c630001, 0xaf620158, 0x38e2000c, 0x2c420001, 1779 0xa7a20020, 0xac8300d0, 0x8f4201b8, 0x00471024, 0x1440fffd, 0x00000000,
1034 0x00621825, 0x14600003, 0x2402000e, 0x14e2002a, 0x00000000, 0x50c00008, 1780 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018,
1035 0x9584000e, 0x10c00004, 0xa7a60040, 0x01061021, 0x0a000583, 0x2445ffff, 1781 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010,
1036 0x01002821, 0x9584000e, 0x93630035, 0x8f62004c, 0x00642004, 0x00892021, 1782 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014,
1037 0x00821023, 0x1840001f, 0x3c026000, 0x8f620018, 0x01021023, 0x1c40000f, 1783 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001,
1038 0x97a20020, 0x8f620018, 0x15020018, 0x3c026000, 0x8f62001c, 0x01221023, 1784 0x3c031000, 0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a0013a5,
1039 0x1c400008, 0x97a20020, 0x8f62001c, 0x15220011, 0x3c026000, 0x8f620058, 1785 0x8fbf0048, 0x31820020, 0x10400011, 0x00000000, 0x95620012, 0x0046102b,
1040 0x00821023, 0x1840000c, 0x97a20020, 0xafa50028, 0xafa80034, 0xafa90038, 1786 0x10400008, 0x97a20020, 0x95660012, 0x10c00003, 0x01061021, 0x0a00129e,
1041 0xafa4003c, 0x34420020, 0x0a0005a8, 0xa7a20020, 0x8f680040, 0x00003021, 1787 0x2445ffff, 0x01002821, 0x97a20020, 0x93a3001a, 0x34420008, 0x34630004,
1042 0x8f640058, 0x01002821, 0x3c026000, 0x8c434448, 0xaf63015c, 0x8f62004c, 1788 0xa7a20020, 0xa3a3001a, 0x8f420104, 0x38e3000a, 0x2c630001, 0x38e2000c,
1043 0x01221023, 0x18400009, 0x00000000, 0x8f620054, 0x01221023, 0x1c400005, 1789 0x2c420001, 0x00621825, 0x14600003, 0x2402000e, 0x54e2002a, 0x00003021,
1044 0x97a20020, 0xafa50028, 0xafa90024, 0x0a0005c3, 0x34420040, 0x9742011a, 1790 0x50c00008, 0x9564000e, 0x10c00004, 0xa7a60040, 0x01061021, 0x0a0012b6,
1045 0x1440000c, 0x24020014, 0x8f620058, 0x14820009, 0x24020014, 0x8f63004c, 1791 0x2445ffff, 0x01002821, 0x9564000e, 0x93630035, 0x8f62004c, 0x00642004,
1046 0x8f620054, 0x10620004, 0x97a20020, 0xafa50028, 0x34420080, 0xa7a20020, 1792 0x008a2021, 0x00821023, 0x1840001d, 0x00000000, 0x8f620018, 0x01021023,
1047 0x24020014, 0x10e2000a, 0x28e20015, 0x10400005, 0x2402000c, 0x10e20006, 1793 0x1c40000f, 0x97a20020, 0x8f620018, 0x15020016, 0x00000000, 0x8f62001c,
1048 0x3c026000, 0x0a000600, 0x00000000, 0x24020016, 0x14e20031, 0x3c026000, 1794 0x01421023, 0x1c400008, 0x97a20020, 0x8f62001c, 0x1542000f, 0x00000000,
1049 0x8f620054, 0x24420001, 0x1522002d, 0x3c026000, 0x24020014, 0x10e2001e, 1795 0x8f620058, 0x00821023, 0x1840000b, 0x97a20020, 0xafa50028, 0xafa80034,
1050 0x28e20015, 0x10400005, 0x2402000c, 0x10e20008, 0x3c026000, 0x0a000600, 1796 0xafaa0038, 0xafa4003c, 0x34420020, 0x0a0012da, 0xa7a20020, 0x01204021,
1051 0x00000000, 0x24020016, 0x10e2000c, 0x97a20020, 0x0a000600, 0x3c026000, 1797 0x01002821, 0x8f640058, 0x8f62004c, 0x01421023, 0x18400009, 0x00000000,
1052 0x97a30020, 0x2402000e, 0xafa50028, 0xa3a70022, 0xa3a20023, 0xafa90024, 1798 0x8f620054, 0x01421023, 0x1c400005, 0x97a20020, 0xafa50028, 0xafaa0024,
1053 0x34630054, 0x0a0005ff, 0xa7a30020, 0x24030010, 0x24040002, 0xafa50028, 1799 0x0a0012f2, 0x34420040, 0x9742011a, 0x1440000c, 0x24020014, 0x8f620058,
1054 0xa3a70022, 0xa3a30023, 0xa3a4001a, 0xafa90024, 0x0a0005fe, 0x3442005d, 1800 0x14820009, 0x24020014, 0x8f63004c, 0x8f620054, 0x10620004, 0x97a20020,
1055 0x97a20020, 0x24030012, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023, 1801 0xafa50028, 0x34420080, 0xa7a20020, 0x24020014, 0x10e2000a, 0x28e20015,
1056 0xa3a4001a, 0xafa90024, 0x3042fffe, 0x3442005c, 0xa7a20020, 0x3c026000, 1802 0x10400005, 0x2402000c, 0x10e20006, 0x31820001, 0x0a001333, 0x00000000,
1057 0x8c434448, 0x31420001, 0xaf630160, 0x1040002c, 0x2402000c, 0x10e20014, 1803 0x24020016, 0x14e20035, 0x31820001, 0x8f620084, 0x24420001, 0x15420031,
1058 0x28e2000d, 0x10400005, 0x2402000a, 0x10e20008, 0x97a20020, 0x0a000631, 1804 0x31820001, 0x24020014, 0x10e20021, 0x28e20015, 0x10400005, 0x2402000c,
1059 0x3c026000, 0x2402000e, 0x10e20018, 0x3c026000, 0x0a000631, 0x00000000, 1805 0x10e20008, 0x31820001, 0x0a001333, 0x00000000, 0x24020016, 0x10e2000c,
1060 0x24030008, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a, 1806 0x31820001, 0x0a001333, 0x00000000, 0x97a30020, 0x2402000e, 0xafa50028,
1061 0x0a00062f, 0x34420013, 0x97a30020, 0x30620004, 0x1440000b, 0x97a20020, 1807 0xa3a70022, 0xa3a20023, 0xafaa0024, 0x34630054, 0x0a001332, 0xa7a30020,
1062 0x3462001b, 0xa7a20020, 0x24020016, 0x24030002, 0xafa50028, 0xa3a70022, 1808 0x97a20020, 0x93a4001a, 0x24030010, 0xafa50028, 0xa3a70022, 0xa3a30023,
1063 0xa3a20023, 0x0a000630, 0xa3a3001a, 0x97a20020, 0x24030010, 0x24040002, 1809 0xafaa0024, 0x3442005d, 0x34840002, 0xa7a20020, 0x0a001332, 0xa3a4001a,
1064 0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a, 0x3442001b, 0xa7a20020, 1810 0x97a20020, 0x24030012, 0xa3a30023, 0x93a3001a, 0xafa50028, 0xa3a70022,
1065 0x3c026000, 0x8c434448, 0x31420009, 0x0002102b, 0x00021023, 0x30420007, 1811 0xafaa0024, 0x3042fffe, 0x3442005c, 0x34630002, 0xa7a20020, 0xa3a3001a,
1066 0x34440003, 0xaf630164, 0x10c00016, 0x24030800, 0x8f820010, 0x27450180, 1812 0x31820001, 0x10400030, 0x2402000c, 0x10e20013, 0x28e2000d, 0x10400005,
1067 0x24420001, 0xaf820010, 0x24020004, 0xaf4301b8, 0xa4a40008, 0xa0a2000b, 1813 0x2402000a, 0x10e20008, 0x97a20020, 0x0a001365, 0x31820009, 0x2402000e,
1068 0x93440120, 0x3c031000, 0xa4a6000e, 0xaca90024, 0xaca80028, 0x008b2021, 1814 0x10e2001b, 0x31820009, 0x0a001366, 0x0002102b, 0x93a4001a, 0x24030008,
1069 0xa4a4000c, 0xaf4301b8, 0x97a20020, 0x00003021, 0x3042ffbf, 0x0a000650, 1815 0xafa50028, 0xa3a70022, 0xa3a30023, 0x0a001361, 0x34420013, 0x97a30020,
1070 0xa7a20020, 0x24060001, 0x3c026000, 0x8c434448, 0xaf630168, 0x97a20020, 1816 0x30620004, 0x14400005, 0x93a2001a, 0x3463001b, 0xa7a30020, 0x0a001354,
1071 0x10400020, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 1817 0x24030016, 0x3463001b, 0xa7a30020, 0x24030010, 0xafa50028, 0xa3a70022,
1072 0x00000000, 0x8f420128, 0xaca20000, 0x8fa30028, 0x240240c1, 0xa4a20008, 1818 0xa3a30023, 0x34420002, 0x0a001364, 0xa3a2001a, 0x97a20020, 0x93a4001a,
1073 0xaca30018, 0x93a4001a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x97a20020, 1819 0x24030010, 0xafa50028, 0xa3a70022, 0xa3a30023, 0x3442001b, 0x34840002,
1074 0xa4a20010, 0x93a30022, 0xa0a30012, 0x93a20023, 0xa0a20013, 0x8fa30024, 1820 0xa7a20020, 0xa3a4001a, 0x31820009, 0x0002102b, 0x00021023, 0x30420007,
1075 0xaca30014, 0x8fa20034, 0xaca20024, 0x8fa30038, 0xaca30028, 0x8fa2003c, 1821 0x10c00017, 0x34440003, 0x8f820014, 0x24030800, 0x27450180, 0x24420001,
1076 0x3c031000, 0xaca2002c, 0xaf4301b8, 0x3c026000, 0x8c434448, 0x00c01021, 1822 0xaf820014, 0x24020004, 0xaf4301b8, 0xa4a40008, 0xa0a2000b, 0x93440120,
1077 0xaf63016c, 0x8fbf0048, 0x03e00008, 0x27bd0050, 0x8f460140, 0x8f470148, 1823 0x3c031000, 0xa4a6000e, 0xacaa0024, 0xaca80028, 0x008d2021, 0xa4a4000c,
1078 0x3c028000, 0x00e24024, 0x00072c02, 0x30a300ff, 0x2402000b, 0x1062008f, 1824 0xaf4301b8, 0x97a20020, 0x00003021, 0x3042ffbf, 0x0a001381, 0xa7a20020,
1079 0x27440180, 0x2862000c, 0x10400011, 0x24020006, 0x1062005a, 0x28620007, 1825 0x24060001, 0x97a20020, 0x10400020, 0x27450180, 0x3c038000, 0x8f4201b8,
1080 0x10400007, 0x24020008, 0x10600024, 0x24020001, 0x10620037, 0x00000000, 1826 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128, 0xaca20000, 0x8fa30028,
1081 0x0a00077e, 0x00000000, 0x106200a9, 0x24020009, 0x106200bb, 0x00071c02, 1827 0x240240c1, 0xa4a20008, 0xaca30018, 0x93a4001a, 0x24020002, 0xa0a2000b,
1082 0x0a00077e, 0x00000000, 0x2402001b, 0x106200c7, 0x2862001c, 0x10400007, 1828 0xa0a4000a, 0x97a20020, 0xa4a20010, 0x93a30022, 0xa0a30012, 0x93a20023,
1083 0x2402000e, 0x106200b1, 0x24020019, 0x106200c2, 0x00071c02, 0x0a00077e, 1829 0xa0a20013, 0x8fa30024, 0xaca30014, 0x8fa20034, 0xaca20024, 0x8fa30038,
1084 0x00000000, 0x24020080, 0x10620060, 0x28620081, 0x10400005, 0x2402001c, 1830 0xaca30028, 0x8fa2003c, 0x3c031000, 0xaca2002c, 0xaf4301b8, 0x00c01021,
1085 0x10620094, 0x00071c02, 0x0a00077e, 0x00000000, 0x240200c2, 0x106200c5, 1831 0x8fbf0048, 0x03e00008, 0x27bd0050, 0x8f470140, 0x8f460148, 0x3c028000,
1086 0x00a01821, 0x0a00077e, 0x00000000, 0x00a01821, 0x3c058000, 0x8f4201b8, 1832 0x00c24024, 0x00062c02, 0x30a300ff, 0x24020019, 0x106200e7, 0x27440180,
1087 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac860000, 1833 0x2862001a, 0x1040001f, 0x24020008, 0x106200be, 0x28620009, 0x1040000d,
1088 0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144, 0x3c021000, 1834 0x24020001, 0x10620046, 0x28620002, 0x50400005, 0x24020006, 0x1060002e,
1835 0x00a01821, 0x0a0014c4, 0x00000000, 0x1062005b, 0x00a01821, 0x0a0014c4,
1836 0x00000000, 0x2402000b, 0x10620084, 0x2862000c, 0x10400005, 0x24020009,
1837 0x106200bc, 0x00061c02, 0x0a0014c4, 0x00000000, 0x2402000e, 0x106200b7,
1838 0x00061c02, 0x0a0014c4, 0x00000000, 0x28620021, 0x10400009, 0x2862001f,
1839 0x104000c1, 0x2402001b, 0x106200bf, 0x2402001c, 0x1062009a, 0x00061c02,
1840 0x0a0014c4, 0x00000000, 0x240200c2, 0x106200ca, 0x286200c3, 0x10400005,
1841 0x24020080, 0x1062005a, 0x00a01821, 0x0a0014c4, 0x00000000, 0x240200c9,
1842 0x106200cd, 0x30c5ffff, 0x0a0014c4, 0x00000000, 0x3c058000, 0x8f4201b8,
1843 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac870000,
1844 0xac800004, 0xa082000a, 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000,
1089 0xac800028, 0xac830024, 0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808, 1845 0xac800028, 0xac830024, 0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808,
1090 0x11000009, 0x00a01821, 0x3c020800, 0x24030002, 0xa0434490, 0x24424490, 1846 0x11000009, 0x00a01821, 0x3c020800, 0x24030002, 0xa0436a08, 0x24426a08,
1091 0xac460008, 0x8f430144, 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8, 1847 0xac470008, 0x8f430144, 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8,
1092 0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 0xac860004, 0xa4830008, 1848 0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 0xac870004, 0xa4830008,
1093 0xa082000a, 0xa082000b, 0xa4870010, 0xac800024, 0x8f420144, 0x3c031000, 1849 0xa082000a, 0xa082000b, 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000,
1094 0xac820028, 0x3c026000, 0xaf4301b8, 0x03e00008, 0xac400808, 0x00a01821, 1850 0xac820028, 0x3c026000, 0xaf4301b8, 0x03e00008, 0xac400808, 0x3c080800,
1095 0x3c080800, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x00000000, 1851 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x00000000, 0xac870000,
1096 0xac860000, 0x91024490, 0x00002821, 0x10400002, 0x25064490, 0x8cc50008, 1852 0x91026a08, 0x00002821, 0x10400002, 0x25076a08, 0x8ce50008, 0xac850004,
1097 0xac850004, 0xa4830008, 0x91034490, 0x24020002, 0xa082000b, 0xa4870010, 1853 0xa4830008, 0x91036a08, 0x24020002, 0xa082000b, 0xa4860010, 0x34630001,
1098 0x34630001, 0xa083000a, 0x8f420144, 0xac820024, 0x91034490, 0x10600002, 1854 0xa083000a, 0x8f420144, 0xac820024, 0x91036a08, 0x10600002, 0x00001021,
1099 0x00001021, 0x8cc20004, 0xac820028, 0x3c021000, 0xaf4201b8, 0x3c026000, 1855 0x8ce20004, 0xac820028, 0x3c021000, 0xaf4201b8, 0x3c026000, 0xa1006a08,
1100 0xa1004490, 0x03e00008, 0xac400808, 0x00a01821, 0x3c058000, 0x8f4201b8, 1856 0x03e00008, 0xac400808, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd,
1101 0x00451024, 0x1440fffd, 0x24020002, 0xa082000b, 0xa4830008, 0xa4870010, 1857 0x24020002, 0xa082000b, 0xa4830008, 0xa4860010, 0x8f420144, 0x3c031000,
1102 0x8f420144, 0x3c031000, 0xa4820012, 0x03e00008, 0xaf4301b8, 0x30e2ffff, 1858 0xa4820012, 0x03e00008, 0xaf4301b8, 0x30c2ffff, 0x14400028, 0x00061c02,
1103 0x14400028, 0x00071c02, 0x93620005, 0x30420004, 0x14400020, 0x3c029000, 1859 0x93620005, 0x30420004, 0x14400020, 0x3c029000, 0x34420001, 0x00e21025,
1104 0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 1860 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000,
1105 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, 0x34630001, 0x00c31825, 1861 0x93620005, 0x3c038000, 0x34630001, 0x00e31825, 0x34420004, 0xa3620005,
1106 0x34420004, 0xa3620005, 0xaf430020, 0x93620005, 0x30420004, 0x14400003, 1862 0xaf430020, 0x93620005, 0x30420004, 0x14400003, 0x3c038000, 0x0000000d,
1107 0x3c038000, 0x0000000d, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 1863 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020005, 0x3c031000,
1108 0x24020005, 0x3c031000, 0xac860000, 0xa082000b, 0xaf4301b8, 0x0a00073d, 1864 0xac870000, 0xa082000b, 0xaf4301b8, 0x0a001473, 0x00061c02, 0x0000000d,
1109 0x00071c02, 0x0000000d, 0x03e00008, 0x00000000, 0x00071c02, 0x3c058000, 1865 0x03e00008, 0x00000000, 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024,
1110 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 1866 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac870000, 0xac800004,
1111 0xac860000, 0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144, 1867 0xa082000a, 0xa083000b, 0xa4860010, 0x8f430144, 0x3c021000, 0xac800028,
1112 0x3c021000, 0xac800028, 0xac830024, 0x03e00008, 0xaf4201b8, 0x00071c02, 1868 0xac830024, 0x03e00008, 0xaf4201b8, 0x3c058000, 0x8f4201b8, 0x00451024,
1113 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 1869 0x1440fffd, 0x24020002, 0xac800000, 0xac870004, 0xa4830008, 0xa082000a,
1114 0xac860004, 0xa4830008, 0xa082000a, 0xa082000b, 0xa4870010, 0xac800024, 1870 0xa082000b, 0xa4860010, 0xac800024, 0x8f420144, 0x3c031000, 0xac820028,
1115 0x8f420144, 0x3c031000, 0xac820028, 0x03e00008, 0xaf4301b8, 0x00071c02, 1871 0x03e00008, 0xaf4301b8, 0x00061c02, 0x3c058000, 0x8f4201b8, 0x00451024,
1116 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 1872 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xa082000a, 0x3c021000,
1117 0x24030002, 0xa082000a, 0x3c021000, 0xac860000, 0xac800004, 0xa083000b, 1873 0xac870000, 0xac800004, 0xa083000b, 0xa4860010, 0xac800024, 0xac800028,
1118 0xa4870010, 0xac800024, 0xac800028, 0x03e00008, 0xaf4201b8, 0x3c058000, 1874 0x03e00008, 0xaf4201b8, 0x00a01821, 0x3c058000, 0x8f4201b8, 0x00451024,
1119 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac860000, 0xac800004, 1875 0x1440fffd, 0x24020002, 0xac870000, 0xac800004, 0xa4830008, 0xa080000a,
1120 0xa4830008, 0xa080000a, 0x0a000748, 0xa082000b, 0x0000000d, 0x03e00008, 1876 0x0a00147e, 0xa082000b, 0x8f440144, 0x3c038000, 0x8f4201b8, 0x00431024,
1121 0x00000000, 0x03e00008, 0x00000000, 0x8f420100, 0x3042003e, 0x14400011, 1877 0x1440fffd, 0x24020002, 0x240340c9, 0xaf470180, 0xa342018b, 0x3c021000,
1122 0x24020001, 0xaf400048, 0x8f420100, 0x304207c0, 0x10400005, 0x00000000, 1878 0xa7430188, 0xaf4401a4, 0xaf4501a8, 0xaf4001ac, 0x03e00008, 0xaf4201b8,
1123 0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001, 0xaf400054, 0xaf400040, 1879 0x0000000d, 0x03e00008, 0x00000000, 0x03e00008, 0x00000000, 0x8f420100,
1124 0x8f420100, 0x30423800, 0x54400001, 0xaf400044, 0x24020001, 0x03e00008, 1880 0x3042003e, 0x14400011, 0x24020001, 0xaf400048, 0x8f420100, 0x304207c0,
1125 0x00000000, 0x3c029000, 0x34420001, 0x00822025, 0xaf440020, 0x3c038000, 1881 0x10400005, 0x00000000, 0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001,
1126 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x03e00008, 0x00000000, 1882 0xaf400054, 0xaf400040, 0x8f420100, 0x30423800, 0x54400001, 0xaf400044,
1127 0x3c028000, 0x34420001, 0x00822025, 0x03e00008, 0xaf440020, 0x8f430128, 1883 0x24020001, 0x03e00008, 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024,
1128 0x27420180, 0xac430000, 0x8f650040, 0x240340c1, 0xa4430008, 0x24030002, 1884 0x1440fffd, 0x24020002, 0x240340c9, 0xaf440180, 0xa342018b, 0x3c021000,
1129 0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010, 0xa0400012, 1885 0xa7430188, 0xaf4501a4, 0xaf4601a8, 0xaf4701ac, 0x03e00008, 0xaf4201b8,
1130 0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c, 0xac450018, 1886 0x3c029000, 0x34420001, 0x00822025, 0xaf440020, 0x3c038000, 0x8f420020,
1131 0x03e00008, 0xaf4301b8, 0x24020001, 0xacc40000, 0x03e00008, 0xa4e50000, 1887 0x00431024, 0x1440fffd, 0x00000000, 0x03e00008, 0x00000000, 0x3c028000,
1132 0x03e00008, 0x24020001, 0x24020001, 0xaf400044, 0x03e00008, 0xaf400050, 1888 0x34420001, 0x00822025, 0x03e00008, 0xaf440020, 0x308600ff, 0x27450180,
1133 0x00803021, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 1889 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000, 0x8f420128,
1134 0x00000000, 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 1890 0xaca20000, 0x8f640040, 0x24030008, 0x240240c1, 0xa4a20008, 0x24020002,
1135 0xaca30018, 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 1891 0xa0a2000b, 0x3c021000, 0xa0a6000a, 0xa4a30010, 0xa0a00012, 0xa0a00013,
1136 0xa4a20010, 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 1892 0xaca00014, 0xaca00024, 0xaca00028, 0xaca0002c, 0xaca40018, 0x03e00008,
1137 0xaca30014, 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc2002c, 1893 0xaf4201b8, 0x24020001, 0xacc40000, 0x03e00008, 0xa4e50000, 0x03e00008,
1138 0x3c031000, 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, 0x03e00008, 1894 0x24020001, 0x24020001, 0xaf400044, 0x03e00008, 0xaf400050, 0x00803021,
1139 0xaf400050, 0x27bdffe8, 0xafbf0010, 0x0e000326, 0x00000000, 0x00002021, 1895 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x00000000,
1140 0x0e00004c, 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f460148, 1896 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018,
1141 0x27450180, 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, 0x00431024, 1897 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010,
1142 0x1440fffd, 0x00000000, 0x8f440140, 0x00061202, 0x304200ff, 0x00061c02, 1898 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014,
1143 0xaca20004, 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, 0xaca30024, 1899 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc2002c, 0x3c031000,
1144 0x10e0000a, 0xaca40000, 0x28e20004, 0x14400005, 0x24020001, 0x24020005, 1900 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, 0x03e00008, 0xaf400050,
1145 0x54e20005, 0xa0a0000a, 0x24020001, 0x0a000816, 0xa0a2000a, 0xa0a0000a, 1901 0x27bdffe8, 0xafbf0010, 0x0e001032, 0x00000000, 0x00002021, 0x0e000c99,
1146 0x3c021000, 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, 0x10c00007, 1902 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f460148, 0x27450180,
1147 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb, 1903 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, 0x00431024, 0x1440fffd,
1148 0x24840004, 0x03e00008, 0x00000000, 0x0a00082a, 0x00a01021, 0xac860000, 1904 0x00000000, 0x8f440140, 0x00061202, 0x304200ff, 0x00061c02, 0xaca20004,
1149 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008, 0x00000000, 1905 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, 0xaca30024, 0x10e0000a,
1150 0x00000000 }; 1906 0xaca40000, 0x28e20004, 0x14400005, 0x24020001, 0x24020005, 0x54e20005,
1907 0xa0a0000a, 0x24020001, 0x0a001571, 0xa0a2000a, 0xa0a0000a, 0x3c021000,
1908 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, 0x10c00007, 0x00000000,
1909 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb, 0x24840004,
1910 0x03e00008, 0x00000000, 0x0a001587, 0x00a01021, 0xac860000, 0x00000000,
1911 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, 0x24a5ffff, 0x03e00008,
1912 0x00000000, 0x00000000 };
1151 1913
1152static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x00000000 }; 1914static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x0 };
1153static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 }; 1915static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
1154static u32 bnx2_RXP_b06FwBss[(0x239c/4) + 1] = { 0x00000000 }; 1916static u32 bnx2_RXP_b06FwBss[(0x1394/4) + 1] = { 0x0 };
1155static u32 bnx2_RXP_b06FwSbss[(0x14/4) + 1] = { 0x00000000 }; 1917static u32 bnx2_RXP_b06FwSbss[(0x18/4) + 1] = { 0x0 };
1156 1918
1157static u32 bnx2_rv2p_proc1[] = { 1919static u32 bnx2_rv2p_proc1[] = {
1158 0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004, 1920 0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004,
@@ -1536,249 +2298,346 @@ static u32 bnx2_rv2p_proc2[] = {
1536 0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000, 2298 0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000,
1537 0x00000018, 0x00570000 }; 2299 0x00000018, 0x00570000 };
1538 2300
1539static int bnx2_TPAT_b06FwReleaseMajor = 0x0; 2301static int bnx2_TPAT_b06FwReleaseMajor = 0x1;
1540static int bnx2_TPAT_b06FwReleaseMinor = 0x0; 2302static int bnx2_TPAT_b06FwReleaseMinor = 0x0;
1541static int bnx2_TPAT_b06FwReleaseFix = 0x0; 2303static int bnx2_TPAT_b06FwReleaseFix = 0x0;
1542static u32 bnx2_TPAT_b06FwStartAddr = 0x08000858; 2304static u32 bnx2_TPAT_b06FwStartAddr = 0x08000860;
1543static u32 bnx2_TPAT_b06FwTextAddr = 0x08000800; 2305static u32 bnx2_TPAT_b06FwTextAddr = 0x08000800;
1544static int bnx2_TPAT_b06FwTextLen = 0x1314; 2306static int bnx2_TPAT_b06FwTextLen = 0x122c;
1545static u32 bnx2_TPAT_b06FwDataAddr = 0x08001b40; 2307static u32 bnx2_TPAT_b06FwDataAddr = 0x08001a60;
1546static int bnx2_TPAT_b06FwDataLen = 0x0; 2308static int bnx2_TPAT_b06FwDataLen = 0x0;
1547static u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000; 2309static u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000;
1548static int bnx2_TPAT_b06FwRodataLen = 0x0; 2310static int bnx2_TPAT_b06FwRodataLen = 0x0;
1549static u32 bnx2_TPAT_b06FwBssAddr = 0x08001b90; 2311static u32 bnx2_TPAT_b06FwBssAddr = 0x08001aa0;
1550static int bnx2_TPAT_b06FwBssLen = 0x80; 2312static int bnx2_TPAT_b06FwBssLen = 0x250;
1551static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001b40; 2313static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001a60;
1552static int bnx2_TPAT_b06FwSbssLen = 0x48; 2314static int bnx2_TPAT_b06FwSbssLen = 0x34;
1553 2315static u32 bnx2_TPAT_b06FwText[(0x122c/4) + 1] = {
1554static u32 bnx2_TPAT_b06FwText[(0x1314/4) + 1] = { 2316 0x0a000218, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20322e35,
1555 0x0a000216, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20302e36, 2317 0x2e313100, 0x02050b01, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1556 0x2e390000, 0x00060901, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2318 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1557 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2319 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1558 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000003, 2320 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
1559 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24421b40, 0x3c030800, 2321 0x24421a60, 0x3c030800, 0x24631cf0, 0xac400000, 0x0043202b, 0x1480fffd,
1560 0x24631c10, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 2322 0x24420004, 0x3c1d0800, 0x37bd2ffc, 0x03a0f021, 0x3c100800, 0x26100860,
1561 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100858, 0x3c1c0800, 0x279c1b40, 2323 0x3c1c0800, 0x279c1a60, 0x0e000546, 0x00000000, 0x0000000d, 0x8f820010,
1562 0x0e00051f, 0x00000000, 0x0000000d, 0x8f820024, 0x27bdffe8, 0xafbf0014,
1563 0x10400004, 0xafb00010, 0x0000000d, 0x00000000, 0x2400015f, 0x8f82001c,
1564 0x8c450008, 0x24030800, 0xaf430178, 0x97430104, 0x3c020008, 0xaf420140, 2324 0x8c450008, 0x24030800, 0xaf430178, 0x97430104, 0x3c020008, 0xaf420140,
1565 0x8f820034, 0x30420001, 0x10400006, 0x3070ffff, 0x24020002, 0x2603fffe, 2325 0x8f820024, 0x30420001, 0x10400007, 0x3069ffff, 0x24020002, 0x2523fffe,
1566 0xa7420146, 0x0a000246, 0xa7430148, 0xa7400146, 0x8f850034, 0x30a20020, 2326 0xa7420146, 0xa7430148, 0x0a000242, 0x3c020800, 0xa7400146, 0x3c020800,
1567 0x0002102b, 0x00021023, 0x30460009, 0x30a30c00, 0x24020400, 0x14620002, 2327 0x8c43083c, 0x1460000e, 0x24020f00, 0x8f820024, 0x30430020, 0x0003182b,
1568 0x34c40001, 0x34c40005, 0xa744014a, 0x3c020800, 0x8c440820, 0x3c030048, 2328 0x00031823, 0x30650009, 0x30420c00, 0x24030400, 0x14430002, 0x34a40001,
1569 0x24020002, 0x00832025, 0x30a30006, 0x1062000d, 0x2c620003, 0x50400005, 2329 0x34a40005, 0xa744014a, 0x0a000264, 0x3c020800, 0x8f830014, 0x14620008,
1570 0x24020004, 0x10600012, 0x3c020001, 0x0a000271, 0x00000000, 0x10620007, 2330 0x00000000, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023, 0x3042000d,
1571 0x24020006, 0x1462000f, 0x3c020111, 0x0a000269, 0x00821025, 0x0a000268, 2331 0x0a000262, 0x34420005, 0x8f820024, 0x30420020, 0x0002102b, 0x00021023,
1572 0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030, 2332 0x30420009, 0x34420001, 0xa742014a, 0x3c020800, 0x8c430820, 0x8f840024,
1573 0x0a000271, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000, 2333 0x3c020048, 0x00621825, 0x30840006, 0x24020002, 0x1082000d, 0x2c820003,
1574 0x00000000, 0x00000000, 0x00000000, 0x8f830030, 0x1060003f, 0x3c048000, 2334 0x50400005, 0x24020004, 0x10800012, 0x3c020001, 0x0a000284, 0x00000000,
1575 0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039, 0x00000000, 2335 0x10820007, 0x24020006, 0x1482000f, 0x3c020111, 0x0a00027c, 0x00621025,
1576 0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000, 0x97421014, 2336 0x0a00027b, 0x3c020101, 0x3c020011, 0x00621025, 0x24030001, 0xaf421000,
1577 0x14400031, 0x00000000, 0x97421008, 0x8f84001c, 0x24420006, 0x00024082, 2337 0xaf830020, 0x0a000284, 0x00000000, 0x00621025, 0xaf421000, 0xaf800020,
1578 0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001, 0x10400004, 2338 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f830020, 0x1060003f,
1579 0x00000000, 0x0000000d, 0x0a0002b0, 0x00081080, 0x5460000f, 0x30a5ffff, 2339 0x3c048000, 0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039,
1580 0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b, 0x00621824, 2340 0x00000000, 0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000,
1581 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fc, 0x8ce20000, 2341 0x97421014, 0x14400031, 0x00000000, 0x97421008, 0x8f840010, 0x24420006,
1582 0x0a0002af, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b, 0x00621824, 2342 0x00024082, 0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001,
1583 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000206, 0x8ce20000, 2343 0x10400004, 0x00000000, 0x0000000d, 0x0a0002c3, 0x00081080, 0x5460000f,
1584 0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000, 0x8c620840, 2344 0x30a5ffff, 0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b,
1585 0x24420001, 0xac620840, 0x8f820008, 0x10400003, 0x00000000, 0x0e000660, 2345 0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fb,
1586 0x00000000, 0x8f840028, 0x02002821, 0x24820008, 0x30421fff, 0x24434000, 2346 0x8ce20000, 0x0a0002c2, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b,
1587 0x0343d821, 0x30a30007, 0xaf840018, 0xaf820028, 0xaf420084, 0x10600002, 2347 0x00621824, 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000205,
1588 0x24a20007, 0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c, 2348 0x8ce20000, 0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000,
1589 0x0064102b, 0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 2349 0x8c620830, 0x24420001, 0xac620830, 0x8f840018, 0x01202821, 0x24820008,
1590 0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021, 0x03421821, 0x3c021000, 2350 0x30421fff, 0x24434000, 0x0343d821, 0x30a30007, 0xaf84000c, 0xaf820018,
1591 0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008, 0x27bd0018, 0x8f820024, 2351 0xaf420084, 0x10600002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000,
1592 0x27bdffe8, 0xafbf0014, 0x10400004, 0xafb00010, 0x0000000d, 0x00000000, 2352 0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023,
1593 0x24000249, 0x8f85001c, 0x24020001, 0xaf820024, 0x8ca70008, 0xa3800023, 2353 0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000,
1594 0x8f620004, 0x3c100800, 0x26041b90, 0x00021402, 0xa3820010, 0x304600ff, 2354 0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x8f830024, 0x27bdffe0,
1595 0x24c60005, 0x0e00064a, 0x00063082, 0x8f640004, 0x8f430108, 0x3c021000, 2355 0xafbf0018, 0xafb10014, 0x30620200, 0x14400004, 0xafb00010, 0x0000000d,
1596 0x00621824, 0xa7840020, 0x10600008, 0x00000000, 0x97420104, 0x93830023, 2356 0x00000000, 0x24000242, 0x00031a82, 0x30630003, 0x000310c0, 0x00431021,
1597 0x2442ffec, 0x34630002, 0xa3830023, 0x0a000304, 0x3045ffff, 0x97420104, 2357 0x00021080, 0x00431021, 0x00021080, 0x3c030800, 0x24631aa0, 0x00438821,
1598 0x2442fff0, 0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x14400004, 2358 0x8e240000, 0x10800004, 0x00000000, 0x0000000d, 0x00000000, 0x2400024d,
1599 0x00000000, 0x93820023, 0x34420001, 0xa3820023, 0x93830023, 0x24020001, 2359 0x8f850010, 0x24020001, 0xae220000, 0x8ca70008, 0xa2200007, 0x8f620004,
1600 0x10620009, 0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003, 2360 0x26300014, 0x02002021, 0x00021402, 0xa2220004, 0x304600ff, 0x24c60005,
1601 0x1062000a, 0x00000000, 0x0a000325, 0x00000000, 0x8f82001c, 0x8c43000c, 2361 0x0e000673, 0x00063082, 0x8f620004, 0xa6220008, 0x8f430108, 0x3c021000,
1602 0x3c04ffff, 0x00641824, 0x00651825, 0x0a000325, 0xac43000c, 0x8f82001c, 2362 0x00621824, 0x10600008, 0x00000000, 0x97420104, 0x92230007, 0x2442ffec,
1603 0x8c430010, 0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004, 2363 0x3045ffff, 0x34630002, 0x0a000321, 0xa2230007, 0x97420104, 0x2442fff0,
1604 0x3042ffff, 0x24420002, 0x00021083, 0xa3820038, 0x304500ff, 0x8f82001c, 2364 0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x54400005, 0x92230007,
1605 0x3c04ffff, 0x00052880, 0x00a22821, 0x8ca70000, 0x97820020, 0x97430104, 2365 0x92220007, 0x34420001, 0xa2220007, 0x92230007, 0x24020001, 0x10620009,
1606 0x00e42024, 0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x93840038, 2366 0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003, 0x1062000a,
1607 0x26061b90, 0x00041080, 0x00461021, 0x90430000, 0x3063000f, 0x00832021, 2367 0x00000000, 0x0a000342, 0x00000000, 0x8f820010, 0x8c43000c, 0x3c04ffff,
1608 0xa3840022, 0x308200ff, 0x3c04fff6, 0x24420003, 0x00021080, 0x00461021, 2368 0x00641824, 0x00651825, 0x0a000342, 0xac43000c, 0x8f820010, 0x8c430010,
1609 0x8c450000, 0x93830022, 0x8f82001c, 0x3484ffff, 0x00a43824, 0x00031880, 2369 0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004, 0x3042ffff,
1610 0x00621821, 0xaf850000, 0xac67000c, 0x93820022, 0x93830022, 0x8f84001c, 2370 0x24420002, 0x00021083, 0xa2220005, 0x304500ff, 0x8f820010, 0x3c04ffff,
1611 0x24420003, 0x00021080, 0x00461021, 0x24630004, 0x00031880, 0xac470000, 2371 0x00052880, 0x00a22821, 0x8ca70000, 0x96220008, 0x97430104, 0x00e42024,
1612 0x93820022, 0x00661821, 0x94670002, 0x00021080, 0x00441021, 0xac670000, 2372 0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x92240005, 0x00041080,
1613 0x24030010, 0xac470010, 0xa7430140, 0x24030002, 0xa7400142, 0xa7400144, 2373 0x02021021, 0x90430000, 0x3c05fff6, 0x34a5ffff, 0x3063000f, 0x00832021,
1614 0xa7430146, 0x97420104, 0x8f840034, 0x24030001, 0x2442fffe, 0x30840006, 2374 0xa2240006, 0x308200ff, 0x24420003, 0x00021080, 0x02021021, 0x8c460000,
1615 0xa7420148, 0x24020002, 0xa743014a, 0x1082000d, 0x2c820003, 0x10400005, 2375 0x308300ff, 0x8f820010, 0x3c04ff3f, 0x00031880, 0x00c53824, 0x00621821,
1616 0x24020004, 0x10800011, 0x3c020009, 0x0a000383, 0x00000000, 0x10820007, 2376 0xae26000c, 0xac67000c, 0x8e22000c, 0x92230006, 0x3484ffff, 0x00441024,
1617 0x24020006, 0x1482000d, 0x3c020119, 0x0a00037d, 0x24030001, 0x0a00037c, 2377 0x24630003, 0x00031880, 0x02031821, 0x00e42024, 0xae22000c, 0xac640000,
1618 0x3c020109, 0x3c020019, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000383, 2378 0x92220006, 0x24420004, 0x00021080, 0x02021021, 0x94470002, 0xac470000,
1619 0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000, 2379 0x92230006, 0x8f820010, 0x00031880, 0x00621821, 0x24020010, 0xac670010,
1620 0x00000000, 0x93820010, 0x24030008, 0x8f840030, 0x24420002, 0x30420007, 2380 0x24030002, 0xa7420140, 0xa7400142, 0xa7400144, 0xa7430146, 0x97420104,
1621 0x00621823, 0x30630007, 0xaf83000c, 0x10800005, 0x3c038000, 0x8f421000, 2381 0x24030001, 0x2442fffe, 0xa7420148, 0xa743014a, 0x8f820024, 0x24030002,
1622 0x00431024, 0x1040fffd, 0x00000000, 0x8f820028, 0xaf820018, 0x24420010, 2382 0x30440006, 0x1083000d, 0x2c820003, 0x10400005, 0x24020004, 0x10800011,
1623 0x30421fff, 0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 2383 0x3c020009, 0x0a0003a5, 0x00000000, 0x10820007, 0x24020006, 0x1482000d,
1624 0x3063ffff, 0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044, 2384 0x3c020119, 0x0a00039f, 0x24030001, 0x0a00039e, 0x3c020109, 0x3c020019,
1625 0x8f840004, 0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002, 2385 0x24030001, 0xaf421000, 0xaf830020, 0x0a0003a5, 0x00000000, 0xaf421000,
1626 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010, 2386 0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x92220004,
1627 0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178, 2387 0x24030008, 0x8f840020, 0x24420002, 0x30420007, 0x00621823, 0x30630007,
1628 0x03e00008, 0x27bd0018, 0x8f820024, 0x27bdffe8, 0xafbf0014, 0x14400004, 2388 0x10800006, 0xae230010, 0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd,
1629 0xafb00010, 0x0000000d, 0x00000000, 0x240002db, 0x8f620004, 0x04410009, 2389 0x00000000, 0x8f820018, 0xaf82000c, 0x24420010, 0x30421fff, 0xaf820018,
1630 0x3c050800, 0x93820022, 0x8f830000, 0x24a41b90, 0xaf800024, 0x24420003, 2390 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007,
1631 0x00021080, 0x00441021, 0xac430000, 0x93820038, 0x24a51b90, 0x93860010, 2391 0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821,
1632 0x3c040001, 0x27700008, 0x24420001, 0x00021080, 0x00451021, 0x8c430000, 2392 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030,
1633 0x24c60005, 0x00063082, 0x00641821, 0x02002021, 0x0e00064a, 0xac430000, 2393 0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021,
1634 0x93840022, 0x3c057fff, 0x8f620004, 0x00042080, 0x00902021, 0x8c830004, 2394 0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008,
1635 0x34a5ffff, 0x00451024, 0x00621821, 0xac830004, 0x93850038, 0x3c07ffff, 2395 0x27bd0020, 0x8f830024, 0x27bdffe0, 0xafbf0018, 0xafb10014, 0x30620200,
1636 0x93840010, 0x00052880, 0x00b02821, 0x8ca30000, 0x97420104, 0x97860020, 2396 0x14400004, 0xafb00010, 0x0000000d, 0x00000000, 0x240002e4, 0x00031a82,
1637 0x00671824, 0x00441021, 0x00461023, 0x3042ffff, 0x00621825, 0xaca30000, 2397 0x30630003, 0x000310c0, 0x00431021, 0x00021080, 0x00431021, 0x00021080,
1638 0x93830023, 0x24020001, 0x10620009, 0x28620002, 0x1440001a, 0x24020002, 2398 0x3c030800, 0x24631aa0, 0x00438021, 0x8e040000, 0x14800004, 0x00000000,
1639 0x10620018, 0x24020003, 0x1062000d, 0x00000000, 0x0a000411, 0x00000000, 2399 0x0000000d, 0x00000000, 0x240002e9, 0x8f620004, 0x04410008, 0x26050014,
1640 0x93820010, 0x97430104, 0x8e04000c, 0x00621821, 0x2463fff2, 0x3063ffff, 2400 0x92020006, 0x8e03000c, 0x24420003, 0x00021080, 0x00a21021, 0xac430000,
1641 0x00872024, 0x00832025, 0x0a000411, 0xae04000c, 0x93820010, 0x97430104, 2401 0xae000000, 0x92020005, 0x24420001, 0x00021080, 0x00a21021, 0x8c430000,
1642 0x8e040010, 0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025, 2402 0x3c040001, 0x00641821, 0xac430000, 0x92060004, 0x27710008, 0x02202021,
1643 0xae040010, 0x9783000e, 0x8f840034, 0x2402000a, 0xa7420140, 0xa7430142, 2403 0x24c60005, 0x0e000673, 0x00063082, 0x92040006, 0x3c057fff, 0x8f620004,
1644 0x93820010, 0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001, 2404 0x00042080, 0x00912021, 0x8c830004, 0x34a5ffff, 0x00451024, 0x00621821,
1645 0xa7430148, 0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005, 2405 0xac830004, 0x92050005, 0x3c07ffff, 0x92040004, 0x00052880, 0x00b12821,
1646 0x24020004, 0x10800011, 0x3c020041, 0x0a000437, 0x00000000, 0x10820007, 2406 0x8ca30000, 0x97420104, 0x96060008, 0x00671824, 0x00441021, 0x00461023,
1647 0x24020006, 0x1482000d, 0x3c020151, 0x0a000431, 0x24030001, 0x0a000430, 2407 0x3042ffff, 0x00621825, 0xaca30000, 0x92030007, 0x24020001, 0x1062000a,
1648 0x3c020141, 0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000437, 2408 0x28620002, 0x1440001d, 0x2402000a, 0x24020002, 0x10620019, 0x24020003,
1649 0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000, 2409 0x1062000e, 0x2402000a, 0x0a000447, 0x00000000, 0x92020004, 0x97430104,
1650 0x00000000, 0x8f820030, 0x93840010, 0x8f850028, 0x10400005, 0x3c038000, 2410 0x8e24000c, 0x00621821, 0x2463fff2, 0x3063ffff, 0x00872024, 0x00832025,
1651 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x2483000a, 0x30620007, 2411 0xae24000c, 0x0a000447, 0x2402000a, 0x92020004, 0x97430104, 0x8e240010,
1652 0x10400002, 0x24620007, 0x304303f8, 0x00a31021, 0x30421fff, 0xaf850018, 2412 0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025, 0xae240010,
1653 0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 2413 0x2402000a, 0xa7420140, 0x96030012, 0x8f840024, 0xa7430142, 0x92020004,
1654 0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044, 0x8f840004, 2414 0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001, 0xa7430148,
1655 0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002, 0x00641023, 2415 0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005, 0x24020004,
1656 0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021, 2416 0x10800011, 0x3c020041, 0x0a00046c, 0x00000000, 0x10820007, 0x24020006,
1657 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008, 2417 0x1482000d, 0x3c020151, 0x0a000466, 0x24030001, 0x0a000465, 0x3c020141,
1658 0x27bd0018, 0x3c026000, 0x8c444448, 0x3c030800, 0xac64082c, 0x8f620000, 2418 0x3c020051, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00046c, 0x00000000,
1659 0x97430104, 0x3c048000, 0x3046ffff, 0x3067ffff, 0x8f420178, 0x00441024, 2419 0xaf421000, 0xaf800020, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1660 0x1440fffd, 0x2402000a, 0x30c30007, 0xa7420140, 0x24020008, 0x00431023, 2420 0x8f820020, 0x8f840018, 0x10400006, 0x92030004, 0x3c058000, 0x8f421000,
1661 0x30420007, 0x24c3fffe, 0xa7420142, 0xa7430144, 0xa7400146, 0xa7470148, 2421 0x00451024, 0x1040fffd, 0x00000000, 0x2463000a, 0x30620007, 0x10400002,
1662 0x8f420108, 0x3c036000, 0x8f850034, 0x30420020, 0x0002102b, 0x00021023, 2422 0x24620007, 0x304303f8, 0x00831021, 0x30421fff, 0xaf84000c, 0xaf820018,
1663 0x30420009, 0x34420001, 0xa742014a, 0x8c644448, 0x3c020800, 0x30a50006, 2423 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, 0x30620007,
1664 0xac440830, 0x24020002, 0x10a2000d, 0x2ca20003, 0x10400005, 0x24020004, 2424 0x10400002, 0x24620007, 0x3043fff8, 0x8f820030, 0x8f840000, 0x00431821,
1665 0x10a00011, 0x3c020041, 0x0a0004a8, 0x00000000, 0x10a20007, 0x24020006, 2425 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023, 0xaf820030,
1666 0x14a2000d, 0x3c020151, 0x0a0004a2, 0x24030001, 0x0a0004a1, 0x3c020141, 2426 0x8f840030, 0x34028000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x00821021,
1667 0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a0004a8, 0x00000000, 2427 0x03421821, 0x3c021000, 0xaf830010, 0xaf440080, 0xaf420178, 0x03e00008,
1668 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2428 0x27bd0020, 0x8f620000, 0x97430104, 0x3c048000, 0x3045ffff, 0x3066ffff,
1669 0x8f820030, 0x24c30008, 0x10400006, 0x30e6ffff, 0x3c048000, 0x8f421000, 2429 0x8f420178, 0x00441024, 0x1440fffd, 0x2402000a, 0x30a30007, 0xa7420140,
1670 0x00441024, 0x1040fffd, 0x00000000, 0x3c026000, 0x8c444448, 0x3065ffff, 2430 0x24020008, 0x00431023, 0x30420007, 0x24a3fffe, 0xa7420142, 0xa7430144,
1671 0x3c020800, 0x30a30007, 0x10600003, 0xac440834, 0x24a20007, 0x3045fff8, 2431 0xa7400146, 0xa7460148, 0x8f420108, 0x8f830024, 0x30420020, 0x0002102b,
1672 0x8f840028, 0x00851021, 0x30421fff, 0x24434000, 0x0343d821, 0x30c30007, 2432 0x00021023, 0x30420009, 0x34420001, 0x30630006, 0xa742014a, 0x24020002,
1673 0xaf840018, 0xaf820028, 0xaf420084, 0x10600002, 0x24c20007, 0x3046fff8, 2433 0x1062000d, 0x2c620003, 0x10400005, 0x24020004, 0x10600011, 0x3c020041,
1674 0x8f820044, 0x8f840004, 0x00461821, 0xaf82002c, 0x0064102b, 0xaf830044, 2434 0x0a0004d6, 0x00000000, 0x10620007, 0x24020006, 0x1462000d, 0x3c020151,
1675 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x3c030800, 2435 0x0a0004d0, 0x24030001, 0x0a0004cf, 0x3c020141, 0x3c020051, 0x24030001,
1676 0x8c650844, 0x00821021, 0x03421821, 0xaf83001c, 0xaf440080, 0x10a00006, 2436 0xaf421000, 0xaf830020, 0x0a0004d6, 0x00000000, 0xaf421000, 0xaf800020,
1677 0x2402000e, 0x93830043, 0x14620004, 0x3c021000, 0x2402043f, 0xa7420148, 2437 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x8f820020, 0x24a30008,
1678 0x3c021000, 0x3c036000, 0xaf420178, 0x8c644448, 0x3c020800, 0x03e00008, 2438 0x8f850018, 0x10400006, 0x30c6ffff, 0x3c048000, 0x8f421000, 0x00441024,
1679 0xac440838, 0x8f820034, 0x30424000, 0x10400005, 0x24020800, 0x0000000d, 2439 0x1040fffd, 0x00000000, 0x3063ffff, 0x30620007, 0x10400002, 0x24620007,
1680 0x00000000, 0x24000405, 0x24020800, 0xaf420178, 0x97440104, 0x3c030008, 2440 0x3043fff8, 0x00a31021, 0x30421fff, 0x24434000, 0x0343d821, 0x00c02021,
1681 0xaf430140, 0x8f820034, 0x30420001, 0x10400006, 0x3085ffff, 0x24020002, 2441 0x30830007, 0xaf85000c, 0xaf820018, 0xaf420084, 0x10600002, 0x24820007,
1682 0x24a3fffe, 0xa7420146, 0x0a0004ff, 0xa7430148, 0xa7400146, 0x8f840028, 2442 0x3044fff8, 0x8f820030, 0x8f850000, 0x00441821, 0xaf82001c, 0x0065102b,
1683 0x2402000d, 0xa742014a, 0x24830008, 0x30631fff, 0x24624000, 0x0342d821, 2443 0xaf830030, 0x14400002, 0x00651023, 0xaf820030, 0x8f840030, 0x34028000,
1684 0x30a20007, 0xaf840018, 0xaf830028, 0xaf430084, 0x10400002, 0x24a20007, 2444 0x3c030800, 0x8c650834, 0x00821021, 0x03421821, 0xaf830010, 0xaf440080,
1685 0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c, 0x0064102b, 2445 0x10a00006, 0x2402000e, 0x9383002f, 0x14620004, 0x3c021000, 0x2402043f,
1686 0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 2446 0xa7420148, 0x3c021000, 0x03e00008, 0xaf420178, 0x8f820024, 0x30424000,
1687 0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0x03e00008, 2447 0x10400005, 0x24020800, 0x0000000d, 0x00000000, 0x2400040e, 0x24020800,
1688 0xaf420178, 0x27bdffe8, 0x3c046008, 0xafbf0014, 0xafb00010, 0x8c825000, 2448 0xaf420178, 0x97440104, 0x3c030008, 0xaf430140, 0x8f820024, 0x30420001,
1689 0x3c1a8000, 0x2403ff7f, 0x375b4000, 0x00431024, 0x3442380c, 0xac825000, 2449 0x10400006, 0x3085ffff, 0x24020002, 0x24a3fffe, 0xa7420146, 0x0a000526,
1690 0x8f430008, 0x3c100800, 0x37428000, 0x34630001, 0xaf430008, 0xaf82001c, 2450 0xa7430148, 0xa7400146, 0x8f840018, 0x2402000d, 0xa742014a, 0x24830008,
1691 0x3c02601c, 0xaf800028, 0xaf400080, 0xaf400084, 0x8c450008, 0x3c036000, 2451 0x30631fff, 0x24624000, 0x0342d821, 0x30a20007, 0xaf84000c, 0xaf830018,
1692 0x8c620808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0, 0x38420010, 2452 0xaf430084, 0x10400002, 0x24a20007, 0x3045fff8, 0x8f820030, 0x8f840000,
1693 0x2c420001, 0xaf850004, 0xaf820008, 0x0e00062f, 0x00000000, 0x8f420000, 2453 0x00451821, 0xaf82001c, 0x0064102b, 0xaf830030, 0x14400002, 0x00641023,
1694 0x30420001, 0x1040fffb, 0x00000000, 0x8f440108, 0x30822000, 0xaf840034, 2454 0xaf820030, 0x8f840030, 0x34028000, 0x00821021, 0x03421821, 0x3c021000,
1695 0x10400004, 0x8e02083c, 0x24420001, 0x0a00059d, 0xae02083c, 0x30820200, 2455 0xaf830010, 0xaf440080, 0x03e00008, 0xaf420178, 0x27bdffe8, 0x3c046008,
1696 0x10400027, 0x00000000, 0x97420104, 0x1040001c, 0x30824000, 0x14400005, 2456 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, 0x375b4000,
1697 0x00000000, 0x0e00022d, 0x00000000, 0x0a000592, 0x00000000, 0x8f620008, 2457 0x00431024, 0x3442380c, 0xac825000, 0x8f430008, 0x3c100800, 0x37428000,
1698 0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007, 0x28620031, 2458 0x34630001, 0xaf430008, 0xaf820010, 0x3c02601c, 0xaf800018, 0xaf400080,
1699 0x14400031, 0x24020040, 0x10620007, 0x00000000, 0x0a000592, 0x00000000, 2459 0xaf400084, 0x8c450008, 0x3c036000, 0x8c620808, 0x3c040800, 0x3c030080,
1700 0x0e0002dd, 0x00000000, 0x0a000592, 0x00000000, 0x0e0003b8, 0x00000000, 2460 0xac830820, 0x3042fff0, 0x38420010, 0x2c420001, 0xaf850000, 0xaf820004,
1701 0x0a000592, 0x00000000, 0x30820040, 0x1440002d, 0x00000000, 0x0000000d, 2461 0x0e000658, 0x00000000, 0x8f420000, 0x30420001, 0x1040fffb, 0x00000000,
1702 0x00000000, 0x240004a6, 0x0a00059d, 0x00000000, 0x8f430100, 0x24020d00, 2462 0x8f430108, 0x8f440100, 0x30622000, 0xaf830024, 0xaf840014, 0x10400004,
1703 0x1462000f, 0x30820006, 0x97420104, 0x10400005, 0x30820040, 0x0e0004e9, 2463 0x8e02082c, 0x24420001, 0x0a0005c6, 0xae02082c, 0x30620200, 0x14400003,
1704 0x00000000, 0x0a000592, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d, 2464 0x24020f00, 0x14820027, 0x24020d00, 0x97420104, 0x1040001c, 0x30624000,
1705 0x00000000, 0x240004b8, 0x0a00059d, 0x00000000, 0x1040000e, 0x30821000, 2465 0x14400005, 0x00000000, 0x0e00022f, 0x00000000, 0x0a0005bb, 0x00000000,
1706 0x10400005, 0x00000000, 0x0e00065d, 0x00000000, 0x0a000592, 0x00000000, 2466 0x8f620008, 0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007,
1707 0x0e00046b, 0x00000000, 0x8f820040, 0x24420001, 0xaf820040, 0x0a00059d, 2467 0x28620031, 0x1440002f, 0x24020040, 0x10620007, 0x00000000, 0x0a0005bb,
1708 0x00000000, 0x30820040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000, 2468 0x00000000, 0x0e0002e8, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0003db,
1709 0x240004cf, 0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a00053f, 2469 0x00000000, 0x0a0005bb, 0x00000000, 0x30620040, 0x1440002b, 0x00000000,
1710 0x00000000, 0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000, 2470 0x0000000d, 0x00000000, 0x240004b2, 0x0a0005c6, 0x00000000, 0x1482000f,
1711 0x00621824, 0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c, 2471 0x30620006, 0x97420104, 0x10400005, 0x30620040, 0x0e000510, 0x00000000,
1712 0x34420001, 0xaf420008, 0x37428000, 0xaf800028, 0xaf82001c, 0xaf400080, 2472 0x0a0005bb, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d, 0x00000000,
1713 0xaf400084, 0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820, 2473 0x240004c4, 0x0a0005c6, 0x00000000, 0x1040000e, 0x30621000, 0x10400005,
1714 0x3042fff0, 0x38420010, 0x2c420001, 0xaf860004, 0xaf820008, 0x03e00008, 2474 0x00000000, 0x0e000688, 0x00000000, 0x0a0005bb, 0x00000000, 0x0e0004a1,
1715 0x00000000, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8, 2475 0x00000000, 0x8f82002c, 0x24420001, 0xaf82002c, 0x0a0005c6, 0x00000000,
1716 0x8f820028, 0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf820018, 2476 0x30620040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000, 0x240004db,
1717 0xaf830028, 0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002, 2477 0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a000566, 0x00000000,
1718 0x24820007, 0x3044fff8, 0x8f820044, 0x8f830004, 0x00442021, 0xaf82002c, 2478 0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000, 0x00621824,
1719 0x0083102b, 0xaf840044, 0x14400002, 0x00831023, 0xaf820044, 0x8f820044, 2479 0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c, 0x34420001,
1720 0x34038000, 0x00431821, 0x03432021, 0xaf84001c, 0x03e00008, 0xaf420080, 2480 0xaf420008, 0x37428000, 0xaf800018, 0xaf820010, 0xaf400080, 0xaf400084,
1721 0x8f830034, 0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005, 2481 0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0,
1722 0x24020004, 0x10600012, 0x3c020001, 0x0a000601, 0x00000000, 0x10620007, 2482 0x38420010, 0x2c420001, 0xaf860000, 0xaf820004, 0x03e00008, 0x00000000,
1723 0x24020006, 0x1462000f, 0x3c020111, 0x0a0005f9, 0x00821025, 0x0a0005f8, 2483 0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8, 0x8f820018,
1724 0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030, 2484 0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf82000c, 0xaf830018,
1725 0x0a000601, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000, 2485 0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007,
1726 0x00000000, 0x00000000, 0x03e00008, 0x00000000, 0x8f820030, 0x10400005, 2486 0x3044fff8, 0x8f820030, 0x8f830000, 0x00442021, 0xaf82001c, 0x0083102b,
1727 0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008, 2487 0xaf840030, 0x14400002, 0x00831023, 0xaf820030, 0x8f820030, 0x34038000,
1728 0x00000000, 0x8f820034, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010, 2488 0x00431821, 0x03432021, 0xaf840010, 0x03e00008, 0xaf420080, 0x8f830024,
1729 0x0e00022d, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x8f620008, 0x8f630000, 2489 0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005, 0x24020004,
1730 0x24020030, 0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d, 2490 0x10600012, 0x3c020001, 0x0a00062a, 0x00000000, 0x10620007, 0x24020006,
1731 0x8fbf0010, 0x24020040, 0x10620007, 0x00000000, 0x0a00062d, 0x00000000, 2491 0x1462000f, 0x3c020111, 0x0a000622, 0x00821025, 0x0a000621, 0x3c020101,
1732 0x0e0002dd, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x0e0003b8, 0x00000000, 2492 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830020, 0x0a00062a,
1733 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f84003c, 0x1080000f, 0x3c026000, 2493 0x00000000, 0x00821025, 0xaf421000, 0xaf800020, 0x00000000, 0x00000000,
1734 0x8c430c3c, 0x30630fff, 0xaf830014, 0x14600011, 0x3082000f, 0x10400005, 2494 0x00000000, 0x03e00008, 0x00000000, 0x8f820020, 0x10400005, 0x3c038000,
1735 0x308200f0, 0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d, 2495 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008, 0x00000000,
1736 0x00000000, 0x2400050e, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000, 2496 0x8f820024, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010, 0x0e00022f,
1737 0x24000513, 0x03e00008, 0x00000000, 0xaf83003c, 0x03e00008, 0x00000000, 2497 0x00000000, 0x0a000656, 0x8fbf0010, 0x8f620008, 0x8f630000, 0x24020030,
1738 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 2498 0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d, 0x8fbf0010,
1739 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000659, 0x00a01021, 2499 0x24020040, 0x10620007, 0x00000000, 0x0a000656, 0x00000000, 0x0e0002e8,
1740 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008, 2500 0x00000000, 0x0a000656, 0x8fbf0010, 0x0e0003db, 0x00000000, 0x8fbf0010,
1741 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x3c040800, 0x8c82084c, 2501 0x03e00008, 0x27bd0018, 0x8f840028, 0x1080000f, 0x3c026000, 0x8c430c3c,
1742 0x54400007, 0xac80084c, 0x8f820034, 0x24030400, 0x30420c00, 0x1443005b, 2502 0x30630fff, 0xaf830008, 0x14600011, 0x3082000f, 0x10400005, 0x308200f0,
1743 0x00000000, 0xac80084c, 0x0000000d, 0x00000000, 0x2400003c, 0x3c026000, 2503 0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d, 0x00000000,
1744 0x8c444448, 0x3c030800, 0xac640850, 0x24000043, 0x97420104, 0x3045ffff, 2504 0x2400051a, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000, 0x2400051f,
1745 0x000530c2, 0x24a2007f, 0x000239c2, 0x2400004e, 0x3c046020, 0x24030020, 2505 0x03e00008, 0x00000000, 0xaf830028, 0x03e00008, 0x00000000, 0x10c00007,
1746 0xac830000, 0x8c820000, 0x30420020, 0x10400005, 0x3c036020, 0x8c620000, 2506 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb,
1747 0x30420020, 0x1440fffd, 0x00000000, 0x3c026020, 0x8c430010, 0x24040001, 2507 0x24840004, 0x03e00008, 0x00000000, 0x0a000684, 0x00a01021, 0xac860000,
1748 0x0087102b, 0x30ea007f, 0x24abfffe, 0x10400010, 0x00034240, 0x3c056020, 2508 0x00000000, 0x00000000, 0x24840004, 0x00a01021, 0x1440fffa, 0x24a5ffff,
1749 0x24090020, 0xaca90000, 0x8ca20000, 0x30420020, 0x10400006, 0x24840001, 2509 0x03e00008, 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x00000000};
1750 0x3c036020, 0x8c620000, 0x30420020, 0x1440fffd, 0x00000000, 0x0087102b,
1751 0x1440fff4, 0x00000000, 0x8f85001c, 0x3c026020, 0x8c430010, 0x3c046020,
1752 0x34848000, 0x006a1825, 0x01034025, 0x2400006b, 0x10c0000b, 0x00000000,
1753 0x8ca30000, 0x24a50004, 0x8ca20000, 0x24a50004, 0x24c6ffff, 0xac820000,
1754 0x24840004, 0xac830000, 0x14c0fff7, 0x24840004, 0x24000077, 0x3c020007,
1755 0x34427700, 0x3c036000, 0xac6223c8, 0xac6b23cc, 0xac6823e4, 0x24000086,
1756 0x3c046000, 0x3c038000, 0x8c8223f8, 0x00431024, 0x1440fffd, 0x3c021000,
1757 0x3c056000, 0x24030019, 0xaca223f8, 0xa743014a, 0x8ca44448, 0x3c020800,
1758 0xac440854, 0x03e00008, 0x00000000, 0x00000000 };
1759 2510
1760static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x00000000 }; 2511static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x0 };
1761static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x00000000 }; 2512static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x0 };
1762static u32 bnx2_TPAT_b06FwBss[(0x80/4) + 1] = { 0x00000000 }; 2513static u32 bnx2_TPAT_b06FwBss[(0x250/4) + 1] = { 0x0 };
1763static u32 bnx2_TPAT_b06FwSbss[(0x48/4) + 1] = { 0x00000000 }; 2514static u32 bnx2_TPAT_b06FwSbss[(0x34/4) + 1] = { 0x0 };
1764 2515
1765static int bnx2_TXP_b06FwReleaseMajor = 0x0; 2516static int bnx2_TXP_b06FwReleaseMajor = 0x1;
1766static int bnx2_TXP_b06FwReleaseMinor = 0x0; 2517static int bnx2_TXP_b06FwReleaseMinor = 0x0;
1767static int bnx2_TXP_b06FwReleaseFix = 0x0; 2518static int bnx2_TXP_b06FwReleaseFix = 0x0;
1768static u32 bnx2_TXP_b06FwStartAddr = 0x08002090; 2519static u32 bnx2_TXP_b06FwStartAddr = 0x080034b0;
1769static u32 bnx2_TXP_b06FwTextAddr = 0x08000000; 2520static u32 bnx2_TXP_b06FwTextAddr = 0x08000000;
1770static int bnx2_TXP_b06FwTextLen = 0x3ffc; 2521static int bnx2_TXP_b06FwTextLen = 0x5748;
1771static u32 bnx2_TXP_b06FwDataAddr = 0x08004020; 2522static u32 bnx2_TXP_b06FwDataAddr = 0x08005760;
1772static int bnx2_TXP_b06FwDataLen = 0x0; 2523static int bnx2_TXP_b06FwDataLen = 0x0;
1773static u32 bnx2_TXP_b06FwRodataAddr = 0x00000000; 2524static u32 bnx2_TXP_b06FwRodataAddr = 0x00000000;
1774static int bnx2_TXP_b06FwRodataLen = 0x0; 2525static int bnx2_TXP_b06FwRodataLen = 0x0;
1775static u32 bnx2_TXP_b06FwBssAddr = 0x08004060; 2526static u32 bnx2_TXP_b06FwBssAddr = 0x080057a0;
1776static int bnx2_TXP_b06FwBssLen = 0x194; 2527static int bnx2_TXP_b06FwBssLen = 0x1c4;
1777static u32 bnx2_TXP_b06FwSbssAddr = 0x08004020; 2528static u32 bnx2_TXP_b06FwSbssAddr = 0x08005760;
1778static int bnx2_TXP_b06FwSbssLen = 0x34; 2529static int bnx2_TXP_b06FwSbssLen = 0x38;
1779static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = { 2530static u32 bnx2_TXP_b06FwText[(0x5748/4) + 1] = {
1780 0x0a000824, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x302e362e, 2531 0x0a000d2c, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x322e352e,
1781 0x39000000, 0x00060900, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000, 2532 0x38000000, 0x02050800, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000,
2533 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2534 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2535 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2536 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2537 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2538 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2539 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2540 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2541 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2542 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2543 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2544 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2545 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2546 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2547 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2548 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2549 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2550 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2551 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2552 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2553 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2554 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2555 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2556 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2557 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2558 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2559 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2560 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2561 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2562 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2563 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2564 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2565 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2566 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2567 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2568 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2569 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2570 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2571 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2572 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2573 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2574 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2575 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2576 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2577 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2578 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2579 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2580 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2581 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2582 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2583 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2584 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2585 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2586 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2587 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2588 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2589 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2590 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2591 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2592 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2593 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2594 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2595 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2596 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2597 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2598 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2599 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2600 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2601 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2602 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2603 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2604 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2605 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2606 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2607 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2608 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2609 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2610 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2611 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2612 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2613 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2614 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2615 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2616 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2617 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2618 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2619 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2620 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2621 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2622 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2623 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2624 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2625 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2626 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2627 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2628 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2629 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2630 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2631 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2632 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2633 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2634 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2635 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2636 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2637 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2638 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2639 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2640 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1782 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2641 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1783 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2642 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1784 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2643 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -2124,55 +2983,164 @@ static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = {
2124 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2983 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2125 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2984 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2126 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2985 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2127 0x00000000, 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 2986 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2128 0x0000000d, 0x3c020800, 0x24424020, 0x3c030800, 0x246341f4, 0xac400000, 2987 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2129 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 2988 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2130 0x3c100800, 0x26102090, 0x3c1c0800, 0x279c4020, 0x0e000a0e, 0x00000000, 2989 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2131 0x0000000d, 0x8f840014, 0x27bdffe8, 0xafb00010, 0x8f460104, 0x8f830008, 2990 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2132 0x8c8500ac, 0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12, 2991 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2133 0x8c8200ac, 0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0xa7420e16, 2992 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2134 0x8f430e18, 0x00005021, 0x00c53023, 0x10c001a3, 0xaf430e1c, 0x240f0800, 2993 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2135 0x3c0e1000, 0x2419fff8, 0x24100010, 0x3c188100, 0x93620008, 0x10400009, 2994 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2136 0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000, 0x97620010, 2995 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2137 0x3042ffff, 0x0a000862, 0xaf420e00, 0xaf460e00, 0x8f420000, 0x30420008, 2996 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2138 0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff, 0x30820001, 2997 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2139 0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a0009e6, 0x00000000, 2998 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2140 0x0000000d, 0x3083a040, 0x24020040, 0x14620049, 0x3082a000, 0x8f87000c, 2999 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2141 0x30880036, 0x30890008, 0xaf4f0178, 0x00e01821, 0x9742008a, 0x00431023, 3000 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2142 0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa, 0x00000000, 0x8f830018, 3001 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2143 0x00a05021, 0x00c53023, 0x24e24000, 0x03422821, 0x306b00ff, 0x24630001, 3002 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2144 0xaf830018, 0x93840012, 0x000b1400, 0x3c030100, 0x00431025, 0xaca20000, 3003 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2145 0x8f820018, 0x30840007, 0x00042240, 0x34870001, 0x00e83825, 0x1120000f, 3004 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2146 0xaca20004, 0x97430e0a, 0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825, 3005 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2147 0xaf430160, 0x25430006, 0x24840008, 0x30841fff, 0xa742015a, 0xa7430158, 3006 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2148 0xaf84000c, 0x0a0008a9, 0x00000000, 0x8f83000c, 0x25420002, 0xa7420158, 3007 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2149 0x24630008, 0x30631fff, 0xaf83000c, 0x54c0000c, 0x8f420e14, 0x97420e10, 3008 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2150 0x97430e12, 0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014, 3009 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2151 0x8f420e18, 0x34e70040, 0xaca200ac, 0x8f420e14, 0x8f430e1c, 0xaf420144, 3010 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2152 0xaf430148, 0xa34b0152, 0xaf470154, 0x0a0009f1, 0xaf4e0178, 0x10400128, 3011 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2153 0x00000000, 0x97620010, 0x00a2102b, 0x10400003, 0x30820040, 0x10400122, 3012 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2154 0x00000000, 0xafa60008, 0xa7840010, 0xaf850004, 0x93620008, 0x1440005e, 3013 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2155 0x27ac0008, 0xaf60000c, 0x97820010, 0x30424000, 0x10400002, 0x2403000e, 3014 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2156 0x24030016, 0xa363000a, 0x24034007, 0xaf630014, 0x93820012, 0x8f630014, 3015 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2157 0x30420007, 0x00021240, 0x00621825, 0xaf630014, 0x97820010, 0x8f630014, 3016 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2158 0x30420010, 0x00621825, 0xaf630014, 0x97820010, 0x30420008, 0x5040000e, 3017 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2159 0x00002821, 0x8f620014, 0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e, 3018 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2160 0x00781825, 0xaf630004, 0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004, 3019 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2161 0x0a0008f2, 0xa363000a, 0xaf600004, 0xa3600002, 0x97820010, 0x9363000a, 3020 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2162 0x30421f00, 0x00021182, 0x24420028, 0x00621821, 0xa3630009, 0x97420e0c, 3021 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2163 0xa7620010, 0x93630009, 0x24020008, 0x24630002, 0x30630007, 0x00431023, 3022 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2164 0x30420007, 0xa362000b, 0x93640009, 0x97620010, 0x8f890004, 0x97830010, 3023 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2165 0x00441021, 0x00a21021, 0x30630040, 0x10600006, 0x3045ffff, 0x15250005, 3024 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2166 0x0125102b, 0x3c068000, 0x0a000925, 0x00005821, 0x0125102b, 0x144000c8, 3025 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2167 0x00005021, 0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c, 3026 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2168 0xaf420e18, 0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000, 3027 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2169 0x97420e08, 0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001, 3028 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2170 0xaf830004, 0x97620010, 0x0a000936, 0x304dffff, 0x8f890004, 0x97820010, 3029 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2171 0x30420040, 0x10400004, 0x01206821, 0x3c068000, 0x0a000936, 0x00005821, 3030 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2172 0x97630010, 0x8f820004, 0x144300a7, 0x00005021, 0x00003021, 0x240b0001, 3031 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3032 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3033 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3034 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3035 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3036 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3037 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3038 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3039 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3040 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3041 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3042 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3043 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3044 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3045 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3046 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3047 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3048 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3049 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3050 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3051 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3052 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3053 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3054 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3055 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3056 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3057 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3058 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3059 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3060 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3061 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3062 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3063 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3064 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3065 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3066 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3067 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3068 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3069 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3070 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3071 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3072 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3073 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3074 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3075 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3076 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3077 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3078 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3079 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3080 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3081 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3082 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3083 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3084 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3085 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3086 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3087 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3088 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3089 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3090 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3091 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3092 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
3093 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800,
3094 0x24425760, 0x3c030800, 0x24635964, 0xac400000, 0x0043202b, 0x1480fffd,
3095 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261034b0,
3096 0x3c1c0800, 0x279c5760, 0x0e000f5b, 0x00000000, 0x0000000d, 0x8f840014,
3097 0x27bdffe8, 0xafb10014, 0xafb00010, 0x8f460104, 0x8f830008, 0x8c8500ac,
3098 0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12, 0x8c8200ac,
3099 0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0x00008021, 0xa7420e16,
3100 0x8f430e18, 0x00006021, 0x00c53023, 0xaf430e1c, 0x10c001a2, 0x2d820001,
3101 0x3c0e1000, 0x2419fff8, 0x24110010, 0x240f0f00, 0x3c188100, 0x93620008,
3102 0x10400009, 0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000,
3103 0x97620010, 0x3042ffff, 0x0a000d6d, 0xaf420e00, 0xaf460e00, 0x8f420000,
3104 0x30420008, 0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff,
3105 0x30820001, 0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a000f34,
3106 0x00000000, 0x0000000d, 0x3083a040, 0x24020040, 0x1462004f, 0x3082a000,
3107 0x308a0036, 0x8f88000c, 0x30890008, 0x24020800, 0xaf420178, 0x01001821,
3108 0x9742008a, 0x00431023, 0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa,
3109 0x00a06021, 0x8f820018, 0x00cc3023, 0x24070001, 0x8f830008, 0x304b00ff,
3110 0x24420001, 0xaf820018, 0x25024000, 0x106f0005, 0x03422021, 0x93820012,
3111 0x30420007, 0x00021240, 0x34470001, 0x000b1400, 0x3c030100, 0x00431025,
3112 0xac820000, 0x8f830018, 0x00ea3825, 0x1120000f, 0xac830004, 0x97430e0a,
3113 0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825, 0xaf430160, 0x25830006,
3114 0x24840008, 0x30841fff, 0xa742015a, 0xa7430158, 0xaf84000c, 0x0a000db7,
3115 0x00000000, 0x8f83000c, 0x25820002, 0xa7420158, 0x24630008, 0x30631fff,
3116 0xaf83000c, 0x54c0000f, 0x8f420e14, 0x8f820008, 0x504f0002, 0x24100001,
3117 0x34e70040, 0x97420e10, 0x97430e12, 0x8f850014, 0x00021400, 0x00621825,
3118 0xaca300a8, 0x8f840014, 0x8f420e18, 0xac8200ac, 0x8f420e14, 0x8f430e1c,
3119 0xaf420144, 0xaf430148, 0xa34b0152, 0xaf470154, 0x0a000efb, 0xaf4e0178,
3120 0x10400165, 0x00000000, 0x93620008, 0x50400008, 0xafa60008, 0x97620010,
3121 0x00a2102b, 0x10400003, 0x30820040, 0x1040015c, 0x00000000, 0xafa60008,
3122 0xa7840010, 0xaf850004, 0x93620008, 0x1440005f, 0x27ac0008, 0xaf60000c,
3123 0x97820010, 0x30424000, 0x10400002, 0x2403000e, 0x24030016, 0xa363000a,
3124 0x24034007, 0xaf630014, 0x93820012, 0x8f630014, 0x30420007, 0x00021240,
3125 0x00621825, 0xaf630014, 0x97820010, 0x8f630014, 0x30420010, 0x00621825,
3126 0xaf630014, 0x97820010, 0x30420008, 0x5040000e, 0x00002821, 0x8f620014,
3127 0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e, 0x00781825, 0xaf630004,
3128 0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004, 0x0a000e06, 0xa363000a,
3129 0xaf600004, 0xa3600002, 0x97820010, 0x9363000a, 0x30421f00, 0x00021182,
3130 0x24420028, 0x00621821, 0xa3630009, 0x97420e0c, 0xa7620010, 0x93630009,
3131 0x24020008, 0x24630002, 0x30630007, 0x00431023, 0x30420007, 0xa362000b,
3132 0x93640009, 0x97620010, 0x8f890004, 0x97830010, 0x00441021, 0x00a21021,
3133 0x30630040, 0x10600007, 0x3045ffff, 0x00a9102b, 0x14400005, 0x0125102b,
3134 0x3c068000, 0x0a000e3a, 0x00005821, 0x0125102b, 0x544000c7, 0x00006021,
3135 0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c, 0xaf420e18,
3136 0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000, 0x97420e08,
3137 0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001, 0xaf830004,
3138 0x97620010, 0x0a000e4c, 0x304dffff, 0x8f890004, 0x97820010, 0x30420040,
3139 0x10400004, 0x01206821, 0x3c068000, 0x0a000e4c, 0x00005821, 0x97630010,
3140 0x8f820004, 0x10430003, 0x00003021, 0x0a000eee, 0x00006021, 0x240b0001,
2173 0x8d820000, 0x00491023, 0x1440000d, 0xad820000, 0x8f620014, 0x34420040, 3141 0x8d820000, 0x00491023, 0x1440000d, 0xad820000, 0x8f620014, 0x34420040,
2174 0xaf620014, 0x97430e10, 0x97420e12, 0x8f840014, 0x00031c00, 0x00431025, 3142 0xaf620014, 0x97430e10, 0x97420e12, 0x8f840014, 0x00031c00, 0x00431025,
2175 0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003f, 3143 0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003e,
2176 0x00000000, 0x25260002, 0x8f84000c, 0x9743008a, 0x3063ffff, 0xafa30000, 3144 0x00000000, 0x25260002, 0x8f84000c, 0x9743008a, 0x3063ffff, 0xafa30000,
2177 0x8fa20000, 0x00441023, 0x2442ffff, 0x30421fff, 0x2c420010, 0x1440fff7, 3145 0x8fa20000, 0x00441023, 0x2442ffff, 0x30421fff, 0x2c420010, 0x1440fff7,
2178 0x00000000, 0x8f82000c, 0x8f830018, 0x00021082, 0x00021080, 0x24424000, 3146 0x00000000, 0x8f82000c, 0x8f830018, 0x00021082, 0x00021080, 0x24424000,
@@ -2180,289 +3148,320 @@ static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = {
2180 0x3c033200, 0x00431025, 0xaca20000, 0x93630009, 0x9362000a, 0x00031c00, 3148 0x3c033200, 0x00431025, 0xaca20000, 0x93630009, 0x9362000a, 0x00031c00,
2181 0x00431025, 0xaca20004, 0x8f830018, 0xaca30008, 0x97820010, 0x30420008, 3149 0x00431025, 0xaca20004, 0x8f830018, 0xaca30008, 0x97820010, 0x30420008,
2182 0x10400002, 0x00c04021, 0x25280006, 0x97430e14, 0x93640002, 0x8f450e1c, 3150 0x10400002, 0x00c04021, 0x25280006, 0x97430e14, 0x93640002, 0x8f450e1c,
2183 0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144, 0x97420e16, 3151 0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0xa7420146,
2184 0xa7420146, 0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a, 3152 0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a, 0xaf460160,
2185 0xaf460160, 0xa7480158, 0xaf470154, 0xaf4e0178, 0x00501021, 0x30421fff, 3153 0xa7480158, 0xaf470154, 0xaf4e0178, 0x00511021, 0x30421fff, 0xaf82000c,
2186 0xaf82000c, 0x0a0009c5, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c, 3154 0x0a000ed9, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c, 0x2463000a,
2187 0x2463000a, 0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff, 3155 0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff, 0xafa30000,
2188 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b, 3156 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b, 0x1440fff7,
2189 0x1440fff7, 0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080, 3157 0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080, 0x24424000,
2190 0x24424000, 0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009, 3158 0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009, 0x310200ff,
2191 0x310200ff, 0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025, 3159 0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025, 0xaca40000,
2192 0xaca40000, 0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002, 3160 0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002, 0x8f450e1c,
2193 0x8f450e1c, 0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144, 3161 0x8f660004, 0x8f670014, 0x3063ffff, 0xa7430144, 0x97420e16, 0x308400ff,
2194 0x97420e16, 0x308400ff, 0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c, 3162 0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c, 0x25420007, 0x00591024,
2195 0x25420007, 0x00591024, 0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154, 3163 0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154, 0xaf4e0178, 0x00621821,
2196 0xaf4e0178, 0x00621821, 0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005, 3164 0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005, 0x00000000, 0x8f620014,
2197 0x00000000, 0x8f620014, 0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c, 3165 0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c, 0x004d1021, 0xaf62000c,
2198 0x004d1021, 0xaf62000c, 0x93630008, 0x14600008, 0x00000000, 0x11600006, 3166 0x93630008, 0x14600008, 0x00000000, 0x11600006, 0x00000000, 0x8f630014,
2199 0x00000000, 0x8f630014, 0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014, 3167 0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014, 0xa36b0008, 0x01206021,
2200 0xa36b0008, 0x01205021, 0x15400016, 0x8fa60008, 0x97420e14, 0x97430e16, 3168 0x1580000c, 0x8fa60008, 0x97420e14, 0x97430e16, 0x8f850014, 0x00021400,
2201 0x8f850014, 0x00021400, 0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c, 3169 0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c, 0xac8200ac, 0x0a000efd,
2202 0x0a0009f3, 0xac8200ac, 0x97420e14, 0x97430e16, 0x8f840014, 0x00021400, 3170 0x2d820001, 0x14c0fe65, 0x2d820001, 0x00501025, 0x10400058, 0x24020f00,
2203 0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c, 0x00005021, 0x0a0009f3, 3171 0x8f830008, 0x14620023, 0x3c048000, 0x11800009, 0x3c038000, 0x97420e08,
2204 0xaca200ac, 0x14c0fe64, 0x00000000, 0x55400018, 0x8fb00010, 0x3c038000, 3172 0x30420040, 0x14400005, 0x00000000, 0x0000000d, 0x00000000, 0x2400032c,
2205 0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97430e14, 0x8f440e1c, 3173 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97420e10,
2206 0x24020800, 0xaf420178, 0x3063ffff, 0xa7430144, 0x97420e16, 0x3c031000, 3174 0x3c030500, 0x00431025, 0xaf42014c, 0x97430e14, 0xa7430144, 0x97420e16,
2207 0xa7420146, 0x24020240, 0xaf440148, 0xa3400152, 0xa740015a, 0xaf400160, 3175 0xa7420146, 0x8f430e1c, 0x24022000, 0xaf430148, 0x3c031000, 0xa3400152,
2208 0xa7400158, 0xaf420154, 0xaf430178, 0x8fb00010, 0x03e00008, 0x27bd0018, 3176 0xa740015a, 0xaf400160, 0xa7400158, 0xaf420154, 0xaf430178, 0x8f830008,
2209 0x27bdffd8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821, 3177 0x3c048000, 0x8f420178, 0x00441024, 0x1440fffd, 0x24020f00, 0x10620016,
2210 0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014, 3178 0x00000000, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c,
2211 0xaf440e00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 3179 0x3c031000, 0xaf420148, 0x0a000f51, 0x24020240, 0x97420e14, 0x97430e16,
2212 0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00, 0x8c835000, 0x24130d00, 3180 0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c,
2213 0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c, 0x24020009, 3181 0x00006021, 0xaca200ac, 0x0a000efd, 0x2d820001, 0xaf40014c, 0x11800007,
2214 0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000, 3182 0x00000000, 0x97420e10, 0xa7420144, 0x97430e12, 0xa7430146, 0x0a000f4e,
2215 0x0e000a96, 0x00000000, 0x3c020800, 0x24504080, 0x8f420000, 0x30420001, 3183 0x8f420e18, 0x97420e14, 0xa7420144, 0x97430e16, 0xa7430146, 0x8f420e1c,
2216 0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020, 0x93430108, 3184 0xaf420148, 0x24020040, 0x3c031000, 0xa3400152, 0xa740015a, 0xaf400160,
2217 0xa3830012, 0x93820012, 0x30420001, 0x10400008, 0x00000000, 0x93820012, 3185 0xa7400158, 0xaf420154, 0xaf430178, 0x8fb10014, 0x8fb00010, 0x03e00008,
2218 0x30420006, 0x00021100, 0x0e00083b, 0x0050d821, 0x0a000a52, 0x00000000, 3186 0x27bd0018, 0x27bdffd0, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008,
2219 0x14930005, 0x00000000, 0x0e00083b, 0x265b4100, 0x0a000a52, 0x00000000, 3187 0x03421821, 0xafbf002c, 0xafb60028, 0xafb50024, 0xafb40020, 0xafb3001c,
2220 0x0e000ba3, 0x00000000, 0xaf510138, 0x0a000a36, 0x00000000, 0x27bdfff8, 3188 0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014, 0xaf440e00, 0x00000000,
2221 0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c, 0x9743008a, 0x3063ffff, 3189 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd,
2222 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b, 3190 0x3c046004, 0xaf420e00, 0x8c835000, 0x24160800, 0x24150d00, 0x3c140800,
2223 0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082, 0x00021080, 0x24424000, 3191 0x24130f00, 0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c,
2224 0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff, 0x8f82000c, 0x24840007, 3192 0x24020009, 0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e001559,
2225 0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c, 0x03e00008, 0x00000000, 3193 0x00000000, 0x0e000ff0, 0x00000000, 0x3c020800, 0x245057c0, 0x8f420000,
2226 0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821, 3194 0x30420001, 0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020,
2227 0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000, 0x00000000, 0x00000000, 3195 0xaf560178, 0x93430108, 0xa3830012, 0x93820012, 0x30420001, 0x10400008,
2228 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00, 3196 0x00000000, 0x93820012, 0x30420006, 0x00021100, 0x0e000d43, 0x0050d821,
2229 0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c, 0x24030009, 0xac825000, 3197 0x0a000fac, 0x00000000, 0x14950005, 0x00000000, 0x0e000d43, 0x269b5840,
2230 0xaf430008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000, 0x0e000a96, 3198 0x0a000fac, 0x00000000, 0x14930005, 0x00000000, 0x0e000d43, 0x265b5860,
2231 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c02000a, 3199 0x0a000fac, 0x00000000, 0x0e0010ea, 0x00000000, 0xaf510138, 0x0a000f89,
2232 0x03421821, 0x3c040800, 0x24844120, 0x24050018, 0xafbf0010, 0xaf830024, 3200 0x00000000, 0x27bdfff8, 0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c,
2233 0x0e000fad, 0x00003021, 0x3c050800, 0x3c020800, 0x24423d60, 0xaca24180, 3201 0x9743008a, 0x3063ffff, 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff,
2234 0x24a54180, 0x3c020800, 0x24423e18, 0x3c030800, 0x24633e2c, 0x3c040800, 3202 0x30421fff, 0x0044102b, 0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082,
2235 0xaca20004, 0x3c020800, 0x24423d68, 0xaca30008, 0xac824190, 0x24844190, 3203 0x00021080, 0x24424000, 0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff,
2236 0x3c020800, 0x24423da4, 0x3c070800, 0x24e73de4, 0x3c060800, 0x24c63e40, 3204 0x8f82000c, 0x24840007, 0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c,
2237 0x3c050800, 0x24a52b28, 0x3c030800, 0xac820004, 0x3c020800, 0x24423e48, 3205 0x03e00008, 0x00000000, 0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd,
2238 0xac870008, 0xac86000c, 0xac850010, 0xac6241b0, 0x246341b0, 0x8fbf0010, 3206 0x3c020008, 0x03421821, 0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000,
2239 0x3c020800, 0x24423e60, 0xac620004, 0xac670008, 0xac66000c, 0xac650010, 3207 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd,
2240 0x03e00008, 0x27bd0018, 0x27bdffc8, 0x3c020800, 0x24424120, 0xafbf0030, 3208 0x3c046004, 0xaf420e00, 0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c,
2241 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x90470021, 0x8c510008, 3209 0x24030009, 0xac825000, 0xaf430008, 0xaf800018, 0xaf80000c, 0x0e001559,
2242 0x8c45001c, 0x8f900020, 0x3c060800, 0x3c038000, 0x8f420178, 0x00431024, 3210 0x00000000, 0x0e000ff0, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018,
2243 0x1440fffd, 0x8cc2414c, 0x24c3414c, 0x2473ffd4, 0xaf420144, 0x8e620030, 3211 0x27bdffe8, 0x3c02000a, 0x03421821, 0x3c040800, 0x24845880, 0x24050019,
2244 0x30b22000, 0xaf420148, 0x3c021000, 0xaf50014c, 0xa3470152, 0xa7510158, 3212 0xafbf0010, 0xaf830024, 0x0e001565, 0x00003021, 0x3c050800, 0x3c020800,
2245 0xaf450154, 0xaf420178, 0x12400004, 0x3c030800, 0x8c620030, 0x24420001, 3213 0x24425330, 0xaca258e8, 0x24a558e8, 0x3c020800, 0x244254f8, 0x3c030800,
2246 0xac620030, 0x93420109, 0x9344010a, 0x00111c00, 0xafa30018, 0x00071a00, 3214 0x2463550c, 0x3c040800, 0xaca20004, 0x3c020800, 0x24425338, 0xaca30008,
2247 0xafa50014, 0x8cc5414c, 0x00021600, 0x00042400, 0x00441025, 0x00431025, 3215 0xac825900, 0x24845900, 0x3c020800, 0x244253c4, 0x3c070800, 0x24e75404,
2248 0xafa20010, 0x8f440100, 0x8e660030, 0x0e000fe1, 0x02003821, 0x1640000e, 3216 0x3c060800, 0x24c65520, 0x3c050800, 0x24a55438, 0x3c030800, 0xac820004,
2249 0x8fbf0030, 0x8f820000, 0x8e630030, 0x8c44017c, 0x02031823, 0x00711823, 3217 0x3c020800, 0x24425528, 0xac870008, 0xac86000c, 0xac850010, 0xac625920,
2250 0x00641823, 0x2c630002, 0x14600006, 0x8fb3002c, 0x0000000d, 0x00000000, 3218 0x24635920, 0x8fbf0010, 0x3c020800, 0x24425540, 0xac620004, 0x3c020800,
2251 0x240000ca, 0x8fbf0030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, 3219 0xac670008, 0xac66000c, 0xac650010, 0xac400048, 0x03e00008, 0x27bd0018,
2252 0x03e00008, 0x27bd0038, 0x974309da, 0x00804021, 0xad030000, 0x8f4209dc, 3220 0x974309da, 0x00804021, 0xad030000, 0x8f4209dc, 0xad020004, 0x8f4309e0,
2253 0xad020004, 0x8f4309e0, 0xad030008, 0x934409d9, 0x24020001, 0x30840003, 3221 0xad030008, 0x934409d9, 0x24020001, 0x30840003, 0x1082001f, 0x30a900ff,
2254 0x1082001f, 0x30a900ff, 0x28820002, 0x10400005, 0x24020002, 0x10800009, 3222 0x28820002, 0x10400005, 0x24020002, 0x10800009, 0x3c0a0800, 0x0a001078,
2255 0x3c0a0800, 0x0a000b64, 0x93420934, 0x1082000b, 0x24020003, 0x10820026, 3223 0x93420934, 0x1082000b, 0x24020003, 0x10820026, 0x3c0a0800, 0x0a001078,
2256 0x3c0a0800, 0x0a000b64, 0x93420934, 0x974209e4, 0x00021400, 0x34420800, 3224 0x93420934, 0x974209e4, 0x00021400, 0x34420800, 0xad02000c, 0x0a001077,
2257 0xad02000c, 0x0a000b63, 0x25080010, 0x974209e4, 0x00021400, 0x34428100, 3225 0x25080010, 0x974209e4, 0x00021400, 0x34428100, 0xad02000c, 0x974309e8,
2258 0xad02000c, 0x974309e8, 0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010, 3226 0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010, 0x0a001077, 0x25080014,
2259 0x0a000b63, 0x25080014, 0x974409e4, 0x3c050800, 0x24a24120, 0x94430018, 3227 0x974409e4, 0x3c050800, 0x24a25880, 0x9443001c, 0x94460014, 0x94470010,
2260 0x94460010, 0x9447000c, 0x00a05021, 0x24020800, 0xad000010, 0xad020014, 3228 0x00a05021, 0x24020800, 0xad000010, 0xad020014, 0x00042400, 0x00661821,
2261 0x00042400, 0x00661821, 0x00671823, 0x2463fff2, 0x00832025, 0xad04000c, 3229 0x00671823, 0x2463fff2, 0x00832025, 0xad04000c, 0x0a001077, 0x25080018,
2262 0x0a000b63, 0x25080018, 0x974209e4, 0x3c050800, 0x00021400, 0x34428100, 3230 0x974209e4, 0x3c050800, 0x00021400, 0x34428100, 0xad02000c, 0x974409e8,
2263 0xad02000c, 0x974409e8, 0x24a24120, 0x94430018, 0x94460010, 0x9447000c, 3231 0x24a25880, 0x9443001c, 0x94460014, 0x94470010, 0x00a05021, 0x24020800,
2264 0x00a05021, 0x24020800, 0xad000014, 0xad020018, 0x00042400, 0x00661821, 3232 0xad000014, 0xad020018, 0x00042400, 0x00661821, 0x00671823, 0x2463ffee,
2265 0x00671823, 0x2463ffee, 0x00832025, 0xad040010, 0x2508001c, 0x93420934, 3233 0x00832025, 0xad040010, 0x2508001c, 0x93420934, 0x93450921, 0x3c074000,
2266 0x93450921, 0x3c074000, 0x25444120, 0x94830014, 0x94860010, 0x00021082, 3234 0x25445880, 0x94830018, 0x94860014, 0x00021082, 0x00021600, 0x00052c00,
2267 0x00021600, 0x00052c00, 0x00a72825, 0x00451025, 0x00661821, 0x00431025, 3235 0x00a72825, 0x00451025, 0x00661821, 0x00431025, 0xad020000, 0x9783002c,
2268 0xad020000, 0x97830028, 0x974209ea, 0x00621821, 0x00031c00, 0xad030004, 3236 0x974209ea, 0x00621821, 0x00031c00, 0xad030004, 0x9782002c, 0x24420001,
2269 0x97820028, 0x24420001, 0x30427fff, 0xa7820028, 0x93430920, 0x3c020006, 3237 0x30427fff, 0xa782002c, 0x93430920, 0x3c020006, 0x00031e00, 0x00621825,
2270 0x00031e00, 0x00621825, 0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930, 3238 0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930, 0xad030010, 0x8f440938,
2271 0xad030010, 0x8f440938, 0x25080014, 0xad040000, 0x8f820020, 0x11200004, 3239 0x25080014, 0xad040000, 0x8f820020, 0x11200004, 0xad020004, 0x8f420940,
2272 0xad020004, 0x8f420940, 0x0a000b8d, 0x2442ffff, 0x8f420940, 0xad020008, 3240 0x0a0010a1, 0x2442ffff, 0x8f420940, 0xad020008, 0x8f440948, 0x8f420940,
2273 0x8f440948, 0x8f420940, 0x93430936, 0x00822823, 0x00652806, 0x3402ffff, 3241 0x93430936, 0x00823023, 0x00663006, 0x3402ffff, 0x0046102b, 0x54400001,
2274 0x0045102b, 0x54400001, 0x3405ffff, 0x93420937, 0x25444120, 0x90830020, 3242 0x3406ffff, 0x93420937, 0x25445880, 0x90830024, 0xad000010, 0x00021700,
2275 0xad000010, 0x00021700, 0x34630010, 0x00031c00, 0x00431025, 0x00451025, 3243 0x34630010, 0x00031c00, 0x00431025, 0x00461025, 0xad02000c, 0x8c830008,
2276 0xad02000c, 0x03e00008, 0x25020014, 0x27bdffb0, 0x3c020008, 0x03421821, 3244 0x14600031, 0x25080014, 0x3c020800, 0x8c430048, 0x1060002d, 0x00000000,
2277 0xafbf004c, 0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038, 3245 0x9342010b, 0xad020000, 0x8f830000, 0x8c6200b0, 0xad020004, 0x8f830000,
2278 0xafb30034, 0xafb20030, 0xafb1002c, 0xafb00028, 0xaf830000, 0x24020040, 3246 0x8c6200b4, 0xad020008, 0x8f830000, 0x8c6200c0, 0xad02000c, 0x8f830000,
2279 0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954, 0x8f45095c, 3247 0x8c6200c4, 0xad020010, 0x8f830000, 0x8c6200c8, 0xad020014, 0x8f830000,
2280 0xaf820030, 0xaf830020, 0xaf84001c, 0xaf85002c, 0x93430900, 0x24020020, 3248 0x8c6200cc, 0xad020018, 0x8f830000, 0x8c6200e0, 0xad02001c, 0x8f830000,
2281 0x10620005, 0x24020030, 0x10620022, 0x3c030800, 0x0a000bf1, 0x8c62002c, 3249 0x8c6200e8, 0xad020020, 0x8f830000, 0x8c6200f0, 0x3c04600e, 0xad020024,
2282 0x24020088, 0xaf420818, 0x3c020800, 0x24424180, 0xafa20020, 0x93430109, 3250 0x8c8200d0, 0xad020028, 0x8c8300d4, 0xad03002c, 0x8f820028, 0x3c046012,
2283 0x3c020800, 0x10600009, 0x24574190, 0x3c026000, 0x24030100, 0xac43081c, 3251 0xad020030, 0x8c8200a8, 0xad020034, 0x8c8300ac, 0x3c026000, 0xad030038,
2284 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x2400031d, 0x9342010a, 3252 0x8c434448, 0xad03003c, 0x03e00008, 0x01001021, 0x27bdffa8, 0x3c020008,
2285 0x30420080, 0x1440001c, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c, 3253 0x03423021, 0xafbf0054, 0xafbe0050, 0xafb7004c, 0xafb60048, 0xafb50044,
2286 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000324, 0x0a000bf4, 3254 0xafb40040, 0xafb3003c, 0xafb20038, 0xafb10034, 0xafb00030, 0xaf860000,
2287 0x00000000, 0x93430109, 0x3063007f, 0x00031140, 0x000318c0, 0x00431021, 3255 0x24020040, 0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954,
2288 0x24430088, 0xaf430818, 0x0000000d, 0x3c020800, 0x244241d0, 0x3c030800, 3256 0x8f45095c, 0xaf820034, 0xaf830020, 0xaf84001c, 0xaf850030, 0x90c20000,
2289 0x247741e0, 0x0a000bf4, 0xafa20020, 0x24420001, 0x0a000f4c, 0xac62002c, 3257 0x24030020, 0x304400ff, 0x10830005, 0x24020030, 0x10820022, 0x3c030800,
2290 0x8f840000, 0x8f850020, 0x24020800, 0xaf420178, 0x8f4209a4, 0x8c83017c, 3258 0x0a001139, 0x8c62002c, 0x24020088, 0xaf420818, 0x3c020800, 0x244258e8,
2291 0x00a21023, 0x00431023, 0x2c420002, 0x14400004, 0x00000000, 0x0000000d, 3259 0xafa20020, 0x93430109, 0x3c020800, 0x10600009, 0x24575900, 0x3c026000,
2292 0x00000000, 0x24000349, 0x8f420104, 0x8f430988, 0x00431023, 0x58400005, 3260 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000,
2293 0x8f4209a0, 0x0000000d, 0x00000000, 0x2400034d, 0x8f4209a0, 0x3c100800, 3261 0x24000376, 0x9342010a, 0x30420080, 0x14400021, 0x24020800, 0x3c026000,
2294 0xae02414c, 0x8f4309a4, 0x2604414c, 0x2491ffd4, 0xae230030, 0x8f420104, 3262 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000,
2295 0xae250024, 0x00431023, 0xac82ffd4, 0x8fa30020, 0x8c620000, 0x0040f809, 3263 0x2400037d, 0x0a001141, 0x24020800, 0x93430109, 0x3063007f, 0x00031140,
3264 0x000318c0, 0x00431021, 0x24430088, 0xaf430818, 0x0000000d, 0x3c020800,
3265 0x24425940, 0x3c030800, 0x24775950, 0x0a001140, 0xafa20020, 0x24420001,
3266 0xac62002c, 0x0000000d, 0x00000000, 0x24000395, 0x0a0014c1, 0x8fbf0054,
3267 0x24020800, 0xaf420178, 0x8f450104, 0x8f420988, 0x00a21023, 0x58400005,
3268 0x8f4309a0, 0x0000000d, 0x00000000, 0x240003b1, 0x8f4309a0, 0x3c100800,
3269 0xae0358b0, 0x8f4209a4, 0x8f830020, 0x260458b0, 0x2491ffd0, 0xae220034,
3270 0x00a21023, 0xae230028, 0xac82ffd0, 0x8fa30020, 0x8c620000, 0x0040f809,
2296 0x0200b021, 0x00409021, 0x32440010, 0x32420002, 0x10400007, 0xafa40024, 3271 0x0200b021, 0x00409021, 0x32440010, 0x32420002, 0x10400007, 0xafa40024,
2297 0x8e22001c, 0x32500040, 0x2403ffbf, 0x00431024, 0x0a000f13, 0xae22001c, 3272 0x8e220020, 0x32530040, 0x2403ffbf, 0x00431024, 0x0a001493, 0xae220020,
2298 0x32420020, 0x10400002, 0x3c020800, 0x245741b0, 0x32420001, 0x14400007, 3273 0x32420020, 0x10400002, 0x3c020800, 0x24575920, 0x32420001, 0x14400007,
2299 0x00000000, 0x8f820008, 0xaf420080, 0x8ec3414c, 0xaf430e10, 0x8e220030, 3274 0x00000000, 0x8f820008, 0xaf420080, 0x8ec358b0, 0xaf430e10, 0x8e220034,
2300 0xaf420e18, 0x9343010b, 0x93420905, 0x30420008, 0x1040003c, 0x307400ff, 3275 0xaf420e18, 0x9343010b, 0x93420905, 0x30420008, 0x1040003c, 0x307400ff,
2301 0x8f820000, 0x8c430074, 0x0460000a, 0x00000000, 0x3c026000, 0x24030100, 3276 0x8f820000, 0x8c430074, 0x0460000a, 0x00000000, 0x3c026000, 0x24030100,
2302 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000384, 3277 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003ed,
2303 0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32500040, 0x24072000, 3278 0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32530040, 0x00003821,
2304 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c, 3279 0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
2305 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100, 0xaf420148, 3280 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100,
2306 0x24020047, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158, 3281 0xaf420148, 0x24020047, 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000,
2307 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001, 3282 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001, 0xad230030,
2308 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600, 3283 0x9342010a, 0x3c030047, 0xafa50014, 0x00021600, 0x00431025, 0x00471025,
2309 0x00031c00, 0x00431025, 0x34424700, 0xafa20010, 0x8f440100, 0x0e000fe1, 3284 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b,
2310 0x3c070100, 0x3c030800, 0x24624120, 0x0a000d01, 0x8c43001c, 0x32820002, 3285 0x3c070100, 0x3c050800, 0x24a25880, 0x0a001250, 0x8c430020, 0x32820002,
2311 0x10400047, 0x3c039000, 0x34630001, 0x8f820008, 0x32500040, 0x3c048000, 3286 0x10400050, 0x00000000, 0x0e0015b9, 0x32530040, 0x3c039000, 0x34630001,
2312 0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000, 3287 0x8f820008, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024,
2313 0x8f830000, 0x90620005, 0x3c058000, 0x34420008, 0xa0620005, 0x8f860000, 3288 0x1440fffd, 0x00000000, 0x8f830000, 0x90620005, 0x34420008, 0xa0620005,
2314 0x34a50001, 0x8f840008, 0x8cc20074, 0x3c038000, 0x00852025, 0x00431025, 3289 0x8f840000, 0x8c820074, 0x3c038000, 0x00431025, 0xac820074, 0x90830000,
2315 0xacc20074, 0xaf440020, 0x90c3007b, 0x9342010a, 0x14620028, 0x3c040800, 3290 0x24020020, 0x10620004, 0x00000000, 0x0000000d, 0x00000000, 0x2400040b,
2316 0x24072000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 3291 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x9084007b,
2317 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100, 3292 0x9342010a, 0x14820028, 0x3c030800, 0x00003821, 0x24052000, 0x3c090800,
2318 0xaf420148, 0x24020046, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 3293 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0,
2319 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 3294 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030100, 0xaf420148, 0x24020046,
2320 0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 3295 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154,
2321 0x00021600, 0x00031c00, 0x00431025, 0x34424600, 0xafa20010, 0x8f440100, 3296 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030046,
2322 0x0e000fe1, 0x3c070100, 0x3c040800, 0x24824120, 0x0a000d01, 0x8c43001c, 3297 0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b,
2323 0x93420108, 0x30420010, 0x50400050, 0x9343093f, 0x8f860000, 0x90c3007f, 3298 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070100, 0x3c030800,
2324 0x90c2007e, 0x90c40080, 0x306800ff, 0x00021600, 0x00081c00, 0x00431025, 3299 0x24625880, 0x0a001250, 0x8c430020, 0x93420108, 0x30420010, 0x50400056,
2325 0x00042200, 0x90c3007a, 0x90c5000a, 0x00441025, 0x11050028, 0x00623825, 3300 0x9343093f, 0x8f860000, 0x90c2007f, 0x8cc30178, 0x304800ff, 0x15030004,
2326 0xa0c8000a, 0x24086000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 3301 0x00000000, 0x0000000d, 0x00000000, 0x24000425, 0x90c2007e, 0x90c40080,
2327 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 3302 0x00081c00, 0x00021600, 0x00431025, 0x00042200, 0x90c3007a, 0x90c5000a,
2328 0x00001821, 0xaf420148, 0x24020052, 0xaf47014c, 0xa3420152, 0x3c021000, 3303 0x00441025, 0x11050028, 0x00623825, 0xa0c8000a, 0x00004021, 0x24056000,
2329 0xa7430158, 0xaf480154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 3304 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0,
2330 0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa80014, 0xafa00018, 3305 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034, 0xaf420148, 0x24020052,
2331 0x00021600, 0x00031c00, 0x00431025, 0x34425200, 0xafa20010, 0x0e000fe1, 3306 0xaf47014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7480158, 0xaf450154,
2332 0x8f440100, 0x0a000cfb, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c, 3307 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030052,
2333 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003cd, 0x16800009, 3308 0xafa50014, 0x00021600, 0x00431025, 0x00481025, 0xafa20010, 0x9343010b,
2334 0x3c040800, 0x3c030800, 0x24624120, 0x8c43001c, 0x32500040, 0x2404ffbf, 3309 0xafa30018, 0x8f440100, 0x0e00159b, 0x8f450104, 0x0a00124a, 0x00000000,
2335 0x00641824, 0x0a000f13, 0xac43001c, 0x8c824120, 0x10400005, 0x3c030800, 3310 0x3c026000, 0x24030100, 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d,
2336 0x8c620034, 0xac804120, 0x24420001, 0xac620034, 0x9343093f, 0x24020012, 3311 0x00000000, 0x2400043e, 0x16800009, 0x3c050800, 0x3c040800, 0x24825880,
2337 0x1462000f, 0x329e0038, 0x17c0000c, 0x3c030800, 0x8f830000, 0x8c62004c, 3312 0x8c430020, 0x32530040, 0x2404ffbf, 0x00641824, 0x0a001493, 0xac430020,
2338 0xac62005c, 0x3c020800, 0x24444120, 0x8c82001c, 0x32500040, 0x2403ffbf, 3313 0x8ca25880, 0x10400005, 0x3c030800, 0x8c620034, 0xaca05880, 0x24420001,
2339 0x00431024, 0x0a000f13, 0xac82001c, 0xac604120, 0x97420908, 0x000211c0, 3314 0xac620034, 0x9343093f, 0x24020012, 0x5462000e, 0x97420908, 0x32820038,
3315 0x14400009, 0x3c030800, 0x8f830000, 0x8c62004c, 0xac62005c, 0x3c020800,
3316 0x24445880, 0x8c820020, 0x0a001285, 0x32530040, 0xac605880, 0x97420908,
3317 0x5440001c, 0x97420908, 0x3c039000, 0x34630001, 0x8f820008, 0x32530040,
3318 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd,
3319 0x3c028000, 0x8f840000, 0x8f850008, 0x8c830050, 0x34420001, 0x00a22825,
3320 0xaf830020, 0xac830070, 0xac83005c, 0xaf450020, 0x3c050800, 0x24a45880,
3321 0x8c820020, 0x2403ffbf, 0x00431024, 0x0a001493, 0xac820020, 0x000211c0,
2340 0xaf420024, 0x97420908, 0x3c030080, 0x34630003, 0x000211c0, 0xaf42080c, 3322 0xaf420024, 0x97420908, 0x3c030080, 0x34630003, 0x000211c0, 0xaf42080c,
2341 0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa7820028, 0x3c020800, 0x24444120, 3323 0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa782002c, 0x3c020800, 0x24445880,
2342 0xac830028, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830014, 3324 0xac83002c, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830018,
2343 0x934209d8, 0x00621821, 0xa4830016, 0x934209d8, 0x93430934, 0x00809821, 3325 0x934209d8, 0x32850038, 0xafa50028, 0x00621821, 0xa483001a, 0x934209d8,
2344 0x00431021, 0x24420010, 0xa4820012, 0x0000a821, 0x24020006, 0x13c00003, 3326 0x93430934, 0x3c1e0800, 0x00809821, 0x00431021, 0x24420010, 0xa4820016,
2345 0xae62001c, 0x0a000d82, 0x24120008, 0x8f420958, 0x8f830020, 0x8f84002c, 3327 0x24020006, 0xae620020, 0x8fa20028, 0x10400003, 0x0000a821, 0x0a0012f0,
2346 0x00431023, 0x00832023, 0x04800003, 0xae620004, 0x04410003, 0x0082102b, 3328 0x24120008, 0x8f420958, 0x8f830020, 0x8f840030, 0x00431023, 0x00832023,
2347 0x0a000d4e, 0xae600004, 0x54400001, 0xae640004, 0x8ee20000, 0x0040f809, 3329 0x04800003, 0xae620004, 0x04410003, 0x0082102b, 0x0a0012bc, 0xae600004,
2348 0x00000000, 0x00409021, 0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008, 3330 0x54400001, 0xae640004, 0x8ee20000, 0x0040f809, 0x00000000, 0x00409021,
2349 0x1060002b, 0x3c02c000, 0x00621025, 0xaf420e00, 0x8f420000, 0x30420008, 3331 0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008, 0x1060002b, 0x3c02c000,
2350 0x1040fffd, 0x00000000, 0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008, 3332 0x00621025, 0xaf420e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000,
2351 0xaf830004, 0x8f840004, 0x0044102b, 0x1040000b, 0x24150001, 0x24020100, 3333 0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008, 0xaf830004, 0x8f840004,
2352 0x3c016000, 0xac22081c, 0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d, 3334 0x0044102b, 0x1040000b, 0x24150001, 0x24020100, 0x3c016000, 0xac22081c,
2353 0x00000000, 0x24000449, 0x24150001, 0x8ee20004, 0x0040f809, 0x00000000, 3335 0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d, 0x00000000, 0x240004cd,
2354 0x02429025, 0x32420002, 0x5040001d, 0x8f470940, 0x12a00006, 0x8ec2414c, 3336 0x24150001, 0x8ee20004, 0x0040f809, 0x00000000, 0x02429025, 0x32420002,
2355 0x8f830000, 0xac6200a8, 0x8f840000, 0x8e620030, 0xac8200ac, 0x32420004, 3337 0x5040001d, 0x8f470940, 0x12a00006, 0x8ec258b0, 0x8f830000, 0xac6200a8,
2356 0x50400013, 0x8f470940, 0x3c020800, 0x3283007d, 0x106000fe, 0x245741b0, 3338 0x8f840000, 0x8e620034, 0xac8200ac, 0x32420004, 0x50400013, 0x8f470940,
2357 0x32820001, 0x50400006, 0x36520002, 0x8f830030, 0x8f420940, 0x106200f7, 3339 0x3c020800, 0x3283007d, 0x10600110, 0x24575920, 0x32820001, 0x50400006,
2358 0x00000000, 0x36520002, 0x24020008, 0xa660000c, 0xa662000e, 0xae600008, 3340 0x36520002, 0x8f830034, 0x8f420940, 0x10620109, 0x00000000, 0x36520002,
2359 0xa2600020, 0x8f470940, 0x3c030800, 0x24684120, 0x8d020028, 0x8d050008, 3341 0x24020008, 0xa6600010, 0xa6620012, 0xae600008, 0xa2600024, 0x8f470940,
2360 0x9504000c, 0x9506000a, 0x95030022, 0x00451021, 0x00862021, 0x00641821, 3342 0x3c030800, 0x24685880, 0x8d02002c, 0x8d050008, 0x95040010, 0x9506000a,
2361 0xaf870030, 0xad020028, 0x32820030, 0x10400006, 0xa5030010, 0x91020020, 3343 0x95030026, 0x00451021, 0x00862021, 0x00641821, 0xaf870034, 0xad02002c,
2362 0x32910040, 0x34420004, 0x0a000dd4, 0xa1020020, 0x93420923, 0x30420040, 3344 0x32820030, 0x10400008, 0xa5030014, 0x91020024, 0x32910040, 0x34420004,
3345 0xa1020024, 0xaf400048, 0x0a001345, 0x3c040800, 0x93420923, 0x30420002,
2363 0x10400029, 0x32910040, 0x8f830000, 0x8f840020, 0x8c620084, 0x00441023, 3346 0x10400029, 0x32910040, 0x8f830000, 0x8f840020, 0x8c620084, 0x00441023,
2364 0x0442000a, 0x3c039000, 0x95020010, 0x8c630084, 0x00821021, 0x00621823, 3347 0x0442000a, 0x3c039000, 0x95020014, 0x8c630084, 0x00821021, 0x00621823,
2365 0x1c600004, 0x3c039000, 0x91020020, 0x34420001, 0xa1020020, 0x34630001, 3348 0x1c600004, 0x3c039000, 0x91020024, 0x34420001, 0xa1020024, 0x34630001,
2366 0x8f820008, 0x32910040, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, 3349 0x8f820008, 0x32910040, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020,
2367 0x00441024, 0x1440fffd, 0x00000000, 0x8f840000, 0x9083003f, 0x2402000a, 3350 0x00441024, 0x1440fffd, 0x00000000, 0x8f840000, 0x9083003f, 0x2402000a,
2368 0x10620005, 0x2402000c, 0x9083003f, 0x24020008, 0x14620002, 0x24020014, 3351 0x10620005, 0x2402000c, 0x9083003f, 0x24020008, 0x14620002, 0x24020014,
2369 0xa082003f, 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 3352 0xa082003f, 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020,
2370 0x3c040800, 0x24904120, 0x9602000c, 0x96030016, 0x9604000e, 0x00431021, 3353 0x3c040800, 0x24865880, 0x94c20010, 0x94c3001a, 0x8cc40008, 0x00432821,
2371 0x00442021, 0x24840002, 0x3084ffff, 0x0e000a55, 0xa6020018, 0x8f850018, 3354 0x14800006, 0xa4c5001c, 0x3c020800, 0x8c430048, 0x10600002, 0x24a20040,
2372 0x00a01821, 0xa2030021, 0x8ee60008, 0x00402021, 0x24a50001, 0xaf850018, 3355 0xa4c2001c, 0x27d05880, 0x9604001c, 0x96020012, 0x00822021, 0x24840002,
2373 0x00c0f809, 0x00000000, 0x00402021, 0x0e000b12, 0x02202821, 0x8ee3000c, 3356 0x0e000faf, 0x3084ffff, 0x8f850018, 0x00a01821, 0xa2030025, 0x8ee60008,
2374 0x0060f809, 0x00402021, 0x96040018, 0x9602000e, 0x00822021, 0x24840002, 3357 0x00402021, 0x24a50001, 0xaf850018, 0x00c0f809, 0x00000000, 0x00402021,
2375 0x0e000a6b, 0x3084ffff, 0x3c030800, 0x8c624120, 0x8e030008, 0x3c040800, 3358 0x0e001026, 0x02202821, 0x8ee3000c, 0x0060f809, 0x00402021, 0x9604001c,
2376 0x00431023, 0x14400012, 0xac824120, 0x54600006, 0x8e02001c, 0x3243004a, 3359 0x96020012, 0x00822021, 0x24840002, 0x0e000fc5, 0x3084ffff, 0x8fc25880,
2377 0x24020002, 0x14620005, 0x00000000, 0x8e02001c, 0x34420040, 0x0a000e0b, 3360 0x8e030008, 0x00431023, 0x14400012, 0xafc25880, 0x54600006, 0x8e020020,
2378 0xae02001c, 0x52a00006, 0x36520002, 0x8e02002c, 0xaf420e10, 0x8e030030, 3361 0x3243004a, 0x24020002, 0x14620005, 0x00000000, 0x8e020020, 0x34420040,
2379 0xaf430e18, 0x36520002, 0x52a00008, 0x96670010, 0x8f830000, 0x8f420e10, 3362 0x0a001382, 0xae020020, 0x52a00006, 0x36520002, 0x8e020030, 0xaf420e10,
2380 0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670010, 0x92680020, 3363 0x8e030034, 0xaf430e18, 0x36520002, 0x52a00008, 0x96670014, 0x8f830000,
2381 0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821, 0x00621023, 3364 0x8f420e10, 0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670014,
2382 0xaf830020, 0x58400005, 0x8f42095c, 0x8f820000, 0xaf83001c, 0xac430054, 3365 0x92680024, 0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821,
2383 0x8f42095c, 0x31030008, 0xaf82002c, 0x1060001a, 0x00000000, 0x8f840000, 3366 0x00621023, 0xaf830020, 0x18400008, 0x00000000, 0x8f820000, 0xaf83001c,
2384 0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007, 0x24020007, 3367 0xac430054, 0x54e00005, 0xaf400040, 0x0a0013a0, 0x8f42095c, 0x54e00001,
2385 0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122, 0x8f850000, 3368 0xaf400044, 0x8f42095c, 0x31030008, 0xaf820030, 0x1060001a, 0x00000000,
2386 0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001, 0x30630007, 3369 0x8f840000, 0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007,
2387 0xac440000, 0x0a000e40, 0xa0a30120, 0x90820122, 0x34420001, 0xa0820122, 3370 0x24020007, 0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122,
2388 0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000, 0x8c43000c, 3371 0x8f850000, 0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001,
2389 0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008, 0x34420001, 3372 0x30630007, 0xac440000, 0x0a0013bd, 0xa0a30120, 0x90820122, 0x34420001,
2390 0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 3373 0xa0820122, 0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000,
2391 0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018, 0x00000000, 3374 0x8c43000c, 0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008,
2392 0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068, 0x90e40081, 3375 0x34420001, 0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024,
2393 0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 3376 0x1440fffd, 0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018,
2394 0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001, 0x00c02021, 3377 0x00000000, 0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068,
2395 0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c, 0x8f830008, 3378 0x90e40081, 0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b,
2396 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f830020, 0x3c020800, 3379 0x54400001, 0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001,
2397 0x24504120, 0xae030024, 0x8ee20010, 0x0040f809, 0x00000000, 0x12a00005, 3380 0x00c02021, 0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c,
2398 0x00000000, 0x8f420e10, 0xae02002c, 0x8f430e18, 0xae030030, 0x1220feba, 3381 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f820020,
2399 0x0000a821, 0x8f870024, 0x97860028, 0x8f830000, 0x8f820030, 0x8f840020, 3382 0x3c050800, 0x24b05880, 0xae020028, 0x8ee30010, 0x0060f809, 0x00000000,
2400 0x8f85001c, 0x32500040, 0xa4e6002c, 0xac620044, 0x32420008, 0xac640050, 3383 0x8f820028, 0x24420001, 0xaf820028, 0x12a00005, 0xaf40004c, 0x8f420e10,
2401 0xac650054, 0x1040007a, 0x32820020, 0x10400027, 0x32910010, 0x24072000, 3384 0xae020030, 0x8f430e18, 0xae030034, 0x1220fea7, 0x24020006, 0x8f870024,
2402 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c, 3385 0x9786002c, 0x8f830000, 0x8f820034, 0x8f840020, 0x8f85001c, 0x32530040,
2403 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030400, 0xaf420148, 3386 0xa4e6002c, 0xac620044, 0x32420008, 0xac640050, 0xac650054, 0x1040007a,
2404 0x24020041, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158, 3387 0x32820020, 0x10400027, 0x32910010, 0x00003821, 0x24052000, 0x3c090800,
2405 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001, 3388 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0,
2406 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600, 3389 0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030400, 0xaf420148, 0x24020041,
2407 0x00031c00, 0x00431025, 0x34424100, 0xafa20010, 0x8f440100, 0x0e000fe1, 3390 0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154,
2408 0x3c070400, 0x12200028, 0x24072000, 0x3c090800, 0x3c038000, 0x8f420178, 3391 0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030041,
2409 0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 3392 0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b,
2410 0x8c820030, 0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0x00001821, 3393 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070400, 0x12200028,
2411 0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c, 3394 0x00003821, 0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
2412 0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a, 3395 0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
2413 0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424e00, 3396 0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0xa3420152, 0x8d230030,
2414 0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070300, 0x0a000f0b, 0x8fa30024, 3397 0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
2415 0x32820008, 0x10400026, 0x3c090800, 0x24072000, 0x3c038000, 0x8f420178, 3398 0xad230030, 0x9342010a, 0x3c03004e, 0xafa50014, 0x00021600, 0x00431025,
2416 0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 3399 0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
2417 0x8c820030, 0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0x00001821, 3400 0x0e00159b, 0x3c070300, 0x0a00148b, 0x8fa20024, 0x32820008, 0x10400026,
2418 0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c, 3401 0x24052000, 0x00003821, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
2419 0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a, 3402 0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
2420 0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424b00, 3403 0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0xa3420152, 0x8d230030,
2421 0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070200, 0x8fa30024, 0x14600004, 3404 0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
2422 0x8fa40020, 0x32420010, 0x10400004, 0x00000000, 0x8c820004, 0x0040f809, 3405 0xad230030, 0x9342010a, 0x3c03004b, 0xafa50014, 0x00021600, 0x00431025,
2423 0x00000000, 0x12000006, 0x8fa30020, 0x8c620008, 0x0040f809, 0x00000000, 3406 0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
2424 0x0a000f4d, 0x8fbf004c, 0x3c030800, 0x8c62413c, 0x30420040, 0x1440002f, 3407 0x0e00159b, 0x3c070200, 0x8fa20024, 0x14400004, 0x8fa30020, 0x32420010,
2425 0x8fbf004c, 0x24040040, 0x8f910020, 0x3c038000, 0x8f420178, 0x00431024, 3408 0x10400004, 0x00000000, 0x8c620004, 0x0040f809, 0x00000000, 0x12600006,
2426 0x1440fffd, 0x8ec2414c, 0x26d0414c, 0x2610ffd4, 0xaf420144, 0x8e020030, 3409 0x8fa40020, 0x8c820008, 0x0040f809, 0x00000000, 0x0a0014c1, 0x8fbf0054,
2427 0x00001821, 0xaf420148, 0x24020049, 0xaf51014c, 0xa3420152, 0x3c021000, 3410 0x3c030800, 0x8c6258a0, 0x30420040, 0x14400023, 0x8fbf0054, 0x00002821,
2428 0xa7430158, 0xaf440154, 0xaf420178, 0x8ec5414c, 0x8e060030, 0x93420109, 3411 0x24040040, 0x8f870020, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
2429 0x9343010a, 0xafa40014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 3412 0x8ec258b0, 0x26c358b0, 0x2463ffd0, 0xaf420144, 0x8c620034, 0xaf420148,
2430 0x34424900, 0xafa20010, 0x8f440100, 0x0e000fe1, 0x02203821, 0x8f830000, 3413 0x24020049, 0xaf47014c, 0xa3420152, 0x3c021000, 0xa7450158, 0xaf440154,
2431 0x8e020030, 0x8c64017c, 0x02221023, 0x00441023, 0x2c420002, 0x14400005, 3414 0xaf420178, 0x8c660034, 0x9342010a, 0x3c030049, 0xafa40014, 0x00021600,
2432 0x8fbf004c, 0x0000000d, 0x00000000, 0x240000ca, 0x8fbf004c, 0x8fbe0048, 3415 0x00431025, 0x00451025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100,
2433 0x8fb70044, 0x8fb60040, 0x8fb5003c, 0x8fb40038, 0x8fb30034, 0x8fb20030, 3416 0x0e00159b, 0x8f450104, 0x8fbf0054, 0x8fbe0050, 0x8fb7004c, 0x8fb60048,
2434 0x8fb1002c, 0x8fb00028, 0x03e00008, 0x27bd0050, 0x03e00008, 0x00001021, 3417 0x8fb50044, 0x8fb40040, 0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
2435 0x3c030800, 0x24654120, 0x8ca40004, 0x8c634120, 0x0064102b, 0x54400001, 3418 0x03e00008, 0x27bd0058, 0x03e00008, 0x00001021, 0x3c020800, 0x24435880,
2436 0x00602021, 0x9743093c, 0x0083102b, 0x54400001, 0x00801821, 0x00001021, 3419 0x8c650004, 0x8c445880, 0x0085182b, 0x10600002, 0x00403021, 0x00802821,
2437 0xaca30008, 0x03e00008, 0xa4a00022, 0x8f850004, 0x97840010, 0x3c030800, 3420 0x9744093c, 0x00a4102b, 0x54400001, 0x00a02021, 0x93420923, 0x0004182b,
2438 0x24634120, 0x24020008, 0xa462000e, 0x8f820004, 0xa460000c, 0x000420c2, 3421 0x00021042, 0x30420001, 0x00431024, 0x1040000d, 0x24c25880, 0x8f850000,
3422 0x8f830020, 0x8ca20084, 0x00431023, 0x04420007, 0x24c25880, 0x8ca20084,
3423 0x00641821, 0x00431023, 0x28420001, 0x00822023, 0x24c25880, 0xac440008,
3424 0xa4400026, 0x03e00008, 0x00001021, 0x8f850004, 0x97840010, 0x3c030800,
3425 0x24635880, 0x24020008, 0xa4620012, 0x8f820004, 0xa4600010, 0x000420c2,
2439 0x30840008, 0x2c420001, 0x00021023, 0x30420006, 0xac650008, 0x03e00008, 3426 0x30840008, 0x2c420001, 0x00021023, 0x30420006, 0xac650008, 0x03e00008,
2440 0xa0640020, 0x3c020800, 0x24424120, 0x90450021, 0x94430018, 0x3c021100, 3427 0xa0640024, 0x3c020800, 0x24425880, 0x90450025, 0x9443001c, 0x3c021100,
2441 0xac800004, 0x00052c00, 0x24630002, 0x00621825, 0x00a32825, 0x24820008, 3428 0xac800004, 0x00052c00, 0x24630002, 0x00621825, 0x00a32825, 0x24820008,
2442 0x03e00008, 0xac850000, 0x0000000d, 0x00000000, 0x2400016f, 0x03e00008, 3429 0x03e00008, 0xac850000, 0x27bdffd8, 0x3c020800, 0x24425880, 0xafbf0020,
2443 0x00000000, 0x0000000d, 0x00000000, 0x2400017b, 0x03e00008, 0x00000000, 3430 0x90480025, 0x8c440008, 0x8c460020, 0x8f870020, 0x3c030800, 0x3c058000,
2444 0x03e00008, 0x00000000, 0x3c020800, 0x24424120, 0xac400008, 0xa4400022, 3431 0x8f420178, 0x00451024, 0x1440fffd, 0x8c6258b0, 0x246358b0, 0x2469ffd0,
2445 0x03e00008, 0x24020001, 0x3c020800, 0x24424120, 0x24030008, 0xac400008, 3432 0xaf420144, 0x8d220034, 0x30c32000, 0xaf420148, 0x3c021000, 0xaf47014c,
2446 0xa440000c, 0xa443000e, 0xa0400020, 0x03e00008, 0x24020004, 0x03e00008, 3433 0xa3480152, 0xa7440158, 0xaf460154, 0xaf420178, 0x10600004, 0x3c030800,
3434 0x8c620030, 0x24420001, 0xac620030, 0x9342010a, 0x00081c00, 0x3084ffff,
3435 0xafa60014, 0x00021600, 0x00431025, 0x00441025, 0xafa20010, 0x9343010b,
3436 0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x8d260034, 0x8fbf0020,
3437 0x03e00008, 0x27bd0028, 0x0000000d, 0x00000000, 0x2400019d, 0x03e00008,
3438 0x00000000, 0x0000000d, 0x00000000, 0x240001a9, 0x03e00008, 0x00000000,
3439 0x03e00008, 0x00000000, 0x3c020800, 0x24425880, 0xac400008, 0xa4400026,
3440 0x03e00008, 0x24020001, 0x3c020800, 0x24425880, 0x24030008, 0xac400008,
3441 0xa4400010, 0xa4430012, 0xa0400024, 0x03e00008, 0x24020004, 0x03e00008,
2447 0x00001021, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 3442 0x00001021, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004,
2448 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000fb2, 3443 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00156c,
2449 0x00a01021, 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 3444 0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021,
2450 0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068, 0x3c050800, 0x24a51090, 3445 0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068,
2451 0x00093140, 0x00c51021, 0xac440000, 0x8f440e04, 0x00a61021, 0xac440004, 3446 0x3c050800, 0x24a52098, 0x00093140, 0x00c51021, 0xac440000, 0x8f440e04,
2452 0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00, 0x00431025, 0xac820008, 3447 0x00a61021, 0xac440004, 0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00,
2453 0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14, 0xac440010, 0x8f430e18, 3448 0x00431025, 0xac820008, 0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14,
2454 0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff, 0x25290001, 0xac470018, 3449 0xac440010, 0x8f430e18, 0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff,
2455 0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000, 0x24630001, 0xace3006c, 3450 0x25290001, 0xac470018, 0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000,
2456 0x8c434448, 0x3129007f, 0x00a62821, 0xad490068, 0x00042600, 0x00681824, 3451 0x24630001, 0xace3006c, 0x8c434448, 0x3129007f, 0x00a62821, 0xad490068,
2457 0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010, 0x8fad0014, 0x8fae0018, 3452 0x00042600, 0x00681824, 0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010,
2458 0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080078, 0x000a4940, 0x01281021, 3453 0x8fad0014, 0x8fae0018, 0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080080,
2459 0x01091821, 0xac440000, 0x00601021, 0xac650004, 0xac460008, 0xac67000c, 3454 0x000a4940, 0x01281021, 0x01091821, 0xac440000, 0x00601021, 0xac650004,
2460 0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018, 0x8c654448, 0x3c040800, 3455 0xac460008, 0xac67000c, 0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018,
2461 0x8c820064, 0x254a0001, 0x314a007f, 0x01094021, 0xad6a0060, 0x24420001, 3456 0x8c654448, 0x3c040800, 0x8c820064, 0x254a0001, 0x314a00ff, 0x01094021,
2462 0xac820064, 0x03e00008, 0xad05001c, 0x00000000 }; 3457 0xad6a0060, 0x24420001, 0xac820064, 0x03e00008, 0xad05001c, 0x3c030800,
2463 3458 0x3c090800, 0x8d250070, 0x246330b0, 0x8f460100, 0x00053900, 0x00e31021,
2464static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x00000000 }; 3459 0xac460000, 0x8f440104, 0x00671021, 0xac440004, 0x8f460108, 0x8f840014,
2465static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 }; 3460 0x24a50001, 0xac460008, 0x8c880074, 0x3c060800, 0x8cc20074, 0x30a5003f,
2466static u32 bnx2_TXP_b06FwBss[(0x194/4) + 1] = { 0x00000000 }; 3461 0x00671821, 0xad250070, 0x24420001, 0xacc20074, 0x03e00008, 0xac68000c,
2467static u32 bnx2_TXP_b06FwSbss[(0x34/4) + 1] = { 0x00000000 }; 3462 0x00000000 };
2468 3463
3464static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
3465static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
3466static u32 bnx2_TXP_b06FwBss[(0x1c4/4) + 1] = { 0x0 };
3467static u32 bnx2_TXP_b06FwSbss[(0x38/4) + 1] = { 0x0 };
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8032126fd589..94cec3cf2a13 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1604,35 +1604,27 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_
1604 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) 1604 (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
1605 1605
1606/* 1606/*
1607 * Compute the features available to the bonding device by 1607 * Compute the common dev->feature set available to all slaves. Some
1608 * intersection of all of the slave devices' BOND_INTERSECT_FEATURES. 1608 * feature bits are managed elsewhere, so preserve feature bits set on
1609 * Call this after attaching or detaching a slave to update the 1609 * master device that are not part of the examined set.
1610 * bond's features.
1611 */ 1610 */
1612static int bond_compute_features(struct bonding *bond) 1611static int bond_compute_features(struct bonding *bond)
1613{ 1612{
1614 int i; 1613 unsigned long features = BOND_INTERSECT_FEATURES;
1615 struct slave *slave; 1614 struct slave *slave;
1616 struct net_device *bond_dev = bond->dev; 1615 struct net_device *bond_dev = bond->dev;
1617 int features = bond->bond_features; 1616 int i;
1618 1617
1619 bond_for_each_slave(bond, slave, i) { 1618 bond_for_each_slave(bond, slave, i)
1620 struct net_device * slave_dev = slave->dev; 1619 features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
1621 if (i == 0) {
1622 features |= BOND_INTERSECT_FEATURES;
1623 }
1624 features &=
1625 ~(~slave_dev->features & BOND_INTERSECT_FEATURES);
1626 }
1627 1620
1628 /* turn off NETIF_F_SG if we need a csum and h/w can't do it */
1629 if ((features & NETIF_F_SG) && 1621 if ((features & NETIF_F_SG) &&
1630 !(features & (NETIF_F_IP_CSUM | 1622 !(features & (NETIF_F_IP_CSUM |
1631 NETIF_F_NO_CSUM | 1623 NETIF_F_NO_CSUM |
1632 NETIF_F_HW_CSUM))) { 1624 NETIF_F_HW_CSUM)))
1633 features &= ~NETIF_F_SG; 1625 features &= ~NETIF_F_SG;
1634 }
1635 1626
1627 features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
1636 bond_dev->features = features; 1628 bond_dev->features = features;
1637 1629
1638 return 0; 1630 return 0;
@@ -4561,8 +4553,6 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
4561 NETIF_F_HW_VLAN_RX | 4553 NETIF_F_HW_VLAN_RX |
4562 NETIF_F_HW_VLAN_FILTER); 4554 NETIF_F_HW_VLAN_FILTER);
4563 4555
4564 bond->bond_features = bond_dev->features;
4565
4566#ifdef CONFIG_PROC_FS 4556#ifdef CONFIG_PROC_FS
4567 bond_create_proc_entry(bond); 4557 bond_create_proc_entry(bond);
4568#endif 4558#endif
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index bbf9da8af624..1433e91db0f7 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -40,8 +40,8 @@
40#include "bond_3ad.h" 40#include "bond_3ad.h"
41#include "bond_alb.h" 41#include "bond_alb.h"
42 42
43#define DRV_VERSION "2.6.4" 43#define DRV_VERSION "2.6.5"
44#define DRV_RELDATE "September 26, 2005" 44#define DRV_RELDATE "November 4, 2005"
45#define DRV_NAME "bonding" 45#define DRV_NAME "bonding"
46#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 46#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
47 47
@@ -211,9 +211,6 @@ struct bonding {
211 struct bond_params params; 211 struct bond_params params;
212 struct list_head vlan_list; 212 struct list_head vlan_list;
213 struct vlan_group *vlgrp; 213 struct vlan_group *vlgrp;
214 /* the features the bonding device supports, independently
215 * of any slaves */
216 int bond_features;
217}; 214};
218 215
219/** 216/**
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 50f43dbf31ae..1f7ca453bb4a 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -67,7 +67,6 @@
67 */ 67 */
68 68
69#include <linux/config.h> 69#include <linux/config.h>
70#include <linux/version.h>
71 70
72#include <linux/module.h> 71#include <linux/module.h>
73#include <linux/kernel.h> 72#include <linux/kernel.h>
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index b68b9cad76e9..64105e4eaf31 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -409,7 +409,6 @@ static irqreturn_t e100nw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
409static void e100_rx(struct net_device *dev); 409static void e100_rx(struct net_device *dev);
410static int e100_close(struct net_device *dev); 410static int e100_close(struct net_device *dev);
411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 411static int e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
412static int e100_ethtool_ioctl(struct net_device* dev, struct ifreq *ifr);
413static int e100_set_config(struct net_device* dev, struct ifmap* map); 412static int e100_set_config(struct net_device* dev, struct ifmap* map);
414static void e100_tx_timeout(struct net_device *dev); 413static void e100_tx_timeout(struct net_device *dev);
415static struct net_device_stats *e100_get_stats(struct net_device *dev); 414static struct net_device_stats *e100_get_stats(struct net_device *dev);
@@ -436,6 +435,8 @@ static void e100_reset_transceiver(struct net_device* net);
436static void e100_clear_network_leds(unsigned long dummy); 435static void e100_clear_network_leds(unsigned long dummy);
437static void e100_set_network_leds(int active); 436static void e100_set_network_leds(int active);
438 437
438static struct ethtool_ops e100_ethtool_ops;
439
439static void broadcom_check_speed(struct net_device* dev); 440static void broadcom_check_speed(struct net_device* dev);
440static void broadcom_check_duplex(struct net_device* dev); 441static void broadcom_check_duplex(struct net_device* dev);
441static void tdk_check_speed(struct net_device* dev); 442static void tdk_check_speed(struct net_device* dev);
@@ -495,6 +496,7 @@ etrax_ethernet_init(void)
495 dev->get_stats = e100_get_stats; 496 dev->get_stats = e100_get_stats;
496 dev->set_multicast_list = set_multicast_list; 497 dev->set_multicast_list = set_multicast_list;
497 dev->set_mac_address = e100_set_mac_address; 498 dev->set_mac_address = e100_set_mac_address;
499 dev->ethtool_ops = &e100_ethtool_ops;
498 dev->do_ioctl = e100_ioctl; 500 dev->do_ioctl = e100_ioctl;
499 dev->set_config = e100_set_config; 501 dev->set_config = e100_set_config;
500 dev->tx_timeout = e100_tx_timeout; 502 dev->tx_timeout = e100_tx_timeout;
@@ -1448,8 +1450,6 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1448 1450
1449 spin_lock(&np->lock); /* Preempt protection */ 1451 spin_lock(&np->lock); /* Preempt protection */
1450 switch (cmd) { 1452 switch (cmd) {
1451 case SIOCETHTOOL:
1452 return e100_ethtool_ioctl(dev,ifr);
1453 case SIOCGMIIPHY: /* Get PHY address */ 1453 case SIOCGMIIPHY: /* Get PHY address */
1454 data->phy_id = mdio_phy_addr; 1454 data->phy_id = mdio_phy_addr;
1455 break; 1455 break;
@@ -1486,88 +1486,81 @@ e100_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1486 return 0; 1486 return 0;
1487} 1487}
1488 1488
1489static int 1489static int e100_set_settings(struct net_device *dev,
1490e100_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr) 1490 struct ethtool_cmd *ecmd)
1491{ 1491{
1492 struct ethtool_cmd ecmd; 1492 ecmd->supported = SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1493
1494 if (copy_from_user(&ecmd, ifr->ifr_data, sizeof (ecmd)))
1495 return -EFAULT;
1496
1497 switch (ecmd.cmd) {
1498 case ETHTOOL_GSET:
1499 {
1500 memset((void *) &ecmd, 0, sizeof (ecmd));
1501 ecmd.supported =
1502 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
1503 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | 1493 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
1504 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; 1494 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
1505 ecmd.port = PORT_TP; 1495 ecmd->port = PORT_TP;
1506 ecmd.transceiver = XCVR_EXTERNAL; 1496 ecmd->transceiver = XCVR_EXTERNAL;
1507 ecmd.phy_address = mdio_phy_addr; 1497 ecmd->phy_address = mdio_phy_addr;
1508 ecmd.speed = current_speed; 1498 ecmd->speed = current_speed;
1509 ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF; 1499 ecmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
1510 ecmd.advertising = ADVERTISED_TP; 1500 ecmd->advertising = ADVERTISED_TP;
1511 if (current_duplex == autoneg && current_speed_selection == 0) 1501
1512 ecmd.advertising |= ADVERTISED_Autoneg; 1502 if (current_duplex == autoneg && current_speed_selection == 0)
1513 else { 1503 ecmd->advertising |= ADVERTISED_Autoneg;
1514 ecmd.advertising |= 1504 else {
1515 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | 1505 ecmd->advertising |=
1516 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; 1506 ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
1517 if (current_speed_selection == 10) 1507 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
1518 ecmd.advertising &= ~(ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full); 1508 if (current_speed_selection == 10)
1519 else if (current_speed_selection == 100) 1509 ecmd->advertising &= ~(ADVERTISED_100baseT_Half |
1520 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full); 1510 ADVERTISED_100baseT_Full);
1521 if (current_duplex == half) 1511 else if (current_speed_selection == 100)
1522 ecmd.advertising &= ~(ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Full); 1512 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1523 else if (current_duplex == full) 1513 ADVERTISED_10baseT_Full);
1524 ecmd.advertising &= ~(ADVERTISED_10baseT_Half | ADVERTISED_100baseT_Half); 1514 if (current_duplex == half)
1525 } 1515 ecmd->advertising &= ~(ADVERTISED_10baseT_Full |
1526 ecmd.autoneg = AUTONEG_ENABLE; 1516 ADVERTISED_100baseT_Full);
1527 if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd))) 1517 else if (current_duplex == full)
1528 return -EFAULT; 1518 ecmd->advertising &= ~(ADVERTISED_10baseT_Half |
1529 } 1519 ADVERTISED_100baseT_Half);
1530 break; 1520 }
1531 case ETHTOOL_SSET: 1521
1532 { 1522 ecmd->autoneg = AUTONEG_ENABLE;
1533 if (!capable(CAP_NET_ADMIN)) { 1523 return 0;
1534 return -EPERM; 1524}
1535 } 1525
1536 if (ecmd.autoneg == AUTONEG_ENABLE) { 1526static int e100_set_settings(struct net_device *dev,
1537 e100_set_duplex(dev, autoneg); 1527 struct ethtool_cmd *ecmd)
1538 e100_set_speed(dev, 0); 1528{
1539 } else { 1529 if (ecmd->autoneg == AUTONEG_ENABLE) {
1540 e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full); 1530 e100_set_duplex(dev, autoneg);
1541 e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100); 1531 e100_set_speed(dev, 0);
1542 } 1532 } else {
1543 } 1533 e100_set_duplex(dev, ecmd->duplex == DUPLEX_HALF ? half : full);
1544 break; 1534 e100_set_speed(dev, ecmd->speed == SPEED_10 ? 10: 100);
1545 case ETHTOOL_GDRVINFO:
1546 {
1547 struct ethtool_drvinfo info;
1548 memset((void *) &info, 0, sizeof (info));
1549 strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1);
1550 strncpy(info.version, "$Revision: 1.31 $", sizeof(info.version) - 1);
1551 strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
1552 strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
1553 info.regdump_len = 0;
1554 info.eedump_len = 0;
1555 info.testinfo_len = 0;
1556 if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
1557 return -EFAULT;
1558 }
1559 break;
1560 case ETHTOOL_NWAY_RST:
1561 if (current_duplex == autoneg && current_speed_selection == 0)
1562 e100_negotiate(dev);
1563 break;
1564 default:
1565 return -EOPNOTSUPP;
1566 break;
1567 } 1535 }
1536
1537 return 0;
1538}
1539
1540static void e100_get_drvinfo(struct net_device *dev,
1541 struct ethtool_drvinfo *info)
1542{
1543 strncpy(info->driver, "ETRAX 100LX", sizeof(info->driver) - 1);
1544 strncpy(info->version, "$Revision: 1.31 $", sizeof(info->version) - 1);
1545 strncpy(info->fw_version, "N/A", sizeof(info->fw_version) - 1);
1546 strncpy(info->bus_info, "N/A", sizeof(info->bus_info) - 1);
1547}
1548
1549static int e100_nway_reset(struct net_device *dev)
1550{
1551 if (current_duplex == autoneg && current_speed_selection == 0)
1552 e100_negotiate(dev);
1568 return 0; 1553 return 0;
1569} 1554}
1570 1555
1556static struct ethtool_ops e100_ethtool_ops = {
1557 .get_settings = e100_get_settings,
1558 .set_settings = e100_set_settings,
1559 .get_drvinfo = e100_get_drvinfo,
1560 .nway_reset = e100_nway_reset,
1561 .get_link = ethtool_op_get_link,
1562};
1563
1571static int 1564static int
1572e100_set_config(struct net_device *dev, struct ifmap *map) 1565e100_set_config(struct net_device *dev, struct ifmap *map)
1573{ 1566{
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 4d26e5e7d18b..0d33a93df96b 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -1470,15 +1470,6 @@ static int __init depca_mca_probe(struct device *device)
1470** ISA bus I/O device probe 1470** ISA bus I/O device probe
1471*/ 1471*/
1472 1472
1473static void depca_platform_release (struct device *device)
1474{
1475 struct platform_device *pldev;
1476
1477 /* free device */
1478 pldev = to_platform_device (device);
1479 kfree (pldev);
1480}
1481
1482static void __init depca_platform_probe (void) 1473static void __init depca_platform_probe (void)
1483{ 1474{
1484 int i; 1475 int i;
@@ -1491,19 +1482,16 @@ static void __init depca_platform_probe (void)
1491 * line, use it (if valid) */ 1482 * line, use it (if valid) */
1492 if (io && io != depca_io_ports[i].iobase) 1483 if (io && io != depca_io_ports[i].iobase)
1493 continue; 1484 continue;
1494 1485
1495 if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) 1486 pldev = platform_device_alloc(depca_string, i);
1487 if (!pldev)
1496 continue; 1488 continue;
1497 1489
1498 memset (pldev, 0, sizeof (*pldev));
1499 pldev->name = depca_string;
1500 pldev->id = i;
1501 pldev->dev.platform_data = (void *) depca_io_ports[i].iobase; 1490 pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
1502 pldev->dev.release = depca_platform_release;
1503 depca_io_ports[i].device = pldev; 1491 depca_io_ports[i].device = pldev;
1504 1492
1505 if (platform_device_register (pldev)) { 1493 if (platform_device_add(pldev)) {
1506 kfree (pldev); 1494 platform_device_put(pldev);
1507 depca_io_ports[i].device = NULL; 1495 depca_io_ports[i].device = NULL;
1508 continue; 1496 continue;
1509 } 1497 }
@@ -1515,6 +1503,7 @@ static void __init depca_platform_probe (void)
1515 * allocated structure */ 1503 * allocated structure */
1516 1504
1517 depca_io_ports[i].device = NULL; 1505 depca_io_ports[i].device = NULL;
1506 pldev->dev.platform_data = NULL;
1518 platform_device_unregister (pldev); 1507 platform_device_unregister (pldev);
1519 } 1508 }
1520 } 1509 }
@@ -2112,6 +2101,7 @@ static void __exit depca_module_exit (void)
2112 2101
2113 for (i = 0; depca_io_ports[i].iobase; i++) { 2102 for (i = 0; depca_io_ports[i].iobase; i++) {
2114 if (depca_io_ports[i].device) { 2103 if (depca_io_ports[i].device) {
2104 depca_io_ports[i].device->dev.platform_data = NULL;
2115 platform_device_unregister (depca_io_ports[i].device); 2105 platform_device_unregister (depca_io_ports[i].device);
2116 depca_io_ports[i].device = NULL; 2106 depca_io_ports[i].device = NULL;
2117 } 2107 }
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index 7809838e6c4c..2a290cc397ad 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -1549,7 +1549,7 @@ MODULE_PARM_DESC(nicmode, "Digi RightSwitch operating mode (1: switch, 2: multi-
1549static int __init dgrs_init_module (void) 1549static int __init dgrs_init_module (void)
1550{ 1550{
1551 int i; 1551 int i;
1552 int eisacount = 0, pcicount = 0; 1552 int cardcount = 0;
1553 1553
1554 /* 1554 /*
1555 * Command line variable overrides 1555 * Command line variable overrides
@@ -1591,15 +1591,13 @@ static int __init dgrs_init_module (void)
1591 * Find and configure all the cards 1591 * Find and configure all the cards
1592 */ 1592 */
1593#ifdef CONFIG_EISA 1593#ifdef CONFIG_EISA
1594 eisacount = eisa_driver_register(&dgrs_eisa_driver); 1594 cardcount = eisa_driver_register(&dgrs_eisa_driver);
1595 if (eisacount < 0) 1595 if (cardcount < 0)
1596 return eisacount; 1596 return cardcount;
1597#endif
1598#ifdef CONFIG_PCI
1599 pcicount = pci_register_driver(&dgrs_pci_driver);
1600 if (pcicount)
1601 return pcicount;
1602#endif 1597#endif
1598 cardcount = pci_register_driver(&dgrs_pci_driver);
1599 if (cardcount)
1600 return cardcount;
1603 return 0; 1601 return 0;
1604} 1602}
1605 1603
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index c0af6fb1fbba..f8c9bcdab68b 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -60,7 +60,6 @@
60#include <linux/etherdevice.h> 60#include <linux/etherdevice.h>
61#include <linux/init.h> 61#include <linux/init.h>
62#include <linux/skbuff.h> 62#include <linux/skbuff.h>
63#include <linux/version.h>
64#include <linux/spinlock.h> 63#include <linux/spinlock.h>
65#include <linux/crc32.h> 64#include <linux/crc32.h>
66#include <linux/mii.h> 65#include <linux/mii.h>
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index eb169a8e8773..7a6aeae2c9fa 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1478,7 +1478,7 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
1478 1478
1479 if(pci_dma_mapping_error(rx->dma_addr)) { 1479 if(pci_dma_mapping_error(rx->dma_addr)) {
1480 dev_kfree_skb_any(rx->skb); 1480 dev_kfree_skb_any(rx->skb);
1481 rx->skb = 0; 1481 rx->skb = NULL;
1482 rx->dma_addr = 0; 1482 rx->dma_addr = 0;
1483 return -ENOMEM; 1483 return -ENOMEM;
1484 } 1484 }
@@ -1764,7 +1764,7 @@ static int e100_up(struct nic *nic)
1764 if((err = e100_hw_init(nic))) 1764 if((err = e100_hw_init(nic)))
1765 goto err_clean_cbs; 1765 goto err_clean_cbs;
1766 e100_set_multicast_list(nic->netdev); 1766 e100_set_multicast_list(nic->netdev);
1767 e100_start_receiver(nic, 0); 1767 e100_start_receiver(nic, NULL);
1768 mod_timer(&nic->watchdog, jiffies); 1768 mod_timer(&nic->watchdog, jiffies);
1769 if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ, 1769 if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
1770 nic->netdev->name, nic->netdev))) 1770 nic->netdev->name, nic->netdev)))
@@ -1844,7 +1844,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
1844 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 1844 mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
1845 BMCR_LOOPBACK); 1845 BMCR_LOOPBACK);
1846 1846
1847 e100_start_receiver(nic, 0); 1847 e100_start_receiver(nic, NULL);
1848 1848
1849 if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) { 1849 if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
1850 err = -ENOMEM; 1850 err = -ENOMEM;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 9c7feaeaa6a4..8eae8ba27e84 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1739,7 +1739,7 @@ e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
1739 } 1739 }
1740} 1740}
1741 1741
1742struct ethtool_ops e1000_ethtool_ops = { 1742static struct ethtool_ops e1000_ethtool_ops = {
1743 .get_settings = e1000_get_settings, 1743 .get_settings = e1000_get_settings,
1744 .set_settings = e1000_set_settings, 1744 .set_settings = e1000_set_settings,
1745 .get_drvinfo = e1000_get_drvinfo, 1745 .get_drvinfo = e1000_get_drvinfo,
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 8fc876da43b4..a267c5235fc0 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -68,6 +68,38 @@ static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);
68static int32_t e1000_set_phy_mode(struct e1000_hw *hw); 68static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
69static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer); 69static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
70static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length); 70static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
71static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
72static int32_t e1000_check_downshift(struct e1000_hw *hw);
73static int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
74static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
75static void e1000_clear_vfta(struct e1000_hw *hw);
76static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
77static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw,
78 boolean_t link_up);
79static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
80static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
81static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
82static int32_t e1000_get_cable_length(struct e1000_hw *hw,
83 uint16_t *min_length,
84 uint16_t *max_length);
85static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
86static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
87static int32_t e1000_id_led_init(struct e1000_hw * hw);
88static void e1000_init_rx_addrs(struct e1000_hw *hw);
89static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
90static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
91static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
92static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset,
93 uint16_t words, uint16_t *data);
94static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
95static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
96static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
97
98static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset,
99 uint32_t value);
100
101#define E1000_WRITE_REG_IO(a, reg, val) \
102 e1000_write_reg_io((a), E1000_##reg, val)
71 103
72/* IGP cable length table */ 104/* IGP cable length table */
73static const 105static const
@@ -2035,7 +2067,7 @@ e1000_force_mac_fc(struct e1000_hw *hw)
2035 * based on the flow control negotiated by the PHY. In TBI mode, the TFCE 2067 * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
2036 * and RFCE bits will be automaticaly set to the negotiated flow control mode. 2068 * and RFCE bits will be automaticaly set to the negotiated flow control mode.
2037 *****************************************************************************/ 2069 *****************************************************************************/
2038int32_t 2070static int32_t
2039e1000_config_fc_after_link_up(struct e1000_hw *hw) 2071e1000_config_fc_after_link_up(struct e1000_hw *hw)
2040{ 2072{
2041 int32_t ret_val; 2073 int32_t ret_val;
@@ -2537,7 +2569,7 @@ e1000_get_speed_and_duplex(struct e1000_hw *hw,
2537* 2569*
2538* hw - Struct containing variables accessed by shared code 2570* hw - Struct containing variables accessed by shared code
2539******************************************************************************/ 2571******************************************************************************/
2540int32_t 2572static int32_t
2541e1000_wait_autoneg(struct e1000_hw *hw) 2573e1000_wait_autoneg(struct e1000_hw *hw)
2542{ 2574{
2543 int32_t ret_val; 2575 int32_t ret_val;
@@ -3021,7 +3053,7 @@ e1000_phy_reset(struct e1000_hw *hw)
3021* 3053*
3022* hw - Struct containing variables accessed by shared code 3054* hw - Struct containing variables accessed by shared code
3023******************************************************************************/ 3055******************************************************************************/
3024int32_t 3056static int32_t
3025e1000_detect_gig_phy(struct e1000_hw *hw) 3057e1000_detect_gig_phy(struct e1000_hw *hw)
3026{ 3058{
3027 int32_t phy_init_status, ret_val; 3059 int32_t phy_init_status, ret_val;
@@ -3121,7 +3153,7 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
3121* hw - Struct containing variables accessed by shared code 3153* hw - Struct containing variables accessed by shared code
3122* phy_info - PHY information structure 3154* phy_info - PHY information structure
3123******************************************************************************/ 3155******************************************************************************/
3124int32_t 3156static int32_t
3125e1000_phy_igp_get_info(struct e1000_hw *hw, 3157e1000_phy_igp_get_info(struct e1000_hw *hw,
3126 struct e1000_phy_info *phy_info) 3158 struct e1000_phy_info *phy_info)
3127{ 3159{
@@ -3195,7 +3227,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw,
3195* hw - Struct containing variables accessed by shared code 3227* hw - Struct containing variables accessed by shared code
3196* phy_info - PHY information structure 3228* phy_info - PHY information structure
3197******************************************************************************/ 3229******************************************************************************/
3198int32_t 3230static int32_t
3199e1000_phy_m88_get_info(struct e1000_hw *hw, 3231e1000_phy_m88_get_info(struct e1000_hw *hw,
3200 struct e1000_phy_info *phy_info) 3232 struct e1000_phy_info *phy_info)
3201{ 3233{
@@ -3905,7 +3937,7 @@ e1000_read_eeprom(struct e1000_hw *hw,
3905 * data - word read from the EEPROM 3937 * data - word read from the EEPROM
3906 * words - number of words to read 3938 * words - number of words to read
3907 *****************************************************************************/ 3939 *****************************************************************************/
3908int32_t 3940static int32_t
3909e1000_read_eeprom_eerd(struct e1000_hw *hw, 3941e1000_read_eeprom_eerd(struct e1000_hw *hw,
3910 uint16_t offset, 3942 uint16_t offset,
3911 uint16_t words, 3943 uint16_t words,
@@ -3939,7 +3971,7 @@ e1000_read_eeprom_eerd(struct e1000_hw *hw,
3939 * data - word read from the EEPROM 3971 * data - word read from the EEPROM
3940 * words - number of words to read 3972 * words - number of words to read
3941 *****************************************************************************/ 3973 *****************************************************************************/
3942int32_t 3974static int32_t
3943e1000_write_eeprom_eewr(struct e1000_hw *hw, 3975e1000_write_eeprom_eewr(struct e1000_hw *hw,
3944 uint16_t offset, 3976 uint16_t offset,
3945 uint16_t words, 3977 uint16_t words,
@@ -3976,7 +4008,7 @@ e1000_write_eeprom_eewr(struct e1000_hw *hw,
3976 * 4008 *
3977 * hw - Struct containing variables accessed by shared code 4009 * hw - Struct containing variables accessed by shared code
3978 *****************************************************************************/ 4010 *****************************************************************************/
3979int32_t 4011static int32_t
3980e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd) 4012e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
3981{ 4013{
3982 uint32_t attempts = 100000; 4014 uint32_t attempts = 100000;
@@ -4004,7 +4036,7 @@ e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
4004* 4036*
4005* hw - Struct containing variables accessed by shared code 4037* hw - Struct containing variables accessed by shared code
4006****************************************************************************/ 4038****************************************************************************/
4007boolean_t 4039static boolean_t
4008e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw) 4040e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
4009{ 4041{
4010 uint32_t eecd = 0; 4042 uint32_t eecd = 0;
@@ -4322,7 +4354,7 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw,
4322 * data - word read from the EEPROM 4354 * data - word read from the EEPROM
4323 * words - number of words to read 4355 * words - number of words to read
4324 *****************************************************************************/ 4356 *****************************************************************************/
4325int32_t 4357static int32_t
4326e1000_commit_shadow_ram(struct e1000_hw *hw) 4358e1000_commit_shadow_ram(struct e1000_hw *hw)
4327{ 4359{
4328 uint32_t attempts = 100000; 4360 uint32_t attempts = 100000;
@@ -4453,7 +4485,7 @@ e1000_read_mac_addr(struct e1000_hw * hw)
4453 * of the receive addresss registers. Clears the multicast table. Assumes 4485 * of the receive addresss registers. Clears the multicast table. Assumes
4454 * the receiver is in reset when the routine is called. 4486 * the receiver is in reset when the routine is called.
4455 *****************************************************************************/ 4487 *****************************************************************************/
4456void 4488static void
4457e1000_init_rx_addrs(struct e1000_hw *hw) 4489e1000_init_rx_addrs(struct e1000_hw *hw)
4458{ 4490{
4459 uint32_t i; 4491 uint32_t i;
@@ -4481,6 +4513,7 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
4481 } 4513 }
4482} 4514}
4483 4515
4516#if 0
4484/****************************************************************************** 4517/******************************************************************************
4485 * Updates the MAC's list of multicast addresses. 4518 * Updates the MAC's list of multicast addresses.
4486 * 4519 *
@@ -4564,6 +4597,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw,
4564 } 4597 }
4565 DEBUGOUT("MC Update Complete\n"); 4598 DEBUGOUT("MC Update Complete\n");
4566} 4599}
4600#endif /* 0 */
4567 4601
4568/****************************************************************************** 4602/******************************************************************************
4569 * Hashes an address to determine its location in the multicast table 4603 * Hashes an address to determine its location in the multicast table
@@ -4705,7 +4739,7 @@ e1000_write_vfta(struct e1000_hw *hw,
4705 * 4739 *
4706 * hw - Struct containing variables accessed by shared code 4740 * hw - Struct containing variables accessed by shared code
4707 *****************************************************************************/ 4741 *****************************************************************************/
4708void 4742static void
4709e1000_clear_vfta(struct e1000_hw *hw) 4743e1000_clear_vfta(struct e1000_hw *hw)
4710{ 4744{
4711 uint32_t offset; 4745 uint32_t offset;
@@ -4735,7 +4769,7 @@ e1000_clear_vfta(struct e1000_hw *hw)
4735 } 4769 }
4736} 4770}
4737 4771
4738int32_t 4772static int32_t
4739e1000_id_led_init(struct e1000_hw * hw) 4773e1000_id_led_init(struct e1000_hw * hw)
4740{ 4774{
4741 uint32_t ledctl; 4775 uint32_t ledctl;
@@ -4997,7 +5031,7 @@ e1000_led_off(struct e1000_hw *hw)
4997 * 5031 *
4998 * hw - Struct containing variables accessed by shared code 5032 * hw - Struct containing variables accessed by shared code
4999 *****************************************************************************/ 5033 *****************************************************************************/
5000void 5034static void
5001e1000_clear_hw_cntrs(struct e1000_hw *hw) 5035e1000_clear_hw_cntrs(struct e1000_hw *hw)
5002{ 5036{
5003 volatile uint32_t temp; 5037 volatile uint32_t temp;
@@ -5283,6 +5317,8 @@ e1000_get_bus_info(struct e1000_hw *hw)
5283 break; 5317 break;
5284 } 5318 }
5285} 5319}
5320
5321#if 0
5286/****************************************************************************** 5322/******************************************************************************
5287 * Reads a value from one of the devices registers using port I/O (as opposed 5323 * Reads a value from one of the devices registers using port I/O (as opposed
5288 * memory mapped I/O). Only 82544 and newer devices support port I/O. 5324 * memory mapped I/O). Only 82544 and newer devices support port I/O.
@@ -5300,6 +5336,7 @@ e1000_read_reg_io(struct e1000_hw *hw,
5300 e1000_io_write(hw, io_addr, offset); 5336 e1000_io_write(hw, io_addr, offset);
5301 return e1000_io_read(hw, io_data); 5337 return e1000_io_read(hw, io_data);
5302} 5338}
5339#endif /* 0 */
5303 5340
5304/****************************************************************************** 5341/******************************************************************************
5305 * Writes a value to one of the devices registers using port I/O (as opposed to 5342 * Writes a value to one of the devices registers using port I/O (as opposed to
@@ -5309,7 +5346,7 @@ e1000_read_reg_io(struct e1000_hw *hw,
5309 * offset - offset to write to 5346 * offset - offset to write to
5310 * value - value to write 5347 * value - value to write
5311 *****************************************************************************/ 5348 *****************************************************************************/
5312void 5349static void
5313e1000_write_reg_io(struct e1000_hw *hw, 5350e1000_write_reg_io(struct e1000_hw *hw,
5314 uint32_t offset, 5351 uint32_t offset,
5315 uint32_t value) 5352 uint32_t value)
@@ -5337,7 +5374,7 @@ e1000_write_reg_io(struct e1000_hw *hw,
5337 * register to the minimum and maximum range. 5374 * register to the minimum and maximum range.
5338 * For IGP phy's, the function calculates the range by the AGC registers. 5375 * For IGP phy's, the function calculates the range by the AGC registers.
5339 *****************************************************************************/ 5376 *****************************************************************************/
5340int32_t 5377static int32_t
5341e1000_get_cable_length(struct e1000_hw *hw, 5378e1000_get_cable_length(struct e1000_hw *hw,
5342 uint16_t *min_length, 5379 uint16_t *min_length,
5343 uint16_t *max_length) 5380 uint16_t *max_length)
@@ -5489,7 +5526,7 @@ e1000_get_cable_length(struct e1000_hw *hw,
5489 * return 0. If the link speed is 1000 Mbps the polarity status is in the 5526 * return 0. If the link speed is 1000 Mbps the polarity status is in the
5490 * IGP01E1000_PHY_PCS_INIT_REG. 5527 * IGP01E1000_PHY_PCS_INIT_REG.
5491 *****************************************************************************/ 5528 *****************************************************************************/
5492int32_t 5529static int32_t
5493e1000_check_polarity(struct e1000_hw *hw, 5530e1000_check_polarity(struct e1000_hw *hw,
5494 uint16_t *polarity) 5531 uint16_t *polarity)
5495{ 5532{
@@ -5551,7 +5588,7 @@ e1000_check_polarity(struct e1000_hw *hw,
5551 * Link Health register. In IGP this bit is latched high, so the driver must 5588 * Link Health register. In IGP this bit is latched high, so the driver must
5552 * read it immediately after link is established. 5589 * read it immediately after link is established.
5553 *****************************************************************************/ 5590 *****************************************************************************/
5554int32_t 5591static int32_t
5555e1000_check_downshift(struct e1000_hw *hw) 5592e1000_check_downshift(struct e1000_hw *hw)
5556{ 5593{
5557 int32_t ret_val; 5594 int32_t ret_val;
@@ -5592,7 +5629,7 @@ e1000_check_downshift(struct e1000_hw *hw)
5592 * 5629 *
5593 ****************************************************************************/ 5630 ****************************************************************************/
5594 5631
5595int32_t 5632static int32_t
5596e1000_config_dsp_after_link_change(struct e1000_hw *hw, 5633e1000_config_dsp_after_link_change(struct e1000_hw *hw,
5597 boolean_t link_up) 5634 boolean_t link_up)
5598{ 5635{
@@ -5823,7 +5860,7 @@ e1000_set_phy_mode(struct e1000_hw *hw)
5823 * 5860 *
5824 ****************************************************************************/ 5861 ****************************************************************************/
5825 5862
5826int32_t 5863static int32_t
5827e1000_set_d3_lplu_state(struct e1000_hw *hw, 5864e1000_set_d3_lplu_state(struct e1000_hw *hw,
5828 boolean_t active) 5865 boolean_t active)
5829{ 5866{
@@ -5936,7 +5973,7 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw,
5936 * 5973 *
5937 ****************************************************************************/ 5974 ****************************************************************************/
5938 5975
5939int32_t 5976static int32_t
5940e1000_set_d0_lplu_state(struct e1000_hw *hw, 5977e1000_set_d0_lplu_state(struct e1000_hw *hw,
5941 boolean_t active) 5978 boolean_t active)
5942{ 5979{
@@ -6103,7 +6140,7 @@ e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer)
6103 * timeout 6140 * timeout
6104 * - E1000_SUCCESS for success. 6141 * - E1000_SUCCESS for success.
6105 ****************************************************************************/ 6142 ****************************************************************************/
6106int32_t 6143static int32_t
6107e1000_mng_enable_host_if(struct e1000_hw * hw) 6144e1000_mng_enable_host_if(struct e1000_hw * hw)
6108{ 6145{
6109 uint32_t hicr; 6146 uint32_t hicr;
@@ -6137,7 +6174,7 @@ e1000_mng_enable_host_if(struct e1000_hw * hw)
6137 * 6174 *
6138 * returns - E1000_SUCCESS for success. 6175 * returns - E1000_SUCCESS for success.
6139 ****************************************************************************/ 6176 ****************************************************************************/
6140int32_t 6177static int32_t
6141e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer, 6178e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer,
6142 uint16_t length, uint16_t offset, uint8_t *sum) 6179 uint16_t length, uint16_t offset, uint8_t *sum)
6143{ 6180{
@@ -6205,7 +6242,7 @@ e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer,
6205 * 6242 *
6206 * returns - E1000_SUCCESS for success. 6243 * returns - E1000_SUCCESS for success.
6207 ****************************************************************************/ 6244 ****************************************************************************/
6208int32_t 6245static int32_t
6209e1000_mng_write_cmd_header(struct e1000_hw * hw, 6246e1000_mng_write_cmd_header(struct e1000_hw * hw,
6210 struct e1000_host_mng_command_header * hdr) 6247 struct e1000_host_mng_command_header * hdr)
6211{ 6248{
@@ -6243,7 +6280,7 @@ e1000_mng_write_cmd_header(struct e1000_hw * hw,
6243 * 6280 *
6244 * returns - E1000_SUCCESS for success. 6281 * returns - E1000_SUCCESS for success.
6245 ****************************************************************************/ 6282 ****************************************************************************/
6246int32_t 6283static int32_t
6247e1000_mng_write_commit( 6284e1000_mng_write_commit(
6248 struct e1000_hw * hw) 6285 struct e1000_hw * hw)
6249{ 6286{
@@ -6496,7 +6533,7 @@ e1000_polarity_reversal_workaround(struct e1000_hw *hw)
6496 * returns: - none. 6533 * returns: - none.
6497 * 6534 *
6498 ***************************************************************************/ 6535 ***************************************************************************/
6499void 6536static void
6500e1000_set_pci_express_master_disable(struct e1000_hw *hw) 6537e1000_set_pci_express_master_disable(struct e1000_hw *hw)
6501{ 6538{
6502 uint32_t ctrl; 6539 uint32_t ctrl;
@@ -6511,6 +6548,7 @@ e1000_set_pci_express_master_disable(struct e1000_hw *hw)
6511 E1000_WRITE_REG(hw, CTRL, ctrl); 6548 E1000_WRITE_REG(hw, CTRL, ctrl);
6512} 6549}
6513 6550
6551#if 0
6514/*************************************************************************** 6552/***************************************************************************
6515 * 6553 *
6516 * Enables PCI-Express master access. 6554 * Enables PCI-Express master access.
@@ -6534,6 +6572,7 @@ e1000_enable_pciex_master(struct e1000_hw *hw)
6534 ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE; 6572 ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
6535 E1000_WRITE_REG(hw, CTRL, ctrl); 6573 E1000_WRITE_REG(hw, CTRL, ctrl);
6536} 6574}
6575#endif /* 0 */
6537 6576
6538/******************************************************************************* 6577/*******************************************************************************
6539 * 6578 *
@@ -6584,7 +6623,7 @@ e1000_disable_pciex_master(struct e1000_hw *hw)
6584 * E1000_SUCCESS at any other case. 6623 * E1000_SUCCESS at any other case.
6585 * 6624 *
6586 ******************************************************************************/ 6625 ******************************************************************************/
6587int32_t 6626static int32_t
6588e1000_get_auto_rd_done(struct e1000_hw *hw) 6627e1000_get_auto_rd_done(struct e1000_hw *hw)
6589{ 6628{
6590 int32_t timeout = AUTO_READ_DONE_TIMEOUT; 6629 int32_t timeout = AUTO_READ_DONE_TIMEOUT;
@@ -6623,7 +6662,7 @@ e1000_get_auto_rd_done(struct e1000_hw *hw)
6623 * E1000_SUCCESS at any other case. 6662 * E1000_SUCCESS at any other case.
6624 * 6663 *
6625 ***************************************************************************/ 6664 ***************************************************************************/
6626int32_t 6665static int32_t
6627e1000_get_phy_cfg_done(struct e1000_hw *hw) 6666e1000_get_phy_cfg_done(struct e1000_hw *hw)
6628{ 6667{
6629 int32_t timeout = PHY_CFG_TIMEOUT; 6668 int32_t timeout = PHY_CFG_TIMEOUT;
@@ -6666,7 +6705,7 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw)
6666 * E1000_SUCCESS at any other case. 6705 * E1000_SUCCESS at any other case.
6667 * 6706 *
6668 ***************************************************************************/ 6707 ***************************************************************************/
6669int32_t 6708static int32_t
6670e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) 6709e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
6671{ 6710{
6672 int32_t timeout; 6711 int32_t timeout;
@@ -6711,7 +6750,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
6711 * returns: - None. 6750 * returns: - None.
6712 * 6751 *
6713 ***************************************************************************/ 6752 ***************************************************************************/
6714void 6753static void
6715e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) 6754e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
6716{ 6755{
6717 uint32_t swsm; 6756 uint32_t swsm;
@@ -6747,7 +6786,7 @@ e1000_check_phy_reset_block(struct e1000_hw *hw)
6747 E1000_BLK_PHY_RESET : E1000_SUCCESS; 6786 E1000_BLK_PHY_RESET : E1000_SUCCESS;
6748} 6787}
6749 6788
6750uint8_t 6789static uint8_t
6751e1000_arc_subsystem_valid(struct e1000_hw *hw) 6790e1000_arc_subsystem_valid(struct e1000_hw *hw)
6752{ 6791{
6753 uint32_t fwsm; 6792 uint32_t fwsm;
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 4f2c196dc314..76ce12809a11 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -284,7 +284,6 @@ typedef enum {
284/* Initialization */ 284/* Initialization */
285int32_t e1000_reset_hw(struct e1000_hw *hw); 285int32_t e1000_reset_hw(struct e1000_hw *hw);
286int32_t e1000_init_hw(struct e1000_hw *hw); 286int32_t e1000_init_hw(struct e1000_hw *hw);
287int32_t e1000_id_led_init(struct e1000_hw * hw);
288int32_t e1000_set_mac_type(struct e1000_hw *hw); 287int32_t e1000_set_mac_type(struct e1000_hw *hw);
289void e1000_set_media_type(struct e1000_hw *hw); 288void e1000_set_media_type(struct e1000_hw *hw);
290 289
@@ -292,10 +291,8 @@ void e1000_set_media_type(struct e1000_hw *hw);
292int32_t e1000_setup_link(struct e1000_hw *hw); 291int32_t e1000_setup_link(struct e1000_hw *hw);
293int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw); 292int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw);
294void e1000_config_collision_dist(struct e1000_hw *hw); 293void e1000_config_collision_dist(struct e1000_hw *hw);
295int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
296int32_t e1000_check_for_link(struct e1000_hw *hw); 294int32_t e1000_check_for_link(struct e1000_hw *hw);
297int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex); 295int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
298int32_t e1000_wait_autoneg(struct e1000_hw *hw);
299int32_t e1000_force_mac_fc(struct e1000_hw *hw); 296int32_t e1000_force_mac_fc(struct e1000_hw *hw);
300 297
301/* PHY */ 298/* PHY */
@@ -303,21 +300,11 @@ int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy
303int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data); 300int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
304int32_t e1000_phy_hw_reset(struct e1000_hw *hw); 301int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
305int32_t e1000_phy_reset(struct e1000_hw *hw); 302int32_t e1000_phy_reset(struct e1000_hw *hw);
306int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
307int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info); 303int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
308int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
309int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
310int32_t e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, uint16_t *max_length);
311int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
312int32_t e1000_check_downshift(struct e1000_hw *hw);
313int32_t e1000_validate_mdi_setting(struct e1000_hw *hw); 304int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
314 305
315/* EEPROM Functions */ 306/* EEPROM Functions */
316int32_t e1000_init_eeprom_params(struct e1000_hw *hw); 307int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
317boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
318int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
319int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
320int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
321 308
322/* MNG HOST IF functions */ 309/* MNG HOST IF functions */
323uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw); 310uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
@@ -377,13 +364,6 @@ int32_t e1000_mng_write_dhcp_info(struct e1000_hw *hw, uint8_t *buffer,
377 uint16_t length); 364 uint16_t length);
378boolean_t e1000_check_mng_mode(struct e1000_hw *hw); 365boolean_t e1000_check_mng_mode(struct e1000_hw *hw);
379boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw); 366boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
380int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
381int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer,
382 uint16_t length, uint16_t offset, uint8_t *sum);
383int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw,
384 struct e1000_host_mng_command_header* hdr);
385
386int32_t e1000_mng_write_commit(struct e1000_hw *hw);
387 367
388int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data); 368int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
389int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw); 369int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
@@ -395,13 +375,10 @@ int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
395void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask); 375void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
396 376
397/* Filters (multicast, vlan, receive) */ 377/* Filters (multicast, vlan, receive) */
398void e1000_init_rx_addrs(struct e1000_hw *hw);
399void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad, uint32_t rar_used_count);
400uint32_t e1000_hash_mc_addr(struct e1000_hw *hw, uint8_t * mc_addr); 378uint32_t e1000_hash_mc_addr(struct e1000_hw *hw, uint8_t * mc_addr);
401void e1000_mta_set(struct e1000_hw *hw, uint32_t hash_value); 379void e1000_mta_set(struct e1000_hw *hw, uint32_t hash_value);
402void e1000_rar_set(struct e1000_hw *hw, uint8_t * mc_addr, uint32_t rar_index); 380void e1000_rar_set(struct e1000_hw *hw, uint8_t * mc_addr, uint32_t rar_index);
403void e1000_write_vfta(struct e1000_hw *hw, uint32_t offset, uint32_t value); 381void e1000_write_vfta(struct e1000_hw *hw, uint32_t offset, uint32_t value);
404void e1000_clear_vfta(struct e1000_hw *hw);
405 382
406/* LED functions */ 383/* LED functions */
407int32_t e1000_setup_led(struct e1000_hw *hw); 384int32_t e1000_setup_led(struct e1000_hw *hw);
@@ -412,7 +389,6 @@ int32_t e1000_led_off(struct e1000_hw *hw);
412/* Adaptive IFS Functions */ 389/* Adaptive IFS Functions */
413 390
414/* Everything else */ 391/* Everything else */
415void e1000_clear_hw_cntrs(struct e1000_hw *hw);
416void e1000_reset_adaptive(struct e1000_hw *hw); 392void e1000_reset_adaptive(struct e1000_hw *hw);
417void e1000_update_adaptive(struct e1000_hw *hw); 393void e1000_update_adaptive(struct e1000_hw *hw);
418void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, uint32_t frame_len, uint8_t * mac_addr); 394void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, uint32_t frame_len, uint8_t * mac_addr);
@@ -423,29 +399,11 @@ void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
423void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value); 399void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
424/* Port I/O is only supported on 82544 and newer */ 400/* Port I/O is only supported on 82544 and newer */
425uint32_t e1000_io_read(struct e1000_hw *hw, unsigned long port); 401uint32_t e1000_io_read(struct e1000_hw *hw, unsigned long port);
426uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
427void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value); 402void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
428void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
429int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
430int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
431int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
432void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
433void e1000_enable_pciex_master(struct e1000_hw *hw);
434int32_t e1000_disable_pciex_master(struct e1000_hw *hw); 403int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
435int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
436int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
437int32_t e1000_get_software_semaphore(struct e1000_hw *hw); 404int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
438void e1000_release_software_semaphore(struct e1000_hw *hw); 405void e1000_release_software_semaphore(struct e1000_hw *hw);
439int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); 406int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
440int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
441void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
442int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
443uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
444
445#define E1000_READ_REG_IO(a, reg) \
446 e1000_read_reg_io((a), E1000_##reg)
447#define E1000_WRITE_REG_IO(a, reg, val) \
448 e1000_write_reg_io((a), E1000_##reg, val)
449 407
450/* PCI Device IDs */ 408/* PCI Device IDs */
451#define E1000_DEV_ID_82542 0x1000 409#define E1000_DEV_ID_82542 0x1000
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index efbbda7cbcbf..8b207f0e139e 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -37,7 +37,7 @@
37 */ 37 */
38 38
39char e1000_driver_name[] = "e1000"; 39char e1000_driver_name[] = "e1000";
40char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; 40static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
41#ifndef CONFIG_E1000_NAPI 41#ifndef CONFIG_E1000_NAPI
42#define DRIVERNAPI 42#define DRIVERNAPI
43#else 43#else
@@ -45,7 +45,7 @@ char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
45#endif 45#endif
46#define DRV_VERSION "6.1.16-k2"DRIVERNAPI 46#define DRV_VERSION "6.1.16-k2"DRIVERNAPI
47char e1000_driver_version[] = DRV_VERSION; 47char e1000_driver_version[] = DRV_VERSION;
48char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; 48static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
49 49
50/* e1000_pci_tbl - PCI Device ID Table 50/* e1000_pci_tbl - PCI Device ID Table
51 * 51 *
@@ -112,14 +112,14 @@ int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
112int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); 112int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
113void e1000_free_all_tx_resources(struct e1000_adapter *adapter); 113void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
114void e1000_free_all_rx_resources(struct e1000_adapter *adapter); 114void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
115int e1000_setup_tx_resources(struct e1000_adapter *adapter, 115static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
116 struct e1000_tx_ring *txdr); 116 struct e1000_tx_ring *txdr);
117int e1000_setup_rx_resources(struct e1000_adapter *adapter, 117static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
118 struct e1000_rx_ring *rxdr); 118 struct e1000_rx_ring *rxdr);
119void e1000_free_tx_resources(struct e1000_adapter *adapter, 119static void e1000_free_tx_resources(struct e1000_adapter *adapter,
120 struct e1000_tx_ring *tx_ring); 120 struct e1000_tx_ring *tx_ring);
121void e1000_free_rx_resources(struct e1000_adapter *adapter, 121static void e1000_free_rx_resources(struct e1000_adapter *adapter,
122 struct e1000_rx_ring *rx_ring); 122 struct e1000_rx_ring *rx_ring);
123void e1000_update_stats(struct e1000_adapter *adapter); 123void e1000_update_stats(struct e1000_adapter *adapter);
124 124
125/* Local Function Prototypes */ 125/* Local Function Prototypes */
@@ -296,7 +296,8 @@ e1000_irq_enable(struct e1000_adapter *adapter)
296 E1000_WRITE_FLUSH(&adapter->hw); 296 E1000_WRITE_FLUSH(&adapter->hw);
297 } 297 }
298} 298}
299void 299
300static void
300e1000_update_mng_vlan(struct e1000_adapter *adapter) 301e1000_update_mng_vlan(struct e1000_adapter *adapter)
301{ 302{
302 struct net_device *netdev = adapter->netdev; 303 struct net_device *netdev = adapter->netdev;
@@ -1141,7 +1142,7 @@ e1000_check_64k_bound(struct e1000_adapter *adapter,
1141 * Return 0 on success, negative on failure 1142 * Return 0 on success, negative on failure
1142 **/ 1143 **/
1143 1144
1144int 1145static int
1145e1000_setup_tx_resources(struct e1000_adapter *adapter, 1146e1000_setup_tx_resources(struct e1000_adapter *adapter,
1146 struct e1000_tx_ring *txdr) 1147 struct e1000_tx_ring *txdr)
1147{ 1148{
@@ -1359,7 +1360,7 @@ e1000_configure_tx(struct e1000_adapter *adapter)
1359 * Returns 0 on success, negative on failure 1360 * Returns 0 on success, negative on failure
1360 **/ 1361 **/
1361 1362
1362int 1363static int
1363e1000_setup_rx_resources(struct e1000_adapter *adapter, 1364e1000_setup_rx_resources(struct e1000_adapter *adapter,
1364 struct e1000_rx_ring *rxdr) 1365 struct e1000_rx_ring *rxdr)
1365{ 1366{
@@ -1747,7 +1748,7 @@ e1000_configure_rx(struct e1000_adapter *adapter)
1747 * Free all transmit software resources 1748 * Free all transmit software resources
1748 **/ 1749 **/
1749 1750
1750void 1751static void
1751e1000_free_tx_resources(struct e1000_adapter *adapter, 1752e1000_free_tx_resources(struct e1000_adapter *adapter,
1752 struct e1000_tx_ring *tx_ring) 1753 struct e1000_tx_ring *tx_ring)
1753{ 1754{
@@ -1858,7 +1859,7 @@ e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
1858 * Free all receive software resources 1859 * Free all receive software resources
1859 **/ 1860 **/
1860 1861
1861void 1862static void
1862e1000_free_rx_resources(struct e1000_adapter *adapter, 1863e1000_free_rx_resources(struct e1000_adapter *adapter,
1863 struct e1000_rx_ring *rx_ring) 1864 struct e1000_rx_ring *rx_ring)
1864{ 1865{
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 85504fb900da..bd6983d1afba 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -18,8 +18,8 @@
18 * Much better multiple PHY support by Magnus Damm. 18 * Much better multiple PHY support by Magnus Damm.
19 * Copyright (c) 2000 Ericsson Radio Systems AB. 19 * Copyright (c) 2000 Ericsson Radio Systems AB.
20 * 20 *
21 * Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282. 21 * Support for FEC controller of ColdFire processors.
22 * Copyright (c) 2001-2004 Greg Ungerer (gerg@snapgear.com) 22 * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com)
23 * 23 *
24 * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) 24 * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
25 * Copyright (c) 2004-2005 Macq Electronique SA. 25 * Copyright (c) 2004-2005 Macq Electronique SA.
@@ -50,7 +50,8 @@
50#include <asm/pgtable.h> 50#include <asm/pgtable.h>
51 51
52#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ 52#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
53 defined(CONFIG_M5272) || defined(CONFIG_M528x) 53 defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
54 defined(CONFIG_M520x)
54#include <asm/coldfire.h> 55#include <asm/coldfire.h>
55#include <asm/mcfsim.h> 56#include <asm/mcfsim.h>
56#include "fec.h" 57#include "fec.h"
@@ -77,6 +78,8 @@ static unsigned int fec_hw[] = {
77 (MCF_MBAR + 0x1800), 78 (MCF_MBAR + 0x1800),
78#elif defined(CONFIG_M523x) || defined(CONFIG_M528x) 79#elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
79 (MCF_MBAR + 0x1000), 80 (MCF_MBAR + 0x1000),
81#elif defined(CONFIG_M520x)
82 (MCF_MBAR+0x30000),
80#else 83#else
81 &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), 84 &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
82#endif 85#endif
@@ -139,6 +142,10 @@ typedef struct {
139#define TX_RING_SIZE 16 /* Must be power of two */ 142#define TX_RING_SIZE 16 /* Must be power of two */
140#define TX_RING_MOD_MASK 15 /* for this to work */ 143#define TX_RING_MOD_MASK 15 /* for this to work */
141 144
145#if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE)
146#error "FEC: descriptor ring size contants too large"
147#endif
148
142/* Interrupt events/masks. 149/* Interrupt events/masks.
143*/ 150*/
144#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */ 151#define FEC_ENET_HBERR ((uint)0x80000000) /* Heartbeat error */
@@ -164,7 +171,8 @@ typedef struct {
164 * size bits. Other FEC hardware does not, so we need to take that into 171 * size bits. Other FEC hardware does not, so we need to take that into
165 * account when setting it. 172 * account when setting it.
166 */ 173 */
167#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) 174#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
175 defined(CONFIG_M520x)
168#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) 176#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
169#else 177#else
170#define OPT_FRAME_SIZE 0 178#define OPT_FRAME_SIZE 0
@@ -1137,6 +1145,65 @@ static phy_info_t const phy_info_ks8721bl = {
1137}; 1145};
1138 1146
1139/* ------------------------------------------------------------------------- */ 1147/* ------------------------------------------------------------------------- */
1148/* register definitions for the DP83848 */
1149
1150#define MII_DP8384X_PHYSTST 16 /* PHY Status Register */
1151
1152static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev)
1153{
1154 struct fec_enet_private *fep = dev->priv;
1155 volatile uint *s = &(fep->phy_status);
1156
1157 *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
1158
1159 /* Link up */
1160 if (mii_reg & 0x0001) {
1161 fep->link = 1;
1162 *s |= PHY_STAT_LINK;
1163 } else
1164 fep->link = 0;
1165 /* Status of link */
1166 if (mii_reg & 0x0010) /* Autonegotioation complete */
1167 *s |= PHY_STAT_ANC;
1168 if (mii_reg & 0x0002) { /* 10MBps? */
1169 if (mii_reg & 0x0004) /* Full Duplex? */
1170 *s |= PHY_STAT_10FDX;
1171 else
1172 *s |= PHY_STAT_10HDX;
1173 } else { /* 100 Mbps? */
1174 if (mii_reg & 0x0004) /* Full Duplex? */
1175 *s |= PHY_STAT_100FDX;
1176 else
1177 *s |= PHY_STAT_100HDX;
1178 }
1179 if (mii_reg & 0x0008)
1180 *s |= PHY_STAT_FAULT;
1181}
1182
1183static phy_info_t phy_info_dp83848= {
1184 0x020005c9,
1185 "DP83848",
1186
1187 (const phy_cmd_t []) { /* config */
1188 { mk_mii_read(MII_REG_CR), mii_parse_cr },
1189 { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
1190 { mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
1191 { mk_mii_end, }
1192 },
1193 (const phy_cmd_t []) { /* startup - enable interrupts */
1194 { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
1195 { mk_mii_read(MII_REG_SR), mii_parse_sr },
1196 { mk_mii_end, }
1197 },
1198 (const phy_cmd_t []) { /* ack_int - never happens, no interrupt */
1199 { mk_mii_end, }
1200 },
1201 (const phy_cmd_t []) { /* shutdown */
1202 { mk_mii_end, }
1203 },
1204};
1205
1206/* ------------------------------------------------------------------------- */
1140 1207
1141static phy_info_t const * const phy_info[] = { 1208static phy_info_t const * const phy_info[] = {
1142 &phy_info_lxt970, 1209 &phy_info_lxt970,
@@ -1144,6 +1211,7 @@ static phy_info_t const * const phy_info[] = {
1144 &phy_info_qs6612, 1211 &phy_info_qs6612,
1145 &phy_info_am79c874, 1212 &phy_info_am79c874,
1146 &phy_info_ks8721bl, 1213 &phy_info_ks8721bl,
1214 &phy_info_dp83848,
1147 NULL 1215 NULL
1148}; 1216};
1149 1217
@@ -1422,6 +1490,134 @@ static void __inline__ fec_uncache(unsigned long addr)
1422 1490
1423/* ------------------------------------------------------------------------- */ 1491/* ------------------------------------------------------------------------- */
1424 1492
1493#elif defined(CONFIG_M520x)
1494
1495/*
1496 * Code specific to Coldfire 520x
1497 */
1498static void __inline__ fec_request_intrs(struct net_device *dev)
1499{
1500 struct fec_enet_private *fep;
1501 int b;
1502 static const struct idesc {
1503 char *name;
1504 unsigned short irq;
1505 } *idp, id[] = {
1506 { "fec(TXF)", 23 },
1507 { "fec(TXB)", 24 },
1508 { "fec(TXFIFO)", 25 },
1509 { "fec(TXCR)", 26 },
1510 { "fec(RXF)", 27 },
1511 { "fec(RXB)", 28 },
1512 { "fec(MII)", 29 },
1513 { "fec(LC)", 30 },
1514 { "fec(HBERR)", 31 },
1515 { "fec(GRA)", 32 },
1516 { "fec(EBERR)", 33 },
1517 { "fec(BABT)", 34 },
1518 { "fec(BABR)", 35 },
1519 { NULL },
1520 };
1521
1522 fep = netdev_priv(dev);
1523 b = 64 + 13;
1524
1525 /* Setup interrupt handlers. */
1526 for (idp = id; idp->name; idp++) {
1527 if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0)
1528 printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
1529 }
1530
1531 /* Unmask interrupts at ColdFire interrupt controller */
1532 {
1533 volatile unsigned char *icrp;
1534 volatile unsigned long *imrp;
1535
1536 icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
1537 MCFINTC_ICR0);
1538 for (b = 36; (b < 49); b++)
1539 icrp[b] = 0x04;
1540 imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 +
1541 MCFINTC_IMRH);
1542 *imrp &= ~0x0001FFF0;
1543 }
1544 *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0;
1545 *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f;
1546}
1547
1548static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
1549{
1550 volatile fec_t *fecp;
1551
1552 fecp = fep->hwp;
1553 fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
1554 fecp->fec_x_cntrl = 0x00;
1555
1556 /*
1557 * Set MII speed to 2.5 MHz
1558 * See 5282 manual section 17.5.4.7: MSCR
1559 */
1560 fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
1561 fecp->fec_mii_speed = fep->phy_speed;
1562
1563 fec_restart(dev, 0);
1564}
1565
1566static void __inline__ fec_get_mac(struct net_device *dev)
1567{
1568 struct fec_enet_private *fep = netdev_priv(dev);
1569 volatile fec_t *fecp;
1570 unsigned char *iap, tmpaddr[ETH_ALEN];
1571
1572 fecp = fep->hwp;
1573
1574 if (FEC_FLASHMAC) {
1575 /*
1576 * Get MAC address from FLASH.
1577 * If it is all 1's or 0's, use the default.
1578 */
1579 iap = FEC_FLASHMAC;
1580 if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
1581 (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
1582 iap = fec_mac_default;
1583 if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
1584 (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
1585 iap = fec_mac_default;
1586 } else {
1587 *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
1588 *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
1589 iap = &tmpaddr[0];
1590 }
1591
1592 memcpy(dev->dev_addr, iap, ETH_ALEN);
1593
1594 /* Adjust MAC if using default MAC address */
1595 if (iap == fec_mac_default)
1596 dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
1597}
1598
1599static void __inline__ fec_enable_phy_intr(void)
1600{
1601}
1602
1603static void __inline__ fec_disable_phy_intr(void)
1604{
1605}
1606
1607static void __inline__ fec_phy_ack_intr(void)
1608{
1609}
1610
1611static void __inline__ fec_localhw_setup(void)
1612{
1613}
1614
1615static void __inline__ fec_uncache(unsigned long addr)
1616{
1617}
1618
1619/* ------------------------------------------------------------------------- */
1620
1425#else 1621#else
1426 1622
1427/* 1623/*
@@ -1952,6 +2148,14 @@ int __init fec_enet_init(struct net_device *dev)
1952 if (index >= FEC_MAX_PORTS) 2148 if (index >= FEC_MAX_PORTS)
1953 return -ENXIO; 2149 return -ENXIO;
1954 2150
2151 /* Allocate memory for buffer descriptors.
2152 */
2153 mem_addr = __get_free_page(GFP_KERNEL);
2154 if (mem_addr == 0) {
2155 printk("FEC: allocate descriptor memory failed?\n");
2156 return -ENOMEM;
2157 }
2158
1955 /* Create an Ethernet device instance. 2159 /* Create an Ethernet device instance.
1956 */ 2160 */
1957 fecp = (volatile fec_t *) fec_hw[index]; 2161 fecp = (volatile fec_t *) fec_hw[index];
@@ -1964,16 +2168,6 @@ int __init fec_enet_init(struct net_device *dev)
1964 fecp->fec_ecntrl = 1; 2168 fecp->fec_ecntrl = 1;
1965 udelay(10); 2169 udelay(10);
1966 2170
1967 /* Clear and enable interrupts */
1968 fecp->fec_ievent = 0xffc00000;
1969 fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
1970 FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
1971 fecp->fec_hash_table_high = 0;
1972 fecp->fec_hash_table_low = 0;
1973 fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
1974 fecp->fec_ecntrl = 2;
1975 fecp->fec_r_des_active = 0x01000000;
1976
1977 /* Set the Ethernet address. If using multiple Enets on the 8xx, 2171 /* Set the Ethernet address. If using multiple Enets on the 8xx,
1978 * this needs some work to get unique addresses. 2172 * this needs some work to get unique addresses.
1979 * 2173 *
@@ -1982,14 +2176,6 @@ int __init fec_enet_init(struct net_device *dev)
1982 */ 2176 */
1983 fec_get_mac(dev); 2177 fec_get_mac(dev);
1984 2178
1985 /* Allocate memory for buffer descriptors.
1986 */
1987 if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
1988 printk("FEC init error. Need more space.\n");
1989 printk("FEC initialization failed.\n");
1990 return 1;
1991 }
1992 mem_addr = __get_free_page(GFP_KERNEL);
1993 cbd_base = (cbd_t *)mem_addr; 2179 cbd_base = (cbd_t *)mem_addr;
1994 /* XXX: missing check for allocation failure */ 2180 /* XXX: missing check for allocation failure */
1995 2181
@@ -2067,6 +2253,16 @@ int __init fec_enet_init(struct net_device *dev)
2067 */ 2253 */
2068 fec_request_intrs(dev); 2254 fec_request_intrs(dev);
2069 2255
2256 /* Clear and enable interrupts */
2257 fecp->fec_ievent = 0xffc00000;
2258 fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
2259 FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
2260 fecp->fec_hash_table_high = 0;
2261 fecp->fec_hash_table_low = 0;
2262 fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
2263 fecp->fec_ecntrl = 2;
2264 fecp->fec_r_des_active = 0x01000000;
2265
2070 dev->base_addr = (unsigned long)fecp; 2266 dev->base_addr = (unsigned long)fecp;
2071 2267
2072 /* The FEC Ethernet specific entries in the device structure. */ 2268 /* The FEC Ethernet specific entries in the device structure. */
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 045761b8a600..965c5c49fcdc 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -1,11 +1,10 @@
1/****************************************************************************/ 1/****************************************************************************/
2 2
3/* 3/*
4 * fec.h -- Fast Ethernet Controller for Motorola ColdFire 5230, 4 * fec.h -- Fast Ethernet Controller for Motorola ColdFire SoC
5 * 5231, 5232, 5234, 5235, 5270, 5271, 5272, 5274, 5275, 5 * processors.
6 * 5280 and 5282.
7 * 6 *
8 * (C) Copyright 2000-2003, Greg Ungerer (gerg@snapgear.com) 7 * (C) Copyright 2000-2005, Greg Ungerer (gerg@snapgear.com)
9 * (C) Copyright 2000-2001, Lineo (www.lineo.com) 8 * (C) Copyright 2000-2001, Lineo (www.lineo.com)
10 */ 9 */
11 10
@@ -14,7 +13,8 @@
14#define FEC_H 13#define FEC_H
15/****************************************************************************/ 14/****************************************************************************/
16 15
17#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) 16#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
17 defined(CONFIG_M520x)
18/* 18/*
19 * Just figures, Motorola would have to change the offsets for 19 * Just figures, Motorola would have to change the offsets for
20 * registers in the same peripheral device on different models 20 * registers in the same peripheral device on different models
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index 4560026ed419..94e7a9af8705 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -1,6 +1,6 @@
1config FEC_8XX 1config FEC_8XX
2 tristate "Motorola 8xx FEC driver" 2 tristate "Motorola 8xx FEC driver"
3 depends on NET_ETHERNET 3 depends on NET_ETHERNET && FEC
4 select MII 4 select MII
5 5
6config FEC_8XX_GENERIC_PHY 6config FEC_8XX_GENERIC_PHY
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 9342d5bc7bb4..f5d49a110654 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -37,6 +37,7 @@
37#include <linux/ethtool.h> 37#include <linux/ethtool.h>
38#include <linux/bitops.h> 38#include <linux/bitops.h>
39#include <linux/fs.h> 39#include <linux/fs.h>
40#include <linux/platform_device.h>
40 41
41#include <linux/vmalloc.h> 42#include <linux/vmalloc.h>
42#include <asm/pgtable.h> 43#include <asm/pgtable.h>
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 1105543b9d88..e7ec96c964a9 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -4,7 +4,6 @@
4#include <linux/mii.h> 4#include <linux/mii.h>
5#include <linux/netdevice.h> 5#include <linux/netdevice.h>
6#include <linux/types.h> 6#include <linux/types.h>
7#include <linux/version.h>
8#include <linux/list.h> 7#include <linux/list.h>
9 8
10#include <linux/fs_enet_pd.h> 9#include <linux/fs_enet_pd.h>
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index a940b96433c7..e67b1d06611c 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -34,6 +34,7 @@
34#include <linux/ethtool.h> 34#include <linux/ethtool.h>
35#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/platform_device.h>
37 38
38#include <asm/immap_cpm2.h> 39#include <asm/immap_cpm2.h>
39#include <asm/mpc8260.h> 40#include <asm/mpc8260.h>
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 5ef4e845a387..2e8f44469699 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -34,6 +34,7 @@
34#include <linux/ethtool.h> 34#include <linux/ethtool.h>
35#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/platform_device.h>
37 38
38#include <asm/irq.h> 39#include <asm/irq.h>
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index d8c6e9cadcf5..a3897fda71fa 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -34,6 +34,7 @@
34#include <linux/ethtool.h> 34#include <linux/ethtool.h>
35#include <linux/bitops.h> 35#include <linux/bitops.h>
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/platform_device.h>
37 38
38#include <asm/irq.h> 39#include <asm/irq.h>
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 962580f2c4ab..54d294ad6df5 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -90,7 +90,6 @@
90#include <asm/irq.h> 90#include <asm/irq.h>
91#include <asm/uaccess.h> 91#include <asm/uaccess.h>
92#include <linux/module.h> 92#include <linux/module.h>
93#include <linux/version.h>
94#include <linux/dma-mapping.h> 93#include <linux/dma-mapping.h>
95#include <linux/crc32.h> 94#include <linux/crc32.h>
96#include <linux/mii.h> 95#include <linux/mii.h>
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index c77ca6c0d04a..220084e53341 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -43,7 +43,6 @@
43#include <asm/irq.h> 43#include <asm/irq.h>
44#include <asm/uaccess.h> 44#include <asm/uaccess.h>
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/version.h>
47#include <linux/crc32.h> 46#include <linux/crc32.h>
48#include <linux/workqueue.h> 47#include <linux/workqueue.h>
49#include <linux/ethtool.h> 48#include <linux/ethtool.h>
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index 68e3578e7613..5a2d810ce575 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -34,7 +34,6 @@
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/uaccess.h> 35#include <asm/uaccess.h>
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/version.h>
38#include <linux/crc32.h> 37#include <linux/crc32.h>
39#include <asm/types.h> 38#include <asm/types.h>
40#include <asm/uaccess.h> 39#include <asm/uaccess.h>
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 5a74d3d3dbe1..7263395d78bb 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -32,7 +32,6 @@
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/version.h>
36#include <linux/platform_device.h> 35#include <linux/platform_device.h>
37#include <asm/ocp.h> 36#include <asm/ocp.h>
38#include <linux/crc32.h> 37#include <linux/crc32.h>
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 3be3f916643a..c8dc40214a08 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -311,16 +311,6 @@ static void __exit dmascc_exit(void)
311 } 311 }
312} 312}
313 313
314#ifndef MODULE
315void __init dmascc_setup(char *str, int *ints)
316{
317 int i;
318
319 for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
320 io[i] = ints[i + 1];
321}
322#endif
323
324static int __init dmascc_init(void) 314static int __init dmascc_init(void)
325{ 315{
326 int h, i, j, n; 316 int h, i, j, n;
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index b71fab6e34f4..e92c17f6931c 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -96,7 +96,6 @@
96 96
97#undef HP100_MULTICAST_FILTER /* Need to be debugged... */ 97#undef HP100_MULTICAST_FILTER /* Need to be debugged... */
98 98
99#include <linux/version.h>
100#include <linux/module.h> 99#include <linux/module.h>
101#include <linux/kernel.h> 100#include <linux/kernel.h>
102#include <linux/string.h> 101#include <linux/string.h>
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 94239f67f3a3..be191d80ef9c 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -35,7 +35,6 @@
35 35
36#include <linux/config.h> 36#include <linux/config.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/version.h>
39#include <linux/types.h> 38#include <linux/types.h>
40#include <linux/errno.h> 39#include <linux/errno.h>
41#include <linux/ioport.h> 40#include <linux/ioport.h>
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 49e5467bdd73..6a3129bc15a6 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -46,10 +46,8 @@
46#include <linux/udp.h> 46#include <linux/udp.h>
47 47
48#ifdef CONFIG_SERIAL_8250 48#ifdef CONFIG_SERIAL_8250
49#include <linux/serial.h> 49#include <linux/serial_core.h>
50#include <asm/serial.h> 50#include <linux/serial_8250.h>
51#define IOC3_BAUD (22000000 / (3*16))
52#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
53#endif 51#endif
54 52
55#include <linux/netdevice.h> 53#include <linux/netdevice.h>
@@ -1146,12 +1144,11 @@ static inline int ioc3_is_menet(struct pci_dev *pdev)
1146 * around ioc3 oddities in this respect. 1144 * around ioc3 oddities in this respect.
1147 * 1145 *
1148 * The IOC3 serials use a 22MHz clock rate with an additional divider by 3. 1146 * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
1149 * (IOC3_BAUD = (22000000 / (3*16)))
1150 */ 1147 */
1151 1148
1152static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) 1149static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
1153{ 1150{
1154 struct serial_struct req; 1151 struct uart_port port;
1155 1152
1156 /* 1153 /*
1157 * We need to recognice and treat the fourth MENET serial as it 1154 * We need to recognice and treat the fourth MENET serial as it
@@ -1165,20 +1162,25 @@ static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
1165 if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3) 1162 if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3)
1166 return; 1163 return;
1167 1164
1168 /* Register to interrupt zero because we share the interrupt with 1165 /*
1169 the serial driver which we don't properly support yet. */ 1166 * Register to interrupt zero because we share the interrupt with
1170 memset(&req, 0, sizeof(req)); 1167 * the serial driver which we don't properly support yet.
1171 req.irq = 0; 1168 *
1172 req.flags = IOC3_COM_FLAGS; 1169 * Can't use UPF_IOREMAP as the whole of IOC3 resources have already
1173 req.io_type = SERIAL_IO_MEM; 1170 * been registered.
1174 req.iomem_reg_shift = 0; 1171 */
1175 req.baud_base = IOC3_BAUD; 1172 memset(&port, 0, sizeof(port));
1176 1173 port.irq = 0;
1177 req.iomem_base = (unsigned char *) &ioc3->sregs.uarta; 1174 port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
1178 register_serial(&req); 1175 port.iotype = UPIO_MEM;
1179 1176 port.regshift = 0;
1180 req.iomem_base = (unsigned char *) &ioc3->sregs.uartb; 1177 port.uartclk = 22000000 / 3;
1181 register_serial(&req); 1178
1179 port.membase = (unsigned char *) &ioc3->sregs.uarta;
1180 serial8250_register_port(&port);
1181
1182 port.membase = (unsigned char *) &ioc3->sregs.uartb;
1183 serial8250_register_port(&port);
1182} 1184}
1183#endif 1185#endif
1184 1186
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 0282771b1cbb..3137592d60c0 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1459,8 +1459,10 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1459 */ 1459 */
1460 IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__ 1460 IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__
1461 ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate ); 1461 ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
1462 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) 1462 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
1463 return -EPERM; 1463 ret = -EPERM;
1464 goto out;
1465 }
1464 1466
1465 /* self->speed=irq->ifr_baudrate; */ 1467 /* self->speed=irq->ifr_baudrate; */
1466 /* toshoboe_setbaud(self); */ 1468 /* toshoboe_setbaud(self); */
@@ -1470,8 +1472,10 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1470 case SIOCSMEDIABUSY: /* Set media busy */ 1472 case SIOCSMEDIABUSY: /* Set media busy */
1471 IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__ 1473 IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__
1472 ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) ); 1474 ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
1473 if (!capable (CAP_NET_ADMIN)) 1475 if (!capable (CAP_NET_ADMIN)) {
1474 return -EPERM; 1476 ret = -EPERM;
1477 goto out;
1478 }
1475 irda_device_set_media_busy (self->netdev, TRUE); 1479 irda_device_set_media_busy (self->netdev, TRUE);
1476 break; 1480 break;
1477 case SIOCGRECEIVING: /* Check if we are receiving right now */ 1481 case SIOCGRECEIVING: /* Check if we are receiving right now */
@@ -1483,7 +1487,7 @@ toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1483 IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); 1487 IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
1484 ret = -EOPNOTSUPP; 1488 ret = -EOPNOTSUPP;
1485 } 1489 }
1486 1490out:
1487 spin_unlock_irqrestore(&self->spinlock, flags); 1491 spin_unlock_irqrestore(&self->spinlock, flags);
1488 return ret; 1492 return ret;
1489 1493
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index d86d8f055a6c..77eadf84cb2c 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -58,7 +58,6 @@
58 58
59#include <linux/config.h> 59#include <linux/config.h>
60#include <linux/module.h> 60#include <linux/module.h>
61#include <linux/version.h>
62#include <linux/types.h> 61#include <linux/types.h>
63#include <linux/errno.h> 62#include <linux/errno.h>
64#include <linux/ioport.h> 63#include <linux/ioport.h>
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 04e47189d830..d38ade5f2f4e 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -694,7 +694,7 @@ ixgb_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
694 } 694 }
695} 695}
696 696
697struct ethtool_ops ixgb_ethtool_ops = { 697static struct ethtool_ops ixgb_ethtool_ops = {
698 .get_settings = ixgb_get_settings, 698 .get_settings = ixgb_get_settings,
699 .set_settings = ixgb_set_settings, 699 .set_settings = ixgb_set_settings,
700 .get_drvinfo = ixgb_get_drvinfo, 700 .get_drvinfo = ixgb_get_drvinfo,
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index 69329c73095a..620cad48bdea 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -47,9 +47,22 @@ static void ixgb_optics_reset(struct ixgb_hw *hw);
47 47
48static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw); 48static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw);
49 49
50uint32_t ixgb_mac_reset(struct ixgb_hw *hw); 50static void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
51 51
52uint32_t ixgb_mac_reset(struct ixgb_hw *hw) 52static void ixgb_clear_vfta(struct ixgb_hw *hw);
53
54static void ixgb_init_rx_addrs(struct ixgb_hw *hw);
55
56static uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
57 uint32_t reg_address,
58 uint32_t phy_address,
59 uint32_t device_type);
60
61static boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
62
63static boolean_t mac_addr_valid(uint8_t *mac_addr);
64
65static uint32_t ixgb_mac_reset(struct ixgb_hw *hw)
53{ 66{
54 uint32_t ctrl_reg; 67 uint32_t ctrl_reg;
55 68
@@ -335,7 +348,7 @@ ixgb_init_hw(struct ixgb_hw *hw)
335 * of the receive addresss registers. Clears the multicast table. Assumes 348 * of the receive addresss registers. Clears the multicast table. Assumes
336 * the receiver is in reset when the routine is called. 349 * the receiver is in reset when the routine is called.
337 *****************************************************************************/ 350 *****************************************************************************/
338void 351static void
339ixgb_init_rx_addrs(struct ixgb_hw *hw) 352ixgb_init_rx_addrs(struct ixgb_hw *hw)
340{ 353{
341 uint32_t i; 354 uint32_t i;
@@ -604,7 +617,7 @@ ixgb_write_vfta(struct ixgb_hw *hw,
604 * 617 *
605 * hw - Struct containing variables accessed by shared code 618 * hw - Struct containing variables accessed by shared code
606 *****************************************************************************/ 619 *****************************************************************************/
607void 620static void
608ixgb_clear_vfta(struct ixgb_hw *hw) 621ixgb_clear_vfta(struct ixgb_hw *hw)
609{ 622{
610 uint32_t offset; 623 uint32_t offset;
@@ -620,7 +633,7 @@ ixgb_clear_vfta(struct ixgb_hw *hw)
620 * hw - Struct containing variables accessed by shared code 633 * hw - Struct containing variables accessed by shared code
621 *****************************************************************************/ 634 *****************************************************************************/
622 635
623boolean_t 636static boolean_t
624ixgb_setup_fc(struct ixgb_hw *hw) 637ixgb_setup_fc(struct ixgb_hw *hw)
625{ 638{
626 uint32_t ctrl_reg; 639 uint32_t ctrl_reg;
@@ -722,7 +735,7 @@ ixgb_setup_fc(struct ixgb_hw *hw)
722 * This requires that first an address cycle command is sent, followed by a 735 * This requires that first an address cycle command is sent, followed by a
723 * read command. 736 * read command.
724 *****************************************************************************/ 737 *****************************************************************************/
725uint16_t 738static uint16_t
726ixgb_read_phy_reg(struct ixgb_hw *hw, 739ixgb_read_phy_reg(struct ixgb_hw *hw,
727 uint32_t reg_address, 740 uint32_t reg_address,
728 uint32_t phy_address, 741 uint32_t phy_address,
@@ -815,7 +828,7 @@ ixgb_read_phy_reg(struct ixgb_hw *hw,
815 * This requires that first an address cycle command is sent, followed by a 828 * This requires that first an address cycle command is sent, followed by a
816 * write command. 829 * write command.
817 *****************************************************************************/ 830 *****************************************************************************/
818void 831static void
819ixgb_write_phy_reg(struct ixgb_hw *hw, 832ixgb_write_phy_reg(struct ixgb_hw *hw,
820 uint32_t reg_address, 833 uint32_t reg_address,
821 uint32_t phy_address, 834 uint32_t phy_address,
@@ -959,7 +972,7 @@ boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw)
959 * 972 *
960 * hw - Struct containing variables accessed by shared code 973 * hw - Struct containing variables accessed by shared code
961 *****************************************************************************/ 974 *****************************************************************************/
962void 975static void
963ixgb_clear_hw_cntrs(struct ixgb_hw *hw) 976ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
964{ 977{
965 volatile uint32_t temp_reg; 978 volatile uint32_t temp_reg;
@@ -1114,7 +1127,7 @@ ixgb_get_bus_info(struct ixgb_hw *hw)
1114 * mac_addr - pointer to MAC address. 1127 * mac_addr - pointer to MAC address.
1115 * 1128 *
1116 *****************************************************************************/ 1129 *****************************************************************************/
1117boolean_t 1130static boolean_t
1118mac_addr_valid(uint8_t *mac_addr) 1131mac_addr_valid(uint8_t *mac_addr)
1119{ 1132{
1120 boolean_t is_valid = TRUE; 1133 boolean_t is_valid = TRUE;
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index 8bcf31ed10c2..382c6300ccc2 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -784,23 +784,8 @@ struct ixgb_hw_stats {
784extern boolean_t ixgb_adapter_stop(struct ixgb_hw *hw); 784extern boolean_t ixgb_adapter_stop(struct ixgb_hw *hw);
785extern boolean_t ixgb_init_hw(struct ixgb_hw *hw); 785extern boolean_t ixgb_init_hw(struct ixgb_hw *hw);
786extern boolean_t ixgb_adapter_start(struct ixgb_hw *hw); 786extern boolean_t ixgb_adapter_start(struct ixgb_hw *hw);
787extern void ixgb_init_rx_addrs(struct ixgb_hw *hw);
788extern void ixgb_check_for_link(struct ixgb_hw *hw); 787extern void ixgb_check_for_link(struct ixgb_hw *hw);
789extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw); 788extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw);
790extern boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
791extern void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
792extern boolean_t mac_addr_valid(uint8_t *mac_addr);
793
794extern uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
795 uint32_t reg_addr,
796 uint32_t phy_addr,
797 uint32_t device_type);
798
799extern void ixgb_write_phy_reg(struct ixgb_hw *hw,
800 uint32_t reg_addr,
801 uint32_t phy_addr,
802 uint32_t device_type,
803 uint16_t data);
804 789
805extern void ixgb_rar_set(struct ixgb_hw *hw, 790extern void ixgb_rar_set(struct ixgb_hw *hw,
806 uint8_t *addr, 791 uint8_t *addr,
@@ -818,8 +803,6 @@ extern void ixgb_write_vfta(struct ixgb_hw *hw,
818 uint32_t offset, 803 uint32_t offset,
819 uint32_t value); 804 uint32_t value);
820 805
821extern void ixgb_clear_vfta(struct ixgb_hw *hw);
822
823/* Access functions to eeprom data */ 806/* Access functions to eeprom data */
824void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr); 807void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr);
825uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw); 808uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 176680cb153e..f9f77e4f5965 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -45,7 +45,7 @@
45 */ 45 */
46 46
47char ixgb_driver_name[] = "ixgb"; 47char ixgb_driver_name[] = "ixgb";
48char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver"; 48static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
49 49
50#ifndef CONFIG_IXGB_NAPI 50#ifndef CONFIG_IXGB_NAPI
51#define DRIVERNAPI 51#define DRIVERNAPI
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index a74a5cfaf5bc..2fb3101cb33e 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -285,18 +285,8 @@ static struct device_driver jazz_sonic_driver = {
285 .remove = __devexit_p(jazz_sonic_device_remove), 285 .remove = __devexit_p(jazz_sonic_device_remove),
286}; 286};
287 287
288static void jazz_sonic_platform_release (struct device *device)
289{
290 struct platform_device *pldev;
291
292 /* free device */
293 pldev = to_platform_device (device);
294 kfree (pldev);
295}
296
297static int __init jazz_sonic_init_module(void) 288static int __init jazz_sonic_init_module(void)
298{ 289{
299 struct platform_device *pldev;
300 int err; 290 int err;
301 291
302 if ((err = driver_register(&jazz_sonic_driver))) { 292 if ((err = driver_register(&jazz_sonic_driver))) {
@@ -304,27 +294,19 @@ static int __init jazz_sonic_init_module(void)
304 return err; 294 return err;
305 } 295 }
306 296
307 jazz_sonic_device = NULL; 297 jazz_sonic_device = platform_device_alloc(jazz_sonic_string, 0);
308 298 if (!jazz_sonnic_device)
309 if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
310 goto out_unregister; 299 goto out_unregister;
311 }
312 300
313 memset(pldev, 0, sizeof (*pldev)); 301 if (platform_device_add(jazz_sonic_device)) {
314 pldev->name = jazz_sonic_string; 302 platform_device_put(jazz_sonic_device);
315 pldev->id = 0;
316 pldev->dev.release = jazz_sonic_platform_release;
317 jazz_sonic_device = pldev;
318
319 if (platform_device_register (pldev)) {
320 kfree(pldev);
321 jazz_sonic_device = NULL; 303 jazz_sonic_device = NULL;
322 } 304 }
323 305
324 return 0; 306 return 0;
325 307
326out_unregister: 308out_unregister:
327 platform_device_unregister(pldev); 309 driver_unregister(&jazz_sonic_driver);
328 310
329 return -ENOMEM; 311 return -ENOMEM;
330} 312}
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index ce5761816a64..d8c99f038fa0 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -15,7 +15,6 @@
15 * and fixed access to Sonic Sys card which masquerades as a Farallon 15 * and fixed access to Sonic Sys card which masquerades as a Farallon
16 * by rayk@knightsmanor.org */ 16 * by rayk@knightsmanor.org */
17 17
18#include <linux/version.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/types.h> 20#include <linux/types.h>
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index e9c999d7eb39..9ef4592aca03 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -599,18 +599,8 @@ static struct device_driver mac_sonic_driver = {
599 .remove = __devexit_p(mac_sonic_device_remove), 599 .remove = __devexit_p(mac_sonic_device_remove),
600}; 600};
601 601
602static void mac_sonic_platform_release(struct device *device)
603{
604 struct platform_device *pldev;
605
606 /* free device */
607 pldev = to_platform_device (device);
608 kfree (pldev);
609}
610
611static int __init mac_sonic_init_module(void) 602static int __init mac_sonic_init_module(void)
612{ 603{
613 struct platform_device *pldev;
614 int err; 604 int err;
615 605
616 if ((err = driver_register(&mac_sonic_driver))) { 606 if ((err = driver_register(&mac_sonic_driver))) {
@@ -618,27 +608,20 @@ static int __init mac_sonic_init_module(void)
618 return err; 608 return err;
619 } 609 }
620 610
621 mac_sonic_device = NULL; 611 mac_sonic_device = platform_device_alloc(mac_sonic_string, 0);
622 612 if (!mac_sonic_device) {
623 if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
624 goto out_unregister; 613 goto out_unregister;
625 } 614 }
626 615
627 memset(pldev, 0, sizeof (*pldev)); 616 if (platform_device_add(mac_sonic_device)) {
628 pldev->name = mac_sonic_string; 617 platform_device_put(mac_sonic_device);
629 pldev->id = 0;
630 pldev->dev.release = mac_sonic_platform_release;
631 mac_sonic_device = pldev;
632
633 if (platform_device_register (pldev)) {
634 kfree(pldev);
635 mac_sonic_device = NULL; 618 mac_sonic_device = NULL;
636 } 619 }
637 620
638 return 0; 621 return 0;
639 622
640out_unregister: 623out_unregister:
641 platform_device_unregister(pldev); 624 driver_unregister(&mac_sonic_driver);
642 625
643 return -ENOMEM; 626 return -ENOMEM;
644} 627}
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
index bcfda5192da0..f769f9b626ea 100644
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -1,7 +1,6 @@
1#ifndef __MV643XX_ETH_H__ 1#ifndef __MV643XX_ETH_H__
2#define __MV643XX_ETH_H__ 2#define __MV643XX_ETH_H__
3 3
4#include <linux/version.h>
5#include <linux/module.h> 4#include <linux/module.h>
6#include <linux/kernel.h> 5#include <linux/kernel.h>
7#include <linux/spinlock.h> 6#include <linux/spinlock.h>
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index a3c3fc9c0d8a..f857ae94d261 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -110,7 +110,6 @@
110#include <linux/init.h> 110#include <linux/init.h>
111#include <linux/ip.h> /* for iph */ 111#include <linux/ip.h> /* for iph */
112#include <linux/in.h> /* for IPPROTO_... */ 112#include <linux/in.h> /* for IPPROTO_... */
113#include <linux/eeprom.h>
114#include <linux/compiler.h> 113#include <linux/compiler.h>
115#include <linux/prefetch.h> 114#include <linux/prefetch.h>
116#include <linux/ethtool.h> 115#include <linux/ethtool.h>
@@ -445,7 +444,6 @@ struct ns83820 {
445 444
446 u32 MEAR_cache; 445 u32 MEAR_cache;
447 u32 IMR_cache; 446 u32 IMR_cache;
448 struct eeprom ee;
449 447
450 unsigned linkstate; 448 unsigned linkstate;
451 449
@@ -1558,15 +1556,13 @@ static void ns83820_getmac(struct ns83820 *dev, u8 *mac)
1558 unsigned i; 1556 unsigned i;
1559 for (i=0; i<3; i++) { 1557 for (i=0; i<3; i++) {
1560 u32 data; 1558 u32 data;
1561#if 0 /* I've left this in as an example of how to use eeprom.h */ 1559
1562 data = eeprom_readw(&dev->ee, 0xa + 2 - i);
1563#else
1564 /* Read from the perfect match memory: this is loaded by 1560 /* Read from the perfect match memory: this is loaded by
1565 * the chip from the EEPROM via the EELOAD self test. 1561 * the chip from the EEPROM via the EELOAD self test.
1566 */ 1562 */
1567 writel(i*2, dev->base + RFCR); 1563 writel(i*2, dev->base + RFCR);
1568 data = readl(dev->base + RFDR); 1564 data = readl(dev->base + RFDR);
1569#endif 1565
1570 *mac++ = data; 1566 *mac++ = data;
1571 *mac++ = data >> 8; 1567 *mac++ = data >> 8;
1572 } 1568 }
@@ -1851,8 +1847,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1851 spin_lock_init(&dev->misc_lock); 1847 spin_lock_init(&dev->misc_lock);
1852 dev->pci_dev = pci_dev; 1848 dev->pci_dev = pci_dev;
1853 1849
1854 dev->ee.cache = &dev->MEAR_cache;
1855 dev->ee.lock = &dev->misc_lock;
1856 SET_MODULE_OWNER(ndev); 1850 SET_MODULE_OWNER(ndev);
1857 SET_NETDEV_DEV(ndev, &pci_dev->dev); 1851 SET_NETDEV_DEV(ndev, &pci_dev->dev);
1858 1852
@@ -1887,9 +1881,6 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
1887 1881
1888 dev->IMR_cache = 0; 1882 dev->IMR_cache = 0;
1889 1883
1890 setup_ee_mem_bitbanger(&dev->ee, dev->base + MEAR, 3, 2, 1, 0,
1891 0);
1892
1893 err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ, 1884 err = request_irq(pci_dev->irq, ns83820_irq, SA_SHIRQ,
1894 DRV_NAME, ndev); 1885 DRV_NAME, ndev);
1895 if (err) { 1886 if (err) {
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c
index c47fb2ecd147..7d8d534255c0 100644
--- a/drivers/net/phy/cicada.c
+++ b/drivers/net/phy/cicada.c
@@ -29,7 +29,6 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h> 32#include <linux/mii.h>
34#include <linux/ethtool.h> 33#include <linux/ethtool.h>
35#include <linux/phy.h> 34#include <linux/phy.h>
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 6caf499fae32..5e9002e444c5 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -29,7 +29,6 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h> 32#include <linux/mii.h>
34#include <linux/ethtool.h> 33#include <linux/ethtool.h>
35#include <linux/phy.h> 34#include <linux/phy.h>
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index 4c840448ec86..bef79e454c33 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -29,7 +29,6 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h> 32#include <linux/mii.h>
34#include <linux/ethtool.h> 33#include <linux/ethtool.h>
35#include <linux/phy.h> 34#include <linux/phy.h>
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4a72b025006b..a2d6386d13bc 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -29,7 +29,6 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h> 32#include <linux/mii.h>
34#include <linux/ethtool.h> 33#include <linux/ethtool.h>
35#include <linux/phy.h> 34#include <linux/phy.h>
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 5eab9c42a111..02940c0fef68 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -29,7 +29,6 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h> 32#include <linux/mii.h>
34#include <linux/ethtool.h> 33#include <linux/ethtool.h>
35#include <linux/phy.h> 34#include <linux/phy.h>
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 9209da9dde0d..b8686e47f899 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -30,7 +30,6 @@
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/version.h>
34#include <linux/mii.h> 33#include <linux/mii.h>
35#include <linux/ethtool.h> 34#include <linux/ethtool.h>
36#include <linux/phy.h> 35#include <linux/phy.h>
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 6da1aa0706a1..16bebe7a7ce1 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -30,7 +30,6 @@
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/version.h>
34#include <linux/mii.h> 33#include <linux/mii.h>
35#include <linux/ethtool.h> 34#include <linux/ethtool.h>
36#include <linux/phy.h> 35#include <linux/phy.h>
diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c
index d461ba457631..65d995b02b25 100644
--- a/drivers/net/phy/qsemi.c
+++ b/drivers/net/phy/qsemi.c
@@ -29,7 +29,6 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/version.h>
33#include <linux/mii.h> 32#include <linux/mii.h>
34#include <linux/ethtool.h> 33#include <linux/ethtool.h>
35#include <linux/phy.h> 34#include <linux/phy.h>
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 59e8183c639e..400f652282d7 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -31,6 +31,7 @@
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34#include <asm/string.h>
34 35
35#define PPP_VERSION "2.4.2" 36#define PPP_VERSION "2.4.2"
36 37
@@ -835,8 +836,11 @@ process_input_packet(struct asyncppp *ap)
835 err: 836 err:
836 /* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */ 837 /* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */
837 ap->state = SC_PREV_ERROR; 838 ap->state = SC_PREV_ERROR;
838 if (skb) 839 if (skb) {
840 /* make skb appear as freshly allocated */
839 skb_trim(skb, 0); 841 skb_trim(skb, 0);
842 skb_reserve(skb, - skb_headroom(skb));
843 }
840} 844}
841 845
842/* Called when the tty driver has data for us. Runs parallel with the 846/* Called when the tty driver has data for us. Runs parallel with the
@@ -889,10 +893,17 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
889 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2); 893 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
890 if (skb == 0) 894 if (skb == 0)
891 goto nomem; 895 goto nomem;
892 /* Try to get the payload 4-byte aligned */ 896 ap->rpkt = skb;
897 }
898 if (skb->len == 0) {
899 /* Try to get the payload 4-byte aligned.
900 * This should match the
901 * PPP_ALLSTATIONS/PPP_UI/compressed tests in
902 * process_input_packet, but we do not have
903 * enough chars here to test buf[1] and buf[2].
904 */
893 if (buf[0] != PPP_ALLSTATIONS) 905 if (buf[0] != PPP_ALLSTATIONS)
894 skb_reserve(skb, 2 + (buf[0] & 1)); 906 skb_reserve(skb, 2 + (buf[0] & 1));
895 ap->rpkt = skb;
896 } 907 }
897 if (n > skb_tailroom(skb)) { 908 if (n > skb_tailroom(skb)) {
898 /* packet overflowed MRU */ 909 /* packet overflowed MRU */
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index d3c9958b00d0..50430f79f8cf 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -137,13 +137,14 @@ struct ppp {
137 137
138/* 138/*
139 * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC, 139 * Bits in flags: SC_NO_TCP_CCID, SC_CCP_OPEN, SC_CCP_UP, SC_LOOP_TRAFFIC,
140 * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP. 140 * SC_MULTILINK, SC_MP_SHORTSEQ, SC_MP_XSHORTSEQ, SC_COMP_TCP, SC_REJ_COMP_TCP,
141 * SC_MUST_COMP
141 * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR. 142 * Bits in rstate: SC_DECOMP_RUN, SC_DC_ERROR, SC_DC_FERROR.
142 * Bits in xstate: SC_COMP_RUN 143 * Bits in xstate: SC_COMP_RUN
143 */ 144 */
144#define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \ 145#define SC_FLAG_BITS (SC_NO_TCP_CCID|SC_CCP_OPEN|SC_CCP_UP|SC_LOOP_TRAFFIC \
145 |SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \ 146 |SC_MULTILINK|SC_MP_SHORTSEQ|SC_MP_XSHORTSEQ \
146 |SC_COMP_TCP|SC_REJ_COMP_TCP) 147 |SC_COMP_TCP|SC_REJ_COMP_TCP|SC_MUST_COMP)
147 148
148/* 149/*
149 * Private data structure for each channel. 150 * Private data structure for each channel.
@@ -1027,6 +1028,56 @@ ppp_xmit_process(struct ppp *ppp)
1027 ppp_xmit_unlock(ppp); 1028 ppp_xmit_unlock(ppp);
1028} 1029}
1029 1030
1031static inline struct sk_buff *
1032pad_compress_skb(struct ppp *ppp, struct sk_buff *skb)
1033{
1034 struct sk_buff *new_skb;
1035 int len;
1036 int new_skb_size = ppp->dev->mtu +
1037 ppp->xcomp->comp_extra + ppp->dev->hard_header_len;
1038 int compressor_skb_size = ppp->dev->mtu +
1039 ppp->xcomp->comp_extra + PPP_HDRLEN;
1040 new_skb = alloc_skb(new_skb_size, GFP_ATOMIC);
1041 if (!new_skb) {
1042 if (net_ratelimit())
1043 printk(KERN_ERR "PPP: no memory (comp pkt)\n");
1044 return NULL;
1045 }
1046 if (ppp->dev->hard_header_len > PPP_HDRLEN)
1047 skb_reserve(new_skb,
1048 ppp->dev->hard_header_len - PPP_HDRLEN);
1049
1050 /* compressor still expects A/C bytes in hdr */
1051 len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
1052 new_skb->data, skb->len + 2,
1053 compressor_skb_size);
1054 if (len > 0 && (ppp->flags & SC_CCP_UP)) {
1055 kfree_skb(skb);
1056 skb = new_skb;
1057 skb_put(skb, len);
1058 skb_pull(skb, 2); /* pull off A/C bytes */
1059 } else if (len == 0) {
1060 /* didn't compress, or CCP not up yet */
1061 kfree_skb(new_skb);
1062 new_skb = skb;
1063 } else {
1064 /*
1065 * (len < 0)
1066 * MPPE requires that we do not send unencrypted
1067 * frames. The compressor will return -1 if we
1068 * should drop the frame. We cannot simply test
1069 * the compress_proto because MPPE and MPPC share
1070 * the same number.
1071 */
1072 if (net_ratelimit())
1073 printk(KERN_ERR "ppp: compressor dropped pkt\n");
1074 kfree_skb(skb);
1075 kfree_skb(new_skb);
1076 new_skb = NULL;
1077 }
1078 return new_skb;
1079}
1080
1030/* 1081/*
1031 * Compress and send a frame. 1082 * Compress and send a frame.
1032 * The caller should have locked the xmit path, 1083 * The caller should have locked the xmit path,
@@ -1113,29 +1164,14 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
1113 /* try to do packet compression */ 1164 /* try to do packet compression */
1114 if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0 1165 if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
1115 && proto != PPP_LCP && proto != PPP_CCP) { 1166 && proto != PPP_LCP && proto != PPP_CCP) {
1116 new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len, 1167 if (!(ppp->flags & SC_CCP_UP) && (ppp->flags & SC_MUST_COMP)) {
1117 GFP_ATOMIC); 1168 if (net_ratelimit())
1118 if (new_skb == 0) { 1169 printk(KERN_ERR "ppp: compression required but down - pkt dropped.\n");
1119 printk(KERN_ERR "PPP: no memory (comp pkt)\n");
1120 goto drop; 1170 goto drop;
1121 } 1171 }
1122 if (ppp->dev->hard_header_len > PPP_HDRLEN) 1172 skb = pad_compress_skb(ppp, skb);
1123 skb_reserve(new_skb, 1173 if (!skb)
1124 ppp->dev->hard_header_len - PPP_HDRLEN); 1174 goto drop;
1125
1126 /* compressor still expects A/C bytes in hdr */
1127 len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
1128 new_skb->data, skb->len + 2,
1129 ppp->dev->mtu + PPP_HDRLEN);
1130 if (len > 0 && (ppp->flags & SC_CCP_UP)) {
1131 kfree_skb(skb);
1132 skb = new_skb;
1133 skb_put(skb, len);
1134 skb_pull(skb, 2); /* pull off A/C bytes */
1135 } else {
1136 /* didn't compress, or CCP not up yet */
1137 kfree_skb(new_skb);
1138 }
1139 } 1175 }
1140 1176
1141 /* 1177 /*
@@ -1155,7 +1191,8 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
1155 return; 1191 return;
1156 1192
1157 drop: 1193 drop:
1158 kfree_skb(skb); 1194 if (skb)
1195 kfree_skb(skb);
1159 ++ppp->stats.tx_errors; 1196 ++ppp->stats.tx_errors;
1160} 1197}
1161 1198
@@ -1552,6 +1589,9 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
1552 && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0) 1589 && (ppp->rstate & (SC_DC_FERROR | SC_DC_ERROR)) == 0)
1553 skb = ppp_decompress_frame(ppp, skb); 1590 skb = ppp_decompress_frame(ppp, skb);
1554 1591
1592 if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR)
1593 goto err;
1594
1555 proto = PPP_PROTO(skb); 1595 proto = PPP_PROTO(skb);
1556 switch (proto) { 1596 switch (proto) {
1557 case PPP_VJC_COMP: 1597 case PPP_VJC_COMP:
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
new file mode 100644
index 000000000000..1985d1b57c45
--- /dev/null
+++ b/drivers/net/ppp_mppe.c
@@ -0,0 +1,724 @@
1/*
2 * ppp_mppe.c - interface MPPE to the PPP code.
3 * This version is for use with Linux kernel 2.6.14+
4 *
5 * By Frank Cusack <fcusack@fcusack.com>.
6 * Copyright (c) 2002,2003,2004 Google, Inc.
7 * All rights reserved.
8 *
9 * License:
10 * Permission to use, copy, modify, and distribute this software and its
11 * documentation is hereby granted, provided that the above copyright
12 * notice appears in all copies. This software is provided without any
13 * warranty, express or implied.
14 *
15 * ALTERNATIVELY, provided that this notice is retained in full, this product
16 * may be distributed under the terms of the GNU General Public License (GPL),
17 * in which case the provisions of the GPL apply INSTEAD OF those given above.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 *
33 *
34 * Changelog:
35 * 08/12/05 - Matt Domsch <Matt_Domsch@dell.com>
36 * Only need extra skb padding on transmit, not receive.
37 * 06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
38 * Use Linux kernel 2.6 arc4 and sha1 routines rather than
39 * providing our own.
40 * 2/15/04 - TS: added #include <version.h> and testing for Kernel
41 * version before using
42 * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
43 * deprecated in 2.6
44 */
45
46#include <linux/config.h>
47#include <linux/module.h>
48#include <linux/kernel.h>
49#include <linux/version.h>
50#include <linux/init.h>
51#include <linux/types.h>
52#include <linux/slab.h>
53#include <linux/string.h>
54#include <linux/crypto.h>
55#include <linux/mm.h>
56#include <linux/ppp_defs.h>
57#include <linux/ppp-comp.h>
58#include <asm/scatterlist.h>
59
60#include "ppp_mppe.h"
61
62MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
63MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
64MODULE_LICENSE("Dual BSD/GPL");
65MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
66MODULE_VERSION("1.0.2");
67
68static void
69setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
70{
71 sg[0].page = virt_to_page(address);
72 sg[0].offset = offset_in_page(address);
73 sg[0].length = length;
74}
75
76#define SHA1_PAD_SIZE 40
77
78/*
79 * kernel crypto API needs its arguments to be in kmalloc'd memory, not in the module
80 * static data area. That means sha_pad needs to be kmalloc'd.
81 */
82
83struct sha_pad {
84 unsigned char sha_pad1[SHA1_PAD_SIZE];
85 unsigned char sha_pad2[SHA1_PAD_SIZE];
86};
87static struct sha_pad *sha_pad;
88
89static inline void sha_pad_init(struct sha_pad *shapad)
90{
91 memset(shapad->sha_pad1, 0x00, sizeof(shapad->sha_pad1));
92 memset(shapad->sha_pad2, 0xF2, sizeof(shapad->sha_pad2));
93}
94
95/*
96 * State for an MPPE (de)compressor.
97 */
98struct ppp_mppe_state {
99 struct crypto_tfm *arc4;
100 struct crypto_tfm *sha1;
101 unsigned char *sha1_digest;
102 unsigned char master_key[MPPE_MAX_KEY_LEN];
103 unsigned char session_key[MPPE_MAX_KEY_LEN];
104 unsigned keylen; /* key length in bytes */
105 /* NB: 128-bit == 16, 40-bit == 8! */
106 /* If we want to support 56-bit, */
107 /* the unit has to change to bits */
108 unsigned char bits; /* MPPE control bits */
109 unsigned ccount; /* 12-bit coherency count (seqno) */
110 unsigned stateful; /* stateful mode flag */
111 int discard; /* stateful mode packet loss flag */
112 int sanity_errors; /* take down LCP if too many */
113 int unit;
114 int debug;
115 struct compstat stats;
116};
117
118/* struct ppp_mppe_state.bits definitions */
119#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */
120#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */
121#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */
122#define MPPE_BIT_D 0x10 /* This is an encrypted frame */
123
124#define MPPE_BIT_FLUSHED MPPE_BIT_A
125#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
126
127#define MPPE_BITS(p) ((p)[4] & 0xf0)
128#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
129#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */
130
131#define MPPE_OVHD 2 /* MPPE overhead/packet */
132#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */
133
134/*
135 * Key Derivation, from RFC 3078, RFC 3079.
136 * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
137 */
138static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
139{
140 struct scatterlist sg[4];
141
142 setup_sg(&sg[0], state->master_key, state->keylen);
143 setup_sg(&sg[1], sha_pad->sha_pad1, sizeof(sha_pad->sha_pad1));
144 setup_sg(&sg[2], state->session_key, state->keylen);
145 setup_sg(&sg[3], sha_pad->sha_pad2, sizeof(sha_pad->sha_pad2));
146
147 crypto_digest_digest (state->sha1, sg, 4, state->sha1_digest);
148
149 memcpy(InterimKey, state->sha1_digest, state->keylen);
150}
151
152/*
153 * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
154 * Well, not what's written there, but rather what they meant.
155 */
156static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
157{
158 unsigned char InterimKey[MPPE_MAX_KEY_LEN];
159 struct scatterlist sg_in[1], sg_out[1];
160
161 get_new_key_from_sha(state, InterimKey);
162 if (!initial_key) {
163 crypto_cipher_setkey(state->arc4, InterimKey, state->keylen);
164 setup_sg(sg_in, InterimKey, state->keylen);
165 setup_sg(sg_out, state->session_key, state->keylen);
166 if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in,
167 state->keylen) != 0) {
168 printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n");
169 }
170 } else {
171 memcpy(state->session_key, InterimKey, state->keylen);
172 }
173 if (state->keylen == 8) {
174 /* See RFC 3078 */
175 state->session_key[0] = 0xd1;
176 state->session_key[1] = 0x26;
177 state->session_key[2] = 0x9e;
178 }
179 crypto_cipher_setkey(state->arc4, state->session_key, state->keylen);
180}
181
182/*
183 * Allocate space for a (de)compressor.
184 */
185static void *mppe_alloc(unsigned char *options, int optlen)
186{
187 struct ppp_mppe_state *state;
188 unsigned int digestsize;
189
190 if (optlen != CILEN_MPPE + sizeof(state->master_key)
191 || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
192 goto out;
193
194 state = (struct ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
195 if (state == NULL)
196 goto out;
197
198 memset(state, 0, sizeof(*state));
199
200 state->arc4 = crypto_alloc_tfm("arc4", 0);
201 if (!state->arc4)
202 goto out_free;
203
204 state->sha1 = crypto_alloc_tfm("sha1", 0);
205 if (!state->sha1)
206 goto out_free;
207
208 digestsize = crypto_tfm_alg_digestsize(state->sha1);
209 if (digestsize < MPPE_MAX_KEY_LEN)
210 goto out_free;
211
212 state->sha1_digest = kmalloc(digestsize, GFP_KERNEL);
213 if (!state->sha1_digest)
214 goto out_free;
215
216 /* Save keys. */
217 memcpy(state->master_key, &options[CILEN_MPPE],
218 sizeof(state->master_key));
219 memcpy(state->session_key, state->master_key,
220 sizeof(state->master_key));
221
222 /*
223 * We defer initial key generation until mppe_init(), as mppe_alloc()
224 * is called frequently during negotiation.
225 */
226
227 return (void *)state;
228
229 out_free:
230 if (state->sha1_digest)
231 kfree(state->sha1_digest);
232 if (state->sha1)
233 crypto_free_tfm(state->sha1);
234 if (state->arc4)
235 crypto_free_tfm(state->arc4);
236 kfree(state);
237 out:
238 return NULL;
239}
240
241/*
242 * Deallocate space for a (de)compressor.
243 */
244static void mppe_free(void *arg)
245{
246 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
247 if (state) {
248 if (state->sha1_digest)
249 kfree(state->sha1_digest);
250 if (state->sha1)
251 crypto_free_tfm(state->sha1);
252 if (state->arc4)
253 crypto_free_tfm(state->arc4);
254 kfree(state);
255 }
256}
257
258/*
259 * Initialize (de)compressor state.
260 */
261static int
262mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
263 const char *debugstr)
264{
265 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
266 unsigned char mppe_opts;
267
268 if (optlen != CILEN_MPPE
269 || options[0] != CI_MPPE || options[1] != CILEN_MPPE)
270 return 0;
271
272 MPPE_CI_TO_OPTS(&options[2], mppe_opts);
273 if (mppe_opts & MPPE_OPT_128)
274 state->keylen = 16;
275 else if (mppe_opts & MPPE_OPT_40)
276 state->keylen = 8;
277 else {
278 printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr,
279 unit);
280 return 0;
281 }
282 if (mppe_opts & MPPE_OPT_STATEFUL)
283 state->stateful = 1;
284
285 /* Generate the initial session key. */
286 mppe_rekey(state, 1);
287
288 if (debug) {
289 int i;
290 char mkey[sizeof(state->master_key) * 2 + 1];
291 char skey[sizeof(state->session_key) * 2 + 1];
292
293 printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n",
294 debugstr, unit, (state->keylen == 16) ? 128 : 40,
295 (state->stateful) ? "stateful" : "stateless");
296
297 for (i = 0; i < sizeof(state->master_key); i++)
298 sprintf(mkey + i * 2, "%02x", state->master_key[i]);
299 for (i = 0; i < sizeof(state->session_key); i++)
300 sprintf(skey + i * 2, "%02x", state->session_key[i]);
301 printk(KERN_DEBUG
302 "%s[%d]: keys: master: %s initial session: %s\n",
303 debugstr, unit, mkey, skey);
304 }
305
306 /*
307 * Initialize the coherency count. The initial value is not specified
308 * in RFC 3078, but we can make a reasonable assumption that it will
309 * start at 0. Setting it to the max here makes the comp/decomp code
310 * do the right thing (determined through experiment).
311 */
312 state->ccount = MPPE_CCOUNT_SPACE - 1;
313
314 /*
315 * Note that even though we have initialized the key table, we don't
316 * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1.
317 */
318 state->bits = MPPE_BIT_ENCRYPTED;
319
320 state->unit = unit;
321 state->debug = debug;
322
323 return 1;
324}
325
326static int
327mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
328 int hdrlen, int debug)
329{
330 /* ARGSUSED */
331 return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
332}
333
334/*
335 * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
336 * tell the compressor to rekey. Note that we MUST NOT rekey for
337 * every CCP Reset-Request; we only rekey on the next xmit packet.
338 * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
339 * So, rekeying for every CCP Reset-Request is broken as the peer will not
340 * know how many times we've rekeyed. (If we rekey and THEN get another
341 * CCP Reset-Request, we must rekey again.)
342 */
343static void mppe_comp_reset(void *arg)
344{
345 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
346
347 state->bits |= MPPE_BIT_FLUSHED;
348}
349
350/*
351 * Compress (encrypt) a packet.
352 * It's strange to call this a compressor, since the output is always
353 * MPPE_OVHD + 2 bytes larger than the input.
354 */
355static int
356mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
357 int isize, int osize)
358{
359 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
360 int proto;
361 struct scatterlist sg_in[1], sg_out[1];
362
363 /*
364 * Check that the protocol is in the range we handle.
365 */
366 proto = PPP_PROTOCOL(ibuf);
367 if (proto < 0x0021 || proto > 0x00fa)
368 return 0;
369
370 /* Make sure we have enough room to generate an encrypted packet. */
371 if (osize < isize + MPPE_OVHD + 2) {
372 /* Drop the packet if we should encrypt it, but can't. */
373 printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
374 "(have: %d need: %d)\n", state->unit,
375 osize, osize + MPPE_OVHD + 2);
376 return -1;
377 }
378
379 osize = isize + MPPE_OVHD + 2;
380
381 /*
382 * Copy over the PPP header and set control bits.
383 */
384 obuf[0] = PPP_ADDRESS(ibuf);
385 obuf[1] = PPP_CONTROL(ibuf);
386 obuf[2] = PPP_COMP >> 8; /* isize + MPPE_OVHD + 1 */
387 obuf[3] = PPP_COMP; /* isize + MPPE_OVHD + 2 */
388 obuf += PPP_HDRLEN;
389
390 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
391 if (state->debug >= 7)
392 printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
393 state->ccount);
394 obuf[0] = state->ccount >> 8;
395 obuf[1] = state->ccount & 0xff;
396
397 if (!state->stateful || /* stateless mode */
398 ((state->ccount & 0xff) == 0xff) || /* "flag" packet */
399 (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */
400 /* We must rekey */
401 if (state->debug && state->stateful)
402 printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n",
403 state->unit);
404 mppe_rekey(state, 0);
405 state->bits |= MPPE_BIT_FLUSHED;
406 }
407 obuf[0] |= state->bits;
408 state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */
409
410 obuf += MPPE_OVHD;
411 ibuf += 2; /* skip to proto field */
412 isize -= 2;
413
414 /* Encrypt packet */
415 setup_sg(sg_in, ibuf, isize);
416 setup_sg(sg_out, obuf, osize);
417 if (crypto_cipher_encrypt(state->arc4, sg_out, sg_in, isize) != 0) {
418 printk(KERN_DEBUG "crypto_cypher_encrypt failed\n");
419 return -1;
420 }
421
422 state->stats.unc_bytes += isize;
423 state->stats.unc_packets++;
424 state->stats.comp_bytes += osize;
425 state->stats.comp_packets++;
426
427 return osize;
428}
429
430/*
431 * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
432 * to look bad ... and the longer the link is up the worse it will get.
433 */
434static void mppe_comp_stats(void *arg, struct compstat *stats)
435{
436 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
437
438 *stats = state->stats;
439}
440
441static int
442mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
443 int hdrlen, int mru, int debug)
444{
445 /* ARGSUSED */
446 return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
447}
448
449/*
450 * We received a CCP Reset-Ack. Just ignore it.
451 */
452static void mppe_decomp_reset(void *arg)
453{
454 /* ARGSUSED */
455 return;
456}
457
458/*
459 * Decompress (decrypt) an MPPE packet.
460 */
461static int
462mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
463 int osize)
464{
465 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
466 unsigned ccount;
467 int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
468 int sanity = 0;
469 struct scatterlist sg_in[1], sg_out[1];
470
471 if (isize <= PPP_HDRLEN + MPPE_OVHD) {
472 if (state->debug)
473 printk(KERN_DEBUG
474 "mppe_decompress[%d]: short pkt (%d)\n",
475 state->unit, isize);
476 return DECOMP_ERROR;
477 }
478
479 /*
480 * Make sure we have enough room to decrypt the packet.
481 * Note that for our test we only subtract 1 byte whereas in
482 * mppe_compress() we added 2 bytes (+MPPE_OVHD);
483 * this is to account for possible PFC.
484 */
485 if (osize < isize - MPPE_OVHD - 1) {
486 printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
487 "(have: %d need: %d)\n", state->unit,
488 osize, isize - MPPE_OVHD - 1);
489 return DECOMP_ERROR;
490 }
491 osize = isize - MPPE_OVHD - 2; /* assume no PFC */
492
493 ccount = MPPE_CCOUNT(ibuf);
494 if (state->debug >= 7)
495 printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n",
496 state->unit, ccount);
497
498 /* sanity checks -- terminate with extreme prejudice */
499 if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
500 printk(KERN_DEBUG
501 "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
502 state->unit);
503 state->sanity_errors += 100;
504 sanity = 1;
505 }
506 if (!state->stateful && !flushed) {
507 printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
508 "stateless mode!\n", state->unit);
509 state->sanity_errors += 100;
510 sanity = 1;
511 }
512 if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
513 printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
514 "flag packet!\n", state->unit);
515 state->sanity_errors += 100;
516 sanity = 1;
517 }
518
519 if (sanity) {
520 if (state->sanity_errors < SANITY_MAX)
521 return DECOMP_ERROR;
522 else
523 /*
524 * Take LCP down if the peer is sending too many bogons.
525 * We don't want to do this for a single or just a few
526 * instances since it could just be due to packet corruption.
527 */
528 return DECOMP_FATALERROR;
529 }
530
531 /*
532 * Check the coherency count.
533 */
534
535 if (!state->stateful) {
536 /* RFC 3078, sec 8.1. Rekey for every packet. */
537 while (state->ccount != ccount) {
538 mppe_rekey(state, 0);
539 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
540 }
541 } else {
542 /* RFC 3078, sec 8.2. */
543 if (!state->discard) {
544 /* normal state */
545 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
546 if (ccount != state->ccount) {
547 /*
548 * (ccount > state->ccount)
549 * Packet loss detected, enter the discard state.
550 * Signal the peer to rekey (by sending a CCP Reset-Request).
551 */
552 state->discard = 1;
553 return DECOMP_ERROR;
554 }
555 } else {
556 /* discard state */
557 if (!flushed) {
558 /* ccp.c will be silent (no additional CCP Reset-Requests). */
559 return DECOMP_ERROR;
560 } else {
561 /* Rekey for every missed "flag" packet. */
562 while ((ccount & ~0xff) !=
563 (state->ccount & ~0xff)) {
564 mppe_rekey(state, 0);
565 state->ccount =
566 (state->ccount +
567 256) % MPPE_CCOUNT_SPACE;
568 }
569
570 /* reset */
571 state->discard = 0;
572 state->ccount = ccount;
573 /*
574 * Another problem with RFC 3078 here. It implies that the
575 * peer need not send a Reset-Ack packet. But RFC 1962
576 * requires it. Hopefully, M$ does send a Reset-Ack; even
577 * though it isn't required for MPPE synchronization, it is
578 * required to reset CCP state.
579 */
580 }
581 }
582 if (flushed)
583 mppe_rekey(state, 0);
584 }
585
586 /*
587 * Fill in the first part of the PPP header. The protocol field
588 * comes from the decrypted data.
589 */
590 obuf[0] = PPP_ADDRESS(ibuf); /* +1 */
591 obuf[1] = PPP_CONTROL(ibuf); /* +1 */
592 obuf += 2;
593 ibuf += PPP_HDRLEN + MPPE_OVHD;
594 isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */
595 /* net osize: isize-4 */
596
597 /*
598 * Decrypt the first byte in order to check if it is
599 * a compressed or uncompressed protocol field.
600 */
601 setup_sg(sg_in, ibuf, 1);
602 setup_sg(sg_out, obuf, 1);
603 if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, 1) != 0) {
604 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
605 return DECOMP_ERROR;
606 }
607
608 /*
609 * Do PFC decompression.
610 * This would be nicer if we were given the actual sk_buff
611 * instead of a char *.
612 */
613 if ((obuf[0] & 0x01) != 0) {
614 obuf[1] = obuf[0];
615 obuf[0] = 0;
616 obuf++;
617 osize++;
618 }
619
620 /* And finally, decrypt the rest of the packet. */
621 setup_sg(sg_in, ibuf + 1, isize - 1);
622 setup_sg(sg_out, obuf + 1, osize - 1);
623 if (crypto_cipher_decrypt(state->arc4, sg_out, sg_in, isize - 1) != 0) {
624 printk(KERN_DEBUG "crypto_cypher_decrypt failed\n");
625 return DECOMP_ERROR;
626 }
627
628 state->stats.unc_bytes += osize;
629 state->stats.unc_packets++;
630 state->stats.comp_bytes += isize;
631 state->stats.comp_packets++;
632
633 /* good packet credit */
634 state->sanity_errors >>= 1;
635
636 return osize;
637}
638
639/*
640 * Incompressible data has arrived (this should never happen!).
641 * We should probably drop the link if the protocol is in the range
642 * of what should be encrypted. At the least, we should drop this
643 * packet. (How to do this?)
644 */
645static void mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
646{
647 struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
648
649 if (state->debug &&
650 (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
651 printk(KERN_DEBUG
652 "mppe_incomp[%d]: incompressible (unencrypted) data! "
653 "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
654
655 state->stats.inc_bytes += icnt;
656 state->stats.inc_packets++;
657 state->stats.unc_bytes += icnt;
658 state->stats.unc_packets++;
659}
660
661/*************************************************************
662 * Module interface table
663 *************************************************************/
664
665/*
666 * Procedures exported to if_ppp.c.
667 */
668static struct compressor ppp_mppe = {
669 .compress_proto = CI_MPPE,
670 .comp_alloc = mppe_alloc,
671 .comp_free = mppe_free,
672 .comp_init = mppe_comp_init,
673 .comp_reset = mppe_comp_reset,
674 .compress = mppe_compress,
675 .comp_stat = mppe_comp_stats,
676 .decomp_alloc = mppe_alloc,
677 .decomp_free = mppe_free,
678 .decomp_init = mppe_decomp_init,
679 .decomp_reset = mppe_decomp_reset,
680 .decompress = mppe_decompress,
681 .incomp = mppe_incomp,
682 .decomp_stat = mppe_comp_stats,
683 .owner = THIS_MODULE,
684 .comp_extra = MPPE_PAD,
685};
686
687/*
688 * ppp_mppe_init()
689 *
690 * Prior to allowing load, try to load the arc4 and sha1 crypto
691 * libraries. The actual use will be allocated later, but
692 * this way the module will fail to insmod if they aren't available.
693 */
694
695static int __init ppp_mppe_init(void)
696{
697 int answer;
698 if (!(crypto_alg_available("arc4", 0) &&
699 crypto_alg_available("sha1", 0)))
700 return -ENODEV;
701
702 sha_pad = kmalloc(sizeof(struct sha_pad), GFP_KERNEL);
703 if (!sha_pad)
704 return -ENOMEM;
705 sha_pad_init(sha_pad);
706
707 answer = ppp_register_compressor(&ppp_mppe);
708
709 if (answer == 0)
710 printk(KERN_INFO "PPP MPPE Compression module registered\n");
711 else
712 kfree(sha_pad);
713
714 return answer;
715}
716
717static void __exit ppp_mppe_cleanup(void)
718{
719 ppp_unregister_compressor(&ppp_mppe);
720 kfree(sha_pad);
721}
722
723module_init(ppp_mppe_init);
724module_exit(ppp_mppe_cleanup);
diff --git a/drivers/net/ppp_mppe.h b/drivers/net/ppp_mppe.h
new file mode 100644
index 000000000000..7a14e058c668
--- /dev/null
+++ b/drivers/net/ppp_mppe.h
@@ -0,0 +1,86 @@
1#define MPPE_PAD 4 /* MPPE growth per frame */
2#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */
3
4/* option bits for ccp_options.mppe */
5#define MPPE_OPT_40 0x01 /* 40 bit */
6#define MPPE_OPT_128 0x02 /* 128 bit */
7#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */
8/* unsupported opts */
9#define MPPE_OPT_56 0x08 /* 56 bit */
10#define MPPE_OPT_MPPC 0x10 /* MPPC compression */
11#define MPPE_OPT_D 0x20 /* Unknown */
12#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
13#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */
14
15/*
16 * This is not nice ... the alternative is a bitfield struct though.
17 * And unfortunately, we cannot share the same bits for the option
18 * names above since C and H are the same bit. We could do a u_int32
19 * but then we have to do a htonl() all the time and/or we still need
20 * to know which octet is which.
21 */
22#define MPPE_C_BIT 0x01 /* MPPC */
23#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */
24#define MPPE_L_BIT 0x20 /* 40-bit */
25#define MPPE_S_BIT 0x40 /* 128-bit */
26#define MPPE_M_BIT 0x80 /* 56-bit, not supported */
27#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */
28
29/* Does not include H bit; used for least significant octet only. */
30#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
31
32/* Build a CI from mppe opts (see RFC 3078) */
33#define MPPE_OPTS_TO_CI(opts, ci) \
34 do { \
35 u_char *ptr = ci; /* u_char[4] */ \
36 \
37 /* H bit */ \
38 if (opts & MPPE_OPT_STATEFUL) \
39 *ptr++ = 0x0; \
40 else \
41 *ptr++ = MPPE_H_BIT; \
42 *ptr++ = 0; \
43 *ptr++ = 0; \
44 \
45 /* S,L bits */ \
46 *ptr = 0; \
47 if (opts & MPPE_OPT_128) \
48 *ptr |= MPPE_S_BIT; \
49 if (opts & MPPE_OPT_40) \
50 *ptr |= MPPE_L_BIT; \
51 /* M,D,C bits not supported */ \
52 } while (/* CONSTCOND */ 0)
53
54/* The reverse of the above */
55#define MPPE_CI_TO_OPTS(ci, opts) \
56 do { \
57 u_char *ptr = ci; /* u_char[4] */ \
58 \
59 opts = 0; \
60 \
61 /* H bit */ \
62 if (!(ptr[0] & MPPE_H_BIT)) \
63 opts |= MPPE_OPT_STATEFUL; \
64 \
65 /* S,L bits */ \
66 if (ptr[3] & MPPE_S_BIT) \
67 opts |= MPPE_OPT_128; \
68 if (ptr[3] & MPPE_L_BIT) \
69 opts |= MPPE_OPT_40; \
70 \
71 /* M,D,C bits */ \
72 if (ptr[3] & MPPE_M_BIT) \
73 opts |= MPPE_OPT_56; \
74 if (ptr[3] & MPPE_D_BIT) \
75 opts |= MPPE_OPT_D; \
76 if (ptr[3] & MPPE_C_BIT) \
77 opts |= MPPE_OPT_MPPC; \
78 \
79 /* Other bits */ \
80 if (ptr[0] & ~MPPE_H_BIT) \
81 opts |= MPPE_OPT_UNKNOWN; \
82 if (ptr[1] || ptr[2]) \
83 opts |= MPPE_OPT_UNKNOWN; \
84 if (ptr[3] & ~MPPE_ALL_BITS) \
85 opts |= MPPE_OPT_UNKNOWN; \
86 } while (/* CONSTCOND */ 0)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 9c4935407f26..e57df8dfe6b4 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -55,7 +55,6 @@
55#include <linux/timex.h> 55#include <linux/timex.h>
56#include <linux/sched.h> 56#include <linux/sched.h>
57#include <linux/ethtool.h> 57#include <linux/ethtool.h>
58#include <linux/version.h>
59#include <linux/workqueue.h> 58#include <linux/workqueue.h>
60#include <linux/if_vlan.h> 59#include <linux/if_vlan.h>
61 60
@@ -1532,7 +1531,7 @@ static int init_nic(struct s2io_nic *nic)
1532#define LINK_UP_DOWN_INTERRUPT 1 1531#define LINK_UP_DOWN_INTERRUPT 1
1533#define MAC_RMAC_ERR_TIMER 2 1532#define MAC_RMAC_ERR_TIMER 2
1534 1533
1535int s2io_link_fault_indication(nic_t *nic) 1534static int s2io_link_fault_indication(nic_t *nic)
1536{ 1535{
1537 if (nic->intr_type != INTA) 1536 if (nic->intr_type != INTA)
1538 return MAC_RMAC_ERR_TIMER; 1537 return MAC_RMAC_ERR_TIMER;
@@ -1864,7 +1863,7 @@ static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag)
1864 * 1863 *
1865 */ 1864 */
1866 1865
1867void fix_mac_address(nic_t * sp) 1866static void fix_mac_address(nic_t * sp)
1868{ 1867{
1869 XENA_dev_config_t __iomem *bar0 = sp->bar0; 1868 XENA_dev_config_t __iomem *bar0 = sp->bar0;
1870 u64 val64; 1869 u64 val64;
@@ -2110,7 +2109,7 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
2110{ 2109{
2111 struct net_device *dev = nic->dev; 2110 struct net_device *dev = nic->dev;
2112 struct sk_buff *frag_list; 2111 struct sk_buff *frag_list;
2113 u64 tmp; 2112 void *tmp;
2114 2113
2115 /* Buffer-1 receives L3/L4 headers */ 2114 /* Buffer-1 receives L3/L4 headers */
2116 ((RxD3_t*)rxdp)->Buffer1_ptr = pci_map_single 2115 ((RxD3_t*)rxdp)->Buffer1_ptr = pci_map_single
@@ -2125,11 +2124,9 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
2125 } 2124 }
2126 frag_list = skb_shinfo(skb)->frag_list; 2125 frag_list = skb_shinfo(skb)->frag_list;
2127 frag_list->next = NULL; 2126 frag_list->next = NULL;
2128 tmp = (u64) frag_list->data; 2127 tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
2129 tmp += ALIGN_SIZE; 2128 frag_list->data = tmp;
2130 tmp &= ~ALIGN_SIZE; 2129 frag_list->tail = tmp;
2131 frag_list->data = (void *) tmp;
2132 frag_list->tail = (void *) tmp;
2133 2130
2134 /* Buffer-2 receives L4 data payload */ 2131 /* Buffer-2 receives L4 data payload */
2135 ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev, 2132 ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev,
@@ -2162,7 +2159,7 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
2162 * SUCCESS on success or an appropriate -ve value on failure. 2159 * SUCCESS on success or an appropriate -ve value on failure.
2163 */ 2160 */
2164 2161
2165int fill_rx_buffers(struct s2io_nic *nic, int ring_no) 2162static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
2166{ 2163{
2167 struct net_device *dev = nic->dev; 2164 struct net_device *dev = nic->dev;
2168 struct sk_buff *skb; 2165 struct sk_buff *skb;
@@ -2833,7 +2830,7 @@ static void alarm_intr_handler(struct s2io_nic *nic)
2833 * SUCCESS on success and FAILURE on failure. 2830 * SUCCESS on success and FAILURE on failure.
2834 */ 2831 */
2835 2832
2836int wait_for_cmd_complete(nic_t * sp) 2833static int wait_for_cmd_complete(nic_t * sp)
2837{ 2834{
2838 XENA_dev_config_t __iomem *bar0 = sp->bar0; 2835 XENA_dev_config_t __iomem *bar0 = sp->bar0;
2839 int ret = FAILURE, cnt = 0; 2836 int ret = FAILURE, cnt = 0;
@@ -3079,7 +3076,7 @@ int s2io_set_swapper(nic_t * sp)
3079 return SUCCESS; 3076 return SUCCESS;
3080} 3077}
3081 3078
3082int wait_for_msix_trans(nic_t *nic, int i) 3079static int wait_for_msix_trans(nic_t *nic, int i)
3083{ 3080{
3084 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 3081 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
3085 u64 val64; 3082 u64 val64;
@@ -3118,7 +3115,7 @@ void restore_xmsi_data(nic_t *nic)
3118 } 3115 }
3119} 3116}
3120 3117
3121void store_xmsi_data(nic_t *nic) 3118static void store_xmsi_data(nic_t *nic)
3122{ 3119{
3123 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 3120 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
3124 u64 val64, addr, data; 3121 u64 val64, addr, data;
@@ -3290,7 +3287,7 @@ int s2io_enable_msi_x(nic_t *nic)
3290 * file on failure. 3287 * file on failure.
3291 */ 3288 */
3292 3289
3293int s2io_open(struct net_device *dev) 3290static int s2io_open(struct net_device *dev)
3294{ 3291{
3295 nic_t *sp = dev->priv; 3292 nic_t *sp = dev->priv;
3296 int err = 0; 3293 int err = 0;
@@ -3420,7 +3417,7 @@ hw_init_failed:
3420 * file on failure. 3417 * file on failure.
3421 */ 3418 */
3422 3419
3423int s2io_close(struct net_device *dev) 3420static int s2io_close(struct net_device *dev)
3424{ 3421{
3425 nic_t *sp = dev->priv; 3422 nic_t *sp = dev->priv;
3426 int i; 3423 int i;
@@ -3469,7 +3466,7 @@ int s2io_close(struct net_device *dev)
3469 * 0 on success & 1 on failure. 3466 * 0 on success & 1 on failure.
3470 */ 3467 */
3471 3468
3472int s2io_xmit(struct sk_buff *skb, struct net_device *dev) 3469static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
3473{ 3470{
3474 nic_t *sp = dev->priv; 3471 nic_t *sp = dev->priv;
3475 u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; 3472 u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
@@ -3915,7 +3912,7 @@ static void s2io_updt_stats(nic_t *sp)
3915 * pointer to the updated net_device_stats structure. 3912 * pointer to the updated net_device_stats structure.
3916 */ 3913 */
3917 3914
3918struct net_device_stats *s2io_get_stats(struct net_device *dev) 3915static struct net_device_stats *s2io_get_stats(struct net_device *dev)
3919{ 3916{
3920 nic_t *sp = dev->priv; 3917 nic_t *sp = dev->priv;
3921 mac_info_t *mac_control; 3918 mac_info_t *mac_control;
@@ -5108,19 +5105,20 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
5108 tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; 5105 tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs;
5109} 5106}
5110 5107
5111int s2io_ethtool_get_regs_len(struct net_device *dev) 5108static int s2io_ethtool_get_regs_len(struct net_device *dev)
5112{ 5109{
5113 return (XENA_REG_SPACE); 5110 return (XENA_REG_SPACE);
5114} 5111}
5115 5112
5116 5113
5117u32 s2io_ethtool_get_rx_csum(struct net_device * dev) 5114static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
5118{ 5115{
5119 nic_t *sp = dev->priv; 5116 nic_t *sp = dev->priv;
5120 5117
5121 return (sp->rx_csum); 5118 return (sp->rx_csum);
5122} 5119}
5123int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) 5120
5121static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
5124{ 5122{
5125 nic_t *sp = dev->priv; 5123 nic_t *sp = dev->priv;
5126 5124
@@ -5131,17 +5129,19 @@ int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
5131 5129
5132 return 0; 5130 return 0;
5133} 5131}
5134int s2io_get_eeprom_len(struct net_device *dev) 5132
5133static int s2io_get_eeprom_len(struct net_device *dev)
5135{ 5134{
5136 return (XENA_EEPROM_SPACE); 5135 return (XENA_EEPROM_SPACE);
5137} 5136}
5138 5137
5139int s2io_ethtool_self_test_count(struct net_device *dev) 5138static int s2io_ethtool_self_test_count(struct net_device *dev)
5140{ 5139{
5141 return (S2IO_TEST_LEN); 5140 return (S2IO_TEST_LEN);
5142} 5141}
5143void s2io_ethtool_get_strings(struct net_device *dev, 5142
5144 u32 stringset, u8 * data) 5143static void s2io_ethtool_get_strings(struct net_device *dev,
5144 u32 stringset, u8 * data)
5145{ 5145{
5146 switch (stringset) { 5146 switch (stringset) {
5147 case ETH_SS_TEST: 5147 case ETH_SS_TEST:
@@ -5157,7 +5157,7 @@ static int s2io_ethtool_get_stats_count(struct net_device *dev)
5157 return (S2IO_STAT_LEN); 5157 return (S2IO_STAT_LEN);
5158} 5158}
5159 5159
5160int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) 5160static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
5161{ 5161{
5162 if (data) 5162 if (data)
5163 dev->features |= NETIF_F_IP_CSUM; 5163 dev->features |= NETIF_F_IP_CSUM;
@@ -5210,7 +5210,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
5210 * function always return EOPNOTSUPPORTED 5210 * function always return EOPNOTSUPPORTED
5211 */ 5211 */
5212 5212
5213int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 5213static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5214{ 5214{
5215 return -EOPNOTSUPP; 5215 return -EOPNOTSUPP;
5216} 5216}
@@ -5226,7 +5226,7 @@ int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
5226 * file on failure. 5226 * file on failure.
5227 */ 5227 */
5228 5228
5229int s2io_change_mtu(struct net_device *dev, int new_mtu) 5229static int s2io_change_mtu(struct net_device *dev, int new_mtu)
5230{ 5230{
5231 nic_t *sp = dev->priv; 5231 nic_t *sp = dev->priv;
5232 5232
diff --git a/drivers/net/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
index 308440bd0e12..91b8d4f45904 100644
--- a/drivers/net/sk98lin/h/skdrv1st.h
+++ b/drivers/net/sk98lin/h/skdrv1st.h
@@ -39,9 +39,6 @@
39#ifndef __INC_SKDRV1ST_H 39#ifndef __INC_SKDRV1ST_H
40#define __INC_SKDRV1ST_H 40#define __INC_SKDRV1ST_H
41 41
42/* Check kernel version */
43#include <linux/version.h>
44
45typedef struct s_AC SK_AC; 42typedef struct s_AC SK_AC;
46 43
47/* Set card versions */ 44/* Set card versions */
diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
index 4c56b8d8221b..e5d6d95960c7 100644
--- a/drivers/net/sk_mca.c
+++ b/drivers/net/sk_mca.c
@@ -93,7 +93,6 @@ History:
93#include <linux/mca-legacy.h> 93#include <linux/mca-legacy.h>
94#include <linux/init.h> 94#include <linux/init.h>
95#include <linux/module.h> 95#include <linux/module.h>
96#include <linux/version.h>
97#include <linux/netdevice.h> 96#include <linux/netdevice.h>
98#include <linux/etherdevice.h> 97#include <linux/etherdevice.h>
99#include <linux/skbuff.h> 98#include <linux/skbuff.h>
diff --git a/drivers/net/sk_mca.h b/drivers/net/sk_mca.h
index 7e7c99582746..d6fa1823dfa6 100644
--- a/drivers/net/sk_mca.h
+++ b/drivers/net/sk_mca.h
@@ -1,5 +1,3 @@
1#include <linux/version.h>
2
3#ifndef _SK_MCA_INCLUDE_ 1#ifndef _SK_MCA_INCLUDE_
4#define _SK_MCA_INCLUDE_ 2#define _SK_MCA_INCLUDE_
5 3
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 572f121b1f4e..596c93b12daa 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -37,12 +37,13 @@
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/crc32.h> 38#include <linux/crc32.h>
39#include <linux/dma-mapping.h> 39#include <linux/dma-mapping.h>
40#include <linux/mii.h>
40#include <asm/irq.h> 41#include <asm/irq.h>
41 42
42#include "skge.h" 43#include "skge.h"
43 44
44#define DRV_NAME "skge" 45#define DRV_NAME "skge"
45#define DRV_VERSION "1.1" 46#define DRV_VERSION "1.2"
46#define PFX DRV_NAME " " 47#define PFX DRV_NAME " "
47 48
48#define DEFAULT_TX_RING_SIZE 128 49#define DEFAULT_TX_RING_SIZE 128
@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
88static int skge_up(struct net_device *dev); 89static int skge_up(struct net_device *dev);
89static int skge_down(struct net_device *dev); 90static int skge_down(struct net_device *dev);
90static void skge_tx_clean(struct skge_port *skge); 91static void skge_tx_clean(struct skge_port *skge);
91static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 92static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
92static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); 93static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
93static void genesis_get_stats(struct skge_port *skge, u64 *data); 94static void genesis_get_stats(struct skge_port *skge, u64 *data);
94static void yukon_get_stats(struct skge_port *skge, u64 *data); 95static void yukon_get_stats(struct skge_port *skge, u64 *data);
95static void yukon_init(struct skge_hw *hw, int port); 96static void yukon_init(struct skge_hw *hw, int port);
@@ -129,7 +130,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
129 regs->len - B3_RI_WTO_R1); 130 regs->len - B3_RI_WTO_R1);
130} 131}
131 132
132/* Wake on Lan only supported on Yukon chps with rev 1 or above */ 133/* Wake on Lan only supported on Yukon chips with rev 1 or above */
133static int wol_supported(const struct skge_hw *hw) 134static int wol_supported(const struct skge_hw *hw)
134{ 135{
135 return !((hw->chip_id == CHIP_ID_GENESIS || 136 return !((hw->chip_id == CHIP_ID_GENESIS ||
@@ -169,8 +170,8 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
169 return 0; 170 return 0;
170} 171}
171 172
172/* Determine supported/adverised modes based on hardware. 173/* Determine supported/advertised modes based on hardware.
173 * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx 174 * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
174 */ 175 */
175static u32 skge_supported_modes(const struct skge_hw *hw) 176static u32 skge_supported_modes(const struct skge_hw *hw)
176{ 177{
@@ -531,13 +532,13 @@ static inline u32 hwkhz(const struct skge_hw *hw)
531 return 78215; /* or: 78.125 MHz */ 532 return 78215; /* or: 78.125 MHz */
532} 533}
533 534
534/* Chip hz to microseconds */ 535/* Chip HZ to microseconds */
535static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks) 536static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
536{ 537{
537 return (ticks * 1000) / hwkhz(hw); 538 return (ticks * 1000) / hwkhz(hw);
538} 539}
539 540
540/* Microseconds to chip hz */ 541/* Microseconds to chip HZ */
541static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec) 542static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
542{ 543{
543 return hwkhz(hw) * usec / 1000; 544 return hwkhz(hw) * usec / 1000;
@@ -883,32 +884,37 @@ static void skge_link_down(struct skge_port *skge)
883 printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); 884 printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
884} 885}
885 886
886static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) 887static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
887{ 888{
888 int i; 889 int i;
889 u16 v;
890 890
891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); 891 xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
892 v = xm_read16(hw, port, XM_PHY_DATA); 892 xm_read16(hw, port, XM_PHY_DATA);
893 893
894 /* Need to wait for external PHY */ 894 /* Need to wait for external PHY */
895 for (i = 0; i < PHY_RETRIES; i++) { 895 for (i = 0; i < PHY_RETRIES; i++) {
896 udelay(1); 896 udelay(1);
897 if (xm_read16(hw, port, XM_MMU_CMD) 897 if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
898 & XM_MMU_PHY_RDY)
899 goto ready; 898 goto ready;
900 } 899 }
901 900
902 printk(KERN_WARNING PFX "%s: phy read timed out\n", 901 return -ETIMEDOUT;
903 hw->dev[port]->name);
904 return 0;
905 ready: 902 ready:
906 v = xm_read16(hw, port, XM_PHY_DATA); 903 *val = xm_read16(hw, port, XM_PHY_DATA);
907 904
905 return 0;
906}
907
908static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
909{
910 u16 v = 0;
911 if (__xm_phy_read(hw, port, reg, &v))
912 printk(KERN_WARNING PFX "%s: phy read timed out\n",
913 hw->dev[port]->name);
908 return v; 914 return v;
909} 915}
910 916
911static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) 917static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
912{ 918{
913 int i; 919 int i;
914 920
@@ -918,19 +924,11 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
918 goto ready; 924 goto ready;
919 udelay(1); 925 udelay(1);
920 } 926 }
921 printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", 927 return -EIO;
922 hw->dev[port]->name);
923
924 928
925 ready: 929 ready:
926 xm_write16(hw, port, XM_PHY_DATA, val); 930 xm_write16(hw, port, XM_PHY_DATA, val);
927 for (i = 0; i < PHY_RETRIES; i++) { 931 return 0;
928 udelay(1);
929 if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
930 return;
931 }
932 printk(KERN_WARNING PFX "%s: phy write timed out\n",
933 hw->dev[port]->name);
934} 932}
935 933
936static void genesis_init(struct skge_hw *hw) 934static void genesis_init(struct skge_hw *hw)
@@ -1165,7 +1163,7 @@ static void bcom_phy_init(struct skge_port *skge, int jumbo)
1165 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); 1163 xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
1166 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); 1164 xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
1167 1165
1168 /* Use link status change interrrupt */ 1166 /* Use link status change interrupt */
1169 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); 1167 xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
1170 1168
1171 bcom_check_link(hw, port); 1169 bcom_check_link(hw, port);
@@ -1205,7 +1203,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1205 skge_write32(hw, B2_GP_IO, r); 1203 skge_write32(hw, B2_GP_IO, r);
1206 skge_read32(hw, B2_GP_IO); 1204 skge_read32(hw, B2_GP_IO);
1207 1205
1208 /* Enable GMII interfac */ 1206 /* Enable GMII interface */
1209 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); 1207 xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
1210 1208
1211 bcom_phy_init(skge, jumbo); 1209 bcom_phy_init(skge, jumbo);
@@ -1256,7 +1254,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port)
1256 * that jumbo frames larger than 8192 bytes will be 1254 * that jumbo frames larger than 8192 bytes will be
1257 * truncated. Disabling all bad frame filtering causes 1255 * truncated. Disabling all bad frame filtering causes
1258 * the RX FIFO to operate in streaming mode, in which 1256 * the RX FIFO to operate in streaming mode, in which
1259 * case the XMAC will start transfering frames out of the 1257 * case the XMAC will start transferring frames out of the
1260 * RX FIFO as soon as the FIFO threshold is reached. 1258 * RX FIFO as soon as the FIFO threshold is reached.
1261 */ 1259 */
1262 xm_write32(hw, port, XM_MODE, XM_DEF_MODE); 1260 xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
@@ -1323,7 +1321,7 @@ static void genesis_stop(struct skge_port *skge)
1323 port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2); 1321 port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
1324 1322
1325 /* 1323 /*
1326 * If the transfer stucks at the MAC the STOP command will not 1324 * If the transfer sticks at the MAC the STOP command will not
1327 * terminate if we don't flush the XMAC's transmit FIFO ! 1325 * terminate if we don't flush the XMAC's transmit FIFO !
1328 */ 1326 */
1329 xm_write32(hw, port, XM_MODE, 1327 xm_write32(hw, port, XM_MODE,
@@ -1400,42 +1398,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port)
1400 } 1398 }
1401} 1399}
1402 1400
1403static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
1404{
1405 int i;
1406
1407 gma_write16(hw, port, GM_SMI_DATA, val);
1408 gma_write16(hw, port, GM_SMI_CTRL,
1409 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
1410 for (i = 0; i < PHY_RETRIES; i++) {
1411 udelay(1);
1412
1413 if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
1414 break;
1415 }
1416}
1417
1418static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
1419{
1420 int i;
1421
1422 gma_write16(hw, port, GM_SMI_CTRL,
1423 GM_SMI_CT_PHY_AD(hw->phy_addr)
1424 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
1425
1426 for (i = 0; i < PHY_RETRIES; i++) {
1427 udelay(1);
1428 if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
1429 goto ready;
1430 }
1431
1432 printk(KERN_WARNING PFX "%s: phy read timeout\n",
1433 hw->dev[port]->name);
1434 return 0;
1435 ready:
1436 return gma_read16(hw, port, GM_SMI_DATA);
1437}
1438
1439static void genesis_link_up(struct skge_port *skge) 1401static void genesis_link_up(struct skge_port *skge)
1440{ 1402{
1441 struct skge_hw *hw = skge->hw; 1403 struct skge_hw *hw = skge->hw;
@@ -1549,7 +1511,55 @@ static inline void bcom_phy_intr(struct skge_port *skge)
1549 1511
1550} 1512}
1551 1513
1552/* Marvell Phy Initailization */ 1514static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
1515{
1516 int i;
1517
1518 gma_write16(hw, port, GM_SMI_DATA, val);
1519 gma_write16(hw, port, GM_SMI_CTRL,
1520 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
1521 for (i = 0; i < PHY_RETRIES; i++) {
1522 udelay(1);
1523
1524 if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
1525 return 0;
1526 }
1527
1528 printk(KERN_WARNING PFX "%s: phy write timeout\n",
1529 hw->dev[port]->name);
1530 return -EIO;
1531}
1532
1533static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
1534{
1535 int i;
1536
1537 gma_write16(hw, port, GM_SMI_CTRL,
1538 GM_SMI_CT_PHY_AD(hw->phy_addr)
1539 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
1540
1541 for (i = 0; i < PHY_RETRIES; i++) {
1542 udelay(1);
1543 if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
1544 goto ready;
1545 }
1546
1547 return -ETIMEDOUT;
1548 ready:
1549 *val = gma_read16(hw, port, GM_SMI_DATA);
1550 return 0;
1551}
1552
1553static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
1554{
1555 u16 v = 0;
1556 if (__gm_phy_read(hw, port, reg, &v))
1557 printk(KERN_WARNING PFX "%s: phy read timeout\n",
1558 hw->dev[port]->name);
1559 return v;
1560}
1561
1562/* Marvell Phy Initialization */
1553static void yukon_init(struct skge_hw *hw, int port) 1563static void yukon_init(struct skge_hw *hw, int port)
1554{ 1564{
1555 struct skge_port *skge = netdev_priv(hw->dev[port]); 1565 struct skge_port *skge = netdev_priv(hw->dev[port]);
@@ -1794,6 +1804,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port)
1794 skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); 1804 skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
1795} 1805}
1796 1806
1807/* Go into power down mode */
1808static void yukon_suspend(struct skge_hw *hw, int port)
1809{
1810 u16 ctrl;
1811
1812 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
1813 ctrl |= PHY_M_PC_POL_R_DIS;
1814 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
1815
1816 ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
1817 ctrl |= PHY_CT_RESET;
1818 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
1819
1820 /* switch IEEE compatible power down mode on */
1821 ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
1822 ctrl |= PHY_CT_PDOWN;
1823 gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
1824}
1825
1797static void yukon_stop(struct skge_port *skge) 1826static void yukon_stop(struct skge_port *skge)
1798{ 1827{
1799 struct skge_hw *hw = skge->hw; 1828 struct skge_hw *hw = skge->hw;
@@ -1807,14 +1836,7 @@ static void yukon_stop(struct skge_port *skge)
1807 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA)); 1836 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
1808 gma_read16(hw, port, GM_GP_CTRL); 1837 gma_read16(hw, port, GM_GP_CTRL);
1809 1838
1810 if (hw->chip_id == CHIP_ID_YUKON_LITE && 1839 yukon_suspend(hw, port);
1811 hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
1812 u32 io = skge_read32(hw, B2_GP_IO);
1813
1814 io |= GP_DIR_9 | GP_IO_9;
1815 skge_write32(hw, B2_GP_IO, io);
1816 skge_read32(hw, B2_GP_IO);
1817 }
1818 1840
1819 /* set GPHY Control reset */ 1841 /* set GPHY Control reset */
1820 skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); 1842 skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
@@ -1997,6 +2019,51 @@ static void yukon_phy_intr(struct skge_port *skge)
1997 /* XXX restart autonegotiation? */ 2019 /* XXX restart autonegotiation? */
1998} 2020}
1999 2021
2022/* Basic MII support */
2023static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
2024{
2025 struct mii_ioctl_data *data = if_mii(ifr);
2026 struct skge_port *skge = netdev_priv(dev);
2027 struct skge_hw *hw = skge->hw;
2028 int err = -EOPNOTSUPP;
2029
2030 if (!netif_running(dev))
2031 return -ENODEV; /* Phy still in reset */
2032
2033 switch(cmd) {
2034 case SIOCGMIIPHY:
2035 data->phy_id = hw->phy_addr;
2036
2037 /* fallthru */
2038 case SIOCGMIIREG: {
2039 u16 val = 0;
2040 spin_lock_bh(&hw->phy_lock);
2041 if (hw->chip_id == CHIP_ID_GENESIS)
2042 err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
2043 else
2044 err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
2045 spin_unlock_bh(&hw->phy_lock);
2046 data->val_out = val;
2047 break;
2048 }
2049
2050 case SIOCSMIIREG:
2051 if (!capable(CAP_NET_ADMIN))
2052 return -EPERM;
2053
2054 spin_lock_bh(&hw->phy_lock);
2055 if (hw->chip_id == CHIP_ID_GENESIS)
2056 err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
2057 data->val_in);
2058 else
2059 err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
2060 data->val_in);
2061 spin_unlock_bh(&hw->phy_lock);
2062 break;
2063 }
2064 return err;
2065}
2066
2000static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len) 2067static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
2001{ 2068{
2002 u32 end; 2069 u32 end;
@@ -2089,7 +2156,7 @@ static int skge_up(struct net_device *dev)
2089 hw->intr_mask |= portirqmask[port]; 2156 hw->intr_mask |= portirqmask[port];
2090 skge_write32(hw, B0_IMSK, hw->intr_mask); 2157 skge_write32(hw, B0_IMSK, hw->intr_mask);
2091 2158
2092 /* Initialze MAC */ 2159 /* Initialize MAC */
2093 spin_lock_bh(&hw->phy_lock); 2160 spin_lock_bh(&hw->phy_lock);
2094 if (hw->chip_id == CHIP_ID_GENESIS) 2161 if (hw->chip_id == CHIP_ID_GENESIS)
2095 genesis_mac_init(hw, port); 2162 genesis_mac_init(hw, port);
@@ -2409,7 +2476,7 @@ static void yukon_set_multicast(struct net_device *dev)
2409 reg = gma_read16(hw, port, GM_RX_CTRL); 2476 reg = gma_read16(hw, port, GM_RX_CTRL);
2410 reg |= GM_RXCR_UCF_ENA; 2477 reg |= GM_RXCR_UCF_ENA;
2411 2478
2412 if (dev->flags & IFF_PROMISC) /* promiscious */ 2479 if (dev->flags & IFF_PROMISC) /* promiscuous */
2413 reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); 2480 reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
2414 else if (dev->flags & IFF_ALLMULTI) /* all multicast */ 2481 else if (dev->flags & IFF_ALLMULTI) /* all multicast */
2415 memset(filter, 0xff, sizeof(filter)); 2482 memset(filter, 0xff, sizeof(filter));
@@ -2560,7 +2627,7 @@ static int skge_poll(struct net_device *dev, int *budget)
2560 unsigned int to_do = min(dev->quota, *budget); 2627 unsigned int to_do = min(dev->quota, *budget);
2561 unsigned int work_done = 0; 2628 unsigned int work_done = 0;
2562 2629
2563 for (e = ring->to_clean; work_done < to_do; e = e->next) { 2630 for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) {
2564 struct skge_rx_desc *rd = e->desc; 2631 struct skge_rx_desc *rd = e->desc;
2565 struct sk_buff *skb; 2632 struct sk_buff *skb;
2566 u32 control; 2633 u32 control;
@@ -2593,11 +2660,11 @@ static int skge_poll(struct net_device *dev, int *budget)
2593 if (work_done >= to_do) 2660 if (work_done >= to_do)
2594 return 1; /* not done */ 2661 return 1; /* not done */
2595 2662
2596 local_irq_disable(); 2663 netif_rx_complete(dev);
2597 __netif_rx_complete(dev);
2598 hw->intr_mask |= portirqmask[skge->port]; 2664 hw->intr_mask |= portirqmask[skge->port];
2599 skge_write32(hw, B0_IMSK, hw->intr_mask); 2665 skge_write32(hw, B0_IMSK, hw->intr_mask);
2600 local_irq_enable(); 2666 skge_read32(hw, B0_IMSK);
2667
2601 return 0; 2668 return 0;
2602} 2669}
2603 2670
@@ -2609,7 +2676,7 @@ static inline void skge_tx_intr(struct net_device *dev)
2609 struct skge_element *e; 2676 struct skge_element *e;
2610 2677
2611 spin_lock(&skge->tx_lock); 2678 spin_lock(&skge->tx_lock);
2612 for (e = ring->to_clean; e != ring->to_use; e = e->next) { 2679 for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) {
2613 struct skge_tx_desc *td = e->desc; 2680 struct skge_tx_desc *td = e->desc;
2614 u32 control; 2681 u32 control;
2615 2682
@@ -2732,7 +2799,7 @@ static void skge_error_irq(struct skge_hw *hw)
2732} 2799}
2733 2800
2734/* 2801/*
2735 * Interrrupt from PHY are handled in tasklet (soft irq) 2802 * Interrupt from PHY are handled in tasklet (soft irq)
2736 * because accessing phy registers requires spin wait which might 2803 * because accessing phy registers requires spin wait which might
2737 * cause excess interrupt latency. 2804 * cause excess interrupt latency.
2738 */ 2805 */
@@ -2762,6 +2829,14 @@ static void skge_extirq(unsigned long data)
2762 local_irq_enable(); 2829 local_irq_enable();
2763} 2830}
2764 2831
2832static inline void skge_wakeup(struct net_device *dev)
2833{
2834 struct skge_port *skge = netdev_priv(dev);
2835
2836 prefetch(skge->rx_ring.to_clean);
2837 netif_rx_schedule(dev);
2838}
2839
2765static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) 2840static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2766{ 2841{
2767 struct skge_hw *hw = dev_id; 2842 struct skge_hw *hw = dev_id;
@@ -2773,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
2773 status &= hw->intr_mask; 2848 status &= hw->intr_mask;
2774 if (status & IS_R1_F) { 2849 if (status & IS_R1_F) {
2775 hw->intr_mask &= ~IS_R1_F; 2850 hw->intr_mask &= ~IS_R1_F;
2776 netif_rx_schedule(hw->dev[0]); 2851 skge_wakeup(hw->dev[0]);
2777 } 2852 }
2778 2853
2779 if (status & IS_R2_F) { 2854 if (status & IS_R2_F) {
2780 hw->intr_mask &= ~IS_R2_F; 2855 hw->intr_mask &= ~IS_R2_F;
2781 netif_rx_schedule(hw->dev[1]); 2856 skge_wakeup(hw->dev[1]);
2782 } 2857 }
2783 2858
2784 if (status & IS_XA1_F) 2859 if (status & IS_XA1_F)
@@ -2893,6 +2968,7 @@ static const char *skge_board_name(const struct skge_hw *hw)
2893 */ 2968 */
2894static int skge_reset(struct skge_hw *hw) 2969static int skge_reset(struct skge_hw *hw)
2895{ 2970{
2971 u32 reg;
2896 u16 ctst; 2972 u16 ctst;
2897 u8 t8, mac_cfg, pmd_type, phy_type; 2973 u8 t8, mac_cfg, pmd_type, phy_type;
2898 int i; 2974 int i;
@@ -2971,6 +3047,7 @@ static int skge_reset(struct skge_hw *hw)
2971 /* switch power to VCC (WA for VAUX problem) */ 3047 /* switch power to VCC (WA for VAUX problem) */
2972 skge_write8(hw, B0_POWER_CTRL, 3048 skge_write8(hw, B0_POWER_CTRL,
2973 PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); 3049 PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
3050
2974 /* avoid boards with stuck Hardware error bits */ 3051 /* avoid boards with stuck Hardware error bits */
2975 if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && 3052 if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
2976 (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { 3053 (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
@@ -2978,6 +3055,14 @@ static int skge_reset(struct skge_hw *hw)
2978 hw->intr_mask &= ~IS_HW_ERR; 3055 hw->intr_mask &= ~IS_HW_ERR;
2979 } 3056 }
2980 3057
3058 /* Clear PHY COMA */
3059 skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
3060 pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg);
3061 reg &= ~PCI_PHY_COMA;
3062 pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg);
3063 skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
3064
3065
2981 for (i = 0; i < hw->ports; i++) { 3066 for (i = 0; i < hw->ports; i++) {
2982 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); 3067 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
2983 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); 3068 skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
@@ -3048,6 +3133,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port,
3048 SET_NETDEV_DEV(dev, &hw->pdev->dev); 3133 SET_NETDEV_DEV(dev, &hw->pdev->dev);
3049 dev->open = skge_up; 3134 dev->open = skge_up;
3050 dev->stop = skge_down; 3135 dev->stop = skge_down;
3136 dev->do_ioctl = skge_ioctl;
3051 dev->hard_start_xmit = skge_xmit_frame; 3137 dev->hard_start_xmit = skge_xmit_frame;
3052 dev->get_stats = skge_get_stats; 3138 dev->get_stats = skge_get_stats;
3053 if (hw->chip_id == CHIP_ID_GENESIS) 3139 if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3147,7 +3233,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3147 } 3233 }
3148 3234
3149#ifdef __BIG_ENDIAN 3235#ifdef __BIG_ENDIAN
3150 /* byte swap decriptors in hardware */ 3236 /* byte swap descriptors in hardware */
3151 { 3237 {
3152 u32 reg; 3238 u32 reg;
3153 3239
@@ -3158,14 +3244,13 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3158#endif 3244#endif
3159 3245
3160 err = -ENOMEM; 3246 err = -ENOMEM;
3161 hw = kmalloc(sizeof(*hw), GFP_KERNEL); 3247 hw = kzalloc(sizeof(*hw), GFP_KERNEL);
3162 if (!hw) { 3248 if (!hw) {
3163 printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", 3249 printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
3164 pci_name(pdev)); 3250 pci_name(pdev));
3165 goto err_out_free_regions; 3251 goto err_out_free_regions;
3166 } 3252 }
3167 3253
3168 memset(hw, 0, sizeof(*hw));
3169 hw->pdev = pdev; 3254 hw->pdev = pdev;
3170 spin_lock_init(&hw->phy_lock); 3255 spin_lock_init(&hw->phy_lock);
3171 tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw); 3256 tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);
@@ -3188,7 +3273,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3188 if (err) 3273 if (err)
3189 goto err_out_free_irq; 3274 goto err_out_free_irq;
3190 3275
3191 printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", 3276 printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n",
3192 pci_resource_start(pdev, 0), pdev->irq, 3277 pci_resource_start(pdev, 0), pdev->irq,
3193 skge_board_name(hw), hw->chip_rev); 3278 skge_board_name(hw), hw->chip_rev);
3194 3279
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 72c175b87a5a..ee123c15f545 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -6,6 +6,8 @@
6 6
7/* PCI config registers */ 7/* PCI config registers */
8#define PCI_DEV_REG1 0x40 8#define PCI_DEV_REG1 0x40
9#define PCI_PHY_COMA 0x8000000
10#define PCI_VIO 0x2000000
9#define PCI_DEV_REG2 0x44 11#define PCI_DEV_REG2 0x44
10#define PCI_REV_DESC 0x4 12#define PCI_REV_DESC 0x4
11 13
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index c796f41b4a52..0d765f1733b5 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -2290,7 +2290,6 @@ spider_net_remove(struct pci_dev *pdev)
2290} 2290}
2291 2291
2292static struct pci_driver spider_net_driver = { 2292static struct pci_driver spider_net_driver = {
2293 .owner = THIS_MODULE,
2294 .name = spider_net_driver_name, 2293 .name = spider_net_driver_name,
2295 .id_table = spider_net_pci_tbl, 2294 .id_table = spider_net_pci_tbl,
2296 .probe = spider_net_probe, 2295 .probe = spider_net_probe,
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 38b2b0a3ce96..d167deda9a53 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -147,7 +147,6 @@ TODO: - fix forced speed/duplexing code (broken a long time ago, when
147#define DRV_RELDATE "October 3, 2005" 147#define DRV_RELDATE "October 3, 2005"
148 148
149#include <linux/config.h> 149#include <linux/config.h>
150#include <linux/version.h>
151#include <linux/module.h> 150#include <linux/module.h>
152#include <linux/kernel.h> 151#include <linux/kernel.h>
153#include <linux/pci.h> 152#include <linux/pci.h>
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index a368d08e7d19..82c6b757d306 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -61,7 +61,6 @@
61#include <linux/timer.h> 61#include <linux/timer.h>
62#include <linux/slab.h> 62#include <linux/slab.h>
63#include <linux/interrupt.h> 63#include <linux/interrupt.h>
64#include <linux/version.h>
65#include <linux/string.h> 64#include <linux/string.h>
66#include <linux/wait.h> 65#include <linux/wait.h>
67#include <asm/io.h> 66#include <asm/io.h>
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 849ac88bcccc..340ab4ee4b67 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -47,6 +47,8 @@
47#include <linux/pci.h> 47#include <linux/pci.h>
48#include <asm/uaccess.h> 48#include <asm/uaccess.h>
49 49
50#include "airo.h"
51
50#ifdef CONFIG_PCI 52#ifdef CONFIG_PCI
51static struct pci_device_id card_ids[] = { 53static struct pci_device_id card_ids[] = {
52 { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, }, 54 { 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
@@ -4533,9 +4535,8 @@ static int proc_status_open( struct inode *inode, struct file *file ) {
4533 StatusRid status_rid; 4535 StatusRid status_rid;
4534 int i; 4536 int i;
4535 4537
4536 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4538 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4537 return -ENOMEM; 4539 return -ENOMEM;
4538 memset(file->private_data, 0, sizeof(struct proc_data));
4539 data = (struct proc_data *)file->private_data; 4540 data = (struct proc_data *)file->private_data;
4540 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4541 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4541 kfree (file->private_data); 4542 kfree (file->private_data);
@@ -4613,9 +4614,8 @@ static int proc_stats_rid_open( struct inode *inode,
4613 int i, j; 4614 int i, j;
4614 u32 *vals = stats.vals; 4615 u32 *vals = stats.vals;
4615 4616
4616 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4617 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4617 return -ENOMEM; 4618 return -ENOMEM;
4618 memset(file->private_data, 0, sizeof(struct proc_data));
4619 data = (struct proc_data *)file->private_data; 4619 data = (struct proc_data *)file->private_data;
4620 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) { 4620 if ((data->rbuffer = kmalloc( 4096, GFP_KERNEL )) == NULL) {
4621 kfree (file->private_data); 4621 kfree (file->private_data);
@@ -4879,20 +4879,18 @@ static int proc_config_open( struct inode *inode, struct file *file ) {
4879 struct airo_info *ai = dev->priv; 4879 struct airo_info *ai = dev->priv;
4880 int i; 4880 int i;
4881 4881
4882 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 4882 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
4883 return -ENOMEM; 4883 return -ENOMEM;
4884 memset(file->private_data, 0, sizeof(struct proc_data));
4885 data = (struct proc_data *)file->private_data; 4884 data = (struct proc_data *)file->private_data;
4886 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4885 if ((data->rbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) {
4887 kfree (file->private_data); 4886 kfree (file->private_data);
4888 return -ENOMEM; 4887 return -ENOMEM;
4889 } 4888 }
4890 if ((data->wbuffer = kmalloc( 2048, GFP_KERNEL )) == NULL) { 4889 if ((data->wbuffer = kzalloc( 2048, GFP_KERNEL )) == NULL) {
4891 kfree (data->rbuffer); 4890 kfree (data->rbuffer);
4892 kfree (file->private_data); 4891 kfree (file->private_data);
4893 return -ENOMEM; 4892 return -ENOMEM;
4894 } 4893 }
4895 memset( data->wbuffer, 0, 2048 );
4896 data->maxwritelen = 2048; 4894 data->maxwritelen = 2048;
4897 data->on_close = proc_config_on_close; 4895 data->on_close = proc_config_on_close;
4898 4896
@@ -5153,24 +5151,21 @@ static int proc_wepkey_open( struct inode *inode, struct file *file ) {
5153 int j=0; 5151 int j=0;
5154 int rc; 5152 int rc;
5155 5153
5156 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5154 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5157 return -ENOMEM; 5155 return -ENOMEM;
5158 memset(file->private_data, 0, sizeof(struct proc_data));
5159 memset(&wkr, 0, sizeof(wkr)); 5156 memset(&wkr, 0, sizeof(wkr));
5160 data = (struct proc_data *)file->private_data; 5157 data = (struct proc_data *)file->private_data;
5161 if ((data->rbuffer = kmalloc( 180, GFP_KERNEL )) == NULL) { 5158 if ((data->rbuffer = kzalloc( 180, GFP_KERNEL )) == NULL) {
5162 kfree (file->private_data); 5159 kfree (file->private_data);
5163 return -ENOMEM; 5160 return -ENOMEM;
5164 } 5161 }
5165 memset(data->rbuffer, 0, 180);
5166 data->writelen = 0; 5162 data->writelen = 0;
5167 data->maxwritelen = 80; 5163 data->maxwritelen = 80;
5168 if ((data->wbuffer = kmalloc( 80, GFP_KERNEL )) == NULL) { 5164 if ((data->wbuffer = kzalloc( 80, GFP_KERNEL )) == NULL) {
5169 kfree (data->rbuffer); 5165 kfree (data->rbuffer);
5170 kfree (file->private_data); 5166 kfree (file->private_data);
5171 return -ENOMEM; 5167 return -ENOMEM;
5172 } 5168 }
5173 memset( data->wbuffer, 0, 80 );
5174 data->on_close = proc_wepkey_on_close; 5169 data->on_close = proc_wepkey_on_close;
5175 5170
5176 ptr = data->rbuffer; 5171 ptr = data->rbuffer;
@@ -5201,9 +5196,8 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5201 char *ptr; 5196 char *ptr;
5202 SsidRid SSID_rid; 5197 SsidRid SSID_rid;
5203 5198
5204 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5199 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5205 return -ENOMEM; 5200 return -ENOMEM;
5206 memset(file->private_data, 0, sizeof(struct proc_data));
5207 data = (struct proc_data *)file->private_data; 5201 data = (struct proc_data *)file->private_data;
5208 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { 5202 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5209 kfree (file->private_data); 5203 kfree (file->private_data);
@@ -5211,12 +5205,11 @@ static int proc_SSID_open( struct inode *inode, struct file *file ) {
5211 } 5205 }
5212 data->writelen = 0; 5206 data->writelen = 0;
5213 data->maxwritelen = 33*3; 5207 data->maxwritelen = 33*3;
5214 if ((data->wbuffer = kmalloc( 33*3, GFP_KERNEL )) == NULL) { 5208 if ((data->wbuffer = kzalloc( 33*3, GFP_KERNEL )) == NULL) {
5215 kfree (data->rbuffer); 5209 kfree (data->rbuffer);
5216 kfree (file->private_data); 5210 kfree (file->private_data);
5217 return -ENOMEM; 5211 return -ENOMEM;
5218 } 5212 }
5219 memset( data->wbuffer, 0, 33*3 );
5220 data->on_close = proc_SSID_on_close; 5213 data->on_close = proc_SSID_on_close;
5221 5214
5222 readSsidRid(ai, &SSID_rid); 5215 readSsidRid(ai, &SSID_rid);
@@ -5245,9 +5238,8 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
5245 char *ptr; 5238 char *ptr;
5246 APListRid APList_rid; 5239 APListRid APList_rid;
5247 5240
5248 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5241 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5249 return -ENOMEM; 5242 return -ENOMEM;
5250 memset(file->private_data, 0, sizeof(struct proc_data));
5251 data = (struct proc_data *)file->private_data; 5243 data = (struct proc_data *)file->private_data;
5252 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) { 5244 if ((data->rbuffer = kmalloc( 104, GFP_KERNEL )) == NULL) {
5253 kfree (file->private_data); 5245 kfree (file->private_data);
@@ -5255,12 +5247,11 @@ static int proc_APList_open( struct inode *inode, struct file *file ) {
5255 } 5247 }
5256 data->writelen = 0; 5248 data->writelen = 0;
5257 data->maxwritelen = 4*6*3; 5249 data->maxwritelen = 4*6*3;
5258 if ((data->wbuffer = kmalloc( data->maxwritelen, GFP_KERNEL )) == NULL) { 5250 if ((data->wbuffer = kzalloc( data->maxwritelen, GFP_KERNEL )) == NULL) {
5259 kfree (data->rbuffer); 5251 kfree (data->rbuffer);
5260 kfree (file->private_data); 5252 kfree (file->private_data);
5261 return -ENOMEM; 5253 return -ENOMEM;
5262 } 5254 }
5263 memset( data->wbuffer, 0, data->maxwritelen );
5264 data->on_close = proc_APList_on_close; 5255 data->on_close = proc_APList_on_close;
5265 5256
5266 readAPListRid(ai, &APList_rid); 5257 readAPListRid(ai, &APList_rid);
@@ -5295,9 +5286,8 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) {
5295 /* If doLoseSync is not 1, we won't do a Lose Sync */ 5286 /* If doLoseSync is not 1, we won't do a Lose Sync */
5296 int doLoseSync = -1; 5287 int doLoseSync = -1;
5297 5288
5298 if ((file->private_data = kmalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL) 5289 if ((file->private_data = kzalloc(sizeof(struct proc_data ), GFP_KERNEL)) == NULL)
5299 return -ENOMEM; 5290 return -ENOMEM;
5300 memset(file->private_data, 0, sizeof(struct proc_data));
5301 data = (struct proc_data *)file->private_data; 5291 data = (struct proc_data *)file->private_data;
5302 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) { 5292 if ((data->rbuffer = kmalloc( 1024, GFP_KERNEL )) == NULL) {
5303 kfree (file->private_data); 5293 kfree (file->private_data);
diff --git a/drivers/net/wireless/airo.h b/drivers/net/wireless/airo.h
new file mode 100644
index 000000000000..e480adf86be6
--- /dev/null
+++ b/drivers/net/wireless/airo.h
@@ -0,0 +1,9 @@
1#ifndef _AIRO_H_
2#define _AIRO_H_
3
4struct net_device *init_airo_card(unsigned short irq, int port, int is_pcmcia,
5 struct device *dmdev);
6int reset_airo_card(struct net_device *dev);
7void stop_airo_card(struct net_device *dev, int freeres);
8
9#endif /* _AIRO_H_ */
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 784de9109113..e328547599dc 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -42,6 +42,8 @@
42#include <asm/io.h> 42#include <asm/io.h>
43#include <asm/system.h> 43#include <asm/system.h>
44 44
45#include "airo.h"
46
45/* 47/*
46 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If 48 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
47 you do not define PCMCIA_DEBUG at all, all the debug code will be 49 you do not define PCMCIA_DEBUG at all, all the debug code will be
@@ -78,10 +80,6 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
78 event handler. 80 event handler.
79*/ 81*/
80 82
81struct net_device *init_airo_card( int, int, int, struct device * );
82void stop_airo_card( struct net_device *, int );
83int reset_airo_card( struct net_device * );
84
85static void airo_config(dev_link_t *link); 83static void airo_config(dev_link_t *link);
86static void airo_release(dev_link_t *link); 84static void airo_release(dev_link_t *link);
87static int airo_event(event_t event, int priority, 85static int airo_event(event_t event, int priority,
@@ -172,12 +170,11 @@ static dev_link_t *airo_attach(void)
172 DEBUG(0, "airo_attach()\n"); 170 DEBUG(0, "airo_attach()\n");
173 171
174 /* Initialize the dev_link_t structure */ 172 /* Initialize the dev_link_t structure */
175 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 173 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
176 if (!link) { 174 if (!link) {
177 printk(KERN_ERR "airo_cs: no memory for new device\n"); 175 printk(KERN_ERR "airo_cs: no memory for new device\n");
178 return NULL; 176 return NULL;
179 } 177 }
180 memset(link, 0, sizeof(struct dev_link_t));
181 178
182 /* Interrupt setup */ 179 /* Interrupt setup */
183 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 180 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -196,13 +193,12 @@ static dev_link_t *airo_attach(void)
196 link->conf.IntType = INT_MEMORY_AND_IO; 193 link->conf.IntType = INT_MEMORY_AND_IO;
197 194
198 /* Allocate space for private device-specific data */ 195 /* Allocate space for private device-specific data */
199 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 196 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
200 if (!local) { 197 if (!local) {
201 printk(KERN_ERR "airo_cs: no memory for new device\n"); 198 printk(KERN_ERR "airo_cs: no memory for new device\n");
202 kfree (link); 199 kfree (link);
203 return NULL; 200 return NULL;
204 } 201 }
205 memset(local, 0, sizeof(local_info_t));
206 link->priv = local; 202 link->priv = local;
207 203
208 /* Register with Card Services */ 204 /* Register with Card Services */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 1fbe027d26b6..a3e23527fe7f 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2217,7 +2217,7 @@ static int atmel_get_range(struct net_device *dev,
2217 int k,i,j; 2217 int k,i,j;
2218 2218
2219 dwrq->length = sizeof(struct iw_range); 2219 dwrq->length = sizeof(struct iw_range);
2220 memset(range, 0, sizeof(range)); 2220 memset(range, 0, sizeof(struct iw_range));
2221 range->min_nwid = 0x0000; 2221 range->min_nwid = 0x0000;
2222 range->max_nwid = 0x0000; 2222 range->max_nwid = 0x0000;
2223 range->num_channels = 0; 2223 range->num_channels = 0;
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 195cb36619e8..1bd13146c644 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -180,12 +180,11 @@ static dev_link_t *atmel_attach(void)
180 DEBUG(0, "atmel_attach()\n"); 180 DEBUG(0, "atmel_attach()\n");
181 181
182 /* Initialize the dev_link_t structure */ 182 /* Initialize the dev_link_t structure */
183 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 183 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
184 if (!link) { 184 if (!link) {
185 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 185 printk(KERN_ERR "atmel_cs: no memory for new device\n");
186 return NULL; 186 return NULL;
187 } 187 }
188 memset(link, 0, sizeof(struct dev_link_t));
189 188
190 /* Interrupt setup */ 189 /* Interrupt setup */
191 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 190 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
@@ -204,13 +203,12 @@ static dev_link_t *atmel_attach(void)
204 link->conf.IntType = INT_MEMORY_AND_IO; 203 link->conf.IntType = INT_MEMORY_AND_IO;
205 204
206 /* Allocate space for private device-specific data */ 205 /* Allocate space for private device-specific data */
207 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 206 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
208 if (!local) { 207 if (!local) {
209 printk(KERN_ERR "atmel_cs: no memory for new device\n"); 208 printk(KERN_ERR "atmel_cs: no memory for new device\n");
210 kfree (link); 209 kfree (link);
211 return NULL; 210 return NULL;
212 } 211 }
213 memset(local, 0, sizeof(local_info_t));
214 link->priv = local; 212 link->priv = local;
215 213
216 /* Register with Card Services */ 214 /* Register with Card Services */
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
index 6a96cd9f2685..3d2ea61033be 100644
--- a/drivers/net/wireless/hostap/hostap.c
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -13,7 +13,6 @@
13 */ 13 */
14 14
15#include <linux/config.h> 15#include <linux/config.h>
16#include <linux/version.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 59fc15572395..abfae7fedebc 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -31,7 +31,6 @@
31 31
32 32
33#include <linux/config.h> 33#include <linux/config.h>
34#include <linux/version.h>
35 34
36#include <asm/delay.h> 35#include <asm/delay.h>
37#include <asm/uaccess.h> 36#include <asm/uaccess.h>
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index da0c80fb941c..2e85bdced2dd 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -5,7 +5,6 @@
5 * Andy Warner <andyw@pobox.com> */ 5 * Andy Warner <andyw@pobox.com> */
6 6
7#include <linux/config.h> 7#include <linux/config.h>
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/if.h> 10#include <linux/if.h>
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 78d67b408b2f..94fe2449f099 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -8,7 +8,6 @@
8 8
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/version.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/if.h> 13#include <linux/if.h>
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index ad7f8cd76db9..a2e6214169e9 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -167,17 +167,16 @@ that only one external action is invoked at a time.
167 167
168#include "ipw2100.h" 168#include "ipw2100.h"
169 169
170#define IPW2100_VERSION "1.1.0" 170#define IPW2100_VERSION "1.1.3"
171 171
172#define DRV_NAME "ipw2100" 172#define DRV_NAME "ipw2100"
173#define DRV_VERSION IPW2100_VERSION 173#define DRV_VERSION IPW2100_VERSION
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" 174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 175#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
176
177 176
178/* Debugging stuff */ 177/* Debugging stuff */
179#ifdef CONFIG_IPW_DEBUG 178#ifdef CONFIG_IPW_DEBUG
180#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */ 179#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
181#endif 180#endif
182 181
183MODULE_DESCRIPTION(DRV_DESCRIPTION); 182MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -220,18 +219,18 @@ do { \
220} while (0) 219} while (0)
221#else 220#else
222#define IPW_DEBUG(level, message...) do {} while (0) 221#define IPW_DEBUG(level, message...) do {} while (0)
223#endif /* CONFIG_IPW_DEBUG */ 222#endif /* CONFIG_IPW_DEBUG */
224 223
225#ifdef CONFIG_IPW_DEBUG 224#ifdef CONFIG_IPW_DEBUG
226static const char *command_types[] = { 225static const char *command_types[] = {
227 "undefined", 226 "undefined",
228 "unused", /* HOST_ATTENTION */ 227 "unused", /* HOST_ATTENTION */
229 "HOST_COMPLETE", 228 "HOST_COMPLETE",
230 "unused", /* SLEEP */ 229 "unused", /* SLEEP */
231 "unused", /* HOST_POWER_DOWN */ 230 "unused", /* HOST_POWER_DOWN */
232 "unused", 231 "unused",
233 "SYSTEM_CONFIG", 232 "SYSTEM_CONFIG",
234 "unused", /* SET_IMR */ 233 "unused", /* SET_IMR */
235 "SSID", 234 "SSID",
236 "MANDATORY_BSSID", 235 "MANDATORY_BSSID",
237 "AUTHENTICATION_TYPE", 236 "AUTHENTICATION_TYPE",
@@ -277,17 +276,16 @@ static const char *command_types[] = {
277 "GROUP_ORDINALS", 276 "GROUP_ORDINALS",
278 "SHORT_RETRY_LIMIT", 277 "SHORT_RETRY_LIMIT",
279 "LONG_RETRY_LIMIT", 278 "LONG_RETRY_LIMIT",
280 "unused", /* SAVE_CALIBRATION */ 279 "unused", /* SAVE_CALIBRATION */
281 "unused", /* RESTORE_CALIBRATION */ 280 "unused", /* RESTORE_CALIBRATION */
282 "undefined", 281 "undefined",
283 "undefined", 282 "undefined",
284 "undefined", 283 "undefined",
285 "HOST_PRE_POWER_DOWN", 284 "HOST_PRE_POWER_DOWN",
286 "unused", /* HOST_INTERRUPT_COALESCING */ 285 "unused", /* HOST_INTERRUPT_COALESCING */
287 "undefined", 286 "undefined",
288 "CARD_DISABLE_PHY_OFF", 287 "CARD_DISABLE_PHY_OFF",
289 "MSDU_TX_RATES" 288 "MSDU_TX_RATES" "undefined",
290 "undefined",
291 "undefined", 289 "undefined",
292 "SET_STATION_STAT_BITS", 290 "SET_STATION_STAT_BITS",
293 "CLEAR_STATIONS_STAT_BITS", 291 "CLEAR_STATIONS_STAT_BITS",
@@ -298,7 +296,6 @@ static const char *command_types[] = {
298}; 296};
299#endif 297#endif
300 298
301
302/* Pre-decl until we get the code solid and then we can clean it up */ 299/* Pre-decl until we get the code solid and then we can clean it up */
303static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); 300static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
304static void ipw2100_tx_send_data(struct ipw2100_priv *priv); 301static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
@@ -321,11 +318,10 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
321static int ipw2100_ucode_download(struct ipw2100_priv *priv, 318static int ipw2100_ucode_download(struct ipw2100_priv *priv,
322 struct ipw2100_fw *fw); 319 struct ipw2100_fw *fw);
323static void ipw2100_wx_event_work(struct ipw2100_priv *priv); 320static void ipw2100_wx_event_work(struct ipw2100_priv *priv);
324static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev); 321static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev);
325static struct iw_handler_def ipw2100_wx_handler_def; 322static struct iw_handler_def ipw2100_wx_handler_def;
326 323
327 324static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
328static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
329{ 325{
330 *val = readl((void __iomem *)(dev->base_addr + reg)); 326 *val = readl((void __iomem *)(dev->base_addr + reg));
331 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val); 327 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
@@ -337,13 +333,14 @@ static inline void write_register(struct net_device *dev, u32 reg, u32 val)
337 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val); 333 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
338} 334}
339 335
340static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val) 336static inline void read_register_word(struct net_device *dev, u32 reg,
337 u16 * val)
341{ 338{
342 *val = readw((void __iomem *)(dev->base_addr + reg)); 339 *val = readw((void __iomem *)(dev->base_addr + reg));
343 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val); 340 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
344} 341}
345 342
346static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val) 343static inline void read_register_byte(struct net_device *dev, u32 reg, u8 * val)
347{ 344{
348 *val = readb((void __iomem *)(dev->base_addr + reg)); 345 *val = readb((void __iomem *)(dev->base_addr + reg));
349 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val); 346 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
@@ -355,14 +352,13 @@ static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
355 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val); 352 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
356} 353}
357 354
358
359static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val) 355static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
360{ 356{
361 writeb(val, (void __iomem *)(dev->base_addr + reg)); 357 writeb(val, (void __iomem *)(dev->base_addr + reg));
362 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val); 358 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
363} 359}
364 360
365static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 *val) 361static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 * val)
366{ 362{
367 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 363 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
368 addr & IPW_REG_INDIRECT_ADDR_MASK); 364 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -376,7 +372,7 @@ static inline void write_nic_dword(struct net_device *dev, u32 addr, u32 val)
376 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val); 372 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
377} 373}
378 374
379static inline void read_nic_word(struct net_device *dev, u32 addr, u16 *val) 375static inline void read_nic_word(struct net_device *dev, u32 addr, u16 * val)
380{ 376{
381 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 377 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
382 addr & IPW_REG_INDIRECT_ADDR_MASK); 378 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -390,7 +386,7 @@ static inline void write_nic_word(struct net_device *dev, u32 addr, u16 val)
390 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val); 386 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
391} 387}
392 388
393static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 *val) 389static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 * val)
394{ 390{
395 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 391 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
396 addr & IPW_REG_INDIRECT_ADDR_MASK); 392 addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -416,7 +412,7 @@ static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val)
416} 412}
417 413
418static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len, 414static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
419 const u8 *buf) 415 const u8 * buf)
420{ 416{
421 u32 aligned_addr; 417 u32 aligned_addr;
422 u32 aligned_len; 418 u32 aligned_len;
@@ -431,32 +427,30 @@ static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
431 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 427 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
432 aligned_addr); 428 aligned_addr);
433 for (i = dif_len; i < 4; i++, buf++) 429 for (i = dif_len; i < 4; i++, buf++)
434 write_register_byte( 430 write_register_byte(dev,
435 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, 431 IPW_REG_INDIRECT_ACCESS_DATA + i,
436 *buf); 432 *buf);
437 433
438 len -= dif_len; 434 len -= dif_len;
439 aligned_addr += 4; 435 aligned_addr += 4;
440 } 436 }
441 437
442 /* read DWs through autoincrement registers */ 438 /* read DWs through autoincrement registers */
443 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, 439 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
444 aligned_addr);
445 aligned_len = len & (~0x3); 440 aligned_len = len & (~0x3);
446 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) 441 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
447 write_register( 442 write_register(dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *) buf);
448 dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *)buf);
449 443
450 /* copy the last nibble */ 444 /* copy the last nibble */
451 dif_len = len - aligned_len; 445 dif_len = len - aligned_len;
452 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr); 446 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
453 for (i = 0; i < dif_len; i++, buf++) 447 for (i = 0; i < dif_len; i++, buf++)
454 write_register_byte( 448 write_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
455 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, *buf); 449 *buf);
456} 450}
457 451
458static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len, 452static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
459 u8 *buf) 453 u8 * buf)
460{ 454{
461 u32 aligned_addr; 455 u32 aligned_addr;
462 u32 aligned_len; 456 u32 aligned_len;
@@ -471,39 +465,38 @@ static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
471 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 465 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
472 aligned_addr); 466 aligned_addr);
473 for (i = dif_len; i < 4; i++, buf++) 467 for (i = dif_len; i < 4; i++, buf++)
474 read_register_byte( 468 read_register_byte(dev,
475 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf); 469 IPW_REG_INDIRECT_ACCESS_DATA + i,
470 buf);
476 471
477 len -= dif_len; 472 len -= dif_len;
478 aligned_addr += 4; 473 aligned_addr += 4;
479 } 474 }
480 475
481 /* read DWs through autoincrement registers */ 476 /* read DWs through autoincrement registers */
482 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, 477 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
483 aligned_addr);
484 aligned_len = len & (~0x3); 478 aligned_len = len & (~0x3);
485 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) 479 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
486 read_register(dev, IPW_REG_AUTOINCREMENT_DATA, 480 read_register(dev, IPW_REG_AUTOINCREMENT_DATA, (u32 *) buf);
487 (u32 *)buf);
488 481
489 /* copy the last nibble */ 482 /* copy the last nibble */
490 dif_len = len - aligned_len; 483 dif_len = len - aligned_len;
491 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, 484 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
492 aligned_addr);
493 for (i = 0; i < dif_len; i++, buf++) 485 for (i = 0; i < dif_len; i++, buf++)
494 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + 486 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
495 i, buf);
496} 487}
497 488
498static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev) 489static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
499{ 490{
500 return (dev->base_addr && 491 return (dev->base_addr &&
501 (readl((void __iomem *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START)) 492 (readl
493 ((void __iomem *)(dev->base_addr +
494 IPW_REG_DOA_DEBUG_AREA_START))
502 == IPW_DATA_DOA_DEBUG_VALUE)); 495 == IPW_DATA_DOA_DEBUG_VALUE));
503} 496}
504 497
505static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord, 498static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
506 void *val, u32 *len) 499 void *val, u32 * len)
507{ 500{
508 struct ipw2100_ordinals *ordinals = &priv->ordinals; 501 struct ipw2100_ordinals *ordinals = &priv->ordinals;
509 u32 addr; 502 u32 addr;
@@ -529,8 +522,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
529 return -EINVAL; 522 return -EINVAL;
530 } 523 }
531 524
532 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2), 525 read_nic_dword(priv->net_dev,
533 &addr); 526 ordinals->table1_addr + (ord << 2), &addr);
534 read_nic_dword(priv->net_dev, addr, val); 527 read_nic_dword(priv->net_dev, addr, val);
535 528
536 *len = IPW_ORD_TAB_1_ENTRY_SIZE; 529 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
@@ -543,8 +536,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
543 ord -= IPW_START_ORD_TAB_2; 536 ord -= IPW_START_ORD_TAB_2;
544 537
545 /* get the address of statistic */ 538 /* get the address of statistic */
546 read_nic_dword(priv->net_dev, ordinals->table2_addr + (ord << 3), 539 read_nic_dword(priv->net_dev,
547 &addr); 540 ordinals->table2_addr + (ord << 3), &addr);
548 541
549 /* get the second DW of statistics ; 542 /* get the second DW of statistics ;
550 * two 16-bit words - first is length, second is count */ 543 * two 16-bit words - first is length, second is count */
@@ -553,10 +546,10 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
553 &field_info); 546 &field_info);
554 547
555 /* get each entry length */ 548 /* get each entry length */
556 field_len = *((u16 *)&field_info); 549 field_len = *((u16 *) & field_info);
557 550
558 /* get number of entries */ 551 /* get number of entries */
559 field_count = *(((u16 *)&field_info) + 1); 552 field_count = *(((u16 *) & field_info) + 1);
560 553
561 /* abort if no enought memory */ 554 /* abort if no enought memory */
562 total_length = field_len * field_count; 555 total_length = field_len * field_count;
@@ -581,8 +574,8 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
581 return -EINVAL; 574 return -EINVAL;
582} 575}
583 576
584static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val, 577static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 * val,
585 u32 *len) 578 u32 * len)
586{ 579{
587 struct ipw2100_ordinals *ordinals = &priv->ordinals; 580 struct ipw2100_ordinals *ordinals = &priv->ordinals;
588 u32 addr; 581 u32 addr;
@@ -594,8 +587,8 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
594 return -EINVAL; 587 return -EINVAL;
595 } 588 }
596 589
597 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2), 590 read_nic_dword(priv->net_dev,
598 &addr); 591 ordinals->table1_addr + (ord << 2), &addr);
599 592
600 write_nic_dword(priv->net_dev, addr, *val); 593 write_nic_dword(priv->net_dev, addr, *val);
601 594
@@ -612,7 +605,7 @@ static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
612} 605}
613 606
614static char *snprint_line(char *buf, size_t count, 607static char *snprint_line(char *buf, size_t count,
615 const u8 *data, u32 len, u32 ofs) 608 const u8 * data, u32 len, u32 ofs)
616{ 609{
617 int out, i, j, l; 610 int out, i, j, l;
618 char c; 611 char c;
@@ -646,7 +639,7 @@ static char *snprint_line(char *buf, size_t count,
646 return buf; 639 return buf;
647} 640}
648 641
649static void printk_buf(int level, const u8 *data, u32 len) 642static void printk_buf(int level, const u8 * data, u32 len)
650{ 643{
651 char line[81]; 644 char line[81];
652 u32 ofs = 0; 645 u32 ofs = 0;
@@ -662,8 +655,6 @@ static void printk_buf(int level, const u8 *data, u32 len)
662 } 655 }
663} 656}
664 657
665
666
667#define MAX_RESET_BACKOFF 10 658#define MAX_RESET_BACKOFF 10
668 659
669static inline void schedule_reset(struct ipw2100_priv *priv) 660static inline void schedule_reset(struct ipw2100_priv *priv)
@@ -703,7 +694,7 @@ static inline void schedule_reset(struct ipw2100_priv *priv)
703 694
704#define HOST_COMPLETE_TIMEOUT (2 * HZ) 695#define HOST_COMPLETE_TIMEOUT (2 * HZ)
705static int ipw2100_hw_send_command(struct ipw2100_priv *priv, 696static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
706 struct host_command * cmd) 697 struct host_command *cmd)
707{ 698{
708 struct list_head *element; 699 struct list_head *element;
709 struct ipw2100_tx_packet *packet; 700 struct ipw2100_tx_packet *packet;
@@ -713,25 +704,28 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
713 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", 704 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
714 command_types[cmd->host_command], cmd->host_command, 705 command_types[cmd->host_command], cmd->host_command,
715 cmd->host_command_length); 706 cmd->host_command_length);
716 printk_buf(IPW_DL_HC, (u8*)cmd->host_command_parameters, 707 printk_buf(IPW_DL_HC, (u8 *) cmd->host_command_parameters,
717 cmd->host_command_length); 708 cmd->host_command_length);
718 709
719 spin_lock_irqsave(&priv->low_lock, flags); 710 spin_lock_irqsave(&priv->low_lock, flags);
720 711
721 if (priv->fatal_error) { 712 if (priv->fatal_error) {
722 IPW_DEBUG_INFO("Attempt to send command while hardware in fatal error condition.\n"); 713 IPW_DEBUG_INFO
714 ("Attempt to send command while hardware in fatal error condition.\n");
723 err = -EIO; 715 err = -EIO;
724 goto fail_unlock; 716 goto fail_unlock;
725 } 717 }
726 718
727 if (!(priv->status & STATUS_RUNNING)) { 719 if (!(priv->status & STATUS_RUNNING)) {
728 IPW_DEBUG_INFO("Attempt to send command while hardware is not running.\n"); 720 IPW_DEBUG_INFO
721 ("Attempt to send command while hardware is not running.\n");
729 err = -EIO; 722 err = -EIO;
730 goto fail_unlock; 723 goto fail_unlock;
731 } 724 }
732 725
733 if (priv->status & STATUS_CMD_ACTIVE) { 726 if (priv->status & STATUS_CMD_ACTIVE) {
734 IPW_DEBUG_INFO("Attempt to send command while another command is pending.\n"); 727 IPW_DEBUG_INFO
728 ("Attempt to send command while another command is pending.\n");
735 err = -EBUSY; 729 err = -EBUSY;
736 goto fail_unlock; 730 goto fail_unlock;
737 } 731 }
@@ -752,7 +746,8 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
752 /* initialize the firmware command packet */ 746 /* initialize the firmware command packet */
753 packet->info.c_struct.cmd->host_command_reg = cmd->host_command; 747 packet->info.c_struct.cmd->host_command_reg = cmd->host_command;
754 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1; 748 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1;
755 packet->info.c_struct.cmd->host_command_len_reg = cmd->host_command_length; 749 packet->info.c_struct.cmd->host_command_len_reg =
750 cmd->host_command_length;
756 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence; 751 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence;
757 752
758 memcpy(packet->info.c_struct.cmd->host_command_params_reg, 753 memcpy(packet->info.c_struct.cmd->host_command_params_reg,
@@ -776,13 +771,15 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
776 * then there is a problem. 771 * then there is a problem.
777 */ 772 */
778 773
779 err = wait_event_interruptible_timeout( 774 err =
780 priv->wait_command_queue, !(priv->status & STATUS_CMD_ACTIVE), 775 wait_event_interruptible_timeout(priv->wait_command_queue,
781 HOST_COMPLETE_TIMEOUT); 776 !(priv->
777 status & STATUS_CMD_ACTIVE),
778 HOST_COMPLETE_TIMEOUT);
782 779
783 if (err == 0) { 780 if (err == 0) {
784 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 781 IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
785 HOST_COMPLETE_TIMEOUT / (HZ / 100)); 782 1000 * (HOST_COMPLETE_TIMEOUT / HZ));
786 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT; 783 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
787 priv->status &= ~STATUS_CMD_ACTIVE; 784 priv->status &= ~STATUS_CMD_ACTIVE;
788 schedule_reset(priv); 785 schedule_reset(priv);
@@ -804,13 +801,12 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
804 801
805 return 0; 802 return 0;
806 803
807 fail_unlock: 804 fail_unlock:
808 spin_unlock_irqrestore(&priv->low_lock, flags); 805 spin_unlock_irqrestore(&priv->low_lock, flags);
809 806
810 return err; 807 return err;
811} 808}
812 809
813
814/* 810/*
815 * Verify the values and data access of the hardware 811 * Verify the values and data access of the hardware
816 * No locks needed or used. No functions called. 812 * No locks needed or used. No functions called.
@@ -825,8 +821,7 @@ static int ipw2100_verify(struct ipw2100_priv *priv)
825 821
826 /* Domain 0 check - all values should be DOA_DEBUG */ 822 /* Domain 0 check - all values should be DOA_DEBUG */
827 for (address = IPW_REG_DOA_DEBUG_AREA_START; 823 for (address = IPW_REG_DOA_DEBUG_AREA_START;
828 address < IPW_REG_DOA_DEBUG_AREA_END; 824 address < IPW_REG_DOA_DEBUG_AREA_END; address += sizeof(u32)) {
829 address += sizeof(u32)) {
830 read_register(priv->net_dev, address, &data1); 825 read_register(priv->net_dev, address, &data1);
831 if (data1 != IPW_DATA_DOA_DEBUG_VALUE) 826 if (data1 != IPW_DATA_DOA_DEBUG_VALUE)
832 return -EIO; 827 return -EIO;
@@ -898,7 +893,6 @@ static int ipw2100_wait_for_card_state(struct ipw2100_priv *priv, int state)
898 return -EIO; 893 return -EIO;
899} 894}
900 895
901
902/********************************************************************* 896/*********************************************************************
903 Procedure : sw_reset_and_clock 897 Procedure : sw_reset_and_clock
904 Purpose : Asserts s/w reset, asserts clock initialization 898 Purpose : Asserts s/w reset, asserts clock initialization
@@ -975,17 +969,16 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
975 969
976 if (priv->fatal_error) { 970 if (priv->fatal_error) {
977 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after " 971 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
978 "fatal error %d. Interface must be brought down.\n", 972 "fatal error %d. Interface must be brought down.\n",
979 priv->net_dev->name, priv->fatal_error); 973 priv->net_dev->name, priv->fatal_error);
980 return -EINVAL; 974 return -EINVAL;
981 } 975 }
982
983#ifdef CONFIG_PM 976#ifdef CONFIG_PM
984 if (!ipw2100_firmware.version) { 977 if (!ipw2100_firmware.version) {
985 err = ipw2100_get_firmware(priv, &ipw2100_firmware); 978 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
986 if (err) { 979 if (err) {
987 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n", 980 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
988 priv->net_dev->name, err); 981 priv->net_dev->name, err);
989 priv->fatal_error = IPW2100_ERR_FW_LOAD; 982 priv->fatal_error = IPW2100_ERR_FW_LOAD;
990 goto fail; 983 goto fail;
991 } 984 }
@@ -994,7 +987,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
994 err = ipw2100_get_firmware(priv, &ipw2100_firmware); 987 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
995 if (err) { 988 if (err) {
996 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n", 989 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
997 priv->net_dev->name, err); 990 priv->net_dev->name, err);
998 priv->fatal_error = IPW2100_ERR_FW_LOAD; 991 priv->fatal_error = IPW2100_ERR_FW_LOAD;
999 goto fail; 992 goto fail;
1000 } 993 }
@@ -1005,21 +998,20 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1005 err = sw_reset_and_clock(priv); 998 err = sw_reset_and_clock(priv);
1006 if (err) { 999 if (err) {
1007 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n", 1000 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n",
1008 priv->net_dev->name, err); 1001 priv->net_dev->name, err);
1009 goto fail; 1002 goto fail;
1010 } 1003 }
1011 1004
1012 err = ipw2100_verify(priv); 1005 err = ipw2100_verify(priv);
1013 if (err) { 1006 if (err) {
1014 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n", 1007 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n",
1015 priv->net_dev->name, err); 1008 priv->net_dev->name, err);
1016 goto fail; 1009 goto fail;
1017 } 1010 }
1018 1011
1019 /* Hold ARC */ 1012 /* Hold ARC */
1020 write_nic_dword(priv->net_dev, 1013 write_nic_dword(priv->net_dev,
1021 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 1014 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x80000000);
1022 0x80000000);
1023 1015
1024 /* allow ARC to run */ 1016 /* allow ARC to run */
1025 write_register(priv->net_dev, IPW_REG_RESET_REG, 0); 1017 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
@@ -1034,13 +1026,13 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1034 1026
1035 /* release ARC */ 1027 /* release ARC */
1036 write_nic_dword(priv->net_dev, 1028 write_nic_dword(priv->net_dev,
1037 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 1029 IPW_INTERNAL_REGISTER_HALT_AND_RESET, 0x00000000);
1038 0x00000000);
1039 1030
1040 /* s/w reset and clock stabilization (again!!!) */ 1031 /* s/w reset and clock stabilization (again!!!) */
1041 err = sw_reset_and_clock(priv); 1032 err = sw_reset_and_clock(priv);
1042 if (err) { 1033 if (err) {
1043 printk(KERN_ERR DRV_NAME ": %s: sw_reset_and_clock failed: %d\n", 1034 printk(KERN_ERR DRV_NAME
1035 ": %s: sw_reset_and_clock failed: %d\n",
1044 priv->net_dev->name, err); 1036 priv->net_dev->name, err);
1045 goto fail; 1037 goto fail;
1046 } 1038 }
@@ -1049,10 +1041,9 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1049 err = ipw2100_fw_download(priv, &ipw2100_firmware); 1041 err = ipw2100_fw_download(priv, &ipw2100_firmware);
1050 if (err) { 1042 if (err) {
1051 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n", 1043 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n",
1052 priv->net_dev->name, err); 1044 priv->net_dev->name, err);
1053 goto fail; 1045 goto fail;
1054 } 1046 }
1055
1056#ifndef CONFIG_PM 1047#ifndef CONFIG_PM
1057 /* 1048 /*
1058 * When the .resume method of the driver is called, the other 1049 * When the .resume method of the driver is called, the other
@@ -1084,7 +1075,7 @@ static int ipw2100_download_firmware(struct ipw2100_priv *priv)
1084 1075
1085 return 0; 1076 return 0;
1086 1077
1087 fail: 1078 fail:
1088 ipw2100_release_firmware(priv, &ipw2100_firmware); 1079 ipw2100_release_firmware(priv, &ipw2100_firmware);
1089 return err; 1080 return err;
1090} 1081}
@@ -1105,7 +1096,6 @@ static inline void ipw2100_disable_interrupts(struct ipw2100_priv *priv)
1105 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0); 1096 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0);
1106} 1097}
1107 1098
1108
1109static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv) 1099static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv)
1110{ 1100{
1111 struct ipw2100_ordinals *ord = &priv->ordinals; 1101 struct ipw2100_ordinals *ord = &priv->ordinals;
@@ -1177,11 +1167,10 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1177 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1 1167 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1
1178 */ 1168 */
1179 len = sizeof(addr); 1169 len = sizeof(addr);
1180 if (ipw2100_get_ordinal( 1170 if (ipw2100_get_ordinal
1181 priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, 1171 (priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS, &addr, &len)) {
1182 &addr, &len)) {
1183 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1172 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1184 __LINE__); 1173 __LINE__);
1185 return -EIO; 1174 return -EIO;
1186 } 1175 }
1187 1176
@@ -1194,7 +1183,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1194 priv->eeprom_version = (val >> 24) & 0xFF; 1183 priv->eeprom_version = (val >> 24) & 0xFF;
1195 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version); 1184 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version);
1196 1185
1197 /* 1186 /*
1198 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware 1187 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware
1199 * 1188 *
1200 * notice that the EEPROM bit is reverse polarity, i.e. 1189 * notice that the EEPROM bit is reverse polarity, i.e.
@@ -1206,8 +1195,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1206 priv->hw_features |= HW_FEATURE_RFKILL; 1195 priv->hw_features |= HW_FEATURE_RFKILL;
1207 1196
1208 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n", 1197 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n",
1209 (priv->hw_features & HW_FEATURE_RFKILL) ? 1198 (priv->hw_features & HW_FEATURE_RFKILL) ? "" : "not ");
1210 "" : "not ");
1211 1199
1212 return 0; 1200 return 0;
1213} 1201}
@@ -1234,7 +1222,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1234 * fw & dino ucode 1222 * fw & dino ucode
1235 */ 1223 */
1236 if (ipw2100_download_firmware(priv)) { 1224 if (ipw2100_download_firmware(priv)) {
1237 printk(KERN_ERR DRV_NAME ": %s: Failed to power on the adapter.\n", 1225 printk(KERN_ERR DRV_NAME
1226 ": %s: Failed to power on the adapter.\n",
1238 priv->net_dev->name); 1227 priv->net_dev->name);
1239 return -EIO; 1228 return -EIO;
1240 } 1229 }
@@ -1293,7 +1282,8 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1293 i ? "SUCCESS" : "FAILED"); 1282 i ? "SUCCESS" : "FAILED");
1294 1283
1295 if (!i) { 1284 if (!i) {
1296 printk(KERN_WARNING DRV_NAME ": %s: Firmware did not initialize.\n", 1285 printk(KERN_WARNING DRV_NAME
1286 ": %s: Firmware did not initialize.\n",
1297 priv->net_dev->name); 1287 priv->net_dev->name);
1298 return -EIO; 1288 return -EIO;
1299 } 1289 }
@@ -1326,7 +1316,6 @@ static inline void ipw2100_reset_fatalerror(struct ipw2100_priv *priv)
1326 priv->fatal_error = 0; 1316 priv->fatal_error = 0;
1327} 1317}
1328 1318
1329
1330/* NOTE: Our interrupt is disabled when this method is called */ 1319/* NOTE: Our interrupt is disabled when this method is called */
1331static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv) 1320static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1332{ 1321{
@@ -1350,19 +1339,19 @@ static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1350 1339
1351 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED) 1340 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1352 break; 1341 break;
1353 } while(i--); 1342 } while (i--);
1354 1343
1355 priv->status &= ~STATUS_RESET_PENDING; 1344 priv->status &= ~STATUS_RESET_PENDING;
1356 1345
1357 if (!i) { 1346 if (!i) {
1358 IPW_DEBUG_INFO("exit - waited too long for master assert stop\n"); 1347 IPW_DEBUG_INFO
1348 ("exit - waited too long for master assert stop\n");
1359 return -EIO; 1349 return -EIO;
1360 } 1350 }
1361 1351
1362 write_register(priv->net_dev, IPW_REG_RESET_REG, 1352 write_register(priv->net_dev, IPW_REG_RESET_REG,
1363 IPW_AUX_HOST_RESET_REG_SW_RESET); 1353 IPW_AUX_HOST_RESET_REG_SW_RESET);
1364 1354
1365
1366 /* Reset any fatal_error conditions */ 1355 /* Reset any fatal_error conditions */
1367 ipw2100_reset_fatalerror(priv); 1356 ipw2100_reset_fatalerror(priv);
1368 1357
@@ -1415,7 +1404,6 @@ static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
1415 return -EIO; 1404 return -EIO;
1416} 1405}
1417 1406
1418
1419static int ipw2100_enable_adapter(struct ipw2100_priv *priv) 1407static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1420{ 1408{
1421 struct host_command cmd = { 1409 struct host_command cmd = {
@@ -1445,9 +1433,8 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1445 1433
1446 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED); 1434 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED);
1447 if (err) { 1435 if (err) {
1448 IPW_DEBUG_INFO( 1436 IPW_DEBUG_INFO("%s: card not responding to init command.\n",
1449 "%s: card not responding to init command.\n", 1437 priv->net_dev->name);
1450 priv->net_dev->name);
1451 goto fail_up; 1438 goto fail_up;
1452 } 1439 }
1453 1440
@@ -1456,7 +1443,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1456 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2); 1443 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
1457 } 1444 }
1458 1445
1459fail_up: 1446 fail_up:
1460 up(&priv->adapter_sem); 1447 up(&priv->adapter_sem);
1461 return err; 1448 return err;
1462} 1449}
@@ -1488,7 +1475,8 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1488 1475
1489 err = ipw2100_hw_phy_off(priv); 1476 err = ipw2100_hw_phy_off(priv);
1490 if (err) 1477 if (err)
1491 printk(KERN_WARNING DRV_NAME ": Error disabling radio %d\n", err); 1478 printk(KERN_WARNING DRV_NAME
1479 ": Error disabling radio %d\n", err);
1492 1480
1493 /* 1481 /*
1494 * If in D0-standby mode going directly to D3 may cause a 1482 * If in D0-standby mode going directly to D3 may cause a
@@ -1566,7 +1554,6 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1566 return 0; 1554 return 0;
1567} 1555}
1568 1556
1569
1570static int ipw2100_disable_adapter(struct ipw2100_priv *priv) 1557static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1571{ 1558{
1572 struct host_command cmd = { 1559 struct host_command cmd = {
@@ -1593,19 +1580,21 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1593 1580
1594 err = ipw2100_hw_send_command(priv, &cmd); 1581 err = ipw2100_hw_send_command(priv, &cmd);
1595 if (err) { 1582 if (err) {
1596 printk(KERN_WARNING DRV_NAME ": exit - failed to send CARD_DISABLE command\n"); 1583 printk(KERN_WARNING DRV_NAME
1584 ": exit - failed to send CARD_DISABLE command\n");
1597 goto fail_up; 1585 goto fail_up;
1598 } 1586 }
1599 1587
1600 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED); 1588 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED);
1601 if (err) { 1589 if (err) {
1602 printk(KERN_WARNING DRV_NAME ": exit - card failed to change to DISABLED\n"); 1590 printk(KERN_WARNING DRV_NAME
1591 ": exit - card failed to change to DISABLED\n");
1603 goto fail_up; 1592 goto fail_up;
1604 } 1593 }
1605 1594
1606 IPW_DEBUG_INFO("TODO: implement scan state machine\n"); 1595 IPW_DEBUG_INFO("TODO: implement scan state machine\n");
1607 1596
1608fail_up: 1597 fail_up:
1609 up(&priv->adapter_sem); 1598 up(&priv->adapter_sem);
1610 return err; 1599 return err;
1611} 1600}
@@ -1627,7 +1616,7 @@ static int ipw2100_set_scan_options(struct ipw2100_priv *priv)
1627 1616
1628 if (!(priv->config & CFG_ASSOCIATE)) 1617 if (!(priv->config & CFG_ASSOCIATE))
1629 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE; 1618 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE;
1630 if ((priv->sec.flags & SEC_ENABLED) && priv->sec.enabled) 1619 if ((priv->ieee->sec.flags & SEC_ENABLED) && priv->ieee->sec.enabled)
1631 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL; 1620 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL;
1632 if (priv->config & CFG_PASSIVE_SCAN) 1621 if (priv->config & CFG_PASSIVE_SCAN)
1633 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE; 1622 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE;
@@ -1709,8 +1698,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1709 (priv->status & STATUS_RESET_PENDING)) { 1698 (priv->status & STATUS_RESET_PENDING)) {
1710 /* Power cycle the card ... */ 1699 /* Power cycle the card ... */
1711 if (ipw2100_power_cycle_adapter(priv)) { 1700 if (ipw2100_power_cycle_adapter(priv)) {
1712 printk(KERN_WARNING DRV_NAME ": %s: Could not cycle adapter.\n", 1701 printk(KERN_WARNING DRV_NAME
1713 priv->net_dev->name); 1702 ": %s: Could not cycle adapter.\n",
1703 priv->net_dev->name);
1714 rc = 1; 1704 rc = 1;
1715 goto exit; 1705 goto exit;
1716 } 1706 }
@@ -1719,8 +1709,9 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1719 1709
1720 /* Load the firmware, start the clocks, etc. */ 1710 /* Load the firmware, start the clocks, etc. */
1721 if (ipw2100_start_adapter(priv)) { 1711 if (ipw2100_start_adapter(priv)) {
1722 printk(KERN_ERR DRV_NAME ": %s: Failed to start the firmware.\n", 1712 printk(KERN_ERR DRV_NAME
1723 priv->net_dev->name); 1713 ": %s: Failed to start the firmware.\n",
1714 priv->net_dev->name);
1724 rc = 1; 1715 rc = 1;
1725 goto exit; 1716 goto exit;
1726 } 1717 }
@@ -1729,16 +1720,18 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1729 1720
1730 /* Determine capabilities of this particular HW configuration */ 1721 /* Determine capabilities of this particular HW configuration */
1731 if (ipw2100_get_hw_features(priv)) { 1722 if (ipw2100_get_hw_features(priv)) {
1732 printk(KERN_ERR DRV_NAME ": %s: Failed to determine HW features.\n", 1723 printk(KERN_ERR DRV_NAME
1733 priv->net_dev->name); 1724 ": %s: Failed to determine HW features.\n",
1725 priv->net_dev->name);
1734 rc = 1; 1726 rc = 1;
1735 goto exit; 1727 goto exit;
1736 } 1728 }
1737 1729
1738 lock = LOCK_NONE; 1730 lock = LOCK_NONE;
1739 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) { 1731 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
1740 printk(KERN_ERR DRV_NAME ": %s: Failed to clear ordinal lock.\n", 1732 printk(KERN_ERR DRV_NAME
1741 priv->net_dev->name); 1733 ": %s: Failed to clear ordinal lock.\n",
1734 priv->net_dev->name);
1742 rc = 1; 1735 rc = 1;
1743 goto exit; 1736 goto exit;
1744 } 1737 }
@@ -1764,7 +1757,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1764 * HOST_COMPLETE */ 1757 * HOST_COMPLETE */
1765 if (ipw2100_adapter_setup(priv)) { 1758 if (ipw2100_adapter_setup(priv)) {
1766 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n", 1759 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n",
1767 priv->net_dev->name); 1760 priv->net_dev->name);
1768 rc = 1; 1761 rc = 1;
1769 goto exit; 1762 goto exit;
1770 } 1763 }
@@ -1773,20 +1766,19 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1773 /* Enable the adapter - sends HOST_COMPLETE */ 1766 /* Enable the adapter - sends HOST_COMPLETE */
1774 if (ipw2100_enable_adapter(priv)) { 1767 if (ipw2100_enable_adapter(priv)) {
1775 printk(KERN_ERR DRV_NAME ": " 1768 printk(KERN_ERR DRV_NAME ": "
1776 "%s: failed in call to enable adapter.\n", 1769 "%s: failed in call to enable adapter.\n",
1777 priv->net_dev->name); 1770 priv->net_dev->name);
1778 ipw2100_hw_stop_adapter(priv); 1771 ipw2100_hw_stop_adapter(priv);
1779 rc = 1; 1772 rc = 1;
1780 goto exit; 1773 goto exit;
1781 } 1774 }
1782 1775
1783
1784 /* Start a scan . . . */ 1776 /* Start a scan . . . */
1785 ipw2100_set_scan_options(priv); 1777 ipw2100_set_scan_options(priv);
1786 ipw2100_start_scan(priv); 1778 ipw2100_start_scan(priv);
1787 } 1779 }
1788 1780
1789 exit: 1781 exit:
1790 return rc; 1782 return rc;
1791} 1783}
1792 1784
@@ -1802,8 +1794,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1802 unsigned long flags; 1794 unsigned long flags;
1803 union iwreq_data wrqu = { 1795 union iwreq_data wrqu = {
1804 .ap_addr = { 1796 .ap_addr = {
1805 .sa_family = ARPHRD_ETHER 1797 .sa_family = ARPHRD_ETHER}
1806 }
1807 }; 1798 };
1808 int associated = priv->status & STATUS_ASSOCIATED; 1799 int associated = priv->status & STATUS_ASSOCIATED;
1809 1800
@@ -1842,7 +1833,7 @@ static void ipw2100_down(struct ipw2100_priv *priv)
1842 1833
1843#ifdef ACPI_CSTATE_LIMIT_DEFINED 1834#ifdef ACPI_CSTATE_LIMIT_DEFINED
1844 if (priv->config & CFG_C3_DISABLED) { 1835 if (priv->config & CFG_C3_DISABLED) {
1845 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n"); 1836 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
1846 acpi_set_cstate_limit(priv->cstate_limit); 1837 acpi_set_cstate_limit(priv->cstate_limit);
1847 priv->config &= ~CFG_C3_DISABLED; 1838 priv->config &= ~CFG_C3_DISABLED;
1848 } 1839 }
@@ -1862,14 +1853,12 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1862 unsigned long flags; 1853 unsigned long flags;
1863 union iwreq_data wrqu = { 1854 union iwreq_data wrqu = {
1864 .ap_addr = { 1855 .ap_addr = {
1865 .sa_family = ARPHRD_ETHER 1856 .sa_family = ARPHRD_ETHER}
1866 }
1867 }; 1857 };
1868 int associated = priv->status & STATUS_ASSOCIATED; 1858 int associated = priv->status & STATUS_ASSOCIATED;
1869 1859
1870 spin_lock_irqsave(&priv->low_lock, flags); 1860 spin_lock_irqsave(&priv->low_lock, flags);
1871 IPW_DEBUG_INFO(DRV_NAME ": %s: Restarting adapter.\n", 1861 IPW_DEBUG_INFO(": %s: Restarting adapter.\n", priv->net_dev->name);
1872 priv->net_dev->name);
1873 priv->resets++; 1862 priv->resets++;
1874 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); 1863 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1875 priv->status |= STATUS_SECURITY_UPDATED; 1864 priv->status |= STATUS_SECURITY_UPDATED;
@@ -1894,7 +1883,6 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
1894 1883
1895} 1884}
1896 1885
1897
1898static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status) 1886static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1899{ 1887{
1900 1888
@@ -1904,7 +1892,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1904 u32 txrate; 1892 u32 txrate;
1905 u32 chan; 1893 u32 chan;
1906 char *txratename; 1894 char *txratename;
1907 u8 bssid[ETH_ALEN]; 1895 u8 bssid[ETH_ALEN];
1908 1896
1909 /* 1897 /*
1910 * TBD: BSSID is usually 00:00:00:00:00:00 here and not 1898 * TBD: BSSID is usually 00:00:00:00:00:00 here and not
@@ -1918,16 +1906,15 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1918 essid, &essid_len); 1906 essid, &essid_len);
1919 if (ret) { 1907 if (ret) {
1920 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1908 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1921 __LINE__); 1909 __LINE__);
1922 return; 1910 return;
1923 } 1911 }
1924 1912
1925 len = sizeof(u32); 1913 len = sizeof(u32);
1926 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, 1914 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &txrate, &len);
1927 &txrate, &len);
1928 if (ret) { 1915 if (ret) {
1929 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1916 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1930 __LINE__); 1917 __LINE__);
1931 return; 1918 return;
1932 } 1919 }
1933 1920
@@ -1935,19 +1922,18 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1935 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len); 1922 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len);
1936 if (ret) { 1923 if (ret) {
1937 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1924 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1938 __LINE__); 1925 __LINE__);
1939 return; 1926 return;
1940 } 1927 }
1941 len = ETH_ALEN; 1928 len = ETH_ALEN;
1942 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len); 1929 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
1943 if (ret) { 1930 if (ret) {
1944 IPW_DEBUG_INFO("failed querying ordinals at line %d\n", 1931 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1945 __LINE__); 1932 __LINE__);
1946 return; 1933 return;
1947 } 1934 }
1948 memcpy(priv->ieee->bssid, bssid, ETH_ALEN); 1935 memcpy(priv->ieee->bssid, bssid, ETH_ALEN);
1949 1936
1950
1951 switch (txrate) { 1937 switch (txrate) {
1952 case TX_RATE_1_MBIT: 1938 case TX_RATE_1_MBIT:
1953 txratename = "1Mbps"; 1939 txratename = "1Mbps";
@@ -1974,7 +1960,7 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1974 1960
1975 /* now we copy read ssid into dev */ 1961 /* now we copy read ssid into dev */
1976 if (!(priv->config & CFG_STATIC_ESSID)) { 1962 if (!(priv->config & CFG_STATIC_ESSID)) {
1977 priv->essid_len = min((u8)essid_len, (u8)IW_ESSID_MAX_SIZE); 1963 priv->essid_len = min((u8) essid_len, (u8) IW_ESSID_MAX_SIZE);
1978 memcpy(priv->essid, essid, priv->essid_len); 1964 memcpy(priv->essid, essid, priv->essid_len);
1979 } 1965 }
1980 priv->channel = chan; 1966 priv->channel = chan;
@@ -1986,7 +1972,6 @@ static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1986 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10); 1972 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
1987} 1973}
1988 1974
1989
1990static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid, 1975static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
1991 int length, int batch_mode) 1976 int length, int batch_mode)
1992{ 1977{
@@ -2001,8 +1986,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2001 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len)); 1986 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
2002 1987
2003 if (ssid_len) 1988 if (ssid_len)
2004 memcpy((char*)cmd.host_command_parameters, 1989 memcpy(cmd.host_command_parameters, essid, ssid_len);
2005 essid, ssid_len);
2006 1990
2007 if (!batch_mode) { 1991 if (!batch_mode) {
2008 err = ipw2100_disable_adapter(priv); 1992 err = ipw2100_disable_adapter(priv);
@@ -2014,7 +1998,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2014 * disable auto association -- so we cheat by setting a bogus SSID */ 1998 * disable auto association -- so we cheat by setting a bogus SSID */
2015 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) { 1999 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) {
2016 int i; 2000 int i;
2017 u8 *bogus = (u8*)cmd.host_command_parameters; 2001 u8 *bogus = (u8 *) cmd.host_command_parameters;
2018 for (i = 0; i < IW_ESSID_MAX_SIZE; i++) 2002 for (i = 0; i < IW_ESSID_MAX_SIZE; i++)
2019 bogus[i] = 0x18 + i; 2003 bogus[i] = 0x18 + i;
2020 cmd.host_command_length = IW_ESSID_MAX_SIZE; 2004 cmd.host_command_length = IW_ESSID_MAX_SIZE;
@@ -2025,8 +2009,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
2025 2009
2026 err = ipw2100_hw_send_command(priv, &cmd); 2010 err = ipw2100_hw_send_command(priv, &cmd);
2027 if (!err) { 2011 if (!err) {
2028 memset(priv->essid + ssid_len, 0, 2012 memset(priv->essid + ssid_len, 0, IW_ESSID_MAX_SIZE - ssid_len);
2029 IW_ESSID_MAX_SIZE - ssid_len);
2030 memcpy(priv->essid, essid, ssid_len); 2013 memcpy(priv->essid, essid, ssid_len);
2031 priv->essid_len = ssid_len; 2014 priv->essid_len = ssid_len;
2032 } 2015 }
@@ -2071,14 +2054,14 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
2071static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) 2054static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
2072{ 2055{
2073 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n", 2056 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n",
2074 priv->net_dev->name); 2057 priv->net_dev->name);
2075 2058
2076 /* RF_KILL is now enabled (else we wouldn't be here) */ 2059 /* RF_KILL is now enabled (else we wouldn't be here) */
2077 priv->status |= STATUS_RF_KILL_HW; 2060 priv->status |= STATUS_RF_KILL_HW;
2078 2061
2079#ifdef ACPI_CSTATE_LIMIT_DEFINED 2062#ifdef ACPI_CSTATE_LIMIT_DEFINED
2080 if (priv->config & CFG_C3_DISABLED) { 2063 if (priv->config & CFG_C3_DISABLED) {
2081 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n"); 2064 IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
2082 acpi_set_cstate_limit(priv->cstate_limit); 2065 acpi_set_cstate_limit(priv->cstate_limit);
2083 priv->config &= ~CFG_C3_DISABLED; 2066 priv->config &= ~CFG_C3_DISABLED;
2084 } 2067 }
@@ -2102,16 +2085,16 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
2102#define IPW2100_HANDLER(v, f) { v, f, # v } 2085#define IPW2100_HANDLER(v, f) { v, f, # v }
2103struct ipw2100_status_indicator { 2086struct ipw2100_status_indicator {
2104 int status; 2087 int status;
2105 void (*cb)(struct ipw2100_priv *priv, u32 status); 2088 void (*cb) (struct ipw2100_priv * priv, u32 status);
2106 char *name; 2089 char *name;
2107}; 2090};
2108#else 2091#else
2109#define IPW2100_HANDLER(v, f) { v, f } 2092#define IPW2100_HANDLER(v, f) { v, f }
2110struct ipw2100_status_indicator { 2093struct ipw2100_status_indicator {
2111 int status; 2094 int status;
2112 void (*cb)(struct ipw2100_priv *priv, u32 status); 2095 void (*cb) (struct ipw2100_priv * priv, u32 status);
2113}; 2096};
2114#endif /* CONFIG_IPW_DEBUG */ 2097#endif /* CONFIG_IPW_DEBUG */
2115 2098
2116static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status) 2099static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
2117{ 2100{
@@ -2135,7 +2118,6 @@ static const struct ipw2100_status_indicator status_handlers[] = {
2135 IPW2100_HANDLER(-1, NULL) 2118 IPW2100_HANDLER(-1, NULL)
2136}; 2119};
2137 2120
2138
2139static void isr_status_change(struct ipw2100_priv *priv, int status) 2121static void isr_status_change(struct ipw2100_priv *priv, int status)
2140{ 2122{
2141 int i; 2123 int i;
@@ -2153,7 +2135,7 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
2153 for (i = 0; status_handlers[i].status != -1; i++) { 2135 for (i = 0; status_handlers[i].status != -1; i++) {
2154 if (status == status_handlers[i].status) { 2136 if (status == status_handlers[i].status) {
2155 IPW_DEBUG_NOTIF("Status change: %s\n", 2137 IPW_DEBUG_NOTIF("Status change: %s\n",
2156 status_handlers[i].name); 2138 status_handlers[i].name);
2157 if (status_handlers[i].cb) 2139 if (status_handlers[i].cb)
2158 status_handlers[i].cb(priv, status); 2140 status_handlers[i].cb(priv, status);
2159 priv->wstats.status = status; 2141 priv->wstats.status = status;
@@ -2164,9 +2146,8 @@ static void isr_status_change(struct ipw2100_priv *priv, int status)
2164 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status); 2146 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status);
2165} 2147}
2166 2148
2167static void isr_rx_complete_command( 2149static void isr_rx_complete_command(struct ipw2100_priv *priv,
2168 struct ipw2100_priv *priv, 2150 struct ipw2100_cmd_header *cmd)
2169 struct ipw2100_cmd_header *cmd)
2170{ 2151{
2171#ifdef CONFIG_IPW_DEBUG 2152#ifdef CONFIG_IPW_DEBUG
2172 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) { 2153 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
@@ -2196,10 +2177,8 @@ static const char *frame_types[] = {
2196}; 2177};
2197#endif 2178#endif
2198 2179
2199 2180static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv,
2200static inline int ipw2100_alloc_skb( 2181 struct ipw2100_rx_packet *packet)
2201 struct ipw2100_priv *priv,
2202 struct ipw2100_rx_packet *packet)
2203{ 2182{
2204 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx)); 2183 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
2205 if (!packet->skb) 2184 if (!packet->skb)
@@ -2215,7 +2194,6 @@ static inline int ipw2100_alloc_skb(
2215 return 0; 2194 return 0;
2216} 2195}
2217 2196
2218
2219#define SEARCH_ERROR 0xffffffff 2197#define SEARCH_ERROR 0xffffffff
2220#define SEARCH_FAIL 0xfffffffe 2198#define SEARCH_FAIL 0xfffffffe
2221#define SEARCH_SUCCESS 0xfffffff0 2199#define SEARCH_SUCCESS 0xfffffff0
@@ -2229,10 +2207,10 @@ static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
2229 if (priv->snapshot[0]) 2207 if (priv->snapshot[0])
2230 return 1; 2208 return 1;
2231 for (i = 0; i < 0x30; i++) { 2209 for (i = 0; i < 0x30; i++) {
2232 priv->snapshot[i] = (u8*)kmalloc(0x1000, GFP_ATOMIC); 2210 priv->snapshot[i] = (u8 *) kmalloc(0x1000, GFP_ATOMIC);
2233 if (!priv->snapshot[i]) { 2211 if (!priv->snapshot[i]) {
2234 IPW_DEBUG_INFO("%s: Error allocating snapshot " 2212 IPW_DEBUG_INFO("%s: Error allocating snapshot "
2235 "buffer %d\n", priv->net_dev->name, i); 2213 "buffer %d\n", priv->net_dev->name, i);
2236 while (i > 0) 2214 while (i > 0)
2237 kfree(priv->snapshot[--i]); 2215 kfree(priv->snapshot[--i]);
2238 priv->snapshot[0] = NULL; 2216 priv->snapshot[0] = NULL;
@@ -2253,7 +2231,7 @@ static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
2253 priv->snapshot[0] = NULL; 2231 priv->snapshot[0] = NULL;
2254} 2232}
2255 2233
2256static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf, 2234static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
2257 size_t len, int mode) 2235 size_t len, int mode)
2258{ 2236{
2259 u32 i, j; 2237 u32 i, j;
@@ -2270,9 +2248,9 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2270 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) { 2248 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) {
2271 read_nic_dword(priv->net_dev, i, &tmp); 2249 read_nic_dword(priv->net_dev, i, &tmp);
2272 if (mode == SEARCH_SNAPSHOT) 2250 if (mode == SEARCH_SNAPSHOT)
2273 *(u32 *)SNAPSHOT_ADDR(i) = tmp; 2251 *(u32 *) SNAPSHOT_ADDR(i) = tmp;
2274 if (ret == SEARCH_FAIL) { 2252 if (ret == SEARCH_FAIL) {
2275 d = (u8*)&tmp; 2253 d = (u8 *) & tmp;
2276 for (j = 0; j < 4; j++) { 2254 for (j = 0; j < 4; j++) {
2277 if (*s != *d) { 2255 if (*s != *d) {
2278 s = in_buf; 2256 s = in_buf;
@@ -2310,8 +2288,7 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2310static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH]; 2288static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
2311#endif 2289#endif
2312 2290
2313static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, 2291static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
2314 int i)
2315{ 2292{
2316#ifdef CONFIG_IPW_DEBUG_C3 2293#ifdef CONFIG_IPW_DEBUG_C3
2317 struct ipw2100_status *status = &priv->status_queue.drv[i]; 2294 struct ipw2100_status *status = &priv->status_queue.drv[i];
@@ -2322,11 +2299,11 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2322 int limit; 2299 int limit;
2323#endif 2300#endif
2324 2301
2325 IPW_DEBUG_INFO(DRV_NAME ": PCI latency error detected at " 2302 IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
2326 "0x%04zX.\n", i * sizeof(struct ipw2100_status)); 2303 i * sizeof(struct ipw2100_status));
2327 2304
2328#ifdef ACPI_CSTATE_LIMIT_DEFINED 2305#ifdef ACPI_CSTATE_LIMIT_DEFINED
2329 IPW_DEBUG_INFO(DRV_NAME ": Disabling C3 transitions.\n"); 2306 IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
2330 limit = acpi_get_cstate_limit(); 2307 limit = acpi_get_cstate_limit();
2331 if (limit > 2) { 2308 if (limit > 2) {
2332 priv->cstate_limit = limit; 2309 priv->cstate_limit = limit;
@@ -2346,9 +2323,9 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2346 2323
2347 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED) 2324 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
2348 break; 2325 break;
2349 } while (j--); 2326 } while (j--);
2350 2327
2351 match = ipw2100_match_buf(priv, (u8*)status, 2328 match = ipw2100_match_buf(priv, (u8 *) status,
2352 sizeof(struct ipw2100_status), 2329 sizeof(struct ipw2100_status),
2353 SEARCH_SNAPSHOT); 2330 SEARCH_SNAPSHOT);
2354 if (match < SEARCH_SUCCESS) 2331 if (match < SEARCH_SUCCESS)
@@ -2360,7 +2337,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2360 IPW_DEBUG_INFO("%s: No DMA status match in " 2337 IPW_DEBUG_INFO("%s: No DMA status match in "
2361 "Firmware.\n", priv->net_dev->name); 2338 "Firmware.\n", priv->net_dev->name);
2362 2339
2363 printk_buf((u8*)priv->status_queue.drv, 2340 printk_buf((u8 *) priv->status_queue.drv,
2364 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH); 2341 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
2365#endif 2342#endif
2366 2343
@@ -2392,26 +2369,26 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
2392 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); 2369 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2393 return; 2370 return;
2394 } 2371 }
2395 2372#ifdef CONFIG_IPW2100_MONITOR
2396 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR && 2373 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
2374 priv->config & CFG_CRC_CHECK &&
2397 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) { 2375 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2398 IPW_DEBUG_RX("CRC error in packet. Dropping.\n"); 2376 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2399 priv->ieee->stats.rx_errors++; 2377 priv->ieee->stats.rx_errors++;
2400 return; 2378 return;
2401 } 2379 }
2380#endif
2402 2381
2403 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR && 2382 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
2404 !(priv->status & STATUS_ASSOCIATED))) { 2383 !(priv->status & STATUS_ASSOCIATED))) {
2405 IPW_DEBUG_DROP("Dropping packet while not associated.\n"); 2384 IPW_DEBUG_DROP("Dropping packet while not associated.\n");
2406 priv->wstats.discard.misc++; 2385 priv->wstats.discard.misc++;
2407 return; 2386 return;
2408 } 2387 }
2409 2388
2410
2411 pci_unmap_single(priv->pci_dev, 2389 pci_unmap_single(priv->pci_dev,
2412 packet->dma_addr, 2390 packet->dma_addr,
2413 sizeof(struct ipw2100_rx), 2391 sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE);
2414 PCI_DMA_FROMDEVICE);
2415 2392
2416 skb_put(packet->skb, status->frame_size); 2393 skb_put(packet->skb, status->frame_size);
2417 2394
@@ -2438,8 +2415,8 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
2438 /* We need to allocate a new SKB and attach it to the RDB. */ 2415 /* We need to allocate a new SKB and attach it to the RDB. */
2439 if (unlikely(ipw2100_alloc_skb(priv, packet))) { 2416 if (unlikely(ipw2100_alloc_skb(priv, packet))) {
2440 printk(KERN_WARNING DRV_NAME ": " 2417 printk(KERN_WARNING DRV_NAME ": "
2441 "%s: Unable to allocate SKB onto RBD ring - disabling " 2418 "%s: Unable to allocate SKB onto RBD ring - disabling "
2442 "adapter.\n", priv->net_dev->name); 2419 "adapter.\n", priv->net_dev->name);
2443 /* TODO: schedule adapter shutdown */ 2420 /* TODO: schedule adapter shutdown */
2444 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n"); 2421 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
2445 } 2422 }
@@ -2534,11 +2511,11 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2534 2511
2535 /* Sync the DMA for the STATUS buffer so CPU is sure to get 2512 /* Sync the DMA for the STATUS buffer so CPU is sure to get
2536 * the correct values */ 2513 * the correct values */
2537 pci_dma_sync_single_for_cpu( 2514 pci_dma_sync_single_for_cpu(priv->pci_dev,
2538 priv->pci_dev, 2515 sq->nic +
2539 sq->nic + sizeof(struct ipw2100_status) * i, 2516 sizeof(struct ipw2100_status) * i,
2540 sizeof(struct ipw2100_status), 2517 sizeof(struct ipw2100_status),
2541 PCI_DMA_FROMDEVICE); 2518 PCI_DMA_FROMDEVICE);
2542 2519
2543 /* Sync the DMA for the RX buffer so CPU is sure to get 2520 /* Sync the DMA for the RX buffer so CPU is sure to get
2544 * the correct values */ 2521 * the correct values */
@@ -2552,8 +2529,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2552 } 2529 }
2553 2530
2554 u = packet->rxp; 2531 u = packet->rxp;
2555 frame_type = sq->drv[i].status_fields & 2532 frame_type = sq->drv[i].status_fields & STATUS_TYPE_MASK;
2556 STATUS_TYPE_MASK;
2557 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM; 2533 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM;
2558 stats.len = sq->drv[i].frame_size; 2534 stats.len = sq->drv[i].frame_size;
2559 2535
@@ -2562,16 +2538,14 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2562 stats.mask |= IEEE80211_STATMASK_RSSI; 2538 stats.mask |= IEEE80211_STATMASK_RSSI;
2563 stats.freq = IEEE80211_24GHZ_BAND; 2539 stats.freq = IEEE80211_24GHZ_BAND;
2564 2540
2565 IPW_DEBUG_RX( 2541 IPW_DEBUG_RX("%s: '%s' frame type received (%d).\n",
2566 "%s: '%s' frame type received (%d).\n", 2542 priv->net_dev->name, frame_types[frame_type],
2567 priv->net_dev->name, frame_types[frame_type], 2543 stats.len);
2568 stats.len);
2569 2544
2570 switch (frame_type) { 2545 switch (frame_type) {
2571 case COMMAND_STATUS_VAL: 2546 case COMMAND_STATUS_VAL:
2572 /* Reset Rx watchdog */ 2547 /* Reset Rx watchdog */
2573 isr_rx_complete_command( 2548 isr_rx_complete_command(priv, &u->rx_data.command);
2574 priv, &u->rx_data.command);
2575 break; 2549 break;
2576 2550
2577 case STATUS_CHANGE_VAL: 2551 case STATUS_CHANGE_VAL:
@@ -2588,12 +2562,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2588#endif 2562#endif
2589 if (stats.len < sizeof(u->rx_data.header)) 2563 if (stats.len < sizeof(u->rx_data.header))
2590 break; 2564 break;
2591 switch (WLAN_FC_GET_TYPE(u->rx_data.header. 2565 switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
2592 frame_ctl)) {
2593 case IEEE80211_FTYPE_MGMT: 2566 case IEEE80211_FTYPE_MGMT:
2594 ieee80211_rx_mgt(priv->ieee, 2567 ieee80211_rx_mgt(priv->ieee,
2595 &u->rx_data.header, 2568 &u->rx_data.header, &stats);
2596 &stats);
2597 break; 2569 break;
2598 2570
2599 case IEEE80211_FTYPE_CTL: 2571 case IEEE80211_FTYPE_CTL:
@@ -2607,7 +2579,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2607 break; 2579 break;
2608 } 2580 }
2609 2581
2610 increment: 2582 increment:
2611 /* clear status field associated with this RBD */ 2583 /* clear status field associated with this RBD */
2612 rxq->drv[i].status.info.field = 0; 2584 rxq->drv[i].status.info.field = 0;
2613 2585
@@ -2619,12 +2591,10 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2619 rxq->next = (i ? i : rxq->entries) - 1; 2591 rxq->next = (i ? i : rxq->entries) - 1;
2620 2592
2621 write_register(priv->net_dev, 2593 write_register(priv->net_dev,
2622 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, 2594 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, rxq->next);
2623 rxq->next);
2624 } 2595 }
2625} 2596}
2626 2597
2627
2628/* 2598/*
2629 * __ipw2100_tx_process 2599 * __ipw2100_tx_process
2630 * 2600 *
@@ -2667,7 +2637,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2667static inline int __ipw2100_tx_process(struct ipw2100_priv *priv) 2637static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2668{ 2638{
2669 struct ipw2100_bd_queue *txq = &priv->tx_queue; 2639 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2670 struct ipw2100_bd *tbd; 2640 struct ipw2100_bd *tbd;
2671 struct list_head *element; 2641 struct list_head *element;
2672 struct ipw2100_tx_packet *packet; 2642 struct ipw2100_tx_packet *packet;
2673 int descriptors_used; 2643 int descriptors_used;
@@ -2680,7 +2650,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2680 element = priv->fw_pend_list.next; 2650 element = priv->fw_pend_list.next;
2681 2651
2682 packet = list_entry(element, struct ipw2100_tx_packet, list); 2652 packet = list_entry(element, struct ipw2100_tx_packet, list);
2683 tbd = &txq->drv[packet->index]; 2653 tbd = &txq->drv[packet->index];
2684 2654
2685 /* Determine how many TBD entries must be finished... */ 2655 /* Determine how many TBD entries must be finished... */
2686 switch (packet->type) { 2656 switch (packet->type) {
@@ -2693,14 +2663,14 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2693 case DATA: 2663 case DATA:
2694 /* DATA uses two slots; advance and loop position. */ 2664 /* DATA uses two slots; advance and loop position. */
2695 descriptors_used = tbd->num_fragments; 2665 descriptors_used = tbd->num_fragments;
2696 frag_num = tbd->num_fragments - 1; 2666 frag_num = tbd->num_fragments - 1;
2697 e = txq->oldest + frag_num; 2667 e = txq->oldest + frag_num;
2698 e %= txq->entries; 2668 e %= txq->entries;
2699 break; 2669 break;
2700 2670
2701 default: 2671 default:
2702 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n", 2672 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n",
2703 priv->net_dev->name); 2673 priv->net_dev->name);
2704 return 0; 2674 return 0;
2705 } 2675 }
2706 2676
@@ -2716,13 +2686,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2716 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n", 2686 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n",
2717 priv->net_dev->name); 2687 priv->net_dev->name);
2718 2688
2719 /* 2689 /*
2720 * txq->next is the index of the last packet written txq->oldest is 2690 * txq->next is the index of the last packet written txq->oldest is
2721 * the index of the r is the index of the next packet to be read by 2691 * the index of the r is the index of the next packet to be read by
2722 * firmware 2692 * firmware
2723 */ 2693 */
2724 2694
2725
2726 /* 2695 /*
2727 * Quick graphic to help you visualize the following 2696 * Quick graphic to help you visualize the following
2728 * if / else statement 2697 * if / else statement
@@ -2750,23 +2719,20 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2750#ifdef CONFIG_IPW_DEBUG 2719#ifdef CONFIG_IPW_DEBUG
2751 { 2720 {
2752 int i = txq->oldest; 2721 int i = txq->oldest;
2753 IPW_DEBUG_TX( 2722 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
2754 "TX%d V=%p P=%04X T=%04X L=%d\n", i, 2723 &txq->drv[i],
2755 &txq->drv[i], 2724 (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),
2756 (u32)(txq->nic + i * sizeof(struct ipw2100_bd)), 2725 txq->drv[i].host_addr, txq->drv[i].buf_length);
2757 txq->drv[i].host_addr,
2758 txq->drv[i].buf_length);
2759 2726
2760 if (packet->type == DATA) { 2727 if (packet->type == DATA) {
2761 i = (i + 1) % txq->entries; 2728 i = (i + 1) % txq->entries;
2762 2729
2763 IPW_DEBUG_TX( 2730 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
2764 "TX%d V=%p P=%04X T=%04X L=%d\n", i, 2731 &txq->drv[i],
2765 &txq->drv[i], 2732 (u32) (txq->nic + i *
2766 (u32)(txq->nic + i * 2733 sizeof(struct ipw2100_bd)),
2767 sizeof(struct ipw2100_bd)), 2734 (u32) txq->drv[i].host_addr,
2768 (u32)txq->drv[i].host_addr, 2735 txq->drv[i].buf_length);
2769 txq->drv[i].buf_length);
2770 } 2736 }
2771 } 2737 }
2772#endif 2738#endif
@@ -2780,23 +2746,18 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2780 priv->net_dev->name, txq->oldest, packet->index); 2746 priv->net_dev->name, txq->oldest, packet->index);
2781 2747
2782 /* DATA packet; we have to unmap and free the SKB */ 2748 /* DATA packet; we have to unmap and free the SKB */
2783 priv->ieee->stats.tx_packets++;
2784 for (i = 0; i < frag_num; i++) { 2749 for (i = 0; i < frag_num; i++) {
2785 tbd = &txq->drv[(packet->index + 1 + i) % 2750 tbd = &txq->drv[(packet->index + 1 + i) % txq->entries];
2786 txq->entries];
2787 2751
2788 IPW_DEBUG_TX( 2752 IPW_DEBUG_TX("TX%d P=%08x L=%d\n",
2789 "TX%d P=%08x L=%d\n", 2753 (packet->index + 1 + i) % txq->entries,
2790 (packet->index + 1 + i) % txq->entries, 2754 tbd->host_addr, tbd->buf_length);
2791 tbd->host_addr, tbd->buf_length);
2792 2755
2793 pci_unmap_single(priv->pci_dev, 2756 pci_unmap_single(priv->pci_dev,
2794 tbd->host_addr, 2757 tbd->host_addr,
2795 tbd->buf_length, 2758 tbd->buf_length, PCI_DMA_TODEVICE);
2796 PCI_DMA_TODEVICE);
2797 } 2759 }
2798 2760
2799 priv->ieee->stats.tx_bytes += packet->info.d_struct.txb->payload_size;
2800 ieee80211_txb_free(packet->info.d_struct.txb); 2761 ieee80211_txb_free(packet->info.d_struct.txb);
2801 packet->info.d_struct.txb = NULL; 2762 packet->info.d_struct.txb = NULL;
2802 2763
@@ -2805,13 +2766,8 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2805 2766
2806 /* We have a free slot in the Tx queue, so wake up the 2767 /* We have a free slot in the Tx queue, so wake up the
2807 * transmit layer if it is stopped. */ 2768 * transmit layer if it is stopped. */
2808 if (priv->status & STATUS_ASSOCIATED && 2769 if (priv->status & STATUS_ASSOCIATED)
2809 netif_queue_stopped(priv->net_dev)) {
2810 IPW_DEBUG_INFO(KERN_INFO
2811 "%s: Waking net queue.\n",
2812 priv->net_dev->name);
2813 netif_wake_queue(priv->net_dev); 2770 netif_wake_queue(priv->net_dev);
2814 }
2815 2771
2816 /* A packet was processed by the hardware, so update the 2772 /* A packet was processed by the hardware, so update the
2817 * watchdog */ 2773 * watchdog */
@@ -2829,11 +2785,12 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2829#ifdef CONFIG_IPW_DEBUG 2785#ifdef CONFIG_IPW_DEBUG
2830 if (packet->info.c_struct.cmd->host_command_reg < 2786 if (packet->info.c_struct.cmd->host_command_reg <
2831 sizeof(command_types) / sizeof(*command_types)) 2787 sizeof(command_types) / sizeof(*command_types))
2832 IPW_DEBUG_TX( 2788 IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
2833 "Command '%s (%d)' processed: %d.\n", 2789 command_types[packet->info.c_struct.cmd->
2834 command_types[packet->info.c_struct.cmd->host_command_reg], 2790 host_command_reg],
2835 packet->info.c_struct.cmd->host_command_reg, 2791 packet->info.c_struct.cmd->
2836 packet->info.c_struct.cmd->cmd_status_reg); 2792 host_command_reg,
2793 packet->info.c_struct.cmd->cmd_status_reg);
2837#endif 2794#endif
2838 2795
2839 list_add_tail(element, &priv->msg_free_list); 2796 list_add_tail(element, &priv->msg_free_list);
@@ -2848,17 +2805,17 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2848 SET_STAT(&priv->txq_stat, txq->available); 2805 SET_STAT(&priv->txq_stat, txq->available);
2849 2806
2850 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n", 2807 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n",
2851 jiffies - packet->jiffy_start); 2808 jiffies - packet->jiffy_start);
2852 2809
2853 return (!list_empty(&priv->fw_pend_list)); 2810 return (!list_empty(&priv->fw_pend_list));
2854} 2811}
2855 2812
2856
2857static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv) 2813static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2858{ 2814{
2859 int i = 0; 2815 int i = 0;
2860 2816
2861 while (__ipw2100_tx_process(priv) && i < 200) i++; 2817 while (__ipw2100_tx_process(priv) && i < 200)
2818 i++;
2862 2819
2863 if (i == 200) { 2820 if (i == 200) {
2864 printk(KERN_WARNING DRV_NAME ": " 2821 printk(KERN_WARNING DRV_NAME ": "
@@ -2867,7 +2824,6 @@ static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2867 } 2824 }
2868} 2825}
2869 2826
2870
2871static void ipw2100_tx_send_commands(struct ipw2100_priv *priv) 2827static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2872{ 2828{
2873 struct list_head *element; 2829 struct list_head *element;
@@ -2892,13 +2848,12 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2892 list_del(element); 2848 list_del(element);
2893 DEC_STAT(&priv->msg_pend_stat); 2849 DEC_STAT(&priv->msg_pend_stat);
2894 2850
2895 packet = list_entry(element, 2851 packet = list_entry(element, struct ipw2100_tx_packet, list);
2896 struct ipw2100_tx_packet, list);
2897 2852
2898 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n", 2853 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
2899 &txq->drv[txq->next], 2854 &txq->drv[txq->next],
2900 (void*)(txq->nic + txq->next * 2855 (void *)(txq->nic + txq->next *
2901 sizeof(struct ipw2100_bd))); 2856 sizeof(struct ipw2100_bd)));
2902 2857
2903 packet->index = txq->next; 2858 packet->index = txq->next;
2904 2859
@@ -2911,8 +2866,8 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2911 * with f/w debug version */ 2866 * with f/w debug version */
2912 tbd->num_fragments = 1; 2867 tbd->num_fragments = 1;
2913 tbd->status.info.field = 2868 tbd->status.info.field =
2914 IPW_BD_STATUS_TX_FRAME_COMMAND | 2869 IPW_BD_STATUS_TX_FRAME_COMMAND |
2915 IPW_BD_STATUS_TX_INTERRUPT_ENABLE; 2870 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
2916 2871
2917 /* update TBD queue counters */ 2872 /* update TBD queue counters */
2918 txq->next++; 2873 txq->next++;
@@ -2934,7 +2889,6 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2934 } 2889 }
2935} 2890}
2936 2891
2937
2938/* 2892/*
2939 * ipw2100_tx_send_data 2893 * ipw2100_tx_send_data
2940 * 2894 *
@@ -2946,7 +2900,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2946 struct ipw2100_bd_queue *txq = &priv->tx_queue; 2900 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2947 struct ipw2100_bd *tbd; 2901 struct ipw2100_bd *tbd;
2948 int next = txq->next; 2902 int next = txq->next;
2949 int i = 0; 2903 int i = 0;
2950 struct ipw2100_data_header *ipw_hdr; 2904 struct ipw2100_data_header *ipw_hdr;
2951 struct ieee80211_hdr_3addr *hdr; 2905 struct ieee80211_hdr_3addr *hdr;
2952 2906
@@ -2958,20 +2912,18 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2958 * maintained between the r and w indexes 2912 * maintained between the r and w indexes
2959 */ 2913 */
2960 element = priv->tx_pend_list.next; 2914 element = priv->tx_pend_list.next;
2961 packet = list_entry(element, struct ipw2100_tx_packet, list); 2915 packet = list_entry(element, struct ipw2100_tx_packet, list);
2962 2916
2963 if (unlikely(1 + packet->info.d_struct.txb->nr_frags > 2917 if (unlikely(1 + packet->info.d_struct.txb->nr_frags >
2964 IPW_MAX_BDS)) { 2918 IPW_MAX_BDS)) {
2965 /* TODO: Support merging buffers if more than 2919 /* TODO: Support merging buffers if more than
2966 * IPW_MAX_BDS are used */ 2920 * IPW_MAX_BDS are used */
2967 IPW_DEBUG_INFO( 2921 IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded. "
2968 "%s: Maximum BD theshold exceeded. " 2922 "Increase fragmentation level.\n",
2969 "Increase fragmentation level.\n", 2923 priv->net_dev->name);
2970 priv->net_dev->name);
2971 } 2924 }
2972 2925
2973 if (txq->available <= 3 + 2926 if (txq->available <= 3 + packet->info.d_struct.txb->nr_frags) {
2974 packet->info.d_struct.txb->nr_frags) {
2975 IPW_DEBUG_TX("no room in tx_queue\n"); 2927 IPW_DEBUG_TX("no room in tx_queue\n");
2976 break; 2928 break;
2977 } 2929 }
@@ -2985,7 +2937,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2985 2937
2986 ipw_hdr = packet->info.d_struct.data; 2938 ipw_hdr = packet->info.d_struct.data;
2987 hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb-> 2939 hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
2988 fragments[0]->data; 2940 fragments[0]->data;
2989 2941
2990 if (priv->ieee->iw_mode == IW_MODE_INFRA) { 2942 if (priv->ieee->iw_mode == IW_MODE_INFRA) {
2991 /* To DS: Addr1 = BSSID, Addr2 = SA, 2943 /* To DS: Addr1 = BSSID, Addr2 = SA,
@@ -3007,7 +2959,8 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3007 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted; 2959 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted;
3008 if (packet->info.d_struct.txb->nr_frags > 1) 2960 if (packet->info.d_struct.txb->nr_frags > 1)
3009 ipw_hdr->fragment_size = 2961 ipw_hdr->fragment_size =
3010 packet->info.d_struct.txb->frag_size - IEEE80211_3ADDR_LEN; 2962 packet->info.d_struct.txb->frag_size -
2963 IEEE80211_3ADDR_LEN;
3011 else 2964 else
3012 ipw_hdr->fragment_size = 0; 2965 ipw_hdr->fragment_size = 0;
3013 2966
@@ -3015,54 +2968,53 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3015 tbd->buf_length = sizeof(struct ipw2100_data_header); 2968 tbd->buf_length = sizeof(struct ipw2100_data_header);
3016 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags; 2969 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags;
3017 tbd->status.info.field = 2970 tbd->status.info.field =
3018 IPW_BD_STATUS_TX_FRAME_802_3 | 2971 IPW_BD_STATUS_TX_FRAME_802_3 |
3019 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT; 2972 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3020 txq->next++; 2973 txq->next++;
3021 txq->next %= txq->entries; 2974 txq->next %= txq->entries;
3022 2975
3023 IPW_DEBUG_TX( 2976 IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n",
3024 "data header tbd TX%d P=%08x L=%d\n", 2977 packet->index, tbd->host_addr, tbd->buf_length);
3025 packet->index, tbd->host_addr,
3026 tbd->buf_length);
3027#ifdef CONFIG_IPW_DEBUG 2978#ifdef CONFIG_IPW_DEBUG
3028 if (packet->info.d_struct.txb->nr_frags > 1) 2979 if (packet->info.d_struct.txb->nr_frags > 1)
3029 IPW_DEBUG_FRAG("fragment Tx: %d frames\n", 2980 IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
3030 packet->info.d_struct.txb->nr_frags); 2981 packet->info.d_struct.txb->nr_frags);
3031#endif 2982#endif
3032 2983
3033 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) { 2984 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {
3034 tbd = &txq->drv[txq->next]; 2985 tbd = &txq->drv[txq->next];
3035 if (i == packet->info.d_struct.txb->nr_frags - 1) 2986 if (i == packet->info.d_struct.txb->nr_frags - 1)
3036 tbd->status.info.field = 2987 tbd->status.info.field =
3037 IPW_BD_STATUS_TX_FRAME_802_3 | 2988 IPW_BD_STATUS_TX_FRAME_802_3 |
3038 IPW_BD_STATUS_TX_INTERRUPT_ENABLE; 2989 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
3039 else 2990 else
3040 tbd->status.info.field = 2991 tbd->status.info.field =
3041 IPW_BD_STATUS_TX_FRAME_802_3 | 2992 IPW_BD_STATUS_TX_FRAME_802_3 |
3042 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT; 2993 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3043 2994
3044 tbd->buf_length = packet->info.d_struct.txb-> 2995 tbd->buf_length = packet->info.d_struct.txb->
3045 fragments[i]->len - IEEE80211_3ADDR_LEN; 2996 fragments[i]->len - IEEE80211_3ADDR_LEN;
3046 2997
3047 tbd->host_addr = pci_map_single( 2998 tbd->host_addr = pci_map_single(priv->pci_dev,
3048 priv->pci_dev, 2999 packet->info.d_struct.
3049 packet->info.d_struct.txb->fragments[i]->data + 3000 txb->fragments[i]->
3050 IEEE80211_3ADDR_LEN, 3001 data +
3051 tbd->buf_length, 3002 IEEE80211_3ADDR_LEN,
3052 PCI_DMA_TODEVICE); 3003 tbd->buf_length,
3004 PCI_DMA_TODEVICE);
3053 3005
3054 IPW_DEBUG_TX( 3006 IPW_DEBUG_TX("data frag tbd TX%d P=%08x L=%d\n",
3055 "data frag tbd TX%d P=%08x L=%d\n", 3007 txq->next, tbd->host_addr,
3056 txq->next, tbd->host_addr, tbd->buf_length); 3008 tbd->buf_length);
3057 3009
3058 pci_dma_sync_single_for_device( 3010 pci_dma_sync_single_for_device(priv->pci_dev,
3059 priv->pci_dev, tbd->host_addr, 3011 tbd->host_addr,
3060 tbd->buf_length, 3012 tbd->buf_length,
3061 PCI_DMA_TODEVICE); 3013 PCI_DMA_TODEVICE);
3062 3014
3063 txq->next++; 3015 txq->next++;
3064 txq->next %= txq->entries; 3016 txq->next %= txq->entries;
3065 } 3017 }
3066 3018
3067 txq->available -= 1 + packet->info.d_struct.txb->nr_frags; 3019 txq->available -= 1 + packet->info.d_struct.txb->nr_frags;
3068 SET_STAT(&priv->txq_stat, txq->available); 3020 SET_STAT(&priv->txq_stat, txq->available);
@@ -3078,7 +3030,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
3078 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX, 3030 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
3079 txq->next); 3031 txq->next);
3080 } 3032 }
3081 return; 3033 return;
3082} 3034}
3083 3035
3084static void ipw2100_irq_tasklet(struct ipw2100_priv *priv) 3036static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
@@ -3106,11 +3058,9 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3106 3058
3107 if (inta & IPW2100_INTA_FATAL_ERROR) { 3059 if (inta & IPW2100_INTA_FATAL_ERROR) {
3108 printk(KERN_WARNING DRV_NAME 3060 printk(KERN_WARNING DRV_NAME
3109 ": Fatal interrupt. Scheduling firmware restart.\n"); 3061 ": Fatal interrupt. Scheduling firmware restart.\n");
3110 priv->inta_other++; 3062 priv->inta_other++;
3111 write_register( 3063 write_register(dev, IPW_REG_INTA, IPW2100_INTA_FATAL_ERROR);
3112 dev, IPW_REG_INTA,
3113 IPW2100_INTA_FATAL_ERROR);
3114 3064
3115 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error); 3065 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error);
3116 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n", 3066 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n",
@@ -3125,11 +3075,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3125 } 3075 }
3126 3076
3127 if (inta & IPW2100_INTA_PARITY_ERROR) { 3077 if (inta & IPW2100_INTA_PARITY_ERROR) {
3128 printk(KERN_ERR DRV_NAME ": ***** PARITY ERROR INTERRUPT !!!! \n"); 3078 printk(KERN_ERR DRV_NAME
3079 ": ***** PARITY ERROR INTERRUPT !!!! \n");
3129 priv->inta_other++; 3080 priv->inta_other++;
3130 write_register( 3081 write_register(dev, IPW_REG_INTA, IPW2100_INTA_PARITY_ERROR);
3131 dev, IPW_REG_INTA,
3132 IPW2100_INTA_PARITY_ERROR);
3133 } 3082 }
3134 3083
3135 if (inta & IPW2100_INTA_RX_TRANSFER) { 3084 if (inta & IPW2100_INTA_RX_TRANSFER) {
@@ -3137,9 +3086,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3137 3086
3138 priv->rx_interrupts++; 3087 priv->rx_interrupts++;
3139 3088
3140 write_register( 3089 write_register(dev, IPW_REG_INTA, IPW2100_INTA_RX_TRANSFER);
3141 dev, IPW_REG_INTA,
3142 IPW2100_INTA_RX_TRANSFER);
3143 3090
3144 __ipw2100_rx_process(priv); 3091 __ipw2100_rx_process(priv);
3145 __ipw2100_tx_complete(priv); 3092 __ipw2100_tx_complete(priv);
@@ -3150,8 +3097,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3150 3097
3151 priv->tx_interrupts++; 3098 priv->tx_interrupts++;
3152 3099
3153 write_register(dev, IPW_REG_INTA, 3100 write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_TRANSFER);
3154 IPW2100_INTA_TX_TRANSFER);
3155 3101
3156 __ipw2100_tx_complete(priv); 3102 __ipw2100_tx_complete(priv);
3157 ipw2100_tx_send_commands(priv); 3103 ipw2100_tx_send_commands(priv);
@@ -3161,9 +3107,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3161 if (inta & IPW2100_INTA_TX_COMPLETE) { 3107 if (inta & IPW2100_INTA_TX_COMPLETE) {
3162 IPW_DEBUG_ISR("TX complete\n"); 3108 IPW_DEBUG_ISR("TX complete\n");
3163 priv->inta_other++; 3109 priv->inta_other++;
3164 write_register( 3110 write_register(dev, IPW_REG_INTA, IPW2100_INTA_TX_COMPLETE);
3165 dev, IPW_REG_INTA,
3166 IPW2100_INTA_TX_COMPLETE);
3167 3111
3168 __ipw2100_tx_complete(priv); 3112 __ipw2100_tx_complete(priv);
3169 } 3113 }
@@ -3171,9 +3115,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3171 if (inta & IPW2100_INTA_EVENT_INTERRUPT) { 3115 if (inta & IPW2100_INTA_EVENT_INTERRUPT) {
3172 /* ipw2100_handle_event(dev); */ 3116 /* ipw2100_handle_event(dev); */
3173 priv->inta_other++; 3117 priv->inta_other++;
3174 write_register( 3118 write_register(dev, IPW_REG_INTA, IPW2100_INTA_EVENT_INTERRUPT);
3175 dev, IPW_REG_INTA,
3176 IPW2100_INTA_EVENT_INTERRUPT);
3177 } 3119 }
3178 3120
3179 if (inta & IPW2100_INTA_FW_INIT_DONE) { 3121 if (inta & IPW2100_INTA_FW_INIT_DONE) {
@@ -3183,30 +3125,25 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3183 read_register(dev, IPW_REG_INTA, &tmp); 3125 read_register(dev, IPW_REG_INTA, &tmp);
3184 if (tmp & (IPW2100_INTA_FATAL_ERROR | 3126 if (tmp & (IPW2100_INTA_FATAL_ERROR |
3185 IPW2100_INTA_PARITY_ERROR)) { 3127 IPW2100_INTA_PARITY_ERROR)) {
3186 write_register( 3128 write_register(dev, IPW_REG_INTA,
3187 dev, IPW_REG_INTA, 3129 IPW2100_INTA_FATAL_ERROR |
3188 IPW2100_INTA_FATAL_ERROR | 3130 IPW2100_INTA_PARITY_ERROR);
3189 IPW2100_INTA_PARITY_ERROR);
3190 } 3131 }
3191 3132
3192 write_register(dev, IPW_REG_INTA, 3133 write_register(dev, IPW_REG_INTA, IPW2100_INTA_FW_INIT_DONE);
3193 IPW2100_INTA_FW_INIT_DONE);
3194 } 3134 }
3195 3135
3196 if (inta & IPW2100_INTA_STATUS_CHANGE) { 3136 if (inta & IPW2100_INTA_STATUS_CHANGE) {
3197 IPW_DEBUG_ISR("Status change interrupt\n"); 3137 IPW_DEBUG_ISR("Status change interrupt\n");
3198 priv->inta_other++; 3138 priv->inta_other++;
3199 write_register( 3139 write_register(dev, IPW_REG_INTA, IPW2100_INTA_STATUS_CHANGE);
3200 dev, IPW_REG_INTA,
3201 IPW2100_INTA_STATUS_CHANGE);
3202 } 3140 }
3203 3141
3204 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) { 3142 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) {
3205 IPW_DEBUG_ISR("slave host mode interrupt\n"); 3143 IPW_DEBUG_ISR("slave host mode interrupt\n");
3206 priv->inta_other++; 3144 priv->inta_other++;
3207 write_register( 3145 write_register(dev, IPW_REG_INTA,
3208 dev, IPW_REG_INTA, 3146 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3209 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3210 } 3147 }
3211 3148
3212 priv->in_isr--; 3149 priv->in_isr--;
@@ -3217,9 +3154,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3217 IPW_DEBUG_ISR("exit\n"); 3154 IPW_DEBUG_ISR("exit\n");
3218} 3155}
3219 3156
3220 3157static irqreturn_t ipw2100_interrupt(int irq, void *data, struct pt_regs *regs)
3221static irqreturn_t ipw2100_interrupt(int irq, void *data,
3222 struct pt_regs *regs)
3223{ 3158{
3224 struct ipw2100_priv *priv = data; 3159 struct ipw2100_priv *priv = data;
3225 u32 inta, inta_mask; 3160 u32 inta, inta_mask;
@@ -3227,7 +3162,7 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
3227 if (!data) 3162 if (!data)
3228 return IRQ_NONE; 3163 return IRQ_NONE;
3229 3164
3230 spin_lock(&priv->low_lock); 3165 spin_lock(&priv->low_lock);
3231 3166
3232 /* We check to see if we should be ignoring interrupts before 3167 /* We check to see if we should be ignoring interrupts before
3233 * we touch the hardware. During ucode load if we try and handle 3168 * we touch the hardware. During ucode load if we try and handle
@@ -3261,10 +3196,10 @@ static irqreturn_t ipw2100_interrupt(int irq, void *data,
3261 ipw2100_disable_interrupts(priv); 3196 ipw2100_disable_interrupts(priv);
3262 3197
3263 tasklet_schedule(&priv->irq_tasklet); 3198 tasklet_schedule(&priv->irq_tasklet);
3264 spin_unlock(&priv->low_lock); 3199 spin_unlock(&priv->low_lock);
3265 3200
3266 return IRQ_HANDLED; 3201 return IRQ_HANDLED;
3267 none: 3202 none:
3268 spin_unlock(&priv->low_lock); 3203 spin_unlock(&priv->low_lock);
3269 return IRQ_NONE; 3204 return IRQ_NONE;
3270} 3205}
@@ -3294,10 +3229,8 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
3294 3229
3295 packet->info.d_struct.txb = txb; 3230 packet->info.d_struct.txb = txb;
3296 3231
3297 IPW_DEBUG_TX("Sending fragment (%d bytes):\n", 3232 IPW_DEBUG_TX("Sending fragment (%d bytes):\n", txb->fragments[0]->len);
3298 txb->fragments[0]->len); 3233 printk_buf(IPW_DL_TX, txb->fragments[0]->data, txb->fragments[0]->len);
3299 printk_buf(IPW_DL_TX, txb->fragments[0]->data,
3300 txb->fragments[0]->len);
3301 3234
3302 packet->jiffy_start = jiffies; 3235 packet->jiffy_start = jiffies;
3303 3236
@@ -3312,22 +3245,23 @@ static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
3312 spin_unlock_irqrestore(&priv->low_lock, flags); 3245 spin_unlock_irqrestore(&priv->low_lock, flags);
3313 return 0; 3246 return 0;
3314 3247
3315 fail_unlock: 3248 fail_unlock:
3316 netif_stop_queue(dev); 3249 netif_stop_queue(dev);
3317 spin_unlock_irqrestore(&priv->low_lock, flags); 3250 spin_unlock_irqrestore(&priv->low_lock, flags);
3318 return 1; 3251 return 1;
3319} 3252}
3320 3253
3321
3322static int ipw2100_msg_allocate(struct ipw2100_priv *priv) 3254static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3323{ 3255{
3324 int i, j, err = -EINVAL; 3256 int i, j, err = -EINVAL;
3325 void *v; 3257 void *v;
3326 dma_addr_t p; 3258 dma_addr_t p;
3327 3259
3328 priv->msg_buffers = (struct ipw2100_tx_packet *)kmalloc( 3260 priv->msg_buffers =
3329 IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet), 3261 (struct ipw2100_tx_packet *)kmalloc(IPW_COMMAND_POOL_SIZE *
3330 GFP_KERNEL); 3262 sizeof(struct
3263 ipw2100_tx_packet),
3264 GFP_KERNEL);
3331 if (!priv->msg_buffers) { 3265 if (!priv->msg_buffers) {
3332 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg " 3266 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
3333 "buffers.\n", priv->net_dev->name); 3267 "buffers.\n", priv->net_dev->name);
@@ -3335,15 +3269,12 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3335 } 3269 }
3336 3270
3337 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) { 3271 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3338 v = pci_alloc_consistent( 3272 v = pci_alloc_consistent(priv->pci_dev,
3339 priv->pci_dev, 3273 sizeof(struct ipw2100_cmd_header), &p);
3340 sizeof(struct ipw2100_cmd_header),
3341 &p);
3342 if (!v) { 3274 if (!v) {
3343 printk(KERN_ERR DRV_NAME ": " 3275 printk(KERN_ERR DRV_NAME ": "
3344 "%s: PCI alloc failed for msg " 3276 "%s: PCI alloc failed for msg "
3345 "buffers.\n", 3277 "buffers.\n", priv->net_dev->name);
3346 priv->net_dev->name);
3347 err = -ENOMEM; 3278 err = -ENOMEM;
3348 break; 3279 break;
3349 } 3280 }
@@ -3352,7 +3283,7 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3352 3283
3353 priv->msg_buffers[i].type = COMMAND; 3284 priv->msg_buffers[i].type = COMMAND;
3354 priv->msg_buffers[i].info.c_struct.cmd = 3285 priv->msg_buffers[i].info.c_struct.cmd =
3355 (struct ipw2100_cmd_header*)v; 3286 (struct ipw2100_cmd_header *)v;
3356 priv->msg_buffers[i].info.c_struct.cmd_phys = p; 3287 priv->msg_buffers[i].info.c_struct.cmd_phys = p;
3357 } 3288 }
3358 3289
@@ -3360,11 +3291,11 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3360 return 0; 3291 return 0;
3361 3292
3362 for (j = 0; j < i; j++) { 3293 for (j = 0; j < i; j++) {
3363 pci_free_consistent( 3294 pci_free_consistent(priv->pci_dev,
3364 priv->pci_dev, 3295 sizeof(struct ipw2100_cmd_header),
3365 sizeof(struct ipw2100_cmd_header), 3296 priv->msg_buffers[j].info.c_struct.cmd,
3366 priv->msg_buffers[j].info.c_struct.cmd, 3297 priv->msg_buffers[j].info.c_struct.
3367 priv->msg_buffers[j].info.c_struct.cmd_phys); 3298 cmd_phys);
3368 } 3299 }
3369 3300
3370 kfree(priv->msg_buffers); 3301 kfree(priv->msg_buffers);
@@ -3398,7 +3329,8 @@ static void ipw2100_msg_free(struct ipw2100_priv *priv)
3398 pci_free_consistent(priv->pci_dev, 3329 pci_free_consistent(priv->pci_dev,
3399 sizeof(struct ipw2100_cmd_header), 3330 sizeof(struct ipw2100_cmd_header),
3400 priv->msg_buffers[i].info.c_struct.cmd, 3331 priv->msg_buffers[i].info.c_struct.cmd,
3401 priv->msg_buffers[i].info.c_struct.cmd_phys); 3332 priv->msg_buffers[i].info.c_struct.
3333 cmd_phys);
3402 } 3334 }
3403 3335
3404 kfree(priv->msg_buffers); 3336 kfree(priv->msg_buffers);
@@ -3424,6 +3356,7 @@ static ssize_t show_pci(struct device *d, struct device_attribute *attr,
3424 3356
3425 return out - buf; 3357 return out - buf;
3426} 3358}
3359
3427static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL); 3360static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
3428 3361
3429static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 3362static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
@@ -3432,209 +3365,269 @@ static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
3432 struct ipw2100_priv *p = d->driver_data; 3365 struct ipw2100_priv *p = d->driver_data;
3433 return sprintf(buf, "0x%08x\n", (int)p->config); 3366 return sprintf(buf, "0x%08x\n", (int)p->config);
3434} 3367}
3368
3435static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 3369static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
3436 3370
3437static ssize_t show_status(struct device *d, struct device_attribute *attr, 3371static ssize_t show_status(struct device *d, struct device_attribute *attr,
3438 char *buf) 3372 char *buf)
3439{ 3373{
3440 struct ipw2100_priv *p = d->driver_data; 3374 struct ipw2100_priv *p = d->driver_data;
3441 return sprintf(buf, "0x%08x\n", (int)p->status); 3375 return sprintf(buf, "0x%08x\n", (int)p->status);
3442} 3376}
3377
3443static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 3378static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
3444 3379
3445static ssize_t show_capability(struct device *d, struct device_attribute *attr, 3380static ssize_t show_capability(struct device *d, struct device_attribute *attr,
3446 char *buf) 3381 char *buf)
3447{ 3382{
3448 struct ipw2100_priv *p = d->driver_data; 3383 struct ipw2100_priv *p = d->driver_data;
3449 return sprintf(buf, "0x%08x\n", (int)p->capability); 3384 return sprintf(buf, "0x%08x\n", (int)p->capability);
3450} 3385}
3451static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3452 3386
3387static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3453 3388
3454#define IPW2100_REG(x) { IPW_ ##x, #x } 3389#define IPW2100_REG(x) { IPW_ ##x, #x }
3455static const struct { 3390static const struct {
3456 u32 addr; 3391 u32 addr;
3457 const char *name; 3392 const char *name;
3458} hw_data[] = { 3393} hw_data[] = {
3459 IPW2100_REG(REG_GP_CNTRL), 3394IPW2100_REG(REG_GP_CNTRL),
3460 IPW2100_REG(REG_GPIO), 3395 IPW2100_REG(REG_GPIO),
3461 IPW2100_REG(REG_INTA), 3396 IPW2100_REG(REG_INTA),
3462 IPW2100_REG(REG_INTA_MASK), 3397 IPW2100_REG(REG_INTA_MASK), IPW2100_REG(REG_RESET_REG),};
3463 IPW2100_REG(REG_RESET_REG),
3464};
3465#define IPW2100_NIC(x, s) { x, #x, s } 3398#define IPW2100_NIC(x, s) { x, #x, s }
3466static const struct { 3399static const struct {
3467 u32 addr; 3400 u32 addr;
3468 const char *name; 3401 const char *name;
3469 size_t size; 3402 size_t size;
3470} nic_data[] = { 3403} nic_data[] = {
3471 IPW2100_NIC(IPW2100_CONTROL_REG, 2), 3404IPW2100_NIC(IPW2100_CONTROL_REG, 2),
3472 IPW2100_NIC(0x210014, 1), 3405 IPW2100_NIC(0x210014, 1), IPW2100_NIC(0x210000, 1),};
3473 IPW2100_NIC(0x210000, 1),
3474};
3475#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d } 3406#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d }
3476static const struct { 3407static const struct {
3477 u8 index; 3408 u8 index;
3478 const char *name; 3409 const char *name;
3479 const char *desc; 3410 const char *desc;
3480} ord_data[] = { 3411} ord_data[] = {
3481 IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"), 3412IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
3482 IPW2100_ORD(STAT_TX_HOST_COMPLETE, "successful Host Tx's (MSDU)"), 3413 IPW2100_ORD(STAT_TX_HOST_COMPLETE,
3483 IPW2100_ORD(STAT_TX_DIR_DATA, "successful Directed Tx's (MSDU)"), 3414 "successful Host Tx's (MSDU)"),
3484 IPW2100_ORD(STAT_TX_DIR_DATA1, "successful Directed Tx's (MSDU) @ 1MB"), 3415 IPW2100_ORD(STAT_TX_DIR_DATA,
3485 IPW2100_ORD(STAT_TX_DIR_DATA2, "successful Directed Tx's (MSDU) @ 2MB"), 3416 "successful Directed Tx's (MSDU)"),
3486 IPW2100_ORD(STAT_TX_DIR_DATA5_5, "successful Directed Tx's (MSDU) @ 5_5MB"), 3417 IPW2100_ORD(STAT_TX_DIR_DATA1,
3487 IPW2100_ORD(STAT_TX_DIR_DATA11, "successful Directed Tx's (MSDU) @ 11MB"), 3418 "successful Directed Tx's (MSDU) @ 1MB"),
3488 IPW2100_ORD(STAT_TX_NODIR_DATA1, "successful Non_Directed Tx's (MSDU) @ 1MB"), 3419 IPW2100_ORD(STAT_TX_DIR_DATA2,
3489 IPW2100_ORD(STAT_TX_NODIR_DATA2, "successful Non_Directed Tx's (MSDU) @ 2MB"), 3420 "successful Directed Tx's (MSDU) @ 2MB"),
3490 IPW2100_ORD(STAT_TX_NODIR_DATA5_5, "successful Non_Directed Tx's (MSDU) @ 5.5MB"), 3421 IPW2100_ORD(STAT_TX_DIR_DATA5_5,
3491 IPW2100_ORD(STAT_TX_NODIR_DATA11, "successful Non_Directed Tx's (MSDU) @ 11MB"), 3422 "successful Directed Tx's (MSDU) @ 5_5MB"),
3492 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"), 3423 IPW2100_ORD(STAT_TX_DIR_DATA11,
3493 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"), 3424 "successful Directed Tx's (MSDU) @ 11MB"),
3494 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"), 3425 IPW2100_ORD(STAT_TX_NODIR_DATA1,
3495 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"), 3426 "successful Non_Directed Tx's (MSDU) @ 1MB"),
3496 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"), 3427 IPW2100_ORD(STAT_TX_NODIR_DATA2,
3497 IPW2100_ORD(STAT_TX_ASSN_RESP, "successful Association response Tx's"), 3428 "successful Non_Directed Tx's (MSDU) @ 2MB"),
3498 IPW2100_ORD(STAT_TX_REASSN, "successful Reassociation Tx's"), 3429 IPW2100_ORD(STAT_TX_NODIR_DATA5_5,
3499 IPW2100_ORD(STAT_TX_REASSN_RESP, "successful Reassociation response Tx's"), 3430 "successful Non_Directed Tx's (MSDU) @ 5.5MB"),
3500 IPW2100_ORD(STAT_TX_PROBE, "probes successfully transmitted"), 3431 IPW2100_ORD(STAT_TX_NODIR_DATA11,
3501 IPW2100_ORD(STAT_TX_PROBE_RESP, "probe responses successfully transmitted"), 3432 "successful Non_Directed Tx's (MSDU) @ 11MB"),
3502 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"), 3433 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"),
3503 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"), 3434 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"),
3504 IPW2100_ORD(STAT_TX_DISASSN, "successful Disassociation TX"), 3435 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"),
3505 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"), 3436 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"),
3506 IPW2100_ORD(STAT_TX_DEAUTH, "successful Deauthentication TX"), 3437 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"),
3507 IPW2100_ORD(STAT_TX_TOTAL_BYTES, "Total successful Tx data bytes"), 3438 IPW2100_ORD(STAT_TX_ASSN_RESP,
3508 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"), 3439 "successful Association response Tx's"),
3509 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"), 3440 IPW2100_ORD(STAT_TX_REASSN,
3510 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"), 3441 "successful Reassociation Tx's"),
3511 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"), 3442 IPW2100_ORD(STAT_TX_REASSN_RESP,
3512 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"), 3443 "successful Reassociation response Tx's"),
3513 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"), 3444 IPW2100_ORD(STAT_TX_PROBE,
3514 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,"times max tries in a hop failed"), 3445 "probes successfully transmitted"),
3515 IPW2100_ORD(STAT_TX_DISASSN_FAIL, "times disassociation failed"), 3446 IPW2100_ORD(STAT_TX_PROBE_RESP,
3516 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"), 3447 "probe responses successfully transmitted"),
3517 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"), 3448 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"),
3518 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"), 3449 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"),
3519 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"), 3450 IPW2100_ORD(STAT_TX_DISASSN,
3520 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"), 3451 "successful Disassociation TX"),
3521 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"), 3452 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"),
3522 IPW2100_ORD(STAT_RX_DIR_DATA5_5, "directed packets at 5.5MB"), 3453 IPW2100_ORD(STAT_TX_DEAUTH,
3523 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"), 3454 "successful Deauthentication TX"),
3524 IPW2100_ORD(STAT_RX_NODIR_DATA,"nondirected packets"), 3455 IPW2100_ORD(STAT_TX_TOTAL_BYTES,
3525 IPW2100_ORD(STAT_RX_NODIR_DATA1, "nondirected packets at 1MB"), 3456 "Total successful Tx data bytes"),
3526 IPW2100_ORD(STAT_RX_NODIR_DATA2, "nondirected packets at 2MB"), 3457 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"),
3527 IPW2100_ORD(STAT_RX_NODIR_DATA5_5, "nondirected packets at 5.5MB"), 3458 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"),
3528 IPW2100_ORD(STAT_RX_NODIR_DATA11, "nondirected packets at 11MB"), 3459 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"),
3529 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"), 3460 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"),
3530 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"), 3461 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"),
3531 IPW2100_ORD(STAT_RX_CTS, "Rx CTS"), 3462 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"),
3532 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"), 3463 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,
3533 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"), 3464 "times max tries in a hop failed"),
3534 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"), 3465 IPW2100_ORD(STAT_TX_DISASSN_FAIL,
3535 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"), 3466 "times disassociation failed"),
3536 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"), 3467 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"),
3537 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"), 3468 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"),
3538 IPW2100_ORD(STAT_RX_REASSN_RESP, "Reassociation response Rx's"), 3469 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"),
3539 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"), 3470 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"),
3540 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"), 3471 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"),
3541 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"), 3472 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"),
3542 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"), 3473 IPW2100_ORD(STAT_RX_DIR_DATA5_5,
3543 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"), 3474 "directed packets at 5.5MB"),
3544 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"), 3475 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"),
3545 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"), 3476 IPW2100_ORD(STAT_RX_NODIR_DATA, "nondirected packets"),
3546 IPW2100_ORD(STAT_RX_TOTAL_BYTES,"Total rx data bytes received"), 3477 IPW2100_ORD(STAT_RX_NODIR_DATA1,
3547 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"), 3478 "nondirected packets at 1MB"),
3548 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"), 3479 IPW2100_ORD(STAT_RX_NODIR_DATA2,
3549 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"), 3480 "nondirected packets at 2MB"),
3550 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"), 3481 IPW2100_ORD(STAT_RX_NODIR_DATA5_5,
3551 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"), 3482 "nondirected packets at 5.5MB"),
3552 IPW2100_ORD(STAT_RX_DUPLICATE1, "duplicate rx packets at 1MB"), 3483 IPW2100_ORD(STAT_RX_NODIR_DATA11,
3553 IPW2100_ORD(STAT_RX_DUPLICATE2, "duplicate rx packets at 2MB"), 3484 "nondirected packets at 11MB"),
3554 IPW2100_ORD(STAT_RX_DUPLICATE5_5, "duplicate rx packets at 5.5MB"), 3485 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"),
3555 IPW2100_ORD(STAT_RX_DUPLICATE11, "duplicate rx packets at 11MB"), 3486 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"), IPW2100_ORD(STAT_RX_CTS,
3556 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"), 3487 "Rx CTS"),
3557 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"), 3488 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"),
3558 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"), 3489 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"),
3559 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"), 3490 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"),
3560 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL, "rx frames with invalid protocol"), 3491 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"),
3561 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"), 3492 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"),
3562 IPW2100_ORD(STAT_RX_NO_BUFFER, "rx frames rejected due to no buffer"), 3493 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"),
3563 IPW2100_ORD(STAT_RX_MISSING_FRAG, "rx frames dropped due to missing fragment"), 3494 IPW2100_ORD(STAT_RX_REASSN_RESP,
3564 IPW2100_ORD(STAT_RX_ORPHAN_FRAG, "rx frames dropped due to non-sequential fragment"), 3495 "Reassociation response Rx's"),
3565 IPW2100_ORD(STAT_RX_ORPHAN_FRAME, "rx frames dropped due to unmatched 1st frame"), 3496 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"),
3566 IPW2100_ORD(STAT_RX_FRAG_AGEOUT, "rx frames dropped due to uncompleted frame"), 3497 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"),
3567 IPW2100_ORD(STAT_RX_ICV_ERRORS, "ICV errors during decryption"), 3498 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"),
3568 IPW2100_ORD(STAT_PSP_SUSPENSION,"times adapter suspended"), 3499 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"),
3569 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"), 3500 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"),
3570 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT, "poll response timeouts"), 3501 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"),
3571 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT, "timeouts waiting for last {broad,multi}cast pkt"), 3502 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"),
3572 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"), 3503 IPW2100_ORD(STAT_RX_TOTAL_BYTES,
3573 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"), 3504 "Total rx data bytes received"),
3574 IPW2100_ORD(STAT_PSP_STATION_ID,"PSP Station ID"), 3505 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"),
3575 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"), 3506 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"),
3576 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,"current calculation of % missed beacons"), 3507 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"),
3577 IPW2100_ORD(STAT_PERCENT_RETRIES,"current calculation of % missed tx retries"), 3508 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"),
3578 IPW2100_ORD(ASSOCIATED_AP_PTR, "0 if not associated, else pointer to AP table entry"), 3509 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"),
3579 IPW2100_ORD(AVAILABLE_AP_CNT, "AP's decsribed in the AP table"), 3510 IPW2100_ORD(STAT_RX_DUPLICATE1,
3580 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"), 3511 "duplicate rx packets at 1MB"),
3581 IPW2100_ORD(STAT_AP_ASSNS, "associations"), 3512 IPW2100_ORD(STAT_RX_DUPLICATE2,
3582 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"), 3513 "duplicate rx packets at 2MB"),
3583 IPW2100_ORD(STAT_ASSN_RESP_FAIL,"failures due to response fail"), 3514 IPW2100_ORD(STAT_RX_DUPLICATE5_5,
3584 IPW2100_ORD(STAT_FULL_SCANS, "full scans"), 3515 "duplicate rx packets at 5.5MB"),
3585 IPW2100_ORD(CARD_DISABLED, "Card Disabled"), 3516 IPW2100_ORD(STAT_RX_DUPLICATE11,
3586 IPW2100_ORD(STAT_ROAM_INHIBIT, "times roaming was inhibited due to activity"), 3517 "duplicate rx packets at 11MB"),
3587 IPW2100_ORD(RSSI_AT_ASSN, "RSSI of associated AP at time of association"), 3518 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"),
3588 IPW2100_ORD(STAT_ASSN_CAUSE1, "reassociation: no probe response or TX on hop"), 3519 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"),
3589 IPW2100_ORD(STAT_ASSN_CAUSE2, "reassociation: poor tx/rx quality"), 3520 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"),
3590 IPW2100_ORD(STAT_ASSN_CAUSE3, "reassociation: tx/rx quality (excessive AP load"), 3521 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"),
3591 IPW2100_ORD(STAT_ASSN_CAUSE4, "reassociation: AP RSSI level"), 3522 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL,
3592 IPW2100_ORD(STAT_ASSN_CAUSE5, "reassociations due to load leveling"), 3523 "rx frames with invalid protocol"),
3593 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"), 3524 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"),
3594 IPW2100_ORD(STAT_AUTH_RESP_FAIL,"times authentication response failed"), 3525 IPW2100_ORD(STAT_RX_NO_BUFFER,
3595 IPW2100_ORD(STATION_TABLE_CNT, "entries in association table"), 3526 "rx frames rejected due to no buffer"),
3596 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"), 3527 IPW2100_ORD(STAT_RX_MISSING_FRAG,
3597 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"), 3528 "rx frames dropped due to missing fragment"),
3598 IPW2100_ORD(COUNTRY_CODE, "IEEE country code as recv'd from beacon"), 3529 IPW2100_ORD(STAT_RX_ORPHAN_FRAG,
3599 IPW2100_ORD(COUNTRY_CHANNELS, "channels suported by country"), 3530 "rx frames dropped due to non-sequential fragment"),
3600 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"), 3531 IPW2100_ORD(STAT_RX_ORPHAN_FRAME,
3601 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"), 3532 "rx frames dropped due to unmatched 1st frame"),
3602 IPW2100_ORD(ANTENNA_DIVERSITY, "TRUE if antenna diversity is disabled"), 3533 IPW2100_ORD(STAT_RX_FRAG_AGEOUT,
3603 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"), 3534 "rx frames dropped due to uncompleted frame"),
3604 IPW2100_ORD(OUR_FREQ, "current radio freq lower digits - channel ID"), 3535 IPW2100_ORD(STAT_RX_ICV_ERRORS,
3605 IPW2100_ORD(RTC_TIME, "current RTC time"), 3536 "ICV errors during decryption"),
3606 IPW2100_ORD(PORT_TYPE, "operating mode"), 3537 IPW2100_ORD(STAT_PSP_SUSPENSION, "times adapter suspended"),
3607 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"), 3538 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"),
3608 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"), 3539 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT,
3609 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"), 3540 "poll response timeouts"),
3610 IPW2100_ORD(BASIC_RATES, "basic tx rates"), 3541 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT,
3611 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"), 3542 "timeouts waiting for last {broad,multi}cast pkt"),
3612 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"), 3543 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"),
3613 IPW2100_ORD(CAPABILITIES, "Management frame capability field"), 3544 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"),
3614 IPW2100_ORD(AUTH_TYPE, "Type of authentication"), 3545 IPW2100_ORD(STAT_PSP_STATION_ID, "PSP Station ID"),
3615 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"), 3546 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"),
3616 IPW2100_ORD(RTS_THRESHOLD, "Min packet length for RTS handshaking"), 3547 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,
3617 IPW2100_ORD(INT_MODE, "International mode"), 3548 "current calculation of % missed beacons"),
3618 IPW2100_ORD(FRAGMENTATION_THRESHOLD, "protocol frag threshold"), 3549 IPW2100_ORD(STAT_PERCENT_RETRIES,
3619 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS, "EEPROM offset in SRAM"), 3550 "current calculation of % missed tx retries"),
3620 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE, "EEPROM size in SRAM"), 3551 IPW2100_ORD(ASSOCIATED_AP_PTR,
3621 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"), 3552 "0 if not associated, else pointer to AP table entry"),
3622 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS, "EEPROM IBSS 11b channel set"), 3553 IPW2100_ORD(AVAILABLE_AP_CNT,
3623 IPW2100_ORD(MAC_VERSION, "MAC Version"), 3554 "AP's decsribed in the AP table"),
3624 IPW2100_ORD(MAC_REVISION, "MAC Revision"), 3555 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"),
3625 IPW2100_ORD(RADIO_VERSION, "Radio Version"), 3556 IPW2100_ORD(STAT_AP_ASSNS, "associations"),
3626 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"), 3557 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"),
3627 IPW2100_ORD(UCODE_VERSION, "Ucode Version"), 3558 IPW2100_ORD(STAT_ASSN_RESP_FAIL,
3628}; 3559 "failures due to response fail"),
3629 3560 IPW2100_ORD(STAT_FULL_SCANS, "full scans"),
3561 IPW2100_ORD(CARD_DISABLED, "Card Disabled"),
3562 IPW2100_ORD(STAT_ROAM_INHIBIT,
3563 "times roaming was inhibited due to activity"),
3564 IPW2100_ORD(RSSI_AT_ASSN,
3565 "RSSI of associated AP at time of association"),
3566 IPW2100_ORD(STAT_ASSN_CAUSE1,
3567 "reassociation: no probe response or TX on hop"),
3568 IPW2100_ORD(STAT_ASSN_CAUSE2,
3569 "reassociation: poor tx/rx quality"),
3570 IPW2100_ORD(STAT_ASSN_CAUSE3,
3571 "reassociation: tx/rx quality (excessive AP load"),
3572 IPW2100_ORD(STAT_ASSN_CAUSE4,
3573 "reassociation: AP RSSI level"),
3574 IPW2100_ORD(STAT_ASSN_CAUSE5,
3575 "reassociations due to load leveling"),
3576 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"),
3577 IPW2100_ORD(STAT_AUTH_RESP_FAIL,
3578 "times authentication response failed"),
3579 IPW2100_ORD(STATION_TABLE_CNT,
3580 "entries in association table"),
3581 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"),
3582 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"),
3583 IPW2100_ORD(COUNTRY_CODE,
3584 "IEEE country code as recv'd from beacon"),
3585 IPW2100_ORD(COUNTRY_CHANNELS,
3586 "channels suported by country"),
3587 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
3588 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
3589 IPW2100_ORD(ANTENNA_DIVERSITY,
3590 "TRUE if antenna diversity is disabled"),
3591 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"),
3592 IPW2100_ORD(OUR_FREQ,
3593 "current radio freq lower digits - channel ID"),
3594 IPW2100_ORD(RTC_TIME, "current RTC time"),
3595 IPW2100_ORD(PORT_TYPE, "operating mode"),
3596 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"),
3597 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"),
3598 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"),
3599 IPW2100_ORD(BASIC_RATES, "basic tx rates"),
3600 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"),
3601 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"),
3602 IPW2100_ORD(CAPABILITIES,
3603 "Management frame capability field"),
3604 IPW2100_ORD(AUTH_TYPE, "Type of authentication"),
3605 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"),
3606 IPW2100_ORD(RTS_THRESHOLD,
3607 "Min packet length for RTS handshaking"),
3608 IPW2100_ORD(INT_MODE, "International mode"),
3609 IPW2100_ORD(FRAGMENTATION_THRESHOLD,
3610 "protocol frag threshold"),
3611 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS,
3612 "EEPROM offset in SRAM"),
3613 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE,
3614 "EEPROM size in SRAM"),
3615 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"),
3616 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS,
3617 "EEPROM IBSS 11b channel set"),
3618 IPW2100_ORD(MAC_VERSION, "MAC Version"),
3619 IPW2100_ORD(MAC_REVISION, "MAC Revision"),
3620 IPW2100_ORD(RADIO_VERSION, "Radio Version"),
3621 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"),
3622 IPW2100_ORD(UCODE_VERSION, "Ucode Version"),};
3630 3623
3631static ssize_t show_registers(struct device *d, struct device_attribute *attr, 3624static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3632 char *buf) 3625 char *buf)
3633{ 3626{
3634 int i; 3627 int i;
3635 struct ipw2100_priv *priv = dev_get_drvdata(d); 3628 struct ipw2100_priv *priv = dev_get_drvdata(d);
3636 struct net_device *dev = priv->net_dev; 3629 struct net_device *dev = priv->net_dev;
3637 char * out = buf; 3630 char *out = buf;
3638 u32 val = 0; 3631 u32 val = 0;
3639 3632
3640 out += sprintf(out, "%30s [Address ] : Hex\n", "Register"); 3633 out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
@@ -3647,15 +3640,15 @@ static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3647 3640
3648 return out - buf; 3641 return out - buf;
3649} 3642}
3650static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3651 3643
3644static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3652 3645
3653static ssize_t show_hardware(struct device *d, struct device_attribute *attr, 3646static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3654 char *buf) 3647 char *buf)
3655{ 3648{
3656 struct ipw2100_priv *priv = dev_get_drvdata(d); 3649 struct ipw2100_priv *priv = dev_get_drvdata(d);
3657 struct net_device *dev = priv->net_dev; 3650 struct net_device *dev = priv->net_dev;
3658 char * out = buf; 3651 char *out = buf;
3659 int i; 3652 int i;
3660 3653
3661 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry"); 3654 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
@@ -3688,11 +3681,11 @@ static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3688 } 3681 }
3689 return out - buf; 3682 return out - buf;
3690} 3683}
3691static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3692 3684
3685static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3693 3686
3694static ssize_t show_memory(struct device *d, struct device_attribute *attr, 3687static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3695 char *buf) 3688 char *buf)
3696{ 3689{
3697 struct ipw2100_priv *priv = dev_get_drvdata(d); 3690 struct ipw2100_priv *priv = dev_get_drvdata(d);
3698 struct net_device *dev = priv->net_dev; 3691 struct net_device *dev = priv->net_dev;
@@ -3708,10 +3701,13 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3708 /* sysfs provides us PAGE_SIZE buffer */ 3701 /* sysfs provides us PAGE_SIZE buffer */
3709 while (len < PAGE_SIZE - 128 && loop < 0x30000) { 3702 while (len < PAGE_SIZE - 128 && loop < 0x30000) {
3710 3703
3711 if (priv->snapshot[0]) for (i = 0; i < 4; i++) 3704 if (priv->snapshot[0])
3712 buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4); 3705 for (i = 0; i < 4; i++)
3713 else for (i = 0; i < 4; i++) 3706 buffer[i] =
3714 read_nic_dword(dev, loop + i * 4, &buffer[i]); 3707 *(u32 *) SNAPSHOT_ADDR(loop + i * 4);
3708 else
3709 for (i = 0; i < 4; i++)
3710 read_nic_dword(dev, loop + i * 4, &buffer[i]);
3715 3711
3716 if (priv->dump_raw) 3712 if (priv->dump_raw)
3717 len += sprintf(buf + len, 3713 len += sprintf(buf + len,
@@ -3719,26 +3715,26 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3719 "%c%c%c%c" 3715 "%c%c%c%c"
3720 "%c%c%c%c" 3716 "%c%c%c%c"
3721 "%c%c%c%c", 3717 "%c%c%c%c",
3722 ((u8*)buffer)[0x0], 3718 ((u8 *) buffer)[0x0],
3723 ((u8*)buffer)[0x1], 3719 ((u8 *) buffer)[0x1],
3724 ((u8*)buffer)[0x2], 3720 ((u8 *) buffer)[0x2],
3725 ((u8*)buffer)[0x3], 3721 ((u8 *) buffer)[0x3],
3726 ((u8*)buffer)[0x4], 3722 ((u8 *) buffer)[0x4],
3727 ((u8*)buffer)[0x5], 3723 ((u8 *) buffer)[0x5],
3728 ((u8*)buffer)[0x6], 3724 ((u8 *) buffer)[0x6],
3729 ((u8*)buffer)[0x7], 3725 ((u8 *) buffer)[0x7],
3730 ((u8*)buffer)[0x8], 3726 ((u8 *) buffer)[0x8],
3731 ((u8*)buffer)[0x9], 3727 ((u8 *) buffer)[0x9],
3732 ((u8*)buffer)[0xa], 3728 ((u8 *) buffer)[0xa],
3733 ((u8*)buffer)[0xb], 3729 ((u8 *) buffer)[0xb],
3734 ((u8*)buffer)[0xc], 3730 ((u8 *) buffer)[0xc],
3735 ((u8*)buffer)[0xd], 3731 ((u8 *) buffer)[0xd],
3736 ((u8*)buffer)[0xe], 3732 ((u8 *) buffer)[0xe],
3737 ((u8*)buffer)[0xf]); 3733 ((u8 *) buffer)[0xf]);
3738 else 3734 else
3739 len += sprintf(buf + len, "%s\n", 3735 len += sprintf(buf + len, "%s\n",
3740 snprint_line(line, sizeof(line), 3736 snprint_line(line, sizeof(line),
3741 (u8*)buffer, 16, loop)); 3737 (u8 *) buffer, 16, loop));
3742 loop += 16; 3738 loop += 16;
3743 } 3739 }
3744 3740
@@ -3746,44 +3742,44 @@ static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3746} 3742}
3747 3743
3748static ssize_t store_memory(struct device *d, struct device_attribute *attr, 3744static ssize_t store_memory(struct device *d, struct device_attribute *attr,
3749 const char *buf, size_t count) 3745 const char *buf, size_t count)
3750{ 3746{
3751 struct ipw2100_priv *priv = dev_get_drvdata(d); 3747 struct ipw2100_priv *priv = dev_get_drvdata(d);
3752 struct net_device *dev = priv->net_dev; 3748 struct net_device *dev = priv->net_dev;
3753 const char *p = buf; 3749 const char *p = buf;
3754 3750
3751 (void) dev; /* kill unused-var warning for debug-only code */
3752
3755 if (count < 1) 3753 if (count < 1)
3756 return count; 3754 return count;
3757 3755
3758 if (p[0] == '1' || 3756 if (p[0] == '1' ||
3759 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) { 3757 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
3760 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n", 3758 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
3761 dev->name); 3759 dev->name);
3762 priv->dump_raw = 1; 3760 priv->dump_raw = 1;
3763 3761
3764 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' && 3762 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
3765 tolower(p[1]) == 'f')) { 3763 tolower(p[1]) == 'f')) {
3766 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n", 3764 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
3767 dev->name); 3765 dev->name);
3768 priv->dump_raw = 0; 3766 priv->dump_raw = 0;
3769 3767
3770 } else if (tolower(p[0]) == 'r') { 3768 } else if (tolower(p[0]) == 'r') {
3771 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n", 3769 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n", dev->name);
3772 dev->name);
3773 ipw2100_snapshot_free(priv); 3770 ipw2100_snapshot_free(priv);
3774 3771
3775 } else 3772 } else
3776 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, " 3773 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
3777 "reset = clear memory snapshot\n", 3774 "reset = clear memory snapshot\n", dev->name);
3778 dev->name);
3779 3775
3780 return count; 3776 return count;
3781} 3777}
3782static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
3783 3778
3779static DEVICE_ATTR(memory, S_IWUSR | S_IRUGO, show_memory, store_memory);
3784 3780
3785static ssize_t show_ordinals(struct device *d, struct device_attribute *attr, 3781static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3786 char *buf) 3782 char *buf)
3787{ 3783{
3788 struct ipw2100_priv *priv = dev_get_drvdata(d); 3784 struct ipw2100_priv *priv = dev_get_drvdata(d);
3789 u32 val = 0; 3785 u32 val = 0;
@@ -3791,6 +3787,9 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3791 u32 val_len; 3787 u32 val_len;
3792 static int loop = 0; 3788 static int loop = 0;
3793 3789
3790 if (priv->status & STATUS_RF_KILL_MASK)
3791 return 0;
3792
3794 if (loop >= sizeof(ord_data) / sizeof(*ord_data)) 3793 if (loop >= sizeof(ord_data) / sizeof(*ord_data))
3795 loop = 0; 3794 loop = 0;
3796 3795
@@ -3814,14 +3813,14 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3814 3813
3815 return len; 3814 return len;
3816} 3815}
3817static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3818 3816
3817static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3819 3818
3820static ssize_t show_stats(struct device *d, struct device_attribute *attr, 3819static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3821 char *buf) 3820 char *buf)
3822{ 3821{
3823 struct ipw2100_priv *priv = dev_get_drvdata(d); 3822 struct ipw2100_priv *priv = dev_get_drvdata(d);
3824 char * out = buf; 3823 char *out = buf;
3825 3824
3826 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n", 3825 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
3827 priv->interrupts, priv->tx_interrupts, 3826 priv->interrupts, priv->tx_interrupts,
@@ -3835,8 +3834,8 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3835 3834
3836 return out - buf; 3835 return out - buf;
3837} 3836}
3838static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3839 3837
3838static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3840 3839
3841static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) 3840static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3842{ 3841{
@@ -3864,19 +3863,18 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3864 priv->last_mode = priv->ieee->iw_mode; 3863 priv->last_mode = priv->ieee->iw_mode;
3865 priv->net_dev->type = ARPHRD_IEEE80211; 3864 priv->net_dev->type = ARPHRD_IEEE80211;
3866 break; 3865 break;
3867#endif /* CONFIG_IPW2100_MONITOR */ 3866#endif /* CONFIG_IPW2100_MONITOR */
3868 } 3867 }
3869 3868
3870 priv->ieee->iw_mode = mode; 3869 priv->ieee->iw_mode = mode;
3871 3870
3872#ifdef CONFIG_PM 3871#ifdef CONFIG_PM
3873 /* Indicate ipw2100_download_firmware download firmware 3872 /* Indicate ipw2100_download_firmware download firmware
3874 * from disk instead of memory. */ 3873 * from disk instead of memory. */
3875 ipw2100_firmware.version = 0; 3874 ipw2100_firmware.version = 0;
3876#endif 3875#endif
3877 3876
3878 printk(KERN_INFO "%s: Reseting on mode change.\n", 3877 printk(KERN_INFO "%s: Reseting on mode change.\n", priv->net_dev->name);
3879 priv->net_dev->name);
3880 priv->reset_backoff = 0; 3878 priv->reset_backoff = 0;
3881 schedule_reset(priv); 3879 schedule_reset(priv);
3882 3880
@@ -3884,12 +3882,12 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
3884} 3882}
3885 3883
3886static ssize_t show_internals(struct device *d, struct device_attribute *attr, 3884static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3887 char *buf) 3885 char *buf)
3888{ 3886{
3889 struct ipw2100_priv *priv = dev_get_drvdata(d); 3887 struct ipw2100_priv *priv = dev_get_drvdata(d);
3890 int len = 0; 3888 int len = 0;
3891 3889
3892#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x) 3890#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" y "\n", priv-> x)
3893 3891
3894 if (priv->status & STATUS_ASSOCIATED) 3892 if (priv->status & STATUS_ASSOCIATED)
3895 len += sprintf(buf + len, "connected: %lu\n", 3893 len += sprintf(buf + len, "connected: %lu\n",
@@ -3897,55 +3895,60 @@ static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3897 else 3895 else
3898 len += sprintf(buf + len, "not connected\n"); 3896 len += sprintf(buf + len, "not connected\n");
3899 3897
3900 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], p); 3898 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], "p");
3901 DUMP_VAR(status, 08lx); 3899 DUMP_VAR(status, "08lx");
3902 DUMP_VAR(config, 08lx); 3900 DUMP_VAR(config, "08lx");
3903 DUMP_VAR(capability, 08lx); 3901 DUMP_VAR(capability, "08lx");
3904 3902
3905 len += sprintf(buf + len, "last_rtc: %lu\n", (unsigned long)priv->last_rtc); 3903 len +=
3904 sprintf(buf + len, "last_rtc: %lu\n",
3905 (unsigned long)priv->last_rtc);
3906 3906
3907 DUMP_VAR(fatal_error, d); 3907 DUMP_VAR(fatal_error, "d");
3908 DUMP_VAR(stop_hang_check, d); 3908 DUMP_VAR(stop_hang_check, "d");
3909 DUMP_VAR(stop_rf_kill, d); 3909 DUMP_VAR(stop_rf_kill, "d");
3910 DUMP_VAR(messages_sent, d); 3910 DUMP_VAR(messages_sent, "d");
3911 3911
3912 DUMP_VAR(tx_pend_stat.value, d); 3912 DUMP_VAR(tx_pend_stat.value, "d");
3913 DUMP_VAR(tx_pend_stat.hi, d); 3913 DUMP_VAR(tx_pend_stat.hi, "d");
3914 3914
3915 DUMP_VAR(tx_free_stat.value, d); 3915 DUMP_VAR(tx_free_stat.value, "d");
3916 DUMP_VAR(tx_free_stat.lo, d); 3916 DUMP_VAR(tx_free_stat.lo, "d");
3917 3917
3918 DUMP_VAR(msg_free_stat.value, d); 3918 DUMP_VAR(msg_free_stat.value, "d");
3919 DUMP_VAR(msg_free_stat.lo, d); 3919 DUMP_VAR(msg_free_stat.lo, "d");
3920 3920
3921 DUMP_VAR(msg_pend_stat.value, d); 3921 DUMP_VAR(msg_pend_stat.value, "d");
3922 DUMP_VAR(msg_pend_stat.hi, d); 3922 DUMP_VAR(msg_pend_stat.hi, "d");
3923 3923
3924 DUMP_VAR(fw_pend_stat.value, d); 3924 DUMP_VAR(fw_pend_stat.value, "d");
3925 DUMP_VAR(fw_pend_stat.hi, d); 3925 DUMP_VAR(fw_pend_stat.hi, "d");
3926 3926
3927 DUMP_VAR(txq_stat.value, d); 3927 DUMP_VAR(txq_stat.value, "d");
3928 DUMP_VAR(txq_stat.lo, d); 3928 DUMP_VAR(txq_stat.lo, "d");
3929 3929
3930 DUMP_VAR(ieee->scans, d); 3930 DUMP_VAR(ieee->scans, "d");
3931 DUMP_VAR(reset_backoff, d); 3931 DUMP_VAR(reset_backoff, "d");
3932 3932
3933 return len; 3933 return len;
3934} 3934}
3935static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3936 3935
3936static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3937 3937
3938static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, 3938static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3939 char *buf) 3939 char *buf)
3940{ 3940{
3941 struct ipw2100_priv *priv = dev_get_drvdata(d); 3941 struct ipw2100_priv *priv = dev_get_drvdata(d);
3942 char essid[IW_ESSID_MAX_SIZE + 1]; 3942 char essid[IW_ESSID_MAX_SIZE + 1];
3943 u8 bssid[ETH_ALEN]; 3943 u8 bssid[ETH_ALEN];
3944 u32 chan = 0; 3944 u32 chan = 0;
3945 char * out = buf; 3945 char *out = buf;
3946 int length; 3946 int length;
3947 int ret; 3947 int ret;
3948 3948
3949 if (priv->status & STATUS_RF_KILL_MASK)
3950 return 0;
3951
3949 memset(essid, 0, sizeof(essid)); 3952 memset(essid, 0, sizeof(essid));
3950 memset(bssid, 0, sizeof(bssid)); 3953 memset(bssid, 0, sizeof(bssid));
3951 3954
@@ -3976,8 +3979,8 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3976 3979
3977 return out - buf; 3980 return out - buf;
3978} 3981}
3979static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3980 3982
3983static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3981 3984
3982#ifdef CONFIG_IPW_DEBUG 3985#ifdef CONFIG_IPW_DEBUG
3983static ssize_t show_debug_level(struct device_driver *d, char *buf) 3986static ssize_t show_debug_level(struct device_driver *d, char *buf)
@@ -3985,8 +3988,8 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
3985 return sprintf(buf, "0x%08X\n", ipw2100_debug_level); 3988 return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
3986} 3989}
3987 3990
3988static ssize_t store_debug_level(struct device_driver *d, const char *buf, 3991static ssize_t store_debug_level(struct device_driver *d,
3989 size_t count) 3992 const char *buf, size_t count)
3990{ 3993{
3991 char *p = (char *)buf; 3994 char *p = (char *)buf;
3992 u32 val; 3995 u32 val;
@@ -3999,28 +4002,26 @@ static ssize_t store_debug_level(struct device_driver *d, const char *buf,
3999 } else 4002 } else
4000 val = simple_strtoul(p, &p, 10); 4003 val = simple_strtoul(p, &p, 10);
4001 if (p == buf) 4004 if (p == buf)
4002 IPW_DEBUG_INFO(DRV_NAME 4005 IPW_DEBUG_INFO(": %s is not in hex or decimal form.\n", buf);
4003 ": %s is not in hex or decimal form.\n", buf);
4004 else 4006 else
4005 ipw2100_debug_level = val; 4007 ipw2100_debug_level = val;
4006 4008
4007 return strnlen(buf, count); 4009 return strnlen(buf, count);
4008} 4010}
4011
4009static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level, 4012static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
4010 store_debug_level); 4013 store_debug_level);
4011#endif /* CONFIG_IPW_DEBUG */ 4014#endif /* CONFIG_IPW_DEBUG */
4012
4013 4015
4014static ssize_t show_fatal_error(struct device *d, 4016static ssize_t show_fatal_error(struct device *d,
4015 struct device_attribute *attr, char *buf) 4017 struct device_attribute *attr, char *buf)
4016{ 4018{
4017 struct ipw2100_priv *priv = dev_get_drvdata(d); 4019 struct ipw2100_priv *priv = dev_get_drvdata(d);
4018 char *out = buf; 4020 char *out = buf;
4019 int i; 4021 int i;
4020 4022
4021 if (priv->fatal_error) 4023 if (priv->fatal_error)
4022 out += sprintf(out, "0x%08X\n", 4024 out += sprintf(out, "0x%08X\n", priv->fatal_error);
4023 priv->fatal_error);
4024 else 4025 else
4025 out += sprintf(out, "0\n"); 4026 out += sprintf(out, "0\n");
4026 4027
@@ -4038,24 +4039,26 @@ static ssize_t show_fatal_error(struct device *d,
4038} 4039}
4039 4040
4040static ssize_t store_fatal_error(struct device *d, 4041static ssize_t store_fatal_error(struct device *d,
4041 struct device_attribute *attr, const char *buf, size_t count) 4042 struct device_attribute *attr, const char *buf,
4043 size_t count)
4042{ 4044{
4043 struct ipw2100_priv *priv = dev_get_drvdata(d); 4045 struct ipw2100_priv *priv = dev_get_drvdata(d);
4044 schedule_reset(priv); 4046 schedule_reset(priv);
4045 return count; 4047 return count;
4046} 4048}
4047static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
4048 4049
4050static DEVICE_ATTR(fatal_error, S_IWUSR | S_IRUGO, show_fatal_error,
4051 store_fatal_error);
4049 4052
4050static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, 4053static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
4051 char *buf) 4054 char *buf)
4052{ 4055{
4053 struct ipw2100_priv *priv = dev_get_drvdata(d); 4056 struct ipw2100_priv *priv = dev_get_drvdata(d);
4054 return sprintf(buf, "%d\n", priv->ieee->scan_age); 4057 return sprintf(buf, "%d\n", priv->ieee->scan_age);
4055} 4058}
4056 4059
4057static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, 4060static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4058 const char *buf, size_t count) 4061 const char *buf, size_t count)
4059{ 4062{
4060 struct ipw2100_priv *priv = dev_get_drvdata(d); 4063 struct ipw2100_priv *priv = dev_get_drvdata(d);
4061 struct net_device *dev = priv->net_dev; 4064 struct net_device *dev = priv->net_dev;
@@ -4065,6 +4068,8 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4065 unsigned long val; 4068 unsigned long val;
4066 char *p = buffer; 4069 char *p = buffer;
4067 4070
4071 (void) dev; /* kill unused-var warning for debug-only code */
4072
4068 IPW_DEBUG_INFO("enter\n"); 4073 IPW_DEBUG_INFO("enter\n");
4069 4074
4070 strncpy(buffer, buf, len); 4075 strncpy(buffer, buf, len);
@@ -4078,8 +4083,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4078 } else 4083 } else
4079 val = simple_strtoul(p, &p, 10); 4084 val = simple_strtoul(p, &p, 10);
4080 if (p == buffer) { 4085 if (p == buffer) {
4081 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", 4086 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
4082 dev->name);
4083 } else { 4087 } else {
4084 priv->ieee->scan_age = val; 4088 priv->ieee->scan_age = val;
4085 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age); 4089 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
@@ -4088,11 +4092,11 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4088 IPW_DEBUG_INFO("exit\n"); 4092 IPW_DEBUG_INFO("exit\n");
4089 return len; 4093 return len;
4090} 4094}
4091static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4092 4095
4096static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4093 4097
4094static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, 4098static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4095 char *buf) 4099 char *buf)
4096{ 4100{
4097 /* 0 - RF kill not enabled 4101 /* 0 - RF kill not enabled
4098 1 - SW based RF kill active (sysfs) 4102 1 - SW based RF kill active (sysfs)
@@ -4100,7 +4104,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4100 3 - Both HW and SW baed RF kill active */ 4104 3 - Both HW and SW baed RF kill active */
4101 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data; 4105 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
4102 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) | 4106 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
4103 (rf_kill_active(priv) ? 0x2 : 0x0); 4107 (rf_kill_active(priv) ? 0x2 : 0x0);
4104 return sprintf(buf, "%i\n", val); 4108 return sprintf(buf, "%i\n", val);
4105} 4109}
4106 4110
@@ -4108,7 +4112,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4108{ 4112{
4109 if ((disable_radio ? 1 : 0) == 4113 if ((disable_radio ? 1 : 0) ==
4110 (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) 4114 (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
4111 return 0 ; 4115 return 0;
4112 4116
4113 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 4117 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
4114 disable_radio ? "OFF" : "ON"); 4118 disable_radio ? "OFF" : "ON");
@@ -4126,8 +4130,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4126 /* Make sure the RF_KILL check timer is running */ 4130 /* Make sure the RF_KILL check timer is running */
4127 priv->stop_rf_kill = 0; 4131 priv->stop_rf_kill = 0;
4128 cancel_delayed_work(&priv->rf_kill); 4132 cancel_delayed_work(&priv->rf_kill);
4129 queue_delayed_work(priv->workqueue, &priv->rf_kill, 4133 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
4130 HZ);
4131 } else 4134 } else
4132 schedule_reset(priv); 4135 schedule_reset(priv);
4133 } 4136 }
@@ -4137,14 +4140,14 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4137} 4140}
4138 4141
4139static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, 4142static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
4140 const char *buf, size_t count) 4143 const char *buf, size_t count)
4141{ 4144{
4142 struct ipw2100_priv *priv = dev_get_drvdata(d); 4145 struct ipw2100_priv *priv = dev_get_drvdata(d);
4143 ipw_radio_kill_sw(priv, buf[0] == '1'); 4146 ipw_radio_kill_sw(priv, buf[0] == '1');
4144 return count; 4147 return count;
4145} 4148}
4146static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
4147 4149
4150static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
4148 4151
4149static struct attribute *ipw2100_sysfs_entries[] = { 4152static struct attribute *ipw2100_sysfs_entries[] = {
4150 &dev_attr_hardware.attr, 4153 &dev_attr_hardware.attr,
@@ -4168,7 +4171,6 @@ static struct attribute_group ipw2100_attribute_group = {
4168 .attrs = ipw2100_sysfs_entries, 4171 .attrs = ipw2100_sysfs_entries,
4169}; 4172};
4170 4173
4171
4172static int status_queue_allocate(struct ipw2100_priv *priv, int entries) 4174static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4173{ 4175{
4174 struct ipw2100_status_queue *q = &priv->status_queue; 4176 struct ipw2100_status_queue *q = &priv->status_queue;
@@ -4176,11 +4178,11 @@ static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4176 IPW_DEBUG_INFO("enter\n"); 4178 IPW_DEBUG_INFO("enter\n");
4177 4179
4178 q->size = entries * sizeof(struct ipw2100_status); 4180 q->size = entries * sizeof(struct ipw2100_status);
4179 q->drv = (struct ipw2100_status *)pci_alloc_consistent( 4181 q->drv =
4180 priv->pci_dev, q->size, &q->nic); 4182 (struct ipw2100_status *)pci_alloc_consistent(priv->pci_dev,
4183 q->size, &q->nic);
4181 if (!q->drv) { 4184 if (!q->drv) {
4182 IPW_DEBUG_WARNING( 4185 IPW_DEBUG_WARNING("Can not allocate status queue.\n");
4183 "Can not allocate status queue.\n");
4184 return -ENOMEM; 4186 return -ENOMEM;
4185 } 4187 }
4186 4188
@@ -4196,9 +4198,9 @@ static void status_queue_free(struct ipw2100_priv *priv)
4196 IPW_DEBUG_INFO("enter\n"); 4198 IPW_DEBUG_INFO("enter\n");
4197 4199
4198 if (priv->status_queue.drv) { 4200 if (priv->status_queue.drv) {
4199 pci_free_consistent( 4201 pci_free_consistent(priv->pci_dev, priv->status_queue.size,
4200 priv->pci_dev, priv->status_queue.size, 4202 priv->status_queue.drv,
4201 priv->status_queue.drv, priv->status_queue.nic); 4203 priv->status_queue.nic);
4202 priv->status_queue.drv = NULL; 4204 priv->status_queue.drv = NULL;
4203 } 4205 }
4204 4206
@@ -4216,7 +4218,8 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
4216 q->size = entries * sizeof(struct ipw2100_bd); 4218 q->size = entries * sizeof(struct ipw2100_bd);
4217 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic); 4219 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic);
4218 if (!q->drv) { 4220 if (!q->drv) {
4219 IPW_DEBUG_INFO("can't allocate shared memory for buffer descriptors\n"); 4221 IPW_DEBUG_INFO
4222 ("can't allocate shared memory for buffer descriptors\n");
4220 return -ENOMEM; 4223 return -ENOMEM;
4221 } 4224 }
4222 memset(q->drv, 0, q->size); 4225 memset(q->drv, 0, q->size);
@@ -4226,8 +4229,7 @@ static int bd_queue_allocate(struct ipw2100_priv *priv,
4226 return 0; 4229 return 0;
4227} 4230}
4228 4231
4229static void bd_queue_free(struct ipw2100_priv *priv, 4232static void bd_queue_free(struct ipw2100_priv *priv, struct ipw2100_bd_queue *q)
4230 struct ipw2100_bd_queue *q)
4231{ 4233{
4232 IPW_DEBUG_INFO("enter\n"); 4234 IPW_DEBUG_INFO("enter\n");
4233 4235
@@ -4235,21 +4237,21 @@ static void bd_queue_free(struct ipw2100_priv *priv,
4235 return; 4237 return;
4236 4238
4237 if (q->drv) { 4239 if (q->drv) {
4238 pci_free_consistent(priv->pci_dev, 4240 pci_free_consistent(priv->pci_dev, q->size, q->drv, q->nic);
4239 q->size, q->drv, q->nic);
4240 q->drv = NULL; 4241 q->drv = NULL;
4241 } 4242 }
4242 4243
4243 IPW_DEBUG_INFO("exit\n"); 4244 IPW_DEBUG_INFO("exit\n");
4244} 4245}
4245 4246
4246static void bd_queue_initialize( 4247static void bd_queue_initialize(struct ipw2100_priv *priv,
4247 struct ipw2100_priv *priv, struct ipw2100_bd_queue * q, 4248 struct ipw2100_bd_queue *q, u32 base, u32 size,
4248 u32 base, u32 size, u32 r, u32 w) 4249 u32 r, u32 w)
4249{ 4250{
4250 IPW_DEBUG_INFO("enter\n"); 4251 IPW_DEBUG_INFO("enter\n");
4251 4252
4252 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, (u32)q->nic); 4253 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv,
4254 (u32) q->nic);
4253 4255
4254 write_register(priv->net_dev, base, q->nic); 4256 write_register(priv->net_dev, base, q->nic);
4255 write_register(priv->net_dev, size, q->entries); 4257 write_register(priv->net_dev, size, q->entries);
@@ -4285,32 +4287,38 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4285 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH); 4287 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
4286 if (err) { 4288 if (err) {
4287 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n", 4289 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
4288 priv->net_dev->name); 4290 priv->net_dev->name);
4289 return err; 4291 return err;
4290 } 4292 }
4291 4293
4292 priv->tx_buffers = (struct ipw2100_tx_packet *)kmalloc( 4294 priv->tx_buffers =
4293 TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet), 4295 (struct ipw2100_tx_packet *)kmalloc(TX_PENDED_QUEUE_LENGTH *
4294 GFP_ATOMIC); 4296 sizeof(struct
4297 ipw2100_tx_packet),
4298 GFP_ATOMIC);
4295 if (!priv->tx_buffers) { 4299 if (!priv->tx_buffers) {
4296 printk(KERN_ERR DRV_NAME ": %s: alloc failed form tx buffers.\n", 4300 printk(KERN_ERR DRV_NAME
4301 ": %s: alloc failed form tx buffers.\n",
4297 priv->net_dev->name); 4302 priv->net_dev->name);
4298 bd_queue_free(priv, &priv->tx_queue); 4303 bd_queue_free(priv, &priv->tx_queue);
4299 return -ENOMEM; 4304 return -ENOMEM;
4300 } 4305 }
4301 4306
4302 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) { 4307 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4303 v = pci_alloc_consistent( 4308 v = pci_alloc_consistent(priv->pci_dev,
4304 priv->pci_dev, sizeof(struct ipw2100_data_header), &p); 4309 sizeof(struct ipw2100_data_header),
4310 &p);
4305 if (!v) { 4311 if (!v) {
4306 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for tx " 4312 printk(KERN_ERR DRV_NAME
4307 "buffers.\n", priv->net_dev->name); 4313 ": %s: PCI alloc failed for tx " "buffers.\n",
4314 priv->net_dev->name);
4308 err = -ENOMEM; 4315 err = -ENOMEM;
4309 break; 4316 break;
4310 } 4317 }
4311 4318
4312 priv->tx_buffers[i].type = DATA; 4319 priv->tx_buffers[i].type = DATA;
4313 priv->tx_buffers[i].info.d_struct.data = (struct ipw2100_data_header*)v; 4320 priv->tx_buffers[i].info.d_struct.data =
4321 (struct ipw2100_data_header *)v;
4314 priv->tx_buffers[i].info.d_struct.data_phys = p; 4322 priv->tx_buffers[i].info.d_struct.data_phys = p;
4315 priv->tx_buffers[i].info.d_struct.txb = NULL; 4323 priv->tx_buffers[i].info.d_struct.txb = NULL;
4316 } 4324 }
@@ -4319,11 +4327,11 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4319 return 0; 4327 return 0;
4320 4328
4321 for (j = 0; j < i; j++) { 4329 for (j = 0; j < i; j++) {
4322 pci_free_consistent( 4330 pci_free_consistent(priv->pci_dev,
4323 priv->pci_dev, 4331 sizeof(struct ipw2100_data_header),
4324 sizeof(struct ipw2100_data_header), 4332 priv->tx_buffers[j].info.d_struct.data,
4325 priv->tx_buffers[j].info.d_struct.data, 4333 priv->tx_buffers[j].info.d_struct.
4326 priv->tx_buffers[j].info.d_struct.data_phys); 4334 data_phys);
4327 } 4335 }
4328 4336
4329 kfree(priv->tx_buffers); 4337 kfree(priv->tx_buffers);
@@ -4356,7 +4364,8 @@ static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
4356 /* We simply drop any SKBs that have been queued for 4364 /* We simply drop any SKBs that have been queued for
4357 * transmit */ 4365 * transmit */
4358 if (priv->tx_buffers[i].info.d_struct.txb) { 4366 if (priv->tx_buffers[i].info.d_struct.txb) {
4359 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb); 4367 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
4368 txb);
4360 priv->tx_buffers[i].info.d_struct.txb = NULL; 4369 priv->tx_buffers[i].info.d_struct.txb = NULL;
4361 } 4370 }
4362 4371
@@ -4394,15 +4403,17 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
4394 4403
4395 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) { 4404 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4396 if (priv->tx_buffers[i].info.d_struct.txb) { 4405 if (priv->tx_buffers[i].info.d_struct.txb) {
4397 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb); 4406 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.
4407 txb);
4398 priv->tx_buffers[i].info.d_struct.txb = NULL; 4408 priv->tx_buffers[i].info.d_struct.txb = NULL;
4399 } 4409 }
4400 if (priv->tx_buffers[i].info.d_struct.data) 4410 if (priv->tx_buffers[i].info.d_struct.data)
4401 pci_free_consistent( 4411 pci_free_consistent(priv->pci_dev,
4402 priv->pci_dev, 4412 sizeof(struct ipw2100_data_header),
4403 sizeof(struct ipw2100_data_header), 4413 priv->tx_buffers[i].info.d_struct.
4404 priv->tx_buffers[i].info.d_struct.data, 4414 data,
4405 priv->tx_buffers[i].info.d_struct.data_phys); 4415 priv->tx_buffers[i].info.d_struct.
4416 data_phys);
4406 } 4417 }
4407 4418
4408 kfree(priv->tx_buffers); 4419 kfree(priv->tx_buffers);
@@ -4411,8 +4422,6 @@ static void ipw2100_tx_free(struct ipw2100_priv *priv)
4411 IPW_DEBUG_INFO("exit\n"); 4422 IPW_DEBUG_INFO("exit\n");
4412} 4423}
4413 4424
4414
4415
4416static int ipw2100_rx_allocate(struct ipw2100_priv *priv) 4425static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
4417{ 4426{
4418 int i, j, err = -EINVAL; 4427 int i, j, err = -EINVAL;
@@ -4542,14 +4551,13 @@ static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
4542 4551
4543 int err; 4552 int err;
4544 4553
4545 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, 4554 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC, mac, &length);
4546 mac, &length);
4547 if (err) { 4555 if (err) {
4548 IPW_DEBUG_INFO("MAC address read failed\n"); 4556 IPW_DEBUG_INFO("MAC address read failed\n");
4549 return -EIO; 4557 return -EIO;
4550 } 4558 }
4551 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n", 4559 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n",
4552 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 4560 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4553 4561
4554 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN); 4562 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN);
4555 4563
@@ -4576,8 +4584,7 @@ static int ipw2100_set_mac_address(struct ipw2100_priv *priv, int batch_mode)
4576 IPW_DEBUG_INFO("enter\n"); 4584 IPW_DEBUG_INFO("enter\n");
4577 4585
4578 if (priv->config & CFG_CUSTOM_MAC) { 4586 if (priv->config & CFG_CUSTOM_MAC) {
4579 memcpy(cmd.host_command_parameters, priv->mac_addr, 4587 memcpy(cmd.host_command_parameters, priv->mac_addr, ETH_ALEN);
4580 ETH_ALEN);
4581 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 4588 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
4582 } else 4589 } else
4583 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr, 4590 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr,
@@ -4614,7 +4621,8 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4614 if (!batch_mode) { 4621 if (!batch_mode) {
4615 err = ipw2100_disable_adapter(priv); 4622 err = ipw2100_disable_adapter(priv);
4616 if (err) { 4623 if (err) {
4617 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 4624 printk(KERN_ERR DRV_NAME
4625 ": %s: Could not disable adapter %d\n",
4618 priv->net_dev->name, err); 4626 priv->net_dev->name, err);
4619 return err; 4627 return err;
4620 } 4628 }
@@ -4629,7 +4637,6 @@ static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
4629 return err; 4637 return err;
4630} 4638}
4631 4639
4632
4633static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel, 4640static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4634 int batch_mode) 4641 int batch_mode)
4635{ 4642{
@@ -4660,8 +4667,7 @@ static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4660 4667
4661 err = ipw2100_hw_send_command(priv, &cmd); 4668 err = ipw2100_hw_send_command(priv, &cmd);
4662 if (err) { 4669 if (err) {
4663 IPW_DEBUG_INFO("Failed to set channel to %d", 4670 IPW_DEBUG_INFO("Failed to set channel to %d", channel);
4664 channel);
4665 return err; 4671 return err;
4666 } 4672 }
4667 4673
@@ -4703,15 +4709,14 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4703 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START; 4709 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START;
4704 4710
4705 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK | 4711 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK |
4706 IPW_CFG_BSS_MASK | 4712 IPW_CFG_BSS_MASK | IPW_CFG_802_1x_ENABLE;
4707 IPW_CFG_802_1x_ENABLE;
4708 4713
4709 if (!(priv->config & CFG_LONG_PREAMBLE)) 4714 if (!(priv->config & CFG_LONG_PREAMBLE))
4710 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO; 4715 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO;
4711 4716
4712 err = ipw2100_get_ordinal(priv, 4717 err = ipw2100_get_ordinal(priv,
4713 IPW_ORD_EEPROM_IBSS_11B_CHANNELS, 4718 IPW_ORD_EEPROM_IBSS_11B_CHANNELS,
4714 &ibss_mask, &len); 4719 &ibss_mask, &len);
4715 if (err) 4720 if (err)
4716 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK; 4721 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK;
4717 4722
@@ -4719,7 +4724,7 @@ static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
4719 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask; 4724 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask;
4720 4725
4721 /* 11b only */ 4726 /* 11b only */
4722 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A;*/ 4727 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A; */
4723 4728
4724 err = ipw2100_hw_send_command(priv, &cmd); 4729 err = ipw2100_hw_send_command(priv, &cmd);
4725 if (err) 4730 if (err)
@@ -4783,8 +4788,7 @@ static int ipw2100_set_tx_rates(struct ipw2100_priv *priv, u32 rate,
4783 return 0; 4788 return 0;
4784} 4789}
4785 4790
4786static int ipw2100_set_power_mode(struct ipw2100_priv *priv, 4791static int ipw2100_set_power_mode(struct ipw2100_priv *priv, int power_level)
4787 int power_level)
4788{ 4792{
4789 struct host_command cmd = { 4793 struct host_command cmd = {
4790 .host_command = POWER_MODE, 4794 .host_command = POWER_MODE,
@@ -4805,11 +4809,10 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4805 priv->power_mode = IPW_POWER_ENABLED | power_level; 4809 priv->power_mode = IPW_POWER_ENABLED | power_level;
4806 4810
4807#ifdef CONFIG_IPW2100_TX_POWER 4811#ifdef CONFIG_IPW2100_TX_POWER
4808 if (priv->port_type == IBSS && 4812 if (priv->port_type == IBSS && priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4809 priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4810 /* Set beacon interval */ 4813 /* Set beacon interval */
4811 cmd.host_command = TX_POWER_INDEX; 4814 cmd.host_command = TX_POWER_INDEX;
4812 cmd.host_command_parameters[0] = (u32)priv->adhoc_power; 4815 cmd.host_command_parameters[0] = (u32) priv->adhoc_power;
4813 4816
4814 err = ipw2100_hw_send_command(priv, &cmd); 4817 err = ipw2100_hw_send_command(priv, &cmd);
4815 if (err) 4818 if (err)
@@ -4820,7 +4823,6 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4820 return 0; 4823 return 0;
4821} 4824}
4822 4825
4823
4824static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold) 4826static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold)
4825{ 4827{
4826 struct host_command cmd = { 4828 struct host_command cmd = {
@@ -4925,8 +4927,7 @@ static int ipw2100_set_long_retry(struct ipw2100_priv *priv, u32 retry)
4925 return 0; 4927 return 0;
4926} 4928}
4927 4929
4928 4930static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
4929static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4930 int batch_mode) 4931 int batch_mode)
4931{ 4932{
4932 struct host_command cmd = { 4933 struct host_command cmd = {
@@ -4938,16 +4939,15 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4938 4939
4939#ifdef CONFIG_IPW_DEBUG 4940#ifdef CONFIG_IPW_DEBUG
4940 if (bssid != NULL) 4941 if (bssid != NULL)
4941 IPW_DEBUG_HC( 4942 IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
4942 "MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", 4943 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
4943 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], 4944 bssid[5]);
4944 bssid[5]);
4945 else 4945 else
4946 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n"); 4946 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n");
4947#endif 4947#endif
4948 /* if BSSID is empty then we disable mandatory bssid mode */ 4948 /* if BSSID is empty then we disable mandatory bssid mode */
4949 if (bssid != NULL) 4949 if (bssid != NULL)
4950 memcpy((u8 *)cmd.host_command_parameters, bssid, ETH_ALEN); 4950 memcpy(cmd.host_command_parameters, bssid, ETH_ALEN);
4951 4951
4952 if (!batch_mode) { 4952 if (!batch_mode) {
4953 err = ipw2100_disable_adapter(priv); 4953 err = ipw2100_disable_adapter(priv);
@@ -4963,7 +4963,6 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4963 return err; 4963 return err;
4964} 4964}
4965 4965
4966#ifdef CONFIG_IEEE80211_WPA
4967static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv) 4966static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4968{ 4967{
4969 struct host_command cmd = { 4968 struct host_command cmd = {
@@ -4987,42 +4986,10 @@ static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4987 4986
4988 return err; 4987 return err;
4989} 4988}
4990#endif
4991
4992/*
4993 * Pseudo code for setting up wpa_frame:
4994 */
4995#if 0
4996void x(struct ieee80211_assoc_frame *wpa_assoc)
4997{
4998 struct ipw2100_wpa_assoc_frame frame;
4999 frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
5000 IPW_WPA_LISTENINTERVAL |
5001 IPW_WPA_AP_ADDRESS;
5002 frame->capab_info = wpa_assoc->capab_info;
5003 frame->lisen_interval = wpa_assoc->listent_interval;
5004 memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
5005
5006 /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
5007 * setup here to test it with.
5008 *
5009 * Walk the IEs in the wpa_assoc and figure out the total size of all
5010 * that data. Stick that into frame->var_ie_len. Then memcpy() all of
5011 * the IEs from wpa_frame into frame.
5012 */
5013 frame->var_ie_len = calculate_ie_len(wpa_assoc);
5014 memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
5015
5016 ipw2100_set_wpa_ie(priv, &frame, 0);
5017}
5018#endif
5019
5020
5021
5022 4989
5023static int ipw2100_set_wpa_ie(struct ipw2100_priv *, 4990static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
5024 struct ipw2100_wpa_assoc_frame *, int) 4991 struct ipw2100_wpa_assoc_frame *, int)
5025__attribute__ ((unused)); 4992 __attribute__ ((unused));
5026 4993
5027static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv, 4994static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv,
5028 struct ipw2100_wpa_assoc_frame *wpa_frame, 4995 struct ipw2100_wpa_assoc_frame *wpa_frame,
@@ -5076,7 +5043,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5076 .host_command_length = sizeof(struct security_info_params) 5043 .host_command_length = sizeof(struct security_info_params)
5077 }; 5044 };
5078 struct security_info_params *security = 5045 struct security_info_params *security =
5079 (struct security_info_params *)&cmd.host_command_parameters; 5046 (struct security_info_params *)&cmd.host_command_parameters;
5080 int err; 5047 int err;
5081 memset(security, 0, sizeof(*security)); 5048 memset(security, 0, sizeof(*security));
5082 5049
@@ -5094,25 +5061,25 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5094 break; 5061 break;
5095 case SEC_LEVEL_1: 5062 case SEC_LEVEL_1:
5096 security->allowed_ciphers = IPW_WEP40_CIPHER | 5063 security->allowed_ciphers = IPW_WEP40_CIPHER |
5097 IPW_WEP104_CIPHER; 5064 IPW_WEP104_CIPHER;
5098 break; 5065 break;
5099 case SEC_LEVEL_2: 5066 case SEC_LEVEL_2:
5100 security->allowed_ciphers = IPW_WEP40_CIPHER | 5067 security->allowed_ciphers = IPW_WEP40_CIPHER |
5101 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER; 5068 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER;
5102 break; 5069 break;
5103 case SEC_LEVEL_2_CKIP: 5070 case SEC_LEVEL_2_CKIP:
5104 security->allowed_ciphers = IPW_WEP40_CIPHER | 5071 security->allowed_ciphers = IPW_WEP40_CIPHER |
5105 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER; 5072 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER;
5106 break; 5073 break;
5107 case SEC_LEVEL_3: 5074 case SEC_LEVEL_3:
5108 security->allowed_ciphers = IPW_WEP40_CIPHER | 5075 security->allowed_ciphers = IPW_WEP40_CIPHER |
5109 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER; 5076 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER;
5110 break; 5077 break;
5111 } 5078 }
5112 5079
5113 IPW_DEBUG_HC( 5080 IPW_DEBUG_HC
5114 "SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n", 5081 ("SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n",
5115 security->auth_mode, security->allowed_ciphers, security_level); 5082 security->auth_mode, security->allowed_ciphers, security_level);
5116 5083
5117 security->replay_counters_number = 0; 5084 security->replay_counters_number = 0;
5118 5085
@@ -5130,8 +5097,7 @@ static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5130 return err; 5097 return err;
5131} 5098}
5132 5099
5133static int ipw2100_set_tx_power(struct ipw2100_priv *priv, 5100static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power)
5134 u32 tx_power)
5135{ 5101{
5136 struct host_command cmd = { 5102 struct host_command cmd = {
5137 .host_command = TX_POWER_INDEX, 5103 .host_command = TX_POWER_INDEX,
@@ -5140,6 +5106,10 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv,
5140 }; 5106 };
5141 int err = 0; 5107 int err = 0;
5142 5108
5109 if (tx_power != IPW_TX_POWER_DEFAULT)
5110 tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
5111 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
5112
5143 cmd.host_command_parameters[0] = tx_power; 5113 cmd.host_command_parameters[0] = tx_power;
5144 5114
5145 if (priv->ieee->iw_mode == IW_MODE_ADHOC) 5115 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
@@ -5185,7 +5155,6 @@ static int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
5185 return 0; 5155 return 0;
5186} 5156}
5187 5157
5188
5189void ipw2100_queues_initialize(struct ipw2100_priv *priv) 5158void ipw2100_queues_initialize(struct ipw2100_priv *priv)
5190{ 5159{
5191 ipw2100_tx_initialize(priv); 5160 ipw2100_tx_initialize(priv);
@@ -5203,13 +5172,12 @@ void ipw2100_queues_free(struct ipw2100_priv *priv)
5203int ipw2100_queues_allocate(struct ipw2100_priv *priv) 5172int ipw2100_queues_allocate(struct ipw2100_priv *priv)
5204{ 5173{
5205 if (ipw2100_tx_allocate(priv) || 5174 if (ipw2100_tx_allocate(priv) ||
5206 ipw2100_rx_allocate(priv) || 5175 ipw2100_rx_allocate(priv) || ipw2100_msg_allocate(priv))
5207 ipw2100_msg_allocate(priv))
5208 goto fail; 5176 goto fail;
5209 5177
5210 return 0; 5178 return 0;
5211 5179
5212 fail: 5180 fail:
5213 ipw2100_tx_free(priv); 5181 ipw2100_tx_free(priv);
5214 ipw2100_rx_free(priv); 5182 ipw2100_rx_free(priv);
5215 ipw2100_msg_free(priv); 5183 ipw2100_msg_free(priv);
@@ -5235,7 +5203,8 @@ static int ipw2100_set_wep_flags(struct ipw2100_priv *priv, u32 flags,
5235 if (!batch_mode) { 5203 if (!batch_mode) {
5236 err = ipw2100_disable_adapter(priv); 5204 err = ipw2100_disable_adapter(priv);
5237 if (err) { 5205 if (err) {
5238 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5206 printk(KERN_ERR DRV_NAME
5207 ": %s: Could not disable adapter %d\n",
5239 priv->net_dev->name, err); 5208 priv->net_dev->name, err);
5240 return err; 5209 return err;
5241 } 5210 }
@@ -5262,7 +5231,6 @@ struct ipw2100_wep_key {
5262#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4] 5231#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4]
5263#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10] 5232#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]
5264 5233
5265
5266/** 5234/**
5267 * Set a the wep key 5235 * Set a the wep key
5268 * 5236 *
@@ -5287,11 +5255,11 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
5287 .host_command_sequence = 0, 5255 .host_command_sequence = 0,
5288 .host_command_length = sizeof(struct ipw2100_wep_key), 5256 .host_command_length = sizeof(struct ipw2100_wep_key),
5289 }; 5257 };
5290 struct ipw2100_wep_key *wep_key = (void*)cmd.host_command_parameters; 5258 struct ipw2100_wep_key *wep_key = (void *)cmd.host_command_parameters;
5291 int err; 5259 int err;
5292 5260
5293 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n", 5261 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
5294 idx, keylen, len); 5262 idx, keylen, len);
5295 5263
5296 /* NOTE: We don't check cached values in case the firmware was reset 5264 /* NOTE: We don't check cached values in case the firmware was reset
5297 * or some other problem is occuring. If the user is setting the key, 5265 * or some other problem is occuring. If the user is setting the key,
@@ -5308,22 +5276,23 @@ static int ipw2100_set_key(struct ipw2100_priv *priv,
5308 /* Will be optimized out on debug not being configured in */ 5276 /* Will be optimized out on debug not being configured in */
5309 if (keylen == 0) 5277 if (keylen == 0)
5310 IPW_DEBUG_WEP("%s: Clearing key %d\n", 5278 IPW_DEBUG_WEP("%s: Clearing key %d\n",
5311 priv->net_dev->name, wep_key->idx); 5279 priv->net_dev->name, wep_key->idx);
5312 else if (keylen == 5) 5280 else if (keylen == 5)
5313 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n", 5281 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n",
5314 priv->net_dev->name, wep_key->idx, wep_key->len, 5282 priv->net_dev->name, wep_key->idx, wep_key->len,
5315 WEP_STR_64(wep_key->key)); 5283 WEP_STR_64(wep_key->key));
5316 else 5284 else
5317 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128 5285 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128
5318 "\n", 5286 "\n",
5319 priv->net_dev->name, wep_key->idx, wep_key->len, 5287 priv->net_dev->name, wep_key->idx, wep_key->len,
5320 WEP_STR_128(wep_key->key)); 5288 WEP_STR_128(wep_key->key));
5321 5289
5322 if (!batch_mode) { 5290 if (!batch_mode) {
5323 err = ipw2100_disable_adapter(priv); 5291 err = ipw2100_disable_adapter(priv);
5324 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */ 5292 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */
5325 if (err) { 5293 if (err) {
5326 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5294 printk(KERN_ERR DRV_NAME
5295 ": %s: Could not disable adapter %d\n",
5327 priv->net_dev->name, err); 5296 priv->net_dev->name, err);
5328 return err; 5297 return err;
5329 } 5298 }
@@ -5347,7 +5316,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5347 .host_command = WEP_KEY_INDEX, 5316 .host_command = WEP_KEY_INDEX,
5348 .host_command_sequence = 0, 5317 .host_command_sequence = 0,
5349 .host_command_length = 4, 5318 .host_command_length = 4,
5350 .host_command_parameters = { idx }, 5319 .host_command_parameters = {idx},
5351 }; 5320 };
5352 int err; 5321 int err;
5353 5322
@@ -5359,7 +5328,8 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5359 if (!batch_mode) { 5328 if (!batch_mode) {
5360 err = ipw2100_disable_adapter(priv); 5329 err = ipw2100_disable_adapter(priv);
5361 if (err) { 5330 if (err) {
5362 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n", 5331 printk(KERN_ERR DRV_NAME
5332 ": %s: Could not disable adapter %d\n",
5363 priv->net_dev->name, err); 5333 priv->net_dev->name, err);
5364 return err; 5334 return err;
5365 } 5335 }
@@ -5374,9 +5344,7 @@ static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5374 return err; 5344 return err;
5375} 5345}
5376 5346
5377 5347static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode)
5378static int ipw2100_configure_security(struct ipw2100_priv *priv,
5379 int batch_mode)
5380{ 5348{
5381 int i, err, auth_mode, sec_level, use_group; 5349 int i, err, auth_mode, sec_level, use_group;
5382 5350
@@ -5389,40 +5357,42 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
5389 return err; 5357 return err;
5390 } 5358 }
5391 5359
5392 if (!priv->sec.enabled) { 5360 if (!priv->ieee->sec.enabled) {
5393 err = ipw2100_set_security_information( 5361 err =
5394 priv, IPW_AUTH_OPEN, SEC_LEVEL_0, 0, 1); 5362 ipw2100_set_security_information(priv, IPW_AUTH_OPEN,
5363 SEC_LEVEL_0, 0, 1);
5395 } else { 5364 } else {
5396 auth_mode = IPW_AUTH_OPEN; 5365 auth_mode = IPW_AUTH_OPEN;
5397 if ((priv->sec.flags & SEC_AUTH_MODE) && 5366 if ((priv->ieee->sec.flags & SEC_AUTH_MODE) &&
5398 (priv->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) 5367 (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
5399 auth_mode = IPW_AUTH_SHARED; 5368 auth_mode = IPW_AUTH_SHARED;
5400 5369
5401 sec_level = SEC_LEVEL_0; 5370 sec_level = SEC_LEVEL_0;
5402 if (priv->sec.flags & SEC_LEVEL) 5371 if (priv->ieee->sec.flags & SEC_LEVEL)
5403 sec_level = priv->sec.level; 5372 sec_level = priv->ieee->sec.level;
5404 5373
5405 use_group = 0; 5374 use_group = 0;
5406 if (priv->sec.flags & SEC_UNICAST_GROUP) 5375 if (priv->ieee->sec.flags & SEC_UNICAST_GROUP)
5407 use_group = priv->sec.unicast_uses_group; 5376 use_group = priv->ieee->sec.unicast_uses_group;
5408 5377
5409 err = ipw2100_set_security_information( 5378 err =
5410 priv, auth_mode, sec_level, use_group, 1); 5379 ipw2100_set_security_information(priv, auth_mode, sec_level,
5380 use_group, 1);
5411 } 5381 }
5412 5382
5413 if (err) 5383 if (err)
5414 goto exit; 5384 goto exit;
5415 5385
5416 if (priv->sec.enabled) { 5386 if (priv->ieee->sec.enabled) {
5417 for (i = 0; i < 4; i++) { 5387 for (i = 0; i < 4; i++) {
5418 if (!(priv->sec.flags & (1 << i))) { 5388 if (!(priv->ieee->sec.flags & (1 << i))) {
5419 memset(priv->sec.keys[i], 0, WEP_KEY_LEN); 5389 memset(priv->ieee->sec.keys[i], 0, WEP_KEY_LEN);
5420 priv->sec.key_sizes[i] = 0; 5390 priv->ieee->sec.key_sizes[i] = 0;
5421 } else { 5391 } else {
5422 err = ipw2100_set_key(priv, i, 5392 err = ipw2100_set_key(priv, i,
5423 priv->sec.keys[i], 5393 priv->ieee->sec.keys[i],
5424 priv->sec.key_sizes[i], 5394 priv->ieee->sec.
5425 1); 5395 key_sizes[i], 1);
5426 if (err) 5396 if (err)
5427 goto exit; 5397 goto exit;
5428 } 5398 }
@@ -5433,14 +5403,16 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv,
5433 5403
5434 /* Always enable privacy so the Host can filter WEP packets if 5404 /* Always enable privacy so the Host can filter WEP packets if
5435 * encrypted data is sent up */ 5405 * encrypted data is sent up */
5436 err = ipw2100_set_wep_flags( 5406 err =
5437 priv, priv->sec.enabled ? IPW_PRIVACY_CAPABLE : 0, 1); 5407 ipw2100_set_wep_flags(priv,
5408 priv->ieee->sec.
5409 enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
5438 if (err) 5410 if (err)
5439 goto exit; 5411 goto exit;
5440 5412
5441 priv->status &= ~STATUS_SECURITY_UPDATED; 5413 priv->status &= ~STATUS_SECURITY_UPDATED;
5442 5414
5443 exit: 5415 exit:
5444 if (!batch_mode) 5416 if (!batch_mode)
5445 ipw2100_enable_adapter(priv); 5417 ipw2100_enable_adapter(priv);
5446 5418
@@ -5469,60 +5441,64 @@ static void shim__set_security(struct net_device *dev,
5469 5441
5470 for (i = 0; i < 4; i++) { 5442 for (i = 0; i < 4; i++) {
5471 if (sec->flags & (1 << i)) { 5443 if (sec->flags & (1 << i)) {
5472 priv->sec.key_sizes[i] = sec->key_sizes[i]; 5444 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
5473 if (sec->key_sizes[i] == 0) 5445 if (sec->key_sizes[i] == 0)
5474 priv->sec.flags &= ~(1 << i); 5446 priv->ieee->sec.flags &= ~(1 << i);
5475 else 5447 else
5476 memcpy(priv->sec.keys[i], sec->keys[i], 5448 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
5477 sec->key_sizes[i]); 5449 sec->key_sizes[i]);
5478 priv->sec.flags |= (1 << i); 5450 if (sec->level == SEC_LEVEL_1) {
5479 priv->status |= STATUS_SECURITY_UPDATED; 5451 priv->ieee->sec.flags |= (1 << i);
5452 priv->status |= STATUS_SECURITY_UPDATED;
5453 } else
5454 priv->ieee->sec.flags &= ~(1 << i);
5480 } 5455 }
5481 } 5456 }
5482 5457
5483 if ((sec->flags & SEC_ACTIVE_KEY) && 5458 if ((sec->flags & SEC_ACTIVE_KEY) &&
5484 priv->sec.active_key != sec->active_key) { 5459 priv->ieee->sec.active_key != sec->active_key) {
5485 if (sec->active_key <= 3) { 5460 if (sec->active_key <= 3) {
5486 priv->sec.active_key = sec->active_key; 5461 priv->ieee->sec.active_key = sec->active_key;
5487 priv->sec.flags |= SEC_ACTIVE_KEY; 5462 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
5488 } else 5463 } else
5489 priv->sec.flags &= ~SEC_ACTIVE_KEY; 5464 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
5490 5465
5491 priv->status |= STATUS_SECURITY_UPDATED; 5466 priv->status |= STATUS_SECURITY_UPDATED;
5492 } 5467 }
5493 5468
5494 if ((sec->flags & SEC_AUTH_MODE) && 5469 if ((sec->flags & SEC_AUTH_MODE) &&
5495 (priv->sec.auth_mode != sec->auth_mode)) { 5470 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
5496 priv->sec.auth_mode = sec->auth_mode; 5471 priv->ieee->sec.auth_mode = sec->auth_mode;
5497 priv->sec.flags |= SEC_AUTH_MODE; 5472 priv->ieee->sec.flags |= SEC_AUTH_MODE;
5498 priv->status |= STATUS_SECURITY_UPDATED; 5473 priv->status |= STATUS_SECURITY_UPDATED;
5499 } 5474 }
5500 5475
5501 if (sec->flags & SEC_ENABLED && 5476 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
5502 priv->sec.enabled != sec->enabled) { 5477 priv->ieee->sec.flags |= SEC_ENABLED;
5503 priv->sec.flags |= SEC_ENABLED; 5478 priv->ieee->sec.enabled = sec->enabled;
5504 priv->sec.enabled = sec->enabled;
5505 priv->status |= STATUS_SECURITY_UPDATED; 5479 priv->status |= STATUS_SECURITY_UPDATED;
5506 force_update = 1; 5480 force_update = 1;
5507 } 5481 }
5508 5482
5509 if (sec->flags & SEC_LEVEL && 5483 if (sec->flags & SEC_ENCRYPT)
5510 priv->sec.level != sec->level) { 5484 priv->ieee->sec.encrypt = sec->encrypt;
5511 priv->sec.level = sec->level; 5485
5512 priv->sec.flags |= SEC_LEVEL; 5486 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
5487 priv->ieee->sec.level = sec->level;
5488 priv->ieee->sec.flags |= SEC_LEVEL;
5513 priv->status |= STATUS_SECURITY_UPDATED; 5489 priv->status |= STATUS_SECURITY_UPDATED;
5514 } 5490 }
5515 5491
5516 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n", 5492 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n",
5517 priv->sec.flags & (1<<8) ? '1' : '0', 5493 priv->ieee->sec.flags & (1 << 8) ? '1' : '0',
5518 priv->sec.flags & (1<<7) ? '1' : '0', 5494 priv->ieee->sec.flags & (1 << 7) ? '1' : '0',
5519 priv->sec.flags & (1<<6) ? '1' : '0', 5495 priv->ieee->sec.flags & (1 << 6) ? '1' : '0',
5520 priv->sec.flags & (1<<5) ? '1' : '0', 5496 priv->ieee->sec.flags & (1 << 5) ? '1' : '0',
5521 priv->sec.flags & (1<<4) ? '1' : '0', 5497 priv->ieee->sec.flags & (1 << 4) ? '1' : '0',
5522 priv->sec.flags & (1<<3) ? '1' : '0', 5498 priv->ieee->sec.flags & (1 << 3) ? '1' : '0',
5523 priv->sec.flags & (1<<2) ? '1' : '0', 5499 priv->ieee->sec.flags & (1 << 2) ? '1' : '0',
5524 priv->sec.flags & (1<<1) ? '1' : '0', 5500 priv->ieee->sec.flags & (1 << 1) ? '1' : '0',
5525 priv->sec.flags & (1<<0) ? '1' : '0'); 5501 priv->ieee->sec.flags & (1 << 0) ? '1' : '0');
5526 5502
5527/* As a temporary work around to enable WPA until we figure out why 5503/* As a temporary work around to enable WPA until we figure out why
5528 * wpa_supplicant toggles the security capability of the driver, which 5504 * wpa_supplicant toggles the security capability of the driver, which
@@ -5531,7 +5507,7 @@ static void shim__set_security(struct net_device *dev,
5531 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/ 5507 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/
5532 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) 5508 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
5533 ipw2100_configure_security(priv, 0); 5509 ipw2100_configure_security(priv, 0);
5534done: 5510 done:
5535 up(&priv->action_sem); 5511 up(&priv->action_sem);
5536} 5512}
5537 5513
@@ -5556,7 +5532,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5556 5532
5557 return 0; 5533 return 0;
5558 } 5534 }
5559#endif /* CONFIG_IPW2100_MONITOR */ 5535#endif /* CONFIG_IPW2100_MONITOR */
5560 5536
5561 err = ipw2100_read_mac_address(priv); 5537 err = ipw2100_read_mac_address(priv);
5562 if (err) 5538 if (err)
@@ -5576,7 +5552,7 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5576 return err; 5552 return err;
5577 } 5553 }
5578 5554
5579 err = ipw2100_system_config(priv, batch_mode); 5555 err = ipw2100_system_config(priv, batch_mode);
5580 if (err) 5556 if (err)
5581 return err; 5557 return err;
5582 5558
@@ -5614,8 +5590,10 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5614 return err; 5590 return err;
5615 5591
5616 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 5592 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5617 err = ipw2100_set_ibss_beacon_interval( 5593 err =
5618 priv, priv->beacon_interval, batch_mode); 5594 ipw2100_set_ibss_beacon_interval(priv,
5595 priv->beacon_interval,
5596 batch_mode);
5619 if (err) 5597 if (err)
5620 return err; 5598 return err;
5621 5599
@@ -5625,18 +5603,17 @@ static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5625 } 5603 }
5626 5604
5627 /* 5605 /*
5628 err = ipw2100_set_fragmentation_threshold( 5606 err = ipw2100_set_fragmentation_threshold(
5629 priv, priv->frag_threshold, batch_mode); 5607 priv, priv->frag_threshold, batch_mode);
5630 if (err) 5608 if (err)
5631 return err; 5609 return err;
5632 */ 5610 */
5633 5611
5634 IPW_DEBUG_INFO("exit\n"); 5612 IPW_DEBUG_INFO("exit\n");
5635 5613
5636 return 0; 5614 return 0;
5637} 5615}
5638 5616
5639
5640/************************************************************************* 5617/*************************************************************************
5641 * 5618 *
5642 * EXTERNALLY CALLED METHODS 5619 * EXTERNALLY CALLED METHODS
@@ -5669,7 +5646,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p)
5669 ipw2100_reset_adapter(priv); 5646 ipw2100_reset_adapter(priv);
5670 return 0; 5647 return 0;
5671 5648
5672 done: 5649 done:
5673 up(&priv->action_sem); 5650 up(&priv->action_sem);
5674 return err; 5651 return err;
5675} 5652}
@@ -5708,7 +5685,7 @@ static int ipw2100_close(struct net_device *dev)
5708 /* Flush the TX queue ... */ 5685 /* Flush the TX queue ... */
5709 while (!list_empty(&priv->tx_pend_list)) { 5686 while (!list_empty(&priv->tx_pend_list)) {
5710 element = priv->tx_pend_list.next; 5687 element = priv->tx_pend_list.next;
5711 packet = list_entry(element, struct ipw2100_tx_packet, list); 5688 packet = list_entry(element, struct ipw2100_tx_packet, list);
5712 5689
5713 list_del(element); 5690 list_del(element);
5714 DEC_STAT(&priv->tx_pend_stat); 5691 DEC_STAT(&priv->tx_pend_stat);
@@ -5726,8 +5703,6 @@ static int ipw2100_close(struct net_device *dev)
5726 return 0; 5703 return 0;
5727} 5704}
5728 5705
5729
5730
5731/* 5706/*
5732 * TODO: Fix this function... its just wrong 5707 * TODO: Fix this function... its just wrong
5733 */ 5708 */
@@ -5747,7 +5722,6 @@ static void ipw2100_tx_timeout(struct net_device *dev)
5747 schedule_reset(priv); 5722 schedule_reset(priv);
5748} 5723}
5749 5724
5750
5751/* 5725/*
5752 * TODO: reimplement it so that it reads statistics 5726 * TODO: reimplement it so that it reads statistics
5753 * from the adapter using ordinal tables 5727 * from the adapter using ordinal tables
@@ -5761,11 +5735,10 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5761 return &priv->ieee->stats; 5735 return &priv->ieee->stats;
5762} 5736}
5763 5737
5764/* Support for wpa_supplicant. Will be replaced with WEXT once 5738#if WIRELESS_EXT < 18
5765 * they get WPA support. */ 5739/* Support for wpa_supplicant before WE-18, deprecated. */
5766#ifdef CONFIG_IEEE80211_WPA
5767 5740
5768/* following definitions must match definitions in driver_ipw2100.c */ 5741/* following definitions must match definitions in driver_ipw.c */
5769 5742
5770#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 5743#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5771 5744
@@ -5796,25 +5769,26 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5796struct ipw2100_param { 5769struct ipw2100_param {
5797 u32 cmd; 5770 u32 cmd;
5798 u8 sta_addr[ETH_ALEN]; 5771 u8 sta_addr[ETH_ALEN];
5799 union { 5772 union {
5800 struct { 5773 struct {
5801 u8 name; 5774 u8 name;
5802 u32 value; 5775 u32 value;
5803 } wpa_param; 5776 } wpa_param;
5804 struct { 5777 struct {
5805 u32 len; 5778 u32 len;
5806 u8 *data; 5779 u8 reserved[32];
5780 u8 data[0];
5807 } wpa_ie; 5781 } wpa_ie;
5808 struct{ 5782 struct {
5809 int command; 5783 u32 command;
5810 int reason_code; 5784 u32 reason_code;
5811 } mlme; 5785 } mlme;
5812 struct { 5786 struct {
5813 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN]; 5787 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
5814 u8 set_tx; 5788 u8 set_tx;
5815 u32 err; 5789 u32 err;
5816 u8 idx; 5790 u8 idx;
5817 u8 seq[8]; /* sequence counter (set: RX, get: TX) */ 5791 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5818 u16 key_len; 5792 u16 key_len;
5819 u8 key[0]; 5793 u8 key[0];
5820 } crypt; 5794 } crypt;
@@ -5822,38 +5796,24 @@ struct ipw2100_param {
5822 } u; 5796 } u;
5823}; 5797};
5824 5798
5825/* end of driver_ipw2100.c code */ 5799/* end of driver_ipw.c code */
5826 5800#endif /* WIRELESS_EXT < 18 */
5827static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value){
5828 5801
5829 struct ieee80211_device *ieee = priv->ieee; 5802static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
5830 struct ieee80211_security sec = { 5803{
5831 .flags = SEC_LEVEL | SEC_ENABLED, 5804 /* This is called when wpa_supplicant loads and closes the driver
5832 }; 5805 * interface. */
5833 int ret = 0; 5806 priv->ieee->wpa_enabled = value;
5834 5807 return 0;
5835 ieee->wpa_enabled = value;
5836
5837 if (value){
5838 sec.level = SEC_LEVEL_3;
5839 sec.enabled = 1;
5840 } else {
5841 sec.level = SEC_LEVEL_0;
5842 sec.enabled = 0;
5843 }
5844
5845 if (ieee->set_security)
5846 ieee->set_security(ieee->dev, &sec);
5847 else
5848 ret = -EOPNOTSUPP;
5849
5850 return ret;
5851} 5808}
5852 5809
5853#define AUTH_ALG_OPEN_SYSTEM 0x1 5810#if WIRELESS_EXT < 18
5854#define AUTH_ALG_SHARED_KEY 0x2 5811#define IW_AUTH_ALG_OPEN_SYSTEM 0x1
5812#define IW_AUTH_ALG_SHARED_KEY 0x2
5813#endif
5855 5814
5856static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){ 5815static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
5816{
5857 5817
5858 struct ieee80211_device *ieee = priv->ieee; 5818 struct ieee80211_device *ieee = priv->ieee;
5859 struct ieee80211_security sec = { 5819 struct ieee80211_security sec = {
@@ -5861,13 +5821,14 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5861 }; 5821 };
5862 int ret = 0; 5822 int ret = 0;
5863 5823
5864 if (value & AUTH_ALG_SHARED_KEY){ 5824 if (value & IW_AUTH_ALG_SHARED_KEY) {
5865 sec.auth_mode = WLAN_AUTH_SHARED_KEY; 5825 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5866 ieee->open_wep = 0; 5826 ieee->open_wep = 0;
5867 } else { 5827 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
5868 sec.auth_mode = WLAN_AUTH_OPEN; 5828 sec.auth_mode = WLAN_AUTH_OPEN;
5869 ieee->open_wep = 1; 5829 ieee->open_wep = 1;
5870 } 5830 } else
5831 return -EINVAL;
5871 5832
5872 if (ieee->set_security) 5833 if (ieee->set_security)
5873 ieee->set_security(ieee->dev, &sec); 5834 ieee->set_security(ieee->dev, &sec);
@@ -5877,103 +5838,135 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5877 return ret; 5838 return ret;
5878} 5839}
5879 5840
5841void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5842 char *wpa_ie, int wpa_ie_len)
5843{
5880 5844
5881static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value){ 5845 struct ipw2100_wpa_assoc_frame frame;
5882
5883 struct ipw2100_priv *priv = ieee80211_priv(dev);
5884 int ret=0;
5885 5846
5886 switch(name){ 5847 frame.fixed_ie_mask = 0;
5887 case IPW2100_PARAM_WPA_ENABLED:
5888 ret = ipw2100_wpa_enable(priv, value);
5889 break;
5890 5848
5891 case IPW2100_PARAM_TKIP_COUNTERMEASURES: 5849 /* copy WPA IE */
5892 priv->ieee->tkip_countermeasures=value; 5850 memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
5893 break; 5851 frame.var_ie_len = wpa_ie_len;
5894 5852
5895 case IPW2100_PARAM_DROP_UNENCRYPTED: 5853 /* make sure WPA is enabled */
5896 priv->ieee->drop_unencrypted=value; 5854 ipw2100_wpa_enable(priv, 1);
5897 break; 5855 ipw2100_set_wpa_ie(priv, &frame, 0);
5856}
5898 5857
5899 case IPW2100_PARAM_PRIVACY_INVOKED: 5858#if WIRELESS_EXT < 18
5900 priv->ieee->privacy_invoked=value; 5859static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5901 break; 5860{
5861 struct ipw2100_priv *priv = ieee80211_priv(dev);
5862 struct ieee80211_crypt_data *crypt;
5863 unsigned long flags;
5864 int ret = 0;
5902 5865
5903 case IPW2100_PARAM_AUTH_ALGS: 5866 switch (name) {
5904 ret = ipw2100_wpa_set_auth_algs(priv, value); 5867 case IPW2100_PARAM_WPA_ENABLED:
5905 break; 5868 ret = ipw2100_wpa_enable(priv, value);
5869 break;
5906 5870
5907 case IPW2100_PARAM_IEEE_802_1X: 5871 case IPW2100_PARAM_TKIP_COUNTERMEASURES:
5908 priv->ieee->ieee802_1x=value; 5872 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
5873 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
5909 break; 5874 break;
5910 5875
5911 default: 5876 flags = crypt->ops->get_flags(crypt->priv);
5912 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5913 dev->name, name);
5914 ret = -EOPNOTSUPP;
5915 }
5916 5877
5917 return ret; 5878 if (value)
5918} 5879 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5880 else
5881 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5919 5882
5920static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason){ 5883 crypt->ops->set_flags(flags, crypt->priv);
5921 5884
5922 struct ipw2100_priv *priv = ieee80211_priv(dev); 5885 break;
5923 int ret=0;
5924 5886
5925 switch(command){ 5887 case IPW2100_PARAM_DROP_UNENCRYPTED:{
5926 case IPW2100_MLME_STA_DEAUTH: 5888 /* See IW_AUTH_DROP_UNENCRYPTED handling for details */
5927 // silently ignore 5889 struct ieee80211_security sec = {
5890 .flags = SEC_ENABLED,
5891 .enabled = value,
5892 };
5893 priv->ieee->drop_unencrypted = value;
5894 /* We only change SEC_LEVEL for open mode. Others
5895 * are set by ipw_wpa_set_encryption.
5896 */
5897 if (!value) {
5898 sec.flags |= SEC_LEVEL;
5899 sec.level = SEC_LEVEL_0;
5900 } else {
5901 sec.flags |= SEC_LEVEL;
5902 sec.level = SEC_LEVEL_1;
5903 }
5904 if (priv->ieee->set_security)
5905 priv->ieee->set_security(priv->ieee->dev, &sec);
5928 break; 5906 break;
5907 }
5929 5908
5930 case IPW2100_MLME_STA_DISASSOC: 5909 case IPW2100_PARAM_PRIVACY_INVOKED:
5931 ipw2100_disassociate_bssid(priv); 5910 priv->ieee->privacy_invoked = value;
5932 break; 5911 break;
5933 5912
5934 default: 5913 case IPW2100_PARAM_AUTH_ALGS:
5935 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n", 5914 ret = ipw2100_wpa_set_auth_algs(priv, value);
5936 dev->name, command); 5915 break;
5937 ret = -EOPNOTSUPP; 5916
5917 case IPW2100_PARAM_IEEE_802_1X:
5918 priv->ieee->ieee802_1x = value;
5919 break;
5920
5921 default:
5922 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
5923 dev->name, name);
5924 ret = -EOPNOTSUPP;
5938 } 5925 }
5939 5926
5940 return ret; 5927 return ret;
5941} 5928}
5942 5929
5930static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
5931{
5943 5932
5944void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, 5933 struct ipw2100_priv *priv = ieee80211_priv(dev);
5945 char *wpa_ie, int wpa_ie_len){ 5934 int ret = 0;
5946 5935
5947 struct ipw2100_wpa_assoc_frame frame; 5936 switch (command) {
5937 case IPW2100_MLME_STA_DEAUTH:
5938 // silently ignore
5939 break;
5948 5940
5949 frame.fixed_ie_mask = 0; 5941 case IPW2100_MLME_STA_DISASSOC:
5942 ipw2100_disassociate_bssid(priv);
5943 break;
5950 5944
5951 /* copy WPA IE */ 5945 default:
5952 memcpy(frame.var_ie, wpa_ie, wpa_ie_len); 5946 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
5953 frame.var_ie_len = wpa_ie_len; 5947 dev->name, command);
5948 ret = -EOPNOTSUPP;
5949 }
5954 5950
5955 /* make sure WPA is enabled */ 5951 return ret;
5956 ipw2100_wpa_enable(priv, 1);
5957 ipw2100_set_wpa_ie(priv, &frame, 0);
5958} 5952}
5959 5953
5960
5961static int ipw2100_wpa_set_wpa_ie(struct net_device *dev, 5954static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5962 struct ipw2100_param *param, int plen){ 5955 struct ipw2100_param *param, int plen)
5956{
5963 5957
5964 struct ipw2100_priv *priv = ieee80211_priv(dev); 5958 struct ipw2100_priv *priv = ieee80211_priv(dev);
5965 struct ieee80211_device *ieee = priv->ieee; 5959 struct ieee80211_device *ieee = priv->ieee;
5966 u8 *buf; 5960 u8 *buf;
5967 5961
5968 if (! ieee->wpa_enabled) 5962 if (!ieee->wpa_enabled)
5969 return -EOPNOTSUPP; 5963 return -EOPNOTSUPP;
5970 5964
5971 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || 5965 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5972 (param->u.wpa_ie.len && 5966 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
5973 param->u.wpa_ie.data==NULL))
5974 return -EINVAL; 5967 return -EINVAL;
5975 5968
5976 if (param->u.wpa_ie.len){ 5969 if (param->u.wpa_ie.len) {
5977 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); 5970 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5978 if (buf == NULL) 5971 if (buf == NULL)
5979 return -ENOMEM; 5972 return -ENOMEM;
@@ -5998,8 +5991,9 @@ static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5998/* implementation borrowed from hostap driver */ 5991/* implementation borrowed from hostap driver */
5999 5992
6000static int ipw2100_wpa_set_encryption(struct net_device *dev, 5993static int ipw2100_wpa_set_encryption(struct net_device *dev,
6001 struct ipw2100_param *param, int param_len){ 5994 struct ipw2100_param *param,
6002 5995 int param_len)
5996{
6003 int ret = 0; 5997 int ret = 0;
6004 struct ipw2100_priv *priv = ieee80211_priv(dev); 5998 struct ipw2100_priv *priv = ieee80211_priv(dev);
6005 struct ieee80211_device *ieee = priv->ieee; 5999 struct ieee80211_device *ieee = priv->ieee;
@@ -6014,9 +6008,10 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6014 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0'; 6008 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
6015 6009
6016 if (param_len != 6010 if (param_len !=
6017 (int) ((char *) param->u.crypt.key - (char *) param) + 6011 (int)((char *)param->u.crypt.key - (char *)param) +
6018 param->u.crypt.key_len){ 6012 param->u.crypt.key_len) {
6019 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len); 6013 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
6014 param->u.crypt.key_len);
6020 return -EINVAL; 6015 return -EINVAL;
6021 } 6016 }
6022 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && 6017 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
@@ -6029,17 +6024,19 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6029 return -EINVAL; 6024 return -EINVAL;
6030 } 6025 }
6031 6026
6027 sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
6032 if (strcmp(param->u.crypt.alg, "none") == 0) { 6028 if (strcmp(param->u.crypt.alg, "none") == 0) {
6033 if (crypt){ 6029 if (crypt) {
6034 sec.enabled = 0; 6030 sec.enabled = 0;
6031 sec.encrypt = 0;
6035 sec.level = SEC_LEVEL_0; 6032 sec.level = SEC_LEVEL_0;
6036 sec.flags |= SEC_ENABLED | SEC_LEVEL; 6033 sec.flags |= SEC_LEVEL;
6037 ieee80211_crypt_delayed_deinit(ieee, crypt); 6034 ieee80211_crypt_delayed_deinit(ieee, crypt);
6038 } 6035 }
6039 goto done; 6036 goto done;
6040 } 6037 }
6041 sec.enabled = 1; 6038 sec.enabled = 1;
6042 sec.flags |= SEC_ENABLED; 6039 sec.encrypt = 1;
6043 6040
6044 ops = ieee80211_get_crypto_ops(param->u.crypt.alg); 6041 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6045 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { 6042 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
@@ -6054,7 +6051,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6054 } 6051 }
6055 if (ops == NULL) { 6052 if (ops == NULL) {
6056 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n", 6053 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
6057 dev->name, param->u.crypt.alg); 6054 dev->name, param->u.crypt.alg);
6058 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG; 6055 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
6059 ret = -EINVAL; 6056 ret = -EINVAL;
6060 goto done; 6057 goto done;
@@ -6065,21 +6062,20 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6065 6062
6066 ieee80211_crypt_delayed_deinit(ieee, crypt); 6063 ieee80211_crypt_delayed_deinit(ieee, crypt);
6067 6064
6068 new_crypt = (struct ieee80211_crypt_data *) 6065 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6069 kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6070 if (new_crypt == NULL) { 6066 if (new_crypt == NULL) {
6071 ret = -ENOMEM; 6067 ret = -ENOMEM;
6072 goto done; 6068 goto done;
6073 } 6069 }
6074 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
6075 new_crypt->ops = ops; 6070 new_crypt->ops = ops;
6076 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 6071 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
6077 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx); 6072 new_crypt->priv =
6073 new_crypt->ops->init(param->u.crypt.idx);
6078 6074
6079 if (new_crypt->priv == NULL) { 6075 if (new_crypt->priv == NULL) {
6080 kfree(new_crypt); 6076 kfree(new_crypt);
6081 param->u.crypt.err = 6077 param->u.crypt.err =
6082 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED; 6078 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
6083 ret = -EINVAL; 6079 ret = -EINVAL;
6084 goto done; 6080 goto done;
6085 } 6081 }
@@ -6091,24 +6087,25 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6091 (*crypt)->ops->set_key(param->u.crypt.key, 6087 (*crypt)->ops->set_key(param->u.crypt.key,
6092 param->u.crypt.key_len, param->u.crypt.seq, 6088 param->u.crypt.key_len, param->u.crypt.seq,
6093 (*crypt)->priv) < 0) { 6089 (*crypt)->priv) < 0) {
6094 IPW_DEBUG_INFO("%s: key setting failed\n", 6090 IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
6095 dev->name);
6096 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED; 6091 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
6097 ret = -EINVAL; 6092 ret = -EINVAL;
6098 goto done; 6093 goto done;
6099 } 6094 }
6100 6095
6101 if (param->u.crypt.set_tx){ 6096 if (param->u.crypt.set_tx) {
6102 ieee->tx_keyidx = param->u.crypt.idx; 6097 ieee->tx_keyidx = param->u.crypt.idx;
6103 sec.active_key = param->u.crypt.idx; 6098 sec.active_key = param->u.crypt.idx;
6104 sec.flags |= SEC_ACTIVE_KEY; 6099 sec.flags |= SEC_ACTIVE_KEY;
6105 } 6100 }
6106 6101
6107 if (ops->name != NULL){ 6102 if (ops->name != NULL) {
6108 6103
6109 if (strcmp(ops->name, "WEP") == 0) { 6104 if (strcmp(ops->name, "WEP") == 0) {
6110 memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len); 6105 memcpy(sec.keys[param->u.crypt.idx],
6111 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; 6106 param->u.crypt.key, param->u.crypt.key_len);
6107 sec.key_sizes[param->u.crypt.idx] =
6108 param->u.crypt.key_len;
6112 sec.flags |= (1 << param->u.crypt.idx); 6109 sec.flags |= (1 << param->u.crypt.idx);
6113 sec.flags |= SEC_LEVEL; 6110 sec.flags |= SEC_LEVEL;
6114 sec.level = SEC_LEVEL_1; 6111 sec.level = SEC_LEVEL_1;
@@ -6120,7 +6117,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6120 sec.level = SEC_LEVEL_3; 6117 sec.level = SEC_LEVEL_3;
6121 } 6118 }
6122 } 6119 }
6123 done: 6120 done:
6124 if (ieee->set_security) 6121 if (ieee->set_security)
6125 ieee->set_security(ieee->dev, &sec); 6122 ieee->set_security(ieee->dev, &sec);
6126 6123
@@ -6131,8 +6128,7 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6131 * the callbacks structures used to initialize the 802.11 stack. */ 6128 * the callbacks structures used to initialize the 802.11 stack. */
6132 if (ieee->reset_on_keychange && 6129 if (ieee->reset_on_keychange &&
6133 ieee->iw_mode != IW_MODE_INFRA && 6130 ieee->iw_mode != IW_MODE_INFRA &&
6134 ieee->reset_port && 6131 ieee->reset_port && ieee->reset_port(dev)) {
6135 ieee->reset_port(dev)) {
6136 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name); 6132 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
6137 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED; 6133 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
6138 return -EINVAL; 6134 return -EINVAL;
@@ -6141,11 +6137,11 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6141 return ret; 6137 return ret;
6142} 6138}
6143 6139
6144 6140static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
6145static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){ 6141{
6146 6142
6147 struct ipw2100_param *param; 6143 struct ipw2100_param *param;
6148 int ret=0; 6144 int ret = 0;
6149 6145
6150 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length); 6146 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
6151 6147
@@ -6156,12 +6152,12 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6156 if (param == NULL) 6152 if (param == NULL)
6157 return -ENOMEM; 6153 return -ENOMEM;
6158 6154
6159 if (copy_from_user(param, p->pointer, p->length)){ 6155 if (copy_from_user(param, p->pointer, p->length)) {
6160 kfree(param); 6156 kfree(param);
6161 return -EFAULT; 6157 return -EFAULT;
6162 } 6158 }
6163 6159
6164 switch (param->cmd){ 6160 switch (param->cmd) {
6165 6161
6166 case IPW2100_CMD_SET_WPA_PARAM: 6162 case IPW2100_CMD_SET_WPA_PARAM:
6167 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name, 6163 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
@@ -6182,8 +6178,9 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6182 break; 6178 break;
6183 6179
6184 default: 6180 default:
6185 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA supplicant request: %d\n", 6181 printk(KERN_ERR DRV_NAME
6186 dev->name, param->cmd); 6182 ": %s: Unknown WPA supplicant request: %d\n", dev->name,
6183 param->cmd);
6187 ret = -EOPNOTSUPP; 6184 ret = -EOPNOTSUPP;
6188 6185
6189 } 6186 }
@@ -6194,27 +6191,23 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6194 kfree(param); 6191 kfree(param);
6195 return ret; 6192 return ret;
6196} 6193}
6197#endif /* CONFIG_IEEE80211_WPA */
6198 6194
6199static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 6195static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6200{ 6196{
6201#ifdef CONFIG_IEEE80211_WPA 6197 struct iwreq *wrq = (struct iwreq *)rq;
6202 struct iwreq *wrq = (struct iwreq *) rq; 6198 int ret = -1;
6203 int ret=-1; 6199 switch (cmd) {
6204 switch (cmd){ 6200 case IPW2100_IOCTL_WPA_SUPPLICANT:
6205 case IPW2100_IOCTL_WPA_SUPPLICANT:
6206 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data); 6201 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
6207 return ret; 6202 return ret;
6208 6203
6209 default: 6204 default:
6210 return -EOPNOTSUPP; 6205 return -EOPNOTSUPP;
6211 } 6206 }
6212 6207
6213#endif /* CONFIG_IEEE80211_WPA */
6214
6215 return -EOPNOTSUPP; 6208 return -EOPNOTSUPP;
6216} 6209}
6217 6210#endif /* WIRELESS_EXT < 18 */
6218 6211
6219static void ipw_ethtool_get_drvinfo(struct net_device *dev, 6212static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6220 struct ethtool_drvinfo *info) 6213 struct ethtool_drvinfo *info)
@@ -6236,14 +6229,13 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6236 6229
6237static u32 ipw2100_ethtool_get_link(struct net_device *dev) 6230static u32 ipw2100_ethtool_get_link(struct net_device *dev)
6238{ 6231{
6239 struct ipw2100_priv *priv = ieee80211_priv(dev); 6232 struct ipw2100_priv *priv = ieee80211_priv(dev);
6240 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0; 6233 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
6241} 6234}
6242 6235
6243
6244static struct ethtool_ops ipw2100_ethtool_ops = { 6236static struct ethtool_ops ipw2100_ethtool_ops = {
6245 .get_link = ipw2100_ethtool_get_link, 6237 .get_link = ipw2100_ethtool_get_link,
6246 .get_drvinfo = ipw_ethtool_get_drvinfo, 6238 .get_drvinfo = ipw_ethtool_get_drvinfo,
6247}; 6239};
6248 6240
6249static void ipw2100_hang_check(void *adapter) 6241static void ipw2100_hang_check(void *adapter)
@@ -6288,7 +6280,6 @@ static void ipw2100_hang_check(void *adapter)
6288 spin_unlock_irqrestore(&priv->low_lock, flags); 6280 spin_unlock_irqrestore(&priv->low_lock, flags);
6289} 6281}
6290 6282
6291
6292static void ipw2100_rf_kill(void *adapter) 6283static void ipw2100_rf_kill(void *adapter)
6293{ 6284{
6294 struct ipw2100_priv *priv = adapter; 6285 struct ipw2100_priv *priv = adapter;
@@ -6313,7 +6304,7 @@ static void ipw2100_rf_kill(void *adapter)
6313 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still " 6304 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
6314 "enabled\n"); 6305 "enabled\n");
6315 6306
6316 exit_unlock: 6307 exit_unlock:
6317 spin_unlock_irqrestore(&priv->low_lock, flags); 6308 spin_unlock_irqrestore(&priv->low_lock, flags);
6318} 6309}
6319 6310
@@ -6321,11 +6312,10 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
6321 6312
6322/* Look into using netdev destructor to shutdown ieee80211? */ 6313/* Look into using netdev destructor to shutdown ieee80211? */
6323 6314
6324static struct net_device *ipw2100_alloc_device( 6315static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6325 struct pci_dev *pci_dev, 6316 void __iomem * base_addr,
6326 void __iomem *base_addr, 6317 unsigned long mem_start,
6327 unsigned long mem_start, 6318 unsigned long mem_len)
6328 unsigned long mem_len)
6329{ 6319{
6330 struct ipw2100_priv *priv; 6320 struct ipw2100_priv *priv;
6331 struct net_device *dev; 6321 struct net_device *dev;
@@ -6341,17 +6331,22 @@ static struct net_device *ipw2100_alloc_device(
6341 priv->ieee->hard_start_xmit = ipw2100_tx; 6331 priv->ieee->hard_start_xmit = ipw2100_tx;
6342 priv->ieee->set_security = shim__set_security; 6332 priv->ieee->set_security = shim__set_security;
6343 6333
6334 priv->ieee->perfect_rssi = -20;
6335 priv->ieee->worst_rssi = -85;
6336
6344 dev->open = ipw2100_open; 6337 dev->open = ipw2100_open;
6345 dev->stop = ipw2100_close; 6338 dev->stop = ipw2100_close;
6346 dev->init = ipw2100_net_init; 6339 dev->init = ipw2100_net_init;
6340#if WIRELESS_EXT < 18
6347 dev->do_ioctl = ipw2100_ioctl; 6341 dev->do_ioctl = ipw2100_ioctl;
6342#endif
6348 dev->get_stats = ipw2100_stats; 6343 dev->get_stats = ipw2100_stats;
6349 dev->ethtool_ops = &ipw2100_ethtool_ops; 6344 dev->ethtool_ops = &ipw2100_ethtool_ops;
6350 dev->tx_timeout = ipw2100_tx_timeout; 6345 dev->tx_timeout = ipw2100_tx_timeout;
6351 dev->wireless_handlers = &ipw2100_wx_handler_def; 6346 dev->wireless_handlers = &ipw2100_wx_handler_def;
6352 dev->get_wireless_stats = ipw2100_wx_wireless_stats; 6347 dev->get_wireless_stats = ipw2100_wx_wireless_stats;
6353 dev->set_mac_address = ipw2100_set_address; 6348 dev->set_mac_address = ipw2100_set_address;
6354 dev->watchdog_timeo = 3*HZ; 6349 dev->watchdog_timeo = 3 * HZ;
6355 dev->irq = 0; 6350 dev->irq = 0;
6356 6351
6357 dev->base_addr = (unsigned long)base_addr; 6352 dev->base_addr = (unsigned long)base_addr;
@@ -6364,22 +6359,19 @@ static struct net_device *ipw2100_alloc_device(
6364 * ends up causing problems. So, we just handle 6359 * ends up causing problems. So, we just handle
6365 * the WX extensions through the ipw2100_ioctl interface */ 6360 * the WX extensions through the ipw2100_ioctl interface */
6366 6361
6367
6368 /* memset() puts everything to 0, so we only have explicitely set 6362 /* memset() puts everything to 0, so we only have explicitely set
6369 * those values that need to be something else */ 6363 * those values that need to be something else */
6370 6364
6371 /* If power management is turned on, default to AUTO mode */ 6365 /* If power management is turned on, default to AUTO mode */
6372 priv->power_mode = IPW_POWER_AUTO; 6366 priv->power_mode = IPW_POWER_AUTO;
6373 6367
6374 6368#ifdef CONFIG_IPW2100_MONITOR
6375 6369 priv->config |= CFG_CRC_CHECK;
6376#ifdef CONFIG_IEEE80211_WPA 6370#endif
6377 priv->ieee->wpa_enabled = 0; 6371 priv->ieee->wpa_enabled = 0;
6378 priv->ieee->tkip_countermeasures = 0;
6379 priv->ieee->drop_unencrypted = 0; 6372 priv->ieee->drop_unencrypted = 0;
6380 priv->ieee->privacy_invoked = 0; 6373 priv->ieee->privacy_invoked = 0;
6381 priv->ieee->ieee802_1x = 1; 6374 priv->ieee->ieee802_1x = 1;
6382#endif /* CONFIG_IEEE80211_WPA */
6383 6375
6384 /* Set module parameters */ 6376 /* Set module parameters */
6385 switch (mode) { 6377 switch (mode) {
@@ -6401,8 +6393,7 @@ static struct net_device *ipw2100_alloc_device(
6401 priv->status |= STATUS_RF_KILL_SW; 6393 priv->status |= STATUS_RF_KILL_SW;
6402 6394
6403 if (channel != 0 && 6395 if (channel != 0 &&
6404 ((channel >= REG_MIN_CHANNEL) && 6396 ((channel >= REG_MIN_CHANNEL) && (channel <= REG_MAX_CHANNEL))) {
6405 (channel <= REG_MAX_CHANNEL))) {
6406 priv->config |= CFG_STATIC_CHANNEL; 6397 priv->config |= CFG_STATIC_CHANNEL;
6407 priv->channel = channel; 6398 priv->channel = channel;
6408 } 6399 }
@@ -6441,12 +6432,8 @@ static struct net_device *ipw2100_alloc_device(
6441 INIT_LIST_HEAD(&priv->fw_pend_list); 6432 INIT_LIST_HEAD(&priv->fw_pend_list);
6442 INIT_STAT(&priv->fw_pend_stat); 6433 INIT_STAT(&priv->fw_pend_stat);
6443 6434
6444
6445#ifdef CONFIG_SOFTWARE_SUSPEND2
6446 priv->workqueue = create_workqueue(DRV_NAME, 0);
6447#else
6448 priv->workqueue = create_workqueue(DRV_NAME); 6435 priv->workqueue = create_workqueue(DRV_NAME);
6449#endif 6436
6450 INIT_WORK(&priv->reset_work, 6437 INIT_WORK(&priv->reset_work,
6451 (void (*)(void *))ipw2100_reset_adapter, priv); 6438 (void (*)(void *))ipw2100_reset_adapter, priv);
6452 INIT_WORK(&priv->security_work, 6439 INIT_WORK(&priv->security_work,
@@ -6535,7 +6522,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6535 return err; 6522 return err;
6536 } 6523 }
6537 6524
6538 /* We disable the RETRY_TIMEOUT register (0x41) to keep 6525 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6539 * PCI Tx retries from interfering with C3 CPU state */ 6526 * PCI Tx retries from interfering with C3 CPU state */
6540 pci_read_config_dword(pci_dev, 0x40, &val); 6527 pci_read_config_dword(pci_dev, 0x40, &val);
6541 if ((val & 0x0000ff00) != 0) 6528 if ((val & 0x0000ff00) != 0)
@@ -6566,12 +6553,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6566 ipw2100_queues_initialize(priv); 6553 ipw2100_queues_initialize(priv);
6567 6554
6568 err = request_irq(pci_dev->irq, 6555 err = request_irq(pci_dev->irq,
6569 ipw2100_interrupt, SA_SHIRQ, 6556 ipw2100_interrupt, SA_SHIRQ, dev->name, priv);
6570 dev->name, priv);
6571 if (err) { 6557 if (err) {
6572 printk(KERN_WARNING DRV_NAME 6558 printk(KERN_WARNING DRV_NAME
6573 "Error calling request_irq: %d.\n", 6559 "Error calling request_irq: %d.\n", pci_dev->irq);
6574 pci_dev->irq);
6575 goto fail; 6560 goto fail;
6576 } 6561 }
6577 dev->irq = pci_dev->irq; 6562 dev->irq = pci_dev->irq;
@@ -6606,7 +6591,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6606 6591
6607 /* perform this after register_netdev so that dev->name is set */ 6592 /* perform this after register_netdev so that dev->name is set */
6608 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6593 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6609 netif_carrier_off(dev);
6610 6594
6611 /* If the RF Kill switch is disabled, go ahead and complete the 6595 /* If the RF Kill switch is disabled, go ahead and complete the
6612 * startup sequence */ 6596 * startup sequence */
@@ -6634,10 +6618,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6634 6618
6635 return 0; 6619 return 0;
6636 6620
6637 fail_unlock: 6621 fail_unlock:
6638 up(&priv->action_sem); 6622 up(&priv->action_sem);
6639 6623
6640 fail: 6624 fail:
6641 if (dev) { 6625 if (dev) {
6642 if (registered) 6626 if (registered)
6643 unregister_netdev(dev); 6627 unregister_netdev(dev);
@@ -6653,7 +6637,8 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6653 6637
6654 /* These are safe to call even if they weren't allocated */ 6638 /* These are safe to call even if they weren't allocated */
6655 ipw2100_queues_free(priv); 6639 ipw2100_queues_free(priv);
6656 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6640 sysfs_remove_group(&pci_dev->dev.kobj,
6641 &ipw2100_attribute_group);
6657 6642
6658 free_ieee80211(dev); 6643 free_ieee80211(dev);
6659 pci_set_drvdata(pci_dev, NULL); 6644 pci_set_drvdata(pci_dev, NULL);
@@ -6679,7 +6664,8 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6679 priv->status &= ~STATUS_INITIALIZED; 6664 priv->status &= ~STATUS_INITIALIZED;
6680 6665
6681 dev = priv->net_dev; 6666 dev = priv->net_dev;
6682 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6667 sysfs_remove_group(&pci_dev->dev.kobj,
6668 &ipw2100_attribute_group);
6683 6669
6684#ifdef CONFIG_PM 6670#ifdef CONFIG_PM
6685 if (ipw2100_firmware.version) 6671 if (ipw2100_firmware.version)
@@ -6721,19 +6707,13 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6721 IPW_DEBUG_INFO("exit\n"); 6707 IPW_DEBUG_INFO("exit\n");
6722} 6708}
6723 6709
6724
6725#ifdef CONFIG_PM 6710#ifdef CONFIG_PM
6726#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
6727static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
6728#else
6729static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) 6711static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6730#endif
6731{ 6712{
6732 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); 6713 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6733 struct net_device *dev = priv->net_dev; 6714 struct net_device *dev = priv->net_dev;
6734 6715
6735 IPW_DEBUG_INFO("%s: Going into suspend...\n", 6716 IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name);
6736 dev->name);
6737 6717
6738 down(&priv->action_sem); 6718 down(&priv->action_sem);
6739 if (priv->status & STATUS_INITIALIZED) { 6719 if (priv->status & STATUS_INITIALIZED) {
@@ -6745,7 +6725,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6745 netif_device_detach(dev); 6725 netif_device_detach(dev);
6746 6726
6747 pci_save_state(pci_dev); 6727 pci_save_state(pci_dev);
6748 pci_disable_device (pci_dev); 6728 pci_disable_device(pci_dev);
6749 pci_set_power_state(pci_dev, PCI_D3hot); 6729 pci_set_power_state(pci_dev, PCI_D3hot);
6750 6730
6751 up(&priv->action_sem); 6731 up(&priv->action_sem);
@@ -6764,8 +6744,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6764 6744
6765 down(&priv->action_sem); 6745 down(&priv->action_sem);
6766 6746
6767 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", 6747 IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name);
6768 dev->name);
6769 6748
6770 pci_set_power_state(pci_dev, PCI_D0); 6749 pci_set_power_state(pci_dev, PCI_D0);
6771 pci_enable_device(pci_dev); 6750 pci_enable_device(pci_dev);
@@ -6785,9 +6764,9 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6785 * the queue of needed */ 6764 * the queue of needed */
6786 netif_device_attach(dev); 6765 netif_device_attach(dev);
6787 6766
6788 /* Bring the device back up */ 6767 /* Bring the device back up */
6789 if (!(priv->status & STATUS_RF_KILL_SW)) 6768 if (!(priv->status & STATUS_RF_KILL_SW))
6790 ipw2100_up(priv, 0); 6769 ipw2100_up(priv, 0);
6791 6770
6792 up(&priv->action_sem); 6771 up(&priv->action_sem);
6793 6772
@@ -6795,56 +6774,55 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6795} 6774}
6796#endif 6775#endif
6797 6776
6798
6799#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x } 6777#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
6800 6778
6801static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = { 6779static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
6802 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */ 6780 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
6803 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */ 6781 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
6804 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */ 6782 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
6805 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */ 6783 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
6806 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */ 6784 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
6807 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */ 6785 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */
6808 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */ 6786 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */
6809 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */ 6787 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */
6810 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */ 6788 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */
6811 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */ 6789 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */
6812 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */ 6790 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */
6813 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */ 6791 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */
6814 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */ 6792 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */
6815 6793
6816 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */ 6794 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */
6817 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */ 6795 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */
6818 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */ 6796 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */
6819 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */ 6797 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */
6820 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */ 6798 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */
6821 6799
6822 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */ 6800 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */
6823 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */ 6801 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */
6824 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */ 6802 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */
6825 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */ 6803 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */
6826 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */ 6804 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */
6827 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */ 6805 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */
6828 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */ 6806 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */
6829 6807
6830 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */ 6808 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */
6831 6809
6832 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */ 6810 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */
6833 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */ 6811 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */
6834 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */ 6812 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */
6835 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */ 6813 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */
6836 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */ 6814 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */
6837 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */ 6815 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */
6838 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */ 6816 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */
6839 6817
6840 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */ 6818 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */
6841 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */ 6819 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */
6842 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */ 6820 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */
6843 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */ 6821 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */
6844 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */ 6822 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */
6845 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */ 6823 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */
6846 6824
6847 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */ 6825 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
6848 {0,}, 6826 {0,},
6849}; 6827};
6850 6828
@@ -6861,7 +6839,6 @@ static struct pci_driver ipw2100_pci_driver = {
6861#endif 6839#endif
6862}; 6840};
6863 6841
6864
6865/** 6842/**
6866 * Initialize the ipw2100 driver/module 6843 * Initialize the ipw2100 driver/module
6867 * 6844 *
@@ -6878,10 +6855,6 @@ static int __init ipw2100_init(void)
6878 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); 6855 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
6879 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT); 6856 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
6880 6857
6881#ifdef CONFIG_IEEE80211_NOWEP
6882 IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
6883#endif
6884
6885 ret = pci_module_init(&ipw2100_pci_driver); 6858 ret = pci_module_init(&ipw2100_pci_driver);
6886 6859
6887#ifdef CONFIG_IPW_DEBUG 6860#ifdef CONFIG_IPW_DEBUG
@@ -6893,7 +6866,6 @@ static int __init ipw2100_init(void)
6893 return ret; 6866 return ret;
6894} 6867}
6895 6868
6896
6897/** 6869/**
6898 * Cleanup ipw2100 driver registration 6870 * Cleanup ipw2100 driver registration
6899 */ 6871 */
@@ -6949,7 +6921,6 @@ static int ipw2100_wx_get_name(struct net_device *dev,
6949 return 0; 6921 return 0;
6950} 6922}
6951 6923
6952
6953static int ipw2100_wx_set_freq(struct net_device *dev, 6924static int ipw2100_wx_set_freq(struct net_device *dev,
6954 struct iw_request_info *info, 6925 struct iw_request_info *info,
6955 union iwreq_data *wrqu, char *extra) 6926 union iwreq_data *wrqu, char *extra)
@@ -6969,8 +6940,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6969 6940
6970 /* if setting by freq convert to channel */ 6941 /* if setting by freq convert to channel */
6971 if (fwrq->e == 1) { 6942 if (fwrq->e == 1) {
6972 if ((fwrq->m >= (int) 2.412e8 && 6943 if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) {
6973 fwrq->m <= (int) 2.487e8)) {
6974 int f = fwrq->m / 100000; 6944 int f = fwrq->m / 100000;
6975 int c = 0; 6945 int c = 0;
6976 6946
@@ -6984,19 +6954,19 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6984 } 6954 }
6985 } 6955 }
6986 6956
6987 if (fwrq->e > 0 || fwrq->m > 1000) 6957 if (fwrq->e > 0 || fwrq->m > 1000) {
6988 return -EOPNOTSUPP; 6958 err = -EOPNOTSUPP;
6989 else { /* Set the channel */ 6959 goto done;
6960 } else { /* Set the channel */
6990 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 6961 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
6991 err = ipw2100_set_channel(priv, fwrq->m, 0); 6962 err = ipw2100_set_channel(priv, fwrq->m, 0);
6992 } 6963 }
6993 6964
6994 done: 6965 done:
6995 up(&priv->action_sem); 6966 up(&priv->action_sem);
6996 return err; 6967 return err;
6997} 6968}
6998 6969
6999
7000static int ipw2100_wx_get_freq(struct net_device *dev, 6970static int ipw2100_wx_get_freq(struct net_device *dev,
7001 struct iw_request_info *info, 6971 struct iw_request_info *info,
7002 union iwreq_data *wrqu, char *extra) 6972 union iwreq_data *wrqu, char *extra)
@@ -7045,7 +7015,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
7045 case IW_MODE_MONITOR: 7015 case IW_MODE_MONITOR:
7046 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR); 7016 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7047 break; 7017 break;
7048#endif /* CONFIG_IPW2100_MONITOR */ 7018#endif /* CONFIG_IPW2100_MONITOR */
7049 case IW_MODE_ADHOC: 7019 case IW_MODE_ADHOC:
7050 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC); 7020 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC);
7051 break; 7021 break;
@@ -7056,9 +7026,9 @@ static int ipw2100_wx_set_mode(struct net_device *dev,
7056 break; 7026 break;
7057 } 7027 }
7058 7028
7059done: 7029 done:
7060 up(&priv->action_sem); 7030 up(&priv->action_sem);
7061 return err; 7031 return err;
7062} 7032}
7063 7033
7064static int ipw2100_wx_get_mode(struct net_device *dev, 7034static int ipw2100_wx_get_mode(struct net_device *dev,
@@ -7077,7 +7047,6 @@ static int ipw2100_wx_get_mode(struct net_device *dev,
7077 return 0; 7047 return 0;
7078} 7048}
7079 7049
7080
7081#define POWER_MODES 5 7050#define POWER_MODES 5
7082 7051
7083/* Values are in microsecond */ 7052/* Values are in microsecond */
@@ -7124,19 +7093,19 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7124 /* ~5 Mb/s real (802.11b) */ 7093 /* ~5 Mb/s real (802.11b) */
7125 range->throughput = 5 * 1000 * 1000; 7094 range->throughput = 5 * 1000 * 1000;
7126 7095
7127// range->sensitivity; /* signal level threshold range */ 7096// range->sensitivity; /* signal level threshold range */
7128 7097
7129 range->max_qual.qual = 100; 7098 range->max_qual.qual = 100;
7130 /* TODO: Find real max RSSI and stick here */ 7099 /* TODO: Find real max RSSI and stick here */
7131 range->max_qual.level = 0; 7100 range->max_qual.level = 0;
7132 range->max_qual.noise = 0; 7101 range->max_qual.noise = 0;
7133 range->max_qual.updated = 7; /* Updated all three */ 7102 range->max_qual.updated = 7; /* Updated all three */
7134 7103
7135 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ 7104 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
7136 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ 7105 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
7137 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM; 7106 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
7138 range->avg_qual.noise = 0; 7107 range->avg_qual.noise = 0;
7139 range->avg_qual.updated = 7; /* Updated all three */ 7108 range->avg_qual.updated = 7; /* Updated all three */
7140 7109
7141 range->num_bitrates = RATE_COUNT; 7110 range->num_bitrates = RATE_COUNT;
7142 7111
@@ -7150,61 +7119,62 @@ static int ipw2100_wx_get_range(struct net_device *dev,
7150 range->max_frag = MAX_FRAG_THRESHOLD; 7119 range->max_frag = MAX_FRAG_THRESHOLD;
7151 7120
7152 range->min_pmp = period_duration[0]; /* Minimal PM period */ 7121 range->min_pmp = period_duration[0]; /* Minimal PM period */
7153 range->max_pmp = period_duration[POWER_MODES-1];/* Maximal PM period */ 7122 range->max_pmp = period_duration[POWER_MODES - 1]; /* Maximal PM period */
7154 range->min_pmt = timeout_duration[POWER_MODES-1]; /* Minimal PM timeout */ 7123 range->min_pmt = timeout_duration[POWER_MODES - 1]; /* Minimal PM timeout */
7155 range->max_pmt = timeout_duration[0];/* Maximal PM timeout */ 7124 range->max_pmt = timeout_duration[0]; /* Maximal PM timeout */
7156 7125
7157 /* How to decode max/min PM period */ 7126 /* How to decode max/min PM period */
7158 range->pmp_flags = IW_POWER_PERIOD; 7127 range->pmp_flags = IW_POWER_PERIOD;
7159 /* How to decode max/min PM period */ 7128 /* How to decode max/min PM period */
7160 range->pmt_flags = IW_POWER_TIMEOUT; 7129 range->pmt_flags = IW_POWER_TIMEOUT;
7161 /* What PM options are supported */ 7130 /* What PM options are supported */
7162 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD; 7131 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD;
7163 7132
7164 range->encoding_size[0] = 5; 7133 range->encoding_size[0] = 5;
7165 range->encoding_size[1] = 13; /* Different token sizes */ 7134 range->encoding_size[1] = 13; /* Different token sizes */
7166 range->num_encoding_sizes = 2; /* Number of entry in the list */ 7135 range->num_encoding_sizes = 2; /* Number of entry in the list */
7167 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */ 7136 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */
7168// range->encoding_login_index; /* token index for login token */ 7137// range->encoding_login_index; /* token index for login token */
7169 7138
7170 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 7139 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7171 range->txpower_capa = IW_TXPOW_DBM; 7140 range->txpower_capa = IW_TXPOW_DBM;
7172 range->num_txpower = IW_MAX_TXPOWER; 7141 range->num_txpower = IW_MAX_TXPOWER;
7173 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16); i < IW_MAX_TXPOWER; 7142 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16);
7174 i++, level -= ((IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM) * 16) / 7143 i < IW_MAX_TXPOWER;
7175 (IW_MAX_TXPOWER - 1)) 7144 i++, level -=
7145 ((IPW_TX_POWER_MAX_DBM -
7146 IPW_TX_POWER_MIN_DBM) * 16) / (IW_MAX_TXPOWER - 1))
7176 range->txpower[i] = level / 16; 7147 range->txpower[i] = level / 16;
7177 } else { 7148 } else {
7178 range->txpower_capa = 0; 7149 range->txpower_capa = 0;
7179 range->num_txpower = 0; 7150 range->num_txpower = 0;
7180 } 7151 }
7181 7152
7182
7183 /* Set the Wireless Extension versions */ 7153 /* Set the Wireless Extension versions */
7184 range->we_version_compiled = WIRELESS_EXT; 7154 range->we_version_compiled = WIRELESS_EXT;
7185 range->we_version_source = 16; 7155 range->we_version_source = 16;
7186 7156
7187// range->retry_capa; /* What retry options are supported */ 7157// range->retry_capa; /* What retry options are supported */
7188// range->retry_flags; /* How to decode max/min retry limit */ 7158// range->retry_flags; /* How to decode max/min retry limit */
7189// range->r_time_flags; /* How to decode max/min retry life */ 7159// range->r_time_flags; /* How to decode max/min retry life */
7190// range->min_retry; /* Minimal number of retries */ 7160// range->min_retry; /* Minimal number of retries */
7191// range->max_retry; /* Maximal number of retries */ 7161// range->max_retry; /* Maximal number of retries */
7192// range->min_r_time; /* Minimal retry lifetime */ 7162// range->min_r_time; /* Minimal retry lifetime */
7193// range->max_r_time; /* Maximal retry lifetime */ 7163// range->max_r_time; /* Maximal retry lifetime */
7194 7164
7195 range->num_channels = FREQ_COUNT; 7165 range->num_channels = FREQ_COUNT;
7196 7166
7197 val = 0; 7167 val = 0;
7198 for (i = 0; i < FREQ_COUNT; i++) { 7168 for (i = 0; i < FREQ_COUNT; i++) {
7199 // TODO: Include only legal frequencies for some countries 7169 // TODO: Include only legal frequencies for some countries
7200// if (local->channel_mask & (1 << i)) { 7170// if (local->channel_mask & (1 << i)) {
7201 range->freq[val].i = i + 1; 7171 range->freq[val].i = i + 1;
7202 range->freq[val].m = ipw2100_frequencies[i] * 100000; 7172 range->freq[val].m = ipw2100_frequencies[i] * 100000;
7203 range->freq[val].e = 1; 7173 range->freq[val].e = 1;
7204 val++; 7174 val++;
7205// } 7175// }
7206 if (val == IW_MAX_FREQUENCIES) 7176 if (val == IW_MAX_FREQUENCIES)
7207 break; 7177 break;
7208 } 7178 }
7209 range->num_frequency = val; 7179 range->num_frequency = val;
7210 7180
@@ -7259,7 +7229,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
7259 wrqu->ap_addr.sa_data[4] & 0xff, 7229 wrqu->ap_addr.sa_data[4] & 0xff,
7260 wrqu->ap_addr.sa_data[5] & 0xff); 7230 wrqu->ap_addr.sa_data[5] & 0xff);
7261 7231
7262 done: 7232 done:
7263 up(&priv->action_sem); 7233 up(&priv->action_sem);
7264 return err; 7234 return err;
7265} 7235}
@@ -7276,10 +7246,9 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
7276 7246
7277 /* If we are associated, trying to associate, or have a statically 7247 /* If we are associated, trying to associate, or have a statically
7278 * configured BSSID then return that; otherwise return ANY */ 7248 * configured BSSID then return that; otherwise return ANY */
7279 if (priv->config & CFG_STATIC_BSSID || 7249 if (priv->config & CFG_STATIC_BSSID || priv->status & STATUS_ASSOCIATED) {
7280 priv->status & STATUS_ASSOCIATED) {
7281 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 7250 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
7282 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); 7251 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
7283 } else 7252 } else
7284 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 7253 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
7285 7254
@@ -7293,7 +7262,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
7293 union iwreq_data *wrqu, char *extra) 7262 union iwreq_data *wrqu, char *extra)
7294{ 7263{
7295 struct ipw2100_priv *priv = ieee80211_priv(dev); 7264 struct ipw2100_priv *priv = ieee80211_priv(dev);
7296 char *essid = ""; /* ANY */ 7265 char *essid = ""; /* ANY */
7297 int length = 0; 7266 int length = 0;
7298 int err = 0; 7267 int err = 0;
7299 7268
@@ -7333,7 +7302,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev,
7333 7302
7334 err = ipw2100_set_essid(priv, essid, length, 0); 7303 err = ipw2100_set_essid(priv, essid, length, 0);
7335 7304
7336 done: 7305 done:
7337 up(&priv->action_sem); 7306 up(&priv->action_sem);
7338 return err; 7307 return err;
7339} 7308}
@@ -7350,17 +7319,16 @@ static int ipw2100_wx_get_essid(struct net_device *dev,
7350 7319
7351 /* If we are associated, trying to associate, or have a statically 7320 /* If we are associated, trying to associate, or have a statically
7352 * configured ESSID then return that; otherwise return ANY */ 7321 * configured ESSID then return that; otherwise return ANY */
7353 if (priv->config & CFG_STATIC_ESSID || 7322 if (priv->config & CFG_STATIC_ESSID || priv->status & STATUS_ASSOCIATED) {
7354 priv->status & STATUS_ASSOCIATED) {
7355 IPW_DEBUG_WX("Getting essid: '%s'\n", 7323 IPW_DEBUG_WX("Getting essid: '%s'\n",
7356 escape_essid(priv->essid, priv->essid_len)); 7324 escape_essid(priv->essid, priv->essid_len));
7357 memcpy(extra, priv->essid, priv->essid_len); 7325 memcpy(extra, priv->essid, priv->essid_len);
7358 wrqu->essid.length = priv->essid_len; 7326 wrqu->essid.length = priv->essid_len;
7359 wrqu->essid.flags = 1; /* active */ 7327 wrqu->essid.flags = 1; /* active */
7360 } else { 7328 } else {
7361 IPW_DEBUG_WX("Getting essid: ANY\n"); 7329 IPW_DEBUG_WX("Getting essid: ANY\n");
7362 wrqu->essid.length = 0; 7330 wrqu->essid.length = 0;
7363 wrqu->essid.flags = 0; /* active */ 7331 wrqu->essid.flags = 0; /* active */
7364 } 7332 }
7365 7333
7366 return 0; 7334 return 0;
@@ -7379,9 +7347,9 @@ static int ipw2100_wx_set_nick(struct net_device *dev,
7379 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 7347 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7380 return -E2BIG; 7348 return -E2BIG;
7381 7349
7382 wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick)); 7350 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
7383 memset(priv->nick, 0, sizeof(priv->nick)); 7351 memset(priv->nick, 0, sizeof(priv->nick));
7384 memcpy(priv->nick, extra, wrqu->data.length); 7352 memcpy(priv->nick, extra, wrqu->data.length);
7385 7353
7386 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick); 7354 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick);
7387 7355
@@ -7400,7 +7368,7 @@ static int ipw2100_wx_get_nick(struct net_device *dev,
7400 7368
7401 wrqu->data.length = strlen(priv->nick) + 1; 7369 wrqu->data.length = strlen(priv->nick) + 1;
7402 memcpy(extra, priv->nick, wrqu->data.length); 7370 memcpy(extra, priv->nick, wrqu->data.length);
7403 wrqu->data.flags = 1; /* active */ 7371 wrqu->data.flags = 1; /* active */
7404 7372
7405 IPW_DEBUG_WX("GET Nickname -> %s \n", extra); 7373 IPW_DEBUG_WX("GET Nickname -> %s \n", extra);
7406 7374
@@ -7442,12 +7410,11 @@ static int ipw2100_wx_set_rate(struct net_device *dev,
7442 err = ipw2100_set_tx_rates(priv, rate, 0); 7410 err = ipw2100_set_tx_rates(priv, rate, 0);
7443 7411
7444 IPW_DEBUG_WX("SET Rate -> %04X \n", rate); 7412 IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
7445 done: 7413 done:
7446 up(&priv->action_sem); 7414 up(&priv->action_sem);
7447 return err; 7415 return err;
7448} 7416}
7449 7417
7450
7451static int ipw2100_wx_get_rate(struct net_device *dev, 7418static int ipw2100_wx_get_rate(struct net_device *dev,
7452 struct iw_request_info *info, 7419 struct iw_request_info *info,
7453 union iwreq_data *wrqu, char *extra) 7420 union iwreq_data *wrqu, char *extra)
@@ -7495,7 +7462,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev,
7495 7462
7496 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 7463 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
7497 7464
7498 done: 7465 done:
7499 up(&priv->action_sem); 7466 up(&priv->action_sem);
7500 return err; 7467 return err;
7501} 7468}
@@ -7520,8 +7487,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7520 if (wrqu->rts.disabled) 7487 if (wrqu->rts.disabled)
7521 value = priv->rts_threshold | RTS_DISABLED; 7488 value = priv->rts_threshold | RTS_DISABLED;
7522 else { 7489 else {
7523 if (wrqu->rts.value < 1 || 7490 if (wrqu->rts.value < 1 || wrqu->rts.value > 2304) {
7524 wrqu->rts.value > 2304) {
7525 err = -EINVAL; 7491 err = -EINVAL;
7526 goto done; 7492 goto done;
7527 } 7493 }
@@ -7531,7 +7497,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev,
7531 err = ipw2100_set_rts_threshold(priv, value); 7497 err = ipw2100_set_rts_threshold(priv, value);
7532 7498
7533 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value); 7499 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
7534 done: 7500 done:
7535 up(&priv->action_sem); 7501 up(&priv->action_sem);
7536 return err; 7502 return err;
7537} 7503}
@@ -7547,7 +7513,7 @@ static int ipw2100_wx_get_rts(struct net_device *dev,
7547 struct ipw2100_priv *priv = ieee80211_priv(dev); 7513 struct ipw2100_priv *priv = ieee80211_priv(dev);
7548 7514
7549 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED; 7515 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
7550 wrqu->rts.fixed = 1; /* no auto select */ 7516 wrqu->rts.fixed = 1; /* no auto select */
7551 7517
7552 /* If RTS is set to the default value, then it is disabled */ 7518 /* If RTS is set to the default value, then it is disabled */
7553 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0; 7519 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
@@ -7574,8 +7540,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7574 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM) 7540 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM)
7575 return -EINVAL; 7541 return -EINVAL;
7576 7542
7577 value = (wrqu->txpower.value - IPW_TX_POWER_MIN_DBM) * 16 / 7543 value = wrqu->txpower.value;
7578 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
7579 } 7544 }
7580 7545
7581 down(&priv->action_sem); 7546 down(&priv->action_sem);
@@ -7588,7 +7553,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev,
7588 7553
7589 IPW_DEBUG_WX("SET TX Power -> %d \n", value); 7554 IPW_DEBUG_WX("SET TX Power -> %d \n", value);
7590 7555
7591 done: 7556 done:
7592 up(&priv->action_sem); 7557 up(&priv->action_sem);
7593 return err; 7558 return err;
7594} 7559}
@@ -7615,11 +7580,7 @@ static int ipw2100_wx_get_txpow(struct net_device *dev,
7615 } else { 7580 } else {
7616 wrqu->power.disabled = 0; 7581 wrqu->power.disabled = 0;
7617 wrqu->power.fixed = 1; 7582 wrqu->power.fixed = 1;
7618 wrqu->power.value = 7583 wrqu->power.value = priv->tx_power;
7619 (priv->tx_power *
7620 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM)) /
7621 (IPW_TX_POWER_MAX - IPW_TX_POWER_MIN) +
7622 IPW_TX_POWER_MIN_DBM;
7623 } 7584 }
7624 7585
7625 wrqu->power.flags = IW_TXPOW_DBM; 7586 wrqu->power.flags = IW_TXPOW_DBM;
@@ -7684,8 +7645,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7684 struct ipw2100_priv *priv = ieee80211_priv(dev); 7645 struct ipw2100_priv *priv = ieee80211_priv(dev);
7685 int err = 0; 7646 int err = 0;
7686 7647
7687 if (wrqu->retry.flags & IW_RETRY_LIFETIME || 7648 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
7688 wrqu->retry.disabled)
7689 return -EINVAL; 7649 return -EINVAL;
7690 7650
7691 if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) 7651 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
@@ -7700,14 +7660,14 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7700 if (wrqu->retry.flags & IW_RETRY_MIN) { 7660 if (wrqu->retry.flags & IW_RETRY_MIN) {
7701 err = ipw2100_set_short_retry(priv, wrqu->retry.value); 7661 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7702 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n", 7662 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
7703 wrqu->retry.value); 7663 wrqu->retry.value);
7704 goto done; 7664 goto done;
7705 } 7665 }
7706 7666
7707 if (wrqu->retry.flags & IW_RETRY_MAX) { 7667 if (wrqu->retry.flags & IW_RETRY_MAX) {
7708 err = ipw2100_set_long_retry(priv, wrqu->retry.value); 7668 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7709 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n", 7669 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
7710 wrqu->retry.value); 7670 wrqu->retry.value);
7711 goto done; 7671 goto done;
7712 } 7672 }
7713 7673
@@ -7717,7 +7677,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev,
7717 7677
7718 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value); 7678 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
7719 7679
7720 done: 7680 done:
7721 up(&priv->action_sem); 7681 up(&priv->action_sem);
7722 return err; 7682 return err;
7723} 7683}
@@ -7732,20 +7692,19 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
7732 7692
7733 struct ipw2100_priv *priv = ieee80211_priv(dev); 7693 struct ipw2100_priv *priv = ieee80211_priv(dev);
7734 7694
7735 wrqu->retry.disabled = 0; /* can't be disabled */ 7695 wrqu->retry.disabled = 0; /* can't be disabled */
7736 7696
7737 if ((wrqu->retry.flags & IW_RETRY_TYPE) == 7697 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME)
7738 IW_RETRY_LIFETIME)
7739 return -EINVAL; 7698 return -EINVAL;
7740 7699
7741 if (wrqu->retry.flags & IW_RETRY_MAX) { 7700 if (wrqu->retry.flags & IW_RETRY_MAX) {
7742 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; 7701 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
7743 wrqu->retry.value = priv->long_retry_limit; 7702 wrqu->retry.value = priv->long_retry_limit;
7744 } else { 7703 } else {
7745 wrqu->retry.flags = 7704 wrqu->retry.flags =
7746 (priv->short_retry_limit != 7705 (priv->short_retry_limit !=
7747 priv->long_retry_limit) ? 7706 priv->long_retry_limit) ?
7748 IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT; 7707 IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT;
7749 7708
7750 wrqu->retry.value = priv->short_retry_limit; 7709 wrqu->retry.value = priv->short_retry_limit;
7751 } 7710 }
@@ -7769,15 +7728,14 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
7769 } 7728 }
7770 7729
7771 IPW_DEBUG_WX("Initiating scan...\n"); 7730 IPW_DEBUG_WX("Initiating scan...\n");
7772 if (ipw2100_set_scan_options(priv) || 7731 if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
7773 ipw2100_start_scan(priv)) {
7774 IPW_DEBUG_WX("Start scan failed.\n"); 7732 IPW_DEBUG_WX("Start scan failed.\n");
7775 7733
7776 /* TODO: Mark a scan as pending so when hardware initialized 7734 /* TODO: Mark a scan as pending so when hardware initialized
7777 * a scan starts */ 7735 * a scan starts */
7778 } 7736 }
7779 7737
7780 done: 7738 done:
7781 up(&priv->action_sem); 7739 up(&priv->action_sem);
7782 return err; 7740 return err;
7783} 7741}
@@ -7794,7 +7752,6 @@ static int ipw2100_wx_get_scan(struct net_device *dev,
7794 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra); 7752 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
7795} 7753}
7796 7754
7797
7798/* 7755/*
7799 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c 7756 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c
7800 */ 7757 */
@@ -7823,8 +7780,8 @@ static int ipw2100_wx_get_encode(struct net_device *dev,
7823} 7780}
7824 7781
7825static int ipw2100_wx_set_power(struct net_device *dev, 7782static int ipw2100_wx_set_power(struct net_device *dev,
7826 struct iw_request_info *info, 7783 struct iw_request_info *info,
7827 union iwreq_data *wrqu, char *extra) 7784 union iwreq_data *wrqu, char *extra)
7828{ 7785{
7829 struct ipw2100_priv *priv = ieee80211_priv(dev); 7786 struct ipw2100_priv *priv = ieee80211_priv(dev);
7830 int err = 0; 7787 int err = 0;
@@ -7843,11 +7800,11 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7843 } 7800 }
7844 7801
7845 switch (wrqu->power.flags & IW_POWER_MODE) { 7802 switch (wrqu->power.flags & IW_POWER_MODE) {
7846 case IW_POWER_ON: /* If not specified */ 7803 case IW_POWER_ON: /* If not specified */
7847 case IW_POWER_MODE: /* If set all mask */ 7804 case IW_POWER_MODE: /* If set all mask */
7848 case IW_POWER_ALL_R: /* If explicitely state all */ 7805 case IW_POWER_ALL_R: /* If explicitely state all */
7849 break; 7806 break;
7850 default: /* Otherwise we don't support it */ 7807 default: /* Otherwise we don't support it */
7851 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 7808 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
7852 wrqu->power.flags); 7809 wrqu->power.flags);
7853 err = -EOPNOTSUPP; 7810 err = -EOPNOTSUPP;
@@ -7859,18 +7816,17 @@ static int ipw2100_wx_set_power(struct net_device *dev,
7859 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode; 7816 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
7860 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 7817 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
7861 7818
7862 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", 7819 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
7863 priv->power_mode);
7864 7820
7865 done: 7821 done:
7866 up(&priv->action_sem); 7822 up(&priv->action_sem);
7867 return err; 7823 return err;
7868 7824
7869} 7825}
7870 7826
7871static int ipw2100_wx_get_power(struct net_device *dev, 7827static int ipw2100_wx_get_power(struct net_device *dev,
7872 struct iw_request_info *info, 7828 struct iw_request_info *info,
7873 union iwreq_data *wrqu, char *extra) 7829 union iwreq_data *wrqu, char *extra)
7874{ 7830{
7875 /* 7831 /*
7876 * This can be called at any time. No action lock required 7832 * This can be called at any time. No action lock required
@@ -7878,9 +7834,9 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7878 7834
7879 struct ipw2100_priv *priv = ieee80211_priv(dev); 7835 struct ipw2100_priv *priv = ieee80211_priv(dev);
7880 7836
7881 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 7837 if (!(priv->power_mode & IPW_POWER_ENABLED))
7882 wrqu->power.disabled = 1; 7838 wrqu->power.disabled = 1;
7883 } else { 7839 else {
7884 wrqu->power.disabled = 0; 7840 wrqu->power.disabled = 0;
7885 wrqu->power.flags = 0; 7841 wrqu->power.flags = 0;
7886 } 7842 }
@@ -7890,6 +7846,269 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7890 return 0; 7846 return 0;
7891} 7847}
7892 7848
7849#if WIRELESS_EXT > 17
7850/*
7851 * WE-18 WPA support
7852 */
7853
7854/* SIOCSIWGENIE */
7855static int ipw2100_wx_set_genie(struct net_device *dev,
7856 struct iw_request_info *info,
7857 union iwreq_data *wrqu, char *extra)
7858{
7859
7860 struct ipw2100_priv *priv = ieee80211_priv(dev);
7861 struct ieee80211_device *ieee = priv->ieee;
7862 u8 *buf;
7863
7864 if (!ieee->wpa_enabled)
7865 return -EOPNOTSUPP;
7866
7867 if (wrqu->data.length > MAX_WPA_IE_LEN ||
7868 (wrqu->data.length && extra == NULL))
7869 return -EINVAL;
7870
7871 if (wrqu->data.length) {
7872 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
7873 if (buf == NULL)
7874 return -ENOMEM;
7875
7876 memcpy(buf, extra, wrqu->data.length);
7877 kfree(ieee->wpa_ie);
7878 ieee->wpa_ie = buf;
7879 ieee->wpa_ie_len = wrqu->data.length;
7880 } else {
7881 kfree(ieee->wpa_ie);
7882 ieee->wpa_ie = NULL;
7883 ieee->wpa_ie_len = 0;
7884 }
7885
7886 ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
7887
7888 return 0;
7889}
7890
7891/* SIOCGIWGENIE */
7892static int ipw2100_wx_get_genie(struct net_device *dev,
7893 struct iw_request_info *info,
7894 union iwreq_data *wrqu, char *extra)
7895{
7896 struct ipw2100_priv *priv = ieee80211_priv(dev);
7897 struct ieee80211_device *ieee = priv->ieee;
7898
7899 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
7900 wrqu->data.length = 0;
7901 return 0;
7902 }
7903
7904 if (wrqu->data.length < ieee->wpa_ie_len)
7905 return -E2BIG;
7906
7907 wrqu->data.length = ieee->wpa_ie_len;
7908 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
7909
7910 return 0;
7911}
7912
7913/* SIOCSIWAUTH */
7914static int ipw2100_wx_set_auth(struct net_device *dev,
7915 struct iw_request_info *info,
7916 union iwreq_data *wrqu, char *extra)
7917{
7918 struct ipw2100_priv *priv = ieee80211_priv(dev);
7919 struct ieee80211_device *ieee = priv->ieee;
7920 struct iw_param *param = &wrqu->param;
7921 struct ieee80211_crypt_data *crypt;
7922 unsigned long flags;
7923 int ret = 0;
7924
7925 switch (param->flags & IW_AUTH_INDEX) {
7926 case IW_AUTH_WPA_VERSION:
7927 case IW_AUTH_CIPHER_PAIRWISE:
7928 case IW_AUTH_CIPHER_GROUP:
7929 case IW_AUTH_KEY_MGMT:
7930 /*
7931 * ipw2200 does not use these parameters
7932 */
7933 break;
7934
7935 case IW_AUTH_TKIP_COUNTERMEASURES:
7936 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
7937 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
7938 break;
7939
7940 flags = crypt->ops->get_flags(crypt->priv);
7941
7942 if (param->value)
7943 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7944 else
7945 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7946
7947 crypt->ops->set_flags(flags, crypt->priv);
7948
7949 break;
7950
7951 case IW_AUTH_DROP_UNENCRYPTED:{
7952 /* HACK:
7953 *
7954 * wpa_supplicant calls set_wpa_enabled when the driver
7955 * is loaded and unloaded, regardless of if WPA is being
7956 * used. No other calls are made which can be used to
7957 * determine if encryption will be used or not prior to
7958 * association being expected. If encryption is not being
7959 * used, drop_unencrypted is set to false, else true -- we
7960 * can use this to determine if the CAP_PRIVACY_ON bit should
7961 * be set.
7962 */
7963 struct ieee80211_security sec = {
7964 .flags = SEC_ENABLED,
7965 .enabled = param->value,
7966 };
7967 priv->ieee->drop_unencrypted = param->value;
7968 /* We only change SEC_LEVEL for open mode. Others
7969 * are set by ipw_wpa_set_encryption.
7970 */
7971 if (!param->value) {
7972 sec.flags |= SEC_LEVEL;
7973 sec.level = SEC_LEVEL_0;
7974 } else {
7975 sec.flags |= SEC_LEVEL;
7976 sec.level = SEC_LEVEL_1;
7977 }
7978 if (priv->ieee->set_security)
7979 priv->ieee->set_security(priv->ieee->dev, &sec);
7980 break;
7981 }
7982
7983 case IW_AUTH_80211_AUTH_ALG:
7984 ret = ipw2100_wpa_set_auth_algs(priv, param->value);
7985 break;
7986
7987 case IW_AUTH_WPA_ENABLED:
7988 ret = ipw2100_wpa_enable(priv, param->value);
7989 break;
7990
7991 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
7992 ieee->ieee802_1x = param->value;
7993 break;
7994
7995 //case IW_AUTH_ROAMING_CONTROL:
7996 case IW_AUTH_PRIVACY_INVOKED:
7997 ieee->privacy_invoked = param->value;
7998 break;
7999
8000 default:
8001 return -EOPNOTSUPP;
8002 }
8003 return ret;
8004}
8005
8006/* SIOCGIWAUTH */
8007static int ipw2100_wx_get_auth(struct net_device *dev,
8008 struct iw_request_info *info,
8009 union iwreq_data *wrqu, char *extra)
8010{
8011 struct ipw2100_priv *priv = ieee80211_priv(dev);
8012 struct ieee80211_device *ieee = priv->ieee;
8013 struct ieee80211_crypt_data *crypt;
8014 struct iw_param *param = &wrqu->param;
8015 int ret = 0;
8016
8017 switch (param->flags & IW_AUTH_INDEX) {
8018 case IW_AUTH_WPA_VERSION:
8019 case IW_AUTH_CIPHER_PAIRWISE:
8020 case IW_AUTH_CIPHER_GROUP:
8021 case IW_AUTH_KEY_MGMT:
8022 /*
8023 * wpa_supplicant will control these internally
8024 */
8025 ret = -EOPNOTSUPP;
8026 break;
8027
8028 case IW_AUTH_TKIP_COUNTERMEASURES:
8029 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
8030 if (!crypt || !crypt->ops->get_flags) {
8031 IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
8032 "crypt not set!\n");
8033 break;
8034 }
8035
8036 param->value = (crypt->ops->get_flags(crypt->priv) &
8037 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
8038
8039 break;
8040
8041 case IW_AUTH_DROP_UNENCRYPTED:
8042 param->value = ieee->drop_unencrypted;
8043 break;
8044
8045 case IW_AUTH_80211_AUTH_ALG:
8046 param->value = priv->ieee->sec.auth_mode;
8047 break;
8048
8049 case IW_AUTH_WPA_ENABLED:
8050 param->value = ieee->wpa_enabled;
8051 break;
8052
8053 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
8054 param->value = ieee->ieee802_1x;
8055 break;
8056
8057 case IW_AUTH_ROAMING_CONTROL:
8058 case IW_AUTH_PRIVACY_INVOKED:
8059 param->value = ieee->privacy_invoked;
8060 break;
8061
8062 default:
8063 return -EOPNOTSUPP;
8064 }
8065 return 0;
8066}
8067
8068/* SIOCSIWENCODEEXT */
8069static int ipw2100_wx_set_encodeext(struct net_device *dev,
8070 struct iw_request_info *info,
8071 union iwreq_data *wrqu, char *extra)
8072{
8073 struct ipw2100_priv *priv = ieee80211_priv(dev);
8074 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
8075}
8076
8077/* SIOCGIWENCODEEXT */
8078static int ipw2100_wx_get_encodeext(struct net_device *dev,
8079 struct iw_request_info *info,
8080 union iwreq_data *wrqu, char *extra)
8081{
8082 struct ipw2100_priv *priv = ieee80211_priv(dev);
8083 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
8084}
8085
8086/* SIOCSIWMLME */
8087static int ipw2100_wx_set_mlme(struct net_device *dev,
8088 struct iw_request_info *info,
8089 union iwreq_data *wrqu, char *extra)
8090{
8091 struct ipw2100_priv *priv = ieee80211_priv(dev);
8092 struct iw_mlme *mlme = (struct iw_mlme *)extra;
8093 u16 reason;
8094
8095 reason = cpu_to_le16(mlme->reason_code);
8096
8097 switch (mlme->cmd) {
8098 case IW_MLME_DEAUTH:
8099 // silently ignore
8100 break;
8101
8102 case IW_MLME_DISASSOC:
8103 ipw2100_disassociate_bssid(priv);
8104 break;
8105
8106 default:
8107 return -EOPNOTSUPP;
8108 }
8109 return 0;
8110}
8111#endif /* WIRELESS_EXT > 17 */
7893 8112
7894/* 8113/*
7895 * 8114 *
@@ -7923,7 +8142,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev,
7923 if (priv->ieee->iw_mode == IW_MODE_MONITOR) 8142 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
7924 err = ipw2100_switch_mode(priv, priv->last_mode); 8143 err = ipw2100_switch_mode(priv, priv->last_mode);
7925 } 8144 }
7926 done: 8145 done:
7927 up(&priv->action_sem); 8146 up(&priv->action_sem);
7928 return err; 8147 return err;
7929} 8148}
@@ -7958,7 +8177,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
7958 8177
7959 if (priv->power_mode != mode) 8178 if (priv->power_mode != mode)
7960 err = ipw2100_set_power_mode(priv, mode); 8179 err = ipw2100_set_power_mode(priv, mode);
7961 done: 8180 done:
7962 up(&priv->action_sem); 8181 up(&priv->action_sem);
7963 return err; 8182 return err;
7964} 8183}
@@ -7986,8 +8205,8 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
7986 "Power save level: %d (None)", level); 8205 "Power save level: %d (None)", level);
7987 break; 8206 break;
7988 case IPW_POWER_AUTO: 8207 case IPW_POWER_AUTO:
7989 snprintf(extra, MAX_POWER_STRING, 8208 snprintf(extra, MAX_POWER_STRING,
7990 "Power save level: %d (Auto)", 0); 8209 "Power save level: %d (Auto)", 0);
7991 break; 8210 break;
7992 default: 8211 default:
7993 timeout = timeout_duration[level - 1] / 1000; 8212 timeout = timeout_duration[level - 1] / 1000;
@@ -8004,7 +8223,6 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
8004 return 0; 8223 return 0;
8005} 8224}
8006 8225
8007
8008static int ipw2100_wx_set_preamble(struct net_device *dev, 8226static int ipw2100_wx_set_preamble(struct net_device *dev,
8009 struct iw_request_info *info, 8227 struct iw_request_info *info,
8010 union iwreq_data *wrqu, char *extra) 8228 union iwreq_data *wrqu, char *extra)
@@ -8029,14 +8247,14 @@ static int ipw2100_wx_set_preamble(struct net_device *dev,
8029 8247
8030 err = ipw2100_system_config(priv, 0); 8248 err = ipw2100_system_config(priv, 0);
8031 8249
8032done: 8250 done:
8033 up(&priv->action_sem); 8251 up(&priv->action_sem);
8034 return err; 8252 return err;
8035} 8253}
8036 8254
8037static int ipw2100_wx_get_preamble(struct net_device *dev, 8255static int ipw2100_wx_get_preamble(struct net_device *dev,
8038 struct iw_request_info *info, 8256 struct iw_request_info *info,
8039 union iwreq_data *wrqu, char *extra) 8257 union iwreq_data *wrqu, char *extra)
8040{ 8258{
8041 /* 8259 /*
8042 * This can be called at any time. No action lock required 8260 * This can be called at any time. No action lock required
@@ -8052,54 +8270,116 @@ static int ipw2100_wx_get_preamble(struct net_device *dev,
8052 return 0; 8270 return 0;
8053} 8271}
8054 8272
8055static iw_handler ipw2100_wx_handlers[] = 8273#ifdef CONFIG_IPW2100_MONITOR
8056{ 8274static int ipw2100_wx_set_crc_check(struct net_device *dev,
8057 NULL, /* SIOCSIWCOMMIT */ 8275 struct iw_request_info *info,
8058 ipw2100_wx_get_name, /* SIOCGIWNAME */ 8276 union iwreq_data *wrqu, char *extra)
8059 NULL, /* SIOCSIWNWID */ 8277{
8060 NULL, /* SIOCGIWNWID */ 8278 struct ipw2100_priv *priv = ieee80211_priv(dev);
8061 ipw2100_wx_set_freq, /* SIOCSIWFREQ */ 8279 int err, mode = *(int *)extra;
8062 ipw2100_wx_get_freq, /* SIOCGIWFREQ */ 8280
8063 ipw2100_wx_set_mode, /* SIOCSIWMODE */ 8281 down(&priv->action_sem);
8064 ipw2100_wx_get_mode, /* SIOCGIWMODE */ 8282 if (!(priv->status & STATUS_INITIALIZED)) {
8065 NULL, /* SIOCSIWSENS */ 8283 err = -EIO;
8066 NULL, /* SIOCGIWSENS */ 8284 goto done;
8067 NULL, /* SIOCSIWRANGE */ 8285 }
8068 ipw2100_wx_get_range, /* SIOCGIWRANGE */ 8286
8069 NULL, /* SIOCSIWPRIV */ 8287 if (mode == 1)
8070 NULL, /* SIOCGIWPRIV */ 8288 priv->config |= CFG_CRC_CHECK;
8071 NULL, /* SIOCSIWSTATS */ 8289 else if (mode == 0)
8072 NULL, /* SIOCGIWSTATS */ 8290 priv->config &= ~CFG_CRC_CHECK;
8073 NULL, /* SIOCSIWSPY */ 8291 else {
8074 NULL, /* SIOCGIWSPY */ 8292 err = -EINVAL;
8075 NULL, /* SIOCGIWTHRSPY */ 8293 goto done;
8076 NULL, /* SIOCWIWTHRSPY */ 8294 }
8077 ipw2100_wx_set_wap, /* SIOCSIWAP */ 8295 err = 0;
8078 ipw2100_wx_get_wap, /* SIOCGIWAP */ 8296
8079 NULL, /* -- hole -- */ 8297 done:
8080 NULL, /* SIOCGIWAPLIST -- deprecated */ 8298 up(&priv->action_sem);
8081 ipw2100_wx_set_scan, /* SIOCSIWSCAN */ 8299 return err;
8082 ipw2100_wx_get_scan, /* SIOCGIWSCAN */ 8300}
8083 ipw2100_wx_set_essid, /* SIOCSIWESSID */ 8301
8084 ipw2100_wx_get_essid, /* SIOCGIWESSID */ 8302static int ipw2100_wx_get_crc_check(struct net_device *dev,
8085 ipw2100_wx_set_nick, /* SIOCSIWNICKN */ 8303 struct iw_request_info *info,
8086 ipw2100_wx_get_nick, /* SIOCGIWNICKN */ 8304 union iwreq_data *wrqu, char *extra)
8087 NULL, /* -- hole -- */ 8305{
8088 NULL, /* -- hole -- */ 8306 /*
8089 ipw2100_wx_set_rate, /* SIOCSIWRATE */ 8307 * This can be called at any time. No action lock required
8090 ipw2100_wx_get_rate, /* SIOCGIWRATE */ 8308 */
8091 ipw2100_wx_set_rts, /* SIOCSIWRTS */ 8309
8092 ipw2100_wx_get_rts, /* SIOCGIWRTS */ 8310 struct ipw2100_priv *priv = ieee80211_priv(dev);
8093 ipw2100_wx_set_frag, /* SIOCSIWFRAG */ 8311
8094 ipw2100_wx_get_frag, /* SIOCGIWFRAG */ 8312 if (priv->config & CFG_CRC_CHECK)
8095 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */ 8313 snprintf(wrqu->name, IFNAMSIZ, "CRC checked (1)");
8096 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */ 8314 else
8097 ipw2100_wx_set_retry, /* SIOCSIWRETRY */ 8315 snprintf(wrqu->name, IFNAMSIZ, "CRC ignored (0)");
8098 ipw2100_wx_get_retry, /* SIOCGIWRETRY */ 8316
8099 ipw2100_wx_set_encode, /* SIOCSIWENCODE */ 8317 return 0;
8100 ipw2100_wx_get_encode, /* SIOCGIWENCODE */ 8318}
8101 ipw2100_wx_set_power, /* SIOCSIWPOWER */ 8319#endif /* CONFIG_IPW2100_MONITOR */
8102 ipw2100_wx_get_power, /* SIOCGIWPOWER */ 8320
8321static iw_handler ipw2100_wx_handlers[] = {
8322 NULL, /* SIOCSIWCOMMIT */
8323 ipw2100_wx_get_name, /* SIOCGIWNAME */
8324 NULL, /* SIOCSIWNWID */
8325 NULL, /* SIOCGIWNWID */
8326 ipw2100_wx_set_freq, /* SIOCSIWFREQ */
8327 ipw2100_wx_get_freq, /* SIOCGIWFREQ */
8328 ipw2100_wx_set_mode, /* SIOCSIWMODE */
8329 ipw2100_wx_get_mode, /* SIOCGIWMODE */
8330 NULL, /* SIOCSIWSENS */
8331 NULL, /* SIOCGIWSENS */
8332 NULL, /* SIOCSIWRANGE */
8333 ipw2100_wx_get_range, /* SIOCGIWRANGE */
8334 NULL, /* SIOCSIWPRIV */
8335 NULL, /* SIOCGIWPRIV */
8336 NULL, /* SIOCSIWSTATS */
8337 NULL, /* SIOCGIWSTATS */
8338 NULL, /* SIOCSIWSPY */
8339 NULL, /* SIOCGIWSPY */
8340 NULL, /* SIOCGIWTHRSPY */
8341 NULL, /* SIOCWIWTHRSPY */
8342 ipw2100_wx_set_wap, /* SIOCSIWAP */
8343 ipw2100_wx_get_wap, /* SIOCGIWAP */
8344#if WIRELESS_EXT > 17
8345 ipw2100_wx_set_mlme, /* SIOCSIWMLME */
8346#else
8347 NULL, /* -- hole -- */
8348#endif
8349 NULL, /* SIOCGIWAPLIST -- deprecated */
8350 ipw2100_wx_set_scan, /* SIOCSIWSCAN */
8351 ipw2100_wx_get_scan, /* SIOCGIWSCAN */
8352 ipw2100_wx_set_essid, /* SIOCSIWESSID */
8353 ipw2100_wx_get_essid, /* SIOCGIWESSID */
8354 ipw2100_wx_set_nick, /* SIOCSIWNICKN */
8355 ipw2100_wx_get_nick, /* SIOCGIWNICKN */
8356 NULL, /* -- hole -- */
8357 NULL, /* -- hole -- */
8358 ipw2100_wx_set_rate, /* SIOCSIWRATE */
8359 ipw2100_wx_get_rate, /* SIOCGIWRATE */
8360 ipw2100_wx_set_rts, /* SIOCSIWRTS */
8361 ipw2100_wx_get_rts, /* SIOCGIWRTS */
8362 ipw2100_wx_set_frag, /* SIOCSIWFRAG */
8363 ipw2100_wx_get_frag, /* SIOCGIWFRAG */
8364 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
8365 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
8366 ipw2100_wx_set_retry, /* SIOCSIWRETRY */
8367 ipw2100_wx_get_retry, /* SIOCGIWRETRY */
8368 ipw2100_wx_set_encode, /* SIOCSIWENCODE */
8369 ipw2100_wx_get_encode, /* SIOCGIWENCODE */
8370 ipw2100_wx_set_power, /* SIOCSIWPOWER */
8371 ipw2100_wx_get_power, /* SIOCGIWPOWER */
8372#if WIRELESS_EXT > 17
8373 NULL, /* -- hole -- */
8374 NULL, /* -- hole -- */
8375 ipw2100_wx_set_genie, /* SIOCSIWGENIE */
8376 ipw2100_wx_get_genie, /* SIOCGIWGENIE */
8377 ipw2100_wx_set_auth, /* SIOCSIWAUTH */
8378 ipw2100_wx_get_auth, /* SIOCGIWAUTH */
8379 ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */
8380 ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */
8381 NULL, /* SIOCSIWPMKSA */
8382#endif
8103}; 8383};
8104 8384
8105#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV 8385#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
@@ -8108,60 +8388,71 @@ static iw_handler ipw2100_wx_handlers[] =
8108#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3 8388#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3
8109#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4 8389#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4
8110#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5 8390#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5
8391#define IPW2100_PRIV_SET_CRC_CHECK SIOCIWFIRSTPRIV+6
8392#define IPW2100_PRIV_GET_CRC_CHECK SIOCIWFIRSTPRIV+7
8111 8393
8112static const struct iw_priv_args ipw2100_private_args[] = { 8394static const struct iw_priv_args ipw2100_private_args[] = {
8113 8395
8114#ifdef CONFIG_IPW2100_MONITOR 8396#ifdef CONFIG_IPW2100_MONITOR
8115 { 8397 {
8116 IPW2100_PRIV_SET_MONITOR, 8398 IPW2100_PRIV_SET_MONITOR,
8117 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor" 8399 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
8118 },
8119 { 8400 {
8120 IPW2100_PRIV_RESET, 8401 IPW2100_PRIV_RESET,
8121 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset" 8402 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
8122 }, 8403#endif /* CONFIG_IPW2100_MONITOR */
8123#endif /* CONFIG_IPW2100_MONITOR */
8124 8404
8125 { 8405 {
8126 IPW2100_PRIV_SET_POWER, 8406 IPW2100_PRIV_SET_POWER,
8127 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power" 8407 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power"},
8128 },
8129 { 8408 {
8130 IPW2100_PRIV_GET_POWER, 8409 IPW2100_PRIV_GET_POWER,
8131 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING, "get_power" 8410 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING,
8132 }, 8411 "get_power"},
8133 { 8412 {
8134 IPW2100_PRIV_SET_LONGPREAMBLE, 8413 IPW2100_PRIV_SET_LONGPREAMBLE,
8135 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble" 8414 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
8136 },
8137 { 8415 {
8138 IPW2100_PRIV_GET_LONGPREAMBLE, 8416 IPW2100_PRIV_GET_LONGPREAMBLE,
8139 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble" 8417 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"},
8140 }, 8418#ifdef CONFIG_IPW2100_MONITOR
8419 {
8420 IPW2100_PRIV_SET_CRC_CHECK,
8421 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_crc_check"},
8422 {
8423 IPW2100_PRIV_GET_CRC_CHECK,
8424 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_crc_check"},
8425#endif /* CONFIG_IPW2100_MONITOR */
8141}; 8426};
8142 8427
8143static iw_handler ipw2100_private_handler[] = { 8428static iw_handler ipw2100_private_handler[] = {
8144#ifdef CONFIG_IPW2100_MONITOR 8429#ifdef CONFIG_IPW2100_MONITOR
8145 ipw2100_wx_set_promisc, 8430 ipw2100_wx_set_promisc,
8146 ipw2100_wx_reset, 8431 ipw2100_wx_reset,
8147#else /* CONFIG_IPW2100_MONITOR */ 8432#else /* CONFIG_IPW2100_MONITOR */
8148 NULL, 8433 NULL,
8149 NULL, 8434 NULL,
8150#endif /* CONFIG_IPW2100_MONITOR */ 8435#endif /* CONFIG_IPW2100_MONITOR */
8151 ipw2100_wx_set_powermode, 8436 ipw2100_wx_set_powermode,
8152 ipw2100_wx_get_powermode, 8437 ipw2100_wx_get_powermode,
8153 ipw2100_wx_set_preamble, 8438 ipw2100_wx_set_preamble,
8154 ipw2100_wx_get_preamble, 8439 ipw2100_wx_get_preamble,
8440#ifdef CONFIG_IPW2100_MONITOR
8441 ipw2100_wx_set_crc_check,
8442 ipw2100_wx_get_crc_check,
8443#else /* CONFIG_IPW2100_MONITOR */
8444 NULL,
8445 NULL,
8446#endif /* CONFIG_IPW2100_MONITOR */
8155}; 8447};
8156 8448
8157static struct iw_handler_def ipw2100_wx_handler_def = 8449static struct iw_handler_def ipw2100_wx_handler_def = {
8158{
8159 .standard = ipw2100_wx_handlers, 8450 .standard = ipw2100_wx_handlers,
8160 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler), 8451 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
8161 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler), 8452 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
8162 .num_private_args = sizeof(ipw2100_private_args) / 8453 .num_private_args = sizeof(ipw2100_private_args) /
8163 sizeof(struct iw_priv_args), 8454 sizeof(struct iw_priv_args),
8164 .private = (iw_handler *)ipw2100_private_handler, 8455 .private = (iw_handler *) ipw2100_private_handler,
8165 .private_args = (struct iw_priv_args *)ipw2100_private_args, 8456 .private_args = (struct iw_priv_args *)ipw2100_private_args,
8166}; 8457};
8167 8458
@@ -8170,7 +8461,7 @@ static struct iw_handler_def ipw2100_wx_handler_def =
8170 * Called by /proc/net/wireless 8461 * Called by /proc/net/wireless
8171 * Also called by SIOCGIWSTATS 8462 * Also called by SIOCGIWSTATS
8172 */ 8463 */
8173static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev) 8464static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
8174{ 8465{
8175 enum { 8466 enum {
8176 POOR = 30, 8467 POOR = 30,
@@ -8190,7 +8481,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8190 u32 ord_len = sizeof(u32); 8481 u32 ord_len = sizeof(u32);
8191 8482
8192 if (!priv) 8483 if (!priv)
8193 return (struct iw_statistics *) NULL; 8484 return (struct iw_statistics *)NULL;
8194 8485
8195 wstats = &priv->wstats; 8486 wstats = &priv->wstats;
8196 8487
@@ -8207,7 +8498,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8207 wstats->qual.noise = 0; 8498 wstats->qual.noise = 0;
8208 wstats->qual.updated = 7; 8499 wstats->qual.updated = 7;
8209 wstats->qual.updated |= IW_QUAL_NOISE_INVALID | 8500 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
8210 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; 8501 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
8211 return wstats; 8502 return wstats;
8212 } 8503 }
8213 8504
@@ -8215,7 +8506,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8215 &missed_beacons, &ord_len)) 8506 &missed_beacons, &ord_len))
8216 goto fail_get_ordinal; 8507 goto fail_get_ordinal;
8217 8508
8218 /* If we don't have a connection the quality and level is 0*/ 8509 /* If we don't have a connection the quality and level is 0 */
8219 if (!(priv->status & STATUS_ASSOCIATED)) { 8510 if (!(priv->status & STATUS_ASSOCIATED)) {
8220 wstats->qual.qual = 0; 8511 wstats->qual.qual = 0;
8221 wstats->qual.level = 0; 8512 wstats->qual.level = 0;
@@ -8232,10 +8523,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8232 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR; 8523 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR;
8233 else if (rssi < 30) 8524 else if (rssi < 30)
8234 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) / 8525 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) /
8235 10 + GOOD; 8526 10 + GOOD;
8236 else 8527 else
8237 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) / 8528 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) /
8238 10 + VERY_GOOD; 8529 10 + VERY_GOOD;
8239 8530
8240 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES, 8531 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES,
8241 &tx_retries, &ord_len)) 8532 &tx_retries, &ord_len))
@@ -8249,25 +8540,25 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8249 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR; 8540 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
8250 else if (tx_retries > 50) 8541 else if (tx_retries > 50)
8251 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) / 8542 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
8252 15 + GOOD; 8543 15 + GOOD;
8253 else 8544 else
8254 tx_qual = (50 - tx_retries) * 8545 tx_qual = (50 - tx_retries) *
8255 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD; 8546 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
8256 8547
8257 if (missed_beacons > 50) 8548 if (missed_beacons > 50)
8258 beacon_qual = (60 - missed_beacons) * POOR / 10; 8549 beacon_qual = (60 - missed_beacons) * POOR / 10;
8259 else if (missed_beacons > 40) 8550 else if (missed_beacons > 40)
8260 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) / 8551 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) /
8261 10 + POOR; 8552 10 + POOR;
8262 else if (missed_beacons > 32) 8553 else if (missed_beacons > 32)
8263 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) / 8554 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) /
8264 18 + FAIR; 8555 18 + FAIR;
8265 else if (missed_beacons > 20) 8556 else if (missed_beacons > 20)
8266 beacon_qual = (32 - missed_beacons) * 8557 beacon_qual = (32 - missed_beacons) *
8267 (VERY_GOOD - GOOD) / 20 + GOOD; 8558 (VERY_GOOD - GOOD) / 20 + GOOD;
8268 else 8559 else
8269 beacon_qual = (20 - missed_beacons) * 8560 beacon_qual = (20 - missed_beacons) *
8270 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD; 8561 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
8271 8562
8272 quality = min(beacon_qual, min(tx_qual, rssi_qual)); 8563 quality = min(beacon_qual, min(tx_qual, rssi_qual));
8273 8564
@@ -8290,7 +8581,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8290 wstats->qual.updated = 7; 8581 wstats->qual.updated = 7;
8291 wstats->qual.updated |= IW_QUAL_NOISE_INVALID; 8582 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
8292 8583
8293 /* FIXME: this is percent and not a # */ 8584 /* FIXME: this is percent and not a # */
8294 wstats->miss.beacon = missed_beacons; 8585 wstats->miss.beacon = missed_beacons;
8295 8586
8296 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES, 8587 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES,
@@ -8300,10 +8591,10 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
8300 8591
8301 return wstats; 8592 return wstats;
8302 8593
8303 fail_get_ordinal: 8594 fail_get_ordinal:
8304 IPW_DEBUG_WX("failed querying ordinals.\n"); 8595 IPW_DEBUG_WX("failed querying ordinals.\n");
8305 8596
8306 return (struct iw_statistics *) NULL; 8597 return (struct iw_statistics *)NULL;
8307} 8598}
8308 8599
8309static void ipw2100_wx_event_work(struct ipw2100_priv *priv) 8600static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
@@ -8326,23 +8617,17 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8326 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) || 8617 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) ||
8327 priv->status & STATUS_RF_KILL_MASK || 8618 priv->status & STATUS_RF_KILL_MASK ||
8328 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, 8619 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
8329 &priv->bssid, &len)) { 8620 &priv->bssid, &len)) {
8330 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 8621 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
8331 } else { 8622 } else {
8332 /* We now have the BSSID, so can finish setting to the full 8623 /* We now have the BSSID, so can finish setting to the full
8333 * associated state */ 8624 * associated state */
8334 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN); 8625 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
8335 memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN); 8626 memcpy(priv->ieee->bssid, priv->bssid, ETH_ALEN);
8336 priv->status &= ~STATUS_ASSOCIATING; 8627 priv->status &= ~STATUS_ASSOCIATING;
8337 priv->status |= STATUS_ASSOCIATED; 8628 priv->status |= STATUS_ASSOCIATED;
8338 netif_carrier_on(priv->net_dev); 8629 netif_carrier_on(priv->net_dev);
8339 if (netif_queue_stopped(priv->net_dev)) { 8630 netif_wake_queue(priv->net_dev);
8340 IPW_DEBUG_INFO("Waking net queue.\n");
8341 netif_wake_queue(priv->net_dev);
8342 } else {
8343 IPW_DEBUG_INFO("Starting net queue.\n");
8344 netif_start_queue(priv->net_dev);
8345 }
8346 } 8631 }
8347 8632
8348 if (!(priv->status & STATUS_ASSOCIATED)) { 8633 if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -8351,7 +8636,8 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8351 /* This is a disassociation event, so kick the firmware to 8636 /* This is a disassociation event, so kick the firmware to
8352 * look for another AP */ 8637 * look for another AP */
8353 if (priv->config & CFG_STATIC_ESSID) 8638 if (priv->config & CFG_STATIC_ESSID)
8354 ipw2100_set_essid(priv, priv->essid, priv->essid_len, 0); 8639 ipw2100_set_essid(priv, priv->essid, priv->essid_len,
8640 0);
8355 else 8641 else
8356 ipw2100_set_essid(priv, NULL, 0, 0); 8642 ipw2100_set_essid(priv, NULL, 0, 0);
8357 up(&priv->action_sem); 8643 up(&priv->action_sem);
@@ -8374,7 +8660,6 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8374 8660
8375#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw" 8661#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw"
8376 8662
8377
8378/* 8663/*
8379 8664
8380BINARY FIRMWARE HEADER FORMAT 8665BINARY FIRMWARE HEADER FORMAT
@@ -8396,12 +8681,10 @@ struct ipw2100_fw_header {
8396 unsigned int uc_size; 8681 unsigned int uc_size;
8397} __attribute__ ((packed)); 8682} __attribute__ ((packed));
8398 8683
8399
8400
8401static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw) 8684static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8402{ 8685{
8403 struct ipw2100_fw_header *h = 8686 struct ipw2100_fw_header *h =
8404 (struct ipw2100_fw_header *)fw->fw_entry->data; 8687 (struct ipw2100_fw_header *)fw->fw_entry->data;
8405 8688
8406 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) { 8689 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) {
8407 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible " 8690 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible "
@@ -8420,7 +8703,6 @@ static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8420 return 0; 8703 return 0;
8421} 8704}
8422 8705
8423
8424static int ipw2100_get_firmware(struct ipw2100_priv *priv, 8706static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8425 struct ipw2100_fw *fw) 8707 struct ipw2100_fw *fw)
8426{ 8708{
@@ -8428,7 +8710,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8428 int rc; 8710 int rc;
8429 8711
8430 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n", 8712 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n",
8431 priv->net_dev->name); 8713 priv->net_dev->name);
8432 8714
8433 switch (priv->ieee->iw_mode) { 8715 switch (priv->ieee->iw_mode) {
8434 case IW_MODE_ADHOC: 8716 case IW_MODE_ADHOC:
@@ -8454,7 +8736,7 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8454 return rc; 8736 return rc;
8455 } 8737 }
8456 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data, 8738 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data,
8457 fw->fw_entry->size); 8739 fw->fw_entry->size);
8458 8740
8459 ipw2100_mod_firmware_load(fw); 8741 ipw2100_mod_firmware_load(fw);
8460 8742
@@ -8470,7 +8752,6 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv,
8470 fw->fw_entry = NULL; 8752 fw->fw_entry = NULL;
8471} 8753}
8472 8754
8473
8474static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf, 8755static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8475 size_t max) 8756 size_t max)
8476{ 8757{
@@ -8479,8 +8760,7 @@ static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8479 u32 tmp; 8760 u32 tmp;
8480 int i; 8761 int i;
8481 /* firmware version is an ascii string (max len of 14) */ 8762 /* firmware version is an ascii string (max len of 14) */
8482 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM, 8763 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM, ver, &len))
8483 ver, &len))
8484 return -EIO; 8764 return -EIO;
8485 tmp = max; 8765 tmp = max;
8486 if (len >= max) 8766 if (len >= max)
@@ -8497,8 +8777,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8497 u32 ver; 8777 u32 ver;
8498 u32 len = sizeof(ver); 8778 u32 len = sizeof(ver);
8499 /* microcode version is a 32 bit integer */ 8779 /* microcode version is a 32 bit integer */
8500 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION, 8780 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION, &ver, &len))
8501 &ver, &len))
8502 return -EIO; 8781 return -EIO;
8503 return snprintf(buf, max, "%08X", ver); 8782 return snprintf(buf, max, "%08X", ver);
8504} 8783}
@@ -8506,8 +8785,7 @@ static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8506/* 8785/*
8507 * On exit, the firmware will have been freed from the fw list 8786 * On exit, the firmware will have been freed from the fw list
8508 */ 8787 */
8509static int ipw2100_fw_download(struct ipw2100_priv *priv, 8788static int ipw2100_fw_download(struct ipw2100_priv *priv, struct ipw2100_fw *fw)
8510 struct ipw2100_fw *fw)
8511{ 8789{
8512 /* firmware is constructed of N contiguous entries, each entry is 8790 /* firmware is constructed of N contiguous entries, each entry is
8513 * structured as: 8791 * structured as:
@@ -8515,7 +8793,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8515 * offset sie desc 8793 * offset sie desc
8516 * 0 4 address to write to 8794 * 0 4 address to write to
8517 * 4 2 length of data run 8795 * 4 2 length of data run
8518 * 6 length data 8796 * 6 length data
8519 */ 8797 */
8520 unsigned int addr; 8798 unsigned int addr;
8521 unsigned short len; 8799 unsigned short len;
@@ -8524,12 +8802,12 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8524 unsigned int firmware_data_left = fw->fw.size; 8802 unsigned int firmware_data_left = fw->fw.size;
8525 8803
8526 while (firmware_data_left > 0) { 8804 while (firmware_data_left > 0) {
8527 addr = *(u32 *)(firmware_data); 8805 addr = *(u32 *) (firmware_data);
8528 firmware_data += 4; 8806 firmware_data += 4;
8529 firmware_data_left -= 4; 8807 firmware_data_left -= 4;
8530 8808
8531 len = *(u16 *)(firmware_data); 8809 len = *(u16 *) (firmware_data);
8532 firmware_data += 2; 8810 firmware_data += 2;
8533 firmware_data_left -= 2; 8811 firmware_data_left -= 2;
8534 8812
8535 if (len > 32) { 8813 if (len > 32) {
@@ -8540,7 +8818,7 @@ static int ipw2100_fw_download(struct ipw2100_priv *priv,
8540 } 8818 }
8541 8819
8542 write_nic_memory(priv->net_dev, addr, len, firmware_data); 8820 write_nic_memory(priv->net_dev, addr, len, firmware_data);
8543 firmware_data += len; 8821 firmware_data += len;
8544 firmware_data_left -= len; 8822 firmware_data_left -= len;
8545 } 8823 }
8546 8824
@@ -8654,21 +8932,19 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
8654 for (i = 0; i < 30; i++) { 8932 for (i = 0; i < 30; i++) {
8655 /* Read alive response structure */ 8933 /* Read alive response structure */
8656 for (j = 0; 8934 for (j = 0;
8657 j < (sizeof(struct symbol_alive_response) >> 1); 8935 j < (sizeof(struct symbol_alive_response) >> 1); j++)
8658 j++) 8936 read_nic_word(dev, 0x210004, ((u16 *) & response) + j);
8659 read_nic_word(dev, 0x210004,
8660 ((u16 *)&response) + j);
8661 8937
8662 if ((response.cmd_id == 1) && 8938 if ((response.cmd_id == 1) && (response.ucode_valid == 0x1))
8663 (response.ucode_valid == 0x1))
8664 break; 8939 break;
8665 udelay(10); 8940 udelay(10);
8666 } 8941 }
8667 8942
8668 if (i == 30) { 8943 if (i == 30) {
8669 printk(KERN_ERR DRV_NAME ": %s: No response from Symbol - hw not alive\n", 8944 printk(KERN_ERR DRV_NAME
8945 ": %s: No response from Symbol - hw not alive\n",
8670 dev->name); 8946 dev->name);
8671 printk_buf(IPW_DL_ERROR, (u8*)&response, sizeof(response)); 8947 printk_buf(IPW_DL_ERROR, (u8 *) & response, sizeof(response));
8672 return -EIO; 8948 return -EIO;
8673 } 8949 }
8674 8950
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index c9e99ce15d66..140fdf2a0a09 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -37,7 +37,6 @@
37#include <linux/socket.h> 37#include <linux/socket.h>
38#include <linux/if_arp.h> 38#include <linux/if_arp.h>
39#include <linux/wireless.h> 39#include <linux/wireless.h>
40#include <linux/version.h>
41#include <net/iw_handler.h> // new driver API 40#include <net/iw_handler.h> // new driver API
42 41
43#include <net/ieee80211.h> 42#include <net/ieee80211.h>
@@ -93,7 +92,6 @@ struct ipw2100_rx_packet;
93#define IPW_DL_IOCTL (1<<14) 92#define IPW_DL_IOCTL (1<<14)
94#define IPW_DL_RF_KILL (1<<17) 93#define IPW_DL_RF_KILL (1<<17)
95 94
96
97#define IPW_DL_MANAGE (1<<15) 95#define IPW_DL_MANAGE (1<<15)
98#define IPW_DL_FW (1<<16) 96#define IPW_DL_FW (1<<16)
99 97
@@ -156,7 +154,9 @@ extern const char *band_str[];
156 154
157struct bd_status { 155struct bd_status {
158 union { 156 union {
159 struct { u8 nlf:1, txType:2, intEnabled:1, reserved:4;} fields; 157 struct {
158 u8 nlf:1, txType:2, intEnabled:1, reserved:4;
159 } fields;
160 u8 field; 160 u8 field;
161 } info; 161 } info;
162} __attribute__ ((packed)); 162} __attribute__ ((packed));
@@ -165,7 +165,7 @@ struct ipw2100_bd {
165 u32 host_addr; 165 u32 host_addr;
166 u32 buf_length; 166 u32 buf_length;
167 struct bd_status status; 167 struct bd_status status;
168 /* number of fragments for frame (should be set only for 168 /* number of fragments for frame (should be set only for
169 * 1st TBD) */ 169 * 1st TBD) */
170 u8 num_fragments; 170 u8 num_fragments;
171 u8 reserved[6]; 171 u8 reserved[6];
@@ -293,10 +293,10 @@ struct ipw2100_cmd_header {
293struct ipw2100_data_header { 293struct ipw2100_data_header {
294 u32 host_command_reg; 294 u32 host_command_reg;
295 u32 host_command_reg1; 295 u32 host_command_reg1;
296 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver 296 u8 encrypted; // BOOLEAN in win! TRUE if frame is enc by driver
297 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC 297 u8 needs_encryption; // BOOLEAN in win! TRUE if frma need to be enc in NIC
298 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key 298 u8 wep_index; // 0 no key, 1-4 key index, 0xff immediate key
299 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV 299 u8 key_size; // 0 no imm key, 0x5 64bit encr, 0xd 128bit encr, 0x10 128bit encr and 128bit IV
300 u8 key[16]; 300 u8 key[16];
301 u8 reserved[10]; // f/w reserved 301 u8 reserved[10]; // f/w reserved
302 u8 src_addr[ETH_ALEN]; 302 u8 src_addr[ETH_ALEN];
@@ -306,14 +306,13 @@ struct ipw2100_data_header {
306 306
307/* Host command data structure */ 307/* Host command data structure */
308struct host_command { 308struct host_command {
309 u32 host_command; // COMMAND ID 309 u32 host_command; // COMMAND ID
310 u32 host_command1; // COMMAND ID 310 u32 host_command1; // COMMAND ID
311 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID) 311 u32 host_command_sequence; // UNIQUE COMMAND NUMBER (ID)
312 u32 host_command_length; // LENGTH 312 u32 host_command_length; // LENGTH
313 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS 313 u32 host_command_parameters[HOST_COMMAND_PARAMS_REG_LEN]; // COMMAND PARAMETERS
314} __attribute__ ((packed)); 314} __attribute__ ((packed));
315 315
316
317typedef enum { 316typedef enum {
318 POWER_ON_RESET, 317 POWER_ON_RESET,
319 EXIT_POWER_DOWN_RESET, 318 EXIT_POWER_DOWN_RESET,
@@ -328,17 +327,16 @@ enum {
328 RX 327 RX
329}; 328};
330 329
331
332struct ipw2100_tx_packet { 330struct ipw2100_tx_packet {
333 int type; 331 int type;
334 int index; 332 int index;
335 union { 333 union {
336 struct { /* COMMAND */ 334 struct { /* COMMAND */
337 struct ipw2100_cmd_header* cmd; 335 struct ipw2100_cmd_header *cmd;
338 dma_addr_t cmd_phys; 336 dma_addr_t cmd_phys;
339 } c_struct; 337 } c_struct;
340 struct { /* DATA */ 338 struct { /* DATA */
341 struct ipw2100_data_header* data; 339 struct ipw2100_data_header *data;
342 dma_addr_t data_phys; 340 dma_addr_t data_phys;
343 struct ieee80211_txb *txb; 341 struct ieee80211_txb *txb;
344 } d_struct; 342 } d_struct;
@@ -348,7 +346,6 @@ struct ipw2100_tx_packet {
348 struct list_head list; 346 struct list_head list;
349}; 347};
350 348
351
352struct ipw2100_rx_packet { 349struct ipw2100_rx_packet {
353 struct ipw2100_rx *rxp; 350 struct ipw2100_rx *rxp;
354 dma_addr_t dma_addr; 351 dma_addr_t dma_addr;
@@ -432,13 +429,13 @@ enum {
432}; 429};
433 430
434#define STATUS_POWERED (1<<0) 431#define STATUS_POWERED (1<<0)
435#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */ 432#define STATUS_CMD_ACTIVE (1<<1) /**< host command in progress */
436#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */ 433#define STATUS_RUNNING (1<<2) /* Card initialized, but not enabled */
437#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */ 434#define STATUS_ENABLED (1<<3) /* Card enabled -- can scan,Tx,Rx */
438#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */ 435#define STATUS_STOPPING (1<<4) /* Card is in shutdown phase */
439#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */ 436#define STATUS_INITIALIZED (1<<5) /* Card is ready for external calls */
440#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */ 437#define STATUS_ASSOCIATING (1<<9) /* Associated, but no BSSID yet */
441#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */ 438#define STATUS_ASSOCIATED (1<<10) /* Associated and BSSID valid */
442#define STATUS_INT_ENABLED (1<<11) 439#define STATUS_INT_ENABLED (1<<11)
443#define STATUS_RF_KILL_HW (1<<12) 440#define STATUS_RF_KILL_HW (1<<12)
444#define STATUS_RF_KILL_SW (1<<13) 441#define STATUS_RF_KILL_SW (1<<13)
@@ -451,9 +448,7 @@ enum {
451#define STATUS_SCAN_COMPLETE (1<<26) 448#define STATUS_SCAN_COMPLETE (1<<26)
452#define STATUS_WX_EVENT_PENDING (1<<27) 449#define STATUS_WX_EVENT_PENDING (1<<27)
453#define STATUS_RESET_PENDING (1<<29) 450#define STATUS_RESET_PENDING (1<<29)
454#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */ 451#define STATUS_SECURITY_UPDATED (1<<30) /* Security sync needed */
455
456
457 452
458/* Internal NIC states */ 453/* Internal NIC states */
459#define IPW_STATE_INITIALIZED (1<<0) 454#define IPW_STATE_INITIALIZED (1<<0)
@@ -469,11 +464,9 @@ enum {
469#define IPW_STATE_POWER_DOWN (1<<10) 464#define IPW_STATE_POWER_DOWN (1<<10)
470#define IPW_STATE_SCANNING (1<<11) 465#define IPW_STATE_SCANNING (1<<11)
471 466
472 467#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */
473 468#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
474#define CFG_STATIC_CHANNEL (1<<0) /* Restrict assoc. to single channel */ 469#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
475#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
476#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
477#define CFG_CUSTOM_MAC (1<<3) 470#define CFG_CUSTOM_MAC (1<<3)
478#define CFG_LONG_PREAMBLE (1<<4) 471#define CFG_LONG_PREAMBLE (1<<4)
479#define CFG_ASSOCIATE (1<<6) 472#define CFG_ASSOCIATE (1<<6)
@@ -481,14 +474,17 @@ enum {
481#define CFG_ADHOC_CREATE (1<<8) 474#define CFG_ADHOC_CREATE (1<<8)
482#define CFG_C3_DISABLED (1<<9) 475#define CFG_C3_DISABLED (1<<9)
483#define CFG_PASSIVE_SCAN (1<<10) 476#define CFG_PASSIVE_SCAN (1<<10)
477#ifdef CONFIG_IPW2100_MONITOR
478#define CFG_CRC_CHECK (1<<11)
479#endif
484 480
485#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 481#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
486#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 482#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
487 483
488struct ipw2100_priv { 484struct ipw2100_priv {
489 485
490 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */ 486 int stop_hang_check; /* Set 1 when shutting down to kill hang_check */
491 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */ 487 int stop_rf_kill; /* Set 1 when shutting down to kill rf_kill */
492 488
493 struct ieee80211_device *ieee; 489 struct ieee80211_device *ieee;
494 unsigned long status; 490 unsigned long status;
@@ -519,19 +515,16 @@ struct ipw2100_priv {
519 unsigned long hw_features; 515 unsigned long hw_features;
520 int hangs; 516 int hangs;
521 u32 last_rtc; 517 u32 last_rtc;
522 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */ 518 int dump_raw; /* 1 to dump raw bytes in /sys/.../memory */
523 u8* snapshot[0x30]; 519 u8 *snapshot[0x30];
524 520
525 u8 mandatory_bssid_mac[ETH_ALEN]; 521 u8 mandatory_bssid_mac[ETH_ALEN];
526 u8 mac_addr[ETH_ALEN]; 522 u8 mac_addr[ETH_ALEN];
527 523
528 int power_mode; 524 int power_mode;
529 525
530 /* WEP data */
531 struct ieee80211_security sec;
532 int messages_sent; 526 int messages_sent;
533 527
534
535 int short_retry_limit; 528 int short_retry_limit;
536 int long_retry_limit; 529 int long_retry_limit;
537 530
@@ -599,7 +592,6 @@ struct ipw2100_priv {
599 wait_queue_head_t wait_command_queue; 592 wait_queue_head_t wait_command_queue;
600}; 593};
601 594
602
603/********************************************************* 595/*********************************************************
604 * Host Command -> From Driver to FW 596 * Host Command -> From Driver to FW
605 *********************************************************/ 597 *********************************************************/
@@ -646,7 +638,6 @@ struct ipw2100_priv {
646#define CARD_DISABLE_PHY_OFF 61 638#define CARD_DISABLE_PHY_OFF 61
647#define MSDU_TX_RATES 62 639#define MSDU_TX_RATES 62
648 640
649
650/* Rogue AP Detection */ 641/* Rogue AP Detection */
651#define SET_STATION_STAT_BITS 64 642#define SET_STATION_STAT_BITS 64
652#define CLEAR_STATIONS_STAT_BITS 65 643#define CLEAR_STATIONS_STAT_BITS 65
@@ -655,8 +646,6 @@ struct ipw2100_priv {
655#define DISASSOCIATION_BSSID 68 646#define DISASSOCIATION_BSSID 68
656#define SET_WPA_IE 69 647#define SET_WPA_IE 69
657 648
658
659
660/* system configuration bit mask: */ 649/* system configuration bit mask: */
661#define IPW_CFG_MONITOR 0x00004 650#define IPW_CFG_MONITOR 0x00004
662#define IPW_CFG_PREAMBLE_AUTO 0x00010 651#define IPW_CFG_PREAMBLE_AUTO 0x00010
@@ -704,7 +693,7 @@ struct ipw2100_priv {
704#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB) 693#define IPW2100_INTA_TX_TRANSFER (0x00000001) // Bit 0 (LSB)
705#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1 694#define IPW2100_INTA_RX_TRANSFER (0x00000002) // Bit 1
706#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2 695#define IPW2100_INTA_TX_COMPLETE (0x00000004) // Bit 2
707#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3 696#define IPW2100_INTA_EVENT_INTERRUPT (0x00000008) // Bit 3
708#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4 697#define IPW2100_INTA_STATUS_CHANGE (0x00000010) // Bit 4
709#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5 698#define IPW2100_INTA_BEACON_PERIOD_EXPIRED (0x00000020) // Bit 5
710#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16 699#define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE (0x00010000) // Bit 16
@@ -784,9 +773,6 @@ struct ipw2100_priv {
784#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli 773#define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT 100 // 100 milli
785#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli 774#define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT 100 // 100 milli
786 775
787
788
789
790#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr) 776#define IPW_HEADER_802_11_SIZE sizeof(struct ieee80211_hdr_3addr)
791#define IPW_MAX_80211_PAYLOAD_SIZE 2304U 777#define IPW_MAX_80211_PAYLOAD_SIZE 2304U
792#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312 778#define IPW_MAX_802_11_PAYLOAD_LENGTH 2312
@@ -843,8 +829,8 @@ struct ipw2100_rx {
843#define IPW_TX_POWER_MIN_DBM (-12) 829#define IPW_TX_POWER_MIN_DBM (-12)
844#define IPW_TX_POWER_MAX_DBM 16 830#define IPW_TX_POWER_MAX_DBM 16
845 831
846#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan 832#define FW_SCAN_DONOT_ASSOCIATE 0x0001 // Dont Attempt to Associate after Scan
847#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan 833#define FW_SCAN_PASSIVE 0x0008 // Force PASSSIVE Scan
848 834
849#define REG_MIN_CHANNEL 0 835#define REG_MIN_CHANNEL 0
850#define REG_MAX_CHANNEL 14 836#define REG_MAX_CHANNEL 14
@@ -856,7 +842,6 @@ struct ipw2100_rx {
856#define DIVERSITY_ANTENNA_A 1 // Use antenna A 842#define DIVERSITY_ANTENNA_A 1 // Use antenna A
857#define DIVERSITY_ANTENNA_B 2 // Use antenna B 843#define DIVERSITY_ANTENNA_B 2 // Use antenna B
858 844
859
860#define HOST_COMMAND_WAIT 0 845#define HOST_COMMAND_WAIT 0
861#define HOST_COMMAND_NO_WAIT 1 846#define HOST_COMMAND_NO_WAIT 1
862 847
@@ -873,10 +858,9 @@ struct ipw2100_rx {
873#define TYPE_ASSOCIATION_REQUEST 0x0013 858#define TYPE_ASSOCIATION_REQUEST 0x0013
874#define TYPE_REASSOCIATION_REQUEST 0x0014 859#define TYPE_REASSOCIATION_REQUEST 0x0014
875 860
876 861#define HW_FEATURE_RFKILL 0x0001
877#define HW_FEATURE_RFKILL (0x0001) 862#define RF_KILLSWITCH_OFF 1
878#define RF_KILLSWITCH_OFF (1) 863#define RF_KILLSWITCH_ON 0
879#define RF_KILLSWITCH_ON (0)
880 864
881#define IPW_COMMAND_POOL_SIZE 40 865#define IPW_COMMAND_POOL_SIZE 40
882 866
@@ -895,7 +879,7 @@ struct ipw2100_rx {
895// Fixed size data: Ordinal Table 1 879// Fixed size data: Ordinal Table 1
896typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW 880typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
897// Transmit statistics 881// Transmit statistics
898 IPW_ORD_STAT_TX_HOST_REQUESTS = 1,// # of requested Host Tx's (MSDU) 882 IPW_ORD_STAT_TX_HOST_REQUESTS = 1, // # of requested Host Tx's (MSDU)
899 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU) 883 IPW_ORD_STAT_TX_HOST_COMPLETE, // # of successful Host Tx's (MSDU)
900 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU) 884 IPW_ORD_STAT_TX_DIR_DATA, // # of successful Directed Tx's (MSDU)
901 885
@@ -905,42 +889,42 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
905 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB 889 IPW_ORD_STAT_TX_DIR_DATA11, // # of successful Directed Tx's (MSDU) @ 11MB
906 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB 890 IPW_ORD_STAT_TX_DIR_DATA22, // # of successful Directed Tx's (MSDU) @ 22MB
907 891
908 IPW_ORD_STAT_TX_NODIR_DATA1 = 13,// # of successful Non_Directed Tx's (MSDU) @ 1MB 892 IPW_ORD_STAT_TX_NODIR_DATA1 = 13, // # of successful Non_Directed Tx's (MSDU) @ 1MB
909 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB 893 IPW_ORD_STAT_TX_NODIR_DATA2, // # of successful Non_Directed Tx's (MSDU) @ 2MB
910 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB 894 IPW_ORD_STAT_TX_NODIR_DATA5_5, // # of successful Non_Directed Tx's (MSDU) @ 5.5MB
911 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB 895 IPW_ORD_STAT_TX_NODIR_DATA11, // # of successful Non_Directed Tx's (MSDU) @ 11MB
912 896
913 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's 897 IPW_ORD_STAT_NULL_DATA = 21, // # of successful NULL data Tx's
914 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS 898 IPW_ORD_STAT_TX_RTS, // # of successful Tx RTS
915 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS 899 IPW_ORD_STAT_TX_CTS, // # of successful Tx CTS
916 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK 900 IPW_ORD_STAT_TX_ACK, // # of successful Tx ACK
917 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's 901 IPW_ORD_STAT_TX_ASSN, // # of successful Association Tx's
918 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's 902 IPW_ORD_STAT_TX_ASSN_RESP, // # of successful Association response Tx's
919 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's 903 IPW_ORD_STAT_TX_REASSN, // # of successful Reassociation Tx's
920 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's 904 IPW_ORD_STAT_TX_REASSN_RESP, // # of successful Reassociation response Tx's
921 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted 905 IPW_ORD_STAT_TX_PROBE, // # of probes successfully transmitted
922 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted 906 IPW_ORD_STAT_TX_PROBE_RESP, // # of probe responses successfully transmitted
923 IPW_ORD_STAT_TX_BEACON, // # of tx beacon 907 IPW_ORD_STAT_TX_BEACON, // # of tx beacon
924 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM 908 IPW_ORD_STAT_TX_ATIM, // # of Tx ATIM
925 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX 909 IPW_ORD_STAT_TX_DISASSN, // # of successful Disassociation TX
926 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx 910 IPW_ORD_STAT_TX_AUTH, // # of successful Authentication Tx
927 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX 911 IPW_ORD_STAT_TX_DEAUTH, // # of successful Deauthentication TX
928 912
929 IPW_ORD_STAT_TX_TOTAL_BYTES = 41,// Total successful Tx data bytes 913 IPW_ORD_STAT_TX_TOTAL_BYTES = 41, // Total successful Tx data bytes
930 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries 914 IPW_ORD_STAT_TX_RETRIES, // # of Tx retries
931 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS 915 IPW_ORD_STAT_TX_RETRY1, // # of Tx retries at 1MBPS
932 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS 916 IPW_ORD_STAT_TX_RETRY2, // # of Tx retries at 2MBPS
933 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS 917 IPW_ORD_STAT_TX_RETRY5_5, // # of Tx retries at 5.5MBPS
934 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS 918 IPW_ORD_STAT_TX_RETRY11, // # of Tx retries at 11MBPS
935 919
936 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures 920 IPW_ORD_STAT_TX_FAILURES = 51, // # of Tx Failures
937 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time 921 IPW_ORD_STAT_TX_ABORT_AT_HOP, //NS // # of Tx's aborted at hop time
938 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,// # of times max tries in a hop failed 922 IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP, // # of times max tries in a hop failed
939 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup 923 IPW_ORD_STAT_TX_ABORT_LATE_DMA, //NS // # of times tx aborted due to late dma setup
940 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted 924 IPW_ORD_STAT_TX_ABORT_STX, //NS // # of times backoff aborted
941 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed 925 IPW_ORD_STAT_TX_DISASSN_FAIL, // # of times disassociation failed
942 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames 926 IPW_ORD_STAT_TX_ERR_CTS, // # of missed/bad CTS frames
943 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent 927 IPW_ORD_STAT_TX_BPDU, //NS // # of spanning tree BPDUs sent
944 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks 928 IPW_ORD_STAT_TX_ERR_ACK, // # of tx err due to acks
945 929
946 // Receive statistics 930 // Receive statistics
@@ -952,7 +936,7 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
952 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB 936 IPW_ORD_STAT_RX_DIR_DATA11, // # of directed packets at 11MB
953 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB 937 IPW_ORD_STAT_RX_DIR_DATA22, // # of directed packets at 22MB
954 938
955 IPW_ORD_STAT_RX_NODIR_DATA = 71,// # of nondirected packets 939 IPW_ORD_STAT_RX_NODIR_DATA = 71, // # of nondirected packets
956 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB 940 IPW_ORD_STAT_RX_NODIR_DATA1, // # of nondirected packets at 1MB
957 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB 941 IPW_ORD_STAT_RX_NODIR_DATA2, // # of nondirected packets at 2MB
958 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB 942 IPW_ORD_STAT_RX_NODIR_DATA5_5, // # of nondirected packets at 5.5MB
@@ -977,18 +961,18 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
977 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx 961 IPW_ORD_STAT_RX_AUTH, // # of authentication Rx
978 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx 962 IPW_ORD_STAT_RX_DEAUTH, // # of deauthentication Rx
979 963
980 IPW_ORD_STAT_RX_TOTAL_BYTES = 101,// Total rx data bytes received 964 IPW_ORD_STAT_RX_TOTAL_BYTES = 101, // Total rx data bytes received
981 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error 965 IPW_ORD_STAT_RX_ERR_CRC, // # of packets with Rx CRC error
982 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB 966 IPW_ORD_STAT_RX_ERR_CRC1, // # of Rx CRC errors at 1MB
983 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB 967 IPW_ORD_STAT_RX_ERR_CRC2, // # of Rx CRC errors at 2MB
984 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB 968 IPW_ORD_STAT_RX_ERR_CRC5_5, // # of Rx CRC errors at 5.5MB
985 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB 969 IPW_ORD_STAT_RX_ERR_CRC11, // # of Rx CRC errors at 11MB
986 970
987 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB 971 IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
988 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB 972 IPW_ORD_STAT_RX_DUPLICATE2, // # of duplicate rx packets at 2MB
989 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB 973 IPW_ORD_STAT_RX_DUPLICATE5_5, // # of duplicate rx packets at 5.5MB
990 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB 974 IPW_ORD_STAT_RX_DUPLICATE11, // # of duplicate rx packets at 11MB
991 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets 975 IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
992 976
993 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db 977 IPW_ORD_PERS_DB_LOCK = 120, // # locking fw permanent db
994 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db 978 IPW_ORD_PERS_DB_SIZE, // # size of fw permanent db
@@ -1006,17 +990,17 @@ typedef enum _ORDINAL_TABLE_1 { // NS - means Not Supported by FW
1006 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption 990 IPW_ORD_STAT_RX_ICV_ERRORS, // # of ICV errors during decryption
1007 991
1008// PSP Statistics 992// PSP Statistics
1009 IPW_ORD_STAT_PSP_SUSPENSION = 137,// # of times adapter suspended 993 IPW_ORD_STAT_PSP_SUSPENSION = 137, // # of times adapter suspended
1010 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout 994 IPW_ORD_STAT_PSP_BCN_TIMEOUT, // # of beacon timeout
1011 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts 995 IPW_ORD_STAT_PSP_POLL_TIMEOUT, // # of poll response timeouts
1012 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,// # of timeouts waiting for last broadcast/muticast pkt 996 IPW_ORD_STAT_PSP_NONDIR_TIMEOUT, // # of timeouts waiting for last broadcast/muticast pkt
1013 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received 997 IPW_ORD_STAT_PSP_RX_DTIMS, // # of PSP DTIMs received
1014 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received 998 IPW_ORD_STAT_PSP_RX_TIMS, // # of PSP TIMs received
1015 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID 999 IPW_ORD_STAT_PSP_STATION_ID, // PSP Station ID
1016 1000
1017// Association and roaming 1001// Association and roaming
1018 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association 1002 IPW_ORD_LAST_ASSN_TIME = 147, // RTC time of last association
1019 IPW_ORD_STAT_PERCENT_MISSED_BCNS,// current calculation of % missed beacons 1003 IPW_ORD_STAT_PERCENT_MISSED_BCNS, // current calculation of % missed beacons
1020 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries 1004 IPW_ORD_STAT_PERCENT_RETRIES, // current calculation of % missed tx retries
1021 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated 1005 IPW_ORD_ASSOCIATED_AP_PTR, // If associated, this is ptr to the associated
1022 // AP table entry. set to 0 if not associated 1006 // AP table entry. set to 0 if not associated
@@ -1151,7 +1135,7 @@ struct ipw2100_fw_chunk {
1151}; 1135};
1152 1136
1153struct ipw2100_fw_chunk_set { 1137struct ipw2100_fw_chunk_set {
1154 const void *data; 1138 const void *data;
1155 unsigned long size; 1139 unsigned long size;
1156}; 1140};
1157 1141
@@ -1164,4 +1148,4 @@ struct ipw2100_fw {
1164 1148
1165#define MAX_FW_VERSION_LEN 14 1149#define MAX_FW_VERSION_LEN 14
1166 1150
1167#endif /* _IPW2100_H */ 1151#endif /* _IPW2100_H */
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 3db0c32afe82..b0d195d1721a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4 4
5 802.11 status code portion of this file from ethereal-0.10.6: 5 802.11 status code portion of this file from ethereal-0.10.6:
6 Copyright 2000, Axis Communications AB 6 Copyright 2000, Axis Communications AB
@@ -31,30 +31,103 @@
31******************************************************************************/ 31******************************************************************************/
32 32
33#include "ipw2200.h" 33#include "ipw2200.h"
34#include <linux/version.h>
34 35
35#define IPW2200_VERSION "1.0.0" 36#define IPW2200_VERSION "git-1.0.8"
36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" 37#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 38#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
38#define DRV_VERSION IPW2200_VERSION 39#define DRV_VERSION IPW2200_VERSION
39 40
41#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
42
40MODULE_DESCRIPTION(DRV_DESCRIPTION); 43MODULE_DESCRIPTION(DRV_DESCRIPTION);
41MODULE_VERSION(DRV_VERSION); 44MODULE_VERSION(DRV_VERSION);
42MODULE_AUTHOR(DRV_COPYRIGHT); 45MODULE_AUTHOR(DRV_COPYRIGHT);
43MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
44 47
48static int cmdlog = 0;
45static int debug = 0; 49static int debug = 0;
46static int channel = 0; 50static int channel = 0;
47static char *ifname;
48static int mode = 0; 51static int mode = 0;
49 52
50static u32 ipw_debug_level; 53static u32 ipw_debug_level;
51static int associate = 1; 54static int associate = 1;
52static int auto_create = 1; 55static int auto_create = 1;
56static int led = 0;
53static int disable = 0; 57static int disable = 0;
58static int hwcrypto = 1;
54static const char ipw_modes[] = { 59static const char ipw_modes[] = {
55 'a', 'b', 'g', '?' 60 'a', 'b', 'g', '?'
56}; 61};
57 62
63#ifdef CONFIG_IPW_QOS
64static int qos_enable = 0;
65static int qos_burst_enable = 0;
66static int qos_no_ack_mask = 0;
67static int burst_duration_CCK = 0;
68static int burst_duration_OFDM = 0;
69
70static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
71 {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
72 QOS_TX3_CW_MIN_OFDM},
73 {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
74 QOS_TX3_CW_MAX_OFDM},
75 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
76 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
77 {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
78 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
79};
80
81static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
82 {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
83 QOS_TX3_CW_MIN_CCK},
84 {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
85 QOS_TX3_CW_MAX_CCK},
86 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
87 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
88 {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
89 QOS_TX3_TXOP_LIMIT_CCK}
90};
91
92static struct ieee80211_qos_parameters def_parameters_OFDM = {
93 {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
94 DEF_TX3_CW_MIN_OFDM},
95 {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
96 DEF_TX3_CW_MAX_OFDM},
97 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
98 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
99 {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
100 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
101};
102
103static struct ieee80211_qos_parameters def_parameters_CCK = {
104 {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
105 DEF_TX3_CW_MIN_CCK},
106 {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
107 DEF_TX3_CW_MAX_CCK},
108 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
109 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
110 {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
111 DEF_TX3_TXOP_LIMIT_CCK}
112};
113
114static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
115
116static int from_priority_to_tx_queue[] = {
117 IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
118 IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
119};
120
121static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
122
123static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
124 *qos_param);
125static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
126 *qos_param);
127#endif /* CONFIG_IPW_QOS */
128
129static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
130static void ipw_remove_current_network(struct ipw_priv *priv);
58static void ipw_rx(struct ipw_priv *priv); 131static void ipw_rx(struct ipw_priv *priv);
59static int ipw_queue_tx_reclaim(struct ipw_priv *priv, 132static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
60 struct clx2_tx_queue *txq, int qindex); 133 struct clx2_tx_queue *txq, int qindex);
@@ -68,42 +141,24 @@ static void ipw_tx_queue_free(struct ipw_priv *);
68static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *); 141static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
69static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *); 142static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
70static void ipw_rx_queue_replenish(void *); 143static void ipw_rx_queue_replenish(void *);
71
72static int ipw_up(struct ipw_priv *); 144static int ipw_up(struct ipw_priv *);
145static void ipw_bg_up(void *);
73static void ipw_down(struct ipw_priv *); 146static void ipw_down(struct ipw_priv *);
147static void ipw_bg_down(void *);
74static int ipw_config(struct ipw_priv *); 148static int ipw_config(struct ipw_priv *);
75static int init_supported_rates(struct ipw_priv *priv, 149static int init_supported_rates(struct ipw_priv *priv,
76 struct ipw_supported_rates *prates); 150 struct ipw_supported_rates *prates);
151static void ipw_set_hwcrypto_keys(struct ipw_priv *);
152static void ipw_send_wep_keys(struct ipw_priv *, int);
77 153
78static u8 band_b_active_channel[MAX_B_CHANNELS] = { 154static int ipw_is_valid_channel(struct ieee80211_device *, u8);
79 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0 155static int ipw_channel_to_index(struct ieee80211_device *, u8);
80}; 156static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
81static u8 band_a_active_channel[MAX_A_CHANNELS] = { 157static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
82 36, 40, 44, 48, 149, 153, 157, 161, 165, 52, 56, 60, 64, 0 158static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
83};
84 159
85static int is_valid_channel(int mode_mask, int channel) 160static int snprint_line(char *buf, size_t count,
86{ 161 const u8 * data, u32 len, u32 ofs)
87 int i;
88
89 if (!channel)
90 return 0;
91
92 if (mode_mask & IEEE_A)
93 for (i = 0; i < MAX_A_CHANNELS; i++)
94 if (band_a_active_channel[i] == channel)
95 return IEEE_A;
96
97 if (mode_mask & (IEEE_B | IEEE_G))
98 for (i = 0; i < MAX_B_CHANNELS; i++)
99 if (band_b_active_channel[i] == channel)
100 return mode_mask & (IEEE_B | IEEE_G);
101
102 return 0;
103}
104
105static char *snprint_line(char *buf, size_t count,
106 const u8 * data, u32 len, u32 ofs)
107{ 162{
108 int out, i, j, l; 163 int out, i, j, l;
109 char c; 164 char c;
@@ -134,7 +189,7 @@ static char *snprint_line(char *buf, size_t count,
134 out += snprintf(buf + out, count - out, " "); 189 out += snprintf(buf + out, count - out, " ");
135 } 190 }
136 191
137 return buf; 192 return out;
138} 193}
139 194
140static void printk_buf(int level, const u8 * data, u32 len) 195static void printk_buf(int level, const u8 * data, u32 len)
@@ -145,14 +200,33 @@ static void printk_buf(int level, const u8 * data, u32 len)
145 return; 200 return;
146 201
147 while (len) { 202 while (len) {
148 printk(KERN_DEBUG "%s\n", 203 snprint_line(line, sizeof(line), &data[ofs],
149 snprint_line(line, sizeof(line), &data[ofs], 204 min(len, 16U), ofs);
150 min(len, 16U), ofs)); 205 printk(KERN_DEBUG "%s\n", line);
151 ofs += 16; 206 ofs += 16;
152 len -= min(len, 16U); 207 len -= min(len, 16U);
153 } 208 }
154} 209}
155 210
211static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
212{
213 size_t out = size;
214 u32 ofs = 0;
215 int total = 0;
216
217 while (size && len) {
218 out = snprint_line(output, size, &data[ofs],
219 min_t(size_t, len, 16U), ofs);
220
221 ofs += 16;
222 output += out;
223 size -= out;
224 len -= min_t(size_t, len, 16U);
225 total += out;
226 }
227 return total;
228}
229
156static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg); 230static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
157#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b) 231#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
158 232
@@ -226,38 +300,42 @@ static inline u32 __ipw_read32(char *f, u32 l, struct ipw_priv *ipw, u32 ofs)
226#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs) 300#define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
227 301
228static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int); 302static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
229#define ipw_read_indirect(a, b, c, d) \ 303static inline void __ipw_read_indirect(const char *f, int l,
230 IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ 304 struct ipw_priv *a, u32 b, u8 * c, int d)
231 _ipw_read_indirect(a, b, c, d) 305{
306 IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
307 d);
308 _ipw_read_indirect(a, b, c, d);
309}
310
311#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
232 312
233static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data, 313static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
234 int num); 314 int num);
235#define ipw_write_indirect(a, b, c, d) \ 315#define ipw_write_indirect(a, b, c, d) \
236 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \ 316 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
237 _ipw_write_indirect(a, b, c, d) 317 _ipw_write_indirect(a, b, c, d)
238 318
239/* indirect write s */ 319/* indirect write s */
240static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value) 320static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
241{ 321{
242 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value); 322 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
243 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); 323 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
244 _ipw_write32(priv, CX2_INDIRECT_DATA, value); 324 _ipw_write32(priv, IPW_INDIRECT_DATA, value);
245} 325}
246 326
247static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value) 327static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
248{ 328{
249 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 329 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
250 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 330 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
251 _ipw_write8(priv, CX2_INDIRECT_DATA, value); 331 _ipw_write8(priv, IPW_INDIRECT_DATA, value);
252 IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
253 (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), value);
254} 332}
255 333
256static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value) 334static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
257{ 335{
258 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value); 336 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
259 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 337 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
260 _ipw_write16(priv, CX2_INDIRECT_DATA, value); 338 _ipw_write16(priv, IPW_INDIRECT_DATA, value);
261} 339}
262 340
263/* indirect read s */ 341/* indirect read s */
@@ -265,9 +343,9 @@ static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
265static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg) 343static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)
266{ 344{
267 u32 word; 345 u32 word;
268 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK); 346 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
269 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg); 347 IPW_DEBUG_IO(" reg = 0x%8X : \n", reg);
270 word = _ipw_read32(priv, CX2_INDIRECT_DATA); 348 word = _ipw_read32(priv, IPW_INDIRECT_DATA);
271 return (word >> ((reg & 0x3) * 8)) & 0xff; 349 return (word >> ((reg & 0x3) * 8)) & 0xff;
272} 350}
273 351
@@ -277,8 +355,8 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
277 355
278 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg); 356 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);
279 357
280 _ipw_write32(priv, CX2_INDIRECT_ADDR, reg); 358 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
281 value = _ipw_read32(priv, CX2_INDIRECT_DATA); 359 value = _ipw_read32(priv, IPW_INDIRECT_DATA);
282 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value); 360 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x \n", reg, value);
283 return value; 361 return value;
284} 362}
@@ -287,67 +365,69 @@ static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)
287static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 365static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
288 int num) 366 int num)
289{ 367{
290 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 368 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
291 u32 dif_len = addr - aligned_addr; 369 u32 dif_len = addr - aligned_addr;
292 u32 aligned_len;
293 u32 i; 370 u32 i;
294 371
295 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 372 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
296 373
374 if (num <= 0) {
375 return;
376 }
377
297 /* Read the first nibble byte by byte */ 378 /* Read the first nibble byte by byte */
298 if (unlikely(dif_len)) { 379 if (unlikely(dif_len)) {
380 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
299 /* Start reading at aligned_addr + dif_len */ 381 /* Start reading at aligned_addr + dif_len */
300 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 382 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
301 for (i = dif_len; i < 4; i++, buf++) 383 *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);
302 *buf = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
303 num -= dif_len;
304 aligned_addr += 4; 384 aligned_addr += 4;
305 } 385 }
306 386
307 /* Read DWs through autoinc register */ 387 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
308 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 388 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
309 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 389 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);
310 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
311 *(u32 *) buf = ipw_read32(priv, CX2_AUTOINC_DATA);
312 390
313 /* Copy the last nibble */ 391 /* Copy the last nibble */
314 dif_len = num - aligned_len; 392 if (unlikely(num)) {
315 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 393 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
316 for (i = 0; i < dif_len; i++, buf++) 394 for (i = 0; num > 0; i++, num--)
317 *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i); 395 *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);
396 }
318} 397}
319 398
320static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 399static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
321 int num) 400 int num)
322{ 401{
323 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 402 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK;
324 u32 dif_len = addr - aligned_addr; 403 u32 dif_len = addr - aligned_addr;
325 u32 aligned_len;
326 u32 i; 404 u32 i;
327 405
328 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 406 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
329 407
408 if (num <= 0) {
409 return;
410 }
411
330 /* Write the first nibble byte by byte */ 412 /* Write the first nibble byte by byte */
331 if (unlikely(dif_len)) { 413 if (unlikely(dif_len)) {
332 /* Start writing at aligned_addr + dif_len */ 414 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
333 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 415 /* Start reading at aligned_addr + dif_len */
334 for (i = dif_len; i < 4; i++, buf++) 416 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
335 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 417 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
336 num -= dif_len;
337 aligned_addr += 4; 418 aligned_addr += 4;
338 } 419 }
339 420
340 /* Write DWs through autoinc register */ 421 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);
341 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 422 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
342 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 423 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);
343 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
344 _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf);
345 424
346 /* Copy the last nibble */ 425 /* Copy the last nibble */
347 dif_len = num - aligned_len; 426 if (unlikely(num)) {
348 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 427 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);
349 for (i = 0; i < dif_len; i++, buf++) 428 for (i = 0; num > 0; i++, num--, buf++)
350 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 429 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);
430 }
351} 431}
352 432
353static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, 433static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
@@ -371,7 +451,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv)
371 if (priv->status & STATUS_INT_ENABLED) 451 if (priv->status & STATUS_INT_ENABLED)
372 return; 452 return;
373 priv->status |= STATUS_INT_ENABLED; 453 priv->status |= STATUS_INT_ENABLED;
374 ipw_write32(priv, CX2_INTA_MASK_R, CX2_INTA_MASK_ALL); 454 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);
375} 455}
376 456
377static inline void ipw_disable_interrupts(struct ipw_priv *priv) 457static inline void ipw_disable_interrupts(struct ipw_priv *priv)
@@ -379,9 +459,10 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv)
379 if (!(priv->status & STATUS_INT_ENABLED)) 459 if (!(priv->status & STATUS_INT_ENABLED))
380 return; 460 return;
381 priv->status &= ~STATUS_INT_ENABLED; 461 priv->status &= ~STATUS_INT_ENABLED;
382 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 462 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
383} 463}
384 464
465#ifdef CONFIG_IPW_DEBUG
385static char *ipw_error_desc(u32 val) 466static char *ipw_error_desc(u32 val)
386{ 467{
387 switch (val) { 468 switch (val) {
@@ -394,81 +475,65 @@ static char *ipw_error_desc(u32 val)
394 case IPW_FW_ERROR_MEMORY_OVERFLOW: 475 case IPW_FW_ERROR_MEMORY_OVERFLOW:
395 return "MEMORY_OVERFLOW"; 476 return "MEMORY_OVERFLOW";
396 case IPW_FW_ERROR_BAD_PARAM: 477 case IPW_FW_ERROR_BAD_PARAM:
397 return "ERROR_BAD_PARAM"; 478 return "BAD_PARAM";
398 case IPW_FW_ERROR_BAD_CHECKSUM: 479 case IPW_FW_ERROR_BAD_CHECKSUM:
399 return "ERROR_BAD_CHECKSUM"; 480 return "BAD_CHECKSUM";
400 case IPW_FW_ERROR_NMI_INTERRUPT: 481 case IPW_FW_ERROR_NMI_INTERRUPT:
401 return "ERROR_NMI_INTERRUPT"; 482 return "NMI_INTERRUPT";
402 case IPW_FW_ERROR_BAD_DATABASE: 483 case IPW_FW_ERROR_BAD_DATABASE:
403 return "ERROR_BAD_DATABASE"; 484 return "BAD_DATABASE";
404 case IPW_FW_ERROR_ALLOC_FAIL: 485 case IPW_FW_ERROR_ALLOC_FAIL:
405 return "ERROR_ALLOC_FAIL"; 486 return "ALLOC_FAIL";
406 case IPW_FW_ERROR_DMA_UNDERRUN: 487 case IPW_FW_ERROR_DMA_UNDERRUN:
407 return "ERROR_DMA_UNDERRUN"; 488 return "DMA_UNDERRUN";
408 case IPW_FW_ERROR_DMA_STATUS: 489 case IPW_FW_ERROR_DMA_STATUS:
409 return "ERROR_DMA_STATUS"; 490 return "DMA_STATUS";
410 case IPW_FW_ERROR_DINOSTATUS_ERROR: 491 case IPW_FW_ERROR_DINO_ERROR:
411 return "ERROR_DINOSTATUS_ERROR"; 492 return "DINO_ERROR";
412 case IPW_FW_ERROR_EEPROMSTATUS_ERROR: 493 case IPW_FW_ERROR_EEPROM_ERROR:
413 return "ERROR_EEPROMSTATUS_ERROR"; 494 return "EEPROM_ERROR";
414 case IPW_FW_ERROR_SYSASSERT: 495 case IPW_FW_ERROR_SYSASSERT:
415 return "ERROR_SYSASSERT"; 496 return "SYSASSERT";
416 case IPW_FW_ERROR_FATAL_ERROR: 497 case IPW_FW_ERROR_FATAL_ERROR:
417 return "ERROR_FATALSTATUS_ERROR"; 498 return "FATAL_ERROR";
418 default: 499 default:
419 return "UNKNOWNSTATUS_ERROR"; 500 return "UNKNOWN_ERROR";
420 } 501 }
421} 502}
422 503
423static void ipw_dump_nic_error_log(struct ipw_priv *priv) 504static void ipw_dump_error_log(struct ipw_priv *priv,
505 struct ipw_fw_error *error)
424{ 506{
425 u32 desc, time, blink1, blink2, ilink1, ilink2, idata, i, count, base; 507 u32 i;
426
427 base = ipw_read32(priv, IPWSTATUS_ERROR_LOG);
428 count = ipw_read_reg32(priv, base);
429 508
430 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { 509 if (!error) {
431 IPW_ERROR("Start IPW Error Log Dump:\n"); 510 IPW_ERROR("Error allocating and capturing error log. "
432 IPW_ERROR("Status: 0x%08X, Config: %08X\n", 511 "Nothing to dump.\n");
433 priv->status, priv->config); 512 return;
434 } 513 }
435 514
436 for (i = ERROR_START_OFFSET; 515 IPW_ERROR("Start IPW Error Log Dump:\n");
437 i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) { 516 IPW_ERROR("Status: 0x%08X, Config: %08X\n",
438 desc = ipw_read_reg32(priv, base + i); 517 error->status, error->config);
439 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
440 blink1 = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
441 blink2 = ipw_read_reg32(priv, base + i + 3 * sizeof(u32));
442 ilink1 = ipw_read_reg32(priv, base + i + 4 * sizeof(u32));
443 ilink2 = ipw_read_reg32(priv, base + i + 5 * sizeof(u32));
444 idata = ipw_read_reg32(priv, base + i + 6 * sizeof(u32));
445 518
519 for (i = 0; i < error->elem_len; i++)
446 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 520 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
447 ipw_error_desc(desc), time, blink1, blink2, 521 ipw_error_desc(error->elem[i].desc),
448 ilink1, ilink2, idata); 522 error->elem[i].time,
449 } 523 error->elem[i].blink1,
524 error->elem[i].blink2,
525 error->elem[i].link1,
526 error->elem[i].link2, error->elem[i].data);
527 for (i = 0; i < error->log_len; i++)
528 IPW_ERROR("%i\t0x%08x\t%i\n",
529 error->log[i].time,
530 error->log[i].data, error->log[i].event);
450} 531}
532#endif
451 533
452static void ipw_dump_nic_event_log(struct ipw_priv *priv) 534static inline int ipw_is_init(struct ipw_priv *priv)
453{ 535{
454 u32 ev, time, data, i, count, base; 536 return (priv->status & STATUS_INIT) ? 1 : 0;
455
456 base = ipw_read32(priv, IPW_EVENT_LOG);
457 count = ipw_read_reg32(priv, base);
458
459 if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE)
460 IPW_ERROR("Start IPW Event Log Dump:\n");
461
462 for (i = EVENT_START_OFFSET;
463 i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) {
464 ev = ipw_read_reg32(priv, base + i);
465 time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
466 data = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
467
468#ifdef CONFIG_IPW_DEBUG
469 IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev);
470#endif
471 }
472} 537}
473 538
474static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len) 539static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
@@ -636,6 +701,340 @@ static void ipw_init_ordinals(struct ipw_priv *priv)
636 701
637} 702}
638 703
704u32 ipw_register_toggle(u32 reg)
705{
706 reg &= ~IPW_START_STANDBY;
707 if (reg & IPW_GATE_ODMA)
708 reg &= ~IPW_GATE_ODMA;
709 if (reg & IPW_GATE_IDMA)
710 reg &= ~IPW_GATE_IDMA;
711 if (reg & IPW_GATE_ADMA)
712 reg &= ~IPW_GATE_ADMA;
713 return reg;
714}
715
716/*
717 * LED behavior:
718 * - On radio ON, turn on any LEDs that require to be on during start
719 * - On initialization, start unassociated blink
720 * - On association, disable unassociated blink
721 * - On disassociation, start unassociated blink
722 * - On radio OFF, turn off any LEDs started during radio on
723 *
724 */
725#define LD_TIME_LINK_ON 300
726#define LD_TIME_LINK_OFF 2700
727#define LD_TIME_ACT_ON 250
728
729void ipw_led_link_on(struct ipw_priv *priv)
730{
731 unsigned long flags;
732 u32 led;
733
734 /* If configured to not use LEDs, or nic_type is 1,
735 * then we don't toggle a LINK led */
736 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
737 return;
738
739 spin_lock_irqsave(&priv->lock, flags);
740
741 if (!(priv->status & STATUS_RF_KILL_MASK) &&
742 !(priv->status & STATUS_LED_LINK_ON)) {
743 IPW_DEBUG_LED("Link LED On\n");
744 led = ipw_read_reg32(priv, IPW_EVENT_REG);
745 led |= priv->led_association_on;
746
747 led = ipw_register_toggle(led);
748
749 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
750 ipw_write_reg32(priv, IPW_EVENT_REG, led);
751
752 priv->status |= STATUS_LED_LINK_ON;
753
754 /* If we aren't associated, schedule turning the LED off */
755 if (!(priv->status & STATUS_ASSOCIATED))
756 queue_delayed_work(priv->workqueue,
757 &priv->led_link_off,
758 LD_TIME_LINK_ON);
759 }
760
761 spin_unlock_irqrestore(&priv->lock, flags);
762}
763
764static void ipw_bg_led_link_on(void *data)
765{
766 struct ipw_priv *priv = data;
767 down(&priv->sem);
768 ipw_led_link_on(data);
769 up(&priv->sem);
770}
771
772void ipw_led_link_off(struct ipw_priv *priv)
773{
774 unsigned long flags;
775 u32 led;
776
777 /* If configured not to use LEDs, or nic type is 1,
778 * then we don't goggle the LINK led. */
779 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
780 return;
781
782 spin_lock_irqsave(&priv->lock, flags);
783
784 if (priv->status & STATUS_LED_LINK_ON) {
785 led = ipw_read_reg32(priv, IPW_EVENT_REG);
786 led &= priv->led_association_off;
787 led = ipw_register_toggle(led);
788
789 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
790 ipw_write_reg32(priv, IPW_EVENT_REG, led);
791
792 IPW_DEBUG_LED("Link LED Off\n");
793
794 priv->status &= ~STATUS_LED_LINK_ON;
795
796 /* If we aren't associated and the radio is on, schedule
797 * turning the LED on (blink while unassociated) */
798 if (!(priv->status & STATUS_RF_KILL_MASK) &&
799 !(priv->status & STATUS_ASSOCIATED))
800 queue_delayed_work(priv->workqueue, &priv->led_link_on,
801 LD_TIME_LINK_OFF);
802
803 }
804
805 spin_unlock_irqrestore(&priv->lock, flags);
806}
807
808static void ipw_bg_led_link_off(void *data)
809{
810 struct ipw_priv *priv = data;
811 down(&priv->sem);
812 ipw_led_link_off(data);
813 up(&priv->sem);
814}
815
816static inline void __ipw_led_activity_on(struct ipw_priv *priv)
817{
818 u32 led;
819
820 if (priv->config & CFG_NO_LED)
821 return;
822
823 if (priv->status & STATUS_RF_KILL_MASK)
824 return;
825
826 if (!(priv->status & STATUS_LED_ACT_ON)) {
827 led = ipw_read_reg32(priv, IPW_EVENT_REG);
828 led |= priv->led_activity_on;
829
830 led = ipw_register_toggle(led);
831
832 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
833 ipw_write_reg32(priv, IPW_EVENT_REG, led);
834
835 IPW_DEBUG_LED("Activity LED On\n");
836
837 priv->status |= STATUS_LED_ACT_ON;
838
839 cancel_delayed_work(&priv->led_act_off);
840 queue_delayed_work(priv->workqueue, &priv->led_act_off,
841 LD_TIME_ACT_ON);
842 } else {
843 /* Reschedule LED off for full time period */
844 cancel_delayed_work(&priv->led_act_off);
845 queue_delayed_work(priv->workqueue, &priv->led_act_off,
846 LD_TIME_ACT_ON);
847 }
848}
849
850void ipw_led_activity_on(struct ipw_priv *priv)
851{
852 unsigned long flags;
853 spin_lock_irqsave(&priv->lock, flags);
854 __ipw_led_activity_on(priv);
855 spin_unlock_irqrestore(&priv->lock, flags);
856}
857
858void ipw_led_activity_off(struct ipw_priv *priv)
859{
860 unsigned long flags;
861 u32 led;
862
863 if (priv->config & CFG_NO_LED)
864 return;
865
866 spin_lock_irqsave(&priv->lock, flags);
867
868 if (priv->status & STATUS_LED_ACT_ON) {
869 led = ipw_read_reg32(priv, IPW_EVENT_REG);
870 led &= priv->led_activity_off;
871
872 led = ipw_register_toggle(led);
873
874 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
875 ipw_write_reg32(priv, IPW_EVENT_REG, led);
876
877 IPW_DEBUG_LED("Activity LED Off\n");
878
879 priv->status &= ~STATUS_LED_ACT_ON;
880 }
881
882 spin_unlock_irqrestore(&priv->lock, flags);
883}
884
885static void ipw_bg_led_activity_off(void *data)
886{
887 struct ipw_priv *priv = data;
888 down(&priv->sem);
889 ipw_led_activity_off(data);
890 up(&priv->sem);
891}
892
893void ipw_led_band_on(struct ipw_priv *priv)
894{
895 unsigned long flags;
896 u32 led;
897
898 /* Only nic type 1 supports mode LEDs */
899 if (priv->config & CFG_NO_LED ||
900 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
901 return;
902
903 spin_lock_irqsave(&priv->lock, flags);
904
905 led = ipw_read_reg32(priv, IPW_EVENT_REG);
906 if (priv->assoc_network->mode == IEEE_A) {
907 led |= priv->led_ofdm_on;
908 led &= priv->led_association_off;
909 IPW_DEBUG_LED("Mode LED On: 802.11a\n");
910 } else if (priv->assoc_network->mode == IEEE_G) {
911 led |= priv->led_ofdm_on;
912 led |= priv->led_association_on;
913 IPW_DEBUG_LED("Mode LED On: 802.11g\n");
914 } else {
915 led &= priv->led_ofdm_off;
916 led |= priv->led_association_on;
917 IPW_DEBUG_LED("Mode LED On: 802.11b\n");
918 }
919
920 led = ipw_register_toggle(led);
921
922 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
923 ipw_write_reg32(priv, IPW_EVENT_REG, led);
924
925 spin_unlock_irqrestore(&priv->lock, flags);
926}
927
928void ipw_led_band_off(struct ipw_priv *priv)
929{
930 unsigned long flags;
931 u32 led;
932
933 /* Only nic type 1 supports mode LEDs */
934 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
935 return;
936
937 spin_lock_irqsave(&priv->lock, flags);
938
939 led = ipw_read_reg32(priv, IPW_EVENT_REG);
940 led &= priv->led_ofdm_off;
941 led &= priv->led_association_off;
942
943 led = ipw_register_toggle(led);
944
945 IPW_DEBUG_LED("Reg: 0x%08X\n", led);
946 ipw_write_reg32(priv, IPW_EVENT_REG, led);
947
948 spin_unlock_irqrestore(&priv->lock, flags);
949}
950
951void ipw_led_radio_on(struct ipw_priv *priv)
952{
953 ipw_led_link_on(priv);
954}
955
956void ipw_led_radio_off(struct ipw_priv *priv)
957{
958 ipw_led_activity_off(priv);
959 ipw_led_link_off(priv);
960}
961
962void ipw_led_link_up(struct ipw_priv *priv)
963{
964 /* Set the Link Led on for all nic types */
965 ipw_led_link_on(priv);
966}
967
968void ipw_led_link_down(struct ipw_priv *priv)
969{
970 ipw_led_activity_off(priv);
971 ipw_led_link_off(priv);
972
973 if (priv->status & STATUS_RF_KILL_MASK)
974 ipw_led_radio_off(priv);
975}
976
977void ipw_led_init(struct ipw_priv *priv)
978{
979 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
980
981 /* Set the default PINs for the link and activity leds */
982 priv->led_activity_on = IPW_ACTIVITY_LED;
983 priv->led_activity_off = ~(IPW_ACTIVITY_LED);
984
985 priv->led_association_on = IPW_ASSOCIATED_LED;
986 priv->led_association_off = ~(IPW_ASSOCIATED_LED);
987
988 /* Set the default PINs for the OFDM leds */
989 priv->led_ofdm_on = IPW_OFDM_LED;
990 priv->led_ofdm_off = ~(IPW_OFDM_LED);
991
992 switch (priv->nic_type) {
993 case EEPROM_NIC_TYPE_1:
994 /* In this NIC type, the LEDs are reversed.... */
995 priv->led_activity_on = IPW_ASSOCIATED_LED;
996 priv->led_activity_off = ~(IPW_ASSOCIATED_LED);
997 priv->led_association_on = IPW_ACTIVITY_LED;
998 priv->led_association_off = ~(IPW_ACTIVITY_LED);
999
1000 if (!(priv->config & CFG_NO_LED))
1001 ipw_led_band_on(priv);
1002
1003 /* And we don't blink link LEDs for this nic, so
1004 * just return here */
1005 return;
1006
1007 case EEPROM_NIC_TYPE_3:
1008 case EEPROM_NIC_TYPE_2:
1009 case EEPROM_NIC_TYPE_4:
1010 case EEPROM_NIC_TYPE_0:
1011 break;
1012
1013 default:
1014 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
1015 priv->nic_type);
1016 priv->nic_type = EEPROM_NIC_TYPE_0;
1017 break;
1018 }
1019
1020 if (!(priv->config & CFG_NO_LED)) {
1021 if (priv->status & STATUS_ASSOCIATED)
1022 ipw_led_link_on(priv);
1023 else
1024 ipw_led_link_off(priv);
1025 }
1026}
1027
1028void ipw_led_shutdown(struct ipw_priv *priv)
1029{
1030 ipw_led_activity_off(priv);
1031 ipw_led_link_off(priv);
1032 ipw_led_band_off(priv);
1033 cancel_delayed_work(&priv->led_link_on);
1034 cancel_delayed_work(&priv->led_link_off);
1035 cancel_delayed_work(&priv->led_act_off);
1036}
1037
639/* 1038/*
640 * The following adds a new attribute to the sysfs representation 1039 * The following adds a new attribute to the sysfs representation
641 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/) 1040 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
@@ -647,8 +1046,9 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
647{ 1046{
648 return sprintf(buf, "0x%08X\n", ipw_debug_level); 1047 return sprintf(buf, "0x%08X\n", ipw_debug_level);
649} 1048}
650static ssize_t store_debug_level(struct device_driver *d, 1049
651 const char *buf, size_t count) 1050static ssize_t store_debug_level(struct device_driver *d, const char *buf,
1051 size_t count)
652{ 1052{
653 char *p = (char *)buf; 1053 char *p = (char *)buf;
654 u32 val; 1054 u32 val;
@@ -672,75 +1072,263 @@ static ssize_t store_debug_level(struct device_driver *d,
672static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, 1072static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
673 show_debug_level, store_debug_level); 1073 show_debug_level, store_debug_level);
674 1074
675static ssize_t show_status(struct device *d, 1075static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
676 struct device_attribute *attr, char *buf)
677{ 1076{
678 struct ipw_priv *p = d->driver_data; 1077 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
679 return sprintf(buf, "0x%08x\n", (int)p->status);
680} 1078}
681 1079
682static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 1080static void ipw_capture_event_log(struct ipw_priv *priv,
1081 u32 log_len, struct ipw_event *log)
1082{
1083 u32 base;
683 1084
684static ssize_t show_cfg(struct device *d, struct device_attribute *attr, 1085 if (log_len) {
685 char *buf) 1086 base = ipw_read32(priv, IPW_EVENT_LOG);
1087 ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
1088 (u8 *) log, sizeof(*log) * log_len);
1089 }
1090}
1091
1092static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
686{ 1093{
687 struct ipw_priv *p = d->driver_data; 1094 struct ipw_fw_error *error;
688 return sprintf(buf, "0x%08x\n", (int)p->config); 1095 u32 log_len = ipw_get_event_log_len(priv);
1096 u32 base = ipw_read32(priv, IPW_ERROR_LOG);
1097 u32 elem_len = ipw_read_reg32(priv, base);
1098
1099 error = kmalloc(sizeof(*error) +
1100 sizeof(*error->elem) * elem_len +
1101 sizeof(*error->log) * log_len, GFP_ATOMIC);
1102 if (!error) {
1103 IPW_ERROR("Memory allocation for firmware error log "
1104 "failed.\n");
1105 return NULL;
1106 }
1107 error->jiffies = jiffies;
1108 error->status = priv->status;
1109 error->config = priv->config;
1110 error->elem_len = elem_len;
1111 error->log_len = log_len;
1112 error->elem = (struct ipw_error_elem *)error->payload;
1113 error->log = (struct ipw_event *)(error->elem +
1114 (sizeof(*error->elem) * elem_len));
1115
1116 ipw_capture_event_log(priv, log_len, error->log);
1117
1118 if (elem_len)
1119 ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
1120 sizeof(*error->elem) * elem_len);
1121
1122 return error;
689} 1123}
690 1124
691static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL); 1125static void ipw_free_error_log(struct ipw_fw_error *error)
1126{
1127 if (error)
1128 kfree(error);
1129}
692 1130
693static ssize_t show_nic_type(struct device *d, 1131static ssize_t show_event_log(struct device *d,
694 struct device_attribute *attr, char *buf) 1132 struct device_attribute *attr, char *buf)
695{ 1133{
696 struct ipw_priv *p = d->driver_data; 1134 struct ipw_priv *priv = dev_get_drvdata(d);
697 u8 type = p->eeprom[EEPROM_NIC_TYPE]; 1135 u32 log_len = ipw_get_event_log_len(priv);
1136 struct ipw_event log[log_len];
1137 u32 len = 0, i;
1138
1139 ipw_capture_event_log(priv, log_len, log);
1140
1141 len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
1142 for (i = 0; i < log_len; i++)
1143 len += snprintf(buf + len, PAGE_SIZE - len,
1144 "\n%08X%08X%08X",
1145 log[i].time, log[i].event, log[i].data);
1146 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1147 return len;
1148}
698 1149
699 switch (type) { 1150static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
700 case EEPROM_NIC_TYPE_STANDARD: 1151
701 return sprintf(buf, "STANDARD\n"); 1152static ssize_t show_error(struct device *d,
702 case EEPROM_NIC_TYPE_DELL: 1153 struct device_attribute *attr, char *buf)
703 return sprintf(buf, "DELL\n"); 1154{
704 case EEPROM_NIC_TYPE_FUJITSU: 1155 struct ipw_priv *priv = dev_get_drvdata(d);
705 return sprintf(buf, "FUJITSU\n"); 1156 u32 len = 0, i;
706 case EEPROM_NIC_TYPE_IBM: 1157 if (!priv->error)
707 return sprintf(buf, "IBM\n"); 1158 return 0;
708 case EEPROM_NIC_TYPE_HP: 1159 len += snprintf(buf + len, PAGE_SIZE - len,
709 return sprintf(buf, "HP\n"); 1160 "%08lX%08X%08X%08X",
1161 priv->error->jiffies,
1162 priv->error->status,
1163 priv->error->config, priv->error->elem_len);
1164 for (i = 0; i < priv->error->elem_len; i++)
1165 len += snprintf(buf + len, PAGE_SIZE - len,
1166 "\n%08X%08X%08X%08X%08X%08X%08X",
1167 priv->error->elem[i].time,
1168 priv->error->elem[i].desc,
1169 priv->error->elem[i].blink1,
1170 priv->error->elem[i].blink2,
1171 priv->error->elem[i].link1,
1172 priv->error->elem[i].link2,
1173 priv->error->elem[i].data);
1174
1175 len += snprintf(buf + len, PAGE_SIZE - len,
1176 "\n%08X", priv->error->log_len);
1177 for (i = 0; i < priv->error->log_len; i++)
1178 len += snprintf(buf + len, PAGE_SIZE - len,
1179 "\n%08X%08X%08X",
1180 priv->error->log[i].time,
1181 priv->error->log[i].event,
1182 priv->error->log[i].data);
1183 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1184 return len;
1185}
1186
1187static ssize_t clear_error(struct device *d,
1188 struct device_attribute *attr,
1189 const char *buf, size_t count)
1190{
1191 struct ipw_priv *priv = dev_get_drvdata(d);
1192 if (priv->error) {
1193 ipw_free_error_log(priv->error);
1194 priv->error = NULL;
710 } 1195 }
1196 return count;
1197}
1198
1199static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
711 1200
712 return sprintf(buf, "UNKNOWN\n"); 1201static ssize_t show_cmd_log(struct device *d,
1202 struct device_attribute *attr, char *buf)
1203{
1204 struct ipw_priv *priv = dev_get_drvdata(d);
1205 u32 len = 0, i;
1206 if (!priv->cmdlog)
1207 return 0;
1208 for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;
1209 (i != priv->cmdlog_pos) && (PAGE_SIZE - len);
1210 i = (i + 1) % priv->cmdlog_len) {
1211 len +=
1212 snprintf(buf + len, PAGE_SIZE - len,
1213 "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
1214 priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
1215 priv->cmdlog[i].cmd.len);
1216 len +=
1217 snprintk_buf(buf + len, PAGE_SIZE - len,
1218 (u8 *) priv->cmdlog[i].cmd.param,
1219 priv->cmdlog[i].cmd.len);
1220 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1221 }
1222 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
1223 return len;
713} 1224}
714 1225
715static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL); 1226static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
716 1227
717static ssize_t dump_error_log(struct device *d, 1228static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
718 struct device_attribute *attr, const char *buf, 1229 char *buf)
719 size_t count)
720{ 1230{
721 char *p = (char *)buf; 1231 struct ipw_priv *priv = dev_get_drvdata(d);
1232 return sprintf(buf, "%d\n", priv->ieee->scan_age);
1233}
722 1234
723 if (p[0] == '1') 1235static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
724 ipw_dump_nic_error_log((struct ipw_priv *)d->driver_data); 1236 const char *buf, size_t count)
1237{
1238 struct ipw_priv *priv = dev_get_drvdata(d);
1239#ifdef CONFIG_IPW_DEBUG
1240 struct net_device *dev = priv->net_dev;
1241#endif
1242 char buffer[] = "00000000";
1243 unsigned long len =
1244 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
1245 unsigned long val;
1246 char *p = buffer;
725 1247
726 return strnlen(buf, count); 1248 IPW_DEBUG_INFO("enter\n");
1249
1250 strncpy(buffer, buf, len);
1251 buffer[len] = 0;
1252
1253 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
1254 p++;
1255 if (p[0] == 'x' || p[0] == 'X')
1256 p++;
1257 val = simple_strtoul(p, &p, 16);
1258 } else
1259 val = simple_strtoul(p, &p, 10);
1260 if (p == buffer) {
1261 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
1262 } else {
1263 priv->ieee->scan_age = val;
1264 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
1265 }
1266
1267 IPW_DEBUG_INFO("exit\n");
1268 return len;
727} 1269}
728 1270
729static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log); 1271static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
730 1272
731static ssize_t dump_event_log(struct device *d, 1273static ssize_t show_led(struct device *d, struct device_attribute *attr,
732 struct device_attribute *attr, const char *buf, 1274 char *buf)
733 size_t count)
734{ 1275{
735 char *p = (char *)buf; 1276 struct ipw_priv *priv = dev_get_drvdata(d);
1277 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
1278}
736 1279
737 if (p[0] == '1') 1280static ssize_t store_led(struct device *d, struct device_attribute *attr,
738 ipw_dump_nic_event_log((struct ipw_priv *)d->driver_data); 1281 const char *buf, size_t count)
1282{
1283 struct ipw_priv *priv = dev_get_drvdata(d);
739 1284
740 return strnlen(buf, count); 1285 IPW_DEBUG_INFO("enter\n");
1286
1287 if (count == 0)
1288 return 0;
1289
1290 if (*buf == 0) {
1291 IPW_DEBUG_LED("Disabling LED control.\n");
1292 priv->config |= CFG_NO_LED;
1293 ipw_led_shutdown(priv);
1294 } else {
1295 IPW_DEBUG_LED("Enabling LED control.\n");
1296 priv->config &= ~CFG_NO_LED;
1297 ipw_led_init(priv);
1298 }
1299
1300 IPW_DEBUG_INFO("exit\n");
1301 return count;
1302}
1303
1304static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
1305
1306static ssize_t show_status(struct device *d,
1307 struct device_attribute *attr, char *buf)
1308{
1309 struct ipw_priv *p = d->driver_data;
1310 return sprintf(buf, "0x%08x\n", (int)p->status);
741} 1311}
742 1312
743static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); 1313static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
1314
1315static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
1316 char *buf)
1317{
1318 struct ipw_priv *p = d->driver_data;
1319 return sprintf(buf, "0x%08x\n", (int)p->config);
1320}
1321
1322static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
1323
1324static ssize_t show_nic_type(struct device *d,
1325 struct device_attribute *attr, char *buf)
1326{
1327 struct ipw_priv *priv = d->driver_data;
1328 return sprintf(buf, "TYPE: %d\n", priv->nic_type);
1329}
1330
1331static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
744 1332
745static ssize_t show_ucode_version(struct device *d, 1333static ssize_t show_ucode_version(struct device *d,
746 struct device_attribute *attr, char *buf) 1334 struct device_attribute *attr, char *buf)
@@ -798,7 +1386,7 @@ static ssize_t show_command_event_reg(struct device *d,
798 u32 reg = 0; 1386 u32 reg = 0;
799 struct ipw_priv *p = d->driver_data; 1387 struct ipw_priv *p = d->driver_data;
800 1388
801 reg = ipw_read_reg32(p, CX2_INTERNAL_CMD_EVENT); 1389 reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
802 return sprintf(buf, "0x%08x\n", reg); 1390 return sprintf(buf, "0x%08x\n", reg);
803} 1391}
804static ssize_t store_command_event_reg(struct device *d, 1392static ssize_t store_command_event_reg(struct device *d,
@@ -809,7 +1397,7 @@ static ssize_t store_command_event_reg(struct device *d,
809 struct ipw_priv *p = d->driver_data; 1397 struct ipw_priv *p = d->driver_data;
810 1398
811 sscanf(buf, "%x", &reg); 1399 sscanf(buf, "%x", &reg);
812 ipw_write_reg32(p, CX2_INTERNAL_CMD_EVENT, reg); 1400 ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
813 return strnlen(buf, count); 1401 return strnlen(buf, count);
814} 1402}
815 1403
@@ -845,6 +1433,7 @@ static ssize_t show_indirect_dword(struct device *d,
845{ 1433{
846 u32 reg = 0; 1434 u32 reg = 0;
847 struct ipw_priv *priv = d->driver_data; 1435 struct ipw_priv *priv = d->driver_data;
1436
848 if (priv->status & STATUS_INDIRECT_DWORD) 1437 if (priv->status & STATUS_INDIRECT_DWORD)
849 reg = ipw_read_reg32(priv, priv->indirect_dword); 1438 reg = ipw_read_reg32(priv, priv->indirect_dword);
850 else 1439 else
@@ -871,6 +1460,7 @@ static ssize_t show_indirect_byte(struct device *d,
871{ 1460{
872 u8 reg = 0; 1461 u8 reg = 0;
873 struct ipw_priv *priv = d->driver_data; 1462 struct ipw_priv *priv = d->driver_data;
1463
874 if (priv->status & STATUS_INDIRECT_BYTE) 1464 if (priv->status & STATUS_INDIRECT_BYTE)
875 reg = ipw_read_reg8(priv, priv->indirect_byte); 1465 reg = ipw_read_reg8(priv, priv->indirect_byte);
876 else 1466 else
@@ -945,7 +1535,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
945static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) 1535static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
946{ 1536{
947 if ((disable_radio ? 1 : 0) == 1537 if ((disable_radio ? 1 : 0) ==
948 (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) 1538 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
949 return 0; 1539 return 0;
950 1540
951 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 1541 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
@@ -954,10 +1544,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
954 if (disable_radio) { 1544 if (disable_radio) {
955 priv->status |= STATUS_RF_KILL_SW; 1545 priv->status |= STATUS_RF_KILL_SW;
956 1546
957 if (priv->workqueue) { 1547 if (priv->workqueue)
958 cancel_delayed_work(&priv->request_scan); 1548 cancel_delayed_work(&priv->request_scan);
959 }
960 wake_up_interruptible(&priv->wait_command_queue);
961 queue_work(priv->workqueue, &priv->down); 1549 queue_work(priv->workqueue, &priv->down);
962 } else { 1550 } else {
963 priv->status &= ~STATUS_RF_KILL_SW; 1551 priv->status &= ~STATUS_RF_KILL_SW;
@@ -987,6 +1575,93 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
987 1575
988static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); 1576static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
989 1577
1578static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
1579 char *buf)
1580{
1581 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1582 int pos = 0, len = 0;
1583 if (priv->config & CFG_SPEED_SCAN) {
1584 while (priv->speed_scan[pos] != 0)
1585 len += sprintf(&buf[len], "%d ",
1586 priv->speed_scan[pos++]);
1587 return len + sprintf(&buf[len], "\n");
1588 }
1589
1590 return sprintf(buf, "0\n");
1591}
1592
1593static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
1594 const char *buf, size_t count)
1595{
1596 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1597 int channel, pos = 0;
1598 const char *p = buf;
1599
1600 /* list of space separated channels to scan, optionally ending with 0 */
1601 while ((channel = simple_strtol(p, NULL, 0))) {
1602 if (pos == MAX_SPEED_SCAN - 1) {
1603 priv->speed_scan[pos] = 0;
1604 break;
1605 }
1606
1607 if (ipw_is_valid_channel(priv->ieee, channel))
1608 priv->speed_scan[pos++] = channel;
1609 else
1610 IPW_WARNING("Skipping invalid channel request: %d\n",
1611 channel);
1612 p = strchr(p, ' ');
1613 if (!p)
1614 break;
1615 while (*p == ' ' || *p == '\t')
1616 p++;
1617 }
1618
1619 if (pos == 0)
1620 priv->config &= ~CFG_SPEED_SCAN;
1621 else {
1622 priv->speed_scan_pos = 0;
1623 priv->config |= CFG_SPEED_SCAN;
1624 }
1625
1626 return count;
1627}
1628
1629static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
1630 store_speed_scan);
1631
1632static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
1633 char *buf)
1634{
1635 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1636 return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
1637}
1638
1639static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
1640 const char *buf, size_t count)
1641{
1642 struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
1643 if (buf[0] == '1')
1644 priv->config |= CFG_NET_STATS;
1645 else
1646 priv->config &= ~CFG_NET_STATS;
1647
1648 return count;
1649}
1650
1651static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
1652 show_net_stats, store_net_stats);
1653
1654static void notify_wx_assoc_event(struct ipw_priv *priv)
1655{
1656 union iwreq_data wrqu;
1657 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1658 if (priv->status & STATUS_ASSOCIATED)
1659 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
1660 else
1661 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1662 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1663}
1664
990static void ipw_irq_tasklet(struct ipw_priv *priv) 1665static void ipw_irq_tasklet(struct ipw_priv *priv)
991{ 1666{
992 u32 inta, inta_mask, handled = 0; 1667 u32 inta, inta_mask, handled = 0;
@@ -995,102 +1670,135 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
995 1670
996 spin_lock_irqsave(&priv->lock, flags); 1671 spin_lock_irqsave(&priv->lock, flags);
997 1672
998 inta = ipw_read32(priv, CX2_INTA_RW); 1673 inta = ipw_read32(priv, IPW_INTA_RW);
999 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R); 1674 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
1000 inta &= (CX2_INTA_MASK_ALL & inta_mask); 1675 inta &= (IPW_INTA_MASK_ALL & inta_mask);
1001 1676
1002 /* Add any cached INTA values that need to be handled */ 1677 /* Add any cached INTA values that need to be handled */
1003 inta |= priv->isr_inta; 1678 inta |= priv->isr_inta;
1004 1679
1005 /* handle all the justifications for the interrupt */ 1680 /* handle all the justifications for the interrupt */
1006 if (inta & CX2_INTA_BIT_RX_TRANSFER) { 1681 if (inta & IPW_INTA_BIT_RX_TRANSFER) {
1007 ipw_rx(priv); 1682 ipw_rx(priv);
1008 handled |= CX2_INTA_BIT_RX_TRANSFER; 1683 handled |= IPW_INTA_BIT_RX_TRANSFER;
1009 } 1684 }
1010 1685
1011 if (inta & CX2_INTA_BIT_TX_CMD_QUEUE) { 1686 if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {
1012 IPW_DEBUG_HC("Command completed.\n"); 1687 IPW_DEBUG_HC("Command completed.\n");
1013 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1); 1688 rc = ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);
1014 priv->status &= ~STATUS_HCMD_ACTIVE; 1689 priv->status &= ~STATUS_HCMD_ACTIVE;
1015 wake_up_interruptible(&priv->wait_command_queue); 1690 wake_up_interruptible(&priv->wait_command_queue);
1016 handled |= CX2_INTA_BIT_TX_CMD_QUEUE; 1691 handled |= IPW_INTA_BIT_TX_CMD_QUEUE;
1017 } 1692 }
1018 1693
1019 if (inta & CX2_INTA_BIT_TX_QUEUE_1) { 1694 if (inta & IPW_INTA_BIT_TX_QUEUE_1) {
1020 IPW_DEBUG_TX("TX_QUEUE_1\n"); 1695 IPW_DEBUG_TX("TX_QUEUE_1\n");
1021 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0); 1696 rc = ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);
1022 handled |= CX2_INTA_BIT_TX_QUEUE_1; 1697 handled |= IPW_INTA_BIT_TX_QUEUE_1;
1023 } 1698 }
1024 1699
1025 if (inta & CX2_INTA_BIT_TX_QUEUE_2) { 1700 if (inta & IPW_INTA_BIT_TX_QUEUE_2) {
1026 IPW_DEBUG_TX("TX_QUEUE_2\n"); 1701 IPW_DEBUG_TX("TX_QUEUE_2\n");
1027 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1); 1702 rc = ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);
1028 handled |= CX2_INTA_BIT_TX_QUEUE_2; 1703 handled |= IPW_INTA_BIT_TX_QUEUE_2;
1029 } 1704 }
1030 1705
1031 if (inta & CX2_INTA_BIT_TX_QUEUE_3) { 1706 if (inta & IPW_INTA_BIT_TX_QUEUE_3) {
1032 IPW_DEBUG_TX("TX_QUEUE_3\n"); 1707 IPW_DEBUG_TX("TX_QUEUE_3\n");
1033 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2); 1708 rc = ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);
1034 handled |= CX2_INTA_BIT_TX_QUEUE_3; 1709 handled |= IPW_INTA_BIT_TX_QUEUE_3;
1035 } 1710 }
1036 1711
1037 if (inta & CX2_INTA_BIT_TX_QUEUE_4) { 1712 if (inta & IPW_INTA_BIT_TX_QUEUE_4) {
1038 IPW_DEBUG_TX("TX_QUEUE_4\n"); 1713 IPW_DEBUG_TX("TX_QUEUE_4\n");
1039 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3); 1714 rc = ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);
1040 handled |= CX2_INTA_BIT_TX_QUEUE_4; 1715 handled |= IPW_INTA_BIT_TX_QUEUE_4;
1041 } 1716 }
1042 1717
1043 if (inta & CX2_INTA_BIT_STATUS_CHANGE) { 1718 if (inta & IPW_INTA_BIT_STATUS_CHANGE) {
1044 IPW_WARNING("STATUS_CHANGE\n"); 1719 IPW_WARNING("STATUS_CHANGE\n");
1045 handled |= CX2_INTA_BIT_STATUS_CHANGE; 1720 handled |= IPW_INTA_BIT_STATUS_CHANGE;
1046 } 1721 }
1047 1722
1048 if (inta & CX2_INTA_BIT_BEACON_PERIOD_EXPIRED) { 1723 if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {
1049 IPW_WARNING("TX_PERIOD_EXPIRED\n"); 1724 IPW_WARNING("TX_PERIOD_EXPIRED\n");
1050 handled |= CX2_INTA_BIT_BEACON_PERIOD_EXPIRED; 1725 handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;
1051 } 1726 }
1052 1727
1053 if (inta & CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) { 1728 if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {
1054 IPW_WARNING("HOST_CMD_DONE\n"); 1729 IPW_WARNING("HOST_CMD_DONE\n");
1055 handled |= CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE; 1730 handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;
1056 } 1731 }
1057 1732
1058 if (inta & CX2_INTA_BIT_FW_INITIALIZATION_DONE) { 1733 if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {
1059 IPW_WARNING("FW_INITIALIZATION_DONE\n"); 1734 IPW_WARNING("FW_INITIALIZATION_DONE\n");
1060 handled |= CX2_INTA_BIT_FW_INITIALIZATION_DONE; 1735 handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;
1061 } 1736 }
1062 1737
1063 if (inta & CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) { 1738 if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {
1064 IPW_WARNING("PHY_OFF_DONE\n"); 1739 IPW_WARNING("PHY_OFF_DONE\n");
1065 handled |= CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE; 1740 handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;
1066 } 1741 }
1067 1742
1068 if (inta & CX2_INTA_BIT_RF_KILL_DONE) { 1743 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
1069 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); 1744 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
1070 priv->status |= STATUS_RF_KILL_HW; 1745 priv->status |= STATUS_RF_KILL_HW;
1071 wake_up_interruptible(&priv->wait_command_queue); 1746 wake_up_interruptible(&priv->wait_command_queue);
1072 netif_carrier_off(priv->net_dev); 1747 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1073 netif_stop_queue(priv->net_dev);
1074 cancel_delayed_work(&priv->request_scan); 1748 cancel_delayed_work(&priv->request_scan);
1749 schedule_work(&priv->link_down);
1075 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); 1750 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
1076 handled |= CX2_INTA_BIT_RF_KILL_DONE; 1751 handled |= IPW_INTA_BIT_RF_KILL_DONE;
1077 } 1752 }
1078 1753
1079 if (inta & CX2_INTA_BIT_FATAL_ERROR) { 1754 if (inta & IPW_INTA_BIT_FATAL_ERROR) {
1080 IPW_ERROR("Firmware error detected. Restarting.\n"); 1755 IPW_ERROR("Firmware error detected. Restarting.\n");
1756 if (priv->error) {
1757 IPW_ERROR("Sysfs 'error' log already exists.\n");
1081#ifdef CONFIG_IPW_DEBUG 1758#ifdef CONFIG_IPW_DEBUG
1082 if (ipw_debug_level & IPW_DL_FW_ERRORS) { 1759 if (ipw_debug_level & IPW_DL_FW_ERRORS) {
1083 ipw_dump_nic_error_log(priv); 1760 struct ipw_fw_error *error =
1084 ipw_dump_nic_event_log(priv); 1761 ipw_alloc_error_log(priv);
1085 } 1762 ipw_dump_error_log(priv, error);
1763 if (error)
1764 ipw_free_error_log(error);
1765 }
1086#endif 1766#endif
1767 } else {
1768 priv->error = ipw_alloc_error_log(priv);
1769 if (priv->error)
1770 IPW_ERROR("Sysfs 'error' log captured.\n");
1771 else
1772 IPW_ERROR("Error allocating sysfs 'error' "
1773 "log.\n");
1774#ifdef CONFIG_IPW_DEBUG
1775 if (ipw_debug_level & IPW_DL_FW_ERRORS)
1776 ipw_dump_error_log(priv, priv->error);
1777#endif
1778 }
1779
1780 /* XXX: If hardware encryption is for WPA/WPA2,
1781 * we have to notify the supplicant. */
1782 if (priv->ieee->sec.encrypt) {
1783 priv->status &= ~STATUS_ASSOCIATED;
1784 notify_wx_assoc_event(priv);
1785 }
1786
1787 /* Keep the restart process from trying to send host
1788 * commands by clearing the INIT status bit */
1789 priv->status &= ~STATUS_INIT;
1790
1791 /* Cancel currently queued command. */
1792 priv->status &= ~STATUS_HCMD_ACTIVE;
1793 wake_up_interruptible(&priv->wait_command_queue);
1794
1087 queue_work(priv->workqueue, &priv->adapter_restart); 1795 queue_work(priv->workqueue, &priv->adapter_restart);
1088 handled |= CX2_INTA_BIT_FATAL_ERROR; 1796 handled |= IPW_INTA_BIT_FATAL_ERROR;
1089 } 1797 }
1090 1798
1091 if (inta & CX2_INTA_BIT_PARITY_ERROR) { 1799 if (inta & IPW_INTA_BIT_PARITY_ERROR) {
1092 IPW_ERROR("Parity error\n"); 1800 IPW_ERROR("Parity error\n");
1093 handled |= CX2_INTA_BIT_PARITY_ERROR; 1801 handled |= IPW_INTA_BIT_PARITY_ERROR;
1094 } 1802 }
1095 1803
1096 if (handled != inta) { 1804 if (handled != inta) {
@@ -1103,7 +1811,6 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1103 spin_unlock_irqrestore(&priv->lock, flags); 1811 spin_unlock_irqrestore(&priv->lock, flags);
1104} 1812}
1105 1813
1106#ifdef CONFIG_IPW_DEBUG
1107#define IPW_CMD(x) case IPW_CMD_ ## x : return #x 1814#define IPW_CMD(x) case IPW_CMD_ ## x : return #x
1108static char *get_cmd_string(u8 cmd) 1815static char *get_cmd_string(u8 cmd)
1109{ 1816{
@@ -1162,44 +1869,78 @@ static char *get_cmd_string(u8 cmd)
1162 return "UNKNOWN"; 1869 return "UNKNOWN";
1163 } 1870 }
1164} 1871}
1165#endif /* CONFIG_IPW_DEBUG */
1166 1872
1167#define HOST_COMPLETE_TIMEOUT HZ 1873#define HOST_COMPLETE_TIMEOUT HZ
1168static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) 1874static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
1169{ 1875{
1170 int rc = 0; 1876 int rc = 0;
1877 unsigned long flags;
1171 1878
1879 spin_lock_irqsave(&priv->lock, flags);
1172 if (priv->status & STATUS_HCMD_ACTIVE) { 1880 if (priv->status & STATUS_HCMD_ACTIVE) {
1173 IPW_ERROR("Already sending a command\n"); 1881 IPW_ERROR("Failed to send %s: Already sending a command.\n",
1174 return -1; 1882 get_cmd_string(cmd->cmd));
1883 spin_unlock_irqrestore(&priv->lock, flags);
1884 return -EAGAIN;
1175 } 1885 }
1176 1886
1177 priv->status |= STATUS_HCMD_ACTIVE; 1887 priv->status |= STATUS_HCMD_ACTIVE;
1178 1888
1179 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n", 1889 if (priv->cmdlog) {
1180 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len); 1890 priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;
1891 priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;
1892 priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;
1893 memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,
1894 cmd->len);
1895 priv->cmdlog[priv->cmdlog_pos].retcode = -1;
1896 }
1897
1898 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
1899 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
1900 priv->status);
1181 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len); 1901 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
1182 1902
1183 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0); 1903 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
1184 if (rc) 1904 if (rc) {
1185 return rc; 1905 priv->status &= ~STATUS_HCMD_ACTIVE;
1906 IPW_ERROR("Failed to send %s: Reason %d\n",
1907 get_cmd_string(cmd->cmd), rc);
1908 spin_unlock_irqrestore(&priv->lock, flags);
1909 goto exit;
1910 }
1911 spin_unlock_irqrestore(&priv->lock, flags);
1186 1912
1187 rc = wait_event_interruptible_timeout(priv->wait_command_queue, 1913 rc = wait_event_interruptible_timeout(priv->wait_command_queue,
1188 !(priv-> 1914 !(priv->
1189 status & STATUS_HCMD_ACTIVE), 1915 status & STATUS_HCMD_ACTIVE),
1190 HOST_COMPLETE_TIMEOUT); 1916 HOST_COMPLETE_TIMEOUT);
1191 if (rc == 0) { 1917 if (rc == 0) {
1192 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 1918 spin_lock_irqsave(&priv->lock, flags);
1193 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); 1919 if (priv->status & STATUS_HCMD_ACTIVE) {
1194 priv->status &= ~STATUS_HCMD_ACTIVE; 1920 IPW_ERROR("Failed to send %s: Command timed out.\n",
1195 return -EIO; 1921 get_cmd_string(cmd->cmd));
1196 } 1922 priv->status &= ~STATUS_HCMD_ACTIVE;
1197 if (priv->status & STATUS_RF_KILL_MASK) { 1923 spin_unlock_irqrestore(&priv->lock, flags);
1198 IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n"); 1924 rc = -EIO;
1199 return -EIO; 1925 goto exit;
1926 }
1927 spin_unlock_irqrestore(&priv->lock, flags);
1928 } else
1929 rc = 0;
1930
1931 if (priv->status & STATUS_RF_KILL_HW) {
1932 IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
1933 get_cmd_string(cmd->cmd));
1934 rc = -EIO;
1935 goto exit;
1200 } 1936 }
1201 1937
1202 return 0; 1938 exit:
1939 if (priv->cmdlog) {
1940 priv->cmdlog[priv->cmdlog_pos++].retcode = rc;
1941 priv->cmdlog_pos %= priv->cmdlog_len;
1942 }
1943 return rc;
1203} 1944}
1204 1945
1205static int ipw_send_host_complete(struct ipw_priv *priv) 1946static int ipw_send_host_complete(struct ipw_priv *priv)
@@ -1214,12 +1955,7 @@ static int ipw_send_host_complete(struct ipw_priv *priv)
1214 return -1; 1955 return -1;
1215 } 1956 }
1216 1957
1217 if (ipw_send_cmd(priv, &cmd)) { 1958 return ipw_send_cmd(priv, &cmd);
1218 IPW_ERROR("failed to send HOST_COMPLETE command\n");
1219 return -1;
1220 }
1221
1222 return 0;
1223} 1959}
1224 1960
1225static int ipw_send_system_config(struct ipw_priv *priv, 1961static int ipw_send_system_config(struct ipw_priv *priv,
@@ -1235,13 +1971,8 @@ static int ipw_send_system_config(struct ipw_priv *priv,
1235 return -1; 1971 return -1;
1236 } 1972 }
1237 1973
1238 memcpy(&cmd.param, config, sizeof(*config)); 1974 memcpy(cmd.param, config, sizeof(*config));
1239 if (ipw_send_cmd(priv, &cmd)) { 1975 return ipw_send_cmd(priv, &cmd);
1240 IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
1241 return -1;
1242 }
1243
1244 return 0;
1245} 1976}
1246 1977
1247static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) 1978static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
@@ -1256,13 +1987,8 @@ static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
1256 return -1; 1987 return -1;
1257 } 1988 }
1258 1989
1259 memcpy(&cmd.param, ssid, cmd.len); 1990 memcpy(cmd.param, ssid, cmd.len);
1260 if (ipw_send_cmd(priv, &cmd)) { 1991 return ipw_send_cmd(priv, &cmd);
1261 IPW_ERROR("failed to send SSID command\n");
1262 return -1;
1263 }
1264
1265 return 0;
1266} 1992}
1267 1993
1268static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac) 1994static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
@@ -1280,16 +2006,15 @@ static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
1280 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n", 2006 IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
1281 priv->net_dev->name, MAC_ARG(mac)); 2007 priv->net_dev->name, MAC_ARG(mac));
1282 2008
1283 memcpy(&cmd.param, mac, ETH_ALEN); 2009 memcpy(cmd.param, mac, ETH_ALEN);
1284 2010 return ipw_send_cmd(priv, &cmd);
1285 if (ipw_send_cmd(priv, &cmd)) {
1286 IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
1287 return -1;
1288 }
1289
1290 return 0;
1291} 2011}
1292 2012
2013/*
2014 * NOTE: This must be executed from our workqueue as it results in udelay
2015 * being called which may corrupt the keyboard if executed on default
2016 * workqueue
2017 */
1293static void ipw_adapter_restart(void *adapter) 2018static void ipw_adapter_restart(void *adapter)
1294{ 2019{
1295 struct ipw_priv *priv = adapter; 2020 struct ipw_priv *priv = adapter;
@@ -1298,12 +2023,25 @@ static void ipw_adapter_restart(void *adapter)
1298 return; 2023 return;
1299 2024
1300 ipw_down(priv); 2025 ipw_down(priv);
2026
2027 if (priv->assoc_network &&
2028 (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))
2029 ipw_remove_current_network(priv);
2030
1301 if (ipw_up(priv)) { 2031 if (ipw_up(priv)) {
1302 IPW_ERROR("Failed to up device\n"); 2032 IPW_ERROR("Failed to up device\n");
1303 return; 2033 return;
1304 } 2034 }
1305} 2035}
1306 2036
2037static void ipw_bg_adapter_restart(void *data)
2038{
2039 struct ipw_priv *priv = data;
2040 down(&priv->sem);
2041 ipw_adapter_restart(data);
2042 up(&priv->sem);
2043}
2044
1307#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ) 2045#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
1308 2046
1309static void ipw_scan_check(void *data) 2047static void ipw_scan_check(void *data)
@@ -1313,10 +2051,18 @@ static void ipw_scan_check(void *data)
1313 IPW_DEBUG_SCAN("Scan completion watchdog resetting " 2051 IPW_DEBUG_SCAN("Scan completion watchdog resetting "
1314 "adapter (%dms).\n", 2052 "adapter (%dms).\n",
1315 IPW_SCAN_CHECK_WATCHDOG / 100); 2053 IPW_SCAN_CHECK_WATCHDOG / 100);
1316 ipw_adapter_restart(priv); 2054 queue_work(priv->workqueue, &priv->adapter_restart);
1317 } 2055 }
1318} 2056}
1319 2057
2058static void ipw_bg_scan_check(void *data)
2059{
2060 struct ipw_priv *priv = data;
2061 down(&priv->sem);
2062 ipw_scan_check(data);
2063 up(&priv->sem);
2064}
2065
1320static int ipw_send_scan_request_ext(struct ipw_priv *priv, 2066static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1321 struct ipw_scan_request_ext *request) 2067 struct ipw_scan_request_ext *request)
1322{ 2068{
@@ -1325,20 +2071,8 @@ static int ipw_send_scan_request_ext(struct ipw_priv *priv,
1325 .len = sizeof(*request) 2071 .len = sizeof(*request)
1326 }; 2072 };
1327 2073
1328 if (!priv || !request) { 2074 memcpy(cmd.param, request, sizeof(*request));
1329 IPW_ERROR("Invalid args\n"); 2075 return ipw_send_cmd(priv, &cmd);
1330 return -1;
1331 }
1332
1333 memcpy(&cmd.param, request, sizeof(*request));
1334 if (ipw_send_cmd(priv, &cmd)) {
1335 IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
1336 return -1;
1337 }
1338
1339 queue_delayed_work(priv->workqueue, &priv->scan_check,
1340 IPW_SCAN_CHECK_WATCHDOG);
1341 return 0;
1342} 2076}
1343 2077
1344static int ipw_send_scan_abort(struct ipw_priv *priv) 2078static int ipw_send_scan_abort(struct ipw_priv *priv)
@@ -1353,12 +2087,7 @@ static int ipw_send_scan_abort(struct ipw_priv *priv)
1353 return -1; 2087 return -1;
1354 } 2088 }
1355 2089
1356 if (ipw_send_cmd(priv, &cmd)) { 2090 return ipw_send_cmd(priv, &cmd);
1357 IPW_ERROR("failed to send SCAN_ABORT command\n");
1358 return -1;
1359 }
1360
1361 return 0;
1362} 2091}
1363 2092
1364static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) 2093static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
@@ -1370,12 +2099,7 @@ static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
1370 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *) 2099 struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
1371 &cmd.param; 2100 &cmd.param;
1372 calib->beacon_rssi_raw = sens; 2101 calib->beacon_rssi_raw = sens;
1373 if (ipw_send_cmd(priv, &cmd)) { 2102 return ipw_send_cmd(priv, &cmd);
1374 IPW_ERROR("failed to send SENSITIVITY CALIB command\n");
1375 return -1;
1376 }
1377
1378 return 0;
1379} 2103}
1380 2104
1381static int ipw_send_associate(struct ipw_priv *priv, 2105static int ipw_send_associate(struct ipw_priv *priv,
@@ -1386,18 +2110,26 @@ static int ipw_send_associate(struct ipw_priv *priv,
1386 .len = sizeof(*associate) 2110 .len = sizeof(*associate)
1387 }; 2111 };
1388 2112
2113 struct ipw_associate tmp_associate;
2114 memcpy(&tmp_associate, associate, sizeof(*associate));
2115 tmp_associate.policy_support =
2116 cpu_to_le16(tmp_associate.policy_support);
2117 tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
2118 tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
2119 tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
2120 tmp_associate.listen_interval =
2121 cpu_to_le16(tmp_associate.listen_interval);
2122 tmp_associate.beacon_interval =
2123 cpu_to_le16(tmp_associate.beacon_interval);
2124 tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
2125
1389 if (!priv || !associate) { 2126 if (!priv || !associate) {
1390 IPW_ERROR("Invalid args\n"); 2127 IPW_ERROR("Invalid args\n");
1391 return -1; 2128 return -1;
1392 } 2129 }
1393 2130
1394 memcpy(&cmd.param, associate, sizeof(*associate)); 2131 memcpy(cmd.param, &tmp_associate, sizeof(*associate));
1395 if (ipw_send_cmd(priv, &cmd)) { 2132 return ipw_send_cmd(priv, &cmd);
1396 IPW_ERROR("failed to send ASSOCIATE command\n");
1397 return -1;
1398 }
1399
1400 return 0;
1401} 2133}
1402 2134
1403static int ipw_send_supported_rates(struct ipw_priv *priv, 2135static int ipw_send_supported_rates(struct ipw_priv *priv,
@@ -1413,13 +2145,8 @@ static int ipw_send_supported_rates(struct ipw_priv *priv,
1413 return -1; 2145 return -1;
1414 } 2146 }
1415 2147
1416 memcpy(&cmd.param, rates, sizeof(*rates)); 2148 memcpy(cmd.param, rates, sizeof(*rates));
1417 if (ipw_send_cmd(priv, &cmd)) { 2149 return ipw_send_cmd(priv, &cmd);
1418 IPW_ERROR("failed to send SUPPORTED_RATES command\n");
1419 return -1;
1420 }
1421
1422 return 0;
1423} 2150}
1424 2151
1425static int ipw_set_random_seed(struct ipw_priv *priv) 2152static int ipw_set_random_seed(struct ipw_priv *priv)
@@ -1436,15 +2163,9 @@ static int ipw_set_random_seed(struct ipw_priv *priv)
1436 2163
1437 get_random_bytes(&cmd.param, sizeof(u32)); 2164 get_random_bytes(&cmd.param, sizeof(u32));
1438 2165
1439 if (ipw_send_cmd(priv, &cmd)) { 2166 return ipw_send_cmd(priv, &cmd);
1440 IPW_ERROR("failed to send SEED_NUMBER command\n");
1441 return -1;
1442 }
1443
1444 return 0;
1445} 2167}
1446 2168
1447#if 0
1448static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) 2169static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1449{ 2170{
1450 struct host_cmd cmd = { 2171 struct host_cmd cmd = {
@@ -1459,14 +2180,8 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
1459 2180
1460 *((u32 *) & cmd.param) = phy_off; 2181 *((u32 *) & cmd.param) = phy_off;
1461 2182
1462 if (ipw_send_cmd(priv, &cmd)) { 2183 return ipw_send_cmd(priv, &cmd);
1463 IPW_ERROR("failed to send CARD_DISABLE command\n");
1464 return -1;
1465 }
1466
1467 return 0;
1468} 2184}
1469#endif
1470 2185
1471static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power) 2186static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
1472{ 2187{
@@ -1480,12 +2195,51 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
1480 return -1; 2195 return -1;
1481 } 2196 }
1482 2197
1483 memcpy(&cmd.param, power, sizeof(*power)); 2198 memcpy(cmd.param, power, sizeof(*power));
1484 if (ipw_send_cmd(priv, &cmd)) { 2199 return ipw_send_cmd(priv, &cmd);
1485 IPW_ERROR("failed to send TX_POWER command\n"); 2200}
1486 return -1; 2201
2202static int ipw_set_tx_power(struct ipw_priv *priv)
2203{
2204 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
2205 struct ipw_tx_power tx_power;
2206 s8 max_power;
2207 int i;
2208
2209 memset(&tx_power, 0, sizeof(tx_power));
2210
2211 /* configure device for 'G' band */
2212 tx_power.ieee_mode = IPW_G_MODE;
2213 tx_power.num_channels = geo->bg_channels;
2214 for (i = 0; i < geo->bg_channels; i++) {
2215 max_power = geo->bg[i].max_power;
2216 tx_power.channels_tx_power[i].channel_number =
2217 geo->bg[i].channel;
2218 tx_power.channels_tx_power[i].tx_power = max_power ?
2219 min(max_power, priv->tx_power) : priv->tx_power;
1487 } 2220 }
2221 if (ipw_send_tx_power(priv, &tx_power))
2222 return -EIO;
2223
2224 /* configure device to also handle 'B' band */
2225 tx_power.ieee_mode = IPW_B_MODE;
2226 if (ipw_send_tx_power(priv, &tx_power))
2227 return -EIO;
1488 2228
2229 /* configure device to also handle 'A' band */
2230 if (priv->ieee->abg_true) {
2231 tx_power.ieee_mode = IPW_A_MODE;
2232 tx_power.num_channels = geo->a_channels;
2233 for (i = 0; i < tx_power.num_channels; i++) {
2234 max_power = geo->a[i].max_power;
2235 tx_power.channels_tx_power[i].channel_number =
2236 geo->a[i].channel;
2237 tx_power.channels_tx_power[i].tx_power = max_power ?
2238 min(max_power, priv->tx_power) : priv->tx_power;
2239 }
2240 if (ipw_send_tx_power(priv, &tx_power))
2241 return -EIO;
2242 }
1489 return 0; 2243 return 0;
1490} 2244}
1491 2245
@@ -1504,13 +2258,8 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
1504 return -1; 2258 return -1;
1505 } 2259 }
1506 2260
1507 memcpy(&cmd.param, &rts_threshold, sizeof(rts_threshold)); 2261 memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));
1508 if (ipw_send_cmd(priv, &cmd)) { 2262 return ipw_send_cmd(priv, &cmd);
1509 IPW_ERROR("failed to send RTS_THRESHOLD command\n");
1510 return -1;
1511 }
1512
1513 return 0;
1514} 2263}
1515 2264
1516static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) 2265static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
@@ -1528,13 +2277,8 @@ static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
1528 return -1; 2277 return -1;
1529 } 2278 }
1530 2279
1531 memcpy(&cmd.param, &frag_threshold, sizeof(frag_threshold)); 2280 memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));
1532 if (ipw_send_cmd(priv, &cmd)) { 2281 return ipw_send_cmd(priv, &cmd);
1533 IPW_ERROR("failed to send FRAG_THRESHOLD command\n");
1534 return -1;
1535 }
1536
1537 return 0;
1538} 2282}
1539 2283
1540static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) 2284static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
@@ -1564,12 +2308,27 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
1564 break; 2308 break;
1565 } 2309 }
1566 2310
1567 if (ipw_send_cmd(priv, &cmd)) { 2311 return ipw_send_cmd(priv, &cmd);
1568 IPW_ERROR("failed to send POWER_MODE command\n"); 2312}
2313
2314static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
2315{
2316 struct ipw_retry_limit retry_limit = {
2317 .short_retry_limit = slimit,
2318 .long_retry_limit = llimit
2319 };
2320 struct host_cmd cmd = {
2321 .cmd = IPW_CMD_RETRY_LIMIT,
2322 .len = sizeof(retry_limit)
2323 };
2324
2325 if (!priv) {
2326 IPW_ERROR("Invalid args\n");
1569 return -1; 2327 return -1;
1570 } 2328 }
1571 2329
1572 return 0; 2330 memcpy(cmd.param, &retry_limit, sizeof(retry_limit));
2331 return ipw_send_cmd(priv, &cmd);
1573} 2332}
1574 2333
1575/* 2334/*
@@ -1671,8 +2430,7 @@ static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)
1671/* data's copy of the eeprom data */ 2430/* data's copy of the eeprom data */
1672static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) 2431static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)
1673{ 2432{
1674 u8 *ee = (u8 *) priv->eeprom; 2433 memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6);
1675 memcpy(mac, &ee[EEPROM_MAC_ADDRESS], 6);
1676} 2434}
1677 2435
1678/* 2436/*
@@ -1692,7 +2450,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1692 2450
1693 /* read entire contents of eeprom into private buffer */ 2451 /* read entire contents of eeprom into private buffer */
1694 for (i = 0; i < 128; i++) 2452 for (i = 0; i < 128; i++)
1695 eeprom[i] = eeprom_read_u16(priv, (u8) i); 2453 eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
1696 2454
1697 /* 2455 /*
1698 If the data looks correct, then copy it to our private 2456 If the data looks correct, then copy it to our private
@@ -1703,7 +2461,7 @@ static void ipw_eeprom_init_sram(struct ipw_priv *priv)
1703 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n"); 2461 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");
1704 2462
1705 /* write the eeprom data to sram */ 2463 /* write the eeprom data to sram */
1706 for (i = 0; i < CX2_EEPROM_IMAGE_SIZE; i++) 2464 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)
1707 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]); 2465 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);
1708 2466
1709 /* Do not load eeprom data on fatal error or suspend */ 2467 /* Do not load eeprom data on fatal error or suspend */
@@ -1723,14 +2481,14 @@ static inline void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)
1723 count >>= 2; 2481 count >>= 2;
1724 if (!count) 2482 if (!count)
1725 return; 2483 return;
1726 _ipw_write32(priv, CX2_AUTOINC_ADDR, start); 2484 _ipw_write32(priv, IPW_AUTOINC_ADDR, start);
1727 while (count--) 2485 while (count--)
1728 _ipw_write32(priv, CX2_AUTOINC_DATA, 0); 2486 _ipw_write32(priv, IPW_AUTOINC_DATA, 0);
1729} 2487}
1730 2488
1731static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv) 2489static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)
1732{ 2490{
1733 ipw_zero_memory(priv, CX2_SHARED_SRAM_DMA_CONTROL, 2491 ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,
1734 CB_NUMBER_OF_ELEMENTS_SMALL * 2492 CB_NUMBER_OF_ELEMENTS_SMALL *
1735 sizeof(struct command_block)); 2493 sizeof(struct command_block));
1736} 2494}
@@ -1744,7 +2502,7 @@ static int ipw_fw_dma_enable(struct ipw_priv *priv)
1744 ipw_fw_dma_reset_command_blocks(priv); 2502 ipw_fw_dma_reset_command_blocks(priv);
1745 2503
1746 /* Write CB base address */ 2504 /* Write CB base address */
1747 ipw_write_reg32(priv, CX2_DMA_I_CB_BASE, CX2_SHARED_SRAM_DMA_CONTROL); 2505 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);
1748 2506
1749 IPW_DEBUG_FW("<< : \n"); 2507 IPW_DEBUG_FW("<< : \n");
1750 return 0; 2508 return 0;
@@ -1758,7 +2516,7 @@ static void ipw_fw_dma_abort(struct ipw_priv *priv)
1758 2516
1759 //set the Stop and Abort bit 2517 //set the Stop and Abort bit
1760 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT; 2518 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;
1761 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); 2519 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
1762 priv->sram_desc.last_cb_index = 0; 2520 priv->sram_desc.last_cb_index = 0;
1763 2521
1764 IPW_DEBUG_FW("<< \n"); 2522 IPW_DEBUG_FW("<< \n");
@@ -1768,7 +2526,7 @@ static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,
1768 struct command_block *cb) 2526 struct command_block *cb)
1769{ 2527{
1770 u32 address = 2528 u32 address =
1771 CX2_SHARED_SRAM_DMA_CONTROL + 2529 IPW_SHARED_SRAM_DMA_CONTROL +
1772 (sizeof(struct command_block) * index); 2530 (sizeof(struct command_block) * index);
1773 IPW_DEBUG_FW(">> :\n"); 2531 IPW_DEBUG_FW(">> :\n");
1774 2532
@@ -1792,13 +2550,13 @@ static int ipw_fw_dma_kick(struct ipw_priv *priv)
1792 &priv->sram_desc.cb_list[index]); 2550 &priv->sram_desc.cb_list[index]);
1793 2551
1794 /* Enable the DMA in the CSR register */ 2552 /* Enable the DMA in the CSR register */
1795 ipw_clear_bit(priv, CX2_RESET_REG, 2553 ipw_clear_bit(priv, IPW_RESET_REG,
1796 CX2_RESET_REG_MASTER_DISABLED | 2554 IPW_RESET_REG_MASTER_DISABLED |
1797 CX2_RESET_REG_STOP_MASTER); 2555 IPW_RESET_REG_STOP_MASTER);
1798 2556
1799 /* Set the Start bit. */ 2557 /* Set the Start bit. */
1800 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START; 2558 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;
1801 ipw_write_reg32(priv, CX2_DMA_I_DMA_CONTROL, control); 2559 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);
1802 2560
1803 IPW_DEBUG_FW("<< :\n"); 2561 IPW_DEBUG_FW("<< :\n");
1804 return 0; 2562 return 0;
@@ -1811,12 +2569,12 @@ static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)
1811 u32 cb_fields_address = 0; 2569 u32 cb_fields_address = 0;
1812 2570
1813 IPW_DEBUG_FW(">> :\n"); 2571 IPW_DEBUG_FW(">> :\n");
1814 address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); 2572 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
1815 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address); 2573 IPW_DEBUG_FW_INFO("Current CB is 0x%x \n", address);
1816 2574
1817 /* Read the DMA Controlor register */ 2575 /* Read the DMA Controlor register */
1818 register_value = ipw_read_reg32(priv, CX2_DMA_I_DMA_CONTROL); 2576 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);
1819 IPW_DEBUG_FW_INFO("CX2_DMA_I_DMA_CONTROL is 0x%x \n", register_value); 2577 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x \n", register_value);
1820 2578
1821 /* Print the CB values */ 2579 /* Print the CB values */
1822 cb_fields_address = address; 2580 cb_fields_address = address;
@@ -1845,9 +2603,9 @@ static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)
1845 u32 current_cb_index = 0; 2603 u32 current_cb_index = 0;
1846 2604
1847 IPW_DEBUG_FW("<< :\n"); 2605 IPW_DEBUG_FW("<< :\n");
1848 current_cb_address = ipw_read_reg32(priv, CX2_DMA_I_CURRENT_CB); 2606 current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);
1849 2607
1850 current_cb_index = (current_cb_address - CX2_SHARED_SRAM_DMA_CONTROL) / 2608 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /
1851 sizeof(struct command_block); 2609 sizeof(struct command_block);
1852 2610
1853 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n", 2611 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X \n",
@@ -1976,8 +2734,8 @@ static int ipw_fw_dma_wait(struct ipw_priv *priv)
1976 ipw_fw_dma_abort(priv); 2734 ipw_fw_dma_abort(priv);
1977 2735
1978 /*Disable the DMA in the CSR register */ 2736 /*Disable the DMA in the CSR register */
1979 ipw_set_bit(priv, CX2_RESET_REG, 2737 ipw_set_bit(priv, IPW_RESET_REG,
1980 CX2_RESET_REG_MASTER_DISABLED | CX2_RESET_REG_STOP_MASTER); 2738 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);
1981 2739
1982 IPW_DEBUG_FW("<< dmaWaitSync \n"); 2740 IPW_DEBUG_FW("<< dmaWaitSync \n");
1983 return 0; 2741 return 0;
@@ -1987,6 +2745,9 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
1987{ 2745{
1988 struct list_head *element, *safe; 2746 struct list_head *element, *safe;
1989 struct ieee80211_network *network = NULL; 2747 struct ieee80211_network *network = NULL;
2748 unsigned long flags;
2749
2750 spin_lock_irqsave(&priv->ieee->lock, flags);
1990 list_for_each_safe(element, safe, &priv->ieee->network_list) { 2751 list_for_each_safe(element, safe, &priv->ieee->network_list) {
1991 network = list_entry(element, struct ieee80211_network, list); 2752 network = list_entry(element, struct ieee80211_network, list);
1992 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 2753 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
@@ -1995,6 +2756,7 @@ static void ipw_remove_current_network(struct ipw_priv *priv)
1995 &priv->ieee->network_free_list); 2756 &priv->ieee->network_free_list);
1996 } 2757 }
1997 } 2758 }
2759 spin_unlock_irqrestore(&priv->ieee->lock, flags);
1998} 2760}
1999 2761
2000/** 2762/**
@@ -2037,10 +2799,10 @@ static int ipw_stop_master(struct ipw_priv *priv)
2037 2799
2038 IPW_DEBUG_TRACE(">> \n"); 2800 IPW_DEBUG_TRACE(">> \n");
2039 /* stop master. typical delay - 0 */ 2801 /* stop master. typical delay - 0 */
2040 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); 2802 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
2041 2803
2042 rc = ipw_poll_bit(priv, CX2_RESET_REG, 2804 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2043 CX2_RESET_REG_MASTER_DISABLED, 100); 2805 IPW_RESET_REG_MASTER_DISABLED, 100);
2044 if (rc < 0) { 2806 if (rc < 0) {
2045 IPW_ERROR("stop master failed in 10ms\n"); 2807 IPW_ERROR("stop master failed in 10ms\n");
2046 return -1; 2808 return -1;
@@ -2056,7 +2818,7 @@ static void ipw_arc_release(struct ipw_priv *priv)
2056 IPW_DEBUG_TRACE(">> \n"); 2818 IPW_DEBUG_TRACE(">> \n");
2057 mdelay(5); 2819 mdelay(5);
2058 2820
2059 ipw_clear_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 2821 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2060 2822
2061 /* no one knows timing, for safety add some delay */ 2823 /* no one knows timing, for safety add some delay */
2062 mdelay(5); 2824 mdelay(5);
@@ -2073,13 +2835,12 @@ struct fw_chunk {
2073}; 2835};
2074 2836
2075#define IPW_FW_MAJOR_VERSION 2 2837#define IPW_FW_MAJOR_VERSION 2
2076#define IPW_FW_MINOR_VERSION 2 2838#define IPW_FW_MINOR_VERSION 4
2077 2839
2078#define IPW_FW_MINOR(x) ((x & 0xff) >> 8) 2840#define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
2079#define IPW_FW_MAJOR(x) (x & 0xff) 2841#define IPW_FW_MAJOR(x) (x & 0xff)
2080 2842
2081#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | \ 2843#define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION)
2082 IPW_FW_MAJOR_VERSION)
2083 2844
2084#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \ 2845#define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \
2085"." __stringify(IPW_FW_MINOR_VERSION) "-" 2846"." __stringify(IPW_FW_MINOR_VERSION) "-"
@@ -2107,8 +2868,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2107 2868
2108// spin_lock_irqsave(&priv->lock, flags); 2869// spin_lock_irqsave(&priv->lock, flags);
2109 2870
2110 for (addr = CX2_SHARED_LOWER_BOUND; 2871 for (addr = IPW_SHARED_LOWER_BOUND;
2111 addr < CX2_REGISTER_DOMAIN1_END; addr += 4) { 2872 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {
2112 ipw_write32(priv, addr, 0); 2873 ipw_write32(priv, addr, 0);
2113 } 2874 }
2114 2875
@@ -2117,16 +2878,16 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2117 /* destroy DMA queues */ 2878 /* destroy DMA queues */
2118 /* reset sequence */ 2879 /* reset sequence */
2119 2880
2120 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_ON); 2881 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);
2121 ipw_arc_release(priv); 2882 ipw_arc_release(priv);
2122 ipw_write_reg32(priv, CX2_MEM_HALT_AND_RESET, CX2_BIT_HALT_RESET_OFF); 2883 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);
2123 mdelay(1); 2884 mdelay(1);
2124 2885
2125 /* reset PHY */ 2886 /* reset PHY */
2126 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, CX2_BASEBAND_POWER_DOWN); 2887 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);
2127 mdelay(1); 2888 mdelay(1);
2128 2889
2129 ipw_write_reg32(priv, CX2_INTERNAL_CMD_EVENT, 0); 2890 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);
2130 mdelay(1); 2891 mdelay(1);
2131 2892
2132 /* enable ucode store */ 2893 /* enable ucode store */
@@ -2144,18 +2905,19 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2144 */ 2905 */
2145 /* load new ipw uCode */ 2906 /* load new ipw uCode */
2146 for (i = 0; i < len / 2; i++) 2907 for (i = 0; i < len / 2; i++)
2147 ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]); 2908 ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,
2909 cpu_to_le16(image[i]));
2148 2910
2149 /* enable DINO */ 2911 /* enable DINO */
2150 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); 2912 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2151 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM); 2913 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);
2152 2914
2153 /* this is where the igx / win driver deveates from the VAP driver. */ 2915 /* this is where the igx / win driver deveates from the VAP driver. */
2154 2916
2155 /* wait for alive response */ 2917 /* wait for alive response */
2156 for (i = 0; i < 100; i++) { 2918 for (i = 0; i < 100; i++) {
2157 /* poll for incoming data */ 2919 /* poll for incoming data */
2158 cr = ipw_read_reg8(priv, CX2_BASEBAND_CONTROL_STATUS); 2920 cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);
2159 if (cr & DINO_RXFIFO_DATA) 2921 if (cr & DINO_RXFIFO_DATA)
2160 break; 2922 break;
2161 mdelay(1); 2923 mdelay(1);
@@ -2167,7 +2929,8 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2167 2929
2168 for (i = 0; i < ARRAY_SIZE(response_buffer); i++) 2930 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
2169 response_buffer[i] = 2931 response_buffer[i] =
2170 ipw_read_reg32(priv, CX2_BASEBAND_RX_FIFO_READ); 2932 le32_to_cpu(ipw_read_reg32(priv,
2933 IPW_BASEBAND_RX_FIFO_READ));
2171 memcpy(&priv->dino_alive, response_buffer, 2934 memcpy(&priv->dino_alive, response_buffer,
2172 sizeof(priv->dino_alive)); 2935 sizeof(priv->dino_alive));
2173 if (priv->dino_alive.alive_command == 1 2936 if (priv->dino_alive.alive_command == 1
@@ -2196,7 +2959,7 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
2196 2959
2197 /* disable DINO, otherwise for some reason 2960 /* disable DINO, otherwise for some reason
2198 firmware have problem getting alive resp. */ 2961 firmware have problem getting alive resp. */
2199 ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0); 2962 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);
2200 2963
2201// spin_unlock_irqrestore(&priv->lock, flags); 2964// spin_unlock_irqrestore(&priv->lock, flags);
2202 2965
@@ -2236,13 +2999,14 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
2236 * offeset*/ 2999 * offeset*/
2237 /* Dma loading */ 3000 /* Dma loading */
2238 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset, 3001 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
2239 chunk->address, chunk->length); 3002 le32_to_cpu(chunk->address),
3003 le32_to_cpu(chunk->length));
2240 if (rc) { 3004 if (rc) {
2241 IPW_DEBUG_INFO("dmaAddBuffer Failed\n"); 3005 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
2242 goto out; 3006 goto out;
2243 } 3007 }
2244 3008
2245 offset += chunk->length; 3009 offset += le32_to_cpu(chunk->length);
2246 } while (offset < len); 3010 } while (offset < len);
2247 3011
2248 /* Run the DMA and wait for the answer */ 3012 /* Run the DMA and wait for the answer */
@@ -2268,16 +3032,16 @@ static int ipw_stop_nic(struct ipw_priv *priv)
2268 int rc = 0; 3032 int rc = 0;
2269 3033
2270 /* stop */ 3034 /* stop */
2271 ipw_write32(priv, CX2_RESET_REG, CX2_RESET_REG_STOP_MASTER); 3035 ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);
2272 3036
2273 rc = ipw_poll_bit(priv, CX2_RESET_REG, 3037 rc = ipw_poll_bit(priv, IPW_RESET_REG,
2274 CX2_RESET_REG_MASTER_DISABLED, 500); 3038 IPW_RESET_REG_MASTER_DISABLED, 500);
2275 if (rc < 0) { 3039 if (rc < 0) {
2276 IPW_ERROR("wait for reg master disabled failed\n"); 3040 IPW_ERROR("wait for reg master disabled failed\n");
2277 return rc; 3041 return rc;
2278 } 3042 }
2279 3043
2280 ipw_set_bit(priv, CX2_RESET_REG, CBD_RESET_REG_PRINCETON_RESET); 3044 ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);
2281 3045
2282 return rc; 3046 return rc;
2283} 3047}
@@ -2287,14 +3051,14 @@ static void ipw_start_nic(struct ipw_priv *priv)
2287 IPW_DEBUG_TRACE(">>\n"); 3051 IPW_DEBUG_TRACE(">>\n");
2288 3052
2289 /* prvHwStartNic release ARC */ 3053 /* prvHwStartNic release ARC */
2290 ipw_clear_bit(priv, CX2_RESET_REG, 3054 ipw_clear_bit(priv, IPW_RESET_REG,
2291 CX2_RESET_REG_MASTER_DISABLED | 3055 IPW_RESET_REG_MASTER_DISABLED |
2292 CX2_RESET_REG_STOP_MASTER | 3056 IPW_RESET_REG_STOP_MASTER |
2293 CBD_RESET_REG_PRINCETON_RESET); 3057 CBD_RESET_REG_PRINCETON_RESET);
2294 3058
2295 /* enable power management */ 3059 /* enable power management */
2296 ipw_set_bit(priv, CX2_GP_CNTRL_RW, 3060 ipw_set_bit(priv, IPW_GP_CNTRL_RW,
2297 CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY); 3061 IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
2298 3062
2299 IPW_DEBUG_TRACE("<<\n"); 3063 IPW_DEBUG_TRACE("<<\n");
2300} 3064}
@@ -2307,25 +3071,25 @@ static int ipw_init_nic(struct ipw_priv *priv)
2307 /* reset */ 3071 /* reset */
2308 /*prvHwInitNic */ 3072 /*prvHwInitNic */
2309 /* set "initialization complete" bit to move adapter to D0 state */ 3073 /* set "initialization complete" bit to move adapter to D0 state */
2310 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); 3074 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
2311 3075
2312 /* low-level PLL activation */ 3076 /* low-level PLL activation */
2313 ipw_write32(priv, CX2_READ_INT_REGISTER, 3077 ipw_write32(priv, IPW_READ_INT_REGISTER,
2314 CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER); 3078 IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);
2315 3079
2316 /* wait for clock stabilization */ 3080 /* wait for clock stabilization */
2317 rc = ipw_poll_bit(priv, CX2_GP_CNTRL_RW, 3081 rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,
2318 CX2_GP_CNTRL_BIT_CLOCK_READY, 250); 3082 IPW_GP_CNTRL_BIT_CLOCK_READY, 250);
2319 if (rc < 0) 3083 if (rc < 0)
2320 IPW_DEBUG_INFO("FAILED wait for clock stablization\n"); 3084 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");
2321 3085
2322 /* assert SW reset */ 3086 /* assert SW reset */
2323 ipw_set_bit(priv, CX2_RESET_REG, CX2_RESET_REG_SW_RESET); 3087 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);
2324 3088
2325 udelay(10); 3089 udelay(10);
2326 3090
2327 /* set "initialization complete" bit to move adapter to D0 state */ 3091 /* set "initialization complete" bit to move adapter to D0 state */
2328 ipw_set_bit(priv, CX2_GP_CNTRL_RW, CX2_GP_CNTRL_BIT_INIT_DONE); 3092 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);
2329 3093
2330 IPW_DEBUG_TRACE(">>\n"); 3094 IPW_DEBUG_TRACE(">>\n");
2331 return 0; 3095 return 0;
@@ -2337,14 +3101,19 @@ static int ipw_init_nic(struct ipw_priv *priv)
2337static int ipw_reset_nic(struct ipw_priv *priv) 3101static int ipw_reset_nic(struct ipw_priv *priv)
2338{ 3102{
2339 int rc = 0; 3103 int rc = 0;
3104 unsigned long flags;
2340 3105
2341 IPW_DEBUG_TRACE(">>\n"); 3106 IPW_DEBUG_TRACE(">>\n");
2342 3107
2343 rc = ipw_init_nic(priv); 3108 rc = ipw_init_nic(priv);
2344 3109
3110 spin_lock_irqsave(&priv->lock, flags);
2345 /* Clear the 'host command active' bit... */ 3111 /* Clear the 'host command active' bit... */
2346 priv->status &= ~STATUS_HCMD_ACTIVE; 3112 priv->status &= ~STATUS_HCMD_ACTIVE;
2347 wake_up_interruptible(&priv->wait_command_queue); 3113 wake_up_interruptible(&priv->wait_command_queue);
3114 priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3115 wake_up_interruptible(&priv->wait_state);
3116 spin_unlock_irqrestore(&priv->lock, flags);
2348 3117
2349 IPW_DEBUG_TRACE("<<\n"); 3118 IPW_DEBUG_TRACE("<<\n");
2350 return rc; 3119 return rc;
@@ -2364,22 +3133,23 @@ static int ipw_get_fw(struct ipw_priv *priv,
2364 } 3133 }
2365 3134
2366 header = (struct fw_header *)(*fw)->data; 3135 header = (struct fw_header *)(*fw)->data;
2367 if (IPW_FW_MAJOR(header->version) != IPW_FW_MAJOR_VERSION) { 3136 if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
2368 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n", 3137 IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
2369 name, 3138 name,
2370 IPW_FW_MAJOR(header->version), IPW_FW_MAJOR_VERSION); 3139 IPW_FW_MAJOR(le32_to_cpu(header->version)),
3140 IPW_FW_MAJOR_VERSION);
2371 return -EINVAL; 3141 return -EINVAL;
2372 } 3142 }
2373 3143
2374 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n", 3144 IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
2375 name, 3145 name,
2376 IPW_FW_MAJOR(header->version), 3146 IPW_FW_MAJOR(le32_to_cpu(header->version)),
2377 IPW_FW_MINOR(header->version), 3147 IPW_FW_MINOR(le32_to_cpu(header->version)),
2378 (*fw)->size - sizeof(struct fw_header)); 3148 (*fw)->size - sizeof(struct fw_header));
2379 return 0; 3149 return 0;
2380} 3150}
2381 3151
2382#define CX2_RX_BUF_SIZE (3000) 3152#define IPW_RX_BUF_SIZE (3000)
2383 3153
2384static inline void ipw_rx_queue_reset(struct ipw_priv *priv, 3154static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2385 struct ipw_rx_queue *rxq) 3155 struct ipw_rx_queue *rxq)
@@ -2398,8 +3168,9 @@ static inline void ipw_rx_queue_reset(struct ipw_priv *priv,
2398 * to an SKB, so we need to unmap and free potential storage */ 3168 * to an SKB, so we need to unmap and free potential storage */
2399 if (rxq->pool[i].skb != NULL) { 3169 if (rxq->pool[i].skb != NULL) {
2400 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, 3170 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
2401 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 3171 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
2402 dev_kfree_skb(rxq->pool[i].skb); 3172 dev_kfree_skb(rxq->pool[i].skb);
3173 rxq->pool[i].skb = NULL;
2403 } 3174 }
2404 list_add_tail(&rxq->pool[i].list, &rxq->rx_used); 3175 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
2405 } 3176 }
@@ -2417,6 +3188,19 @@ static int fw_loaded = 0;
2417static const struct firmware *bootfw = NULL; 3188static const struct firmware *bootfw = NULL;
2418static const struct firmware *firmware = NULL; 3189static const struct firmware *firmware = NULL;
2419static const struct firmware *ucode = NULL; 3190static const struct firmware *ucode = NULL;
3191
3192static void free_firmware(void)
3193{
3194 if (fw_loaded) {
3195 release_firmware(bootfw);
3196 release_firmware(ucode);
3197 release_firmware(firmware);
3198 bootfw = ucode = firmware = NULL;
3199 fw_loaded = 0;
3200 }
3201}
3202#else
3203#define free_firmware() do {} while (0)
2420#endif 3204#endif
2421 3205
2422static int ipw_load(struct ipw_priv *priv) 3206static int ipw_load(struct ipw_priv *priv)
@@ -2445,10 +3229,10 @@ static int ipw_load(struct ipw_priv *priv)
2445 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss")); 3229 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
2446 break; 3230 break;
2447 3231
2448#ifdef CONFIG_IPW_PROMISC 3232#ifdef CONFIG_IPW2200_MONITOR
2449 case IW_MODE_MONITOR: 3233 case IW_MODE_MONITOR:
2450 rc = ipw_get_fw(priv, &ucode, 3234 rc = ipw_get_fw(priv, &ucode,
2451 IPW_FW_NAME("ibss_ucode")); 3235 IPW_FW_NAME("sniffer_ucode"));
2452 if (rc) 3236 if (rc)
2453 goto error; 3237 goto error;
2454 3238
@@ -2487,11 +3271,11 @@ static int ipw_load(struct ipw_priv *priv)
2487 3271
2488 retry: 3272 retry:
2489 /* Ensure interrupts are disabled */ 3273 /* Ensure interrupts are disabled */
2490 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 3274 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
2491 priv->status &= ~STATUS_INT_ENABLED; 3275 priv->status &= ~STATUS_INT_ENABLED;
2492 3276
2493 /* ack pending interrupts */ 3277 /* ack pending interrupts */
2494 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL); 3278 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2495 3279
2496 ipw_stop_nic(priv); 3280 ipw_stop_nic(priv);
2497 3281
@@ -2501,14 +3285,14 @@ static int ipw_load(struct ipw_priv *priv)
2501 goto error; 3285 goto error;
2502 } 3286 }
2503 3287
2504 ipw_zero_memory(priv, CX2_NIC_SRAM_LOWER_BOUND, 3288 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,
2505 CX2_NIC_SRAM_UPPER_BOUND - CX2_NIC_SRAM_LOWER_BOUND); 3289 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);
2506 3290
2507 /* DMA the initial boot firmware into the device */ 3291 /* DMA the initial boot firmware into the device */
2508 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), 3292 rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
2509 bootfw->size - sizeof(struct fw_header)); 3293 bootfw->size - sizeof(struct fw_header));
2510 if (rc < 0) { 3294 if (rc < 0) {
2511 IPW_ERROR("Unable to load boot firmware\n"); 3295 IPW_ERROR("Unable to load boot firmware: %d\n", rc);
2512 goto error; 3296 goto error;
2513 } 3297 }
2514 3298
@@ -2516,8 +3300,8 @@ static int ipw_load(struct ipw_priv *priv)
2516 ipw_start_nic(priv); 3300 ipw_start_nic(priv);
2517 3301
2518 /* wait for the device to finish it's initial startup sequence */ 3302 /* wait for the device to finish it's initial startup sequence */
2519 rc = ipw_poll_bit(priv, CX2_INTA_RW, 3303 rc = ipw_poll_bit(priv, IPW_INTA_RW,
2520 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3304 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2521 if (rc < 0) { 3305 if (rc < 0) {
2522 IPW_ERROR("device failed to boot initial fw image\n"); 3306 IPW_ERROR("device failed to boot initial fw image\n");
2523 goto error; 3307 goto error;
@@ -2525,13 +3309,13 @@ static int ipw_load(struct ipw_priv *priv)
2525 IPW_DEBUG_INFO("initial device response after %dms\n", rc); 3309 IPW_DEBUG_INFO("initial device response after %dms\n", rc);
2526 3310
2527 /* ack fw init done interrupt */ 3311 /* ack fw init done interrupt */
2528 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE); 3312 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
2529 3313
2530 /* DMA the ucode into the device */ 3314 /* DMA the ucode into the device */
2531 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), 3315 rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
2532 ucode->size - sizeof(struct fw_header)); 3316 ucode->size - sizeof(struct fw_header));
2533 if (rc < 0) { 3317 if (rc < 0) {
2534 IPW_ERROR("Unable to load ucode\n"); 3318 IPW_ERROR("Unable to load ucode: %d\n", rc);
2535 goto error; 3319 goto error;
2536 } 3320 }
2537 3321
@@ -2543,7 +3327,7 @@ static int ipw_load(struct ipw_priv *priv)
2543 sizeof(struct fw_header), 3327 sizeof(struct fw_header),
2544 firmware->size - sizeof(struct fw_header)); 3328 firmware->size - sizeof(struct fw_header));
2545 if (rc < 0) { 3329 if (rc < 0) {
2546 IPW_ERROR("Unable to load firmware\n"); 3330 IPW_ERROR("Unable to load firmware: %d\n", rc);
2547 goto error; 3331 goto error;
2548 } 3332 }
2549 3333
@@ -2556,12 +3340,14 @@ static int ipw_load(struct ipw_priv *priv)
2556 } 3340 }
2557 3341
2558 /* Ensure interrupts are disabled */ 3342 /* Ensure interrupts are disabled */
2559 ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL); 3343 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
3344 /* ack pending interrupts */
3345 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2560 3346
2561 /* kick start the device */ 3347 /* kick start the device */
2562 ipw_start_nic(priv); 3348 ipw_start_nic(priv);
2563 3349
2564 if (ipw_read32(priv, CX2_INTA_RW) & CX2_INTA_BIT_PARITY_ERROR) { 3350 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {
2565 if (retries > 0) { 3351 if (retries > 0) {
2566 IPW_WARNING("Parity error. Retrying init.\n"); 3352 IPW_WARNING("Parity error. Retrying init.\n");
2567 retries--; 3353 retries--;
@@ -2574,8 +3360,8 @@ static int ipw_load(struct ipw_priv *priv)
2574 } 3360 }
2575 3361
2576 /* wait for the device */ 3362 /* wait for the device */
2577 rc = ipw_poll_bit(priv, CX2_INTA_RW, 3363 rc = ipw_poll_bit(priv, IPW_INTA_RW,
2578 CX2_INTA_BIT_FW_INITIALIZATION_DONE, 500); 3364 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);
2579 if (rc < 0) { 3365 if (rc < 0) {
2580 IPW_ERROR("device failed to start after 500ms\n"); 3366 IPW_ERROR("device failed to start after 500ms\n");
2581 goto error; 3367 goto error;
@@ -2583,7 +3369,7 @@ static int ipw_load(struct ipw_priv *priv)
2583 IPW_DEBUG_INFO("device response after %dms\n", rc); 3369 IPW_DEBUG_INFO("device response after %dms\n", rc);
2584 3370
2585 /* ack fw init done interrupt */ 3371 /* ack fw init done interrupt */
2586 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_BIT_FW_INITIALIZATION_DONE); 3372 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);
2587 3373
2588 /* read eeprom data and initialize the eeprom region of sram */ 3374 /* read eeprom data and initialize the eeprom region of sram */
2589 priv->eeprom_delay = 1; 3375 priv->eeprom_delay = 1;
@@ -2595,10 +3381,10 @@ static int ipw_load(struct ipw_priv *priv)
2595 /* Ensure our queue has valid packets */ 3381 /* Ensure our queue has valid packets */
2596 ipw_rx_queue_replenish(priv); 3382 ipw_rx_queue_replenish(priv);
2597 3383
2598 ipw_write32(priv, CX2_RX_READ_INDEX, priv->rxq->read); 3384 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);
2599 3385
2600 /* ack pending interrupts */ 3386 /* ack pending interrupts */
2601 ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL); 3387 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);
2602 3388
2603#ifndef CONFIG_PM 3389#ifndef CONFIG_PM
2604 release_firmware(bootfw); 3390 release_firmware(bootfw);
@@ -2755,16 +3541,18 @@ static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,
2755 return; 3541 return;
2756 3542
2757 /* sanity check */ 3543 /* sanity check */
2758 if (bd->u.data.num_chunks > NUM_TFD_CHUNKS) { 3544 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
2759 IPW_ERROR("Too many chunks: %i\n", bd->u.data.num_chunks); 3545 IPW_ERROR("Too many chunks: %i\n",
3546 le32_to_cpu(bd->u.data.num_chunks));
2760 /** @todo issue fatal error, it is quite serious situation */ 3547 /** @todo issue fatal error, it is quite serious situation */
2761 return; 3548 return;
2762 } 3549 }
2763 3550
2764 /* unmap chunks if any */ 3551 /* unmap chunks if any */
2765 for (i = 0; i < bd->u.data.num_chunks; i++) { 3552 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
2766 pci_unmap_single(dev, bd->u.data.chunk_ptr[i], 3553 pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
2767 bd->u.data.chunk_len[i], PCI_DMA_TODEVICE); 3554 le16_to_cpu(bd->u.data.chunk_len[i]),
3555 PCI_DMA_TODEVICE);
2768 if (txq->txb[txq->q.last_used]) { 3556 if (txq->txb[txq->q.last_used]) {
2769 ieee80211_txb_free(txq->txb[txq->q.last_used]); 3557 ieee80211_txb_free(txq->txb[txq->q.last_used]);
2770 txq->txb[txq->q.last_used] = NULL; 3558 txq->txb[txq->q.last_used] = NULL;
@@ -2821,21 +3609,6 @@ static void ipw_tx_queue_free(struct ipw_priv *priv)
2821 ipw_queue_tx_free(priv, &priv->txq[3]); 3609 ipw_queue_tx_free(priv, &priv->txq[3]);
2822} 3610}
2823 3611
2824static void inline __maybe_wake_tx(struct ipw_priv *priv)
2825{
2826 if (netif_running(priv->net_dev)) {
2827 switch (priv->port_type) {
2828 case DCR_TYPE_MU_BSS:
2829 case DCR_TYPE_MU_IBSS:
2830 if (!(priv->status & STATUS_ASSOCIATED)) {
2831 return;
2832 }
2833 }
2834 netif_wake_queue(priv->net_dev);
2835 }
2836
2837}
2838
2839static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid) 3612static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
2840{ 3613{
2841 /* First 3 bytes are manufacturer */ 3614 /* First 3 bytes are manufacturer */
@@ -2898,7 +3671,13 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2898{ 3671{
2899 int err; 3672 int err;
2900 3673
2901 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) { 3674 if (priv->status & STATUS_ASSOCIATING) {
3675 IPW_DEBUG_ASSOC("Disassociating while associating.\n");
3676 queue_work(priv->workqueue, &priv->disassociate);
3677 return;
3678 }
3679
3680 if (!(priv->status & STATUS_ASSOCIATED)) {
2902 IPW_DEBUG_ASSOC("Disassociating while not associated.\n"); 3681 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
2903 return; 3682 return;
2904 } 3683 }
@@ -2915,6 +3694,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2915 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET; 3694 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
2916 else 3695 else
2917 priv->assoc_request.assoc_type = HC_DISASSOCIATE; 3696 priv->assoc_request.assoc_type = HC_DISASSOCIATE;
3697
2918 err = ipw_send_associate(priv, &priv->assoc_request); 3698 err = ipw_send_associate(priv, &priv->assoc_request);
2919 if (err) { 3699 if (err) {
2920 IPW_DEBUG_HC("Attempt to send [dis]associate command " 3700 IPW_DEBUG_HC("Attempt to send [dis]associate command "
@@ -2924,20 +3704,27 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
2924 3704
2925} 3705}
2926 3706
2927static void ipw_disassociate(void *data) 3707static int ipw_disassociate(void *data)
2928{ 3708{
3709 struct ipw_priv *priv = data;
3710 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
3711 return 0;
2929 ipw_send_disassociate(data, 0); 3712 ipw_send_disassociate(data, 0);
3713 return 1;
2930} 3714}
2931 3715
2932static void notify_wx_assoc_event(struct ipw_priv *priv) 3716static void ipw_bg_disassociate(void *data)
2933{ 3717{
2934 union iwreq_data wrqu; 3718 struct ipw_priv *priv = data;
2935 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 3719 down(&priv->sem);
2936 if (priv->status & STATUS_ASSOCIATED) 3720 ipw_disassociate(data);
2937 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN); 3721 up(&priv->sem);
2938 else 3722}
2939 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 3723
2940 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); 3724static void ipw_system_config(void *data)
3725{
3726 struct ipw_priv *priv = data;
3727 ipw_send_system_config(priv, &priv->sys_config);
2941} 3728}
2942 3729
2943struct ipw_status_code { 3730struct ipw_status_code {
@@ -2997,7 +3784,7 @@ static const char *ipw_get_status_code(u16 status)
2997{ 3784{
2998 int i; 3785 int i;
2999 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++) 3786 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
3000 if (ipw_status_codes[i].status == status) 3787 if (ipw_status_codes[i].status == (status & 0xff))
3001 return ipw_status_codes[i].reason; 3788 return ipw_status_codes[i].reason;
3002 return "Unknown status value."; 3789 return "Unknown status value.";
3003} 3790}
@@ -3076,18 +3863,30 @@ static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
3076 while (i && !(mask & i)) 3863 while (i && !(mask & i))
3077 i >>= 1; 3864 i >>= 1;
3078 switch (i) { 3865 switch (i) {
3079 case IEEE80211_CCK_RATE_1MB_MASK: return 1000000; 3866 case IEEE80211_CCK_RATE_1MB_MASK:
3080 case IEEE80211_CCK_RATE_2MB_MASK: return 2000000; 3867 return 1000000;
3081 case IEEE80211_CCK_RATE_5MB_MASK: return 5500000; 3868 case IEEE80211_CCK_RATE_2MB_MASK:
3082 case IEEE80211_OFDM_RATE_6MB_MASK: return 6000000; 3869 return 2000000;
3083 case IEEE80211_OFDM_RATE_9MB_MASK: return 9000000; 3870 case IEEE80211_CCK_RATE_5MB_MASK:
3084 case IEEE80211_CCK_RATE_11MB_MASK: return 11000000; 3871 return 5500000;
3085 case IEEE80211_OFDM_RATE_12MB_MASK: return 12000000; 3872 case IEEE80211_OFDM_RATE_6MB_MASK:
3086 case IEEE80211_OFDM_RATE_18MB_MASK: return 18000000; 3873 return 6000000;
3087 case IEEE80211_OFDM_RATE_24MB_MASK: return 24000000; 3874 case IEEE80211_OFDM_RATE_9MB_MASK:
3088 case IEEE80211_OFDM_RATE_36MB_MASK: return 36000000; 3875 return 9000000;
3089 case IEEE80211_OFDM_RATE_48MB_MASK: return 48000000; 3876 case IEEE80211_CCK_RATE_11MB_MASK:
3090 case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000; 3877 return 11000000;
3878 case IEEE80211_OFDM_RATE_12MB_MASK:
3879 return 12000000;
3880 case IEEE80211_OFDM_RATE_18MB_MASK:
3881 return 18000000;
3882 case IEEE80211_OFDM_RATE_24MB_MASK:
3883 return 24000000;
3884 case IEEE80211_OFDM_RATE_36MB_MASK:
3885 return 36000000;
3886 case IEEE80211_OFDM_RATE_48MB_MASK:
3887 return 48000000;
3888 case IEEE80211_OFDM_RATE_54MB_MASK:
3889 return 54000000;
3091 } 3890 }
3092 3891
3093 if (priv->ieee->mode == IEEE_B) 3892 if (priv->ieee->mode == IEEE_B)
@@ -3115,25 +3914,35 @@ static u32 ipw_get_current_rate(struct ipw_priv *priv)
3115 return ipw_get_max_rate(priv); 3914 return ipw_get_max_rate(priv);
3116 3915
3117 switch (rate) { 3916 switch (rate) {
3118 case IPW_TX_RATE_1MB: return 1000000; 3917 case IPW_TX_RATE_1MB:
3119 case IPW_TX_RATE_2MB: return 2000000; 3918 return 1000000;
3120 case IPW_TX_RATE_5MB: return 5500000; 3919 case IPW_TX_RATE_2MB:
3121 case IPW_TX_RATE_6MB: return 6000000; 3920 return 2000000;
3122 case IPW_TX_RATE_9MB: return 9000000; 3921 case IPW_TX_RATE_5MB:
3123 case IPW_TX_RATE_11MB: return 11000000; 3922 return 5500000;
3124 case IPW_TX_RATE_12MB: return 12000000; 3923 case IPW_TX_RATE_6MB:
3125 case IPW_TX_RATE_18MB: return 18000000; 3924 return 6000000;
3126 case IPW_TX_RATE_24MB: return 24000000; 3925 case IPW_TX_RATE_9MB:
3127 case IPW_TX_RATE_36MB: return 36000000; 3926 return 9000000;
3128 case IPW_TX_RATE_48MB: return 48000000; 3927 case IPW_TX_RATE_11MB:
3129 case IPW_TX_RATE_54MB: return 54000000; 3928 return 11000000;
3929 case IPW_TX_RATE_12MB:
3930 return 12000000;
3931 case IPW_TX_RATE_18MB:
3932 return 18000000;
3933 case IPW_TX_RATE_24MB:
3934 return 24000000;
3935 case IPW_TX_RATE_36MB:
3936 return 36000000;
3937 case IPW_TX_RATE_48MB:
3938 return 48000000;
3939 case IPW_TX_RATE_54MB:
3940 return 54000000;
3130 } 3941 }
3131 3942
3132 return 0; 3943 return 0;
3133} 3944}
3134 3945
3135#define PERFECT_RSSI (-50)
3136#define WORST_RSSI (-85)
3137#define IPW_STATS_INTERVAL (2 * HZ) 3946#define IPW_STATS_INTERVAL (2 * HZ)
3138static void ipw_gather_stats(struct ipw_priv *priv) 3947static void ipw_gather_stats(struct ipw_priv *priv)
3139{ 3948{
@@ -3145,6 +3954,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3145 s16 rssi; 3954 s16 rssi;
3146 u32 beacon_quality, signal_quality, tx_quality, rx_quality, 3955 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
3147 rate_quality; 3956 rate_quality;
3957 u32 max_rate;
3148 3958
3149 if (!(priv->status & STATUS_ASSOCIATED)) { 3959 if (!(priv->status & STATUS_ASSOCIATED)) {
3150 priv->quality = 0; 3960 priv->quality = 0;
@@ -3201,7 +4011,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3201 beacon_quality, missed_beacons_percent); 4011 beacon_quality, missed_beacons_percent);
3202 4012
3203 priv->last_rate = ipw_get_current_rate(priv); 4013 priv->last_rate = ipw_get_current_rate(priv);
3204 rate_quality = priv->last_rate * 40 / priv->last_rate + 60; 4014 max_rate = ipw_get_max_rate(priv);
4015 rate_quality = priv->last_rate * 40 / max_rate + 60;
3205 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n", 4016 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
3206 rate_quality, priv->last_rate / 1000000); 4017 rate_quality, priv->last_rate / 1000000);
3207 4018
@@ -3222,13 +4033,20 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3222 tx_quality, tx_failures_delta, tx_packets_delta); 4033 tx_quality, tx_failures_delta, tx_packets_delta);
3223 4034
3224 rssi = average_value(&priv->average_rssi); 4035 rssi = average_value(&priv->average_rssi);
3225 if (rssi > PERFECT_RSSI) 4036 signal_quality =
4037 (100 *
4038 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4039 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
4040 (priv->ieee->perfect_rssi - rssi) *
4041 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
4042 62 * (priv->ieee->perfect_rssi - rssi))) /
4043 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
4044 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
4045 if (signal_quality > 100)
3226 signal_quality = 100; 4046 signal_quality = 100;
3227 else if (rssi < WORST_RSSI) 4047 else if (signal_quality < 1)
3228 signal_quality = 0; 4048 signal_quality = 0;
3229 else 4049
3230 signal_quality = (rssi - WORST_RSSI) * 100 /
3231 (PERFECT_RSSI - WORST_RSSI);
3232 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", 4050 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
3233 signal_quality, rssi); 4051 signal_quality, rssi);
3234 4052
@@ -3257,6 +4075,85 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3257 IPW_STATS_INTERVAL); 4075 IPW_STATS_INTERVAL);
3258} 4076}
3259 4077
4078static void ipw_bg_gather_stats(void *data)
4079{
4080 struct ipw_priv *priv = data;
4081 down(&priv->sem);
4082 ipw_gather_stats(data);
4083 up(&priv->sem);
4084}
4085
4086/* Missed beacon behavior:
4087 * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.
4088 * roaming_threshold -> disassociate_threshold, scan and roam for better signal.
4089 * Above disassociate threshold, give up and stop scanning.
4090 * Roaming is disabled if disassociate_threshold <= roaming_threshold */
4091static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
4092 int missed_count)
4093{
4094 priv->notif_missed_beacons = missed_count;
4095
4096 if (missed_count > priv->disassociate_threshold &&
4097 priv->status & STATUS_ASSOCIATED) {
4098 /* If associated and we've hit the missed
4099 * beacon threshold, disassociate, turn
4100 * off roaming, and abort any active scans */
4101 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4102 IPW_DL_STATE | IPW_DL_ASSOC,
4103 "Missed beacon: %d - disassociate\n", missed_count);
4104 priv->status &= ~STATUS_ROAMING;
4105 if (priv->status & STATUS_SCANNING) {
4106 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
4107 IPW_DL_STATE,
4108 "Aborting scan with missed beacon.\n");
4109 queue_work(priv->workqueue, &priv->abort_scan);
4110 }
4111
4112 queue_work(priv->workqueue, &priv->disassociate);
4113 return;
4114 }
4115
4116 if (priv->status & STATUS_ROAMING) {
4117 /* If we are currently roaming, then just
4118 * print a debug statement... */
4119 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4120 "Missed beacon: %d - roam in progress\n",
4121 missed_count);
4122 return;
4123 }
4124
4125 if (missed_count > priv->roaming_threshold &&
4126 missed_count <= priv->disassociate_threshold) {
4127 /* If we are not already roaming, set the ROAM
4128 * bit in the status and kick off a scan.
4129 * This can happen several times before we reach
4130 * disassociate_threshold. */
4131 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
4132 "Missed beacon: %d - initiate "
4133 "roaming\n", missed_count);
4134 if (!(priv->status & STATUS_ROAMING)) {
4135 priv->status |= STATUS_ROAMING;
4136 if (!(priv->status & STATUS_SCANNING))
4137 queue_work(priv->workqueue,
4138 &priv->request_scan);
4139 }
4140 return;
4141 }
4142
4143 if (priv->status & STATUS_SCANNING) {
4144 /* Stop scan to keep fw from getting
4145 * stuck (only if we aren't roaming --
4146 * otherwise we'll never scan more than 2 or 3
4147 * channels..) */
4148 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,
4149 "Aborting scan with missed beacon.\n");
4150 queue_work(priv->workqueue, &priv->abort_scan);
4151 }
4152
4153 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
4154
4155}
4156
3260/** 4157/**
3261 * Handle host notification packet. 4158 * Handle host notification packet.
3262 * Called from interrupt routine 4159 * Called from interrupt routine
@@ -3264,6 +4161,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3264static inline void ipw_rx_notification(struct ipw_priv *priv, 4161static inline void ipw_rx_notification(struct ipw_priv *priv,
3265 struct ipw_rx_notification *notif) 4162 struct ipw_rx_notification *notif)
3266{ 4163{
4164 notif->size = le16_to_cpu(notif->size);
4165
3267 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size); 4166 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
3268 4167
3269 switch (notif->subtype) { 4168 switch (notif->subtype) {
@@ -3307,30 +4206,44 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3307 4206
3308 priv->status &= ~STATUS_ASSOCIATING; 4207 priv->status &= ~STATUS_ASSOCIATING;
3309 priv->status |= STATUS_ASSOCIATED; 4208 priv->status |= STATUS_ASSOCIATED;
3310 4209 queue_work(priv->workqueue,
3311 netif_carrier_on(priv->net_dev); 4210 &priv->system_config);
3312 if (netif_queue_stopped(priv->net_dev)) { 4211
3313 IPW_DEBUG_NOTIF 4212#ifdef CONFIG_IPW_QOS
3314 ("waking queue\n"); 4213#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
3315 netif_wake_queue(priv->net_dev); 4214 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_ctl))
3316 } else { 4215 if ((priv->status & STATUS_AUTH) &&
3317 IPW_DEBUG_NOTIF 4216 (IPW_GET_PACKET_STYPE(&notif->u.raw)
3318 ("starting queue\n"); 4217 == IEEE80211_STYPE_ASSOC_RESP)) {
3319 netif_start_queue(priv-> 4218 if ((sizeof
3320 net_dev); 4219 (struct
4220 ieee80211_assoc_response)
4221 <= notif->size)
4222 && (notif->size <= 2314)) {
4223 struct
4224 ieee80211_rx_stats
4225 stats = {
4226 .len =
4227 notif->
4228 size - 1,
4229 };
4230
4231 IPW_DEBUG_QOS
4232 ("QoS Associate "
4233 "size %d\n",
4234 notif->size);
4235 ieee80211_rx_mgt(priv->
4236 ieee,
4237 (struct
4238 ieee80211_hdr_4addr
4239 *)
4240 &notif->u.raw, &stats);
4241 }
3321 } 4242 }
4243#endif
3322 4244
3323 ipw_reset_stats(priv); 4245 schedule_work(&priv->link_up);
3324 /* Ensure the rate is updated immediately */
3325 priv->last_rate =
3326 ipw_get_current_rate(priv);
3327 schedule_work(&priv->gather_stats);
3328 notify_wx_assoc_event(priv);
3329 4246
3330/* queue_delayed_work(priv->workqueue,
3331 &priv->request_scan,
3332 SCAN_ASSOCIATED_INTERVAL);
3333*/
3334 break; 4247 break;
3335 } 4248 }
3336 4249
@@ -3363,12 +4276,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3363 STATUS_AUTH | 4276 STATUS_AUTH |
3364 STATUS_ASSOCIATED); 4277 STATUS_ASSOCIATED);
3365 4278
3366 netif_carrier_off(priv-> 4279 schedule_work(&priv->link_down);
3367 net_dev);
3368 netif_stop_queue(priv->net_dev);
3369 queue_work(priv->workqueue,
3370 &priv->request_scan);
3371 notify_wx_assoc_event(priv);
3372 break; 4280 break;
3373 } 4281 }
3374 4282
@@ -3383,6 +4291,24 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3383 } 4291 }
3384 4292
3385 case CMAS_INIT:{ 4293 case CMAS_INIT:{
4294 if (priv->status & STATUS_AUTH) {
4295 struct
4296 ieee80211_assoc_response
4297 *resp;
4298 resp =
4299 (struct
4300 ieee80211_assoc_response
4301 *)&notif->u.raw;
4302 IPW_DEBUG(IPW_DL_NOTIF |
4303 IPW_DL_STATE |
4304 IPW_DL_ASSOC,
4305 "association failed (0x%04X): %s\n",
4306 ntohs(resp->status),
4307 ipw_get_status_code
4308 (ntohs
4309 (resp->status)));
4310 }
4311
3386 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4312 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3387 IPW_DL_ASSOC, 4313 IPW_DL_ASSOC,
3388 "disassociated: '%s' " MAC_FMT 4314 "disassociated: '%s' " MAC_FMT
@@ -3395,35 +4321,21 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3395 ~(STATUS_DISASSOCIATING | 4321 ~(STATUS_DISASSOCIATING |
3396 STATUS_ASSOCIATING | 4322 STATUS_ASSOCIATING |
3397 STATUS_ASSOCIATED | STATUS_AUTH); 4323 STATUS_ASSOCIATED | STATUS_AUTH);
4324 if (priv->assoc_network
4325 && (priv->assoc_network->
4326 capability &
4327 WLAN_CAPABILITY_IBSS))
4328 ipw_remove_current_network
4329 (priv);
3398 4330
3399 netif_stop_queue(priv->net_dev); 4331 schedule_work(&priv->link_down);
3400 if (!(priv->status & STATUS_ROAMING)) {
3401 netif_carrier_off(priv->
3402 net_dev);
3403 notify_wx_assoc_event(priv);
3404
3405 /* Cancel any queued work ... */
3406 cancel_delayed_work(&priv->
3407 request_scan);
3408 cancel_delayed_work(&priv->
3409 adhoc_check);
3410
3411 /* Queue up another scan... */
3412 queue_work(priv->workqueue,
3413 &priv->request_scan);
3414
3415 cancel_delayed_work(&priv->
3416 gather_stats);
3417 } else {
3418 priv->status |= STATUS_ROAMING;
3419 queue_work(priv->workqueue,
3420 &priv->request_scan);
3421 }
3422 4332
3423 ipw_reset_stats(priv);
3424 break; 4333 break;
3425 } 4334 }
3426 4335
4336 case CMAS_RX_ASSOC_RESP:
4337 break;
4338
3427 default: 4339 default:
3428 IPW_ERROR("assoc: unknown (%d)\n", 4340 IPW_ERROR("assoc: unknown (%d)\n",
3429 assoc->state); 4341 assoc->state);
@@ -3466,11 +4378,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3466 STATUS_AUTH | 4378 STATUS_AUTH |
3467 STATUS_ASSOCIATED); 4379 STATUS_ASSOCIATED);
3468 4380
3469 netif_carrier_off(priv->net_dev); 4381 schedule_work(&priv->link_down);
3470 netif_stop_queue(priv->net_dev);
3471 queue_work(priv->workqueue,
3472 &priv->request_scan);
3473 notify_wx_assoc_event(priv);
3474 break; 4382 break;
3475 4383
3476 case CMAS_TX_AUTH_SEQ_1: 4384 case CMAS_TX_AUTH_SEQ_1:
@@ -3512,6 +4420,7 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3512 case CMAS_RX_ASSOC_RESP: 4420 case CMAS_RX_ASSOC_RESP:
3513 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4421 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3514 IPW_DL_ASSOC, "RX_ASSOC_RESP\n"); 4422 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");
4423
3515 break; 4424 break;
3516 case CMAS_ASSOCIATED: 4425 case CMAS_ASSOCIATED:
3517 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 4426 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
@@ -3556,43 +4465,67 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3556 priv->status &= 4465 priv->status &=
3557 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING); 4466 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
3558 4467
4468 wake_up_interruptible(&priv->wait_state);
3559 cancel_delayed_work(&priv->scan_check); 4469 cancel_delayed_work(&priv->scan_check);
3560 4470
4471 if (priv->status & STATUS_EXIT_PENDING)
4472 break;
4473
4474 priv->ieee->scans++;
4475
4476#ifdef CONFIG_IPW2200_MONITOR
4477 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4478 priv->status |= STATUS_SCAN_FORCED;
4479 queue_work(priv->workqueue,
4480 &priv->request_scan);
4481 break;
4482 }
4483 priv->status &= ~STATUS_SCAN_FORCED;
4484#endif /* CONFIG_IPW2200_MONITOR */
4485
3561 if (!(priv->status & (STATUS_ASSOCIATED | 4486 if (!(priv->status & (STATUS_ASSOCIATED |
3562 STATUS_ASSOCIATING | 4487 STATUS_ASSOCIATING |
3563 STATUS_ROAMING | 4488 STATUS_ROAMING |
3564 STATUS_DISASSOCIATING))) 4489 STATUS_DISASSOCIATING)))
3565 queue_work(priv->workqueue, &priv->associate); 4490 queue_work(priv->workqueue, &priv->associate);
3566 else if (priv->status & STATUS_ROAMING) { 4491 else if (priv->status & STATUS_ROAMING) {
3567 /* If a scan completed and we are in roam mode, then 4492 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
3568 * the scan that completed was the one requested as a 4493 /* If a scan completed and we are in roam mode, then
3569 * result of entering roam... so, schedule the 4494 * the scan that completed was the one requested as a
3570 * roam work */ 4495 * result of entering roam... so, schedule the
3571 queue_work(priv->workqueue, &priv->roam); 4496 * roam work */
4497 queue_work(priv->workqueue,
4498 &priv->roam);
4499 else
4500 /* Don't schedule if we aborted the scan */
4501 priv->status &= ~STATUS_ROAMING;
3572 } else if (priv->status & STATUS_SCAN_PENDING) 4502 } else if (priv->status & STATUS_SCAN_PENDING)
3573 queue_work(priv->workqueue, 4503 queue_work(priv->workqueue,
3574 &priv->request_scan); 4504 &priv->request_scan);
3575 4505 else if (priv->config & CFG_BACKGROUND_SCAN
3576 priv->ieee->scans++; 4506 && priv->status & STATUS_ASSOCIATED)
4507 queue_delayed_work(priv->workqueue,
4508 &priv->request_scan, HZ);
3577 break; 4509 break;
3578 } 4510 }
3579 4511
3580 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{ 4512 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
3581 struct notif_frag_length *x = &notif->u.frag_len; 4513 struct notif_frag_length *x = &notif->u.frag_len;
3582 4514
3583 if (notif->size == sizeof(*x)) { 4515 if (notif->size == sizeof(*x))
3584 IPW_ERROR("Frag length: %d\n", x->frag_length); 4516 IPW_ERROR("Frag length: %d\n",
3585 } else { 4517 le16_to_cpu(x->frag_length));
4518 else
3586 IPW_ERROR("Frag length of wrong size %d " 4519 IPW_ERROR("Frag length of wrong size %d "
3587 "(should be %zd)\n", 4520 "(should be %zd)\n",
3588 notif->size, sizeof(*x)); 4521 notif->size, sizeof(*x));
3589 }
3590 break; 4522 break;
3591 } 4523 }
3592 4524
3593 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{ 4525 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{
3594 struct notif_link_deterioration *x = 4526 struct notif_link_deterioration *x =
3595 &notif->u.link_deterioration; 4527 &notif->u.link_deterioration;
4528
3596 if (notif->size == sizeof(*x)) { 4529 if (notif->size == sizeof(*x)) {
3597 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, 4530 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3598 "link deterioration: '%s' " MAC_FMT 4531 "link deterioration: '%s' " MAC_FMT
@@ -3612,11 +4545,9 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3612 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{ 4545 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
3613 IPW_ERROR("Dino config\n"); 4546 IPW_ERROR("Dino config\n");
3614 if (priv->hcmd 4547 if (priv->hcmd
3615 && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) { 4548 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
3616 /* TODO: Do anything special? */
3617 } else {
3618 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n"); 4549 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
3619 } 4550
3620 break; 4551 break;
3621 } 4552 }
3622 4553
@@ -3629,36 +4560,11 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3629 break; 4560 break;
3630 } 4561 }
3631 4562
3632 if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) { 4563 if (le32_to_cpu(x->state) ==
3633 if (priv->status & STATUS_SCANNING) { 4564 HOST_NOTIFICATION_STATUS_BEACON_MISSING)
3634 /* Stop scan to keep fw from getting 4565 ipw_handle_missed_beacon(priv,
3635 * stuck... */ 4566 le32_to_cpu(x->
3636 queue_work(priv->workqueue, 4567 number));
3637 &priv->abort_scan);
3638 }
3639
3640 if (x->number > priv->missed_beacon_threshold &&
3641 priv->status & STATUS_ASSOCIATED) {
3642 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3643 IPW_DL_STATE,
3644 "Missed beacon: %d - disassociate\n",
3645 x->number);
3646 queue_work(priv->workqueue,
3647 &priv->disassociate);
3648 } else if (x->number > priv->roaming_threshold) {
3649 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3650 "Missed beacon: %d - initiate "
3651 "roaming\n", x->number);
3652 queue_work(priv->workqueue,
3653 &priv->roam);
3654 } else {
3655 IPW_DEBUG_NOTIF("Missed beacon: %d\n",
3656 x->number);
3657 }
3658
3659 priv->notif_missed_beacons = x->number;
3660
3661 }
3662 4568
3663 break; 4569 break;
3664 } 4570 }
@@ -3697,7 +4603,8 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3697 case HOST_NOTIFICATION_NOISE_STATS:{ 4603 case HOST_NOTIFICATION_NOISE_STATS:{
3698 if (notif->size == sizeof(u32)) { 4604 if (notif->size == sizeof(u32)) {
3699 priv->last_noise = 4605 priv->last_noise =
3700 (u8) (notif->u.noise.value & 0xff); 4606 (u8) (le32_to_cpu(notif->u.noise.value) &
4607 0xff);
3701 average_add(&priv->average_noise, 4608 average_add(&priv->average_noise,
3702 priv->last_noise); 4609 priv->last_noise);
3703 break; 4610 break;
@@ -3730,43 +4637,43 @@ static int ipw_queue_reset(struct ipw_priv *priv)
3730 ipw_tx_queue_free(priv); 4637 ipw_tx_queue_free(priv);
3731 /* Tx CMD queue */ 4638 /* Tx CMD queue */
3732 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd, 4639 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,
3733 CX2_TX_CMD_QUEUE_READ_INDEX, 4640 IPW_TX_CMD_QUEUE_READ_INDEX,
3734 CX2_TX_CMD_QUEUE_WRITE_INDEX, 4641 IPW_TX_CMD_QUEUE_WRITE_INDEX,
3735 CX2_TX_CMD_QUEUE_BD_BASE, 4642 IPW_TX_CMD_QUEUE_BD_BASE,
3736 CX2_TX_CMD_QUEUE_BD_SIZE); 4643 IPW_TX_CMD_QUEUE_BD_SIZE);
3737 if (rc) { 4644 if (rc) {
3738 IPW_ERROR("Tx Cmd queue init failed\n"); 4645 IPW_ERROR("Tx Cmd queue init failed\n");
3739 goto error; 4646 goto error;
3740 } 4647 }
3741 /* Tx queue(s) */ 4648 /* Tx queue(s) */
3742 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx, 4649 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,
3743 CX2_TX_QUEUE_0_READ_INDEX, 4650 IPW_TX_QUEUE_0_READ_INDEX,
3744 CX2_TX_QUEUE_0_WRITE_INDEX, 4651 IPW_TX_QUEUE_0_WRITE_INDEX,
3745 CX2_TX_QUEUE_0_BD_BASE, CX2_TX_QUEUE_0_BD_SIZE); 4652 IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);
3746 if (rc) { 4653 if (rc) {
3747 IPW_ERROR("Tx 0 queue init failed\n"); 4654 IPW_ERROR("Tx 0 queue init failed\n");
3748 goto error; 4655 goto error;
3749 } 4656 }
3750 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx, 4657 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,
3751 CX2_TX_QUEUE_1_READ_INDEX, 4658 IPW_TX_QUEUE_1_READ_INDEX,
3752 CX2_TX_QUEUE_1_WRITE_INDEX, 4659 IPW_TX_QUEUE_1_WRITE_INDEX,
3753 CX2_TX_QUEUE_1_BD_BASE, CX2_TX_QUEUE_1_BD_SIZE); 4660 IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);
3754 if (rc) { 4661 if (rc) {
3755 IPW_ERROR("Tx 1 queue init failed\n"); 4662 IPW_ERROR("Tx 1 queue init failed\n");
3756 goto error; 4663 goto error;
3757 } 4664 }
3758 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx, 4665 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,
3759 CX2_TX_QUEUE_2_READ_INDEX, 4666 IPW_TX_QUEUE_2_READ_INDEX,
3760 CX2_TX_QUEUE_2_WRITE_INDEX, 4667 IPW_TX_QUEUE_2_WRITE_INDEX,
3761 CX2_TX_QUEUE_2_BD_BASE, CX2_TX_QUEUE_2_BD_SIZE); 4668 IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);
3762 if (rc) { 4669 if (rc) {
3763 IPW_ERROR("Tx 2 queue init failed\n"); 4670 IPW_ERROR("Tx 2 queue init failed\n");
3764 goto error; 4671 goto error;
3765 } 4672 }
3766 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx, 4673 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,
3767 CX2_TX_QUEUE_3_READ_INDEX, 4674 IPW_TX_QUEUE_3_READ_INDEX,
3768 CX2_TX_QUEUE_3_WRITE_INDEX, 4675 IPW_TX_QUEUE_3_WRITE_INDEX,
3769 CX2_TX_QUEUE_3_BD_BASE, CX2_TX_QUEUE_3_BD_SIZE); 4676 IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);
3770 if (rc) { 4677 if (rc) {
3771 IPW_ERROR("Tx 3 queue init failed\n"); 4678 IPW_ERROR("Tx 3 queue init failed\n");
3772 goto error; 4679 goto error;
@@ -3814,9 +4721,10 @@ static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
3814 priv->tx_packets++; 4721 priv->tx_packets++;
3815 } 4722 }
3816 done: 4723 done:
3817 if (ipw_queue_space(q) > q->low_mark && qindex >= 0) { 4724 if ((ipw_queue_space(q) > q->low_mark) &&
3818 __maybe_wake_tx(priv); 4725 (qindex >= 0) &&
3819 } 4726 (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
4727 netif_wake_queue(priv->net_dev);
3820 used = q->first_empty - q->last_used; 4728 used = q->first_empty - q->last_used;
3821 if (used < 0) 4729 if (used < 0)
3822 used += q->n_bd; 4730 used += q->n_bd;
@@ -3857,7 +4765,7 @@ static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, void *buf,
3857 * Rx theory of operation 4765 * Rx theory of operation
3858 * 4766 *
3859 * The host allocates 32 DMA target addresses and passes the host address 4767 * The host allocates 32 DMA target addresses and passes the host address
3860 * to the firmware at register CX2_RFDS_TABLE_LOWER + N * RFD_SIZE where N is 4768 * to the firmware at register IPW_RFDS_TABLE_LOWER + N * RFD_SIZE where N is
3861 * 0 to 31 4769 * 0 to 31
3862 * 4770 *
3863 * Rx Queue Indexes 4771 * Rx Queue Indexes
@@ -3941,7 +4849,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
3941 rxb = list_entry(element, struct ipw_rx_mem_buffer, list); 4849 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3942 list_del(element); 4850 list_del(element);
3943 4851
3944 ipw_write32(priv, CX2_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE, 4852 ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,
3945 rxb->dma_addr); 4853 rxb->dma_addr);
3946 rxq->queue[rxq->write] = rxb; 4854 rxq->queue[rxq->write] = rxb;
3947 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE; 4855 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;
@@ -3956,7 +4864,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv)
3956 4864
3957 /* If we've added more space for the firmware to place data, tell it */ 4865 /* If we've added more space for the firmware to place data, tell it */
3958 if (write != rxq->write) 4866 if (write != rxq->write)
3959 ipw_write32(priv, CX2_RX_WRITE_INDEX, rxq->write); 4867 ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);
3960} 4868}
3961 4869
3962/* 4870/*
@@ -3977,7 +4885,7 @@ static void ipw_rx_queue_replenish(void *data)
3977 while (!list_empty(&rxq->rx_used)) { 4885 while (!list_empty(&rxq->rx_used)) {
3978 element = rxq->rx_used.next; 4886 element = rxq->rx_used.next;
3979 rxb = list_entry(element, struct ipw_rx_mem_buffer, list); 4887 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);
3980 rxb->skb = alloc_skb(CX2_RX_BUF_SIZE, GFP_ATOMIC); 4888 rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);
3981 if (!rxb->skb) { 4889 if (!rxb->skb) {
3982 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n", 4890 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",
3983 priv->net_dev->name); 4891 priv->net_dev->name);
@@ -3991,7 +4899,7 @@ static void ipw_rx_queue_replenish(void *data)
3991 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data; 4899 rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data;
3992 rxb->dma_addr = 4900 rxb->dma_addr =
3993 pci_map_single(priv->pci_dev, rxb->skb->data, 4901 pci_map_single(priv->pci_dev, rxb->skb->data,
3994 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 4902 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
3995 4903
3996 list_add_tail(&rxb->list, &rxq->rx_free); 4904 list_add_tail(&rxb->list, &rxq->rx_free);
3997 rxq->free_count++; 4905 rxq->free_count++;
@@ -4001,6 +4909,14 @@ static void ipw_rx_queue_replenish(void *data)
4001 ipw_rx_queue_restock(priv); 4909 ipw_rx_queue_restock(priv);
4002} 4910}
4003 4911
4912static void ipw_bg_rx_queue_replenish(void *data)
4913{
4914 struct ipw_priv *priv = data;
4915 down(&priv->sem);
4916 ipw_rx_queue_replenish(data);
4917 up(&priv->sem);
4918}
4919
4004/* Assumes that the skb field of the buffers in 'pool' is kept accurate. 4920/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
4005 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL 4921 * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
4006 * This free routine walks the list of POOL entries and if SKB is set to 4922 * This free routine walks the list of POOL entries and if SKB is set to
@@ -4016,7 +4932,7 @@ static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)
4016 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { 4932 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
4017 if (rxq->pool[i].skb != NULL) { 4933 if (rxq->pool[i].skb != NULL) {
4018 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, 4934 pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
4019 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 4935 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
4020 dev_kfree_skb(rxq->pool[i].skb); 4936 dev_kfree_skb(rxq->pool[i].skb);
4021 } 4937 }
4022 } 4938 }
@@ -4135,8 +5051,18 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4135 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES); 5051 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
4136 rates->num_rates = 0; 5052 rates->num_rates = 0;
4137 for (i = 0; i < num_rates; i++) { 5053 for (i = 0; i < num_rates; i++) {
4138 if (!ipw_is_rate_in_mask 5054 if (!ipw_is_rate_in_mask(priv, network->mode,
4139 (priv, network->mode, network->rates[i])) { 5055 network->rates[i])) {
5056
5057 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
5058 IPW_DEBUG_SCAN("Adding masked mandatory "
5059 "rate %02X\n",
5060 network->rates[i]);
5061 rates->supported_rates[rates->num_rates++] =
5062 network->rates[i];
5063 continue;
5064 }
5065
4140 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 5066 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4141 network->rates[i], priv->rates_mask); 5067 network->rates[i], priv->rates_mask);
4142 continue; 5068 continue;
@@ -4145,11 +5071,20 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4145 rates->supported_rates[rates->num_rates++] = network->rates[i]; 5071 rates->supported_rates[rates->num_rates++] = network->rates[i];
4146 } 5072 }
4147 5073
4148 num_rates = 5074 num_rates = min(network->rates_ex_len,
4149 min(network->rates_ex_len, (u8) (IPW_MAX_RATES - num_rates)); 5075 (u8) (IPW_MAX_RATES - num_rates));
4150 for (i = 0; i < num_rates; i++) { 5076 for (i = 0; i < num_rates; i++) {
4151 if (!ipw_is_rate_in_mask 5077 if (!ipw_is_rate_in_mask(priv, network->mode,
4152 (priv, network->mode, network->rates_ex[i])) { 5078 network->rates_ex[i])) {
5079 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
5080 IPW_DEBUG_SCAN("Adding masked mandatory "
5081 "rate %02X\n",
5082 network->rates_ex[i]);
5083 rates->supported_rates[rates->num_rates++] =
5084 network->rates[i];
5085 continue;
5086 }
5087
4153 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 5088 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4154 network->rates_ex[i], priv->rates_mask); 5089 network->rates_ex[i], priv->rates_mask);
4155 continue; 5090 continue;
@@ -4159,7 +5094,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4159 network->rates_ex[i]; 5094 network->rates_ex[i];
4160 } 5095 }
4161 5096
4162 return rates->num_rates; 5097 return 1;
4163} 5098}
4164 5099
4165static inline void ipw_copy_rates(struct ipw_supported_rates *dest, 5100static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
@@ -4241,6 +5176,216 @@ struct ipw_network_match {
4241 struct ipw_supported_rates rates; 5176 struct ipw_supported_rates rates;
4242}; 5177};
4243 5178
5179static int ipw_find_adhoc_network(struct ipw_priv *priv,
5180 struct ipw_network_match *match,
5181 struct ieee80211_network *network,
5182 int roaming)
5183{
5184 struct ipw_supported_rates rates;
5185
5186 /* Verify that this network's capability is compatible with the
5187 * current mode (AdHoc or Infrastructure) */
5188 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
5189 !(network->capability & WLAN_CAPABILITY_IBSS))) {
5190 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to "
5191 "capability mismatch.\n",
5192 escape_essid(network->ssid, network->ssid_len),
5193 MAC_ARG(network->bssid));
5194 return 0;
5195 }
5196
5197 /* If we do not have an ESSID for this AP, we can not associate with
5198 * it */
5199 if (network->flags & NETWORK_EMPTY_ESSID) {
5200 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5201 "because of hidden ESSID.\n",
5202 escape_essid(network->ssid, network->ssid_len),
5203 MAC_ARG(network->bssid));
5204 return 0;
5205 }
5206
5207 if (unlikely(roaming)) {
5208 /* If we are roaming, then ensure check if this is a valid
5209 * network to try and roam to */
5210 if ((network->ssid_len != match->network->ssid_len) ||
5211 memcmp(network->ssid, match->network->ssid,
5212 network->ssid_len)) {
5213 IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded "
5214 "because of non-network ESSID.\n",
5215 escape_essid(network->ssid,
5216 network->ssid_len),
5217 MAC_ARG(network->bssid));
5218 return 0;
5219 }
5220 } else {
5221 /* If an ESSID has been configured then compare the broadcast
5222 * ESSID to ours */
5223 if ((priv->config & CFG_STATIC_ESSID) &&
5224 ((network->ssid_len != priv->essid_len) ||
5225 memcmp(network->ssid, priv->essid,
5226 min(network->ssid_len, priv->essid_len)))) {
5227 char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
5228
5229 strncpy(escaped,
5230 escape_essid(network->ssid, network->ssid_len),
5231 sizeof(escaped));
5232 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5233 "because of ESSID mismatch: '%s'.\n",
5234 escaped, MAC_ARG(network->bssid),
5235 escape_essid(priv->essid,
5236 priv->essid_len));
5237 return 0;
5238 }
5239 }
5240
5241 /* If the old network rate is better than this one, don't bother
5242 * testing everything else. */
5243
5244 if (network->time_stamp[0] < match->network->time_stamp[0]) {
5245 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5246 "current network.\n",
5247 escape_essid(match->network->ssid,
5248 match->network->ssid_len));
5249 return 0;
5250 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {
5251 IPW_DEBUG_MERGE("Network '%s excluded because newer than "
5252 "current network.\n",
5253 escape_essid(match->network->ssid,
5254 match->network->ssid_len));
5255 return 0;
5256 }
5257
5258 /* Now go through and see if the requested network is valid... */
5259 if (priv->ieee->scan_age != 0 &&
5260 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
5261 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5262 "because of age: %lums.\n",
5263 escape_essid(network->ssid, network->ssid_len),
5264 MAC_ARG(network->bssid),
5265 1000 * (jiffies - network->last_scanned) / HZ);
5266 return 0;
5267 }
5268
5269 if ((priv->config & CFG_STATIC_CHANNEL) &&
5270 (network->channel != priv->channel)) {
5271 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5272 "because of channel mismatch: %d != %d.\n",
5273 escape_essid(network->ssid, network->ssid_len),
5274 MAC_ARG(network->bssid),
5275 network->channel, priv->channel);
5276 return 0;
5277 }
5278
5279 /* Verify privacy compatability */
5280 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
5281 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
5282 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5283 "because of privacy mismatch: %s != %s.\n",
5284 escape_essid(network->ssid, network->ssid_len),
5285 MAC_ARG(network->bssid),
5286 priv->
5287 capability & CAP_PRIVACY_ON ? "on" : "off",
5288 network->
5289 capability & WLAN_CAPABILITY_PRIVACY ? "on" :
5290 "off");
5291 return 0;
5292 }
5293
5294 if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
5295 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5296 "because of the same BSSID match: " MAC_FMT
5297 ".\n", escape_essid(network->ssid,
5298 network->ssid_len),
5299 MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
5300 return 0;
5301 }
5302
5303 /* Filter out any incompatible freq / mode combinations */
5304 if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
5305 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5306 "because of invalid frequency/mode "
5307 "combination.\n",
5308 escape_essid(network->ssid, network->ssid_len),
5309 MAC_ARG(network->bssid));
5310 return 0;
5311 }
5312
5313 /* Ensure that the rates supported by the driver are compatible with
5314 * this AP, including verification of basic rates (mandatory) */
5315 if (!ipw_compatible_rates(priv, network, &rates)) {
5316 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5317 "because configured rate mask excludes "
5318 "AP mandatory rate.\n",
5319 escape_essid(network->ssid, network->ssid_len),
5320 MAC_ARG(network->bssid));
5321 return 0;
5322 }
5323
5324 if (rates.num_rates == 0) {
5325 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
5326 "because of no compatible rates.\n",
5327 escape_essid(network->ssid, network->ssid_len),
5328 MAC_ARG(network->bssid));
5329 return 0;
5330 }
5331
5332 /* TODO: Perform any further minimal comparititive tests. We do not
5333 * want to put too much policy logic here; intelligent scan selection
5334 * should occur within a generic IEEE 802.11 user space tool. */
5335
5336 /* Set up 'new' AP to this network */
5337 ipw_copy_rates(&match->rates, &rates);
5338 match->network = network;
5339 IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n",
5340 escape_essid(network->ssid, network->ssid_len),
5341 MAC_ARG(network->bssid));
5342
5343 return 1;
5344}
5345
5346static void ipw_merge_adhoc_network(void *data)
5347{
5348 struct ipw_priv *priv = data;
5349 struct ieee80211_network *network = NULL;
5350 struct ipw_network_match match = {
5351 .network = priv->assoc_network
5352 };
5353
5354 if ((priv->status & STATUS_ASSOCIATED) &&
5355 (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5356 /* First pass through ROAM process -- look for a better
5357 * network */
5358 unsigned long flags;
5359
5360 spin_lock_irqsave(&priv->ieee->lock, flags);
5361 list_for_each_entry(network, &priv->ieee->network_list, list) {
5362 if (network != priv->assoc_network)
5363 ipw_find_adhoc_network(priv, &match, network,
5364 1);
5365 }
5366 spin_unlock_irqrestore(&priv->ieee->lock, flags);
5367
5368 if (match.network == priv->assoc_network) {
5369 IPW_DEBUG_MERGE("No better ADHOC in this network to "
5370 "merge to.\n");
5371 return;
5372 }
5373
5374 down(&priv->sem);
5375 if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
5376 IPW_DEBUG_MERGE("remove network %s\n",
5377 escape_essid(priv->essid,
5378 priv->essid_len));
5379 ipw_remove_current_network(priv);
5380 }
5381
5382 ipw_disassociate(priv);
5383 priv->assoc_network = match.network;
5384 up(&priv->sem);
5385 return;
5386 }
5387}
5388
4244static int ipw_best_network(struct ipw_priv *priv, 5389static int ipw_best_network(struct ipw_priv *priv,
4245 struct ipw_network_match *match, 5390 struct ipw_network_match *match,
4246 struct ieee80211_network *network, int roaming) 5391 struct ieee80211_network *network, int roaming)
@@ -4322,9 +5467,9 @@ static int ipw_best_network(struct ipw_priv *priv,
4322 /* If this network has already had an association attempt within the 5467 /* If this network has already had an association attempt within the
4323 * last 3 seconds, do not try and associate again... */ 5468 * last 3 seconds, do not try and associate again... */
4324 if (network->last_associate && 5469 if (network->last_associate &&
4325 time_after(network->last_associate + (HZ * 5UL), jiffies)) { 5470 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
4326 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5471 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4327 "because of storming (%lu since last " 5472 "because of storming (%lus since last "
4328 "assoc attempt).\n", 5473 "assoc attempt).\n",
4329 escape_essid(network->ssid, network->ssid_len), 5474 escape_essid(network->ssid, network->ssid_len),
4330 MAC_ARG(network->bssid), 5475 MAC_ARG(network->bssid),
@@ -4334,12 +5479,12 @@ static int ipw_best_network(struct ipw_priv *priv,
4334 5479
4335 /* Now go through and see if the requested network is valid... */ 5480 /* Now go through and see if the requested network is valid... */
4336 if (priv->ieee->scan_age != 0 && 5481 if (priv->ieee->scan_age != 0 &&
4337 jiffies - network->last_scanned > priv->ieee->scan_age) { 5482 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
4338 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5483 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4339 "because of age: %lums.\n", 5484 "because of age: %lums.\n",
4340 escape_essid(network->ssid, network->ssid_len), 5485 escape_essid(network->ssid, network->ssid_len),
4341 MAC_ARG(network->bssid), 5486 MAC_ARG(network->bssid),
4342 (jiffies - network->last_scanned) / (HZ / 100)); 5487 1000 * (jiffies - network->last_scanned) / HZ);
4343 return 0; 5488 return 0;
4344 } 5489 }
4345 5490
@@ -4367,6 +5512,15 @@ static int ipw_best_network(struct ipw_priv *priv,
4367 return 0; 5512 return 0;
4368 } 5513 }
4369 5514
5515 if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 ||
5516 network->rsn_ie_len > 0)) {
5517 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5518 "because of WPA capability mismatch.\n",
5519 escape_essid(network->ssid, network->ssid_len),
5520 MAC_ARG(network->bssid));
5521 return 0;
5522 }
5523
4370 if ((priv->config & CFG_STATIC_BSSID) && 5524 if ((priv->config & CFG_STATIC_BSSID) &&
4371 memcmp(network->bssid, priv->bssid, ETH_ALEN)) { 5525 memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
4372 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5526 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
@@ -4386,7 +5540,26 @@ static int ipw_best_network(struct ipw_priv *priv,
4386 return 0; 5540 return 0;
4387 } 5541 }
4388 5542
4389 ipw_compatible_rates(priv, network, &rates); 5543 /* Filter out invalid channel in current GEO */
5544 if (!ipw_is_valid_channel(priv->ieee, network->channel)) {
5545 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5546 "because of invalid channel in current GEO\n",
5547 escape_essid(network->ssid, network->ssid_len),
5548 MAC_ARG(network->bssid));
5549 return 0;
5550 }
5551
5552 /* Ensure that the rates supported by the driver are compatible with
5553 * this AP, including verification of basic rates (mandatory) */
5554 if (!ipw_compatible_rates(priv, network, &rates)) {
5555 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
5556 "because configured rate mask excludes "
5557 "AP mandatory rate.\n",
5558 escape_essid(network->ssid, network->ssid_len),
5559 MAC_ARG(network->bssid));
5560 return 0;
5561 }
5562
4390 if (rates.num_rates == 0) { 5563 if (rates.num_rates == 0) {
4391 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 5564 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4392 "because of no compatible rates.\n", 5565 "because of no compatible rates.\n",
@@ -4413,6 +5586,9 @@ static int ipw_best_network(struct ipw_priv *priv,
4413static void ipw_adhoc_create(struct ipw_priv *priv, 5586static void ipw_adhoc_create(struct ipw_priv *priv,
4414 struct ieee80211_network *network) 5587 struct ieee80211_network *network)
4415{ 5588{
5589 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5590 int i;
5591
4416 /* 5592 /*
4417 * For the purposes of scanning, we can set our wireless mode 5593 * For the purposes of scanning, we can set our wireless mode
4418 * to trigger scans across combinations of bands, but when it 5594 * to trigger scans across combinations of bands, but when it
@@ -4423,22 +5599,47 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4423 * chossen band. Attempting to create a new ad-hoc network 5599 * chossen band. Attempting to create a new ad-hoc network
4424 * with an invalid channel for wireless mode will trigger a 5600 * with an invalid channel for wireless mode will trigger a
4425 * FW fatal error. 5601 * FW fatal error.
5602 *
4426 */ 5603 */
4427 network->mode = is_valid_channel(priv->ieee->mode, priv->channel); 5604 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
4428 if (network->mode) { 5605 case IEEE80211_52GHZ_BAND:
4429 network->channel = priv->channel; 5606 network->mode = IEEE_A;
4430 } else { 5607 i = ipw_channel_to_index(priv->ieee, priv->channel);
5608 if (i == -1)
5609 BUG();
5610 if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5611 IPW_WARNING("Overriding invalid channel\n");
5612 priv->channel = geo->a[0].channel;
5613 }
5614 break;
5615
5616 case IEEE80211_24GHZ_BAND:
5617 if (priv->ieee->mode & IEEE_G)
5618 network->mode = IEEE_G;
5619 else
5620 network->mode = IEEE_B;
5621 i = ipw_channel_to_index(priv->ieee, priv->channel);
5622 if (i == -1)
5623 BUG();
5624 if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
5625 IPW_WARNING("Overriding invalid channel\n");
5626 priv->channel = geo->bg[0].channel;
5627 }
5628 break;
5629
5630 default:
4431 IPW_WARNING("Overriding invalid channel\n"); 5631 IPW_WARNING("Overriding invalid channel\n");
4432 if (priv->ieee->mode & IEEE_A) { 5632 if (priv->ieee->mode & IEEE_A) {
4433 network->mode = IEEE_A; 5633 network->mode = IEEE_A;
4434 priv->channel = band_a_active_channel[0]; 5634 priv->channel = geo->a[0].channel;
4435 } else if (priv->ieee->mode & IEEE_G) { 5635 } else if (priv->ieee->mode & IEEE_G) {
4436 network->mode = IEEE_G; 5636 network->mode = IEEE_G;
4437 priv->channel = band_b_active_channel[0]; 5637 priv->channel = geo->bg[0].channel;
4438 } else { 5638 } else {
4439 network->mode = IEEE_B; 5639 network->mode = IEEE_B;
4440 priv->channel = band_b_active_channel[0]; 5640 priv->channel = geo->bg[0].channel;
4441 } 5641 }
5642 break;
4442 } 5643 }
4443 5644
4444 network->channel = priv->channel; 5645 network->channel = priv->channel;
@@ -4448,6 +5649,8 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4448 memcpy(network->ssid, priv->essid, priv->essid_len); 5649 memcpy(network->ssid, priv->essid, priv->essid_len);
4449 memset(&network->stats, 0, sizeof(network->stats)); 5650 memset(&network->stats, 0, sizeof(network->stats));
4450 network->capability = WLAN_CAPABILITY_IBSS; 5651 network->capability = WLAN_CAPABILITY_IBSS;
5652 if (!(priv->config & CFG_PREAMBLE_LONG))
5653 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
4451 if (priv->capability & CAP_PRIVACY_ON) 5654 if (priv->capability & CAP_PRIVACY_ON)
4452 network->capability |= WLAN_CAPABILITY_PRIVACY; 5655 network->capability |= WLAN_CAPABILITY_PRIVACY;
4453 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH); 5656 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
@@ -4464,13 +5667,35 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4464 network->beacon_interval = 100; /* Default */ 5667 network->beacon_interval = 100; /* Default */
4465 network->listen_interval = 10; /* Default */ 5668 network->listen_interval = 10; /* Default */
4466 network->atim_window = 0; /* Default */ 5669 network->atim_window = 0; /* Default */
4467#ifdef CONFIG_IEEE80211_WPA
4468 network->wpa_ie_len = 0; 5670 network->wpa_ie_len = 0;
4469 network->rsn_ie_len = 0; 5671 network->rsn_ie_len = 0;
4470#endif /* CONFIG_IEEE80211_WPA */
4471} 5672}
4472 5673
4473static void ipw_send_wep_keys(struct ipw_priv *priv) 5674static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)
5675{
5676 struct ipw_tgi_tx_key *key;
5677 struct host_cmd cmd = {
5678 .cmd = IPW_CMD_TGI_TX_KEY,
5679 .len = sizeof(*key)
5680 };
5681
5682 if (!(priv->ieee->sec.flags & (1 << index)))
5683 return;
5684
5685 key = (struct ipw_tgi_tx_key *)&cmd.param;
5686 key->key_id = index;
5687 memcpy(key->key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);
5688 key->security_type = type;
5689 key->station_index = 0; /* always 0 for BSS */
5690 key->flags = 0;
5691 /* 0 for new key; previous value of counter (after fatal error) */
5692 key->tx_counter[0] = 0;
5693 key->tx_counter[1] = 0;
5694
5695 ipw_send_cmd(priv, &cmd);
5696}
5697
5698static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
4474{ 5699{
4475 struct ipw_wep_key *key; 5700 struct ipw_wep_key *key;
4476 int i; 5701 int i;
@@ -4483,19 +5708,97 @@ static void ipw_send_wep_keys(struct ipw_priv *priv)
4483 key->cmd_id = DINO_CMD_WEP_KEY; 5708 key->cmd_id = DINO_CMD_WEP_KEY;
4484 key->seq_num = 0; 5709 key->seq_num = 0;
4485 5710
5711 /* Note: AES keys cannot be set for multiple times.
5712 * Only set it at the first time. */
4486 for (i = 0; i < 4; i++) { 5713 for (i = 0; i < 4; i++) {
4487 key->key_index = i; 5714 key->key_index = i | type;
4488 if (!(priv->sec.flags & (1 << i))) { 5715 if (!(priv->ieee->sec.flags & (1 << i))) {
4489 key->key_size = 0; 5716 key->key_size = 0;
4490 } else { 5717 continue;
4491 key->key_size = priv->sec.key_sizes[i];
4492 memcpy(key->key, priv->sec.keys[i], key->key_size);
4493 } 5718 }
4494 5719
4495 if (ipw_send_cmd(priv, &cmd)) { 5720 key->key_size = priv->ieee->sec.key_sizes[i];
4496 IPW_ERROR("failed to send WEP_KEY command\n"); 5721 memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
4497 return; 5722
4498 } 5723 ipw_send_cmd(priv, &cmd);
5724 }
5725}
5726
5727static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)
5728{
5729 if (priv->ieee->host_encrypt)
5730 return;
5731
5732 switch (level) {
5733 case SEC_LEVEL_3:
5734 priv->sys_config.disable_unicast_decryption = 0;
5735 priv->ieee->host_decrypt = 0;
5736 break;
5737 case SEC_LEVEL_2:
5738 priv->sys_config.disable_unicast_decryption = 1;
5739 priv->ieee->host_decrypt = 1;
5740 break;
5741 case SEC_LEVEL_1:
5742 priv->sys_config.disable_unicast_decryption = 0;
5743 priv->ieee->host_decrypt = 0;
5744 break;
5745 case SEC_LEVEL_0:
5746 priv->sys_config.disable_unicast_decryption = 1;
5747 break;
5748 default:
5749 break;
5750 }
5751}
5752
5753static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)
5754{
5755 if (priv->ieee->host_encrypt)
5756 return;
5757
5758 switch (level) {
5759 case SEC_LEVEL_3:
5760 priv->sys_config.disable_multicast_decryption = 0;
5761 break;
5762 case SEC_LEVEL_2:
5763 priv->sys_config.disable_multicast_decryption = 1;
5764 break;
5765 case SEC_LEVEL_1:
5766 priv->sys_config.disable_multicast_decryption = 0;
5767 break;
5768 case SEC_LEVEL_0:
5769 priv->sys_config.disable_multicast_decryption = 1;
5770 break;
5771 default:
5772 break;
5773 }
5774}
5775
5776static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
5777{
5778 switch (priv->ieee->sec.level) {
5779 case SEC_LEVEL_3:
5780 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5781 ipw_send_tgi_tx_key(priv,
5782 DCT_FLAG_EXT_SECURITY_CCM,
5783 priv->ieee->sec.active_key);
5784
5785 if (!priv->ieee->host_mc_decrypt)
5786 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
5787 break;
5788 case SEC_LEVEL_2:
5789 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
5790 ipw_send_tgi_tx_key(priv,
5791 DCT_FLAG_EXT_SECURITY_TKIP,
5792 priv->ieee->sec.active_key);
5793 break;
5794 case SEC_LEVEL_1:
5795 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
5796 ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
5797 ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
5798 break;
5799 case SEC_LEVEL_0:
5800 default:
5801 break;
4499 } 5802 }
4500} 5803}
4501 5804
@@ -4503,9 +5806,12 @@ static void ipw_adhoc_check(void *data)
4503{ 5806{
4504 struct ipw_priv *priv = data; 5807 struct ipw_priv *priv = data;
4505 5808
4506 if (priv->missed_adhoc_beacons++ > priv->missed_beacon_threshold && 5809 if (priv->missed_adhoc_beacons++ > priv->disassociate_threshold &&
4507 !(priv->config & CFG_ADHOC_PERSIST)) { 5810 !(priv->config & CFG_ADHOC_PERSIST)) {
4508 IPW_DEBUG_SCAN("Disassociating due to missed beacons\n"); 5811 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
5812 IPW_DL_STATE | IPW_DL_ASSOC,
5813 "Missed beacon: %d - disassociate\n",
5814 priv->missed_adhoc_beacons);
4509 ipw_remove_current_network(priv); 5815 ipw_remove_current_network(priv);
4510 ipw_disassociate(priv); 5816 ipw_disassociate(priv);
4511 return; 5817 return;
@@ -4515,6 +5821,14 @@ static void ipw_adhoc_check(void *data)
4515 priv->assoc_request.beacon_interval); 5821 priv->assoc_request.beacon_interval);
4516} 5822}
4517 5823
5824static void ipw_bg_adhoc_check(void *data)
5825{
5826 struct ipw_priv *priv = data;
5827 down(&priv->sem);
5828 ipw_adhoc_check(data);
5829 up(&priv->sem);
5830}
5831
4518#ifdef CONFIG_IPW_DEBUG 5832#ifdef CONFIG_IPW_DEBUG
4519static void ipw_debug_config(struct ipw_priv *priv) 5833static void ipw_debug_config(struct ipw_priv *priv)
4520{ 5834{
@@ -4530,7 +5844,8 @@ static void ipw_debug_config(struct ipw_priv *priv)
4530 else 5844 else
4531 IPW_DEBUG_INFO("ESSID unlocked.\n"); 5845 IPW_DEBUG_INFO("ESSID unlocked.\n");
4532 if (priv->config & CFG_STATIC_BSSID) 5846 if (priv->config & CFG_STATIC_BSSID)
4533 IPW_DEBUG_INFO("BSSID locked to %d\n", priv->channel); 5847 IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n",
5848 MAC_ARG(priv->bssid));
4534 else 5849 else
4535 IPW_DEBUG_INFO("BSSID unlocked.\n"); 5850 IPW_DEBUG_INFO("BSSID unlocked.\n");
4536 if (priv->capability & CAP_PRIVACY_ON) 5851 if (priv->capability & CAP_PRIVACY_ON)
@@ -4543,8 +5858,7 @@ static void ipw_debug_config(struct ipw_priv *priv)
4543#define ipw_debug_config(x) do {} while (0) 5858#define ipw_debug_config(x) do {} while (0)
4544#endif 5859#endif
4545 5860
4546static inline void ipw_set_fixed_rate(struct ipw_priv *priv, 5861static inline void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
4547 struct ieee80211_network *network)
4548{ 5862{
4549 /* TODO: Verify that this works... */ 5863 /* TODO: Verify that this works... */
4550 struct ipw_fixed_rate fr = { 5864 struct ipw_fixed_rate fr = {
@@ -4561,6 +5875,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4561 /* IEEE_A */ 5875 /* IEEE_A */
4562 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) { 5876 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
4563 /* Invalid fixed rate mask */ 5877 /* Invalid fixed rate mask */
5878 IPW_DEBUG_WX
5879 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4564 fr.tx_rates = 0; 5880 fr.tx_rates = 0;
4565 break; 5881 break;
4566 } 5882 }
@@ -4570,9 +5886,11 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4570 5886
4571 default: /* 2.4Ghz or Mixed */ 5887 default: /* 2.4Ghz or Mixed */
4572 /* IEEE_B */ 5888 /* IEEE_B */
4573 if (network->mode == IEEE_B) { 5889 if (mode == IEEE_B) {
4574 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) { 5890 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
4575 /* Invalid fixed rate mask */ 5891 /* Invalid fixed rate mask */
5892 IPW_DEBUG_WX
5893 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4576 fr.tx_rates = 0; 5894 fr.tx_rates = 0;
4577 } 5895 }
4578 break; 5896 break;
@@ -4582,6 +5900,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4582 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK | 5900 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
4583 IEEE80211_OFDM_RATES_MASK)) { 5901 IEEE80211_OFDM_RATES_MASK)) {
4584 /* Invalid fixed rate mask */ 5902 /* Invalid fixed rate mask */
5903 IPW_DEBUG_WX
5904 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4585 fr.tx_rates = 0; 5905 fr.tx_rates = 0;
4586 break; 5906 break;
4587 } 5907 }
@@ -4609,6 +5929,1112 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4609 ipw_write_reg32(priv, reg, *(u32 *) & fr); 5929 ipw_write_reg32(priv, reg, *(u32 *) & fr);
4610} 5930}
4611 5931
5932static void ipw_abort_scan(struct ipw_priv *priv)
5933{
5934 int err;
5935
5936 if (priv->status & STATUS_SCAN_ABORTING) {
5937 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
5938 return;
5939 }
5940 priv->status |= STATUS_SCAN_ABORTING;
5941
5942 err = ipw_send_scan_abort(priv);
5943 if (err)
5944 IPW_DEBUG_HC("Request to abort scan failed.\n");
5945}
5946
5947static void ipw_add_scan_channels(struct ipw_priv *priv,
5948 struct ipw_scan_request_ext *scan,
5949 int scan_type)
5950{
5951 int channel_index = 0;
5952 const struct ieee80211_geo *geo;
5953 int i;
5954
5955 geo = ipw_get_geo(priv->ieee);
5956
5957 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5958 int start = channel_index;
5959 for (i = 0; i < geo->a_channels; i++) {
5960 if ((priv->status & STATUS_ASSOCIATED) &&
5961 geo->a[i].channel == priv->channel)
5962 continue;
5963 channel_index++;
5964 scan->channels_list[channel_index] = geo->a[i].channel;
5965 ipw_set_scan_type(scan, channel_index,
5966 geo->a[i].
5967 flags & IEEE80211_CH_PASSIVE_ONLY ?
5968 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
5969 scan_type);
5970 }
5971
5972 if (start != channel_index) {
5973 scan->channels_list[start] = (u8) (IPW_A_MODE << 6) |
5974 (channel_index - start);
5975 channel_index++;
5976 }
5977 }
5978
5979 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
5980 int start = channel_index;
5981 if (priv->config & CFG_SPEED_SCAN) {
5982 int index;
5983 u8 channels[IEEE80211_24GHZ_CHANNELS] = {
5984 /* nop out the list */
5985 [0] = 0
5986 };
5987
5988 u8 channel;
5989 while (channel_index < IPW_SCAN_CHANNELS) {
5990 channel =
5991 priv->speed_scan[priv->speed_scan_pos];
5992 if (channel == 0) {
5993 priv->speed_scan_pos = 0;
5994 channel = priv->speed_scan[0];
5995 }
5996 if ((priv->status & STATUS_ASSOCIATED) &&
5997 channel == priv->channel) {
5998 priv->speed_scan_pos++;
5999 continue;
6000 }
6001
6002 /* If this channel has already been
6003 * added in scan, break from loop
6004 * and this will be the first channel
6005 * in the next scan.
6006 */
6007 if (channels[channel - 1] != 0)
6008 break;
6009
6010 channels[channel - 1] = 1;
6011 priv->speed_scan_pos++;
6012 channel_index++;
6013 scan->channels_list[channel_index] = channel;
6014 index =
6015 ipw_channel_to_index(priv->ieee, channel);
6016 ipw_set_scan_type(scan, channel_index,
6017 geo->bg[index].
6018 flags &
6019 IEEE80211_CH_PASSIVE_ONLY ?
6020 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6021 : scan_type);
6022 }
6023 } else {
6024 for (i = 0; i < geo->bg_channels; i++) {
6025 if ((priv->status & STATUS_ASSOCIATED) &&
6026 geo->bg[i].channel == priv->channel)
6027 continue;
6028 channel_index++;
6029 scan->channels_list[channel_index] =
6030 geo->bg[i].channel;
6031 ipw_set_scan_type(scan, channel_index,
6032 geo->bg[i].
6033 flags &
6034 IEEE80211_CH_PASSIVE_ONLY ?
6035 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
6036 : scan_type);
6037 }
6038 }
6039
6040 if (start != channel_index) {
6041 scan->channels_list[start] = (u8) (IPW_B_MODE << 6) |
6042 (channel_index - start);
6043 }
6044 }
6045}
6046
6047static int ipw_request_scan(struct ipw_priv *priv)
6048{
6049 struct ipw_scan_request_ext scan;
6050 int err = 0, scan_type;
6051
6052 if (!(priv->status & STATUS_INIT) ||
6053 (priv->status & STATUS_EXIT_PENDING))
6054 return 0;
6055
6056 down(&priv->sem);
6057
6058 if (priv->status & STATUS_SCANNING) {
6059 IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n");
6060 priv->status |= STATUS_SCAN_PENDING;
6061 goto done;
6062 }
6063
6064 if (!(priv->status & STATUS_SCAN_FORCED) &&
6065 priv->status & STATUS_SCAN_ABORTING) {
6066 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
6067 priv->status |= STATUS_SCAN_PENDING;
6068 goto done;
6069 }
6070
6071 if (priv->status & STATUS_RF_KILL_MASK) {
6072 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
6073 priv->status |= STATUS_SCAN_PENDING;
6074 goto done;
6075 }
6076
6077 memset(&scan, 0, sizeof(scan));
6078
6079 if (priv->config & CFG_SPEED_SCAN)
6080 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6081 cpu_to_le16(30);
6082 else
6083 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
6084 cpu_to_le16(20);
6085
6086 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
6087 cpu_to_le16(20);
6088 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
6089
6090 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
6091
6092#ifdef CONFIG_IPW2200_MONITOR
6093 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
6094 u8 channel;
6095 u8 band = 0;
6096
6097 switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
6098 case IEEE80211_52GHZ_BAND:
6099 band = (u8) (IPW_A_MODE << 6) | 1;
6100 channel = priv->channel;
6101 break;
6102
6103 case IEEE80211_24GHZ_BAND:
6104 band = (u8) (IPW_B_MODE << 6) | 1;
6105 channel = priv->channel;
6106 break;
6107
6108 default:
6109 band = (u8) (IPW_B_MODE << 6) | 1;
6110 channel = 9;
6111 break;
6112 }
6113
6114 scan.channels_list[0] = band;
6115 scan.channels_list[1] = channel;
6116 ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
6117
6118 /* NOTE: The card will sit on this channel for this time
6119 * period. Scan aborts are timing sensitive and frequently
6120 * result in firmware restarts. As such, it is best to
6121 * set a small dwell_time here and just keep re-issuing
6122 * scans. Otherwise fast channel hopping will not actually
6123 * hop channels.
6124 *
6125 * TODO: Move SPEED SCAN support to all modes and bands */
6126 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
6127 cpu_to_le16(2000);
6128 } else {
6129#endif /* CONFIG_IPW2200_MONITOR */
6130 /* If we are roaming, then make this a directed scan for the
6131 * current network. Otherwise, ensure that every other scan
6132 * is a fast channel hop scan */
6133 if ((priv->status & STATUS_ROAMING)
6134 || (!(priv->status & STATUS_ASSOCIATED)
6135 && (priv->config & CFG_STATIC_ESSID)
6136 && (le32_to_cpu(scan.full_scan_index) % 2))) {
6137 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
6138 if (err) {
6139 IPW_DEBUG_HC("Attempt to send SSID command "
6140 "failed.\n");
6141 goto done;
6142 }
6143
6144 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
6145 } else
6146 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
6147
6148 ipw_add_scan_channels(priv, &scan, scan_type);
6149#ifdef CONFIG_IPW2200_MONITOR
6150 }
6151#endif
6152
6153 err = ipw_send_scan_request_ext(priv, &scan);
6154 if (err) {
6155 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
6156 goto done;
6157 }
6158
6159 priv->status |= STATUS_SCANNING;
6160 priv->status &= ~STATUS_SCAN_PENDING;
6161 queue_delayed_work(priv->workqueue, &priv->scan_check,
6162 IPW_SCAN_CHECK_WATCHDOG);
6163 done:
6164 up(&priv->sem);
6165 return err;
6166}
6167
6168static void ipw_bg_abort_scan(void *data)
6169{
6170 struct ipw_priv *priv = data;
6171 down(&priv->sem);
6172 ipw_abort_scan(data);
6173 up(&priv->sem);
6174}
6175
6176static int ipw_wpa_enable(struct ipw_priv *priv, int value)
6177{
6178 /* This is called when wpa_supplicant loads and closes the driver
6179 * interface. */
6180 priv->ieee->wpa_enabled = value;
6181 return 0;
6182}
6183
6184static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
6185{
6186 struct ieee80211_device *ieee = priv->ieee;
6187 struct ieee80211_security sec = {
6188 .flags = SEC_AUTH_MODE,
6189 };
6190 int ret = 0;
6191
6192 if (value & IW_AUTH_ALG_SHARED_KEY) {
6193 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
6194 ieee->open_wep = 0;
6195 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
6196 sec.auth_mode = WLAN_AUTH_OPEN;
6197 ieee->open_wep = 1;
6198 } else
6199 return -EINVAL;
6200
6201 if (ieee->set_security)
6202 ieee->set_security(ieee->dev, &sec);
6203 else
6204 ret = -EOPNOTSUPP;
6205
6206 return ret;
6207}
6208
6209void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
6210{
6211 /* make sure WPA is enabled */
6212 ipw_wpa_enable(priv, 1);
6213
6214 ipw_disassociate(priv);
6215}
6216
6217static int ipw_set_rsn_capa(struct ipw_priv *priv,
6218 char *capabilities, int length)
6219{
6220 struct host_cmd cmd = {
6221 .cmd = IPW_CMD_RSN_CAPABILITIES,
6222 .len = length,
6223 };
6224
6225 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
6226
6227 memcpy(cmd.param, capabilities, length);
6228 return ipw_send_cmd(priv, &cmd);
6229}
6230
6231/*
6232 * WE-18 support
6233 */
6234
6235/* SIOCSIWGENIE */
6236static int ipw_wx_set_genie(struct net_device *dev,
6237 struct iw_request_info *info,
6238 union iwreq_data *wrqu, char *extra)
6239{
6240 struct ipw_priv *priv = ieee80211_priv(dev);
6241 struct ieee80211_device *ieee = priv->ieee;
6242 u8 *buf;
6243 int err = 0;
6244
6245 if (wrqu->data.length > MAX_WPA_IE_LEN ||
6246 (wrqu->data.length && extra == NULL))
6247 return -EINVAL;
6248
6249 //down(&priv->sem);
6250
6251 //if (!ieee->wpa_enabled) {
6252 // err = -EOPNOTSUPP;
6253 // goto out;
6254 //}
6255
6256 if (wrqu->data.length) {
6257 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
6258 if (buf == NULL) {
6259 err = -ENOMEM;
6260 goto out;
6261 }
6262
6263 memcpy(buf, extra, wrqu->data.length);
6264 kfree(ieee->wpa_ie);
6265 ieee->wpa_ie = buf;
6266 ieee->wpa_ie_len = wrqu->data.length;
6267 } else {
6268 kfree(ieee->wpa_ie);
6269 ieee->wpa_ie = NULL;
6270 ieee->wpa_ie_len = 0;
6271 }
6272
6273 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
6274 out:
6275 //up(&priv->sem);
6276 return err;
6277}
6278
6279/* SIOCGIWGENIE */
6280static int ipw_wx_get_genie(struct net_device *dev,
6281 struct iw_request_info *info,
6282 union iwreq_data *wrqu, char *extra)
6283{
6284 struct ipw_priv *priv = ieee80211_priv(dev);
6285 struct ieee80211_device *ieee = priv->ieee;
6286 int err = 0;
6287
6288 //down(&priv->sem);
6289
6290 //if (!ieee->wpa_enabled) {
6291 // err = -EOPNOTSUPP;
6292 // goto out;
6293 //}
6294
6295 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
6296 wrqu->data.length = 0;
6297 goto out;
6298 }
6299
6300 if (wrqu->data.length < ieee->wpa_ie_len) {
6301 err = -E2BIG;
6302 goto out;
6303 }
6304
6305 wrqu->data.length = ieee->wpa_ie_len;
6306 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
6307
6308 out:
6309 //up(&priv->sem);
6310 return err;
6311}
6312
6313static int wext_cipher2level(int cipher)
6314{
6315 switch (cipher) {
6316 case IW_AUTH_CIPHER_NONE:
6317 return SEC_LEVEL_0;
6318 case IW_AUTH_CIPHER_WEP40:
6319 case IW_AUTH_CIPHER_WEP104:
6320 return SEC_LEVEL_1;
6321 case IW_AUTH_CIPHER_TKIP:
6322 return SEC_LEVEL_2;
6323 case IW_AUTH_CIPHER_CCMP:
6324 return SEC_LEVEL_3;
6325 default:
6326 return -1;
6327 }
6328}
6329
6330/* SIOCSIWAUTH */
6331static int ipw_wx_set_auth(struct net_device *dev,
6332 struct iw_request_info *info,
6333 union iwreq_data *wrqu, char *extra)
6334{
6335 struct ipw_priv *priv = ieee80211_priv(dev);
6336 struct ieee80211_device *ieee = priv->ieee;
6337 struct iw_param *param = &wrqu->param;
6338 struct ieee80211_crypt_data *crypt;
6339 unsigned long flags;
6340 int ret = 0;
6341
6342 switch (param->flags & IW_AUTH_INDEX) {
6343 case IW_AUTH_WPA_VERSION:
6344 break;
6345 case IW_AUTH_CIPHER_PAIRWISE:
6346 ipw_set_hw_decrypt_unicast(priv,
6347 wext_cipher2level(param->value));
6348 break;
6349 case IW_AUTH_CIPHER_GROUP:
6350 ipw_set_hw_decrypt_multicast(priv,
6351 wext_cipher2level(param->value));
6352 break;
6353 case IW_AUTH_KEY_MGMT:
6354 /*
6355 * ipw2200 does not use these parameters
6356 */
6357 break;
6358
6359 case IW_AUTH_TKIP_COUNTERMEASURES:
6360 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6361 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
6362 break;
6363
6364 flags = crypt->ops->get_flags(crypt->priv);
6365
6366 if (param->value)
6367 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6368 else
6369 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
6370
6371 crypt->ops->set_flags(flags, crypt->priv);
6372
6373 break;
6374
6375 case IW_AUTH_DROP_UNENCRYPTED:{
6376 /* HACK:
6377 *
6378 * wpa_supplicant calls set_wpa_enabled when the driver
6379 * is loaded and unloaded, regardless of if WPA is being
6380 * used. No other calls are made which can be used to
6381 * determine if encryption will be used or not prior to
6382 * association being expected. If encryption is not being
6383 * used, drop_unencrypted is set to false, else true -- we
6384 * can use this to determine if the CAP_PRIVACY_ON bit should
6385 * be set.
6386 */
6387 struct ieee80211_security sec = {
6388 .flags = SEC_ENABLED,
6389 .enabled = param->value,
6390 };
6391 priv->ieee->drop_unencrypted = param->value;
6392 /* We only change SEC_LEVEL for open mode. Others
6393 * are set by ipw_wpa_set_encryption.
6394 */
6395 if (!param->value) {
6396 sec.flags |= SEC_LEVEL;
6397 sec.level = SEC_LEVEL_0;
6398 } else {
6399 sec.flags |= SEC_LEVEL;
6400 sec.level = SEC_LEVEL_1;
6401 }
6402 if (priv->ieee->set_security)
6403 priv->ieee->set_security(priv->ieee->dev, &sec);
6404 break;
6405 }
6406
6407 case IW_AUTH_80211_AUTH_ALG:
6408 ret = ipw_wpa_set_auth_algs(priv, param->value);
6409 break;
6410
6411 case IW_AUTH_WPA_ENABLED:
6412 ret = ipw_wpa_enable(priv, param->value);
6413 break;
6414
6415 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6416 ieee->ieee802_1x = param->value;
6417 break;
6418
6419 //case IW_AUTH_ROAMING_CONTROL:
6420 case IW_AUTH_PRIVACY_INVOKED:
6421 ieee->privacy_invoked = param->value;
6422 break;
6423
6424 default:
6425 return -EOPNOTSUPP;
6426 }
6427 return ret;
6428}
6429
6430/* SIOCGIWAUTH */
6431static int ipw_wx_get_auth(struct net_device *dev,
6432 struct iw_request_info *info,
6433 union iwreq_data *wrqu, char *extra)
6434{
6435 struct ipw_priv *priv = ieee80211_priv(dev);
6436 struct ieee80211_device *ieee = priv->ieee;
6437 struct ieee80211_crypt_data *crypt;
6438 struct iw_param *param = &wrqu->param;
6439 int ret = 0;
6440
6441 switch (param->flags & IW_AUTH_INDEX) {
6442 case IW_AUTH_WPA_VERSION:
6443 case IW_AUTH_CIPHER_PAIRWISE:
6444 case IW_AUTH_CIPHER_GROUP:
6445 case IW_AUTH_KEY_MGMT:
6446 /*
6447 * wpa_supplicant will control these internally
6448 */
6449 ret = -EOPNOTSUPP;
6450 break;
6451
6452 case IW_AUTH_TKIP_COUNTERMEASURES:
6453 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
6454 if (!crypt || !crypt->ops->get_flags)
6455 break;
6456
6457 param->value = (crypt->ops->get_flags(crypt->priv) &
6458 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
6459
6460 break;
6461
6462 case IW_AUTH_DROP_UNENCRYPTED:
6463 param->value = ieee->drop_unencrypted;
6464 break;
6465
6466 case IW_AUTH_80211_AUTH_ALG:
6467 param->value = ieee->sec.auth_mode;
6468 break;
6469
6470 case IW_AUTH_WPA_ENABLED:
6471 param->value = ieee->wpa_enabled;
6472 break;
6473
6474 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
6475 param->value = ieee->ieee802_1x;
6476 break;
6477
6478 case IW_AUTH_ROAMING_CONTROL:
6479 case IW_AUTH_PRIVACY_INVOKED:
6480 param->value = ieee->privacy_invoked;
6481 break;
6482
6483 default:
6484 return -EOPNOTSUPP;
6485 }
6486 return 0;
6487}
6488
6489/* SIOCSIWENCODEEXT */
6490static int ipw_wx_set_encodeext(struct net_device *dev,
6491 struct iw_request_info *info,
6492 union iwreq_data *wrqu, char *extra)
6493{
6494 struct ipw_priv *priv = ieee80211_priv(dev);
6495 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
6496
6497 if (hwcrypto) {
6498 if (ext->alg == IW_ENCODE_ALG_TKIP) {
6499 /* IPW HW can't build TKIP MIC,
6500 host decryption still needed */
6501 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
6502 priv->ieee->host_mc_decrypt = 1;
6503 else {
6504 priv->ieee->host_encrypt = 0;
6505 priv->ieee->host_encrypt_msdu = 1;
6506 priv->ieee->host_decrypt = 1;
6507 }
6508 } else {
6509 priv->ieee->host_encrypt = 0;
6510 priv->ieee->host_encrypt_msdu = 0;
6511 priv->ieee->host_decrypt = 0;
6512 priv->ieee->host_mc_decrypt = 0;
6513 }
6514 }
6515
6516 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
6517}
6518
6519/* SIOCGIWENCODEEXT */
6520static int ipw_wx_get_encodeext(struct net_device *dev,
6521 struct iw_request_info *info,
6522 union iwreq_data *wrqu, char *extra)
6523{
6524 struct ipw_priv *priv = ieee80211_priv(dev);
6525 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
6526}
6527
6528/* SIOCSIWMLME */
6529static int ipw_wx_set_mlme(struct net_device *dev,
6530 struct iw_request_info *info,
6531 union iwreq_data *wrqu, char *extra)
6532{
6533 struct ipw_priv *priv = ieee80211_priv(dev);
6534 struct iw_mlme *mlme = (struct iw_mlme *)extra;
6535 u16 reason;
6536
6537 reason = cpu_to_le16(mlme->reason_code);
6538
6539 switch (mlme->cmd) {
6540 case IW_MLME_DEAUTH:
6541 // silently ignore
6542 break;
6543
6544 case IW_MLME_DISASSOC:
6545 ipw_disassociate(priv);
6546 break;
6547
6548 default:
6549 return -EOPNOTSUPP;
6550 }
6551 return 0;
6552}
6553
6554#ifdef CONFIG_IPW_QOS
6555
6556/* QoS */
6557/*
6558* get the modulation type of the current network or
6559* the card current mode
6560*/
6561u8 ipw_qos_current_mode(struct ipw_priv * priv)
6562{
6563 u8 mode = 0;
6564
6565 if (priv->status & STATUS_ASSOCIATED) {
6566 unsigned long flags;
6567
6568 spin_lock_irqsave(&priv->ieee->lock, flags);
6569 mode = priv->assoc_network->mode;
6570 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6571 } else {
6572 mode = priv->ieee->mode;
6573 }
6574 IPW_DEBUG_QOS("QoS network/card mode %d \n", mode);
6575 return mode;
6576}
6577
6578/*
6579* Handle management frame beacon and probe response
6580*/
6581static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
6582 int active_network,
6583 struct ieee80211_network *network)
6584{
6585 u32 size = sizeof(struct ieee80211_qos_parameters);
6586
6587 if (network->capability & WLAN_CAPABILITY_IBSS)
6588 network->qos_data.active = network->qos_data.supported;
6589
6590 if (network->flags & NETWORK_HAS_QOS_MASK) {
6591 if (active_network &&
6592 (network->flags & NETWORK_HAS_QOS_PARAMETERS))
6593 network->qos_data.active = network->qos_data.supported;
6594
6595 if ((network->qos_data.active == 1) && (active_network == 1) &&
6596 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
6597 (network->qos_data.old_param_count !=
6598 network->qos_data.param_count)) {
6599 network->qos_data.old_param_count =
6600 network->qos_data.param_count;
6601 schedule_work(&priv->qos_activate);
6602 IPW_DEBUG_QOS("QoS parameters change call "
6603 "qos_activate\n");
6604 }
6605 } else {
6606 if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B))
6607 memcpy(&network->qos_data.parameters,
6608 &def_parameters_CCK, size);
6609 else
6610 memcpy(&network->qos_data.parameters,
6611 &def_parameters_OFDM, size);
6612
6613 if ((network->qos_data.active == 1) && (active_network == 1)) {
6614 IPW_DEBUG_QOS("QoS was disabled call qos_activate \n");
6615 schedule_work(&priv->qos_activate);
6616 }
6617
6618 network->qos_data.active = 0;
6619 network->qos_data.supported = 0;
6620 }
6621 if ((priv->status & STATUS_ASSOCIATED) &&
6622 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {
6623 if (memcmp(network->bssid, priv->bssid, ETH_ALEN))
6624 if ((network->capability & WLAN_CAPABILITY_IBSS) &&
6625 !(network->flags & NETWORK_EMPTY_ESSID))
6626 if ((network->ssid_len ==
6627 priv->assoc_network->ssid_len) &&
6628 !memcmp(network->ssid,
6629 priv->assoc_network->ssid,
6630 network->ssid_len)) {
6631 queue_work(priv->workqueue,
6632 &priv->merge_networks);
6633 }
6634 }
6635
6636 return 0;
6637}
6638
6639/*
6640* This function set up the firmware to support QoS. It sends
6641* IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO
6642*/
6643static int ipw_qos_activate(struct ipw_priv *priv,
6644 struct ieee80211_qos_data *qos_network_data)
6645{
6646 int err;
6647 struct ieee80211_qos_parameters qos_parameters[QOS_QOS_SETS];
6648 struct ieee80211_qos_parameters *active_one = NULL;
6649 u32 size = sizeof(struct ieee80211_qos_parameters);
6650 u32 burst_duration;
6651 int i;
6652 u8 type;
6653
6654 type = ipw_qos_current_mode(priv);
6655
6656 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);
6657 memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);
6658 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);
6659 memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);
6660
6661 if (qos_network_data == NULL) {
6662 if (type == IEEE_B) {
6663 IPW_DEBUG_QOS("QoS activate network mode %d\n", type);
6664 active_one = &def_parameters_CCK;
6665 } else
6666 active_one = &def_parameters_OFDM;
6667
6668 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6669 burst_duration = ipw_qos_get_burst_duration(priv);
6670 for (i = 0; i < QOS_QUEUE_NUM; i++)
6671 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =
6672 (u16) burst_duration;
6673 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6674 if (type == IEEE_B) {
6675 IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n",
6676 type);
6677 if (priv->qos_data.qos_enable == 0)
6678 active_one = &def_parameters_CCK;
6679 else
6680 active_one = priv->qos_data.def_qos_parm_CCK;
6681 } else {
6682 if (priv->qos_data.qos_enable == 0)
6683 active_one = &def_parameters_OFDM;
6684 else
6685 active_one = priv->qos_data.def_qos_parm_OFDM;
6686 }
6687 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6688 } else {
6689 unsigned long flags;
6690 int active;
6691
6692 spin_lock_irqsave(&priv->ieee->lock, flags);
6693 active_one = &(qos_network_data->parameters);
6694 qos_network_data->old_param_count =
6695 qos_network_data->param_count;
6696 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);
6697 active = qos_network_data->supported;
6698 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6699
6700 if (active == 0) {
6701 burst_duration = ipw_qos_get_burst_duration(priv);
6702 for (i = 0; i < QOS_QUEUE_NUM; i++)
6703 qos_parameters[QOS_PARAM_SET_ACTIVE].
6704 tx_op_limit[i] = (u16) burst_duration;
6705 }
6706 }
6707
6708 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");
6709 err = ipw_send_qos_params_command(priv,
6710 (struct ieee80211_qos_parameters *)
6711 &(qos_parameters[0]));
6712 if (err)
6713 IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");
6714
6715 return err;
6716}
6717
6718/*
6719* send IPW_CMD_WME_INFO to the firmware
6720*/
6721static int ipw_qos_set_info_element(struct ipw_priv *priv)
6722{
6723 int ret = 0;
6724 struct ieee80211_qos_information_element qos_info;
6725
6726 if (priv == NULL)
6727 return -1;
6728
6729 qos_info.elementID = QOS_ELEMENT_ID;
6730 qos_info.length = sizeof(struct ieee80211_qos_information_element) - 2;
6731
6732 qos_info.version = QOS_VERSION_1;
6733 qos_info.ac_info = 0;
6734
6735 memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);
6736 qos_info.qui_type = QOS_OUI_TYPE;
6737 qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;
6738
6739 ret = ipw_send_qos_info_command(priv, &qos_info);
6740 if (ret != 0) {
6741 IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");
6742 }
6743 return ret;
6744}
6745
6746/*
6747* Set the QoS parameter with the association request structure
6748*/
6749static int ipw_qos_association(struct ipw_priv *priv,
6750 struct ieee80211_network *network)
6751{
6752 int err = 0;
6753 struct ieee80211_qos_data *qos_data = NULL;
6754 struct ieee80211_qos_data ibss_data = {
6755 .supported = 1,
6756 .active = 1,
6757 };
6758
6759 switch (priv->ieee->iw_mode) {
6760 case IW_MODE_ADHOC:
6761 if (!(network->capability & WLAN_CAPABILITY_IBSS))
6762 BUG();
6763
6764 qos_data = &ibss_data;
6765 break;
6766
6767 case IW_MODE_INFRA:
6768 qos_data = &network->qos_data;
6769 break;
6770
6771 default:
6772 BUG();
6773 break;
6774 }
6775
6776 err = ipw_qos_activate(priv, qos_data);
6777 if (err) {
6778 priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;
6779 return err;
6780 }
6781
6782 if (priv->qos_data.qos_enable && qos_data->supported) {
6783 IPW_DEBUG_QOS("QoS will be enabled for this association\n");
6784 priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;
6785 return ipw_qos_set_info_element(priv);
6786 }
6787
6788 return 0;
6789}
6790
6791/*
6792* handling the beaconing responces. if we get different QoS setting
6793* of the network from the the associated setting adjust the QoS
6794* setting
6795*/
6796static int ipw_qos_association_resp(struct ipw_priv *priv,
6797 struct ieee80211_network *network)
6798{
6799 int ret = 0;
6800 unsigned long flags;
6801 u32 size = sizeof(struct ieee80211_qos_parameters);
6802 int set_qos_param = 0;
6803
6804 if ((priv == NULL) || (network == NULL) ||
6805 (priv->assoc_network == NULL))
6806 return ret;
6807
6808 if (!(priv->status & STATUS_ASSOCIATED))
6809 return ret;
6810
6811 if ((priv->ieee->iw_mode != IW_MODE_INFRA))
6812 return ret;
6813
6814 spin_lock_irqsave(&priv->ieee->lock, flags);
6815 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {
6816 memcpy(&priv->assoc_network->qos_data, &network->qos_data,
6817 sizeof(struct ieee80211_qos_data));
6818 priv->assoc_network->qos_data.active = 1;
6819 if ((network->qos_data.old_param_count !=
6820 network->qos_data.param_count)) {
6821 set_qos_param = 1;
6822 network->qos_data.old_param_count =
6823 network->qos_data.param_count;
6824 }
6825
6826 } else {
6827 if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B))
6828 memcpy(&priv->assoc_network->qos_data.parameters,
6829 &def_parameters_CCK, size);
6830 else
6831 memcpy(&priv->assoc_network->qos_data.parameters,
6832 &def_parameters_OFDM, size);
6833 priv->assoc_network->qos_data.active = 0;
6834 priv->assoc_network->qos_data.supported = 0;
6835 set_qos_param = 1;
6836 }
6837
6838 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6839
6840 if (set_qos_param == 1)
6841 schedule_work(&priv->qos_activate);
6842
6843 return ret;
6844}
6845
6846static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)
6847{
6848 u32 ret = 0;
6849
6850 if ((priv == NULL))
6851 return 0;
6852
6853 if (!(priv->ieee->modulation & IEEE80211_OFDM_MODULATION))
6854 ret = priv->qos_data.burst_duration_CCK;
6855 else
6856 ret = priv->qos_data.burst_duration_OFDM;
6857
6858 return ret;
6859}
6860
6861/*
6862* Initialize the setting of QoS global
6863*/
6864static void ipw_qos_init(struct ipw_priv *priv, int enable,
6865 int burst_enable, u32 burst_duration_CCK,
6866 u32 burst_duration_OFDM)
6867{
6868 priv->qos_data.qos_enable = enable;
6869
6870 if (priv->qos_data.qos_enable) {
6871 priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;
6872 priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;
6873 IPW_DEBUG_QOS("QoS is enabled\n");
6874 } else {
6875 priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;
6876 priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;
6877 IPW_DEBUG_QOS("QoS is not enabled\n");
6878 }
6879
6880 priv->qos_data.burst_enable = burst_enable;
6881
6882 if (burst_enable) {
6883 priv->qos_data.burst_duration_CCK = burst_duration_CCK;
6884 priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;
6885 } else {
6886 priv->qos_data.burst_duration_CCK = 0;
6887 priv->qos_data.burst_duration_OFDM = 0;
6888 }
6889}
6890
6891/*
6892* map the packet priority to the right TX Queue
6893*/
6894static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)
6895{
6896 if (priority > 7 || !priv->qos_data.qos_enable)
6897 priority = 0;
6898
6899 return from_priority_to_tx_queue[priority] - 1;
6900}
6901
6902/*
6903* add QoS parameter to the TX command
6904*/
6905static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,
6906 u16 priority,
6907 struct tfd_data *tfd, u8 unicast)
6908{
6909 int ret = 0;
6910 int tx_queue_id = 0;
6911 struct ieee80211_qos_data *qos_data = NULL;
6912 int active, supported;
6913 unsigned long flags;
6914
6915 if (!(priv->status & STATUS_ASSOCIATED))
6916 return 0;
6917
6918 qos_data = &priv->assoc_network->qos_data;
6919
6920 spin_lock_irqsave(&priv->ieee->lock, flags);
6921
6922 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
6923 if (unicast == 0)
6924 qos_data->active = 0;
6925 else
6926 qos_data->active = qos_data->supported;
6927 }
6928
6929 active = qos_data->active;
6930 supported = qos_data->supported;
6931
6932 spin_unlock_irqrestore(&priv->ieee->lock, flags);
6933
6934 IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d "
6935 "unicast %d\n",
6936 priv->qos_data.qos_enable, active, supported, unicast);
6937 if (active && priv->qos_data.qos_enable) {
6938 ret = from_priority_to_tx_queue[priority];
6939 tx_queue_id = ret - 1;
6940 IPW_DEBUG_QOS("QoS packet priority is %d \n", priority);
6941 if (priority <= 7) {
6942 tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;
6943 tfd->tfd.tfd_26.mchdr.qos_ctrl = priority;
6944 tfd->tfd.tfd_26.mchdr.frame_ctl |=
6945 IEEE80211_STYPE_QOS_DATA;
6946
6947 if (priv->qos_data.qos_no_ack_mask &
6948 (1UL << tx_queue_id)) {
6949 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;
6950 tfd->tfd.tfd_26.mchdr.qos_ctrl |=
6951 CTRL_QOS_NO_ACK;
6952 }
6953 }
6954 }
6955
6956 return ret;
6957}
6958
6959/*
6960* background support to run QoS activate functionality
6961*/
6962static void ipw_bg_qos_activate(void *data)
6963{
6964 struct ipw_priv *priv = data;
6965
6966 if (priv == NULL)
6967 return;
6968
6969 down(&priv->sem);
6970
6971 if (priv->status & STATUS_ASSOCIATED)
6972 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));
6973
6974 up(&priv->sem);
6975}
6976
6977static int ipw_handle_probe_response(struct net_device *dev,
6978 struct ieee80211_probe_response *resp,
6979 struct ieee80211_network *network)
6980{
6981 struct ipw_priv *priv = ieee80211_priv(dev);
6982 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
6983 (network == priv->assoc_network));
6984
6985 ipw_qos_handle_probe_response(priv, active_network, network);
6986
6987 return 0;
6988}
6989
6990static int ipw_handle_beacon(struct net_device *dev,
6991 struct ieee80211_beacon *resp,
6992 struct ieee80211_network *network)
6993{
6994 struct ipw_priv *priv = ieee80211_priv(dev);
6995 int active_network = ((priv->status & STATUS_ASSOCIATED) &&
6996 (network == priv->assoc_network));
6997
6998 ipw_qos_handle_probe_response(priv, active_network, network);
6999
7000 return 0;
7001}
7002
7003static int ipw_handle_assoc_response(struct net_device *dev,
7004 struct ieee80211_assoc_response *resp,
7005 struct ieee80211_network *network)
7006{
7007 struct ipw_priv *priv = ieee80211_priv(dev);
7008 ipw_qos_association_resp(priv, network);
7009 return 0;
7010}
7011
7012static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
7013 *qos_param)
7014{
7015 struct host_cmd cmd = {
7016 .cmd = IPW_CMD_QOS_PARAMETERS,
7017 .len = (sizeof(struct ieee80211_qos_parameters) * 3)
7018 };
7019
7020 memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
7021 return ipw_send_cmd(priv, &cmd);
7022}
7023
7024static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
7025 *qos_param)
7026{
7027 struct host_cmd cmd = {
7028 .cmd = IPW_CMD_WME_INFO,
7029 .len = sizeof(*qos_param)
7030 };
7031
7032 memcpy(cmd.param, qos_param, sizeof(*qos_param));
7033 return ipw_send_cmd(priv, &cmd);
7034}
7035
7036#endif /* CONFIG_IPW_QOS */
7037
4612static int ipw_associate_network(struct ipw_priv *priv, 7038static int ipw_associate_network(struct ipw_priv *priv,
4613 struct ieee80211_network *network, 7039 struct ieee80211_network *network,
4614 struct ipw_supported_rates *rates, int roaming) 7040 struct ipw_supported_rates *rates, int roaming)
@@ -4616,7 +7042,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
4616 int err; 7042 int err;
4617 7043
4618 if (priv->config & CFG_FIXED_RATE) 7044 if (priv->config & CFG_FIXED_RATE)
4619 ipw_set_fixed_rate(priv, network); 7045 ipw_set_fixed_rate(priv, network->mode);
4620 7046
4621 if (!(priv->config & CFG_STATIC_ESSID)) { 7047 if (!(priv->config & CFG_STATIC_ESSID)) {
4622 priv->essid_len = min(network->ssid_len, 7048 priv->essid_len = min(network->ssid_len,
@@ -4631,14 +7057,22 @@ static int ipw_associate_network(struct ipw_priv *priv,
4631 if ((priv->capability & CAP_PRIVACY_ON) && 7057 if ((priv->capability & CAP_PRIVACY_ON) &&
4632 (priv->capability & CAP_SHARED_KEY)) { 7058 (priv->capability & CAP_SHARED_KEY)) {
4633 priv->assoc_request.auth_type = AUTH_SHARED_KEY; 7059 priv->assoc_request.auth_type = AUTH_SHARED_KEY;
4634 priv->assoc_request.auth_key = priv->sec.active_key; 7060 priv->assoc_request.auth_key = priv->ieee->sec.active_key;
7061
7062 if ((priv->capability & CAP_PRIVACY_ON) &&
7063 (priv->ieee->sec.level == SEC_LEVEL_1) &&
7064 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
7065 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
4635 } else { 7066 } else {
4636 priv->assoc_request.auth_type = AUTH_OPEN; 7067 priv->assoc_request.auth_type = AUTH_OPEN;
4637 priv->assoc_request.auth_key = 0; 7068 priv->assoc_request.auth_key = 0;
4638 } 7069 }
4639 7070
4640 if (priv->capability & CAP_PRIVACY_ON) 7071 if (priv->ieee->wpa_ie_len) {
4641 ipw_send_wep_keys(priv); 7072 priv->assoc_request.policy_support = 0x02; /* RSN active */
7073 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
7074 priv->ieee->wpa_ie_len);
7075 }
4642 7076
4643 /* 7077 /*
4644 * It is valid for our ieee device to support multiple modes, but 7078 * It is valid for our ieee device to support multiple modes, but
@@ -4652,20 +7086,41 @@ static int ipw_associate_network(struct ipw_priv *priv,
4652 else if (network->mode & priv->ieee->mode & IEEE_B) 7086 else if (network->mode & priv->ieee->mode & IEEE_B)
4653 priv->assoc_request.ieee_mode = IPW_B_MODE; 7087 priv->assoc_request.ieee_mode = IPW_B_MODE;
4654 7088
7089 priv->assoc_request.capability = network->capability;
7090 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
7091 && !(priv->config & CFG_PREAMBLE_LONG)) {
7092 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
7093 } else {
7094 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
7095
7096 /* Clear the short preamble if we won't be supporting it */
7097 priv->assoc_request.capability &=
7098 ~WLAN_CAPABILITY_SHORT_PREAMBLE;
7099 }
7100
7101 /* Clear capability bits that aren't used in Ad Hoc */
7102 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7103 priv->assoc_request.capability &=
7104 ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
7105
4655 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, " 7106 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
4656 "802.11%c [%d], enc=%s%s%s%c%c\n", 7107 "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
4657 roaming ? "Rea" : "A", 7108 roaming ? "Rea" : "A",
4658 escape_essid(priv->essid, priv->essid_len), 7109 escape_essid(priv->essid, priv->essid_len),
4659 network->channel, 7110 network->channel,
4660 ipw_modes[priv->assoc_request.ieee_mode], 7111 ipw_modes[priv->assoc_request.ieee_mode],
4661 rates->num_rates, 7112 rates->num_rates,
7113 (priv->assoc_request.preamble_length ==
7114 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
7115 network->capability &
7116 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
4662 priv->capability & CAP_PRIVACY_ON ? "on " : "off", 7117 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
4663 priv->capability & CAP_PRIVACY_ON ? 7118 priv->capability & CAP_PRIVACY_ON ?
4664 (priv->capability & CAP_SHARED_KEY ? "(shared)" : 7119 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
4665 "(open)") : "", 7120 "(open)") : "",
4666 priv->capability & CAP_PRIVACY_ON ? " key=" : "", 7121 priv->capability & CAP_PRIVACY_ON ? " key=" : "",
4667 priv->capability & CAP_PRIVACY_ON ? 7122 priv->capability & CAP_PRIVACY_ON ?
4668 '1' + priv->sec.active_key : '.', 7123 '1' + priv->ieee->sec.active_key : '.',
4669 priv->capability & CAP_PRIVACY_ON ? '.' : ' '); 7124 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');
4670 7125
4671 priv->assoc_request.beacon_interval = network->beacon_interval; 7126 priv->assoc_request.beacon_interval = network->beacon_interval;
@@ -4683,17 +7138,16 @@ static int ipw_associate_network(struct ipw_priv *priv,
4683 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0]; 7138 priv->assoc_request.assoc_tsf_lsw = network->time_stamp[0];
4684 } 7139 }
4685 7140
4686 memcpy(&priv->assoc_request.bssid, network->bssid, ETH_ALEN); 7141 memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);
4687 7142
4688 if (priv->ieee->iw_mode == IW_MODE_ADHOC) { 7143 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
4689 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN); 7144 memset(&priv->assoc_request.dest, 0xFF, ETH_ALEN);
4690 priv->assoc_request.atim_window = network->atim_window; 7145 priv->assoc_request.atim_window = network->atim_window;
4691 } else { 7146 } else {
4692 memcpy(&priv->assoc_request.dest, network->bssid, ETH_ALEN); 7147 memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);
4693 priv->assoc_request.atim_window = 0; 7148 priv->assoc_request.atim_window = 0;
4694 } 7149 }
4695 7150
4696 priv->assoc_request.capability = network->capability;
4697 priv->assoc_request.listen_interval = network->listen_interval; 7151 priv->assoc_request.listen_interval = network->listen_interval;
4698 7152
4699 err = ipw_send_ssid(priv, priv->essid, priv->essid_len); 7153 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
@@ -4710,6 +7164,12 @@ static int ipw_associate_network(struct ipw_priv *priv,
4710 priv->sys_config.dot11g_auto_detection = 1; 7164 priv->sys_config.dot11g_auto_detection = 1;
4711 else 7165 else
4712 priv->sys_config.dot11g_auto_detection = 0; 7166 priv->sys_config.dot11g_auto_detection = 0;
7167
7168 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
7169 priv->sys_config.answer_broadcast_ssid_probe = 1;
7170 else
7171 priv->sys_config.answer_broadcast_ssid_probe = 0;
7172
4713 err = ipw_send_system_config(priv, &priv->sys_config); 7173 err = ipw_send_system_config(priv, &priv->sys_config);
4714 if (err) { 7174 if (err) {
4715 IPW_DEBUG_HC("Attempt to send sys config command failed.\n"); 7175 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
@@ -4717,7 +7177,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
4717 } 7177 }
4718 7178
4719 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi); 7179 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
4720 err = ipw_set_sensitivity(priv, network->stats.rssi); 7180 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
4721 if (err) { 7181 if (err) {
4722 IPW_DEBUG_HC("Attempt to send associate command failed.\n"); 7182 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
4723 return err; 7183 return err;
@@ -4735,6 +7195,10 @@ static int ipw_associate_network(struct ipw_priv *priv,
4735 7195
4736 priv->assoc_network = network; 7196 priv->assoc_network = network;
4737 7197
7198#ifdef CONFIG_IPW_QOS
7199 ipw_qos_association(priv, network);
7200#endif
7201
4738 err = ipw_send_associate(priv, &priv->assoc_request); 7202 err = ipw_send_associate(priv, &priv->assoc_request);
4739 if (err) { 7203 if (err) {
4740 IPW_DEBUG_HC("Attempt to send associate command failed.\n"); 7204 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
@@ -4782,12 +7246,15 @@ static void ipw_roam(void *data)
4782 if (priv->status & STATUS_ASSOCIATED) { 7246 if (priv->status & STATUS_ASSOCIATED) {
4783 /* First pass through ROAM process -- look for a better 7247 /* First pass through ROAM process -- look for a better
4784 * network */ 7248 * network */
7249 unsigned long flags;
4785 u8 rssi = priv->assoc_network->stats.rssi; 7250 u8 rssi = priv->assoc_network->stats.rssi;
4786 priv->assoc_network->stats.rssi = -128; 7251 priv->assoc_network->stats.rssi = -128;
7252 spin_lock_irqsave(&priv->ieee->lock, flags);
4787 list_for_each_entry(network, &priv->ieee->network_list, list) { 7253 list_for_each_entry(network, &priv->ieee->network_list, list) {
4788 if (network != priv->assoc_network) 7254 if (network != priv->assoc_network)
4789 ipw_best_network(priv, &match, network, 1); 7255 ipw_best_network(priv, &match, network, 1);
4790 } 7256 }
7257 spin_unlock_irqrestore(&priv->ieee->lock, flags);
4791 priv->assoc_network->stats.rssi = rssi; 7258 priv->assoc_network->stats.rssi = rssi;
4792 7259
4793 if (match.network == priv->assoc_network) { 7260 if (match.network == priv->assoc_network) {
@@ -4810,7 +7277,15 @@ static void ipw_roam(void *data)
4810 priv->status &= ~STATUS_ROAMING; 7277 priv->status &= ~STATUS_ROAMING;
4811} 7278}
4812 7279
4813static void ipw_associate(void *data) 7280static void ipw_bg_roam(void *data)
7281{
7282 struct ipw_priv *priv = data;
7283 down(&priv->sem);
7284 ipw_roam(data);
7285 up(&priv->sem);
7286}
7287
7288static int ipw_associate(void *data)
4814{ 7289{
4815 struct ipw_priv *priv = data; 7290 struct ipw_priv *priv = data;
4816 7291
@@ -4820,14 +7295,41 @@ static void ipw_associate(void *data)
4820 }; 7295 };
4821 struct ipw_supported_rates *rates; 7296 struct ipw_supported_rates *rates;
4822 struct list_head *element; 7297 struct list_head *element;
7298 unsigned long flags;
7299
7300 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7301 IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");
7302 return 0;
7303 }
7304
7305 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
7306 IPW_DEBUG_ASSOC("Not attempting association (already in "
7307 "progress)\n");
7308 return 0;
7309 }
7310
7311 if (priv->status & STATUS_DISASSOCIATING) {
7312 IPW_DEBUG_ASSOC("Not attempting association (in "
7313 "disassociating)\n ");
7314 queue_work(priv->workqueue, &priv->associate);
7315 return 0;
7316 }
7317
7318 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
7319 IPW_DEBUG_ASSOC("Not attempting association (scanning or not "
7320 "initialized)\n");
7321 return 0;
7322 }
4823 7323
4824 if (!(priv->config & CFG_ASSOCIATE) && 7324 if (!(priv->config & CFG_ASSOCIATE) &&
4825 !(priv->config & (CFG_STATIC_ESSID | 7325 !(priv->config & (CFG_STATIC_ESSID |
4826 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) { 7326 CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
4827 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n"); 7327 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
4828 return; 7328 return 0;
4829 } 7329 }
4830 7330
7331 /* Protect our use of the network_list */
7332 spin_lock_irqsave(&priv->ieee->lock, flags);
4831 list_for_each_entry(network, &priv->ieee->network_list, list) 7333 list_for_each_entry(network, &priv->ieee->network_list, list)
4832 ipw_best_network(priv, &match, network, 0); 7334 ipw_best_network(priv, &match, network, 0);
4833 7335
@@ -4838,6 +7340,7 @@ static void ipw_associate(void *data)
4838 priv->ieee->iw_mode == IW_MODE_ADHOC && 7340 priv->ieee->iw_mode == IW_MODE_ADHOC &&
4839 priv->config & CFG_ADHOC_CREATE && 7341 priv->config & CFG_ADHOC_CREATE &&
4840 priv->config & CFG_STATIC_ESSID && 7342 priv->config & CFG_STATIC_ESSID &&
7343 priv->config & CFG_STATIC_CHANNEL &&
4841 !list_empty(&priv->ieee->network_free_list)) { 7344 !list_empty(&priv->ieee->network_free_list)) {
4842 element = priv->ieee->network_free_list.next; 7345 element = priv->ieee->network_free_list.next;
4843 network = list_entry(element, struct ieee80211_network, list); 7346 network = list_entry(element, struct ieee80211_network, list);
@@ -4846,25 +7349,83 @@ static void ipw_associate(void *data)
4846 list_del(element); 7349 list_del(element);
4847 list_add_tail(&network->list, &priv->ieee->network_list); 7350 list_add_tail(&network->list, &priv->ieee->network_list);
4848 } 7351 }
7352 spin_unlock_irqrestore(&priv->ieee->lock, flags);
4849 7353
4850 /* If we reached the end of the list, then we don't have any valid 7354 /* If we reached the end of the list, then we don't have any valid
4851 * matching APs */ 7355 * matching APs */
4852 if (!network) { 7356 if (!network) {
4853 ipw_debug_config(priv); 7357 ipw_debug_config(priv);
4854 7358
4855 queue_delayed_work(priv->workqueue, &priv->request_scan, 7359 if (!(priv->status & STATUS_SCANNING)) {
4856 SCAN_INTERVAL); 7360 if (!(priv->config & CFG_SPEED_SCAN))
7361 queue_delayed_work(priv->workqueue,
7362 &priv->request_scan,
7363 SCAN_INTERVAL);
7364 else
7365 queue_work(priv->workqueue,
7366 &priv->request_scan);
7367 }
4857 7368
4858 return; 7369 return 0;
4859 } 7370 }
4860 7371
4861 ipw_associate_network(priv, network, rates, 0); 7372 ipw_associate_network(priv, network, rates, 0);
7373
7374 return 1;
4862} 7375}
4863 7376
4864static inline void ipw_handle_data_packet(struct ipw_priv *priv, 7377static void ipw_bg_associate(void *data)
4865 struct ipw_rx_mem_buffer *rxb,
4866 struct ieee80211_rx_stats *stats)
4867{ 7378{
7379 struct ipw_priv *priv = data;
7380 down(&priv->sem);
7381 ipw_associate(data);
7382 up(&priv->sem);
7383}
7384
7385static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
7386 struct sk_buff *skb)
7387{
7388 struct ieee80211_hdr *hdr;
7389 u16 fc;
7390
7391 hdr = (struct ieee80211_hdr *)skb->data;
7392 fc = le16_to_cpu(hdr->frame_ctl);
7393 if (!(fc & IEEE80211_FCTL_PROTECTED))
7394 return;
7395
7396 fc &= ~IEEE80211_FCTL_PROTECTED;
7397 hdr->frame_ctl = cpu_to_le16(fc);
7398 switch (priv->ieee->sec.level) {
7399 case SEC_LEVEL_3:
7400 /* Remove CCMP HDR */
7401 memmove(skb->data + IEEE80211_3ADDR_LEN,
7402 skb->data + IEEE80211_3ADDR_LEN + 8,
7403 skb->len - IEEE80211_3ADDR_LEN - 8);
7404 skb_trim(skb, skb->len - 16); /* CCMP_HDR_LEN + CCMP_MIC_LEN */
7405 break;
7406 case SEC_LEVEL_2:
7407 break;
7408 case SEC_LEVEL_1:
7409 /* Remove IV */
7410 memmove(skb->data + IEEE80211_3ADDR_LEN,
7411 skb->data + IEEE80211_3ADDR_LEN + 4,
7412 skb->len - IEEE80211_3ADDR_LEN - 4);
7413 skb_trim(skb, skb->len - 8); /* IV + ICV */
7414 break;
7415 case SEC_LEVEL_0:
7416 break;
7417 default:
7418 printk(KERN_ERR "Unknow security level %d\n",
7419 priv->ieee->sec.level);
7420 break;
7421 }
7422}
7423
7424static void ipw_handle_data_packet(struct ipw_priv *priv,
7425 struct ipw_rx_mem_buffer *rxb,
7426 struct ieee80211_rx_stats *stats)
7427{
7428 struct ieee80211_hdr_4addr *hdr;
4868 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data; 7429 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
4869 7430
4870 /* We received data from the HW, so stop the watchdog */ 7431 /* We received data from the HW, so stop the watchdog */
@@ -4872,7 +7433,7 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4872 7433
4873 /* We only process data packets if the 7434 /* We only process data packets if the
4874 * interface is open */ 7435 * interface is open */
4875 if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) > 7436 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
4876 skb_tailroom(rxb->skb))) { 7437 skb_tailroom(rxb->skb))) {
4877 priv->ieee->stats.rx_errors++; 7438 priv->ieee->stats.rx_errors++;
4878 priv->wstats.discard.misc++; 7439 priv->wstats.discard.misc++;
@@ -4889,14 +7450,351 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4889 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data)); 7450 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
4890 7451
4891 /* Set the size of the skb to the size of the frame */ 7452 /* Set the size of the skb to the size of the frame */
4892 skb_put(rxb->skb, pkt->u.frame.length); 7453 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
4893 7454
4894 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len); 7455 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
4895 7456
7457 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
7458 hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
7459 if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
7460 ((is_multicast_ether_addr(hdr->addr1) ||
7461 is_broadcast_ether_addr(hdr->addr1)) ?
7462 !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
7463 ipw_rebuild_decrypted_skb(priv, rxb->skb);
7464
4896 if (!ieee80211_rx(priv->ieee, rxb->skb, stats)) 7465 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
4897 priv->ieee->stats.rx_errors++; 7466 priv->ieee->stats.rx_errors++;
4898 else /* ieee80211_rx succeeded, so it now owns the SKB */ 7467 else { /* ieee80211_rx succeeded, so it now owns the SKB */
4899 rxb->skb = NULL; 7468 rxb->skb = NULL;
7469 __ipw_led_activity_on(priv);
7470 }
7471}
7472
7473#ifdef CONFIG_IEEE80211_RADIOTAP
7474static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7475 struct ipw_rx_mem_buffer *rxb,
7476 struct ieee80211_rx_stats *stats)
7477{
7478 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7479 struct ipw_rx_frame *frame = &pkt->u.frame;
7480
7481 /* initial pull of some data */
7482 u16 received_channel = frame->received_channel;
7483 u8 antennaAndPhy = frame->antennaAndPhy;
7484 s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM; /* call it signed anyhow */
7485 u16 pktrate = frame->rate;
7486
7487 /* Magic struct that slots into the radiotap header -- no reason
7488 * to build this manually element by element, we can write it much
7489 * more efficiently than we can parse it. ORDER MATTERS HERE */
7490 struct ipw_rt_hdr {
7491 struct ieee80211_radiotap_header rt_hdr;
7492 u8 rt_flags; /* radiotap packet flags */
7493 u8 rt_rate; /* rate in 500kb/s */
7494 u16 rt_channel; /* channel in mhz */
7495 u16 rt_chbitmask; /* channel bitfield */
7496 s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
7497 u8 rt_antenna; /* antenna number */
7498 } *ipw_rt;
7499
7500 short len = le16_to_cpu(pkt->u.frame.length);
7501
7502 /* We received data from the HW, so stop the watchdog */
7503 priv->net_dev->trans_start = jiffies;
7504
7505 /* We only process data packets if the
7506 * interface is open */
7507 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
7508 skb_tailroom(rxb->skb))) {
7509 priv->ieee->stats.rx_errors++;
7510 priv->wstats.discard.misc++;
7511 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7512 return;
7513 } else if (unlikely(!netif_running(priv->net_dev))) {
7514 priv->ieee->stats.rx_dropped++;
7515 priv->wstats.discard.misc++;
7516 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7517 return;
7518 }
7519
7520 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
7521 * that now */
7522 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7523 /* FIXME: Should alloc bigger skb instead */
7524 priv->ieee->stats.rx_dropped++;
7525 priv->wstats.discard.misc++;
7526 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7527 return;
7528 }
7529
7530 /* copy the frame itself */
7531 memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
7532 rxb->skb->data + IPW_RX_FRAME_SIZE, len);
7533
7534 /* Zero the radiotap static buffer ... We only need to zero the bytes NOT
7535 * part of our real header, saves a little time.
7536 *
7537 * No longer necessary since we fill in all our data. Purge before merging
7538 * patch officially.
7539 * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
7540 * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
7541 */
7542
7543 ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
7544
7545 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7546 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
7547 ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total header+data */
7548
7549 /* Big bitfield of all the fields we provide in radiotap */
7550 ipw_rt->rt_hdr.it_present =
7551 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7552 (1 << IEEE80211_RADIOTAP_RATE) |
7553 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7554 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7555 (1 << IEEE80211_RADIOTAP_ANTENNA));
7556
7557 /* Zero the flags, we'll add to them as we go */
7558 ipw_rt->rt_flags = 0;
7559
7560 /* Convert signal to DBM */
7561 ipw_rt->rt_dbmsignal = antsignal;
7562
7563 /* Convert the channel data and set the flags */
7564 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
7565 if (received_channel > 14) { /* 802.11a */
7566 ipw_rt->rt_chbitmask =
7567 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
7568 } else if (antennaAndPhy & 32) { /* 802.11b */
7569 ipw_rt->rt_chbitmask =
7570 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
7571 } else { /* 802.11g */
7572 ipw_rt->rt_chbitmask =
7573 (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
7574 }
7575
7576 /* set the rate in multiples of 500k/s */
7577 switch (pktrate) {
7578 case IPW_TX_RATE_1MB:
7579 ipw_rt->rt_rate = 2;
7580 break;
7581 case IPW_TX_RATE_2MB:
7582 ipw_rt->rt_rate = 4;
7583 break;
7584 case IPW_TX_RATE_5MB:
7585 ipw_rt->rt_rate = 10;
7586 break;
7587 case IPW_TX_RATE_6MB:
7588 ipw_rt->rt_rate = 12;
7589 break;
7590 case IPW_TX_RATE_9MB:
7591 ipw_rt->rt_rate = 18;
7592 break;
7593 case IPW_TX_RATE_11MB:
7594 ipw_rt->rt_rate = 22;
7595 break;
7596 case IPW_TX_RATE_12MB:
7597 ipw_rt->rt_rate = 24;
7598 break;
7599 case IPW_TX_RATE_18MB:
7600 ipw_rt->rt_rate = 36;
7601 break;
7602 case IPW_TX_RATE_24MB:
7603 ipw_rt->rt_rate = 48;
7604 break;
7605 case IPW_TX_RATE_36MB:
7606 ipw_rt->rt_rate = 72;
7607 break;
7608 case IPW_TX_RATE_48MB:
7609 ipw_rt->rt_rate = 96;
7610 break;
7611 case IPW_TX_RATE_54MB:
7612 ipw_rt->rt_rate = 108;
7613 break;
7614 default:
7615 ipw_rt->rt_rate = 0;
7616 break;
7617 }
7618
7619 /* antenna number */
7620 ipw_rt->rt_antenna = (antennaAndPhy & 3); /* Is this right? */
7621
7622 /* set the preamble flag if we have it */
7623 if ((antennaAndPhy & 64))
7624 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7625
7626 /* Set the size of the skb to the size of the frame */
7627 skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));
7628
7629 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
7630
7631 if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
7632 priv->ieee->stats.rx_errors++;
7633 else { /* ieee80211_rx succeeded, so it now owns the SKB */
7634 rxb->skb = NULL;
7635 /* no LED during capture */
7636 }
7637}
7638#endif
7639
7640static inline int is_network_packet(struct ipw_priv *priv,
7641 struct ieee80211_hdr_4addr *header)
7642{
7643 /* Filter incoming packets to determine if they are targetted toward
7644 * this network, discarding packets coming from ourselves */
7645 switch (priv->ieee->iw_mode) {
7646 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */
7647 /* packets from our adapter are dropped (echo) */
7648 if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
7649 return 0;
7650
7651 /* {broad,multi}cast packets to our BSSID go through */
7652 if (is_multicast_ether_addr(header->addr1) ||
7653 is_broadcast_ether_addr(header->addr1))
7654 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
7655
7656 /* packets to our adapter go through */
7657 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7658 ETH_ALEN);
7659
7660 case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */
7661 /* packets from our adapter are dropped (echo) */
7662 if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
7663 return 0;
7664
7665 /* {broad,multi}cast packets to our BSS go through */
7666 if (is_multicast_ether_addr(header->addr1) ||
7667 is_broadcast_ether_addr(header->addr1))
7668 return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
7669
7670 /* packets to our adapter go through */
7671 return !memcmp(header->addr1, priv->net_dev->dev_addr,
7672 ETH_ALEN);
7673 }
7674
7675 return 1;
7676}
7677
7678#define IPW_PACKET_RETRY_TIME HZ
7679
7680static inline int is_duplicate_packet(struct ipw_priv *priv,
7681 struct ieee80211_hdr_4addr *header)
7682{
7683 u16 sc = le16_to_cpu(header->seq_ctl);
7684 u16 seq = WLAN_GET_SEQ_SEQ(sc);
7685 u16 frag = WLAN_GET_SEQ_FRAG(sc);
7686 u16 *last_seq, *last_frag;
7687 unsigned long *last_time;
7688
7689 switch (priv->ieee->iw_mode) {
7690 case IW_MODE_ADHOC:
7691 {
7692 struct list_head *p;
7693 struct ipw_ibss_seq *entry = NULL;
7694 u8 *mac = header->addr2;
7695 int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;
7696
7697 __list_for_each(p, &priv->ibss_mac_hash[index]) {
7698 entry =
7699 list_entry(p, struct ipw_ibss_seq, list);
7700 if (!memcmp(entry->mac, mac, ETH_ALEN))
7701 break;
7702 }
7703 if (p == &priv->ibss_mac_hash[index]) {
7704 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
7705 if (!entry) {
7706 IPW_ERROR
7707 ("Cannot malloc new mac entry\n");
7708 return 0;
7709 }
7710 memcpy(entry->mac, mac, ETH_ALEN);
7711 entry->seq_num = seq;
7712 entry->frag_num = frag;
7713 entry->packet_time = jiffies;
7714 list_add(&entry->list,
7715 &priv->ibss_mac_hash[index]);
7716 return 0;
7717 }
7718 last_seq = &entry->seq_num;
7719 last_frag = &entry->frag_num;
7720 last_time = &entry->packet_time;
7721 break;
7722 }
7723 case IW_MODE_INFRA:
7724 last_seq = &priv->last_seq_num;
7725 last_frag = &priv->last_frag_num;
7726 last_time = &priv->last_packet_time;
7727 break;
7728 default:
7729 return 0;
7730 }
7731 if ((*last_seq == seq) &&
7732 time_after(*last_time + IPW_PACKET_RETRY_TIME, jiffies)) {
7733 if (*last_frag == frag)
7734 goto drop;
7735 if (*last_frag + 1 != frag)
7736 /* out-of-order fragment */
7737 goto drop;
7738 } else
7739 *last_seq = seq;
7740
7741 *last_frag = frag;
7742 *last_time = jiffies;
7743 return 0;
7744
7745 drop:
7746 /* Comment this line now since we observed the card receives
7747 * duplicate packets but the FCTL_RETRY bit is not set in the
7748 * IBSS mode with fragmentation enabled.
7749 BUG_ON(!(le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_RETRY)); */
7750 return 1;
7751}
7752
7753static void ipw_handle_mgmt_packet(struct ipw_priv *priv,
7754 struct ipw_rx_mem_buffer *rxb,
7755 struct ieee80211_rx_stats *stats)
7756{
7757 struct sk_buff *skb = rxb->skb;
7758 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;
7759 struct ieee80211_hdr_4addr *header = (struct ieee80211_hdr_4addr *)
7760 (skb->data + IPW_RX_FRAME_SIZE);
7761
7762 ieee80211_rx_mgt(priv->ieee, header, stats);
7763
7764 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&
7765 ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7766 IEEE80211_STYPE_PROBE_RESP) ||
7767 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==
7768 IEEE80211_STYPE_BEACON))) {
7769 if (!memcmp(header->addr3, priv->bssid, ETH_ALEN))
7770 ipw_add_station(priv, header->addr2);
7771 }
7772
7773 if (priv->config & CFG_NET_STATS) {
7774 IPW_DEBUG_HC("sending stat packet\n");
7775
7776 /* Set the size of the skb to the size of the full
7777 * ipw header and 802.11 frame */
7778 skb_put(skb, le16_to_cpu(pkt->u.frame.length) +
7779 IPW_RX_FRAME_SIZE);
7780
7781 /* Advance past the ipw packet header to the 802.11 frame */
7782 skb_pull(skb, IPW_RX_FRAME_SIZE);
7783
7784 /* Push the ieee80211_rx_stats before the 802.11 frame */
7785 memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));
7786
7787 skb->dev = priv->ieee->dev;
7788
7789 /* Point raw at the ieee80211_stats */
7790 skb->mac.raw = skb->data;
7791
7792 skb->pkt_type = PACKET_OTHERHOST;
7793 skb->protocol = __constant_htons(ETH_P_80211_STATS);
7794 memset(skb->cb, 0, sizeof(rxb->skb->cb));
7795 netif_rx(skb);
7796 rxb->skb = NULL;
7797 }
4900} 7798}
4901 7799
4902/* 7800/*
@@ -4912,8 +7810,8 @@ static void ipw_rx(struct ipw_priv *priv)
4912 u32 r, w, i; 7810 u32 r, w, i;
4913 u8 network_packet; 7811 u8 network_packet;
4914 7812
4915 r = ipw_read32(priv, CX2_RX_READ_INDEX); 7813 r = ipw_read32(priv, IPW_RX_READ_INDEX);
4916 w = ipw_read32(priv, CX2_RX_WRITE_INDEX); 7814 w = ipw_read32(priv, IPW_RX_WRITE_INDEX);
4917 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE; 7815 i = (priv->rxq->processed + 1) % RX_QUEUE_SIZE;
4918 7816
4919 while (i != r) { 7817 while (i != r) {
@@ -4927,7 +7825,7 @@ static void ipw_rx(struct ipw_priv *priv)
4927 priv->rxq->queue[i] = NULL; 7825 priv->rxq->queue[i] = NULL;
4928 7826
4929 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, 7827 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr,
4930 CX2_RX_BUF_SIZE, 7828 IPW_RX_BUF_SIZE,
4931 PCI_DMA_FROMDEVICE); 7829 PCI_DMA_FROMDEVICE);
4932 7830
4933 pkt = (struct ipw_rx_packet *)rxb->skb->data; 7831 pkt = (struct ipw_rx_packet *)rxb->skb->data;
@@ -4938,9 +7836,13 @@ static void ipw_rx(struct ipw_priv *priv)
4938 switch (pkt->header.message_type) { 7836 switch (pkt->header.message_type) {
4939 case RX_FRAME_TYPE: /* 802.11 frame */ { 7837 case RX_FRAME_TYPE: /* 802.11 frame */ {
4940 struct ieee80211_rx_stats stats = { 7838 struct ieee80211_rx_stats stats = {
4941 .rssi = pkt->u.frame.rssi_dbm - 7839 .rssi =
7840 le16_to_cpu(pkt->u.frame.rssi_dbm) -
4942 IPW_RSSI_TO_DBM, 7841 IPW_RSSI_TO_DBM,
4943 .signal = pkt->u.frame.signal, 7842 .signal =
7843 le16_to_cpu(pkt->u.frame.signal),
7844 .noise =
7845 le16_to_cpu(pkt->u.frame.noise),
4944 .rate = pkt->u.frame.rate, 7846 .rate = pkt->u.frame.rate,
4945 .mac_time = jiffies, 7847 .mac_time = jiffies,
4946 .received_channel = 7848 .received_channel =
@@ -4950,22 +7852,30 @@ static void ipw_rx(struct ipw_priv *priv)
4950 control & (1 << 0)) ? 7852 control & (1 << 0)) ?
4951 IEEE80211_24GHZ_BAND : 7853 IEEE80211_24GHZ_BAND :
4952 IEEE80211_52GHZ_BAND, 7854 IEEE80211_52GHZ_BAND,
4953 .len = pkt->u.frame.length, 7855 .len = le16_to_cpu(pkt->u.frame.length),
4954 }; 7856 };
4955 7857
4956 if (stats.rssi != 0) 7858 if (stats.rssi != 0)
4957 stats.mask |= IEEE80211_STATMASK_RSSI; 7859 stats.mask |= IEEE80211_STATMASK_RSSI;
4958 if (stats.signal != 0) 7860 if (stats.signal != 0)
4959 stats.mask |= IEEE80211_STATMASK_SIGNAL; 7861 stats.mask |= IEEE80211_STATMASK_SIGNAL;
7862 if (stats.noise != 0)
7863 stats.mask |= IEEE80211_STATMASK_NOISE;
4960 if (stats.rate != 0) 7864 if (stats.rate != 0)
4961 stats.mask |= IEEE80211_STATMASK_RATE; 7865 stats.mask |= IEEE80211_STATMASK_RATE;
4962 7866
4963 priv->rx_packets++; 7867 priv->rx_packets++;
4964 7868
4965#ifdef CONFIG_IPW_PROMISC 7869#ifdef CONFIG_IPW2200_MONITOR
4966 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 7870 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7871#ifdef CONFIG_IEEE80211_RADIOTAP
7872 ipw_handle_data_packet_monitor(priv,
7873 rxb,
7874 &stats);
7875#else
4967 ipw_handle_data_packet(priv, rxb, 7876 ipw_handle_data_packet(priv, rxb,
4968 &stats); 7877 &stats);
7878#endif
4969 break; 7879 break;
4970 } 7880 }
4971#endif 7881#endif
@@ -4979,35 +7889,9 @@ static void ipw_rx(struct ipw_priv *priv)
4979 * correctly -- we should probably use the 7889 * correctly -- we should probably use the
4980 * frame control of the packet and disregard 7890 * frame control of the packet and disregard
4981 * the current iw_mode */ 7891 * the current iw_mode */
4982 switch (priv->ieee->iw_mode) {
4983 case IW_MODE_ADHOC:
4984 network_packet =
4985 !memcmp(header->addr1,
4986 priv->net_dev->dev_addr,
4987 ETH_ALEN) ||
4988 !memcmp(header->addr3,
4989 priv->bssid, ETH_ALEN) ||
4990 is_broadcast_ether_addr(header->
4991 addr1)
4992 || is_multicast_ether_addr(header->
4993 addr1);
4994 break;
4995
4996 case IW_MODE_INFRA:
4997 default:
4998 network_packet =
4999 !memcmp(header->addr3,
5000 priv->bssid, ETH_ALEN) ||
5001 !memcmp(header->addr1,
5002 priv->net_dev->dev_addr,
5003 ETH_ALEN) ||
5004 is_broadcast_ether_addr(header->
5005 addr1)
5006 || is_multicast_ether_addr(header->
5007 addr1);
5008 break;
5009 }
5010 7892
7893 network_packet =
7894 is_network_packet(priv, header);
5011 if (network_packet && priv->assoc_network) { 7895 if (network_packet && priv->assoc_network) {
5012 priv->assoc_network->stats.rssi = 7896 priv->assoc_network->stats.rssi =
5013 stats.rssi; 7897 stats.rssi;
@@ -5017,9 +7901,10 @@ static void ipw_rx(struct ipw_priv *priv)
5017 } 7901 }
5018 7902
5019 IPW_DEBUG_RX("Frame: len=%u\n", 7903 IPW_DEBUG_RX("Frame: len=%u\n",
5020 pkt->u.frame.length); 7904 le16_to_cpu(pkt->u.frame.length));
5021 7905
5022 if (pkt->u.frame.length < frame_hdr_len(header)) { 7906 if (le16_to_cpu(pkt->u.frame.length) <
7907 frame_hdr_len(header)) {
5023 IPW_DEBUG_DROP 7908 IPW_DEBUG_DROP
5024 ("Received packet is too small. " 7909 ("Received packet is too small. "
5025 "Dropping.\n"); 7910 "Dropping.\n");
@@ -5028,34 +7913,22 @@ static void ipw_rx(struct ipw_priv *priv)
5028 break; 7913 break;
5029 } 7914 }
5030 7915
5031 switch (WLAN_FC_GET_TYPE(header->frame_ctl)) { 7916 switch (WLAN_FC_GET_TYPE
7917 (le16_to_cpu(header->frame_ctl))) {
7918
5032 case IEEE80211_FTYPE_MGMT: 7919 case IEEE80211_FTYPE_MGMT:
5033 ieee80211_rx_mgt(priv->ieee, header, 7920 ipw_handle_mgmt_packet(priv, rxb,
5034 &stats); 7921 &stats);
5035 if (priv->ieee->iw_mode == IW_MODE_ADHOC
5036 &&
5037 ((WLAN_FC_GET_STYPE
5038 (header->frame_ctl) ==
5039 IEEE80211_STYPE_PROBE_RESP)
5040 ||
5041 (WLAN_FC_GET_STYPE
5042 (header->frame_ctl) ==
5043 IEEE80211_STYPE_BEACON))
5044 && !memcmp(header->addr3,
5045 priv->bssid, ETH_ALEN))
5046 ipw_add_station(priv,
5047 header->addr2);
5048 break; 7922 break;
5049 7923
5050 case IEEE80211_FTYPE_CTL: 7924 case IEEE80211_FTYPE_CTL:
5051 break; 7925 break;
5052 7926
5053 case IEEE80211_FTYPE_DATA: 7927 case IEEE80211_FTYPE_DATA:
5054 if (network_packet) 7928 if (unlikely(!network_packet ||
5055 ipw_handle_data_packet(priv, 7929 is_duplicate_packet(priv,
5056 rxb, 7930 header)))
5057 &stats); 7931 {
5058 else
5059 IPW_DEBUG_DROP("Dropping: " 7932 IPW_DEBUG_DROP("Dropping: "
5060 MAC_FMT ", " 7933 MAC_FMT ", "
5061 MAC_FMT ", " 7934 MAC_FMT ", "
@@ -5066,6 +7939,12 @@ static void ipw_rx(struct ipw_priv *priv)
5066 addr2), 7939 addr2),
5067 MAC_ARG(header-> 7940 MAC_ARG(header->
5068 addr3)); 7941 addr3));
7942 break;
7943 }
7944
7945 ipw_handle_data_packet(priv, rxb,
7946 &stats);
7947
5069 break; 7948 break;
5070 } 7949 }
5071 break; 7950 break;
@@ -5096,7 +7975,7 @@ static void ipw_rx(struct ipw_priv *priv)
5096 } 7975 }
5097 7976
5098 pci_unmap_single(priv->pci_dev, rxb->dma_addr, 7977 pci_unmap_single(priv->pci_dev, rxb->dma_addr,
5099 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); 7978 IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
5100 list_add_tail(&rxb->list, &priv->rxq->rx_used); 7979 list_add_tail(&rxb->list, &priv->rxq->rx_used);
5101 7980
5102 i = (i + 1) % RX_QUEUE_SIZE; 7981 i = (i + 1) % RX_QUEUE_SIZE;
@@ -5108,128 +7987,129 @@ static void ipw_rx(struct ipw_priv *priv)
5108 ipw_rx_queue_restock(priv); 7987 ipw_rx_queue_restock(priv);
5109} 7988}
5110 7989
5111static void ipw_abort_scan(struct ipw_priv *priv) 7990#define DEFAULT_RTS_THRESHOLD 2304U
7991#define MIN_RTS_THRESHOLD 1U
7992#define MAX_RTS_THRESHOLD 2304U
7993#define DEFAULT_BEACON_INTERVAL 100U
7994#define DEFAULT_SHORT_RETRY_LIMIT 7U
7995#define DEFAULT_LONG_RETRY_LIMIT 4U
7996
7997static int ipw_sw_reset(struct ipw_priv *priv, int init)
5112{ 7998{
5113 int err; 7999 int band, modulation;
8000 int old_mode = priv->ieee->iw_mode;
5114 8001
5115 if (priv->status & STATUS_SCAN_ABORTING) { 8002 /* Initialize module parameter values here */
5116 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n"); 8003 priv->config = 0;
5117 return;
5118 }
5119 priv->status |= STATUS_SCAN_ABORTING;
5120 8004
5121 err = ipw_send_scan_abort(priv); 8005 /* We default to disabling the LED code as right now it causes
5122 if (err) 8006 * too many systems to lock up... */
5123 IPW_DEBUG_HC("Request to abort scan failed.\n"); 8007 if (!led)
5124} 8008 priv->config |= CFG_NO_LED;
5125 8009
5126static int ipw_request_scan(struct ipw_priv *priv) 8010 if (associate)
5127{ 8011 priv->config |= CFG_ASSOCIATE;
5128 struct ipw_scan_request_ext scan; 8012 else
5129 int channel_index = 0; 8013 IPW_DEBUG_INFO("Auto associate disabled.\n");
5130 int i, err, scan_type;
5131 8014
5132 if (priv->status & STATUS_EXIT_PENDING) { 8015 if (auto_create)
5133 IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n"); 8016 priv->config |= CFG_ADHOC_CREATE;
5134 priv->status |= STATUS_SCAN_PENDING; 8017 else
5135 return 0; 8018 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
5136 }
5137 8019
5138 if (priv->status & STATUS_SCANNING) { 8020 if (disable) {
5139 IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n"); 8021 priv->status |= STATUS_RF_KILL_SW;
5140 priv->status |= STATUS_SCAN_PENDING; 8022 IPW_DEBUG_INFO("Radio disabled.\n");
5141 ipw_abort_scan(priv);
5142 return 0;
5143 } 8023 }
5144 8024
5145 if (priv->status & STATUS_SCAN_ABORTING) { 8025 if (channel != 0) {
5146 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); 8026 priv->config |= CFG_STATIC_CHANNEL;
5147 priv->status |= STATUS_SCAN_PENDING; 8027 priv->channel = channel;
5148 return 0; 8028 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
8029 /* TODO: Validate that provided channel is in range */
5149 } 8030 }
8031#ifdef CONFIG_IPW_QOS
8032 ipw_qos_init(priv, qos_enable, qos_burst_enable,
8033 burst_duration_CCK, burst_duration_OFDM);
8034#endif /* CONFIG_IPW_QOS */
5150 8035
5151 if (priv->status & STATUS_RF_KILL_MASK) { 8036 switch (mode) {
5152 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n"); 8037 case 1:
5153 priv->status |= STATUS_SCAN_PENDING; 8038 priv->ieee->iw_mode = IW_MODE_ADHOC;
5154 return 0; 8039 priv->net_dev->type = ARPHRD_ETHER;
8040
8041 break;
8042#ifdef CONFIG_IPW2200_MONITOR
8043 case 2:
8044 priv->ieee->iw_mode = IW_MODE_MONITOR;
8045#ifdef CONFIG_IEEE80211_RADIOTAP
8046 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8047#else
8048 priv->net_dev->type = ARPHRD_IEEE80211;
8049#endif
8050 break;
8051#endif
8052 default:
8053 case 0:
8054 priv->net_dev->type = ARPHRD_ETHER;
8055 priv->ieee->iw_mode = IW_MODE_INFRA;
8056 break;
5155 } 8057 }
5156 8058
5157 memset(&scan, 0, sizeof(scan)); 8059 if (hwcrypto) {
8060 priv->ieee->host_encrypt = 0;
8061 priv->ieee->host_encrypt_msdu = 0;
8062 priv->ieee->host_decrypt = 0;
8063 priv->ieee->host_mc_decrypt = 0;
8064 }
8065 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
5158 8066
5159 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20; 8067 /* IPW2200/2915 is abled to do hardware fragmentation. */
5160 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20; 8068 priv->ieee->host_open_frag = 0;
5161 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20;
5162
5163 scan.full_scan_index = ieee80211_get_scans(priv->ieee);
5164 /* If we are roaming, then make this a directed scan for the current
5165 * network. Otherwise, ensure that every other scan is a fast
5166 * channel hop scan */
5167 if ((priv->status & STATUS_ROAMING)
5168 || (!(priv->status & STATUS_ASSOCIATED)
5169 && (priv->config & CFG_STATIC_ESSID)
5170 && (scan.full_scan_index % 2))) {
5171 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
5172 if (err) {
5173 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
5174 return err;
5175 }
5176 8069
5177 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; 8070 if ((priv->pci_dev->device == 0x4223) ||
8071 (priv->pci_dev->device == 0x4224)) {
8072 if (init)
8073 printk(KERN_INFO DRV_NAME
8074 ": Detected Intel PRO/Wireless 2915ABG Network "
8075 "Connection\n");
8076 priv->ieee->abg_true = 1;
8077 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
8078 modulation = IEEE80211_OFDM_MODULATION |
8079 IEEE80211_CCK_MODULATION;
8080 priv->adapter = IPW_2915ABG;
8081 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
5178 } else { 8082 } else {
5179 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN; 8083 if (init)
5180 } 8084 printk(KERN_INFO DRV_NAME
5181 8085 ": Detected Intel PRO/Wireless 2200BG Network "
5182 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { 8086 "Connection\n");
5183 int start = channel_index;
5184 for (i = 0; i < MAX_A_CHANNELS; i++) {
5185 if (band_a_active_channel[i] == 0)
5186 break;
5187 if ((priv->status & STATUS_ASSOCIATED) &&
5188 band_a_active_channel[i] == priv->channel)
5189 continue;
5190 channel_index++;
5191 scan.channels_list[channel_index] =
5192 band_a_active_channel[i];
5193 ipw_set_scan_type(&scan, channel_index, scan_type);
5194 }
5195 8087
5196 if (start != channel_index) { 8088 priv->ieee->abg_true = 0;
5197 scan.channels_list[start] = (u8) (IPW_A_MODE << 6) | 8089 band = IEEE80211_24GHZ_BAND;
5198 (channel_index - start); 8090 modulation = IEEE80211_OFDM_MODULATION |
5199 channel_index++; 8091 IEEE80211_CCK_MODULATION;
5200 } 8092 priv->adapter = IPW_2200BG;
8093 priv->ieee->mode = IEEE_G | IEEE_B;
5201 } 8094 }
5202 8095
5203 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) { 8096 priv->ieee->freq_band = band;
5204 int start = channel_index; 8097 priv->ieee->modulation = modulation;
5205 for (i = 0; i < MAX_B_CHANNELS; i++) {
5206 if (band_b_active_channel[i] == 0)
5207 break;
5208 if ((priv->status & STATUS_ASSOCIATED) &&
5209 band_b_active_channel[i] == priv->channel)
5210 continue;
5211 channel_index++;
5212 scan.channels_list[channel_index] =
5213 band_b_active_channel[i];
5214 ipw_set_scan_type(&scan, channel_index, scan_type);
5215 }
5216 8098
5217 if (start != channel_index) { 8099 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
5218 scan.channels_list[start] = (u8) (IPW_B_MODE << 6) |
5219 (channel_index - start);
5220 }
5221 }
5222 8100
5223 err = ipw_send_scan_request_ext(priv, &scan); 8101 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
5224 if (err) { 8102 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
5225 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
5226 return -EIO;
5227 }
5228 8103
5229 priv->status |= STATUS_SCANNING; 8104 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
5230 priv->status &= ~STATUS_SCAN_PENDING; 8105 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
8106 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
5231 8107
5232 return 0; 8108 /* If power management is turned on, default to AC mode */
8109 priv->power_mode = IPW_POWER_AC;
8110 priv->tx_power = IPW_TX_POWER_DEFAULT;
8111
8112 return old_mode == priv->ieee->iw_mode;
5233} 8113}
5234 8114
5235/* 8115/*
@@ -5247,12 +8127,16 @@ static int ipw_wx_get_name(struct net_device *dev,
5247 union iwreq_data *wrqu, char *extra) 8127 union iwreq_data *wrqu, char *extra)
5248{ 8128{
5249 struct ipw_priv *priv = ieee80211_priv(dev); 8129 struct ipw_priv *priv = ieee80211_priv(dev);
5250 if (!(priv->status & STATUS_ASSOCIATED)) 8130 down(&priv->sem);
8131 if (priv->status & STATUS_RF_KILL_MASK)
8132 strcpy(wrqu->name, "radio off");
8133 else if (!(priv->status & STATUS_ASSOCIATED))
5251 strcpy(wrqu->name, "unassociated"); 8134 strcpy(wrqu->name, "unassociated");
5252 else 8135 else
5253 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", 8136 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
5254 ipw_modes[priv->assoc_request.ieee_mode]); 8137 ipw_modes[priv->assoc_request.ieee_mode]);
5255 IPW_DEBUG_WX("Name: %s\n", wrqu->name); 8138 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
8139 up(&priv->sem);
5256 return 0; 8140 return 0;
5257} 8141}
5258 8142
@@ -5261,13 +8145,9 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5261 if (channel == 0) { 8145 if (channel == 0) {
5262 IPW_DEBUG_INFO("Setting channel to ANY (0)\n"); 8146 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
5263 priv->config &= ~CFG_STATIC_CHANNEL; 8147 priv->config &= ~CFG_STATIC_CHANNEL;
5264 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8148 IPW_DEBUG_ASSOC("Attempting to associate with new "
5265 STATUS_ASSOCIATING))) { 8149 "parameters.\n");
5266 IPW_DEBUG_ASSOC("Attempting to associate with new " 8150 ipw_associate(priv);
5267 "parameters.\n");
5268 ipw_associate(priv);
5269 }
5270
5271 return 0; 8151 return 0;
5272 } 8152 }
5273 8153
@@ -5282,14 +8162,32 @@ static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
5282 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel); 8162 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
5283 priv->channel = channel; 8163 priv->channel = channel;
5284 8164
5285 /* If we are currently associated, or trying to associate 8165#ifdef CONFIG_IPW2200_MONITOR
5286 * then see if this is a new channel (causing us to disassociate) */ 8166 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
5287 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8167 int i;
5288 IPW_DEBUG_ASSOC("Disassociating due to channel change.\n"); 8168 if (priv->status & STATUS_SCANNING) {
5289 ipw_disassociate(priv); 8169 IPW_DEBUG_SCAN("Scan abort triggered due to "
5290 } else { 8170 "channel change.\n");
5291 ipw_associate(priv); 8171 ipw_abort_scan(priv);
8172 }
8173
8174 for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)
8175 udelay(10);
8176
8177 if (priv->status & STATUS_SCANNING)
8178 IPW_DEBUG_SCAN("Still scanning...\n");
8179 else
8180 IPW_DEBUG_SCAN("Took %dms to abort current scan\n",
8181 1000 - i);
8182
8183 return 0;
5292 } 8184 }
8185#endif /* CONFIG_IPW2200_MONITOR */
8186
8187 /* Network configuration changed -- force [re]association */
8188 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
8189 if (!ipw_disassociate(priv))
8190 ipw_associate(priv);
5293 8191
5294 return 0; 8192 return 0;
5295} 8193}
@@ -5299,29 +8197,48 @@ static int ipw_wx_set_freq(struct net_device *dev,
5299 union iwreq_data *wrqu, char *extra) 8197 union iwreq_data *wrqu, char *extra)
5300{ 8198{
5301 struct ipw_priv *priv = ieee80211_priv(dev); 8199 struct ipw_priv *priv = ieee80211_priv(dev);
8200 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5302 struct iw_freq *fwrq = &wrqu->freq; 8201 struct iw_freq *fwrq = &wrqu->freq;
5303 8202 int ret = 0, i;
8203 u8 channel, flags;
8204 int band;
8205
8206 if (fwrq->m == 0) {
8207 IPW_DEBUG_WX("SET Freq/Channel -> any\n");
8208 down(&priv->sem);
8209 ret = ipw_set_channel(priv, 0);
8210 up(&priv->sem);
8211 return ret;
8212 }
5304 /* if setting by freq convert to channel */ 8213 /* if setting by freq convert to channel */
5305 if (fwrq->e == 1) { 8214 if (fwrq->e == 1) {
5306 if ((fwrq->m >= (int)2.412e8 && fwrq->m <= (int)2.487e8)) { 8215 channel = ipw_freq_to_channel(priv->ieee, fwrq->m);
5307 int f = fwrq->m / 100000; 8216 if (channel == 0)
5308 int c = 0; 8217 return -EINVAL;
8218 } else
8219 channel = fwrq->m;
8220
8221 if (!(band = ipw_is_valid_channel(priv->ieee, channel)))
8222 return -EINVAL;
5309 8223
5310 while ((c < REG_MAX_CHANNEL) && 8224 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5311 (f != ipw_frequencies[c])) 8225 i = ipw_channel_to_index(priv->ieee, channel);
5312 c++; 8226 if (i == -1)
8227 return -EINVAL;
5313 8228
5314 /* hack to fall through */ 8229 flags = (band == IEEE80211_24GHZ_BAND) ?
5315 fwrq->e = 0; 8230 geo->bg[i].flags : geo->a[i].flags;
5316 fwrq->m = c + 1; 8231 if (flags & IEEE80211_CH_PASSIVE_ONLY) {
8232 IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
8233 return -EINVAL;
5317 } 8234 }
5318 } 8235 }
5319 8236
5320 if (fwrq->e > 0 || fwrq->m > 1000)
5321 return -EOPNOTSUPP;
5322
5323 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 8237 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
5324 return ipw_set_channel(priv, (u8) fwrq->m); 8238 down(&priv->sem);
8239 ret = ipw_set_channel(priv, channel);
8240 up(&priv->sem);
8241 return ret;
5325} 8242}
5326 8243
5327static int ipw_wx_get_freq(struct net_device *dev, 8244static int ipw_wx_get_freq(struct net_device *dev,
@@ -5334,12 +8251,14 @@ static int ipw_wx_get_freq(struct net_device *dev,
5334 8251
5335 /* If we are associated, trying to associate, or have a statically 8252 /* If we are associated, trying to associate, or have a statically
5336 * configured CHANNEL then return that; otherwise return ANY */ 8253 * configured CHANNEL then return that; otherwise return ANY */
8254 down(&priv->sem);
5337 if (priv->config & CFG_STATIC_CHANNEL || 8255 if (priv->config & CFG_STATIC_CHANNEL ||
5338 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) 8256 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
5339 wrqu->freq.m = priv->channel; 8257 wrqu->freq.m = priv->channel;
5340 else 8258 else
5341 wrqu->freq.m = 0; 8259 wrqu->freq.m = 0;
5342 8260
8261 up(&priv->sem);
5343 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel); 8262 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
5344 return 0; 8263 return 0;
5345} 8264}
@@ -5353,11 +8272,8 @@ static int ipw_wx_set_mode(struct net_device *dev,
5353 8272
5354 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode); 8273 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
5355 8274
5356 if (wrqu->mode == priv->ieee->iw_mode)
5357 return 0;
5358
5359 switch (wrqu->mode) { 8275 switch (wrqu->mode) {
5360#ifdef CONFIG_IPW_PROMISC 8276#ifdef CONFIG_IPW2200_MONITOR
5361 case IW_MODE_MONITOR: 8277 case IW_MODE_MONITOR:
5362#endif 8278#endif
5363 case IW_MODE_ADHOC: 8279 case IW_MODE_ADHOC:
@@ -5369,31 +8285,33 @@ static int ipw_wx_set_mode(struct net_device *dev,
5369 default: 8285 default:
5370 return -EINVAL; 8286 return -EINVAL;
5371 } 8287 }
8288 if (wrqu->mode == priv->ieee->iw_mode)
8289 return 0;
8290
8291 down(&priv->sem);
8292
8293 ipw_sw_reset(priv, 0);
5372 8294
5373#ifdef CONFIG_IPW_PROMISC 8295#ifdef CONFIG_IPW2200_MONITOR
5374 if (priv->ieee->iw_mode == IW_MODE_MONITOR) 8296 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
5375 priv->net_dev->type = ARPHRD_ETHER; 8297 priv->net_dev->type = ARPHRD_ETHER;
5376 8298
5377 if (wrqu->mode == IW_MODE_MONITOR) 8299 if (wrqu->mode == IW_MODE_MONITOR)
8300#ifdef CONFIG_IEEE80211_RADIOTAP
8301 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
8302#else
5378 priv->net_dev->type = ARPHRD_IEEE80211; 8303 priv->net_dev->type = ARPHRD_IEEE80211;
5379#endif /* CONFIG_IPW_PROMISC */ 8304#endif
8305#endif /* CONFIG_IPW2200_MONITOR */
5380 8306
5381#ifdef CONFIG_PM
5382 /* Free the existing firmware and reset the fw_loaded 8307 /* Free the existing firmware and reset the fw_loaded
5383 * flag so ipw_load() will bring in the new firmawre */ 8308 * flag so ipw_load() will bring in the new firmawre */
5384 if (fw_loaded) { 8309 free_firmware();
5385 fw_loaded = 0;
5386 }
5387
5388 release_firmware(bootfw);
5389 release_firmware(ucode);
5390 release_firmware(firmware);
5391 bootfw = ucode = firmware = NULL;
5392#endif
5393 8310
5394 priv->ieee->iw_mode = wrqu->mode; 8311 priv->ieee->iw_mode = wrqu->mode;
5395 ipw_adapter_restart(priv);
5396 8312
8313 queue_work(priv->workqueue, &priv->adapter_restart);
8314 up(&priv->sem);
5397 return err; 8315 return err;
5398} 8316}
5399 8317
@@ -5402,20 +8320,13 @@ static int ipw_wx_get_mode(struct net_device *dev,
5402 union iwreq_data *wrqu, char *extra) 8320 union iwreq_data *wrqu, char *extra)
5403{ 8321{
5404 struct ipw_priv *priv = ieee80211_priv(dev); 8322 struct ipw_priv *priv = ieee80211_priv(dev);
5405 8323 down(&priv->sem);
5406 wrqu->mode = priv->ieee->iw_mode; 8324 wrqu->mode = priv->ieee->iw_mode;
5407 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode); 8325 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
5408 8326 up(&priv->sem);
5409 return 0; 8327 return 0;
5410} 8328}
5411 8329
5412#define DEFAULT_RTS_THRESHOLD 2304U
5413#define MIN_RTS_THRESHOLD 1U
5414#define MAX_RTS_THRESHOLD 2304U
5415#define DEFAULT_BEACON_INTERVAL 100U
5416#define DEFAULT_SHORT_RETRY_LIMIT 7U
5417#define DEFAULT_LONG_RETRY_LIMIT 4U
5418
5419/* Values are in microsecond */ 8330/* Values are in microsecond */
5420static const s32 timeout_duration[] = { 8331static const s32 timeout_duration[] = {
5421 350000, 8332 350000,
@@ -5439,8 +8350,8 @@ static int ipw_wx_get_range(struct net_device *dev,
5439{ 8350{
5440 struct ipw_priv *priv = ieee80211_priv(dev); 8351 struct ipw_priv *priv = ieee80211_priv(dev);
5441 struct iw_range *range = (struct iw_range *)extra; 8352 struct iw_range *range = (struct iw_range *)extra;
5442 u16 val; 8353 const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
5443 int i; 8354 int i = 0, j;
5444 8355
5445 wrqu->data.length = sizeof(*range); 8356 wrqu->data.length = sizeof(*range);
5446 memset(range, 0, sizeof(*range)); 8357 memset(range, 0, sizeof(*range));
@@ -5451,7 +8362,7 @@ static int ipw_wx_get_range(struct net_device *dev,
5451 range->max_qual.qual = 100; 8362 range->max_qual.qual = 100;
5452 /* TODO: Find real max RSSI and stick here */ 8363 /* TODO: Find real max RSSI and stick here */
5453 range->max_qual.level = 0; 8364 range->max_qual.level = 0;
5454 range->max_qual.noise = 0; 8365 range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
5455 range->max_qual.updated = 7; /* Updated all three */ 8366 range->max_qual.updated = 7; /* Updated all three */
5456 8367
5457 range->avg_qual.qual = 70; 8368 range->avg_qual.qual = 70;
@@ -5459,7 +8370,7 @@ static int ipw_wx_get_range(struct net_device *dev,
5459 range->avg_qual.level = 0; /* FIXME to real average level */ 8370 range->avg_qual.level = 0; /* FIXME to real average level */
5460 range->avg_qual.noise = 0; 8371 range->avg_qual.noise = 0;
5461 range->avg_qual.updated = 7; /* Updated all three */ 8372 range->avg_qual.updated = 7; /* Updated all three */
5462 8373 down(&priv->sem);
5463 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES); 8374 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
5464 8375
5465 for (i = 0; i < range->num_bitrates; i++) 8376 for (i = 0; i < range->num_bitrates; i++)
@@ -5479,19 +8390,35 @@ static int ipw_wx_get_range(struct net_device *dev,
5479 range->we_version_compiled = WIRELESS_EXT; 8390 range->we_version_compiled = WIRELESS_EXT;
5480 range->we_version_source = 16; 8391 range->we_version_source = 16;
5481 8392
5482 range->num_channels = FREQ_COUNT; 8393 i = 0;
5483 8394 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {
5484 val = 0; 8395 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES;
5485 for (i = 0; i < FREQ_COUNT; i++) { 8396 i++, j++) {
5486 range->freq[val].i = i + 1; 8397 range->freq[i].i = geo->bg[j].channel;
5487 range->freq[val].m = ipw_frequencies[i] * 100000; 8398 range->freq[i].m = geo->bg[j].freq * 100000;
5488 range->freq[val].e = 1; 8399 range->freq[i].e = 1;
5489 val++; 8400 }
8401 }
5490 8402
5491 if (val == IW_MAX_FREQUENCIES) 8403 if (priv->ieee->mode & IEEE_A) {
5492 break; 8404 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES;
8405 i++, j++) {
8406 range->freq[i].i = geo->a[j].channel;
8407 range->freq[i].m = geo->a[j].freq * 100000;
8408 range->freq[i].e = 1;
8409 }
5493 } 8410 }
5494 range->num_frequency = val; 8411
8412 range->num_channels = i;
8413 range->num_frequency = i;
8414
8415 up(&priv->sem);
8416
8417 /* Event capability (kernel + driver) */
8418 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
8419 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
8420 IW_EVENT_CAPA_MASK(SIOCGIWAP));
8421 range->event_capa[1] = IW_EVENT_CAPA_K_1;
5495 8422
5496 IPW_DEBUG_WX("GET Range\n"); 8423 IPW_DEBUG_WX("GET Range\n");
5497 return 0; 8424 return 0;
@@ -5512,25 +8439,23 @@ static int ipw_wx_set_wap(struct net_device *dev,
5512 8439
5513 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) 8440 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
5514 return -EINVAL; 8441 return -EINVAL;
5515 8442 down(&priv->sem);
5516 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) || 8443 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
5517 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8444 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5518 /* we disable mandatory BSSID association */ 8445 /* we disable mandatory BSSID association */
5519 IPW_DEBUG_WX("Setting AP BSSID to ANY\n"); 8446 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
5520 priv->config &= ~CFG_STATIC_BSSID; 8447 priv->config &= ~CFG_STATIC_BSSID;
5521 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8448 IPW_DEBUG_ASSOC("Attempting to associate with new "
5522 STATUS_ASSOCIATING))) { 8449 "parameters.\n");
5523 IPW_DEBUG_ASSOC("Attempting to associate with new " 8450 ipw_associate(priv);
5524 "parameters.\n"); 8451 up(&priv->sem);
5525 ipw_associate(priv);
5526 }
5527
5528 return 0; 8452 return 0;
5529 } 8453 }
5530 8454
5531 priv->config |= CFG_STATIC_BSSID; 8455 priv->config |= CFG_STATIC_BSSID;
5532 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) { 8456 if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
5533 IPW_DEBUG_WX("BSSID set to current BSSID.\n"); 8457 IPW_DEBUG_WX("BSSID set to current BSSID.\n");
8458 up(&priv->sem);
5534 return 0; 8459 return 0;
5535 } 8460 }
5536 8461
@@ -5539,15 +8464,12 @@ static int ipw_wx_set_wap(struct net_device *dev,
5539 8464
5540 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN); 8465 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
5541 8466
5542 /* If we are currently associated, or trying to associate 8467 /* Network configuration changed -- force [re]association */
5543 * then see if this is a new BSSID (causing us to disassociate) */ 8468 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
5544 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8469 if (!ipw_disassociate(priv))
5545 IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n");
5546 ipw_disassociate(priv);
5547 } else {
5548 ipw_associate(priv); 8470 ipw_associate(priv);
5549 }
5550 8471
8472 up(&priv->sem);
5551 return 0; 8473 return 0;
5552} 8474}
5553 8475
@@ -5558,15 +8480,17 @@ static int ipw_wx_get_wap(struct net_device *dev,
5558 struct ipw_priv *priv = ieee80211_priv(dev); 8480 struct ipw_priv *priv = ieee80211_priv(dev);
5559 /* If we are associated, trying to associate, or have a statically 8481 /* If we are associated, trying to associate, or have a statically
5560 * configured BSSID then return that; otherwise return ANY */ 8482 * configured BSSID then return that; otherwise return ANY */
8483 down(&priv->sem);
5561 if (priv->config & CFG_STATIC_BSSID || 8484 if (priv->config & CFG_STATIC_BSSID ||
5562 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8485 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5563 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 8486 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
5564 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); 8487 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
5565 } else 8488 } else
5566 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 8489 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
5567 8490
5568 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n", 8491 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
5569 MAC_ARG(wrqu->ap_addr.sa_data)); 8492 MAC_ARG(wrqu->ap_addr.sa_data));
8493 up(&priv->sem);
5570 return 0; 8494 return 0;
5571} 8495}
5572 8496
@@ -5577,21 +8501,22 @@ static int ipw_wx_set_essid(struct net_device *dev,
5577 struct ipw_priv *priv = ieee80211_priv(dev); 8501 struct ipw_priv *priv = ieee80211_priv(dev);
5578 char *essid = ""; /* ANY */ 8502 char *essid = ""; /* ANY */
5579 int length = 0; 8503 int length = 0;
5580 8504 down(&priv->sem);
5581 if (wrqu->essid.flags && wrqu->essid.length) { 8505 if (wrqu->essid.flags && wrqu->essid.length) {
5582 length = wrqu->essid.length - 1; 8506 length = wrqu->essid.length - 1;
5583 essid = extra; 8507 essid = extra;
5584 } 8508 }
5585 if (length == 0) { 8509 if (length == 0) {
5586 IPW_DEBUG_WX("Setting ESSID to ANY\n"); 8510 IPW_DEBUG_WX("Setting ESSID to ANY\n");
5587 priv->config &= ~CFG_STATIC_ESSID; 8511 if ((priv->config & CFG_STATIC_ESSID) &&
5588 if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED | 8512 !(priv->status & (STATUS_ASSOCIATED |
5589 STATUS_ASSOCIATING))) { 8513 STATUS_ASSOCIATING))) {
5590 IPW_DEBUG_ASSOC("Attempting to associate with new " 8514 IPW_DEBUG_ASSOC("Attempting to associate with new "
5591 "parameters.\n"); 8515 "parameters.\n");
8516 priv->config &= ~CFG_STATIC_ESSID;
5592 ipw_associate(priv); 8517 ipw_associate(priv);
5593 } 8518 }
5594 8519 up(&priv->sem);
5595 return 0; 8520 return 0;
5596 } 8521 }
5597 8522
@@ -5601,6 +8526,7 @@ static int ipw_wx_set_essid(struct net_device *dev,
5601 8526
5602 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { 8527 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
5603 IPW_DEBUG_WX("ESSID set to current ESSID.\n"); 8528 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
8529 up(&priv->sem);
5604 return 0; 8530 return 0;
5605 } 8531 }
5606 8532
@@ -5610,15 +8536,12 @@ static int ipw_wx_set_essid(struct net_device *dev,
5610 priv->essid_len = length; 8536 priv->essid_len = length;
5611 memcpy(priv->essid, essid, priv->essid_len); 8537 memcpy(priv->essid, essid, priv->essid_len);
5612 8538
5613 /* If we are currently associated, or trying to associate 8539 /* Network configuration changed -- force [re]association */
5614 * then see if this is a new ESSID (causing us to disassociate) */ 8540 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
5615 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8541 if (!ipw_disassociate(priv))
5616 IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n");
5617 ipw_disassociate(priv);
5618 } else {
5619 ipw_associate(priv); 8542 ipw_associate(priv);
5620 }
5621 8543
8544 up(&priv->sem);
5622 return 0; 8545 return 0;
5623} 8546}
5624 8547
@@ -5630,6 +8553,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
5630 8553
5631 /* If we are associated, trying to associate, or have a statically 8554 /* If we are associated, trying to associate, or have a statically
5632 * configured ESSID then return that; otherwise return ANY */ 8555 * configured ESSID then return that; otherwise return ANY */
8556 down(&priv->sem);
5633 if (priv->config & CFG_STATIC_ESSID || 8557 if (priv->config & CFG_STATIC_ESSID ||
5634 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) { 8558 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
5635 IPW_DEBUG_WX("Getting essid: '%s'\n", 8559 IPW_DEBUG_WX("Getting essid: '%s'\n",
@@ -5642,7 +8566,7 @@ static int ipw_wx_get_essid(struct net_device *dev,
5642 wrqu->essid.length = 0; 8566 wrqu->essid.length = 0;
5643 wrqu->essid.flags = 0; /* active */ 8567 wrqu->essid.flags = 0; /* active */
5644 } 8568 }
5645 8569 up(&priv->sem);
5646 return 0; 8570 return 0;
5647} 8571}
5648 8572
@@ -5655,11 +8579,12 @@ static int ipw_wx_set_nick(struct net_device *dev,
5655 IPW_DEBUG_WX("Setting nick to '%s'\n", extra); 8579 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
5656 if (wrqu->data.length > IW_ESSID_MAX_SIZE) 8580 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
5657 return -E2BIG; 8581 return -E2BIG;
5658 8582 down(&priv->sem);
5659 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); 8583 wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
5660 memset(priv->nick, 0, sizeof(priv->nick)); 8584 memset(priv->nick, 0, sizeof(priv->nick));
5661 memcpy(priv->nick, extra, wrqu->data.length); 8585 memcpy(priv->nick, extra, wrqu->data.length);
5662 IPW_DEBUG_TRACE("<<\n"); 8586 IPW_DEBUG_TRACE("<<\n");
8587 up(&priv->sem);
5663 return 0; 8588 return 0;
5664 8589
5665} 8590}
@@ -5670,9 +8595,11 @@ static int ipw_wx_get_nick(struct net_device *dev,
5670{ 8595{
5671 struct ipw_priv *priv = ieee80211_priv(dev); 8596 struct ipw_priv *priv = ieee80211_priv(dev);
5672 IPW_DEBUG_WX("Getting nick\n"); 8597 IPW_DEBUG_WX("Getting nick\n");
8598 down(&priv->sem);
5673 wrqu->data.length = strlen(priv->nick) + 1; 8599 wrqu->data.length = strlen(priv->nick) + 1;
5674 memcpy(extra, priv->nick, wrqu->data.length); 8600 memcpy(extra, priv->nick, wrqu->data.length);
5675 wrqu->data.flags = 1; /* active */ 8601 wrqu->data.flags = 1; /* active */
8602 up(&priv->sem);
5676 return 0; 8603 return 0;
5677} 8604}
5678 8605
@@ -5680,8 +8607,113 @@ static int ipw_wx_set_rate(struct net_device *dev,
5680 struct iw_request_info *info, 8607 struct iw_request_info *info,
5681 union iwreq_data *wrqu, char *extra) 8608 union iwreq_data *wrqu, char *extra)
5682{ 8609{
5683 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8610 /* TODO: We should use semaphores or locks for access to priv */
5684 return -EOPNOTSUPP; 8611 struct ipw_priv *priv = ieee80211_priv(dev);
8612 u32 target_rate = wrqu->bitrate.value;
8613 u32 fixed, mask;
8614
8615 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
8616 /* value = X, fixed = 1 means only rate X */
8617 /* value = X, fixed = 0 means all rates lower equal X */
8618
8619 if (target_rate == -1) {
8620 fixed = 0;
8621 mask = IEEE80211_DEFAULT_RATES_MASK;
8622 /* Now we should reassociate */
8623 goto apply;
8624 }
8625
8626 mask = 0;
8627 fixed = wrqu->bitrate.fixed;
8628
8629 if (target_rate == 1000000 || !fixed)
8630 mask |= IEEE80211_CCK_RATE_1MB_MASK;
8631 if (target_rate == 1000000)
8632 goto apply;
8633
8634 if (target_rate == 2000000 || !fixed)
8635 mask |= IEEE80211_CCK_RATE_2MB_MASK;
8636 if (target_rate == 2000000)
8637 goto apply;
8638
8639 if (target_rate == 5500000 || !fixed)
8640 mask |= IEEE80211_CCK_RATE_5MB_MASK;
8641 if (target_rate == 5500000)
8642 goto apply;
8643
8644 if (target_rate == 6000000 || !fixed)
8645 mask |= IEEE80211_OFDM_RATE_6MB_MASK;
8646 if (target_rate == 6000000)
8647 goto apply;
8648
8649 if (target_rate == 9000000 || !fixed)
8650 mask |= IEEE80211_OFDM_RATE_9MB_MASK;
8651 if (target_rate == 9000000)
8652 goto apply;
8653
8654 if (target_rate == 11000000 || !fixed)
8655 mask |= IEEE80211_CCK_RATE_11MB_MASK;
8656 if (target_rate == 11000000)
8657 goto apply;
8658
8659 if (target_rate == 12000000 || !fixed)
8660 mask |= IEEE80211_OFDM_RATE_12MB_MASK;
8661 if (target_rate == 12000000)
8662 goto apply;
8663
8664 if (target_rate == 18000000 || !fixed)
8665 mask |= IEEE80211_OFDM_RATE_18MB_MASK;
8666 if (target_rate == 18000000)
8667 goto apply;
8668
8669 if (target_rate == 24000000 || !fixed)
8670 mask |= IEEE80211_OFDM_RATE_24MB_MASK;
8671 if (target_rate == 24000000)
8672 goto apply;
8673
8674 if (target_rate == 36000000 || !fixed)
8675 mask |= IEEE80211_OFDM_RATE_36MB_MASK;
8676 if (target_rate == 36000000)
8677 goto apply;
8678
8679 if (target_rate == 48000000 || !fixed)
8680 mask |= IEEE80211_OFDM_RATE_48MB_MASK;
8681 if (target_rate == 48000000)
8682 goto apply;
8683
8684 if (target_rate == 54000000 || !fixed)
8685 mask |= IEEE80211_OFDM_RATE_54MB_MASK;
8686 if (target_rate == 54000000)
8687 goto apply;
8688
8689 IPW_DEBUG_WX("invalid rate specified, returning error\n");
8690 return -EINVAL;
8691
8692 apply:
8693 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
8694 mask, fixed ? "fixed" : "sub-rates");
8695 down(&priv->sem);
8696 if (mask == IEEE80211_DEFAULT_RATES_MASK) {
8697 priv->config &= ~CFG_FIXED_RATE;
8698 ipw_set_fixed_rate(priv, priv->ieee->mode);
8699 } else
8700 priv->config |= CFG_FIXED_RATE;
8701
8702 if (priv->rates_mask == mask) {
8703 IPW_DEBUG_WX("Mask set to current mask.\n");
8704 up(&priv->sem);
8705 return 0;
8706 }
8707
8708 priv->rates_mask = mask;
8709
8710 /* Network configuration changed -- force [re]association */
8711 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
8712 if (!ipw_disassociate(priv))
8713 ipw_associate(priv);
8714
8715 up(&priv->sem);
8716 return 0;
5685} 8717}
5686 8718
5687static int ipw_wx_get_rate(struct net_device *dev, 8719static int ipw_wx_get_rate(struct net_device *dev,
@@ -5689,8 +8721,9 @@ static int ipw_wx_get_rate(struct net_device *dev,
5689 union iwreq_data *wrqu, char *extra) 8721 union iwreq_data *wrqu, char *extra)
5690{ 8722{
5691 struct ipw_priv *priv = ieee80211_priv(dev); 8723 struct ipw_priv *priv = ieee80211_priv(dev);
8724 down(&priv->sem);
5692 wrqu->bitrate.value = priv->last_rate; 8725 wrqu->bitrate.value = priv->last_rate;
5693 8726 up(&priv->sem);
5694 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); 8727 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
5695 return 0; 8728 return 0;
5696} 8729}
@@ -5700,18 +8733,20 @@ static int ipw_wx_set_rts(struct net_device *dev,
5700 union iwreq_data *wrqu, char *extra) 8733 union iwreq_data *wrqu, char *extra)
5701{ 8734{
5702 struct ipw_priv *priv = ieee80211_priv(dev); 8735 struct ipw_priv *priv = ieee80211_priv(dev);
5703 8736 down(&priv->sem);
5704 if (wrqu->rts.disabled) 8737 if (wrqu->rts.disabled)
5705 priv->rts_threshold = DEFAULT_RTS_THRESHOLD; 8738 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
5706 else { 8739 else {
5707 if (wrqu->rts.value < MIN_RTS_THRESHOLD || 8740 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
5708 wrqu->rts.value > MAX_RTS_THRESHOLD) 8741 wrqu->rts.value > MAX_RTS_THRESHOLD) {
8742 up(&priv->sem);
5709 return -EINVAL; 8743 return -EINVAL;
5710 8744 }
5711 priv->rts_threshold = wrqu->rts.value; 8745 priv->rts_threshold = wrqu->rts.value;
5712 } 8746 }
5713 8747
5714 ipw_send_rts_threshold(priv, priv->rts_threshold); 8748 ipw_send_rts_threshold(priv, priv->rts_threshold);
8749 up(&priv->sem);
5715 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold); 8750 IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
5716 return 0; 8751 return 0;
5717} 8752}
@@ -5721,10 +8756,11 @@ static int ipw_wx_get_rts(struct net_device *dev,
5721 union iwreq_data *wrqu, char *extra) 8756 union iwreq_data *wrqu, char *extra)
5722{ 8757{
5723 struct ipw_priv *priv = ieee80211_priv(dev); 8758 struct ipw_priv *priv = ieee80211_priv(dev);
8759 down(&priv->sem);
5724 wrqu->rts.value = priv->rts_threshold; 8760 wrqu->rts.value = priv->rts_threshold;
5725 wrqu->rts.fixed = 0; /* no auto select */ 8761 wrqu->rts.fixed = 0; /* no auto select */
5726 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); 8762 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
5727 8763 up(&priv->sem);
5728 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value); 8764 IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
5729 return 0; 8765 return 0;
5730} 8766}
@@ -5734,41 +8770,33 @@ static int ipw_wx_set_txpow(struct net_device *dev,
5734 union iwreq_data *wrqu, char *extra) 8770 union iwreq_data *wrqu, char *extra)
5735{ 8771{
5736 struct ipw_priv *priv = ieee80211_priv(dev); 8772 struct ipw_priv *priv = ieee80211_priv(dev);
5737 struct ipw_tx_power tx_power; 8773 int err = 0;
5738 int i;
5739
5740 if (ipw_radio_kill_sw(priv, wrqu->power.disabled))
5741 return -EINPROGRESS;
5742
5743 if (wrqu->power.flags != IW_TXPOW_DBM)
5744 return -EINVAL;
5745 8774
5746 if ((wrqu->power.value > 20) || (wrqu->power.value < -12)) 8775 down(&priv->sem);
5747 return -EINVAL; 8776 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
8777 err = -EINPROGRESS;
8778 goto out;
8779 }
5748 8780
5749 priv->tx_power = wrqu->power.value; 8781 if (!wrqu->power.fixed)
8782 wrqu->power.value = IPW_TX_POWER_DEFAULT;
5750 8783
5751 memset(&tx_power, 0, sizeof(tx_power)); 8784 if (wrqu->power.flags != IW_TXPOW_DBM) {
5752 8785 err = -EINVAL;
5753 /* configure device for 'G' band */ 8786 goto out;
5754 tx_power.ieee_mode = IPW_G_MODE;
5755 tx_power.num_channels = 11;
5756 for (i = 0; i < 11; i++) {
5757 tx_power.channels_tx_power[i].channel_number = i + 1;
5758 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
5759 } 8787 }
5760 if (ipw_send_tx_power(priv, &tx_power))
5761 goto error;
5762 8788
5763 /* configure device to also handle 'B' band */ 8789 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
5764 tx_power.ieee_mode = IPW_B_MODE; 8790 (wrqu->power.value < IPW_TX_POWER_MIN)) {
5765 if (ipw_send_tx_power(priv, &tx_power)) 8791 err = -EINVAL;
5766 goto error; 8792 goto out;
5767 8793 }
5768 return 0;
5769 8794
5770 error: 8795 priv->tx_power = wrqu->power.value;
5771 return -EIO; 8796 err = ipw_set_tx_power(priv);
8797 out:
8798 up(&priv->sem);
8799 return err;
5772} 8800}
5773 8801
5774static int ipw_wx_get_txpow(struct net_device *dev, 8802static int ipw_wx_get_txpow(struct net_device *dev,
@@ -5776,14 +8804,15 @@ static int ipw_wx_get_txpow(struct net_device *dev,
5776 union iwreq_data *wrqu, char *extra) 8804 union iwreq_data *wrqu, char *extra)
5777{ 8805{
5778 struct ipw_priv *priv = ieee80211_priv(dev); 8806 struct ipw_priv *priv = ieee80211_priv(dev);
5779 8807 down(&priv->sem);
5780 wrqu->power.value = priv->tx_power; 8808 wrqu->power.value = priv->tx_power;
5781 wrqu->power.fixed = 1; 8809 wrqu->power.fixed = 1;
5782 wrqu->power.flags = IW_TXPOW_DBM; 8810 wrqu->power.flags = IW_TXPOW_DBM;
5783 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; 8811 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
8812 up(&priv->sem);
5784 8813
5785 IPW_DEBUG_WX("GET TX Power -> %s %d \n", 8814 IPW_DEBUG_WX("GET TX Power -> %s %d \n",
5786 wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value); 8815 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
5787 8816
5788 return 0; 8817 return 0;
5789} 8818}
@@ -5793,18 +8822,21 @@ static int ipw_wx_set_frag(struct net_device *dev,
5793 union iwreq_data *wrqu, char *extra) 8822 union iwreq_data *wrqu, char *extra)
5794{ 8823{
5795 struct ipw_priv *priv = ieee80211_priv(dev); 8824 struct ipw_priv *priv = ieee80211_priv(dev);
5796 8825 down(&priv->sem);
5797 if (wrqu->frag.disabled) 8826 if (wrqu->frag.disabled)
5798 priv->ieee->fts = DEFAULT_FTS; 8827 priv->ieee->fts = DEFAULT_FTS;
5799 else { 8828 else {
5800 if (wrqu->frag.value < MIN_FRAG_THRESHOLD || 8829 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
5801 wrqu->frag.value > MAX_FRAG_THRESHOLD) 8830 wrqu->frag.value > MAX_FRAG_THRESHOLD) {
8831 up(&priv->sem);
5802 return -EINVAL; 8832 return -EINVAL;
8833 }
5803 8834
5804 priv->ieee->fts = wrqu->frag.value & ~0x1; 8835 priv->ieee->fts = wrqu->frag.value & ~0x1;
5805 } 8836 }
5806 8837
5807 ipw_send_frag_threshold(priv, wrqu->frag.value); 8838 ipw_send_frag_threshold(priv, wrqu->frag.value);
8839 up(&priv->sem);
5808 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value); 8840 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
5809 return 0; 8841 return 0;
5810} 8842}
@@ -5814,10 +8846,11 @@ static int ipw_wx_get_frag(struct net_device *dev,
5814 union iwreq_data *wrqu, char *extra) 8846 union iwreq_data *wrqu, char *extra)
5815{ 8847{
5816 struct ipw_priv *priv = ieee80211_priv(dev); 8848 struct ipw_priv *priv = ieee80211_priv(dev);
8849 down(&priv->sem);
5817 wrqu->frag.value = priv->ieee->fts; 8850 wrqu->frag.value = priv->ieee->fts;
5818 wrqu->frag.fixed = 0; /* no auto select */ 8851 wrqu->frag.fixed = 0; /* no auto select */
5819 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS); 8852 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
5820 8853 up(&priv->sem);
5821 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value); 8854 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
5822 8855
5823 return 0; 8856 return 0;
@@ -5827,16 +8860,128 @@ static int ipw_wx_set_retry(struct net_device *dev,
5827 struct iw_request_info *info, 8860 struct iw_request_info *info,
5828 union iwreq_data *wrqu, char *extra) 8861 union iwreq_data *wrqu, char *extra)
5829{ 8862{
5830 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8863 struct ipw_priv *priv = ieee80211_priv(dev);
5831 return -EOPNOTSUPP; 8864
8865 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)
8866 return -EINVAL;
8867
8868 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
8869 return 0;
8870
8871 if (wrqu->retry.value < 0 || wrqu->retry.value > 255)
8872 return -EINVAL;
8873
8874 down(&priv->sem);
8875 if (wrqu->retry.flags & IW_RETRY_MIN)
8876 priv->short_retry_limit = (u8) wrqu->retry.value;
8877 else if (wrqu->retry.flags & IW_RETRY_MAX)
8878 priv->long_retry_limit = (u8) wrqu->retry.value;
8879 else {
8880 priv->short_retry_limit = (u8) wrqu->retry.value;
8881 priv->long_retry_limit = (u8) wrqu->retry.value;
8882 }
8883
8884 ipw_send_retry_limit(priv, priv->short_retry_limit,
8885 priv->long_retry_limit);
8886 up(&priv->sem);
8887 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",
8888 priv->short_retry_limit, priv->long_retry_limit);
8889 return 0;
5832} 8890}
5833 8891
5834static int ipw_wx_get_retry(struct net_device *dev, 8892static int ipw_wx_get_retry(struct net_device *dev,
5835 struct iw_request_info *info, 8893 struct iw_request_info *info,
5836 union iwreq_data *wrqu, char *extra) 8894 union iwreq_data *wrqu, char *extra)
5837{ 8895{
5838 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 8896 struct ipw_priv *priv = ieee80211_priv(dev);
5839 return -EOPNOTSUPP; 8897
8898 down(&priv->sem);
8899 wrqu->retry.disabled = 0;
8900
8901 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
8902 up(&priv->sem);
8903 return -EINVAL;
8904 }
8905
8906 if (wrqu->retry.flags & IW_RETRY_MAX) {
8907 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
8908 wrqu->retry.value = priv->long_retry_limit;
8909 } else if (wrqu->retry.flags & IW_RETRY_MIN) {
8910 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
8911 wrqu->retry.value = priv->short_retry_limit;
8912 } else {
8913 wrqu->retry.flags = IW_RETRY_LIMIT;
8914 wrqu->retry.value = priv->short_retry_limit;
8915 }
8916 up(&priv->sem);
8917
8918 IPW_DEBUG_WX("GET retry -> %d \n", wrqu->retry.value);
8919
8920 return 0;
8921}
8922
8923static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
8924 int essid_len)
8925{
8926 struct ipw_scan_request_ext scan;
8927 int err = 0, scan_type;
8928
8929 down(&priv->sem);
8930
8931 if (priv->status & STATUS_RF_KILL_MASK) {
8932 IPW_DEBUG_HC("Aborting scan due to RF kill activation\n");
8933 priv->status |= STATUS_SCAN_PENDING;
8934 goto done;
8935 }
8936
8937 IPW_DEBUG_HC("starting request direct scan!\n");
8938
8939 if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
8940 err = wait_event_interruptible(priv->wait_state,
8941 !(priv->
8942 status & (STATUS_SCANNING |
8943 STATUS_SCAN_ABORTING)));
8944 if (err) {
8945 IPW_DEBUG_HC("aborting direct scan");
8946 goto done;
8947 }
8948 }
8949 memset(&scan, 0, sizeof(scan));
8950
8951 if (priv->config & CFG_SPEED_SCAN)
8952 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8953 cpu_to_le16(30);
8954 else
8955 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =
8956 cpu_to_le16(20);
8957
8958 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
8959 cpu_to_le16(20);
8960 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
8961 scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
8962
8963 scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
8964
8965 err = ipw_send_ssid(priv, essid, essid_len);
8966 if (err) {
8967 IPW_DEBUG_HC("Attempt to send SSID command failed\n");
8968 goto done;
8969 }
8970 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
8971
8972 ipw_add_scan_channels(priv, &scan, scan_type);
8973
8974 err = ipw_send_scan_request_ext(priv, &scan);
8975 if (err) {
8976 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
8977 goto done;
8978 }
8979
8980 priv->status |= STATUS_SCANNING;
8981
8982 done:
8983 up(&priv->sem);
8984 return err;
5840} 8985}
5841 8986
5842static int ipw_wx_set_scan(struct net_device *dev, 8987static int ipw_wx_set_scan(struct net_device *dev,
@@ -5844,9 +8989,21 @@ static int ipw_wx_set_scan(struct net_device *dev,
5844 union iwreq_data *wrqu, char *extra) 8989 union iwreq_data *wrqu, char *extra)
5845{ 8990{
5846 struct ipw_priv *priv = ieee80211_priv(dev); 8991 struct ipw_priv *priv = ieee80211_priv(dev);
8992 struct iw_scan_req *req = NULL;
8993 if (wrqu->data.length
8994 && wrqu->data.length == sizeof(struct iw_scan_req)) {
8995 req = (struct iw_scan_req *)extra;
8996 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
8997 ipw_request_direct_scan(priv, req->essid,
8998 req->essid_len);
8999 return 0;
9000 }
9001 }
9002
5847 IPW_DEBUG_WX("Start scan\n"); 9003 IPW_DEBUG_WX("Start scan\n");
5848 if (ipw_request_scan(priv)) 9004
5849 return -EIO; 9005 queue_work(priv->workqueue, &priv->request_scan);
9006
5850 return 0; 9007 return 0;
5851} 9008}
5852 9009
@@ -5863,7 +9020,21 @@ static int ipw_wx_set_encode(struct net_device *dev,
5863 union iwreq_data *wrqu, char *key) 9020 union iwreq_data *wrqu, char *key)
5864{ 9021{
5865 struct ipw_priv *priv = ieee80211_priv(dev); 9022 struct ipw_priv *priv = ieee80211_priv(dev);
5866 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key); 9023 int ret;
9024 u32 cap = priv->capability;
9025
9026 down(&priv->sem);
9027 ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
9028
9029 /* In IBSS mode, we need to notify the firmware to update
9030 * the beacon info after we changed the capability. */
9031 if (cap != priv->capability &&
9032 priv->ieee->iw_mode == IW_MODE_ADHOC &&
9033 priv->status & STATUS_ASSOCIATED)
9034 ipw_disassociate(priv);
9035
9036 up(&priv->sem);
9037 return ret;
5867} 9038}
5868 9039
5869static int ipw_wx_get_encode(struct net_device *dev, 9040static int ipw_wx_get_encode(struct net_device *dev,
@@ -5880,17 +9051,17 @@ static int ipw_wx_set_power(struct net_device *dev,
5880{ 9051{
5881 struct ipw_priv *priv = ieee80211_priv(dev); 9052 struct ipw_priv *priv = ieee80211_priv(dev);
5882 int err; 9053 int err;
5883 9054 down(&priv->sem);
5884 if (wrqu->power.disabled) { 9055 if (wrqu->power.disabled) {
5885 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode); 9056 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
5886 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM); 9057 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
5887 if (err) { 9058 if (err) {
5888 IPW_DEBUG_WX("failed setting power mode.\n"); 9059 IPW_DEBUG_WX("failed setting power mode.\n");
9060 up(&priv->sem);
5889 return err; 9061 return err;
5890 } 9062 }
5891
5892 IPW_DEBUG_WX("SET Power Management Mode -> off\n"); 9063 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
5893 9064 up(&priv->sem);
5894 return 0; 9065 return 0;
5895 } 9066 }
5896 9067
@@ -5902,6 +9073,7 @@ static int ipw_wx_set_power(struct net_device *dev,
5902 default: /* Otherwise we don't support it */ 9073 default: /* Otherwise we don't support it */
5903 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n", 9074 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
5904 wrqu->power.flags); 9075 wrqu->power.flags);
9076 up(&priv->sem);
5905 return -EOPNOTSUPP; 9077 return -EOPNOTSUPP;
5906 } 9078 }
5907 9079
@@ -5914,11 +9086,12 @@ static int ipw_wx_set_power(struct net_device *dev,
5914 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode)); 9086 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
5915 if (err) { 9087 if (err) {
5916 IPW_DEBUG_WX("failed setting power mode.\n"); 9088 IPW_DEBUG_WX("failed setting power mode.\n");
9089 up(&priv->sem);
5917 return err; 9090 return err;
5918 } 9091 }
5919 9092
5920 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); 9093 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
5921 9094 up(&priv->sem);
5922 return 0; 9095 return 0;
5923} 9096}
5924 9097
@@ -5927,13 +9100,13 @@ static int ipw_wx_get_power(struct net_device *dev,
5927 union iwreq_data *wrqu, char *extra) 9100 union iwreq_data *wrqu, char *extra)
5928{ 9101{
5929 struct ipw_priv *priv = ieee80211_priv(dev); 9102 struct ipw_priv *priv = ieee80211_priv(dev);
5930 9103 down(&priv->sem);
5931 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 9104 if (!(priv->power_mode & IPW_POWER_ENABLED))
5932 wrqu->power.disabled = 1; 9105 wrqu->power.disabled = 1;
5933 } else { 9106 else
5934 wrqu->power.disabled = 0; 9107 wrqu->power.disabled = 0;
5935 }
5936 9108
9109 up(&priv->sem);
5937 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode); 9110 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
5938 9111
5939 return 0; 9112 return 0;
@@ -5946,7 +9119,7 @@ static int ipw_wx_set_powermode(struct net_device *dev,
5946 struct ipw_priv *priv = ieee80211_priv(dev); 9119 struct ipw_priv *priv = ieee80211_priv(dev);
5947 int mode = *(int *)extra; 9120 int mode = *(int *)extra;
5948 int err; 9121 int err;
5949 9122 down(&priv->sem);
5950 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) { 9123 if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
5951 mode = IPW_POWER_AC; 9124 mode = IPW_POWER_AC;
5952 priv->power_mode = mode; 9125 priv->power_mode = mode;
@@ -5959,10 +9132,11 @@ static int ipw_wx_set_powermode(struct net_device *dev,
5959 9132
5960 if (err) { 9133 if (err) {
5961 IPW_DEBUG_WX("failed setting power mode.\n"); 9134 IPW_DEBUG_WX("failed setting power mode.\n");
9135 up(&priv->sem);
5962 return err; 9136 return err;
5963 } 9137 }
5964 } 9138 }
5965 9139 up(&priv->sem);
5966 return 0; 9140 return 0;
5967} 9141}
5968 9142
@@ -6011,7 +9185,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6011 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode); 9185 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
6012 return -EINVAL; 9186 return -EINVAL;
6013 } 9187 }
6014 9188 down(&priv->sem);
6015 if (priv->adapter == IPW_2915ABG) { 9189 if (priv->adapter == IPW_2915ABG) {
6016 priv->ieee->abg_true = 1; 9190 priv->ieee->abg_true = 1;
6017 if (mode & IEEE_A) { 9191 if (mode & IEEE_A) {
@@ -6023,6 +9197,7 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6023 if (mode & IEEE_A) { 9197 if (mode & IEEE_A) {
6024 IPW_WARNING("Attempt to set 2200BG into " 9198 IPW_WARNING("Attempt to set 2200BG into "
6025 "802.11a mode\n"); 9199 "802.11a mode\n");
9200 up(&priv->sem);
6026 return -EINVAL; 9201 return -EINVAL;
6027 } 9202 }
6028 9203
@@ -6046,20 +9221,20 @@ static int ipw_wx_set_wireless_mode(struct net_device *dev,
6046 priv->ieee->modulation = modulation; 9221 priv->ieee->modulation = modulation;
6047 init_supported_rates(priv, &priv->rates); 9222 init_supported_rates(priv, &priv->rates);
6048 9223
6049 /* If we are currently associated, or trying to associate 9224 /* Network configuration changed -- force [re]association */
6050 * then see if this is a new configuration (causing us to 9225 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
6051 * disassociate) */ 9226 if (!ipw_disassociate(priv)) {
6052 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
6053 /* The resulting association will trigger
6054 * the new rates to be sent to the device */
6055 IPW_DEBUG_ASSOC("Disassociating due to mode change.\n");
6056 ipw_disassociate(priv);
6057 } else
6058 ipw_send_supported_rates(priv, &priv->rates); 9227 ipw_send_supported_rates(priv, &priv->rates);
9228 ipw_associate(priv);
9229 }
9230
9231 /* Update the band LEDs */
9232 ipw_led_band_on(priv);
6059 9233
6060 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n", 9234 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
6061 mode & IEEE_A ? 'a' : '.', 9235 mode & IEEE_A ? 'a' : '.',
6062 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.'); 9236 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
9237 up(&priv->sem);
6063 return 0; 9238 return 0;
6064} 9239}
6065 9240
@@ -6068,124 +9243,234 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
6068 union iwreq_data *wrqu, char *extra) 9243 union iwreq_data *wrqu, char *extra)
6069{ 9244{
6070 struct ipw_priv *priv = ieee80211_priv(dev); 9245 struct ipw_priv *priv = ieee80211_priv(dev);
6071 9246 down(&priv->sem);
6072 switch (priv->ieee->freq_band) { 9247 switch (priv->ieee->mode) {
6073 case IEEE80211_24GHZ_BAND: 9248 case IEEE_A:
6074 switch (priv->ieee->modulation) {
6075 case IEEE80211_CCK_MODULATION:
6076 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6077 break;
6078 case IEEE80211_OFDM_MODULATION:
6079 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6080 break;
6081 default:
6082 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
6083 break;
6084 }
6085 break;
6086
6087 case IEEE80211_52GHZ_BAND:
6088 strncpy(extra, "802.11a (1)", MAX_WX_STRING); 9249 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
6089 break; 9250 break;
6090 9251 case IEEE_B:
6091 default: /* Mixed Band */ 9252 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6092 switch (priv->ieee->modulation) { 9253 break;
6093 case IEEE80211_CCK_MODULATION: 9254 case IEEE_A | IEEE_B:
6094 strncpy(extra, "802.11ab (3)", MAX_WX_STRING); 9255 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
6095 break; 9256 break;
6096 case IEEE80211_OFDM_MODULATION: 9257 case IEEE_G:
6097 strncpy(extra, "802.11ag (5)", MAX_WX_STRING); 9258 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6098 break; 9259 break;
6099 default: 9260 case IEEE_A | IEEE_G:
6100 strncpy(extra, "802.11abg (7)", MAX_WX_STRING); 9261 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
6101 break; 9262 break;
6102 } 9263 case IEEE_B | IEEE_G:
9264 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
9265 break;
9266 case IEEE_A | IEEE_B | IEEE_G:
9267 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
9268 break;
9269 default:
9270 strncpy(extra, "unknown", MAX_WX_STRING);
6103 break; 9271 break;
6104 } 9272 }
6105 9273
6106 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra); 9274 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
6107 9275
6108 wrqu->data.length = strlen(extra) + 1; 9276 wrqu->data.length = strlen(extra) + 1;
9277 up(&priv->sem);
6109 9278
6110 return 0; 9279 return 0;
6111} 9280}
6112 9281
6113#ifdef CONFIG_IPW_PROMISC 9282static int ipw_wx_set_preamble(struct net_device *dev,
6114static int ipw_wx_set_promisc(struct net_device *dev, 9283 struct iw_request_info *info,
9284 union iwreq_data *wrqu, char *extra)
9285{
9286 struct ipw_priv *priv = ieee80211_priv(dev);
9287 int mode = *(int *)extra;
9288 down(&priv->sem);
9289 /* Switching from SHORT -> LONG requires a disassociation */
9290 if (mode == 1) {
9291 if (!(priv->config & CFG_PREAMBLE_LONG)) {
9292 priv->config |= CFG_PREAMBLE_LONG;
9293
9294 /* Network configuration changed -- force [re]association */
9295 IPW_DEBUG_ASSOC
9296 ("[re]association triggered due to preamble change.\n");
9297 if (!ipw_disassociate(priv))
9298 ipw_associate(priv);
9299 }
9300 goto done;
9301 }
9302
9303 if (mode == 0) {
9304 priv->config &= ~CFG_PREAMBLE_LONG;
9305 goto done;
9306 }
9307 up(&priv->sem);
9308 return -EINVAL;
9309
9310 done:
9311 up(&priv->sem);
9312 return 0;
9313}
9314
9315static int ipw_wx_get_preamble(struct net_device *dev,
9316 struct iw_request_info *info,
9317 union iwreq_data *wrqu, char *extra)
9318{
9319 struct ipw_priv *priv = ieee80211_priv(dev);
9320 down(&priv->sem);
9321 if (priv->config & CFG_PREAMBLE_LONG)
9322 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
9323 else
9324 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
9325 up(&priv->sem);
9326 return 0;
9327}
9328
9329#ifdef CONFIG_IPW2200_MONITOR
9330static int ipw_wx_set_monitor(struct net_device *dev,
6115 struct iw_request_info *info, 9331 struct iw_request_info *info,
6116 union iwreq_data *wrqu, char *extra) 9332 union iwreq_data *wrqu, char *extra)
6117{ 9333{
6118 struct ipw_priv *priv = ieee80211_priv(dev); 9334 struct ipw_priv *priv = ieee80211_priv(dev);
6119 int *parms = (int *)extra; 9335 int *parms = (int *)extra;
6120 int enable = (parms[0] > 0); 9336 int enable = (parms[0] > 0);
6121 9337 down(&priv->sem);
6122 IPW_DEBUG_WX("SET PROMISC: %d %d\n", enable, parms[1]); 9338 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
6123 if (enable) { 9339 if (enable) {
6124 if (priv->ieee->iw_mode != IW_MODE_MONITOR) { 9340 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9341#ifdef CONFIG_IEEE80211_RADIOTAP
9342 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
9343#else
6125 priv->net_dev->type = ARPHRD_IEEE80211; 9344 priv->net_dev->type = ARPHRD_IEEE80211;
6126 ipw_adapter_restart(priv); 9345#endif
9346 queue_work(priv->workqueue, &priv->adapter_restart);
6127 } 9347 }
6128 9348
6129 ipw_set_channel(priv, parms[1]); 9349 ipw_set_channel(priv, parms[1]);
6130 } else { 9350 } else {
6131 if (priv->ieee->iw_mode != IW_MODE_MONITOR) 9351 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
9352 up(&priv->sem);
6132 return 0; 9353 return 0;
9354 }
6133 priv->net_dev->type = ARPHRD_ETHER; 9355 priv->net_dev->type = ARPHRD_ETHER;
6134 ipw_adapter_restart(priv); 9356 queue_work(priv->workqueue, &priv->adapter_restart);
6135 } 9357 }
9358 up(&priv->sem);
6136 return 0; 9359 return 0;
6137} 9360}
6138 9361
9362#endif // CONFIG_IPW2200_MONITOR
9363
6139static int ipw_wx_reset(struct net_device *dev, 9364static int ipw_wx_reset(struct net_device *dev,
6140 struct iw_request_info *info, 9365 struct iw_request_info *info,
6141 union iwreq_data *wrqu, char *extra) 9366 union iwreq_data *wrqu, char *extra)
6142{ 9367{
6143 struct ipw_priv *priv = ieee80211_priv(dev); 9368 struct ipw_priv *priv = ieee80211_priv(dev);
6144 IPW_DEBUG_WX("RESET\n"); 9369 IPW_DEBUG_WX("RESET\n");
6145 ipw_adapter_restart(priv); 9370 queue_work(priv->workqueue, &priv->adapter_restart);
9371 return 0;
9372}
9373
9374static int ipw_wx_sw_reset(struct net_device *dev,
9375 struct iw_request_info *info,
9376 union iwreq_data *wrqu, char *extra)
9377{
9378 struct ipw_priv *priv = ieee80211_priv(dev);
9379 union iwreq_data wrqu_sec = {
9380 .encoding = {
9381 .flags = IW_ENCODE_DISABLED,
9382 },
9383 };
9384 int ret;
9385
9386 IPW_DEBUG_WX("SW_RESET\n");
9387
9388 down(&priv->sem);
9389
9390 ret = ipw_sw_reset(priv, 0);
9391 if (!ret) {
9392 free_firmware();
9393 ipw_adapter_restart(priv);
9394 }
9395
9396 /* The SW reset bit might have been toggled on by the 'disable'
9397 * module parameter, so take appropriate action */
9398 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);
9399
9400 up(&priv->sem);
9401 ieee80211_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);
9402 down(&priv->sem);
9403
9404 if (!(priv->status & STATUS_RF_KILL_MASK)) {
9405 /* Configuration likely changed -- force [re]association */
9406 IPW_DEBUG_ASSOC("[re]association triggered due to sw "
9407 "reset.\n");
9408 if (!ipw_disassociate(priv))
9409 ipw_associate(priv);
9410 }
9411
9412 up(&priv->sem);
9413
6146 return 0; 9414 return 0;
6147} 9415}
6148#endif // CONFIG_IPW_PROMISC
6149 9416
6150/* Rebase the WE IOCTLs to zero for the handler array */ 9417/* Rebase the WE IOCTLs to zero for the handler array */
6151#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] 9418#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
6152static iw_handler ipw_wx_handlers[] = { 9419static iw_handler ipw_wx_handlers[] = {
6153 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, 9420 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
6154 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 9421 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
6155 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 9422 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
6156 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 9423 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
6157 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, 9424 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
6158 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 9425 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
6159 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 9426 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
6160 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 9427 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
6161 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, 9428 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
6162 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, 9429 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
6163 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, 9430 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
6164 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, 9431 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
6165 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, 9432 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
6166 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, 9433 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
6167 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, 9434 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
6168 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, 9435 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
6169 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, 9436 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
6170 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, 9437 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
6171 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, 9438 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
6172 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, 9439 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
6173 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, 9440 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
6174 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, 9441 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
6175 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, 9442 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
6176 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, 9443 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
6177 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, 9444 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
6178 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, 9445 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
6179 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, 9446 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
6180 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, 9447 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
9448 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
9449 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
9450 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
9451 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
9452 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
9453 IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
9454 IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
9455 IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth,
9456 IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
9457 IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
9458 IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
6181}; 9459};
6182 9460
6183#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV 9461enum {
6184#define IPW_PRIV_GET_POWER SIOCIWFIRSTPRIV+1 9462 IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,
6185#define IPW_PRIV_SET_MODE SIOCIWFIRSTPRIV+2 9463 IPW_PRIV_GET_POWER,
6186#define IPW_PRIV_GET_MODE SIOCIWFIRSTPRIV+3 9464 IPW_PRIV_SET_MODE,
6187#define IPW_PRIV_SET_PROMISC SIOCIWFIRSTPRIV+4 9465 IPW_PRIV_GET_MODE,
6188#define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5 9466 IPW_PRIV_SET_PREAMBLE,
9467 IPW_PRIV_GET_PREAMBLE,
9468 IPW_PRIV_RESET,
9469 IPW_PRIV_SW_RESET,
9470#ifdef CONFIG_IPW2200_MONITOR
9471 IPW_PRIV_SET_MONITOR,
9472#endif
9473};
6189 9474
6190static struct iw_priv_args ipw_priv_args[] = { 9475static struct iw_priv_args ipw_priv_args[] = {
6191 { 9476 {
@@ -6204,14 +9489,25 @@ static struct iw_priv_args ipw_priv_args[] = {
6204 .cmd = IPW_PRIV_GET_MODE, 9489 .cmd = IPW_PRIV_GET_MODE,
6205 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, 9490 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
6206 .name = "get_mode"}, 9491 .name = "get_mode"},
6207#ifdef CONFIG_IPW_PROMISC
6208 { 9492 {
6209 IPW_PRIV_SET_PROMISC, 9493 .cmd = IPW_PRIV_SET_PREAMBLE,
6210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"}, 9494 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
9495 .name = "set_preamble"},
9496 {
9497 .cmd = IPW_PRIV_GET_PREAMBLE,
9498 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
9499 .name = "get_preamble"},
6211 { 9500 {
6212 IPW_PRIV_RESET, 9501 IPW_PRIV_RESET,
6213 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"}, 9502 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
6214#endif /* CONFIG_IPW_PROMISC */ 9503 {
9504 IPW_PRIV_SW_RESET,
9505 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},
9506#ifdef CONFIG_IPW2200_MONITOR
9507 {
9508 IPW_PRIV_SET_MONITOR,
9509 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
9510#endif /* CONFIG_IPW2200_MONITOR */
6215}; 9511};
6216 9512
6217static iw_handler ipw_priv_handler[] = { 9513static iw_handler ipw_priv_handler[] = {
@@ -6219,19 +9515,23 @@ static iw_handler ipw_priv_handler[] = {
6219 ipw_wx_get_powermode, 9515 ipw_wx_get_powermode,
6220 ipw_wx_set_wireless_mode, 9516 ipw_wx_set_wireless_mode,
6221 ipw_wx_get_wireless_mode, 9517 ipw_wx_get_wireless_mode,
6222#ifdef CONFIG_IPW_PROMISC 9518 ipw_wx_set_preamble,
6223 ipw_wx_set_promisc, 9519 ipw_wx_get_preamble,
6224 ipw_wx_reset, 9520 ipw_wx_reset,
9521 ipw_wx_sw_reset,
9522#ifdef CONFIG_IPW2200_MONITOR
9523 ipw_wx_set_monitor,
6225#endif 9524#endif
6226}; 9525};
6227 9526
6228static struct iw_handler_def ipw_wx_handler_def = { 9527static struct iw_handler_def ipw_wx_handler_def = {
6229 .standard = ipw_wx_handlers, 9528 .standard = ipw_wx_handlers,
6230 .num_standard = ARRAY_SIZE(ipw_wx_handlers), 9529 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
6231 .num_private = ARRAY_SIZE(ipw_priv_handler), 9530 .num_private = ARRAY_SIZE(ipw_priv_handler),
6232 .num_private_args = ARRAY_SIZE(ipw_priv_args), 9531 .num_private_args = ARRAY_SIZE(ipw_priv_args),
6233 .private = ipw_priv_handler, 9532 .private = ipw_priv_handler,
6234 .private_args = ipw_priv_args, 9533 .private_args = ipw_priv_args,
9534 .get_wireless_stats = ipw_get_wireless_stats,
6235}; 9535};
6236 9536
6237/* 9537/*
@@ -6246,8 +9546,8 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
6246 9546
6247 wstats = &priv->wstats; 9547 wstats = &priv->wstats;
6248 9548
6249 /* if hw is disabled, then ipw2100_get_ordinal() can't be called. 9549 /* if hw is disabled, then ipw_get_ordinal() can't be called.
6250 * ipw2100_wx_wireless_stats seems to be called before fw is 9550 * netdev->get_wireless_stats seems to be called before fw is
6251 * initialized. STATUS_ASSOCIATED will only be set if the hw is up 9551 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
6252 * and associated; if not associcated, the values are all meaningless 9552 * and associated; if not associcated, the values are all meaningless
6253 * anyway, so set them all to NULL and INVALID */ 9553 * anyway, so set them all to NULL and INVALID */
@@ -6298,7 +9598,7 @@ static inline void init_sys_config(struct ipw_sys_config *sys_config)
6298 sys_config->dot11g_auto_detection = 0; 9598 sys_config->dot11g_auto_detection = 0;
6299 sys_config->enable_cts_to_self = 0; 9599 sys_config->enable_cts_to_self = 0;
6300 sys_config->bt_coexist_collision_thr = 0; 9600 sys_config->bt_coexist_collision_thr = 0;
6301 sys_config->pass_noise_stats_to_host = 1; 9601 sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256
6302} 9602}
6303 9603
6304static int ipw_net_open(struct net_device *dev) 9604static int ipw_net_open(struct net_device *dev)
@@ -6306,9 +9606,11 @@ static int ipw_net_open(struct net_device *dev)
6306 struct ipw_priv *priv = ieee80211_priv(dev); 9606 struct ipw_priv *priv = ieee80211_priv(dev);
6307 IPW_DEBUG_INFO("dev->open\n"); 9607 IPW_DEBUG_INFO("dev->open\n");
6308 /* we should be verifying the device is ready to be opened */ 9608 /* we should be verifying the device is ready to be opened */
9609 down(&priv->sem);
6309 if (!(priv->status & STATUS_RF_KILL_MASK) && 9610 if (!(priv->status & STATUS_RF_KILL_MASK) &&
6310 (priv->status & STATUS_ASSOCIATED)) 9611 (priv->status & STATUS_ASSOCIATED))
6311 netif_start_queue(dev); 9612 netif_start_queue(dev);
9613 up(&priv->sem);
6312 return 0; 9614 return 0;
6313} 9615}
6314 9616
@@ -6326,22 +9628,34 @@ modify to send one tfd per fragment instead of using chunking. otherwise
6326we need to heavily modify the ieee80211_skb_to_txb. 9628we need to heavily modify the ieee80211_skb_to_txb.
6327*/ 9629*/
6328 9630
6329static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb) 9631static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
9632 int pri)
6330{ 9633{
6331 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) 9634 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
6332 txb->fragments[0]->data; 9635 txb->fragments[0]->data;
6333 int i = 0; 9636 int i = 0;
6334 struct tfd_frame *tfd; 9637 struct tfd_frame *tfd;
9638#ifdef CONFIG_IPW_QOS
9639 int tx_id = ipw_get_tx_queue_number(priv, pri);
9640 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9641#else
6335 struct clx2_tx_queue *txq = &priv->txq[0]; 9642 struct clx2_tx_queue *txq = &priv->txq[0];
9643#endif
6336 struct clx2_queue *q = &txq->q; 9644 struct clx2_queue *q = &txq->q;
6337 u8 id, hdr_len, unicast; 9645 u8 id, hdr_len, unicast;
6338 u16 remaining_bytes; 9646 u16 remaining_bytes;
9647 int fc;
9648
9649 /* If there isn't room in the queue, we return busy and let the
9650 * network stack requeue the packet for us */
9651 if (ipw_queue_space(q) < q->high_mark)
9652 return NETDEV_TX_BUSY;
6339 9653
6340 switch (priv->ieee->iw_mode) { 9654 switch (priv->ieee->iw_mode) {
6341 case IW_MODE_ADHOC: 9655 case IW_MODE_ADHOC:
6342 hdr_len = IEEE80211_3ADDR_LEN; 9656 hdr_len = IEEE80211_3ADDR_LEN;
6343 unicast = !is_broadcast_ether_addr(hdr->addr1) && 9657 unicast = !(is_multicast_ether_addr(hdr->addr1) ||
6344 !is_multicast_ether_addr(hdr->addr1); 9658 is_broadcast_ether_addr(hdr->addr1));
6345 id = ipw_find_station(priv, hdr->addr1); 9659 id = ipw_find_station(priv, hdr->addr1);
6346 if (id == IPW_INVALID_STATION) { 9660 if (id == IPW_INVALID_STATION) {
6347 id = ipw_add_station(priv, hdr->addr1); 9661 id = ipw_add_station(priv, hdr->addr1);
@@ -6356,8 +9670,8 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6356 9670
6357 case IW_MODE_INFRA: 9671 case IW_MODE_INFRA:
6358 default: 9672 default:
6359 unicast = !is_broadcast_ether_addr(hdr->addr3) && 9673 unicast = !(is_multicast_ether_addr(hdr->addr3) ||
6360 !is_multicast_ether_addr(hdr->addr3); 9674 is_broadcast_ether_addr(hdr->addr3));
6361 hdr_len = IEEE80211_3ADDR_LEN; 9675 hdr_len = IEEE80211_3ADDR_LEN;
6362 id = 0; 9676 id = 0;
6363 break; 9677 break;
@@ -6372,26 +9686,83 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6372 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK; 9686 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
6373 9687
6374 tfd->u.data.cmd_id = DINO_CMD_TX; 9688 tfd->u.data.cmd_id = DINO_CMD_TX;
6375 tfd->u.data.len = txb->payload_size; 9689 tfd->u.data.len = cpu_to_le16(txb->payload_size);
6376 remaining_bytes = txb->payload_size; 9690 remaining_bytes = txb->payload_size;
6377 if (unlikely(!unicast))
6378 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP;
6379 else
6380 tfd->u.data.tx_flags = DCT_FLAG_NO_WEP | DCT_FLAG_ACK_REQD;
6381 9691
6382 if (priv->assoc_request.ieee_mode == IPW_B_MODE) 9692 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
6383 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_CCK; 9693 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
6384 else 9694 else
6385 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM; 9695 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;
6386 9696
6387 if (priv->config & CFG_PREAMBLE) 9697 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
6388 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREMBL; 9698 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
9699
9700 fc = le16_to_cpu(hdr->frame_ctl);
9701 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
6389 9702
6390 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len); 9703 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
6391 9704
9705 if (likely(unicast))
9706 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9707
9708 if (txb->encrypted && !priv->ieee->host_encrypt) {
9709 switch (priv->ieee->sec.level) {
9710 case SEC_LEVEL_3:
9711 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9712 IEEE80211_FCTL_PROTECTED;
9713 /* XXX: ACK flag must be set for CCMP even if it
9714 * is a multicast/broadcast packet, because CCMP
9715 * group communication encrypted by GTK is
9716 * actually done by the AP. */
9717 if (!unicast)
9718 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;
9719
9720 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9721 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;
9722 tfd->u.data.key_index = 0;
9723 tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;
9724 break;
9725 case SEC_LEVEL_2:
9726 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9727 IEEE80211_FCTL_PROTECTED;
9728 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;
9729 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;
9730 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;
9731 break;
9732 case SEC_LEVEL_1:
9733 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=
9734 IEEE80211_FCTL_PROTECTED;
9735 tfd->u.data.key_index = priv->ieee->tx_keyidx;
9736 if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <=
9737 40)
9738 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;
9739 else
9740 tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;
9741 break;
9742 case SEC_LEVEL_0:
9743 break;
9744 default:
9745 printk(KERN_ERR "Unknow security level %d\n",
9746 priv->ieee->sec.level);
9747 break;
9748 }
9749 } else
9750 /* No hardware encryption */
9751 tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;
9752
9753#ifdef CONFIG_IPW_QOS
9754 ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data), unicast);
9755#endif /* CONFIG_IPW_QOS */
9756
6392 /* payload */ 9757 /* payload */
6393 tfd->u.data.num_chunks = min((u8) (NUM_TFD_CHUNKS - 2), txb->nr_frags); 9758 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
6394 for (i = 0; i < tfd->u.data.num_chunks; i++) { 9759 txb->nr_frags));
9760 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
9761 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
9762 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
9763 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
9764 i, le32_to_cpu(tfd->u.data.num_chunks),
9765 txb->fragments[i]->len - hdr_len);
6395 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n", 9766 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
6396 i, tfd->u.data.num_chunks, 9767 i, tfd->u.data.num_chunks,
6397 txb->fragments[i]->len - hdr_len); 9768 txb->fragments[i]->len - hdr_len);
@@ -6399,11 +9770,13 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6399 txb->fragments[i]->len - hdr_len); 9770 txb->fragments[i]->len - hdr_len);
6400 9771
6401 tfd->u.data.chunk_ptr[i] = 9772 tfd->u.data.chunk_ptr[i] =
6402 pci_map_single(priv->pci_dev, 9773 cpu_to_le32(pci_map_single
6403 txb->fragments[i]->data + hdr_len, 9774 (priv->pci_dev,
6404 txb->fragments[i]->len - hdr_len, 9775 txb->fragments[i]->data + hdr_len,
6405 PCI_DMA_TODEVICE); 9776 txb->fragments[i]->len - hdr_len,
6406 tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len; 9777 PCI_DMA_TODEVICE));
9778 tfd->u.data.chunk_len[i] =
9779 cpu_to_le16(txb->fragments[i]->len - hdr_len);
6407 } 9780 }
6408 9781
6409 if (i != txb->nr_frags) { 9782 if (i != txb->nr_frags) {
@@ -6418,9 +9791,10 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6418 remaining_bytes); 9791 remaining_bytes);
6419 skb = alloc_skb(remaining_bytes, GFP_ATOMIC); 9792 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
6420 if (skb != NULL) { 9793 if (skb != NULL) {
6421 tfd->u.data.chunk_len[i] = remaining_bytes; 9794 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
6422 for (j = i; j < txb->nr_frags; j++) { 9795 for (j = i; j < txb->nr_frags; j++) {
6423 int size = txb->fragments[j]->len - hdr_len; 9796 int size = txb->fragments[j]->len - hdr_len;
9797
6424 printk(KERN_INFO "Adding frag %d %d...\n", 9798 printk(KERN_INFO "Adding frag %d %d...\n",
6425 j, size); 9799 j, size);
6426 memcpy(skb_put(skb, size), 9800 memcpy(skb_put(skb, size),
@@ -6429,10 +9803,14 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6429 dev_kfree_skb_any(txb->fragments[i]); 9803 dev_kfree_skb_any(txb->fragments[i]);
6430 txb->fragments[i] = skb; 9804 txb->fragments[i] = skb;
6431 tfd->u.data.chunk_ptr[i] = 9805 tfd->u.data.chunk_ptr[i] =
6432 pci_map_single(priv->pci_dev, skb->data, 9806 cpu_to_le32(pci_map_single
6433 tfd->u.data.chunk_len[i], 9807 (priv->pci_dev, skb->data,
6434 PCI_DMA_TODEVICE); 9808 tfd->u.data.chunk_len[i],
6435 tfd->u.data.num_chunks++; 9809 PCI_DMA_TODEVICE));
9810
9811 tfd->u.data.num_chunks =
9812 cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
9813 1);
6436 } 9814 }
6437 } 9815 }
6438 9816
@@ -6440,14 +9818,28 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6440 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); 9818 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
6441 ipw_write32(priv, q->reg_w, q->first_empty); 9819 ipw_write32(priv, q->reg_w, q->first_empty);
6442 9820
6443 if (ipw_queue_space(q) < q->high_mark) 9821 return NETDEV_TX_OK;
6444 netif_stop_queue(priv->net_dev);
6445
6446 return;
6447 9822
6448 drop: 9823 drop:
6449 IPW_DEBUG_DROP("Silently dropping Tx packet.\n"); 9824 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
6450 ieee80211_txb_free(txb); 9825 ieee80211_txb_free(txb);
9826 return NETDEV_TX_OK;
9827}
9828
9829static int ipw_net_is_queue_full(struct net_device *dev, int pri)
9830{
9831 struct ipw_priv *priv = ieee80211_priv(dev);
9832#ifdef CONFIG_IPW_QOS
9833 int tx_id = ipw_get_tx_queue_number(priv, pri);
9834 struct clx2_tx_queue *txq = &priv->txq[tx_id];
9835#else
9836 struct clx2_tx_queue *txq = &priv->txq[0];
9837#endif /* CONFIG_IPW_QOS */
9838
9839 if (ipw_queue_space(&txq->q) < txq->q.high_mark)
9840 return 1;
9841
9842 return 0;
6451} 9843}
6452 9844
6453static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, 9845static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
@@ -6455,9 +9847,9 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
6455{ 9847{
6456 struct ipw_priv *priv = ieee80211_priv(dev); 9848 struct ipw_priv *priv = ieee80211_priv(dev);
6457 unsigned long flags; 9849 unsigned long flags;
9850 int ret;
6458 9851
6459 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size); 9852 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
6460
6461 spin_lock_irqsave(&priv->lock, flags); 9853 spin_lock_irqsave(&priv->lock, flags);
6462 9854
6463 if (!(priv->status & STATUS_ASSOCIATED)) { 9855 if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -6467,10 +9859,12 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
6467 goto fail_unlock; 9859 goto fail_unlock;
6468 } 9860 }
6469 9861
6470 ipw_tx_skb(priv, txb); 9862 ret = ipw_tx_skb(priv, txb, pri);
6471 9863 if (ret == NETDEV_TX_OK)
9864 __ipw_led_activity_on(priv);
6472 spin_unlock_irqrestore(&priv->lock, flags); 9865 spin_unlock_irqrestore(&priv->lock, flags);
6473 return 0; 9866
9867 return ret;
6474 9868
6475 fail_unlock: 9869 fail_unlock:
6476 spin_unlock_irqrestore(&priv->lock, flags); 9870 spin_unlock_irqrestore(&priv->lock, flags);
@@ -6497,11 +9891,13 @@ static int ipw_net_set_mac_address(struct net_device *dev, void *p)
6497 struct sockaddr *addr = p; 9891 struct sockaddr *addr = p;
6498 if (!is_valid_ether_addr(addr->sa_data)) 9892 if (!is_valid_ether_addr(addr->sa_data))
6499 return -EADDRNOTAVAIL; 9893 return -EADDRNOTAVAIL;
9894 down(&priv->sem);
6500 priv->config |= CFG_CUSTOM_MAC; 9895 priv->config |= CFG_CUSTOM_MAC;
6501 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); 9896 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
6502 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n", 9897 printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
6503 priv->net_dev->name, MAC_ARG(priv->mac_addr)); 9898 priv->net_dev->name, MAC_ARG(priv->mac_addr));
6504 ipw_adapter_restart(priv); 9899 queue_work(priv->workqueue, &priv->adapter_restart);
9900 up(&priv->sem);
6505 return 0; 9901 return 0;
6506} 9902}
6507 9903
@@ -6524,7 +9920,7 @@ static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6524 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)", 9920 snprintf(info->fw_version, sizeof(info->fw_version), "%s (%s)",
6525 vers, date); 9921 vers, date);
6526 strcpy(info->bus_info, pci_name(p->pci_dev)); 9922 strcpy(info->bus_info, pci_name(p->pci_dev));
6527 info->eedump_len = CX2_EEPROM_IMAGE_SIZE; 9923 info->eedump_len = IPW_EEPROM_IMAGE_SIZE;
6528} 9924}
6529 9925
6530static u32 ipw_ethtool_get_link(struct net_device *dev) 9926static u32 ipw_ethtool_get_link(struct net_device *dev)
@@ -6535,7 +9931,7 @@ static u32 ipw_ethtool_get_link(struct net_device *dev)
6535 9931
6536static int ipw_ethtool_get_eeprom_len(struct net_device *dev) 9932static int ipw_ethtool_get_eeprom_len(struct net_device *dev)
6537{ 9933{
6538 return CX2_EEPROM_IMAGE_SIZE; 9934 return IPW_EEPROM_IMAGE_SIZE;
6539} 9935}
6540 9936
6541static int ipw_ethtool_get_eeprom(struct net_device *dev, 9937static int ipw_ethtool_get_eeprom(struct net_device *dev,
@@ -6543,10 +9939,11 @@ static int ipw_ethtool_get_eeprom(struct net_device *dev,
6543{ 9939{
6544 struct ipw_priv *p = ieee80211_priv(dev); 9940 struct ipw_priv *p = ieee80211_priv(dev);
6545 9941
6546 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) 9942 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
6547 return -EINVAL; 9943 return -EINVAL;
6548 9944 down(&p->sem);
6549 memcpy(bytes, &((u8 *) p->eeprom)[eeprom->offset], eeprom->len); 9945 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);
9946 up(&p->sem);
6550 return 0; 9947 return 0;
6551} 9948}
6552 9949
@@ -6556,23 +9953,23 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
6556 struct ipw_priv *p = ieee80211_priv(dev); 9953 struct ipw_priv *p = ieee80211_priv(dev);
6557 int i; 9954 int i;
6558 9955
6559 if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE) 9956 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)
6560 return -EINVAL; 9957 return -EINVAL;
6561 9958 down(&p->sem);
6562 memcpy(&((u8 *) p->eeprom)[eeprom->offset], bytes, eeprom->len); 9959 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);
6563 for (i = IPW_EEPROM_DATA; 9960 for (i = IPW_EEPROM_DATA;
6564 i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; i++) 9961 i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++)
6565 ipw_write8(p, i, p->eeprom[i]); 9962 ipw_write8(p, i, p->eeprom[i]);
6566 9963 up(&p->sem);
6567 return 0; 9964 return 0;
6568} 9965}
6569 9966
6570static struct ethtool_ops ipw_ethtool_ops = { 9967static struct ethtool_ops ipw_ethtool_ops = {
6571 .get_link = ipw_ethtool_get_link, 9968 .get_link = ipw_ethtool_get_link,
6572 .get_drvinfo = ipw_ethtool_get_drvinfo, 9969 .get_drvinfo = ipw_ethtool_get_drvinfo,
6573 .get_eeprom_len = ipw_ethtool_get_eeprom_len, 9970 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
6574 .get_eeprom = ipw_ethtool_get_eeprom, 9971 .get_eeprom = ipw_ethtool_get_eeprom,
6575 .set_eeprom = ipw_ethtool_set_eeprom, 9972 .set_eeprom = ipw_ethtool_set_eeprom,
6576}; 9973};
6577 9974
6578static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) 9975static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
@@ -6590,8 +9987,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6590 goto none; 9987 goto none;
6591 } 9988 }
6592 9989
6593 inta = ipw_read32(priv, CX2_INTA_RW); 9990 inta = ipw_read32(priv, IPW_INTA_RW);
6594 inta_mask = ipw_read32(priv, CX2_INTA_MASK_R); 9991 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);
6595 9992
6596 if (inta == 0xFFFFFFFF) { 9993 if (inta == 0xFFFFFFFF) {
6597 /* Hardware disappeared */ 9994 /* Hardware disappeared */
@@ -6599,7 +9996,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6599 goto none; 9996 goto none;
6600 } 9997 }
6601 9998
6602 if (!(inta & (CX2_INTA_MASK_ALL & inta_mask))) { 9999 if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {
6603 /* Shared interrupt */ 10000 /* Shared interrupt */
6604 goto none; 10001 goto none;
6605 } 10002 }
@@ -6608,8 +10005,8 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
6608 ipw_disable_interrupts(priv); 10005 ipw_disable_interrupts(priv);
6609 10006
6610 /* ack current interrupts */ 10007 /* ack current interrupts */
6611 inta &= (CX2_INTA_MASK_ALL & inta_mask); 10008 inta &= (IPW_INTA_MASK_ALL & inta_mask);
6612 ipw_write32(priv, CX2_INTA_RW, inta); 10009 ipw_write32(priv, IPW_INTA_RW, inta);
6613 10010
6614 /* Cache INTA value for our tasklet */ 10011 /* Cache INTA value for our tasklet */
6615 priv->isr_inta = inta; 10012 priv->isr_inta = inta;
@@ -6655,28 +10052,116 @@ static void ipw_rf_kill(void *adapter)
6655 spin_unlock_irqrestore(&priv->lock, flags); 10052 spin_unlock_irqrestore(&priv->lock, flags);
6656} 10053}
6657 10054
10055static void ipw_bg_rf_kill(void *data)
10056{
10057 struct ipw_priv *priv = data;
10058 down(&priv->sem);
10059 ipw_rf_kill(data);
10060 up(&priv->sem);
10061}
10062
10063void ipw_link_up(struct ipw_priv *priv)
10064{
10065 priv->last_seq_num = -1;
10066 priv->last_frag_num = -1;
10067 priv->last_packet_time = 0;
10068
10069 netif_carrier_on(priv->net_dev);
10070 if (netif_queue_stopped(priv->net_dev)) {
10071 IPW_DEBUG_NOTIF("waking queue\n");
10072 netif_wake_queue(priv->net_dev);
10073 } else {
10074 IPW_DEBUG_NOTIF("starting queue\n");
10075 netif_start_queue(priv->net_dev);
10076 }
10077
10078 cancel_delayed_work(&priv->request_scan);
10079 ipw_reset_stats(priv);
10080 /* Ensure the rate is updated immediately */
10081 priv->last_rate = ipw_get_current_rate(priv);
10082 ipw_gather_stats(priv);
10083 ipw_led_link_up(priv);
10084 notify_wx_assoc_event(priv);
10085
10086 if (priv->config & CFG_BACKGROUND_SCAN)
10087 queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
10088}
10089
10090static void ipw_bg_link_up(void *data)
10091{
10092 struct ipw_priv *priv = data;
10093 down(&priv->sem);
10094 ipw_link_up(data);
10095 up(&priv->sem);
10096}
10097
10098void ipw_link_down(struct ipw_priv *priv)
10099{
10100 ipw_led_link_down(priv);
10101 netif_carrier_off(priv->net_dev);
10102 netif_stop_queue(priv->net_dev);
10103 notify_wx_assoc_event(priv);
10104
10105 /* Cancel any queued work ... */
10106 cancel_delayed_work(&priv->request_scan);
10107 cancel_delayed_work(&priv->adhoc_check);
10108 cancel_delayed_work(&priv->gather_stats);
10109
10110 ipw_reset_stats(priv);
10111
10112 if (!(priv->status & STATUS_EXIT_PENDING)) {
10113 /* Queue up another scan... */
10114 queue_work(priv->workqueue, &priv->request_scan);
10115 }
10116}
10117
10118static void ipw_bg_link_down(void *data)
10119{
10120 struct ipw_priv *priv = data;
10121 down(&priv->sem);
10122 ipw_link_down(data);
10123 up(&priv->sem);
10124}
10125
6658static int ipw_setup_deferred_work(struct ipw_priv *priv) 10126static int ipw_setup_deferred_work(struct ipw_priv *priv)
6659{ 10127{
6660 int ret = 0; 10128 int ret = 0;
6661 10129
6662 priv->workqueue = create_workqueue(DRV_NAME); 10130 priv->workqueue = create_workqueue(DRV_NAME);
6663 init_waitqueue_head(&priv->wait_command_queue); 10131 init_waitqueue_head(&priv->wait_command_queue);
6664 10132 init_waitqueue_head(&priv->wait_state);
6665 INIT_WORK(&priv->adhoc_check, ipw_adhoc_check, priv); 10133
6666 INIT_WORK(&priv->associate, ipw_associate, priv); 10134 INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
6667 INIT_WORK(&priv->disassociate, ipw_disassociate, priv); 10135 INIT_WORK(&priv->associate, ipw_bg_associate, priv);
6668 INIT_WORK(&priv->rx_replenish, ipw_rx_queue_replenish, priv); 10136 INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
6669 INIT_WORK(&priv->adapter_restart, ipw_adapter_restart, priv); 10137 INIT_WORK(&priv->system_config, ipw_system_config, priv);
6670 INIT_WORK(&priv->rf_kill, ipw_rf_kill, priv); 10138 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
6671 INIT_WORK(&priv->up, (void (*)(void *))ipw_up, priv); 10139 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
6672 INIT_WORK(&priv->down, (void (*)(void *))ipw_down, priv); 10140 INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
10141 INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
10142 INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
6673 INIT_WORK(&priv->request_scan, 10143 INIT_WORK(&priv->request_scan,
6674 (void (*)(void *))ipw_request_scan, priv); 10144 (void (*)(void *))ipw_request_scan, priv);
6675 INIT_WORK(&priv->gather_stats, 10145 INIT_WORK(&priv->gather_stats,
6676 (void (*)(void *))ipw_gather_stats, priv); 10146 (void (*)(void *))ipw_bg_gather_stats, priv);
6677 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv); 10147 INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
6678 INIT_WORK(&priv->roam, ipw_roam, priv); 10148 INIT_WORK(&priv->roam, ipw_bg_roam, priv);
6679 INIT_WORK(&priv->scan_check, ipw_scan_check, priv); 10149 INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
10150 INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
10151 INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
10152 INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
10153 priv);
10154 INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
10155 priv);
10156 INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
10157 priv);
10158 INIT_WORK(&priv->merge_networks,
10159 (void (*)(void *))ipw_merge_adhoc_network, priv);
10160
10161#ifdef CONFIG_IPW_QOS
10162 INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate,
10163 priv);
10164#endif /* CONFIG_IPW_QOS */
6680 10165
6681 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 10166 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6682 ipw_irq_tasklet, (unsigned long)priv); 10167 ipw_irq_tasklet, (unsigned long)priv);
@@ -6689,34 +10174,36 @@ static void shim__set_security(struct net_device *dev,
6689{ 10174{
6690 struct ipw_priv *priv = ieee80211_priv(dev); 10175 struct ipw_priv *priv = ieee80211_priv(dev);
6691 int i; 10176 int i;
6692
6693 for (i = 0; i < 4; i++) { 10177 for (i = 0; i < 4; i++) {
6694 if (sec->flags & (1 << i)) { 10178 if (sec->flags & (1 << i)) {
6695 priv->sec.key_sizes[i] = sec->key_sizes[i]; 10179 priv->ieee->sec.encode_alg[i] = sec->encode_alg[i];
10180 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
6696 if (sec->key_sizes[i] == 0) 10181 if (sec->key_sizes[i] == 0)
6697 priv->sec.flags &= ~(1 << i); 10182 priv->ieee->sec.flags &= ~(1 << i);
6698 else 10183 else {
6699 memcpy(priv->sec.keys[i], sec->keys[i], 10184 memcpy(priv->ieee->sec.keys[i], sec->keys[i],
6700 sec->key_sizes[i]); 10185 sec->key_sizes[i]);
6701 priv->sec.flags |= (1 << i); 10186 priv->ieee->sec.flags |= (1 << i);
10187 }
6702 priv->status |= STATUS_SECURITY_UPDATED; 10188 priv->status |= STATUS_SECURITY_UPDATED;
6703 } 10189 } else if (sec->level != SEC_LEVEL_1)
10190 priv->ieee->sec.flags &= ~(1 << i);
6704 } 10191 }
6705 10192
6706 if ((sec->flags & SEC_ACTIVE_KEY) && 10193 if (sec->flags & SEC_ACTIVE_KEY) {
6707 priv->sec.active_key != sec->active_key) {
6708 if (sec->active_key <= 3) { 10194 if (sec->active_key <= 3) {
6709 priv->sec.active_key = sec->active_key; 10195 priv->ieee->sec.active_key = sec->active_key;
6710 priv->sec.flags |= SEC_ACTIVE_KEY; 10196 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
6711 } else 10197 } else
6712 priv->sec.flags &= ~SEC_ACTIVE_KEY; 10198 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
6713 priv->status |= STATUS_SECURITY_UPDATED; 10199 priv->status |= STATUS_SECURITY_UPDATED;
6714 } 10200 } else
10201 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
6715 10202
6716 if ((sec->flags & SEC_AUTH_MODE) && 10203 if ((sec->flags & SEC_AUTH_MODE) &&
6717 (priv->sec.auth_mode != sec->auth_mode)) { 10204 (priv->ieee->sec.auth_mode != sec->auth_mode)) {
6718 priv->sec.auth_mode = sec->auth_mode; 10205 priv->ieee->sec.auth_mode = sec->auth_mode;
6719 priv->sec.flags |= SEC_AUTH_MODE; 10206 priv->ieee->sec.flags |= SEC_AUTH_MODE;
6720 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY) 10207 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)
6721 priv->capability |= CAP_SHARED_KEY; 10208 priv->capability |= CAP_SHARED_KEY;
6722 else 10209 else
@@ -6724,9 +10211,9 @@ static void shim__set_security(struct net_device *dev,
6724 priv->status |= STATUS_SECURITY_UPDATED; 10211 priv->status |= STATUS_SECURITY_UPDATED;
6725 } 10212 }
6726 10213
6727 if (sec->flags & SEC_ENABLED && priv->sec.enabled != sec->enabled) { 10214 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
6728 priv->sec.flags |= SEC_ENABLED; 10215 priv->ieee->sec.flags |= SEC_ENABLED;
6729 priv->sec.enabled = sec->enabled; 10216 priv->ieee->sec.enabled = sec->enabled;
6730 priv->status |= STATUS_SECURITY_UPDATED; 10217 priv->status |= STATUS_SECURITY_UPDATED;
6731 if (sec->enabled) 10218 if (sec->enabled)
6732 priv->capability |= CAP_PRIVACY_ON; 10219 priv->capability |= CAP_PRIVACY_ON;
@@ -6734,12 +10221,18 @@ static void shim__set_security(struct net_device *dev,
6734 priv->capability &= ~CAP_PRIVACY_ON; 10221 priv->capability &= ~CAP_PRIVACY_ON;
6735 } 10222 }
6736 10223
6737 if (sec->flags & SEC_LEVEL && priv->sec.level != sec->level) { 10224 if (sec->flags & SEC_ENCRYPT)
6738 priv->sec.level = sec->level; 10225 priv->ieee->sec.encrypt = sec->encrypt;
6739 priv->sec.flags |= SEC_LEVEL; 10226
10227 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
10228 priv->ieee->sec.level = sec->level;
10229 priv->ieee->sec.flags |= SEC_LEVEL;
6740 priv->status |= STATUS_SECURITY_UPDATED; 10230 priv->status |= STATUS_SECURITY_UPDATED;
6741 } 10231 }
6742 10232
10233 if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
10234 ipw_set_hwcrypto_keys(priv);
10235
6743 /* To match current functionality of ipw2100 (which works well w/ 10236 /* To match current functionality of ipw2100 (which works well w/
6744 * various supplicants, we don't force a disassociate if the 10237 * various supplicants, we don't force a disassociate if the
6745 * privacy capability changes ... */ 10238 * privacy capability changes ... */
@@ -6788,29 +10281,10 @@ static int init_supported_rates(struct ipw_priv *priv,
6788 10281
6789static int ipw_config(struct ipw_priv *priv) 10282static int ipw_config(struct ipw_priv *priv)
6790{ 10283{
6791 int i;
6792 struct ipw_tx_power tx_power;
6793
6794 memset(&priv->sys_config, 0, sizeof(priv->sys_config));
6795 memset(&tx_power, 0, sizeof(tx_power));
6796
6797 /* This is only called from ipw_up, which resets/reloads the firmware 10284 /* This is only called from ipw_up, which resets/reloads the firmware
6798 so, we don't need to first disable the card before we configure 10285 so, we don't need to first disable the card before we configure
6799 it */ 10286 it */
6800 10287 if (ipw_set_tx_power(priv))
6801 /* configure device for 'G' band */
6802 tx_power.ieee_mode = IPW_G_MODE;
6803 tx_power.num_channels = 11;
6804 for (i = 0; i < 11; i++) {
6805 tx_power.channels_tx_power[i].channel_number = i + 1;
6806 tx_power.channels_tx_power[i].tx_power = priv->tx_power;
6807 }
6808 if (ipw_send_tx_power(priv, &tx_power))
6809 goto error;
6810
6811 /* configure device to also handle 'B' band */
6812 tx_power.ieee_mode = IPW_B_MODE;
6813 if (ipw_send_tx_power(priv, &tx_power))
6814 goto error; 10288 goto error;
6815 10289
6816 /* initialize adapter address */ 10290 /* initialize adapter address */
@@ -6819,6 +10293,11 @@ static int ipw_config(struct ipw_priv *priv)
6819 10293
6820 /* set basic system config settings */ 10294 /* set basic system config settings */
6821 init_sys_config(&priv->sys_config); 10295 init_sys_config(&priv->sys_config);
10296 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10297 priv->sys_config.answer_broadcast_ssid_probe = 1;
10298 else
10299 priv->sys_config.answer_broadcast_ssid_probe = 0;
10300
6822 if (ipw_send_system_config(priv, &priv->sys_config)) 10301 if (ipw_send_system_config(priv, &priv->sys_config))
6823 goto error; 10302 goto error;
6824 10303
@@ -6831,6 +10310,10 @@ static int ipw_config(struct ipw_priv *priv)
6831 if (ipw_send_rts_threshold(priv, priv->rts_threshold)) 10310 if (ipw_send_rts_threshold(priv, priv->rts_threshold))
6832 goto error; 10311 goto error;
6833 } 10312 }
10313#ifdef CONFIG_IPW_QOS
10314 IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");
10315 ipw_qos_activate(priv, NULL);
10316#endif /* CONFIG_IPW_QOS */
6834 10317
6835 if (ipw_set_random_seed(priv)) 10318 if (ipw_set_random_seed(priv))
6836 goto error; 10319 goto error;
@@ -6839,9 +10322,17 @@ static int ipw_config(struct ipw_priv *priv)
6839 if (ipw_send_host_complete(priv)) 10322 if (ipw_send_host_complete(priv))
6840 goto error; 10323 goto error;
6841 10324
6842 /* If configured to try and auto-associate, kick off a scan */ 10325 priv->status |= STATUS_INIT;
6843 if ((priv->config & CFG_ASSOCIATE) && ipw_request_scan(priv)) 10326
6844 goto error; 10327 ipw_led_init(priv);
10328 ipw_led_radio_on(priv);
10329 priv->notif_missed_beacons = 0;
10330
10331 /* Set hardware WEP key if it is configured. */
10332 if ((priv->capability & CAP_PRIVACY_ON) &&
10333 (priv->ieee->sec.level == SEC_LEVEL_1) &&
10334 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
10335 ipw_set_hwcrypto_keys(priv);
6845 10336
6846 return 0; 10337 return 0;
6847 10338
@@ -6849,20 +10340,379 @@ static int ipw_config(struct ipw_priv *priv)
6849 return -EIO; 10340 return -EIO;
6850} 10341}
6851 10342
10343/*
10344 * NOTE:
10345 *
10346 * These tables have been tested in conjunction with the
10347 * Intel PRO/Wireless 2200BG and 2915ABG Network Connection Adapters.
10348 *
10349 * Altering this values, using it on other hardware, or in geographies
10350 * not intended for resale of the above mentioned Intel adapters has
10351 * not been tested.
10352 *
10353 */
10354static const struct ieee80211_geo ipw_geos[] = {
10355 { /* Restricted */
10356 "---",
10357 .bg_channels = 11,
10358 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10359 {2427, 4}, {2432, 5}, {2437, 6},
10360 {2442, 7}, {2447, 8}, {2452, 9},
10361 {2457, 10}, {2462, 11}},
10362 },
10363
10364 { /* Custom US/Canada */
10365 "ZZF",
10366 .bg_channels = 11,
10367 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10368 {2427, 4}, {2432, 5}, {2437, 6},
10369 {2442, 7}, {2447, 8}, {2452, 9},
10370 {2457, 10}, {2462, 11}},
10371 .a_channels = 8,
10372 .a = {{5180, 36},
10373 {5200, 40},
10374 {5220, 44},
10375 {5240, 48},
10376 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10377 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10378 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10379 {5320, 64, IEEE80211_CH_PASSIVE_ONLY}},
10380 },
10381
10382 { /* Rest of World */
10383 "ZZD",
10384 .bg_channels = 13,
10385 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10386 {2427, 4}, {2432, 5}, {2437, 6},
10387 {2442, 7}, {2447, 8}, {2452, 9},
10388 {2457, 10}, {2462, 11}, {2467, 12},
10389 {2472, 13}},
10390 },
10391
10392 { /* Custom USA & Europe & High */
10393 "ZZA",
10394 .bg_channels = 11,
10395 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10396 {2427, 4}, {2432, 5}, {2437, 6},
10397 {2442, 7}, {2447, 8}, {2452, 9},
10398 {2457, 10}, {2462, 11}},
10399 .a_channels = 13,
10400 .a = {{5180, 36},
10401 {5200, 40},
10402 {5220, 44},
10403 {5240, 48},
10404 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10405 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10406 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10407 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10408 {5745, 149},
10409 {5765, 153},
10410 {5785, 157},
10411 {5805, 161},
10412 {5825, 165}},
10413 },
10414
10415 { /* Custom NA & Europe */
10416 "ZZB",
10417 .bg_channels = 11,
10418 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10419 {2427, 4}, {2432, 5}, {2437, 6},
10420 {2442, 7}, {2447, 8}, {2452, 9},
10421 {2457, 10}, {2462, 11}},
10422 .a_channels = 13,
10423 .a = {{5180, 36},
10424 {5200, 40},
10425 {5220, 44},
10426 {5240, 48},
10427 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10428 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10429 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10430 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10431 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10432 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10433 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10434 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10435 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10436 },
10437
10438 { /* Custom Japan */
10439 "ZZC",
10440 .bg_channels = 11,
10441 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10442 {2427, 4}, {2432, 5}, {2437, 6},
10443 {2442, 7}, {2447, 8}, {2452, 9},
10444 {2457, 10}, {2462, 11}},
10445 .a_channels = 4,
10446 .a = {{5170, 34}, {5190, 38},
10447 {5210, 42}, {5230, 46}},
10448 },
10449
10450 { /* Custom */
10451 "ZZM",
10452 .bg_channels = 11,
10453 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10454 {2427, 4}, {2432, 5}, {2437, 6},
10455 {2442, 7}, {2447, 8}, {2452, 9},
10456 {2457, 10}, {2462, 11}},
10457 },
10458
10459 { /* Europe */
10460 "ZZE",
10461 .bg_channels = 13,
10462 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10463 {2427, 4}, {2432, 5}, {2437, 6},
10464 {2442, 7}, {2447, 8}, {2452, 9},
10465 {2457, 10}, {2462, 11}, {2467, 12},
10466 {2472, 13}},
10467 .a_channels = 19,
10468 .a = {{5180, 36},
10469 {5200, 40},
10470 {5220, 44},
10471 {5240, 48},
10472 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10473 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10474 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10475 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10476 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10477 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10478 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10479 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10480 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10481 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10482 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10483 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10484 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10485 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10486 {5700, 140, IEEE80211_CH_PASSIVE_ONLY}},
10487 },
10488
10489 { /* Custom Japan */
10490 "ZZJ",
10491 .bg_channels = 14,
10492 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10493 {2427, 4}, {2432, 5}, {2437, 6},
10494 {2442, 7}, {2447, 8}, {2452, 9},
10495 {2457, 10}, {2462, 11}, {2467, 12},
10496 {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY}},
10497 .a_channels = 4,
10498 .a = {{5170, 34}, {5190, 38},
10499 {5210, 42}, {5230, 46}},
10500 },
10501
10502 { /* Rest of World */
10503 "ZZR",
10504 .bg_channels = 14,
10505 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10506 {2427, 4}, {2432, 5}, {2437, 6},
10507 {2442, 7}, {2447, 8}, {2452, 9},
10508 {2457, 10}, {2462, 11}, {2467, 12},
10509 {2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY |
10510 IEEE80211_CH_PASSIVE_ONLY}},
10511 },
10512
10513 { /* High Band */
10514 "ZZH",
10515 .bg_channels = 13,
10516 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10517 {2427, 4}, {2432, 5}, {2437, 6},
10518 {2442, 7}, {2447, 8}, {2452, 9},
10519 {2457, 10}, {2462, 11},
10520 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10521 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10522 .a_channels = 4,
10523 .a = {{5745, 149}, {5765, 153},
10524 {5785, 157}, {5805, 161}},
10525 },
10526
10527 { /* Custom Europe */
10528 "ZZG",
10529 .bg_channels = 13,
10530 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10531 {2427, 4}, {2432, 5}, {2437, 6},
10532 {2442, 7}, {2447, 8}, {2452, 9},
10533 {2457, 10}, {2462, 11},
10534 {2467, 12}, {2472, 13}},
10535 .a_channels = 4,
10536 .a = {{5180, 36}, {5200, 40},
10537 {5220, 44}, {5240, 48}},
10538 },
10539
10540 { /* Europe */
10541 "ZZK",
10542 .bg_channels = 13,
10543 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10544 {2427, 4}, {2432, 5}, {2437, 6},
10545 {2442, 7}, {2447, 8}, {2452, 9},
10546 {2457, 10}, {2462, 11},
10547 {2467, 12, IEEE80211_CH_PASSIVE_ONLY},
10548 {2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
10549 .a_channels = 24,
10550 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10551 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10552 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10553 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10554 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10555 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10556 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10557 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10558 {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
10559 {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
10560 {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
10561 {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
10562 {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
10563 {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
10564 {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
10565 {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
10566 {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
10567 {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
10568 {5700, 140, IEEE80211_CH_PASSIVE_ONLY},
10569 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10570 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10571 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10572 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10573 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10574 },
10575
10576 { /* Europe */
10577 "ZZL",
10578 .bg_channels = 11,
10579 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
10580 {2427, 4}, {2432, 5}, {2437, 6},
10581 {2442, 7}, {2447, 8}, {2452, 9},
10582 {2457, 10}, {2462, 11}},
10583 .a_channels = 13,
10584 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
10585 {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
10586 {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
10587 {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
10588 {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
10589 {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
10590 {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
10591 {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
10592 {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
10593 {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
10594 {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
10595 {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
10596 {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
10597 }
10598};
10599
10600/* GEO code borrowed from ieee80211_geo.c */
10601static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
10602{
10603 int i;
10604
10605 /* Driver needs to initialize the geography map before using
10606 * these helper functions */
10607 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10608
10609 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10610 for (i = 0; i < ieee->geo.bg_channels; i++)
10611 /* NOTE: If G mode is currently supported but
10612 * this is a B only channel, we don't see it
10613 * as valid. */
10614 if ((ieee->geo.bg[i].channel == channel) &&
10615 (!(ieee->mode & IEEE_G) ||
10616 !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
10617 return IEEE80211_24GHZ_BAND;
10618
10619 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10620 for (i = 0; i < ieee->geo.a_channels; i++)
10621 if (ieee->geo.a[i].channel == channel)
10622 return IEEE80211_52GHZ_BAND;
10623
10624 return 0;
10625}
10626
10627static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
10628{
10629 int i;
10630
10631 /* Driver needs to initialize the geography map before using
10632 * these helper functions */
10633 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10634
10635 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10636 for (i = 0; i < ieee->geo.bg_channels; i++)
10637 if (ieee->geo.bg[i].channel == channel)
10638 return i;
10639
10640 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10641 for (i = 0; i < ieee->geo.a_channels; i++)
10642 if (ieee->geo.a[i].channel == channel)
10643 return i;
10644
10645 return -1;
10646}
10647
10648static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
10649{
10650 int i;
10651
10652 /* Driver needs to initialize the geography map before using
10653 * these helper functions */
10654 BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
10655
10656 freq /= 100000;
10657
10658 if (ieee->freq_band & IEEE80211_24GHZ_BAND)
10659 for (i = 0; i < ieee->geo.bg_channels; i++)
10660 if (ieee->geo.bg[i].freq == freq)
10661 return ieee->geo.bg[i].channel;
10662
10663 if (ieee->freq_band & IEEE80211_52GHZ_BAND)
10664 for (i = 0; i < ieee->geo.a_channels; i++)
10665 if (ieee->geo.a[i].freq == freq)
10666 return ieee->geo.a[i].channel;
10667
10668 return 0;
10669}
10670
10671static int ipw_set_geo(struct ieee80211_device *ieee,
10672 const struct ieee80211_geo *geo)
10673{
10674 memcpy(ieee->geo.name, geo->name, 3);
10675 ieee->geo.name[3] = '\0';
10676 ieee->geo.bg_channels = geo->bg_channels;
10677 ieee->geo.a_channels = geo->a_channels;
10678 memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
10679 sizeof(struct ieee80211_channel));
10680 memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
10681 sizeof(struct ieee80211_channel));
10682 return 0;
10683}
10684
10685static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
10686{
10687 return &ieee->geo;
10688}
10689
6852#define MAX_HW_RESTARTS 5 10690#define MAX_HW_RESTARTS 5
6853static int ipw_up(struct ipw_priv *priv) 10691static int ipw_up(struct ipw_priv *priv)
6854{ 10692{
6855 int rc, i; 10693 int rc, i, j;
6856 10694
6857 if (priv->status & STATUS_EXIT_PENDING) 10695 if (priv->status & STATUS_EXIT_PENDING)
6858 return -EIO; 10696 return -EIO;
6859 10697
10698 if (cmdlog && !priv->cmdlog) {
10699 priv->cmdlog = kmalloc(sizeof(*priv->cmdlog) * cmdlog,
10700 GFP_KERNEL);
10701 if (priv->cmdlog == NULL) {
10702 IPW_ERROR("Error allocating %d command log entries.\n",
10703 cmdlog);
10704 } else {
10705 memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
10706 priv->cmdlog_len = cmdlog;
10707 }
10708 }
10709
6860 for (i = 0; i < MAX_HW_RESTARTS; i++) { 10710 for (i = 0; i < MAX_HW_RESTARTS; i++) {
6861 /* Load the microcode, firmware, and eeprom. 10711 /* Load the microcode, firmware, and eeprom.
6862 * Also start the clocks. */ 10712 * Also start the clocks. */
6863 rc = ipw_load(priv); 10713 rc = ipw_load(priv);
6864 if (rc) { 10714 if (rc) {
6865 IPW_ERROR("Unable to load firmware: 0x%08X\n", rc); 10715 IPW_ERROR("Unable to load firmware: %d\n", rc);
6866 return rc; 10716 return rc;
6867 } 10717 }
6868 10718
@@ -6871,20 +10721,50 @@ static int ipw_up(struct ipw_priv *priv)
6871 eeprom_parse_mac(priv, priv->mac_addr); 10721 eeprom_parse_mac(priv, priv->mac_addr);
6872 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 10722 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
6873 10723
6874 if (priv->status & STATUS_RF_KILL_MASK) 10724 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
10725 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
10726 ipw_geos[j].name, 3))
10727 break;
10728 }
10729 if (j == ARRAY_SIZE(ipw_geos)) {
10730 IPW_WARNING("SKU [%c%c%c] not recognized.\n",
10731 priv->eeprom[EEPROM_COUNTRY_CODE + 0],
10732 priv->eeprom[EEPROM_COUNTRY_CODE + 1],
10733 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
10734 j = 0;
10735 }
10736 if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
10737 IPW_WARNING("Could not set geography.");
10738 return 0;
10739 }
10740
10741 IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
10742 j, priv->ieee->geo.name);
10743
10744 if (priv->status & STATUS_RF_KILL_SW) {
10745 IPW_WARNING("Radio disabled by module parameter.\n");
10746 return 0;
10747 } else if (rf_kill_active(priv)) {
10748 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
10749 "Kill switch must be turned off for "
10750 "wireless networking to work.\n");
10751 queue_delayed_work(priv->workqueue, &priv->rf_kill,
10752 2 * HZ);
6875 return 0; 10753 return 0;
10754 }
6876 10755
6877 rc = ipw_config(priv); 10756 rc = ipw_config(priv);
6878 if (!rc) { 10757 if (!rc) {
6879 IPW_DEBUG_INFO("Configured device on count %i\n", i); 10758 IPW_DEBUG_INFO("Configured device on count %i\n", i);
6880 priv->notif_missed_beacons = 0; 10759
6881 netif_start_queue(priv->net_dev); 10760 /* If configure to try and auto-associate, kick
10761 * off a scan. */
10762 queue_work(priv->workqueue, &priv->request_scan);
10763
6882 return 0; 10764 return 0;
6883 } else {
6884 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n",
6885 rc);
6886 } 10765 }
6887 10766
10767 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
6888 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n", 10768 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
6889 i, MAX_HW_RESTARTS); 10769 i, MAX_HW_RESTARTS);
6890 10770
@@ -6896,47 +10776,101 @@ static int ipw_up(struct ipw_priv *priv)
6896 /* tried to restart and config the device for as long as our 10776 /* tried to restart and config the device for as long as our
6897 * patience could withstand */ 10777 * patience could withstand */
6898 IPW_ERROR("Unable to initialize device after %d attempts.\n", i); 10778 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
10779
6899 return -EIO; 10780 return -EIO;
6900} 10781}
6901 10782
6902static void ipw_down(struct ipw_priv *priv) 10783static void ipw_bg_up(void *data)
10784{
10785 struct ipw_priv *priv = data;
10786 down(&priv->sem);
10787 ipw_up(data);
10788 up(&priv->sem);
10789}
10790
10791static void ipw_deinit(struct ipw_priv *priv)
6903{ 10792{
10793 int i;
10794
10795 if (priv->status & STATUS_SCANNING) {
10796 IPW_DEBUG_INFO("Aborting scan during shutdown.\n");
10797 ipw_abort_scan(priv);
10798 }
10799
10800 if (priv->status & STATUS_ASSOCIATED) {
10801 IPW_DEBUG_INFO("Disassociating during shutdown.\n");
10802 ipw_disassociate(priv);
10803 }
10804
10805 ipw_led_shutdown(priv);
10806
10807 /* Wait up to 1s for status to change to not scanning and not
10808 * associated (disassociation can take a while for a ful 802.11
10809 * exchange */
10810 for (i = 1000; i && (priv->status &
10811 (STATUS_DISASSOCIATING |
10812 STATUS_ASSOCIATED | STATUS_SCANNING)); i--)
10813 udelay(10);
10814
10815 if (priv->status & (STATUS_DISASSOCIATING |
10816 STATUS_ASSOCIATED | STATUS_SCANNING))
10817 IPW_DEBUG_INFO("Still associated or scanning...\n");
10818 else
10819 IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);
10820
6904 /* Attempt to disable the card */ 10821 /* Attempt to disable the card */
6905#if 0
6906 ipw_send_card_disable(priv, 0); 10822 ipw_send_card_disable(priv, 0);
6907#endif 10823
10824 priv->status &= ~STATUS_INIT;
10825}
10826
10827static void ipw_down(struct ipw_priv *priv)
10828{
10829 int exit_pending = priv->status & STATUS_EXIT_PENDING;
10830
10831 priv->status |= STATUS_EXIT_PENDING;
10832
10833 if (ipw_is_init(priv))
10834 ipw_deinit(priv);
10835
10836 /* Wipe out the EXIT_PENDING status bit if we are not actually
10837 * exiting the module */
10838 if (!exit_pending)
10839 priv->status &= ~STATUS_EXIT_PENDING;
6908 10840
6909 /* tell the device to stop sending interrupts */ 10841 /* tell the device to stop sending interrupts */
6910 ipw_disable_interrupts(priv); 10842 ipw_disable_interrupts(priv);
6911 10843
6912 /* Clear all bits but the RF Kill */ 10844 /* Clear all bits but the RF Kill */
6913 priv->status &= STATUS_RF_KILL_MASK; 10845 priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;
6914
6915 netif_carrier_off(priv->net_dev); 10846 netif_carrier_off(priv->net_dev);
6916 netif_stop_queue(priv->net_dev); 10847 netif_stop_queue(priv->net_dev);
6917 10848
6918 ipw_stop_nic(priv); 10849 ipw_stop_nic(priv);
10850
10851 ipw_led_radio_off(priv);
10852}
10853
10854static void ipw_bg_down(void *data)
10855{
10856 struct ipw_priv *priv = data;
10857 down(&priv->sem);
10858 ipw_down(data);
10859 up(&priv->sem);
6919} 10860}
6920 10861
6921/* Called by register_netdev() */ 10862/* Called by register_netdev() */
6922static int ipw_net_init(struct net_device *dev) 10863static int ipw_net_init(struct net_device *dev)
6923{ 10864{
6924 struct ipw_priv *priv = ieee80211_priv(dev); 10865 struct ipw_priv *priv = ieee80211_priv(dev);
10866 down(&priv->sem);
6925 10867
6926 if (priv->status & STATUS_RF_KILL_SW) { 10868 if (ipw_up(priv)) {
6927 IPW_WARNING("Radio disabled by module parameter.\n"); 10869 up(&priv->sem);
6928 return 0;
6929 } else if (rf_kill_active(priv)) {
6930 IPW_WARNING("Radio Frequency Kill Switch is On:\n"
6931 "Kill switch must be turned off for "
6932 "wireless networking to work.\n");
6933 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
6934 return 0;
6935 }
6936
6937 if (ipw_up(priv))
6938 return -EIO; 10870 return -EIO;
10871 }
6939 10872
10873 up(&priv->sem);
6940 return 0; 10874 return 0;
6941} 10875}
6942 10876
@@ -6961,7 +10895,7 @@ static struct pci_device_id card_ids[] = {
6961 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0}, 10895 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
6962 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 10896 {PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
6963 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */ 10897 {PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
6964 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 2225BG */ 10898 {PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* BG */
6965 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 10899 {PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6966 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */ 10900 {PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* ABG */
6967 10901
@@ -6981,11 +10915,16 @@ static struct attribute *ipw_sysfs_entries[] = {
6981 &dev_attr_nic_type.attr, 10915 &dev_attr_nic_type.attr,
6982 &dev_attr_status.attr, 10916 &dev_attr_status.attr,
6983 &dev_attr_cfg.attr, 10917 &dev_attr_cfg.attr,
6984 &dev_attr_dump_errors.attr, 10918 &dev_attr_error.attr,
6985 &dev_attr_dump_events.attr, 10919 &dev_attr_event_log.attr,
10920 &dev_attr_cmd_log.attr,
6986 &dev_attr_eeprom_delay.attr, 10921 &dev_attr_eeprom_delay.attr,
6987 &dev_attr_ucode_version.attr, 10922 &dev_attr_ucode_version.attr,
6988 &dev_attr_rtc.attr, 10923 &dev_attr_rtc.attr,
10924 &dev_attr_scan_age.attr,
10925 &dev_attr_led.attr,
10926 &dev_attr_speed_scan.attr,
10927 &dev_attr_net_stats.attr,
6989 NULL 10928 NULL
6990}; 10929};
6991 10930
@@ -7001,7 +10940,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7001 void __iomem *base; 10940 void __iomem *base;
7002 u32 length, val; 10941 u32 length, val;
7003 struct ipw_priv *priv; 10942 struct ipw_priv *priv;
7004 int band, modulation; 10943 int i;
7005 10944
7006 net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); 10945 net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
7007 if (net_dev == NULL) { 10946 if (net_dev == NULL) {
@@ -7011,13 +10950,17 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7011 10950
7012 priv = ieee80211_priv(net_dev); 10951 priv = ieee80211_priv(net_dev);
7013 priv->ieee = netdev_priv(net_dev); 10952 priv->ieee = netdev_priv(net_dev);
10953
7014 priv->net_dev = net_dev; 10954 priv->net_dev = net_dev;
7015 priv->pci_dev = pdev; 10955 priv->pci_dev = pdev;
7016#ifdef CONFIG_IPW_DEBUG 10956#ifdef CONFIG_IPW_DEBUG
7017 ipw_debug_level = debug; 10957 ipw_debug_level = debug;
7018#endif 10958#endif
7019 spin_lock_init(&priv->lock); 10959 spin_lock_init(&priv->lock);
10960 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
10961 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
7020 10962
10963 init_MUTEX(&priv->sem);
7021 if (pci_enable_device(pdev)) { 10964 if (pci_enable_device(pdev)) {
7022 err = -ENODEV; 10965 err = -ENODEV;
7023 goto out_free_ieee80211; 10966 goto out_free_ieee80211;
@@ -7064,90 +11007,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7064 goto out_iounmap; 11007 goto out_iounmap;
7065 } 11008 }
7066 11009
7067 /* Initialize module parameter values here */ 11010 ipw_sw_reset(priv, 1);
7068 if (ifname)
7069 strncpy(net_dev->name, ifname, IFNAMSIZ);
7070
7071 if (associate)
7072 priv->config |= CFG_ASSOCIATE;
7073 else
7074 IPW_DEBUG_INFO("Auto associate disabled.\n");
7075
7076 if (auto_create)
7077 priv->config |= CFG_ADHOC_CREATE;
7078 else
7079 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");
7080
7081 if (disable) {
7082 priv->status |= STATUS_RF_KILL_SW;
7083 IPW_DEBUG_INFO("Radio disabled.\n");
7084 }
7085
7086 if (channel != 0) {
7087 priv->config |= CFG_STATIC_CHANNEL;
7088 priv->channel = channel;
7089 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7090 IPW_DEBUG_INFO("Bind to static channel %d\n", channel);
7091 /* TODO: Validate that provided channel is in range */
7092 }
7093
7094 switch (mode) {
7095 case 1:
7096 priv->ieee->iw_mode = IW_MODE_ADHOC;
7097 break;
7098#ifdef CONFIG_IPW_PROMISC
7099 case 2:
7100 priv->ieee->iw_mode = IW_MODE_MONITOR;
7101 break;
7102#endif
7103 default:
7104 case 0:
7105 priv->ieee->iw_mode = IW_MODE_INFRA;
7106 break;
7107 }
7108
7109 if ((priv->pci_dev->device == 0x4223) ||
7110 (priv->pci_dev->device == 0x4224)) {
7111 printk(KERN_INFO DRV_NAME
7112 ": Detected Intel PRO/Wireless 2915ABG Network "
7113 "Connection\n");
7114 priv->ieee->abg_true = 1;
7115 band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
7116 modulation = IEEE80211_OFDM_MODULATION |
7117 IEEE80211_CCK_MODULATION;
7118 priv->adapter = IPW_2915ABG;
7119 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
7120 } else {
7121 if (priv->pci_dev->device == 0x4221)
7122 printk(KERN_INFO DRV_NAME
7123 ": Detected Intel PRO/Wireless 2225BG Network "
7124 "Connection\n");
7125 else
7126 printk(KERN_INFO DRV_NAME
7127 ": Detected Intel PRO/Wireless 2200BG Network "
7128 "Connection\n");
7129
7130 priv->ieee->abg_true = 0;
7131 band = IEEE80211_24GHZ_BAND;
7132 modulation = IEEE80211_OFDM_MODULATION |
7133 IEEE80211_CCK_MODULATION;
7134 priv->adapter = IPW_2200BG;
7135 priv->ieee->mode = IEEE_G | IEEE_B;
7136 }
7137
7138 priv->ieee->freq_band = band;
7139 priv->ieee->modulation = modulation;
7140
7141 priv->rates_mask = IEEE80211_DEFAULT_RATES_MASK;
7142
7143 priv->missed_beacon_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;
7144 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;
7145
7146 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
7147
7148 /* If power management is turned on, default to AC mode */
7149 priv->power_mode = IPW_POWER_AC;
7150 priv->tx_power = IPW_DEFAULT_TX_POWER;
7151 11011
7152 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv); 11012 err = request_irq(pdev->irq, ipw_isr, SA_SHIRQ, DRV_NAME, priv);
7153 if (err) { 11013 if (err) {
@@ -7158,8 +11018,20 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7158 SET_MODULE_OWNER(net_dev); 11018 SET_MODULE_OWNER(net_dev);
7159 SET_NETDEV_DEV(net_dev, &pdev->dev); 11019 SET_NETDEV_DEV(net_dev, &pdev->dev);
7160 11020
11021 down(&priv->sem);
11022
7161 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; 11023 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
7162 priv->ieee->set_security = shim__set_security; 11024 priv->ieee->set_security = shim__set_security;
11025 priv->ieee->is_queue_full = ipw_net_is_queue_full;
11026
11027#ifdef CONFIG_IPW_QOS
11028 priv->ieee->handle_probe_response = ipw_handle_beacon;
11029 priv->ieee->handle_beacon = ipw_handle_probe_response;
11030 priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
11031#endif /* CONFIG_IPW_QOS */
11032
11033 priv->ieee->perfect_rssi = -20;
11034 priv->ieee->worst_rssi = -85;
7163 11035
7164 net_dev->open = ipw_net_open; 11036 net_dev->open = ipw_net_open;
7165 net_dev->stop = ipw_net_stop; 11037 net_dev->stop = ipw_net_stop;
@@ -7167,7 +11039,9 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7167 net_dev->get_stats = ipw_net_get_stats; 11039 net_dev->get_stats = ipw_net_get_stats;
7168 net_dev->set_multicast_list = ipw_net_set_multicast_list; 11040 net_dev->set_multicast_list = ipw_net_set_multicast_list;
7169 net_dev->set_mac_address = ipw_net_set_mac_address; 11041 net_dev->set_mac_address = ipw_net_set_mac_address;
7170 net_dev->get_wireless_stats = ipw_get_wireless_stats; 11042 priv->wireless_data.spy_data = &priv->ieee->spy_data;
11043 priv->wireless_data.ieee80211 = priv->ieee;
11044 net_dev->wireless_data = &priv->wireless_data;
7171 net_dev->wireless_handlers = &ipw_wx_handler_def; 11045 net_dev->wireless_handlers = &ipw_wx_handler_def;
7172 net_dev->ethtool_ops = &ipw_ethtool_ops; 11046 net_dev->ethtool_ops = &ipw_ethtool_ops;
7173 net_dev->irq = pdev->irq; 11047 net_dev->irq = pdev->irq;
@@ -7178,18 +11052,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7178 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group); 11052 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
7179 if (err) { 11053 if (err) {
7180 IPW_ERROR("failed to create sysfs device attributes\n"); 11054 IPW_ERROR("failed to create sysfs device attributes\n");
11055 up(&priv->sem);
7181 goto out_release_irq; 11056 goto out_release_irq;
7182 } 11057 }
7183 11058
11059 up(&priv->sem);
7184 err = register_netdev(net_dev); 11060 err = register_netdev(net_dev);
7185 if (err) { 11061 if (err) {
7186 IPW_ERROR("failed to register network device\n"); 11062 IPW_ERROR("failed to register network device\n");
7187 goto out_remove_group; 11063 goto out_remove_sysfs;
7188 } 11064 }
7189
7190 return 0; 11065 return 0;
7191 11066
7192 out_remove_group: 11067 out_remove_sysfs:
7193 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11068 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7194 out_release_irq: 11069 out_release_irq:
7195 free_irq(pdev->irq, priv); 11070 free_irq(pdev->irq, priv);
@@ -7212,14 +11087,19 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7212static void ipw_pci_remove(struct pci_dev *pdev) 11087static void ipw_pci_remove(struct pci_dev *pdev)
7213{ 11088{
7214 struct ipw_priv *priv = pci_get_drvdata(pdev); 11089 struct ipw_priv *priv = pci_get_drvdata(pdev);
11090 struct list_head *p, *q;
11091 int i;
11092
7215 if (!priv) 11093 if (!priv)
7216 return; 11094 return;
7217 11095
7218 priv->status |= STATUS_EXIT_PENDING; 11096 down(&priv->sem);
7219 11097
11098 priv->status |= STATUS_EXIT_PENDING;
11099 ipw_down(priv);
7220 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11100 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
7221 11101
7222 ipw_down(priv); 11102 up(&priv->sem);
7223 11103
7224 unregister_netdev(priv->net_dev); 11104 unregister_netdev(priv->net_dev);
7225 11105
@@ -7229,16 +11109,31 @@ static void ipw_pci_remove(struct pci_dev *pdev)
7229 } 11109 }
7230 ipw_tx_queue_free(priv); 11110 ipw_tx_queue_free(priv);
7231 11111
11112 if (priv->cmdlog) {
11113 kfree(priv->cmdlog);
11114 priv->cmdlog = NULL;
11115 }
7232 /* ipw_down will ensure that there is no more pending work 11116 /* ipw_down will ensure that there is no more pending work
7233 * in the workqueue's, so we can safely remove them now. */ 11117 * in the workqueue's, so we can safely remove them now. */
7234 if (priv->workqueue) { 11118 cancel_delayed_work(&priv->adhoc_check);
7235 cancel_delayed_work(&priv->adhoc_check); 11119 cancel_delayed_work(&priv->gather_stats);
7236 cancel_delayed_work(&priv->gather_stats); 11120 cancel_delayed_work(&priv->request_scan);
7237 cancel_delayed_work(&priv->request_scan); 11121 cancel_delayed_work(&priv->rf_kill);
7238 cancel_delayed_work(&priv->rf_kill); 11122 cancel_delayed_work(&priv->scan_check);
7239 cancel_delayed_work(&priv->scan_check); 11123 destroy_workqueue(priv->workqueue);
7240 destroy_workqueue(priv->workqueue); 11124 priv->workqueue = NULL;
7241 priv->workqueue = NULL; 11125
11126 /* Free MAC hash list for ADHOC */
11127 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
11128 list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
11129 kfree(list_entry(p, struct ipw_ibss_seq, list));
11130 list_del(p);
11131 }
11132 }
11133
11134 if (priv->error) {
11135 ipw_free_error_log(priv->error);
11136 priv->error = NULL;
7242 } 11137 }
7243 11138
7244 free_irq(pdev->irq, priv); 11139 free_irq(pdev->irq, priv);
@@ -7247,15 +11142,7 @@ static void ipw_pci_remove(struct pci_dev *pdev)
7247 pci_disable_device(pdev); 11142 pci_disable_device(pdev);
7248 pci_set_drvdata(pdev, NULL); 11143 pci_set_drvdata(pdev, NULL);
7249 free_ieee80211(priv->net_dev); 11144 free_ieee80211(priv->net_dev);
7250 11145 free_firmware();
7251#ifdef CONFIG_PM
7252 if (fw_loaded) {
7253 release_firmware(bootfw);
7254 release_firmware(ucode);
7255 release_firmware(firmware);
7256 fw_loaded = 0;
7257 }
7258#endif
7259} 11146}
7260 11147
7261#ifdef CONFIG_PM 11148#ifdef CONFIG_PM
@@ -7287,13 +11174,10 @@ static int ipw_pci_resume(struct pci_dev *pdev)
7287 11174
7288 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name); 11175 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
7289 11176
7290 pci_set_power_state(pdev, 0); 11177 pci_set_power_state(pdev, PCI_D0);
7291 pci_enable_device(pdev); 11178 pci_enable_device(pdev);
7292#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
7293 pci_restore_state(pdev, priv->pm_state);
7294#else
7295 pci_restore_state(pdev); 11179 pci_restore_state(pdev);
7296#endif 11180
7297 /* 11181 /*
7298 * Suspend/Resume resets the PCI configuration space, so we have to 11182 * Suspend/Resume resets the PCI configuration space, so we have to
7299 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries 11183 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -7365,16 +11249,33 @@ MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
7365module_param(auto_create, int, 0444); 11249module_param(auto_create, int, 0444);
7366MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); 11250MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
7367 11251
11252module_param(led, int, 0444);
11253MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
11254
7368module_param(debug, int, 0444); 11255module_param(debug, int, 0444);
7369MODULE_PARM_DESC(debug, "debug output mask"); 11256MODULE_PARM_DESC(debug, "debug output mask");
7370 11257
7371module_param(channel, int, 0444); 11258module_param(channel, int, 0444);
7372MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11259MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
7373 11260
7374module_param(ifname, charp, 0444); 11261#ifdef CONFIG_IPW_QOS
7375MODULE_PARM_DESC(ifname, "network device name (default eth%d)"); 11262module_param(qos_enable, int, 0444);
11263MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
11264
11265module_param(qos_burst_enable, int, 0444);
11266MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");
11267
11268module_param(qos_no_ack_mask, int, 0444);
11269MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");
7376 11270
7377#ifdef CONFIG_IPW_PROMISC 11271module_param(burst_duration_CCK, int, 0444);
11272MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");
11273
11274module_param(burst_duration_OFDM, int, 0444);
11275MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
11276#endif /* CONFIG_IPW_QOS */
11277
11278#ifdef CONFIG_IPW2200_MONITOR
7378module_param(mode, int, 0444); 11279module_param(mode, int, 0444);
7379MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)"); 11280MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
7380#else 11281#else
@@ -7382,5 +11283,12 @@ module_param(mode, int, 0444);
7382MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)"); 11283MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
7383#endif 11284#endif
7384 11285
11286module_param(hwcrypto, int, 0444);
11287MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
11288
11289module_param(cmdlog, int, 0444);
11290MODULE_PARM_DESC(cmdlog,
11291 "allocate a ring buffer for logging firmware commands");
11292
7385module_exit(ipw_exit); 11293module_exit(ipw_exit);
7386module_init(ipw_init); 11294module_init(ipw_init);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index e9cf32bf3e31..1c98db0652c9 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -34,7 +34,6 @@
34#include <linux/config.h> 34#include <linux/config.h>
35#include <linux/init.h> 35#include <linux/init.h>
36 36
37#include <linux/version.h>
38#include <linux/pci.h> 37#include <linux/pci.h>
39#include <linux/netdevice.h> 38#include <linux/netdevice.h>
40#include <linux/ethtool.h> 39#include <linux/ethtool.h>
@@ -50,6 +49,7 @@
50#include <asm/io.h> 49#include <asm/io.h>
51 50
52#include <net/ieee80211.h> 51#include <net/ieee80211.h>
52#include <net/ieee80211_radiotap.h>
53 53
54#define DRV_NAME "ipw2200" 54#define DRV_NAME "ipw2200"
55 55
@@ -161,6 +161,16 @@ enum connection_manager_assoc_states {
161 * TX Queue Flag Definitions 161 * TX Queue Flag Definitions
162 */ 162 */
163 163
164/* tx wep key definition */
165#define DCT_WEP_KEY_NOT_IMMIDIATE 0x00
166#define DCT_WEP_KEY_64Bit 0x40
167#define DCT_WEP_KEY_128Bit 0x80
168#define DCT_WEP_KEY_128bitIV 0xC0
169#define DCT_WEP_KEY_SIZE_MASK 0xC0
170
171#define DCT_WEP_KEY_INDEX_MASK 0x0F
172#define DCT_WEP_INDEX_USE_IMMEDIATE 0x20
173
164/* abort attempt if mgmt frame is rx'd */ 174/* abort attempt if mgmt frame is rx'd */
165#define DCT_FLAG_ABORT_MGMT 0x01 175#define DCT_FLAG_ABORT_MGMT 0x01
166 176
@@ -168,7 +178,8 @@ enum connection_manager_assoc_states {
168#define DCT_FLAG_CTS_REQUIRED 0x02 178#define DCT_FLAG_CTS_REQUIRED 0x02
169 179
170/* use short preamble */ 180/* use short preamble */
171#define DCT_FLAG_SHORT_PREMBL 0x04 181#define DCT_FLAG_LONG_PREAMBLE 0x00
182#define DCT_FLAG_SHORT_PREAMBLE 0x04
172 183
173/* RTS/CTS first */ 184/* RTS/CTS first */
174#define DCT_FLAG_RTS_REQD 0x08 185#define DCT_FLAG_RTS_REQD 0x08
@@ -185,9 +196,23 @@ enum connection_manager_assoc_states {
185/* ACK rx is expected to follow */ 196/* ACK rx is expected to follow */
186#define DCT_FLAG_ACK_REQD 0x80 197#define DCT_FLAG_ACK_REQD 0x80
187 198
199/* TX flags extension */
188#define DCT_FLAG_EXT_MODE_CCK 0x01 200#define DCT_FLAG_EXT_MODE_CCK 0x01
189#define DCT_FLAG_EXT_MODE_OFDM 0x00 201#define DCT_FLAG_EXT_MODE_OFDM 0x00
190 202
203#define DCT_FLAG_EXT_SECURITY_WEP 0x00
204#define DCT_FLAG_EXT_SECURITY_NO DCT_FLAG_EXT_SECURITY_WEP
205#define DCT_FLAG_EXT_SECURITY_CKIP 0x04
206#define DCT_FLAG_EXT_SECURITY_CCM 0x08
207#define DCT_FLAG_EXT_SECURITY_TKIP 0x0C
208#define DCT_FLAG_EXT_SECURITY_MASK 0x0C
209
210#define DCT_FLAG_EXT_QOS_ENABLED 0x10
211
212#define DCT_FLAG_EXT_HC_NO_SIFS_PIFS 0x00
213#define DCT_FLAG_EXT_HC_SIFS 0x20
214#define DCT_FLAG_EXT_HC_PIFS 0x40
215
191#define TX_RX_TYPE_MASK 0xFF 216#define TX_RX_TYPE_MASK 0xFF
192#define TX_FRAME_TYPE 0x00 217#define TX_FRAME_TYPE 0x00
193#define TX_HOST_COMMAND_TYPE 0x01 218#define TX_HOST_COMMAND_TYPE 0x01
@@ -233,6 +258,117 @@ enum connection_manager_assoc_states {
233#define DCR_TYPE_SNIFFER 0x06 258#define DCR_TYPE_SNIFFER 0x06
234#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS 259#define DCR_TYPE_MU_BSS DCR_TYPE_MU_ESS
235 260
261/* QoS definitions */
262
263#define CW_MIN_OFDM 15
264#define CW_MAX_OFDM 1023
265#define CW_MIN_CCK 31
266#define CW_MAX_CCK 1023
267
268#define QOS_TX0_CW_MIN_OFDM CW_MIN_OFDM
269#define QOS_TX1_CW_MIN_OFDM CW_MIN_OFDM
270#define QOS_TX2_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
271#define QOS_TX3_CW_MIN_OFDM ( (CW_MIN_OFDM + 1) / 4 - 1 )
272
273#define QOS_TX0_CW_MIN_CCK CW_MIN_CCK
274#define QOS_TX1_CW_MIN_CCK CW_MIN_CCK
275#define QOS_TX2_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
276#define QOS_TX3_CW_MIN_CCK ( (CW_MIN_CCK + 1) / 4 - 1 )
277
278#define QOS_TX0_CW_MAX_OFDM CW_MAX_OFDM
279#define QOS_TX1_CW_MAX_OFDM CW_MAX_OFDM
280#define QOS_TX2_CW_MAX_OFDM CW_MIN_OFDM
281#define QOS_TX3_CW_MAX_OFDM ( (CW_MIN_OFDM + 1) / 2 - 1 )
282
283#define QOS_TX0_CW_MAX_CCK CW_MAX_CCK
284#define QOS_TX1_CW_MAX_CCK CW_MAX_CCK
285#define QOS_TX2_CW_MAX_CCK CW_MIN_CCK
286#define QOS_TX3_CW_MAX_CCK ( (CW_MIN_CCK + 1) / 2 - 1 )
287
288#define QOS_TX0_AIFS (3 - QOS_AIFSN_MIN_VALUE)
289#define QOS_TX1_AIFS (7 - QOS_AIFSN_MIN_VALUE)
290#define QOS_TX2_AIFS (2 - QOS_AIFSN_MIN_VALUE)
291#define QOS_TX3_AIFS (2 - QOS_AIFSN_MIN_VALUE)
292
293#define QOS_TX0_ACM 0
294#define QOS_TX1_ACM 0
295#define QOS_TX2_ACM 0
296#define QOS_TX3_ACM 0
297
298#define QOS_TX0_TXOP_LIMIT_CCK 0
299#define QOS_TX1_TXOP_LIMIT_CCK 0
300#define QOS_TX2_TXOP_LIMIT_CCK 6016
301#define QOS_TX3_TXOP_LIMIT_CCK 3264
302
303#define QOS_TX0_TXOP_LIMIT_OFDM 0
304#define QOS_TX1_TXOP_LIMIT_OFDM 0
305#define QOS_TX2_TXOP_LIMIT_OFDM 3008
306#define QOS_TX3_TXOP_LIMIT_OFDM 1504
307
308#define DEF_TX0_CW_MIN_OFDM CW_MIN_OFDM
309#define DEF_TX1_CW_MIN_OFDM CW_MIN_OFDM
310#define DEF_TX2_CW_MIN_OFDM CW_MIN_OFDM
311#define DEF_TX3_CW_MIN_OFDM CW_MIN_OFDM
312
313#define DEF_TX0_CW_MIN_CCK CW_MIN_CCK
314#define DEF_TX1_CW_MIN_CCK CW_MIN_CCK
315#define DEF_TX2_CW_MIN_CCK CW_MIN_CCK
316#define DEF_TX3_CW_MIN_CCK CW_MIN_CCK
317
318#define DEF_TX0_CW_MAX_OFDM CW_MAX_OFDM
319#define DEF_TX1_CW_MAX_OFDM CW_MAX_OFDM
320#define DEF_TX2_CW_MAX_OFDM CW_MAX_OFDM
321#define DEF_TX3_CW_MAX_OFDM CW_MAX_OFDM
322
323#define DEF_TX0_CW_MAX_CCK CW_MAX_CCK
324#define DEF_TX1_CW_MAX_CCK CW_MAX_CCK
325#define DEF_TX2_CW_MAX_CCK CW_MAX_CCK
326#define DEF_TX3_CW_MAX_CCK CW_MAX_CCK
327
328#define DEF_TX0_AIFS 0
329#define DEF_TX1_AIFS 0
330#define DEF_TX2_AIFS 0
331#define DEF_TX3_AIFS 0
332
333#define DEF_TX0_ACM 0
334#define DEF_TX1_ACM 0
335#define DEF_TX2_ACM 0
336#define DEF_TX3_ACM 0
337
338#define DEF_TX0_TXOP_LIMIT_CCK 0
339#define DEF_TX1_TXOP_LIMIT_CCK 0
340#define DEF_TX2_TXOP_LIMIT_CCK 0
341#define DEF_TX3_TXOP_LIMIT_CCK 0
342
343#define DEF_TX0_TXOP_LIMIT_OFDM 0
344#define DEF_TX1_TXOP_LIMIT_OFDM 0
345#define DEF_TX2_TXOP_LIMIT_OFDM 0
346#define DEF_TX3_TXOP_LIMIT_OFDM 0
347
348#define QOS_QOS_SETS 3
349#define QOS_PARAM_SET_ACTIVE 0
350#define QOS_PARAM_SET_DEF_CCK 1
351#define QOS_PARAM_SET_DEF_OFDM 2
352
353#define CTRL_QOS_NO_ACK (0x0020)
354
355#define IPW_TX_QUEUE_1 1
356#define IPW_TX_QUEUE_2 2
357#define IPW_TX_QUEUE_3 3
358#define IPW_TX_QUEUE_4 4
359
360/* QoS sturctures */
361struct ipw_qos_info {
362 int qos_enable;
363 struct ieee80211_qos_parameters *def_qos_parm_OFDM;
364 struct ieee80211_qos_parameters *def_qos_parm_CCK;
365 u32 burst_duration_CCK;
366 u32 burst_duration_OFDM;
367 u16 qos_no_ack_mask;
368 int burst_enable;
369};
370
371/**************************************************************/
236/** 372/**
237 * Generic queue structure 373 * Generic queue structure
238 * 374 *
@@ -402,9 +538,9 @@ struct clx2_tx_queue {
402#define RX_FREE_BUFFERS 32 538#define RX_FREE_BUFFERS 32
403#define RX_LOW_WATERMARK 8 539#define RX_LOW_WATERMARK 8
404 540
405#define SUP_RATE_11A_MAX_NUM_CHANNELS (8) 541#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
406#define SUP_RATE_11B_MAX_NUM_CHANNELS (4) 542#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
407#define SUP_RATE_11G_MAX_NUM_CHANNELS (12) 543#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
408 544
409// Used for passing to driver number of successes and failures per rate 545// Used for passing to driver number of successes and failures per rate
410struct rate_histogram { 546struct rate_histogram {
@@ -453,6 +589,9 @@ struct notif_channel_result {
453 u8 uReserved; 589 u8 uReserved;
454} __attribute__ ((packed)); 590} __attribute__ ((packed));
455 591
592#define SCAN_COMPLETED_STATUS_COMPLETE 1
593#define SCAN_COMPLETED_STATUS_ABORTED 2
594
456struct notif_scan_complete { 595struct notif_scan_complete {
457 u8 scan_type; 596 u8 scan_type;
458 u8 num_channels; 597 u8 num_channels;
@@ -563,8 +702,8 @@ struct ipw_rx_packet {
563} __attribute__ ((packed)); 702} __attribute__ ((packed));
564 703
565#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12 704#define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12
566#define IPW_RX_FRAME_SIZE sizeof(struct ipw_rx_header) + \ 705#define IPW_RX_FRAME_SIZE (unsigned int)(sizeof(struct ipw_rx_header) + \
567 sizeof(struct ipw_rx_frame) 706 sizeof(struct ipw_rx_frame))
568 707
569struct ipw_rx_mem_buffer { 708struct ipw_rx_mem_buffer {
570 dma_addr_t dma_addr; 709 dma_addr_t dma_addr;
@@ -657,6 +796,19 @@ struct ipw_multicast_addr {
657 u8 mac4[6]; 796 u8 mac4[6];
658} __attribute__ ((packed)); 797} __attribute__ ((packed));
659 798
799#define DCW_WEP_KEY_INDEX_MASK 0x03 /* bits [0:1] */
800#define DCW_WEP_KEY_SEC_TYPE_MASK 0x30 /* bits [4:5] */
801
802#define DCW_WEP_KEY_SEC_TYPE_WEP 0x00
803#define DCW_WEP_KEY_SEC_TYPE_CCM 0x20
804#define DCW_WEP_KEY_SEC_TYPE_TKIP 0x30
805
806#define DCW_WEP_KEY_INVALID_SIZE 0x00 /* 0 = Invalid key */
807#define DCW_WEP_KEY64Bit_SIZE 0x05 /* 64-bit encryption */
808#define DCW_WEP_KEY128Bit_SIZE 0x0D /* 128-bit encryption */
809#define DCW_CCM_KEY128Bit_SIZE 0x10 /* 128-bit key */
810//#define DCW_WEP_KEY128BitIV_SIZE 0x10 /* 128-bit key and 128-bit IV */
811
660struct ipw_wep_key { 812struct ipw_wep_key {
661 u8 cmd_id; 813 u8 cmd_id;
662 u8 seq_num; 814 u8 seq_num;
@@ -818,14 +970,6 @@ struct ipw_tx_power {
818 struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS]; 970 struct ipw_channel_tx_power channels_tx_power[MAX_A_CHANNELS];
819} __attribute__ ((packed)); 971} __attribute__ ((packed));
820 972
821struct ipw_qos_parameters {
822 u16 cw_min[4];
823 u16 cw_max[4];
824 u8 aifs[4];
825 u8 flag[4];
826 u16 tx_op_limit[4];
827} __attribute__ ((packed));
828
829struct ipw_rsn_capabilities { 973struct ipw_rsn_capabilities {
830 u8 id; 974 u8 id;
831 u8 length; 975 u8 length;
@@ -888,6 +1032,10 @@ struct ipw_cmd {
888#define STATUS_SCAN_PENDING (1<<20) 1032#define STATUS_SCAN_PENDING (1<<20)
889#define STATUS_SCANNING (1<<21) 1033#define STATUS_SCANNING (1<<21)
890#define STATUS_SCAN_ABORTING (1<<22) 1034#define STATUS_SCAN_ABORTING (1<<22)
1035#define STATUS_SCAN_FORCED (1<<23)
1036
1037#define STATUS_LED_LINK_ON (1<<24)
1038#define STATUS_LED_ACT_ON (1<<25)
891 1039
892#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */ 1040#define STATUS_INDIRECT_BYTE (1<<28) /* sysfs entry configured for access */
893#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */ 1041#define STATUS_INDIRECT_DWORD (1<<29) /* sysfs entry configured for access */
@@ -899,11 +1047,15 @@ struct ipw_cmd {
899#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */ 1047#define CFG_STATIC_ESSID (1<<1) /* Restrict assoc. to single SSID */
900#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */ 1048#define CFG_STATIC_BSSID (1<<2) /* Restrict assoc. to single BSSID */
901#define CFG_CUSTOM_MAC (1<<3) 1049#define CFG_CUSTOM_MAC (1<<3)
902#define CFG_PREAMBLE (1<<4) 1050#define CFG_PREAMBLE_LONG (1<<4)
903#define CFG_ADHOC_PERSIST (1<<5) 1051#define CFG_ADHOC_PERSIST (1<<5)
904#define CFG_ASSOCIATE (1<<6) 1052#define CFG_ASSOCIATE (1<<6)
905#define CFG_FIXED_RATE (1<<7) 1053#define CFG_FIXED_RATE (1<<7)
906#define CFG_ADHOC_CREATE (1<<8) 1054#define CFG_ADHOC_CREATE (1<<8)
1055#define CFG_NO_LED (1<<9)
1056#define CFG_BACKGROUND_SCAN (1<<10)
1057#define CFG_SPEED_SCAN (1<<11)
1058#define CFG_NET_STATS (1<<12)
907 1059
908#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 1060#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
909#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 1061#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
@@ -925,13 +1077,50 @@ struct average {
925 s32 sum; 1077 s32 sum;
926}; 1078};
927 1079
1080#define MAX_SPEED_SCAN 100
1081#define IPW_IBSS_MAC_HASH_SIZE 31
1082
1083struct ipw_ibss_seq {
1084 u8 mac[ETH_ALEN];
1085 u16 seq_num;
1086 u16 frag_num;
1087 unsigned long packet_time;
1088 struct list_head list;
1089};
1090
1091struct ipw_error_elem {
1092 u32 desc;
1093 u32 time;
1094 u32 blink1;
1095 u32 blink2;
1096 u32 link1;
1097 u32 link2;
1098 u32 data;
1099};
1100
1101struct ipw_event {
1102 u32 event;
1103 u32 time;
1104 u32 data;
1105} __attribute__ ((packed));
1106
1107struct ipw_fw_error {
1108 unsigned long jiffies;
1109 u32 status;
1110 u32 config;
1111 u32 elem_len;
1112 u32 log_len;
1113 struct ipw_error_elem *elem;
1114 struct ipw_event *log;
1115 u8 payload[0];
1116} __attribute__ ((packed));
1117
928struct ipw_priv { 1118struct ipw_priv {
929 /* ieee device used by generic ieee processing code */ 1119 /* ieee device used by generic ieee processing code */
930 struct ieee80211_device *ieee; 1120 struct ieee80211_device *ieee;
931 struct ieee80211_security sec;
932 1121
933 /* spinlock */
934 spinlock_t lock; 1122 spinlock_t lock;
1123 struct semaphore sem;
935 1124
936 /* basic pci-network driver stuff */ 1125 /* basic pci-network driver stuff */
937 struct pci_dev *pci_dev; 1126 struct pci_dev *pci_dev;
@@ -966,7 +1155,7 @@ struct ipw_priv {
966 int rx_bufs_min; /**< minimum number of bufs in Rx queue */ 1155 int rx_bufs_min; /**< minimum number of bufs in Rx queue */
967 int rx_pend_max; /**< maximum pending buffers for one IRQ */ 1156 int rx_pend_max; /**< maximum pending buffers for one IRQ */
968 u32 hcmd_seq; /**< sequence number for hcmd */ 1157 u32 hcmd_seq; /**< sequence number for hcmd */
969 u32 missed_beacon_threshold; 1158 u32 disassociate_threshold;
970 u32 roaming_threshold; 1159 u32 roaming_threshold;
971 1160
972 struct ipw_associate assoc_request; 1161 struct ipw_associate assoc_request;
@@ -1007,6 +1196,8 @@ struct ipw_priv {
1007 u8 mac_addr[ETH_ALEN]; 1196 u8 mac_addr[ETH_ALEN];
1008 u8 num_stations; 1197 u8 num_stations;
1009 u8 stations[MAX_STATIONS][ETH_ALEN]; 1198 u8 stations[MAX_STATIONS][ETH_ALEN];
1199 u8 short_retry_limit;
1200 u8 long_retry_limit;
1010 1201
1011 u32 notif_missed_beacons; 1202 u32 notif_missed_beacons;
1012 1203
@@ -1024,17 +1215,29 @@ struct ipw_priv {
1024 u32 tx_packets; 1215 u32 tx_packets;
1025 u32 quality; 1216 u32 quality;
1026 1217
1218 u8 speed_scan[MAX_SPEED_SCAN];
1219 u8 speed_scan_pos;
1220
1221 u16 last_seq_num;
1222 u16 last_frag_num;
1223 unsigned long last_packet_time;
1224 struct list_head ibss_mac_hash[IPW_IBSS_MAC_HASH_SIZE];
1225
1027 /* eeprom */ 1226 /* eeprom */
1028 u8 eeprom[0x100]; /* 256 bytes of eeprom */ 1227 u8 eeprom[0x100]; /* 256 bytes of eeprom */
1228 u8 country[4];
1029 int eeprom_delay; 1229 int eeprom_delay;
1030 1230
1031 struct iw_statistics wstats; 1231 struct iw_statistics wstats;
1032 1232
1233 struct iw_public_data wireless_data;
1234
1033 struct workqueue_struct *workqueue; 1235 struct workqueue_struct *workqueue;
1034 1236
1035 struct work_struct adhoc_check; 1237 struct work_struct adhoc_check;
1036 struct work_struct associate; 1238 struct work_struct associate;
1037 struct work_struct disassociate; 1239 struct work_struct disassociate;
1240 struct work_struct system_config;
1038 struct work_struct rx_replenish; 1241 struct work_struct rx_replenish;
1039 struct work_struct request_scan; 1242 struct work_struct request_scan;
1040 struct work_struct adapter_restart; 1243 struct work_struct adapter_restart;
@@ -1045,25 +1248,51 @@ struct ipw_priv {
1045 struct work_struct abort_scan; 1248 struct work_struct abort_scan;
1046 struct work_struct roam; 1249 struct work_struct roam;
1047 struct work_struct scan_check; 1250 struct work_struct scan_check;
1251 struct work_struct link_up;
1252 struct work_struct link_down;
1048 1253
1049 struct tasklet_struct irq_tasklet; 1254 struct tasklet_struct irq_tasklet;
1050 1255
1256 /* LED related variables and work_struct */
1257 u8 nic_type;
1258 u32 led_activity_on;
1259 u32 led_activity_off;
1260 u32 led_association_on;
1261 u32 led_association_off;
1262 u32 led_ofdm_on;
1263 u32 led_ofdm_off;
1264
1265 struct work_struct led_link_on;
1266 struct work_struct led_link_off;
1267 struct work_struct led_act_off;
1268 struct work_struct merge_networks;
1269
1270 struct ipw_cmd_log *cmdlog;
1271 int cmdlog_len;
1272 int cmdlog_pos;
1273
1051#define IPW_2200BG 1 1274#define IPW_2200BG 1
1052#define IPW_2915ABG 2 1275#define IPW_2915ABG 2
1053 u8 adapter; 1276 u8 adapter;
1054 1277
1055#define IPW_DEFAULT_TX_POWER 0x14 1278 s8 tx_power;
1056 u8 tx_power;
1057 1279
1058#ifdef CONFIG_PM 1280#ifdef CONFIG_PM
1059 u32 pm_state[16]; 1281 u32 pm_state[16];
1060#endif 1282#endif
1061 1283
1284 struct ipw_fw_error *error;
1285
1062 /* network state */ 1286 /* network state */
1063 1287
1064 /* Used to pass the current INTA value from ISR to Tasklet */ 1288 /* Used to pass the current INTA value from ISR to Tasklet */
1065 u32 isr_inta; 1289 u32 isr_inta;
1066 1290
1291 /* QoS */
1292 struct ipw_qos_info qos_data;
1293 struct work_struct qos_activate;
1294 /*********************************/
1295
1067 /* debugging info */ 1296 /* debugging info */
1068 u32 indirect_dword; 1297 u32 indirect_dword;
1069 u32 direct_dword; 1298 u32 direct_dword;
@@ -1125,6 +1354,8 @@ do { if (ipw_debug_level & (level)) \
1125#define IPW_DL_RF_KILL (1<<17) 1354#define IPW_DL_RF_KILL (1<<17)
1126#define IPW_DL_FW_ERRORS (1<<18) 1355#define IPW_DL_FW_ERRORS (1<<18)
1127 1356
1357#define IPW_DL_LED (1<<19)
1358
1128#define IPW_DL_ORD (1<<20) 1359#define IPW_DL_ORD (1<<20)
1129 1360
1130#define IPW_DL_FRAG (1<<21) 1361#define IPW_DL_FRAG (1<<21)
@@ -1137,6 +1368,8 @@ do { if (ipw_debug_level & (level)) \
1137#define IPW_DL_TRACE (1<<28) 1368#define IPW_DL_TRACE (1<<28)
1138 1369
1139#define IPW_DL_STATS (1<<29) 1370#define IPW_DL_STATS (1<<29)
1371#define IPW_DL_MERGE (1<<30)
1372#define IPW_DL_QOS (1<<31)
1140 1373
1141#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) 1374#define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
1142#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) 1375#define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
@@ -1150,6 +1383,7 @@ do { if (ipw_debug_level & (level)) \
1150#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a) 1383#define IPW_DEBUG_TX(f, a...) IPW_DEBUG(IPW_DL_TX, f, ## a)
1151#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a) 1384#define IPW_DEBUG_ISR(f, a...) IPW_DEBUG(IPW_DL_ISR, f, ## a)
1152#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a) 1385#define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a)
1386#define IPW_DEBUG_LED(f, a...) IPW_DEBUG(IPW_DL_LED, f, ## a)
1153#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a) 1387#define IPW_DEBUG_WEP(f, a...) IPW_DEBUG(IPW_DL_WEP, f, ## a)
1154#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a) 1388#define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a)
1155#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a) 1389#define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a)
@@ -1163,6 +1397,8 @@ do { if (ipw_debug_level & (level)) \
1163#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1397#define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1164#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a) 1398#define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
1165#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a) 1399#define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a)
1400#define IPW_DEBUG_MERGE(f, a...) IPW_DEBUG(IPW_DL_MERGE, f, ## a)
1401#define IPW_DEBUG_QOS(f, a...) IPW_DEBUG(IPW_DL_QOS, f, ## a)
1166 1402
1167#include <linux/ctype.h> 1403#include <linux/ctype.h>
1168 1404
@@ -1177,59 +1413,65 @@ do { if (ipw_debug_level & (level)) \
1177#define DINO_RXFIFO_DATA 0x01 1413#define DINO_RXFIFO_DATA 0x01
1178#define DINO_CONTROL_REG 0x00200000 1414#define DINO_CONTROL_REG 0x00200000
1179 1415
1180#define CX2_INTA_RW 0x00000008 1416#define IPW_INTA_RW 0x00000008
1181#define CX2_INTA_MASK_R 0x0000000C 1417#define IPW_INTA_MASK_R 0x0000000C
1182#define CX2_INDIRECT_ADDR 0x00000010 1418#define IPW_INDIRECT_ADDR 0x00000010
1183#define CX2_INDIRECT_DATA 0x00000014 1419#define IPW_INDIRECT_DATA 0x00000014
1184#define CX2_AUTOINC_ADDR 0x00000018 1420#define IPW_AUTOINC_ADDR 0x00000018
1185#define CX2_AUTOINC_DATA 0x0000001C 1421#define IPW_AUTOINC_DATA 0x0000001C
1186#define CX2_RESET_REG 0x00000020 1422#define IPW_RESET_REG 0x00000020
1187#define CX2_GP_CNTRL_RW 0x00000024 1423#define IPW_GP_CNTRL_RW 0x00000024
1188 1424
1189#define CX2_READ_INT_REGISTER 0xFF4 1425#define IPW_READ_INT_REGISTER 0xFF4
1190 1426
1191#define CX2_GP_CNTRL_BIT_INIT_DONE 0x00000004 1427#define IPW_GP_CNTRL_BIT_INIT_DONE 0x00000004
1192 1428
1193#define CX2_REGISTER_DOMAIN1_END 0x00001000 1429#define IPW_REGISTER_DOMAIN1_END 0x00001000
1194#define CX2_SRAM_READ_INT_REGISTER 0x00000ff4 1430#define IPW_SRAM_READ_INT_REGISTER 0x00000ff4
1195 1431
1196#define CX2_SHARED_LOWER_BOUND 0x00000200 1432#define IPW_SHARED_LOWER_BOUND 0x00000200
1197#define CX2_INTERRUPT_AREA_LOWER_BOUND 0x00000f80 1433#define IPW_INTERRUPT_AREA_LOWER_BOUND 0x00000f80
1198 1434
1199#define CX2_NIC_SRAM_LOWER_BOUND 0x00000000 1435#define IPW_NIC_SRAM_LOWER_BOUND 0x00000000
1200#define CX2_NIC_SRAM_UPPER_BOUND 0x00030000 1436#define IPW_NIC_SRAM_UPPER_BOUND 0x00030000
1201 1437
1202#define CX2_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29) 1438#define IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER (1 << 29)
1203#define CX2_GP_CNTRL_BIT_CLOCK_READY 0x00000001 1439#define IPW_GP_CNTRL_BIT_CLOCK_READY 0x00000001
1204#define CX2_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002 1440#define IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY 0x00000002
1205 1441
1206/* 1442/*
1207 * RESET Register Bit Indexes 1443 * RESET Register Bit Indexes
1208 */ 1444 */
1209#define CBD_RESET_REG_PRINCETON_RESET 0x00000001 /* Bit 0 (LSB) */ 1445#define CBD_RESET_REG_PRINCETON_RESET (1<<0)
1210#define CX2_RESET_REG_SW_RESET 0x00000080 /* Bit 7 */ 1446#define IPW_START_STANDBY (1<<2)
1211#define CX2_RESET_REG_MASTER_DISABLED 0x00000100 /* Bit 8 */ 1447#define IPW_ACTIVITY_LED (1<<4)
1212#define CX2_RESET_REG_STOP_MASTER 0x00000200 /* Bit 9 */ 1448#define IPW_ASSOCIATED_LED (1<<5)
1213#define CX2_ARC_KESHET_CONFIG 0x08000000 /* Bit 27 */ 1449#define IPW_OFDM_LED (1<<6)
1214#define CX2_START_STANDBY 0x00000004 /* Bit 2 */ 1450#define IPW_RESET_REG_SW_RESET (1<<7)
1215 1451#define IPW_RESET_REG_MASTER_DISABLED (1<<8)
1216#define CX2_CSR_CIS_UPPER_BOUND 0x00000200 1452#define IPW_RESET_REG_STOP_MASTER (1<<9)
1217#define CX2_DOMAIN_0_END 0x1000 1453#define IPW_GATE_ODMA (1<<25)
1454#define IPW_GATE_IDMA (1<<26)
1455#define IPW_ARC_KESHET_CONFIG (1<<27)
1456#define IPW_GATE_ADMA (1<<29)
1457
1458#define IPW_CSR_CIS_UPPER_BOUND 0x00000200
1459#define IPW_DOMAIN_0_END 0x1000
1218#define CLX_MEM_BAR_SIZE 0x1000 1460#define CLX_MEM_BAR_SIZE 0x1000
1219 1461
1220#define CX2_BASEBAND_CONTROL_STATUS 0X00200000 1462#define IPW_BASEBAND_CONTROL_STATUS 0X00200000
1221#define CX2_BASEBAND_TX_FIFO_WRITE 0X00200004 1463#define IPW_BASEBAND_TX_FIFO_WRITE 0X00200004
1222#define CX2_BASEBAND_RX_FIFO_READ 0X00200004 1464#define IPW_BASEBAND_RX_FIFO_READ 0X00200004
1223#define CX2_BASEBAND_CONTROL_STORE 0X00200010 1465#define IPW_BASEBAND_CONTROL_STORE 0X00200010
1224 1466
1225#define CX2_INTERNAL_CMD_EVENT 0X00300004 1467#define IPW_INTERNAL_CMD_EVENT 0X00300004
1226#define CX2_BASEBAND_POWER_DOWN 0x00000001 1468#define IPW_BASEBAND_POWER_DOWN 0x00000001
1227 1469
1228#define CX2_MEM_HALT_AND_RESET 0x003000e0 1470#define IPW_MEM_HALT_AND_RESET 0x003000e0
1229 1471
1230/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */ 1472/* defgroup bits_halt_reset MEM_HALT_AND_RESET register bits */
1231#define CX2_BIT_HALT_RESET_ON 0x80000000 1473#define IPW_BIT_HALT_RESET_ON 0x80000000
1232#define CX2_BIT_HALT_RESET_OFF 0x00000000 1474#define IPW_BIT_HALT_RESET_OFF 0x00000000
1233 1475
1234#define CB_LAST_VALID 0x20000000 1476#define CB_LAST_VALID 0x20000000
1235#define CB_INT_ENABLED 0x40000000 1477#define CB_INT_ENABLED 0x40000000
@@ -1248,63 +1490,63 @@ do { if (ipw_debug_level & (level)) \
1248#define DMA_CB_STOP_AND_ABORT 0x00000C00 1490#define DMA_CB_STOP_AND_ABORT 0x00000C00
1249#define DMA_CB_START 0x00000100 1491#define DMA_CB_START 0x00000100
1250 1492
1251#define CX2_SHARED_SRAM_SIZE 0x00030000 1493#define IPW_SHARED_SRAM_SIZE 0x00030000
1252#define CX2_SHARED_SRAM_DMA_CONTROL 0x00027000 1494#define IPW_SHARED_SRAM_DMA_CONTROL 0x00027000
1253#define CB_MAX_LENGTH 0x1FFF 1495#define CB_MAX_LENGTH 0x1FFF
1254 1496
1255#define CX2_HOST_EEPROM_DATA_SRAM_SIZE 0xA18 1497#define IPW_HOST_EEPROM_DATA_SRAM_SIZE 0xA18
1256#define CX2_EEPROM_IMAGE_SIZE 0x100 1498#define IPW_EEPROM_IMAGE_SIZE 0x100
1257 1499
1258/* DMA defs */ 1500/* DMA defs */
1259#define CX2_DMA_I_CURRENT_CB 0x003000D0 1501#define IPW_DMA_I_CURRENT_CB 0x003000D0
1260#define CX2_DMA_O_CURRENT_CB 0x003000D4 1502#define IPW_DMA_O_CURRENT_CB 0x003000D4
1261#define CX2_DMA_I_DMA_CONTROL 0x003000A4 1503#define IPW_DMA_I_DMA_CONTROL 0x003000A4
1262#define CX2_DMA_I_CB_BASE 0x003000A0 1504#define IPW_DMA_I_CB_BASE 0x003000A0
1263 1505
1264#define CX2_TX_CMD_QUEUE_BD_BASE (0x00000200) 1506#define IPW_TX_CMD_QUEUE_BD_BASE 0x00000200
1265#define CX2_TX_CMD_QUEUE_BD_SIZE (0x00000204) 1507#define IPW_TX_CMD_QUEUE_BD_SIZE 0x00000204
1266#define CX2_TX_QUEUE_0_BD_BASE (0x00000208) 1508#define IPW_TX_QUEUE_0_BD_BASE 0x00000208
1267#define CX2_TX_QUEUE_0_BD_SIZE (0x0000020C) 1509#define IPW_TX_QUEUE_0_BD_SIZE (0x0000020C)
1268#define CX2_TX_QUEUE_1_BD_BASE (0x00000210) 1510#define IPW_TX_QUEUE_1_BD_BASE 0x00000210
1269#define CX2_TX_QUEUE_1_BD_SIZE (0x00000214) 1511#define IPW_TX_QUEUE_1_BD_SIZE 0x00000214
1270#define CX2_TX_QUEUE_2_BD_BASE (0x00000218) 1512#define IPW_TX_QUEUE_2_BD_BASE 0x00000218
1271#define CX2_TX_QUEUE_2_BD_SIZE (0x0000021C) 1513#define IPW_TX_QUEUE_2_BD_SIZE (0x0000021C)
1272#define CX2_TX_QUEUE_3_BD_BASE (0x00000220) 1514#define IPW_TX_QUEUE_3_BD_BASE 0x00000220
1273#define CX2_TX_QUEUE_3_BD_SIZE (0x00000224) 1515#define IPW_TX_QUEUE_3_BD_SIZE 0x00000224
1274#define CX2_RX_BD_BASE (0x00000240) 1516#define IPW_RX_BD_BASE 0x00000240
1275#define CX2_RX_BD_SIZE (0x00000244) 1517#define IPW_RX_BD_SIZE 0x00000244
1276#define CX2_RFDS_TABLE_LOWER (0x00000500) 1518#define IPW_RFDS_TABLE_LOWER 0x00000500
1277 1519
1278#define CX2_TX_CMD_QUEUE_READ_INDEX (0x00000280) 1520#define IPW_TX_CMD_QUEUE_READ_INDEX 0x00000280
1279#define CX2_TX_QUEUE_0_READ_INDEX (0x00000284) 1521#define IPW_TX_QUEUE_0_READ_INDEX 0x00000284
1280#define CX2_TX_QUEUE_1_READ_INDEX (0x00000288) 1522#define IPW_TX_QUEUE_1_READ_INDEX 0x00000288
1281#define CX2_TX_QUEUE_2_READ_INDEX (0x0000028C) 1523#define IPW_TX_QUEUE_2_READ_INDEX (0x0000028C)
1282#define CX2_TX_QUEUE_3_READ_INDEX (0x00000290) 1524#define IPW_TX_QUEUE_3_READ_INDEX 0x00000290
1283#define CX2_RX_READ_INDEX (0x000002A0) 1525#define IPW_RX_READ_INDEX (0x000002A0)
1284 1526
1285#define CX2_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80) 1527#define IPW_TX_CMD_QUEUE_WRITE_INDEX (0x00000F80)
1286#define CX2_TX_QUEUE_0_WRITE_INDEX (0x00000F84) 1528#define IPW_TX_QUEUE_0_WRITE_INDEX (0x00000F84)
1287#define CX2_TX_QUEUE_1_WRITE_INDEX (0x00000F88) 1529#define IPW_TX_QUEUE_1_WRITE_INDEX (0x00000F88)
1288#define CX2_TX_QUEUE_2_WRITE_INDEX (0x00000F8C) 1530#define IPW_TX_QUEUE_2_WRITE_INDEX (0x00000F8C)
1289#define CX2_TX_QUEUE_3_WRITE_INDEX (0x00000F90) 1531#define IPW_TX_QUEUE_3_WRITE_INDEX (0x00000F90)
1290#define CX2_RX_WRITE_INDEX (0x00000FA0) 1532#define IPW_RX_WRITE_INDEX (0x00000FA0)
1291 1533
1292/* 1534/*
1293 * EEPROM Related Definitions 1535 * EEPROM Related Definitions
1294 */ 1536 */
1295 1537
1296#define IPW_EEPROM_DATA_SRAM_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x814) 1538#define IPW_EEPROM_DATA_SRAM_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x814)
1297#define IPW_EEPROM_DATA_SRAM_SIZE (CX2_SHARED_LOWER_BOUND + 0x818) 1539#define IPW_EEPROM_DATA_SRAM_SIZE (IPW_SHARED_LOWER_BOUND + 0x818)
1298#define IPW_EEPROM_LOAD_DISABLE (CX2_SHARED_LOWER_BOUND + 0x81C) 1540#define IPW_EEPROM_LOAD_DISABLE (IPW_SHARED_LOWER_BOUND + 0x81C)
1299#define IPW_EEPROM_DATA (CX2_SHARED_LOWER_BOUND + 0x820) 1541#define IPW_EEPROM_DATA (IPW_SHARED_LOWER_BOUND + 0x820)
1300#define IPW_EEPROM_UPPER_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x9E0) 1542#define IPW_EEPROM_UPPER_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x9E0)
1301 1543
1302#define IPW_STATION_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0xA0C) 1544#define IPW_STATION_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0xA0C)
1303#define IPW_STATION_TABLE_UPPER (CX2_SHARED_LOWER_BOUND + 0xB0C) 1545#define IPW_STATION_TABLE_UPPER (IPW_SHARED_LOWER_BOUND + 0xB0C)
1304#define IPW_REQUEST_ATIM (CX2_SHARED_LOWER_BOUND + 0xB0C) 1546#define IPW_REQUEST_ATIM (IPW_SHARED_LOWER_BOUND + 0xB0C)
1305#define IPW_ATIM_SENT (CX2_SHARED_LOWER_BOUND + 0xB10) 1547#define IPW_ATIM_SENT (IPW_SHARED_LOWER_BOUND + 0xB10)
1306#define IPW_WHO_IS_AWAKE (CX2_SHARED_LOWER_BOUND + 0xB14) 1548#define IPW_WHO_IS_AWAKE (IPW_SHARED_LOWER_BOUND + 0xB14)
1307#define IPW_DURING_ATIM_WINDOW (CX2_SHARED_LOWER_BOUND + 0xB18) 1549#define IPW_DURING_ATIM_WINDOW (IPW_SHARED_LOWER_BOUND + 0xB18)
1308 1550
1309#define MSB 1 1551#define MSB 1
1310#define LSB 0 1552#define LSB 0
@@ -1326,15 +1568,15 @@ do { if (ipw_debug_level & (level)) \
1326#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */ 1568#define EEPROM_HW_VERSION (GET_EEPROM_ADDR(0x72,LSB)) /* 2 bytes */
1327 1569
1328/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/ 1570/* NIC type as found in the one byte EEPROM_NIC_TYPE offset*/
1329#define EEPROM_NIC_TYPE_STANDARD 0 1571#define EEPROM_NIC_TYPE_0 0
1330#define EEPROM_NIC_TYPE_DELL 1 1572#define EEPROM_NIC_TYPE_1 1
1331#define EEPROM_NIC_TYPE_FUJITSU 2 1573#define EEPROM_NIC_TYPE_2 2
1332#define EEPROM_NIC_TYPE_IBM 3 1574#define EEPROM_NIC_TYPE_3 3
1333#define EEPROM_NIC_TYPE_HP 4 1575#define EEPROM_NIC_TYPE_4 4
1334 1576
1335#define FW_MEM_REG_LOWER_BOUND 0x00300000 1577#define FW_MEM_REG_LOWER_BOUND 0x00300000
1336#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40) 1578#define FW_MEM_REG_EEPROM_ACCESS (FW_MEM_REG_LOWER_BOUND + 0x40)
1337 1579#define IPW_EVENT_REG (FW_MEM_REG_LOWER_BOUND + 0x04)
1338#define EEPROM_BIT_SK (1<<0) 1580#define EEPROM_BIT_SK (1<<0)
1339#define EEPROM_BIT_CS (1<<1) 1581#define EEPROM_BIT_CS (1<<1)
1340#define EEPROM_BIT_DI (1<<2) 1582#define EEPROM_BIT_DI (1<<2)
@@ -1343,50 +1585,47 @@ do { if (ipw_debug_level & (level)) \
1343#define EEPROM_CMD_READ 0x2 1585#define EEPROM_CMD_READ 0x2
1344 1586
1345/* Interrupts masks */ 1587/* Interrupts masks */
1346#define CX2_INTA_NONE 0x00000000 1588#define IPW_INTA_NONE 0x00000000
1347 1589
1348#define CX2_INTA_BIT_RX_TRANSFER 0x00000002 1590#define IPW_INTA_BIT_RX_TRANSFER 0x00000002
1349#define CX2_INTA_BIT_STATUS_CHANGE 0x00000010 1591#define IPW_INTA_BIT_STATUS_CHANGE 0x00000010
1350#define CX2_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020 1592#define IPW_INTA_BIT_BEACON_PERIOD_EXPIRED 0x00000020
1351 1593
1352//Inta Bits for CF 1594//Inta Bits for CF
1353#define CX2_INTA_BIT_TX_CMD_QUEUE 0x00000800 1595#define IPW_INTA_BIT_TX_CMD_QUEUE 0x00000800
1354#define CX2_INTA_BIT_TX_QUEUE_1 0x00001000 1596#define IPW_INTA_BIT_TX_QUEUE_1 0x00001000
1355#define CX2_INTA_BIT_TX_QUEUE_2 0x00002000 1597#define IPW_INTA_BIT_TX_QUEUE_2 0x00002000
1356#define CX2_INTA_BIT_TX_QUEUE_3 0x00004000 1598#define IPW_INTA_BIT_TX_QUEUE_3 0x00004000
1357#define CX2_INTA_BIT_TX_QUEUE_4 0x00008000 1599#define IPW_INTA_BIT_TX_QUEUE_4 0x00008000
1358 1600
1359#define CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000 1601#define IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE 0x00010000
1360 1602
1361#define CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000 1603#define IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN 0x00100000
1362#define CX2_INTA_BIT_POWER_DOWN 0x00200000 1604#define IPW_INTA_BIT_POWER_DOWN 0x00200000
1363 1605
1364#define CX2_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000 1606#define IPW_INTA_BIT_FW_INITIALIZATION_DONE 0x01000000
1365#define CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000 1607#define IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE 0x02000000
1366#define CX2_INTA_BIT_RF_KILL_DONE 0x04000000 1608#define IPW_INTA_BIT_RF_KILL_DONE 0x04000000
1367#define CX2_INTA_BIT_FATAL_ERROR 0x40000000 1609#define IPW_INTA_BIT_FATAL_ERROR 0x40000000
1368#define CX2_INTA_BIT_PARITY_ERROR 0x80000000 1610#define IPW_INTA_BIT_PARITY_ERROR 0x80000000
1369 1611
1370/* Interrupts enabled at init time. */ 1612/* Interrupts enabled at init time. */
1371#define CX2_INTA_MASK_ALL \ 1613#define IPW_INTA_MASK_ALL \
1372 (CX2_INTA_BIT_TX_QUEUE_1 | \ 1614 (IPW_INTA_BIT_TX_QUEUE_1 | \
1373 CX2_INTA_BIT_TX_QUEUE_2 | \ 1615 IPW_INTA_BIT_TX_QUEUE_2 | \
1374 CX2_INTA_BIT_TX_QUEUE_3 | \ 1616 IPW_INTA_BIT_TX_QUEUE_3 | \
1375 CX2_INTA_BIT_TX_QUEUE_4 | \ 1617 IPW_INTA_BIT_TX_QUEUE_4 | \
1376 CX2_INTA_BIT_TX_CMD_QUEUE | \ 1618 IPW_INTA_BIT_TX_CMD_QUEUE | \
1377 CX2_INTA_BIT_RX_TRANSFER | \ 1619 IPW_INTA_BIT_RX_TRANSFER | \
1378 CX2_INTA_BIT_FATAL_ERROR | \ 1620 IPW_INTA_BIT_FATAL_ERROR | \
1379 CX2_INTA_BIT_PARITY_ERROR | \ 1621 IPW_INTA_BIT_PARITY_ERROR | \
1380 CX2_INTA_BIT_STATUS_CHANGE | \ 1622 IPW_INTA_BIT_STATUS_CHANGE | \
1381 CX2_INTA_BIT_FW_INITIALIZATION_DONE | \ 1623 IPW_INTA_BIT_FW_INITIALIZATION_DONE | \
1382 CX2_INTA_BIT_BEACON_PERIOD_EXPIRED | \ 1624 IPW_INTA_BIT_BEACON_PERIOD_EXPIRED | \
1383 CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \ 1625 IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \
1384 CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN | \ 1626 IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN | \
1385 CX2_INTA_BIT_POWER_DOWN | \ 1627 IPW_INTA_BIT_POWER_DOWN | \
1386 CX2_INTA_BIT_RF_KILL_DONE ) 1628 IPW_INTA_BIT_RF_KILL_DONE )
1387
1388#define IPWSTATUS_ERROR_LOG (CX2_SHARED_LOWER_BOUND + 0x410)
1389#define IPW_EVENT_LOG (CX2_SHARED_LOWER_BOUND + 0x414)
1390 1629
1391/* FW event log definitions */ 1630/* FW event log definitions */
1392#define EVENT_ELEM_SIZE (3 * sizeof(u32)) 1631#define EVENT_ELEM_SIZE (3 * sizeof(u32))
@@ -1396,6 +1635,11 @@ do { if (ipw_debug_level & (level)) \
1396#define ERROR_ELEM_SIZE (7 * sizeof(u32)) 1635#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1397#define ERROR_START_OFFSET (1 * sizeof(u32)) 1636#define ERROR_START_OFFSET (1 * sizeof(u32))
1398 1637
1638/* TX power level (dbm) */
1639#define IPW_TX_POWER_MIN -12
1640#define IPW_TX_POWER_MAX 20
1641#define IPW_TX_POWER_DEFAULT IPW_TX_POWER_MAX
1642
1399enum { 1643enum {
1400 IPW_FW_ERROR_OK = 0, 1644 IPW_FW_ERROR_OK = 0,
1401 IPW_FW_ERROR_FAIL, 1645 IPW_FW_ERROR_FAIL,
@@ -1408,8 +1652,8 @@ enum {
1408 IPW_FW_ERROR_ALLOC_FAIL, 1652 IPW_FW_ERROR_ALLOC_FAIL,
1409 IPW_FW_ERROR_DMA_UNDERRUN, 1653 IPW_FW_ERROR_DMA_UNDERRUN,
1410 IPW_FW_ERROR_DMA_STATUS, 1654 IPW_FW_ERROR_DMA_STATUS,
1411 IPW_FW_ERROR_DINOSTATUS_ERROR, 1655 IPW_FW_ERROR_DINO_ERROR,
1412 IPW_FW_ERROR_EEPROMSTATUS_ERROR, 1656 IPW_FW_ERROR_EEPROM_ERROR,
1413 IPW_FW_ERROR_SYSASSERT, 1657 IPW_FW_ERROR_SYSASSERT,
1414 IPW_FW_ERROR_FATAL_ERROR 1658 IPW_FW_ERROR_FATAL_ERROR
1415}; 1659};
@@ -1425,6 +1669,8 @@ enum {
1425#define HC_IBSS_RECONF 4 1669#define HC_IBSS_RECONF 4
1426#define HC_DISASSOC_QUIET 5 1670#define HC_DISASSOC_QUIET 5
1427 1671
1672#define HC_QOS_SUPPORT_ASSOC 0x01
1673
1428#define IPW_RATE_CAPABILITIES 1 1674#define IPW_RATE_CAPABILITIES 1
1429#define IPW_RATE_CONNECT 0 1675#define IPW_RATE_CONNECT 0
1430 1676
@@ -1595,18 +1841,20 @@ enum {
1595 IPW_ORD_TABLE_7_LAST 1841 IPW_ORD_TABLE_7_LAST
1596}; 1842};
1597 1843
1598#define IPW_ORDINALS_TABLE_LOWER (CX2_SHARED_LOWER_BOUND + 0x500) 1844#define IPW_ERROR_LOG (IPW_SHARED_LOWER_BOUND + 0x410)
1599#define IPW_ORDINALS_TABLE_0 (CX2_SHARED_LOWER_BOUND + 0x180) 1845#define IPW_EVENT_LOG (IPW_SHARED_LOWER_BOUND + 0x414)
1600#define IPW_ORDINALS_TABLE_1 (CX2_SHARED_LOWER_BOUND + 0x184) 1846#define IPW_ORDINALS_TABLE_LOWER (IPW_SHARED_LOWER_BOUND + 0x500)
1601#define IPW_ORDINALS_TABLE_2 (CX2_SHARED_LOWER_BOUND + 0x188) 1847#define IPW_ORDINALS_TABLE_0 (IPW_SHARED_LOWER_BOUND + 0x180)
1602#define IPW_MEM_FIXED_OVERRIDE (CX2_SHARED_LOWER_BOUND + 0x41C) 1848#define IPW_ORDINALS_TABLE_1 (IPW_SHARED_LOWER_BOUND + 0x184)
1849#define IPW_ORDINALS_TABLE_2 (IPW_SHARED_LOWER_BOUND + 0x188)
1850#define IPW_MEM_FIXED_OVERRIDE (IPW_SHARED_LOWER_BOUND + 0x41C)
1603 1851
1604struct ipw_fixed_rate { 1852struct ipw_fixed_rate {
1605 u16 tx_rates; 1853 u16 tx_rates;
1606 u16 reserved; 1854 u16 reserved;
1607} __attribute__ ((packed)); 1855} __attribute__ ((packed));
1608 1856
1609#define CX2_INDIRECT_ADDR_MASK (~0x3ul) 1857#define IPW_INDIRECT_ADDR_MASK (~0x3ul)
1610 1858
1611struct host_cmd { 1859struct host_cmd {
1612 u8 cmd; 1860 u8 cmd;
@@ -1615,6 +1863,12 @@ struct host_cmd {
1615 u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH]; 1863 u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH];
1616} __attribute__ ((packed)); 1864} __attribute__ ((packed));
1617 1865
1866struct ipw_cmd_log {
1867 unsigned long jiffies;
1868 int retcode;
1869 struct host_cmd cmd;
1870};
1871
1618#define CFG_BT_COEXISTENCE_MIN 0x00 1872#define CFG_BT_COEXISTENCE_MIN 0x00
1619#define CFG_BT_COEXISTENCE_DEFER 0x02 1873#define CFG_BT_COEXISTENCE_DEFER 0x02
1620#define CFG_BT_COEXISTENCE_KILL 0x04 1874#define CFG_BT_COEXISTENCE_KILL 0x04
@@ -1643,15 +1897,6 @@ struct host_cmd {
1643#define REG_CHANNEL_MASK 0x00003FFF 1897#define REG_CHANNEL_MASK 0x00003FFF
1644#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff 1898#define IPW_IBSS_11B_DEFAULT_MASK 0x87ff
1645 1899
1646static const long ipw_frequencies[] = {
1647 2412, 2417, 2422, 2427,
1648 2432, 2437, 2442, 2447,
1649 2452, 2457, 2462, 2467,
1650 2472, 2484
1651};
1652
1653#define FREQ_COUNT ARRAY_SIZE(ipw_frequencies)
1654
1655#define IPW_MAX_CONFIG_RETRIES 10 1900#define IPW_MAX_CONFIG_RETRIES 10
1656 1901
1657static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr) 1902static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 7a17bb31fc89..f5d856db92a1 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -12,7 +12,6 @@
12#include <linux/netdevice.h> 12#include <linux/netdevice.h>
13#include <linux/wireless.h> 13#include <linux/wireless.h>
14#include <net/iw_handler.h> 14#include <net/iw_handler.h>
15#include <linux/version.h>
16 15
17#include "hermes.h" 16#include "hermes.h"
18 17
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index adc7499136dc..109a96d90007 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -18,7 +18,6 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/types.h> 22#include <linux/types.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
@@ -112,9 +111,10 @@ isl38xx_handle_wakeup(isl38xx_control_block *control_block,
112void 111void
113isl38xx_trigger_device(int asleep, void __iomem *device_base) 112isl38xx_trigger_device(int asleep, void __iomem *device_base)
114{ 113{
115 u32 reg, counter = 0; 114 u32 reg;
116 115
117#if VERBOSE > SHOW_ERROR_MESSAGES 116#if VERBOSE > SHOW_ERROR_MESSAGES
117 u32 counter = 0;
118 struct timeval current_time; 118 struct timeval current_time;
119 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n"); 119 DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
120#endif 120#endif
@@ -131,7 +131,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
131 current_time.tv_sec, (long)current_time.tv_usec, 131 current_time.tv_sec, (long)current_time.tv_usec,
132 readl(device_base + ISL38XX_CTRL_STAT_REG)); 132 readl(device_base + ISL38XX_CTRL_STAT_REG));
133#endif 133#endif
134 udelay(ISL38XX_WRITEIO_DELAY);
135 134
136 reg = readl(device_base + ISL38XX_INT_IDENT_REG); 135 reg = readl(device_base + ISL38XX_INT_IDENT_REG);
137 if (reg == 0xabadface) { 136 if (reg == 0xabadface) {
@@ -145,7 +144,9 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
145 while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG), 144 while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
146 (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) { 145 (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
147 udelay(ISL38XX_WRITEIO_DELAY); 146 udelay(ISL38XX_WRITEIO_DELAY);
147#if VERBOSE > SHOW_ERROR_MESSAGES
148 counter++; 148 counter++;
149#endif
149 } 150 }
150 151
151#if VERBOSE > SHOW_ERROR_MESSAGES 152#if VERBOSE > SHOW_ERROR_MESSAGES
@@ -153,10 +154,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
153 "%08li.%08li Device register read %08x\n", 154 "%08li.%08li Device register read %08x\n",
154 current_time.tv_sec, (long)current_time.tv_usec, 155 current_time.tv_sec, (long)current_time.tv_usec,
155 readl(device_base + ISL38XX_CTRL_STAT_REG)); 156 readl(device_base + ISL38XX_CTRL_STAT_REG));
156#endif
157 udelay(ISL38XX_WRITEIO_DELAY);
158
159#if VERBOSE > SHOW_ERROR_MESSAGES
160 do_gettimeofday(&current_time); 157 do_gettimeofday(&current_time);
161 DEBUG(SHOW_TRACING, 158 DEBUG(SHOW_TRACING,
162 "%08li.%08li Device asleep counter %i\n", 159 "%08li.%08li Device asleep counter %i\n",
@@ -171,7 +168,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
171 168
172 /* perform another read on the Device Status Register */ 169 /* perform another read on the Device Status Register */
173 reg = readl(device_base + ISL38XX_CTRL_STAT_REG); 170 reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
174 udelay(ISL38XX_WRITEIO_DELAY);
175 171
176#if VERBOSE > SHOW_ERROR_MESSAGES 172#if VERBOSE > SHOW_ERROR_MESSAGES
177 do_gettimeofday(&current_time); 173 do_gettimeofday(&current_time);
@@ -187,7 +183,6 @@ isl38xx_trigger_device(int asleep, void __iomem *device_base)
187 183
188 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE, 184 isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
189 ISL38XX_DEV_INT_REG); 185 ISL38XX_DEV_INT_REG);
190 udelay(ISL38XX_WRITEIO_DELAY);
191 } 186 }
192} 187}
193 188
diff --git a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
index e83e4912ab66..8af20980af8d 100644
--- a/drivers/net/wireless/prism54/isl_38xx.h
+++ b/drivers/net/wireless/prism54/isl_38xx.h
@@ -20,7 +20,6 @@
20#ifndef _ISL_38XX_H 20#ifndef _ISL_38XX_H
21#define _ISL_38XX_H 21#define _ISL_38XX_H
22 22
23#include <linux/version.h>
24#include <asm/io.h> 23#include <asm/io.h>
25#include <asm/byteorder.h> 24#include <asm/byteorder.h>
26 25
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 5c1a1adf1ff8..135a156db25d 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/version.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/kernel.h> 24#include <linux/kernel.h>
26#include <linux/if_arp.h> 25#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 78bdb359835e..5ddf29599032 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -19,7 +19,6 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/version.h>
23#include <linux/module.h> 22#include <linux/module.h>
24 23
25#include <linux/netdevice.h> 24#include <linux/netdevice.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index efbed4397951..07053165e4c5 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -23,7 +23,6 @@
23#ifndef _ISLPCI_DEV_H 23#ifndef _ISLPCI_DEV_H
24#define _ISLPCI_DEV_H 24#define _ISLPCI_DEV_H
25 25
26#include <linux/version.h>
27#include <linux/netdevice.h> 26#include <linux/netdevice.h>
28#include <linux/wireless.h> 27#include <linux/wireless.h>
29#include <net/iw_handler.h> 28#include <net/iw_handler.h>
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 3b49efa37ee5..33d64d2ee53f 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -17,7 +17,6 @@
17 * 17 *
18 */ 18 */
19 19
20#include <linux/version.h>
21#include <linux/module.h> 20#include <linux/module.h>
22 21
23#include <linux/pci.h> 22#include <linux/pci.h>
@@ -227,24 +226,23 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
227 priv->data_low_tx_full = 1; 226 priv->data_low_tx_full = 1;
228 } 227 }
229 228
229 /* set the transmission time */
230 ndev->trans_start = jiffies;
231 priv->statistics.tx_packets++;
232 priv->statistics.tx_bytes += skb->len;
233
230 /* trigger the device */ 234 /* trigger the device */
231 islpci_trigger(priv); 235 islpci_trigger(priv);
232 236
233 /* unlock the driver code */ 237 /* unlock the driver code */
234 spin_unlock_irqrestore(&priv->slock, flags); 238 spin_unlock_irqrestore(&priv->slock, flags);
235 239
236 /* set the transmission time */
237 ndev->trans_start = jiffies;
238 priv->statistics.tx_packets++;
239 priv->statistics.tx_bytes += skb->len;
240
241 return 0; 240 return 0;
242 241
243 drop_free: 242 drop_free:
244 priv->statistics.tx_dropped++; 243 priv->statistics.tx_dropped++;
245 spin_unlock_irqrestore(&priv->slock, flags); 244 spin_unlock_irqrestore(&priv->slock, flags);
246 dev_kfree_skb(skb); 245 dev_kfree_skb(skb);
247 skb = NULL;
248 return err; 246 return err;
249} 247}
250 248
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index dc040caab7d7..b41d666fea3c 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -18,7 +18,6 @@
18 * 18 *
19 */ 19 */
20 20
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/pci.h> 22#include <linux/pci.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 4b3c98f5c564..c822cad3333f 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4608,9 +4608,8 @@ wavelan_attach(void)
4608#endif 4608#endif
4609 4609
4610 /* Initialize the dev_link_t structure */ 4610 /* Initialize the dev_link_t structure */
4611 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); 4611 link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
4612 if (!link) return NULL; 4612 if (!link) return NULL;
4613 memset(link, 0, sizeof(struct dev_link_t));
4614 4613
4615 /* The io structure describes IO port mapping */ 4614 /* The io structure describes IO port mapping */
4616 link->io.NumPorts1 = 8; 4615 link->io.NumPorts1 = 8;
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 3f8c27f0871b..978fdc606781 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1965,10 +1965,9 @@ static dev_link_t *wl3501_attach(void)
1965 int ret; 1965 int ret;
1966 1966
1967 /* Initialize the dev_link_t structure */ 1967 /* Initialize the dev_link_t structure */
1968 link = kmalloc(sizeof(*link), GFP_KERNEL); 1968 link = kzalloc(sizeof(*link), GFP_KERNEL);
1969 if (!link) 1969 if (!link)
1970 goto out; 1970 goto out;
1971 memset(link, 0, sizeof(struct dev_link_t));
1972 1971
1973 /* The io structure describes IO port mapping */ 1972 /* The io structure describes IO port mapping */
1974 link->io.NumPorts1 = 16; 1973 link->io.NumPorts1 = 16;
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
index 6e6f42d01e64..4b48b31ec235 100644
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -78,17 +78,15 @@ static void parse_data(struct parport *port, int device, char *str)
78 u++; 78 u++;
79 } 79 }
80 if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) { 80 if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
81 if (info->mfr) 81 kfree(info->mfr);
82 kfree (info->mfr);
83 info->mfr = kstrdup(sep, GFP_KERNEL); 82 info->mfr = kstrdup(sep, GFP_KERNEL);
84 } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) { 83 } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
85 if (info->model) 84 kfree(info->model);
86 kfree (info->model);
87 info->model = kstrdup(sep, GFP_KERNEL); 85 info->model = kstrdup(sep, GFP_KERNEL);
88 } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) { 86 } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
89 int i; 87 int i;
90 if (info->class_name) 88
91 kfree (info->class_name); 89 kfree(info->class_name);
92 info->class_name = kstrdup(sep, GFP_KERNEL); 90 info->class_name = kstrdup(sep, GFP_KERNEL);
93 for (u = sep; *u; u++) 91 for (u = sep; *u; u++)
94 *u = toupper(*u); 92 *u = toupper(*u);
@@ -102,21 +100,22 @@ static void parse_data(struct parport *port, int device, char *str)
102 info->class = PARPORT_CLASS_OTHER; 100 info->class = PARPORT_CLASS_OTHER;
103 } else if (!strcmp(p, "CMD") || 101 } else if (!strcmp(p, "CMD") ||
104 !strcmp(p, "COMMAND SET")) { 102 !strcmp(p, "COMMAND SET")) {
105 if (info->cmdset) 103 kfree(info->cmdset);
106 kfree (info->cmdset);
107 info->cmdset = kstrdup(sep, GFP_KERNEL); 104 info->cmdset = kstrdup(sep, GFP_KERNEL);
108 /* if it speaks printer language, it's 105 /* if it speaks printer language, it's
109 probably a printer */ 106 probably a printer */
110 if (strstr(sep, "PJL") || strstr(sep, "PCL")) 107 if (strstr(sep, "PJL") || strstr(sep, "PCL"))
111 guessed_class = PARPORT_CLASS_PRINTER; 108 guessed_class = PARPORT_CLASS_PRINTER;
112 } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) { 109 } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
113 if (info->description) 110 kfree(info->description);
114 kfree (info->description);
115 info->description = kstrdup(sep, GFP_KERNEL); 111 info->description = kstrdup(sep, GFP_KERNEL);
116 } 112 }
117 } 113 }
118 rock_on: 114 rock_on:
119 if (q) p = q+1; else p=NULL; 115 if (q)
116 p = q + 1;
117 else
118 p = NULL;
120 } 119 }
121 120
122 /* If the device didn't tell us its class, maybe we have managed to 121 /* If the device didn't tell us its class, maybe we have managed to
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index ae7becf7efa5..9cb3ab156b09 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -202,16 +202,11 @@ static void free_port (struct parport *port)
202 list_del(&port->full_list); 202 list_del(&port->full_list);
203 spin_unlock(&full_list_lock); 203 spin_unlock(&full_list_lock);
204 for (d = 0; d < 5; d++) { 204 for (d = 0; d < 5; d++) {
205 if (port->probe_info[d].class_name) 205 kfree(port->probe_info[d].class_name);
206 kfree (port->probe_info[d].class_name); 206 kfree(port->probe_info[d].mfr);
207 if (port->probe_info[d].mfr) 207 kfree(port->probe_info[d].model);
208 kfree (port->probe_info[d].mfr); 208 kfree(port->probe_info[d].cmdset);
209 if (port->probe_info[d].model) 209 kfree(port->probe_info[d].description);
210 kfree (port->probe_info[d].model);
211 if (port->probe_info[d].cmdset)
212 kfree (port->probe_info[d].cmdset);
213 if (port->probe_info[d].description)
214 kfree (port->probe_info[d].description);
215 } 210 }
216 211
217 kfree(port->name); 212 kfree(port->name);
@@ -618,9 +613,9 @@ parport_register_device(struct parport *port, const char *name,
618 return tmp; 613 return tmp;
619 614
620 out_free_all: 615 out_free_all:
621 kfree (tmp->state); 616 kfree(tmp->state);
622 out_free_pardevice: 617 out_free_pardevice:
623 kfree (tmp); 618 kfree(tmp);
624 out: 619 out:
625 parport_put_port (port); 620 parport_put_port (port);
626 module_put(port->ops->owner); 621 module_put(port->ops->owner);
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 2a42add7f563..ea16805a153c 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -2,6 +2,8 @@
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/ioport.h> 3#include <linux/ioport.h>
4 4
5#include "pci.h"
6
5/* 7/*
6 * This interrupt-safe spinlock protects all accesses to PCI 8 * This interrupt-safe spinlock protects all accesses to PCI
7 * configuration space. 9 * configuration space.
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 93e39c4096a9..00b81a7bdd26 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -259,8 +259,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
259 sizeof(struct irq_routing_table)) / sizeof(struct irq_info); 259 sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
260 // Make sure I got at least one entry 260 // Make sure I got at least one entry
261 if (len == 0) { 261 if (len == 0) {
262 if (PCIIRQRoutingInfoLength != NULL) 262 kfree(PCIIRQRoutingInfoLength );
263 kfree(PCIIRQRoutingInfoLength );
264 return -1; 263 return -1;
265 } 264 }
266 265
@@ -275,8 +274,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
275 ctrl->pci_bus->number = tbus; 274 ctrl->pci_bus->number = tbus;
276 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work); 275 pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
277 if (!nobridge || (work == 0xffffffff)) { 276 if (!nobridge || (work == 0xffffffff)) {
278 if (PCIIRQRoutingInfoLength != NULL) 277 kfree(PCIIRQRoutingInfoLength );
279 kfree(PCIIRQRoutingInfoLength );
280 return 0; 278 return 0;
281 } 279 }
282 280
@@ -289,20 +287,17 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
289 dbg("Scan bus for Non Bridge: bus %d\n", tbus); 287 dbg("Scan bus for Non Bridge: bus %d\n", tbus);
290 if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) { 288 if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
291 *bus_num = tbus; 289 *bus_num = tbus;
292 if (PCIIRQRoutingInfoLength != NULL) 290 kfree(PCIIRQRoutingInfoLength );
293 kfree(PCIIRQRoutingInfoLength );
294 return 0; 291 return 0;
295 } 292 }
296 } else { 293 } else {
297 if (PCIIRQRoutingInfoLength != NULL) 294 kfree(PCIIRQRoutingInfoLength );
298 kfree(PCIIRQRoutingInfoLength );
299 return 0; 295 return 0;
300 } 296 }
301 297
302 } 298 }
303 } 299 }
304 if (PCIIRQRoutingInfoLength != NULL) 300 kfree(PCIIRQRoutingInfoLength );
305 kfree(PCIIRQRoutingInfoLength );
306 return -1; 301 return -1;
307} 302}
308 303
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 061ead21ef14..c42b68d3aa24 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -32,8 +32,6 @@
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <asm/semaphore.h>
36#include <asm/io.h>
37#include <linux/pcieport_if.h> 35#include <linux/pcieport_if.h>
38#include "pci_hotplug.h" 36#include "pci_hotplug.h"
39 37
@@ -42,6 +40,7 @@
42extern int pciehp_poll_mode; 40extern int pciehp_poll_mode;
43extern int pciehp_poll_time; 41extern int pciehp_poll_time;
44extern int pciehp_debug; 42extern int pciehp_debug;
43extern int pciehp_force;
45 44
46/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ 45/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
47#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) 46#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
@@ -49,39 +48,20 @@ extern int pciehp_debug;
49#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) 48#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
50#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) 49#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
51 50
52struct pci_func { 51struct hotplug_params {
53 struct pci_func *next; 52 u8 cache_line_size;
54 u8 bus; 53 u8 latency_timer;
55 u8 device; 54 u8 enable_serr;
56 u8 function; 55 u8 enable_perr;
57 u8 is_a_board;
58 u16 status;
59 u8 configured;
60 u8 switch_save;
61 u8 presence_save;
62 u32 base_length[0x06];
63 u8 base_type[0x06];
64 u16 reserved2;
65 u32 config_space[0x20];
66 struct pci_resource *mem_head;
67 struct pci_resource *p_mem_head;
68 struct pci_resource *io_head;
69 struct pci_resource *bus_head;
70 struct pci_dev* pci_dev;
71}; 56};
72 57
73struct slot { 58struct slot {
74 struct slot *next; 59 struct slot *next;
75 u8 bus; 60 u8 bus;
76 u8 device; 61 u8 device;
62 u16 status;
77 u32 number; 63 u32 number;
78 u8 is_a_board;
79 u8 configured;
80 u8 state; 64 u8 state;
81 u8 switch_save;
82 u8 presence_save;
83 u32 capabilities;
84 u16 reserved2;
85 struct timer_list task_event; 65 struct timer_list task_event;
86 u8 hp_slot; 66 u8 hp_slot;
87 struct controller *ctrl; 67 struct controller *ctrl;
@@ -90,42 +70,47 @@ struct slot {
90 struct list_head slot_list; 70 struct list_head slot_list;
91}; 71};
92 72
93struct pci_resource {
94 struct pci_resource * next;
95 u32 base;
96 u32 length;
97};
98
99struct event_info { 73struct event_info {
100 u32 event_type; 74 u32 event_type;
101 u8 hp_slot; 75 u8 hp_slot;
102}; 76};
103 77
78typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
79
80struct php_ctlr_state_s {
81 struct php_ctlr_state_s *pnext;
82 struct pci_dev *pci_dev;
83 unsigned int irq;
84 unsigned long flags; /* spinlock's */
85 u32 slot_device_offset;
86 u32 num_slots;
87 struct timer_list int_poll_timer; /* Added for poll event */
88 php_intr_callback_t attention_button_callback;
89 php_intr_callback_t switch_change_callback;
90 php_intr_callback_t presence_change_callback;
91 php_intr_callback_t power_fault_callback;
92 void *callback_instance_id;
93 struct ctrl_reg *creg; /* Ptr to controller register space */
94};
95
96#define MAX_EVENTS 10
104struct controller { 97struct controller {
105 struct controller *next; 98 struct controller *next;
106 struct semaphore crit_sect; /* critical section semaphore */ 99 struct semaphore crit_sect; /* critical section semaphore */
107 void *hpc_ctlr_handle; /* HPC controller handle */ 100 struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
108 int num_slots; /* Number of slots on ctlr */ 101 int num_slots; /* Number of slots on ctlr */
109 int slot_num_inc; /* 1 or -1 */ 102 int slot_num_inc; /* 1 or -1 */
110 struct pci_resource *mem_head;
111 struct pci_resource *p_mem_head;
112 struct pci_resource *io_head;
113 struct pci_resource *bus_head;
114 struct pci_dev *pci_dev; 103 struct pci_dev *pci_dev;
115 struct pci_bus *pci_bus; 104 struct pci_bus *pci_bus;
116 struct event_info event_queue[10]; 105 struct event_info event_queue[MAX_EVENTS];
117 struct slot *slot; 106 struct slot *slot;
118 struct hpc_ops *hpc_ops; 107 struct hpc_ops *hpc_ops;
119 wait_queue_head_t queue; /* sleep & wake process */ 108 wait_queue_head_t queue; /* sleep & wake process */
120 u8 next_event; 109 u8 next_event;
121 u8 seg;
122 u8 bus; 110 u8 bus;
123 u8 device; 111 u8 device;
124 u8 function; 112 u8 function;
125 u8 rev;
126 u8 slot_device_offset; 113 u8 slot_device_offset;
127 u8 add_support;
128 enum pci_bus_speed speed;
129 u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */ 114 u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */
130 u8 slot_bus; /* Bus where the slots handled by this controller sit */ 115 u8 slot_bus; /* Bus where the slots handled by this controller sit */
131 u8 ctrlcap; 116 u8 ctrlcap;
@@ -133,20 +118,6 @@ struct controller {
133 u8 cap_base; 118 u8 cap_base;
134}; 119};
135 120
136struct irq_mapping {
137 u8 barber_pole;
138 u8 valid_INT;
139 u8 interrupt[4];
140};
141
142struct resource_lists {
143 struct pci_resource *mem_head;
144 struct pci_resource *p_mem_head;
145 struct pci_resource *io_head;
146 struct pci_resource *bus_head;
147 struct irq_mapping *irqs;
148};
149
150#define INT_BUTTON_IGNORE 0 121#define INT_BUTTON_IGNORE 0
151#define INT_PRESENCE_ON 1 122#define INT_PRESENCE_ON 1
152#define INT_PRESENCE_OFF 2 123#define INT_PRESENCE_OFF 2
@@ -200,21 +171,14 @@ struct resource_lists {
200 * error Messages 171 * error Messages
201 */ 172 */
202#define msg_initialization_err "Initialization failure, error=%d\n" 173#define msg_initialization_err "Initialization failure, error=%d\n"
203#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
204#define msg_HPC_non_pcie "The PCI hot plug controller is not supported by this driver.\n"
205#define msg_HPC_not_supported "This system is not supported by this version of pciephd module. Upgrade to a newer version of pciehpd\n"
206#define msg_unable_to_save "Unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
207#define msg_button_on "PCI slot #%d - powering on due to button press.\n" 174#define msg_button_on "PCI slot #%d - powering on due to button press.\n"
208#define msg_button_off "PCI slot #%d - powering off due to button press.\n" 175#define msg_button_off "PCI slot #%d - powering off due to button press.\n"
209#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" 176#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
210#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" 177#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
211 178
212/* controller functions */ 179/* controller functions */
213extern int pciehprm_find_available_resources (struct controller *ctrl);
214extern int pciehp_event_start_thread (void); 180extern int pciehp_event_start_thread (void);
215extern void pciehp_event_stop_thread (void); 181extern void pciehp_event_stop_thread (void);
216extern struct pci_func *pciehp_slot_create (unsigned char busnumber);
217extern struct pci_func *pciehp_slot_find (unsigned char bus, unsigned char device, unsigned char index);
218extern int pciehp_enable_slot (struct slot *slot); 182extern int pciehp_enable_slot (struct slot *slot);
219extern int pciehp_disable_slot (struct slot *slot); 183extern int pciehp_disable_slot (struct slot *slot);
220 184
@@ -224,25 +188,17 @@ extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id);
224extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id); 188extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
225/* extern void long_delay (int delay); */ 189/* extern void long_delay (int delay); */
226 190
227/* resource functions */
228extern int pciehp_resource_sort_and_combine (struct pci_resource **head);
229
230/* pci functions */ 191/* pci functions */
231extern int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); 192extern int pciehp_configure_device (struct slot *p_slot);
232/*extern int pciehp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, struct slot *slot);*/ 193extern int pciehp_unconfigure_device (struct slot *p_slot);
233extern int pciehp_save_config (struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); 194extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev);
234extern int pciehp_save_used_resources (struct controller *ctrl, struct pci_func * func, int flag); 195extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
235extern int pciehp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot); 196 struct hotplug_params *hpp);
236extern void pciehp_destroy_board_resources (struct pci_func * func); 197
237extern int pciehp_return_board_resources (struct pci_func * func, struct resource_lists * resources);
238extern void pciehp_destroy_resource_list (struct resource_lists * resources);
239extern int pciehp_configure_device (struct controller* ctrl, struct pci_func* func);
240extern int pciehp_unconfigure_device (struct pci_func* func);
241 198
242 199
243/* Global variables */ 200/* Global variables */
244extern struct controller *pciehp_ctrl_list; 201extern struct controller *pciehp_ctrl_list;
245extern struct pci_func *pciehp_slot_list[256];
246 202
247/* Inline functions */ 203/* Inline functions */
248 204
@@ -252,12 +208,9 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
252 208
253 p_slot = ctrl->slot; 209 p_slot = ctrl->slot;
254 210
255 dbg("p_slot = %p\n", p_slot);
256
257 while (p_slot && (p_slot->device != device)) { 211 while (p_slot && (p_slot->device != device)) {
258 tmp_slot = p_slot; 212 tmp_slot = p_slot;
259 p_slot = p_slot->next; 213 p_slot = p_slot->next;
260 dbg("In while loop, p_slot = %p\n", p_slot);
261 } 214 }
262 if (p_slot == NULL) { 215 if (p_slot == NULL) {
263 err("ERROR: pciehp_find_slot device=0x%x\n", device); 216 err("ERROR: pciehp_find_slot device=0x%x\n", device);
@@ -273,7 +226,6 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
273 226
274 DECLARE_WAITQUEUE(wait, current); 227 DECLARE_WAITQUEUE(wait, current);
275 228
276 dbg("%s : start\n", __FUNCTION__);
277 add_wait_queue(&ctrl->queue, &wait); 229 add_wait_queue(&ctrl->queue, &wait);
278 if (!pciehp_poll_mode) 230 if (!pciehp_poll_mode)
279 /* Sleep for up to 1 second */ 231 /* Sleep for up to 1 second */
@@ -285,19 +237,9 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl)
285 if (signal_pending(current)) 237 if (signal_pending(current))
286 retval = -EINTR; 238 retval = -EINTR;
287 239
288 dbg("%s : end\n", __FUNCTION__);
289 return retval; 240 return retval;
290} 241}
291 242
292/* Puts node back in the resource list pointed to by head */
293static inline void return_resource(struct pci_resource **head, struct pci_resource *node)
294{
295 if (!node || !head)
296 return;
297 node->next = *head;
298 *head = node;
299}
300
301#define SLOT_NAME_SIZE 10 243#define SLOT_NAME_SIZE 10
302 244
303static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) 245static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot)
@@ -311,14 +253,7 @@ enum php_ctlr_type {
311 ACPI 253 ACPI
312}; 254};
313 255
314typedef u8(*php_intr_callback_t) (unsigned int change_id, void *instance_id); 256int pcie_init(struct controller *ctrl, struct pcie_device *dev);
315
316int pcie_init(struct controller *ctrl, struct pcie_device *dev,
317 php_intr_callback_t attention_button_callback,
318 php_intr_callback_t switch_change_callback,
319 php_intr_callback_t presence_change_callback,
320 php_intr_callback_t power_fault_callback);
321
322 257
323/* This has no meaning for PCI Express, as there is only 1 slot per port */ 258/* This has no meaning for PCI Express, as there is only 1 slot per port */
324int pcie_get_ctlr_slot_config(struct controller *ctrl, 259int pcie_get_ctlr_slot_config(struct controller *ctrl,
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index cafc7eadcf80..8df704860348 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -27,27 +27,20 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/moduleparam.h> 31#include <linux/moduleparam.h>
33#include <linux/kernel.h> 32#include <linux/kernel.h>
34#include <linux/types.h> 33#include <linux/types.h>
35#include <linux/proc_fs.h>
36#include <linux/slab.h>
37#include <linux/workqueue.h>
38#include <linux/pci.h> 34#include <linux/pci.h>
39#include <linux/init.h>
40#include <asm/uaccess.h>
41#include "pciehp.h" 35#include "pciehp.h"
42#include "pciehprm.h"
43#include <linux/interrupt.h> 36#include <linux/interrupt.h>
44 37
45/* Global variables */ 38/* Global variables */
46int pciehp_debug; 39int pciehp_debug;
47int pciehp_poll_mode; 40int pciehp_poll_mode;
48int pciehp_poll_time; 41int pciehp_poll_time;
42int pciehp_force;
49struct controller *pciehp_ctrl_list; 43struct controller *pciehp_ctrl_list;
50struct pci_func *pciehp_slot_list[256];
51 44
52#define DRIVER_VERSION "0.4" 45#define DRIVER_VERSION "0.4"
53#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" 46#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
@@ -60,9 +53,11 @@ MODULE_LICENSE("GPL");
60module_param(pciehp_debug, bool, 0644); 53module_param(pciehp_debug, bool, 0644);
61module_param(pciehp_poll_mode, bool, 0644); 54module_param(pciehp_poll_mode, bool, 0644);
62module_param(pciehp_poll_time, int, 0644); 55module_param(pciehp_poll_time, int, 0644);
56module_param(pciehp_force, bool, 0644);
63MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); 57MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
64MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); 58MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
65MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); 59MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
60MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
66 61
67#define PCIE_MODULE_NAME "pciehp" 62#define PCIE_MODULE_NAME "pciehp"
68 63
@@ -114,8 +109,6 @@ static int init_slots(struct controller *ctrl)
114 u32 slot_number; 109 u32 slot_number;
115 int result = -ENOMEM; 110 int result = -ENOMEM;
116 111
117 dbg("%s\n",__FUNCTION__);
118
119 number_of_slots = ctrl->num_slots; 112 number_of_slots = ctrl->num_slots;
120 slot_device = ctrl->slot_device_offset; 113 slot_device = ctrl->slot_device_offset;
121 slot_number = ctrl->first_slot; 114 slot_number = ctrl->first_slot;
@@ -370,7 +363,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
370 u8 value; 363 u8 value;
371 struct pci_dev *pdev; 364 struct pci_dev *pdev;
372 365
373 dbg("%s: Called by hp_drv\n", __FUNCTION__);
374 ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL); 366 ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
375 if (!ctrl) { 367 if (!ctrl) {
376 err("%s : out of memory\n", __FUNCTION__); 368 err("%s : out of memory\n", __FUNCTION__);
@@ -378,22 +370,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
378 } 370 }
379 memset(ctrl, 0, sizeof(struct controller)); 371 memset(ctrl, 0, sizeof(struct controller));
380 372
381 dbg("%s: DRV_thread pid = %d\n", __FUNCTION__, current->pid);
382
383 pdev = dev->port; 373 pdev = dev->port;
374 ctrl->pci_dev = pdev;
384 375
385 rc = pcie_init(ctrl, dev, 376 rc = pcie_init(ctrl, dev);
386 (php_intr_callback_t) pciehp_handle_attention_button,
387 (php_intr_callback_t) pciehp_handle_switch_change,
388 (php_intr_callback_t) pciehp_handle_presence_change,
389 (php_intr_callback_t) pciehp_handle_power_fault);
390 if (rc) { 377 if (rc) {
391 dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME); 378 dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
392 goto err_out_free_ctrl; 379 goto err_out_free_ctrl;
393 } 380 }
394 381
395 ctrl->pci_dev = pdev;
396
397 pci_set_drvdata(pdev, ctrl); 382 pci_set_drvdata(pdev, ctrl);
398 383
399 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); 384 ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL);
@@ -402,7 +387,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
402 rc = -ENOMEM; 387 rc = -ENOMEM;
403 goto err_out_unmap_mmio_region; 388 goto err_out_unmap_mmio_region;
404 } 389 }
405 dbg("%s: ctrl->pci_bus %p\n", __FUNCTION__, ctrl->pci_bus);
406 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); 390 memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
407 ctrl->bus = pdev->bus->number; /* ctrl bus */ 391 ctrl->bus = pdev->bus->number; /* ctrl bus */
408 ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */ 392 ctrl->slot_bus = pdev->subordinate->number; /* bus controlled by this HPC */
@@ -424,25 +408,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
424 first_device_num = ctrl->slot_device_offset; 408 first_device_num = ctrl->slot_device_offset;
425 num_ctlr_slots = ctrl->num_slots; 409 num_ctlr_slots = ctrl->num_slots;
426 410
427 /* Store PCI Config Space for all devices on this bus */
428 dbg("%s: Before calling pciehp_save_config, ctrl->bus %x,ctrl->slot_bus %x\n",
429 __FUNCTION__,ctrl->bus, ctrl->slot_bus);
430 rc = pciehp_save_config(ctrl, ctrl->slot_bus, num_ctlr_slots, first_device_num);
431 if (rc) {
432 err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
433 goto err_out_free_ctrl_bus;
434 }
435
436 /* Get IO, memory, and IRQ resources for new devices */
437 rc = pciehprm_find_available_resources(ctrl);
438 ctrl->add_support = !rc;
439
440 if (rc) {
441 dbg("pciehprm_find_available_resources = %#x\n", rc);
442 err("unable to locate PCI configuration resources for hot plug add.\n");
443 goto err_out_free_ctrl_bus;
444 }
445
446 /* Setup the slot information structures */ 411 /* Setup the slot information structures */
447 rc = init_slots(ctrl); 412 rc = init_slots(ctrl);
448 if (rc) { 413 if (rc) {
@@ -451,7 +416,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
451 } 416 }
452 417
453 t_slot = pciehp_find_slot(ctrl, first_device_num); 418 t_slot = pciehp_find_slot(ctrl, first_device_num);
454 dbg("%s: t_slot %p\n", __FUNCTION__, t_slot);
455 419
456 /* Finish setting up the hot plug ctrl device */ 420 /* Finish setting up the hot plug ctrl device */
457 ctrl->next_event = 0; 421 ctrl->next_event = 0;
@@ -468,7 +432,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
468 down(&ctrl->crit_sect); 432 down(&ctrl->crit_sect);
469 433
470 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ 434 t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */
471 dbg("%s: adpater value %x\n", __FUNCTION__, value);
472 435
473 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { 436 if ((POWER_CTRL(ctrl->ctrlcap)) && !value) {
474 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ 437 rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/
@@ -501,7 +464,6 @@ err_out_none:
501 464
502static int pcie_start_thread(void) 465static int pcie_start_thread(void)
503{ 466{
504 int loop;
505 int retval = 0; 467 int retval = 0;
506 468
507 dbg("Initialize + Start the notification/polling mechanism \n"); 469 dbg("Initialize + Start the notification/polling mechanism \n");
@@ -512,32 +474,11 @@ static int pcie_start_thread(void)
512 return retval; 474 return retval;
513 } 475 }
514 476
515 dbg("Initialize slot lists\n");
516 /* One slot list for each bus in the system */
517 for (loop = 0; loop < 256; loop++) {
518 pciehp_slot_list[loop] = NULL;
519 }
520
521 return retval; 477 return retval;
522} 478}
523 479
524static inline void __exit
525free_pciehp_res(struct pci_resource *res)
526{
527 struct pci_resource *tres;
528
529 while (res) {
530 tres = res;
531 res = res->next;
532 kfree(tres);
533 }
534}
535
536static void __exit unload_pciehpd(void) 480static void __exit unload_pciehpd(void)
537{ 481{
538 struct pci_func *next;
539 struct pci_func *TempSlot;
540 int loop;
541 struct controller *ctrl; 482 struct controller *ctrl;
542 struct controller *tctrl; 483 struct controller *tctrl;
543 484
@@ -546,11 +487,6 @@ static void __exit unload_pciehpd(void)
546 while (ctrl) { 487 while (ctrl) {
547 cleanup_slots(ctrl); 488 cleanup_slots(ctrl);
548 489
549 free_pciehp_res(ctrl->io_head);
550 free_pciehp_res(ctrl->mem_head);
551 free_pciehp_res(ctrl->p_mem_head);
552 free_pciehp_res(ctrl->bus_head);
553
554 kfree (ctrl->pci_bus); 490 kfree (ctrl->pci_bus);
555 491
556 ctrl->hpc_ops->release_ctlr(ctrl); 492 ctrl->hpc_ops->release_ctlr(ctrl);
@@ -561,20 +497,6 @@ static void __exit unload_pciehpd(void)
561 kfree(tctrl); 497 kfree(tctrl);
562 } 498 }
563 499
564 for (loop = 0; loop < 256; loop++) {
565 next = pciehp_slot_list[loop];
566 while (next != NULL) {
567 free_pciehp_res(next->io_head);
568 free_pciehp_res(next->mem_head);
569 free_pciehp_res(next->p_mem_head);
570 free_pciehp_res(next->bus_head);
571
572 TempSlot = next;
573 next = next->next;
574 kfree(TempSlot);
575 }
576 }
577
578 /* Stop the notification mechanism */ 500 /* Stop the notification mechanism */
579 pciehp_event_stop_thread(); 501 pciehp_event_stop_thread();
580 502
@@ -639,21 +561,16 @@ static int __init pcied_init(void)
639 if (retval) 561 if (retval)
640 goto error_hpc_init; 562 goto error_hpc_init;
641 563
642 retval = pciehprm_init(PCI); 564 retval = pcie_port_service_register(&hpdriver_portdrv);
643 if (!retval) { 565 dbg("pcie_port_service_register = %d\n", retval);
644 retval = pcie_port_service_register(&hpdriver_portdrv); 566 info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
645 dbg("pcie_port_service_register = %d\n", retval); 567 if (retval)
646 info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); 568 dbg("%s: Failure to register service\n", __FUNCTION__);
647 if (retval)
648 dbg("%s: Failure to register service\n", __FUNCTION__);
649 }
650 569
651error_hpc_init: 570error_hpc_init:
652 if (retval) { 571 if (retval) {
653 pciehprm_cleanup();
654 pciehp_event_stop_thread(); 572 pciehp_event_stop_thread();
655 } else 573 };
656 pciehprm_print_pirt();
657 574
658 return retval; 575 return retval;
659} 576}
@@ -663,9 +580,6 @@ static void __exit pcied_cleanup(void)
663 dbg("unload_pciehpd()\n"); 580 dbg("unload_pciehpd()\n");
664 unload_pciehpd(); 581 unload_pciehpd();
665 582
666 pciehprm_cleanup();
667
668 dbg("pcie_port_service_unregister\n");
669 pcie_port_service_unregister(&hpdriver_portdrv); 583 pcie_port_service_unregister(&hpdriver_portdrv);
670 584
671 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); 585 info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n");
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 898f6da6f0de..5e582eca21d8 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -27,25 +27,14 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/interrupt.h>
37#include <linux/delay.h>
38#include <linux/wait.h>
39#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
40#include <linux/pci.h> 34#include <linux/pci.h>
41#include "../pci.h" 35#include "../pci.h"
42#include "pciehp.h" 36#include "pciehp.h"
43#include "pciehprm.h"
44 37
45static u32 configure_new_device(struct controller *ctrl, struct pci_func *func,
46 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
47static int configure_new_function( struct controller *ctrl, struct pci_func *func,
48 u8 behind_bridge, struct resource_lists *resources, u8 bridge_bus, u8 bridge_dev);
49static void interrupt_event_handler(struct controller *ctrl); 38static void interrupt_event_handler(struct controller *ctrl);
50 39
51static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ 40static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
@@ -60,22 +49,18 @@ u8 pciehp_handle_attention_button(u8 hp_slot, void *inst_id)
60 struct slot *p_slot; 49 struct slot *p_slot;
61 u8 rc = 0; 50 u8 rc = 0;
62 u8 getstatus; 51 u8 getstatus;
63 struct pci_func *func;
64 struct event_info *taskInfo; 52 struct event_info *taskInfo;
65 53
66 /* Attention Button Change */ 54 /* Attention Button Change */
67 dbg("pciehp: Attention button interrupt received.\n"); 55 dbg("pciehp: Attention button interrupt received.\n");
68 56
69 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
70
71 /* This is the structure that tells the worker thread what to do */ 57 /* This is the structure that tells the worker thread what to do */
72 taskInfo = &(ctrl->event_queue[ctrl->next_event]); 58 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
73 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 59 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
74 60
75 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
76 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 61 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
77 62
78 ctrl->next_event = (ctrl->next_event + 1) % 10; 63 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
79 taskInfo->hp_slot = hp_slot; 64 taskInfo->hp_slot = hp_slot;
80 65
81 rc++; 66 rc++;
@@ -117,24 +102,20 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
117 struct slot *p_slot; 102 struct slot *p_slot;
118 u8 rc = 0; 103 u8 rc = 0;
119 u8 getstatus; 104 u8 getstatus;
120 struct pci_func *func;
121 struct event_info *taskInfo; 105 struct event_info *taskInfo;
122 106
123 /* Switch Change */ 107 /* Switch Change */
124 dbg("pciehp: Switch interrupt received.\n"); 108 dbg("pciehp: Switch interrupt received.\n");
125 109
126 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
127
128 /* This is the structure that tells the worker thread 110 /* This is the structure that tells the worker thread
129 * what to do 111 * what to do
130 */ 112 */
131 taskInfo = &(ctrl->event_queue[ctrl->next_event]); 113 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
132 ctrl->next_event = (ctrl->next_event + 1) % 10; 114 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
133 taskInfo->hp_slot = hp_slot; 115 taskInfo->hp_slot = hp_slot;
134 116
135 rc++; 117 rc++;
136 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 118 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
137 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
138 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 119 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
139 120
140 if (getstatus) { 121 if (getstatus) {
@@ -142,14 +123,12 @@ u8 pciehp_handle_switch_change(u8 hp_slot, void *inst_id)
142 * Switch opened 123 * Switch opened
143 */ 124 */
144 info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot); 125 info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
145 func->switch_save = 0;
146 taskInfo->event_type = INT_SWITCH_OPEN; 126 taskInfo->event_type = INT_SWITCH_OPEN;
147 } else { 127 } else {
148 /* 128 /*
149 * Switch closed 129 * Switch closed
150 */ 130 */
151 info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot); 131 info("Latch close on Slot(%d)\n", ctrl->first_slot + hp_slot);
152 func->switch_save = 0x10;
153 taskInfo->event_type = INT_SWITCH_CLOSE; 132 taskInfo->event_type = INT_SWITCH_CLOSE;
154 } 133 }
155 134
@@ -163,20 +142,17 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
163{ 142{
164 struct controller *ctrl = (struct controller *) inst_id; 143 struct controller *ctrl = (struct controller *) inst_id;
165 struct slot *p_slot; 144 struct slot *p_slot;
166 u8 rc = 0; 145 u8 presence_save, rc = 0;
167 struct pci_func *func;
168 struct event_info *taskInfo; 146 struct event_info *taskInfo;
169 147
170 /* Presence Change */ 148 /* Presence Change */
171 dbg("pciehp: Presence/Notify input change.\n"); 149 dbg("pciehp: Presence/Notify input change.\n");
172 150
173 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
174
175 /* This is the structure that tells the worker thread 151 /* This is the structure that tells the worker thread
176 * what to do 152 * what to do
177 */ 153 */
178 taskInfo = &(ctrl->event_queue[ctrl->next_event]); 154 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
179 ctrl->next_event = (ctrl->next_event + 1) % 10; 155 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
180 taskInfo->hp_slot = hp_slot; 156 taskInfo->hp_slot = hp_slot;
181 157
182 rc++; 158 rc++;
@@ -185,8 +161,8 @@ u8 pciehp_handle_presence_change(u8 hp_slot, void *inst_id)
185 /* Switch is open, assume a presence change 161 /* Switch is open, assume a presence change
186 * Save the presence state 162 * Save the presence state
187 */ 163 */
188 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save)); 164 p_slot->hpc_ops->get_adapter_status(p_slot, &presence_save);
189 if (func->presence_save) { 165 if (presence_save) {
190 /* 166 /*
191 * Card Present 167 * Card Present
192 */ 168 */
@@ -211,19 +187,16 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
211 struct controller *ctrl = (struct controller *) inst_id; 187 struct controller *ctrl = (struct controller *) inst_id;
212 struct slot *p_slot; 188 struct slot *p_slot;
213 u8 rc = 0; 189 u8 rc = 0;
214 struct pci_func *func;
215 struct event_info *taskInfo; 190 struct event_info *taskInfo;
216 191
217 /* power fault */ 192 /* power fault */
218 dbg("pciehp: Power fault interrupt received.\n"); 193 dbg("pciehp: Power fault interrupt received.\n");
219 194
220 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
221
222 /* this is the structure that tells the worker thread 195 /* this is the structure that tells the worker thread
223 * what to do 196 * what to do
224 */ 197 */
225 taskInfo = &(ctrl->event_queue[ctrl->next_event]); 198 taskInfo = &(ctrl->event_queue[ctrl->next_event]);
226 ctrl->next_event = (ctrl->next_event + 1) % 10; 199 ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS;
227 taskInfo->hp_slot = hp_slot; 200 taskInfo->hp_slot = hp_slot;
228 201
229 rc++; 202 rc++;
@@ -234,7 +207,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
234 * power fault Cleared 207 * power fault Cleared
235 */ 208 */
236 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot); 209 info("Power fault cleared on Slot(%d)\n", ctrl->first_slot + hp_slot);
237 func->status = 0x00; 210 p_slot->status = 0x00;
238 taskInfo->event_type = INT_POWER_FAULT_CLEAR; 211 taskInfo->event_type = INT_POWER_FAULT_CLEAR;
239 } else { 212 } else {
240 /* 213 /*
@@ -243,7 +216,7 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
243 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot); 216 info("Power fault on Slot(%d)\n", ctrl->first_slot + hp_slot);
244 taskInfo->event_type = INT_POWER_FAULT; 217 taskInfo->event_type = INT_POWER_FAULT;
245 /* set power fault status for this board */ 218 /* set power fault status for this board */
246 func->status = 0xFF; 219 p_slot->status = 0xFF;
247 info("power fault bit %x set\n", hp_slot); 220 info("power fault bit %x set\n", hp_slot);
248 } 221 }
249 if (rc) 222 if (rc)
@@ -252,810 +225,6 @@ u8 pciehp_handle_power_fault(u8 hp_slot, void *inst_id)
252 return rc; 225 return rc;
253} 226}
254 227
255
256/**
257 * sort_by_size: sort nodes by their length, smallest first.
258 *
259 * @head: list to sort
260 */
261static int sort_by_size(struct pci_resource **head)
262{
263 struct pci_resource *current_res;
264 struct pci_resource *next_res;
265 int out_of_order = 1;
266
267 if (!(*head))
268 return 1;
269
270 if (!((*head)->next))
271 return 0;
272
273 while (out_of_order) {
274 out_of_order = 0;
275
276 /* Special case for swapping list head */
277 if (((*head)->next) &&
278 ((*head)->length > (*head)->next->length)) {
279 out_of_order++;
280 current_res = *head;
281 *head = (*head)->next;
282 current_res->next = (*head)->next;
283 (*head)->next = current_res;
284 }
285
286 current_res = *head;
287
288 while (current_res->next && current_res->next->next) {
289 if (current_res->next->length > current_res->next->next->length) {
290 out_of_order++;
291 next_res = current_res->next;
292 current_res->next = current_res->next->next;
293 current_res = current_res->next;
294 next_res->next = current_res->next;
295 current_res->next = next_res;
296 } else
297 current_res = current_res->next;
298 }
299 } /* End of out_of_order loop */
300
301 return 0;
302}
303
304
305/*
306 * sort_by_max_size
307 *
308 * Sorts nodes on the list by their length.
309 * Largest first.
310 *
311 */
312static int sort_by_max_size(struct pci_resource **head)
313{
314 struct pci_resource *current_res;
315 struct pci_resource *next_res;
316 int out_of_order = 1;
317
318 if (!(*head))
319 return 1;
320
321 if (!((*head)->next))
322 return 0;
323
324 while (out_of_order) {
325 out_of_order = 0;
326
327 /* Special case for swapping list head */
328 if (((*head)->next) &&
329 ((*head)->length < (*head)->next->length)) {
330 out_of_order++;
331 current_res = *head;
332 *head = (*head)->next;
333 current_res->next = (*head)->next;
334 (*head)->next = current_res;
335 }
336
337 current_res = *head;
338
339 while (current_res->next && current_res->next->next) {
340 if (current_res->next->length < current_res->next->next->length) {
341 out_of_order++;
342 next_res = current_res->next;
343 current_res->next = current_res->next->next;
344 current_res = current_res->next;
345 next_res->next = current_res->next;
346 current_res->next = next_res;
347 } else
348 current_res = current_res->next;
349 }
350 } /* End of out_of_order loop */
351
352 return 0;
353}
354
355
356/**
357 * do_pre_bridge_resource_split: return one unused resource node
358 * @head: list to scan
359 *
360 */
361static struct pci_resource *
362do_pre_bridge_resource_split(struct pci_resource **head,
363 struct pci_resource **orig_head, u32 alignment)
364{
365 struct pci_resource *prevnode = NULL;
366 struct pci_resource *node;
367 struct pci_resource *split_node;
368 u32 rc;
369 u32 temp_dword;
370 dbg("do_pre_bridge_resource_split\n");
371
372 if (!(*head) || !(*orig_head))
373 return NULL;
374
375 rc = pciehp_resource_sort_and_combine(head);
376
377 if (rc)
378 return NULL;
379
380 if ((*head)->base != (*orig_head)->base)
381 return NULL;
382
383 if ((*head)->length == (*orig_head)->length)
384 return NULL;
385
386
387 /* If we got here, there the bridge requires some of the resource, but
388 * we may be able to split some off of the front
389 */
390 node = *head;
391
392 if (node->length & (alignment -1)) {
393 /* this one isn't an aligned length, so we'll make a new entry
394 * and split it up.
395 */
396 split_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
397
398 if (!split_node)
399 return NULL;
400
401 temp_dword = (node->length | (alignment-1)) + 1 - alignment;
402
403 split_node->base = node->base;
404 split_node->length = temp_dword;
405
406 node->length -= temp_dword;
407 node->base += split_node->length;
408
409 /* Put it in the list */
410 *head = split_node;
411 split_node->next = node;
412 }
413
414 if (node->length < alignment)
415 return NULL;
416
417 /* Now unlink it */
418 if (*head == node) {
419 *head = node->next;
420 } else {
421 prevnode = *head;
422 while (prevnode->next != node)
423 prevnode = prevnode->next;
424
425 prevnode->next = node->next;
426 }
427 node->next = NULL;
428
429 return node;
430}
431
432
433/**
434 * do_bridge_resource_split: return one unused resource node
435 * @head: list to scan
436 *
437 */
438static struct pci_resource *
439do_bridge_resource_split(struct pci_resource **head, u32 alignment)
440{
441 struct pci_resource *prevnode = NULL;
442 struct pci_resource *node;
443 u32 rc;
444 u32 temp_dword;
445
446 if (!(*head))
447 return NULL;
448
449 rc = pciehp_resource_sort_and_combine(head);
450
451 if (rc)
452 return NULL;
453
454 node = *head;
455
456 while (node->next) {
457 prevnode = node;
458 node = node->next;
459 kfree(prevnode);
460 }
461
462 if (node->length < alignment) {
463 kfree(node);
464 return NULL;
465 }
466
467 if (node->base & (alignment - 1)) {
468 /* Short circuit if adjusted size is too small */
469 temp_dword = (node->base | (alignment-1)) + 1;
470 if ((node->length - (temp_dword - node->base)) < alignment) {
471 kfree(node);
472 return NULL;
473 }
474
475 node->length -= (temp_dword - node->base);
476 node->base = temp_dword;
477 }
478
479 if (node->length & (alignment - 1)) {
480 /* There's stuff in use after this node */
481 kfree(node);
482 return NULL;
483 }
484
485 return node;
486}
487
488
489/*
490 * get_io_resource
491 *
492 * this function sorts the resource list by size and then
493 * returns the first node of "size" length that is not in the
494 * ISA aliasing window. If it finds a node larger than "size"
495 * it will split it up.
496 *
497 * size must be a power of two.
498 */
499static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size)
500{
501 struct pci_resource *prevnode;
502 struct pci_resource *node;
503 struct pci_resource *split_node = NULL;
504 u32 temp_dword;
505
506 if (!(*head))
507 return NULL;
508
509 if ( pciehp_resource_sort_and_combine(head) )
510 return NULL;
511
512 if ( sort_by_size(head) )
513 return NULL;
514
515 for (node = *head; node; node = node->next) {
516 if (node->length < size)
517 continue;
518
519 if (node->base & (size - 1)) {
520 /* this one isn't base aligned properly
521 so we'll make a new entry and split it up */
522 temp_dword = (node->base | (size-1)) + 1;
523
524 /*/ Short circuit if adjusted size is too small */
525 if ((node->length - (temp_dword - node->base)) < size)
526 continue;
527
528 split_node = kmalloc(sizeof(struct pci_resource),
529 GFP_KERNEL);
530
531 if (!split_node)
532 return NULL;
533
534 split_node->base = node->base;
535 split_node->length = temp_dword - node->base;
536 node->base = temp_dword;
537 node->length -= split_node->length;
538
539 /* Put it in the list */
540 split_node->next = node->next;
541 node->next = split_node;
542 } /* End of non-aligned base */
543
544 /* Don't need to check if too small since we already did */
545 if (node->length > size) {
546 /* this one is longer than we need
547 so we'll make a new entry and split it up */
548 split_node = kmalloc(sizeof(struct pci_resource),
549 GFP_KERNEL);
550
551 if (!split_node)
552 return NULL;
553
554 split_node->base = node->base + size;
555 split_node->length = node->length - size;
556 node->length = size;
557
558 /* Put it in the list */
559 split_node->next = node->next;
560 node->next = split_node;
561 } /* End of too big on top end */
562
563 /* For IO make sure it's not in the ISA aliasing space */
564 if (node->base & 0x300L)
565 continue;
566
567 /* If we got here, then it is the right size
568 Now take it out of the list */
569 if (*head == node) {
570 *head = node->next;
571 } else {
572 prevnode = *head;
573 while (prevnode->next != node)
574 prevnode = prevnode->next;
575
576 prevnode->next = node->next;
577 }
578 node->next = NULL;
579 /* Stop looping */
580 break;
581 }
582
583 return node;
584}
585
586
587/*
588 * get_max_resource
589 *
590 * Gets the largest node that is at least "size" big from the
591 * list pointed to by head. It aligns the node on top and bottom
592 * to "size" alignment before returning it.
593 * J.I. modified to put max size limits of; 64M->32M->16M->8M->4M->1M
594 * This is needed to avoid allocating entire ACPI _CRS res to one child bridge/slot.
595 */
596static struct pci_resource *get_max_resource(struct pci_resource **head, u32 size)
597{
598 struct pci_resource *max;
599 struct pci_resource *temp;
600 struct pci_resource *split_node;
601 u32 temp_dword;
602 u32 max_size[] = { 0x4000000, 0x2000000, 0x1000000, 0x0800000, 0x0400000, 0x0200000, 0x0100000, 0x00 };
603 int i;
604
605 if (!(*head))
606 return NULL;
607
608 if (pciehp_resource_sort_and_combine(head))
609 return NULL;
610
611 if (sort_by_max_size(head))
612 return NULL;
613
614 for (max = *head;max; max = max->next) {
615
616 /* If not big enough we could probably just bail,
617 instead we'll continue to the next. */
618 if (max->length < size)
619 continue;
620
621 if (max->base & (size - 1)) {
622 /* this one isn't base aligned properly
623 so we'll make a new entry and split it up */
624 temp_dword = (max->base | (size-1)) + 1;
625
626 /* Short circuit if adjusted size is too small */
627 if ((max->length - (temp_dword - max->base)) < size)
628 continue;
629
630 split_node = kmalloc(sizeof(struct pci_resource),
631 GFP_KERNEL);
632
633 if (!split_node)
634 return NULL;
635
636 split_node->base = max->base;
637 split_node->length = temp_dword - max->base;
638 max->base = temp_dword;
639 max->length -= split_node->length;
640
641 /* Put it next in the list */
642 split_node->next = max->next;
643 max->next = split_node;
644 }
645
646 if ((max->base + max->length) & (size - 1)) {
647 /* this one isn't end aligned properly at the top
648 so we'll make a new entry and split it up */
649 split_node = kmalloc(sizeof(struct pci_resource),
650 GFP_KERNEL);
651
652 if (!split_node)
653 return NULL;
654 temp_dword = ((max->base + max->length) & ~(size - 1));
655 split_node->base = temp_dword;
656 split_node->length = max->length + max->base
657 - split_node->base;
658 max->length -= split_node->length;
659
660 /* Put it in the list */
661 split_node->next = max->next;
662 max->next = split_node;
663 }
664
665 /* Make sure it didn't shrink too much when we aligned it */
666 if (max->length < size)
667 continue;
668
669 for ( i = 0; max_size[i] > size; i++) {
670 if (max->length > max_size[i]) {
671 split_node = kmalloc(sizeof(struct pci_resource),
672 GFP_KERNEL);
673 if (!split_node)
674 break; /* return NULL; */
675 split_node->base = max->base + max_size[i];
676 split_node->length = max->length - max_size[i];
677 max->length = max_size[i];
678 /* Put it next in the list */
679 split_node->next = max->next;
680 max->next = split_node;
681 break;
682 }
683 }
684
685 /* Now take it out of the list */
686 temp = (struct pci_resource*) *head;
687 if (temp == max) {
688 *head = max->next;
689 } else {
690 while (temp && temp->next != max) {
691 temp = temp->next;
692 }
693
694 temp->next = max->next;
695 }
696
697 max->next = NULL;
698 return max;
699 }
700
701 /* If we get here, we couldn't find one */
702 return NULL;
703}
704
705
706/*
707 * get_resource
708 *
709 * this function sorts the resource list by size and then
710 * returns the first node of "size" length. If it finds a node
711 * larger than "size" it will split it up.
712 *
713 * size must be a power of two.
714 */
715static struct pci_resource *get_resource(struct pci_resource **head, u32 size)
716{
717 struct pci_resource *prevnode;
718 struct pci_resource *node;
719 struct pci_resource *split_node;
720 u32 temp_dword;
721
722 if (!(*head))
723 return NULL;
724
725 if ( pciehp_resource_sort_and_combine(head) )
726 return NULL;
727
728 if ( sort_by_size(head) )
729 return NULL;
730
731 for (node = *head; node; node = node->next) {
732 dbg("%s: req_size =0x%x node=%p, base=0x%x, length=0x%x\n",
733 __FUNCTION__, size, node, node->base, node->length);
734 if (node->length < size)
735 continue;
736
737 if (node->base & (size - 1)) {
738 dbg("%s: not aligned\n", __FUNCTION__);
739 /* this one isn't base aligned properly
740 so we'll make a new entry and split it up */
741 temp_dword = (node->base | (size-1)) + 1;
742
743 /* Short circuit if adjusted size is too small */
744 if ((node->length - (temp_dword - node->base)) < size)
745 continue;
746
747 split_node = kmalloc(sizeof(struct pci_resource),
748 GFP_KERNEL);
749
750 if (!split_node)
751 return NULL;
752
753 split_node->base = node->base;
754 split_node->length = temp_dword - node->base;
755 node->base = temp_dword;
756 node->length -= split_node->length;
757
758 /* Put it in the list */
759 split_node->next = node->next;
760 node->next = split_node;
761 } /* End of non-aligned base */
762
763 /* Don't need to check if too small since we already did */
764 if (node->length > size) {
765 dbg("%s: too big\n", __FUNCTION__);
766 /* this one is longer than we need
767 so we'll make a new entry and split it up */
768 split_node = kmalloc(sizeof(struct pci_resource),
769 GFP_KERNEL);
770
771 if (!split_node)
772 return NULL;
773
774 split_node->base = node->base + size;
775 split_node->length = node->length - size;
776 node->length = size;
777
778 /* Put it in the list */
779 split_node->next = node->next;
780 node->next = split_node;
781 } /* End of too big on top end */
782
783 dbg("%s: got one!!!\n", __FUNCTION__);
784 /* If we got here, then it is the right size
785 Now take it out of the list */
786 if (*head == node) {
787 *head = node->next;
788 } else {
789 prevnode = *head;
790 while (prevnode->next != node)
791 prevnode = prevnode->next;
792
793 prevnode->next = node->next;
794 }
795 node->next = NULL;
796 /* Stop looping */
797 break;
798 }
799 return node;
800}
801
802
803/*
804 * pciehp_resource_sort_and_combine
805 *
806 * Sorts all of the nodes in the list in ascending order by
807 * their base addresses. Also does garbage collection by
808 * combining adjacent nodes.
809 *
810 * returns 0 if success
811 */
812int pciehp_resource_sort_and_combine(struct pci_resource **head)
813{
814 struct pci_resource *node1;
815 struct pci_resource *node2;
816 int out_of_order = 1;
817
818 dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
819
820 if (!(*head))
821 return 1;
822
823 dbg("*head->next = %p\n",(*head)->next);
824
825 if (!(*head)->next)
826 return 0; /* only one item on the list, already sorted! */
827
828 dbg("*head->base = 0x%x\n",(*head)->base);
829 dbg("*head->next->base = 0x%x\n",(*head)->next->base);
830 while (out_of_order) {
831 out_of_order = 0;
832
833 /* Special case for swapping list head */
834 if (((*head)->next) &&
835 ((*head)->base > (*head)->next->base)) {
836 node1 = *head;
837 (*head) = (*head)->next;
838 node1->next = (*head)->next;
839 (*head)->next = node1;
840 out_of_order++;
841 }
842
843 node1 = (*head);
844
845 while (node1->next && node1->next->next) {
846 if (node1->next->base > node1->next->next->base) {
847 out_of_order++;
848 node2 = node1->next;
849 node1->next = node1->next->next;
850 node1 = node1->next;
851 node2->next = node1->next;
852 node1->next = node2;
853 } else
854 node1 = node1->next;
855 }
856 } /* End of out_of_order loop */
857
858 node1 = *head;
859
860 while (node1 && node1->next) {
861 if ((node1->base + node1->length) == node1->next->base) {
862 /* Combine */
863 dbg("8..\n");
864 node1->length += node1->next->length;
865 node2 = node1->next;
866 node1->next = node1->next->next;
867 kfree(node2);
868 } else
869 node1 = node1->next;
870 }
871
872 return 0;
873}
874
875
876/**
877 * pciehp_slot_create - Creates a node and adds it to the proper bus.
878 * @busnumber - bus where new node is to be located
879 *
880 * Returns pointer to the new node or NULL if unsuccessful
881 */
882struct pci_func *pciehp_slot_create(u8 busnumber)
883{
884 struct pci_func *new_slot;
885 struct pci_func *next;
886 dbg("%s: busnumber %x\n", __FUNCTION__, busnumber);
887 new_slot = kmalloc(sizeof(struct pci_func), GFP_KERNEL);
888
889 if (new_slot == NULL)
890 return new_slot;
891
892 memset(new_slot, 0, sizeof(struct pci_func));
893
894 new_slot->next = NULL;
895 new_slot->configured = 1;
896
897 if (pciehp_slot_list[busnumber] == NULL) {
898 pciehp_slot_list[busnumber] = new_slot;
899 } else {
900 next = pciehp_slot_list[busnumber];
901 while (next->next != NULL)
902 next = next->next;
903 next->next = new_slot;
904 }
905 return new_slot;
906}
907
908
909/**
910 * slot_remove - Removes a node from the linked list of slots.
911 * @old_slot: slot to remove
912 *
913 * Returns 0 if successful, !0 otherwise.
914 */
915static int slot_remove(struct pci_func * old_slot)
916{
917 struct pci_func *next;
918
919 if (old_slot == NULL)
920 return 1;
921
922 next = pciehp_slot_list[old_slot->bus];
923
924 if (next == NULL)
925 return 1;
926
927 if (next == old_slot) {
928 pciehp_slot_list[old_slot->bus] = old_slot->next;
929 pciehp_destroy_board_resources(old_slot);
930 kfree(old_slot);
931 return 0;
932 }
933
934 while ((next->next != old_slot) && (next->next != NULL)) {
935 next = next->next;
936 }
937
938 if (next->next == old_slot) {
939 next->next = old_slot->next;
940 pciehp_destroy_board_resources(old_slot);
941 kfree(old_slot);
942 return 0;
943 } else
944 return 2;
945}
946
947
948/**
949 * bridge_slot_remove - Removes a node from the linked list of slots.
950 * @bridge: bridge to remove
951 *
952 * Returns 0 if successful, !0 otherwise.
953 */
954static int bridge_slot_remove(struct pci_func *bridge)
955{
956 u8 subordinateBus, secondaryBus;
957 u8 tempBus;
958 struct pci_func *next;
959
960 if (bridge == NULL)
961 return 1;
962
963 secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
964 subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
965
966 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
967 next = pciehp_slot_list[tempBus];
968
969 while (!slot_remove(next)) {
970 next = pciehp_slot_list[tempBus];
971 }
972 }
973
974 next = pciehp_slot_list[bridge->bus];
975
976 if (next == NULL) {
977 return 1;
978 }
979
980 if (next == bridge) {
981 pciehp_slot_list[bridge->bus] = bridge->next;
982 kfree(bridge);
983 return 0;
984 }
985
986 while ((next->next != bridge) && (next->next != NULL)) {
987 next = next->next;
988 }
989
990 if (next->next == bridge) {
991 next->next = bridge->next;
992 kfree(bridge);
993 return 0;
994 } else
995 return 2;
996}
997
998
999/**
1000 * pciehp_slot_find - Looks for a node by bus, and device, multiple functions accessed
1001 * @bus: bus to find
1002 * @device: device to find
1003 * @index: is 0 for first function found, 1 for the second...
1004 *
1005 * Returns pointer to the node if successful, %NULL otherwise.
1006 */
1007struct pci_func *pciehp_slot_find(u8 bus, u8 device, u8 index)
1008{
1009 int found = -1;
1010 struct pci_func *func;
1011
1012 func = pciehp_slot_list[bus];
1013 dbg("%s: bus %x device %x index %x\n",
1014 __FUNCTION__, bus, device, index);
1015 if (func != NULL) {
1016 dbg("%s: func-> bus %x device %x function %x pci_dev %p\n",
1017 __FUNCTION__, func->bus, func->device, func->function,
1018 func->pci_dev);
1019 } else
1020 dbg("%s: func == NULL\n", __FUNCTION__);
1021
1022 if ((func == NULL) || ((func->device == device) && (index == 0)))
1023 return func;
1024
1025 if (func->device == device)
1026 found++;
1027
1028 while (func->next != NULL) {
1029 func = func->next;
1030
1031 dbg("%s: In while loop, func-> bus %x device %x function %x pci_dev %p\n",
1032 __FUNCTION__, func->bus, func->device, func->function,
1033 func->pci_dev);
1034 if (func->device == device)
1035 found++;
1036 dbg("%s: while loop, found %d, index %d\n", __FUNCTION__,
1037 found, index);
1038
1039 if ((found == index) || (func->function == index)) {
1040 dbg("%s: Found bus %x dev %x func %x\n", __FUNCTION__,
1041 func->bus, func->device, func->function);
1042 return func;
1043 }
1044 }
1045
1046 return NULL;
1047}
1048
1049static int is_bridge(struct pci_func * func)
1050{
1051 /* Check the header type */
1052 if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01)
1053 return 1;
1054 else
1055 return 0;
1056}
1057
1058
1059/* The following routines constitute the bulk of the 228/* The following routines constitute the bulk of the
1060 hotplug controller logic 229 hotplug controller logic
1061 */ 230 */
@@ -1100,20 +269,17 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
1100 * Configures board 269 * Configures board
1101 * 270 *
1102 */ 271 */
1103static u32 board_added(struct pci_func * func, struct controller * ctrl) 272static int board_added(struct slot *p_slot)
1104{ 273{
1105 u8 hp_slot; 274 u8 hp_slot;
1106 int index; 275 int rc = 0;
1107 u32 temp_register = 0xFFFFFFFF; 276 struct controller *ctrl = p_slot->ctrl;
1108 u32 rc = 0;
1109 struct pci_func *new_func = NULL;
1110 struct slot *p_slot;
1111 struct resource_lists res_lists;
1112 277
1113 p_slot = pciehp_find_slot(ctrl, func->device); 278 hp_slot = p_slot->device - ctrl->slot_device_offset;
1114 hp_slot = func->device - ctrl->slot_device_offset;
1115 279
1116 dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n", __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot); 280 dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
281 __FUNCTION__, p_slot->device,
282 ctrl->slot_device_offset, hp_slot);
1117 283
1118 /* Wait for exclusive access to hardware */ 284 /* Wait for exclusive access to hardware */
1119 down(&ctrl->crit_sect); 285 down(&ctrl->crit_sect);
@@ -1141,9 +307,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
1141 up(&ctrl->crit_sect); 307 up(&ctrl->crit_sect);
1142 308
1143 /* Wait for ~1 second */ 309 /* Wait for ~1 second */
1144 dbg("%s: before long_delay\n", __FUNCTION__);
1145 wait_for_ctrl_irq (ctrl); 310 wait_for_ctrl_irq (ctrl);
1146 dbg("%s: afterlong_delay\n", __FUNCTION__);
1147 311
1148 /* Check link training status */ 312 /* Check link training status */
1149 rc = p_slot->hpc_ops->check_lnk_status(ctrl); 313 rc = p_slot->hpc_ops->check_lnk_status(ctrl);
@@ -1153,98 +317,47 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
1153 return rc; 317 return rc;
1154 } 318 }
1155 319
1156 dbg("%s: func status = %x\n", __FUNCTION__, func->status); 320 dbg("%s: slot status = %x\n", __FUNCTION__, p_slot->status);
1157 321
1158 /* Check for a power fault */ 322 /* Check for a power fault */
1159 if (func->status == 0xFF) { 323 if (p_slot->status == 0xFF) {
1160 /* power fault occurred, but it was benign */ 324 /* power fault occurred, but it was benign */
1161 temp_register = 0xFFFFFFFF;
1162 dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
1163 rc = POWER_FAILURE; 325 rc = POWER_FAILURE;
1164 func->status = 0; 326 p_slot->status = 0;
1165 } else { 327 goto err_exit;
1166 /* Get vendor/device ID u32 */
1167 rc = pci_bus_read_config_dword (ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function),
1168 PCI_VENDOR_ID, &temp_register);
1169 dbg("%s: pci_bus_read_config_dword returns %d\n", __FUNCTION__, rc);
1170 dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
1171
1172 if (rc != 0) {
1173 /* Something's wrong here */
1174 temp_register = 0xFFFFFFFF;
1175 dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
1176 }
1177 /* Preset return code. It will be changed later if things go okay. */
1178 rc = NO_ADAPTER_PRESENT;
1179 } 328 }
1180 329
1181 /* All F's is an empty slot or an invalid board */ 330 rc = pciehp_configure_device(p_slot);
1182 if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */ 331 if (rc) {
1183 res_lists.io_head = ctrl->io_head; 332 err("Cannot add device 0x%x:%x\n", p_slot->bus,
1184 res_lists.mem_head = ctrl->mem_head; 333 p_slot->device);
1185 res_lists.p_mem_head = ctrl->p_mem_head; 334 goto err_exit;
1186 res_lists.bus_head = ctrl->bus_head; 335 }
1187 res_lists.irqs = NULL;
1188
1189 rc = configure_new_device(ctrl, func, 0, &res_lists, 0, 0);
1190 dbg("%s: back from configure_new_device\n", __FUNCTION__);
1191
1192 ctrl->io_head = res_lists.io_head;
1193 ctrl->mem_head = res_lists.mem_head;
1194 ctrl->p_mem_head = res_lists.p_mem_head;
1195 ctrl->bus_head = res_lists.bus_head;
1196 336
1197 pciehp_resource_sort_and_combine(&(ctrl->mem_head)); 337 p_slot->status = 0;
1198 pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
1199 pciehp_resource_sort_and_combine(&(ctrl->io_head));
1200 pciehp_resource_sort_and_combine(&(ctrl->bus_head));
1201 338
1202 if (rc) { 339 /*
1203 set_slot_off(ctrl, p_slot); 340 * Some PCI Express root ports require fixup after hot-plug operation.
1204 return rc; 341 */
1205 } 342 if (pcie_mch_quirk)
1206 pciehp_save_slot_config(ctrl, func); 343 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
1207 344 if (PWR_LED(ctrl->ctrlcap)) {
1208 func->status = 0; 345 /* Wait for exclusive access to hardware */
1209 func->switch_save = 0x10; 346 down(&ctrl->crit_sect);
1210 func->is_a_board = 0x01;
1211 347
1212 /* next, we will instantiate the linux pci_dev structures 348 p_slot->hpc_ops->green_led_on(p_slot);
1213 * (with appropriate driver notification, if already present)
1214 */
1215 index = 0;
1216 do {
1217 new_func = pciehp_slot_find(ctrl->slot_bus, func->device, index++);
1218 if (new_func && !new_func->pci_dev) {
1219 dbg("%s:call pci_hp_configure_dev, func %x\n",
1220 __FUNCTION__, index);
1221 pciehp_configure_device(ctrl, new_func);
1222 }
1223 } while (new_func);
1224
1225 /*
1226 * Some PCI Express root ports require fixup after hot-plug operation.
1227 */
1228 if (pcie_mch_quirk)
1229 pci_fixup_device(pci_fixup_final, ctrl->pci_dev);
1230
1231 if (PWR_LED(ctrl->ctrlcap)) {
1232 /* Wait for exclusive access to hardware */
1233 down(&ctrl->crit_sect);
1234
1235 p_slot->hpc_ops->green_led_on(p_slot);
1236 349
1237 /* Wait for the command to complete */ 350 /* Wait for the command to complete */
1238 wait_for_ctrl_irq (ctrl); 351 wait_for_ctrl_irq (ctrl);
1239 352
1240 /* Done with exclusive hardware access */ 353 /* Done with exclusive hardware access */
1241 up(&ctrl->crit_sect); 354 up(&ctrl->crit_sect);
1242 } 355 }
1243 } else {
1244 set_slot_off(ctrl, p_slot);
1245 return -1;
1246 }
1247 return 0; 356 return 0;
357
358err_exit:
359 set_slot_off(ctrl, p_slot);
360 return -1;
1248} 361}
1249 362
1250 363
@@ -1252,55 +365,25 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
1252 * remove_board - Turns off slot and LED's 365 * remove_board - Turns off slot and LED's
1253 * 366 *
1254 */ 367 */
1255static u32 remove_board(struct pci_func *func, struct controller *ctrl) 368static int remove_board(struct slot *p_slot)
1256{ 369{
1257 int index;
1258 u8 skip = 0;
1259 u8 device; 370 u8 device;
1260 u8 hp_slot; 371 u8 hp_slot;
1261 u32 rc; 372 int rc;
1262 struct resource_lists res_lists; 373 struct controller *ctrl = p_slot->ctrl;
1263 struct pci_func *temp_func;
1264 struct slot *p_slot;
1265
1266 if (func == NULL)
1267 return 1;
1268 374
1269 if (pciehp_unconfigure_device(func)) 375 if (pciehp_unconfigure_device(p_slot))
1270 return 1; 376 return 1;
1271 377
1272 device = func->device; 378 device = p_slot->device;
1273 379
1274 hp_slot = func->device - ctrl->slot_device_offset; 380 hp_slot = p_slot->device - ctrl->slot_device_offset;
1275 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 381 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1276 382
1277 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot); 383 dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
1278 384
1279 if ((ctrl->add_support) &&
1280 !(func->bus_head || func->mem_head || func->p_mem_head || func->io_head)) {
1281 /* Here we check to see if we've saved any of the board's
1282 * resources already. If so, we'll skip the attempt to
1283 * determine what's being used.
1284 */
1285 index = 0;
1286
1287 temp_func = func;
1288
1289 while ((temp_func = pciehp_slot_find(temp_func->bus, temp_func->device, index++))) {
1290 if (temp_func->bus_head || temp_func->mem_head
1291 || temp_func->p_mem_head || temp_func->io_head) {
1292 skip = 1;
1293 break;
1294 }
1295 }
1296
1297 if (!skip)
1298 rc = pciehp_save_used_resources(ctrl, func, DISABLE_CARD);
1299 }
1300 /* Change status to shutdown */ 385 /* Change status to shutdown */
1301 if (func->is_a_board) 386 p_slot->status = 0x01;
1302 func->status = 0x01;
1303 func->configured = 0;
1304 387
1305 /* Wait for exclusive access to hardware */ 388 /* Wait for exclusive access to hardware */
1306 down(&ctrl->crit_sect); 389 down(&ctrl->crit_sect);
@@ -1328,56 +411,6 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl)
1328 /* Done with exclusive hardware access */ 411 /* Done with exclusive hardware access */
1329 up(&ctrl->crit_sect); 412 up(&ctrl->crit_sect);
1330 413
1331 if (ctrl->add_support) {
1332 while (func) {
1333 res_lists.io_head = ctrl->io_head;
1334 res_lists.mem_head = ctrl->mem_head;
1335 res_lists.p_mem_head = ctrl->p_mem_head;
1336 res_lists.bus_head = ctrl->bus_head;
1337
1338 dbg("Returning resources to ctlr lists for (B/D/F) = (%#x/%#x/%#x)\n",
1339 func->bus, func->device, func->function);
1340
1341 pciehp_return_board_resources(func, &res_lists);
1342
1343 ctrl->io_head = res_lists.io_head;
1344 ctrl->mem_head = res_lists.mem_head;
1345 ctrl->p_mem_head = res_lists.p_mem_head;
1346 ctrl->bus_head = res_lists.bus_head;
1347
1348 pciehp_resource_sort_and_combine(&(ctrl->mem_head));
1349 pciehp_resource_sort_and_combine(&(ctrl->p_mem_head));
1350 pciehp_resource_sort_and_combine(&(ctrl->io_head));
1351 pciehp_resource_sort_and_combine(&(ctrl->bus_head));
1352
1353 if (is_bridge(func)) {
1354 dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
1355 ctrl->seg, func->bus, func->device, func->function);
1356 bridge_slot_remove(func);
1357 } else {
1358 dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n",
1359 ctrl->seg, func->bus, func->device, func->function);
1360 slot_remove(func);
1361 }
1362
1363 func = pciehp_slot_find(ctrl->slot_bus, device, 0);
1364 }
1365
1366 /* Setup slot structure with entry for empty slot */
1367 func = pciehp_slot_create(ctrl->slot_bus);
1368
1369 if (func == NULL) {
1370 return 1;
1371 }
1372
1373 func->bus = ctrl->slot_bus;
1374 func->device = device;
1375 func->function = 0;
1376 func->configured = 0;
1377 func->switch_save = 0x10;
1378 func->is_a_board = 0;
1379 }
1380
1381 return 0; 414 return 0;
1382} 415}
1383 416
@@ -1411,13 +444,15 @@ static void pciehp_pushbutton_thread(unsigned long slot)
1411 p_slot->hpc_ops->get_power_status(p_slot, &getstatus); 444 p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
1412 if (getstatus) { 445 if (getstatus) {
1413 p_slot->state = POWEROFF_STATE; 446 p_slot->state = POWEROFF_STATE;
1414 dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); 447 dbg("%s: disabling bus:device(%x:%x)\n", __FUNCTION__,
448 p_slot->bus, p_slot->device);
1415 449
1416 pciehp_disable_slot(p_slot); 450 pciehp_disable_slot(p_slot);
1417 p_slot->state = STATIC_STATE; 451 p_slot->state = STATIC_STATE;
1418 } else { 452 } else {
1419 p_slot->state = POWERON_STATE; 453 p_slot->state = POWERON_STATE;
1420 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); 454 dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__,
455 p_slot->bus, p_slot->device);
1421 456
1422 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { 457 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
1423 /* Wait for exclusive access to hardware */ 458 /* Wait for exclusive access to hardware */
@@ -1459,13 +494,15 @@ static void pciehp_surprise_rm_thread(unsigned long slot)
1459 p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); 494 p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
1460 if (!getstatus) { 495 if (!getstatus) {
1461 p_slot->state = POWEROFF_STATE; 496 p_slot->state = POWEROFF_STATE;
1462 dbg("In removing board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); 497 dbg("%s: removing bus:device(%x:%x)\n",
498 __FUNCTION__, p_slot->bus, p_slot->device);
1463 499
1464 pciehp_disable_slot(p_slot); 500 pciehp_disable_slot(p_slot);
1465 p_slot->state = STATIC_STATE; 501 p_slot->state = STATIC_STATE;
1466 } else { 502 } else {
1467 p_slot->state = POWERON_STATE; 503 p_slot->state = POWERON_STATE;
1468 dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device); 504 dbg("%s: adding bus:device(%x:%x)\n",
505 __FUNCTION__, p_slot->bus, p_slot->device);
1469 506
1470 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) { 507 if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) {
1471 /* Wait for exclusive access to hardware */ 508 /* Wait for exclusive access to hardware */
@@ -1531,7 +568,6 @@ int pciehp_event_start_thread(void)
1531 err ("Can't start up our event thread\n"); 568 err ("Can't start up our event thread\n");
1532 return -1; 569 return -1;
1533 } 570 }
1534 dbg("Our event thread pid = %d\n", pid);
1535 return 0; 571 return 0;
1536} 572}
1537 573
@@ -1539,9 +575,7 @@ int pciehp_event_start_thread(void)
1539void pciehp_event_stop_thread(void) 575void pciehp_event_stop_thread(void)
1540{ 576{
1541 event_finished = 1; 577 event_finished = 1;
1542 dbg("event_thread finish command given\n");
1543 up(&event_semaphore); 578 up(&event_semaphore);
1544 dbg("wait for event_thread to exit\n");
1545 down(&event_exit); 579 down(&event_exit);
1546} 580}
1547 581
@@ -1573,7 +607,6 @@ static void interrupt_event_handler(struct controller *ctrl)
1573{ 607{
1574 int loop = 0; 608 int loop = 0;
1575 int change = 1; 609 int change = 1;
1576 struct pci_func *func;
1577 u8 hp_slot; 610 u8 hp_slot;
1578 u8 getstatus; 611 u8 getstatus;
1579 struct slot *p_slot; 612 struct slot *p_slot;
@@ -1581,16 +614,12 @@ static void interrupt_event_handler(struct controller *ctrl)
1581 while (change) { 614 while (change) {
1582 change = 0; 615 change = 0;
1583 616
1584 for (loop = 0; loop < 10; loop++) { 617 for (loop = 0; loop < MAX_EVENTS; loop++) {
1585 if (ctrl->event_queue[loop].event_type != 0) { 618 if (ctrl->event_queue[loop].event_type != 0) {
1586 hp_slot = ctrl->event_queue[loop].hp_slot; 619 hp_slot = ctrl->event_queue[loop].hp_slot;
1587 620
1588 func = pciehp_slot_find(ctrl->slot_bus, (hp_slot + ctrl->slot_device_offset), 0);
1589
1590 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); 621 p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
1591 622
1592 dbg("hp_slot %d, func %p, p_slot %p\n", hp_slot, func, p_slot);
1593
1594 if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) { 623 if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) {
1595 dbg("button cancel\n"); 624 dbg("button cancel\n");
1596 del_timer(&p_slot->task_event); 625 del_timer(&p_slot->task_event);
@@ -1682,7 +711,6 @@ static void interrupt_event_handler(struct controller *ctrl)
1682 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; 711 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
1683 p_slot->task_event.data = (unsigned long) p_slot; 712 p_slot->task_event.data = (unsigned long) p_slot;
1684 713
1685 dbg("add_timer p_slot = %p\n", (void *) p_slot);
1686 add_timer(&p_slot->task_event); 714 add_timer(&p_slot->task_event);
1687 } 715 }
1688 } 716 }
@@ -1737,13 +765,6 @@ int pciehp_enable_slot(struct slot *p_slot)
1737{ 765{
1738 u8 getstatus = 0; 766 u8 getstatus = 0;
1739 int rc; 767 int rc;
1740 struct pci_func *func;
1741
1742 func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
1743 if (!func) {
1744 dbg("%s: Error! slot NULL\n", __FUNCTION__);
1745 return 1;
1746 }
1747 768
1748 /* Check to see if (latch closed, card present, power off) */ 769 /* Check to see if (latch closed, card present, power off) */
1749 down(&p_slot->ctrl->crit_sect); 770 down(&p_slot->ctrl->crit_sect);
@@ -1773,45 +794,11 @@ int pciehp_enable_slot(struct slot *p_slot)
1773 } 794 }
1774 up(&p_slot->ctrl->crit_sect); 795 up(&p_slot->ctrl->crit_sect);
1775 796
1776 slot_remove(func);
1777
1778 func = pciehp_slot_create(p_slot->bus);
1779 if (func == NULL)
1780 return 1;
1781
1782 func->bus = p_slot->bus;
1783 func->device = p_slot->device;
1784 func->function = 0;
1785 func->configured = 0;
1786 func->is_a_board = 1;
1787
1788 /* We have to save the presence info for these slots */
1789 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1790 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 797 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1791 func->switch_save = !getstatus? 0x10:0;
1792 798
1793 rc = board_added(func, p_slot->ctrl); 799 rc = board_added(p_slot);
1794 if (rc) { 800 if (rc) {
1795 if (is_bridge(func))
1796 bridge_slot_remove(func);
1797 else
1798 slot_remove(func);
1799
1800 /* Setup slot structure with entry for empty slot */
1801 func = pciehp_slot_create(p_slot->bus);
1802 if (func == NULL)
1803 return 1; /* Out of memory */
1804
1805 func->bus = p_slot->bus;
1806 func->device = p_slot->device;
1807 func->function = 0;
1808 func->configured = 0;
1809 func->is_a_board = 1;
1810
1811 /* We have to save the presence info for these slots */
1812 p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
1813 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); 801 p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
1814 func->switch_save = !getstatus? 0x10:0;
1815 } 802 }
1816 803
1817 if (p_slot) 804 if (p_slot)
@@ -1823,14 +810,8 @@ int pciehp_enable_slot(struct slot *p_slot)
1823 810
1824int pciehp_disable_slot(struct slot *p_slot) 811int pciehp_disable_slot(struct slot *p_slot)
1825{ 812{
1826 u8 class_code, header_type, BCR;
1827 u8 index = 0;
1828 u8 getstatus = 0; 813 u8 getstatus = 0;
1829 u32 rc = 0;
1830 int ret = 0; 814 int ret = 0;
1831 unsigned int devfn;
1832 struct pci_bus *pci_bus = p_slot->ctrl->pci_dev->subordinate;
1833 struct pci_func *func;
1834 815
1835 if (!p_slot->ctrl) 816 if (!p_slot->ctrl)
1836 return 1; 817 return 1;
@@ -1867,838 +848,8 @@ int pciehp_disable_slot(struct slot *p_slot)
1867 848
1868 up(&p_slot->ctrl->crit_sect); 849 up(&p_slot->ctrl->crit_sect);
1869 850
1870 func = pciehp_slot_find(p_slot->bus, p_slot->device, index++); 851 ret = remove_board(p_slot);
1871 852 update_slot_info(p_slot);
1872 /* Make sure there are no video controllers here 853 return ret;
1873 * for all func of p_slot
1874 */
1875 while (func && !rc) {
1876 pci_bus->number = func->bus;
1877 devfn = PCI_DEVFN(func->device, func->function);
1878
1879 /* Check the Class Code */
1880 rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
1881 if (rc)
1882 return rc;
1883
1884 if (class_code == PCI_BASE_CLASS_DISPLAY) {
1885 /* Display/Video adapter (not supported) */
1886 rc = REMOVE_NOT_SUPPORTED;
1887 } else {
1888 /* See if it's a bridge */
1889 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
1890 if (rc)
1891 return rc;
1892
1893 /* If it's a bridge, check the VGA Enable bit */
1894 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
1895 rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
1896 if (rc)
1897 return rc;
1898
1899 /* If the VGA Enable bit is set, remove isn't supported */
1900 if (BCR & PCI_BRIDGE_CTL_VGA) {
1901 rc = REMOVE_NOT_SUPPORTED;
1902 }
1903 }
1904 }
1905
1906 func = pciehp_slot_find(p_slot->bus, p_slot->device, index++);
1907 }
1908
1909 func = pciehp_slot_find(p_slot->bus, p_slot->device, 0);
1910 if ((func != NULL) && !rc) {
1911 rc = remove_board(func, p_slot->ctrl);
1912 } else if (!rc)
1913 rc = 1;
1914
1915 if (p_slot)
1916 update_slot_info(p_slot);
1917
1918 return rc;
1919}
1920
1921
1922/**
1923 * configure_new_device - Configures the PCI header information of one board.
1924 *
1925 * @ctrl: pointer to controller structure
1926 * @func: pointer to function structure
1927 * @behind_bridge: 1 if this is a recursive call, 0 if not
1928 * @resources: pointer to set of resource lists
1929 *
1930 * Returns 0 if success
1931 *
1932 */
1933static u32 configure_new_device(struct controller * ctrl, struct pci_func * func,
1934 u8 behind_bridge, struct resource_lists * resources, u8 bridge_bus, u8 bridge_dev)
1935{
1936 u8 temp_byte, function, max_functions, stop_it;
1937 int rc;
1938 u32 ID;
1939 struct pci_func *new_slot;
1940 struct pci_bus lpci_bus, *pci_bus;
1941 int index;
1942
1943 new_slot = func;
1944
1945 dbg("%s\n", __FUNCTION__);
1946 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
1947 pci_bus = &lpci_bus;
1948 pci_bus->number = func->bus;
1949
1950 /* Check for Multi-function device */
1951 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
1952 if (rc) {
1953 dbg("%s: rc = %d\n", __FUNCTION__, rc);
1954 return rc;
1955 }
1956
1957 if (temp_byte & 0x80) /* Multi-function device */
1958 max_functions = 8;
1959 else
1960 max_functions = 1;
1961
1962 function = 0;
1963
1964 do {
1965 rc = configure_new_function(ctrl, new_slot, behind_bridge,
1966 resources, bridge_bus, bridge_dev);
1967
1968 if (rc) {
1969 dbg("configure_new_function failed: %d\n", rc);
1970 index = 0;
1971
1972 while (new_slot) {
1973 new_slot = pciehp_slot_find(new_slot->bus,
1974 new_slot->device, index++);
1975
1976 if (new_slot)
1977 pciehp_return_board_resources(new_slot,
1978 resources);
1979 }
1980
1981 return rc;
1982 }
1983
1984 function++;
1985
1986 stop_it = 0;
1987
1988 /* The following loop skips to the next present function
1989 * and creates a board structure
1990 */
1991
1992 while ((function < max_functions) && (!stop_it)) {
1993 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
1994
1995 if (ID == 0xFFFFFFFF) { /* There's nothing there. */
1996 function++;
1997 } else { /* There's something there */
1998 /* Setup slot structure. */
1999 new_slot = pciehp_slot_create(func->bus);
2000
2001 if (new_slot == NULL) {
2002 /* Out of memory */
2003 return 1;
2004 }
2005
2006 new_slot->bus = func->bus;
2007 new_slot->device = func->device;
2008 new_slot->function = function;
2009 new_slot->is_a_board = 1;
2010 new_slot->status = 0;
2011
2012 stop_it++;
2013 }
2014 }
2015
2016 } while (function < max_functions);
2017 dbg("returning from %s\n", __FUNCTION__);
2018
2019 return 0;
2020}
2021
2022/*
2023 * Configuration logic that involves the hotplug data structures and
2024 * their bookkeeping
2025 */
2026
2027/**
2028 * configure_bridge: fill bridge's registers, either configure or disable it.
2029 */
2030static int
2031configure_bridge(struct pci_bus *pci_bus, unsigned int devfn,
2032 struct pci_resource *mem_node,
2033 struct pci_resource **hold_mem_node,
2034 int base_addr, int limit_addr)
2035{
2036 u16 temp_word;
2037 u32 rc;
2038
2039 if (mem_node) {
2040 memcpy(*hold_mem_node, mem_node, sizeof(struct pci_resource));
2041 mem_node->next = NULL;
2042
2043 /* set Mem base and Limit registers */
2044 RES_CHECK(mem_node->base, 16);
2045 temp_word = (u16)(mem_node->base >> 16);
2046 rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
2047
2048 RES_CHECK(mem_node->base + mem_node->length - 1, 16);
2049 temp_word = (u16)((mem_node->base + mem_node->length - 1) >> 16);
2050 rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
2051 } else {
2052 temp_word = 0xFFFF;
2053 rc = pci_bus_write_config_word(pci_bus, devfn, base_addr, temp_word);
2054
2055 temp_word = 0x0000;
2056 rc = pci_bus_write_config_word(pci_bus, devfn, limit_addr, temp_word);
2057
2058 kfree(*hold_mem_node);
2059 *hold_mem_node = NULL;
2060 }
2061 return rc;
2062}
2063
2064static int
2065configure_new_bridge(struct controller *ctrl, struct pci_func *func,
2066 u8 behind_bridge, struct resource_lists *resources,
2067 struct pci_bus *pci_bus)
2068{
2069 int cloop;
2070 u8 temp_byte;
2071 u8 device;
2072 u16 temp_word;
2073 u32 rc;
2074 u32 ID;
2075 unsigned int devfn;
2076 struct pci_resource *mem_node;
2077 struct pci_resource *p_mem_node;
2078 struct pci_resource *io_node;
2079 struct pci_resource *bus_node;
2080 struct pci_resource *hold_mem_node;
2081 struct pci_resource *hold_p_mem_node;
2082 struct pci_resource *hold_IO_node;
2083 struct pci_resource *hold_bus_node;
2084 struct irq_mapping irqs;
2085 struct pci_func *new_slot;
2086 struct resource_lists temp_resources;
2087
2088 devfn = PCI_DEVFN(func->device, func->function);
2089
2090 /* set Primary bus */
2091 dbg("set Primary bus = 0x%x\n", func->bus);
2092 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
2093 if (rc)
2094 return rc;
2095
2096 /* find range of busses to use */
2097 bus_node = get_max_resource(&resources->bus_head, 1L);
2098
2099 /* If we don't have any busses to allocate, we can't continue */
2100 if (!bus_node) {
2101 err("Got NO bus resource to use\n");
2102 return -ENOMEM;
2103 }
2104 dbg("Got ranges of buses to use: base:len=0x%x:%x\n", bus_node->base, bus_node->length);
2105
2106 /* set Secondary bus */
2107 temp_byte = (u8)bus_node->base;
2108 dbg("set Secondary bus = 0x%x\n", temp_byte);
2109 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
2110 if (rc)
2111 return rc;
2112
2113 /* set subordinate bus */
2114 temp_byte = (u8)(bus_node->base + bus_node->length - 1);
2115 dbg("set subordinate bus = 0x%x\n", temp_byte);
2116 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2117 if (rc)
2118 return rc;
2119
2120 /* Set HP parameters (Cache Line Size, Latency Timer) */
2121 rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2122 if (rc)
2123 return rc;
2124
2125 /* Setup the IO, memory, and prefetchable windows */
2126
2127 io_node = get_max_resource(&(resources->io_head), 0x1000L);
2128 if (io_node) {
2129 dbg("io_node(base, len, next) (%x, %x, %p)\n", io_node->base,
2130 io_node->length, io_node->next);
2131 }
2132
2133 mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2134 if (mem_node) {
2135 dbg("mem_node(base, len, next) (%x, %x, %p)\n", mem_node->base,
2136 mem_node->length, mem_node->next);
2137 }
2138
2139 if (resources->p_mem_head)
2140 p_mem_node = get_max_resource(&(resources->p_mem_head), 0x100000L);
2141 else {
2142 /*
2143 * In some platform implementation, MEM and PMEM are not
2144 * distinguished, and hence ACPI _CRS has only MEM entries
2145 * for both MEM and PMEM.
2146 */
2147 dbg("using MEM for PMEM\n");
2148 p_mem_node = get_max_resource(&(resources->mem_head), 0x100000L);
2149 }
2150 if (p_mem_node) {
2151 dbg("p_mem_node(base, len, next) (%x, %x, %p)\n", p_mem_node->base,
2152 p_mem_node->length, p_mem_node->next);
2153 }
2154
2155 /* set up the IRQ info */
2156 if (!resources->irqs) {
2157 irqs.barber_pole = 0;
2158 irqs.interrupt[0] = 0;
2159 irqs.interrupt[1] = 0;
2160 irqs.interrupt[2] = 0;
2161 irqs.interrupt[3] = 0;
2162 irqs.valid_INT = 0;
2163 } else {
2164 irqs.barber_pole = resources->irqs->barber_pole;
2165 irqs.interrupt[0] = resources->irqs->interrupt[0];
2166 irqs.interrupt[1] = resources->irqs->interrupt[1];
2167 irqs.interrupt[2] = resources->irqs->interrupt[2];
2168 irqs.interrupt[3] = resources->irqs->interrupt[3];
2169 irqs.valid_INT = resources->irqs->valid_INT;
2170 }
2171
2172 /* set up resource lists that are now aligned on top and bottom
2173 * for anything behind the bridge.
2174 */
2175 temp_resources.bus_head = bus_node;
2176 temp_resources.io_head = io_node;
2177 temp_resources.mem_head = mem_node;
2178 temp_resources.p_mem_head = p_mem_node;
2179 temp_resources.irqs = &irqs;
2180
2181 /* Make copies of the nodes we are going to pass down so that
2182 * if there is a problem,we can just use these to free resources
2183 */
2184 hold_bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2185 hold_IO_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2186 hold_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2187 hold_p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
2188
2189 if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
2190 kfree(hold_bus_node);
2191 kfree(hold_IO_node);
2192 kfree(hold_mem_node);
2193 kfree(hold_p_mem_node);
2194
2195 return 1;
2196 }
2197
2198 memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
2199
2200 bus_node->base += 1;
2201 bus_node->length -= 1;
2202 bus_node->next = NULL;
2203
2204 /* If we have IO resources copy them and fill in the bridge's
2205 * IO range registers
2206 */
2207 if (io_node) {
2208 memcpy(hold_IO_node, io_node, sizeof(struct pci_resource));
2209 io_node->next = NULL;
2210
2211 /* set IO base and Limit registers */
2212 RES_CHECK(io_node->base, 8);
2213 temp_byte = (u8)(io_node->base >> 8);
2214 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2215
2216 RES_CHECK(io_node->base + io_node->length - 1, 8);
2217 temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
2218 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2219 } else {
2220 kfree(hold_IO_node);
2221 hold_IO_node = NULL;
2222 }
2223
2224 /* If we have memory resources copy them and fill in the bridge's
2225 * memory range registers. Otherwise, fill in the range
2226 * registers with values that disable them.
2227 */
2228 rc = configure_bridge(pci_bus, devfn, mem_node, &hold_mem_node,
2229 PCI_MEMORY_BASE, PCI_MEMORY_LIMIT);
2230
2231 /* If we have prefetchable memory resources copy them and
2232 * fill in the bridge's memory range registers. Otherwise,
2233 * fill in the range registers with values that disable them.
2234 */
2235 rc = configure_bridge(pci_bus, devfn, p_mem_node, &hold_p_mem_node,
2236 PCI_PREF_MEMORY_BASE, PCI_PREF_MEMORY_LIMIT);
2237
2238 /* Adjust this to compensate for extra adjustment in first loop */
2239 irqs.barber_pole--;
2240
2241 rc = 0;
2242
2243 /* Here we actually find the devices and configure them */
2244 for (device = 0; (device <= 0x1F) && !rc; device++) {
2245 irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
2246
2247 ID = 0xFFFFFFFF;
2248 pci_bus->number = hold_bus_node->base;
2249 pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
2250 pci_bus->number = func->bus;
2251
2252 if (ID != 0xFFFFFFFF) { /* device Present */
2253 /* Setup slot structure. */
2254 new_slot = pciehp_slot_create(hold_bus_node->base);
2255
2256 if (new_slot == NULL) {
2257 /* Out of memory */
2258 rc = -ENOMEM;
2259 continue;
2260 }
2261
2262 new_slot->bus = hold_bus_node->base;
2263 new_slot->device = device;
2264 new_slot->function = 0;
2265 new_slot->is_a_board = 1;
2266 new_slot->status = 0;
2267
2268 rc = configure_new_device(ctrl, new_slot, 1,
2269 &temp_resources, func->bus,
2270 func->device);
2271 dbg("configure_new_device rc=0x%x\n",rc);
2272 } /* End of IF (device in slot?) */
2273 } /* End of FOR loop */
2274
2275 if (rc) {
2276 pciehp_destroy_resource_list(&temp_resources);
2277
2278 return_resource(&(resources->bus_head), hold_bus_node);
2279 return_resource(&(resources->io_head), hold_IO_node);
2280 return_resource(&(resources->mem_head), hold_mem_node);
2281 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2282 return(rc);
2283 }
2284
2285 /* save the interrupt routing information */
2286 if (resources->irqs) {
2287 resources->irqs->interrupt[0] = irqs.interrupt[0];
2288 resources->irqs->interrupt[1] = irqs.interrupt[1];
2289 resources->irqs->interrupt[2] = irqs.interrupt[2];
2290 resources->irqs->interrupt[3] = irqs.interrupt[3];
2291 resources->irqs->valid_INT = irqs.valid_INT;
2292 } else if (!behind_bridge) {
2293 /* We need to hook up the interrupts here */
2294 for (cloop = 0; cloop < 4; cloop++) {
2295 if (irqs.valid_INT & (0x01 << cloop)) {
2296 rc = pciehp_set_irq(func->bus, func->device,
2297 0x0A + cloop, irqs.interrupt[cloop]);
2298 if (rc) {
2299 pciehp_destroy_resource_list (&temp_resources);
2300 return_resource(&(resources->bus_head), hold_bus_node);
2301 return_resource(&(resources->io_head), hold_IO_node);
2302 return_resource(&(resources->mem_head), hold_mem_node);
2303 return_resource(&(resources->p_mem_head), hold_p_mem_node);
2304 return rc;
2305 }
2306 }
2307 } /* end of for loop */
2308 }
2309
2310 /* Return unused bus resources
2311 * First use the temporary node to store information for the board
2312 */
2313 if (hold_bus_node && bus_node && temp_resources.bus_head) {
2314 hold_bus_node->length = bus_node->base - hold_bus_node->base;
2315
2316 hold_bus_node->next = func->bus_head;
2317 func->bus_head = hold_bus_node;
2318
2319 temp_byte = (u8)(temp_resources.bus_head->base - 1);
2320
2321 /* set subordinate bus */
2322 dbg("re-set subordinate bus = 0x%x\n", temp_byte);
2323 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
2324
2325 if (temp_resources.bus_head->length == 0) {
2326 kfree(temp_resources.bus_head);
2327 temp_resources.bus_head = NULL;
2328 } else {
2329 dbg("return bus res of b:d(0x%x:%x) base:len(0x%x:%x)\n",
2330 func->bus, func->device, temp_resources.bus_head->base, temp_resources.bus_head->length);
2331 return_resource(&(resources->bus_head), temp_resources.bus_head);
2332 }
2333 }
2334
2335 /* If we have IO space available and there is some left,
2336 * return the unused portion
2337 */
2338 if (hold_IO_node && temp_resources.io_head) {
2339 io_node = do_pre_bridge_resource_split(&(temp_resources.io_head),
2340 &hold_IO_node, 0x1000);
2341
2342 /* Check if we were able to split something off */
2343 if (io_node) {
2344 hold_IO_node->base = io_node->base + io_node->length;
2345
2346 RES_CHECK(hold_IO_node->base, 8);
2347 temp_byte = (u8)((hold_IO_node->base) >> 8);
2348 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
2349
2350 return_resource(&(resources->io_head), io_node);
2351 }
2352
2353 io_node = do_bridge_resource_split(&(temp_resources.io_head), 0x1000);
2354
2355 /* Check if we were able to split something off */
2356 if (io_node) {
2357 /* First use the temporary node to store information for the board */
2358 hold_IO_node->length = io_node->base - hold_IO_node->base;
2359
2360 /* If we used any, add it to the board's list */
2361 if (hold_IO_node->length) {
2362 hold_IO_node->next = func->io_head;
2363 func->io_head = hold_IO_node;
2364
2365 RES_CHECK(io_node->base - 1, 8);
2366 temp_byte = (u8)((io_node->base - 1) >> 8);
2367 rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2368
2369 return_resource(&(resources->io_head), io_node);
2370 } else {
2371 /* it doesn't need any IO */
2372 temp_byte = 0x00;
2373 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
2374
2375 return_resource(&(resources->io_head), io_node);
2376 kfree(hold_IO_node);
2377 }
2378 } else {
2379 /* it used most of the range */
2380 hold_IO_node->next = func->io_head;
2381 func->io_head = hold_IO_node;
2382 }
2383 } else if (hold_IO_node) {
2384 /* it used the whole range */
2385 hold_IO_node->next = func->io_head;
2386 func->io_head = hold_IO_node;
2387 }
2388
2389 /* If we have memory space available and there is some left,
2390 * return the unused portion
2391 */
2392 if (hold_mem_node && temp_resources.mem_head) {
2393 mem_node = do_pre_bridge_resource_split(&(temp_resources.mem_head), &hold_mem_node, 0x100000L);
2394
2395 /* Check if we were able to split something off */
2396 if (mem_node) {
2397 hold_mem_node->base = mem_node->base + mem_node->length;
2398
2399 RES_CHECK(hold_mem_node->base, 16);
2400 temp_word = (u16)((hold_mem_node->base) >> 16);
2401 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
2402
2403 return_resource(&(resources->mem_head), mem_node);
2404 }
2405
2406 mem_node = do_bridge_resource_split(&(temp_resources.mem_head), 0x100000L);
2407
2408 /* Check if we were able to split something off */
2409 if (mem_node) {
2410 /* First use the temporary node to store information for the board */
2411 hold_mem_node->length = mem_node->base - hold_mem_node->base;
2412
2413 if (hold_mem_node->length) {
2414 hold_mem_node->next = func->mem_head;
2415 func->mem_head = hold_mem_node;
2416
2417 /* configure end address */
2418 RES_CHECK(mem_node->base - 1, 16);
2419 temp_word = (u16)((mem_node->base - 1) >> 16);
2420 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2421
2422 /* Return unused resources to the pool */
2423 return_resource(&(resources->mem_head), mem_node);
2424 } else {
2425 /* it doesn't need any Mem */
2426 temp_word = 0x0000;
2427 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
2428
2429 return_resource(&(resources->mem_head), mem_node);
2430 kfree(hold_mem_node);
2431 }
2432 } else {
2433 /* it used most of the range */
2434 hold_mem_node->next = func->mem_head;
2435 func->mem_head = hold_mem_node;
2436 }
2437 } else if (hold_mem_node) {
2438 /* it used the whole range */
2439 hold_mem_node->next = func->mem_head;
2440 func->mem_head = hold_mem_node;
2441 }
2442
2443 /* If we have prefetchable memory space available and there is some
2444 * left at the end, return the unused portion
2445 */
2446 if (hold_p_mem_node && temp_resources.p_mem_head) {
2447 p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head),
2448 &hold_p_mem_node, 0x100000L);
2449
2450 /* Check if we were able to split something off */
2451 if (p_mem_node) {
2452 hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
2453
2454 RES_CHECK(hold_p_mem_node->base, 16);
2455 temp_word = (u16)((hold_p_mem_node->base) >> 16);
2456 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
2457
2458 return_resource(&(resources->p_mem_head), p_mem_node);
2459 }
2460
2461 p_mem_node = do_bridge_resource_split(&(temp_resources.p_mem_head), 0x100000L);
2462
2463 /* Check if we were able to split something off */
2464 if (p_mem_node) {
2465 /* First use the temporary node to store information for the board */
2466 hold_p_mem_node->length = p_mem_node->base - hold_p_mem_node->base;
2467
2468 /* If we used any, add it to the board's list */
2469 if (hold_p_mem_node->length) {
2470 hold_p_mem_node->next = func->p_mem_head;
2471 func->p_mem_head = hold_p_mem_node;
2472
2473 RES_CHECK(p_mem_node->base - 1, 16);
2474 temp_word = (u16)((p_mem_node->base - 1) >> 16);
2475 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2476
2477 return_resource(&(resources->p_mem_head), p_mem_node);
2478 } else {
2479 /* it doesn't need any PMem */
2480 temp_word = 0x0000;
2481 rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
2482
2483 return_resource(&(resources->p_mem_head), p_mem_node);
2484 kfree(hold_p_mem_node);
2485 }
2486 } else {
2487 /* it used the most of the range */
2488 hold_p_mem_node->next = func->p_mem_head;
2489 func->p_mem_head = hold_p_mem_node;
2490 }
2491 } else if (hold_p_mem_node) {
2492 /* it used the whole range */
2493 hold_p_mem_node->next = func->p_mem_head;
2494 func->p_mem_head = hold_p_mem_node;
2495 }
2496
2497 /* We should be configuring an IRQ and the bridge's base address
2498 * registers if it needs them. Although we have never seen such
2499 * a device
2500 */
2501
2502 pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_BRIDGE);
2503
2504 dbg("PCI Bridge Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device, func->function);
2505
2506 return rc;
2507} 854}
2508 855
2509/**
2510 * configure_new_function - Configures the PCI header information of one device
2511 *
2512 * @ctrl: pointer to controller structure
2513 * @func: pointer to function structure
2514 * @behind_bridge: 1 if this is a recursive call, 0 if not
2515 * @resources: pointer to set of resource lists
2516 *
2517 * Calls itself recursively for bridged devices.
2518 * Returns 0 if success
2519 *
2520 */
2521static int
2522configure_new_function(struct controller *ctrl, struct pci_func *func,
2523 u8 behind_bridge, struct resource_lists *resources,
2524 u8 bridge_bus, u8 bridge_dev)
2525{
2526 int cloop;
2527 u8 temp_byte;
2528 u8 class_code;
2529 u32 rc;
2530 u32 temp_register;
2531 u32 base;
2532 unsigned int devfn;
2533 struct pci_resource *mem_node;
2534 struct pci_resource *io_node;
2535 struct pci_bus lpci_bus, *pci_bus;
2536
2537 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
2538 pci_bus = &lpci_bus;
2539 pci_bus->number = func->bus;
2540 devfn = PCI_DEVFN(func->device, func->function);
2541
2542 /* Check for Bridge */
2543 rc = pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
2544 if (rc)
2545 return rc;
2546 dbg("%s: bus %x dev %x func %x temp_byte = %x\n", __FUNCTION__,
2547 func->bus, func->device, func->function, temp_byte);
2548
2549 if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
2550 rc = configure_new_bridge(ctrl, func, behind_bridge, resources,
2551 pci_bus);
2552
2553 if (rc)
2554 return rc;
2555 } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
2556 /* Standard device */
2557 u64 base64;
2558 rc = pci_bus_read_config_byte(pci_bus, devfn, 0x0B, &class_code);
2559
2560 if (class_code == PCI_BASE_CLASS_DISPLAY)
2561 return DEVICE_TYPE_NOT_SUPPORTED;
2562
2563 /* Figure out IO and memory needs */
2564 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
2565 temp_register = 0xFFFFFFFF;
2566
2567 rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
2568 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
2569 dbg("Bar[%x]=0x%x on bus:dev:func(0x%x:%x:%x)\n", cloop, temp_register,
2570 func->bus, func->device, func->function);
2571
2572 if (!temp_register)
2573 continue;
2574
2575 base64 = 0L;
2576 if (temp_register & PCI_BASE_ADDRESS_SPACE_IO) {
2577 /* Map IO */
2578
2579 /* set base = amount of IO space */
2580 base = temp_register & 0xFFFFFFFC;
2581 base = ~base + 1;
2582
2583 dbg("NEED IO length(0x%x)\n", base);
2584 io_node = get_io_resource(&(resources->io_head),(ulong)base);
2585
2586 /* allocate the resource to the board */
2587 if (io_node) {
2588 dbg("Got IO base=0x%x(length=0x%x)\n", io_node->base, io_node->length);
2589 base = (u32)io_node->base;
2590 io_node->next = func->io_head;
2591 func->io_head = io_node;
2592 } else {
2593 err("Got NO IO resource(length=0x%x)\n", base);
2594 return -ENOMEM;
2595 }
2596 } else { /* map MEM */
2597 int prefetchable = 1;
2598 struct pci_resource **res_node = &func->p_mem_head;
2599 char *res_type_str = "PMEM";
2600 u32 temp_register2;
2601
2602 if (!(temp_register & PCI_BASE_ADDRESS_MEM_PREFETCH)) {
2603 prefetchable = 0;
2604 res_node = &func->mem_head;
2605 res_type_str++;
2606 }
2607
2608 base = temp_register & 0xFFFFFFF0;
2609 base = ~base + 1;
2610
2611 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
2612 case PCI_BASE_ADDRESS_MEM_TYPE_32:
2613 dbg("NEED 32 %s bar=0x%x(length=0x%x)\n", res_type_str, temp_register, base);
2614
2615 if (prefetchable && resources->p_mem_head)
2616 mem_node=get_resource(&(resources->p_mem_head), (ulong)base);
2617 else {
2618 if (prefetchable)
2619 dbg("using MEM for PMEM\n");
2620 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2621 }
2622
2623 /* allocate the resource to the board */
2624 if (mem_node) {
2625 base = (u32)mem_node->base;
2626 mem_node->next = *res_node;
2627 *res_node = mem_node;
2628 dbg("Got 32 %s base=0x%x(length=0x%x)\n", res_type_str, mem_node->base,
2629 mem_node->length);
2630 } else {
2631 err("Got NO 32 %s resource(length=0x%x)\n", res_type_str, base);
2632 return -ENOMEM;
2633 }
2634 break;
2635 case PCI_BASE_ADDRESS_MEM_TYPE_64:
2636 rc = pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
2637 dbg("NEED 64 %s bar=0x%x:%x(length=0x%x)\n", res_type_str, temp_register2,
2638 temp_register, base);
2639
2640 if (prefetchable && resources->p_mem_head)
2641 mem_node = get_resource(&(resources->p_mem_head), (ulong)base);
2642 else {
2643 if (prefetchable)
2644 dbg("using MEM for PMEM\n");
2645 mem_node = get_resource(&(resources->mem_head), (ulong)base);
2646 }
2647
2648 /* allocate the resource to the board */
2649 if (mem_node) {
2650 base64 = mem_node->base;
2651 mem_node->next = *res_node;
2652 *res_node = mem_node;
2653 dbg("Got 64 %s base=0x%x:%x(length=%x)\n", res_type_str, (u32)(base64 >> 32),
2654 (u32)base64, mem_node->length);
2655 } else {
2656 err("Got NO 64 %s resource(length=0x%x)\n", res_type_str, base);
2657 return -ENOMEM;
2658 }
2659 break;
2660 default:
2661 dbg("reserved BAR type=0x%x\n", temp_register);
2662 break;
2663 }
2664
2665 }
2666
2667 if (base64) {
2668 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2669 cloop += 4;
2670 base64 >>= 32;
2671
2672 if (base64) {
2673 dbg("%s: high dword of base64(0x%x) set to 0\n", __FUNCTION__, (u32)base64);
2674 base64 = 0x0L;
2675 }
2676
2677 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, (u32)base64);
2678 } else {
2679 rc = pci_bus_write_config_dword(pci_bus, devfn, cloop, base);
2680 }
2681 } /* End of base register loop */
2682
2683 /* disable ROM base Address */
2684 rc = pci_bus_write_config_dword (pci_bus, devfn, PCI_ROM_ADDRESS, 0x00);
2685
2686 /* Set HP parameters (Cache Line Size, Latency Timer) */
2687 rc = pciehprm_set_hpp(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2688 if (rc)
2689 return rc;
2690
2691 pciehprm_enable_card(ctrl, func, PCI_HEADER_TYPE_NORMAL);
2692
2693 dbg("PCI function Hot-Added s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, func->device,
2694 func->function);
2695 } /* End of Not-A-Bridge else */
2696 else {
2697 /* It's some strange type of PCI adapter (Cardbus?) */
2698 return DEVICE_TYPE_NOT_SUPPORTED;
2699 }
2700
2701 func->configured = 1;
2702
2703 return 0;
2704}
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7a0e27f0e063..4a3cecca012c 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -27,16 +27,10 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/kernel.h> 30#include <linux/kernel.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/vmalloc.h>
36#include <linux/interrupt.h>
37#include <linux/spinlock.h>
38#include <linux/pci.h> 33#include <linux/pci.h>
39#include <asm/system.h>
40#include "../pci.h" 34#include "../pci.h"
41#include "pciehp.h" 35#include "pciehp.h"
42 36
@@ -217,23 +211,6 @@ static int pcie_cap_base = 0; /* Base of the PCI Express capability item struct
217#define MRL_STATE 0x0020 211#define MRL_STATE 0x0020
218#define PRSN_STATE 0x0040 212#define PRSN_STATE 0x0040
219 213
220struct php_ctlr_state_s {
221 struct php_ctlr_state_s *pnext;
222 struct pci_dev *pci_dev;
223 unsigned int irq;
224 unsigned long flags; /* spinlock's */
225 u32 slot_device_offset;
226 u32 num_slots;
227 struct timer_list int_poll_timer; /* Added for poll event */
228 php_intr_callback_t attention_button_callback;
229 php_intr_callback_t switch_change_callback;
230 php_intr_callback_t presence_change_callback;
231 php_intr_callback_t power_fault_callback;
232 void *callback_instance_id;
233 struct ctrl_reg *creg; /* Ptr to controller register space */
234};
235
236
237static spinlock_t hpc_event_lock; 214static spinlock_t hpc_event_lock;
238 215
239DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ 216DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
@@ -297,7 +274,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
297 274
298 DBG_ENTER_ROUTINE 275 DBG_ENTER_ROUTINE
299 276
300 dbg("%s : Enter\n", __FUNCTION__);
301 if (!php_ctlr) { 277 if (!php_ctlr) {
302 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 278 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
303 return -1; 279 return -1;
@@ -308,7 +284,6 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
308 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 284 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
309 return retval; 285 return retval;
310 } 286 }
311 dbg("%s : hp_register_read_word SLOT_STATUS %x\n", __FUNCTION__, slot_status);
312 287
313 if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { 288 if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
314 /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue 289 /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue
@@ -316,14 +291,11 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd)
316 dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__); 291 dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
317 } 292 }
318 293
319 dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd);
320 retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); 294 retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
321 if (retval) { 295 if (retval) {
322 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 296 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
323 return retval; 297 return retval;
324 } 298 }
325 dbg("%s : hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd | CMD_CMPL_INTR_ENABLE);
326 dbg("%s : Exit\n", __FUNCTION__);
327 299
328 DBG_LEAVE_ROUTINE 300 DBG_LEAVE_ROUTINE
329 return retval; 301 return retval;
@@ -509,7 +481,6 @@ static int hpc_query_power_fault(struct slot * slot)
509 u16 slot_status; 481 u16 slot_status;
510 u8 pwr_fault; 482 u8 pwr_fault;
511 int retval = 0; 483 int retval = 0;
512 u8 status;
513 484
514 DBG_ENTER_ROUTINE 485 DBG_ENTER_ROUTINE
515 486
@@ -521,15 +492,13 @@ static int hpc_query_power_fault(struct slot * slot)
521 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); 492 retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
522 493
523 if (retval) { 494 if (retval) {
524 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 495 err("%s : Cannot check for power fault\n", __FUNCTION__);
525 return retval; 496 return retval;
526 } 497 }
527 pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1); 498 pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
528 status = (pwr_fault != 1) ? 1 : 0;
529 499
530 DBG_LEAVE_ROUTINE 500 DBG_LEAVE_ROUTINE
531 /* Note: Logic 0 => fault */ 501 return pwr_fault;
532 return status;
533} 502}
534 503
535static int hpc_set_attention_status(struct slot *slot, u8 value) 504static int hpc_set_attention_status(struct slot *slot, u8 value)
@@ -539,7 +508,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
539 u16 slot_ctrl; 508 u16 slot_ctrl;
540 int rc = 0; 509 int rc = 0;
541 510
542 dbg("%s: \n", __FUNCTION__); 511 DBG_ENTER_ROUTINE
512
543 if (!php_ctlr) { 513 if (!php_ctlr) {
544 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 514 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
545 return -1; 515 return -1;
@@ -555,7 +525,6 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
555 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 525 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
556 return rc; 526 return rc;
557 } 527 }
558 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
559 528
560 switch (value) { 529 switch (value) {
561 case 0 : /* turn off */ 530 case 0 : /* turn off */
@@ -576,6 +545,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
576 pcie_write_cmd(slot, slot_cmd); 545 pcie_write_cmd(slot, slot_cmd);
577 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); 546 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
578 547
548 DBG_LEAVE_ROUTINE
579 return rc; 549 return rc;
580} 550}
581 551
@@ -587,7 +557,8 @@ static void hpc_set_green_led_on(struct slot *slot)
587 u16 slot_ctrl; 557 u16 slot_ctrl;
588 int rc = 0; 558 int rc = 0;
589 559
590 dbg("%s: \n", __FUNCTION__); 560 DBG_ENTER_ROUTINE
561
591 if (!php_ctlr) { 562 if (!php_ctlr) {
592 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 563 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
593 return ; 564 return ;
@@ -604,7 +575,6 @@ static void hpc_set_green_led_on(struct slot *slot)
604 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 575 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
605 return; 576 return;
606 } 577 }
607 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
608 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100; 578 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
609 if (!pciehp_poll_mode) 579 if (!pciehp_poll_mode)
610 slot_cmd = slot_cmd | HP_INTR_ENABLE; 580 slot_cmd = slot_cmd | HP_INTR_ENABLE;
@@ -612,6 +582,7 @@ static void hpc_set_green_led_on(struct slot *slot)
612 pcie_write_cmd(slot, slot_cmd); 582 pcie_write_cmd(slot, slot_cmd);
613 583
614 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); 584 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
585 DBG_LEAVE_ROUTINE
615 return; 586 return;
616} 587}
617 588
@@ -622,7 +593,8 @@ static void hpc_set_green_led_off(struct slot *slot)
622 u16 slot_ctrl; 593 u16 slot_ctrl;
623 int rc = 0; 594 int rc = 0;
624 595
625 dbg("%s: \n", __FUNCTION__); 596 DBG_ENTER_ROUTINE
597
626 if (!php_ctlr) { 598 if (!php_ctlr) {
627 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 599 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
628 return ; 600 return ;
@@ -639,7 +611,6 @@ static void hpc_set_green_led_off(struct slot *slot)
639 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 611 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
640 return; 612 return;
641 } 613 }
642 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
643 614
644 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300; 615 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;
645 616
@@ -648,6 +619,7 @@ static void hpc_set_green_led_off(struct slot *slot)
648 pcie_write_cmd(slot, slot_cmd); 619 pcie_write_cmd(slot, slot_cmd);
649 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); 620 dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
650 621
622 DBG_LEAVE_ROUTINE
651 return; 623 return;
652} 624}
653 625
@@ -658,7 +630,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
658 u16 slot_ctrl; 630 u16 slot_ctrl;
659 int rc = 0; 631 int rc = 0;
660 632
661 dbg("%s: \n", __FUNCTION__); 633 DBG_ENTER_ROUTINE
634
662 if (!php_ctlr) { 635 if (!php_ctlr) {
663 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 636 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
664 return ; 637 return ;
@@ -675,7 +648,6 @@ static void hpc_set_green_led_blink(struct slot *slot)
675 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 648 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
676 return; 649 return;
677 } 650 }
678 dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);
679 651
680 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200; 652 slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;
681 653
@@ -684,6 +656,7 @@ static void hpc_set_green_led_blink(struct slot *slot)
684 pcie_write_cmd(slot, slot_cmd); 656 pcie_write_cmd(slot, slot_cmd);
685 657
686 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); 658 dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
659 DBG_LEAVE_ROUTINE
687 return; 660 return;
688} 661}
689 662
@@ -780,7 +753,6 @@ static int hpc_power_on_slot(struct slot * slot)
780 int retval = 0; 753 int retval = 0;
781 754
782 DBG_ENTER_ROUTINE 755 DBG_ENTER_ROUTINE
783 dbg("%s: \n", __FUNCTION__);
784 756
785 if (!php_ctlr) { 757 if (!php_ctlr) {
786 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 758 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
@@ -799,8 +771,6 @@ static int hpc_power_on_slot(struct slot * slot)
799 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 771 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
800 return retval; 772 return retval;
801 } 773 }
802 dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
803 slot_ctrl);
804 774
805 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; 775 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
806 776
@@ -829,7 +799,6 @@ static int hpc_power_off_slot(struct slot * slot)
829 int retval = 0; 799 int retval = 0;
830 800
831 DBG_ENTER_ROUTINE 801 DBG_ENTER_ROUTINE
832 dbg("%s: \n", __FUNCTION__);
833 802
834 if (!php_ctlr) { 803 if (!php_ctlr) {
835 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 804 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
@@ -848,8 +817,6 @@ static int hpc_power_off_slot(struct slot * slot)
848 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 817 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
849 return retval; 818 return retval;
850 } 819 }
851 dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),
852 slot_ctrl);
853 820
854 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; 821 slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
855 822
@@ -924,7 +891,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
924 return IRQ_NONE; 891 return IRQ_NONE;
925 } 892 }
926 893
927 dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);
928 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); 894 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
929 temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; 895 temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
930 896
@@ -933,7 +899,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
933 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 899 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
934 return IRQ_NONE; 900 return IRQ_NONE;
935 } 901 }
936 dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
937 902
938 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 903 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
939 if (rc) { 904 if (rc) {
@@ -949,14 +914,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
949 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); 914 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
950 return IRQ_NONE; 915 return IRQ_NONE;
951 } 916 }
952 dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
953 } 917 }
954 918
955 if (intr_loc & CMD_COMPLETED) { 919 if (intr_loc & CMD_COMPLETED) {
956 /* 920 /*
957 * Command Complete Interrupt Pending 921 * Command Complete Interrupt Pending
958 */ 922 */
959 dbg("%s: In Command Complete Interrupt Pending\n", __FUNCTION__);
960 wake_up_interruptible(&ctrl->queue); 923 wake_up_interruptible(&ctrl->queue);
961 } 924 }
962 925
@@ -989,7 +952,6 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
989 } 952 }
990 953
991 dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__); 954 dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
992 dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
993 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; 955 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
994 956
995 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); 957 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
@@ -997,14 +959,12 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
997 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 959 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
998 return IRQ_NONE; 960 return IRQ_NONE;
999 } 961 }
1000 dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
1001 962
1002 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 963 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
1003 if (rc) { 964 if (rc) {
1004 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 965 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1005 return IRQ_NONE; 966 return IRQ_NONE;
1006 } 967 }
1007 dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
1008 968
1009 /* Clear command complete interrupt caused by this write */ 969 /* Clear command complete interrupt caused by this write */
1010 temp_word = 0x1F; 970 temp_word = 0x1F;
@@ -1248,12 +1208,7 @@ static struct hpc_ops pciehp_hpc_ops = {
1248 .check_lnk_status = hpc_check_lnk_status, 1208 .check_lnk_status = hpc_check_lnk_status,
1249}; 1209};
1250 1210
1251int pcie_init(struct controller * ctrl, 1211int pcie_init(struct controller * ctrl, struct pcie_device *dev)
1252 struct pcie_device *dev,
1253 php_intr_callback_t attention_button_callback,
1254 php_intr_callback_t switch_change_callback,
1255 php_intr_callback_t presence_change_callback,
1256 php_intr_callback_t power_fault_callback)
1257{ 1212{
1258 struct php_ctlr_state_s *php_ctlr, *p; 1213 struct php_ctlr_state_s *php_ctlr, *p;
1259 void *instance_id = ctrl; 1214 void *instance_id = ctrl;
@@ -1282,8 +1237,8 @@ int pcie_init(struct controller * ctrl,
1282 pdev = dev->port; 1237 pdev = dev->port;
1283 php_ctlr->pci_dev = pdev; /* save pci_dev in context */ 1238 php_ctlr->pci_dev = pdev; /* save pci_dev in context */
1284 1239
1285 dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__, 1240 dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
1286 pdev->vendor, pdev->device); 1241 __FUNCTION__, pdev->vendor, pdev->device);
1287 1242
1288 saved_cap_base = pcie_cap_base; 1243 saved_cap_base = pcie_cap_base;
1289 1244
@@ -1340,8 +1295,6 @@ int pcie_init(struct controller * ctrl,
1340 first = 0; 1295 first = 0;
1341 } 1296 }
1342 1297
1343 dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number,
1344 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
1345 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) 1298 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
1346 if (pci_resource_len(pdev, rc) > 0) 1299 if (pci_resource_len(pdev, rc) > 0)
1347 dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc, 1300 dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
@@ -1359,13 +1312,12 @@ int pcie_init(struct controller * ctrl,
1359 1312
1360 /* find the IRQ */ 1313 /* find the IRQ */
1361 php_ctlr->irq = dev->irq; 1314 php_ctlr->irq = dev->irq;
1362 dbg("HPC interrupt = %d\n", php_ctlr->irq);
1363 1315
1364 /* Save interrupt callback info */ 1316 /* Save interrupt callback info */
1365 php_ctlr->attention_button_callback = attention_button_callback; 1317 php_ctlr->attention_button_callback = pciehp_handle_attention_button;
1366 php_ctlr->switch_change_callback = switch_change_callback; 1318 php_ctlr->switch_change_callback = pciehp_handle_switch_change;
1367 php_ctlr->presence_change_callback = presence_change_callback; 1319 php_ctlr->presence_change_callback = pciehp_handle_presence_change;
1368 php_ctlr->power_fault_callback = power_fault_callback; 1320 php_ctlr->power_fault_callback = pciehp_handle_power_fault;
1369 php_ctlr->callback_instance_id = instance_id; 1321 php_ctlr->callback_instance_id = instance_id;
1370 1322
1371 /* return PCI Controller Info */ 1323 /* return PCI Controller Info */
@@ -1387,15 +1339,12 @@ int pcie_init(struct controller * ctrl,
1387 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 1339 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1388 goto abort_free_ctlr; 1340 goto abort_free_ctlr;
1389 } 1341 }
1390 dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word);
1391 1342
1392 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 1343 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
1393 if (rc) { 1344 if (rc) {
1394 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 1345 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1395 goto abort_free_ctlr; 1346 goto abort_free_ctlr;
1396 } 1347 }
1397 dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base)
1398 , slot_status);
1399 1348
1400 temp_word = 0x1F; /* Clear all events */ 1349 temp_word = 0x1F; /* Clear all events */
1401 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); 1350 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
@@ -1403,7 +1352,6 @@ int pcie_init(struct controller * ctrl,
1403 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); 1352 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1404 goto abort_free_ctlr; 1353 goto abort_free_ctlr;
1405 } 1354 }
1406 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
1407 1355
1408 if (pciehp_poll_mode) {/* Install interrupt polling code */ 1356 if (pciehp_poll_mode) {/* Install interrupt polling code */
1409 /* Install and start the interrupt polling timer */ 1357 /* Install and start the interrupt polling timer */
@@ -1419,13 +1367,14 @@ int pcie_init(struct controller * ctrl,
1419 } 1367 }
1420 } 1368 }
1421 1369
1370 dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
1371 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
1372
1422 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); 1373 rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
1423 if (rc) { 1374 if (rc) {
1424 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); 1375 err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
1425 goto abort_free_ctlr; 1376 goto abort_free_ctlr;
1426 } 1377 }
1427 dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
1428 dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
1429 1378
1430 intr_enable = intr_enable | PRSN_DETECT_ENABLE; 1379 intr_enable = intr_enable | PRSN_DETECT_ENABLE;
1431 1380
@@ -1445,7 +1394,6 @@ int pcie_init(struct controller * ctrl,
1445 } else { 1394 } else {
1446 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; 1395 temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
1447 } 1396 }
1448 dbg("%s: temp_word %x\n", __FUNCTION__, temp_word);
1449 1397
1450 /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ 1398 /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
1451 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); 1399 rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
@@ -1453,14 +1401,11 @@ int pcie_init(struct controller * ctrl,
1453 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); 1401 err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
1454 goto abort_free_ctlr; 1402 goto abort_free_ctlr;
1455 } 1403 }
1456 dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word);
1457 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); 1404 rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
1458 if (rc) { 1405 if (rc) {
1459 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); 1406 err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
1460 goto abort_free_ctlr; 1407 goto abort_free_ctlr;
1461 } 1408 }
1462 dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__,
1463 SLOT_STATUS(ctrl->cap_base), slot_status);
1464 1409
1465 temp_word = 0x1F; /* Clear all events */ 1410 temp_word = 0x1F; /* Clear all events */
1466 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); 1411 rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
@@ -1468,8 +1413,16 @@ int pcie_init(struct controller * ctrl,
1468 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); 1413 err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
1469 goto abort_free_ctlr; 1414 goto abort_free_ctlr;
1470 } 1415 }
1471 dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word);
1472 1416
1417 if (pciehp_force) {
1418 dbg("Bypassing BIOS check for pciehp use on %s\n",
1419 pci_name(ctrl->pci_dev));
1420 } else {
1421 rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
1422 if (rc)
1423 goto abort_free_ctlr;
1424 }
1425
1473 /* Add this HPC instance into the HPC list */ 1426 /* Add this HPC instance into the HPC list */
1474 spin_lock(&list_lock); 1427 spin_lock(&list_lock);
1475 if (php_ctlr_list_head == 0) { 1428 if (php_ctlr_list_head == 0) {
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index ff17d8e07e94..647673a7d224 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -27,801 +27,111 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
33#include <linux/types.h> 32#include <linux/types.h>
34#include <linux/slab.h>
35#include <linux/workqueue.h>
36#include <linux/proc_fs.h>
37#include <linux/pci.h> 33#include <linux/pci.h>
38#include "../pci.h" 34#include "../pci.h"
39#include "pciehp.h" 35#include "pciehp.h"
40#ifndef CONFIG_IA64
41#include "../../../arch/i386/pci/pci.h" /* horrible hack showing how processor dependant we are... */
42#endif
43 36
44 37
45int pciehp_configure_device (struct controller* ctrl, struct pci_func* func) 38int pciehp_configure_device(struct slot *p_slot)
46{ 39{
47 unsigned char bus; 40 struct pci_dev *dev;
48 struct pci_bus *child; 41 struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
49 int num; 42 int num, fn;
50 43
51 if (func->pci_dev == NULL) 44 dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0));
52 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function)); 45 if (dev) {
53 46 err("Device %s already exists at %x:%x, cannot hot-add\n",
54 /* Still NULL ? Well then scan for it ! */ 47 pci_name(dev), p_slot->bus, p_slot->device);
55 if (func->pci_dev == NULL) { 48 return -EINVAL;
56 dbg("%s: pci_dev still null. do pci_scan_slot\n", __FUNCTION__);
57
58 num = pci_scan_slot(ctrl->pci_dev->subordinate, PCI_DEVFN(func->device, func->function));
59
60 if (num)
61 pci_bus_add_devices(ctrl->pci_dev->subordinate);
62
63 func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function));
64 if (func->pci_dev == NULL) {
65 dbg("ERROR: pci_dev still null\n");
66 return 0;
67 }
68 } 49 }
69 50
70 if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { 51 num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
71 pci_read_config_byte(func->pci_dev, PCI_SECONDARY_BUS, &bus); 52 if (num == 0) {
72 child = pci_add_new_bus(func->pci_dev->bus, (func->pci_dev), bus); 53 err("No new device found\n");
73 pci_do_scan_bus(child); 54 return -ENODEV;
55 }
74 56
57 for (fn = 0; fn < 8; fn++) {
58 if (!(dev = pci_find_slot(p_slot->bus,
59 PCI_DEVFN(p_slot->device, fn))))
60 continue;
61 if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
62 err("Cannot hot-add display device %s\n",
63 pci_name(dev));
64 continue;
65 }
66 if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
67 (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
68 /* Find an unused bus number for the new bridge */
69 struct pci_bus *child;
70 unsigned char busnr, start = parent->secondary;
71 unsigned char end = parent->subordinate;
72 for (busnr = start; busnr <= end; busnr++) {
73 if (!pci_find_bus(pci_domain_nr(parent),
74 busnr))
75 break;
76 }
77 if (busnr >= end) {
78 err("No free bus for hot-added bridge\n");
79 continue;
80 }
81 child = pci_add_new_bus(parent, dev, busnr);
82 if (!child) {
83 err("Cannot add new bus for %s\n",
84 pci_name(dev));
85 continue;
86 }
87 child->subordinate = pci_do_scan_bus(child);
88 pci_bus_size_bridges(child);
89 }
90 /* TBD: program firmware provided _HPP values */
91 /* program_fw_provided_values(dev); */
75 } 92 }
76 93
94 pci_bus_assign_resources(parent);
95 pci_bus_add_devices(parent);
96 pci_enable_bridges(parent);
77 return 0; 97 return 0;
78} 98}
79 99
80 100int pciehp_unconfigure_device(struct slot *p_slot)
81int pciehp_unconfigure_device(struct pci_func* func)
82{ 101{
83 int rc = 0; 102 int rc = 0;
84 int j; 103 int j;
85 struct pci_bus *pbus; 104 u8 bctl = 0;
86 105
87 dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, 106 dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus,
88 func->device, func->function); 107 p_slot->device);
89 pbus = func->pci_dev->bus;
90 108
91 for (j=0; j<8 ; j++) { 109 for (j=0; j<8 ; j++) {
92 struct pci_dev* temp = pci_find_slot(func->bus, 110 struct pci_dev* temp = pci_find_slot(p_slot->bus,
93 (func->device << 3) | j); 111 (p_slot->device << 3) | j);
94 if (temp) { 112 if (!temp)
95 pci_remove_bus_device(temp); 113 continue;
114 if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
115 err("Cannot remove display device %s\n",
116 pci_name(temp));
117 continue;
96 } 118 }
119 if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
120 pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
121 if (bctl & PCI_BRIDGE_CTL_VGA) {
122 err("Cannot remove display device %s\n",
123 pci_name(temp));
124 continue;
125 }
126 }
127 pci_remove_bus_device(temp);
97 } 128 }
98 /* 129 /*
99 * Some PCI Express root ports require fixup after hot-plug operation. 130 * Some PCI Express root ports require fixup after hot-plug operation.
100 */ 131 */
101 if (pcie_mch_quirk) 132 if (pcie_mch_quirk)
102 pci_fixup_device(pci_fixup_final, pbus->self); 133 pci_fixup_device(pci_fixup_final, p_slot->ctrl->pci_dev);
103 134
104 return rc; 135 return rc;
105} 136}
106 137
107/*
108 * pciehp_set_irq
109 *
110 * @bus_num: bus number of PCI device
111 * @dev_num: device number of PCI device
112 * @slot: pointer to u8 where slot number will be returned
113 */
114int pciehp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
115{
116#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_IO_APIC)
117 int rc;
118 u16 temp_word;
119 struct pci_dev fakedev;
120 struct pci_bus fakebus;
121
122 fakedev.devfn = dev_num << 3;
123 fakedev.bus = &fakebus;
124 fakebus.number = bus_num;
125 dbg("%s: dev %d, bus %d, pin %d, num %d\n",
126 __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
127 rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
128 dbg("%s: rc %d\n", __FUNCTION__, rc);
129 if (!rc)
130 return !rc;
131
132 /* set the Edge Level Control Register (ELCR) */
133 temp_word = inb(0x4d0);
134 temp_word |= inb(0x4d1) << 8;
135
136 temp_word |= 0x01 << irq_num;
137
138 /* This should only be for x86 as it sets the Edge Level Control Register */
139 outb((u8) (temp_word & 0xFF), 0x4d0);
140 outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1);
141#endif
142 return 0;
143}
144
145/* More PCI configuration routines; this time centered around hotplug controller */
146
147
148/*
149 * pciehp_save_config
150 *
151 * Reads configuration for all slots in a PCI bus and saves info.
152 *
153 * Note: For non-hot plug busses, the slot # saved is the device #
154 *
155 * returns 0 if success
156 */
157int pciehp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num)
158{
159 int rc;
160 u8 class_code;
161 u8 header_type;
162 u32 ID;
163 u8 secondary_bus;
164 struct pci_func *new_slot;
165 int sub_bus;
166 int max_functions;
167 int function;
168 u8 DevError;
169 int device = 0;
170 int cloop = 0;
171 int stop_it;
172 int index;
173 int is_hot_plug = num_ctlr_slots || first_device_num;
174 struct pci_bus lpci_bus, *pci_bus;
175 int FirstSupported, LastSupported;
176
177 dbg("%s: Enter\n", __FUNCTION__);
178
179 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
180 pci_bus = &lpci_bus;
181
182 dbg("%s: num_ctlr_slots = %d, first_device_num = %d\n", __FUNCTION__,
183 num_ctlr_slots, first_device_num);
184
185 /* Decide which slots are supported */
186 if (is_hot_plug) {
187 /*********************************
188 * is_hot_plug is the slot mask
189 *********************************/
190 FirstSupported = first_device_num;
191 LastSupported = FirstSupported + num_ctlr_slots - 1;
192 } else {
193 FirstSupported = 0;
194 LastSupported = 0x1F;
195 }
196
197 dbg("FirstSupported = %d, LastSupported = %d\n", FirstSupported,
198 LastSupported);
199
200 /* Save PCI configuration space for all devices in supported slots */
201 dbg("%s: pci_bus->number = %x\n", __FUNCTION__, pci_bus->number);
202 pci_bus->number = busnumber;
203 dbg("%s: bus = %x, dev = %x\n", __FUNCTION__, busnumber, device);
204 for (device = FirstSupported; device <= LastSupported; device++) {
205 ID = 0xFFFFFFFF;
206 rc = pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
207 PCI_VENDOR_ID, &ID);
208
209 if (ID != 0xFFFFFFFF) { /* device in slot */
210 dbg("%s: ID = %x\n", __FUNCTION__, ID);
211 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
212 0x0B, &class_code);
213 if (rc)
214 return rc;
215
216 rc = pci_bus_read_config_byte(pci_bus, PCI_DEVFN(device, 0),
217 PCI_HEADER_TYPE, &header_type);
218 if (rc)
219 return rc;
220
221 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
222
223 /* If multi-function device, set max_functions to 8 */
224 if (header_type & 0x80)
225 max_functions = 8;
226 else
227 max_functions = 1;
228
229 function = 0;
230
231 do {
232 DevError = 0;
233 dbg("%s: In do loop\n", __FUNCTION__);
234
235 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* P-P Bridge */
236 /* Recurse the subordinate bus
237 * get the subordinate bus number
238 */
239 rc = pci_bus_read_config_byte(pci_bus,
240 PCI_DEVFN(device, function),
241 PCI_SECONDARY_BUS, &secondary_bus);
242 if (rc) {
243 return rc;
244 } else {
245 sub_bus = (int) secondary_bus;
246
247 /* Save secondary bus cfg spc with this recursive call. */
248 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
249 if (rc)
250 return rc;
251 }
252 }
253
254 index = 0;
255 new_slot = pciehp_slot_find(busnumber, device, index++);
256
257 dbg("%s: new_slot = %p bus %x dev %x fun %x\n",
258 __FUNCTION__, new_slot, busnumber, device, index-1);
259
260 while (new_slot && (new_slot->function != (u8) function)) {
261 new_slot = pciehp_slot_find(busnumber, device, index++);
262 dbg("%s: while loop, new_slot = %p bus %x dev %x fun %x\n",
263 __FUNCTION__, new_slot, busnumber, device, index-1);
264 }
265 if (!new_slot) {
266 /* Setup slot structure. */
267 new_slot = pciehp_slot_create(busnumber);
268 dbg("%s: if, new_slot = %p bus %x dev %x fun %x\n",
269 __FUNCTION__, new_slot, busnumber, device, function);
270
271 if (new_slot == NULL)
272 return(1);
273 }
274
275 new_slot->bus = (u8) busnumber;
276 new_slot->device = (u8) device;
277 new_slot->function = (u8) function;
278 new_slot->is_a_board = 1;
279 new_slot->switch_save = 0x10;
280 /* In case of unsupported board */
281 new_slot->status = DevError;
282 new_slot->pci_dev = pci_find_slot(new_slot->bus,
283 (new_slot->device << 3) | new_slot->function);
284 dbg("new_slot->pci_dev = %p\n", new_slot->pci_dev);
285
286 for (cloop = 0; cloop < 0x20; cloop++) {
287 rc = pci_bus_read_config_dword(pci_bus,
288 PCI_DEVFN(device, function),
289 cloop << 2,
290 (u32 *) &(new_slot->config_space [cloop]));
291 /* dbg("new_slot->config_space[%x] = %x\n",
292 cloop, new_slot->config_space[cloop]); */
293 if (rc)
294 return rc;
295 }
296
297 function++;
298
299 stop_it = 0;
300
301 /* this loop skips to the next present function
302 * reading in Class Code and Header type.
303 */
304
305 while ((function < max_functions)&&(!stop_it)) {
306 dbg("%s: In while loop \n", __FUNCTION__);
307 rc = pci_bus_read_config_dword(pci_bus,
308 PCI_DEVFN(device, function),
309 PCI_VENDOR_ID, &ID);
310
311 if (ID == 0xFFFFFFFF) { /* nothing there. */
312 function++;
313 dbg("Nothing there\n");
314 } else { /* Something there */
315 rc = pci_bus_read_config_byte(pci_bus,
316 PCI_DEVFN(device, function),
317 0x0B, &class_code);
318 if (rc)
319 return rc;
320
321 rc = pci_bus_read_config_byte(pci_bus,
322 PCI_DEVFN(device, function),
323 PCI_HEADER_TYPE, &header_type);
324 if (rc)
325 return rc;
326
327 dbg("class_code = %x, header_type = %x\n", class_code, header_type);
328 stop_it++;
329 }
330 }
331
332 } while (function < max_functions);
333 /* End of IF (device in slot?) */
334 } else if (is_hot_plug) {
335 /* Setup slot structure with entry for empty slot */
336 new_slot = pciehp_slot_create(busnumber);
337
338 if (new_slot == NULL) {
339 return(1);
340 }
341 dbg("new_slot = %p, bus = %x, dev = %x, fun = %x\n", new_slot,
342 new_slot->bus, new_slot->device, new_slot->function);
343
344 new_slot->bus = (u8) busnumber;
345 new_slot->device = (u8) device;
346 new_slot->function = 0;
347 new_slot->is_a_board = 0;
348 new_slot->presence_save = 0;
349 new_slot->switch_save = 0;
350 }
351 } /* End of FOR loop */
352
353 dbg("%s: Exit\n", __FUNCTION__);
354 return(0);
355}
356
357
358/*
359 * pciehp_save_slot_config
360 *
361 * Saves configuration info for all PCI devices in a given slot
362 * including subordinate busses.
363 *
364 * returns 0 if success
365 */
366int pciehp_save_slot_config(struct controller *ctrl, struct pci_func * new_slot)
367{
368 int rc;
369 u8 class_code;
370 u8 header_type;
371 u32 ID;
372 u8 secondary_bus;
373 int sub_bus;
374 int max_functions;
375 int function;
376 int cloop = 0;
377 int stop_it;
378 struct pci_bus lpci_bus, *pci_bus;
379 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
380 pci_bus = &lpci_bus;
381 pci_bus->number = new_slot->bus;
382
383 ID = 0xFFFFFFFF;
384
385 pci_bus_read_config_dword(pci_bus, PCI_DEVFN(new_slot->device, 0),
386 PCI_VENDOR_ID, &ID);
387
388 if (ID != 0xFFFFFFFF) { /* device in slot */
389 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
390 0x0B, &class_code);
391
392 pci_bus_read_config_byte(pci_bus, PCI_DEVFN(new_slot->device, 0),
393 PCI_HEADER_TYPE, &header_type);
394
395 if (header_type & 0x80) /* Multi-function device */
396 max_functions = 8;
397 else
398 max_functions = 1;
399
400 function = 0;
401
402 do {
403 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
404 /* Recurse the subordinate bus */
405 pci_bus_read_config_byte(pci_bus,
406 PCI_DEVFN(new_slot->device, function),
407 PCI_SECONDARY_BUS, &secondary_bus);
408
409 sub_bus = (int) secondary_bus;
410
411 /* Save the config headers for the secondary bus. */
412 rc = pciehp_save_config(ctrl, sub_bus, 0, 0);
413
414 if (rc)
415 return rc;
416
417 } /* End of IF */
418
419 new_slot->status = 0;
420
421 for (cloop = 0; cloop < 0x20; cloop++) {
422 pci_bus_read_config_dword(pci_bus,
423 PCI_DEVFN(new_slot->device, function),
424 cloop << 2,
425 (u32 *) &(new_slot->config_space [cloop]));
426 }
427
428 function++;
429
430 stop_it = 0;
431
432 /* this loop skips to the next present function
433 * reading in the Class Code and the Header type.
434 */
435
436 while ((function < max_functions) && (!stop_it)) {
437 pci_bus_read_config_dword(pci_bus,
438 PCI_DEVFN(new_slot->device, function),
439 PCI_VENDOR_ID, &ID);
440
441 if (ID == 0xFFFFFFFF) { /* nothing there. */
442 function++;
443 } else { /* Something there */
444 pci_bus_read_config_byte(pci_bus,
445 PCI_DEVFN(new_slot->device, function),
446 0x0B, &class_code);
447
448 pci_bus_read_config_byte(pci_bus,
449 PCI_DEVFN(new_slot->device, function),
450 PCI_HEADER_TYPE, &header_type);
451
452 stop_it++;
453 }
454 }
455
456 } while (function < max_functions);
457 } /* End of IF (device in slot?) */
458 else {
459 return 2;
460 }
461
462 return 0;
463}
464
465
466/*
467 * pciehp_save_used_resources
468 *
469 * Stores used resource information for existing boards. this is
470 * for boards that were in the system when this driver was loaded.
471 * this function is for hot plug ADD
472 *
473 * returns 0 if success
474 * if disable == 1(DISABLE_CARD),
475 * it loops for all functions of the slot and disables them.
476 * else, it just get resources of the function and return.
477 */
478int pciehp_save_used_resources(struct controller *ctrl, struct pci_func *func, int disable)
479{
480 u8 cloop;
481 u8 header_type;
482 u8 secondary_bus;
483 u8 temp_byte;
484 u16 command;
485 u16 save_command;
486 u16 w_base, w_length;
487 u32 temp_register;
488 u32 save_base;
489 u32 base, length;
490 u64 base64 = 0;
491 int index = 0;
492 unsigned int devfn;
493 struct pci_resource *mem_node = NULL;
494 struct pci_resource *p_mem_node = NULL;
495 struct pci_resource *t_mem_node;
496 struct pci_resource *io_node;
497 struct pci_resource *bus_node;
498 struct pci_bus lpci_bus, *pci_bus;
499 memcpy(&lpci_bus, ctrl->pci_dev->subordinate, sizeof(lpci_bus));
500 pci_bus = &lpci_bus;
501
502 if (disable)
503 func = pciehp_slot_find(func->bus, func->device, index++);
504
505 while ((func != NULL) && func->is_a_board) {
506 pci_bus->number = func->bus;
507 devfn = PCI_DEVFN(func->device, func->function);
508
509 /* Save the command register */
510 pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command);
511
512 if (disable) {
513 /* disable card */
514 command = 0x00;
515 pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
516 }
517
518 /* Check for Bridge */
519 pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
520
521 if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */
522 dbg("Save_used_res of PCI bridge b:d=0x%x:%x, sc=0x%x\n",
523 func->bus, func->device, save_command);
524 if (disable) {
525 /* Clear Bridge Control Register */
526 command = 0x00;
527 pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
528 }
529
530 pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
531 pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
532
533 bus_node = kmalloc(sizeof(struct pci_resource),
534 GFP_KERNEL);
535 if (!bus_node)
536 return -ENOMEM;
537
538 bus_node->base = (ulong)secondary_bus;
539 bus_node->length = (ulong)(temp_byte - secondary_bus + 1);
540
541 bus_node->next = func->bus_head;
542 func->bus_head = bus_node;
543
544 /* Save IO base and Limit registers */
545 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &temp_byte);
546 base = temp_byte;
547 pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &temp_byte);
548 length = temp_byte;
549
550 if ((base <= length) && (!disable || (save_command & PCI_COMMAND_IO))) {
551 io_node = kmalloc(sizeof(struct pci_resource),
552 GFP_KERNEL);
553 if (!io_node)
554 return -ENOMEM;
555
556 io_node->base = (ulong)(base & PCI_IO_RANGE_MASK) << 8;
557 io_node->length = (ulong)(length - base + 0x10) << 8;
558
559 io_node->next = func->io_head;
560 func->io_head = io_node;
561 }
562
563 /* Save memory base and Limit registers */
564 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
565 pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
566
567 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
568 mem_node = kmalloc(sizeof(struct pci_resource),
569 GFP_KERNEL);
570 if (!mem_node)
571 return -ENOMEM;
572
573 mem_node->base = (ulong)w_base << 16;
574 mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
575
576 mem_node->next = func->mem_head;
577 func->mem_head = mem_node;
578 }
579 /* Save prefetchable memory base and Limit registers */
580 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
581 pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
582
583 if ((w_base <= w_length) && (!disable || (save_command & PCI_COMMAND_MEMORY))) {
584 p_mem_node = kmalloc(sizeof(struct pci_resource),
585 GFP_KERNEL);
586 if (!p_mem_node)
587 return -ENOMEM;
588
589 p_mem_node->base = (ulong)w_base << 16;
590 p_mem_node->length = (ulong)(w_length - w_base + 0x10) << 16;
591
592 p_mem_node->next = func->p_mem_head;
593 func->p_mem_head = p_mem_node;
594 }
595 } else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
596 dbg("Save_used_res of PCI adapter b:d=0x%x:%x, sc=0x%x\n",
597 func->bus, func->device, save_command);
598
599 /* Figure out IO and memory base lengths */
600 for (cloop = PCI_BASE_ADDRESS_0; cloop <= PCI_BASE_ADDRESS_5; cloop += 4) {
601 pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base);
602
603 temp_register = 0xFFFFFFFF;
604 pci_bus_write_config_dword(pci_bus, devfn, cloop, temp_register);
605 pci_bus_read_config_dword(pci_bus, devfn, cloop, &temp_register);
606
607 if (!disable)
608 pci_bus_write_config_dword(pci_bus, devfn, cloop, save_base);
609
610 if (!temp_register)
611 continue;
612
613 base = temp_register;
614
615 if ((base & PCI_BASE_ADDRESS_SPACE_IO) &&
616 (!disable || (save_command & PCI_COMMAND_IO))) {
617 /* IO base */
618 /* set temp_register = amount of IO space requested */
619 base = base & 0xFFFFFFFCL;
620 base = (~base) + 1;
621
622 io_node = kmalloc(sizeof (struct pci_resource),
623 GFP_KERNEL);
624 if (!io_node)
625 return -ENOMEM;
626
627 io_node->base = (ulong)save_base & PCI_BASE_ADDRESS_IO_MASK;
628 io_node->length = (ulong)base;
629 dbg("sur adapter: IO bar=0x%x(length=0x%x)\n",
630 io_node->base, io_node->length);
631
632 io_node->next = func->io_head;
633 func->io_head = io_node;
634 } else { /* map Memory */
635 int prefetchable = 1;
636 /* struct pci_resources **res_node; */
637 char *res_type_str = "PMEM";
638 u32 temp_register2;
639
640 t_mem_node = kmalloc(sizeof (struct pci_resource),
641 GFP_KERNEL);
642 if (!t_mem_node)
643 return -ENOMEM;
644
645 if (!(base & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
646 (!disable || (save_command & PCI_COMMAND_MEMORY))) {
647 prefetchable = 0;
648 mem_node = t_mem_node;
649 res_type_str++;
650 } else
651 p_mem_node = t_mem_node;
652
653 base = base & 0xFFFFFFF0L;
654 base = (~base) + 1;
655
656 switch (temp_register & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
657 case PCI_BASE_ADDRESS_MEM_TYPE_32:
658 if (prefetchable) {
659 p_mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
660 p_mem_node->length = (ulong)base;
661 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
662 res_type_str,
663 p_mem_node->base,
664 p_mem_node->length);
665
666 p_mem_node->next = func->p_mem_head;
667 func->p_mem_head = p_mem_node;
668 } else {
669 mem_node->base = (ulong)save_base & PCI_BASE_ADDRESS_MEM_MASK;
670 mem_node->length = (ulong)base;
671 dbg("sur adapter: 32 %s bar=0x%x(length=0x%x)\n",
672 res_type_str,
673 mem_node->base,
674 mem_node->length);
675
676 mem_node->next = func->mem_head;
677 func->mem_head = mem_node;
678 }
679 break;
680 case PCI_BASE_ADDRESS_MEM_TYPE_64:
681 pci_bus_read_config_dword(pci_bus, devfn, cloop+4, &temp_register2);
682 base64 = temp_register2;
683 base64 = (base64 << 32) | save_base;
684
685 if (temp_register2) {
686 dbg("sur adapter: 64 %s high dword of base64(0x%x:%x) masked to 0\n",
687 res_type_str, temp_register2, (u32)base64);
688 base64 &= 0x00000000FFFFFFFFL;
689 }
690
691 if (prefetchable) {
692 p_mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
693 p_mem_node->length = base;
694 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
695 res_type_str,
696 p_mem_node->base,
697 p_mem_node->length);
698
699 p_mem_node->next = func->p_mem_head;
700 func->p_mem_head = p_mem_node;
701 } else {
702 mem_node->base = base64 & PCI_BASE_ADDRESS_MEM_MASK;
703 mem_node->length = base;
704 dbg("sur adapter: 64 %s base=0x%x(len=0x%x)\n",
705 res_type_str,
706 mem_node->base,
707 mem_node->length);
708
709 mem_node->next = func->mem_head;
710 func->mem_head = mem_node;
711 }
712 cloop += 4;
713 break;
714 default:
715 dbg("asur: reserved BAR type=0x%x\n",
716 temp_register);
717 break;
718 }
719 }
720 } /* End of base register loop */
721 } else { /* Some other unknown header type */
722 dbg("Save_used_res of PCI unknown type b:d=0x%x:%x. skip.\n",
723 func->bus, func->device);
724 }
725
726 /* find the next device in this slot */
727 if (!disable)
728 break;
729 func = pciehp_slot_find(func->bus, func->device, index++);
730 }
731
732 return 0;
733}
734
735
736/**
737 * kfree_resource_list: release memory of all list members
738 * @res: resource list to free
739 */
740static inline void
741return_resource_list(struct pci_resource **func, struct pci_resource **res)
742{
743 struct pci_resource *node;
744 struct pci_resource *t_node;
745
746 node = *func;
747 *func = NULL;
748 while (node) {
749 t_node = node->next;
750 return_resource(res, node);
751 node = t_node;
752 }
753}
754
755/*
756 * pciehp_return_board_resources
757 *
758 * this routine returns all resources allocated to a board to
759 * the available pool.
760 *
761 * returns 0 if success
762 */
763int pciehp_return_board_resources(struct pci_func * func,
764 struct resource_lists * resources)
765{
766 int rc;
767
768 dbg("%s\n", __FUNCTION__);
769
770 if (!func)
771 return 1;
772
773 return_resource_list(&(func->io_head),&(resources->io_head));
774 return_resource_list(&(func->mem_head),&(resources->mem_head));
775 return_resource_list(&(func->p_mem_head),&(resources->p_mem_head));
776 return_resource_list(&(func->bus_head),&(resources->bus_head));
777
778 rc = pciehp_resource_sort_and_combine(&(resources->mem_head));
779 rc |= pciehp_resource_sort_and_combine(&(resources->p_mem_head));
780 rc |= pciehp_resource_sort_and_combine(&(resources->io_head));
781 rc |= pciehp_resource_sort_and_combine(&(resources->bus_head));
782
783 return rc;
784}
785
786/**
787 * kfree_resource_list: release memory of all list members
788 * @res: resource list to free
789 */
790static inline void
791kfree_resource_list(struct pci_resource **r)
792{
793 struct pci_resource *res, *tres;
794
795 res = *r;
796 *r = NULL;
797
798 while (res) {
799 tres = res;
800 res = res->next;
801 kfree(tres);
802 }
803}
804
805/**
806 * pciehp_destroy_resource_list: put node back in the resource list
807 * @resources: list to put nodes back
808 */
809void pciehp_destroy_resource_list(struct resource_lists * resources)
810{
811 kfree_resource_list(&(resources->io_head));
812 kfree_resource_list(&(resources->mem_head));
813 kfree_resource_list(&(resources->p_mem_head));
814 kfree_resource_list(&(resources->bus_head));
815}
816
817/**
818 * pciehp_destroy_board_resources: put node back in the resource list
819 * @resources: list to put nodes back
820 */
821void pciehp_destroy_board_resources(struct pci_func * func)
822{
823 kfree_resource_list(&(func->io_head));
824 kfree_resource_list(&(func->mem_head));
825 kfree_resource_list(&(func->p_mem_head));
826 kfree_resource_list(&(func->bus_head));
827}
diff --git a/drivers/pci/hotplug/pciehprm.h b/drivers/pci/hotplug/pciehprm.h
deleted file mode 100644
index 05f20fbc5f50..000000000000
--- a/drivers/pci/hotplug/pciehprm.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * PCIEHPRM : PCIEHP Resource Manager for ACPI/non-ACPI platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#ifndef _PCIEHPRM_H_
31#define _PCIEHPRM_H_
32
33#ifdef CONFIG_HOTPLUG_PCI_PCIE_PHPRM_NONACPI
34#include "pciehprm_nonacpi.h"
35#endif
36
37int pciehprm_init(enum php_ctlr_type ct);
38void pciehprm_cleanup(void);
39int pciehprm_print_pirt(void);
40int pciehprm_find_available_resources(struct controller *ctrl);
41int pciehprm_set_hpp(struct controller *ctrl, struct pci_func *func, u8 card_type);
42void pciehprm_enable_card(struct controller *ctrl, struct pci_func *func, u8 card_type);
43
44#ifdef DEBUG
45#define RES_CHECK(this, bits) \
46 { if (((this) & (bits - 1))) \
47 printk("%s:%d ERR: potential res loss!\n", __FUNCTION__, __LINE__); }
48#else
49#define RES_CHECK(this, bits)
50#endif
51
52#endif /* _PCIEHPRM_H_ */
diff --git a/drivers/pci/hotplug/pciehprm_acpi.c b/drivers/pci/hotplug/pciehprm_acpi.c
index 1406db35b089..ae244e218620 100644
--- a/drivers/pci/hotplug/pciehprm_acpi.c
+++ b/drivers/pci/hotplug/pciehprm_acpi.c
@@ -24,100 +24,20 @@
24 * 24 *
25 */ 25 */
26 26
27#include <linux/config.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/kernel.h> 28#include <linux/kernel.h>
30#include <linux/types.h> 29#include <linux/types.h>
31#include <linux/pci.h> 30#include <linux/pci.h>
32#include <linux/init.h>
33#include <linux/acpi.h> 31#include <linux/acpi.h>
34#include <linux/efi.h>
35#include <linux/pci-acpi.h> 32#include <linux/pci-acpi.h>
36#include <asm/uaccess.h>
37#include <asm/system.h>
38#ifdef CONFIG_IA64
39#include <asm/iosapic.h>
40#endif
41#include <acpi/acpi.h>
42#include <acpi/acpi_bus.h> 33#include <acpi/acpi_bus.h>
43#include <acpi/actypes.h> 34#include <acpi/actypes.h>
44#include "pciehp.h" 35#include "pciehp.h"
45#include "pciehprm.h"
46
47#define PCI_MAX_BUS 0x100
48#define ACPI_STA_DEVICE_PRESENT 0x01
49 36
50#define METHOD_NAME__SUN "_SUN" 37#define METHOD_NAME__SUN "_SUN"
51#define METHOD_NAME__HPP "_HPP" 38#define METHOD_NAME__HPP "_HPP"
52#define METHOD_NAME_OSHP "OSHP" 39#define METHOD_NAME_OSHP "OSHP"
53 40
54/* Status code for running acpi method to gain native control */
55#define NC_NOT_RUN 0
56#define OSC_NOT_EXIST 1
57#define OSC_RUN_FAILED 2
58#define OSHP_NOT_EXIST 3
59#define OSHP_RUN_FAILED 4
60#define NC_RUN_SUCCESS 5
61
62#define PHP_RES_BUS 0xA0
63#define PHP_RES_IO 0xA1
64#define PHP_RES_MEM 0xA2
65#define PHP_RES_PMEM 0xA3
66
67#define BRIDGE_TYPE_P2P 0x00
68#define BRIDGE_TYPE_HOST 0x01
69
70/* this should go to drivers/acpi/include/ */
71struct acpi__hpp {
72 u8 cache_line_size;
73 u8 latency_timer;
74 u8 enable_serr;
75 u8 enable_perr;
76};
77
78struct acpi_php_slot {
79 struct acpi_php_slot *next;
80 struct acpi_bridge *bridge;
81 acpi_handle handle;
82 int seg;
83 int bus;
84 int dev;
85 int fun;
86 u32 sun;
87 struct pci_resource *mem_head;
88 struct pci_resource *p_mem_head;
89 struct pci_resource *io_head;
90 struct pci_resource *bus_head;
91 void *slot_ops; /* _STA, _EJx, etc */
92 struct slot *slot;
93}; /* per func */
94
95struct acpi_bridge {
96 struct acpi_bridge *parent;
97 struct acpi_bridge *next;
98 struct acpi_bridge *child;
99 acpi_handle handle;
100 int seg;
101 int pbus; /* pdev->bus->number */
102 int pdevice; /* PCI_SLOT(pdev->devfn) */
103 int pfunction; /* PCI_DEVFN(pdev->devfn) */
104 int bus; /* pdev->subordinate->number */
105 struct acpi__hpp *_hpp;
106 struct acpi_php_slot *slots;
107 struct pci_resource *tmem_head; /* total from crs */
108 struct pci_resource *tp_mem_head; /* total from crs */
109 struct pci_resource *tio_head; /* total from crs */
110 struct pci_resource *tbus_head; /* total from crs */
111 struct pci_resource *mem_head; /* available */
112 struct pci_resource *p_mem_head; /* available */
113 struct pci_resource *io_head; /* available */
114 struct pci_resource *bus_head; /* available */
115 int scanned;
116 int type;
117};
118
119static struct acpi_bridge *acpi_bridges_head;
120
121static u8 * acpi_path_name( acpi_handle handle) 41static u8 * acpi_path_name( acpi_handle handle)
122{ 42{
123 acpi_status status; 43 acpi_status status;
@@ -133,85 +53,43 @@ static u8 * acpi_path_name( acpi_handle handle)
133 return path_name; 53 return path_name;
134} 54}
135 55
136static void acpi_get__hpp ( struct acpi_bridge *ab); 56static acpi_status
137static int acpi_run_oshp ( struct acpi_bridge *ab); 57acpi_run_hpp(acpi_handle handle, struct hotplug_params *hpp)
138static int osc_run_status = NC_NOT_RUN;
139static int oshp_run_status = NC_NOT_RUN;
140
141static int acpi_add_slot_to_php_slots(
142 struct acpi_bridge *ab,
143 int bus_num,
144 acpi_handle handle,
145 u32 adr,
146 u32 sun
147 )
148{
149 struct acpi_php_slot *aps;
150 static long samesun = -1;
151
152 aps = (struct acpi_php_slot *) kmalloc (sizeof(struct acpi_php_slot), GFP_KERNEL);
153 if (!aps) {
154 err ("acpi_pciehprm: alloc for aps fail\n");
155 return -1;
156 }
157 memset(aps, 0, sizeof(struct acpi_php_slot));
158
159 aps->handle = handle;
160 aps->bus = bus_num;
161 aps->dev = (adr >> 16) & 0xffff;
162 aps->fun = adr & 0xffff;
163 aps->sun = sun;
164
165 aps->next = ab->slots; /* cling to the bridge */
166 aps->bridge = ab;
167 ab->slots = aps;
168
169 ab->scanned += 1;
170 if (!ab->_hpp)
171 acpi_get__hpp(ab);
172
173 if (osc_run_status == OSC_NOT_EXIST)
174 oshp_run_status = acpi_run_oshp(ab);
175
176 if (sun != samesun) {
177 info("acpi_pciehprm: Slot sun(%x) at s:b:d:f=0x%02x:%02x:%02x:%02x\n",
178 aps->sun, ab->seg, aps->bus, aps->dev, aps->fun);
179 samesun = sun;
180 }
181 return 0;
182}
183
184static void acpi_get__hpp ( struct acpi_bridge *ab)
185{ 58{
186 acpi_status status; 59 acpi_status status;
187 u8 nui[4]; 60 u8 nui[4];
188 struct acpi_buffer ret_buf = { 0, NULL}; 61 struct acpi_buffer ret_buf = { 0, NULL};
189 union acpi_object *ext_obj, *package; 62 union acpi_object *ext_obj, *package;
190 u8 *path_name = acpi_path_name(ab->handle); 63 u8 *path_name = acpi_path_name(handle);
191 int i, len = 0; 64 int i, len = 0;
192 65
193 /* get _hpp */ 66 /* get _hpp */
194 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 67 status = acpi_evaluate_object(handle, METHOD_NAME__HPP, NULL, &ret_buf);
195 switch (status) { 68 switch (status) {
196 case AE_BUFFER_OVERFLOW: 69 case AE_BUFFER_OVERFLOW:
197 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL); 70 ret_buf.pointer = kmalloc (ret_buf.length, GFP_KERNEL);
198 if (!ret_buf.pointer) { 71 if (!ret_buf.pointer) {
199 err ("acpi_pciehprm:%s alloc for _HPP fail\n", path_name); 72 err ("%s:%s alloc for _HPP fail\n", __FUNCTION__,
200 return; 73 path_name);
74 return AE_NO_MEMORY;
201 } 75 }
202 status = acpi_evaluate_object(ab->handle, METHOD_NAME__HPP, NULL, &ret_buf); 76 status = acpi_evaluate_object(handle, METHOD_NAME__HPP,
77 NULL, &ret_buf);
203 if (ACPI_SUCCESS(status)) 78 if (ACPI_SUCCESS(status))
204 break; 79 break;
205 default: 80 default:
206 if (ACPI_FAILURE(status)) { 81 if (ACPI_FAILURE(status)) {
207 err("acpi_pciehprm:%s _HPP fail=0x%x\n", path_name, status); 82 dbg("%s:%s _HPP fail=0x%x\n", __FUNCTION__,
208 return; 83 path_name, status);
84 return status;
209 } 85 }
210 } 86 }
211 87
212 ext_obj = (union acpi_object *) ret_buf.pointer; 88 ext_obj = (union acpi_object *) ret_buf.pointer;
213 if (ext_obj->type != ACPI_TYPE_PACKAGE) { 89 if (ext_obj->type != ACPI_TYPE_PACKAGE) {
214 err ("acpi_pciehprm:%s _HPP obj not a package\n", path_name); 90 err ("%s:%s _HPP obj not a package\n", __FUNCTION__,
91 path_name);
92 status = AE_ERROR;
215 goto free_and_return; 93 goto free_and_return;
216 } 94 }
217 95
@@ -224,1514 +102,153 @@ static void acpi_get__hpp ( struct acpi_bridge *ab)
224 nui[i] = (u8)ext_obj->integer.value; 102 nui[i] = (u8)ext_obj->integer.value;
225 break; 103 break;
226 default: 104 default:
227 err ("acpi_pciehprm:%s _HPP obj type incorrect\n", path_name); 105 err ("%s:%s _HPP obj type incorrect\n", __FUNCTION__,
106 path_name);
107 status = AE_ERROR;
228 goto free_and_return; 108 goto free_and_return;
229 } 109 }
230 } 110 }
231 111
232 ab->_hpp = kmalloc (sizeof (struct acpi__hpp), GFP_KERNEL); 112 hpp->cache_line_size = nui[0];
233 if (!ab->_hpp) { 113 hpp->latency_timer = nui[1];
234 err ("acpi_pciehprm:%s alloc for _HPP failed\n", path_name); 114 hpp->enable_serr = nui[2];
235 goto free_and_return; 115 hpp->enable_perr = nui[3];
236 }
237 memset(ab->_hpp, 0, sizeof(struct acpi__hpp));
238 116
239 ab->_hpp->cache_line_size = nui[0]; 117 dbg(" _HPP: cache_line_size=0x%x\n", hpp->cache_line_size);
240 ab->_hpp->latency_timer = nui[1]; 118 dbg(" _HPP: latency timer =0x%x\n", hpp->latency_timer);
241 ab->_hpp->enable_serr = nui[2]; 119 dbg(" _HPP: enable SERR =0x%x\n", hpp->enable_serr);
242 ab->_hpp->enable_perr = nui[3]; 120 dbg(" _HPP: enable PERR =0x%x\n", hpp->enable_perr);
243
244 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
245 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
246 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
247 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
248 121
249free_and_return: 122free_and_return:
250 kfree(ret_buf.pointer); 123 kfree(ret_buf.pointer);
124 return status;
251} 125}
252 126
253static int acpi_run_oshp ( struct acpi_bridge *ab) 127static acpi_status acpi_run_oshp(acpi_handle handle)
254{ 128{
255 acpi_status status; 129 acpi_status status;
256 u8 *path_name = acpi_path_name(ab->handle); 130 u8 *path_name = acpi_path_name(handle);
257 131
258 /* run OSHP */ 132 /* run OSHP */
259 status = acpi_evaluate_object(ab->handle, METHOD_NAME_OSHP, NULL, NULL); 133 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL);
260 if (ACPI_FAILURE(status)) { 134 if (ACPI_FAILURE(status)) {
261 err("acpi_pciehprm:%s OSHP fails=0x%x\n", path_name, status); 135 dbg("%s:%s OSHP fails=0x%x\n", __FUNCTION__, path_name,
262 oshp_run_status = (status == AE_NOT_FOUND) ? OSHP_NOT_EXIST : OSHP_RUN_FAILED; 136 status);
263 } else { 137 } else {
264 oshp_run_status = NC_RUN_SUCCESS; 138 dbg("%s:%s OSHP passes\n", __FUNCTION__, path_name);
265 dbg("acpi_pciehprm:%s OSHP passes =0x%x\n", path_name, status);
266 dbg("acpi_pciehprm:%s oshp_run_status =0x%x\n", path_name, oshp_run_status);
267 }
268 return oshp_run_status;
269}
270
271static acpi_status acpi_evaluate_crs(
272 acpi_handle handle,
273 struct acpi_resource **retbuf
274 )
275{
276 acpi_status status;
277 struct acpi_buffer crsbuf;
278 u8 *path_name = acpi_path_name(handle);
279
280 crsbuf.length = 0;
281 crsbuf.pointer = NULL;
282
283 status = acpi_get_current_resources (handle, &crsbuf);
284
285 switch (status) {
286 case AE_BUFFER_OVERFLOW:
287 break; /* found */
288 case AE_NOT_FOUND:
289 dbg("acpi_pciehprm:%s _CRS not found\n", path_name);
290 return status;
291 default:
292 err ("acpi_pciehprm:%s _CRS fail=0x%x\n", path_name, status);
293 return status;
294 } 139 }
295
296 crsbuf.pointer = kmalloc (crsbuf.length, GFP_KERNEL);
297 if (!crsbuf.pointer) {
298 err ("acpi_pciehprm: alloc %ld bytes for %s _CRS fail\n", (ulong)crsbuf.length, path_name);
299 return AE_NO_MEMORY;
300 }
301
302 status = acpi_get_current_resources (handle, &crsbuf);
303 if (ACPI_FAILURE(status)) {
304 err("acpi_pciehprm: %s _CRS fail=0x%x.\n", path_name, status);
305 kfree(crsbuf.pointer);
306 return status;
307 }
308
309 *retbuf = crsbuf.pointer;
310
311 return status; 140 return status;
312} 141}
313 142
314static void free_pci_resource ( struct pci_resource *aprh) 143static int is_root_bridge(acpi_handle handle)
315{ 144{
316 struct pci_resource *res, *next; 145 acpi_status status;
146 struct acpi_device_info *info;
147 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
148 int i;
317 149
318 for (res = aprh; res; res = next) { 150 status = acpi_get_object_info(handle, &buffer);
319 next = res->next; 151 if (ACPI_SUCCESS(status)) {
320 kfree(res); 152 info = buffer.pointer;
321 } 153 if ((info->valid & ACPI_VALID_HID) &&
322} 154 !strcmp(PCI_ROOT_HID_STRING,
323 155 info->hardware_id.value)) {
324static void print_pci_resource ( struct pci_resource *aprh) 156 acpi_os_free(buffer.pointer);
325{ 157 return 1;
326 struct pci_resource *res; 158 }
327 159 if (info->valid & ACPI_VALID_CID) {
328 for (res = aprh; res; res = res->next) 160 for (i=0; i < info->compatibility_id.count; i++) {
329 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length); 161 if (!strcmp(PCI_ROOT_HID_STRING,
330} 162 info->compatibility_id.id[i].value)) {
331 163 acpi_os_free(buffer.pointer);
332static void print_slot_resources( struct acpi_php_slot *aps) 164 return 1;
333{ 165 }
334 if (aps->bus_head) { 166 }
335 dbg(" BUS Resources:\n");
336 print_pci_resource (aps->bus_head);
337 }
338
339 if (aps->io_head) {
340 dbg(" IO Resources:\n");
341 print_pci_resource (aps->io_head);
342 }
343
344 if (aps->mem_head) {
345 dbg(" MEM Resources:\n");
346 print_pci_resource (aps->mem_head);
347 }
348
349 if (aps->p_mem_head) {
350 dbg(" PMEM Resources:\n");
351 print_pci_resource (aps->p_mem_head);
352 }
353}
354
355static void print_pci_resources( struct acpi_bridge *ab)
356{
357 if (ab->tbus_head) {
358 dbg(" Total BUS Resources:\n");
359 print_pci_resource (ab->tbus_head);
360 }
361 if (ab->bus_head) {
362 dbg(" BUS Resources:\n");
363 print_pci_resource (ab->bus_head);
364 }
365
366 if (ab->tio_head) {
367 dbg(" Total IO Resources:\n");
368 print_pci_resource (ab->tio_head);
369 }
370 if (ab->io_head) {
371 dbg(" IO Resources:\n");
372 print_pci_resource (ab->io_head);
373 }
374
375 if (ab->tmem_head) {
376 dbg(" Total MEM Resources:\n");
377 print_pci_resource (ab->tmem_head);
378 }
379 if (ab->mem_head) {
380 dbg(" MEM Resources:\n");
381 print_pci_resource (ab->mem_head);
382 }
383
384 if (ab->tp_mem_head) {
385 dbg(" Total PMEM Resources:\n");
386 print_pci_resource (ab->tp_mem_head);
387 }
388 if (ab->p_mem_head) {
389 dbg(" PMEM Resources:\n");
390 print_pci_resource (ab->p_mem_head);
391 }
392 if (ab->_hpp) {
393 dbg(" _HPP: cache_line_size=0x%x\n", ab->_hpp->cache_line_size);
394 dbg(" _HPP: latency timer =0x%x\n", ab->_hpp->latency_timer);
395 dbg(" _HPP: enable SERR =0x%x\n", ab->_hpp->enable_serr);
396 dbg(" _HPP: enable PERR =0x%x\n", ab->_hpp->enable_perr);
397 }
398}
399
400static int pciehprm_delete_resource(
401 struct pci_resource **aprh,
402 ulong base,
403 ulong size)
404{
405 struct pci_resource *res;
406 struct pci_resource *prevnode;
407 struct pci_resource *split_node;
408 ulong tbase;
409
410 pciehp_resource_sort_and_combine(aprh);
411
412 for (res = *aprh; res; res = res->next) {
413 if (res->base > base)
414 continue;
415
416 if ((res->base + res->length) < (base + size))
417 continue;
418
419 if (res->base < base) {
420 tbase = base;
421
422 if ((res->length - (tbase - res->base)) < size)
423 continue;
424
425 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
426 if (!split_node)
427 return -ENOMEM;
428
429 split_node->base = res->base;
430 split_node->length = tbase - res->base;
431 res->base = tbase;
432 res->length -= split_node->length;
433
434 split_node->next = res->next;
435 res->next = split_node;
436 }
437
438 if (res->length >= size) {
439 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
440 if (!split_node)
441 return -ENOMEM;
442
443 split_node->base = res->base + size;
444 split_node->length = res->length - size;
445 res->length = size;
446
447 split_node->next = res->next;
448 res->next = split_node;
449 }
450
451 if (*aprh == res) {
452 *aprh = res->next;
453 } else {
454 prevnode = *aprh;
455 while (prevnode->next != res)
456 prevnode = prevnode->next;
457
458 prevnode->next = res->next;
459 }
460 res->next = NULL;
461 kfree(res);
462 break;
463 }
464
465 return 0;
466}
467
468static int pciehprm_delete_resources(
469 struct pci_resource **aprh,
470 struct pci_resource *this
471 )
472{
473 struct pci_resource *res;
474
475 for (res = this; res; res = res->next)
476 pciehprm_delete_resource(aprh, res->base, res->length);
477
478 return 0;
479}
480
481static int pciehprm_add_resource(
482 struct pci_resource **aprh,
483 ulong base,
484 ulong size)
485{
486 struct pci_resource *res;
487
488 for (res = *aprh; res; res = res->next) {
489 if ((res->base + res->length) == base) {
490 res->length += size;
491 size = 0L;
492 break;
493 } 167 }
494 if (res->next == *aprh)
495 break;
496 } 168 }
497
498 if (size) {
499 res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
500 if (!res) {
501 err ("acpi_pciehprm: alloc for res fail\n");
502 return -ENOMEM;
503 }
504 memset(res, 0, sizeof (struct pci_resource));
505
506 res->base = base;
507 res->length = size;
508 res->next = *aprh;
509 *aprh = res;
510 }
511
512 return 0; 169 return 0;
513} 170}
514 171
515static int pciehprm_add_resources( 172int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
516 struct pci_resource **aprh,
517 struct pci_resource *this
518 )
519{
520 struct pci_resource *res;
521 int rc = 0;
522
523 for (res = this; res && !rc; res = res->next)
524 rc = pciehprm_add_resource(aprh, res->base, res->length);
525
526 return rc;
527}
528
529static void acpi_parse_io (
530 struct acpi_bridge *ab,
531 union acpi_resource_data *data
532 )
533{ 173{
534 struct acpi_resource_io *dataio; 174 acpi_status status;
535 dataio = (struct acpi_resource_io *) data; 175 acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
536 176 struct pci_dev *pdev = dev;
537 dbg("Io Resource\n"); 177 u8 *path_name;
538 dbg(" %d bit decode\n", ACPI_DECODE_16 == dataio->io_decode ? 16:10); 178 /*
539 dbg(" Range minimum base: %08X\n", dataio->min_base_address); 179 * Per PCI firmware specification, we should run the ACPI _OSC
540 dbg(" Range maximum base: %08X\n", dataio->max_base_address); 180 * method to get control of hotplug hardware before using it.
541 dbg(" Alignment: %08X\n", dataio->alignment); 181 * If an _OSC is missing, we look for an OSHP to do the same thing.
542 dbg(" Range Length: %08X\n", dataio->range_length); 182 * To handle different BIOS behavior, we look for _OSC and OSHP
543} 183 * within the scope of the hotplug controller and its parents, upto
544 184 * the host bridge under which this controller exists.
545static void acpi_parse_fixed_io (
546 struct acpi_bridge *ab,
547 union acpi_resource_data *data
548 )
549{
550 struct acpi_resource_fixed_io *datafio;
551 datafio = (struct acpi_resource_fixed_io *) data;
552
553 dbg("Fixed Io Resource\n");
554 dbg(" Range base address: %08X", datafio->base_address);
555 dbg(" Range length: %08X", datafio->range_length);
556}
557
558static void acpi_parse_address16_32 (
559 struct acpi_bridge *ab,
560 union acpi_resource_data *data,
561 acpi_resource_type id
562 )
563{
564 /*
565 * acpi_resource_address16 == acpi_resource_address32
566 * acpi_resource_address16 *data16 = (acpi_resource_address16 *) data;
567 */ 185 */
568 struct acpi_resource_address32 *data32 = (struct acpi_resource_address32 *) data; 186 while (!handle) {
569 struct pci_resource **aprh, **tprh; 187 /*
570 188 * This hotplug controller was not listed in the ACPI name
571 if (id == ACPI_RSTYPE_ADDRESS16) 189 * space at all. Try to get acpi handle of parent pci bus.
572 dbg("acpi_pciehprm:16-Bit Address Space Resource\n"); 190 */
573 else 191 if (!pdev || !pdev->bus->parent)
574 dbg("acpi_pciehprm:32-Bit Address Space Resource\n");
575
576 switch (data32->resource_type) {
577 case ACPI_MEMORY_RANGE:
578 dbg(" Resource Type: Memory Range\n");
579 aprh = &ab->mem_head;
580 tprh = &ab->tmem_head;
581
582 switch (data32->attribute.memory.cache_attribute) {
583 case ACPI_NON_CACHEABLE_MEMORY:
584 dbg(" Type Specific: Noncacheable memory\n");
585 break;
586 case ACPI_CACHABLE_MEMORY:
587 dbg(" Type Specific: Cacheable memory\n");
588 break;
589 case ACPI_WRITE_COMBINING_MEMORY:
590 dbg(" Type Specific: Write-combining memory\n");
591 break;
592 case ACPI_PREFETCHABLE_MEMORY:
593 aprh = &ab->p_mem_head;
594 dbg(" Type Specific: Prefetchable memory\n");
595 break;
596 default:
597 dbg(" Type Specific: Invalid cache attribute\n");
598 break; 192 break;
599 } 193 dbg("Could not find %s in acpi namespace, trying parent\n",
600 194 pci_name(pdev));
601 dbg(" Type Specific: Read%s\n", ACPI_READ_WRITE_MEMORY == data32->attribute.memory.read_write_attribute ? "/Write":" Only"); 195 if (!pdev->bus->parent->self)
602 break; 196 /* Parent must be a host bridge */
603 197 handle = acpi_get_pci_rootbridge_handle(
604 case ACPI_IO_RANGE: 198 pci_domain_nr(pdev->bus->parent),
605 dbg(" Resource Type: I/O Range\n"); 199 pdev->bus->parent->number);
606 aprh = &ab->io_head; 200 else
607 tprh = &ab->tio_head; 201 handle = DEVICE_ACPI_HANDLE(
608 202 &(pdev->bus->parent->self->dev));
609 switch (data32->attribute.io.range_attribute) { 203 pdev = pdev->bus->parent->self;
610 case ACPI_NON_ISA_ONLY_RANGES: 204 }
611 dbg(" Type Specific: Non-ISA Io Addresses\n"); 205
612 break; 206 while (handle) {
613 case ACPI_ISA_ONLY_RANGES: 207 path_name = acpi_path_name(handle);
614 dbg(" Type Specific: ISA Io Addresses\n"); 208 dbg("Trying to get hotplug control for %s \n", path_name);
615 break; 209 status = pci_osc_control_set(handle,
616 case ACPI_ENTIRE_RANGE: 210 OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
617 dbg(" Type Specific: ISA and non-ISA Io Addresses\n"); 211 if (status == AE_NOT_FOUND)
618 break; 212 status = acpi_run_oshp(handle);
619 default: 213 if (ACPI_SUCCESS(status)) {
620 dbg(" Type Specific: Invalid range attribute\n"); 214 dbg("Gained control for hotplug HW for pci %s (%s)\n",
215 pci_name(dev), path_name);
216 return 0;
217 }
218 if (is_root_bridge(handle))
621 break; 219 break;
622 } 220 chandle = handle;
623 break; 221 status = acpi_get_parent(chandle, &handle);
624
625 case ACPI_BUS_NUMBER_RANGE:
626 dbg(" Resource Type: Bus Number Range(fixed)\n");
627 /* fixup to be compatible with the rest of php driver */
628 data32->min_address_range++;
629 data32->address_length--;
630 aprh = &ab->bus_head;
631 tprh = &ab->tbus_head;
632 break;
633 default:
634 dbg(" Resource Type: Invalid resource type. Exiting.\n");
635 return;
636 }
637
638 dbg(" Resource %s\n", ACPI_CONSUMER == data32->producer_consumer ? "Consumer":"Producer");
639 dbg(" %s decode\n", ACPI_SUB_DECODE == data32->decode ? "Subtractive":"Positive");
640 dbg(" Min address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->min_address_fixed ? "":"not");
641 dbg(" Max address is %s fixed\n", ACPI_ADDRESS_FIXED == data32->max_address_fixed ? "":"not");
642 dbg(" Granularity: %08X\n", data32->granularity);
643 dbg(" Address range min: %08X\n", data32->min_address_range);
644 dbg(" Address range max: %08X\n", data32->max_address_range);
645 dbg(" Address translation offset: %08X\n", data32->address_translation_offset);
646 dbg(" Address Length: %08X\n", data32->address_length);
647
648 if (0xFF != data32->resource_source.index) {
649 dbg(" Resource Source Index: %X\n", data32->resource_source.index);
650 /* dbg(" Resource Source: %s\n", data32->resource_source.string_ptr); */
651 }
652
653 pciehprm_add_resource(aprh, data32->min_address_range, data32->address_length);
654}
655
656static acpi_status acpi_parse_crs(
657 struct acpi_bridge *ab,
658 struct acpi_resource *crsbuf
659 )
660{
661 acpi_status status = AE_OK;
662 struct acpi_resource *resource = crsbuf;
663 u8 count = 0;
664 u8 done = 0;
665
666 while (!done) {
667 dbg("acpi_pciehprm: PCI bus 0x%x Resource structure %x.\n", ab->bus, count++);
668 switch (resource->id) {
669 case ACPI_RSTYPE_IRQ:
670 dbg("Irq -------- Resource\n");
671 break;
672 case ACPI_RSTYPE_DMA:
673 dbg("DMA -------- Resource\n");
674 break;
675 case ACPI_RSTYPE_START_DPF:
676 dbg("Start DPF -------- Resource\n");
677 break;
678 case ACPI_RSTYPE_END_DPF:
679 dbg("End DPF -------- Resource\n");
680 break;
681 case ACPI_RSTYPE_IO:
682 acpi_parse_io (ab, &resource->data);
683 break;
684 case ACPI_RSTYPE_FIXED_IO:
685 acpi_parse_fixed_io (ab, &resource->data);
686 break;
687 case ACPI_RSTYPE_VENDOR:
688 dbg("Vendor -------- Resource\n");
689 break;
690 case ACPI_RSTYPE_END_TAG:
691 dbg("End_tag -------- Resource\n");
692 done = 1;
693 break;
694 case ACPI_RSTYPE_MEM24:
695 dbg("Mem24 -------- Resource\n");
696 break;
697 case ACPI_RSTYPE_MEM32:
698 dbg("Mem32 -------- Resource\n");
699 break;
700 case ACPI_RSTYPE_FIXED_MEM32:
701 dbg("Fixed Mem32 -------- Resource\n");
702 break;
703 case ACPI_RSTYPE_ADDRESS16:
704 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS16);
705 break;
706 case ACPI_RSTYPE_ADDRESS32:
707 acpi_parse_address16_32(ab, &resource->data, ACPI_RSTYPE_ADDRESS32);
708 break;
709 case ACPI_RSTYPE_ADDRESS64:
710 info("Address64 -------- Resource unparsed\n");
711 break;
712 case ACPI_RSTYPE_EXT_IRQ:
713 dbg("Ext Irq -------- Resource\n");
714 break;
715 default:
716 dbg("Invalid -------- resource type 0x%x\n", resource->id);
717 break;
718 }
719
720 resource = (struct acpi_resource *) ((char *)resource + resource->length);
721 }
722
723 return status;
724}
725
726static acpi_status acpi_get_crs( struct acpi_bridge *ab)
727{
728 acpi_status status;
729 struct acpi_resource *crsbuf;
730
731 status = acpi_evaluate_crs(ab->handle, &crsbuf);
732 if (ACPI_SUCCESS(status)) {
733 status = acpi_parse_crs(ab, crsbuf);
734 kfree(crsbuf);
735
736 pciehp_resource_sort_and_combine(&ab->bus_head);
737 pciehp_resource_sort_and_combine(&ab->io_head);
738 pciehp_resource_sort_and_combine(&ab->mem_head);
739 pciehp_resource_sort_and_combine(&ab->p_mem_head);
740
741 pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
742 pciehprm_add_resources (&ab->tio_head, ab->io_head);
743 pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
744 pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
745 }
746
747 return status;
748}
749
750/* find acpi_bridge downword from ab. */
751static struct acpi_bridge *
752find_acpi_bridge_by_bus(
753 struct acpi_bridge *ab,
754 int seg,
755 int bus /* pdev->subordinate->number */
756 )
757{
758 struct acpi_bridge *lab = NULL;
759
760 if (!ab)
761 return NULL;
762
763 if ((ab->bus == bus) && (ab->seg == seg))
764 return ab;
765
766 if (ab->child)
767 lab = find_acpi_bridge_by_bus(ab->child, seg, bus);
768
769 if (!lab)
770 if (ab->next)
771 lab = find_acpi_bridge_by_bus(ab->next, seg, bus);
772
773 return lab;
774}
775
776/*
777 * Build a device tree of ACPI PCI Bridges
778 */
779static void pciehprm_acpi_register_a_bridge (
780 struct acpi_bridge **head,
781 struct acpi_bridge *pab, /* parent bridge to which child bridge is added */
782 struct acpi_bridge *cab /* child bridge to add */
783 )
784{
785 struct acpi_bridge *lpab;
786 struct acpi_bridge *lcab;
787
788 lpab = find_acpi_bridge_by_bus(*head, pab->seg, pab->bus);
789 if (!lpab) {
790 if (!(pab->type & BRIDGE_TYPE_HOST))
791 warn("PCI parent bridge s:b(%x:%x) not in list.\n", pab->seg, pab->bus);
792 pab->next = *head;
793 *head = pab;
794 lpab = pab;
795 }
796
797 if ((cab->type & BRIDGE_TYPE_HOST) && (pab == cab))
798 return;
799
800 lcab = find_acpi_bridge_by_bus(*head, cab->seg, cab->bus);
801 if (lcab) {
802 if ((pab->bus != lcab->parent->bus) || (lcab->bus != cab->bus))
803 err("PCI child bridge s:b(%x:%x) in list with diff parent.\n", cab->seg, cab->bus);
804 return;
805 } else
806 lcab = cab;
807
808 lcab->parent = lpab;
809 lcab->next = lpab->child;
810 lpab->child = lcab;
811}
812
813static acpi_status pciehprm_acpi_build_php_slots_callback(
814 acpi_handle handle,
815 u32 Level,
816 void *context,
817 void **retval
818 )
819{
820 ulong bus_num;
821 ulong seg_num;
822 ulong sun, adr;
823 ulong padr = 0;
824 acpi_handle phandle = NULL;
825 struct acpi_bridge *pab = (struct acpi_bridge *)context;
826 struct acpi_bridge *lab;
827 acpi_status status;
828 u8 *path_name = acpi_path_name(handle);
829
830 /* get _SUN */
831 status = acpi_evaluate_integer(handle, METHOD_NAME__SUN, NULL, &sun);
832 switch(status) {
833 case AE_NOT_FOUND:
834 return AE_OK;
835 default:
836 if (ACPI_FAILURE(status)) {
837 err("acpi_pciehprm:%s _SUN fail=0x%x\n", path_name, status);
838 return status;
839 }
840 }
841
842 /* get _ADR. _ADR must exist if _SUN exists */
843 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
844 if (ACPI_FAILURE(status)) {
845 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
846 return status;
847 }
848
849 dbg("acpi_pciehprm:%s sun=0x%08x adr=0x%08x\n", path_name, (u32)sun, (u32)adr);
850
851 status = acpi_get_parent(handle, &phandle);
852 if (ACPI_FAILURE(status)) {
853 err("acpi_pciehprm:%s get_parent fail=0x%x\n", path_name, status);
854 return (status);
855 }
856
857 bus_num = pab->bus;
858 seg_num = pab->seg;
859
860 if (pab->bus == bus_num) {
861 lab = pab;
862 } else {
863 dbg("WARN: pab is not parent\n");
864 lab = find_acpi_bridge_by_bus(pab, seg_num, bus_num);
865 if (!lab) {
866 dbg("acpi_pciehprm: alloc new P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
867 lab = (struct acpi_bridge *)kmalloc(sizeof(struct acpi_bridge), GFP_KERNEL);
868 if (!lab) {
869 err("acpi_pciehprm: alloc for ab fail\n");
870 return AE_NO_MEMORY;
871 }
872 memset(lab, 0, sizeof(struct acpi_bridge));
873
874 lab->handle = phandle;
875 lab->pbus = pab->bus;
876 lab->pdevice = (int)(padr >> 16) & 0xffff;
877 lab->pfunction = (int)(padr & 0xffff);
878 lab->bus = (int)bus_num;
879 lab->scanned = 0;
880 lab->type = BRIDGE_TYPE_P2P;
881
882 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, lab);
883 } else
884 dbg("acpi_pciehprm: found P2P bridge(%x) for sun(%08x)\n", (u32)bus_num, (u32)sun);
885 }
886
887 acpi_add_slot_to_php_slots(lab, (int)bus_num, handle, (u32)adr, (u32)sun);
888
889 return (status);
890}
891
892static int pciehprm_acpi_build_php_slots(
893 struct acpi_bridge *ab,
894 u32 depth
895 )
896{
897 acpi_status status;
898 u8 *path_name = acpi_path_name(ab->handle);
899
900 /* Walk down this pci bridge to get _SUNs if any behind P2P */
901 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
902 ab->handle,
903 depth,
904 pciehprm_acpi_build_php_slots_callback,
905 ab,
906 NULL );
907 if (ACPI_FAILURE(status)) {
908 dbg("acpi_pciehprm:%s walk for _SUN on pci bridge seg:bus(%x:%x) fail=0x%x\n", path_name, ab->seg, ab->bus, status);
909 return -1;
910 }
911
912 return 0;
913}
914
915static void build_a_bridge(
916 struct acpi_bridge *pab,
917 struct acpi_bridge *ab
918 )
919{
920 u8 *path_name = acpi_path_name(ab->handle);
921
922 pciehprm_acpi_register_a_bridge (&acpi_bridges_head, pab, ab);
923
924 switch (ab->type) {
925 case BRIDGE_TYPE_HOST:
926 dbg("acpi_pciehprm: Registered PCI HOST Bridge(%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
927 ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
928 break;
929 case BRIDGE_TYPE_P2P:
930 dbg("acpi_pciehprm: Registered PCI P2P Bridge(%02x-%02x) on s:b:d:f(%02x:%02x:%02x:%02x) [%s]\n",
931 ab->pbus, ab->bus, ab->seg, ab->pbus, ab->pdevice, ab->pfunction, path_name);
932 break;
933 };
934
935 /* build any immediate PHP slots under this pci bridge */
936 pciehprm_acpi_build_php_slots(ab, 1);
937}
938
939static struct acpi_bridge * add_p2p_bridge(
940 acpi_handle handle,
941 struct acpi_bridge *pab, /* parent */
942 ulong adr
943 )
944{
945 struct acpi_bridge *ab;
946 struct pci_dev *pdev;
947 ulong devnum, funcnum;
948 u8 *path_name = acpi_path_name(handle);
949
950 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
951 if (!ab) {
952 err("acpi_pciehprm: alloc for ab fail\n");
953 return NULL;
954 }
955 memset(ab, 0, sizeof(struct acpi_bridge));
956
957 devnum = (adr >> 16) & 0xffff;
958 funcnum = adr & 0xffff;
959
960 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
961 if (!pdev || !pdev->subordinate) {
962 err("acpi_pciehprm:%s is not a P2P Bridge\n", path_name);
963 kfree(ab);
964 return NULL;
965 }
966
967 ab->handle = handle;
968 ab->seg = pab->seg;
969 ab->pbus = pab->bus; /* or pdev->bus->number */
970 ab->pdevice = devnum; /* or PCI_SLOT(pdev->devfn) */
971 ab->pfunction = funcnum; /* or PCI_FUNC(pdev->devfn) */
972 ab->bus = pdev->subordinate->number;
973 ab->scanned = 0;
974 ab->type = BRIDGE_TYPE_P2P;
975
976 dbg("acpi_pciehprm: P2P(%x-%x) on pci=b:d:f(%x:%x:%x) acpi=b:d:f(%x:%x:%x) [%s]\n",
977 pab->bus, ab->bus, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
978 pab->bus, (u32)devnum, (u32)funcnum, path_name);
979
980 build_a_bridge(pab, ab);
981
982 return ab;
983}
984
985static acpi_status scan_p2p_bridge(
986 acpi_handle handle,
987 u32 Level,
988 void *context,
989 void **retval
990 )
991{
992 struct acpi_bridge *pab = (struct acpi_bridge *)context;
993 struct acpi_bridge *ab;
994 acpi_status status;
995 ulong adr = 0;
996 u8 *path_name = acpi_path_name(handle);
997 ulong devnum, funcnum;
998 struct pci_dev *pdev;
999
1000 /* get device, function */
1001 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1002 if (ACPI_FAILURE(status)) {
1003 if (status != AE_NOT_FOUND)
1004 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1005 return AE_OK;
1006 }
1007
1008 devnum = (adr >> 16) & 0xffff;
1009 funcnum = adr & 0xffff;
1010
1011 pdev = pci_find_slot(pab->bus, PCI_DEVFN(devnum, funcnum));
1012 if (!pdev)
1013 return AE_OK;
1014 if (!pdev->subordinate)
1015 return AE_OK;
1016
1017 ab = add_p2p_bridge(handle, pab, adr);
1018 if (ab) {
1019 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1020 handle,
1021 (u32)1,
1022 scan_p2p_bridge,
1023 ab,
1024 NULL);
1025 if (ACPI_FAILURE(status)) 222 if (ACPI_FAILURE(status))
1026 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status); 223 break;
1027 }
1028
1029 return AE_OK;
1030}
1031
1032static struct acpi_bridge * add_host_bridge(
1033 acpi_handle handle,
1034 ulong segnum,
1035 ulong busnum
1036 )
1037{
1038 ulong adr = 0;
1039 acpi_status status;
1040 struct acpi_bridge *ab;
1041 u8 *path_name = acpi_path_name(handle);
1042
1043 /* get device, function: host br adr is always 0000 though. */
1044 status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
1045 if (ACPI_FAILURE(status)) {
1046 err("acpi_pciehprm:%s _ADR fail=0x%x\n", path_name, status);
1047 return NULL;
1048 }
1049 dbg("acpi_pciehprm: ROOT PCI seg(0x%x)bus(0x%x)dev(0x%x)func(0x%x) [%s]\n", (u32)segnum,
1050 (u32)busnum, (u32)(adr >> 16) & 0xffff, (u32)adr & 0xffff, path_name);
1051
1052 ab = (struct acpi_bridge *) kmalloc (sizeof(struct acpi_bridge), GFP_KERNEL);
1053 if (!ab) {
1054 err("acpi_pciehprm: alloc for ab fail\n");
1055 return NULL;
1056 }
1057 memset(ab, 0, sizeof(struct acpi_bridge));
1058
1059 ab->handle = handle;
1060 ab->seg = (int)segnum;
1061 ab->bus = ab->pbus = (int)busnum;
1062 ab->pdevice = (int)(adr >> 16) & 0xffff;
1063 ab->pfunction = (int)(adr & 0xffff);
1064 ab->scanned = 0;
1065 ab->type = BRIDGE_TYPE_HOST;
1066
1067 /* get root pci bridge's current resources */
1068 status = acpi_get_crs(ab);
1069 if (ACPI_FAILURE(status)) {
1070 err("acpi_pciehprm:%s evaluate _CRS fail=0x%x\n", path_name, status);
1071 kfree(ab);
1072 return NULL;
1073 }
1074
1075 status = pci_osc_control_set (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL);
1076 if (ACPI_FAILURE(status)) {
1077 err("%s: status %x\n", __FUNCTION__, status);
1078 osc_run_status = (status == AE_NOT_FOUND) ? OSC_NOT_EXIST : OSC_RUN_FAILED;
1079 } else {
1080 osc_run_status = NC_RUN_SUCCESS;
1081 }
1082 dbg("%s: osc_run_status %x\n", __FUNCTION__, osc_run_status);
1083
1084 build_a_bridge(ab, ab);
1085
1086 return ab;
1087}
1088
1089static acpi_status acpi_scan_from_root_pci_callback (
1090 acpi_handle handle,
1091 u32 Level,
1092 void *context,
1093 void **retval
1094 )
1095{
1096 ulong segnum = 0;
1097 ulong busnum = 0;
1098 acpi_status status;
1099 struct acpi_bridge *ab;
1100 u8 *path_name = acpi_path_name(handle);
1101
1102 /* get bus number of this pci root bridge */
1103 status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, &segnum);
1104 if (ACPI_FAILURE(status)) {
1105 if (status != AE_NOT_FOUND) {
1106 err("acpi_pciehprm:%s evaluate _SEG fail=0x%x\n", path_name, status);
1107 return status;
1108 }
1109 segnum = 0;
1110 }
1111
1112 /* get bus number of this pci root bridge */
1113 status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, NULL, &busnum);
1114 if (ACPI_FAILURE(status)) {
1115 err("acpi_pciehprm:%s evaluate _BBN fail=0x%x\n", path_name, status);
1116 return (status);
1117 }
1118
1119 ab = add_host_bridge(handle, segnum, busnum);
1120 if (ab) {
1121 status = acpi_walk_namespace ( ACPI_TYPE_DEVICE,
1122 handle,
1123 1,
1124 scan_p2p_bridge,
1125 ab,
1126 NULL);
1127 if (ACPI_FAILURE(status))
1128 dbg("acpi_pciehprm:%s find_p2p fail=0x%x\n", path_name, status);
1129 } 224 }
1130 225
1131 return AE_OK; 226 err("Cannot get control of hotplug hardware for pci %s\n",
227 pci_name(dev));
228 return -1;
1132} 229}
1133 230
1134static int pciehprm_acpi_scan_pci (void) 231void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
232 struct hotplug_params *hpp)
1135{ 233{
1136 acpi_status status; 234 acpi_status status = AE_NOT_FOUND;
235 struct pci_dev *pdev = dev;
1137 236
1138 /* 237 /*
1139 * TBD: traverse LDM device tree with the help of 238 * _HPP settings apply to all child buses, until another _HPP is
1140 * unified ACPI augmented for php device population. 239 * encountered. If we don't find an _HPP for the input pci dev,
240 * look for it in the parent device scope since that would apply to
241 * this pci dev. If we don't find any _HPP, use hardcoded defaults
1141 */ 242 */
1142 status = acpi_get_devices ( PCI_ROOT_HID_STRING, 243 while (pdev && (ACPI_FAILURE(status))) {
1143 acpi_scan_from_root_pci_callback, 244 acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
1144 NULL, 245 if (!handle)
1145 NULL ); 246 break;
1146 if (ACPI_FAILURE(status)) { 247 status = acpi_run_hpp(handle, hpp);
1147 err("acpi_pciehprm:get_device PCI ROOT HID fail=0x%x\n", status); 248 if (!(pdev->bus->parent))
1148 return -1; 249 break;
1149 } 250 /* Check if a parent object supports _HPP */
1150 251 pdev = pdev->bus->parent->self;
1151 return 0;
1152}
1153
1154int pciehprm_init(enum php_ctlr_type ctlr_type)
1155{
1156 int rc;
1157
1158 if (ctlr_type != PCI)
1159 return -ENODEV;
1160
1161 dbg("pciehprm ACPI init <enter>\n");
1162 acpi_bridges_head = NULL;
1163
1164 /* construct PCI bus:device tree of acpi_handles */
1165 rc = pciehprm_acpi_scan_pci();
1166 if (rc)
1167 return rc;
1168
1169 if ((oshp_run_status != NC_RUN_SUCCESS) && (osc_run_status != NC_RUN_SUCCESS)) {
1170 err("Fails to gain control of native hot-plug\n");
1171 rc = -ENODEV;
1172 }
1173
1174 dbg("pciehprm ACPI init %s\n", (rc)?"fail":"success");
1175 return rc;
1176}
1177
1178static void free_a_slot(struct acpi_php_slot *aps)
1179{
1180 dbg(" free a php func of slot(0x%02x) on PCI b:d:f=0x%02x:%02x:%02x\n", aps->sun, aps->bus, aps->dev, aps->fun);
1181
1182 free_pci_resource (aps->io_head);
1183 free_pci_resource (aps->bus_head);
1184 free_pci_resource (aps->mem_head);
1185 free_pci_resource (aps->p_mem_head);
1186
1187 kfree(aps);
1188}
1189
1190static void free_a_bridge( struct acpi_bridge *ab)
1191{
1192 struct acpi_php_slot *aps, *next;
1193
1194 switch (ab->type) {
1195 case BRIDGE_TYPE_HOST:
1196 dbg("Free ACPI PCI HOST Bridge(%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1197 ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1198 break;
1199 case BRIDGE_TYPE_P2P:
1200 dbg("Free ACPI PCI P2P Bridge(%x-%x) [%s] on s:b:d:f(%x:%x:%x:%x)\n",
1201 ab->pbus, ab->bus, acpi_path_name(ab->handle), ab->seg, ab->pbus, ab->pdevice, ab->pfunction);
1202 break;
1203 };
1204
1205 /* free slots first */
1206 for (aps = ab->slots; aps; aps = next) {
1207 next = aps->next;
1208 free_a_slot(aps);
1209 }
1210
1211 free_pci_resource (ab->io_head);
1212 free_pci_resource (ab->tio_head);
1213 free_pci_resource (ab->bus_head);
1214 free_pci_resource (ab->tbus_head);
1215 free_pci_resource (ab->mem_head);
1216 free_pci_resource (ab->tmem_head);
1217 free_pci_resource (ab->p_mem_head);
1218 free_pci_resource (ab->tp_mem_head);
1219
1220 kfree(ab);
1221}
1222
1223static void pciehprm_free_bridges ( struct acpi_bridge *ab)
1224{
1225 if (!ab)
1226 return;
1227
1228 if (ab->child)
1229 pciehprm_free_bridges (ab->child);
1230
1231 if (ab->next)
1232 pciehprm_free_bridges (ab->next);
1233
1234 free_a_bridge(ab);
1235}
1236
1237void pciehprm_cleanup(void)
1238{
1239 pciehprm_free_bridges (acpi_bridges_head);
1240}
1241
1242static int get_number_of_slots (
1243 struct acpi_bridge *ab,
1244 int selfonly
1245 )
1246{
1247 struct acpi_php_slot *aps;
1248 int prev_slot = -1;
1249 int slot_num = 0;
1250
1251 for ( aps = ab->slots; aps; aps = aps->next)
1252 if (aps->dev != prev_slot) {
1253 prev_slot = aps->dev;
1254 slot_num++;
1255 }
1256
1257 if (ab->child)
1258 slot_num += get_number_of_slots (ab->child, 0);
1259
1260 if (selfonly)
1261 return slot_num;
1262
1263 if (ab->next)
1264 slot_num += get_number_of_slots (ab->next, 0);
1265
1266 return slot_num;
1267}
1268
1269static int print_acpi_resources (struct acpi_bridge *ab)
1270{
1271 struct acpi_php_slot *aps;
1272 int i;
1273
1274 switch (ab->type) {
1275 case BRIDGE_TYPE_HOST:
1276 dbg("PCI HOST Bridge (%x) [%s]\n", ab->bus, acpi_path_name(ab->handle));
1277 break;
1278 case BRIDGE_TYPE_P2P:
1279 dbg("PCI P2P Bridge (%x-%x) [%s]\n", ab->pbus, ab->bus, acpi_path_name(ab->handle));
1280 break;
1281 };
1282
1283 print_pci_resources (ab);
1284
1285 for ( i = -1, aps = ab->slots; aps; aps = aps->next) {
1286 if (aps->dev == i)
1287 continue;
1288 dbg(" Slot sun(%x) s:b:d:f(%02x:%02x:%02x:%02x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1289 print_slot_resources(aps);
1290 i = aps->dev;
1291 }
1292
1293 if (ab->child)
1294 print_acpi_resources (ab->child);
1295
1296 if (ab->next)
1297 print_acpi_resources (ab->next);
1298
1299 return 0;
1300}
1301
1302int pciehprm_print_pirt(void)
1303{
1304 dbg("PCIEHPRM ACPI Slots\n");
1305 if (acpi_bridges_head)
1306 print_acpi_resources (acpi_bridges_head);
1307
1308 return 0;
1309}
1310
1311static struct acpi_php_slot * get_acpi_slot (
1312 struct acpi_bridge *ab,
1313 u32 sun
1314 )
1315{
1316 struct acpi_php_slot *aps = NULL;
1317
1318 for ( aps = ab->slots; aps; aps = aps->next)
1319 if (aps->sun == sun)
1320 return aps;
1321
1322 if (!aps && ab->child) {
1323 aps = (struct acpi_php_slot *)get_acpi_slot (ab->child, sun);
1324 if (aps)
1325 return aps;
1326 }
1327
1328 if (!aps && ab->next) {
1329 aps = (struct acpi_php_slot *)get_acpi_slot (ab->next, sun);
1330 if (aps)
1331 return aps;
1332 }
1333
1334 return aps;
1335
1336}
1337
1338#if 0
1339void * pciehprm_get_slot(struct slot *slot)
1340{
1341 struct acpi_bridge *ab = acpi_bridges_head;
1342 struct acpi_php_slot *aps = get_acpi_slot (ab, slot->number);
1343
1344 aps->slot = slot;
1345
1346 dbg("Got acpi slot sun(%x): s:b:d:f(%x:%x:%x:%x)\n", aps->sun, aps->seg, aps->bus, aps->dev, aps->fun);
1347
1348 return (void *)aps;
1349}
1350#endif
1351
1352static void pciehprm_dump_func_res( struct pci_func *fun)
1353{
1354 struct pci_func *func = fun;
1355
1356 if (func->bus_head) {
1357 dbg(": BUS Resources:\n");
1358 print_pci_resource (func->bus_head);
1359 }
1360 if (func->io_head) {
1361 dbg(": IO Resources:\n");
1362 print_pci_resource (func->io_head);
1363 }
1364 if (func->mem_head) {
1365 dbg(": MEM Resources:\n");
1366 print_pci_resource (func->mem_head);
1367 }
1368 if (func->p_mem_head) {
1369 dbg(": PMEM Resources:\n");
1370 print_pci_resource (func->p_mem_head);
1371 }
1372}
1373
1374static void pciehprm_dump_ctrl_res( struct controller *ctlr)
1375{
1376 struct controller *ctrl = ctlr;
1377
1378 if (ctrl->bus_head) {
1379 dbg(": BUS Resources:\n");
1380 print_pci_resource (ctrl->bus_head);
1381 }
1382 if (ctrl->io_head) {
1383 dbg(": IO Resources:\n");
1384 print_pci_resource (ctrl->io_head);
1385 }
1386 if (ctrl->mem_head) {
1387 dbg(": MEM Resources:\n");
1388 print_pci_resource (ctrl->mem_head);
1389 }
1390 if (ctrl->p_mem_head) {
1391 dbg(": PMEM Resources:\n");
1392 print_pci_resource (ctrl->p_mem_head);
1393 }
1394}
1395
1396static int pciehprm_get_used_resources (
1397 struct controller *ctrl,
1398 struct pci_func *func
1399 )
1400{
1401 return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
1402}
1403
1404static int configure_existing_function(
1405 struct controller *ctrl,
1406 struct pci_func *func
1407 )
1408{
1409 int rc;
1410
1411 /* see how much resources the func has used. */
1412 rc = pciehprm_get_used_resources (ctrl, func);
1413
1414 if (!rc) {
1415 /* subtract the resources used by the func from ctrl resources */
1416 rc = pciehprm_delete_resources (&ctrl->bus_head, func->bus_head);
1417 rc |= pciehprm_delete_resources (&ctrl->io_head, func->io_head);
1418 rc |= pciehprm_delete_resources (&ctrl->mem_head, func->mem_head);
1419 rc |= pciehprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
1420 if (rc)
1421 warn("aCEF: cannot del used resources\n");
1422 } else
1423 err("aCEF: cannot get used resources\n");
1424
1425 return rc;
1426}
1427
1428static int bind_pci_resources_to_slots ( struct controller *ctrl)
1429{
1430 struct pci_func *func, new_func;
1431 int busn = ctrl->slot_bus;
1432 int devn, funn;
1433 u32 vid;
1434
1435 for (devn = 0; devn < 32; devn++) {
1436 for (funn = 0; funn < 8; funn++) {
1437 /*
1438 if (devn == ctrl->device && funn == ctrl->function)
1439 continue;
1440 */
1441 /* find out if this entry is for an occupied slot */
1442 vid = 0xFFFFFFFF;
1443 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
1444
1445 if (vid != 0xFFFFFFFF) {
1446 dbg("%s: vid = %x\n", __FUNCTION__, vid);
1447 func = pciehp_slot_find(busn, devn, funn);
1448 if (!func) {
1449 memset(&new_func, 0, sizeof(struct pci_func));
1450 new_func.bus = busn;
1451 new_func.device = devn;
1452 new_func.function = funn;
1453 new_func.is_a_board = 1;
1454 configure_existing_function(ctrl, &new_func);
1455 pciehprm_dump_func_res(&new_func);
1456 } else {
1457 configure_existing_function(ctrl, func);
1458 pciehprm_dump_func_res(func);
1459 }
1460 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
1461 }
1462 }
1463 }
1464
1465 return 0;
1466}
1467
1468static int bind_pci_resources(
1469 struct controller *ctrl,
1470 struct acpi_bridge *ab
1471 )
1472{
1473 int status = 0;
1474
1475 if (ab->bus_head) {
1476 dbg("bapr: BUS Resources add on PCI 0x%x\n", ab->bus);
1477 status = pciehprm_add_resources (&ctrl->bus_head, ab->bus_head);
1478 if (pciehprm_delete_resources (&ab->bus_head, ctrl->bus_head))
1479 warn("bapr: cannot sub BUS Resource on PCI 0x%x\n", ab->bus);
1480 if (status) {
1481 err("bapr: BUS Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1482 return status;
1483 }
1484 } else
1485 info("bapr: No BUS Resource on PCI 0x%x.\n", ab->bus);
1486
1487 if (ab->io_head) {
1488 dbg("bapr: IO Resources add on PCI 0x%x\n", ab->bus);
1489 status = pciehprm_add_resources (&ctrl->io_head, ab->io_head);
1490 if (pciehprm_delete_resources (&ab->io_head, ctrl->io_head))
1491 warn("bapr: cannot sub IO Resource on PCI 0x%x\n", ab->bus);
1492 if (status) {
1493 err("bapr: IO Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1494 return status;
1495 }
1496 } else
1497 info("bapr: No IO Resource on PCI 0x%x.\n", ab->bus);
1498
1499 if (ab->mem_head) {
1500 dbg("bapr: MEM Resources add on PCI 0x%x\n", ab->bus);
1501 status = pciehprm_add_resources (&ctrl->mem_head, ab->mem_head);
1502 if (pciehprm_delete_resources (&ab->mem_head, ctrl->mem_head))
1503 warn("bapr: cannot sub MEM Resource on PCI 0x%x\n", ab->bus);
1504 if (status) {
1505 err("bapr: MEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1506 return status;
1507 }
1508 } else
1509 info("bapr: No MEM Resource on PCI 0x%x.\n", ab->bus);
1510
1511 if (ab->p_mem_head) {
1512 dbg("bapr: PMEM Resources add on PCI 0x%x\n", ab->bus);
1513 status = pciehprm_add_resources (&ctrl->p_mem_head, ab->p_mem_head);
1514 if (pciehprm_delete_resources (&ab->p_mem_head, ctrl->p_mem_head))
1515 warn("bapr: cannot sub PMEM Resource on PCI 0x%x\n", ab->bus);
1516 if (status) {
1517 err("bapr: PMEM Resource add on PCI 0x%x: fail=0x%x\n", ab->bus, status);
1518 return status;
1519 }
1520 } else
1521 info("bapr: No PMEM Resource on PCI 0x%x.\n", ab->bus);
1522
1523 return status;
1524}
1525
1526static int no_pci_resources( struct acpi_bridge *ab)
1527{
1528 return !(ab->p_mem_head || ab->mem_head || ab->io_head || ab->bus_head);
1529}
1530
1531static int find_pci_bridge_resources (
1532 struct controller *ctrl,
1533 struct acpi_bridge *ab
1534 )
1535{
1536 int rc = 0;
1537 struct pci_func func;
1538
1539 memset(&func, 0, sizeof(struct pci_func));
1540
1541 func.bus = ab->pbus;
1542 func.device = ab->pdevice;
1543 func.function = ab->pfunction;
1544 func.is_a_board = 1;
1545
1546 /* Get used resources for this PCI bridge */
1547 rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
1548
1549 ab->io_head = func.io_head;
1550 ab->mem_head = func.mem_head;
1551 ab->p_mem_head = func.p_mem_head;
1552 ab->bus_head = func.bus_head;
1553 if (ab->bus_head)
1554 pciehprm_delete_resource(&ab->bus_head, ctrl->pci_dev->subordinate->number, 1);
1555
1556 return rc;
1557}
1558
1559static int get_pci_resources_from_bridge(
1560 struct controller *ctrl,
1561 struct acpi_bridge *ab
1562 )
1563{
1564 int rc = 0;
1565
1566 dbg("grfb: Get Resources for PCI 0x%x from actual PCI bridge 0x%x.\n", ctrl->bus, ab->bus);
1567
1568 rc = find_pci_bridge_resources (ctrl, ab);
1569
1570 pciehp_resource_sort_and_combine(&ab->bus_head);
1571 pciehp_resource_sort_and_combine(&ab->io_head);
1572 pciehp_resource_sort_and_combine(&ab->mem_head);
1573 pciehp_resource_sort_and_combine(&ab->p_mem_head);
1574
1575 pciehprm_add_resources (&ab->tbus_head, ab->bus_head);
1576 pciehprm_add_resources (&ab->tio_head, ab->io_head);
1577 pciehprm_add_resources (&ab->tmem_head, ab->mem_head);
1578 pciehprm_add_resources (&ab->tp_mem_head, ab->p_mem_head);
1579
1580 return rc;
1581}
1582
1583static int get_pci_resources(
1584 struct controller *ctrl,
1585 struct acpi_bridge *ab
1586 )
1587{
1588 int rc = 0;
1589
1590 if (no_pci_resources(ab)) {
1591 dbg("spbr:PCI 0x%x has no resources. Get parent resources.\n", ab->bus);
1592 rc = get_pci_resources_from_bridge(ctrl, ab);
1593 }
1594
1595 return rc;
1596}
1597
1598/*
1599 * Get resources for this ctrl.
1600 * 1. get total resources from ACPI _CRS or bridge (this ctrl)
1601 * 2. find used resources of existing adapters
1602 * 3. subtract used resources from total resources
1603 */
1604int pciehprm_find_available_resources( struct controller *ctrl)
1605{
1606 int rc = 0;
1607 struct acpi_bridge *ab;
1608
1609 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->pci_dev->subordinate->number);
1610 if (!ab) {
1611 err("pfar:cannot locate acpi bridge of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1612 return -1;
1613 }
1614 if (no_pci_resources(ab)) {
1615 rc = get_pci_resources(ctrl, ab);
1616 if (rc) {
1617 err("pfar:cannot get pci resources of PCI 0x%x.\n", ctrl->pci_dev->subordinate->number);
1618 return -1;
1619 }
1620 }
1621
1622 rc = bind_pci_resources(ctrl, ab);
1623 dbg("pfar:pre-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1624 pciehprm_dump_ctrl_res(ctrl);
1625
1626 bind_pci_resources_to_slots (ctrl);
1627
1628 dbg("pfar:post-Bind PCI 0x%x Ctrl Resource Dump\n", ctrl->pci_dev->subordinate->number);
1629 pciehprm_dump_ctrl_res(ctrl);
1630
1631 return rc;
1632}
1633
1634int pciehprm_set_hpp(
1635 struct controller *ctrl,
1636 struct pci_func *func,
1637 u8 card_type
1638 )
1639{
1640 struct acpi_bridge *ab;
1641 struct pci_bus lpci_bus, *pci_bus;
1642 int rc = 0;
1643 unsigned int devfn;
1644 u8 cls= 0x08; /* default cache line size */
1645 u8 lt = 0x40; /* default latency timer */
1646 u8 ep = 0;
1647 u8 es = 0;
1648
1649 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1650 pci_bus = &lpci_bus;
1651 pci_bus->number = func->bus;
1652 devfn = PCI_DEVFN(func->device, func->function);
1653
1654 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1655
1656 if (ab) {
1657 if (ab->_hpp) {
1658 lt = (u8)ab->_hpp->latency_timer;
1659 cls = (u8)ab->_hpp->cache_line_size;
1660 ep = (u8)ab->_hpp->enable_perr;
1661 es = (u8)ab->_hpp->enable_serr;
1662 } else
1663 dbg("_hpp: no _hpp for B/D/F=%#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1664 } else
1665 dbg("_hpp: no acpi bridge for B/D/F = %#x/%#x/%#x. use default value\n", func->bus, func->device, func->function);
1666
1667
1668 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1669 /* set subordinate Latency Timer */
1670 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, lt);
1671 } 252 }
1672
1673 /* set base Latency Timer */
1674 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, lt);
1675 dbg(" set latency timer =0x%02x: %x\n", lt, rc);
1676
1677 rc |= pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, cls);
1678 dbg(" set cache_line_size=0x%02x: %x\n", cls, rc);
1679
1680 return rc;
1681} 253}
1682 254
1683void pciehprm_enable_card(
1684 struct controller *ctrl,
1685 struct pci_func *func,
1686 u8 card_type)
1687{
1688 u16 command, cmd, bcommand, bcmd;
1689 struct pci_bus lpci_bus, *pci_bus;
1690 struct acpi_bridge *ab;
1691 unsigned int devfn;
1692 int rc;
1693
1694 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
1695 pci_bus = &lpci_bus;
1696 pci_bus->number = func->bus;
1697 devfn = PCI_DEVFN(func->device, func->function);
1698
1699 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &cmd);
1700
1701 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
1702 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcmd);
1703 }
1704
1705 command = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
1706 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
1707 bcommand = bcmd | PCI_BRIDGE_CTL_NO_ISA;
1708
1709 ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus);
1710 if (ab) {
1711 if (ab->_hpp) {
1712 if (ab->_hpp->enable_perr) {
1713 command |= PCI_COMMAND_PARITY;
1714 bcommand |= PCI_BRIDGE_CTL_PARITY;
1715 } else {
1716 command &= ~PCI_COMMAND_PARITY;
1717 bcommand &= ~PCI_BRIDGE_CTL_PARITY;
1718 }
1719 if (ab->_hpp->enable_serr) {
1720 command |= PCI_COMMAND_SERR;
1721 bcommand |= PCI_BRIDGE_CTL_SERR;
1722 } else {
1723 command &= ~PCI_COMMAND_SERR;
1724 bcommand &= ~PCI_BRIDGE_CTL_SERR;
1725 }
1726 } else
1727 dbg("no _hpp for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1728 } else
1729 dbg("no acpi bridge for B/D/F = %#x/%#x/%#x.\n", func->bus, func->device, func->function);
1730
1731 if (command != cmd) {
1732 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
1733 }
1734 if ((card_type == PCI_HEADER_TYPE_BRIDGE) && (bcommand != bcmd)) {
1735 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
1736 }
1737}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.c b/drivers/pci/hotplug/pciehprm_nonacpi.c
index 33b2c69a0829..29180dfe8493 100644
--- a/drivers/pci/hotplug/pciehprm_nonacpi.c
+++ b/drivers/pci/hotplug/pciehprm_nonacpi.c
@@ -27,478 +27,21 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
33#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/sched.h>
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/init.h>
36#include <linux/slab.h> 35#include <linux/slab.h>
37
38#include <asm/uaccess.h>
39#ifdef CONFIG_IA64
40#include <asm/iosapic.h>
41#endif
42
43#include "pciehp.h" 36#include "pciehp.h"
44#include "pciehprm.h"
45#include "pciehprm_nonacpi.h"
46
47 37
48void pciehprm_cleanup(void) 38void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
39 struct hotplug_params *hpp)
49{ 40{
50 return; 41 return;
51} 42}
52 43
53int pciehprm_print_pirt(void) 44int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
54{
55 return 0;
56}
57
58int pciehprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, u8 busnum, u8 devnum)
59{
60
61 *sun = (u8) (ctrl->first_slot);
62 return 0;
63}
64
65
66static void print_pci_resource ( struct pci_resource *aprh)
67{
68 struct pci_resource *res;
69
70 for (res = aprh; res; res = res->next)
71 dbg(" base= 0x%x length= 0x%x\n", res->base, res->length);
72}
73
74
75static void phprm_dump_func_res( struct pci_func *fun)
76{
77 struct pci_func *func = fun;
78
79 if (func->bus_head) {
80 dbg(": BUS Resources:\n");
81 print_pci_resource (func->bus_head);
82 }
83 if (func->io_head) {
84 dbg(": IO Resources:\n");
85 print_pci_resource (func->io_head);
86 }
87 if (func->mem_head) {
88 dbg(": MEM Resources:\n");
89 print_pci_resource (func->mem_head);
90 }
91 if (func->p_mem_head) {
92 dbg(": PMEM Resources:\n");
93 print_pci_resource (func->p_mem_head);
94 }
95}
96
97static int phprm_get_used_resources (
98 struct controller *ctrl,
99 struct pci_func *func
100 )
101{
102 return pciehp_save_used_resources (ctrl, func, !DISABLE_CARD);
103}
104
105static int phprm_delete_resource(
106 struct pci_resource **aprh,
107 ulong base,
108 ulong size)
109{
110 struct pci_resource *res;
111 struct pci_resource *prevnode;
112 struct pci_resource *split_node;
113 ulong tbase;
114
115 pciehp_resource_sort_and_combine(aprh);
116
117 for (res = *aprh; res; res = res->next) {
118 if (res->base > base)
119 continue;
120
121 if ((res->base + res->length) < (base + size))
122 continue;
123
124 if (res->base < base) {
125 tbase = base;
126
127 if ((res->length - (tbase - res->base)) < size)
128 continue;
129
130 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
131 if (!split_node)
132 return -ENOMEM;
133
134 split_node->base = res->base;
135 split_node->length = tbase - res->base;
136 res->base = tbase;
137 res->length -= split_node->length;
138
139 split_node->next = res->next;
140 res->next = split_node;
141 }
142
143 if (res->length >= size) {
144 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
145 if (!split_node)
146 return -ENOMEM;
147
148 split_node->base = res->base + size;
149 split_node->length = res->length - size;
150 res->length = size;
151
152 split_node->next = res->next;
153 res->next = split_node;
154 }
155
156 if (*aprh == res) {
157 *aprh = res->next;
158 } else {
159 prevnode = *aprh;
160 while (prevnode->next != res)
161 prevnode = prevnode->next;
162
163 prevnode->next = res->next;
164 }
165 res->next = NULL;
166 kfree(res);
167 break;
168 }
169
170 return 0;
171}
172
173
174static int phprm_delete_resources(
175 struct pci_resource **aprh,
176 struct pci_resource *this
177 )
178{
179 struct pci_resource *res;
180
181 for (res = this; res; res = res->next)
182 phprm_delete_resource(aprh, res->base, res->length);
183
184 return 0;
185}
186
187
188static int configure_existing_function(
189 struct controller *ctrl,
190 struct pci_func *func
191 )
192{
193 int rc;
194
195 /* see how much resources the func has used. */
196 rc = phprm_get_used_resources (ctrl, func);
197
198 if (!rc) {
199 /* subtract the resources used by the func from ctrl resources */
200 rc = phprm_delete_resources (&ctrl->bus_head, func->bus_head);
201 rc |= phprm_delete_resources (&ctrl->io_head, func->io_head);
202 rc |= phprm_delete_resources (&ctrl->mem_head, func->mem_head);
203 rc |= phprm_delete_resources (&ctrl->p_mem_head, func->p_mem_head);
204 if (rc)
205 warn("aCEF: cannot del used resources\n");
206 } else
207 err("aCEF: cannot get used resources\n");
208
209 return rc;
210}
211
212static int pciehprm_delete_resource(
213 struct pci_resource **aprh,
214 ulong base,
215 ulong size)
216{
217 struct pci_resource *res;
218 struct pci_resource *prevnode;
219 struct pci_resource *split_node;
220 ulong tbase;
221
222 pciehp_resource_sort_and_combine(aprh);
223
224 for (res = *aprh; res; res = res->next) {
225 if (res->base > base)
226 continue;
227
228 if ((res->base + res->length) < (base + size))
229 continue;
230
231 if (res->base < base) {
232 tbase = base;
233
234 if ((res->length - (tbase - res->base)) < size)
235 continue;
236
237 split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
238 if (!split_node)
239 return -ENOMEM;
240
241 split_node->base = res->base;
242 split_node->length = tbase - res->base;
243 res->base = tbase;
244 res->length -= split_node->length;
245
246 split_node->next = res->next;
247 res->next = split_node;
248 }
249
250 if (res->length >= size) {
251 split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
252 if (!split_node)
253 return -ENOMEM;
254
255 split_node->base = res->base + size;
256 split_node->length = res->length - size;
257 res->length = size;
258
259 split_node->next = res->next;
260 res->next = split_node;
261 }
262
263 if (*aprh == res) {
264 *aprh = res->next;
265 } else {
266 prevnode = *aprh;
267 while (prevnode->next != res)
268 prevnode = prevnode->next;
269
270 prevnode->next = res->next;
271 }
272 res->next = NULL;
273 kfree(res);
274 break;
275 }
276
277 return 0;
278}
279
280static int bind_pci_resources_to_slots ( struct controller *ctrl)
281{ 45{
282 struct pci_func *func, new_func;
283 int busn = ctrl->slot_bus;
284 int devn, funn;
285 u32 vid;
286
287 for (devn = 0; devn < 32; devn++) {
288 for (funn = 0; funn < 8; funn++) {
289 /*
290 if (devn == ctrl->device && funn == ctrl->function)
291 continue;
292 */
293 /* find out if this entry is for an occupied slot */
294 vid = 0xFFFFFFFF;
295
296 pci_bus_read_config_dword(ctrl->pci_dev->subordinate, PCI_DEVFN(devn, funn), PCI_VENDOR_ID, &vid);
297
298 if (vid != 0xFFFFFFFF) {
299 dbg("%s: vid = %x bus %x dev %x fun %x\n", __FUNCTION__,
300 vid, busn, devn, funn);
301 func = pciehp_slot_find(busn, devn, funn);
302 dbg("%s: func = %p\n", __FUNCTION__,func);
303 if (!func) {
304 memset(&new_func, 0, sizeof(struct pci_func));
305 new_func.bus = busn;
306 new_func.device = devn;
307 new_func.function = funn;
308 new_func.is_a_board = 1;
309 configure_existing_function(ctrl, &new_func);
310 phprm_dump_func_res(&new_func);
311 } else {
312 configure_existing_function(ctrl, func);
313 phprm_dump_func_res(func);
314 }
315 dbg("aCCF:existing PCI 0x%x Func ResourceDump\n", ctrl->bus);
316 }
317 }
318 }
319
320 return 0; 46 return 0;
321} 47}
322
323static void phprm_dump_ctrl_res( struct controller *ctlr)
324{
325 struct controller *ctrl = ctlr;
326
327 if (ctrl->bus_head) {
328 dbg(": BUS Resources:\n");
329 print_pci_resource (ctrl->bus_head);
330 }
331 if (ctrl->io_head) {
332 dbg(": IO Resources:\n");
333 print_pci_resource (ctrl->io_head);
334 }
335 if (ctrl->mem_head) {
336 dbg(": MEM Resources:\n");
337 print_pci_resource (ctrl->mem_head);
338 }
339 if (ctrl->p_mem_head) {
340 dbg(": PMEM Resources:\n");
341 print_pci_resource (ctrl->p_mem_head);
342 }
343}
344
345/*
346 * phprm_find_available_resources
347 *
348 * Finds available memory, IO, and IRQ resources for programming
349 * devices which may be added to the system
350 * this function is for hot plug ADD!
351 *
352 * returns 0 if success
353 */
354int pciehprm_find_available_resources(struct controller *ctrl)
355{
356 struct pci_func func;
357 u32 rc;
358
359 memset(&func, 0, sizeof(struct pci_func));
360
361 func.bus = ctrl->bus;
362 func.device = ctrl->device;
363 func.function = ctrl->function;
364 func.is_a_board = 1;
365
366 /* Get resources for this PCI bridge */
367 rc = pciehp_save_used_resources (ctrl, &func, !DISABLE_CARD);
368 dbg("%s: pciehp_save_used_resources rc = %d\n", __FUNCTION__, rc);
369
370 if (func.mem_head)
371 func.mem_head->next = ctrl->mem_head;
372 ctrl->mem_head = func.mem_head;
373
374 if (func.p_mem_head)
375 func.p_mem_head->next = ctrl->p_mem_head;
376 ctrl->p_mem_head = func.p_mem_head;
377
378 if (func.io_head)
379 func.io_head->next = ctrl->io_head;
380 ctrl->io_head = func.io_head;
381
382 if(func.bus_head)
383 func.bus_head->next = ctrl->bus_head;
384 ctrl->bus_head = func.bus_head;
385
386 if (ctrl->bus_head)
387 pciehprm_delete_resource(&ctrl->bus_head, ctrl->pci_dev->subordinate->number, 1);
388
389 dbg("%s:pre-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
390 phprm_dump_ctrl_res(ctrl);
391
392 dbg("%s: before bind_pci_resources_to slots\n", __FUNCTION__);
393
394 bind_pci_resources_to_slots (ctrl);
395
396 dbg("%s:post-Bind PCI 0x%x Ctrl Resource Dump\n", __FUNCTION__, ctrl->bus);
397 phprm_dump_ctrl_res(ctrl);
398
399 return (rc);
400}
401
402int pciehprm_set_hpp(
403 struct controller *ctrl,
404 struct pci_func *func,
405 u8 card_type)
406{
407 u32 rc;
408 u8 temp_byte;
409 struct pci_bus lpci_bus, *pci_bus;
410 unsigned int devfn;
411 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
412 pci_bus = &lpci_bus;
413 pci_bus->number = func->bus;
414 devfn = PCI_DEVFN(func->device, func->function);
415
416 temp_byte = 0x40; /* hard coded value for LT */
417 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
418 /* set subordinate Latency Timer */
419 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
420
421 if (rc) {
422 dbg("%s: set secondary LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__,
423 func->bus, func->device, func->function);
424 return rc;
425 }
426 }
427
428 /* set base Latency Timer */
429 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
430
431 if (rc) {
432 dbg("%s: set LT error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
433 return rc;
434 }
435
436 /* set Cache Line size */
437 temp_byte = 0x08; /* hard coded value for CLS */
438
439 rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
440
441 if (rc) {
442 dbg("%s: set CLS error. b:d:f(%02x:%02x:%02x)\n", __FUNCTION__, func->bus, func->device, func->function);
443 }
444
445 /* set enable_perr */
446 /* set enable_serr */
447
448 return rc;
449}
450
451void pciehprm_enable_card(
452 struct controller *ctrl,
453 struct pci_func *func,
454 u8 card_type)
455{
456 u16 command, bcommand;
457 struct pci_bus lpci_bus, *pci_bus;
458 unsigned int devfn;
459 int rc;
460
461 memcpy(&lpci_bus, ctrl->pci_bus, sizeof(lpci_bus));
462 pci_bus = &lpci_bus;
463 pci_bus->number = func->bus;
464 devfn = PCI_DEVFN(func->device, func->function);
465
466 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &command);
467
468 command |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR
469 | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
470 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
471
472 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command);
473
474 if (card_type == PCI_HEADER_TYPE_BRIDGE) {
475
476 rc = pci_bus_read_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, &bcommand);
477
478 bcommand |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR
479 | PCI_BRIDGE_CTL_NO_ISA;
480
481 rc = pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, bcommand);
482 }
483}
484
485static int legacy_pciehprm_init_pci(void)
486{
487 return 0;
488}
489
490int pciehprm_init(enum php_ctlr_type ctrl_type)
491{
492 int retval;
493
494 switch (ctrl_type) {
495 case PCI:
496 retval = legacy_pciehprm_init_pci();
497 break;
498 default:
499 retval = -ENODEV;
500 break;
501 }
502
503 return retval;
504}
diff --git a/drivers/pci/hotplug/pciehprm_nonacpi.h b/drivers/pci/hotplug/pciehprm_nonacpi.h
deleted file mode 100644
index b10603b0e958..000000000000
--- a/drivers/pci/hotplug/pciehprm_nonacpi.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * PCIEHPRM NONACPI: PHP Resource Manager for Non-ACPI/Legacy platform
3 *
4 * Copyright (C) 1995,2001 Compaq Computer Corporation
5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
6 * Copyright (C) 2001 IBM Corp.
7 * Copyright (C) 2003-2004 Intel Corporation
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or (at
14 * your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
19 * NON INFRINGEMENT. See the GNU General Public License for more
20 * details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
27 *
28 */
29
30#ifndef _PCIEHPRM_NONACPI_H_
31#define _PCIEHPRM_NONACPI_H_
32
33struct irq_info {
34 u8 bus, devfn; /* bus, device and function */
35 struct {
36 u8 link; /* IRQ line ID, chipset dependent, 0=not routed */
37 u16 bitmap; /* Available IRQs */
38 } __attribute__ ((packed)) irq[4];
39 u8 slot; /* slot number, 0=onboard */
40 u8 rfu;
41} __attribute__ ((packed));
42
43struct irq_routing_table {
44 u32 signature; /* PIRQ_SIGNATURE should be here */
45 u16 version; /* PIRQ_VERSION */
46 u16 size; /* Table size in bytes */
47 u8 rtr_bus, rtr_devfn; /* Where the interrupt router lies */
48 u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
49 u16 rtr_vendor, rtr_device; /* Vendor and device ID of interrupt router */
50 u32 miniport_data; /* Crap */
51 u8 rfu[11];
52 u8 checksum; /* Modulo 256 checksum must give zero */
53 struct irq_info slots[0];
54} __attribute__ ((packed));
55
56#endif /* _PCIEHPRM_NONACPI_H_ */
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index fcb66b9a0e28..cc03609f45d0 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -134,43 +134,6 @@ static void rpadlpar_claim_one_bus(struct pci_bus *b)
134 rpadlpar_claim_one_bus(child_bus); 134 rpadlpar_claim_one_bus(child_bus);
135} 135}
136 136
137static int pci_add_secondary_bus(struct device_node *dn,
138 struct pci_dev *bridge_dev)
139{
140 struct pci_dn *pdn = dn->data;
141 struct pci_controller *hose = pdn->phb;
142 struct pci_bus *child;
143 u8 sec_busno;
144
145 /* Get busno of downstream bus */
146 pci_read_config_byte(bridge_dev, PCI_SECONDARY_BUS, &sec_busno);
147
148 /* Allocate and add to children of bridge_dev->bus */
149 child = pci_add_new_bus(bridge_dev->bus, bridge_dev, sec_busno);
150 if (!child) {
151 printk(KERN_ERR "%s: could not add secondary bus\n", __FUNCTION__);
152 return -ENOMEM;
153 }
154
155 sprintf(child->name, "PCI Bus #%02x", child->number);
156
157 /* Fixup subordinate bridge bases and resources */
158 pcibios_fixup_bus(child);
159
160 /* Claim new bus resources */
161 rpadlpar_claim_one_bus(bridge_dev->bus);
162
163 if (hose->last_busno < child->number)
164 hose->last_busno = child->number;
165
166 pdn->bussubno = child->number;
167
168 /* ioremap() for child bus, which may or may not succeed */
169 remap_bus_range(child);
170
171 return 0;
172}
173
174static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent, 137static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
175 struct device_node *dev_dn) 138 struct device_node *dev_dn)
176{ 139{
@@ -188,29 +151,41 @@ static struct pci_dev *dlpar_find_new_dev(struct pci_bus *parent,
188static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn) 151static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
189{ 152{
190 struct pci_dn *pdn = dn->data; 153 struct pci_dn *pdn = dn->data;
191 struct pci_controller *hose = pdn->phb; 154 struct pci_controller *phb = pdn->phb;
192 struct pci_dev *dev = NULL; 155 struct pci_dev *dev = NULL;
193 156
194 /* Scan phb bus for EADS device, adding new one to bus->devices */ 157 rpaphp_eeh_init_nodes(dn);
195 if (!pci_scan_single_device(hose->bus, pdn->devfn)) { 158 /* Add EADS device to PHB bus, adding new entry to bus->devices */
196 printk(KERN_ERR "%s: found no device on bus\n", __FUNCTION__); 159 dev = of_create_pci_dev(dn, phb->bus, pdn->devfn);
160 if (!dev) {
161 printk(KERN_ERR "%s: failed to create pci dev for %s\n",
162 __FUNCTION__, dn->full_name);
197 return NULL; 163 return NULL;
198 } 164 }
199 165
166 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
167 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
168 of_scan_pci_bridge(dn, dev);
169
170 rpaphp_init_new_devs(dev->subordinate);
171
172 /* Claim new bus resources */
173 rpadlpar_claim_one_bus(dev->bus);
174
175 /* ioremap() for child bus, which may or may not succeed */
176 (void) remap_bus_range(dev->bus);
177
200 /* Add new devices to global lists. Register in proc, sysfs. */ 178 /* Add new devices to global lists. Register in proc, sysfs. */
201 pci_bus_add_devices(hose->bus); 179 pci_bus_add_devices(phb->bus);
202 180
203 /* Confirm new bridge dev was created */ 181 /* Confirm new bridge dev was created */
204 dev = dlpar_find_new_dev(hose->bus, dn); 182 dev = dlpar_find_new_dev(phb->bus, dn);
205 if (dev) { 183 if (dev) {
206 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) { 184 if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
207 printk(KERN_ERR "%s: unexpected header type %d\n", 185 printk(KERN_ERR "%s: unexpected header type %d\n",
208 __FUNCTION__, dev->hdr_type); 186 __FUNCTION__, dev->hdr_type);
209 return NULL; 187 return NULL;
210 } 188 }
211
212 if (pci_add_secondary_bus(dn, dev))
213 return NULL;
214 } 189 }
215 190
216 return dev; 191 return dev;
@@ -219,7 +194,6 @@ static struct pci_dev *dlpar_pci_add_bus(struct device_node *dn)
219static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn) 194static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
220{ 195{
221 struct pci_dev *dev; 196 struct pci_dev *dev;
222 int rc;
223 197
224 if (rpaphp_find_pci_bus(dn)) 198 if (rpaphp_find_pci_bus(dn))
225 return -EINVAL; 199 return -EINVAL;
@@ -232,15 +206,6 @@ static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
232 return -EIO; 206 return -EIO;
233 } 207 }
234 208
235 if (dn->child) {
236 rc = rpaphp_config_pci_adapter(dev->subordinate);
237 if (rc < 0) {
238 printk(KERN_ERR "%s: unable to enable slot %s\n",
239 __FUNCTION__, drc_name);
240 return -EIO;
241 }
242 }
243
244 /* Add hotplug slot */ 209 /* Add hotplug slot */
245 if (rpaphp_add_slot(dn)) { 210 if (rpaphp_add_slot(dn)) {
246 printk(KERN_ERR "%s: unable to add hotplug slot %s\n", 211 printk(KERN_ERR "%s: unable to add hotplug slot %s\n",
@@ -306,7 +271,7 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn)
306{ 271{
307 struct pci_controller *phb; 272 struct pci_controller *phb;
308 273
309 if (PCI_DN(dn)->phb) { 274 if (PCI_DN(dn) && PCI_DN(dn)->phb) {
310 /* PHB already exists */ 275 /* PHB already exists */
311 return -EINVAL; 276 return -EINVAL;
312 } 277 }
@@ -435,6 +400,8 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
435 __FUNCTION__, drc_name); 400 __FUNCTION__, drc_name);
436 return -EIO; 401 return -EIO;
437 } 402 }
403 } else {
404 rpaphp_unconfig_pci_adapter(bus);
438 } 405 }
439 406
440 if (unmap_bus_range(bus)) { 407 if (unmap_bus_range(bus)) {
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 71ea5f9bb284..57ea71a7bda5 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -93,6 +93,8 @@ extern int rpaphp_claim_resource(struct pci_dev *dev, int resource);
93extern int rpaphp_enable_pci_slot(struct slot *slot); 93extern int rpaphp_enable_pci_slot(struct slot *slot);
94extern int register_pci_slot(struct slot *slot); 94extern int register_pci_slot(struct slot *slot);
95extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); 95extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value);
96extern void rpaphp_init_new_devs(struct pci_bus *bus);
97extern void rpaphp_eeh_init_nodes(struct device_node *dn);
96 98
97extern int rpaphp_config_pci_adapter(struct pci_bus *bus); 99extern int rpaphp_config_pci_adapter(struct pci_bus *bus);
98extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus); 100extern int rpaphp_unconfig_pci_adapter(struct pci_bus *bus);
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index f7c12d7dfcfc..a7859a84d1ae 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -154,8 +154,7 @@ exit:
154} 154}
155 155
156/* Must be called before pci_bus_add_devices */ 156/* Must be called before pci_bus_add_devices */
157static void 157void rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
158rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
159{ 158{
160 struct pci_dev *dev; 159 struct pci_dev *dev;
161 160
@@ -184,6 +183,20 @@ rpaphp_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
184 } 183 }
185} 184}
186 185
186static void rpaphp_eeh_add_bus_device(struct pci_bus *bus)
187{
188 struct pci_dev *dev;
189
190 list_for_each_entry(dev, &bus->devices, bus_list) {
191 eeh_add_device_late(dev);
192 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
193 struct pci_bus *subbus = dev->subordinate;
194 if (subbus)
195 rpaphp_eeh_add_bus_device (subbus);
196 }
197 }
198}
199
187static int rpaphp_pci_config_bridge(struct pci_dev *dev) 200static int rpaphp_pci_config_bridge(struct pci_dev *dev)
188{ 201{
189 u8 sec_busno; 202 u8 sec_busno;
@@ -217,6 +230,13 @@ static int rpaphp_pci_config_bridge(struct pci_dev *dev)
217 return 0; 230 return 0;
218} 231}
219 232
233void rpaphp_init_new_devs(struct pci_bus *bus)
234{
235 rpaphp_fixup_new_pci_devices(bus, 0);
236 rpaphp_eeh_add_bus_device(bus);
237}
238EXPORT_SYMBOL_GPL(rpaphp_init_new_devs);
239
220/***************************************************************************** 240/*****************************************************************************
221 rpaphp_pci_config_slot() will configure all devices under the 241 rpaphp_pci_config_slot() will configure all devices under the
222 given slot->dn and return the the first pci_dev. 242 given slot->dn and return the the first pci_dev.
@@ -233,36 +253,51 @@ rpaphp_pci_config_slot(struct pci_bus *bus)
233 if (!dn || !dn->child) 253 if (!dn || !dn->child)
234 return NULL; 254 return NULL;
235 255
236 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); 256 if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
257 of_scan_bus(dn, bus);
258 if (list_empty(&bus->devices)) {
259 err("%s: No new device found\n", __FUNCTION__);
260 return NULL;
261 }
237 262
238 /* pci_scan_slot should find all children */ 263 rpaphp_init_new_devs(bus);
239 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
240 if (num) {
241 rpaphp_fixup_new_pci_devices(bus, 1);
242 pci_bus_add_devices(bus); 264 pci_bus_add_devices(bus);
243 } 265 dev = list_entry(&bus->devices, struct pci_dev, bus_list);
244 if (list_empty(&bus->devices)) { 266 } else {
245 err("%s: No new device found\n", __FUNCTION__); 267 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
246 return NULL; 268
247 } 269 /* pci_scan_slot should find all children */
248 list_for_each_entry(dev, &bus->devices, bus_list) { 270 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
249 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) 271 if (num) {
250 rpaphp_pci_config_bridge(dev); 272 rpaphp_fixup_new_pci_devices(bus, 1);
273 pci_bus_add_devices(bus);
274 }
275 if (list_empty(&bus->devices)) {
276 err("%s: No new device found\n", __FUNCTION__);
277 return NULL;
278 }
279 list_for_each_entry(dev, &bus->devices, bus_list) {
280 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
281 rpaphp_pci_config_bridge(dev);
282
283 rpaphp_eeh_add_bus_device(bus);
284 }
251 } 285 }
252 286
253 return dev; 287 return dev;
254} 288}
255 289
256static void enable_eeh(struct device_node *dn) 290void rpaphp_eeh_init_nodes(struct device_node *dn)
257{ 291{
258 struct device_node *sib; 292 struct device_node *sib;
259 293
260 for (sib = dn->child; sib; sib = sib->sibling) 294 for (sib = dn->child; sib; sib = sib->sibling)
261 enable_eeh(sib); 295 rpaphp_eeh_init_nodes(sib);
262 eeh_add_device_early(dn); 296 eeh_add_device_early(dn);
263 return; 297 return;
264 298
265} 299}
300EXPORT_SYMBOL_GPL(rpaphp_eeh_init_nodes);
266 301
267static void print_slot_pci_funcs(struct pci_bus *bus) 302static void print_slot_pci_funcs(struct pci_bus *bus)
268{ 303{
@@ -289,7 +324,7 @@ int rpaphp_config_pci_adapter(struct pci_bus *bus)
289 if (!dn) 324 if (!dn)
290 goto exit; 325 goto exit;
291 326
292 enable_eeh(dn); 327 rpaphp_eeh_init_nodes(dn);
293 dev = rpaphp_pci_config_slot(bus); 328 dev = rpaphp_pci_config_slot(bus);
294 if (!dev) { 329 if (!dev) {
295 err("%s: can't find any devices.\n", __FUNCTION__); 330 err("%s: can't find any devices.\n", __FUNCTION__);
@@ -331,6 +366,7 @@ int rpaphp_unconfig_pci_adapter(struct pci_bus *bus)
331 } 366 }
332 return 0; 367 return 0;
333} 368}
369EXPORT_SYMBOL_GPL(rpaphp_unconfig_pci_adapter);
334 370
335static int setup_pci_hotplug_slot_info(struct slot *slot) 371static int setup_pci_hotplug_slot_info(struct slot *slot)
336{ 372{
@@ -444,8 +480,8 @@ int rpaphp_enable_pci_slot(struct slot *slot)
444 retval = rpaphp_config_pci_adapter(slot->bus); 480 retval = rpaphp_config_pci_adapter(slot->bus);
445 if (!retval) { 481 if (!retval) {
446 slot->state = CONFIGURED; 482 slot->state = CONFIGURED;
447 dbg("%s: PCI devices in slot[%s] has been configured\n", 483 info("%s: devices in slot[%s] configured\n",
448 __FUNCTION__, slot->name); 484 __FUNCTION__, slot->name);
449 } else { 485 } else {
450 slot->state = NOT_CONFIGURED; 486 slot->state = NOT_CONFIGURED;
451 dbg("%s: no pci_dev struct for adapter in slot[%s]\n", 487 dbg("%s: no pci_dev struct for adapter in slot[%s]\n",
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index b8e95acea3b6..38009bc0fd5d 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -34,7 +34,7 @@
34#include "../pci.h" 34#include "../pci.h"
35#include "shpchp.h" 35#include "shpchp.h"
36 36
37void program_fw_provided_values(struct pci_dev *dev) 37static void program_fw_provided_values(struct pci_dev *dev)
38{ 38{
39 u16 pci_cmd, pci_bctl; 39 u16 pci_cmd, pci_bctl;
40 struct pci_dev *cdev; 40 struct pci_dev *cdev;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index a2033552423c..202b7507a357 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,6 +23,8 @@
23#include "pci.h" 23#include "pci.h"
24#include "msi.h" 24#include "msi.h"
25 25
26#define MSI_TARGET_CPU first_cpu(cpu_online_map)
27
26static DEFINE_SPINLOCK(msi_lock); 28static DEFINE_SPINLOCK(msi_lock);
27static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; 29static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
28static kmem_cache_t* msi_cachep; 30static kmem_cache_t* msi_cachep;
@@ -92,6 +94,7 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
92 struct msi_desc *entry; 94 struct msi_desc *entry;
93 struct msg_address address; 95 struct msg_address address;
94 unsigned int irq = vector; 96 unsigned int irq = vector;
97 unsigned int dest_cpu = first_cpu(cpu_mask);
95 98
96 entry = (struct msi_desc *)msi_desc[vector]; 99 entry = (struct msi_desc *)msi_desc[vector];
97 if (!entry || !entry->dev) 100 if (!entry || !entry->dev)
@@ -108,9 +111,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
108 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos), 111 pci_read_config_dword(entry->dev, msi_lower_address_reg(pos),
109 &address.lo_address.value); 112 &address.lo_address.value);
110 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; 113 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
111 address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) << 114 address.lo_address.value |= (cpu_physical_id(dest_cpu) <<
112 MSI_TARGET_CPU_SHIFT); 115 MSI_TARGET_CPU_SHIFT);
113 entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask); 116 entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu);
114 pci_write_config_dword(entry->dev, msi_lower_address_reg(pos), 117 pci_write_config_dword(entry->dev, msi_lower_address_reg(pos),
115 address.lo_address.value); 118 address.lo_address.value);
116 set_native_irq_info(irq, cpu_mask); 119 set_native_irq_info(irq, cpu_mask);
@@ -123,9 +126,9 @@ static void set_msi_affinity(unsigned int vector, cpumask_t cpu_mask)
123 126
124 address.lo_address.value = readl(entry->mask_base + offset); 127 address.lo_address.value = readl(entry->mask_base + offset);
125 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK; 128 address.lo_address.value &= MSI_ADDRESS_DEST_ID_MASK;
126 address.lo_address.value |= (cpu_mask_to_apicid(cpu_mask) << 129 address.lo_address.value |= (cpu_physical_id(dest_cpu) <<
127 MSI_TARGET_CPU_SHIFT); 130 MSI_TARGET_CPU_SHIFT);
128 entry->msi_attrib.current_cpu = cpu_mask_to_apicid(cpu_mask); 131 entry->msi_attrib.current_cpu = cpu_physical_id(dest_cpu);
129 writel(address.lo_address.value, entry->mask_base + offset); 132 writel(address.lo_address.value, entry->mask_base + offset);
130 set_native_irq_info(irq, cpu_mask); 133 set_native_irq_info(irq, cpu_mask);
131 break; 134 break;
@@ -259,14 +262,15 @@ static void msi_data_init(struct msg_data *msi_data,
259static void msi_address_init(struct msg_address *msi_address) 262static void msi_address_init(struct msg_address *msi_address)
260{ 263{
261 unsigned int dest_id; 264 unsigned int dest_id;
265 unsigned long dest_phys_id = cpu_physical_id(MSI_TARGET_CPU);
262 266
263 memset(msi_address, 0, sizeof(struct msg_address)); 267 memset(msi_address, 0, sizeof(struct msg_address));
264 msi_address->hi_address = (u32)0; 268 msi_address->hi_address = (u32)0;
265 dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT); 269 dest_id = (MSI_ADDRESS_HEADER << MSI_ADDRESS_HEADER_SHIFT);
266 msi_address->lo_address.u.dest_mode = MSI_DEST_MODE; 270 msi_address->lo_address.u.dest_mode = MSI_PHYSICAL_MODE;
267 msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE; 271 msi_address->lo_address.u.redirection_hint = MSI_REDIRECTION_HINT_MODE;
268 msi_address->lo_address.u.dest_id = dest_id; 272 msi_address->lo_address.u.dest_id = dest_id;
269 msi_address->lo_address.value |= (MSI_TARGET_CPU << MSI_TARGET_CPU_SHIFT); 273 msi_address->lo_address.value |= (dest_phys_id << MSI_TARGET_CPU_SHIFT);
270} 274}
271 275
272static int msi_free_vector(struct pci_dev* dev, int vector, int reassign); 276static int msi_free_vector(struct pci_dev* dev, int vector, int reassign);
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index e9e37abe1f76..a9b00cc2d885 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -91,9 +91,7 @@ acpi_query_osc (
91static acpi_status 91static acpi_status
92acpi_run_osc ( 92acpi_run_osc (
93 acpi_handle handle, 93 acpi_handle handle,
94 u32 level, 94 void *context)
95 void *context,
96 void **retval )
97{ 95{
98 acpi_status status; 96 acpi_status status;
99 struct acpi_object_list input; 97 struct acpi_object_list input;
@@ -184,7 +182,7 @@ EXPORT_SYMBOL(pci_osc_support_set);
184 * 182 *
185 * Attempt to take control from Firmware on requested control bits. 183 * Attempt to take control from Firmware on requested control bits.
186 **/ 184 **/
187acpi_status pci_osc_control_set(u32 flags) 185acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
188{ 186{
189 acpi_status status; 187 acpi_status status;
190 u32 ctrlset; 188 u32 ctrlset;
@@ -198,10 +196,7 @@ acpi_status pci_osc_control_set(u32 flags)
198 return AE_SUPPORT; 196 return AE_SUPPORT;
199 } 197 }
200 ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset; 198 ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset;
201 status = acpi_get_devices ( PCI_ROOT_HID_STRING, 199 status = acpi_run_osc(handle, ctrlset_buf);
202 acpi_run_osc,
203 ctrlset_buf,
204 NULL );
205 if (ACPI_FAILURE (status)) { 200 if (ACPI_FAILURE (status)) {
206 ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset; 201 ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset;
207 } 202 }
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index ae986e590b48..a9046d4b8af3 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -10,6 +10,7 @@
10#include <linux/mempolicy.h> 10#include <linux/mempolicy.h>
11#include <linux/string.h> 11#include <linux/string.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/sched.h>
13#include "pci.h" 14#include "pci.h"
14 15
15/* 16/*
@@ -36,7 +37,7 @@ struct pci_dynid {
36 * Adds a new dynamic pci device ID to this driver, 37 * Adds a new dynamic pci device ID to this driver,
37 * and causes the driver to probe for all devices again. 38 * and causes the driver to probe for all devices again.
38 */ 39 */
39static inline ssize_t 40static ssize_t
40store_new_id(struct device_driver *driver, const char *buf, size_t count) 41store_new_id(struct device_driver *driver, const char *buf, size_t count)
41{ 42{
42 struct pci_dynid *dynid; 43 struct pci_dynid *dynid;
@@ -363,15 +364,16 @@ static struct kobj_type pci_driver_kobj_type = {
363}; 364};
364 365
365/** 366/**
366 * pci_register_driver - register a new pci driver 367 * __pci_register_driver - register a new pci driver
367 * @drv: the driver structure to register 368 * @drv: the driver structure to register
369 * @owner: owner module of drv
368 * 370 *
369 * Adds the driver structure to the list of registered drivers. 371 * Adds the driver structure to the list of registered drivers.
370 * Returns a negative value on error, otherwise 0. 372 * Returns a negative value on error, otherwise 0.
371 * If no error occurred, the driver remains registered even if 373 * If no error occurred, the driver remains registered even if
372 * no device was claimed during registration. 374 * no device was claimed during registration.
373 */ 375 */
374int pci_register_driver(struct pci_driver *drv) 376int __pci_register_driver(struct pci_driver *drv, struct module *owner)
375{ 377{
376 int error; 378 int error;
377 379
@@ -388,7 +390,7 @@ int pci_register_driver(struct pci_driver *drv)
388 printk(KERN_WARNING "Warning: PCI driver %s has a struct " 390 printk(KERN_WARNING "Warning: PCI driver %s has a struct "
389 "device_driver shutdown method, please update!\n", 391 "device_driver shutdown method, please update!\n",
390 drv->name); 392 drv->name);
391 drv->driver.owner = drv->owner; 393 drv->driver.owner = owner;
392 drv->driver.kobj.ktype = &pci_driver_kobj_type; 394 drv->driver.kobj.ktype = &pci_driver_kobj_type;
393 395
394 spin_lock_init(&drv->dynids.lock); 396 spin_lock_init(&drv->dynids.lock);
@@ -525,7 +527,7 @@ postcore_initcall(pci_driver_init);
525 527
526EXPORT_SYMBOL(pci_match_id); 528EXPORT_SYMBOL(pci_match_id);
527EXPORT_SYMBOL(pci_match_device); 529EXPORT_SYMBOL(pci_match_device);
528EXPORT_SYMBOL(pci_register_driver); 530EXPORT_SYMBOL(__pci_register_driver);
529EXPORT_SYMBOL(pci_unregister_driver); 531EXPORT_SYMBOL(pci_unregister_driver);
530EXPORT_SYMBOL(pci_dev_driver); 532EXPORT_SYMBOL(pci_dev_driver);
531EXPORT_SYMBOL(pci_bus_type); 533EXPORT_SYMBOL(pci_bus_type);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e74d75843047..8e287a828d5d 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -63,11 +63,38 @@ pci_max_busnr(void)
63 return max; 63 return max;
64} 64}
65 65
66static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)
67{
68 u8 id;
69 int ttl = 48;
70
71 while (ttl--) {
72 pci_bus_read_config_byte(bus, devfn, pos, &pos);
73 if (pos < 0x40)
74 break;
75 pos &= ~3;
76 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID,
77 &id);
78 if (id == 0xff)
79 break;
80 if (id == cap)
81 return pos;
82 pos += PCI_CAP_LIST_NEXT;
83 }
84 return 0;
85}
86
87int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
88{
89 return __pci_find_next_cap(dev->bus, dev->devfn,
90 pos + PCI_CAP_LIST_NEXT, cap);
91}
92EXPORT_SYMBOL_GPL(pci_find_next_capability);
93
66static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap) 94static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
67{ 95{
68 u16 status; 96 u16 status;
69 u8 pos, id; 97 u8 pos;
70 int ttl = 48;
71 98
72 pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status); 99 pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
73 if (!(status & PCI_STATUS_CAP_LIST)) 100 if (!(status & PCI_STATUS_CAP_LIST))
@@ -76,24 +103,15 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
76 switch (hdr_type) { 103 switch (hdr_type) {
77 case PCI_HEADER_TYPE_NORMAL: 104 case PCI_HEADER_TYPE_NORMAL:
78 case PCI_HEADER_TYPE_BRIDGE: 105 case PCI_HEADER_TYPE_BRIDGE:
79 pci_bus_read_config_byte(bus, devfn, PCI_CAPABILITY_LIST, &pos); 106 pos = PCI_CAPABILITY_LIST;
80 break; 107 break;
81 case PCI_HEADER_TYPE_CARDBUS: 108 case PCI_HEADER_TYPE_CARDBUS:
82 pci_bus_read_config_byte(bus, devfn, PCI_CB_CAPABILITY_LIST, &pos); 109 pos = PCI_CB_CAPABILITY_LIST;
83 break; 110 break;
84 default: 111 default:
85 return 0; 112 return 0;
86 } 113 }
87 while (ttl-- && pos >= 0x40) { 114 return __pci_find_next_cap(bus, devfn, pos, cap);
88 pos &= ~3;
89 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, &id);
90 if (id == 0xff)
91 break;
92 if (id == cap)
93 return pos;
94 pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_NEXT, &pos);
95 }
96 return 0;
97} 115}
98 116
99/** 117/**
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 5627ce1d2b32..3a4f49f4effb 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -462,11 +462,11 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
462 462
463 pci_read_config_word(dev, 0x70, &hm); 463 pci_read_config_word(dev, 0x70, &hm);
464 hm &= PCI_BASE_ADDRESS_IO_MASK; 464 hm &= PCI_BASE_ADDRESS_IO_MASK;
465 quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c868 HW-mon"); 465 quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon");
466 466
467 pci_read_config_dword(dev, 0x90, &smb); 467 pci_read_config_dword(dev, 0x90, &smb);
468 smb &= PCI_BASE_ADDRESS_IO_MASK; 468 smb &= PCI_BASE_ADDRESS_IO_MASK;
469 quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c868 SMB"); 469 quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB");
470} 470}
471DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi ); 471DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi );
472 472
@@ -1243,6 +1243,21 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
1243} 1243}
1244DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); 1244DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos);
1245 1245
1246
1247static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
1248{
1249 /* rev 1 ncr53c810 chips don't set the class at all which means
1250 * they don't get their resources remapped. Fix that here.
1251 */
1252
1253 if (dev->class == PCI_CLASS_NOT_DEFINED) {
1254 printk(KERN_INFO "NCR 53c810 rev 1 detected, setting PCI class.\n");
1255 dev->class = PCI_CLASS_STORAGE_SCSI;
1256 }
1257}
1258DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
1259
1260
1246static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) 1261static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
1247{ 1262{
1248 while (f < end) { 1263 while (f < end) {
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index ccf20039e909..309eb557f9a3 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -156,7 +156,7 @@ config TCIC
156 156
157config PCMCIA_M8XX 157config PCMCIA_M8XX
158 tristate "MPC8xx PCMCIA support" 158 tristate "MPC8xx PCMCIA support"
159 depends on PCMCIA && PPC 159 depends on PCMCIA && PPC && 8xx
160 select PCCARD_NONSTATIC 160 select PCCARD_NONSTATIC
161 help 161 help
162 Say Y here to include support for PowerPC 8xx series PCMCIA 162 Say Y here to include support for PowerPC 8xx series PCMCIA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index fe37541abbfe..bcecf5133b7e 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -25,7 +25,7 @@ obj-$(CONFIG_PD6729) += pd6729.o
25obj-$(CONFIG_I82365) += i82365.o 25obj-$(CONFIG_I82365) += i82365.o
26obj-$(CONFIG_I82092) += i82092.o 26obj-$(CONFIG_I82092) += i82092.o
27obj-$(CONFIG_TCIC) += tcic.o 27obj-$(CONFIG_TCIC) += tcic.o
28obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o 28obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
29obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o 29obj-$(CONFIG_HD64465_PCMCIA) += hd64465_ss.o
30obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o 30obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
31obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o 31obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
@@ -47,10 +47,10 @@ au1x00_ss-$(CONFIG_MIPS_PB1200) += au1000_db1x00.o
47au1x00_ss-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o 47au1x00_ss-$(CONFIG_MIPS_PB1500) += au1000_pb1x00.o
48au1x00_ss-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o 48au1x00_ss-$(CONFIG_MIPS_DB1000) += au1000_db1x00.o
49au1x00_ss-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o 49au1x00_ss-$(CONFIG_MIPS_DB1100) += au1000_db1x00.o
50au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o 50au1x00_ss-$(CONFIG_MIPS_DB1200) += au1000_db1x00.o
51au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o 51au1x00_ss-$(CONFIG_MIPS_DB1500) += au1000_db1x00.o
52au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o 52au1x00_ss-$(CONFIG_MIPS_DB1550) += au1000_db1x00.o
53au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o 53au1x00_ss-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o
54 54
55sa1111_cs-y += sa1111_generic.o 55sa1111_cs-y += sa1111_generic.o
56sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o 56sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
diff --git a/drivers/pcmcia/au1000_db1x00.c b/drivers/pcmcia/au1000_db1x00.c
index 24cfee1a412c..abc13f28ba3f 100644
--- a/drivers/pcmcia/au1000_db1x00.c
+++ b/drivers/pcmcia/au1000_db1x00.c
@@ -30,6 +30,7 @@
30 * 30 *
31 */ 31 */
32 32
33#include <linux/config.h>
33#include <linux/module.h> 34#include <linux/module.h>
34#include <linux/kernel.h> 35#include <linux/kernel.h>
35#include <linux/errno.h> 36#include <linux/errno.h>
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
index b0e7908392a7..f2c970b5f4ff 100644
--- a/drivers/pcmcia/au1000_generic.h
+++ b/drivers/pcmcia/au1000_generic.h
@@ -22,6 +22,8 @@
22#define __ASM_AU1000_PCMCIA_H 22#define __ASM_AU1000_PCMCIA_H
23 23
24/* include the world */ 24/* include the world */
25#include <linux/config.h>
26
25#include <pcmcia/cs_types.h> 27#include <pcmcia/cs_types.h>
26#include <pcmcia/cs.h> 28#include <pcmcia/cs.h>
27#include <pcmcia/ss.h> 29#include <pcmcia/ss.h>
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
index d414a3bb50b9..fd5522ede867 100644
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ b/drivers/pcmcia/au1000_pb1x00.c
@@ -21,6 +21,7 @@
21 * with this program; if not, write to the Free Software Foundation, Inc., 21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 22 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 */ 23 */
24#include <linux/config.h>
24#include <linux/module.h> 25#include <linux/module.h>
25#include <linux/init.h> 26#include <linux/init.h>
26#include <linux/delay.h> 27#include <linux/delay.h>
@@ -30,7 +31,6 @@
30#include <linux/timer.h> 31#include <linux/timer.h>
31#include <linux/mm.h> 32#include <linux/mm.h>
32#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
33#include <linux/version.h>
34#include <linux/types.h> 34#include <linux/types.h>
35 35
36#include <pcmcia/cs_types.h> 36#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index f113b69d699b..01874b0bb03b 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -27,7 +27,6 @@
27 */ 27 */
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/config.h>
31#include <linux/delay.h> 30#include <linux/delay.h>
32#include <linux/ioport.h> 31#include <linux/ioport.h>
33#include <linux/kernel.h> 32#include <linux/kernel.h>
@@ -35,7 +34,6 @@
35#include <linux/timer.h> 34#include <linux/timer.h>
36#include <linux/mm.h> 35#include <linux/mm.h>
37#include <linux/proc_fs.h> 36#include <linux/proc_fs.h>
38#include <linux/version.h>
39#include <linux/types.h> 37#include <linux/types.h>
40 38
41#include <pcmcia/cs_types.h> 39#include <pcmcia/cs_types.h>
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 3afb682255a0..2dc3e611a9a3 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -334,10 +334,8 @@ void destroy_cis_cache(struct pcmcia_socket *s)
334 /* 334 /*
335 * If there was a fake CIS, destroy that as well. 335 * If there was a fake CIS, destroy that as well.
336 */ 336 */
337 if (s->fake_cis) { 337 kfree(s->fake_cis);
338 kfree(s->fake_cis); 338 s->fake_cis = NULL;
339 s->fake_cis = NULL;
340 }
341} 339}
342EXPORT_SYMBOL(destroy_cis_cache); 340EXPORT_SYMBOL(destroy_cis_cache);
343 341
@@ -386,10 +384,8 @@ int verify_cis_cache(struct pcmcia_socket *s)
386 384
387int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis) 385int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
388{ 386{
389 if (s->fake_cis != NULL) { 387 kfree(s->fake_cis);
390 kfree(s->fake_cis); 388 s->fake_cis = NULL;
391 s->fake_cis = NULL;
392 }
393 if (cis->Length > CISTPL_MAX_CIS_SIZE) 389 if (cis->Length > CISTPL_MAX_CIS_SIZE)
394 return CS_BAD_SIZE; 390 return CS_BAD_SIZE;
395 s->fake_cis = kmalloc(cis->Length, GFP_KERNEL); 391 s->fake_cis = kmalloc(cis->Length, GFP_KERNEL);
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index d5e76423a0ee..234cdca6fe13 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -331,10 +331,8 @@ static void shutdown_socket(struct pcmcia_socket *s)
331 cb_free(s); 331 cb_free(s);
332#endif 332#endif
333 s->functions = 0; 333 s->functions = 0;
334 if (s->config) { 334 kfree(s->config);
335 kfree(s->config); 335 s->config = NULL;
336 s->config = NULL;
337 }
338 336
339 { 337 {
340 int status; 338 int status;
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 7ce455d01cc9..4ddd76239b34 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1366,6 +1366,7 @@ static int __init init_i82365(void)
1366 if (sockets == 0) { 1366 if (sockets == 0) {
1367 printk("not found.\n"); 1367 printk("not found.\n");
1368 platform_device_unregister(&i82365_device); 1368 platform_device_unregister(&i82365_device);
1369 release_region(i365_base, 2);
1369 driver_unregister(&i82365_driver); 1370 driver_unregister(&i82365_driver);
1370 return -ENODEV; 1371 return -ENODEV;
1371 } 1372 }
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index f8bed87cf2f1..6d9f71cfcb34 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -39,7 +39,6 @@
39 39
40#include <asm/io.h> 40#include <asm/io.h>
41#include <asm/bitops.h> 41#include <asm/bitops.h>
42#include <asm/segment.h>
43#include <asm/system.h> 42#include <asm/system.h>
44 43
45#include <linux/kernel.h> 44#include <linux/kernel.h>
@@ -50,6 +49,7 @@
50#include <linux/ioport.h> 49#include <linux/ioport.h>
51#include <linux/delay.h> 50#include <linux/delay.h>
52#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/platform_device.h>
53 53
54#include <asm/mpc8xx.h> 54#include <asm/mpc8xx.h>
55#include <asm/8xx_immap.h> 55#include <asm/8xx_immap.h>
@@ -546,29 +546,11 @@ static void m8xx_shutdown(void)
546 free_irq(pcmcia_schlvl, NULL); 546 free_irq(pcmcia_schlvl, NULL);
547} 547}
548 548
549/* copied from tcic.c */
550
551static int m8xx_drv_suspend(struct device *dev, pm_message_t state, u32 level)
552{
553 int ret = 0;
554 if (level == SUSPEND_SAVE_STATE)
555 ret = pcmcia_socket_dev_suspend(dev, state);
556 return ret;
557}
558
559static int m8xx_drv_resume(struct device *dev, u32 level)
560{
561 int ret = 0;
562 if (level == RESUME_RESTORE_STATE)
563 ret = pcmcia_socket_dev_resume(dev);
564 return ret;
565}
566
567static struct device_driver m8xx_driver = { 549static struct device_driver m8xx_driver = {
568 .name = "m8xx-pcmcia", 550 .name = "m8xx-pcmcia",
569 .bus = &platform_bus_type, 551 .bus = &platform_bus_type,
570 .suspend = m8xx_drv_suspend, 552 .suspend = pcmcia_socket_dev_suspend,
571 .resume = m8xx_drv_resume, 553 .resume = pcmcia_socket_dev_resume,
572}; 554};
573 555
574static struct platform_device m8xx_device = { 556static struct platform_device m8xx_device = {
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index fe5ea36e7de3..56c58831e80e 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -22,16 +22,20 @@
22#include <asm/hardware.h> 22#include <asm/hardware.h>
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <asm/hardware/scoop.h> 24#include <asm/hardware/scoop.h>
25#ifdef CONFIG_SA1100_COLLIE
26#include <asm/arch-sa1100/collie.h>
27#else
28#include <asm/arch-pxa/pxa-regs.h>
29#endif
30 25
31#include "soc_common.h" 26#include "soc_common.h"
32 27
33#define NO_KEEP_VS 0x0001 28#define NO_KEEP_VS 0x0001
34 29
30/* PCMCIA to Scoop linkage
31
32 There is no easy way to link multiple scoop devices into one
33 single entity for the pxa2xx_pcmcia device so this structure
34 is used which is setup by the platform code
35*/
36struct scoop_pcmcia_config *platform_scoop_config;
37#define SCOOP_DEV platform_scoop_config->devs
38
35static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev) 39static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev)
36{ 40{
37 reset_scoop(scoopdev->dev); 41 reset_scoop(scoopdev->dev);
@@ -43,38 +47,16 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
43{ 47{
44 int ret; 48 int ret;
45 49
46#ifndef CONFIG_SA1100_COLLIE 50 if (platform_scoop_config->pcmcia_init)
47 /* 51 platform_scoop_config->pcmcia_init();
48 * Setup default state of GPIO outputs
49 * before we enable them as outputs.
50 */
51 GPSR(GPIO48_nPOE) =
52 GPIO_bit(GPIO48_nPOE) |
53 GPIO_bit(GPIO49_nPWE) |
54 GPIO_bit(GPIO50_nPIOR) |
55 GPIO_bit(GPIO51_nPIOW) |
56 GPIO_bit(GPIO52_nPCE_1) |
57 GPIO_bit(GPIO53_nPCE_2);
58
59 pxa_gpio_mode(GPIO48_nPOE_MD);
60 pxa_gpio_mode(GPIO49_nPWE_MD);
61 pxa_gpio_mode(GPIO50_nPIOR_MD);
62 pxa_gpio_mode(GPIO51_nPIOW_MD);
63 pxa_gpio_mode(GPIO52_nPCE_1_MD);
64 pxa_gpio_mode(GPIO53_nPCE_2_MD);
65 pxa_gpio_mode(GPIO54_pSKTSEL_MD);
66 pxa_gpio_mode(GPIO55_nPREG_MD);
67 pxa_gpio_mode(GPIO56_nPWAIT_MD);
68 pxa_gpio_mode(GPIO57_nIOIS16_MD);
69#endif
70 52
71 /* Register interrupts */ 53 /* Register interrupts */
72 if (scoop_devs[skt->nr].cd_irq >= 0) { 54 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
73 struct pcmcia_irqs cd_irq; 55 struct pcmcia_irqs cd_irq;
74 56
75 cd_irq.sock = skt->nr; 57 cd_irq.sock = skt->nr;
76 cd_irq.irq = scoop_devs[skt->nr].cd_irq; 58 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
77 cd_irq.str = scoop_devs[skt->nr].cd_irq_str; 59 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
78 ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1); 60 ret = soc_pcmcia_request_irqs(skt, &cd_irq, 1);
79 61
80 if (ret) { 62 if (ret) {
@@ -83,19 +65,19 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
83 } 65 }
84 } 66 }
85 67
86 skt->irq = scoop_devs[skt->nr].irq; 68 skt->irq = SCOOP_DEV[skt->nr].irq;
87 69
88 return 0; 70 return 0;
89} 71}
90 72
91static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 73static void sharpsl_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
92{ 74{
93 if (scoop_devs[skt->nr].cd_irq >= 0) { 75 if (SCOOP_DEV[skt->nr].cd_irq >= 0) {
94 struct pcmcia_irqs cd_irq; 76 struct pcmcia_irqs cd_irq;
95 77
96 cd_irq.sock = skt->nr; 78 cd_irq.sock = skt->nr;
97 cd_irq.irq = scoop_devs[skt->nr].cd_irq; 79 cd_irq.irq = SCOOP_DEV[skt->nr].cd_irq;
98 cd_irq.str = scoop_devs[skt->nr].cd_irq_str; 80 cd_irq.str = SCOOP_DEV[skt->nr].cd_irq_str;
99 soc_pcmcia_free_irqs(skt, &cd_irq, 1); 81 soc_pcmcia_free_irqs(skt, &cd_irq, 1);
100 } 82 }
101} 83}
@@ -105,9 +87,9 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
105 struct pcmcia_state *state) 87 struct pcmcia_state *state)
106{ 88{
107 unsigned short cpr, csr; 89 unsigned short cpr, csr;
108 struct device *scoop = scoop_devs[skt->nr].dev; 90 struct device *scoop = SCOOP_DEV[skt->nr].dev;
109 91
110 cpr = read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR); 92 cpr = read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR);
111 93
112 write_scoop_reg(scoop, SCOOP_IRM, 0x00FF); 94 write_scoop_reg(scoop, SCOOP_IRM, 0x00FF);
113 write_scoop_reg(scoop, SCOOP_ISR, 0x0000); 95 write_scoop_reg(scoop, SCOOP_ISR, 0x0000);
@@ -116,21 +98,25 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
116 if (csr & 0x0004) { 98 if (csr & 0x0004) {
117 /* card eject */ 99 /* card eject */
118 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 100 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
119 scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; 101 SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
120 } 102 }
121 else if (!(scoop_devs[skt->nr].keep_vs & NO_KEEP_VS)) { 103 else if (!(SCOOP_DEV[skt->nr].keep_vs & NO_KEEP_VS)) {
122 /* keep vs1,vs2 */ 104 /* keep vs1,vs2 */
123 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 105 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
124 csr |= scoop_devs[skt->nr].keep_vs; 106 csr |= SCOOP_DEV[skt->nr].keep_vs;
125 } 107 }
126 else if (cpr & 0x0003) { 108 else if (cpr & 0x0003) {
127 /* power on */ 109 /* power on */
128 write_scoop_reg(scoop, SCOOP_CDR, 0x0000); 110 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
129 scoop_devs[skt->nr].keep_vs = (csr & 0x00C0); 111 SCOOP_DEV[skt->nr].keep_vs = (csr & 0x00C0);
130 } 112 }
131 else { 113 else {
132 /* card detect */ 114 /* card detect */
133 write_scoop_reg(scoop, SCOOP_CDR, 0x0002); 115 if ((machine_is_spitz() || machine_is_borzoi()) && skt->nr == 1) {
116 write_scoop_reg(scoop, SCOOP_CDR, 0x0000);
117 } else {
118 write_scoop_reg(scoop, SCOOP_CDR, 0x0002);
119 }
134 } 120 }
135 121
136 state->detect = (csr & 0x0004) ? 0 : 1; 122 state->detect = (csr & 0x0004) ? 0 : 1;
@@ -144,7 +130,6 @@ static void sharpsl_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
144 if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) { 130 if ((cpr & 0x0080) && ((cpr & 0x8040) != 0x8040)) {
145 printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr); 131 printk(KERN_ERR "sharpsl_pcmcia_socket_state(): CPR=%04X, Low voltage!\n", cpr);
146 } 132 }
147
148} 133}
149 134
150 135
@@ -152,7 +137,7 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
152 const socket_state_t *state) 137 const socket_state_t *state)
153{ 138{
154 unsigned long flags; 139 unsigned long flags;
155 struct device *scoop = scoop_devs[skt->nr].dev; 140 struct device *scoop = SCOOP_DEV[skt->nr].dev;
156 141
157 unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr; 142 unsigned short cpr, ncpr, ccr, nccr, mcr, nmcr, imr, nimr;
158 143
@@ -177,8 +162,13 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
177 nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080; 162 nccr = (ccr = read_scoop_reg(scoop, SCOOP_CCR)) & ~0x0080;
178 nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E; 163 nimr = (imr = read_scoop_reg(scoop, SCOOP_IMR)) & ~0x003E;
179 164
180 ncpr |= (state->Vcc == 33) ? 0x0001 : 165 if ((machine_is_spitz() || machine_is_borzoi() || machine_is_akita()) && skt->nr == 0) {
181 (state->Vcc == 50) ? 0x0002 : 0; 166 ncpr |= (state->Vcc == 33) ? 0x0002 :
167 (state->Vcc == 50) ? 0x0002 : 0;
168 } else {
169 ncpr |= (state->Vcc == 33) ? 0x0001 :
170 (state->Vcc == 50) ? 0x0002 : 0;
171 }
182 nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0; 172 nmcr |= (state->flags&SS_IOCARD) ? 0x0010 : 0;
183 ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0; 173 ncpr |= (state->flags&SS_OUTPUT_ENA) ? 0x0080 : 0;
184 nccr |= (state->flags&SS_RESET)? 0x0080: 0; 174 nccr |= (state->flags&SS_RESET)? 0x0080: 0;
@@ -190,18 +180,22 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
190 ((skt->status&SS_WRPROT) ? 0x0008 : 0); 180 ((skt->status&SS_WRPROT) ? 0x0008 : 0);
191 181
192 if (!(ncpr & 0x0003)) { 182 if (!(ncpr & 0x0003)) {
193 scoop_devs[skt->nr].keep_rd = 0; 183 SCOOP_DEV[skt->nr].keep_rd = 0;
194 } else if (!scoop_devs[skt->nr].keep_rd) { 184 } else if (!SCOOP_DEV[skt->nr].keep_rd) {
195 if (nccr & 0x0080) 185 if (nccr & 0x0080)
196 scoop_devs[skt->nr].keep_rd = 1; 186 SCOOP_DEV[skt->nr].keep_rd = 1;
197 else 187 else
198 nccr |= 0x0080; 188 nccr |= 0x0080;
199 } 189 }
200 190
201 if (mcr != nmcr) 191 if (mcr != nmcr)
202 write_scoop_reg(scoop, SCOOP_MCR, nmcr); 192 write_scoop_reg(scoop, SCOOP_MCR, nmcr);
203 if (cpr != ncpr) 193 if (cpr != ncpr) {
204 write_scoop_reg(scoop, SCOOP_CPR, ncpr); 194 if (platform_scoop_config->power_ctrl)
195 platform_scoop_config->power_ctrl(scoop, ncpr , skt->nr);
196 else
197 write_scoop_reg(scoop, SCOOP_CPR, ncpr);
198 }
205 if (ccr != nccr) 199 if (ccr != nccr)
206 write_scoop_reg(scoop, SCOOP_CCR, nccr); 200 write_scoop_reg(scoop, SCOOP_CCR, nccr);
207 if (imr != nimr) 201 if (imr != nimr)
@@ -214,43 +208,43 @@ static int sharpsl_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
214 208
215static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt) 209static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
216{ 210{
217 sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); 211 sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
218 212
219 /* Enable interrupt */ 213 /* Enable interrupt */
220 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0); 214 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0);
221 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101); 215 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101);
222 scoop_devs[skt->nr].keep_vs = NO_KEEP_VS; 216 SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
223 217
224 if (machine_is_collie()) 218 if (machine_is_collie())
225 /* We need to disable SS_OUTPUT_ENA here. */ 219 /* We need to disable SS_OUTPUT_ENA here. */
226 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); 220 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
227} 221}
228 222
229static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 223static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
230{ 224{
231 /* CF_BUS_OFF */ 225 /* CF_BUS_OFF */
232 sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]); 226 sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
233 227
234 if (machine_is_collie()) 228 if (machine_is_collie())
235 /* We need to disable SS_OUTPUT_ENA here. */ 229 /* We need to disable SS_OUTPUT_ENA here. */
236 write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080); 230 write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
237} 231}
238 232
239static struct pcmcia_low_level sharpsl_pcmcia_ops = { 233static struct pcmcia_low_level sharpsl_pcmcia_ops = {
240 .owner = THIS_MODULE, 234 .owner = THIS_MODULE,
241 .hw_init = sharpsl_pcmcia_hw_init, 235 .hw_init = sharpsl_pcmcia_hw_init,
242 .hw_shutdown = sharpsl_pcmcia_hw_shutdown, 236 .hw_shutdown = sharpsl_pcmcia_hw_shutdown,
243 .socket_state = sharpsl_pcmcia_socket_state, 237 .socket_state = sharpsl_pcmcia_socket_state,
244 .configure_socket = sharpsl_pcmcia_configure_socket, 238 .configure_socket = sharpsl_pcmcia_configure_socket,
245 .socket_init = sharpsl_pcmcia_socket_init, 239 .socket_init = sharpsl_pcmcia_socket_init,
246 .socket_suspend = sharpsl_pcmcia_socket_suspend, 240 .socket_suspend = sharpsl_pcmcia_socket_suspend,
247 .first = 0, 241 .first = 0,
248 .nr = 0, 242 .nr = 0,
249}; 243};
250 244
251static struct platform_device *sharpsl_pcmcia_device;
252
253#ifdef CONFIG_SA1100_COLLIE 245#ifdef CONFIG_SA1100_COLLIE
246#include "sa11xx_base.h"
247
254int __init pcmcia_collie_init(struct device *dev) 248int __init pcmcia_collie_init(struct device *dev)
255{ 249{
256 int ret = -ENODEV; 250 int ret = -ENODEV;
@@ -263,11 +257,13 @@ int __init pcmcia_collie_init(struct device *dev)
263 257
264#else 258#else
265 259
260static struct platform_device *sharpsl_pcmcia_device;
261
266static int __init sharpsl_pcmcia_init(void) 262static int __init sharpsl_pcmcia_init(void)
267{ 263{
268 int ret; 264 int ret;
269 265
270 sharpsl_pcmcia_ops.nr=scoop_num; 266 sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
271 sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); 267 sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
272 if (!sharpsl_pcmcia_device) 268 if (!sharpsl_pcmcia_device)
273 return -ENOMEM; 269 return -ENOMEM;
@@ -275,7 +271,7 @@ static int __init sharpsl_pcmcia_init(void)
275 memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device)); 271 memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
276 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia"; 272 sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
277 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; 273 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
278 sharpsl_pcmcia_device->dev.parent=scoop_devs[0].dev; 274 sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
279 275
280 ret = platform_device_register(sharpsl_pcmcia_device); 276 ret = platform_device_register(sharpsl_pcmcia_device);
281 if (ret) 277 if (ret)
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index e95ed67d4f05..bd7c966ea2d7 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -12,7 +12,7 @@
12#include "base.h" 12#include "base.h"
13 13
14LIST_HEAD(pnp_cards); 14LIST_HEAD(pnp_cards);
15LIST_HEAD(pnp_card_drivers); 15static LIST_HEAD(pnp_card_drivers);
16 16
17 17
18static const struct pnp_card_device_id * match_card(struct pnp_card_driver * drv, struct pnp_card * card) 18static const struct pnp_card_device_id * match_card(struct pnp_card_driver * drv, struct pnp_card * card)
@@ -374,11 +374,13 @@ void pnp_unregister_card_driver(struct pnp_card_driver * drv)
374 pnp_unregister_driver(&drv->link); 374 pnp_unregister_driver(&drv->link);
375} 375}
376 376
377#if 0
377EXPORT_SYMBOL(pnp_add_card); 378EXPORT_SYMBOL(pnp_add_card);
378EXPORT_SYMBOL(pnp_remove_card); 379EXPORT_SYMBOL(pnp_remove_card);
379EXPORT_SYMBOL(pnp_add_card_device); 380EXPORT_SYMBOL(pnp_add_card_device);
380EXPORT_SYMBOL(pnp_remove_card_device); 381EXPORT_SYMBOL(pnp_remove_card_device);
381EXPORT_SYMBOL(pnp_add_card_id); 382EXPORT_SYMBOL(pnp_add_card_id);
383#endif /* 0 */
382EXPORT_SYMBOL(pnp_request_card_device); 384EXPORT_SYMBOL(pnp_request_card_device);
383EXPORT_SYMBOL(pnp_release_card_device); 385EXPORT_SYMBOL(pnp_release_card_device);
384EXPORT_SYMBOL(pnp_register_card_driver); 386EXPORT_SYMBOL(pnp_register_card_driver);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index deed92459bc5..aec83ec5ea23 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -158,13 +158,14 @@ void __pnp_remove_device(struct pnp_dev *dev)
158 * 158 *
159 * this function will free all mem used by dev 159 * this function will free all mem used by dev
160 */ 160 */
161 161#if 0
162void pnp_remove_device(struct pnp_dev *dev) 162void pnp_remove_device(struct pnp_dev *dev)
163{ 163{
164 if (!dev || dev->card) 164 if (!dev || dev->card)
165 return; 165 return;
166 __pnp_remove_device(dev); 166 __pnp_remove_device(dev);
167} 167}
168#endif /* 0 */
168 169
169static int __init pnp_init(void) 170static int __init pnp_init(void)
170{ 171{
@@ -174,7 +175,9 @@ static int __init pnp_init(void)
174 175
175subsys_initcall(pnp_init); 176subsys_initcall(pnp_init);
176 177
178#if 0
177EXPORT_SYMBOL(pnp_register_protocol); 179EXPORT_SYMBOL(pnp_register_protocol);
178EXPORT_SYMBOL(pnp_unregister_protocol); 180EXPORT_SYMBOL(pnp_unregister_protocol);
179EXPORT_SYMBOL(pnp_add_device); 181EXPORT_SYMBOL(pnp_add_device);
180EXPORT_SYMBOL(pnp_remove_device); 182EXPORT_SYMBOL(pnp_remove_device);
183#endif /* 0 */
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index 33da25f3213f..d3ccce706ab4 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -214,6 +214,8 @@ int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev)
214 214
215EXPORT_SYMBOL(pnp_register_driver); 215EXPORT_SYMBOL(pnp_register_driver);
216EXPORT_SYMBOL(pnp_unregister_driver); 216EXPORT_SYMBOL(pnp_unregister_driver);
217#if 0
217EXPORT_SYMBOL(pnp_add_id); 218EXPORT_SYMBOL(pnp_add_id);
219#endif
218EXPORT_SYMBOL(pnp_device_attach); 220EXPORT_SYMBOL(pnp_device_attach);
219EXPORT_SYMBOL(pnp_device_detach); 221EXPORT_SYMBOL(pnp_device_detach);
diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c
index beedd86800f4..57fd60314d59 100644
--- a/drivers/pnp/isapnp/core.c
+++ b/drivers/pnp/isapnp/core.c
@@ -941,7 +941,9 @@ EXPORT_SYMBOL(isapnp_protocol);
941EXPORT_SYMBOL(isapnp_present); 941EXPORT_SYMBOL(isapnp_present);
942EXPORT_SYMBOL(isapnp_cfg_begin); 942EXPORT_SYMBOL(isapnp_cfg_begin);
943EXPORT_SYMBOL(isapnp_cfg_end); 943EXPORT_SYMBOL(isapnp_cfg_end);
944#if 0
944EXPORT_SYMBOL(isapnp_read_byte); 945EXPORT_SYMBOL(isapnp_read_byte);
946#endif
945EXPORT_SYMBOL(isapnp_write_byte); 947EXPORT_SYMBOL(isapnp_write_byte);
946 948
947static int isapnp_read_resources(struct pnp_dev *dev, struct pnp_resource_table *res) 949static int isapnp_read_resources(struct pnp_dev *dev, struct pnp_resource_table *res)
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index cbb2749db178..261668618b2d 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -555,7 +555,9 @@ void pnp_resource_change(struct resource *resource, unsigned long start, unsigne
555 555
556 556
557EXPORT_SYMBOL(pnp_manual_config_dev); 557EXPORT_SYMBOL(pnp_manual_config_dev);
558#if 0
558EXPORT_SYMBOL(pnp_auto_config_dev); 559EXPORT_SYMBOL(pnp_auto_config_dev);
560#endif
559EXPORT_SYMBOL(pnp_activate_dev); 561EXPORT_SYMBOL(pnp_activate_dev);
560EXPORT_SYMBOL(pnp_disable_dev); 562EXPORT_SYMBOL(pnp_disable_dev);
561EXPORT_SYMBOL(pnp_resource_change); 563EXPORT_SYMBOL(pnp_resource_change);
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 1a8915e74160..816479ad217b 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -117,7 +117,7 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
117 return ACPI_FAILURE(status) ? -ENODEV : 0; 117 return ACPI_FAILURE(status) ? -ENODEV : 0;
118} 118}
119 119
120struct pnp_protocol pnpacpi_protocol = { 120static struct pnp_protocol pnpacpi_protocol = {
121 .name = "Plug and Play ACPI", 121 .name = "Plug and Play ACPI",
122 .get = pnpacpi_get_resources, 122 .get = pnpacpi_get_resources,
123 .set = pnpacpi_set_resources, 123 .set = pnpacpi_set_resources,
@@ -234,7 +234,7 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
234} 234}
235 235
236int pnpacpi_disabled __initdata; 236int pnpacpi_disabled __initdata;
237int __init pnpacpi_init(void) 237static int __init pnpacpi_init(void)
238{ 238{
239 if (acpi_disabled || pnpacpi_disabled) { 239 if (acpi_disabled || pnpacpi_disabled) {
240 pnp_info("PnP ACPI: disabled"); 240 pnp_info("PnP ACPI: disabled");
@@ -258,4 +258,6 @@ static int __init pnpacpi_setup(char *str)
258} 258}
259__setup("pnpacpi=", pnpacpi_setup); 259__setup("pnpacpi=", pnpacpi_setup);
260 260
261#if 0
261EXPORT_SYMBOL(pnpacpi_protocol); 262EXPORT_SYMBOL(pnpacpi_protocol);
263#endif
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 887ad8939349..6ded527169f4 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -477,12 +477,14 @@ int pnp_check_dma(struct pnp_dev * dev, int idx)
477} 477}
478 478
479 479
480#if 0
480EXPORT_SYMBOL(pnp_register_dependent_option); 481EXPORT_SYMBOL(pnp_register_dependent_option);
481EXPORT_SYMBOL(pnp_register_independent_option); 482EXPORT_SYMBOL(pnp_register_independent_option);
482EXPORT_SYMBOL(pnp_register_irq_resource); 483EXPORT_SYMBOL(pnp_register_irq_resource);
483EXPORT_SYMBOL(pnp_register_dma_resource); 484EXPORT_SYMBOL(pnp_register_dma_resource);
484EXPORT_SYMBOL(pnp_register_port_resource); 485EXPORT_SYMBOL(pnp_register_port_resource);
485EXPORT_SYMBOL(pnp_register_mem_resource); 486EXPORT_SYMBOL(pnp_register_mem_resource);
487#endif /* 0 */
486 488
487 489
488/* format is: pnp_reserve_irq=irq1[,irq2] .... */ 490/* format is: pnp_reserve_irq=irq1[,irq2] .... */
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
new file mode 100644
index 000000000000..0b2d2c3579a7
--- /dev/null
+++ b/drivers/rapidio/Kconfig
@@ -0,0 +1,18 @@
1#
2# RapidIO configuration
3#
4config RAPIDIO_8_BIT_TRANSPORT
5 bool "8-bit transport addressing"
6 depends on RAPIDIO
7 ---help---
8 By default, the kernel assumes a 16-bit addressed RapidIO
9 network. By selecting this option, the kernel will support
10 an 8-bit addressed network.
11
12config RAPIDIO_DISC_TIMEOUT
13 int "Discovery timeout duration (seconds)"
14 depends on RAPIDIO
15 default "30"
16 ---help---
17 Amount of time a discovery node waits for a host to complete
18 enumeration beforing giving up.
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
new file mode 100644
index 000000000000..7c0e1818de51
--- /dev/null
+++ b/drivers/rapidio/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for RapidIO interconnect services
3#
4obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
5
6obj-$(CONFIG_RAPIDIO) += switches/
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c
new file mode 100644
index 000000000000..b9fab2ae3a36
--- /dev/null
+++ b/drivers/rapidio/rio-access.c
@@ -0,0 +1,175 @@
1/*
2 * RapidIO configuration space access support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/rio.h>
14#include <linux/module.h>
15
16/*
17 * These interrupt-safe spinlocks protect all accesses to RIO
18 * configuration space and doorbell access.
19 */
20static spinlock_t rio_config_lock = SPIN_LOCK_UNLOCKED;
21static spinlock_t rio_doorbell_lock = SPIN_LOCK_UNLOCKED;
22
23/*
24 * Wrappers for all RIO configuration access functions. They just check
25 * alignment, do locking and call the low-level functions pointed to
26 * by rio_mport->ops.
27 */
28
29#define RIO_8_BAD 0
30#define RIO_16_BAD (offset & 1)
31#define RIO_32_BAD (offset & 3)
32
33/**
34 * RIO_LOP_READ - Generate rio_local_read_config_* functions
35 * @size: Size of configuration space read (8, 16, 32 bits)
36 * @type: C type of value argument
37 * @len: Length of configuration space read (1, 2, 4 bytes)
38 *
39 * Generates rio_local_read_config_* functions used to access
40 * configuration space registers on the local device.
41 */
42#define RIO_LOP_READ(size,type,len) \
43int __rio_local_read_config_##size \
44 (struct rio_mport *mport, u32 offset, type *value) \
45{ \
46 int res; \
47 unsigned long flags; \
48 u32 data = 0; \
49 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
50 spin_lock_irqsave(&rio_config_lock, flags); \
51 res = mport->ops->lcread(mport->id, offset, len, &data); \
52 *value = (type)data; \
53 spin_unlock_irqrestore(&rio_config_lock, flags); \
54 return res; \
55}
56
57/**
58 * RIO_LOP_WRITE - Generate rio_local_write_config_* functions
59 * @size: Size of configuration space write (8, 16, 32 bits)
60 * @type: C type of value argument
61 * @len: Length of configuration space write (1, 2, 4 bytes)
62 *
63 * Generates rio_local_write_config_* functions used to access
64 * configuration space registers on the local device.
65 */
66#define RIO_LOP_WRITE(size,type,len) \
67int __rio_local_write_config_##size \
68 (struct rio_mport *mport, u32 offset, type value) \
69{ \
70 int res; \
71 unsigned long flags; \
72 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
73 spin_lock_irqsave(&rio_config_lock, flags); \
74 res = mport->ops->lcwrite(mport->id, offset, len, value); \
75 spin_unlock_irqrestore(&rio_config_lock, flags); \
76 return res; \
77}
78
79RIO_LOP_READ(8, u8, 1)
80RIO_LOP_READ(16, u16, 2)
81RIO_LOP_READ(32, u32, 4)
82RIO_LOP_WRITE(8, u8, 1)
83RIO_LOP_WRITE(16, u16, 2)
84RIO_LOP_WRITE(32, u32, 4)
85
86EXPORT_SYMBOL_GPL(__rio_local_read_config_8);
87EXPORT_SYMBOL_GPL(__rio_local_read_config_16);
88EXPORT_SYMBOL_GPL(__rio_local_read_config_32);
89EXPORT_SYMBOL_GPL(__rio_local_write_config_8);
90EXPORT_SYMBOL_GPL(__rio_local_write_config_16);
91EXPORT_SYMBOL_GPL(__rio_local_write_config_32);
92
93/**
94 * RIO_OP_READ - Generate rio_mport_read_config_* functions
95 * @size: Size of configuration space read (8, 16, 32 bits)
96 * @type: C type of value argument
97 * @len: Length of configuration space read (1, 2, 4 bytes)
98 *
99 * Generates rio_mport_read_config_* functions used to access
100 * configuration space registers on the local device.
101 */
102#define RIO_OP_READ(size,type,len) \
103int rio_mport_read_config_##size \
104 (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \
105{ \
106 int res; \
107 unsigned long flags; \
108 u32 data = 0; \
109 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
110 spin_lock_irqsave(&rio_config_lock, flags); \
111 res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \
112 *value = (type)data; \
113 spin_unlock_irqrestore(&rio_config_lock, flags); \
114 return res; \
115}
116
117/**
118 * RIO_OP_WRITE - Generate rio_mport_write_config_* functions
119 * @size: Size of configuration space write (8, 16, 32 bits)
120 * @type: C type of value argument
121 * @len: Length of configuration space write (1, 2, 4 bytes)
122 *
123 * Generates rio_mport_write_config_* functions used to access
124 * configuration space registers on the local device.
125 */
126#define RIO_OP_WRITE(size,type,len) \
127int rio_mport_write_config_##size \
128 (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \
129{ \
130 int res; \
131 unsigned long flags; \
132 if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
133 spin_lock_irqsave(&rio_config_lock, flags); \
134 res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \
135 spin_unlock_irqrestore(&rio_config_lock, flags); \
136 return res; \
137}
138
139RIO_OP_READ(8, u8, 1)
140RIO_OP_READ(16, u16, 2)
141RIO_OP_READ(32, u32, 4)
142RIO_OP_WRITE(8, u8, 1)
143RIO_OP_WRITE(16, u16, 2)
144RIO_OP_WRITE(32, u32, 4)
145
146EXPORT_SYMBOL_GPL(rio_mport_read_config_8);
147EXPORT_SYMBOL_GPL(rio_mport_read_config_16);
148EXPORT_SYMBOL_GPL(rio_mport_read_config_32);
149EXPORT_SYMBOL_GPL(rio_mport_write_config_8);
150EXPORT_SYMBOL_GPL(rio_mport_write_config_16);
151EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
152
153/**
154 * rio_mport_send_doorbell - Send a doorbell message
155 *
156 * @mport: RIO master port
157 * @destid: RIO device destination ID
158 * @data: Doorbell message data
159 *
160 * Send a doorbell message to a RIO device. The doorbell message
161 * has a 16-bit info field provided by the data argument.
162 */
163int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
164{
165 int res;
166 unsigned long flags;
167
168 spin_lock_irqsave(&rio_doorbell_lock, flags);
169 res = mport->ops->dsend(mport->id, destid, data);
170 spin_unlock_irqrestore(&rio_doorbell_lock, flags);
171
172 return res;
173}
174
175EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
new file mode 100644
index 000000000000..dc749609699a
--- /dev/null
+++ b/drivers/rapidio/rio-driver.c
@@ -0,0 +1,229 @@
1/*
2 * RapidIO driver support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/rio.h>
16#include <linux/rio_ids.h>
17
18#include "rio.h"
19
20/**
21 * rio_match_device - Tell if a RIO device has a matching RIO device id structure
22 * @id: the RIO device id structure to match against
23 * @rdev: the RIO device structure to match against
24 *
25 * Used from driver probe and bus matching to check whether a RIO device
26 * matches a device id structure provided by a RIO driver. Returns the
27 * matching &struct rio_device_id or %NULL if there is no match.
28 */
29static const struct rio_device_id *rio_match_device(const struct rio_device_id
30 *id,
31 const struct rio_dev *rdev)
32{
33 while (id->vid || id->asm_vid) {
34 if (((id->vid == RIO_ANY_ID) || (id->vid == rdev->vid)) &&
35 ((id->did == RIO_ANY_ID) || (id->did == rdev->did)) &&
36 ((id->asm_vid == RIO_ANY_ID)
37 || (id->asm_vid == rdev->asm_vid))
38 && ((id->asm_did == RIO_ANY_ID)
39 || (id->asm_did == rdev->asm_did)))
40 return id;
41 id++;
42 }
43 return NULL;
44}
45
46/**
47 * rio_dev_get - Increments the reference count of the RIO device structure
48 *
49 * @rdev: RIO device being referenced
50 *
51 * Each live reference to a device should be refcounted.
52 *
53 * Drivers for RIO devices should normally record such references in
54 * their probe() methods, when they bind to a device, and release
55 * them by calling rio_dev_put(), in their disconnect() methods.
56 */
57struct rio_dev *rio_dev_get(struct rio_dev *rdev)
58{
59 if (rdev)
60 get_device(&rdev->dev);
61
62 return rdev;
63}
64
65/**
66 * rio_dev_put - Release a use of the RIO device structure
67 *
68 * @rdev: RIO device being disconnected
69 *
70 * Must be called when a user of a device is finished with it.
71 * When the last user of the device calls this function, the
72 * memory of the device is freed.
73 */
74void rio_dev_put(struct rio_dev *rdev)
75{
76 if (rdev)
77 put_device(&rdev->dev);
78}
79
80/**
81 * rio_device_probe - Tell if a RIO device structure has a matching RIO
82 * device id structure
83 * @id: the RIO device id structure to match against
84 * @dev: the RIO device structure to match against
85 *
86 * return 0 and set rio_dev->driver when drv claims rio_dev, else error
87 */
88static int rio_device_probe(struct device *dev)
89{
90 struct rio_driver *rdrv = to_rio_driver(dev->driver);
91 struct rio_dev *rdev = to_rio_dev(dev);
92 int error = -ENODEV;
93 const struct rio_device_id *id;
94
95 if (!rdev->driver && rdrv->probe) {
96 if (!rdrv->id_table)
97 return error;
98 id = rio_match_device(rdrv->id_table, rdev);
99 rio_dev_get(rdev);
100 if (id)
101 error = rdrv->probe(rdev, id);
102 if (error >= 0) {
103 rdev->driver = rdrv;
104 error = 0;
105 rio_dev_put(rdev);
106 }
107 }
108 return error;
109}
110
111/**
112 * rio_device_remove - Remove a RIO device from the system
113 *
114 * @dev: the RIO device structure to match against
115 *
116 * Remove a RIO device from the system. If it has an associated
117 * driver, then run the driver remove() method. Then update
118 * the reference count.
119 */
120static int rio_device_remove(struct device *dev)
121{
122 struct rio_dev *rdev = to_rio_dev(dev);
123 struct rio_driver *rdrv = rdev->driver;
124
125 if (rdrv) {
126 if (rdrv->remove)
127 rdrv->remove(rdev);
128 rdev->driver = NULL;
129 }
130
131 rio_dev_put(rdev);
132
133 return 0;
134}
135
136/**
137 * rio_register_driver - register a new RIO driver
138 * @rdrv: the RIO driver structure to register
139 *
140 * Adds a &struct rio_driver to the list of registered drivers
141 * Returns a negative value on error, otherwise 0. If no error
142 * occurred, the driver remains registered even if no device
143 * was claimed during registration.
144 */
145int rio_register_driver(struct rio_driver *rdrv)
146{
147 /* initialize common driver fields */
148 rdrv->driver.name = rdrv->name;
149 rdrv->driver.bus = &rio_bus_type;
150 rdrv->driver.probe = rio_device_probe;
151 rdrv->driver.remove = rio_device_remove;
152
153 /* register with core */
154 return driver_register(&rdrv->driver);
155}
156
157/**
158 * rio_unregister_driver - unregister a RIO driver
159 * @rdrv: the RIO driver structure to unregister
160 *
161 * Deletes the &struct rio_driver from the list of registered RIO
162 * drivers, gives it a chance to clean up by calling its remove()
163 * function for each device it was responsible for, and marks those
164 * devices as driverless.
165 */
166void rio_unregister_driver(struct rio_driver *rdrv)
167{
168 driver_unregister(&rdrv->driver);
169}
170
171/**
172 * rio_match_bus - Tell if a RIO device structure has a matching RIO
173 * driver device id structure
174 * @dev: the standard device structure to match against
175 * @drv: the standard driver structure containing the ids to match against
176 *
177 * Used by a driver to check whether a RIO device present in the
178 * system is in its list of supported devices. Returns 1 if
179 * there is a matching &struct rio_device_id or 0 if there is
180 * no match.
181 */
182static int rio_match_bus(struct device *dev, struct device_driver *drv)
183{
184 struct rio_dev *rdev = to_rio_dev(dev);
185 struct rio_driver *rdrv = to_rio_driver(drv);
186 const struct rio_device_id *id = rdrv->id_table;
187 const struct rio_device_id *found_id;
188
189 if (!id)
190 goto out;
191
192 found_id = rio_match_device(id, rdev);
193
194 if (found_id)
195 return 1;
196
197 out:return 0;
198}
199
200static struct device rio_bus = {
201 .bus_id = "rapidio",
202};
203
204struct bus_type rio_bus_type = {
205 .name = "rapidio",
206 .match = rio_match_bus,
207 .dev_attrs = rio_dev_attrs
208};
209
210/**
211 * rio_bus_init - Register the RapidIO bus with the device model
212 *
213 * Registers the RIO bus device and RIO bus type with the Linux
214 * device model.
215 */
216static int __init rio_bus_init(void)
217{
218 if (device_register(&rio_bus) < 0)
219 printk("RIO: failed to register RIO bus device\n");
220 return bus_register(&rio_bus_type);
221}
222
223postcore_initcall(rio_bus_init);
224
225EXPORT_SYMBOL_GPL(rio_register_driver);
226EXPORT_SYMBOL_GPL(rio_unregister_driver);
227EXPORT_SYMBOL_GPL(rio_bus_type);
228EXPORT_SYMBOL_GPL(rio_dev_get);
229EXPORT_SYMBOL_GPL(rio_dev_put);
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
new file mode 100644
index 000000000000..4f7ed4bd3be9
--- /dev/null
+++ b/drivers/rapidio/rio-scan.c
@@ -0,0 +1,945 @@
1/*
2 * RapidIO enumeration and discovery support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/config.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16
17#include <linux/delay.h>
18#include <linux/dma-mapping.h>
19#include <linux/init.h>
20#include <linux/rio.h>
21#include <linux/rio_drv.h>
22#include <linux/rio_ids.h>
23#include <linux/rio_regs.h>
24#include <linux/module.h>
25#include <linux/spinlock.h>
26#include <linux/timer.h>
27
28#include "rio.h"
29
30LIST_HEAD(rio_devices);
31static LIST_HEAD(rio_switches);
32
33#define RIO_ENUM_CMPL_MAGIC 0xdeadbeef
34
35static void rio_enum_timeout(unsigned long);
36
37DEFINE_SPINLOCK(rio_global_list_lock);
38
39static int next_destid = 0;
40static int next_switchid = 0;
41static int next_net = 0;
42
43static struct timer_list rio_enum_timer =
44TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
45
46static int rio_mport_phys_table[] = {
47 RIO_EFB_PAR_EP_ID,
48 RIO_EFB_PAR_EP_REC_ID,
49 RIO_EFB_SER_EP_ID,
50 RIO_EFB_SER_EP_REC_ID,
51 -1,
52};
53
54static int rio_sport_phys_table[] = {
55 RIO_EFB_PAR_EP_FREE_ID,
56 RIO_EFB_SER_EP_FREE_ID,
57 -1,
58};
59
60/**
61 * rio_get_device_id - Get the base/extended device id for a device
62 * @port: RIO master port
63 * @destid: Destination ID of device
64 * @hopcount: Hopcount to device
65 *
66 * Reads the base/extended device id from a device. Returns the
67 * 8/16-bit device ID.
68 */
69static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
70{
71 u32 result;
72
73 rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
74
75 return RIO_GET_DID(result);
76}
77
78/**
79 * rio_set_device_id - Set the base/extended device id for a device
80 * @port: RIO master port
81 * @destid: Destination ID of device
82 * @hopcount: Hopcount to device
83 * @did: Device ID value to be written
84 *
85 * Writes the base/extended device id from a device.
86 */
87static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
88{
89 rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
90 RIO_SET_DID(did));
91}
92
93/**
94 * rio_local_set_device_id - Set the base/extended device id for a port
95 * @port: RIO master port
96 * @did: Device ID value to be written
97 *
98 * Writes the base/extended device id from a device.
99 */
100static void rio_local_set_device_id(struct rio_mport *port, u16 did)
101{
102 rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did));
103}
104
105/**
106 * rio_clear_locks- Release all host locks and signal enumeration complete
107 * @port: Master port to issue transaction
108 *
109 * Marks the component tag CSR on each device with the enumeration
110 * complete flag. When complete, it then release the host locks on
111 * each device. Returns 0 on success or %-EINVAL on failure.
112 */
113static int rio_clear_locks(struct rio_mport *port)
114{
115 struct rio_dev *rdev;
116 u32 result;
117 int ret = 0;
118
119 /* Write component tag CSR magic complete value */
120 rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR,
121 RIO_ENUM_CMPL_MAGIC);
122 list_for_each_entry(rdev, &rio_devices, global_list)
123 rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR,
124 RIO_ENUM_CMPL_MAGIC);
125
126 /* Release host device id locks */
127 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
128 port->host_deviceid);
129 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
130 if ((result & 0xffff) != 0xffff) {
131 printk(KERN_INFO
132 "RIO: badness when releasing host lock on master port, result %8.8x\n",
133 result);
134 ret = -EINVAL;
135 }
136 list_for_each_entry(rdev, &rio_devices, global_list) {
137 rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
138 port->host_deviceid);
139 rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result);
140 if ((result & 0xffff) != 0xffff) {
141 printk(KERN_INFO
142 "RIO: badness when releasing host lock on vid %4.4x did %4.4x\n",
143 rdev->vid, rdev->did);
144 ret = -EINVAL;
145 }
146 }
147
148 return ret;
149}
150
151/**
152 * rio_enum_host- Set host lock and initialize host destination ID
153 * @port: Master port to issue transaction
154 *
155 * Sets the local host master port lock and destination ID register
156 * with the host device ID value. The host device ID value is provided
157 * by the platform. Returns %0 on success or %-1 on failure.
158 */
159static int rio_enum_host(struct rio_mport *port)
160{
161 u32 result;
162
163 /* Set master port host device id lock */
164 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
165 port->host_deviceid);
166
167 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
168 if ((result & 0xffff) != port->host_deviceid)
169 return -1;
170
171 /* Set master port destid and init destid ctr */
172 rio_local_set_device_id(port, port->host_deviceid);
173
174 if (next_destid == port->host_deviceid)
175 next_destid++;
176
177 return 0;
178}
179
180/**
181 * rio_device_has_destid- Test if a device contains a destination ID register
182 * @port: Master port to issue transaction
183 * @src_ops: RIO device source operations
184 * @dst_ops: RIO device destination operations
185 *
186 * Checks the provided @src_ops and @dst_ops for the necessary transaction
187 * capabilities that indicate whether or not a device will implement a
188 * destination ID register. Returns 1 if true or 0 if false.
189 */
190static int rio_device_has_destid(struct rio_mport *port, int src_ops,
191 int dst_ops)
192{
193 u32 mask = RIO_OPS_READ | RIO_OPS_WRITE | RIO_OPS_ATOMIC_TST_SWP | RIO_OPS_ATOMIC_INC | RIO_OPS_ATOMIC_DEC | RIO_OPS_ATOMIC_SET | RIO_OPS_ATOMIC_CLR;
194
195 return !!((src_ops | dst_ops) & mask);
196}
197
198/**
199 * rio_release_dev- Frees a RIO device struct
200 * @dev: LDM device associated with a RIO device struct
201 *
202 * Gets the RIO device struct associated a RIO device struct.
203 * The RIO device struct is freed.
204 */
205static void rio_release_dev(struct device *dev)
206{
207 struct rio_dev *rdev;
208
209 rdev = to_rio_dev(dev);
210 kfree(rdev);
211}
212
213/**
214 * rio_is_switch- Tests if a RIO device has switch capabilities
215 * @rdev: RIO device
216 *
217 * Gets the RIO device Processing Element Features register
218 * contents and tests for switch capabilities. Returns 1 if
219 * the device is a switch or 0 if it is not a switch.
220 * The RIO device struct is freed.
221 */
222static int rio_is_switch(struct rio_dev *rdev)
223{
224 if (rdev->pef & RIO_PEF_SWITCH)
225 return 1;
226 return 0;
227}
228
229/**
230 * rio_route_set_ops- Sets routing operations for a particular vendor switch
231 * @rdev: RIO device
232 *
233 * Searches the RIO route ops table for known switch types. If the vid
234 * and did match a switch table entry, then set the add_entry() and
235 * get_entry() ops to the table entry values.
236 */
237static void rio_route_set_ops(struct rio_dev *rdev)
238{
239 struct rio_route_ops *cur = __start_rio_route_ops;
240 struct rio_route_ops *end = __end_rio_route_ops;
241
242 while (cur < end) {
243 if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
244 pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev));
245 rdev->rswitch->add_entry = cur->add_hook;
246 rdev->rswitch->get_entry = cur->get_hook;
247 }
248 cur++;
249 }
250
251 if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
252 printk(KERN_ERR "RIO: missing routing ops for %s\n",
253 rio_name(rdev));
254}
255
256/**
257 * rio_add_device- Adds a RIO device to the device model
258 * @rdev: RIO device
259 *
260 * Adds the RIO device to the global device list and adds the RIO
261 * device to the RIO device list. Creates the generic sysfs nodes
262 * for an RIO device.
263 */
264static void __devinit rio_add_device(struct rio_dev *rdev)
265{
266 device_add(&rdev->dev);
267
268 spin_lock(&rio_global_list_lock);
269 list_add_tail(&rdev->global_list, &rio_devices);
270 spin_unlock(&rio_global_list_lock);
271
272 rio_create_sysfs_dev_files(rdev);
273}
274
275/**
276 * rio_setup_device- Allocates and sets up a RIO device
277 * @net: RIO network
278 * @port: Master port to send transactions
279 * @destid: Current destination ID
280 * @hopcount: Current hopcount
281 * @do_enum: Enumeration/Discovery mode flag
282 *
283 * Allocates a RIO device and configures fields based on configuration
284 * space contents. If device has a destination ID register, a destination
285 * ID is either assigned in enumeration mode or read from configuration
286 * space in discovery mode. If the device has switch capabilities, then
287 * a switch is allocated and configured appropriately. Returns a pointer
288 * to a RIO device on success or NULL on failure.
289 *
290 */
291static struct rio_dev *rio_setup_device(struct rio_net *net,
292 struct rio_mport *port, u16 destid,
293 u8 hopcount, int do_enum)
294{
295 struct rio_dev *rdev;
296 struct rio_switch *rswitch;
297 int result, rdid;
298
299 rdev = kmalloc(sizeof(struct rio_dev), GFP_KERNEL);
300 if (!rdev)
301 goto out;
302
303 memset(rdev, 0, sizeof(struct rio_dev));
304 rdev->net = net;
305 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
306 &result);
307 rdev->did = result >> 16;
308 rdev->vid = result & 0xffff;
309 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_INFO_CAR,
310 &rdev->device_rev);
311 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_ID_CAR,
312 &result);
313 rdev->asm_did = result >> 16;
314 rdev->asm_vid = result & 0xffff;
315 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
316 &result);
317 rdev->asm_rev = result >> 16;
318 rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
319 &rdev->pef);
320 if (rdev->pef & RIO_PEF_EXT_FEATURES)
321 rdev->efptr = result & 0xffff;
322
323 rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
324 &rdev->src_ops);
325 rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
326 &rdev->dst_ops);
327
328 if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)
329 && do_enum) {
330 rio_set_device_id(port, destid, hopcount, next_destid);
331 rdev->destid = next_destid++;
332 if (next_destid == port->host_deviceid)
333 next_destid++;
334 } else
335 rdev->destid = rio_get_device_id(port, destid, hopcount);
336
337 /* If a PE has both switch and other functions, show it as a switch */
338 if (rio_is_switch(rdev)) {
339 rio_mport_read_config_32(port, destid, hopcount,
340 RIO_SWP_INFO_CAR, &rdev->swpinfo);
341 rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL);
342 if (!rswitch) {
343 kfree(rdev);
344 rdev = NULL;
345 goto out;
346 }
347 rswitch->switchid = next_switchid;
348 rswitch->hopcount = hopcount;
349 rswitch->destid = 0xffff;
350 /* Initialize switch route table */
351 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
352 rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
353 rdev->rswitch = rswitch;
354 sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
355 rdev->rswitch->switchid);
356 rio_route_set_ops(rdev);
357
358 list_add_tail(&rswitch->node, &rio_switches);
359
360 } else
361 sprintf(rio_name(rdev), "%02x:e:%04x", rdev->net->id,
362 rdev->destid);
363
364 rdev->dev.bus = &rio_bus_type;
365
366 device_initialize(&rdev->dev);
367 rdev->dev.release = rio_release_dev;
368 rio_dev_get(rdev);
369
370 rdev->dma_mask = DMA_32BIT_MASK;
371 rdev->dev.dma_mask = &rdev->dma_mask;
372 rdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
373
374 if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
375 (rdev->dst_ops & RIO_DST_OPS_DOORBELL))
376 rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
377 0, 0xffff);
378
379 rio_add_device(rdev);
380
381 out:
382 return rdev;
383}
384
385/**
386 * rio_sport_is_active- Tests if a switch port has an active connection.
387 * @port: Master port to send transaction
388 * @destid: Associated destination ID for switch
389 * @hopcount: Hopcount to reach switch
390 * @sport: Switch port number
391 *
392 * Reads the port error status CSR for a particular switch port to
393 * determine if the port has an active link. Returns
394 * %PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is
395 * inactive.
396 */
397static int
398rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
399{
400 u32 result;
401 u32 ext_ftr_ptr;
402
403 int *entry = rio_sport_phys_table;
404
405 do {
406 if ((ext_ftr_ptr =
407 rio_mport_get_feature(port, 0, destid, hopcount, *entry)))
408
409 break;
410 } while (*++entry >= 0);
411
412 if (ext_ftr_ptr)
413 rio_mport_read_config_32(port, destid, hopcount,
414 ext_ftr_ptr +
415 RIO_PORT_N_ERR_STS_CSR(sport),
416 &result);
417
418 return (result & PORT_N_ERR_STS_PORT_OK);
419}
420
421/**
422 * rio_route_add_entry- Add a route entry to a switch routing table
423 * @mport: Master port to send transaction
424 * @rdev: Switch device
425 * @table: Routing table ID
426 * @route_destid: Destination ID to be routed
427 * @route_port: Port number to be routed
428 *
429 * Calls the switch specific add_entry() method to add a route entry
430 * on a switch. The route table can be specified using the @table
431 * argument if a switch has per port routing tables or the normal
432 * use is to specific all tables (or the global table) by passing
433 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
434 * on failure.
435 */
436static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
437 u16 table, u16 route_destid, u8 route_port)
438{
439 return rdev->rswitch->add_entry(mport, rdev->rswitch->destid,
440 rdev->rswitch->hopcount, table,
441 route_destid, route_port);
442}
443
444/**
445 * rio_route_get_entry- Read a route entry in a switch routing table
446 * @mport: Master port to send transaction
447 * @rdev: Switch device
448 * @table: Routing table ID
449 * @route_destid: Destination ID to be routed
450 * @route_port: Pointer to read port number into
451 *
452 * Calls the switch specific get_entry() method to read a route entry
453 * in a switch. The route table can be specified using the @table
454 * argument if a switch has per port routing tables or the normal
455 * use is to specific all tables (or the global table) by passing
456 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
457 * on failure.
458 */
459static int
460rio_route_get_entry(struct rio_mport *mport, struct rio_dev *rdev, u16 table,
461 u16 route_destid, u8 * route_port)
462{
463 return rdev->rswitch->get_entry(mport, rdev->rswitch->destid,
464 rdev->rswitch->hopcount, table,
465 route_destid, route_port);
466}
467
468/**
469 * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device
470 * @port: Master port to send transaction
471 * @hopcount: Number of hops to the device
472 *
473 * Used during enumeration to read the Host Device ID Lock CSR on a
474 * RIO device. Returns the value of the lock register.
475 */
476static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
477{
478 u32 result;
479
480 rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount,
481 RIO_HOST_DID_LOCK_CSR, &result);
482
483 return (u16) (result & 0xffff);
484}
485
486/**
487 * rio_get_swpinfo_inport- Gets the ingress port number
488 * @mport: Master port to send transaction
489 * @destid: Destination ID associated with the switch
490 * @hopcount: Number of hops to the device
491 *
492 * Returns port number being used to access the switch device.
493 */
494static u8
495rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
496{
497 u32 result;
498
499 rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
500 &result);
501
502 return (u8) (result & 0xff);
503}
504
505/**
506 * rio_get_swpinfo_tports- Gets total number of ports on the switch
507 * @mport: Master port to send transaction
508 * @destid: Destination ID associated with the switch
509 * @hopcount: Number of hops to the device
510 *
511 * Returns total numbers of ports implemented by the switch device.
512 */
513static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
514 u8 hopcount)
515{
516 u32 result;
517
518 rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
519 &result);
520
521 return RIO_GET_TOTAL_PORTS(result);
522}
523
524/**
525 * rio_net_add_mport- Add a master port to a RIO network
526 * @net: RIO network
527 * @port: Master port to add
528 *
529 * Adds a master port to the network list of associated master
530 * ports..
531 */
532static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
533{
534 spin_lock(&rio_global_list_lock);
535 list_add_tail(&port->nnode, &net->mports);
536 spin_unlock(&rio_global_list_lock);
537}
538
539/**
540 * rio_enum_peer- Recursively enumerate a RIO network through a master port
541 * @net: RIO network being enumerated
542 * @port: Master port to send transactions
543 * @hopcount: Number of hops into the network
544 *
545 * Recursively enumerates a RIO network. Transactions are sent via the
546 * master port passed in @port.
547 */
548static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
549 u8 hopcount)
550{
551 int port_num;
552 int num_ports;
553 int cur_destid;
554 struct rio_dev *rdev;
555 u16 destid;
556 int tmp;
557
558 if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) {
559 pr_debug("RIO: PE already discovered by this host\n");
560 /*
561 * Already discovered by this host. Add it as another
562 * master port for the current network.
563 */
564 rio_net_add_mport(net, port);
565 return 0;
566 }
567
568 /* Attempt to acquire device lock */
569 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
570 RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
571 while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
572 < port->host_deviceid) {
573 /* Delay a bit */
574 mdelay(1);
575 /* Attempt to acquire device lock again */
576 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
577 RIO_HOST_DID_LOCK_CSR,
578 port->host_deviceid);
579 }
580
581 if (rio_get_host_deviceid_lock(port, hopcount) > port->host_deviceid) {
582 pr_debug(
583 "RIO: PE locked by a higher priority host...retreating\n");
584 return -1;
585 }
586
587 /* Setup new RIO device */
588 if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) {
589 /* Add device to the global and bus/net specific list. */
590 list_add_tail(&rdev->net_list, &net->devices);
591 } else
592 return -1;
593
594 if (rio_is_switch(rdev)) {
595 next_switchid++;
596
597 for (destid = 0; destid < next_destid; destid++) {
598 rio_route_add_entry(port, rdev, RIO_GLOBAL_TABLE,
599 destid, rio_get_swpinfo_inport(port,
600 RIO_ANY_DESTID,
601 hopcount));
602 rdev->rswitch->route_table[destid] =
603 rio_get_swpinfo_inport(port, RIO_ANY_DESTID,
604 hopcount);
605 }
606
607 num_ports =
608 rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount);
609 pr_debug(
610 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
611 rio_name(rdev), rdev->vid, rdev->did, num_ports);
612 for (port_num = 0; port_num < num_ports; port_num++) {
613 if (rio_get_swpinfo_inport
614 (port, RIO_ANY_DESTID, hopcount) == port_num)
615 continue;
616
617 cur_destid = next_destid;
618
619 if (rio_sport_is_active
620 (port, RIO_ANY_DESTID, hopcount, port_num)) {
621 pr_debug(
622 "RIO: scanning device on port %d\n",
623 port_num);
624 rio_route_add_entry(port, rdev,
625 RIO_GLOBAL_TABLE,
626 RIO_ANY_DESTID, port_num);
627
628 if (rio_enum_peer(net, port, hopcount + 1) < 0)
629 return -1;
630
631 /* Update routing tables */
632 if (next_destid > cur_destid) {
633 for (destid = cur_destid;
634 destid < next_destid; destid++) {
635 rio_route_add_entry(port, rdev,
636 RIO_GLOBAL_TABLE,
637 destid,
638 port_num);
639 rdev->rswitch->
640 route_table[destid] =
641 port_num;
642 }
643 rdev->rswitch->destid = cur_destid;
644 }
645 }
646 }
647 } else
648 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
649 rio_name(rdev), rdev->vid, rdev->did);
650
651 return 0;
652}
653
654/**
655 * rio_enum_complete- Tests if enumeration of a network is complete
656 * @port: Master port to send transaction
657 *
658 * Tests the Component Tag CSR for presence of the magic enumeration
659 * complete flag. Return %1 if enumeration is complete or %0 if
660 * enumeration is incomplete.
661 */
662static int rio_enum_complete(struct rio_mport *port)
663{
664 u32 tag_csr;
665 int ret = 0;
666
667 rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr);
668
669 if (tag_csr == RIO_ENUM_CMPL_MAGIC)
670 ret = 1;
671
672 return ret;
673}
674
675/**
676 * rio_disc_peer- Recursively discovers a RIO network through a master port
677 * @net: RIO network being discovered
678 * @port: Master port to send transactions
679 * @destid: Current destination ID in network
680 * @hopcount: Number of hops into the network
681 *
682 * Recursively discovers a RIO network. Transactions are sent via the
683 * master port passed in @port.
684 */
685static int
686rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
687 u8 hopcount)
688{
689 u8 port_num, route_port;
690 int num_ports;
691 struct rio_dev *rdev;
692 u16 ndestid;
693
694 /* Setup new RIO device */
695 if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
696 /* Add device to the global and bus/net specific list. */
697 list_add_tail(&rdev->net_list, &net->devices);
698 } else
699 return -1;
700
701 if (rio_is_switch(rdev)) {
702 next_switchid++;
703
704 /* Associated destid is how we accessed this switch */
705 rdev->rswitch->destid = destid;
706
707 num_ports = rio_get_swpinfo_tports(port, destid, hopcount);
708 pr_debug(
709 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
710 rio_name(rdev), rdev->vid, rdev->did, num_ports);
711 for (port_num = 0; port_num < num_ports; port_num++) {
712 if (rio_get_swpinfo_inport(port, destid, hopcount) ==
713 port_num)
714 continue;
715
716 if (rio_sport_is_active
717 (port, destid, hopcount, port_num)) {
718 pr_debug(
719 "RIO: scanning device on port %d\n",
720 port_num);
721 for (ndestid = 0; ndestid < RIO_ANY_DESTID;
722 ndestid++) {
723 rio_route_get_entry(port, rdev,
724 RIO_GLOBAL_TABLE,
725 ndestid,
726 &route_port);
727 if (route_port == port_num)
728 break;
729 }
730
731 if (rio_disc_peer
732 (net, port, ndestid, hopcount + 1) < 0)
733 return -1;
734 }
735 }
736 } else
737 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
738 rio_name(rdev), rdev->vid, rdev->did);
739
740 return 0;
741}
742
743/**
744 * rio_mport_is_active- Tests if master port link is active
745 * @port: Master port to test
746 *
747 * Reads the port error status CSR for the master port to
748 * determine if the port has an active link. Returns
749 * %PORT_N_ERR_STS_PORT_OK if the master port is active
750 * or %0 if it is inactive.
751 */
752static int rio_mport_is_active(struct rio_mport *port)
753{
754 u32 result = 0;
755 u32 ext_ftr_ptr;
756 int *entry = rio_mport_phys_table;
757
758 do {
759 if ((ext_ftr_ptr =
760 rio_mport_get_feature(port, 1, 0, 0, *entry)))
761 break;
762 } while (*++entry >= 0);
763
764 if (ext_ftr_ptr)
765 rio_local_read_config_32(port,
766 ext_ftr_ptr +
767 RIO_PORT_N_ERR_STS_CSR(port->index),
768 &result);
769
770 return (result & PORT_N_ERR_STS_PORT_OK);
771}
772
773/**
774 * rio_alloc_net- Allocate and configure a new RIO network
775 * @port: Master port associated with the RIO network
776 *
777 * Allocates a RIO network structure, initializes per-network
778 * list heads, and adds the associated master port to the
779 * network list of associated master ports. Returns a
780 * RIO network pointer on success or %NULL on failure.
781 */
782static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
783{
784 struct rio_net *net;
785
786 net = kmalloc(sizeof(struct rio_net), GFP_KERNEL);
787 if (net) {
788 memset(net, 0, sizeof(struct rio_net));
789 INIT_LIST_HEAD(&net->node);
790 INIT_LIST_HEAD(&net->devices);
791 INIT_LIST_HEAD(&net->mports);
792 list_add_tail(&port->nnode, &net->mports);
793 net->hport = port;
794 net->id = next_net++;
795 }
796 return net;
797}
798
799/**
800 * rio_enum_mport- Start enumeration through a master port
801 * @mport: Master port to send transactions
802 *
803 * Starts the enumeration process. If somebody has enumerated our
804 * master port device, then give up. If not and we have an active
805 * link, then start recursive peer enumeration. Returns %0 if
806 * enumeration succeeds or %-EBUSY if enumeration fails.
807 */
808int rio_enum_mport(struct rio_mport *mport)
809{
810 struct rio_net *net = NULL;
811 int rc = 0;
812
813 printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
814 mport->name);
815 /* If somebody else enumerated our master port device, bail. */
816 if (rio_enum_host(mport) < 0) {
817 printk(KERN_INFO
818 "RIO: master port %d device has been enumerated by a remote host\n",
819 mport->id);
820 rc = -EBUSY;
821 goto out;
822 }
823
824 /* If master port has an active link, allocate net and enum peers */
825 if (rio_mport_is_active(mport)) {
826 if (!(net = rio_alloc_net(mport))) {
827 printk(KERN_ERR "RIO: failed to allocate new net\n");
828 rc = -ENOMEM;
829 goto out;
830 }
831 if (rio_enum_peer(net, mport, 0) < 0) {
832 /* A higher priority host won enumeration, bail. */
833 printk(KERN_INFO
834 "RIO: master port %d device has lost enumeration to a remote host\n",
835 mport->id);
836 rio_clear_locks(mport);
837 rc = -EBUSY;
838 goto out;
839 }
840 rio_clear_locks(mport);
841 } else {
842 printk(KERN_INFO "RIO: master port %d link inactive\n",
843 mport->id);
844 rc = -EINVAL;
845 }
846
847 out:
848 return rc;
849}
850
851/**
852 * rio_build_route_tables- Generate route tables from switch route entries
853 *
854 * For each switch device, generate a route table by copying existing
855 * route entries from the switch.
856 */
857static void rio_build_route_tables(void)
858{
859 struct rio_dev *rdev;
860 int i;
861 u8 sport;
862
863 list_for_each_entry(rdev, &rio_devices, global_list)
864 if (rio_is_switch(rdev))
865 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
866 if (rio_route_get_entry
867 (rdev->net->hport, rdev, RIO_GLOBAL_TABLE, i,
868 &sport) < 0)
869 continue;
870 rdev->rswitch->route_table[i] = sport;
871 }
872}
873
874/**
875 * rio_enum_timeout- Signal that enumeration timed out
876 * @data: Address of timeout flag.
877 *
878 * When the enumeration complete timer expires, set a flag that
879 * signals to the discovery process that enumeration did not
880 * complete in a sane amount of time.
881 */
882static void rio_enum_timeout(unsigned long data)
883{
884 /* Enumeration timed out, set flag */
885 *(int *)data = 1;
886}
887
888/**
889 * rio_disc_mport- Start discovery through a master port
890 * @mport: Master port to send transactions
891 *
892 * Starts the discovery process. If we have an active link,
893 * then wait for the signal that enumeration is complete.
894 * When enumeration completion is signaled, start recursive
895 * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
896 * on failure.
897 */
898int rio_disc_mport(struct rio_mport *mport)
899{
900 struct rio_net *net = NULL;
901 int enum_timeout_flag = 0;
902
903 printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id,
904 mport->name);
905
906 /* If master port has an active link, allocate net and discover peers */
907 if (rio_mport_is_active(mport)) {
908 if (!(net = rio_alloc_net(mport))) {
909 printk(KERN_ERR "RIO: Failed to allocate new net\n");
910 goto bail;
911 }
912
913 pr_debug("RIO: wait for enumeration complete...");
914
915 rio_enum_timer.expires =
916 jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
917 rio_enum_timer.data = (unsigned long)&enum_timeout_flag;
918 add_timer(&rio_enum_timer);
919 while (!rio_enum_complete(mport)) {
920 mdelay(1);
921 if (enum_timeout_flag) {
922 del_timer_sync(&rio_enum_timer);
923 goto timeout;
924 }
925 }
926 del_timer_sync(&rio_enum_timer);
927
928 pr_debug("done\n");
929 if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) {
930 printk(KERN_INFO
931 "RIO: master port %d device has failed discovery\n",
932 mport->id);
933 goto bail;
934 }
935
936 rio_build_route_tables();
937 }
938
939 return 0;
940
941 timeout:
942 pr_debug("timeout\n");
943 bail:
944 return -EBUSY;
945}
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
new file mode 100644
index 000000000000..30a11436e241
--- /dev/null
+++ b/drivers/rapidio/rio-sysfs.c
@@ -0,0 +1,230 @@
1/*
2 * RapidIO sysfs attributes and support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/config.h>
14#include <linux/kernel.h>
15#include <linux/rio.h>
16#include <linux/rio_drv.h>
17#include <linux/stat.h>
18
19#include "rio.h"
20
21/* Sysfs support */
22#define rio_config_attr(field, format_string) \
23static ssize_t \
24field##_show(struct device *dev, struct device_attribute *attr, char *buf) \
25{ \
26 struct rio_dev *rdev = to_rio_dev(dev); \
27 \
28 return sprintf(buf, format_string, rdev->field); \
29} \
30
31rio_config_attr(did, "0x%04x\n");
32rio_config_attr(vid, "0x%04x\n");
33rio_config_attr(device_rev, "0x%08x\n");
34rio_config_attr(asm_did, "0x%04x\n");
35rio_config_attr(asm_vid, "0x%04x\n");
36rio_config_attr(asm_rev, "0x%04x\n");
37
38static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
39{
40 struct rio_dev *rdev = to_rio_dev(dev);
41 char *str = buf;
42 int i;
43
44 if (!rdev->rswitch)
45 goto out;
46
47 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
48 if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
49 continue;
50 str +=
51 sprintf(str, "%04x %02x\n", i,
52 rdev->rswitch->route_table[i]);
53 }
54
55 out:
56 return (str - buf);
57}
58
59struct device_attribute rio_dev_attrs[] = {
60 __ATTR_RO(did),
61 __ATTR_RO(vid),
62 __ATTR_RO(device_rev),
63 __ATTR_RO(asm_did),
64 __ATTR_RO(asm_vid),
65 __ATTR_RO(asm_rev),
66 __ATTR_RO(routes),
67 __ATTR_NULL,
68};
69
70static ssize_t
71rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
72{
73 struct rio_dev *dev =
74 to_rio_dev(container_of(kobj, struct device, kobj));
75 unsigned int size = 0x100;
76 loff_t init_off = off;
77 u8 *data = (u8 *) buf;
78
79 /* Several chips lock up trying to read undefined config space */
80 if (capable(CAP_SYS_ADMIN))
81 size = 0x200000;
82
83 if (off > size)
84 return 0;
85 if (off + count > size) {
86 size -= off;
87 count = size;
88 } else {
89 size = count;
90 }
91
92 if ((off & 1) && size) {
93 u8 val;
94 rio_read_config_8(dev, off, &val);
95 data[off - init_off] = val;
96 off++;
97 size--;
98 }
99
100 if ((off & 3) && size > 2) {
101 u16 val;
102 rio_read_config_16(dev, off, &val);
103 data[off - init_off] = (val >> 8) & 0xff;
104 data[off - init_off + 1] = val & 0xff;
105 off += 2;
106 size -= 2;
107 }
108
109 while (size > 3) {
110 u32 val;
111 rio_read_config_32(dev, off, &val);
112 data[off - init_off] = (val >> 24) & 0xff;
113 data[off - init_off + 1] = (val >> 16) & 0xff;
114 data[off - init_off + 2] = (val >> 8) & 0xff;
115 data[off - init_off + 3] = val & 0xff;
116 off += 4;
117 size -= 4;
118 }
119
120 if (size >= 2) {
121 u16 val;
122 rio_read_config_16(dev, off, &val);
123 data[off - init_off] = (val >> 8) & 0xff;
124 data[off - init_off + 1] = val & 0xff;
125 off += 2;
126 size -= 2;
127 }
128
129 if (size > 0) {
130 u8 val;
131 rio_read_config_8(dev, off, &val);
132 data[off - init_off] = val;
133 off++;
134 --size;
135 }
136
137 return count;
138}
139
140static ssize_t
141rio_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
142{
143 struct rio_dev *dev =
144 to_rio_dev(container_of(kobj, struct device, kobj));
145 unsigned int size = count;
146 loff_t init_off = off;
147 u8 *data = (u8 *) buf;
148
149 if (off > 0x200000)
150 return 0;
151 if (off + count > 0x200000) {
152 size = 0x200000 - off;
153 count = size;
154 }
155
156 if ((off & 1) && size) {
157 rio_write_config_8(dev, off, data[off - init_off]);
158 off++;
159 size--;
160 }
161
162 if ((off & 3) && (size > 2)) {
163 u16 val = data[off - init_off + 1];
164 val |= (u16) data[off - init_off] << 8;
165 rio_write_config_16(dev, off, val);
166 off += 2;
167 size -= 2;
168 }
169
170 while (size > 3) {
171 u32 val = data[off - init_off + 3];
172 val |= (u32) data[off - init_off + 2] << 8;
173 val |= (u32) data[off - init_off + 1] << 16;
174 val |= (u32) data[off - init_off] << 24;
175 rio_write_config_32(dev, off, val);
176 off += 4;
177 size -= 4;
178 }
179
180 if (size >= 2) {
181 u16 val = data[off - init_off + 1];
182 val |= (u16) data[off - init_off] << 8;
183 rio_write_config_16(dev, off, val);
184 off += 2;
185 size -= 2;
186 }
187
188 if (size) {
189 rio_write_config_8(dev, off, data[off - init_off]);
190 off++;
191 --size;
192 }
193
194 return count;
195}
196
197static struct bin_attribute rio_config_attr = {
198 .attr = {
199 .name = "config",
200 .mode = S_IRUGO | S_IWUSR,
201 .owner = THIS_MODULE,
202 },
203 .size = 0x200000,
204 .read = rio_read_config,
205 .write = rio_write_config,
206};
207
208/**
209 * rio_create_sysfs_dev_files - create RIO specific sysfs files
210 * @rdev: device whose entries should be created
211 *
212 * Create files when @rdev is added to sysfs.
213 */
214int rio_create_sysfs_dev_files(struct rio_dev *rdev)
215{
216 sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr);
217
218 return 0;
219}
220
221/**
222 * rio_remove_sysfs_dev_files - cleanup RIO specific sysfs files
223 * @rdev: device whose entries we should free
224 *
225 * Cleanup when @rdev is removed from sysfs.
226 */
227void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
228{
229 sysfs_remove_bin_file(&rdev->dev.kobj, &rio_config_attr);
230}
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
new file mode 100644
index 000000000000..3ca1011ceaac
--- /dev/null
+++ b/drivers/rapidio/rio.c
@@ -0,0 +1,510 @@
1/*
2 * RapidIO interconnect services
3 * (RapidIO Interconnect Specification, http://www.rapidio.org)
4 *
5 * Copyright 2005 MontaVista Software, Inc.
6 * Matt Porter <mporter@kernel.crashing.org>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/config.h>
15#include <linux/types.h>
16#include <linux/kernel.h>
17
18#include <linux/delay.h>
19#include <linux/init.h>
20#include <linux/rio.h>
21#include <linux/rio_drv.h>
22#include <linux/rio_ids.h>
23#include <linux/rio_regs.h>
24#include <linux/module.h>
25#include <linux/spinlock.h>
26
27#include "rio.h"
28
29static LIST_HEAD(rio_mports);
30
31/**
32 * rio_local_get_device_id - Get the base/extended device id for a port
33 * @port: RIO master port from which to get the deviceid
34 *
35 * Reads the base/extended device id from the local device
36 * implementing the master port. Returns the 8/16-bit device
37 * id.
38 */
39u16 rio_local_get_device_id(struct rio_mport *port)
40{
41 u32 result;
42
43 rio_local_read_config_32(port, RIO_DID_CSR, &result);
44
45 return (RIO_GET_DID(result));
46}
47
48/**
49 * rio_request_inb_mbox - request inbound mailbox service
50 * @mport: RIO master port from which to allocate the mailbox resource
51 * @dev_id: Device specific pointer to pass on event
52 * @mbox: Mailbox number to claim
53 * @entries: Number of entries in inbound mailbox queue
54 * @minb: Callback to execute when inbound message is received
55 *
56 * Requests ownership of an inbound mailbox resource and binds
57 * a callback function to the resource. Returns %0 on success.
58 */
59int rio_request_inb_mbox(struct rio_mport *mport,
60 void *dev_id,
61 int mbox,
62 int entries,
63 void (*minb) (struct rio_mport * mport, void *dev_id, int mbox,
64 int slot))
65{
66 int rc = 0;
67
68 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
69
70 if (res) {
71 rio_init_mbox_res(res, mbox, mbox);
72
73 /* Make sure this mailbox isn't in use */
74 if ((rc =
75 request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
76 res)) < 0) {
77 kfree(res);
78 goto out;
79 }
80
81 mport->inb_msg[mbox].res = res;
82
83 /* Hook the inbound message callback */
84 mport->inb_msg[mbox].mcback = minb;
85
86 rc = rio_open_inb_mbox(mport, dev_id, mbox, entries);
87 } else
88 rc = -ENOMEM;
89
90 out:
91 return rc;
92}
93
94/**
95 * rio_release_inb_mbox - release inbound mailbox message service
96 * @mport: RIO master port from which to release the mailbox resource
97 * @mbox: Mailbox number to release
98 *
99 * Releases ownership of an inbound mailbox resource. Returns 0
100 * if the request has been satisfied.
101 */
102int rio_release_inb_mbox(struct rio_mport *mport, int mbox)
103{
104 rio_close_inb_mbox(mport, mbox);
105
106 /* Release the mailbox resource */
107 return release_resource(mport->inb_msg[mbox].res);
108}
109
110/**
111 * rio_request_outb_mbox - request outbound mailbox service
112 * @mport: RIO master port from which to allocate the mailbox resource
113 * @dev_id: Device specific pointer to pass on event
114 * @mbox: Mailbox number to claim
115 * @entries: Number of entries in outbound mailbox queue
116 * @moutb: Callback to execute when outbound message is sent
117 *
118 * Requests ownership of an outbound mailbox resource and binds
119 * a callback function to the resource. Returns 0 on success.
120 */
121int rio_request_outb_mbox(struct rio_mport *mport,
122 void *dev_id,
123 int mbox,
124 int entries,
125 void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot))
126{
127 int rc = 0;
128
129 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
130
131 if (res) {
132 rio_init_mbox_res(res, mbox, mbox);
133
134 /* Make sure this outbound mailbox isn't in use */
135 if ((rc =
136 request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
137 res)) < 0) {
138 kfree(res);
139 goto out;
140 }
141
142 mport->outb_msg[mbox].res = res;
143
144 /* Hook the inbound message callback */
145 mport->outb_msg[mbox].mcback = moutb;
146
147 rc = rio_open_outb_mbox(mport, dev_id, mbox, entries);
148 } else
149 rc = -ENOMEM;
150
151 out:
152 return rc;
153}
154
155/**
156 * rio_release_outb_mbox - release outbound mailbox message service
157 * @mport: RIO master port from which to release the mailbox resource
158 * @mbox: Mailbox number to release
159 *
160 * Releases ownership of an inbound mailbox resource. Returns 0
161 * if the request has been satisfied.
162 */
163int rio_release_outb_mbox(struct rio_mport *mport, int mbox)
164{
165 rio_close_outb_mbox(mport, mbox);
166
167 /* Release the mailbox resource */
168 return release_resource(mport->outb_msg[mbox].res);
169}
170
171/**
172 * rio_setup_inb_dbell - bind inbound doorbell callback
173 * @mport: RIO master port to bind the doorbell callback
174 * @dev_id: Device specific pointer to pass on event
175 * @res: Doorbell message resource
176 * @dinb: Callback to execute when doorbell is received
177 *
178 * Adds a doorbell resource/callback pair into a port's
179 * doorbell event list. Returns 0 if the request has been
180 * satisfied.
181 */
182static int
183rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
184 void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst,
185 u16 info))
186{
187 int rc = 0;
188 struct rio_dbell *dbell;
189
190 if (!(dbell = kmalloc(sizeof(struct rio_dbell), GFP_KERNEL))) {
191 rc = -ENOMEM;
192 goto out;
193 }
194
195 dbell->res = res;
196 dbell->dinb = dinb;
197 dbell->dev_id = dev_id;
198
199 list_add_tail(&dbell->node, &mport->dbells);
200
201 out:
202 return rc;
203}
204
205/**
206 * rio_request_inb_dbell - request inbound doorbell message service
207 * @mport: RIO master port from which to allocate the doorbell resource
208 * @dev_id: Device specific pointer to pass on event
209 * @start: Doorbell info range start
210 * @end: Doorbell info range end
211 * @dinb: Callback to execute when doorbell is received
212 *
213 * Requests ownership of an inbound doorbell resource and binds
214 * a callback function to the resource. Returns 0 if the request
215 * has been satisfied.
216 */
217int rio_request_inb_dbell(struct rio_mport *mport,
218 void *dev_id,
219 u16 start,
220 u16 end,
221 void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src,
222 u16 dst, u16 info))
223{
224 int rc = 0;
225
226 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
227
228 if (res) {
229 rio_init_dbell_res(res, start, end);
230
231 /* Make sure these doorbells aren't in use */
232 if ((rc =
233 request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
234 res)) < 0) {
235 kfree(res);
236 goto out;
237 }
238
239 /* Hook the doorbell callback */
240 rc = rio_setup_inb_dbell(mport, dev_id, res, dinb);
241 } else
242 rc = -ENOMEM;
243
244 out:
245 return rc;
246}
247
248/**
249 * rio_release_inb_dbell - release inbound doorbell message service
250 * @mport: RIO master port from which to release the doorbell resource
251 * @start: Doorbell info range start
252 * @end: Doorbell info range end
253 *
254 * Releases ownership of an inbound doorbell resource and removes
255 * callback from the doorbell event list. Returns 0 if the request
256 * has been satisfied.
257 */
258int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end)
259{
260 int rc = 0, found = 0;
261 struct rio_dbell *dbell;
262
263 list_for_each_entry(dbell, &mport->dbells, node) {
264 if ((dbell->res->start == start) && (dbell->res->end == end)) {
265 found = 1;
266 break;
267 }
268 }
269
270 /* If we can't find an exact match, fail */
271 if (!found) {
272 rc = -EINVAL;
273 goto out;
274 }
275
276 /* Delete from list */
277 list_del(&dbell->node);
278
279 /* Release the doorbell resource */
280 rc = release_resource(dbell->res);
281
282 /* Free the doorbell event */
283 kfree(dbell);
284
285 out:
286 return rc;
287}
288
289/**
290 * rio_request_outb_dbell - request outbound doorbell message range
291 * @rdev: RIO device from which to allocate the doorbell resource
292 * @start: Doorbell message range start
293 * @end: Doorbell message range end
294 *
295 * Requests ownership of a doorbell message range. Returns a resource
296 * if the request has been satisfied or %NULL on failure.
297 */
298struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start,
299 u16 end)
300{
301 struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
302
303 if (res) {
304 rio_init_dbell_res(res, start, end);
305
306 /* Make sure these doorbells aren't in use */
307 if (request_resource(&rdev->riores[RIO_DOORBELL_RESOURCE], res)
308 < 0) {
309 kfree(res);
310 res = NULL;
311 }
312 }
313
314 return res;
315}
316
317/**
318 * rio_release_outb_dbell - release outbound doorbell message range
319 * @rdev: RIO device from which to release the doorbell resource
320 * @res: Doorbell resource to be freed
321 *
322 * Releases ownership of a doorbell message range. Returns 0 if the
323 * request has been satisfied.
324 */
325int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res)
326{
327 int rc = release_resource(res);
328
329 kfree(res);
330
331 return rc;
332}
333
334/**
335 * rio_mport_get_feature - query for devices' extended features
336 * @port: Master port to issue transaction
337 * @local: Indicate a local master port or remote device access
338 * @destid: Destination ID of the device
339 * @hopcount: Number of switch hops to the device
340 * @ftr: Extended feature code
341 *
342 * Tell if a device supports a given RapidIO capability.
343 * Returns the offset of the requested extended feature
344 * block within the device's RIO configuration space or
345 * 0 in case the device does not support it. Possible
346 * values for @ftr:
347 *
348 * %RIO_EFB_PAR_EP_ID LP/LVDS EP Devices
349 *
350 * %RIO_EFB_PAR_EP_REC_ID LP/LVDS EP Recovery Devices
351 *
352 * %RIO_EFB_PAR_EP_FREE_ID LP/LVDS EP Free Devices
353 *
354 * %RIO_EFB_SER_EP_ID LP/Serial EP Devices
355 *
356 * %RIO_EFB_SER_EP_REC_ID LP/Serial EP Recovery Devices
357 *
358 * %RIO_EFB_SER_EP_FREE_ID LP/Serial EP Free Devices
359 */
360u32
361rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
362 u8 hopcount, int ftr)
363{
364 u32 asm_info, ext_ftr_ptr, ftr_header;
365
366 if (local)
367 rio_local_read_config_32(port, RIO_ASM_INFO_CAR, &asm_info);
368 else
369 rio_mport_read_config_32(port, destid, hopcount,
370 RIO_ASM_INFO_CAR, &asm_info);
371
372 ext_ftr_ptr = asm_info & RIO_EXT_FTR_PTR_MASK;
373
374 while (ext_ftr_ptr) {
375 if (local)
376 rio_local_read_config_32(port, ext_ftr_ptr,
377 &ftr_header);
378 else
379 rio_mport_read_config_32(port, destid, hopcount,
380 ext_ftr_ptr, &ftr_header);
381 if (RIO_GET_BLOCK_ID(ftr_header) == ftr)
382 return ext_ftr_ptr;
383 if (!(ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header)))
384 break;
385 }
386
387 return 0;
388}
389
390/**
391 * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
392 * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
393 * @did: RIO did to match or %RIO_ANY_ID to match all dids
394 * @asm_vid: RIO asm_vid to match or %RIO_ANY_ID to match all asm_vids
395 * @asm_did: RIO asm_did to match or %RIO_ANY_ID to match all asm_dids
396 * @from: Previous RIO device found in search, or %NULL for new search
397 *
398 * Iterates through the list of known RIO devices. If a RIO device is
399 * found with a matching @vid, @did, @asm_vid, @asm_did, the reference
400 * count to the device is incrememted and a pointer to its device
401 * structure is returned. Otherwise, %NULL is returned. A new search
402 * is initiated by passing %NULL to the @from argument. Otherwise, if
403 * @from is not %NULL, searches continue from next device on the global
404 * list. The reference count for @from is always decremented if it is
405 * not %NULL.
406 */
407struct rio_dev *rio_get_asm(u16 vid, u16 did,
408 u16 asm_vid, u16 asm_did, struct rio_dev *from)
409{
410 struct list_head *n;
411 struct rio_dev *rdev;
412
413 WARN_ON(in_interrupt());
414 spin_lock(&rio_global_list_lock);
415 n = from ? from->global_list.next : rio_devices.next;
416
417 while (n && (n != &rio_devices)) {
418 rdev = rio_dev_g(n);
419 if ((vid == RIO_ANY_ID || rdev->vid == vid) &&
420 (did == RIO_ANY_ID || rdev->did == did) &&
421 (asm_vid == RIO_ANY_ID || rdev->asm_vid == asm_vid) &&
422 (asm_did == RIO_ANY_ID || rdev->asm_did == asm_did))
423 goto exit;
424 n = n->next;
425 }
426 rdev = NULL;
427 exit:
428 rio_dev_put(from);
429 rdev = rio_dev_get(rdev);
430 spin_unlock(&rio_global_list_lock);
431 return rdev;
432}
433
434/**
435 * rio_get_device - Begin or continue searching for a RIO device by vid/did
436 * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
437 * @did: RIO did to match or %RIO_ANY_ID to match all dids
438 * @from: Previous RIO device found in search, or %NULL for new search
439 *
440 * Iterates through the list of known RIO devices. If a RIO device is
441 * found with a matching @vid and @did, the reference count to the
442 * device is incrememted and a pointer to its device structure is returned.
443 * Otherwise, %NULL is returned. A new search is initiated by passing %NULL
444 * to the @from argument. Otherwise, if @from is not %NULL, searches
445 * continue from next device on the global list. The reference count for
446 * @from is always decremented if it is not %NULL.
447 */
448struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
449{
450 return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
451}
452
453static void rio_fixup_device(struct rio_dev *dev)
454{
455}
456
457static int __devinit rio_init(void)
458{
459 struct rio_dev *dev = NULL;
460
461 while ((dev = rio_get_device(RIO_ANY_ID, RIO_ANY_ID, dev)) != NULL) {
462 rio_fixup_device(dev);
463 }
464 return 0;
465}
466
467device_initcall(rio_init);
468
469int rio_init_mports(void)
470{
471 int rc = 0;
472 struct rio_mport *port;
473
474 list_for_each_entry(port, &rio_mports, node) {
475 if (!request_mem_region(port->iores.start,
476 port->iores.end - port->iores.start,
477 port->name)) {
478 printk(KERN_ERR
479 "RIO: Error requesting master port region %8.8lx-%8.8lx\n",
480 port->iores.start, port->iores.end - 1);
481 rc = -ENOMEM;
482 goto out;
483 }
484
485 if (port->host_deviceid >= 0)
486 rio_enum_mport(port);
487 else
488 rio_disc_mport(port);
489 }
490
491 out:
492 return rc;
493}
494
495void rio_register_mport(struct rio_mport *port)
496{
497 list_add_tail(&port->node, &rio_mports);
498}
499
500EXPORT_SYMBOL_GPL(rio_local_get_device_id);
501EXPORT_SYMBOL_GPL(rio_get_device);
502EXPORT_SYMBOL_GPL(rio_get_asm);
503EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
504EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
505EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
506EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
507EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
508EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
509EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
510EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
new file mode 100644
index 000000000000..b242cee656e7
--- /dev/null
+++ b/drivers/rapidio/rio.h
@@ -0,0 +1,60 @@
1/*
2 * RapidIO interconnect services
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/device.h>
14#include <linux/list.h>
15#include <linux/rio.h>
16
17/* Functions internal to the RIO core code */
18
19extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid,
20 u8 hopcount, int ftr);
21extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
22extern int rio_enum_mport(struct rio_mport *mport);
23extern int rio_disc_mport(struct rio_mport *mport);
24
25/* Structures internal to the RIO core code */
26extern struct device_attribute rio_dev_attrs[];
27extern spinlock_t rio_global_list_lock;
28
29extern struct rio_route_ops __start_rio_route_ops[];
30extern struct rio_route_ops __end_rio_route_ops[];
31
32/* Helpers internal to the RIO core code */
33#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook) \
34 static struct rio_route_ops __rio_route_ops __attribute_used__ \
35 __attribute__((__section__(#section))) = { vid, did, add_hook, get_hook };
36
37/**
38 * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations
39 * @vid: RIO vendor ID
40 * @did: RIO device ID
41 * @add_hook: Callback that adds a route entry
42 * @get_hook: Callback that gets a route entry
43 *
44 * Manipulating switch route tables in RIO is switch specific. This
45 * registers a switch by vendor and device ID with two callbacks for
46 * modifying and retrieving route entries in a switch. A &struct
47 * rio_route_ops is initialized with the ops and placed into a
48 * RIO-specific kernel section.
49 */
50#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook) \
51 DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \
52 vid, did, add_hook, get_hook)
53
54#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
55#define RIO_GET_DID(x) ((x & 0x00ff0000) >> 16)
56#define RIO_SET_DID(x) ((x & 0x000000ff) << 16)
57#else
58#define RIO_GET_DID(x) (x & 0xffff)
59#define RIO_SET_DID(x) (x & 0xffff)
60#endif
diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile
new file mode 100644
index 000000000000..b924f8301761
--- /dev/null
+++ b/drivers/rapidio/switches/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for RIO switches
3#
4
5obj-$(CONFIG_RAPIDIO) += tsi500.o
diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c
new file mode 100644
index 000000000000..c77c23bd9840
--- /dev/null
+++ b/drivers/rapidio/switches/tsi500.c
@@ -0,0 +1,60 @@
1/*
2 * RapidIO Tsi500 switch support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/rio.h>
14#include <linux/rio_drv.h>
15#include <linux/rio_ids.h>
16#include "../rio.h"
17
18static int
19tsi500_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port)
20{
21 int i;
22 u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
23 u32 result;
24
25 if (table == 0xff) {
26 rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
27 result &= ~(0xf << (4*(route_destid & 0x7)));
28 for (i=0;i<4;i++)
29 rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*i), result | (route_port << (4*(route_destid & 0x7))));
30 }
31 else {
32 rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
33 result &= ~(0xf << (4*(route_destid & 0x7)));
34 rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*table), result | (route_port << (4*(route_destid & 0x7))));
35 }
36
37 return 0;
38}
39
40static int
41tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port)
42{
43 int ret = 0;
44 u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
45 u32 result;
46
47 if (table == 0xff)
48 rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
49 else
50 rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
51
52 result &= 0xf << (4*(route_destid & 0x7));
53 *route_port = result >> (4*(route_destid & 0x7));
54 if (*route_port > 3)
55 ret = -1;
56
57 return ret;
58}
59
60DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 8fc891a9d47f..7008d32433bf 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -115,8 +115,7 @@ dasd_alloc_device(void)
115void 115void
116dasd_free_device(struct dasd_device *device) 116dasd_free_device(struct dasd_device *device)
117{ 117{
118 if (device->private) 118 kfree(device->private);
119 kfree(device->private);
120 free_page((unsigned long) device->erp_mem); 119 free_page((unsigned long) device->erp_mem);
121 free_pages((unsigned long) device->ccw_mem, 1); 120 free_pages((unsigned long) device->ccw_mem, 1);
122 kfree(device); 121 kfree(device);
@@ -539,8 +538,7 @@ dasd_kmalloc_request(char *magic, int cplength, int datasize,
539 if (datasize > 0) { 538 if (datasize > 0) {
540 cqr->data = kmalloc(datasize, GFP_ATOMIC | GFP_DMA); 539 cqr->data = kmalloc(datasize, GFP_ATOMIC | GFP_DMA);
541 if (cqr->data == NULL) { 540 if (cqr->data == NULL) {
542 if (cqr->cpaddr != NULL) 541 kfree(cqr->cpaddr);
543 kfree(cqr->cpaddr);
544 kfree(cqr); 542 kfree(cqr);
545 return ERR_PTR(-ENOMEM); 543 return ERR_PTR(-ENOMEM);
546 } 544 }
@@ -615,10 +613,8 @@ dasd_kfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device)
615 clear_normalized_cda(ccw); 613 clear_normalized_cda(ccw);
616 } while (ccw++->flags & (CCW_FLAG_CC | CCW_FLAG_DC)); 614 } while (ccw++->flags & (CCW_FLAG_CC | CCW_FLAG_DC));
617#endif 615#endif
618 if (cqr->cpaddr != NULL) 616 kfree(cqr->cpaddr);
619 kfree(cqr->cpaddr); 617 kfree(cqr->data);
620 if (cqr->data != NULL)
621 kfree(cqr->data);
622 kfree(cqr); 618 kfree(cqr);
623 dasd_put_device(device); 619 dasd_put_device(device);
624} 620}
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index bda896d9d788..caee16a3dc62 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -387,8 +387,7 @@ dasd_add_busid(char *bus_id, int features)
387 new = 0; 387 new = 0;
388 } 388 }
389 spin_unlock(&dasd_devmap_lock); 389 spin_unlock(&dasd_devmap_lock);
390 if (new) 390 kfree(new);
391 kfree(new);
392 return devmap; 391 return devmap;
393} 392}
394 393
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 7478423b53bb..ab8754e566bc 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -6,7 +6,7 @@
6 * Bugreports.to..: <Linux390@de.ibm.com> 6 * Bugreports.to..: <Linux390@de.ibm.com>
7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
8 * 8 *
9 * $Revision: 1.49 $ 9 * $Revision: 1.51 $
10 */ 10 */
11 11
12#include <linux/config.h> 12#include <linux/config.h>
@@ -67,9 +67,9 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
67static __inline__ int 67static __inline__ int
68dia250(void *iob, int cmd) 68dia250(void *iob, int cmd)
69{ 69{
70 typedef struct { 70 typedef union {
71 char _[max(sizeof (struct dasd_diag_init_io), 71 struct dasd_diag_init_io init_io;
72 sizeof (struct dasd_diag_rw_io))]; 72 struct dasd_diag_rw_io rw_io;
73 } addr_type; 73 } addr_type;
74 int rc; 74 int rc;
75 75
@@ -190,7 +190,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
190 private->iob.flags = DASD_DIAG_RWFLAG_ASYNC; 190 private->iob.flags = DASD_DIAG_RWFLAG_ASYNC;
191 private->iob.block_count = dreq->block_count; 191 private->iob.block_count = dreq->block_count;
192 private->iob.interrupt_params = (addr_t) cqr; 192 private->iob.interrupt_params = (addr_t) cqr;
193 private->iob.bio_list = __pa(dreq->bio); 193 private->iob.bio_list = dreq->bio;
194 private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; 194 private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
195 195
196 cqr->startclk = get_clock(); 196 cqr->startclk = get_clock();
@@ -394,47 +394,57 @@ dasd_diag_check_device(struct dasd_device *device)
394 memset(&bio, 0, sizeof (struct dasd_diag_bio)); 394 memset(&bio, 0, sizeof (struct dasd_diag_bio));
395 bio.type = MDSK_READ_REQ; 395 bio.type = MDSK_READ_REQ;
396 bio.block_number = private->pt_block + 1; 396 bio.block_number = private->pt_block + 1;
397 bio.buffer = __pa(label); 397 bio.buffer = label;
398 memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io)); 398 memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io));
399 private->iob.dev_nr = rdc_data->dev_nr; 399 private->iob.dev_nr = rdc_data->dev_nr;
400 private->iob.key = 0; 400 private->iob.key = 0;
401 private->iob.flags = 0; /* do synchronous io */ 401 private->iob.flags = 0; /* do synchronous io */
402 private->iob.block_count = 1; 402 private->iob.block_count = 1;
403 private->iob.interrupt_params = 0; 403 private->iob.interrupt_params = 0;
404 private->iob.bio_list = __pa(&bio); 404 private->iob.bio_list = &bio;
405 private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; 405 private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
406 rc = dia250(&private->iob, RW_BIO); 406 rc = dia250(&private->iob, RW_BIO);
407 if (rc == 0 || rc == 3) 407 if (rc == 3) {
408 break; 408 DEV_MESSAGE(KERN_WARNING, device, "%s",
409 "DIAG call failed");
410 rc = -EOPNOTSUPP;
411 goto out;
412 }
409 mdsk_term_io(device); 413 mdsk_term_io(device);
414 if (rc == 0)
415 break;
410 } 416 }
411 if (rc == 3) { 417 if (bsize > PAGE_SIZE) {
412 DEV_MESSAGE(KERN_WARNING, device, "%s", "DIAG call failed");
413 rc = -EOPNOTSUPP;
414 } else if (rc != 0) {
415 DEV_MESSAGE(KERN_WARNING, device, "device access failed " 418 DEV_MESSAGE(KERN_WARNING, device, "device access failed "
416 "(rc=%d)", rc); 419 "(rc=%d)", rc);
417 rc = -EIO; 420 rc = -EIO;
421 goto out;
422 }
423 /* check for label block */
424 if (memcmp(label->label_id, DASD_DIAG_CMS1,
425 sizeof(DASD_DIAG_CMS1)) == 0) {
426 /* get formatted blocksize from label block */
427 bsize = (unsigned int) label->block_size;
428 device->blocks = (unsigned long) label->block_count;
429 } else
430 device->blocks = end_block;
431 device->bp_block = bsize;
432 device->s2b_shift = 0; /* bits to shift 512 to get a block */
433 for (sb = 512; sb < bsize; sb = sb << 1)
434 device->s2b_shift++;
435 rc = mdsk_init_io(device, device->bp_block, 0, NULL);
436 if (rc) {
437 DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
438 "failed (rc=%d)", rc);
439 rc = -EIO;
418 } else { 440 } else {
419 if (memcmp(label->label_id, DASD_DIAG_CMS1,
420 sizeof(DASD_DIAG_CMS1)) == 0) {
421 /* get formatted blocksize from label block */
422 bsize = (unsigned int) label->block_size;
423 device->blocks = (unsigned long) label->block_count;
424 } else
425 device->blocks = end_block;
426 device->bp_block = bsize;
427 device->s2b_shift = 0; /* bits to shift 512 to get a block */
428 for (sb = 512; sb < bsize; sb = sb << 1)
429 device->s2b_shift++;
430
431 DEV_MESSAGE(KERN_INFO, device, 441 DEV_MESSAGE(KERN_INFO, device,
432 "(%ld B/blk): %ldkB", 442 "(%ld B/blk): %ldkB",
433 (unsigned long) device->bp_block, 443 (unsigned long) device->bp_block,
434 (unsigned long) (device->blocks << 444 (unsigned long) (device->blocks <<
435 device->s2b_shift) >> 1); 445 device->s2b_shift) >> 1);
436 rc = 0;
437 } 446 }
447out:
438 free_page((long) label); 448 free_page((long) label);
439 return rc; 449 return rc;
440} 450}
@@ -529,7 +539,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
529 memset(dbio, 0, sizeof (struct dasd_diag_bio)); 539 memset(dbio, 0, sizeof (struct dasd_diag_bio));
530 dbio->type = rw_cmd; 540 dbio->type = rw_cmd;
531 dbio->block_number = recid + 1; 541 dbio->block_number = recid + 1;
532 dbio->buffer = __pa(dst); 542 dbio->buffer = dst;
533 dbio++; 543 dbio++;
534 dst += blksize; 544 dst += blksize;
535 recid++; 545 recid++;
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h
index b26eb28df4bf..df31484d73a7 100644
--- a/drivers/s390/block/dasd_diag.h
+++ b/drivers/s390/block/dasd_diag.h
@@ -6,7 +6,7 @@
6 * Bugreports.to..: <Linux390@de.ibm.com> 6 * Bugreports.to..: <Linux390@de.ibm.com>
7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
8 * 8 *
9 * $Revision: 1.7 $ 9 * $Revision: 1.8 $
10 */ 10 */
11 11
12#define MDSK_WRITE_REQ 0x01 12#define MDSK_WRITE_REQ 0x01
@@ -78,7 +78,7 @@ struct dasd_diag_bio {
78 u8 spare1[2]; 78 u8 spare1[2];
79 u32 alet; 79 u32 alet;
80 blocknum_t block_number; 80 blocknum_t block_number;
81 u64 buffer; 81 void *buffer;
82} __attribute__ ((packed, aligned(8))); 82} __attribute__ ((packed, aligned(8)));
83 83
84struct dasd_diag_init_io { 84struct dasd_diag_init_io {
@@ -104,7 +104,7 @@ struct dasd_diag_rw_io {
104 u32 alet; 104 u32 alet;
105 u8 spare3[4]; 105 u8 spare3[4];
106 u64 interrupt_params; 106 u64 interrupt_params;
107 u64 bio_list; 107 struct dasd_diag_bio *bio_list;
108 u8 spare4[8]; 108 u8 spare4[8];
109} __attribute__ ((packed, aligned(8))); 109} __attribute__ ((packed, aligned(8)));
110#else /* CONFIG_ARCH_S390X */ 110#else /* CONFIG_ARCH_S390X */
@@ -119,7 +119,7 @@ struct dasd_diag_bio {
119 u16 spare1; 119 u16 spare1;
120 blocknum_t block_number; 120 blocknum_t block_number;
121 u32 alet; 121 u32 alet;
122 u32 buffer; 122 void *buffer;
123} __attribute__ ((packed, aligned(8))); 123} __attribute__ ((packed, aligned(8)));
124 124
125struct dasd_diag_init_io { 125struct dasd_diag_init_io {
@@ -142,7 +142,7 @@ struct dasd_diag_rw_io {
142 u8 spare2[2]; 142 u8 spare2[2];
143 u32 block_count; 143 u32 block_count;
144 u32 alet; 144 u32 alet;
145 u32 bio_list; 145 struct dasd_diag_bio *bio_list;
146 u32 interrupt_params; 146 u32 interrupt_params;
147 u8 spare3[20]; 147 u8 spare3[20];
148} __attribute__ ((packed, aligned(8))); 148} __attribute__ ((packed, aligned(8)));
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index f11a67fda40e..75419cf9d353 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -727,8 +727,7 @@ raw3215_remove (struct ccw_device *cdev)
727 raw = cdev->dev.driver_data; 727 raw = cdev->dev.driver_data;
728 if (raw) { 728 if (raw) {
729 cdev->dev.driver_data = NULL; 729 cdev->dev.driver_data = NULL;
730 if (raw->buffer) 730 kfree(raw->buffer);
731 kfree(raw->buffer);
732 kfree(raw); 731 kfree(raw);
733 } 732 }
734} 733}
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index fd43d99b45a3..5bda2340a39d 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -99,13 +99,11 @@ out_fn_handler:
99 kfree(kbd->fn_handler); 99 kfree(kbd->fn_handler);
100out_func: 100out_func:
101 for (i = 0; i < ARRAY_SIZE(func_table); i++) 101 for (i = 0; i < ARRAY_SIZE(func_table); i++)
102 if (kbd->func_table[i]) 102 kfree(kbd->func_table[i]);
103 kfree(kbd->func_table[i]);
104 kfree(kbd->func_table); 103 kfree(kbd->func_table);
105out_maps: 104out_maps:
106 for (i = 0; i < ARRAY_SIZE(key_maps); i++) 105 for (i = 0; i < ARRAY_SIZE(key_maps); i++)
107 if (kbd->key_maps[i]) 106 kfree(kbd->key_maps[i]);
108 kfree(kbd->key_maps[i]);
109 kfree(kbd->key_maps); 107 kfree(kbd->key_maps);
110out_kbd: 108out_kbd:
111 kfree(kbd); 109 kfree(kbd);
@@ -121,12 +119,10 @@ kbd_free(struct kbd_data *kbd)
121 kfree(kbd->accent_table); 119 kfree(kbd->accent_table);
122 kfree(kbd->fn_handler); 120 kfree(kbd->fn_handler);
123 for (i = 0; i < ARRAY_SIZE(func_table); i++) 121 for (i = 0; i < ARRAY_SIZE(func_table); i++)
124 if (kbd->func_table[i]) 122 kfree(kbd->func_table[i]);
125 kfree(kbd->func_table[i]);
126 kfree(kbd->func_table); 123 kfree(kbd->func_table);
127 for (i = 0; i < ARRAY_SIZE(key_maps); i++) 124 for (i = 0; i < ARRAY_SIZE(key_maps); i++)
128 if (kbd->key_maps[i]) 125 kfree(kbd->key_maps[i]);
129 kfree(kbd->key_maps[i]);
130 kfree(kbd->key_maps); 126 kfree(kbd->key_maps);
131 kfree(kbd); 127 kfree(kbd);
132} 128}
@@ -452,8 +448,7 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
452 return -EFAULT; 448 return -EFAULT;
453 } 449 }
454 p[len] = 0; 450 p[len] = 0;
455 if (kbd->func_table[kb_func]) 451 kfree(kbd->func_table[kb_func]);
456 kfree(kbd->func_table[kb_func]);
457 kbd->func_table[kb_func] = p; 452 kbd->func_table[kb_func] = p;
458 break; 453 break;
459 } 454 }
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index 3b4da5a9cf79..f7bf45c6bf0d 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -41,14 +41,14 @@ int kbd_ioctl(struct kbd_data *, struct file *, unsigned int, unsigned long);
41/* 41/*
42 * Helper Functions. 42 * Helper Functions.
43 */ 43 */
44extern inline void 44static inline void
45kbd_put_queue(struct tty_struct *tty, int ch) 45kbd_put_queue(struct tty_struct *tty, int ch)
46{ 46{
47 tty_insert_flip_char(tty, ch, 0); 47 tty_insert_flip_char(tty, ch, 0);
48 tty_schedule_flip(tty); 48 tty_schedule_flip(tty);
49} 49}
50 50
51extern inline void 51static inline void
52kbd_puts_queue(struct tty_struct *tty, char *cp) 52kbd_puts_queue(struct tty_struct *tty, char *cp)
53{ 53{
54 while (*cp) 54 while (*cp)
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index d66946443dfc..f5b7d360fc10 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -183,8 +183,7 @@ raw3270_request_alloc_bootmem(size_t size)
183void 183void
184raw3270_request_free (struct raw3270_request *rq) 184raw3270_request_free (struct raw3270_request *rq)
185{ 185{
186 if (rq->buffer) 186 kfree(rq->buffer);
187 kfree(rq->buffer);
188 kfree(rq); 187 kfree(rq);
189} 188}
190 189
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 6c52e8307dc5..8f486e1a8507 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -682,8 +682,7 @@ tape_alloc_request(int cplength, int datasize)
682 request->cpdata = kmalloc(datasize, GFP_KERNEL | GFP_DMA); 682 request->cpdata = kmalloc(datasize, GFP_KERNEL | GFP_DMA);
683 if (request->cpdata == NULL) { 683 if (request->cpdata == NULL) {
684 DBF_EXCEPTION(1, "cqra nomem\n"); 684 DBF_EXCEPTION(1, "cqra nomem\n");
685 if (request->cpaddr != NULL) 685 kfree(request->cpaddr);
686 kfree(request->cpaddr);
687 kfree(request); 686 kfree(request);
688 return ERR_PTR(-ENOMEM); 687 return ERR_PTR(-ENOMEM);
689 } 688 }
@@ -706,10 +705,8 @@ tape_free_request (struct tape_request * request)
706 if (request->device != NULL) { 705 if (request->device != NULL) {
707 request->device = tape_put_device(request->device); 706 request->device = tape_put_device(request->device);
708 } 707 }
709 if (request->cpdata != NULL) 708 kfree(request->cpdata);
710 kfree(request->cpdata); 709 kfree(request->cpaddr);
711 if (request->cpaddr != NULL)
712 kfree(request->cpaddr);
713 kfree(request); 710 kfree(request);
714} 711}
715 712
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 8990d8076e7d..19762f3476aa 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -103,8 +103,10 @@ vmcp_write(struct file *file, const char __user * buff, size_t count,
103 } 103 }
104 cmd[count] = '\0'; 104 cmd[count] = '\0';
105 session = (struct vmcp_session *)file->private_data; 105 session = (struct vmcp_session *)file->private_data;
106 if (down_interruptible(&session->mutex)) 106 if (down_interruptible(&session->mutex)) {
107 kfree(cmd);
107 return -ERESTARTSYS; 108 return -ERESTARTSYS;
109 }
108 if (!session->response) 110 if (!session->response)
109 session->response = (char *)__get_free_pages(GFP_KERNEL 111 session->response = (char *)__get_free_pages(GFP_KERNEL
110 | __GFP_REPEAT | GFP_DMA, 112 | __GFP_REPEAT | GFP_DMA,
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index dbb3eb0e330b..e7bd7f37f080 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/cio/ccwgroup.c 2 * drivers/s390/cio/ccwgroup.c
3 * bus driver for ccwgroup 3 * bus driver for ccwgroup
4 * $Revision: 1.29 $ 4 * $Revision: 1.32 $
5 * 5 *
6 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, 6 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
7 * IBM Corporation 7 * IBM Corporation
@@ -274,7 +274,7 @@ ccwgroup_set_online(struct ccwgroup_device *gdev)
274 goto out; 274 goto out;
275 } 275 }
276 gdrv = to_ccwgroupdrv (gdev->dev.driver); 276 gdrv = to_ccwgroupdrv (gdev->dev.driver);
277 if ((ret = gdrv->set_online(gdev))) 277 if ((ret = gdrv->set_online ? gdrv->set_online(gdev) : 0))
278 goto out; 278 goto out;
279 279
280 gdev->state = CCWGROUP_ONLINE; 280 gdev->state = CCWGROUP_ONLINE;
@@ -300,7 +300,7 @@ ccwgroup_set_offline(struct ccwgroup_device *gdev)
300 goto out; 300 goto out;
301 } 301 }
302 gdrv = to_ccwgroupdrv (gdev->dev.driver); 302 gdrv = to_ccwgroupdrv (gdev->dev.driver);
303 if ((ret = gdrv->set_offline(gdev))) 303 if ((ret = gdrv->set_offline ? gdrv->set_offline(gdev) : 0))
304 goto out; 304 goto out;
305 305
306 gdev->state = CCWGROUP_OFFLINE; 306 gdev->state = CCWGROUP_OFFLINE;
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index c05b069c2996..b978f7fe8327 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -642,8 +642,7 @@ static void
642free_cmbe (struct ccw_device *cdev) 642free_cmbe (struct ccw_device *cdev)
643{ 643{
644 spin_lock_irq(cdev->ccwlock); 644 spin_lock_irq(cdev->ccwlock);
645 if (cdev->private->cmb) 645 kfree(cdev->private->cmb);
646 kfree(cdev->private->cmb);
647 cdev->private->cmb = NULL; 646 cdev->private->cmb = NULL;
648 spin_unlock_irq(cdev->ccwlock); 647 spin_unlock_irq(cdev->ccwlock);
649 648
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index ad3fe5aeb663..85a3026e6900 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -550,10 +550,8 @@ ccw_device_stlck(struct ccw_device *cdev)
550 /* Clear irb. */ 550 /* Clear irb. */
551 memset(&cdev->private->irb, 0, sizeof(struct irb)); 551 memset(&cdev->private->irb, 0, sizeof(struct irb));
552out_unlock: 552out_unlock:
553 if (buf) 553 kfree(buf);
554 kfree(buf); 554 kfree(buf2);
555 if (buf2)
556 kfree(buf2);
557 spin_unlock_irqrestore(&sch->lock, flags); 555 spin_unlock_irqrestore(&sch->lock, flags);
558 return ret; 556 return ret;
559} 557}
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 381f339e3200..eb39218b925e 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -56,7 +56,7 @@
56#include "ioasm.h" 56#include "ioasm.h"
57#include "chsc.h" 57#include "chsc.h"
58 58
59#define VERSION_QDIO_C "$Revision: 1.101 $" 59#define VERSION_QDIO_C "$Revision: 1.108 $"
60 60
61/****************** MODULE PARAMETER VARIABLES ********************/ 61/****************** MODULE PARAMETER VARIABLES ********************/
62MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>"); 62MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -1338,16 +1338,14 @@ qdio_release_irq_memory(struct qdio_irq *irq_ptr)
1338 if (!irq_ptr->input_qs[i]) 1338 if (!irq_ptr->input_qs[i])
1339 goto next; 1339 goto next;
1340 1340
1341 if (irq_ptr->input_qs[i]->slib) 1341 kfree(irq_ptr->input_qs[i]->slib);
1342 kfree(irq_ptr->input_qs[i]->slib);
1343 kfree(irq_ptr->input_qs[i]); 1342 kfree(irq_ptr->input_qs[i]);
1344 1343
1345next: 1344next:
1346 if (!irq_ptr->output_qs[i]) 1345 if (!irq_ptr->output_qs[i])
1347 continue; 1346 continue;
1348 1347
1349 if (irq_ptr->output_qs[i]->slib) 1348 kfree(irq_ptr->output_qs[i]->slib);
1350 kfree(irq_ptr->output_qs[i]->slib);
1351 kfree(irq_ptr->output_qs[i]); 1349 kfree(irq_ptr->output_qs[i]);
1352 1350
1353 } 1351 }
@@ -2873,10 +2871,10 @@ qdio_establish(struct qdio_initialize *init_data)
2873 return result; 2871 return result;
2874 } 2872 }
2875 2873
2876 wait_event_interruptible_timeout(cdev->private->wait_q, 2874 /* Timeout is cared for already by using ccw_device_start_timeout(). */
2875 wait_event_interruptible(cdev->private->wait_q,
2877 irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || 2876 irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED ||
2878 irq_ptr->state == QDIO_IRQ_STATE_ERR, 2877 irq_ptr->state == QDIO_IRQ_STATE_ERR);
2879 QDIO_ESTABLISH_TIMEOUT);
2880 2878
2881 if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED) 2879 if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED)
2882 result = 0; 2880 result = 0;
@@ -3315,8 +3313,7 @@ qdio_get_qdio_memory(void)
3315static void 3313static void
3316qdio_release_qdio_memory(void) 3314qdio_release_qdio_memory(void)
3317{ 3315{
3318 if (indicators) 3316 kfree(indicators);
3319 kfree(indicators);
3320} 3317}
3321 3318
3322static void 3319static void
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 6b8aa6a852be..328e31cc6854 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -265,7 +265,7 @@ QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
265/* 265/*
266 * Some instructions as assembly 266 * Some instructions as assembly
267 */ 267 */
268extern __inline__ int 268static inline int
269do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) 269do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
270{ 270{
271 int cc; 271 int cc;
@@ -300,7 +300,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
300 return cc; 300 return cc;
301} 301}
302 302
303extern __inline__ int 303static inline int
304do_siga_input(unsigned int irq, unsigned int mask) 304do_siga_input(unsigned int irq, unsigned int mask)
305{ 305{
306 int cc; 306 int cc;
@@ -334,7 +334,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
334 return cc; 334 return cc;
335} 335}
336 336
337extern __inline__ int 337static inline int
338do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb) 338do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
339{ 339{
340 int cc; 340 int cc;
@@ -401,7 +401,7 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
401 return cc; 401 return cc;
402} 402}
403 403
404extern __inline__ unsigned long 404static inline unsigned long
405do_clear_global_summary(void) 405do_clear_global_summary(void)
406{ 406{
407 407
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 0cb47eca91f3..4010f2bb85af 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -37,7 +37,6 @@
37#include <linux/kobject_uevent.h> 37#include <linux/kobject_uevent.h>
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/syscalls.h> 39#include <linux/syscalls.h>
40#include <linux/version.h>
41#include "z90crypt.h" 40#include "z90crypt.h"
42#include "z90common.h" 41#include "z90common.h"
43 42
@@ -3051,8 +3050,7 @@ destroy_crypto_device(int index)
3051 if (dev_ptr) { 3050 if (dev_ptr) {
3052 disabledFlag = dev_ptr->disabled; 3051 disabledFlag = dev_ptr->disabled;
3053 t = dev_ptr->dev_type; 3052 t = dev_ptr->dev_type;
3054 if (dev_ptr->dev_resp_p) 3053 kfree(dev_ptr->dev_resp_p);
3055 kfree(dev_ptr->dev_resp_p);
3056 kfree(dev_ptr); 3054 kfree(dev_ptr);
3057 } else { 3055 } else {
3058 disabledFlag = 0; 3056 disabledFlag = 0;
@@ -3080,11 +3078,11 @@ static void
3080destroy_z90crypt(void) 3078destroy_z90crypt(void)
3081{ 3079{
3082 int i; 3080 int i;
3081
3083 for (i = 0; i < z90crypt.max_count; i++) 3082 for (i = 0; i < z90crypt.max_count; i++)
3084 if (z90crypt.device_p[i]) 3083 if (z90crypt.device_p[i])
3085 destroy_crypto_device(i); 3084 destroy_crypto_device(i);
3086 if (z90crypt.hdware_info) 3085 kfree(z90crypt.hdware_info);
3087 kfree((void *)z90crypt.hdware_info);
3088 memset((void *)&z90crypt, 0, sizeof(z90crypt)); 3086 memset((void *)&z90crypt, 0, sizeof(z90crypt));
3089} 3087}
3090 3088
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 3092473991a7..6b63d21612ec 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -88,7 +88,6 @@
88#include <linux/tcp.h> 88#include <linux/tcp.h>
89#include <linux/timer.h> 89#include <linux/timer.h>
90#include <linux/types.h> 90#include <linux/types.h>
91#include <linux/version.h>
92 91
93#include "cu3088.h" 92#include "cu3088.h"
94#include "claw.h" 93#include "claw.h"
@@ -2743,14 +2742,10 @@ probe_error( struct ccwgroup_device *cgdev)
2743#endif 2742#endif
2744 privptr=(struct claw_privbk *)cgdev->dev.driver_data; 2743 privptr=(struct claw_privbk *)cgdev->dev.driver_data;
2745 if (privptr!=NULL) { 2744 if (privptr!=NULL) {
2746 if (privptr->p_env != NULL) { 2745 kfree(privptr->p_env);
2747 kfree(privptr->p_env); 2746 privptr->p_env=NULL;
2748 privptr->p_env=NULL; 2747 kfree(privptr->p_mtc_envelope);
2749 } 2748 privptr->p_mtc_envelope=NULL;
2750 if (privptr->p_mtc_envelope!=NULL) {
2751 kfree(privptr->p_mtc_envelope);
2752 privptr->p_mtc_envelope=NULL;
2753 }
2754 kfree(privptr); 2749 kfree(privptr);
2755 privptr=NULL; 2750 privptr=NULL;
2756 } 2751 }
@@ -4121,22 +4116,14 @@ claw_remove_device(struct ccwgroup_device *cgdev)
4121 if (cgdev->state == CCWGROUP_ONLINE) 4116 if (cgdev->state == CCWGROUP_ONLINE)
4122 claw_shutdown_device(cgdev); 4117 claw_shutdown_device(cgdev);
4123 claw_remove_files(&cgdev->dev); 4118 claw_remove_files(&cgdev->dev);
4124 if (priv->p_mtc_envelope!=NULL) { 4119 kfree(priv->p_mtc_envelope);
4125 kfree(priv->p_mtc_envelope); 4120 priv->p_mtc_envelope=NULL;
4126 priv->p_mtc_envelope=NULL; 4121 kfree(priv->p_env);
4127 } 4122 priv->p_env=NULL;
4128 if (priv->p_env != NULL) { 4123 kfree(priv->channel[0].irb);
4129 kfree(priv->p_env); 4124 priv->channel[0].irb=NULL;
4130 priv->p_env=NULL; 4125 kfree(priv->channel[1].irb);
4131 } 4126 priv->channel[1].irb=NULL;
4132 if (priv->channel[0].irb != NULL) {
4133 kfree(priv->channel[0].irb);
4134 priv->channel[0].irb=NULL;
4135 }
4136 if (priv->channel[1].irb != NULL) {
4137 kfree(priv->channel[1].irb);
4138 priv->channel[1].irb=NULL;
4139 }
4140 kfree(priv); 4127 kfree(priv);
4141 cgdev->dev.driver_data=NULL; 4128 cgdev->dev.driver_data=NULL;
4142 cgdev->cdev[READ]->dev.driver_data = NULL; 4129 cgdev->cdev[READ]->dev.driver_data = NULL;
diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c
index 38f50b7129a2..24029bd9c7d0 100644
--- a/drivers/s390/net/fsm.c
+++ b/drivers/s390/net/fsm.c
@@ -78,8 +78,7 @@ kfree_fsm(fsm_instance *this)
78{ 78{
79 if (this) { 79 if (this) {
80 if (this->f) { 80 if (this->f) {
81 if (this->f->jumpmatrix) 81 kfree(this->f->jumpmatrix);
82 kfree(this->f->jumpmatrix);
83 kfree(this->f); 82 kfree(this->f);
84 } 83 }
85 kfree(this); 84 kfree(this);
diff --git a/drivers/s390/net/fsm.h b/drivers/s390/net/fsm.h
index 1b8a7e7c34f3..5b98253be7aa 100644
--- a/drivers/s390/net/fsm.h
+++ b/drivers/s390/net/fsm.h
@@ -140,7 +140,7 @@ fsm_record_history(fsm_instance *fi, int state, int event);
140 * 1 if current state or event is out of range 140 * 1 if current state or event is out of range
141 * !0 if state and event in range, but no action defined. 141 * !0 if state and event in range, but no action defined.
142 */ 142 */
143extern __inline__ int 143static inline int
144fsm_event(fsm_instance *fi, int event, void *arg) 144fsm_event(fsm_instance *fi, int event, void *arg)
145{ 145{
146 fsm_function_t r; 146 fsm_function_t r;
@@ -188,7 +188,7 @@ fsm_event(fsm_instance *fi, int event, void *arg)
188 * @param fi Pointer to FSM 188 * @param fi Pointer to FSM
189 * @param state The new state for this FSM. 189 * @param state The new state for this FSM.
190 */ 190 */
191extern __inline__ void 191static inline void
192fsm_newstate(fsm_instance *fi, int newstate) 192fsm_newstate(fsm_instance *fi, int newstate)
193{ 193{
194 atomic_set(&fi->state,newstate); 194 atomic_set(&fi->state,newstate);
@@ -208,7 +208,7 @@ fsm_newstate(fsm_instance *fi, int newstate)
208 * 208 *
209 * @return The current state of the FSM. 209 * @return The current state of the FSM.
210 */ 210 */
211extern __inline__ int 211static inline int
212fsm_getstate(fsm_instance *fi) 212fsm_getstate(fsm_instance *fi)
213{ 213{
214 return atomic_read(&fi->state); 214 return atomic_read(&fi->state);
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index e08e74e16124..df7647c3c100 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -447,14 +447,10 @@ static void
447iucv_exit(void) 447iucv_exit(void)
448{ 448{
449 iucv_retrieve_buffer(); 449 iucv_retrieve_buffer();
450 if (iucv_external_int_buffer) { 450 kfree(iucv_external_int_buffer);
451 kfree(iucv_external_int_buffer); 451 iucv_external_int_buffer = NULL;
452 iucv_external_int_buffer = NULL; 452 kfree(iucv_param_pool);
453 } 453 iucv_param_pool = NULL;
454 if (iucv_param_pool) {
455 kfree(iucv_param_pool);
456 iucv_param_pool = NULL;
457 }
458 s390_root_dev_unregister(iucv_root); 454 s390_root_dev_unregister(iucv_root);
459 bus_unregister(&iucv_bus); 455 bus_unregister(&iucv_bus);
460 printk(KERN_INFO "IUCV lowlevel driver unloaded\n"); 456 printk(KERN_INFO "IUCV lowlevel driver unloaded\n");
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 46f34ba93ac5..1c8ad2fcad8a 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -145,8 +145,7 @@ lcs_free_channel(struct lcs_channel *channel)
145 145
146 LCS_DBF_TEXT(2, setup, "ichfree"); 146 LCS_DBF_TEXT(2, setup, "ichfree");
147 for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++) { 147 for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++) {
148 if (channel->iob[cnt].data != NULL) 148 kfree(channel->iob[cnt].data);
149 kfree(channel->iob[cnt].data);
150 channel->iob[cnt].data = NULL; 149 channel->iob[cnt].data = NULL;
151 } 150 }
152} 151}
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index f94f1f25eec6..011915d5e243 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -62,8 +62,7 @@ qeth_eddp_free_context(struct qeth_eddp_context *ctx)
62 for (i = 0; i < ctx->num_pages; ++i) 62 for (i = 0; i < ctx->num_pages; ++i)
63 free_page((unsigned long)ctx->pages[i]); 63 free_page((unsigned long)ctx->pages[i]);
64 kfree(ctx->pages); 64 kfree(ctx->pages);
65 if (ctx->elements != NULL) 65 kfree(ctx->elements);
66 kfree(ctx->elements);
67 kfree(ctx); 66 kfree(ctx);
68} 67}
69 68
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
index 4eaa70179182..d9ea7ed2e46e 100644
--- a/drivers/s390/s390mach.h
+++ b/drivers/s390/s390mach.h
@@ -88,7 +88,7 @@ struct crw {
88#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */ 88#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
89#define CRW_ERC_PMOD 0x08 /* installed parameters modified */ 89#define CRW_ERC_PMOD 0x08 /* installed parameters modified */
90 90
91extern __inline__ int stcrw(struct crw *pcrw ) 91static inline int stcrw(struct crw *pcrw )
92{ 92{
93 int ccode; 93 int ccode;
94 94
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index cab098556b44..c218b5c944a6 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -450,8 +450,7 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
450 kfree(sg_list); 450 kfree(sg_list);
451 } 451 }
452 452
453 if (sense_data != NULL) 453 kfree(sense_data);
454 kfree(sense_data);
455 454
456 return retval; 455 return retval;
457} 456}
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index c82abeb59d3a..fd2cc7782f76 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -26,6 +26,7 @@
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/ioport.h> 27#include <linux/ioport.h>
28#include <linux/timer.h> 28#include <linux/timer.h>
29#include <linux/smp_lock.h>
29#include <asm/irq.h> 30#include <asm/irq.h>
30#include <asm/ebus.h> 31#include <asm/ebus.h>
31#include <asm/oplib.h> 32#include <asm/oplib.h>
@@ -394,6 +395,28 @@ static int wd_ioctl(struct inode *inode, struct file *file,
394 return(0); 395 return(0);
395} 396}
396 397
398static long wd_compat_ioctl(struct file *file, unsigned int cmd,
399 unsigned long arg)
400{
401 int rval = -ENOIOCTLCMD;
402
403 switch (cmd) {
404 /* solaris ioctls are specific to this driver */
405 case WIOCSTART:
406 case WIOCSTOP:
407 case WIOCGSTAT:
408 lock_kernel();
409 rval = wd_ioctl(file->f_dentry->d_inode, file, cmd, arg);
410 unlock_kernel();
411 break;
412 /* everything else is handled by the generic compat layer */
413 default:
414 break;
415 }
416
417 return rval;
418}
419
397static ssize_t wd_write(struct file *file, 420static ssize_t wd_write(struct file *file,
398 const char __user *buf, 421 const char __user *buf,
399 size_t count, 422 size_t count,
@@ -441,6 +464,7 @@ static irqreturn_t wd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
441static struct file_operations wd_fops = { 464static struct file_operations wd_fops = {
442 .owner = THIS_MODULE, 465 .owner = THIS_MODULE,
443 .ioctl = wd_ioctl, 466 .ioctl = wd_ioctl,
467 .compat_ioctl = wd_compat_ioctl,
444 .open = wd_open, 468 .open = wd_open,
445 .write = wd_write, 469 .write = wd_write,
446 .read = wd_read, 470 .read = wd_read,
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index 24ed5893b4f0..c3a51d1fae5d 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/miscdevice.h> 16#include <linux/miscdevice.h>
17#include <linux/ioport.h> /* request_region */ 17#include <linux/ioport.h> /* request_region */
18#include <linux/smp_lock.h>
18#include <asm/atomic.h> 19#include <asm/atomic.h>
19#include <asm/ebus.h> /* EBus device */ 20#include <asm/ebus.h> /* EBus device */
20#include <asm/oplib.h> /* OpenProm Library */ 21#include <asm/oplib.h> /* OpenProm Library */
@@ -114,22 +115,25 @@ static int d7s_release(struct inode *inode, struct file *f)
114 return 0; 115 return 0;
115} 116}
116 117
117static int d7s_ioctl(struct inode *inode, struct file *f, 118static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
118 unsigned int cmd, unsigned long arg)
119{ 119{
120 __u8 regs = readb(d7s_regs); 120 __u8 regs = readb(d7s_regs);
121 __u8 ireg = 0; 121 __u8 ireg = 0;
122 int error = 0;
122 123
123 if (D7S_MINOR != iminor(inode)) 124 if (D7S_MINOR != iminor(file->f_dentry->d_inode))
124 return -ENODEV; 125 return -ENODEV;
125 126
127 lock_kernel();
126 switch (cmd) { 128 switch (cmd) {
127 case D7SIOCWR: 129 case D7SIOCWR:
128 /* assign device register values 130 /* assign device register values
129 * we mask-out D7S_FLIP if in sol_compat mode 131 * we mask-out D7S_FLIP if in sol_compat mode
130 */ 132 */
131 if (get_user(ireg, (int __user *) arg)) 133 if (get_user(ireg, (int __user *) arg)) {
132 return -EFAULT; 134 error = -EFAULT;
135 break;
136 }
133 if (0 != sol_compat) { 137 if (0 != sol_compat) {
134 (regs & D7S_FLIP) ? 138 (regs & D7S_FLIP) ?
135 (ireg |= D7S_FLIP) : (ireg &= ~D7S_FLIP); 139 (ireg |= D7S_FLIP) : (ireg &= ~D7S_FLIP);
@@ -144,8 +148,10 @@ static int d7s_ioctl(struct inode *inode, struct file *f,
144 * This driver will not misinform you about the state 148 * This driver will not misinform you about the state
145 * of your hardware while in sol_compat mode 149 * of your hardware while in sol_compat mode
146 */ 150 */
147 if (put_user(regs, (int __user *) arg)) 151 if (put_user(regs, (int __user *) arg)) {
148 return -EFAULT; 152 error = -EFAULT;
153 break;
154 }
149 break; 155 break;
150 156
151 case D7SIOCTM: 157 case D7SIOCTM:
@@ -155,15 +161,17 @@ static int d7s_ioctl(struct inode *inode, struct file *f,
155 writeb(regs, d7s_regs); 161 writeb(regs, d7s_regs);
156 break; 162 break;
157 }; 163 };
164 unlock_kernel();
158 165
159 return 0; 166 return error;
160} 167}
161 168
162static struct file_operations d7s_fops = { 169static struct file_operations d7s_fops = {
163 .owner = THIS_MODULE, 170 .owner = THIS_MODULE,
164 .ioctl = d7s_ioctl, 171 .unlocked_ioctl = d7s_ioctl,
165 .open = d7s_open, 172 .compat_ioctl = d7s_ioctl,
166 .release = d7s_release, 173 .open = d7s_open,
174 .release = d7s_release,
167}; 175};
168 176
169static struct miscdevice d7s_miscdev = { D7S_MINOR, D7S_DEVNAME, &d7s_fops }; 177static struct miscdevice d7s_miscdev = { D7S_MINOR, D7S_DEVNAME, &d7s_fops };
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index b0cc3c2588fd..19e8eddf887a 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -654,9 +654,8 @@ envctrl_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
654/* Function Description: Command what to read. Mapped to user ioctl(). 654/* Function Description: Command what to read. Mapped to user ioctl().
655 * Return: Gives 0 for implemented commands, -EINVAL otherwise. 655 * Return: Gives 0 for implemented commands, -EINVAL otherwise.
656 */ 656 */
657static int 657static long
658envctrl_ioctl(struct inode *inode, struct file *file, 658envctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
659 unsigned int cmd, unsigned long arg)
660{ 659{
661 char __user *infobuf; 660 char __user *infobuf;
662 661
@@ -715,11 +714,14 @@ envctrl_release(struct inode *inode, struct file *file)
715} 714}
716 715
717static struct file_operations envctrl_fops = { 716static struct file_operations envctrl_fops = {
718 .owner = THIS_MODULE, 717 .owner = THIS_MODULE,
719 .read = envctrl_read, 718 .read = envctrl_read,
720 .ioctl = envctrl_ioctl, 719 .unlocked_ioctl = envctrl_ioctl,
721 .open = envctrl_open, 720#ifdef CONFIG_COMPAT
722 .release = envctrl_release, 721 .compat_ioctl = envctrl_ioctl,
722#endif
723 .open = envctrl_open,
724 .release = envctrl_release,
723}; 725};
724 726
725static struct miscdevice envctrl_dev = { 727static struct miscdevice envctrl_dev = {
@@ -1125,10 +1127,9 @@ out_deregister:
1125 misc_deregister(&envctrl_dev); 1127 misc_deregister(&envctrl_dev);
1126out_iounmap: 1128out_iounmap:
1127 iounmap(i2c); 1129 iounmap(i2c);
1128 for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) { 1130 for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
1129 if (i2c_childlist[i].tables) 1131 kfree(i2c_childlist[i].tables);
1130 kfree(i2c_childlist[i].tables); 1132
1131 }
1132 return err; 1133 return err;
1133} 1134}
1134 1135
@@ -1141,10 +1142,8 @@ static void __exit envctrl_cleanup(void)
1141 iounmap(i2c); 1142 iounmap(i2c);
1142 misc_deregister(&envctrl_dev); 1143 misc_deregister(&envctrl_dev);
1143 1144
1144 for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) { 1145 for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
1145 if (i2c_childlist[i].tables) 1146 kfree(i2c_childlist[i].tables);
1146 kfree(i2c_childlist[i].tables);
1147 }
1148} 1147}
1149 1148
1150module_init(envctrl_init); 1149module_init(envctrl_init);
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 58ed33749571..383a95f34a0d 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -39,6 +39,7 @@
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/string.h> 40#include <linux/string.h>
41#include <linux/miscdevice.h> 41#include <linux/miscdevice.h>
42#include <linux/smp_lock.h>
42#include <linux/init.h> 43#include <linux/init.h>
43#include <linux/fs.h> 44#include <linux/fs.h>
44#include <asm/oplib.h> 45#include <asm/oplib.h>
@@ -565,6 +566,40 @@ static int openprom_ioctl(struct inode * inode, struct file * file,
565 } 566 }
566} 567}
567 568
569static long openprom_compat_ioctl(struct file *file, unsigned int cmd,
570 unsigned long arg)
571{
572 long rval = -ENOTTY;
573
574 /*
575 * SunOS/Solaris only, the NetBSD one's have embedded pointers in
576 * the arg which we'd need to clean up...
577 */
578 switch (cmd) {
579 case OPROMGETOPT:
580 case OPROMSETOPT:
581 case OPROMNXTOPT:
582 case OPROMSETOPT2:
583 case OPROMNEXT:
584 case OPROMCHILD:
585 case OPROMGETPROP:
586 case OPROMNXTPROP:
587 case OPROMU2P:
588 case OPROMGETCONS:
589 case OPROMGETFBNAME:
590 case OPROMGETBOOTARGS:
591 case OPROMSETCUR:
592 case OPROMPCI2NODE:
593 case OPROMPATH2NODE:
594 lock_kernel();
595 rval = openprom_ioctl(file->f_dentry->d_inode, file, cmd, arg);
596 lock_kernel();
597 break;
598 }
599
600 return rval;
601}
602
568static int openprom_open(struct inode * inode, struct file * file) 603static int openprom_open(struct inode * inode, struct file * file)
569{ 604{
570 DATA *data; 605 DATA *data;
@@ -590,6 +625,7 @@ static struct file_operations openprom_fops = {
590 .owner = THIS_MODULE, 625 .owner = THIS_MODULE,
591 .llseek = no_llseek, 626 .llseek = no_llseek,
592 .ioctl = openprom_ioctl, 627 .ioctl = openprom_ioctl,
628 .compat_ioctl = openprom_compat_ioctl,
593 .open = openprom_open, 629 .open = openprom_open,
594 .release = openprom_release, 630 .release = openprom_release,
595}; 631};
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 9b988baf0b51..5774bdd0e26f 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -210,6 +210,27 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
210 } 210 }
211} 211}
212 212
213static long rtc_compat_ioctl(struct file *file, unsigned int cmd,
214 unsigned long arg)
215{
216 int rval = -ENOIOCTLCMD;
217
218 switch (cmd) {
219 /*
220 * These two are specific to this driver, the generic rtc ioctls
221 * are hanlded elsewhere.
222 */
223 case RTCGET:
224 case RTCSET:
225 lock_kernel();
226 rval = rtc_ioctl(file->f_dentry->d_inode, file, cmd, arg);
227 unlock_kernel();
228 break;
229 }
230
231 return rval;
232}
233
213static int rtc_open(struct inode *inode, struct file *file) 234static int rtc_open(struct inode *inode, struct file *file)
214{ 235{
215 int ret; 236 int ret;
@@ -237,6 +258,7 @@ static struct file_operations rtc_fops = {
237 .owner = THIS_MODULE, 258 .owner = THIS_MODULE,
238 .llseek = no_llseek, 259 .llseek = no_llseek,
239 .ioctl = rtc_ioctl, 260 .ioctl = rtc_ioctl,
261 .compat_ioctl = rtc_compat_ioctl,
240 .open = rtc_open, 262 .open = rtc_open,
241 .release = rtc_release, 263 .release = rtc_release,
242}; 264};
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index d06ee65d668d..3ff74f472249 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1017,8 +1017,7 @@ static void twa_free_device_extension(TW_Device_Extension *tw_dev)
1017 tw_dev->generic_buffer_virt[0], 1017 tw_dev->generic_buffer_virt[0],
1018 tw_dev->generic_buffer_phys[0]); 1018 tw_dev->generic_buffer_phys[0]);
1019 1019
1020 if (tw_dev->event_queue[0]) 1020 kfree(tw_dev->event_queue[0]);
1021 kfree(tw_dev->event_queue[0]);
1022} /* End twa_free_device_extension() */ 1021} /* End twa_free_device_extension() */
1023 1022
1024/* This function will free a request id */ 1023/* This function will free a request id */
diff --git a/drivers/scsi/3w-xxxx.h b/drivers/scsi/3w-xxxx.h
index 98bad773f240..4f81fc39ec57 100644
--- a/drivers/scsi/3w-xxxx.h
+++ b/drivers/scsi/3w-xxxx.h
@@ -54,7 +54,6 @@
54#ifndef _3W_XXXX_H 54#ifndef _3W_XXXX_H
55#define _3W_XXXX_H 55#define _3W_XXXX_H
56 56
57#include <linux/version.h>
58#include <linux/types.h> 57#include <linux/types.h>
59 58
60/* AEN strings */ 59/* AEN strings */
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index cc9ecb35b412..cba9655d0f14 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -606,10 +606,7 @@ static int __init NCR5380_probe_irq(struct Scsi_Host *instance, int possible)
606 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); 606 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
607 607
608 while (probe_irq == SCSI_IRQ_NONE && time_before(jiffies, timeout)) 608 while (probe_irq == SCSI_IRQ_NONE && time_before(jiffies, timeout))
609 { 609 schedule_timeout_uninterruptible(1);
610 set_current_state(TASK_UNINTERRUPTIBLE);
611 schedule_timeout(1);
612 }
613 610
614 NCR5380_write(SELECT_ENABLE_REG, 0); 611 NCR5380_write(SELECT_ENABLE_REG, 0);
615 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); 612 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index f7a1751e892d..30a14ba77a6a 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/init.h> 5#include <linux/init.h>
7#include <linux/interrupt.h> 6#include <linux/interrupt.h>
8 7
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index ee9067255930..723c0cea7c04 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1164,7 +1164,7 @@ int aac_command_thread(struct aac_dev * dev)
1164 kfree(hw_fib_pool); 1164 kfree(hw_fib_pool);
1165 hw_fib_pool = NULL; 1165 hw_fib_pool = NULL;
1166 } 1166 }
1167 } else if (hw_fib_pool) { 1167 } else {
1168 kfree(hw_fib_pool); 1168 kfree(hw_fib_pool);
1169 hw_fib_pool = NULL; 1169 hw_fib_pool = NULL;
1170 } 1170 }
@@ -1247,17 +1247,13 @@ int aac_command_thread(struct aac_dev * dev)
1247 hw_fib_p = hw_fib_pool; 1247 hw_fib_p = hw_fib_pool;
1248 fib_p = fib_pool; 1248 fib_p = fib_pool;
1249 while (hw_fib_p < &hw_fib_pool[num]) { 1249 while (hw_fib_p < &hw_fib_pool[num]) {
1250 if (*hw_fib_p) 1250 kfree(*hw_fib_p);
1251 kfree(*hw_fib_p); 1251 kfree(*fib_p);
1252 if (*fib_p)
1253 kfree(*fib_p);
1254 ++fib_p; 1252 ++fib_p;
1255 ++hw_fib_p; 1253 ++hw_fib_p;
1256 } 1254 }
1257 if (hw_fib_pool) 1255 kfree(hw_fib_pool);
1258 kfree(hw_fib_pool); 1256 kfree(fib_pool);
1259 if (fib_pool)
1260 kfree(fib_pool);
1261 } 1257 }
1262 kfree(fib); 1258 kfree(fib);
1263 spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags); 1259 spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index fc4c73c2a6a9..e9b775d6bec9 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -183,8 +183,7 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command,
183 /* 183 /*
184 * Yield the processor in case we are slow 184 * Yield the processor in case we are slow
185 */ 185 */
186 set_current_state(TASK_UNINTERRUPTIBLE); 186 schedule_timeout_uninterruptible(1);
187 schedule_timeout(1);
188 } 187 }
189 if (ok != 1) { 188 if (ok != 1) {
190 /* 189 /*
@@ -452,8 +451,7 @@ int aac_rkt_init(struct aac_dev *dev)
452 dev->name, instance, status); 451 dev->name, instance, status);
453 goto error_iounmap; 452 goto error_iounmap;
454 } 453 }
455 set_current_state(TASK_UNINTERRUPTIBLE); 454 schedule_timeout_uninterruptible(1);
456 schedule_timeout(1);
457 } 455 }
458 if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) 456 if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0)
459 { 457 {
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index da99046e5393..6998bc877dd6 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -183,8 +183,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command,
183 /* 183 /*
184 * Yield the processor in case we are slow 184 * Yield the processor in case we are slow
185 */ 185 */
186 set_current_state(TASK_UNINTERRUPTIBLE); 186 schedule_timeout_uninterruptible(1);
187 schedule_timeout(1);
188 } 187 }
189 if (ok != 1) { 188 if (ok != 1) {
190 /* 189 /*
@@ -452,8 +451,7 @@ int aac_rx_init(struct aac_dev *dev)
452 dev->name, instance, status); 451 dev->name, instance, status);
453 goto error_iounmap; 452 goto error_iounmap;
454 } 453 }
455 set_current_state(TASK_UNINTERRUPTIBLE); 454 schedule_timeout_uninterruptible(1);
456 schedule_timeout(1);
457 } 455 }
458 if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) 456 if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0)
459 { 457 {
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index 8b9596209164..466f05cfbf0c 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -189,8 +189,7 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command,
189 ok = 1; 189 ok = 1;
190 break; 190 break;
191 } 191 }
192 set_current_state(TASK_UNINTERRUPTIBLE); 192 schedule_timeout_uninterruptible(1);
193 schedule_timeout(1);
194 } 193 }
195 194
196 if (ok != 1) 195 if (ok != 1)
@@ -325,8 +324,7 @@ int aac_sa_init(struct aac_dev *dev)
325 name, instance, status); 324 name, instance, status);
326 goto error_iounmap; 325 goto error_iounmap;
327 } 326 }
328 set_current_state(TASK_UNINTERRUPTIBLE); 327 schedule_timeout_uninterruptible(1);
329 schedule_timeout(1);
330 } 328 }
331 329
332 if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev ) < 0) { 330 if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev ) < 0) {
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 37ec5411e325..f4cfb8f29620 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -5402,10 +5402,8 @@ advansys_detect(struct scsi_host_template *tpnt)
5402 release_region(shp->io_port, boardp->asc_n_io_port); 5402 release_region(shp->io_port, boardp->asc_n_io_port);
5403 if (ASC_WIDE_BOARD(boardp)) { 5403 if (ASC_WIDE_BOARD(boardp)) {
5404 iounmap(boardp->ioremap_addr); 5404 iounmap(boardp->ioremap_addr);
5405 if (boardp->orig_carrp) { 5405 kfree(boardp->orig_carrp);
5406 kfree(boardp->orig_carrp); 5406 boardp->orig_carrp = NULL;
5407 boardp->orig_carrp = NULL;
5408 }
5409 if (boardp->orig_reqp) { 5407 if (boardp->orig_reqp) {
5410 kfree(boardp->orig_reqp); 5408 kfree(boardp->orig_reqp);
5411 boardp->orig_reqp = boardp->adv_reqp = NULL; 5409 boardp->orig_reqp = boardp->adv_reqp = NULL;
@@ -5457,10 +5455,8 @@ advansys_release(struct Scsi_Host *shp)
5457 adv_sgblk_t *sgp = NULL; 5455 adv_sgblk_t *sgp = NULL;
5458 5456
5459 iounmap(boardp->ioremap_addr); 5457 iounmap(boardp->ioremap_addr);
5460 if (boardp->orig_carrp) { 5458 kfree(boardp->orig_carrp);
5461 kfree(boardp->orig_carrp); 5459 boardp->orig_carrp = NULL;
5462 boardp->orig_carrp = NULL;
5463 }
5464 if (boardp->orig_reqp) { 5460 if (boardp->orig_reqp) {
5465 kfree(boardp->orig_reqp); 5461 kfree(boardp->orig_reqp);
5466 boardp->orig_reqp = boardp->adv_reqp = NULL; 5462 boardp->orig_reqp = boardp->adv_reqp = NULL;
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index adda750412f2..1b1adfb384cb 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -543,10 +543,8 @@ static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id, struct pt
543 return; 543 return;
544 } 544 }
545 my_done = SCtmp->scsi_done; 545 my_done = SCtmp->scsi_done;
546 if (SCtmp->host_scribble) { 546 kfree(SCtmp->host_scribble);
547 kfree(SCtmp->host_scribble); 547 SCtmp->host_scribble = NULL;
548 SCtmp->host_scribble = NULL;
549 }
550 /* Fetch the sense data, and tuck it away, in the required slot. The 548 /* Fetch the sense data, and tuck it away, in the required slot. The
551 Adaptec automatically fetches it, and there is no guarantee that 549 Adaptec automatically fetches it, and there is no guarantee that
552 we will still have it in the cdb when we come back */ 550 we will still have it in the cdb when we come back */
@@ -1432,10 +1430,8 @@ static int aha1542_dev_reset(Scsi_Cmnd * SCpnt)
1432 HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target) { 1430 HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target) {
1433 Scsi_Cmnd *SCtmp; 1431 Scsi_Cmnd *SCtmp;
1434 SCtmp = HOSTDATA(SCpnt->host)->SCint[i]; 1432 SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
1435 if (SCtmp->host_scribble) { 1433 kfree(SCtmp->host_scribble);
1436 kfree(SCtmp->host_scribble); 1434 SCtmp->host_scribble = NULL;
1437 SCtmp->host_scribble = NULL;
1438 }
1439 HOSTDATA(SCpnt->host)->SCint[i] = NULL; 1435 HOSTDATA(SCpnt->host)->SCint[i] = NULL;
1440 HOSTDATA(SCpnt->host)->mb[i].status = 0; 1436 HOSTDATA(SCpnt->host)->mb[i].status = 0;
1441 } 1437 }
@@ -1495,10 +1491,8 @@ static int aha1542_bus_reset(Scsi_Cmnd * SCpnt)
1495 */ 1491 */
1496 continue; 1492 continue;
1497 } 1493 }
1498 if (SCtmp->host_scribble) { 1494 kfree(SCtmp->host_scribble);
1499 kfree(SCtmp->host_scribble); 1495 SCtmp->host_scribble = NULL;
1500 SCtmp->host_scribble = NULL;
1501 }
1502 HOSTDATA(SCpnt->device->host)->SCint[i] = NULL; 1496 HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
1503 HOSTDATA(SCpnt->device->host)->mb[i].status = 0; 1497 HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
1504 } 1498 }
@@ -1565,10 +1559,8 @@ static int aha1542_host_reset(Scsi_Cmnd * SCpnt)
1565 */ 1559 */
1566 continue; 1560 continue;
1567 } 1561 }
1568 if (SCtmp->host_scribble) { 1562 kfree(SCtmp->host_scribble);
1569 kfree(SCtmp->host_scribble); 1563 SCtmp->host_scribble = NULL;
1570 SCtmp->host_scribble = NULL;
1571 }
1572 HOSTDATA(SCpnt->device->host)->SCint[i] = NULL; 1564 HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
1573 HOSTDATA(SCpnt->device->host)->mb[i].status = 0; 1565 HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
1574 } 1566 }
@@ -1711,10 +1703,8 @@ static int aha1542_old_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
1711 Scsi_Cmnd *SCtmp; 1703 Scsi_Cmnd *SCtmp;
1712 SCtmp = HOSTDATA(SCpnt->host)->SCint[i]; 1704 SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
1713 SCtmp->result = DID_RESET << 16; 1705 SCtmp->result = DID_RESET << 16;
1714 if (SCtmp->host_scribble) { 1706 kfree(SCtmp->host_scribble);
1715 kfree(SCtmp->host_scribble); 1707 SCtmp->host_scribble = NULL;
1716 SCtmp->host_scribble = NULL;
1717 }
1718 printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target); 1708 printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
1719 SCtmp->scsi_done(SCpnt); 1709 SCtmp->scsi_done(SCpnt);
1720 1710
@@ -1757,10 +1747,8 @@ fail:
1757 Scsi_Cmnd *SCtmp; 1747 Scsi_Cmnd *SCtmp;
1758 SCtmp = HOSTDATA(SCpnt->host)->SCint[i]; 1748 SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
1759 SCtmp->result = DID_RESET << 16; 1749 SCtmp->result = DID_RESET << 16;
1760 if (SCtmp->host_scribble) { 1750 kfree(SCtmp->host_scribble);
1761 kfree(SCtmp->host_scribble); 1751 SCtmp->host_scribble = NULL;
1762 SCtmp->host_scribble = NULL;
1763 }
1764 printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target); 1752 printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
1765 SCtmp->scsi_done(SCpnt); 1753 SCtmp->scsi_done(SCpnt);
1766 1754
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 4612312c0c2d..10c470e7d316 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -42,8 +42,8 @@
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/dma-mapping.h> 43#include <linux/dma-mapping.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
46#include <scsi/scsi_cmnd.h>
47#include <linux/libata.h> 47#include <linux/libata.h>
48#include <asm/io.h> 48#include <asm/io.h>
49 49
@@ -196,7 +196,7 @@ static u8 ahci_check_status(struct ata_port *ap);
196static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); 196static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
197static void ahci_remove_one (struct pci_dev *pdev); 197static void ahci_remove_one (struct pci_dev *pdev);
198 198
199static Scsi_Host_Template ahci_sht = { 199static struct scsi_host_template ahci_sht = {
200 .module = THIS_MODULE, 200 .module = THIS_MODULE,
201 .name = DRV_NAME, 201 .name = DRV_NAME,
202 .ioctl = ata_scsi_ioctl, 202 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 052c6619accc..bc44222d6cc3 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -49,7 +49,6 @@
49#include <linux/ioport.h> 49#include <linux/ioport.h>
50#include <linux/pci.h> 50#include <linux/pci.h>
51#include <linux/smp_lock.h> 51#include <linux/smp_lock.h>
52#include <linux/version.h>
53#include <linux/interrupt.h> 52#include <linux/interrupt.h>
54#include <linux/module.h> 53#include <linux/module.h>
55#include <linux/slab.h> 54#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index be9edbe26dbe..f2a95447142c 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -66,7 +66,6 @@
66#include <linux/ioport.h> 66#include <linux/ioport.h>
67#include <linux/pci.h> 67#include <linux/pci.h>
68#include <linux/smp_lock.h> 68#include <linux/smp_lock.h>
69#include <linux/version.h>
70#include <linux/interrupt.h> 69#include <linux/interrupt.h>
71#include <linux/module.h> 70#include <linux/module.h>
72#include <linux/slab.h> 71#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 52b72d7794f5..880e2d9ffe9b 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -8492,8 +8492,7 @@ aic7xxx_free(struct aic7xxx_host *p)
8492 - scb_dma->dma_offset), 8492 - scb_dma->dma_offset),
8493 scb_dma->dma_address); 8493 scb_dma->dma_address);
8494 } 8494 }
8495 if (p->scb_data->scb_array[i]->kmalloc_ptr != NULL) 8495 kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
8496 kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
8497 p->scb_data->scb_array[i] = NULL; 8496 p->scb_data->scb_array[i] = NULL;
8498 } 8497 }
8499 8498
diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
index 5f13546d6392..dea8446f5360 100644
--- a/drivers/scsi/amiga7xx.c
+++ b/drivers/scsi/amiga7xx.c
@@ -11,7 +11,6 @@
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/blkdev.h> 12#include <linux/blkdev.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/version.h>
15#include <linux/config.h> 14#include <linux/config.h>
16#include <linux/zorro.h> 15#include <linux/zorro.h>
17#include <linux/stat.h> 16#include <linux/stat.h>
diff --git a/drivers/scsi/arm/queue.c b/drivers/scsi/arm/queue.c
index e6d159270d29..b10750bb5c09 100644
--- a/drivers/scsi/arm/queue.c
+++ b/drivers/scsi/arm/queue.c
@@ -91,8 +91,7 @@ void queue_free (Queue_t *queue)
91{ 91{
92 if (!list_empty(&queue->head)) 92 if (!list_empty(&queue->head))
93 printk(KERN_WARNING "freeing non-empty queue %p\n", queue); 93 printk(KERN_WARNING "freeing non-empty queue %p\n", queue);
94 if (queue->alloc) 94 kfree(queue->alloc);
95 kfree(queue->alloc);
96} 95}
97 96
98 97
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 7f8aa1b552ce..a1bd8d95623c 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -46,7 +46,6 @@
46#include <linux/blkdev.h> 46#include <linux/blkdev.h>
47#include <linux/delay.h> 47#include <linux/delay.h>
48#include <linux/device.h> 48#include <linux/device.h>
49#include "scsi.h"
50#include <scsi/scsi_host.h> 49#include <scsi/scsi_host.h>
51#include <linux/libata.h> 50#include <linux/libata.h>
52 51
@@ -128,7 +127,7 @@ static struct pci_driver piix_pci_driver = {
128 .remove = ata_pci_remove_one, 127 .remove = ata_pci_remove_one,
129}; 128};
130 129
131static Scsi_Host_Template piix_sht = { 130static struct scsi_host_template piix_sht = {
132 .module = THIS_MODULE, 131 .module = THIS_MODULE,
133 .name = DRV_NAME, 132 .name = DRV_NAME,
134 .ioctl = ata_scsi_ioctl, 133 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/atari_dma_emul.c b/drivers/scsi/atari_dma_emul.c
index 7026045527fd..8d5d2a5da961 100644
--- a/drivers/scsi/atari_dma_emul.c
+++ b/drivers/scsi/atari_dma_emul.c
@@ -19,6 +19,8 @@
19 * this code. 19 * this code.
20 */ 20 */
21 21
22#include <linux/compiler.h>
23#include <asm/thread_info.h>
22#include <asm/uaccess.h> 24#include <asm/uaccess.h>
23 25
24#define hades_dma_ctrl (*(unsigned char *) 0xffff8717) 26#define hades_dma_ctrl (*(unsigned char *) 0xffff8717)
diff --git a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
index 29c7ed30c09e..130f30f51a9b 100644
--- a/drivers/scsi/bvme6000.c
+++ b/drivers/scsi/bvme6000.c
@@ -7,7 +7,6 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/version.h>
11#include <linux/zorro.h> 10#include <linux/zorro.h>
12 11
13#include <asm/setup.h> 12#include <asm/setup.h>
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index c44af5795b10..c8a32cf47d73 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -4270,8 +4270,7 @@ static void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
4270 const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN; 4270 const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
4271 4271
4272 for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page) 4272 for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
4273 if (acb->srb_array[i].segment_x) 4273 kfree(acb->srb_array[i].segment_x);
4274 kfree(acb->srb_array[i].segment_x);
4275} 4274}
4276 4275
4277 4276
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 7235f94f1191..c28e3aea1c3c 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -1037,18 +1037,10 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
1037 if(pHba->msg_addr_virt != pHba->base_addr_virt){ 1037 if(pHba->msg_addr_virt != pHba->base_addr_virt){
1038 iounmap(pHba->msg_addr_virt); 1038 iounmap(pHba->msg_addr_virt);
1039 } 1039 }
1040 if(pHba->hrt) { 1040 kfree(pHba->hrt);
1041 kfree(pHba->hrt); 1041 kfree(pHba->lct);
1042 } 1042 kfree(pHba->status_block);
1043 if(pHba->lct){ 1043 kfree(pHba->reply_pool);
1044 kfree(pHba->lct);
1045 }
1046 if(pHba->status_block) {
1047 kfree(pHba->status_block);
1048 }
1049 if(pHba->reply_pool){
1050 kfree(pHba->reply_pool);
1051 }
1052 1044
1053 for(d = pHba->devices; d ; d = next){ 1045 for(d = pHba->devices; d ; d = next){
1054 next = d->next; 1046 next = d->next;
@@ -1218,8 +1210,7 @@ static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
1218 printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit); 1210 printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
1219 return -ETIMEDOUT; 1211 return -ETIMEDOUT;
1220 } 1212 }
1221 set_current_state(TASK_UNINTERRUPTIBLE); 1213 schedule_timeout_uninterruptible(1);
1222 schedule_timeout(1);
1223 } while(m == EMPTY_QUEUE); 1214 } while(m == EMPTY_QUEUE);
1224 1215
1225 msg = pHba->msg_addr_virt + m; 1216 msg = pHba->msg_addr_virt + m;
@@ -1294,8 +1285,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
1294 printk(KERN_WARNING"Timeout waiting for message!\n"); 1285 printk(KERN_WARNING"Timeout waiting for message!\n");
1295 return -ETIMEDOUT; 1286 return -ETIMEDOUT;
1296 } 1287 }
1297 set_current_state(TASK_UNINTERRUPTIBLE); 1288 schedule_timeout_uninterruptible(1);
1298 schedule_timeout(1);
1299 } while (m == EMPTY_QUEUE); 1289 } while (m == EMPTY_QUEUE);
1300 1290
1301 status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32); 1291 status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
@@ -1327,8 +1317,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
1327 return -ETIMEDOUT; 1317 return -ETIMEDOUT;
1328 } 1318 }
1329 rmb(); 1319 rmb();
1330 set_current_state(TASK_UNINTERRUPTIBLE); 1320 schedule_timeout_uninterruptible(1);
1331 schedule_timeout(1);
1332 } 1321 }
1333 1322
1334 if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) { 1323 if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
@@ -1345,8 +1334,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
1345 printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name); 1334 printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
1346 return -ETIMEDOUT; 1335 return -ETIMEDOUT;
1347 } 1336 }
1348 set_current_state(TASK_UNINTERRUPTIBLE); 1337 schedule_timeout_uninterruptible(1);
1349 schedule_timeout(1);
1350 } while (m == EMPTY_QUEUE); 1338 } while (m == EMPTY_QUEUE);
1351 // Flush the offset 1339 // Flush the offset
1352 adpt_send_nop(pHba, m); 1340 adpt_send_nop(pHba, m);
@@ -1917,11 +1905,8 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
1917 return -ENXIO; 1905 return -ENXIO;
1918 } 1906 }
1919 1907
1920 while((volatile u32) pHba->state & DPTI_STATE_RESET ) { 1908 while((volatile u32) pHba->state & DPTI_STATE_RESET )
1921 set_task_state(current,TASK_UNINTERRUPTIBLE); 1909 schedule_timeout_uninterruptible(2);
1922 schedule_timeout(2);
1923
1924 }
1925 1910
1926 switch (cmd) { 1911 switch (cmd) {
1927 // TODO: handle 3 cases 1912 // TODO: handle 3 cases
@@ -2635,8 +2620,7 @@ static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
2635 printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name); 2620 printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
2636 return 2; 2621 return 2;
2637 } 2622 }
2638 set_current_state(TASK_UNINTERRUPTIBLE); 2623 schedule_timeout_uninterruptible(1);
2639 schedule_timeout(1);
2640 } 2624 }
2641 msg = (u32 __iomem *)(pHba->msg_addr_virt + m); 2625 msg = (u32 __iomem *)(pHba->msg_addr_virt + m);
2642 writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]); 2626 writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
@@ -2670,8 +2654,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
2670 printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name); 2654 printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
2671 return -ETIMEDOUT; 2655 return -ETIMEDOUT;
2672 } 2656 }
2673 set_current_state(TASK_UNINTERRUPTIBLE); 2657 schedule_timeout_uninterruptible(1);
2674 schedule_timeout(1);
2675 } while(m == EMPTY_QUEUE); 2658 } while(m == EMPTY_QUEUE);
2676 2659
2677 msg=(u32 __iomem *)(pHba->msg_addr_virt+m); 2660 msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
@@ -2709,21 +2692,18 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
2709 printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name); 2692 printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
2710 return -ETIMEDOUT; 2693 return -ETIMEDOUT;
2711 } 2694 }
2712 set_current_state(TASK_UNINTERRUPTIBLE); 2695 schedule_timeout_uninterruptible(1);
2713 schedule_timeout(1);
2714 } while (1); 2696 } while (1);
2715 2697
2716 // If the command was successful, fill the fifo with our reply 2698 // If the command was successful, fill the fifo with our reply
2717 // message packets 2699 // message packets
2718 if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) { 2700 if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
2719 kfree((void*)status); 2701 kfree(status);
2720 return -2; 2702 return -2;
2721 } 2703 }
2722 kfree((void*)status); 2704 kfree(status);
2723 2705
2724 if(pHba->reply_pool != NULL){ 2706 kfree(pHba->reply_pool);
2725 kfree(pHba->reply_pool);
2726 }
2727 2707
2728 pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32); 2708 pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
2729 if(!pHba->reply_pool){ 2709 if(!pHba->reply_pool){
@@ -2788,8 +2768,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
2788 pHba->name); 2768 pHba->name);
2789 return -ETIMEDOUT; 2769 return -ETIMEDOUT;
2790 } 2770 }
2791 set_current_state(TASK_UNINTERRUPTIBLE); 2771 schedule_timeout_uninterruptible(1);
2792 schedule_timeout(1);
2793 } while(m==EMPTY_QUEUE); 2772 } while(m==EMPTY_QUEUE);
2794 2773
2795 2774
@@ -2816,8 +2795,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
2816 return -ETIMEDOUT; 2795 return -ETIMEDOUT;
2817 } 2796 }
2818 rmb(); 2797 rmb();
2819 set_current_state(TASK_UNINTERRUPTIBLE); 2798 schedule_timeout_uninterruptible(1);
2820 schedule_timeout(1);
2821 } 2799 }
2822 2800
2823 // Set up our number of outbound and inbound messages 2801 // Set up our number of outbound and inbound messages
@@ -2941,8 +2919,7 @@ static int adpt_i2o_build_sys_table(void)
2941 sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs 2919 sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs
2942 (hba_count) * sizeof(struct i2o_sys_tbl_entry); 2920 (hba_count) * sizeof(struct i2o_sys_tbl_entry);
2943 2921
2944 if(sys_tbl) 2922 kfree(sys_tbl);
2945 kfree(sys_tbl);
2946 2923
2947 sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32); 2924 sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
2948 if(!sys_tbl) { 2925 if(!sys_tbl) {
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index b45a4c730230..b3f9de8f7595 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -2580,8 +2580,7 @@ static int eata2x_release(struct Scsi_Host *shost)
2580 unsigned int i; 2580 unsigned int i;
2581 2581
2582 for (i = 0; i < shost->can_queue; i++) 2582 for (i = 0; i < shost->can_queue; i++)
2583 if ((&ha->cp[i])->sglist) 2583 kfree((&ha->cp[i])->sglist);
2584 kfree((&ha->cp[i])->sglist);
2585 2584
2586 for (i = 0; i < shost->can_queue; i++) 2585 for (i = 0; i < shost->can_queue; i++)
2587 pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr, 2586 pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr,
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c
index d12342fa8199..ab22387c9df1 100644
--- a/drivers/scsi/gvp11.c
+++ b/drivers/scsi/gvp11.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/init.h> 5#include <linux/init.h>
7#include <linux/interrupt.h> 6#include <linux/interrupt.h>
8 7
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 887a5c3ded28..8d97999db60e 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -18,12 +18,6 @@
18 */ 18 */
19 19
20#include <linux/config.h> 20#include <linux/config.h>
21#ifndef LINUX_VERSION_CODE
22#include <linux/version.h>
23#endif
24#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
25#error "This driver works only with kernel 2.5.45 or higher!"
26#endif
27#include <linux/module.h> 21#include <linux/module.h>
28#include <linux/kernel.h> 22#include <linux/kernel.h>
29#include <linux/types.h> 23#include <linux/types.h>
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index f04f3289938d..3553da0e1cd5 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -331,9 +331,9 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co
331 rq = kmalloc (sizeof (struct request), GFP_ATOMIC); 331 rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
332 buf = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC); 332 buf = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);
333 if (pc == NULL || rq == NULL || buf == NULL) { 333 if (pc == NULL || rq == NULL || buf == NULL) {
334 if (pc) kfree(pc); 334 kfree(buf);
335 if (rq) kfree(rq); 335 kfree(rq);
336 if (buf) kfree(buf); 336 kfree(pc);
337 return -ENOMEM; 337 return -ENOMEM;
338 } 338 }
339 memset (pc, 0, sizeof (idescsi_pc_t)); 339 memset (pc, 0, sizeof (idescsi_pc_t));
@@ -395,6 +395,7 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
395 int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); 395 int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
396 struct Scsi_Host *host; 396 struct Scsi_Host *host;
397 u8 *scsi_buf; 397 u8 *scsi_buf;
398 int errors = rq->errors;
398 unsigned long flags; 399 unsigned long flags;
399 400
400 if (!(rq->flags & (REQ_SPECIAL|REQ_SENSE))) { 401 if (!(rq->flags & (REQ_SPECIAL|REQ_SENSE))) {
@@ -421,11 +422,11 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs)
421 printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n", 422 printk (KERN_WARNING "ide-scsi: %s: timed out for %lu\n",
422 drive->name, pc->scsi_cmd->serial_number); 423 drive->name, pc->scsi_cmd->serial_number);
423 pc->scsi_cmd->result = DID_TIME_OUT << 16; 424 pc->scsi_cmd->result = DID_TIME_OUT << 16;
424 } else if (rq->errors >= ERROR_MAX) { 425 } else if (errors >= ERROR_MAX) {
425 pc->scsi_cmd->result = DID_ERROR << 16; 426 pc->scsi_cmd->result = DID_ERROR << 16;
426 if (log) 427 if (log)
427 printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number); 428 printk ("ide-scsi: %s: I/O error for %lu\n", drive->name, pc->scsi_cmd->serial_number);
428 } else if (rq->errors) { 429 } else if (errors) {
429 if (log) 430 if (log)
430 printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number); 431 printk ("ide-scsi: %s: check condition for %lu\n", drive->name, pc->scsi_cmd->serial_number);
431 if (!idescsi_check_condition(drive, rq)) 432 if (!idescsi_check_condition(drive, rq))
@@ -949,8 +950,8 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
949 spin_lock_irq(host->host_lock); 950 spin_lock_irq(host->host_lock);
950 return 0; 951 return 0;
951abort: 952abort:
952 if (pc) kfree (pc); 953 kfree (pc);
953 if (rq) kfree (rq); 954 kfree (rq);
954 cmd->result = DID_ERROR << 16; 955 cmd->result = DID_ERROR << 16;
955 done(cmd); 956 done(cmd);
956 return 0; 957 return 0;
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 68e5b2ab27c4..cd9b95db5a7d 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -4517,10 +4517,8 @@ ips_free(ips_ha_t * ha)
4517 ha->enq = NULL; 4517 ha->enq = NULL;
4518 } 4518 }
4519 4519
4520 if (ha->conf) { 4520 kfree(ha->conf);
4521 kfree(ha->conf); 4521 ha->conf = NULL;
4522 ha->conf = NULL;
4523 }
4524 4522
4525 if (ha->adapt) { 4523 if (ha->adapt) {
4526 pci_free_consistent(ha->pcidev, 4524 pci_free_consistent(ha->pcidev,
@@ -4538,15 +4536,11 @@ ips_free(ips_ha_t * ha)
4538 ha->logical_drive_info = NULL; 4536 ha->logical_drive_info = NULL;
4539 } 4537 }
4540 4538
4541 if (ha->nvram) { 4539 kfree(ha->nvram);
4542 kfree(ha->nvram); 4540 ha->nvram = NULL;
4543 ha->nvram = NULL;
4544 }
4545 4541
4546 if (ha->subsys) { 4542 kfree(ha->subsys);
4547 kfree(ha->subsys); 4543 ha->subsys = NULL;
4548 ha->subsys = NULL;
4549 }
4550 4544
4551 if (ha->ioctl_data) { 4545 if (ha->ioctl_data) {
4552 pci_free_consistent(ha->pcidev, ha->ioctl_len, 4546 pci_free_consistent(ha->pcidev, ha->ioctl_len,
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index 505e967013de..adc6eabbf610 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -50,6 +50,7 @@
50#ifndef _IPS_H_ 50#ifndef _IPS_H_
51 #define _IPS_H_ 51 #define _IPS_H_
52 52
53#include <linux/version.h>
53 #include <asm/uaccess.h> 54 #include <asm/uaccess.h>
54 #include <asm/io.h> 55 #include <asm/io.h>
55 56
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 1c1a7caf785e..a74b4071a662 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -51,8 +51,8 @@
51#include <linux/jiffies.h> 51#include <linux/jiffies.h>
52#include <linux/scatterlist.h> 52#include <linux/scatterlist.h>
53#include <scsi/scsi.h> 53#include <scsi/scsi.h>
54#include "scsi.h"
55#include "scsi_priv.h" 54#include "scsi_priv.h"
55#include <scsi/scsi_cmnd.h>
56#include <scsi/scsi_host.h> 56#include <scsi/scsi_host.h>
57#include <linux/libata.h> 57#include <linux/libata.h>
58#include <asm/io.h> 58#include <asm/io.h>
@@ -1144,7 +1144,7 @@ retry:
1144 * ATA software reset (SRST, the default) does not appear 1144 * ATA software reset (SRST, the default) does not appear
1145 * to have this problem. 1145 * to have this problem.
1146 */ 1146 */
1147 if ((using_edd) && (qc->tf.command == ATA_CMD_ID_ATA)) { 1147 if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
1148 u8 err = qc->tf.feature; 1148 u8 err = qc->tf.feature;
1149 if (err & ATA_ABORTED) { 1149 if (err & ATA_ABORTED) {
1150 dev->class = ATA_DEV_ATAPI; 1150 dev->class = ATA_DEV_ATAPI;
@@ -2713,7 +2713,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
2713/** 2713/**
2714 * ata_poll_qc_complete - turn irq back on and finish qc 2714 * ata_poll_qc_complete - turn irq back on and finish qc
2715 * @qc: Command to complete 2715 * @qc: Command to complete
2716 * @drv_stat: ATA status register content 2716 * @err_mask: ATA status register content
2717 * 2717 *
2718 * LOCKING: 2718 * LOCKING:
2719 * None. (grabs host lock) 2719 * None. (grabs host lock)
@@ -2747,7 +2747,6 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
2747 u8 status; 2747 u8 status;
2748 unsigned int poll_state = HSM_ST_UNKNOWN; 2748 unsigned int poll_state = HSM_ST_UNKNOWN;
2749 unsigned int reg_state = HSM_ST_UNKNOWN; 2749 unsigned int reg_state = HSM_ST_UNKNOWN;
2750 const unsigned int tmout_state = HSM_ST_TMOUT;
2751 2750
2752 switch (ap->hsm_task_state) { 2751 switch (ap->hsm_task_state) {
2753 case HSM_ST: 2752 case HSM_ST:
@@ -2768,7 +2767,7 @@ static unsigned long ata_pio_poll(struct ata_port *ap)
2768 status = ata_chk_status(ap); 2767 status = ata_chk_status(ap);
2769 if (status & ATA_BUSY) { 2768 if (status & ATA_BUSY) {
2770 if (time_after(jiffies, ap->pio_task_timeout)) { 2769 if (time_after(jiffies, ap->pio_task_timeout)) {
2771 ap->hsm_task_state = tmout_state; 2770 ap->hsm_task_state = HSM_ST_TMOUT;
2772 return 0; 2771 return 0;
2773 } 2772 }
2774 ap->hsm_task_state = poll_state; 2773 ap->hsm_task_state = poll_state;
@@ -3478,7 +3477,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
3478/** 3477/**
3479 * ata_qc_complete - Complete an active ATA command 3478 * ata_qc_complete - Complete an active ATA command
3480 * @qc: Command to complete 3479 * @qc: Command to complete
3481 * @drv_stat: ATA Status register contents 3480 * @err_mask: ATA Status register contents
3482 * 3481 *
3483 * Indicate to the mid and upper layers that an ATA 3482 * Indicate to the mid and upper layers that an ATA
3484 * command has completed, with either an ok or not-ok status. 3483 * command has completed, with either an ok or not-ok status.
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index eb604b0a8990..bb30fcdc9297 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -37,9 +37,9 @@
37#include <linux/blkdev.h> 37#include <linux/blkdev.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <scsi/scsi.h> 39#include <scsi/scsi.h>
40#include "scsi.h"
41#include <scsi/scsi_host.h> 40#include <scsi/scsi_host.h>
42#include <scsi/scsi_device.h> 41#include <scsi/scsi_device.h>
42#include <scsi/scsi_request.h>
43#include <linux/libata.h> 43#include <linux/libata.h>
44#include <linux/hdreg.h> 44#include <linux/hdreg.h>
45#include <asm/uaccess.h> 45#include <asm/uaccess.h>
@@ -131,7 +131,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
131 131
132/** 132/**
133 * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl 133 * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
134 * @dev: Device to whom we are issuing command 134 * @scsidev: Device to which we are issuing command
135 * @arg: User provided data for issuing command 135 * @arg: User provided data for issuing command
136 * 136 *
137 * LOCKING: 137 * LOCKING:
@@ -217,7 +217,7 @@ error:
217 217
218/** 218/**
219 * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl 219 * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl
220 * @dev: Device to whom we are issuing command 220 * @scsidev: Device to which we are issuing command
221 * @arg: User provided data for issuing command 221 * @arg: User provided data for issuing command
222 * 222 *
223 * LOCKING: 223 * LOCKING:
@@ -416,6 +416,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf)
416 416
417/** 417/**
418 * ata_to_sense_error - convert ATA error to SCSI error 418 * ata_to_sense_error - convert ATA error to SCSI error
419 * @id: ATA device number
419 * @drv_stat: value contained in ATA status register 420 * @drv_stat: value contained in ATA status register
420 * @drv_err: value contained in ATA error register 421 * @drv_err: value contained in ATA error register
421 * @sk: the sense key we'll fill out 422 * @sk: the sense key we'll fill out
@@ -2231,7 +2232,7 @@ ata_scsi_map_proto(u8 byte1)
2231/** 2232/**
2232 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile 2233 * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
2233 * @qc: command structure to be initialized 2234 * @qc: command structure to be initialized
2234 * @cmd: SCSI command to convert 2235 * @scsicmd: SCSI command to convert
2235 * 2236 *
2236 * Handles either 12 or 16-byte versions of the CDB. 2237 * Handles either 12 or 16-byte versions of the CDB.
2237 * 2238 *
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 08a0c00cfc30..bcc29ec126dc 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -127,8 +127,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
127 if (((pcmd = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) || 127 if (((pcmd = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
128 ((pcmd->virt = lpfc_mbuf_alloc(phba, 128 ((pcmd->virt = lpfc_mbuf_alloc(phba,
129 MEM_PRI, &(pcmd->phys))) == 0)) { 129 MEM_PRI, &(pcmd->phys))) == 0)) {
130 if (pcmd) 130 kfree(pcmd);
131 kfree(pcmd);
132 131
133 spin_lock_irq(phba->host->host_lock); 132 spin_lock_irq(phba->host->host_lock);
134 lpfc_sli_release_iocbq(phba, elsiocb); 133 lpfc_sli_release_iocbq(phba, elsiocb);
@@ -145,8 +144,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
145 prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, 144 prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
146 &prsp->phys); 145 &prsp->phys);
147 if (prsp == 0 || prsp->virt == 0) { 146 if (prsp == 0 || prsp->virt == 0) {
148 if (prsp) 147 kfree(prsp);
149 kfree(prsp);
150 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys); 148 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
151 kfree(pcmd); 149 kfree(pcmd);
152 spin_lock_irq(phba->host->host_lock); 150 spin_lock_irq(phba->host->host_lock);
@@ -172,8 +170,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
172 lpfc_mbuf_free(phba, prsp->virt, prsp->phys); 170 lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
173 kfree(pcmd); 171 kfree(pcmd);
174 kfree(prsp); 172 kfree(prsp);
175 if (pbuflist) 173 kfree(pbuflist);
176 kfree(pbuflist);
177 return NULL; 174 return NULL;
178 } 175 }
179 176
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 4e04470321a2..07498118359d 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -894,8 +894,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
894 mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI, 894 mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
895 &mp1->phys); 895 &mp1->phys);
896 if (mp1 == 0 || mp1->virt == 0) { 896 if (mp1 == 0 || mp1->virt == 0) {
897 if (mp1) 897 kfree(mp1);
898 kfree(mp1);
899 spin_lock_irq(phba->host->host_lock); 898 spin_lock_irq(phba->host->host_lock);
900 lpfc_sli_release_iocbq(phba, iocb); 899 lpfc_sli_release_iocbq(phba, iocb);
901 spin_unlock_irq(phba->host->host_lock); 900 spin_unlock_irq(phba->host->host_lock);
@@ -911,8 +910,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
911 mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI, 910 mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
912 &mp2->phys); 911 &mp2->phys);
913 if (mp2 == 0 || mp2->virt == 0) { 912 if (mp2 == 0 || mp2->virt == 0) {
914 if (mp2) 913 kfree(mp2);
915 kfree(mp2);
916 lpfc_mbuf_free(phba, mp1->virt, mp1->phys); 914 lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
917 kfree(mp1); 915 kfree(mp1);
918 spin_lock_irq(phba->host->host_lock); 916 spin_lock_irq(phba->host->host_lock);
@@ -1706,7 +1704,6 @@ MODULE_DEVICE_TABLE(pci, lpfc_id_table);
1706 1704
1707static struct pci_driver lpfc_driver = { 1705static struct pci_driver lpfc_driver = {
1708 .name = LPFC_DRIVER_NAME, 1706 .name = LPFC_DRIVER_NAME,
1709 .owner = THIS_MODULE,
1710 .id_table = lpfc_id_table, 1707 .id_table = lpfc_id_table,
1711 .probe = lpfc_pci_probe_one, 1708 .probe = lpfc_pci_probe_one,
1712 .remove = __devexit_p(lpfc_pci_remove_one), 1709 .remove = __devexit_p(lpfc_pci_remove_one),
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 31c20cc00609..e3bc8d3f7302 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -248,8 +248,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
248 248
249 if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) || 249 if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
250 ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) { 250 ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
251 if (mp) 251 kfree(mp);
252 kfree(mp);
253 mb->mbxCommand = MBX_READ_SPARM64; 252 mb->mbxCommand = MBX_READ_SPARM64;
254 /* READ_SPARAM: no buffers */ 253 /* READ_SPARAM: no buffers */
255 lpfc_printf_log(phba, 254 lpfc_printf_log(phba,
@@ -363,9 +362,7 @@ lpfc_reg_login(struct lpfc_hba * phba,
363 /* Get a buffer to hold NPorts Service Parameters */ 362 /* Get a buffer to hold NPorts Service Parameters */
364 if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == NULL) || 363 if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == NULL) ||
365 ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) { 364 ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
366 if (mp) 365 kfree(mp);
367 kfree(mp);
368
369 mb->mbxCommand = MBX_REG_LOGIN64; 366 mb->mbxCommand = MBX_REG_LOGIN64;
370 /* REG_LOGIN: no buffers */ 367 /* REG_LOGIN: no buffers */
371 lpfc_printf_log(phba, 368 lpfc_printf_log(phba,
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c34d3cf4f19c..c63275e66e2e 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -825,8 +825,7 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
825 while (lpfc_cmd->pCmd == cmnd) 825 while (lpfc_cmd->pCmd == cmnd)
826 { 826 {
827 spin_unlock_irq(phba->host->host_lock); 827 spin_unlock_irq(phba->host->host_lock);
828 set_current_state(TASK_UNINTERRUPTIBLE); 828 schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ);
829 schedule_timeout(LPFC_ABORT_WAIT*HZ);
830 spin_lock_irq(phba->host->host_lock); 829 spin_lock_irq(phba->host->host_lock);
831 if (++loop_count 830 if (++loop_count
832 > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT) 831 > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT)
@@ -885,8 +884,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
885 884
886 if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { 885 if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
887 spin_unlock_irq(phba->host->host_lock); 886 spin_unlock_irq(phba->host->host_lock);
888 set_current_state(TASK_UNINTERRUPTIBLE); 887 schedule_timeout_uninterruptible(msecs_to_jiffies(500));
889 schedule_timeout( HZ/2);
890 spin_lock_irq(phba->host->host_lock); 888 spin_lock_irq(phba->host->host_lock);
891 } 889 }
892 if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE)) 890 if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE))
@@ -939,8 +937,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
939 cmnd->device->id, cmnd->device->lun, 937 cmnd->device->id, cmnd->device->lun,
940 LPFC_CTX_LUN))) { 938 LPFC_CTX_LUN))) {
941 spin_unlock_irq(phba->host->host_lock); 939 spin_unlock_irq(phba->host->host_lock);
942 set_current_state(TASK_UNINTERRUPTIBLE); 940 schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
943 schedule_timeout(LPFC_RESET_WAIT*HZ);
944 spin_lock_irq(phba->host->host_lock); 941 spin_lock_irq(phba->host->host_lock);
945 942
946 if (++loopcnt 943 if (++loopcnt
@@ -1038,8 +1035,7 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
1038 &phba->sli.ring[phba->sli.fcp_ring], 1035 &phba->sli.ring[phba->sli.fcp_ring],
1039 0, 0, LPFC_CTX_HOST))) { 1036 0, 0, LPFC_CTX_HOST))) {
1040 spin_unlock_irq(phba->host->host_lock); 1037 spin_unlock_irq(phba->host->host_lock);
1041 set_current_state(TASK_UNINTERRUPTIBLE); 1038 schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
1042 schedule_timeout(LPFC_RESET_WAIT*HZ);
1043 spin_lock_irq(phba->host->host_lock); 1039 spin_lock_irq(phba->host->host_lock);
1044 1040
1045 if (++loopcnt 1041 if (++loopcnt
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 508710001ed6..e2c08c5d83fb 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -2269,11 +2269,8 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
2269 2269
2270 INIT_LIST_HEAD(&(pring->txq)); 2270 INIT_LIST_HEAD(&(pring->txq));
2271 2271
2272 if (pring->fast_lookup) { 2272 kfree(pring->fast_lookup);
2273 kfree(pring->fast_lookup); 2273 pring->fast_lookup = NULL;
2274 pring->fast_lookup = NULL;
2275 }
2276
2277 } 2274 }
2278 2275
2279 spin_unlock_irqrestore(phba->host->host_lock, flags); 2276 spin_unlock_irqrestore(phba->host->host_lock, flags);
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
index 69df1a9b935d..8e547130e97d 100644
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -25,7 +25,6 @@
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/blkdev.h> 26#include <linux/blkdev.h>
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/version.h>
29#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
30#include <linux/dma-mapping.h> 29#include <linux/dma-mapping.h>
31#include <asm/semaphore.h> 30#include <asm/semaphore.h>
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index c9e743ba09ec..1a3d195a2d36 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -3937,9 +3937,8 @@ megaraid_sysfs_free_resources(adapter_t *adapter)
3937{ 3937{
3938 mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); 3938 mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter);
3939 3939
3940 if (raid_dev->sysfs_uioc) kfree(raid_dev->sysfs_uioc); 3940 kfree(raid_dev->sysfs_uioc);
3941 3941 kfree(raid_dev->sysfs_mbox64);
3942 if (raid_dev->sysfs_mbox64) kfree(raid_dev->sysfs_mbox64);
3943 3942
3944 if (raid_dev->sysfs_buffer) { 3943 if (raid_dev->sysfs_buffer) {
3945 pci_free_consistent(adapter->pdev, PAGE_SIZE, 3944 pci_free_consistent(adapter->pdev, PAGE_SIZE,
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
index 37d110e864c4..8f3ce0432295 100644
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -995,17 +995,13 @@ pthru_dma_pool_error:
995 995
996memalloc_error: 996memalloc_error:
997 997
998 if (adapter->kioc_list) 998 kfree(adapter->kioc_list);
999 kfree(adapter->kioc_list); 999 kfree(adapter->mbox_list);
1000
1001 if (adapter->mbox_list)
1002 kfree(adapter->mbox_list);
1003 1000
1004 if (adapter->pthru_dma_pool) 1001 if (adapter->pthru_dma_pool)
1005 pci_pool_destroy(adapter->pthru_dma_pool); 1002 pci_pool_destroy(adapter->pthru_dma_pool);
1006 1003
1007 if (adapter) 1004 kfree(adapter);
1008 kfree(adapter);
1009 1005
1010 return rval; 1006 return rval;
1011} 1007}
@@ -1157,7 +1153,6 @@ mraid_mm_free_adp_resources(mraid_mmadp_t *adp)
1157 } 1153 }
1158 1154
1159 kfree(adp->kioc_list); 1155 kfree(adp->kioc_list);
1160
1161 kfree(adp->mbox_list); 1156 kfree(adp->mbox_list);
1162 1157
1163 pci_pool_destroy(adp->pthru_dma_pool); 1158 pci_pool_destroy(adp->pthru_dma_pool);
diff --git a/drivers/scsi/megaraid/megaraid_mm.h b/drivers/scsi/megaraid/megaraid_mm.h
index 7e36c46e7c43..eb8c390a0fa3 100644
--- a/drivers/scsi/megaraid/megaraid_mm.h
+++ b/drivers/scsi/megaraid/megaraid_mm.h
@@ -18,7 +18,6 @@
18#include <linux/spinlock.h> 18#include <linux/spinlock.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include <linux/version.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/moduleparam.h> 22#include <linux/moduleparam.h>
24#include <linux/pci.h> 23#include <linux/pci.h>
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 4245d05e628b..801a63bea8a5 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/version.h>
30#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
31#include <linux/module.h> 30#include <linux/module.h>
32#include <linux/spinlock.h> 31#include <linux/spinlock.h>
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
index 2fb31ee6d9f5..33380cee9b77 100644
--- a/drivers/scsi/mvme147.c
+++ b/drivers/scsi/mvme147.c
@@ -2,7 +2,6 @@
2#include <linux/mm.h> 2#include <linux/mm.h>
3#include <linux/blkdev.h> 3#include <linux/blkdev.h>
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/version.h>
6#include <linux/interrupt.h> 5#include <linux/interrupt.h>
7 6
8#include <asm/page.h> 7#include <asm/page.h>
diff --git a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
index b2d8d8ea1604..29ec699e0e4d 100644
--- a/drivers/scsi/mvme16x.c
+++ b/drivers/scsi/mvme16x.c
@@ -7,7 +7,6 @@
7#include <linux/mm.h> 7#include <linux/mm.h>
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/version.h>
11 10
12#include <asm/page.h> 11#include <asm/page.h>
13#include <asm/pgtable.h> 12#include <asm/pgtable.h>
diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h
index 5664398fa0ad..5addf9fb1e15 100644
--- a/drivers/scsi/nsp32.h
+++ b/drivers/scsi/nsp32.h
@@ -16,6 +16,7 @@
16#ifndef _NSP32_H 16#ifndef _NSP32_H
17#define _NSP32_H 17#define _NSP32_H
18 18
19#include <linux/version.h>
19//#define NSP32_DEBUG 9 20//#define NSP32_DEBUG 9
20 21
21/* 22/*
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 1cf11c3322fb..d9946bd95492 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -862,8 +862,7 @@ static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request *
862 retval = osst_write_error_recovery(STp, aSRpnt, 0); 862 retval = osst_write_error_recovery(STp, aSRpnt, 0);
863 break; 863 break;
864 } 864 }
865 set_current_state(TASK_INTERRUPTIBLE); 865 schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
866 schedule_timeout (HZ / OSST_POLL_PER_SEC);
867 866
868 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; 867 STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
869 memset(cmd, 0, MAX_COMMAND_SIZE); 868 memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -1558,8 +1557,7 @@ static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request
1558 osst_set_frame_position(STp, aSRpnt, frame + skip, 1); 1557 osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
1559 flag = 0; 1558 flag = 0;
1560 attempts--; 1559 attempts--;
1561 set_current_state(TASK_INTERRUPTIBLE); 1560 schedule_timeout_interruptible(msecs_to_jiffies(100));
1562 schedule_timeout(HZ / 10);
1563 } 1561 }
1564 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */ 1562 if (osst_get_frame_position(STp, aSRpnt) < 0) { /* additional write error */
1565#if DEBUG 1563#if DEBUG
@@ -1620,8 +1618,7 @@ static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request
1620 debugging = 0; 1618 debugging = 0;
1621 } 1619 }
1622#endif 1620#endif
1623 set_current_state(TASK_INTERRUPTIBLE); 1621 schedule_timeout_interruptible(msecs_to_jiffies(100));
1624 schedule_timeout(HZ / 10);
1625 } 1622 }
1626 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name); 1623 printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
1627#if DEBUG 1624#if DEBUG
diff --git a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h
index c65afc964121..6c962d7dca47 100644
--- a/drivers/scsi/pci2000.h
+++ b/drivers/scsi/pci2000.h
@@ -26,9 +26,6 @@
26#ifndef PSI_EIDE_SCSIOP 26#ifndef PSI_EIDE_SCSIOP
27#define PSI_EIDE_SCSIOP 1 27#define PSI_EIDE_SCSIOP 1
28 28
29#ifndef LINUX_VERSION_CODE
30#include <linux/version.h>
31#endif
32#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s)) 29#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s))
33 30
34/************************************************/ 31/************************************************/
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index a50588c60fab..78b4ff117af6 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -41,7 +41,6 @@
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/sched.h> 42#include <linux/sched.h>
43#include <linux/device.h> 43#include <linux/device.h>
44#include "scsi.h"
45#include <scsi/scsi_host.h> 44#include <scsi/scsi_host.h>
46#include <asm/io.h> 45#include <asm/io.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
@@ -139,7 +138,7 @@ static u8 adma_bmdma_status(struct ata_port *ap);
139static void adma_irq_clear(struct ata_port *ap); 138static void adma_irq_clear(struct ata_port *ap);
140static void adma_eng_timeout(struct ata_port *ap); 139static void adma_eng_timeout(struct ata_port *ap);
141 140
142static Scsi_Host_Template adma_ata_sht = { 141static struct scsi_host_template adma_ata_sht = {
143 .module = THIS_MODULE, 142 .module = THIS_MODULE,
144 .name = DRV_NAME, 143 .name = DRV_NAME,
145 .ioctl = ata_scsi_ioctl, 144 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 290a6b92616c..72d9090df3df 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1977,8 +1977,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
1977 } 1977 }
1978 1978
1979cleanup_allocation: 1979cleanup_allocation:
1980 if (new_fcport) 1980 kfree(new_fcport);
1981 kfree(new_fcport);
1982 1981
1983 if (rval != QLA_SUCCESS) { 1982 if (rval != QLA_SUCCESS) {
1984 DEBUG2(printk("scsi(%ld): Configure local loop error exit: " 1983 DEBUG2(printk("scsi(%ld): Configure local loop error exit: "
@@ -2348,8 +2347,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
2348 /* Allocate temporary fcport for any new fcports discovered. */ 2347 /* Allocate temporary fcport for any new fcports discovered. */
2349 new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL); 2348 new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
2350 if (new_fcport == NULL) { 2349 if (new_fcport == NULL) {
2351 if (swl) 2350 kfree(swl);
2352 kfree(swl);
2353 return (QLA_MEMORY_ALLOC_FAILED); 2351 return (QLA_MEMORY_ALLOC_FAILED);
2354 } 2352 }
2355 new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED); 2353 new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
@@ -2485,19 +2483,15 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
2485 nxt_d_id.b24 = new_fcport->d_id.b24; 2483 nxt_d_id.b24 = new_fcport->d_id.b24;
2486 new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL); 2484 new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
2487 if (new_fcport == NULL) { 2485 if (new_fcport == NULL) {
2488 if (swl) 2486 kfree(swl);
2489 kfree(swl);
2490 return (QLA_MEMORY_ALLOC_FAILED); 2487 return (QLA_MEMORY_ALLOC_FAILED);
2491 } 2488 }
2492 new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED); 2489 new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
2493 new_fcport->d_id.b24 = nxt_d_id.b24; 2490 new_fcport->d_id.b24 = nxt_d_id.b24;
2494 } 2491 }
2495 2492
2496 if (swl) 2493 kfree(swl);
2497 kfree(swl); 2494 kfree(new_fcport);
2498
2499 if (new_fcport)
2500 kfree(new_fcport);
2501 2495
2502 if (!list_empty(new_fcports)) 2496 if (!list_empty(new_fcports))
2503 ha->device_flags |= DFLG_FABRIC_DEVICES; 2497 ha->device_flags |= DFLG_FABRIC_DEVICES;
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
index f1ea5027865f..caa0c3629626 100644
--- a/drivers/scsi/raid_class.c
+++ b/drivers/scsi/raid_class.c
@@ -4,6 +4,8 @@
4#include <linux/init.h> 4#include <linux/init.h>
5#include <linux/module.h> 5#include <linux/module.h>
6#include <linux/list.h> 6#include <linux/list.h>
7#include <linux/slab.h>
8#include <linux/string.h>
7#include <linux/raid_class.h> 9#include <linux/raid_class.h>
8#include <scsi/scsi_device.h> 10#include <scsi/scsi_device.h>
9#include <scsi/scsi_host.h> 11#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 0f469e3dabe2..93d55233af7b 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -30,8 +30,8 @@
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/device.h> 32#include <linux/device.h>
33#include "scsi.h"
34#include <scsi/scsi_host.h> 33#include <scsi/scsi_host.h>
34#include <scsi/scsi_cmnd.h>
35#include <linux/libata.h> 35#include <linux/libata.h>
36#include <asm/io.h> 36#include <asm/io.h>
37 37
@@ -270,7 +270,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
270static void mv_eng_timeout(struct ata_port *ap); 270static void mv_eng_timeout(struct ata_port *ap);
271static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); 271static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
272 272
273static Scsi_Host_Template mv_sht = { 273static struct scsi_host_template mv_sht = {
274 .module = THIS_MODULE, 274 .module = THIS_MODULE,
275 .name = DRV_NAME, 275 .name = DRV_NAME,
276 .ioctl = ata_scsi_ioctl, 276 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index d573888eda76..37a4fae95ed4 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -62,7 +62,6 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <linux/interrupt.h> 63#include <linux/interrupt.h>
64#include <linux/device.h> 64#include <linux/device.h>
65#include "scsi.h"
66#include <scsi/scsi_host.h> 65#include <scsi/scsi_host.h>
67#include <linux/libata.h> 66#include <linux/libata.h>
68 67
@@ -219,7 +218,7 @@ static struct pci_driver nv_pci_driver = {
219 .remove = ata_pci_remove_one, 218 .remove = ata_pci_remove_one,
220}; 219};
221 220
222static Scsi_Host_Template nv_sht = { 221static struct scsi_host_template nv_sht = {
223 .module = THIS_MODULE, 222 .module = THIS_MODULE,
224 .name = DRV_NAME, 223 .name = DRV_NAME,
225 .ioctl = ata_scsi_ioctl, 224 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index b41c977d6fab..9edc9d91efc3 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -39,8 +39,8 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
43#include <scsi/scsi_cmnd.h>
44#include <linux/libata.h> 44#include <linux/libata.h>
45#include <asm/io.h> 45#include <asm/io.h>
46#include "sata_promise.h" 46#include "sata_promise.h"
@@ -94,7 +94,7 @@ static void pdc_irq_clear(struct ata_port *ap);
94static int pdc_qc_issue_prot(struct ata_queued_cmd *qc); 94static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
95 95
96 96
97static Scsi_Host_Template pdc_ata_sht = { 97static struct scsi_host_template pdc_ata_sht = {
98 .module = THIS_MODULE, 98 .module = THIS_MODULE,
99 .name = DRV_NAME, 99 .name = DRV_NAME,
100 .ioctl = ata_scsi_ioctl, 100 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index 65502c157a54..d274ab235781 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -36,7 +36,6 @@
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/sched.h> 37#include <linux/sched.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include "scsi.h"
40#include <scsi/scsi_host.h> 39#include <scsi/scsi_host.h>
41#include <asm/io.h> 40#include <asm/io.h>
42#include <linux/libata.h> 41#include <linux/libata.h>
@@ -128,7 +127,7 @@ static u8 qs_bmdma_status(struct ata_port *ap);
128static void qs_irq_clear(struct ata_port *ap); 127static void qs_irq_clear(struct ata_port *ap);
129static void qs_eng_timeout(struct ata_port *ap); 128static void qs_eng_timeout(struct ata_port *ap);
130 129
131static Scsi_Host_Template qs_ata_sht = { 130static struct scsi_host_template qs_ata_sht = {
132 .module = THIS_MODULE, 131 .module = THIS_MODULE,
133 .name = DRV_NAME, 132 .name = DRV_NAME,
134 .ioctl = ata_scsi_ioctl, 133 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 435f7e0085ec..d0e3c3c6c25f 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -42,7 +42,6 @@
42#include <linux/delay.h> 42#include <linux/delay.h>
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
48 47
@@ -131,7 +130,7 @@ static struct pci_driver sil_pci_driver = {
131 .remove = ata_pci_remove_one, 130 .remove = ata_pci_remove_one,
132}; 131};
133 132
134static Scsi_Host_Template sil_sht = { 133static struct scsi_host_template sil_sht = {
135 .module = THIS_MODULE, 134 .module = THIS_MODULE,
136 .name = DRV_NAME, 135 .name = DRV_NAME,
137 .ioctl = ata_scsi_ioctl, 136 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index e6c8e89c226f..4682a50650b4 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -37,7 +37,7 @@
37#include <linux/dma-mapping.h> 37#include <linux/dma-mapping.h>
38#include <linux/device.h> 38#include <linux/device.h>
39#include <scsi/scsi_host.h> 39#include <scsi/scsi_host.h>
40#include "scsi.h" 40#include <scsi/scsi_cmnd.h>
41#include <linux/libata.h> 41#include <linux/libata.h>
42#include <asm/io.h> 42#include <asm/io.h>
43 43
@@ -255,7 +255,7 @@ static struct pci_driver sil24_pci_driver = {
255 .remove = ata_pci_remove_one, /* safe? */ 255 .remove = ata_pci_remove_one, /* safe? */
256}; 256};
257 257
258static Scsi_Host_Template sil24_sht = { 258static struct scsi_host_template sil24_sht = {
259 .module = THIS_MODULE, 259 .module = THIS_MODULE,
260 .name = DRV_NAME, 260 .name = DRV_NAME,
261 .ioctl = ata_scsi_ioctl, 261 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 42288be0e561..42d7c4e92501 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -39,7 +39,6 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/interrupt.h> 40#include <linux/interrupt.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
44#include <linux/libata.h> 43#include <linux/libata.h>
45 44
@@ -83,7 +82,7 @@ static struct pci_driver sis_pci_driver = {
83 .remove = ata_pci_remove_one, 82 .remove = ata_pci_remove_one,
84}; 83};
85 84
86static Scsi_Host_Template sis_sht = { 85static struct scsi_host_template sis_sht = {
87 .module = THIS_MODULE, 86 .module = THIS_MODULE,
88 .name = DRV_NAME, 87 .name = DRV_NAME,
89 .ioctl = ata_scsi_ioctl, 88 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index db615ff794d8..9895d1caefcf 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -45,7 +45,6 @@
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/interrupt.h> 46#include <linux/interrupt.h>
47#include <linux/device.h> 47#include <linux/device.h>
48#include "scsi.h"
49#include <scsi/scsi_host.h> 48#include <scsi/scsi_host.h>
50#include <linux/libata.h> 49#include <linux/libata.h>
51 50
@@ -284,7 +283,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
284#endif /* CONFIG_PPC_OF */ 283#endif /* CONFIG_PPC_OF */
285 284
286 285
287static Scsi_Host_Template k2_sata_sht = { 286static struct scsi_host_template k2_sata_sht = {
288 .module = THIS_MODULE, 287 .module = THIS_MODULE,
289 .name = DRV_NAME, 288 .name = DRV_NAME,
290 .ioctl = ata_scsi_ioctl, 289 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index f859bbd681ed..d5a38784352b 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -39,8 +39,8 @@
39#include <linux/interrupt.h> 39#include <linux/interrupt.h>
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/device.h> 41#include <linux/device.h>
42#include "scsi.h"
43#include <scsi/scsi_host.h> 42#include <scsi/scsi_host.h>
43#include <scsi/scsi_cmnd.h>
44#include <linux/libata.h> 44#include <linux/libata.h>
45#include <asm/io.h> 45#include <asm/io.h>
46#include "sata_promise.h" 46#include "sata_promise.h"
@@ -177,7 +177,7 @@ static void pdc20621_irq_clear(struct ata_port *ap);
177static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc); 177static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
178 178
179 179
180static Scsi_Host_Template pdc_sata_sht = { 180static struct scsi_host_template pdc_sata_sht = {
181 .module = THIS_MODULE, 181 .module = THIS_MODULE,
182 .name = DRV_NAME, 182 .name = DRV_NAME,
183 .ioctl = ata_scsi_ioctl, 183 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index a5e245c098e1..cf0baaa4e045 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -33,7 +33,6 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <linux/device.h> 35#include <linux/device.h>
36#include "scsi.h"
37#include <scsi/scsi_host.h> 36#include <scsi/scsi_host.h>
38#include <linux/libata.h> 37#include <linux/libata.h>
39 38
@@ -71,7 +70,7 @@ static struct pci_driver uli_pci_driver = {
71 .remove = ata_pci_remove_one, 70 .remove = ata_pci_remove_one,
72}; 71};
73 72
74static Scsi_Host_Template uli_sht = { 73static struct scsi_host_template uli_sht = {
75 .module = THIS_MODULE, 74 .module = THIS_MODULE,
76 .name = DRV_NAME, 75 .name = DRV_NAME,
77 .ioctl = ata_scsi_ioctl, 76 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index b3ecdbe400e9..ab19d2ba2a4b 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -42,7 +42,6 @@
42#include <linux/blkdev.h> 42#include <linux/blkdev.h>
43#include <linux/delay.h> 43#include <linux/delay.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include "scsi.h"
46#include <scsi/scsi_host.h> 45#include <scsi/scsi_host.h>
47#include <linux/libata.h> 46#include <linux/libata.h>
48#include <asm/io.h> 47#include <asm/io.h>
@@ -90,7 +89,7 @@ static struct pci_driver svia_pci_driver = {
90 .remove = ata_pci_remove_one, 89 .remove = ata_pci_remove_one,
91}; 90};
92 91
93static Scsi_Host_Template svia_sht = { 92static struct scsi_host_template svia_sht = {
94 .module = THIS_MODULE, 93 .module = THIS_MODULE,
95 .name = DRV_NAME, 94 .name = DRV_NAME,
96 .ioctl = ata_scsi_ioctl, 95 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index bb84ba0c7e83..ce8a2fd7da84 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -43,7 +43,6 @@
43#include <linux/interrupt.h> 43#include <linux/interrupt.h>
44#include <linux/dma-mapping.h> 44#include <linux/dma-mapping.h>
45#include <linux/device.h> 45#include <linux/device.h>
46#include "scsi.h"
47#include <scsi/scsi_host.h> 46#include <scsi/scsi_host.h>
48#include <linux/libata.h> 47#include <linux/libata.h>
49 48
@@ -219,7 +218,7 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance,
219} 218}
220 219
221 220
222static Scsi_Host_Template vsc_sata_sht = { 221static struct scsi_host_template vsc_sata_sht = {
223 .module = THIS_MODULE, 222 .module = THIS_MODULE,
224 .name = DRV_NAME, 223 .name = DRV_NAME,
225 .ioctl = ata_scsi_ioctl, 224 .ioctl = ata_scsi_ioctl,
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index aadf051274fa..b61fb1295b8b 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -48,10 +48,6 @@
48 48
49#include <linux/stat.h> 49#include <linux/stat.h>
50 50
51#ifndef LINUX_VERSION_CODE
52#include <linux/version.h>
53#endif
54
55#include "scsi_logging.h" 51#include "scsi_logging.h"
56#include "scsi_debug.h" 52#include "scsi_debug.h"
57 53
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 0cc766a9aa65..edabbd05d258 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -26,6 +26,8 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/err.h> 28#include <linux/err.h>
29#include <linux/slab.h>
30#include <linux/string.h>
29 31
30#include <scsi/scsi_device.h> 32#include <scsi/scsi_device.h>
31#include <scsi/scsi_host.h> 33#include <scsi/scsi_host.h>
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 4f30a37db63c..72ec59456e69 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -68,10 +68,6 @@ static int sg_proc_init(void);
68static void sg_proc_cleanup(void); 68static void sg_proc_cleanup(void);
69#endif 69#endif
70 70
71#ifndef LINUX_VERSION_CODE
72#include <linux/version.h>
73#endif /* LINUX_VERSION_CODE */
74
75#define SG_ALLOW_DIO_DEF 0 71#define SG_ALLOW_DIO_DEF 0
76#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */ 72#define SG_ALLOW_DIO_CODE /* compile out by commenting this define */
77 73
@@ -476,8 +472,7 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
476 sg_finish_rem_req(srp); 472 sg_finish_rem_req(srp);
477 retval = count; 473 retval = count;
478free_old_hdr: 474free_old_hdr:
479 if (old_hdr) 475 kfree(old_hdr);
480 kfree(old_hdr);
481 return retval; 476 return retval;
482} 477}
483 478
@@ -1703,10 +1698,8 @@ exit_sg(void)
1703 sg_sysfs_valid = 0; 1698 sg_sysfs_valid = 0;
1704 unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), 1699 unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
1705 SG_MAX_DEVS); 1700 SG_MAX_DEVS);
1706 if (sg_dev_arr != NULL) { 1701 kfree((char *)sg_dev_arr);
1707 kfree((char *) sg_dev_arr); 1702 sg_dev_arr = NULL;
1708 sg_dev_arr = NULL;
1709 }
1710 sg_dev_max = 0; 1703 sg_dev_max = 0;
1711} 1704}
1712 1705
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c
index 09fd203e4b86..f37147f8f7bf 100644
--- a/drivers/scsi/sgiwd93.c
+++ b/drivers/scsi/sgiwd93.c
@@ -15,7 +15,6 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/blkdev.h> 17#include <linux/blkdev.h>
18#include <linux/version.h>
19#include <linux/delay.h> 18#include <linux/delay.h>
20#include <linux/dma-mapping.h> 19#include <linux/dma-mapping.h>
21#include <linux/spinlock.h> 20#include <linux/spinlock.h>
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 6b85f84c8397..770c4324f3d5 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4107,8 +4107,7 @@ out_free_tape:
4107 write_unlock(&st_dev_arr_lock); 4107 write_unlock(&st_dev_arr_lock);
4108out_put_disk: 4108out_put_disk:
4109 put_disk(disk); 4109 put_disk(disk);
4110 if (tpnt) 4110 kfree(tpnt);
4111 kfree(tpnt);
4112out_buffer_free: 4111out_buffer_free:
4113 kfree(buffer); 4112 kfree(buffer);
4114out: 4113out:
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index a1a58e1d5ad3..a7420cad4547 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -39,6 +39,7 @@
39 */ 39 */
40 40
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <asm/param.h> /* for timeouts in units of HZ */
42 43
43#include "sym_glue.h" 44#include "sym_glue.h"
44#include "sym_nvram.h" 45#include "sym_nvram.h"
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index cfab8f197084..1ce29ba683eb 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -1953,11 +1953,11 @@ static int u14_34f_release(struct Scsi_Host *shpnt) {
1953 1953
1954 for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++); 1954 for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
1955 1955
1956 if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n", 1956 if (sh[j] == NULL)
1957 driver_name); 1957 panic("%s: release, invalid Scsi_Host pointer.\n", driver_name);
1958 1958
1959 for (i = 0; i < sh[j]->can_queue; i++) 1959 for (i = 0; i < sh[j]->can_queue; i++)
1960 if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist); 1960 kfree((&HD(j)->cp[i])->sglist);
1961 1961
1962 for (i = 0; i < sh[j]->can_queue; i++) 1962 for (i = 0; i < sh[j]->can_queue; i++)
1963 pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr, 1963 pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr,
@@ -1965,7 +1965,8 @@ static int u14_34f_release(struct Scsi_Host *shpnt) {
1965 1965
1966 free_irq(sh[j]->irq, &sha[j]); 1966 free_irq(sh[j]->irq, &sha[j]);
1967 1967
1968 if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel); 1968 if (sh[j]->dma_channel != NO_DMA)
1969 free_dma(sh[j]->dma_channel);
1969 1970
1970 release_region(sh[j]->io_port, sh[j]->n_io_port); 1971 release_region(sh[j]->io_port, sh[j]->n_io_port);
1971 scsi_unregister(sh[j]); 1972 scsi_unregister(sh[j]);
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 5754445fb36a..fd63add6a577 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -77,7 +77,6 @@
77#include <linux/sched.h> 77#include <linux/sched.h>
78#include <linux/string.h> 78#include <linux/string.h>
79#include <linux/delay.h> 79#include <linux/delay.h>
80#include <linux/version.h>
81#include <linux/init.h> 80#include <linux/init.h>
82#include <linux/blkdev.h> 81#include <linux/blkdev.h>
83#include <asm/irq.h> 82#include <asm/irq.h>
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index f47d2c454e33..98820603e75f 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -40,6 +40,7 @@
40#include <linux/serial_core.h> 40#include <linux/serial_core.h>
41#include <linux/serial.h> 41#include <linux/serial.h>
42#include <linux/serial_8250.h> 42#include <linux/serial_8250.h>
43#include <linux/nmi.h>
43 44
44#include <asm/io.h> 45#include <asm/io.h>
45#include <asm/irq.h> 46#include <asm/irq.h>
@@ -251,9 +252,53 @@ static const struct serial8250_config uart_config[] = {
251 }, 252 },
252}; 253};
253 254
255#ifdef CONFIG_SERIAL_8250_AU1X00
256
257/* Au1x00 UART hardware has a weird register layout */
258static const u8 au_io_in_map[] = {
259 [UART_RX] = 0,
260 [UART_IER] = 2,
261 [UART_IIR] = 3,
262 [UART_LCR] = 5,
263 [UART_MCR] = 6,
264 [UART_LSR] = 7,
265 [UART_MSR] = 8,
266};
267
268static const u8 au_io_out_map[] = {
269 [UART_TX] = 1,
270 [UART_IER] = 2,
271 [UART_FCR] = 4,
272 [UART_LCR] = 5,
273 [UART_MCR] = 6,
274};
275
276/* sane hardware needs no mapping */
277static inline int map_8250_in_reg(struct uart_8250_port *up, int offset)
278{
279 if (up->port.iotype != UPIO_AU)
280 return offset;
281 return au_io_in_map[offset];
282}
283
284static inline int map_8250_out_reg(struct uart_8250_port *up, int offset)
285{
286 if (up->port.iotype != UPIO_AU)
287 return offset;
288 return au_io_out_map[offset];
289}
290
291#else
292
293/* sane hardware needs no mapping */
294#define map_8250_in_reg(up, offset) (offset)
295#define map_8250_out_reg(up, offset) (offset)
296
297#endif
298
254static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) 299static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
255{ 300{
256 offset <<= up->port.regshift; 301 offset = map_8250_in_reg(up, offset) << up->port.regshift;
257 302
258 switch (up->port.iotype) { 303 switch (up->port.iotype) {
259 case UPIO_HUB6: 304 case UPIO_HUB6:
@@ -266,6 +311,11 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
266 case UPIO_MEM32: 311 case UPIO_MEM32:
267 return readl(up->port.membase + offset); 312 return readl(up->port.membase + offset);
268 313
314#ifdef CONFIG_SERIAL_8250_AU1X00
315 case UPIO_AU:
316 return __raw_readl(up->port.membase + offset);
317#endif
318
269 default: 319 default:
270 return inb(up->port.iobase + offset); 320 return inb(up->port.iobase + offset);
271 } 321 }
@@ -274,7 +324,7 @@ static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
274static _INLINE_ void 324static _INLINE_ void
275serial_out(struct uart_8250_port *up, int offset, int value) 325serial_out(struct uart_8250_port *up, int offset, int value)
276{ 326{
277 offset <<= up->port.regshift; 327 offset = map_8250_out_reg(up, offset) << up->port.regshift;
278 328
279 switch (up->port.iotype) { 329 switch (up->port.iotype) {
280 case UPIO_HUB6: 330 case UPIO_HUB6:
@@ -290,6 +340,12 @@ serial_out(struct uart_8250_port *up, int offset, int value)
290 writel(value, up->port.membase + offset); 340 writel(value, up->port.membase + offset);
291 break; 341 break;
292 342
343#ifdef CONFIG_SERIAL_8250_AU1X00
344 case UPIO_AU:
345 __raw_writel(value, up->port.membase + offset);
346 break;
347#endif
348
293 default: 349 default:
294 outb(value, up->port.iobase + offset); 350 outb(value, up->port.iobase + offset);
295 } 351 }
@@ -910,6 +966,13 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
910 } 966 }
911 } 967 }
912#endif 968#endif
969
970#ifdef CONFIG_SERIAL_8250_AU1X00
971 /* if access method is AU, it is a 16550 with a quirk */
972 if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU)
973 up->bugs |= UART_BUG_NOMSR;
974#endif
975
913 serial_outp(up, UART_LCR, save_lcr); 976 serial_outp(up, UART_LCR, save_lcr);
914 977
915 if (up->capabilities != uart_config[up->port.type].flags) { 978 if (up->capabilities != uart_config[up->port.type].flags) {
@@ -1057,6 +1120,10 @@ static void serial8250_enable_ms(struct uart_port *port)
1057{ 1120{
1058 struct uart_8250_port *up = (struct uart_8250_port *)port; 1121 struct uart_8250_port *up = (struct uart_8250_port *)port;
1059 1122
1123 /* no MSR capabilities */
1124 if (up->bugs & UART_BUG_NOMSR)
1125 return;
1126
1060 up->ier |= UART_IER_MSI; 1127 up->ier |= UART_IER_MSI;
1061 serial_out(up, UART_IER, up->ier); 1128 serial_out(up, UART_IER, up->ier);
1062} 1129}
@@ -1774,7 +1841,8 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
1774 * CTS flow control flag and modem status interrupts 1841 * CTS flow control flag and modem status interrupts
1775 */ 1842 */
1776 up->ier &= ~UART_IER_MSI; 1843 up->ier &= ~UART_IER_MSI;
1777 if (UART_ENABLE_MS(&up->port, termios->c_cflag)) 1844 if (!(up->bugs & UART_BUG_NOMSR) &&
1845 UART_ENABLE_MS(&up->port, termios->c_cflag))
1778 up->ier |= UART_IER_MSI; 1846 up->ier |= UART_IER_MSI;
1779 if (up->capabilities & UART_CAP_UUE) 1847 if (up->capabilities & UART_CAP_UUE)
1780 up->ier |= UART_IER_UUE | UART_IER_RTOIE; 1848 up->ier |= UART_IER_UUE | UART_IER_RTOIE;
@@ -2141,6 +2209,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
2141 unsigned int ier; 2209 unsigned int ier;
2142 int i; 2210 int i;
2143 2211
2212 touch_nmi_watchdog();
2213
2144 /* 2214 /*
2145 * First save the UER then disable the interrupts 2215 * First save the UER then disable the interrupts
2146 */ 2216 */
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index b1b459efda52..a607b98016db 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -49,6 +49,7 @@ struct serial8250_config {
49 49
50#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ 50#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
51#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ 51#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
52#define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */
52 53
53#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486)) 54#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
54#define _INLINE_ inline 55#define _INLINE_ inline
diff --git a/drivers/serial/8250_au1x00.c b/drivers/serial/8250_au1x00.c
new file mode 100644
index 000000000000..06ae8fbcc947
--- /dev/null
+++ b/drivers/serial/8250_au1x00.c
@@ -0,0 +1,102 @@
1/*
2 * Serial Device Initialisation for Au1x00
3 *
4 * (C) Copyright Embedded Alley Solutions, Inc 2005
5 * Author: Pantelis Antoniou <pantelis@embeddedalley.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/errno.h>
14#include <linux/init.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <linux/module.h>
18#include <linux/serial_core.h>
19#include <linux/signal.h>
20#include <linux/slab.h>
21#include <linux/types.h>
22
23#include <linux/serial_8250.h>
24
25#include <asm/mach-au1x00/au1000.h>
26
27#include "8250.h"
28
29#define PORT(_base, _irq) \
30 { \
31 .iobase = _base, \
32 .membase = (void __iomem *)_base,\
33 .mapbase = _base, \
34 .irq = _irq, \
35 .uartclk = 0, /* filled */ \
36 .regshift = 2, \
37 .iotype = UPIO_AU, \
38 .flags = UPF_SKIP_TEST | \
39 UPF_IOREMAP, \
40 }
41
42static struct plat_serial8250_port au1x00_data[] = {
43#if defined(CONFIG_SOC_AU1000)
44 PORT(UART0_ADDR, AU1000_UART0_INT),
45 PORT(UART1_ADDR, AU1000_UART1_INT),
46 PORT(UART2_ADDR, AU1000_UART2_INT),
47 PORT(UART3_ADDR, AU1000_UART3_INT),
48#elif defined(CONFIG_SOC_AU1500)
49 PORT(UART0_ADDR, AU1500_UART0_INT),
50 PORT(UART3_ADDR, AU1500_UART3_INT),
51#elif defined(CONFIG_SOC_AU1100)
52 PORT(UART0_ADDR, AU1100_UART0_INT),
53 PORT(UART1_ADDR, AU1100_UART1_INT),
54 PORT(UART2_ADDR, AU1100_UART2_INT),
55 PORT(UART3_ADDR, AU1100_UART3_INT),
56#elif defined(CONFIG_SOC_AU1550)
57 PORT(UART0_ADDR, AU1550_UART0_INT),
58 PORT(UART1_ADDR, AU1550_UART1_INT),
59 PORT(UART2_ADDR, AU1550_UART2_INT),
60 PORT(UART3_ADDR, AU1550_UART3_INT),
61#elif defined(CONFIG_SOC_AU1200)
62 PORT(UART0_ADDR, AU1200_UART0_INT),
63 PORT(UART1_ADDR, AU1200_UART1_INT),
64#endif
65 { },
66};
67
68static struct platform_device au1x00_device = {
69 .name = "serial8250",
70 .id = PLAT8250_DEV_AU1X00,
71 .dev = {
72 .platform_data = au1x00_data,
73 },
74};
75
76static int __init au1x00_init(void)
77{
78 int i;
79 unsigned int uartclk;
80
81 /* get uart clock */
82 uartclk = get_au1x00_uart_baud_base() * 16;
83
84 /* fill up uartclk */
85 for (i = 0; au1x00_data[i].flags ; i++)
86 au1x00_data[i].uartclk = uartclk;
87
88 return platform_device_register(&au1x00_device);
89}
90
91/* XXX: Yes, I know this doesn't yet work. */
92static void __exit au1x00_exit(void)
93{
94 platform_device_unregister(&au1x00_device);
95}
96
97module_init(au1x00_init);
98module_exit(au1x00_exit);
99
100MODULE_AUTHOR("Pantelis Antoniou <pantelis@embeddedalley.com>");
101MODULE_DESCRIPTION("8250 serial probe module for Au1x000 cards");
102MODULE_LICENSE("GPL");
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b745a1b9e835..ff36f0c9fdad 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -207,6 +207,14 @@ config SERIAL_8250_ACORN
207 system, say Y to this option. The driver can handle 1, 2, or 3 port 207 system, say Y to this option. The driver can handle 1, 2, or 3 port
208 cards. If unsure, say N. 208 cards. If unsure, say N.
209 209
210config SERIAL_8250_AU1X00
211 bool "AU1X00 serial port support"
212 depends on SERIAL_8250 != n && SOC_AU1X00
213 help
214 If you have an Au1x00 board and want to use the serial port, say Y
215 to this option. The driver can handle 1 or 2 serial ports.
216 If unsure, say N.
217
210comment "Non-8250 serial port support" 218comment "Non-8250 serial port support"
211 219
212config SERIAL_AMBA_PL010 220config SERIAL_AMBA_PL010
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 11c7dc483f93..d7c7c7180e33 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o
22obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o 22obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o
23obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o 23obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
24obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o 24obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
25obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o
25obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o 26obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
26obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o 27obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
27obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o 28obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 40d3e7139cfe..08c42c000188 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -4416,10 +4416,8 @@ rs_close(struct tty_struct *tty, struct file * filp)
4416 info->event = 0; 4416 info->event = 0;
4417 info->tty = 0; 4417 info->tty = 0;
4418 if (info->blocked_open) { 4418 if (info->blocked_open) {
4419 if (info->close_delay) { 4419 if (info->close_delay)
4420 set_current_state(TASK_INTERRUPTIBLE); 4420 schedule_timeout_interruptible(info->close_delay);
4421 schedule_timeout(info->close_delay);
4422 }
4423 wake_up_interruptible(&info->open_wait); 4421 wake_up_interruptible(&info->open_wait);
4424 } 4422 }
4425 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 4423 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -4469,8 +4467,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
4469 while (info->xmit.head != info->xmit.tail || /* More in send queue */ 4467 while (info->xmit.head != info->xmit.tail || /* More in send queue */
4470 (*info->ostatusadr & 0x007f) || /* more in FIFO */ 4468 (*info->ostatusadr & 0x007f) || /* more in FIFO */
4471 (elapsed_usec < 2*info->char_time_usec)) { 4469 (elapsed_usec < 2*info->char_time_usec)) {
4472 set_current_state(TASK_INTERRUPTIBLE); 4470 schedule_timeout_interruptible(1);
4473 schedule_timeout(1);
4474 if (signal_pending(current)) 4471 if (signal_pending(current))
4475 break; 4472 break;
4476 if (timeout && time_after(jiffies, orig_jiffies + timeout)) 4473 if (timeout && time_after(jiffies, orig_jiffies + timeout))
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c
index e2ebdcad553c..47f7404cb045 100644
--- a/drivers/serial/mcfserial.c
+++ b/drivers/serial/mcfserial.c
@@ -57,7 +57,8 @@ struct timer_list mcfrs_timer_struct;
57 * keep going. Perhaps one day the cflag settings for the 57 * keep going. Perhaps one day the cflag settings for the
58 * console can be used instead. 58 * console can be used instead.
59 */ 59 */
60#if defined(CONFIG_ARNEWSH) || defined(CONFIG_MOTOROLA) || defined(CONFIG_senTec) || defined(CONFIG_SNEHA) 60#if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
61 defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
61#define CONSOLE_BAUD_RATE 19200 62#define CONSOLE_BAUD_RATE 19200
62#define DEFAULT_CBAUD B19200 63#define DEFAULT_CBAUD B19200
63#endif 64#endif
@@ -67,7 +68,7 @@ struct timer_list mcfrs_timer_struct;
67#define DEFAULT_CBAUD B38400 68#define DEFAULT_CBAUD B38400
68#endif 69#endif
69 70
70#if defined(CONFIG_MOD5272) 71#if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
71#define CONSOLE_BAUD_RATE 115200 72#define CONSOLE_BAUD_RATE 115200
72#define DEFAULT_CBAUD B115200 73#define DEFAULT_CBAUD B115200
73#endif 74#endif
@@ -95,7 +96,8 @@ static struct tty_driver *mcfrs_serial_driver;
95#undef SERIAL_DEBUG_OPEN 96#undef SERIAL_DEBUG_OPEN
96#undef SERIAL_DEBUG_FLOW 97#undef SERIAL_DEBUG_FLOW
97 98
98#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) 99#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
100 defined(CONFIG_M520x)
99#define IRQBASE (MCFINT_VECBASE+MCFINT_UART0) 101#define IRQBASE (MCFINT_VECBASE+MCFINT_UART0)
100#else 102#else
101#define IRQBASE 73 103#define IRQBASE 73
@@ -1528,6 +1530,35 @@ static void mcfrs_irqinit(struct mcf_serial *info)
1528 imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + 1530 imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
1529 MCFINTC_IMRL); 1531 MCFINTC_IMRL);
1530 *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); 1532 *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
1533#elif defined(CONFIG_M520x)
1534 volatile unsigned char *icrp, *uartp;
1535 volatile unsigned long *imrp;
1536
1537 uartp = info->addr;
1538
1539 icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
1540 MCFINTC_ICR0 + MCFINT_UART0 + info->line);
1541 *icrp = 0x03;
1542
1543 imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
1544 MCFINTC_IMRL);
1545 *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
1546 if (info->line < 2) {
1547 unsigned short *uart_par;
1548 uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART);
1549 if (info->line == 0)
1550 *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD0
1551 | MCF_GPIO_PAR_UART_PAR_URXD0;
1552 else if (info->line == 1)
1553 *uart_par |= MCF_GPIO_PAR_UART_PAR_UTXD1
1554 | MCF_GPIO_PAR_UART_PAR_URXD1;
1555 } else if (info->line == 2) {
1556 unsigned char *feci2c_par;
1557 feci2c_par = (unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
1558 *feci2c_par &= ~0x0F;
1559 *feci2c_par |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2
1560 | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
1561 }
1531#else 1562#else
1532 volatile unsigned char *icrp, *uartp; 1563 volatile unsigned char *icrp, *uartp;
1533 1564
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 0745ce782974..427a23858076 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1959,6 +1959,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
1959 break; 1959 break;
1960 case UPIO_MEM: 1960 case UPIO_MEM:
1961 case UPIO_MEM32: 1961 case UPIO_MEM32:
1962 case UPIO_AU:
1962 snprintf(address, sizeof(address), 1963 snprintf(address, sizeof(address),
1963 "MMIO 0x%lx", port->mapbase); 1964 "MMIO 0x%lx", port->mapbase);
1964 break; 1965 break;
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 656c0e8d160e..f0738533f39a 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1441,7 +1441,7 @@ static void sunsu_console_write(struct console *co, const char *s,
1441 * - initialize the serial port 1441 * - initialize the serial port
1442 * Return non-zero if we didn't find a serial port. 1442 * Return non-zero if we didn't find a serial port.
1443 */ 1443 */
1444static int __init sunsu_console_setup(struct console *co, char *options) 1444static int sunsu_console_setup(struct console *co, char *options)
1445{ 1445{
1446 struct uart_port *port; 1446 struct uart_port *port;
1447 int baud = 9600; 1447 int baud = 9600;
diff --git a/drivers/sh/superhyway/superhyway-sysfs.c b/drivers/sh/superhyway/superhyway-sysfs.c
index dc119ce68e3e..55434330867b 100644
--- a/drivers/sh/superhyway/superhyway-sysfs.c
+++ b/drivers/sh/superhyway/superhyway-sysfs.c
@@ -30,7 +30,7 @@ superhyway_ro_attr(bot_mb, "0x%02x\n", vcr.bot_mb);
30superhyway_ro_attr(top_mb, "0x%02x\n", vcr.top_mb); 30superhyway_ro_attr(top_mb, "0x%02x\n", vcr.top_mb);
31 31
32/* Misc */ 32/* Misc */
33superhyway_ro_attr(resource, "0x%08lx\n", resource.start); 33superhyway_ro_attr(resource, "0x%08lx\n", resource[0].start);
34 34
35struct device_attribute superhyway_dev_attrs[] = { 35struct device_attribute superhyway_dev_attrs[] = {
36 __ATTR_RO(perr_flags), 36 __ATTR_RO(perr_flags),
diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c
index 28757cb9d246..7bdab2a7f59c 100644
--- a/drivers/sh/superhyway/superhyway.c
+++ b/drivers/sh/superhyway/superhyway.c
@@ -27,19 +27,20 @@ static struct device superhyway_bus_device = {
27 27
28static void superhyway_device_release(struct device *dev) 28static void superhyway_device_release(struct device *dev)
29{ 29{
30 kfree(to_superhyway_device(dev)); 30 struct superhyway_device *sdev = to_superhyway_device(dev);
31
32 kfree(sdev->resource);
33 kfree(sdev);
31} 34}
32 35
33/** 36/**
34 * superhyway_add_device - Add a SuperHyway module 37 * superhyway_add_device - Add a SuperHyway module
35 * @mod_id: Module ID (taken from MODULE.VCR.MOD_ID).
36 * @base: Physical address where module is mapped. 38 * @base: Physical address where module is mapped.
37 * @vcr: VCR value. 39 * @sdev: SuperHyway device to add, or NULL to allocate a new one.
40 * @bus: Bus where SuperHyway module resides.
38 * 41 *
39 * This is responsible for adding a new SuperHyway module. This sets up a new 42 * This is responsible for adding a new SuperHyway module. This sets up a new
40 * struct superhyway_device for the module being added. Each one of @mod_id, 43 * struct superhyway_device for the module being added if @sdev == NULL.
41 * @base, and @vcr are registered with the new device for further use
42 * elsewhere.
43 * 44 *
44 * Devices are initially added in the order that they are scanned (from the 45 * Devices are initially added in the order that they are scanned (from the
45 * top-down of the memory map), and are assigned an ID based on the order that 46 * top-down of the memory map), and are assigned an ID based on the order that
@@ -49,28 +50,40 @@ static void superhyway_device_release(struct device *dev)
49 * Further work can and should be done in superhyway_scan_bus(), to be sure 50 * Further work can and should be done in superhyway_scan_bus(), to be sure
50 * that any new modules are properly discovered and subsequently registered. 51 * that any new modules are properly discovered and subsequently registered.
51 */ 52 */
52int superhyway_add_device(unsigned int mod_id, unsigned long base, 53int superhyway_add_device(unsigned long base, struct superhyway_device *sdev,
53 unsigned long long vcr) 54 struct superhyway_bus *bus)
54{ 55{
55 struct superhyway_device *dev; 56 struct superhyway_device *dev = sdev;
57
58 if (!dev) {
59 dev = kmalloc(sizeof(struct superhyway_device), GFP_KERNEL);
60 if (!dev)
61 return -ENOMEM;
56 62
57 dev = kmalloc(sizeof(struct superhyway_device), GFP_KERNEL); 63 memset(dev, 0, sizeof(struct superhyway_device));
58 if (!dev) 64 }
59 return -ENOMEM;
60 65
61 memset(dev, 0, sizeof(struct superhyway_device)); 66 dev->bus = bus;
67 superhyway_read_vcr(dev, base, &dev->vcr);
62 68
63 dev->id.id = mod_id; 69 if (!dev->resource) {
64 sprintf(dev->name, "SuperHyway device %04x", dev->id.id); 70 dev->resource = kmalloc(sizeof(struct resource), GFP_KERNEL);
71 if (!dev->resource) {
72 kfree(dev);
73 return -ENOMEM;
74 }
75
76 dev->resource->name = dev->name;
77 dev->resource->start = base;
78 dev->resource->end = dev->resource->start + 0x01000000;
79 }
65 80
66 dev->vcr = *((struct vcr_info *)(&vcr));
67 dev->resource.name = dev->name;
68 dev->resource.start = base;
69 dev->resource.end = dev->resource.start + 0x01000000;
70 dev->dev.parent = &superhyway_bus_device; 81 dev->dev.parent = &superhyway_bus_device;
71 dev->dev.bus = &superhyway_bus_type; 82 dev->dev.bus = &superhyway_bus_type;
72 dev->dev.release = superhyway_device_release; 83 dev->dev.release = superhyway_device_release;
84 dev->id.id = dev->vcr.mod_id;
73 85
86 sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
74 sprintf(dev->dev.bus_id, "%02x", superhyway_devices); 87 sprintf(dev->dev.bus_id, "%02x", superhyway_devices);
75 88
76 superhyway_devices++; 89 superhyway_devices++;
@@ -78,10 +91,31 @@ int superhyway_add_device(unsigned int mod_id, unsigned long base,
78 return device_register(&dev->dev); 91 return device_register(&dev->dev);
79} 92}
80 93
94int superhyway_add_devices(struct superhyway_bus *bus,
95 struct superhyway_device **devices,
96 int nr_devices)
97{
98 int i, ret = 0;
99
100 for (i = 0; i < nr_devices; i++) {
101 struct superhyway_device *dev = devices[i];
102 ret |= superhyway_add_device(dev->resource[0].start, dev, bus);
103 }
104
105 return ret;
106}
107
81static int __init superhyway_init(void) 108static int __init superhyway_init(void)
82{ 109{
110 struct superhyway_bus *bus;
111 int ret = 0;
112
83 device_register(&superhyway_bus_device); 113 device_register(&superhyway_bus_device);
84 return superhyway_scan_bus(); 114
115 for (bus = superhyway_channels; bus->ops; bus++)
116 ret |= superhyway_scan_bus(bus);
117
118 return ret;
85} 119}
86 120
87postcore_initcall(superhyway_init); 121postcore_initcall(superhyway_init);
@@ -197,6 +231,7 @@ module_exit(superhyway_bus_exit);
197 231
198EXPORT_SYMBOL(superhyway_bus_type); 232EXPORT_SYMBOL(superhyway_bus_type);
199EXPORT_SYMBOL(superhyway_add_device); 233EXPORT_SYMBOL(superhyway_add_device);
234EXPORT_SYMBOL(superhyway_add_devices);
200EXPORT_SYMBOL(superhyway_register_driver); 235EXPORT_SYMBOL(superhyway_register_driver);
201EXPORT_SYMBOL(superhyway_unregister_driver); 236EXPORT_SYMBOL(superhyway_unregister_driver);
202 237
diff --git a/drivers/tc/.gitignore b/drivers/tc/.gitignore
new file mode 100644
index 000000000000..acc0e1e6a650
--- /dev/null
+++ b/drivers/tc/.gitignore
@@ -0,0 +1 @@
lk201-map.c
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index 51e3f7f6597b..fbea4541c234 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -40,7 +40,6 @@
40 *****************************************************************************/ 40 *****************************************************************************/
41#define IXJ_VERSION 3031 41#define IXJ_VERSION 3031
42 42
43#include <linux/version.h>
44#include <linux/types.h> 43#include <linux/types.h>
45 44
46#include <linux/ixjuser.h> 45#include <linux/ixjuser.h>
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 975ace3f5b1e..904519085334 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -49,7 +49,6 @@
49#include <linux/timer.h> 49#include <linux/timer.h>
50#include <linux/list.h> 50#include <linux/list.h>
51#include <linux/interrupt.h> 51#include <linux/interrupt.h>
52#include <linux/version.h>
53#include <linux/platform_device.h> 52#include <linux/platform_device.h>
54#include <linux/usb.h> 53#include <linux/usb.h>
55#include <linux/usb_gadget.h> 54#include <linux/usb_gadget.h>
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 654469778ab5..b0f3cd63e3b9 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -1970,7 +1970,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
1970static struct pci_driver goku_pci_driver = { 1970static struct pci_driver goku_pci_driver = {
1971 .name = (char *) driver_name, 1971 .name = (char *) driver_name,
1972 .id_table = pci_ids, 1972 .id_table = pci_ids,
1973 .owner = THIS_MODULE,
1974 1973
1975 .probe = goku_probe, 1974 .probe = goku_probe,
1976 .remove = goku_remove, 1975 .remove = goku_remove,
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h
index 1bb455c045a9..9b2e6f7cbb8b 100644
--- a/drivers/usb/gadget/lh7a40x_udc.h
+++ b/drivers/usb/gadget/lh7a40x_udc.h
@@ -29,7 +29,6 @@
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/version.h>
33#include <linux/errno.h> 32#include <linux/errno.h>
34#include <linux/delay.h> 33#include <linux/delay.h>
35#include <linux/sched.h> 34#include <linux/sched.h>
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 0dc6bb00bf72..c32e1f7476da 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -2948,7 +2948,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
2948static struct pci_driver net2280_pci_driver = { 2948static struct pci_driver net2280_pci_driver = {
2949 .name = (char *) driver_name, 2949 .name = (char *) driver_name,
2950 .id_table = pci_ids, 2950 .id_table = pci_ids,
2951 .owner = THIS_MODULE,
2952 2951
2953 .probe = net2280_probe, 2952 .probe = net2280_probe,
2954 .remove = net2280_remove, 2953 .remove = net2280_remove,
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index ee9cd7869d92..510d28a924db 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -32,7 +32,6 @@
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/ioport.h> 33#include <linux/ioport.h>
34#include <linux/types.h> 34#include <linux/types.h>
35#include <linux/version.h>
36#include <linux/errno.h> 35#include <linux/errno.h>
37#include <linux/delay.h> 36#include <linux/delay.h>
38#include <linux/sched.h> 37#include <linux/sched.h>
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 06b6eba925b5..9689efeb364c 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -28,7 +28,6 @@
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/version.h>
32#include <linux/init.h> 31#include <linux/init.h>
33#include <linux/list.h> 32#include <linux/list.h>
34#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 145008853966..dfd9bd0b1828 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -383,7 +383,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
383static struct pci_driver ehci_pci_driver = { 383static struct pci_driver ehci_pci_driver = {
384 .name = (char *) hcd_name, 384 .name = (char *) hcd_name,
385 .id_table = pci_ids, 385 .id_table = pci_ids,
386 .owner = THIS_MODULE,
387 386
388 .probe = usb_hcd_pci_probe, 387 .probe = usb_hcd_pci_probe,
389 .remove = usb_hcd_pci_remove, 388 .remove = usb_hcd_pci_remove,
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index a8267cf17db4..0eaabeb37ac3 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -14,7 +14,6 @@
14#include <linux/unistd.h> 14#include <linux/unistd.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/version.h>
18#include <linux/list.h> 17#include <linux/list.h>
19#include <linux/spinlock.h> 18#include <linux/spinlock.h>
20 19
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 7ce1d9ef0289..a59e536441e1 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -218,7 +218,6 @@ MODULE_DEVICE_TABLE (pci, pci_ids);
218static struct pci_driver ohci_pci_driver = { 218static struct pci_driver ohci_pci_driver = {
219 .name = (char *) hcd_name, 219 .name = (char *) hcd_name,
220 .id_table = pci_ids, 220 .id_table = pci_ids,
221 .owner = THIS_MODULE,
222 221
223 .probe = usb_hcd_pci_probe, 222 .probe = usb_hcd_pci_probe,
224 .remove = usb_hcd_pci_remove, 223 .remove = usb_hcd_pci_remove,
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 15e0a511069b..d33ce3982a5f 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -831,7 +831,6 @@ MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
831static struct pci_driver uhci_pci_driver = { 831static struct pci_driver uhci_pci_driver = {
832 .name = (char *)hcd_name, 832 .name = (char *)hcd_name,
833 .id_table = uhci_pci_ids, 833 .id_table = uhci_pci_ids,
834 .owner = THIS_MODULE,
835 834
836 .probe = usb_hcd_pci_probe, 835 .probe = usb_hcd_pci_probe,
837 .remove = usb_hcd_pci_remove, 836 .remove = usb_hcd_pci_remove,
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index b77e65c03659..5524fd70210b 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -62,6 +62,7 @@
62#include <linux/poll.h> 62#include <linux/poll.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/vmalloc.h> 64#include <linux/vmalloc.h>
65#include <linux/version.h>
65#include <asm/io.h> 66#include <asm/io.h>
66 67
67#include "pwc.h" 68#include "pwc.h"
diff --git a/drivers/usb/media/pwc/pwc.h b/drivers/usb/media/pwc/pwc.h
index 267869dab185..6dd76bb3dff1 100644
--- a/drivers/usb/media/pwc/pwc.h
+++ b/drivers/usb/media/pwc/pwc.h
@@ -25,8 +25,6 @@
25#ifndef PWC_H 25#ifndef PWC_H
26#define PWC_H 26#define PWC_H
27 27
28#include <linux/version.h>
29
30#include <linux/config.h> 28#include <linux/config.h>
31#include <linux/module.h> 29#include <linux/module.h>
32#include <linux/usb.h> 30#include <linux/usb.h>
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index f36c0b6c6e36..67612c81cb9f 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -25,7 +25,6 @@
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 ***************************************************************************/ 26 ***************************************************************************/
27 27
28#include <linux/version.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/kernel.h> 29#include <linux/kernel.h>
31#include <linux/kmod.h> 30#include <linux/kmod.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index c946c9a538a0..41ef2b606751 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -37,7 +37,6 @@
37 */ 37 */
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/version.h>
41#include <linux/module.h> 40#include <linux/module.h>
42#include <linux/kernel.h> 41#include <linux/kernel.h>
43#include <linux/signal.h> 42#include <linux/signal.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h
index 401ff21d7881..1d7a77cc7c4a 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.h
+++ b/drivers/usb/misc/sisusbvga/sisusb.h
@@ -37,6 +37,7 @@
37#ifndef _SISUSB_H_ 37#ifndef _SISUSB_H_
38#define _SISUSB_H_ 38#define _SISUSB_H_
39 39
40#include <linux/version.h>
40#ifdef CONFIG_COMPAT 41#ifdef CONFIG_COMPAT
41#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) 42#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
42#include <linux/ioctl32.h> 43#include <linux/ioctl32.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 24584463553d..be5c1a25ae21 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -48,7 +48,6 @@
48 */ 48 */
49 49
50#include <linux/config.h> 50#include <linux/config.h>
51#include <linux/version.h>
52#include <linux/module.h> 51#include <linux/module.h>
53#include <linux/kernel.h> 52#include <linux/kernel.h>
54#include <linux/signal.h> 53#include <linux/signal.h>
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c
index f28bc240f9b6..044fa4482f9f 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_init.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.c
@@ -37,7 +37,6 @@
37 */ 37 */
38 38
39#include <linux/config.h> 39#include <linux/config.h>
40#include <linux/version.h>
41#include <linux/module.h> 40#include <linux/module.h>
42#include <linux/kernel.h> 41#include <linux/kernel.h>
43#include <linux/errno.h> 42#include <linux/errno.h>
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 6a3cfbdc6dc9..3b0ddc55236b 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -113,7 +113,6 @@ static struct fb_ops mc68x328fb_ops = {
113 .fb_fillrect = cfb_fillrect, 113 .fb_fillrect = cfb_fillrect,
114 .fb_copyarea = cfb_copyarea, 114 .fb_copyarea = cfb_copyarea,
115 .fb_imageblit = cfb_imageblit, 115 .fb_imageblit = cfb_imageblit,
116 .fb_cursor = soft_cursor,
117 .fb_mmap = mc68x328fb_mmap, 116 .fb_mmap = mc68x328fb_mmap,
118}; 117};
119 118
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7192b770bfb6..25b6ca6ad081 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -65,15 +65,6 @@ config FB_CFB_IMAGEBLIT
65 blitting. This is used by drivers that don't provide their own 65 blitting. This is used by drivers that don't provide their own
66 (accelerated) version. 66 (accelerated) version.
67 67
68config FB_SOFT_CURSOR
69 tristate
70 depends on FB
71 default n
72 ---help---
73 Include the soft_cursor function for generic software cursor support.
74 This is used by drivers that don't provide their own (accelerated)
75 version.
76
77config FB_MACMODES 68config FB_MACMODES
78 tristate 69 tristate
79 depends on FB 70 depends on FB
@@ -114,7 +105,6 @@ config FB_CIRRUS
114 select FB_CFB_FILLRECT 105 select FB_CFB_FILLRECT
115 select FB_CFB_COPYAREA 106 select FB_CFB_COPYAREA
116 select FB_CFB_IMAGEBLIT 107 select FB_CFB_IMAGEBLIT
117 select FB_SOFT_CURSOR
118 ---help--- 108 ---help---
119 This enables support for Cirrus Logic GD542x/543x based boards on 109 This enables support for Cirrus Logic GD542x/543x based boards on
120 Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. 110 Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
@@ -133,7 +123,6 @@ config FB_PM2
133 select FB_CFB_FILLRECT 123 select FB_CFB_FILLRECT
134 select FB_CFB_COPYAREA 124 select FB_CFB_COPYAREA
135 select FB_CFB_IMAGEBLIT 125 select FB_CFB_IMAGEBLIT
136 select FB_SOFT_CURSOR
137 help 126 help
138 This is the frame buffer device driver for the Permedia2 AGP frame 127 This is the frame buffer device driver for the Permedia2 AGP frame
139 buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a 128 buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a
@@ -152,7 +141,6 @@ config FB_ARMCLCD
152 select FB_CFB_FILLRECT 141 select FB_CFB_FILLRECT
153 select FB_CFB_COPYAREA 142 select FB_CFB_COPYAREA
154 select FB_CFB_IMAGEBLIT 143 select FB_CFB_IMAGEBLIT
155 select FB_SOFT_CURSOR
156 help 144 help
157 This framebuffer device driver is for the ARM PrimeCell PL110 145 This framebuffer device driver is for the ARM PrimeCell PL110
158 Colour LCD controller. ARM PrimeCells provide the building 146 Colour LCD controller. ARM PrimeCells provide the building
@@ -169,7 +157,6 @@ config FB_ACORN
169 select FB_CFB_FILLRECT 157 select FB_CFB_FILLRECT
170 select FB_CFB_COPYAREA 158 select FB_CFB_COPYAREA
171 select FB_CFB_IMAGEBLIT 159 select FB_CFB_IMAGEBLIT
172 select FB_SOFT_CURSOR
173 help 160 help
174 This is the frame buffer device driver for the Acorn VIDC graphics 161 This is the frame buffer device driver for the Acorn VIDC graphics
175 hardware found in Acorn RISC PCs and other ARM-based machines. If 162 hardware found in Acorn RISC PCs and other ARM-based machines. If
@@ -181,7 +168,9 @@ config FB_CLPS711X
181 select FB_CFB_FILLRECT 168 select FB_CFB_FILLRECT
182 select FB_CFB_COPYAREA 169 select FB_CFB_COPYAREA
183 select FB_CFB_IMAGEBLIT 170 select FB_CFB_IMAGEBLIT
184 select FB_SOFT_CURSOR 171 help
172 Say Y to enable the Framebuffer driver for the CLPS7111 and
173 EP7212 processors.
185 174
186config FB_SA1100 175config FB_SA1100
187 bool "SA-1100 LCD support" 176 bool "SA-1100 LCD support"
@@ -189,7 +178,6 @@ config FB_SA1100
189 select FB_CFB_FILLRECT 178 select FB_CFB_FILLRECT
190 select FB_CFB_COPYAREA 179 select FB_CFB_COPYAREA
191 select FB_CFB_IMAGEBLIT 180 select FB_CFB_IMAGEBLIT
192 select FB_SOFT_CURSOR
193 help 181 help
194 This is a framebuffer device for the SA-1100 LCD Controller. 182 This is a framebuffer device for the SA-1100 LCD Controller.
195 See <http://www.linux-fbdev.org/> for information on framebuffer 183 See <http://www.linux-fbdev.org/> for information on framebuffer
@@ -204,7 +192,6 @@ config FB_IMX
204 select FB_CFB_FILLRECT 192 select FB_CFB_FILLRECT
205 select FB_CFB_COPYAREA 193 select FB_CFB_COPYAREA
206 select FB_CFB_IMAGEBLIT 194 select FB_CFB_IMAGEBLIT
207 select FB_SOFT_CURSOR
208 195
209config FB_CYBER2000 196config FB_CYBER2000
210 tristate "CyberPro 2000/2010/5000 support" 197 tristate "CyberPro 2000/2010/5000 support"
@@ -212,7 +199,6 @@ config FB_CYBER2000
212 select FB_CFB_FILLRECT 199 select FB_CFB_FILLRECT
213 select FB_CFB_COPYAREA 200 select FB_CFB_COPYAREA
214 select FB_CFB_IMAGEBLIT 201 select FB_CFB_IMAGEBLIT
215 select FB_SOFT_CURSOR
216 help 202 help
217 This enables support for the Integraphics CyberPro 20x0 and 5000 203 This enables support for the Integraphics CyberPro 20x0 and 5000
218 VGA chips used in the Rebel.com Netwinder and other machines. 204 VGA chips used in the Rebel.com Netwinder and other machines.
@@ -225,7 +211,6 @@ config FB_APOLLO
225 default y 211 default y
226 select FB_CFB_FILLRECT 212 select FB_CFB_FILLRECT
227 select FB_CFB_IMAGEBLIT 213 select FB_CFB_IMAGEBLIT
228 select FB_SOFT_CURSOR
229 214
230config FB_Q40 215config FB_Q40
231 bool 216 bool
@@ -234,12 +219,10 @@ config FB_Q40
234 select FB_CFB_FILLRECT 219 select FB_CFB_FILLRECT
235 select FB_CFB_COPYAREA 220 select FB_CFB_COPYAREA
236 select FB_CFB_IMAGEBLIT 221 select FB_CFB_IMAGEBLIT
237 select FB_SOFT_CURSOR
238 222
239config FB_AMIGA 223config FB_AMIGA
240 tristate "Amiga native chipset support" 224 tristate "Amiga native chipset support"
241 depends on FB && AMIGA 225 depends on FB && AMIGA
242 select FB_SOFT_CURSOR
243 help 226 help
244 This is the frame buffer device driver for the builtin graphics 227 This is the frame buffer device driver for the builtin graphics
245 chipset found in Amigas. 228 chipset found in Amigas.
@@ -279,7 +262,6 @@ config FB_CYBER
279 select FB_CFB_FILLRECT 262 select FB_CFB_FILLRECT
280 select FB_CFB_COPYAREA 263 select FB_CFB_COPYAREA
281 select FB_CFB_IMAGEBLIT 264 select FB_CFB_IMAGEBLIT
282 select FB_SOFT_CURSOR
283 help 265 help
284 This enables support for the Cybervision 64 graphics card from 266 This enables support for the Cybervision 64 graphics card from
285 Phase5. Please note that its use is not all that intuitive (i.e. if 267 Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -294,7 +276,6 @@ config FB_VIRGE
294 select FB_CFB_FILLRECT 276 select FB_CFB_FILLRECT
295 select FB_CFB_COPYAREA 277 select FB_CFB_COPYAREA
296 select FB_CFB_IMAGEBLIT 278 select FB_CFB_IMAGEBLIT
297 select FB_SOFT_CURSOR
298 help 279 help
299 This enables support for the Cybervision 64/3D graphics card from 280 This enables support for the Cybervision 64/3D graphics card from
300 Phase5. Please note that its use is not all that intuitive (i.e. if 281 Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -317,7 +298,6 @@ config FB_FM2
317 select FB_CFB_FILLRECT 298 select FB_CFB_FILLRECT
318 select FB_CFB_COPYAREA 299 select FB_CFB_COPYAREA
319 select FB_CFB_IMAGEBLIT 300 select FB_CFB_IMAGEBLIT
320 select FB_SOFT_CURSOR
321 help 301 help
322 This is the frame buffer device driver for the Amiga FrameMaster 302 This is the frame buffer device driver for the Amiga FrameMaster
323 card from BSC (exhibited 1992 but not shipped as a CBM product). 303 card from BSC (exhibited 1992 but not shipped as a CBM product).
@@ -328,7 +308,6 @@ config FB_ARC
328 select FB_CFB_FILLRECT 308 select FB_CFB_FILLRECT
329 select FB_CFB_COPYAREA 309 select FB_CFB_COPYAREA
330 select FB_CFB_IMAGEBLIT 310 select FB_CFB_IMAGEBLIT
331 select FB_SOFT_CURSOR
332 help 311 help
333 This enables support for the Arc Monochrome LCD board. The board 312 This enables support for the Arc Monochrome LCD board. The board
334 is based on the KS-108 lcd controller and is typically a matrix 313 is based on the KS-108 lcd controller and is typically a matrix
@@ -351,7 +330,6 @@ config FB_OF
351 select FB_CFB_FILLRECT 330 select FB_CFB_FILLRECT
352 select FB_CFB_COPYAREA 331 select FB_CFB_COPYAREA
353 select FB_CFB_IMAGEBLIT 332 select FB_CFB_IMAGEBLIT
354 select FB_SOFT_CURSOR
355 select FB_MACMODES 333 select FB_MACMODES
356 help 334 help
357 Say Y if you want support with Open Firmware for your graphics 335 Say Y if you want support with Open Firmware for your graphics
@@ -363,7 +341,6 @@ config FB_CONTROL
363 select FB_CFB_FILLRECT 341 select FB_CFB_FILLRECT
364 select FB_CFB_COPYAREA 342 select FB_CFB_COPYAREA
365 select FB_CFB_IMAGEBLIT 343 select FB_CFB_IMAGEBLIT
366 select FB_SOFT_CURSOR
367 select FB_MACMODES 344 select FB_MACMODES
368 help 345 help
369 This driver supports a frame buffer for the graphics adapter in the 346 This driver supports a frame buffer for the graphics adapter in the
@@ -375,7 +352,6 @@ config FB_PLATINUM
375 select FB_CFB_FILLRECT 352 select FB_CFB_FILLRECT
376 select FB_CFB_COPYAREA 353 select FB_CFB_COPYAREA
377 select FB_CFB_IMAGEBLIT 354 select FB_CFB_IMAGEBLIT
378 select FB_SOFT_CURSOR
379 select FB_MACMODES 355 select FB_MACMODES
380 help 356 help
381 This driver supports a frame buffer for the "platinum" graphics 357 This driver supports a frame buffer for the "platinum" graphics
@@ -387,7 +363,6 @@ config FB_VALKYRIE
387 select FB_CFB_FILLRECT 363 select FB_CFB_FILLRECT
388 select FB_CFB_COPYAREA 364 select FB_CFB_COPYAREA
389 select FB_CFB_IMAGEBLIT 365 select FB_CFB_IMAGEBLIT
390 select FB_SOFT_CURSOR
391 select FB_MACMODES 366 select FB_MACMODES
392 help 367 help
393 This driver supports a frame buffer for the "valkyrie" graphics 368 This driver supports a frame buffer for the "valkyrie" graphics
@@ -399,42 +374,32 @@ config FB_CT65550
399 select FB_CFB_FILLRECT 374 select FB_CFB_FILLRECT
400 select FB_CFB_COPYAREA 375 select FB_CFB_COPYAREA
401 select FB_CFB_IMAGEBLIT 376 select FB_CFB_IMAGEBLIT
402 select FB_SOFT_CURSOR
403 help 377 help
404 This is the frame buffer device driver for the Chips & Technologies 378 This is the frame buffer device driver for the Chips & Technologies
405 65550 graphics chip in PowerBooks. 379 65550 graphics chip in PowerBooks.
406 380
407config FB_ASILIANT 381config FB_ASILIANT
408 bool "Chips 69000 display support" 382 bool "Asiliant (Chips) 69000 display support"
409 depends on (FB = y) && PCI 383 depends on (FB = y) && PCI
410 select FB_CFB_FILLRECT 384 select FB_CFB_FILLRECT
411 select FB_CFB_COPYAREA 385 select FB_CFB_COPYAREA
412 select FB_CFB_IMAGEBLIT 386 select FB_CFB_IMAGEBLIT
413 select FB_SOFT_CURSOR
414 387
415config FB_IMSTT 388config FB_IMSTT
416 bool "IMS Twin Turbo display support" 389 bool "IMS Twin Turbo display support"
417 depends on (FB = y) && PCI 390 depends on (FB = y) && PCI
418 select FB_CFB_IMAGEBLIT 391 select FB_CFB_IMAGEBLIT
419 select FB_SOFT_CURSOR
420 select FB_MACMODES if PPC 392 select FB_MACMODES if PPC
421 help 393 help
422 The IMS Twin Turbo is a PCI-based frame buffer card bundled with 394 The IMS Twin Turbo is a PCI-based frame buffer card bundled with
423 many Macintosh and compatible computers. 395 many Macintosh and compatible computers.
424 396
425config FB_S3TRIO
426 bool "S3 Trio display support"
427 depends on (FB = y) && PPC && BROKEN
428 help
429 If you have a S3 Trio say Y. Say N for S3 Virge.
430
431config FB_VGA16 397config FB_VGA16
432 tristate "VGA 16-color graphics support" 398 tristate "VGA 16-color graphics support"
433 depends on FB && (X86 || PPC) 399 depends on FB && (X86 || PPC)
434 select FB_CFB_FILLRECT 400 select FB_CFB_FILLRECT
435 select FB_CFB_COPYAREA 401 select FB_CFB_COPYAREA
436 select FB_CFB_IMAGEBLIT 402 select FB_CFB_IMAGEBLIT
437 select FB_SOFT_CURSOR
438 help 403 help
439 This is the frame buffer device driver for VGA 16 color graphic 404 This is the frame buffer device driver for VGA 16 color graphic
440 cards. Say Y if you have such a card. 405 cards. Say Y if you have such a card.
@@ -448,7 +413,6 @@ config FB_STI
448 select FB_CFB_FILLRECT 413 select FB_CFB_FILLRECT
449 select FB_CFB_COPYAREA 414 select FB_CFB_COPYAREA
450 select FB_CFB_IMAGEBLIT 415 select FB_CFB_IMAGEBLIT
451 select FB_SOFT_CURSOR
452 default y 416 default y
453 ---help--- 417 ---help---
454 STI refers to the HP "Standard Text Interface" which is a set of 418 STI refers to the HP "Standard Text Interface" which is a set of
@@ -469,7 +433,6 @@ config FB_MAC
469 select FB_CFB_FILLRECT 433 select FB_CFB_FILLRECT
470 select FB_CFB_COPYAREA 434 select FB_CFB_COPYAREA
471 select FB_CFB_IMAGEBLIT 435 select FB_CFB_IMAGEBLIT
472 select FB_SOFT_CURSOR
473 select FB_MACMODES 436 select FB_MACMODES
474 437
475# bool ' Apple DAFB display support' CONFIG_FB_DAFB 438# bool ' Apple DAFB display support' CONFIG_FB_DAFB
@@ -478,7 +441,6 @@ config FB_HP300
478 depends on (FB = y) && HP300 441 depends on (FB = y) && HP300
479 select FB_CFB_FILLRECT 442 select FB_CFB_FILLRECT
480 select FB_CFB_IMAGEBLIT 443 select FB_CFB_IMAGEBLIT
481 select FB_SOFT_CURSOR
482 default y 444 default y
483 445
484config FB_TGA 446config FB_TGA
@@ -487,7 +449,6 @@ config FB_TGA
487 select FB_CFB_FILLRECT 449 select FB_CFB_FILLRECT
488 select FB_CFB_COPYAREA 450 select FB_CFB_COPYAREA
489 select FB_CFB_IMAGEBLIT 451 select FB_CFB_IMAGEBLIT
490 select FB_SOFT_CURSOR
491 help 452 help
492 This is the frame buffer device driver for generic TGA graphic 453 This is the frame buffer device driver for generic TGA graphic
493 cards. Say Y if you have one of those. 454 cards. Say Y if you have one of those.
@@ -498,7 +459,6 @@ config FB_VESA
498 select FB_CFB_FILLRECT 459 select FB_CFB_FILLRECT
499 select FB_CFB_COPYAREA 460 select FB_CFB_COPYAREA
500 select FB_CFB_IMAGEBLIT 461 select FB_CFB_IMAGEBLIT
501 select FB_SOFT_CURSOR
502 help 462 help
503 This is the frame buffer device driver for generic VESA 2.0 463 This is the frame buffer device driver for generic VESA 2.0
504 compliant graphic cards. The older VESA 1.2 cards are not supported. 464 compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -516,7 +476,6 @@ config FB_HGA
516 select FB_CFB_FILLRECT 476 select FB_CFB_FILLRECT
517 select FB_CFB_COPYAREA 477 select FB_CFB_COPYAREA
518 select FB_CFB_IMAGEBLIT 478 select FB_CFB_IMAGEBLIT
519 select FB_SOFT_CURSOR
520 help 479 help
521 Say Y here if you have a Hercules mono graphics card. 480 Say Y here if you have a Hercules mono graphics card.
522 481
@@ -545,7 +504,6 @@ config FB_SGIVW
545 select FB_CFB_FILLRECT 504 select FB_CFB_FILLRECT
546 select FB_CFB_COPYAREA 505 select FB_CFB_COPYAREA
547 select FB_CFB_IMAGEBLIT 506 select FB_CFB_IMAGEBLIT
548 select FB_SOFT_CURSOR
549 help 507 help
550 SGI Visual Workstation support for framebuffer graphics. 508 SGI Visual Workstation support for framebuffer graphics.
551 509
@@ -555,7 +513,6 @@ config FB_GBE
555 select FB_CFB_FILLRECT 513 select FB_CFB_FILLRECT
556 select FB_CFB_COPYAREA 514 select FB_CFB_COPYAREA
557 select FB_CFB_IMAGEBLIT 515 select FB_CFB_IMAGEBLIT
558 select FB_SOFT_CURSOR
559 help 516 help
560 This is the frame buffer device driver for SGI Graphics Backend. 517 This is the frame buffer device driver for SGI Graphics Backend.
561 This chip is used in SGI O2 and Visual Workstation 320/540. 518 This chip is used in SGI O2 and Visual Workstation 320/540.
@@ -583,7 +540,6 @@ config FB_BW2
583 select FB_CFB_FILLRECT 540 select FB_CFB_FILLRECT
584 select FB_CFB_COPYAREA 541 select FB_CFB_COPYAREA
585 select FB_CFB_IMAGEBLIT 542 select FB_CFB_IMAGEBLIT
586 select FB_SOFT_CURSOR
587 help 543 help
588 This is the frame buffer device driver for the BWtwo frame buffer. 544 This is the frame buffer device driver for the BWtwo frame buffer.
589 545
@@ -592,7 +548,6 @@ config FB_CG3
592 depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) 548 depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
593 select FB_CFB_COPYAREA 549 select FB_CFB_COPYAREA
594 select FB_CFB_IMAGEBLIT 550 select FB_CFB_IMAGEBLIT
595 select FB_SOFT_CURSOR
596 help 551 help
597 This is the frame buffer device driver for the CGthree frame buffer. 552 This is the frame buffer device driver for the CGthree frame buffer.
598 553
@@ -601,7 +556,6 @@ config FB_CG6
601 depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) 556 depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
602 select FB_CFB_COPYAREA 557 select FB_CFB_COPYAREA
603 select FB_CFB_IMAGEBLIT 558 select FB_CFB_IMAGEBLIT
604 select FB_SOFT_CURSOR
605 help 559 help
606 This is the frame buffer device driver for the CGsix (GX, TurboGX) 560 This is the frame buffer device driver for the CGsix (GX, TurboGX)
607 frame buffer. 561 frame buffer.
@@ -612,7 +566,6 @@ config FB_PVR2
612 select FB_CFB_FILLRECT 566 select FB_CFB_FILLRECT
613 select FB_CFB_COPYAREA 567 select FB_CFB_COPYAREA
614 select FB_CFB_IMAGEBLIT 568 select FB_CFB_IMAGEBLIT
615 select FB_SOFT_CURSOR
616 ---help--- 569 ---help---
617 Say Y here if you have a PowerVR 2 card in your box. If you plan to 570 Say Y here if you have a PowerVR 2 card in your box. If you plan to
618 run linux on your Dreamcast, you will have to say Y here. 571 run linux on your Dreamcast, you will have to say Y here.
@@ -634,13 +587,23 @@ config FB_EPSON1355
634 select FB_CFB_FILLRECT 587 select FB_CFB_FILLRECT
635 select FB_CFB_COPYAREA 588 select FB_CFB_COPYAREA
636 select FB_CFB_IMAGEBLIT 589 select FB_CFB_IMAGEBLIT
637 select FB_SOFT_CURSOR
638 help 590 help
639 Build in support for the SED1355 Epson Research Embedded RAMDAC 591 Build in support for the SED1355 Epson Research Embedded RAMDAC
640 LCD/CRT Controller (since redesignated as the S1D13505) as a 592 LCD/CRT Controller (since redesignated as the S1D13505) as a
641 framebuffer. Product specs at 593 framebuffer. Product specs at
642 <http://www.erd.epson.com/vdc/html/products.htm>. 594 <http://www.erd.epson.com/vdc/html/products.htm>.
643 595
596config FB_S1D13XXX
597 tristate "Epson S1D13XXX framebuffer support"
598 depends on FB
599 select FB_CFB_FILLRECT
600 select FB_CFB_COPYAREA
601 select FB_CFB_IMAGEBLIT
602 help
603 Support for S1D13XXX framebuffer device family (currently only
604 working with S1D13806). Product specs at
605 <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
606
644config FB_NVIDIA 607config FB_NVIDIA
645 tristate "nVidia Framebuffer Support" 608 tristate "nVidia Framebuffer Support"
646 depends on FB && PCI 609 depends on FB && PCI
@@ -650,7 +613,6 @@ config FB_NVIDIA
650 select FB_CFB_FILLRECT 613 select FB_CFB_FILLRECT
651 select FB_CFB_COPYAREA 614 select FB_CFB_COPYAREA
652 select FB_CFB_IMAGEBLIT 615 select FB_CFB_IMAGEBLIT
653 select FB_SOFT_CURSOR
654 help 616 help
655 This driver supports graphics boards with the nVidia chips, TNT 617 This driver supports graphics boards with the nVidia chips, TNT
656 and newer. For very old chipsets, such as the RIVA128, then use 618 and newer. For very old chipsets, such as the RIVA128, then use
@@ -662,7 +624,7 @@ config FB_NVIDIA
662 624
663config FB_NVIDIA_I2C 625config FB_NVIDIA_I2C
664 bool "Enable DDC Support" 626 bool "Enable DDC Support"
665 depends on FB_NVIDIA && !PPC_OF 627 depends on FB_NVIDIA
666 help 628 help
667 This enables I2C support for nVidia Chipsets. This is used 629 This enables I2C support for nVidia Chipsets. This is used
668 only for getting EDID information from the attached display 630 only for getting EDID information from the attached display
@@ -768,7 +730,6 @@ config FB_INTEL
768 select FB_CFB_FILLRECT 730 select FB_CFB_FILLRECT
769 select FB_CFB_COPYAREA 731 select FB_CFB_COPYAREA
770 select FB_CFB_IMAGEBLIT 732 select FB_CFB_IMAGEBLIT
771 select FB_SOFT_CURSOR
772 help 733 help
773 This driver supports the on-board graphics built in to the Intel 734 This driver supports the on-board graphics built in to the Intel
774 830M/845G/852GM/855GM/865G chipsets. 735 830M/845G/852GM/855GM/865G chipsets.
@@ -791,7 +752,6 @@ config FB_MATROX
791 select FB_CFB_FILLRECT 752 select FB_CFB_FILLRECT
792 select FB_CFB_COPYAREA 753 select FB_CFB_COPYAREA
793 select FB_CFB_IMAGEBLIT 754 select FB_CFB_IMAGEBLIT
794 select FB_SOFT_CURSOR
795 select FB_TILEBLITTING 755 select FB_TILEBLITTING
796 select FB_MACMODES if PPC_PMAC 756 select FB_MACMODES if PPC_PMAC
797 ---help--- 757 ---help---
@@ -932,7 +892,6 @@ config FB_RADEON_OLD
932 select FB_CFB_FILLRECT 892 select FB_CFB_FILLRECT
933 select FB_CFB_COPYAREA 893 select FB_CFB_COPYAREA
934 select FB_CFB_IMAGEBLIT 894 select FB_CFB_IMAGEBLIT
935 select FB_SOFT_CURSOR
936 select FB_MACMODES if PPC 895 select FB_MACMODES if PPC
937 help 896 help
938 Choose this option if you want to use an ATI Radeon graphics card as 897 Choose this option if you want to use an ATI Radeon graphics card as
@@ -950,7 +909,6 @@ config FB_RADEON
950 select FB_CFB_FILLRECT 909 select FB_CFB_FILLRECT
951 select FB_CFB_COPYAREA 910 select FB_CFB_COPYAREA
952 select FB_CFB_IMAGEBLIT 911 select FB_CFB_IMAGEBLIT
953 select FB_SOFT_CURSOR
954 select FB_MACMODES if PPC_OF 912 select FB_MACMODES if PPC_OF
955 help 913 help
956 Choose this option if you want to use an ATI Radeon graphics card as 914 Choose this option if you want to use an ATI Radeon graphics card as
@@ -988,7 +946,6 @@ config FB_ATY128
988 select FB_CFB_FILLRECT 946 select FB_CFB_FILLRECT
989 select FB_CFB_COPYAREA 947 select FB_CFB_COPYAREA
990 select FB_CFB_IMAGEBLIT 948 select FB_CFB_IMAGEBLIT
991 select FB_SOFT_CURSOR
992 select FB_MACMODES if PPC_PMAC 949 select FB_MACMODES if PPC_PMAC
993 help 950 help
994 This driver supports graphics boards with the ATI Rage128 chips. 951 This driver supports graphics boards with the ATI Rage128 chips.
@@ -1004,7 +961,6 @@ config FB_ATY
1004 select FB_CFB_FILLRECT 961 select FB_CFB_FILLRECT
1005 select FB_CFB_COPYAREA 962 select FB_CFB_COPYAREA
1006 select FB_CFB_IMAGEBLIT 963 select FB_CFB_IMAGEBLIT
1007 select FB_SOFT_CURSOR
1008 select FB_MACMODES if PPC 964 select FB_MACMODES if PPC
1009 help 965 help
1010 This driver supports graphics boards with the ATI Mach64 chips. 966 This driver supports graphics boards with the ATI Mach64 chips.
@@ -1047,6 +1003,12 @@ config FB_ATY_GX
1047 is at 1003 is at
1048 <http://support.ati.com/products/pc/mach64/graphics_xpression.html>. 1004 <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
1049 1005
1006config FB_S3TRIO
1007 bool "S3 Trio display support"
1008 depends on (FB = y) && PPC && BROKEN
1009 help
1010 If you have a S3 Trio say Y. Say N for S3 Virge.
1011
1050config FB_SAVAGE 1012config FB_SAVAGE
1051 tristate "S3 Savage support" 1013 tristate "S3 Savage support"
1052 depends on FB && PCI && EXPERIMENTAL 1014 depends on FB && PCI && EXPERIMENTAL
@@ -1056,7 +1018,6 @@ config FB_SAVAGE
1056 select FB_CFB_FILLRECT 1018 select FB_CFB_FILLRECT
1057 select FB_CFB_COPYAREA 1019 select FB_CFB_COPYAREA
1058 select FB_CFB_IMAGEBLIT 1020 select FB_CFB_IMAGEBLIT
1059 select FB_SOFT_CURSOR
1060 help 1021 help
1061 This driver supports notebooks and computers with S3 Savage PCI/AGP 1022 This driver supports notebooks and computers with S3 Savage PCI/AGP
1062 chips. 1023 chips.
@@ -1093,7 +1054,6 @@ config FB_SIS
1093 select FB_CFB_FILLRECT 1054 select FB_CFB_FILLRECT
1094 select FB_CFB_COPYAREA 1055 select FB_CFB_COPYAREA
1095 select FB_CFB_IMAGEBLIT 1056 select FB_CFB_IMAGEBLIT
1096 select FB_SOFT_CURSOR
1097 help 1057 help
1098 This is the frame buffer device driver for the SiS 300, 315, 330 1058 This is the frame buffer device driver for the SiS 300, 315, 330
1099 and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. 1059 and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
@@ -1123,7 +1083,6 @@ config FB_NEOMAGIC
1123 select FB_CFB_FILLRECT 1083 select FB_CFB_FILLRECT
1124 select FB_CFB_COPYAREA 1084 select FB_CFB_COPYAREA
1125 select FB_CFB_IMAGEBLIT 1085 select FB_CFB_IMAGEBLIT
1126 select FB_SOFT_CURSOR
1127 help 1086 help
1128 This driver supports notebooks with NeoMagic PCI chips. 1087 This driver supports notebooks with NeoMagic PCI chips.
1129 Say Y if you have such a graphics card. 1088 Say Y if you have such a graphics card.
@@ -1137,7 +1096,6 @@ config FB_KYRO
1137 select FB_CFB_FILLRECT 1096 select FB_CFB_FILLRECT
1138 select FB_CFB_COPYAREA 1097 select FB_CFB_COPYAREA
1139 select FB_CFB_IMAGEBLIT 1098 select FB_CFB_IMAGEBLIT
1140 select FB_SOFT_CURSOR
1141 help 1099 help
1142 Say Y here if you have a STG4000 / Kyro / PowerVR 3 based 1100 Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
1143 graphics board. 1101 graphics board.
@@ -1151,7 +1109,6 @@ config FB_3DFX
1151 select FB_CFB_IMAGEBLIT 1109 select FB_CFB_IMAGEBLIT
1152 select FB_CFB_FILLRECT 1110 select FB_CFB_FILLRECT
1153 select FB_CFB_COPYAREA 1111 select FB_CFB_COPYAREA
1154 select FB_SOFT_CURSOR
1155 help 1112 help
1156 This driver supports graphics boards with the 3Dfx Banshee/Voodoo3 1113 This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
1157 chips. Say Y if you have such a graphics board. 1114 chips. Say Y if you have such a graphics board.
@@ -1173,7 +1130,6 @@ config FB_VOODOO1
1173 select FB_CFB_FILLRECT 1130 select FB_CFB_FILLRECT
1174 select FB_CFB_COPYAREA 1131 select FB_CFB_COPYAREA
1175 select FB_CFB_IMAGEBLIT 1132 select FB_CFB_IMAGEBLIT
1176 select FB_SOFT_CURSOR
1177 ---help--- 1133 ---help---
1178 Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or 1134 Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
1179 Voodoo2 (cvg) based graphics card. 1135 Voodoo2 (cvg) based graphics card.
@@ -1190,7 +1146,6 @@ config FB_CYBLA
1190 tristate "Cyberblade/i1 support" 1146 tristate "Cyberblade/i1 support"
1191 depends on FB && PCI 1147 depends on FB && PCI
1192 select FB_CFB_IMAGEBLIT 1148 select FB_CFB_IMAGEBLIT
1193 select FB_SOFT_CURSOR
1194 select VIDEO_SELECT 1149 select VIDEO_SELECT
1195 ---help--- 1150 ---help---
1196 This driver is supposed to support the Trident Cyberblade/i1 1151 This driver is supposed to support the Trident Cyberblade/i1
@@ -1218,7 +1173,6 @@ config FB_TRIDENT
1218 select FB_CFB_FILLRECT 1173 select FB_CFB_FILLRECT
1219 select FB_CFB_COPYAREA 1174 select FB_CFB_COPYAREA
1220 select FB_CFB_IMAGEBLIT 1175 select FB_CFB_IMAGEBLIT
1221 select FB_SOFT_CURSOR
1222 ---help--- 1176 ---help---
1223 This driver is supposed to support graphics boards with the 1177 This driver is supposed to support graphics boards with the
1224 Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops 1178 Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
@@ -1250,38 +1204,6 @@ config FB_PM3
1250 similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000 1204 similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
1251 and maybe other boards. 1205 and maybe other boards.
1252 1206
1253config FB_E1356
1254 tristate "Epson SED1356 framebuffer support"
1255 depends on FB && EXPERIMENTAL && PCI && MIPS
1256
1257config PB1000_CRT
1258 bool "Use CRT on Pb1000 (J65)"
1259 depends on MIPS_PB1000=y && FB_E1356
1260
1261config PB1000_NTSC
1262 bool "Use Compsite NTSC on Pb1000 (J63)"
1263 depends on MIPS_PB1000=y && FB_E1356
1264
1265config PB1000_TFT
1266 bool "Use TFT Panel on Pb1000 (J64)"
1267 depends on MIPS_PB1000=y && FB_E1356
1268
1269config PB1500_CRT
1270 bool "Use CRT on Pb1500 " if MIPS_PB1500=y
1271 depends on FB_E1356
1272
1273config PB1500_CRT
1274 prompt "Use CRT on Pb1100 "
1275 depends on FB_E1356 && MIPS_PB1100=y
1276
1277config PB1500_TFT
1278 bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
1279 depends on FB_E1356
1280
1281config PB1500_TFT
1282 prompt "Use TFT Panel on Pb1100 "
1283 depends on FB_E1356 && MIPS_PB1100=y
1284
1285config FB_AU1100 1207config FB_AU1100
1286 bool "Au1100 LCD Driver" 1208 bool "Au1100 LCD Driver"
1287 depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y 1209 depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y
@@ -1299,7 +1221,6 @@ config FB_FFB
1299 depends on FB_SBUS && SPARC64 1221 depends on FB_SBUS && SPARC64
1300 select FB_CFB_COPYAREA 1222 select FB_CFB_COPYAREA
1301 select FB_CFB_IMAGEBLIT 1223 select FB_CFB_IMAGEBLIT
1302 select FB_SOFT_CURSOR
1303 help 1224 help
1304 This is the frame buffer device driver for the Creator, Creator3D, 1225 This is the frame buffer device driver for the Creator, Creator3D,
1305 and Elite3D graphics boards. 1226 and Elite3D graphics boards.
@@ -1310,7 +1231,6 @@ config FB_TCX
1310 select FB_CFB_FILLRECT 1231 select FB_CFB_FILLRECT
1311 select FB_CFB_COPYAREA 1232 select FB_CFB_COPYAREA
1312 select FB_CFB_IMAGEBLIT 1233 select FB_CFB_IMAGEBLIT
1313 select FB_SOFT_CURSOR
1314 help 1234 help
1315 This is the frame buffer device driver for the TCX 24/8bit frame 1235 This is the frame buffer device driver for the TCX 24/8bit frame
1316 buffer. 1236 buffer.
@@ -1321,7 +1241,6 @@ config FB_CG14
1321 select FB_CFB_FILLRECT 1241 select FB_CFB_FILLRECT
1322 select FB_CFB_COPYAREA 1242 select FB_CFB_COPYAREA
1323 select FB_CFB_IMAGEBLIT 1243 select FB_CFB_IMAGEBLIT
1324 select FB_SOFT_CURSOR
1325 help 1244 help
1326 This is the frame buffer device driver for the CGfourteen frame 1245 This is the frame buffer device driver for the CGfourteen frame
1327 buffer on Desktop SPARCsystems with the SX graphics option. 1246 buffer on Desktop SPARCsystems with the SX graphics option.
@@ -1332,7 +1251,6 @@ config FB_P9100
1332 select FB_CFB_FILLRECT 1251 select FB_CFB_FILLRECT
1333 select FB_CFB_COPYAREA 1252 select FB_CFB_COPYAREA
1334 select FB_CFB_IMAGEBLIT 1253 select FB_CFB_IMAGEBLIT
1335 select FB_SOFT_CURSOR
1336 help 1254 help
1337 This is the frame buffer device driver for the P9100 card 1255 This is the frame buffer device driver for the P9100 card
1338 supported on Sparcbook 3 machines. 1256 supported on Sparcbook 3 machines.
@@ -1343,7 +1261,6 @@ config FB_LEO
1343 select FB_CFB_FILLRECT 1261 select FB_CFB_FILLRECT
1344 select FB_CFB_COPYAREA 1262 select FB_CFB_COPYAREA
1345 select FB_CFB_IMAGEBLIT 1263 select FB_CFB_IMAGEBLIT
1346 select FB_SOFT_CURSOR
1347 help 1264 help
1348 This is the frame buffer device driver for the SBUS-based Sun ZX 1265 This is the frame buffer device driver for the SBUS-based Sun ZX
1349 (leo) frame buffer cards. 1266 (leo) frame buffer cards.
@@ -1358,7 +1275,6 @@ config FB_IGA
1358 select FB_CFB_FILLRECT 1275 select FB_CFB_FILLRECT
1359 select FB_CFB_COPYAREA 1276 select FB_CFB_COPYAREA
1360 select FB_CFB_IMAGEBLIT 1277 select FB_CFB_IMAGEBLIT
1361 select FB_SOFT_CURSOR
1362 help 1278 help
1363 This is the framebuffer device for the INTERGRAPHICS 1680 and 1279 This is the framebuffer device for the INTERGRAPHICS 1680 and
1364 successor frame buffer cards. 1280 successor frame buffer cards.
@@ -1369,7 +1285,6 @@ config FB_HIT
1369 select FB_CFB_FILLRECT 1285 select FB_CFB_FILLRECT
1370 select FB_CFB_COPYAREA 1286 select FB_CFB_COPYAREA
1371 select FB_CFB_IMAGEBLIT 1287 select FB_CFB_IMAGEBLIT
1372 select FB_SOFT_CURSOR
1373 help 1288 help
1374 This is the frame buffer device driver for the Hitachi HD64461 LCD 1289 This is the frame buffer device driver for the Hitachi HD64461 LCD
1375 frame buffer card. 1290 frame buffer card.
@@ -1380,7 +1295,6 @@ config FB_PMAG_AA
1380 select FB_CFB_FILLRECT 1295 select FB_CFB_FILLRECT
1381 select FB_CFB_COPYAREA 1296 select FB_CFB_COPYAREA
1382 select FB_CFB_IMAGEBLIT 1297 select FB_CFB_IMAGEBLIT
1383 select FB_SOFT_CURSOR
1384 help 1298 help
1385 Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) 1299 Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
1386 used mainly in the MIPS-based DECstation series. 1300 used mainly in the MIPS-based DECstation series.
@@ -1391,7 +1305,6 @@ config FB_PMAG_BA
1391 select FB_CFB_FILLRECT 1305 select FB_CFB_FILLRECT
1392 select FB_CFB_COPYAREA 1306 select FB_CFB_COPYAREA
1393 select FB_CFB_IMAGEBLIT 1307 select FB_CFB_IMAGEBLIT
1394 select FB_SOFT_CURSOR
1395 help 1308 help
1396 Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) 1309 Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
1397 used mainly in the MIPS-based DECstation series. 1310 used mainly in the MIPS-based DECstation series.
@@ -1402,7 +1315,6 @@ config FB_PMAGB_B
1402 select FB_CFB_FILLRECT 1315 select FB_CFB_FILLRECT
1403 select FB_CFB_COPYAREA 1316 select FB_CFB_COPYAREA
1404 select FB_CFB_IMAGEBLIT 1317 select FB_CFB_IMAGEBLIT
1405 select FB_SOFT_CURSOR
1406 help 1318 help
1407 Support for the PMAGB-B TURBOchannel framebuffer card used mainly 1319 Support for the PMAGB-B TURBOchannel framebuffer card used mainly
1408 in the MIPS-based DECstation series. The card is currently only 1320 in the MIPS-based DECstation series. The card is currently only
@@ -1414,7 +1326,6 @@ config FB_MAXINE
1414 select FB_CFB_FILLRECT 1326 select FB_CFB_FILLRECT
1415 select FB_CFB_COPYAREA 1327 select FB_CFB_COPYAREA
1416 select FB_CFB_IMAGEBLIT 1328 select FB_CFB_IMAGEBLIT
1417 select FB_SOFT_CURSOR
1418 help 1329 help
1419 Support for the onboard framebuffer (1024x768x8) in the Personal 1330 Support for the onboard framebuffer (1024x768x8) in the Personal
1420 DECstation series (Personal DECstation 5000/20, /25, /33, /50, 1331 DECstation series (Personal DECstation 5000/20, /25, /33, /50,
@@ -1426,7 +1337,6 @@ config FB_TX3912
1426 select FB_CFB_FILLRECT 1337 select FB_CFB_FILLRECT
1427 select FB_CFB_COPYAREA 1338 select FB_CFB_COPYAREA
1428 select FB_CFB_IMAGEBLIT 1339 select FB_CFB_IMAGEBLIT
1429 select FB_SOFT_CURSOR
1430 help 1340 help
1431 The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core 1341 The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core
1432 see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>. 1342 see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
@@ -1439,7 +1349,6 @@ config FB_G364
1439 select FB_CFB_FILLRECT 1349 select FB_CFB_FILLRECT
1440 select FB_CFB_COPYAREA 1350 select FB_CFB_COPYAREA
1441 select FB_CFB_IMAGEBLIT 1351 select FB_CFB_IMAGEBLIT
1442 select FB_SOFT_CURSOR
1443 help 1352 help
1444 The G364 driver is the framebuffer used in MIPS Magnum 4000 and 1353 The G364 driver is the framebuffer used in MIPS Magnum 4000 and
1445 Olivetti M700-10 systems. 1354 Olivetti M700-10 systems.
@@ -1450,7 +1359,6 @@ config FB_68328
1450 select FB_CFB_FILLRECT 1359 select FB_CFB_FILLRECT
1451 select FB_CFB_COPYAREA 1360 select FB_CFB_COPYAREA
1452 select FB_CFB_IMAGEBLIT 1361 select FB_CFB_IMAGEBLIT
1453 select FB_SOFT_CURSOR
1454 help 1362 help
1455 Say Y here if you want to support the built-in frame buffer of 1363 Say Y here if you want to support the built-in frame buffer of
1456 the Motorola 68328 CPU family. 1364 the Motorola 68328 CPU family.
@@ -1461,7 +1369,6 @@ config FB_PXA
1461 select FB_CFB_FILLRECT 1369 select FB_CFB_FILLRECT
1462 select FB_CFB_COPYAREA 1370 select FB_CFB_COPYAREA
1463 select FB_CFB_IMAGEBLIT 1371 select FB_CFB_IMAGEBLIT
1464 select FB_SOFT_CURSOR
1465 ---help--- 1372 ---help---
1466 Frame buffer driver for the built-in LCD controller in the Intel 1373 Frame buffer driver for the built-in LCD controller in the Intel
1467 PXA2x0 processor. 1374 PXA2x0 processor.
@@ -1473,23 +1380,6 @@ config FB_PXA
1473 1380
1474 If unsure, say N. 1381 If unsure, say N.
1475 1382
1476config FB_W100
1477 tristate "W100 frame buffer support"
1478 depends on FB && PXA_SHARPSL
1479 select FB_CFB_FILLRECT
1480 select FB_CFB_COPYAREA
1481 select FB_CFB_IMAGEBLIT
1482 select FB_SOFT_CURSOR
1483 ---help---
1484 Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
1485
1486 This driver is also available as a module ( = code which can be
1487 inserted and removed from the running kernel whenever you want). The
1488 module will be called vfb. If you want to compile it as a module,
1489 say M here and read <file:Documentation/modules.txt>.
1490
1491 If unsure, say N.
1492
1493config FB_PXA_PARAMETERS 1383config FB_PXA_PARAMETERS
1494 bool "PXA LCD command line parameters" 1384 bool "PXA LCD command line parameters"
1495 default n 1385 default n
@@ -1507,17 +1397,21 @@ config FB_PXA_PARAMETERS
1507 1397
1508 <file:Documentation/fb/pxafb.txt> describes the available parameters. 1398 <file:Documentation/fb/pxafb.txt> describes the available parameters.
1509 1399
1510config FB_S1D13XXX 1400config FB_W100
1511 tristate "Epson S1D13XXX framebuffer support" 1401 tristate "W100 frame buffer support"
1512 depends on FB 1402 depends on FB && PXA_SHARPSL
1513 select FB_CFB_FILLRECT 1403 select FB_CFB_FILLRECT
1514 select FB_CFB_COPYAREA 1404 select FB_CFB_COPYAREA
1515 select FB_CFB_IMAGEBLIT 1405 select FB_CFB_IMAGEBLIT
1516 select FB_SOFT_CURSOR 1406 ---help---
1517 help 1407 Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
1518 Support for S1D13XXX framebuffer device family (currently only 1408
1519 working with S1D13806). Product specs at 1409 This driver is also available as a module ( = code which can be
1520 <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm> 1410 inserted and removed from the running kernel whenever you want). The
1411 module will be called vfb. If you want to compile it as a module,
1412 say M here and read <file:Documentation/modules.txt>.
1413
1414 If unsure, say N.
1521 1415
1522config FB_S3C2410 1416config FB_S3C2410
1523 tristate "S3C2410 LCD framebuffer support" 1417 tristate "S3C2410 LCD framebuffer support"
@@ -1525,7 +1419,6 @@ config FB_S3C2410
1525 select FB_CFB_FILLRECT 1419 select FB_CFB_FILLRECT
1526 select FB_CFB_COPYAREA 1420 select FB_CFB_COPYAREA
1527 select FB_CFB_IMAGEBLIT 1421 select FB_CFB_IMAGEBLIT
1528 select FB_SOFT_CURSOR
1529 ---help--- 1422 ---help---
1530 Frame buffer driver for the built-in LCD controller in the Samsung 1423 Frame buffer driver for the built-in LCD controller in the Samsung
1531 S3C2410 processor. 1424 S3C2410 processor.
@@ -1549,7 +1442,6 @@ config FB_VIRTUAL
1549 select FB_CFB_FILLRECT 1442 select FB_CFB_FILLRECT
1550 select FB_CFB_COPYAREA 1443 select FB_CFB_COPYAREA
1551 select FB_CFB_IMAGEBLIT 1444 select FB_CFB_IMAGEBLIT
1552 select FB_SOFT_CURSOR
1553 ---help--- 1445 ---help---
1554 This is a `virtual' frame buffer device. It operates on a chunk of 1446 This is a `virtual' frame buffer device. It operates on a chunk of
1555 unswappable kernel memory instead of on the memory of a graphics 1447 unswappable kernel memory instead of on the memory of a graphics
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 97c5d03ac8d9..aa434e725c0d 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -16,7 +16,6 @@ fb-objs := $(fb-y)
16obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o 16obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
17obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o 17obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
18obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o 18obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
19obj-$(CONFIG_FB_SOFT_CURSOR) += softcursor.o
20obj-$(CONFIG_FB_MACMODES) += macmodes.o 19obj-$(CONFIG_FB_MACMODES) += macmodes.o
21 20
22# Hardware specific drivers go first 21# Hardware specific drivers go first
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 9b6a39348f81..193b482570c7 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -926,7 +926,6 @@ static struct fb_ops acornfb_ops = {
926 .fb_copyarea = cfb_copyarea, 926 .fb_copyarea = cfb_copyarea,
927 .fb_imageblit = cfb_imageblit, 927 .fb_imageblit = cfb_imageblit,
928 .fb_mmap = acornfb_mmap, 928 .fb_mmap = acornfb_mmap,
929 .fb_cursor = soft_cursor,
930}; 929};
931 930
932/* 931/*
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 4fc93dc2b4d3..a3c2c45e29e0 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -333,7 +333,6 @@ static struct fb_ops clcdfb_ops = {
333 .fb_fillrect = cfb_fillrect, 333 .fb_fillrect = cfb_fillrect,
334 .fb_copyarea = cfb_copyarea, 334 .fb_copyarea = cfb_copyarea,
335 .fb_imageblit = cfb_imageblit, 335 .fb_imageblit = cfb_imageblit,
336 .fb_cursor = soft_cursor,
337 .fb_mmap = clcdfb_mmap, 336 .fb_mmap = clcdfb_mmap,
338}; 337};
339 338
@@ -519,7 +518,7 @@ static struct amba_driver clcd_driver = {
519 .id_table = clcdfb_id_table, 518 .id_table = clcdfb_id_table,
520}; 519};
521 520
522int __init amba_clcdfb_init(void) 521static int __init amba_clcdfb_init(void)
523{ 522{
524 if (fb_get_options("ambafb", NULL)) 523 if (fb_get_options("ambafb", NULL))
525 return -ENODEV; 524 return -ENODEV;
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index cf8bb67462dc..d549e215f3c5 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -1185,7 +1185,6 @@ static struct fb_ops amifb_ops = {
1185 .fb_fillrect = amifb_fillrect, 1185 .fb_fillrect = amifb_fillrect,
1186 .fb_copyarea = amifb_copyarea, 1186 .fb_copyarea = amifb_copyarea,
1187 .fb_imageblit = amifb_imageblit, 1187 .fb_imageblit = amifb_imageblit,
1188 .fb_cursor = soft_cursor,
1189 .fb_ioctl = amifb_ioctl, 1188 .fb_ioctl = amifb_ioctl,
1190}; 1189};
1191 1190
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 126daff1c848..a1fc8bbb1090 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -502,10 +502,6 @@ static ssize_t arcfb_write(struct file *file, const char *buf, size_t count,
502 return err; 502 return err;
503} 503}
504 504
505static void arcfb_platform_release(struct device *device)
506{
507}
508
509static struct fb_ops arcfb_ops = { 505static struct fb_ops arcfb_ops = {
510 .owner = THIS_MODULE, 506 .owner = THIS_MODULE,
511 .fb_open = arcfb_open, 507 .fb_open = arcfb_open,
@@ -515,7 +511,6 @@ static struct fb_ops arcfb_ops = {
515 .fb_fillrect = arcfb_fillrect, 511 .fb_fillrect = arcfb_fillrect,
516 .fb_copyarea = arcfb_copyarea, 512 .fb_copyarea = arcfb_copyarea,
517 .fb_imageblit = arcfb_imageblit, 513 .fb_imageblit = arcfb_imageblit,
518 .fb_cursor = soft_cursor,
519 .fb_ioctl = arcfb_ioctl, 514 .fb_ioctl = arcfb_ioctl,
520}; 515};
521 516
@@ -624,13 +619,7 @@ static struct device_driver arcfb_driver = {
624 .remove = arcfb_remove, 619 .remove = arcfb_remove,
625}; 620};
626 621
627static struct platform_device arcfb_device = { 622static struct platform_device *arcfb_device;
628 .name = "arcfb",
629 .id = 0,
630 .dev = {
631 .release = arcfb_platform_release,
632 }
633};
634 623
635static int __init arcfb_init(void) 624static int __init arcfb_init(void)
636{ 625{
@@ -641,9 +630,16 @@ static int __init arcfb_init(void)
641 630
642 ret = driver_register(&arcfb_driver); 631 ret = driver_register(&arcfb_driver);
643 if (!ret) { 632 if (!ret) {
644 ret = platform_device_register(&arcfb_device); 633 arcfb_device = platform_device_alloc("arcfb", 0);
645 if (ret) 634 if (arcfb_device) {
635 ret = platform_device_add(arcfb_device);
636 } else {
637 ret = -ENOMEM;
638 }
639 if (ret) {
640 platform_device_put(arcfb_device);
646 driver_unregister(&arcfb_driver); 641 driver_unregister(&arcfb_driver);
642 }
647 } 643 }
648 return ret; 644 return ret;
649 645
@@ -651,7 +647,7 @@ static int __init arcfb_init(void)
651 647
652static void __exit arcfb_exit(void) 648static void __exit arcfb_exit(void)
653{ 649{
654 platform_device_unregister(&arcfb_device); 650 platform_device_unregister(arcfb_device);
655 driver_unregister(&arcfb_driver); 651 driver_unregister(&arcfb_driver);
656} 652}
657 653
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index f4729f4df8ce..c64de59398f4 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -106,7 +106,6 @@ static struct fb_ops asiliantfb_ops = {
106 .fb_fillrect = cfb_fillrect, 106 .fb_fillrect = cfb_fillrect,
107 .fb_copyarea = cfb_copyarea, 107 .fb_copyarea = cfb_copyarea,
108 .fb_imageblit = cfb_imageblit, 108 .fb_imageblit = cfb_imageblit,
109 .fb_cursor = soft_cursor,
110}; 109};
111 110
112/* Calculate the ratios for the dot clocks without using a single long long 111/* Calculate the ratios for the dot clocks without using a single long long
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
index 13321c689cf6..39ab483fc250 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/aty/ati_ids.h
@@ -150,6 +150,7 @@
150#define PCI_CHIP_RV200_QX 0x5158 150#define PCI_CHIP_RV200_QX 0x5158
151#define PCI_CHIP_RV100_QY 0x5159 151#define PCI_CHIP_RV100_QY 0x5159
152#define PCI_CHIP_RV100_QZ 0x515A 152#define PCI_CHIP_RV100_QZ 0x515A
153#define PCI_CHIP_RN50 0x515E
153#define PCI_CHIP_RAGE128RE 0x5245 154#define PCI_CHIP_RAGE128RE 0x5245
154#define PCI_CHIP_RAGE128RF 0x5246 155#define PCI_CHIP_RAGE128RF 0x5246
155#define PCI_CHIP_RAGE128RG 0x5247 156#define PCI_CHIP_RAGE128RG 0x5247
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index e380ee8b0247..e686185a076d 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -478,7 +478,6 @@ static struct fb_ops aty128fb_ops = {
478 .fb_fillrect = cfb_fillrect, 478 .fb_fillrect = cfb_fillrect,
479 .fb_copyarea = cfb_copyarea, 479 .fb_copyarea = cfb_copyarea,
480 .fb_imageblit = cfb_imageblit, 480 .fb_imageblit = cfb_imageblit,
481 .fb_cursor = soft_cursor,
482}; 481};
483 482
484#ifdef CONFIG_PMAC_BACKLIGHT 483#ifdef CONFIG_PMAC_BACKLIGHT
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 037fe9d32fe3..08edbfcfca58 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -292,7 +292,6 @@ static struct fb_ops atyfb_ops = {
292 .fb_fillrect = atyfb_fillrect, 292 .fb_fillrect = atyfb_fillrect,
293 .fb_copyarea = atyfb_copyarea, 293 .fb_copyarea = atyfb_copyarea,
294 .fb_imageblit = atyfb_imageblit, 294 .fb_imageblit = atyfb_imageblit,
295 .fb_cursor = soft_cursor,
296#ifdef __sparc__ 295#ifdef __sparc__
297 .fb_mmap = atyfb_mmap, 296 .fb_mmap = atyfb_mmap,
298#endif 297#endif
@@ -2157,11 +2156,38 @@ static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
2157 2156
2158static struct fb_info *fb_list = NULL; 2157static struct fb_info *fb_list = NULL;
2159 2158
2159#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2160static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
2161 struct fb_var_screeninfo *var)
2162{
2163 int ret = -EINVAL;
2164
2165 if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2166 *var = default_var;
2167 var->xres = var->xres_virtual = par->lcd_hdisp;
2168 var->right_margin = par->lcd_right_margin;
2169 var->left_margin = par->lcd_hblank_len -
2170 (par->lcd_right_margin + par->lcd_hsync_dly +
2171 par->lcd_hsync_len);
2172 var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
2173 var->yres = var->yres_virtual = par->lcd_vdisp;
2174 var->lower_margin = par->lcd_lower_margin;
2175 var->upper_margin = par->lcd_vblank_len -
2176 (par->lcd_lower_margin + par->lcd_vsync_len);
2177 var->vsync_len = par->lcd_vsync_len;
2178 var->pixclock = par->lcd_pixclock;
2179 ret = 0;
2180 }
2181
2182 return ret;
2183}
2184#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
2185
2160static int __init aty_init(struct fb_info *info, const char *name) 2186static int __init aty_init(struct fb_info *info, const char *name)
2161{ 2187{
2162 struct atyfb_par *par = (struct atyfb_par *) info->par; 2188 struct atyfb_par *par = (struct atyfb_par *) info->par;
2163 const char *ramname = NULL, *xtal; 2189 const char *ramname = NULL, *xtal;
2164 int gtb_memsize; 2190 int gtb_memsize, has_var = 0;
2165 struct fb_var_screeninfo var; 2191 struct fb_var_screeninfo var;
2166 u8 pll_ref_div; 2192 u8 pll_ref_div;
2167 u32 i; 2193 u32 i;
@@ -2469,8 +2495,8 @@ static int __init aty_init(struct fb_info *info, const char *name)
2469 * applies to all Mac video cards 2495 * applies to all Mac video cards
2470 */ 2496 */
2471 if (mode) { 2497 if (mode) {
2472 if (!mac_find_mode(&var, info, mode, 8)) 2498 if (mac_find_mode(&var, info, mode, 8))
2473 var = default_var; 2499 has_var = 1;
2474 } else { 2500 } else {
2475 if (default_vmode == VMODE_CHOOSE) { 2501 if (default_vmode == VMODE_CHOOSE) {
2476 if (M64_HAS(G3_PB_1024x768)) 2502 if (M64_HAS(G3_PB_1024x768))
@@ -2492,20 +2518,23 @@ static int __init aty_init(struct fb_info *info, const char *name)
2492 default_vmode = VMODE_640_480_60; 2518 default_vmode = VMODE_640_480_60;
2493 if (default_cmode < CMODE_8 || default_cmode > CMODE_32) 2519 if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
2494 default_cmode = CMODE_8; 2520 default_cmode = CMODE_8;
2495 if (mac_vmode_to_var(default_vmode, default_cmode, &var)) 2521 if (!mac_vmode_to_var(default_vmode, default_cmode,
2496 var = default_var; 2522 &var))
2523 has_var = 1;
2497 } 2524 }
2498 } else 2525 }
2526
2499#endif /* !CONFIG_PPC */ 2527#endif /* !CONFIG_PPC */
2500 if ( 2528
2501#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) 2529#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
2502 /* On Sparc, unless the user gave a specific mode 2530 if (!atyfb_get_timings_from_lcd(par, &var))
2503 * specification, use the PROM probed values in 2531 has_var = 1;
2504 * default_var.
2505 */
2506 !mode ||
2507#endif 2532#endif
2508 !fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8)) 2533
2534 if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
2535 has_var = 1;
2536
2537 if (!has_var)
2509 var = default_var; 2538 var = default_var;
2510 2539
2511 if (noaccel) 2540 if (noaccel)
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 8a24a66d9ba8..4f01ccc02aa4 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -69,7 +69,6 @@
69#include <linux/pci.h> 69#include <linux/pci.h>
70#include <linux/vmalloc.h> 70#include <linux/vmalloc.h>
71#include <linux/device.h> 71#include <linux/device.h>
72#include <linux/i2c.h>
73 72
74#include <asm/io.h> 73#include <asm/io.h>
75#include <asm/uaccess.h> 74#include <asm/uaccess.h>
@@ -113,6 +112,7 @@ static struct pci_device_id radeonfb_pci_table[] = {
113 /* Radeon VE/7000 */ 112 /* Radeon VE/7000 */
114 CHIP_DEF(PCI_CHIP_RV100_QY, RV100, CHIP_HAS_CRTC2), 113 CHIP_DEF(PCI_CHIP_RV100_QY, RV100, CHIP_HAS_CRTC2),
115 CHIP_DEF(PCI_CHIP_RV100_QZ, RV100, CHIP_HAS_CRTC2), 114 CHIP_DEF(PCI_CHIP_RV100_QZ, RV100, CHIP_HAS_CRTC2),
115 CHIP_DEF(PCI_CHIP_RN50, RV100, CHIP_HAS_CRTC2),
116 /* Radeon IGP320M (U1) */ 116 /* Radeon IGP320M (U1) */
117 CHIP_DEF(PCI_CHIP_RS100_4336, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), 117 CHIP_DEF(PCI_CHIP_RS100_4336, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
118 /* Radeon IGP320 (A3) */ 118 /* Radeon IGP320 (A3) */
@@ -1874,7 +1874,6 @@ static struct fb_ops radeonfb_ops = {
1874 .fb_fillrect = radeonfb_fillrect, 1874 .fb_fillrect = radeonfb_fillrect,
1875 .fb_copyarea = radeonfb_copyarea, 1875 .fb_copyarea = radeonfb_copyarea,
1876 .fb_imageblit = radeonfb_imageblit, 1876 .fb_imageblit = radeonfb_imageblit,
1877 .fb_cursor = soft_cursor,
1878}; 1877};
1879 1878
1880 1879
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 01b8b2f78514..217e00ab4a2d 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -10,9 +10,10 @@
10#include <linux/fb.h> 10#include <linux/fb.h>
11 11
12 12
13#ifdef CONFIG_FB_RADEON_I2C
13#include <linux/i2c.h> 14#include <linux/i2c.h>
14#include <linux/i2c-id.h>
15#include <linux/i2c-algo-bit.h> 15#include <linux/i2c-algo-bit.h>
16#endif
16 17
17#include <asm/io.h> 18#include <asm/io.h>
18 19
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index acc81cb01d56..9d5015e99372 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -5,7 +5,6 @@
5 * 5 *
6 */ 6 */
7 7
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/device.h> 10#include <linux/device.h>
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index 4867498f68e8..bd9a6996aee7 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -48,6 +48,12 @@ static void corgibl_send_intensity(int intensity)
48 corgibl_mach_set_intensity(intensity); 48 corgibl_mach_set_intensity(intensity);
49 49
50 spin_unlock_irqrestore(&bl_lock, flags); 50 spin_unlock_irqrestore(&bl_lock, flags);
51
52 corgi_kick_batt = symbol_get(sharpsl_battery_kick);
53 if (corgi_kick_batt) {
54 corgi_kick_batt();
55 symbol_put(sharpsl_battery_kick);
56 }
51} 57}
52 58
53static void corgibl_blank(int blank) 59static void corgibl_blank(int blank)
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 470e6f0ee4dd..68c690605aa7 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -5,7 +5,6 @@
5 * 5 *
6 */ 6 */
7 7
8#include <linux/version.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/device.h> 10#include <linux/device.h>
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 3d20b2d47d46..f53bf3ba1278 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -51,7 +51,6 @@ static struct fb_ops bw2_ops = {
51 .fb_imageblit = cfb_imageblit, 51 .fb_imageblit = cfb_imageblit,
52 .fb_mmap = bw2_mmap, 52 .fb_mmap = bw2_mmap,
53 .fb_ioctl = bw2_ioctl, 53 .fb_ioctl = bw2_ioctl,
54 .fb_cursor = soft_cursor,
55}; 54};
56 55
57/* OBio addresses for the bwtwo registers */ 56/* OBio addresses for the bwtwo registers */
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 67711f7b11b1..cdc71572cf35 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -349,46 +349,10 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
349 unsigned long __iomem *dst = NULL, *src = NULL; 349 unsigned long __iomem *dst = NULL, *src = NULL;
350 int bits = BITS_PER_LONG, bytes = bits >> 3; 350 int bits = BITS_PER_LONG, bytes = bits >> 3;
351 int dst_idx = 0, src_idx = 0, rev_copy = 0; 351 int dst_idx = 0, src_idx = 0, rev_copy = 0;
352 int x2, y2, vxres, vyres;
353 352
354 if (p->state != FBINFO_STATE_RUNNING) 353 if (p->state != FBINFO_STATE_RUNNING)
355 return; 354 return;
356 355
357 /* We want rotation but lack hardware to do it for us. */
358 if (!p->fbops->fb_rotate && p->var.rotate) {
359 }
360
361 vxres = p->var.xres_virtual;
362 vyres = p->var.yres_virtual;
363
364 if (area->dx > vxres || area->sx > vxres ||
365 area->dy > vyres || area->sy > vyres)
366 return;
367
368 /* clip the destination
369 * We could use hardware clipping but on many cards you get around
370 * hardware clipping by writing to framebuffer directly.
371 */
372 x2 = area->dx + area->width;
373 y2 = area->dy + area->height;
374 dx = area->dx > 0 ? area->dx : 0;
375 dy = area->dy > 0 ? area->dy : 0;
376 x2 = x2 < vxres ? x2 : vxres;
377 y2 = y2 < vyres ? y2 : vyres;
378 width = x2 - dx;
379 height = y2 - dy;
380
381 if ((width==0) ||(height==0))
382 return;
383
384 /* update sx1,sy1 */
385 sx += (dx - area->dx);
386 sy += (dy - area->dy);
387
388 /* the source must be completely inside the virtual screen */
389 if (sx < 0 || sy < 0 || (sx + width) > vxres || (sy + height) > vyres)
390 return;
391
392 /* if the beginning of the target area might overlap with the end of 356 /* if the beginning of the target area might overlap with the end of
393 the source area, be have to copy the area reverse. */ 357 the source area, be have to copy the area reverse. */
394 if ((dy == sy && dx > sx) || (dy > sy)) { 358 if ((dy == sy && dx > sx) || (dy > sy)) {
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index e4fc42b013eb..167d9314e6eb 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -344,7 +344,8 @@ bitfill_unaligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat
344 344
345void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) 345void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
346{ 346{
347 unsigned long x2, y2, vxres, vyres, height, width, pat, fg; 347 unsigned long pat, fg;
348 unsigned long width = rect->width, height = rect->height;
348 int bits = BITS_PER_LONG, bytes = bits >> 3; 349 int bits = BITS_PER_LONG, bytes = bits >> 3;
349 u32 bpp = p->var.bits_per_pixel; 350 u32 bpp = p->var.bits_per_pixel;
350 unsigned long __iomem *dst; 351 unsigned long __iomem *dst;
@@ -353,27 +354,6 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
353 if (p->state != FBINFO_STATE_RUNNING) 354 if (p->state != FBINFO_STATE_RUNNING)
354 return; 355 return;
355 356
356 /* We want rotation but lack hardware to do it for us. */
357 if (!p->fbops->fb_rotate && p->var.rotate) {
358 }
359
360 vxres = p->var.xres_virtual;
361 vyres = p->var.yres_virtual;
362
363 if (!rect->width || !rect->height ||
364 rect->dx > vxres || rect->dy > vyres)
365 return;
366
367 /* We could use hardware clipping but on many cards you get around
368 * hardware clipping by writing to framebuffer directly. */
369
370 x2 = rect->dx + rect->width;
371 y2 = rect->dy + rect->height;
372 x2 = x2 < vxres ? x2 : vxres;
373 y2 = y2 < vyres ? y2 : vyres;
374 width = x2 - rect->dx;
375 height = y2 - rect->dy;
376
377 if (p->fix.visual == FB_VISUAL_TRUECOLOR || 357 if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
378 p->fix.visual == FB_VISUAL_DIRECTCOLOR ) 358 p->fix.visual == FB_VISUAL_DIRECTCOLOR )
379 fg = ((u32 *) (p->pseudo_palette))[rect->color]; 359 fg = ((u32 *) (p->pseudo_palette))[rect->color];
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 4c123abaa843..a7770c4f17d0 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -80,10 +80,12 @@ static u32 cfb_tab32[] = {
80#define LEFT_POS(bpp) (32 - bpp) 80#define LEFT_POS(bpp) (32 - bpp)
81#define SHIFT_HIGH(val, bits) ((val) >> (bits)) 81#define SHIFT_HIGH(val, bits) ((val) >> (bits))
82#define SHIFT_LOW(val, bits) ((val) << (bits)) 82#define SHIFT_LOW(val, bits) ((val) << (bits))
83#define BIT_NR(b) (7 - (b))
83#else 84#else
84#define LEFT_POS(bpp) (0) 85#define LEFT_POS(bpp) (0)
85#define SHIFT_HIGH(val, bits) ((val) << (bits)) 86#define SHIFT_HIGH(val, bits) ((val) << (bits))
86#define SHIFT_LOW(val, bits) ((val) >> (bits)) 87#define SHIFT_LOW(val, bits) ((val) >> (bits))
88#define BIT_NR(b) (b)
87#endif 89#endif
88 90
89static inline void color_imageblit(const struct fb_image *image, 91static inline void color_imageblit(const struct fb_image *image,
@@ -177,7 +179,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
177 179
178 while (j--) { 180 while (j--) {
179 l--; 181 l--;
180 color = (*s & (1 << l)) ? fgcolor : bgcolor; 182 color = (*s & 1 << (BIT_NR(l))) ? fgcolor : bgcolor;
181 color <<= LEFT_POS(bpp); 183 color <<= LEFT_POS(bpp);
182 val |= SHIFT_HIGH(color, shift); 184 val |= SHIFT_HIGH(color, shift);
183 185
@@ -272,33 +274,13 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
272{ 274{
273 u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; 275 u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
274 u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel; 276 u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
275 u32 width = image->width, height = image->height; 277 u32 width = image->width;
276 u32 dx = image->dx, dy = image->dy; 278 u32 dx = image->dx, dy = image->dy;
277 int x2, y2, vxres, vyres;
278 u8 __iomem *dst1; 279 u8 __iomem *dst1;
279 280
280 if (p->state != FBINFO_STATE_RUNNING) 281 if (p->state != FBINFO_STATE_RUNNING)
281 return; 282 return;
282 283
283 vxres = p->var.xres_virtual;
284 vyres = p->var.yres_virtual;
285 /*
286 * We could use hardware clipping but on many cards you get around
287 * hardware clipping by writing to framebuffer directly like we are
288 * doing here.
289 */
290 if (image->dx > vxres || image->dy > vyres)
291 return;
292
293 x2 = image->dx + image->width;
294 y2 = image->dy + image->height;
295 dx = image->dx > 0 ? image->dx : 0;
296 dy = image->dy > 0 ? image->dy : 0;
297 x2 = x2 < vxres ? x2 : vxres;
298 y2 = y2 < vyres ? y2 : vyres;
299 width = x2 - dx;
300 height = y2 - dy;
301
302 bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); 284 bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
303 start_index = bitstart & (32 - 1); 285 start_index = bitstart & (32 - 1);
304 pitch_index = (p->fix.line_length & (bpl - 1)) * 8; 286 pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 18e60b941e21..030d4b13b1c2 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -49,7 +49,6 @@ static struct fb_ops cg14_ops = {
49 .fb_imageblit = cfb_imageblit, 49 .fb_imageblit = cfb_imageblit,
50 .fb_mmap = cg14_mmap, 50 .fb_mmap = cg14_mmap,
51 .fb_ioctl = cg14_ioctl, 51 .fb_ioctl = cg14_ioctl,
52 .fb_cursor = soft_cursor,
53}; 52};
54 53
55#define CG14_MCR_INTENABLE_SHIFT 7 54#define CG14_MCR_INTENABLE_SHIFT 7
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 6e7d8d45dc68..b94eee8c42d5 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -50,7 +50,6 @@ static struct fb_ops cg3_ops = {
50 .fb_imageblit = cfb_imageblit, 50 .fb_imageblit = cfb_imageblit,
51 .fb_mmap = cg3_mmap, 51 .fb_mmap = cg3_mmap,
52 .fb_ioctl = cg3_ioctl, 52 .fb_ioctl = cg3_ioctl,
53 .fb_cursor = soft_cursor,
54}; 53};
55 54
56 55
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 49a2545671d9..414c4409e924 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -54,7 +54,6 @@ static struct fb_ops cg6_ops = {
54 .fb_sync = cg6_sync, 54 .fb_sync = cg6_sync,
55 .fb_mmap = cg6_mmap, 55 .fb_mmap = cg6_mmap,
56 .fb_ioctl = cg6_ioctl, 56 .fb_ioctl = cg6_ioctl,
57 .fb_cursor = soft_cursor,
58}; 57};
59 58
60/* Offset of interesting structures in the OBIO space */ 59/* Offset of interesting structures in the OBIO space */
@@ -654,12 +653,6 @@ static void cg6_chip_init(struct fb_info *info)
654 sbus_writel(0, &fbc->clipminy); 653 sbus_writel(0, &fbc->clipminy);
655 sbus_writel(info->var.xres - 1, &fbc->clipmaxx); 654 sbus_writel(info->var.xres - 1, &fbc->clipmaxx);
656 sbus_writel(info->var.yres - 1, &fbc->clipmaxy); 655 sbus_writel(info->var.yres - 1, &fbc->clipmaxy);
657
658 /* Disable cursor in Brooktree DAC. */
659 sbus_writel(0x06 << 24, &par->bt->addr);
660 tmp = sbus_readl(&par->bt->control);
661 tmp &= ~(0x03 << 24);
662 sbus_writel(tmp, &par->bt->control);
663} 656}
664 657
665struct all_info { 658struct all_info {
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index 4131243cfdf8..bc061d4ec786 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -91,7 +91,6 @@ static struct fb_ops chipsfb_ops = {
91 .fb_fillrect = cfb_fillrect, 91 .fb_fillrect = cfb_fillrect,
92 .fb_copyarea = cfb_copyarea, 92 .fb_copyarea = cfb_copyarea,
93 .fb_imageblit = cfb_imageblit, 93 .fb_imageblit = cfb_imageblit,
94 .fb_cursor = soft_cursor,
95}; 94};
96 95
97static int chipsfb_check_var(struct fb_var_screeninfo *var, 96static int chipsfb_check_var(struct fb_var_screeninfo *var,
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 3a26f9cc8585..2858c5c8ba3c 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -548,7 +548,6 @@ static struct fb_ops cirrusfb_ops = {
548 .fb_fillrect = cirrusfb_fillrect, 548 .fb_fillrect = cirrusfb_fillrect,
549 .fb_copyarea = cirrusfb_copyarea, 549 .fb_copyarea = cirrusfb_copyarea,
550 .fb_imageblit = cirrusfb_imageblit, 550 .fb_imageblit = cirrusfb_imageblit,
551 .fb_cursor = soft_cursor,
552}; 551};
553 552
554/*--- Hardware Specific Routines -------------------------------------------*/ 553/*--- Hardware Specific Routines -------------------------------------------*/
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index 8692e002986b..50b78af0fa24 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -219,7 +219,6 @@ static struct fb_ops clps7111fb_ops = {
219 .fb_fillrect = cfb_fillrect, 219 .fb_fillrect = cfb_fillrect,
220 .fb_copyarea = cfb_copyarea, 220 .fb_copyarea = cfb_copyarea,
221 .fb_imageblit = cfb_imageblit, 221 .fb_imageblit = cfb_imageblit,
222 .fb_cursor = soft_cursor,
223}; 222};
224 223
225static int 224static int
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 6a9ae2b3d1ab..94c5f1392cce 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -98,6 +98,18 @@ config FRAMEBUFFER_CONSOLE
98 tristate "Framebuffer Console support" 98 tristate "Framebuffer Console support"
99 depends on FB 99 depends on FB
100 select CRC32 100 select CRC32
101 help
102 Low-level framebuffer-based console driver.
103
104config FRAMEBUFFER_CONSOLE_ROTATION
105 bool "Framebuffer Console Rotation"
106 depends on FRAMEBUFFER_CONSOLE
107 help
108 Enable display rotation for the framebuffer console. This is done
109 in software and may be significantly slower than a normally oriented
110 display. Note that the rotation is done at the console level only
111 such that other users of the framebuffer will remain normally
112 oriented.
101 113
102config STI_CONSOLE 114config STI_CONSOLE
103 tristate "STI text console" 115 tristate "STI text console"
@@ -203,5 +215,12 @@ config FONT_10x18
203 big letters. It fits between the sun 12x22 and the normal 8x16 font. 215 big letters. It fits between the sun 12x22 and the normal 8x16 font.
204 If other fonts are too big or too small for you, say Y, otherwise say N. 216 If other fonts are too big or too small for you, say Y, otherwise say N.
205 217
218config FONT_RL
219 bool "console Roman Large 8x16 font" if FONTS
220 depends on FRAMEBUFFER_CONSOLE
221 help
222 This is the visually-appealing "RL" console font that is
223 included with the kbd package.
224
206endmenu 225endmenu
207 226
diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
index 42c7b8dcd220..fed600c9ca55 100644
--- a/drivers/video/console/Makefile
+++ b/drivers/video/console/Makefile
@@ -15,6 +15,7 @@ font-objs-$(CONFIG_FONT_10x18) += font_10x18.o
15font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o 15font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
16font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o 16font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
17font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o 17font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
18font-objs-$(CONFIG_FONT_RL) += font_rl.o
18 19
19font-objs += $(font-objs-y) 20font-objs += $(font-objs-y)
20 21
@@ -26,10 +27,14 @@ obj-$(CONFIG_PROM_CONSOLE) += promcon.o promcon_tbl.o
26obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o 27obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o font.o
27obj-$(CONFIG_VGA_CONSOLE) += vgacon.o 28obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
28obj-$(CONFIG_MDA_CONSOLE) += mdacon.o 29obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
29obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o 30obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o
30ifeq ($(CONFIG_FB_TILEBLITTING),y) 31ifeq ($(CONFIG_FB_TILEBLITTING),y)
31obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o 32obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += tileblit.o
32endif 33endif
34ifeq ($(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION),y)
35obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
36 fbcon_ccw.o
37endif
33 38
34obj-$(CONFIG_FB_STI) += sticore.o font.o 39obj-$(CONFIG_FB_STI) += sticore.o font.o
35 40
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
index 9f70e512b88b..e65fc3ef7630 100644
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
@@ -22,35 +22,6 @@
22/* 22/*
23 * Accelerated handlers. 23 * Accelerated handlers.
24 */ 24 */
25#define FBCON_ATTRIBUTE_UNDERLINE 1
26#define FBCON_ATTRIBUTE_REVERSE 2
27#define FBCON_ATTRIBUTE_BOLD 4
28
29static inline int real_y(struct display *p, int ypos)
30{
31 int rows = p->vrows;
32
33 ypos += p->yscroll;
34 return ypos < rows ? ypos : ypos - rows;
35}
36
37
38static inline int get_attribute(struct fb_info *info, u16 c)
39{
40 int attribute = 0;
41
42 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
43 if (attr_underline(c))
44 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
45 if (attr_reverse(c))
46 attribute |= FBCON_ATTRIBUTE_REVERSE;
47 if (attr_bold(c))
48 attribute |= FBCON_ATTRIBUTE_BOLD;
49 }
50
51 return attribute;
52}
53
54static inline void update_attr(u8 *dst, u8 *src, int attribute, 25static inline void update_attr(u8 *dst, u8 *src, int attribute,
55 struct vc_data *vc) 26 struct vc_data *vc)
56{ 27{
@@ -272,6 +243,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
272 int w = (vc->vc_font.width + 7) >> 3, c; 243 int w = (vc->vc_font.width + 7) >> 3, c;
273 int y = real_y(p, vc->vc_y); 244 int y = real_y(p, vc->vc_y);
274 int attribute, use_sw = (vc->vc_cursor_type & 0x10); 245 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
246 int err = 1;
275 char *src; 247 char *src;
276 248
277 cursor.set = 0; 249 cursor.set = 0;
@@ -408,11 +380,27 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
408 cursor.image.depth = 1; 380 cursor.image.depth = 1;
409 cursor.rop = ROP_XOR; 381 cursor.rop = ROP_XOR;
410 382
411 info->fbops->fb_cursor(info, &cursor); 383 if (info->fbops->fb_cursor)
384 err = info->fbops->fb_cursor(info, &cursor);
385
386 if (err)
387 soft_cursor(info, &cursor);
412 388
413 ops->cursor_reset = 0; 389 ops->cursor_reset = 0;
414} 390}
415 391
392static int bit_update_start(struct fb_info *info)
393{
394 struct fbcon_ops *ops = info->fbcon_par;
395 int err;
396
397 err = fb_pan_display(info, &ops->var);
398 ops->var.xoffset = info->var.xoffset;
399 ops->var.yoffset = info->var.yoffset;
400 ops->var.vmode = info->var.vmode;
401 return err;
402}
403
416void fbcon_set_bitops(struct fbcon_ops *ops) 404void fbcon_set_bitops(struct fbcon_ops *ops)
417{ 405{
418 ops->bmove = bit_bmove; 406 ops->bmove = bit_bmove;
@@ -420,6 +408,11 @@ void fbcon_set_bitops(struct fbcon_ops *ops)
420 ops->putcs = bit_putcs; 408 ops->putcs = bit_putcs;
421 ops->clear_margins = bit_clear_margins; 409 ops->clear_margins = bit_clear_margins;
422 ops->cursor = bit_cursor; 410 ops->cursor = bit_cursor;
411 ops->update_start = bit_update_start;
412 ops->rotate_font = NULL;
413
414 if (ops->rotate)
415 fbcon_set_rotate(ops);
423} 416}
424 417
425EXPORT_SYMBOL(fbcon_set_bitops); 418EXPORT_SYMBOL(fbcon_set_bitops);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 0fc8bb499c3f..e7802ffe549a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,6 +107,8 @@ enum {
107}; 107};
108 108
109struct display fb_display[MAX_NR_CONSOLES]; 109struct display fb_display[MAX_NR_CONSOLES];
110EXPORT_SYMBOL(fb_display);
111
110static signed char con2fb_map[MAX_NR_CONSOLES]; 112static signed char con2fb_map[MAX_NR_CONSOLES];
111static signed char con2fb_map_boot[MAX_NR_CONSOLES]; 113static signed char con2fb_map_boot[MAX_NR_CONSOLES];
112static int logo_height; 114static int logo_height;
@@ -130,6 +132,9 @@ static char fontname[40];
130/* current fb_info */ 132/* current fb_info */
131static int info_idx = -1; 133static int info_idx = -1;
132 134
135/* console rotation */
136static int rotate;
137
133static const struct consw fb_con; 138static const struct consw fb_con;
134 139
135#define CM_SOFTBACK (8) 140#define CM_SOFTBACK (8)
@@ -176,7 +181,6 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines);
176/* 181/*
177 * Internal routines 182 * Internal routines
178 */ 183 */
179static __inline__ int real_y(struct display *p, int ypos);
180static __inline__ void ywrap_up(struct vc_data *vc, int count); 184static __inline__ void ywrap_up(struct vc_data *vc, int count);
181static __inline__ void ywrap_down(struct vc_data *vc, int count); 185static __inline__ void ywrap_down(struct vc_data *vc, int count);
182static __inline__ void ypan_up(struct vc_data *vc, int count); 186static __inline__ void ypan_up(struct vc_data *vc, int count);
@@ -189,6 +193,8 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
189 int unit); 193 int unit);
190static void fbcon_redraw_move(struct vc_data *vc, struct display *p, 194static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
191 int line, int count, int dy); 195 int line, int count, int dy);
196static void fbcon_modechanged(struct fb_info *info);
197static void fbcon_set_all_vcs(struct fb_info *info);
192 198
193#ifdef CONFIG_MAC 199#ifdef CONFIG_MAC
194/* 200/*
@@ -203,6 +209,88 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
203} 209}
204#endif 210#endif
205 211
212#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
213static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
214{
215 struct fbcon_ops *ops = info->fbcon_par;
216
217 if (!(info->flags & FBINFO_MISC_TILEBLITTING) &&
218 p->con_rotate < 4)
219 ops->rotate = p->con_rotate;
220 else
221 ops->rotate = 0;
222}
223
224static void fbcon_rotate(struct fb_info *info, u32 rotate)
225{
226 struct fbcon_ops *ops= info->fbcon_par;
227 struct fb_info *fb_info;
228
229 if (!ops || ops->currcon == -1)
230 return;
231
232 fb_info = registered_fb[con2fb_map[ops->currcon]];
233
234 if (info == fb_info) {
235 struct display *p = &fb_display[ops->currcon];
236
237 if (rotate < 4)
238 p->con_rotate = rotate;
239 else
240 p->con_rotate = 0;
241
242 fbcon_modechanged(info);
243 }
244}
245
246static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
247{
248 struct fbcon_ops *ops = info->fbcon_par;
249 struct vc_data *vc;
250 struct display *p;
251 int i;
252
253 if (!ops || ops->currcon < 0 || rotate > 3)
254 return;
255
256 for (i = 0; i < MAX_NR_CONSOLES; i++) {
257 vc = vc_cons[i].d;
258 if (!vc || vc->vc_mode != KD_TEXT ||
259 registered_fb[con2fb_map[i]] != info)
260 continue;
261
262 p = &fb_display[vc->vc_num];
263 p->con_rotate = rotate;
264 }
265
266 fbcon_set_all_vcs(info);
267}
268#else
269static inline void fbcon_set_rotation(struct fb_info *info, struct display *p)
270{
271 struct fbcon_ops *ops = info->fbcon_par;
272
273 ops->rotate = FB_ROTATE_UR;
274}
275
276static void fbcon_rotate(struct fb_info *info, u32 rotate)
277{
278 return;
279}
280
281static void fbcon_rotate_all(struct fb_info *info, u32 rotate)
282{
283 return;
284}
285#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
286
287static int fbcon_get_rotate(struct fb_info *info)
288{
289 struct fbcon_ops *ops = info->fbcon_par;
290
291 return (ops) ? ops->rotate : 0;
292}
293
206static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) 294static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
207{ 295{
208 struct fbcon_ops *ops = info->fbcon_par; 296 struct fbcon_ops *ops = info->fbcon_par;
@@ -281,6 +369,18 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
281 return color; 369 return color;
282} 370}
283 371
372static void fbcon_update_softback(struct vc_data *vc)
373{
374 int l = fbcon_softback_size / vc->vc_size_row;
375
376 if (l > 5)
377 softback_end = softback_buf + l * vc->vc_size_row;
378 else
379 /* Smaller scrollback makes no sense, and 0 would screw
380 the operation totally */
381 softback_top = 0;
382}
383
284static void fb_flashcursor(void *private) 384static void fb_flashcursor(void *private)
285{ 385{
286 struct fb_info *info = private; 386 struct fb_info *info = private;
@@ -410,6 +510,14 @@ static int __init fb_console_setup(char *this_opt)
410 last_fb_vc = simple_strtoul(options, &options, 10) - 1; 510 last_fb_vc = simple_strtoul(options, &options, 10) - 1;
411 fbcon_is_default = 0; 511 fbcon_is_default = 0;
412 } 512 }
513
514 if (!strncmp(options, "rotate:", 7)) {
515 options += 7;
516 if (*options)
517 rotate = simple_strtoul(options, &options, 0);
518 if (rotate > 3)
519 rotate = 0;
520 }
413 } 521 }
414 return 0; 522 return 0;
415} 523}
@@ -468,6 +576,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
468 int cols, int rows, int new_cols, int new_rows) 576 int cols, int rows, int new_cols, int new_rows)
469{ 577{
470 /* Need to make room for the logo */ 578 /* Need to make room for the logo */
579 struct fbcon_ops *ops = info->fbcon_par;
471 int cnt, erase = vc->vc_video_erase_char, step; 580 int cnt, erase = vc->vc_video_erase_char, step;
472 unsigned short *save = NULL, *r, *q; 581 unsigned short *save = NULL, *r, *q;
473 582
@@ -477,7 +586,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
477 */ 586 */
478 if (fb_get_color_depth(&info->var, &info->fix) == 1) 587 if (fb_get_color_depth(&info->var, &info->fix) == 1)
479 erase &= ~0x400; 588 erase &= ~0x400;
480 logo_height = fb_prepare_logo(info); 589 logo_height = fb_prepare_logo(info, ops->rotate);
481 logo_lines = (logo_height + vc->vc_font.height - 1) / 590 logo_lines = (logo_height + vc->vc_font.height - 1) /
482 vc->vc_font.height; 591 vc->vc_font.height;
483 q = (unsigned short *) (vc->vc_origin + 592 q = (unsigned short *) (vc->vc_origin +
@@ -546,16 +655,24 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
546 655
547 if ((info->flags & FBINFO_MISC_TILEBLITTING)) 656 if ((info->flags & FBINFO_MISC_TILEBLITTING))
548 fbcon_set_tileops(vc, info, p, ops); 657 fbcon_set_tileops(vc, info, p, ops);
549 else 658 else {
659 struct display *disp;
660
661 disp = (p) ? p : &fb_display[vc->vc_num];
662 fbcon_set_rotation(info, disp);
550 fbcon_set_bitops(ops); 663 fbcon_set_bitops(ops);
664 }
551} 665}
552#else 666#else
553static void set_blitting_type(struct vc_data *vc, struct fb_info *info, 667static void set_blitting_type(struct vc_data *vc, struct fb_info *info,
554 struct display *p) 668 struct display *p)
555{ 669{
556 struct fbcon_ops *ops = info->fbcon_par; 670 struct fbcon_ops *ops = info->fbcon_par;
671 struct display *disp;
557 672
558 info->flags &= ~FBINFO_MISC_TILEBLITTING; 673 info->flags &= ~FBINFO_MISC_TILEBLITTING;
674 disp = (p) ? p : &fb_display[vc->vc_num];
675 fbcon_set_rotation(info, disp);
559 fbcon_set_bitops(ops); 676 fbcon_set_bitops(ops);
560} 677}
561#endif /* CONFIG_MISC_TILEBLITTING */ 678#endif /* CONFIG_MISC_TILEBLITTING */
@@ -615,9 +732,19 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
615 fbcon_del_cursor_timer(oldinfo); 732 fbcon_del_cursor_timer(oldinfo);
616 kfree(ops->cursor_state.mask); 733 kfree(ops->cursor_state.mask);
617 kfree(ops->cursor_data); 734 kfree(ops->cursor_data);
735 kfree(ops->fontbuffer);
618 kfree(oldinfo->fbcon_par); 736 kfree(oldinfo->fbcon_par);
619 oldinfo->fbcon_par = NULL; 737 oldinfo->fbcon_par = NULL;
620 module_put(oldinfo->fbops->owner); 738 module_put(oldinfo->fbops->owner);
739 /*
740 If oldinfo and newinfo are driving the same hardware,
741 the fb_release() method of oldinfo may attempt to
742 restore the hardware state. This will leave the
743 newinfo in an undefined state. Thus, a call to
744 fb_set_par() may be needed for the newinfo.
745 */
746 if (newinfo->fbops->fb_set_par)
747 newinfo->fbops->fb_set_par(newinfo);
621 } 748 }
622 749
623 return err; 750 return err;
@@ -806,7 +933,9 @@ static const char *fbcon_startup(void)
806 memset(ops, 0, sizeof(struct fbcon_ops)); 933 memset(ops, 0, sizeof(struct fbcon_ops));
807 ops->currcon = -1; 934 ops->currcon = -1;
808 ops->graphics = 1; 935 ops->graphics = 1;
936 ops->cur_rotate = -1;
809 info->fbcon_par = ops; 937 info->fbcon_par = ops;
938 p->con_rotate = rotate;
810 set_blitting_type(vc, info, NULL); 939 set_blitting_type(vc, info, NULL);
811 940
812 if (info->fix.type != FB_TYPE_TEXT) { 941 if (info->fix.type != FB_TYPE_TEXT) {
@@ -845,8 +974,10 @@ static const char *fbcon_startup(void)
845 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ 974 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
846 } 975 }
847 976
848 cols = info->var.xres / vc->vc_font.width; 977 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
849 rows = info->var.yres / vc->vc_font.height; 978 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
979 cols /= vc->vc_font.width;
980 rows /= vc->vc_font.height;
850 vc_resize(vc, cols, rows); 981 vc_resize(vc, cols, rows);
851 982
852 DPRINTK("mode: %s\n", info->fix.id); 983 DPRINTK("mode: %s\n", info->fix.id);
@@ -932,8 +1063,6 @@ static void fbcon_init(struct vc_data *vc, int init)
932 (info->fix.type == FB_TYPE_TEXT)) 1063 (info->fix.type == FB_TYPE_TEXT))
933 logo = 0; 1064 logo = 0;
934 1065
935 info->var.xoffset = info->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
936
937 if (var_to_display(p, &info->var, info)) 1066 if (var_to_display(p, &info->var, info))
938 return; 1067 return;
939 1068
@@ -965,13 +1094,18 @@ static void fbcon_init(struct vc_data *vc, int init)
965 if (!*vc->vc_uni_pagedir_loc) 1094 if (!*vc->vc_uni_pagedir_loc)
966 con_copy_unimap(vc, svc); 1095 con_copy_unimap(vc, svc);
967 1096
1097 ops = info->fbcon_par;
1098 p->con_rotate = rotate;
1099 set_blitting_type(vc, info, NULL);
1100
968 cols = vc->vc_cols; 1101 cols = vc->vc_cols;
969 rows = vc->vc_rows; 1102 rows = vc->vc_rows;
970 new_cols = info->var.xres / vc->vc_font.width; 1103 new_cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
971 new_rows = info->var.yres / vc->vc_font.height; 1104 new_rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1105 new_cols /= vc->vc_font.width;
1106 new_rows /= vc->vc_font.height;
972 vc_resize(vc, new_cols, new_rows); 1107 vc_resize(vc, new_cols, new_rows);
973 1108
974 ops = info->fbcon_par;
975 /* 1109 /*
976 * We must always set the mode. The mode of the previous console 1110 * We must always set the mode. The mode of the previous console
977 * driver could be in the same resolution but we are using different 1111 * driver could be in the same resolution but we are using different
@@ -1007,16 +1141,14 @@ static void fbcon_init(struct vc_data *vc, int init)
1007 if (logo) 1141 if (logo)
1008 fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); 1142 fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
1009 1143
1010 if (vc == svc && softback_buf) { 1144 if (vc == svc && softback_buf)
1011 int l = fbcon_softback_size / vc->vc_size_row; 1145 fbcon_update_softback(vc);
1012 if (l > 5) 1146
1013 softback_end = softback_buf + l * vc->vc_size_row; 1147 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
1014 else { 1148 ops->rotate = FB_ROTATE_UR;
1015 /* Smaller scrollback makes no sense, and 0 would screw 1149 set_blitting_type(vc, info, p);
1016 the operation totally */
1017 softback_top = 0;
1018 }
1019 } 1150 }
1151
1020} 1152}
1021 1153
1022static void fbcon_deinit(struct vc_data *vc) 1154static void fbcon_deinit(struct vc_data *vc)
@@ -1053,15 +1185,6 @@ static void fbcon_deinit(struct vc_data *vc)
1053 * restriction is simplicity & efficiency at the moment. 1185 * restriction is simplicity & efficiency at the moment.
1054 */ 1186 */
1055 1187
1056static __inline__ int real_y(struct display *p, int ypos)
1057{
1058 int rows = p->vrows;
1059
1060 ypos += p->yscroll;
1061 return ypos < rows ? ypos : ypos - rows;
1062}
1063
1064
1065static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, 1188static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
1066 int width) 1189 int width)
1067{ 1190{
@@ -1149,13 +1272,6 @@ static int scrollback_phys_max = 0;
1149static int scrollback_max = 0; 1272static int scrollback_max = 0;
1150static int scrollback_current = 0; 1273static int scrollback_current = 0;
1151 1274
1152static int update_var(int con, struct fb_info *info)
1153{
1154 if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon)
1155 return fb_pan_display(info, &info->var);
1156 return 0;
1157}
1158
1159/* 1275/*
1160 * If no vc is existent yet, just set struct display 1276 * If no vc is existent yet, just set struct display
1161 */ 1277 */
@@ -1165,7 +1281,6 @@ static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *va
1165 struct display *p = &fb_display[unit]; 1281 struct display *p = &fb_display[unit];
1166 struct display *t = &fb_display[fg_console]; 1282 struct display *t = &fb_display[fg_console];
1167 1283
1168 var->xoffset = var->yoffset = p->yscroll = 0;
1169 if (var_to_display(p, var, info)) 1284 if (var_to_display(p, var, info))
1170 return; 1285 return;
1171 1286
@@ -1181,9 +1296,9 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1181 struct display *p = &fb_display[vc->vc_num], *t; 1296 struct display *p = &fb_display[vc->vc_num], *t;
1182 struct vc_data **default_mode = vc->vc_display_fg; 1297 struct vc_data **default_mode = vc->vc_display_fg;
1183 struct vc_data *svc = *default_mode; 1298 struct vc_data *svc = *default_mode;
1299 struct fbcon_ops *ops = info->fbcon_par;
1184 int rows, cols, charcnt = 256; 1300 int rows, cols, charcnt = 256;
1185 1301
1186 var->xoffset = var->yoffset = p->yscroll = 0;
1187 if (var_to_display(p, var, info)) 1302 if (var_to_display(p, var, info))
1188 return; 1303 return;
1189 t = &fb_display[svc->vc_num]; 1304 t = &fb_display[svc->vc_num];
@@ -1200,9 +1315,10 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1200 1315
1201 var->activate = FB_ACTIVATE_NOW; 1316 var->activate = FB_ACTIVATE_NOW;
1202 info->var.activate = var->activate; 1317 info->var.activate = var->activate;
1203 info->var.yoffset = info->var.xoffset = 0; 1318 var->yoffset = info->var.yoffset;
1319 var->xoffset = info->var.xoffset;
1204 fb_set_var(info, var); 1320 fb_set_var(info, var);
1205 1321 ops->var = info->var;
1206 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 1322 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
1207 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 1323 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1208 if (charcnt == 256) { 1324 if (charcnt == 256) {
@@ -1218,38 +1334,32 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
1218 if (!*vc->vc_uni_pagedir_loc) 1334 if (!*vc->vc_uni_pagedir_loc)
1219 con_copy_unimap(vc, svc); 1335 con_copy_unimap(vc, svc);
1220 1336
1221 cols = var->xres / vc->vc_font.width; 1337 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
1222 rows = var->yres / vc->vc_font.height; 1338 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1339 cols /= vc->vc_font.width;
1340 rows /= vc->vc_font.height;
1223 vc_resize(vc, cols, rows); 1341 vc_resize(vc, cols, rows);
1342
1224 if (CON_IS_VISIBLE(vc)) { 1343 if (CON_IS_VISIBLE(vc)) {
1225 update_screen(vc); 1344 update_screen(vc);
1226 if (softback_buf) { 1345 if (softback_buf)
1227 int l = fbcon_softback_size / vc->vc_size_row; 1346 fbcon_update_softback(vc);
1228
1229 if (l > 5)
1230 softback_end = softback_buf + l *
1231 vc->vc_size_row;
1232 else {
1233 /* Smaller scrollback makes no sense, and 0
1234 would screw the operation totally */
1235 softback_top = 0;
1236 }
1237 }
1238 } 1347 }
1239} 1348}
1240 1349
1241static __inline__ void ywrap_up(struct vc_data *vc, int count) 1350static __inline__ void ywrap_up(struct vc_data *vc, int count)
1242{ 1351{
1243 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1352 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1353 struct fbcon_ops *ops = info->fbcon_par;
1244 struct display *p = &fb_display[vc->vc_num]; 1354 struct display *p = &fb_display[vc->vc_num];
1245 1355
1246 p->yscroll += count; 1356 p->yscroll += count;
1247 if (p->yscroll >= p->vrows) /* Deal with wrap */ 1357 if (p->yscroll >= p->vrows) /* Deal with wrap */
1248 p->yscroll -= p->vrows; 1358 p->yscroll -= p->vrows;
1249 info->var.xoffset = 0; 1359 ops->var.xoffset = 0;
1250 info->var.yoffset = p->yscroll * vc->vc_font.height; 1360 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1251 info->var.vmode |= FB_VMODE_YWRAP; 1361 ops->var.vmode |= FB_VMODE_YWRAP;
1252 update_var(vc->vc_num, info); 1362 ops->update_start(info);
1253 scrollback_max += count; 1363 scrollback_max += count;
1254 if (scrollback_max > scrollback_phys_max) 1364 if (scrollback_max > scrollback_phys_max)
1255 scrollback_max = scrollback_phys_max; 1365 scrollback_max = scrollback_phys_max;
@@ -1259,15 +1369,16 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count)
1259static __inline__ void ywrap_down(struct vc_data *vc, int count) 1369static __inline__ void ywrap_down(struct vc_data *vc, int count)
1260{ 1370{
1261 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1371 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1372 struct fbcon_ops *ops = info->fbcon_par;
1262 struct display *p = &fb_display[vc->vc_num]; 1373 struct display *p = &fb_display[vc->vc_num];
1263 1374
1264 p->yscroll -= count; 1375 p->yscroll -= count;
1265 if (p->yscroll < 0) /* Deal with wrap */ 1376 if (p->yscroll < 0) /* Deal with wrap */
1266 p->yscroll += p->vrows; 1377 p->yscroll += p->vrows;
1267 info->var.xoffset = 0; 1378 ops->var.xoffset = 0;
1268 info->var.yoffset = p->yscroll * vc->vc_font.height; 1379 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1269 info->var.vmode |= FB_VMODE_YWRAP; 1380 ops->var.vmode |= FB_VMODE_YWRAP;
1270 update_var(vc->vc_num, info); 1381 ops->update_start(info);
1271 scrollback_max -= count; 1382 scrollback_max -= count;
1272 if (scrollback_max < 0) 1383 if (scrollback_max < 0)
1273 scrollback_max = 0; 1384 scrollback_max = 0;
@@ -1286,10 +1397,11 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1286 0, 0, 0, vc->vc_rows, vc->vc_cols); 1397 0, 0, 0, vc->vc_rows, vc->vc_cols);
1287 p->yscroll -= p->vrows - vc->vc_rows; 1398 p->yscroll -= p->vrows - vc->vc_rows;
1288 } 1399 }
1289 info->var.xoffset = 0; 1400
1290 info->var.yoffset = p->yscroll * vc->vc_font.height; 1401 ops->var.xoffset = 0;
1291 info->var.vmode &= ~FB_VMODE_YWRAP; 1402 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1292 update_var(vc->vc_num, info); 1403 ops->var.vmode &= ~FB_VMODE_YWRAP;
1404 ops->update_start(info);
1293 fbcon_clear_margins(vc, 1); 1405 fbcon_clear_margins(vc, 1);
1294 scrollback_max += count; 1406 scrollback_max += count;
1295 if (scrollback_max > scrollback_phys_max) 1407 if (scrollback_max > scrollback_phys_max)
@@ -1300,6 +1412,7 @@ static __inline__ void ypan_up(struct vc_data *vc, int count)
1300static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) 1412static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1301{ 1413{
1302 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1414 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1415 struct fbcon_ops *ops = info->fbcon_par;
1303 struct display *p = &fb_display[vc->vc_num]; 1416 struct display *p = &fb_display[vc->vc_num];
1304 int redraw = 0; 1417 int redraw = 0;
1305 1418
@@ -1309,12 +1422,13 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count)
1309 redraw = 1; 1422 redraw = 1;
1310 } 1423 }
1311 1424
1312 info->var.xoffset = 0;
1313 info->var.yoffset = p->yscroll * vc->vc_font.height;
1314 info->var.vmode &= ~FB_VMODE_YWRAP;
1315 if (redraw) 1425 if (redraw)
1316 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t); 1426 fbcon_redraw_move(vc, p, t + count, vc->vc_rows - count, t);
1317 update_var(vc->vc_num, info); 1427
1428 ops->var.xoffset = 0;
1429 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1430 ops->var.vmode &= ~FB_VMODE_YWRAP;
1431 ops->update_start(info);
1318 fbcon_clear_margins(vc, 1); 1432 fbcon_clear_margins(vc, 1);
1319 scrollback_max += count; 1433 scrollback_max += count;
1320 if (scrollback_max > scrollback_phys_max) 1434 if (scrollback_max > scrollback_phys_max)
@@ -1334,10 +1448,11 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1334 0, vc->vc_rows, vc->vc_cols); 1448 0, vc->vc_rows, vc->vc_cols);
1335 p->yscroll += p->vrows - vc->vc_rows; 1449 p->yscroll += p->vrows - vc->vc_rows;
1336 } 1450 }
1337 info->var.xoffset = 0; 1451
1338 info->var.yoffset = p->yscroll * vc->vc_font.height; 1452 ops->var.xoffset = 0;
1339 info->var.vmode &= ~FB_VMODE_YWRAP; 1453 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1340 update_var(vc->vc_num, info); 1454 ops->var.vmode &= ~FB_VMODE_YWRAP;
1455 ops->update_start(info);
1341 fbcon_clear_margins(vc, 1); 1456 fbcon_clear_margins(vc, 1);
1342 scrollback_max -= count; 1457 scrollback_max -= count;
1343 if (scrollback_max < 0) 1458 if (scrollback_max < 0)
@@ -1348,6 +1463,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count)
1348static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) 1463static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1349{ 1464{
1350 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 1465 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
1466 struct fbcon_ops *ops = info->fbcon_par;
1351 struct display *p = &fb_display[vc->vc_num]; 1467 struct display *p = &fb_display[vc->vc_num];
1352 int redraw = 0; 1468 int redraw = 0;
1353 1469
@@ -1356,12 +1472,14 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count)
1356 p->yscroll += p->vrows - vc->vc_rows; 1472 p->yscroll += p->vrows - vc->vc_rows;
1357 redraw = 1; 1473 redraw = 1;
1358 } 1474 }
1359 info->var.xoffset = 0; 1475
1360 info->var.yoffset = p->yscroll * vc->vc_font.height;
1361 info->var.vmode &= ~FB_VMODE_YWRAP;
1362 if (redraw) 1476 if (redraw)
1363 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count); 1477 fbcon_redraw_move(vc, p, t, vc->vc_rows - count, t + count);
1364 update_var(vc->vc_num, info); 1478
1479 ops->var.xoffset = 0;
1480 ops->var.yoffset = p->yscroll * vc->vc_font.height;
1481 ops->var.vmode &= ~FB_VMODE_YWRAP;
1482 ops->update_start(info);
1365 fbcon_clear_margins(vc, 1); 1483 fbcon_clear_margins(vc, 1);
1366 scrollback_max -= count; 1484 scrollback_max -= count;
1367 if (scrollback_max < 0) 1485 if (scrollback_max < 0)
@@ -1835,31 +1953,41 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
1835 height, width); 1953 height, width);
1836} 1954}
1837 1955
1838static __inline__ void updatescrollmode(struct display *p, struct fb_info *info, 1956static __inline__ void updatescrollmode(struct display *p,
1957 struct fb_info *info,
1839 struct vc_data *vc) 1958 struct vc_data *vc)
1840{ 1959{
1960 struct fbcon_ops *ops = info->fbcon_par;
1841 int fh = vc->vc_font.height; 1961 int fh = vc->vc_font.height;
1842 int cap = info->flags; 1962 int cap = info->flags;
1843 int good_pan = (cap & FBINFO_HWACCEL_YPAN) 1963 u16 t = 0;
1844 && divides(info->fix.ypanstep, vc->vc_font.height) 1964 int ypan = FBCON_SWAP(ops->rotate, info->fix.ypanstep,
1845 && info->var.yres_virtual > info->var.yres; 1965 info->fix.xpanstep);
1846 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) 1966 int ywrap = FBCON_SWAP(ops->rotate, info->fix.ywrapstep, t);
1847 && divides(info->fix.ywrapstep, vc->vc_font.height) 1967 int yres = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1848 && divides(vc->vc_font.height, info->var.yres_virtual); 1968 int vyres = FBCON_SWAP(ops->rotate, info->var.yres_virtual,
1969 info->var.xres_virtual);
1970 int good_pan = (cap & FBINFO_HWACCEL_YPAN) &&
1971 divides(ypan, vc->vc_font.height) && vyres > yres;
1972 int good_wrap = (cap & FBINFO_HWACCEL_YWRAP) &&
1973 divides(ywrap, vc->vc_font.height) &&
1974 divides(vc->vc_font.height, vyres);
1849 int reading_fast = cap & FBINFO_READS_FAST; 1975 int reading_fast = cap & FBINFO_READS_FAST;
1850 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) && !(cap & FBINFO_HWACCEL_DISABLED); 1976 int fast_copyarea = (cap & FBINFO_HWACCEL_COPYAREA) &&
1851 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) && !(cap & FBINFO_HWACCEL_DISABLED); 1977 !(cap & FBINFO_HWACCEL_DISABLED);
1852 1978 int fast_imageblit = (cap & FBINFO_HWACCEL_IMAGEBLIT) &&
1853 p->vrows = info->var.yres_virtual/fh; 1979 !(cap & FBINFO_HWACCEL_DISABLED);
1854 if (info->var.yres > (fh * (vc->vc_rows + 1))) 1980
1855 p->vrows -= (info->var.yres - (fh * vc->vc_rows)) / fh; 1981 p->vrows = vyres/fh;
1856 if ((info->var.yres % fh) && (info->var.yres_virtual % fh < 1982 if (yres > (fh * (vc->vc_rows + 1)))
1857 info->var.yres % fh)) 1983 p->vrows -= (yres - (fh * vc->vc_rows)) / fh;
1984 if ((yres % fh) && (vyres % fh < yres % fh))
1858 p->vrows--; 1985 p->vrows--;
1859 1986
1860 if (good_wrap || good_pan) { 1987 if (good_wrap || good_pan) {
1861 if (reading_fast || fast_copyarea) 1988 if (reading_fast || fast_copyarea)
1862 p->scrollmode = good_wrap ? SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE; 1989 p->scrollmode = good_wrap ?
1990 SCROLL_WRAP_MOVE : SCROLL_PAN_MOVE;
1863 else 1991 else
1864 p->scrollmode = good_wrap ? SCROLL_REDRAW : 1992 p->scrollmode = good_wrap ? SCROLL_REDRAW :
1865 SCROLL_PAN_REDRAW; 1993 SCROLL_PAN_REDRAW;
@@ -1875,41 +2003,34 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1875 unsigned int height) 2003 unsigned int height)
1876{ 2004{
1877 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2005 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2006 struct fbcon_ops *ops = info->fbcon_par;
1878 struct display *p = &fb_display[vc->vc_num]; 2007 struct display *p = &fb_display[vc->vc_num];
1879 struct fb_var_screeninfo var = info->var; 2008 struct fb_var_screeninfo var = info->var;
1880 int x_diff, y_diff; 2009 int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh;
1881 int fw = vc->vc_font.width; 2010
1882 int fh = vc->vc_font.height; 2011 virt_w = FBCON_SWAP(ops->rotate, width, height);
1883 2012 virt_h = FBCON_SWAP(ops->rotate, height, width);
1884 var.xres = width * fw; 2013 virt_fw = FBCON_SWAP(ops->rotate, vc->vc_font.width,
1885 var.yres = height * fh; 2014 vc->vc_font.height);
2015 virt_fh = FBCON_SWAP(ops->rotate, vc->vc_font.height,
2016 vc->vc_font.width);
2017 var.xres = virt_w * virt_fw;
2018 var.yres = virt_h * virt_fh;
1886 x_diff = info->var.xres - var.xres; 2019 x_diff = info->var.xres - var.xres;
1887 y_diff = info->var.yres - var.yres; 2020 y_diff = info->var.yres - var.yres;
1888 if (x_diff < 0 || x_diff > fw || (y_diff < 0 || y_diff > fh)) { 2021 if (x_diff < 0 || x_diff > virt_fw ||
2022 y_diff < 0 || y_diff > virt_fh) {
1889 struct fb_videomode *mode; 2023 struct fb_videomode *mode;
1890 2024
1891 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); 2025 DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
1892 mode = fb_find_best_mode(&var, &info->modelist); 2026 mode = fb_find_best_mode(&var, &info->modelist);
1893 if (mode == NULL) 2027 if (mode == NULL)
1894 return -EINVAL; 2028 return -EINVAL;
2029 display_to_var(&var, p);
1895 fb_videomode_to_var(&var, mode); 2030 fb_videomode_to_var(&var, mode);
1896 if (width > var.xres/fw || height > var.yres/fh) 2031
2032 if (virt_w > var.xres/virt_fw || virt_h > var.yres/virt_fh)
1897 return -EINVAL; 2033 return -EINVAL;
1898 /*
1899 * The following can probably have any value... Do we need to
1900 * set all of them?
1901 */
1902 var.bits_per_pixel = p->bits_per_pixel;
1903 var.xres_virtual = p->xres_virtual;
1904 var.yres_virtual = p->yres_virtual;
1905 var.accel_flags = p->accel_flags;
1906 var.width = p->width;
1907 var.height = p->height;
1908 var.red = p->red;
1909 var.green = p->green;
1910 var.blue = p->blue;
1911 var.transp = p->transp;
1912 var.nonstd = p->nonstd;
1913 2034
1914 DPRINTK("resize now %ix%i\n", var.xres, var.yres); 2035 DPRINTK("resize now %ix%i\n", var.xres, var.yres);
1915 if (CON_IS_VISIBLE(vc)) { 2036 if (CON_IS_VISIBLE(vc)) {
@@ -1918,6 +2039,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1918 fb_set_var(info, &var); 2039 fb_set_var(info, &var);
1919 } 2040 }
1920 var_to_display(p, &info->var, info); 2041 var_to_display(p, &info->var, info);
2042 ops->var = info->var;
1921 } 2043 }
1922 updatescrollmode(p, info, vc); 2044 updatescrollmode(p, info, vc);
1923 return 0; 2045 return 0;
@@ -1926,26 +2048,20 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
1926static int fbcon_switch(struct vc_data *vc) 2048static int fbcon_switch(struct vc_data *vc)
1927{ 2049{
1928 struct fb_info *info, *old_info = NULL; 2050 struct fb_info *info, *old_info = NULL;
2051 struct fbcon_ops *ops;
1929 struct display *p = &fb_display[vc->vc_num]; 2052 struct display *p = &fb_display[vc->vc_num];
1930 struct fb_var_screeninfo var; 2053 struct fb_var_screeninfo var;
1931 int i, prev_console; 2054 int i, prev_console;
1932 2055
1933 info = registered_fb[con2fb_map[vc->vc_num]]; 2056 info = registered_fb[con2fb_map[vc->vc_num]];
2057 ops = info->fbcon_par;
1934 2058
1935 if (softback_top) { 2059 if (softback_top) {
1936 int l = fbcon_softback_size / vc->vc_size_row;
1937 if (softback_lines) 2060 if (softback_lines)
1938 fbcon_set_origin(vc); 2061 fbcon_set_origin(vc);
1939 softback_top = softback_curr = softback_in = softback_buf; 2062 softback_top = softback_curr = softback_in = softback_buf;
1940 softback_lines = 0; 2063 softback_lines = 0;
1941 2064 fbcon_update_softback(vc);
1942 if (l > 5)
1943 softback_end = softback_buf + l * vc->vc_size_row;
1944 else {
1945 /* Smaller scrollback makes no sense, and 0 would screw
1946 the operation totally */
1947 softback_top = 0;
1948 }
1949 } 2065 }
1950 2066
1951 if (logo_shown >= 0) { 2067 if (logo_shown >= 0) {
@@ -1957,7 +2073,7 @@ static int fbcon_switch(struct vc_data *vc)
1957 logo_shown = FBCON_LOGO_CANSHOW; 2073 logo_shown = FBCON_LOGO_CANSHOW;
1958 } 2074 }
1959 2075
1960 prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; 2076 prev_console = ops->currcon;
1961 if (prev_console != -1) 2077 if (prev_console != -1)
1962 old_info = registered_fb[con2fb_map[prev_console]]; 2078 old_info = registered_fb[con2fb_map[prev_console]];
1963 /* 2079 /*
@@ -1970,9 +2086,9 @@ static int fbcon_switch(struct vc_data *vc)
1970 */ 2086 */
1971 for (i = 0; i < FB_MAX; i++) { 2087 for (i = 0; i < FB_MAX; i++) {
1972 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) { 2088 if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) {
1973 struct fbcon_ops *ops = registered_fb[i]->fbcon_par; 2089 struct fbcon_ops *o = registered_fb[i]->fbcon_par;
1974 2090
1975 ops->currcon = vc->vc_num; 2091 o->currcon = vc->vc_num;
1976 } 2092 }
1977 } 2093 }
1978 memset(&var, 0, sizeof(struct fb_var_screeninfo)); 2094 memset(&var, 0, sizeof(struct fb_var_screeninfo));
@@ -1984,8 +2100,11 @@ static int fbcon_switch(struct vc_data *vc)
1984 * in fb_set_var() 2100 * in fb_set_var()
1985 */ 2101 */
1986 info->var.activate = var.activate; 2102 info->var.activate = var.activate;
1987 info->var.yoffset = info->var.xoffset = p->yscroll = 0; 2103 var.yoffset = info->var.yoffset;
2104 var.xoffset = info->var.xoffset;
2105 var.vmode = info->var.vmode;
1988 fb_set_var(info, &var); 2106 fb_set_var(info, &var);
2107 ops->var = info->var;
1989 2108
1990 if (old_info != NULL && old_info != info) { 2109 if (old_info != NULL && old_info != info) {
1991 if (info->fbops->fb_set_par) 2110 if (info->fbops->fb_set_par)
@@ -1995,7 +2114,12 @@ static int fbcon_switch(struct vc_data *vc)
1995 } 2114 }
1996 2115
1997 set_blitting_type(vc, info, p); 2116 set_blitting_type(vc, info, p);
1998 ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; 2117 ops->cursor_reset = 1;
2118
2119 if (ops->rotate_font && ops->rotate_font(info, vc, p)) {
2120 ops->rotate = FB_ROTATE_UR;
2121 set_blitting_type(vc, info, p);
2122 }
1999 2123
2000 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1); 2124 vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
2001 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; 2125 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
@@ -2015,10 +2139,11 @@ static int fbcon_switch(struct vc_data *vc)
2015 scrollback_phys_max = 0; 2139 scrollback_phys_max = 0;
2016 break; 2140 break;
2017 } 2141 }
2142
2018 scrollback_max = 0; 2143 scrollback_max = 0;
2019 scrollback_current = 0; 2144 scrollback_current = 0;
2020 2145 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2021 update_var(vc->vc_num, info); 2146 ops->update_start(info);
2022 fbcon_set_palette(vc, color_table); 2147 fbcon_set_palette(vc, color_table);
2023 fbcon_clear_margins(vc, 0); 2148 fbcon_clear_margins(vc, 0);
2024 2149
@@ -2026,7 +2151,7 @@ static int fbcon_switch(struct vc_data *vc)
2026 2151
2027 logo_shown = fg_console; 2152 logo_shown = fg_console;
2028 /* This is protected above by initmem_freed */ 2153 /* This is protected above by initmem_freed */
2029 fb_show_logo(info); 2154 fb_show_logo(info, ops->rotate);
2030 update_region(vc, 2155 update_region(vc,
2031 vc->vc_origin + vc->vc_size_row * vc->vc_top, 2156 vc->vc_origin + vc->vc_size_row * vc->vc_top,
2032 vc->vc_size_row * (vc->vc_bottom - 2157 vc->vc_size_row * (vc->vc_bottom -
@@ -2065,6 +2190,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2065 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; 2190 var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
2066 fb_set_var(info, &var); 2191 fb_set_var(info, &var);
2067 ops->graphics = 0; 2192 ops->graphics = 0;
2193 ops->var = info->var;
2068 } 2194 }
2069 } 2195 }
2070 2196
@@ -2153,6 +2279,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2153 const u8 * data, int userfont) 2279 const u8 * data, int userfont)
2154{ 2280{
2155 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2281 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2282 struct fbcon_ops *ops = info->fbcon_par;
2156 struct display *p = &fb_display[vc->vc_num]; 2283 struct display *p = &fb_display[vc->vc_num];
2157 int resize; 2284 int resize;
2158 int cnt; 2285 int cnt;
@@ -2232,20 +2359,15 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
2232 } 2359 }
2233 2360
2234 if (resize) { 2361 if (resize) {
2235 /* reset wrap/pan */ 2362 int cols, rows;
2236 info->var.xoffset = info->var.yoffset = p->yscroll = 0; 2363
2237 vc_resize(vc, info->var.xres / w, info->var.yres / h); 2364 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2238 if (CON_IS_VISIBLE(vc) && softback_buf) { 2365 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2239 int l = fbcon_softback_size / vc->vc_size_row; 2366 cols /= w;
2240 if (l > 5) 2367 rows /= h;
2241 softback_end = 2368 vc_resize(vc, cols, rows);
2242 softback_buf + l * vc->vc_size_row; 2369 if (CON_IS_VISIBLE(vc) && softback_buf)
2243 else { 2370 fbcon_update_softback(vc);
2244 /* Smaller scrollback makes no sense, and 0 would screw
2245 the operation totally */
2246 softback_top = 0;
2247 }
2248 }
2249 } else if (CON_IS_VISIBLE(vc) 2371 } else if (CON_IS_VISIBLE(vc)
2250 && vc->vc_mode == KD_TEXT) { 2372 && vc->vc_mode == KD_TEXT) {
2251 fbcon_clear_margins(vc, 0); 2373 fbcon_clear_margins(vc, 0);
@@ -2471,6 +2593,7 @@ static void fbcon_invert_region(struct vc_data *vc, u16 * p, int cnt)
2471static int fbcon_scrolldelta(struct vc_data *vc, int lines) 2593static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2472{ 2594{
2473 struct fb_info *info = registered_fb[con2fb_map[fg_console]]; 2595 struct fb_info *info = registered_fb[con2fb_map[fg_console]];
2596 struct fbcon_ops *ops = info->fbcon_par;
2474 struct display *p = &fb_display[fg_console]; 2597 struct display *p = &fb_display[fg_console];
2475 int offset, limit, scrollback_old; 2598 int offset, limit, scrollback_old;
2476 2599
@@ -2547,9 +2670,11 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines)
2547 offset += limit; 2670 offset += limit;
2548 else if (offset >= limit) 2671 else if (offset >= limit)
2549 offset -= limit; 2672 offset -= limit;
2550 info->var.xoffset = 0; 2673
2551 info->var.yoffset = offset * vc->vc_font.height; 2674 ops->var.xoffset = 0;
2552 update_var(vc->vc_num, info); 2675 ops->var.yoffset = offset * vc->vc_font.height;
2676 ops->update_start(info);
2677
2553 if (!scrollback_current) 2678 if (!scrollback_current)
2554 fbcon_cursor(vc, CM_DRAW); 2679 fbcon_cursor(vc, CM_DRAW);
2555 return 0; 2680 return 0;
@@ -2597,34 +2722,29 @@ static void fbcon_modechanged(struct fb_info *info)
2597 if (!ops || ops->currcon < 0) 2722 if (!ops || ops->currcon < 0)
2598 return; 2723 return;
2599 vc = vc_cons[ops->currcon].d; 2724 vc = vc_cons[ops->currcon].d;
2600 if (vc->vc_mode != KD_TEXT || registered_fb[con2fb_map[ops->currcon]] != info) 2725 if (vc->vc_mode != KD_TEXT ||
2726 registered_fb[con2fb_map[ops->currcon]] != info)
2601 return; 2727 return;
2602 2728
2603 p = &fb_display[vc->vc_num]; 2729 p = &fb_display[vc->vc_num];
2604 2730 set_blitting_type(vc, info, p);
2605 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2606 2731
2607 if (CON_IS_VISIBLE(vc)) { 2732 if (CON_IS_VISIBLE(vc)) {
2608 var_to_display(p, &info->var, info); 2733 var_to_display(p, &info->var, info);
2609 cols = info->var.xres / vc->vc_font.width; 2734 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2610 rows = info->var.yres / vc->vc_font.height; 2735 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2736 cols /= vc->vc_font.width;
2737 rows /= vc->vc_font.height;
2611 vc_resize(vc, cols, rows); 2738 vc_resize(vc, cols, rows);
2612 updatescrollmode(p, info, vc); 2739 updatescrollmode(p, info, vc);
2613 scrollback_max = 0; 2740 scrollback_max = 0;
2614 scrollback_current = 0; 2741 scrollback_current = 0;
2615 update_var(vc->vc_num, info); 2742 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2743 ops->update_start(info);
2616 fbcon_set_palette(vc, color_table); 2744 fbcon_set_palette(vc, color_table);
2617 update_screen(vc); 2745 update_screen(vc);
2618 if (softback_buf) { 2746 if (softback_buf)
2619 int l = fbcon_softback_size / vc->vc_size_row; 2747 fbcon_update_softback(vc);
2620 if (l > 5)
2621 softback_end = softback_buf + l * vc->vc_size_row;
2622 else {
2623 /* Smaller scrollback makes no sense, and 0
2624 would screw the operation totally */
2625 softback_top = 0;
2626 }
2627 }
2628 } 2748 }
2629} 2749}
2630 2750
@@ -2645,30 +2765,24 @@ static void fbcon_set_all_vcs(struct fb_info *info)
2645 continue; 2765 continue;
2646 2766
2647 p = &fb_display[vc->vc_num]; 2767 p = &fb_display[vc->vc_num];
2648 2768 set_blitting_type(vc, info, p);
2649 info->var.xoffset = info->var.yoffset = p->yscroll = 0;
2650 var_to_display(p, &info->var, info); 2769 var_to_display(p, &info->var, info);
2651 cols = info->var.xres / vc->vc_font.width; 2770 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
2652 rows = info->var.yres / vc->vc_font.height; 2771 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
2772 cols /= vc->vc_font.width;
2773 rows /= vc->vc_font.height;
2653 vc_resize(vc, cols, rows); 2774 vc_resize(vc, cols, rows);
2654 2775
2655 if (CON_IS_VISIBLE(vc)) { 2776 if (CON_IS_VISIBLE(vc)) {
2656 updatescrollmode(p, info, vc); 2777 updatescrollmode(p, info, vc);
2657 scrollback_max = 0; 2778 scrollback_max = 0;
2658 scrollback_current = 0; 2779 scrollback_current = 0;
2659 update_var(vc->vc_num, info); 2780 ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
2781 ops->update_start(info);
2660 fbcon_set_palette(vc, color_table); 2782 fbcon_set_palette(vc, color_table);
2661 update_screen(vc); 2783 update_screen(vc);
2662 if (softback_buf) { 2784 if (softback_buf)
2663 int l = fbcon_softback_size / vc->vc_size_row; 2785 fbcon_update_softback(vc);
2664 if (l > 5)
2665 softback_end = softback_buf + l * vc->vc_size_row;
2666 else {
2667 /* Smaller scrollback makes no sense, and 0
2668 would screw the operation totally */
2669 softback_top = 0;
2670 }
2671 }
2672 } 2786 }
2673 } 2787 }
2674} 2788}
@@ -2758,7 +2872,8 @@ static void fbcon_new_modelist(struct fb_info *info)
2758 continue; 2872 continue;
2759 vc = vc_cons[i].d; 2873 vc = vc_cons[i].d;
2760 display_to_var(&var, &fb_display[i]); 2874 display_to_var(&var, &fb_display[i]);
2761 mode = fb_find_nearest_mode(&var, &info->modelist); 2875 mode = fb_find_nearest_mode(fb_display[i].mode,
2876 &info->modelist);
2762 fb_videomode_to_var(&var, mode); 2877 fb_videomode_to_var(&var, mode);
2763 2878
2764 if (vc) 2879 if (vc)
@@ -2813,6 +2928,14 @@ static int fbcon_event_notify(struct notifier_block *self,
2813 case FB_EVENT_NEW_MODELIST: 2928 case FB_EVENT_NEW_MODELIST:
2814 fbcon_new_modelist(info); 2929 fbcon_new_modelist(info);
2815 break; 2930 break;
2931 case FB_EVENT_SET_CON_ROTATE:
2932 fbcon_rotate(info, *(int *)event->data);
2933 break;
2934 case FB_EVENT_GET_CON_ROTATE:
2935 ret = fbcon_get_rotate(info);
2936 break;
2937 case FB_EVENT_SET_CON_ROTATE_ALL:
2938 fbcon_rotate_all(info, *(int *)event->data);
2816 } 2939 }
2817 2940
2818 return ret; 2941 return ret;
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 0738cd62def2..accfd7bd8e93 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -27,15 +27,15 @@
27 */ 27 */
28 28
29struct display { 29struct display {
30 /* Filled in by the frame buffer device */
31 u_short inverse; /* != 0 text black on white as default */
32 /* Filled in by the low-level console driver */ 30 /* Filled in by the low-level console driver */
33 const u_char *fontdata; 31 const u_char *fontdata;
34 int userfont; /* != 0 if fontdata kmalloc()ed */ 32 int userfont; /* != 0 if fontdata kmalloc()ed */
35 u_short scrollmode; /* Scroll Method */ 33 u_short scrollmode; /* Scroll Method */
34 u_short inverse; /* != 0 text black on white as default */
36 short yscroll; /* Hardware scrolling */ 35 short yscroll; /* Hardware scrolling */
37 int vrows; /* number of virtual rows */ 36 int vrows; /* number of virtual rows */
38 int cursor_shape; 37 int cursor_shape;
38 int con_rotate;
39 u32 xres_virtual; 39 u32 xres_virtual;
40 u32 yres_virtual; 40 u32 yres_virtual;
41 u32 height; 41 u32 height;
@@ -52,6 +52,8 @@ struct display {
52 struct fb_videomode *mode; 52 struct fb_videomode *mode;
53}; 53};
54 54
55extern struct display fb_display[];
56
55struct fbcon_ops { 57struct fbcon_ops {
56 void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy, 58 void (*bmove)(struct vc_data *vc, struct fb_info *info, int sy,
57 int sx, int dy, int dx, int height, int width); 59 int sx, int dy, int dx, int height, int width);
@@ -63,8 +65,12 @@ struct fbcon_ops {
63 void (*clear_margins)(struct vc_data *vc, struct fb_info *info, 65 void (*clear_margins)(struct vc_data *vc, struct fb_info *info,
64 int bottom_only); 66 int bottom_only);
65 void (*cursor)(struct vc_data *vc, struct fb_info *info, 67 void (*cursor)(struct vc_data *vc, struct fb_info *info,
66 struct display *p, int mode, int softback_lines, int fg, int bg); 68 struct display *p, int mode, int softback_lines,
67 69 int fg, int bg);
70 int (*update_start)(struct fb_info *info);
71 int (*rotate_font)(struct fb_info *info, struct vc_data *vc,
72 struct display *p);
73 struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */
68 struct timer_list cursor_timer; /* Cursor timer */ 74 struct timer_list cursor_timer; /* Cursor timer */
69 struct fb_cursor cursor_state; 75 struct fb_cursor cursor_state;
70 int currcon; /* Current VC. */ 76 int currcon; /* Current VC. */
@@ -73,7 +79,12 @@ struct fbcon_ops {
73 int blank_state; 79 int blank_state;
74 int graphics; 80 int graphics;
75 int flags; 81 int flags;
82 int rotate;
83 int cur_rotate;
76 char *cursor_data; 84 char *cursor_data;
85 u8 *fontbuffer;
86 u8 *fontdata;
87 u32 fd_size;
77}; 88};
78 /* 89 /*
79 * Attribute Decoding 90 * Attribute Decoding
@@ -167,5 +178,48 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
167 struct display *p, struct fbcon_ops *ops); 178 struct display *p, struct fbcon_ops *ops);
168#endif 179#endif
169extern void fbcon_set_bitops(struct fbcon_ops *ops); 180extern void fbcon_set_bitops(struct fbcon_ops *ops);
181extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
182
183#define FBCON_ATTRIBUTE_UNDERLINE 1
184#define FBCON_ATTRIBUTE_REVERSE 2
185#define FBCON_ATTRIBUTE_BOLD 4
186
187static inline int real_y(struct display *p, int ypos)
188{
189 int rows = p->vrows;
190
191 ypos += p->yscroll;
192 return ypos < rows ? ypos : ypos - rows;
193}
194
195
196static inline int get_attribute(struct fb_info *info, u16 c)
197{
198 int attribute = 0;
199
200 if (fb_get_color_depth(&info->var, &info->fix) == 1) {
201 if (attr_underline(c))
202 attribute |= FBCON_ATTRIBUTE_UNDERLINE;
203 if (attr_reverse(c))
204 attribute |= FBCON_ATTRIBUTE_REVERSE;
205 if (attr_bold(c))
206 attribute |= FBCON_ATTRIBUTE_BOLD;
207 }
208
209 return attribute;
210}
211
212#define FBCON_SWAP(i,r,v) ({ \
213 typeof(r) _r = (r); \
214 typeof(v) _v = (v); \
215 (void) (&_r == &_v); \
216 (i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; })
217
218#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
219extern void fbcon_set_rotate(struct fbcon_ops *ops);
220#else
221#define fbcon_set_rotate(x) do {} while(0)
222#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
170 223
171#endif /* _VIDEO_FBCON_H */ 224#endif /* _VIDEO_FBCON_H */
225
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
new file mode 100644
index 000000000000..680aabab73c5
--- /dev/null
+++ b/drivers/video/console/fbcon_ccw.c
@@ -0,0 +1,428 @@
1/*
2 * linux/drivers/video/console/fbcon_ccw.c -- Software Rotation - 270 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 270 degrees
23 */
24
25static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.height + 7) >> 3;
30 int mod = vc->vc_font.height % 8;
31 u8 c, msk = ~(0xff << offset), msk1 = 0;
32
33 if (mod)
34 msk <<= (8 - mod);
35
36 if (offset > mod)
37 set_bit(FBCON_BIT(7), (void *)&msk1);
38
39 for (i = 0; i < vc->vc_font.width; i++) {
40 for (j = 0; j < width; j++) {
41 c = *src;
42
43 if (attribute & FBCON_ATTRIBUTE_UNDERLINE) {
44 if (j == width - 1)
45 c |= msk;
46
47 if (msk1 && j == width - 2)
48 c |= msk1;
49 }
50
51 if (attribute & FBCON_ATTRIBUTE_BOLD && i)
52 *(dst - width) |= c;
53
54 if (attribute & FBCON_ATTRIBUTE_REVERSE)
55 c = ~c;
56 src++;
57 *dst++ = c;
58 }
59 }
60}
61
62
63static void ccw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
64 int sx, int dy, int dx, int height, int width)
65{
66 struct display *p = &fb_display[vc->vc_num];
67 struct fb_copyarea area;
68 u32 vyres = GETVYRES(p->scrollmode, info);
69
70 area.sx = sy * vc->vc_font.height;
71 area.sy = vyres - ((sx + width) * vc->vc_font.width);
72 area.dx = dy * vc->vc_font.height;
73 area.dy = vyres - ((dx + width) * vc->vc_font.width);
74 area.width = height * vc->vc_font.height;
75 area.height = width * vc->vc_font.width;
76
77 info->fbops->fb_copyarea(info, &area);
78}
79
80static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy,
81 int sx, int height, int width)
82{
83 struct display *p = &fb_display[vc->vc_num];
84 struct fb_fillrect region;
85 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
86 u32 vyres = GETVYRES(p->scrollmode, info);
87
88 region.color = attr_bgcol_ec(bgshift,vc);
89 region.dx = sy * vc->vc_font.height;
90 region.dy = vyres - ((sx + width) * vc->vc_font.width);
91 region.height = width * vc->vc_font.width;
92 region.width = height * vc->vc_font.height;
93 region.rop = ROP_COPY;
94
95 info->fbops->fb_fillrect(info, &region);
96}
97
98static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
99 const u16 *s, u32 attr, u32 cnt,
100 u32 d_pitch, u32 s_pitch, u32 cellsize,
101 struct fb_image *image, u8 *buf, u8 *dst)
102{
103 struct fbcon_ops *ops = info->fbcon_par;
104 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
105 u32 idx = (vc->vc_font.height + 7) >> 3;
106 u8 *src;
107
108 while (cnt--) {
109 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
110
111 if (attr) {
112 ccw_update_attr(buf, src, attr, vc);
113 src = buf;
114 }
115
116 if (likely(idx == 1))
117 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
118 vc->vc_font.width);
119 else
120 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
121 vc->vc_font.width);
122
123 dst += d_pitch * vc->vc_font.width;
124 }
125
126 info->fbops->fb_imageblit(info, image);
127}
128
129static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
130 const unsigned short *s, int count, int yy, int xx,
131 int fg, int bg)
132{
133 struct fb_image image;
134 struct display *p = &fb_display[vc->vc_num];
135 struct fbcon_ops *ops = info->fbcon_par;
136 u32 width = (vc->vc_font.height + 7)/8;
137 u32 cellsize = width * vc->vc_font.width;
138 u32 maxcnt = info->pixmap.size/cellsize;
139 u32 scan_align = info->pixmap.scan_align - 1;
140 u32 buf_align = info->pixmap.buf_align - 1;
141 u32 cnt, pitch, size;
142 u32 attribute = get_attribute(info, scr_readw(s));
143 u8 *dst, *buf = NULL;
144 u32 vyres = GETVYRES(p->scrollmode, info);
145
146 if (!ops->fontbuffer)
147 return;
148
149 image.fg_color = fg;
150 image.bg_color = bg;
151 image.dx = yy * vc->vc_font.height;
152 image.dy = vyres - ((xx + count) * vc->vc_font.width);
153 image.width = vc->vc_font.height;
154 image.depth = 1;
155
156 if (attribute) {
157 buf = kmalloc(cellsize, GFP_KERNEL);
158 if (!buf)
159 return;
160 }
161
162 s += count - 1;
163
164 while (count) {
165 if (count > maxcnt)
166 cnt = maxcnt;
167 else
168 cnt = count;
169
170 image.height = vc->vc_font.width * cnt;
171 pitch = ((image.width + 7) >> 3) + scan_align;
172 pitch &= ~scan_align;
173 size = pitch * image.height + buf_align;
174 size &= ~buf_align;
175 dst = fb_get_buffer_offset(info, &info->pixmap, size);
176 image.data = dst;
177 ccw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
178 width, cellsize, &image, buf, dst);
179 image.dy += image.height;
180 count -= cnt;
181 s -= cnt;
182 }
183
184 /* buf is always NULL except when in monochrome mode, so in this case
185 it's a gain to check buf against NULL even though kfree() handles
186 NULL pointers just fine */
187 if (unlikely(buf))
188 kfree(buf);
189
190}
191
192static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info,
193 int bottom_only)
194{
195 unsigned int cw = vc->vc_font.width;
196 unsigned int ch = vc->vc_font.height;
197 unsigned int rw = info->var.yres - (vc->vc_cols*cw);
198 unsigned int bh = info->var.xres - (vc->vc_rows*ch);
199 unsigned int bs = vc->vc_rows*ch;
200 struct fb_fillrect region;
201 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
202
203 region.color = attr_bgcol_ec(bgshift,vc);
204 region.rop = ROP_COPY;
205
206 if (rw && !bottom_only) {
207 region.dx = 0;
208 region.dy = info->var.yoffset;
209 region.height = rw;
210 region.width = info->var.xres_virtual;
211 info->fbops->fb_fillrect(info, &region);
212 }
213
214 if (bh) {
215 region.dx = info->var.xoffset + bs;
216 region.dy = 0;
217 region.height = info->var.yres_virtual;
218 region.width = bh;
219 info->fbops->fb_fillrect(info, &region);
220 }
221}
222
223static void ccw_cursor(struct vc_data *vc, struct fb_info *info,
224 struct display *p, int mode, int softback_lines,
225 int fg, int bg)
226{
227 struct fb_cursor cursor;
228 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
229 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
230 int w = (vc->vc_font.height + 7) >> 3, c;
231 int y = real_y(p, vc->vc_y);
232 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
233 int err = 1, dx, dy;
234 char *src;
235 u32 vyres = GETVYRES(p->scrollmode, info);
236
237 if (!ops->fontbuffer)
238 return;
239
240 cursor.set = 0;
241
242 if (softback_lines) {
243 if (y + softback_lines >= vc->vc_rows) {
244 mode = CM_ERASE;
245 ops->cursor_flash = 0;
246 return;
247 } else
248 y += softback_lines;
249 }
250
251 c = scr_readw((u16 *) vc->vc_pos);
252 attribute = get_attribute(info, c);
253 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
254
255 if (ops->cursor_state.image.data != src ||
256 ops->cursor_reset) {
257 ops->cursor_state.image.data = src;
258 cursor.set |= FB_CUR_SETIMAGE;
259 }
260
261 if (attribute) {
262 u8 *dst;
263
264 dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
265 if (!dst)
266 return;
267 kfree(ops->cursor_data);
268 ops->cursor_data = dst;
269 ccw_update_attr(dst, src, attribute, vc);
270 src = dst;
271 }
272
273 if (ops->cursor_state.image.fg_color != fg ||
274 ops->cursor_state.image.bg_color != bg ||
275 ops->cursor_reset) {
276 ops->cursor_state.image.fg_color = fg;
277 ops->cursor_state.image.bg_color = bg;
278 cursor.set |= FB_CUR_SETCMAP;
279 }
280
281 if (ops->cursor_state.image.height != vc->vc_font.width ||
282 ops->cursor_state.image.width != vc->vc_font.height ||
283 ops->cursor_reset) {
284 ops->cursor_state.image.height = vc->vc_font.width;
285 ops->cursor_state.image.width = vc->vc_font.height;
286 cursor.set |= FB_CUR_SETSIZE;
287 }
288
289 dx = y * vc->vc_font.height;
290 dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width);
291
292 if (ops->cursor_state.image.dx != dx ||
293 ops->cursor_state.image.dy != dy ||
294 ops->cursor_reset) {
295 ops->cursor_state.image.dx = dx;
296 ops->cursor_state.image.dy = dy;
297 cursor.set |= FB_CUR_SETPOS;
298 }
299
300 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
301 ops->cursor_reset) {
302 ops->cursor_state.hot.x = cursor.hot.y = 0;
303 cursor.set |= FB_CUR_SETHOT;
304 }
305
306 if (cursor.set & FB_CUR_SETSIZE ||
307 vc->vc_cursor_type != p->cursor_shape ||
308 ops->cursor_state.mask == NULL ||
309 ops->cursor_reset) {
310 char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
311 int cur_height, size, i = 0;
312 int width = (vc->vc_font.width + 7)/8;
313
314 if (!mask)
315 return;
316
317 tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
318
319 if (!tmp) {
320 kfree(mask);
321 return;
322 }
323
324 kfree(ops->cursor_state.mask);
325 ops->cursor_state.mask = mask;
326
327 p->cursor_shape = vc->vc_cursor_type;
328 cursor.set |= FB_CUR_SETSHAPE;
329
330 switch (p->cursor_shape & CUR_HWMASK) {
331 case CUR_NONE:
332 cur_height = 0;
333 break;
334 case CUR_UNDERLINE:
335 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
336 break;
337 case CUR_LOWER_THIRD:
338 cur_height = vc->vc_font.height/3;
339 break;
340 case CUR_LOWER_HALF:
341 cur_height = vc->vc_font.height >> 1;
342 break;
343 case CUR_TWO_THIRDS:
344 cur_height = (vc->vc_font.height << 1)/3;
345 break;
346 case CUR_BLOCK:
347 default:
348 cur_height = vc->vc_font.height;
349 break;
350 }
351
352 size = (vc->vc_font.height - cur_height) * width;
353 while (size--)
354 tmp[i++] = 0;
355 size = cur_height * width;
356 while (size--)
357 tmp[i++] = 0xff;
358 memset(mask, 0, w * vc->vc_font.width);
359 rotate_ccw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
360 kfree(tmp);
361 }
362
363 switch (mode) {
364 case CM_ERASE:
365 ops->cursor_state.enable = 0;
366 break;
367 case CM_DRAW:
368 case CM_MOVE:
369 default:
370 ops->cursor_state.enable = (use_sw) ? 0 : 1;
371 break;
372 }
373
374 cursor.image.data = src;
375 cursor.image.fg_color = ops->cursor_state.image.fg_color;
376 cursor.image.bg_color = ops->cursor_state.image.bg_color;
377 cursor.image.dx = ops->cursor_state.image.dx;
378 cursor.image.dy = ops->cursor_state.image.dy;
379 cursor.image.height = ops->cursor_state.image.height;
380 cursor.image.width = ops->cursor_state.image.width;
381 cursor.hot.x = ops->cursor_state.hot.x;
382 cursor.hot.y = ops->cursor_state.hot.y;
383 cursor.mask = ops->cursor_state.mask;
384 cursor.enable = ops->cursor_state.enable;
385 cursor.image.depth = 1;
386 cursor.rop = ROP_XOR;
387
388 if (info->fbops->fb_cursor)
389 err = info->fbops->fb_cursor(info, &cursor);
390
391 if (err)
392 soft_cursor(info, &cursor);
393
394 ops->cursor_reset = 0;
395}
396
397int ccw_update_start(struct fb_info *info)
398{
399 struct fbcon_ops *ops = info->fbcon_par;
400 struct display *p = &fb_display[ops->currcon];
401 u32 yoffset;
402 u32 vyres = GETVYRES(p->scrollmode, info);
403 int err;
404
405 yoffset = (vyres - info->var.yres) - ops->var.xoffset;
406 ops->var.xoffset = ops->var.yoffset;
407 ops->var.yoffset = yoffset;
408 err = fb_pan_display(info, &ops->var);
409 ops->var.xoffset = info->var.xoffset;
410 ops->var.yoffset = info->var.yoffset;
411 ops->var.vmode = info->var.vmode;
412 return err;
413}
414
415void fbcon_rotate_ccw(struct fbcon_ops *ops)
416{
417 ops->bmove = ccw_bmove;
418 ops->clear = ccw_clear;
419 ops->putcs = ccw_putcs;
420 ops->clear_margins = ccw_clear_margins;
421 ops->cursor = ccw_cursor;
422 ops->update_start = ccw_update_start;
423}
424EXPORT_SYMBOL(fbcon_rotate_ccw);
425
426MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
427MODULE_DESCRIPTION("Console Rotation (270 degrees) Support");
428MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c
new file mode 100644
index 000000000000..6c6f3b6dd175
--- /dev/null
+++ b/drivers/video/console/fbcon_cw.c
@@ -0,0 +1,412 @@
1/*
2 * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 90 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 90 degrees
23 */
24
25static inline void cw_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.height + 7) >> 3;
30 u8 c, t = 0, msk = ~(0xff >> offset);
31
32 for (i = 0; i < vc->vc_font.width; i++) {
33 for (j = 0; j < width; j++) {
34 c = *src;
35 if (attribute & FBCON_ATTRIBUTE_UNDERLINE && !j)
36 c |= msk;
37 if (attribute & FBCON_ATTRIBUTE_BOLD && i)
38 c |= *(src-width);
39 if (attribute & FBCON_ATTRIBUTE_REVERSE)
40 c = ~c;
41 src++;
42 *dst++ = c;
43 t = c;
44 }
45 }
46}
47
48
49static void cw_bmove(struct vc_data *vc, struct fb_info *info, int sy,
50 int sx, int dy, int dx, int height, int width)
51{
52 struct display *p = &fb_display[vc->vc_num];
53 struct fb_copyarea area;
54 u32 vxres = GETVXRES(p->scrollmode, info);
55
56 area.sx = vxres - ((sy + height) * vc->vc_font.height);
57 area.sy = sx * vc->vc_font.width;
58 area.dx = vxres - ((dy + height) * vc->vc_font.height);
59 area.dy = dx * vc->vc_font.width;
60 area.width = height * vc->vc_font.height;
61 area.height = width * vc->vc_font.width;
62
63 info->fbops->fb_copyarea(info, &area);
64}
65
66static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy,
67 int sx, int height, int width)
68{
69 struct display *p = &fb_display[vc->vc_num];
70 struct fb_fillrect region;
71 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
72 u32 vxres = GETVXRES(p->scrollmode, info);
73
74 region.color = attr_bgcol_ec(bgshift,vc);
75 region.dx = vxres - ((sy + height) * vc->vc_font.height);
76 region.dy = sx * vc->vc_font.width;
77 region.height = width * vc->vc_font.width;
78 region.width = height * vc->vc_font.height;
79 region.rop = ROP_COPY;
80
81 info->fbops->fb_fillrect(info, &region);
82}
83
84static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
85 const u16 *s, u32 attr, u32 cnt,
86 u32 d_pitch, u32 s_pitch, u32 cellsize,
87 struct fb_image *image, u8 *buf, u8 *dst)
88{
89 struct fbcon_ops *ops = info->fbcon_par;
90 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
91 u32 idx = (vc->vc_font.height + 7) >> 3;
92 u8 *src;
93
94 while (cnt--) {
95 src = ops->fontbuffer + (scr_readw(s++) & charmask)*cellsize;
96
97 if (attr) {
98 cw_update_attr(buf, src, attr, vc);
99 src = buf;
100 }
101
102 if (likely(idx == 1))
103 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
104 vc->vc_font.width);
105 else
106 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
107 vc->vc_font.width);
108
109 dst += d_pitch * vc->vc_font.width;
110 }
111
112 info->fbops->fb_imageblit(info, image);
113}
114
115static void cw_putcs(struct vc_data *vc, struct fb_info *info,
116 const unsigned short *s, int count, int yy, int xx,
117 int fg, int bg)
118{
119 struct fb_image image;
120 struct display *p = &fb_display[vc->vc_num];
121 struct fbcon_ops *ops = info->fbcon_par;
122 u32 width = (vc->vc_font.height + 7)/8;
123 u32 cellsize = width * vc->vc_font.width;
124 u32 maxcnt = info->pixmap.size/cellsize;
125 u32 scan_align = info->pixmap.scan_align - 1;
126 u32 buf_align = info->pixmap.buf_align - 1;
127 u32 cnt, pitch, size;
128 u32 attribute = get_attribute(info, scr_readw(s));
129 u8 *dst, *buf = NULL;
130 u32 vxres = GETVXRES(p->scrollmode, info);
131
132 if (!ops->fontbuffer)
133 return;
134
135 image.fg_color = fg;
136 image.bg_color = bg;
137 image.dx = vxres - ((yy + 1) * vc->vc_font.height);
138 image.dy = xx * vc->vc_font.width;
139 image.width = vc->vc_font.height;
140 image.depth = 1;
141
142 if (attribute) {
143 buf = kmalloc(cellsize, GFP_KERNEL);
144 if (!buf)
145 return;
146 }
147
148 while (count) {
149 if (count > maxcnt)
150 cnt = maxcnt;
151 else
152 cnt = count;
153
154 image.height = vc->vc_font.width * cnt;
155 pitch = ((image.width + 7) >> 3) + scan_align;
156 pitch &= ~scan_align;
157 size = pitch * image.height + buf_align;
158 size &= ~buf_align;
159 dst = fb_get_buffer_offset(info, &info->pixmap, size);
160 image.data = dst;
161 cw_putcs_aligned(vc, info, s, attribute, cnt, pitch,
162 width, cellsize, &image, buf, dst);
163 image.dy += image.height;
164 count -= cnt;
165 s += cnt;
166 }
167
168 /* buf is always NULL except when in monochrome mode, so in this case
169 it's a gain to check buf against NULL even though kfree() handles
170 NULL pointers just fine */
171 if (unlikely(buf))
172 kfree(buf);
173
174}
175
176static void cw_clear_margins(struct vc_data *vc, struct fb_info *info,
177 int bottom_only)
178{
179 unsigned int cw = vc->vc_font.width;
180 unsigned int ch = vc->vc_font.height;
181 unsigned int rw = info->var.yres - (vc->vc_cols*cw);
182 unsigned int bh = info->var.xres - (vc->vc_rows*ch);
183 unsigned int rs = info->var.yres - rw;
184 struct fb_fillrect region;
185 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
186
187 region.color = attr_bgcol_ec(bgshift,vc);
188 region.rop = ROP_COPY;
189
190 if (rw && !bottom_only) {
191 region.dx = 0;
192 region.dy = info->var.yoffset + rs;
193 region.height = rw;
194 region.width = info->var.xres_virtual;
195 info->fbops->fb_fillrect(info, &region);
196 }
197
198 if (bh) {
199 region.dx = info->var.xoffset;
200 region.dy = info->var.yoffset;
201 region.height = info->var.yres;
202 region.width = bh;
203 info->fbops->fb_fillrect(info, &region);
204 }
205}
206
207static void cw_cursor(struct vc_data *vc, struct fb_info *info,
208 struct display *p, int mode, int softback_lines,
209 int fg, int bg)
210{
211 struct fb_cursor cursor;
212 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
213 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
214 int w = (vc->vc_font.height + 7) >> 3, c;
215 int y = real_y(p, vc->vc_y);
216 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
217 int err = 1, dx, dy;
218 char *src;
219 u32 vxres = GETVXRES(p->scrollmode, info);
220
221 if (!ops->fontbuffer)
222 return;
223
224 cursor.set = 0;
225
226 if (softback_lines) {
227 if (y + softback_lines >= vc->vc_rows) {
228 mode = CM_ERASE;
229 ops->cursor_flash = 0;
230 return;
231 } else
232 y += softback_lines;
233 }
234
235 c = scr_readw((u16 *) vc->vc_pos);
236 attribute = get_attribute(info, c);
237 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
238
239 if (ops->cursor_state.image.data != src ||
240 ops->cursor_reset) {
241 ops->cursor_state.image.data = src;
242 cursor.set |= FB_CUR_SETIMAGE;
243 }
244
245 if (attribute) {
246 u8 *dst;
247
248 dst = kmalloc(w * vc->vc_font.width, GFP_ATOMIC);
249 if (!dst)
250 return;
251 kfree(ops->cursor_data);
252 ops->cursor_data = dst;
253 cw_update_attr(dst, src, attribute, vc);
254 src = dst;
255 }
256
257 if (ops->cursor_state.image.fg_color != fg ||
258 ops->cursor_state.image.bg_color != bg ||
259 ops->cursor_reset) {
260 ops->cursor_state.image.fg_color = fg;
261 ops->cursor_state.image.bg_color = bg;
262 cursor.set |= FB_CUR_SETCMAP;
263 }
264
265 if (ops->cursor_state.image.height != vc->vc_font.width ||
266 ops->cursor_state.image.width != vc->vc_font.height ||
267 ops->cursor_reset) {
268 ops->cursor_state.image.height = vc->vc_font.width;
269 ops->cursor_state.image.width = vc->vc_font.height;
270 cursor.set |= FB_CUR_SETSIZE;
271 }
272
273 dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
274 dy = vc->vc_x * vc->vc_font.width;
275
276 if (ops->cursor_state.image.dx != dx ||
277 ops->cursor_state.image.dy != dy ||
278 ops->cursor_reset) {
279 ops->cursor_state.image.dx = dx;
280 ops->cursor_state.image.dy = dy;
281 cursor.set |= FB_CUR_SETPOS;
282 }
283
284 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
285 ops->cursor_reset) {
286 ops->cursor_state.hot.x = cursor.hot.y = 0;
287 cursor.set |= FB_CUR_SETHOT;
288 }
289
290 if (cursor.set & FB_CUR_SETSIZE ||
291 vc->vc_cursor_type != p->cursor_shape ||
292 ops->cursor_state.mask == NULL ||
293 ops->cursor_reset) {
294 char *tmp, *mask = kmalloc(w*vc->vc_font.width, GFP_ATOMIC);
295 int cur_height, size, i = 0;
296 int width = (vc->vc_font.width + 7)/8;
297
298 if (!mask)
299 return;
300
301 tmp = kmalloc(width * vc->vc_font.height, GFP_ATOMIC);
302
303 if (!tmp) {
304 kfree(mask);
305 return;
306 }
307
308 kfree(ops->cursor_state.mask);
309 ops->cursor_state.mask = mask;
310
311 p->cursor_shape = vc->vc_cursor_type;
312 cursor.set |= FB_CUR_SETSHAPE;
313
314 switch (p->cursor_shape & CUR_HWMASK) {
315 case CUR_NONE:
316 cur_height = 0;
317 break;
318 case CUR_UNDERLINE:
319 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
320 break;
321 case CUR_LOWER_THIRD:
322 cur_height = vc->vc_font.height/3;
323 break;
324 case CUR_LOWER_HALF:
325 cur_height = vc->vc_font.height >> 1;
326 break;
327 case CUR_TWO_THIRDS:
328 cur_height = (vc->vc_font.height << 1)/3;
329 break;
330 case CUR_BLOCK:
331 default:
332 cur_height = vc->vc_font.height;
333 break;
334 }
335
336 size = (vc->vc_font.height - cur_height) * width;
337 while (size--)
338 tmp[i++] = 0;
339 size = cur_height * width;
340 while (size--)
341 tmp[i++] = 0xff;
342 memset(mask, 0, w * vc->vc_font.width);
343 rotate_cw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
344 kfree(tmp);
345 }
346
347 switch (mode) {
348 case CM_ERASE:
349 ops->cursor_state.enable = 0;
350 break;
351 case CM_DRAW:
352 case CM_MOVE:
353 default:
354 ops->cursor_state.enable = (use_sw) ? 0 : 1;
355 break;
356 }
357
358 cursor.image.data = src;
359 cursor.image.fg_color = ops->cursor_state.image.fg_color;
360 cursor.image.bg_color = ops->cursor_state.image.bg_color;
361 cursor.image.dx = ops->cursor_state.image.dx;
362 cursor.image.dy = ops->cursor_state.image.dy;
363 cursor.image.height = ops->cursor_state.image.height;
364 cursor.image.width = ops->cursor_state.image.width;
365 cursor.hot.x = ops->cursor_state.hot.x;
366 cursor.hot.y = ops->cursor_state.hot.y;
367 cursor.mask = ops->cursor_state.mask;
368 cursor.enable = ops->cursor_state.enable;
369 cursor.image.depth = 1;
370 cursor.rop = ROP_XOR;
371
372 if (info->fbops->fb_cursor)
373 err = info->fbops->fb_cursor(info, &cursor);
374
375 if (err)
376 soft_cursor(info, &cursor);
377
378 ops->cursor_reset = 0;
379}
380
381int cw_update_start(struct fb_info *info)
382{
383 struct fbcon_ops *ops = info->fbcon_par;
384 struct display *p = &fb_display[ops->currcon];
385 u32 vxres = GETVXRES(p->scrollmode, info);
386 u32 xoffset;
387 int err;
388
389 xoffset = vxres - (info->var.xres + ops->var.yoffset);
390 ops->var.yoffset = ops->var.xoffset;
391 ops->var.xoffset = xoffset;
392 err = fb_pan_display(info, &ops->var);
393 ops->var.xoffset = info->var.xoffset;
394 ops->var.yoffset = info->var.yoffset;
395 ops->var.vmode = info->var.vmode;
396 return err;
397}
398
399void fbcon_rotate_cw(struct fbcon_ops *ops)
400{
401 ops->bmove = cw_bmove;
402 ops->clear = cw_clear;
403 ops->putcs = cw_putcs;
404 ops->clear_margins = cw_clear_margins;
405 ops->cursor = cw_cursor;
406 ops->update_start = cw_update_start;
407}
408EXPORT_SYMBOL(fbcon_rotate_cw);
409
410MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
411MODULE_DESCRIPTION("Console Rotation (90 degrees) Support");
412MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.c b/drivers/video/console/fbcon_rotate.c
new file mode 100644
index 000000000000..ec0dd8fe241c
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.c
@@ -0,0 +1,117 @@
1/*
2 * linux/drivers/video/console/fbcon_rotate.c -- Software Rotation
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc,
22 struct display *p)
23{
24 struct fbcon_ops *ops = info->fbcon_par;
25 int len, err = 0;
26 int s_cellsize, d_cellsize, i;
27 const u8 *src;
28 u8 *dst;
29
30 if (vc->vc_font.data == ops->fontdata &&
31 p->con_rotate == ops->cur_rotate)
32 goto finished;
33
34 src = ops->fontdata = vc->vc_font.data;
35 ops->cur_rotate = p->con_rotate;
36 len = (!p->userfont) ? 256 : FNTCHARCNT(src);
37 s_cellsize = ((vc->vc_font.width + 7)/8) *
38 vc->vc_font.height;
39 d_cellsize = s_cellsize;
40
41 if (ops->rotate == FB_ROTATE_CW ||
42 ops->rotate == FB_ROTATE_CCW)
43 d_cellsize = ((vc->vc_font.height + 7)/8) *
44 vc->vc_font.width;
45
46 if (info->fbops->fb_sync)
47 info->fbops->fb_sync(info);
48
49 if (ops->fd_size < d_cellsize * len) {
50 dst = kmalloc(d_cellsize * len, GFP_KERNEL);
51
52 if (dst == NULL) {
53 err = -ENOMEM;
54 goto finished;
55 }
56
57 ops->fd_size = d_cellsize * len;
58 kfree(ops->fontbuffer);
59 ops->fontbuffer = dst;
60 }
61
62 dst = ops->fontbuffer;
63 memset(dst, 0, ops->fd_size);
64
65 switch (ops->rotate) {
66 case FB_ROTATE_UD:
67 for (i = len; i--; ) {
68 rotate_ud(src, dst, vc->vc_font.width,
69 vc->vc_font.height);
70
71 src += s_cellsize;
72 dst += d_cellsize;
73 }
74 break;
75 case FB_ROTATE_CW:
76 for (i = len; i--; ) {
77 rotate_cw(src, dst, vc->vc_font.width,
78 vc->vc_font.height);
79 src += s_cellsize;
80 dst += d_cellsize;
81 }
82 break;
83 case FB_ROTATE_CCW:
84 for (i = len; i--; ) {
85 rotate_ccw(src, dst, vc->vc_font.width,
86 vc->vc_font.height);
87 src += s_cellsize;
88 dst += d_cellsize;
89 }
90 break;
91 }
92
93finished:
94 return err;
95}
96
97void fbcon_set_rotate(struct fbcon_ops *ops)
98{
99 ops->rotate_font = fbcon_rotate_font;
100
101 switch(ops->rotate) {
102 case FB_ROTATE_CW:
103 fbcon_rotate_cw(ops);
104 break;
105 case FB_ROTATE_UD:
106 fbcon_rotate_ud(ops);
107 break;
108 case FB_ROTATE_CCW:
109 fbcon_rotate_ccw(ops);
110 break;
111 }
112}
113EXPORT_SYMBOL(fbcon_set_rotate);
114
115MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
116MODULE_DESCRIPTION("Console Rotation Support");
117MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h
new file mode 100644
index 000000000000..90c672096c2e
--- /dev/null
+++ b/drivers/video/console/fbcon_rotate.h
@@ -0,0 +1,105 @@
1/*
2 * linux/drivers/video/console/fbcon_rotate.h -- Software Display Rotation
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas@pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#ifndef _FBCON_ROTATE_H
12#define _FBCON_ROTATE_H
13
14#define FNTCHARCNT(fd) (((int *)(fd))[-3])
15
16#define GETVYRES(s,i) ({ \
17 (s == SCROLL_REDRAW || s == SCROLL_MOVE) ? \
18 (i)->var.yres : (i)->var.yres_virtual; })
19
20#define GETVXRES(s,i) ({ \
21 (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
22 (i)->var.xres : (i)->var.xres_virtual; })
23
24/*
25 * The bitmap is always big endian
26 */
27#if defined(__LITTLE_ENDIAN)
28#define FBCON_BIT(b) (7 - (b))
29#else
30#define FBCON_BIT(b) (b)
31#endif
32
33static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
34{
35 u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
36
37 pat +=index;
38 return (test_bit(FBCON_BIT(bit), (void *)pat));
39}
40
41static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
42{
43 u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
44
45 pat += index;
46 set_bit(FBCON_BIT(bit), (void *)pat);
47}
48
49static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
50{
51 int i, j;
52 int shift = width % 8;
53
54 width = (width + 7) & ~7;
55
56 for (i = 0; i < height; i++) {
57 for (j = 0; j < width; j++) {
58 if (pattern_test_bit(j, i, width, in))
59 pattern_set_bit(width - (1 + j + shift),
60 height - (1 + i),
61 width, out);
62 }
63
64 }
65}
66
67static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
68{
69 int i, j, h = height, w = width;
70 int shift = (8 - (height % 8)) & 7;
71
72 width = (width + 7) & ~7;
73 height = (height + 7) & ~7;
74
75 for (i = 0; i < h; i++) {
76 for (j = 0; j < w; j++) {
77 if (pattern_test_bit(j, i, width, in))
78 pattern_set_bit(height - 1 - i - shift, j,
79 height, out);
80
81 }
82 }
83}
84
85static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
86{
87 int i, j, h = height, w = width;
88 int shift = width % 8;
89
90 width = (width + 7) & ~7;
91 height = (height + 7) & ~7;
92
93 for (i = 0; i < h; i++) {
94 for (j = 0; j < w; j++) {
95 if (pattern_test_bit(j, i, width, in))
96 pattern_set_bit(i, width - 1 - j - shift,
97 height, out);
98 }
99 }
100}
101
102extern void fbcon_rotate_cw(struct fbcon_ops *ops);
103extern void fbcon_rotate_ud(struct fbcon_ops *ops);
104extern void fbcon_rotate_ccw(struct fbcon_ops *ops);
105#endif
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
new file mode 100644
index 000000000000..2e1d9d4249cd
--- /dev/null
+++ b/drivers/video/console/fbcon_ud.c
@@ -0,0 +1,454 @@
1/*
2 * linux/drivers/video/console/fbcon_ud.c -- Software Rotation - 180 degrees
3 *
4 * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
10
11#include <linux/config.h>
12#include <linux/module.h>
13#include <linux/string.h>
14#include <linux/fb.h>
15#include <linux/vt_kern.h>
16#include <linux/console.h>
17#include <asm/types.h>
18#include "fbcon.h"
19#include "fbcon_rotate.h"
20
21/*
22 * Rotation 180 degrees
23 */
24
25static inline void ud_update_attr(u8 *dst, u8 *src, int attribute,
26 struct vc_data *vc)
27{
28 int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
29 int width = (vc->vc_font.width + 7) >> 3;
30 unsigned int cellsize = vc->vc_font.height * width;
31 u8 c;
32
33 offset = offset * width;
34
35 for (i = 0; i < cellsize; i++) {
36 c = src[i];
37 if (attribute & FBCON_ATTRIBUTE_UNDERLINE && i < offset)
38 c = 0xff;
39 if (attribute & FBCON_ATTRIBUTE_BOLD)
40 c |= c << 1;
41 if (attribute & FBCON_ATTRIBUTE_REVERSE)
42 c = ~c;
43 dst[i] = c;
44 }
45}
46
47
48static void ud_bmove(struct vc_data *vc, struct fb_info *info, int sy,
49 int sx, int dy, int dx, int height, int width)
50{
51 struct display *p = &fb_display[vc->vc_num];
52 struct fb_copyarea area;
53 u32 vyres = GETVYRES(p->scrollmode, info);
54 u32 vxres = GETVXRES(p->scrollmode, info);
55
56 area.sy = vyres - ((sy + height) * vc->vc_font.height);
57 area.sx = vxres - ((sx + width) * vc->vc_font.width);
58 area.dy = vyres - ((dy + height) * vc->vc_font.height);
59 area.dx = vxres - ((dx + width) * vc->vc_font.width);
60 area.height = height * vc->vc_font.height;
61 area.width = width * vc->vc_font.width;
62
63 info->fbops->fb_copyarea(info, &area);
64}
65
66static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy,
67 int sx, int height, int width)
68{
69 struct display *p = &fb_display[vc->vc_num];
70 struct fb_fillrect region;
71 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
72 u32 vyres = GETVYRES(p->scrollmode, info);
73 u32 vxres = GETVXRES(p->scrollmode, info);
74
75 region.color = attr_bgcol_ec(bgshift,vc);
76 region.dy = vyres - ((sy + height) * vc->vc_font.height);
77 region.dx = vxres - ((sx + width) * vc->vc_font.width);
78 region.width = width * vc->vc_font.width;
79 region.height = height * vc->vc_font.height;
80 region.rop = ROP_COPY;
81
82 info->fbops->fb_fillrect(info, &region);
83}
84
85static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
86 const u16 *s, u32 attr, u32 cnt,
87 u32 d_pitch, u32 s_pitch, u32 cellsize,
88 struct fb_image *image, u8 *buf, u8 *dst)
89{
90 struct fbcon_ops *ops = info->fbcon_par;
91 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
92 u32 idx = vc->vc_font.width >> 3;
93 u8 *src;
94
95 while (cnt--) {
96 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
97
98 if (attr) {
99 ud_update_attr(buf, src, attr, vc);
100 src = buf;
101 }
102
103 if (likely(idx == 1))
104 __fb_pad_aligned_buffer(dst, d_pitch, src, idx,
105 image->height);
106 else
107 fb_pad_aligned_buffer(dst, d_pitch, src, idx,
108 image->height);
109
110 dst += s_pitch;
111 }
112
113 info->fbops->fb_imageblit(info, image);
114}
115
116static inline void ud_putcs_unaligned(struct vc_data *vc,
117 struct fb_info *info, const u16 *s,
118 u32 attr, u32 cnt, u32 d_pitch,
119 u32 s_pitch, u32 cellsize,
120 struct fb_image *image, u8 *buf,
121 u8 *dst)
122{
123 struct fbcon_ops *ops = info->fbcon_par;
124 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
125 u32 shift_low = 0, mod = vc->vc_font.width % 8;
126 u32 shift_high = 8;
127 u32 idx = vc->vc_font.width >> 3;
128 u8 *src;
129
130 while (cnt--) {
131 src = ops->fontbuffer + (scr_readw(s--) & charmask)*cellsize;
132
133 if (attr) {
134 ud_update_attr(buf, src, attr, vc);
135 src = buf;
136 }
137
138 fb_pad_unaligned_buffer(dst, d_pitch, src, idx,
139 image->height, shift_high,
140 shift_low, mod);
141 shift_low += mod;
142 dst += (shift_low >= 8) ? s_pitch : s_pitch - 1;
143 shift_low &= 7;
144 shift_high = 8 - shift_low;
145 }
146
147 info->fbops->fb_imageblit(info, image);
148
149}
150
151static void ud_putcs(struct vc_data *vc, struct fb_info *info,
152 const unsigned short *s, int count, int yy, int xx,
153 int fg, int bg)
154{
155 struct fb_image image;
156 struct display *p = &fb_display[vc->vc_num];
157 struct fbcon_ops *ops = info->fbcon_par;
158 u32 width = (vc->vc_font.width + 7)/8;
159 u32 cellsize = width * vc->vc_font.height;
160 u32 maxcnt = info->pixmap.size/cellsize;
161 u32 scan_align = info->pixmap.scan_align - 1;
162 u32 buf_align = info->pixmap.buf_align - 1;
163 u32 mod = vc->vc_font.width % 8, cnt, pitch, size;
164 u32 attribute = get_attribute(info, scr_readw(s));
165 u8 *dst, *buf = NULL;
166 u32 vyres = GETVYRES(p->scrollmode, info);
167 u32 vxres = GETVXRES(p->scrollmode, info);
168
169 if (!ops->fontbuffer)
170 return;
171
172 image.fg_color = fg;
173 image.bg_color = bg;
174 image.dy = vyres - ((yy * vc->vc_font.height) + vc->vc_font.height);
175 image.dx = vxres - ((xx + count) * vc->vc_font.width);
176 image.height = vc->vc_font.height;
177 image.depth = 1;
178
179 if (attribute) {
180 buf = kmalloc(cellsize, GFP_KERNEL);
181 if (!buf)
182 return;
183 }
184
185 s += count - 1;
186
187 while (count) {
188 if (count > maxcnt)
189 cnt = maxcnt;
190 else
191 cnt = count;
192
193 image.width = vc->vc_font.width * cnt;
194 pitch = ((image.width + 7) >> 3) + scan_align;
195 pitch &= ~scan_align;
196 size = pitch * image.height + buf_align;
197 size &= ~buf_align;
198 dst = fb_get_buffer_offset(info, &info->pixmap, size);
199 image.data = dst;
200
201 if (!mod)
202 ud_putcs_aligned(vc, info, s, attribute, cnt, pitch,
203 width, cellsize, &image, buf, dst);
204 else
205 ud_putcs_unaligned(vc, info, s, attribute, cnt, pitch,
206 width, cellsize, &image,
207 buf, dst);
208
209 image.dx += image.width;
210 count -= cnt;
211 s -= cnt;
212 xx += cnt;
213 }
214
215 /* buf is always NULL except when in monochrome mode, so in this case
216 it's a gain to check buf against NULL even though kfree() handles
217 NULL pointers just fine */
218 if (unlikely(buf))
219 kfree(buf);
220
221}
222
223static void ud_clear_margins(struct vc_data *vc, struct fb_info *info,
224 int bottom_only)
225{
226 unsigned int cw = vc->vc_font.width;
227 unsigned int ch = vc->vc_font.height;
228 unsigned int rw = info->var.xres - (vc->vc_cols*cw);
229 unsigned int bh = info->var.yres - (vc->vc_rows*ch);
230 struct fb_fillrect region;
231 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
232
233 region.color = attr_bgcol_ec(bgshift,vc);
234 region.rop = ROP_COPY;
235
236 if (rw && !bottom_only) {
237 region.dy = 0;
238 region.dx = info->var.xoffset;
239 region.width = rw;
240 region.height = info->var.yres_virtual;
241 info->fbops->fb_fillrect(info, &region);
242 }
243
244 if (bh) {
245 region.dy = info->var.yoffset;
246 region.dx = info->var.xoffset;
247 region.height = bh;
248 region.width = info->var.xres;
249 info->fbops->fb_fillrect(info, &region);
250 }
251}
252
253static void ud_cursor(struct vc_data *vc, struct fb_info *info,
254 struct display *p, int mode, int softback_lines,
255 int fg, int bg)
256{
257 struct fb_cursor cursor;
258 struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par;
259 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
260 int w = (vc->vc_font.width + 7) >> 3, c;
261 int y = real_y(p, vc->vc_y);
262 int attribute, use_sw = (vc->vc_cursor_type & 0x10);
263 int err = 1, dx, dy;
264 char *src;
265 u32 vyres = GETVYRES(p->scrollmode, info);
266 u32 vxres = GETVXRES(p->scrollmode, info);
267
268 if (!ops->fontbuffer)
269 return;
270
271 cursor.set = 0;
272
273 if (softback_lines) {
274 if (y + softback_lines >= vc->vc_rows) {
275 mode = CM_ERASE;
276 ops->cursor_flash = 0;
277 return;
278 } else
279 y += softback_lines;
280 }
281
282 c = scr_readw((u16 *) vc->vc_pos);
283 attribute = get_attribute(info, c);
284 src = ops->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
285
286 if (ops->cursor_state.image.data != src ||
287 ops->cursor_reset) {
288 ops->cursor_state.image.data = src;
289 cursor.set |= FB_CUR_SETIMAGE;
290 }
291
292 if (attribute) {
293 u8 *dst;
294
295 dst = kmalloc(w * vc->vc_font.height, GFP_ATOMIC);
296 if (!dst)
297 return;
298 kfree(ops->cursor_data);
299 ops->cursor_data = dst;
300 ud_update_attr(dst, src, attribute, vc);
301 src = dst;
302 }
303
304 if (ops->cursor_state.image.fg_color != fg ||
305 ops->cursor_state.image.bg_color != bg ||
306 ops->cursor_reset) {
307 ops->cursor_state.image.fg_color = fg;
308 ops->cursor_state.image.bg_color = bg;
309 cursor.set |= FB_CUR_SETCMAP;
310 }
311
312 if (ops->cursor_state.image.height != vc->vc_font.height ||
313 ops->cursor_state.image.width != vc->vc_font.width ||
314 ops->cursor_reset) {
315 ops->cursor_state.image.height = vc->vc_font.height;
316 ops->cursor_state.image.width = vc->vc_font.width;
317 cursor.set |= FB_CUR_SETSIZE;
318 }
319
320 dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
321 dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width);
322
323 if (ops->cursor_state.image.dx != dx ||
324 ops->cursor_state.image.dy != dy ||
325 ops->cursor_reset) {
326 ops->cursor_state.image.dx = dx;
327 ops->cursor_state.image.dy = dy;
328 cursor.set |= FB_CUR_SETPOS;
329 }
330
331 if (ops->cursor_state.hot.x || ops->cursor_state.hot.y ||
332 ops->cursor_reset) {
333 ops->cursor_state.hot.x = cursor.hot.y = 0;
334 cursor.set |= FB_CUR_SETHOT;
335 }
336
337 if (cursor.set & FB_CUR_SETSIZE ||
338 vc->vc_cursor_type != p->cursor_shape ||
339 ops->cursor_state.mask == NULL ||
340 ops->cursor_reset) {
341 char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
342 int cur_height, size, i = 0;
343 u8 msk = 0xff;
344
345 if (!mask)
346 return;
347
348 kfree(ops->cursor_state.mask);
349 ops->cursor_state.mask = mask;
350
351 p->cursor_shape = vc->vc_cursor_type;
352 cursor.set |= FB_CUR_SETSHAPE;
353
354 switch (p->cursor_shape & CUR_HWMASK) {
355 case CUR_NONE:
356 cur_height = 0;
357 break;
358 case CUR_UNDERLINE:
359 cur_height = (vc->vc_font.height < 10) ? 1 : 2;
360 break;
361 case CUR_LOWER_THIRD:
362 cur_height = vc->vc_font.height/3;
363 break;
364 case CUR_LOWER_HALF:
365 cur_height = vc->vc_font.height >> 1;
366 break;
367 case CUR_TWO_THIRDS:
368 cur_height = (vc->vc_font.height << 1)/3;
369 break;
370 case CUR_BLOCK:
371 default:
372 cur_height = vc->vc_font.height;
373 break;
374 }
375
376 size = cur_height * w;
377
378 while (size--)
379 mask[i++] = msk;
380
381 size = (vc->vc_font.height - cur_height) * w;
382
383 while (size--)
384 mask[i++] = ~msk;
385 }
386
387 switch (mode) {
388 case CM_ERASE:
389 ops->cursor_state.enable = 0;
390 break;
391 case CM_DRAW:
392 case CM_MOVE:
393 default:
394 ops->cursor_state.enable = (use_sw) ? 0 : 1;
395 break;
396 }
397
398 cursor.image.data = src;
399 cursor.image.fg_color = ops->cursor_state.image.fg_color;
400 cursor.image.bg_color = ops->cursor_state.image.bg_color;
401 cursor.image.dx = ops->cursor_state.image.dx;
402 cursor.image.dy = ops->cursor_state.image.dy;
403 cursor.image.height = ops->cursor_state.image.height;
404 cursor.image.width = ops->cursor_state.image.width;
405 cursor.hot.x = ops->cursor_state.hot.x;
406 cursor.hot.y = ops->cursor_state.hot.y;
407 cursor.mask = ops->cursor_state.mask;
408 cursor.enable = ops->cursor_state.enable;
409 cursor.image.depth = 1;
410 cursor.rop = ROP_XOR;
411
412 if (info->fbops->fb_cursor)
413 err = info->fbops->fb_cursor(info, &cursor);
414
415 if (err)
416 soft_cursor(info, &cursor);
417
418 ops->cursor_reset = 0;
419}
420
421int ud_update_start(struct fb_info *info)
422{
423 struct fbcon_ops *ops = info->fbcon_par;
424 struct display *p = &fb_display[ops->currcon];
425 u32 xoffset, yoffset;
426 u32 vyres = GETVYRES(p->scrollmode, info);
427 u32 vxres = GETVXRES(p->scrollmode, info);
428 int err;
429
430 xoffset = (vxres - info->var.xres) - ops->var.xoffset;
431 yoffset = (vyres - info->var.yres) - ops->var.yoffset;
432 ops->var.xoffset = xoffset;
433 ops->var.yoffset = yoffset;
434 err = fb_pan_display(info, &ops->var);
435 ops->var.xoffset = info->var.xoffset;
436 ops->var.yoffset = info->var.yoffset;
437 ops->var.vmode = info->var.vmode;
438 return err;
439}
440
441void fbcon_rotate_ud(struct fbcon_ops *ops)
442{
443 ops->bmove = ud_bmove;
444 ops->clear = ud_clear;
445 ops->putcs = ud_putcs;
446 ops->clear_margins = ud_clear_margins;
447 ops->cursor = ud_cursor;
448 ops->update_start = ud_update_start;
449}
450EXPORT_SYMBOL(fbcon_rotate_ud);
451
452MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
453MODULE_DESCRIPTION("Console Rotation (180 degrees) Support");
454MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/font_rl.c b/drivers/video/console/font_rl.c
new file mode 100644
index 000000000000..dfecc27d8ded
--- /dev/null
+++ b/drivers/video/console/font_rl.c
@@ -0,0 +1,4374 @@
1
2/* This font is simply the "rl.fnt" console font from the kbd utility.
3 * Converted by Zack T Smith, fbui@comcast.net.
4 * The original binary file is covered under the GNU Public License.
5 */
6
7#include <linux/font.h>
8
9#define FONTDATAMAX 4096
10
11static unsigned char patterns[4096] = {
120x00,
130x00,
140x00,
150x00,
160x00,
170x00,
180x00,
190x00,
200x00,
210x00,
220x00,
230x00,
240x00,
250x00,
260x00,
270x00,
28
290x00,
300x00,
310x3c,
320x42,
330x81,
340xe7,
350xa5,
360x99,
370x81,
380x81,
390x99,
400x42,
410x3c,
420x00,
430x00,
440x00,
45
460x00,
470x00,
480x3c,
490x7e,
500xff,
510x99,
520xdb,
530xe7,
540xff,
550xff,
560xe7,
570x7e,
580x3c,
590x00,
600x00,
610x00,
62
630x00,
640x00,
650x00,
660x6c,
670xfe,
680xfe,
690xfe,
700xfe,
710xfe,
720x7c,
730x38,
740x10,
750x00,
760x00,
770x00,
780x00,
79
800x00,
810x00,
820x00,
830x00,
840x10,
850x38,
860x7c,
870xfe,
880x7c,
890x38,
900x10,
910x00,
920x00,
930x00,
940x00,
950x00,
96
970x00,
980x00,
990x38,
1000x38,
1010x10,
1020xd6,
1030xfe,
1040xd6,
1050x10,
1060x10,
1070x38,
1080x7c,
1090x00,
1100x00,
1110x00,
1120x00,
113
1140x00,
1150x00,
1160x10,
1170x38,
1180x7c,
1190xfe,
1200xfe,
1210x54,
1220x10,
1230x10,
1240x38,
1250x7c,
1260x00,
1270x00,
1280x00,
1290x00,
130
1310x00,
1320x00,
1330x00,
1340x00,
1350x00,
1360x00,
1370x18,
1380x3c,
1390x3c,
1400x18,
1410x00,
1420x00,
1430x00,
1440x00,
1450x00,
1460x00,
147
1480xff,
1490xff,
1500xff,
1510xff,
1520xff,
1530xff,
1540xe7,
1550xc3,
1560xc3,
1570xe7,
1580xff,
1590xff,
1600xff,
1610xff,
1620xff,
1630xff,
164
1650x00,
1660x00,
1670x00,
1680x00,
1690x00,
1700x3c,
1710x66,
1720x42,
1730x42,
1740x66,
1750x3c,
1760x00,
1770x00,
1780x00,
1790x00,
1800x00,
181
1820xff,
1830xff,
1840xff,
1850xff,
1860xff,
1870xc3,
1880x99,
1890xbd,
1900xbd,
1910x99,
1920xc3,
1930xff,
1940xff,
1950xff,
1960xff,
1970xff,
198
1990x00,
2000x00,
2010x0f,
2020x07,
2030x0d,
2040x18,
2050x78,
2060xcc,
2070xcc,
2080xcc,
2090xcc,
2100x78,
2110x00,
2120x00,
2130x00,
2140x00,
215
2160x00,
2170x00,
2180x3c,
2190x66,
2200x66,
2210x66,
2220x3c,
2230x18,
2240x7e,
2250x18,
2260x18,
2270x18,
2280x00,
2290x00,
2300x00,
2310x00,
232
2330x00,
2340x08,
2350x0c,
2360x0a,
2370x0a,
2380x0a,
2390x08,
2400x08,
2410x08,
2420x38,
2430x78,
2440x30,
2450x00,
2460x00,
2470x00,
2480x00,
249
2500x00,
2510x10,
2520x18,
2530x1c,
2540x1e,
2550x1e,
2560x16,
2570x12,
2580x72,
2590xf2,
2600x62,
2610x0e,
2620x1e,
2630x0c,
2640x00,
2650x00,
266
2670x00,
2680x00,
2690x00,
2700x10,
2710x92,
2720x54,
2730x38,
2740xfe,
2750x38,
2760x54,
2770x92,
2780x10,
2790x00,
2800x00,
2810x00,
2820x00,
283
2840x00,
2850x00,
2860x00,
2870x80,
2880xc0,
2890xe0,
2900xb8,
2910x8e,
2920xb8,
2930xe0,
2940xc0,
2950x80,
2960x00,
2970x00,
2980x00,
2990x00,
300
3010x00,
3020x00,
3030x00,
3040x02,
3050x06,
3060x0e,
3070x3a,
3080xe2,
3090x3a,
3100x0e,
3110x06,
3120x02,
3130x00,
3140x00,
3150x00,
3160x00,
317
3180x00,
3190x00,
3200x10,
3210x38,
3220x7c,
3230xd6,
3240x10,
3250x10,
3260x10,
3270x10,
3280xd6,
3290x7c,
3300x38,
3310x10,
3320x00,
3330x00,
334
3350x00,
3360x42,
3370xe7,
3380xe7,
3390xe7,
3400xe7,
3410x42,
3420x42,
3430x42,
3440x00,
3450x66,
3460x66,
3470x66,
3480x00,
3490x00,
3500x00,
351
3520x00,
3530x7f,
3540xca,
3550xca,
3560xca,
3570xca,
3580x7a,
3590x0a,
3600x0a,
3610x0a,
3620x0a,
3630x0a,
3640x1b,
3650x00,
3660x00,
3670x00,
368
3690x00,
3700x1e,
3710x31,
3720x78,
3730xcc,
3740xc6,
3750xc3,
3760x63,
3770x33,
3780x1e,
3790x8c,
3800x78,
3810x00,
3820x00,
3830x00,
3840x00,
385
3860x00,
3870x00,
3880x00,
3890x00,
3900x00,
3910x00,
3920x00,
3930x00,
3940xfe,
3950xfe,
3960xfe,
3970xfe,
3980x00,
3990x00,
4000x00,
4010x00,
402
4030x00,
4040x00,
4050x10,
4060x38,
4070x7c,
4080xd6,
4090x10,
4100x10,
4110x10,
4120x10,
4130xd6,
4140x7c,
4150x38,
4160x10,
4170xfe,
4180x00,
419
4200x00,
4210x00,
4220x10,
4230x38,
4240x7c,
4250xd6,
4260x10,
4270x10,
4280x10,
4290x10,
4300x10,
4310x10,
4320x10,
4330x10,
4340x00,
4350x00,
436
4370x00,
4380x00,
4390x10,
4400x10,
4410x10,
4420x10,
4430x10,
4440x10,
4450x10,
4460x10,
4470xd6,
4480x7c,
4490x38,
4500x10,
4510x00,
4520x00,
453
4540x00,
4550x00,
4560x00,
4570x00,
4580x00,
4590x08,
4600x0c,
4610x06,
4620xff,
4630x06,
4640x0c,
4650x08,
4660x00,
4670x00,
4680x00,
4690x00,
470
4710x00,
4720x00,
4730x00,
4740x00,
4750x00,
4760x10,
4770x30,
4780x60,
4790xff,
4800x60,
4810x30,
4820x10,
4830x00,
4840x00,
4850x00,
4860x00,
487
4880x22,
4890x44,
4900x88,
4910xcc,
4920xee,
4930x44,
4940x00,
4950x00,
4960x00,
4970x00,
4980x00,
4990x00,
5000x00,
5010x00,
5020x00,
5030x00,
504
5050x00,
5060x00,
5070x00,
5080x00,
5090x00,
5100x24,
5110x42,
5120xff,
5130x42,
5140x24,
5150x00,
5160x00,
5170x00,
5180x00,
5190x00,
5200x00,
521
5220x00,
5230x00,
5240x00,
5250x10,
5260x38,
5270x38,
5280x6c,
5290x6c,
5300xc6,
5310xfe,
5320x00,
5330x00,
5340x00,
5350x00,
5360x00,
5370x00,
538
5390x00,
5400x00,
5410x00,
5420xfe,
5430xc6,
5440x6c,
5450x6c,
5460x38,
5470x38,
5480x10,
5490x00,
5500x00,
5510x00,
5520x00,
5530x00,
5540x00,
555
5560x00,
5570x00,
5580x00,
5590x00,
5600x00,
5610x00,
5620x00,
5630x00,
5640x00,
5650x00,
5660x00,
5670x00,
5680x00,
5690x00,
5700x00,
5710x00,
572
5730x00,
5740x18,
5750x3c,
5760x3c,
5770x3c,
5780x3c,
5790x18,
5800x18,
5810x18,
5820x10,
5830x00,
5840x18,
5850x18,
5860x00,
5870x00,
5880x00,
589
5900x22,
5910x77,
5920x33,
5930x11,
5940x22,
5950x44,
5960x00,
5970x00,
5980x00,
5990x00,
6000x00,
6010x00,
6020x00,
6030x00,
6040x00,
6050x00,
606
6070x00,
6080x00,
6090x12,
6100x12,
6110x12,
6120x7f,
6130x24,
6140x24,
6150x24,
6160xfe,
6170x48,
6180x48,
6190x48,
6200x00,
6210x00,
6220x00,
623
6240x10,
6250x10,
6260x7c,
6270xd2,
6280xd0,
6290xd0,
6300xd0,
6310x7c,
6320x16,
6330x16,
6340x16,
6350x96,
6360x7c,
6370x10,
6380x10,
6390x00,
640
6410x00,
6420x42,
6430xbe,
6440x44,
6450x0c,
6460x08,
6470x18,
6480x10,
6490x30,
6500x20,
6510x64,
6520x4a,
6530xc4,
6540x00,
6550x00,
6560x00,
657
6580x00,
6590x38,
6600x6c,
6610x6c,
6620x6c,
6630x38,
6640x37,
6650x72,
6660xdc,
6670xcc,
6680xcc,
6690xcc,
6700x77,
6710x00,
6720x00,
6730x00,
674
6750x10,
6760x38,
6770x18,
6780x08,
6790x10,
6800x20,
6810x00,
6820x00,
6830x00,
6840x00,
6850x00,
6860x00,
6870x00,
6880x00,
6890x00,
6900x00,
691
6920x00,
6930x04,
6940x08,
6950x10,
6960x10,
6970x30,
6980x30,
6990x30,
7000x30,
7010x30,
7020x10,
7030x10,
7040x08,
7050x04,
7060x00,
7070x00,
708
7090x00,
7100x20,
7110x10,
7120x08,
7130x08,
7140x0c,
7150x0c,
7160x0c,
7170x0c,
7180x0c,
7190x08,
7200x08,
7210x10,
7220x20,
7230x00,
7240x00,
725
7260x00,
7270x00,
7280x00,
7290x00,
7300x44,
7310x28,
7320x38,
7330xfe,
7340x38,
7350x28,
7360x44,
7370x00,
7380x00,
7390x00,
7400x00,
7410x00,
742
7430x00,
7440x00,
7450x00,
7460x00,
7470x00,
7480x18,
7490x18,
7500x7e,
7510x18,
7520x18,
7530x00,
7540x00,
7550x00,
7560x00,
7570x00,
7580x00,
759
7600x00,
7610x00,
7620x00,
7630x00,
7640x00,
7650x00,
7660x00,
7670x00,
7680x00,
7690x00,
7700x10,
7710x38,
7720x18,
7730x08,
7740x10,
7750x20,
776
7770x00,
7780x00,
7790x00,
7800x00,
7810x00,
7820x00,
7830x00,
7840x7e,
7850x00,
7860x00,
7870x00,
7880x00,
7890x00,
7900x00,
7910x00,
7920x00,
793
7940x00,
7950x00,
7960x00,
7970x00,
7980x00,
7990x00,
8000x00,
8010x00,
8020x00,
8030x00,
8040x10,
8050x38,
8060x10,
8070x00,
8080x00,
8090x00,
810
8110x00,
8120x06,
8130x06,
8140x0c,
8150x0c,
8160x18,
8170x18,
8180x30,
8190x30,
8200x60,
8210x60,
8220xc0,
8230xc0,
8240x00,
8250x00,
8260x00,
827
8280x00,
8290x00,
8300x00,
8310x00,
8320x3c,
8330x46,
8340xc6,
8350xc6,
8360xc6,
8370xc6,
8380xc6,
8390xc4,
8400x78,
8410x00,
8420x00,
8430x00,
844
8450x00,
8460x00,
8470x00,
8480x00,
8490x08,
8500x18,
8510x78,
8520x18,
8530x18,
8540x18,
8550x18,
8560x18,
8570x7e,
8580x00,
8590x00,
8600x00,
861
8620x00,
8630x00,
8640x00,
8650x00,
8660x7c,
8670x86,
8680x06,
8690x0c,
8700x18,
8710x20,
8720x40,
8730xc1,
8740xfe,
8750x00,
8760x00,
8770x00,
878
8790x00,
8800x00,
8810x00,
8820x00,
8830x3c,
8840x46,
8850x04,
8860x08,
8870x1c,
8880x06,
8890x06,
8900x06,
8910x06,
8920x0c,
8930x70,
8940x00,
895
8960x00,
8970x00,
8980x00,
8990x00,
9000x04,
9010x08,
9020x10,
9030x2c,
9040x4c,
9050x8c,
9060x8c,
9070xfe,
9080x0c,
9090x0c,
9100x0c,
9110x00,
912
9130x00,
9140x00,
9150x00,
9160x02,
9170x3c,
9180x20,
9190x20,
9200x70,
9210x0c,
9220x06,
9230x06,
9240x06,
9250x06,
9260x0c,
9270x70,
9280x00,
929
9300x00,
9310x00,
9320x18,
9330x20,
9340x40,
9350xc0,
9360xdc,
9370xc6,
9380xc6,
9390xc6,
9400xc6,
9410x44,
9420x38,
9430x00,
9440x00,
9450x00,
946
9470x00,
9480x00,
9490x00,
9500x40,
9510x7e,
9520x82,
9530x06,
9540x04,
9550x0c,
9560x18,
9570x18,
9580x30,
9590x30,
9600x30,
9610x30,
9620x00,
963
9640x00,
9650x00,
9660x7c,
9670xc6,
9680xc6,
9690x64,
9700x38,
9710x4c,
9720xc6,
9730xc6,
9740xc6,
9750xc6,
9760x7c,
9770x00,
9780x00,
9790x00,
980
9810x00,
9820x00,
9830x00,
9840x00,
9850x38,
9860x44,
9870xc6,
9880xc6,
9890x76,
9900x06,
9910x06,
9920x06,
9930x04,
9940x08,
9950x30,
9960x00,
997
9980x00,
9990x00,
10000x00,
10010x00,
10020x10,
10030x38,
10040x10,
10050x00,
10060x00,
10070x00,
10080x10,
10090x38,
10100x10,
10110x00,
10120x00,
10130x00,
1014
10150x00,
10160x00,
10170x00,
10180x00,
10190x10,
10200x38,
10210x10,
10220x00,
10230x00,
10240x00,
10250x10,
10260x38,
10270x18,
10280x08,
10290x10,
10300x20,
1031
10320x00,
10330x06,
10340x0c,
10350x18,
10360x30,
10370x60,
10380xa0,
10390xa0,
10400x60,
10410x30,
10420x18,
10430x0c,
10440x06,
10450x00,
10460x00,
10470x00,
1048
10490x00,
10500x00,
10510x00,
10520x00,
10530x00,
10540x7e,
10550x00,
10560x00,
10570x7e,
10580x00,
10590x00,
10600x00,
10610x00,
10620x00,
10630x00,
10640x00,
1065
10660x00,
10670x60,
10680x30,
10690x18,
10700x0c,
10710x06,
10720x05,
10730x05,
10740x06,
10750x0c,
10760x18,
10770x30,
10780x60,
10790x00,
10800x00,
10810x00,
1082
10830x00,
10840x7c,
10850x86,
10860xc6,
10870x06,
10880x04,
10890x08,
10900x10,
10910x10,
10920x18,
10930x00,
10940x18,
10950x18,
10960x00,
10970x00,
10980x00,
1099
11000x00,
11010x00,
11020x3c,
11030x46,
11040xc6,
11050xce,
11060xd6,
11070xd6,
11080xd6,
11090xdc,
11100xc0,
11110xc4,
11120x78,
11130x00,
11140x00,
11150x00,
1116
11170x00,
11180x18,
11190x18,
11200x18,
11210x3c,
11220x2c,
11230x2c,
11240x2c,
11250x7e,
11260x46,
11270x46,
11280x46,
11290xef,
11300x00,
11310x00,
11320x00,
1133
11340x00,
11350xfc,
11360x66,
11370x66,
11380x66,
11390x66,
11400x7c,
11410x66,
11420x66,
11430x66,
11440x66,
11450x66,
11460xfc,
11470x00,
11480x00,
11490x00,
1150
11510x00,
11520x3a,
11530x66,
11540xc2,
11550xc0,
11560xc0,
11570xc0,
11580xc0,
11590xc0,
11600xc0,
11610xc0,
11620x62,
11630x3c,
11640x00,
11650x00,
11660x00,
1167
11680x00,
11690xfc,
11700x66,
11710x63,
11720x63,
11730x63,
11740x63,
11750x63,
11760x63,
11770x63,
11780x63,
11790x66,
11800xfc,
11810x00,
11820x00,
11830x00,
1184
11850x00,
11860xff,
11870x61,
11880x60,
11890x60,
11900x64,
11910x7c,
11920x64,
11930x60,
11940x60,
11950x60,
11960x61,
11970xfe,
11980x00,
11990x00,
12000x00,
1201
12020x00,
12030xff,
12040x61,
12050x61,
12060x60,
12070x64,
12080x7c,
12090x64,
12100x60,
12110x60,
12120x60,
12130x60,
12140xf0,
12150x00,
12160x00,
12170x00,
1218
12190x00,
12200x3a,
12210x66,
12220xc2,
12230xc0,
12240xc0,
12250xc0,
12260xcf,
12270xc6,
12280xc6,
12290xc6,
12300x66,
12310x38,
12320x00,
12330x00,
12340x00,
1235
12360x00,
12370xf7,
12380x62,
12390x62,
12400x62,
12410x62,
12420x7e,
12430x62,
12440x62,
12450x62,
12460x62,
12470x62,
12480xf7,
12490x00,
12500x00,
12510x00,
1252
12530x00,
12540x3c,
12550x18,
12560x18,
12570x18,
12580x18,
12590x18,
12600x18,
12610x18,
12620x18,
12630x18,
12640x18,
12650x3c,
12660x00,
12670x00,
12680x00,
1269
12700x00,
12710x1e,
12720x0c,
12730x0c,
12740x0c,
12750x0c,
12760x0c,
12770x0c,
12780x0c,
12790x0c,
12800x0c,
12810x0c,
12820x0c,
12830x0c,
12840x08,
12850xf0,
1286
12870x00,
12880xf7,
12890x64,
12900x6c,
12910x68,
12920x68,
12930x78,
12940x6c,
12950x6c,
12960x6c,
12970x66,
12980x66,
12990xf7,
13000x00,
13010x00,
13020x00,
1303
13040x00,
13050xf8,
13060x60,
13070x60,
13080x60,
13090x60,
13100x60,
13110x60,
13120x60,
13130x60,
13140x60,
13150x61,
13160xfe,
13170x00,
13180x00,
13190x00,
1320
13210x00,
13220xc3,
13230x66,
13240x76,
13250x7e,
13260x56,
13270x56,
13280x46,
13290x46,
13300x46,
13310x46,
13320x46,
13330xef,
13340x00,
13350x00,
13360x00,
1337
13380x00,
13390xe7,
13400x62,
13410x62,
13420x72,
13430x52,
13440x5a,
13450x4a,
13460x4e,
13470x46,
13480x46,
13490x42,
13500xe2,
13510x00,
13520x00,
13530x00,
1354
13550x00,
13560x3c,
13570x66,
13580xc3,
13590xc3,
13600xc3,
13610xc3,
13620xc3,
13630xc3,
13640xc3,
13650xc3,
13660x66,
13670x3c,
13680x00,
13690x00,
13700x00,
1371
13720x00,
13730xfc,
13740x66,
13750x66,
13760x66,
13770x66,
13780x6c,
13790x60,
13800x60,
13810x60,
13820x60,
13830x60,
13840xf0,
13850x00,
13860x00,
13870x00,
1388
13890x00,
13900x3c,
13910x66,
13920xc3,
13930xc3,
13940xc3,
13950xc3,
13960xc3,
13970xc3,
13980xc3,
13990xc3,
14000x66,
14010x3c,
14020x10,
14030x39,
14040x0e,
1405
14060x00,
14070xfc,
14080x66,
14090x66,
14100x66,
14110x66,
14120x7c,
14130x6c,
14140x66,
14150x66,
14160x66,
14170x66,
14180xf3,
14190x00,
14200x00,
14210x00,
1422
14230x00,
14240x7a,
14250xc6,
14260xc2,
14270xc0,
14280x70,
14290x3c,
14300x0e,
14310x06,
14320x06,
14330x86,
14340xc6,
14350xbc,
14360x00,
14370x00,
14380x00,
1439
14400x00,
14410xff,
14420x99,
14430x18,
14440x18,
14450x18,
14460x18,
14470x18,
14480x18,
14490x18,
14500x18,
14510x18,
14520x3c,
14530x00,
14540x00,
14550x00,
1456
14570x00,
14580xf7,
14590x62,
14600x62,
14610x62,
14620x62,
14630x62,
14640x62,
14650x62,
14660x62,
14670x62,
14680x62,
14690x3c,
14700x00,
14710x00,
14720x00,
1473
14740x00,
14750xf7,
14760x62,
14770x62,
14780x62,
14790x76,
14800x34,
14810x34,
14820x34,
14830x3c,
14840x18,
14850x18,
14860x18,
14870x00,
14880x00,
14890x00,
1490
14910x00,
14920xf7,
14930x62,
14940x62,
14950x62,
14960x62,
14970x6a,
14980x6a,
14990x6a,
15000x6a,
15010x7e,
15020x7e,
15030x34,
15040x00,
15050x00,
15060x00,
1507
15080x00,
15090xf7,
15100x62,
15110x62,
15120x34,
15130x34,
15140x18,
15150x18,
15160x2c,
15170x2c,
15180x46,
15190x46,
15200xef,
15210x00,
15220x00,
15230x00,
1524
15250x00,
15260xf7,
15270x62,
15280x62,
15290x62,
15300x34,
15310x34,
15320x18,
15330x18,
15340x18,
15350x18,
15360x18,
15370x3c,
15380x00,
15390x00,
15400x00,
1541
15420x00,
15430x7f,
15440x46,
15450x86,
15460x0c,
15470x0c,
15480x18,
15490x18,
15500x30,
15510x30,
15520x61,
15530x62,
15540xfe,
15550x00,
15560x00,
15570x00,
1558
15590x00,
15600x3c,
15610x30,
15620x30,
15630x30,
15640x30,
15650x30,
15660x30,
15670x30,
15680x30,
15690x30,
15700x30,
15710x3c,
15720x00,
15730x00,
15740x00,
1575
15760x00,
15770xc0,
15780xc0,
15790x60,
15800x60,
15810x30,
15820x30,
15830x18,
15840x18,
15850x0c,
15860x0c,
15870x06,
15880x06,
15890x00,
15900x00,
15910x00,
1592
15930x00,
15940x3c,
15950x0c,
15960x0c,
15970x0c,
15980x0c,
15990x0c,
16000x0c,
16010x0c,
16020x0c,
16030x0c,
16040x0c,
16050x3c,
16060x00,
16070x00,
16080x00,
1609
16100x00,
16110x10,
16120x38,
16130x4c,
16140x86,
16150x00,
16160x00,
16170x00,
16180x00,
16190x00,
16200x00,
16210x00,
16220x00,
16230x00,
16240x00,
16250x00,
1626
16270x00,
16280x00,
16290x00,
16300x00,
16310x00,
16320x00,
16330x00,
16340x00,
16350x00,
16360x00,
16370x00,
16380x00,
16390x00,
16400xff,
16410x00,
16420x00,
1643
16440x00,
16450x18,
16460x20,
16470x30,
16480x38,
16490x10,
16500x00,
16510x00,
16520x00,
16530x00,
16540x00,
16550x00,
16560x00,
16570x00,
16580x00,
16590x00,
1660
16610x00,
16620x00,
16630x00,
16640x00,
16650x00,
16660x78,
16670x8c,
16680x0c,
16690x3c,
16700xcc,
16710xcc,
16720xcd,
16730x76,
16740x00,
16750x00,
16760x00,
1677
16780x00,
16790x20,
16800xe0,
16810x60,
16820x60,
16830x6c,
16840x76,
16850x66,
16860x66,
16870x66,
16880x66,
16890x76,
16900x6c,
16910x00,
16920x00,
16930x00,
1694
16950x00,
16960x00,
16970x00,
16980x00,
16990x00,
17000x3c,
17010x66,
17020x60,
17030x60,
17040x60,
17050x60,
17060x62,
17070x3c,
17080x00,
17090x00,
17100x00,
1711
17120x00,
17130x04,
17140x1c,
17150x0c,
17160x0c,
17170x6c,
17180xdc,
17190xcc,
17200xcc,
17210xcc,
17220xcc,
17230xdc,
17240x66,
17250x00,
17260x00,
17270x00,
1728
17290x00,
17300x00,
17310x00,
17320x00,
17330x00,
17340x3c,
17350x66,
17360x7e,
17370x60,
17380x60,
17390x60,
17400x62,
17410x3c,
17420x00,
17430x00,
17440x00,
1745
17460x00,
17470x1e,
17480x31,
17490x33,
17500x30,
17510x30,
17520x78,
17530x30,
17540x30,
17550x30,
17560x30,
17570x30,
17580x78,
17590x00,
17600x00,
17610x00,
1762
17630x00,
17640x00,
17650x00,
17660x00,
17670x00,
17680x7b,
17690xce,
17700xcc,
17710xcc,
17720xcc,
17730x78,
17740x60,
17750x7c,
17760x86,
17770xc6,
17780x7c,
1779
17800x00,
17810x20,
17820xe0,
17830x60,
17840x60,
17850x6c,
17860x76,
17870x66,
17880x66,
17890x66,
17900x66,
17910x66,
17920xf7,
17930x00,
17940x00,
17950x00,
1796
17970x00,
17980x10,
17990x38,
18000x10,
18010x00,
18020x18,
18030x38,
18040x18,
18050x18,
18060x18,
18070x18,
18080x18,
18090x3c,
18100x00,
18110x00,
18120x00,
1813
18140x00,
18150x08,
18160x1c,
18170x08,
18180x00,
18190x0c,
18200x1c,
18210x0c,
18220x0c,
18230x0c,
18240x0c,
18250x0c,
18260x6c,
18270x4c,
18280x38,
18290x00,
1830
18310x00,
18320x20,
18330xe0,
18340x60,
18350x60,
18360x67,
18370x66,
18380x6c,
18390x78,
18400x6c,
18410x6c,
18420x66,
18430xe7,
18440x00,
18450x00,
18460x00,
1847
18480x00,
18490x08,
18500x38,
18510x18,
18520x18,
18530x18,
18540x18,
18550x18,
18560x18,
18570x18,
18580x18,
18590x18,
18600x3c,
18610x00,
18620x00,
18630x00,
1864
18650x00,
18660x00,
18670x00,
18680x00,
18690x00,
18700x6a,
18710xfe,
18720x6a,
18730x6a,
18740x6a,
18750x62,
18760x62,
18770xf7,
18780x00,
18790x00,
18800x00,
1881
18820x00,
18830x00,
18840x00,
18850x00,
18860x00,
18870x5c,
18880xf6,
18890x66,
18900x66,
18910x66,
18920x66,
18930x66,
18940xf7,
18950x00,
18960x00,
18970x00,
1898
18990x00,
19000x00,
19010x00,
19020x00,
19030x00,
19040x3c,
19050x66,
19060x66,
19070x66,
19080x66,
19090x66,
19100x66,
19110x3c,
19120x00,
19130x00,
19140x00,
1915
19160x00,
19170x00,
19180x00,
19190x00,
19200x00,
19210x5c,
19220xe6,
19230x66,
19240x66,
19250x66,
19260x66,
19270x66,
19280x7c,
19290x60,
19300x60,
19310xf0,
1932
19330x00,
19340x00,
19350x00,
19360x00,
19370x00,
19380x76,
19390xcc,
19400xcc,
19410xcc,
19420xcc,
19430xcc,
19440xcc,
19450x7c,
19460x0c,
19470x0c,
19480x1e,
1949
19500x00,
19510x00,
19520x00,
19530x00,
19540x00,
19550x5e,
19560xf6,
19570x60,
19580x60,
19590x60,
19600x60,
19610x60,
19620xf0,
19630x00,
19640x00,
19650x00,
1966
19670x00,
19680x00,
19690x00,
19700x00,
19710x00,
19720x7a,
19730xc6,
19740x72,
19750x1c,
19760x06,
19770x86,
19780xc6,
19790xbc,
19800x00,
19810x00,
19820x00,
1983
19840x00,
19850x00,
19860x00,
19870x10,
19880x30,
19890x7c,
19900x30,
19910x30,
19920x30,
19930x30,
19940x30,
19950x34,
19960x18,
19970x00,
19980x00,
19990x00,
2000
20010x00,
20020x00,
20030x00,
20040x00,
20050x00,
20060xee,
20070x66,
20080x66,
20090x66,
20100x66,
20110x66,
20120x67,
20130x3a,
20140x00,
20150x00,
20160x00,
2017
20180x00,
20190x00,
20200x00,
20210x00,
20220x00,
20230xf7,
20240x62,
20250x76,
20260x34,
20270x34,
20280x3c,
20290x18,
20300x18,
20310x00,
20320x00,
20330x00,
2034
20350x00,
20360x00,
20370x00,
20380x00,
20390x00,
20400xf7,
20410x62,
20420x6a,
20430x6a,
20440x6a,
20450x6a,
20460x7e,
20470x24,
20480x00,
20490x00,
20500x00,
2051
20520x00,
20530x00,
20540x00,
20550x00,
20560x00,
20570xf7,
20580x62,
20590x34,
20600x18,
20610x2c,
20620x46,
20630x46,
20640xef,
20650x00,
20660x00,
20670x00,
2068
20690x00,
20700x00,
20710x00,
20720x00,
20730x00,
20740xf7,
20750x62,
20760x62,
20770x34,
20780x34,
20790x18,
20800x18,
20810x18,
20820x10,
20830xb0,
20840xe0,
2085
20860x00,
20870x00,
20880x00,
20890x00,
20900x00,
20910xfe,
20920x8c,
20930x18,
20940x30,
20950x30,
20960x60,
20970xc2,
20980xfe,
20990x00,
21000x00,
21010x00,
2102
21030x00,
21040x0e,
21050x18,
21060x10,
21070x10,
21080x08,
21090x70,
21100x70,
21110x08,
21120x10,
21130x10,
21140x18,
21150x0e,
21160x00,
21170x00,
21180x00,
2119
21200x18,
21210x18,
21220x18,
21230x18,
21240x18,
21250x18,
21260x18,
21270x18,
21280x18,
21290x18,
21300x18,
21310x18,
21320x18,
21330x18,
21340x00,
21350x00,
2136
21370x00,
21380x70,
21390x18,
21400x08,
21410x08,
21420x10,
21430x0e,
21440x0e,
21450x10,
21460x08,
21470x08,
21480x18,
21490x70,
21500x00,
21510x00,
21520x00,
2153
21540x00,
21550x00,
21560x00,
21570x00,
21580x00,
21590x00,
21600x76,
21610xdc,
21620x00,
21630x00,
21640x00,
21650x00,
21660x00,
21670x00,
21680x00,
21690x00,
2170
21710x00,
21720x00,
21730x00,
21740x00,
21750x10,
21760x38,
21770x6c,
21780xc6,
21790xc6,
21800xc6,
21810xfe,
21820x00,
21830x00,
21840x00,
21850x00,
21860x00,
2187
21880x00,
21890x00,
21900x3a,
21910x66,
21920xc2,
21930xc0,
21940xc0,
21950xc0,
21960xc0,
21970xc0,
21980x62,
21990x3c,
22000x18,
22010x0c,
22020x24,
22030x18,
2204
22050x00,
22060x00,
22070x66,
22080x00,
22090x00,
22100xee,
22110x66,
22120x66,
22130x66,
22140x66,
22150x66,
22160x66,
22170x3b,
22180x00,
22190x00,
22200x00,
2221
22220x00,
22230x0c,
22240x18,
22250x20,
22260x00,
22270x3c,
22280x66,
22290x7e,
22300x60,
22310x60,
22320x60,
22330x62,
22340x3c,
22350x00,
22360x00,
22370x00,
2238
22390x00,
22400x30,
22410x58,
22420x8c,
22430x00,
22440x78,
22450x8c,
22460x0c,
22470x3c,
22480xcc,
22490xcc,
22500xcd,
22510x76,
22520x00,
22530x00,
22540x00,
2255
22560x00,
22570x00,
22580x66,
22590x00,
22600x00,
22610x78,
22620x8c,
22630x0c,
22640x3c,
22650xcc,
22660xcc,
22670xcd,
22680x76,
22690x00,
22700x00,
22710x00,
2272
22730x00,
22740x30,
22750x18,
22760x04,
22770x00,
22780x78,
22790x8c,
22800x0c,
22810x3c,
22820xcc,
22830xcc,
22840xcd,
22850x76,
22860x00,
22870x00,
22880x00,
2289
22900x38,
22910x44,
22920x44,
22930x38,
22940x00,
22950x78,
22960x8c,
22970x0c,
22980x3c,
22990xcc,
23000xcc,
23010xcd,
23020x76,
23030x00,
23040x00,
23050x00,
2306
23070x00,
23080x00,
23090x00,
23100x00,
23110x00,
23120x3c,
23130x66,
23140x60,
23150x60,
23160x60,
23170x60,
23180x62,
23190x3c,
23200x08,
23210x24,
23220x18,
2323
23240x00,
23250x18,
23260x2c,
23270x46,
23280x00,
23290x3c,
23300x66,
23310x7e,
23320x60,
23330x60,
23340x60,
23350x62,
23360x3c,
23370x00,
23380x00,
23390x00,
2340
23410x00,
23420x00,
23430x66,
23440x00,
23450x00,
23460x3c,
23470x66,
23480x7e,
23490x60,
23500x60,
23510x60,
23520x62,
23530x3c,
23540x00,
23550x00,
23560x00,
2357
23580x00,
23590x30,
23600x18,
23610x04,
23620x00,
23630x3c,
23640x66,
23650x7e,
23660x60,
23670x60,
23680x60,
23690x62,
23700x3c,
23710x00,
23720x00,
23730x00,
2374
23750x00,
23760x00,
23770x66,
23780x00,
23790x00,
23800x38,
23810x18,
23820x18,
23830x18,
23840x18,
23850x18,
23860x18,
23870x3c,
23880x00,
23890x00,
23900x00,
2391
23920x00,
23930x18,
23940x2c,
23950x46,
23960x00,
23970x38,
23980x18,
23990x18,
24000x18,
24010x18,
24020x18,
24030x18,
24040x3c,
24050x00,
24060x00,
24070x00,
2408
24090x00,
24100x60,
24110x30,
24120x08,
24130x00,
24140x38,
24150x18,
24160x18,
24170x18,
24180x18,
24190x18,
24200x18,
24210x3c,
24220x00,
24230x00,
24240x00,
2425
24260x66,
24270x18,
24280x18,
24290x18,
24300x3c,
24310x2c,
24320x2c,
24330x2c,
24340x7e,
24350x46,
24360x46,
24370x46,
24380xef,
24390x00,
24400x00,
24410x00,
2442
24430x18,
24440x24,
24450x18,
24460x18,
24470x3c,
24480x2c,
24490x2c,
24500x2c,
24510x7e,
24520x46,
24530x46,
24540x46,
24550xef,
24560x00,
24570x00,
24580x00,
2459
24600x0c,
24610x18,
24620xff,
24630x61,
24640x60,
24650x60,
24660x64,
24670x7c,
24680x64,
24690x60,
24700x60,
24710x61,
24720xfe,
24730x00,
24740x00,
24750x00,
2476
24770x00,
24780x00,
24790x00,
24800x00,
24810x00,
24820x76,
24830x9b,
24840x1b,
24850x3f,
24860xd8,
24870xd8,
24880xd9,
24890x6e,
24900x00,
24910x00,
24920x00,
2493
24940x00,
24950x1f,
24960x1d,
24970x1d,
24980x3c,
24990x2c,
25000x2e,
25010x2c,
25020x7c,
25030x4c,
25040x4c,
25050x4d,
25060xef,
25070x00,
25080x00,
25090x00,
2510
25110x00,
25120x18,
25130x2c,
25140x46,
25150x00,
25160x3c,
25170x66,
25180x66,
25190x66,
25200x66,
25210x66,
25220x66,
25230x3c,
25240x00,
25250x00,
25260x00,
2527
25280x00,
25290x00,
25300x66,
25310x00,
25320x00,
25330x3c,
25340x66,
25350x66,
25360x66,
25370x66,
25380x66,
25390x66,
25400x3c,
25410x00,
25420x00,
25430x00,
2544
25450x00,
25460x30,
25470x18,
25480x04,
25490x00,
25500x3c,
25510x66,
25520x66,
25530x66,
25540x66,
25550x66,
25560x66,
25570x3c,
25580x00,
25590x00,
25600x00,
2561
25620x00,
25630x18,
25640x2c,
25650x46,
25660x00,
25670xee,
25680x66,
25690x66,
25700x66,
25710x66,
25720x66,
25730x67,
25740x3a,
25750x00,
25760x00,
25770x00,
2578
25790x00,
25800x30,
25810x18,
25820x04,
25830x00,
25840xee,
25850x66,
25860x66,
25870x66,
25880x66,
25890x66,
25900x67,
25910x3a,
25920x00,
25930x00,
25940x00,
2595
25960x00,
25970x00,
25980x66,
25990x00,
26000x00,
26010xf7,
26020x62,
26030x62,
26040x34,
26050x34,
26060x18,
26070x18,
26080x18,
26090x10,
26100xb0,
26110xe0,
2612
26130x66,
26140x00,
26150x3c,
26160x66,
26170xc3,
26180xc3,
26190xc3,
26200xc3,
26210xc3,
26220xc3,
26230xc3,
26240x66,
26250x3c,
26260x00,
26270x00,
26280x00,
2629
26300x66,
26310x00,
26320xf7,
26330x62,
26340x62,
26350x62,
26360x62,
26370x62,
26380x62,
26390x62,
26400x62,
26410x62,
26420x3c,
26430x00,
26440x00,
26450x00,
2646
26470x00,
26480x00,
26490x10,
26500x10,
26510x10,
26520x7c,
26530xc6,
26540xc0,
26550xc0,
26560xc0,
26570xc0,
26580xc2,
26590x7c,
26600x10,
26610x10,
26620x00,
2663
26640x00,
26650x38,
26660x64,
26670x6c,
26680x60,
26690x60,
26700xf0,
26710x60,
26720x60,
26730x60,
26740x60,
26750x66,
26760xfc,
26770x00,
26780x00,
26790x00,
2680
26810x00,
26820x81,
26830xc3,
26840x66,
26850x3c,
26860x18,
26870xff,
26880x18,
26890x18,
26900xff,
26910x18,
26920x18,
26930x18,
26940x00,
26950x00,
26960x00,
2697
26980x00,
26990xfe,
27000x63,
27010x63,
27020x63,
27030x63,
27040x6e,
27050x60,
27060x64,
27070x6e,
27080x64,
27090x64,
27100xf5,
27110x06,
27120x00,
27130x00,
2714
27150x00,
27160x0e,
27170x19,
27180x1b,
27190x18,
27200x18,
27210x3c,
27220x18,
27230x18,
27240x18,
27250x18,
27260xd8,
27270x98,
27280x70,
27290x00,
27300x00,
2731
27320x00,
27330x0c,
27340x18,
27350x20,
27360x00,
27370x78,
27380x8c,
27390x0c,
27400x3c,
27410xcc,
27420xcc,
27430xcd,
27440x76,
27450x00,
27460x00,
27470x00,
2748
27490x00,
27500x06,
27510x0c,
27520x10,
27530x00,
27540x38,
27550x18,
27560x18,
27570x18,
27580x18,
27590x18,
27600x18,
27610x3c,
27620x00,
27630x00,
27640x00,
2765
27660x00,
27670x0c,
27680x18,
27690x20,
27700x00,
27710x3c,
27720x66,
27730x66,
27740x66,
27750x66,
27760x66,
27770x66,
27780x3c,
27790x00,
27800x00,
27810x00,
2782
27830x00,
27840x0c,
27850x18,
27860x20,
27870x00,
27880xee,
27890x66,
27900x66,
27910x66,
27920x66,
27930x66,
27940x67,
27950x3a,
27960x00,
27970x00,
27980x00,
2799
28000x00,
28010x00,
28020x32,
28030x4c,
28040x00,
28050x5c,
28060xf6,
28070x66,
28080x66,
28090x66,
28100x66,
28110x66,
28120xf7,
28130x00,
28140x00,
28150x00,
2816
28170x32,
28180x4c,
28190x00,
28200xe7,
28210x72,
28220x52,
28230x5a,
28240x4a,
28250x4e,
28260x46,
28270x46,
28280x42,
28290xe2,
28300x00,
28310x00,
28320x00,
2833
28340x00,
28350x78,
28360x8c,
28370x0c,
28380x3c,
28390xcc,
28400xcc,
28410xcd,
28420x76,
28430x00,
28440xfe,
28450x00,
28460x00,
28470x00,
28480x00,
28490x00,
2850
28510x00,
28520x3c,
28530x66,
28540x66,
28550x66,
28560x66,
28570x66,
28580x66,
28590x3c,
28600x00,
28610x7e,
28620x00,
28630x00,
28640x00,
28650x00,
28660x00,
2867
28680x00,
28690x30,
28700x30,
28710x00,
28720x30,
28730x10,
28740x10,
28750x20,
28760x40,
28770xc0,
28780xc6,
28790xc2,
28800x7c,
28810x00,
28820x00,
28830x00,
2884
28850x00,
28860x00,
28870x00,
28880x00,
28890x00,
28900x00,
28910xfe,
28920xc0,
28930xc0,
28940xc0,
28950xc0,
28960x00,
28970x00,
28980x00,
28990x00,
29000x00,
2901
29020x00,
29030x00,
29040x00,
29050x00,
29060x00,
29070x00,
29080xfe,
29090x06,
29100x06,
29110x06,
29120x06,
29130x00,
29140x00,
29150x00,
29160x00,
29170x00,
2918
29190x00,
29200x20,
29210xe0,
29220x63,
29230x66,
29240xfc,
29250x18,
29260x30,
29270x60,
29280xce,
29290x93,
29300x06,
29310x0c,
29320x1f,
29330x00,
29340x00,
2935
29360x00,
29370x20,
29380xe0,
29390x63,
29400x66,
29410xfc,
29420x18,
29430x30,
29440x64,
29450xc8,
29460x96,
29470x3f,
29480x06,
29490x06,
29500x00,
29510x00,
2952
29530x00,
29540x18,
29550x18,
29560x00,
29570x08,
29580x18,
29590x18,
29600x18,
29610x3c,
29620x3c,
29630x3c,
29640x3c,
29650x18,
29660x00,
29670x00,
29680x00,
2969
29700x00,
29710x00,
29720x00,
29730x00,
29740x00,
29750x36,
29760x6c,
29770xd8,
29780xd8,
29790x6c,
29800x36,
29810x00,
29820x00,
29830x00,
29840x00,
29850x00,
2986
29870x00,
29880x00,
29890x00,
29900x00,
29910x00,
29920xd8,
29930x6c,
29940x36,
29950x36,
29960x6c,
29970xd8,
29980x00,
29990x00,
30000x00,
30010x00,
30020x00,
3003
30040x82,
30050x10,
30060x82,
30070x10,
30080x82,
30090x10,
30100x82,
30110x10,
30120x82,
30130x10,
30140x82,
30150x10,
30160x82,
30170x10,
30180x82,
30190x10,
3020
30210x00,
30220x95,
30230x00,
30240xa9,
30250x00,
30260x95,
30270x00,
30280xa9,
30290x00,
30300x95,
30310x00,
30320xa9,
30330x00,
30340x95,
30350x00,
30360xa9,
3037
30380x92,
30390x49,
30400x92,
30410x49,
30420x92,
30430x49,
30440x92,
30450x49,
30460x92,
30470x49,
30480x92,
30490x49,
30500x92,
30510x49,
30520x92,
30530x49,
3054
30550x18,
30560x18,
30570x18,
30580x18,
30590x18,
30600x18,
30610x18,
30620x18,
30630x18,
30640x18,
30650x18,
30660x18,
30670x18,
30680x18,
30690x18,
30700x18,
3071
30720x18,
30730x18,
30740x18,
30750x18,
30760x18,
30770x18,
30780x18,
30790xf8,
30800x18,
30810x18,
30820x18,
30830x18,
30840x18,
30850x18,
30860x18,
30870x18,
3088
30890x18,
30900x18,
30910x18,
30920x18,
30930x18,
30940x18,
30950xf8,
30960x18,
30970x18,
30980xf8,
30990x18,
31000x18,
31010x18,
31020x18,
31030x18,
31040x18,
3105
31060x66,
31070x66,
31080x66,
31090x66,
31100x66,
31110x66,
31120x66,
31130xe6,
31140x66,
31150x66,
31160x66,
31170x66,
31180x66,
31190x66,
31200x66,
31210x66,
3122
31230x00,
31240x00,
31250x00,
31260x00,
31270x00,
31280x00,
31290x00,
31300xfe,
31310x66,
31320x66,
31330x66,
31340x66,
31350x66,
31360x66,
31370x66,
31380x66,
3139
31400x00,
31410x00,
31420x00,
31430x00,
31440x00,
31450x00,
31460xf8,
31470x18,
31480x18,
31490xf8,
31500x18,
31510x18,
31520x18,
31530x18,
31540x18,
31550x18,
3156
31570x66,
31580x66,
31590x66,
31600x66,
31610x66,
31620x66,
31630xe6,
31640x06,
31650x06,
31660xe6,
31670x66,
31680x66,
31690x66,
31700x66,
31710x66,
31720x66,
3173
31740x66,
31750x66,
31760x66,
31770x66,
31780x66,
31790x66,
31800x66,
31810x66,
31820x66,
31830x66,
31840x66,
31850x66,
31860x66,
31870x66,
31880x66,
31890x66,
3190
31910x00,
31920x00,
31930x00,
31940x00,
31950x00,
31960x00,
31970xfe,
31980x06,
31990x06,
32000xe6,
32010x66,
32020x66,
32030x66,
32040x66,
32050x66,
32060x66,
3207
32080x66,
32090x66,
32100x66,
32110x66,
32120x66,
32130x66,
32140xe6,
32150x06,
32160x06,
32170xfe,
32180x00,
32190x00,
32200x00,
32210x00,
32220x00,
32230x00,
3224
32250x66,
32260x66,
32270x66,
32280x66,
32290x66,
32300x66,
32310x66,
32320xfe,
32330x00,
32340x00,
32350x00,
32360x00,
32370x00,
32380x00,
32390x00,
32400x00,
3241
32420x18,
32430x18,
32440x18,
32450x18,
32460x18,
32470x18,
32480xf8,
32490x18,
32500x18,
32510xf8,
32520x00,
32530x00,
32540x00,
32550x00,
32560x00,
32570x00,
3258
32590x00,
32600x00,
32610x00,
32620x00,
32630x00,
32640x00,
32650x00,
32660xf8,
32670x18,
32680x18,
32690x18,
32700x18,
32710x18,
32720x18,
32730x18,
32740x18,
3275
32760x18,
32770x18,
32780x18,
32790x18,
32800x18,
32810x18,
32820x18,
32830x1f,
32840x00,
32850x00,
32860x00,
32870x00,
32880x00,
32890x00,
32900x00,
32910x00,
3292
32930x18,
32940x18,
32950x18,
32960x18,
32970x18,
32980x18,
32990x18,
33000xff,
33010x00,
33020x00,
33030x00,
33040x00,
33050x00,
33060x00,
33070x00,
33080x00,
3309
33100x00,
33110x00,
33120x00,
33130x00,
33140x00,
33150x00,
33160x00,
33170xff,
33180x18,
33190x18,
33200x18,
33210x18,
33220x18,
33230x18,
33240x18,
33250x18,
3326
33270x18,
33280x18,
33290x18,
33300x18,
33310x18,
33320x18,
33330x18,
33340x1f,
33350x18,
33360x18,
33370x18,
33380x18,
33390x18,
33400x18,
33410x18,
33420x18,
3343
33440x00,
33450x00,
33460x00,
33470x00,
33480x00,
33490x00,
33500x00,
33510xff,
33520x00,
33530x00,
33540x00,
33550x00,
33560x00,
33570x00,
33580x00,
33590x00,
3360
33610x18,
33620x18,
33630x18,
33640x18,
33650x18,
33660x18,
33670x18,
33680xff,
33690x18,
33700x18,
33710x18,
33720x18,
33730x18,
33740x18,
33750x18,
33760x18,
3377
33780x18,
33790x18,
33800x18,
33810x18,
33820x18,
33830x18,
33840x1f,
33850x18,
33860x18,
33870x1f,
33880x18,
33890x18,
33900x18,
33910x18,
33920x18,
33930x18,
3394
33950x66,
33960x66,
33970x66,
33980x66,
33990x66,
34000x66,
34010x66,
34020x67,
34030x66,
34040x66,
34050x66,
34060x66,
34070x66,
34080x66,
34090x66,
34100x66,
3411
34120x66,
34130x66,
34140x66,
34150x66,
34160x66,
34170x66,
34180x67,
34190x60,
34200x60,
34210x7f,
34220x00,
34230x00,
34240x00,
34250x00,
34260x00,
34270x00,
3428
34290x00,
34300x00,
34310x00,
34320x00,
34330x00,
34340x00,
34350x7f,
34360x60,
34370x60,
34380x67,
34390x66,
34400x66,
34410x66,
34420x66,
34430x66,
34440x66,
3445
34460x66,
34470x66,
34480x66,
34490x66,
34500x66,
34510x66,
34520xe7,
34530x00,
34540x00,
34550xff,
34560x00,
34570x00,
34580x00,
34590x00,
34600x00,
34610x00,
3462
34630x00,
34640x00,
34650x00,
34660x00,
34670x00,
34680x00,
34690xff,
34700x00,
34710x00,
34720xe7,
34730x66,
34740x66,
34750x66,
34760x66,
34770x66,
34780x66,
3479
34800x66,
34810x66,
34820x66,
34830x66,
34840x66,
34850x66,
34860x67,
34870x60,
34880x60,
34890x67,
34900x66,
34910x66,
34920x66,
34930x66,
34940x66,
34950x66,
3496
34970x00,
34980x00,
34990x00,
35000x00,
35010x00,
35020x00,
35030xff,
35040x00,
35050x00,
35060xff,
35070x00,
35080x00,
35090x00,
35100x00,
35110x00,
35120x00,
3513
35140x66,
35150x66,
35160x66,
35170x66,
35180x66,
35190x66,
35200xe7,
35210x00,
35220x00,
35230xe7,
35240x66,
35250x66,
35260x66,
35270x66,
35280x66,
35290x66,
3530
35310x18,
35320x18,
35330x18,
35340x18,
35350x18,
35360x18,
35370xff,
35380x00,
35390x00,
35400xff,
35410x00,
35420x00,
35430x00,
35440x00,
35450x00,
35460x00,
3547
35480x66,
35490x66,
35500x66,
35510x66,
35520x66,
35530x66,
35540x66,
35550xff,
35560x00,
35570x00,
35580x00,
35590x00,
35600x00,
35610x00,
35620x00,
35630x00,
3564
35650x00,
35660x00,
35670x00,
35680x00,
35690x00,
35700x00,
35710xff,
35720x00,
35730x00,
35740xff,
35750x18,
35760x18,
35770x18,
35780x18,
35790x18,
35800x18,
3581
35820x00,
35830x00,
35840x00,
35850x00,
35860x00,
35870x00,
35880x00,
35890xff,
35900x66,
35910x66,
35920x66,
35930x66,
35940x66,
35950x66,
35960x66,
35970x66,
3598
35990x66,
36000x66,
36010x66,
36020x66,
36030x66,
36040x66,
36050x66,
36060x7f,
36070x00,
36080x00,
36090x00,
36100x00,
36110x00,
36120x00,
36130x00,
36140x00,
3615
36160x18,
36170x18,
36180x18,
36190x18,
36200x18,
36210x18,
36220x1f,
36230x18,
36240x18,
36250x1f,
36260x00,
36270x00,
36280x00,
36290x00,
36300x00,
36310x00,
3632
36330x00,
36340x00,
36350x00,
36360x00,
36370x00,
36380x00,
36390x1f,
36400x18,
36410x18,
36420x1f,
36430x18,
36440x18,
36450x18,
36460x18,
36470x18,
36480x18,
3649
36500x00,
36510x00,
36520x00,
36530x00,
36540x00,
36550x00,
36560x00,
36570x7f,
36580x66,
36590x66,
36600x66,
36610x66,
36620x66,
36630x66,
36640x66,
36650x66,
3666
36670x66,
36680x66,
36690x66,
36700x66,
36710x66,
36720x66,
36730x66,
36740xff,
36750x66,
36760x66,
36770x66,
36780x66,
36790x66,
36800x66,
36810x66,
36820x66,
3683
36840x18,
36850x18,
36860x18,
36870x18,
36880x18,
36890x18,
36900xff,
36910x00,
36920x00,
36930xff,
36940x18,
36950x18,
36960x18,
36970x18,
36980x18,
36990x18,
3700
37010x18,
37020x18,
37030x18,
37040x18,
37050x18,
37060x18,
37070x18,
37080xf8,
37090x00,
37100x00,
37110x00,
37120x00,
37130x00,
37140x00,
37150x00,
37160x00,
3717
37180x00,
37190x00,
37200x00,
37210x00,
37220x00,
37230x00,
37240x00,
37250x1f,
37260x18,
37270x18,
37280x18,
37290x18,
37300x18,
37310x18,
37320x18,
37330x18,
3734
37350xff,
37360xff,
37370xff,
37380xff,
37390xff,
37400xff,
37410xff,
37420xff,
37430xff,
37440xff,
37450xff,
37460xff,
37470xff,
37480xff,
37490xff,
37500xff,
3751
37520x00,
37530x00,
37540x00,
37550x00,
37560x00,
37570x00,
37580x00,
37590x00,
37600xff,
37610xff,
37620xff,
37630xff,
37640xff,
37650xff,
37660xff,
37670xff,
3768
37690xf0,
37700xf0,
37710xf0,
37720xf0,
37730xf0,
37740xf0,
37750xf0,
37760xf0,
37770xf0,
37780xf0,
37790xf0,
37800xf0,
37810xf0,
37820xf0,
37830xf0,
37840xf0,
3785
37860x0f,
37870x0f,
37880x0f,
37890x0f,
37900x0f,
37910x0f,
37920x0f,
37930x0f,
37940x0f,
37950x0f,
37960x0f,
37970x0f,
37980x0f,
37990x0f,
38000x0f,
38010x0f,
3802
38030xff,
38040xff,
38050xff,
38060xff,
38070xff,
38080xff,
38090xff,
38100xff,
38110x00,
38120x00,
38130x00,
38140x00,
38150x00,
38160x00,
38170x00,
38180x00,
3819
38200x00,
38210x00,
38220x00,
38230x00,
38240x00,
38250x00,
38260x77,
38270xcc,
38280xcc,
38290xcc,
38300xcc,
38310xde,
38320x73,
38330x00,
38340x00,
38350x00,
3836
38370x00,
38380x7c,
38390xc6,
38400xc6,
38410xc6,
38420xc4,
38430xc8,
38440xc4,
38450xc6,
38460xc6,
38470xc6,
38480xc6,
38490xdc,
38500xc0,
38510xc0,
38520x00,
3853
38540x00,
38550xff,
38560x61,
38570x60,
38580x60,
38590x60,
38600x60,
38610x60,
38620x60,
38630x60,
38640x60,
38650x60,
38660xf0,
38670x00,
38680x00,
38690x00,
3870
38710x00,
38720x00,
38730x00,
38740x00,
38750x01,
38760x7e,
38770xa4,
38780x24,
38790x2c,
38800x6c,
38810x6c,
38820x6c,
38830x48,
38840x00,
38850x00,
38860x00,
3887
38880x00,
38890xff,
38900xc1,
38910x60,
38920x30,
38930x18,
38940x0c,
38950x18,
38960x30,
38970x60,
38980xc0,
38990xc1,
39000xfe,
39010x00,
39020x00,
39030x00,
3904
39050x00,
39060x00,
39070x00,
39080x00,
39090x00,
39100x7f,
39110xc8,
39120xc8,
39130xc8,
39140xc8,
39150xc8,
39160xc8,
39170x70,
39180x00,
39190x00,
39200x00,
3921
39220x00,
39230x00,
39240x00,
39250x00,
39260x00,
39270x22,
39280x66,
39290x66,
39300x66,
39310x66,
39320x66,
39330x7c,
39340x60,
39350x60,
39360x60,
39370xc0,
3938
39390x00,
39400x00,
39410x00,
39420x00,
39430x00,
39440x76,
39450xdc,
39460x18,
39470x18,
39480x18,
39490x18,
39500x18,
39510x10,
39520x00,
39530x00,
39540x00,
3955
39560x00,
39570x38,
39580x10,
39590x7c,
39600xd6,
39610xd6,
39620xd6,
39630xd6,
39640xd6,
39650xd6,
39660x7c,
39670x10,
39680x38,
39690x00,
39700x00,
39710x00,
3972
39730x00,
39740x38,
39750x6c,
39760xc6,
39770xc6,
39780xc6,
39790xfe,
39800xc6,
39810xc6,
39820xc6,
39830xc6,
39840x6c,
39850x38,
39860x00,
39870x00,
39880x00,
3989
39900x00,
39910x3c,
39920x66,
39930xc3,
39940xc3,
39950xc3,
39960xc3,
39970xc3,
39980x66,
39990x24,
40000x24,
40010xa5,
40020xe7,
40030x00,
40040x00,
40050x00,
4006
40070x00,
40080x1e,
40090x31,
40100x30,
40110x18,
40120x0c,
40130x3e,
40140x66,
40150x66,
40160x66,
40170x66,
40180x66,
40190x3c,
40200x00,
40210x00,
40220x00,
4023
40240x00,
40250x00,
40260x00,
40270x00,
40280x6e,
40290xff,
40300x99,
40310x99,
40320x99,
40330x99,
40340xff,
40350x76,
40360x00,
40370x00,
40380x00,
40390x00,
4040
40410x00,
40420x00,
40430x00,
40440x02,
40450x04,
40460x7c,
40470xca,
40480x92,
40490xa6,
40500x7c,
40510x40,
40520x80,
40530x00,
40540x00,
40550x00,
40560x00,
4057
40580x00,
40590x1c,
40600x30,
40610x60,
40620x60,
40630x60,
40640x7c,
40650x60,
40660x60,
40670x60,
40680x60,
40690x30,
40700x1c,
40710x00,
40720x00,
40730x00,
4074
40750x00,
40760x00,
40770x7c,
40780xc6,
40790xc6,
40800xc6,
40810xc6,
40820xc6,
40830xc6,
40840xc6,
40850xc6,
40860xc6,
40870xc6,
40880x00,
40890x00,
40900x00,
4091
40920x00,
40930x00,
40940x00,
40950xfe,
40960x00,
40970x00,
40980x00,
40990x7c,
41000x00,
41010x00,
41020x00,
41030xfe,
41040x00,
41050x00,
41060x00,
41070x00,
4108
41090x00,
41100x00,
41110x00,
41120x00,
41130x18,
41140x18,
41150x7e,
41160x18,
41170x18,
41180x00,
41190x00,
41200x7e,
41210x00,
41220x00,
41230x00,
41240x00,
4125
41260x00,
41270x00,
41280x00,
41290x30,
41300x18,
41310x0c,
41320x06,
41330x0c,
41340x18,
41350x30,
41360x00,
41370x7e,
41380x00,
41390x00,
41400x00,
41410x00,
4142
41430x00,
41440x00,
41450x00,
41460x0c,
41470x18,
41480x30,
41490x60,
41500x30,
41510x18,
41520x0c,
41530x00,
41540x7e,
41550x00,
41560x00,
41570x00,
41580x00,
4159
41600x00,
41610x00,
41620x00,
41630x0e,
41640x19,
41650x1b,
41660x18,
41670x18,
41680x18,
41690x18,
41700x18,
41710x18,
41720x18,
41730x18,
41740x18,
41750x18,
4176
41770x18,
41780x18,
41790x18,
41800x18,
41810x18,
41820x18,
41830x18,
41840x18,
41850x18,
41860xd8,
41870x98,
41880x70,
41890x00,
41900x00,
41910x00,
41920x00,
4193
41940x00,
41950x00,
41960x00,
41970x00,
41980x18,
41990x18,
42000x00,
42010x7e,
42020x00,
42030x18,
42040x18,
42050x00,
42060x00,
42070x00,
42080x00,
42090x00,
4210
42110x00,
42120x00,
42130x00,
42140x00,
42150x00,
42160x76,
42170xdc,
42180x00,
42190x00,
42200x76,
42210xdc,
42220x00,
42230x00,
42240x00,
42250x00,
42260x00,
4227
42280x00,
42290x38,
42300x44,
42310x44,
42320x44,
42330x38,
42340x00,
42350x00,
42360x00,
42370x00,
42380x00,
42390x00,
42400x00,
42410x00,
42420x00,
42430x00,
4244
42450x00,
42460x00,
42470x00,
42480x00,
42490x00,
42500x00,
42510x00,
42520x18,
42530x18,
42540x00,
42550x00,
42560x00,
42570x00,
42580x00,
42590x00,
42600x00,
4261
42620x00,
42630x00,
42640x00,
42650x00,
42660x00,
42670x00,
42680x00,
42690x00,
42700x18,
42710x00,
42720x00,
42730x00,
42740x00,
42750x00,
42760x00,
42770x00,
4278
42790x00,
42800x00,
42810x07,
42820x06,
42830x06,
42840x0c,
42850x0c,
42860x08,
42870x98,
42880xd0,
42890xf0,
42900x60,
42910x20,
42920x00,
42930x00,
42940x00,
4295
42960x00,
42970xcc,
42980x76,
42990x66,
43000x66,
43010x66,
43020x66,
43030xf7,
43040x00,
43050x00,
43060x00,
43070x00,
43080x00,
43090x00,
43100x00,
43110x00,
4312
43130x00,
43140x70,
43150x98,
43160x18,
43170x30,
43180x60,
43190x88,
43200xf8,
43210x00,
43220x00,
43230x00,
43240x00,
43250x00,
43260x00,
43270x00,
43280x00,
4329
43300x00,
43310x00,
43320x00,
43330x00,
43340x00,
43350x7c,
43360x64,
43370x64,
43380x64,
43390x64,
43400x64,
43410x7c,
43420x00,
43430x00,
43440x00,
43450x00,
4346
43470x00,
43480x00,
43490x00,
43500x00,
43510x00,
43520x00,
43530x00,
43540x00,
43550x00,
43560x00,
43570x00,
43580x00,
43590x00,
43600x00,
43610x00,
43620x00,
4363
4364};
4365
4366
4367const struct font_desc font_rl = {
4368 RL_IDX,
4369 "RomanLarge",
4370 8,
4371 16,
4372 patterns,
4373 -1
4374};
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index 4fd07d9eca03..9be83bed1959 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -64,6 +64,10 @@ static const struct font_desc *fonts[] = {
64#undef NO_FONTS 64#undef NO_FONTS
65 &font_mini_4x6, 65 &font_mini_4x6,
66#endif 66#endif
67#ifdef CONFIG_FONT_RL
68#undef NO_FONTS
69 &font_rl,
70#endif
67}; 71};
68 72
69#define num_fonts (sizeof(fonts)/sizeof(*fonts)) 73#define num_fonts (sizeof(fonts)/sizeof(*fonts))
diff --git a/drivers/video/softcursor.c b/drivers/video/console/softcursor.c
index 229c4bc35079..8529bf08db28 100644
--- a/drivers/video/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices 2 * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices
3 * 3 *
4 * Created 14 Nov 2002 by James Simmons 4 * Created 14 Nov 2002 by James Simmons
5 * 5 *
6 * This file is subject to the terms and conditions of the GNU General Public 6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive 7 * License. See the file COPYING in the main directory of this archive
@@ -55,9 +55,9 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
55 src[i] = image->data[i] & cursor->mask[i]; 55 src[i] = image->data[i] & cursor->mask[i];
56 break; 56 break;
57 } 57 }
58 } else 58 } else
59 memcpy(src, image->data, dsize); 59 memcpy(src, image->data, dsize);
60 60
61 fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); 61 fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
62 image->data = dst; 62 image->data = dst;
63 info->fbops->fb_imageblit(info, image); 63 info->fbops->fb_imageblit(info, image);
@@ -66,7 +66,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
66} 66}
67 67
68EXPORT_SYMBOL(soft_cursor); 68EXPORT_SYMBOL(soft_cursor);
69 69
70MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>"); 70MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
71MODULE_DESCRIPTION("Generic software cursor"); 71MODULE_DESCRIPTION("Generic software cursor");
72MODULE_LICENSE("GPL"); 72MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c
index 7f76e2c6a4a1..cb25324a5635 100644
--- a/drivers/video/console/tileblit.c
+++ b/drivers/video/console/tileblit.c
@@ -118,6 +118,18 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info,
118 info->tileops->fb_tilecursor(info, &cursor); 118 info->tileops->fb_tilecursor(info, &cursor);
119} 119}
120 120
121static int tile_update_start(struct fb_info *info)
122{
123 struct fbcon_ops *ops = info->fbcon_par;
124 int err;
125
126 err = fb_pan_display(info, &ops->var);
127 ops->var.xoffset = info->var.xoffset;
128 ops->var.yoffset = info->var.yoffset;
129 ops->var.vmode = info->var.vmode;
130 return err;
131}
132
121void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info, 133void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
122 struct display *p, struct fbcon_ops *ops) 134 struct display *p, struct fbcon_ops *ops)
123{ 135{
@@ -128,6 +140,7 @@ void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
128 ops->putcs = tile_putcs; 140 ops->putcs = tile_putcs;
129 ops->clear_margins = tile_clear_margins; 141 ops->clear_margins = tile_clear_margins;
130 ops->cursor = tile_cursor; 142 ops->cursor = tile_cursor;
143 ops->update_start = tile_update_start;
131 144
132 if (p) { 145 if (p) {
133 map.width = vc->vc_font.width; 146 map.width = vc->vc_font.width;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 56cd199605f4..274f90543e32 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -448,7 +448,8 @@ static void vgacon_cursor(struct vc_data *c, int mode)
448 vgacon_scrolldelta(c, 0); 448 vgacon_scrolldelta(c, 0);
449 switch (mode) { 449 switch (mode) {
450 case CM_ERASE: 450 case CM_ERASE:
451 write_vga(14, (vga_vram_end - vga_vram_base - 1) / 2); 451 write_vga(14, (c->vc_pos - vga_vram_base) / 2);
452 vgacon_set_cursor_size(c->vc_x, 31, 30);
452 break; 453 break;
453 454
454 case CM_MOVE: 455 case CM_MOVE:
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 989e700159e0..403d17377f8d 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -176,7 +176,6 @@ static struct fb_ops controlfb_ops = {
176 .fb_fillrect = cfb_fillrect, 176 .fb_fillrect = cfb_fillrect,
177 .fb_copyarea = cfb_copyarea, 177 .fb_copyarea = cfb_copyarea,
178 .fb_imageblit = cfb_imageblit, 178 .fb_imageblit = cfb_imageblit,
179 .fb_cursor = soft_cursor,
180}; 179};
181 180
182 181
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 3894b2a501d6..c589d23e7f91 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1064,7 +1064,6 @@ static struct fb_ops cyber2000fb_ops = {
1064 .fb_fillrect = cyber2000fb_fillrect, 1064 .fb_fillrect = cyber2000fb_fillrect,
1065 .fb_copyarea = cyber2000fb_copyarea, 1065 .fb_copyarea = cyber2000fb_copyarea,
1066 .fb_imageblit = cyber2000fb_imageblit, 1066 .fb_imageblit = cyber2000fb_imageblit,
1067 .fb_cursor = soft_cursor,
1068 .fb_sync = cyber2000fb_sync, 1067 .fb_sync = cyber2000fb_sync,
1069}; 1068};
1070 1069
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
index 6992100a508c..03fbe83d71a8 100644
--- a/drivers/video/cyblafb.c
+++ b/drivers/video/cyblafb.c
@@ -968,7 +968,6 @@ static struct fb_ops cyblafb_ops __devinitdata = {
968 .fb_fillrect = cyblafb_fillrect, 968 .fb_fillrect = cyblafb_fillrect,
969 .fb_copyarea= cyblafb_copyarea, 969 .fb_copyarea= cyblafb_copyarea,
970 .fb_imageblit = cyblafb_imageblit, 970 .fb_imageblit = cyblafb_imageblit,
971 .fb_cursor = soft_cursor,
972}; 971};
973 972
974//========================================================================== 973//==========================================================================
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index 1785686a7f11..957a3ada2b75 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -116,7 +116,6 @@ static struct fb_ops dn_fb_ops = {
116 .fb_fillrect = cfb_fillrect, 116 .fb_fillrect = cfb_fillrect,
117 .fb_copyarea = dnfb_copyarea, 117 .fb_copyarea = dnfb_copyarea,
118 .fb_imageblit = cfb_imageblit, 118 .fb_imageblit = cfb_imageblit,
119 .fb_cursor = soft_cursor,
120}; 119};
121 120
122struct fb_var_screeninfo dnfb_var __devinitdata = { 121struct fb_var_screeninfo dnfb_var __devinitdata = {
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 7363d0b25fdf..6a81a1dd8f3d 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -484,7 +484,6 @@ static struct fb_ops epson1355fb_fbops = {
484 .fb_imageblit = cfb_imageblit, 484 .fb_imageblit = cfb_imageblit,
485 .fb_read = epson1355fb_read, 485 .fb_read = epson1355fb_read,
486 .fb_write = epson1355fb_write, 486 .fb_write = epson1355fb_write,
487 .fb_cursor = soft_cursor,
488}; 487};
489 488
490/* ------------------------------------------------------------------------- */ 489/* ------------------------------------------------------------------------- */
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e2667ddab3f1..9f180096c896 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -14,6 +14,7 @@
14#include <linux/config.h> 14#include <linux/config.h>
15#include <linux/module.h> 15#include <linux/module.h>
16 16
17#include <linux/compat.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/errno.h> 19#include <linux/errno.h>
19#include <linux/sched.h> 20#include <linux/sched.h>
@@ -323,9 +324,103 @@ static struct logo_data {
323 const struct linux_logo *logo; 324 const struct linux_logo *logo;
324} fb_logo; 325} fb_logo;
325 326
326int fb_prepare_logo(struct fb_info *info) 327static void fb_rotate_logo_ud(const u8 *in, u8 *out, u32 width, u32 height)
328{
329 u32 size = width * height, i;
330
331 out += size - 1;
332
333 for (i = size; i--; )
334 *out-- = *in++;
335}
336
337static void fb_rotate_logo_cw(const u8 *in, u8 *out, u32 width, u32 height)
338{
339 int i, j, w = width - 1;
340
341 for (i = 0; i < height; i++)
342 for (j = 0; j < width; j++)
343 out[height * j + w - i] = *in++;
344}
345
346static void fb_rotate_logo_ccw(const u8 *in, u8 *out, u32 width, u32 height)
347{
348 int i, j, w = width - 1;
349
350 for (i = 0; i < height; i++)
351 for (j = 0; j < width; j++)
352 out[height * (w - j) + i] = *in++;
353}
354
355static void fb_rotate_logo(struct fb_info *info, u8 *dst,
356 struct fb_image *image, int rotate)
357{
358 u32 tmp;
359
360 if (rotate == FB_ROTATE_UD) {
361 image->dx = info->var.xres - image->width;
362 image->dy = info->var.yres - image->height;
363 fb_rotate_logo_ud(image->data, dst, image->width,
364 image->height);
365 } else if (rotate == FB_ROTATE_CW) {
366 tmp = image->width;
367 image->width = image->height;
368 image->height = tmp;
369 image->dx = info->var.xres - image->height;
370 fb_rotate_logo_cw(image->data, dst, image->width,
371 image->height);
372 } else if (rotate == FB_ROTATE_CCW) {
373 tmp = image->width;
374 image->width = image->height;
375 image->height = tmp;
376 image->dy = info->var.yres - image->width;
377 fb_rotate_logo_ccw(image->data, dst, image->width,
378 image->height);
379 }
380
381 image->data = dst;
382}
383
384static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
385 int rotate)
386{
387 int x;
388
389 if (rotate == FB_ROTATE_UR) {
390 for (x = 0; x < num_online_cpus() &&
391 x * (fb_logo.logo->width + 8) <=
392 info->var.xres - fb_logo.logo->width; x++) {
393 info->fbops->fb_imageblit(info, image);
394 image->dx += fb_logo.logo->width + 8;
395 }
396 } else if (rotate == FB_ROTATE_UD) {
397 for (x = 0; x < num_online_cpus() &&
398 x * (fb_logo.logo->width + 8) <=
399 info->var.xres - fb_logo.logo->width; x++) {
400 info->fbops->fb_imageblit(info, image);
401 image->dx -= fb_logo.logo->width + 8;
402 }
403 } else if (rotate == FB_ROTATE_CW) {
404 for (x = 0; x < num_online_cpus() &&
405 x * (fb_logo.logo->width + 8) <=
406 info->var.yres - fb_logo.logo->width; x++) {
407 info->fbops->fb_imageblit(info, image);
408 image->dy += fb_logo.logo->width + 8;
409 }
410 } else if (rotate == FB_ROTATE_CCW) {
411 for (x = 0; x < num_online_cpus() &&
412 x * (fb_logo.logo->width + 8) <=
413 info->var.yres - fb_logo.logo->width; x++) {
414 info->fbops->fb_imageblit(info, image);
415 image->dy -= fb_logo.logo->width + 8;
416 }
417 }
418}
419
420int fb_prepare_logo(struct fb_info *info, int rotate)
327{ 421{
328 int depth = fb_get_color_depth(&info->var, &info->fix); 422 int depth = fb_get_color_depth(&info->var, &info->fix);
423 int yres;
329 424
330 memset(&fb_logo, 0, sizeof(struct logo_data)); 425 memset(&fb_logo, 0, sizeof(struct logo_data));
331 426
@@ -358,10 +453,16 @@ int fb_prepare_logo(struct fb_info *info)
358 /* Return if no suitable logo was found */ 453 /* Return if no suitable logo was found */
359 fb_logo.logo = fb_find_logo(depth); 454 fb_logo.logo = fb_find_logo(depth);
360 455
361 if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { 456 if (rotate == FB_ROTATE_UR || rotate == FB_ROTATE_UD)
457 yres = info->var.yres;
458 else
459 yres = info->var.xres;
460
461 if (fb_logo.logo && fb_logo.logo->height > yres) {
362 fb_logo.logo = NULL; 462 fb_logo.logo = NULL;
363 return 0; 463 return 0;
364 } 464 }
465
365 /* What depth we asked for might be different from what we get */ 466 /* What depth we asked for might be different from what we get */
366 if (fb_logo.logo->type == LINUX_LOGO_CLUT224) 467 if (fb_logo.logo->type == LINUX_LOGO_CLUT224)
367 fb_logo.depth = 8; 468 fb_logo.depth = 8;
@@ -372,12 +473,11 @@ int fb_prepare_logo(struct fb_info *info)
372 return fb_logo.logo->height; 473 return fb_logo.logo->height;
373} 474}
374 475
375int fb_show_logo(struct fb_info *info) 476int fb_show_logo(struct fb_info *info, int rotate)
376{ 477{
377 u32 *palette = NULL, *saved_pseudo_palette = NULL; 478 u32 *palette = NULL, *saved_pseudo_palette = NULL;
378 unsigned char *logo_new = NULL; 479 unsigned char *logo_new = NULL, *logo_rotate = NULL;
379 struct fb_image image; 480 struct fb_image image;
380 int x;
381 481
382 /* Return if the frame buffer is not mapped or suspended */ 482 /* Return if the frame buffer is not mapped or suspended */
383 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) 483 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
@@ -417,25 +517,30 @@ int fb_show_logo(struct fb_info *info)
417 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); 517 fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth);
418 } 518 }
419 519
520 image.dx = 0;
521 image.dy = 0;
420 image.width = fb_logo.logo->width; 522 image.width = fb_logo.logo->width;
421 image.height = fb_logo.logo->height; 523 image.height = fb_logo.logo->height;
422 image.dy = 0;
423 524
424 for (x = 0; x < num_online_cpus() * (fb_logo.logo->width + 8) && 525 if (rotate) {
425 x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) { 526 logo_rotate = kmalloc(fb_logo.logo->width *
426 image.dx = x; 527 fb_logo.logo->height, GFP_KERNEL);
427 info->fbops->fb_imageblit(info, &image); 528 if (logo_rotate)
529 fb_rotate_logo(info, logo_rotate, &image, rotate);
428 } 530 }
429 531
532 fb_do_show_logo(info, &image, rotate);
533
430 kfree(palette); 534 kfree(palette);
431 if (saved_pseudo_palette != NULL) 535 if (saved_pseudo_palette != NULL)
432 info->pseudo_palette = saved_pseudo_palette; 536 info->pseudo_palette = saved_pseudo_palette;
433 kfree(logo_new); 537 kfree(logo_new);
538 kfree(logo_rotate);
434 return fb_logo.logo->height; 539 return fb_logo.logo->height;
435} 540}
436#else 541#else
437int fb_prepare_logo(struct fb_info *info) { return 0; } 542int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
438int fb_show_logo(struct fb_info *info) { return 0; } 543int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
439#endif /* CONFIG_LOGO */ 544#endif /* CONFIG_LOGO */
440 545
441static int fbmem_read_proc(char *buf, char **start, off_t offset, 546static int fbmem_read_proc(char *buf, char **start, off_t offset,
@@ -829,18 +934,154 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
829} 934}
830 935
831#ifdef CONFIG_COMPAT 936#ifdef CONFIG_COMPAT
937struct fb_fix_screeninfo32 {
938 char id[16];
939 compat_caddr_t smem_start;
940 u32 smem_len;
941 u32 type;
942 u32 type_aux;
943 u32 visual;
944 u16 xpanstep;
945 u16 ypanstep;
946 u16 ywrapstep;
947 u32 line_length;
948 compat_caddr_t mmio_start;
949 u32 mmio_len;
950 u32 accel;
951 u16 reserved[3];
952};
953
954struct fb_cmap32 {
955 u32 start;
956 u32 len;
957 compat_caddr_t red;
958 compat_caddr_t green;
959 compat_caddr_t blue;
960 compat_caddr_t transp;
961};
962
963static int fb_getput_cmap(struct inode *inode, struct file *file,
964 unsigned int cmd, unsigned long arg)
965{
966 struct fb_cmap_user __user *cmap;
967 struct fb_cmap32 __user *cmap32;
968 __u32 data;
969 int err;
970
971 cmap = compat_alloc_user_space(sizeof(*cmap));
972 cmap32 = compat_ptr(arg);
973
974 if (copy_in_user(&cmap->start, &cmap32->start, 2 * sizeof(__u32)))
975 return -EFAULT;
976
977 if (get_user(data, &cmap32->red) ||
978 put_user(compat_ptr(data), &cmap->red) ||
979 get_user(data, &cmap32->green) ||
980 put_user(compat_ptr(data), &cmap->green) ||
981 get_user(data, &cmap32->blue) ||
982 put_user(compat_ptr(data), &cmap->blue) ||
983 get_user(data, &cmap32->transp) ||
984 put_user(compat_ptr(data), &cmap->transp))
985 return -EFAULT;
986
987 err = fb_ioctl(inode, file, cmd, (unsigned long) cmap);
988
989 if (!err) {
990 if (copy_in_user(&cmap32->start,
991 &cmap->start,
992 2 * sizeof(__u32)))
993 err = -EFAULT;
994 }
995 return err;
996}
997
998static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
999 struct fb_fix_screeninfo32 __user *fix32)
1000{
1001 __u32 data;
1002 int err;
1003
1004 err = copy_to_user(&fix32->id, &fix->id, sizeof(fix32->id));
1005
1006 data = (__u32) (unsigned long) fix->smem_start;
1007 err |= put_user(data, &fix32->smem_start);
1008
1009 err |= put_user(fix->smem_len, &fix32->smem_len);
1010 err |= put_user(fix->type, &fix32->type);
1011 err |= put_user(fix->type_aux, &fix32->type_aux);
1012 err |= put_user(fix->visual, &fix32->visual);
1013 err |= put_user(fix->xpanstep, &fix32->xpanstep);
1014 err |= put_user(fix->ypanstep, &fix32->ypanstep);
1015 err |= put_user(fix->ywrapstep, &fix32->ywrapstep);
1016 err |= put_user(fix->line_length, &fix32->line_length);
1017
1018 data = (__u32) (unsigned long) fix->mmio_start;
1019 err |= put_user(data, &fix32->mmio_start);
1020
1021 err |= put_user(fix->mmio_len, &fix32->mmio_len);
1022 err |= put_user(fix->accel, &fix32->accel);
1023 err |= copy_to_user(fix32->reserved, fix->reserved,
1024 sizeof(fix->reserved));
1025
1026 return err;
1027}
1028
1029static int fb_get_fscreeninfo(struct inode *inode, struct file *file,
1030 unsigned int cmd, unsigned long arg)
1031{
1032 mm_segment_t old_fs;
1033 struct fb_fix_screeninfo fix;
1034 struct fb_fix_screeninfo32 __user *fix32;
1035 int err;
1036
1037 fix32 = compat_ptr(arg);
1038
1039 old_fs = get_fs();
1040 set_fs(KERNEL_DS);
1041 err = fb_ioctl(inode, file, cmd, (unsigned long) &fix);
1042 set_fs(old_fs);
1043
1044 if (!err)
1045 err = do_fscreeninfo_to_user(&fix, fix32);
1046
1047 return err;
1048}
1049
832static long 1050static long
833fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1051fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
834{ 1052{
835 int fbidx = iminor(file->f_dentry->d_inode); 1053 struct inode *inode = file->f_dentry->d_inode;
1054 int fbidx = iminor(inode);
836 struct fb_info *info = registered_fb[fbidx]; 1055 struct fb_info *info = registered_fb[fbidx];
837 struct fb_ops *fb = info->fbops; 1056 struct fb_ops *fb = info->fbops;
838 long ret; 1057 long ret = -ENOIOCTLCMD;
839 1058
840 if (fb->fb_compat_ioctl == NULL)
841 return -ENOIOCTLCMD;
842 lock_kernel(); 1059 lock_kernel();
843 ret = fb->fb_compat_ioctl(file, cmd, arg, info); 1060 switch(cmd) {
1061 case FBIOGET_VSCREENINFO:
1062 case FBIOPUT_VSCREENINFO:
1063 case FBIOPAN_DISPLAY:
1064 case FBIOGET_CON2FBMAP:
1065 case FBIOPUT_CON2FBMAP:
1066 arg = (unsigned long) compat_ptr(arg);
1067 case FBIOBLANK:
1068 ret = fb_ioctl(inode, file, cmd, arg);
1069 break;
1070
1071 case FBIOGET_FSCREENINFO:
1072 ret = fb_get_fscreeninfo(inode, file, cmd, arg);
1073 break;
1074
1075 case FBIOGETCMAP:
1076 case FBIOPUTCMAP:
1077 ret = fb_getput_cmap(inode, file, cmd, arg);
1078 break;
1079
1080 default:
1081 if (fb->fb_compat_ioctl)
1082 ret = fb->fb_compat_ioctl(file, cmd, arg, info);
1083 break;
1084 }
844 unlock_kernel(); 1085 unlock_kernel();
845 return ret; 1086 return ret;
846} 1087}
@@ -1215,6 +1456,28 @@ int fb_new_modelist(struct fb_info *info)
1215 return err; 1456 return err;
1216} 1457}
1217 1458
1459/**
1460 * fb_con_duit - user<->fbcon passthrough
1461 * @info: struct fb_info
1462 * @event: notification event to be passed to fbcon
1463 * @data: private data
1464 *
1465 * DESCRIPTION
1466 * This function is an fbcon-user event passing channel
1467 * which bypasses fbdev. This is hopefully temporary
1468 * until a user interface for fbcon is created
1469 */
1470int fb_con_duit(struct fb_info *info, int event, void *data)
1471{
1472 struct fb_event evnt;
1473
1474 evnt.info = info;
1475 evnt.data = data;
1476
1477 return notifier_call_chain(&fb_notifier_list, event, &evnt);
1478}
1479EXPORT_SYMBOL(fb_con_duit);
1480
1218static char *video_options[FB_MAX]; 1481static char *video_options[FB_MAX];
1219static int ofonly; 1482static int ofonly;
1220 1483
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 713226cdf3c6..fc7965b66775 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -538,25 +538,12 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
538 538
539 *dbsize = 0; 539 *dbsize = 0;
540 540
541 DPRINTK(" Supported VESA Modes\n");
542 block = edid + ESTABLISHED_TIMING_1;
543 num += get_est_timing(block, &mode[num]);
544
545 DPRINTK(" Standard Timings\n");
546 block = edid + STD_TIMING_DESCRIPTIONS_START;
547 for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
548 num += get_std_timing(block, &mode[num]);
549
550 DPRINTK(" Detailed Timings\n"); 541 DPRINTK(" Detailed Timings\n");
551 block = edid + DETAILED_TIMING_DESCRIPTIONS_START; 542 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
552 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { 543 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
553 int first = 1; 544 int first = 1;
554 545
555 if (block[0] == 0x00 && block[1] == 0x00) { 546 if (!(block[0] == 0x00 && block[1] == 0x00)) {
556 if (block[3] == 0xfa) {
557 num += get_dst_timing(block + 5, &mode[num]);
558 }
559 } else {
560 get_detailed_timing(block, &mode[num]); 547 get_detailed_timing(block, &mode[num]);
561 if (first) { 548 if (first) {
562 mode[num].flag |= FB_MODE_IS_FIRST; 549 mode[num].flag |= FB_MODE_IS_FIRST;
@@ -565,6 +552,21 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
565 num++; 552 num++;
566 } 553 }
567 } 554 }
555
556 DPRINTK(" Supported VESA Modes\n");
557 block = edid + ESTABLISHED_TIMING_1;
558 num += get_est_timing(block, &mode[num]);
559
560 DPRINTK(" Standard Timings\n");
561 block = edid + STD_TIMING_DESCRIPTIONS_START;
562 for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
563 num += get_std_timing(block, &mode[num]);
564
565 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
566 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
567 if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
568 num += get_dst_timing(block + 5, &mode[num]);
569 }
568 570
569 /* Yikes, EDID data is totally useless */ 571 /* Yikes, EDID data is totally useless */
570 if (!num) { 572 if (!num) {
@@ -827,7 +829,7 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
827void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) 829void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
828{ 830{
829 unsigned char *block; 831 unsigned char *block;
830 int i; 832 int i, found = 0;
831 833
832 if (edid == NULL) 834 if (edid == NULL)
833 return; 835 return;
@@ -869,6 +871,22 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
869 get_monspecs(edid, specs); 871 get_monspecs(edid, specs);
870 872
871 specs->modedb = fb_create_modedb(edid, &specs->modedb_len); 873 specs->modedb = fb_create_modedb(edid, &specs->modedb_len);
874
875 /*
876 * Workaround for buggy EDIDs that sets that the first
877 * detailed timing is preferred but has not detailed
878 * timing specified
879 */
880 for (i = 0; i < specs->modedb_len; i++) {
881 if (specs->modedb[i].flag & FB_MODE_IS_DETAILED) {
882 found = 1;
883 break;
884 }
885 }
886
887 if (!found)
888 specs->misc &= ~FB_MISC_1ST_DETAIL;
889
872 DPRINTK("========================================\n"); 890 DPRINTK("========================================\n");
873} 891}
874 892
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 007c8e9b2b39..08dac9580d15 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -213,6 +213,70 @@ static ssize_t show_bpp(struct class_device *class_device, char *buf)
213 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel); 213 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel);
214} 214}
215 215
216static ssize_t store_rotate(struct class_device *class_device, const char *buf,
217 size_t count)
218{
219 struct fb_info *fb_info = class_get_devdata(class_device);
220 struct fb_var_screeninfo var;
221 char **last = NULL;
222 int err;
223
224 var = fb_info->var;
225 var.rotate = simple_strtoul(buf, last, 0);
226
227 if ((err = activate(fb_info, &var)))
228 return err;
229
230 return count;
231}
232
233
234static ssize_t show_rotate(struct class_device *class_device, char *buf)
235{
236 struct fb_info *fb_info = class_get_devdata(class_device);
237
238 return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.rotate);
239}
240
241static ssize_t store_con_rotate(struct class_device *class_device,
242 const char *buf, size_t count)
243{
244 struct fb_info *fb_info = class_get_devdata(class_device);
245 int rotate;
246 char **last = NULL;
247
248 acquire_console_sem();
249 rotate = simple_strtoul(buf, last, 0);
250 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE, &rotate);
251 release_console_sem();
252 return count;
253}
254
255static ssize_t store_con_rotate_all(struct class_device *class_device,
256 const char *buf, size_t count)
257{
258 struct fb_info *fb_info = class_get_devdata(class_device);
259 int rotate;
260 char **last = NULL;
261
262 acquire_console_sem();
263 rotate = simple_strtoul(buf, last, 0);
264 fb_con_duit(fb_info, FB_EVENT_SET_CON_ROTATE_ALL, &rotate);
265 release_console_sem();
266 return count;
267}
268
269static ssize_t show_con_rotate(struct class_device *class_device, char *buf)
270{
271 struct fb_info *fb_info = class_get_devdata(class_device);
272 int rotate;
273
274 acquire_console_sem();
275 rotate = fb_con_duit(fb_info, FB_EVENT_GET_CON_ROTATE, NULL);
276 release_console_sem();
277 return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
278}
279
216static ssize_t store_virtual(struct class_device *class_device, 280static ssize_t store_virtual(struct class_device *class_device,
217 const char * buf, size_t count) 281 const char * buf, size_t count)
218{ 282{
@@ -440,6 +504,9 @@ static struct class_device_attribute class_device_attrs[] = {
440 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual), 504 __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
441 __ATTR(name, S_IRUGO, show_name, NULL), 505 __ATTR(name, S_IRUGO, show_name, NULL),
442 __ATTR(stride, S_IRUGO, show_stride, NULL), 506 __ATTR(stride, S_IRUGO, show_stride, NULL),
507 __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
508 __ATTR(con_rotate, S_IRUGO|S_IWUSR, show_con_rotate, store_con_rotate),
509 __ATTR(con_rotate_all, S_IWUSR, NULL, store_con_rotate_all),
443}; 510};
444 511
445int fb_init_class_device(struct fb_info *fb_info) 512int fb_init_class_device(struct fb_info *fb_info)
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 10cd05059fe9..04417dc16c2e 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -57,9 +57,6 @@ static struct fb_ops ffb_ops = {
57 .fb_sync = ffb_sync, 57 .fb_sync = ffb_sync,
58 .fb_mmap = ffb_mmap, 58 .fb_mmap = ffb_mmap,
59 .fb_ioctl = ffb_ioctl, 59 .fb_ioctl = ffb_ioctl,
60
61 /* XXX Use FFB hw cursor once fb cursor API is better understood... */
62 .fb_cursor = soft_cursor,
63}; 60};
64 61
65/* Register layout and definitions */ 62/* Register layout and definitions */
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index a0763283d776..998374cfae6d 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -172,7 +172,6 @@ static struct fb_ops fm2fb_ops = {
172 .fb_fillrect = cfb_fillrect, 172 .fb_fillrect = cfb_fillrect,
173 .fb_copyarea = cfb_copyarea, 173 .fb_copyarea = cfb_copyarea,
174 .fb_imageblit = cfb_imageblit, 174 .fb_imageblit = cfb_imageblit,
175 .fb_cursor = soft_cursor,
176}; 175};
177 176
178 /* 177 /*
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 316bfe994811..9d5e4f342110 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -1038,7 +1038,6 @@ static struct fb_ops gbefb_ops = {
1038 .fb_fillrect = cfb_fillrect, 1038 .fb_fillrect = cfb_fillrect,
1039 .fb_copyarea = cfb_copyarea, 1039 .fb_copyarea = cfb_copyarea,
1040 .fb_imageblit = cfb_imageblit, 1040 .fb_imageblit = cfb_imageblit,
1041 .fb_cursor = soft_cursor,
1042}; 1041};
1043 1042
1044/* 1043/*
@@ -1260,24 +1259,30 @@ static struct device_driver gbefb_driver = {
1260 .remove = __devexit_p(gbefb_remove), 1259 .remove = __devexit_p(gbefb_remove),
1261}; 1260};
1262 1261
1263static struct platform_device gbefb_device = { 1262static struct platform_device *gbefb_device;
1264 .name = "gbefb",
1265};
1266 1263
1267int __init gbefb_init(void) 1264int __init gbefb_init(void)
1268{ 1265{
1269 int ret = driver_register(&gbefb_driver); 1266 int ret = driver_register(&gbefb_driver);
1270 if (!ret) { 1267 if (!ret) {
1271 ret = platform_device_register(&gbefb_device); 1268 gbefb_device = platform_device_alloc("gbefb", 0);
1272 if (ret) 1269 if (gbefb_device) {
1270 ret = platform_device_add(gbefb_device);
1271 } else {
1272 ret = -ENOMEM;
1273 }
1274 if (ret) {
1275 platform_device_put(gbefb_device);
1273 driver_unregister(&gbefb_driver); 1276 driver_unregister(&gbefb_driver);
1277 }
1274 } 1278 }
1275 return ret; 1279 return ret;
1276} 1280}
1277 1281
1278void __exit gbefb_exit(void) 1282void __exit gbefb_exit(void)
1279{ 1283{
1280 driver_unregister(&gbefb_driver); 1284 platform_device_unregister(gbefb_device);
1285 driver_unregister(&gbefb_driver);
1281} 1286}
1282 1287
1283module_init(gbefb_init); 1288module_init(gbefb_init);
diff --git a/drivers/video/geode/Kconfig b/drivers/video/geode/Kconfig
index 5a9b89c3831b..42fb9a89a792 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/geode/Kconfig
@@ -14,7 +14,6 @@ config FB_GEODE_GX1
14 select FB_CFB_FILLRECT 14 select FB_CFB_FILLRECT
15 select FB_CFB_COPYAREA 15 select FB_CFB_COPYAREA
16 select FB_CFB_IMAGEBLIT 16 select FB_CFB_IMAGEBLIT
17 select FB_SOFT_CURSOR
18 ---help--- 17 ---help---
19 Framebuffer driver for the display controller integrated into the 18 Framebuffer driver for the display controller integrated into the
20 AMD Geode GX1 processor. 19 AMD Geode GX1 processor.
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index 74a5fca86b8a..8e8da7433994 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -275,7 +275,6 @@ static struct fb_ops gx1fb_ops = {
275 .fb_fillrect = cfb_fillrect, 275 .fb_fillrect = cfb_fillrect,
276 .fb_copyarea = cfb_copyarea, 276 .fb_copyarea = cfb_copyarea,
277 .fb_imageblit = cfb_imageblit, 277 .fb_imageblit = cfb_imageblit,
278 .fb_cursor = soft_cursor,
279}; 278};
280 279
281static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev) 280static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c
index 0d376ba54814..f04ca721f94c 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/hitfb.c
@@ -262,7 +262,6 @@ static struct fb_ops hitfb_ops = {
262 .fb_fillrect = hitfb_fillrect, 262 .fb_fillrect = hitfb_fillrect,
263 .fb_copyarea = hitfb_copyarea, 263 .fb_copyarea = hitfb_copyarea,
264 .fb_imageblit = cfb_imageblit, 264 .fb_imageblit = cfb_imageblit,
265 .fb_cursor = soft_cursor,
266}; 265};
267 266
268int __init hitfb_init(void) 267int __init hitfb_init(void)
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index e97fe8481d59..bebdac59d231 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -193,7 +193,6 @@ static struct fb_ops hpfb_ops = {
193 .fb_fillrect = hpfb_fillrect, 193 .fb_fillrect = hpfb_fillrect,
194 .fb_copyarea = hpfb_copyarea, 194 .fb_copyarea = hpfb_copyarea,
195 .fb_imageblit = cfb_imageblit, 195 .fb_imageblit = cfb_imageblit,
196 .fb_cursor = soft_cursor,
197 .fb_sync = hpfb_sync, 196 .fb_sync = hpfb_sync,
198}; 197};
199 198
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/i810/i810-i2c.c
index 689d2586366d..c61bad0da20f 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/i810/i810-i2c.c
@@ -46,92 +46,45 @@ static void i810i2c_setscl(void *data, int state)
46 struct i810fb_par *par = chan->par; 46 struct i810fb_par *par = chan->par;
47 u8 __iomem *mmio = par->mmio_start_virtual; 47 u8 __iomem *mmio = par->mmio_start_virtual;
48 48
49 i810_writel(mmio, GPIOB, (state ? SCL_VAL_OUT : 0) | SCL_DIR | 49 i810_writel(mmio, chan->ddc_base, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
50 SCL_DIR_MASK | SCL_VAL_MASK); 50 SCL_DIR_MASK | SCL_VAL_MASK);
51 i810_readl(mmio, GPIOB); /* flush posted write */ 51 i810_readl(mmio, chan->ddc_base); /* flush posted write */
52} 52}
53 53
54static void i810i2c_setsda(void *data, int state) 54static void i810i2c_setsda(void *data, int state)
55{ 55{
56 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; 56 struct i810fb_i2c_chan *chan = data;
57 struct i810fb_par *par = chan->par; 57 struct i810fb_par *par = chan->par;
58 u8 __iomem *mmio = par->mmio_start_virtual; 58 u8 __iomem *mmio = par->mmio_start_virtual;
59 59
60 i810_writel(mmio, GPIOB, (state ? SDA_VAL_OUT : 0) | SDA_DIR | 60 i810_writel(mmio, chan->ddc_base, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
61 SDA_DIR_MASK | SDA_VAL_MASK); 61 SDA_DIR_MASK | SDA_VAL_MASK);
62 i810_readl(mmio, GPIOB); /* flush posted write */ 62 i810_readl(mmio, chan->ddc_base); /* flush posted write */
63} 63}
64 64
65static int i810i2c_getscl(void *data) 65static int i810i2c_getscl(void *data)
66{ 66{
67 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; 67 struct i810fb_i2c_chan *chan = data;
68 struct i810fb_par *par = chan->par; 68 struct i810fb_par *par = chan->par;
69 u8 __iomem *mmio = par->mmio_start_virtual; 69 u8 __iomem *mmio = par->mmio_start_virtual;
70 70
71 i810_writel(mmio, GPIOB, SCL_DIR_MASK); 71 i810_writel(mmio, chan->ddc_base, SCL_DIR_MASK);
72 i810_writel(mmio, GPIOB, 0); 72 i810_writel(mmio, chan->ddc_base, 0);
73 return (0 != (i810_readl(mmio, GPIOB) & SCL_VAL_IN)); 73 return ((i810_readl(mmio, chan->ddc_base) & SCL_VAL_IN) != 0);
74} 74}
75 75
76static int i810i2c_getsda(void *data) 76static int i810i2c_getsda(void *data)
77{ 77{
78 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data; 78 struct i810fb_i2c_chan *chan = data;
79 struct i810fb_par *par = chan->par; 79 struct i810fb_par *par = chan->par;
80 u8 __iomem *mmio = par->mmio_start_virtual; 80 u8 __iomem *mmio = par->mmio_start_virtual;
81 81
82 i810_writel(mmio, GPIOB, SDA_DIR_MASK); 82 i810_writel(mmio, chan->ddc_base, SDA_DIR_MASK);
83 i810_writel(mmio, GPIOB, 0); 83 i810_writel(mmio, chan->ddc_base, 0);
84 return (0 != (i810_readl(mmio, GPIOB) & SDA_VAL_IN)); 84 return ((i810_readl(mmio, chan->ddc_base) & SDA_VAL_IN) != 0);
85}
86
87static void i810ddc_setscl(void *data, int state)
88{
89 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
90 struct i810fb_par *par = chan->par;
91 u8 __iomem *mmio = par->mmio_start_virtual;
92
93 i810_writel(mmio, GPIOA, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
94 SCL_DIR_MASK | SCL_VAL_MASK);
95 i810_readl(mmio, GPIOA); /* flush posted write */
96}
97
98static void i810ddc_setsda(void *data, int state)
99{
100 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
101 struct i810fb_par *par = chan->par;
102 u8 __iomem *mmio = par->mmio_start_virtual;
103
104 i810_writel(mmio, GPIOA, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
105 SDA_DIR_MASK | SDA_VAL_MASK);
106 i810_readl(mmio, GPIOA); /* flush posted write */
107}
108
109static int i810ddc_getscl(void *data)
110{
111 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
112 struct i810fb_par *par = chan->par;
113 u8 __iomem *mmio = par->mmio_start_virtual;
114
115 i810_writel(mmio, GPIOA, SCL_DIR_MASK);
116 i810_writel(mmio, GPIOA, 0);
117 return (0 != (i810_readl(mmio, GPIOA) & SCL_VAL_IN));
118}
119
120static int i810ddc_getsda(void *data)
121{
122 struct i810fb_i2c_chan *chan = (struct i810fb_i2c_chan *)data;
123 struct i810fb_par *par = chan->par;
124 u8 __iomem *mmio = par->mmio_start_virtual;
125
126 i810_writel(mmio, GPIOA, SDA_DIR_MASK);
127 i810_writel(mmio, GPIOA, 0);
128 return (0 != (i810_readl(mmio, GPIOA) & SDA_VAL_IN));
129} 85}
130 86
131#define I2C_ALGO_DDC_I810 0x0e0000 87static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name)
132#define I2C_ALGO_I2C_I810 0x0f0000
133static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
134 int conn)
135{ 88{
136 int rc; 89 int rc;
137 90
@@ -139,22 +92,11 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
139 chan->adapter.owner = THIS_MODULE; 92 chan->adapter.owner = THIS_MODULE;
140 chan->adapter.algo_data = &chan->algo; 93 chan->adapter.algo_data = &chan->algo;
141 chan->adapter.dev.parent = &chan->par->dev->dev; 94 chan->adapter.dev.parent = &chan->par->dev->dev;
142 switch (conn) { 95 chan->adapter.id = I2C_HW_B_I810;
143 case 1: 96 chan->algo.setsda = i810i2c_setsda;
144 chan->adapter.id = I2C_ALGO_DDC_I810; 97 chan->algo.setscl = i810i2c_setscl;
145 chan->algo.setsda = i810ddc_setsda; 98 chan->algo.getsda = i810i2c_getsda;
146 chan->algo.setscl = i810ddc_setscl; 99 chan->algo.getscl = i810i2c_getscl;
147 chan->algo.getsda = i810ddc_getsda;
148 chan->algo.getscl = i810ddc_getscl;
149 break;
150 case 2:
151 chan->adapter.id = I2C_ALGO_I2C_I810;
152 chan->algo.setsda = i810i2c_setsda;
153 chan->algo.setscl = i810i2c_setscl;
154 chan->algo.getsda = i810i2c_getsda;
155 chan->algo.getscl = i810i2c_getscl;
156 break;
157 }
158 chan->algo.udelay = 10; 100 chan->algo.udelay = 10;
159 chan->algo.mdelay = 10; 101 chan->algo.mdelay = 10;
160 chan->algo.timeout = (HZ/2); 102 chan->algo.timeout = (HZ/2);
@@ -168,11 +110,15 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
168 udelay(20); 110 udelay(20);
169 111
170 rc = i2c_bit_add_bus(&chan->adapter); 112 rc = i2c_bit_add_bus(&chan->adapter);
113
171 if (rc == 0) 114 if (rc == 0)
172 dev_dbg(&chan->par->dev->dev, "I2C bus %s registered.\n",name); 115 dev_dbg(&chan->par->dev->dev, "I2C bus %s registered.\n",name);
173 else 116 else {
174 dev_warn(&chan->par->dev->dev, "Failed to register I2C bus " 117 dev_warn(&chan->par->dev->dev, "Failed to register I2C bus "
175 "%s.\n", name); 118 "%s.\n", name);
119 chan->par = NULL;
120 }
121
176 return rc; 122 return rc;
177} 123}
178 124
@@ -180,8 +126,14 @@ void i810_create_i2c_busses(struct i810fb_par *par)
180{ 126{
181 par->chan[0].par = par; 127 par->chan[0].par = par;
182 par->chan[1].par = par; 128 par->chan[1].par = par;
183 i810_setup_i2c_bus(&par->chan[0], "I810-DDC", 1); 129 par->chan[2].par = par;
184 i810_setup_i2c_bus(&par->chan[1], "I810-I2C", 2); 130
131 par->chan[0].ddc_base = GPIOA;
132 i810_setup_i2c_bus(&par->chan[0], "I810-DDC");
133 par->chan[1].ddc_base = GPIOB;
134 i810_setup_i2c_bus(&par->chan[1], "I810-I2C");
135 par->chan[2].ddc_base = GPIOC;
136 i810_setup_i2c_bus(&par->chan[2], "I810-GPIOC");
185} 137}
186 138
187void i810_delete_i2c_busses(struct i810fb_par *par) 139void i810_delete_i2c_busses(struct i810fb_par *par)
@@ -189,9 +141,14 @@ void i810_delete_i2c_busses(struct i810fb_par *par)
189 if (par->chan[0].par) 141 if (par->chan[0].par)
190 i2c_bit_del_bus(&par->chan[0].adapter); 142 i2c_bit_del_bus(&par->chan[0].adapter);
191 par->chan[0].par = NULL; 143 par->chan[0].par = NULL;
144
192 if (par->chan[1].par) 145 if (par->chan[1].par)
193 i2c_bit_del_bus(&par->chan[1].adapter); 146 i2c_bit_del_bus(&par->chan[1].adapter);
194 par->chan[1].par = NULL; 147 par->chan[1].par = NULL;
148
149 if (par->chan[2].par)
150 i2c_bit_del_bus(&par->chan[2].adapter);
151 par->chan[2].par = NULL;
195} 152}
196 153
197static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan) 154static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
@@ -221,6 +178,7 @@ static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
221 DPRINTK("i810-i2c: I2C Transfer successful\n"); 178 DPRINTK("i810-i2c: I2C Transfer successful\n");
222 return buf; 179 return buf;
223 } 180 }
181
224 DPRINTK("i810-i2c: Unable to read EDID block.\n"); 182 DPRINTK("i810-i2c: Unable to read EDID block.\n");
225 kfree(buf); 183 kfree(buf);
226 return NULL; 184 return NULL;
@@ -233,7 +191,7 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
233 int i; 191 int i;
234 192
235 DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn); 193 DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn);
236 if (conn < 3) { 194 if (conn < 4) {
237 for (i = 0; i < 3; i++) { 195 for (i = 0; i < 3; i++) {
238 /* Do the real work */ 196 /* Do the real work */
239 edid = i810_do_probe_i2c_edid(&par->chan[conn-1]); 197 edid = i810_do_probe_i2c_edid(&par->chan[conn-1]);
@@ -241,11 +199,14 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
241 break; 199 break;
242 } 200 }
243 } else { 201 } else {
244 DPRINTK("i810-i2c: Getting EDID from BIOS\n"); 202 const u8 *e = fb_firmware_edid(info->device);
245 edid = kmalloc(EDID_LENGTH, GFP_KERNEL); 203
246 if (edid) 204 if (e != NULL) {
247 memcpy(edid, fb_firmware_edid(info->device), 205 DPRINTK("i810-i2c: Getting EDID from BIOS\n");
248 EDID_LENGTH); 206 edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
207 if (edid)
208 memcpy(edid, e, EDID_LENGTH);
209 }
249 } 210 }
250 211
251 if (out_edid) 212 if (out_edid)
@@ -253,5 +214,3 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
253 214
254 return (edid) ? 0 : 1; 215 return (edid) ? 0 : 1;
255} 216}
256
257
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index d48949ceaacc..6c187d5fe951 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -249,6 +249,7 @@ struct i810fb_i2c_chan {
249 struct i810fb_par *par; 249 struct i810fb_par *par;
250 struct i2c_adapter adapter; 250 struct i2c_adapter adapter;
251 struct i2c_algo_bit_data algo; 251 struct i2c_algo_bit_data algo;
252 unsigned long ddc_base;
252}; 253};
253 254
254struct i810fb_par { 255struct i810fb_par {
@@ -262,7 +263,7 @@ struct i810fb_par {
262 struct heap_data iring; 263 struct heap_data iring;
263 struct heap_data cursor_heap; 264 struct heap_data cursor_heap;
264 struct vgastate state; 265 struct vgastate state;
265 struct i810fb_i2c_chan chan[2]; 266 struct i810fb_i2c_chan chan[3];
266 atomic_t use_count; 267 atomic_t use_count;
267 u32 pseudo_palette[17]; 268 u32 pseudo_palette[17];
268 unsigned long mmio_start_phys; 269 unsigned long mmio_start_phys;
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 0dbc9ddb6766..c0c974b1afaa 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1854,7 +1854,7 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info)
1854#ifdef CONFIG_FB_I810_I2C 1854#ifdef CONFIG_FB_I810_I2C
1855 i810_create_i2c_busses(par); 1855 i810_create_i2c_busses(par);
1856 1856
1857 for (i = 0; i < 3; i++) { 1857 for (i = 0; i < 4; i++) {
1858 err = i810_probe_i2c_connector(info, &par->edid, i+1); 1858 err = i810_probe_i2c_connector(info, &par->edid, i+1);
1859 if (!err) 1859 if (!err)
1860 break; 1860 break;
@@ -1871,27 +1871,18 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info)
1871 fb_videomode_to_modelist(specs->modedb, specs->modedb_len, 1871 fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
1872 &info->modelist); 1872 &info->modelist);
1873 if (specs->modedb != NULL) { 1873 if (specs->modedb != NULL) {
1874 if (xres && yres) { 1874 struct fb_videomode *m;
1875 struct fb_videomode *m;
1876 1875
1876 if (xres && yres) {
1877 if ((m = fb_find_best_mode(&var, &info->modelist))) { 1877 if ((m = fb_find_best_mode(&var, &info->modelist))) {
1878 mode = *m; 1878 mode = *m;
1879 found = 1; 1879 found = 1;
1880 } 1880 }
1881 } 1881 }
1882 1882
1883 if (!found && specs->misc & FB_MISC_1ST_DETAIL) {
1884 for (i = 0; i < specs->modedb_len; i++) {
1885 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1886 mode = specs->modedb[i];
1887 found = 1;
1888 break;
1889 }
1890 }
1891 }
1892
1893 if (!found) { 1883 if (!found) {
1894 mode = specs->modedb[0]; 1884 m = fb_find_best_display(&info->monspecs, &info->modelist);
1885 mode = *m;
1895 found = 1; 1886 found = 1;
1896 } 1887 }
1897 1888
@@ -2066,8 +2057,7 @@ static void i810fb_release_resource(struct fb_info *info,
2066 iounmap(par->mmio_start_virtual); 2057 iounmap(par->mmio_start_virtual);
2067 if (par->aperture.virtual) 2058 if (par->aperture.virtual)
2068 iounmap(par->aperture.virtual); 2059 iounmap(par->aperture.virtual);
2069 if (par->edid) 2060 kfree(par->edid);
2070 kfree(par->edid);
2071 if (par->res_flags & FRAMEBUFFER_REQ) 2061 if (par->res_flags & FRAMEBUFFER_REQ)
2072 release_mem_region(par->aperture.physical, 2062 release_mem_region(par->aperture.physical,
2073 par->aperture.size); 2063 par->aperture.size);
diff --git a/drivers/video/i810/i810_regs.h b/drivers/video/i810/i810_regs.h
index 6e4b9afa4d98..91c6bd9d0d0d 100644
--- a/drivers/video/i810/i810_regs.h
+++ b/drivers/video/i810/i810_regs.h
@@ -70,6 +70,7 @@
70#define HVSYNC 0x05000 70#define HVSYNC 0x05000
71#define GPIOA 0x05010 71#define GPIOA 0x05010
72#define GPIOB 0x05014 72#define GPIOB 0x05014
73#define GPIOC 0x0501C
73 74
74/* Clock Control and Power Management Registers (06000h 06FFFh) */ 75/* Clock Control and Power Management Registers (06000h 06FFFh) */
75#define DCLK_0D 0x06000 76#define DCLK_0D 0x06000
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 7b9bf45ab6fe..7fbe24206b19 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -1344,7 +1344,6 @@ static struct fb_ops imsttfb_ops = {
1344 .fb_fillrect = imsttfb_fillrect, 1344 .fb_fillrect = imsttfb_fillrect,
1345 .fb_copyarea = imsttfb_copyarea, 1345 .fb_copyarea = imsttfb_copyarea,
1346 .fb_imageblit = cfb_imageblit, 1346 .fb_imageblit = cfb_imageblit,
1347 .fb_cursor = soft_cursor,
1348 .fb_ioctl = imsttfb_ioctl, 1347 .fb_ioctl = imsttfb_ioctl,
1349}; 1348};
1350 1349
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 64d9bcc38da3..e20b9f3a255f 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -298,7 +298,6 @@ static struct fb_ops imxfb_ops = {
298 .fb_copyarea = cfb_copyarea, 298 .fb_copyarea = cfb_copyarea,
299 .fb_imageblit = cfb_imageblit, 299 .fb_imageblit = cfb_imageblit,
300 .fb_blank = imxfb_blank, 300 .fb_blank = imxfb_blank,
301 .fb_cursor = soft_cursor, /* FIXME: i.MX can do hardware cursor */
302}; 301};
303 302
304/* 303/*
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 011e11626558..f077ca34faba 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -10,7 +10,7 @@
10/*** Version/name ***/ 10/*** Version/name ***/
11#define INTELFB_VERSION "0.9.2" 11#define INTELFB_VERSION "0.9.2"
12#define INTELFB_MODULE_NAME "intelfb" 12#define INTELFB_MODULE_NAME "intelfb"
13#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G" 13#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM"
14 14
15 15
16/*** Debug/feature defines ***/ 16/*** Debug/feature defines ***/
@@ -47,6 +47,7 @@
47#define PCI_DEVICE_ID_INTEL_85XGM 0x3582 47#define PCI_DEVICE_ID_INTEL_85XGM 0x3582
48#define PCI_DEVICE_ID_INTEL_865G 0x2572 48#define PCI_DEVICE_ID_INTEL_865G 0x2572
49#define PCI_DEVICE_ID_INTEL_915G 0x2582 49#define PCI_DEVICE_ID_INTEL_915G 0x2582
50#define PCI_DEVICE_ID_INTEL_915GM 0x2592
50 51
51/* Size of MMIO region */ 52/* Size of MMIO region */
52#define INTEL_REG_SIZE 0x80000 53#define INTEL_REG_SIZE 0x80000
@@ -119,7 +120,8 @@ enum intel_chips {
119 INTEL_855GM, 120 INTEL_855GM,
120 INTEL_855GME, 121 INTEL_855GME,
121 INTEL_865G, 122 INTEL_865G,
122 INTEL_915G 123 INTEL_915G,
124 INTEL_915GM
123}; 125};
124 126
125struct intelfb_hwstate { 127struct intelfb_hwstate {
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 80a09344f1aa..427689e584da 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * intelfb 2 * intelfb
3 * 3 *
4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G 4 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM
5 * integrated graphics chips. 5 * integrated graphics chips.
6 * 6 *
7 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org> 7 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
@@ -122,7 +122,6 @@
122#include <linux/pci.h> 122#include <linux/pci.h>
123#include <linux/vmalloc.h> 123#include <linux/vmalloc.h>
124#include <linux/pagemap.h> 124#include <linux/pagemap.h>
125#include <linux/version.h>
126 125
127#include <asm/io.h> 126#include <asm/io.h>
128 127
@@ -186,6 +185,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
186 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM }, 185 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM },
187 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G }, 186 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G },
188 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G }, 187 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G },
188 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
189 { 0, } 189 { 0, }
190}; 190};
191 191
@@ -549,10 +549,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
549 } 549 }
550 550
551 /* Set base addresses. */ 551 /* Set base addresses. */
552 if (ent->device == PCI_DEVICE_ID_INTEL_915G) { 552 if ((ent->device == PCI_DEVICE_ID_INTEL_915G) ||
553 (ent->device == PCI_DEVICE_ID_INTEL_915GM)) {
553 aperture_bar = 2; 554 aperture_bar = 2;
554 mmio_bar = 0; 555 mmio_bar = 0;
555 /* Disable HW cursor on 915G (not implemented yet) */ 556 /* Disable HW cursor on 915G/M (not implemented yet) */
556 hwcursor = 0; 557 hwcursor = 0;
557 } 558 }
558 dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar); 559 dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar);
@@ -1483,7 +1484,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1483#endif 1484#endif
1484 1485
1485 if (!dinfo->hwcursor) 1486 if (!dinfo->hwcursor)
1486 return soft_cursor(info, cursor); 1487 return -ENODEV;
1487 1488
1488 intelfbhw_cursor_hide(dinfo); 1489 intelfbhw_cursor_hide(dinfo);
1489 1490
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 5bafc3c54db7..624c4bc96f0d 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -34,7 +34,6 @@
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
36#include <linux/pagemap.h> 36#include <linux/pagemap.h>
37#include <linux/version.h>
38 37
39#include <asm/io.h> 38#include <asm/io.h>
40 39
@@ -99,6 +98,11 @@ intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset,
99 *chipset = INTEL_915G; 98 *chipset = INTEL_915G;
100 *mobile = 0; 99 *mobile = 0;
101 return 0; 100 return 0;
101 case PCI_DEVICE_ID_INTEL_915GM:
102 *name = "Intel(R) 915GM";
103 *chipset = INTEL_915GM;
104 *mobile = 1;
105 return 0;
102 default: 106 default:
103 return 1; 107 return 1;
104 } 108 }
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index d8bac9e97842..5eb4d5c177bd 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -669,7 +669,6 @@ static struct fb_ops kyrofb_ops = {
669 .fb_fillrect = cfb_fillrect, 669 .fb_fillrect = cfb_fillrect,
670 .fb_copyarea = cfb_copyarea, 670 .fb_copyarea = cfb_copyarea,
671 .fb_imageblit = cfb_imageblit, 671 .fb_imageblit = cfb_imageblit,
672 .fb_cursor = soft_cursor,
673}; 672};
674 673
675static int __devinit kyrofb_probe(struct pci_dev *pdev, 674static int __devinit kyrofb_probe(struct pci_dev *pdev,
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 7e1e7fb168bd..84a7fe435bb8 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -51,7 +51,6 @@ static struct fb_ops leo_ops = {
51 .fb_imageblit = cfb_imageblit, 51 .fb_imageblit = cfb_imageblit,
52 .fb_mmap = leo_mmap, 52 .fb_mmap = leo_mmap,
53 .fb_ioctl = leo_ioctl, 53 .fb_ioctl = leo_ioctl,
54 .fb_cursor = soft_cursor,
55}; 54};
56 55
57#define LEO_OFF_LC_SS0_KRN 0x00200000UL 56#define LEO_OFF_LC_SS0_KRN 0x00200000UL
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 3e9ccf370ab2..8cb7fb4db441 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -7,6 +7,8 @@ menu "Logo configuration"
7config LOGO 7config LOGO
8 bool "Bootup logo" 8 bool "Bootup logo"
9 depends on FB || SGI_NEWPORT_CONSOLE 9 depends on FB || SGI_NEWPORT_CONSOLE
10 help
11 Enable and select frame buffer bootup logos.
10 12
11config LOGO_LINUX_MONO 13config LOGO_LINUX_MONO
12 bool "Standard black and white Linux logo" 14 bool "Standard black and white Linux logo"
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 4945a4c02209..cfc748e94272 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -589,7 +589,6 @@ static struct fb_ops macfb_ops = {
589 .fb_fillrect = cfb_fillrect, 589 .fb_fillrect = cfb_fillrect,
590 .fb_copyarea = cfb_copyarea, 590 .fb_copyarea = cfb_copyarea,
591 .fb_imageblit = cfb_imageblit, 591 .fb_imageblit = cfb_imageblit,
592 .fb_cursor = soft_cursor,
593}; 592};
594 593
595void __init macfb_setup(char *options) 594void __init macfb_setup(char *options)
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/matrox/matroxfb_DAC1064.c
index 149680f8bcf0..0fbd9b5149f1 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.c
+++ b/drivers/video/matrox/matroxfb_DAC1064.c
@@ -657,7 +657,6 @@ static int MGA1064_preinit(WPMINFO2) {
657 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ 657 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
658 ACCESS_FBINFO(capable.text) = 1; 658 ACCESS_FBINFO(capable.text) = 1;
659 ACCESS_FBINFO(capable.vxres) = vxres_mystique; 659 ACCESS_FBINFO(capable.vxres) = vxres_mystique;
660 ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
661 660
662 ACCESS_FBINFO(outputs[0]).output = &m1064; 661 ACCESS_FBINFO(outputs[0]).output = &m1064;
663 ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src; 662 ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
@@ -842,7 +841,6 @@ static int MGAG100_preinit(WPMINFO2) {
842 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */ 841 /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
843 ACCESS_FBINFO(capable.text) = 1; 842 ACCESS_FBINFO(capable.text) = 1;
844 ACCESS_FBINFO(capable.vxres) = vxres_g100; 843 ACCESS_FBINFO(capable.vxres) = vxres_g100;
845 ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
846 ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100 844 ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
847 ? ACCESS_FBINFO(devflags.sgram) : 1; 845 ? ACCESS_FBINFO(devflags.sgram) : 1;
848 846
@@ -980,7 +978,7 @@ static void MGAG100_reset(WPMINFO2) {
980 hw->MXoptionReg |= 0x40; /* FIXME... */ 978 hw->MXoptionReg |= 0x40; /* FIXME... */
981 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg); 979 pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
982 } 980 }
983 mga_setr(M_EXTVGA_INDEX, 0x06, 0x50); 981 mga_setr(M_EXTVGA_INDEX, 0x06, 0x00);
984 } 982 }
985 } 983 }
986 if (ACCESS_FBINFO(devflags.g450dac)) { 984 if (ACCESS_FBINFO(devflags.g450dac)) {
diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c
index c7f3e1321224..a5c825d99466 100644
--- a/drivers/video/matrox/matroxfb_accel.c
+++ b/drivers/video/matrox/matroxfb_accel.c
@@ -122,7 +122,7 @@ void matrox_cfbX_init(WPMINFO2) {
122 ACCESS_FBINFO(fbops).fb_copyarea = cfb_copyarea; 122 ACCESS_FBINFO(fbops).fb_copyarea = cfb_copyarea;
123 ACCESS_FBINFO(fbops).fb_fillrect = cfb_fillrect; 123 ACCESS_FBINFO(fbops).fb_fillrect = cfb_fillrect;
124 ACCESS_FBINFO(fbops).fb_imageblit = cfb_imageblit; 124 ACCESS_FBINFO(fbops).fb_imageblit = cfb_imageblit;
125 ACCESS_FBINFO(fbops).fb_cursor = soft_cursor; 125 ACCESS_FBINFO(fbops).fb_cursor = NULL;
126 126
127 accel = (ACCESS_FBINFO(fbcon).var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT; 127 accel = (ACCESS_FBINFO(fbcon).var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT;
128 128
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index e02da41f1b26..1e74f4cca53b 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -264,7 +264,6 @@ static void matroxfb_disable_irq(WPMINFO2) {
264} 264}
265 265
266int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) { 266int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {
267 wait_queue_t __wait;
268 struct matrox_vsync *vs; 267 struct matrox_vsync *vs;
269 unsigned int cnt; 268 unsigned int cnt;
270 int ret; 269 int ret;
@@ -286,7 +285,6 @@ int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {
286 if (ret) { 285 if (ret) {
287 return ret; 286 return ret;
288 } 287 }
289 init_waitqueue_entry(&__wait, current);
290 288
291 cnt = vs->cnt; 289 cnt = vs->cnt;
292 ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10); 290 ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10);
@@ -500,10 +498,6 @@ static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) {
500 } else { 498 } else {
501 xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp); 499 xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp);
502 } 500 }
503 if (!xres_new) return 0;
504 if (xres != xres_new) {
505 printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new);
506 }
507 return xres_new; 501 return xres_new;
508} 502}
509 503
@@ -1285,7 +1279,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
1285 vaddr_t vm; 1279 vaddr_t vm;
1286 unsigned int offs; 1280 unsigned int offs;
1287 unsigned int offs2; 1281 unsigned int offs2;
1288 unsigned char store, orig; 1282 unsigned char orig;
1289 unsigned char bytes[32]; 1283 unsigned char bytes[32];
1290 unsigned char* tmp; 1284 unsigned char* tmp;
1291 1285
@@ -1301,16 +1295,12 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
1301 orig = mga_inb(M_EXTVGA_DATA); 1295 orig = mga_inb(M_EXTVGA_DATA);
1302 mga_outb(M_EXTVGA_DATA, orig | 0x80); 1296 mga_outb(M_EXTVGA_DATA, orig | 0x80);
1303 1297
1304 store = mga_readb(vm, 0x1234);
1305 tmp = bytes; 1298 tmp = bytes;
1306 for (offs = 0x100000; offs < maxSize; offs += 0x200000) 1299 for (offs = 0x100000; offs < maxSize; offs += 0x200000)
1307 *tmp++ = mga_readb(vm, offs); 1300 *tmp++ = mga_readb(vm, offs);
1308 for (offs = 0x100000; offs < maxSize; offs += 0x200000) 1301 for (offs = 0x100000; offs < maxSize; offs += 0x200000)
1309 mga_writeb(vm, offs, 0x02); 1302 mga_writeb(vm, offs, 0x02);
1310 if (ACCESS_FBINFO(features.accel.has_cacheflush)) 1303 mga_outb(M_CACHEFLUSH, 0x00);
1311 mga_outb(M_CACHEFLUSH, 0x00);
1312 else
1313 mga_writeb(vm, 0x1234, 0x99);
1314 for (offs = 0x100000; offs < maxSize; offs += 0x200000) { 1304 for (offs = 0x100000; offs < maxSize; offs += 0x200000) {
1315 if (mga_readb(vm, offs) != 0x02) 1305 if (mga_readb(vm, offs) != 0x02)
1316 break; 1306 break;
@@ -1321,7 +1311,6 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
1321 tmp = bytes; 1311 tmp = bytes;
1322 for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000) 1312 for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000)
1323 mga_writeb(vm, offs2, *tmp++); 1313 mga_writeb(vm, offs2, *tmp++);
1324 mga_writeb(vm, 0x1234, store);
1325 1314
1326 mga_outb(M_EXTVGA_INDEX, 0x03); 1315 mga_outb(M_EXTVGA_INDEX, 0x03);
1327 mga_outb(M_EXTVGA_DATA, orig); 1316 mga_outb(M_EXTVGA_DATA, orig);
@@ -1430,6 +1419,20 @@ static struct board {
1430 MGA_1164, 1419 MGA_1164,
1431 &vbMystique, 1420 &vbMystique,
1432 "Mystique 220 (PCI)"}, 1421 "Mystique 220 (PCI)"},
1422 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0x02,
1423 0, 0,
1424 DEVF_VIDEO64BIT | DEVF_CROSS4MB,
1425 180000,
1426 MGA_1064,
1427 &vbMystique,
1428 "Mystique (AGP)"},
1429 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS_AGP, 0xFF,
1430 0, 0,
1431 DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
1432 220000,
1433 MGA_1164,
1434 &vbMystique,
1435 "Mystique 220 (AGP)"},
1433#endif 1436#endif
1434#ifdef CONFIG_FB_MATROX_G 1437#ifdef CONFIG_FB_MATROX_G
1435 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF, 1438 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF,
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index 85a0b2558452..a8c47ad2cdb6 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/matrox/matroxfb_base.h
@@ -272,10 +272,6 @@ struct matrox_DAC1064_features {
272 u_int8_t xmiscctrl; 272 u_int8_t xmiscctrl;
273}; 273};
274 274
275struct matrox_accel_features {
276 int has_cacheflush;
277};
278
279/* current hardware status */ 275/* current hardware status */
280struct mavenregs { 276struct mavenregs {
281 u_int8_t regs[256]; 277 u_int8_t regs[256];
@@ -440,7 +436,6 @@ struct matrox_fb_info {
440 struct { 436 struct {
441 struct matrox_pll_features pll; 437 struct matrox_pll_features pll;
442 struct matrox_DAC1064_features DAC1064; 438 struct matrox_DAC1064_features DAC1064;
443 struct matrox_accel_features accel;
444 } features; 439 } features;
445 struct { 440 struct {
446 spinlock_t DAC; 441 spinlock_t DAC;
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 429047ac615a..d52d7d825c41 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -576,7 +576,6 @@ static struct fb_ops matroxfb_dh_ops = {
576 .fb_fillrect = cfb_fillrect, 576 .fb_fillrect = cfb_fillrect,
577 .fb_copyarea = cfb_copyarea, 577 .fb_copyarea = cfb_copyarea,
578 .fb_imageblit = cfb_imageblit, 578 .fb_imageblit = cfb_imageblit,
579 .fb_cursor = soft_cursor,
580}; 579};
581 580
582static struct fb_var_screeninfo matroxfb_dh_defined = { 581static struct fb_var_screeninfo matroxfb_dh_defined = {
diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c
index f192d995d030..743e7ad26acc 100644
--- a/drivers/video/maxinefb.c
+++ b/drivers/video/maxinefb.c
@@ -113,7 +113,6 @@ static struct fb_ops maxinefb_ops = {
113 .fb_fillrect = cfb_fillrect, 113 .fb_fillrect = cfb_fillrect,
114 .fb_copyarea = cfb_copyarea, 114 .fb_copyarea = cfb_copyarea,
115 .fb_imageblit = cfb_imageblit, 115 .fb_imageblit = cfb_imageblit,
116 .fb_cursor = soft_cursor,
117}; 116};
118 117
119int __init maxinefb_init(void) 118int __init maxinefb_init(void)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 47516c44a390..1da2f84bdc25 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -251,6 +251,10 @@ static const struct fb_videomode modedb[] = {
251 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, 251 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
253 FB_VMODE_NONINTERLACED 253 FB_VMODE_NONINTERLACED
254 }, {
255 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
256 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
257 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
254 }, 258 },
255}; 259};
256 260
@@ -676,6 +680,8 @@ void fb_var_to_videomode(struct fb_videomode *mode,
676 mode->sync = var->sync; 680 mode->sync = var->sync;
677 mode->vmode = var->vmode & FB_VMODE_MASK; 681 mode->vmode = var->vmode & FB_VMODE_MASK;
678 mode->flag = FB_MODE_IS_FROM_VAR; 682 mode->flag = FB_MODE_IS_FROM_VAR;
683 mode->refresh = 0;
684
679 if (!var->pixclock) 685 if (!var->pixclock)
680 return; 686 return;
681 687
@@ -785,39 +791,39 @@ struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
785} 791}
786 792
787/** 793/**
788 * fb_find_nearest_mode - find mode closest video mode 794 * fb_find_nearest_mode - find closest videomode
789 * 795 *
790 * @var: pointer to struct fb_var_screeninfo 796 * @mode: pointer to struct fb_videomode
791 * @head: pointer to modelist 797 * @head: pointer to modelist
792 * 798 *
793 * Finds best matching videomode, smaller or greater in dimension. 799 * Finds best matching videomode, smaller or greater in dimension.
794 * If more than 1 videomode is found, will return the videomode with 800 * If more than 1 videomode is found, will return the videomode with
795 * the closest refresh rate 801 * the closest refresh rate.
796 */ 802 */
797struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var, 803struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
798 struct list_head *head) 804 struct list_head *head)
799{ 805{
800 struct list_head *pos; 806 struct list_head *pos;
801 struct fb_modelist *modelist; 807 struct fb_modelist *modelist;
802 struct fb_videomode *mode, *best = NULL; 808 struct fb_videomode *cmode, *best = NULL;
803 u32 diff = -1, diff_refresh = -1; 809 u32 diff = -1, diff_refresh = -1;
804 810
805 list_for_each(pos, head) { 811 list_for_each(pos, head) {
806 u32 d; 812 u32 d;
807 813
808 modelist = list_entry(pos, struct fb_modelist, list); 814 modelist = list_entry(pos, struct fb_modelist, list);
809 mode = &modelist->mode; 815 cmode = &modelist->mode;
810 816
811 d = abs(mode->xres - var->xres) + 817 d = abs(cmode->xres - mode->xres) +
812 abs(mode->yres - var->yres); 818 abs(cmode->yres - mode->yres);
813 if (diff > d) { 819 if (diff > d) {
814 diff = d; 820 diff = d;
815 best = mode; 821 best = cmode;
816 } else if (diff == d) { 822 } else if (diff == d) {
817 d = abs(mode->refresh - best->refresh); 823 d = abs(cmode->refresh - mode->refresh);
818 if (diff_refresh > d) { 824 if (diff_refresh > d) {
819 diff_refresh = d; 825 diff_refresh = d;
820 best = mode; 826 best = cmode;
821 } 827 }
822 } 828 }
823 } 829 }
@@ -942,6 +948,66 @@ void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
942 } 948 }
943} 949}
944 950
951struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
952 struct list_head *head)
953{
954 struct list_head *pos;
955 struct fb_modelist *modelist;
956 struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL;
957 int first = 0;
958
959 if (!head->prev || !head->next || list_empty(head))
960 goto finished;
961
962 /* get the first detailed mode and the very first mode */
963 list_for_each(pos, head) {
964 modelist = list_entry(pos, struct fb_modelist, list);
965 m = &modelist->mode;
966
967 if (!first) {
968 m1 = m;
969 first = 1;
970 }
971
972 if (m->flag & FB_MODE_IS_FIRST) {
973 md = m;
974 break;
975 }
976 }
977
978 /* first detailed timing is preferred */
979 if (specs->misc & FB_MISC_1ST_DETAIL) {
980 best = md;
981 goto finished;
982 }
983
984 /* find best mode based on display width and height */
985 if (specs->max_x && specs->max_y) {
986 struct fb_var_screeninfo var;
987
988 memset(&var, 0, sizeof(struct fb_var_screeninfo));
989 var.xres = (specs->max_x * 7200)/254;
990 var.yres = (specs->max_y * 7200)/254;
991 m = fb_find_best_mode(&var, head);
992 if (m) {
993 best = m;
994 goto finished;
995 }
996 }
997
998 /* use first detailed mode */
999 if (md) {
1000 best = md;
1001 goto finished;
1002 }
1003
1004 /* last resort, use the very first mode */
1005 best = m1;
1006finished:
1007 return best;
1008}
1009EXPORT_SYMBOL(fb_find_best_display);
1010
945EXPORT_SYMBOL(fb_videomode_to_var); 1011EXPORT_SYMBOL(fb_videomode_to_var);
946EXPORT_SYMBOL(fb_var_to_videomode); 1012EXPORT_SYMBOL(fb_var_to_videomode);
947EXPORT_SYMBOL(fb_mode_is_equal); 1013EXPORT_SYMBOL(fb_mode_is_equal);
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 5d424a30270a..8486e77872dc 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -1665,7 +1665,6 @@ static struct fb_ops neofb_ops = {
1665 .fb_fillrect = neofb_fillrect, 1665 .fb_fillrect = neofb_fillrect,
1666 .fb_copyarea = neofb_copyarea, 1666 .fb_copyarea = neofb_copyarea,
1667 .fb_imageblit = neofb_imageblit, 1667 .fb_imageblit = neofb_imageblit,
1668 .fb_cursor = soft_cursor,
1669}; 1668};
1670 1669
1671/* --------------------------------------------------------------------- */ 1670/* --------------------------------------------------------------------- */
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index afee284fc73c..4243d7fae972 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -105,7 +105,7 @@ do { \
105 *a = byte_rev[*a]; \ 105 *a = byte_rev[*a]; \
106} while(0) 106} while(0)
107#else 107#else
108#define reverse_order(l) 108#define reverse_order(l) do { } while(0)
109#endif /* __LITTLE_ENDIAN */ 109#endif /* __LITTLE_ENDIAN */
110 110
111#endif /* __NV_LOCAL_H__ */ 111#endif /* __NV_LOCAL_H__ */
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/nvidia/nv_of.c
index 4fa2cf9a8af2..7a03d040b1a3 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/nvidia/nv_of.c
@@ -27,34 +27,60 @@
27#include "nv_local.h" 27#include "nv_local.h"
28#include "nv_proto.h" 28#include "nv_proto.h"
29 29
30void nvidia_create_i2c_busses(struct nvidia_par *par) {} 30#include "../edid.h"
31void nvidia_delete_i2c_busses(struct nvidia_par *par) {}
32 31
33int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) 32int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
34{ 33{
35 struct nvidia_par *par = info->par; 34 struct nvidia_par *par = info->par;
36 struct device_node *dp; 35 struct device_node *parent, *dp;
37 unsigned char *pedid = NULL; 36 unsigned char *pedid = NULL;
38 unsigned char *disptype = NULL;
39 static char *propnames[] = { 37 static char *propnames[] = {
40 "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL }; 38 "DFP,EDID", "LCD,EDID", "EDID", "EDID1",
39 "EDID,B", "EDID,A", NULL };
41 int i; 40 int i;
42 41
43 dp = pci_device_to_OF_node(par->pci_dev); 42 parent = pci_device_to_OF_node(par->pci_dev);
44 for (; dp != NULL; dp = dp->child) { 43 if (parent == NULL)
45 disptype = (unsigned char *)get_property(dp, "display-type", NULL); 44 return -1;
46 if (disptype == NULL) 45 if (par->twoHeads) {
47 continue; 46 char *pname;
48 if (strncmp(disptype, "LCD", 3) != 0) 47 int len;
49 continue; 48
49 for (dp = NULL;
50 (dp = of_get_next_child(parent, dp)) != NULL;) {
51 pname = (char *)get_property(dp, "name", NULL);
52 if (!pname)
53 continue;
54 len = strlen(pname);
55 if ((pname[len-1] == 'A' && conn == 1) ||
56 (pname[len-1] == 'B' && conn == 2)) {
57 for (i = 0; propnames[i] != NULL; ++i) {
58 pedid = (unsigned char *)
59 get_property(dp, propnames[i],
60 NULL);
61 if (pedid != NULL)
62 break;
63 }
64 of_node_put(dp);
65 break;
66 }
67 }
68 }
69 if (pedid == NULL) {
50 for (i = 0; propnames[i] != NULL; ++i) { 70 for (i = 0; propnames[i] != NULL; ++i) {
51 pedid = (unsigned char *) 71 pedid = (unsigned char *)
52 get_property(dp, propnames[i], NULL); 72 get_property(parent, propnames[i], NULL);
53 if (pedid != NULL) { 73 if (pedid != NULL)
54 *out_edid = pedid; 74 break;
55 return 0;
56 }
57 } 75 }
58 } 76 }
59 return 1; 77 if (pedid) {
78 *out_edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
79 if (*out_edid == NULL)
80 return -1;
81 memcpy(*out_edid, pedid, EDID_LENGTH);
82 printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn);
83 return 0;
84 }
85 return -1;
60} 86}
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/nvidia/nv_proto.h
index cac44fc7f587..f60b1f432270 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/nvidia/nv_proto.h
@@ -31,7 +31,7 @@ int NVShowHideCursor(struct nvidia_par *par, int);
31void NVLockUnlock(struct nvidia_par *par, int); 31void NVLockUnlock(struct nvidia_par *par, int);
32 32
33/* in nvidia-i2c.c */ 33/* in nvidia-i2c.c */
34#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF) 34#ifdef CONFIG_FB_NVIDIA_I2C
35void nvidia_create_i2c_busses(struct nvidia_par *par); 35void nvidia_create_i2c_busses(struct nvidia_par *par);
36void nvidia_delete_i2c_busses(struct nvidia_par *par); 36void nvidia_delete_i2c_busses(struct nvidia_par *par);
37int nvidia_probe_i2c_connector(struct fb_info *info, int conn, 37int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
@@ -39,10 +39,18 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
39#else 39#else
40#define nvidia_create_i2c_busses(...) 40#define nvidia_create_i2c_busses(...)
41#define nvidia_delete_i2c_busses(...) 41#define nvidia_delete_i2c_busses(...)
42#define nvidia_probe_i2c_connector(p, c, edid) \ 42#define nvidia_probe_i2c_connector(p, c, edid) (-1)
43do { \ 43#endif
44 *(edid) = NULL; \ 44
45} while(0) 45#ifdef CONFIG_FB_OF
46int nvidia_probe_of_connector(struct fb_info *info, int conn,
47 u8 ** out_edid);
48#else
49static inline int nvidia_probe_of_connector(struct fb_info *info, int conn,
50 u8 ** out_edid)
51{
52 return -1;
53}
46#endif 54#endif
47 55
48/* in nv_accel.c */ 56/* in nv_accel.c */
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index 11c84178f420..1f06a9f1bd0f 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -190,9 +190,9 @@ static int NVIsConnected(struct nvidia_par *par, int output)
190 present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? 1 : 0; 190 present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? 1 : 0;
191 191
192 if (present) 192 if (present)
193 printk("nvidiafb: CRTC%i found\n", output); 193 printk("nvidiafb: CRTC%i analog found\n", output);
194 else 194 else
195 printk("nvidiafb: CRTC%i not found\n", output); 195 printk("nvidiafb: CRTC%i analog not found\n", output);
196 196
197 NV_WR32(par->PRAMDAC0, 0x0608, NV_RD32(par->PRAMDAC0, 0x0608) & 197 NV_WR32(par->PRAMDAC0, 0x0608, NV_RD32(par->PRAMDAC0, 0x0608) &
198 0x0000EFFF); 198 0x0000EFFF);
@@ -305,6 +305,9 @@ void NVCommonSetup(struct fb_info *info)
305 int FlatPanel = -1; /* really means the CRTC is slaved */ 305 int FlatPanel = -1; /* really means the CRTC is slaved */
306 int Television = 0; 306 int Television = 0;
307 307
308 memset(&monitorA, 0, sizeof(struct fb_monspecs));
309 memset(&monitorB, 0, sizeof(struct fb_monspecs));
310
308 par->PRAMIN = par->REGS + (0x00710000 / 4); 311 par->PRAMIN = par->REGS + (0x00710000 / 4);
309 par->PCRTC0 = par->REGS + (0x00600000 / 4); 312 par->PCRTC0 = par->REGS + (0x00600000 / 4);
310 par->PRAMDAC0 = par->REGS + (0x00680000 / 4); 313 par->PRAMDAC0 = par->REGS + (0x00680000 / 4);
@@ -401,7 +404,8 @@ void NVCommonSetup(struct fb_info *info)
401 nvidia_create_i2c_busses(par); 404 nvidia_create_i2c_busses(par);
402 if (!par->twoHeads) { 405 if (!par->twoHeads) {
403 par->CRTCnumber = 0; 406 par->CRTCnumber = 0;
404 nvidia_probe_i2c_connector(info, 1, &edidA); 407 if (nvidia_probe_i2c_connector(info, 1, &edidA))
408 nvidia_probe_of_connector(info, 1, &edidA);
405 if (edidA && !fb_parse_edid(edidA, &var)) { 409 if (edidA && !fb_parse_edid(edidA, &var)) {
406 printk("nvidiafb: EDID found from BUS1\n"); 410 printk("nvidiafb: EDID found from BUS1\n");
407 monA = &monitorA; 411 monA = &monitorA;
@@ -488,14 +492,16 @@ void NVCommonSetup(struct fb_info *info)
488 oldhead = NV_RD32(par->PCRTC0, 0x00000860); 492 oldhead = NV_RD32(par->PCRTC0, 0x00000860);
489 NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010); 493 NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010);
490 494
491 nvidia_probe_i2c_connector(info, 1, &edidA); 495 if (nvidia_probe_i2c_connector(info, 1, &edidA))
496 nvidia_probe_of_connector(info, 1, &edidA);
492 if (edidA && !fb_parse_edid(edidA, &var)) { 497 if (edidA && !fb_parse_edid(edidA, &var)) {
493 printk("nvidiafb: EDID found from BUS1\n"); 498 printk("nvidiafb: EDID found from BUS1\n");
494 monA = &monitorA; 499 monA = &monitorA;
495 fb_edid_to_monspecs(edidA, monA); 500 fb_edid_to_monspecs(edidA, monA);
496 } 501 }
497 502
498 nvidia_probe_i2c_connector(info, 2, &edidB); 503 if (nvidia_probe_i2c_connector(info, 2, &edidB))
504 nvidia_probe_of_connector(info, 2, &edidB);
499 if (edidB && !fb_parse_edid(edidB, &var)) { 505 if (edidB && !fb_parse_edid(edidB, &var)) {
500 printk("nvidiafb: EDID found from BUS2\n"); 506 printk("nvidiafb: EDID found from BUS2\n");
501 monB = &monitorB; 507 monB = &monitorB;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 308defc389a2..0b40a2a721c1 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -411,6 +411,7 @@ MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
411 411
412/* command line data, set in nvidiafb_setup() */ 412/* command line data, set in nvidiafb_setup() */
413static int flatpanel __devinitdata = -1; /* Autodetect later */ 413static int flatpanel __devinitdata = -1; /* Autodetect later */
414static int fpdither __devinitdata = -1;
414static int forceCRTC __devinitdata = -1; 415static int forceCRTC __devinitdata = -1;
415static int hwcur __devinitdata = 0; 416static int hwcur __devinitdata = 0;
416static int noaccel __devinitdata = 0; 417static int noaccel __devinitdata = 0;
@@ -627,41 +628,85 @@ static void nvidia_save_vga(struct nvidia_par *par,
627 NVTRACE_LEAVE(); 628 NVTRACE_LEAVE();
628} 629}
629 630
631#undef DUMP_REG
632
630static void nvidia_write_regs(struct nvidia_par *par) 633static void nvidia_write_regs(struct nvidia_par *par)
631{ 634{
632 struct _riva_hw_state *state = &par->ModeReg; 635 struct _riva_hw_state *state = &par->ModeReg;
633 int i; 636 int i;
634 637
635 NVTRACE_ENTER(); 638 NVTRACE_ENTER();
636 NVWriteCrtc(par, 0x11, 0x00);
637
638 NVLockUnlock(par, 0);
639 639
640 NVLoadStateExt(par, state); 640 NVLoadStateExt(par, state);
641 641
642 NVWriteMiscOut(par, state->misc_output); 642 NVWriteMiscOut(par, state->misc_output);
643 643
644 for (i = 1; i < NUM_SEQ_REGS; i++) {
645#ifdef DUMP_REG
646 printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
647#endif
648 NVWriteSeq(par, i, state->seq[i]);
649 }
650
651 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
652 NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
653
644 for (i = 0; i < NUM_CRT_REGS; i++) { 654 for (i = 0; i < NUM_CRT_REGS; i++) {
645 switch (i) { 655 switch (i) {
646 case 0x19: 656 case 0x19:
647 case 0x20 ... 0x40: 657 case 0x20 ... 0x40:
648 break; 658 break;
649 default: 659 default:
660#ifdef DUMP_REG
661 printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
662#endif
650 NVWriteCrtc(par, i, state->crtc[i]); 663 NVWriteCrtc(par, i, state->crtc[i]);
651 } 664 }
652 } 665 }
653 666
654 for (i = 0; i < NUM_ATC_REGS; i++) 667 for (i = 0; i < NUM_GRC_REGS; i++) {
655 NVWriteAttr(par, i, state->attr[i]); 668#ifdef DUMP_REG
656 669 printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
657 for (i = 0; i < NUM_GRC_REGS; i++) 670#endif
658 NVWriteGr(par, i, state->gra[i]); 671 NVWriteGr(par, i, state->gra[i]);
672 }
673
674 for (i = 0; i < NUM_ATC_REGS; i++) {
675#ifdef DUMP_REG
676 printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
677#endif
678 NVWriteAttr(par, i, state->attr[i]);
679 }
659 680
660 for (i = 0; i < NUM_SEQ_REGS; i++)
661 NVWriteSeq(par, i, state->seq[i]);
662 NVTRACE_LEAVE(); 681 NVTRACE_LEAVE();
663} 682}
664 683
684static void nvidia_vga_protect(struct nvidia_par *par, int on)
685{
686 unsigned char tmp;
687
688 if (on) {
689 /*
690 * Turn off screen and disable sequencer.
691 */
692 tmp = NVReadSeq(par, 0x01);
693
694 NVWriteSeq(par, 0x00, 0x01); /* Synchronous Reset */
695 NVWriteSeq(par, 0x01, tmp | 0x20); /* disable the display */
696 } else {
697 /*
698 * Reenable sequencer, then turn on screen.
699 */
700
701 tmp = NVReadSeq(par, 0x01);
702
703 NVWriteSeq(par, 0x01, tmp & ~0x20); /* reenable display */
704 NVWriteSeq(par, 0x00, 0x03); /* End Reset */
705 }
706}
707
708
709
665static int nvidia_calc_regs(struct fb_info *info) 710static int nvidia_calc_regs(struct fb_info *info)
666{ 711{
667 struct nvidia_par *par = info->par; 712 struct nvidia_par *par = info->par;
@@ -868,7 +913,7 @@ static void nvidia_init_vga(struct fb_info *info)
868 for (i = 0; i < 0x10; i++) 913 for (i = 0; i < 0x10; i++)
869 state->attr[i] = i; 914 state->attr[i] = i;
870 state->attr[0x10] = 0x41; 915 state->attr[0x10] = 0x41;
871 state->attr[0x11] = 0x01; 916 state->attr[0x11] = 0xff;
872 state->attr[0x12] = 0x0f; 917 state->attr[0x12] = 0x0f;
873 state->attr[0x13] = 0x00; 918 state->attr[0x13] = 0x00;
874 state->attr[0x14] = 0x00; 919 state->attr[0x14] = 0x00;
@@ -982,16 +1027,24 @@ static int nvidiafb_set_par(struct fb_info *info)
982 NVTRACE_ENTER(); 1027 NVTRACE_ENTER();
983 1028
984 NVLockUnlock(par, 1); 1029 NVLockUnlock(par, 1);
985 if (!par->FlatPanel || (info->var.bits_per_pixel != 24) || 1030 if (!par->FlatPanel || !par->twoHeads)
986 !par->twoHeads)
987 par->FPDither = 0; 1031 par->FPDither = 0;
988 1032
1033 if (par->FPDither < 0) {
1034 if ((par->Chipset & 0x0ff0) == 0x0110)
1035 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
1036 & 0x00010000);
1037 else
1038 par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
1039 printk(KERN_INFO PFX "Flat panel dithering %s\n",
1040 par->FPDither ? "enabled" : "disabled");
1041 }
1042
989 info->fix.visual = (info->var.bits_per_pixel == 8) ? 1043 info->fix.visual = (info->var.bits_per_pixel == 8) ?
990 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; 1044 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
991 1045
992 nvidia_init_vga(info); 1046 nvidia_init_vga(info);
993 nvidia_calc_regs(info); 1047 nvidia_calc_regs(info);
994 nvidia_write_regs(par);
995 1048
996 NVLockUnlock(par, 0); 1049 NVLockUnlock(par, 0);
997 if (par->twoHeads) { 1050 if (par->twoHeads) {
@@ -1000,7 +1053,22 @@ static int nvidiafb_set_par(struct fb_info *info)
1000 NVLockUnlock(par, 0); 1053 NVLockUnlock(par, 0);
1001 } 1054 }
1002 1055
1003 NVWriteCrtc(par, 0x11, 0x00); 1056 nvidia_vga_protect(par, 1);
1057
1058 nvidia_write_regs(par);
1059
1060#if defined (__BIG_ENDIAN)
1061 /* turn on LFB swapping */
1062 {
1063 unsigned char tmp;
1064
1065 VGA_WR08(par->PCIO, 0x3d4, 0x46);
1066 tmp = VGA_RD08(par->PCIO, 0x3d5);
1067 tmp |= (1 << 7);
1068 VGA_WR08(par->PCIO, 0x3d5, tmp);
1069 }
1070#endif
1071
1004 info->fix.line_length = (info->var.xres_virtual * 1072 info->fix.line_length = (info->var.xres_virtual *
1005 info->var.bits_per_pixel) >> 3; 1073 info->var.bits_per_pixel) >> 3;
1006 if (info->var.accel_flags) { 1074 if (info->var.accel_flags) {
@@ -1022,7 +1090,7 @@ static int nvidiafb_set_par(struct fb_info *info)
1022 1090
1023 par->cursor_reset = 1; 1091 par->cursor_reset = 1;
1024 1092
1025 NVWriteCrtc(par, 0x11, 0xff); 1093 nvidia_vga_protect(par, 0);
1026 1094
1027 NVTRACE_LEAVE(); 1095 NVTRACE_LEAVE();
1028 return 0; 1096 return 0;
@@ -1315,22 +1383,10 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1315 fb_var_to_videomode(&modedb, &nvidiafb_default_var); 1383 fb_var_to_videomode(&modedb, &nvidiafb_default_var);
1316 1384
1317 if (specs->modedb != NULL) { 1385 if (specs->modedb != NULL) {
1318 /* get preferred timing */ 1386 struct fb_videomode *modedb;
1319 if (specs->misc & FB_MISC_1ST_DETAIL) {
1320 int i;
1321
1322 for (i = 0; i < specs->modedb_len; i++) {
1323 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
1324 modedb = specs->modedb[i];
1325 break;
1326 }
1327 }
1328 } else {
1329 /* otherwise, get first mode in database */
1330 modedb = specs->modedb[0];
1331 }
1332 1387
1333 fb_videomode_to_var(&nvidiafb_default_var, &modedb); 1388 modedb = fb_find_best_display(specs, &info->modelist);
1389 fb_videomode_to_var(&nvidiafb_default_var, modedb);
1334 nvidiafb_default_var.bits_per_pixel = 8; 1390 nvidiafb_default_var.bits_per_pixel = 8;
1335 } else if (par->fpWidth && par->fpHeight) { 1391 } else if (par->fpWidth && par->fpHeight) {
1336 char buf[16]; 1392 char buf[16];
@@ -1365,7 +1421,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
1365 info->pixmap.flags = FB_PIXMAP_SYSTEM; 1421 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1366 1422
1367 if (!hwcur) 1423 if (!hwcur)
1368 info->fbops->fb_cursor = soft_cursor; 1424 info->fbops->fb_cursor = NULL;
1369 1425
1370 info->var.accel_flags = (!noaccel); 1426 info->var.accel_flags = (!noaccel);
1371 1427
@@ -1490,9 +1546,9 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1490 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4); 1546 sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
1491 1547
1492 par->FlatPanel = flatpanel; 1548 par->FlatPanel = flatpanel;
1493
1494 if (flatpanel == 1) 1549 if (flatpanel == 1)
1495 printk(KERN_INFO PFX "flatpanel support enabled\n"); 1550 printk(KERN_INFO PFX "flatpanel support enabled\n");
1551 par->FPDither = fpdither;
1496 1552
1497 par->CRTCnumber = forceCRTC; 1553 par->CRTCnumber = forceCRTC;
1498 par->FpScale = (!noscale); 1554 par->FpScale = (!noscale);
@@ -1671,6 +1727,8 @@ static int __devinit nvidiafb_setup(char *options)
1671 } else if (!strncmp(this_opt, "nomtrr", 6)) { 1727 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1672 nomtrr = 1; 1728 nomtrr = 1;
1673#endif 1729#endif
1730 } else if (!strncmp(this_opt, "fpdither:", 9)) {
1731 fpdither = simple_strtol(this_opt+9, NULL, 0);
1674 } else 1732 } else
1675 mode_option = this_opt; 1733 mode_option = this_opt;
1676 } 1734 }
@@ -1717,7 +1775,11 @@ module_exit(nvidiafb_exit);
1717module_param(flatpanel, int, 0); 1775module_param(flatpanel, int, 0);
1718MODULE_PARM_DESC(flatpanel, 1776MODULE_PARM_DESC(flatpanel,
1719 "Enables experimental flat panel support for some chipsets. " 1777 "Enables experimental flat panel support for some chipsets. "
1720 "(0 or 1=enabled) (default=0)"); 1778 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1779module_param(fpdither, int, 0);
1780MODULE_PARM_DESC(fpdither,
1781 "Enables dithering of flat panel for 6 bits panels. "
1782 "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
1721module_param(hwcur, int, 0); 1783module_param(hwcur, int, 0);
1722MODULE_PARM_DESC(hwcur, 1784MODULE_PARM_DESC(hwcur,
1723 "Enables hardware cursor implementation. (0 or 1=enabled) " 1785 "Enables hardware cursor implementation. (0 or 1=enabled) "
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 611922c0b22f..2c856838694e 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -85,7 +85,6 @@ static struct fb_ops offb_ops = {
85 .fb_fillrect = cfb_fillrect, 85 .fb_fillrect = cfb_fillrect,
86 .fb_copyarea = cfb_copyarea, 86 .fb_copyarea = cfb_copyarea,
87 .fb_imageblit = cfb_imageblit, 87 .fb_imageblit = cfb_imageblit,
88 .fb_cursor = soft_cursor,
89}; 88};
90 89
91 /* 90 /*
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index b76a5a9a125b..9aaf65fb623a 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -48,7 +48,6 @@ static struct fb_ops p9100_ops = {
48 .fb_imageblit = cfb_imageblit, 48 .fb_imageblit = cfb_imageblit,
49 .fb_mmap = p9100_mmap, 49 .fb_mmap = p9100_mmap,
50 .fb_ioctl = p9100_ioctl, 50 .fb_ioctl = p9100_ioctl,
51 .fb_cursor = soft_cursor,
52}; 51};
53 52
54/* P9100 control registers */ 53/* P9100 control registers */
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index b00887e9851c..ca4082ae5a18 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -109,7 +109,6 @@ static struct fb_ops platinumfb_ops = {
109 .fb_fillrect = cfb_fillrect, 109 .fb_fillrect = cfb_fillrect,
110 .fb_copyarea = cfb_copyarea, 110 .fb_copyarea = cfb_copyarea,
111 .fb_imageblit = cfb_imageblit, 111 .fb_imageblit = cfb_imageblit,
112 .fb_cursor = soft_cursor,
113}; 112};
114 113
115/* 114/*
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 42c17efa9fb0..0277ce031e5e 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -1034,7 +1034,6 @@ static struct fb_ops pm2fb_ops = {
1034 .fb_fillrect = cfb_fillrect, 1034 .fb_fillrect = cfb_fillrect,
1035 .fb_copyarea = cfb_copyarea, 1035 .fb_copyarea = cfb_copyarea,
1036 .fb_imageblit = cfb_imageblit, 1036 .fb_imageblit = cfb_imageblit,
1037 .fb_cursor = soft_cursor,
1038}; 1037};
1039 1038
1040/* 1039/*
@@ -1121,6 +1120,22 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1121 default_par->mem_control, default_par->boot_address, 1120 default_par->mem_control, default_par->boot_address,
1122 default_par->mem_config); 1121 default_par->mem_config);
1123 1122
1123 if(default_par->mem_control == 0 &&
1124 default_par->boot_address == 0x31 &&
1125 default_par->mem_config == 0x259fffff &&
1126 pdev->subsystem_vendor == 0x1048 &&
1127 pdev->subsystem_device == 0x0a31) {
1128 DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
1129 pdev->subsystem_vendor, pdev->subsystem_device);
1130 DPRINTK("We have not been initialized by VGA BIOS "
1131 "and are running on an Elsa Winner 2000 Office\n");
1132 DPRINTK("Initializing card timings manually...\n");
1133 default_par->mem_control=0;
1134 default_par->boot_address=0x20;
1135 default_par->mem_config=0xe6002021;
1136 default_par->memclock=100000;
1137 }
1138
1124 /* Now work out how big lfb is going to be. */ 1139 /* Now work out how big lfb is going to be. */
1125 switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) { 1140 switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
1126 case PM2F_MEM_BANKS_1: 1141 case PM2F_MEM_BANKS_1:
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index c98f1c8d7dc2..f3927b6cda9d 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -128,7 +128,6 @@ static struct fb_ops pmagbafb_ops = {
128 .fb_fillrect = cfb_fillrect, 128 .fb_fillrect = cfb_fillrect,
129 .fb_copyarea = cfb_copyarea, 129 .fb_copyarea = cfb_copyarea,
130 .fb_imageblit = cfb_imageblit, 130 .fb_imageblit = cfb_imageblit,
131 .fb_cursor = soft_cursor,
132}; 131};
133 132
134 133
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index a483b13e117b..25148de5fe67 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -132,7 +132,6 @@ static struct fb_ops pmagbbfb_ops = {
132 .fb_fillrect = cfb_fillrect, 132 .fb_fillrect = cfb_fillrect,
133 .fb_copyarea = cfb_copyarea, 133 .fb_copyarea = cfb_copyarea,
134 .fb_imageblit = cfb_imageblit, 134 .fb_imageblit = cfb_imageblit,
135 .fb_cursor = soft_cursor,
136}; 135};
137 136
138 137
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 31c547fd383b..ec4bacf9dd2e 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -230,7 +230,6 @@ static struct fb_ops pvr2fb_ops = {
230 .fb_fillrect = cfb_fillrect, 230 .fb_fillrect = cfb_fillrect,
231 .fb_copyarea = cfb_copyarea, 231 .fb_copyarea = cfb_copyarea,
232 .fb_imageblit = cfb_imageblit, 232 .fb_imageblit = cfb_imageblit,
233 .fb_cursor = soft_cursor,
234}; 233};
235 234
236static struct fb_videomode pvr2_modedb[] __initdata = { 235static struct fb_videomode pvr2_modedb[] __initdata = {
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index efd9333b05c2..f305a5b77b23 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -418,7 +418,6 @@ static struct fb_ops pxafb_ops = {
418 .fb_copyarea = cfb_copyarea, 418 .fb_copyarea = cfb_copyarea,
419 .fb_imageblit = cfb_imageblit, 419 .fb_imageblit = cfb_imageblit,
420 .fb_blank = pxafb_blank, 420 .fb_blank = pxafb_blank,
421 .fb_cursor = soft_cursor,
422 .fb_mmap = pxafb_mmap, 421 .fb_mmap = pxafb_mmap,
423}; 422};
424 423
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index 8416b2e2b501..bfc41f2c902a 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -84,7 +84,6 @@ static struct fb_ops q40fb_ops = {
84 .fb_fillrect = cfb_fillrect, 84 .fb_fillrect = cfb_fillrect,
85 .fb_copyarea = cfb_copyarea, 85 .fb_copyarea = cfb_copyarea,
86 .fb_imageblit = cfb_imageblit, 86 .fb_imageblit = cfb_imageblit,
87 .fb_cursor = soft_cursor,
88}; 87};
89 88
90static int __init q40fb_probe(struct device *device) 89static int __init q40fb_probe(struct device *device)
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
index a78b9bd8f897..600318f708f2 100644
--- a/drivers/video/radeonfb.c
+++ b/drivers/video/radeonfb.c
@@ -2218,7 +2218,6 @@ static struct fb_ops radeonfb_ops = {
2218 .fb_copyarea = cfb_copyarea, 2218 .fb_copyarea = cfb_copyarea,
2219 .fb_imageblit = cfb_imageblit, 2219 .fb_imageblit = cfb_imageblit,
2220#endif 2220#endif
2221 .fb_cursor = soft_cursor,
2222}; 2221};
2223 2222
2224 2223
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index f4437430dc5f..3edbd14c5c46 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -388,7 +388,6 @@ static struct fb_ops s1d13xxxfb_fbops = {
388 .fb_fillrect = cfb_fillrect, 388 .fb_fillrect = cfb_fillrect,
389 .fb_copyarea = cfb_copyarea, 389 .fb_copyarea = cfb_copyarea,
390 .fb_imageblit = cfb_imageblit, 390 .fb_imageblit = cfb_imageblit,
391 .fb_cursor = soft_cursor
392}; 391};
393 392
394static int s1d13xxxfb_width_tab[2][4] __devinitdata = { 393static int s1d13xxxfb_width_tab[2][4] __devinitdata = {
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 3cef90456a4b..855a6778b9eb 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -495,7 +495,6 @@ static struct fb_ops s3c2410fb_ops = {
495 .fb_fillrect = cfb_fillrect, 495 .fb_fillrect = cfb_fillrect,
496 .fb_copyarea = cfb_copyarea, 496 .fb_copyarea = cfb_copyarea,
497 .fb_imageblit = cfb_imageblit, 497 .fb_imageblit = cfb_imageblit,
498 .fb_cursor = soft_cursor,
499}; 498};
500 499
501 500
@@ -885,6 +884,7 @@ static int s3c2410fb_resume(struct device *dev)
885 884
886static struct device_driver s3c2410fb_driver = { 885static struct device_driver s3c2410fb_driver = {
887 .name = "s3c2410-lcd", 886 .name = "s3c2410-lcd",
887 .owner = THIS_MODULE,
888 .bus = &platform_bus_type, 888 .bus = &platform_bus_type,
889 .probe = s3c2410fb_probe, 889 .probe = s3c2410fb_probe,
890 .suspend = s3c2410fb_suspend, 890 .suspend = s3c2410fb_suspend,
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 3d35b28aaac7..a5184575cfae 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -853,7 +853,6 @@ static struct fb_ops sa1100fb_ops = {
853 .fb_copyarea = cfb_copyarea, 853 .fb_copyarea = cfb_copyarea,
854 .fb_imageblit = cfb_imageblit, 854 .fb_imageblit = cfb_imageblit,
855 .fb_blank = sa1100fb_blank, 855 .fb_blank = sa1100fb_blank,
856 .fb_cursor = soft_cursor,
857 .fb_mmap = sa1100fb_mmap, 856 .fb_mmap = sa1100fb_mmap,
858}; 857};
859 858
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index ea17f7e0482c..58cfdfb41833 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -169,6 +169,7 @@ struct savagefb_par {
169 struct savagefb_i2c_chan chan; 169 struct savagefb_i2c_chan chan;
170 unsigned char *edid; 170 unsigned char *edid;
171 u32 pseudo_palette[16]; 171 u32 pseudo_palette[16];
172 int paletteEnabled;
172 int pm_state; 173 int pm_state;
173 int display_type; 174 int display_type;
174 int dvi; 175 int dvi;
@@ -244,105 +245,150 @@ struct savagefb_par {
244 245
245 246
246/* IO functions */ 247/* IO functions */
248static inline u8 savage_in8(u32 addr, struct savagefb_par *par)
249{
250 return readb(par->mmio.vbase + addr);
251}
252
253static inline u16 savage_in16(u32 addr, struct savagefb_par *par)
254{
255 return readw(par->mmio.vbase + addr);
256}
257
258static inline u32 savage_in32(u32 addr, struct savagefb_par *par)
259{
260 return readl(par->mmio.vbase + addr);
261}
262
263static inline void savage_out8(u32 addr, u8 val, struct savagefb_par *par)
264{
265 writeb(val, par->mmio.vbase + addr);
266}
267
268static inline void savage_out16(u32 addr, u16 val, struct savagefb_par *par)
269{
270 writew(val, par->mmio.vbase + addr);
271}
272
273static inline void savage_out32(u32 addr, u32 val, struct savagefb_par *par)
274{
275 writel(val, par->mmio.vbase + addr);
276}
277
278static inline u8 vga_in8(int addr, struct savagefb_par *par)
279{
280 return savage_in8(0x8000 + addr, par);
281}
282
283static inline u16 vga_in16(int addr, struct savagefb_par *par)
284{
285 return savage_in16(0x8000 + addr, par);
286}
287
288static inline u8 vga_in32(int addr, struct savagefb_par *par)
289{
290 return savage_in32(0x8000 + addr, par);
291}
292
293static inline void vga_out8(int addr, u8 val, struct savagefb_par *par)
294{
295 savage_out8(0x8000 + addr, val, par);
296}
297
298static inline void vga_out16(int addr, u16 val, struct savagefb_par *par)
299{
300 savage_out16(0x8000 + addr, val, par);
301}
302
303static inline void vga_out32(int addr, u32 val, struct savagefb_par *par)
304{
305 savage_out32(0x8000 + addr, val, par);
306}
247 307
248#define vga_in8(addr) (inb (addr)) 308static inline u8 VGArCR (u8 index, struct savagefb_par *par)
249#define vga_in16(addr) (inw (addr)) 309{
250#define vga_in32(addr) (inl (addr)) 310 vga_out8(0x3d4, index, par);
311 return vga_in8(0x3d5, par);
312}
313
314static inline u8 VGArGR (u8 index, struct savagefb_par *par)
315{
316 vga_out8(0x3ce, index, par);
317 return vga_in8(0x3cf, par);
318}
319
320static inline u8 VGArSEQ (u8 index, struct savagefb_par *par)
321{
322 vga_out8(0x3c4, index, par);
323 return vga_in8(0x3c5, par);
324}
251 325
252#define vga_out8(addr,val) (outb ((val), (addr))) 326static inline void VGAwCR(u8 index, u8 val, struct savagefb_par *par)
253#define vga_out16(addr,val) (outw ((val), (addr))) 327{
254#define vga_out32(addr,val) (outl ((val), (addr))) 328 vga_out8(0x3d4, index, par);
329 vga_out8(0x3d5, val, par);
330}
255 331
256#define savage_in16(addr) readw(par->mmio.vbase + (addr)) 332static inline void VGAwGR(u8 index, u8 val, struct savagefb_par *par)
257#define savage_in32(addr) readl(par->mmio.vbase + (addr)) 333{
334 vga_out8(0x3ce, index, par);
335 vga_out8(0x3cf, val, par);
336}
258 337
259#define savage_out16(addr,val) writew((val), par->mmio.vbase + (addr)) 338static inline void VGAwSEQ(u8 index, u8 val, struct savagefb_par *par)
260#define savage_out32(addr,val) writel((val), par->mmio.vbase + (addr)) 339{
340 vga_out8(0x3c4, index, par);
341 vga_out8 (0x3c5, val, par);
342}
261 343
262static inline u8 VGArCR (u8 index) 344static inline void VGAenablePalette(struct savagefb_par *par)
263{ 345{
264 outb (index, 0x3d4); 346 u8 tmp;
265 return inb (0x3d5); 347
348 tmp = vga_in8(0x3da, par);
349 vga_out8(0x3c0, 0x00, par);
350 par->paletteEnabled = 1;
266} 351}
267 352
268static inline u8 VGArGR (u8 index) 353static inline void VGAdisablePalette(struct savagefb_par *par)
269{ 354{
270 outb (index, 0x3ce); 355 u8 tmp;
271 return inb (0x3cf); 356
357 tmp = vga_in8(0x3da, par);
358 vga_out8(0x3c0, 0x20, par);
359 par->paletteEnabled = 0;
272} 360}
273 361
274static inline u8 VGArSEQ (u8 index) 362static inline void VGAwATTR(u8 index, u8 value, struct savagefb_par *par)
275{ 363{
276 outb (index, 0x3c4); 364 u8 tmp;
277 return inb (0x3c5); 365
366 if (par->paletteEnabled)
367 index &= ~0x20;
368 else
369 index |= 0x20;
370
371 tmp = vga_in8(0x3da, par);
372 vga_out8(0x3c0, index, par);
373 vga_out8 (0x3c0, value, par);
278} 374}
279 375
280#define VGAwCR(index, val) \ 376static inline void VGAwMISC(u8 value, struct savagefb_par *par)
281do { \ 377{
282 vga_out8 (0x3d4, index); \ 378 vga_out8(0x3c2, value, par);
283 vga_out8 (0x3d5, val); \ 379}
284} while (0)
285
286#define VGAwGR(index, val) \
287do { \
288 vga_out8 (0x3ce, index); \
289 vga_out8 (0x3cf, val); \
290} while (0)
291
292#define VGAwSEQ(index, val) \
293do { \
294 vga_out8 (0x3c4, index); \
295 vga_out8 (0x3c5, val); \
296} while (0)
297
298#define VGAenablePalette() \
299do { \
300 u8 tmp; \
301 \
302 tmp = vga_in8 (0x3da); \
303 vga_out8 (0x3c0, 0x00); \
304 paletteEnabled = 1; \
305} while (0)
306
307#define VGAdisablePalette() \
308do { \
309 u8 tmp; \
310 \
311 tmp = vga_in8 (0x3da); \
312 vga_out8 (0x3c0, 0x20); \
313 paletteEnabled = 0; \
314} while (0)
315
316#define VGAwATTR(index, value) \
317do { \
318 u8 tmp; \
319 \
320 if (paletteEnabled) \
321 index &= ~0x20; \
322 else \
323 index |= 0x20; \
324 \
325 tmp = vga_in8 (0x3da); \
326 vga_out8 (0x3c0, index); \
327 vga_out8 (0x3c0, value); \
328} while (0)
329
330#define VGAwMISC(value) \
331do { \
332 vga_out8 (0x3c2, value); \
333} while (0)
334 380
335#ifndef CONFIG_FB_SAVAGE_ACCEL 381#ifndef CONFIG_FB_SAVAGE_ACCEL
336#define savagefb_set_clip(x) 382#define savagefb_set_clip(x)
337#endif 383#endif
338 384
339#define VerticalRetraceWait() \ 385static inline void VerticalRetraceWait(struct savagefb_par *par)
340{ \ 386{
341 vga_out8 (0x3d4, 0x17); \ 387 vga_out8(0x3d4, 0x17, par);
342 if (vga_in8 (0x3d5) & 0x80) { \ 388 if (vga_in8(0x3d5, par) & 0x80) {
343 while ((vga_in8(0x3da) & 0x08) == 0x08) ; \ 389 while ((vga_in8(0x3da, par) & 0x08) == 0x08);
344 while ((vga_in8(0x3da) & 0x08) == 0x00) ; \ 390 while ((vga_in8(0x3da, par) & 0x08) == 0x00);
345 } \ 391 }
346} 392}
347 393
348extern int savagefb_probe_i2c_connector(struct fb_info *info, 394extern int savagefb_probe_i2c_connector(struct fb_info *info,
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 7c285455c924..09e2f2841901 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -74,7 +74,6 @@
74 74
75 75
76static char *mode_option __initdata = NULL; 76static char *mode_option __initdata = NULL;
77static int paletteEnabled = 0;
78 77
79#ifdef MODULE 78#ifdef MODULE
80 79
@@ -90,9 +89,9 @@ MODULE_DESCRIPTION("FBDev driver for S3 Savage PCI/AGP Chips");
90static void vgaHWSeqReset (struct savagefb_par *par, int start) 89static void vgaHWSeqReset (struct savagefb_par *par, int start)
91{ 90{
92 if (start) 91 if (start)
93 VGAwSEQ (0x00, 0x01); /* Synchronous Reset */ 92 VGAwSEQ (0x00, 0x01, par); /* Synchronous Reset */
94 else 93 else
95 VGAwSEQ (0x00, 0x03); /* End Reset */ 94 VGAwSEQ (0x00, 0x03, par); /* End Reset */
96} 95}
97 96
98static void vgaHWProtect (struct savagefb_par *par, int on) 97static void vgaHWProtect (struct savagefb_par *par, int on)
@@ -103,23 +102,23 @@ static void vgaHWProtect (struct savagefb_par *par, int on)
103 /* 102 /*
104 * Turn off screen and disable sequencer. 103 * Turn off screen and disable sequencer.
105 */ 104 */
106 tmp = VGArSEQ (0x01); 105 tmp = VGArSEQ (0x01, par);
107 106
108 vgaHWSeqReset (par, 1); /* start synchronous reset */ 107 vgaHWSeqReset (par, 1); /* start synchronous reset */
109 VGAwSEQ (0x01, tmp | 0x20); /* disable the display */ 108 VGAwSEQ (0x01, tmp | 0x20, par);/* disable the display */
110 109
111 VGAenablePalette(); 110 VGAenablePalette(par);
112 } else { 111 } else {
113 /* 112 /*
114 * Reenable sequencer, then turn on screen. 113 * Reenable sequencer, then turn on screen.
115 */ 114 */
116 115
117 tmp = VGArSEQ (0x01); 116 tmp = VGArSEQ (0x01, par);
118 117
119 VGAwSEQ (0x01, tmp & ~0x20); /* reenable display */ 118 VGAwSEQ (0x01, tmp & ~0x20, par);/* reenable display */
120 vgaHWSeqReset (par, 0); /* clear synchronous reset */ 119 vgaHWSeqReset (par, 0); /* clear synchronous reset */
121 120
122 VGAdisablePalette(); 121 VGAdisablePalette(par);
123 } 122 }
124} 123}
125 124
@@ -127,27 +126,27 @@ static void vgaHWRestore (struct savagefb_par *par)
127{ 126{
128 int i; 127 int i;
129 128
130 VGAwMISC (par->MiscOutReg); 129 VGAwMISC (par->MiscOutReg, par);
131 130
132 for (i = 1; i < 5; i++) 131 for (i = 1; i < 5; i++)
133 VGAwSEQ (i, par->Sequencer[i]); 132 VGAwSEQ (i, par->Sequencer[i], par);
134 133
135 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or 134 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or
136 CRTC[17] */ 135 CRTC[17] */
137 VGAwCR (17, par->CRTC[17] & ~0x80); 136 VGAwCR (17, par->CRTC[17] & ~0x80, par);
138 137
139 for (i = 0; i < 25; i++) 138 for (i = 0; i < 25; i++)
140 VGAwCR (i, par->CRTC[i]); 139 VGAwCR (i, par->CRTC[i], par);
141 140
142 for (i = 0; i < 9; i++) 141 for (i = 0; i < 9; i++)
143 VGAwGR (i, par->Graphics[i]); 142 VGAwGR (i, par->Graphics[i], par);
144 143
145 VGAenablePalette(); 144 VGAenablePalette(par);
146 145
147 for (i = 0; i < 21; i++) 146 for (i = 0; i < 21; i++)
148 VGAwATTR (i, par->Attribute[i]); 147 VGAwATTR (i, par->Attribute[i], par);
149 148
150 VGAdisablePalette(); 149 VGAdisablePalette(par);
151} 150}
152 151
153static void vgaHWInit (struct fb_var_screeninfo *var, 152static void vgaHWInit (struct fb_var_screeninfo *var,
@@ -267,7 +266,7 @@ savage3D_waitfifo(struct savagefb_par *par, int space)
267{ 266{
268 int slots = MAXFIFO - space; 267 int slots = MAXFIFO - space;
269 268
270 while ((savage_in32(0x48C00) & 0x0000ffff) > slots); 269 while ((savage_in32(0x48C00, par) & 0x0000ffff) > slots);
271} 270}
272 271
273static void 272static void
@@ -275,7 +274,7 @@ savage4_waitfifo(struct savagefb_par *par, int space)
275{ 274{
276 int slots = MAXFIFO - space; 275 int slots = MAXFIFO - space;
277 276
278 while ((savage_in32(0x48C60) & 0x001fffff) > slots); 277 while ((savage_in32(0x48C60, par) & 0x001fffff) > slots);
279} 278}
280 279
281static void 280static void
@@ -283,26 +282,26 @@ savage2000_waitfifo(struct savagefb_par *par, int space)
283{ 282{
284 int slots = MAXFIFO - space; 283 int slots = MAXFIFO - space;
285 284
286 while ((savage_in32(0x48C60) & 0x0000ffff) > slots); 285 while ((savage_in32(0x48C60, par) & 0x0000ffff) > slots);
287} 286}
288 287
289/* Wait for idle accelerator */ 288/* Wait for idle accelerator */
290static void 289static void
291savage3D_waitidle(struct savagefb_par *par) 290savage3D_waitidle(struct savagefb_par *par)
292{ 291{
293 while ((savage_in32(0x48C00) & 0x0008ffff) != 0x80000); 292 while ((savage_in32(0x48C00, par) & 0x0008ffff) != 0x80000);
294} 293}
295 294
296static void 295static void
297savage4_waitidle(struct savagefb_par *par) 296savage4_waitidle(struct savagefb_par *par)
298{ 297{
299 while ((savage_in32(0x48C60) & 0x00a00000) != 0x00a00000); 298 while ((savage_in32(0x48C60, par) & 0x00a00000) != 0x00a00000);
300} 299}
301 300
302static void 301static void
303savage2000_waitidle(struct savagefb_par *par) 302savage2000_waitidle(struct savagefb_par *par)
304{ 303{
305 while ((savage_in32(0x48C60) & 0x009fffff)); 304 while ((savage_in32(0x48C60, par) & 0x009fffff));
306} 305}
307 306
308 307
@@ -319,59 +318,64 @@ SavageSetup2DEngine (struct savagefb_par *par)
319 case S3_SAVAGE3D: 318 case S3_SAVAGE3D:
320 case S3_SAVAGE_MX: 319 case S3_SAVAGE_MX:
321 /* Disable BCI */ 320 /* Disable BCI */
322 savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0); 321 savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
323 /* Setup BCI command overflow buffer */ 322 /* Setup BCI command overflow buffer */
324 savage_out32(0x48C14, (par->cob_offset >> 11) | (par->cob_index << 29)); 323 savage_out32(0x48C14,
324 (par->cob_offset >> 11) | (par->cob_index << 29),
325 par);
325 /* Program shadow status update. */ 326 /* Program shadow status update. */
326 savage_out32(0x48C10, 0x78207220); 327 savage_out32(0x48C10, 0x78207220, par);
327 savage_out32(0x48C0C, 0); 328 savage_out32(0x48C0C, 0, par);
328 /* Enable BCI and command overflow buffer */ 329 /* Enable BCI and command overflow buffer */
329 savage_out32(0x48C18, savage_in32(0x48C18) | 0x0C); 330 savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x0C, par);
330 break; 331 break;
331 case S3_SAVAGE4: 332 case S3_SAVAGE4:
332 case S3_PROSAVAGE: 333 case S3_PROSAVAGE:
333 case S3_SUPERSAVAGE: 334 case S3_SUPERSAVAGE:
334 /* Disable BCI */ 335 /* Disable BCI */
335 savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0); 336 savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
336 /* Program shadow status update */ 337 /* Program shadow status update */
337 savage_out32(0x48C10, 0x00700040); 338 savage_out32(0x48C10, 0x00700040, par);
338 savage_out32(0x48C0C, 0); 339 savage_out32(0x48C0C, 0, par);
339 /* Enable BCI without the COB */ 340 /* Enable BCI without the COB */
340 savage_out32(0x48C18, savage_in32(0x48C18) | 0x08); 341 savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x08, par);
341 break; 342 break;
342 case S3_SAVAGE2000: 343 case S3_SAVAGE2000:
343 /* Disable BCI */ 344 /* Disable BCI */
344 savage_out32(0x48C18, 0); 345 savage_out32(0x48C18, 0, par);
345 /* Setup BCI command overflow buffer */ 346 /* Setup BCI command overflow buffer */
346 savage_out32(0x48C18, (par->cob_offset >> 7) | (par->cob_index)); 347 savage_out32(0x48C18,
348 (par->cob_offset >> 7) | (par->cob_index),
349 par);
347 /* Disable shadow status update */ 350 /* Disable shadow status update */
348 savage_out32(0x48A30, 0); 351 savage_out32(0x48A30, 0, par);
349 /* Enable BCI and command overflow buffer */ 352 /* Enable BCI and command overflow buffer */
350 savage_out32(0x48C18, savage_in32(0x48C18) | 0x00280000 ); 353 savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x00280000,
354 par);
351 break; 355 break;
352 default: 356 default:
353 break; 357 break;
354 } 358 }
355 /* Turn on 16-bit register access. */ 359 /* Turn on 16-bit register access. */
356 vga_out8(0x3d4, 0x31); 360 vga_out8(0x3d4, 0x31, par);
357 vga_out8(0x3d5, 0x0c); 361 vga_out8(0x3d5, 0x0c, par);
358 362
359 /* Set stride to use GBD. */ 363 /* Set stride to use GBD. */
360 vga_out8 (0x3d4, 0x50); 364 vga_out8 (0x3d4, 0x50, par);
361 vga_out8 (0x3d5, vga_in8 (0x3d5 ) | 0xC1); 365 vga_out8 (0x3d5, vga_in8(0x3d5, par) | 0xC1, par);
362 366
363 /* Enable 2D engine. */ 367 /* Enable 2D engine. */
364 vga_out8 (0x3d4, 0x40 ); 368 vga_out8 (0x3d4, 0x40, par);
365 vga_out8 (0x3d5, 0x01 ); 369 vga_out8 (0x3d5, 0x01, par);
366 370
367 savage_out32 (MONO_PAT_0, ~0); 371 savage_out32 (MONO_PAT_0, ~0, par);
368 savage_out32 (MONO_PAT_1, ~0); 372 savage_out32 (MONO_PAT_1, ~0, par);
369 373
370 /* Setup plane masks */ 374 /* Setup plane masks */
371 savage_out32 (0x8128, ~0 ); /* enable all write planes */ 375 savage_out32 (0x8128, ~0, par); /* enable all write planes */
372 savage_out32 (0x812C, ~0 ); /* enable all read planes */ 376 savage_out32 (0x812C, ~0, par); /* enable all read planes */
373 savage_out16 (0x8134, 0x27 ); 377 savage_out16 (0x8134, 0x27, par);
374 savage_out16 (0x8136, 0x07 ); 378 savage_out16 (0x8136, 0x07, par);
375 379
376 /* Now set the GBD */ 380 /* Now set the GBD */
377 par->bci_ptr = 0; 381 par->bci_ptr = 0;
@@ -489,8 +493,8 @@ static void SavagePrintRegs(void)
489 for( i = 0; i < 0x70; i++ ) { 493 for( i = 0; i < 0x70; i++ ) {
490 if( !(i % 16) ) 494 if( !(i % 16) )
491 printk(KERN_DEBUG "\nSR%xx ", i >> 4 ); 495 printk(KERN_DEBUG "\nSR%xx ", i >> 4 );
492 vga_out8( 0x3c4, i ); 496 vga_out8( 0x3c4, i, par);
493 printk(KERN_DEBUG " %02x", vga_in8(0x3c5) ); 497 printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par) );
494 } 498 }
495 499
496 printk(KERN_DEBUG "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC " 500 printk(KERN_DEBUG "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC "
@@ -499,8 +503,8 @@ static void SavagePrintRegs(void)
499 for( i = 0; i < 0xB7; i++ ) { 503 for( i = 0; i < 0xB7; i++ ) {
500 if( !(i % 16) ) 504 if( !(i % 16) )
501 printk(KERN_DEBUG "\nCR%xx ", i >> 4 ); 505 printk(KERN_DEBUG "\nCR%xx ", i >> 4 );
502 vga_out8( vgaCRIndex, i ); 506 vga_out8( vgaCRIndex, i, par);
503 printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg) ); 507 printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par) );
504 } 508 }
505 509
506 printk(KERN_DEBUG "\n\n"); 510 printk(KERN_DEBUG "\n\n");
@@ -513,152 +517,152 @@ static void savage_get_default_par(struct savagefb_par *par)
513{ 517{
514 unsigned char cr3a, cr53, cr66; 518 unsigned char cr3a, cr53, cr66;
515 519
516 vga_out16 (0x3d4, 0x4838); 520 vga_out16 (0x3d4, 0x4838, par);
517 vga_out16 (0x3d4, 0xa039); 521 vga_out16 (0x3d4, 0xa039, par);
518 vga_out16 (0x3c4, 0x0608); 522 vga_out16 (0x3c4, 0x0608, par);
519 523
520 vga_out8 (0x3d4, 0x66); 524 vga_out8 (0x3d4, 0x66, par);
521 cr66 = vga_in8 (0x3d5); 525 cr66 = vga_in8 (0x3d5, par);
522 vga_out8 (0x3d5, cr66 | 0x80); 526 vga_out8 (0x3d5, cr66 | 0x80, par);
523 vga_out8 (0x3d4, 0x3a); 527 vga_out8 (0x3d4, 0x3a, par);
524 cr3a = vga_in8 (0x3d5); 528 cr3a = vga_in8 (0x3d5, par);
525 vga_out8 (0x3d5, cr3a | 0x80); 529 vga_out8 (0x3d5, cr3a | 0x80, par);
526 vga_out8 (0x3d4, 0x53); 530 vga_out8 (0x3d4, 0x53, par);
527 cr53 = vga_in8 (0x3d5); 531 cr53 = vga_in8 (0x3d5, par);
528 vga_out8 (0x3d5, cr53 & 0x7f); 532 vga_out8 (0x3d5, cr53 & 0x7f, par);
529 533
530 vga_out8 (0x3d4, 0x66); 534 vga_out8 (0x3d4, 0x66, par);
531 vga_out8 (0x3d5, cr66); 535 vga_out8 (0x3d5, cr66, par);
532 vga_out8 (0x3d4, 0x3a); 536 vga_out8 (0x3d4, 0x3a, par);
533 vga_out8 (0x3d5, cr3a); 537 vga_out8 (0x3d5, cr3a, par);
534 538
535 vga_out8 (0x3d4, 0x66); 539 vga_out8 (0x3d4, 0x66, par);
536 vga_out8 (0x3d5, cr66); 540 vga_out8 (0x3d5, cr66, par);
537 vga_out8 (0x3d4, 0x3a); 541 vga_out8 (0x3d4, 0x3a, par);
538 vga_out8 (0x3d5, cr3a); 542 vga_out8 (0x3d5, cr3a, par);
539 543
540 /* unlock extended seq regs */ 544 /* unlock extended seq regs */
541 vga_out8 (0x3c4, 0x08); 545 vga_out8 (0x3c4, 0x08, par);
542 par->SR08 = vga_in8 (0x3c5); 546 par->SR08 = vga_in8 (0x3c5, par);
543 vga_out8 (0x3c5, 0x06); 547 vga_out8 (0x3c5, 0x06, par);
544 548
545 /* now save all the extended regs we need */ 549 /* now save all the extended regs we need */
546 vga_out8 (0x3d4, 0x31); 550 vga_out8 (0x3d4, 0x31, par);
547 par->CR31 = vga_in8 (0x3d5); 551 par->CR31 = vga_in8 (0x3d5, par);
548 vga_out8 (0x3d4, 0x32); 552 vga_out8 (0x3d4, 0x32, par);
549 par->CR32 = vga_in8 (0x3d5); 553 par->CR32 = vga_in8 (0x3d5, par);
550 vga_out8 (0x3d4, 0x34); 554 vga_out8 (0x3d4, 0x34, par);
551 par->CR34 = vga_in8 (0x3d5); 555 par->CR34 = vga_in8 (0x3d5, par);
552 vga_out8 (0x3d4, 0x36); 556 vga_out8 (0x3d4, 0x36, par);
553 par->CR36 = vga_in8 (0x3d5); 557 par->CR36 = vga_in8 (0x3d5, par);
554 vga_out8 (0x3d4, 0x3a); 558 vga_out8 (0x3d4, 0x3a, par);
555 par->CR3A = vga_in8 (0x3d5); 559 par->CR3A = vga_in8 (0x3d5, par);
556 vga_out8 (0x3d4, 0x40); 560 vga_out8 (0x3d4, 0x40, par);
557 par->CR40 = vga_in8 (0x3d5); 561 par->CR40 = vga_in8 (0x3d5, par);
558 vga_out8 (0x3d4, 0x42); 562 vga_out8 (0x3d4, 0x42, par);
559 par->CR42 = vga_in8 (0x3d5); 563 par->CR42 = vga_in8 (0x3d5, par);
560 vga_out8 (0x3d4, 0x45); 564 vga_out8 (0x3d4, 0x45, par);
561 par->CR45 = vga_in8 (0x3d5); 565 par->CR45 = vga_in8 (0x3d5, par);
562 vga_out8 (0x3d4, 0x50); 566 vga_out8 (0x3d4, 0x50, par);
563 par->CR50 = vga_in8 (0x3d5); 567 par->CR50 = vga_in8 (0x3d5, par);
564 vga_out8 (0x3d4, 0x51); 568 vga_out8 (0x3d4, 0x51, par);
565 par->CR51 = vga_in8 (0x3d5); 569 par->CR51 = vga_in8 (0x3d5, par);
566 vga_out8 (0x3d4, 0x53); 570 vga_out8 (0x3d4, 0x53, par);
567 par->CR53 = vga_in8 (0x3d5); 571 par->CR53 = vga_in8 (0x3d5, par);
568 vga_out8 (0x3d4, 0x58); 572 vga_out8 (0x3d4, 0x58, par);
569 par->CR58 = vga_in8 (0x3d5); 573 par->CR58 = vga_in8 (0x3d5, par);
570 vga_out8 (0x3d4, 0x60); 574 vga_out8 (0x3d4, 0x60, par);
571 par->CR60 = vga_in8 (0x3d5); 575 par->CR60 = vga_in8 (0x3d5, par);
572 vga_out8 (0x3d4, 0x66); 576 vga_out8 (0x3d4, 0x66, par);
573 par->CR66 = vga_in8 (0x3d5); 577 par->CR66 = vga_in8 (0x3d5, par);
574 vga_out8 (0x3d4, 0x67); 578 vga_out8 (0x3d4, 0x67, par);
575 par->CR67 = vga_in8 (0x3d5); 579 par->CR67 = vga_in8 (0x3d5, par);
576 vga_out8 (0x3d4, 0x68); 580 vga_out8 (0x3d4, 0x68, par);
577 par->CR68 = vga_in8 (0x3d5); 581 par->CR68 = vga_in8 (0x3d5, par);
578 vga_out8 (0x3d4, 0x69); 582 vga_out8 (0x3d4, 0x69, par);
579 par->CR69 = vga_in8 (0x3d5); 583 par->CR69 = vga_in8 (0x3d5, par);
580 vga_out8 (0x3d4, 0x6f); 584 vga_out8 (0x3d4, 0x6f, par);
581 par->CR6F = vga_in8 (0x3d5); 585 par->CR6F = vga_in8 (0x3d5, par);
582 586
583 vga_out8 (0x3d4, 0x33); 587 vga_out8 (0x3d4, 0x33, par);
584 par->CR33 = vga_in8 (0x3d5); 588 par->CR33 = vga_in8 (0x3d5, par);
585 vga_out8 (0x3d4, 0x86); 589 vga_out8 (0x3d4, 0x86, par);
586 par->CR86 = vga_in8 (0x3d5); 590 par->CR86 = vga_in8 (0x3d5, par);
587 vga_out8 (0x3d4, 0x88); 591 vga_out8 (0x3d4, 0x88, par);
588 par->CR88 = vga_in8 (0x3d5); 592 par->CR88 = vga_in8 (0x3d5, par);
589 vga_out8 (0x3d4, 0x90); 593 vga_out8 (0x3d4, 0x90, par);
590 par->CR90 = vga_in8 (0x3d5); 594 par->CR90 = vga_in8 (0x3d5, par);
591 vga_out8 (0x3d4, 0x91); 595 vga_out8 (0x3d4, 0x91, par);
592 par->CR91 = vga_in8 (0x3d5); 596 par->CR91 = vga_in8 (0x3d5, par);
593 vga_out8 (0x3d4, 0xb0); 597 vga_out8 (0x3d4, 0xb0, par);
594 par->CRB0 = vga_in8 (0x3d5) | 0x80; 598 par->CRB0 = vga_in8 (0x3d5, par) | 0x80;
595 599
596 /* extended mode timing regs */ 600 /* extended mode timing regs */
597 vga_out8 (0x3d4, 0x3b); 601 vga_out8 (0x3d4, 0x3b, par);
598 par->CR3B = vga_in8 (0x3d5); 602 par->CR3B = vga_in8 (0x3d5, par);
599 vga_out8 (0x3d4, 0x3c); 603 vga_out8 (0x3d4, 0x3c, par);
600 par->CR3C = vga_in8 (0x3d5); 604 par->CR3C = vga_in8 (0x3d5, par);
601 vga_out8 (0x3d4, 0x43); 605 vga_out8 (0x3d4, 0x43, par);
602 par->CR43 = vga_in8 (0x3d5); 606 par->CR43 = vga_in8 (0x3d5, par);
603 vga_out8 (0x3d4, 0x5d); 607 vga_out8 (0x3d4, 0x5d, par);
604 par->CR5D = vga_in8 (0x3d5); 608 par->CR5D = vga_in8 (0x3d5, par);
605 vga_out8 (0x3d4, 0x5e); 609 vga_out8 (0x3d4, 0x5e, par);
606 par->CR5E = vga_in8 (0x3d5); 610 par->CR5E = vga_in8 (0x3d5, par);
607 vga_out8 (0x3d4, 0x65); 611 vga_out8 (0x3d4, 0x65, par);
608 par->CR65 = vga_in8 (0x3d5); 612 par->CR65 = vga_in8 (0x3d5, par);
609 613
610 /* save seq extended regs for DCLK PLL programming */ 614 /* save seq extended regs for DCLK PLL programming */
611 vga_out8 (0x3c4, 0x0e); 615 vga_out8 (0x3c4, 0x0e, par);
612 par->SR0E = vga_in8 (0x3c5); 616 par->SR0E = vga_in8 (0x3c5, par);
613 vga_out8 (0x3c4, 0x0f); 617 vga_out8 (0x3c4, 0x0f, par);
614 par->SR0F = vga_in8 (0x3c5); 618 par->SR0F = vga_in8 (0x3c5, par);
615 vga_out8 (0x3c4, 0x10); 619 vga_out8 (0x3c4, 0x10, par);
616 par->SR10 = vga_in8 (0x3c5); 620 par->SR10 = vga_in8 (0x3c5, par);
617 vga_out8 (0x3c4, 0x11); 621 vga_out8 (0x3c4, 0x11, par);
618 par->SR11 = vga_in8 (0x3c5); 622 par->SR11 = vga_in8 (0x3c5, par);
619 vga_out8 (0x3c4, 0x12); 623 vga_out8 (0x3c4, 0x12, par);
620 par->SR12 = vga_in8 (0x3c5); 624 par->SR12 = vga_in8 (0x3c5, par);
621 vga_out8 (0x3c4, 0x13); 625 vga_out8 (0x3c4, 0x13, par);
622 par->SR13 = vga_in8 (0x3c5); 626 par->SR13 = vga_in8 (0x3c5, par);
623 vga_out8 (0x3c4, 0x29); 627 vga_out8 (0x3c4, 0x29, par);
624 par->SR29 = vga_in8 (0x3c5); 628 par->SR29 = vga_in8 (0x3c5, par);
625 629
626 vga_out8 (0x3c4, 0x15); 630 vga_out8 (0x3c4, 0x15, par);
627 par->SR15 = vga_in8 (0x3c5); 631 par->SR15 = vga_in8 (0x3c5, par);
628 vga_out8 (0x3c4, 0x30); 632 vga_out8 (0x3c4, 0x30, par);
629 par->SR30 = vga_in8 (0x3c5); 633 par->SR30 = vga_in8 (0x3c5, par);
630 vga_out8 (0x3c4, 0x18); 634 vga_out8 (0x3c4, 0x18, par);
631 par->SR18 = vga_in8 (0x3c5); 635 par->SR18 = vga_in8 (0x3c5, par);
632 636
633 /* Save flat panel expansion regsters. */ 637 /* Save flat panel expansion regsters. */
634 if (par->chip == S3_SAVAGE_MX) { 638 if (par->chip == S3_SAVAGE_MX) {
635 int i; 639 int i;
636 640
637 for (i = 0; i < 8; i++) { 641 for (i = 0; i < 8; i++) {
638 vga_out8 (0x3c4, 0x54+i); 642 vga_out8 (0x3c4, 0x54+i, par);
639 par->SR54[i] = vga_in8 (0x3c5); 643 par->SR54[i] = vga_in8 (0x3c5, par);
640 } 644 }
641 } 645 }
642 646
643 vga_out8 (0x3d4, 0x66); 647 vga_out8 (0x3d4, 0x66, par);
644 cr66 = vga_in8 (0x3d5); 648 cr66 = vga_in8 (0x3d5, par);
645 vga_out8 (0x3d5, cr66 | 0x80); 649 vga_out8 (0x3d5, cr66 | 0x80, par);
646 vga_out8 (0x3d4, 0x3a); 650 vga_out8 (0x3d4, 0x3a, par);
647 cr3a = vga_in8 (0x3d5); 651 cr3a = vga_in8 (0x3d5, par);
648 vga_out8 (0x3d5, cr3a | 0x80); 652 vga_out8 (0x3d5, cr3a | 0x80, par);
649 653
650 /* now save MIU regs */ 654 /* now save MIU regs */
651 if (par->chip != S3_SAVAGE_MX) { 655 if (par->chip != S3_SAVAGE_MX) {
652 par->MMPR0 = savage_in32(FIFO_CONTROL_REG); 656 par->MMPR0 = savage_in32(FIFO_CONTROL_REG, par);
653 par->MMPR1 = savage_in32(MIU_CONTROL_REG); 657 par->MMPR1 = savage_in32(MIU_CONTROL_REG, par);
654 par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG); 658 par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par);
655 par->MMPR3 = savage_in32(MISC_TIMEOUT_REG); 659 par->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par);
656 } 660 }
657 661
658 vga_out8 (0x3d4, 0x3a); 662 vga_out8 (0x3d4, 0x3a, par);
659 vga_out8 (0x3d5, cr3a); 663 vga_out8 (0x3d5, cr3a, par);
660 vga_out8 (0x3d4, 0x66); 664 vga_out8 (0x3d4, 0x66, par);
661 vga_out8 (0x3d5, cr66); 665 vga_out8 (0x3d5, cr66, par);
662} 666}
663 667
664static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb) 668static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
@@ -868,8 +872,8 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
868 * match. Fall back to traditional register-crunching. 872 * match. Fall back to traditional register-crunching.
869 */ 873 */
870 874
871 vga_out8 (0x3d4, 0x3a); 875 vga_out8 (0x3d4, 0x3a, par);
872 tmp = vga_in8 (0x3d5); 876 tmp = vga_in8 (0x3d5, par);
873 if (1 /*FIXME:psav->pci_burst*/) 877 if (1 /*FIXME:psav->pci_burst*/)
874 par->CR3A = (tmp & 0x7f) | 0x15; 878 par->CR3A = (tmp & 0x7f) | 0x15;
875 else 879 else
@@ -879,16 +883,16 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
879 par->CR31 = 0x8c; 883 par->CR31 = 0x8c;
880 par->CR66 = 0x89; 884 par->CR66 = 0x89;
881 885
882 vga_out8 (0x3d4, 0x58); 886 vga_out8 (0x3d4, 0x58, par);
883 par->CR58 = vga_in8 (0x3d5) & 0x80; 887 par->CR58 = vga_in8 (0x3d5, par) & 0x80;
884 par->CR58 |= 0x13; 888 par->CR58 |= 0x13;
885 889
886 par->SR15 = 0x03 | 0x80; 890 par->SR15 = 0x03 | 0x80;
887 par->SR18 = 0x00; 891 par->SR18 = 0x00;
888 par->CR43 = par->CR45 = par->CR65 = 0x00; 892 par->CR43 = par->CR45 = par->CR65 = 0x00;
889 893
890 vga_out8 (0x3d4, 0x40); 894 vga_out8 (0x3d4, 0x40, par);
891 par->CR40 = vga_in8 (0x3d5) & ~0x01; 895 par->CR40 = vga_in8 (0x3d5, par) & ~0x01;
892 896
893 par->MMPR0 = 0x010400; 897 par->MMPR0 = 0x010400;
894 par->MMPR1 = 0x00; 898 par->MMPR1 = 0x00;
@@ -992,19 +996,19 @@ static int savagefb_decode_var (struct fb_var_screeninfo *var,
992 996
993 par->CR67 |= 1; 997 par->CR67 |= 1;
994 998
995 vga_out8(0x3d4, 0x36); 999 vga_out8(0x3d4, 0x36, par);
996 par->CR36 = vga_in8 (0x3d5); 1000 par->CR36 = vga_in8 (0x3d5, par);
997 vga_out8 (0x3d4, 0x68); 1001 vga_out8 (0x3d4, 0x68, par);
998 par->CR68 = vga_in8 (0x3d5); 1002 par->CR68 = vga_in8 (0x3d5, par);
999 par->CR69 = 0; 1003 par->CR69 = 0;
1000 vga_out8 (0x3d4, 0x6f); 1004 vga_out8 (0x3d4, 0x6f, par);
1001 par->CR6F = vga_in8 (0x3d5); 1005 par->CR6F = vga_in8 (0x3d5, par);
1002 vga_out8 (0x3d4, 0x86); 1006 vga_out8 (0x3d4, 0x86, par);
1003 par->CR86 = vga_in8 (0x3d5); 1007 par->CR86 = vga_in8 (0x3d5, par);
1004 vga_out8 (0x3d4, 0x88); 1008 vga_out8 (0x3d4, 0x88, par);
1005 par->CR88 = vga_in8 (0x3d5) | 0x08; 1009 par->CR88 = vga_in8 (0x3d5, par) | 0x08;
1006 vga_out8 (0x3d4, 0xb0); 1010 vga_out8 (0x3d4, 0xb0, par);
1007 par->CRB0 = vga_in8 (0x3d5) | 0x80; 1011 par->CRB0 = vga_in8 (0x3d5, par) | 0x80;
1008 1012
1009 return 0; 1013 return 0;
1010} 1014}
@@ -1033,11 +1037,11 @@ static int savagefb_setcolreg(unsigned regno,
1033 1037
1034 switch (info->var.bits_per_pixel) { 1038 switch (info->var.bits_per_pixel) {
1035 case 8: 1039 case 8:
1036 vga_out8 (0x3c8, regno); 1040 vga_out8 (0x3c8, regno, par);
1037 1041
1038 vga_out8 (0x3c9, red >> 10); 1042 vga_out8 (0x3c9, red >> 10, par);
1039 vga_out8 (0x3c9, green >> 10); 1043 vga_out8 (0x3c9, green >> 10, par);
1040 vga_out8 (0x3c9, blue >> 10); 1044 vga_out8 (0x3c9, blue >> 10, par);
1041 break; 1045 break;
1042 1046
1043 case 16: 1047 case 16:
@@ -1079,11 +1083,11 @@ static void savagefb_set_par_int (struct savagefb_par *par)
1079 1083
1080 par->SavageWaitIdle (par); 1084 par->SavageWaitIdle (par);
1081 1085
1082 vga_out8 (0x3c2, 0x23); 1086 vga_out8 (0x3c2, 0x23, par);
1083 1087
1084 vga_out16 (0x3d4, 0x4838); 1088 vga_out16 (0x3d4, 0x4838, par);
1085 vga_out16 (0x3d4, 0xa539); 1089 vga_out16 (0x3d4, 0xa539, par);
1086 vga_out16 (0x3c4, 0x0608); 1090 vga_out16 (0x3c4, 0x0608, par);
1087 1091
1088 vgaHWProtect (par, 1); 1092 vgaHWProtect (par, 1);
1089 1093
@@ -1094,197 +1098,197 @@ static void savagefb_set_par_int (struct savagefb_par *par)
1094 * switch to mode 3 here seems to eliminate the issue. 1098 * switch to mode 3 here seems to eliminate the issue.
1095 */ 1099 */
1096 1100
1097 VerticalRetraceWait(); 1101 VerticalRetraceWait(par);
1098 vga_out8 (0x3d4, 0x67); 1102 vga_out8 (0x3d4, 0x67, par);
1099 cr67 = vga_in8 (0x3d5); 1103 cr67 = vga_in8 (0x3d5, par);
1100 vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c); /* no STREAMS yet */ 1104 vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */
1101 1105
1102 vga_out8 (0x3d4, 0x23); 1106 vga_out8 (0x3d4, 0x23, par);
1103 vga_out8 (0x3d5, 0x00); 1107 vga_out8 (0x3d5, 0x00, par);
1104 vga_out8 (0x3d4, 0x26); 1108 vga_out8 (0x3d4, 0x26, par);
1105 vga_out8 (0x3d5, 0x00); 1109 vga_out8 (0x3d5, 0x00, par);
1106 1110
1107 /* restore extended regs */ 1111 /* restore extended regs */
1108 vga_out8 (0x3d4, 0x66); 1112 vga_out8 (0x3d4, 0x66, par);
1109 vga_out8 (0x3d5, par->CR66); 1113 vga_out8 (0x3d5, par->CR66, par);
1110 vga_out8 (0x3d4, 0x3a); 1114 vga_out8 (0x3d4, 0x3a, par);
1111 vga_out8 (0x3d5, par->CR3A); 1115 vga_out8 (0x3d5, par->CR3A, par);
1112 vga_out8 (0x3d4, 0x31); 1116 vga_out8 (0x3d4, 0x31, par);
1113 vga_out8 (0x3d5, par->CR31); 1117 vga_out8 (0x3d5, par->CR31, par);
1114 vga_out8 (0x3d4, 0x32); 1118 vga_out8 (0x3d4, 0x32, par);
1115 vga_out8 (0x3d5, par->CR32); 1119 vga_out8 (0x3d5, par->CR32, par);
1116 vga_out8 (0x3d4, 0x58); 1120 vga_out8 (0x3d4, 0x58, par);
1117 vga_out8 (0x3d5, par->CR58); 1121 vga_out8 (0x3d5, par->CR58, par);
1118 vga_out8 (0x3d4, 0x53); 1122 vga_out8 (0x3d4, 0x53, par);
1119 vga_out8 (0x3d5, par->CR53 & 0x7f); 1123 vga_out8 (0x3d5, par->CR53 & 0x7f, par);
1120 1124
1121 vga_out16 (0x3c4, 0x0608); 1125 vga_out16 (0x3c4, 0x0608, par);
1122 1126
1123 /* Restore DCLK registers. */ 1127 /* Restore DCLK registers. */
1124 1128
1125 vga_out8 (0x3c4, 0x0e); 1129 vga_out8 (0x3c4, 0x0e, par);
1126 vga_out8 (0x3c5, par->SR0E); 1130 vga_out8 (0x3c5, par->SR0E, par);
1127 vga_out8 (0x3c4, 0x0f); 1131 vga_out8 (0x3c4, 0x0f, par);
1128 vga_out8 (0x3c5, par->SR0F); 1132 vga_out8 (0x3c5, par->SR0F, par);
1129 vga_out8 (0x3c4, 0x29); 1133 vga_out8 (0x3c4, 0x29, par);
1130 vga_out8 (0x3c5, par->SR29); 1134 vga_out8 (0x3c5, par->SR29, par);
1131 vga_out8 (0x3c4, 0x15); 1135 vga_out8 (0x3c4, 0x15, par);
1132 vga_out8 (0x3c5, par->SR15); 1136 vga_out8 (0x3c5, par->SR15, par);
1133 1137
1134 /* Restore flat panel expansion regsters. */ 1138 /* Restore flat panel expansion regsters. */
1135 if( par->chip == S3_SAVAGE_MX ) { 1139 if( par->chip == S3_SAVAGE_MX ) {
1136 int i; 1140 int i;
1137 1141
1138 for( i = 0; i < 8; i++ ) { 1142 for( i = 0; i < 8; i++ ) {
1139 vga_out8 (0x3c4, 0x54+i); 1143 vga_out8 (0x3c4, 0x54+i, par);
1140 vga_out8 (0x3c5, par->SR54[i]); 1144 vga_out8 (0x3c5, par->SR54[i], par);
1141 } 1145 }
1142 } 1146 }
1143 1147
1144 vgaHWRestore (par); 1148 vgaHWRestore (par);
1145 1149
1146 /* extended mode timing registers */ 1150 /* extended mode timing registers */
1147 vga_out8 (0x3d4, 0x53); 1151 vga_out8 (0x3d4, 0x53, par);
1148 vga_out8 (0x3d5, par->CR53); 1152 vga_out8 (0x3d5, par->CR53, par);
1149 vga_out8 (0x3d4, 0x5d); 1153 vga_out8 (0x3d4, 0x5d, par);
1150 vga_out8 (0x3d5, par->CR5D); 1154 vga_out8 (0x3d5, par->CR5D, par);
1151 vga_out8 (0x3d4, 0x5e); 1155 vga_out8 (0x3d4, 0x5e, par);
1152 vga_out8 (0x3d5, par->CR5E); 1156 vga_out8 (0x3d5, par->CR5E, par);
1153 vga_out8 (0x3d4, 0x3b); 1157 vga_out8 (0x3d4, 0x3b, par);
1154 vga_out8 (0x3d5, par->CR3B); 1158 vga_out8 (0x3d5, par->CR3B, par);
1155 vga_out8 (0x3d4, 0x3c); 1159 vga_out8 (0x3d4, 0x3c, par);
1156 vga_out8 (0x3d5, par->CR3C); 1160 vga_out8 (0x3d5, par->CR3C, par);
1157 vga_out8 (0x3d4, 0x43); 1161 vga_out8 (0x3d4, 0x43, par);
1158 vga_out8 (0x3d5, par->CR43); 1162 vga_out8 (0x3d5, par->CR43, par);
1159 vga_out8 (0x3d4, 0x65); 1163 vga_out8 (0x3d4, 0x65, par);
1160 vga_out8 (0x3d5, par->CR65); 1164 vga_out8 (0x3d5, par->CR65, par);
1161 1165
1162 /* restore the desired video mode with cr67 */ 1166 /* restore the desired video mode with cr67 */
1163 vga_out8 (0x3d4, 0x67); 1167 vga_out8 (0x3d4, 0x67, par);
1164 /* following part not present in X11 driver */ 1168 /* following part not present in X11 driver */
1165 cr67 = vga_in8 (0x3d5) & 0xf; 1169 cr67 = vga_in8 (0x3d5, par) & 0xf;
1166 vga_out8 (0x3d5, 0x50 | cr67); 1170 vga_out8 (0x3d5, 0x50 | cr67, par);
1167 udelay (10000); 1171 udelay (10000);
1168 vga_out8 (0x3d4, 0x67); 1172 vga_out8 (0x3d4, 0x67, par);
1169 /* end of part */ 1173 /* end of part */
1170 vga_out8 (0x3d5, par->CR67 & ~0x0c); 1174 vga_out8 (0x3d5, par->CR67 & ~0x0c, par);
1171 1175
1172 /* other mode timing and extended regs */ 1176 /* other mode timing and extended regs */
1173 vga_out8 (0x3d4, 0x34); 1177 vga_out8 (0x3d4, 0x34, par);
1174 vga_out8 (0x3d5, par->CR34); 1178 vga_out8 (0x3d5, par->CR34, par);
1175 vga_out8 (0x3d4, 0x40); 1179 vga_out8 (0x3d4, 0x40, par);
1176 vga_out8 (0x3d5, par->CR40); 1180 vga_out8 (0x3d5, par->CR40, par);
1177 vga_out8 (0x3d4, 0x42); 1181 vga_out8 (0x3d4, 0x42, par);
1178 vga_out8 (0x3d5, par->CR42); 1182 vga_out8 (0x3d5, par->CR42, par);
1179 vga_out8 (0x3d4, 0x45); 1183 vga_out8 (0x3d4, 0x45, par);
1180 vga_out8 (0x3d5, par->CR45); 1184 vga_out8 (0x3d5, par->CR45, par);
1181 vga_out8 (0x3d4, 0x50); 1185 vga_out8 (0x3d4, 0x50, par);
1182 vga_out8 (0x3d5, par->CR50); 1186 vga_out8 (0x3d5, par->CR50, par);
1183 vga_out8 (0x3d4, 0x51); 1187 vga_out8 (0x3d4, 0x51, par);
1184 vga_out8 (0x3d5, par->CR51); 1188 vga_out8 (0x3d5, par->CR51, par);
1185 1189
1186 /* memory timings */ 1190 /* memory timings */
1187 vga_out8 (0x3d4, 0x36); 1191 vga_out8 (0x3d4, 0x36, par);
1188 vga_out8 (0x3d5, par->CR36); 1192 vga_out8 (0x3d5, par->CR36, par);
1189 vga_out8 (0x3d4, 0x60); 1193 vga_out8 (0x3d4, 0x60, par);
1190 vga_out8 (0x3d5, par->CR60); 1194 vga_out8 (0x3d5, par->CR60, par);
1191 vga_out8 (0x3d4, 0x68); 1195 vga_out8 (0x3d4, 0x68, par);
1192 vga_out8 (0x3d5, par->CR68); 1196 vga_out8 (0x3d5, par->CR68, par);
1193 vga_out8 (0x3d4, 0x69); 1197 vga_out8 (0x3d4, 0x69, par);
1194 vga_out8 (0x3d5, par->CR69); 1198 vga_out8 (0x3d5, par->CR69, par);
1195 vga_out8 (0x3d4, 0x6f); 1199 vga_out8 (0x3d4, 0x6f, par);
1196 vga_out8 (0x3d5, par->CR6F); 1200 vga_out8 (0x3d5, par->CR6F, par);
1197 1201
1198 vga_out8 (0x3d4, 0x33); 1202 vga_out8 (0x3d4, 0x33, par);
1199 vga_out8 (0x3d5, par->CR33); 1203 vga_out8 (0x3d5, par->CR33, par);
1200 vga_out8 (0x3d4, 0x86); 1204 vga_out8 (0x3d4, 0x86, par);
1201 vga_out8 (0x3d5, par->CR86); 1205 vga_out8 (0x3d5, par->CR86, par);
1202 vga_out8 (0x3d4, 0x88); 1206 vga_out8 (0x3d4, 0x88, par);
1203 vga_out8 (0x3d5, par->CR88); 1207 vga_out8 (0x3d5, par->CR88, par);
1204 vga_out8 (0x3d4, 0x90); 1208 vga_out8 (0x3d4, 0x90, par);
1205 vga_out8 (0x3d5, par->CR90); 1209 vga_out8 (0x3d5, par->CR90, par);
1206 vga_out8 (0x3d4, 0x91); 1210 vga_out8 (0x3d4, 0x91, par);
1207 vga_out8 (0x3d5, par->CR91); 1211 vga_out8 (0x3d5, par->CR91, par);
1208 1212
1209 if (par->chip == S3_SAVAGE4) { 1213 if (par->chip == S3_SAVAGE4) {
1210 vga_out8 (0x3d4, 0xb0); 1214 vga_out8 (0x3d4, 0xb0, par);
1211 vga_out8 (0x3d5, par->CRB0); 1215 vga_out8 (0x3d5, par->CRB0, par);
1212 } 1216 }
1213 1217
1214 vga_out8 (0x3d4, 0x32); 1218 vga_out8 (0x3d4, 0x32, par);
1215 vga_out8 (0x3d5, par->CR32); 1219 vga_out8 (0x3d5, par->CR32, par);
1216 1220
1217 /* unlock extended seq regs */ 1221 /* unlock extended seq regs */
1218 vga_out8 (0x3c4, 0x08); 1222 vga_out8 (0x3c4, 0x08, par);
1219 vga_out8 (0x3c5, 0x06); 1223 vga_out8 (0x3c5, 0x06, par);
1220 1224
1221 /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates 1225 /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates
1222 * that we should leave the default SR10 and SR11 values there. 1226 * that we should leave the default SR10 and SR11 values there.
1223 */ 1227 */
1224 if (par->SR10 != 255) { 1228 if (par->SR10 != 255) {
1225 vga_out8 (0x3c4, 0x10); 1229 vga_out8 (0x3c4, 0x10, par);
1226 vga_out8 (0x3c5, par->SR10); 1230 vga_out8 (0x3c5, par->SR10, par);
1227 vga_out8 (0x3c4, 0x11); 1231 vga_out8 (0x3c4, 0x11, par);
1228 vga_out8 (0x3c5, par->SR11); 1232 vga_out8 (0x3c5, par->SR11, par);
1229 } 1233 }
1230 1234
1231 /* restore extended seq regs for dclk */ 1235 /* restore extended seq regs for dclk */
1232 vga_out8 (0x3c4, 0x0e); 1236 vga_out8 (0x3c4, 0x0e, par);
1233 vga_out8 (0x3c5, par->SR0E); 1237 vga_out8 (0x3c5, par->SR0E, par);
1234 vga_out8 (0x3c4, 0x0f); 1238 vga_out8 (0x3c4, 0x0f, par);
1235 vga_out8 (0x3c5, par->SR0F); 1239 vga_out8 (0x3c5, par->SR0F, par);
1236 vga_out8 (0x3c4, 0x12); 1240 vga_out8 (0x3c4, 0x12, par);
1237 vga_out8 (0x3c5, par->SR12); 1241 vga_out8 (0x3c5, par->SR12, par);
1238 vga_out8 (0x3c4, 0x13); 1242 vga_out8 (0x3c4, 0x13, par);
1239 vga_out8 (0x3c5, par->SR13); 1243 vga_out8 (0x3c5, par->SR13, par);
1240 vga_out8 (0x3c4, 0x29); 1244 vga_out8 (0x3c4, 0x29, par);
1241 vga_out8 (0x3c5, par->SR29); 1245 vga_out8 (0x3c5, par->SR29, par);
1242 1246
1243 vga_out8 (0x3c4, 0x18); 1247 vga_out8 (0x3c4, 0x18, par);
1244 vga_out8 (0x3c5, par->SR18); 1248 vga_out8 (0x3c5, par->SR18, par);
1245 1249
1246 /* load new m, n pll values for dclk & mclk */ 1250 /* load new m, n pll values for dclk & mclk */
1247 vga_out8 (0x3c4, 0x15); 1251 vga_out8 (0x3c4, 0x15, par);
1248 tmp = vga_in8 (0x3c5) & ~0x21; 1252 tmp = vga_in8 (0x3c5, par) & ~0x21;
1249 1253
1250 vga_out8 (0x3c5, tmp | 0x03); 1254 vga_out8 (0x3c5, tmp | 0x03, par);
1251 vga_out8 (0x3c5, tmp | 0x23); 1255 vga_out8 (0x3c5, tmp | 0x23, par);
1252 vga_out8 (0x3c5, tmp | 0x03); 1256 vga_out8 (0x3c5, tmp | 0x03, par);
1253 vga_out8 (0x3c5, par->SR15); 1257 vga_out8 (0x3c5, par->SR15, par);
1254 udelay (100); 1258 udelay (100);
1255 1259
1256 vga_out8 (0x3c4, 0x30); 1260 vga_out8 (0x3c4, 0x30, par);
1257 vga_out8 (0x3c5, par->SR30); 1261 vga_out8 (0x3c5, par->SR30, par);
1258 vga_out8 (0x3c4, 0x08); 1262 vga_out8 (0x3c4, 0x08, par);
1259 vga_out8 (0x3c5, par->SR08); 1263 vga_out8 (0x3c5, par->SR08, par);
1260 1264
1261 /* now write out cr67 in full, possibly starting STREAMS */ 1265 /* now write out cr67 in full, possibly starting STREAMS */
1262 VerticalRetraceWait(); 1266 VerticalRetraceWait(par);
1263 vga_out8 (0x3d4, 0x67); 1267 vga_out8 (0x3d4, 0x67, par);
1264 vga_out8 (0x3d5, par->CR67); 1268 vga_out8 (0x3d5, par->CR67, par);
1265 1269
1266 vga_out8 (0x3d4, 0x66); 1270 vga_out8 (0x3d4, 0x66, par);
1267 cr66 = vga_in8 (0x3d5); 1271 cr66 = vga_in8 (0x3d5, par);
1268 vga_out8 (0x3d5, cr66 | 0x80); 1272 vga_out8 (0x3d5, cr66 | 0x80, par);
1269 vga_out8 (0x3d4, 0x3a); 1273 vga_out8 (0x3d4, 0x3a, par);
1270 cr3a = vga_in8 (0x3d5); 1274 cr3a = vga_in8 (0x3d5, par);
1271 vga_out8 (0x3d5, cr3a | 0x80); 1275 vga_out8 (0x3d5, cr3a | 0x80, par);
1272 1276
1273 if (par->chip != S3_SAVAGE_MX) { 1277 if (par->chip != S3_SAVAGE_MX) {
1274 VerticalRetraceWait(); 1278 VerticalRetraceWait(par);
1275 savage_out32 (FIFO_CONTROL_REG, par->MMPR0); 1279 savage_out32 (FIFO_CONTROL_REG, par->MMPR0, par);
1276 par->SavageWaitIdle (par); 1280 par->SavageWaitIdle (par);
1277 savage_out32 (MIU_CONTROL_REG, par->MMPR1); 1281 savage_out32 (MIU_CONTROL_REG, par->MMPR1, par);
1278 par->SavageWaitIdle (par); 1282 par->SavageWaitIdle (par);
1279 savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2); 1283 savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2, par);
1280 par->SavageWaitIdle (par); 1284 par->SavageWaitIdle (par);
1281 savage_out32 (MISC_TIMEOUT_REG, par->MMPR3); 1285 savage_out32 (MISC_TIMEOUT_REG, par->MMPR3, par);
1282 } 1286 }
1283 1287
1284 vga_out8 (0x3d4, 0x66); 1288 vga_out8 (0x3d4, 0x66, par);
1285 vga_out8 (0x3d5, cr66); 1289 vga_out8 (0x3d5, cr66, par);
1286 vga_out8 (0x3d4, 0x3a); 1290 vga_out8 (0x3d4, 0x3a, par);
1287 vga_out8 (0x3d5, cr3a); 1291 vga_out8 (0x3d5, cr3a, par);
1288 1292
1289 SavageSetup2DEngine (par); 1293 SavageSetup2DEngine (par);
1290 vgaHWProtect (par, 0); 1294 vgaHWProtect (par, 0);
@@ -1299,10 +1303,10 @@ static void savagefb_update_start (struct savagefb_par *par,
1299 * ((var->bits_per_pixel+7) / 8)) >> 2; 1303 * ((var->bits_per_pixel+7) / 8)) >> 2;
1300 1304
1301 /* now program the start address registers */ 1305 /* now program the start address registers */
1302 vga_out16(0x3d4, (base & 0x00ff00) | 0x0c); 1306 vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par);
1303 vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d); 1307 vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par);
1304 vga_out8 (0x3d4, 0x69); 1308 vga_out8 (0x3d4, 0x69, par);
1305 vga_out8 (0x3d5, (base & 0x7f0000) >> 16); 1309 vga_out8 (0x3d5, (base & 0x7f0000) >> 16, par);
1306} 1310}
1307 1311
1308 1312
@@ -1311,10 +1315,14 @@ static void savagefb_set_fix(struct fb_info *info)
1311 info->fix.line_length = info->var.xres_virtual * 1315 info->fix.line_length = info->var.xres_virtual *
1312 info->var.bits_per_pixel / 8; 1316 info->var.bits_per_pixel / 8;
1313 1317
1314 if (info->var.bits_per_pixel == 8) 1318 if (info->var.bits_per_pixel == 8) {
1315 info->fix.visual = FB_VISUAL_PSEUDOCOLOR; 1319 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
1316 else 1320 info->fix.xpanstep = 4;
1321 } else {
1317 info->fix.visual = FB_VISUAL_TRUECOLOR; 1322 info->fix.visual = FB_VISUAL_TRUECOLOR;
1323 info->fix.xpanstep = 2;
1324 }
1325
1318} 1326}
1319 1327
1320#if defined(CONFIG_FB_SAVAGE_ACCEL) 1328#if defined(CONFIG_FB_SAVAGE_ACCEL)
@@ -1359,7 +1367,6 @@ static int savagefb_set_par (struct fb_info *info)
1359 par->minClock = 10000; 1367 par->minClock = 10000;
1360 1368
1361 savagefb_set_par_int (par); 1369 savagefb_set_par_int (par);
1362 savagefb_update_start (par, var);
1363 fb_set_cmap (&info->cmap, info); 1370 fb_set_cmap (&info->cmap, info);
1364 savagefb_set_fix(info); 1371 savagefb_set_fix(info);
1365 savagefb_set_clip(info); 1372 savagefb_set_clip(info);
@@ -1406,12 +1413,12 @@ static int savagefb_blank(int blank, struct fb_info *info)
1406 u8 sr8 = 0, srd = 0; 1413 u8 sr8 = 0, srd = 0;
1407 1414
1408 if (par->display_type == DISP_CRT) { 1415 if (par->display_type == DISP_CRT) {
1409 vga_out8(0x3c4, 0x08); 1416 vga_out8(0x3c4, 0x08, par);
1410 sr8 = vga_in8(0x3c5); 1417 sr8 = vga_in8(0x3c5, par);
1411 sr8 |= 0x06; 1418 sr8 |= 0x06;
1412 vga_out8(0x3c5, sr8); 1419 vga_out8(0x3c5, sr8, par);
1413 vga_out8(0x3c4, 0x0d); 1420 vga_out8(0x3c4, 0x0d, par);
1414 srd = vga_in8(0x3c5); 1421 srd = vga_in8(0x3c5, par);
1415 srd &= 0x03; 1422 srd &= 0x03;
1416 1423
1417 switch (blank) { 1424 switch (blank) {
@@ -1429,8 +1436,8 @@ static int savagefb_blank(int blank, struct fb_info *info)
1429 break; 1436 break;
1430 } 1437 }
1431 1438
1432 vga_out8(0x3c4, 0x0d); 1439 vga_out8(0x3c4, 0x0d, par);
1433 vga_out8(0x3c5, srd); 1440 vga_out8(0x3c5, srd, par);
1434 } 1441 }
1435 1442
1436 if (par->display_type == DISP_LCD || 1443 if (par->display_type == DISP_LCD ||
@@ -1438,14 +1445,14 @@ static int savagefb_blank(int blank, struct fb_info *info)
1438 switch(blank) { 1445 switch(blank) {
1439 case FB_BLANK_UNBLANK: 1446 case FB_BLANK_UNBLANK:
1440 case FB_BLANK_NORMAL: 1447 case FB_BLANK_NORMAL:
1441 vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */ 1448 vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
1442 vga_out8(0x3c5, vga_in8(0x3c5) | 0x10); 1449 vga_out8(0x3c5, vga_in8(0x3c5, par) | 0x10, par);
1443 break; 1450 break;
1444 case FB_BLANK_VSYNC_SUSPEND: 1451 case FB_BLANK_VSYNC_SUSPEND:
1445 case FB_BLANK_HSYNC_SUSPEND: 1452 case FB_BLANK_HSYNC_SUSPEND:
1446 case FB_BLANK_POWERDOWN: 1453 case FB_BLANK_POWERDOWN:
1447 vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */ 1454 vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
1448 vga_out8(0x3c5, vga_in8(0x3c5) & ~0x10); 1455 vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x10, par);
1449 break; 1456 break;
1450 } 1457 }
1451 } 1458 }
@@ -1470,7 +1477,6 @@ static struct fb_ops savagefb_ops = {
1470 .fb_copyarea = cfb_copyarea, 1477 .fb_copyarea = cfb_copyarea,
1471 .fb_imageblit = cfb_imageblit, 1478 .fb_imageblit = cfb_imageblit,
1472#endif 1479#endif
1473 .fb_cursor = soft_cursor,
1474}; 1480};
1475 1481
1476/* --------------------------------------------------------------------- */ 1482/* --------------------------------------------------------------------- */
@@ -1499,15 +1505,15 @@ static void savage_enable_mmio (struct savagefb_par *par)
1499 1505
1500 DBG ("savage_enable_mmio\n"); 1506 DBG ("savage_enable_mmio\n");
1501 1507
1502 val = vga_in8 (0x3c3); 1508 val = vga_in8 (0x3c3, par);
1503 vga_out8 (0x3c3, val | 0x01); 1509 vga_out8 (0x3c3, val | 0x01, par);
1504 val = vga_in8 (0x3cc); 1510 val = vga_in8 (0x3cc, par);
1505 vga_out8 (0x3c2, val | 0x01); 1511 vga_out8 (0x3c2, val | 0x01, par);
1506 1512
1507 if (par->chip >= S3_SAVAGE4) { 1513 if (par->chip >= S3_SAVAGE4) {
1508 vga_out8 (0x3d4, 0x40); 1514 vga_out8 (0x3d4, 0x40, par);
1509 val = vga_in8 (0x3d5); 1515 val = vga_in8 (0x3d5, par);
1510 vga_out8 (0x3d5, val | 1); 1516 vga_out8 (0x3d5, val | 1, par);
1511 } 1517 }
1512} 1518}
1513 1519
@@ -1519,9 +1525,9 @@ static void savage_disable_mmio (struct savagefb_par *par)
1519 DBG ("savage_disable_mmio\n"); 1525 DBG ("savage_disable_mmio\n");
1520 1526
1521 if(par->chip >= S3_SAVAGE4 ) { 1527 if(par->chip >= S3_SAVAGE4 ) {
1522 vga_out8 (0x3d4, 0x40); 1528 vga_out8 (0x3d4, 0x40, par);
1523 val = vga_in8 (0x3d5); 1529 val = vga_in8 (0x3d5, par);
1524 vga_out8 (0x3d5, val | 1); 1530 vga_out8 (0x3d5, val | 1, par);
1525 } 1531 }
1526} 1532}
1527 1533
@@ -1641,30 +1647,30 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1641 DBG("savage_init_hw"); 1647 DBG("savage_init_hw");
1642 1648
1643 /* unprotect CRTC[0-7] */ 1649 /* unprotect CRTC[0-7] */
1644 vga_out8(0x3d4, 0x11); 1650 vga_out8(0x3d4, 0x11, par);
1645 tmp = vga_in8(0x3d5); 1651 tmp = vga_in8(0x3d5, par);
1646 vga_out8(0x3d5, tmp & 0x7f); 1652 vga_out8(0x3d5, tmp & 0x7f, par);
1647 1653
1648 /* unlock extended regs */ 1654 /* unlock extended regs */
1649 vga_out16(0x3d4, 0x4838); 1655 vga_out16(0x3d4, 0x4838, par);
1650 vga_out16(0x3d4, 0xa039); 1656 vga_out16(0x3d4, 0xa039, par);
1651 vga_out16(0x3c4, 0x0608); 1657 vga_out16(0x3c4, 0x0608, par);
1652 1658
1653 vga_out8(0x3d4, 0x40); 1659 vga_out8(0x3d4, 0x40, par);
1654 tmp = vga_in8(0x3d5); 1660 tmp = vga_in8(0x3d5, par);
1655 vga_out8(0x3d5, tmp & ~0x01); 1661 vga_out8(0x3d5, tmp & ~0x01, par);
1656 1662
1657 /* unlock sys regs */ 1663 /* unlock sys regs */
1658 vga_out8(0x3d4, 0x38); 1664 vga_out8(0x3d4, 0x38, par);
1659 vga_out8(0x3d5, 0x48); 1665 vga_out8(0x3d5, 0x48, par);
1660 1666
1661 /* Unlock system registers. */ 1667 /* Unlock system registers. */
1662 vga_out16(0x3d4, 0x4838); 1668 vga_out16(0x3d4, 0x4838, par);
1663 1669
1664 /* Next go on to detect amount of installed ram */ 1670 /* Next go on to detect amount of installed ram */
1665 1671
1666 vga_out8(0x3d4, 0x36); /* for register CR36 (CONFG_REG1), */ 1672 vga_out8(0x3d4, 0x36, par); /* for register CR36 (CONFG_REG1), */
1667 config1 = vga_in8(0x3d5); /* get amount of vram installed */ 1673 config1 = vga_in8(0x3d5, par); /* get amount of vram installed */
1668 1674
1669 /* Compute the amount of video memory and offscreen memory. */ 1675 /* Compute the amount of video memory and offscreen memory. */
1670 1676
@@ -1680,8 +1686,8 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1680 * when it really means 8MB. Why do it the same when you 1686 * when it really means 8MB. Why do it the same when you
1681 * can do it different... 1687 * can do it different...
1682 */ 1688 */
1683 vga_out8(0x3d4, 0x68); /* memory control 1 */ 1689 vga_out8(0x3d4, 0x68, par); /* memory control 1 */
1684 if( (vga_in8(0x3d5) & 0xC0) == (0x01 << 6) ) 1690 if( (vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6) )
1685 RamSavage4[1] = 8; 1691 RamSavage4[1] = 8;
1686 1692
1687 /*FALLTHROUGH*/ 1693 /*FALLTHROUGH*/
@@ -1710,13 +1716,13 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1710 printk (KERN_INFO "savagefb: probed videoram: %dk\n", videoRam); 1716 printk (KERN_INFO "savagefb: probed videoram: %dk\n", videoRam);
1711 1717
1712 /* reset graphics engine to avoid memory corruption */ 1718 /* reset graphics engine to avoid memory corruption */
1713 vga_out8 (0x3d4, 0x66); 1719 vga_out8 (0x3d4, 0x66, par);
1714 cr66 = vga_in8 (0x3d5); 1720 cr66 = vga_in8 (0x3d5, par);
1715 vga_out8 (0x3d5, cr66 | 0x02); 1721 vga_out8 (0x3d5, cr66 | 0x02, par);
1716 udelay (10000); 1722 udelay (10000);
1717 1723
1718 vga_out8 (0x3d4, 0x66); 1724 vga_out8 (0x3d4, 0x66, par);
1719 vga_out8 (0x3d5, cr66 & ~0x02); /* clear reset flag */ 1725 vga_out8 (0x3d5, cr66 & ~0x02, par); /* clear reset flag */
1720 udelay (10000); 1726 udelay (10000);
1721 1727
1722 1728
@@ -1724,13 +1730,13 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1724 * reset memory interface, 3D engine, AGP master, PCI master, 1730 * reset memory interface, 3D engine, AGP master, PCI master,
1725 * master engine unit, motion compensation/LPB 1731 * master engine unit, motion compensation/LPB
1726 */ 1732 */
1727 vga_out8 (0x3d4, 0x3f); 1733 vga_out8 (0x3d4, 0x3f, par);
1728 cr3f = vga_in8 (0x3d5); 1734 cr3f = vga_in8 (0x3d5, par);
1729 vga_out8 (0x3d5, cr3f | 0x08); 1735 vga_out8 (0x3d5, cr3f | 0x08, par);
1730 udelay (10000); 1736 udelay (10000);
1731 1737
1732 vga_out8 (0x3d4, 0x3f); 1738 vga_out8 (0x3d4, 0x3f, par);
1733 vga_out8 (0x3d5, cr3f & ~0x08); /* clear reset flags */ 1739 vga_out8 (0x3d5, cr3f & ~0x08, par); /* clear reset flags */
1734 udelay (10000); 1740 udelay (10000);
1735 1741
1736 /* Savage ramdac speeds */ 1742 /* Savage ramdac speeds */
@@ -1741,15 +1747,15 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1741 par->clock[3] = 220000; 1747 par->clock[3] = 220000;
1742 1748
1743 /* detect current mclk */ 1749 /* detect current mclk */
1744 vga_out8(0x3c4, 0x08); 1750 vga_out8(0x3c4, 0x08, par);
1745 sr8 = vga_in8(0x3c5); 1751 sr8 = vga_in8(0x3c5, par);
1746 vga_out8(0x3c5, 0x06); 1752 vga_out8(0x3c5, 0x06, par);
1747 vga_out8(0x3c4, 0x10); 1753 vga_out8(0x3c4, 0x10, par);
1748 n = vga_in8(0x3c5); 1754 n = vga_in8(0x3c5, par);
1749 vga_out8(0x3c4, 0x11); 1755 vga_out8(0x3c4, 0x11, par);
1750 m = vga_in8(0x3c5); 1756 m = vga_in8(0x3c5, par);
1751 vga_out8(0x3c4, 0x08); 1757 vga_out8(0x3c4, 0x08, par);
1752 vga_out8(0x3c5, sr8); 1758 vga_out8(0x3c5, sr8, par);
1753 m &= 0x7f; 1759 m &= 0x7f;
1754 n1 = n & 0x1f; 1760 n1 = n & 0x1f;
1755 n2 = (n >> 5) & 0x03; 1761 n2 = (n >> 5) & 0x03;
@@ -1763,10 +1769,10 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1763 if (par->chip == S3_SAVAGE4) { 1769 if (par->chip == S3_SAVAGE4) {
1764 unsigned char sr30 = 0x00; 1770 unsigned char sr30 = 0x00;
1765 1771
1766 vga_out8(0x3c4, 0x30); 1772 vga_out8(0x3c4, 0x30, par);
1767 /* clear bit 1 */ 1773 /* clear bit 1 */
1768 vga_out8(0x3c5, vga_in8(0x3c5) & ~0x02); 1774 vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x02, par);
1769 sr30 = vga_in8(0x3c5); 1775 sr30 = vga_in8(0x3c5, par);
1770 if (sr30 & 0x02 /*0x04 */) { 1776 if (sr30 & 0x02 /*0x04 */) {
1771 dvi = 1; 1777 dvi = 1;
1772 printk("savagefb: Digital Flat Panel Detected\n"); 1778 printk("savagefb: Digital Flat Panel Detected\n");
@@ -1783,12 +1789,12 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1783 /* Check LCD panel parrmation */ 1789 /* Check LCD panel parrmation */
1784 1790
1785 if (par->display_type == DISP_LCD) { 1791 if (par->display_type == DISP_LCD) {
1786 unsigned char cr6b = VGArCR( 0x6b ); 1792 unsigned char cr6b = VGArCR( 0x6b, par);
1787 1793
1788 int panelX = (VGArSEQ (0x61) + 1794 int panelX = (VGArSEQ (0x61, par) +
1789 ((VGArSEQ (0x66) & 0x02) << 7) + 1) * 8; 1795 ((VGArSEQ (0x66, par) & 0x02) << 7) + 1) * 8;
1790 int panelY = (VGArSEQ (0x69) + 1796 int panelY = (VGArSEQ (0x69, par) +
1791 ((VGArSEQ (0x6e) & 0x70) << 4) + 1); 1797 ((VGArSEQ (0x6e, par) & 0x70) << 4) + 1);
1792 1798
1793 char * sTechnology = "Unknown"; 1799 char * sTechnology = "Unknown";
1794 1800
@@ -1810,9 +1816,9 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
1810 ActiveDUO = 0x80 1816 ActiveDUO = 0x80
1811 }; 1817 };
1812 1818
1813 if ((VGArSEQ (0x39) & 0x03) == 0) { 1819 if ((VGArSEQ (0x39, par) & 0x03) == 0) {
1814 sTechnology = "TFT"; 1820 sTechnology = "TFT";
1815 } else if ((VGArSEQ (0x30) & 0x01) == 0) { 1821 } else if ((VGArSEQ (0x30, par) & 0x01) == 0) {
1816 sTechnology = "DSTN"; 1822 sTechnology = "DSTN";
1817 } else { 1823 } else {
1818 sTechnology = "STN"; 1824 sTechnology = "STN";
@@ -1870,7 +1876,6 @@ static int __devinit savage_init_fb_info (struct fb_info *info,
1870 1876
1871 info->fix.type = FB_TYPE_PACKED_PIXELS; 1877 info->fix.type = FB_TYPE_PACKED_PIXELS;
1872 info->fix.type_aux = 0; 1878 info->fix.type_aux = 0;
1873 info->fix.xpanstep = 2;
1874 info->fix.ypanstep = 1; 1879 info->fix.ypanstep = 1;
1875 info->fix.ywrapstep = 0; 1880 info->fix.ywrapstep = 0;
1876 info->fix.accel = id->driver_data; 1881 info->fix.accel = id->driver_data;
@@ -2049,24 +2054,11 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
2049 info->monspecs.modedb, info->monspecs.modedb_len, 2054 info->monspecs.modedb, info->monspecs.modedb_len,
2050 NULL, 8); 2055 NULL, 8);
2051 } else if (info->monspecs.modedb != NULL) { 2056 } else if (info->monspecs.modedb != NULL) {
2052 struct fb_monspecs *specs = &info->monspecs; 2057 struct fb_videomode *modedb;
2053 struct fb_videomode modedb;
2054
2055 if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
2056 int i;
2057
2058 for (i = 0; i < specs->modedb_len; i++) {
2059 if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
2060 modedb = specs->modedb[i];
2061 break;
2062 }
2063 }
2064 } else {
2065 /* otherwise, get first mode in database */
2066 modedb = specs->modedb[0];
2067 }
2068 2058
2069 savage_update_var(&info->var, &modedb); 2059 modedb = fb_find_best_display(&info->monspecs,
2060 &info->modelist);
2061 savage_update_var(&info->var, modedb);
2070 } 2062 }
2071 2063
2072 /* maximize virtual vertical length */ 2064 /* maximize virtual vertical length */
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index cf5106eab2d5..2e8769dd345a 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -126,7 +126,6 @@ static struct fb_ops sgivwfb_ops = {
126 .fb_fillrect = cfb_fillrect, 126 .fb_fillrect = cfb_fillrect,
127 .fb_copyarea = cfb_copyarea, 127 .fb_copyarea = cfb_copyarea,
128 .fb_imageblit = cfb_imageblit, 128 .fb_imageblit = cfb_imageblit,
129 .fb_cursor = soft_cursor,
130 .fb_mmap = sgivwfb_mmap, 129 .fb_mmap = sgivwfb_mmap,
131}; 130};
132 131
@@ -751,10 +750,6 @@ int __init sgivwfb_setup(char *options)
751/* 750/*
752 * Initialisation 751 * Initialisation
753 */ 752 */
754static void sgivwfb_release(struct device *device)
755{
756}
757
758static int __init sgivwfb_probe(struct device *device) 753static int __init sgivwfb_probe(struct device *device)
759{ 754{
760 struct platform_device *dev = to_platform_device(device); 755 struct platform_device *dev = to_platform_device(device);
@@ -859,13 +854,7 @@ static struct device_driver sgivwfb_driver = {
859 .remove = sgivwfb_remove, 854 .remove = sgivwfb_remove,
860}; 855};
861 856
862static struct platform_device sgivwfb_device = { 857static struct platform_device *sgivwfb_device;
863 .name = "sgivwfb",
864 .id = 0,
865 .dev = {
866 .release = sgivwfb_release,
867 }
868};
869 858
870int __init sgivwfb_init(void) 859int __init sgivwfb_init(void)
871{ 860{
@@ -880,9 +869,15 @@ int __init sgivwfb_init(void)
880#endif 869#endif
881 ret = driver_register(&sgivwfb_driver); 870 ret = driver_register(&sgivwfb_driver);
882 if (!ret) { 871 if (!ret) {
883 ret = platform_device_register(&sgivwfb_device); 872 sgivwfb_device = platform_device_alloc("sgivwfb", 0);
884 if (ret) 873 if (sgivwfb_device) {
874 ret = platform_device_add(sgivwfb_device);
875 } else
876 ret = -ENOMEM;
877 if (ret) {
885 driver_unregister(&sgivwfb_driver); 878 driver_unregister(&sgivwfb_driver);
879 platform_device_put(sgivwfb_device);
880 }
886 } 881 }
887 return ret; 882 return ret;
888} 883}
@@ -894,7 +889,7 @@ MODULE_LICENSE("GPL");
894 889
895static void __exit sgivwfb_exit(void) 890static void __exit sgivwfb_exit(void)
896{ 891{
897 platform_device_unregister(&sgivwfb_device); 892 platform_device_unregister(sgivwfb_device);
898 driver_unregister(&sgivwfb_driver); 893 driver_unregister(&sgivwfb_driver);
899} 894}
900 895
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 42c54b69726e..dea1a46c67c4 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -2002,7 +2002,9 @@ static struct fb_ops sisfb_ops = {
2002 .fb_fillrect = fbcon_sis_fillrect, 2002 .fb_fillrect = fbcon_sis_fillrect,
2003 .fb_copyarea = fbcon_sis_copyarea, 2003 .fb_copyarea = fbcon_sis_copyarea,
2004 .fb_imageblit = cfb_imageblit, 2004 .fb_imageblit = cfb_imageblit,
2005#ifdef CONFIG_FB_SOFT_CURSOR
2005 .fb_cursor = soft_cursor, 2006 .fb_cursor = soft_cursor,
2007#endif
2006 .fb_sync = fbcon_sis_sync, 2008 .fb_sync = fbcon_sis_sync,
2007#ifdef SIS_NEW_CONFIG_COMPAT 2009#ifdef SIS_NEW_CONFIG_COMPAT
2008 .fb_compat_ioctl= sisfb_compat_ioctl, 2010 .fb_compat_ioctl= sisfb_compat_ioctl,
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 7b43716ab665..a01e7ecc15ed 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -457,11 +457,8 @@ void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image)
457} 457}
458 458
459/** 459/**
460 * xxxfb_cursor - REQUIRED function. If your hardware lacks support 460 * xxxfb_cursor - OPTIONAL. If your hardware lacks support
461 * for a cursor you can use the default cursor whose 461 * for a cursor, leave this field NULL.
462 * function is called soft_cursor. It will always
463 * work since it uses xxxfb_imageblit function which
464 * is required.
465 * 462 *
466 * @info: frame buffer structure that represents a single frame buffer 463 * @info: frame buffer structure that represents a single frame buffer
467 * @cursor: structure defining the cursor to draw. 464 * @cursor: structure defining the cursor to draw.
@@ -663,7 +660,7 @@ static struct fb_ops xxxfb_ops = {
663 .fb_fillrect = xxxfb_fillrect, /* Needed !!! */ 660 .fb_fillrect = xxxfb_fillrect, /* Needed !!! */
664 .fb_copyarea = xxxfb_copyarea, /* Needed !!! */ 661 .fb_copyarea = xxxfb_copyarea, /* Needed !!! */
665 .fb_imageblit = xxxfb_imageblit, /* Needed !!! */ 662 .fb_imageblit = xxxfb_imageblit, /* Needed !!! */
666 .fb_cursor = xxxfb_cursor, /* Needed !!! */ 663 .fb_cursor = xxxfb_cursor, /* Optional !!! */
667 .fb_rotate = xxxfb_rotate, 664 .fb_rotate = xxxfb_rotate,
668 .fb_poll = xxxfb_poll, 665 .fb_poll = xxxfb_poll,
669 .fb_sync = xxxfb_sync, 666 .fb_sync = xxxfb_sync,
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 663d53657fa4..e0f14df840d9 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -1382,7 +1382,6 @@ static struct fb_ops sstfb_ops = {
1382 .fb_fillrect = cfb_fillrect, /* sstfb_fillrect */ 1382 .fb_fillrect = cfb_fillrect, /* sstfb_fillrect */
1383 .fb_copyarea = cfb_copyarea, /* sstfb_copyarea */ 1383 .fb_copyarea = cfb_copyarea, /* sstfb_copyarea */
1384 .fb_imageblit = cfb_imageblit, 1384 .fb_imageblit = cfb_imageblit,
1385 .fb_cursor = soft_cursor,
1386 .fb_ioctl = sstfb_ioctl, 1385 .fb_ioctl = sstfb_ioctl,
1387}; 1386};
1388 1387
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 9e52794768e6..fbb17332afd7 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1147,7 +1147,6 @@ static struct fb_ops stifb_ops = {
1147 .fb_fillrect = cfb_fillrect, 1147 .fb_fillrect = cfb_fillrect,
1148 .fb_copyarea = cfb_copyarea, 1148 .fb_copyarea = cfb_copyarea,
1149 .fb_imageblit = cfb_imageblit, 1149 .fb_imageblit = cfb_imageblit,
1150 .fb_cursor = soft_cursor,
1151}; 1150};
1152 1151
1153 1152
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index 1986a8b3833c..59fff29bc02e 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -52,7 +52,6 @@ static struct fb_ops tcx_ops = {
52 .fb_imageblit = cfb_imageblit, 52 .fb_imageblit = cfb_imageblit,
53 .fb_mmap = tcx_mmap, 53 .fb_mmap = tcx_mmap,
54 .fb_ioctl = tcx_ioctl, 54 .fb_ioctl = tcx_ioctl,
55 .fb_cursor = soft_cursor,
56}; 55};
57 56
58/* THC definitions */ 57/* THC definitions */
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 7044226c5d4c..9d53387e6a66 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -184,7 +184,6 @@ static struct fb_ops tdfxfb_ops = {
184 .fb_copyarea = cfb_copyarea, 184 .fb_copyarea = cfb_copyarea,
185 .fb_imageblit = cfb_imageblit, 185 .fb_imageblit = cfb_imageblit,
186#endif 186#endif
187 .fb_cursor = soft_cursor,
188}; 187};
189 188
190/* 189/*
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 9d9d2009ad8c..7398bd48ba6c 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -63,7 +63,6 @@ static struct fb_ops tgafb_ops = {
63 .fb_fillrect = tgafb_fillrect, 63 .fb_fillrect = tgafb_fillrect,
64 .fb_copyarea = tgafb_copyarea, 64 .fb_copyarea = tgafb_copyarea,
65 .fb_imageblit = tgafb_imageblit, 65 .fb_imageblit = tgafb_imageblit,
66 .fb_cursor = soft_cursor,
67}; 66};
68 67
69 68
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 81a6d9f188cf..9ac2d3171187 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1293,7 +1293,6 @@ static struct fb_ops tridentfb_ops = {
1293 .fb_fillrect = tridentfb_fillrect, 1293 .fb_fillrect = tridentfb_fillrect,
1294 .fb_copyarea= tridentfb_copyarea, 1294 .fb_copyarea= tridentfb_copyarea,
1295 .fb_imageblit = cfb_imageblit, 1295 .fb_imageblit = cfb_imageblit,
1296 .fb_cursor = soft_cursor,
1297}; 1296};
1298 1297
1299module_init(tridentfb_init); 1298module_init(tridentfb_init);
diff --git a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
index 39d9ca71856b..d904da44e1aa 100644
--- a/drivers/video/tx3912fb.c
+++ b/drivers/video/tx3912fb.c
@@ -89,7 +89,6 @@ static struct fb_ops tx3912fb_ops = {
89 .fb_fillrect = cfb_fillrect, 89 .fb_fillrect = cfb_fillrect,
90 .fb_copyarea = cfb_copyarea, 90 .fb_copyarea = cfb_copyarea,
91 .fb_imageblit = cfb_imageblit, 91 .fb_imageblit = cfb_imageblit,
92 .fb_cursor = soft_cursor,
93}; 92};
94 93
95static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 94static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 31a2bbc53974..ce97ec8eae97 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -135,7 +135,6 @@ static struct fb_ops valkyriefb_ops = {
135 .fb_fillrect = cfb_fillrect, 135 .fb_fillrect = cfb_fillrect,
136 .fb_copyarea = cfb_copyarea, 136 .fb_copyarea = cfb_copyarea,
137 .fb_imageblit = cfb_imageblit, 137 .fb_imageblit = cfb_imageblit,
138 .fb_cursor = soft_cursor,
139}; 138};
140 139
141/* Sets the video mode according to info->var */ 140/* Sets the video mode according to info->var */
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 3cc23106641d..e25eae1a78c1 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -48,7 +48,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
48}; 48};
49 49
50static int inverse = 0; 50static int inverse = 0;
51static int mtrr = 3; /* default to write-combining */ 51static int mtrr = 0; /* disable mtrr */
52static int vram_remap __initdata = 0; /* Set amount of memory to be used */ 52static int vram_remap __initdata = 0; /* Set amount of memory to be used */
53static int vram_total __initdata = 0; /* Set total amount of memory */ 53static int vram_total __initdata = 0; /* Set total amount of memory */
54static int pmi_setpal = 0; /* pmi for palette changes ??? */ 54static int pmi_setpal = 0; /* pmi for palette changes ??? */
@@ -166,45 +166,39 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
166 if (regno >= info->cmap.len) 166 if (regno >= info->cmap.len)
167 return 1; 167 return 1;
168 168
169 switch (info->var.bits_per_pixel) { 169 if (info->var.bits_per_pixel == 8)
170 case 8:
171 vesa_setpalette(regno,red,green,blue); 170 vesa_setpalette(regno,red,green,blue);
172 break; 171 else if (regno < 16) {
173 case 16: 172 switch (info->var.bits_per_pixel) {
174 if (info->var.red.offset == 10) { 173 case 16:
175 /* 1:5:5:5 */ 174 if (info->var.red.offset == 10) {
176 ((u32*) (info->pseudo_palette))[regno] = 175 /* 1:5:5:5 */
176 ((u32*) (info->pseudo_palette))[regno] =
177 ((red & 0xf800) >> 1) | 177 ((red & 0xf800) >> 1) |
178 ((green & 0xf800) >> 6) | 178 ((green & 0xf800) >> 6) |
179 ((blue & 0xf800) >> 11); 179 ((blue & 0xf800) >> 11);
180 } else { 180 } else {
181 /* 0:5:6:5 */ 181 /* 0:5:6:5 */
182 ((u32*) (info->pseudo_palette))[regno] = 182 ((u32*) (info->pseudo_palette))[regno] =
183 ((red & 0xf800) ) | 183 ((red & 0xf800) ) |
184 ((green & 0xfc00) >> 5) | 184 ((green & 0xfc00) >> 5) |
185 ((blue & 0xf800) >> 11); 185 ((blue & 0xf800) >> 11);
186 }
187 break;
188 case 24:
189 case 32:
190 red >>= 8;
191 green >>= 8;
192 blue >>= 8;
193 ((u32 *)(info->pseudo_palette))[regno] =
194 (red << info->var.red.offset) |
195 (green << info->var.green.offset) |
196 (blue << info->var.blue.offset);
197 break;
186 } 198 }
187 break; 199 }
188 case 24: 200
189 red >>= 8; 201 return 0;
190 green >>= 8;
191 blue >>= 8;
192 ((u32 *)(info->pseudo_palette))[regno] =
193 (red << info->var.red.offset) |
194 (green << info->var.green.offset) |
195 (blue << info->var.blue.offset);
196 break;
197 case 32:
198 red >>= 8;
199 green >>= 8;
200 blue >>= 8;
201 ((u32 *)(info->pseudo_palette))[regno] =
202 (red << info->var.red.offset) |
203 (green << info->var.green.offset) |
204 (blue << info->var.blue.offset);
205 break;
206 }
207 return 0;
208} 202}
209 203
210static struct fb_ops vesafb_ops = { 204static struct fb_ops vesafb_ops = {
@@ -215,7 +209,6 @@ static struct fb_ops vesafb_ops = {
215 .fb_fillrect = cfb_fillrect, 209 .fb_fillrect = cfb_fillrect,
216 .fb_copyarea = cfb_copyarea, 210 .fb_copyarea = cfb_copyarea,
217 .fb_imageblit = cfb_imageblit, 211 .fb_imageblit = cfb_imageblit,
218 .fb_cursor = soft_cursor,
219}; 212};
220 213
221static int __init vesafb_setup(char *options) 214static int __init vesafb_setup(char *options)
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 92d46555dd86..8794dc5d2466 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -92,7 +92,6 @@ static struct fb_ops vfb_ops = {
92 .fb_fillrect = cfb_fillrect, 92 .fb_fillrect = cfb_fillrect,
93 .fb_copyarea = cfb_copyarea, 93 .fb_copyarea = cfb_copyarea,
94 .fb_imageblit = cfb_imageblit, 94 .fb_imageblit = cfb_imageblit,
95 .fb_cursor = soft_cursor,
96 .fb_mmap = vfb_mmap, 95 .fb_mmap = vfb_mmap,
97}; 96};
98 97
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index b46454c55c91..226ae8a88482 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -21,6 +21,7 @@
21#include <linux/fb.h> 21#include <linux/fb.h>
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/platform_device.h>
24 25
25#include <asm/io.h> 26#include <asm/io.h>
26#include <video/vga.h> 27#include <video/vga.h>
@@ -51,35 +52,33 @@
51 * card parameters 52 * card parameters
52 */ 53 */
53 54
54static struct fb_info vga16fb; 55struct vga16fb_par {
55
56static struct vga16fb_par {
57 /* structure holding original VGA register settings when the 56 /* structure holding original VGA register settings when the
58 screen is blanked */ 57 screen is blanked */
59 struct { 58 struct {
60 unsigned char SeqCtrlIndex; /* Sequencer Index reg. */ 59 unsigned char SeqCtrlIndex; /* Sequencer Index reg. */
61 unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */ 60 unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */
62 unsigned char CrtMiscIO; /* Miscellaneous register */ 61 unsigned char CrtMiscIO; /* Miscellaneous register */
63 unsigned char HorizontalTotal; /* CRT-Controller:00h */ 62 unsigned char HorizontalTotal; /* CRT-Controller:00h */
64 unsigned char HorizDisplayEnd; /* CRT-Controller:01h */ 63 unsigned char HorizDisplayEnd; /* CRT-Controller:01h */
65 unsigned char StartHorizRetrace; /* CRT-Controller:04h */ 64 unsigned char StartHorizRetrace;/* CRT-Controller:04h */
66 unsigned char EndHorizRetrace; /* CRT-Controller:05h */ 65 unsigned char EndHorizRetrace; /* CRT-Controller:05h */
67 unsigned char Overflow; /* CRT-Controller:07h */ 66 unsigned char Overflow; /* CRT-Controller:07h */
68 unsigned char StartVertRetrace; /* CRT-Controller:10h */ 67 unsigned char StartVertRetrace; /* CRT-Controller:10h */
69 unsigned char EndVertRetrace; /* CRT-Controller:11h */ 68 unsigned char EndVertRetrace; /* CRT-Controller:11h */
70 unsigned char ModeControl; /* CRT-Controller:17h */ 69 unsigned char ModeControl; /* CRT-Controller:17h */
71 unsigned char ClockingMode; /* Seq-Controller:01h */ 70 unsigned char ClockingMode; /* Seq-Controller:01h */
72 } vga_state; 71 } vga_state;
73 struct vgastate state; 72 struct vgastate state;
74 atomic_t ref_count; 73 atomic_t ref_count;
75 int palette_blanked, vesa_blanked, mode, isVGA; 74 int palette_blanked, vesa_blanked, mode, isVGA;
76 u8 misc, pel_msk, vss, clkdiv; 75 u8 misc, pel_msk, vss, clkdiv;
77 u8 crtc[VGA_CRT_C]; 76 u8 crtc[VGA_CRT_C];
78} vga16_par; 77};
79 78
80/* --------------------------------------------------------------------- */ 79/* --------------------------------------------------------------------- */
81 80
82static struct fb_var_screeninfo vga16fb_defined = { 81static struct fb_var_screeninfo vga16fb_defined __initdata = {
83 .xres = 640, 82 .xres = 640,
84 .yres = 480, 83 .yres = 480,
85 .xres_virtual = 640, 84 .xres_virtual = 640,
@@ -205,7 +204,7 @@ static inline void setindex(int index)
205static void vga16fb_pan_var(struct fb_info *info, 204static void vga16fb_pan_var(struct fb_info *info,
206 struct fb_var_screeninfo *var) 205 struct fb_var_screeninfo *var)
207{ 206{
208 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 207 struct vga16fb_par *par = info->par;
209 u32 xoffset, pos; 208 u32 xoffset, pos;
210 209
211 xoffset = var->xoffset; 210 xoffset = var->xoffset;
@@ -300,7 +299,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
300 299
301static int vga16fb_open(struct fb_info *info, int user) 300static int vga16fb_open(struct fb_info *info, int user)
302{ 301{
303 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 302 struct vga16fb_par *par = info->par;
304 int cnt = atomic_read(&par->ref_count); 303 int cnt = atomic_read(&par->ref_count);
305 304
306 if (!cnt) { 305 if (!cnt) {
@@ -315,7 +314,7 @@ static int vga16fb_open(struct fb_info *info, int user)
315 314
316static int vga16fb_release(struct fb_info *info, int user) 315static int vga16fb_release(struct fb_info *info, int user)
317{ 316{
318 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 317 struct vga16fb_par *par = info->par;
319 int cnt = atomic_read(&par->ref_count); 318 int cnt = atomic_read(&par->ref_count);
320 319
321 if (!cnt) 320 if (!cnt)
@@ -330,7 +329,7 @@ static int vga16fb_release(struct fb_info *info, int user)
330static int vga16fb_check_var(struct fb_var_screeninfo *var, 329static int vga16fb_check_var(struct fb_var_screeninfo *var,
331 struct fb_info *info) 330 struct fb_info *info)
332{ 331{
333 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 332 struct vga16fb_par *par = info->par;
334 u32 xres, right, hslen, left, xtotal; 333 u32 xres, right, hslen, left, xtotal;
335 u32 yres, lower, vslen, upper, ytotal; 334 u32 yres, lower, vslen, upper, ytotal;
336 u32 vxres, xoffset, vyres, yoffset; 335 u32 vxres, xoffset, vyres, yoffset;
@@ -535,7 +534,7 @@ static int vga16fb_check_var(struct fb_var_screeninfo *var,
535 534
536static int vga16fb_set_par(struct fb_info *info) 535static int vga16fb_set_par(struct fb_info *info)
537{ 536{
538 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 537 struct vga16fb_par *par = info->par;
539 u8 gdc[VGA_GFX_C]; 538 u8 gdc[VGA_GFX_C];
540 u8 seq[VGA_SEQ_C]; 539 u8 seq[VGA_SEQ_C];
541 u8 atc[VGA_ATT_C]; 540 u8 atc[VGA_ATT_C];
@@ -677,7 +676,7 @@ static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
677 unsigned blue, unsigned transp, 676 unsigned blue, unsigned transp,
678 struct fb_info *info) 677 struct fb_info *info)
679{ 678{
680 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 679 struct vga16fb_par *par = info->par;
681 int gray; 680 int gray;
682 681
683 /* 682 /*
@@ -850,7 +849,7 @@ static void vga_pal_blank(void)
850/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ 849/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
851static int vga16fb_blank(int blank, struct fb_info *info) 850static int vga16fb_blank(int blank, struct fb_info *info)
852{ 851{
853 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 852 struct vga16fb_par *par = info->par;
854 853
855 switch (blank) { 854 switch (blank) {
856 case FB_BLANK_UNBLANK: /* Unblank */ 855 case FB_BLANK_UNBLANK: /* Unblank */
@@ -1201,7 +1200,7 @@ static void vga_imageblit_expand(struct fb_info *info, const struct fb_image *im
1201{ 1200{
1202 char __iomem *where = info->screen_base + (image->dx/8) + 1201 char __iomem *where = info->screen_base + (image->dx/8) +
1203 image->dy * info->fix.line_length; 1202 image->dy * info->fix.line_length;
1204 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 1203 struct vga16fb_par *par = info->par;
1205 char *cdat = (char *) image->data; 1204 char *cdat = (char *) image->data;
1206 char __iomem *dst; 1205 char __iomem *dst;
1207 int x, y; 1206 int x, y;
@@ -1266,7 +1265,7 @@ static void vga_imageblit_color(struct fb_info *info, const struct fb_image *ima
1266 /* 1265 /*
1267 * Draw logo 1266 * Draw logo
1268 */ 1267 */
1269 struct vga16fb_par *par = (struct vga16fb_par *) info->par; 1268 struct vga16fb_par *par = info->par;
1270 char __iomem *where = 1269 char __iomem *where =
1271 info->screen_base + image->dy * info->fix.line_length + 1270 info->screen_base + image->dy * info->fix.line_length +
1272 image->dx/8; 1271 image->dx/8;
@@ -1326,7 +1325,6 @@ static struct fb_ops vga16fb_ops = {
1326 .fb_fillrect = vga16fb_fillrect, 1325 .fb_fillrect = vga16fb_fillrect,
1327 .fb_copyarea = vga16fb_copyarea, 1326 .fb_copyarea = vga16fb_copyarea,
1328 .fb_imageblit = vga16fb_imageblit, 1327 .fb_imageblit = vga16fb_imageblit,
1329 .fb_cursor = soft_cursor,
1330}; 1328};
1331 1329
1332#ifndef MODULE 1330#ifndef MODULE
@@ -1344,89 +1342,141 @@ static int vga16fb_setup(char *options)
1344} 1342}
1345#endif 1343#endif
1346 1344
1347static int __init vga16fb_init(void) 1345static int __init vga16fb_probe(struct device *device)
1348{ 1346{
1347 struct platform_device *dev = to_platform_device(device);
1348 struct fb_info *info;
1349 struct vga16fb_par *par;
1349 int i; 1350 int i;
1350 int ret; 1351 int ret = 0;
1351#ifndef MODULE
1352 char *option = NULL;
1353 1352
1354 if (fb_get_options("vga16fb", &option))
1355 return -ENODEV;
1356
1357 vga16fb_setup(option);
1358#endif
1359 printk(KERN_DEBUG "vga16fb: initializing\n"); 1353 printk(KERN_DEBUG "vga16fb: initializing\n");
1354 info = framebuffer_alloc(sizeof(struct vga16fb_par), &dev->dev);
1355
1356 if (!info) {
1357 ret = -ENOMEM;
1358 goto err_fb_alloc;
1359 }
1360 1360
1361 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */ 1361 /* XXX share VGA_FB_PHYS and I/O region with vgacon and others */
1362 info->screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS);
1362 1363
1363 vga16fb.screen_base = (void __iomem *)VGA_MAP_MEM(VGA_FB_PHYS); 1364 if (!info->screen_base) {
1364 if (!vga16fb.screen_base) {
1365 printk(KERN_ERR "vga16fb: unable to map device\n"); 1365 printk(KERN_ERR "vga16fb: unable to map device\n");
1366 ret = -ENOMEM; 1366 ret = -ENOMEM;
1367 goto err_ioremap; 1367 goto err_ioremap;
1368 } 1368 }
1369 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.screen_base);
1370 1369
1371 vga16_par.isVGA = ORIG_VIDEO_ISVGA; 1370 printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
1372 vga16_par.palette_blanked = 0; 1371 par = info->par;
1373 vga16_par.vesa_blanked = 0;
1374 1372
1375 i = vga16_par.isVGA? 6 : 2; 1373 par->isVGA = ORIG_VIDEO_ISVGA;
1374 par->palette_blanked = 0;
1375 par->vesa_blanked = 0;
1376
1377 i = par->isVGA? 6 : 2;
1376 1378
1377 vga16fb_defined.red.length = i; 1379 vga16fb_defined.red.length = i;
1378 vga16fb_defined.green.length = i; 1380 vga16fb_defined.green.length = i;
1379 vga16fb_defined.blue.length = i; 1381 vga16fb_defined.blue.length = i;
1380 1382
1381 /* name should not depend on EGA/VGA */ 1383 /* name should not depend on EGA/VGA */
1382 vga16fb.fbops = &vga16fb_ops; 1384 info->fbops = &vga16fb_ops;
1383 vga16fb.var = vga16fb_defined; 1385 info->var = vga16fb_defined;
1384 vga16fb.fix = vga16fb_fix; 1386 info->fix = vga16fb_fix;
1385 vga16fb.par = &vga16_par; 1387 info->flags = FBINFO_FLAG_DEFAULT |
1386 vga16fb.flags = FBINFO_FLAG_DEFAULT |
1387 FBINFO_HWACCEL_YPAN; 1388 FBINFO_HWACCEL_YPAN;
1388 1389
1389 i = (vga16fb_defined.bits_per_pixel == 8) ? 256 : 16; 1390 i = (info->var.bits_per_pixel == 8) ? 256 : 16;
1390 ret = fb_alloc_cmap(&vga16fb.cmap, i, 0); 1391 ret = fb_alloc_cmap(&info->cmap, i, 0);
1391 if (ret) { 1392 if (ret) {
1392 printk(KERN_ERR "vga16fb: unable to allocate colormap\n"); 1393 printk(KERN_ERR "vga16fb: unable to allocate colormap\n");
1393 ret = -ENOMEM; 1394 ret = -ENOMEM;
1394 goto err_alloc_cmap; 1395 goto err_alloc_cmap;
1395 } 1396 }
1396 1397
1397 if (vga16fb_check_var(&vga16fb.var, &vga16fb)) { 1398 if (vga16fb_check_var(&info->var, info)) {
1398 printk(KERN_ERR "vga16fb: unable to validate variable\n"); 1399 printk(KERN_ERR "vga16fb: unable to validate variable\n");
1399 ret = -EINVAL; 1400 ret = -EINVAL;
1400 goto err_check_var; 1401 goto err_check_var;
1401 } 1402 }
1402 1403
1403 vga16fb_update_fix(&vga16fb); 1404 vga16fb_update_fix(info);
1404 1405
1405 if (register_framebuffer(&vga16fb) < 0) { 1406 if (register_framebuffer(info) < 0) {
1406 printk(KERN_ERR "vga16fb: unable to register framebuffer\n"); 1407 printk(KERN_ERR "vga16fb: unable to register framebuffer\n");
1407 ret = -EINVAL; 1408 ret = -EINVAL;
1408 goto err_check_var; 1409 goto err_check_var;
1409 } 1410 }
1410 1411
1411 printk(KERN_INFO "fb%d: %s frame buffer device\n", 1412 printk(KERN_INFO "fb%d: %s frame buffer device\n",
1412 vga16fb.node, vga16fb.fix.id); 1413 info->node, info->fix.id);
1414 dev_set_drvdata(device, info);
1413 1415
1414 return 0; 1416 return 0;
1415 1417
1416 err_check_var: 1418 err_check_var:
1417 fb_dealloc_cmap(&vga16fb.cmap); 1419 fb_dealloc_cmap(&info->cmap);
1418 err_alloc_cmap: 1420 err_alloc_cmap:
1419 iounmap(vga16fb.screen_base); 1421 iounmap(info->screen_base);
1420 err_ioremap: 1422 err_ioremap:
1423 framebuffer_release(info);
1424 err_fb_alloc:
1425 return ret;
1426}
1427
1428static int vga16fb_remove(struct device *device)
1429{
1430 struct fb_info *info = dev_get_drvdata(device);
1431
1432 if (info) {
1433 unregister_framebuffer(info);
1434 iounmap(info->screen_base);
1435 fb_dealloc_cmap(&info->cmap);
1436 /* XXX unshare VGA regions */
1437 framebuffer_release(info);
1438 }
1439
1440 return 0;
1441}
1442
1443static struct device_driver vga16fb_driver = {
1444 .name = "vga16fb",
1445 .bus = &platform_bus_type,
1446 .probe = vga16fb_probe,
1447 .remove = vga16fb_remove,
1448};
1449
1450static struct platform_device vga16fb_device = {
1451 .name = "vga16fb",
1452};
1453
1454static int __init vga16fb_init(void)
1455{
1456 int ret;
1457#ifndef MODULE
1458 char *option = NULL;
1459
1460 if (fb_get_options("vga16fb", &option))
1461 return -ENODEV;
1462
1463 vga16fb_setup(option);
1464#endif
1465 ret = driver_register(&vga16fb_driver);
1466
1467 if (!ret) {
1468 ret = platform_device_register(&vga16fb_device);
1469 if (ret)
1470 driver_unregister(&vga16fb_driver);
1471 }
1472
1421 return ret; 1473 return ret;
1422} 1474}
1423 1475
1424static void __exit vga16fb_exit(void) 1476static void __exit vga16fb_exit(void)
1425{ 1477{
1426 unregister_framebuffer(&vga16fb); 1478 platform_device_unregister(&vga16fb_device);
1427 iounmap(vga16fb.screen_base); 1479 driver_unregister(&vga16fb_driver);
1428 fb_dealloc_cmap(&vga16fb.cmap);
1429 /* XXX unshare VGA regions */
1430} 1480}
1431 1481
1432MODULE_LICENSE("GPL"); 1482MODULE_LICENSE("GPL");
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index ca92940f3943..d9e01daee630 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -485,11 +485,6 @@ int restore_vga (struct vgastate *state)
485 return 0; 485 return 0;
486} 486}
487 487
488#ifdef MODULE
489int init_module(void) { return 0; };
490void cleanup_module(void) {};
491#endif
492
493EXPORT_SYMBOL(save_vga); 488EXPORT_SYMBOL(save_vga);
494EXPORT_SYMBOL(restore_vga); 489EXPORT_SYMBOL(restore_vga);
495 490
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index cf8cdb108fd9..48e70f153c4b 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -397,7 +397,6 @@ static struct fb_ops w100fb_ops = {
397 .fb_fillrect = cfb_fillrect, 397 .fb_fillrect = cfb_fillrect,
398 .fb_copyarea = cfb_copyarea, 398 .fb_copyarea = cfb_copyarea,
399 .fb_imageblit = cfb_imageblit, 399 .fb_imageblit = cfb_imageblit,
400 .fb_cursor = soft_cursor,
401}; 400};
402 401
403#ifdef CONFIG_PM 402#ifdef CONFIG_PM
diff --git a/drivers/w1/w1_ds2433.c b/drivers/w1/w1_ds2433.c
index 279e0e0363d6..1e3d98aac12d 100644
--- a/drivers/w1/w1_ds2433.c
+++ b/drivers/w1/w1_ds2433.c
@@ -299,10 +299,8 @@ static int w1_f23_add_slave(struct w1_slave *sl)
299static void w1_f23_remove_slave(struct w1_slave *sl) 299static void w1_f23_remove_slave(struct w1_slave *sl)
300{ 300{
301#ifdef CONFIG_W1_F23_CRC 301#ifdef CONFIG_W1_F23_CRC
302 if (sl->family_data) { 302 kfree(sl->family_data);
303 kfree(sl->family_data); 303 sl->family_data = NULL;
304 sl->family_data = NULL;
305 }
306#endif /* CONFIG_W1_F23_CRC */ 304#endif /* CONFIG_W1_F23_CRC */
307 sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr); 305 sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
308} 306}