aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig2
-rw-r--r--drivers/acpi/pci_irq.c1
-rw-r--r--drivers/base/cpu.c11
-rw-r--r--drivers/block/as-iosched.c8
-rw-r--r--drivers/block/deadline-iosched.c8
-rw-r--r--drivers/block/genhd.c25
-rw-r--r--drivers/block/ioctl.c74
-rw-r--r--drivers/block/ll_rw_blk.c184
-rw-r--r--drivers/block/loop.c81
-rw-r--r--drivers/block/pktcdvd.c39
-rw-r--r--drivers/bluetooth/hci_ldisc.c2
-rw-r--r--drivers/cdrom/cm206.c113
-rw-r--r--drivers/cdrom/sonycd535.c3
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/amiserial.c22
-rw-r--r--drivers/char/applicom.c2
-rw-r--r--drivers/char/drm/Kconfig2
-rw-r--r--drivers/char/drm/i915_dma.c24
-rw-r--r--drivers/char/drm/i915_drm.h27
-rw-r--r--drivers/char/drm/i915_drv.c25
-rw-r--r--drivers/char/drm/i915_drv.h24
-rw-r--r--drivers/char/drm/i915_irq.c24
-rw-r--r--drivers/char/drm/i915_mem.c24
-rw-r--r--drivers/char/drm/radeon_irq.c27
-rw-r--r--drivers/char/ds1620.c3
-rw-r--r--drivers/char/ftape/compressor/zftape-compress.c4
-rw-r--r--drivers/char/hpet.c2
-rw-r--r--drivers/char/i8k.c909
-rw-r--r--drivers/char/ip2/i2cmd.c6
-rw-r--r--drivers/char/ip2/i2cmd.h12
-rw-r--r--drivers/char/ip2main.c10
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c196
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c46
-rw-r--r--drivers/char/ipmi/ipmi_poweroff.c137
-rw-r--r--drivers/char/isicom.c12
-rw-r--r--drivers/char/istallion.c3
-rw-r--r--drivers/char/mem.c53
-rw-r--r--drivers/char/misc.c8
-rw-r--r--drivers/char/mwave/3780i.c6
-rw-r--r--drivers/char/mwave/3780i.h4
-rw-r--r--drivers/char/mwave/tp3780i.c14
-rw-r--r--drivers/char/n_hdlc.c2
-rw-r--r--drivers/char/n_r3964.c2
-rw-r--r--drivers/char/nvram.c6
-rw-r--r--drivers/char/rio/func.h1
-rw-r--r--drivers/char/rio/rio_linux.c5
-rw-r--r--drivers/char/rio/rioinit.c7
-rw-r--r--drivers/char/rio/riotty.c15
-rw-r--r--drivers/char/rocket.c226
-rw-r--r--drivers/char/rocket_int.h40
-rw-r--r--drivers/char/sysrq.c24
-rw-r--r--drivers/char/toshiba.c60
-rw-r--r--drivers/char/tpm/tpm.c360
-rw-r--r--drivers/char/tpm/tpm.h38
-rw-r--r--drivers/char/tpm/tpm_atmel.c63
-rw-r--r--drivers/char/tpm/tpm_nsc.c199
-rw-r--r--drivers/char/tty_io.c47
-rw-r--r--drivers/char/watchdog/Kconfig10
-rw-r--r--drivers/char/watchdog/Makefile1
-rw-r--r--drivers/char/watchdog/wdrtas.c696
-rw-r--r--drivers/firmware/efivars.c7
-rw-r--r--drivers/firmware/pcdp.c11
-rw-r--r--drivers/firmware/pcdp.h2
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c3
-rw-r--r--drivers/i2c/busses/i2c-mpc.c204
-rw-r--r--drivers/ide/ide-cd.c89
-rw-r--r--drivers/ide/ide-disk.c3
-rw-r--r--drivers/ide/ide-floppy.c6
-rw-r--r--drivers/ide/ide-probe.c8
-rw-r--r--drivers/ieee1394/ieee1394_core.c4
-rw-r--r--drivers/ieee1394/nodemgr.c2
-rw-r--r--drivers/input/gameport/gameport.c2
-rw-r--r--drivers/input/serio/i8042.c2
-rw-r--r--drivers/input/serio/serio.c2
-rw-r--r--drivers/input/serio/serport.c2
-rw-r--r--drivers/isdn/act2000/capi.c2
-rw-r--r--drivers/isdn/act2000/capi.h1
-rw-r--r--drivers/isdn/hardware/avm/b1dma.c4
-rw-r--r--drivers/isdn/hardware/avm/c4.c6
-rw-r--r--drivers/isdn/hardware/avm/t1isa.c2
-rw-r--r--drivers/isdn/hisax/Makefile2
-rw-r--r--drivers/isdn/hisax/amd7930_fn.c8
-rw-r--r--drivers/isdn/hisax/asuscom.c4
-rw-r--r--drivers/isdn/hisax/avm_pci.c18
-rw-r--r--drivers/isdn/hisax/bkm_a4t.c4
-rw-r--r--drivers/isdn/hisax/bkm_a8.c6
-rw-r--r--drivers/isdn/hisax/callc.c6
-rw-r--r--drivers/isdn/hisax/config.c14
-rw-r--r--drivers/isdn/hisax/diva.c4
-rw-r--r--drivers/isdn/hisax/elsa.c8
-rw-r--r--drivers/isdn/hisax/elsa_ser.c20
-rw-r--r--drivers/isdn/hisax/enternow.h51
-rw-r--r--drivers/isdn/hisax/enternow_pci.c91
-rw-r--r--drivers/isdn/hisax/gazel.c5
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c2
-rw-r--r--drivers/isdn/hisax/hfc_2bds0.c12
-rw-r--r--drivers/isdn/hisax/hfc_2bs0.c12
-rw-r--r--drivers/isdn/hisax/hfc_pci.c12
-rw-r--r--drivers/isdn/hisax/hfc_pci.h1
-rw-r--r--drivers/isdn/hisax/hfc_sx.c10
-rw-r--r--drivers/isdn/hisax/hfc_sx.h1
-rw-r--r--drivers/isdn/hisax/hfc_usb.c6
-rw-r--r--drivers/isdn/hisax/hfc_usb.h4
-rw-r--r--drivers/isdn/hisax/hfcscard.c2
-rw-r--r--drivers/isdn/hisax/hisax.h5
-rw-r--r--drivers/isdn/hisax/hscx.c4
-rw-r--r--drivers/isdn/hisax/icc.c6
-rw-r--r--drivers/isdn/hisax/ipacx.c86
-rw-r--r--drivers/isdn/hisax/isac.c6
-rw-r--r--drivers/isdn/hisax/isar.c46
-rw-r--r--drivers/isdn/hisax/isdnl1.c8
-rw-r--r--drivers/isdn/hisax/isdnl2.c100
-rw-r--r--drivers/isdn/hisax/isdnl3.c2
-rw-r--r--drivers/isdn/hisax/isurf.c2
-rw-r--r--drivers/isdn/hisax/ix1_micro.c4
-rw-r--r--drivers/isdn/hisax/jade.c6
-rw-r--r--drivers/isdn/hisax/jade.h1
-rw-r--r--drivers/isdn/hisax/l3_1tr6.c2
-rw-r--r--drivers/isdn/hisax/l3dss1.c2
-rw-r--r--drivers/isdn/hisax/l3ni1.c4
-rw-r--r--drivers/isdn/hisax/mic.c4
-rw-r--r--drivers/isdn/hisax/netjet.c12
-rw-r--r--drivers/isdn/hisax/niccy.c4
-rw-r--r--drivers/isdn/hisax/nj_s.c2
-rw-r--r--drivers/isdn/hisax/nj_u.c2
-rw-r--r--drivers/isdn/hisax/q931.c4
-rw-r--r--drivers/isdn/hisax/s0box.c4
-rw-r--r--drivers/isdn/hisax/saphir.c2
-rw-r--r--drivers/isdn/hisax/sedlbauer.c6
-rw-r--r--drivers/isdn/hisax/sportster.c6
-rw-r--r--drivers/isdn/hisax/st5481.h4
-rw-r--r--drivers/isdn/hisax/st5481_hdlc.c580
-rw-r--r--drivers/isdn/hisax/st5481_hdlc.h62
-rw-r--r--drivers/isdn/hisax/st5481_usb.c10
-rw-r--r--drivers/isdn/hisax/tei.c2
-rw-r--r--drivers/isdn/hisax/teleint.c4
-rw-r--r--drivers/isdn/hisax/teles0.c4
-rw-r--r--drivers/isdn/hisax/teles3.c4
-rw-r--r--drivers/isdn/hisax/telespci.c4
-rw-r--r--drivers/isdn/hisax/w6692.c6
-rw-r--r--drivers/isdn/i4l/isdn_audio.c10
-rw-r--r--drivers/isdn/i4l/isdn_audio.h1
-rw-r--r--drivers/isdn/i4l/isdn_common.c6
-rw-r--r--drivers/isdn/i4l/isdn_common.h1
-rw-r--r--drivers/isdn/i4l/isdn_concap.c15
-rw-r--r--drivers/isdn/i4l/isdn_concap.h1
-rw-r--r--drivers/isdn/i4l/isdn_net.c10
-rw-r--r--drivers/isdn/i4l/isdn_tty.c4
-rw-r--r--drivers/isdn/i4l/isdn_tty.h1
-rw-r--r--drivers/isdn/i4l/isdn_ttyfax.c6
-rw-r--r--drivers/isdn/i4l/isdn_x25iface.c36
-rw-r--r--drivers/isdn/pcbit/callbacks.c17
-rw-r--r--drivers/isdn/pcbit/callbacks.h3
-rw-r--r--drivers/isdn/pcbit/capi.c10
-rw-r--r--drivers/isdn/pcbit/capi.h1
-rw-r--r--drivers/isdn/pcbit/drv.c16
-rw-r--r--drivers/isdn/sc/Makefile2
-rw-r--r--drivers/isdn/sc/command.c88
-rw-r--r--drivers/isdn/sc/debug.c46
-rw-r--r--drivers/isdn/sc/init.c21
-rw-r--r--drivers/isdn/sc/interrupt.c2
-rw-r--r--drivers/isdn/sc/ioctl.c5
-rw-r--r--drivers/isdn/sc/packet.c16
-rw-r--r--drivers/isdn/sc/shmem.c2
-rw-r--r--drivers/isdn/sc/timer.c18
-rw-r--r--drivers/macintosh/therm_adt746x.c4
-rw-r--r--drivers/mca/mca-legacy.c1
-rw-r--r--drivers/md/dm-ioctl.c14
-rw-r--r--drivers/md/md.c3
-rw-r--r--drivers/media/common/ir-common.c72
-rw-r--r--drivers/media/common/saa7146_fops.c2
-rw-r--r--drivers/media/dvb/Kconfig2
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/b2c2/Kconfig1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c26
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c11
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h3
-rw-r--r--drivers/media/dvb/dibusb/Kconfig62
-rw-r--r--drivers/media/dvb/dibusb/Makefile11
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-core.c558
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-dvb.c185
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c582
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-firmware.c87
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-remote.c316
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb-usb.c303
-rw-r--r--drivers/media/dvb/dibusb/dvb-dibusb.h327
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c7
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig99
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile30
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c176
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c272
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c316
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c116
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h122
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c282
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.h65
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c (renamed from drivers/media/dvb/dibusb/dvb-fe-dtt200u.c)113
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c171
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.h66
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-common.h44
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c210
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-firmware.c100
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c118
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h83
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c211
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c175
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c211
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h315
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c236
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c162
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045-fe.c196
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c263
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.h78
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/bcm3510.c853
-rw-r--r--drivers/media/dvb/frontends/bcm3510.h40
-rw-r--r--drivers/media/dvb/frontends/bcm3510_priv.h460
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.c2
-rw-r--r--drivers/media/dvb/frontends/dib3000.h5
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c20
-rw-r--r--drivers/media/dvb/frontends/dib3000mb_priv.h2
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c29
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c94
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h9
-rw-r--r--drivers/media/video/Kconfig14
-rw-r--r--drivers/media/video/bt832.c46
-rw-r--r--drivers/media/video/bt832.h36
-rw-r--r--drivers/media/video/bttv-cards.c100
-rw-r--r--drivers/media/video/bttv-driver.c2
-rw-r--r--drivers/media/video/bttv-i2c.c2
-rw-r--r--drivers/media/video/bttv.h3
-rw-r--r--drivers/media/video/bttvp.h8
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c488
-rw-r--r--drivers/media/video/cx88/cx88-cards.c230
-rw-r--r--drivers/media/video/cx88/cx88-core.c28
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c2
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c18
-rw-r--r--drivers/media/video/cx88/cx88-input.c11
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c52
-rw-r--r--drivers/media/video/cx88/cx88-reg.h3
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c103
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c6
-rw-r--r--drivers/media/video/cx88/cx88-video.c59
-rw-r--r--drivers/media/video/cx88/cx88.h22
-rw-r--r--drivers/media/video/ir-kbd-gpio.c34
-rw-r--r--drivers/media/video/msp3400.c11
-rw-r--r--drivers/media/video/msp3400.h4
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c20
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c163
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c8
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c112
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c16
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c21
-rw-r--r--drivers/media/video/saa7134/saa7134-vbi.c14
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c92
-rw-r--r--drivers/media/video/saa7134/saa7134.h17
-rw-r--r--drivers/media/video/tda9887.c40
-rw-r--r--drivers/media/video/tuner-core.c194
-rw-r--r--drivers/media/video/tuner-simple.c53
-rw-r--r--drivers/media/video/tvaudio.c23
-rw-r--r--drivers/media/video/tveeprom.c2
-rw-r--r--drivers/media/video/tvmixer.c4
-rw-r--r--drivers/media/video/v4l1-compat.c10
-rw-r--r--drivers/media/video/video-buf-dvb.c3
-rw-r--r--drivers/message/i2o/Kconfig46
-rw-r--r--drivers/message/i2o/Makefile3
-rw-r--r--drivers/message/i2o/bus-osm.c164
-rw-r--r--drivers/message/i2o/config-osm.c579
-rw-r--r--drivers/message/i2o/core.h58
-rw-r--r--drivers/message/i2o/debug.c3
-rw-r--r--drivers/message/i2o/device.c40
-rw-r--r--drivers/message/i2o/driver.c130
-rw-r--r--drivers/message/i2o/exec-osm.c131
-rw-r--r--drivers/message/i2o/i2o_block.c453
-rw-r--r--drivers/message/i2o/i2o_block.h34
-rw-r--r--drivers/message/i2o/i2o_config.c124
-rw-r--r--drivers/message/i2o/i2o_proc.c6
-rw-r--r--drivers/message/i2o/i2o_scsi.c505
-rw-r--r--drivers/message/i2o/iop.c566
-rw-r--r--drivers/message/i2o/pci.c246
-rw-r--r--drivers/net/8139too.c2
-rw-r--r--drivers/net/e1000/e1000_main.c1
-rw-r--r--drivers/net/hamradio/6pack.c2
-rw-r--r--drivers/net/hamradio/mkiss.c2
-rw-r--r--drivers/net/irda/irtty-sir.c2
-rw-r--r--drivers/net/irda/sir_kthread.c3
-rw-r--r--drivers/net/irda/stir4200.c4
-rw-r--r--drivers/net/ppp_async.c2
-rw-r--r--drivers/net/ppp_synctty.c2
-rw-r--r--drivers/net/slip.c16
-rw-r--r--drivers/net/tg3.c337
-rw-r--r--drivers/net/tg3.h24
-rw-r--r--drivers/net/wan/Kconfig2
-rw-r--r--drivers/net/wan/x25_asy.c2
-rw-r--r--drivers/net/wireless/airo.c2
-rw-r--r--drivers/net/wireless/strip.c2
-rw-r--r--drivers/oprofile/buffer_sync.c29
-rw-r--r--drivers/oprofile/event_buffer.h3
-rw-r--r--drivers/parport/parport_pc.c4
-rw-r--r--drivers/parport/parport_serial.c5
-rw-r--r--drivers/parport/probe.c18
-rw-r--r--drivers/pcmcia/cs.c13
-rw-r--r--drivers/pcmcia/ti113x.h167
-rw-r--r--drivers/pcmcia/yenta_socket.c60
-rw-r--r--drivers/pnp/card.c3
-rw-r--r--drivers/pnp/manager.c1
-rw-r--r--drivers/pnp/pnpbios/core.c2
-rw-r--r--drivers/s390/Kconfig7
-rw-r--r--drivers/s390/block/dasd.c30
-rw-r--r--drivers/s390/block/dasd_proc.c3
-rw-r--r--drivers/s390/block/dcssblk.c48
-rw-r--r--drivers/s390/char/Makefile1
-rw-r--r--drivers/s390/char/con3215.c4
-rw-r--r--drivers/s390/char/con3270.c4
-rw-r--r--drivers/s390/char/tape_34xx.c6
-rw-r--r--drivers/s390/char/tape_core.c2
-rw-r--r--drivers/s390/char/tape_proc.c1
-rw-r--r--drivers/s390/char/vmcp.c219
-rw-r--r--drivers/s390/char/vmcp.h30
-rw-r--r--drivers/s390/char/vmlogrdr.c10
-rw-r--r--drivers/s390/cio/ccwgroup.c30
-rw-r--r--drivers/s390/cio/cio.c8
-rw-r--r--drivers/s390/cio/css.c34
-rw-r--r--drivers/s390/cio/device.c84
-rw-r--r--drivers/s390/cio/qdio.c14
-rw-r--r--drivers/s390/cio/qdio.h16
-rw-r--r--drivers/s390/net/claw.c4
-rw-r--r--drivers/s390/net/ctcdbug.c10
-rw-r--r--drivers/s390/net/ctcdbug.h10
-rw-r--r--drivers/s390/net/iucv.h6
-rw-r--r--drivers/s390/net/lcs.c8
-rw-r--r--drivers/s390/net/netiucv.c12
-rw-r--r--drivers/s390/net/qeth.h14
-rw-r--r--drivers/s390/net/qeth_main.c14
-rw-r--r--drivers/s390/net/smsgiucv.c4
-rw-r--r--drivers/s390/s390mach.c321
-rw-r--r--drivers/s390/s390mach.h35
-rw-r--r--drivers/scsi/dpt_i2o.c24
-rw-r--r--drivers/scsi/dpti.h12
-rw-r--r--drivers/scsi/hosts.c2
-rw-r--r--drivers/scsi/initio.c85
-rw-r--r--drivers/scsi/initio.h18
-rw-r--r--drivers/scsi/scsi.c6
-rw-r--r--drivers/scsi/scsi_debug.c2
-rw-r--r--drivers/scsi/scsi_lib.c2
-rw-r--r--drivers/scsi/scsi_priv.h4
-rw-r--r--drivers/scsi/scsi_sysfs.c4
-rw-r--r--drivers/serial/68328serial.c9
-rw-r--r--drivers/serial/68360serial.c9
-rw-r--r--drivers/serial/8250.c64
-rw-r--r--drivers/serial/8250.h3
-rw-r--r--drivers/serial/au1x00_uart.c10
-rw-r--r--drivers/serial/icom.h2
-rw-r--r--drivers/serial/m32r_sio.c10
-rw-r--r--drivers/serial/mpsc.c8
-rw-r--r--drivers/serial/pxa.c10
-rw-r--r--drivers/serial/s3c2410.c4
-rw-r--r--drivers/serial/sn_console.c1
-rw-r--r--drivers/serial/sunzilog.c8
-rw-r--r--drivers/telephony/ixj.c52
-rw-r--r--drivers/usb/core/hcd.c2
-rw-r--r--drivers/usb/core/hcd.h2
-rw-r--r--drivers/usb/core/hub.c2
-rw-r--r--drivers/usb/core/inode.c13
-rw-r--r--drivers/usb/gadget/file_storage.c3
-rw-r--r--drivers/usb/media/pwc/pwc-uncompress.c11
-rw-r--r--drivers/usb/mon/Kconfig13
-rw-r--r--drivers/usb/mon/Makefile2
-rw-r--r--drivers/usb/storage/usb.c4
-rw-r--r--drivers/video/au1100fb.c18
-rw-r--r--drivers/video/console/Kconfig5
-rw-r--r--drivers/video/fbsysfs.c2
-rw-r--r--drivers/video/matrox/matroxfb_misc.c5
-rw-r--r--drivers/video/pxafb.c3
-rw-r--r--drivers/video/vesafb.c9
-rw-r--r--drivers/w1/w1.c4
380 files changed, 13516 insertions, 8126 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 670fdb5142d..86c52520ed3 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -55,7 +55,7 @@ if ACPI_INTERPRETER
config ACPI_SLEEP
bool "Sleep States (EXPERIMENTAL)"
- depends on X86
+ depends on X86 && (!SMP || SUSPEND_SMP)
depends on EXPERIMENTAL && PM
default y
---help---
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 8093f2e0032..8dbf802ee7f 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -435,6 +435,7 @@ acpi_pci_irq_enable (
/* Interrupt Line values above 0xF are forbidden */
if (dev->irq >= 0 && (dev->irq <= 0xF)) {
printk(" - using IRQ %d\n", dev->irq);
+ acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
return_VALUE(0);
}
else {
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 6ef3069b571..b79badd0f15 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -16,6 +16,11 @@ struct sysdev_class cpu_sysdev_class = {
EXPORT_SYMBOL(cpu_sysdev_class);
#ifdef CONFIG_HOTPLUG_CPU
+int __attribute__((weak)) smp_prepare_cpu (int cpu)
+{
+ return 0;
+}
+
static ssize_t show_online(struct sys_device *dev, char *buf)
{
struct cpu *cpu = container_of(dev, struct cpu, sysdev);
@@ -36,7 +41,11 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
kobject_hotplug(&dev->kobj, KOBJ_OFFLINE);
break;
case '1':
- ret = cpu_up(cpu->sysdev.id);
+ ret = smp_prepare_cpu(cpu->sysdev.id);
+ if (!ret)
+ ret = cpu_up(cpu->sysdev.id);
+ if (!ret)
+ kobject_hotplug(&dev->kobj, KOBJ_ONLINE);
break;
default:
ret = -EINVAL;
diff --git a/drivers/block/as-iosched.c b/drivers/block/as-iosched.c
index 638db06de2b..3410b4d294b 100644
--- a/drivers/block/as-iosched.c
+++ b/drivers/block/as-iosched.c
@@ -1871,20 +1871,22 @@ static int as_init_queue(request_queue_t *q, elevator_t *e)
if (!arq_pool)
return -ENOMEM;
- ad = kmalloc(sizeof(*ad), GFP_KERNEL);
+ ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node);
if (!ad)
return -ENOMEM;
memset(ad, 0, sizeof(*ad));
ad->q = q; /* Identify what queue the data belongs to */
- ad->hash = kmalloc(sizeof(struct list_head)*AS_HASH_ENTRIES,GFP_KERNEL);
+ ad->hash = kmalloc_node(sizeof(struct list_head)*AS_HASH_ENTRIES,
+ GFP_KERNEL, q->node);
if (!ad->hash) {
kfree(ad);
return -ENOMEM;
}
- ad->arq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, arq_pool);
+ ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
+ mempool_free_slab, arq_pool, q->node);
if (!ad->arq_pool) {
kfree(ad->hash);
kfree(ad);
diff --git a/drivers/block/deadline-iosched.c b/drivers/block/deadline-iosched.c
index 7f79f3dd016..4bc2fea7327 100644
--- a/drivers/block/deadline-iosched.c
+++ b/drivers/block/deadline-iosched.c
@@ -711,18 +711,20 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e)
if (!drq_pool)
return -ENOMEM;
- dd = kmalloc(sizeof(*dd), GFP_KERNEL);
+ dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node);
if (!dd)
return -ENOMEM;
memset(dd, 0, sizeof(*dd));
- dd->hash = kmalloc(sizeof(struct list_head)*DL_HASH_ENTRIES,GFP_KERNEL);
+ dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES,
+ GFP_KERNEL, q->node);
if (!dd->hash) {
kfree(dd);
return -ENOMEM;
}
- dd->drq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, drq_pool);
+ dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
+ mempool_free_slab, drq_pool, q->node);
if (!dd->drq_pool) {
kfree(dd->hash);
kfree(dd);
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index 53f7d846b74..47fd3659a06 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -40,7 +40,7 @@ static inline int major_to_index(int major)
#ifdef CONFIG_PROC_FS
/* get block device names in somewhat random order */
-int get_blkdev_list(char *p)
+int get_blkdev_list(char *p, int used)
{
struct blk_major_name *n;
int i, len;
@@ -49,10 +49,18 @@ int get_blkdev_list(char *p)
down(&block_subsys_sem);
for (i = 0; i < ARRAY_SIZE(major_names); i++) {
- for (n = major_names[i]; n; n = n->next)
+ for (n = major_names[i]; n; n = n->next) {
+ /*
+ * If the curent string plus the 5 extra characters
+ * in the line would run us off the page, then we're done
+ */
+ if ((len + used + strlen(n->name) + 5) >= PAGE_SIZE)
+ goto page_full;
len += sprintf(p+len, "%3d %s\n",
n->major, n->name);
+ }
}
+page_full:
up(&block_subsys_sem);
return len;
@@ -582,10 +590,16 @@ struct seq_operations diskstats_op = {
.show = diskstats_show
};
-
struct gendisk *alloc_disk(int minors)
{
- struct gendisk *disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
+ return alloc_disk_node(minors, -1);
+}
+
+struct gendisk *alloc_disk_node(int minors, int node_id)
+{
+ struct gendisk *disk;
+
+ disk = kmalloc_node(sizeof(struct gendisk), GFP_KERNEL, node_id);
if (disk) {
memset(disk, 0, sizeof(struct gendisk));
if (!init_disk_stats(disk)) {
@@ -594,7 +608,7 @@ struct gendisk *alloc_disk(int minors)
}
if (minors > 1) {
int size = (minors - 1) * sizeof(struct hd_struct *);
- disk->part = kmalloc(size, GFP_KERNEL);
+ disk->part = kmalloc_node(size, GFP_KERNEL, node_id);
if (!disk->part) {
kfree(disk);
return NULL;
@@ -610,6 +624,7 @@ struct gendisk *alloc_disk(int minors)
}
EXPORT_SYMBOL(alloc_disk);
+EXPORT_SYMBOL(alloc_disk_node);
struct kobject *get_disk(struct gendisk *disk)
{
diff --git a/drivers/block/ioctl.c b/drivers/block/ioctl.c
index 6d7bcc9da9e..6e278474f9a 100644
--- a/drivers/block/ioctl.c
+++ b/drivers/block/ioctl.c
@@ -133,11 +133,9 @@ static int put_u64(unsigned long arg, u64 val)
return put_user(val, (u64 __user *)arg);
}
-int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
- unsigned long arg)
+static int blkdev_locked_ioctl(struct file *file, struct block_device *bdev,
+ unsigned cmd, unsigned long arg)
{
- struct block_device *bdev = inode->i_bdev;
- struct gendisk *disk = bdev->bd_disk;
struct backing_dev_info *bdi;
int ret, n;
@@ -190,36 +188,72 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
return put_ulong(arg, bdev->bd_inode->i_size >> 9);
case BLKGETSIZE64:
return put_u64(arg, bdev->bd_inode->i_size);
+ }
+ return -ENOIOCTLCMD;
+}
+
+static int blkdev_driver_ioctl(struct inode *inode, struct file *file,
+ struct gendisk *disk, unsigned cmd, unsigned long arg)
+{
+ int ret;
+ if (disk->fops->unlocked_ioctl)
+ return disk->fops->unlocked_ioctl(file, cmd, arg);
+
+ if (disk->fops->ioctl) {
+ lock_kernel();
+ ret = disk->fops->ioctl(inode, file, cmd, arg);
+ unlock_kernel();
+ return ret;
+ }
+
+ return -ENOTTY;
+}
+
+int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
+ unsigned long arg)
+{
+ struct block_device *bdev = inode->i_bdev;
+ struct gendisk *disk = bdev->bd_disk;
+ int ret, n;
+
+ switch(cmd) {
case BLKFLSBUF:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (disk->fops->ioctl) {
- ret = disk->fops->ioctl(inode, file, cmd, arg);
- /* -EINVAL to handle old uncorrected drivers */
- if (ret != -EINVAL && ret != -ENOTTY)
- return ret;
- }
+
+ ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
+ /* -EINVAL to handle old uncorrected drivers */
+ if (ret != -EINVAL && ret != -ENOTTY)
+ return ret;
+
+ lock_kernel();
fsync_bdev(bdev);
invalidate_bdev(bdev, 0);
+ unlock_kernel();
return 0;
+
case BLKROSET:
- if (disk->fops->ioctl) {
- ret = disk->fops->ioctl(inode, file, cmd, arg);
- /* -EINVAL to handle old uncorrected drivers */
- if (ret != -EINVAL && ret != -ENOTTY)
- return ret;
- }
+ ret = blkdev_driver_ioctl(inode, file, disk, cmd, arg);
+ /* -EINVAL to handle old uncorrected drivers */
+ if (ret != -EINVAL && ret != -ENOTTY)
+ return ret;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (get_user(n, (int __user *)(arg)))
return -EFAULT;
+ lock_kernel();
set_device_ro(bdev, n);
+ unlock_kernel();
return 0;
- default:
- if (disk->fops->ioctl)
- return disk->fops->ioctl(inode, file, cmd, arg);
}
- return -ENOTTY;
+
+ lock_kernel();
+ ret = blkdev_locked_ioctl(file, bdev, cmd, arg);
+ unlock_kernel();
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+
+ return blkdev_driver_ioctl(inode, file, disk, cmd, arg);
}
/* Most of the generic ioctls are handled in the normal fallback path.
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 81fe3a0c1fe..60e64091de1 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/swap.h>
#include <linux/writeback.h>
+#include <linux/blkdev.h>
/*
* for max sense size
@@ -36,6 +37,7 @@
static void blk_unplug_work(void *data);
static void blk_unplug_timeout(unsigned long data);
+static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io);
/*
* For the allocated request tables
@@ -716,7 +718,7 @@ struct request *blk_queue_find_tag(request_queue_t *q, int tag)
{
struct blk_queue_tag *bqt = q->queue_tags;
- if (unlikely(bqt == NULL || tag >= bqt->real_max_depth))
+ if (unlikely(bqt == NULL || tag >= bqt->max_depth))
return NULL;
return bqt->tag_index[tag];
@@ -774,9 +776,9 @@ EXPORT_SYMBOL(blk_queue_free_tags);
static int
init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth)
{
- int bits, i;
struct request **tag_index;
unsigned long *tag_map;
+ int nr_ulongs;
if (depth > q->nr_requests * 2) {
depth = q->nr_requests * 2;
@@ -788,24 +790,17 @@ init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth)
if (!tag_index)
goto fail;
- bits = (depth / BLK_TAGS_PER_LONG) + 1;
- tag_map = kmalloc(bits * sizeof(unsigned long), GFP_ATOMIC);
+ nr_ulongs = ALIGN(depth, BITS_PER_LONG) / BITS_PER_LONG;
+ tag_map = kmalloc(nr_ulongs * sizeof(unsigned long), GFP_ATOMIC);
if (!tag_map)
goto fail;
memset(tag_index, 0, depth * sizeof(struct request *));
- memset(tag_map, 0, bits * sizeof(unsigned long));
+ memset(tag_map, 0, nr_ulongs * sizeof(unsigned long));
tags->max_depth = depth;
- tags->real_max_depth = bits * BITS_PER_LONG;
tags->tag_index = tag_index;
tags->tag_map = tag_map;
- /*
- * set the upper bits if the depth isn't a multiple of the word size
- */
- for (i = depth; i < bits * BLK_TAGS_PER_LONG; i++)
- __set_bit(i, tag_map);
-
return 0;
fail:
kfree(tag_index);
@@ -870,32 +865,24 @@ int blk_queue_resize_tags(request_queue_t *q, int new_depth)
struct blk_queue_tag *bqt = q->queue_tags;
struct request **tag_index;
unsigned long *tag_map;
- int bits, max_depth;
+ int max_depth, nr_ulongs;
if (!bqt)
return -ENXIO;
/*
- * don't bother sizing down
- */
- if (new_depth <= bqt->real_max_depth) {
- bqt->max_depth = new_depth;
- return 0;
- }
-
- /*
* save the old state info, so we can copy it back
*/
tag_index = bqt->tag_index;
tag_map = bqt->tag_map;
- max_depth = bqt->real_max_depth;
+ max_depth = bqt->max_depth;
if (init_tag_map(q, bqt, new_depth))
return -ENOMEM;
memcpy(bqt->tag_index, tag_index, max_depth * sizeof(struct request *));
- bits = max_depth / BLK_TAGS_PER_LONG;
- memcpy(bqt->tag_map, tag_map, bits * sizeof(unsigned long));
+ nr_ulongs = ALIGN(max_depth, BITS_PER_LONG) / BITS_PER_LONG;
+ memcpy(bqt->tag_map, tag_map, nr_ulongs * sizeof(unsigned long));
kfree(tag_index);
kfree(tag_map);
@@ -925,11 +912,16 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq)
BUG_ON(tag == -1);
- if (unlikely(tag >= bqt->real_max_depth))
+ if (unlikely(tag >= bqt->max_depth))
+ /*
+ * This can happen after tag depth has been reduced.
+ * FIXME: how about a warning or info message here?
+ */
return;
if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) {
- printk("attempt to clear non-busy tag (%d)\n", tag);
+ printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
+ __FUNCTION__, tag);
return;
}
@@ -938,7 +930,8 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq)
rq->tag = -1;
if (unlikely(bqt->tag_index[tag] == NULL))
- printk("tag %d is missing\n", tag);
+ printk(KERN_ERR "%s: tag %d is missing\n",
+ __FUNCTION__, tag);
bqt->tag_index[tag] = NULL;
bqt->busy--;
@@ -967,24 +960,20 @@ EXPORT_SYMBOL(blk_queue_end_tag);
int blk_queue_start_tag(request_queue_t *q, struct request *rq)
{
struct blk_queue_tag *bqt = q->queue_tags;
- unsigned long *map = bqt->tag_map;
- int tag = 0;
+ int tag;
if (unlikely((rq->flags & REQ_QUEUED))) {
printk(KERN_ERR
- "request %p for device [%s] already tagged %d",
- rq, rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag);
+ "%s: request %p for device [%s] already tagged %d",
+ __FUNCTION__, rq,
+ rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->tag);
BUG();
}
- for (map = bqt->tag_map; *map == -1UL; map++) {
- tag += BLK_TAGS_PER_LONG;
-
- if (tag >= bqt->max_depth)
- return 1;
- }
+ tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth);
+ if (tag >= bqt->max_depth)
+ return 1;
- tag += ffz(*map);
__set_bit(tag, bqt->tag_map);
rq->flags |= REQ_QUEUED;
@@ -1020,7 +1009,8 @@ void blk_queue_invalidate_tags(request_queue_t *q)
rq = list_entry_rq(tmp);
if (rq->tag == -1) {
- printk("bad tag found on list\n");
+ printk(KERN_ERR
+ "%s: bad tag found on list\n", __FUNCTION__);
list_del_init(&rq->queuelist);
rq->flags &= ~REQ_QUEUED;
} else
@@ -1148,7 +1138,7 @@ new_hw_segment:
}
-int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
+static int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
struct bio *nxt)
{
if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER)))
@@ -1169,9 +1159,7 @@ int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
return 0;
}
-EXPORT_SYMBOL(blk_phys_contig_segment);
-
-int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
+static int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
struct bio *nxt)
{
if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
@@ -1187,8 +1175,6 @@ int blk_hw_contig_segment(request_queue_t *q, struct bio *bio,
return 1;
}
-EXPORT_SYMBOL(blk_hw_contig_segment);
-
/*
* map a request to scatterlist, return number of sg entries setup. Caller
* must make sure sg can hold rq->nr_phys_segments entries
@@ -1358,8 +1344,8 @@ static int ll_front_merge_fn(request_queue_t *q, struct request *req,
static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
struct request *next)
{
- int total_phys_segments = req->nr_phys_segments +next->nr_phys_segments;
- int total_hw_segments = req->nr_hw_segments + next->nr_hw_segments;
+ int total_phys_segments;
+ int total_hw_segments;
/*
* First check if the either of the requests are re-queued
@@ -1369,7 +1355,7 @@ static int ll_merge_requests_fn(request_queue_t *q, struct request *req,
return 0;
/*
- * Will it become to large?
+ * Will it become too large?
*/
if ((req->nr_sectors + next->nr_sectors) > q->max_sectors)
return 0;
@@ -1450,7 +1436,7 @@ EXPORT_SYMBOL(blk_remove_plug);
*/
void __generic_unplug_device(request_queue_t *q)
{
- if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
+ if (unlikely(test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)))
return;
if (!blk_remove_plug(q))
@@ -1645,7 +1631,8 @@ static int blk_init_free_list(request_queue_t *q)
init_waitqueue_head(&rl->wait[WRITE]);
init_waitqueue_head(&rl->drain);
- rl->rq_pool = mempool_create(BLKDEV_MIN_RQ, mempool_alloc_slab, mempool_free_slab, request_cachep);
+ rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
+ mempool_free_slab, request_cachep, q->node);
if (!rl->rq_pool)
return -ENOMEM;
@@ -1657,8 +1644,15 @@ static int __make_request(request_queue_t *, struct bio *);
request_queue_t *blk_alloc_queue(int gfp_mask)
{
- request_queue_t *q = kmem_cache_alloc(requestq_cachep, gfp_mask);
+ return blk_alloc_queue_node(gfp_mask, -1);
+}
+EXPORT_SYMBOL(blk_alloc_queue);
+
+request_queue_t *blk_alloc_queue_node(int gfp_mask, int node_id)
+{
+ request_queue_t *q;
+ q = kmem_cache_alloc_node(requestq_cachep, gfp_mask, node_id);
if (!q)
return NULL;
@@ -1671,8 +1665,7 @@ request_queue_t *blk_alloc_queue(int gfp_mask)
return q;
}
-
-EXPORT_SYMBOL(blk_alloc_queue);
+EXPORT_SYMBOL(blk_alloc_queue_node);
/**
* blk_init_queue - prepare a request queue for use with a block device
@@ -1705,13 +1698,22 @@ EXPORT_SYMBOL(blk_alloc_queue);
* blk_init_queue() must be paired with a blk_cleanup_queue() call
* when the block device is deactivated (such as at module unload).
**/
+
request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock)
{
- request_queue_t *q = blk_alloc_queue(GFP_KERNEL);
+ return blk_init_queue_node(rfn, lock, -1);
+}
+EXPORT_SYMBOL(blk_init_queue);
+
+request_queue_t *
+blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id)
+{
+ request_queue_t *q = blk_alloc_queue_node(GFP_KERNEL, node_id);
if (!q)
return NULL;
+ q->node = node_id;
if (blk_init_free_list(q))
goto out_init;
@@ -1754,12 +1756,11 @@ out_init:
kmem_cache_free(requestq_cachep, q);
return NULL;
}
-
-EXPORT_SYMBOL(blk_init_queue);
+EXPORT_SYMBOL(blk_init_queue_node);
int blk_get_queue(request_queue_t *q)
{
- if (!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)) {
+ if (likely(!test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
atomic_inc(&q->refcnt);
return 0;
}
@@ -1821,7 +1822,7 @@ static inline int ioc_batching(request_queue_t *q, struct io_context *ioc)
* is the behaviour we want though - once it gets a wakeup it should be given
* a nice run.
*/
-void ioc_set_batching(request_queue_t *q, struct io_context *ioc)
+static void ioc_set_batching(request_queue_t *q, struct io_context *ioc)
{
if (!ioc || ioc_batching(q, ioc))
return;
@@ -1838,7 +1839,6 @@ static void __freed_request(request_queue_t *q, int rw)
clear_queue_congested(q, rw);
if (rl->count[rw] + 1 <= q->nr_requests) {
- smp_mb();
if (waitqueue_active(&rl->wait[rw]))
wake_up(&rl->wait[rw]);
@@ -1966,7 +1966,6 @@ static struct request *get_request_wait(request_queue_t *q, int rw)
DEFINE_WAIT(wait);
struct request *rq;
- generic_unplug_device(q);
do {
struct request_list *rl = &q->rq;
@@ -1978,6 +1977,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw)
if (!rq) {
struct io_context *ioc;
+ generic_unplug_device(q);
io_schedule();
/*
@@ -2251,45 +2251,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
EXPORT_SYMBOL(blkdev_issue_flush);
-/**
- * blkdev_scsi_issue_flush_fn - issue flush for SCSI devices
- * @q: device queue
- * @disk: gendisk
- * @error_sector: error offset
- *
- * Description:
- * Devices understanding the SCSI command set, can use this function as
- * a helper for issuing a cache flush. Note: driver is required to store
- * the error offset (in case of error flushing) in ->sector of struct
- * request.
- */
-int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT);
- int ret;
-
- rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
- rq->sector = 0;
- memset(rq->cmd, 0, sizeof(rq->cmd));
- rq->cmd[0] = 0x35;
- rq->cmd_len = 12;
- rq->data = NULL;
- rq->data_len = 0;
- rq->timeout = 60 * HZ;
-
- ret = blk_execute_rq(q, disk, rq);
-
- if (ret && error_sector)
- *error_sector = rq->sector;
-
- blk_put_request(rq);
- return ret;
-}
-
-EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn);
-
-void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
+static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
{
int rw = rq_data_dir(rq);
@@ -2548,16 +2510,6 @@ void blk_attempt_remerge(request_queue_t *q, struct request *rq)
EXPORT_SYMBOL(blk_attempt_remerge);
-/*
- * Non-locking blk_attempt_remerge variant.
- */
-void __blk_attempt_remerge(request_queue_t *q, struct request *rq)
-{
- attempt_back_merge(q, rq);
-}
-
-EXPORT_SYMBOL(__blk_attempt_remerge);
-
static int __make_request(request_queue_t *q, struct bio *bio)
{
struct request *req, *freereq = NULL;
@@ -2581,7 +2533,7 @@ static int __make_request(request_queue_t *q, struct bio *bio)
spin_lock_prefetch(q->queue_lock);
barrier = bio_barrier(bio);
- if (barrier && (q->ordered == QUEUE_ORDERED_NONE)) {
+ if (unlikely(barrier) && (q->ordered == QUEUE_ORDERED_NONE)) {
err = -EOPNOTSUPP;
goto end_io;
}
@@ -2682,7 +2634,7 @@ get_rq:
/*
* REQ_BARRIER implies no merging, but lets make it explicit
*/
- if (barrier)
+ if (unlikely(barrier))
req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
req->errors = 0;
@@ -2806,7 +2758,7 @@ static inline void block_wait_queue_running(request_queue_t *q)
{
DEFINE_WAIT(wait);
- while (test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags)) {
+ while (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) {
struct request_list *rl = &q->rq;
prepare_to_wait_exclusive(&rl->drain, &wait,
@@ -2915,7 +2867,7 @@ end_io:
goto end_io;
}
- if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))
+ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
goto end_io;
block_wait_queue_running(q);
@@ -2968,7 +2920,7 @@ void submit_bio(int rw, struct bio *bio)
EXPORT_SYMBOL(submit_bio);
-void blk_recalc_rq_segments(struct request *rq)
+static void blk_recalc_rq_segments(struct request *rq)
{
struct bio *bio, *prevbio = NULL;
int nr_phys_segs, nr_hw_segs;
@@ -3010,7 +2962,7 @@ void blk_recalc_rq_segments(struct request *rq)
rq->nr_hw_segments = nr_hw_segs;
}
-void blk_recalc_rq_sectors(struct request *rq, int nsect)
+static void blk_recalc_rq_sectors(struct request *rq, int nsect)
{
if (blk_fs_request(rq)) {
rq->hard_sector += nsect;
@@ -3598,7 +3550,7 @@ static struct sysfs_ops queue_sysfs_ops = {
.store = queue_attr_store,
};
-struct kobj_type queue_ktype = {
+static struct kobj_type queue_ktype = {
.sysfs_ops = &queue_sysfs_ops,
.default_attrs = default_attrs,
};
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 6f011d0d8e9..b35e08876dd 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -472,17 +472,11 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
*/
static void loop_add_bio(struct loop_device *lo, struct bio *bio)
{
- unsigned long flags;
-
- spin_lock_irqsave(&lo->lo_lock, flags);
if (lo->lo_biotail) {
lo->lo_biotail->bi_next = bio;
lo->lo_biotail = bio;
} else
lo->lo_bio = lo->lo_biotail = bio;
- spin_unlock_irqrestore(&lo->lo_lock, flags);
-
- up(&lo->lo_bh_mutex);
}
/*
@@ -492,14 +486,12 @@ static struct bio *loop_get_bio(struct loop_device *lo)
{
struct bio *bio;
- spin_lock_irq(&lo->lo_lock);
if ((bio = lo->lo_bio)) {
if (bio == lo->lo_biotail)
lo->lo_biotail = NULL;
lo->lo_bio = bio->bi_next;
bio->bi_next = NULL;
}
- spin_unlock_irq(&lo->lo_lock);
return bio;
}
@@ -509,35 +501,28 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio)
struct loop_device *lo = q->queuedata;
int rw = bio_rw(old_bio);
- if (!lo)
- goto out;
+ if (rw == READA)
+ rw = READ;
+
+ BUG_ON(!lo || (rw != READ && rw != WRITE));
spin_lock_irq(&lo->lo_lock);
if (lo->lo_state != Lo_bound)
- goto inactive;
- atomic_inc(&lo->lo_pending);
- spin_unlock_irq(&lo->lo_lock);
-
- if (rw == WRITE) {
- if (lo->lo_flags & LO_FLAGS_READ_ONLY)
- goto err;
- } else if (rw == READA) {
- rw = READ;
- } else if (rw != READ) {
- printk(KERN_ERR "loop: unknown command (%x)\n", rw);
- goto err;
- }
+ goto out;
+ if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))
+ goto out;
+ lo->lo_pending++;
loop_add_bio(lo, old_bio);
+ spin_unlock_irq(&lo->lo_lock);
+ up(&lo->lo_bh_mutex);
return 0;
-err:
- if (atomic_dec_and_test(&lo->lo_pending))
- up(&lo->lo_bh_mutex);
+
out:
+ if (lo->lo_pending == 0)
+ up(&lo->lo_bh_mutex);
+ spin_unlock_irq(&lo->lo_lock);
bio_io_error(old_bio, old_bio->bi_size);
return 0;
-inactive:
- spin_unlock_irq(&lo->lo_lock);
- goto out;
}
/*
@@ -560,13 +545,11 @@ static void do_loop_switch(struct loop_device *, struct switch_request *);
static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio)
{
- int ret;
-
if (unlikely(!bio->bi_bdev)) {
do_loop_switch(lo, bio->bi_private);
bio_put(bio);
} else {
- ret = do_bio_filebacked(lo, bio);
+ int ret = do_bio_filebacked(lo, bio);
bio_endio(bio, bio->bi_size, ret);
}
}
@@ -594,7 +577,7 @@ static int loop_thread(void *data)
set_user_nice(current, -20);
lo->lo_state = Lo_bound;
- atomic_inc(&lo->lo_pending);
+ lo->lo_pending = 1;
/*
* up sem, we are running
@@ -602,26 +585,37 @@ static int loop_thread(void *data)
up(&lo->lo_sem);
for (;;) {
- down_interruptible(&lo->lo_bh_mutex);
+ int pending;
+
/*
- * could be upped because of tear-down, not because of
- * pending work
+ * interruptible just to not contribute to load avg
*/
- if (!atomic_read(&lo->lo_pending))
+ if (down_interruptible(&lo->lo_bh_mutex))
+ continue;
+
+ spin_lock_irq(&lo->lo_lock);
+
+ /*
+ * could be upped because of tear-down, not pending work
+ */
+ if (unlikely(!lo->lo_pending)) {
+ spin_unlock_irq(&lo->lo_lock);
break;
+ }
bio = loop_get_bio(lo);
- if (!bio) {
- printk("loop: missing bio\n");
- continue;
- }
+ lo->lo_pending--;
+ pending = lo->lo_pending;
+ spin_unlock_irq(&lo->lo_lock);
+
+ BUG_ON(!bio);
loop_handle_bio(lo, bio);
/*
* upped both for pending work and tear-down, lo_pending
* will hit zero then
*/
- if (atomic_dec_and_test(&lo->lo_pending))
+ if (unlikely(!pending))
break;
}
@@ -900,7 +894,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
spin_lock_irq(&lo->lo_lock);
lo->lo_state = Lo_rundown;
- if (atomic_dec_and_test(&lo->lo_pending))
+ lo->lo_pending--;
+ if (!lo->lo_pending)
up(&lo->lo_bh_mutex);
spin_unlock_irq(&lo->lo_lock);
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index bc56770bcc9..7b838342f0a 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -467,14 +467,12 @@ static int pkt_set_speed(struct pktcdvd_device *pd, unsigned write_speed, unsign
* Queue a bio for processing by the low-level CD device. Must be called
* from process context.
*/
-static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio, int high_prio_read)
+static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
{
spin_lock(&pd->iosched.lock);
if (bio_data_dir(bio) == READ) {
pkt_add_list_last(bio, &pd->iosched.read_queue,
&pd->iosched.read_queue_tail);
- if (high_prio_read)
- pd->iosched.high_prio_read = 1;
} else {
pkt_add_list_last(bio, &pd->iosched.write_queue,
&pd->iosched.write_queue_tail);
@@ -490,15 +488,16 @@ static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio, int high_p
* requirements for CDRW drives:
* - A cache flush command must be inserted before a read request if the
* previous request was a write.
- * - Switching between reading and writing is slow, so don't it more often
+ * - Switching between reading and writing is slow, so don't do it more often
* than necessary.
+ * - Optimize for throughput at the expense of latency. This means that streaming
+ * writes will never be interrupted by a read, but if the drive has to seek
+ * before the next write, switch to reading instead if there are any pending
+ * read requests.
* - Set the read speed according to current usage pattern. When only reading
* from the device, it's best to use the highest possible read speed, but
* when switching often between reading and writing, it's better to have the
* same read and write speeds.
- * - Reads originating from user space should have higher priority than reads
- * originating from pkt_gather_data, because some process is usually waiting
- * on reads of the first kind.
*/
static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
{
@@ -512,21 +511,24 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
for (;;) {
struct bio *bio;
- int reads_queued, writes_queued, high_prio_read;
+ int reads_queued, writes_queued;
spin_lock(&pd->iosched.lock);
reads_queued = (pd->iosched.read_queue != NULL);
writes_queued = (pd->iosched.write_queue != NULL);
- if (!reads_queued)
- pd->iosched.high_prio_read = 0;
- high_prio_read = pd->iosched.high_prio_read;
spin_unlock(&pd->iosched.lock);
if (!reads_queued && !writes_queued)
break;
if (pd->iosched.writing) {
- if (high_prio_read || (!writes_queued && reads_queued)) {
+ int need_write_seek = 1;
+ spin_lock(&pd->iosched.lock);
+ bio = pd->iosched.write_queue;
+ spin_unlock(&pd->iosched.lock);
+ if (bio && (bio->bi_sector == pd->iosched.last_write))
+ need_write_seek = 0;
+ if (need_write_seek && reads_queued) {
if (atomic_read(&pd->cdrw.pending_bios) > 0) {
VPRINTK("pktcdvd: write, waiting\n");
break;
@@ -559,8 +561,10 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
if (bio_data_dir(bio) == READ)
pd->iosched.successive_reads += bio->bi_size >> 10;
- else
+ else {
pd->iosched.successive_reads = 0;
+ pd->iosched.last_write = bio->bi_sector + bio_sectors(bio);
+ }
if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) {
if (pd->read_speed == pd->write_speed) {
pd->read_speed = MAX_SPEED;
@@ -765,7 +769,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
atomic_inc(&pkt->io_wait);
bio->bi_rw = READ;
- pkt_queue_bio(pd, bio, 0);
+ pkt_queue_bio(pd, bio);
frames_read++;
}
@@ -1062,7 +1066,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
atomic_set(&pkt->io_wait, 1);
pkt->w_bio->bi_rw = WRITE;
- pkt_queue_bio(pd, pkt->w_bio, 0);
+ pkt_queue_bio(pd, pkt->w_bio);
}
static void pkt_finish_packet(struct packet_data *pkt, int uptodate)
@@ -1247,8 +1251,7 @@ static int kcdrwd(void *foobar)
VPRINTK("kcdrwd: wake up\n");
/* make swsusp happy with our thread */
- if (current->flags & PF_FREEZE)
- refrigerator(PF_FREEZE);
+ try_to_freeze();
list_for_each_entry(pkt, &pd->cdrw.pkt_active_list, list) {
if (!pkt->sleep_time)
@@ -2120,7 +2123,7 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
cloned_bio->bi_private = psd;
cloned_bio->bi_end_io = pkt_end_io_read_cloned;
pd->stats.secs_r += bio->bi_size >> 9;
- pkt_queue_bio(pd, cloned_bio, 1);
+ pkt_queue_bio(pd, cloned_bio);
return 0;
}
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 9075bbb56ad..f766bc22c6b 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -576,7 +576,7 @@ static void __exit hci_uart_exit(void)
#endif
/* Release tty registration of line discipline */
- if ((err = tty_register_ldisc(N_HCI, NULL)))
+ if ((err = tty_unregister_ldisc(N_HCI)))
BT_ERR("Can't unregister HCI line discipline (%d)", err);
}
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
index da80b14335a..01f03517332 100644
--- a/drivers/cdrom/cm206.c
+++ b/drivers/cdrom/cm206.c
@@ -307,7 +307,7 @@ static DEFINE_SPINLOCK(cm206_lock);
/* First, we define some polling functions. These are actually
only being used in the initialization. */
-void send_command_polled(int command)
+static void send_command_polled(int command)
{
int loop = POLLOOP;
while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
@@ -318,7 +318,7 @@ void send_command_polled(int command)
outw(command, r_uart_transmit);
}
-uch receive_echo_polled(void)
+static uch receive_echo_polled(void)
{
int loop = POLLOOP;
while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
@@ -328,13 +328,13 @@ uch receive_echo_polled(void)
return ((uch) inw(r_uart_receive));
}
-uch send_receive_polled(int command)
+static uch send_receive_polled(int command)
{
send_command_polled(command);
return receive_echo_polled();
}
-inline void clear_ur(void)
+static inline void clear_ur(void)
{
if (cd->ur_r != cd->ur_w) {
debug(("Deleting bytes from fifo:"));
@@ -439,7 +439,7 @@ static irqreturn_t cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
}
/* we have put the address of the wait queue in who */
-void cm206_timeout(unsigned long who)
+static void cm206_timeout(unsigned long who)
{
cd->timed_out = 1;
debug(("Timing out\n"));
@@ -448,7 +448,7 @@ void cm206_timeout(unsigned long who)
/* This function returns 1 if a timeout occurred, 0 if an interrupt
happened */
-int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
+static int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
{
cd->timed_out = 0;
init_timer(&cd->timer);
@@ -465,13 +465,7 @@ int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
return 0;
}
-void cm206_delay(int nr_jiffies)
-{
- DECLARE_WAIT_QUEUE_HEAD(wait);
- sleep_or_timeout(&wait, nr_jiffies);
-}
-
-void send_command(int command)
+static void send_command(int command)
{
debug(("Sending 0x%x\n", command));
if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
@@ -490,7 +484,7 @@ void send_command(int command)
outw(command, r_uart_transmit);
}
-uch receive_byte(int timeout)
+static uch receive_byte(int timeout)
{
uch ret;
cli();
@@ -521,23 +515,23 @@ uch receive_byte(int timeout)
return ret;
}
-inline uch receive_echo(void)
+static inline uch receive_echo(void)
{
return receive_byte(UART_TIMEOUT);
}
-inline uch send_receive(int command)
+static inline uch send_receive(int command)
{
send_command(command);
return receive_echo();
}
-inline uch wait_dsb(void)
+static inline uch wait_dsb(void)
{
return receive_byte(DSB_TIMEOUT);
}
-int type_0_command(int command, int expect_dsb)
+static int type_0_command(int command, int expect_dsb)
{
int e;
clear_ur();
@@ -552,7 +546,7 @@ int type_0_command(int command, int expect_dsb)
return 0;
}
-int type_1_command(int command, int bytes, uch * status)
+static int type_1_command(int command, int bytes, uch * status)
{ /* returns info */
int i;
if (type_0_command(command, 0))
@@ -564,7 +558,7 @@ int type_1_command(int command, int bytes, uch * status)
/* This function resets the adapter card. We'd better not do this too
* often, because it tends to generate `lost interrupts.' */
-void reset_cm260(void)
+static void reset_cm260(void)
{
outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
udelay(10); /* 3.3 mu sec minimum */
@@ -572,7 +566,7 @@ void reset_cm260(void)
}
/* fsm: frame-sec-min from linear address; one of many */
-void fsm(int lba, uch * fsm)
+static void fsm(int lba, uch * fsm)
{
fsm[0] = lba % 75;
lba /= 75;
@@ -581,17 +575,17 @@ void fsm(int lba, uch * fsm)
fsm[2] = lba / 60;
}
-inline int fsm2lba(uch * fsm)
+static inline int fsm2lba(uch * fsm)
{
return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
}
-inline int f_s_m2lba(uch f, uch s, uch m)
+static inline int f_s_m2lba(uch f, uch s, uch m)
{
return f + 75 * (s - 2 + 60 * m);
}
-int start_read(int start)
+static int start_read(int start)
{
uch read_sector[4] = { c_read_data, };
int i, e;
@@ -613,7 +607,7 @@ int start_read(int start)
return 0;
}
-int stop_read(void)
+static int stop_read(void)
{
int e;
type_0_command(c_stop, 0);
@@ -630,7 +624,7 @@ int stop_read(void)
routine takes care of this. Set a flag `background' in the cd
struct to indicate the process. */
-int read_background(int start, int reading)
+static int read_background(int start, int reading)
{
if (cd->background)
return -1; /* can't do twice */
@@ -658,7 +652,7 @@ void transport_data(int port, ush * dest, int count)
#define MAX_TRIES 100
-int read_sector(int start)
+static int read_sector(int start)
{
int tries = 0;
if (cd->background) {
@@ -753,7 +747,7 @@ static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0);
/* This command clears the dsb_possible_media_change flag, so we must
* retain it.
*/
-void get_drive_status(void)
+static void get_drive_status(void)
{
uch status[2];
type_1_command(c_drive_status, 2, status); /* this might be done faster */
@@ -764,7 +758,7 @@ void get_drive_status(void)
dsb_drive_not_ready | dsb_tray_not_closed));
}
-void get_disc_status(void)
+static void get_disc_status(void)
{
if (type_1_command(c_disc_status, 7, cd->disc_status)) {
debug(("get_disc_status: error\n"));
@@ -801,7 +795,7 @@ static void cm206_release(struct cdrom_device_info *cdi)
/* Empty buffer empties $sectors$ sectors of the adapter card buffer,
* and then reads a sector in kernel memory. */
-void empty_buffer(int sectors)
+static void empty_buffer(int sectors)
{
while (sectors >= 0) {
transport_data(r_fifo_output_buffer,
@@ -819,7 +813,7 @@ void empty_buffer(int sectors)
/* try_adapter. This function determines if the requested sector is
in adapter memory, or will appear there soon. Returns 0 upon
success */
-int try_adapter(int sector)
+static int try_adapter(int sector)
{
if (cd->adapter_first <= sector && sector < cd->adapter_last) {
/* sector is in adapter memory */
@@ -910,7 +904,7 @@ static void do_cm206_request(request_queue_t * q)
*/
/* seek seeks to address lba. It does wait to arrive there. */
-void seek(int lba)
+static void seek(int lba)
{
int i;
uch seek_command[4] = { c_seek, };
@@ -926,7 +920,7 @@ uch bcdbin(unsigned char bcd)
return (bcd >> 4) * 10 + (bcd & 0xf);
}
-inline uch normalize_track(uch track)
+static inline uch normalize_track(uch track)
{
if (track < 1)
return 1;
@@ -939,7 +933,7 @@ inline uch normalize_track(uch track)
* tracks seen in the process. Input $track$ must be between 1 and
* #-of-tracks+1. Note that the start of the disc must be in toc[1].fsm.
*/
-int get_toc_lba(uch track)
+static int get_toc_lba(uch track)
{
int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
int i, lba, l, old_lba = 0;
@@ -991,7 +985,7 @@ int get_toc_lba(uch track)
return lba;
}
-void update_toc_entry(uch track)
+static void update_toc_entry(uch track)
{
track = normalize_track(track);
if (!cd->toc[track].track)
@@ -999,7 +993,7 @@ void update_toc_entry(uch track)
}
/* return 0 upon success */
-int read_toc_header(struct cdrom_tochdr *hp)
+static int read_toc_header(struct cdrom_tochdr *hp)
{
if (!FIRST_TRACK)
get_disc_status();
@@ -1016,7 +1010,7 @@ int read_toc_header(struct cdrom_tochdr *hp)
return -1;
}
-void play_from_to_msf(struct cdrom_msf *msfp)
+static void play_from_to_msf(struct cdrom_msf *msfp)
{
uch play_command[] = { c_play,
msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
@@ -1032,7 +1026,7 @@ void play_from_to_msf(struct cdrom_msf *msfp)
cd->dsb = wait_dsb();
}
-void play_from_to_track(int from, int to)
+static void play_from_to_track(int from, int to)
{
uch play_command[8] = { c_play, };
int i;
@@ -1059,7 +1053,7 @@ void play_from_to_track(int from, int to)
cd->dsb = wait_dsb();
}
-int get_current_q(struct cdrom_subchnl *qp)
+static int get_current_q(struct cdrom_subchnl *qp)
{
int i;
uch *q = cd->q;
@@ -1093,14 +1087,14 @@ int get_current_q(struct cdrom_subchnl *qp)
return 0;
}
-void invalidate_toc(void)
+static void invalidate_toc(void)
{
memset(cd->toc, 0, sizeof(cd->toc));
memset(cd->disc_status, 0, sizeof(cd->disc_status));
}
/* cdrom.c guarantees that cdte_format == CDROM_MSF */
-void get_toc_entry(struct cdrom_tocentry *ep)
+static void get_toc_entry(struct cdrom_tocentry *ep)
{
uch track = normalize_track(ep->cdte_track);
update_toc_entry(track);
@@ -1117,8 +1111,8 @@ void get_toc_entry(struct cdrom_tocentry *ep)
* upon success. Memory checking has been done by cdrom_ioctl(), the
* calling function, as well as LBA/MSF sanitization.
*/
-int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
- void *arg)
+static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+ void *arg)
{
switch (cmd) {
case CDROMREADTOCHDR:
@@ -1189,7 +1183,7 @@ static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
}
}
-int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
+static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
{
if (cd != NULL) {
int r;
@@ -1204,16 +1198,9 @@ int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
/* The new generic cdrom support. Routines should be concise, most of
the logic should be in cdrom.c */
-/* returns number of times device is in use */
-int cm206_open_files(struct cdrom_device_info *cdi)
-{
- if (cd)
- return cd->openfiles;
- return -1;
-}
/* controls tray movement */
-int cm206_tray_move(struct cdrom_device_info *cdi, int position)
+static int cm206_tray_move(struct cdrom_device_info *cdi, int position)
{
if (position) { /* 1: eject */
type_0_command(c_open_tray, 1);
@@ -1224,7 +1211,7 @@ int cm206_tray_move(struct cdrom_device_info *cdi, int position)
}
/* gives current state of the drive */
-int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
+static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
{
get_drive_status();
if (cd->dsb & dsb_tray_not_closed)
@@ -1237,7 +1224,7 @@ int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
}
/* locks or unlocks door lock==1: lock; return 0 upon success */
-int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
+static int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
{
uch command = (lock) ? c_lock_tray : c_unlock_tray;
type_0_command(command, 1); /* wait and get dsb */
@@ -1248,8 +1235,8 @@ int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
/* Although a session start should be in LBA format, we return it in
MSF format because it is slightly easier, and the new generic ioctl
will take care of the necessary conversion. */
-int cm206_get_last_session(struct cdrom_device_info *cdi,
- struct cdrom_multisession *mssp)
+static int cm206_get_last_session(struct cdrom_device_info *cdi,
+ struct cdrom_multisession *mssp)
{
if (!FIRST_TRACK)
get_disc_status();
@@ -1268,7 +1255,7 @@ int cm206_get_last_session(struct cdrom_device_info *cdi,
return 0;
}
-int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
+static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
{
uch upc[10];
char *ret = mcn->medium_catalog_number;
@@ -1287,7 +1274,7 @@ int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
return 0;
}
-int cm206_reset(struct cdrom_device_info *cdi)
+static int cm206_reset(struct cdrom_device_info *cdi)
{
stop_read();
reset_cm260();
@@ -1300,7 +1287,7 @@ int cm206_reset(struct cdrom_device_info *cdi)
return 0;
}
-int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
+static int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
{
int r;
switch (speed) {
@@ -1392,7 +1379,7 @@ static struct gendisk *cm206_gendisk;
request_region, 15 bits of one port and 6 of another make things
likely enough to accept the region on the first hit...
*/
-int __init probe_base_port(int base)
+static int __init probe_base_port(int base)
{
int b = 0x300, e = 0x370; /* this is the range of start addresses */
volatile int fool, i;
@@ -1416,7 +1403,7 @@ int __init probe_base_port(int base)
#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
/* Probe for irq# nr. If nr==0, probe for all possible irq's. */
-int __init probe_irq(int nr)
+static int __init probe_irq(int nr)
{
int irqs, irq;
outw(dc_normal | READ_AHEAD, r_data_control); /* disable irq-generation */
@@ -1558,7 +1545,7 @@ static void __init parse_options(void)
}
}
-int __cm206_init(void)
+static int __cm206_init(void)
{
parse_options();
#if !defined(AUTO_PROBE_MODULE)
@@ -1567,7 +1554,7 @@ int __cm206_init(void)
return cm206_init();
}
-void __exit cm206_exit(void)
+static void __exit cm206_exit(void)
{
del_gendisk(cm206_gendisk);
put_disk(cm206_gendisk);
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
index f4be7bfd667..9f22e8f1f6c 100644
--- a/drivers/cdrom/sonycd535.c
+++ b/drivers/cdrom/sonycd535.c
@@ -1605,8 +1605,7 @@ out7:
put_disk(cdu_disk);
out6:
for (i = 0; i < sony_buffer_sectors; i++)
- if (sony_buffer[i])
- kfree(sony_buffer[i]);
+ kfree(sony_buffer[i]);
out5:
kfree(sony_buffer);
out4:
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 7ccf871d3c9..43d0cb19ef6 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -940,8 +940,8 @@ config RAW_DRIVER
Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
See the raw(8) manpage for more details.
- The raw driver is deprecated and may be removed from 2.7
- kernels. Applications should simply open the device (eg /dev/hda1)
+ The raw driver is deprecated and will be removed soon.
+ Applications should simply open the device (eg /dev/hda1)
with the O_DIRECT flag.
config HPET
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 1dc4259213a..2a36561eec6 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -861,13 +861,18 @@ static void change_speed(struct async_struct *info,
static void rs_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct async_struct *info = (struct async_struct *)tty->driver_data;
+ struct async_struct *info;
unsigned long flags;
+ if (!tty)
+ return;
+
+ info = tty->driver_data;
+
if (serial_paranoia_check(info, tty->name, "rs_put_char"))
return;
- if (!tty || !info->xmit.buf)
+ if (!info->xmit.buf)
return;
local_irq_save(flags);
@@ -910,13 +915,18 @@ static void rs_flush_chars(struct tty_struct *tty)
static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count)
{
int c, ret = 0;
- struct async_struct *info = (struct async_struct *)tty->driver_data;
+ struct async_struct *info;
unsigned long flags;
+ if (!tty)
+ return 0;
+
+ info = tty->driver_data;
+
if (serial_paranoia_check(info, tty->name, "rs_write"))
return 0;
- if (!tty || !info->xmit.buf || !tmp_buf)
+ if (!info->xmit.buf || !tmp_buf)
return 0;
local_save_flags(flags);
@@ -1963,10 +1973,6 @@ static _INLINE_ void show_serial_version(void)
}
-int register_serial(struct serial_struct *req);
-void unregister_serial(int line);
-
-
static struct tty_operations serial_ops = {
.open = rs_open,
.close = rs_close,
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 6bf2e27dc23..11f9ee58112 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -599,7 +599,7 @@ static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_
#ifdef DEBUG
if (loopcount++ > 2) {
- printk("Looping in ac_read. loopcount %d\n", loopcount);
+ printk(KERN_DEBUG "Looping in ac_read. loopcount %d\n", loopcount);
}
#endif
}
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index d9a02993467..c2b12eab67c 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -6,7 +6,7 @@
#
config DRM
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
- depends on AGP || AGP=n
+ depends on (AGP || AGP=n) && PCI
help
Kernel-level support for the Direct Rendering Infrastructure (DRI)
introduced in XFree86 4.0. If you say Y here, you need to select
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 7300a09dbd5..b5903f9f142 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -1,10 +1,30 @@
/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
*/
/**************************************************************************
- *
+ *
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
**************************************************************************/
#include "drmP.h"
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
index 7e55edf45c4..23e027d2908 100644
--- a/drivers/char/drm/i915_drm.h
+++ b/drivers/char/drm/i915_drm.h
@@ -1,3 +1,30 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
#ifndef _I915_DRM_H_
#define _I915_DRM_H_
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 002b7082e21..e6a9e1d1d28 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -1,11 +1,30 @@
/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
*/
-
/**************************************************************************
- *
+ *
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
**************************************************************************/
#include "drmP.h"
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index f6ca92a565d..fa940d64b85 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -1,10 +1,30 @@
/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
*/
/**************************************************************************
- *
+ *
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
**************************************************************************/
#ifndef _I915_DRV_H_
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index b0239262a84..a101cc9cfd7 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -1,10 +1,30 @@
/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
*/
/**************************************************************************
- *
+ *
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
**************************************************************************/
#include "drmP.h"
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
index d54a3005946..9b1698f521b 100644
--- a/drivers/char/drm/i915_mem.c
+++ b/drivers/char/drm/i915_mem.c
@@ -1,10 +1,30 @@
/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*-
*/
/**************************************************************************
- *
+ *
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
**************************************************************************/
#include "drmP.h"
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index cd25f28e26a..40474a65f56 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -35,6 +35,14 @@
#include "radeon_drm.h"
#include "radeon_drv.h"
+static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask)
+{
+ u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
+ if (irqs)
+ RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
+ return irqs;
+}
+
/* Interrupts - Used for device synchronization and flushing in the
* following circumstances:
*
@@ -63,8 +71,8 @@ irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS )
/* Only consider the bits we're interested in - others could be used
* outside the DRM
*/
- stat = RADEON_READ(RADEON_GEN_INT_STATUS)
- & (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT);
+ stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
+ RADEON_CRTC_VBLANK_STAT));
if (!stat)
return IRQ_NONE;
@@ -80,19 +88,9 @@ irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS )
drm_vbl_send_signals( dev );
}
- /* Acknowledge interrupts we handle */
- RADEON_WRITE(RADEON_GEN_INT_STATUS, stat);
return IRQ_HANDLED;
}
-static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv)
-{
- u32 tmp = RADEON_READ( RADEON_GEN_INT_STATUS )
- & (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT);
- if (tmp)
- RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp );
-}
-
static int radeon_emit_irq(drm_device_t *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -141,7 +139,7 @@ int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
return DRM_ERR(EINVAL);
}
- radeon_acknowledge_irqs( dev_priv );
+ radeon_acknowledge_irqs(dev_priv, RADEON_CRTC_VBLANK_STAT);
dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
@@ -219,7 +217,8 @@ void radeon_driver_irq_preinstall( drm_device_t *dev ) {
RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
/* Clear bits if they're already high */
- radeon_acknowledge_irqs( dev_priv );
+ radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
+ RADEON_CRTC_VBLANK_STAT));
}
void radeon_driver_irq_postinstall( drm_device_t *dev ) {
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 7def6ad5179..62cda25724e 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -163,8 +163,7 @@ static void ds1620_out(int cmd, int bits, int value)
netwinder_ds1620_reset();
netwinder_unlock(&flags);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(2);
+ msleep(20);
}
static unsigned int ds1620_in(int cmd, int bits)
diff --git a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c
index 220a227e606..65ffc0be3df 100644
--- a/drivers/char/ftape/compressor/zftape-compress.c
+++ b/drivers/char/ftape/compressor/zftape-compress.c
@@ -1176,8 +1176,8 @@ KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n");
}
#else /* !MODULE */
/* print a short no-nonsense boot message */
- printk("zftape compressor v1.00a 970514\n");
- printk("For use with " FTAPE_VERSION "\n");
+ printk(KERN_INFO "zftape compressor v1.00a 970514\n");
+ printk(KERN_INFO "For use with " FTAPE_VERSION "\n");
#endif /* MODULE */
TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);
TRACE(ft_t_info, "installing compressor for zftape ...");
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 5ec732e6ca9..762fa430fb5 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -834,7 +834,7 @@ int hpet_alloc(struct hpet_data *hdp)
printk("\n");
ns = hpetp->hp_period; /* femptoseconds, 10^-15 */
- do_div(ns, 1000000); /* convert to nanoseconds, 10^-9 */
+ ns /= 1000000; /* convert to nanoseconds, 10^-9 */
printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n",
hpetp->hp_which, ns, hpetp->hp_ntimer,
cap & HPET_COUNTER_SIZE_MASK ? 64 : 32);
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index a8119764028..6c4b3f986d0 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -20,13 +20,14 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
-#include <linux/apm_bios.h>
+#include <linux/seq_file.h>
+#include <linux/dmi.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/i8k.h>
-#define I8K_VERSION "1.13 14/05/2002"
+#define I8K_VERSION "1.14 21/02/2005"
#define I8K_SMM_FN_STATUS 0x0025
#define I8K_SMM_POWER_STATUS 0x0069
@@ -34,7 +35,8 @@
#define I8K_SMM_GET_FAN 0x00a3
#define I8K_SMM_GET_SPEED 0x02a3
#define I8K_SMM_GET_TEMP 0x10a3
-#define I8K_SMM_GET_DELL_SIG 0xffa3
+#define I8K_SMM_GET_DELL_SIG1 0xfea3
+#define I8K_SMM_GET_DELL_SIG2 0xffa3
#define I8K_SMM_BIOS_VERSION 0x00a6
#define I8K_FAN_MULT 30
@@ -52,18 +54,7 @@
#define I8K_TEMPERATURE_BUG 1
-#define DELL_SIGNATURE "Dell Computer"
-
-static char *supported_models[] = {
- "Inspiron",
- "Latitude",
- NULL
-};
-
-static char system_vendor[48] = "?";
-static char product_name [48] = "?";
-static char bios_version [4] = "?";
-static char serial_number[16] = "?";
+static char bios_version[4];
MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -73,6 +64,10 @@ static int force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force loading without checking for supported models");
+static int ignore_dmi;
+module_param(ignore_dmi, bool, 0);
+MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
+
static int restricted;
module_param(restricted, bool, 0);
MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
@@ -81,69 +76,69 @@ static int power_status;
module_param(power_status, bool, 0600);
MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
-static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *);
+static int i8k_open_fs(struct inode *inode, struct file *file);
static int i8k_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
static struct file_operations i8k_fops = {
- .read = i8k_read,
- .ioctl = i8k_ioctl,
+ .open = i8k_open_fs,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .ioctl = i8k_ioctl,
+};
+
+struct smm_regs {
+ unsigned int eax;
+ unsigned int ebx __attribute__ ((packed));
+ unsigned int ecx __attribute__ ((packed));
+ unsigned int edx __attribute__ ((packed));
+ unsigned int esi __attribute__ ((packed));
+ unsigned int edi __attribute__ ((packed));
};
-typedef struct {
- unsigned int eax;
- unsigned int ebx __attribute__ ((packed));
- unsigned int ecx __attribute__ ((packed));
- unsigned int edx __attribute__ ((packed));
- unsigned int esi __attribute__ ((packed));
- unsigned int edi __attribute__ ((packed));
-} SMMRegisters;
-
-typedef struct {
- u8 type;
- u8 length;
- u16 handle;
-} DMIHeader;
+static inline char *i8k_get_dmi_data(int field)
+{
+ return dmi_get_system_info(field) ? : "N/A";
+}
/*
* Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
*/
-static int i8k_smm(SMMRegisters *regs)
+static int i8k_smm(struct smm_regs *regs)
{
- int rc;
- int eax = regs->eax;
-
- asm("pushl %%eax\n\t" \
- "movl 0(%%eax),%%edx\n\t" \
- "push %%edx\n\t" \
- "movl 4(%%eax),%%ebx\n\t" \
- "movl 8(%%eax),%%ecx\n\t" \
- "movl 12(%%eax),%%edx\n\t" \
- "movl 16(%%eax),%%esi\n\t" \
- "movl 20(%%eax),%%edi\n\t" \
- "popl %%eax\n\t" \
- "out %%al,$0xb2\n\t" \
- "out %%al,$0x84\n\t" \
- "xchgl %%eax,(%%esp)\n\t"
- "movl %%ebx,4(%%eax)\n\t" \
- "movl %%ecx,8(%%eax)\n\t" \
- "movl %%edx,12(%%eax)\n\t" \
- "movl %%esi,16(%%eax)\n\t" \
- "movl %%edi,20(%%eax)\n\t" \
- "popl %%edx\n\t" \
- "movl %%edx,0(%%eax)\n\t" \
- "lahf\n\t" \
- "shrl $8,%%eax\n\t" \
- "andl $1,%%eax\n" \
- : "=a" (rc)
- : "a" (regs)
- : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
-
- if ((rc != 0) || ((regs->eax & 0xffff) == 0xffff) || (regs->eax == eax)) {
- return -EINVAL;
- }
-
- return 0;
+ int rc;
+ int eax = regs->eax;
+
+ asm("pushl %%eax\n\t"
+ "movl 0(%%eax),%%edx\n\t"
+ "push %%edx\n\t"
+ "movl 4(%%eax),%%ebx\n\t"
+ "movl 8(%%eax),%%ecx\n\t"
+ "movl 12(%%eax),%%edx\n\t"
+ "movl 16(%%eax),%%esi\n\t"
+ "movl 20(%%eax),%%edi\n\t"
+ "popl %%eax\n\t"
+ "out %%al,$0xb2\n\t"
+ "out %%al,$0x84\n\t"
+ "xchgl %%eax,(%%esp)\n\t"
+ "movl %%ebx,4(%%eax)\n\t"
+ "movl %%ecx,8(%%eax)\n\t"
+ "movl %%edx,12(%%eax)\n\t"
+ "movl %%esi,16(%%eax)\n\t"
+ "movl %%edi,20(%%eax)\n\t"
+ "popl %%edx\n\t"
+ "movl %%edx,0(%%eax)\n\t"
+ "lahf\n\t"
+ "shrl $8,%%eax\n\t"
+ "andl $1,%%eax\n":"=a"(rc)
+ : "a"(regs)
+ : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
+
+ if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
+ return -EINVAL;
+
+ return 0;
}
/*
@@ -152,24 +147,9 @@ static int i8k_smm(SMMRegisters *regs)
*/
static int i8k_get_bios_version(void)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
- int rc;
-
- regs.eax = I8K_SMM_BIOS_VERSION;
- if ((rc=i8k_smm(&regs)) < 0) {
- return rc;
- }
-
- return regs.eax;
-}
+ struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, };
-/*
- * Read the machine id.
- */
-static int i8k_get_serial_number(unsigned char *buff)
-{
- strlcpy(buff, serial_number, sizeof(serial_number));
- return 0;
+ return i8k_smm(&regs) ? : regs.eax;
}
/*
@@ -177,24 +157,22 @@ static int i8k_get_serial_number(unsigned char *buff)
*/
static int i8k_get_fn_status(void)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
- int rc;
-
- regs.eax = I8K_SMM_FN_STATUS;
- if ((rc=i8k_smm(&regs)) < 0) {
- return rc;
- }
-
- switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
- case I8K_FN_UP:
- return I8K_VOL_UP;
- case I8K_FN_DOWN:
- return I8K_VOL_DOWN;
- case I8K_FN_MUTE:
- return I8K_VOL_MUTE;
- default:
- return 0;
- }
+ struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
+ int rc;
+
+ if ((rc = i8k_smm(&regs)) < 0)
+ return rc;
+
+ switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
+ case I8K_FN_UP:
+ return I8K_VOL_UP;
+ case I8K_FN_DOWN:
+ return I8K_VOL_DOWN;
+ case I8K_FN_MUTE:
+ return I8K_VOL_MUTE;
+ default:
+ return 0;
+ }
}
/*
@@ -202,20 +180,13 @@ static int i8k_get_fn_status(void)
*/
static int i8k_get_power_status(void)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
- int rc;
-
- regs.eax = I8K_SMM_POWER_STATUS;
- if ((rc=i8k_smm(&regs)) < 0) {
- return rc;
- }
-
- switch (regs.eax & 0xff) {
- case I8K_POWER_AC:
- return I8K_AC;
- default:
- return I8K_BATTERY;
- }
+ struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
+ int rc;
+
+ if ((rc = i8k_smm(&regs)) < 0)
+ return rc;
+
+ return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
}
/*
@@ -223,16 +194,10 @@ static int i8k_get_power_status(void)
*/
static int i8k_get_fan_status(int fan)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
- int rc;
-
- regs.eax = I8K_SMM_GET_FAN;
- regs.ebx = fan & 0xff;
- if ((rc=i8k_smm(&regs)) < 0) {
- return rc;
- }
+ struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
- return (regs.eax & 0xff);
+ regs.ebx = fan & 0xff;
+ return i8k_smm(&regs) ? : regs.eax & 0xff;
}
/*
@@ -240,16 +205,10 @@ static int i8k_get_fan_status(int fan)
*/
static int i8k_get_fan_speed(int fan)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
- int rc;
+ struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
- regs.eax = I8K_SMM_GET_SPEED;
- regs.ebx = fan & 0xff;
- if ((rc=i8k_smm(&regs)) < 0) {
- return rc;
- }
-
- return (regs.eax & 0xffff) * I8K_FAN_MULT;
+ regs.ebx = fan & 0xff;
+ return i8k_smm(&regs) ? : (regs.eax & 0xffff) * I8K_FAN_MULT;
}
/*
@@ -257,532 +216,318 @@ static int i8k_get_fan_speed(int fan)
*/
static int i8k_set_fan(int fan, int speed)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
- int rc;
-
- speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
+ struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
- regs.eax = I8K_SMM_SET_FAN;
- regs.ebx = (fan & 0xff) | (speed << 8);
- if ((rc=i8k_smm(&regs)) < 0) {
- return rc;
- }
+ speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
+ regs.ebx = (fan & 0xff) | (speed << 8);
- return (i8k_get_fan_status(fan));
+ return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
}
/*
* Read the cpu temperature.
*/
-static int i8k_get_cpu_temp(void)
+static int i8k_get_temp(int sensor)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
- int rc;
- int temp;
+ struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP, };
+ int rc;
+ int temp;
#ifdef I8K_TEMPERATURE_BUG
- static int prev = 0;
+ static int prev;
#endif
+ regs.ebx = sensor & 0xff;
+ if ((rc = i8k_smm(&regs)) < 0)
+ return rc;
- regs.eax = I8K_SMM_GET_TEMP;
- if ((rc=i8k_smm(&regs)) < 0) {
- return rc;
- }
- temp = regs.eax & 0xff;
+ temp = regs.eax & 0xff;
#ifdef I8K_TEMPERATURE_BUG
- /*
- * Sometimes the temperature sensor returns 0x99, which is out of range.
- * In this case we return (once) the previous cached value. For example:
- # 1003655137 00000058 00005a4b
- # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
- # 1003655139 00000054 00005c52
- */
- if (temp > I8K_MAX_TEMP) {
- temp = prev;
- prev = I8K_MAX_TEMP;
- } else {
- prev = temp;
- }
+ /*
+ * Sometimes the temperature sensor returns 0x99, which is out of range.
+ * In this case we return (once) the previous cached value. For example:
+ # 1003655137 00000058 00005a4b
+ # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
+ # 1003655139 00000054 00005c52
+ */
+ if (temp > I8K_MAX_TEMP) {
+ temp = prev;
+ prev = I8K_MAX_TEMP;
+ } else {
+ prev = temp;
+ }
#endif
- return temp;
+ return temp;
}
-static int i8k_get_dell_signature(void)
+static int i8k_get_dell_signature(int req_fn)
{
- SMMRegisters regs = { 0, 0, 0, 0, 0, 0 };
- int rc;
+ struct smm_regs regs = { .eax = req_fn, };
+ int rc;
- regs.eax = I8K_SMM_GET_DELL_SIG;
- if ((rc=i8k_smm(&regs)) < 0) {
- return rc;
- }
+ if ((rc = i8k_smm(&regs)) < 0)
+ return rc;
- if ((regs.eax == 1145651527) && (regs.edx == 1145392204)) {
- return 0;
- } else {
- return -1;
- }
+ return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
}
static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
unsigned long arg)
{
- int val;
- int speed;
- unsigned char buff[16];
- int __user *argp = (int __user *)arg;
-
- if (!argp)
- return -EINVAL;
-
- switch (cmd) {
- case I8K_BIOS_VERSION:
- val = i8k_get_bios_version();
- break;
-
- case I8K_MACHINE_ID:
- memset(buff, 0, 16);
- val = i8k_get_serial_number(buff);
- break;
-
- case I8K_FN_STATUS:
- val = i8k_get_fn_status();
- break;
-
- case I8K_POWER_STATUS:
- val = i8k_get_power_status();
- break;
-
- case I8K_GET_TEMP:
- val = i8k_get_cpu_temp();
- break;
-
- case I8K_GET_SPEED:
- if (copy_from_user(&val, argp, sizeof(int))) {
- return -EFAULT;
- }
- val = i8k_get_fan_speed(val);
- break;
-
- case I8K_GET_FAN:
- if (copy_from_user(&val, argp, sizeof(int))) {
- return -EFAULT;
- }
- val = i8k_get_fan_status(val);
- break;
+ int val = 0;
+ int speed;
+ unsigned char buff[16];
+ int __user *argp = (int __user *)arg;
- case I8K_SET_FAN:
- if (restricted && !capable(CAP_SYS_ADMIN)) {
- return -EPERM;
- }
- if (copy_from_user(&val, argp, sizeof(int))) {
- return -EFAULT;
- }
- if (copy_from_user(&speed, argp+1, sizeof(int))) {
- return -EFAULT;
- }
- val = i8k_set_fan(val, speed);
- break;
+ if (!argp)
+ return -EINVAL;
- default:
- return -EINVAL;
- }
+ switch (cmd) {
+ case I8K_BIOS_VERSION:
+ val = i8k_get_bios_version();
+ break;
- if (val < 0) {
- return val;
- }
+ case I8K_MACHINE_ID:
+ memset(buff, 0, 16);
+ strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), sizeof(buff));
+ break;
- switch (cmd) {
- case I8K_BIOS_VERSION:
- if (copy_to_user(argp, &val, 4)) {
- return -EFAULT;
- }
- break;
- case I8K_MACHINE_ID:
- if (copy_to_user(argp, buff, 16)) {
- return -EFAULT;
- }
- break;
- default:
- if (copy_to_user(argp, &val, sizeof(int))) {
- return -EFAULT;
- }
- break;
- }
+ case I8K_FN_STATUS:
+ val = i8k_get_fn_status();
+ break;
- return 0;
-}
+ case I8K_POWER_STATUS:
+ val = i8k_get_power_status();
+ break;
-/*
- * Print the information for /proc/i8k.
- */
-static int i8k_get_info(char *buffer, char **start, off_t fpos, int length)
-{
- int n, fn_key, cpu_temp, ac_power;
- int left_fan, right_fan, left_speed, right_speed;
-
- cpu_temp = i8k_get_cpu_temp(); /* 11100 µs */
- left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 µs */
- right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 µs */
- left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */
- right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */
- fn_key = i8k_get_fn_status(); /* 750 µs */
- if (power_status) {
- ac_power = i8k_get_power_status(); /* 14700 µs */
- } else {
- ac_power = -1;
- }
-
- /*
- * Info:
- *
- * 1) Format version (this will change if format changes)
- * 2) BIOS version
- * 3) BIOS machine ID
- * 4) Cpu temperature
- * 5) Left fan status
- * 6) Right fan status
- * 7) Left fan speed
- * 8) Right fan speed
- * 9) AC power
- * 10) Fn Key status
- */
- n = sprintf(buffer, "%s %s %s %d %d %d %d %d %d %d\n",
- I8K_PROC_FMT,
- bios_version,
- serial_number,
- cpu_temp,
- left_fan,
- right_fan,
- left_speed,
- right_speed,
- ac_power,
- fn_key);
-
- return n;
-}
+ case I8K_GET_TEMP:
+ val = i8k_get_temp(0);
+ break;
-static ssize_t i8k_read(struct file *f, char __user *buffer, size_t len, loff_t *fpos)
-{
- int n;
- char info[128];
+ case I8K_GET_SPEED:
+ if (copy_from_user(&val, argp, sizeof(int)))
+ return -EFAULT;
- n = i8k_get_info(info, NULL, 0, 128);
- if (n <= 0) {
- return n;
- }
+ val = i8k_get_fan_speed(val);
+ break;
- if (*fpos >= n) {
- return 0;
- }
+ case I8K_GET_FAN:
+ if (copy_from_user(&val, argp, sizeof(int)))
+ return -EFAULT;
- if ((*fpos + len) >= n) {
- len = n - *fpos;
- }
+ val = i8k_get_fan_status(val);
+ break;
- if (copy_to_user(buffer, info, len) != 0) {
- return -EFAULT;
- }
+ case I8K_SET_FAN:
+ if (restricted && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
- *fpos += len;
- return len;
-}
+ if (copy_from_user(&val, argp, sizeof(int)))
+ return -EFAULT;
-static char* __init string_trim(char *s, int size)
-{
- int len;
- char *p;
+ if (copy_from_user(&speed, argp + 1, sizeof(int)))
+ return -EFAULT;
- if ((len = strlen(s)) > size) {
- len = size;
- }
+ val = i8k_set_fan(val, speed);
+ break;
- for (p=s+len-1; len && (*p==' '); len--,p--) {
- *p = '\0';
- }
+ default:
+ return -EINVAL;
+ }
- return s;
-}
+ if (val < 0)
+ return val;
-/* DMI code, stolen from arch/i386/kernel/dmi_scan.c */
+ switch (cmd) {
+ case I8K_BIOS_VERSION:
+ if (copy_to_user(argp, &val, 4))
+ return -EFAULT;
-/*
- * |<-- dmi->length -->|
- * | |
- * |dmi header s=N | string1,\0, ..., stringN,\0, ..., \0
- * | |
- * +-----------------------+
- */
-static char* __init dmi_string(DMIHeader *dmi, u8 s)
-{
- u8 *p;
+ break;
+ case I8K_MACHINE_ID:
+ if (copy_to_user(argp, buff, 16))
+ return -EFAULT;
- if (!s) {
- return "";
- }
- s--;
+ break;
+ default:
+ if (copy_to_user(argp, &val, sizeof(int)))
+ return -EFAULT;
- p = (u8 *)dmi + dmi->length;
- while (s > 0) {
- p += strlen(p);
- p++;
- s--;
- }
+ break;
+ }
- return p;
+ return 0;
}
-static void __init dmi_decode(DMIHeader *dmi)
+/*
+ * Print the information for /proc/i8k.
+ */
+static int i8k_proc_show(struct seq_file *seq, void *offset)
{
- u8 *data = (u8 *) dmi;
- char *p;
-
-#ifdef I8K_DEBUG
- int i;
- printk("%08x ", (int)data);
- for (i=0; i<data[1] && i<64; i++) {
- printk("%02x ", data[i]);
- }
- printk("\n");
-#endif
-
- switch (dmi->type) {
- case 0: /* BIOS Information */
- p = dmi_string(dmi,data[5]);
- if (*p) {
- strlcpy(bios_version, p, sizeof(bios_version));
- string_trim(bios_version, sizeof(bios_version));
- }
- break;
- case 1: /* System Information */
- p = dmi_string(dmi,data[4]);
- if (*p) {
- strlcpy(system_vendor, p, sizeof(system_vendor));
- string_trim(system_vendor, sizeof(system_vendor));
- }
- p = dmi_string(dmi,data[5]);
- if (*p) {
- strlcpy(product_name, p, sizeof(product_name));
- string_trim(product_name, sizeof(product_name));
- }
- p = dmi_string(dmi,data[7]);
- if (*p) {
- strlcpy(serial_number, p, sizeof(serial_number));
- string_trim(serial_number, sizeof(serial_number));
- }
- break;
- }
-}
+ int fn_key, cpu_temp, ac_power;
+ int left_fan, right_fan, left_speed, right_speed;
+
+ cpu_temp = i8k_get_temp(0); /* 11100 µs */
+ left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 µs */
+ right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 µs */
+ left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */
+ right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */
+ fn_key = i8k_get_fn_status(); /* 750 µs */
+ if (power_status)
+ ac_power = i8k_get_power_status(); /* 14700 µs */
+ else
+ ac_power = -1;
-static int __init dmi_table(u32 base, int len, int num, void (*fn)(DMIHeader*))
-{
- u8 *buf;
- u8 *data;
- DMIHeader *dmi;
- int i = 1;
-
- buf = ioremap(base, len);
- if (buf == NULL) {
- return -1;
- }
- data = buf;
-
- /*
- * Stop when we see al the items the table claimed to have
- * or we run off the end of the table (also happens)
- */
- while ((i<num) && ((data-buf) < len)) {
- dmi = (DMIHeader *)data;
- /*
- * Avoid misparsing crud if the length of the last
- * record is crap
- */
- if ((data-buf+dmi->length) >= len) {
- break;
- }
- fn(dmi);
- data += dmi->length;
/*
- * Don't go off the end of the data if there is
- * stuff looking like string fill past the end
+ * Info:
+ *
+ * 1) Format version (this will change if format changes)
+ * 2) BIOS version
+ * 3) BIOS machine ID
+ * 4) Cpu temperature
+ * 5) Left fan status
+ * 6) Right fan status
+ * 7) Left fan speed
+ * 8) Right fan speed
+ * 9) AC power
+ * 10) Fn Key status
*/
- while (((data-buf) < len) && (*data || data[1])) {
- data++;
- }
- data += 2;
- i++;
- }
- iounmap(buf);
-
- return 0;
+ return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
+ I8K_PROC_FMT,
+ bios_version,
+ dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A",
+ cpu_temp,
+ left_fan, right_fan, left_speed, right_speed,
+ ac_power, fn_key);
}
-static int __init dmi_iterate(void (*decode)(DMIHeader *))
+static int i8k_open_fs(struct inode *inode, struct file *file)
{
- unsigned char buf[20];
- void __iomem *p = ioremap(0xe0000, 0x20000), *q;
-
- if (!p)
- return -1;
-
- for (q = p; q < p + 0x20000; q += 16) {
- memcpy_fromio(buf, q, 20);
- if (memcmp(buf, "_DMI_", 5)==0) {
- u16 num = buf[13]<<8 | buf[12];
- u16 len = buf [7]<<8 | buf [6];
- u32 base = buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8];
-#ifdef I8K_DEBUG
- printk(KERN_INFO "DMI %d.%d present.\n",
- buf[14]>>4, buf[14]&0x0F);
- printk(KERN_INFO "%d structures occupying %d bytes.\n",
- buf[13]<<8 | buf[12],
- buf [7]<<8 | buf[6]);
- printk(KERN_INFO "DMI table at 0x%08X.\n",
- buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8]);
-#endif
- if (dmi_table(base, len, num, decode)==0) {
- iounmap(p);
- return 0;
- }
- }
- }
- iounmap(p);
- return -1;
+ return single_open(file, i8k_proc_show, NULL);
}
-/* end of DMI code */
-
-/*
- * Get DMI information.
- */
-static int __init i8k_dmi_probe(void)
-{
- char **p;
-
- if (dmi_iterate(dmi_decode) != 0) {
- printk(KERN_INFO "i8k: unable to get DMI information\n");
- return -ENODEV;
- }
-
- if (strncmp(system_vendor,DELL_SIGNATURE,strlen(DELL_SIGNATURE)) != 0) {
- printk(KERN_INFO "i8k: not running on a Dell system\n");
- return -ENODEV;
- }
-
- for (p=supported_models; ; p++) {
- if (!*p) {
- printk(KERN_INFO "i8k: unsupported model: %s\n", product_name);
- return -ENODEV;
- }
- if (strncmp(product_name,*p,strlen(*p)) == 0) {
- break;
- }
- }
- return 0;
-}
+static struct dmi_system_id __initdata i8k_dmi_table[] = {
+ {
+ .ident = "Dell Inspiron",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
+ },
+ },
+ {
+ .ident = "Dell Latitude",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
+ },
+ },
+ {
+ .ident = "Dell Inspiron 2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
+ },
+ },
+ {
+ .ident = "Dell Latitude 2",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
+ },
+ },
+ { }
+};
/*
* Probe for the presence of a supported laptop.
*/
static int __init i8k_probe(void)
{
- char buff[4];
- int version;
- int smm_found = 0;
-
- /*
- * Get DMI information
- */
- if (i8k_dmi_probe() != 0) {
- printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
- system_vendor, product_name, bios_version);
- }
-
- /*
- * Get SMM Dell signature
- */
- if (i8k_get_dell_signature() != 0) {
- printk(KERN_INFO "i8k: unable to get SMM Dell signature\n");
- } else {
- smm_found = 1;
- }
-
- /*
- * Get SMM BIOS version.
- */
- version = i8k_get_bios_version();
- if (version <= 0) {
- printk(KERN_INFO "i8k: unable to get SMM BIOS version\n");
- } else {
- smm_found = 1;
- buff[0] = (version >> 16) & 0xff;
- buff[1] = (version >> 8) & 0xff;
- buff[2] = (version) & 0xff;
- buff[3] = '\0';
+ char buff[4];
+ int version;
+
/*
- * If DMI BIOS version is unknown use SMM BIOS version.
+ * Get DMI information
*/
- if (bios_version[0] == '?') {
- strcpy(bios_version, buff);
+ if (!dmi_check_system(i8k_dmi_table)) {
+ if (!ignore_dmi && !force)
+ return -ENODEV;
+
+ printk(KERN_INFO "i8k: not running on a supported Dell system.\n");
+ printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
+ i8k_get_dmi_data(DMI_SYS_VENDOR),
+ i8k_get_dmi_data(DMI_PRODUCT_NAME),
+ i8k_get_dmi_data(DMI_BIOS_VERSION));
}
+
+ strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), sizeof(bios_version));
+
/*
- * Check if the two versions match.
+ * Get SMM Dell signature
*/
- if (strncmp(buff,bios_version,sizeof(bios_version)) != 0) {
- printk(KERN_INFO "i8k: BIOS version mismatch: %s != %s\n",
- buff, bios_version);
+ if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
+ i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
+ printk(KERN_ERR "i8k: unable to get SMM Dell signature\n");
+ if (!force)
+ return -ENODEV;
}
- }
- if (!smm_found && !force) {
- return -ENODEV;
- }
+ /*
+ * Get SMM BIOS version.
+ */
+ version = i8k_get_bios_version();
+ if (version <= 0) {
+ printk(KERN_WARNING "i8k: unable to get SMM BIOS version\n");
+ } else {
+ buff[0] = (version >> 16) & 0xff;
+ buff[1] = (version >> 8) & 0xff;
+ buff[2] = (version) & 0xff;
+ buff[3] = '\0';
+ /*
+ * If DMI BIOS version is unknown use SMM BIOS version.
+ */
+ if (!dmi_get_system_info(DMI_BIOS_VERSION))
+ strlcpy(bios_version, buff, sizeof(bios_version));
+
+ /*
+ * Check if the two versions match.
+ */
+ if (strncmp(buff, bios_version, sizeof(bios_version)) != 0)
+ printk(KERN_WARNING "i8k: BIOS version mismatch: %s != %s\n",
+ buff, bios_version);
+ }
- return 0;
+ return 0;
}
-#ifdef MODULE
-static
-#endif
-int __init i8k_init(void)
+static int __init i8k_init(void)
{
- struct proc_dir_entry *proc_i8k;
-
- /* Are we running on an supported laptop? */
- if (i8k_probe() != 0) {
- return -ENODEV;
- }
-
- /* Register the proc entry */
- proc_i8k = create_proc_info_entry("i8k", 0, NULL, i8k_get_info);
- if (!proc_i8k) {
- return -ENOENT;
- }
- proc_i8k->proc_fops = &i8k_fops;
- proc_i8k->owner = THIS_MODULE;
-
- printk(KERN_INFO
- "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
- I8K_VERSION);
-
- return 0;
-}
+ struct proc_dir_entry *proc_i8k;
-#ifdef MODULE
-int init_module(void)
-{
- return i8k_init();
+ /* Are we running on an supported laptop? */
+ if (i8k_probe())
+ return -ENODEV;
+
+ /* Register the proc entry */
+ proc_i8k = create_proc_entry("i8k", 0, NULL);
+ if (!proc_i8k)
+ return -ENOENT;
+
+ proc_i8k->proc_fops = &i8k_fops;
+ proc_i8k->owner = THIS_MODULE;
+
+ printk(KERN_INFO
+ "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
+ I8K_VERSION);
+
+ return 0;
}
-void cleanup_module(void)
+static void __exit i8k_exit(void)
{
- /* Remove the proc entry */
- remove_proc_entry("i8k", NULL);
-
- printk(KERN_INFO "i8k: module unloaded\n");
+ remove_proc_entry("i8k", NULL);
}
-#endif
-/* end of file */
+module_init(i8k_init);
+module_exit(i8k_exit);
diff --git a/drivers/char/ip2/i2cmd.c b/drivers/char/ip2/i2cmd.c
index fd299d6c42a..cb8f4198e9a 100644
--- a/drivers/char/ip2/i2cmd.c
+++ b/drivers/char/ip2/i2cmd.c
@@ -97,7 +97,7 @@ static UCHAR ct41[] = { 1, BYP, 0x29 }; // RESUME
//static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING
//static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB
//static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB
-static UCHAR ct47[] = { 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS
+//static UCHAR ct47[]={ 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS
//static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB
//static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB
//static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB
@@ -162,6 +162,7 @@ static UCHAR ct89[]={ 1, BYP, 0x59 }; // DSS_NOW
// This routine sets the parameters of command 47 and returns a pointer to the
// appropriate structure.
//******************************************************************************
+#if 0
cmdSyntaxPtr
i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
{
@@ -175,6 +176,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
pCM->cmd[6] = (unsigned char) (lflag >> 8);
return pCM;
}
+#endif /* 0 */
//******************************************************************************
// Function: i2cmdBaudDef(which, rate)
@@ -187,7 +189,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
// This routine sets the parameters of commands 54 or 55 (according to the
// argument which), and returns a pointer to the appropriate structure.
//******************************************************************************
-cmdSyntaxPtr
+static cmdSyntaxPtr
i2cmdBaudDef(int which, unsigned short rate)
{
cmdSyntaxPtr pCM;
diff --git a/drivers/char/ip2/i2cmd.h b/drivers/char/ip2/i2cmd.h
index c41728a8571..baa4e721b75 100644
--- a/drivers/char/ip2/i2cmd.h
+++ b/drivers/char/ip2/i2cmd.h
@@ -64,16 +64,6 @@ typedef struct _cmdSyntax
// directly from user-level
#define VAR 0x10 // This command is of variable length!
-//-----------------------------------
-// External declarations for i2cmd.c
-//-----------------------------------
-// Routine to set up parameters for the "define hot-key sequence" command. Since
-// there is more than one parameter to assign, we must use a function rather
-// than a macro (used usually).
-//
-extern cmdSyntaxPtr i2cmdUnixFlags(USHORT iflag,USHORT cflag,USHORT lflag);
-extern cmdSyntaxPtr i2cmdBaudDef(int which, USHORT rate);
-
// Declarations for the global arrays used to bear the commands and their
// arguments.
//
@@ -433,6 +423,7 @@ static UCHAR cc02[];
#define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking
#define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking
+#if 0
// COMMAND 47: Send Protocol info via Unix flags:
// iflag = Unix tty t_iflag
// cflag = Unix tty t_cflag
@@ -441,6 +432,7 @@ static UCHAR cc02[];
// within these flags
//
#define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag)
+#endif /* 0 */
#define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl
#define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index 3b8314b4249..cf0cd58d630 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -2691,16 +2691,6 @@ no_xon:
pCh->flags |= ASYNC_CHECK_CD;
}
-#ifdef XXX
-do_flags_thing: // This is a test, we don't do the flags thing
-
- if ( (cflag & CRTSCTS) ) {
- cflag |= 014000000000;
- }
- i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1,
- CMD_UNIX_FLAGS(iflag,cflag,lflag));
-#endif
-
service_it:
i2DrainOutput( pCh, 100 );
}
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 88d1ad656e9..e0a53570fea 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -45,6 +45,7 @@
#include <asm/semaphore.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/compat.h>
#define IPMI_DEVINTF_VERSION "v33"
@@ -500,10 +501,205 @@ static int ipmi_ioctl(struct inode *inode,
return rv;
}
+#ifdef CONFIG_COMPAT
+
+/*
+ * The following code contains code for supporting 32-bit compatible
+ * ioctls on 64-bit kernels. This allows running 32-bit apps on the
+ * 64-bit kernel
+ */
+#define COMPAT_IPMICTL_SEND_COMMAND \
+ _IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
+#define COMPAT_IPMICTL_SEND_COMMAND_SETTIME \
+ _IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
+#define COMPAT_IPMICTL_RECEIVE_MSG \
+ _IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
+#define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC \
+ _IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
+
+struct compat_ipmi_msg {
+ u8 netfn;
+ u8 cmd;
+ u16 data_len;
+ compat_uptr_t data;
+};
+
+struct compat_ipmi_req {
+ compat_uptr_t addr;
+ compat_uint_t addr_len;
+ compat_long_t msgid;
+ struct compat_ipmi_msg msg;
+};
+
+struct compat_ipmi_recv {
+ compat_int_t recv_type;
+ compat_uptr_t addr;
+ compat_uint_t addr_len;
+ compat_long_t msgid;
+ struct compat_ipmi_msg msg;
+};
+
+struct compat_ipmi_req_settime {
+ struct compat_ipmi_req req;
+ compat_int_t retries;
+ compat_uint_t retry_time_ms;
+};
+
+/*
+ * Define some helper functions for copying IPMI data
+ */
+static long get_compat_ipmi_msg(struct ipmi_msg *p64,
+ struct compat_ipmi_msg __user *p32)
+{
+ compat_uptr_t tmp;
+
+ if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
+ __get_user(p64->netfn, &p32->netfn) ||
+ __get_user(p64->cmd, &p32->cmd) ||
+ __get_user(p64->data_len, &p32->data_len) ||
+ __get_user(tmp, &p32->data))
+ return -EFAULT;
+ p64->data = compat_ptr(tmp);
+ return 0;
+}
+
+static long put_compat_ipmi_msg(struct ipmi_msg *p64,
+ struct compat_ipmi_msg __user *p32)
+{
+ if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
+ __put_user(p64->netfn, &p32->netfn) ||
+ __put_user(p64->cmd, &p32->cmd) ||
+ __put_user(p64->data_len, &p32->data_len))
+ return -EFAULT;
+ return 0;
+}
+
+static long get_compat_ipmi_req(struct ipmi_req *p64,
+ struct compat_ipmi_req __user *p32)
+{
+
+ compat_uptr_t tmp;
+
+ if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
+ __get_user(tmp, &p32->addr) ||
+ __get_user(p64->addr_len, &p32->addr_len) ||
+ __get_user(p64->msgid, &p32->msgid) ||
+ get_compat_ipmi_msg(&p64->msg, &p32->msg))
+ return -EFAULT;
+ p64->addr = compat_ptr(tmp);
+ return 0;
+}
+
+static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
+ struct compat_ipmi_req_settime __user *p32)
+{
+ if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
+ get_compat_ipmi_req(&p64->req, &p32->req) ||
+ __get_user(p64->retries, &p32->retries) ||
+ __get_user(p64->retry_time_ms, &p32->retry_time_ms))
+ return -EFAULT;
+ return 0;
+}
+
+static long get_compat_ipmi_recv(struct ipmi_recv *p64,
+ struct compat_ipmi_recv __user *p32)
+{
+ compat_uptr_t tmp;
+
+ if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
+ __get_user(p64->recv_type, &p32->recv_type) ||
+ __get_user(tmp, &p32->addr) ||
+ __get_user(p64->addr_len, &p32->addr_len) ||
+ __get_user(p64->msgid, &p32->msgid) ||
+ get_compat_ipmi_msg(&p64->msg, &p32->msg))
+ return -EFAULT;
+ p64->addr = compat_ptr(tmp);
+ return 0;
+}
+
+static long put_compat_ipmi_recv(struct ipmi_recv *p64,
+ struct compat_ipmi_recv __user *p32)
+{
+ if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
+ __put_user(p64->recv_type, &p32->recv_type) ||
+ __put_user(p64->addr_len, &p32->addr_len) ||
+ __put_user(p64->msgid, &p32->msgid) ||
+ put_compat_ipmi_msg(&p64->msg, &p32->msg))
+ return -EFAULT;
+ return 0;
+}
+
+/*
+ * Handle compatibility ioctls
+ */
+static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
+ unsigned long arg)
+{
+ int rc;
+ struct ipmi_file_private *priv = filep->private_data;
+
+ switch(cmd) {
+ case COMPAT_IPMICTL_SEND_COMMAND:
+ {
+ struct ipmi_req rp;
+
+ if (get_compat_ipmi_req(&rp, compat_ptr(arg)))
+ return -EFAULT;
+
+ return handle_send_req(priv->user, &rp,
+ priv->default_retries,
+ priv->default_retry_time_ms);
+ }
+ case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
+ {
+ struct ipmi_req_settime sp;
+
+ if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))
+ return -EFAULT;
+
+ return handle_send_req(priv->user, &sp.req,
+ sp.retries, sp.retry_time_ms);
+ }
+ case COMPAT_IPMICTL_RECEIVE_MSG:
+ case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
+ {
+ struct ipmi_recv *precv64, recv64;
+
+ if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
+ return -EFAULT;
+
+ precv64 = compat_alloc_user_space(sizeof(recv64));
+ if (copy_to_user(precv64, &recv64, sizeof(recv64)))
+ return -EFAULT;
+
+ rc = ipmi_ioctl(filep->f_dentry->d_inode, filep,
+ ((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
+ ? IPMICTL_RECEIVE_MSG
+ : IPMICTL_RECEIVE_MSG_TRUNC),
+ (long) precv64);
+ if (rc != 0)
+ return rc;
+
+ if (copy_from_user(&recv64, precv64, sizeof(recv64)))
+ return -EFAULT;
+
+ if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))
+ return -EFAULT;
+
+ return rc;
+ }
+ default:
+ return ipmi_ioctl(filep->f_dentry->d_inode, filep, cmd, arg);
+ }
+}
+#endif
static struct file_operations ipmi_fops = {
.owner = THIS_MODULE,
.ioctl = ipmi_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = compat_ipmi_ioctl,
+#endif
.open = ipmi_open,
.release = ipmi_release,
.fasync = ipmi_fasync,
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 0c81652eaba..1813d0d198f 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -54,7 +54,9 @@ static int ipmi_init_msghandler(void);
static int initialized = 0;
-static struct proc_dir_entry *proc_ipmi_root = NULL;
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *proc_ipmi_root = NULL;
+#endif /* CONFIG_PROC_FS */
#define MAX_EVENTS_IN_QUEUE 25
@@ -124,11 +126,13 @@ struct ipmi_channel
unsigned char protocol;
};
+#ifdef CONFIG_PROC_FS
struct ipmi_proc_entry
{
char *name;
struct ipmi_proc_entry *next;
};
+#endif
#define IPMI_IPMB_NUM_SEQ 64
#define IPMI_MAX_CHANNELS 8
@@ -156,10 +160,13 @@ struct ipmi_smi
struct ipmi_smi_handlers *handlers;
void *send_info;
+#ifdef CONFIG_PROC_FS
/* A list of proc entries for this interface. This does not
need a lock, only one thread creates it and only one thread
destroys it. */
+ spinlock_t proc_entry_lock;
struct ipmi_proc_entry *proc_entries;
+#endif
/* A table of sequence numbers for this interface. We use the
sequence numbers for IPMB messages that go out of the
@@ -1470,8 +1477,9 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
read_proc_t *read_proc, write_proc_t *write_proc,
void *data, struct module *owner)
{
- struct proc_dir_entry *file;
int rv = 0;
+#ifdef CONFIG_PROC_FS
+ struct proc_dir_entry *file;
struct ipmi_proc_entry *entry;
/* Create a list element. */
@@ -1497,10 +1505,13 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
file->write_proc = write_proc;
file->owner = owner;
+ spin_lock(&smi->proc_entry_lock);
/* Stick it on the list. */
entry->next = smi->proc_entries;
smi->proc_entries = entry;
+ spin_unlock(&smi->proc_entry_lock);
}
+#endif /* CONFIG_PROC_FS */
return rv;
}
@@ -1509,6 +1520,7 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
{
int rv = 0;
+#ifdef CONFIG_PROC_FS
sprintf(smi->proc_dir_name, "%d", num);
smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
if (!smi->proc_dir)
@@ -1531,14 +1543,17 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
rv = ipmi_smi_add_proc_entry(smi, "version",
version_file_read_proc, NULL,
smi, THIS_MODULE);
+#endif /* CONFIG_PROC_FS */
return rv;
}
static void remove_proc_entries(ipmi_smi_t smi)
{
+#ifdef CONFIG_PROC_FS
struct ipmi_proc_entry *entry;
+ spin_lock(&smi->proc_entry_lock);
while (smi->proc_entries) {
entry = smi->proc_entries;
smi->proc_entries = entry->next;
@@ -1547,7 +1562,9 @@ static void remove_proc_entries(ipmi_smi_t smi)
kfree(entry->name);
kfree(entry);
}
+ spin_unlock(&smi->proc_entry_lock);
remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
+#endif /* CONFIG_PROC_FS */
}
static int
@@ -1694,6 +1711,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
new_intf->seq_table[j].seqid = 0;
}
new_intf->curr_seq = 0;
+#ifdef CONFIG_PROC_FS
+ spin_lock_init(&(new_intf->proc_entry_lock));
+#endif
spin_lock_init(&(new_intf->waiting_msgs_lock));
INIT_LIST_HEAD(&(new_intf->waiting_msgs));
spin_lock_init(&(new_intf->events_lock));
@@ -2747,16 +2767,13 @@ static struct timer_list ipmi_timer;
the queue and this silliness can go away. */
#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
-static volatile int stop_operation = 0;
-static volatile int timer_stopped = 0;
+static atomic_t stop_operation;
static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
static void ipmi_timeout(unsigned long data)
{
- if (stop_operation) {
- timer_stopped = 1;
+ if (atomic_read(&stop_operation))
return;
- }
ticks_to_req_ev--;
if (ticks_to_req_ev == 0) {
@@ -2766,8 +2783,7 @@ static void ipmi_timeout(unsigned long data)
ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
- ipmi_timer.expires += IPMI_TIMEOUT_JIFFIES;
- add_timer(&ipmi_timer);
+ mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
}
@@ -3089,6 +3105,7 @@ static int ipmi_init_msghandler(void)
ipmi_interfaces[i] = NULL;
}
+#ifdef CONFIG_PROC_FS
proc_ipmi_root = proc_mkdir("ipmi", NULL);
if (!proc_ipmi_root) {
printk(KERN_ERR PFX "Unable to create IPMI proc dir");
@@ -3096,6 +3113,7 @@ static int ipmi_init_msghandler(void)
}
proc_ipmi_root->owner = THIS_MODULE;
+#endif /* CONFIG_PROC_FS */
init_timer(&ipmi_timer);
ipmi_timer.data = 0;
@@ -3130,13 +3148,12 @@ static __exit void cleanup_ipmi(void)
/* Tell the timer to stop, then wait for it to stop. This avoids
problems with race conditions removing the timer here. */
- stop_operation = 1;
- while (!timer_stopped) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ atomic_inc(&stop_operation);
+ del_timer_sync(&ipmi_timer);
+#ifdef CONFIG_PROC_FS
remove_proc_entry(proc_ipmi_root->name, &proc_root);
+#endif /* CONFIG_PROC_FS */
initialized = 0;
@@ -3177,4 +3194,5 @@ EXPORT_SYMBOL(ipmi_get_my_address);
EXPORT_SYMBOL(ipmi_set_my_LUN);
EXPORT_SYMBOL(ipmi_get_my_LUN);
EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
+EXPORT_SYMBOL(proc_ipmi_root);
EXPORT_SYMBOL(ipmi_user_set_run_to_completion);
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c
index cb5cdc6f14b..f951c30236c 100644
--- a/drivers/char/ipmi/ipmi_poweroff.c
+++ b/drivers/char/ipmi/ipmi_poweroff.c
@@ -31,10 +31,13 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <asm/semaphore.h>
-#include <linux/kdev_t.h>
+#include <linux/config.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/proc_fs.h>
#include <linux/string.h>
+#include <linux/completion.h>
+#include <linux/kdev_t.h>
#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
@@ -44,6 +47,18 @@
/* Where to we insert our poweroff function? */
extern void (*pm_power_off)(void);
+/* Definitions for controlling power off (if the system supports it). It
+ * conveniently matches the IPMI chassis control values. */
+#define IPMI_CHASSIS_POWER_DOWN 0 /* power down, the default. */
+#define IPMI_CHASSIS_POWER_CYCLE 0x02 /* power cycle */
+
+/* the IPMI data command */
+static int poweroff_control = IPMI_CHASSIS_POWER_DOWN;
+
+/* parameter definition to allow user to flag power cycle */
+module_param(poweroff_control, int, IPMI_CHASSIS_POWER_DOWN);
+MODULE_PARM_DESC(poweroff_control, " Set to 2 to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
+
/* Stuff from the get device id command. */
static unsigned int mfg_id;
static unsigned int prod_id;
@@ -75,10 +90,10 @@ static struct ipmi_recv_msg halt_recv_msg =
static void receive_handler(struct ipmi_recv_msg *recv_msg, void *handler_data)
{
- struct semaphore *sem = recv_msg->user_msg_data;
+ struct completion *comp = recv_msg->user_msg_data;
- if (sem)
- up(sem);
+ if (comp)
+ complete(comp);
}
static struct ipmi_user_hndl ipmi_poweroff_handler =
@@ -91,27 +106,27 @@ static int ipmi_request_wait_for_response(ipmi_user_t user,
struct ipmi_addr *addr,
struct kernel_ipmi_msg *send_msg)
{
- int rv;
- struct semaphore sem;
+ int rv;
+ struct completion comp;
- sema_init (&sem, 0);
+ init_completion(&comp);
- rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &sem,
+ rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, &comp,
&halt_smi_msg, &halt_recv_msg, 0);
if (rv)
return rv;
- down (&sem);
+ wait_for_completion(&comp);
return halt_recv_msg.msg.data[0];
}
-/* We are in run-to-completion mode, no semaphore is desired. */
+/* We are in run-to-completion mode, no completion is desired. */
static int ipmi_request_in_rc_mode(ipmi_user_t user,
struct ipmi_addr *addr,
struct kernel_ipmi_msg *send_msg)
{
- int rv;
+ int rv;
rv = ipmi_request_supply_msgs(user, addr, 0, send_msg, NULL,
&halt_smi_msg, &halt_recv_msg, 0);
@@ -349,26 +364,38 @@ static void ipmi_poweroff_chassis (ipmi_user_t user)
smi_addr.channel = IPMI_BMC_CHANNEL;
smi_addr.lun = 0;
- printk(KERN_INFO PFX "Powering down via IPMI chassis control command\n");
+ powercyclefailed:
+ printk(KERN_INFO PFX "Powering %s via IPMI chassis control command\n",
+ ((poweroff_control != IPMI_CHASSIS_POWER_CYCLE) ? "down" : "cycle"));
/*
* Power down
*/
send_msg.netfn = IPMI_NETFN_CHASSIS_REQUEST;
send_msg.cmd = IPMI_CHASSIS_CONTROL_CMD;
- data[0] = 0; /* Power down */
+ data[0] = poweroff_control;
send_msg.data = data;
send_msg.data_len = sizeof(data);
rv = ipmi_request_in_rc_mode(user,
(struct ipmi_addr *) &smi_addr,
&send_msg);
if (rv) {
- printk(KERN_ERR PFX "Unable to send chassis powerdown message,"
- " IPMI error 0x%x\n", rv);
- goto out;
+ switch (poweroff_control) {
+ case IPMI_CHASSIS_POWER_CYCLE:
+ /* power cycle failed, default to power down */
+ printk(KERN_ERR PFX "Unable to send chassis power " \
+ "cycle message, IPMI error 0x%x\n", rv);
+ poweroff_control = IPMI_CHASSIS_POWER_DOWN;
+ goto powercyclefailed;
+
+ case IPMI_CHASSIS_POWER_DOWN:
+ default:
+ printk(KERN_ERR PFX "Unable to send chassis power " \
+ "down message, IPMI error 0x%x\n", rv);
+ break;
+ }
}
- out:
return;
}
@@ -430,7 +457,8 @@ static void ipmi_po_new_smi(int if_num)
if (ready)
return;
- rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL, &ipmi_user);
+ rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL,
+ &ipmi_user);
if (rv) {
printk(KERN_ERR PFX "could not create IPMI user, error %d\n",
rv);
@@ -509,21 +537,84 @@ static struct ipmi_smi_watcher smi_watcher =
};
+#ifdef CONFIG_PROC_FS
+/* displays properties to proc */
+static int proc_read_chassctrl(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ return sprintf(page, "%d\t[ 0=powerdown 2=powercycle ]\n",
+ poweroff_control);
+}
+
+/* process property writes from proc */
+static int proc_write_chassctrl(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int rv = count;
+ unsigned int newval = 0;
+
+ sscanf(buffer, "%d", &newval);
+ switch (newval) {
+ case IPMI_CHASSIS_POWER_CYCLE:
+ printk(KERN_INFO PFX "power cycle is now enabled\n");
+ poweroff_control = newval;
+ break;
+
+ case IPMI_CHASSIS_POWER_DOWN:
+ poweroff_control = IPMI_CHASSIS_POWER_DOWN;
+ break;
+
+ default:
+ rv = -EINVAL;
+ break;
+ }
+
+ return rv;
+}
+#endif /* CONFIG_PROC_FS */
+
/*
* Startup and shutdown functions.
*/
static int ipmi_poweroff_init (void)
{
- int rv;
+ int rv;
+ struct proc_dir_entry *file;
printk ("Copyright (C) 2004 MontaVista Software -"
" IPMI Powerdown via sys_reboot version "
IPMI_POWEROFF_VERSION ".\n");
+ switch (poweroff_control) {
+ case IPMI_CHASSIS_POWER_CYCLE:
+ printk(KERN_INFO PFX "Power cycle is enabled.\n");
+ break;
+
+ case IPMI_CHASSIS_POWER_DOWN:
+ default:
+ poweroff_control = IPMI_CHASSIS_POWER_DOWN;
+ break;
+ }
+
rv = ipmi_smi_watcher_register(&smi_watcher);
- if (rv)
+ if (rv) {
printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
+ goto out_err;
+ }
+
+#ifdef CONFIG_PROC_FS
+ file = create_proc_entry("poweroff_control", 0, proc_ipmi_root);
+ if (!file) {
+ printk(KERN_ERR PFX "Unable to create proc power control\n");
+ } else {
+ file->nlink = 1;
+ file->read_proc = proc_read_chassctrl;
+ file->write_proc = proc_write_chassctrl;
+ file->owner = THIS_MODULE;
+ }
+#endif
+ out_err:
return rv;
}
@@ -532,6 +623,10 @@ static __exit void ipmi_poweroff_cleanup(void)
{
int rv;
+#ifdef CONFIG_PROC_FS
+ remove_proc_entry("poweroff_control", proc_ipmi_root);
+#endif
+
ipmi_smi_watcher_unregister(&smi_watcher);
if (ready) {
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 601c7fccb4c..1bbf507adda 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1756,7 +1756,7 @@ static void isicom_flush_buffer(struct tty_struct * tty)
}
-static int __init register_ioregion(void)
+static int __devinit register_ioregion(void)
{
int count, done=0;
for (count=0; count < BOARD_COUNT; count++ ) {
@@ -1771,7 +1771,7 @@ static int __init register_ioregion(void)
return done;
}
-static void __exit unregister_ioregion(void)
+static void unregister_ioregion(void)
{
int count;
for (count=0; count < BOARD_COUNT; count++ )
@@ -1803,7 +1803,7 @@ static struct tty_operations isicom_ops = {
.tiocmset = isicom_tiocmset,
};
-static int __init register_drivers(void)
+static int __devinit register_drivers(void)
{
int error;
@@ -1834,7 +1834,7 @@ static int __init register_drivers(void)
return 0;
}
-static void __exit unregister_drivers(void)
+static void unregister_drivers(void)
{
int error = tty_unregister_driver(isicom_normal);
if (error)
@@ -1842,7 +1842,7 @@ static void __exit unregister_drivers(void)
put_tty_driver(isicom_normal);
}
-static int __init register_isr(void)
+static int __devinit register_isr(void)
{
int count, done=0;
unsigned long irqflags;
@@ -1883,7 +1883,7 @@ static void __exit unregister_isr(void)
}
}
-static int __init isicom_init(void)
+static int __devinit isicom_init(void)
{
int card, channel, base;
struct isi_port * port;
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index c02a21dbad5..52a073eee20 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -407,7 +407,6 @@ static unsigned long stli_eisamemprobeaddrs[] = {
};
static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);
-int stli_eisaprobe = STLI_EISAPROBE;
/*
* Define the Stallion PCI vendor and device IDs.
@@ -4685,7 +4684,7 @@ static int stli_initbrds(void)
#ifdef MODULE
stli_argbrds();
#endif
- if (stli_eisaprobe)
+ if (STLI_EISAPROBE)
stli_findeisabrds();
#ifdef CONFIG_PCI
stli_findpcibrds();
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index e3085b22a36..42187381506 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -23,7 +23,10 @@
#include <linux/devfs_fs_kernel.h>
#include <linux/ptrace.h>
#include <linux/device.h>
+#include <linux/highmem.h>
+#include <linux/crash_dump.h>
#include <linux/backing-dev.h>
+#include <linux/bootmem.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -273,6 +276,40 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
return mmap_mem(file, vma);
}
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * Read memory corresponding to the old kernel.
+ */
+static ssize_t read_oldmem(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long pfn, offset;
+ size_t read = 0, csize;
+ int rc = 0;
+
+ while (count) {
+ pfn = *ppos / PAGE_SIZE;
+ if (pfn > saved_max_pfn)
+ return read;
+
+ offset = (unsigned long)(*ppos % PAGE_SIZE);
+ if (count > PAGE_SIZE - offset)
+ csize = PAGE_SIZE - offset;
+ else
+ csize = count;
+
+ rc = copy_oldmem_page(pfn, buf, csize, offset, 1);
+ if (rc < 0)
+ return rc;
+ buf += csize;
+ *ppos += csize;
+ read += csize;
+ count -= csize;
+ }
+ return read;
+}
+#endif
+
extern long vread(char *buf, char *addr, unsigned long count);
extern long vwrite(char *buf, char *addr, unsigned long count);
@@ -721,6 +758,7 @@ static int open_port(struct inode * inode, struct file * filp)
#define read_full read_zero
#define open_mem open_port
#define open_kmem open_mem
+#define open_oldmem open_mem
static struct file_operations mem_fops = {
.llseek = memory_lseek,
@@ -770,6 +808,13 @@ static struct file_operations full_fops = {
.write = write_full,
};
+#ifdef CONFIG_CRASH_DUMP
+static struct file_operations oldmem_fops = {
+ .read = read_oldmem,
+ .open = open_oldmem,
+};
+#endif
+
static ssize_t kmsg_write(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
@@ -825,6 +870,11 @@ static int memory_open(struct inode * inode, struct file * filp)
case 11:
filp->f_op = &kmsg_fops;
break;
+#ifdef CONFIG_CRASH_DUMP
+ case 12:
+ filp->f_op = &oldmem_fops;
+ break;
+#endif
default:
return -ENXIO;
}
@@ -854,6 +904,9 @@ static const struct {
{8, "random", S_IRUGO | S_IWUSR, &random_fops},
{9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops},
{11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops},
+#ifdef CONFIG_CRASH_DUMP
+ {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
+#endif
};
static struct class *mem_class;
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 3115d318b99..31cf84d6902 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -66,8 +66,6 @@ static unsigned char misc_minors[DYNAMIC_MINORS / 8];
extern int rtc_DP8570A_init(void);
extern int rtc_MK48T08_init(void);
extern int pmu_device_init(void);
-extern int tosh_init(void);
-extern int i8k_init(void);
#ifdef CONFIG_PROC_FS
static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
@@ -314,12 +312,6 @@ static int __init misc_init(void)
#ifdef CONFIG_PMAC_PBOOK
pmu_device_init();
#endif
-#ifdef CONFIG_TOSHIBA
- tosh_init();
-#endif
-#ifdef CONFIG_I8K
- i8k_init();
-#endif
if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
printk("unable to get major %d for misc devices\n",
MISC_MAJOR);
diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c
index ab00f51475d..613aed9e184 100644
--- a/drivers/char/mwave/3780i.c
+++ b/drivers/char/mwave/3780i.c
@@ -107,8 +107,8 @@ void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
spin_unlock_irqrestore(&dsp_lock, flags);
}
-void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
- unsigned char ucValue)
+static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
+ unsigned char ucValue)
{
DSP_ISA_SLAVE_CONTROL rSlaveControl;
DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
@@ -141,6 +141,7 @@ void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
}
+#if 0
unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
unsigned uIndex)
{
@@ -167,6 +168,7 @@ unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
return ucValue;
}
+#endif /* 0 */
int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
unsigned short *pIrqMap,
diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h
index 3e7d020d1bf..270431ca7da 100644
--- a/drivers/char/mwave/3780i.h
+++ b/drivers/char/mwave/3780i.h
@@ -338,10 +338,6 @@ unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
unsigned long ulMsaAddr);
void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
unsigned long ulMsaAddr, unsigned short usValue);
-void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
- unsigned char ucValue);
-unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
- unsigned uIndex);
int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
unsigned short *pusIPCSource);
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
index ab650cd6efc..d6c72e0934e 100644
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -242,20 +242,14 @@ int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData)
{
int retval = 0;
DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
struct resource *pres;
-#endif
PRINTK_2(TRACE_TP3780I,
"tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
if ( pres == NULL ) retval = -EIO;
-#else
- retval = check_region(pSettings->usDspBaseIO, 16);
- if (!retval) request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
-#endif
+
if (retval) {
PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO);
retval = -EIO;
@@ -292,7 +286,7 @@ int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData)
int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
{
DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
- BOOLEAN bDSPPoweredUp = FALSE, bDSPEnabled = FALSE, bInterruptAllocated = FALSE;
+ BOOLEAN bDSPPoweredUp = FALSE, bInterruptAllocated = FALSE;
PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData);
@@ -397,8 +391,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) {
PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n");
goto exit_cleanup;
- } else {
- bDSPEnabled = TRUE;
}
EnableSRAM(pBDData);
@@ -411,8 +403,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
exit_cleanup:
PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n");
- if (bDSPEnabled)
- dsp3780I_DisableDSP(pSettings);
if (bDSPPoweredUp)
smapi_set_DSP_power_state(FALSE);
if (bInterruptAllocated) {
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index b3dbff1cf96..5079beda69b 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -960,7 +960,7 @@ static char hdlc_unregister_fail[] __exitdata =
static void __exit n_hdlc_exit(void)
{
/* Release tty registration of line discipline */
- int status = tty_register_ldisc(N_HDLC, NULL);
+ int status = tty_unregister_ldisc(N_HDLC);
if (status)
printk(hdlc_unregister_fail, status);
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 3883073ab48..2291a87e8ad 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -200,7 +200,7 @@ static void __exit r3964_exit(void)
TRACE_M ("cleanup_module()");
- status=tty_register_ldisc(N_R3964, NULL);
+ status=tty_unregister_ldisc(N_R3964);
if(status!=0)
{
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index f63a3fd7ca6..1af733d0732 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -211,12 +211,13 @@ nvram_check_checksum(void)
return rv;
}
-void
+static void
__nvram_set_checksum(void)
{
mach_set_checksum();
}
+#if 0
void
nvram_set_checksum(void)
{
@@ -226,6 +227,7 @@ nvram_set_checksum(void)
__nvram_set_checksum();
spin_unlock_irqrestore(&rtc_lock, flags);
}
+#endif /* 0 */
/*
* The are the file operation function for user access to /dev/nvram
@@ -921,6 +923,4 @@ EXPORT_SYMBOL(__nvram_write_byte);
EXPORT_SYMBOL(nvram_write_byte);
EXPORT_SYMBOL(__nvram_check_checksum);
EXPORT_SYMBOL(nvram_check_checksum);
-EXPORT_SYMBOL(__nvram_set_checksum);
-EXPORT_SYMBOL(nvram_set_checksum);
MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h
index e8f3860f472..01987c6dc39 100644
--- a/drivers/char/rio/func.h
+++ b/drivers/char/rio/func.h
@@ -147,7 +147,6 @@ struct rio_info * rio_info_store( int cmd, struct rio_info * p);
extern int rio_pcicopy(char *src, char *dst, int n);
extern int rio_minor (struct tty_struct *tty);
extern int rio_ismodem (struct tty_struct *tty);
-extern void rio_udelay (int usecs);
extern void rio_start_card_running (struct Host * HostP);
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 763893e289b..7db3370f497 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -354,11 +354,6 @@ int rio_ismodem(struct tty_struct *tty)
}
-void rio_udelay (int usecs)
-{
- udelay (usecs);
-}
-
static int rio_set_real_termios (void *ptr)
{
int rv, modem;
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index dca941ed10c..898a126ae3e 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -37,6 +37,7 @@ static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/errno.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/string.h>
@@ -1560,14 +1561,14 @@ uint Slot;
INTERRUPT_DISABLE | BYTE_OPERATION |
SLOW_LINKS | SLOW_AT_BUS);
WBYTE(DpRamP->DpResetTpu, 0xFF);
- rio_udelay (3);
+ udelay(3);
rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n");
WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
INTERRUPT_DISABLE | BYTE_OPERATION |
SLOW_LINKS | SLOW_AT_BUS);
WBYTE(DpRamP->DpResetTpu, 0xFF);
- rio_udelay (3);
+ udelay(3);
break;
#ifdef FUTURE_RELEASE
case RIO_EISA:
@@ -1599,7 +1600,7 @@ uint Slot;
DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM;
DpRamP->DpResetInt = 0xFF;
DpRamP->DpResetTpu = 0xFF;
- rio_udelay (100);
+ udelay(100);
/* for (i=0; i<6000; i++); */
/* suspend( 3 ); */
break;
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index db655002671..78a321afdf4 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -524,16 +524,16 @@ riotclose(void *ptr)
register uint SysPort = dev;
struct ttystatics *tp; /* pointer to our ttystruct */
#endif
- struct Port *PortP =ptr; /* pointer to the port structure */
+ struct Port *PortP = ptr; /* pointer to the port structure */
int deleted = 0;
int try = -1; /* Disable the timeouts by setting them to -1 */
int repeat_this = -1; /* Congrats to those having 15 years of
uptime! (You get to break the driver.) */
- long end_time;
+ unsigned long end_time;
struct tty_struct * tty;
unsigned long flags;
int Modem;
- int rv =0;
+ int rv = 0;
rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
@@ -620,7 +620,7 @@ riotclose(void *ptr)
if (repeat_this -- <= 0) {
rv = -EINTR;
rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
- RIOPreemptiveCmd(p, PortP, FCLOSE );
+ RIOPreemptiveCmd(p, PortP, FCLOSE);
goto close_end;
}
rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
@@ -656,14 +656,12 @@ riotclose(void *ptr)
goto close_end;
}
-
-
/* Can't call RIOShortCommand with the port locked. */
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
- RIOPreemptiveCmd(p, PortP,FCLOSE);
- goto close_end;
+ RIOPreemptiveCmd(p, PortP, FCLOSE);
+ goto close_end;
}
if (!deleted)
@@ -698,7 +696,6 @@ riotclose(void *ptr)
*/
PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);
-
#ifdef STATS
PortP->Stat.CloseCnt++;
#endif
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 5bcbeb0cb9a..f463d6baa68 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -161,6 +161,64 @@ static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
UPCI_AIOP_INTR_BIT_3
};
+static Byte_t RData[RDATASIZE] = {
+ 0x00, 0x09, 0xf6, 0x82,
+ 0x02, 0x09, 0x86, 0xfb,
+ 0x04, 0x09, 0x00, 0x0a,
+ 0x06, 0x09, 0x01, 0x0a,
+ 0x08, 0x09, 0x8a, 0x13,
+ 0x0a, 0x09, 0xc5, 0x11,
+ 0x0c, 0x09, 0x86, 0x85,
+ 0x0e, 0x09, 0x20, 0x0a,
+ 0x10, 0x09, 0x21, 0x0a,
+ 0x12, 0x09, 0x41, 0xff,
+ 0x14, 0x09, 0x82, 0x00,
+ 0x16, 0x09, 0x82, 0x7b,
+ 0x18, 0x09, 0x8a, 0x7d,
+ 0x1a, 0x09, 0x88, 0x81,
+ 0x1c, 0x09, 0x86, 0x7a,
+ 0x1e, 0x09, 0x84, 0x81,
+ 0x20, 0x09, 0x82, 0x7c,
+ 0x22, 0x09, 0x0a, 0x0a
+};
+
+static Byte_t RRegData[RREGDATASIZE] = {
+ 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
+ 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
+ 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
+ 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
+ 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
+ 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
+ 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
+ 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
+ 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
+ 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
+ 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
+ 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
+ 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
+};
+
+static CONTROLLER_T sController[CTL_SIZE] = {
+ {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+ {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+ {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+ {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+ {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
+};
+
+static Byte_t sBitMapClrTbl[8] = {
+ 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
+};
+
+static Byte_t sBitMapSetTbl[8] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
+};
+
+static int sClockPrescale = 0x14;
+
/*
* Line number is the ttySIx number (x), the Minor number. We
* assign them sequentially, starting at zero. The following
@@ -177,6 +235,26 @@ static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
static void rp_start(struct tty_struct *tty);
+static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
+ int ChanNum);
+static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
+static void sFlushRxFIFO(CHANNEL_T * ChP);
+static void sFlushTxFIFO(CHANNEL_T * ChP);
+static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
+static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
+static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
+static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
+static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
+static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
+ ByteIO_t * AiopIOList, int AiopIOListSize,
+ WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
+ int PeriodicOnly, int altChanRingIndicator,
+ int UPCIRingInd);
+static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
+ ByteIO_t * AiopIOList, int AiopIOListSize,
+ int IRQNum, Byte_t Frequency, int PeriodicOnly);
+static int sReadAiopID(ByteIO_t io);
+static int sReadAiopNumChan(WordIO_t io);
#ifdef MODULE
MODULE_AUTHOR("Theodore Ts'o");
@@ -1798,7 +1876,7 @@ static void rp_flush_buffer(struct tty_struct *tty)
* init's aiopic and serial port hardware.
* Inputs: i is the board number (0-n)
*/
-__init int register_PCI(int i, struct pci_dev *dev)
+static __init int register_PCI(int i, struct pci_dev *dev)
{
int num_aiops, aiop, max_num_aiops, num_chan, chan;
unsigned int aiopio[MAX_AIOPS_PER_BOARD];
@@ -2453,72 +2531,6 @@ static void rp_cleanup_module(void)
}
#endif
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-static Byte_t RData[RDATASIZE] = {
- 0x00, 0x09, 0xf6, 0x82,
- 0x02, 0x09, 0x86, 0xfb,
- 0x04, 0x09, 0x00, 0x0a,
- 0x06, 0x09, 0x01, 0x0a,
- 0x08, 0x09, 0x8a, 0x13,
- 0x0a, 0x09, 0xc5, 0x11,
- 0x0c, 0x09, 0x86, 0x85,
- 0x0e, 0x09, 0x20, 0x0a,
- 0x10, 0x09, 0x21, 0x0a,
- 0x12, 0x09, 0x41, 0xff,
- 0x14, 0x09, 0x82, 0x00,
- 0x16, 0x09, 0x82, 0x7b,
- 0x18, 0x09, 0x8a, 0x7d,
- 0x1a, 0x09, 0x88, 0x81,
- 0x1c, 0x09, 0x86, 0x7a,
- 0x1e, 0x09, 0x84, 0x81,
- 0x20, 0x09, 0x82, 0x7c,
- 0x22, 0x09, 0x0a, 0x0a
-};
-
-static Byte_t RRegData[RREGDATASIZE] = {
- 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
- 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
- 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
- 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
- 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
- 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
- 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
- 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
- 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
- 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
- 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
- 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
- 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
-};
-
-CONTROLLER_T sController[CTL_SIZE] = {
- {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
- {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
- {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
- {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
- {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
- {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
- {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
- {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
-};
-
-Byte_t sBitMapClrTbl[8] = {
- 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
-};
-
-Byte_t sBitMapSetTbl[8] = {
- 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
-};
-
-int sClockPrescale = 0x14;
-
/***************************************************************************
Function: sInitController
Purpose: Initialization of controller global registers and controller
@@ -2554,22 +2566,22 @@ Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
FREQ_4HZ - 4 Hertz
If IRQNum is set to 0 the Frequency parameter is
overidden, it is forced to a value of FREQ_DIS.
- int PeriodicOnly: TRUE if all interrupts except the periodic
+ int PeriodicOnly: 1 if all interrupts except the periodic
interrupt are to be blocked.
- FALSE is both the periodic interrupt and
+ 0 is both the periodic interrupt and
other channel interrupts are allowed.
If IRQNum is set to 0 the PeriodicOnly parameter is
- overidden, it is forced to a value of FALSE.
+ overidden, it is forced to a value of 0.
Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
initialization failed.
Comments:
If periodic interrupts are to be disabled but AIOP interrupts
- are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
+ are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
If interrupts are to be completely disabled set IRQNum to 0.
- Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
+ Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
invalid combination.
This function performs initialization of global interrupt modes,
@@ -2589,9 +2601,9 @@ Warnings: No range checking on any of the parameters is done.
After this function all AIOPs on the controller are disabled,
they can be enabled with sEnAiop().
*/
-int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
- ByteIO_t * AiopIOList, int AiopIOListSize, int IRQNum,
- Byte_t Frequency, int PeriodicOnly)
+static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
+ ByteIO_t * AiopIOList, int AiopIOListSize,
+ int IRQNum, Byte_t Frequency, int PeriodicOnly)
{
int i;
ByteIO_t io;
@@ -2687,22 +2699,22 @@ Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
FREQ_4HZ - 4 Hertz
If IRQNum is set to 0 the Frequency parameter is
overidden, it is forced to a value of FREQ_DIS.
- int PeriodicOnly: TRUE if all interrupts except the periodic
+ int PeriodicOnly: 1 if all interrupts except the periodic
interrupt are to be blocked.
- FALSE is both the periodic interrupt and
+ 0 is both the periodic interrupt and
other channel interrupts are allowed.
If IRQNum is set to 0 the PeriodicOnly parameter is
- overidden, it is forced to a value of FALSE.
+ overidden, it is forced to a value of 0.
Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
initialization failed.
Comments:
If periodic interrupts are to be disabled but AIOP interrupts
- are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE.
+ are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
If interrupts are to be completely disabled set IRQNum to 0.
- Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an
+ Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
invalid combination.
This function performs initialization of global interrupt modes,
@@ -2722,11 +2734,11 @@ Warnings: No range checking on any of the parameters is done.
After this function all AIOPs on the controller are disabled,
they can be enabled with sEnAiop().
*/
-int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
- ByteIO_t * AiopIOList, int AiopIOListSize,
- WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
- int PeriodicOnly, int altChanRingIndicator,
- int UPCIRingInd)
+static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
+ ByteIO_t * AiopIOList, int AiopIOListSize,
+ WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
+ int PeriodicOnly, int altChanRingIndicator,
+ int UPCIRingInd)
{
int i;
ByteIO_t io;
@@ -2784,7 +2796,7 @@ Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X
Warnings: No context switches are allowed while executing this function.
*/
-int sReadAiopID(ByteIO_t io)
+static int sReadAiopID(ByteIO_t io)
{
Byte_t AiopID; /* ID byte from AIOP */
@@ -2810,7 +2822,7 @@ Comments: The number of channels is determined by write/reads from identical
AIOP, otherwise it is an 8 channel.
Warnings: No context switches are allowed while executing this function.
*/
-int sReadAiopNumChan(WordIO_t io)
+static int sReadAiopNumChan(WordIO_t io)
{
Word_t x;
static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
@@ -2834,15 +2846,15 @@ Call: sInitChan(CtlP,ChP,AiopNum,ChanNum)
CHANNEL_T *ChP; Ptr to channel structure
int AiopNum; AIOP number within controller
int ChanNum; Channel number within AIOP
-Return: int: TRUE if initialization succeeded, FALSE if it fails because channel
+Return: int: 1 if initialization succeeded, 0 if it fails because channel
number exceeds number of channels available in AIOP.
Comments: This function must be called before a channel can be used.
Warnings: No range checking on any of the parameters is done.
No context switches are allowed while executing this function.
*/
-int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
- int ChanNum)
+static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
+ int ChanNum)
{
int i;
WordIO_t AiopIO;
@@ -2853,7 +2865,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
int brd9600;
if (ChanNum >= CtlP->AiopNumChan[AiopNum])
- return (FALSE); /* exceeds num chans in AIOP */
+ return 0; /* exceeds num chans in AIOP */
/* Channel, AIOP, and controller identifiers */
ChP->CtlP = CtlP;
@@ -2968,7 +2980,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
ChP->TxPrioBuf = ChOff + _TXP_BUF;
sEnRxProcessor(ChP); /* start the Rx processor */
- return (TRUE);
+ return 1;
}
/***************************************************************************
@@ -2989,7 +3001,7 @@ Warnings: No context switches are allowed while executing this function.
After calling this function a delay of 4 uS is required to ensure
that the receive processor is no longer processing this channel.
*/
-void sStopRxProcessor(CHANNEL_T * ChP)
+static void sStopRxProcessor(CHANNEL_T * ChP)
{
Byte_t R[4];
@@ -3014,18 +3026,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
this function.
Warnings: No context switches are allowed while executing this function.
*/
-void sFlushRxFIFO(CHANNEL_T * ChP)
+static void sFlushRxFIFO(CHANNEL_T * ChP)
{
int i;
Byte_t Ch; /* channel number within AIOP */
- int RxFIFOEnabled; /* TRUE if Rx FIFO enabled */
+ int RxFIFOEnabled; /* 1 if Rx FIFO enabled */
if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */
return; /* don't need to flush */
- RxFIFOEnabled = FALSE;
+ RxFIFOEnabled = 0;
if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */
- RxFIFOEnabled = TRUE;
+ RxFIFOEnabled = 1;
sDisRxFIFO(ChP); /* disable it */
for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */
sInB(ChP->IntChan); /* depends on bus i/o timing */
@@ -3056,18 +3068,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
this function.
Warnings: No context switches are allowed while executing this function.
*/
-void sFlushTxFIFO(CHANNEL_T * ChP)
+static void sFlushTxFIFO(CHANNEL_T * ChP)
{
int i;
Byte_t Ch; /* channel number within AIOP */
- int TxEnabled; /* TRUE if transmitter enabled */
+ int TxEnabled; /* 1 if transmitter enabled */
if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */
return; /* don't need to flush */
- TxEnabled = FALSE;
+ TxEnabled = 0;
if (ChP->TxControl[3] & TX_ENABLE) {
- TxEnabled = TRUE;
+ TxEnabled = 1;
sDisTransmit(ChP); /* disable transmitter */
}
sStopRxProcessor(ChP); /* stop Rx processor */
@@ -3096,7 +3108,7 @@ Comments: The priority byte is transmitted before any data in the Tx FIFO.
Warnings: No context switches are allowed while executing this function.
*/
-int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
+static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
{
Byte_t DWBuf[4]; /* buffer for double word writes */
Word_t *WordPtr; /* must be far because Win SS != DS */
@@ -3158,7 +3170,7 @@ Comments: If an interrupt enable flag is set in Flags, that interrupt will be
enable channel interrupts. This would allow the global interrupt
status register to be used to determine which AIOPs need service.
*/
-void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
+static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
{
Byte_t Mask; /* Interrupt Mask Register */
@@ -3202,7 +3214,7 @@ Comments: If an interrupt flag is set in Flags, that interrupt will be
this channel's bit from being set in the AIOP's Interrupt Channel
Register.
*/
-void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
+static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
{
Byte_t Mask; /* Interrupt Mask Register */
@@ -3218,7 +3230,7 @@ void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
}
}
-void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
+static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
{
sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
}
@@ -3227,7 +3239,7 @@ void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
* Not an official SSCI function, but how to reset RocketModems.
* ISA bus version
*/
-void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
+static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
{
ByteIO_t addr;
Byte_t val;
@@ -3252,7 +3264,7 @@ void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
* Not an official SSCI function, but how to reset RocketModems.
* PCI bus version
*/
-void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
+static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
{
ByteIO_t addr;
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 802687290ee..3a8bcc85bc1 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1130,46 +1130,6 @@ Warnings: This function writes the data byte without checking to see if
*/
#define sWriteTxByte(IO,DATA) sOutB(IO,DATA)
-int sInitController(CONTROLLER_T * CtlP,
- int CtlNum,
- ByteIO_t MudbacIO,
- ByteIO_t * AiopIOList,
- int AiopIOListSize,
- int IRQNum, Byte_t Frequency, int PeriodicOnly);
-
-int sPCIInitController(CONTROLLER_T * CtlP,
- int CtlNum,
- ByteIO_t * AiopIOList,
- int AiopIOListSize,
- WordIO_t ConfigIO,
- int IRQNum,
- Byte_t Frequency,
- int PeriodicOnly,
- int altChanRingIndicator, int UPCIRingInd);
-
-int sReadAiopID(ByteIO_t io);
-int sReadAiopNumChan(WordIO_t io);
-int sInitChan(CONTROLLER_T * CtlP,
- CHANNEL_T * ChP, int AiopNum, int ChanNum);
-Byte_t sGetRxErrStatus(CHANNEL_T * ChP);
-void sStopRxProcessor(CHANNEL_T * ChP);
-void sStopSWInFlowCtl(CHANNEL_T * ChP);
-void sFlushRxFIFO(CHANNEL_T * ChP);
-void sFlushTxFIFO(CHANNEL_T * ChP);
-int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
-void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
-void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
-void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
-void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
-void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
-
-extern Byte_t R[RDATASIZE];
-extern CONTROLLER_T sController[CTL_SIZE];
-extern Byte_t sIRQMap[16];
-extern Byte_t sBitMapClrTbl[8];
-extern Byte_t sBitMapSetTbl[8];
-extern int sClockPrescale;
-
/*
* Begin Linux specific definitions for the Rocketport driver
*
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index f59f7cbd525..af79805b557 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <linux/vt_kern.h>
#include <linux/workqueue.h>
+#include <linux/kexec.h>
#include <asm/ptrace.h>
@@ -94,6 +95,21 @@ static struct sysrq_key_op sysrq_unraw_op = {
};
#endif /* CONFIG_VT */
+#ifdef CONFIG_KEXEC
+/* crashdump sysrq handler */
+static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
+ struct tty_struct *tty)
+{
+ crash_kexec(pt_regs);
+}
+static struct sysrq_key_op sysrq_crashdump_op = {
+ .handler = sysrq_handle_crashdump,
+ .help_msg = "Crashdump",
+ .action_msg = "Trigger a crashdump",
+ .enable_mask = SYSRQ_ENABLE_DUMP,
+};
+#endif
+
/* reboot sysrq handler */
static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
struct tty_struct *tty)
@@ -273,8 +289,12 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = {
it is handled specially on the sparc
and will never arrive */
/* b */ &sysrq_reboot_op,
-/* c */ NULL,
-/* d */ NULL,
+#ifdef CONFIG_KEXEC
+/* c */ &sysrq_crashdump_op,
+#else
+/* c */ NULL,
+#endif
+/* d */ NULL,
/* e */ &sysrq_term_op,
/* f */ &sysrq_moom_op,
/* g */ NULL,
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index 58e21fe4426..0c6f521abd0 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -73,16 +73,20 @@
#define TOSH_MINOR_DEV 181
-static int tosh_id = 0x0000;
-static int tosh_bios = 0x0000;
-static int tosh_date = 0x0000;
-static int tosh_sci = 0x0000;
-static int tosh_fan = 0;
-
-static int tosh_fn = 0;
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
+MODULE_DESCRIPTION("Toshiba laptop SMM driver");
+MODULE_SUPPORTED_DEVICE("toshiba");
-module_param(tosh_fn, int, 0);
+static int tosh_fn;
+module_param_named(fn, tosh_fn, int, 0);
+MODULE_PARM_DESC(fn, "User specified Fn key detection port");
+static int tosh_id;
+static int tosh_bios;
+static int tosh_date;
+static int tosh_sci;
+static int tosh_fan;
static int tosh_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
@@ -359,7 +363,7 @@ static int tosh_get_machine_id(void)
unsigned long address;
id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa));
-
+
/* do we have a SCTTable machine identication number on our hands */
if (id==0xfc2f) {
@@ -424,7 +428,7 @@ static int tosh_probe(void)
}
/* call the Toshiba SCI support check routine */
-
+
regs.eax = 0xf0f0;
regs.ebx = 0x0000;
regs.ecx = 0x0000;
@@ -440,7 +444,7 @@ static int tosh_probe(void)
/* if we get this far then we are running on a Toshiba (probably)! */
tosh_sci = regs.edx & 0xffff;
-
+
/* next get the machine ID of the current laptop */
tosh_id = tosh_get_machine_id();
@@ -475,16 +479,15 @@ static int tosh_probe(void)
return 0;
}
-int __init tosh_init(void)
+static int __init toshiba_init(void)
{
int retval;
/* are we running on a Toshiba laptop */
- if (tosh_probe()!=0)
- return -EIO;
+ if (tosh_probe())
+ return -ENODEV;
- printk(KERN_INFO "Toshiba System Managment Mode driver v"
- TOSH_VERSION"\n");
+ printk(KERN_INFO "Toshiba System Managment Mode driver v" TOSH_VERSION "\n");
/* set the port to use for Fn status if not specified as a parameter */
if (tosh_fn==0x00)
@@ -492,12 +495,12 @@ int __init tosh_init(void)
/* register the device file */
retval = misc_register(&tosh_device);
- if(retval < 0)
+ if (retval < 0)
return retval;
#ifdef CONFIG_PROC_FS
/* register the proc entry */
- if(create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL){
+ if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) {
misc_deregister(&tosh_device);
return -ENOMEM;
}
@@ -506,27 +509,12 @@ int __init tosh_init(void)
return 0;
}
-#ifdef MODULE
-int init_module(void)
-{
- return tosh_init();
-}
-
-void cleanup_module(void)
+static void __exit toshiba_exit(void)
{
- /* remove the proc entry */
-
remove_proc_entry("toshiba", NULL);
-
- /* unregister the device file */
-
misc_deregister(&tosh_device);
}
-#endif
-MODULE_LICENSE("GPL");
-MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port");
-MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
-MODULE_DESCRIPTION("Toshiba laptop SMM driver");
-MODULE_SUPPORTED_DEVICE("toshiba");
+module_init(toshiba_init);
+module_exit(toshiba_exit);
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 8ce508b2986..854475c54f0 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -19,7 +19,7 @@
*
* Note, the TPM chip is not interrupt driven (only polling)
* and can have very long timeouts (minutes!). Hence the unusual
- * calls to schedule_timeout.
+ * calls to msleep.
*
*/
@@ -28,19 +28,16 @@
#include <linux/spinlock.h>
#include "tpm.h"
-#define TPM_MINOR 224 /* officially assigned */
-
-#define TPM_BUFSIZE 2048
-
-/* PCI configuration addresses */
-#define PCI_GEN_PMCON_1 0xA0
-#define PCI_GEN1_DEC 0xE4
-#define PCI_LPC_EN 0xE6
-#define PCI_GEN2_DEC 0xEC
+enum tpm_const {
+ TPM_MINOR = 224, /* officially assigned */
+ TPM_BUFSIZE = 2048,
+ TPM_NUM_DEVICES = 256,
+ TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
+};
static LIST_HEAD(tpm_chip_list);
static DEFINE_SPINLOCK(driver_lock);
-static int dev_mask[32];
+static int dev_mask[TPM_NUM_MASK_ENTRIES];
static void user_reader_timeout(unsigned long ptr)
{
@@ -52,92 +49,17 @@ static void user_reader_timeout(unsigned long ptr)
up(&chip->buffer_mutex);
}
-void tpm_time_expired(unsigned long ptr)
-{
- int *exp = (int *) ptr;
- *exp = 1;
-}
-
-EXPORT_SYMBOL_GPL(tpm_time_expired);
-
-/*
- * Initialize the LPC bus and enable the TPM ports
- */
-int tpm_lpc_bus_init(struct pci_dev *pci_dev, u16 base)
-{
- u32 lpcenable, tmp;
- int is_lpcm = 0;
-
- switch (pci_dev->vendor) {
- case PCI_VENDOR_ID_INTEL:
- switch (pci_dev->device) {
- case PCI_DEVICE_ID_INTEL_82801CA_12:
- case PCI_DEVICE_ID_INTEL_82801DB_12:
- is_lpcm = 1;
- break;
- }
- /* init ICH (enable LPC) */
- pci_read_config_dword(pci_dev, PCI_GEN1_DEC, &lpcenable);
- lpcenable |= 0x20000000;
- pci_write_config_dword(pci_dev, PCI_GEN1_DEC, lpcenable);
-
- if (is_lpcm) {
- pci_read_config_dword(pci_dev, PCI_GEN1_DEC,
- &lpcenable);
- if ((lpcenable & 0x20000000) == 0) {
- dev_err(&pci_dev->dev,
- "cannot enable LPC\n");
- return -ENODEV;
- }
- }
-
- /* initialize TPM registers */
- pci_read_config_dword(pci_dev, PCI_GEN2_DEC, &tmp);
-
- if (!is_lpcm)
- tmp = (tmp & 0xFFFF0000) | (base & 0xFFF0);
- else
- tmp =
- (tmp & 0xFFFF0000) | (base & 0xFFF0) |
- 0x00000001;
-
- pci_write_config_dword(pci_dev, PCI_GEN2_DEC, tmp);
-
- if (is_lpcm) {
- pci_read_config_dword(pci_dev, PCI_GEN_PMCON_1,
- &tmp);
- tmp |= 0x00000004; /* enable CLKRUN */
- pci_write_config_dword(pci_dev, PCI_GEN_PMCON_1,
- tmp);
- }
- tpm_write_index(0x0D, 0x55); /* unlock 4F */
- tpm_write_index(0x0A, 0x00); /* int disable */
- tpm_write_index(0x08, base); /* base addr lo */
- tpm_write_index(0x09, (base & 0xFF00) >> 8); /* base addr hi */
- tpm_write_index(0x0D, 0xAA); /* lock 4F */
- break;
- case PCI_VENDOR_ID_AMD:
- /* nothing yet */
- break;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL_GPL(tpm_lpc_bus_init);
-
/*
* Internal kernel interface to transmit TPM commands
*/
static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
size_t bufsiz)
{
- ssize_t len;
+ ssize_t rc;
u32 count;
- __be32 *native_size;
+ unsigned long stop;
- native_size = (__force __be32 *) (buf + 2);
- count = be32_to_cpu(*native_size);
+ count = be32_to_cpu(*((__be32 *) (buf + 2)));
if (count == 0)
return -ENODATA;
@@ -149,53 +71,49 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
down(&chip->tpm_mutex);
- if ((len = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+ if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
dev_err(&chip->pci_dev->dev,
- "tpm_transmit: tpm_send: error %zd\n", len);
- return len;
+ "tpm_transmit: tpm_send: error %zd\n", rc);
+ goto out;
}
- down(&chip->timer_manipulation_mutex);
- chip->time_expired = 0;
- init_timer(&chip->device_timer);
- chip->device_timer.function = tpm_time_expired;
- chip->device_timer.expires = jiffies + 2 * 60 * HZ;
- chip->device_timer.data = (unsigned long) &chip->time_expired;
- add_timer(&chip->device_timer);
- up(&chip->timer_manipulation_mutex);
-
+ stop = jiffies + 2 * 60 * HZ;
do {
u8 status = inb(chip->vendor->base + 1);
if ((status & chip->vendor->req_complete_mask) ==
chip->vendor->req_complete_val) {
- down(&chip->timer_manipulation_mutex);
- del_singleshot_timer_sync(&chip->device_timer);
- up(&chip->timer_manipulation_mutex);
goto out_recv;
}
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(TPM_TIMEOUT);
+
+ if ((status == chip->vendor->req_canceled)) {
+ dev_err(&chip->pci_dev->dev, "Operation Canceled\n");
+ rc = -ECANCELED;
+ goto out;
+ }
+
+ msleep(TPM_TIMEOUT); /* CHECK */
rmb();
- } while (!chip->time_expired);
+ } while (time_before(jiffies, stop));
chip->vendor->cancel(chip);
- dev_err(&chip->pci_dev->dev, "Time expired\n");
- up(&chip->tpm_mutex);
- return -EIO;
+ dev_err(&chip->pci_dev->dev, "Operation Timed out\n");
+ rc = -ETIME;
+ goto out;
out_recv:
- len = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
- if (len < 0)
+ rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+ if (rc < 0)
dev_err(&chip->pci_dev->dev,
- "tpm_transmit: tpm_recv: error %zd\n", len);
+ "tpm_transmit: tpm_recv: error %zd\n", rc);
+out:
up(&chip->tpm_mutex);
- return len;
+ return rc;
}
#define TPM_DIGEST_SIZE 20
#define CAP_PCR_RESULT_SIZE 18
-static u8 cap_pcr[] = {
+static const u8 cap_pcr[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 22, /* length */
0, 0, 0, 101, /* TPM_ORD_GetCapability */
@@ -205,75 +123,94 @@ static u8 cap_pcr[] = {
};
#define READ_PCR_RESULT_SIZE 30
-static u8 pcrread[] = {
+static const u8 pcrread[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 14, /* length */
0, 0, 0, 21, /* TPM_ORD_PcrRead */
0, 0, 0, 0 /* PCR index */
};
-static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char *buf)
+ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
u8 data[READ_PCR_RESULT_SIZE];
ssize_t len;
- int i, j, index, num_pcrs;
+ int i, j, num_pcrs;
+ __be32 index;
char *str = buf;
struct tpm_chip *chip =
- pci_get_drvdata(container_of(dev, struct pci_dev, dev));
+ pci_get_drvdata(to_pci_dev(dev));
if (chip == NULL)
return -ENODEV;
memcpy(data, cap_pcr, sizeof(cap_pcr));
if ((len = tpm_transmit(chip, data, sizeof(data)))
- < CAP_PCR_RESULT_SIZE)
- return len;
+ < CAP_PCR_RESULT_SIZE) {
+ dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+ "attempting to determine the number of PCRS\n",
+ be32_to_cpu(*((__be32 *) (data + 6))));
+ return 0;
+ }
- num_pcrs = be32_to_cpu(*((__force __be32 *) (data + 14)));
+ num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
for (i = 0; i < num_pcrs; i++) {
memcpy(data, pcrread, sizeof(pcrread));
index = cpu_to_be32(i);
memcpy(data + 10, &index, 4);
if ((len = tpm_transmit(chip, data, sizeof(data)))
- < READ_PCR_RESULT_SIZE)
- return len;
+ < READ_PCR_RESULT_SIZE){
+ dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred"
+ " attempting to read PCR %d of %d\n",
+ be32_to_cpu(*((__be32 *) (data + 6))), i, num_pcrs);
+ goto out;
+ }
str += sprintf(str, "PCR-%02d: ", i);
for (j = 0; j < TPM_DIGEST_SIZE; j++)
str += sprintf(str, "%02X ", *(data + 10 + j));
str += sprintf(str, "\n");
}
+out:
return str - buf;
}
-
-static DEVICE_ATTR(pcrs, S_IRUGO, show_pcrs, NULL);
+EXPORT_SYMBOL_GPL(tpm_show_pcrs);
#define READ_PUBEK_RESULT_SIZE 314
-static u8 readpubek[] = {
+static const u8 readpubek[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 30, /* length */
0, 0, 0, 124, /* TPM_ORD_ReadPubek */
};
-static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, char *buf)
+ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- u8 data[READ_PUBEK_RESULT_SIZE];
+ u8 *data;
ssize_t len;
- __be32 *native_val;
- int i;
+ int i, rc;
char *str = buf;
struct tpm_chip *chip =
- pci_get_drvdata(container_of(dev, struct pci_dev, dev));
+ pci_get_drvdata(to_pci_dev(dev));
if (chip == NULL)
return -ENODEV;
+ data = kmalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
memcpy(data, readpubek, sizeof(readpubek));
memset(data + sizeof(readpubek), 0, 20); /* zero nonce */
- if ((len = tpm_transmit(chip, data, sizeof(data))) <
- READ_PUBEK_RESULT_SIZE)
- return len;
+ if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
+ READ_PUBEK_RESULT_SIZE) {
+ dev_dbg(&chip->pci_dev->dev, "A TPM error (%d) occurred "
+ "attempting to read the PUBEK\n",
+ be32_to_cpu(*((__be32 *) (data + 6))));
+ rc = 0;
+ goto out;
+ }
/*
ignore header 10 bytes
@@ -286,8 +223,6 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha
ignore checksum 20 bytes
*/
- native_val = (__force __be32 *) (data + 34);
-
str +=
sprintf(str,
"Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
@@ -298,21 +233,23 @@ static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, cha
data[15], data[16], data[17], data[22], data[23],
data[24], data[25], data[26], data[27], data[28],
data[29], data[30], data[31], data[32], data[33],
- be32_to_cpu(*native_val)
- );
+ be32_to_cpu(*((__be32 *) (data + 34))));
for (i = 0; i < 256; i++) {
- str += sprintf(str, "%02X ", data[i + 39]);
+ str += sprintf(str, "%02X ", data[i + 38]);
if ((i + 1) % 16 == 0)
str += sprintf(str, "\n");
}
- return str - buf;
+ rc = str - buf;
+out:
+ kfree(data);
+ return rc;
}
-static DEVICE_ATTR(pubek, S_IRUGO, show_pubek, NULL);
+EXPORT_SYMBOL_GPL(tpm_show_pubek);
#define CAP_VER_RESULT_SIZE 18
-static u8 cap_version[] = {
+static const u8 cap_version[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 18, /* length */
0, 0, 0, 101, /* TPM_ORD_GetCapability */
@@ -321,7 +258,7 @@ static u8 cap_version[] = {
};
#define CAP_MANUFACTURER_RESULT_SIZE 18
-static u8 cap_manufacturer[] = {
+static const u8 cap_manufacturer[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 22, /* length */
0, 0, 0, 101, /* TPM_ORD_GetCapability */
@@ -330,14 +267,15 @@ static u8 cap_manufacturer[] = {
0, 0, 1, 3
};
-static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char *buf)
+ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
- u8 data[READ_PUBEK_RESULT_SIZE];
+ u8 data[sizeof(cap_manufacturer)];
ssize_t len;
char *str = buf;
struct tpm_chip *chip =
- pci_get_drvdata(container_of(dev, struct pci_dev, dev));
+ pci_get_drvdata(to_pci_dev(dev));
if (chip == NULL)
return -ENODEV;
@@ -348,7 +286,7 @@ static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char
return len;
str += sprintf(str, "Manufacturer: 0x%x\n",
- be32_to_cpu(*(data + 14)));
+ be32_to_cpu(*((__be32 *) (data + 14))));
memcpy(data, cap_version, sizeof(cap_version));
@@ -363,8 +301,20 @@ static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char
return str - buf;
}
+EXPORT_SYMBOL_GPL(tpm_show_caps);
+
+ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+ if (chip == NULL)
+ return 0;
+
+ chip->vendor->cancel(chip);
+ return count;
+}
+EXPORT_SYMBOL_GPL(tpm_store_cancel);
-static DEVICE_ATTR(caps, S_IRUGO, show_caps, NULL);
/*
* Device file system interface to the TPM
@@ -422,24 +372,15 @@ EXPORT_SYMBOL_GPL(tpm_open);
int tpm_release(struct inode *inode, struct file *file)
{
struct tpm_chip *chip = file->private_data;
-
- file->private_data = NULL;
spin_lock(&driver_lock);
+ file->private_data = NULL;
chip->num_opens--;
- spin_unlock(&driver_lock);
-
- down(&chip->timer_manipulation_mutex);
- if (timer_pending(&chip->user_read_timer))
- del_singleshot_timer_sync(&chip->user_read_timer);
- else if (timer_pending(&chip->device_timer))
- del_singleshot_timer_sync(&chip->device_timer);
- up(&chip->timer_manipulation_mutex);
-
- kfree(chip->data_buffer);
+ del_singleshot_timer_sync(&chip->user_read_timer);
atomic_set(&chip->data_pending, 0);
-
pci_dev_put(chip->pci_dev);
+ kfree(chip->data_buffer);
+ spin_unlock(&driver_lock);
return 0;
}
@@ -453,10 +394,8 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
/* cannot perform a write until the read has cleared
either via tpm_read or a user_read_timer timeout */
- while (atomic_read(&chip->data_pending) != 0) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(TPM_TIMEOUT);
- }
+ while (atomic_read(&chip->data_pending) != 0)
+ msleep(TPM_TIMEOUT);
down(&chip->buffer_mutex);
@@ -476,13 +415,7 @@ ssize_t tpm_write(struct file * file, const char __user * buf,
up(&chip->buffer_mutex);
/* Set a timeout by which the reader must come claim the result */
- down(&chip->timer_manipulation_mutex);
- init_timer(&chip->user_read_timer);
- chip->user_read_timer.function = user_reader_timeout;
- chip->user_read_timer.data = (unsigned long) chip;
- chip->user_read_timer.expires = jiffies + (60 * HZ);
- add_timer(&chip->user_read_timer);
- up(&chip->timer_manipulation_mutex);
+ mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
return in_size;
}
@@ -493,29 +426,19 @@ ssize_t tpm_read(struct file * file, char __user * buf,
size_t size, loff_t * off)
{
struct tpm_chip *chip = file->private_data;
- int ret_size = -ENODATA;
+ int ret_size;
- if (atomic_read(&chip->data_pending) != 0) { /* Result available */
- down(&chip->timer_manipulation_mutex);
- del_singleshot_timer_sync(&chip->user_read_timer);
- up(&chip->timer_manipulation_mutex);
+ del_singleshot_timer_sync(&chip->user_read_timer);
+ ret_size = atomic_read(&chip->data_pending);
+ atomic_set(&chip->data_pending, 0);
+ if (ret_size > 0) { /* relay data */
+ if (size < ret_size)
+ ret_size = size;
down(&chip->buffer_mutex);
-
- ret_size = atomic_read(&chip->data_pending);
- atomic_set(&chip->data_pending, 0);
-
- if (ret_size == 0) /* timeout just occurred */
- ret_size = -ETIME;
- else if (ret_size > 0) { /* relay data */
- if (size < ret_size)
- ret_size = size;
-
- if (copy_to_user((void __user *) buf,
- chip->data_buffer, ret_size)) {
- ret_size = -EFAULT;
- }
- }
+ if (copy_to_user
+ ((void __user *) buf, chip->data_buffer, ret_size))
+ ret_size = -EFAULT;
up(&chip->buffer_mutex);
}
@@ -541,14 +464,13 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
pci_set_drvdata(pci_dev, NULL);
misc_deregister(&chip->vendor->miscdev);
+ kfree(&chip->vendor->miscdev.name);
- device_remove_file(&pci_dev->dev, &dev_attr_pubek);
- device_remove_file(&pci_dev->dev, &dev_attr_pcrs);
- device_remove_file(&pci_dev->dev, &dev_attr_caps);
+ sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
pci_disable_device(pci_dev);
- dev_mask[chip->dev_num / 32] &= !(1 << (chip->dev_num % 32));
+ dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= !(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
kfree(chip);
@@ -590,10 +512,6 @@ int tpm_pm_resume(struct pci_dev *pci_dev)
if (chip == NULL)
return -ENODEV;
- spin_lock(&driver_lock);
- tpm_lpc_bus_init(pci_dev, chip->vendor->base);
- spin_unlock(&driver_lock);
-
return 0;
}
@@ -609,7 +527,9 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
int tpm_register_hardware(struct pci_dev *pci_dev,
struct tpm_vendor_specific *entry)
{
- char devname[7];
+#define DEVNAME_SIZE 7
+
+ char *devname;
struct tpm_chip *chip;
int i, j;
@@ -622,17 +542,21 @@ int tpm_register_hardware(struct pci_dev *pci_dev,
init_MUTEX(&chip->buffer_mutex);
init_MUTEX(&chip->tpm_mutex);
- init_MUTEX(&chip->timer_manipulation_mutex);
INIT_LIST_HEAD(&chip->list);
+ init_timer(&chip->user_read_timer);
+ chip->user_read_timer.function = user_reader_timeout;
+ chip->user_read_timer.data = (unsigned long) chip;
+
chip->vendor = entry;
chip->dev_num = -1;
- for (i = 0; i < 32; i++)
- for (j = 0; j < 8; j++)
+ for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
+ for (j = 0; j < 8 * sizeof(int); j++)
if ((dev_mask[i] & (1 << j)) == 0) {
- chip->dev_num = i * 32 + j;
+ chip->dev_num =
+ i * TPM_NUM_MASK_ENTRIES + j;
dev_mask[i] |= 1 << j;
goto dev_num_search_complete;
}
@@ -648,7 +572,8 @@ dev_num_search_complete:
else
chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
- snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num);
+ devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
+ scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
chip->vendor->miscdev.name = devname;
chip->vendor->miscdev.dev = &(pci_dev->dev);
@@ -665,31 +590,20 @@ dev_num_search_complete:
return -ENODEV;
}
+ spin_lock(&driver_lock);
+
pci_set_drvdata(pci_dev, chip);
list_add(&chip->list, &tpm_chip_list);
- device_create_file(&pci_dev->dev, &dev_attr_pubek);
- device_create_file(&pci_dev->dev, &dev_attr_pcrs);
- device_create_file(&pci_dev->dev, &dev_attr_caps);
-
- return 0;
-}
+ spin_unlock(&driver_lock);
-EXPORT_SYMBOL_GPL(tpm_register_hardware);
+ sysfs_create_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
-static int __init init_tpm(void)
-{
return 0;
}
-static void __exit cleanup_tpm(void)
-{
-
-}
-
-module_init(init_tpm);
-module_exit(cleanup_tpm);
+EXPORT_SYMBOL_GPL(tpm_register_hardware);
MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
MODULE_DESCRIPTION("TPM Driver");
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index de0c796fce8..373b41f6b46 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -25,23 +25,38 @@
#include <linux/fs.h>
#include <linux/miscdevice.h>
-#define TPM_TIMEOUT msecs_to_jiffies(5)
+enum tpm_timeout {
+ TPM_TIMEOUT = 5, /* msecs */
+};
/* TPM addresses */
-#define TPM_ADDR 0x4E
-#define TPM_DATA 0x4F
+enum tpm_addr {
+ TPM_SUPERIO_ADDR = 0x2E,
+ TPM_ADDR = 0x4E,
+};
+
+extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
+ char *);
+extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
+ char *);
+extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
+ char *);
+extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
+ const char *, size_t);
struct tpm_chip;
struct tpm_vendor_specific {
u8 req_complete_mask;
u8 req_complete_val;
+ u8 req_canceled;
u16 base; /* TPM base address */
int (*recv) (struct tpm_chip *, u8 *, size_t);
int (*send) (struct tpm_chip *, u8 *, size_t);
void (*cancel) (struct tpm_chip *);
struct miscdevice miscdev;
+ struct attribute_group *attr_group;
};
struct tpm_chip {
@@ -58,29 +73,24 @@ struct tpm_chip {
struct timer_list user_read_timer; /* user needs to claim result */
struct semaphore tpm_mutex; /* tpm is processing */
- struct timer_list device_timer; /* tpm is processing */
- struct semaphore timer_manipulation_mutex;
struct tpm_vendor_specific *vendor;
struct list_head list;
};
-static inline int tpm_read_index(int index)
+static inline int tpm_read_index(int base, int index)
{
- outb(index, TPM_ADDR);
- return inb(TPM_DATA) & 0xFF;
+ outb(index, base);
+ return inb(base+1) & 0xFF;
}
-static inline void tpm_write_index(int index, int value)
+static inline void tpm_write_index(int base, int index, int value)
{
- outb(index, TPM_ADDR);
- outb(value & 0xFF, TPM_DATA);
+ outb(index, base);
+ outb(value & 0xFF, base+1);
}
-extern void tpm_time_expired(unsigned long);
-extern int tpm_lpc_bus_init(struct pci_dev *, u16);
-
extern int tpm_register_hardware(struct pci_dev *,
struct tpm_vendor_specific *);
extern int tpm_open(struct inode *, struct file *);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index f9333e729b6..cc2cc77fd17 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -22,17 +22,23 @@
#include "tpm.h"
/* Atmel definitions */
-#define TPM_ATML_BASE 0x400
+enum tpm_atmel_addr {
+ TPM_ATMEL_BASE_ADDR_LO = 0x08,
+ TPM_ATMEL_BASE_ADDR_HI = 0x09
+};
/* write status bits */
-#define ATML_STATUS_ABORT 0x01
-#define ATML_STATUS_LASTBYTE 0x04
-
+enum tpm_atmel_write_status {
+ ATML_STATUS_ABORT = 0x01,
+ ATML_STATUS_LASTBYTE = 0x04
+};
/* read status bits */
-#define ATML_STATUS_BUSY 0x01
-#define ATML_STATUS_DATA_AVAIL 0x02
-#define ATML_STATUS_REWRITE 0x04
-
+enum tpm_atmel_read_status {
+ ATML_STATUS_BUSY = 0x01,
+ ATML_STATUS_DATA_AVAIL = 0x02,
+ ATML_STATUS_REWRITE = 0x04,
+ ATML_STATUS_READY = 0x08
+};
static int tpm_atml_recv(struct tpm_chip *chip, u8 * buf, size_t count)
{
@@ -121,13 +127,29 @@ static struct file_operations atmel_ops = {
.release = tpm_release,
};
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR |S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute* atmel_attrs[] = {
+ &dev_attr_pubek.attr,
+ &dev_attr_pcrs.attr,
+ &dev_attr_caps.attr,
+ &dev_attr_cancel.attr,
+ 0,
+};
+
+static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
+
static struct tpm_vendor_specific tpm_atmel = {
.recv = tpm_atml_recv,
.send = tpm_atml_send,
.cancel = tpm_atml_cancel,
.req_complete_mask = ATML_STATUS_BUSY | ATML_STATUS_DATA_AVAIL,
.req_complete_val = ATML_STATUS_DATA_AVAIL,
- .base = TPM_ATML_BASE,
+ .req_canceled = ATML_STATUS_READY,
+ .attr_group = &atmel_attr_grp,
.miscdev = { .fops = &atmel_ops, },
};
@@ -136,27 +158,29 @@ static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
{
u8 version[4];
int rc = 0;
+ int lo, hi;
if (pci_enable_device(pci_dev))
return -EIO;
- if (tpm_lpc_bus_init(pci_dev, TPM_ATML_BASE)) {
- rc = -ENODEV;
- goto out_err;
- }
+ lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
+ hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
+
+ tpm_atmel.base = (hi<<8)|lo;
+ dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
/* verify that it is an Atmel part */
- if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T'
- || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') {
+ if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
+ || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
rc = -ENODEV;
goto out_err;
}
/* query chip for its version number */
- if ((version[0] = tpm_read_index(0x00)) != 0xFF) {
- version[1] = tpm_read_index(0x01);
- version[2] = tpm_read_index(0x02);
- version[3] = tpm_read_index(0x03);
+ if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
+ version[1] = tpm_read_index(TPM_ADDR, 0x01);
+ version[2] = tpm_read_index(TPM_ADDR, 0x02);
+ version[3] = tpm_read_index(TPM_ADDR, 0x03);
} else {
dev_info(&pci_dev->dev, "version query failed\n");
rc = -ENODEV;
@@ -183,6 +207,7 @@ static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
+ {PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6LPC)},
{0,}
};
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 9cce833a092..b4127348c06 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -22,43 +22,52 @@
#include "tpm.h"
/* National definitions */
-#define TPM_NSC_BASE 0x360
-#define TPM_NSC_IRQ 0x07
+enum tpm_nsc_addr{
+ TPM_NSC_IRQ = 0x07,
+ TPM_NSC_BASE0_HI = 0x60,
+ TPM_NSC_BASE0_LO = 0x61,
+ TPM_NSC_BASE1_HI = 0x62,
+ TPM_NSC_BASE1_LO = 0x63
+};
-#define NSC_LDN_INDEX 0x07
-#define NSC_SID_INDEX 0x20
-#define NSC_LDC_INDEX 0x30
-#define NSC_DIO_INDEX 0x60
-#define NSC_CIO_INDEX 0x62
-#define NSC_IRQ_INDEX 0x70
-#define NSC_ITS_INDEX 0x71
+enum tpm_nsc_index {
+ NSC_LDN_INDEX = 0x07,
+ NSC_SID_INDEX = 0x20,
+ NSC_LDC_INDEX = 0x30,
+ NSC_DIO_INDEX = 0x60,
+ NSC_CIO_INDEX = 0x62,
+ NSC_IRQ_INDEX = 0x70,
+ NSC_ITS_INDEX = 0x71
+};
-#define NSC_STATUS 0x01
-#define NSC_COMMAND 0x01
-#define NSC_DATA 0x00
+enum tpm_nsc_status_loc {
+ NSC_STATUS = 0x01,
+ NSC_COMMAND = 0x01,
+ NSC_DATA = 0x00
+};
/* status bits */
-#define NSC_STATUS_OBF 0x01 /* output buffer full */
-#define NSC_STATUS_IBF 0x02 /* input buffer full */
-#define NSC_STATUS_F0 0x04 /* F0 */
-#define NSC_STATUS_A2 0x08 /* A2 */
-#define NSC_STATUS_RDY 0x10 /* ready to receive command */
-#define NSC_STATUS_IBR 0x20 /* ready to receive data */
+enum tpm_nsc_status {
+ NSC_STATUS_OBF = 0x01, /* output buffer full */
+ NSC_STATUS_IBF = 0x02, /* input buffer full */
+ NSC_STATUS_F0 = 0x04, /* F0 */
+ NSC_STATUS_A2 = 0x08, /* A2 */
+ NSC_STATUS_RDY = 0x10, /* ready to receive command */
+ NSC_STATUS_IBR = 0x20 /* ready to receive data */
+};
/* command bits */
-#define NSC_COMMAND_NORMAL 0x01 /* normal mode */
-#define NSC_COMMAND_EOC 0x03
-#define NSC_COMMAND_CANCEL 0x22
-
+enum tpm_nsc_cmd_mode {
+ NSC_COMMAND_NORMAL = 0x01, /* normal mode */
+ NSC_COMMAND_EOC = 0x03,
+ NSC_COMMAND_CANCEL = 0x22
+};
/*
* Wait for a certain status to appear
*/
static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
{
- int expired = 0;
- struct timer_list status_timer =
- TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ,
- (unsigned long) &expired);
+ unsigned long stop;
/* status immediately available check */
*data = inb(chip->vendor->base + NSC_STATUS);
@@ -66,17 +75,14 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
return 0;
/* wait for status */
- add_timer(&status_timer);
+ stop = jiffies + 10 * HZ;
do {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(TPM_TIMEOUT);
+ msleep(TPM_TIMEOUT);
*data = inb(chip->vendor->base + 1);
- if ((*data & mask) == val) {
- del_singleshot_timer_sync(&status_timer);
+ if ((*data & mask) == val)
return 0;
- }
}
- while (!expired);
+ while (time_before(jiffies, stop));
return -EBUSY;
}
@@ -84,10 +90,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
static int nsc_wait_for_ready(struct tpm_chip *chip)
{
int status;
- int expired = 0;
- struct timer_list status_timer =
- TIMER_INITIALIZER(tpm_time_expired, jiffies + 100,
- (unsigned long) &expired);
+ unsigned long stop;
/* status immediately available check */
status = inb(chip->vendor->base + NSC_STATUS);
@@ -97,19 +100,16 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
return 0;
/* wait for status */
- add_timer(&status_timer);
+ stop = jiffies + 100;
do {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(TPM_TIMEOUT);
+ msleep(TPM_TIMEOUT);
status = inb(chip->vendor->base + NSC_STATUS);
if (status & NSC_STATUS_OBF)
status = inb(chip->vendor->base + NSC_DATA);
- if (status & NSC_STATUS_RDY) {
- del_singleshot_timer_sync(&status_timer);
+ if (status & NSC_STATUS_RDY)
return 0;
- }
}
- while (!expired);
+ while (time_before(jiffies, stop));
dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
return -EBUSY;
@@ -150,7 +150,8 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
*p = inb(chip->vendor->base + NSC_DATA);
}
- if ((data & NSC_STATUS_F0) == 0) {
+ if ((data & NSC_STATUS_F0) == 0 &&
+ (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
dev_err(&chip->pci_dev->dev, "F0 not set\n");
return -EIO;
}
@@ -228,100 +229,95 @@ static struct file_operations nsc_ops = {
.release = tpm_release,
};
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR|S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute * nsc_attrs[] = {
+ &dev_attr_pubek.attr,
+ &dev_attr_pcrs.attr,
+ &dev_attr_caps.attr,
+ &dev_attr_cancel.attr,
+ 0,
+};
+
+static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
+
static struct tpm_vendor_specific tpm_nsc = {
.recv = tpm_nsc_recv,
.send = tpm_nsc_send,
.cancel = tpm_nsc_cancel,
.req_complete_mask = NSC_STATUS_OBF,
.req_complete_val = NSC_STATUS_OBF,
- .base = TPM_NSC_BASE,
+ .req_canceled = NSC_STATUS_RDY,
+ .attr_group = &nsc_attr_grp,
.miscdev = { .fops = &nsc_ops, },
-
};
static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
int rc = 0;
+ int lo, hi;
+ int nscAddrBase = TPM_ADDR;
+
if (pci_enable_device(pci_dev))
return -EIO;
- if (tpm_lpc_bus_init(pci_dev, TPM_NSC_BASE)) {
- rc = -ENODEV;
- goto out_err;
- }
+ /* select PM channel 1 */
+ tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
/* verify that it is a National part (SID) */
- if (tpm_read_index(NSC_SID_INDEX) != 0xEF) {
- rc = -ENODEV;
- goto out_err;
+ if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
+ nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
+ (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
+ if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
+ rc = -ENODEV;
+ goto out_err;
+ }
}
+ hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
+ lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
+ tpm_nsc.base = (hi<<8) | lo;
+
dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
dev_dbg(&pci_dev->dev,
"NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
- tpm_read_index(0x07), tpm_read_index(0x20),
- tpm_read_index(0x27));
+ tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
+ tpm_read_index(nscAddrBase,0x27));
dev_dbg(&pci_dev->dev,
"NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
- tpm_read_index(0x21), tpm_read_index(0x25),
- tpm_read_index(0x26), tpm_read_index(0x28));
+ tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
+ tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
- (tpm_read_index(0x60) << 8) | tpm_read_index(0x61));
+ (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
- (tpm_read_index(0x62) << 8) | tpm_read_index(0x63));
+ (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
- tpm_read_index(0x70));
+ tpm_read_index(nscAddrBase,0x70));
dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
- tpm_read_index(0x71));
+ tpm_read_index(nscAddrBase,0x71));
dev_dbg(&pci_dev->dev,
"NSC DMA channel select0 0x%x, select1 0x%x\n",
- tpm_read_index(0x74), tpm_read_index(0x75));
+ tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
dev_dbg(&pci_dev->dev,
"NSC Config "
"0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
- tpm_read_index(0xF0), tpm_read_index(0xF1),
- tpm_read_index(0xF2), tpm_read_index(0xF3),
- tpm_read_index(0xF4), tpm_read_index(0xF5),
- tpm_read_index(0xF6), tpm_read_index(0xF7),
- tpm_read_index(0xF8), tpm_read_index(0xF9));
+ tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
+ tpm_read_index(nscAddrBase,0xF2), tpm_read_index(nscAddrBase,0xF3),
+ tpm_read_index(nscAddrBase,0xF4), tpm_read_index(nscAddrBase,0xF5),
+ tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
+ tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));
dev_info(&pci_dev->dev,
- "NSC PC21100 TPM revision %d\n",
- tpm_read_index(0x27) & 0x1F);
-
- if (tpm_read_index(NSC_LDC_INDEX) == 0)
- dev_info(&pci_dev->dev, ": NSC TPM not active\n");
-
- /* select PM channel 1 */
- tpm_write_index(NSC_LDN_INDEX, 0x12);
- tpm_read_index(NSC_LDN_INDEX);
-
- /* disable the DPM module */
- tpm_write_index(NSC_LDC_INDEX, 0);
- tpm_read_index(NSC_LDC_INDEX);
-
- /* set the data register base addresses */
- tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
- tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
- tpm_read_index(NSC_DIO_INDEX);
- tpm_read_index(NSC_DIO_INDEX + 1);
-
- /* set the command register base addresses */
- tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
- tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
- tpm_read_index(NSC_DIO_INDEX);
- tpm_read_index(NSC_DIO_INDEX + 1);
-
- /* set the interrupt number to be used for the host interface */
- tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
- tpm_write_index(NSC_ITS_INDEX, 0x00);
- tpm_read_index(NSC_IRQ_INDEX);
+ "NSC TPM revision %d\n",
+ tpm_read_index(nscAddrBase, 0x27) & 0x1F);
/* enable the DPM module */
- tpm_write_index(NSC_LDC_INDEX, 0x01);
- tpm_read_index(NSC_LDC_INDEX);
+ tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
goto out_err;
@@ -339,6 +335,9 @@ static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
{PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
{0,}
};
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 31831030f73..6e4be3bb2d8 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -94,6 +94,7 @@
#include <linux/idr.h>
#include <linux/wait.h>
#include <linux/bitops.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -251,7 +252,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
static DEFINE_SPINLOCK(tty_ldisc_lock);
static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
-static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */
+static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */
int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
{
@@ -262,24 +263,35 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
return -EINVAL;
spin_lock_irqsave(&tty_ldisc_lock, flags);
- if (new_ldisc) {
- tty_ldiscs[disc] = *new_ldisc;
- tty_ldiscs[disc].num = disc;
- tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
- tty_ldiscs[disc].refcount = 0;
- } else {
- if(tty_ldiscs[disc].refcount)
- ret = -EBUSY;
- else
- tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
- }
+ tty_ldiscs[disc] = *new_ldisc;
+ tty_ldiscs[disc].num = disc;
+ tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
+ tty_ldiscs[disc].refcount = 0;
spin_unlock_irqrestore(&tty_ldisc_lock, flags);
return ret;
}
-
EXPORT_SYMBOL(tty_register_ldisc);
+int tty_unregister_ldisc(int disc)
+{
+ unsigned long flags;
+ int ret = 0;
+
+ if (disc < N_TTY || disc >= NR_LDISCS)
+ return -EINVAL;
+
+ spin_lock_irqsave(&tty_ldisc_lock, flags);
+ if (tty_ldiscs[disc].refcount)
+ ret = -EBUSY;
+ else
+ tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
+ spin_unlock_irqrestore(&tty_ldisc_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(tty_unregister_ldisc);
+
struct tty_ldisc *tty_ldisc_get(int disc)
{
unsigned long flags;
@@ -2169,12 +2181,11 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
return tty_set_ldisc(tty, ldisc);
}
-static int send_break(struct tty_struct *tty, int duration)
+static int send_break(struct tty_struct *tty, unsigned int duration)
{
tty->driver->break_ctl(tty, -1);
if (!signal_pending(current)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(duration);
+ msleep_interruptible(duration);
}
tty->driver->break_ctl(tty, 0);
if (signal_pending(current))
@@ -2355,10 +2366,10 @@ int tty_ioctl(struct inode * inode, struct file * file,
* all by anyone?
*/
if (!arg)
- return send_break(tty, HZ/4);
+ return send_break(tty, 250);
return 0;
case TCSBRKP: /* support for POSIX tcsendbreak() */
- return send_break(tty, arg ? arg*(HZ/10) : HZ/4);
+ return send_break(tty, arg ? arg*100 : 250);
case TIOCMGET:
return tty_tiocmget(tty, file, p);
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 06a31da2381..b53e2e2b5ae 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -414,6 +414,16 @@ config WATCHDOG_RIO
machines. The watchdog timeout period is normally one minute but
can be changed with a boot-time parameter.
+# ppc64 RTAS watchdog
+config WATCHDOG_RTAS
+ tristate "RTAS watchdog"
+ depends on WATCHDOG && PPC_RTAS
+ help
+ This driver adds watchdog support for the RTAS watchdog.
+
+ To compile this driver as a module, choose M here. The module
+ will be called wdrtas.
+
#
# ISA-based Watchdog Cards
#
diff --git a/drivers/char/watchdog/Makefile b/drivers/char/watchdog/Makefile
index 1cd27efa35c..c1838834ea7 100644
--- a/drivers/char/watchdog/Makefile
+++ b/drivers/char/watchdog/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o
obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
+obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
# Only one watchdog can succeed. We probe the hardware watchdog
# drivers first, then the softdog driver. This means if your hardware
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
new file mode 100644
index 00000000000..619e2ffca33
--- /dev/null
+++ b/drivers/char/watchdog/wdrtas.c
@@ -0,0 +1,696 @@
+/*
+ * FIXME: add wdrtas_get_status and wdrtas_get_boot_status as soon as
+ * RTAS calls are available
+ */
+
+/*
+ * RTAS watchdog driver
+ *
+ * (C) Copyright IBM Corp. 2005
+ * device driver to exploit watchdog RTAS functions
+ *
+ * Authors : Utz Bacher <utz.bacher@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+
+#include <asm/rtas.h>
+#include <asm/uaccess.h>
+
+#define WDRTAS_MAGIC_CHAR 42
+#define WDRTAS_SUPPORTED_MASK (WDIOF_SETTIMEOUT | \
+ WDIOF_MAGICCLOSE)
+
+MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
+MODULE_DESCRIPTION("RTAS watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS_MISCDEV(TEMP_MINOR);
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int wdrtas_nowayout = 1;
+#else
+static int wdrtas_nowayout = 0;
+#endif
+
+static atomic_t wdrtas_miscdev_open = ATOMIC_INIT(0);
+static char wdrtas_expect_close = 0;
+
+static int wdrtas_interval;
+
+#define WDRTAS_THERMAL_SENSOR 3
+static int wdrtas_token_get_sensor_state;
+#define WDRTAS_SURVEILLANCE_IND 9000
+static int wdrtas_token_set_indicator;
+#define WDRTAS_SP_SPI 28
+static int wdrtas_token_get_sp;
+static int wdrtas_token_event_scan;
+
+#define WDRTAS_DEFAULT_INTERVAL 300
+
+#define WDRTAS_LOGBUFFER_LEN 128
+static char wdrtas_logbuffer[WDRTAS_LOGBUFFER_LEN];
+
+
+/*** watchdog access functions */
+
+/**
+ * wdrtas_set_interval - sets the watchdog interval
+ * @interval: new interval
+ *
+ * returns 0 on success, <0 on failures
+ *
+ * wdrtas_set_interval sets the watchdog keepalive interval by calling the
+ * RTAS function set-indicator (surveillance). The unit of interval is
+ * seconds.
+ */
+static int
+wdrtas_set_interval(int interval)
+{
+ long result;
+ static int print_msg = 10;
+
+ /* rtas uses minutes */
+ interval = (interval + 59) / 60;
+
+ result = rtas_call(wdrtas_token_set_indicator, 3, 1, NULL,
+ WDRTAS_SURVEILLANCE_IND, 0, interval);
+ if ( (result < 0) && (print_msg) ) {
+ printk(KERN_ERR "wdrtas: setting the watchdog to %i "
+ "timeout failed: %li\n", interval, result);
+ print_msg--;
+ }
+
+ return result;
+}
+
+/**
+ * wdrtas_get_interval - returns the current watchdog interval
+ * @fallback_value: value (in seconds) to use, if the RTAS call fails
+ *
+ * returns the interval
+ *
+ * wdrtas_get_interval returns the current watchdog keepalive interval
+ * as reported by the RTAS function ibm,get-system-parameter. The unit
+ * of the return value is seconds.
+ */
+static int
+wdrtas_get_interval(int fallback_value)
+{
+ long result;
+ char value[4];
+
+ result = rtas_call(wdrtas_token_get_sp, 3, 1, NULL,
+ WDRTAS_SP_SPI, (void *)__pa(&value), 4);
+ if ( (value[0] != 0) || (value[1] != 2) || (value[3] != 0) ||
+ (result < 0) ) {
+ printk(KERN_WARNING "wdrtas: could not get sp_spi watchdog "
+ "timeout (%li). Continuing\n", result);
+ return fallback_value;
+ }
+
+ /* rtas uses minutes */
+ return ((int)value[2]) * 60;
+}
+
+/**
+ * wdrtas_timer_start - starts watchdog
+ *
+ * wdrtas_timer_start starts the watchdog by calling the RTAS function
+ * set-interval (surveillance)
+ */
+static void
+wdrtas_timer_start(void)
+{
+ wdrtas_set_interval(wdrtas_interval);
+}
+
+/**
+ * wdrtas_timer_stop - stops watchdog
+ *
+ * wdrtas_timer_stop stops the watchdog timer by calling the RTAS function
+ * set-interval (surveillance)
+ */
+static void
+wdrtas_timer_stop(void)
+{
+ wdrtas_set_interval(0);
+}
+
+/**
+ * wdrtas_log_scanned_event - logs an event we received during keepalive
+ *
+ * wdrtas_log_scanned_event prints a message to the log buffer dumping
+ * the results of the last event-scan call
+ */
+static void
+wdrtas_log_scanned_event(void)
+{
+ int i;
+
+ for (i = 0; i < WDRTAS_LOGBUFFER_LEN; i += 16)
+ printk(KERN_INFO "wdrtas: dumping event (line %i/%i), data = "
+ "%02x %02x %02x %02x %02x %02x %02x %02x "
+ "%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ (i / 16) + 1, (WDRTAS_LOGBUFFER_LEN / 16),
+ wdrtas_logbuffer[i + 0], wdrtas_logbuffer[i + 1],
+ wdrtas_logbuffer[i + 2], wdrtas_logbuffer[i + 3],
+ wdrtas_logbuffer[i + 4], wdrtas_logbuffer[i + 5],
+ wdrtas_logbuffer[i + 6], wdrtas_logbuffer[i + 7],
+ wdrtas_logbuffer[i + 8], wdrtas_logbuffer[i + 9],
+ wdrtas_logbuffer[i + 10], wdrtas_logbuffer[i + 11],
+ wdrtas_logbuffer[i + 12], wdrtas_logbuffer[i + 13],
+ wdrtas_logbuffer[i + 14], wdrtas_logbuffer[i + 15]);
+}
+
+/**
+ * wdrtas_timer_keepalive - resets watchdog timer to keep system alive
+ *
+ * wdrtas_timer_keepalive restarts the watchdog timer by calling the
+ * RTAS function event-scan and repeats these calls as long as there are
+ * events available. All events will be dumped.
+ */
+static void
+wdrtas_timer_keepalive(void)
+{
+ long result;
+
+ do {
+ result = rtas_call(wdrtas_token_event_scan, 4, 1, NULL,
+ RTAS_EVENT_SCAN_ALL_EVENTS, 0,
+ (void *)__pa(wdrtas_logbuffer),
+ WDRTAS_LOGBUFFER_LEN);
+ if (result < 0)
+ printk(KERN_ERR "wdrtas: event-scan failed: %li\n",
+ result);
+ if (result == 0)
+ wdrtas_log_scanned_event();
+ } while (result == 0);
+}
+
+/**
+ * wdrtas_get_temperature - returns current temperature
+ *
+ * returns temperature or <0 on failures
+ *
+ * wdrtas_get_temperature returns the current temperature in Fahrenheit. It
+ * uses the RTAS call get-sensor-state, token 3 to do so
+ */
+static int
+wdrtas_get_temperature(void)
+{
+ long result;
+ int temperature = 0;
+
+ result = rtas_call(wdrtas_token_get_sensor_state, 2, 2,
+ (void *)__pa(&temperature),
+ WDRTAS_THERMAL_SENSOR, 0);
+
+ if (result < 0)
+ printk(KERN_WARNING "wdrtas: reading the thermal sensor "
+ "faild: %li\n", result);
+ else
+ temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */
+
+ return temperature;
+}
+
+/**
+ * wdrtas_get_status - returns the status of the watchdog
+ *
+ * returns a bitmask of defines WDIOF_... as defined in
+ * include/linux/watchdog.h
+ */
+static int
+wdrtas_get_status(void)
+{
+ return 0; /* TODO */
+}
+
+/**
+ * wdrtas_get_boot_status - returns the reason for the last boot
+ *
+ * returns a bitmask of defines WDIOF_... as defined in
+ * include/linux/watchdog.h, indicating why the watchdog rebooted the system
+ */
+static int
+wdrtas_get_boot_status(void)
+{
+ return 0; /* TODO */
+}
+
+/*** watchdog API and operations stuff */
+
+/* wdrtas_write - called when watchdog device is written to
+ * @file: file structure
+ * @buf: user buffer with data
+ * @len: amount to data written
+ * @ppos: position in file
+ *
+ * returns the number of successfully processed characters, which is always
+ * the number of bytes passed to this function
+ *
+ * wdrtas_write processes all the data given to it and looks for the magic
+ * character 'V'. This character allows the watchdog device to be closed
+ * properly.
+ */
+static ssize_t
+wdrtas_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ int i;
+ char c;
+
+ if (!len)
+ goto out;
+
+ if (!wdrtas_nowayout) {
+ wdrtas_expect_close = 0;
+ /* look for 'V' */
+ for (i = 0; i < len; i++) {
+ if (get_user(c, buf + i))
+ return -EFAULT;
+ /* allow to close device */
+ if (c == 'V')
+ wdrtas_expect_close = WDRTAS_MAGIC_CHAR;
+ }
+ }
+
+ wdrtas_timer_keepalive();
+
+out:
+ return len;
+}
+
+/**
+ * wdrtas_ioctl - ioctl function for the watchdog device
+ * @inode: inode structure
+ * @file: file structure
+ * @cmd: command for ioctl
+ * @arg: argument pointer
+ *
+ * returns 0 on success, <0 on failure
+ *
+ * wdrtas_ioctl implements the watchdog API ioctls
+ */
+static int
+wdrtas_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int __user *argp = (void *)arg;
+ int i;
+ static struct watchdog_info wdinfo = {
+ .options = WDRTAS_SUPPORTED_MASK,
+ .firmware_version = 0,
+ .identity = "wdrtas"
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user(argp, &wdinfo, sizeof(wdinfo)))
+ return -EFAULT;
+ return 0;
+
+ case WDIOC_GETSTATUS:
+ i = wdrtas_get_status();
+ return put_user(i, argp);
+
+ case WDIOC_GETBOOTSTATUS:
+ i = wdrtas_get_boot_status();
+ return put_user(i, argp);
+
+ case WDIOC_GETTEMP:
+ if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE)
+ return -EOPNOTSUPP;
+
+ i = wdrtas_get_temperature();
+ return put_user(i, argp);
+
+ case WDIOC_SETOPTIONS:
+ if (get_user(i, argp))
+ return -EFAULT;
+ if (i & WDIOS_DISABLECARD)
+ wdrtas_timer_stop();
+ if (i & WDIOS_ENABLECARD) {
+ wdrtas_timer_keepalive();
+ wdrtas_timer_start();
+ }
+ if (i & WDIOS_TEMPPANIC) {
+ /* not implemented. Done by H8 */
+ }
+ return 0;
+
+ case WDIOC_KEEPALIVE:
+ wdrtas_timer_keepalive();
+ return 0;
+
+ case WDIOC_SETTIMEOUT:
+ if (get_user(i, argp))
+ return -EFAULT;
+
+ if (wdrtas_set_interval(i))
+ return -EINVAL;
+
+ wdrtas_timer_keepalive();
+
+ if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
+ wdrtas_interval = i;
+ else
+ wdrtas_interval = wdrtas_get_interval(i);
+ /* fallthrough */
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(wdrtas_interval, argp);
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+/**
+ * wdrtas_open - open function of watchdog device
+ * @inode: inode structure
+ * @file: file structure
+ *
+ * returns 0 on success, -EBUSY if the file has been opened already, <0 on
+ * other failures
+ *
+ * function called when watchdog device is opened
+ */
+static int
+wdrtas_open(struct inode *inode, struct file *file)
+{
+ /* only open once */
+ if (atomic_inc_return(&wdrtas_miscdev_open) > 1) {
+ atomic_dec(&wdrtas_miscdev_open);
+ return -EBUSY;
+ }
+
+ wdrtas_timer_start();
+ wdrtas_timer_keepalive();
+
+ return nonseekable_open(inode, file);
+}
+
+/**
+ * wdrtas_close - close function of watchdog device
+ * @inode: inode structure
+ * @file: file structure
+ *
+ * returns 0 on success
+ *
+ * close function. Always succeeds
+ */
+static int
+wdrtas_close(struct inode *inode, struct file *file)
+{
+ /* only stop watchdog, if this was announced using 'V' before */
+ if (wdrtas_expect_close == WDRTAS_MAGIC_CHAR)
+ wdrtas_timer_stop();
+ else {
+ printk(KERN_WARNING "wdrtas: got unexpected close. Watchdog "
+ "not stopped.\n");
+ wdrtas_timer_keepalive();
+ }
+
+ wdrtas_expect_close = 0;
+ atomic_dec(&wdrtas_miscdev_open);
+ return 0;
+}
+
+/**
+ * wdrtas_temp_read - gives back the temperature in fahrenheit
+ * @file: file structure
+ * @buf: user buffer
+ * @count: number of bytes to be read
+ * @ppos: position in file
+ *
+ * returns always 1 or -EFAULT in case of user space copy failures, <0 on
+ * other failures
+ *
+ * wdrtas_temp_read gives the temperature to the users by copying this
+ * value as one byte into the user space buffer. The unit is Fahrenheit...
+ */
+static ssize_t
+wdrtas_temp_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int temperature = 0;
+
+ temperature = wdrtas_get_temperature();
+ if (temperature < 0)
+ return temperature;
+
+ if (copy_to_user(buf, &temperature, 1))
+ return -EFAULT;
+
+ return 1;
+}
+
+/**
+ * wdrtas_temp_open - open function of temperature device
+ * @inode: inode structure
+ * @file: file structure
+ *
+ * returns 0 on success, <0 on failure
+ *
+ * function called when temperature device is opened
+ */
+static int
+wdrtas_temp_open(struct inode *inode, struct file *file)
+{
+ return nonseekable_open(inode, file);
+}
+
+/**
+ * wdrtas_temp_close - close function of temperature device
+ * @inode: inode structure
+ * @file: file structure
+ *
+ * returns 0 on success
+ *
+ * close function. Always succeeds
+ */
+static int
+wdrtas_temp_close(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+/**
+ * wdrtas_reboot - reboot notifier function
+ * @nb: notifier block structure
+ * @code: reboot code
+ * @ptr: unused
+ *
+ * returns NOTIFY_DONE
+ *
+ * wdrtas_reboot stops the watchdog in case of a reboot
+ */
+static int
+wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr)
+{
+ if ( (code==SYS_DOWN) || (code==SYS_HALT) )
+ wdrtas_timer_stop();
+
+ return NOTIFY_DONE;
+}
+
+/*** initialization stuff */
+
+static struct file_operations wdrtas_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = wdrtas_write,
+ .ioctl = wdrtas_ioctl,
+ .open = wdrtas_open,
+ .release = wdrtas_close,
+};
+
+static struct miscdevice wdrtas_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &wdrtas_fops,
+};
+
+static struct file_operations wdrtas_temp_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .read = wdrtas_temp_read,
+ .open = wdrtas_temp_open,
+ .release = wdrtas_temp_close,
+};
+
+static struct miscdevice wdrtas_tempdev = {
+ .minor = TEMP_MINOR,
+ .name = "temperature",
+ .fops = &wdrtas_temp_fops,
+};
+
+static struct notifier_block wdrtas_notifier = {
+ .notifier_call = wdrtas_reboot,
+};
+
+/**
+ * wdrtas_get_tokens - reads in RTAS tokens
+ *
+ * returns 0 on succes, <0 on failure
+ *
+ * wdrtas_get_tokens reads in the tokens for the RTAS calls used in
+ * this watchdog driver. It tolerates, if "get-sensor-state" and
+ * "ibm,get-system-parameter" are not available.
+ */
+static int
+wdrtas_get_tokens(void)
+{
+ wdrtas_token_get_sensor_state = rtas_token("get-sensor-state");
+ if (wdrtas_token_get_sensor_state == RTAS_UNKNOWN_SERVICE) {
+ printk(KERN_WARNING "wdrtas: couldn't get token for "
+ "get-sensor-state. Trying to continue without "
+ "temperature support.\n");
+ }
+
+ wdrtas_token_get_sp = rtas_token("ibm,get-system-parameter");
+ if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE) {
+ printk(KERN_WARNING "wdrtas: couldn't get token for "
+ "ibm,get-system-parameter. Trying to continue with "
+ "a default timeout value of %i seconds.\n",
+ WDRTAS_DEFAULT_INTERVAL);
+ }
+
+ wdrtas_token_set_indicator = rtas_token("set-indicator");
+ if (wdrtas_token_set_indicator == RTAS_UNKNOWN_SERVICE) {
+ printk(KERN_ERR "wdrtas: couldn't get token for "
+ "set-indicator. Terminating watchdog code.\n");
+ return -EIO;
+ }
+
+ wdrtas_token_event_scan = rtas_token("event-scan");
+ if (wdrtas_token_event_scan == RTAS_UNKNOWN_SERVICE) {
+ printk(KERN_ERR "wdrtas: couldn't get token for event-scan. "
+ "Terminating watchdog code.\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * wdrtas_unregister_devs - unregisters the misc dev handlers
+ *
+ * wdrtas_register_devs unregisters the watchdog and temperature watchdog
+ * misc devs
+ */
+static void
+wdrtas_unregister_devs(void)
+{
+ misc_deregister(&wdrtas_miscdev);
+ if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE)
+ misc_deregister(&wdrtas_tempdev);
+}
+
+/**
+ * wdrtas_register_devs - registers the misc dev handlers
+ *
+ * returns 0 on succes, <0 on failure
+ *
+ * wdrtas_register_devs registers the watchdog and temperature watchdog
+ * misc devs
+ */
+static int
+wdrtas_register_devs(void)
+{
+ int result;
+
+ result = misc_register(&wdrtas_miscdev);
+ if (result) {
+ printk(KERN_ERR "wdrtas: couldn't register watchdog misc "
+ "device. Terminating watchdog code.\n");
+ return result;
+ }
+
+ if (wdrtas_token_get_sensor_state != RTAS_UNKNOWN_SERVICE) {
+ result = misc_register(&wdrtas_tempdev);
+ if (result) {
+ printk(KERN_WARNING "wdrtas: couldn't register "
+ "watchdog temperature misc device. Continuing "
+ "without temperature support.\n");
+ wdrtas_token_get_sensor_state = RTAS_UNKNOWN_SERVICE;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * wdrtas_init - init function of the watchdog driver
+ *
+ * returns 0 on succes, <0 on failure
+ *
+ * registers the file handlers and the reboot notifier
+ */
+static int __init
+wdrtas_init(void)
+{
+ if (wdrtas_get_tokens())
+ return -ENODEV;
+
+ if (wdrtas_register_devs())
+ return -ENODEV;
+
+ if (register_reboot_notifier(&wdrtas_notifier)) {
+ printk(KERN_ERR "wdrtas: could not register reboot notifier. "
+ "Terminating watchdog code.\n");
+ wdrtas_unregister_devs();
+ return -ENODEV;
+ }
+
+ if (wdrtas_token_get_sp == RTAS_UNKNOWN_SERVICE)
+ wdrtas_interval = WDRTAS_DEFAULT_INTERVAL;
+ else
+ wdrtas_interval = wdrtas_get_interval(WDRTAS_DEFAULT_INTERVAL);
+
+ return 0;
+}
+
+/**
+ * wdrtas_exit - exit function of the watchdog driver
+ *
+ * unregisters the file handlers and the reboot notifier
+ */
+static void __exit
+wdrtas_exit(void)
+{
+ if (!wdrtas_nowayout)
+ wdrtas_timer_stop();
+
+ wdrtas_unregister_devs();
+
+ unregister_reboot_notifier(&wdrtas_notifier);
+}
+
+module_init(wdrtas_init);
+module_exit(wdrtas_exit);
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index a3451cb9400..33b17c6a46f 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -618,8 +618,8 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL);
if (!short_name || !new_efivar) {
- if (short_name) kfree(short_name);
- if (new_efivar) kfree(new_efivar);
+ kfree(short_name);
+ kfree(new_efivar);
return 1;
}
memset(short_name, 0, short_name_size+1);
@@ -644,7 +644,8 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
kobj_set_kset_s(new_efivar, vars_subsys);
kobject_register(&new_efivar->kobj);
- kfree(short_name); short_name = NULL;
+ kfree(short_name);
+ short_name = NULL;
spin_lock(&efivars_lock);
list_add(&new_efivar->list, &efivar_list);
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c
index df1b721154d..839b44a7e08 100644
--- a/drivers/firmware/pcdp.c
+++ b/drivers/firmware/pcdp.c
@@ -23,12 +23,15 @@ setup_serial_console(struct pcdp_uart *uart)
{
#ifdef CONFIG_SERIAL_8250_CONSOLE
int mmio;
- static char options[64];
+ static char options[64], *p = options;
mmio = (uart->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY);
- snprintf(options, sizeof(options), "console=uart,%s,0x%lx,%lun%d",
- mmio ? "mmio" : "io", uart->addr.address, uart->baud,
- uart->bits ? uart->bits : 8);
+ p += sprintf(p, "console=uart,%s,0x%lx",
+ mmio ? "mmio" : "io", uart->addr.address);
+ if (uart->baud)
+ p += sprintf(p, ",%lu", uart->baud);
+ if (uart->bits)
+ p += sprintf(p, "n%d", uart->bits);
return early_serial_console_init(options);
#else
diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h
index 863bb6f768c..1dc7c88b7b4 100644
--- a/drivers/firmware/pcdp.h
+++ b/drivers/firmware/pcdp.h
@@ -2,7 +2,7 @@
* Definitions for PCDP-defined console devices
*
* v1.0a: http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf
- * v2.0: http://www.dig64.org/specifications/DIG64_HCDPv20_042804.pdf
+ * v2.0: http://www.dig64.org/specifications/DIG64_PCDPv20.pdf
*
* (c) Copyright 2002, 2004 Hewlett-Packard Development Company, L.P.
* Khalid Aziz <khalid.aziz@hp.com>
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index ec943cad231..1956af382cd 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -33,7 +33,8 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <asm/hardware.h> /* Pick up IXP42000-specific bits */
+#include <asm/hardware.h> /* Pick up IXP2000-specific bits */
+#include <asm/arch/gpio.h>
static inline int ixp2000_scl_pin(void *data)
{
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index d41ca31dbcb..03c23ce98ed 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -20,13 +20,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>
-#ifdef CONFIG_FSL_OCP
-#include <asm/ocp.h>
-#define FSL_I2C_DEV_SEPARATE_DFSRR FS_I2C_SEPARATE_DFSRR
-#define FSL_I2C_DEV_CLOCK_5200 FS_I2C_CLOCK_5200
-#else
#include <linux/fsl_devices.h>
-#endif
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
@@ -294,204 +288,6 @@ static struct i2c_adapter mpc_ops = {
.retries = 1
};
-#ifdef CONFIG_FSL_OCP
-static int __devinit mpc_i2c_probe(struct ocp_device *ocp)
-{
- int result = 0;
- struct mpc_i2c *i2c;
-
- if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
- return -ENOMEM;
- }
- memset(i2c, 0, sizeof(*i2c));
-
- i2c->irq = ocp->def->irq;
- i2c->flags = ((struct ocp_fs_i2c_data *)ocp->def->additions)->flags;
- init_waitqueue_head(&i2c->queue);
-
- if (!request_mem_region(ocp->def->paddr, MPC_I2C_REGION, "i2c-mpc")) {
- printk(KERN_ERR "i2c-mpc - resource unavailable\n");
- return -ENODEV;
- }
-
- i2c->base = ioremap(ocp->def->paddr, MPC_I2C_REGION);
-
- if (!i2c->base) {
- printk(KERN_ERR "i2c-mpc - failed to map controller\n");
- result = -ENOMEM;
- goto fail_map;
- }
-
- if (i2c->irq != OCP_IRQ_NA)
- {
- if ((result = request_irq(ocp->def->irq, mpc_i2c_isr,
- SA_SHIRQ, "i2c-mpc", i2c)) < 0) {
- printk(KERN_ERR
- "i2c-mpc - failed to attach interrupt\n");
- goto fail_irq;
- }
- } else
- i2c->irq = 0;
-
- mpc_i2c_setclock(i2c);
- ocp_set_drvdata(ocp, i2c);
-
- i2c->adap = mpc_ops;
- i2c_set_adapdata(&i2c->adap, i2c);
-
- if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
- printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
- goto fail_add;
- }
-
- return result;
-
- fail_add:
- if (ocp->def->irq != OCP_IRQ_NA)
- free_irq(ocp->def->irq, 0);
- fail_irq:
- iounmap(i2c->base);
- fail_map:
- release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
- kfree(i2c);
- return result;
-}
-static void __devexit mpc_i2c_remove(struct ocp_device *ocp)
-{
- struct mpc_i2c *i2c = ocp_get_drvdata(ocp);
- i2c_del_adapter(&i2c->adap);
- ocp_set_drvdata(ocp, NULL);
-
- if (ocp->def->irq != OCP_IRQ_NA)
- free_irq(i2c->irq, i2c);
- iounmap(i2c->base);
- release_mem_region(ocp->def->paddr, MPC_I2C_REGION);
- kfree(i2c);
-}
-
-static struct ocp_device_id mpc_iic_ids[] __devinitdata = {
- {.vendor = OCP_VENDOR_FREESCALE,.function = OCP_FUNC_IIC},
- {.vendor = OCP_VENDOR_INVALID}
-};
-
-MODULE_DEVICE_TABLE(ocp, mpc_iic_ids);
-
-static struct ocp_driver mpc_iic_driver = {
- .name = "iic",
- .id_table = mpc_iic_ids,
- .probe = mpc_i2c_probe,
- .remove = __devexit_p(mpc_i2c_remove)
-};
-
-static int __init iic_init(void)
-{
- return ocp_register_driver(&mpc_iic_driver);
-}
-
-static void __exit iic_exit(void)
-{
- ocp_unregister_driver(&mpc_iic_driver);
-}
-
-module_init(iic_init);
-module_exit(iic_exit);
-#else
-static int fsl_i2c_probe(struct device *device)
-{
- int result = 0;
- struct mpc_i2c *i2c;
- struct platform_device *pdev = to_platform_device(device);
- struct fsl_i2c_platform_data *pdata;
- struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
- pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data;
-
- if (!(i2c = kmalloc(sizeof(*i2c), GFP_KERNEL))) {
- return -ENOMEM;
- }
- memset(i2c, 0, sizeof(*i2c));
-
- i2c->irq = platform_get_irq(pdev, 0);
- i2c->flags = pdata->device_flags;
- init_waitqueue_head(&i2c->queue);
-
- i2c->base = ioremap((phys_addr_t)r->start, MPC_I2C_REGION);
-
- if (!i2c->base) {
- printk(KERN_ERR "i2c-mpc - failed to map controller\n");
- result = -ENOMEM;
- goto fail_map;
- }
-
- if (i2c->irq != 0)
- if ((result = request_irq(i2c->irq, mpc_i2c_isr,
- SA_SHIRQ, "i2c-mpc", i2c)) < 0) {
- printk(KERN_ERR
- "i2c-mpc - failed to attach interrupt\n");
- goto fail_irq;
- }
-
- mpc_i2c_setclock(i2c);
- dev_set_drvdata(device, i2c);
-
- i2c->adap = mpc_ops;
- i2c_set_adapdata(&i2c->adap, i2c);
- i2c->adap.dev.parent = &pdev->dev;
- if ((result = i2c_add_adapter(&i2c->adap)) < 0) {
- printk(KERN_ERR "i2c-mpc - failed to add adapter\n");
- goto fail_add;
- }
-
- return result;
-
- fail_add:
- if (i2c->irq != 0)
- free_irq(i2c->irq, NULL);
- fail_irq:
- iounmap(i2c->base);
- fail_map:
- kfree(i2c);
- return result;
-};
-
-static int fsl_i2c_remove(struct device *device)
-{
- struct mpc_i2c *i2c = dev_get_drvdata(device);
-
- i2c_del_adapter(&i2c->adap);
- dev_set_drvdata(device, NULL);
-
- if (i2c->irq != 0)
- free_irq(i2c->irq, i2c);
-
- iounmap(i2c->base);
- kfree(i2c);
- return 0;
-};
-
-/* Structure for a device driver */
-static struct device_driver fsl_i2c_driver = {
- .name = "fsl-i2c",
- .bus = &platform_bus_type,
- .probe = fsl_i2c_probe,
- .remove = fsl_i2c_remove,
-};
-
-static int __init fsl_i2c_init(void)
-{
- return driver_register(&fsl_i2c_driver);
-}
-
-static void __exit fsl_i2c_exit(void)
-{
- driver_unregister(&fsl_i2c_driver);
-}
-
-module_init(fsl_i2c_init);
-module_exit(fsl_i2c_exit);
-
-#endif /* CONFIG_FSL_OCP */
-
MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
MODULE_DESCRIPTION
("I2C-Bus adapter for MPC107 bridge and MPC824x/85xx/52xx processors");
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 39f3e9101ed..0a31cfda08a 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2657,16 +2657,63 @@ int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
}
static
+int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
+{
+ struct cdrom_info *info = drive->driver_data;
+ struct cdrom_device_info *cdi = &info->devinfo;
+ struct packet_command cgc;
+ int stat, attempts = 3, size = sizeof(*cap);
+
+ /*
+ * ACER50 (and others?) require the full spec length mode sense
+ * page capabilities size, but older drives break.
+ */
+ if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
+ !strcmp(drive->id->model, "WPI CDS-32X")))
+ size -= sizeof(cap->pad);
+
+ init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
+ do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
+ stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
+ if (!stat)
+ break;
+ } while (--attempts);
+ return stat;
+}
+
+static
+void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap)
+{
+ /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
+ if (!drive->id->model[0] &&
+ !strncmp(drive->id->fw_rev, "241N", 4)) {
+ CDROM_STATE_FLAGS(drive)->current_speed =
+ (((unsigned int)cap->curspeed) + (176/2)) / 176;
+ CDROM_CONFIG_FLAGS(drive)->max_speed =
+ (((unsigned int)cap->maxspeed) + (176/2)) / 176;
+ } else {
+ CDROM_STATE_FLAGS(drive)->current_speed =
+ (ntohs(cap->curspeed) + (176/2)) / 176;
+ CDROM_CONFIG_FLAGS(drive)->max_speed =
+ (ntohs(cap->maxspeed) + (176/2)) / 176;
+ }
+}
+
+static
int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
{
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
struct request_sense sense;
+ struct atapi_capabilities_page cap;
int stat;
if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
return stat;
- cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
+ if (!ide_cdrom_get_capabilities(drive, &cap)) {
+ ide_cdrom_update_speed(drive, &cap);
+ cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
+ }
return 0;
}
@@ -2869,31 +2916,6 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
}
static
-int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
-{
- struct cdrom_info *info = drive->driver_data;
- struct cdrom_device_info *cdi = &info->devinfo;
- struct packet_command cgc;
- int stat, attempts = 3, size = sizeof(*cap);
-
- /*
- * ACER50 (and others?) require the full spec length mode sense
- * page capabilities size, but older drives break.
- */
- if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
- !strcmp(drive->id->model, "WPI CDS-32X")))
- size -= sizeof(cap->pad);
-
- init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
- do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
- stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
- if (!stat)
- break;
- } while (--attempts);
- return stat;
-}
-
-static
int ide_cdrom_probe_capabilities (ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
@@ -2978,20 +3000,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
}
}
- /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
- if (!drive->id->model[0] &&
- !strncmp(drive->id->fw_rev, "241N", 4)) {
- CDROM_STATE_FLAGS(drive)->current_speed =
- (((unsigned int)cap.curspeed) + (176/2)) / 176;
- CDROM_CONFIG_FLAGS(drive)->max_speed =
- (((unsigned int)cap.maxspeed) + (176/2)) / 176;
- } else {
- CDROM_STATE_FLAGS(drive)->current_speed =
- (ntohs(cap.curspeed) + (176/2)) / 176;
- CDROM_CONFIG_FLAGS(drive)->max_speed =
- (ntohs(cap.maxspeed) + (176/2)) / 176;
- }
-
+ ide_cdrom_update_speed(drive, &cap);
/* don't print speed if the drive reported 0.
*/
printk(KERN_INFO "%s: ATAPI", drive->name);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 3302cd8eab4..d6f934886b0 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1215,7 +1215,8 @@ static int ide_disk_probe(struct device *dev)
if (!idkp)
goto failed;
- g = alloc_disk(1 << PARTN_BITS);
+ g = alloc_disk_node(1 << PARTN_BITS,
+ pcibus_to_node(drive->hwif->pci_dev->bus));
if (!g)
goto out_free_idkp;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index c949e98df4b..9eab6426148 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -661,10 +661,12 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un
idefloppy_do_end_request(drive, 1, done >> 9);
+#if IDEFLOPPY_DEBUG_BUGS
if (bcount) {
printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount);
idefloppy_write_zeros(drive, bcount);
}
+#endif
}
static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc)
@@ -1048,6 +1050,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
atapi_bcount_t bcount;
ide_handler_t *pkt_xfer_routine;
+#if 0 /* Accessing floppy->pc is not valid here, the previous pc may be gone
+ and have lived on another thread's stack; that stack may have become
+ unmapped meanwhile (CONFIG_DEBUG_PAGEALLOC). */
#if IDEFLOPPY_DEBUG_BUGS
if (floppy->pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD &&
pc->c[0] == IDEFLOPPY_REQUEST_SENSE_CMD) {
@@ -1055,6 +1060,7 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
"Two request sense in serial were issued\n");
}
#endif /* IDEFLOPPY_DEBUG_BUGS */
+#endif
if (floppy->failed_pc == NULL &&
pc->c[0] != IDEFLOPPY_REQUEST_SENSE_CMD)
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 5d876f53c69..7df85af7537 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -977,8 +977,9 @@ static int ide_init_queue(ide_drive_t *drive)
* limits and LBA48 we could raise it but as yet
* do not.
*/
-
- q = blk_init_queue(do_ide_request, &ide_lock);
+
+ q = blk_init_queue_node(do_ide_request, &ide_lock,
+ pcibus_to_node(drive->hwif->pci_dev->bus));
if (!q)
return 1;
@@ -1095,7 +1096,8 @@ static int init_irq (ide_hwif_t *hwif)
hwgroup->hwif->next = hwif;
spin_unlock_irq(&ide_lock);
} else {
- hwgroup = kmalloc(sizeof(ide_hwgroup_t),GFP_KERNEL);
+ hwgroup = kmalloc_node(sizeof(ide_hwgroup_t), GFP_KERNEL,
+ pcibus_to_node(hwif->drives[0].hwif->pci_dev->bus));
if (!hwgroup)
goto out_up;
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 2d9a9b74e68..629070b83a3 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -1041,10 +1041,8 @@ static int hpsbpkt_thread(void *__hi)
while (1) {
if (down_interruptible(&khpsbpkt_sig)) {
- if (current->flags & PF_FREEZE) {
- refrigerator(0);
+ if (try_to_freeze())
continue;
- }
printk("khpsbpkt: received unexpected signal?!\n" );
break;
}
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 32abb6dda88..9a46c3b44bf 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -1510,7 +1510,7 @@ static int nodemgr_host_thread(void *__hi)
if (down_interruptible(&hi->reset_sem) ||
down_interruptible(&nodemgr_serialize)) {
- if (try_to_freeze(PF_FREEZE))
+ if (try_to_freeze())
continue;
printk("NodeMgr: received unexpected signal?!\n" );
break;
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index e152d0fa0cd..c77a82e4605 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -439,7 +439,7 @@ static int gameport_thread(void *nothing)
do {
gameport_handle_events();
wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list));
- try_to_freeze(PF_FREEZE);
+ try_to_freeze();
} while (!signal_pending(current));
printk(KERN_DEBUG "gameport: kgameportd exiting\n");
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 5900de3c3f4..a9bf549c8dc 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -396,7 +396,7 @@ static void i8042_stop(struct serio *serio)
struct i8042_port *port = serio->port_data;
port->exists = 0;
- synchronize_kernel();
+ synchronize_sched();
port->serio = NULL;
}
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index feab4970406..341824c4852 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -344,7 +344,7 @@ static int serio_thread(void *nothing)
do {
serio_handle_events();
wait_event_interruptible(serio_wait, !list_empty(&serio_event_list));
- try_to_freeze(PF_FREEZE);
+ try_to_freeze();
} while (!signal_pending(current));
printk(KERN_DEBUG "serio: kseriod exiting\n");
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index f6b85222ba3..79ca3846915 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -257,7 +257,7 @@ static int __init serport_init(void)
static void __exit serport_exit(void)
{
- tty_register_ldisc(N_MOUSE, NULL);
+ tty_unregister_ldisc(N_MOUSE);
}
module_init(serport_init);
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c
index 40395f56723..afa46681f98 100644
--- a/drivers/isdn/act2000/capi.c
+++ b/drivers/isdn/act2000/capi.c
@@ -224,6 +224,7 @@ actcapi_manufacturer_req_net(act2000_card *card)
/*
* Switch V.42 on or off
*/
+#if 0
int
actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
{
@@ -242,6 +243,7 @@ actcapi_manufacturer_req_v42(act2000_card *card, ulong arg)
ACTCAPI_QUEUE_TX;
return 0;
}
+#endif /* 0 */
/*
* Set error-handler
diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h
index 04d2bcdd37a..f6d5f530b86 100644
--- a/drivers/isdn/act2000/capi.h
+++ b/drivers/isdn/act2000/capi.h
@@ -350,7 +350,6 @@ actcapi_nextsmsg(act2000_card *card)
extern int actcapi_chkhdr(act2000_card *, actcapi_msghdr *);
extern int actcapi_listen_req(act2000_card *);
extern int actcapi_manufacturer_req_net(act2000_card *);
-extern int actcapi_manufacturer_req_v42(act2000_card *, ulong);
extern int actcapi_manufacturer_req_errh(act2000_card *);
extern int actcapi_manufacturer_req_msn(act2000_card *);
extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int, int);
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
index 55bed00ca86..91dd0551fc7 100644
--- a/drivers/isdn/hardware/avm/b1dma.c
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -955,7 +955,7 @@ EXPORT_SYMBOL(b1dma_release_appl);
EXPORT_SYMBOL(b1dma_send_message);
EXPORT_SYMBOL(b1dmactl_read_proc);
-int b1dma_init(void)
+static int __init b1dma_init(void)
{
char *p;
char rev[32];
@@ -972,7 +972,7 @@ int b1dma_init(void)
return 0;
}
-void b1dma_exit(void)
+static void __exit b1dma_exit(void)
{
}
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index fa6b93b1a42..724aac2c1cc 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -885,7 +885,7 @@ static int c4_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
}
-void c4_reset_ctr(struct capi_ctr *ctrl)
+static void c4_reset_ctr(struct capi_ctr *ctrl)
{
avmcard *card = ((avmctrl_info *)(ctrl->driverdata))->card;
avmctrl_info *cinfo;
@@ -933,7 +933,7 @@ static void c4_remove(struct pci_dev *pdev)
/* ------------------------------------------------------------- */
-void c4_register_appl(struct capi_ctr *ctrl,
+static void c4_register_appl(struct capi_ctr *ctrl,
u16 appl,
capi_register_params *rp)
{
@@ -978,7 +978,7 @@ void c4_register_appl(struct capi_ctr *ctrl,
/* ------------------------------------------------------------- */
-void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
+static void c4_release_appl(struct capi_ctr *ctrl, u16 appl)
{
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card;
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
index cb9d9cee2a6..3b701d97bdf 100644
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -328,7 +328,7 @@ static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
return 0;
}
-void t1isa_reset_ctr(struct capi_ctr *ctrl)
+static void t1isa_reset_ctr(struct capi_ctr *ctrl)
{
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card;
diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile
index 8d6bb56754b..293e27789d5 100644
--- a/drivers/isdn/hisax/Makefile
+++ b/drivers/isdn/hisax/Makefile
@@ -23,7 +23,7 @@ endif
# Multipart objects.
hisax_st5481-y := st5481_init.o st5481_usb.o st5481_d.o \
- st5481_b.o st5481_hdlc.o
+ st5481_b.o
hisax-y := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
lmgr.o q931.o callc.o fsm.o
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index c4f861a5db2..8ae08c41c85 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -97,7 +97,7 @@ static WORD initAMD[] = {
};
-void /* macro wWordAMD */
+static void /* macro wWordAMD */
WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val)
{
wByteAMD(cs, 0x00, reg);
@@ -105,7 +105,7 @@ WriteWordAmd7930(struct IsdnCardState *cs, BYTE reg, WORD val)
wByteAMD(cs, 0x01, HIBYTE(val));
}
-WORD /* macro rWordAMD */
+static WORD /* macro rWordAMD */
ReadWordAmd7930(struct IsdnCardState *cs, BYTE reg)
{
WORD res;
@@ -665,7 +665,7 @@ Amd7930_l1hw(struct PStack *st, int pr, void *arg)
}
}
-void
+static void
setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
{
@@ -676,7 +676,7 @@ setstack_Amd7930(struct PStack *st, struct IsdnCardState *cs)
}
-void
+static void
DC_Close_Amd7930(struct IsdnCardState *cs) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "Amd7930: DC_Close called");
diff --git a/drivers/isdn/hisax/asuscom.c b/drivers/isdn/hisax/asuscom.c
index 7546e2e4a94..a98c5e38bbb 100644
--- a/drivers/isdn/hisax/asuscom.c
+++ b/drivers/isdn/hisax/asuscom.c
@@ -22,7 +22,7 @@
extern const char *CardType[];
-const char *Asuscom_revision = "$Revision: 1.14.2.4 $";
+static const char *Asuscom_revision = "$Revision: 1.14.2.4 $";
#define byteout(addr,val) outb(val,addr)
#define bytein(addr) inb(addr)
@@ -239,7 +239,7 @@ Start_IPAC:
return IRQ_HANDLED;
}
-void
+static void
release_io_asuscom(struct IsdnCardState *cs)
{
int bytecnt = 8;
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 6fcb2cf7b0b..625799ab0d1 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -172,7 +172,7 @@ struct BCState *Sel_BCS(struct IsdnCardState *cs, int channel)
return(NULL);
}
-void
+static void
write_ctrl(struct BCState *bcs, int which) {
if (bcs->cs->debug & L1_DEB_HSCX)
@@ -193,7 +193,7 @@ write_ctrl(struct BCState *bcs, int which) {
}
}
-void
+static void
modehdlc(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
@@ -451,7 +451,7 @@ HDLC_irq(struct BCState *bcs, u_int stat) {
}
}
-inline void
+static inline void
HDLC_irq_main(struct IsdnCardState *cs)
{
u_int stat;
@@ -487,7 +487,7 @@ HDLC_irq_main(struct IsdnCardState *cs)
}
}
-void
+static void
hdlc_l2l1(struct PStack *st, int pr, void *arg)
{
struct BCState *bcs = st->l1.bcs;
@@ -547,7 +547,7 @@ hdlc_l2l1(struct PStack *st, int pr, void *arg)
}
}
-void
+static void
close_hdlcstate(struct BCState *bcs)
{
modehdlc(bcs, 0, 0);
@@ -570,7 +570,7 @@ close_hdlcstate(struct BCState *bcs)
}
}
-int
+static int
open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
{
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
@@ -598,7 +598,7 @@ open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
return (0);
}
-int
+static int
setstack_hdlc(struct PStack *st, struct BCState *bcs)
{
bcs->channel = st->l1.bc;
@@ -612,6 +612,7 @@ setstack_hdlc(struct PStack *st, struct BCState *bcs)
return (0);
}
+#if 0
void __init
clear_pending_hdlc_ints(struct IsdnCardState *cs)
{
@@ -641,8 +642,9 @@ clear_pending_hdlc_ints(struct IsdnCardState *cs)
debugl1(cs, "HDLC 2 VIN %x", val);
}
}
+#endif /* 0 */
-void __init
+static void __init
inithdlc(struct IsdnCardState *cs)
{
cs->bcs[0].BC_SetStack = setstack_hdlc;
diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c
index f410f628a3e..dcb308aeb50 100644
--- a/drivers/isdn/hisax/bkm_a4t.c
+++ b/drivers/isdn/hisax/bkm_a4t.c
@@ -23,7 +23,7 @@
extern const char *CardType[];
-const char *bkm_a4t_revision = "$Revision: 1.22.2.4 $";
+static const char *bkm_a4t_revision = "$Revision: 1.22.2.4 $";
static inline u_char
@@ -167,7 +167,7 @@ bkm_interrupt(int intno, void *dev_id, struct pt_regs *regs)
}
}
-void
+static void
release_io_bkm(struct IsdnCardState *cs)
{
if (cs->hw.ax.base) {
diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c
index 94bb83ce7fd..5f21b82c8c8 100644
--- a/drivers/isdn/hisax/bkm_a8.c
+++ b/drivers/isdn/hisax/bkm_a8.c
@@ -27,7 +27,7 @@
extern const char *CardType[];
-const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $";
+static const char sct_quadro_revision[] = "$Revision: 1.22.2.4 $";
static const char *sct_quadro_subtypes[] =
{
@@ -193,7 +193,7 @@ bkm_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_sct_quadro(struct IsdnCardState *cs)
{
release_region(cs->hw.ax.base & 0xffffffc0, 128);
@@ -261,7 +261,7 @@ BKM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
return (0);
}
-int __init
+static int __init
sct_alloc_io(u_int adr, u_int len)
{
if (!request_region(adr, len, "scitel")) {
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index 04065ab2610..7c56c44f0fd 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -874,7 +874,7 @@ release_b_st(struct Channel *chanp)
}
}
-struct Channel
+static struct Channel
*selectfreechannel(struct PStack *st, int bch)
{
struct IsdnCardState *cs = st->l1.hardware;
@@ -1429,7 +1429,7 @@ capi_debug(struct Channel *chanp, capi_msg *cm)
HiSax_putstatus(chanp->cs, "Ch", "%d CAPIMSG %s", chanp->chan, tmpbuf);
}
-void
+static void
lli_got_fac_req(struct Channel *chanp, capi_msg *cm) {
if ((cm->para[0] != 3) || (cm->para[1] != 0))
return;
@@ -1454,7 +1454,7 @@ lli_got_fac_req(struct Channel *chanp, capi_msg *cm) {
}
}
-void
+static void
lli_got_manufacturer(struct Channel *chanp, struct IsdnCardState *cs, capi_msg *cm) {
if ((cs->typ == ISDN_CTYPE_ELSA) || (cs->typ == ISDN_CTYPE_ELSA_PNP) ||
(cs->typ == ISDN_CTYPE_ELSA_PCI)) {
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index 1663ee69d41..c542e6fb2bd 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -332,7 +332,7 @@ struct IsdnCard cards[HISAX_MAX_CARDS] = {
#define HISAX_IDSIZE (HISAX_MAX_CARDS*8)
static char HiSaxID[HISAX_IDSIZE] = { 0, };
-char *HiSax_id = HiSaxID;
+static char *HiSax_id = HiSaxID;
#ifdef MODULE
/* Variables for insmod */
static int type[HISAX_MAX_CARDS] = { 0, };
@@ -391,7 +391,7 @@ char *HiSax_getrev(const char *revision)
return rev;
}
-void __init HiSaxVersion(void)
+static void __init HiSaxVersion(void)
{
char tmp[64];
@@ -608,6 +608,7 @@ static inline struct IsdnCardState *hisax_findcard(int driverid)
/*
* Find card with given card number
*/
+#if 0
struct IsdnCardState *hisax_get_card(int cardnr)
{
if ((cardnr <= nrcards) && (cardnr > 0))
@@ -615,8 +616,9 @@ struct IsdnCardState *hisax_get_card(int cardnr)
return cards[cardnr - 1].cs;
return NULL;
}
+#endif /* 0 */
-int HiSax_readstatus(u_char __user *buf, int len, int id, int channel)
+static int HiSax_readstatus(u_char __user *buf, int len, int id, int channel)
{
int count, cnt;
u_char __user *p = buf;
@@ -768,7 +770,7 @@ int ll_run(struct IsdnCardState *cs, int addfeatures)
return 0;
}
-void ll_stop(struct IsdnCardState *cs)
+static void ll_stop(struct IsdnCardState *cs)
{
isdn_ctrl ic;
@@ -1184,7 +1186,7 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow
return ret;
}
-void HiSax_shiftcards(int idx)
+static void HiSax_shiftcards(int idx)
{
int i;
@@ -1192,7 +1194,7 @@ void HiSax_shiftcards(int idx)
memcpy(&cards[i], &cards[i + 1], sizeof(cards[i]));
}
-int HiSax_inithardware(int *busy_flag)
+static int HiSax_inithardware(int *busy_flag)
{
int foundcards = 0;
int i = 0;
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
index 394d481e093..b62d6b30b72 100644
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -28,7 +28,7 @@
extern const char *CardType[];
-const char *Diva_revision = "$Revision: 1.33.2.6 $";
+static const char *Diva_revision = "$Revision: 1.33.2.6 $";
#define byteout(addr,val) outb(val,addr)
#define bytein(addr) inb(addr)
@@ -706,7 +706,7 @@ diva_irq_ipacx_pci(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_diva(struct IsdnCardState *cs)
{
int bytecnt;
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
index 4d7a0250d7e..110e9fd669c 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -33,13 +33,13 @@
extern const char *CardType[];
-const char *Elsa_revision = "$Revision: 2.32.2.4 $";
-const char *Elsa_Types[] =
+static const char *Elsa_revision = "$Revision: 2.32.2.4 $";
+static const char *Elsa_Types[] =
{"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
"PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI",
"PCMCIA-IPAC" };
-const char *ITACVer[] =
+static const char *ITACVer[] =
{"?0?", "?1?", "?2?", "?3?", "?4?", "V2.2",
"B1", "A1"};
@@ -425,7 +425,7 @@ Start_IPAC:
return IRQ_HANDLED;
}
-void
+static void
release_io_elsa(struct IsdnCardState *cs)
{
int bytecnt = 8;
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c
index 689c8339569..898ec091619 100644
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -237,7 +237,7 @@ static void mshutdown(struct IsdnCardState *cs)
#endif
}
-inline int
+static inline int
write_modem(struct BCState *bcs) {
int ret=0;
struct IsdnCardState *cs = bcs->cs;
@@ -275,7 +275,7 @@ write_modem(struct BCState *bcs) {
return(ret);
}
-inline void
+static inline void
modem_fill(struct BCState *bcs) {
if (bcs->tx_skb) {
@@ -422,7 +422,7 @@ extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);
extern void modehscx(struct BCState *bcs, int mode, int bc);
extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
-void
+static void
close_elsastate(struct BCState *bcs)
{
modehscx(bcs, 0, bcs->channel);
@@ -442,7 +442,7 @@ close_elsastate(struct BCState *bcs)
}
}
-void
+static void
modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
int count, fp;
u_char *msg = buf;
@@ -472,7 +472,7 @@ modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
}
}
-void
+static void
modem_set_init(struct IsdnCardState *cs) {
int timeout;
@@ -521,7 +521,7 @@ modem_set_init(struct IsdnCardState *cs) {
udelay(RCV_DELAY);
}
-void
+static void
modem_set_dial(struct IsdnCardState *cs, int outgoing) {
int timeout;
#define RCV_DELAY 20000
@@ -543,7 +543,7 @@ modem_set_dial(struct IsdnCardState *cs, int outgoing) {
udelay(RCV_DELAY);
}
-void
+static void
modem_l2l1(struct PStack *st, int pr, void *arg)
{
struct BCState *bcs = st->l1.bcs;
@@ -579,7 +579,7 @@ modem_l2l1(struct PStack *st, int pr, void *arg)
}
}
-int
+static int
setstack_elsa(struct PStack *st, struct BCState *bcs)
{
@@ -614,7 +614,7 @@ setstack_elsa(struct PStack *st, struct BCState *bcs)
return (0);
}
-void
+static void
init_modem(struct IsdnCardState *cs) {
cs->bcs[0].BC_SetStack = setstack_elsa;
@@ -641,7 +641,7 @@ init_modem(struct IsdnCardState *cs) {
modem_set_init(cs);
}
-void
+static void
release_modem(struct IsdnCardState *cs) {
cs->hw.elsa.MFlag = 0;
diff --git a/drivers/isdn/hisax/enternow.h b/drivers/isdn/hisax/enternow.h
deleted file mode 100644
index ed2eec5874c..00000000000
--- a/drivers/isdn/hisax/enternow.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* 2001/10/02
- *
- * enternow.h Header-file included by
- * enternow_pci.c
- *
- * Author Christoph Ersfeld <info@formula-n.de>
- * Formula-n Europe AG (www.formula-n.com)
- * previously Gerdes AG
- *
- *
- * This file is (c) under GNU PUBLIC LICENSE
- */
-
-
-/* ***************************************************************************************** *
- * ****************************** datatypes and macros ************************************* *
- * ***************************************************************************************** */
-
-#define BYTE unsigned char
-#define WORD unsigned int
-#define HIBYTE(w) ((unsigned char)((w & 0xff00) / 256))
-#define LOBYTE(w) ((unsigned char)(w & 0x00ff))
-#define InByte(addr) inb(addr)
-#define OutByte(addr,val) outb(val,addr)
-
-
-
-/* ***************************************************************************************** *
- * *********************************** card-specific *************************************** *
- * ***************************************************************************************** */
-
-/* für PowerISDN PCI */
-#define TJ_AMD_IRQ 0x20
-#define TJ_LED1 0x40
-#define TJ_LED2 0x80
-
-
-/* Das Fenster zum AMD...
- * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in
- * den TigerJet i/o-Raum gemappt
- * -> 0x01 des AMD bei hw.njet.base + 0C4 */
-#define TJ_AMD_PORT 0xC0
-
-
-
-/* ***************************************************************************************** *
- * *************************************** Prototypen ************************************** *
- * ***************************************************************************************** */
-
-BYTE ReadByteAmd7930(struct IsdnCardState *cs, BYTE offset);
-void WriteByteAmd7930(struct IsdnCardState *cs, BYTE offset, BYTE value);
diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c
index 1cc4d11e007..3341cf15553 100644
--- a/drivers/isdn/hisax/enternow_pci.c
+++ b/drivers/isdn/hisax/enternow_pci.c
@@ -65,7 +65,6 @@
#include "isac.h"
#include "isdnl1.h"
#include "amd7930_fn.h"
-#include "enternow.h"
#include <linux/interrupt.h>
#include <linux/ppp_defs.h>
#include <linux/pci.h>
@@ -74,58 +73,72 @@
-const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
+static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
+
+
+/* für PowerISDN PCI */
+#define TJ_AMD_IRQ 0x20
+#define TJ_LED1 0x40
+#define TJ_LED2 0x80
+
+
+/* Das Fenster zum AMD...
+ * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in
+ * den TigerJet i/o-Raum gemappt
+ * -> 0x01 des AMD bei hw.njet.base + 0C4 */
+#define TJ_AMD_PORT 0xC0
+
/* *************************** I/O-Interface functions ************************************* */
/* cs->readisac, macro rByteAMD */
-BYTE
-ReadByteAmd7930(struct IsdnCardState *cs, BYTE offset)
+static unsigned char
+ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset)
{
/* direktes Register */
if(offset < 8)
- return (InByte(cs->hw.njet.isac + 4*offset));
+ return (inb(cs->hw.njet.isac + 4*offset));
/* indirektes Register */
else {
- OutByte(cs->hw.njet.isac + 4*AMD_CR, offset);
- return(InByte(cs->hw.njet.isac + 4*AMD_DR));
+ outb(offset, cs->hw.njet.isac + 4*AMD_CR);
+ return(inb(cs->hw.njet.isac + 4*AMD_DR));
}
}
/* cs->writeisac, macro wByteAMD */
-void
-WriteByteAmd7930(struct IsdnCardState *cs, BYTE offset, BYTE value)
+static void
+WriteByteAmd7930(struct IsdnCardState *cs, unsigned char offset, unsigned char value)
{
/* direktes Register */
if(offset < 8)
- OutByte(cs->hw.njet.isac + 4*offset, value);
+ outb(value, cs->hw.njet.isac + 4*offset);
/* indirektes Register */
else {
- OutByte(cs->hw.njet.isac + 4*AMD_CR, offset);
- OutByte(cs->hw.njet.isac + 4*AMD_DR, value);
+ outb(offset, cs->hw.njet.isac + 4*AMD_CR);
+ outb(value, cs->hw.njet.isac + 4*AMD_DR);
}
}
-void
-enpci_setIrqMask(struct IsdnCardState *cs, BYTE val) {
+static void
+enpci_setIrqMask(struct IsdnCardState *cs, unsigned char val) {
if (!val)
- OutByte(cs->hw.njet.base+NETJET_IRQMASK1, 0x00);
+ outb(0x00, cs->hw.njet.base+NETJET_IRQMASK1);
else
- OutByte(cs->hw.njet.base+NETJET_IRQMASK1, TJ_AMD_IRQ);
+ outb(TJ_AMD_IRQ, cs->hw.njet.base+NETJET_IRQMASK1);
}
-static BYTE dummyrr(struct IsdnCardState *cs, int chan, BYTE off)
+static unsigned char dummyrr(struct IsdnCardState *cs, int chan, unsigned char off)
{
return(5);
}
-static void dummywr(struct IsdnCardState *cs, int chan, BYTE off, BYTE value)
+static void dummywr(struct IsdnCardState *cs, int chan, unsigned char off, unsigned char value)
{
}
@@ -142,18 +155,18 @@ reset_enpci(struct IsdnCardState *cs)
/* Reset on, (also for AMD) */
cs->hw.njet.ctrl_reg = 0x07;
- OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+ outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
mdelay(20);
/* Reset off */
cs->hw.njet.ctrl_reg = 0x30;
- OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+ outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
/* 20ms delay */
mdelay(20);
cs->hw.njet.auxd = 0; // LED-status
cs->hw.njet.dmactrl = 0;
- OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ);
- OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
- OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd); // LED off
+ outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL);
+ outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1);
+ outb(cs->hw.njet.auxd, cs->hw.njet.auxa); // LED off
}
@@ -161,7 +174,7 @@ static int
enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
u_long flags;
- BYTE *chan;
+ unsigned char *chan;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "enter:now PCI: card_msg: 0x%04X", mt);
@@ -187,16 +200,16 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
case MDL_ASSIGN:
/* TEI assigned, LED1 on */
cs->hw.njet.auxd = TJ_AMD_IRQ << 1;
- OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
+ outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
break;
case MDL_REMOVE:
/* TEI removed, LEDs off */
cs->hw.njet.auxd = 0;
- OutByte(cs->hw.njet.base + NETJET_AUXDATA, 0x00);
+ outb(0x00, cs->hw.njet.base + NETJET_AUXDATA);
break;
case MDL_BC_ASSIGN:
/* activate B-channel */
- chan = (BYTE *)arg;
+ chan = (unsigned char *)arg;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "enter:now PCI: assign phys. BC %d in AMD LMR1", *chan);
@@ -204,11 +217,11 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
cs->dc.amd7930.ph_command(cs, (cs->dc.amd7930.lmr1 | (*chan + 1)), "MDL_BC_ASSIGN");
/* at least one b-channel in use, LED 2 on */
cs->hw.njet.auxd |= TJ_AMD_IRQ << 2;
- OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
+ outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
break;
case MDL_BC_RELEASE:
/* deactivate B-channel */
- chan = (BYTE *)arg;
+ chan = (unsigned char *)arg;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "enter:now PCI: release phys. BC %d in Amd LMR1", *chan);
@@ -217,7 +230,7 @@ enpci_card_msg(struct IsdnCardState *cs, int mt, void *arg)
/* no b-channel active -> LED2 off */
if (!(cs->dc.amd7930.lmr1 & 3)) {
cs->hw.njet.auxd &= ~(TJ_AMD_IRQ << 2);
- OutByte(cs->hw.njet.base + NETJET_AUXDATA, cs->hw.njet.auxd);
+ outb(cs->hw.njet.auxd, cs->hw.njet.base + NETJET_AUXDATA);
}
break;
default:
@@ -231,11 +244,11 @@ static irqreturn_t
enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
- BYTE s0val, s1val, ir;
+ unsigned char s0val, s1val, ir;
u_long flags;
spin_lock_irqsave(&cs->lock, flags);
- s1val = InByte(cs->hw.njet.base + NETJET_IRQSTAT1);
+ s1val = inb(cs->hw.njet.base + NETJET_IRQSTAT1);
/* AMD threw an interrupt */
if (!(s1val & TJ_AMD_IRQ)) {
@@ -245,13 +258,13 @@ enpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
s1val = 1;
} else
s1val = 0;
- s0val = InByte(cs->hw.njet.base + NETJET_IRQSTAT0);
+ s0val = inb(cs->hw.njet.base + NETJET_IRQSTAT0);
if ((s0val | s1val)==0) { // shared IRQ
spin_unlock_irqrestore(&cs->lock, flags);
return IRQ_NONE;
}
if (s0val)
- OutByte(cs->hw.njet.base + NETJET_IRQSTAT0, s0val);
+ outb(s0val, cs->hw.njet.base + NETJET_IRQSTAT0);
/* DMA-Interrupt: B-channel-stuff */
/* set bits in sval to indicate which page is free */
@@ -342,20 +355,20 @@ setup_enternow_pci(struct IsdnCard *card)
/* Reset an */
cs->hw.njet.ctrl_reg = 0x07; // geändert von 0xff
- OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+ outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
/* 20 ms Pause */
mdelay(20);
cs->hw.njet.ctrl_reg = 0x30; /* Reset Off and status read clear */
- OutByte(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
+ outb(cs->hw.njet.ctrl_reg, cs->hw.njet.base + NETJET_CTRL);
mdelay(10);
cs->hw.njet.auxd = 0x00; // war 0xc0
cs->hw.njet.dmactrl = 0;
- OutByte(cs->hw.njet.base + NETJET_AUXCTRL, ~TJ_AMD_IRQ);
- OutByte(cs->hw.njet.base + NETJET_IRQMASK1, TJ_AMD_IRQ);
- OutByte(cs->hw.njet.auxa, cs->hw.njet.auxd);
+ outb(~TJ_AMD_IRQ, cs->hw.njet.base + NETJET_AUXCTRL);
+ outb(TJ_AMD_IRQ, cs->hw.njet.base + NETJET_IRQMASK1);
+ outb(cs->hw.njet.auxd, cs->hw.njet.auxa);
break;
}
diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c
index 24a05a43f33..352b45ac534 100644
--- a/drivers/isdn/hisax/gazel.c
+++ b/drivers/isdn/hisax/gazel.c
@@ -21,7 +21,7 @@
#include <linux/pci.h>
extern const char *CardType[];
-const char *gazel_revision = "$Revision: 2.19.2.4 $";
+static const char *gazel_revision = "$Revision: 2.19.2.4 $";
#define R647 1
#define R685 2
@@ -317,7 +317,8 @@ gazel_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
spin_unlock_irqrestore(&cs->lock, flags);
return IRQ_HANDLED;
}
-void
+
+static void
release_io_gazel(struct IsdnCardState *cs)
{
unsigned int i;
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index ba1d028343e..6e7e060716b 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -1358,7 +1358,7 @@ chipreset(hfc4s8s_hw * hw)
/********************************************/
/* disable/enable hardware in nt or te mode */
/********************************************/
-void
+static void
hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode)
{
u_long flags;
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index ebea3feef00..7cf87793e79 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -345,7 +345,7 @@ hfc_send_data(struct BCState *bcs)
debugl1(cs,"send_data %d blocked", bcs->channel);
}
-void
+static void
main_rec_2bds0(struct BCState *bcs)
{
struct IsdnCardState *cs = bcs->cs;
@@ -399,7 +399,7 @@ main_rec_2bds0(struct BCState *bcs)
return;
}
-void
+static void
mode_2bs0(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
@@ -505,7 +505,7 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
}
}
-void
+static void
close_2bs0(struct BCState *bcs)
{
mode_2bs0(bcs, 0, bcs->channel);
@@ -534,7 +534,7 @@ open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
return (0);
}
-int
+static int
setstack_2b(struct PStack *st, struct BCState *bcs)
{
bcs->channel = st->l1.bc;
@@ -1004,7 +1004,7 @@ HFCD_l1hw(struct PStack *st, int pr, void *arg)
}
}
-void
+static void
setstack_hfcd(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = HFCD_l1hw;
@@ -1015,7 +1015,7 @@ hfc_dbusy_timer(struct IsdnCardState *cs)
{
}
-unsigned int __init
+static unsigned int __init
*init_send_hfcd(int cnt)
{
int i, *send;
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index bb376f39ac8..f978a5af866 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -52,7 +52,7 @@ WaitNoBusy(struct IsdnCardState *cs)
return (to);
}
-int
+static int
GetFreeFifoBytes(struct BCState *bcs)
{
int s;
@@ -66,7 +66,7 @@ GetFreeFifoBytes(struct BCState *bcs)
return (s);
}
-int
+static int
ReadZReg(struct BCState *bcs, u_char reg)
{
int val;
@@ -394,7 +394,7 @@ main_irq_hfc(struct BCState *bcs)
return;
}
-void
+static void
mode_hfc(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
@@ -507,7 +507,7 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
}
-void
+static void
close_hfcstate(struct BCState *bcs)
{
mode_hfc(bcs, 0, bcs->channel);
@@ -537,7 +537,7 @@ open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
return (0);
}
-int
+static int
setstack_hfc(struct PStack *st, struct BCState *bcs)
{
bcs->channel = st->l1.bc;
@@ -551,7 +551,7 @@ setstack_hfc(struct PStack *st, struct BCState *bcs)
return (0);
}
-void __init
+static void __init
init_send(struct BCState *bcs)
{
int i;
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index c2db52696a8..8337b0f26cc 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -70,7 +70,7 @@ static const PCI_ENTRY id_list[] =
/******************************************/
/* free hardware resources used by driver */
/******************************************/
-void
+static void
release_io_hfcpci(struct IsdnCardState *cs)
{
printk(KERN_INFO "HiSax: release hfcpci at %p\n",
@@ -394,7 +394,7 @@ receive_dmsg(struct IsdnCardState *cs)
/*******************************************************************************/
/* check for transparent receive data and read max one threshold size if avail */
/*******************************************************************************/
-int
+static int
hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata)
{
unsigned short *z1r, *z2r;
@@ -446,7 +446,7 @@ hfcpci_empty_fifo_trans(struct BCState *bcs, bzfifo_type * bz, u_char * bdata)
/**********************************/
/* B-channel main receive routine */
/**********************************/
-void
+static void
main_rec_hfcpci(struct BCState *bcs)
{
struct IsdnCardState *cs = bcs->cs;
@@ -1244,7 +1244,7 @@ HFCPCI_l1hw(struct PStack *st, int pr, void *arg)
/***********************************************/
/* called during init setting l1 stack pointer */
/***********************************************/
-void
+static void
setstack_hfcpci(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = HFCPCI_l1hw;
@@ -1268,7 +1268,7 @@ hfcpci_send_data(struct BCState *bcs)
/***************************************************************/
/* activate/deactivate hardware for selected channels and mode */
/***************************************************************/
-void
+static void
mode_hfcpci(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
@@ -1579,7 +1579,7 @@ hfcpci_bh(struct IsdnCardState *cs)
/********************************/
/* called for card init message */
/********************************/
-void __init
+static void __init
inithfcpci(struct IsdnCardState *cs)
{
cs->bcs[0].BC_SetStack = setstack_2b;
diff --git a/drivers/isdn/hisax/hfc_pci.h b/drivers/isdn/hisax/hfc_pci.h
index 4df036ed1af..9ef2981e404 100644
--- a/drivers/isdn/hisax/hfc_pci.h
+++ b/drivers/isdn/hisax/hfc_pci.h
@@ -232,5 +232,4 @@ typedef union {
#define Read_hfc(a,b) (*(((u_char *)a->hw.hfcpci.pci_io)+b))
extern void main_irq_hcpci(struct BCState *bcs);
-extern void inithfcpci(struct IsdnCardState *cs);
extern void releasehfcpci(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index a307fcb6c63..f27c1608a3a 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -308,7 +308,7 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max)
/******************************************/
/* free hardware resources used by driver */
/******************************************/
-void
+static void
release_io_hfcsx(struct IsdnCardState *cs)
{
cs->hw.hfcsx.int_m2 = 0; /* interrupt output off ! */
@@ -472,7 +472,7 @@ receive_dmsg(struct IsdnCardState *cs)
/**********************************/
/* B-channel main receive routine */
/**********************************/
-void
+static void
main_rec_hfcsx(struct BCState *bcs)
{
struct IsdnCardState *cs = bcs->cs;
@@ -1003,7 +1003,7 @@ HFCSX_l1hw(struct PStack *st, int pr, void *arg)
/***********************************************/
/* called during init setting l1 stack pointer */
/***********************************************/
-void
+static void
setstack_hfcsx(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = HFCSX_l1hw;
@@ -1027,7 +1027,7 @@ hfcsx_send_data(struct BCState *bcs)
/***************************************************************/
/* activate/deactivate hardware for selected channels and mode */
/***************************************************************/
-void
+static void
mode_hfcsx(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
@@ -1328,7 +1328,7 @@ hfcsx_bh(struct IsdnCardState *cs)
/********************************/
/* called for card init message */
/********************************/
-void __devinit
+static void __devinit
inithfcsx(struct IsdnCardState *cs)
{
cs->setstack_d = setstack_hfcsx;
diff --git a/drivers/isdn/hisax/hfc_sx.h b/drivers/isdn/hisax/hfc_sx.h
index 12f54159344..6792f13dc22 100644
--- a/drivers/isdn/hisax/hfc_sx.h
+++ b/drivers/isdn/hisax/hfc_sx.h
@@ -193,5 +193,4 @@ struct hfcsx_extra {
};
extern void main_irq_hfcsx(struct BCState *bcs);
-extern void inithfcsx(struct IsdnCardState *cs);
extern void releasehfcsx(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index ffd74b84f50..e2c3af49d72 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -60,7 +60,7 @@ static const char *hfcusb_revision =
#include "hisax_debug.h"
static u_int debug;
module_param(debug, uint, 0);
-int hfc_debug;
+static int hfc_debug;
#endif
@@ -85,7 +85,7 @@ static struct usb_device_id hfc_usb_idtab[] = {
* VendorID, ProductID, Devicename, LED_SCHEME,
* LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2
*/
-vendor_data vdata[] = {
+static vendor_data vdata[] = {
/* CologneChip Eval TA */
{0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)",
LED_OFF, {4, 0, 2, 1}
@@ -1137,7 +1137,7 @@ set_hfcmode(hfcusb_data * hfc, int channel, int mode)
}
}
-void
+static void
hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
{
usb_fifo *fifo = my_hisax_if->priv;
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h
index b171600cf64..280dd29b30d 100644
--- a/drivers/isdn/hisax/hfc_usb.h
+++ b/drivers/isdn/hisax/hfc_usb.h
@@ -168,7 +168,7 @@ static struct hfcusb_symbolic_list urb_errlist[] = {
* 3 entries are the configuration number, the minimum interval for
* Interrupt endpoints & boolean if E-channel logging possible
*/
-int validconf[][19] = {
+static int validconf[][19] = {
// INT in, ISO out config
{EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT,
EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_ISO, EP_NUL, EP_NUL, EP_NUL,
@@ -187,7 +187,7 @@ int validconf[][19] = {
};
// string description of chosen config
-char *conf_str[] = {
+static char *conf_str[] = {
"4 Interrupt IN + 3 Isochron OUT",
"3 Interrupt IN + 3 Isochron OUT",
"4 Isochron IN + 3 Isochron OUT",
diff --git a/drivers/isdn/hisax/hfcscard.c b/drivers/isdn/hisax/hfcscard.c
index 6fc55fea170..86ab1c13f6b 100644
--- a/drivers/isdn/hisax/hfcscard.c
+++ b/drivers/isdn/hisax/hfcscard.c
@@ -52,7 +52,7 @@ hfcs_Timer(struct IsdnCardState *cs)
*/
}
-void
+static void
release_io_hfcs(struct IsdnCardState *cs)
{
release2bds0(cs);
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index dc5791728d5..17cf7663c58 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1271,7 +1271,6 @@ extern void Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf,
void init_bcstate(struct IsdnCardState *cs, int bc);
void setstack_HiSax(struct PStack *st, struct IsdnCardState *cs);
-unsigned int random_ri(void);
void HiSax_addlist(struct IsdnCardState *sp, struct PStack *st);
void HiSax_rmlist(struct IsdnCardState *sp, struct PStack *st);
@@ -1315,15 +1314,11 @@ int QuickHex(char *txt, u_char * p, int cnt);
void LogFrame(struct IsdnCardState *cs, u_char * p, int size);
void dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir);
void iecpy(u_char * dest, u_char * iestart, int ieoffset);
-#ifdef ISDN_CHIP_ISAC
-void setstack_isac(struct PStack *st, struct IsdnCardState *cs);
-#endif /* ISDN_CHIP_ISAC */
#endif /* __KERNEL__ */
#define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}
int ll_run(struct IsdnCardState *cs, int addfeatures);
-void ll_stop(struct IsdnCardState *cs);
int CallcNew(void);
void CallcFree(void);
int CallcNewChan(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c
index 5bbbe3e9512..66dbaee77bf 100644
--- a/drivers/isdn/hisax/hscx.c
+++ b/drivers/isdn/hisax/hscx.c
@@ -151,7 +151,7 @@ hscx_l2l1(struct PStack *st, int pr, void *arg)
}
}
-void
+static void
close_hscxstate(struct BCState *bcs)
{
modehscx(bcs, 0, bcs->channel);
@@ -203,7 +203,7 @@ open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs)
return (0);
}
-int
+static int
setstack_hscx(struct PStack *st, struct BCState *bcs)
{
bcs->channel = st->l1.bc;
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index dcf31f83c60..b4ca5859b17 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -108,7 +108,7 @@ icc_bh(struct IsdnCardState *cs)
#endif
}
-void
+static void
icc_empty_fifo(struct IsdnCardState *cs, int count)
{
u_char *ptr;
@@ -563,13 +563,13 @@ ICC_l1hw(struct PStack *st, int pr, void *arg)
}
}
-void
+static void
setstack_icc(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = ICC_l1hw;
}
-void
+static void
DC_Close_icc(struct IsdnCardState *cs) {
if (cs->dc.icc.mon_rx) {
kfree(cs->dc.icc.mon_rx);
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index 6485e232d86..efba2f44801 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -36,8 +36,6 @@ static void ph_command(struct IsdnCardState *cs, unsigned int command);
static inline void cic_int(struct IsdnCardState *cs);
static void dch_l2l1(struct PStack *st, int pr, void *arg);
static void dbusy_timer_handler(struct IsdnCardState *cs);
-static void ipacx_new_ph(struct IsdnCardState *cs);
-static void dch_bh(struct IsdnCardState *cs);
static void dch_empty_fifo(struct IsdnCardState *cs, int count);
static void dch_fill_fifo(struct IsdnCardState *cs);
static inline void dch_int(struct IsdnCardState *cs);
@@ -232,81 +230,6 @@ dbusy_timer_handler(struct IsdnCardState *cs)
}
//----------------------------------------------------------
-// L1 state machine intermediate layer to isdnl1 module
-//----------------------------------------------------------
-static void
-ipacx_new_ph(struct IsdnCardState *cs)
-{
- switch (cs->dc.isac.ph_state) {
- case (IPACX_IND_RES):
- ph_command(cs, IPACX_CMD_DI);
- l1_msg(cs, HW_RESET | INDICATION, NULL);
- break;
-
- case (IPACX_IND_DC):
- l1_msg(cs, HW_DEACTIVATE | CONFIRM, NULL);
- break;
-
- case (IPACX_IND_DR):
- l1_msg(cs, HW_DEACTIVATE | INDICATION, NULL);
- break;
-
- case (IPACX_IND_PU):
- l1_msg(cs, HW_POWERUP | CONFIRM, NULL);
- break;
-
- case (IPACX_IND_RSY):
- l1_msg(cs, HW_RSYNC | INDICATION, NULL);
- break;
-
- case (IPACX_IND_AR):
- l1_msg(cs, HW_INFO2 | INDICATION, NULL);
- break;
-
- case (IPACX_IND_AI8):
- l1_msg(cs, HW_INFO4_P8 | INDICATION, NULL);
- break;
-
- case (IPACX_IND_AI10):
- l1_msg(cs, HW_INFO4_P10 | INDICATION, NULL);
- break;
-
- default:
- break;
- }
-}
-
-//----------------------------------------------------------
-// bottom half handler for D channel
-//----------------------------------------------------------
-static void
-dch_bh(struct IsdnCardState *cs)
-{
- struct PStack *st;
-
- if (!cs) return;
-
- if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
- if (cs->debug) debugl1(cs, "D-Channel Busy cleared");
- for (st = cs->stlist; st; st = st->next) {
- st->l1.l1l2(st, PH_PAUSE | CONFIRM, NULL);
- }
- }
-
- if (test_and_clear_bit(D_RCVBUFREADY, &cs->event)) {
- DChannel_proc_rcv(cs);
- }
-
- if (test_and_clear_bit(D_XMTBUFREADY, &cs->event)) {
- DChannel_proc_xmt(cs);
- }
-
- if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
- ipacx_new_ph(cs);
- }
-}
-
-//----------------------------------------------------------
// Fill buffer from receive FIFO
//----------------------------------------------------------
static void
@@ -991,14 +914,5 @@ init_ipacx(struct IsdnCardState *cs, int part)
}
}
-
-void __devinit
-setup_ipacx(struct IsdnCardState *cs)
-{
- INIT_WORK(&cs->tqueue, (void *)(void *) dch_bh, cs);
- cs->dbusytimer.function = (void *) dbusy_timer_handler;
- cs->dbusytimer.data = (long) cs;
- init_timer(&cs->dbusytimer);
-}
//----------------- end of file -----------------------
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index 20b94995295..85e063a08d2 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -112,7 +112,7 @@ isac_bh(struct IsdnCardState *cs)
#endif
}
-void
+static void
isac_empty_fifo(struct IsdnCardState *cs, int count)
{
u_char *ptr;
@@ -563,13 +563,13 @@ ISAC_l1hw(struct PStack *st, int pr, void *arg)
}
}
-void
+static void
setstack_isac(struct PStack *st, struct IsdnCardState *cs)
{
st->l1.l1hw = ISAC_l1hw;
}
-void
+static void
DC_Close_isac(struct IsdnCardState *cs) {
if (cs->dc.isac.mon_rx) {
kfree(cs->dc.isac.mon_rx);
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index ee081321efb..642a87c5129 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -21,13 +21,13 @@
#define ETX 0x03
#define FAXMODCNT 13
-const u_char faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
+static const u_char faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
static u_int modmask = 0x1fff;
static int frm_extra_delay = 2;
static int para_TOA = 6;
-const u_char *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" };
+static const u_char *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" };
-void isar_setup(struct IsdnCardState *cs);
+static void isar_setup(struct IsdnCardState *cs);
static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para);
static void ll_deliver_faxstat(struct BCState *bcs, u_char status);
@@ -45,7 +45,7 @@ waitforHIA(struct IsdnCardState *cs, int timeout)
}
-int
+static int
sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
u_char *msg)
{
@@ -85,7 +85,7 @@ sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len,
}
/* Call only with IRQ disabled !!! */
-inline void
+static inline void
rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg)
{
int i;
@@ -114,7 +114,7 @@ rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg)
}
/* Call only with IRQ disabled !!! */
-inline void
+static inline void
get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg)
{
ireg->iis = cs->BC_Read_Reg(cs, 1, ISAR_IIS);
@@ -127,7 +127,7 @@ get_irq_infos(struct IsdnCardState *cs, struct isar_reg *ireg)
#endif
}
-int
+static int
waitrecmsg(struct IsdnCardState *cs, u_char *len,
u_char *msg, int maxdelay)
{
@@ -185,7 +185,7 @@ ISARVersion(struct IsdnCardState *cs, char *s)
return(ver);
}
-int
+static int
isar_load_firmware(struct IsdnCardState *cs, u_char __user *buf)
{
int ret, size, cnt, debug;
@@ -739,7 +739,7 @@ isar_fill_fifo(struct BCState *bcs)
}
}
-inline
+static inline
struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath)
{
if ((!dpath) || (dpath == 3))
@@ -751,7 +751,7 @@ struct BCState *sel_bcs_isar(struct IsdnCardState *cs, u_char dpath)
return(NULL);
}
-void
+static void
send_frames(struct BCState *bcs)
{
if (bcs->tx_skb) {
@@ -806,7 +806,7 @@ send_frames(struct BCState *bcs)
}
}
-inline void
+static inline void
check_send(struct IsdnCardState *cs, u_char rdm)
{
struct BCState *bcs;
@@ -828,11 +828,13 @@ check_send(struct IsdnCardState *cs, u_char rdm)
}
-const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
- "300", "600", "1200", "2400", "4800", "7200",
- "9600nt", "9600t", "12000", "14400", "WRONG"};
-const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
- "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
+static const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200",
+ "NODEF4", "300", "600", "1200", "2400",
+ "4800", "7200", "9600nt", "9600t", "12000",
+ "14400", "WRONG"};
+static const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
+ "Bell103", "V23", "Bell202", "V17", "V29",
+ "V27ter"};
static void
isar_pump_status_rsp(struct BCState *bcs, struct isar_reg *ireg) {
@@ -1388,7 +1390,7 @@ setup_iom2(struct BCState *bcs) {
udelay(1000);
}
-int
+static int
modeisar(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
@@ -1562,7 +1564,7 @@ isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para)
sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
}
-void
+static void
isar_setup(struct IsdnCardState *cs)
{
u_char msg;
@@ -1582,7 +1584,7 @@ isar_setup(struct IsdnCardState *cs)
}
}
-void
+static void
isar_l2l1(struct PStack *st, int pr, void *arg)
{
struct BCState *bcs = st->l1.bcs;
@@ -1681,7 +1683,7 @@ isar_l2l1(struct PStack *st, int pr, void *arg)
}
}
-void
+static void
close_isarstate(struct BCState *bcs)
{
modeisar(bcs, 0, bcs->channel);
@@ -1703,7 +1705,7 @@ close_isarstate(struct BCState *bcs)
del_timer(&bcs->hw.isar.ftimer);
}
-int
+static int
open_isarstate(struct IsdnCardState *cs, struct BCState *bcs)
{
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
@@ -1725,7 +1727,7 @@ open_isarstate(struct IsdnCardState *cs, struct BCState *bcs)
return (0);
}
-int
+static int
setstack_isar(struct PStack *st, struct BCState *bcs)
{
bcs->channel = st->l1.bc;
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index 4d08d27f149..ac899503a74 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -151,7 +151,7 @@ l1m_debug(struct FsmInst *fi, char *fmt, ...)
va_end(args);
}
-void
+static void
L1activated(struct IsdnCardState *cs)
{
struct PStack *st;
@@ -166,7 +166,7 @@ L1activated(struct IsdnCardState *cs)
}
}
-void
+static void
L1deactivated(struct IsdnCardState *cs)
{
struct PStack *st;
@@ -370,7 +370,7 @@ init_bcstate(struct IsdnCardState *cs, int bc)
#ifdef L2FRAME_DEBUG /* psa */
-char *
+static char *
l2cmd(u_char cmd)
{
switch (cmd & ~0x10) {
@@ -404,7 +404,7 @@ l2cmd(u_char cmd)
static char tmpdeb[32];
-char *
+static char *
l2frames(u_char * ptr)
{
switch (ptr[2] & ~0x10) {
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
index d311b5fbf89..9022583fd6a 100644
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -142,7 +142,7 @@ freewin1(struct Layer2 *l2)
return cnt;
}
-inline void
+static inline void
freewin(struct PStack *st)
{
freewin1(&st->l2);
@@ -157,7 +157,7 @@ ReleaseWin(struct Layer2 *l2)
printk(KERN_WARNING "isdl2 freed %d skbuffs in release\n", cnt);
}
-inline unsigned int
+static inline unsigned int
cansend(struct PStack *st)
{
unsigned int p1;
@@ -169,7 +169,7 @@ cansend(struct PStack *st)
return ((p1 < st->l2.window) && !test_bit(FLG_PEER_BUSY, &st->l2.flag));
}
-inline void
+static inline void
clear_exception(struct Layer2 *l2)
{
test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
@@ -178,7 +178,7 @@ clear_exception(struct Layer2 *l2)
clear_peer_busy(l2);
}
-inline int
+static inline int
l2headersize(struct Layer2 *l2, int ui)
{
return (((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) +
@@ -223,40 +223,31 @@ enqueue_super(struct PStack *st,
#define enqueue_ui(a, b) enqueue_super(a, b)
-inline int
+static inline int
IsUI(u_char * data)
{
return ((data[0] & 0xef) == UI);
}
-inline int
+static inline int
IsUA(u_char * data)
{
return ((data[0] & 0xef) == UA);
}
-inline int
+static inline int
IsDM(u_char * data)
{
return ((data[0] & 0xef) == DM);
}
-inline int
+static inline int
IsDISC(u_char * data)
{
return ((data[0] & 0xef) == DISC);
}
-inline int
-IsRR(u_char * data, struct PStack *st)
-{
- if (test_bit(FLG_MOD128, &st->l2.flag))
- return (data[0] == RR);
- else
- return ((data[0] & 0xf) == 1);
-}
-
-inline int
+static inline int
IsSFrame(u_char * data, struct PStack *st)
{
register u_char d = *data;
@@ -266,7 +257,7 @@ IsSFrame(u_char * data, struct PStack *st)
return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c));
}
-inline int
+static inline int
IsSABME(u_char * data, struct PStack *st)
{
u_char d = data[0] & ~0x10;
@@ -274,25 +265,25 @@ IsSABME(u_char * data, struct PStack *st)
return (test_bit(FLG_MOD128, &st->l2.flag) ? d == SABME : d == SABM);
}
-inline int
+static inline int
IsREJ(u_char * data, struct PStack *st)
{
return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == REJ : (data[0] & 0xf) == REJ);
}
-inline int
+static inline int
IsFRMR(u_char * data)
{
return ((data[0] & 0xef) == FRMR);
}
-inline int
+static inline int
IsRNR(u_char * data, struct PStack *st)
{
return (test_bit(FLG_MOD128, &st->l2.flag) ? data[0] == RNR : (data[0] & 0xf) == RNR);
}
-int
+static int
iframe_error(struct PStack *st, struct sk_buff *skb)
{
int i = l2addrsize(&st->l2) + (test_bit(FLG_MOD128, &st->l2.flag) ? 2 : 1);
@@ -315,7 +306,7 @@ iframe_error(struct PStack *st, struct sk_buff *skb)
return 0;
}
-int
+static int
super_error(struct PStack *st, struct sk_buff *skb)
{
if (skb->len != l2addrsize(&st->l2) +
@@ -325,7 +316,7 @@ super_error(struct PStack *st, struct sk_buff *skb)
return 0;
}
-int
+static int
unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp)
{
int rsp = (*skb->data & 0x2) >> 1;
@@ -341,7 +332,7 @@ unnum_error(struct PStack *st, struct sk_buff *skb, int wantrsp)
return 0;
}
-int
+static int
UI_error(struct PStack *st, struct sk_buff *skb)
{
int rsp = *skb->data & 0x2;
@@ -357,7 +348,7 @@ UI_error(struct PStack *st, struct sk_buff *skb)
return 0;
}
-int
+static int
FRMR_error(struct PStack *st, struct sk_buff *skb)
{
int headers = l2addrsize(&st->l2) + 1;
@@ -444,51 +435,44 @@ send_uframe(struct PStack *st, u_char cmd, u_char cr)
enqueue_super(st, skb);
}
-inline u_char
+static inline u_char
get_PollFlag(struct PStack * st, struct sk_buff * skb)
{
return (skb->data[l2addrsize(&(st->l2))] & 0x10);
}
-inline void
-FreeSkb(struct sk_buff *skb)
-{
- dev_kfree_skb(skb);
-}
-
-
-inline u_char
+static inline u_char
get_PollFlagFree(struct PStack *st, struct sk_buff *skb)
{
u_char PF;
PF = get_PollFlag(st, skb);
- FreeSkb(skb);
+ dev_kfree_skb(skb);
return (PF);
}
-inline void
+static inline void
start_t200(struct PStack *st, int i)
{
FsmAddTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i);
test_and_set_bit(FLG_T200_RUN, &st->l2.flag);
}
-inline void
+static inline void
restart_t200(struct PStack *st, int i)
{
FsmRestartTimer(&st->l2.t200, st->l2.T200, EV_L2_T200, NULL, i);
test_and_set_bit(FLG_T200_RUN, &st->l2.flag);
}
-inline void
+static inline void
stop_t200(struct PStack *st, int i)
{
if(test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))
FsmDelTimer(&st->l2.t200, i);
}
-inline void
+static inline void
st5_dl_release_l2l3(struct PStack *st)
{
int pr;
@@ -501,7 +485,7 @@ st5_dl_release_l2l3(struct PStack *st)
st->l2.l2l3(st, pr, NULL);
}
-inline void
+static inline void
lapb_dl_release_l2l3(struct PStack *st, int f)
{
if (test_bit(FLG_LAPB, &st->l2.flag))
@@ -802,7 +786,7 @@ l2_connected(struct FsmInst *fi, int event, void *arg)
l2_mdl_error_ua(fi, event, arg);
return;
}
- FreeSkb(skb);
+ dev_kfree_skb(skb);
if (test_and_clear_bit(FLG_PEND_REL, &st->l2.flag))
l2_disconnect(fi, event, arg);
@@ -840,7 +824,7 @@ l2_released(struct FsmInst *fi, int event, void *arg)
l2_mdl_error_ua(fi, event, arg);
return;
}
- FreeSkb(skb);
+ dev_kfree_skb(skb);
stop_t200(st, 6);
lapb_dl_release_l2l3(st, CONFIRM);
@@ -889,7 +873,7 @@ l2_st6_dm_release(struct FsmInst *fi, int event, void *arg)
}
}
-inline void
+static inline void
enquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf)
{
struct sk_buff *skb;
@@ -912,7 +896,7 @@ enquiry_cr(struct PStack *st, u_char typ, u_char cr, u_char pf)
enqueue_super(st, skb);
}
-inline void
+static inline void
enquiry_response(struct PStack *st)
{
if (test_bit(FLG_OWN_BUSY, &st->l2.flag))
@@ -922,7 +906,7 @@ enquiry_response(struct PStack *st)
test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
}
-inline void
+static inline void
transmit_enquiry(struct PStack *st)
{
if (test_bit(FLG_OWN_BUSY, &st->l2.flag))
@@ -1004,7 +988,7 @@ l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
PollFlag = (skb->data[0] & 0x10);
nr = (skb->data[0] >> 5) & 0x7;
}
- FreeSkb(skb);
+ dev_kfree_skb(skb);
if (PollFlag) {
if (rsp)
@@ -1047,7 +1031,7 @@ l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg)
if (!test_bit(FLG_L3_INIT, &st->l2.flag))
skb_queue_tail(&st->l2.i_queue, skb);
else
- FreeSkb(skb);
+ dev_kfree_skb(skb);
}
static void
@@ -1093,7 +1077,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
nr = (skb->data[i] >> 5) & 0x7;
}
if (test_bit(FLG_OWN_BUSY, &l2->flag)) {
- FreeSkb(skb);
+ dev_kfree_skb(skb);
if(PollFlag) enquiry_response(st);
} else if (l2->vr == ns) {
(l2->vr)++;
@@ -1111,7 +1095,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
st->l2.l2l3(st, DL_DATA | INDICATION, skb);
} else {
/* n(s)!=v(r) */
- FreeSkb(skb);
+ dev_kfree_skb(skb);
if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {
if (PollFlag)
enquiry_response(st);
@@ -1309,7 +1293,7 @@ l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
skb = alloc_skb(oskb->len + i, GFP_ATOMIC);
memcpy(skb_put(skb, i), header, i);
memcpy(skb_put(skb, oskb->len), oskb->data, oskb->len);
- FreeSkb(oskb);
+ dev_kfree_skb(oskb);
}
st->l2.l2l1(st, PH_PULL | INDICATION, skb);
test_and_clear_bit(FLG_ACK_PEND, &st->l2.flag);
@@ -1349,7 +1333,7 @@ l2_st8_got_super(struct FsmInst *fi, int event, void *arg)
PollFlag = (skb->data[0] & 0x10);
nr = (skb->data[0] >> 5) & 0x7;
}
- FreeSkb(skb);
+ dev_kfree_skb(skb);
if (rsp && PollFlag) {
if (legalnr(st, nr)) {
@@ -1391,7 +1375,7 @@ l2_got_FRMR(struct FsmInst *fi, int event, void *arg)
establishlink(fi);
test_and_clear_bit(FLG_L3_INIT, &st->l2.flag);
}
- FreeSkb(skb);
+ dev_kfree_skb(skb);
}
static void
@@ -1655,7 +1639,7 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg)
datap += len;
else {
FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'N');
- FreeSkb(skb);
+ dev_kfree_skb(skb);
return;
}
if (!(*datap & 1)) { /* I-Frame */
@@ -1684,16 +1668,16 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg)
ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb);
} else {
FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *) 'L');
- FreeSkb(skb);
+ dev_kfree_skb(skb);
ret = 0;
}
if(c) {
- FreeSkb(skb);
+ dev_kfree_skb(skb);
FsmEvent(&st->l2.l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
ret = 0;
}
if (ret)
- FreeSkb(skb);
+ dev_kfree_skb(skb);
break;
case (PH_PULL | CONFIRM):
FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg);
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
index f571b5d18e9..abcc9530eb3 100644
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -390,7 +390,7 @@ setstack_l3dc(struct PStack *st, struct Channel *chanp)
}
}
-void
+static void
isdnl3_trans(struct PStack *st, int pr, void *arg) {
st->l3.l3l2(st, pr, arg);
}
diff --git a/drivers/isdn/hisax/isurf.c b/drivers/isdn/hisax/isurf.c
index af5171da734..33747afc984 100644
--- a/drivers/isdn/hisax/isurf.c
+++ b/drivers/isdn/hisax/isurf.c
@@ -122,7 +122,7 @@ isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_isurf(struct IsdnCardState *cs)
{
release_region(cs->hw.isurf.reset, 1);
diff --git a/drivers/isdn/hisax/ix1_micro.c b/drivers/isdn/hisax/ix1_micro.c
index b843b7509ae..908a7e14442 100644
--- a/drivers/isdn/hisax/ix1_micro.c
+++ b/drivers/isdn/hisax/ix1_micro.c
@@ -25,7 +25,7 @@
#include "isdnl1.h"
extern const char *CardType[];
-const char *ix1_revision = "$Revision: 2.12.2.4 $";
+static const char *ix1_revision = "$Revision: 2.12.2.4 $";
#define byteout(addr,val) outb(val,addr)
#define bytein(addr) inb(addr)
@@ -162,7 +162,7 @@ ix1micro_interrupt(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_ix1micro(struct IsdnCardState *cs)
{
if (cs->hw.ix1.cfg_reg)
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index f05d5275755..363ae3179bb 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -74,7 +74,7 @@ jade_write_indirect(struct IsdnCardState *cs, u_char reg, u_char value)
-void
+static void
modejade(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
@@ -190,7 +190,7 @@ jade_l2l1(struct PStack *st, int pr, void *arg)
}
}
-void
+static void
close_jadestate(struct BCState *bcs)
{
modejade(bcs, 0, bcs->channel);
@@ -243,7 +243,7 @@ open_jadestate(struct IsdnCardState *cs, struct BCState *bcs)
}
-int
+static int
setstack_jade(struct PStack *st, struct BCState *bcs)
{
bcs->channel = st->l1.bc;
diff --git a/drivers/isdn/hisax/jade.h b/drivers/isdn/hisax/jade.h
index fa294448599..29055e1ee38 100644
--- a/drivers/isdn/hisax/jade.h
+++ b/drivers/isdn/hisax/jade.h
@@ -128,7 +128,6 @@
#define jade_TXAUDIOCH2CFG 0x1A
extern int JadeVersion(struct IsdnCardState *cs, char *s);
-extern void modejade(struct BCState *bcs, int mode, int bc);
extern void clear_pending_jade_ints(struct IsdnCardState *cs);
extern void initjade(struct IsdnCardState *cs);
diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c
index d6c1c8f8329..c5c36eeff26 100644
--- a/drivers/isdn/hisax/l3_1tr6.c
+++ b/drivers/isdn/hisax/l3_1tr6.c
@@ -19,7 +19,7 @@
#include <linux/ctype.h>
extern char *HiSax_getrev(const char *revision);
-const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $";
+static const char *l3_1tr6_revision = "$Revision: 2.15.2.3 $";
#define MsgHead(ptr, cref, mty, dis) \
*ptr++ = dis; \
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
index ec92308c1ef..a6d2abdb478 100644
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -26,7 +26,7 @@
#include <linux/config.h>
extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 2.32.2.3 $";
+static const char *dss1_revision = "$Revision: 2.32.2.3 $";
#define EXT_BEARER_CAPS 1
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
index 3ab3a54daac..f7041d5ba64 100644
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -24,7 +24,7 @@
#include <linux/ctype.h>
extern char *HiSax_getrev(const char *revision);
-const char *ni1_revision = "$Revision: 2.8.2.3 $";
+static const char *ni1_revision = "$Revision: 2.8.2.3 $";
#define EXT_BEARER_CAPS 1
@@ -2665,7 +2665,7 @@ static void l3ni1_spid_send( struct l3_process *pc, u_char pr, void *arg )
l3ni1_SendSpid( pc, pr, arg, 20 );
}
-void l3ni1_spid_epid( struct l3_process *pc, u_char pr, void *arg )
+static void l3ni1_spid_epid( struct l3_process *pc, u_char pr, void *arg )
{
struct sk_buff *skb = arg;
diff --git a/drivers/isdn/hisax/mic.c b/drivers/isdn/hisax/mic.c
index 3ac4484a488..fe11f226b28 100644
--- a/drivers/isdn/hisax/mic.c
+++ b/drivers/isdn/hisax/mic.c
@@ -18,7 +18,7 @@
extern const char *CardType[];
-const char *mic_revision = "$Revision: 1.12.2.4 $";
+static const char *mic_revision = "$Revision: 1.12.2.4 $";
#define byteout(addr,val) outb(val,addr)
#define bytein(addr) inb(addr)
@@ -157,7 +157,7 @@ mic_interrupt(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_mic(struct IsdnCardState *cs)
{
int bytecnt = 8;
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index fe61d26365d..94da03c30c5 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -25,8 +25,6 @@
#include <asm/io.h>
#include "netjet.h"
-const char *NETjet_revision = "$Revision: 1.29.2.4 $";
-
/* Interface functions */
u_char
@@ -66,7 +64,7 @@ NETjet_WriteICfifo(struct IsdnCardState *cs, u_char *data, int size)
outsb(cs->hw.njet.isac, data, size);
}
-void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
+static void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
{
u_int mask=0x000000ff, val = 0, *p=pos;
u_int i;
@@ -85,7 +83,7 @@ void fill_mem(struct BCState *bcs, u_int *pos, u_int cnt, int chan, u_char fill)
}
}
-void
+static void
mode_tiger(struct BCState *bcs, int mode, int bc)
{
struct IsdnCardState *cs = bcs->cs;
@@ -852,7 +850,7 @@ tiger_l2l1(struct PStack *st, int pr, void *arg)
}
-void
+static void
close_tigerstate(struct BCState *bcs)
{
mode_tiger(bcs, 0, bcs->channel);
@@ -900,7 +898,7 @@ open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs)
return (0);
}
-int
+static int
setstack_tiger(struct PStack *st, struct BCState *bcs)
{
bcs->channel = st->l1.bc;
@@ -966,7 +964,7 @@ inittiger(struct IsdnCardState *cs)
cs->bcs[1].BC_Close = close_tigerstate;
}
-void
+static void
releasetiger(struct IsdnCardState *cs)
{
if (cs->bcs[0].hw.tiger.send) {
diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c
index cf77d836097..68a2159cbd1 100644
--- a/drivers/isdn/hisax/niccy.c
+++ b/drivers/isdn/hisax/niccy.c
@@ -24,7 +24,7 @@
#include <linux/isapnp.h>
extern const char *CardType[];
-const char *niccy_revision = "$Revision: 1.21.2.4 $";
+static const char *niccy_revision = "$Revision: 1.21.2.4 $";
#define byteout(addr,val) outb(val,addr)
#define bytein(addr) inb(addr)
@@ -178,7 +178,7 @@ niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_niccy(struct IsdnCardState *cs)
{
if (cs->subtyp == NICCY_PCI) {
diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c
index fd664697f82..a7d3cd3f36f 100644
--- a/drivers/isdn/hisax/nj_s.c
+++ b/drivers/isdn/hisax/nj_s.c
@@ -15,7 +15,7 @@
#include <linux/ppp_defs.h>
#include "netjet.h"
-const char *NETjet_S_revision = "$Revision: 2.13.2.4 $";
+static const char *NETjet_S_revision = "$Revision: 2.13.2.4 $";
static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
{
diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c
index 3d6441e9633..1ae7cac98a8 100644
--- a/drivers/isdn/hisax/nj_u.c
+++ b/drivers/isdn/hisax/nj_u.c
@@ -15,7 +15,7 @@
#include <linux/ppp_defs.h>
#include "netjet.h"
-const char *NETjet_U_revision = "$Revision: 2.14.2.3 $";
+static const char *NETjet_U_revision = "$Revision: 2.14.2.3 $";
static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
{
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c
index 170fcd4a398..abecabf8c27 100644
--- a/drivers/isdn/hisax/q931.c
+++ b/drivers/isdn/hisax/q931.c
@@ -516,7 +516,7 @@ struct MessageType cause_1tr6[] =
{CAUSE_UserInfoDiscarded, "User Info Discarded"}
};
-int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
+static int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType));
static int
prcause_1tr6(char *dest, u_char * p)
@@ -935,7 +935,7 @@ display(char *dest, u_char * p)
return (dp - dest);
}
-int
+static int
prfacility(char *dest, u_char * p)
{
char *dp = dest;
diff --git a/drivers/isdn/hisax/s0box.c b/drivers/isdn/hisax/s0box.c
index f3c481384a4..7b63085ea6e 100644
--- a/drivers/isdn/hisax/s0box.c
+++ b/drivers/isdn/hisax/s0box.c
@@ -17,7 +17,7 @@
#include "isdnl1.h"
extern const char *CardType[];
-const char *s0box_revision = "$Revision: 2.6.2.4 $";
+static const char *s0box_revision = "$Revision: 2.6.2.4 $";
static inline void
writereg(unsigned int padr, signed int addr, u_char off, u_char val) {
@@ -183,7 +183,7 @@ s0box_interrupt(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_s0box(struct IsdnCardState *cs)
{
release_region(cs->hw.teles3.cfg_reg, 8);
diff --git a/drivers/isdn/hisax/saphir.c b/drivers/isdn/hisax/saphir.c
index 9e6d3d686cc..821776e1561 100644
--- a/drivers/isdn/hisax/saphir.c
+++ b/drivers/isdn/hisax/saphir.c
@@ -171,7 +171,7 @@ SaphirWatchDog(struct IsdnCardState *cs)
mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
}
-void
+static void
release_io_saphir(struct IsdnCardState *cs)
{
byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff);
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c
index 8390f160685..8c044a6a7fe 100644
--- a/drivers/isdn/hisax/sedlbauer.c
+++ b/drivers/isdn/hisax/sedlbauer.c
@@ -51,9 +51,9 @@
extern const char *CardType[];
-const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
+static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
-const char *Sedlbauer_Types[] =
+static const char *Sedlbauer_Types[] =
{"None", "speed card/win", "speed star", "speed fax+",
"speed win II / ISDN PC/104", "speed star II", "speed pci",
"speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"};
@@ -394,7 +394,7 @@ sedlbauer_interrupt_isar(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_sedlbauer(struct IsdnCardState *cs)
{
int bytecnt = 8;
diff --git a/drivers/isdn/hisax/sportster.c b/drivers/isdn/hisax/sportster.c
index 132840b750c..cdf35dc564c 100644
--- a/drivers/isdn/hisax/sportster.c
+++ b/drivers/isdn/hisax/sportster.c
@@ -19,7 +19,7 @@
#include "isdnl1.h"
extern const char *CardType[];
-const char *sportster_revision = "$Revision: 1.16.2.4 $";
+static const char *sportster_revision = "$Revision: 1.16.2.4 $";
#define byteout(addr,val) outb(val,addr)
#define bytein(addr) inb(addr)
@@ -132,7 +132,7 @@ sportster_interrupt(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_sportster(struct IsdnCardState *cs)
{
int i, adr;
@@ -144,7 +144,7 @@ release_io_sportster(struct IsdnCardState *cs)
}
}
-void
+static void
reset_sportster(struct IsdnCardState *cs)
{
cs->hw.spt.res_irq |= SPORTSTER_RESET; /* Reset On */
diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h
index e8177b017b1..0fda5c89429 100644
--- a/drivers/isdn/hisax/st5481.h
+++ b/drivers/isdn/hisax/st5481.h
@@ -450,12 +450,8 @@ int st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
usb_complete_t complete, void *context);
void st5481_release_isocpipes(struct urb* urb[2]);
-int st5481_isoc_flatten(struct urb *urb);
void st5481_usb_pipe_reset(struct st5481_adapter *adapter,
u_char pipe, ctrl_complete_t complete, void *context);
-void st5481_usb_ctrl_msg(struct st5481_adapter *adapter,
- u8 request, u8 requesttype, u16 value, u16 index,
- ctrl_complete_t complete, void *context);
void st5481_usb_device_ctrl_msg(struct st5481_adapter *adapter,
u8 request, u16 value,
ctrl_complete_t complete, void *context);
diff --git a/drivers/isdn/hisax/st5481_hdlc.c b/drivers/isdn/hisax/st5481_hdlc.c
deleted file mode 100644
index 680f42e9a99..00000000000
--- a/drivers/isdn/hisax/st5481_hdlc.c
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Driver for ST5481 USB ISDN modem
- *
- * Author Frode Isaksen
- * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com>
- * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/crc-ccitt.h>
-#include "st5481_hdlc.h"
-
-
-enum {
- HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
- HDLC_GET_DATA,HDLC_FAST_FLAG
-};
-
-enum {
- HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG,
- HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG,
- HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0,
- HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED
-};
-
-void
-hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56)
-{
- hdlc->bit_shift = 0;
- hdlc->hdlc_bits1 = 0;
- hdlc->data_bits = 0;
- hdlc->ffbit_shift = 0;
- hdlc->data_received = 0;
- hdlc->state = HDLC_GET_DATA;
- hdlc->do_adapt56 = do_adapt56;
- hdlc->dchannel = 0;
- hdlc->crc = 0;
- hdlc->cbin = 0;
- hdlc->shift_reg = 0;
- hdlc->ffvalue = 0;
- hdlc->dstpos = 0;
-}
-
-void
-hdlc_out_init(struct hdlc_vars *hdlc, int is_d_channel, int do_adapt56)
-{
- hdlc->bit_shift = 0;
- hdlc->hdlc_bits1 = 0;
- hdlc->data_bits = 0;
- hdlc->ffbit_shift = 0;
- hdlc->data_received = 0;
- hdlc->do_closing = 0;
- hdlc->ffvalue = 0;
- if (is_d_channel) {
- hdlc->dchannel = 1;
- hdlc->state = HDLC_SEND_FIRST_FLAG;
- } else {
- hdlc->dchannel = 0;
- hdlc->state = HDLC_SEND_FAST_FLAG;
- hdlc->ffvalue = 0x7e;
- }
- hdlc->cbin = 0x7e;
- hdlc->bit_shift = 0;
- if(do_adapt56){
- hdlc->do_adapt56 = 1;
- hdlc->data_bits = 0;
- hdlc->state = HDLC_SENDFLAG_B0;
- } else {
- hdlc->do_adapt56 = 0;
- hdlc->data_bits = 8;
- }
- hdlc->shift_reg = 0;
-}
-
-/*
- hdlc_decode - decodes HDLC frames from a transparent bit stream.
-
- The source buffer is scanned for valid HDLC frames looking for
- flags (01111110) to indicate the start of a frame. If the start of
- the frame is found, the bit stuffing is removed (0 after 5 1's).
- When a new flag is found, the complete frame has been received
- and the CRC is checked.
- If a valid frame is found, the function returns the frame length
- excluding the CRC with the bit HDLC_END_OF_FRAME set.
- If the beginning of a valid frame is found, the function returns
- the length.
- If a framing error is found (too many 1s and not a flag) the function
- returns the length with the bit HDLC_FRAMING_ERROR set.
- If a CRC error is found the function returns the length with the
- bit HDLC_CRC_ERROR set.
- If the frame length exceeds the destination buffer size, the function
- returns the length with the bit HDLC_LENGTH_ERROR set.
-
- src - source buffer
- slen - source buffer length
- count - number of bytes removed (decoded) from the source buffer
- dst _ destination buffer
- dsize - destination buffer size
- returns - number of decoded bytes in the destination buffer and status
- flag.
- */
-int hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src,
- int slen, int *count, unsigned char *dst, int dsize)
-{
- int status=0;
-
- static const unsigned char fast_flag[]={
- 0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
- };
-
- static const unsigned char fast_flag_value[]={
- 0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
- };
-
- static const unsigned char fast_abort[]={
- 0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
- };
-
- *count = slen;
-
- while(slen > 0){
- if(hdlc->bit_shift==0){
- hdlc->cbin = *src++;
- slen--;
- hdlc->bit_shift = 8;
- if(hdlc->do_adapt56){
- hdlc->bit_shift --;
- }
- }
-
- switch(hdlc->state){
- case STOPPED:
- return 0;
- case HDLC_FAST_IDLE:
- if(hdlc->cbin == 0xff){
- hdlc->bit_shift = 0;
- break;
- }
- hdlc->state = HDLC_GET_FLAG_B0;
- hdlc->hdlc_bits1 = 0;
- hdlc->bit_shift = 8;
- break;
- case HDLC_GET_FLAG_B0:
- if(!(hdlc->cbin & 0x80)) {
- hdlc->state = HDLC_GETFLAG_B1A6;
- hdlc->hdlc_bits1 = 0;
- } else {
- if(!hdlc->do_adapt56){
- if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
- hdlc->state = HDLC_FAST_IDLE;
- }
- }
- hdlc->cbin<<=1;
- hdlc->bit_shift --;
- break;
- case HDLC_GETFLAG_B1A6:
- if(hdlc->cbin & 0x80){
- hdlc->hdlc_bits1++;
- if(hdlc->hdlc_bits1==6){
- hdlc->state = HDLC_GETFLAG_B7;
- }
- } else {
- hdlc->hdlc_bits1 = 0;
- }
- hdlc->cbin<<=1;
- hdlc->bit_shift --;
- break;
- case HDLC_GETFLAG_B7:
- if(hdlc->cbin & 0x80) {
- hdlc->state = HDLC_GET_FLAG_B0;
- } else {
- hdlc->state = HDLC_GET_DATA;
- hdlc->crc = 0xffff;
- hdlc->shift_reg = 0;
- hdlc->hdlc_bits1 = 0;
- hdlc->data_bits = 0;
- hdlc->data_received = 0;
- }
- hdlc->cbin<<=1;
- hdlc->bit_shift --;
- break;
- case HDLC_GET_DATA:
- if(hdlc->cbin & 0x80){
- hdlc->hdlc_bits1++;
- switch(hdlc->hdlc_bits1){
- case 6:
- break;
- case 7:
- if(hdlc->data_received) {
- // bad frame
- status = -HDLC_FRAMING_ERROR;
- }
- if(!hdlc->do_adapt56){
- if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
- hdlc->state = HDLC_FAST_IDLE;
- hdlc->bit_shift=1;
- break;
- }
- } else {
- hdlc->state = HDLC_GET_FLAG_B0;
- }
- break;
- default:
- hdlc->shift_reg>>=1;
- hdlc->shift_reg |= 0x80;
- hdlc->data_bits++;
- break;
- }
- } else {
- switch(hdlc->hdlc_bits1){
- case 5:
- break;
- case 6:
- if(hdlc->data_received){
- if (hdlc->dstpos < 2) {
- status = -HDLC_FRAMING_ERROR;
- } else if (hdlc->crc != 0xf0b8){
- // crc error
- status = -HDLC_CRC_ERROR;
- } else {
- // remove CRC
- hdlc->dstpos -= 2;
- // good frame
- status = hdlc->dstpos;
- }
- }
- hdlc->crc = 0xffff;
- hdlc->shift_reg = 0;
- hdlc->data_bits = 0;
- if(!hdlc->do_adapt56){
- if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
- hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
- hdlc->state = HDLC_FAST_FLAG;
- hdlc->ffbit_shift = hdlc->bit_shift;
- hdlc->bit_shift = 1;
- } else {
- hdlc->state = HDLC_GET_DATA;
- hdlc->data_received = 0;
- }
- } else {
- hdlc->state = HDLC_GET_DATA;
- hdlc->data_received = 0;
- }
- break;
- default:
- hdlc->shift_reg>>=1;
- hdlc->data_bits++;
- break;
- }
- hdlc->hdlc_bits1 = 0;
- }
- if (status) {
- hdlc->dstpos = 0;
- *count -= slen;
- hdlc->cbin <<= 1;
- hdlc->bit_shift--;
- return status;
- }
- if(hdlc->data_bits==8){
- hdlc->data_bits = 0;
- hdlc->data_received = 1;
- hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
-
- // good byte received
- if (dsize--) {
- dst[hdlc->dstpos++] = hdlc->shift_reg;
- } else {
- // frame too long
- status = -HDLC_LENGTH_ERROR;
- hdlc->dstpos = 0;
- }
- }
- hdlc->cbin <<= 1;
- hdlc->bit_shift--;
- break;
- case HDLC_FAST_FLAG:
- if(hdlc->cbin==hdlc->ffvalue){
- hdlc->bit_shift = 0;
- break;
- } else {
- if(hdlc->cbin == 0xff){
- hdlc->state = HDLC_FAST_IDLE;
- hdlc->bit_shift=0;
- } else if(hdlc->ffbit_shift==8){
- hdlc->state = HDLC_GETFLAG_B7;
- break;
- } else {
- hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
- hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
- if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
- hdlc->data_bits = hdlc->ffbit_shift-1;
- hdlc->state = HDLC_GET_DATA;
- hdlc->data_received = 0;
- }
- }
- break;
- default:
- break;
- }
- }
- *count -= slen;
- return 0;
-}
-
-/*
- hdlc_encode - encodes HDLC frames to a transparent bit stream.
-
- The bit stream starts with a beginning flag (01111110). After
- that each byte is added to the bit stream with bit stuffing added
- (0 after 5 1's).
- When the last byte has been removed from the source buffer, the
- CRC (2 bytes is added) and the frame terminates with the ending flag.
- For the dchannel, the idle character (all 1's) is also added at the end.
- If this function is called with empty source buffer (slen=0), flags or
- idle character will be generated.
-
- src - source buffer
- slen - source buffer length
- count - number of bytes removed (encoded) from source buffer
- dst _ destination buffer
- dsize - destination buffer size
- returns - number of encoded bytes in the destination buffer
-*/
-int hdlc_encode(struct hdlc_vars *hdlc, const unsigned char *src,
- unsigned short slen, int *count,
- unsigned char *dst, int dsize)
-{
- static const unsigned char xfast_flag_value[] = {
- 0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
- };
-
- int len = 0;
-
- *count = slen;
-
- while (dsize > 0) {
- if(hdlc->bit_shift==0){
- if(slen && !hdlc->do_closing){
- hdlc->shift_reg = *src++;
- slen--;
- if (slen == 0)
- hdlc->do_closing = 1; /* closing sequence, CRC + flag(s) */
- hdlc->bit_shift = 8;
- } else {
- if(hdlc->state == HDLC_SEND_DATA){
- if(hdlc->data_received){
- hdlc->state = HDLC_SEND_CRC1;
- hdlc->crc ^= 0xffff;
- hdlc->bit_shift = 8;
- hdlc->shift_reg = hdlc->crc & 0xff;
- } else if(!hdlc->do_adapt56){
- hdlc->state = HDLC_SEND_FAST_FLAG;
- } else {
- hdlc->state = HDLC_SENDFLAG_B0;
- }
- }
-
- }
- }
-
- switch(hdlc->state){
- case STOPPED:
- while (dsize--)
- *dst++ = 0xff;
-
- return dsize;
- case HDLC_SEND_FAST_FLAG:
- hdlc->do_closing = 0;
- if(slen == 0){
- *dst++ = hdlc->ffvalue;
- len++;
- dsize--;
- break;
- }
- if(hdlc->bit_shift==8){
- hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
- hdlc->state = HDLC_SEND_DATA;
- hdlc->crc = 0xffff;
- hdlc->hdlc_bits1 = 0;
- hdlc->data_received = 1;
- }
- break;
- case HDLC_SENDFLAG_B0:
- hdlc->do_closing = 0;
- hdlc->cbin <<= 1;
- hdlc->data_bits++;
- hdlc->hdlc_bits1 = 0;
- hdlc->state = HDLC_SENDFLAG_B1A6;
- break;
- case HDLC_SENDFLAG_B1A6:
- hdlc->cbin <<= 1;
- hdlc->data_bits++;
- hdlc->cbin++;
- if(++hdlc->hdlc_bits1 == 6)
- hdlc->state = HDLC_SENDFLAG_B7;
- break;
- case HDLC_SENDFLAG_B7:
- hdlc->cbin <<= 1;
- hdlc->data_bits++;
- if(slen == 0){
- hdlc->state = HDLC_SENDFLAG_B0;
- break;
- }
- if(hdlc->bit_shift==8){
- hdlc->state = HDLC_SEND_DATA;
- hdlc->crc = 0xffff;
- hdlc->hdlc_bits1 = 0;
- hdlc->data_received = 1;
- }
- break;
- case HDLC_SEND_FIRST_FLAG:
- hdlc->data_received = 1;
- if(hdlc->data_bits==8){
- hdlc->state = HDLC_SEND_DATA;
- hdlc->crc = 0xffff;
- hdlc->hdlc_bits1 = 0;
- break;
- }
- hdlc->cbin <<= 1;
- hdlc->data_bits++;
- if(hdlc->shift_reg & 0x01)
- hdlc->cbin++;
- hdlc->shift_reg >>= 1;
- hdlc->bit_shift--;
- if(hdlc->bit_shift==0){
- hdlc->state = HDLC_SEND_DATA;
- hdlc->crc = 0xffff;
- hdlc->hdlc_bits1 = 0;
- }
- break;
- case HDLC_SEND_DATA:
- hdlc->cbin <<= 1;
- hdlc->data_bits++;
- if(hdlc->hdlc_bits1 == 5){
- hdlc->hdlc_bits1 = 0;
- break;
- }
- if(hdlc->bit_shift==8){
- hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg);
- }
- if(hdlc->shift_reg & 0x01){
- hdlc->hdlc_bits1++;
- hdlc->cbin++;
- hdlc->shift_reg >>= 1;
- hdlc->bit_shift--;
- } else {
- hdlc->hdlc_bits1 = 0;
- hdlc->shift_reg >>= 1;
- hdlc->bit_shift--;
- }
- break;
- case HDLC_SEND_CRC1:
- hdlc->cbin <<= 1;
- hdlc->data_bits++;
- if(hdlc->hdlc_bits1 == 5){
- hdlc->hdlc_bits1 = 0;
- break;
- }
- if(hdlc->shift_reg & 0x01){
- hdlc->hdlc_bits1++;
- hdlc->cbin++;
- hdlc->shift_reg >>= 1;
- hdlc->bit_shift--;
- } else {
- hdlc->hdlc_bits1 = 0;
- hdlc->shift_reg >>= 1;
- hdlc->bit_shift--;
- }
- if(hdlc->bit_shift==0){
- hdlc->shift_reg = (hdlc->crc >> 8);
- hdlc->state = HDLC_SEND_CRC2;
- hdlc->bit_shift = 8;
- }
- break;
- case HDLC_SEND_CRC2:
- hdlc->cbin <<= 1;
- hdlc->data_bits++;
- if(hdlc->hdlc_bits1 == 5){
- hdlc->hdlc_bits1 = 0;
- break;
- }
- if(hdlc->shift_reg & 0x01){
- hdlc->hdlc_bits1++;
- hdlc->cbin++;
- hdlc->shift_reg >>= 1;
- hdlc->bit_shift--;
- } else {
- hdlc->hdlc_bits1 = 0;
- hdlc->shift_reg >>= 1;
- hdlc->bit_shift--;
- }
- if(hdlc->bit_shift==0){
- hdlc->shift_reg = 0x7e;
- hdlc->state = HDLC_SEND_CLOSING_FLAG;
- hdlc->bit_shift = 8;
- }
- break;
- case HDLC_SEND_CLOSING_FLAG:
- hdlc->cbin <<= 1;
- hdlc->data_bits++;
- if(hdlc->hdlc_bits1 == 5){
- hdlc->hdlc_bits1 = 0;
- break;
- }
- if(hdlc->shift_reg & 0x01){
- hdlc->cbin++;
- }
- hdlc->shift_reg >>= 1;
- hdlc->bit_shift--;
- if(hdlc->bit_shift==0){
- hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
- if(hdlc->dchannel){
- hdlc->ffvalue = 0x7e;
- hdlc->state = HDLC_SEND_IDLE1;
- hdlc->bit_shift = 8-hdlc->data_bits;
- if(hdlc->bit_shift==0)
- hdlc->state = HDLC_SEND_FAST_IDLE;
- } else {
- if(!hdlc->do_adapt56){
- hdlc->state = HDLC_SEND_FAST_FLAG;
- hdlc->data_received = 0;
- } else {
- hdlc->state = HDLC_SENDFLAG_B0;
- hdlc->data_received = 0;
- }
- // Finished with this frame, send flags
- if (dsize > 1) dsize = 1;
- }
- }
- break;
- case HDLC_SEND_IDLE1:
- hdlc->do_closing = 0;
- hdlc->cbin <<= 1;
- hdlc->cbin++;
- hdlc->data_bits++;
- hdlc->bit_shift--;
- if(hdlc->bit_shift==0){
- hdlc->state = HDLC_SEND_FAST_IDLE;
- hdlc->bit_shift = 0;
- }
- break;
- case HDLC_SEND_FAST_IDLE:
- hdlc->do_closing = 0;
- hdlc->cbin = 0xff;
- hdlc->data_bits = 8;
- if(hdlc->bit_shift == 8){
- hdlc->cbin = 0x7e;
- hdlc->state = HDLC_SEND_FIRST_FLAG;
- } else {
- *dst++ = hdlc->cbin;
- hdlc->bit_shift = hdlc->data_bits = 0;
- len++;
- dsize = 0;
- }
- break;
- default:
- break;
- }
- if(hdlc->do_adapt56){
- if(hdlc->data_bits==7){
- hdlc->cbin <<= 1;
- hdlc->cbin++;
- hdlc->data_bits++;
- }
- }
- if(hdlc->data_bits==8){
- *dst++ = hdlc->cbin;
- hdlc->data_bits = 0;
- len++;
- dsize--;
- }
- }
- *count -= slen;
-
- return len;
-}
-
diff --git a/drivers/isdn/hisax/st5481_hdlc.h b/drivers/isdn/hisax/st5481_hdlc.h
deleted file mode 100644
index 495432f0f6b..00000000000
--- a/drivers/isdn/hisax/st5481_hdlc.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Driver for ST5481 USB ISDN modem
- *
- * Author Frode Isaksen
- * Copyright 2001 by Frode Isaksen <fisaksen@bewan.com>
- * 2001 by Kai Germaschewski <kai.germaschewski@gmx.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#ifndef __ST5481_HDLC_H__
-#define __ST5481_HDLC_H__
-
-struct hdlc_vars {
- int bit_shift;
- int hdlc_bits1;
- int data_bits;
- int ffbit_shift; // encoding only
- int state;
- int dstpos;
-
- int data_received:1; // set if transferring data
- int dchannel:1; // set if D channel (send idle instead of flags)
- int do_adapt56:1; // set if 56K adaptation
- int do_closing:1; // set if in closing phase (need to send CRC + flag
-
- unsigned short crc;
-
- unsigned char cbin;
- unsigned char shift_reg;
- unsigned char ffvalue;
-
-};
-
-
-/*
- The return value from hdlc_decode is
- the frame length, 0 if no complete frame was decoded,
- or a negative error number
-*/
-
-#define HDLC_FRAMING_ERROR 1
-#define HDLC_CRC_ERROR 2
-#define HDLC_LENGTH_ERROR 3
-
-void
-hdlc_rcv_init(struct hdlc_vars *hdlc, int do_adapt56);
-
-int
-hdlc_decode(struct hdlc_vars *hdlc, const unsigned char *src, int slen,int *count,
- unsigned char *dst, int dsize);
-
-void
-hdlc_out_init(struct hdlc_vars *hdlc,int is_d_channel,int do_adapt56);
-
-int
-hdlc_encode(struct hdlc_vars *hdlc,const unsigned char *src,unsigned short slen,int *count,
- unsigned char *dst,int dsize);
-
-#endif
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index 2369180b1cb..ab62223297a 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -15,6 +15,8 @@
#include <linux/slab.h>
#include "st5481.h"
+static int st5481_isoc_flatten(struct urb *urb);
+
/* ======================================================================
* control pipe
*/
@@ -55,9 +57,9 @@ static void usb_next_ctrl_msg(struct urb *urb,
* Asynchronous endpoint 0 request (async version of usb_control_msg).
* The request will be queued up in a FIFO if the endpoint is busy.
*/
-void usb_ctrl_msg(struct st5481_adapter *adapter,
- u8 request, u8 requesttype, u16 value, u16 index,
- ctrl_complete_t complete, void *context)
+static void usb_ctrl_msg(struct st5481_adapter *adapter,
+ u8 request, u8 requesttype, u16 value, u16 index,
+ ctrl_complete_t complete, void *context)
{
struct st5481_ctrl *ctrl = &adapter->ctrl;
int w_index;
@@ -571,7 +573,7 @@ void st5481_release_in(struct st5481_in *in)
* Make the transfer_buffer contiguous by
* copying from the iso descriptors if necessary.
*/
-int st5481_isoc_flatten(struct urb *urb)
+static int st5481_isoc_flatten(struct urb *urb)
{
struct usb_iso_packet_descriptor *pipd,*pend;
unsigned char *src,*dst;
diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c
index 082726db398..ceb0df92fd3 100644
--- a/drivers/isdn/hisax/tei.c
+++ b/drivers/isdn/hisax/tei.c
@@ -74,7 +74,7 @@ static char *strTeiEvent[] =
"EV_T202",
};
-unsigned int
+static unsigned int
random_ri(void)
{
unsigned int x;
diff --git a/drivers/isdn/hisax/teleint.c b/drivers/isdn/hisax/teleint.c
index ef8984c5f1f..a2b1816af37 100644
--- a/drivers/isdn/hisax/teleint.c
+++ b/drivers/isdn/hisax/teleint.c
@@ -18,7 +18,7 @@
extern const char *CardType[];
-const char *TeleInt_revision = "$Revision: 1.16.2.5 $";
+static const char *TeleInt_revision = "$Revision: 1.16.2.5 $";
#define byteout(addr,val) outb(val,addr)
#define bytein(addr) inb(addr)
@@ -203,7 +203,7 @@ TeleInt_Timer(struct IsdnCardState *cs)
add_timer(&cs->hw.hfc.timer);
}
-void
+static void
release_io_TeleInt(struct IsdnCardState *cs)
{
del_timer(&cs->hw.hfc.timer);
diff --git a/drivers/isdn/hisax/teles0.c b/drivers/isdn/hisax/teles0.c
index 5ec5ec3e1ea..2b7df8f9823 100644
--- a/drivers/isdn/hisax/teles0.c
+++ b/drivers/isdn/hisax/teles0.c
@@ -23,7 +23,7 @@
extern const char *CardType[];
-const char *teles0_revision = "$Revision: 2.15.2.4 $";
+static const char *teles0_revision = "$Revision: 2.15.2.4 $";
#define TELES_IOMEM_SIZE 0x400
#define byteout(addr,val) outb(val,addr)
@@ -183,7 +183,7 @@ teles0_interrupt(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_teles0(struct IsdnCardState *cs)
{
if (cs->hw.teles0.cfg_reg)
diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c
index c5b1f65f727..adeaad62d35 100644
--- a/drivers/isdn/hisax/teles3.c
+++ b/drivers/isdn/hisax/teles3.c
@@ -21,7 +21,7 @@
#include "isdnl1.h"
extern const char *CardType[];
-const char *teles3_revision = "$Revision: 2.19.2.4 $";
+static const char *teles3_revision = "$Revision: 2.19.2.4 $";
#define byteout(addr,val) outb(val,addr)
#define bytein(addr) inb(addr)
@@ -154,7 +154,7 @@ release_ioregs(struct IsdnCardState *cs, int mask)
release_region(cs->hw.teles3.hscx[1] + 32, 32);
}
-void
+static void
release_io_teles3(struct IsdnCardState *cs)
{
if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c
index 0661c6c31ad..e2bb4fd8e25 100644
--- a/drivers/isdn/hisax/telespci.c
+++ b/drivers/isdn/hisax/telespci.c
@@ -21,7 +21,7 @@
#include <linux/pci.h>
extern const char *CardType[];
-const char *telespci_revision = "$Revision: 2.23.2.3 $";
+static const char *telespci_revision = "$Revision: 2.23.2.3 $";
#define ZORAN_PO_RQ_PEN 0x02000000
#define ZORAN_PO_WR 0x00800000
@@ -257,7 +257,7 @@ telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-void
+static void
release_io_telespci(struct IsdnCardState *cs)
{
iounmap(cs->hw.teles0.membase);
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index d2b6b8e7298..7baf8e48847 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -41,7 +41,7 @@ static const PCI_ENTRY id_list[] =
extern const char *CardType[];
-const char *w6692_revision = "$Revision: 1.18.2.4 $";
+static const char *w6692_revision = "$Revision: 1.18.2.4 $";
#define DBUSY_TIMER_VALUE 80
@@ -880,7 +880,7 @@ setstack_w6692(struct PStack *st, struct BCState *bcs)
return (0);
}
-void resetW6692(struct IsdnCardState *cs)
+static void resetW6692(struct IsdnCardState *cs)
{
cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST);
mdelay(10);
@@ -902,7 +902,7 @@ void resetW6692(struct IsdnCardState *cs)
}
}
-void __init initW6692(struct IsdnCardState *cs, int part)
+static void __init initW6692(struct IsdnCardState *cs, int part)
{
if (part & 1) {
cs->setstack_d = setstack_W6692;
diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c
index 5350836a4f9..2cc56d6a9fa 100644
--- a/drivers/isdn/i4l/isdn_audio.c
+++ b/drivers/isdn/i4l/isdn_audio.c
@@ -392,16 +392,6 @@ isdn_audio_adpcm2xlaw(adpcm_state * s, int fmt, unsigned char *in,
}
int
-isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out)
-{
- int olen = 0;
-
- if (s->nleft)
- isdn_audio_put_bits(0, 8 - s->nleft, s, &out, &olen);
- return olen;
-}
-
-int
isdn_audio_xlaw2adpcm(adpcm_state * s, int fmt, unsigned char *in,
unsigned char *out, int len)
{
diff --git a/drivers/isdn/i4l/isdn_audio.h b/drivers/isdn/i4l/isdn_audio.h
index 5a977b21dcf..013c3582e0d 100644
--- a/drivers/isdn/i4l/isdn_audio.h
+++ b/drivers/isdn/i4l/isdn_audio.h
@@ -35,7 +35,6 @@ extern void isdn_audio_alaw2ulaw(unsigned char *, unsigned long);
extern adpcm_state *isdn_audio_adpcm_init(adpcm_state *, int);
extern int isdn_audio_adpcm2xlaw(adpcm_state *, int, unsigned char *, unsigned char *, int);
extern int isdn_audio_xlaw2adpcm(adpcm_state *, int, unsigned char *, unsigned char *, int);
-extern int isdn_audio_2adpcm_flush(adpcm_state * s, unsigned char *out);
extern void isdn_audio_calc_dtmf(modem_info *, unsigned char *, int, int);
extern void isdn_audio_eval_dtmf(modem_info *);
dtmf_state *isdn_audio_dtmf_init(dtmf_state *);
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index c406df6f268..eebcb0b97f0 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -67,7 +67,7 @@ static isdn_divert_if *divert_if; /* = NULL */
static int isdn_writebuf_stub(int, int, const u_char __user *, int);
static void set_global_features(void);
static int isdn_wildmat(char *s, char *p);
-
+static int isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding);
static inline void
isdn_lock_driver(isdn_driver_t *drv)
@@ -388,7 +388,7 @@ isdn_all_eaz(int di, int ch)
*/
#include <linux/isdn/capicmd.h>
-int
+static int
isdn_capi_rec_hl_msg(capi_msg *cm) {
int di;
@@ -1923,7 +1923,7 @@ isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
return ret;
}
-int
+static int
isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding)
{
int j, k, m;
diff --git a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h
index 808135c427a..e27e9c3a81e 100644
--- a/drivers/isdn/i4l/isdn_common.h
+++ b/drivers/isdn/i4l/isdn_common.h
@@ -41,7 +41,6 @@ extern int isdn_get_free_channel(int, int, int, int, int, char *);
extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
extern int register_isdn(isdn_if * i);
extern int isdn_msncmp( const char *, const char *);
-extern int isdn_add_channels(isdn_driver_t *, int, int, int);
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
extern void isdn_dumppkt(char *, u_char *, int, int);
#endif
diff --git a/drivers/isdn/i4l/isdn_concap.c b/drivers/isdn/i4l/isdn_concap.c
index 83a4f5382bc..0193b6f7c70 100644
--- a/drivers/isdn/i4l/isdn_concap.c
+++ b/drivers/isdn/i4l/isdn_concap.c
@@ -39,7 +39,7 @@
*/
-int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
+static int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
{
struct net_device *ndev = concap -> net_dev;
isdn_net_dev *nd = ((isdn_net_local *) ndev->priv)->netdev;
@@ -58,7 +58,7 @@ int isdn_concap_dl_data_req(struct concap_proto *concap, struct sk_buff *skb)
}
-int isdn_concap_dl_connect_req(struct concap_proto *concap)
+static int isdn_concap_dl_connect_req(struct concap_proto *concap)
{
struct net_device *ndev = concap -> net_dev;
isdn_net_local *lp = (isdn_net_local *) ndev->priv;
@@ -71,7 +71,7 @@ int isdn_concap_dl_connect_req(struct concap_proto *concap)
return ret;
}
-int isdn_concap_dl_disconn_req(struct concap_proto *concap)
+static int isdn_concap_dl_disconn_req(struct concap_proto *concap)
{
IX25DEBUG( "isdn_concap_dl_disconn_req: %s \n", concap -> net_dev -> name);
@@ -85,15 +85,6 @@ struct concap_device_ops isdn_concap_reliable_dl_dops = {
&isdn_concap_dl_disconn_req
};
-struct concap_device_ops isdn_concap_demand_dial_dops = {
- NULL, /* set this first entry to something like &isdn_net_start_xmit,
- but the entry part of the current isdn_net_start_xmit must be
- separated first. */
- /* no connection control for demand dial semantics */
- NULL,
- NULL,
-};
-
/* The following should better go into a dedicated source file such that
this sourcefile does not need to include any protocol specific header
files. For now:
diff --git a/drivers/isdn/i4l/isdn_concap.h b/drivers/isdn/i4l/isdn_concap.h
index 306eb180438..6ac7e0445ea 100644
--- a/drivers/isdn/i4l/isdn_concap.h
+++ b/drivers/isdn/i4l/isdn_concap.h
@@ -8,7 +8,6 @@
*/
extern struct concap_device_ops isdn_concap_reliable_dl_dops;
-extern struct concap_device_ops isdn_concap_demand_dial_dops;
extern struct concap_proto * isdn_concap_new( int );
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index e2b790e3451..f30e8e63ae0 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -176,7 +176,7 @@ static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
/* Prototypes */
-int isdn_net_force_dial_lp(isdn_net_local *);
+static int isdn_net_force_dial_lp(isdn_net_local *);
static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
@@ -312,7 +312,7 @@ isdn_net_unbind_channel(isdn_net_local * lp)
* Since this function is called every second, simply reset the
* byte-counter of the interface after copying it to the cps-variable.
*/
-unsigned long last_jiffies = -HZ;
+static unsigned long last_jiffies = -HZ;
void
isdn_net_autohup(void)
@@ -1131,7 +1131,7 @@ isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev)
}
-void isdn_net_tx_timeout(struct net_device * ndev)
+static void isdn_net_tx_timeout(struct net_device * ndev)
{
isdn_net_local *lp = (isdn_net_local *) ndev->priv;
@@ -1424,7 +1424,7 @@ isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len)
}
/* cisco hdlck device private ioctls */
-int
+static int
isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
isdn_net_local *lp = (isdn_net_local *) dev->priv;
@@ -2461,7 +2461,7 @@ isdn_net_findif(char *name)
* This is called from the userlevel-routine below or
* from isdn_net_start_xmit().
*/
-int
+static int
isdn_net_force_dial_lp(isdn_net_local * lp)
{
if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) {
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index e21007eca0f..ad5aa38fb5a 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -273,7 +273,7 @@ isdn_tty_rcv_skb(int i, int di, int channel, struct sk_buff *skb)
return 1;
}
-void
+static void
isdn_tty_cleanup_xmit(modem_info * info)
{
skb_queue_purge(&info->xmit_queue);
@@ -560,7 +560,7 @@ isdn_tty_modem_ncarrier(modem_info * info)
/*
* return the usage calculated by si and layer 2 protocol
*/
-int
+static int
isdn_calc_usage(int si, int l2)
{
int usg = ISDN_USAGE_MODEM;
diff --git a/drivers/isdn/i4l/isdn_tty.h b/drivers/isdn/i4l/isdn_tty.h
index 2423a7ff0cc..9f0fa9501f4 100644
--- a/drivers/isdn/i4l/isdn_tty.h
+++ b/drivers/isdn/i4l/isdn_tty.h
@@ -109,7 +109,6 @@ extern int isdn_tty_modem_init(void);
extern void isdn_tty_exit(void);
extern void isdn_tty_readmodem(void);
extern int isdn_tty_find_icall(int, int, setup_parm *);
-extern void isdn_tty_cleanup_xmit(modem_info *);
extern int isdn_tty_stat_callback(int, isdn_ctrl *);
extern int isdn_tty_rcv_skb(int, int, int, struct sk_buff *);
extern int isdn_tty_capi_facility(capi_msg *cm);
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c
index ce2c3ef92e4..a943d078bac 100644
--- a/drivers/isdn/i4l/isdn_ttyfax.c
+++ b/drivers/isdn/i4l/isdn_ttyfax.c
@@ -148,7 +148,7 @@ isdn_tty_fax_modem_result(int code, modem_info * info)
}
}
-int
+static int
isdn_tty_fax_command1(modem_info * info, isdn_ctrl * c)
{
static char *msg[] =
@@ -316,7 +316,7 @@ isdn_tty_fax_bitorder(modem_info * info, struct sk_buff *skb)
* Parse AT+F.. FAX class 1 commands
*/
-int
+static int
isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
{
static char *cmd[] =
@@ -408,7 +408,7 @@ isdn_tty_cmd_FCLASS1(char **p, modem_info * info)
* Parse AT+F.. FAX class 2 commands
*/
-int
+static int
isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
{
atemu *m = &info->emu;
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c
index 4ab7600cf9c..edf14a2aa3c 100644
--- a/drivers/isdn/i4l/isdn_x25iface.c
+++ b/drivers/isdn/i4l/isdn_x25iface.c
@@ -40,15 +40,15 @@ typedef struct isdn_x25iface_proto_data {
/* is now in header file (extern): struct concap_proto * isdn_x25iface_proto_new(void); */
-void isdn_x25iface_proto_del( struct concap_proto * );
-int isdn_x25iface_proto_close( struct concap_proto * );
-int isdn_x25iface_proto_restart( struct concap_proto *,
- struct net_device *,
- struct concap_device_ops *);
-int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * );
-int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * );
-int isdn_x25iface_connect_ind( struct concap_proto * );
-int isdn_x25iface_disconn_ind( struct concap_proto * );
+static void isdn_x25iface_proto_del( struct concap_proto * );
+static int isdn_x25iface_proto_close( struct concap_proto * );
+static int isdn_x25iface_proto_restart( struct concap_proto *,
+ struct net_device *,
+ struct concap_device_ops *);
+static int isdn_x25iface_xmit( struct concap_proto *, struct sk_buff * );
+static int isdn_x25iface_receive( struct concap_proto *, struct sk_buff * );
+static int isdn_x25iface_connect_ind( struct concap_proto * );
+static int isdn_x25iface_disconn_ind( struct concap_proto * );
static struct concap_proto_ops ix25_pops = {
@@ -102,7 +102,7 @@ struct concap_proto * isdn_x25iface_proto_new(void)
/* close the x25iface encapsulation protocol
*/
-int isdn_x25iface_proto_close(struct concap_proto *cprot){
+static int isdn_x25iface_proto_close(struct concap_proto *cprot){
ix25_pdata_t *tmp;
int ret = 0;
@@ -129,7 +129,7 @@ int isdn_x25iface_proto_close(struct concap_proto *cprot){
/* Delete the x25iface encapsulation protocol instance
*/
-void isdn_x25iface_proto_del(struct concap_proto *cprot){
+static void isdn_x25iface_proto_del(struct concap_proto *cprot){
ix25_pdata_t * tmp;
@@ -158,9 +158,9 @@ void isdn_x25iface_proto_del(struct concap_proto *cprot){
/* (re-)initialize the data structures for x25iface encapsulation
*/
-int isdn_x25iface_proto_restart(struct concap_proto *cprot,
- struct net_device *ndev,
- struct concap_device_ops *dops)
+static int isdn_x25iface_proto_restart(struct concap_proto *cprot,
+ struct net_device *ndev,
+ struct concap_device_ops *dops)
{
ix25_pdata_t * pda = cprot -> proto_data ;
ulong flags;
@@ -187,7 +187,7 @@ int isdn_x25iface_proto_restart(struct concap_proto *cprot,
/* deliver a dl_data frame received from i4l HL driver to the network layer
*/
-int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
+static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
{
IX25DEBUG( "isdn_x25iface_receive %s \n", MY_DEVNAME(cprot->net_dev) );
if ( ( (ix25_pdata_t*) (cprot->proto_data) )
@@ -206,7 +206,7 @@ int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb)
/* a connection set up is indicated by lower layer
*/
-int isdn_x25iface_connect_ind(struct concap_proto *cprot)
+static int isdn_x25iface_connect_ind(struct concap_proto *cprot)
{
struct sk_buff * skb = dev_alloc_skb(1);
enum wan_states *state_p
@@ -235,7 +235,7 @@ int isdn_x25iface_connect_ind(struct concap_proto *cprot)
/* a disconnect is indicated by lower layer
*/
-int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
+static int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
{
struct sk_buff *skb;
enum wan_states *state_p
@@ -264,7 +264,7 @@ int isdn_x25iface_disconn_ind(struct concap_proto *cprot)
/* process a frame handed over to us from linux network layer. First byte
semantics as defined in Documentation/networking/x25-iface.txt
*/
-int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
+static int isdn_x25iface_xmit(struct concap_proto *cprot, struct sk_buff *skb)
{
unsigned char firstbyte = skb->data[0];
enum wan_states *state = &((ix25_pdata_t*)cprot->proto_data)->state;
diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c
index 692ec72d1ee..f151f36c825 100644
--- a/drivers/isdn/pcbit/callbacks.c
+++ b/drivers/isdn/pcbit/callbacks.c
@@ -125,23 +125,6 @@ void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
/*
- * Disconnect received (actually RELEASE COMPLETE)
- * This means we were not able to establish connection with remote
- * Inform the big boss above
- */
-void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
- struct callb_data *data)
-{
- isdn_ctrl ictl;
-
- ictl.command = ISDN_STAT_DHUP;
- ictl.driver=dev->id;
- ictl.arg=chan->id;
- dev->dev_if->statcallb(&ictl);
-}
-
-
-/*
* Incoming call received
* inform user
*/
diff --git a/drivers/isdn/pcbit/callbacks.h b/drivers/isdn/pcbit/callbacks.h
index f510dc56b57..17aa0f54bfc 100644
--- a/drivers/isdn/pcbit/callbacks.h
+++ b/drivers/isdn/pcbit/callbacks.h
@@ -19,9 +19,6 @@ extern void cb_out_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
extern void cb_out_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
struct callb_data *data);
-extern void cb_out_3(struct pcbit_dev * dev, struct pcbit_chan* chan,
- struct callb_data *data);
-
extern void cb_in_1(struct pcbit_dev * dev, struct pcbit_chan* chan,
struct callb_data *data);
extern void cb_in_2(struct pcbit_dev * dev, struct pcbit_chan* chan,
diff --git a/drivers/isdn/pcbit/capi.c b/drivers/isdn/pcbit/capi.c
index 29eb03a8c29..bef321d0e51 100644
--- a/drivers/isdn/pcbit/capi.c
+++ b/drivers/isdn/pcbit/capi.c
@@ -627,16 +627,6 @@ int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb)
return 0;
}
-int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb)
-{
- ushort errcode;
-
- errcode = *((ushort*) skb->data);
- skb_pull(skb, 2);
-
- return errcode;
-}
-
#ifdef DEBUG
int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
{
diff --git a/drivers/isdn/pcbit/capi.h b/drivers/isdn/pcbit/capi.h
index 18e6aa360a8..df8e73c04d7 100644
--- a/drivers/isdn/pcbit/capi.h
+++ b/drivers/isdn/pcbit/capi.h
@@ -54,7 +54,6 @@ extern int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff ** skb);
/* Connection Termination */
extern int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause);
-extern int capi_decode_disc_conf(struct pcbit_chan *chan, struct sk_buff *skb);
extern int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb);
extern int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb);
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index e98f9c48c18..5de861f4081 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -56,10 +56,10 @@ static char* pcbit_devname[MAX_PCBIT_CARDS] = {
* prototypes
*/
-int pcbit_command(isdn_ctrl* ctl);
-int pcbit_stat(u_char __user * buf, int len, int, int);
-int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
-int pcbit_writecmd(const u_char __user *, int, int, int);
+static int pcbit_command(isdn_ctrl* ctl);
+static int pcbit_stat(u_char __user * buf, int len, int, int);
+static int pcbit_xmit(int driver, int chan, int ack, struct sk_buff *skb);
+static int pcbit_writecmd(const u_char __user *, int, int, int);
static int set_protocol_running(struct pcbit_dev * dev);
@@ -238,7 +238,7 @@ void pcbit_terminate(int board)
}
#endif
-int pcbit_command(isdn_ctrl* ctl)
+static int pcbit_command(isdn_ctrl* ctl)
{
struct pcbit_dev *dev;
struct pcbit_chan *chan;
@@ -330,7 +330,7 @@ static void pcbit_block_timer(unsigned long data)
}
#endif
-int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
+static int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
{
ushort hdrlen;
int refnum, len;
@@ -389,7 +389,7 @@ int pcbit_xmit(int driver, int chnum, int ack, struct sk_buff *skb)
return len;
}
-int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
+static int pcbit_writecmd(const u_char __user *buf, int len, int driver, int channel)
{
struct pcbit_dev * dev;
int i, j;
@@ -713,7 +713,7 @@ static char statbuf[STATBUF_LEN];
static int stat_st = 0;
static int stat_end = 0;
-int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
+static int pcbit_stat(u_char __user *buf, int len, int driver, int channel)
{
int stat_count;
stat_count = stat_end - stat_st;
diff --git a/drivers/isdn/sc/Makefile b/drivers/isdn/sc/Makefile
index 9cc474cd0c4..0f2b7d602ac 100644
--- a/drivers/isdn/sc/Makefile
+++ b/drivers/isdn/sc/Makefile
@@ -6,5 +6,5 @@ obj-$(CONFIG_ISDN_DRV_SC) += sc.o
# Multipart objects.
-sc-y := shmem.o init.o debug.o packet.o command.o event.o \
+sc-y := shmem.o init.o packet.o command.o event.o \
ioctl.o interrupt.o message.o timer.o
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c
index b2c4eac7cef..19f2fcf0ae4 100644
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -22,14 +22,14 @@
#include "card.h"
#include "scioc.h"
-int dial(int card, unsigned long channel, setup_parm setup);
-int hangup(int card, unsigned long channel);
-int answer(int card, unsigned long channel);
-int clreaz(int card, unsigned long channel);
-int seteaz(int card, unsigned long channel, char *);
-int setl2(int card, unsigned long arg);
-int setl3(int card, unsigned long arg);
-int acceptb(int card, unsigned long channel);
+static int dial(int card, unsigned long channel, setup_parm setup);
+static int hangup(int card, unsigned long channel);
+static int answer(int card, unsigned long channel);
+static int clreaz(int card, unsigned long channel);
+static int seteaz(int card, unsigned long channel, char *);
+static int setl2(int card, unsigned long arg);
+static int setl3(int card, unsigned long arg);
+static int acceptb(int card, unsigned long channel);
extern int cinst;
extern board *sc_adapter[];
@@ -148,56 +148,6 @@ int command(isdn_ctrl *cmd)
}
/*
- * Confirm our ability to communicate with the board. This test assumes no
- * other message activity is present
- */
-int loopback(int card)
-{
-
- int status;
- static char testmsg[] = "Test Message";
- RspMessage rspmsg;
-
- if(!IS_VALID_CARD(card)) {
- pr_debug("Invalid param: %d is not a valid card id\n", card);
- return -ENODEV;
- }
-
- pr_debug("%s: Sending loopback message\n",
- sc_adapter[card]->devicename);
-
- /*
- * Send the loopback message to confirm that memory transfer is
- * operational
- */
- status = send_and_receive(card, CMPID, cmReqType1,
- cmReqClass0,
- cmReqMsgLpbk,
- 0,
- (unsigned char) strlen(testmsg),
- (unsigned char *)testmsg,
- &rspmsg, SAR_TIMEOUT);
-
-
- if (!status) {
- pr_debug("%s: Loopback message successfully sent\n",
- sc_adapter[card]->devicename);
- if(strcmp(rspmsg.msg_data.byte_array, testmsg)) {
- pr_debug("%s: Loopback return != sent\n",
- sc_adapter[card]->devicename);
- return -EIO;
- }
- return 0;
- }
- else {
- pr_debug("%s: Send loopback message failed\n",
- sc_adapter[card]->devicename);
- return -EIO;
- }
-
-}
-
-/*
* start the onboard firmware
*/
int startproc(int card)
@@ -222,16 +172,10 @@ int startproc(int card)
}
-int loadproc(int card, char *data)
-{
- return -1;
-}
-
-
/*
* Dials the number passed in
*/
-int dial(int card, unsigned long channel, setup_parm setup)
+static int dial(int card, unsigned long channel, setup_parm setup)
{
int status;
char Phone[48];
@@ -261,7 +205,7 @@ int dial(int card, unsigned long channel, setup_parm setup)
/*
* Answer an incoming call
*/
-int answer(int card, unsigned long channel)
+static int answer(int card, unsigned long channel)
{
if(!IS_VALID_CARD(card)) {
pr_debug("Invalid param: %d is not a valid card id\n", card);
@@ -282,7 +226,7 @@ int answer(int card, unsigned long channel)
/*
* Hangup up the call on specified channel
*/
-int hangup(int card, unsigned long channel)
+static int hangup(int card, unsigned long channel)
{
int status;
@@ -305,7 +249,7 @@ int hangup(int card, unsigned long channel)
/*
* Set the layer 2 protocol (X.25, HDLC, Raw)
*/
-int setl2(int card, unsigned long arg)
+static int setl2(int card, unsigned long arg)
{
int status =0;
int protocol,channel;
@@ -340,7 +284,7 @@ int setl2(int card, unsigned long arg)
/*
* Set the layer 3 protocol
*/
-int setl3(int card, unsigned long channel)
+static int setl3(int card, unsigned long channel)
{
int protocol = channel >> 8;
@@ -355,7 +299,7 @@ int setl3(int card, unsigned long channel)
return 0;
}
-int acceptb(int card, unsigned long channel)
+static int acceptb(int card, unsigned long channel)
{
if(!IS_VALID_CARD(card)) {
pr_debug("Invalid param: %d is not a valid card id\n", card);
@@ -374,7 +318,7 @@ int acceptb(int card, unsigned long channel)
return 0;
}
-int clreaz(int card, unsigned long arg)
+static int clreaz(int card, unsigned long arg)
{
if(!IS_VALID_CARD(card)) {
pr_debug("Invalid param: %d is not a valid card id\n", card);
@@ -388,7 +332,7 @@ int clreaz(int card, unsigned long arg)
return 0;
}
-int seteaz(int card, unsigned long arg, char *num)
+static int seteaz(int card, unsigned long arg, char *num)
{
if(!IS_VALID_CARD(card)) {
pr_debug("Invalid param: %d is not a valid card id\n", card);
diff --git a/drivers/isdn/sc/debug.c b/drivers/isdn/sc/debug.c
deleted file mode 100644
index 1a992a75868..00000000000
--- a/drivers/isdn/sc/debug.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* $Id: debug.c,v 1.5.6.1 2001/09/23 22:24:59 kai Exp $
- *
- * Copyright (C) 1996 SpellCaster Telecommunications Inc.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * For more information, please contact gpl-info@spellcast.com or write:
- *
- * SpellCaster Telecommunications Inc.
- * 5621 Finch Avenue East, Unit #3
- * Scarborough, Ontario Canada
- * M1B 2T9
- * +1 (416) 297-8565
- * +1 (416) 297-6433 Facsimile
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-int dbg_level = 0;
-static char dbg_funcname[255];
-
-void dbg_endfunc(void)
-{
- if (dbg_level) {
- printk("<-- Leaving function %s\n", dbg_funcname);
- strcpy(dbg_funcname, "");
- }
-}
-
-void dbg_func(char *func)
-{
- strcpy(dbg_funcname, func);
- if(dbg_level)
- printk("--> Entering function %s\n", dbg_funcname);
-}
-
-inline void pullphone(char *dn, char *str)
-{
- int i = 0;
-
- while(dn[i] != ',')
- str[i] = dn[i], i++;
- str[i] = 0x0;
-}
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index efefedea37b..40b0df04ed9 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -20,9 +20,9 @@ board *sc_adapter[MAX_CARDS];
int cinst;
static char devname[] = "scX";
-const char version[] = "2.0b1";
+static const char version[] = "2.0b1";
-const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" };
+static const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" };
/* insmod set parameters */
static unsigned int io[] = {0,0,0,0};
@@ -35,26 +35,13 @@ module_param_array(irq, int, NULL, 0);
module_param_array(ram, int, NULL, 0);
module_param(do_reset, bool, 0);
-static int sup_irq[] = { 11, 10, 9, 5, 12, 14, 7, 3, 4, 6 };
-#define MAX_IRQS 10
-
extern irqreturn_t interrupt_handler(int, void *, struct pt_regs *);
extern int sndpkt(int, int, int, struct sk_buff *);
extern int command(isdn_ctrl *);
extern int indicate_status(int, int, ulong, char*);
extern int reset(int);
-int identify_board(unsigned long, unsigned int);
-
-int irq_supported(int irq_x)
-{
- int i;
- for(i=0 ; i < MAX_IRQS ; i++) {
- if(sup_irq[i] == irq_x)
- return 1;
- }
- return 0;
-}
+static int identify_board(unsigned long, unsigned int);
static int __init sc_init(void)
{
@@ -454,7 +441,7 @@ static void __exit sc_exit(void)
pr_info("SpellCaster ISA ISDN Adapter Driver Unloaded.\n");
}
-int identify_board(unsigned long rambase, unsigned int iobase)
+static int identify_board(unsigned long rambase, unsigned int iobase)
{
unsigned int pgport;
unsigned long sig;
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c
index e5e164aca7f..8631d338d69 100644
--- a/drivers/isdn/sc/interrupt.c
+++ b/drivers/isdn/sc/interrupt.c
@@ -31,7 +31,7 @@ extern void rcvpkt(int, RspMessage *);
extern int cinst;
extern board *sc_adapter[];
-int get_card_from_irq(int irq)
+static int get_card_from_irq(int irq)
{
int i;
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c
index 1371a990416..3314a5a1985 100644
--- a/drivers/isdn/sc/ioctl.c
+++ b/drivers/isdn/sc/ioctl.c
@@ -14,7 +14,6 @@
extern int indicate_status(int, int, unsigned long, char *);
extern int startproc(int);
-extern int loadproc(int, char *record);
extern int reset(int);
extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,
unsigned char,unsigned char,
@@ -23,7 +22,7 @@ extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,
extern board *sc_adapter[];
-int GetStatus(int card, boardInfo *);
+static int GetStatus(int card, boardInfo *);
/*
* Process private IOCTL messages (typically from scctrl)
@@ -428,7 +427,7 @@ int sc_ioctl(int card, scs_ioctl *data)
return 0;
}
-int GetStatus(int card, boardInfo *bi)
+static int GetStatus(int card, boardInfo *bi)
{
RspMessage rcvmsg;
int i, status;
diff --git a/drivers/isdn/sc/packet.c b/drivers/isdn/sc/packet.c
index 8e3fac3ba1a..f50defc38ae 100644
--- a/drivers/isdn/sc/packet.c
+++ b/drivers/isdn/sc/packet.c
@@ -213,19 +213,3 @@ int setup_buffers(int card, int c)
return 0;
}
-int print_skb(int card,char *skb_p, int len){
- int i,data;
- pr_debug("%s: data at 0x%x len: 0x%x\n", sc_adapter[card]->devicename,
- skb_p,len);
- for(i=1;i<=len;i++,skb_p++){
- data = (int) (0xff & (*skb_p));
- pr_debug("%s: data = 0x%x", sc_adapter[card]->devicename,data);
- if(!(i%4))
- pr_debug(" ");
- if(!(i%32))
- pr_debug("\n");
- }
- pr_debug("\n");
- return 0;
-}
-
diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c
index 7bc2dfad077..24854826ca4 100644
--- a/drivers/isdn/sc/shmem.c
+++ b/drivers/isdn/sc/shmem.c
@@ -108,6 +108,7 @@ void memcpy_fromshmem(int card, void *dest, const void *src, size_t n)
sc_adapter[card]->rambase + ((unsigned long) src %0x4000), (unsigned long) dest); */
}
+#if 0
void memset_shmem(int card, void *dest, int c, size_t n)
{
unsigned long flags;
@@ -141,3 +142,4 @@ void memset_shmem(int card, void *dest, int c, size_t n)
((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
}
+#endif /* 0 */
diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c
index 710d0f47ca3..aced19aac5a 100644
--- a/drivers/isdn/sc/timer.c
+++ b/drivers/isdn/sc/timer.c
@@ -32,7 +32,7 @@ extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
/*
* Write the proper values into the I/O ports following a reset
*/
-void setup_ports(int card)
+static void setup_ports(int card)
{
outb((sc_adapter[card]->rambase >> 12), sc_adapter[card]->ioport[EXP_BASE]);
@@ -129,19 +129,3 @@ void check_phystat(unsigned long data)
ceReqPhyStatus,0,0,NULL);
}
-/*
- * When in trace mode, this callback is used to swap the working shared
- * RAM page to the trace page(s) and process all received messages. It
- * must be called often enough to get all of the messages out of RAM before
- * it loops around.
- * Trace messages are \n terminated strings.
- * We output the messages in 64 byte chunks through readstat. Each chunk
- * is scanned for a \n followed by a time stamp. If the timerstamp is older
- * than the current time, scanning stops and the page and offset are recorded
- * as the starting point the next time the trace timer is called. The final
- * step is to restore the working page and reset the timer.
- */
-void trace_timer(unsigned long data)
-{
- /* not implemented */
-}
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 5ba190ce14a..c9ca1118e44 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -328,9 +328,7 @@ static int monitor_task(void *arg)
struct thermostat* th = arg;
while(!kthread_should_stop()) {
- if (current->flags & PF_FREEZE)
- refrigerator(PF_FREEZE);
-
+ try_to_freeze();
msleep_interruptible(2000);
#ifndef DEBUG
diff --git a/drivers/mca/mca-legacy.c b/drivers/mca/mca-legacy.c
index af56313ba0a..0c7bfa74c8e 100644
--- a/drivers/mca/mca-legacy.c
+++ b/drivers/mca/mca-legacy.c
@@ -180,7 +180,6 @@ struct mca_device *mca_find_device_by_slot(int slot)
return info.mca_dev;
}
-EXPORT_SYMBOL(mca_find_device_by_slot);
/**
* mca_read_stored_pos - read POS register from boot data
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index ee3c869d970..200a0688f71 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -122,14 +122,6 @@ static struct hash_cell *__get_uuid_cell(const char *str)
/*-----------------------------------------------------------------
* Inserting, removing and renaming a device.
*---------------------------------------------------------------*/
-static inline char *kstrdup(const char *str)
-{
- char *r = kmalloc(strlen(str) + 1, GFP_KERNEL);
- if (r)
- strcpy(r, str);
- return r;
-}
-
static struct hash_cell *alloc_cell(const char *name, const char *uuid,
struct mapped_device *md)
{
@@ -139,7 +131,7 @@ static struct hash_cell *alloc_cell(const char *name, const char *uuid,
if (!hc)
return NULL;
- hc->name = kstrdup(name);
+ hc->name = kstrdup(name, GFP_KERNEL);
if (!hc->name) {
kfree(hc);
return NULL;
@@ -149,7 +141,7 @@ static struct hash_cell *alloc_cell(const char *name, const char *uuid,
hc->uuid = NULL;
else {
- hc->uuid = kstrdup(uuid);
+ hc->uuid = kstrdup(uuid, GFP_KERNEL);
if (!hc->uuid) {
kfree(hc->name);
kfree(hc);
@@ -273,7 +265,7 @@ static int dm_hash_rename(const char *old, const char *new)
/*
* duplicate new.
*/
- new_name = kstrdup(new);
+ new_name = kstrdup(new, GFP_KERNEL);
if (!new_name)
return -ENOMEM;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0c6b5b6baff..3802f7a17f1 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2976,8 +2976,7 @@ static int md_thread(void * arg)
wait_event_interruptible_timeout(thread->wqueue,
test_bit(THREAD_WAKEUP, &thread->flags),
thread->timeout);
- if (current->flags & PF_FREEZE)
- refrigerator(PF_FREEZE);
+ try_to_freeze();
clear_bit(THREAD_WAKEUP, &thread->flags);
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 84a49d2ec91..4adb2843f8b 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -1,5 +1,5 @@
/*
- * $Id: ir-common.c,v 1.8 2005/02/22 12:28:40 kraxel Exp $
+ * $Id: ir-common.c,v 1.10 2005/05/22 19:23:39 nsh Exp $
*
* some common structs and functions to handle infrared remotes via
* input layer ...
@@ -131,10 +131,10 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
[ 18 ] = KEY_KP0,
[ 0 ] = KEY_POWER,
- [ 27 ] = KEY_LANGUAGE, //MTS button
+// [ 27 ] = MTS button
[ 2 ] = KEY_TUNER, // TV/FM
[ 30 ] = KEY_VIDEO,
- [ 22 ] = KEY_INFO, //display button
+// [ 22 ] = display button
[ 4 ] = KEY_VOLUMEUP,
[ 8 ] = KEY_VOLUMEDOWN,
[ 12 ] = KEY_CHANNELUP,
@@ -142,7 +142,7 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
[ 3 ] = KEY_ZOOM, // fullscreen
[ 31 ] = KEY_SUBTITLE, // closed caption/teletext
[ 32 ] = KEY_SLEEP,
- [ 41 ] = KEY_SEARCH, //boss key
+// [ 41 ] = boss key
[ 20 ] = KEY_MUTE,
[ 43 ] = KEY_RED,
[ 44 ] = KEY_GREEN,
@@ -150,17 +150,17 @@ IR_KEYTAB_TYPE ir_codes_winfast[IR_KEYTAB_SIZE] = {
[ 46 ] = KEY_BLUE,
[ 24 ] = KEY_KPPLUS, //fine tune +
[ 25 ] = KEY_KPMINUS, //fine tune -
- [ 42 ] = KEY_ANGLE, //picture in picture
- [ 33 ] = KEY_KPDOT,
+// [ 42 ] = picture in picture
+ [ 33 ] = KEY_KPDOT,
[ 19 ] = KEY_KPENTER,
- [ 17 ] = KEY_AGAIN, //recall
+// [ 17 ] = recall
[ 34 ] = KEY_BACK,
[ 35 ] = KEY_PLAYPAUSE,
[ 36 ] = KEY_NEXT,
- [ 37 ] = KEY_T, //time shifting
+// [ 37 ] = time shifting
[ 38 ] = KEY_STOP,
- [ 39 ] = KEY_RECORD,
- [ 40 ] = KEY_SHUFFLE //snapshot
+ [ 39 ] = KEY_RECORD
+// [ 40 ] = snapshot
};
EXPORT_SYMBOL_GPL(ir_codes_winfast);
@@ -184,18 +184,30 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
[ 0x07 ] = KEY_KP7, // 7
[ 0x08 ] = KEY_KP8, // 8
[ 0x09 ] = KEY_KP9, // 9
+ [ 0x0a ] = KEY_TEXT, // keypad asterisk as well
[ 0x0b ] = KEY_RED, // red button
- [ 0x0c ] = KEY_OPTION, // black key without text
+ [ 0x0c ] = KEY_RADIO, // radio
[ 0x0d ] = KEY_MENU, // menu
+ [ 0x0e ] = KEY_SUBTITLE, // also the # key
[ 0x0f ] = KEY_MUTE, // mute
[ 0x10 ] = KEY_VOLUMEUP, // volume +
[ 0x11 ] = KEY_VOLUMEDOWN, // volume -
- [ 0x1e ] = KEY_NEXT, // skip >|
+ [ 0x12 ] = KEY_PREVIOUS, // previous channel
+ [ 0x14 ] = KEY_UP, // up
+ [ 0x15 ] = KEY_DOWN, // down
+ [ 0x16 ] = KEY_LEFT, // left
+ [ 0x17 ] = KEY_RIGHT, // right
+ [ 0x18 ] = KEY_VIDEO, // Videos
+ [ 0x19 ] = KEY_AUDIO, // Music
+ [ 0x1a ] = KEY_MHP, // Pictures - presume this means "Multimedia Home Platform"- no "PICTURES" key in input.h
+ [ 0x1b ] = KEY_EPG, // Guide
+ [ 0x1c ] = KEY_TV, // TV
+ [ 0x1e ] = KEY_NEXTSONG, // skip >|
[ 0x1f ] = KEY_EXIT, // back/exit
[ 0x20 ] = KEY_CHANNELUP, // channel / program +
[ 0x21 ] = KEY_CHANNELDOWN, // channel / program -
[ 0x22 ] = KEY_CHANNEL, // source (old black remote)
- [ 0x24 ] = KEY_PREVIOUS, // replay |<
+ [ 0x24 ] = KEY_PREVIOUSSONG, // replay |<
[ 0x25 ] = KEY_ENTER, // OK
[ 0x26 ] = KEY_SLEEP, // minimize (old black remote)
[ 0x29 ] = KEY_BLUE, // blue key
@@ -213,6 +225,39 @@ IR_KEYTAB_TYPE ir_codes_hauppauge_new[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL(ir_codes_hauppauge_new);
+IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
+ [ 2 ] = KEY_KP0,
+ [ 1 ] = KEY_KP1,
+ [ 11 ] = KEY_KP2,
+ [ 27 ] = KEY_KP3,
+ [ 5 ] = KEY_KP4,
+ [ 9 ] = KEY_KP5,
+ [ 21 ] = KEY_KP6,
+ [ 6 ] = KEY_KP7,
+ [ 10 ] = KEY_KP8,
+ [ 18 ] = KEY_KP9,
+
+ [ 3 ] = KEY_TUNER, // TV/FM
+ [ 7 ] = KEY_SEARCH, // scan
+ [ 28 ] = KEY_ZOOM, // full screen
+ [ 30 ] = KEY_POWER,
+ [ 23 ] = KEY_VOLUMEDOWN,
+ [ 31 ] = KEY_VOLUMEUP,
+ [ 20 ] = KEY_CHANNELDOWN,
+ [ 22 ] = KEY_CHANNELUP,
+ [ 24 ] = KEY_MUTE,
+
+ [ 0 ] = KEY_LIST, // source
+ [ 19 ] = KEY_INFO, // loop
+ [ 16 ] = KEY_LAST, // +100
+ [ 13 ] = KEY_CLEAR, // reset
+ [ 12 ] = BTN_RIGHT, // fun++
+ [ 4 ] = BTN_LEFT, // fun--
+ [ 14 ] = KEY_GOTO, // function
+ [ 15 ] = KEY_STOP, // freeze
+};
+EXPORT_SYMBOL(ir_codes_pixelview);
+
/* -------------------------------------------------------------------------- */
static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
@@ -379,3 +424,4 @@ EXPORT_SYMBOL_GPL(ir_decode_biphase);
* c-basic-offset: 8
* End:
*/
+
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index cb826c9adfe..c04fd11526e 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -403,7 +403,7 @@ static struct file_operations video_fops =
.llseek = no_llseek,
};
-void vv_callback(struct saa7146_dev *dev, unsigned long status)
+static void vv_callback(struct saa7146_dev *dev, unsigned long status)
{
u32 isr = status;
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 4983e1b1bb1..01387f883cd 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -27,9 +27,9 @@ source "drivers/media/dvb/ttpci/Kconfig"
comment "Supported USB Adapters"
depends on DVB_CORE && USB
+source "drivers/media/dvb/dvb-usb/Kconfig"
source "drivers/media/dvb/ttusb-budget/Kconfig"
source "drivers/media/dvb/ttusb-dec/Kconfig"
-source "drivers/media/dvb/dibusb/Kconfig"
source "drivers/media/dvb/cinergyT2/Kconfig"
comment "Supported FlexCopII (B2C2) Adapters"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index 520fc390281..3c6ff161910 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,4 +2,4 @@
# Makefile for the kernel multimedia device drivers.
#
-obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dibusb/ cinergyT2/
+obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 99bd675df95..fafd0ab3a28 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -6,6 +6,7 @@ config DVB_B2C2_FLEXCOP
select DVB_MT312
select DVB_NXT2002
select DVB_STV0297
+ select DVB_BCM3510
help
Support for the digital TV receiver chip made by B2C2 Inc. included in
Technisats PCI cards and USB boxes.
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 71be400e9ae..0410cc96a48 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -10,6 +10,7 @@
#include "stv0299.h"
#include "mt352.h"
#include "nxt2002.h"
+#include "bcm3510.h"
#include "stv0297.h"
#include "mt312.h"
@@ -285,21 +286,25 @@ static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_front
}
static struct mt352_config samsung_tdtc9251dh0_config = {
-
.demod_address = 0x0f,
- .demod_init = samsung_tdtc9251dh0_demod_init,
- .pll_set = samsung_tdtc9251dh0_pll_set,
+ .demod_init = samsung_tdtc9251dh0_demod_init,
+ .pll_set = samsung_tdtc9251dh0_pll_set,
};
-static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
{
struct flexcop_device *fc = fe->dvb->priv;
return request_firmware(fw, name, fc->dev);
}
static struct nxt2002_config samsung_tbmv_config = {
- .demod_address = 0x0a,
- .request_firmware = nxt2002_request_firmware,
+ .demod_address = 0x0a,
+ .request_firmware = flexcop_fe_request_firmware,
+};
+
+static struct bcm3510_config air2pc_atsc_first_gen_config = {
+ .demod_address = 0x0f,
+ .request_firmware = flexcop_fe_request_firmware,
};
static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -354,11 +359,16 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->dev_type = FC_AIR_DVB;
info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
} else
- /* try the air atsc (nxt2002) */
+ /* try the air atsc 2nd generation (nxt2002) */
if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
- fc->dev_type = FC_AIR_ATSC;
+ fc->dev_type = FC_AIR_ATSC2;
info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
} else
+ /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
+ if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
+ fc->dev_type = FC_AIR_ATSC1;
+ info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
+ } else
/* try the cable dvb (stv0297) */
if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) {
fc->dev_type = FC_CABLE;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 19e06da4677..23082545651 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -45,11 +45,12 @@ const char *flexcop_revision_names[] = {
const char *flexcop_device_names[] = {
"Unkown device",
- "AirStar 2 DVB-T",
- "AirStar 2 ATSC",
- "SkyStar 2 DVB-S",
- "SkyStar 2 DVB-S (old version)",
- "CableStar 2 DVB-C",
+ "Air2PC/AirStar 2 DVB-T",
+ "Air2PC/AirStar 2 ATSC 1st generation",
+ "Air2PC/AirStar 2 ATSC 2nd generation",
+ "Sky2PC/SkyStar 2 DVB-S",
+ "Sky2PC/SkyStar 2 DVB-S (old version)",
+ "Cable2PC/CableStar 2 DVB-C",
};
const char *flexcop_bus_names[] = {
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 5e131be55cb..75b50f21afe 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -21,7 +21,8 @@ extern const char *flexcop_revision_names[];
typedef enum {
FC_UNK = 0,
FC_AIR_DVB,
- FC_AIR_ATSC,
+ FC_AIR_ATSC1,
+ FC_AIR_ATSC2,
FC_SKY,
FC_SKY_OLD,
FC_CABLE,
diff --git a/drivers/media/dvb/dibusb/Kconfig b/drivers/media/dvb/dibusb/Kconfig
deleted file mode 100644
index 74dfc73ae5b..00000000000
--- a/drivers/media/dvb/dibusb/Kconfig
+++ /dev/null
@@ -1,62 +0,0 @@
-config DVB_DIBUSB
- tristate "DiBcom USB DVB-T devices (see help for a complete device list)"
- depends on DVB_CORE && USB
- select FW_LOADER
- select DVB_DIB3000MB
- select DVB_DIB3000MC
- select DVB_MT352
- help
- Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by
- DiBcom (http://www.dibcom.fr) and C&E.
-
- Devices supported by this driver:
-
- TwinhanDTV USB-Ter (VP7041)
- TwinhanDTV Magic Box (VP7041e)
- KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
- Hama DVB-T USB-Box
- DiBcom reference devices (non-public)
- Ultima Electronic/Artec T1 USB TVBOX
- Compro Videomate DVB-U2000 - DVB-T USB
- Grandtec DVB-T USB
- Avermedia AverTV DVBT USB
- Artec T1 USB1.1 and USB2.0 boxes
- Yakumo/Typhoon DVB-T USB2.0
- Hanftek UMT-010 USB2.0
- Hauppauge WinTV NOVA-T USB2
-
- The VP7041 seems to be identical to "CTS Portable" (Chinese
- Television System).
-
- These devices can be understood as budget ones, they "only" deliver
- (a part of) the MPEG2 transport stream.
-
- A firmware is needed to get the device working. See Documentation/dvb/README.dibusb
- details.
-
- Say Y if you own such a device and want to use it. You should build it as
- a module.
-
-config DVB_DIBUSB_MISDESIGNED_DEVICES
- bool "Enable support for some misdesigned (see help) devices, which identify with wrong IDs"
- depends on DVB_DIBUSB
- help
- Somehow Artec/Ultima Electronic forgot to program the eeprom of some of their
- USB1.1/USB2.0 devices.
- So comes that they identify with the default Vendor and Product ID of the Cypress
- CY7C64613 (AN2235) or Cypress FX2.
-
- Affected device IDs:
- 0x0574:0x2235 (Artec T1 USB1.1, cold)
- 0x04b4:0x8613 (Artec T1 USB2.0, cold)
- 0x0574:0x1002 (Artec T1 USB2.0, warm)
- 0x0574:0x2131 (aged DiBcom USB1.1 test device)
-
- Say Y if your device has one of the mentioned IDs.
-
-config DVB_DIBCOM_DEBUG
- bool "Enable extended debug support for DiBcom USB device"
- depends on DVB_DIBUSB
- help
- Say Y if you want to enable debuging. See modinfo dvb-dibusb for
- debug levels.
diff --git a/drivers/media/dvb/dibusb/Makefile b/drivers/media/dvb/dibusb/Makefile
deleted file mode 100644
index e941c508624..00000000000
--- a/drivers/media/dvb/dibusb/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-dvb-dibusb-objs = dvb-dibusb-core.o \
- dvb-dibusb-dvb.o \
- dvb-dibusb-fe-i2c.o \
- dvb-dibusb-firmware.o \
- dvb-dibusb-remote.o \
- dvb-dibusb-usb.o \
- dvb-fe-dtt200u.o
-
-obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o
-
-EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-core.c b/drivers/media/dvb/dibusb/dvb-dibusb-core.c
deleted file mode 100644
index 26235f9247e..00000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-core.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Driver for mobile USB Budget DVB-T devices based on reference
- * design made by DiBcom (http://www.dibcom.fr/)
- *
- * dvb-dibusb-core.c
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * based on GPL code from DiBcom, which has
- * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
- *
- * Remote control code added by David Matthews (dm@prolingua.co.uk)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- * Acknowledgements
- *
- * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
- * sources, on which this driver (and the dib3000mb/mc/p frontends) are based.
- *
- * see Documentation/dvb/README.dibusb for more information
- */
-#include "dvb-dibusb.h"
-
-#include <linux/moduleparam.h>
-
-/* debug */
-int dvb_dibusb_debug;
-module_param_named(debug, dvb_dibusb_debug, int, 0644);
-
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
-#define DBSTATUS ""
-#else
-#define DBSTATUS " (debugging is not enabled)"
-#endif
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=alotmore,8=ts,16=err,32=rc (|-able))." DBSTATUS);
-#undef DBSTATUS
-
-static int pid_parse;
-module_param(pid_parse, int, 0644);
-MODULE_PARM_DESC(pid_parse, "enable pid parsing (filtering) when running at USB2.0");
-
-static int rc_query_interval = 100;
-module_param(rc_query_interval, int, 0644);
-MODULE_PARM_DESC(rc_query_interval, "interval in msecs for remote control query (default: 100; min: 40)");
-
-static int rc_key_repeat_count = 2;
-module_param(rc_key_repeat_count, int, 0644);
-MODULE_PARM_DESC(rc_key_repeat_count, "how many key repeats will be dropped before passing the key event again (default: 2)");
-
-/* Vendor IDs */
-#define USB_VID_ADSTECH 0x06e1
-#define USB_VID_ANCHOR 0x0547
-#define USB_VID_AVERMEDIA 0x14aa
-#define USB_VID_COMPRO 0x185b
-#define USB_VID_COMPRO_UNK 0x145f
-#define USB_VID_CYPRESS 0x04b4
-#define USB_VID_DIBCOM 0x10b8
-#define USB_VID_EMPIA 0xeb1a
-#define USB_VID_GRANDTEC 0x5032
-#define USB_VID_HANFTEK 0x15f4
-#define USB_VID_HAUPPAUGE 0x2040
-#define USB_VID_HYPER_PALTEK 0x1025
-#define USB_VID_IMC_NETWORKS 0x13d3
-#define USB_VID_TWINHAN 0x1822
-#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
-
-/* Product IDs */
-#define USB_PID_ADSTECH_USB2_COLD 0xa333
-#define USB_PID_ADSTECH_USB2_WARM 0xa334
-#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
-#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
-#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
-#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
-#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
-#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
-#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
-#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
-#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
-#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
-#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
-#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
-#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
-#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
-#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
-#define USB_PID_TWINHAN_VP7041_COLD 0x3201
-#define USB_PID_TWINHAN_VP7041_WARM 0x3202
-#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
-#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
-#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
-#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
-#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
-#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
-#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
-#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
-#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
-#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
-#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
-#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
-#define USB_PID_YAKUMO_DTT200U_COLD 0x0201
-#define USB_PID_YAKUMO_DTT200U_WARM 0x0301
-#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
-#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
-
-/* USB Driver stuff
- * table of devices that this driver is working with
- *
- * ATTENTION: Never ever change the order of this table, the particular
- * devices depend on this order
- *
- * Each entry is used as a reference in the device_struct. Currently this is
- * the only non-redundant way of assigning USB ids to actual devices I'm aware
- * of, because there is only one place in the code where the assignment of
- * vendor and product id is done, here.
- */
-static struct usb_device_id dib_table [] = {
-/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
-/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
-/* 02 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_COLD) },
-/* 03 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_YAKUMO_DTT200U_WARM) },
-
-/* 04 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
-/* 05 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
-/* 06 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
-/* 07 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
-/* 08 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
-/* 09 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
-/* 10 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
-/* 11 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
-/* 12 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
-/* 13 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
-/* 14 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
-/* 15 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
-/* 16 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
-/* 17 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
-/* 18 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
-/* 19 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_COLD) },
-/* 20 */ { USB_DEVICE(USB_VID_IMC_NETWORKS, USB_PID_TWINHAN_VP7041_WARM) },
-/* 21 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
-/* 22 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
-/* 23 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
-/* 24 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
-/* 25 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
-/* 26 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
-/* 27 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
-
-/* 28 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
-/* 29 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
-
-/* 30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) },
-/* 31 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
-/* 32 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
-/* 33 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
-/*
- * activate the following define when you have one of the devices and want to
- * build it from build-2.6 in dvb-kernel
- */
-// #define CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
-#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
-/* 34 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
-/* 35 */ { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ULTIMA_TVBOX_USB2_FX_COLD) },
-/* 36 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_USB2_FX_WARM) },
-/* 37 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_DIBCOM_ANCHOR_2135_COLD) },
-#endif
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, dib_table);
-
-static struct dibusb_usb_controller dibusb_usb_ctrl[] = {
- { .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
- { .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
- { .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
-};
-
-struct dibusb_tuner dibusb_tuner[] = {
- { DIBUSB_TUNER_CABLE_THOMSON,
- 0x61
- },
- { DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
- 0x60
- },
- { DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
- 0x61
- },
- { DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
- 0x60
- },
-};
-
-static struct dibusb_demod dibusb_demod[] = {
- { DIBUSB_DIB3000MB,
- 16,
- { 0x8, 0 },
- },
- { DIBUSB_DIB3000MC,
- 32,
- { 0x9, 0xa, 0xb, 0xc },
- },
- { DIBUSB_MT352,
- 254,
- { 0xf, 0 },
- },
- { DTT200U_FE,
- 8,
- { 0xff,0 }, /* there is no i2c bus in this device */
- }
-};
-
-static struct dibusb_device_class dibusb_device_classes[] = {
- { .id = DIBUSB1_1, .usb_ctrl = &dibusb_usb_ctrl[0],
- .firmware = "dvb-dibusb-5.0.0.11.fw",
- .pipe_cmd = 0x01, .pipe_data = 0x02,
- .urb_count = 7, .urb_buffer_size = 4096,
- DIBUSB_RC_NEC_PROTOCOL,
- &dibusb_demod[DIBUSB_DIB3000MB],
- &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
- },
- { DIBUSB1_1_AN2235, &dibusb_usb_ctrl[1],
- "dvb-dibusb-an2235-1.fw",
- 0x01, 0x02,
- 7, 4096,
- DIBUSB_RC_NEC_PROTOCOL,
- &dibusb_demod[DIBUSB_DIB3000MB],
- &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
- },
- { DIBUSB2_0,&dibusb_usb_ctrl[2],
- "dvb-dibusb-6.0.0.5.fw",
- 0x01, 0x06,
- 7, 4096,
- DIBUSB_RC_NEC_PROTOCOL,
- &dibusb_demod[DIBUSB_DIB3000MC],
- &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
- },
- { UMT2_0, &dibusb_usb_ctrl[2],
- "dvb-dibusb-umt-2.fw",
- 0x01, 0x06,
- 20, 512,
- DIBUSB_RC_NO,
- &dibusb_demod[DIBUSB_MT352],
- &dibusb_tuner[DIBUSB_TUNER_CABLE_LG_TDTP_E102P],
- },
- { DIBUSB2_0B,&dibusb_usb_ctrl[2],
- "dvb-dibusb-adstech-usb2-1.fw",
- 0x01, 0x06,
- 7, 4096,
- DIBUSB_RC_NEC_PROTOCOL,
- &dibusb_demod[DIBUSB_DIB3000MB],
- &dibusb_tuner[DIBUSB_TUNER_CABLE_THOMSON],
- },
- { NOVAT_USB2,&dibusb_usb_ctrl[2],
- "dvb-dibusb-nova-t-1.fw",
- 0x01, 0x06,
- 7, 4096,
- DIBUSB_RC_HAUPPAUGE_PROTO,
- &dibusb_demod[DIBUSB_DIB3000MC],
- &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5],
- },
- { DTT200U,&dibusb_usb_ctrl[2],
- "dvb-dtt200u-1.fw",
- 0x01, 0x02,
- 7, 4096,
- DIBUSB_RC_NO,
- &dibusb_demod[DTT200U_FE],
- NULL, /* no explicit tuner/pll-programming necessary (it has the ENV57H1XD5) */
- },
-};
-
-static struct dibusb_usb_device dibusb_devices[] = {
- { "TwinhanDTV USB1.1 / Magic Box / HAMA USB1.1 DVB-T device",
- &dibusb_device_classes[DIBUSB1_1],
- { &dib_table[19], &dib_table[21], NULL},
- { &dib_table[20], &dib_table[22], NULL},
- },
- { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
- &dibusb_device_classes[DIBUSB1_1],
- { &dib_table[11], NULL },
- { &dib_table[12], NULL },
- },
- { "Grandtec USB1.1 DVB-T",
- &dibusb_device_classes[DIBUSB1_1],
- { &dib_table[13], &dib_table[15], NULL },
- { &dib_table[14], &dib_table[16], NULL },
- },
- { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
- &dibusb_device_classes[DIBUSB1_1],
- { &dib_table[7], NULL },
- { &dib_table[8], NULL },
- },
- { "Artec T1 USB1.1 TVBOX with AN2135",
- &dibusb_device_classes[DIBUSB1_1],
- { &dib_table[23], NULL },
- { &dib_table[24], NULL },
- },
- { "Artec T1 USB1.1 TVBOX with AN2235",
- &dibusb_device_classes[DIBUSB1_1_AN2235],
- { &dib_table[25], NULL },
- { &dib_table[26], NULL },
- },
- { "Avermedia AverTV DVBT USB1.1",
- &dibusb_device_classes[DIBUSB1_1],
- { &dib_table[0], NULL },
- { &dib_table[1], NULL },
- },
- { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
- &dibusb_device_classes[DIBUSB1_1],
- { &dib_table[4], &dib_table[6], NULL},
- { &dib_table[5], NULL },
- },
- { "Unkown USB1.1 DVB-T device ???? please report the name to the author",
- &dibusb_device_classes[DIBUSB1_1],
- { &dib_table[17], NULL },
- { &dib_table[18], NULL },
- },
- { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
- &dibusb_device_classes[DIBUSB2_0],
- { &dib_table[9], NULL },
- { &dib_table[10], NULL },
- },
- { "Artec T1 USB2.0 TVBOX (please report the warm ID)",
- &dibusb_device_classes[DIBUSB2_0],
- { &dib_table[27], NULL },
- { NULL },
- },
- { "Hauppauge WinTV NOVA-T USB2",
- &dibusb_device_classes[NOVAT_USB2],
- { &dib_table[30], NULL },
- { &dib_table[31], NULL },
- },
- { "DTT200U (Yakumo/Hama/Typhoon) DVB-T USB2.0",
- &dibusb_device_classes[DTT200U],
- { &dib_table[2], NULL },
- { &dib_table[3], NULL },
- },
- { "Hanftek UMT-010 DVB-T USB2.0",
- &dibusb_device_classes[UMT2_0],
- { &dib_table[28], NULL },
- { &dib_table[29], NULL },
- },
- { "KWorld/ADSTech Instant DVB-T USB 2.0",
- &dibusb_device_classes[DIBUSB2_0B],
- { &dib_table[32], NULL },
- { &dib_table[33], NULL }, /* device ID with default DIBUSB2_0-firmware */
- },
-#ifdef CONFIG_DVB_DIBUSB_MISDESIGNED_DEVICES
- { "Artec T1 USB1.1 TVBOX with AN2235 (misdesigned)",
- &dibusb_device_classes[DIBUSB1_1_AN2235],
- { &dib_table[34], NULL },
- { NULL },
- },
- { "Artec T1 USB2.0 TVBOX with FX2 IDs (misdesigned, please report the warm ID)",
- &dibusb_device_classes[DTT200U],
- { &dib_table[35], NULL },
- { &dib_table[36], NULL }, /* undefined, it could be that the device will get another USB ID in warm state */
- },
- { "DiBcom USB1.1 DVB-T reference design (MOD3000) with AN2135 default IDs",
- &dibusb_device_classes[DIBUSB1_1],
- { &dib_table[37], NULL },
- { NULL },
- },
-#endif
-};
-
-static int dibusb_exit(struct usb_dibusb *dib)
-{
- deb_info("init_state before exiting everything: %x\n",dib->init_state);
- dibusb_remote_exit(dib);
- dibusb_fe_exit(dib);
- dibusb_i2c_exit(dib);
- dibusb_dvb_exit(dib);
- dibusb_urb_exit(dib);
- deb_info("init_state should be zero now: %x\n",dib->init_state);
- dib->init_state = DIBUSB_STATE_INIT;
- kfree(dib);
- return 0;
-}
-
-static int dibusb_init(struct usb_dibusb *dib)
-{
- int ret = 0;
- sema_init(&dib->usb_sem, 1);
- sema_init(&dib->i2c_sem, 1);
-
- dib->init_state = DIBUSB_STATE_INIT;
-
- if ((ret = dibusb_urb_init(dib)) ||
- (ret = dibusb_dvb_init(dib)) ||
- (ret = dibusb_i2c_init(dib))) {
- dibusb_exit(dib);
- return ret;
- }
-
- if ((ret = dibusb_fe_init(dib)))
- err("could not initialize a frontend.");
-
- if ((ret = dibusb_remote_init(dib)))
- err("could not initialize remote control.");
-
- return 0;
-}
-
-static struct dibusb_usb_device * dibusb_device_class_quirk(struct usb_device *udev, struct dibusb_usb_device *dev)
-{
- int i;
-
- /* Quirk for the Kworld/ADSTech Instant USB2.0 device. It has the same USB
- * IDs like the USB1.1 KWorld after loading the firmware. Which is a bad
- * idea and make this quirk necessary.
- */
- if (dev->dev_cl->id == DIBUSB1_1 && udev->speed == USB_SPEED_HIGH) {
- info("this seems to be the Kworld/ADSTech Instant USB2.0 device or equal.");
- for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
- if (dibusb_devices[i].dev_cl->id == DIBUSB2_0B) {
- dev = &dibusb_devices[i];
- break;
- }
- }
- }
-
- return dev;
-}
-
-static struct dibusb_usb_device * dibusb_find_device (struct usb_device *udev,int *cold)
-{
- int i,j;
- struct dibusb_usb_device *dev = NULL;
- *cold = -1;
-
- for (i = 0; i < sizeof(dibusb_devices)/sizeof(struct dibusb_usb_device); i++) {
- for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].cold_ids[j] != NULL; j++) {
- deb_info("check for cold %x %x\n",dibusb_devices[i].cold_ids[j]->idVendor, dibusb_devices[i].cold_ids[j]->idProduct);
- if (dibusb_devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
- dibusb_devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
- *cold = 1;
- dev = &dibusb_devices[i];
- break;
- }
- }
-
- if (dev != NULL)
- break;
-
- for (j = 0; j < DIBUSB_ID_MAX_NUM && dibusb_devices[i].warm_ids[j] != NULL; j++) {
- deb_info("check for warm %x %x\n",dibusb_devices[i].warm_ids[j]->idVendor, dibusb_devices[i].warm_ids[j]->idProduct);
- if (dibusb_devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
- dibusb_devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
- *cold = 0;
- dev = &dibusb_devices[i];
- break;
- }
- }
- }
-
- if (dev != NULL)
- dev = dibusb_device_class_quirk(udev,dev);
-
- return dev;
-}
-
-/*
- * USB
- */
-static int dibusb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct usb_dibusb *dib = NULL;
- struct dibusb_usb_device *dibdev = NULL;
-
- int ret = -ENOMEM,cold=0;
-
- if ((dibdev = dibusb_find_device(udev,&cold)) == NULL) {
- err("something went very wrong, "
- "unknown product ID: %.4x",le16_to_cpu(udev->descriptor.idProduct));
- return -ENODEV;
- }
-
- if (cold == 1) {
- info("found a '%s' in cold state, will try to load a firmware",dibdev->name);
- ret = dibusb_loadfirmware(udev,dibdev);
- } else {
- info("found a '%s' in warm state.",dibdev->name);
- dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL);
- if (dib == NULL) {
- err("no memory");
- return ret;
- }
- memset(dib,0,sizeof(struct usb_dibusb));
-
- dib->udev = udev;
- dib->dibdev = dibdev;
-
- /* store parameters to structures */
- dib->rc_query_interval = rc_query_interval;
- dib->pid_parse = pid_parse;
- dib->rc_key_repeat_count = rc_key_repeat_count;
-
- usb_set_intfdata(intf, dib);
-
- ret = dibusb_init(dib);
- }
-
- if (ret == 0)
- info("%s successfully initialized and connected.",dibdev->name);
- else
- info("%s error while loading driver (%d)",dibdev->name,ret);
- return ret;
-}
-
-static void dibusb_disconnect(struct usb_interface *intf)
-{
- struct usb_dibusb *dib = usb_get_intfdata(intf);
- const char *name = DRIVER_DESC;
-
- usb_set_intfdata(intf,NULL);
- if (dib != NULL && dib->dibdev != NULL) {
- name = dib->dibdev->name;
- dibusb_exit(dib);
- }
- info("%s successfully deinitialized and disconnected.",name);
-
-}
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver dibusb_driver = {
- .owner = THIS_MODULE,
- .name = DRIVER_DESC,
- .probe = dibusb_probe,
- .disconnect = dibusb_disconnect,
- .id_table = dib_table,
-};
-
-/* module stuff */
-static int __init usb_dibusb_init(void)
-{
- int result;
- if ((result = usb_register(&dibusb_driver))) {
- err("usb_register failed. Error number %d",result);
- return result;
- }
-
- return 0;
-}
-
-static void __exit usb_dibusb_exit(void)
-{
- /* deregister this driver from the USB subsystem */
- usb_deregister(&dibusb_driver);
-}
-
-module_init (usb_dibusb_init);
-module_exit (usb_dibusb_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
deleted file mode 100644
index 400b439e804..00000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * dvb-dibusb-dvb.c is part of the driver for mobile USB Budget DVB-T devices
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for initializing and handling the
- * linux-dvb API.
- */
-#include "dvb-dibusb.h"
-
-#include <linux/usb.h>
-#include <linux/version.h>
-
-static u32 urb_compl_count;
-
-/*
- * MPEG2 TS DVB stuff
- */
-void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
-{
- struct usb_dibusb *dib = urb->context;
-
- deb_ts("urb complete feedcount: %d, status: %d, length: %d\n",dib->feedcount,urb->status,
- urb->actual_length);
-
- urb_compl_count++;
- if (urb_compl_count % 1000 == 0)
- deb_info("%d urbs completed so far.\n",urb_compl_count);
-
- switch (urb->status) {
- case 0: /* success */
- case -ETIMEDOUT: /* NAK */
- break;
- case -ECONNRESET: /* kill */
- case -ENOENT:
- case -ESHUTDOWN:
- return;
- default: /* error */
- deb_ts("urb completition error %d.", urb->status);
- break;
- }
-
- if (dib->feedcount > 0 && urb->actual_length > 0) {
- if (dib->init_state & DIBUSB_STATE_DVB)
- dvb_dmx_swfilter(&dib->demux, (u8*) urb->transfer_buffer,urb->actual_length);
- } else
- deb_ts("URB dropped because of feedcount.\n");
-
- usb_submit_urb(urb,GFP_ATOMIC);
-}
-
-static int dibusb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
-{
- struct usb_dibusb *dib = dvbdmxfeed->demux->priv;
- int newfeedcount;
-
- if (dib == NULL)
- return -ENODEV;
-
- newfeedcount = dib->feedcount + (onoff ? 1 : -1);
-
- /*
- * stop feed before setting a new pid if there will be no pid anymore
- */
- if (newfeedcount == 0) {
- deb_ts("stop feeding\n");
- if (dib->xfer_ops.fifo_ctrl != NULL) {
- if (dib->xfer_ops.fifo_ctrl(dib->fe,0)) {
- err("error while inhibiting fifo.");
- return -ENODEV;
- }
- }
- dibusb_streaming(dib,0);
- }
-
- dib->feedcount = newfeedcount;
-
- /* activate the pid on the device specific pid_filter */
- deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
- if (dib->pid_parse && dib->xfer_ops.pid_ctrl != NULL)
- dib->xfer_ops.pid_ctrl(dib->fe,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
-
- /*
- * start the feed if this was the first pid to set and there is still a pid
- * for reception.
- */
- if (dib->feedcount == onoff && dib->feedcount > 0) {
-
- deb_ts("controlling pid parser\n");
- if (dib->xfer_ops.pid_parse != NULL) {
- if (dib->xfer_ops.pid_parse(dib->fe,dib->pid_parse) < 0) {
- err("could not handle pid_parser");
- }
- }
-
- deb_ts("start feeding\n");
- if (dib->xfer_ops.fifo_ctrl != NULL) {
- if (dib->xfer_ops.fifo_ctrl(dib->fe,1)) {
- err("error while enabling fifo.");
- return -ENODEV;
- }
- }
- dibusb_streaming(dib,1);
- }
- return 0;
-}
-
-static int dibusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
- return dibusb_ctrl_feed(dvbdmxfeed,1);
-}
-
-static int dibusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
- return dibusb_ctrl_feed(dvbdmxfeed,0);
-}
-
-int dibusb_dvb_init(struct usb_dibusb *dib)
-{
- int ret;
-
- urb_compl_count = 0;
-
- if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC,
- THIS_MODULE)) < 0) {
- deb_info("dvb_register_adapter failed: error %d", ret);
- goto err;
- }
- dib->adapter.priv = dib;
-
-/* i2c is done in dibusb_i2c_init */
-
- dib->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
-
- dib->demux.priv = (void *)dib;
- /* get pidcount from demod */
- dib->demux.feednum = dib->demux.filternum = 255;
- dib->demux.start_feed = dibusb_start_feed;
- dib->demux.stop_feed = dibusb_stop_feed;
- dib->demux.write_to_decoder = NULL;
- if ((ret = dvb_dmx_init(&dib->demux)) < 0) {
- err("dvb_dmx_init failed: error %d",ret);
- goto err_dmx;
- }
-
- dib->dmxdev.filternum = dib->demux.filternum;
- dib->dmxdev.demux = &dib->demux.dmx;
- dib->dmxdev.capabilities = 0;
- if ((ret = dvb_dmxdev_init(&dib->dmxdev, &dib->adapter)) < 0) {
- err("dvb_dmxdev_init failed: error %d",ret);
- goto err_dmx_dev;
- }
-
- dvb_net_init(&dib->adapter, &dib->dvb_net, &dib->demux.dmx);
-
- goto success;
-err_dmx_dev:
- dvb_dmx_release(&dib->demux);
-err_dmx:
- dvb_unregister_adapter(&dib->adapter);
-err:
- return ret;
-success:
- dib->init_state |= DIBUSB_STATE_DVB;
- return 0;
-}
-
-int dibusb_dvb_exit(struct usb_dibusb *dib)
-{
- if (dib->init_state & DIBUSB_STATE_DVB) {
- dib->init_state &= ~DIBUSB_STATE_DVB;
- deb_info("unregistering DVB part\n");
- dvb_net_release(&dib->dvb_net);
- dib->demux.dmx.close(&dib->demux.dmx);
- dvb_dmxdev_release(&dib->dmxdev);
- dvb_dmx_release(&dib->demux);
- dvb_unregister_adapter(&dib->adapter);
- }
- return 0;
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
deleted file mode 100644
index 5a71b88797d..00000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * dvb-dibusb-fe-i2c.c is part of the driver for mobile USB Budget DVB-T devices
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for attaching, initializing of an appropriate
- * demodulator/frontend. I2C-stuff is also located here.
- *
- */
-#include "dvb-dibusb.h"
-
-#include <linux/usb.h>
-
-static int dibusb_i2c_msg(struct usb_dibusb *dib, u8 addr,
- u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
-{
- u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
- /* write only ? */
- int wo = (rbuf == NULL || rlen == 0),
- len = 2 + wlen + (wo ? 0 : 2);
-
- sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
- sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
-
- memcpy(&sndbuf[2],wbuf,wlen);
-
- if (!wo) {
- sndbuf[wlen+2] = (rlen >> 8) & 0xff;
- sndbuf[wlen+3] = rlen & 0xff;
- }
-
- return dibusb_readwrite_usb(dib,sndbuf,len,rbuf,rlen);
-}
-
-/*
- * I2C master xfer function
- */
-static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num)
-{
- struct usb_dibusb *dib = i2c_get_adapdata(adap);
- int i;
-
- if (down_interruptible(&dib->i2c_sem) < 0)
- return -EAGAIN;
-
- if (num > 2)
- warn("more than 2 i2c messages at a time is not handled yet. TODO.");
-
- for (i = 0; i < num; i++) {
- /* write/read request */
- if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
- if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,
- msg[i+1].buf,msg[i+1].len) < 0)
- break;
- i++;
- } else
- if (dibusb_i2c_msg(dib, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
- break;
- }
-
- up(&dib->i2c_sem);
- return i;
-}
-
-static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
-{
- return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm dibusb_algo = {
- .name = "DiBcom USB i2c algorithm",
- .id = I2C_ALGO_BIT,
- .master_xfer = dibusb_i2c_xfer,
- .functionality = dibusb_i2c_func,
-};
-
-static int dibusb_general_demod_init(struct dvb_frontend *fe);
-static u8 dibusb_general_pll_addr(struct dvb_frontend *fe);
-static int dibusb_general_pll_init(struct dvb_frontend *fe, u8 pll_buf[5]);
-static int dibusb_general_pll_set(struct dvb_frontend *fe,
- struct dvb_frontend_parameters* params, u8 pll_buf[5]);
-
-static struct mt352_config mt352_hanftek_umt_010_config = {
- .demod_address = 0x1e,
- .demod_init = dibusb_general_demod_init,
- .pll_set = dibusb_general_pll_set,
-};
-
-static int dibusb_tuner_quirk(struct usb_dibusb *dib)
-{
- switch (dib->dibdev->dev_cl->id) {
- case DIBUSB1_1: /* some these device have the ENV77H11D5 and some the THOMSON CABLE */
- case DIBUSB1_1_AN2235: { /* actually its this device, but in warm state they are indistinguishable */
- struct dibusb_tuner *t;
- u8 b[2] = { 0,0 } ,b2[1];
- struct i2c_msg msg[2] = {
- { .flags = 0, .buf = b, .len = 2 },
- { .flags = I2C_M_RD, .buf = b2, .len = 1},
- };
-
- t = &dibusb_tuner[DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5];
-
- msg[0].addr = msg[1].addr = t->pll_addr;
-
- if (dib->xfer_ops.tuner_pass_ctrl != NULL)
- dib->xfer_ops.tuner_pass_ctrl(dib->fe,1,t->pll_addr);
- dibusb_i2c_xfer(&dib->i2c_adap,msg,2);
- if (dib->xfer_ops.tuner_pass_ctrl != NULL)
- dib->xfer_ops.tuner_pass_ctrl(dib->fe,0,t->pll_addr);
-
- if (b2[0] == 0xfe)
- info("this device has the Thomson Cable onboard. Which is default.");
- else {
- dib->tuner = t;
- info("this device has the Panasonic ENV77H11D5 onboard.");
- }
- break;
- }
- default:
- break;
- }
- return 0;
-}
-
-int dibusb_fe_init(struct usb_dibusb* dib)
-{
- struct dib3000_config demod_cfg;
- int i;
-
- if (dib->init_state & DIBUSB_STATE_I2C) {
- for (i = 0; i < sizeof(dib->dibdev->dev_cl->demod->i2c_addrs) / sizeof(unsigned char) &&
- dib->dibdev->dev_cl->demod->i2c_addrs[i] != 0; i++) {
-
- demod_cfg.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
- demod_cfg.pll_addr = dibusb_general_pll_addr;
- demod_cfg.pll_set = dibusb_general_pll_set;
- demod_cfg.pll_init = dibusb_general_pll_init;
-
- deb_info("demod id: %d %d\n",dib->dibdev->dev_cl->demod->id,DTT200U_FE);
-
- switch (dib->dibdev->dev_cl->demod->id) {
- case DIBUSB_DIB3000MB:
- dib->fe = dib3000mb_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
- break;
- case DIBUSB_DIB3000MC:
- dib->fe = dib3000mc_attach(&demod_cfg,&dib->i2c_adap,&dib->xfer_ops);
- break;
- case DIBUSB_MT352:
- mt352_hanftek_umt_010_config.demod_address = dib->dibdev->dev_cl->demod->i2c_addrs[i];
- dib->fe = mt352_attach(&mt352_hanftek_umt_010_config, &dib->i2c_adap);
- break;
- case DTT200U_FE:
- dib->fe = dtt200u_fe_attach(dib,&dib->xfer_ops);
- break;
- }
- if (dib->fe != NULL) {
- info("found demodulator at i2c address 0x%x",dib->dibdev->dev_cl->demod->i2c_addrs[i]);
- break;
- }
- }
- /* if a frontend was found */
- if (dib->fe != NULL) {
- if (dib->fe->ops->sleep != NULL)
- dib->fe_sleep = dib->fe->ops->sleep;
- dib->fe->ops->sleep = dibusb_hw_sleep;
-
- if (dib->fe->ops->init != NULL )
- dib->fe_init = dib->fe->ops->init;
- dib->fe->ops->init = dibusb_hw_wakeup;
-
- /* setting the default tuner */
- dib->tuner = dib->dibdev->dev_cl->tuner;
-
- /* check which tuner is mounted on this device, in case this is unsure */
- dibusb_tuner_quirk(dib);
- }
- }
- if (dib->fe == NULL) {
- err("A frontend driver was not found for device '%s'.",
- dib->dibdev->name);
- return -ENODEV;
- } else {
- if (dvb_register_frontend(&dib->adapter, dib->fe)) {
- err("Frontend registration failed.");
- if (dib->fe->ops->release)
- dib->fe->ops->release(dib->fe);
- dib->fe = NULL;
- return -ENODEV;
- }
- }
-
- return 0;
-}
-
-int dibusb_fe_exit(struct usb_dibusb *dib)
-{
- if (dib->fe != NULL)
- dvb_unregister_frontend(dib->fe);
- return 0;
-}
-
-int dibusb_i2c_init(struct usb_dibusb *dib)
-{
- int ret = 0;
-
- dib->adapter.priv = dib;
-
- strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE);
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- dib->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
-#else
- dib->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
-#endif
- dib->i2c_adap.algo = &dibusb_algo;
- dib->i2c_adap.algo_data = NULL;
- dib->i2c_adap.id = I2C_ALGO_BIT;
-
- i2c_set_adapdata(&dib->i2c_adap, dib);
-
- if ((ret = i2c_add_adapter(&dib->i2c_adap)) < 0)
- err("could not add i2c adapter");
-
- dib->init_state |= DIBUSB_STATE_I2C;
-
- return ret;
-}
-
-int dibusb_i2c_exit(struct usb_dibusb *dib)
-{
- if (dib->init_state & DIBUSB_STATE_I2C)
- i2c_del_adapter(&dib->i2c_adap);
- dib->init_state &= ~DIBUSB_STATE_I2C;
- return 0;
-}
-
-
-/* pll stuff, maybe removed soon (thx to Gerd/Andrew in advance) */
-static int thomson_cable_eu_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
-{
- u32 tfreq = (fep->frequency + 36125000) / 62500;
- int vu,p0,p1,p2;
-
- if (fep->frequency > 403250000)
- vu = 1, p2 = 1, p1 = 0, p0 = 1;
- else if (fep->frequency > 115750000)
- vu = 0, p2 = 1, p1 = 1, p0 = 0;
- else if (fep->frequency > 44250000)
- vu = 0, p2 = 0, p1 = 1, p0 = 1;
- else
- return -EINVAL;
-
- pllbuf[0] = (tfreq >> 8) & 0x7f;
- pllbuf[1] = tfreq & 0xff;
- pllbuf[2] = 0x8e;
- pllbuf[3] = (vu << 7) | (p2 << 2) | (p1 << 1) | p0;
- return 0;
-}
-
-static int panasonic_cofdm_env57h1xd5_pll_set(struct dvb_frontend_parameters *fep, u8 pllbuf[4])
-{
- u32 freq_khz = fep->frequency / 1000;
- u32 tfreq = ((freq_khz + 36125)*6 + 500) / 1000;
- u8 TA, T210, R210, ctrl1, cp210, p4321;
- if (freq_khz > 858000) {
- err("frequency cannot be larger than 858 MHz.");
- return -EINVAL;
- }
-
- // contol data 1 : 1 | T/A=1 | T2,T1,T0 = 0,0,0 | R2,R1,R0 = 0,1,0
- TA = 1;
- T210 = 0;
- R210 = 0x2;
- ctrl1 = (1 << 7) | (TA << 6) | (T210 << 3) | R210;
-
-// ******** CHARGE PUMP CONFIG vs RF FREQUENCIES *****************
- if (freq_khz < 470000)
- cp210 = 2; // VHF Low and High band ch E12 to E4 to E12
- else if (freq_khz < 526000)
- cp210 = 4; // UHF band Ch E21 to E27
- else // if (freq < 862000000)
- cp210 = 5; // UHF band ch E28 to E69
-
-//********************* BW select *******************************
- if (freq_khz < 153000)
- p4321 = 1; // BW selected for VHF low
- else if (freq_khz < 470000)
- p4321 = 2; // BW selected for VHF high E5 to E12
- else // if (freq < 862000000)
- p4321 = 4; // BW selection for UHF E21 to E69
-
- pllbuf[0] = (tfreq >> 8) & 0xff;
- pllbuf[1] = (tfreq >> 0) & 0xff;
- pllbuf[2] = 0xff & ctrl1;
- pllbuf[3] = (cp210 << 5) | (p4321);
-
- return 0;
-}
-
-/*
- * 7 6 5 4 3 2 1 0
- * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0
- *
- * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8
- * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0
- *
- * Control byte 1 1 T/A=1 T2 T1 T0 R2 R1 R0
- * 1 T/A=0 0 0 ATC AL2 AL1 AL0
- *
- * Control byte 2 CP2 CP1 CP0 BS5 BS4 BS3 BS2 BS1
- *
- * MA0/1 = programmable address bits
- * R/~W = read/write bit (0 for writing)
- * N14-0 = programmable LO frequency
- *
- * T/A = test AGC bit (0 = next 6 bits AGC setting,
- * 1 = next 6 bits test and reference divider ratio settings)
- * T2-0 = test bits
- * R2-0 = reference divider ratio and programmable frequency step
- * ATC = AGC current setting and time constant
- * ATC = 0: AGC current = 220nA, AGC time constant = 2s
- * ATC = 1: AGC current = 9uA, AGC time constant = 50ms
- * AL2-0 = AGC take-over point bits
- * CP2-0 = charge pump current
- * BS5-1 = PMOS ports control bits;
- * BSn = 0 corresponding port is off, high-impedance state (at power-on)
- * BSn = 1 corresponding port is on
- */
-static int panasonic_cofdm_env77h11d5_tda6650_init(struct dvb_frontend *fe, u8 pllbuf[4])
-{
- pllbuf[0] = 0x0b;
- pllbuf[1] = 0xf5;
- pllbuf[2] = 0x85;
- pllbuf[3] = 0xab;
- return 0;
-}
-
-static int panasonic_cofdm_env77h11d5_tda6650_set (struct dvb_frontend_parameters *fep,u8 pllbuf[4])
-{
- int tuner_frequency = 0;
- u8 band, cp, filter;
-
- // determine charge pump
- tuner_frequency = fep->frequency + 36166000;
- if (tuner_frequency < 87000000)
- return -EINVAL;
- else if (tuner_frequency < 130000000)
- cp = 3;
- else if (tuner_frequency < 160000000)
- cp = 5;
- else if (tuner_frequency < 200000000)
- cp = 6;
- else if (tuner_frequency < 290000000)
- cp = 3;
- else if (tuner_frequency < 420000000)
- cp = 5;
- else if (tuner_frequency < 480000000)
- cp = 6;
- else if (tuner_frequency < 620000000)
- cp = 3;
- else if (tuner_frequency < 830000000)
- cp = 5;
- else if (tuner_frequency < 895000000)
- cp = 7;
- else
- return -EINVAL;
-
- // determine band
- if (fep->frequency < 49000000)
- return -EINVAL;
- else if (fep->frequency < 161000000)
- band = 1;
- else if (fep->frequency < 444000000)
- band = 2;
- else if (fep->frequency < 861000000)
- band = 4;
- else
- return -EINVAL;
-
- // setup PLL filter
- switch (fep->u.ofdm.bandwidth) {
- case BANDWIDTH_6_MHZ:
- case BANDWIDTH_7_MHZ:
- filter = 0;
- break;
- case BANDWIDTH_8_MHZ:
- filter = 1;
- break;
- default:
- return -EINVAL;
- }
-
- // calculate divisor
- // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
- tuner_frequency = (((fep->frequency / 1000) * 6) + 217496) / 1000;
-
- // setup tuner buffer
- pllbuf[0] = (tuner_frequency >> 8) & 0x7f;
- pllbuf[1] = tuner_frequency & 0xff;
- pllbuf[2] = 0xca;
- pllbuf[3] = (cp << 5) | (filter << 3) | band;
- return 0;
-}
-
-/*
- * 7 6 5 4 3 2 1 0
- * Address Byte 1 1 0 0 0 MA1 MA0 R/~W=0
- *
- * Program divider byte 1 0 n14 n13 n12 n11 n10 n9 n8
- * Program divider byte 2 n7 n6 n5 n4 n3 n2 n1 n0
- *
- * Control byte 1 CP T2 T1 T0 RSA RSB OS
- *
- * Band Switch byte X X X P4 P3 P2 P1 P0
- *
- * Auxiliary byte ATC AL2 AL1 AL0 0 0 0 0
- *
- * Address: MA1 MA0 Address
- * 0 0 c0
- * 0 1 c2 (always valid)
- * 1 0 c4
- * 1 1 c6
- */
-static int lg_tdtp_e102p_tua6034(struct dvb_frontend_parameters* fep, u8 pllbuf[4])
-{
- u32 div;
- u8 p210, p3;
-
-#define TUNER_MUL 62500
-
- div = (fep->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL;
-// div = ((fep->frequency/1000 + 36166) * 6) / 1000;
-
- if (fep->frequency < 174500000)
- p210 = 1; // not supported by the tdtp_e102p
- else if (fep->frequency < 230000000) // VHF
- p210 = 2;
- else
- p210 = 4;
-
- if (fep->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
- p3 = 0;
- else
- p3 = 1;
-
- pllbuf[0] = (div >> 8) & 0x7f;
- pllbuf[1] = div & 0xff;
- pllbuf[2] = 0xce;
-// pllbuf[2] = 0xcc;
- pllbuf[3] = (p3 << 3) | p210;
-
- return 0;
-}
-
-static int lg_tdtp_e102p_mt352_demod_init(struct dvb_frontend *fe)
-{
- static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
- static u8 mt352_reset[] = { 0x50, 0x80 };
- static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
- static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
- static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
-
- static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
- static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
- static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
- static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
- static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
-
- static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
- static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
-
- mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
- udelay(2000);
- mt352_write(fe, mt352_reset, sizeof(mt352_reset));
- mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
-
- mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
- mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
-
- mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
- mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
- mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
- mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
- mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
-
- mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
- mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
-
- return 0;
-}
-
-static int dibusb_general_demod_init(struct dvb_frontend *fe)
-{
- struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
- switch (dib->dibdev->dev_cl->id) {
- case UMT2_0:
- return lg_tdtp_e102p_mt352_demod_init(fe);
- default: /* other device classes do not have device specific demod inits */
- break;
- }
- return 0;
-}
-
-static u8 dibusb_general_pll_addr(struct dvb_frontend *fe)
-{
- struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
- return dib->tuner->pll_addr;
-}
-
-static int dibusb_pll_i2c_helper(struct usb_dibusb *dib, u8 pll_buf[5], u8 buf[4])
-{
- if (pll_buf == NULL) {
- struct i2c_msg msg = {
- .addr = dib->tuner->pll_addr,
- .flags = 0,
- .buf = buf,
- .len = sizeof(buf)
- };
- if (i2c_transfer (&dib->i2c_adap, &msg, 1) != 1)
- return -EIO;
- msleep(1);
- } else {
- pll_buf[0] = dib->tuner->pll_addr << 1;
- memcpy(&pll_buf[1],buf,4);
- }
-
- return 0;
-}
-
-static int dibusb_general_pll_init(struct dvb_frontend *fe,
- u8 pll_buf[5])
-{
- struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
- u8 buf[4];
- int ret=0;
- switch (dib->tuner->id) {
- case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
- ret = panasonic_cofdm_env77h11d5_tda6650_init(fe,buf);
- break;
- default:
- break;
- }
-
- if (ret)
- return ret;
-
- return dibusb_pll_i2c_helper(dib,pll_buf,buf);
-}
-
-static int dibusb_general_pll_set(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *fep, u8 pll_buf[5])
-{
- struct usb_dibusb* dib = (struct usb_dibusb*) fe->dvb->priv;
- u8 buf[4];
- int ret=0;
-
- switch (dib->tuner->id) {
- case DIBUSB_TUNER_CABLE_THOMSON:
- ret = thomson_cable_eu_pll_set(fep, buf);
- break;
- case DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5:
- ret = panasonic_cofdm_env57h1xd5_pll_set(fep, buf);
- break;
- case DIBUSB_TUNER_CABLE_LG_TDTP_E102P:
- ret = lg_tdtp_e102p_tua6034(fep, buf);
- break;
- case DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5:
- ret = panasonic_cofdm_env77h11d5_tda6650_set(fep,buf);
- break;
- default:
- warn("no pll programming routine found for tuner %d.\n",dib->tuner->id);
- ret = -ENODEV;
- break;
- }
-
- if (ret)
- return ret;
-
- return dibusb_pll_i2c_helper(dib,pll_buf,buf);
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c b/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
deleted file mode 100644
index 504ba47afdf..00000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-firmware.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * dvb-dibusb-firmware.c is part of the driver for mobile USB Budget DVB-T devices
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for downloading the firmware to the device.
- */
-#include "dvb-dibusb.h"
-
-#include <linux/firmware.h>
-#include <linux/usb.h>
-
-/*
- * load a firmware packet to the device
- */
-static int dibusb_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
-{
- return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
- 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
-}
-
-int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev)
-{
- const struct firmware *fw = NULL;
- u16 addr;
- u8 *b,*p;
- int ret = 0,i;
-
- if ((ret = request_firmware(&fw, dibdev->dev_cl->firmware, &udev->dev)) != 0) {
- err("did not find the firmware file. (%s) "
- "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
- dibdev->dev_cl->firmware);
- return ret;
- }
-
- info("downloading firmware from file '%s'.",dibdev->dev_cl->firmware);
-
- p = kmalloc(fw->size,GFP_KERNEL);
- if (p != NULL) {
- u8 reset;
- /*
- * you cannot use the fw->data as buffer for
- * usb_control_msg, a new buffer has to be
- * created
- */
- memcpy(p,fw->data,fw->size);
-
- /* stop the CPU */
- reset = 1;
- if ((ret = dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1)) != 1)
- err("could not stop the USB controller CPU.");
- for(i = 0; p[i+3] == 0 && i < fw->size; ) {
- b = (u8 *) &p[i];
- addr = *((u16 *) &b[1]);
-
- ret = dibusb_writemem(udev,addr,&b[4],b[0]);
-
- if (ret != b[0]) {
- err("error while transferring firmware "
- "(transferred size: %d, block size: %d)",
- ret,b[0]);
- ret = -EINVAL;
- break;
- }
- i += 5 + b[0];
- }
- /* length in ret */
- if (ret > 0)
- ret = 0;
- /* restart the CPU */
- reset = 0;
- if (ret || dibusb_writemem(udev,dibdev->dev_cl->usb_ctrl->cpu_cs_register,&reset,1) != 1) {
- err("could not restart the USB controller CPU.");
- ret = -EINVAL;
- }
-
- kfree(p);
- } else {
- ret = -ENOMEM;
- }
- release_firmware(fw);
-
- return ret;
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c b/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
deleted file mode 100644
index 9dc8b15517b..00000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-remote.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * dvb-dibusb-remote.c is part of the driver for mobile USB Budget DVB-T devices
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for handling the event device on the software
- * side and the remote control on the hardware side.
- */
-#include "dvb-dibusb.h"
-
-/* Table to map raw key codes to key events. This should not be hard-wired
- into the kernel. */
-static const struct { u8 c0, c1, c2; uint32_t key; } nec_rc_keys [] =
-{
- /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
- { 0x00, 0xff, 0x16, KEY_POWER },
- { 0x00, 0xff, 0x10, KEY_MUTE },
- { 0x00, 0xff, 0x03, KEY_1 },
- { 0x00, 0xff, 0x01, KEY_2 },
- { 0x00, 0xff, 0x06, KEY_3 },
- { 0x00, 0xff, 0x09, KEY_4 },
- { 0x00, 0xff, 0x1d, KEY_5 },
- { 0x00, 0xff, 0x1f, KEY_6 },
- { 0x00, 0xff, 0x0d, KEY_7 },
- { 0x00, 0xff, 0x19, KEY_8 },
- { 0x00, 0xff, 0x1b, KEY_9 },
- { 0x00, 0xff, 0x15, KEY_0 },
- { 0x00, 0xff, 0x05, KEY_CHANNELUP },
- { 0x00, 0xff, 0x02, KEY_CHANNELDOWN },
- { 0x00, 0xff, 0x1e, KEY_VOLUMEUP },
- { 0x00, 0xff, 0x0a, KEY_VOLUMEDOWN },
- { 0x00, 0xff, 0x11, KEY_RECORD },
- { 0x00, 0xff, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
- { 0x00, 0xff, 0x14, KEY_PLAY },
- { 0x00, 0xff, 0x1a, KEY_STOP },
- { 0x00, 0xff, 0x40, KEY_REWIND },
- { 0x00, 0xff, 0x12, KEY_FASTFORWARD },
- { 0x00, 0xff, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
- { 0x00, 0xff, 0x4c, KEY_PAUSE },
- { 0x00, 0xff, 0x4d, KEY_SCREEN }, /* Full screen mode. */
- { 0x00, 0xff, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
- /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
- { 0x00, 0xff, 0x0c, KEY_CANCEL }, /* Cancel */
- { 0x00, 0xff, 0x1c, KEY_EPG }, /* EPG */
- { 0x00, 0xff, 0x00, KEY_TAB }, /* Tab */
- { 0x00, 0xff, 0x48, KEY_INFO }, /* Preview */
- { 0x00, 0xff, 0x04, KEY_LIST }, /* RecordList */
- { 0x00, 0xff, 0x0f, KEY_TEXT }, /* Teletext */
- /* Key codes for the KWorld/ADSTech/JetWay remote. */
- { 0x86, 0x6b, 0x12, KEY_POWER },
- { 0x86, 0x6b, 0x0f, KEY_SELECT }, /* source */
- { 0x86, 0x6b, 0x0c, KEY_UNKNOWN }, /* scan */
- { 0x86, 0x6b, 0x0b, KEY_EPG },
- { 0x86, 0x6b, 0x10, KEY_MUTE },
- { 0x86, 0x6b, 0x01, KEY_1 },
- { 0x86, 0x6b, 0x02, KEY_2 },
- { 0x86, 0x6b, 0x03, KEY_3 },
- { 0x86, 0x6b, 0x04, KEY_4 },
- { 0x86, 0x6b, 0x05, KEY_5 },
- { 0x86, 0x6b, 0x06, KEY_6 },
- { 0x86, 0x6b, 0x07, KEY_7 },
- { 0x86, 0x6b, 0x08, KEY_8 },
- { 0x86, 0x6b, 0x09, KEY_9 },
- { 0x86, 0x6b, 0x0a, KEY_0 },
- { 0x86, 0x6b, 0x18, KEY_ZOOM },
- { 0x86, 0x6b, 0x1c, KEY_UNKNOWN }, /* preview */
- { 0x86, 0x6b, 0x13, KEY_UNKNOWN }, /* snap */
- { 0x86, 0x6b, 0x00, KEY_UNDO },
- { 0x86, 0x6b, 0x1d, KEY_RECORD },
- { 0x86, 0x6b, 0x0d, KEY_STOP },
- { 0x86, 0x6b, 0x0e, KEY_PAUSE },
- { 0x86, 0x6b, 0x16, KEY_PLAY },
- { 0x86, 0x6b, 0x11, KEY_BACK },
- { 0x86, 0x6b, 0x19, KEY_FORWARD },
- { 0x86, 0x6b, 0x14, KEY_UNKNOWN }, /* pip */
- { 0x86, 0x6b, 0x15, KEY_ESC },
- { 0x86, 0x6b, 0x1a, KEY_UP },
- { 0x86, 0x6b, 0x1e, KEY_DOWN },
- { 0x86, 0x6b, 0x1f, KEY_LEFT },
- { 0x86, 0x6b, 0x1b, KEY_RIGHT },
-};
-
-/* Hauppauge NOVA-T USB2 keys */
-static const struct { u16 raw; uint32_t key; } haupp_rc_keys [] = {
- { 0xddf, KEY_GOTO },
- { 0xdef, KEY_POWER },
- { 0xce7, KEY_TV },
- { 0xcc7, KEY_VIDEO },
- { 0xccf, KEY_AUDIO },
- { 0xcd7, KEY_MEDIA },
- { 0xcdf, KEY_EPG },
- { 0xca7, KEY_UP },
- { 0xc67, KEY_RADIO },
- { 0xcb7, KEY_LEFT },
- { 0xd2f, KEY_OK },
- { 0xcbf, KEY_RIGHT },
- { 0xcff, KEY_BACK },
- { 0xcaf, KEY_DOWN },
- { 0xc6f, KEY_MENU },
- { 0xc87, KEY_VOLUMEUP },
- { 0xc8f, KEY_VOLUMEDOWN },
- { 0xc97, KEY_CHANNEL },
- { 0xc7f, KEY_MUTE },
- { 0xd07, KEY_CHANNELUP },
- { 0xd0f, KEY_CHANNELDOWN },
- { 0xdbf, KEY_RECORD },
- { 0xdb7, KEY_STOP },
- { 0xd97, KEY_REWIND },
- { 0xdaf, KEY_PLAY },
- { 0xda7, KEY_FASTFORWARD },
- { 0xd27, KEY_LAST }, /* Skip backwards */
- { 0xd87, KEY_PAUSE },
- { 0xcf7, KEY_NEXT },
- { 0xc07, KEY_0 },
- { 0xc0f, KEY_1 },
- { 0xc17, KEY_2 },
- { 0xc1f, KEY_3 },
- { 0xc27, KEY_4 },
- { 0xc2f, KEY_5 },
- { 0xc37, KEY_6 },
- { 0xc3f, KEY_7 },
- { 0xc47, KEY_8 },
- { 0xc4f, KEY_9 },
- { 0xc57, KEY_KPASTERISK },
- { 0xc77, KEY_GRAVE }, /* # */
- { 0xc5f, KEY_RED },
- { 0xd77, KEY_GREEN },
- { 0xdc7, KEY_YELLOW },
- { 0xd4f, KEY_BLUE},
-};
-
-static int dibusb_key2event_nec(struct usb_dibusb *dib,u8 rb[5])
-{
- int i;
- switch (rb[0]) {
- case DIBUSB_RC_NEC_KEY_PRESSED:
- /* rb[1-3] is the actual key, rb[4] is a checksum */
- deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
- rb[1], rb[2], rb[3], rb[4]);
-
- if ((0xff - rb[3]) != rb[4]) {
- deb_rc("remote control checksum failed.\n");
- break;
- }
-
- /* See if we can match the raw key code. */
- for (i = 0; i < sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++) {
- if (nec_rc_keys[i].c0 == rb[1] &&
- nec_rc_keys[i].c1 == rb[2] &&
- nec_rc_keys[i].c2 == rb[3]) {
-
- dib->last_event = nec_rc_keys[i].key;
- return 1;
- }
- }
- break;
- case DIBUSB_RC_NEC_KEY_REPEATED:
- /* rb[1]..rb[4] are always zero.*/
- /* Repeats often seem to occur so for the moment just ignore this. */
- return 0;
- case DIBUSB_RC_NEC_EMPTY: /* No (more) remote control keys. */
- default:
- break;
- }
- return -1;
-}
-
-static int dibusb_key2event_hauppauge(struct usb_dibusb *dib,u8 rb[4])
-{
- u16 raw;
- int i,state;
- switch (rb[0]) {
- case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
- raw = ((rb[1] & 0x0f) << 8) | rb[2];
-
- state = !!(rb[1] & 0x40);
-
- deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to %04x state: %d\n",rb[1],rb[2],rb[3],raw,state);
- for (i = 0; i < sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++) {
- if (haupp_rc_keys[i].raw == raw) {
- if (dib->last_event == haupp_rc_keys[i].key &&
- dib->last_state == state) {
- deb_rc("key repeat\n");
- return 0;
- } else {
- dib->last_event = haupp_rc_keys[i].key;
- dib->last_state = state;
- return 1;
- }
- }
- }
-
- break;
- case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
- default:
- break;
- }
- return -1;
-}
-
-/*
- * Read the remote control and feed the appropriate event.
- * NEC protocol is used for remote controls
- */
-static int dibusb_read_remote_control(struct usb_dibusb *dib)
-{
- u8 b[1] = { DIBUSB_REQ_POLL_REMOTE }, rb[5];
- int ret,event = 0;
-
- if ((ret = dibusb_readwrite_usb(dib,b,1,rb,5)))
- return ret;
-
- switch (dib->dibdev->dev_cl->remote_type) {
- case DIBUSB_RC_NEC_PROTOCOL:
- event = dibusb_key2event_nec(dib,rb);
- break;
- case DIBUSB_RC_HAUPPAUGE_PROTO:
- event = dibusb_key2event_hauppauge(dib,rb);
- default:
- break;
- }
-
- /* key repeat */
- if (event == 0)
- if (++dib->repeat_key_count < dib->rc_key_repeat_count) {
- deb_rc("key repeat dropped. (%d)\n",dib->repeat_key_count);
- event = -1; /* skip this key repeat */
- }
-
- if (event == 1 || event == 0) {
- deb_rc("Translated key 0x%04x\n",event);
-
- /* Signal down and up events for this key. */
- input_report_key(&dib->rc_input_dev, dib->last_event, 1);
- input_report_key(&dib->rc_input_dev, dib->last_event, 0);
- input_sync(&dib->rc_input_dev);
-
- if (event == 1)
- dib->repeat_key_count = 0;
- }
- return 0;
-}
-
-/* Remote-control poll function - called every dib->rc_query_interval ms to see
- whether the remote control has received anything. */
-static void dibusb_remote_query(void *data)
-{
- struct usb_dibusb *dib = (struct usb_dibusb *) data;
- /* TODO: need a lock here. We can simply skip checking for the remote control
- if we're busy. */
- dibusb_read_remote_control(dib);
- schedule_delayed_work(&dib->rc_query_work,
- msecs_to_jiffies(dib->rc_query_interval));
-}
-
-int dibusb_remote_init(struct usb_dibusb *dib)
-{
- int i;
-
- if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
- return 0;
-
- /* Initialise the remote-control structures.*/
- init_input_dev(&dib->rc_input_dev);
-
- dib->rc_input_dev.evbit[0] = BIT(EV_KEY);
- dib->rc_input_dev.keycodesize = sizeof(unsigned char);
- dib->rc_input_dev.keycodemax = KEY_MAX;
- dib->rc_input_dev.name = DRIVER_DESC " remote control";
-
- switch (dib->dibdev->dev_cl->remote_type) {
- case DIBUSB_RC_NEC_PROTOCOL:
- for (i=0; i<sizeof(nec_rc_keys)/sizeof(nec_rc_keys[0]); i++)
- set_bit(nec_rc_keys[i].key, dib->rc_input_dev.keybit);
- break;
- case DIBUSB_RC_HAUPPAUGE_PROTO:
- for (i=0; i<sizeof(haupp_rc_keys)/sizeof(haupp_rc_keys[0]); i++)
- set_bit(haupp_rc_keys[i].key, dib->rc_input_dev.keybit);
- break;
- default:
- break;
- }
-
-
- input_register_device(&dib->rc_input_dev);
-
- INIT_WORK(&dib->rc_query_work, dibusb_remote_query, dib);
-
- /* Start the remote-control polling. */
- if (dib->rc_query_interval < 40)
- dib->rc_query_interval = 100; /* default */
-
- info("schedule remote query interval to %d msecs.",dib->rc_query_interval);
- schedule_delayed_work(&dib->rc_query_work,msecs_to_jiffies(dib->rc_query_interval));
-
- dib->init_state |= DIBUSB_STATE_REMOTE;
-
- return 0;
-}
-
-int dibusb_remote_exit(struct usb_dibusb *dib)
-{
- if (dib->dibdev->dev_cl->remote_type == DIBUSB_RC_NO)
- return 0;
-
- if (dib->init_state & DIBUSB_STATE_REMOTE) {
- cancel_delayed_work(&dib->rc_query_work);
- flush_scheduled_work();
- input_unregister_device(&dib->rc_input_dev);
- }
- dib->init_state &= ~DIBUSB_STATE_REMOTE;
- return 0;
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
deleted file mode 100644
index 642f0596a5b..00000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * dvb-dibusb-usb.c is part of the driver for mobile USB Budget DVB-T devices
- * based on reference design made by DiBcom (http://www.dibcom.fr/)
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * see dvb-dibusb-core.c for more copyright details.
- *
- * This file contains functions for initializing and handling the
- * usb specific stuff.
- */
-#include "dvb-dibusb.h"
-
-#include <linux/version.h>
-#include <linux/pci.h>
-
-int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
- u16 rlen)
-{
- int actlen,ret = -ENOMEM;
-
- if (wbuf == NULL || wlen == 0)
- return -EINVAL;
-
- if ((ret = down_interruptible(&dib->usb_sem)))
- return ret;
-
- debug_dump(wbuf,wlen);
-
- ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev,
- dib->dibdev->dev_cl->pipe_cmd), wbuf,wlen,&actlen,
- DIBUSB_I2C_TIMEOUT);
-
- if (ret)
- err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
- else
- ret = actlen != wlen ? -1 : 0;
-
- /* an answer is expected, and no error before */
- if (!ret && rbuf && rlen) {
- ret = usb_bulk_msg(dib->udev,usb_rcvbulkpipe(dib->udev,
- dib->dibdev->dev_cl->pipe_cmd),rbuf,rlen,&actlen,
- DIBUSB_I2C_TIMEOUT);
-
- if (ret)
- err("recv bulk message failed: %d",ret);
- else {
- deb_alot("rlen: %d\n",rlen);
- debug_dump(rbuf,actlen);
- }
- }
-
- up(&dib->usb_sem);
- return ret;
-}
-
-/*
- * Cypress controls
- */
-int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len)
-{
- return dibusb_readwrite_usb(dib,buf,len,NULL,0);
-}
-
-#if 0
-/*
- * #if 0'ing the following functions as they are not in use _now_,
- * but probably will be sometime.
- */
-/*
- * do not use this, just a workaround for a bug,
- * which will hopefully never occur :).
- */
-int dibusb_interrupt_read_loop(struct usb_dibusb *dib)
-{
- u8 b[1] = { DIBUSB_REQ_INTR_READ };
- return dibusb_write_usb(dib,b,1);
-}
-#endif
-
-/*
- * ioctl for the firmware
- */
-static int dibusb_ioctl_cmd(struct usb_dibusb *dib, u8 cmd, u8 *param, int plen)
-{
- u8 b[34];
- int size = plen > 32 ? 32 : plen;
- memset(b,0,34);
- b[0] = DIBUSB_REQ_SET_IOCTL;
- b[1] = cmd;
-
- if (size > 0)
- memcpy(&b[2],param,size);
-
- return dibusb_write_usb(dib,b,34); //2+size);
-}
-
-/*
- * ioctl for power control
- */
-int dibusb_hw_wakeup(struct dvb_frontend *fe)
-{
- struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
- u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP };
- deb_info("dibusb-device is getting up.\n");
-
- switch (dib->dibdev->dev_cl->id) {
- case DTT200U:
- break;
- default:
- dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
- break;
- }
-
- if (dib->fe_init)
- return dib->fe_init(fe);
-
- return 0;
-}
-
-int dibusb_hw_sleep(struct dvb_frontend *fe)
-{
- struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
- u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP };
- deb_info("dibusb-device is going to bed.\n");
- /* workaround, something is wrong, when dibusb 1.1 device are going to bed too late */
- switch (dib->dibdev->dev_cl->id) {
- case DIBUSB1_1:
- case NOVAT_USB2:
- case DTT200U:
- break;
- default:
- dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
- break;
- }
- if (dib->fe_sleep)
- return dib->fe_sleep(fe);
-
- return 0;
-}
-
-int dibusb_set_streaming_mode(struct usb_dibusb *dib,u8 mode)
-{
- u8 b[2] = { DIBUSB_REQ_SET_STREAMING_MODE, mode };
- return dibusb_readwrite_usb(dib,b,2,NULL,0);
-}
-
-static int dibusb_urb_kill(struct usb_dibusb *dib)
-{
- int i;
-deb_info("trying to kill urbs\n");
- if (dib->init_state & DIBUSB_STATE_URB_SUBMIT) {
- for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
- deb_info("killing URB no. %d.\n",i);
-
- /* stop the URB */
- usb_kill_urb(dib->urb_list[i]);
- }
- } else
- deb_info(" URBs not killed.\n");
- dib->init_state &= ~DIBUSB_STATE_URB_SUBMIT;
- return 0;
-}
-
-static int dibusb_urb_submit(struct usb_dibusb *dib)
-{
- int i,ret;
- if (dib->init_state & DIBUSB_STATE_URB_INIT) {
- for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
- deb_info("submitting URB no. %d\n",i);
- if ((ret = usb_submit_urb(dib->urb_list[i],GFP_ATOMIC))) {
- err("could not submit buffer urb no. %d - get them all back\n",i);
- dibusb_urb_kill(dib);
- return ret;
- }
- dib->init_state |= DIBUSB_STATE_URB_SUBMIT;
- }
- }
- return 0;
-}
-
-int dibusb_streaming(struct usb_dibusb *dib,int onoff)
-{
- if (onoff)
- dibusb_urb_submit(dib);
- else
- dibusb_urb_kill(dib);
-
- switch (dib->dibdev->dev_cl->id) {
- case DIBUSB2_0:
- case DIBUSB2_0B:
- case NOVAT_USB2:
- case UMT2_0:
- if (onoff)
- return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0);
- else
- return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_DISABLE_STREAM,NULL,0);
- break;
- default:
- break;
- }
- return 0;
-}
-
-int dibusb_urb_init(struct usb_dibusb *dib)
-{
- int i,bufsize,def_pid_parse = 1;
-
- /*
- * when reloading the driver w/o replugging the device
- * a timeout occures, this helps
- */
- usb_clear_halt(dib->udev,usb_sndbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
- usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
- usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data));
-
- /* allocate the array for the data transfer URBs */
- dib->urb_list = kmalloc(dib->dibdev->dev_cl->urb_count*sizeof(struct urb *),GFP_KERNEL);
- if (dib->urb_list == NULL)
- return -ENOMEM;
- memset(dib->urb_list,0,dib->dibdev->dev_cl->urb_count*sizeof(struct urb *));
-
- dib->init_state |= DIBUSB_STATE_URB_LIST;
-
- bufsize = dib->dibdev->dev_cl->urb_count*dib->dibdev->dev_cl->urb_buffer_size;
- deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
- /* allocate the actual buffer for the URBs */
- if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) {
- deb_info("not enough memory.\n");
- return -ENOMEM;
- }
- deb_info("allocation complete\n");
- memset(dib->buffer,0,bufsize);
-
- dib->init_state |= DIBUSB_STATE_URB_BUF;
-
- /* allocate and submit the URBs */
- for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
- if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
- return -ENOMEM;
- }
-
- usb_fill_bulk_urb( dib->urb_list[i], dib->udev,
- usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data),
- &dib->buffer[i*dib->dibdev->dev_cl->urb_buffer_size],
- dib->dibdev->dev_cl->urb_buffer_size,
- dibusb_urb_complete, dib);
-
- dib->urb_list[i]->transfer_flags = 0;
-
- dib->init_state |= DIBUSB_STATE_URB_INIT;
- }
-
- /* dib->pid_parse here contains the value of the module parameter */
- /* decide if pid parsing can be deactivated:
- * is possible (by device type) and wanted (by user)
- */
- switch (dib->dibdev->dev_cl->id) {
- case DIBUSB2_0:
- case DIBUSB2_0B:
- if (dib->udev->speed == USB_SPEED_HIGH && !dib->pid_parse) {
- def_pid_parse = 0;
- info("running at HIGH speed, will deliver the complete TS.");
- } else
- info("will use pid_parsing.");
- break;
- default:
- break;
- }
- /* from here on it contains the device and user decision */
- dib->pid_parse = def_pid_parse;
-
- return 0;
-}
-
-int dibusb_urb_exit(struct usb_dibusb *dib)
-{
- int i;
-
- dibusb_urb_kill(dib);
-
- if (dib->init_state & DIBUSB_STATE_URB_LIST) {
- for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
- if (dib->urb_list[i] != NULL) {
- deb_info("freeing URB no. %d.\n",i);
- /* free the URBs */
- usb_free_urb(dib->urb_list[i]);
- }
- }
- /* free the urb array */
- kfree(dib->urb_list);
- dib->init_state &= ~DIBUSB_STATE_URB_LIST;
- }
-
- if (dib->init_state & DIBUSB_STATE_URB_BUF)
- pci_free_consistent(NULL,
- dib->dibdev->dev_cl->urb_buffer_size*dib->dibdev->dev_cl->urb_count,
- dib->buffer,dib->dma_handle);
-
- dib->init_state &= ~DIBUSB_STATE_URB_BUF;
- dib->init_state &= ~DIBUSB_STATE_URB_INIT;
- return 0;
-}
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb.h b/drivers/media/dvb/dibusb/dvb-dibusb.h
deleted file mode 100644
index c965b64fb1a..00000000000
--- a/drivers/media/dvb/dibusb/dvb-dibusb.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * dvb-dibusb.h
- *
- * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- * for more information see dvb-dibusb-core.c .
- */
-#ifndef __DVB_DIBUSB_H__
-#define __DVB_DIBUSB_H__
-
-#include <linux/input.h>
-#include <linux/config.h>
-#include <linux/usb.h>
-
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
-
-#include "dib3000.h"
-#include "mt352.h"
-
-/* debug */
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
-#define dprintk(level,args...) \
- do { if ((dvb_dibusb_debug & level)) { printk(args); } } while (0)
-
-#define debug_dump(b,l) {\
- int i; \
- for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \
- deb_xfer("\n");\
-}
-
-#else
-#define dprintk(args...)
-#define debug_dump(b,l)
-#endif
-
-extern int dvb_dibusb_debug;
-
-/* Version information */
-#define DRIVER_VERSION "0.3"
-#define DRIVER_DESC "DiBcom based USB Budget DVB-T device"
-#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
-
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_xfer(args...) dprintk(0x02,args)
-#define deb_alot(args...) dprintk(0x04,args)
-#define deb_ts(args...) dprintk(0x08,args)
-#define deb_err(args...) dprintk(0x10,args)
-#define deb_rc(args...) dprintk(0x20,args)
-
-/* generic log methods - taken from usb.h */
-#undef err
-#define err(format, arg...) printk(KERN_ERR "dvb-dibusb: " format "\n" , ## arg)
-#undef info
-#define info(format, arg...) printk(KERN_INFO "dvb-dibusb: " format "\n" , ## arg)
-#undef warn
-#define warn(format, arg...) printk(KERN_WARNING "dvb-dibusb: " format "\n" , ## arg)
-
-struct dibusb_usb_controller {
- const char *name; /* name of the usb controller */
- u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */
-};
-
-typedef enum {
- DIBUSB1_1 = 0,
- DIBUSB1_1_AN2235,
- DIBUSB2_0,
- UMT2_0,
- DIBUSB2_0B,
- NOVAT_USB2,
- DTT200U,
-} dibusb_class_t;
-
-typedef enum {
- DIBUSB_TUNER_CABLE_THOMSON = 0,
- DIBUSB_TUNER_COFDM_PANASONIC_ENV57H1XD5,
- DIBUSB_TUNER_CABLE_LG_TDTP_E102P,
- DIBUSB_TUNER_COFDM_PANASONIC_ENV77H11D5,
-} dibusb_tuner_t;
-
-typedef enum {
- DIBUSB_DIB3000MB = 0,
- DIBUSB_DIB3000MC,
- DIBUSB_MT352,
- DTT200U_FE,
-} dibusb_demodulator_t;
-
-typedef enum {
- DIBUSB_RC_NO = 0,
- DIBUSB_RC_NEC_PROTOCOL,
- DIBUSB_RC_HAUPPAUGE_PROTO,
-} dibusb_remote_t;
-
-struct dibusb_tuner {
- dibusb_tuner_t id;
-
- u8 pll_addr; /* tuner i2c address */
-};
-extern struct dibusb_tuner dibusb_tuner[];
-
-#define DIBUSB_POSSIBLE_I2C_ADDR_NUM 4
-struct dibusb_demod {
- dibusb_demodulator_t id;
-
- int pid_filter_count; /* counter of the internal pid_filter */
- u8 i2c_addrs[DIBUSB_POSSIBLE_I2C_ADDR_NUM]; /* list of possible i2c addresses of the demod */
-};
-
-#define DIBUSB_MAX_TUNER_NUM 2
-struct dibusb_device_class {
- dibusb_class_t id;
-
- const struct dibusb_usb_controller *usb_ctrl; /* usb controller */
- const char *firmware; /* valid firmware filenames */
-
- int pipe_cmd; /* command pipe (read/write) */
- int pipe_data; /* data pipe */
-
- int urb_count; /* number of data URBs to be submitted */
- int urb_buffer_size; /* the size of the buffer for each URB */
-
- dibusb_remote_t remote_type; /* does this device have a ir-receiver */
-
- struct dibusb_demod *demod; /* which demodulator is mount */
- struct dibusb_tuner *tuner; /* which tuner can be found here */
-};
-
-#define DIBUSB_ID_MAX_NUM 15
-struct dibusb_usb_device {
- const char *name; /* real name of the box */
- struct dibusb_device_class *dev_cl; /* which dibusb_device_class is this device part of */
-
- struct usb_device_id *cold_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at pre firmware state */
- struct usb_device_id *warm_ids[DIBUSB_ID_MAX_NUM]; /* list of USB ids when this device is at post firmware state */
-};
-
-/* a PID for the pid_filter list, when in use */
-struct dibusb_pid
-{
- int index;
- u16 pid;
- int active;
-};
-
-struct usb_dibusb {
- /* usb */
- struct usb_device * udev;
-
- struct dibusb_usb_device * dibdev;
-
-#define DIBUSB_STATE_INIT 0x000
-#define DIBUSB_STATE_URB_LIST 0x001
-#define DIBUSB_STATE_URB_BUF 0x002
-#define DIBUSB_STATE_URB_INIT 0x004
-#define DIBUSB_STATE_DVB 0x008
-#define DIBUSB_STATE_I2C 0x010
-#define DIBUSB_STATE_REMOTE 0x020
-#define DIBUSB_STATE_URB_SUBMIT 0x040
- int init_state;
-
- int feedcount;
- struct dib_fe_xfer_ops xfer_ops;
-
- struct dibusb_tuner *tuner;
-
- struct urb **urb_list;
- u8 *buffer;
- dma_addr_t dma_handle;
-
- /* I2C */
- struct i2c_adapter i2c_adap;
-
- /* locking */
- struct semaphore usb_sem;
- struct semaphore i2c_sem;
-
- /* dvb */
- struct dvb_adapter adapter;
- struct dmxdev dmxdev;
- struct dvb_demux demux;
- struct dvb_net dvb_net;
- struct dvb_frontend* fe;
-
- int (*fe_sleep) (struct dvb_frontend *);
- int (*fe_init) (struct dvb_frontend *);
-
- /* remote control */
- struct input_dev rc_input_dev;
- struct work_struct rc_query_work;
- int last_event;
- int last_state; /* for Hauppauge RC protocol */
- int repeat_key_count;
- int rc_key_repeat_count; /* module parameter */
-
- /* module parameters */
- int pid_parse;
- int rc_query_interval;
-};
-
-/* commonly used functions in the separated files */
-
-/* dvb-dibusb-firmware.c */
-int dibusb_loadfirmware(struct usb_device *udev, struct dibusb_usb_device *dibdev);
-
-/* dvb-dibusb-remote.c */
-int dibusb_remote_exit(struct usb_dibusb *dib);
-int dibusb_remote_init(struct usb_dibusb *dib);
-
-/* dvb-dibusb-fe-i2c.c */
-int dibusb_fe_init(struct usb_dibusb* dib);
-int dibusb_fe_exit(struct usb_dibusb *dib);
-int dibusb_i2c_init(struct usb_dibusb *dib);
-int dibusb_i2c_exit(struct usb_dibusb *dib);
-
-/* dvb-dibusb-dvb.c */
-void dibusb_urb_complete(struct urb *urb, struct pt_regs *ptregs);
-int dibusb_dvb_init(struct usb_dibusb *dib);
-int dibusb_dvb_exit(struct usb_dibusb *dib);
-
-/* dvb-dibusb-usb.c */
-int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
- u16 rlen);
-int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len);
-
-int dibusb_hw_wakeup(struct dvb_frontend *);
-int dibusb_hw_sleep(struct dvb_frontend *);
-int dibusb_set_streaming_mode(struct usb_dibusb *,u8);
-int dibusb_streaming(struct usb_dibusb *,int);
-
-int dibusb_urb_init(struct usb_dibusb *);
-int dibusb_urb_exit(struct usb_dibusb *);
-
-/* dvb-fe-dtt200u.c */
-struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *,struct dib_fe_xfer_ops *);
-
-/* i2c and transfer stuff */
-#define DIBUSB_I2C_TIMEOUT 5000
-
-/*
- * protocol of all dibusb related devices
- */
-
-/*
- * bulk msg to/from endpoint 0x01
- *
- * general structure:
- * request_byte parameter_bytes
- */
-
-#define DIBUSB_REQ_START_READ 0x00
-#define DIBUSB_REQ_START_DEMOD 0x01
-
-/*
- * i2c read
- * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
- * bulk read: byte_buffer (length_word bytes)
- */
-#define DIBUSB_REQ_I2C_READ 0x02
-
-/*
- * i2c write
- * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
- */
-#define DIBUSB_REQ_I2C_WRITE 0x03
-
-/*
- * polling the value of the remote control
- * bulk write: 0x04
- * bulk read: byte_buffer (5 bytes)
- *
- * first byte of byte_buffer shows the status (0x00, 0x01, 0x02)
- */
-#define DIBUSB_REQ_POLL_REMOTE 0x04
-
-#define DIBUSB_RC_NEC_EMPTY 0x00
-#define DIBUSB_RC_NEC_KEY_PRESSED 0x01
-#define DIBUSB_RC_NEC_KEY_REPEATED 0x02
-
-/* additional status values for Hauppauge Remote Control Protocol */
-#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01
-#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03
-
-/* streaming mode:
- * bulk write: 0x05 mode_byte
- *
- * mode_byte is mostly 0x00
- */
-#define DIBUSB_REQ_SET_STREAMING_MODE 0x05
-
-/* interrupt the internal read loop, when blocking */
-#define DIBUSB_REQ_INTR_READ 0x06
-
-/* io control
- * 0x07 cmd_byte param_bytes
- *
- * param_bytes can be up to 32 bytes
- *
- * cmd_byte function parameter name
- * 0x00 power mode
- * 0x00 sleep
- * 0x01 wakeup
- *
- * 0x01 enable streaming
- * 0x02 disable streaming
- *
- *
- */
-#define DIBUSB_REQ_SET_IOCTL 0x07
-
-/* IOCTL commands */
-
-/* change the power mode in firmware */
-#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00
-#define DIBUSB_IOCTL_POWER_SLEEP 0x00
-#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
-
-/* modify streaming of the FX2 */
-#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
-#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02
-
-#endif
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index d19301d90a0..f11daae91cd 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -35,6 +35,7 @@
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/suspend.h>
+#include <linux/jiffies.h>
#include <asm/processor.h>
#include <asm/semaphore.h>
@@ -327,7 +328,8 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe)
return 1;
if (fepriv->dvbdev->writers == 1)
- if (jiffies - fepriv->release_jiffies > dvb_shutdown_timeout * HZ)
+ if (time_after(jiffies, fepriv->release_jiffies +
+ dvb_shutdown_timeout * HZ))
return 1;
return 0;
@@ -389,8 +391,7 @@ static int dvb_frontend_thread(void *data)
break;
}
- if (current->flags & PF_FREEZE)
- refrigerator(PF_FREEZE);
+ try_to_freeze();
if (down_interruptible(&fepriv->sem))
break;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
new file mode 100644
index 00000000000..8aa32f6e447
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -0,0 +1,99 @@
+config DVB_USB
+ tristate "Support for various USB DVB devices"
+ depends on DVB_CORE && USB
+ select FW_LOADER
+ help
+ By enabling this you will be able to choose the various USB 1.1 and
+ USB2.0 DVB devices.
+
+ Almost every USB device needs a firmware, please look into
+ <file:Documentation/dvb/README.dvb-usb>
+
+ Say Y if you own an USB DVB device.
+
+config DVB_USB_DEBUG
+ bool "Enable extended debug support for all DVB-USB devices"
+ depends on DVB_USB
+ help
+ Say Y if you want to enable debuging. See modinfo dvb-usb (and the
+ appropriate drivers) for debug levels.
+
+config DVB_USB_A800
+ tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
+ depends on DVB_USB
+ help
+ Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
+
+config DVB_USB_DIBUSB_MB
+ tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
+ depends on DVB_USB
+ help
+ Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
+ DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
+
+ Devices supported by this driver:
+ TwinhanDTV USB-Ter (VP7041)
+ TwinhanDTV Magic Box (VP7041e)
+ KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0
+ Hama DVB-T USB1.1-Box
+ DiBcom USB1.1 reference devices (non-public)
+ Ultima Electronic/Artec T1 USB TVBOX
+ Compro Videomate DVB-U2000 - DVB-T USB
+ Grandtec DVB-T USB
+ Avermedia AverTV DVBT USB1.1
+ Artec T1 USB1.1 boxes
+
+ The VP7041 seems to be identical to "CTS Portable" (Chinese
+ Television System).
+
+ Say Y if you own such a device and want to use it. You should build it as
+ a module.
+
+config DVB_USB_DIBUSB_MC
+ tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
+ depends on DVB_USB
+ help
+ Support for 2.0 DVB-T receivers based on reference designs made by
+ DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
+
+ Devices supported by this driver:
+ DiBcom USB2.0 reference devices (non-public)
+ Artec T1 USB2.0 boxes
+
+ Say Y if you own such a device and want to use it. You should build it as
+ a module.
+
+config DVB_USB_UMT_010
+ tristate "HanfTek UMT-010 DVB-T USB2.0 support"
+ depends on DVB_USB
+ help
+ Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
+
+config DVB_USB_DIGITV
+ tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
+ depends on DVB_USB
+ help
+ Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
+
+config DVB_USB_VP7045
+ tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support"
+ depends on DVB_USB
+ help
+ Say Y here to support the
+ TwinhanDTV Alpha (stick) (VP-7045),
+ TwinhanDTV MagicBox II (VP-7046) and
+ DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers.
+
+config DVB_USB_NOVA_T_USB2
+ tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
+ depends on DVB_USB
+ help
+ Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
+
+config DVB_USB_DTT200U
+ tristate "Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 support"
+ depends on DVB_USB
+ help
+ Say Y here to support the Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
+
+ The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
new file mode 100644
index 00000000000..d65b50f9abb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -0,0 +1,30 @@
+dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o
+obj-$(CONFIG_DVB_USB) += dvb-usb.o
+
+dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
+obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
+
+dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
+obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
+
+dvb-usb-dibusb-common-objs = dibusb-common.o
+
+dvb-usb-a800-objs = a800.o
+obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
+
+dvb-usb-dibusb-mb-objs = dibusb-mb.o
+obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
+
+dvb-usb-dibusb-mc-objs = dibusb-mc.o
+obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
+
+dvb-usb-nova-t-usb2-objs = nova-t-usb2.o
+obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
+
+dvb-usb-umt-010-objs = umt-010.o
+obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
+
+dvb-usb-digitv-objs = digitv.o
+obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
+
+EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
new file mode 100644
index 00000000000..a3542935604
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -0,0 +1,176 @@
+/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
+ * USB2.0 (A800) DVB-T receiver.
+ *
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to
+ * - AVerMedia who kindly provided information and
+ * - Glen Harris who suffered from my mistakes during development.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
+#define deb_rc(args...) dprintk(debug,0x01,args)
+
+static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ /* do nothing for the AVerMedia */
+ return 0;
+}
+
+static struct dvb_usb_rc_key a800_rc_keys[] = {
+ { 0x02, 0x01, KEY_PROG1 }, /* SOURCE */
+ { 0x02, 0x00, KEY_POWER }, /* POWER */
+ { 0x02, 0x05, KEY_1 }, /* 1 */
+ { 0x02, 0x06, KEY_2 }, /* 2 */
+ { 0x02, 0x07, KEY_3 }, /* 3 */
+ { 0x02, 0x09, KEY_4 }, /* 4 */
+ { 0x02, 0x0a, KEY_5 }, /* 5 */
+ { 0x02, 0x0b, KEY_6 }, /* 6 */
+ { 0x02, 0x0d, KEY_7 }, /* 7 */
+ { 0x02, 0x0e, KEY_8 }, /* 8 */
+ { 0x02, 0x0f, KEY_9 }, /* 9 */
+ { 0x02, 0x12, KEY_LEFT }, /* L / DISPLAY */
+ { 0x02, 0x11, KEY_0 }, /* 0 */
+ { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */
+ { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */
+ { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */
+ { 0x02, 0x03, KEY_CHANNELUP }, /* CH UP */
+ { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */
+ { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */
+ { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */
+ { 0x02, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */
+ { 0x02, 0x14, KEY_MUTE }, /* MUTE */
+ { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */
+ { 0x02, 0x19, KEY_RECORD }, /* RECORD */
+ { 0x02, 0x18, KEY_PLAY }, /* PLAY */
+ { 0x02, 0x1b, KEY_STOP }, /* STOP */
+ { 0x02, 0x1a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
+ { 0x02, 0x1d, KEY_BACK }, /* << / RED */
+ { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */
+ { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */
+ { 0x02, 0x01, KEY_FIRST }, /* |<< / GREEN */
+ { 0x02, 0x00, KEY_LAST }, /* >>| / BLUE */
+ { 0x02, 0x04, KEY_EPG }, /* EPG */
+ { 0x02, 0x15, KEY_MENU }, /* MENU */
+};
+
+int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ u8 key[5];
+ if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
+ 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
+ 2*HZ) != 5)
+ return -ENODEV;
+
+ /* call the universal NEC remote processor, to find out the key's state and event */
+ dvb_usb_nec_rc_key_to_event(d,key,event,state);
+ if (key[0] != 0)
+ deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+ return 0;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_properties a800_properties;
+
+static int a800_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE);
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id a800_table [] = {
+/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
+/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, a800_table);
+
+static struct dvb_usb_properties a800_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+ .pid_filter_count = 32,
+
+ .usb_ctrl = CYPRESS_FX2,
+
+ .firmware = "dvb-usb-avertv-a800-02.fw",
+
+ .size_of_priv = sizeof(struct dibusb_state),
+
+ .streaming_ctrl = dibusb2_0_streaming_ctrl,
+ .pid_filter = dibusb_pid_filter,
+ .pid_filter_ctrl = dibusb_pid_filter_ctrl,
+ .power_ctrl = a800_power_ctrl,
+ .frontend_attach = dibusb_dib3000mc_frontend_attach,
+ .tuner_attach = dibusb_dib3000mc_tuner_attach,
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = a800_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(a800_rc_keys),
+ .rc_query = a800_rc_query,
+
+ .i2c_algo = &dibusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x06,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { "AVerMedia AverTV DVB-T USB 2.0 (A800)",
+ { &a800_table[0], NULL },
+ { &a800_table[1], NULL },
+ },
+ }
+};
+
+static struct usb_driver a800_driver = {
+ .owner = THIS_MODULE,
+ .name = "AVerMedia AverTV DVB-T USB 2.0 (A800)",
+ .probe = a800_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = a800_table,
+};
+
+/* module stuff */
+static int __init a800_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&a800_driver))) {
+ err("usb_register failed. Error number %d",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit a800_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&a800_driver);
+}
+
+module_init (a800_module_init);
+module_exit (a800_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
new file mode 100644
index 00000000000..63b626f70c8
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -0,0 +1,272 @@
+/* Common methods for dibusb-based-receivers.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
+MODULE_LICENSE("GPL");
+
+#define deb_info(args...) dprintk(debug,0x01,args)
+
+/* common stuff used by the different dibusb modules */
+int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ if (d->priv != NULL) {
+ struct dib_fe_xfer_ops *ops = d->priv;
+ if (ops->fifo_ctrl != NULL)
+ if (ops->fifo_ctrl(d->fe,onoff)) {
+ err("error while controlling the fifo of the demod.");
+ return -ENODEV;
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_streaming_ctrl);
+
+int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+{
+ if (d->priv != NULL) {
+ struct dib_fe_xfer_ops *ops = d->priv;
+ if (d->pid_filtering && ops->pid_ctrl != NULL)
+ ops->pid_ctrl(d->fe,index,pid,onoff);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_pid_filter);
+
+int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ if (d->priv != NULL) {
+ struct dib_fe_xfer_ops *ops = d->priv;
+ if (ops->pid_parse != NULL)
+ if (ops->pid_parse(d->fe,onoff) < 0)
+ err("could not handle pid_parser");
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
+
+int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 b[3];
+ int ret;
+ b[0] = DIBUSB_REQ_SET_IOCTL;
+ b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
+ b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
+ ret = dvb_usb_generic_write(d,b,3);
+ msleep(10);
+ return ret;
+}
+EXPORT_SYMBOL(dibusb_power_ctrl);
+
+int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 b[2];
+ b[0] = DIBUSB_REQ_SET_IOCTL;
+ b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
+
+ dvb_usb_generic_write(d,b,3);
+
+ return dibusb_streaming_ctrl(d,onoff);
+}
+EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
+
+int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ if (onoff) {
+ u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
+ return dvb_usb_generic_write(d,b,3);
+ } else
+ return 0;
+}
+EXPORT_SYMBOL(dibusb2_0_power_ctrl);
+
+static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
+ u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
+{
+ u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
+ /* write only ? */
+ int wo = (rbuf == NULL || rlen == 0),
+ len = 2 + wlen + (wo ? 0 : 2);
+
+ sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
+ sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
+
+ memcpy(&sndbuf[2],wbuf,wlen);
+
+ if (!wo) {
+ sndbuf[wlen+2] = (rlen >> 8) & 0xff;
+ sndbuf[wlen+3] = rlen & 0xff;
+ }
+
+ return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0);
+}
+
+/*
+ * I2C master xfer function
+ */
+static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i;
+
+ if (down_interruptible(&d->i2c_sem) < 0)
+ return -EAGAIN;
+
+ if (num > 2)
+ warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+ for (i = 0; i < num; i++) {
+ /* write/read request */
+ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+ if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
+ msg[i+1].buf,msg[i+1].len) < 0)
+ break;
+ i++;
+ } else
+ if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
+ break;
+ }
+
+ up(&d->i2c_sem);
+ return i;
+}
+
+static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+struct i2c_algorithm dibusb_i2c_algo = {
+ .name = "DiBcom USB I2C algorithm",
+ .id = I2C_ALGO_BIT,
+ .master_xfer = dibusb_i2c_xfer,
+ .functionality = dibusb_i2c_func,
+};
+EXPORT_SYMBOL(dibusb_i2c_algo);
+
+int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
+{
+ u8 wbuf[1] = { offs };
+ return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
+}
+EXPORT_SYMBOL(dibusb_read_eeprom_byte);
+
+int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
+{
+ struct dib3000_config demod_cfg;
+ struct dibusb_state *st = d->priv;
+
+ demod_cfg.pll_set = dvb_usb_pll_set_i2c;
+ demod_cfg.pll_init = dvb_usb_pll_init_i2c;
+
+ for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++)
+ if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) {
+ d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
+ return 0;
+ }
+
+ return -ENODEV;
+}
+EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
+
+int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
+{
+ d->pll_addr = 0x60;
+ d->pll_desc = &dvb_pll_env57h1xd5;
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
+
+/*
+ * common remote control stuff
+ */
+struct dvb_usb_rc_key dibusb_rc_keys[] = {
+ /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
+ { 0x00, 0x16, KEY_POWER },
+ { 0x00, 0x10, KEY_MUTE },
+ { 0x00, 0x03, KEY_1 },
+ { 0x00, 0x01, KEY_2 },
+ { 0x00, 0x06, KEY_3 },
+ { 0x00, 0x09, KEY_4 },
+ { 0x00, 0x1d, KEY_5 },
+ { 0x00, 0x1f, KEY_6 },
+ { 0x00, 0x0d, KEY_7 },
+ { 0x00, 0x19, KEY_8 },
+ { 0x00, 0x1b, KEY_9 },
+ { 0x00, 0x15, KEY_0 },
+ { 0x00, 0x05, KEY_CHANNELUP },
+ { 0x00, 0x02, KEY_CHANNELDOWN },
+ { 0x00, 0x1e, KEY_VOLUMEUP },
+ { 0x00, 0x0a, KEY_VOLUMEDOWN },
+ { 0x00, 0x11, KEY_RECORD },
+ { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */
+ { 0x00, 0x14, KEY_PLAY },
+ { 0x00, 0x1a, KEY_STOP },
+ { 0x00, 0x40, KEY_REWIND },
+ { 0x00, 0x12, KEY_FASTFORWARD },
+ { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */
+ { 0x00, 0x4c, KEY_PAUSE },
+ { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */
+ { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
+ /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
+ { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */
+ { 0x00, 0x1c, KEY_EPG }, /* EPG */
+ { 0x00, 0x00, KEY_TAB }, /* Tab */
+ { 0x00, 0x48, KEY_INFO }, /* Preview */
+ { 0x00, 0x04, KEY_LIST }, /* RecordList */
+ { 0x00, 0x0f, KEY_TEXT }, /* Teletext */
+ /* Key codes for the KWorld/ADSTech/JetWay remote. */
+ { 0x86, 0x12, KEY_POWER },
+ { 0x86, 0x0f, KEY_SELECT }, /* source */
+ { 0x86, 0x0c, KEY_UNKNOWN }, /* scan */
+ { 0x86, 0x0b, KEY_EPG },
+ { 0x86, 0x10, KEY_MUTE },
+ { 0x86, 0x01, KEY_1 },
+ { 0x86, 0x02, KEY_2 },
+ { 0x86, 0x03, KEY_3 },
+ { 0x86, 0x04, KEY_4 },
+ { 0x86, 0x05, KEY_5 },
+ { 0x86, 0x06, KEY_6 },
+ { 0x86, 0x07, KEY_7 },
+ { 0x86, 0x08, KEY_8 },
+ { 0x86, 0x09, KEY_9 },
+ { 0x86, 0x0a, KEY_0 },
+ { 0x86, 0x18, KEY_ZOOM },
+ { 0x86, 0x1c, KEY_UNKNOWN }, /* preview */
+ { 0x86, 0x13, KEY_UNKNOWN }, /* snap */
+ { 0x86, 0x00, KEY_UNDO },
+ { 0x86, 0x1d, KEY_RECORD },
+ { 0x86, 0x0d, KEY_STOP },
+ { 0x86, 0x0e, KEY_PAUSE },
+ { 0x86, 0x16, KEY_PLAY },
+ { 0x86, 0x11, KEY_BACK },
+ { 0x86, 0x19, KEY_FORWARD },
+ { 0x86, 0x14, KEY_UNKNOWN }, /* pip */
+ { 0x86, 0x15, KEY_ESC },
+ { 0x86, 0x1a, KEY_UP },
+ { 0x86, 0x1e, KEY_DOWN },
+ { 0x86, 0x1f, KEY_LEFT },
+ { 0x86, 0x1b, KEY_RIGHT },
+};
+EXPORT_SYMBOL(dibusb_rc_keys);
+
+int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
+ dvb_usb_generic_rw(d,&cmd,1,key,5,0);
+ dvb_usb_nec_rc_key_to_event(d,key,event,state);
+ if (key[0] != 0)
+ deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+ return 0;
+}
+EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
new file mode 100644
index 00000000000..a0ffbb59fa1
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -0,0 +1,316 @@
+/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
+ * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * based on GPL code from DiBcom, which has
+ * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
+{
+ struct dib3000_config demod_cfg;
+ struct dibusb_state *st = d->priv;
+
+ demod_cfg.demod_address = 0x8;
+ demod_cfg.pll_set = dvb_usb_pll_set_i2c;
+ demod_cfg.pll_init = dvb_usb_pll_init_i2c;
+
+ if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL)
+ return -ENODEV;
+
+ d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
+
+ return 0;
+}
+
+/* some of the dibusb 1.1 device aren't equipped with the default tuner
+ * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
+ * this out. */
+static int dibusb_dib3000mb_tuner_attach (struct dvb_usb_device *d)
+{
+ u8 b[2] = { 0,0 }, b2[1];
+ int ret = 0;
+ struct i2c_msg msg[2] = {
+ { .flags = 0, .buf = b, .len = 2 },
+ { .flags = I2C_M_RD, .buf = b2, .len = 1 },
+ };
+
+ /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
+ msg[0].addr = msg[1].addr = 0x60;
+
+ if (d->tuner_pass_ctrl)
+ d->tuner_pass_ctrl(d->fe,1,msg[0].addr);
+
+ if (i2c_transfer (&d->i2c_adap, msg, 2) != 2) {
+ err("tuner i2c write failed.");
+ ret = -EREMOTEIO;
+ }
+
+ if (d->tuner_pass_ctrl)
+ d->tuner_pass_ctrl(d->fe,0,msg[0].addr);
+
+ if (b2[0] == 0xfe) {
+ info("this device has the Thomson Cable onboard. Which is default.");
+ d->pll_addr = 0x61;
+ d->pll_desc = &dvb_pll_tua6010xs;
+ } else {
+ u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab };
+ info("this device has the Panasonic ENV77H11D5 onboard.");
+ d->pll_addr = 0x60;
+ memcpy(d->pll_init,bpll,4);
+ d->pll_desc = &dvb_pll_tda665x;
+ }
+
+ return ret;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_properties dibusb1_1_properties;
+static struct dvb_usb_properties dibusb1_1_an2235_properties;
+static struct dvb_usb_properties dibusb2_0b_properties;
+
+static int dibusb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 ||
+ dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) == 0 ||
+ dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0)
+ return 0;
+
+ return -EINVAL;
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id dibusb_dib3000mb_table [] = {
+/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_COLD)},
+/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_AVERMEDIA_DVBT_USB_WARM)},
+/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
+/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
+/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
+/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
+/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
+/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
+/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
+/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
+/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
+/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
+/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
+/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
+/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
+/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) },
+/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) },
+/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
+/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
+/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
+/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
+/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
+/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
+/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
+/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
+
+static struct dvb_usb_properties dibusb1_1_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+ .pid_filter_count = 16,
+
+ .usb_ctrl = CYPRESS_AN2135,
+
+ .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
+
+ .size_of_priv = sizeof(struct dibusb_state),
+
+ .streaming_ctrl = dibusb_streaming_ctrl,
+ .pid_filter = dibusb_pid_filter,
+ .pid_filter_ctrl = dibusb_pid_filter_ctrl,
+ .power_ctrl = dibusb_power_ctrl,
+ .frontend_attach = dibusb_dib3000mb_frontend_attach,
+ .tuner_attach = dibusb_dib3000mb_tuner_attach,
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dibusb_rc_keys,
+ .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_query = dibusb_rc_query,
+
+ .i2c_algo = &dibusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x02,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 8,
+ .devices = {
+ { "AVerMedia AverTV DVBT USB1.1",
+ { &dibusb_dib3000mb_table[0], NULL },
+ { &dibusb_dib3000mb_table[1], NULL },
+ },
+ { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
+ { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
+ { &dibusb_dib3000mb_table[3], NULL },
+ },
+ { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
+ { &dibusb_dib3000mb_table[5], NULL },
+ { &dibusb_dib3000mb_table[6], NULL },
+ },
+ { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
+ { &dibusb_dib3000mb_table[7], NULL },
+ { &dibusb_dib3000mb_table[8], NULL },
+ },
+ { "Grandtec USB1.1 DVB-T",
+ { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL },
+ { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
+ },
+ { "Unkown USB1.1 DVB-T device ???? please report the name to the author",
+ { &dibusb_dib3000mb_table[13], NULL },
+ { &dibusb_dib3000mb_table[14], NULL },
+ },
+ { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
+ { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
+ { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
+ },
+ { "Artec T1 USB1.1 TVBOX with AN2135",
+ { &dibusb_dib3000mb_table[19], NULL },
+ { &dibusb_dib3000mb_table[20], NULL },
+ },
+ }
+};
+
+static struct dvb_usb_properties dibusb1_1_an2235_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = CYPRESS_AN2235,
+
+ .firmware = "dvb-usb-dibusb-an2235-01.fw",
+
+ .size_of_priv = sizeof(struct dibusb_state),
+
+ .streaming_ctrl = dibusb_streaming_ctrl,
+ .pid_filter = dibusb_pid_filter,
+ .pid_filter_ctrl = dibusb_pid_filter_ctrl,
+ .power_ctrl = dibusb_power_ctrl,
+ .frontend_attach = dibusb_dib3000mb_frontend_attach,
+ .tuner_attach = dibusb_dib3000mb_tuner_attach,
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dibusb_rc_keys,
+ .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_query = dibusb_rc_query,
+
+ .i2c_algo = &dibusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x02,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { "Artec T1 USB1.1 TVBOX with AN2235",
+ { &dibusb_dib3000mb_table[20], NULL },
+ { &dibusb_dib3000mb_table[21], NULL },
+ },
+ }
+};
+
+static struct dvb_usb_properties dibusb2_0b_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+ .usb_ctrl = CYPRESS_FX2,
+
+ .firmware = "dvb-usb-adstech-usb2-01.fw",
+
+ .size_of_priv = sizeof(struct dibusb_state),
+
+ .streaming_ctrl = dibusb2_0_streaming_ctrl,
+ .pid_filter = dibusb_pid_filter,
+ .pid_filter_ctrl = dibusb_pid_filter_ctrl,
+ .power_ctrl = dibusb2_0_power_ctrl,
+ .frontend_attach = dibusb_dib3000mb_frontend_attach,
+ .tuner_attach = dibusb_dib3000mb_tuner_attach,
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dibusb_rc_keys,
+ .rc_key_map_size = 63, /* wow, that is ugly ... I want to load it to the driver dynamically */
+ .rc_query = dibusb_rc_query,
+
+ .i2c_algo = &dibusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x06,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { "KWorld/ADSTech Instant DVB-T USB 2.0",
+ { &dibusb_dib3000mb_table[23], NULL },
+ { &dibusb_dib3000mb_table[24], NULL }, /* device ID with default DIBUSB2_0-firmware */
+ },
+ }
+};
+
+static struct usb_driver dibusb_driver = {
+ .owner = THIS_MODULE,
+ .name = "DiBcom based USB DVB-T devices (DiB3000M-B based)",
+ .probe = dibusb_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = dibusb_dib3000mb_table,
+};
+
+/* module stuff */
+static int __init dibusb_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&dibusb_driver))) {
+ err("usb_register failed. Error number %d",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit dibusb_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&dibusb_driver);
+}
+
+module_init (dibusb_module_init);
+module_exit (dibusb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
new file mode 100644
index 00000000000..aad8ed3fe00
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -0,0 +1,116 @@
+/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
+ * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * based on GPL code from DiBcom, which has
+ * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+/* USB Driver stuff */
+static struct dvb_usb_properties dibusb_mc_properties;
+
+static int dibusb_mc_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE);
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id dibusb_dib3000mc_table [] = {
+/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
+/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
+/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
+
+static struct dvb_usb_properties dibusb_mc_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+ .pid_filter_count = 32,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
+
+ .size_of_priv = sizeof(struct dibusb_state),
+
+ .streaming_ctrl = dibusb2_0_streaming_ctrl,
+ .pid_filter = dibusb_pid_filter,
+ .pid_filter_ctrl = dibusb_pid_filter_ctrl,
+ .power_ctrl = dibusb2_0_power_ctrl,
+ .frontend_attach = dibusb_dib3000mc_frontend_attach,
+ .tuner_attach = dibusb_dib3000mc_tuner_attach,
+
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dibusb_rc_keys,
+ .rc_key_map_size = 63, /* FIXME */
+ .rc_query = dibusb_rc_query,
+
+ .i2c_algo = &dibusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x06,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
+ { &dibusb_dib3000mc_table[0], NULL },
+ { &dibusb_dib3000mc_table[1], NULL },
+ },
+ { "Artec T1 USB2.0 TVBOX (please report the warm ID)",
+ { &dibusb_dib3000mc_table[2], NULL },
+ { NULL },
+ },
+ }
+};
+
+static struct usb_driver dibusb_mc_driver = {
+ .owner = THIS_MODULE,
+ .name = "DiBcom based USB2.0 DVB-T (DiB3000M-C/P based) devices",
+ .probe = dibusb_mc_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = dibusb_dib3000mc_table,
+};
+
+/* module stuff */
+static int __init dibusb_mc_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&dibusb_mc_driver))) {
+ err("usb_register failed. Error number %d",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit dibusb_mc_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&dibusb_mc_driver);
+}
+
+module_init (dibusb_mc_module_init);
+module_exit (dibusb_mc_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
new file mode 100644
index 00000000000..6611f62977c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -0,0 +1,122 @@
+/* Header file for all dibusb-based-receivers.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_DIBUSB_H_
+#define _DVB_USB_DIBUSB_H_
+
+#define DVB_USB_LOG_PREFIX "dibusb"
+#include "dvb-usb.h"
+
+#include "dib3000.h"
+
+/*
+ * protocol of all dibusb related devices
+ */
+
+/*
+ * bulk msg to/from endpoint 0x01
+ *
+ * general structure:
+ * request_byte parameter_bytes
+ */
+
+#define DIBUSB_REQ_START_READ 0x00
+#define DIBUSB_REQ_START_DEMOD 0x01
+
+/*
+ * i2c read
+ * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
+ * bulk read: byte_buffer (length_word bytes)
+ */
+#define DIBUSB_REQ_I2C_READ 0x02
+
+/*
+ * i2c write
+ * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
+ */
+#define DIBUSB_REQ_I2C_WRITE 0x03
+
+/*
+ * polling the value of the remote control
+ * bulk write: 0x04
+ * bulk read: byte_buffer (5 bytes)
+ */
+#define DIBUSB_REQ_POLL_REMOTE 0x04
+
+/* additional status values for Hauppauge Remote Control Protocol */
+#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01
+#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03
+
+/* streaming mode:
+ * bulk write: 0x05 mode_byte
+ *
+ * mode_byte is mostly 0x00
+ */
+#define DIBUSB_REQ_SET_STREAMING_MODE 0x05
+
+/* interrupt the internal read loop, when blocking */
+#define DIBUSB_REQ_INTR_READ 0x06
+
+/* io control
+ * 0x07 cmd_byte param_bytes
+ *
+ * param_bytes can be up to 32 bytes
+ *
+ * cmd_byte function parameter name
+ * 0x00 power mode
+ * 0x00 sleep
+ * 0x01 wakeup
+ *
+ * 0x01 enable streaming
+ * 0x02 disable streaming
+ *
+ *
+ */
+#define DIBUSB_REQ_SET_IOCTL 0x07
+
+/* IOCTL commands */
+
+/* change the power mode in firmware */
+#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00
+#define DIBUSB_IOCTL_POWER_SLEEP 0x00
+#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
+
+/* modify streaming of the FX2 */
+#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
+#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02
+
+struct dibusb_state {
+ struct dib_fe_xfer_ops ops;
+
+ /* for RC5 remote control */
+ int old_toggle;
+ int last_repeat_count;
+};
+
+extern struct i2c_algorithm dibusb_i2c_algo;
+
+extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *);
+extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *);
+
+extern int dibusb_streaming_ctrl(struct dvb_usb_device *, int);
+extern int dibusb_pid_filter(struct dvb_usb_device *, int, u16, int);
+extern int dibusb_pid_filter_ctrl(struct dvb_usb_device *, int);
+extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
+extern int dibusb2_0_streaming_ctrl(struct dvb_usb_device *, int);
+extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
+
+#define DEFAULT_RC_INTERVAL 150
+//#define DEFAULT_RC_INTERVAL 100000
+
+extern struct dvb_usb_rc_key dibusb_rc_keys[];
+extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
+extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
new file mode 100644
index 00000000000..5acf3fde952
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -0,0 +1,282 @@
+/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
+ * receiver
+ *
+ * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) and
+ * Allan Third (allan.third@cs.man.ac.uk)
+ *
+ * partly based on the SDK published by Nebula Electronics (TODO do we want this line ?)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "digitv.h"
+
+#include "mt352.h"
+#include "nxt6000.h"
+
+/* debug */
+int dvb_usb_digitv_debug;
+module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
+
+static int digitv_ctrl_msg(struct dvb_usb_device *d,
+ u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+ int wo = (rbuf == NULL || rlen == 0); /* write-only */
+ u8 sndbuf[7],rcvbuf[7];
+ memset(sndbuf,0,7); memset(rcvbuf,0,7);
+
+ sndbuf[0] = cmd;
+ sndbuf[1] = vv;
+ sndbuf[2] = wo ? wlen : rlen;
+
+ if (!wo) {
+ memcpy(&sndbuf[3],wbuf,wlen);
+ dvb_usb_generic_write(d,sndbuf,7);
+ } else {
+ dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
+ memcpy(&rbuf,&rcvbuf[3],rlen);
+ }
+ return 0;
+}
+
+/* I2C */
+static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i;
+
+ if (down_interruptible(&d->i2c_sem) < 0)
+ return -EAGAIN;
+
+ if (num > 2)
+ warn("more than 2 i2c messages at a time is not handled yet. TODO.");
+
+ for (i = 0; i < num; i++) {
+ /* write/read request */
+ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
+ if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
+ msg[i+1].buf,msg[i+1].len) < 0)
+ break;
+ i++;
+ } else
+ if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0],
+ &msg[i].buf[1],msg[i].len-1,NULL,0) < 0)
+ break;
+ }
+
+ up(&d->i2c_sem);
+ return i;
+}
+
+static u32 digitv_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm digitv_i2c_algo = {
+ .name = "Nebula DigiTV USB I2C algorithm",
+ .id = I2C_ALGO_BIT,
+ .master_xfer = digitv_i2c_xfer,
+ .functionality = digitv_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static int digitv_identify_state (struct usb_device *udev, struct
+ dvb_usb_properties *props, struct dvb_usb_device_description **desc,
+ int *cold)
+{
+ *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
+ return 0;
+}
+
+static int digitv_mt352_demod_init(struct dvb_frontend *fe)
+{
+ static u8 mt352_clock_config[] = { 0x89, 0x38, 0x2d };
+ static u8 mt352_reset[] = { 0x50, 0x80 };
+ static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
+
+ static u8 mt352_agc_cfg[] = { 0x68, 0xa0 };
+ static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0xa0 };
+ static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
+ static u8 mt352_agc_target[] = { 0x67, 0x20 };
+
+ static u8 mt352_rs_err_per[] = { 0x7c, 0x00, 0x01 };
+ static u8 mt352_snr_select[] = { 0x79, 0x00, 0x20 };
+
+ static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x05 };
+
+ static u8 mt352_scan_ctl[] = { 0x88, 0x0f };
+ static u8 mt352_capt_range[] = { 0x75, 0x32 };
+
+ mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+ mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+ msleep(1);
+ mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
+
+ mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
+ mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+ mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
+ mt352_write(fe, mt352_agc_target, sizeof(mt352_agc_target));
+
+
+ mt352_write(fe, mt352_rs_err_per, sizeof(mt352_rs_err_per));
+ mt352_write(fe, mt352_snr_select, sizeof(mt352_snr_select));
+
+ mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
+
+ mt352_write(fe, mt352_scan_ctl, sizeof(mt352_scan_ctl));
+ mt352_write(fe, mt352_capt_range, sizeof(mt352_capt_range));
+
+ return 0;
+}
+
+static struct mt352_config digitv_mt352_config = {
+ .demod_address = 0x0, /* ignored by the digitv anyway */
+ .demod_init = digitv_mt352_demod_init,
+ .pll_set = NULL, /* TODO */
+};
+
+static struct nxt6000_config digitv_nxt6000_config = {
+ .demod_address = 0x0, /* ignored by the digitv anyway */
+ .clock_inversion = 0x0,
+
+ .pll_init = NULL,
+ .pll_set = NULL,
+};
+
+static int digitv_frontend_attach(struct dvb_usb_device *d)
+{
+ if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) == NULL)
+ return 0;
+ if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) == NULL) {
+
+ warn("nxt6000 support is not done yet, in fact you are one of the first "
+ "person who wants to use this device in Linux. Please report to "
+ "linux-dvb@linuxtv.org");
+
+ return 0;
+ }
+ return -EIO;
+}
+
+static struct dvb_usb_rc_key digitv_rc_keys[] = {
+ { 0x00, 0x16, KEY_POWER }, /* dummy key */
+};
+
+/* TODO is it really the NEC protocol ? */
+int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ u8 key[5];
+
+ digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
+ /* TODO state, maybe it is VV ? */
+ if (key[1] != 0)
+ key[0] = 0x01; /* if something is inside the buffer, simulate key press */
+
+ /* call the universal NEC remote processor, to find out the key's state and event */
+ dvb_usb_nec_rc_key_to_event(d,key,event,state);
+ if (key[0] != 0)
+ deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+ return 0;
+}
+
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_properties digitv_properties;
+
+static int digitv_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE);
+}
+
+static struct usb_device_id digitv_table [] = {
+ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, digitv_table);
+
+static struct dvb_usb_properties digitv_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-digitv-01.fw",
+
+ .size_of_priv = 0,
+
+ .streaming_ctrl = NULL,
+ .pid_filter = NULL,
+ .pid_filter_ctrl = NULL,
+ .power_ctrl = NULL,
+ .frontend_attach = digitv_frontend_attach,
+ .tuner_attach = NULL, // digitv_tuner_attach,
+ .read_mac_address = NULL,
+
+ .rc_interval = 1000,
+ .rc_key_map = digitv_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(digitv_rc_keys),
+ .rc_query = digitv_rc_query,
+
+ .identify_state = digitv_identify_state,
+
+ .i2c_algo = &digitv_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x02,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { "Nebula Electronics uDigiTV DVB-T USB2.0)",
+ { &digitv_table[0], NULL },
+ { NULL },
+ },
+ }
+};
+
+static struct usb_driver digitv_driver = {
+ .owner = THIS_MODULE,
+ .name = "Nebula Electronics uDigiTV DVB-T USB2.0 device",
+ .probe = digitv_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = digitv_table,
+};
+
+/* module stuff */
+static int __init digitv_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&digitv_driver))) {
+ err("usb_register failed. Error number %d",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit digitv_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&digitv_driver);
+}
+
+module_init (digitv_module_init);
+module_exit (digitv_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
+MODULE_VERSION("1.0-alpha");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h
new file mode 100644
index 00000000000..477ee428a70
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.h
@@ -0,0 +1,65 @@
+#ifndef _DVB_USB_DIGITV_H_
+#define _DVB_USB_DIGITV_H_
+
+#define DVB_USB_LOG_PREFIX "digitv"
+#include "dvb-usb.h"
+
+extern int dvb_usb_digitv_debug;
+#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args)
+
+/* protocol (from usblogging and the SDK:
+ *
+ * Always 7 bytes bulk message(s) for controlling
+ *
+ * First byte describes the command. Reads are 2 consecutive transfer (as always).
+ *
+ * General structure:
+ *
+ * write or first message of a read:
+ * <cmdbyte> VV <len> B0 B1 B2 B3
+ *
+ * second message of a read
+ * <cmdbyte> VV <len> R0 R1 R2 R3
+ *
+ * whereas 0 < len <= 4
+ *
+ * I2C address is stored somewhere inside the device.
+ *
+ * 0x01 read from EEPROM
+ * VV = offset; B* = 0; R* = value(s)
+ *
+ * 0x02 read register of the COFDM
+ * VV = register; B* = 0; R* = value(s)
+ *
+ * 0x05 write register of the COFDM
+ * VV = register; B* = value(s);
+ *
+ * 0x06 write to the tuner (only for NXT6000)
+ * VV = 0; B* = PLL data; len = 4;
+ *
+ * 0x03 read remote control
+ * VV = 0; B* = 0; len = 4; R* = key
+ *
+ * 0x07 write to the remote (don't know why one should this, resetting ?)
+ * VV = 0; B* = key; len = 4;
+ *
+ * 0x08 write remote type
+ * VV = 0; B[0] = 0x01, len = 4
+ *
+ * 0x09 write device init
+ * TODO
+ */
+#define USB_READ_EEPROM 1
+
+#define USB_READ_COFDM 2
+#define USB_WRITE_COFDM 5
+
+#define USB_WRITE_TUNER 6
+
+#define USB_READ_REMOTE 3
+#define USB_WRITE_REMOTE 7
+#define USB_WRITE_REMOTE_TYPE 8
+
+#define USB_DEV_INIT 9
+
+#endif
diff --git a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
index 1872aa6d200..d17d768038c 100644
--- a/drivers/media/dvb/dibusb/dvb-fe-dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -1,42 +1,18 @@
-/*
- * dvb-dtt200u-fe.c is a driver which implements the frontend-part of the
- * Yakumo/Typhoon/Hama USB2.0 boxes. It is hard-wired to the dibusb-driver as
- * it uses the usb-transfer functions directly (maybe creating a
- * generic-dvb-usb-lib for all usb-drivers will be reduce some more code.)
+/* Frontend part of the Linux driver for the Yakumo/Hama/Typhoon DVB-T
+ * USB2.0 receiver.
*
* Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
*
- * see dvb-dibusb-core.c for copyright details.
- */
-
-/* guessed protocol description (reverse engineered):
- * read
- * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
- * 81 - <TS_LOCK> <current frequency divided by 250000>
- * 82 - crash - do not touch
- * 83 - crash - do not touch
- * 84 - remote control
- * 85 - crash - do not touch (OK, stop testing here)
- * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
- * 89 - noise-to-signal
- * 8a - unkown 1 byte - signal_strength
- * 8c - ber ???
- * 8d - ber
- * 8e - unc
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
*
- * write
- * 02 - bandwidth
- * 03 - frequency (divided by 250000)
- * 04 - pid table (index pid(7:0) pid(12:8))
- * 05 - reset the pid table
- * 08 - demod transfer enabled or not (FX2 transfer is enabled by default)
+ * see Documentation/dvb/README.dvb-usb for more information
*/
-
-#include "dvb-dibusb.h"
-#include "dvb_frontend.h"
+#include "dtt200u.h"
struct dtt200u_fe_state {
- struct usb_dibusb *dib;
+ struct dvb_usb_device *d;
struct dvb_frontend_parameters fep;
struct dvb_frontend frontend;
@@ -47,11 +23,11 @@ struct dtt200u_fe_state {
static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 bw[1] = { 0x81 };
+ u8 bw = GET_TUNE_STAT;
u8 br[3] = { 0 };
// u8 bdeb[5] = { 0 };
- dibusb_readwrite_usb(state->dib,bw,1,br,3);
+ dvb_usb_generic_rw(state->d,&bw,1,br,3,0);
switch (br[0]) {
case 0x01:
*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
@@ -60,12 +36,12 @@ static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
*stat = 0;
break;
default:
- moan("br[0]",0x81);
+ moan("br[0]",GET_TUNE_STAT);
break;
}
// bw[0] = 0x88;
-// dibusb_readwrite_usb(state->dib,bw,1,bdeb,5);
+// dvb_usb_generic_rw(state->d,bw,1,bdeb,5,0);
// deb_info("%02x: %02x %02x %02x %02x %02x\n",bw[0],bdeb[0],bdeb[1],bdeb[2],bdeb[3],bdeb[4]);
@@ -74,27 +50,26 @@ static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 bw[1] = { 0x8d };
+ u8 bw = GET_BER;
*ber = 0;
- dibusb_readwrite_usb(state->dib,bw,1,(u8*) ber, 3);
+ dvb_usb_generic_rw(state->d,&bw,1,(u8*) ber,3,0);
return 0;
}
static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 bw[1] = { 0x8c };
+ u8 bw = GET_UNK;
*unc = 0;
- dibusb_readwrite_usb(state->dib,bw,1,(u8*) unc, 3);
+ dvb_usb_generic_rw(state->d,&bw,1,(u8*) unc,3,0);
return 0;
}
static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 bw[1] = { 0x8a };
- u8 b;
- dibusb_readwrite_usb(state->dib,bw,1,&b, 1);
+ u8 bw = GET_SIG_STRENGTH, b;
+ dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
*strength = (b << 8) | b;
return 0;
}
@@ -102,18 +77,17 @@ static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strengt
static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 bw[1] = { 0x89 };
- u8 br[1] = { 0 };
- dibusb_readwrite_usb(state->dib,bw,1,br,1);
- *snr = ((0xff - br[0]) << 8) | (0xff - br[0]);
+ u8 bw = GET_SNR,br;
+ dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
+ *snr = ~((br << 8) | br);
return 0;
}
static int dtt200u_fe_init(struct dvb_frontend* fe)
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
- u8 b[] = { 0x01 };
- return dibusb_write_usb(state->dib,b,1);
+ u8 b = RESET_DEMOD;
+ return dvb_usb_generic_write(state->d,&b,1);
}
static int dtt200u_fe_sleep(struct dvb_frontend* fe)
@@ -134,7 +108,7 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
{
struct dtt200u_fe_state *state = fe->demodulator_priv;
u16 freq = fep->frequency / 250000;
- u8 bw,bwbuf[2] = { 0x03, 0 }, freqbuf[3] = { 0x02, 0, 0 };
+ u8 bw,bwbuf[2] = { SET_BANDWIDTH, 0 }, freqbuf[3] = { SET_FREQUENCY, 0, 0 };
switch (fep->u.ofdm.bandwidth) {
case BANDWIDTH_8_MHZ: bw = 8; break;
@@ -147,11 +121,11 @@ static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
deb_info("set_frontend\n");
bwbuf[1] = bw;
- dibusb_write_usb(state->dib,bwbuf,2);
+ dvb_usb_generic_write(state->d,bwbuf,2);
freqbuf[1] = freq & 0xff;
freqbuf[2] = (freq >> 8) & 0xff;
- dibusb_write_usb(state->dib,freqbuf,3);
+ dvb_usb_generic_write(state->d,freqbuf,3);
memcpy(&state->fep,fep,sizeof(struct dvb_frontend_parameters));
@@ -172,37 +146,9 @@ static void dtt200u_fe_release(struct dvb_frontend* fe)
kfree(state);
}
-static int dtt200u_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
-{
- struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
- u8 b_pid[4];
- pid = onoff ? pid : 0;
-
- b_pid[0] = 0x04;
- b_pid[1] = index;
- b_pid[2] = pid & 0xff;
- b_pid[3] = (pid >> 8) & 0xff;
-
- dibusb_write_usb(state->dib,b_pid,4);
- return 0;
-}
-
-static int dtt200u_fifo_control(struct dvb_frontend *fe, int onoff)
-{
- struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
- u8 b_streaming[2] = { 0x08, onoff };
- u8 b_rst_pid[1] = { 0x05 };
-
- dibusb_write_usb(state->dib,b_streaming,2);
-
- if (!onoff)
- dibusb_write_usb(state->dib,b_rst_pid,1);
- return 0;
-}
-
static struct dvb_frontend_ops dtt200u_fe_ops;
-struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *dib, struct dib_fe_xfer_ops *xfer_ops)
+struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
{
struct dtt200u_fe_state* state = NULL;
@@ -214,14 +160,11 @@ struct dvb_frontend* dtt200u_fe_attach(struct usb_dibusb *dib, struct dib_fe_xfe
deb_info("attaching frontend dtt200u\n");
- state->dib = dib;
+ state->d = d;
state->frontend.ops = &dtt200u_fe_ops;
state->frontend.demodulator_priv = state;
- xfer_ops->fifo_ctrl = dtt200u_fifo_control;
- xfer_ops->pid_ctrl = dtt200u_pid_control;
-
goto success;
error:
return NULL;
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
new file mode 100644
index 00000000000..fb2b5a2da13
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -0,0 +1,171 @@
+/* DVB USB library compliant Linux driver for the Yakumo/Hama/Typhoon DVB-T
+ * USB2.0 receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dtt200u.h"
+
+/* debug */
+int dvb_usb_dtt200u_debug;
+module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
+
+static int dtt200u_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 b_streaming[2] = { SET_TS_CTRL, onoff };
+ u8 b_rst_pid = RESET_PID_FILTER;
+
+ dvb_usb_generic_write(d,b_streaming,2);
+
+ if (!onoff)
+ dvb_usb_generic_write(d,&b_rst_pid,1);
+ return 0;
+}
+
+static int dtt200u_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
+{
+ u8 b_pid[4];
+ pid = onoff ? pid : 0;
+
+ b_pid[0] = SET_PID_FILTER;
+ b_pid[1] = index;
+ b_pid[2] = pid & 0xff;
+ b_pid[3] = (pid >> 8) & 0xff;
+
+ return dvb_usb_generic_write(d,b_pid,4);
+}
+
+/* remote control */
+/* key list for the tiny remote control (Yakumo, don't know about the others) */
+static struct dvb_usb_rc_key dtt200u_rc_keys[] = {
+ { 0x80, 0x01, KEY_MUTE },
+ { 0x80, 0x02, KEY_CHANNELDOWN },
+ { 0x80, 0x03, KEY_VOLUMEDOWN },
+ { 0x80, 0x04, KEY_1 },
+ { 0x80, 0x05, KEY_2 },
+ { 0x80, 0x06, KEY_3 },
+ { 0x80, 0x07, KEY_4 },
+ { 0x80, 0x08, KEY_5 },
+ { 0x80, 0x09, KEY_6 },
+ { 0x80, 0x0a, KEY_7 },
+ { 0x00, 0x0c, KEY_ZOOM },
+ { 0x80, 0x0d, KEY_0 },
+ { 0x00, 0x0e, KEY_SELECT },
+ { 0x80, 0x12, KEY_POWER },
+ { 0x80, 0x1a, KEY_CHANNELUP },
+ { 0x80, 0x1b, KEY_8 },
+ { 0x80, 0x1e, KEY_VOLUMEUP },
+ { 0x80, 0x1f, KEY_9 },
+};
+
+static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ u8 key[5],cmd = GET_RC_KEY;
+ dvb_usb_generic_rw(d,&cmd,1,key,5,0);
+ dvb_usb_nec_rc_key_to_event(d,key,event,state);
+ if (key[0] != 0)
+ deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
+ return 0;
+}
+
+static int dtt200u_frontend_attach(struct dvb_usb_device *d)
+{
+ d->fe = dtt200u_fe_attach(d);
+ return 0;
+}
+
+static struct dvb_usb_properties dtt200u_properties;
+
+static int dtt200u_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE);
+}
+
+static struct usb_device_id dtt200u_usb_table [] = {
+ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_COLD) },
+ { USB_DEVICE(USB_VID_AVERMEDIA_UNK, USB_PID_DTT200U_WARM) },
+ { 0 },
+};
+MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
+
+static struct dvb_usb_properties dtt200u_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING,
+ .pid_filter_count = 255, /* It is a guess, but there are at least 10 */
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-dtt200u-01.fw",
+
+ .streaming_ctrl = dtt200u_streaming_ctrl,
+ .pid_filter = dtt200u_pid_filter,
+ .frontend_attach = dtt200u_frontend_attach,
+
+ .rc_interval = 200,
+ .rc_key_map = dtt200u_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys),
+ .rc_query = dtt200u_rc_query,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x02,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { .name = "Yakumo/Hama/Typhoon DVB-T USB2.0)",
+ .cold_ids = { &dtt200u_usb_table[0], &dtt200u_usb_table[2] },
+ .warm_ids = { &dtt200u_usb_table[1], NULL },
+ },
+ { 0 },
+ }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver dtt200u_usb_driver = {
+ .owner = THIS_MODULE,
+ .name = "Yakumo/Hama/Typhoon DVB-T USB2.0",
+ .probe = dtt200u_usb_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = dtt200u_usb_table,
+};
+
+/* module stuff */
+static int __init dtt200u_usb_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&dtt200u_usb_driver))) {
+ err("usb_register failed. (%d)",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit dtt200u_usb_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&dtt200u_usb_driver);
+}
+
+module_init(dtt200u_usb_module_init);
+module_exit(dtt200u_usb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for the Yakumo/Hama/Typhoon DVB-T USB2.0 device");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
new file mode 100644
index 00000000000..ed414207151
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.h
@@ -0,0 +1,66 @@
+/* Common header file of Linux driver for the Yakumo/Hama/Typhoon DVB-T
+ * USB2.0 receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_DTT200U_H_
+#define _DVB_USB_DTT200U_H_
+
+#define DVB_USB_LOG_PREFIX "dtt200u"
+#include "dvb-usb.h"
+
+extern int dvb_usb_dtt200u_debug;
+#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args)
+
+/* guessed protocol description (reverse engineered):
+ * read
+ * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
+ * 81 - <TS_LOCK> <current frequency divided by 250000>
+ * 82 - crash - do not touch
+ * 83 - crash - do not touch
+ * 84 - remote control
+ * 85 - crash - do not touch (OK, stop testing here)
+ * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
+ * 89 - noise-to-signal
+ * 8a - unkown 1 byte - signal_strength
+ * 8c - ber ???
+ * 8d - ber
+ * 8e - unc
+ */
+
+#define GET_SPEED 0x00
+#define GET_TUNE_STAT 0x81
+#define GET_RC_KEY 0x84
+#define GET_STATUS 0x88
+#define GET_SNR 0x89
+#define GET_SIG_STRENGTH 0x8a
+#define GET_UNK 0x8c
+#define GET_BER 0x8d
+#define GET_UNC 0x8e
+
+/* write
+ * 01 - reset the demod
+ * 02 - frequency (divided by 250000)
+ * 03 - bandwidth
+ * 04 - pid table (index pid(7:0) pid(12:8))
+ * 05 - reset the pid table
+ * 08 - demod transfer enabled or not (FX2 transfer is enabled by default)
+ */
+
+#define RESET_DEMOD 0x01
+#define SET_FREQUENCY 0x02
+#define SET_BANDWIDTH 0x03
+#define SET_PID_FILTER 0x04
+#define RESET_PID_FILTER 0x05
+#define SET_TS_CTRL 0x08
+
+extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
new file mode 100644
index 00000000000..67e0d73fbce
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -0,0 +1,44 @@
+/* dvb-usb-common.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * a header file containing prototypes and types for internal use of the dvb-usb-lib
+ */
+#ifndef _DVB_USB_COMMON_H_
+#define _DVB_USB_COMMON_H_
+
+#define DVB_USB_LOG_PREFIX "dvb-usb"
+#include "dvb-usb.h"
+
+extern int dvb_usb_debug;
+
+#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args)
+#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args)
+#define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args)
+#define deb_err(args...) dprintk(dvb_usb_debug,0x10,args)
+#define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args)
+#define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args)
+
+/* commonly used methods */
+extern int usb_cypress_load_firmware(struct usb_device *, const char *, int);
+
+extern int dvb_usb_urb_submit(struct dvb_usb_device *);
+extern int dvb_usb_urb_kill(struct dvb_usb_device *);
+extern int dvb_usb_urb_init(struct dvb_usb_device *);
+extern int dvb_usb_urb_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_i2c_init(struct dvb_usb_device *);
+extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_dvb_init(struct dvb_usb_device *);
+extern int dvb_usb_dvb_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_fe_init(struct dvb_usb_device *);
+extern int dvb_usb_fe_exit(struct dvb_usb_device *);
+
+extern int dvb_usb_remote_init(struct dvb_usb_device *);
+extern int dvb_usb_remote_exit(struct dvb_usb_device *);
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
new file mode 100644
index 00000000000..bdd72f77970
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -0,0 +1,210 @@
+/* dvb-usb-dvb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing and handling the
+ * linux-dvb API.
+ */
+#include "dvb-usb-common.h"
+
+static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
+{
+ struct dvb_usb_device *d = dvbdmxfeed->demux->priv;
+ int newfeedcount,ret;
+
+ if (d == NULL)
+ return -ENODEV;
+
+ newfeedcount = d->feedcount + (onoff ? 1 : -1);
+
+ /*
+ * stop feed before setting a new pid if there will be no pid anymore
+ */
+ if (newfeedcount == 0) {
+ deb_ts("stop feeding\n");
+
+ if (d->props.streaming_ctrl != NULL)
+ if ((ret = d->props.streaming_ctrl(d,0)))
+ err("error while stopping stream.");
+
+ dvb_usb_urb_kill(d);
+ }
+
+ d->feedcount = newfeedcount;
+
+ /* activate the pid on the device specific pid_filter */
+ deb_ts("setting pid: %5d %04x at index %d '%s'\n",dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? "on" : "off");
+ if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
+ d->pid_filtering &&
+ d->props.pid_filter != NULL)
+ d->props.pid_filter(d,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+
+ /* start the feed if this was the first feed and there is still a feed
+ * for reception.
+ */
+ if (d->feedcount == onoff && d->feedcount > 0) {
+
+ deb_ts("controlling pid parser\n");
+ if (d->props.caps & DVB_USB_HAS_PID_FILTER &&
+ d->props.caps & DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF &&
+ d->props.pid_filter_ctrl != NULL)
+ if (d->props.pid_filter_ctrl(d,d->pid_filtering) < 0)
+ err("could not handle pid_parser");
+
+ deb_ts("start feeding\n");
+ if (d->props.streaming_ctrl != NULL)
+ if (d->props.streaming_ctrl(d,1)) {
+ err("error while enabling fifo.");
+ return -ENODEV;
+ }
+
+ dvb_usb_urb_submit(d);
+ }
+ return 0;
+}
+
+static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
+ return dvb_usb_ctrl_feed(dvbdmxfeed,1);
+}
+
+static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
+{
+ deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
+ return dvb_usb_ctrl_feed(dvbdmxfeed,0);
+}
+
+int dvb_usb_dvb_init(struct dvb_usb_device *d)
+{
+ int ret;
+
+ if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name,
+ d->owner)) < 0) {
+ deb_info("dvb_register_adapter failed: error %d", ret);
+ goto err;
+ }
+ d->dvb_adap.priv = d;
+
+ if (d->props.read_mac_address) {
+ if (d->props.read_mac_address(d,d->dvb_adap.proposed_mac) == 0)
+ info("MAC address: %02x:%02x:%02x:%02x:%02x:%02x",d->dvb_adap.proposed_mac[0],
+ d->dvb_adap.proposed_mac[1],d->dvb_adap.proposed_mac[2],
+ d->dvb_adap.proposed_mac[3],d->dvb_adap.proposed_mac[4],
+ d->dvb_adap.proposed_mac[5]);
+ else
+ err("MAC address reading failed.");
+ }
+
+
+ d->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
+ d->demux.priv = d;
+
+ d->demux.feednum = d->demux.filternum = d->max_feed_count;
+ d->demux.start_feed = dvb_usb_start_feed;
+ d->demux.stop_feed = dvb_usb_stop_feed;
+ d->demux.write_to_decoder = NULL;
+ if ((ret = dvb_dmx_init(&d->demux)) < 0) {
+ err("dvb_dmx_init failed: error %d",ret);
+ goto err_dmx;
+ }
+
+ d->dmxdev.filternum = d->demux.filternum;
+ d->dmxdev.demux = &d->demux.dmx;
+ d->dmxdev.capabilities = 0;
+ if ((ret = dvb_dmxdev_init(&d->dmxdev, &d->dvb_adap)) < 0) {
+ err("dvb_dmxdev_init failed: error %d",ret);
+ goto err_dmx_dev;
+ }
+
+ dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx);
+
+ goto success;
+err_dmx_dev:
+ dvb_dmx_release(&d->demux);
+err_dmx:
+ dvb_unregister_adapter(&d->dvb_adap);
+err:
+ return ret;
+success:
+ d->state |= DVB_USB_STATE_DVB;
+ return 0;
+}
+
+int dvb_usb_dvb_exit(struct dvb_usb_device *d)
+{
+ if (d->state & DVB_USB_STATE_DVB) {
+ deb_info("unregistering DVB part\n");
+ dvb_net_release(&d->dvb_net);
+ d->demux.dmx.close(&d->demux.dmx);
+ dvb_dmxdev_release(&d->dmxdev);
+ dvb_dmx_release(&d->demux);
+ dvb_unregister_adapter(&d->dvb_adap);
+ d->state &= ~DVB_USB_STATE_DVB;
+ }
+ return 0;
+}
+
+static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+
+ if (d->props.power_ctrl)
+ d->props.power_ctrl(d,1);
+
+ if (d->fe_init)
+ d->fe_init(fe);
+
+ return 0;
+}
+
+static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+
+ if (d->fe_sleep)
+ d->fe_sleep(fe);
+
+ if (d->props.power_ctrl)
+ d->props.power_ctrl(d,0);
+
+ return 0;
+}
+
+int dvb_usb_fe_init(struct dvb_usb_device* d)
+{
+ if (d->props.frontend_attach == NULL) {
+ err("strange '%s' don't want to attach a frontend.",d->desc->name);
+ return 0;
+ }
+
+ d->props.frontend_attach(d);
+
+ /* re-assign sleep and wakeup functions */
+ if (d->fe != NULL) {
+ d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup;
+ d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep;
+
+ if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
+ err("Frontend registration failed.");
+ if (d->fe->ops->release)
+ d->fe->ops->release(d->fe);
+ d->fe = NULL;
+ return -ENODEV;
+ }
+ } else
+ err("no frontend was attached by '%s'",d->desc->name);
+
+ if (d->props.tuner_attach != NULL)
+ d->props.tuner_attach(d);
+
+ return 0;
+}
+
+int dvb_usb_fe_exit(struct dvb_usb_device *d)
+{
+ if (d->fe != NULL)
+ dvb_unregister_frontend(d->fe);
+ return 0;
+}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
new file mode 100644
index 00000000000..5244e39770a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
@@ -0,0 +1,100 @@
+/* dvb-usb-firmware.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
+ *
+ * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem.
+ */
+#include "dvb-usb-common.h"
+
+#include <linux/firmware.h>
+#include <linux/usb.h>
+
+struct usb_cypress_controller {
+ int id;
+ const char *name; /* name of the usb controller */
+ u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */
+};
+
+static struct usb_cypress_controller cypress[] = {
+ { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
+ { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
+ { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
+};
+
+/*
+ * load a firmware packet to the device
+ */
+static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
+{
+ return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+ 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ);
+}
+
+int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type)
+{
+ const struct firmware *fw = NULL;
+ u16 addr;
+ u8 *b,*p;
+ int ret = 0,i;
+
+ if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) {
+ err("did not find the firmware file. (%s) "
+ "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
+ filename);
+ return ret;
+ }
+
+ info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name);
+
+ p = kmalloc(fw->size,GFP_KERNEL);
+ if (p != NULL) {
+ u8 reset;
+ /*
+ * you cannot use the fw->data as buffer for
+ * usb_control_msg, a new buffer has to be
+ * created
+ */
+ memcpy(p,fw->data,fw->size);
+
+ /* stop the CPU */
+ reset = 1;
+ if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
+ err("could not stop the USB controller CPU.");
+ for(i = 0; p[i+3] == 0 && i < fw->size; ) {
+ b = (u8 *) &p[i];
+ addr = cpu_to_le16( *((u16 *) &b[1]) );
+
+ deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]);
+
+ ret = usb_cypress_writemem(udev,addr,&b[4],b[0]);
+
+ if (ret != b[0]) {
+ err("error while transferring firmware "
+ "(transferred size: %d, block size: %d)",
+ ret,b[0]);
+ ret = -EINVAL;
+ break;
+ }
+ i += 5 + b[0];
+ }
+ /* length in ret */
+ if (ret > 0)
+ ret = 0;
+ /* restart the CPU */
+ reset = 0;
+ if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
+ err("could not restart the USB controller CPU.");
+ ret = -EINVAL;
+ }
+
+ kfree(p);
+ } else {
+ ret = -ENOMEM;
+ }
+ release_firmware(fw);
+
+ return ret;
+}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
new file mode 100644
index 00000000000..9f0a8d90d14
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -0,0 +1,118 @@
+/* dvb-usb-i2c.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for (de-)initializing an I2C adapter.
+ */
+#include "dvb-usb-common.h"
+
+int dvb_usb_i2c_init(struct dvb_usb_device *d)
+{
+ int ret = 0;
+
+ if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER))
+ return 0;
+
+ if (d->props.i2c_algo == NULL) {
+ err("no i2c algorithm specified");
+ return -EINVAL;
+ }
+
+ strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE);
+#ifdef I2C_ADAP_CLASS_TV_DIGITAL
+ d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
+#else
+ d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
+#endif
+ d->i2c_adap.algo = d->props.i2c_algo;
+ d->i2c_adap.algo_data = NULL;
+ d->i2c_adap.id = I2C_ALGO_BIT;
+
+ i2c_set_adapdata(&d->i2c_adap, d);
+
+ if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
+ err("could not add i2c adapter");
+
+ d->state |= DVB_USB_STATE_I2C;
+
+ return ret;
+}
+
+int dvb_usb_i2c_exit(struct dvb_usb_device *d)
+{
+ if (d->state & DVB_USB_STATE_I2C)
+ i2c_del_adapter(&d->i2c_adap);
+ d->state &= ~DVB_USB_STATE_I2C;
+ return 0;
+}
+
+int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+ struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
+ int ret = 0;
+
+ /* if there is nothing to initialize */
+ if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 &&
+ d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00)
+ return 0;
+
+ if (d->tuner_pass_ctrl)
+ d->tuner_pass_ctrl(fe,1,d->pll_addr);
+
+ deb_pll("pll init: %x\n",d->pll_addr);
+ deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1],
+ d->pll_init[2],d->pll_init[3]);
+
+ if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
+ err("tuner i2c write failed for pll_init.");
+ ret = -EREMOTEIO;
+ }
+ msleep(1);
+
+ if (d->tuner_pass_ctrl)
+ d->tuner_pass_ctrl(fe,0,d->pll_addr);
+ return ret;
+}
+EXPORT_SYMBOL(dvb_usb_pll_init_i2c);
+
+int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5])
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+
+ deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
+
+ b[0] = d->pll_addr << 1;
+ dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth);
+
+ deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]);
+
+ return 0;
+}
+EXPORT_SYMBOL(dvb_usb_pll_set);
+
+int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+ int ret = 0;
+ u8 b[5];
+ struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
+
+ dvb_usb_pll_set(fe,fep,b);
+
+ if (d->tuner_pass_ctrl)
+ d->tuner_pass_ctrl(fe,1,d->pll_addr);
+
+ if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
+ err("tuner i2c write failed for pll_set.");
+ ret = -EREMOTEIO;
+ }
+ msleep(1);
+
+ if (d->tuner_pass_ctrl)
+ d->tuner_pass_ctrl(fe,0,d->pll_addr);
+
+ return ret;
+}
+EXPORT_SYMBOL(dvb_usb_pll_set_i2c);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
new file mode 100644
index 00000000000..bcb34191868
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -0,0 +1,83 @@
+/* dvb-usb-ids.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) see
+ * dvb-usb-init.c for copyright information.
+ *
+ * a header file containing define's for the USB device supported by the
+ * various drivers.
+ */
+#ifndef _DVB_USB_IDS_H_
+#define _DVB_USB_IDS_H_
+
+/* Vendor IDs */
+#define USB_VID_ADSTECH 0x06e1
+#define USB_VID_ANCHOR 0x0547
+#define USB_VID_AVERMEDIA_UNK 0x14aa
+#define USB_VID_AVERMEDIA 0x07ca
+#define USB_VID_COMPRO 0x185b
+#define USB_VID_COMPRO_UNK 0x145f
+#define USB_VID_CYPRESS 0x04b4
+#define USB_VID_DIBCOM 0x10b8
+#define USB_VID_DVICO 0x0fe9
+#define USB_VID_EMPIA 0xeb1a
+#define USB_VID_GRANDTEC 0x5032
+#define USB_VID_HANFTEK 0x15f4
+#define USB_VID_HAUPPAUGE 0x2040
+#define USB_VID_HYPER_PALTEK 0x1025
+#define USB_VID_VISIONPLUS 0x13d3
+#define USB_VID_TWINHAN 0x1822
+#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
+
+/* Product IDs */
+#define USB_PID_ADSTECH_USB2_COLD 0xa333
+#define USB_PID_ADSTECH_USB2_WARM 0xa334
+#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
+#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
+#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
+#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801
+#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
+#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
+#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
+#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
+#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
+#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
+#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
+#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
+#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
+#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
+#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
+#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
+#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
+#define USB_PID_TWINHAN_VP7041_COLD 0x3201
+#define USB_PID_TWINHAN_VP7041_WARM 0x3202
+#define USB_PID_TWINHAN_VP7045_COLD 0x3205
+#define USB_PID_TWINHAN_VP7045_WARM 0x3206
+#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
+#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
+#define USB_PID_TWINHAN_VP7021_COLD 0x3207
+#define USB_PID_TWINHAN_VP7021_WARM 0x3208
+#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
+#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
+#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
+#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
+#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
+#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
+#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
+#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
+#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
+#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
+#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
+#define USB_PID_DTT200U_COLD 0x0201
+#define USB_PID_DTT200U_WARM 0x0301
+#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
+#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
+#define USB_PID_NEBULA_DIGITV 0x0201
+#define USB_PID_DVICO_BLUEBIRD_LGZ201 0xdb00
+#define USB_PID_DVICO_BLUEBIRD_TH7579 0xdb10
+#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
+#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01
+#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11
+
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
new file mode 100644
index 00000000000..3aadec974cf
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -0,0 +1,211 @@
+/*
+ * DVB USB library - provides a generic interface for a DVB USB device driver.
+ *
+ * dvb-usb-init.c
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dvb-usb-common.h"
+
+/* debug */
+int dvb_usb_debug;
+module_param_named(debug,dvb_usb_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." DVB_USB_DEBUG_STATUS);
+
+/* general initialization functions */
+int dvb_usb_exit(struct dvb_usb_device *d)
+{
+ deb_info("state before exiting everything: %x\n",d->state);
+ dvb_usb_remote_exit(d);
+ dvb_usb_fe_exit(d);
+ dvb_usb_i2c_exit(d);
+ dvb_usb_dvb_exit(d);
+ dvb_usb_urb_exit(d);
+ deb_info("state should be zero now: %x\n",d->state);
+ d->state = DVB_USB_STATE_INIT;
+ kfree(d->priv);
+ kfree(d);
+ return 0;
+}
+
+static int dvb_usb_init(struct dvb_usb_device *d)
+{
+ int ret = 0;
+
+ sema_init(&d->usb_sem, 1);
+ sema_init(&d->i2c_sem, 1);
+
+ d->state = DVB_USB_STATE_INIT;
+
+/* check the capabilites and set appropriate variables */
+
+/* speed - when running at FULL speed we need a HW PID filter */
+ if (d->udev->speed == USB_SPEED_FULL && !(d->props.caps & DVB_USB_HAS_PID_FILTER)) {
+ err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a HW PID filter)");
+ return -ENODEV;
+ }
+
+ if ((d->udev->speed == USB_SPEED_FULL && d->props.caps & DVB_USB_HAS_PID_FILTER) ||
+ (d->props.caps & DVB_USB_NEED_PID_FILTERING)) {
+ info("will use the device's hw PID filter.");
+ d->pid_filtering = 1;
+ d->max_feed_count = d->props.pid_filter_count;
+ } else {
+ info("will pass the complete MPEG2 transport stream to the demuxer.");
+ d->pid_filtering = 0;
+ d->max_feed_count = 255;
+ }
+
+ if (d->props.power_ctrl)
+ d->props.power_ctrl(d,1);
+
+ if ((ret = dvb_usb_urb_init(d)) ||
+ (ret = dvb_usb_dvb_init(d)) ||
+ (ret = dvb_usb_i2c_init(d)) ||
+ (ret = dvb_usb_fe_init(d))) {
+ dvb_usb_exit(d);
+ return ret;
+ }
+
+ if ((ret = dvb_usb_remote_init(d)))
+ err("could not initialize remote control.");
+
+ if (d->props.power_ctrl)
+ d->props.power_ctrl(d,0);
+
+ return 0;
+}
+
+/* determine the name and the state of the just found USB device */
+static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_properties *props, int *cold)
+{
+ int i,j;
+ struct dvb_usb_device_description *desc = NULL;
+ *cold = -1;
+
+ for (i = 0; i < props->num_device_descs; i++) {
+
+ for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
+ deb_info("check for cold %x %x\n",props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
+ if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
+ props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
+ *cold = 1;
+ desc = &props->devices[i];
+ break;
+ }
+ }
+
+ if (desc != NULL)
+ break;
+
+ for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
+ deb_info("check for warm %x %x\n",props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
+ if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
+ props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
+ *cold = 0;
+ desc = &props->devices[i];
+ break;
+ }
+ }
+ }
+
+ if (desc != NULL && props->identify_state != NULL)
+ props->identify_state(udev,props,&desc,cold);
+
+ return desc;
+}
+
+/*
+ * USB
+ */
+int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct dvb_usb_device *d = NULL;
+ struct dvb_usb_device_description *desc = NULL;
+
+ int ret = -ENOMEM,cold=0;
+
+ if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) {
+ deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
+ return -ENODEV;
+ }
+
+ if (cold) {
+ info("found a '%s' in cold state, will try to load a firmware",desc->name);
+ ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl);
+ } else {
+ info("found a '%s' in warm state.",desc->name);
+ d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
+ if (d == NULL) {
+ err("no memory for 'struct dvb_usb_device'");
+ return ret;
+ }
+ memset(d,0,sizeof(struct dvb_usb_device));
+
+ d->udev = udev;
+ memcpy(&d->props,props,sizeof(struct dvb_usb_properties));
+ d->desc = desc;
+ d->owner = owner;
+
+ if (d->props.size_of_priv > 0) {
+ d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL);
+ if (d->priv == NULL) {
+ err("no memory for priv in 'struct dvb_usb_device'");
+ kfree(d);
+ return -ENOMEM;
+ }
+ memset(d->priv,0,d->props.size_of_priv);
+ }
+
+ usb_set_intfdata(intf, d);
+
+ ret = dvb_usb_init(d);
+ }
+
+ if (ret == 0)
+ info("%s successfully initialized and connected.",desc->name);
+ else
+ info("%s error while loading driver (%d)",desc->name,ret);
+ return ret;
+}
+EXPORT_SYMBOL(dvb_usb_device_init);
+
+void dvb_usb_device_exit(struct usb_interface *intf)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ const char *name = "generic DVB-USB module";
+
+ usb_set_intfdata(intf,NULL);
+ if (d != NULL && d->desc != NULL) {
+ name = d->desc->name;
+ dvb_usb_exit(d);
+ }
+ info("%s successfully deinitialized and disconnected.",name);
+
+}
+EXPORT_SYMBOL(dvb_usb_device_exit);
+
+/* module stuff */
+static int __init dvb_usb_module_init(void)
+{
+ return 0;
+}
+
+static void __exit dvb_usb_module_exit(void)
+{
+}
+
+module_init (dvb_usb_module_init);
+module_exit (dvb_usb_module_exit);
+
+MODULE_VERSION("0.3");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
new file mode 100644
index 00000000000..9f1e23f82ba
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -0,0 +1,175 @@
+/* dvb-usb-remote.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing the the input-device and for handling remote-control-queries.
+ */
+#include "dvb-usb-common.h"
+
+/* Remote-control poll function - called every dib->rc_query_interval ms to see
+ * whether the remote control has received anything.
+ *
+ * TODO: Fix the repeat rate of the input device.
+ */
+static void dvb_usb_read_remote_control(void *data)
+{
+ struct dvb_usb_device *d = data;
+ u32 event;
+ int state;
+
+ /* TODO: need a lock here. We can simply skip checking for the remote control
+ if we're busy. */
+
+ if (d->props.rc_query(d,&event,&state)) {
+ err("error while querying for an remote control event.");
+ goto schedule;
+ }
+
+
+ switch (state) {
+ case REMOTE_NO_KEY_PRESSED:
+ break;
+ case REMOTE_KEY_PRESSED:
+ deb_rc("key pressed\n");
+ d->last_event = event;
+ case REMOTE_KEY_REPEAT:
+ deb_rc("key repeated\n");
+ input_event(&d->rc_input_dev, EV_KEY, event, 1);
+ input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
+ input_sync(&d->rc_input_dev);
+ break;
+ default:
+ break;
+ }
+
+/* improved repeat handling ???
+ switch (state) {
+ case REMOTE_NO_KEY_PRESSED:
+ deb_rc("NO KEY PRESSED\n");
+ if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+ deb_rc("releasing event %d\n",d->last_event);
+ input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
+ input_sync(&d->rc_input_dev);
+ }
+ d->last_state = REMOTE_NO_KEY_PRESSED;
+ d->last_event = 0;
+ break;
+ case REMOTE_KEY_PRESSED:
+ deb_rc("KEY PRESSED\n");
+ deb_rc("pressing event %d\n",event);
+
+ input_event(&d->rc_input_dev, EV_KEY, event, 1);
+ input_sync(&d->rc_input_dev);
+
+ d->last_event = event;
+ d->last_state = REMOTE_KEY_PRESSED;
+ break;
+ case REMOTE_KEY_REPEAT:
+ deb_rc("KEY_REPEAT\n");
+ if (d->last_state != REMOTE_NO_KEY_PRESSED) {
+ deb_rc("repeating event %d\n",d->last_event);
+ input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2);
+ input_sync(&d->rc_input_dev);
+ d->last_state = REMOTE_KEY_REPEAT;
+ }
+ default:
+ break;
+ }
+*/
+
+schedule:
+ schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
+}
+
+int dvb_usb_remote_init(struct dvb_usb_device *d)
+{
+ int i;
+ if (d->props.rc_key_map == NULL)
+ return 0;
+
+ /* Initialise the remote-control structures.*/
+ init_input_dev(&d->rc_input_dev);
+
+ d->rc_input_dev.evbit[0] = BIT(EV_KEY);
+ d->rc_input_dev.keycodesize = sizeof(unsigned char);
+ d->rc_input_dev.keycodemax = KEY_MAX;
+ d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver";
+
+ /* set the bits for the keys */
+ deb_rc("key map size: %d\n",d->props.rc_key_map_size);
+ for (i = 0; i < d->props.rc_key_map_size; i++) {
+ deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
+ set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit);
+ }
+
+ /* Start the remote-control polling. */
+ if (d->props.rc_interval < 40)
+ d->props.rc_interval = 100; /* default */
+
+ /* setting these two values to non-zero, we have to manage key repeats */
+ d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval;
+ d->rc_input_dev.rep[REP_DELAY] = d->props.rc_interval + 150;
+
+ input_register_device(&d->rc_input_dev);
+
+ INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
+
+ info("schedule remote query interval to %d msecs.",d->props.rc_interval);
+ schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
+
+ d->state |= DVB_USB_STATE_REMOTE;
+
+ return 0;
+}
+
+int dvb_usb_remote_exit(struct dvb_usb_device *d)
+{
+ if (d->state & DVB_USB_STATE_REMOTE) {
+ cancel_delayed_work(&d->rc_query_work);
+ flush_scheduled_work();
+ input_unregister_device(&d->rc_input_dev);
+ }
+ d->state &= ~DVB_USB_STATE_REMOTE;
+ return 0;
+}
+
+#define DVB_USB_RC_NEC_EMPTY 0x00
+#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
+#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
+int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
+ u8 keybuf[5], u32 *event, int *state)
+{
+ int i;
+ struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
+ *event = 0;
+ *state = REMOTE_NO_KEY_PRESSED;
+ switch (keybuf[0]) {
+ case DVB_USB_RC_NEC_EMPTY:
+ break;
+ case DVB_USB_RC_NEC_KEY_PRESSED:
+ if ((u8) ~keybuf[1] != keybuf[2] ||
+ (u8) ~keybuf[3] != keybuf[4]) {
+ deb_err("remote control checksum failed.\n");
+ break;
+ }
+ /* See if we can match the raw key code. */
+ for (i = 0; i < sizeof(keymap)/sizeof(struct dvb_usb_rc_key); i++)
+ if (keymap[i].custom == keybuf[1] &&
+ keymap[i].data == keybuf[3]) {
+ *event = keymap[i].event;
+ *state = REMOTE_KEY_PRESSED;
+ break;
+ }
+ deb_err("key mapping failed - no appropriate key found in keymapping\n");
+ break;
+ case DVB_USB_RC_NEC_KEY_REPEATED:
+ *state = REMOTE_KEY_REPEAT;
+ break;
+ default:
+ deb_err("unkown type of remote status: %d\n",keybuf[0]);
+ break;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
new file mode 100644
index 00000000000..83d476fb410
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -0,0 +1,211 @@
+/* dvb-usb-urb.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for initializing and handling the
+ * USB and URB stuff.
+ */
+#include "dvb-usb-common.h"
+
+int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
+ u16 rlen, int delay_ms)
+{
+ int actlen,ret = -ENOMEM;
+
+ if (d->props.generic_bulk_ctrl_endpoint == 0) {
+ err("endpoint for generic control not specified.");
+ return -EINVAL;
+ }
+
+ if (wbuf == NULL || wlen == 0)
+ return -EINVAL;
+
+ if ((ret = down_interruptible(&d->usb_sem)))
+ return ret;
+
+ debug_dump(wbuf,wlen,deb_xfer);
+
+ ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
+ d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
+ 2*HZ);
+
+ if (ret)
+ err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
+ else
+ ret = actlen != wlen ? -1 : 0;
+
+ /* an answer is expected, and no error before */
+ if (!ret && rbuf && rlen) {
+ if (delay_ms)
+ msleep(delay_ms);
+
+ ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
+ d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
+ 2*HZ);
+
+ if (ret)
+ err("recv bulk message failed: %d",ret);
+ else
+ debug_dump(rbuf,actlen,deb_xfer);
+ }
+
+ up(&d->usb_sem);
+ return ret;
+}
+EXPORT_SYMBOL(dvb_usb_generic_rw);
+
+int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
+{
+ return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
+}
+EXPORT_SYMBOL(dvb_usb_generic_write);
+
+static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+{
+ struct dvb_usb_device *d = urb->context;
+
+ deb_ts("bulk urb completed. feedcount: %d, status: %d, length: %d\n",d->feedcount,urb->status,
+ urb->actual_length);
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ deb_ts("urb completition error %d.", urb->status);
+ break;
+ }
+
+ if (d->feedcount > 0 && urb->actual_length > 0) {
+ if (d->state & DVB_USB_STATE_DVB)
+ dvb_dmx_swfilter(&d->demux, (u8*) urb->transfer_buffer,urb->actual_length);
+ } else
+ deb_ts("URB dropped because of feedcount.\n");
+
+ usb_submit_urb(urb,GFP_ATOMIC);
+}
+
+int dvb_usb_urb_kill(struct dvb_usb_device *d)
+{
+ int i;
+ for (i = 0; i < d->urbs_submitted; i++) {
+ deb_info("killing URB no. %d.\n",i);
+
+ /* stop the URB */
+ usb_kill_urb(d->urb_list[i]);
+ }
+ d->urbs_submitted = 0;
+ return 0;
+}
+
+int dvb_usb_urb_submit(struct dvb_usb_device *d)
+{
+ int i,ret;
+ for (i = 0; i < d->urbs_initialized; i++) {
+ deb_info("submitting URB no. %d\n",i);
+ if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
+ err("could not submit URB no. %d - get them all back\n",i);
+ dvb_usb_urb_kill(d);
+ return ret;
+ }
+ d->urbs_submitted++;
+ }
+ return 0;
+}
+
+static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
+{
+ int i,bufsize = d->props.urb.count * d->props.urb.u.bulk.buffersize;
+
+ deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
+ /* allocate the actual buffer for the URBs */
+ if ((d->buffer = usb_buffer_alloc(d->udev, bufsize, SLAB_ATOMIC, &d->dma_handle)) == NULL) {
+ deb_info("not enough memory for urb-buffer allocation.\n");
+ return -ENOMEM;
+ }
+ deb_info("allocation successful\n");
+ memset(d->buffer,0,bufsize);
+
+ d->state |= DVB_USB_STATE_URB_BUF;
+
+ /* allocate the URBs */
+ for (i = 0; i < d->props.urb.count; i++) {
+ if (!(d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
+ return -ENOMEM;
+ }
+
+ usb_fill_bulk_urb( d->urb_list[i], d->udev,
+ usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
+ &d->buffer[i*d->props.urb.u.bulk.buffersize],
+ d->props.urb.u.bulk.buffersize,
+ dvb_usb_bulk_urb_complete, d);
+
+ d->urb_list[i]->transfer_flags = 0;
+ d->urbs_initialized++;
+ }
+ return 0;
+}
+
+int dvb_usb_urb_init(struct dvb_usb_device *d)
+{
+ /*
+ * when reloading the driver w/o replugging the device
+ * sometimes a timeout occures, this helps
+ */
+ if (d->props.generic_bulk_ctrl_endpoint != 0) {
+ usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
+ usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
+ }
+ usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.urb.endpoint));
+
+ /* allocate the array for the data transfer URBs */
+ d->urb_list = kmalloc(d->props.urb.count * sizeof(struct urb *),GFP_KERNEL);
+ if (d->urb_list == NULL)
+ return -ENOMEM;
+ memset(d->urb_list,0,d->props.urb.count * sizeof(struct urb *));
+ d->state |= DVB_USB_STATE_URB_LIST;
+
+ switch (d->props.urb.type) {
+ case DVB_USB_BULK:
+ return dvb_usb_bulk_urb_init(d);
+ case DVB_USB_ISOC:
+ err("isochronous transfer not yet implemented in dvb-usb.");
+ return -EINVAL;
+ default:
+ err("unkown URB-type for data transfer.");
+ return -EINVAL;
+ }
+}
+
+int dvb_usb_urb_exit(struct dvb_usb_device *d)
+{
+ int i;
+
+ dvb_usb_urb_kill(d);
+
+ if (d->state & DVB_USB_STATE_URB_LIST) {
+ for (i = 0; i < d->urbs_initialized; i++) {
+ if (d->urb_list[i] != NULL) {
+ deb_info("freeing URB no. %d.\n",i);
+ /* free the URBs */
+ usb_free_urb(d->urb_list[i]);
+ }
+ }
+ d->urbs_initialized = 0;
+ /* free the urb array */
+ kfree(d->urb_list);
+ d->state &= ~DVB_USB_STATE_URB_LIST;
+ }
+
+ if (d->state & DVB_USB_STATE_URB_BUF)
+ usb_buffer_free(d->udev, d->props.urb.u.bulk.buffersize * d->props.urb.count,
+ d->buffer, d->dma_handle);
+
+ d->state &= ~DVB_USB_STATE_URB_BUF;
+ return 0;
+}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
new file mode 100644
index 00000000000..abcee1943f6
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -0,0 +1,315 @@
+/* dvb-usb.h is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * the headerfile, all dvb-usb-drivers have to include.
+ */
+#ifndef __DVB_USB_H__
+#define __DVB_USB_H__
+
+#include <linux/config.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "dvb_frontend.h"
+#include "dvb_demux.h"
+#include "dvb_net.h"
+#include "dmxdev.h"
+
+#include "dvb-pll.h"
+
+#include "dvb-usb-ids.h"
+
+/* debug */
+#ifdef CONFIG_DVB_USB_DEBUG
+#define dprintk(var,level,args...) \
+ do { if ((var & level)) { printk(args); } } while (0)
+
+#define debug_dump(b,l,func) {\
+ int loop_; \
+ for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \
+ func("\n");\
+}
+#define DVB_USB_DEBUG_STATUS
+#else
+#define dprintk(args...)
+#define debug_dump(b,l,func)
+
+#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
+
+#endif
+
+/* generic log methods - taken from usb.h */
+#ifndef DVB_USB_LOG_PREFIX
+ #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)"
+#endif
+
+#undef err
+#define err(format, arg...) printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef info
+#define info(format, arg...) printk(KERN_INFO DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
+
+/**
+ * struct dvb_usb_device_description - name and its according USB IDs
+ * @name: real name of the box, regardless which DVB USB device class is in use
+ * @cold_ids: array of struct usb_device_id which describe the device in
+ * pre-firmware state
+ * @warm_ids: array of struct usb_device_id which describe the device in
+ * post-firmware state
+ *
+ * Each DVB USB device class can have one or more actual devices, this struct
+ * assigns a name to it.
+ */
+struct dvb_usb_device_description {
+ const char *name;
+
+#define DVB_USB_ID_MAX_NUM 15
+ struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
+ struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
+};
+
+/**
+ * struct dvb_usb_rc_key - a remote control key and its input-event
+ * @custom: the vendor/custom part of the key
+ * @data: the actual key part
+ * @event: the input event assigned to key identified by custom and data
+ */
+struct dvb_usb_rc_key {
+ u8 custom,data;
+ u32 event;
+};
+
+struct dvb_usb_device;
+
+/**
+ * struct dvb_usb_properties - properties of a dvb-usb-device
+ * @caps: capabilites of the DVB USB device.
+ * @pid_filter_count: number of PID filter position in the optional hardware
+ * PID-filter.
+ *
+ * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
+ * download.
+ * @firmware: name of the firmware file.
+ *
+ * @size_of_priv: how many bytes shall be allocated for the private field
+ * of struct dvb_usb_device.
+ *
+ * @power_ctrl: called to enable/disable power of the device.
+ * @streaming_crtl: called to start and stop the MPEG2-TS streaming of the
+ * device (not URB submitting/killing).
+ * @pid_filter_ctrl: called to en/disable the PID filter, if any.
+ * @pid_filter: called to set/unset a PID for filtering.
+ *
+ * @read_mac_address: called to read the MAC address of the device.
+ *
+ * @frontend_attach: called to attach the possible frontends (fill fe-field
+ * of struct dvb_usb_device).
+ * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
+ * pll_desc and pll_init_buf of struct dvb_usb_device).
+ * @identify_state: called to determine the state (cold or warm), when it
+ * is not distinguishable by the USB IDs.
+ *
+ * @rc_key_map: a hard-wired array of struct dvb_usb_rc_key (NULL to disable
+ * remote control handling).
+ * @rc_key_map_size: number of items in @rc_key_map.
+ * @rc_query: called to query an event event.
+ * @rc_interval: time in ms between two queries.
+ *
+ * @i2c_algo: i2c_algorithm if the device has I2CoverUSB.
+ *
+ * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic
+ * endpoint which received control messages with bulk transfers. When this
+ * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
+ * helper functions.
+ *
+ * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming.
+ * Currently only BULK is implemented
+ *
+ * @num_device_descs: number of struct dvb_usb_device_description in @devices
+ * @devices: array of struct dvb_usb_device_description compatibles with these
+ * properties.
+ */
+struct dvb_usb_properties {
+
+#define DVB_USB_HAS_PID_FILTER 0x01
+#define DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF 0x02
+#define DVB_USB_NEED_PID_FILTERING 0x04
+#define DVB_USB_IS_AN_I2C_ADAPTER 0x08
+ int caps;
+ int pid_filter_count;
+
+#define CYPRESS_AN2135 0
+#define CYPRESS_AN2235 1
+#define CYPRESS_FX2 2
+ int usb_ctrl;
+ const char *firmware;
+
+ int size_of_priv;
+
+ int (*power_ctrl) (struct dvb_usb_device *, int);
+ int (*streaming_ctrl) (struct dvb_usb_device *, int);
+ int (*pid_filter_ctrl) (struct dvb_usb_device *, int);
+ int (*pid_filter) (struct dvb_usb_device *, int, u16, int);
+
+ int (*read_mac_address) (struct dvb_usb_device *, u8 []);
+ int (*frontend_attach) (struct dvb_usb_device *);
+ int (*tuner_attach) (struct dvb_usb_device *);
+
+ int (*identify_state) (struct usb_device *, struct dvb_usb_properties *,
+ struct dvb_usb_device_description **, int *);
+
+/* remote control properties */
+#define REMOTE_NO_KEY_PRESSED 0x00
+#define REMOTE_KEY_PRESSED 0x01
+#define REMOTE_KEY_REPEAT 0x02
+ struct dvb_usb_rc_key *rc_key_map;
+ int rc_key_map_size;
+ int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
+ int rc_interval;
+
+ struct i2c_algorithm *i2c_algo;
+
+ int generic_bulk_ctrl_endpoint;
+
+ struct {
+#define DVB_USB_BULK 1
+#define DVB_USB_ISOC 2
+ int type;
+ int count;
+ int endpoint;
+
+ union {
+ struct {
+ int buffersize; /* per URB */
+ } bulk;
+ struct {
+ int framesperurb;
+ int framesize;
+ } isoc;
+ } u;
+ } urb;
+
+ int num_device_descs;
+ struct dvb_usb_device_description devices[8];
+};
+
+
+/**
+ * struct dvb_usb_device - object of a DVB USB device
+ * @props: copy of the struct dvb_usb_properties this device belongs to.
+ * @desc: pointer to the device's struct dvb_usb_device_description.
+ * @state: initialization and runtime state of the device.
+ *
+ * @udev: pointer to the device's struct usb_device.
+ * @urb_list: array of dynamically allocated struct urb for the MPEG2-TS-
+ * streaming.
+ * @buffer: buffer used to streaming.
+ * @dma_handle: dma_addr_t for buffer.
+ * @urbs_initialized: number of URBs initialized.
+ * @urbs_submitted: number of URBs submitted.
+ * @feedcount: number of reqested feeds (used for streaming-activation)
+ * @pid_filtering: is hardware pid_filtering used or not.
+ * @usb_sem: semaphore of USB control messages (reading needs two messages)
+ * @i2c_sem: semaphore for i2c-transfers
+ * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
+ * @pll_addr: I2C address of the tuner for programming
+ * @pll_init: array containing the initialization buffer
+ * @pll_desc: pointer to the appropriate struct dvb_pll_desc
+ * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod
+ * @dvb_adap: device's dvb_adapter.
+ * @dmxdev: device's dmxdev.
+ * @demux: device's software demuxer.
+ * @dvb_net: device's dvb_net interfaces.
+ * @dvb_frontend: device's frontend.
+ * @max_feed_count: how many feeds can be handled simultaneously by this
+ * device
+ * @fe_sleep: rerouted frontend-sleep function.
+ * @fe_init: rerouted frontend-init (wakeup) function.
+ * @rc_input_dev: input device for the remote control.
+ * @rc_query_work: struct work_struct frequent rc queries
+ * @last_event: last triggered event
+ * @last_state: last state (no, pressed, repeat)
+ * @owner: owner of the dvb_adapter
+ * @priv: private data of the actual driver (allocate by dvb-usb, size defined
+ * in size_of_priv of dvb_usb_properties).
+ */
+struct dvb_usb_device {
+ struct dvb_usb_properties props;
+ struct dvb_usb_device_description *desc;
+
+#define DVB_USB_STATE_INIT 0x000
+#define DVB_USB_STATE_URB_LIST 0x001
+#define DVB_USB_STATE_URB_BUF 0x002
+#define DVB_USB_STATE_DVB 0x004
+#define DVB_USB_STATE_I2C 0x008
+#define DVB_USB_STATE_REMOTE 0x010
+#define DVB_USB_STATE_URB_SUBMIT 0x020
+ int state;
+
+ /* usb */
+ struct usb_device *udev;
+ struct urb **urb_list;
+ u8 *buffer;
+ dma_addr_t dma_handle;
+ int urbs_initialized;
+ int urbs_submitted;
+
+ int feedcount;
+ int pid_filtering;
+
+ /* locking */
+ struct semaphore usb_sem;
+
+ /* i2c */
+ struct semaphore i2c_sem;
+ struct i2c_adapter i2c_adap;
+
+ /* tuner programming information */
+ u8 pll_addr;
+ u8 pll_init[4];
+ struct dvb_pll_desc *pll_desc;
+ int (*tuner_pass_ctrl)(struct dvb_frontend *, int, u8);
+
+ /* dvb */
+ struct dvb_adapter dvb_adap;
+ struct dmxdev dmxdev;
+ struct dvb_demux demux;
+ struct dvb_net dvb_net;
+ struct dvb_frontend* fe;
+ int max_feed_count;
+
+ int (*fe_sleep) (struct dvb_frontend *);
+ int (*fe_init) (struct dvb_frontend *);
+
+ /* remote control */
+ struct input_dev rc_input_dev;
+ struct work_struct rc_query_work;
+ u32 last_event;
+ int last_state;
+
+ struct module *owner;
+
+ void *priv;
+};
+
+extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *);
+extern void dvb_usb_device_exit(struct usb_interface *);
+
+/* the generic read/write method for device control */
+extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
+extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
+
+/* commonly used remote control parsing */
+extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
+
+/* commonly used pll init and set functions */
+extern int dvb_usb_pll_init_i2c(struct dvb_frontend *);
+extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]);
+extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *);
+
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
new file mode 100644
index 00000000000..9d83781aef9
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -0,0 +1,236 @@
+/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2
+ * DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS);
+
+#define deb_rc(args...) dprintk(debug,0x01,args)
+#define deb_ee(args...) dprintk(debug,0x02,args)
+
+/* Hauppauge NOVA-T USB2 keys */
+static struct dvb_usb_rc_key haupp_rc_keys [] = {
+ { 0x1e, 0x00, KEY_0 },
+ { 0x1e, 0x01, KEY_1 },
+ { 0x1e, 0x02, KEY_2 },
+ { 0x1e, 0x03, KEY_3 },
+ { 0x1e, 0x04, KEY_4 },
+ { 0x1e, 0x05, KEY_5 },
+ { 0x1e, 0x06, KEY_6 },
+ { 0x1e, 0x07, KEY_7 },
+ { 0x1e, 0x08, KEY_8 },
+ { 0x1e, 0x09, KEY_9 },
+ { 0x1e, 0x0a, KEY_KPASTERISK },
+ { 0x1e, 0x0b, KEY_RED },
+ { 0x1e, 0x0c, KEY_RADIO },
+ { 0x1e, 0x0d, KEY_MENU },
+ { 0x1e, 0x0e, KEY_GRAVE }, /* # */
+ { 0x1e, 0x0f, KEY_MUTE },
+ { 0x1e, 0x10, KEY_VOLUMEUP },
+ { 0x1e, 0x11, KEY_VOLUMEDOWN },
+ { 0x1e, 0x12, KEY_CHANNEL },
+ { 0x1e, 0x14, KEY_UP },
+ { 0x1e, 0x15, KEY_DOWN },
+ { 0x1e, 0x16, KEY_LEFT },
+ { 0x1e, 0x17, KEY_RIGHT },
+ { 0x1e, 0x18, KEY_VIDEO },
+ { 0x1e, 0x19, KEY_AUDIO },
+ { 0x1e, 0x1a, KEY_MEDIA },
+ { 0x1e, 0x1b, KEY_EPG },
+ { 0x1e, 0x1c, KEY_TV },
+ { 0x1e, 0x1e, KEY_NEXT },
+ { 0x1e, 0x1f, KEY_BACK },
+ { 0x1e, 0x20, KEY_CHANNELUP },
+ { 0x1e, 0x21, KEY_CHANNELDOWN },
+ { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */
+ { 0x1e, 0x25, KEY_OK },
+ { 0x1e, 0x29, KEY_BLUE},
+ { 0x1e, 0x2e, KEY_GREEN },
+ { 0x1e, 0x30, KEY_PAUSE },
+ { 0x1e, 0x32, KEY_REWIND },
+ { 0x1e, 0x34, KEY_FASTFORWARD },
+ { 0x1e, 0x35, KEY_PLAY },
+ { 0x1e, 0x36, KEY_STOP },
+ { 0x1e, 0x37, KEY_RECORD },
+ { 0x1e, 0x38, KEY_YELLOW },
+ { 0x1e, 0x3b, KEY_GOTO },
+ { 0x1e, 0x3d, KEY_POWER },
+};
+
+/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
+ * is delivered. No workaround yet, maybe a new firmware.
+ */
+static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+{
+ u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
+ u16 raw;
+ int i;
+ struct dibusb_state *st = d->priv;
+
+ dvb_usb_generic_rw(d,cmd,2,key,5,0);
+
+ *state = REMOTE_NO_KEY_PRESSED;
+ switch (key[0]) {
+ case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
+ raw = ((key[1] << 8) | key[2]) >> 3;
+ toggle = !!(raw & 0x800);
+ data = raw & 0x3f;
+ custom = (raw >> 6) & 0x1f;
+
+ deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
+
+ for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) {
+ deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom);
+ if (haupp_rc_keys[i].data == data &&
+ haupp_rc_keys[i].custom == custom) {
+ *event = haupp_rc_keys[i].event;
+ *state = REMOTE_KEY_PRESSED;
+ if (st->old_toggle == toggle) {
+ if (st->last_repeat_count++ < 2)
+ *state = REMOTE_NO_KEY_PRESSED;
+ } else {
+ st->last_repeat_count = 0;
+ st->old_toggle = toggle;
+ }
+ break;
+ }
+ }
+
+ break;
+ case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
+{
+ int i;
+ u8 b;
+
+ mac[0] = 0x00;
+ mac[1] = 0x0d;
+ mac[2] = 0xfe;
+
+ /* this is a complete guess, but works for my box */
+ for (i = 136; i < 139; i++) {
+ dibusb_read_eeprom_byte(d,i, &b);
+
+ mac[5 - (i - 136)] = b;
+
+/* deb_ee("%02x ",b);
+ if ((i+1) % 16 == 0)
+ deb_ee("\n");*/
+ }
+
+ return 0;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_properties nova_t_properties;
+
+static int nova_t_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE);
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id nova_t_table [] = {
+/* 00 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) },
+/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, nova_t_table);
+
+static struct dvb_usb_properties nova_t_properties = {
+ .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER,
+ .pid_filter_count = 32,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-nova-t-usb2-01.fw",
+
+ .size_of_priv = sizeof(struct dibusb_state),
+
+ .streaming_ctrl = dibusb2_0_streaming_ctrl,
+ .pid_filter = dibusb_pid_filter,
+ .pid_filter_ctrl = dibusb_pid_filter_ctrl,
+ .power_ctrl = dibusb2_0_power_ctrl,
+ .frontend_attach = dibusb_dib3000mc_frontend_attach,
+ .tuner_attach = dibusb_dib3000mc_tuner_attach,
+ .read_mac_address = nova_t_read_mac_address,
+
+ .rc_interval = 100,
+ .rc_key_map = haupp_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(haupp_rc_keys),
+ .rc_query = nova_t_rc_query,
+
+ .i2c_algo = &dibusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x06,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { "Hauppauge WinTV-NOVA-T usb2",
+ { &nova_t_table[0], NULL },
+ { &nova_t_table[1], NULL },
+ },
+ }
+};
+
+static struct usb_driver nova_t_driver = {
+ .owner = THIS_MODULE,
+ .name = "Hauppauge WinTV-NOVA-T usb2",
+ .probe = nova_t_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = nova_t_table,
+};
+
+/* module stuff */
+static int __init nova_t_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&nova_t_driver))) {
+ err("usb_register failed. Error number %d",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit nova_t_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&nova_t_driver);
+}
+
+module_init (nova_t_module_init);
+module_exit (nova_t_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
new file mode 100644
index 00000000000..aa560422ce7
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -0,0 +1,162 @@
+/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0
+ * DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "dibusb.h"
+
+#include "mt352.h"
+
+static int umt_mt352_demod_init(struct dvb_frontend *fe)
+{
+ static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
+ static u8 mt352_reset[] = { 0x50, 0x80 };
+ static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
+ static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
+ static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
+
+ static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
+ static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
+ static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
+ static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
+ static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
+
+ static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
+ static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
+
+ mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
+ udelay(2000);
+ mt352_write(fe, mt352_reset, sizeof(mt352_reset));
+ mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
+
+ mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
+ mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
+
+ mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
+ mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
+ mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
+ mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
+ mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
+
+ mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
+ mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
+
+ return 0;
+}
+
+static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
+{
+ struct mt352_config umt_config;
+
+ memset(&umt_config,0,sizeof(struct mt352_config));
+ umt_config.demod_init = umt_mt352_demod_init;
+ umt_config.demod_address = 0xf;
+ umt_config.pll_set = dvb_usb_pll_set;
+
+ d->fe = mt352_attach(&umt_config, &d->i2c_adap);
+
+ return 0;
+}
+
+static int umt_tuner_attach (struct dvb_usb_device *d)
+{
+ d->pll_addr = 0x61;
+ d->pll_desc = &dvb_pll_tua6034;
+ return 0;
+}
+
+/* USB Driver stuff */
+static struct dvb_usb_properties umt_properties;
+
+static int umt_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0)
+ return 0;
+ return -EINVAL;
+}
+
+/* do not change the order of the ID table */
+static struct usb_device_id umt_table [] = {
+/* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
+/* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE (usb, umt_table);
+
+static struct dvb_usb_properties umt_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-umt-010-02.fw",
+
+ .size_of_priv = sizeof(struct dibusb_state),
+
+ .streaming_ctrl = dibusb2_0_streaming_ctrl,
+ .power_ctrl = dibusb_power_ctrl,
+ .frontend_attach = umt_mt352_frontend_attach,
+ .tuner_attach = umt_tuner_attach,
+
+ .i2c_algo = &dibusb_i2c_algo,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 20,
+ .endpoint = 0x06,
+ .u = {
+ .bulk = {
+ .buffersize = 512,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { "Hanftek UMT-010 DVB-T USB2.0",
+ { &umt_table[0], NULL },
+ { &umt_table[1], NULL },
+ },
+ }
+};
+
+static struct usb_driver umt_driver = {
+ .owner = THIS_MODULE,
+ .name = "HanfTek UMT-010 USB2.0 DVB-T devices",
+ .probe = umt_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = umt_table,
+};
+
+/* module stuff */
+static int __init umt_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&umt_driver))) {
+ err("usb_register failed. Error number %d",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit umt_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&umt_driver);
+}
+
+module_init (umt_module_init);
+module_exit (umt_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
new file mode 100644
index 00000000000..2746edfeccb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -0,0 +1,196 @@
+/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0
+ * DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ *
+ */
+#include "vp7045.h"
+
+/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT
+ *
+ * Programming is hidden inside the firmware, so set_frontend is very easy.
+ * Even though there is a Firmware command that one can use to access the demod
+ * via its registers. This is used for status information.
+ */
+
+struct vp7045_fe_state {
+ struct dvb_frontend fe;
+ struct dvb_usb_device *d;
+};
+
+
+static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+ struct vp7045_fe_state *state = fe->demodulator_priv;
+ u8 s0 = vp7045_read_reg(state->d,0x00),
+ s1 = vp7045_read_reg(state->d,0x01),
+ s3 = vp7045_read_reg(state->d,0x03);
+
+ *status = 0;
+ if (s0 & (1 << 4))
+ *status |= FE_HAS_CARRIER;
+ if (s0 & (1 << 1))
+ *status |= FE_HAS_VITERBI;
+ if (s0 & (1 << 5))
+ *status |= FE_HAS_LOCK;
+ if (s1 & (1 << 1))
+ *status |= FE_HAS_SYNC;
+ if (s3 & (1 << 6))
+ *status |= FE_HAS_SIGNAL;
+
+ if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
+ (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
+ *status &= ~FE_HAS_LOCK;
+
+ return 0;
+}
+
+static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+ struct vp7045_fe_state *state = fe->demodulator_priv;
+ *ber = (vp7045_read_reg(state->d, 0x0D) << 16) |
+ (vp7045_read_reg(state->d, 0x0E) << 8) |
+ vp7045_read_reg(state->d, 0x0F);
+ return 0;
+}
+
+static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+ struct vp7045_fe_state *state = fe->demodulator_priv;
+ *unc = (vp7045_read_reg(state->d, 0x10) << 8) |
+ vp7045_read_reg(state->d, 0x11);
+ return 0;
+}
+
+static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+ struct vp7045_fe_state *state = fe->demodulator_priv;
+ u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) |
+ vp7045_read_reg(state->d, 0x15);
+
+ *strength = ~signal;
+ return 0;
+}
+
+static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+ struct vp7045_fe_state *state = fe->demodulator_priv;
+ u8 _snr = vp7045_read_reg(state->d, 0x09);
+ *snr = (_snr << 8) | _snr;
+ return 0;
+}
+
+static int vp7045_fe_init(struct dvb_frontend* fe)
+{
+ return 0;
+}
+
+static int vp7045_fe_sleep(struct dvb_frontend* fe)
+{
+ return 0;
+}
+
+static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 800;
+ return 0;
+}
+
+static int vp7045_fe_set_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct vp7045_fe_state *state = fe->demodulator_priv;
+ u8 buf[5];
+ u32 freq = fep->frequency / 1000;
+
+ buf[0] = (freq >> 16) & 0xff;
+ buf[1] = (freq >> 8) & 0xff;
+ buf[2] = freq & 0xff;
+ buf[3] = 0;
+
+ switch (fep->u.ofdm.bandwidth) {
+ case BANDWIDTH_8_MHZ: buf[4] = 8; break;
+ case BANDWIDTH_7_MHZ: buf[4] = 7; break;
+ case BANDWIDTH_6_MHZ: buf[4] = 6; break;
+ case BANDWIDTH_AUTO: return -EOPNOTSUPP;
+ default:
+ return -EINVAL;
+ }
+
+ vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200);
+ return 0;
+}
+
+static int vp7045_fe_get_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
+{
+ return 0;
+}
+
+static void vp7045_fe_release(struct dvb_frontend* fe)
+{
+ struct vp7045_fe_state *state = fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops vp7045_fe_ops;
+
+struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
+{
+ struct vp7045_fe_state *s = kmalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL);
+ if (s == NULL)
+ goto error;
+ memset(s,0,sizeof(struct vp7045_fe_state));
+
+ s->d = d;
+ s->fe.ops = &vp7045_fe_ops;
+ s->fe.demodulator_priv = s;
+
+ goto success;
+error:
+ return NULL;
+success:
+ return &s->fe;
+}
+
+
+static struct dvb_frontend_ops vp7045_fe_ops = {
+ .info = {
+ .name = "Twinhan VP7045/46 USB DVB-T",
+ .type = FE_OFDM,
+ .frequency_min = 44250000,
+ .frequency_max = 867250000,
+ .frequency_stepsize = 1000,
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_RECOVER |
+ FE_CAN_HIERARCHY_AUTO,
+ },
+
+ .release = vp7045_fe_release,
+
+ .init = vp7045_fe_init,
+ .sleep = vp7045_fe_sleep,
+
+ .set_frontend = vp7045_fe_set_frontend,
+ .get_frontend = vp7045_fe_get_frontend,
+ .get_tune_settings = vp7045_fe_get_tune_settings,
+
+ .read_status = vp7045_fe_read_status,
+ .read_ber = vp7045_fe_read_ber,
+ .read_signal_strength = vp7045_fe_read_signal_strength,
+ .read_snr = vp7045_fe_read_snr,
+ .read_ucblocks = vp7045_fe_read_unc_blocks,
+};
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
new file mode 100644
index 00000000000..02ecc9a8e3b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -0,0 +1,263 @@
+/* DVB USB compliant Linux driver for the
+ * - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver
+ * - DigitalNow TinyUSB2 DVB-t receiver
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#include "vp7045.h"
+
+/* debug */
+int dvb_usb_vp7045_debug;
+module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
+{
+ int ret = 0;
+ u8 inbuf[12] = { 0 }, outbuf[20] = { 0 };
+
+ outbuf[0] = cmd;
+
+ if (outlen > 19)
+ outlen = 19;
+
+ if (inlen > 11)
+ inlen = 11;
+
+ if (out != NULL && outlen > 0)
+ memcpy(&outbuf[1], out, outlen);
+
+ deb_xfer("out buffer: ");
+ debug_dump(outbuf,outlen+1,deb_xfer);
+
+ if ((ret = down_interruptible(&d->usb_sem)))
+ return ret;
+
+ if (usb_control_msg(d->udev,
+ usb_sndctrlpipe(d->udev,0),
+ TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
+ outbuf, 20, 2*HZ) != 20) {
+ err("USB control message 'out' went wrong.");
+ ret = -EIO;
+ goto unlock;
+ }
+
+ msleep(msec);
+
+ if (usb_control_msg(d->udev,
+ usb_rcvctrlpipe(d->udev,0),
+ TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
+ inbuf, 12, 2*HZ) != 12) {
+ err("USB control message 'in' went wrong.");
+ ret = -EIO;
+ goto unlock;
+ }
+
+ deb_xfer("in buffer: ");
+ debug_dump(inbuf,12,deb_xfer);
+
+ if (in != NULL && inlen > 0)
+ memcpy(in,&inbuf[1],inlen);
+
+unlock:
+ up(&d->usb_sem);
+
+ return ret;
+}
+
+u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg)
+{
+ u8 obuf[2] = { 0 },v;
+ obuf[1] = reg;
+
+ vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30);
+
+ return v;
+}
+
+static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 v = onoff;
+ return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
+}
+
+/* remote control stuff */
+
+/* The keymapping struct. Somehow this should be loaded to the driver, but
+ * currently it is hardcoded. */
+static struct dvb_usb_rc_key vp7045_rc_keys[] = {
+ /* insert the keys like this. to make the raw keys visible, enable
+ * debug=0x04 when loading dvb-usb-vp7045. */
+
+ /* these keys are probably wrong. I don't have a working IR-receiver on my
+ * vp7045, so I can't test it. Patches are welcome. */
+ { 0x00, 0x01, KEY_1 },
+ { 0x00, 0x02, KEY_2 },
+};
+
+static int vp7045_rc_query(struct dvb_usb_device *d, u32 *key_buf, int *state)
+{
+ u8 key;
+ int i;
+ vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
+
+ deb_rc("remote query key: %x %d\n",key,key);
+
+ if (key == 0x44) {
+ *state = REMOTE_NO_KEY_PRESSED;
+ return 0;
+ }
+
+ for (i = 0; i < sizeof(vp7045_rc_keys)/sizeof(struct dvb_usb_rc_key); i++)
+ if (vp7045_rc_keys[i].data == key) {
+ *state = REMOTE_KEY_PRESSED;
+ *key_buf = vp7045_rc_keys[i].event;
+ break;
+ }
+ return 0;
+}
+
+static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset)
+{
+ int i = 0;
+ u8 v,br[2];
+ for (i=0; i < len; i++) {
+ v = offset + i;
+ vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5);
+ buf[i] = br[1];
+ }
+ deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i);
+ debug_dump(buf,i,deb_info);
+ return 0;
+}
+
+
+static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
+{
+ return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
+}
+
+static int vp7045_frontend_attach(struct dvb_usb_device *d)
+{
+ u8 buf[255] = { 0 };
+
+ vp7045_usb_op(d,VENDOR_STRING_READ,NULL,0,buf,20,0);
+ buf[10] = '\0';
+ deb_info("firmware says: %s ",buf);
+
+ vp7045_usb_op(d,PRODUCT_STRING_READ,NULL,0,buf,20,0);
+ buf[10] = '\0';
+ deb_info("%s ",buf);
+
+ vp7045_usb_op(d,FW_VERSION_READ,NULL,0,buf,20,0);
+ buf[10] = '\0';
+ deb_info("v%s\n",buf);
+
+/* Dump the EEPROM */
+/* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
+
+ d->fe = vp7045_fe_attach(d);
+
+ return 0;
+}
+
+static struct dvb_usb_properties vp7045_properties;
+
+static int vp7045_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE);
+}
+
+static struct usb_device_id vp7045_usb_table [] = {
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) },
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) },
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) },
+ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) },
+ { 0 },
+};
+MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
+
+static struct dvb_usb_properties vp7045_properties = {
+ .caps = 0,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-vp7045-01.fw",
+
+ .power_ctrl = vp7045_power_ctrl,
+ .frontend_attach = vp7045_frontend_attach,
+ .read_mac_address = vp7045_read_mac_addr,
+
+ .rc_interval = 400,
+ .rc_key_map = vp7045_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(vp7045_rc_keys),
+ .rc_query = vp7045_rc_query,
+
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x02,
+ .u = {
+ .bulk = {
+ .buffersize = 4096,
+ }
+ }
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)",
+ .cold_ids = { &vp7045_usb_table[0], NULL },
+ .warm_ids = { &vp7045_usb_table[1], NULL },
+ },
+ { .name = "DigitalNow TinyUSB 2 DVB-t Receiver",
+ .cold_ids = { &vp7045_usb_table[2], NULL },
+ .warm_ids = { &vp7045_usb_table[3], NULL },
+ },
+ { 0 },
+ }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver vp7045_usb_driver = {
+ .owner = THIS_MODULE,
+ .name = "dvb-usb-vp7045",
+ .probe = vp7045_usb_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = vp7045_usb_table,
+};
+
+/* module stuff */
+static int __init vp7045_usb_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&vp7045_usb_driver))) {
+ err("usb_register failed. (%d)",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit vp7045_usb_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&vp7045_usb_driver);
+}
+
+module_init(vp7045_usb_module_init);
+module_exit(vp7045_usb_module_exit);
+
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h
new file mode 100644
index 00000000000..9ce21a20fa8
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.h
@@ -0,0 +1,78 @@
+/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII
+ * USB2.0 DVB-T receiver.
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * Thanks to Twinhan who kindly provided hardware and information.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation, version 2.
+ *
+ * see Documentation/dvb/README.dvb-usb for more information
+ */
+#ifndef _DVB_USB_VP7045_H_
+#define _DVB_USB_VP7045_H_
+
+#define DVB_USB_LOG_PREFIX "vp7045"
+#include "dvb-usb.h"
+
+extern int dvb_usb_vp7045_debug;
+#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
+#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args)
+
+/* vp7045 commands */
+
+/* Twinhan Vendor requests */
+#define TH_COMMAND_IN 0xC0
+#define TH_COMMAND_OUT 0xC1
+
+/* command bytes */
+#define TUNER_REG_READ 0x03
+#define TUNER_REG_WRITE 0x04
+
+#define RC_VAL_READ 0x05
+ #define RC_NO_KEY 0x44
+
+#define SET_TUNER_POWER 0x06
+#define CHECK_TUNER_POWER 0x12
+ #define Tuner_Power_ON 1
+ #define Tuner_Power_OFF 0
+
+#define GET_USB_SPEED 0x07
+ #define USB_SPEED_LOW 0
+ #define USB_SPEED_FULL 1
+ #define USB_SPEED_HIGH 2
+
+#define LOCK_TUNER_COMMAND 0x09
+
+#define TUNER_SIGNAL_READ 0x0A
+
+/* FX2 eeprom */
+#define SET_EE_VALUE 0x10
+#define GET_EE_VALUE 0x11
+ #define FX2_ID_ADDR 0x00
+ #define VID_MSB_ADDR 0x02
+ #define VID_LSB_ADDR 0x01
+ #define PID_MSB_ADDR 0x04
+ #define PID_LSB_ADDR 0x03
+ #define MAC_0_ADDR 0x07
+ #define MAC_1_ADDR 0x08
+ #define MAC_2_ADDR 0x09
+ #define MAC_3_ADDR 0x0a
+ #define MAC_4_ADDR 0x0b
+ #define MAC_5_ADDR 0x0c
+
+#define RESET_FX2 0x13
+
+#define FW_VERSION_READ 0x0B
+#define VENDOR_STRING_READ 0x0C
+#define PRODUCT_STRING_READ 0x0D
+#define FW_BCD_VERSION_READ 0x14
+
+extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d);
+extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec);
+extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg);
+
+#endif
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 75fb556ec01..b4fddf513eb 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -173,4 +173,12 @@ config DVB_OR51132
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
+config DVB_BCM3510
+ tristate "Broadcom BCM3510"
+ depends on DVB_CORE
+ select FW_LOADER
+ help
+ An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
+ support this frontend.
+
endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 7f8784870ea..91d6d3576d3 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -28,3 +28,4 @@ obj-$(CONFIG_DVB_STV0297) += stv0297.o
obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
obj-$(CONFIG_DVB_OR51211) += or51211.o
obj-$(CONFIG_DVB_OR51132) += or51132.o
+obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
new file mode 100644
index 00000000000..f5fdc5c3e60
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -0,0 +1,853 @@
+/*
+ * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
+ *
+ * Copyright (C) 2001-5, B2C2 inc.
+ *
+ * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * This driver is "hard-coded" to be used with the 1st generation of
+ * Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming
+ * (Panasonic CT10S) is located here, which is actually wrong. Unless there is
+ * another device with a BCM3510, this is no problem.
+ *
+ * The driver works also with QAM64 DVB-C, but had an unreasonable high
+ * UNC. (Tested with the Air2PC ATSC 1st generation)
+ *
+ * You'll need a firmware for this driver in order to get it running. It is
+ * called "dvb-fe-bcm3510-01.fw".
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
+ * Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+
+#include "dvb_frontend.h"
+#include "bcm3510.h"
+#include "bcm3510_priv.h"
+
+struct bcm3510_state {
+
+ struct i2c_adapter* i2c;
+ struct dvb_frontend_ops ops;
+ const struct bcm3510_config* config;
+ struct dvb_frontend frontend;
+
+ /* demodulator private data */
+ struct semaphore hab_sem;
+ u8 firmware_loaded:1;
+
+ unsigned long next_status_check;
+ unsigned long status_check_interval;
+ struct bcm3510_hab_cmd_status1 status1;
+ struct bcm3510_hab_cmd_status2 status2;
+};
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able)).");
+
+#define dprintk(level,x...) if (level & debug) printk(x)
+#define dbufout(b,l,m) {\
+ int i; \
+ for (i = 0; i < l; i++) \
+ m("%02x ",b[i]); \
+}
+#define deb_info(args...) dprintk(0x01,args)
+#define deb_i2c(args...) dprintk(0x02,args)
+#define deb_hab(args...) dprintk(0x04,args)
+
+/* transfer functions */
+static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
+{
+ u8 b[256];
+ int err;
+ struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 };
+
+ b[0] = reg;
+ memcpy(&b[1],buf,len);
+
+ deb_i2c("i2c wr %02x: ",reg);
+ dbufout(buf,len,deb_i2c);
+ deb_i2c("\n");
+
+ if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+
+ deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
+ __FUNCTION__, state->config->demod_address, reg, err);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
+{
+ struct i2c_msg msg[] = {
+ { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
+ { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len }
+ };
+ int err;
+
+ memset(buf,0,len);
+
+ if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
+ deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
+ __FUNCTION__, state->config->demod_address, reg, err);
+ return -EREMOTEIO;
+ }
+ deb_i2c("i2c rd %02x: ",reg);
+ dbufout(buf,len,deb_i2c);
+ deb_i2c("\n");
+
+ return 0;
+}
+
+static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v)
+{
+ return bcm3510_writebytes(state,reg,&v.raw,1);
+}
+
+static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v)
+{
+ return bcm3510_readbytes(state,reg,&v->raw,1);
+}
+
+/* Host Access Buffer transfers */
+static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len)
+{
+ bcm3510_register_value v;
+ int ret,i;
+
+ v.HABADR_a6.HABADR = 0;
+ if ((ret = bcm3510_writeB(st,0xa6,v)) < 0)
+ return ret;
+
+ for (i = 0; i < len; i++) {
+ if ((ret = bcm3510_readB(st,0xa7,&v)) < 0)
+ return ret;
+ buf[i] = v.HABDATA_a7;
+ }
+ return 0;
+}
+
+static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len)
+{
+ bcm3510_register_value v,hab;
+ int ret,i;
+ unsigned long t;
+
+/* Check if any previous HAB request still needs to be serviced by the
+ * Aquisition Processor before sending new request */
+ if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
+ return ret;
+ if (v.HABSTAT_a8.HABR) {
+ deb_info("HAB is running already - clearing it.\n");
+ v.HABSTAT_a8.HABR = 0;
+ bcm3510_writeB(st,0xa8,v);
+// return -EBUSY;
+ }
+
+/* Send the start HAB Address (automatically incremented after write of
+ * HABDATA) and write the HAB Data */
+ hab.HABADR_a6.HABADR = 0;
+ if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0)
+ return ret;
+
+ for (i = 0; i < len; i++) {
+ hab.HABDATA_a7 = buf[i];
+ if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0)
+ return ret;
+ }
+
+/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to
+ * be written) */
+ v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1;
+ if ((ret = bcm3510_writeB(st,0xa8,v)) < 0)
+ return ret;
+
+/* Polling method: Wait until the AP finishes processing the HAB request */
+ t = jiffies + 1*HZ;
+ while (time_before(jiffies, t)) {
+ deb_info("waiting for HAB to complete\n");
+ msleep(10);
+ if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
+ return ret;
+
+ if (!v.HABSTAT_a8.HABR)
+ return 0;
+ }
+
+ deb_info("send_request execution timed out.\n");
+ return -ETIMEDOUT;
+}
+
+static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen)
+{
+ u8 ob[olen+2],ib[ilen+2];
+ int ret = 0;
+
+ ob[0] = cmd;
+ ob[1] = msgid;
+ memcpy(&ob[2],obuf,olen);
+
+ deb_hab("hab snd: ");
+ dbufout(ob,olen+2,deb_hab);
+ deb_hab("\n");
+
+ if (down_interruptible(&st->hab_sem) < 0)
+ return -EAGAIN;
+
+ if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
+ (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0)
+ goto error;
+
+ deb_hab("hab get: ");
+ dbufout(ib,ilen+2,deb_hab);
+ deb_hab("\n");
+
+ memcpy(ibuf,&ib[2],ilen);
+error:
+ up(&st->hab_sem);
+ return ret;
+}
+
+#if 0
+/* not needed, we use a semaphore to prevent HAB races */
+static int bcm3510_is_ap_ready(struct bcm3510_state *st)
+{
+ bcm3510_register_value ap,hab;
+ int ret;
+
+ if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 ||
+ (ret = bcm3510_readB(st,0xa2,&ap) < 0))
+ return ret;
+
+ if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) {
+ deb_info("AP is busy\n");
+ return -EBUSY;
+ }
+
+ return 0;
+}
+#endif
+
+static int bcm3510_bert_reset(struct bcm3510_state *st)
+{
+ bcm3510_register_value b;
+ int ret;
+
+ if ((ret < bcm3510_readB(st,0xfa,&b)) < 0)
+ return ret;
+
+ b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
+ b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b);
+ b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
+ b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b);
+
+ /* clear residual bit counter TODO */
+ return 0;
+}
+
+static int bcm3510_refresh_state(struct bcm3510_state *st)
+{
+ if (time_after(jiffies,st->next_status_check)) {
+ bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1));
+ bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2));
+ st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
+ }
+ return 0;
+}
+
+static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct bcm3510_state* st = fe->demodulator_priv;
+ bcm3510_refresh_state(st);
+
+ *status = 0;
+ if (st->status1.STATUS1.RECEIVER_LOCK)
+ *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+
+ if (st->status1.STATUS1.FEC_LOCK)
+ *status |= FE_HAS_VITERBI;
+
+ if (st->status1.STATUS1.OUT_PLL_LOCK)
+ *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+
+ if (*status & FE_HAS_LOCK)
+ st->status_check_interval = 1500;
+ else /* more frequently checks if no lock has been achieved yet */
+ st->status_check_interval = 500;
+
+ deb_info("real_status: %02x\n",*status);
+ return 0;
+}
+
+static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+ struct bcm3510_state* st = fe->demodulator_priv;
+ bcm3510_refresh_state(st);
+
+ *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2;
+ return 0;
+}
+
+static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc)
+{
+ struct bcm3510_state* st = fe->demodulator_priv;
+ bcm3510_refresh_state(st);
+ *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1;
+ return 0;
+}
+
+static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+ struct bcm3510_state* st = fe->demodulator_priv;
+ s32 t;
+
+ bcm3510_refresh_state(st);
+ t = st->status2.SIGNAL;
+
+ if (t > 190)
+ t = 190;
+ if (t < 90)
+ t = 90;
+
+ t -= 90;
+ t = t * 0xff / 100;
+ /* normalize if necessary */
+ *strength = (t << 8) | t;
+ return 0;
+}
+
+static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+ struct bcm3510_state* st = fe->demodulator_priv;
+ bcm3510_refresh_state(st);
+
+ *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8);
+ return 0;
+}
+
+/* tuner frontend programming */
+static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a)
+{
+ struct bcm3510_hab_cmd_tune c;
+ memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune));
+
+/* I2C Mode disabled, set 16 control / Data pairs */
+ c.length = 0x10;
+ c.clock_width = 0;
+/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to
+ * logic high (as Configuration) */
+ c.misc = 0x10;
+/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */
+ c.TUNCTL_state = 0x40;
+
+/* PRESCALER DEVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */
+ c.ctl_dat[0].ctrl.size = BITS_8;
+ c.ctl_dat[0].data = 0x80 | bc;
+
+/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */
+ c.ctl_dat[1].ctrl.size = BITS_8;
+ c.ctl_dat[1].data = 4;
+
+/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */
+ c.ctl_dat[2].ctrl.size = BITS_3;
+ c.ctl_dat[2].data = 0x20;
+
+/* control CS0 pin, pulse byte ? */
+ c.ctl_dat[3].ctrl.size = BITS_3;
+ c.ctl_dat[3].ctrl.clk_off = 1;
+ c.ctl_dat[3].ctrl.cs0 = 1;
+ c.ctl_dat[3].data = 0x40;
+
+/* PGM_S18 to PGM_S11 */
+ c.ctl_dat[4].ctrl.size = BITS_8;
+ c.ctl_dat[4].data = n >> 3;
+
+/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */
+ c.ctl_dat[5].ctrl.size = BITS_8;
+ c.ctl_dat[5].data = ((n & 0x7) << 5) | (a >> 2);
+
+/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */
+ c.ctl_dat[6].ctrl.size = BITS_3;
+ c.ctl_dat[6].data = (a << 6) & 0xdf;
+
+/* control CS0 pin, pulse byte ? */
+ c.ctl_dat[7].ctrl.size = BITS_3;
+ c.ctl_dat[7].ctrl.clk_off = 1;
+ c.ctl_dat[7].ctrl.cs0 = 1;
+ c.ctl_dat[7].data = 0x40;
+
+/* PRESCALER DEVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */
+ c.ctl_dat[8].ctrl.size = BITS_8;
+ c.ctl_dat[8].data = 0x80;
+
+/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */
+ c.ctl_dat[9].ctrl.size = BITS_8;
+ c.ctl_dat[9].data = 0x10;
+
+/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */
+ c.ctl_dat[10].ctrl.size = BITS_3;
+ c.ctl_dat[10].data = 0x20;
+
+/* pulse byte */
+ c.ctl_dat[11].ctrl.size = BITS_3;
+ c.ctl_dat[11].ctrl.clk_off = 1;
+ c.ctl_dat[11].ctrl.cs1 = 1;
+ c.ctl_dat[11].data = 0x40;
+
+/* PGM_S18 to PGM_S11 */
+ c.ctl_dat[12].ctrl.size = BITS_8;
+ c.ctl_dat[12].data = 0x2a;
+
+/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */
+ c.ctl_dat[13].ctrl.size = BITS_8;
+ c.ctl_dat[13].data = 0x8e;
+
+/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */
+ c.ctl_dat[14].ctrl.size = BITS_3;
+ c.ctl_dat[14].data = 0;
+
+/* Pulse Byte */
+ c.ctl_dat[15].ctrl.size = BITS_3;
+ c.ctl_dat[15].ctrl.clk_off = 1;
+ c.ctl_dat[15].ctrl.cs1 = 1;
+ c.ctl_dat[15].data = 0x40;
+
+ return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);
+}
+
+static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq)
+{
+ u8 bc,a;
+ u16 n;
+ s32 YIntercept,Tfvco1;
+
+ freq /= 1000;
+
+ deb_info("%dkHz:",freq);
+ /* set Band Switch */
+ if (freq <= 168000)
+ bc = 0x1c;
+ else if (freq <= 378000)
+ bc = 0x2c;
+ else
+ bc = 0x30;
+
+ if (freq >= 470000) {
+ freq -= 470001;
+ YIntercept = 18805;
+ } else if (freq >= 90000) {
+ freq -= 90001;
+ YIntercept = 15005;
+ } else if (freq >= 76000){
+ freq -= 76001;
+ YIntercept = 14865;
+ } else {
+ freq -= 54001;
+ YIntercept = 14645;
+ }
+
+ Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;
+
+ n = Tfvco1 >> 6;
+ a = Tfvco1 & 0x3f;
+
+ deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);
+ if (n >= 16 && n <= 2047)
+ return bcm3510_tuner_cmd(st,bc,n,a);
+
+ return -EINVAL;
+}
+
+static int bcm3510_set_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct bcm3510_state* st = fe->demodulator_priv;
+ struct bcm3510_hab_cmd_ext_acquire cmd;
+ struct bcm3510_hab_cmd_bert_control bert;
+ int ret;
+
+ memset(&cmd,0,sizeof(cmd));
+ switch (p->u.vsb.modulation) {
+ case QAM_256:
+ cmd.ACQUIRE0.MODE = 0x1;
+ cmd.ACQUIRE1.SYM_RATE = 0x1;
+ cmd.ACQUIRE1.IF_FREQ = 0x1;
+ break;
+ case QAM_64:
+ cmd.ACQUIRE0.MODE = 0x2;
+ cmd.ACQUIRE1.SYM_RATE = 0x2;
+ cmd.ACQUIRE1.IF_FREQ = 0x1;
+ break;
+/* case QAM_256:
+ cmd.ACQUIRE0.MODE = 0x3;
+ break;
+ case QAM_128:
+ cmd.ACQUIRE0.MODE = 0x4;
+ break;
+ case QAM_64:
+ cmd.ACQUIRE0.MODE = 0x5;
+ break;
+ case QAM_32:
+ cmd.ACQUIRE0.MODE = 0x6;
+ break;
+ case QAM_16:
+ cmd.ACQUIRE0.MODE = 0x7;
+ break;*/
+ case VSB_8:
+ cmd.ACQUIRE0.MODE = 0x8;
+ cmd.ACQUIRE1.SYM_RATE = 0x0;
+ cmd.ACQUIRE1.IF_FREQ = 0x0;
+ break;
+ case VSB_16:
+ cmd.ACQUIRE0.MODE = 0x9;
+ cmd.ACQUIRE1.SYM_RATE = 0x0;
+ cmd.ACQUIRE1.IF_FREQ = 0x0;
+ default:
+ return -EINVAL;
+ };
+ cmd.ACQUIRE0.OFFSET = 0;
+ cmd.ACQUIRE0.NTSCSWEEP = 1;
+ cmd.ACQUIRE0.FA = 1;
+ cmd.ACQUIRE0.BW = 0;
+
+/* if (enableOffset) {
+ cmd.IF_OFFSET0 = xx;
+ cmd.IF_OFFSET1 = xx;
+
+ cmd.SYM_OFFSET0 = xx;
+ cmd.SYM_OFFSET1 = xx;
+ if (enableNtscSweep) {
+ cmd.NTSC_OFFSET0;
+ cmd.NTSC_OFFSET1;
+ }
+ } */
+ bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
+
+/* doing it with different MSGIDs, data book and source differs */
+ bert.BE = 0;
+ bert.unused = 0;
+ bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
+ bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
+
+ bcm3510_bert_reset(st);
+
+ if ((ret = bcm3510_set_freq(st,p->frequency)) < 0)
+ return ret;
+
+ memset(&st->status1,0,sizeof(st->status1));
+ memset(&st->status2,0,sizeof(st->status2));
+ st->status_check_interval = 500;
+
+/* Give the AP some time */
+ msleep(200);
+
+ return 0;
+}
+
+static int bcm3510_sleep(struct dvb_frontend* fe)
+{
+ return 0;
+}
+
+static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
+{
+ s->min_delay_ms = 1000;
+ s->step_size = 0;
+ s->max_drift = 0;
+ return 0;
+}
+
+static void bcm3510_release(struct dvb_frontend* fe)
+{
+ struct bcm3510_state* state = fe->demodulator_priv;
+ kfree(state);
+}
+
+/* firmware download:
+ * firmware file is build up like this:
+ * 16bit addr, 16bit length, 8byte of length
+ */
+#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
+
+static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, u8 *b, u16 len)
+{
+ int ret = 0,i;
+ bcm3510_register_value vH, vL,vD;
+
+ vH.MADRH_a9 = addr >> 8;
+ vL.MADRL_aa = addr;
+ if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
+ if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
+
+ for (i = 0; i < len; i++) {
+ vD.MDATA_ab = b[i];
+ if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int bcm3510_download_firmware(struct dvb_frontend* fe)
+{
+ struct bcm3510_state* st = fe->demodulator_priv;
+ const struct firmware *fw;
+ u16 addr,len;
+ u8 *b;
+ int ret,i;
+
+ deb_info("requesting firmware\n");
+ if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
+ err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
+ return ret;
+ }
+ deb_info("got firmware: %d\n",fw->size);
+
+ b = fw->data;
+ for (i = 0; i < fw->size;) {
+ addr = le16_to_cpu( *( (u16 *)&b[i] ) );
+ len = le16_to_cpu( *( (u16 *)&b[i+2] ) );
+ deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size);
+ if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
+ err("firmware download failed: %d\n",ret);
+ return ret;
+ }
+ i += 4 + len;
+ }
+ release_firmware(fw);
+ deb_info("firmware download successfully completed\n");
+ return 0;
+}
+
+static int bcm3510_check_firmware_version(struct bcm3510_state *st)
+{
+ struct bcm3510_hab_cmd_get_version_info ver;
+ bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
+
+ deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
+
+ if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
+ ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
+ ver.demod_version == BCM3510_DEF_DEMOD_VERSION)
+ return 0;
+
+ deb_info("version check failed\n");
+ return -ENODEV;
+}
+
+/* (un)resetting the AP */
+static int bcm3510_reset(struct bcm3510_state *st)
+{
+ int ret;
+ unsigned long t;
+ bcm3510_register_value v;
+
+ bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
+ if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
+ return ret;
+
+ t = jiffies + 3*HZ;
+ while (time_before(jiffies, t)) {
+ msleep(10);
+ if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
+ return ret;
+
+ if (v.APSTAT1_a2.RESET)
+ return 0;
+ }
+ deb_info("reset timed out\n");
+ return -ETIMEDOUT;
+}
+
+static int bcm3510_clear_reset(struct bcm3510_state *st)
+{
+ bcm3510_register_value v;
+ int ret;
+ unsigned long t;
+
+ v.raw = 0;
+ if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
+ return ret;
+
+ t = jiffies + 3*HZ;
+ while (time_before(jiffies, t)) {
+ msleep(10);
+ if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
+ return ret;
+
+ /* verify that reset is cleared */
+ if (!v.APSTAT1_a2.RESET)
+ return 0;
+ }
+ deb_info("reset clear timed out\n");
+ return -ETIMEDOUT;
+}
+
+static int bcm3510_init_cold(struct bcm3510_state *st)
+{
+ int ret;
+ bcm3510_register_value v;
+
+ /* read Acquisation Processor status register and check it is not in RUN mode */
+ if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
+ return ret;
+ if (v.APSTAT1_a2.RUN) {
+ deb_info("AP is already running - firmware already loaded.\n");
+ return 0;
+ }
+
+ deb_info("reset?\n");
+ if ((ret = bcm3510_reset(st)) < 0)
+ return ret;
+
+ deb_info("tristate?\n");
+ /* tri-state */
+ v.TSTCTL_2e.CTL = 0;
+ if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
+ return ret;
+
+ deb_info("firmware?\n");
+ if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
+ (ret = bcm3510_clear_reset(st)) < 0)
+ return ret;
+
+ /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */
+
+ return 0;
+}
+
+static int bcm3510_init(struct dvb_frontend* fe)
+{
+ struct bcm3510_state* st = fe->demodulator_priv;
+ bcm3510_register_value j;
+ struct bcm3510_hab_cmd_set_agc c;
+ int ret;
+
+ if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
+ return ret;
+
+ deb_info("JDEC: %02x\n",j.raw);
+
+ switch (j.JDEC_ca.JDEC) {
+ case JDEC_WAIT_AT_RAM:
+ deb_info("attempting to download firmware\n");
+ if ((ret = bcm3510_init_cold(st)) < 0)
+ return ret;
+ case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */
+ deb_info("firmware is loaded\n");
+ bcm3510_check_firmware_version(st);
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ memset(&c,0,1);
+ c.SEL = 1;
+ bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
+
+ return 0;
+}
+
+
+static struct dvb_frontend_ops bcm3510_ops;
+
+struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct bcm3510_state* state = NULL;
+ int ret;
+ bcm3510_register_value v;
+
+ /* allocate memory for the internal state */
+ state = kmalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+ memset(state,0,sizeof(struct bcm3510_state));
+
+ /* setup the state */
+
+ state->config = config;
+ state->i2c = i2c;
+ memcpy(&state->ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
+
+ /* create dvb_frontend */
+ state->frontend.ops = &state->ops;
+ state->frontend.demodulator_priv = state;
+
+ sema_init(&state->hab_sem, 1);
+
+ if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
+ goto error;
+
+ deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
+
+ if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */
+ (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0)) /* warm */
+ goto error;
+
+ info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
+
+ bcm3510_reset(state);
+
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(bcm3510_attach);
+
+static struct dvb_frontend_ops bcm3510_ops = {
+
+ .info = {
+ .name = "Broadcom BCM3510 VSB/QAM frontend",
+ .type = FE_ATSC,
+ .frequency_min = 54000000,
+ .frequency_max = 803000000,
+ /* stepsize is just a guess */
+ .frequency_stepsize = 0,
+ .caps =
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_8VSB | FE_CAN_16VSB |
+ FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256
+ },
+
+ .release = bcm3510_release,
+
+ .init = bcm3510_init,
+ .sleep = bcm3510_sleep,
+
+ .set_frontend = bcm3510_set_frontend,
+ .get_tune_settings = bcm3510_get_tune_settings,
+
+ .read_status = bcm3510_read_status,
+ .read_ber = bcm3510_read_ber,
+ .read_signal_strength = bcm3510_read_signal_strength,
+ .read_snr = bcm3510_read_snr,
+ .read_ucblocks = bcm3510_read_unc,
+};
+
+MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
+MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h
new file mode 100644
index 00000000000..80f5d0953d0
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510.h
@@ -0,0 +1,40 @@
+/*
+ * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
+ *
+ * Copyright (C) 2001-5, B2C2 inc.
+ *
+ * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef BCM3510_H
+#define BCM3510_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct bcm3510_config
+{
+ /* the demodulator's i2c address */
+ u8 demod_address;
+
+ /* request firmware for device */
+ int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+};
+
+extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
+ struct i2c_adapter* i2c);
+
+#endif
diff --git a/drivers/media/dvb/frontends/bcm3510_priv.h b/drivers/media/dvb/frontends/bcm3510_priv.h
new file mode 100644
index 00000000000..3bb1bc2a04f
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510_priv.h
@@ -0,0 +1,460 @@
+/*
+ * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
+ *
+ * Copyright (C) 2001-5, B2C2 inc.
+ *
+ * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __BCM3510_PRIV_H__
+#define __BCM3510_PRIV_H__
+
+#define PACKED __attribute__((packed))
+
+#undef err
+#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n" , ## arg)
+#undef info
+#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n" , ## arg)
+#undef warn
+#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg)
+
+
+#define PANASONIC_FIRST_IF_BASE_IN_KHz 1407500
+#define BCM3510_SYMBOL_RATE 5381000
+
+typedef union {
+ u8 raw;
+
+ struct {
+ u8 CTL :8;
+ } TSTCTL_2e;
+
+ u8 LDCERC_4e;
+ u8 LDUERC_4f;
+ u8 LD_BER0_65;
+ u8 LD_BER1_66;
+ u8 LD_BER2_67;
+ u8 LD_BER3_68;
+
+ struct {
+ u8 RESET :1;
+ u8 IDLE :1;
+ u8 STOP :1;
+ u8 HIRQ0 :1;
+ u8 HIRQ1 :1;
+ u8 na0 :1;
+ u8 HABAV :1;
+ u8 na1 :1;
+ } HCTL1_a0;
+
+ struct {
+ u8 na0 :1;
+ u8 IDLMSK :1;
+ u8 STMSK :1;
+ u8 I0MSK :1;
+ u8 I1MSK :1;
+ u8 na1 :1;
+ u8 HABMSK :1;
+ u8 na2 :1;
+ } HCTLMSK_a1;
+
+ struct {
+ u8 RESET :1;
+ u8 IDLE :1;
+ u8 STOP :1;
+ u8 RUN :1;
+ u8 HABAV :1;
+ u8 MEMAV :1;
+ u8 ALDONE :1;
+ u8 REIRQ :1;
+ } APSTAT1_a2;
+
+ struct {
+ u8 RSTMSK :1;
+ u8 IMSK :1;
+ u8 SMSK :1;
+ u8 RMSK :1;
+ u8 HABMSK :1;
+ u8 MAVMSK :1;
+ u8 ALDMSK :1;
+ u8 REMSK :1;
+ } APMSK1_a3;
+
+ u8 APSTAT2_a4;
+ u8 APMSK2_a5;
+
+ struct {
+ u8 HABADR :7;
+ u8 na :1;
+ } HABADR_a6;
+
+ u8 HABDATA_a7;
+
+ struct {
+ u8 HABR :1;
+ u8 LDHABR :1;
+ u8 APMSK :1;
+ u8 HMSK :1;
+ u8 LDMSK :1;
+ u8 na :3;
+ } HABSTAT_a8;
+
+ u8 MADRH_a9;
+ u8 MADRL_aa;
+ u8 MDATA_ab;
+
+ struct {
+#define JDEC_WAIT_AT_RAM 0x7
+#define JDEC_EEPROM_LOAD_WAIT 0x4
+ u8 JDEC :3;
+ u8 na :5;
+ } JDEC_ca;
+
+ struct {
+ u8 REV :4;
+ u8 LAYER :4;
+ } REVID_e0;
+
+ struct {
+ u8 unk0 :1;
+ u8 CNTCTL :1;
+ u8 BITCNT :1;
+ u8 unk1 :1;
+ u8 RESYNC :1;
+ u8 unk2 :3;
+ } BERCTL_fa;
+
+ struct {
+ u8 CSEL0 :1;
+ u8 CLKED0 :1;
+ u8 CSEL1 :1;
+ u8 CLKED1 :1;
+ u8 CLKLEV :1;
+ u8 SPIVAR :1;
+ u8 na :2;
+ } TUNSET_fc;
+
+ struct {
+ u8 CLK :1;
+ u8 DATA :1;
+ u8 CS0 :1;
+ u8 CS1 :1;
+ u8 AGCSEL :1;
+ u8 na0 :1;
+ u8 TUNSEL :1;
+ u8 na1 :1;
+ } TUNCTL_fd;
+
+ u8 TUNSEL0_fe;
+ u8 TUNSEL1_ff;
+
+} bcm3510_register_value;
+
+/* HAB commands */
+
+/* version */
+#define CMD_GET_VERSION_INFO 0x3D
+#define MSGID_GET_VERSION_INFO 0x15
+struct bcm3510_hab_cmd_get_version_info {
+ u8 microcode_version;
+ u8 script_version;
+ u8 config_version;
+ u8 demod_version;
+} PACKED;
+
+#define BCM3510_DEF_MICROCODE_VERSION 0x0E
+#define BCM3510_DEF_SCRIPT_VERSION 0x06
+#define BCM3510_DEF_CONFIG_VERSION 0x01
+#define BCM3510_DEF_DEMOD_VERSION 0xB1
+
+/* acquire */
+#define CMD_ACQUIRE 0x38
+
+#define MSGID_EXT_TUNER_ACQUIRE 0x0A
+struct bcm3510_hab_cmd_ext_acquire {
+ struct {
+ u8 MODE :4;
+ u8 BW :1;
+ u8 FA :1;
+ u8 NTSCSWEEP :1;
+ u8 OFFSET :1;
+ } PACKED ACQUIRE0; /* control_byte */
+
+ struct {
+ u8 IF_FREQ :3;
+ u8 zero0 :1;
+ u8 SYM_RATE :3;
+ u8 zero1 :1;
+ } PACKED ACQUIRE1; /* sym_if */
+
+ u8 IF_OFFSET0; /* IF_Offset_10hz */
+ u8 IF_OFFSET1;
+ u8 SYM_OFFSET0; /* SymbolRateOffset */
+ u8 SYM_OFFSET1;
+ u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
+ u8 NTSC_OFFSET1;
+} PACKED;
+
+#define MSGID_INT_TUNER_ACQUIRE 0x0B
+struct bcm3510_hab_cmd_int_acquire {
+ struct {
+ u8 MODE :4;
+ u8 BW :1;
+ u8 FA :1;
+ u8 NTSCSWEEP :1;
+ u8 OFFSET :1;
+ } PACKED ACQUIRE0; /* control_byte */
+
+ struct {
+ u8 IF_FREQ :3;
+ u8 zero0 :1;
+ u8 SYM_RATE :3;
+ u8 zero1 :1;
+ } PACKED ACQUIRE1; /* sym_if */
+
+ u8 TUNER_FREQ0;
+ u8 TUNER_FREQ1;
+ u8 TUNER_FREQ2;
+ u8 TUNER_FREQ3;
+ u8 IF_OFFSET0; /* IF_Offset_10hz */
+ u8 IF_OFFSET1;
+ u8 SYM_OFFSET0; /* SymbolRateOffset */
+ u8 SYM_OFFSET1;
+ u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
+ u8 NTSC_OFFSET1;
+} PACKED;
+
+/* modes */
+#define BCM3510_QAM16 = 0x01
+#define BCM3510_QAM32 = 0x02
+#define BCM3510_QAM64 = 0x03
+#define BCM3510_QAM128 = 0x04
+#define BCM3510_QAM256 = 0x05
+#define BCM3510_8VSB = 0x0B
+#define BCM3510_16VSB = 0x0D
+
+/* IF_FREQS */
+#define BCM3510_IF_TERRESTRIAL 0x0
+#define BCM3510_IF_CABLE 0x1
+#define BCM3510_IF_USE_CMD 0x7
+
+/* SYM_RATE */
+#define BCM3510_SR_8VSB 0x0 /* 5381119 s/sec */
+#define BCM3510_SR_256QAM 0x1 /* 5360537 s/sec */
+#define BCM3510_SR_16QAM 0x2 /* 5056971 s/sec */
+#define BCM3510_SR_MISC 0x3 /* 5000000 s/sec */
+#define BCM3510_SR_USE_CMD 0x7
+
+/* special symbol rate */
+#define CMD_SET_VALUE_NOT_LISTED 0x2d
+#define MSGID_SET_SYMBOL_RATE_NOT_LISTED 0x0c
+struct bcm3510_hab_cmd_set_sr_not_listed {
+ u8 HOST_SYM_RATE0;
+ u8 HOST_SYM_RATE1;
+ u8 HOST_SYM_RATE2;
+ u8 HOST_SYM_RATE3;
+} PACKED;
+
+/* special IF */
+#define MSGID_SET_IF_FREQ_NOT_LISTED 0x0d
+struct bcm3510_hab_cmd_set_if_freq_not_listed {
+ u8 HOST_IF_FREQ0;
+ u8 HOST_IF_FREQ1;
+ u8 HOST_IF_FREQ2;
+ u8 HOST_IF_FREQ3;
+} PACKED;
+
+/* auto reacquire */
+#define CMD_AUTO_PARAM 0x2a
+#define MSGID_AUTO_REACQUIRE 0x0e
+struct bcm3510_hab_cmd_auto_reacquire {
+ u8 ACQ :1; /* on/off*/
+ u8 unused :7;
+} PACKED;
+
+#define MSGID_SET_RF_AGC_SEL 0x12
+struct bcm3510_hab_cmd_set_agc {
+ u8 LVL :1;
+ u8 unused :6;
+ u8 SEL :1;
+} PACKED;
+
+#define MSGID_SET_AUTO_INVERSION 0x14
+struct bcm3510_hab_cmd_auto_inversion {
+ u8 AI :1;
+ u8 unused :7;
+} PACKED;
+
+
+/* bert control */
+#define CMD_STATE_CONTROL 0x12
+#define MSGID_BERT_CONTROL 0x0e
+#define MSGID_BERT_SET 0xfa
+struct bcm3510_hab_cmd_bert_control {
+ u8 BE :1;
+ u8 unused :7;
+} PACKED;
+
+#define MSGID_TRI_STATE 0x2e
+struct bcm3510_hab_cmd_tri_state {
+ u8 RE :1; /* a/d ram port pins */
+ u8 PE :1; /* baud clock pin */
+ u8 AC :1; /* a/d clock pin */
+ u8 BE :1; /* baud clock pin */
+ u8 unused :4;
+} PACKED;
+
+
+/* tune */
+#define CMD_TUNE 0x38
+#define MSGID_TUNE 0x16
+struct bcm3510_hab_cmd_tune_ctrl_data_pair {
+ struct {
+#define BITS_8 0x07
+#define BITS_7 0x06
+#define BITS_6 0x05
+#define BITS_5 0x04
+#define BITS_4 0x03
+#define BITS_3 0x02
+#define BITS_2 0x01
+#define BITS_1 0x00
+ u8 size :3;
+ u8 unk :2;
+ u8 clk_off :1;
+ u8 cs0 :1;
+ u8 cs1 :1;
+
+ } PACKED ctrl;
+
+ u8 data;
+} PACKED;
+
+struct bcm3510_hab_cmd_tune {
+ u8 length;
+ u8 clock_width;
+ u8 misc;
+ u8 TUNCTL_state;
+
+ struct bcm3510_hab_cmd_tune_ctrl_data_pair ctl_dat[16];
+} PACKED;
+
+#define CMD_STATUS 0x38
+#define MSGID_STATUS1 0x08
+struct bcm3510_hab_cmd_status1 {
+ struct {
+ u8 EQ_MODE :4;
+ u8 reserved :2;
+ u8 QRE :1; /* if QSE and the spectrum is inversed */
+ u8 QSE :1; /* automatic spectral inversion */
+ } PACKED STATUS0;
+
+ struct {
+ u8 RECEIVER_LOCK :1;
+ u8 FEC_LOCK :1;
+ u8 OUT_PLL_LOCK :1;
+ u8 reserved :5;
+ } PACKED STATUS1;
+
+ struct {
+ u8 reserved :2;
+ u8 BW :1;
+ u8 NTE :1; /* NTSC filter sweep enabled */
+ u8 AQI :1; /* currently acquiring */
+ u8 FA :1; /* fast acquisition */
+ u8 ARI :1; /* auto reacquire */
+ u8 TI :1; /* programming the tuner */
+ } PACKED STATUS2;
+ u8 STATUS3;
+ u8 SNR_EST0;
+ u8 SNR_EST1;
+ u8 TUNER_FREQ0;
+ u8 TUNER_FREQ1;
+ u8 TUNER_FREQ2;
+ u8 TUNER_FREQ3;
+ u8 SYM_RATE0;
+ u8 SYM_RATE1;
+ u8 SYM_RATE2;
+ u8 SYM_RATE3;
+ u8 SYM_OFFSET0;
+ u8 SYM_OFFSET1;
+ u8 SYM_ERROR0;
+ u8 SYM_ERROR1;
+ u8 IF_FREQ0;
+ u8 IF_FREQ1;
+ u8 IF_FREQ2;
+ u8 IF_FREQ3;
+ u8 IF_OFFSET0;
+ u8 IF_OFFSET1;
+ u8 IF_ERROR0;
+ u8 IF_ERROR1;
+ u8 NTSC_FILTER0;
+ u8 NTSC_FILTER1;
+ u8 NTSC_FILTER2;
+ u8 NTSC_FILTER3;
+ u8 NTSC_OFFSET0;
+ u8 NTSC_OFFSET1;
+ u8 NTSC_ERROR0;
+ u8 NTSC_ERROR1;
+ u8 INT_AGC_LEVEL0;
+ u8 INT_AGC_LEVEL1;
+ u8 EXT_AGC_LEVEL0;
+ u8 EXT_AGC_LEVEL1;
+} PACKED;
+
+#define MSGID_STATUS2 0x14
+struct bcm3510_hab_cmd_status2 {
+ struct {
+ u8 EQ_MODE :4;
+ u8 reserved :2;
+ u8 QRE :1;
+ u8 QSR :1;
+ } PACKED STATUS0;
+ struct {
+ u8 RL :1;
+ u8 FL :1;
+ u8 OL :1;
+ u8 reserved :5;
+ } PACKED STATUS1;
+ u8 SYMBOL_RATE0;
+ u8 SYMBOL_RATE1;
+ u8 SYMBOL_RATE2;
+ u8 SYMBOL_RATE3;
+ u8 LDCERC0;
+ u8 LDCERC1;
+ u8 LDCERC2;
+ u8 LDCERC3;
+ u8 LDUERC0;
+ u8 LDUERC1;
+ u8 LDUERC2;
+ u8 LDUERC3;
+ u8 LDBER0;
+ u8 LDBER1;
+ u8 LDBER2;
+ u8 LDBER3;
+ struct {
+ u8 MODE_TYPE :4; /* acquire mode 0 */
+ u8 reservd :4;
+ } MODE_TYPE;
+ u8 SNR_EST0;
+ u8 SNR_EST1;
+ u8 SIGNAL;
+} PACKED;
+
+#define CMD_SET_RF_BW_NOT_LISTED 0x3f
+#define MSGID_SET_RF_BW_NOT_LISTED 0x11
+/* TODO */
+
+#endif
diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c
index 47ab02e133d..1a4f1f7c228 100644
--- a/drivers/media/dvb/frontends/dib3000-common.c
+++ b/drivers/media/dvb/frontends/dib3000-common.c
@@ -73,7 +73,7 @@ u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
};
MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
-MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb-frontend drivers");
+MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb frontend drivers");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(dib3000_seq);
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
index 80687c13083..2d5475b5c06 100644
--- a/drivers/media/dvb/frontends/dib3000.h
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -32,9 +32,8 @@ struct dib3000_config
u8 demod_address;
/* PLL maintenance and the i2c address of the PLL */
- u8 (*pll_addr)(struct dvb_frontend *fe);
- int (*pll_init)(struct dvb_frontend *fe, u8 pll_buf[5]);
- int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params, u8 pll_buf[5]);
+ int (*pll_init)(struct dvb_frontend *fe);
+ int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params);
};
struct dib_fe_xfer_ops
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index 6f52d649e97..cd434b7cf9d 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -48,8 +48,6 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-a
#define deb_setf(args...) dprintk(0x04,args)
#define deb_getf(args...) dprintk(0x08,args)
-static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
-
static int dib3000mb_get_frontend(struct dvb_frontend* fe,
struct dvb_frontend_parameters *fep);
@@ -61,10 +59,8 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe,
fe_code_rate_t fe_cr = FEC_NONE;
int search_state, seq;
- if (tuner && state->config.pll_addr && state->config.pll_set) {
- dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
- state->config.pll_set(fe, fep, NULL);
- dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
+ if (tuner && state->config.pll_set) {
+ state->config.pll_set(fe, fep);
deb_setf("bandwidth: ");
switch (ofdm->bandwidth) {
@@ -389,11 +385,8 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
- if (state->config.pll_init) {
- dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
- state->config.pll_init(fe,NULL);
- dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
- }
+ if (state->config.pll_init)
+ state->config.pll_init(fe);
return 0;
}
@@ -623,7 +616,7 @@ static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
{
struct dib3000_state* state = fe->demodulator_priv;
- *unc = rd(DIB3000MB_REG_UNC);
+ *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE);
return 0;
}
@@ -638,9 +631,6 @@ static int dib3000mb_sleep(struct dvb_frontend* fe)
static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
{
tune->min_delay_ms = 800;
- tune->step_size = 166667;
- tune->max_drift = 166667 * 2;
-
return 0;
}
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
index 57e61aa5b07..999b1904781 100644
--- a/drivers/media/dvb/frontends/dib3000mb_priv.h
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -294,7 +294,7 @@ static u16 dib3000mb_reg_filter_coeffs[] = {
static u16 dib3000mb_filter_coeffs[] = {
226, 160, 29,
- 979, 998, 19,
+ 979, 998, 19,
22, 1019, 1006,
1022, 12, 6,
1017, 1017, 3,
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 888f10a5e96..cd33705a432 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -48,8 +48,6 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=s
#define deb_getf(args...) dprintk(0x08,args)
#define deb_stat(args...) dprintk(0x10,args)
-static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr);
-
static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
{
@@ -463,10 +461,8 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
int search_state,auto_val;
u16 val;
- if (tuner && state->config.pll_addr && state->config.pll_set) { /* initial call from dvb */
- dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
- state->config.pll_set(fe,fep,NULL);
- dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
+ if (tuner && state->config.pll_set) { /* initial call from dvb */
+ state->config.pll_set(fe,fep);
state->last_tuned_freq = fep->frequency;
// if (!scanboost) {
@@ -554,19 +550,15 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe,
dib3000mc_set_adp_cfg(state,ofdm->constellation);
wr_foreach(dib3000mc_reg_offset,
dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
-
-
}
return 0;
}
static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
{
- struct dib3000_state *state;
-
+ struct dib3000_state *state = fe->demodulator_priv;
deb_info("init start\n");
- state = fe->demodulator_priv;
state->timing_offset = 0;
state->timing_offset_comp_done = 0;
@@ -649,11 +641,9 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode)
set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF);
-/* if (state->config->pll_init) {
- dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe));
- state->config->pll_init(fe,NULL);
- dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe));
- }*/
+ if (state->config.pll_init)
+ state->config.pll_init(fe);
+
deb_info("init end\n");
return 0;
}
@@ -688,7 +678,7 @@ static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
{
struct dib3000_state* state = fe->demodulator_priv;
- *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT);
+ *unc = rd(DIB3000MC_REG_PACKET_ERRORS);
return 0;
}
@@ -737,10 +727,7 @@ static int dib3000mc_sleep(struct dvb_frontend* fe)
static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
{
- tune->min_delay_ms = 2000;
- tune->step_size = 166667;
- tune->max_drift = 166667 * 2;
-
+ tune->min_delay_ms = 1000;
return 0;
}
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 2a3c2ce7b2a..f73b5f48e23 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -1,6 +1,4 @@
/*
- * $Id: dvb-pll.c,v 1.7 2005/02/10 11:52:02 kraxel Exp $
- *
* descriptions + helper functions for simple dvb plls.
*
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
@@ -114,6 +112,92 @@ struct dvb_pll_desc dvb_pll_unknown_1 = {
};
EXPORT_SYMBOL(dvb_pll_unknown_1);
+/* Infineon TUA6010XS
+ * used in Thomson Cable Tuner
+ */
+struct dvb_pll_desc dvb_pll_tua6010xs = {
+ .name = "Infineon TUA6010XS",
+ .min = 44250000,
+ .max = 858000000,
+ .count = 3,
+ .entries = {
+ { 115750000, 36125000, 62500, 0x8e, 0x03 },
+ { 403250000, 36125000, 62500, 0x8e, 0x06 },
+ { 999999999, 36125000, 62500, 0x8e, 0x85 },
+ },
+};
+EXPORT_SYMBOL(dvb_pll_tua6010xs);
+
+/* Panasonic env57h1xd5 (some Philips PLL ?) */
+struct dvb_pll_desc dvb_pll_env57h1xd5 = {
+ .name = "Panasonic ENV57H1XD5",
+ .min = 44250000,
+ .max = 858000000,
+ .count = 4,
+ .entries = {
+ { 153000000, 36291666, 166666, 0xc2, 0x41 },
+ { 470000000, 36291666, 166666, 0xc2, 0x42 },
+ { 526000000, 36291666, 166666, 0xc2, 0x84 },
+ { 999999999, 36291666, 166666, 0xc2, 0xa4 },
+ },
+};
+EXPORT_SYMBOL(dvb_pll_env57h1xd5);
+
+/* Philips TDA6650/TDA6651
+ * used in Panasonic ENV77H11D5
+ */
+static void tda665x_bw(u8 *buf, int bandwidth)
+{
+ if (bandwidth == BANDWIDTH_8_MHZ)
+ buf[3] |= 0x08;
+}
+
+struct dvb_pll_desc dvb_pll_tda665x = {
+ .name = "Philips TDA6650/TDA6651",
+ .min = 44250000,
+ .max = 858000000,
+ .setbw = tda665x_bw,
+ .count = 12,
+ .entries = {
+ { 93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
+ { 123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
+ { 161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
+ { 163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
+ { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
+ { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
+ { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
+ { 444000000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ },
+ { 583834000, 36249333, 166667, 0xca, 0x63 /* 011 0 0 0 11 */ },
+ { 793834000, 36249333, 166667, 0xca, 0xa3 /* 101 0 0 0 11 */ },
+ { 444834000, 36249333, 166667, 0xca, 0xc3 /* 110 0 0 0 11 */ },
+ { 861000000, 36249333, 166667, 0xca, 0xe3 /* 111 0 0 0 11 */ },
+ }
+};
+EXPORT_SYMBOL(dvb_pll_tda665x);
+
+/* Infineon TUA6034
+ * used in LG TDTP E102P
+ */
+static void tua6034_bw(u8 *buf, int bandwidth)
+{
+ if (BANDWIDTH_7_MHZ != bandwidth)
+ buf[3] |= 0x08;
+}
+
+struct dvb_pll_desc dvb_pll_tua6034 = {
+ .name = "Infineon TUA6034",
+ .min = 44250000,
+ .max = 858000000,
+ .count = 3,
+ .setbw = tua6034_bw,
+ .entries = {
+ { 174500000, 36166667, 62500, 0xce, 0x01 },
+ { 230000000, 36166667, 62500, 0xce, 0x02 },
+ { 999999999, 36166667, 62500, 0xce, 0x04 },
+ },
+};
+EXPORT_SYMBOL(dvb_pll_tua6034);
+
/* ----------------------------------------------------------- */
/* code */
@@ -160,9 +244,3 @@ EXPORT_SYMBOL(dvb_pll_configure);
MODULE_DESCRIPTION("dvb pll library");
MODULE_AUTHOR("Gerd Knorr");
MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index c4c3c56c4a8..b796778624b 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -1,5 +1,5 @@
/*
- * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $
+ * descriptions + helper functions for simple dvb plls.
*/
#ifndef __DVB_PLL_H__
@@ -17,7 +17,7 @@ struct dvb_pll_desc {
u32 stepsize;
u8 cb1;
u8 cb2;
- } entries[9];
+ } entries[12];
};
extern struct dvb_pll_desc dvb_pll_thomson_dtt7579;
@@ -26,6 +26,11 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt7610;
extern struct dvb_pll_desc dvb_pll_lg_z201;
extern struct dvb_pll_desc dvb_pll_unknown_1;
+extern struct dvb_pll_desc dvb_pll_tua6010xs;
+extern struct dvb_pll_desc dvb_pll_env57h1xd5;
+extern struct dvb_pll_desc dvb_pll_tua6034;
+extern struct dvb_pll_desc dvb_pll_tda665x;
+
int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
u32 freq, int bandwidth);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 6c05fddb69a..f9383e7f34f 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -7,6 +7,19 @@ menu "Video For Linux"
comment "Video Adapters"
+config CONFIG_TUNER_MULTI_I2C
+ bool "Enable support for multiple I2C devices on Video Adapters (EXPERIMENTAL)"
+ depends on VIDEO_DEV && EXPERIMENTAL
+ ---help---
+ Some video adapters have more than one tuner inside. This patch
+ enables support for using more than one tuner. This is required
+ for some cards to allow tunning both video and radio.
+ It also improves I2C autodetection for these cards.
+
+ Only few tuners currently is supporting this. More to come.
+
+ It is safe to say 'Y' here even if your card has only one I2C tuner.
+
config VIDEO_BT848
tristate "BT848 Video For Linux"
depends on VIDEO_DEV && PCI && I2C
@@ -330,6 +343,7 @@ config VIDEO_CX88_DVB
select VIDEO_BUF_DVB
select DVB_MT352
select DVB_OR51132
+ select DVB_CX22702
---help---
This adds support for DVB/ATSC cards based on the
Connexant 2388x chip.
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index 07f72f64c5f..9a642c7de54 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -6,7 +6,7 @@
It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly
connected to bt848/bt878 GPIO pins on this purpose.
(see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets)
-
+
Supported Cards:
- Pixelview Rev.4E: 0x8a
GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 !
@@ -31,8 +31,8 @@
#include <linux/errno.h>
#include <linux/slab.h>
-#include "id.h"
-#include "audiochip.h"
+#include <media/audiochip.h>
+#include <media/id.h>
#include "bttv.h"
#include "bt832.h"
@@ -95,7 +95,7 @@ int bt832_init(struct i2c_client *i2c_client_s)
buf=kmalloc(65,GFP_KERNEL);
bt832_hexdump(i2c_client_s,buf);
-
+
if(buf[0x40] != 0x31) {
printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
kfree(buf);
@@ -135,7 +135,7 @@ int bt832_init(struct i2c_client *i2c_client_s)
buf[1]= 0x27 & (~0x01); // Default | !skip
if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc);
-
+
bt832_hexdump(i2c_client_s,buf);
#if 0
@@ -168,8 +168,7 @@ int bt832_init(struct i2c_client *i2c_client_s)
-static int bt832_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
+static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct bt832 *t;
@@ -184,27 +183,32 @@ static int bt832_attach(struct i2c_adapter *adap, int addr,
return -ENOMEM;
memset(t,0,sizeof(*t));
t->client = client_template;
- t->client.data = t;
+ i2c_set_clientdata(&t->client, t);
i2c_attach_client(&t->client);
if(! bt832_init(&t->client)) {
bt832_detach(&t->client);
return -1;
}
-
+
return 0;
}
static int bt832_probe(struct i2c_adapter *adap)
{
+#ifdef I2C_CLASS_TV_ANALOG
if (adap->class & I2C_CLASS_TV_ANALOG)
return i2c_probe(adap, &addr_data, bt832_attach);
+#else
+ if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
+ return i2c_probe(adap, &addr_data, bt832_attach);
+#endif
return 0;
}
static int bt832_detach(struct i2c_client *client)
{
- struct bt832 *t = (struct bt832*)client->data;
+ struct bt832 *t = i2c_get_clientdata(client);
printk("bt832: detach.\n");
i2c_detach_client(client);
@@ -215,7 +219,7 @@ static int bt832_detach(struct i2c_client *client)
static int
bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
- struct bt832 *t = (struct bt832*)client->data;
+ struct bt832 *t = i2c_get_clientdata(client);
printk("bt832: command %x\n",cmd);
@@ -249,19 +253,18 @@ static struct i2c_driver driver = {
};
static struct i2c_client client_template =
{
- .name = "bt832",
- .flags = I2C_CLIENT_ALLOW_USE,
- .driver = &driver,
+ I2C_DEVNAME("bt832"),
+ .flags = I2C_CLIENT_ALLOW_USE,
+ .driver = &driver,
};
-int bt832_init_module(void)
+static int __init bt832_init_module(void)
{
- i2c_add_driver(&driver);
- return 0;
+ return i2c_add_driver(&driver);
}
-static void bt832_cleanup_module(void)
+static void __exit bt832_cleanup_module(void)
{
i2c_del_driver(&driver);
}
@@ -269,3 +272,10 @@ static void bt832_cleanup_module(void)
module_init(bt832_init_module);
module_exit(bt832_cleanup_module);
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/video/bt832.h b/drivers/media/video/bt832.h
index 7a98c06e0e3..9b6a8d2c96b 100644
--- a/drivers/media/video/bt832.h
+++ b/drivers/media/video/bt832.h
@@ -1,6 +1,6 @@
/* Bt832 CMOS Camera Video Processor (VP)
- The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS
+ The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS
color digital camera directly to video capture devices via an 8-bit,
4:2:2 YUV or YCrCb video interface.
@@ -85,7 +85,7 @@
#define BT832_DEVICE_ID 63
# define BT832_DEVICE_ID__31 0x31 // Bt832 has ID 0x31
-/* STMicroelectronivcs VV5404 camera module
+/* STMicroelectronivcs VV5404 camera module
i2c: 0x20: sensor address
i2c: 0xa0: eeprom for ccd defect map
*/
@@ -256,26 +256,26 @@ For the CCIR-601 standards, the sampling is based on a static orthogonal samplin
//===========================================================================
// Timing generator SRAM table values for CCIR601 720x480 NTSC
//===========================================================================
-// For NTSC CCIR656
+// For NTSC CCIR656
BYTE BtCard::SRAMTable_NTSC[] =
{
// SRAM Timing Table for NTSC
- 0x0c, 0xc0, 0x00,
- 0x00, 0x90, 0xc2,
- 0x03, 0x10, 0x03,
- 0x06, 0x10, 0x34,
- 0x12, 0x12, 0x65,
- 0x02, 0x13, 0x24,
- 0x19, 0x00, 0x24,
- 0x39, 0x00, 0x96,
- 0x59, 0x08, 0x93,
+ 0x0c, 0xc0, 0x00,
+ 0x00, 0x90, 0xc2,
+ 0x03, 0x10, 0x03,
+ 0x06, 0x10, 0x34,
+ 0x12, 0x12, 0x65,
+ 0x02, 0x13, 0x24,
+ 0x19, 0x00, 0x24,
+ 0x39, 0x00, 0x96,
+ 0x59, 0x08, 0x93,
0x83, 0x08, 0x97,
- 0x03, 0x50, 0x30,
- 0xc0, 0x40, 0x30,
- 0x86, 0x01, 0x01,
- 0xa6, 0x0d, 0x62,
- 0x03, 0x11, 0x61,
- 0x05, 0x37, 0x30,
+ 0x03, 0x50, 0x30,
+ 0xc0, 0x40, 0x30,
+ 0x86, 0x01, 0x01,
+ 0xa6, 0x0d, 0x62,
+ 0x03, 0x11, 0x61,
+ 0x05, 0x37, 0x30,
0xac, 0x21, 0x50
};
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index 6334122704a..251092e7f19 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -1,5 +1,5 @@
/*
- $Id: bttv-cards.c,v 1.47 2005/02/22 14:06:32 kraxel Exp $
+ $Id: bttv-cards.c,v 1.49 2005/06/10 17:20:24 mchehab Exp $
bttv-cards.c
@@ -51,6 +51,7 @@ static void avermedia_eeprom(struct bttv *btv);
static void osprey_eeprom(struct bttv *btv);
static void modtec_eeprom(struct bttv *btv);
static void init_PXC200(struct bttv *btv);
+static void init_RTV24(struct bttv *btv);
static void winview_audio(struct bttv *btv, struct video_audio *v, int set);
static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set);
@@ -2251,6 +2252,20 @@ struct tvcard bttv_tvcards[] = {
.no_tda7432 = 1,
.no_tda9875 = 1,
.muxsel_hook = kodicom4400r_muxsel,
+},
+{
+ /* ---- card 0x85---------------------------------- */
+ /* Michael Henson <mhenson@clarityvi.com> */
+ /* Adlink RTV24 with special unlock codes */
+ .name = "Adlink RTV24",
+ .video_inputs = 4,
+ .audio_inputs = 1,
+ .tuner = 0,
+ .svhs = 2,
+ .muxsel = { 2, 3, 1, 0},
+ .tuner_type = -1,
+ .pll = PLL_28,
+
}};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -2636,6 +2651,10 @@ void __devinit bttv_init_card1(struct bttv *btv)
case BTTV_AVDVBT_771:
btv->use_i2c_hw = 1;
break;
+ case BTTV_ADLINK_RTV24:
+ init_RTV24( btv );
+ break;
+
}
if (!bttv_tvcards[btv->c.type].has_dvb)
bttv_reset_audio(btv);
@@ -2784,6 +2803,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
}
btv->pll.pll_current = -1;
+ bttv_reset_audio(btv);
+
/* tuner configuration (from card list / autodetect / insmod option) */
if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
if(UNSET == btv->tuner_type)
@@ -3304,6 +3325,83 @@ static void __devinit init_PXC200(struct bttv *btv)
}
+
+/* ----------------------------------------------------------------------- */
+/*
+ * The Adlink RTV-24 (aka Angelo) has some special initialisation to unlock
+ * it. This apparently involves the following procedure for each 878 chip:
+ *
+ * 1) write 0x00C3FEFF to the GPIO_OUT_EN register
+ *
+ * 2) write to GPIO_DATA
+ * - 0x0E
+ * - sleep 1ms
+ * - 0x10 + 0x0E
+ * - sleep 10ms
+ * - 0x0E
+ * read from GPIO_DATA into buf (uint_32)
+ * - if ( data>>18 & 0x01 != 0) || ( buf>>19 & 0x01 != 1 )
+ * error. ERROR_CPLD_Check_Failed stop.
+ *
+ * 3) write to GPIO_DATA
+ * - write 0x4400 + 0x0E
+ * - sleep 10ms
+ * - write 0x4410 + 0x0E
+ * - sleep 1ms
+ * - write 0x0E
+ * read from GPIO_DATA into buf (uint_32)
+ * - if ( buf>>18 & 0x01 ) || ( buf>>19 && 0x01 != 0 )
+ * error. ERROR_CPLD_Check_Failed.
+ */
+/* ----------------------------------------------------------------------- */
+void
+init_RTV24 (struct bttv *btv)
+{
+ uint32_t dataRead = 0;
+ long watchdog_value = 0x0E;
+
+ printk (KERN_INFO
+ "bttv%d: Adlink RTV-24 initialisation in progress ...\n",
+ btv->c.nr);
+
+ btwrite (0x00c3feff, BT848_GPIO_OUT_EN);
+
+ btwrite (0 + watchdog_value, BT848_GPIO_DATA);
+ msleep (1);
+ btwrite (0x10 + watchdog_value, BT848_GPIO_DATA);
+ msleep (10);
+ btwrite (0 + watchdog_value, BT848_GPIO_DATA);
+
+ dataRead = btread (BT848_GPIO_DATA);
+
+ if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 1)) {
+ printk (KERN_INFO
+ "bttv%d: Adlink RTV-24 initialisation(1) ERROR_CPLD_Check_Failed (read %d)\n",
+ btv->c.nr, dataRead);
+ }
+
+ btwrite (0x4400 + watchdog_value, BT848_GPIO_DATA);
+ msleep (10);
+ btwrite (0x4410 + watchdog_value, BT848_GPIO_DATA);
+ msleep (1);
+ btwrite (watchdog_value, BT848_GPIO_DATA);
+ msleep (1);
+ dataRead = btread (BT848_GPIO_DATA);
+
+ if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 0)) {
+ printk (KERN_INFO
+ "bttv%d: Adlink RTV-24 initialisation(2) ERROR_CPLD_Check_Failed (read %d)\n",
+ btv->c.nr, dataRead);
+
+ return;
+ }
+
+ printk (KERN_INFO
+ "bttv%d: Adlink RTV-24 initialisation complete.\n", btv->c.nr);
+}
+
+
+
/* ----------------------------------------------------------------------- */
/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
/*
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 033cc5498f2..290289a9975 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -1,5 +1,5 @@
/*
- $Id: bttv-driver.c,v 1.37 2005/02/21 13:57:59 kraxel Exp $
+ $Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $
bttv - Bt848 frame grabber driver
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index c2368bc832e..da448a5f9e9 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -1,5 +1,5 @@
/*
- $Id: bttv-i2c.c,v 1.18 2005/02/16 12:14:10 kraxel Exp $
+ $Id: bttv-i2c.c,v 1.21 2005/06/10 17:20:24 mchehab Exp $
bttv-i2c.c -- all the i2c code is here
diff --git a/drivers/media/video/bttv.h b/drivers/media/video/bttv.h
index 8322b66e090..191eaf1714b 100644
--- a/drivers/media/video/bttv.h
+++ b/drivers/media/video/bttv.h
@@ -1,5 +1,5 @@
/*
- * $Id: bttv.h,v 1.17 2005/02/22 14:06:32 kraxel Exp $
+ * $Id: bttv.h,v 1.18 2005/05/24 23:41:42 nsh Exp $
*
* bttv - Bt848 frame grabber driver
*
@@ -135,6 +135,7 @@
#define BTTV_DVICO_DVBT_LITE 0x80
#define BTTV_TIBET_CS16 0x83
#define BTTV_KODICOM_4400R 0x84
+#define BTTV_ADLINK_RTV24 0x85
/* i2c address list */
#define I2C_TSA5522 0xc2
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 1a9ba7e1cf5..7b6f1e85602 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -226,10 +226,6 @@ extern int fini_bttv_i2c(struct bttv *btv);
#define dprintk if (bttv_debug >= 1) printk
#define d2printk if (bttv_debug >= 2) printk
-/* our devices */
-#define BTTV_MAX 16
-extern unsigned int bttv_num;
-
#define BTTV_MAX_FBUF 0x208000
#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */
@@ -375,6 +371,10 @@ struct bttv {
unsigned int users;
struct bttv_fh init;
};
+
+/* our devices */
+#define BTTV_MAX 16
+extern unsigned int bttv_num;
extern struct bttv bttvs[BTTV_MAX];
/* private ioctls */
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 46d6778b863..91f8afeded8 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-blackbird.c,v 1.26 2005/03/07 15:58:05 kraxel Exp $
+ * $Id: cx88-blackbird.c,v 1.27 2005/06/03 13:31:50 mchehab Exp $
*
* Support for a cx23416 mpeg encoder via cx2388x host port.
* "blackbird" reference design.
@@ -61,37 +61,304 @@ static LIST_HEAD(cx8802_devlist);
#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
-/*Firmware API commands*/
-#define IVTV_API_ENC_PING_FW 0x00000080
-#define IVTV_API_ENC_GETVER 0x000000C4
-#define IVTV_API_ENC_HALT_FW 0x000000C3
-#define IVTV_API_STD_TIMEOUT 0x00010000 /*units??*/
-//#define IVTV_API_ASSIGN_PGM_INDEX_INFO 0x000000c7
-#define IVTV_API_ASSIGN_STREAM_TYPE 0x000000b9
-#define IVTV_API_ASSIGN_OUTPUT_PORT 0x000000bb
-#define IVTV_API_ASSIGN_FRAMERATE 0x0000008f
-#define IVTV_API_ASSIGN_FRAME_SIZE 0x00000091
-#define IVTV_API_ASSIGN_ASPECT_RATIO 0x00000099
-#define IVTV_API_ASSIGN_BITRATES 0x00000095
-#define IVTV_API_ASSIGN_GOP_PROPERTIES 0x00000097
-#define IVTV_API_ASSIGN_3_2_PULLDOWN 0x000000b1
-#define IVTV_API_ASSIGN_GOP_CLOSURE 0x000000c5
-#define IVTV_API_ASSIGN_AUDIO_PROPERTIES 0x000000bd
-#define IVTV_API_ASSIGN_DNR_FILTER_MODE 0x0000009b
-#define IVTV_API_ASSIGN_DNR_FILTER_PROPS 0x0000009d
-#define IVTV_API_ASSIGN_CORING_LEVELS 0x0000009f
-#define IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE 0x000000a1
-#define IVTV_API_ASSIGN_FRAME_DROP_RATE 0x000000d0
-#define IVTV_API_ASSIGN_PLACEHOLDER 0x000000d8
-#define IVTV_API_MUTE_VIDEO 0x000000d9
-#define IVTV_API_MUTE_AUDIO 0x000000da
-#define IVTV_API_INITIALIZE_INPUT 0x000000cd
-#define IVTV_API_REFRESH_INPUT 0x000000d3
-#define IVTV_API_ASSIGN_NUM_VSYNC_LINES 0x000000d6
-#define IVTV_API_BEGIN_CAPTURE 0x00000081
-//#define IVTV_API_PAUSE_ENCODER 0x000000d2
-//#define IVTV_API_EVENT_NOTIFICATION 0x000000d5
-#define IVTV_API_END_CAPTURE 0x00000082
+/* Firmware API commands */
+/* #define IVTV_API_STD_TIMEOUT 0x00010000 // 65536, units?? */
+#define IVTV_API_STD_TIMEOUT 500
+
+#define BLACKBIRD_API_PING 0x80
+#define BLACKBIRD_API_BEGIN_CAPTURE 0x81
+enum blackbird_capture_type {
+ BLACKBIRD_MPEG_CAPTURE,
+ BLACKBIRD_RAW_CAPTURE,
+ BLACKBIRD_RAW_PASSTHRU_CAPTURE
+};
+enum blackbird_capture_bits {
+ BLACKBIRD_RAW_BITS_NONE = 0x00,
+ BLACKBIRD_RAW_BITS_YUV_CAPTURE = 0x01,
+ BLACKBIRD_RAW_BITS_PCM_CAPTURE = 0x02,
+ BLACKBIRD_RAW_BITS_VBI_CAPTURE = 0x04,
+ BLACKBIRD_RAW_BITS_PASSTHRU_CAPTURE = 0x08,
+ BLACKBIRD_RAW_BITS_TO_HOST_CAPTURE = 0x10
+};
+#define BLACKBIRD_API_END_CAPTURE 0x82
+enum blackbird_capture_end {
+ BLACKBIRD_END_AT_GOP, /* stop at the end of gop, generate irq */
+ BLACKBIRD_END_NOW, /* stop immediately, no irq */
+};
+#define BLACKBIRD_API_SET_AUDIO_ID 0x89
+#define BLACKBIRD_API_SET_VIDEO_ID 0x8B
+#define BLACKBIRD_API_SET_PCR_ID 0x8D
+#define BLACKBIRD_API_SET_FRAMERATE 0x8F
+enum blackbird_framerate {
+ BLACKBIRD_FRAMERATE_NTSC_30, /* NTSC: 30fps */
+ BLACKBIRD_FRAMERATE_PAL_25 /* PAL: 25fps */
+};
+#define BLACKBIRD_API_SET_RESOLUTION 0x91
+#define BLACKBIRD_API_SET_VIDEO_BITRATE 0x95
+enum blackbird_video_bitrate_type {
+ BLACKBIRD_VIDEO_VBR,
+ BLACKBIRD_VIDEO_CBR
+};
+#define BLACKBIRD_PEAK_RATE_DIVISOR 400
+enum blackbird_mux_rate {
+ BLACKBIRD_MUX_RATE_DEFAULT,
+ /* dvd mux rate: multiply by 400 to get the actual rate */
+ BLACKBIRD_MUX_RATE_DVD = 25200
+};
+#define BLACKBIRD_API_SET_GOP_STRUCTURE 0x97
+#define BLACKBIRD_API_SET_ASPECT_RATIO 0x99
+enum blackbird_aspect_ratio {
+ BLACKBIRD_ASPECT_RATIO_FORBIDDEN,
+ BLACKBIRD_ASPECT_RATIO_1_1_SQUARE,
+ BLACKBIRD_ASPECT_RATIO_4_3,
+ BLACKBIRD_ASPECT_RATIO_16_9,
+ BLACKBIRD_ASPECT_RATIO_221_100,
+ BLACKBIRD_ASPECT_RATIO_RESERVED
+};
+#define BLACKBIRD_API_SET_DNR_MODE 0x9B
+enum blackbird_dnr_bits {
+ BLACKBIRD_DNR_BITS_MANUAL,
+ BLACKBIRD_DNR_BITS_AUTO_SPATIAL,
+ BLACKBIRD_DNR_BITS_AUTO_TEMPORAL,
+ BLACKBIRD_DNR_BITS_AUTO
+};
+enum blackbird_median_filter {
+ BLACKBIRD_MEDIAN_FILTER_DISABLED,
+ BLACKBIRD_MEDIAN_FILTER_HORIZONTAL,
+ BLACKBIRD_MEDIAN_FILTER_VERTICAL,
+ BLACKBIRD_MEDIAN_FILTER_HV,
+ BLACKBIRD_MEDIAN_FILTER_DIAGONAL
+};
+#define BLACKBIRD_API_SET_MANUAL_DNR 0x9D
+#define BLACKBIRD_API_SET_DNR_MEDIAN 0x9F
+#define BLACKBIRD_API_SET_SPATIAL_FILTER 0xA1
+enum blackbird_spatial_filter_luma {
+ BLACKBIRD_SPATIAL_FILTER_LUMA_DISABLED,
+ BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
+ BLACKBIRD_SPATIAL_FILTER_LUMA_1D_VERT,
+ BLACKBIRD_SPATIAL_FILTER_LUMA_2D_HV, /* separable, default */
+ BLACKBIRD_SPATIAL_FILTER_LUMA_2D_SYMM /* symmetric non-separable */
+};
+enum blackbird_spatial_filter_chroma {
+ BLACKBIRD_SPATIAL_FILTER_CHROMA_DISABLED,
+ BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ /* default */
+};
+#define BLACKBIRD_API_SET_3_2_PULLDOWN 0xB1
+enum blackbird_pulldown {
+ BLACKBIRD_3_2_PULLDOWN_DISABLED,
+ BLACKBIRD_3_2_PULLDOWN_ENABLED
+};
+#define BLACKBIRD_API_SET_VBI_LINE_NO 0xB7
+enum blackbird_vbi_line_bits {
+ BLACKBIRD_VBI_LINE_BITS_TOP_FIELD,
+ BLACKBIRD_VBI_LINE_BITS_BOT_FIELD = (1 << 31),
+ BLACKBIRD_VBI_LINE_BITS_ALL_LINES = 0xFFFFFFFF
+};
+enum blackbird_vbi_line {
+ BLACKBIRD_VBI_LINE_DISABLED,
+ BLACKBIRD_VBI_LINE_ENABLED
+};
+enum blackbird_vbi_slicing {
+ BLACKBIRD_VBI_SLICING_NONE,
+ BLACKBIRD_VBI_SLICING_CLOSED_CAPTION
+};
+#define BLACKBIRD_API_SET_STREAM_TYPE 0xB9
+enum blackbird_stream_type {
+ BLACKBIRD_STREAM_PROGRAM,
+ BLACKBIRD_STREAM_TRANSPORT,
+ BLACKBIRD_STREAM_MPEG1,
+ BLACKBIRD_STREAM_PES_AV,
+ BLACKBIRD_STREAM_UNKNOWN4,
+ BLACKBIRD_STREAM_PES_VIDEO,
+ BLACKBIRD_STREAM_UNKNOWN6,
+ BLACKBIRD_STREAM_PES_AUDIO,
+ BLACKBIRD_STREAM_UNKNOWN8,
+ BLACKBIRD_STREAM_UNKNOWN9, /* audio/pcm ? */
+ BLACKBIRD_STREAM_DVD,
+ BLACKBIRD_STREAM_VCD,
+ BLACKBIRD_STREAM_UNKNOWN12 /* svcd/xvcd ? */
+};
+#define BLACKBIRD_API_SET_OUTPUT_PORT 0xBB
+enum blackbird_stream_port {
+ BLACKBIRD_OUTPUT_PORT_MEMORY,
+ BLACKBIRD_OUTPUT_PORT_STREAMING,
+ BLACKBIRD_OUTPUT_PORT_SERIAL
+};
+#define BLACKBIRD_API_SET_AUDIO_PARAMS 0xBD
+enum blackbird_audio_bits_sample_rate {
+ BLACKBIRD_AUDIO_BITS_44100HZ,
+ BLACKBIRD_AUDIO_BITS_48000HZ,
+ BLACKBIRD_AUDIO_BITS_32000HZ,
+ BLACKBIRD_AUDIO_BITS_RESERVED_HZ,
+};
+enum blackbird_audio_bits_encoding {
+ BLACKBIRD_AUDIO_BITS_LAYER_1 = 0x1 << 2,
+ BLACKBIRD_AUDIO_BITS_LAYER_2 = 0x2 << 2,
+};
+enum blackbird_audio_bits_bitrate_layer_1 {
+ BLACKBIRD_AUDIO_BITS_LAYER_1_FREE_FORMAT,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_32 = 0x01 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_64 = 0x02 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_96 = 0x03 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_128 = 0x04 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_160 = 0x05 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_192 = 0x06 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_224 = 0x07 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_256 = 0x08 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_288 = 0x09 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_320 = 0x0A << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_352 = 0x0B << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_384 = 0x0C << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_416 = 0x0D << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_1_448 = 0x0E << 4,
+};
+enum blackbird_audio_bits_bitrate_layer_2 {
+ BLACKBIRD_AUDIO_BITS_LAYER_2_FREE_FORMAT,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_32 = 0x01 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_48 = 0x02 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_56 = 0x03 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_64 = 0x04 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_80 = 0x05 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_96 = 0x06 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_112 = 0x07 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_128 = 0x08 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_160 = 0x09 << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_192 = 0x0A << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_224 = 0x0B << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_256 = 0x0C << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_320 = 0x0D << 4,
+ BLACKBIRD_AUDIO_BITS_LAYER_2_384 = 0x0E << 4,
+};
+enum blackbird_audio_bits_mode {
+ BLACKBIRD_AUDIO_BITS_STEREO,
+ BLACKBIRD_AUDIO_BITS_JOINT_STEREO = 0x1 << 8,
+ BLACKBIRD_AUDIO_BITS_DUAL = 0x2 << 8,
+ BLACKBIRD_AUDIO_BITS_MONO = 0x3 << 8,
+};
+enum blackbird_audio_bits_mode_extension {
+ BLACKBIRD_AUDIO_BITS_BOUND_4,
+ BLACKBIRD_AUDIO_BITS_BOUND_8 = 0x1 << 10,
+ BLACKBIRD_AUDIO_BITS_BOUND_12 = 0x2 << 10,
+ BLACKBIRD_AUDIO_BITS_BOUND_16 = 0x3 << 10,
+};
+enum blackbird_audio_bits_emphasis {
+ BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE,
+ BLACKBIRD_AUDIO_BITS_EMPHASIS_50_15 = 0x1 << 12,
+ BLACKBIRD_AUDIO_BITS_EMPHASIS_RESERVED = 0x2 << 12,
+ BLACKBIRD_AUDIO_BITS_EMPHASIS_CCITT_J17 = 0x3 << 12,
+};
+enum blackbird_audio_bits_crc {
+ BLACKBIRD_AUDIO_BITS_CRC_OFF,
+ BLACKBIRD_AUDIO_BITS_CRC_ON = 0x1 << 14,
+};
+enum blackbird_audio_bits_copyright {
+ BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF,
+ BLACKBIRD_AUDIO_BITS_COPYRIGHT_ON = 0x1 << 15,
+};
+enum blackbird_audio_bits_original {
+ BLACKBIRD_AUDIO_BITS_COPY,
+ BLACKBIRD_AUDIO_BITS_ORIGINAL = 0x1 << 16,
+};
+#define BLACKBIRD_API_HALT 0xC3
+#define BLACKBIRD_API_GET_VERSION 0xC4
+#define BLACKBIRD_API_SET_GOP_CLOSURE 0xC5
+enum blackbird_gop_closure {
+ BLACKBIRD_GOP_CLOSURE_OFF,
+ BLACKBIRD_GOP_CLOSURE_ON,
+};
+#define BLACKBIRD_API_DATA_XFER_STATUS 0xC6
+enum blackbird_data_xfer_status {
+ BLACKBIRD_MORE_BUFFERS_FOLLOW,
+ BLACKBIRD_LAST_BUFFER,
+};
+#define BLACKBIRD_API_PROGRAM_INDEX_INFO 0xC7
+enum blackbird_picture_mask {
+ BLACKBIRD_PICTURE_MASK_NONE,
+ BLACKBIRD_PICTURE_MASK_I_FRAMES,
+ BLACKBIRD_PICTURE_MASK_I_P_FRAMES = 0x3,
+ BLACKBIRD_PICTURE_MASK_ALL_FRAMES = 0x7,
+};
+#define BLACKBIRD_API_SET_VBI_PARAMS 0xC8
+enum blackbird_vbi_mode_bits {
+ BLACKBIRD_VBI_BITS_SLICED,
+ BLACKBIRD_VBI_BITS_RAW,
+};
+enum blackbird_vbi_insertion_bits {
+ BLACKBIRD_VBI_BITS_INSERT_IN_XTENSION_USR_DATA,
+ BLACKBIRD_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1,
+ BLACKBIRD_VBI_BITS_SEPARATE_STREAM = 0x2 << 1,
+ BLACKBIRD_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1,
+ BLACKBIRD_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1,
+};
+#define BLACKBIRD_API_SET_DMA_BLOCK_SIZE 0xC9
+enum blackbird_dma_unit {
+ BLACKBIRD_DMA_BYTES,
+ BLACKBIRD_DMA_FRAMES,
+};
+#define BLACKBIRD_API_DMA_TRANSFER_INFO 0xCA
+#define BLACKBIRD_API_DMA_TRANSFER_STAT 0xCB
+enum blackbird_dma_transfer_status_bits {
+ BLACKBIRD_DMA_TRANSFER_BITS_DONE = 0x01,
+ BLACKBIRD_DMA_TRANSFER_BITS_ERROR = 0x04,
+ BLACKBIRD_DMA_TRANSFER_BITS_LL_ERROR = 0x10,
+};
+#define BLACKBIRD_API_SET_DMA2HOST_ADDR 0xCC
+#define BLACKBIRD_API_INIT_VIDEO_INPUT 0xCD
+#define BLACKBIRD_API_SET_FRAMESKIP 0xD0
+#define BLACKBIRD_API_PAUSE 0xD2
+enum blackbird_pause {
+ BLACKBIRD_PAUSE_ENCODING,
+ BLACKBIRD_RESUME_ENCODING,
+};
+#define BLACKBIRD_API_REFRESH_INPUT 0xD3
+#define BLACKBIRD_API_SET_COPYRIGHT 0xD4
+enum blackbird_copyright {
+ BLACKBIRD_COPYRIGHT_OFF,
+ BLACKBIRD_COPYRIGHT_ON,
+};
+#define BLACKBIRD_API_SET_NOTIFICATION 0xD5
+enum blackbird_notification_type {
+ BLACKBIRD_NOTIFICATION_REFRESH,
+};
+enum blackbird_notification_status {
+ BLACKBIRD_NOTIFICATION_OFF,
+ BLACKBIRD_NOTIFICATION_ON,
+};
+enum blackbird_notification_mailbox {
+ BLACKBIRD_NOTIFICATION_NO_MAILBOX = -1,
+};
+#define BLACKBIRD_API_SET_CAPTURE_LINES 0xD6
+enum blackbird_field1_lines {
+ BLACKBIRD_FIELD1_SAA7114 = 0x00EF, /* 239 */
+ BLACKBIRD_FIELD1_SAA7115 = 0x00F0, /* 240 */
+ BLACKBIRD_FIELD1_MICRONAS = 0x0105, /* 261 */
+};
+enum blackbird_field2_lines {
+ BLACKBIRD_FIELD2_SAA7114 = 0x00EF, /* 239 */
+ BLACKBIRD_FIELD2_SAA7115 = 0x00F0, /* 240 */
+ BLACKBIRD_FIELD2_MICRONAS = 0x0106, /* 262 */
+};
+#define BLACKBIRD_API_SET_CUSTOM_DATA 0xD7
+enum blackbird_custom_data_type {
+ BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
+ BLACKBIRD_CUSTOM_PRIVATE_PACKET,
+};
+#define BLACKBIRD_API_MUTE_VIDEO 0xD9
+enum blackbird_mute {
+ BLACKBIRD_UNMUTE,
+ BLACKBIRD_MUTE,
+};
+enum blackbird_mute_video_mask {
+ BLACKBIRD_MUTE_VIDEO_V_MASK = 0x0000FF00,
+ BLACKBIRD_MUTE_VIDEO_U_MASK = 0x00FF0000,
+ BLACKBIRD_MUTE_VIDEO_Y_MASK = 0xFF000000,
+};
+enum blackbird_mute_video_shift {
+ BLACKBIRD_MUTE_VIDEO_V_SHIFT = 8,
+ BLACKBIRD_MUTE_VIDEO_U_SHIFT = 16,
+ BLACKBIRD_MUTE_VIDEO_Y_SHIFT = 24,
+};
+#define BLACKBIRD_API_MUTE_AUDIO 0xDA
/* Registers */
#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8 /*| IVTV_REG_OFFSET*/)
@@ -405,68 +672,100 @@ static int blackbird_load_firmware(struct cx8802_dev *dev)
return 0;
}
+/**
+ Settings used by the windows tv app for PVR2000:
+=================================================================================================================
+Profile | Codec | Resolution | CBR/VBR | Video Qlty | V. Bitrate | Frmrate | Audio Codec | A. Bitrate | A. Mode
+-----------------------------------------------------------------------------------------------------------------
+MPEG-1 | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 2000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
+MPEG-2 | MPEG2 | 720x576PAL | VBR | 600 :Good | 4000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
+VCD | MPEG1 | 352x288PAL | (CBR) | 1000:Optimal | 1150 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
+DVD | MPEG2 | 720x576PAL | VBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
+DB* DVD | MPEG2 | 720x576PAL | CBR | 600 :Good | 6000 Kbps | 25fps | MPG1 Layer2 | 224kbps | Stereo
+=================================================================================================================
+*DB: "DirectBurn"
+*/
static void blackbird_codec_settings(struct cx8802_dev *dev)
{
int bitrate_mode = 1;
int bitrate = 7500000;
int bitrate_peak = 7500000;
+#if 1
+ bitrate_mode = BLACKBIRD_VIDEO_CBR;
+ bitrate = 4000*1024;
+ bitrate_peak = 4000*1024;
+#endif
/* assign stream type */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 0); /* program stream */
- //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 2); /* MPEG1 stream */
- //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 3); /* PES A/V */
- //blackbird_api_cmd(dev, IVTV_API_ASSIGN_STREAM_TYPE, 1, 0, 10); /* DVD stream */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM);
+ /* blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_TRANSPORT); */
- /* assign output port */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_OUTPUT_PORT, 1, 0, 1); /* 1 = Host */
+ /* assign output port */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
- /* assign framerate */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAMERATE, 1, 0, 0);
+ /* assign framerate */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_FRAMERATE, 1, 0, BLACKBIRD_FRAMERATE_PAL_25);
- /* assign frame size */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_SIZE, 2, 0,
+ /* assign frame size */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_RESOLUTION, 2, 0,
dev->height, dev->width);
- /* assign aspect ratio */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_ASPECT_RATIO, 1, 0, 2);
+ /* assign aspect ratio */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_ASPECT_RATIO, 1, 0, BLACKBIRD_ASPECT_RATIO_4_3);
- /* assign bitrates */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_BITRATES, 5, 0,
+ /* assign bitrates */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_VIDEO_BITRATE, 5, 0,
bitrate_mode, /* mode */
bitrate, /* bps */
- bitrate_peak / 400, /* peak/400 */
- 0, 0x70); /* encoding buffer, ckennedy */
-
- /* assign gop properties */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 15, 3);
- //blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_PROPERTIES, 2, 0, 2, 1);
-
- /* assign 3 2 pulldown */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_3_2_PULLDOWN, 1, 0, 0);
-
- /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
+ bitrate_peak / BLACKBIRD_PEAK_RATE_DIVISOR, /* peak/400 */
+ BLACKBIRD_MUX_RATE_DEFAULT /*, 0x70*/); /* encoding buffer, ckennedy */
+
+ /* assign gop properties */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_STRUCTURE, 2, 0, 15, 3);
+
+ /* assign 3 2 pulldown */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_3_2_PULLDOWN, 1, 0, BLACKBIRD_3_2_PULLDOWN_DISABLED);
+
+ /* assign audio properties */
+ /* note: it's not necessary to set the samplerate, the mpeg encoder seems to autodetect/adjust */
+ /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, (2<<2) | (8<<4));
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4)); */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_AUDIO_PARAMS, 1, 0,
+ BLACKBIRD_AUDIO_BITS_44100HZ |
+ BLACKBIRD_AUDIO_BITS_LAYER_2 |
+ BLACKBIRD_AUDIO_BITS_LAYER_2_224 |
+ BLACKBIRD_AUDIO_BITS_STEREO |
+ /* BLACKBIRD_AUDIO_BITS_BOUND_4 | */
+ BLACKBIRD_AUDIO_BITS_EMPHASIS_NONE |
+ BLACKBIRD_AUDIO_BITS_CRC_OFF |
+ BLACKBIRD_AUDIO_BITS_COPYRIGHT_OFF |
+ BLACKBIRD_AUDIO_BITS_COPY
+ );
/* assign gop closure */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_GOP_CLOSURE, 1, 0, 0);
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_GOP_CLOSURE, 1, 0, BLACKBIRD_GOP_CLOSURE_OFF);
- /* assign audio properties */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_AUDIO_PROPERTIES, 1, 0, 0 | (2 << 2) | (14 << 4));
- /* assign dnr filter mode */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_MODE, 2, 0, 0, 0);
+ /* assign dnr filter mode */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MODE, 2, 0,
+ BLACKBIRD_DNR_BITS_MANUAL,
+ BLACKBIRD_MEDIAN_FILTER_DISABLED
+ );
- /* assign dnr filter props*/
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_DNR_FILTER_PROPS, 2, 0, 0, 0);
+ /* assign dnr filter props*/
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_MANUAL_DNR, 2, 0, 0, 0);
- /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_CORING_LEVELS, 4, 0, 0, 255, 0, 255);
+ /* assign coring levels (luma_h, luma_l, chroma_h, chroma_l) */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_DNR_MEDIAN, 4, 0, 0, 255, 0, 255);
- /* assign spatial filter type: luma_t: 1 = horiz_only, chroma_t: 1 = horiz_only */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_SPATIAL_FILTER_TYPE, 2, 0, 1, 1);
+ /* assign spatial filter type: luma_t: horiz_only, chroma_t: horiz_only */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_SPATIAL_FILTER, 2, 0,
+ BLACKBIRD_SPATIAL_FILTER_LUMA_1D_HORIZ,
+ BLACKBIRD_SPATIAL_FILTER_CHROMA_1D_HORIZ
+ );
- /* assign frame drop rate */
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0);
+ /* assign frame drop rate */
+ /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_FRAME_DROP_RATE, 1, 0, 0); */
}
static int blackbird_initialize_codec(struct cx8802_dev *dev)
@@ -476,7 +775,7 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
int retval;
dprintk(1,"Initialize codec\n");
- retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
+ retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */
if (retval < 0) {
/* ping was not successful, reset and upload firmware */
cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
@@ -491,13 +790,13 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
if (dev->mailbox < 0)
return -1;
- retval = blackbird_api_cmd(dev, IVTV_API_ENC_PING_FW, 0, 0); /* ping */
+ retval = blackbird_api_cmd(dev, BLACKBIRD_API_PING, 0, 0); /* ping */
if (retval < 0) {
dprintk(0, "ERROR: Firmware ping failed!\n");
return -1;
}
- retval = blackbird_api_cmd(dev, IVTV_API_ENC_GETVER, 0, 1, &version);
+ retval = blackbird_api_cmd(dev, BLACKBIRD_API_GET_VERSION, 0, 1, &version);
if (retval < 0) {
dprintk(0, "ERROR: Firmware get encoder version failed!\n");
return -1;
@@ -517,25 +816,36 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
blackbird_codec_settings(dev);
msleep(1);
- //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
- //blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180);
- blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
+ blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_CAPTURE_LINES, 2, 0,
+ BLACKBIRD_FIELD1_SAA7115,
+ BLACKBIRD_FIELD1_SAA7115
+ );
+
+ /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */
+ blackbird_api_cmd(dev, BLACKBIRD_API_SET_CUSTOM_DATA, 12, 0,
+ BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- blackbird_api_cmd(dev, IVTV_API_INITIALIZE_INPUT, 0, 0); /* initialize the video input */
+ blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); /* initialize the video input */
msleep(1);
- blackbird_api_cmd(dev, IVTV_API_MUTE_VIDEO, 1, 0, 0);
+ blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE);
msleep(1);
- blackbird_api_cmd(dev, IVTV_API_MUTE_AUDIO, 1, 0, 0);
+ blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
msleep(1);
- blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); /* start capturing to the host interface */
- //blackbird_api_cmd(dev, IVTV_API_BEGIN_CAPTURE, 2, 0, 0, 0); /* start capturing to the host interface */
- msleep(1);
+ /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); // start capturing to the host interface */
+ blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0,
+ BLACKBIRD_MPEG_CAPTURE,
+ BLACKBIRD_RAW_BITS_NONE
+ ); /* start capturing to the host interface */
+ msleep(10);
- blackbird_api_cmd(dev, IVTV_API_REFRESH_INPUT, 0,0);
+ blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0);
return 0;
}
@@ -709,7 +1019,12 @@ static int mpeg_release(struct inode *inode, struct file *file)
{
struct cx8802_fh *fh = file->private_data;
- blackbird_api_cmd(fh->dev, IVTV_API_END_CAPTURE, 3, 0, 1, 0, 0x13);
+ /* blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */
+ blackbird_api_cmd(fh->dev, BLACKBIRD_API_END_CAPTURE, 3, 0,
+ BLACKBIRD_END_NOW,
+ BLACKBIRD_MPEG_CAPTURE,
+ BLACKBIRD_RAW_BITS_NONE
+ );
/* stop mpeg capture */
if (fh->mpegq.streaming)
@@ -908,4 +1223,5 @@ module_exit(blackbird_fini);
* Local variables:
* c-basic-offset: 8
* End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
*/
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 367624822d7..b3fb04356b7 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-cards.c,v 1.66 2005/03/04 09:12:23 kraxel Exp $
+ * $Id: cx88-cards.c,v 1.76 2005/06/08 01:28:09 mchehab Exp $
*
* device driver for Conexant 2388x based TV cards
* card-specific stuff.
@@ -35,6 +35,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_UNKNOWN] = {
.name = "UNKNOWN/GENERIC",
.tuner_type = UNSET,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 0,
@@ -52,6 +55,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_HAUPPAUGE] = {
.name = "Hauppauge WinTV 34xxx models",
.tuner_type = UNSET,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -78,6 +84,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_GDI] = {
.name = "GDI Black Gold",
.tuner_type = UNSET,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -85,7 +94,10 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_PIXELVIEW] = {
.name = "PixelView",
- .tuner_type = 5,
+ .tuner_type = TUNER_PHILIPS_PAL,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -104,7 +116,10 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_ATI_WONDER_PRO] = {
.name = "ATI TV Wonder Pro",
- .tuner_type = 44,
+ .tuner_type = TUNER_PHILIPS_4IN1,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT | TDA9887_INTERCARRIER,
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -122,7 +137,10 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_WINFAST2000XP_EXPERT] = {
.name = "Leadtek Winfast 2000XP Expert",
- .tuner_type = 44,
+ .tuner_type = TUNER_PHILIPS_4IN1,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -156,7 +174,10 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_AVERTV_303] = {
.name = "AverTV Studio 303 (M126)",
- .tuner_type = 38,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -179,7 +200,10 @@ struct cx88_board cx88_boards[] = {
// added gpio values thanks to Michal
// values for PAL from DScaler
.name = "MSI TV-@nywhere Master",
- .tuner_type = 33,
+ .tuner_type = TUNER_MT2032,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -206,7 +230,10 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_WINFAST_DV2000] = {
.name = "Leadtek Winfast DV2000",
- .tuner_type = 38,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -239,34 +266,40 @@ struct cx88_board cx88_boards[] = {
.gpio3 = 0x02000000,
},
},
- [CX88_BOARD_LEADTEK_PVR2000] = {
+ [CX88_BOARD_LEADTEK_PVR2000] = {
// gpio values for PAL version from regspy by DScaler
- .name = "Leadtek PVR 2000",
- .tuner_type = 38,
+ .name = "Leadtek PVR 2000",
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
- .input = {{
- .type = CX88_VMUX_TELEVISION,
- .vmux = 0,
- .gpio0 = 0x0000bde6,
- },{
- .type = CX88_VMUX_COMPOSITE1,
- .vmux = 1,
- .gpio0 = 0x0000bde6,
- },{
- .type = CX88_VMUX_SVIDEO,
- .vmux = 2,
- .gpio0 = 0x0000bde6,
- }},
- .radio = {
- .type = CX88_RADIO,
- .gpio0 = 0x0000bd62,
- },
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x0000bde2,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x0000bde6,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x0000bde6,
+ }},
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0x0000bd62,
+ },
.blackbird = 1,
- },
+ },
[CX88_BOARD_IODATA_GVVCP3PCI] = {
.name = "IODATA GV-VCP3/PCI",
.tuner_type = TUNER_ABSENT,
- .input = {{
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 0,
},{
@@ -279,7 +312,10 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_PROLINK_PLAYTVPVR] = {
.name = "Prolink PlayTV PVR",
- .tuner_type = 43,
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -301,8 +337,11 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_ASUS_PVR_416] = {
.name = "ASUS PVR-416",
- .tuner_type = 43,
- .tda9887_conf = TDA9887_PRESENT,
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -320,7 +359,10 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_MSI_TVANYWHERE] = {
.name = "MSI TV-@nywhere",
- .tuner_type = 33,
+ .tuner_type = TUNER_MT2032,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -342,6 +384,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_KWORLD_DVB_T] = {
.name = "KWorld/VStream XPert DVB-T",
.tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
@@ -358,6 +403,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1] = {
.name = "DVICO FusionHDTV DVB-T1",
.tuner_type = TUNER_ABSENT, /* No analog tuner */
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
@@ -371,7 +419,10 @@ struct cx88_board cx88_boards[] = {
},
[CX88_BOARD_KWORLD_LTV883] = {
.name = "KWorld LTV883RF",
- .tuner_type = 48,
+ .tuner_type = TUNER_TNF_8831BGFF,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -397,6 +448,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD] = {
.name = "DViCO - FusionHDTV 3 Gold",
.tuner_type = TUNER_MICROTUNE_4042FI5,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
/*
GPIO[0] resets DT3302 DTV receiver
0 - reset asserted
@@ -428,17 +482,14 @@ struct cx88_board cx88_boards[] = {
.vmux = 2,
.gpio0 = 0x0f00,
}},
-#if 0
- .ts = {
- .type = CX88_TS,
- .gpio0 = 0x00000f01, /* Hooked to tuner reset bit */
- }
-#endif
},
[CX88_BOARD_HAUPPAUGE_DVB_T1] = {
- .name = "Hauppauge Nova-T DVB-T",
+ .name = "Hauppauge Nova-T DVB-T",
.tuner_type = TUNER_ABSENT,
- .input = {{
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .input = {{
.type = CX88_VMUX_DVB,
.vmux = 0,
}},
@@ -447,6 +498,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_CONEXANT_DVB_T1] = {
.name = "Conexant DVB-T reference design",
.tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_DVB,
.vmux = 0,
@@ -456,6 +510,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_PROVIDEO_PV259] = {
.name = "Provideo PV259",
.tuner_type = TUNER_PHILIPS_FQ1216ME,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -465,6 +522,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS] = {
.name = "DVICO FusionHDTV DVB-T Plus",
.tuner_type = TUNER_ABSENT, /* No analog tuner */
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
@@ -479,6 +539,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_DNTV_LIVE_DVB_T] = {
.name = "digitalnow DNTV Live! DVB-T",
.tuner_type = TUNER_ABSENT,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
@@ -495,6 +558,9 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_PCHDTV_HD3000] = {
.name = "pcHDTV HD3000 HDTV",
.tuner_type = TUNER_THOMSON_DTT7610,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -530,8 +596,11 @@ struct cx88_board cx88_boards[] = {
[CX88_BOARD_HAUPPAUGE_ROSLYN] = {
// entry added by Kaustubh D. Bhalerao <bhalerao.1@osu.edu>
// GPIO values obtained from regspy, courtesy Sean Covel
- .name = "Hauppauge WinTV 28xxx (Roslyn) models",
- .tuner_type = UNSET,
+ .name = "Hauppauge WinTV 28xxx (Roslyn) models",
+ .tuner_type = UNSET,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -559,33 +628,37 @@ struct cx88_board cx88_boards[] = {
.blackbird = 1,
},
[CX88_BOARD_DIGITALLOGIC_MEC] = {
- /* params copied over from Leadtek PVR 2000 */
.name = "Digital-Logic MICROSPACE Entertainment Center (MEC)",
- /* not sure yet about the tuner type */
- .tuner_type = 38,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
- .gpio0 = 0x0000bde6,
+ .gpio0 = 0x00009d80,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
- .gpio0 = 0x0000bde6,
+ .gpio0 = 0x00009d76,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
- .gpio0 = 0x0000bde6,
+ .gpio0 = 0x00009d76,
}},
.radio = {
.type = CX88_RADIO,
- .gpio0 = 0x0000bd62,
+ .gpio0 = 0x00009d00,
},
.blackbird = 1,
},
[CX88_BOARD_IODATA_GVBCTV7E] = {
.name = "IODATA GV/BCTV7E",
.tuner_type = TUNER_PHILIPS_FQ1286,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
.input = {{
.type = CX88_VMUX_TELEVISION,
@@ -601,6 +674,56 @@ struct cx88_board cx88_boards[] = {
.gpio1 = 0x0000e07f,
}}
},
+ [CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO] = {
+ .name = "PixelView PlayTV Ultra Pro (Stereo)",
+ /* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = TUNER_TEA5767,
+ .tuner_addr = 0xc2>>1,
+ .radio_addr = 0xc0>>1,
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0xbf61, /* internal decoder */
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0xbf63,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0xbf63,
+ }},
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0xbf60,
+ },
+ },
+ [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = {
+ .name = "DViCO - FusionHDTV 3 Gold-T",
+ .tuner_type = TUNER_THOMSON_DTT7611,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ /* See DViCO FusionHDTV 3 Gold for GPIO documentation. */
+ .input = {{
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x0f0d,
+ },{
+ .type = CX88_VMUX_CABLE,
+ .vmux = 0,
+ .gpio0 = 0x0f05,
+ },{
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x0f00,
+ },{
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x0f00,
+ }},
+ },
};
const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
@@ -673,6 +796,10 @@ struct cx88_subid cx88_subids[] = {
.subdevice = 0xd810,
.card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD,
},{
+ .subvendor = 0x18ac,
+ .subdevice = 0xd820,
+ .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T,
+ },{
.subvendor = 0x18AC,
.subdevice = 0xDB00,
.card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1,
@@ -935,4 +1062,5 @@ EXPORT_SYMBOL(cx88_card_setup);
* Local variables:
* c-basic-offset: 8
* End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
*/
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 1ff79b5a883..c046a23537d 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-core.c,v 1.24 2005/01/19 12:01:55 kraxel Exp $
+ * $Id: cx88-core.c,v 1.28 2005/06/12 04:19:19 mchehab Exp $
*
* device driver for Conexant 2388x based TV cards
* driver core
@@ -51,12 +51,15 @@ module_param(latency,int,0444);
MODULE_PARM_DESC(latency,"pci latency timer");
static unsigned int tuner[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
+static unsigned int radio[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
static unsigned int card[] = {[0 ... (CX88_MAXBOARDS - 1)] = UNSET };
module_param_array(tuner, int, NULL, 0444);
+module_param_array(radio, int, NULL, 0444);
module_param_array(card, int, NULL, 0444);
MODULE_PARM_DESC(tuner,"tuner type");
+MODULE_PARM_DESC(radio,"radio tuner type");
MODULE_PARM_DESC(card,"card type");
static unsigned int nicam = 0;
@@ -429,7 +432,7 @@ int cx88_sram_channel_setup(struct cx88_core *core,
/* ------------------------------------------------------------------ */
/* debug helper code */
-static int cx88_risc_decode(u32 risc)
+int cx88_risc_decode(u32 risc)
{
static char *instr[16] = {
[ RISC_SYNC >> 28 ] = "sync",
@@ -736,6 +739,10 @@ static unsigned int inline norm_fsc8(struct cx88_tvnorm *norm)
{
static const unsigned int ntsc = 28636360;
static const unsigned int pal = 35468950;
+ static const unsigned int palm = 28604892;
+
+ if (norm->id & V4L2_STD_PAL_M)
+ return palm;
return (norm->id & V4L2_STD_625_50) ? pal : ntsc;
}
@@ -749,6 +756,11 @@ static unsigned int inline norm_notchfilter(struct cx88_tvnorm *norm)
static unsigned int inline norm_htotal(struct cx88_tvnorm *norm)
{
+ /* Should always be Line Draw Time / (4*FSC) */
+
+ if (norm->id & V4L2_STD_PAL_M)
+ return 909;
+
return (norm->id & V4L2_STD_625_50) ? 1135 : 910;
}
@@ -1164,8 +1176,20 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
"insmod option" : "autodetected");
core->tuner_type = tuner[core->nr];
+ core->radio_type = radio[core->nr];
if (UNSET == core->tuner_type)
core->tuner_type = cx88_boards[core->board].tuner_type;
+ if (UNSET == core->radio_type)
+ core->radio_type = cx88_boards[core->board].radio_type;
+ if (!core->tuner_addr)
+ core->tuner_addr = cx88_boards[core->board].tuner_addr;
+ if (!core->radio_addr)
+ core->radio_addr = cx88_boards[core->board].radio_addr;
+
+ printk(KERN_INFO "TV tuner %d at 0x%02x, Radio tuner %d at 0x%02x\n",
+ core->tuner_type, core->tuner_addr<<1,
+ core->radio_type, core->radio_addr<<1);
+
core->tda9887_conf = cx88_boards[core->board].tda9887_conf;
/* init hardware */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 9d15d3d5a2b..1a259c3966c 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-dvb.c,v 1.31 2005/03/07 15:58:05 kraxel Exp $
+ * $Id: cx88-dvb.c,v 1.33 2005/06/12 04:19:19 mchehab Exp $
*
* device driver for Conexant 2388x based TV cards
* MPEG Transport Stream (DVB) routines
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 0725b1288f4..e20adefcfc6 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -1,5 +1,5 @@
/*
- $Id: cx88-i2c.c,v 1.20 2005/02/15 15:59:35 kraxel Exp $
+ $Id: cx88-i2c.c,v 1.23 2005/06/12 04:19:19 mchehab Exp $
cx88-i2c.c -- all the i2c code is here
@@ -91,6 +91,7 @@ static int cx8800_bit_getsda(void *data)
static int attach_inform(struct i2c_client *client)
{
+ struct tuner_addr tun_addr;
struct cx88_core *core = i2c_get_adapdata(client->adapter);
dprintk(1, "i2c attach [addr=0x%x,client=%s]\n",
@@ -98,8 +99,19 @@ static int attach_inform(struct i2c_client *client)
if (!client->driver->command)
return 0;
- if (core->tuner_type != UNSET)
- client->driver->command(client, TUNER_SET_TYPE, &core->tuner_type);
+ if (core->radio_type != UNSET) {
+ tun_addr.v4l2_tuner = V4L2_TUNER_RADIO;
+ tun_addr.type = core->radio_type;
+ tun_addr.addr = core->radio_addr;
+ client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr);
+ }
+ if (core->tuner_type != UNSET) {
+ tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV;
+ tun_addr.type = core->tuner_type;
+ tun_addr.addr = core->tuner_addr;
+ client->driver->command(client,TUNER_SET_TYPE_ADDR, &tun_addr);
+ }
+
if (core->tda9887_conf)
client->driver->command(client, TDA9887_SET_CONFIG, &core->tda9887_conf);
return 0;
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index af6ad8cdbdb..dc0dcf249aa 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-input.c,v 1.9 2005/03/04 09:12:23 kraxel Exp $
+ * $Id: cx88-input.c,v 1.11 2005/05/22 20:57:56 nsh Exp $
*
* Device driver for GPIO attached remote control interfaces
* on Conexant 2388x based TV/DVB cards.
@@ -235,6 +235,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
/* detect & configure */
switch (core->board) {
case CX88_BOARD_DNTV_LIVE_DVB_T:
+ case CX88_BOARD_KWORLD_DVB_T:
ir_codes = ir_codes_dntv_live_dvb_t;
ir->gpio_addr = MO_GP1_IO;
ir->mask_keycode = 0x1f;
@@ -261,7 +262,15 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
ir->mask_keydown = 0x02;
ir->polling = 5; // ms
break;
+ case CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO:
+ ir_codes = ir_codes_pixelview;
+ ir->gpio_addr = MO_GP1_IO;
+ ir->mask_keycode = 0x1f;
+ ir->mask_keyup = 0x80;
+ ir->polling = 1; // ms
+ break;
}
+
if (NULL == ir_codes) {
kfree(ir);
return -ENODEV;
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 07aae1899e1..9ade2ae91e9 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $
+ * $Id: cx88-mpeg.c,v 1.26 2005/06/03 13:31:51 mchehab Exp $
*
* Support for the mpeg transport stream transfers
* PCI function #2 of the cx2388x.
@@ -55,7 +55,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
{
struct cx88_core *core = dev->core;
- dprintk(1, "cx8802_start_mpegport_dma %d\n", buf->vb.width);
+ dprintk(0, "cx8802_start_dma %d\n", buf->vb.width);
/* setup fifo + format */
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -100,18 +100,21 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
q->count = 1;
/* enable irqs */
+ dprintk( 0, "setting the interrupt mask\n" );
cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
- cx_write(MO_TS_INTMSK, 0x1f0011);
+ cx_set(MO_TS_INTMSK, 0x1f0011);
+ //cx_write(MO_TS_INTMSK, 0x0f0011);
/* start dma */
- cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */
- cx_write(MO_TS_DMACNTRL, 0x11);
+ cx_set(MO_DEV_CNTRL2, (1<<5));
+ cx_set(MO_TS_DMACNTRL, 0x11);
return 0;
}
static int cx8802_stop_dma(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
+ dprintk( 0, "cx8802_stop_dma\n" );
/* stop dma */
cx_clear(MO_TS_DMACNTRL, 0x11);
@@ -131,8 +134,12 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
struct cx88_buffer *buf;
struct list_head *item;
+ dprintk( 0, "cx8802_restart_queue\n" );
if (list_empty(&q->active))
+ {
+ dprintk( 0, "cx8802_restart_queue: queue is empty\n" );
return 0;
+ }
buf = list_entry(q->active.next, struct cx88_buffer, vb.queue);
dprintk(2,"restart_queue [%p/%d]: restart dma\n",
@@ -182,27 +189,32 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
struct cx88_buffer *prev;
struct cx88_dmaqueue *q = &dev->mpegq;
+ dprintk( 1, "cx8802_buf_queue\n" );
/* add jump to stopper */
buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
if (list_empty(&q->active)) {
+ dprintk( 0, "queue is empty - first active\n" );
list_add_tail(&buf->vb.queue,&q->active);
cx8802_start_dma(dev, q, buf);
buf->vb.state = STATE_ACTIVE;
buf->count = q->count++;
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(2,"[%p/%d] %s - first active\n",
+ dprintk(0,"[%p/%d] %s - first active\n",
buf, buf->vb.i, __FUNCTION__);
+ //udelay(100);
} else {
+ dprintk( 1, "queue is not empty - append to active\n" );
prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
list_add_tail(&buf->vb.queue,&q->active);
buf->vb.state = STATE_ACTIVE;
buf->count = q->count++;
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- dprintk(2,"[%p/%d] %s - append to active\n",
+ dprintk( 1, "[%p/%d] %s - append to active\n",
buf, buf->vb.i, __FUNCTION__);
+ //udelay(100);
}
}
@@ -224,7 +236,10 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart)
buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
}
if (restart)
+ {
+ dprintk(0, "restarting queue\n" );
cx8802_restart_queue(dev,q);
+ }
spin_unlock_irqrestore(&dev->slock,flags);
}
@@ -232,6 +247,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev)
{
struct cx88_dmaqueue *q = &dev->mpegq;
+ dprintk( 1, "cx8802_cancel_buffers" );
del_timer_sync(&q->timeout);
cx8802_stop_dma(dev);
do_cancel_buffers(dev,"cancel",0);
@@ -241,7 +257,7 @@ static void cx8802_timeout(unsigned long data)
{
struct cx8802_dev *dev = (struct cx8802_dev*)data;
- dprintk(1, "%s\n",__FUNCTION__);
+ dprintk(0, "%s\n",__FUNCTION__);
if (debug)
cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]);
@@ -254,12 +270,17 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
struct cx88_core *core = dev->core;
u32 status, mask, count;
+ dprintk( 1, "cx8802_mpeg_irq\n" );
status = cx_read(MO_TS_INTSTAT);
mask = cx_read(MO_TS_INTMSK);
if (0 == (status & mask))
return;
cx_write(MO_TS_INTSTAT, status);
+#if 0
+ cx88_print_irqbits(core->name, "irq mpeg ",
+ cx88_mpeg_irqs, status, mask);
+#endif
if (debug || (status & mask & ~0xff))
cx88_print_irqbits(core->name, "irq mpeg ",
cx88_mpeg_irqs, status, mask);
@@ -273,6 +294,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
/* risc1 y */
if (status & 0x01) {
+ dprintk( 1, "wake up\n" );
spin_lock(&dev->slock);
count = cx_read(MO_TS_GPCNT);
cx88_wakeup(dev->core, &dev->mpegq, count);
@@ -288,6 +310,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
/* other general errors */
if (status & 0x1f0100) {
+ dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 );
spin_lock(&dev->slock);
cx8802_stop_dma(dev);
cx8802_restart_queue(dev,&dev->mpegq);
@@ -295,6 +318,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev)
}
}
+#define MAX_IRQ_LOOP 10
+
static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
{
struct cx8802_dev *dev = dev_id;
@@ -302,10 +327,13 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
u32 status;
int loop, handled = 0;
- for (loop = 0; loop < 10; loop++) {
+ for (loop = 0; loop < MAX_IRQ_LOOP; loop++) {
status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04);
if (0 == status)
goto out;
+ dprintk( 1, "cx8802_irq\n" );
+ dprintk( 1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP );
+ dprintk( 1, " status: %d\n", status );
handled = 1;
cx_write(MO_PCI_INTSTAT, status);
@@ -314,7 +342,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs)
if (status & 0x04)
cx8802_mpeg_irq(dev);
};
- if (10 == loop) {
+ if (MAX_IRQ_LOOP == loop) {
+ dprintk( 0, "clearing mask\n" );
printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n",
core->name);
cx_write(MO_PCI_INTMSK,0);
@@ -378,6 +407,7 @@ int cx8802_init_common(struct cx8802_dev *dev)
void cx8802_fini_common(struct cx8802_dev *dev)
{
+ dprintk( 2, "cx8802_fini_common\n" );
cx8802_stop_dma(dev);
pci_disable_device(dev->pci);
@@ -399,6 +429,7 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state)
/* stop mpeg dma */
spin_lock(&dev->slock);
if (!list_empty(&dev->mpegq.active)) {
+ dprintk( 2, "suspend\n" );
printk("%s: suspend mpeg\n", core->name);
cx8802_stop_dma(dev);
del_timer(&dev->mpegq.timeout);
@@ -463,4 +494,5 @@ EXPORT_SYMBOL(cx8802_resume_common);
* Local variables:
* c-basic-offset: 8
* End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
*/
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 8638ce57d84..63ad33f5818 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -1,5 +1,5 @@
/*
- $Id: cx88-reg.h,v 1.6 2004/10/13 10:39:00 kraxel Exp $
+ $Id: cx88-reg.h,v 1.7 2005/06/03 13:31:51 mchehab Exp $
cx88x-hw.h - CX2388x register offsets
@@ -397,6 +397,7 @@
#define AUD_RATE_ADJ4 0x3205e4
#define AUD_RATE_ADJ5 0x3205e8
#define AUD_APB_IN_RATE_ADJ 0x3205ec
+#define AUD_I2SCNTL 0x3205ec
#define AUD_PHASE_FIX_CTL 0x3205f0
#define AUD_PLL_PRESCALE 0x320600
#define AUD_PLL_DDS 0x320604
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index f2a9475a2fe..46d78b1dc9b 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -1,5 +1,5 @@
/*
- $Id: cx88-tvaudio.c,v 1.34 2005/03/07 16:10:51 kraxel Exp $
+ $Id: cx88-tvaudio.c,v 1.36 2005/06/05 05:53:45 mchehab Exp $
cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
@@ -127,7 +127,8 @@ static void set_audio_start(struct cx88_core *core,
cx_write(AUD_VOL_CTL, (1 << 6));
// increase level of input by 12dB
- cx_write(AUD_AFE_12DB_EN, 0x0001);
+// cx_write(AUD_AFE_12DB_EN, 0x0001);
+ cx_write(AUD_AFE_12DB_EN, 0x0000);
// start programming
cx_write(AUD_CTL, 0x0000);
@@ -143,9 +144,15 @@ static void set_audio_finish(struct cx88_core *core)
u32 volume;
if (cx88_boards[core->board].blackbird) {
+ // sets sound input from external adc
+ cx_set(AUD_CTL, EN_I2SIN_ENABLE);
+ //cx_write(AUD_I2SINPUTCNTL, 0);
+ cx_write(AUD_I2SINPUTCNTL, 4);
+ cx_write(AUD_BAUDRATE, 1);
// 'pass-thru mode': this enables the i2s output to the mpeg encoder
- cx_set(AUD_CTL, 0x2000);
+ cx_set(AUD_CTL, EN_I2SOUT_ENABLE);
cx_write(AUD_I2SOUTPUTCNTL, 1);
+ cx_write(AUD_I2SCNTL, 0);
//cx_write(AUD_APB_IN_RATE_ADJ, 0);
}
@@ -707,50 +714,65 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
set_audio_finish(core);
}
-static void set_audio_standard_FM(struct cx88_core *core)
+static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph)
{
-#if 0 /* FIXME */
- switch (dev->audio_properties.FM_deemphasis)
- {
- case WW_FM_DEEMPH_50:
- //Set De-emphasis filter coefficients for 50 usec
- cx_write(AUD_DEEMPH0_G0, 0x0C45);
- cx_write(AUD_DEEMPH0_A0, 0x6262);
- cx_write(AUD_DEEMPH0_B0, 0x1C29);
- cx_write(AUD_DEEMPH0_A1, 0x3FC66);
- cx_write(AUD_DEEMPH0_B1, 0x399A);
-
- cx_write(AUD_DEEMPH1_G0, 0x0D80);
- cx_write(AUD_DEEMPH1_A0, 0x6262);
- cx_write(AUD_DEEMPH1_B0, 0x1C29);
- cx_write(AUD_DEEMPH1_A1, 0x3FC66);
- cx_write(AUD_DEEMPH1_B1, 0x399A);
+ static const struct rlist fm_deemph_50[] = {
+ { AUD_DEEMPH0_G0, 0x0C45 },
+ { AUD_DEEMPH0_A0, 0x6262 },
+ { AUD_DEEMPH0_B0, 0x1C29 },
+ { AUD_DEEMPH0_A1, 0x3FC66},
+ { AUD_DEEMPH0_B1, 0x399A },
+
+ { AUD_DEEMPH1_G0, 0x0D80 },
+ { AUD_DEEMPH1_A0, 0x6262 },
+ { AUD_DEEMPH1_B0, 0x1C29 },
+ { AUD_DEEMPH1_A1, 0x3FC66},
+ { AUD_DEEMPH1_B1, 0x399A},
+
+ { AUD_POLYPH80SCALEFAC, 0x0003},
+ { /* end of list */ },
+ };
+ static const struct rlist fm_deemph_75[] = {
+ { AUD_DEEMPH0_G0, 0x091B },
+ { AUD_DEEMPH0_A0, 0x6B68 },
+ { AUD_DEEMPH0_B0, 0x11EC },
+ { AUD_DEEMPH0_A1, 0x3FC66},
+ { AUD_DEEMPH0_B1, 0x399A },
+
+ { AUD_DEEMPH1_G0, 0x0AA0 },
+ { AUD_DEEMPH1_A0, 0x6B68 },
+ { AUD_DEEMPH1_B0, 0x11EC },
+ { AUD_DEEMPH1_A1, 0x3FC66},
+ { AUD_DEEMPH1_B1, 0x399A},
+
+ { AUD_POLYPH80SCALEFAC, 0x0003},
+ { /* end of list */ },
+ };
- break;
+ /* It is enough to leave default values? */
+ static const struct rlist fm_no_deemph[] = {
- case WW_FM_DEEMPH_75:
- //Set De-emphasis filter coefficients for 75 usec
- cx_write(AUD_DEEMPH0_G0, 0x91B );
- cx_write(AUD_DEEMPH0_A0, 0x6B68);
- cx_write(AUD_DEEMPH0_B0, 0x11EC);
- cx_write(AUD_DEEMPH0_A1, 0x3FC66);
- cx_write(AUD_DEEMPH0_B1, 0x399A);
+ { AUD_POLYPH80SCALEFAC, 0x0003},
+ { /* end of list */ },
+ };
- cx_write(AUD_DEEMPH1_G0, 0xAA0 );
- cx_write(AUD_DEEMPH1_A0, 0x6B68);
- cx_write(AUD_DEEMPH1_B0, 0x11EC);
- cx_write(AUD_DEEMPH1_A1, 0x3FC66);
- cx_write(AUD_DEEMPH1_B1, 0x399A);
+ dprintk("%s (status: unknown)\n",__FUNCTION__);
+ set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO);
+ switch (deemph)
+ {
+ case FM_NO_DEEMPH:
+ set_audio_registers(core, fm_no_deemph);
break;
- }
-#endif
- dprintk("%s (status: unknown)\n",__FUNCTION__);
- set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO);
+ case FM_DEEMPH_50:
+ set_audio_registers(core, fm_deemph_50);
+ break;
- // AB: 10/2/01: this register is not being reset appropriately on occasion.
- cx_write(AUD_POLYPH80SCALEFAC,3);
+ case FM_DEEMPH_75:
+ set_audio_registers(core, fm_deemph_75);
+ break;
+ }
set_audio_finish(core);
}
@@ -778,7 +800,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
set_audio_standard_EIAJ(core);
break;
case WW_FM:
- set_audio_standard_FM(core);
+ set_audio_standard_FM(core,FM_NO_DEEMPH);
break;
case WW_SYSTEM_L_AM:
set_audio_standard_NICAM_L(core, 1);
@@ -1029,4 +1051,5 @@ EXPORT_SYMBOL(cx88_audio_thread);
* Local variables:
* c-basic-offset: 8
* End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
*/
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
index 0584ff47638..320d57888bb 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-vbi.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
+ * $Id: cx88-vbi.c,v 1.17 2005/06/12 04:19:19 mchehab Exp $
*/
#include <linux/kernel.h>
#include <linux/module.h>
@@ -47,8 +47,8 @@ void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f)
}
static int cx8800_start_vbi_dma(struct cx8800_dev *dev,
- struct cx88_dmaqueue *q,
- struct cx88_buffer *buf)
+ struct cx88_dmaqueue *q,
+ struct cx88_buffer *buf)
{
struct cx88_core *core = dev->core;
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index d1f5c92f0ce..e4ca7350df1 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,5 +1,5 @@
/*
- * $Id: cx88-video.c,v 1.58 2005/03/07 15:58:05 kraxel Exp $
+ * $Id: cx88-video.c,v 1.63 2005/06/12 04:19:19 mchehab Exp $
*
* device driver for Conexant 2388x based TV cards
* video4linux video interface
@@ -1187,9 +1187,24 @@ static void init_controls(struct cx8800_dev *dev)
.id = V4L2_CID_AUDIO_VOLUME,
.value = 0x3f,
};
+ static struct v4l2_control hue = {
+ .id = V4L2_CID_HUE,
+ .value = 0x80,
+ };
+ static struct v4l2_control contrast = {
+ .id = V4L2_CID_CONTRAST,
+ .value = 0x80,
+ };
+ static struct v4l2_control brightness = {
+ .id = V4L2_CID_BRIGHTNESS,
+ .value = 0x80,
+ };
set_control(dev,&mute);
set_control(dev,&volume);
+ set_control(dev,&hue);
+ set_control(dev,&contrast);
+ set_control(dev,&brightness);
}
/* ------------------------------------------------------------------ */
@@ -1336,6 +1351,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
V4L2_CAP_STREAMING |
V4L2_CAP_VBI_CAPTURE |
#if 0
+ V4L2_TUNER_CAP_LOW |
+#endif
+#if 0
V4L2_CAP_VIDEO_OVERLAY |
#endif
0;
@@ -1696,7 +1714,11 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
sizeof(cap->card));
sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
cap->version = CX88_VERSION_CODE;
- cap->capabilities = V4L2_CAP_TUNER;
+ cap->capabilities = V4L2_CAP_TUNER
+#if 0
+ | V4L2_TUNER_CAP_LOW
+#endif
+ ;
return 0;
}
case VIDIOC_G_TUNER:
@@ -1992,6 +2014,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
{
struct cx8800_dev *dev;
struct cx88_core *core;
+ struct tuner_addr tun_addr;
int err;
dev = kmalloc(sizeof(*dev),GFP_KERNEL);
@@ -2065,8 +2088,19 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
request_module("tuner");
if (core->tda9887_conf)
request_module("tda9887");
- if (core->tuner_type != UNSET)
- cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE,&core->tuner_type);
+ if (core->radio_type != UNSET) {
+ tun_addr.v4l2_tuner = V4L2_TUNER_RADIO;
+ tun_addr.type = core->radio_type;
+ tun_addr.addr = core->radio_addr;
+ cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
+ }
+ if (core->tuner_type != UNSET) {
+ tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV;
+ tun_addr.type = core->tuner_type;
+ tun_addr.addr = core->tuner_addr;
+ cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
+ }
+
if (core->tda9887_conf)
cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf);
@@ -2162,7 +2196,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
{
- struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
+ struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
/* stop video+vbi capture */
@@ -2194,7 +2228,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
static int cx8800_resume(struct pci_dev *pci_dev)
{
- struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
+ struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
struct cx88_core *core = dev->core;
if (dev->state.disabled) {
@@ -2230,8 +2264,8 @@ static struct pci_device_id cx8800_pci_tbl[] = {
{
.vendor = 0x14f1,
.device = 0x8800,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
},{
/* --- end of list --- */
}
@@ -2239,10 +2273,10 @@ static struct pci_device_id cx8800_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl);
static struct pci_driver cx8800_pci_driver = {
- .name = "cx8800",
- .id_table = cx8800_pci_tbl,
- .probe = cx8800_initdev,
- .remove = __devexit_p(cx8800_finidev),
+ .name = "cx8800",
+ .id_table = cx8800_pci_tbl,
+ .probe = cx8800_initdev,
+ .remove = __devexit_p(cx8800_finidev),
.suspend = cx8800_suspend,
.resume = cx8800_resume,
@@ -2274,4 +2308,5 @@ module_exit(cx8800_fini);
* Local variables:
* c-basic-offset: 8
* End:
+ * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
*/
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 88eaaaba5ad..867e988a5a9 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -1,5 +1,5 @@
/*
- * $Id: cx88.h,v 1.56 2005/03/04 09:12:23 kraxel Exp $
+ * $Id: cx88.h,v 1.62 2005/06/12 04:19:19 mchehab Exp $
*
* v4l2 device driver for cx2388x based TV cards
*
@@ -64,6 +64,13 @@
#define SHADOW_AUD_BAL_CTL 2
#define SHADOW_MAX 2
+/* FM Radio deemphasis type */
+enum cx88_deemph_type {
+ FM_NO_DEEMPH = 0,
+ FM_DEEMPH_50,
+ FM_DEEMPH_75
+};
+
/* ----------------------------------------------------------- */
/* tv norms */
@@ -162,6 +169,8 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_HAUPPAUGE_ROSLYN 24
#define CX88_BOARD_DIGITALLOGIC_MEC 25
#define CX88_BOARD_IODATA_GVBCTV7E 26
+#define CX88_BOARD_PIXELVIEW_PLAYTV_ULTRA_PRO 27
+#define CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T 28
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -185,6 +194,9 @@ struct cx88_input {
struct cx88_board {
char *name;
unsigned int tuner_type;
+ unsigned int radio_type;
+ unsigned char tuner_addr;
+ unsigned char radio_addr;
int tda9887_conf;
struct cx88_input input[8];
struct cx88_input radio;
@@ -255,6 +267,9 @@ struct cx88_core {
/* config info -- analog */
unsigned int board;
unsigned int tuner_type;
+ unsigned int radio_type;
+ unsigned char tuner_addr;
+ unsigned char radio_addr;
unsigned int tda9887_conf;
unsigned int has_radio;
@@ -471,6 +486,11 @@ extern void cx88_core_put(struct cx88_core *core,
/* cx88-vbi.c */
void cx8800_vbi_fmt(struct cx8800_dev *dev, struct v4l2_format *f);
+/*
+int cx8800_start_vbi_dma(struct cx8800_dev *dev,
+ struct cx88_dmaqueue *q,
+ struct cx88_buffer *buf);
+*/
int cx8800_stop_vbi_dma(struct cx8800_dev *dev);
int cx8800_restart_vbi_queue(struct cx8800_dev *dev,
struct cx88_dmaqueue *q);
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index ab6620de4b3..a565823330a 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -1,5 +1,5 @@
/*
- * $Id: ir-kbd-gpio.c,v 1.12 2005/02/22 12:28:40 kraxel Exp $
+ * $Id: ir-kbd-gpio.c,v 1.13 2005/05/15 19:01:26 mchehab Exp $
*
* Copyright (c) 2003 Gerd Knorr
* Copyright (c) 2003 Pavel Machek
@@ -114,38 +114,6 @@ static IR_KEYTAB_TYPE ir_codes_avermedia_dvbt[IR_KEYTAB_SIZE] = {
[ 0x3e ] = KEY_VOLUMEUP, // 'volume +'
};
-static IR_KEYTAB_TYPE ir_codes_pixelview[IR_KEYTAB_SIZE] = {
- [ 2 ] = KEY_KP0,
- [ 1 ] = KEY_KP1,
- [ 11 ] = KEY_KP2,
- [ 27 ] = KEY_KP3,
- [ 5 ] = KEY_KP4,
- [ 9 ] = KEY_KP5,
- [ 21 ] = KEY_KP6,
- [ 6 ] = KEY_KP7,
- [ 10 ] = KEY_KP8,
- [ 18 ] = KEY_KP9,
-
- [ 3 ] = KEY_TUNER, // TV/FM
- [ 7 ] = KEY_SEARCH, // scan
- [ 28 ] = KEY_ZOOM, // full screen
- [ 30 ] = KEY_POWER,
- [ 23 ] = KEY_VOLUMEDOWN,
- [ 31 ] = KEY_VOLUMEUP,
- [ 20 ] = KEY_CHANNELDOWN,
- [ 22 ] = KEY_CHANNELUP,
- [ 24 ] = KEY_MUTE,
-
- [ 0 ] = KEY_LIST, // source
- [ 19 ] = KEY_INFO, // loop
- [ 16 ] = KEY_LAST, // +100
- [ 13 ] = KEY_CLEAR, // reset
- [ 12 ] = BTN_RIGHT, // fun++
- [ 4 ] = BTN_LEFT, // fun--
- [ 14 ] = KEY_GOTO, // function
- [ 15 ] = KEY_STOP, // freeze
-};
-
/* Attila Kondoros <attila.kondoros@chello.hu> */
static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index 09464d624a6..b4ee9dfe6d4 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -735,7 +735,6 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout)
{
DECLARE_WAITQUEUE(wait, current);
-again:
add_wait_queue(&msp->wq, &wait);
if (!kthread_should_stop()) {
if (timeout < 0) {
@@ -751,12 +750,8 @@ again:
#endif
}
}
-
+ try_to_freeze();
remove_wait_queue(&msp->wq, &wait);
-
- if (try_to_freeze(PF_FREEZE))
- goto again;
-
return msp->restart;
}
@@ -1436,7 +1431,7 @@ static int msp_detach(struct i2c_client *client);
static int msp_probe(struct i2c_adapter *adap);
static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
-static int msp_suspend(struct device * dev, pm_message_t state, u32 level);
+static int msp_suspend(struct device * dev, u32 state, u32 level);
static int msp_resume(struct device * dev, u32 level);
static void msp_wake_thread(struct i2c_client *client);
@@ -1841,7 +1836,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
return 0;
}
-static int msp_suspend(struct device * dev, pm_message_t state, u32 level)
+static int msp_suspend(struct device * dev, u32 state, u32 level)
{
struct i2c_client *c = container_of(dev, struct i2c_client, dev);
diff --git a/drivers/media/video/msp3400.h b/drivers/media/video/msp3400.h
index d70a954e13a..023f33056a4 100644
--- a/drivers/media/video/msp3400.h
+++ b/drivers/media/video/msp3400.h
@@ -1,3 +1,7 @@
+/*
+ * $Id: msp3400.h,v 1.3 2005/06/12 04:19:19 mchehab Exp $
+ */
+
#ifndef MSP3400_H
#define MSP3400_H
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 42c2b565c9f..e6d0a18833d 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -41,16 +41,16 @@ enum saa6752hs_videoformat {
static const struct v4l2_format v4l2_format_table[] =
{
- [SAA6752HS_VF_D1] = {
- .fmt = { .pix = { .width = 720, .height = 576 }, }, },
- [SAA6752HS_VF_2_3_D1] = {
- .fmt = { .pix = { .width = 480, .height = 576 }, }, },
- [SAA6752HS_VF_1_2_D1] = {
- .fmt = { .pix = { .width = 352, .height = 576 }, }, },
- [SAA6752HS_VF_SIF] = {
- .fmt = { .pix = { .width = 352, .height = 288 }, }, },
- [SAA6752HS_VF_UNKNOWN] = {
- .fmt = { .pix = { .width = 0, .height = 0 }, }, },
+ [SAA6752HS_VF_D1] =
+ { .fmt = { .pix = { .width = 720, .height = 576 }}},
+ [SAA6752HS_VF_2_3_D1] =
+ { .fmt = { .pix = { .width = 480, .height = 576 }}},
+ [SAA6752HS_VF_1_2_D1] =
+ { .fmt = { .pix = { .width = 352, .height = 576 }}},
+ [SAA6752HS_VF_SIF] =
+ { .fmt = { .pix = { .width = 352, .height = 288 }}},
+ [SAA6752HS_VF_UNKNOWN] =
+ { .fmt = { .pix = { .width = 0, .height = 0}}},
};
struct saa6752hs_state {
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index c51eb7f078d..0c781e24c44 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -1,6 +1,6 @@
/*
- * $Id: saa7134-cards.c,v 1.54 2005/03/07 12:01:51 kraxel Exp $
+ * $Id: saa7134-cards.c,v 1.58 2005/06/07 18:05:00 nsh Exp $
*
* device driver for philips saa7134 based TV cards
* card-specific stuff.
@@ -165,7 +165,7 @@ struct saa7134_board saa7134_boards[] = {
.inputs = {{
.name = name_tv,
.vmux = 1,
- .amux = LINE2,
+ .amux = TV,
.tv = 1,
},{
.name = name_comp1,
@@ -878,7 +878,7 @@ struct saa7134_board saa7134_boards[] = {
},
[SAA7134_BOARD_MANLI_MTV002] = {
/* Ognjen Nastic <ognjen@logosoft.ba> */
- .name = "Manli MuchTV M-TV002",
+ .name = "Manli MuchTV M-TV002/Behold TV 403 FM",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL,
.inputs = {{
@@ -899,14 +899,10 @@ struct saa7134_board saa7134_boards[] = {
.name = name_radio,
.amux = LINE2,
},
- .mute = {
- .name = name_mute,
- .amux = LINE1,
- },
},
[SAA7134_BOARD_MANLI_MTV001] = {
/* Ognjen Nastic <ognjen@logosoft.ba> UNTESTED */
- .name = "Manli MuchTV M-TV001",
+ .name = "Manli MuchTV M-TV001/Behold TV 401",
.audio_clock = 0x00200000,
.tuner_type = TUNER_PHILIPS_PAL,
.inputs = {{
@@ -923,6 +919,10 @@ struct saa7134_board saa7134_boards[] = {
.amux = LINE2,
.tv = 1,
}},
+ .mute = {
+ .name = name_mute,
+ .amux = LINE1,
+ },
},
[SAA7134_BOARD_TG3000TV] = {
/* TransGear 3000TV */
@@ -1078,7 +1078,6 @@ struct saa7134_board saa7134_boards[] = {
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FM1256_IH3,
.tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x3,
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -1285,7 +1284,7 @@ struct saa7134_board saa7134_boards[] = {
.gpio =0x8000,
}
},
- [SAA7134_BOARD_AVERMEDIA_307] = {
+ [SAA7134_BOARD_AVERMEDIA_STUDIO_307] = {
/*
Nickolay V. Shmyrev <nshmyrev@yandex.ru>
Lots of thanks to Andrey Zolotarev <zolotarev_andrey@mail.ru>
@@ -1323,6 +1322,35 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x01,
},
},
+ [SAA7134_BOARD_AVERMEDIA_GO_007_FM] = {
+ .name = "Avermedia AVerTV GO 007 FM",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .gpiomask = 0x00300003,
+// .gpiomask = 0x8c240003,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x01,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE2,
+ .gpio = 0x02,
+ },{
+ .name = name_svideo,
+ .vmux = 6,
+ .amux = LINE2,
+ .gpio = 0x02,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ .gpio = 0x00300001,
+ },
+ },
[SAA7134_BOARD_AVERMEDIA_CARDBUS] = {
/* Jon Westgate <oryn@oryn.fsck.tv> */
.name = "AVerMedia Cardbus TV/Radio",
@@ -1492,7 +1520,6 @@ struct saa7134_board saa7134_boards[] = {
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_FQ1216ME,
.tda9887_conf = TDA9887_PRESENT,
- .gpiomask = 0x3,
.inputs = {{
.name = name_tv,
.vmux = 1,
@@ -1546,7 +1573,82 @@ struct saa7134_board saa7134_boards[] = {
// .gpio = 0x4000,
}},
},
-};
+ [SAA7134_BOARD_AVERMEDIA_307] = {
+ /*
+ Davydov Vladimir <vladimir@iqmedia.com>
+ */
+ .name = "Avermedia AVerTV 307",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FQ1216ME,
+ .tda9887_conf = TDA9887_PRESENT,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE1,
+ },{
+ .name = name_comp2,
+ .vmux = 3,
+ .amux = LINE1,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ }},
+ },
+ [SAA7134_BOARD_ADS_INSTANT_TV] = {
+ .name = "ADS Tech Instant TV (saa7135)",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE2,
+ },{
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ }},
+ },
+ [SAA7134_BOARD_KWORLD_VSTREAM_XPERT] = {
+ .name = "Kworld/Tevion V-Stream Xpert TV PVR7134",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_PAL_I,
+ .gpiomask = 0x0700,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x000,
+ },{
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ .gpio = 0x200, //gpio by DScaler
+ },{
+ .name = name_svideo,
+ .vmux = 0,
+ .amux = LINE1,
+ .gpio = 0x200,
+ }},
+ .radio = {
+ .name = name_radio,
+ .amux = LINE1,
+ .gpio = 0x100,
+ },
+ },
+ };
+
const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);
/* ------------------------------------------------------------------ */
@@ -1663,7 +1765,7 @@ struct pci_device_id saa7134_pci_tbl[] = {
.driver_data = SAA7134_BOARD_ASUSTeK_TVFM7134,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
- .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
.subvendor = PCI_VENDOR_ID_ASUSTEK,
.subdevice = 0x4845,
.driver_data = SAA7135_BOARD_ASUSTeK_TVFM7135,
@@ -1824,6 +1926,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x1461, /* Avermedia Technologies Inc */
.subdevice = 0x9715,
+ .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_307,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0xa70a,
.driver_data = SAA7134_BOARD_AVERMEDIA_307,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
@@ -1844,6 +1952,26 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subvendor = 0x5168,
.subdevice = 0x0306,
.driver_data = SAA7134_BOARD_FLYDVBTDUO,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x1461, /* Avermedia Technologies Inc */
+ .subdevice = 0xf31f,
+ .driver_data = SAA7134_BOARD_AVERMEDIA_GO_007_FM,
+
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
+ .subvendor = 0x1421,
+ .subdevice = 0x0350, /* PCI version */
+ .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
+
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7135,
+ .subvendor = 0x1421,
+ .subdevice = 0x0370, /* cardbus version */
+ .driver_data = SAA7134_BOARD_ADS_INSTANT_TV,
},{
/* --- boards without eeprom + subsystem ID --- */
@@ -1954,20 +2082,23 @@ int saa7134_board_init1(struct saa7134_dev *dev)
dev->has_remote = 1;
board_flyvideo(dev);
break;
- case SAA7134_BOARD_FLYTVPLATINUM_FM:
+ case SAA7134_BOARD_FLYTVPLATINUM_FM:
case SAA7134_BOARD_CINERGY400:
case SAA7134_BOARD_CINERGY600:
case SAA7134_BOARD_CINERGY600_MK3:
case SAA7134_BOARD_ECS_TVP3XP:
case SAA7134_BOARD_ECS_TVP3XP_4CB5:
case SAA7134_BOARD_MD2819:
+ case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
case SAA7134_BOARD_AVERMEDIA_305:
+ case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
case SAA7134_BOARD_AVERMEDIA_307:
+ case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
// case SAA7134_BOARD_SABRENT_SBTTVFM: /* not finished yet */
case SAA7134_BOARD_VIDEOMATE_TV_PVR:
- dev->has_remote = 1;
- break;
+ case SAA7134_BOARD_MANLI_MTV001:
+ case SAA7134_BOARD_MANLI_MTV002:
case SAA7134_BOARD_AVACSSMARTTV:
dev->has_remote = 1;
break;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index d506cafba8f..f61ed1849a2 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-core.c,v 1.28 2005/02/22 09:56:29 kraxel Exp $
+ * $Id: saa7134-core.c,v 1.30 2005/05/22 19:23:39 nsh Exp $
*
* device driver for philips saa7134 based TV cards
* driver core
@@ -316,7 +316,7 @@ unsigned long saa7134_buffer_base(struct saa7134_buf *buf)
int saa7134_pgtable_alloc(struct pci_dev *pci, struct saa7134_pgtable *pt)
{
- u32 *cpu;
+ __le32 *cpu;
dma_addr_t dma_addr;
cpu = pci_alloc_consistent(pci, SAA7134_PGTABLE_SIZE, &dma_addr);
@@ -332,7 +332,7 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
struct scatterlist *list, unsigned int length,
unsigned int startpage)
{
- u32 *ptr;
+ __le32 *ptr;
unsigned int i,p;
BUG_ON(NULL == pt || NULL == pt->cpu);
@@ -340,7 +340,7 @@ int saa7134_pgtable_build(struct pci_dev *pci, struct saa7134_pgtable *pt,
ptr = pt->cpu + startpage;
for (i = 0; i < length; i++, list++)
for (p = 0; p * 4096 < list->length; p++, ptr++)
- *ptr = sg_dma_address(list) - list->offset;
+ *ptr = cpu_to_le32(sg_dma_address(list) - list->offset);
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index c2873ae029f..aa8e2cf62d5 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-dvb.c,v 1.12 2005/02/18 12:28:29 kraxel Exp $
+ * $Id: saa7134-dvb.c,v 1.13 2005/06/12 04:19:19 mchehab Exp $
*
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
*
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index fa135733690..c85348d0239 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-empress.c,v 1.10 2005/02/03 10:24:33 kraxel Exp $
+ * $Id: saa7134-empress.c,v 1.11 2005/05/22 19:23:39 nsh Exp $
*
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
*
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 702bb63d981..b6f002e8421 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-i2c.c,v 1.10 2005/01/24 17:37:23 kraxel Exp $
+ * $Id: saa7134-i2c.c,v 1.11 2005/06/12 01:36:14 mchehab Exp $
*
* device driver for philips saa7134 based TV cards
* i2c interface support
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index ca50cf531f2..aba2b9de60d 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-input.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
+ * $Id: saa7134-input.c,v 1.19 2005/06/07 18:02:26 nsh Exp $
*
* handle saa7134 IR remotes via linux kernel input layer.
*
@@ -308,6 +308,102 @@ static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
[ 32 ] = KEY_LANGUAGE,
[ 33 ] = KEY_SLEEP,
};
+
+/* Michael Tokarev <mjt@tls.msk.ru>
+ http://www.corpit.ru/mjt/beholdTV/remote_control.jpg
+ keytable is used by MANLI MTV00[12] and BeholdTV 40[13] at
+ least, and probably other cards too.
+ The "ascii-art picture" below (in comments, first row
+ is the keycode in hex, and subsequent row(s) shows
+ the button labels (several variants when appropriate)
+ helps to descide which keycodes to assign to the buttons.
+ */
+static IR_KEYTAB_TYPE manli_codes[IR_KEYTAB_SIZE] = {
+
+ /* 0x1c 0x12 *
+ * FUNCTION POWER *
+ * FM (|) *
+ * */
+ [ 0x1c ] = KEY_RADIO, /*XXX*/
+ [ 0x12 ] = KEY_POWER,
+
+ /* 0x01 0x02 0x03 *
+ * 1 2 3 *
+ * *
+ * 0x04 0x05 0x06 *
+ * 4 5 6 *
+ * *
+ * 0x07 0x08 0x09 *
+ * 7 8 9 *
+ * */
+ [ 0x01 ] = KEY_KP1,
+ [ 0x02 ] = KEY_KP2,
+ [ 0x03 ] = KEY_KP3,
+ [ 0x04 ] = KEY_KP4,
+ [ 0x05 ] = KEY_KP5,
+ [ 0x06 ] = KEY_KP6,
+ [ 0x07 ] = KEY_KP7,
+ [ 0x08 ] = KEY_KP8,
+ [ 0x09 ] = KEY_KP9,
+
+ /* 0x0a 0x00 0x17 *
+ * RECALL 0 +100 *
+ * PLUS *
+ * */
+ [ 0x0a ] = KEY_AGAIN, /*XXX KEY_REWIND? */
+ [ 0x00 ] = KEY_KP0,
+ [ 0x17 ] = KEY_DIGITS, /*XXX*/
+
+ /* 0x14 0x10 *
+ * MENU INFO *
+ * OSD */
+ [ 0x14 ] = KEY_MENU,
+ [ 0x10 ] = KEY_INFO,
+
+ /* 0x0b *
+ * Up *
+ * *
+ * 0x18 0x16 0x0c *
+ * Left Ok Right *
+ * *
+ * 0x015 *
+ * Down *
+ * */
+ [ 0x0b ] = KEY_UP, /*XXX KEY_SCROLLUP? */
+ [ 0x18 ] = KEY_LEFT, /*XXX KEY_BACK? */
+ [ 0x16 ] = KEY_OK, /*XXX KEY_SELECT? KEY_ENTER? */
+ [ 0x0c ] = KEY_RIGHT, /*XXX KEY_FORWARD? */
+ [ 0x15 ] = KEY_DOWN, /*XXX KEY_SCROLLDOWN? */
+
+ /* 0x11 0x0d *
+ * TV/AV MODE *
+ * SOURCE STEREO *
+ * */
+ [ 0x11 ] = KEY_TV, /*XXX*/
+ [ 0x0d ] = KEY_MODE, /*XXX there's no KEY_STEREO */
+
+ /* 0x0f 0x1b 0x1a *
+ * AUDIO Vol+ Chan+ *
+ * TIMESHIFT??? *
+ * *
+ * 0x0e 0x1f 0x1e *
+ * SLEEP Vol- Chan- *
+ * */
+ [ 0x0f ] = KEY_AUDIO,
+ [ 0x1b ] = KEY_VOLUMEUP,
+ [ 0x1a ] = KEY_CHANNELUP,
+ [ 0x0e ] = KEY_SLEEP, /*XXX maybe KEY_PAUSE */
+ [ 0x1f ] = KEY_VOLUMEDOWN,
+ [ 0x1e ] = KEY_CHANNELDOWN,
+
+ /* 0x13 0x19 *
+ * MUTE SNAPSHOT*
+ * */
+ [ 0x13 ] = KEY_MUTE,
+ [ 0x19 ] = KEY_RECORD, /*XXX*/
+
+ // 0x1d unused ?
+};
/* ---------------------------------------------------------------------- */
static int build_key(struct saa7134_dev *dev)
@@ -379,7 +475,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_FLYVIDEO2000:
case SAA7134_BOARD_FLYVIDEO3000:
- case SAA7134_BOARD_FLYTVPLATINUM_FM:
+ case SAA7134_BOARD_FLYTVPLATINUM_FM:
ir_codes = flyvideo_codes;
mask_keycode = 0xEC00000;
mask_keydown = 0x0040000;
@@ -405,8 +501,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
polling = 50; // ms
break;
case SAA7134_BOARD_MD2819:
+ case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
case SAA7134_BOARD_AVERMEDIA_305:
case SAA7134_BOARD_AVERMEDIA_307:
+ case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
+ case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
+ case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
ir_codes = md2819_codes;
mask_keycode = 0x0007C8;
mask_keydown = 0x000010;
@@ -415,6 +515,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
break;
+ case SAA7134_BOARD_MANLI_MTV001:
+ case SAA7134_BOARD_MANLI_MTV002:
+ ir_codes = manli_codes;
+ mask_keycode = 0x001f00;
+ mask_keyup = 0x004000;
+ mask_keydown = 0x002000;
+ polling = 50; // ms
+ break;
case SAA7134_BOARD_VIDEOMATE_TV_PVR:
ir_codes = videomate_tv_pvr_codes;
mask_keycode = 0x00003F;
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index 6b6a643bf1c..81732904623 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-oss.c,v 1.13 2004/12/10 12:33:39 kraxel Exp $
+ * $Id: saa7134-oss.c,v 1.14 2005/05/18 22:45:16 hhackmann Exp $
*
* device driver for philips saa7134 based TV cards
* oss dsp interface
@@ -49,7 +49,6 @@ MODULE_PARM_DESC(oss_rate,"sample rate (valid are: 32000,48000)");
static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
{
- blksize &= ~0xff;
if (blksize < 0x100)
blksize = 0x100;
if (blksize > 0x10000)
@@ -57,8 +56,6 @@ static int dsp_buffer_conf(struct saa7134_dev *dev, int blksize, int blocks)
if (blocks < 2)
blocks = 2;
- while ((blksize * blocks) & ~PAGE_MASK)
- blocks++;
if ((blksize * blocks) > 1024*1024)
blocks = 1024*1024 / blksize;
@@ -79,7 +76,7 @@ static int dsp_buffer_init(struct saa7134_dev *dev)
BUG();
videobuf_dma_init(&dev->oss.dma);
err = videobuf_dma_init_kernel(&dev->oss.dma, PCI_DMA_FROMDEVICE,
- dev->oss.bufsize >> PAGE_SHIFT);
+ (dev->oss.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
if (0 != err)
return err;
return 0;
@@ -163,10 +160,11 @@ static int dsp_rec_start(struct saa7134_dev *dev)
fmt |= 0x04;
fmt |= (TV == dev->oss.input) ? 0xc0 : 0x80;
- saa_writeb(SAA7134_NUM_SAMPLES0, (dev->oss.blksize & 0x0000ff));
- saa_writeb(SAA7134_NUM_SAMPLES1, (dev->oss.blksize & 0x00ff00) >> 8);
- saa_writeb(SAA7134_NUM_SAMPLES2, (dev->oss.blksize & 0xff0000) >> 16);
+ saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->oss.blksize - 1) & 0x0000ff));
+ saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->oss.blksize - 1) & 0x00ff00) >> 8);
+ saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->oss.blksize - 1) & 0xff0000) >> 16);
saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);
+
break;
case PCI_DEVICE_ID_PHILIPS_SAA7133:
case PCI_DEVICE_ID_PHILIPS_SAA7135:
@@ -817,7 +815,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status)
reg = SAA7134_RS_BA1(6);
} else {
/* even */
- if (0 == (dev->oss.dma_blk & 0x00))
+ if (1 == (dev->oss.dma_blk & 0x01))
reg = SAA7134_RS_BA2(6);
}
if (0 == reg) {
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index ecac13c006d..3617e7f7a41 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-tvaudio.c,v 1.22 2005/01/07 13:11:19 kraxel Exp $
+ * $Id: saa7134-tvaudio.c,v 1.25 2005/06/07 19:00:38 nsh Exp $
*
* device driver for philips saa7134 based TV cards
* tv audio decoder (fm stereo, nicam, ...)
@@ -181,7 +181,8 @@ static void tvaudio_init(struct saa7134_dev *dev)
saa_writeb(SAA7134_AUDIO_CLOCK0, clock & 0xff);
saa_writeb(SAA7134_AUDIO_CLOCK1, (clock >> 8) & 0xff);
saa_writeb(SAA7134_AUDIO_CLOCK2, (clock >> 16) & 0xff);
- saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x01);
+ // frame locked audio was reported not to be reliable
+ saa_writeb(SAA7134_AUDIO_PLL_CTRL, 0x02);
saa_writeb(SAA7134_NICAM_ERROR_LOW, 0x14);
saa_writeb(SAA7134_NICAM_ERROR_HIGH, 0x50);
@@ -250,6 +251,11 @@ static void mute_input_7134(struct saa7134_dev *dev)
saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel);
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics);
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, ocs);
+ // for oss, we need to change the clock configuration
+ if (in->amux == TV)
+ saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x00);
+ else
+ saa_andorb(SAA7134_SIF_SAMPLE_FREQ, 0x03, 0x01);
/* switch gpio-connected external audio mux */
if (0 == card(dev).gpiomask)
@@ -439,16 +445,15 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
nicam = saa_readb(SAA7134_NICAM_STATUS);
dprintk("getstereo: nicam=0x%x\n",nicam);
switch (nicam & 0x0b) {
+ case 0x08:
+ retval = V4L2_TUNER_SUB_MONO;
+ break;
case 0x09:
retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
break;
case 0x0a:
retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
break;
- case 0x08:
- default:
- retval = V4L2_TUNER_SUB_MONO;
- break;
}
break;
}
@@ -572,14 +577,14 @@ static int tvaudio_thread(void *data)
} else if (0 != dev->last_carrier) {
/* no carrier -- try last detected one as fallback */
carrier = dev->last_carrier;
- printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
+ dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
"using %d.%03d MHz [last detected]\n",
dev->name, carrier/1000, carrier%1000);
} else {
/* no carrier + no fallback -- use default */
carrier = default_carrier;
- printk(KERN_WARNING "%s/audio: audio carrier scan failed, "
+ dprintk(KERN_WARNING "%s/audio: audio carrier scan failed, "
"using %d.%03d MHz [default]\n",
dev->name, carrier/1000, carrier%1000);
}
diff --git a/drivers/media/video/saa7134/saa7134-vbi.c b/drivers/media/video/saa7134/saa7134-vbi.c
index 86954cc7c37..3c33c591cc8 100644
--- a/drivers/media/video/saa7134/saa7134-vbi.c
+++ b/drivers/media/video/saa7134/saa7134-vbi.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-vbi.c,v 1.6 2004/12/10 12:33:39 kraxel Exp $
+ * $Id: saa7134-vbi.c,v 1.7 2005/05/24 23:13:06 nsh Exp $
*
* device driver for philips saa7134 based TV cards
* video4linux video interface
@@ -60,10 +60,10 @@ static void task_init(struct saa7134_dev *dev, struct saa7134_buf *buf,
saa_writeb(SAA7134_VBI_H_START2(task), norm->h_start >> 8);
saa_writeb(SAA7134_VBI_H_STOP1(task), norm->h_stop & 0xff);
saa_writeb(SAA7134_VBI_H_STOP2(task), norm->h_stop >> 8);
- saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start & 0xff);
- saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start >> 8);
- saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop & 0xff);
- saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop >> 8);
+ saa_writeb(SAA7134_VBI_V_START1(task), norm->vbi_v_start_0 & 0xff);
+ saa_writeb(SAA7134_VBI_V_START2(task), norm->vbi_v_start_0 >> 8);
+ saa_writeb(SAA7134_VBI_V_STOP1(task), norm->vbi_v_stop_0 & 0xff);
+ saa_writeb(SAA7134_VBI_V_STOP2(task), norm->vbi_v_stop_0 >> 8);
saa_writeb(SAA7134_VBI_H_SCALE_INC1(task), VBI_SCALE & 0xff);
saa_writeb(SAA7134_VBI_H_SCALE_INC2(task), VBI_SCALE >> 8);
@@ -127,7 +127,7 @@ static int buffer_prepare(struct videobuf_queue *q,
unsigned int lines, llength, size;
int err;
- lines = norm->vbi_v_stop - norm->vbi_v_start +1;
+ lines = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
if (lines > VBI_LINE_COUNT)
lines = VBI_LINE_COUNT;
#if 1
@@ -177,7 +177,7 @@ buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
struct saa7134_dev *dev = fh->dev;
int llength,lines;
- lines = dev->tvnorm->vbi_v_stop - dev->tvnorm->vbi_v_start +1;
+ lines = dev->tvnorm->vbi_v_stop_0 - dev->tvnorm->vbi_v_start_0 +1;
#if 1
llength = VBI_LINE_LENGTH;
#else
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 5d66060026f..c0a2ee52053 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134-video.c,v 1.28 2005/02/15 15:59:35 kraxel Exp $
+ * $Id: saa7134-video.c,v 1.30 2005/06/07 19:00:38 nsh Exp $
*
* device driver for philips saa7134 based TV cards
* video4linux video interface
@@ -31,8 +31,6 @@
#include "saa7134-reg.h"
#include "saa7134.h"
-#define V4L2_I2C_CLIENTS 1
-
/* ------------------------------------------------------------------ */
static unsigned int video_debug = 0;
@@ -158,18 +156,20 @@ static struct saa7134_format formats[] = {
.h_stop = 719, \
.video_v_start = 24, \
.video_v_stop = 311, \
- .vbi_v_start = 7, \
- .vbi_v_stop = 22, \
+ .vbi_v_start_0 = 7, \
+ .vbi_v_stop_0 = 22, \
+ .vbi_v_start_1 = 319, \
.src_timing = 4
#define NORM_525_60 \
.h_start = 0, \
.h_stop = 703, \
- .video_v_start = 22, \
- .video_v_stop = 22+239, \
- .vbi_v_start = 10, /* FIXME */ \
- .vbi_v_stop = 21, /* FIXME */ \
- .src_timing = 1
+ .video_v_start = 23, \
+ .video_v_stop = 262, \
+ .vbi_v_start_0 = 10, \
+ .vbi_v_stop_0 = 21, \
+ .vbi_v_start_1 = 273, \
+ .src_timing = 7
static struct saa7134_tvnorm tvnorms[] = {
{
@@ -274,11 +274,12 @@ static struct saa7134_tvnorm tvnorms[] = {
.h_start = 0,
.h_stop = 719,
- .video_v_start = 22,
- .video_v_stop = 22+239,
- .vbi_v_start = 10, /* FIXME */
- .vbi_v_stop = 21, /* FIXME */
- .src_timing = 1,
+ .video_v_start = 23,
+ .video_v_stop = 262,
+ .vbi_v_start_0 = 10,
+ .vbi_v_stop_0 = 21,
+ .vbi_v_start_1 = 273,
+ .src_timing = 7,
.sync_control = 0x18,
.luma_control = 0x40,
@@ -335,8 +336,8 @@ static const struct v4l2_queryctrl video_ctrls[] = {
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
- .id = V4L2_CID_VFLIP,
- .name = "vertical flip",
+ .id = V4L2_CID_HFLIP,
+ .name = "Mirror",
.minimum = 0,
.maximum = 1,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -482,7 +483,7 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
dev->crop_bounds.width = norm->h_stop - norm->h_start +1;
dev->crop_defrect.width = norm->h_stop - norm->h_start +1;
- dev->crop_bounds.top = (norm->vbi_v_stop+1)*2;
+ dev->crop_bounds.top = (norm->vbi_v_stop_0+1)*2;
dev->crop_defrect.top = norm->video_v_start*2;
dev->crop_bounds.height = ((norm->id & V4L2_STD_525_60) ? 524 : 624)
- dev->crop_bounds.top;
@@ -521,22 +522,7 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
saa_writeb(SAA7134_RAW_DATA_GAIN, 0x40);
saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
-#ifdef V4L2_I2C_CLIENTS
saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
-#else
- {
- /* pass down info to the i2c chips (v4l1) */
- struct video_channel c;
- memset(&c,0,sizeof(c));
- c.channel = dev->ctl_input;
- c.norm = VIDEO_MODE_PAL;
- if (norm->id & V4L2_STD_NTSC)
- c.norm = VIDEO_MODE_NTSC;
- if (norm->id & V4L2_STD_SECAM)
- c.norm = VIDEO_MODE_SECAM;
- saa7134_i2c_call_clients(dev,VIDIOCSCHAN,&c);
- }
-#endif
}
static void video_mux(struct saa7134_dev *dev, int input)
@@ -1064,7 +1050,7 @@ static int get_control(struct saa7134_dev *dev, struct v4l2_control *c)
case V4L2_CID_PRIVATE_INVERT:
c->value = dev->ctl_invert;
break;
- case V4L2_CID_VFLIP:
+ case V4L2_CID_HFLIP:
c->value = dev->ctl_mirror;
break;
case V4L2_CID_PRIVATE_Y_EVEN:
@@ -1139,7 +1125,7 @@ static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
break;
- case V4L2_CID_VFLIP:
+ case V4L2_CID_HFLIP:
dev->ctl_mirror = c->value;
restart_overlay = 1;
break;
@@ -1407,9 +1393,9 @@ static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
f->fmt.vbi.offset = 64 * 4;
- f->fmt.vbi.start[0] = norm->vbi_v_start;
- f->fmt.vbi.count[0] = norm->vbi_v_stop - norm->vbi_v_start +1;
- f->fmt.vbi.start[1] = norm->video_v_stop + norm->vbi_v_start +1;
+ f->fmt.vbi.start[0] = norm->vbi_v_start_0;
+ f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
+ f->fmt.vbi.start[1] = norm->vbi_v_start_1;
f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
@@ -1880,11 +1866,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
down(&dev->lock);
dev->ctl_freq = f->frequency;
-#ifdef V4L2_I2C_CLIENTS
+
saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
-#else
- saa7134_i2c_call_clients(dev,VIDIOCSFREQ,&dev->ctl_freq);
-#endif
+
saa7134_tvaudio_do_scan(dev);
up(&dev->lock);
return 0;
@@ -2139,16 +2123,19 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
t->rangelow = (int)(65*16);
t->rangehigh = (int)(108*16);
-#ifdef V4L2_I2C_CLIENTS
- saa7134_i2c_call_clients(dev,VIDIOC_G_TUNER,t);
-#else
- {
- struct video_tuner vt;
- memset(&vt,0,sizeof(vt));
- saa7134_i2c_call_clients(dev,VIDIOCGTUNER,&vt);
- t->signal = vt.signal;
- }
-#endif
+ saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+
+ return 0;
+ }
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *t = arg;
+
+ if (0 != t->index)
+ return -EINVAL;
+
+ saa7134_i2c_call_clients(dev,VIDIOC_S_TUNER,t);
+
return 0;
}
case VIDIOC_ENUMINPUT:
@@ -2182,7 +2169,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
return 0;
}
case VIDIOC_S_AUDIO:
- case VIDIOC_S_TUNER:
case VIDIOC_S_INPUT:
case VIDIOC_S_STD:
return 0;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index ac90a985323..d6b1c0d4d0f 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -1,5 +1,5 @@
/*
- * $Id: saa7134.h,v 1.38 2005/03/07 12:01:51 kraxel Exp $
+ * $Id: saa7134.h,v 1.41 2005/06/07 18:02:26 nsh Exp $
*
* v4l2 device driver for philips saa7134 based TV cards
*
@@ -21,7 +21,7 @@
*/
#include <linux/version.h>
-#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,12)
+#define SAA7134_VERSION_CODE KERNEL_VERSION(0,2,13)
#include <linux/pci.h>
#include <linux/i2c.h>
@@ -91,9 +91,10 @@ struct saa7134_tvnorm {
unsigned int h_stop;
unsigned int video_v_start;
unsigned int video_v_stop;
- unsigned int vbi_v_start;
- unsigned int vbi_v_stop;
+ unsigned int vbi_v_start_0;
+ unsigned int vbi_v_stop_0;
unsigned int src_timing;
+ unsigned int vbi_v_start_1;
};
struct saa7134_tvaudio {
@@ -167,7 +168,7 @@ struct saa7134_format {
#define SAA7134_BOARD_SABRENT_SBTTVFM 42
#define SAA7134_BOARD_ZOLID_XPERT_TV7134 43
#define SAA7134_BOARD_EMPIRE_PCI_TV_RADIO_LE 44
-#define SAA7134_BOARD_AVERMEDIA_307 45
+#define SAA7134_BOARD_AVERMEDIA_STUDIO_307 45
#define SAA7134_BOARD_AVERMEDIA_CARDBUS 46
#define SAA7134_BOARD_CINERGY400_CARDBUS 47
#define SAA7134_BOARD_CINERGY600_MK3 48
@@ -178,6 +179,10 @@ struct saa7134_format {
#define SAA7135_BOARD_ASUSTeK_TVFM7135 53
#define SAA7134_BOARD_FLYTVPLATINUM_FM 54
#define SAA7134_BOARD_FLYDVBTDUO 55
+#define SAA7134_BOARD_AVERMEDIA_307 56
+#define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57
+#define SAA7134_BOARD_ADS_INSTANT_TV 58
+#define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59
#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8
@@ -241,7 +246,7 @@ struct saa7134_dma;
/* saa7134 page table */
struct saa7134_pgtable {
unsigned int size;
- u32 *cpu;
+ __le32 *cpu;
dma_addr_t dma;
};
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 7e6e6dd966a..39773633cc3 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -53,6 +53,7 @@ struct tda9887 {
unsigned int config;
unsigned int pinnacle_id;
unsigned int using_v4l2;
+ unsigned int radio_mode;
};
struct tvnorm {
@@ -212,12 +213,22 @@ static struct tvnorm tvnorms[] = {
}
};
-static struct tvnorm radio = {
- .name = "radio",
+static struct tvnorm radio_stereo = {
+ .name = "Radio Stereo",
+ .b = ( cFmRadio |
+ cQSS ),
+ .c = ( cDeemphasisOFF |
+ cAudioGain6 ),
+ .e = ( cAudioIF_5_5 |
+ cRadioIF_38_90 ),
+};
+
+static struct tvnorm radio_mono = {
+ .name = "Radio Mono",
.b = ( cFmRadio |
cQSS ),
.c = ( cDeemphasisON |
- cDeemphasis50 ),
+ cDeemphasis50),
.e = ( cAudioIF_5_5 |
cRadioIF_38_90 ),
};
@@ -354,7 +365,10 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf)
int i;
if (t->radio) {
- norm = &radio;
+ if (t->radio_mode == V4L2_TUNER_MODE_MONO)
+ norm = &radio_mono;
+ else
+ norm = &radio_stereo;
} else {
for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
if (tvnorms[i].std & t->std) {
@@ -545,11 +559,14 @@ static int tda9887_configure(struct tda9887 *t)
memset(buf,0,sizeof(buf));
tda9887_set_tvnorm(t,buf);
+
buf[1] |= cOutputPort1Inactive;
buf[1] |= cOutputPort2Inactive;
+
if (UNSET != t->pinnacle_id) {
tda9887_set_pinnacle(t,buf);
}
+
tda9887_set_config(t,buf);
tda9887_set_insmod(t,buf);
@@ -592,9 +609,12 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind)
if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL)))
return -ENOMEM;
memset(t,0,sizeof(*t));
+
t->client = client_template;
t->std = 0;
t->pinnacle_id = UNSET;
+ t->radio_mode = V4L2_TUNER_MODE_STEREO;
+
i2c_set_clientdata(&t->client, t);
i2c_attach_client(&t->client);
@@ -733,6 +753,16 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
}
break;
}
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner* tuner = arg;
+
+ if (t->radio) {
+ t->radio_mode = tuner->audmode;
+ tda9887_configure (t);
+ }
+ break;
+ }
default:
/* nothing */
break;
@@ -740,7 +770,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
return 0;
}
-static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level)
+static int tda9887_suspend(struct device * dev, u32 state, u32 level)
{
dprintk("tda9887: suspend\n");
return 0;
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 81882ddab85..eaabfc85870 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,5 +1,5 @@
/*
- * $Id: tuner-core.c,v 1.5 2005/02/15 15:59:35 kraxel Exp $
+ * $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $
*
* i2c tv tuner chip device driver
* core core, i.e. kernel interfaces, registering and so on
@@ -23,6 +23,11 @@
#include <media/tuner.h>
#include <media/audiochip.h>
+/*
+ * comment line bellow to return to old behavor, where only one I2C device is supported
+ */
+#define CONFIG_TUNER_MULTI_I2C /**/
+
#define UNSET (-1U)
/* standard i2c insmod options */
@@ -53,13 +58,16 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
MODULE_LICENSE("GPL");
static int this_adap;
+#ifdef CONFIG_TUNER_MULTI_I2C
+static unsigned short first_tuner, tv_tuner, radio_tuner;
+#endif
static struct i2c_driver driver;
static struct i2c_client client_template;
/* ---------------------------------------------------------------------- */
-// Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz
+/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */
static void set_tv_freq(struct i2c_client *c, unsigned int freq)
{
struct tuner *t = i2c_get_clientdata(c);
@@ -73,14 +81,26 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
return;
}
if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
- /* FIXME: better do that chip-specific, but
- right now we don't have that in the config
- struct and this way is still better than no
- check at all */
- tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
- freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
- return;
+
+ if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
+ /* V4L2_TUNER_CAP_LOW frequency */
+
+ tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n");
+
+ t->tv_freq(c,freq>>10);
+
+ return;
+ } else {
+ /* FIXME: better do that chip-specific, but
+ right now we don't have that in the config
+ struct and this way is still better than no
+ check at all */
+ tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n",
+ freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
+ return;
+ }
}
+ tuner_dbg("62.5 Khz freq step selected for TV.\n");
t->tv_freq(c,freq);
}
@@ -97,11 +117,29 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq)
return;
}
if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
- tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
+ if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) {
+ /* V4L2_TUNER_CAP_LOW frequency */
+ if (t->type == TUNER_TEA5767) {
+ tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
+ t->radio_freq(c,freq>>10);
+ return;
+ }
+
+ tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n");
+
+ tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000);
+
+ t->radio_freq(c,freq>>10);
+ return;
+
+ } else {
+ tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n",
freq/16,freq%16*100/16,
- radio_range[0],radio_range[1]);
- return;
+ radio_range[0],radio_range[1]);
+ return;
+ }
}
+ tuner_dbg("62.5 Khz freq step selected for Radio.\n");
t->radio_freq(c,freq);
}
@@ -129,8 +167,9 @@ static void set_type(struct i2c_client *c, unsigned int type)
{
struct tuner *t = i2c_get_clientdata(c);
+ tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type);
/* sanity check */
- if (type == UNSET || type == TUNER_ABSENT)
+ if (type == UNSET || type == TUNER_ABSENT)
return;
if (type >= tuner_count)
return;
@@ -145,6 +184,7 @@ static void set_type(struct i2c_client *c, unsigned int type)
return;
t->initialized = 1;
+
t->type = type;
switch (t->type) {
case TUNER_MT2032:
@@ -159,6 +199,53 @@ static void set_type(struct i2c_client *c, unsigned int type)
}
}
+#ifdef CONFIG_TUNER_MULTI_I2C
+#define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \
+ return 0; } else \
+ tuner_info ("Cmd %s accepted to "tun"\n",cmd);
+#define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \
+ CHECK_ADDR(radio_tuner,cmd,"radio") } else \
+ { CHECK_ADDR(tv_tuner,cmd,"TV"); }
+#else
+#define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd);
+#define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd);
+#endif
+
+#ifdef CONFIG_TUNER_MULTI_I2C
+
+static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr)
+{
+ /* ADDR_UNSET defaults to first available tuner */
+ if ( tun_addr->addr == ADDR_UNSET ) {
+ if (first_tuner != c->addr)
+ return;
+ switch (tun_addr->v4l2_tuner) {
+ case V4L2_TUNER_RADIO:
+ radio_tuner=c->addr;
+ break;
+ default:
+ tv_tuner=c->addr;
+ break;
+ }
+ } else {
+ /* Sets tuner to its configured value */
+ switch (tun_addr->v4l2_tuner) {
+ case V4L2_TUNER_RADIO:
+ radio_tuner=tun_addr->addr;
+ if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type);
+ return;
+ default:
+ tv_tuner=tun_addr->addr;
+ if ( tun_addr->addr == c->addr ) set_type(c,tun_addr->type);
+ return;
+ }
+ }
+ set_type(c,tun_addr->type);
+}
+#else
+#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type)
+#endif
+
static char pal[] = "-";
module_param_string(pal, pal, sizeof(pal), 0644);
@@ -197,8 +284,17 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
{
struct tuner *t;
+#ifndef CONFIG_TUNER_MULTI_I2C
if (this_adap > 0)
return -1;
+#else
+ /* by default, first I2C card is both tv and radio tuner */
+ if (this_adap == 0) {
+ first_tuner = addr;
+ tv_tuner = addr;
+ radio_tuner = addr;
+ }
+#endif
this_adap++;
client_template.adapter = adap;
@@ -211,11 +307,12 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
memcpy(&t->i2c,&client_template,sizeof(struct i2c_client));
i2c_set_clientdata(&t->i2c, t);
t->type = UNSET;
- t->radio_if2 = 10700*1000; // 10.7MHz - FM radio
+ t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */
i2c_attach_client(&t->i2c);
tuner_info("chip found @ 0x%x (%s)\n",
addr << 1, adap->name);
+
set_type(&t->i2c, t->type);
return 0;
}
@@ -228,6 +325,12 @@ static int tuner_probe(struct i2c_adapter *adap)
}
this_adap = 0;
+#ifdef CONFIG_TUNER_MULTI_I2C
+ first_tuner = 0;
+ tv_tuner = 0;
+ radio_tuner = 0;
+#endif
+
if (adap->class & I2C_CLASS_TV_ANALOG)
return i2c_probe(adap, &addr_data, tuner_attach);
return 0;
@@ -236,8 +339,14 @@ static int tuner_probe(struct i2c_adapter *adap)
static int tuner_detach(struct i2c_client *client)
{
struct tuner *t = i2c_get_clientdata(client);
+ int err;
+
+ err=i2c_detach_client(&t->i2c);
+ if (err) {
+ tuner_warn ("Client deregistration failed, client not detached.\n");
+ return err;
+ }
- i2c_detach_client(&t->i2c);
kfree(t);
return 0;
}
@@ -256,18 +365,23 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
unsigned int *iarg = (int*)arg;
switch (cmd) {
-
/* --- configuration --- */
case TUNER_SET_TYPE:
set_type(client,*iarg);
break;
+ case TUNER_SET_TYPE_ADDR:
+ set_addr(client,(struct tuner_addr *)arg);
+ break;
case AUDC_SET_RADIO:
+ t->mode = V4L2_TUNER_RADIO;
+ CHECK_ADDR(tv_tuner,"AUDC_SET_RADIO","TV");
+
if (V4L2_TUNER_RADIO != t->mode) {
set_tv_freq(client,400 * 16);
- t->mode = V4L2_TUNER_RADIO;
}
break;
case AUDC_CONFIG_PINNACLE:
+ CHECK_ADDR(tv_tuner,"AUDC_CONFIG_PINNACLE","TV");
switch (*iarg) {
case 2:
tuner_dbg("pinnacle pal\n");
@@ -297,6 +411,8 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
CHECK_V4L2;
t->mode = V4L2_TUNER_ANALOG_TV;
+ CHECK_ADDR(tv_tuner,"VIDIOCSCHAN","TV");
+
if (vc->norm < ARRAY_SIZE(map))
t->std = map[vc->norm];
tuner_fixup_std(t);
@@ -308,6 +424,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
unsigned long *v = arg;
+ CHECK_MODE("VIDIOCSFREQ");
CHECK_V4L2;
set_freq(client,*v);
return 0;
@@ -316,15 +433,27 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct video_tuner *vt = arg;
+ CHECK_ADDR(radio_tuner,"VIDIOCGTUNER","radio");
CHECK_V4L2;
- if (V4L2_TUNER_RADIO == t->mode && t->has_signal)
- vt->signal = t->has_signal(client);
+ if (V4L2_TUNER_RADIO == t->mode) {
+ if (t->has_signal)
+ vt->signal = t->has_signal(client);
+ if (t->is_stereo) {
+ if (t->is_stereo(client))
+ vt-> flags |= VIDEO_TUNER_STEREO_ON;
+ else
+ vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON;
+ }
+ vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */
+ }
+
return 0;
}
case VIDIOCGAUDIO:
{
struct video_audio *va = arg;
+ CHECK_ADDR(radio_tuner,"VIDIOCGAUDIO","radio");
CHECK_V4L2;
if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
va->mode = t->is_stereo(client)
@@ -339,6 +468,8 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
SWITCH_V4L2;
t->mode = V4L2_TUNER_ANALOG_TV;
+ CHECK_ADDR(tv_tuner,"VIDIOC_S_STD","TV");
+
t->std = *id;
tuner_fixup_std(t);
if (t->freq)
@@ -349,6 +480,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct v4l2_frequency *f = arg;
+ CHECK_MODE("VIDIOC_S_FREQUENCY");
SWITCH_V4L2;
if (V4L2_TUNER_RADIO == f->type &&
V4L2_TUNER_RADIO != t->mode)
@@ -361,6 +493,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct v4l2_frequency *f = arg;
+ CHECK_MODE("VIDIOC_G_FREQUENCY");
SWITCH_V4L2;
f->type = t->mode;
f->frequency = t->freq;
@@ -370,14 +503,29 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct v4l2_tuner *tuner = arg;
+ CHECK_MODE("VIDIOC_G_TUNER");
SWITCH_V4L2;
- if (V4L2_TUNER_RADIO == t->mode && t->has_signal)
- tuner->signal = t->has_signal(client);
+ if (V4L2_TUNER_RADIO == t->mode) {
+ if (t->has_signal)
+ tuner -> signal = t->has_signal(client);
+ if (t->is_stereo) {
+ if (t->is_stereo(client)) {
+ tuner -> capability |= V4L2_TUNER_CAP_STEREO;
+ tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO;
+ } else {
+ tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO;
+ }
+ }
+ }
+ /* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step to high at 62.5 Hz */
tuner->rangelow = tv_range[0] * 16;
- tuner->rangehigh = tv_range[1] * 16;
+// tuner->rangehigh = tv_range[1] * 16;
+// tuner->rangelow = tv_range[0] * 16384;
+ tuner->rangehigh = tv_range[1] * 16384;
break;
}
default:
+ tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
/* nothing */
break;
}
@@ -385,7 +533,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
return 0;
}
-static int tuner_suspend(struct device * dev, pm_message_t state, u32 level)
+static int tuner_suspend(struct device * dev, u32 state, u32 level)
{
struct i2c_client *c = container_of(dev, struct i2c_client, dev);
struct tuner *t = i2c_get_clientdata(c);
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 48c6ceff1dc..539f3055731 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -1,5 +1,5 @@
/*
- * $Id: tuner-simple.c,v 1.10 2005/03/08 08:38:00 kraxel Exp $
+ * $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $
*
* i2c tv tuner chip device driver
* controls all those simple 4-control-bytes style tuners.
@@ -212,7 +212,25 @@ static struct tunertype tuners[] = {
{ "Philips FQ1236A MK4", Philips, NTSC,
16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
+ /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */
+ { "Ymec TVision TVF-8531MF", Philips, NTSC,
+ 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
+ { "Ymec TVision TVF-5533MF", Philips, NTSC,
+ 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732},
+
+ { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC,
+ 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732},
+ { "Tena TNF9533-D/IF", LGINNOTEK, PAL,
+ 16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623},
+
+ /*
+ * This entry is for TEA5767 FM radio only chip used on several boards
+ * w/TV tuner
+ */
+ { TEA5767_TUNER_NAME, Philips, RADIO,
+ -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0},
};
+
unsigned const int tuner_count = ARRAY_SIZE(tuners);
/* ---------------------------------------------------------------------- */
@@ -223,6 +241,7 @@ static int tuner_getstatus(struct i2c_client *c)
if (1 != i2c_master_recv(c,&byte,1))
return 0;
+
return byte;
}
@@ -231,17 +250,33 @@ static int tuner_getstatus(struct i2c_client *c)
#define TUNER_MODE 0x38
#define TUNER_AFC 0x07
-#define TUNER_STEREO 0x10 /* radio mode */
-#define TUNER_SIGNAL 0x07 /* radio mode */
+#define TUNER_STEREO 0x10 /* radio mode */
+#define TUNER_STEREO_MK3 0x04 /* radio mode */
+#define TUNER_SIGNAL 0x07 /* radio mode */
static int tuner_signal(struct i2c_client *c)
{
- return (tuner_getstatus(c) & TUNER_SIGNAL)<<13;
+ return (tuner_getstatus(c) & TUNER_SIGNAL) << 13;
}
static int tuner_stereo(struct i2c_client *c)
{
- return (tuner_getstatus (c) & TUNER_STEREO);
+ int stereo, status;
+ struct tuner *t = i2c_get_clientdata(c);
+
+ status = tuner_getstatus (c);
+
+ switch (t->type) {
+ case TUNER_PHILIPS_FM1216ME_MK3:
+ case TUNER_PHILIPS_FM1236_MK3:
+ case TUNER_PHILIPS_FM1256_IH3:
+ stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
+ break;
+ default:
+ stereo = status & TUNER_STEREO;
+ }
+
+ return stereo;
}
#if 0 /* unused */
@@ -424,6 +459,14 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
buffer[2] = tun->config;
switch (t->type) {
+ case TUNER_TENA_9533_DI:
+ case TUNER_YMEC_TVF_5533MF:
+
+ /*These values are empirically determinated */
+ div = (freq*122)/16 - 20;
+ buffer[2] = 0x88; /* could be also 0x80 */
+ buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */
+ break;
case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3:
buffer[3] = 0x19;
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 41b635e0d3c..9a493bea76d 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -285,7 +285,6 @@ static int chip_thread(void *data)
schedule();
}
remove_wait_queue(&chip->wq, &wait);
- try_to_freeze(PF_FREEZE);
if (chip->done || signal_pending(current))
break;
dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c));
@@ -1237,17 +1236,17 @@ static int ta8874z_checkit(struct CHIPSTATE *chip)
/* audio chip descriptions - struct CHIPDESC */
/* insmod options to enable/disable individual audio chips */
-int tda8425 = 1;
-int tda9840 = 1;
-int tda9850 = 1;
-int tda9855 = 1;
-int tda9873 = 1;
-int tda9874a = 1;
-int tea6300 = 0; // address clash with msp34xx
-int tea6320 = 0; // address clash with msp34xx
-int tea6420 = 1;
-int pic16c54 = 1;
-int ta8874z = 0; // address clash with tda9840
+static int tda8425 = 1;
+static int tda9840 = 1;
+static int tda9850 = 1;
+static int tda9855 = 1;
+static int tda9873 = 1;
+static int tda9874a = 1;
+static int tea6300 = 0; // address clash with msp34xx
+static int tea6320 = 0; // address clash with msp34xx
+static int tea6420 = 1;
+static int pic16c54 = 1;
+static int ta8874z = 0; // address clash with tda9840
module_param(tda8425, int, 0444);
module_param(tda9840, int, 0444);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 3d216973798..0f03c25489f 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -75,7 +75,7 @@ hauppauge_tuner_fmt[] =
{ 0x00000007, "PAL(B/G)" },
{ 0x00001000, "NTSC(M)" },
{ 0x00000010, "PAL(I)" },
- { 0x00400000, "SECAM(L/L�)" },
+ { 0x00400000, "SECAM(L/L´)" },
{ 0x00000e00, "PAL(D/K)" },
{ 0x03000000, "ATSC Digital" },
};
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index eafd7061b31..51b99cdbf29 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -1,3 +1,7 @@
+/*
+ * $Id: tvmixer.c,v 1.8 2005/06/12 04:19:19 mchehab Exp $
+ */
+
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index b0d4bcb027d..70ecbdb8027 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -1,4 +1,6 @@
/*
+ * $Id: v4l1-compat.c,v 1.9 2005/06/12 04:19:19 mchehab Exp $
+ *
* Video for Linux Two
* Backward Compatibility Layer
*
@@ -15,14 +17,11 @@
*
*/
-#ifndef __KERNEL__
-#define __KERNEL__
-#endif
-
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -787,12 +786,15 @@ v4l_compat_translate_ioctl(struct inode *inode,
!(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
aud->step = qctrl2.step;
aud->mode = 0;
+
+ memset(&tun2,0,sizeof(tun2));
err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
if (err < 0) {
dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n",err);
err = 0;
break;
}
+
if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
index 5f870075b55..15f5bb48696 100644
--- a/drivers/media/video/video-buf-dvb.c
+++ b/drivers/media/video/video-buf-dvb.c
@@ -62,8 +62,7 @@ static int videobuf_dvb_thread(void *data)
break;
if (kthread_should_stop())
break;
- if (current->flags & PF_FREEZE)
- refrigerator(PF_FREEZE);
+ try_to_freeze();
/* feed buffer data to demux */
if (buf->state == STATE_DONE)
diff --git a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
index 8d132b0d6b1..06e8eb19a05 100644
--- a/drivers/message/i2o/Kconfig
+++ b/drivers/message/i2o/Kconfig
@@ -24,10 +24,28 @@ config I2O
If unsure, say N.
+config I2O_EXT_ADAPTEC
+ bool "Enable Adaptec extensions"
+ depends on I2O
+ default y
+ ---help---
+ Say Y for support of raidutils for Adaptec I2O controllers. You also
+ have to say Y to "I2O Configuration support", "I2O SCSI OSM" below
+ and to "SCSI generic support" under "SCSI device configuration".
+
+config I2O_EXT_ADAPTEC_DMA64
+ bool "Enable 64-bit DMA"
+ depends on I2O_EXT_ADAPTEC && ( 64BIT || HIGHMEM64G )
+ default y
+ ---help---
+ Say Y for support of 64-bit DMA transfer mode on Adaptec I2O
+ controllers.
+ Note: You need at least firmware version 3709.
+
config I2O_CONFIG
tristate "I2O Configuration support"
- depends on PCI && I2O
- help
+ depends on I2O
+ ---help---
Say Y for support of the configuration interface for the I2O adapters.
If you have a RAID controller from Adaptec and you want to use the
raidutils to manage your RAID array, you have to say Y here.
@@ -35,10 +53,28 @@ config I2O_CONFIG
To compile this support as a module, choose M here: the
module will be called i2o_config.
+config I2O_CONFIG_OLD_IOCTL
+ bool "Enable ioctls (OBSOLETE)"
+ depends on I2O_CONFIG
+ default y
+ ---help---
+ Enables old ioctls.
+
+config I2O_BUS
+ tristate "I2O Bus Adapter OSM"
+ depends on I2O
+ ---help---
+ Include support for the I2O Bus Adapter OSM. The Bus Adapter OSM
+ provides access to the busses on the I2O controller. The main purpose
+ is to rescan the bus to find new devices.
+
+ To compile this support as a module, choose M here: the
+ module will be called i2o_bus.
+
config I2O_BLOCK
tristate "I2O Block OSM"
depends on I2O
- help
+ ---help---
Include support for the I2O Block OSM. The Block OSM presents disk
and other structured block devices to the operating system. If you
are using an RAID controller, you could access the array only by
@@ -51,7 +87,7 @@ config I2O_BLOCK
config I2O_SCSI
tristate "I2O SCSI OSM"
depends on I2O && SCSI
- help
+ ---help---
Allows direct SCSI access to SCSI devices on a SCSI or FibreChannel
I2O controller. You can use both the SCSI and Block OSM together if
you wish. To access a RAID array, you must use the Block OSM driver.
@@ -63,7 +99,7 @@ config I2O_SCSI
config I2O_PROC
tristate "I2O /proc support"
depends on I2O
- help
+ ---help---
If you say Y here and to "/proc file system support", you will be
able to read I2O related information from the virtual directory
/proc/i2o.
diff --git a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile
index aabc6cdc3fc..2c2e39aa1ef 100644
--- a/drivers/message/i2o/Makefile
+++ b/drivers/message/i2o/Makefile
@@ -6,8 +6,11 @@
#
i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o
+i2o_bus-y += bus-osm.o
+i2o_config-y += config-osm.o
obj-$(CONFIG_I2O) += i2o_core.o
obj-$(CONFIG_I2O_CONFIG)+= i2o_config.o
+obj-$(CONFIG_I2O_BUS) += i2o_bus.o
obj-$(CONFIG_I2O_BLOCK) += i2o_block.o
obj-$(CONFIG_I2O_SCSI) += i2o_scsi.o
obj-$(CONFIG_I2O_PROC) += i2o_proc.o
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/message/i2o/bus-osm.c
new file mode 100644
index 00000000000..151b228e1cb
--- /dev/null
+++ b/drivers/message/i2o/bus-osm.c
@@ -0,0 +1,164 @@
+/*
+ * Bus Adapter OSM
+ *
+ * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Fixes/additions:
+ * Markus Lidel <Markus.Lidel@shadowconnect.com>
+ * initial version.
+ */
+
+#include <linux/module.h>
+#include <linux/i2o.h>
+
+#define OSM_NAME "bus-osm"
+#define OSM_VERSION "$Rev$"
+#define OSM_DESCRIPTION "I2O Bus Adapter OSM"
+
+static struct i2o_driver i2o_bus_driver;
+
+/* Bus OSM class handling definition */
+static struct i2o_class_id i2o_bus_class_id[] = {
+ {I2O_CLASS_BUS_ADAPTER},
+ {I2O_CLASS_END}
+};
+
+/**
+ * i2o_bus_scan - Scan the bus for new devices
+ * @dev: I2O device of the bus, which should be scanned
+ *
+ * Scans the bus dev for new / removed devices. After the scan a new LCT
+ * will be fetched automatically.
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+static int i2o_bus_scan(struct i2o_device *dev)
+{
+ struct i2o_message __iomem *msg;
+ u32 m;
+
+ m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
+ if (m == I2O_QUEUE_EMPTY)
+ return -ETIMEDOUT;
+
+ writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
+ writel(I2O_CMD_BUS_SCAN << 24 | HOST_TID << 12 | dev->lct_data.tid,
+ &msg->u.head[1]);
+
+ return i2o_msg_post_wait(dev->iop, m, 60);
+};
+
+/**
+ * i2o_bus_store_scan - Scan the I2O Bus Adapter
+ * @d: device which should be scanned
+ *
+ * Returns count.
+ */
+static ssize_t i2o_bus_store_scan(struct device *d, struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct i2o_device *i2o_dev = to_i2o_device(d);
+ int rc;
+
+ if ((rc = i2o_bus_scan(i2o_dev)))
+ osm_warn("bus scan failed %d\n", rc);
+
+ return count;
+}
+
+/* Bus Adapter OSM device attributes */
+static DEVICE_ATTR(scan, S_IWUSR, NULL, i2o_bus_store_scan);
+
+/**
+ * i2o_bus_probe - verify if dev is a I2O Bus Adapter device and install it
+ * @dev: device to verify if it is a I2O Bus Adapter device
+ *
+ * Because we want all Bus Adapters always return 0.
+ *
+ * Returns 0.
+ */
+static int i2o_bus_probe(struct device *dev)
+{
+ struct i2o_device *i2o_dev = to_i2o_device(get_device(dev));
+
+ device_create_file(dev, &dev_attr_scan);
+
+ osm_info("device added (TID: %03x)\n", i2o_dev->lct_data.tid);
+
+ return 0;
+};
+
+/**
+ * i2o_bus_remove - remove the I2O Bus Adapter device from the system again
+ * @dev: I2O Bus Adapter device which should be removed
+ *
+ * Always returns 0.
+ */
+static int i2o_bus_remove(struct device *dev)
+{
+ struct i2o_device *i2o_dev = to_i2o_device(dev);
+
+ device_remove_file(dev, &dev_attr_scan);
+
+ put_device(dev);
+
+ osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
+
+ return 0;
+};
+
+/* Bus Adapter OSM driver struct */
+static struct i2o_driver i2o_bus_driver = {
+ .name = OSM_NAME,
+ .classes = i2o_bus_class_id,
+ .driver = {
+ .probe = i2o_bus_probe,
+ .remove = i2o_bus_remove,
+ },
+};
+
+/**
+ * i2o_bus_init - Bus Adapter OSM initialization function
+ *
+ * Only register the Bus Adapter OSM in the I2O core.
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+static int __init i2o_bus_init(void)
+{
+ int rc;
+
+ printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
+
+ /* Register Bus Adapter OSM into I2O core */
+ rc = i2o_driver_register(&i2o_bus_driver);
+ if (rc) {
+ osm_err("Could not register Bus Adapter OSM\n");
+ return rc;
+ }
+
+ return 0;
+};
+
+/**
+ * i2o_bus_exit - Bus Adapter OSM exit function
+ *
+ * Unregisters Bus Adapter OSM from I2O core.
+ */
+static void __exit i2o_bus_exit(void)
+{
+ i2o_driver_unregister(&i2o_bus_driver);
+};
+
+MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
+
+module_init(i2o_bus_init);
+module_exit(i2o_bus_exit);
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c
new file mode 100644
index 00000000000..d0267609a94
--- /dev/null
+++ b/drivers/message/i2o/config-osm.c
@@ -0,0 +1,579 @@
+/*
+ * Configuration OSM
+ *
+ * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Fixes/additions:
+ * Markus Lidel <Markus.Lidel@shadowconnect.com>
+ * initial version.
+ */
+
+#include <linux/module.h>
+#include <linux/i2o.h>
+#include <linux/namei.h>
+
+#include <asm/uaccess.h>
+
+#define OSM_NAME "config-osm"
+#define OSM_VERSION "1.248"
+#define OSM_DESCRIPTION "I2O Configuration OSM"
+
+/* access mode user rw */
+#define S_IWRSR (S_IRUSR | S_IWUSR)
+
+static struct i2o_driver i2o_config_driver;
+
+/* Special file operations for sysfs */
+struct fops_attribute {
+ struct bin_attribute bin;
+ struct file_operations fops;
+};
+
+/**
+ * sysfs_read_dummy
+ */
+static ssize_t sysfs_read_dummy(struct kobject *kobj, char *buf, loff_t offset,
+ size_t count)
+{
+ return 0;
+};
+
+/**
+ * sysfs_write_dummy
+ */
+static ssize_t sysfs_write_dummy(struct kobject *kobj, char *buf, loff_t offset,
+ size_t count)
+{
+ return 0;
+};
+
+/**
+ * sysfs_create_fops_file - Creates attribute with special file operations
+ * @kobj: kobject which should contains the attribute
+ * @attr: attributes which should be used to create file
+ *
+ * First creates attribute @attr in kobject @kobj. If it is the first time
+ * this function is called, merge old fops from sysfs with new one and
+ * write it back. Afterwords the new fops will be set for the created
+ * attribute.
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+static int sysfs_create_fops_file(struct kobject *kobj,
+ struct fops_attribute *attr)
+{
+ struct file_operations tmp, *fops;
+ struct dentry *d;
+ struct qstr qstr;
+ int rc;
+
+ fops = &attr->fops;
+
+ if (fops->read)
+ attr->bin.read = sysfs_read_dummy;
+
+ if (fops->write)
+ attr->bin.write = sysfs_write_dummy;
+
+ if ((rc = sysfs_create_bin_file(kobj, &attr->bin)))
+ return rc;
+
+ qstr.name = attr->bin.attr.name;
+ qstr.len = strlen(qstr.name);
+ qstr.hash = full_name_hash(qstr.name, qstr.len);
+
+ if ((d = lookup_hash(&qstr, kobj->dentry))) {
+ if (!fops->owner) {
+ memcpy(&tmp, d->d_inode->i_fop, sizeof(tmp));
+ if (fops->read)
+ tmp.read = fops->read;
+ if (fops->write)
+ tmp.write = fops->write;
+ memcpy(fops, &tmp, sizeof(tmp));
+ }
+
+ d->d_inode->i_fop = fops;
+ } else
+ sysfs_remove_bin_file(kobj, &attr->bin);
+
+ return -ENOENT;
+};
+
+/**
+ * sysfs_remove_fops_file - Remove attribute with special file operations
+ * @kobj: kobject which contains the attribute
+ * @attr: attributes which are used to create file
+ *
+ * Only wrapper arround sysfs_remove_bin_file()
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+static inline int sysfs_remove_fops_file(struct kobject *kobj,
+ struct fops_attribute *attr)
+{
+ return sysfs_remove_bin_file(kobj, &attr->bin);
+};
+
+/**
+ * i2o_config_read_hrt - Returns the HRT of the controller
+ * @kob: kernel object handle
+ * @buf: buffer into which the HRT should be copied
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the HRT of the I2O
+ * controller corresponding to @kobj.
+ *
+ * Returns number of bytes copied into buffer.
+ */
+static ssize_t i2o_config_read_hrt(struct kobject *kobj, char *buf,
+ loff_t offset, size_t count)
+{
+ struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
+ i2o_hrt *hrt = c->hrt.virt;
+
+ u32 size = (hrt->num_entries * hrt->entry_len + 2) * 4;
+
+ if (offset > size)
+ return 0;
+
+ if (offset + count > size)
+ count = size - offset;
+
+ memcpy(buf, (u8 *) hrt + offset, count);
+
+ return count;
+};
+
+/**
+ * i2o_config_read_lct - Returns the LCT of the controller
+ * @kob: kernel object handle
+ * @buf: buffer into which the LCT should be copied
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the LCT of the I2O
+ * controller corresponding to @kobj.
+ *
+ * Returns number of bytes copied into buffer.
+ */
+static ssize_t i2o_config_read_lct(struct kobject *kobj, char *buf,
+ loff_t offset, size_t count)
+{
+ struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
+ u32 size = c->lct->table_size * 4;
+
+ if (offset > size)
+ return 0;
+
+ if (offset + count > size)
+ count = size - offset;
+
+ memcpy(buf, (u8 *) c->lct + offset, count);
+
+ return count;
+};
+
+#define I2O_CONFIG_SW_ATTR(_name,_mode,_type,_swid) \
+static ssize_t i2o_config_##_name##_read(struct file *file, char __user *buf, size_t count, loff_t * offset) { \
+ return i2o_config_sw_read(file, buf, count, offset, _type, _swid); \
+};\
+\
+static ssize_t i2o_config_##_name##_write(struct file *file, const char __user *buf, size_t count, loff_t * offset) { \
+ return i2o_config_sw_write(file, buf, count, offset, _type, _swid); \
+}; \
+\
+static struct fops_attribute i2o_config_attr_##_name = { \
+ .bin = { .attr = { .name = __stringify(_name), .mode = _mode, \
+ .owner = THIS_MODULE }, \
+ .size = 0, }, \
+ .fops = { .write = i2o_config_##_name##_write, \
+ .read = i2o_config_##_name##_read} \
+};
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+
+/**
+ * i2o_config_dpt_reagion - Converts type and id to flash region
+ * @swtype: type of software module reading
+ * @swid: id of software which should be read
+ *
+ * Converts type and id from I2O spec to the matching region for DPT /
+ * Adaptec controllers.
+ *
+ * Returns region which match type and id or -1 on error.
+ */
+static u32 i2o_config_dpt_region(u8 swtype, u8 swid)
+{
+ switch (swtype) {
+ case I2O_SOFTWARE_MODULE_IRTOS:
+ /*
+ * content: operation firmware
+ * region size:
+ * 0xbc000 for 2554, 3754, 2564, 3757
+ * 0x170000 for 2865
+ * 0x17c000 for 3966
+ */
+ if (!swid)
+ return 0;
+
+ break;
+
+ case I2O_SOFTWARE_MODULE_IOP_PRIVATE:
+ /*
+ * content: BIOS and SMOR
+ * BIOS size: first 0x8000 bytes
+ * region size:
+ * 0x40000 for 2554, 3754, 2564, 3757
+ * 0x80000 for 2865, 3966
+ */
+ if (!swid)
+ return 1;
+
+ break;
+
+ case I2O_SOFTWARE_MODULE_IOP_CONFIG:
+ switch (swid) {
+ case 0:
+ /*
+ * content: NVRAM defaults
+ * region size: 0x2000 bytes
+ */
+ return 2;
+ case 1:
+ /*
+ * content: serial number
+ * region size: 0x2000 bytes
+ */
+ return 3;
+ }
+ break;
+ }
+
+ return -1;
+};
+
+#endif
+
+/**
+ * i2o_config_sw_read - Read a software module from controller
+ * @file: file pointer
+ * @buf: buffer into which the data should be copied
+ * @count: number of bytes to read
+ * @off: file offset
+ * @swtype: type of software module reading
+ * @swid: id of software which should be read
+ *
+ * Transfers @count bytes at offset @offset from IOP into buffer using
+ * type @swtype and id @swid as described in I2O spec.
+ *
+ * Returns number of bytes copied into buffer or error code on failure.
+ */
+static ssize_t i2o_config_sw_read(struct file *file, char __user * buf,
+ size_t count, loff_t * offset, u8 swtype,
+ u32 swid)
+{
+ struct sysfs_dirent *sd = file->f_dentry->d_parent->d_fsdata;
+ struct kobject *kobj = sd->s_element;
+ struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
+ u32 m, function = I2O_CMD_SW_UPLOAD;
+ struct i2o_dma buffer;
+ struct i2o_message __iomem *msg;
+ u32 __iomem *mptr;
+ int rc, status;
+
+ m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
+ if (m == I2O_QUEUE_EMPTY)
+ return -EBUSY;
+
+ mptr = &msg->body[3];
+
+ if ((rc = i2o_dma_alloc(&c->pdev->dev, &buffer, count, GFP_KERNEL))) {
+ i2o_msg_nop(c, m);
+ return rc;
+ }
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (c->adaptec) {
+ mptr = &msg->body[4];
+ function = I2O_CMD_PRIVATE;
+
+ writel(TEN_WORD_MSG_SIZE | SGL_OFFSET_8, &msg->u.head[0]);
+
+ writel(I2O_VENDOR_DPT << 16 | I2O_DPT_FLASH_READ,
+ &msg->body[0]);
+ writel(i2o_config_dpt_region(swtype, swid), &msg->body[1]);
+ writel(*offset, &msg->body[2]);
+ writel(count, &msg->body[3]);
+ } else
+#endif
+ writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
+
+ writel(0xD0000000 | count, mptr++);
+ writel(buffer.phys, mptr);
+
+ writel(function << 24 | HOST_TID << 12 | ADAPTER_TID, &msg->u.head[1]);
+ writel(i2o_config_driver.context, &msg->u.head[2]);
+ writel(0, &msg->u.head[3]);
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (!c->adaptec)
+#endif
+ {
+ writel((u32) swtype << 16 | (u32) 1 << 8, &msg->body[0]);
+ writel(0, &msg->body[1]);
+ writel(swid, &msg->body[2]);
+ }
+
+ status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
+
+ if (status == I2O_POST_WAIT_OK) {
+ if (!(rc = copy_to_user(buf, buffer.virt, count))) {
+ rc = count;
+ *offset += count;
+ }
+ } else
+ rc = -EIO;
+
+ if (status != -ETIMEDOUT)
+ i2o_dma_free(&c->pdev->dev, &buffer);
+
+ return rc;
+};
+
+/**
+ * i2o_config_sw_write - Write a software module to controller
+ * @file: file pointer
+ * @buf: buffer into which the data should be copied
+ * @count: number of bytes to read
+ * @off: file offset
+ * @swtype: type of software module writing
+ * @swid: id of software which should be written
+ *
+ * Transfers @count bytes at offset @offset from buffer to IOP using
+ * type @swtype and id @swid as described in I2O spec.
+ *
+ * Returns number of bytes copied from buffer or error code on failure.
+ */
+static ssize_t i2o_config_sw_write(struct file *file, const char __user * buf,
+ size_t count, loff_t * offset, u8 swtype,
+ u32 swid)
+{
+ struct sysfs_dirent *sd = file->f_dentry->d_parent->d_fsdata;
+ struct kobject *kobj = sd->s_element;
+ struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
+ u32 m, function = I2O_CMD_SW_DOWNLOAD;
+ struct i2o_dma buffer;
+ struct i2o_message __iomem *msg;
+ u32 __iomem *mptr;
+ int rc, status;
+
+ m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
+ if (m == I2O_QUEUE_EMPTY)
+ return -EBUSY;
+
+ mptr = &msg->body[3];
+
+ if ((rc = i2o_dma_alloc(&c->pdev->dev, &buffer, count, GFP_KERNEL)))
+ goto nop_msg;
+
+ if ((rc = copy_from_user(buffer.virt, buf, count)))
+ goto free_buffer;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (c->adaptec) {
+ mptr = &msg->body[4];
+ function = I2O_CMD_PRIVATE;
+
+ writel(TEN_WORD_MSG_SIZE | SGL_OFFSET_8, &msg->u.head[0]);
+
+ writel(I2O_VENDOR_DPT << 16 | I2O_DPT_FLASH_WRITE,
+ &msg->body[0]);
+ writel(i2o_config_dpt_region(swtype, swid), &msg->body[1]);
+ writel(*offset, &msg->body[2]);
+ writel(count, &msg->body[3]);
+ } else
+#endif
+ writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
+
+ writel(0xD4000000 | count, mptr++);
+ writel(buffer.phys, mptr);
+
+ writel(function << 24 | HOST_TID << 12 | ADAPTER_TID, &msg->u.head[1]);
+ writel(i2o_config_driver.context, &msg->u.head[2]);
+ writel(0, &msg->u.head[3]);
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (!c->adaptec)
+#endif
+ {
+ writel((u32) swtype << 16 | (u32) 1 << 8, &msg->body[0]);
+ writel(0, &msg->body[1]);
+ writel(swid, &msg->body[2]);
+ }
+
+ status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
+
+ if (status != -ETIMEDOUT)
+ i2o_dma_free(&c->pdev->dev, &buffer);
+
+ if (status != I2O_POST_WAIT_OK)
+ return -EIO;
+
+ *offset += count;
+
+ return count;
+
+ free_buffer:
+ i2o_dma_free(&c->pdev->dev, &buffer);
+
+ nop_msg:
+ i2o_msg_nop(c, m);
+
+ return rc;
+};
+
+/* attribute for HRT in sysfs */
+static struct bin_attribute i2o_config_hrt_attr = {
+ .attr = {
+ .name = "hrt",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE},
+ .size = 0,
+ .read = i2o_config_read_hrt
+};
+
+/* attribute for LCT in sysfs */
+static struct bin_attribute i2o_config_lct_attr = {
+ .attr = {
+ .name = "lct",
+ .mode = S_IRUGO,
+ .owner = THIS_MODULE},
+ .size = 0,
+ .read = i2o_config_read_lct
+};
+
+/* IRTOS firmware access */
+I2O_CONFIG_SW_ATTR(irtos, S_IWRSR, I2O_SOFTWARE_MODULE_IRTOS, 0);
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+
+/*
+ * attribute for BIOS / SMOR, nvram and serial number access on DPT / Adaptec
+ * controllers
+ */
+I2O_CONFIG_SW_ATTR(bios, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_PRIVATE, 0);
+I2O_CONFIG_SW_ATTR(nvram, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_CONFIG, 0);
+I2O_CONFIG_SW_ATTR(serial, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_CONFIG, 1);
+
+#endif
+
+/**
+ * i2o_config_notify_controller_add - Notify of added controller
+ * @c: the controller which was added
+ *
+ * If a I2O controller is added, we catch the notification to add sysfs
+ * entries.
+ */
+static void i2o_config_notify_controller_add(struct i2o_controller *c)
+{
+ struct kobject *kobj = &c->exec->device.kobj;
+
+ sysfs_create_bin_file(kobj, &i2o_config_hrt_attr);
+ sysfs_create_bin_file(kobj, &i2o_config_lct_attr);
+
+ sysfs_create_fops_file(kobj, &i2o_config_attr_irtos);
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (c->adaptec) {
+ sysfs_create_fops_file(kobj, &i2o_config_attr_bios);
+ sysfs_create_fops_file(kobj, &i2o_config_attr_nvram);
+ sysfs_create_fops_file(kobj, &i2o_config_attr_serial);
+ }
+#endif
+};
+
+/**
+ * i2o_config_notify_controller_remove - Notify of removed controller
+ * @c: the controller which was removed
+ *
+ * If a I2O controller is removed, we catch the notification to remove the
+ * sysfs entries.
+ */
+static void i2o_config_notify_controller_remove(struct i2o_controller *c)
+{
+ struct kobject *kobj = &c->exec->device.kobj;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (c->adaptec) {
+ sysfs_remove_fops_file(kobj, &i2o_config_attr_serial);
+ sysfs_remove_fops_file(kobj, &i2o_config_attr_nvram);
+ sysfs_remove_fops_file(kobj, &i2o_config_attr_bios);
+ }
+#endif
+ sysfs_remove_fops_file(kobj, &i2o_config_attr_irtos);
+
+ sysfs_remove_bin_file(kobj, &i2o_config_lct_attr);
+ sysfs_remove_bin_file(kobj, &i2o_config_hrt_attr);
+};
+
+/* Config OSM driver struct */
+static struct i2o_driver i2o_config_driver = {
+ .name = OSM_NAME,
+ .notify_controller_add = i2o_config_notify_controller_add,
+ .notify_controller_remove = i2o_config_notify_controller_remove
+};
+
+#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
+#include "i2o_config.c"
+#endif
+
+/**
+ * i2o_config_init - Configuration OSM initialization function
+ *
+ * Registers Configuration OSM in the I2O core and if old ioctl's are
+ * compiled in initialize them.
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+static int __init i2o_config_init(void)
+{
+ printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
+
+ if (i2o_driver_register(&i2o_config_driver)) {
+ osm_err("handler register failed.\n");
+ return -EBUSY;
+ }
+#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
+ if (i2o_config_old_init())
+ i2o_driver_unregister(&i2o_config_driver);
+#endif
+
+ return 0;
+}
+
+/**
+ * i2o_config_exit - Configuration OSM exit function
+ *
+ * If old ioctl's are compiled in exit remove them and unregisters
+ * Configuration OSM from I2O core.
+ */
+static void i2o_config_exit(void)
+{
+#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
+ i2o_config_old_exit();
+#endif
+
+ i2o_driver_unregister(&i2o_config_driver);
+}
+
+MODULE_AUTHOR("Markus Lidel <Markus.Lidel@shadowconnect.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(OSM_DESCRIPTION);
+MODULE_VERSION(OSM_VERSION);
+
+module_init(i2o_config_init);
+module_exit(i2o_config_exit);
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
new file mode 100644
index 00000000000..c5bcfd70f71
--- /dev/null
+++ b/drivers/message/i2o/core.h
@@ -0,0 +1,58 @@
+/*
+ * I2O core internal declarations
+ *
+ * Copyright (C) 2005 Markus Lidel <Markus.Lidel@shadowconnect.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Fixes/additions:
+ * Markus Lidel <Markus.Lidel@shadowconnect.com>
+ * initial version.
+ */
+
+/* Exec-OSM */
+extern struct bus_type i2o_bus_type;
+
+extern struct i2o_driver i2o_exec_driver;
+extern int i2o_exec_lct_get(struct i2o_controller *);
+
+extern int __init i2o_exec_init(void);
+extern void __exit i2o_exec_exit(void);
+
+/* driver */
+extern int i2o_driver_dispatch(struct i2o_controller *, u32);
+
+extern int __init i2o_driver_init(void);
+extern void __exit i2o_driver_exit(void);
+
+/* PCI */
+extern int __init i2o_pci_init(void);
+extern void __exit i2o_pci_exit(void);
+
+/* device */
+extern void i2o_device_remove(struct i2o_device *);
+extern int i2o_device_parse_lct(struct i2o_controller *);
+
+extern int i2o_device_init(void);
+extern void i2o_device_exit(void);
+
+/* IOP */
+extern struct i2o_controller *i2o_iop_alloc(void);
+extern void i2o_iop_free(struct i2o_controller *);
+
+extern int i2o_iop_add(struct i2o_controller *);
+extern void i2o_iop_remove(struct i2o_controller *);
+
+/* config */
+extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
+
+/* control registers relative to c->base */
+#define I2O_IRQ_STATUS 0x30
+#define I2O_IRQ_MASK 0x34
+#define I2O_IN_PORT 0x40
+#define I2O_OUT_PORT 0x44
+
+#define I2O_IRQ_OUTBOUND_POST 0x00000008
diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c
index 2a5d478fc60..018ca887ca8 100644
--- a/drivers/message/i2o/debug.c
+++ b/drivers/message/i2o/debug.c
@@ -4,8 +4,6 @@
#include <linux/pci.h>
#include <linux/i2o.h>
-extern struct i2o_driver **i2o_drivers;
-extern unsigned int i2o_max_drivers;
static void i2o_report_util_cmd(u8 cmd);
static void i2o_report_exec_cmd(u8 cmd);
static void i2o_report_fail_status(u8 req_status, u32 * msg);
@@ -23,7 +21,6 @@ void i2o_report_status(const char *severity, const char *str,
u8 cmd = (msg[1] >> 24) & 0xFF;
u8 req_status = (msg[4] >> 24) & 0xFF;
u16 detailed_status = msg[4] & 0xFFFF;
- //struct i2o_driver *h = i2o_drivers[msg[2] & (i2o_max_drivers-1)];
if (cmd == I2O_CMD_UTIL_EVT_REGISTER)
return; // No status in this reply
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index eb907e87bc7..21f16ba3ac3 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -16,9 +16,7 @@
#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
-
-/* Exec OSM functions */
-extern struct bus_type i2o_bus_type;
+#include "core.h"
/**
* i2o_device_issue_claim - claim or release a device
@@ -282,8 +280,7 @@ int i2o_device_parse_lct(struct i2o_controller *c)
down(&c->lct_lock);
- if (c->lct)
- kfree(c->lct);
+ kfree(c->lct);
lct = c->dlct.virt;
@@ -294,12 +291,12 @@ int i2o_device_parse_lct(struct i2o_controller *c)
}
if (lct->table_size * 4 > c->dlct.len) {
- memcpy_fromio(c->lct, c->dlct.virt, c->dlct.len);
+ memcpy(c->lct, c->dlct.virt, c->dlct.len);
up(&c->lct_lock);
return -EAGAIN;
}
- memcpy_fromio(c->lct, c->dlct.virt, lct->table_size * 4);
+ memcpy(c->lct, c->dlct.virt, lct->table_size * 4);
lct = c->lct;
@@ -354,7 +351,7 @@ static ssize_t i2o_device_class_show_class_id(struct class_device *cd,
{
struct i2o_device *dev = to_i2o_device(cd->dev);
- sprintf(buf, "%03x\n", dev->lct_data.class_id);
+ sprintf(buf, "0x%03x\n", dev->lct_data.class_id);
return strlen(buf) + 1;
};
@@ -369,7 +366,7 @@ static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf)
{
struct i2o_device *dev = to_i2o_device(cd->dev);
- sprintf(buf, "%03x\n", dev->lct_data.tid);
+ sprintf(buf, "0x%03x\n", dev->lct_data.tid);
return strlen(buf) + 1;
};
@@ -401,25 +398,27 @@ static int i2o_device_class_add(struct class_device *cd)
/* create user entries for this device */
tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
- if (tmp)
+ if (tmp && (tmp != i2o_dev))
sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
"user");
/* create user entries refering to this device */
list_for_each_entry(tmp, &c->devices, list)
- if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+ if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+ && (tmp != i2o_dev))
sysfs_create_link(&tmp->device.kobj,
&i2o_dev->device.kobj, "user");
/* create parent entries for this device */
tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
- if (tmp)
+ if (tmp && (tmp != i2o_dev))
sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
"parent");
/* create parent entries refering to this device */
list_for_each_entry(tmp, &c->devices, list)
- if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+ if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+ && (tmp != i2o_dev))
sysfs_create_link(&tmp->device.kobj,
&i2o_dev->device.kobj, "parent");
@@ -444,9 +443,8 @@ static struct class_interface i2o_device_class_interface = {
* Note that the minimum sized reslist is 8 bytes and contains
* ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
*/
-
int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
- int oplen, void *reslist, int reslen)
+ int oplen, void *reslist, int reslen)
{
struct i2o_message __iomem *msg;
u32 m;
@@ -489,7 +487,7 @@ int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
if (rc == -ETIMEDOUT)
return rc;
- memcpy_fromio(reslist, res.virt, res.len);
+ memcpy(reslist, res.virt, res.len);
i2o_dma_free(dev, &res);
/* Query failed */
@@ -531,17 +529,23 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
void *buf, int buflen)
{
u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
- u8 resblk[8 + buflen]; /* 8 bytes for header */
+ u8 *resblk; /* 8 bytes for header */
int size;
if (field == -1) /* whole group */
opblk[4] = -1;
+ resblk = kmalloc(buflen + 8, GFP_KERNEL | GFP_ATOMIC);
+ if (!resblk)
+ return -ENOMEM;
+
size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
- sizeof(opblk), resblk, sizeof(resblk));
+ sizeof(opblk), resblk, buflen + 8);
memcpy(buf, resblk + 8, buflen); /* cut off header */
+ kfree(resblk);
+
if (size > buflen)
return buflen;
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 91f4edbb2a2..739bfdef0c6 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -17,9 +17,12 @@
#include <linux/module.h>
#include <linux/rwsem.h>
#include <linux/i2o.h>
+#include "core.h"
+
+#define OSM_NAME "i2o"
/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */
-unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
+static unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
module_param_named(max_drivers, i2o_max_drivers, uint, 0);
MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support");
@@ -76,17 +79,16 @@ int i2o_driver_register(struct i2o_driver *drv)
int rc = 0;
unsigned long flags;
- pr_debug("i2o: Register driver %s\n", drv->name);
+ osm_debug("Register driver %s\n", drv->name);
if (drv->event) {
drv->event_queue = create_workqueue(drv->name);
if (!drv->event_queue) {
- printk(KERN_ERR "i2o: Could not initialize event queue "
- "for driver %s\n", drv->name);
+ osm_err("Could not initialize event queue for driver "
+ "%s\n", drv->name);
return -EFAULT;
}
- pr_debug("i2o: Event queue initialized for driver %s\n",
- drv->name);
+ osm_debug("Event queue initialized for driver %s\n", drv->name);
} else
drv->event_queue = NULL;
@@ -97,8 +99,8 @@ int i2o_driver_register(struct i2o_driver *drv)
for (i = 0; i2o_drivers[i]; i++)
if (i >= i2o_max_drivers) {
- printk(KERN_ERR "i2o: too many drivers registered, "
- "increase max_drivers\n");
+ osm_err("too many drivers registered, increase "
+ "max_drivers\n");
spin_unlock_irqrestore(&i2o_drivers_lock, flags);
return -EFAULT;
}
@@ -108,18 +110,16 @@ int i2o_driver_register(struct i2o_driver *drv)
spin_unlock_irqrestore(&i2o_drivers_lock, flags);
- pr_debug("i2o: driver %s gets context id %d\n", drv->name,
- drv->context);
+ osm_debug("driver %s gets context id %d\n", drv->name, drv->context);
list_for_each_entry(c, &i2o_controllers, list) {
struct i2o_device *i2o_dev;
i2o_driver_notify_controller_add(drv, c);
list_for_each_entry(i2o_dev, &c->devices, list)
- i2o_driver_notify_device_add(drv, i2o_dev);
+ i2o_driver_notify_device_add(drv, i2o_dev);
}
-
rc = driver_register(&drv->driver);
if (rc)
destroy_workqueue(drv->event_queue);
@@ -139,7 +139,7 @@ void i2o_driver_unregister(struct i2o_driver *drv)
struct i2o_controller *c;
unsigned long flags;
- pr_debug("i2o: unregister driver %s\n", drv->name);
+ osm_debug("unregister driver %s\n", drv->name);
driver_unregister(&drv->driver);
@@ -159,7 +159,7 @@ void i2o_driver_unregister(struct i2o_driver *drv)
if (drv->event_queue) {
destroy_workqueue(drv->event_queue);
drv->event_queue = NULL;
- pr_debug("i2o: event queue removed for %s\n", drv->name);
+ osm_debug("event queue removed for %s\n", drv->name);
}
};
@@ -176,68 +176,70 @@ void i2o_driver_unregister(struct i2o_driver *drv)
* on success and if the message should be flushed afterwords. Returns
* negative error code on failure (the message will be flushed too).
*/
-int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
- struct i2o_message __iomem *msg)
+int i2o_driver_dispatch(struct i2o_controller *c, u32 m)
{
struct i2o_driver *drv;
- u32 context = readl(&msg->u.s.icntxt);
+ struct i2o_message *msg = i2o_msg_out_to_virt(c, m);
+ u32 context = le32_to_cpu(msg->u.s.icntxt);
+ unsigned long flags;
- if (likely(context < i2o_max_drivers)) {
- spin_lock(&i2o_drivers_lock);
- drv = i2o_drivers[context];
- spin_unlock(&i2o_drivers_lock);
+ if (unlikely(context >= i2o_max_drivers)) {
+ osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
+ context);
+ return -EIO;
+ }
- if (unlikely(!drv)) {
- printk(KERN_WARNING "%s: Spurious reply to unknown "
- "driver %d\n", c->name, context);
- return -EIO;
- }
+ spin_lock_irqsave(&i2o_drivers_lock, flags);
+ drv = i2o_drivers[context];
+ spin_unlock_irqrestore(&i2o_drivers_lock, flags);
- if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
- struct i2o_device *dev, *tmp;
- struct i2o_event *evt;
- u16 size;
- u16 tid;
+ if (unlikely(!drv)) {
+ osm_warn("%s: Spurious reply to unknown driver %d\n", c->name,
+ context);
+ return -EIO;
+ }
- tid = readl(&msg->u.head[1]) & 0x1fff;
+ if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
+ struct i2o_device *dev, *tmp;
+ struct i2o_event *evt;
+ u16 size;
+ u16 tid = le32_to_cpu(msg->u.head[1]) & 0xfff;
- pr_debug("%s: event received from device %d\n", c->name,
- tid);
+ osm_debug("event received from device %d\n", tid);
- /* cut of header from message size (in 32-bit words) */
- size = (readl(&msg->u.head[0]) >> 16) - 5;
+ if (!drv->event)
+ return -EIO;
- evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC);
- if (!evt)
- return -ENOMEM;
- memset(evt, 0, size * 4 + sizeof(*evt));
+ /* cut of header from message size (in 32-bit words) */
+ size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5;
- evt->size = size;
- memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt,
- (size + 2) * 4);
+ evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO);
+ if (!evt)
+ return -ENOMEM;
- list_for_each_entry_safe(dev, tmp, &c->devices, list)
- if (dev->lct_data.tid == tid) {
- evt->i2o_dev = dev;
- break;
- }
+ evt->size = size;
+ evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt);
+ evt->event_indicator = le32_to_cpu(msg->body[0]);
+ memcpy(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
- INIT_WORK(&evt->work, (void (*)(void *))drv->event,
- evt);
- queue_work(drv->event_queue, &evt->work);
- return 1;
+ list_for_each_entry_safe(dev, tmp, &c->devices, list)
+ if (dev->lct_data.tid == tid) {
+ evt->i2o_dev = dev;
+ break;
}
- if (likely(drv->reply))
- return drv->reply(c, m, msg);
- else
- pr_debug("%s: Reply to driver %s, but no reply function"
- " defined!\n", c->name, drv->name);
+ INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt);
+ queue_work(drv->event_queue, &evt->work);
+ return 1;
+ }
+
+ if (unlikely(!drv->reply)) {
+ osm_debug("%s: Reply to driver %s, but no reply function"
+ " defined!\n", c->name, drv->name);
return -EIO;
- } else
- printk(KERN_WARNING "%s: Spurious reply to unknown driver "
- "%d\n", c->name, readl(&msg->u.s.icntxt));
- return -EIO;
+ }
+
+ return drv->reply(c, m, msg);
}
/**
@@ -334,11 +336,11 @@ int __init i2o_driver_init(void)
if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) ||
((i2o_max_drivers ^ (i2o_max_drivers - 1)) !=
(2 * i2o_max_drivers - 1))) {
- printk(KERN_WARNING "i2o: max_drivers set to %d, but must be "
- ">=2 and <= 64 and a power of 2\n", i2o_max_drivers);
+ osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and "
+ "a power of 2\n", i2o_max_drivers);
i2o_max_drivers = I2O_MAX_DRIVERS;
}
- printk(KERN_INFO "i2o: max drivers = %d\n", i2o_max_drivers);
+ osm_info("max drivers = %d\n", i2o_max_drivers);
i2o_drivers =
kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 79c1cbfb8f4..bda2c62648b 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
+#include "core.h"
#define OSM_NAME "exec-osm"
@@ -37,9 +38,6 @@ struct i2o_driver i2o_exec_driver;
static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind);
-/* Module internal functions from other sources */
-extern int i2o_device_parse_lct(struct i2o_controller *);
-
/* global wait list for POST WAIT */
static LIST_HEAD(i2o_exec_wait_list);
@@ -50,7 +48,7 @@ struct i2o_exec_wait {
u32 tcntxt; /* transaction context from reply */
int complete; /* 1 if reply received otherwise 0 */
u32 m; /* message id */
- struct i2o_message __iomem *msg; /* pointer to the reply message */
+ struct i2o_message *msg; /* pointer to the reply message */
struct list_head list; /* node in global wait list */
};
@@ -108,7 +106,8 @@ static void i2o_exec_wait_free(struct i2o_exec_wait *wait)
* buffer must not be freed. Instead the event completion will free them
* for you. In all other cases the buffer are your problem.
*
- * Returns 0 on success or negative error code on failure.
+ * Returns 0 on success, negative error code on timeout or positive error
+ * code from reply.
*/
int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
timeout, struct i2o_dma *dma)
@@ -116,7 +115,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
DECLARE_WAIT_QUEUE_HEAD(wq);
struct i2o_exec_wait *wait;
static u32 tcntxt = 0x80000000;
- struct i2o_message __iomem *msg = c->in_queue.virt + m;
+ struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
int rc = 0;
wait = i2o_exec_wait_alloc();
@@ -153,7 +152,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
list_add(&wait->list, &i2o_exec_wait_list);
wait_event_interruptible_timeout(wq, wait->complete,
- timeout * HZ);
+ timeout * HZ);
wait->wq = NULL;
}
@@ -161,8 +160,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
barrier();
if (wait->complete) {
- if (readl(&wait->msg->body[0]) >> 24)
- rc = readl(&wait->msg->body[0]) & 0xff;
+ rc = le32_to_cpu(wait->msg->body[0]) >> 24;
i2o_flush_reply(c, wait->m);
i2o_exec_wait_free(wait);
} else {
@@ -187,6 +185,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
* @c: I2O controller which answers
* @m: message id
* @msg: pointer to the I2O reply message
+ * @context: transaction context of request
*
* This function is called in interrupt context only. If the reply reached
* before the timeout, the i2o_exec_wait struct is filled with the message
@@ -201,16 +200,12 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
* message must also be given back to the controller.
*/
static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
- struct i2o_message __iomem *msg)
+ struct i2o_message *msg, u32 context)
{
struct i2o_exec_wait *wait, *tmp;
- static spinlock_t lock;
+ unsigned long flags;
+ static spinlock_t lock = SPIN_LOCK_UNLOCKED;
int rc = 1;
- u32 context;
-
- spin_lock_init(&lock);
-
- context = readl(&msg->u.s.tcntxt);
/*
* We need to search through the i2o_exec_wait_list to see if the given
@@ -219,11 +214,13 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
* already expired. Not much we can do about that except log it for
* debug purposes, increase timeout, and recompile.
*/
- spin_lock(&lock);
+ spin_lock_irqsave(&lock, flags);
list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) {
if (wait->tcntxt == context) {
list_del(&wait->list);
+ spin_unlock_irqrestore(&lock, flags);
+
wait->m = m;
wait->msg = msg;
wait->complete = 1;
@@ -245,21 +242,63 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
rc = -1;
}
- spin_unlock(&lock);
-
return rc;
}
}
- spin_unlock(&lock);
+ spin_unlock_irqrestore(&lock, flags);
- pr_debug("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
+ osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name,
context);
return -1;
};
/**
+ * i2o_exec_show_vendor_id - Displays Vendor ID of controller
+ * @d: device of which the Vendor ID should be displayed
+ * @buf: buffer into which the Vendor ID should be printed
+ *
+ * Returns number of bytes printed into buffer.
+ */
+static ssize_t i2o_exec_show_vendor_id(struct device *d, struct device_attribute *attr, char *buf)
+{
+ struct i2o_device *dev = to_i2o_device(d);
+ u16 id;
+
+ if (i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) {
+ sprintf(buf, "0x%04x", id);
+ return strlen(buf) + 1;
+ }
+
+ return 0;
+};
+
+/**
+ * i2o_exec_show_product_id - Displays Product ID of controller
+ * @d: device of which the Product ID should be displayed
+ * @buf: buffer into which the Product ID should be printed
+ *
+ * Returns number of bytes printed into buffer.
+ */
+static ssize_t i2o_exec_show_product_id(struct device *d, struct device_attribute *attr, char *buf)
+{
+ struct i2o_device *dev = to_i2o_device(d);
+ u16 id;
+
+ if (i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) {
+ sprintf(buf, "0x%04x", id);
+ return strlen(buf) + 1;
+ }
+
+ return 0;
+};
+
+/* Exec-OSM device attributes */
+static DEVICE_ATTR(vendor_id, S_IRUGO, i2o_exec_show_vendor_id, NULL);
+static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL);
+
+/**
* i2o_exec_probe - Called if a new I2O device (executive class) appears
* @dev: I2O device which should be probed
*
@@ -271,10 +310,16 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m,
static int i2o_exec_probe(struct device *dev)
{
struct i2o_device *i2o_dev = to_i2o_device(dev);
+ struct i2o_controller *c = i2o_dev->iop;
i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff);
- i2o_dev->iop->exec = i2o_dev;
+ c->exec = i2o_dev;
+
+ i2o_exec_lct_notify(c, c->lct->change_ind + 1);
+
+ device_create_file(dev, &dev_attr_vendor_id);
+ device_create_file(dev, &dev_attr_product_id);
return 0;
};
@@ -289,6 +334,9 @@ static int i2o_exec_probe(struct device *dev)
*/
static int i2o_exec_remove(struct device *dev)
{
+ device_remove_file(dev, &dev_attr_product_id);
+ device_remove_file(dev, &dev_attr_vendor_id);
+
i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0);
return 0;
@@ -300,12 +348,16 @@ static int i2o_exec_remove(struct device *dev)
*
* This function handles asynchronus LCT NOTIFY replies. It parses the
* new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY
- * again.
+ * again, otherwise send LCT NOTIFY to get informed on next LCT change.
*/
static void i2o_exec_lct_modified(struct i2o_controller *c)
{
- if (i2o_device_parse_lct(c) == -EAGAIN)
- i2o_exec_lct_notify(c, 0);
+ u32 change_ind = 0;
+
+ if (i2o_device_parse_lct(c) != -EAGAIN)
+ change_ind = c->lct->change_ind + 1;
+
+ i2o_exec_lct_notify(c, change_ind);
};
/**
@@ -325,8 +377,14 @@ static void i2o_exec_lct_modified(struct i2o_controller *c)
static int i2o_exec_reply(struct i2o_controller *c, u32 m,
struct i2o_message *msg)
{
- if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) { // Fail bit is set
- struct i2o_message __iomem *pmsg; /* preserved message */
+ u32 context;
+
+ if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) {
+ /*
+ * If Fail bit is set we must take the transaction context of
+ * the preserved message to find the right request again.
+ */
+ struct i2o_message __iomem *pmsg;
u32 pm;
pm = le32_to_cpu(msg->body[3]);
@@ -335,15 +393,15 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
i2o_report_status(KERN_INFO, "i2o_core", msg);
- /* Release the preserved msg by resubmitting it as a NOP */
- i2o_msg_nop(c, pm);
+ context = readl(&pmsg->u.s.tcntxt);
- /* If reply to i2o_post_wait failed, return causes a timeout */
- return -1;
- }
+ /* Release the preserved msg */
+ i2o_msg_nop(c, pm);
+ } else
+ context = le32_to_cpu(msg->u.s.tcntxt);
- if (le32_to_cpu(msg->u.s.tcntxt) & 0x80000000)
- return i2o_msg_post_wait_complete(c, m, msg);
+ if (context & 0x80000000)
+ return i2o_msg_post_wait_complete(c, m, msg, context);
if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_LCT_NOTIFY) {
struct work_struct *work;
@@ -381,8 +439,9 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m,
*/
static void i2o_exec_event(struct i2o_event *evt)
{
- osm_info("Event received from device: %d\n",
- evt->i2o_dev->lct_data.tid);
+ if (likely(evt->i2o_dev))
+ osm_debug("Event received from device: %d\n",
+ evt->i2o_dev->lct_data.tid);
kfree(evt);
};
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 4830b775906..f283b5bafdd 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -62,7 +62,7 @@
#include "i2o_block.h"
#define OSM_NAME "block-osm"
-#define OSM_VERSION "$Rev$"
+#define OSM_VERSION "1.287"
#define OSM_DESCRIPTION "I2O Block Device OSM"
static struct i2o_driver i2o_block_driver;
@@ -104,7 +104,8 @@ static int i2o_block_remove(struct device *dev)
struct i2o_device *i2o_dev = to_i2o_device(dev);
struct i2o_block_device *i2o_blk_dev = dev_get_drvdata(dev);
- osm_info("Device removed %s\n", i2o_blk_dev->gd->disk_name);
+ osm_info("device removed (TID: %03x): %s\n", i2o_dev->lct_data.tid,
+ i2o_blk_dev->gd->disk_name);
i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0);
@@ -146,6 +147,29 @@ static int i2o_block_device_flush(struct i2o_device *dev)
};
/**
+ * i2o_block_issue_flush - device-flush interface for block-layer
+ * @queue: the request queue of the device which should be flushed
+ * @disk: gendisk
+ * @error_sector: error offset
+ *
+ * Helper function to provide flush functionality to block-layer.
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+
+static int i2o_block_issue_flush(request_queue_t * queue, struct gendisk *disk,
+ sector_t * error_sector)
+{
+ struct i2o_block_device *i2o_blk_dev = queue->queuedata;
+ int rc = -ENODEV;
+
+ if (likely(i2o_blk_dev))
+ rc = i2o_block_device_flush(i2o_blk_dev->i2o_dev);
+
+ return rc;
+}
+
+/**
* i2o_block_device_mount - Mount (load) the media of device dev
* @dev: I2O device which should receive the mount request
* @media_id: Media Identifier
@@ -298,28 +322,31 @@ static inline void i2o_block_request_free(struct i2o_block_request *ireq)
/**
* i2o_block_sglist_alloc - Allocate the SG list and map it
+ * @c: I2O controller to which the request belongs
* @ireq: I2O block request
*
- * Builds the SG list and map it into to be accessable by the controller.
+ * Builds the SG list and map it to be accessable by the controller.
*
- * Returns the number of elements in the SG list or 0 on failure.
+ * Returns 0 on failure or 1 on success.
*/
-static inline int i2o_block_sglist_alloc(struct i2o_block_request *ireq)
+static inline int i2o_block_sglist_alloc(struct i2o_controller *c,
+ struct i2o_block_request *ireq,
+ u32 __iomem ** mptr)
{
- struct device *dev = &ireq->i2o_blk_dev->i2o_dev->iop->pdev->dev;
int nents;
+ enum dma_data_direction direction;
+ ireq->dev = &c->pdev->dev;
nents = blk_rq_map_sg(ireq->req->q, ireq->req, ireq->sg_table);
if (rq_data_dir(ireq->req) == READ)
- ireq->sg_dma_direction = PCI_DMA_FROMDEVICE;
+ direction = PCI_DMA_FROMDEVICE;
else
- ireq->sg_dma_direction = PCI_DMA_TODEVICE;
+ direction = PCI_DMA_TODEVICE;
- ireq->sg_nents = dma_map_sg(dev, ireq->sg_table, nents,
- ireq->sg_dma_direction);
+ ireq->sg_nents = nents;
- return ireq->sg_nents;
+ return i2o_dma_map_sg(c, ireq->sg_table, nents, direction, mptr);
};
/**
@@ -330,10 +357,14 @@ static inline int i2o_block_sglist_alloc(struct i2o_block_request *ireq)
*/
static inline void i2o_block_sglist_free(struct i2o_block_request *ireq)
{
- struct device *dev = &ireq->i2o_blk_dev->i2o_dev->iop->pdev->dev;
+ enum dma_data_direction direction;
- dma_unmap_sg(dev, ireq->sg_table, ireq->sg_nents,
- ireq->sg_dma_direction);
+ if (rq_data_dir(ireq->req) == READ)
+ direction = PCI_DMA_FROMDEVICE;
+ else
+ direction = PCI_DMA_TODEVICE;
+
+ dma_unmap_sg(ireq->dev, ireq->sg_table, ireq->sg_nents, direction);
};
/**
@@ -351,6 +382,11 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req)
struct i2o_block_device *i2o_blk_dev = q->queuedata;
struct i2o_block_request *ireq;
+ if (unlikely(!i2o_blk_dev)) {
+ osm_err("block device already removed\n");
+ return BLKPREP_KILL;
+ }
+
/* request is already processed by us, so return */
if (req->flags & REQ_SPECIAL) {
osm_debug("REQ_SPECIAL already set!\n");
@@ -400,71 +436,65 @@ static void i2o_block_delayed_request_fn(void *delayed_request)
};
/**
- * i2o_block_reply - Block OSM reply handler.
- * @c: I2O controller from which the message arrives
- * @m: message id of reply
- * qmsg: the actuall I2O message reply
+ * i2o_block_end_request - Post-processing of completed commands
+ * @req: request which should be completed
+ * @uptodate: 1 for success, 0 for I/O error, < 0 for specific error
+ * @nr_bytes: number of bytes to complete
*
- * This function gets all the message replies.
+ * Mark the request as complete. The lock must not be held when entering.
*
*/
-static int i2o_block_reply(struct i2o_controller *c, u32 m,
- struct i2o_message *msg)
+static void i2o_block_end_request(struct request *req, int uptodate,
+ int nr_bytes)
{
- struct i2o_block_request *ireq;
- struct request *req;
- struct i2o_block_device *dev;
- struct request_queue *q;
- u8 st;
+ struct i2o_block_request *ireq = req->special;
+ struct i2o_block_device *dev = ireq->i2o_blk_dev;
+ request_queue_t *q = req->q;
unsigned long flags;
- /* FAILed message */
- if (unlikely(le32_to_cpu(msg->u.head[0]) & (1 << 13))) {
- struct i2o_message *pmsg;
- u32 pm;
+ if (end_that_request_chunk(req, uptodate, nr_bytes)) {
+ int leftover = (req->hard_nr_sectors << KERNEL_SECTOR_SHIFT);
- /*
- * FAILed message from controller
- * We increment the error count and abort it
- *
- * In theory this will never happen. The I2O block class
- * specification states that block devices never return
- * FAILs but instead use the REQ status field...but
- * better be on the safe side since no one really follows
- * the spec to the book :)
- */
- pm = le32_to_cpu(msg->body[3]);
- pmsg = i2o_msg_in_to_virt(c, pm);
+ if (blk_pc_request(req))
+ leftover = req->data_len;
- req = i2o_cntxt_list_get(c, le32_to_cpu(pmsg->u.s.tcntxt));
- if (unlikely(!req)) {
- osm_err("NULL reply received!\n");
- return -1;
- }
+ if (end_io_error(uptodate))
+ end_that_request_chunk(req, 0, leftover);
+ }
- ireq = req->special;
- dev = ireq->i2o_blk_dev;
- q = dev->gd->queue;
+ add_disk_randomness(req->rq_disk);
- req->errors++;
-
- spin_lock_irqsave(q->queue_lock, flags);
+ spin_lock_irqsave(q->queue_lock, flags);
- while (end_that_request_chunk(req, !req->errors,
- le32_to_cpu(pmsg->body[1]))) ;
- end_that_request_last(req);
+ end_that_request_last(req);
+ if (likely(dev)) {
dev->open_queue_depth--;
list_del(&ireq->queue);
- blk_start_queue(q);
+ }
- spin_unlock_irqrestore(q->queue_lock, flags);
+ blk_start_queue(q);
- /* Now flush the message by making it a NOP */
- i2o_msg_nop(c, pm);
+ spin_unlock_irqrestore(q->queue_lock, flags);
- return -1;
- }
+ i2o_block_sglist_free(ireq);
+ i2o_block_request_free(ireq);
+};
+
+/**
+ * i2o_block_reply - Block OSM reply handler.
+ * @c: I2O controller from which the message arrives
+ * @m: message id of reply
+ * qmsg: the actuall I2O message reply
+ *
+ * This function gets all the message replies.
+ *
+ */
+static int i2o_block_reply(struct i2o_controller *c, u32 m,
+ struct i2o_message *msg)
+{
+ struct request *req;
+ int uptodate = 1;
req = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
if (unlikely(!req)) {
@@ -472,61 +502,13 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
return -1;
}
- ireq = req->special;
- dev = ireq->i2o_blk_dev;
- q = dev->gd->queue;
-
- if (unlikely(!dev->i2o_dev)) {
- /*
- * This is HACK, but Intel Integrated RAID allows user
- * to delete a volume that is claimed, locked, and in use
- * by the OS. We have to check for a reply from a
- * non-existent device and flag it as an error or the system
- * goes kaput...
- */
- req->errors++;
- osm_warn("Data transfer to deleted device!\n");
- spin_lock_irqsave(q->queue_lock, flags);
- while (end_that_request_chunk
- (req, !req->errors, le32_to_cpu(msg->body[1]))) ;
- end_that_request_last(req);
-
- dev->open_queue_depth--;
- list_del(&ireq->queue);
- blk_start_queue(q);
-
- spin_unlock_irqrestore(q->queue_lock, flags);
- return -1;
- }
-
/*
* Lets see what is cooking. We stuffed the
* request in the context.
*/
- st = le32_to_cpu(msg->body[0]) >> 24;
-
- if (st != 0) {
- int err;
- char *bsa_errors[] = {
- "Success",
- "Media Error",
- "Failure communicating to device",
- "Device Failure",
- "Device is not ready",
- "Media not present",
- "Media is locked by another user",
- "Media has failed",
- "Failure communicating to device",
- "Device bus failure",
- "Device is locked by another user",
- "Device is write protected",
- "Device has reset",
- "Volume has changed, waiting for acknowledgement"
- };
-
- err = le32_to_cpu(msg->body[0]) & 0xffff;
-
+ if ((le32_to_cpu(msg->body[0]) >> 24) != 0) {
+ u32 status = le32_to_cpu(msg->body[0]);
/*
* Device not ready means two things. One is that the
* the thing went offline (but not a removal media)
@@ -539,40 +521,23 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m,
* Don't stick a supertrak100 into cache aggressive modes
*/
- osm_err("block-osm: /dev/%s error: %s", dev->gd->disk_name,
- bsa_errors[le32_to_cpu(msg->body[0]) & 0xffff]);
- if (le32_to_cpu(msg->body[0]) & 0x00ff0000)
- printk(KERN_ERR " - DDM attempted %d retries",
- (le32_to_cpu(msg->body[0]) >> 16) & 0x00ff);
- printk(KERN_ERR ".\n");
- req->errors++;
- } else
- req->errors = 0;
+ osm_err("TID %03x error status: 0x%02x, detailed status: "
+ "0x%04x\n", (le32_to_cpu(msg->u.head[1]) >> 12 & 0xfff),
+ status >> 24, status & 0xffff);
- if (!end_that_request_chunk
- (req, !req->errors, le32_to_cpu(msg->body[1]))) {
- add_disk_randomness(req->rq_disk);
- spin_lock_irqsave(q->queue_lock, flags);
-
- end_that_request_last(req);
+ req->errors++;
- dev->open_queue_depth--;
- list_del(&ireq->queue);
- blk_start_queue(q);
+ uptodate = 0;
+ }
- spin_unlock_irqrestore(q->queue_lock, flags);
-
- i2o_block_sglist_free(ireq);
- i2o_block_request_free(ireq);
- } else
- osm_err("still remaining chunks\n");
+ i2o_block_end_request(req, uptodate, le32_to_cpu(msg->body[1]));
return 1;
};
static void i2o_block_event(struct i2o_event *evt)
{
- osm_info("block-osm: event received\n");
+ osm_debug("event received\n");
kfree(evt);
};
@@ -778,18 +743,25 @@ static int i2o_block_media_changed(struct gendisk *disk)
static int i2o_block_transfer(struct request *req)
{
struct i2o_block_device *dev = req->rq_disk->private_data;
- struct i2o_controller *c = dev->i2o_dev->iop;
+ struct i2o_controller *c;
int tid = dev->i2o_dev->lct_data.tid;
struct i2o_message __iomem *msg;
- void __iomem *mptr;
+ u32 __iomem *mptr;
struct i2o_block_request *ireq = req->special;
- struct scatterlist *sg;
- int sgnum;
- int i;
u32 m;
u32 tcntxt;
- u32 sg_flags;
+ u32 sgl_offset = SGL_OFFSET_8;
+ u32 ctl_flags = 0x00000000;
int rc;
+ u32 cmd;
+
+ if (unlikely(!dev->i2o_dev)) {
+ osm_err("transfer to removed drive\n");
+ rc = -ENODEV;
+ goto exit;
+ }
+
+ c = dev->i2o_dev->iop;
m = i2o_msg_get(c, &msg);
if (m == I2O_QUEUE_EMPTY) {
@@ -803,82 +775,109 @@ static int i2o_block_transfer(struct request *req)
goto nop_msg;
}
- if ((sgnum = i2o_block_sglist_alloc(ireq)) <= 0) {
- rc = -ENOMEM;
- goto context_remove;
- }
-
- /* Build the message based on the request. */
writel(i2o_block_driver.context, &msg->u.s.icntxt);
writel(tcntxt, &msg->u.s.tcntxt);
- writel(req->nr_sectors << 9, &msg->body[1]);
-
- writel((((u64) req->sector) << 9) & 0xffffffff, &msg->body[2]);
- writel(req->sector >> 23, &msg->body[3]);
- mptr = &msg->body[4];
-
- sg = ireq->sg_table;
+ mptr = &msg->body[0];
if (rq_data_dir(req) == READ) {
- writel(I2O_CMD_BLOCK_READ << 24 | HOST_TID << 12 | tid,
- &msg->u.head[1]);
- sg_flags = 0x10000000;
+ cmd = I2O_CMD_BLOCK_READ << 24;
+
switch (dev->rcache) {
- case CACHE_NULL:
- writel(0, &msg->body[0]);
- break;
case CACHE_PREFETCH:
- writel(0x201F0008, &msg->body[0]);
+ ctl_flags = 0x201F0008;
break;
+
case CACHE_SMARTFETCH:
if (req->nr_sectors > 16)
- writel(0x201F0008, &msg->body[0]);
+ ctl_flags = 0x201F0008;
else
- writel(0x001F0000, &msg->body[0]);
+ ctl_flags = 0x001F0000;
+ break;
+
+ default:
break;
}
} else {
- writel(I2O_CMD_BLOCK_WRITE << 24 | HOST_TID << 12 | tid,
- &msg->u.head[1]);
- sg_flags = 0x14000000;
+ cmd = I2O_CMD_BLOCK_WRITE << 24;
+
switch (dev->wcache) {
- case CACHE_NULL:
- writel(0, &msg->body[0]);
- break;
case CACHE_WRITETHROUGH:
- writel(0x001F0008, &msg->body[0]);
+ ctl_flags = 0x001F0008;
break;
case CACHE_WRITEBACK:
- writel(0x001F0010, &msg->body[0]);
+ ctl_flags = 0x001F0010;
break;
case CACHE_SMARTBACK:
if (req->nr_sectors > 16)
- writel(0x001F0004, &msg->body[0]);
+ ctl_flags = 0x001F0004;
else
- writel(0x001F0010, &msg->body[0]);
+ ctl_flags = 0x001F0010;
break;
case CACHE_SMARTTHROUGH:
if (req->nr_sectors > 16)
- writel(0x001F0004, &msg->body[0]);
+ ctl_flags = 0x001F0004;
else
- writel(0x001F0010, &msg->body[0]);
+ ctl_flags = 0x001F0010;
+ default:
+ break;
+ }
+ }
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (c->adaptec) {
+ u8 cmd[10];
+ u32 scsi_flags;
+ u16 hwsec = queue_hardsect_size(req->q) >> KERNEL_SECTOR_SHIFT;
+
+ memset(cmd, 0, 10);
+
+ sgl_offset = SGL_OFFSET_12;
+
+ writel(I2O_CMD_PRIVATE << 24 | HOST_TID << 12 | tid,
+ &msg->u.head[1]);
+
+ writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++);
+ writel(tid, mptr++);
+
+ /*
+ * ENABLE_DISCONNECT
+ * SIMPLE_TAG
+ * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME
+ */
+ if (rq_data_dir(req) == READ) {
+ cmd[0] = 0x28;
+ scsi_flags = 0x60a0000a;
+ } else {
+ cmd[0] = 0x2A;
+ scsi_flags = 0xa0a0000a;
}
+
+ writel(scsi_flags, mptr++);
+
+ *((u32 *) & cmd[2]) = cpu_to_be32(req->sector * hwsec);
+ *((u16 *) & cmd[7]) = cpu_to_be16(req->nr_sectors * hwsec);
+
+ memcpy_toio(mptr, cmd, 10);
+ mptr += 4;
+ writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++);
+ } else
+#endif
+ {
+ writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]);
+ writel(ctl_flags, mptr++);
+ writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++);
+ writel((u32) (req->sector << KERNEL_SECTOR_SHIFT), mptr++);
+ writel(req->sector >> (32 - KERNEL_SECTOR_SHIFT), mptr++);
}
- for (i = sgnum; i > 0; i--) {
- if (i == 1)
- sg_flags |= 0x80000000;
- writel(sg_flags | sg_dma_len(sg), mptr);
- writel(sg_dma_address(sg), mptr + 4);
- mptr += 8;
- sg++;
+ if (!i2o_block_sglist_alloc(c, ireq, &mptr)) {
+ rc = -ENOMEM;
+ goto context_remove;
}
- writel(I2O_MESSAGE_SIZE
- (((unsigned long)mptr -
- (unsigned long)&msg->u.head[0]) >> 2) | SGL_OFFSET_8,
- &msg->u.head[0]);
+ writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) |
+ sgl_offset, &msg->u.head[0]);
list_add_tail(&ireq->queue, &dev->open_queue);
dev->open_queue_depth++;
@@ -921,11 +920,13 @@ static void i2o_block_request_fn(struct request_queue *q)
queue_depth = ireq->i2o_blk_dev->open_queue_depth;
- if (queue_depth < I2O_BLOCK_MAX_OPEN_REQUESTS)
+ if (queue_depth < I2O_BLOCK_MAX_OPEN_REQUESTS) {
if (!i2o_block_transfer(req)) {
blkdev_dequeue_request(req);
continue;
- }
+ } else
+ osm_info("transfer error\n");
+ }
if (queue_depth)
break;
@@ -939,7 +940,6 @@ static void i2o_block_request_fn(struct request_queue *q)
INIT_WORK(&dreq->work, i2o_block_delayed_request_fn,
dreq);
- osm_info("transfer error\n");
if (!queue_delayed_work(i2o_block_driver.event_queue,
&dreq->work,
I2O_BLOCK_RETRY_TIME))
@@ -1008,6 +1008,7 @@ static struct i2o_block_device *i2o_block_device_alloc(void)
}
blk_queue_prep_rq(queue, i2o_block_prep_req_fn);
+ blk_queue_issue_flush_fn(queue, i2o_block_issue_flush);
gd->major = I2O_MAJOR;
gd->queue = queue;
@@ -1040,17 +1041,27 @@ static struct i2o_block_device *i2o_block_device_alloc(void)
static int i2o_block_probe(struct device *dev)
{
struct i2o_device *i2o_dev = to_i2o_device(dev);
- struct i2o_block_device *i2o_blk_dev;
struct i2o_controller *c = i2o_dev->iop;
+ struct i2o_block_device *i2o_blk_dev;
struct gendisk *gd;
struct request_queue *queue;
static int unit = 0;
int rc;
u64 size;
u32 blocksize;
- u16 power;
u32 flags, status;
- int segments;
+ u16 body_size = 4;
+ unsigned short max_sectors;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (c->adaptec)
+ body_size = 8;
+#endif
+
+ if (c->limit_sectors)
+ max_sectors = I2O_MAX_SECTORS_LIMITED;
+ else
+ max_sectors = I2O_MAX_SECTORS;
/* skip devices which are used by IOP */
if (i2o_dev->lct_data.user_tid != 0xfff) {
@@ -1058,8 +1069,6 @@ static int i2o_block_probe(struct device *dev)
return -ENODEV;
}
- osm_info("New device detected (TID: %03x)\n", i2o_dev->lct_data.tid);
-
if (i2o_device_claim(i2o_dev)) {
osm_warn("Unable to claim device. Installation aborted\n");
rc = -EFAULT;
@@ -1087,50 +1096,44 @@ static int i2o_block_probe(struct device *dev)
queue = gd->queue;
queue->queuedata = i2o_blk_dev;
- blk_queue_max_phys_segments(queue, I2O_MAX_SEGMENTS);
- blk_queue_max_sectors(queue, I2O_MAX_SECTORS);
-
- if (c->short_req)
- segments = 8;
- else {
- i2o_status_block *sb;
+ blk_queue_max_phys_segments(queue, I2O_MAX_PHYS_SEGMENTS);
+ blk_queue_max_sectors(queue, max_sectors);
+ blk_queue_max_hw_segments(queue, i2o_sg_tablesize(c, body_size));
- sb = c->status_block.virt;
-
- segments = (sb->inbound_frame_size -
- sizeof(struct i2o_message) / 4 - 4) / 2;
- }
-
- blk_queue_max_hw_segments(queue, segments);
-
- osm_debug("max sectors = %d\n", I2O_MAX_SECTORS);
- osm_debug("phys segments = %d\n", I2O_MAX_SEGMENTS);
- osm_debug("hw segments = %d\n", segments);
+ osm_debug("max sectors = %d\n", queue->max_phys_segments);
+ osm_debug("phys segments = %d\n", queue->max_sectors);
+ osm_debug("max hw segments = %d\n", queue->max_hw_segments);
/*
* Ask for the current media data. If that isn't supported
* then we ask for the device capacity data
*/
- if (i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) != 0
- || i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) != 0) {
- i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4);
- i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8);
- }
- osm_debug("blocksize = %d\n", blocksize);
+ if (i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) ||
+ i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4)) {
+ blk_queue_hardsect_size(queue, blocksize);
+ } else
+ osm_warn("unable to get blocksize of %s\n", gd->disk_name);
- if (i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2))
- power = 0;
+ if (i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) ||
+ i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8)) {
+ set_capacity(gd, size >> KERNEL_SECTOR_SHIFT);
+ } else
+ osm_warn("could not get size of %s\n", gd->disk_name);
+
+ if (!i2o_parm_field_get(i2o_dev, 0x0000, 2, &i2o_blk_dev->power, 2))
+ i2o_blk_dev->power = 0;
i2o_parm_field_get(i2o_dev, 0x0000, 5, &flags, 4);
i2o_parm_field_get(i2o_dev, 0x0000, 6, &status, 4);
- set_capacity(gd, size >> 9);
-
i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0xffffffff);
add_disk(gd);
unit++;
+ osm_info("device added (TID: %03x): %s\n", i2o_dev->lct_data.tid,
+ i2o_blk_dev->gd->disk_name);
+
return 0;
claim_release:
@@ -1178,7 +1181,7 @@ static int __init i2o_block_init(void)
goto exit;
}
- i2o_blk_req_pool.pool = mempool_create(I2O_REQ_MEMPOOL_SIZE,
+ i2o_blk_req_pool.pool = mempool_create(I2O_BLOCK_REQ_MEMPOOL_SIZE,
mempool_alloc_slab,
mempool_free_slab,
i2o_blk_req_pool.slab);
diff --git a/drivers/message/i2o/i2o_block.h b/drivers/message/i2o/i2o_block.h
index ddd9a15679c..4fdaa5bda41 100644
--- a/drivers/message/i2o/i2o_block.h
+++ b/drivers/message/i2o/i2o_block.h
@@ -56,42 +56,46 @@
#define I2O_BLOCK_RETRY_TIME HZ/4
#define I2O_BLOCK_MAX_OPEN_REQUESTS 50
+/* request queue sizes */
+#define I2O_BLOCK_REQ_MEMPOOL_SIZE 32
+
+#define KERNEL_SECTOR_SHIFT 9
+#define KERNEL_SECTOR_SIZE (1 << KERNEL_SECTOR_SHIFT)
+
/* I2O Block OSM mempool struct */
struct i2o_block_mempool {
- kmem_cache_t *slab;
- mempool_t *pool;
+ kmem_cache_t *slab;
+ mempool_t *pool;
};
/* I2O Block device descriptor */
struct i2o_block_device {
struct i2o_device *i2o_dev; /* pointer to I2O device */
struct gendisk *gd;
- spinlock_t lock; /* queue lock */
+ spinlock_t lock; /* queue lock */
struct list_head open_queue; /* list of transfered, but unfinished
requests */
unsigned int open_queue_depth; /* number of requests in the queue */
- int rcache; /* read cache flags */
- int wcache; /* write cache flags */
+ int rcache; /* read cache flags */
+ int wcache; /* write cache flags */
int flags;
- int power; /* power state */
- int media_change_flag; /* media changed flag */
+ u16 power; /* power state */
+ int media_change_flag; /* media changed flag */
};
/* I2O Block device request */
-struct i2o_block_request
-{
+struct i2o_block_request {
struct list_head queue;
- struct request *req; /* corresponding request */
+ struct request *req; /* corresponding request */
struct i2o_block_device *i2o_blk_dev; /* I2O block device */
- int sg_dma_direction; /* direction of DMA buffer read/write */
- int sg_nents; /* number of SG elements */
- struct scatterlist sg_table[I2O_MAX_SEGMENTS]; /* SG table */
+ struct device *dev; /* device used for DMA */
+ int sg_nents; /* number of SG elements */
+ struct scatterlist sg_table[I2O_MAX_PHYS_SEGMENTS]; /* SG table */
};
/* I2O Block device delayed request */
-struct i2o_block_delayed_request
-{
+struct i2o_block_delayed_request {
struct work_struct work;
struct request_queue *queue;
};
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 1fb5cdf67f8..3c3a7abebb1 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -30,29 +30,15 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/i2o.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
#include <linux/miscdevice.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
#include <linux/smp_lock.h>
-#include <linux/ioctl32.h>
#include <linux/compat.h>
-#include <linux/syscalls.h>
#include <asm/uaccess.h>
-#include <asm/io.h>
-#define OSM_NAME "config-osm"
-#define OSM_VERSION "$Rev$"
-#define OSM_DESCRIPTION "I2O Configuration OSM"
+#include "core.h"
-extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
+#define SG_TABLESIZE 30
static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
unsigned long arg);
@@ -80,15 +66,6 @@ struct i2o_cfg_info {
static struct i2o_cfg_info *open_files = NULL;
static ulong i2o_cfg_info_id = 0;
-/*
- * Each of these describes an i2o message handler. They are
- * multiplexed by the i2o_core code
- */
-
-static struct i2o_driver i2o_config_driver = {
- .name = OSM_NAME
-};
-
static int i2o_cfg_getiops(unsigned long arg)
{
struct i2o_controller *c;
@@ -391,9 +368,9 @@ static int i2o_cfg_swul(unsigned long arg)
i2o_dma_free(&c->pdev->dev, &buffer);
-return_ret:
+ return_ret:
return ret;
-return_fault:
+ return_fault:
ret = -EFAULT;
goto return_ret;
};
@@ -540,8 +517,10 @@ static int i2o_cfg_evt_get(unsigned long arg, struct file *fp)
return 0;
}
+#ifdef CONFIG_I2O_EXT_ADAPTEC
#ifdef CONFIG_COMPAT
-static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long arg)
+static int i2o_cfg_passthru32(struct file *file, unsigned cmnd,
+ unsigned long arg)
{
struct i2o_cmd_passthru32 __user *cmd;
struct i2o_controller *c;
@@ -555,6 +534,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
u32 sg_offset = 0;
u32 sg_count = 0;
u32 i = 0;
+ u32 sg_index = 0;
i2o_status_block *sb;
struct i2o_message *msg;
u32 m;
@@ -634,8 +614,8 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
if (sg_count > SG_TABLESIZE) {
printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
c->name, sg_count);
- kfree(reply);
- return -EINVAL;
+ rcode = -EINVAL;
+ goto cleanup;
}
for (i = 0; i < sg_count; i++) {
@@ -651,7 +631,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
goto cleanup;
}
sg_size = sg[i].flag_count & 0xffffff;
- p = &(sg_list[i]);
+ p = &(sg_list[sg_index++]);
/* Allocate memory for the transfer */
if (i2o_dma_alloc
(&c->pdev->dev, p, sg_size,
@@ -660,20 +640,21 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
c->name, sg_size, i, sg_count);
rcode = -ENOMEM;
- goto cleanup;
+ goto sg_list_cleanup;
}
/* Copy in the user's SG buffer if necessary */
if (sg[i].
flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
// TODO 64bit fix
if (copy_from_user
- (p->virt, (void __user *)(unsigned long)sg[i].addr_bus,
- sg_size)) {
+ (p->virt,
+ (void __user *)(unsigned long)sg[i].
+ addr_bus, sg_size)) {
printk(KERN_DEBUG
"%s: Could not copy SG buf %d FROM user\n",
c->name, i);
rcode = -EFAULT;
- goto cleanup;
+ goto sg_list_cleanup;
}
}
//TODO 64bit fix
@@ -683,10 +664,10 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
rcode = i2o_msg_post_wait(c, m, 60);
if (rcode)
- goto cleanup;
+ goto sg_list_cleanup;
if (sg_offset) {
- u32 msg[128];
+ u32 msg[I2O_OUTBOUND_MSG_FRAME_SIZE];
/* Copy back the Scatter Gather buffers back to user space */
u32 j;
// TODO 64bit fix
@@ -694,18 +675,18 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
int sg_size;
// re-acquire the original message to handle correctly the sg copy operation
- memset(&msg, 0, MSG_FRAME_SIZE * 4);
+ memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
// get user msg size in u32s
if (get_user(size, &user_msg[0])) {
rcode = -EFAULT;
- goto cleanup;
+ goto sg_list_cleanup;
}
size = size >> 16;
size *= 4;
/* Copy in the user's I2O command */
if (copy_from_user(msg, user_msg, size)) {
rcode = -EFAULT;
- goto cleanup;
+ goto sg_list_cleanup;
}
sg_count =
(size - sg_offset * 4) / sizeof(struct sg_simple_element);
@@ -727,7 +708,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
c->name, sg_list[j].virt,
sg[j].addr_bus);
rcode = -EFAULT;
- goto cleanup;
+ goto sg_list_cleanup;
}
}
}
@@ -741,6 +722,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
"%s: Could not copy message context FROM user\n",
c->name);
rcode = -EFAULT;
+ goto sg_list_cleanup;
}
if (copy_to_user(user_reply, reply, reply_size)) {
printk(KERN_WARNING
@@ -749,16 +731,21 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd, unsigned long ar
}
}
+ sg_list_cleanup:
+ for (i = 0; i < sg_index; i++)
+ i2o_dma_free(&c->pdev->dev, &sg_list[i]);
+
cleanup:
kfree(reply);
return rcode;
}
-static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg)
+static long i2o_cfg_compat_ioctl(struct file *file, unsigned cmd,
+ unsigned long arg)
{
int ret;
- lock_kernel();
- switch (cmd) {
+ lock_kernel();
+ switch (cmd) {
case I2OGETIOPS:
ret = i2o_cfg_ioctl(NULL, file, cmd, arg);
break;
@@ -862,8 +849,8 @@ static int i2o_cfg_passthru(unsigned long arg)
if (sg_count > SG_TABLESIZE) {
printk(KERN_DEBUG "%s:IOCTL SG List too large (%u)\n",
c->name, sg_count);
- kfree(reply);
- return -EINVAL;
+ rcode = -EINVAL;
+ goto cleanup;
}
for (i = 0; i < sg_count; i++) {
@@ -875,7 +862,7 @@ static int i2o_cfg_passthru(unsigned long arg)
"%s:Bad SG element %d - not simple (%x)\n",
c->name, i, sg[i].flag_count);
rcode = -EINVAL;
- goto cleanup;
+ goto sg_list_cleanup;
}
sg_size = sg[i].flag_count & 0xffffff;
/* Allocate memory for the transfer */
@@ -885,7 +872,7 @@ static int i2o_cfg_passthru(unsigned long arg)
"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
c->name, sg_size, i, sg_count);
rcode = -ENOMEM;
- goto cleanup;
+ goto sg_list_cleanup;
}
sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
/* Copy in the user's SG buffer if necessary */
@@ -899,7 +886,7 @@ static int i2o_cfg_passthru(unsigned long arg)
"%s: Could not copy SG buf %d FROM user\n",
c->name, i);
rcode = -EFAULT;
- goto cleanup;
+ goto sg_list_cleanup;
}
}
//TODO 64bit fix
@@ -909,7 +896,7 @@ static int i2o_cfg_passthru(unsigned long arg)
rcode = i2o_msg_post_wait(c, m, 60);
if (rcode)
- goto cleanup;
+ goto sg_list_cleanup;
if (sg_offset) {
u32 msg[128];
@@ -920,18 +907,18 @@ static int i2o_cfg_passthru(unsigned long arg)
int sg_size;
// re-acquire the original message to handle correctly the sg copy operation
- memset(&msg, 0, MSG_FRAME_SIZE * 4);
+ memset(&msg, 0, I2O_OUTBOUND_MSG_FRAME_SIZE * 4);
// get user msg size in u32s
if (get_user(size, &user_msg[0])) {
rcode = -EFAULT;
- goto cleanup;
+ goto sg_list_cleanup;
}
size = size >> 16;
size *= 4;
/* Copy in the user's I2O command */
if (copy_from_user(msg, user_msg, size)) {
rcode = -EFAULT;
- goto cleanup;
+ goto sg_list_cleanup;
}
sg_count =
(size - sg_offset * 4) / sizeof(struct sg_simple_element);
@@ -953,7 +940,7 @@ static int i2o_cfg_passthru(unsigned long arg)
c->name, sg_list[j],
sg[j].addr_bus);
rcode = -EFAULT;
- goto cleanup;
+ goto sg_list_cleanup;
}
}
}
@@ -975,10 +962,15 @@ static int i2o_cfg_passthru(unsigned long arg)
}
}
+ sg_list_cleanup:
+ for (i = 0; i < sg_index; i++)
+ kfree(sg_list[i]);
+
cleanup:
kfree(reply);
return rcode;
}
+#endif
/*
* IOCTL Handler
@@ -1033,9 +1025,11 @@ static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
ret = i2o_cfg_evt_get(arg, fp);
break;
+#ifdef CONFIG_I2O_EXT_ADAPTEC
case I2OPASSTHRU:
ret = i2o_cfg_passthru(arg);
break;
+#endif
default:
osm_debug("unknown ioctl called!\n");
@@ -1137,37 +1131,21 @@ static struct miscdevice i2o_miscdev = {
&config_fops
};
-static int __init i2o_config_init(void)
+static int __init i2o_config_old_init(void)
{
- printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
-
spin_lock_init(&i2o_config_lock);
if (misc_register(&i2o_miscdev) < 0) {
osm_err("can't register device.\n");
return -EBUSY;
}
- /*
- * Install our handler
- */
- if (i2o_driver_register(&i2o_config_driver)) {
- osm_err("handler register failed.\n");
- misc_deregister(&i2o_miscdev);
- return -EBUSY;
- }
+
return 0;
}
-static void i2o_config_exit(void)
+static void i2o_config_old_exit(void)
{
misc_deregister(&i2o_miscdev);
- i2o_driver_unregister(&i2o_config_driver);
}
MODULE_AUTHOR("Red Hat Software");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION(OSM_DESCRIPTION);
-MODULE_VERSION(OSM_VERSION);
-
-module_init(i2o_config_init);
-module_exit(i2o_config_exit);
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index b176d0eeff7..d559a175836 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -28,7 +28,7 @@
*/
#define OSM_NAME "proc-osm"
-#define OSM_VERSION "$Rev$"
+#define OSM_VERSION "1.145"
#define OSM_DESCRIPTION "I2O ProcFS OSM"
#define I2O_MAX_MODULES 4
@@ -228,7 +228,7 @@ static const char *i2o_get_class_name(int class)
case I2O_CLASS_FLOPPY_DEVICE:
idx = 12;
break;
- case I2O_CLASS_BUS_ADAPTER_PORT:
+ case I2O_CLASS_BUS_ADAPTER:
idx = 13;
break;
case I2O_CLASS_PEER_TRANSPORT_AGENT:
@@ -490,7 +490,7 @@ static int i2o_seq_show_lct(struct seq_file *seq, void *v)
seq_printf(seq, ", Unknown Device Type");
break;
- case I2O_CLASS_BUS_ADAPTER_PORT:
+ case I2O_CLASS_BUS_ADAPTER:
if (lct->lct_entry[i].sub_class < BUS_TABLE_SIZE)
seq_printf(seq, ", %s",
bus_ports[lct->lct_entry[i].
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index 43f5875e0be..9f1744c3933 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -54,6 +54,7 @@
#include <linux/pci.h>
#include <linux/blkdev.h>
#include <linux/i2o.h>
+#include <linux/scatterlist.h>
#include <asm/dma.h>
#include <asm/system.h>
@@ -64,19 +65,23 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_request.h>
+#include <scsi/sg.h>
+#include <scsi/sg_request.h>
#define OSM_NAME "scsi-osm"
-#define OSM_VERSION "$Rev$"
+#define OSM_VERSION "1.282"
#define OSM_DESCRIPTION "I2O SCSI Peripheral OSM"
static struct i2o_driver i2o_scsi_driver;
-static int i2o_scsi_max_id = 16;
-static int i2o_scsi_max_lun = 8;
+static unsigned int i2o_scsi_max_id = 16;
+static unsigned int i2o_scsi_max_lun = 255;
struct i2o_scsi_host {
struct Scsi_Host *scsi_host; /* pointer to the SCSI host */
struct i2o_controller *iop; /* pointer to the I2O controller */
+ unsigned int lun; /* lun's used for block devices */
struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */
};
@@ -99,11 +104,17 @@ static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c)
u8 type;
int i;
size_t size;
- i2o_status_block *sb;
+ u16 body_size = 6;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (c->adaptec)
+ body_size = 8;
+#endif
list_for_each_entry(i2o_dev, &c->devices, list)
- if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT) {
- if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) || (type == 1)) /* SCSI bus */
+ if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
+ if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
+ && (type == 0x01)) /* SCSI bus */
max_channel++;
}
@@ -125,20 +136,18 @@ static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c)
scsi_host->max_id = i2o_scsi_max_id;
scsi_host->max_lun = i2o_scsi_max_lun;
scsi_host->this_id = c->unit;
-
- sb = c->status_block.virt;
-
- scsi_host->sg_tablesize = (sb->inbound_frame_size -
- sizeof(struct i2o_message) / 4 - 6) / 2;
+ scsi_host->sg_tablesize = i2o_sg_tablesize(c, body_size);
i2o_shost = (struct i2o_scsi_host *)scsi_host->hostdata;
i2o_shost->scsi_host = scsi_host;
i2o_shost->iop = c;
+ i2o_shost->lun = 1;
i = 0;
list_for_each_entry(i2o_dev, &c->devices, list)
- if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT) {
- if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1) || (type == 1)) /* only SCSI bus */
+ if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
+ if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
+ && (type == 0x01)) /* only SCSI bus */
i2o_shost->channel[i++] = i2o_dev;
if (i >= max_channel)
@@ -178,10 +187,13 @@ static int i2o_scsi_remove(struct device *dev)
struct i2o_scsi_host *i2o_shost;
struct scsi_device *scsi_dev;
+ osm_info("device removed (TID: %03x)\n", i2o_dev->lct_data.tid);
+
i2o_shost = i2o_scsi_get_host(c);
shost_for_each_device(scsi_dev, i2o_shost->scsi_host)
if (scsi_dev->hostdata == i2o_dev) {
+ sysfs_remove_link(&i2o_dev->device.kobj, "scsi");
scsi_remove_device(scsi_dev);
scsi_device_put(scsi_dev);
break;
@@ -207,8 +219,8 @@ static int i2o_scsi_probe(struct device *dev)
struct Scsi_Host *scsi_host;
struct i2o_device *parent;
struct scsi_device *scsi_dev;
- u32 id;
- u64 lun;
+ u32 id = -1;
+ u64 lun = -1;
int channel = -1;
int i;
@@ -218,8 +230,56 @@ static int i2o_scsi_probe(struct device *dev)
scsi_host = i2o_shost->scsi_host;
- if (i2o_parm_field_get(i2o_dev, 0, 3, &id, 4) < 0)
+ switch (i2o_dev->lct_data.class_id) {
+ case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+ case I2O_CLASS_EXECUTIVE:
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (c->adaptec) {
+ u8 type;
+ struct i2o_device *d = i2o_shost->channel[0];
+
+ if (i2o_parm_field_get(d, 0x0000, 0, &type, 1)
+ && (type == 0x01)) /* SCSI bus */
+ if (i2o_parm_field_get(d, 0x0200, 4, &id, 4)) {
+ channel = 0;
+ if (i2o_dev->lct_data.class_id ==
+ I2O_CLASS_RANDOM_BLOCK_STORAGE)
+ lun = i2o_shost->lun++;
+ else
+ lun = 0;
+ }
+ }
+#endif
+ break;
+
+ case I2O_CLASS_SCSI_PERIPHERAL:
+ if (i2o_parm_field_get(i2o_dev, 0x0000, 3, &id, 4) < 0)
+ return -EFAULT;
+
+ if (i2o_parm_field_get(i2o_dev, 0x0000, 4, &lun, 8) < 0)
+ return -EFAULT;
+
+ parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid);
+ if (!parent) {
+ osm_warn("can not find parent of device %03x\n",
+ i2o_dev->lct_data.tid);
+ return -EFAULT;
+ }
+
+ for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++)
+ if (i2o_shost->channel[i] == parent)
+ channel = i;
+ break;
+
+ default:
return -EFAULT;
+ }
+
+ if (channel == -1) {
+ osm_warn("can not find channel of device %03x\n",
+ i2o_dev->lct_data.tid);
+ return -EFAULT;
+ }
if (id >= scsi_host->max_id) {
osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", id,
@@ -227,42 +287,26 @@ static int i2o_scsi_probe(struct device *dev)
return -EFAULT;
}
- if (i2o_parm_field_get(i2o_dev, 0, 4, &lun, 8) < 0)
- return -EFAULT;
if (lun >= scsi_host->max_lun) {
osm_warn("SCSI device id (%d) >= max_lun of I2O host (%d)",
(unsigned int)lun, scsi_host->max_lun);
return -EFAULT;
}
- parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid);
- if (!parent) {
- osm_warn("can not find parent of device %03x\n",
- i2o_dev->lct_data.tid);
- return -EFAULT;
- }
-
- for (i = 0; i <= i2o_shost->scsi_host->max_channel; i++)
- if (i2o_shost->channel[i] == parent)
- channel = i;
-
- if (channel == -1) {
- osm_warn("can not find channel of device %03x\n",
- i2o_dev->lct_data.tid);
- return -EFAULT;
- }
-
scsi_dev =
__scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev);
- if (!scsi_dev) {
+ if (IS_ERR(scsi_dev)) {
osm_warn("can not add SCSI device %03x\n",
i2o_dev->lct_data.tid);
- return -EFAULT;
+ return PTR_ERR(scsi_dev);
}
- osm_debug("added new SCSI device %03x (cannel: %d, id: %d, lun: %d)\n",
- i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
+ sysfs_create_link(&i2o_dev->device.kobj, &scsi_dev->sdev_gendev.kobj,
+ "scsi");
+
+ osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %d\n",
+ i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
return 0;
};
@@ -293,162 +337,89 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
struct i2o_message *msg)
{
struct scsi_cmnd *cmd;
+ u32 error;
struct device *dev;
- u8 as, ds, st;
cmd = i2o_cntxt_list_get(c, le32_to_cpu(msg->u.s.tcntxt));
-
- if (msg->u.head[0] & (1 << 13)) {
- struct i2o_message __iomem *pmsg; /* preserved message */
- u32 pm;
- int err = DID_ERROR;
-
- pm = le32_to_cpu(msg->body[3]);
-
- pmsg = i2o_msg_in_to_virt(c, pm);
-
- osm_err("IOP fail.\n");
- osm_err("From %d To %d Cmd %d.\n",
- (msg->u.head[1] >> 12) & 0xFFF,
- msg->u.head[1] & 0xFFF, msg->u.head[1] >> 24);
- osm_err("Failure Code %d.\n", msg->body[0] >> 24);
- if (msg->body[0] & (1 << 16))
- osm_err("Format error.\n");
- if (msg->body[0] & (1 << 17))
- osm_err("Path error.\n");
- if (msg->body[0] & (1 << 18))
- osm_err("Path State.\n");
- if (msg->body[0] & (1 << 18))
- {
- osm_err("Congestion.\n");
- err = DID_BUS_BUSY;
- }
-
- osm_debug("Failing message is %p.\n", pmsg);
-
- cmd = i2o_cntxt_list_get(c, readl(&pmsg->u.s.tcntxt));
- if (!cmd)
- return 1;
-
- cmd->result = err << 16;
- cmd->scsi_done(cmd);
-
- /* Now flush the message by making it a NOP */
- i2o_msg_nop(c, pm);
-
- return 1;
+ if (unlikely(!cmd)) {
+ osm_err("NULL reply received!\n");
+ return -1;
}
/*
* Low byte is device status, next is adapter status,
* (then one byte reserved), then request status.
*/
- ds = (u8) le32_to_cpu(msg->body[0]);
- as = (u8) (le32_to_cpu(msg->body[0]) >> 8);
- st = (u8) (le32_to_cpu(msg->body[0]) >> 24);
+ error = le32_to_cpu(msg->body[0]);
+
+ osm_debug("Completed %ld\n", cmd->serial_number);
+ cmd->result = error & 0xff;
/*
- * Is this a control request coming back - eg an abort ?
+ * if DeviceStatus is not SCSI_SUCCESS copy over the sense data and let
+ * the SCSI layer handle the error
*/
+ if (cmd->result)
+ memcpy(cmd->sense_buffer, &msg->body[3],
+ min(sizeof(cmd->sense_buffer), (size_t) 40));
- if (!cmd) {
- if (st)
- osm_warn("SCSI abort: %08X", le32_to_cpu(msg->body[0]));
- osm_info("SCSI abort completed.\n");
- return -EFAULT;
- }
+ /* only output error code if AdapterStatus is not HBA_SUCCESS */
+ if ((error >> 8) & 0xff)
+ osm_err("SCSI error %08x\n", error);
- osm_debug("Completed %ld\n", cmd->serial_number);
+ dev = &c->pdev->dev;
+ if (cmd->use_sg)
+ dma_unmap_sg(dev, cmd->request_buffer, cmd->use_sg,
+ cmd->sc_data_direction);
+ else if (cmd->SCp.dma_handle)
+ dma_unmap_single(dev, cmd->SCp.dma_handle, cmd->request_bufflen,
+ cmd->sc_data_direction);
- if (st) {
- u32 count, error;
- /* An error has occurred */
-
- switch (st) {
- case 0x06:
- count = le32_to_cpu(msg->body[1]);
- if (count < cmd->underflow) {
- int i;
-
- osm_err("SCSI underflow 0x%08X 0x%08X\n", count,
- cmd->underflow);
- osm_debug("Cmd: ");
- for (i = 0; i < 15; i++)
- pr_debug("%02X ", cmd->cmnd[i]);
- pr_debug(".\n");
- cmd->result = (DID_ERROR << 16);
- }
- break;
+ cmd->scsi_done(cmd);
- default:
- error = le32_to_cpu(msg->body[0]);
-
- osm_err("SCSI error %08x\n", error);
-
- if ((error & 0xff) == 0x02 /*CHECK_CONDITION */ ) {
- int i;
- u32 len = sizeof(cmd->sense_buffer);
- len = (len > 40) ? 40 : len;
- // Copy over the sense data
- memcpy(cmd->sense_buffer, (void *)&msg->body[3],
- len);
- for (i = 0; i <= len; i++)
- osm_info("%02x\n",
- cmd->sense_buffer[i]);
- if (cmd->sense_buffer[0] == 0x70
- && cmd->sense_buffer[2] == DATA_PROTECT) {
- /* This is to handle an array failed */
- cmd->result = (DID_TIME_OUT << 16);
- printk(KERN_WARNING "%s: SCSI Data "
- "Protect-Device (%d,%d,%d) "
- "hba_status=0x%x, dev_status="
- "0x%x, cmd=0x%x\n", c->name,
- (u32) cmd->device->channel,
- (u32) cmd->device->id,
- (u32) cmd->device->lun,
- (error >> 8) & 0xff,
- error & 0xff, cmd->cmnd[0]);
- } else
- cmd->result = (DID_ERROR << 16);
-
- break;
- }
-
- switch (as) {
- case 0x0E:
- /* SCSI Reset */
- cmd->result = DID_RESET << 16;
- break;
-
- case 0x0F:
- cmd->result = DID_PARITY << 16;
- break;
-
- default:
- cmd->result = DID_ERROR << 16;
- break;
- }
+ return 1;
+};
- break;
- }
+/**
+ * i2o_scsi_notify_device_add - Retrieve notifications of added devices
+ * @i2o_dev: the I2O device which was added
+ *
+ * If a I2O device is added we catch the notification, because I2O classes
+ * other then SCSI peripheral will not be received through
+ * i2o_scsi_probe().
+ */
+static void i2o_scsi_notify_device_add(struct i2o_device *i2o_dev)
+{
+ switch (i2o_dev->lct_data.class_id) {
+ case I2O_CLASS_EXECUTIVE:
+ case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+ i2o_scsi_probe(&i2o_dev->device);
+ break;
- cmd->scsi_done(cmd);
- return 1;
+ default:
+ break;
}
+};
- cmd->result = DID_OK << 16 | ds;
-
- cmd->scsi_done(cmd);
-
- dev = &c->pdev->dev;
- if (cmd->use_sg)
- dma_unmap_sg(dev, (struct scatterlist *)cmd->buffer,
- cmd->use_sg, cmd->sc_data_direction);
- else if (cmd->request_bufflen)
- dma_unmap_single(dev, (dma_addr_t) ((long)cmd->SCp.ptr),
- cmd->request_bufflen, cmd->sc_data_direction);
+/**
+ * i2o_scsi_notify_device_remove - Retrieve notifications of removed
+ * devices
+ * @i2o_dev: the I2O device which was removed
+ *
+ * If a I2O device is removed, we catch the notification to remove the
+ * corresponding SCSI device.
+ */
+static void i2o_scsi_notify_device_remove(struct i2o_device *i2o_dev)
+{
+ switch (i2o_dev->lct_data.class_id) {
+ case I2O_CLASS_EXECUTIVE:
+ case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+ i2o_scsi_remove(&i2o_dev->device);
+ break;
- return 1;
+ default:
+ break;
+ }
};
/**
@@ -501,7 +472,7 @@ static void i2o_scsi_notify_controller_remove(struct i2o_controller *c)
scsi_remove_host(i2o_shost->scsi_host);
scsi_host_put(i2o_shost->scsi_host);
- pr_info("I2O SCSI host removed\n");
+ osm_debug("I2O SCSI host removed\n");
};
/* SCSI OSM driver struct */
@@ -509,6 +480,8 @@ static struct i2o_driver i2o_scsi_driver = {
.name = OSM_NAME,
.reply = i2o_scsi_reply,
.classes = i2o_scsi_class_id,
+ .notify_device_add = i2o_scsi_notify_device_add,
+ .notify_device_remove = i2o_scsi_notify_device_remove,
.notify_controller_add = i2o_scsi_notify_controller_add,
.notify_controller_remove = i2o_scsi_notify_controller_remove,
.driver = {
@@ -535,26 +508,26 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
void (*done) (struct scsi_cmnd *))
{
struct i2o_controller *c;
- struct Scsi_Host *host;
struct i2o_device *i2o_dev;
- struct device *dev;
int tid;
struct i2o_message __iomem *msg;
u32 m;
- u32 scsi_flags, sg_flags;
+ /*
+ * ENABLE_DISCONNECT
+ * SIMPLE_TAG
+ * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME
+ */
+ u32 scsi_flags = 0x20a00000;
+ u32 sgl_offset;
u32 __iomem *mptr;
- u32 __iomem *lenptr;
- u32 len, reqlen;
- int i;
+ u32 cmd = I2O_CMD_SCSI_EXEC << 24;
+ int rc = 0;
/*
* Do the incoming paperwork
*/
-
i2o_dev = SCpnt->device->hostdata;
- host = SCpnt->device->host;
c = i2o_dev->iop;
- dev = &c->pdev->dev;
SCpnt->scsi_done = done;
@@ -562,7 +535,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
osm_warn("no I2O device in request\n");
SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt);
- return 0;
+ goto exit;
}
tid = i2o_dev->lct_data.tid;
@@ -571,44 +544,85 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
osm_debug("Real scsi messages.\n");
/*
- * Obtain an I2O message. If there are none free then
- * throw it back to the scsi layer
- */
-
- m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
- if (m == I2O_QUEUE_EMPTY)
- return SCSI_MLQUEUE_HOST_BUSY;
-
- /*
* Put together a scsi execscb message
*/
-
- len = SCpnt->request_bufflen;
-
switch (SCpnt->sc_data_direction) {
case PCI_DMA_NONE:
- scsi_flags = 0x00000000; // DATA NO XFER
- sg_flags = 0x00000000;
+ /* DATA NO XFER */
+ sgl_offset = SGL_OFFSET_0;
break;
case PCI_DMA_TODEVICE:
- scsi_flags = 0x80000000; // DATA OUT (iop-->dev)
- sg_flags = 0x14000000;
+ /* DATA OUT (iop-->dev) */
+ scsi_flags |= 0x80000000;
+ sgl_offset = SGL_OFFSET_10;
break;
case PCI_DMA_FROMDEVICE:
- scsi_flags = 0x40000000; // DATA IN (iop<--dev)
- sg_flags = 0x10000000;
+ /* DATA IN (iop<--dev) */
+ scsi_flags |= 0x40000000;
+ sgl_offset = SGL_OFFSET_10;
break;
default:
/* Unknown - kill the command */
SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt);
- return 0;
+ goto exit;
}
- writel(I2O_CMD_SCSI_EXEC << 24 | HOST_TID << 12 | tid, &msg->u.head[1]);
+ /*
+ * Obtain an I2O message. If there are none free then
+ * throw it back to the scsi layer
+ */
+
+ m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
+ if (m == I2O_QUEUE_EMPTY) {
+ rc = SCSI_MLQUEUE_HOST_BUSY;
+ goto exit;
+ }
+
+ mptr = &msg->body[0];
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC
+ if (c->adaptec) {
+ u32 adpt_flags = 0;
+
+ if (SCpnt->sc_request && SCpnt->sc_request->upper_private_data) {
+ i2o_sg_io_hdr_t __user *usr_ptr =
+ ((Sg_request *) (SCpnt->sc_request->
+ upper_private_data))->header.
+ usr_ptr;
+
+ if (usr_ptr)
+ get_user(adpt_flags, &usr_ptr->flags);
+ }
+
+ switch (i2o_dev->lct_data.class_id) {
+ case I2O_CLASS_EXECUTIVE:
+ case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+ /* interpret flag has to be set for executive */
+ adpt_flags ^= I2O_DPT_SG_FLAG_INTERPRET;
+ break;
+
+ default:
+ break;
+ }
+
+ /*
+ * for Adaptec controllers we use the PRIVATE command, because
+ * the normal SCSI EXEC doesn't support all SCSI commands on
+ * all controllers (for example READ CAPACITY).
+ */
+ if (sgl_offset == SGL_OFFSET_10)
+ sgl_offset = SGL_OFFSET_12;
+ cmd = I2O_CMD_PRIVATE << 24;
+ writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++);
+ writel(adpt_flags | tid, mptr++);
+ }
+#endif
+
+ writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]);
writel(i2o_scsi_driver.context, &msg->u.s.icntxt);
/* We want the SCSI control block back */
@@ -626,7 +640,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
*/
/* Attach tags to the devices */
- /*
+ /* FIXME: implement
if(SCpnt->device->tagged_supported) {
if(SCpnt->tag == HEAD_OF_QUEUE_TAG)
scsi_flags |= 0x01000000;
@@ -635,67 +649,35 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
}
*/
- /* Direction, disconnect ok, tag, CDBLen */
- writel(scsi_flags | 0x20200000 | SCpnt->cmd_len, &msg->body[0]);
-
- mptr = &msg->body[1];
+ writel(scsi_flags | SCpnt->cmd_len, mptr++);
/* Write SCSI command into the message - always 16 byte block */
memcpy_toio(mptr, SCpnt->cmnd, 16);
mptr += 4;
- lenptr = mptr++; /* Remember me - fill in when we know */
-
- reqlen = 12; // SINGLE SGE
-
- /* Now fill in the SGList and command */
- if (SCpnt->use_sg) {
- struct scatterlist *sg;
- int sg_count;
-
- sg = SCpnt->request_buffer;
- len = 0;
-
- sg_count = dma_map_sg(dev, sg, SCpnt->use_sg,
- SCpnt->sc_data_direction);
- if (unlikely(sg_count <= 0))
- return -ENOMEM;
-
- for (i = SCpnt->use_sg; i > 0; i--) {
- if (i == 1)
- sg_flags |= 0xC0000000;
- writel(sg_flags | sg_dma_len(sg), mptr++);
- writel(sg_dma_address(sg), mptr++);
- len += sg_dma_len(sg);
- sg++;
+ if (sgl_offset != SGL_OFFSET_0) {
+ /* write size of data addressed by SGL */
+ writel(SCpnt->request_bufflen, mptr++);
+
+ /* Now fill in the SGList and command */
+ if (SCpnt->use_sg) {
+ if (!i2o_dma_map_sg(c, SCpnt->request_buffer,
+ SCpnt->use_sg,
+ SCpnt->sc_data_direction, &mptr))
+ goto nomem;
+ } else {
+ SCpnt->SCp.dma_handle =
+ i2o_dma_map_single(c, SCpnt->request_buffer,
+ SCpnt->request_bufflen,
+ SCpnt->sc_data_direction, &mptr);
+ if (dma_mapping_error(SCpnt->SCp.dma_handle))
+ goto nomem;
}
-
- reqlen = mptr - &msg->u.head[0];
- writel(len, lenptr);
- } else {
- len = SCpnt->request_bufflen;
-
- writel(len, lenptr);
-
- if (len > 0) {
- dma_addr_t dma_addr;
-
- dma_addr = dma_map_single(dev, SCpnt->request_buffer,
- SCpnt->request_bufflen,
- SCpnt->sc_data_direction);
- if (!dma_addr)
- return -ENOMEM;
-
- SCpnt->SCp.ptr = (void *)(unsigned long)dma_addr;
- sg_flags |= 0xC0000000;
- writel(sg_flags | SCpnt->request_bufflen, mptr++);
- writel(dma_addr, mptr++);
- } else
- reqlen = 9;
}
/* Stick the headers on */
- writel(reqlen << 16 | SGL_OFFSET_10, &msg->u.head[0]);
+ writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset,
+ &msg->u.head[0]);
/* Queue the message */
i2o_msg_post(c, m);
@@ -703,6 +685,13 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
osm_debug("Issued %ld\n", SCpnt->serial_number);
return 0;
+
+ nomem:
+ rc = -ENOMEM;
+ i2o_msg_nop(c, m);
+
+ exit:
+ return rc;
};
/**
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 50c8cedf7a2..42f8b810d6e 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -28,8 +28,10 @@
#include <linux/module.h>
#include <linux/i2o.h>
#include <linux/delay.h>
+#include "core.h"
-#define OSM_VERSION "$Rev$"
+#define OSM_NAME "i2o"
+#define OSM_VERSION "1.288"
#define OSM_DESCRIPTION "I2O subsystem"
/* global I2O controller list */
@@ -43,20 +45,6 @@ static struct i2o_dma i2o_systab;
static int i2o_hrt_get(struct i2o_controller *c);
-/* Module internal functions from other sources */
-extern struct i2o_driver i2o_exec_driver;
-extern int i2o_exec_lct_get(struct i2o_controller *);
-extern void i2o_device_remove(struct i2o_device *);
-
-extern int __init i2o_driver_init(void);
-extern void __exit i2o_driver_exit(void);
-extern int __init i2o_exec_init(void);
-extern void __exit i2o_exec_exit(void);
-extern int __init i2o_pci_init(void);
-extern void __exit i2o_pci_exit(void);
-extern int i2o_device_init(void);
-extern void i2o_device_exit(void);
-
/**
* i2o_msg_nop - Returns a message which is not used
* @c: I2O controller from which the message was created
@@ -68,7 +56,7 @@ extern void i2o_device_exit(void);
*/
void i2o_msg_nop(struct i2o_controller *c, u32 m)
{
- struct i2o_message __iomem *msg = c->in_queue.virt + m;
+ struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
writel(THREE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
writel(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID,
@@ -92,16 +80,16 @@ void i2o_msg_nop(struct i2o_controller *c, u32 m)
* address from the read port (see the i2o spec). If no message is
* available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
*/
-u32 i2o_msg_get_wait(struct i2o_controller *c, struct i2o_message __iomem **msg,
- int wait)
+u32 i2o_msg_get_wait(struct i2o_controller *c,
+ struct i2o_message __iomem ** msg, int wait)
{
unsigned long timeout = jiffies + wait * HZ;
u32 m;
while ((m = i2o_msg_get(c, msg)) == I2O_QUEUE_EMPTY) {
if (time_after(jiffies, timeout)) {
- pr_debug("%s: Timeout waiting for message frame.\n",
- c->name);
+ osm_debug("%s: Timeout waiting for message frame.\n",
+ c->name);
return I2O_QUEUE_EMPTY;
}
set_current_state(TASK_UNINTERRUPTIBLE);
@@ -129,13 +117,13 @@ u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr)
unsigned long flags;
if (!ptr)
- printk(KERN_ERR "%s: couldn't add NULL pointer to context list!"
- "\n", c->name);
+ osm_err("%s: couldn't add NULL pointer to context list!\n",
+ c->name);
entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
if (!entry) {
- printk(KERN_ERR "%s: Could not allocate memory for context "
- "list element\n", c->name);
+ osm_err("%s: Could not allocate memory for context list element"
+ "\n", c->name);
return 0;
}
@@ -154,7 +142,7 @@ u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr)
spin_unlock_irqrestore(&c->context_list_lock, flags);
- pr_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context);
+ osm_debug("%s: Add context to list %p -> %d\n", c->name, ptr, context);
return entry->context;
};
@@ -186,11 +174,11 @@ u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr)
spin_unlock_irqrestore(&c->context_list_lock, flags);
if (!context)
- printk(KERN_WARNING "%s: Could not remove nonexistent ptr "
- "%p\n", c->name, ptr);
+ osm_warn("%s: Could not remove nonexistent ptr %p\n", c->name,
+ ptr);
- pr_debug("%s: remove ptr from context list %d -> %p\n", c->name,
- context, ptr);
+ osm_debug("%s: remove ptr from context list %d -> %p\n", c->name,
+ context, ptr);
return context;
};
@@ -220,11 +208,10 @@ void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context)
spin_unlock_irqrestore(&c->context_list_lock, flags);
if (!ptr)
- printk(KERN_WARNING "%s: context id %d not found\n", c->name,
- context);
+ osm_warn("%s: context id %d not found\n", c->name, context);
- pr_debug("%s: get ptr from context list %d -> %p\n", c->name, context,
- ptr);
+ osm_debug("%s: get ptr from context list %d -> %p\n", c->name, context,
+ ptr);
return ptr;
};
@@ -252,11 +239,11 @@ u32 i2o_cntxt_list_get_ptr(struct i2o_controller * c, void *ptr)
spin_unlock_irqrestore(&c->context_list_lock, flags);
if (!context)
- printk(KERN_WARNING "%s: Could not find nonexistent ptr "
- "%p\n", c->name, ptr);
+ osm_warn("%s: Could not find nonexistent ptr %p\n", c->name,
+ ptr);
- pr_debug("%s: get context id from context list %p -> %d\n", c->name,
- ptr, context);
+ osm_debug("%s: get context id from context list %p -> %d\n", c->name,
+ ptr, context);
return context;
};
@@ -336,10 +323,9 @@ static int i2o_iop_quiesce(struct i2o_controller *c)
/* Long timeout needed for quiesce if lots of devices */
if ((rc = i2o_msg_post_wait(c, m, 240)))
- printk(KERN_INFO "%s: Unable to quiesce (status=%#x).\n",
- c->name, -rc);
+ osm_info("%s: Unable to quiesce (status=%#x).\n", c->name, -rc);
else
- pr_debug("%s: Quiesced.\n", c->name);
+ osm_debug("%s: Quiesced.\n", c->name);
i2o_status_get(c); // Entered READY state
@@ -377,10 +363,9 @@ static int i2o_iop_enable(struct i2o_controller *c)
/* How long of a timeout do we need? */
if ((rc = i2o_msg_post_wait(c, m, 240)))
- printk(KERN_ERR "%s: Could not enable (status=%#x).\n",
- c->name, -rc);
+ osm_err("%s: Could not enable (status=%#x).\n", c->name, -rc);
else
- pr_debug("%s: Enabled.\n", c->name);
+ osm_debug("%s: Enabled.\n", c->name);
i2o_status_get(c); // entered OPERATIONAL state
@@ -444,20 +429,78 @@ static int i2o_iop_clear(struct i2o_controller *c)
&msg->u.head[1]);
if ((rc = i2o_msg_post_wait(c, m, 30)))
- printk(KERN_INFO "%s: Unable to clear (status=%#x).\n",
- c->name, -rc);
+ osm_info("%s: Unable to clear (status=%#x).\n", c->name, -rc);
else
- pr_debug("%s: Cleared.\n", c->name);
+ osm_debug("%s: Cleared.\n", c->name);
/* Enable all IOPs */
i2o_iop_enable_all();
- i2o_status_get(c);
-
return rc;
}
/**
+ * i2o_iop_init_outbound_queue - setup the outbound message queue
+ * @c: I2O controller
+ *
+ * Clear and (re)initialize IOP's outbound queue and post the message
+ * frames to the IOP.
+ *
+ * Returns 0 on success or a negative errno code on failure.
+ */
+static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
+{
+ volatile u8 *status = c->status.virt;
+ u32 m;
+ struct i2o_message __iomem *msg;
+ ulong timeout;
+ int i;
+
+ osm_debug("%s: Initializing Outbound Queue...\n", c->name);
+
+ memset(c->status.virt, 0, 4);
+
+ m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
+ if (m == I2O_QUEUE_EMPTY)
+ return -ETIMEDOUT;
+
+ writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]);
+ writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID,
+ &msg->u.head[1]);
+ writel(i2o_exec_driver.context, &msg->u.s.icntxt);
+ writel(0x00000000, &msg->u.s.tcntxt);
+ writel(PAGE_SIZE, &msg->body[0]);
+ /* Outbound msg frame size in words and Initcode */
+ writel(I2O_OUTBOUND_MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]);
+ writel(0xd0000004, &msg->body[2]);
+ writel(i2o_dma_low(c->status.phys), &msg->body[3]);
+ writel(i2o_dma_high(c->status.phys), &msg->body[4]);
+
+ i2o_msg_post(c, m);
+
+ timeout = jiffies + I2O_TIMEOUT_INIT_OUTBOUND_QUEUE * HZ;
+ while (*status <= I2O_CMD_IN_PROGRESS) {
+ if (time_after(jiffies, timeout)) {
+ osm_warn("%s: Timeout Initializing\n", c->name);
+ return -ETIMEDOUT;
+ }
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+
+ m = c->out_queue.phys;
+
+ /* Post frames */
+ for (i = 0; i < I2O_MAX_OUTBOUND_MSG_FRAMES; i++) {
+ i2o_flush_reply(c, m);
+ udelay(1); /* Promise */
+ m += I2O_OUTBOUND_MSG_FRAME_SIZE * sizeof(u32);
+ }
+
+ return 0;
+}
+
+/**
* i2o_iop_reset - reset an I2O controller
* @c: controller to reset
*
@@ -468,20 +511,20 @@ static int i2o_iop_clear(struct i2o_controller *c)
*/
static int i2o_iop_reset(struct i2o_controller *c)
{
- u8 *status = c->status.virt;
+ volatile u8 *status = c->status.virt;
struct i2o_message __iomem *msg;
u32 m;
unsigned long timeout;
i2o_status_block *sb = c->status_block.virt;
int rc = 0;
- pr_debug("%s: Resetting controller\n", c->name);
+ osm_debug("%s: Resetting controller\n", c->name);
m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
if (m == I2O_QUEUE_EMPTY)
return -ETIMEDOUT;
- memset(status, 0, 8);
+ memset(c->status_block.virt, 0, 8);
/* Quiesce all IOPs first */
i2o_iop_quiesce_all();
@@ -493,49 +536,43 @@ static int i2o_iop_reset(struct i2o_controller *c)
writel(0, &msg->u.s.tcntxt); //FIXME: use reasonable transaction context
writel(0, &msg->body[0]);
writel(0, &msg->body[1]);
- writel(i2o_ptr_low((void *)c->status.phys), &msg->body[2]);
- writel(i2o_ptr_high((void *)c->status.phys), &msg->body[3]);
+ writel(i2o_dma_low(c->status.phys), &msg->body[2]);
+ writel(i2o_dma_high(c->status.phys), &msg->body[3]);
i2o_msg_post(c, m);
/* Wait for a reply */
timeout = jiffies + I2O_TIMEOUT_RESET * HZ;
while (!*status) {
- if (time_after(jiffies, timeout)) {
- printk(KERN_ERR "%s: IOP reset timeout.\n", c->name);
- rc = -ETIMEDOUT;
- goto exit;
- }
-
- /* Promise bug */
- if (status[1] || status[4]) {
- *status = 0;
+ if (time_after(jiffies, timeout))
break;
- }
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
-
- rmb();
}
- if (*status == I2O_CMD_IN_PROGRESS) {
+ switch (*status) {
+ case I2O_CMD_REJECTED:
+ osm_warn("%s: IOP reset rejected\n", c->name);
+ rc = -EPERM;
+ break;
+
+ case I2O_CMD_IN_PROGRESS:
/*
* Once the reset is sent, the IOP goes into the INIT state
- * which is indeterminate. We need to wait until the IOP
- * has rebooted before we can let the system talk to
- * it. We read the inbound Free_List until a message is
- * available. If we can't read one in the given ammount of
- * time, we assume the IOP could not reboot properly.
+ * which is indeterminate. We need to wait until the IOP has
+ * rebooted before we can let the system talk to it. We read
+ * the inbound Free_List until a message is available. If we
+ * can't read one in the given ammount of time, we assume the
+ * IOP could not reboot properly.
*/
- pr_debug("%s: Reset in progress, waiting for reboot...\n",
- c->name);
+ osm_debug("%s: Reset in progress, waiting for reboot...\n",
+ c->name);
m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
while (m == I2O_QUEUE_EMPTY) {
if (time_after(jiffies, timeout)) {
- printk(KERN_ERR "%s: IOP reset timeout.\n",
- c->name);
+ osm_err("%s: IOP reset timeout.\n", c->name);
rc = -ETIMEDOUT;
goto exit;
}
@@ -545,19 +582,26 @@ static int i2o_iop_reset(struct i2o_controller *c)
m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
}
i2o_msg_nop(c, m);
- }
- /* from here all quiesce commands are safe */
- c->no_quiesce = 0;
+ /* from here all quiesce commands are safe */
+ c->no_quiesce = 0;
- /* If IopReset was rejected or didn't perform reset, try IopClear */
- i2o_status_get(c);
- if (*status == I2O_CMD_REJECTED || sb->iop_state != ADAPTER_STATE_RESET) {
- printk(KERN_WARNING "%s: Reset rejected, trying to clear\n",
- c->name);
- i2o_iop_clear(c);
- } else
- pr_debug("%s: Reset completed.\n", c->name);
+ /* verify if controller is in state RESET */
+ i2o_status_get(c);
+
+ if (!c->promise && (sb->iop_state != ADAPTER_STATE_RESET))
+ osm_warn("%s: reset completed, but adapter not in RESET"
+ " state.\n", c->name);
+ else
+ osm_debug("%s: reset completed.\n", c->name);
+
+ break;
+
+ default:
+ osm_err("%s: IOP reset timeout.\n", c->name);
+ rc = -ETIMEDOUT;
+ break;
+ }
exit:
/* Enable all IOPs */
@@ -567,88 +611,6 @@ static int i2o_iop_reset(struct i2o_controller *c)
};
/**
- * i2o_iop_init_outbound_queue - setup the outbound message queue
- * @c: I2O controller
- *
- * Clear and (re)initialize IOP's outbound queue and post the message
- * frames to the IOP.
- *
- * Returns 0 on success or a negative errno code on failure.
- */
-static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
-{
- u8 *status = c->status.virt;
- u32 m;
- struct i2o_message __iomem *msg;
- ulong timeout;
- int i;
-
- pr_debug("%s: Initializing Outbound Queue...\n", c->name);
-
- memset(status, 0, 4);
-
- m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
- if (m == I2O_QUEUE_EMPTY)
- return -ETIMEDOUT;
-
- writel(EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6, &msg->u.head[0]);
- writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID,
- &msg->u.head[1]);
- writel(i2o_exec_driver.context, &msg->u.s.icntxt);
- writel(0x0106, &msg->u.s.tcntxt); /* FIXME: why 0x0106, maybe in
- Spec? */
- writel(PAGE_SIZE, &msg->body[0]);
- writel(MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]); /* Outbound msg frame
- size in words and Initcode */
- writel(0xd0000004, &msg->body[2]);
- writel(i2o_ptr_low((void *)c->status.phys), &msg->body[3]);
- writel(i2o_ptr_high((void *)c->status.phys), &msg->body[4]);
-
- i2o_msg_post(c, m);
-
- timeout = jiffies + I2O_TIMEOUT_INIT_OUTBOUND_QUEUE * HZ;
- while (*status <= I2O_CMD_IN_PROGRESS) {
- if (time_after(jiffies, timeout)) {
- printk(KERN_WARNING "%s: Timeout Initializing\n",
- c->name);
- return -ETIMEDOUT;
- }
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
-
- rmb();
- }
-
- m = c->out_queue.phys;
-
- /* Post frames */
- for (i = 0; i < NMBR_MSG_FRAMES; i++) {
- i2o_flush_reply(c, m);
- udelay(1); /* Promise */
- m += MSG_FRAME_SIZE * 4;
- }
-
- return 0;
-}
-
-/**
- * i2o_iop_send_nop - send a core NOP message
- * @c: controller
- *
- * Send a no-operation message with a reply set to cause no
- * action either. Needed for bringing up promise controllers.
- */
-static int i2o_iop_send_nop(struct i2o_controller *c)
-{
- struct i2o_message __iomem *msg;
- u32 m = i2o_msg_get_wait(c, &msg, HZ);
- if (m == I2O_QUEUE_EMPTY)
- return -ETIMEDOUT;
- i2o_msg_nop(c, m);
- return 0;
-}
-
-/**
* i2o_iop_activate - Bring controller up to HOLD
* @c: controller
*
@@ -659,78 +621,62 @@ static int i2o_iop_send_nop(struct i2o_controller *c)
*/
static int i2o_iop_activate(struct i2o_controller *c)
{
- struct pci_dev *i960 = NULL;
i2o_status_block *sb = c->status_block.virt;
int rc;
-
- if (c->promise) {
- /* Beat up the hardware first of all */
- i960 =
- pci_find_slot(c->pdev->bus->number,
- PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0));
- if (i960)
- pci_write_config_word(i960, 0x42, 0);
-
- /* Follow this sequence precisely or the controller
- ceases to perform useful functions until reboot */
- if ((rc = i2o_iop_send_nop(c)))
- return rc;
-
- if ((rc = i2o_iop_reset(c)))
- return rc;
- }
+ int state;
/* In INIT state, Wait Inbound Q to initialize (in i2o_status_get) */
/* In READY state, Get status */
rc = i2o_status_get(c);
if (rc) {
- printk(KERN_INFO "%s: Unable to obtain status, "
- "attempting a reset.\n", c->name);
- if (i2o_iop_reset(c))
+ osm_info("%s: Unable to obtain status, attempting a reset.\n",
+ c->name);
+ rc = i2o_iop_reset(c);
+ if (rc)
return rc;
}
if (sb->i2o_version > I2OVER15) {
- printk(KERN_ERR "%s: Not running version 1.5 of the I2O "
- "Specification.\n", c->name);
+ osm_err("%s: Not running version 1.5 of the I2O Specification."
+ "\n", c->name);
return -ENODEV;
}
switch (sb->iop_state) {
case ADAPTER_STATE_FAULTED:
- printk(KERN_CRIT "%s: hardware fault\n", c->name);
- return -ENODEV;
+ osm_err("%s: hardware fault\n", c->name);
+ return -EFAULT;
case ADAPTER_STATE_READY:
case ADAPTER_STATE_OPERATIONAL:
case ADAPTER_STATE_HOLD:
case ADAPTER_STATE_FAILED:
- pr_debug("%s: already running, trying to reset...\n", c->name);
- if (i2o_iop_reset(c))
- return -ENODEV;
+ osm_debug("%s: already running, trying to reset...\n", c->name);
+ rc = i2o_iop_reset(c);
+ if (rc)
+ return rc;
}
+ /* preserve state */
+ state = sb->iop_state;
+
rc = i2o_iop_init_outbound_queue(c);
if (rc)
return rc;
- if (c->promise) {
- if ((rc = i2o_iop_send_nop(c)))
- return rc;
+ /* if adapter was not in RESET state clear now */
+ if (state != ADAPTER_STATE_RESET)
+ i2o_iop_clear(c);
- if ((rc = i2o_status_get(c)))
- return rc;
+ i2o_status_get(c);
- if (i960)
- pci_write_config_word(i960, 0x42, 0x3FF);
+ if (sb->iop_state != ADAPTER_STATE_HOLD) {
+ osm_err("%s: failed to bring IOP into HOLD state\n", c->name);
+ return -EIO;
}
- /* In HOLD state */
-
- rc = i2o_hrt_get(c);
-
- return rc;
+ return i2o_hrt_get(c);
};
/**
@@ -756,20 +702,18 @@ static int i2o_iop_systab_set(struct i2o_controller *c)
res->flags = IORESOURCE_MEM;
res->start = 0;
res->end = 0;
- printk(KERN_INFO "%s: requires private memory resources.\n",
- c->name);
+ osm_info("%s: requires private memory resources.\n", c->name);
root = pci_find_parent_resource(c->pdev, res);
if (root == NULL)
- printk(KERN_WARNING "%s: Can't find parent resource!\n",
- c->name);
+ osm_warn("%s: Can't find parent resource!\n", c->name);
if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
NULL, NULL) >= 0) {
c->mem_alloc = 1;
sb->current_mem_size = 1 + res->end - res->start;
sb->current_mem_base = res->start;
- printk(KERN_INFO "%s: allocated %ld bytes of PCI memory"
- " at 0x%08lX.\n", c->name,
- 1 + res->end - res->start, res->start);
+ osm_info("%s: allocated %ld bytes of PCI memory at "
+ "0x%08lX.\n", c->name,
+ 1 + res->end - res->start, res->start);
}
}
@@ -779,20 +723,18 @@ static int i2o_iop_systab_set(struct i2o_controller *c)
res->flags = IORESOURCE_IO;
res->start = 0;
res->end = 0;
- printk(KERN_INFO "%s: requires private memory resources.\n",
- c->name);
+ osm_info("%s: requires private memory resources.\n", c->name);
root = pci_find_parent_resource(c->pdev, res);
if (root == NULL)
- printk(KERN_WARNING "%s: Can't find parent resource!\n",
- c->name);
+ osm_warn("%s: Can't find parent resource!\n", c->name);
if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
NULL, NULL) >= 0) {
c->io_alloc = 1;
sb->current_io_size = 1 + res->end - res->start;
sb->current_mem_base = res->start;
- printk(KERN_INFO "%s: allocated %ld bytes of PCI I/O at"
- " 0x%08lX.\n", c->name,
- 1 + res->end - res->start, res->start);
+ osm_info("%s: allocated %ld bytes of PCI I/O at 0x%08lX"
+ ".\n", c->name, 1 + res->end - res->start,
+ res->start);
}
}
@@ -836,10 +778,10 @@ static int i2o_iop_systab_set(struct i2o_controller *c)
PCI_DMA_TODEVICE);
if (rc < 0)
- printk(KERN_ERR "%s: Unable to set SysTab (status=%#x).\n",
- c->name, -rc);
+ osm_err("%s: Unable to set SysTab (status=%#x).\n", c->name,
+ -rc);
else
- pr_debug("%s: SysTab set.\n", c->name);
+ osm_debug("%s: SysTab set.\n", c->name);
i2o_status_get(c); // Entered READY state
@@ -863,7 +805,7 @@ static int i2o_iop_online(struct i2o_controller *c)
return rc;
/* In READY state */
- pr_debug("%s: Attempting to enable...\n", c->name);
+ osm_debug("%s: Attempting to enable...\n", c->name);
rc = i2o_iop_enable(c);
if (rc)
return rc;
@@ -882,7 +824,7 @@ void i2o_iop_remove(struct i2o_controller *c)
{
struct i2o_device *dev, *tmp;
- pr_debug("%s: deleting controller\n", c->name);
+ osm_debug("%s: deleting controller\n", c->name);
i2o_driver_notify_controller_remove_all(c);
@@ -891,8 +833,12 @@ void i2o_iop_remove(struct i2o_controller *c)
list_for_each_entry_safe(dev, tmp, &c->devices, list)
i2o_device_remove(dev);
+ device_del(&c->device);
+
/* Ask the IOP to switch to RESET state */
i2o_iop_reset(c);
+
+ put_device(&c->device);
}
/**
@@ -927,8 +873,7 @@ static int i2o_systab_build(void)
systab = i2o_systab.virt = kmalloc(i2o_systab.len, GFP_KERNEL);
if (!systab) {
- printk(KERN_ERR "i2o: unable to allocate memory for System "
- "Table\n");
+ osm_err("unable to allocate memory for System Table\n");
return -ENOMEM;
}
memset(systab, 0, i2o_systab.len);
@@ -940,8 +885,8 @@ static int i2o_systab_build(void)
i2o_status_block *sb;
if (count >= num_controllers) {
- printk(KERN_ERR "i2o: controller added while building "
- "system table\n");
+ osm_err("controller added while building system table"
+ "\n");
break;
}
@@ -955,9 +900,8 @@ static int i2o_systab_build(void)
* it is techninically not part of the I2O subsystem...
*/
if (unlikely(i2o_status_get(c))) {
- printk(KERN_ERR "%s: Deleting b/c could not get status"
- " while attempting to build system table\n",
- c->name);
+ osm_err("%s: Deleting b/c could not get status while "
+ "attempting to build system table\n", c->name);
i2o_iop_remove(c);
continue; // try the next one
}
@@ -971,8 +915,10 @@ static int i2o_systab_build(void)
systab->iops[count].frame_size = sb->inbound_frame_size;
systab->iops[count].last_changed = change_ind;
systab->iops[count].iop_capabilities = sb->iop_capabilities;
- systab->iops[count].inbound_low = i2o_ptr_low(c->post_port);
- systab->iops[count].inbound_high = i2o_ptr_high(c->post_port);
+ systab->iops[count].inbound_low =
+ i2o_dma_low(c->base.phys + I2O_IN_PORT);
+ systab->iops[count].inbound_high =
+ i2o_dma_high(c->base.phys + I2O_IN_PORT);
count++;
}
@@ -1010,11 +956,11 @@ int i2o_status_get(struct i2o_controller *c)
{
struct i2o_message __iomem *msg;
u32 m;
- u8 *status_block;
+ volatile u8 *status_block;
unsigned long timeout;
status_block = (u8 *) c->status_block.virt;
- memset(status_block, 0, sizeof(i2o_status_block));
+ memset(c->status_block.virt, 0, sizeof(i2o_status_block));
m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
if (m == I2O_QUEUE_EMPTY)
@@ -1027,8 +973,8 @@ int i2o_status_get(struct i2o_controller *c)
writel(0, &msg->u.s.tcntxt); // FIXME: use resonable transaction context
writel(0, &msg->body[0]);
writel(0, &msg->body[1]);
- writel(i2o_ptr_low((void *)c->status_block.phys), &msg->body[2]);
- writel(i2o_ptr_high((void *)c->status_block.phys), &msg->body[3]);
+ writel(i2o_dma_low(c->status_block.phys), &msg->body[2]);
+ writel(i2o_dma_high(c->status_block.phys), &msg->body[3]);
writel(sizeof(i2o_status_block), &msg->body[4]); /* always 88 bytes */
i2o_msg_post(c, m);
@@ -1037,14 +983,12 @@ int i2o_status_get(struct i2o_controller *c)
timeout = jiffies + I2O_TIMEOUT_STATUS_GET * HZ;
while (status_block[87] != 0xFF) {
if (time_after(jiffies, timeout)) {
- printk(KERN_ERR "%s: Get status timeout.\n", c->name);
+ osm_err("%s: Get status timeout.\n", c->name);
return -ETIMEDOUT;
}
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
-
- rmb();
}
#ifdef DEBUG
@@ -1088,8 +1032,8 @@ static int i2o_hrt_get(struct i2o_controller *c)
rc = i2o_msg_post_wait_mem(c, m, 20, &c->hrt);
if (rc < 0) {
- printk(KERN_ERR "%s: Unable to get HRT (status=%#x)\n",
- c->name, -rc);
+ osm_err("%s: Unable to get HRT (status=%#x)\n", c->name,
+ -rc);
return rc;
}
@@ -1103,13 +1047,41 @@ static int i2o_hrt_get(struct i2o_controller *c)
return i2o_parse_hrt(c);
}
- printk(KERN_ERR "%s: Unable to get HRT after %d tries, giving up\n",
- c->name, I2O_HRT_GET_TRIES);
+ osm_err("%s: Unable to get HRT after %d tries, giving up\n", c->name,
+ I2O_HRT_GET_TRIES);
return -EBUSY;
}
/**
+ * i2o_iop_free - Free the i2o_controller struct
+ * @c: I2O controller to free
+ */
+void i2o_iop_free(struct i2o_controller *c)
+{
+ kfree(c);
+};
+
+/**
+ * i2o_iop_release - release the memory for a I2O controller
+ * @dev: I2O controller which should be released
+ *
+ * Release the allocated memory. This function is called if refcount of
+ * device reaches 0 automatically.
+ */
+static void i2o_iop_release(struct device *dev)
+{
+ struct i2o_controller *c = to_i2o_controller(dev);
+
+ i2o_iop_free(c);
+};
+
+/* I2O controller class */
+static struct class i2o_controller_class = {
+ .name = "i2o_controller",
+};
+
+/**
* i2o_iop_alloc - Allocate and initialize a i2o_controller struct
*
* Allocate the necessary memory for a i2o_controller struct and
@@ -1125,8 +1097,8 @@ struct i2o_controller *i2o_iop_alloc(void)
c = kmalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
- printk(KERN_ERR "i2o: Insufficient memory to allocate a I2O "
- "controller.\n");
+ osm_err("i2o: Insufficient memory to allocate a I2O controller."
+ "\n");
return ERR_PTR(-ENOMEM);
}
memset(c, 0, sizeof(*c));
@@ -1137,6 +1109,16 @@ struct i2o_controller *i2o_iop_alloc(void)
c->unit = unit++;
sprintf(c->name, "iop%d", c->unit);
+ device_initialize(&c->device);
+ class_device_initialize(&c->classdev);
+
+ c->device.release = &i2o_iop_release;
+ c->classdev.class = &i2o_controller_class;
+ c->classdev.dev = &c->device;
+
+ snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit);
+ snprintf(c->classdev.class_id, BUS_ID_SIZE, "iop%d", c->unit);
+
#if BITS_PER_LONG == 64
spin_lock_init(&c->context_list_lock);
atomic_set(&c->context_list_counter, 0);
@@ -1147,15 +1129,6 @@ struct i2o_controller *i2o_iop_alloc(void)
};
/**
- * i2o_iop_free - Free the i2o_controller struct
- * @c: I2O controller to free
- */
-void i2o_iop_free(struct i2o_controller *c)
-{
- kfree(c);
-};
-
-/**
* i2o_iop_add - Initialize the I2O controller and add him to the I2O core
* @c: controller
*
@@ -1168,45 +1141,58 @@ int i2o_iop_add(struct i2o_controller *c)
{
int rc;
- printk(KERN_INFO "%s: Activating I2O controller...\n", c->name);
- printk(KERN_INFO "%s: This may take a few minutes if there are many "
- "devices\n", c->name);
+ if ((rc = device_add(&c->device))) {
+ osm_err("%s: could not add controller\n", c->name);
+ goto iop_reset;
+ }
- if ((rc = i2o_iop_activate(c))) {
- printk(KERN_ERR "%s: could not activate controller\n",
- c->name);
- i2o_iop_reset(c);
- return rc;
+ if ((rc = class_device_add(&c->classdev))) {
+ osm_err("%s: could not add controller class\n", c->name);
+ goto device_del;
}
- pr_debug("%s: building sys table...\n", c->name);
+ osm_info("%s: Activating I2O controller...\n", c->name);
+ osm_info("%s: This may take a few minutes if there are many devices\n",
+ c->name);
- if ((rc = i2o_systab_build())) {
- i2o_iop_reset(c);
- return rc;
+ if ((rc = i2o_iop_activate(c))) {
+ osm_err("%s: could not activate controller\n", c->name);
+ goto class_del;
}
- pr_debug("%s: online controller...\n", c->name);
+ osm_debug("%s: building sys table...\n", c->name);
- if ((rc = i2o_iop_online(c))) {
- i2o_iop_reset(c);
- return rc;
- }
+ if ((rc = i2o_systab_build()))
+ goto class_del;
- pr_debug("%s: getting LCT...\n", c->name);
+ osm_debug("%s: online controller...\n", c->name);
- if ((rc = i2o_exec_lct_get(c))) {
- i2o_iop_reset(c);
- return rc;
- }
+ if ((rc = i2o_iop_online(c)))
+ goto class_del;
+
+ osm_debug("%s: getting LCT...\n", c->name);
+
+ if ((rc = i2o_exec_lct_get(c)))
+ goto class_del;
list_add(&c->list, &i2o_controllers);
i2o_driver_notify_controller_add_all(c);
- printk(KERN_INFO "%s: Controller added\n", c->name);
+ osm_info("%s: Controller added\n", c->name);
return 0;
+
+ class_del:
+ class_device_del(&c->classdev);
+
+ device_del:
+ device_del(&c->device);
+
+ iop_reset:
+ i2o_iop_reset(c);
+
+ return rc;
};
/**
@@ -1264,16 +1250,18 @@ static int __init i2o_iop_init(void)
if (rc)
goto exit;
- rc = i2o_driver_init();
- if (rc)
+ if ((rc = class_register(&i2o_controller_class))) {
+ osm_err("can't register class i2o_controller\n");
goto device_exit;
+ }
- rc = i2o_exec_init();
- if (rc)
+ if ((rc = i2o_driver_init()))
+ goto class_exit;
+
+ if ((rc = i2o_exec_init()))
goto driver_exit;
- rc = i2o_pci_init();
- if (rc < 0)
+ if ((rc = i2o_pci_init()))
goto exec_exit;
return 0;
@@ -1284,6 +1272,9 @@ static int __init i2o_iop_init(void)
driver_exit:
i2o_driver_exit();
+ class_exit:
+ class_unregister(&i2o_controller_class);
+
device_exit:
i2o_device_exit();
@@ -1301,6 +1292,7 @@ static void __exit i2o_iop_exit(void)
i2o_pci_exit();
i2o_exec_exit();
i2o_driver_exit();
+ class_unregister(&i2o_controller_class);
i2o_device_exit();
};
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index e772752f056..7a60fd7be8a 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -30,53 +30,18 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/i2o.h>
-
-#ifdef CONFIG_MTRR
-#include <asm/mtrr.h>
-#endif // CONFIG_MTRR
-
-/* Module internal functions from other sources */
-extern struct i2o_controller *i2o_iop_alloc(void);
-extern void i2o_iop_free(struct i2o_controller *);
-
-extern int i2o_iop_add(struct i2o_controller *);
-extern void i2o_iop_remove(struct i2o_controller *);
-
-extern int i2o_driver_dispatch(struct i2o_controller *, u32,
- struct i2o_message *);
+#include "core.h"
/* PCI device id table for all I2O controllers */
static struct pci_device_id __devinitdata i2o_pci_ids[] = {
{PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)},
{PCI_DEVICE(PCI_VENDOR_ID_DPT, 0xa511)},
+ {.vendor = PCI_VENDOR_ID_INTEL,.device = 0x1962,
+ .subvendor = PCI_VENDOR_ID_PROMISE,.subdevice = PCI_ANY_ID},
{0}
};
/**
- * i2o_dma_realloc - Realloc DMA memory
- * @dev: struct device pointer to the PCI device of the I2O controller
- * @addr: pointer to a i2o_dma struct DMA buffer
- * @len: new length of memory
- * @gfp_mask: GFP mask
- *
- * If there was something allocated in the addr, free it first. If len > 0
- * than try to allocate it and write the addresses back to the addr
- * structure. If len == 0 set the virtual address to NULL.
- *
- * Returns the 0 on success or negative error code on failure.
- */
-int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len,
- unsigned int gfp_mask)
-{
- i2o_dma_free(dev, addr);
-
- if (len)
- return i2o_dma_alloc(dev, addr, len, gfp_mask);
-
- return 0;
-};
-
-/**
* i2o_pci_free - Frees the DMA memory for the I2O controller
* @c: I2O controller to free
*
@@ -91,19 +56,11 @@ static void i2o_pci_free(struct i2o_controller *c)
i2o_dma_free(dev, &c->out_queue);
i2o_dma_free(dev, &c->status_block);
- if (c->lct)
- kfree(c->lct);
+ kfree(c->lct);
i2o_dma_free(dev, &c->dlct);
i2o_dma_free(dev, &c->hrt);
i2o_dma_free(dev, &c->status);
-#ifdef CONFIG_MTRR
- if (c->mtrr_reg0 >= 0)
- mtrr_del(c->mtrr_reg0, 0, 0);
- if (c->mtrr_reg1 >= 0)
- mtrr_del(c->mtrr_reg1, 0, 0);
-#endif
-
if (c->raptor && c->in_queue.virt)
iounmap(c->in_queue.virt);
@@ -178,14 +135,15 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
c->name, (unsigned long)c->base.phys,
(unsigned long)c->base.len);
- c->base.virt = ioremap(c->base.phys, c->base.len);
+ c->base.virt = ioremap_nocache(c->base.phys, c->base.len);
if (!c->base.virt) {
printk(KERN_ERR "%s: Unable to map controller.\n", c->name);
return -ENOMEM;
}
if (c->raptor) {
- c->in_queue.virt = ioremap(c->in_queue.phys, c->in_queue.len);
+ c->in_queue.virt =
+ ioremap_nocache(c->in_queue.phys, c->in_queue.len);
if (!c->in_queue.virt) {
printk(KERN_ERR "%s: Unable to map controller.\n",
c->name);
@@ -195,43 +153,10 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
} else
c->in_queue = c->base;
- c->irq_mask = c->base.virt + 0x34;
- c->post_port = c->base.virt + 0x40;
- c->reply_port = c->base.virt + 0x44;
-
-#ifdef CONFIG_MTRR
- /* Enable Write Combining MTRR for IOP's memory region */
- c->mtrr_reg0 = mtrr_add(c->in_queue.phys, c->in_queue.len,
- MTRR_TYPE_WRCOMB, 1);
- c->mtrr_reg1 = -1;
-
- if (c->mtrr_reg0 < 0)
- printk(KERN_WARNING "%s: could not enable write combining "
- "MTRR\n", c->name);
- else
- printk(KERN_INFO "%s: using write combining MTRR\n", c->name);
-
- /*
- * If it is an INTEL i960 I/O processor then set the first 64K to
- * Uncacheable since the region contains the messaging unit which
- * shouldn't be cached.
- */
- if ((pdev->vendor == PCI_VENDOR_ID_INTEL ||
- pdev->vendor == PCI_VENDOR_ID_DPT) && !c->raptor) {
- printk(KERN_INFO "%s: MTRR workaround for Intel i960 processor"
- "\n", c->name);
- c->mtrr_reg1 = mtrr_add(c->base.phys, 0x10000,
- MTRR_TYPE_UNCACHABLE, 1);
-
- if (c->mtrr_reg1 < 0) {
- printk(KERN_WARNING "%s: Error in setting "
- "MTRR_TYPE_UNCACHABLE\n", c->name);
- mtrr_del(c->mtrr_reg0, c->in_queue.phys,
- c->in_queue.len);
- c->mtrr_reg0 = -1;
- }
- }
-#endif
+ c->irq_status = c->base.virt + I2O_IRQ_STATUS;
+ c->irq_mask = c->base.virt + I2O_IRQ_MASK;
+ c->in_port = c->base.virt + I2O_IN_PORT;
+ c->out_port = c->base.virt + I2O_OUT_PORT;
if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) {
i2o_pci_free(c);
@@ -254,7 +179,10 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
return -ENOMEM;
}
- if (i2o_dma_alloc(dev, &c->out_queue, MSG_POOL_SIZE, GFP_KERNEL)) {
+ if (i2o_dma_alloc
+ (dev, &c->out_queue,
+ I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE *
+ sizeof(u32), GFP_KERNEL)) {
i2o_pci_free(c);
return -ENOMEM;
}
@@ -276,51 +204,30 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
{
struct i2o_controller *c = dev_id;
- struct device *dev = &c->pdev->dev;
- struct i2o_message *m;
- u32 mv;
-
- /*
- * Old 960 steppings had a bug in the I2O unit that caused
- * the queue to appear empty when it wasn't.
- */
- mv = I2O_REPLY_READ32(c);
- if (mv == I2O_QUEUE_EMPTY) {
- mv = I2O_REPLY_READ32(c);
- if (unlikely(mv == I2O_QUEUE_EMPTY)) {
- return IRQ_NONE;
- } else
- pr_debug("%s: 960 bug detected\n", c->name);
- }
-
- while (mv != I2O_QUEUE_EMPTY) {
- /*
- * Map the message from the page frame map to kernel virtual.
- * Because bus_to_virt is deprecated, we have calculate the
- * location by ourself!
- */
- m = i2o_msg_out_to_virt(c, mv);
-
- /*
- * Ensure this message is seen coherently but cachably by
- * the processor
- */
- dma_sync_single_for_cpu(dev, mv, MSG_FRAME_SIZE * 4,
- PCI_DMA_FROMDEVICE);
+ u32 m;
+ irqreturn_t rc = IRQ_NONE;
+
+ while (readl(c->irq_status) & I2O_IRQ_OUTBOUND_POST) {
+ m = readl(c->out_port);
+ if (m == I2O_QUEUE_EMPTY) {
+ /*
+ * Old 960 steppings had a bug in the I2O unit that
+ * caused the queue to appear empty when it wasn't.
+ */
+ m = readl(c->out_port);
+ if (unlikely(m == I2O_QUEUE_EMPTY))
+ break;
+ }
/* dispatch it */
- if (i2o_driver_dispatch(c, mv, m))
+ if (i2o_driver_dispatch(c, m))
/* flush it if result != 0 */
- i2o_flush_reply(c, mv);
+ i2o_flush_reply(c, m);
- /*
- * That 960 bug again...
- */
- mv = I2O_REPLY_READ32(c);
- if (mv == I2O_QUEUE_EMPTY)
- mv = I2O_REPLY_READ32(c);
+ rc = IRQ_HANDLED;
}
- return IRQ_HANDLED;
+
+ return rc;
}
/**
@@ -336,7 +243,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
struct pci_dev *pdev = c->pdev;
int rc;
- I2O_IRQ_WRITE32(c, 0xffffffff);
+ writel(0xffffffff, c->irq_mask);
if (pdev->irq) {
rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ,
@@ -348,7 +255,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
}
}
- I2O_IRQ_WRITE32(c, 0x00000000);
+ writel(0x00000000, c->irq_mask);
printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq);
@@ -363,7 +270,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c)
*/
static void i2o_pci_irq_disable(struct i2o_controller *c)
{
- I2O_IRQ_WRITE32(c, 0xffffffff);
+ writel(0xffffffff, c->irq_mask);
if (c->pdev->irq > 0)
free_irq(c->pdev->irq, c);
@@ -385,28 +292,25 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
{
struct i2o_controller *c;
int rc;
+ struct pci_dev *i960 = NULL;
printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
if ((pdev->class & 0xff) > 1) {
- printk(KERN_WARNING "i2o: I2O controller found but does not "
- "support I2O 1.5 (skipping).\n");
+ printk(KERN_WARNING "i2o: %s does not support I2O 1.5 "
+ "(skipping).\n", pci_name(pdev));
return -ENODEV;
}
if ((rc = pci_enable_device(pdev))) {
- printk(KERN_WARNING "i2o: I2O controller found but could not be"
- " enabled.\n");
+ printk(KERN_WARNING "i2o: couldn't enable device %s\n",
+ pci_name(pdev));
return rc;
}
- printk(KERN_INFO "i2o: I2O controller found on bus %d at %d.\n",
- pdev->bus->number, pdev->devfn);
-
if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
- printk(KERN_WARNING "i2o: I2O controller on bus %d at %d: No "
- "suitable DMA available!\n", pdev->bus->number,
- pdev->devfn);
+ printk(KERN_WARNING "i2o: no suitable DMA found for %s\n",
+ pci_name(pdev));
rc = -ENODEV;
goto disable;
}
@@ -415,14 +319,16 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
c = i2o_iop_alloc();
if (IS_ERR(c)) {
- printk(KERN_ERR "i2o: memory for I2O controller could not be "
- "allocated\n");
+ printk(KERN_ERR "i2o: couldn't allocate memory for %s\n",
+ pci_name(pdev));
rc = PTR_ERR(c);
goto disable;
- }
+ } else
+ printk(KERN_INFO "%s: controller found (%s)\n", c->name,
+ pci_name(pdev));
c->pdev = pdev;
- c->device = pdev->dev;
+ c->device.parent = get_device(&pdev->dev);
/* Cards that fall apart if you hit them with large I/O loads... */
if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) {
@@ -432,16 +338,48 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
}
if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) {
+ /*
+ * Expose the ship behind i960 for initialization, or it will
+ * failed
+ */
+ i960 =
+ pci_find_slot(c->pdev->bus->number,
+ PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0));
+
+ if (i960)
+ pci_write_config_word(i960, 0x42, 0);
+
c->promise = 1;
- printk(KERN_INFO "%s: Promise workarounds activated.\n",
- c->name);
+ c->limit_sectors = 1;
}
+ if (pdev->subsystem_vendor == PCI_VENDOR_ID_DPT)
+ c->adaptec = 1;
+
/* Cards that go bananas if you quiesce them before you reset them. */
if (pdev->vendor == PCI_VENDOR_ID_DPT) {
c->no_quiesce = 1;
if (pdev->device == 0xa511)
c->raptor = 1;
+
+ if (pdev->subsystem_device == 0xc05a) {
+ c->limit_sectors = 1;
+ printk(KERN_INFO
+ "%s: limit sectors per request to %d\n", c->name,
+ I2O_MAX_SECTORS_LIMITED);
+ }
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+ if (sizeof(dma_addr_t) > 4) {
+ if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+ printk(KERN_INFO "%s: 64-bit DMA unavailable\n",
+ c->name);
+ else {
+ c->pae_support = 1;
+ printk(KERN_INFO "%s: using 64-bit DMA\n",
+ c->name);
+ }
+ }
+#endif
}
if ((rc = i2o_pci_alloc(c))) {
@@ -459,6 +397,11 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
if ((rc = i2o_iop_add(c)))
goto uninstall;
+ get_device(&c->device);
+
+ if (i960)
+ pci_write_config_word(i960, 0x42, 0x03ff);
+
return 0;
uninstall:
@@ -469,6 +412,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev,
free_controller:
i2o_iop_free(c);
+ put_device(c->device.parent);
disable:
pci_disable_device(pdev);
@@ -492,15 +436,17 @@ static void __devexit i2o_pci_remove(struct pci_dev *pdev)
i2o_pci_irq_disable(c);
i2o_pci_free(c);
+ pci_disable_device(pdev);
+
printk(KERN_INFO "%s: Controller removed.\n", c->name);
- i2o_iop_free(c);
- pci_disable_device(pdev);
+ put_device(c->device.parent);
+ put_device(&c->device);
};
/* PCI driver for I2O controller */
static struct pci_driver i2o_pci_driver = {
- .name = "I2O controller",
+ .name = "PCI_I2O",
.id_table = i2o_pci_ids,
.probe = i2o_pci_probe,
.remove = __devexit_p(i2o_pci_remove),
@@ -523,6 +469,4 @@ void __exit i2o_pci_exit(void)
{
pci_unregister_driver(&i2o_pci_driver);
};
-
-EXPORT_SYMBOL(i2o_dma_realloc);
MODULE_DEVICE_TABLE(pci, i2o_pci_ids);
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 047202c4d9a..5a4a08a7c95 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -1606,7 +1606,7 @@ static int rtl8139_thread (void *data)
do {
timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
/* make swsusp happy with our thread */
- try_to_freeze(PF_FREEZE);
+ try_to_freeze();
} while (!signal_pending (current) && (timeout > 0));
if (signal_pending (current)) {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 325495b8b60..137226d98d4 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2307,6 +2307,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
tso = e1000_tso(adapter, skb);
if (tso < 0) {
dev_kfree_skb_any(skb);
+ spin_unlock_irqrestore(&adapter->tx_lock, flags);
return NETDEV_TX_OK;
}
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 89454915b85..e44f8e9055e 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -848,7 +848,7 @@ static void __exit sixpack_exit_driver(void)
{
int ret;
- if ((ret = tty_register_ldisc(N_6PACK, NULL)))
+ if ((ret = tty_unregister_ldisc(N_6PACK)))
printk(msg_unregfail, ret);
}
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 62790511098..3035422f5ad 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -934,7 +934,7 @@ static void __exit mkiss_exit_driver(void)
kfree(ax25_ctrls);
ax25_ctrls = NULL;
- if ((i = tty_register_ldisc(N_AX25, NULL)))
+ if ((i = tty_unregister_ldisc(N_AX25)))
printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i);
}
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 7d23aa37590..b8d112348ba 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -626,7 +626,7 @@ static void __exit irtty_sir_cleanup(void)
{
int err;
- if ((err = tty_register_ldisc(N_IRDA, NULL))) {
+ if ((err = tty_unregister_ldisc(N_IRDA))) {
IRDA_ERROR("%s(), can't unregister line discipline (err = %d)\n",
__FUNCTION__, err);
}
diff --git a/drivers/net/irda/sir_kthread.c b/drivers/net/irda/sir_kthread.c
index 18cea109953..c65054364bc 100644
--- a/drivers/net/irda/sir_kthread.c
+++ b/drivers/net/irda/sir_kthread.c
@@ -135,8 +135,7 @@ static int irda_thread(void *startup)
remove_wait_queue(&irda_rq_queue.kick, &wait);
/* make swsusp happy with our thread */
- if (current->flags & PF_FREEZE)
- refrigerator(PF_FREEZE);
+ try_to_freeze();
run_irda_queue();
}
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 66f488c1371..15f207323d9 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -763,7 +763,7 @@ static int stir_transmit_thread(void *arg)
{
#ifdef CONFIG_PM
/* if suspending, then power off and wait */
- if (unlikely(current->flags & PF_FREEZE)) {
+ if (unlikely(freezing(current))) {
if (stir->receiving)
receive_stop(stir);
else
@@ -771,7 +771,7 @@ static int stir_transmit_thread(void *arg)
write_reg(stir, REG_CTRL1, CTRL1_TXPWD|CTRL1_RXPWD);
- refrigerator(PF_FREEZE);
+ refrigerator();
if (change_speed(stir, stir->speed))
break;
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 33b9d79b1aa..5e48b9ab304 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -1025,7 +1025,7 @@ static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
static void __exit ppp_async_cleanup(void)
{
- if (tty_register_ldisc(N_PPP, NULL) != 0)
+ if (tty_unregister_ldisc(N_PPP) != 0)
printk(KERN_ERR "failed to unregister PPP line discipline\n");
}
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 7d0150b4c62..fd9f5018035 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -793,7 +793,7 @@ err:
static void __exit
ppp_sync_cleanup(void)
{
- if (tty_register_ldisc(N_SYNC_PPP, NULL) != 0)
+ if (tty_unregister_ldisc(N_SYNC_PPP) != 0)
printk(KERN_ERR "failed to unregister Sync PPP line discipline\n");
}
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 8f7841c0374..c79e0ad4ba0 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -198,18 +198,12 @@ err_exit:
static void
sl_free_bufs(struct slip *sl)
{
- void * tmp;
-
/* Free all SLIP frame buffers. */
- tmp = xchg(&sl->rbuff, NULL);
- kfree(tmp);
- tmp = xchg(&sl->xbuff, NULL);
- kfree(tmp);
+ kfree(xchg(&sl->rbuff, NULL));
+ kfree(xchg(&sl->xbuff, NULL));
#ifdef SL_INCLUDE_CSLIP
- tmp = xchg(&sl->cbuff, NULL);
- kfree(tmp);
- if ((tmp = xchg(&sl->slcomp, NULL)) != NULL)
- slhc_free(tmp);
+ kfree(xchg(&sl->cbuff, NULL));
+ slhc_free(xchg(&sl->slcomp, NULL));
#endif
}
@@ -1430,7 +1424,7 @@ static void __exit slip_exit(void)
kfree(slip_devs);
slip_devs = NULL;
- if ((i = tty_register_ldisc(N_SLIP, NULL)))
+ if ((i = tty_unregister_ldisc(N_SLIP)))
{
printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i);
}
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index a0b8848049c..7e371b1209a 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -66,8 +66,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.31"
-#define DRV_MODULE_RELDATE "June 8, 2005"
+#define DRV_MODULE_VERSION "3.32"
+#define DRV_MODULE_RELDATE "June 24, 2005"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -337,12 +337,10 @@ static struct {
static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
{
if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
- unsigned long flags;
-
- spin_lock_irqsave(&tp->indirect_lock, flags);
+ spin_lock_bh(&tp->indirect_lock);
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
- spin_unlock_irqrestore(&tp->indirect_lock, flags);
+ spin_unlock_bh(&tp->indirect_lock);
} else {
writel(val, tp->regs + off);
if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0)
@@ -353,12 +351,10 @@ static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
static void _tw32_flush(struct tg3 *tp, u32 off, u32 val)
{
if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
- unsigned long flags;
-
- spin_lock_irqsave(&tp->indirect_lock, flags);
+ spin_lock_bh(&tp->indirect_lock);
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
- spin_unlock_irqrestore(&tp->indirect_lock, flags);
+ spin_unlock_bh(&tp->indirect_lock);
} else {
void __iomem *dest = tp->regs + off;
writel(val, dest);
@@ -398,28 +394,24 @@ static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
{
- unsigned long flags;
-
- spin_lock_irqsave(&tp->indirect_lock, flags);
+ spin_lock_bh(&tp->indirect_lock);
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
/* Always leave this as zero. */
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
- spin_unlock_irqrestore(&tp->indirect_lock, flags);
+ spin_unlock_bh(&tp->indirect_lock);
}
static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
{
- unsigned long flags;
-
- spin_lock_irqsave(&tp->indirect_lock, flags);
+ spin_lock_bh(&tp->indirect_lock);
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
/* Always leave this as zero. */
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
- spin_unlock_irqrestore(&tp->indirect_lock, flags);
+ spin_unlock_bh(&tp->indirect_lock);
}
static void tg3_disable_ints(struct tg3 *tp)
@@ -438,12 +430,14 @@ static inline void tg3_cond_int(struct tg3 *tp)
static void tg3_enable_ints(struct tg3 *tp)
{
+ tp->irq_sync = 0;
+ wmb();
+
tw32(TG3PCI_MISC_HOST_CTRL,
(tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
(tp->last_tag << 24));
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
-
tg3_cond_int(tp);
}
@@ -492,6 +486,7 @@ static void tg3_restart_ints(struct tg3 *tp)
static inline void tg3_netif_stop(struct tg3 *tp)
{
+ tp->dev->trans_start = jiffies; /* prevent tx timeout */
netif_poll_disable(tp->dev);
netif_tx_disable(tp->dev);
}
@@ -504,7 +499,8 @@ static inline void tg3_netif_start(struct tg3 *tp)
* (such as after tg3_init_hw)
*/
netif_poll_enable(tp->dev);
- tg3_cond_int(tp);
+ tp->hw_status->status |= SD_STATUS_UPDATED;
+ tg3_enable_ints(tp);
}
static void tg3_switch_clocks(struct tg3 *tp)
@@ -2578,7 +2574,7 @@ static void tg3_tx(struct tg3 *tp)
sw_idx = NEXT_TX(sw_idx);
}
- dev_kfree_skb_irq(skb);
+ dev_kfree_skb(skb);
}
tp->tx_cons = sw_idx;
@@ -2884,11 +2880,8 @@ static int tg3_poll(struct net_device *netdev, int *budget)
{
struct tg3 *tp = netdev_priv(netdev);
struct tg3_hw_status *sblk = tp->hw_status;
- unsigned long flags;
int done;
- spin_lock_irqsave(&tp->lock, flags);
-
/* handle link change and other phy events */
if (!(tp->tg3_flags &
(TG3_FLAG_USE_LINKCHG_REG |
@@ -2896,7 +2889,9 @@ static int tg3_poll(struct net_device *netdev, int *budget)
if (sblk->status & SD_STATUS_LINK_CHG) {
sblk->status = SD_STATUS_UPDATED |
(sblk->status & ~SD_STATUS_LINK_CHG);
+ spin_lock(&tp->lock);
tg3_setup_phy(tp, 0);
+ spin_unlock(&tp->lock);
}
}
@@ -2907,8 +2902,6 @@ static int tg3_poll(struct net_device *netdev, int *budget)
spin_unlock(&tp->tx_lock);
}
- spin_unlock_irqrestore(&tp->lock, flags);
-
/* run RX thread, within the bounds set by NAPI.
* All RX "locking" is done by ensuring outside
* code synchronizes with dev->poll()
@@ -2929,19 +2922,54 @@ static int tg3_poll(struct net_device *netdev, int *budget)
if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
tp->last_tag = sblk->status_tag;
rmb();
+ sblk->status &= ~SD_STATUS_UPDATED;
/* if no more work, tell net stack and NIC we're done */
done = !tg3_has_work(tp);
if (done) {
- spin_lock_irqsave(&tp->lock, flags);
- __netif_rx_complete(netdev);
+ spin_lock(&tp->lock);
+ netif_rx_complete(netdev);
tg3_restart_ints(tp);
- spin_unlock_irqrestore(&tp->lock, flags);
+ spin_unlock(&tp->lock);
}
return (done ? 0 : 1);
}
+static void tg3_irq_quiesce(struct tg3 *tp)
+{
+ BUG_ON(tp->irq_sync);
+
+ tp->irq_sync = 1;
+ smp_mb();
+
+ synchronize_irq(tp->pdev->irq);
+}
+
+static inline int tg3_irq_sync(struct tg3 *tp)
+{
+ return tp->irq_sync;
+}
+
+/* Fully shutdown all tg3 driver activity elsewhere in the system.
+ * If irq_sync is non-zero, then the IRQ handler must be synchronized
+ * with as well. Most of the time, this is not necessary except when
+ * shutting down the device.
+ */
+static inline void tg3_full_lock(struct tg3 *tp, int irq_sync)
+{
+ if (irq_sync)
+ tg3_irq_quiesce(tp);
+ spin_lock_bh(&tp->lock);
+ spin_lock(&tp->tx_lock);
+}
+
+static inline void tg3_full_unlock(struct tg3 *tp)
+{
+ spin_unlock(&tp->tx_lock);
+ spin_unlock_bh(&tp->lock);
+}
+
/* MSI ISR - No need to check for interrupt sharing and no need to
* flush status block and interrupt mailbox. PCI ordering rules
* guarantee that MSI will arrive after the status block.
@@ -2951,9 +2979,6 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
struct net_device *dev = dev_id;
struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;
- unsigned long flags;
-
- spin_lock_irqsave(&tp->lock, flags);
/*
* Writing any value to intr-mbox-0 clears PCI INTA# and
@@ -2964,6 +2989,9 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
*/
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
tp->last_tag = sblk->status_tag;
+ rmb();
+ if (tg3_irq_sync(tp))
+ goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */
@@ -2972,9 +3000,7 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs)
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
tp->last_tag << 24);
}
-
- spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
return IRQ_RETVAL(1);
}
@@ -2983,11 +3009,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct net_device *dev = dev_id;
struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;
- unsigned long flags;
unsigned int handled = 1;
- spin_lock_irqsave(&tp->lock, flags);
-
/* In INTx mode, it is possible for the interrupt to arrive at
* the CPU before the status block posted prior to the interrupt.
* Reading the PCI State register will confirm whether the
@@ -3004,6 +3027,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
0x00000001);
+ if (tg3_irq_sync(tp))
+ goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */
@@ -3018,9 +3043,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
} else { /* shared interrupt */
handled = 0;
}
-
- spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
return IRQ_RETVAL(handled);
}
@@ -3029,11 +3052,8 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
struct net_device *dev = dev_id;
struct tg3 *tp = netdev_priv(dev);
struct tg3_hw_status *sblk = tp->hw_status;
- unsigned long flags;
unsigned int handled = 1;
- spin_lock_irqsave(&tp->lock, flags);
-
/* In INTx mode, it is possible for the interrupt to arrive at
* the CPU before the status block posted prior to the interrupt.
* Reading the PCI State register will confirm whether the
@@ -3051,6 +3071,9 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
0x00000001);
tp->last_tag = sblk->status_tag;
+ rmb();
+ if (tg3_irq_sync(tp))
+ goto out;
sblk->status &= ~SD_STATUS_UPDATED;
if (likely(tg3_has_work(tp)))
netif_rx_schedule(dev); /* schedule NAPI poll */
@@ -3065,9 +3088,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
} else { /* shared interrupt */
handled = 0;
}
-
- spin_unlock_irqrestore(&tp->lock, flags);
-
+out:
return IRQ_RETVAL(handled);
}
@@ -3106,8 +3127,7 @@ static void tg3_reset_task(void *_data)
tg3_netif_stop(tp);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
@@ -3117,8 +3137,7 @@ static void tg3_reset_task(void *_data)
tg3_netif_start(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
if (restart_timer)
mod_timer(&tp->timer, jiffies + 1);
@@ -3224,39 +3243,21 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned int i;
u32 len, entry, base_flags, mss;
int would_hit_hwbug;
- unsigned long flags;
len = skb_headlen(skb);
/* No BH disabling for tx_lock here. We are running in BH disabled
* context and TX reclaim runs via tp->poll inside of a software
- * interrupt. Rejoice!
- *
- * Actually, things are not so simple. If we are to take a hw
- * IRQ here, we can deadlock, consider:
- *
- * CPU1 CPU2
- * tg3_start_xmit
- * take tp->tx_lock
- * tg3_timer
- * take tp->lock
- * tg3_interrupt
- * spin on tp->lock
- * spin on tp->tx_lock
- *
- * So we really do need to disable interrupts when taking
- * tx_lock here.
+ * interrupt. Furthermore, IRQ processing runs lockless so we have
+ * no IRQ context deadlocks to worry about either. Rejoice!
*/
- local_irq_save(flags);
- if (!spin_trylock(&tp->tx_lock)) {
- local_irq_restore(flags);
+ if (!spin_trylock(&tp->tx_lock))
return NETDEV_TX_LOCKED;
- }
/* This is a hard error, log it. */
if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
netif_stop_queue(dev);
- spin_unlock_irqrestore(&tp->tx_lock, flags);
+ spin_unlock(&tp->tx_lock);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
return NETDEV_TX_BUSY;
@@ -3421,7 +3422,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
out_unlock:
mmiowb();
- spin_unlock_irqrestore(&tp->tx_lock, flags);
+ spin_unlock(&tp->tx_lock);
dev->trans_start = jiffies;
@@ -3455,8 +3456,8 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
}
tg3_netif_stop(tp);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+
+ tg3_full_lock(tp, 1);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
@@ -3466,8 +3467,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
tg3_netif_start(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return 0;
}
@@ -5088,9 +5088,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p)
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
__tg3_set_mac_addr(tp);
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return 0;
}
@@ -5727,9 +5727,6 @@ static int tg3_reset_hw(struct tg3 *tp)
tg3_write_sig_post_reset(tp, RESET_KIND_INIT);
- if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)
- tg3_enable_ints(tp);
-
return 0;
}
@@ -5802,10 +5799,8 @@ static void tg3_periodic_fetch_stats(struct tg3 *tp)
static void tg3_timer(unsigned long __opaque)
{
struct tg3 *tp = (struct tg3 *) __opaque;
- unsigned long flags;
- spin_lock_irqsave(&tp->lock, flags);
- spin_lock(&tp->tx_lock);
+ spin_lock(&tp->lock);
if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
/* All of this garbage is because when using non-tagged
@@ -5822,8 +5817,7 @@ static void tg3_timer(unsigned long __opaque)
if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
- spin_unlock(&tp->tx_lock);
- spin_unlock_irqrestore(&tp->lock, flags);
+ spin_unlock(&tp->lock);
schedule_work(&tp->reset_task);
return;
}
@@ -5891,8 +5885,7 @@ static void tg3_timer(unsigned long __opaque)
tp->asf_counter = tp->asf_multiplier;
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irqrestore(&tp->lock, flags);
+ spin_unlock(&tp->lock);
tp->timer.expires = jiffies + tp->timer_offset;
add_timer(&tp->timer);
@@ -6007,14 +6000,12 @@ static int tg3_test_msi(struct tg3 *tp)
/* Need to reset the chip because the MSI cycle may have terminated
* with Master Abort.
*/
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
err = tg3_init_hw(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
if (err)
free_irq(tp->pdev->irq, dev);
@@ -6027,14 +6018,12 @@ static int tg3_open(struct net_device *dev)
struct tg3 *tp = netdev_priv(dev);
int err;
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tg3_disable_ints(tp);
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
/* The placement of this call is tied
* to the setup and use of Host TX descriptors.
@@ -6081,8 +6070,7 @@ static int tg3_open(struct net_device *dev)
return err;
}
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
err = tg3_init_hw(tp);
if (err) {
@@ -6106,8 +6094,7 @@ static int tg3_open(struct net_device *dev)
tp->timer.function = tg3_timer;
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
if (err) {
free_irq(tp->pdev->irq, dev);
@@ -6123,8 +6110,7 @@ static int tg3_open(struct net_device *dev)
err = tg3_test_msi(tp);
if (err) {
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
pci_disable_msi(tp->pdev);
@@ -6134,22 +6120,19 @@ static int tg3_open(struct net_device *dev)
tg3_free_rings(tp);
tg3_free_consistent(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return err;
}
}
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
add_timer(&tp->timer);
tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
tg3_enable_ints(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
netif_start_queue(dev);
@@ -6395,8 +6378,7 @@ static int tg3_close(struct net_device *dev)
del_timer_sync(&tp->timer);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
#if 0
tg3_dump_state(tp);
#endif
@@ -6410,8 +6392,7 @@ static int tg3_close(struct net_device *dev)
TG3_FLAG_GOT_SERDES_FLOWCTL);
netif_carrier_off(tp->dev);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
free_irq(tp->pdev->irq, dev);
if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
@@ -6448,16 +6429,15 @@ static unsigned long calc_crc_errors(struct tg3 *tp)
if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
- unsigned long flags;
u32 val;
- spin_lock_irqsave(&tp->lock, flags);
+ spin_lock_bh(&tp->lock);
if (!tg3_readphy(tp, 0x1e, &val)) {
tg3_writephy(tp, 0x1e, val | 0x8000);
tg3_readphy(tp, 0x14, &val);
} else
val = 0;
- spin_unlock_irqrestore(&tp->lock, flags);
+ spin_unlock_bh(&tp->lock);
tp->phy_crc_errors += val;
@@ -6719,11 +6699,9 @@ static void tg3_set_rx_mode(struct net_device *dev)
{
struct tg3 *tp = netdev_priv(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
__tg3_set_rx_mode(dev);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
#define TG3_REGDUMP_LEN (32 * 1024)
@@ -6745,8 +6723,7 @@ static void tg3_get_regs(struct net_device *dev,
memset(p, 0, TG3_REGDUMP_LEN);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
#define __GET_REG32(reg) (*(p)++ = tr32(reg))
#define GET_REG32_LOOP(base,len) \
@@ -6796,8 +6773,7 @@ do { p = (u32 *)(orig_p + (reg)); \
#undef GET_REG32_LOOP
#undef GET_REG32_1
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
static int tg3_get_eeprom_len(struct net_device *dev)
@@ -6973,8 +6949,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
return -EINVAL;
}
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tp->link_config.autoneg = cmd->autoneg;
if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -6990,8 +6965,7 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
if (netif_running(dev))
tg3_setup_phy(tp, 1);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return 0;
}
@@ -7027,12 +7001,12 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
!(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP))
return -EINVAL;
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
if (wol->wolopts & WAKE_MAGIC)
tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
else
tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return 0;
}
@@ -7072,7 +7046,7 @@ static int tg3_nway_reset(struct net_device *dev)
if (!netif_running(dev))
return -EAGAIN;
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
r = -EINVAL;
tg3_readphy(tp, MII_BMCR, &bmcr);
if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
@@ -7080,7 +7054,7 @@ static int tg3_nway_reset(struct net_device *dev)
tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART);
r = 0;
}
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return r;
}
@@ -7102,17 +7076,19 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam *
static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
{
struct tg3 *tp = netdev_priv(dev);
+ int irq_sync = 0;
if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) ||
(ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) ||
(ering->tx_pending > TG3_TX_RING_SIZE - 1))
return -EINVAL;
- if (netif_running(dev))
+ if (netif_running(dev)) {
tg3_netif_stop(tp);
+ irq_sync = 1;
+ }
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, irq_sync);
tp->rx_pending = ering->rx_pending;
@@ -7128,8 +7104,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
tg3_netif_start(tp);
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return 0;
}
@@ -7146,12 +7121,15 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam
static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
{
struct tg3 *tp = netdev_priv(dev);
+ int irq_sync = 0;
- if (netif_running(dev))
+ if (netif_running(dev)) {
tg3_netif_stop(tp);
+ irq_sync = 1;
+ }
+
+ tg3_full_lock(tp, irq_sync);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
if (epause->autoneg)
tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
else
@@ -7170,8 +7148,8 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
tg3_init_hw(tp);
tg3_netif_start(tp);
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+
+ tg3_full_unlock(tp);
return 0;
}
@@ -7192,12 +7170,12 @@ static int tg3_set_rx_csum(struct net_device *dev, u32 data)
return 0;
}
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
if (data)
tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
else
tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return 0;
}
@@ -7606,8 +7584,6 @@ static int tg3_test_loopback(struct tg3 *tp)
tg3_abort_hw(tp, 1);
- /* Clearing this flag to keep interrupts disabled */
- tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
tg3_reset_hw(tp);
mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) |
@@ -7716,11 +7692,14 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
data[1] = 1;
}
if (etest->flags & ETH_TEST_FL_OFFLINE) {
- if (netif_running(dev))
+ int irq_sync = 0;
+
+ if (netif_running(dev)) {
tg3_netif_stop(tp);
+ irq_sync = 1;
+ }
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, irq_sync);
tg3_halt(tp, RESET_KIND_SUSPEND, 1);
tg3_nvram_lock(tp);
@@ -7742,14 +7721,14 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
data[4] = 1;
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
+
if (tg3_test_interrupt(tp) != 0) {
etest->flags |= ETH_TEST_FL_FAILED;
data[5] = 1;
}
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+
+ tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
if (netif_running(dev)) {
@@ -7757,8 +7736,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
tg3_init_hw(tp);
tg3_netif_start(tp);
}
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+
+ tg3_full_unlock(tp);
}
}
@@ -7779,9 +7758,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
break; /* We have no PHY */
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval);
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
data->val_out = mii_regval;
@@ -7795,9 +7774,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- spin_lock_irq(&tp->lock);
+ spin_lock_bh(&tp->lock);
err = tg3_writephy(tp, data->reg_num & 0x1f, data->val_in);
- spin_unlock_irq(&tp->lock);
+ spin_unlock_bh(&tp->lock);
return err;
@@ -7813,28 +7792,24 @@ static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
{
struct tg3 *tp = netdev_priv(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tp->vlgrp = grp;
/* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
__tg3_set_rx_mode(dev);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
{
struct tg3 *tp = netdev_priv(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
if (tp->vlgrp)
tp->vlgrp->vlan_devices[vid] = NULL;
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
#endif
@@ -10165,24 +10140,19 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
del_timer_sync(&tp->timer);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 1);
tg3_disable_ints(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
netif_device_detach(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
if (err) {
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tg3_init_hw(tp);
@@ -10192,8 +10162,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
netif_device_attach(dev);
tg3_netif_start(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
}
return err;
@@ -10216,20 +10185,16 @@ static int tg3_resume(struct pci_dev *pdev)
netif_device_attach(dev);
- spin_lock_irq(&tp->lock);
- spin_lock(&tp->tx_lock);
+ tg3_full_lock(tp, 0);
tg3_init_hw(tp);
tp->timer.expires = jiffies + tp->timer_offset;
add_timer(&tp->timer);
- tg3_enable_ints(tp);
-
tg3_netif_start(tp);
- spin_unlock(&tp->tx_lock);
- spin_unlock_irq(&tp->lock);
+ tg3_full_unlock(tp);
return 0;
}
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 993f84c93dc..99c5f9675a5 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2006,17 +2006,31 @@ struct tg3_ethtool_stats {
struct tg3 {
/* begin "general, frequently-used members" cacheline section */
+ /* If the IRQ handler (which runs lockless) needs to be
+ * quiesced, the following bitmask state is used. The
+ * SYNC flag is set by non-IRQ context code to initiate
+ * the quiescence.
+ *
+ * When the IRQ handler notices that SYNC is set, it
+ * disables interrupts and returns.
+ *
+ * When all outstanding IRQ handlers have returned after
+ * the SYNC flag has been set, the setter can be assured
+ * that interrupts will no longer get run.
+ *
+ * In this way all SMP driver locks are never acquired
+ * in hw IRQ context, only sw IRQ context or lower.
+ */
+ unsigned int irq_sync;
+
/* SMP locking strategy:
*
* lock: Held during all operations except TX packet
* processing.
*
- * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx
+ * tx_lock: Held during tg3_start_xmit and tg3_tx
*
- * If you want to shut up all asynchronous processing you must
- * acquire both locks, 'lock' taken before 'tx_lock'. IRQs must
- * be disabled to take 'lock' but only softirq disabling is
- * necessary for acquisition of 'tx_lock'.
+ * Both of these locks are to be held with BH safety.
*/
spinlock_t lock;
spinlock_t indirect_lock;
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 66b94668ddd..18c27e1e788 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -435,7 +435,7 @@ config VENDOR_SANGOMA
the driver to support.
If you have one or more of these cards, say M to this option;
- and read <file:Documentation/networking/wanpipe.txt>.
+ and read <file:Documentation/networking/wan-router.txt>.
To compile this driver as a module, choose M here: the
module will be called wanpipe.
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 1c540d82555..bdf672c4818 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -829,7 +829,7 @@ static void __exit exit_x25_asy(void)
}
kfree(x25_asy_devs);
- tty_register_ldisc(N_X25, NULL);
+ tty_unregister_ldisc(N_X25);
}
module_init(init_x25_asy);
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index fb10a2db63a..d72e0385e4f 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2918,7 +2918,7 @@ static int airo_thread(void *data) {
flush_signals(current);
/* make swsusp happy with our thread */
- try_to_freeze(PF_FREEZE);
+ try_to_freeze();
if (test_bit(JOB_DIE, &ai->flags))
break;
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index ec8cf29ffce..6c42b573a95 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -2828,7 +2828,7 @@ static void __exit strip_exit_driver(void)
/* Unregister with the /proc/net file here. */
proc_net_remove("strip");
- if ((i = tty_register_ldisc(N_STRIP, NULL)))
+ if ((i = tty_unregister_ldisc(N_STRIP)))
printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
printk(signoff);
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 745a1418363..531b0731314 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -206,7 +206,7 @@ static inline unsigned long fast_get_dcookie(struct dentry * dentry,
*/
static unsigned long get_exec_dcookie(struct mm_struct * mm)
{
- unsigned long cookie = 0;
+ unsigned long cookie = NO_COOKIE;
struct vm_area_struct * vma;
if (!mm)
@@ -234,35 +234,42 @@ out:
*/
static unsigned long lookup_dcookie(struct mm_struct * mm, unsigned long addr, off_t * offset)
{
- unsigned long cookie = 0;
+ unsigned long cookie = NO_COOKIE;
struct vm_area_struct * vma;
for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
- if (!vma->vm_file)
- continue;
-
if (addr < vma->vm_start || addr >= vma->vm_end)
continue;
- cookie = fast_get_dcookie(vma->vm_file->f_dentry,
- vma->vm_file->f_vfsmnt);
- *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - vma->vm_start;
+ if (vma->vm_file) {
+ cookie = fast_get_dcookie(vma->vm_file->f_dentry,
+ vma->vm_file->f_vfsmnt);
+ *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr -
+ vma->vm_start;
+ } else {
+ /* must be an anonymous map */
+ *offset = addr;
+ }
+
break;
}
+ if (!vma)
+ cookie = INVALID_COOKIE;
+
return cookie;
}
-static unsigned long last_cookie = ~0UL;
+static unsigned long last_cookie = INVALID_COOKIE;
static void add_cpu_switch(int i)
{
add_event_entry(ESCAPE_CODE);
add_event_entry(CPU_SWITCH_CODE);
add_event_entry(i);
- last_cookie = ~0UL;
+ last_cookie = INVALID_COOKIE;
}
static void add_kernel_ctx_switch(unsigned int in_kernel)
@@ -317,7 +324,7 @@ static int add_us_sample(struct mm_struct * mm, struct op_sample * s)
cookie = lookup_dcookie(mm, s->eip, &offset);
- if (!cookie) {
+ if (cookie == INVALID_COOKIE) {
atomic_inc(&oprofile_stats.sample_lost_no_mapping);
return 0;
}
diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h
index 442aaad391e..01802363059 100644
--- a/drivers/oprofile/event_buffer.h
+++ b/drivers/oprofile/event_buffer.h
@@ -35,6 +35,9 @@ void wake_up_buffer_waiter(void);
#define TRACE_BEGIN_CODE 8
#define TRACE_END_CODE 9
+#define INVALID_COOKIE ~0UL
+#define NO_COOKIE 0UL
+
/* add data to the event buffer */
void add_event_entry(unsigned long data);
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index e7f3bcb7900..80edfa3abd2 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -2751,7 +2751,6 @@ enum parport_pc_pci_cards {
netmos_9755,
netmos_9805,
netmos_9815,
- netmos_9855,
};
@@ -2826,7 +2825,6 @@ static struct parport_pc_pci {
/* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */
/* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */
/* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
- /* netmos_9855 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
};
static struct pci_device_id parport_pc_pci_tbl[] = {
@@ -2907,8 +2905,6 @@ static struct pci_device_id parport_pc_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 },
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 },
- { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
{ 0, } /* terminate list */
};
MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 6715a17b5d0..00498e2f120 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -34,6 +34,7 @@ enum parport_pc_pci_cards {
titan_110l = 0,
titan_210l,
netmos_9xx5_combo,
+ netmos_9855,
avlab_1s1p,
avlab_1s1p_650,
avlab_1s1p_850,
@@ -87,6 +88,7 @@ static struct parport_pc_pci cards[] __devinitdata = {
/* titan_110l */ { 1, { { 3, -1 }, } },
/* titan_210l */ { 1, { { 3, -1 }, } },
/* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init },
+ /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init },
/* avlab_1s1p */ { 1, { { 1, 2}, } },
/* avlab_1s1p_650 */ { 1, { { 1, 2}, } },
/* avlab_1s1p_850 */ { 1, { { 1, 2}, } },
@@ -120,7 +122,7 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
{ PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
/* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
{ 0x14db, 0x2110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p},
{ 0x14db, 0x2111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p_650},
@@ -207,6 +209,7 @@ static struct pci_board_no_ids pci_boards[] __devinitdata = {
/* titan_110l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 1, 921600 },
/* titan_210l */ { SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
/* netmos_9xx5_combo */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init },
+/* netmos_9855 */ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200, 0, 0, netmos_serial_init },
/* avlab_1s1p (n/t) */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
/* avlab_1s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
/* avlab_1s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
index c94963145e1..6e6f42d01e6 100644
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -48,14 +48,6 @@ static void pretty_print(struct parport *port, int device)
printk("\n");
}
-static char *strdup(char *str)
-{
- int n = strlen(str)+1;
- char *s = kmalloc(n, GFP_KERNEL);
- if (!s) return NULL;
- return strcpy(s, str);
-}
-
static void parse_data(struct parport *port, int device, char *str)
{
char *txt = kmalloc(strlen(str)+1, GFP_KERNEL);
@@ -88,16 +80,16 @@ static void parse_data(struct parport *port, int device, char *str)
if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
if (info->mfr)
kfree (info->mfr);
- info->mfr = strdup(sep);
+ info->mfr = kstrdup(sep, GFP_KERNEL);
} else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
if (info->model)
kfree (info->model);
- info->model = strdup(sep);
+ info->model = kstrdup(sep, GFP_KERNEL);
} else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
int i;
if (info->class_name)
kfree (info->class_name);
- info->class_name = strdup(sep);
+ info->class_name = kstrdup(sep, GFP_KERNEL);
for (u = sep; *u; u++)
*u = toupper(*u);
for (i = 0; classes[i].token; i++) {
@@ -112,7 +104,7 @@ static void parse_data(struct parport *port, int device, char *str)
!strcmp(p, "COMMAND SET")) {
if (info->cmdset)
kfree (info->cmdset);
- info->cmdset = strdup(sep);
+ info->cmdset = kstrdup(sep, GFP_KERNEL);
/* if it speaks printer language, it's
probably a printer */
if (strstr(sep, "PJL") || strstr(sep, "PCL"))
@@ -120,7 +112,7 @@ static void parse_data(struct parport *port, int device, char *str)
} else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
if (info->description)
kfree (info->description);
- info->description = strdup(sep);
+ info->description = kstrdup(sep, GFP_KERNEL);
}
}
rock_on:
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 03fc885db1c..48e4f04530d 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -508,6 +508,10 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
cs_err(skt, "unsupported voltage key.\n");
return CS_BAD_TYPE;
}
+
+ if (skt->power_hook)
+ skt->power_hook(skt, HOOK_POWER_PRE);
+
skt->socket.flags = 0;
skt->ops->set_socket(skt, &skt->socket);
@@ -522,7 +526,12 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
return CS_BAD_TYPE;
}
- return socket_reset(skt);
+ status = socket_reset(skt);
+
+ if (skt->power_hook)
+ skt->power_hook(skt, HOOK_POWER_POST);
+
+ return status;
}
/*
@@ -709,7 +718,7 @@ static int pccardd(void *__skt)
}
schedule();
- try_to_freeze(PF_FREEZE);
+ try_to_freeze();
if (!skt->thread)
break;
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index a8a1d104524..c7ba99871ac 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -611,6 +611,170 @@ out:
}
}
+
+/* Returns true value if the second slot of a two-slot controller is empty */
+static int ti12xx_2nd_slot_empty(struct yenta_socket *socket)
+{
+ struct pci_dev *func;
+ struct yenta_socket *slot2;
+ int devfn;
+ unsigned int state;
+ int ret = 1;
+
+ /* catch the two-slot controllers */
+ switch (socket->dev->device) {
+ case PCI_DEVICE_ID_TI_1220:
+ case PCI_DEVICE_ID_TI_1221:
+ case PCI_DEVICE_ID_TI_1225:
+ case PCI_DEVICE_ID_TI_1251A:
+ case PCI_DEVICE_ID_TI_1251B:
+ case PCI_DEVICE_ID_TI_1420:
+ case PCI_DEVICE_ID_TI_1450:
+ case PCI_DEVICE_ID_TI_1451A:
+ case PCI_DEVICE_ID_TI_1520:
+ case PCI_DEVICE_ID_TI_1620:
+ case PCI_DEVICE_ID_TI_4520:
+ case PCI_DEVICE_ID_TI_4450:
+ case PCI_DEVICE_ID_TI_4451:
+ /*
+ * there are way more, but they need to be added in yenta_socket.c
+ * and pci_ids.h first anyway.
+ */
+ break;
+
+ /* single-slot controllers have the 2nd slot empty always :) */
+ default:
+ return 1;
+ }
+
+ /* get other slot */
+ devfn = socket->dev->devfn & ~0x07;
+ func = pci_get_slot(socket->dev->bus,
+ (socket->dev->devfn & 0x07) ? devfn : devfn | 0x01);
+ if (!func)
+ return 1;
+
+ slot2 = pci_get_drvdata(func);
+ if (!slot2)
+ goto out;
+
+ /* check state */
+ yenta_get_status(&socket->socket, &state);
+ if (state & SS_DETECT) {
+ ret = 0;
+ goto out;
+ }
+
+out:
+ pci_dev_put(func);
+ return ret;
+}
+
+/*
+ * TI specifiy parts for the power hook.
+ *
+ * some TI's with some CB's produces interrupt storm on power on. it has been
+ * seen with atheros wlan cards on TI1225 and TI1410. solution is simply to
+ * disable any CB interrupts during this time.
+ */
+static int ti12xx_power_hook(struct pcmcia_socket *sock, int operation)
+{
+ struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+ u32 mfunc, devctl, sysctl;
+ u8 gpio3;
+
+ /* only POWER_PRE and POWER_POST are interesting */
+ if ((operation != HOOK_POWER_PRE) && (operation != HOOK_POWER_POST))
+ return 0;
+
+ devctl = config_readb(socket, TI113X_DEVICE_CONTROL);
+ sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL);
+ mfunc = config_readl(socket, TI122X_MFUNC);
+
+ /*
+ * all serial/tied: only disable when modparm set. always doing it
+ * would mean a regression for working setups 'cos it disables the
+ * interrupts for both both slots on 2-slot controllers
+ * (and users of single slot controllers where it's save have to
+ * live with setting the modparm, most don't have to anyway)
+ */
+ if (((devctl & TI113X_DCR_IMODE_MASK) == TI12XX_DCR_IMODE_ALL_SERIAL) &&
+ (pwr_irqs_off || ti12xx_2nd_slot_empty(socket))) {
+ switch (socket->dev->device) {
+ case PCI_DEVICE_ID_TI_1250:
+ case PCI_DEVICE_ID_TI_1251A:
+ case PCI_DEVICE_ID_TI_1251B:
+ case PCI_DEVICE_ID_TI_1450:
+ case PCI_DEVICE_ID_TI_1451A:
+ case PCI_DEVICE_ID_TI_4450:
+ case PCI_DEVICE_ID_TI_4451:
+ /* these chips have no IRQSER setting in MFUNC3 */
+ break;
+
+ default:
+ if (operation == HOOK_POWER_PRE)
+ mfunc = (mfunc & ~TI122X_MFUNC3_MASK);
+ else
+ mfunc = (mfunc & ~TI122X_MFUNC3_MASK) | TI122X_MFUNC3_IRQSER;
+ }
+
+ return 0;
+ }
+
+ /* do the job differently for func0/1 */
+ if ((PCI_FUNC(socket->dev->devfn) == 0) ||
+ ((sysctl & TI122X_SCR_INTRTIE) &&
+ (pwr_irqs_off || ti12xx_2nd_slot_empty(socket)))) {
+ /* some bridges are different */
+ switch (socket->dev->device) {
+ case PCI_DEVICE_ID_TI_1250:
+ case PCI_DEVICE_ID_TI_1251A:
+ case PCI_DEVICE_ID_TI_1251B:
+ case PCI_DEVICE_ID_TI_1450:
+ /* those oldies use gpio3 for INTA */
+ gpio3 = config_readb(socket, TI1250_GPIO3_CONTROL);
+ if (operation == HOOK_POWER_PRE)
+ gpio3 = (gpio3 & ~TI1250_GPIO_MODE_MASK) | 0x40;
+ else
+ gpio3 &= ~TI1250_GPIO_MODE_MASK;
+ config_writeb(socket, TI1250_GPIO3_CONTROL, gpio3);
+ break;
+
+ default:
+ /* all new bridges are the same */
+ if (operation == HOOK_POWER_PRE)
+ mfunc &= ~TI122X_MFUNC0_MASK;
+ else
+ mfunc |= TI122X_MFUNC0_INTA;
+ config_writel(socket, TI122X_MFUNC, mfunc);
+ }
+ } else {
+ switch (socket->dev->device) {
+ case PCI_DEVICE_ID_TI_1251A:
+ case PCI_DEVICE_ID_TI_1251B:
+ case PCI_DEVICE_ID_TI_1450:
+ /* those have INTA elsewhere and INTB in MFUNC0 */
+ if (operation == HOOK_POWER_PRE)
+ mfunc &= ~TI122X_MFUNC0_MASK;
+ else
+ mfunc |= TI125X_MFUNC0_INTB;
+ config_writel(socket, TI122X_MFUNC, mfunc);
+
+ break;
+
+ default:
+ /* all new bridges are the same */
+ if (operation == HOOK_POWER_PRE)
+ mfunc &= ~TI122X_MFUNC1_MASK;
+ else
+ mfunc |= TI122X_MFUNC1_INTB;
+ config_writel(socket, TI122X_MFUNC, mfunc);
+ }
+ }
+
+ return 0;
+}
+
static int ti12xx_override(struct yenta_socket *socket)
{
u32 val, val_orig;
@@ -654,6 +818,9 @@ static int ti12xx_override(struct yenta_socket *socket)
else
ti12xx_irqroute_func1(socket);
+ /* install power hook */
+ socket->socket.power_hook = ti12xx_power_hook;
+
return ti_override(socket);
}
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 6404d97a12e..bee05362fd2 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -32,6 +32,14 @@ static int disable_clkrun;
module_param(disable_clkrun, bool, 0444);
MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option");
+static int isa_probe = 1;
+module_param(isa_probe, bool, 0444);
+MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing");
+
+static int pwr_irqs_off;
+module_param(pwr_irqs_off, bool, 0644);
+MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
+
#if 0
#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
#else
@@ -150,15 +158,16 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
val = (state & CB_3VCARD) ? SS_3VCARD : 0;
val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
- val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD
- | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
+ val |= (state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
+ val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? SS_PENDING : 0;
+
if (state & CB_CBCARD) {
val |= SS_CARDBUS;
val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
- } else {
+ } else if (state & CB_16BITCARD) {
u8 status = exca_readb(socket, I365_STATUS);
val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
@@ -405,11 +414,13 @@ static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *
}
-static unsigned int yenta_events(struct yenta_socket *socket)
+
+static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
+ unsigned int events;
+ struct yenta_socket *socket = (struct yenta_socket *) dev_id;
u8 csc;
u32 cb_event;
- unsigned int events;
/* Clear interrupt status for the event */
cb_event = cb_readl(socket, CB_SOCKET_EVENT);
@@ -426,20 +437,13 @@ static unsigned int yenta_events(struct yenta_socket *socket)
events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
events |= (csc & I365_CSC_READY) ? SS_READY : 0;
}
- return events;
-}
-
-
-static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- unsigned int events;
- struct yenta_socket *socket = (struct yenta_socket *) dev_id;
- events = yenta_events(socket);
- if (events) {
+ if (events)
pcmcia_parse_events(&socket->socket, events);
+
+ if (cb_event || csc)
return IRQ_HANDLED;
- }
+
return IRQ_NONE;
}
@@ -470,11 +474,22 @@ static void yenta_clear_maps(struct yenta_socket *socket)
}
}
+/* redoes voltage interrogation if required */
+static void yenta_interrogate(struct yenta_socket *socket)
+{
+ u32 state;
+
+ state = cb_readl(socket, CB_SOCKET_STATE);
+ if (!(state & (CB_5VCARD | CB_3VCARD | CB_XVCARD | CB_YVCARD)) ||
+ (state & (CB_CDETECT1 | CB_CDETECT2 | CB_NOTACARD | CB_BADVCCREQ)) ||
+ ((state & (CB_16BITCARD | CB_CBCARD)) == (CB_16BITCARD | CB_CBCARD)))
+ cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
+}
+
/* Called at resume and initialization events */
static int yenta_sock_init(struct pcmcia_socket *sock)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
- u32 state;
u16 bridge;
bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~CB_BRIDGE_INTR;
@@ -486,10 +501,7 @@ static int yenta_sock_init(struct pcmcia_socket *sock)
exca_writeb(socket, I365_GENCTL, 0x00);
/* Redo card voltage interrogation */
- state = cb_readl(socket, CB_SOCKET_STATE);
- if (!(state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD |
- CB_3VCARD | CB_XVCARD | CB_YVCARD)))
- cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
+ yenta_interrogate(socket);
yenta_clear_maps(socket);
@@ -856,7 +868,10 @@ static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_i
socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
socket->socket.map_size = 0x1000;
socket->socket.pci_irq = socket->cb_irq;
- socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
+ if (isa_probe)
+ socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
+ else
+ socket->socket.irq_mask = 0;
socket->socket.cb_dev = socket->dev;
printk(KERN_INFO "Yenta: ISA IRQ mask 0x%04x, PCI irq %d\n",
@@ -996,6 +1011,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
}
/* Figure out what the dang thing can do for the PCMCIA layer... */
+ yenta_interrogate(socket);
yenta_get_socket_capabilities(socket, isa_interrupts);
printk(KERN_INFO "Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index 3252662958d..add12f7c489 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -259,7 +259,6 @@ int pnp_add_card_device(struct pnp_card * card, struct pnp_dev * dev)
/**
* pnp_remove_card_device- removes a device from the specified card
- * @card: pointer to the card to remove from
* @dev: pointer to the device to remove
*/
@@ -274,7 +273,7 @@ void pnp_remove_card_device(struct pnp_dev * dev)
/**
* pnp_request_card_device - Searches for a PnP device under the specified card
- * @lcard: pointer to the card link, cannot be NULL
+ * @clink: pointer to the card link, cannot be NULL
* @id: pointer to a PnP ID structure that explains the rules for finding the device
* @from: Starting place to search from. If NULL it will start from the begining.
*/
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 65ecef73853..6c510c19ad7 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -390,6 +390,7 @@ fail:
* pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
* @dev: pointer to the desired device
* @res: pointer to the new resource config
+ * @mode: 0 or PNP_CONFIG_FORCE
*
* This function can be used by drivers that want to manually set thier resources.
*/
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index e939c93a931..778a324028f 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -182,7 +182,7 @@ static int pnp_dock_thread(void * unused)
msleep_interruptible(2000);
if(signal_pending(current)) {
- if (try_to_freeze(PF_FREEZE))
+ if (try_to_freeze())
continue;
break;
}
diff --git a/drivers/s390/Kconfig b/drivers/s390/Kconfig
index 96413c2cd1a..a86a650f3d6 100644
--- a/drivers/s390/Kconfig
+++ b/drivers/s390/Kconfig
@@ -187,6 +187,13 @@ config VMLOGRDR
*SYMPTOM.
This driver depends on the IUCV support driver.
+config VMCP
+ tristate "Support for the z/VM CP interface (VM only)"
+ help
+ Select this option if you want to be able to interact with the control
+ program on z/VM
+
+
config MONREADER
tristate "API for reading z/VM monitor service records"
depends on IUCV
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index ceeb3cf64a1..6527ff6f470 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -176,7 +176,7 @@ dasd_state_known_to_basic(struct dasd_device * device)
return rc;
/* register 'device' debug area, used for all DBF_DEV_XXX calls */
- device->debug_area = debug_register(device->cdev->dev.bus_id, 0, 2,
+ device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2,
8 * sizeof (long));
debug_register_view(device->debug_area, &debug_sprintf_view);
debug_set_level(device->debug_area, DBF_EMERG);
@@ -1952,26 +1952,24 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
* Automatically online either all dasd devices (dasd_autodetect) or
* all devices specified with dasd= parameters.
*/
+static int
+__dasd_auto_online(struct device *dev, void *data)
+{
+ struct ccw_device *cdev;
+
+ cdev = to_ccwdev(dev);
+ if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
+ ccw_device_set_online(cdev);
+ return 0;
+}
+
void
dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
{
struct device_driver *drv;
- struct device *d, *dev;
- struct ccw_device *cdev;
drv = get_driver(&dasd_discipline_driver->driver);
- down_read(&drv->bus->subsys.rwsem);
- dev = NULL;
- list_for_each_entry(d, &drv->devices, driver_list) {
- dev = get_device(d);
- if (!dev)
- continue;
- cdev = to_ccwdev(dev);
- if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
- ccw_device_set_online(cdev);
- put_device(dev);
- }
- up_read(&drv->bus->subsys.rwsem);
+ driver_for_each_device(drv, NULL, NULL, __dasd_auto_online);
put_driver(drv);
}
@@ -1983,7 +1981,7 @@ dasd_init(void)
init_waitqueue_head(&dasd_init_waitq);
/* register 'common' DASD debug area, used for all DBF_XXX calls */
- dasd_debug_area = debug_register("dasd", 0, 2, 8 * sizeof (long));
+ dasd_debug_area = debug_register("dasd", 1, 2, 8 * sizeof (long));
if (dasd_debug_area == NULL) {
rc = -ENOMEM;
goto failed;
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index d7f19745911..43c34f8c5e6 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -9,13 +9,14 @@
*
* /proc interface for the dasd driver.
*
- * $Revision: 1.31 $
+ * $Revision: 1.32 $
*/
#include <linux/config.h>
#include <linux/ctype.h>
#include <linux/seq_file.h>
#include <linux/vmalloc.h>
+#include <linux/proc_fs.h>
#include <asm/debug.h>
#include <asm/uaccess.h>
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 16ab8d363ac..4fde4118899 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -35,14 +35,17 @@
static int dcssblk_open(struct inode *inode, struct file *filp);
static int dcssblk_release(struct inode *inode, struct file *filp);
static int dcssblk_make_request(struct request_queue *q, struct bio *bio);
+static int dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
+ unsigned long *data);
static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";
static int dcssblk_major;
static struct block_device_operations dcssblk_devops = {
- .owner = THIS_MODULE,
- .open = dcssblk_open,
- .release = dcssblk_release,
+ .owner = THIS_MODULE,
+ .open = dcssblk_open,
+ .release = dcssblk_release,
+ .direct_access = dcssblk_direct_access,
};
static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
@@ -641,6 +644,20 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
/* Request beyond end of DCSS segment. */
goto fail;
}
+ /* verify data transfer direction */
+ if (dev_info->is_shared) {
+ switch (dev_info->segment_type) {
+ case SEG_TYPE_SR:
+ case SEG_TYPE_ER:
+ case SEG_TYPE_SC:
+ /* cannot write to these segments */
+ if (bio_data_dir(bio) == WRITE) {
+ PRINT_WARN("rejecting write to ro segment %s\n", dev_info->dev.bus_id);
+ goto fail;
+ }
+ }
+ }
+
index = (bio->bi_sector >> 3);
bio_for_each_segment(bvec, bio, i) {
page_addr = (unsigned long)
@@ -661,7 +678,26 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
bio_endio(bio, bytes_done, 0);
return 0;
fail:
- bio_io_error(bio, bytes_done);
+ bio_io_error(bio, bio->bi_size);
+ return 0;
+}
+
+static int
+dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
+ unsigned long *data)
+{
+ struct dcssblk_dev_info *dev_info;
+ unsigned long pgoff;
+
+ dev_info = bdev->bd_disk->private_data;
+ if (!dev_info)
+ return -ENODEV;
+ if (secnum % (PAGE_SIZE/512))
+ return -EINVAL;
+ pgoff = secnum / (PAGE_SIZE / 512);
+ if ((pgoff+1)*PAGE_SIZE-1 > dev_info->end - dev_info->start)
+ return -ERANGE;
+ *data = (unsigned long) (dev_info->start+pgoff*PAGE_SIZE);
return 0;
}
@@ -682,7 +718,7 @@ dcssblk_check_params(void)
buf[j-i] = dcssblk_segments[j];
}
buf[j-i] = '\0';
- rc = dcssblk_add_store(dcssblk_root_dev, buf, j-i);
+ rc = dcssblk_add_store(dcssblk_root_dev, NULL, buf, j-i);
if ((rc >= 0) && (dcssblk_segments[j] == '(')) {
for (k = 0; buf[k] != '\0'; k++)
buf[k] = toupper(buf[k]);
@@ -692,7 +728,7 @@ dcssblk_check_params(void)
up_read(&dcssblk_devices_sem);
if (dev_info)
dcssblk_shared_store(&dev_info->dev,
- "0\n", 2);
+ NULL, "0\n", 2);
}
}
while ((dcssblk_segments[j] != ',') &&
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index 14e8cce9f86..6377a96735d 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
obj-$(CONFIG_ZVM_WATCHDOG) += vmwatchdog.o
obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
+obj-$(CONFIG_VMCP) += vmcp.o
tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o
tape-$(CONFIG_PROC_FS) += tape_proc.o
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 022f17bff73..f11a67fda40 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -860,8 +860,8 @@ con3215_init(void)
/* Set the console mode for VM */
if (MACHINE_IS_VM) {
- cpcmd("TERM CONMODE 3215", NULL, 0);
- cpcmd("TERM AUTOCR OFF", NULL, 0);
+ cpcmd("TERM CONMODE 3215", NULL, 0, NULL);
+ cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
}
/* allocate 3215 request structures */
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index d52fb57a6b1..fc7a213e591 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -591,8 +591,8 @@ con3270_init(void)
/* Set the console mode for VM */
if (MACHINE_IS_VM) {
- cpcmd("TERM CONMODE 3270", 0, 0);
- cpcmd("TERM AUTOCR OFF", 0, 0);
+ cpcmd("TERM CONMODE 3270", NULL, 0, NULL);
+ cpcmd("TERM AUTOCR OFF", NULL, 0, NULL);
}
cdev = ccw_device_probe_console();
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 480ec87976f..20be88e91fa 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -1351,13 +1351,13 @@ tape_34xx_init (void)
{
int rc;
- TAPE_DBF_AREA = debug_register ( "tape_34xx", 1, 2, 4*sizeof(long));
+ TAPE_DBF_AREA = debug_register ( "tape_34xx", 2, 2, 4*sizeof(long));
debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
#ifdef DBF_LIKE_HELL
debug_set_level(TAPE_DBF_AREA, 6);
#endif
- DBF_EVENT(3, "34xx init: $Revision: 1.21 $\n");
+ DBF_EVENT(3, "34xx init: $Revision: 1.23 $\n");
/* Register driver for 3480/3490 tapes. */
rc = ccw_driver_register(&tape_34xx_driver);
if (rc)
@@ -1378,7 +1378,7 @@ tape_34xx_exit(void)
MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);
MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");
MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape "
- "device driver ($Revision: 1.21 $)");
+ "device driver ($Revision: 1.23 $)");
MODULE_LICENSE("GPL");
module_init(tape_34xx_init);
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index b4df4a515b1..0597aa0e27e 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -1186,7 +1186,7 @@ tape_mtop(struct tape_device *device, int mt_op, int mt_count)
static int
tape_init (void)
{
- TAPE_DBF_AREA = debug_register ( "tape", 1, 2, 4*sizeof(long));
+ TAPE_DBF_AREA = debug_register ( "tape", 2, 2, 4*sizeof(long));
debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);
#ifdef DBF_LIKE_HELL
debug_set_level(TAPE_DBF_AREA, 6);
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
index 801d17cca34..5fec0a10cc3 100644
--- a/drivers/s390/char/tape_proc.c
+++ b/drivers/s390/char/tape_proc.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
#define TAPE_DBF_AREA tape_core_dbf
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
new file mode 100644
index 00000000000..7f11a608a63
--- /dev/null
+++ b/drivers/s390/char/vmcp.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2004,2005 IBM Corporation
+ * Interface implementation for communication with the v/VM control program
+ * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
+ *
+ *
+ * z/VMs CP offers the possibility to issue commands via the diagnose code 8
+ * this driver implements a character device that issues these commands and
+ * returns the answer of CP.
+
+ * The idea of this driver is based on cpint from Neale Ferguson and #CP in CMS
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <asm/cpcmd.h>
+#include <asm/debug.h>
+#include <asm/uaccess.h>
+#include "vmcp.h"
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Christian Borntraeger <cborntra@de.ibm.com>");
+MODULE_DESCRIPTION("z/VM CP interface");
+
+static debug_info_t *vmcp_debug;
+
+static int vmcp_open(struct inode *inode, struct file *file)
+{
+ struct vmcp_session *session;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ session = kmalloc(sizeof(*session), GFP_KERNEL);
+ if (!session)
+ return -ENOMEM;
+ session->bufsize = PAGE_SIZE;
+ session->response = NULL;
+ session->resp_size = 0;
+ init_MUTEX(&session->mutex);
+ file->private_data = session;
+ return nonseekable_open(inode, file);
+}
+
+static int vmcp_release(struct inode *inode, struct file *file)
+{
+ struct vmcp_session *session;
+
+ session = (struct vmcp_session *)file->private_data;
+ file->private_data = NULL;
+ free_pages((unsigned long)session->response, get_order(session->bufsize));
+ kfree(session);
+ return 0;
+}
+
+static ssize_t
+vmcp_read(struct file *file, char __user * buff, size_t count, loff_t * ppos)
+{
+ size_t tocopy;
+ struct vmcp_session *session;
+
+ session = (struct vmcp_session *)file->private_data;
+ if (down_interruptible(&session->mutex))
+ return -ERESTARTSYS;
+ if (!session->response) {
+ up(&session->mutex);
+ return 0;
+ }
+ if (*ppos > session->resp_size) {
+ up(&session->mutex);
+ return 0;
+ }
+ tocopy = min(session->resp_size - (size_t) (*ppos), count);
+ tocopy = min(tocopy,session->bufsize - (size_t) (*ppos));
+
+ if (copy_to_user(buff, session->response + (*ppos), tocopy)) {
+ up(&session->mutex);
+ return -EFAULT;
+ }
+ up(&session->mutex);
+ *ppos += tocopy;
+ return tocopy;
+}
+
+static ssize_t
+vmcp_write(struct file *file, const char __user * buff, size_t count,
+ loff_t * ppos)
+{
+ char *cmd;
+ struct vmcp_session *session;
+
+ if (count > 240)
+ return -EINVAL;
+ cmd = kmalloc(count + 1, GFP_KERNEL);
+ if (!cmd)
+ return -ENOMEM;
+ if (copy_from_user(cmd, buff, count)) {
+ kfree(cmd);
+ return -EFAULT;
+ }
+ cmd[count] = '\0';
+ session = (struct vmcp_session *)file->private_data;
+ if (down_interruptible(&session->mutex))
+ return -ERESTARTSYS;
+ if (!session->response)
+ session->response = (char *)__get_free_pages(GFP_KERNEL
+ | __GFP_REPEAT | GFP_DMA,
+ get_order(session->bufsize));
+ if (!session->response) {
+ up(&session->mutex);
+ kfree(cmd);
+ return -ENOMEM;
+ }
+ debug_text_event(vmcp_debug, 1, cmd);
+ session->resp_size = cpcmd(cmd, session->response,
+ session->bufsize,
+ &session->resp_code);
+ up(&session->mutex);
+ kfree(cmd);
+ *ppos = 0; /* reset the file pointer after a command */
+ return count;
+}
+
+
+/*
+ * These ioctls are available, as the semantics of the diagnose 8 call
+ * does not fit very well into a Linux call. Diagnose X'08' is described in
+ * CP Programming Services SC24-6084-00
+ *
+ * VMCP_GETCODE: gives the CP return code back to user space
+ * VMCP_SETBUF: sets the response buffer for the next write call. diagnose 8
+ * expects adjacent pages in real storage and to make matters worse, we
+ * dont know the size of the response. Therefore we default to PAGESIZE and
+ * let userspace to change the response size, if userspace expects a bigger
+ * response
+ */
+static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct vmcp_session *session;
+ int temp;
+
+ session = (struct vmcp_session *)file->private_data;
+ if (down_interruptible(&session->mutex))
+ return -ERESTARTSYS;
+ switch (cmd) {
+ case VMCP_GETCODE:
+ temp = session->resp_code;
+ up(&session->mutex);
+ return put_user(temp, (int __user *)arg);
+ case VMCP_SETBUF:
+ free_pages((unsigned long)session->response,
+ get_order(session->bufsize));
+ session->response=NULL;
+ temp = get_user(session->bufsize, (int __user *)arg);
+ if (get_order(session->bufsize) > 8) {
+ session->bufsize = PAGE_SIZE;
+ temp = -EINVAL;
+ }
+ up(&session->mutex);
+ return temp;
+ case VMCP_GETSIZE:
+ temp = session->resp_size;
+ up(&session->mutex);
+ return put_user(temp, (int __user *)arg);
+ default:
+ up(&session->mutex);
+ return -ENOIOCTLCMD;
+ }
+}
+
+static struct file_operations vmcp_fops = {
+ .owner = THIS_MODULE,
+ .open = &vmcp_open,
+ .release = &vmcp_release,
+ .read = &vmcp_read,
+ .llseek = &no_llseek,
+ .write = &vmcp_write,
+ .unlocked_ioctl = &vmcp_ioctl,
+ .compat_ioctl = &vmcp_ioctl
+};
+
+static struct miscdevice vmcp_dev = {
+ .name = "vmcp",
+ .minor = MISC_DYNAMIC_MINOR,
+ .fops = &vmcp_fops,
+};
+
+static int __init vmcp_init(void)
+{
+ int ret;
+
+ if (!MACHINE_IS_VM) {
+ printk(KERN_WARNING
+ "z/VM CP interface is only available under z/VM\n");
+ return -ENODEV;
+ }
+ ret = misc_register(&vmcp_dev);
+ if (!ret)
+ printk(KERN_INFO "z/VM CP interface loaded\n");
+ else
+ printk(KERN_WARNING
+ "z/VM CP interface not loaded. Could not register misc device.\n");
+ vmcp_debug = debug_register("vmcp", 1, 1, 240);
+ debug_register_view(vmcp_debug, &debug_hex_ascii_view);
+ return ret;
+}
+
+static void __exit vmcp_exit(void)
+{
+ WARN_ON(misc_deregister(&vmcp_dev) != 0);
+ debug_unregister(vmcp_debug);
+ printk(KERN_INFO "z/VM CP interface unloaded.\n");
+}
+
+module_init(vmcp_init);
+module_exit(vmcp_exit);
diff --git a/drivers/s390/char/vmcp.h b/drivers/s390/char/vmcp.h
new file mode 100644
index 00000000000..87389e73046
--- /dev/null
+++ b/drivers/s390/char/vmcp.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2004, 2005 IBM Corporation
+ * Interface implementation for communication with the v/VM control program
+ * Version 1.0
+ * Author(s): Christian Borntraeger <cborntra@de.ibm.com>
+ *
+ *
+ * z/VMs CP offers the possibility to issue commands via the diagnose code 8
+ * this driver implements a character device that issues these commands and
+ * returns the answer of CP.
+ *
+ * The idea of this driver is based on cpint from Neale Ferguson
+ */
+
+#include <asm/semaphore.h>
+#include <linux/ioctl.h>
+
+#define VMCP_GETCODE _IOR(0x10, 1, int)
+#define VMCP_SETBUF _IOW(0x10, 2, int)
+#define VMCP_GETSIZE _IOR(0x10, 3, int)
+
+struct vmcp_session {
+ unsigned int bufsize;
+ char *response;
+ int resp_size;
+ int resp_code;
+ /* As we use copy_from/to_user, which might *
+ * sleep and cannot use a spinlock */
+ struct semaphore mutex;
+};
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index f7717327d15..491f00c032e 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -236,7 +236,7 @@ vmlogrdr_get_recording_class_AB(void) {
int len,i;
printk (KERN_DEBUG "vmlogrdr: query command: %s\n", cp_command);
- cpcmd(cp_command, cp_response, sizeof(cp_response));
+ cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
printk (KERN_DEBUG "vmlogrdr: response: %s", cp_response);
len = strnlen(cp_response,sizeof(cp_response));
// now the parsing
@@ -288,7 +288,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) {
printk (KERN_DEBUG "vmlogrdr: recording command: %s\n",
cp_command);
- cpcmd(cp_command, cp_response, sizeof(cp_response));
+ cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
printk (KERN_DEBUG "vmlogrdr: recording response: %s",
cp_response);
}
@@ -301,7 +301,7 @@ vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, int action, int purge) {
qid_string);
printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
- cpcmd(cp_command, cp_response, sizeof(cp_response));
+ cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
printk (KERN_DEBUG "vmlogrdr: recording response: %s",
cp_response);
/* The recording command will usually answer with 'Command complete'
@@ -607,7 +607,7 @@ vmlogrdr_purge_store(struct device * dev, struct device_attribute *attr, const c
priv->recording_name);
printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command);
- cpcmd(cp_command, cp_response, sizeof(cp_response));
+ cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
printk (KERN_DEBUG "vmlogrdr: recording response: %s",
cp_response);
@@ -682,7 +682,7 @@ vmlogrdr_recording_status_show(struct device_driver *driver, char *buf) {
char cp_command[] = "QUERY RECORDING ";
int len;
- cpcmd(cp_command, buf, 4096);
+ cpcmd(cp_command, buf, 4096, NULL);
len = strlen(buf);
return len;
}
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 306525acb9f..91ea8e4777f 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -403,34 +403,22 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver)
return driver_register(&cdriver->driver);
}
-static inline struct device *
-__get_next_ccwgroup_device(struct device_driver *drv)
+static int
+__ccwgroup_driver_unregister_device(struct device *dev, void *data)
{
- struct device *dev, *d;
-
- down_read(&drv->bus->subsys.rwsem);
- dev = NULL;
- list_for_each_entry(d, &drv->devices, driver_list) {
- dev = get_device(d);
- if (dev)
- break;
- }
- up_read(&drv->bus->subsys.rwsem);
- return dev;
+ __ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
+ device_unregister(dev);
+ put_device(dev);
+ return 0;
}
void
ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver)
{
- struct device *dev;
-
/* We don't want ccwgroup devices to live longer than their driver. */
get_driver(&cdriver->driver);
- while ((dev = __get_next_ccwgroup_device(&cdriver->driver))) {
- __ccwgroup_remove_symlinks(to_ccwgroupdev(dev));
- device_unregister(dev);
- put_device(dev);
- };
+ driver_for_each_device(&cdriver->driver, NULL, NULL,
+ __ccwgroup_driver_unregister_device);
put_driver(&cdriver->driver);
driver_unregister(&cdriver->driver);
}
@@ -449,7 +437,7 @@ __ccwgroup_get_gdev_by_cdev(struct ccw_device *cdev)
if (cdev->dev.driver_data) {
gdev = (struct ccwgroup_device *)cdev->dev.driver_data;
if (get_device(&gdev->dev)) {
- if (!list_empty(&gdev->dev.node))
+ if (klist_node_attached(&gdev->dev.knode_bus))
return gdev;
put_device(&gdev->dev);
}
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 1d9b3f18d8d..ea813bdce1d 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -1,7 +1,7 @@
/*
* drivers/s390/cio/cio.c
* S/390 common I/O routines -- low level i/o calls
- * $Revision: 1.133 $
+ * $Revision: 1.134 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
@@ -63,17 +63,17 @@ __setup ("cio_msg=", cio_setup);
static int __init
cio_debug_init (void)
{
- cio_debug_msg_id = debug_register ("cio_msg", 4, 4, 16*sizeof (long));
+ cio_debug_msg_id = debug_register ("cio_msg", 16, 4, 16*sizeof (long));
if (!cio_debug_msg_id)
goto out_unregister;
debug_register_view (cio_debug_msg_id, &debug_sprintf_view);
debug_set_level (cio_debug_msg_id, 2);
- cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8);
+ cio_debug_trace_id = debug_register ("cio_trace", 16, 4, 8);
if (!cio_debug_trace_id)
goto out_unregister;
debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view);
debug_set_level (cio_debug_trace_id, 2);
- cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16*sizeof (long));
+ cio_debug_crw_id = debug_register ("cio_crw", 4, 4, 16*sizeof (long));
if (!cio_debug_crw_id)
goto out_unregister;
debug_register_view (cio_debug_crw_id, &debug_sprintf_view);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 87bd70eeabe..555119cacc2 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -128,34 +128,28 @@ css_probe_device(int irq)
return ret;
}
+static int
+check_subchannel(struct device * dev, void * data)
+{
+ struct subchannel *sch;
+ int irq = (unsigned long)data;
+
+ sch = to_subchannel(dev);
+ return (sch->irq == irq);
+}
+
struct subchannel *
get_subchannel_by_schid(int irq)
{
- struct subchannel *sch;
- struct list_head *entry;
struct device *dev;
- if (!get_bus(&css_bus_type))
- return NULL;
- down_read(&css_bus_type.subsys.rwsem);
- sch = NULL;
- list_for_each(entry, &css_bus_type.devices.list) {
- dev = get_device(container_of(entry,
- struct device, bus_list));
- if (!dev)
- continue;
- sch = to_subchannel(dev);
- if (sch->irq == irq)
- break;
- put_device(dev);
- sch = NULL;
- }
- up_read(&css_bus_type.subsys.rwsem);
- put_bus(&css_bus_type);
+ dev = bus_find_device(&css_bus_type, NULL,
+ (void *)(unsigned long)irq, check_subchannel);
- return sch;
+ return dev ? to_subchannel(dev) : NULL;
}
+
static inline int
css_get_subchannel_status(struct subchannel *sch, int schid)
{
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 809e1108a06..14c76f5e417 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -514,36 +514,39 @@ ccw_device_register(struct ccw_device *cdev)
return ret;
}
+struct match_data {
+ unsigned int devno;
+ struct ccw_device * sibling;
+};
+
+static int
+match_devno(struct device * dev, void * data)
+{
+ struct match_data * d = (struct match_data *)data;
+ struct ccw_device * cdev;
+
+ cdev = to_ccwdev(dev);
+ if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
+ (cdev->private->devno == d->devno) &&
+ (cdev != d->sibling)) {
+ cdev->private->state = DEV_STATE_NOT_OPER;
+ return 1;
+ }
+ return 0;
+}
+
static struct ccw_device *
get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
{
- struct ccw_device *cdev;
- struct list_head *entry;
struct device *dev;
+ struct match_data data = {
+ .devno = devno,
+ .sibling = sibling,
+ };
- if (!get_bus(&ccw_bus_type))
- return NULL;
- down_read(&ccw_bus_type.subsys.rwsem);
- cdev = NULL;
- list_for_each(entry, &ccw_bus_type.devices.list) {
- dev = get_device(container_of(entry,
- struct device, bus_list));
- if (!dev)
- continue;
- cdev = to_ccwdev(dev);
- if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
- (cdev->private->devno == devno) &&
- (cdev != sibling)) {
- cdev->private->state = DEV_STATE_NOT_OPER;
- break;
- }
- put_device(dev);
- cdev = NULL;
- }
- up_read(&ccw_bus_type.subsys.rwsem);
- put_bus(&ccw_bus_type);
+ dev = bus_find_device(&css_bus_type, NULL, &data, match_devno);
- return cdev;
+ return dev ? to_ccwdev(dev) : NULL;
}
static void
@@ -647,7 +650,7 @@ io_subchannel_register(void *data)
cdev = (struct ccw_device *) data;
sch = to_subchannel(cdev->dev.parent);
- if (!list_empty(&sch->dev.children)) {
+ if (klist_node_attached(&cdev->dev.knode_parent)) {
bus_rescan_devices(&ccw_bus_type);
goto out;
}
@@ -1019,30 +1022,29 @@ ccw_device_probe_console(void)
/*
* get ccw_device matching the busid, but only if owned by cdrv
*/
+static int
+__ccwdev_check_busid(struct device *dev, void *id)
+{
+ char *bus_id;
+
+ bus_id = (char *)id;
+
+ return (strncmp(bus_id, dev->bus_id, BUS_ID_SIZE) == 0);
+}
+
+
struct ccw_device *
get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id)
{
- struct device *d, *dev;
+ struct device *dev;
struct device_driver *drv;
drv = get_driver(&cdrv->driver);
if (!drv)
- return 0;
-
- down_read(&drv->bus->subsys.rwsem);
-
- dev = NULL;
- list_for_each_entry(d, &drv->devices, driver_list) {
- dev = get_device(d);
+ return NULL;
- if (dev && !strncmp(bus_id, dev->bus_id, BUS_ID_SIZE))
- break;
- else if (dev) {
- put_device(dev);
- dev = NULL;
- }
- }
- up_read(&drv->bus->subsys.rwsem);
+ dev = driver_find_device(drv, NULL, (void *)bus_id,
+ __ccwdev_check_busid);
put_driver(drv);
return dev ? to_ccwdev(dev) : 0;
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index bbe9f45d143..82194c4eadf 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -56,7 +56,7 @@
#include "ioasm.h"
#include "chsc.h"
-#define VERSION_QDIO_C "$Revision: 1.98 $"
+#define VERSION_QDIO_C "$Revision: 1.101 $"
/****************** MODULE PARAMETER VARIABLES ********************/
MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -3342,7 +3342,7 @@ static int
qdio_register_dbf_views(void)
{
qdio_dbf_setup=debug_register(QDIO_DBF_SETUP_NAME,
- QDIO_DBF_SETUP_INDEX,
+ QDIO_DBF_SETUP_PAGES,
QDIO_DBF_SETUP_NR_AREAS,
QDIO_DBF_SETUP_LEN);
if (!qdio_dbf_setup)
@@ -3351,7 +3351,7 @@ qdio_register_dbf_views(void)
debug_set_level(qdio_dbf_setup,QDIO_DBF_SETUP_LEVEL);
qdio_dbf_sbal=debug_register(QDIO_DBF_SBAL_NAME,
- QDIO_DBF_SBAL_INDEX,
+ QDIO_DBF_SBAL_PAGES,
QDIO_DBF_SBAL_NR_AREAS,
QDIO_DBF_SBAL_LEN);
if (!qdio_dbf_sbal)
@@ -3361,7 +3361,7 @@ qdio_register_dbf_views(void)
debug_set_level(qdio_dbf_sbal,QDIO_DBF_SBAL_LEVEL);
qdio_dbf_sense=debug_register(QDIO_DBF_SENSE_NAME,
- QDIO_DBF_SENSE_INDEX,
+ QDIO_DBF_SENSE_PAGES,
QDIO_DBF_SENSE_NR_AREAS,
QDIO_DBF_SENSE_LEN);
if (!qdio_dbf_sense)
@@ -3371,7 +3371,7 @@ qdio_register_dbf_views(void)
debug_set_level(qdio_dbf_sense,QDIO_DBF_SENSE_LEVEL);
qdio_dbf_trace=debug_register(QDIO_DBF_TRACE_NAME,
- QDIO_DBF_TRACE_INDEX,
+ QDIO_DBF_TRACE_PAGES,
QDIO_DBF_TRACE_NR_AREAS,
QDIO_DBF_TRACE_LEN);
if (!qdio_dbf_trace)
@@ -3382,7 +3382,7 @@ qdio_register_dbf_views(void)
#ifdef CONFIG_QDIO_DEBUG
qdio_dbf_slsb_out=debug_register(QDIO_DBF_SLSB_OUT_NAME,
- QDIO_DBF_SLSB_OUT_INDEX,
+ QDIO_DBF_SLSB_OUT_PAGES,
QDIO_DBF_SLSB_OUT_NR_AREAS,
QDIO_DBF_SLSB_OUT_LEN);
if (!qdio_dbf_slsb_out)
@@ -3391,7 +3391,7 @@ qdio_register_dbf_views(void)
debug_set_level(qdio_dbf_slsb_out,QDIO_DBF_SLSB_OUT_LEVEL);
qdio_dbf_slsb_in=debug_register(QDIO_DBF_SLSB_IN_NAME,
- QDIO_DBF_SLSB_IN_INDEX,
+ QDIO_DBF_SLSB_IN_PAGES,
QDIO_DBF_SLSB_IN_NR_AREAS,
QDIO_DBF_SLSB_IN_LEN);
if (!qdio_dbf_slsb_in)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index b6daadac4e8..6b8aa6a852b 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -3,7 +3,7 @@
#include <asm/page.h>
-#define VERSION_CIO_QDIO_H "$Revision: 1.32 $"
+#define VERSION_CIO_QDIO_H "$Revision: 1.33 $"
#ifdef CONFIG_QDIO_DEBUG
#define QDIO_VERBOSE_LEVEL 9
@@ -132,7 +132,7 @@ enum qdio_irq_states {
#define QDIO_DBF_SETUP_NAME "qdio_setup"
#define QDIO_DBF_SETUP_LEN 8
-#define QDIO_DBF_SETUP_INDEX 2
+#define QDIO_DBF_SETUP_PAGES 4
#define QDIO_DBF_SETUP_NR_AREAS 1
#ifdef CONFIG_QDIO_DEBUG
#define QDIO_DBF_SETUP_LEVEL 6
@@ -142,7 +142,7 @@ enum qdio_irq_states {
#define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */
#define QDIO_DBF_SBAL_LEN 256
-#define QDIO_DBF_SBAL_INDEX 2
+#define QDIO_DBF_SBAL_PAGES 4
#define QDIO_DBF_SBAL_NR_AREAS 2
#ifdef CONFIG_QDIO_DEBUG
#define QDIO_DBF_SBAL_LEVEL 6
@@ -154,16 +154,16 @@ enum qdio_irq_states {
#define QDIO_DBF_TRACE_LEN 8
#define QDIO_DBF_TRACE_NR_AREAS 2
#ifdef CONFIG_QDIO_DEBUG
-#define QDIO_DBF_TRACE_INDEX 4
+#define QDIO_DBF_TRACE_PAGES 16
#define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */
#else /* CONFIG_QDIO_DEBUG */
-#define QDIO_DBF_TRACE_INDEX 2
+#define QDIO_DBF_TRACE_PAGES 4
#define QDIO_DBF_TRACE_LEVEL 2
#endif /* CONFIG_QDIO_DEBUG */
#define QDIO_DBF_SENSE_NAME "qdio_sense"
#define QDIO_DBF_SENSE_LEN 64
-#define QDIO_DBF_SENSE_INDEX 1
+#define QDIO_DBF_SENSE_PAGES 2
#define QDIO_DBF_SENSE_NR_AREAS 1
#ifdef CONFIG_QDIO_DEBUG
#define QDIO_DBF_SENSE_LEVEL 6
@@ -176,13 +176,13 @@ enum qdio_irq_states {
#define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out"
#define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_OUT_INDEX 8
+#define QDIO_DBF_SLSB_OUT_PAGES 256
#define QDIO_DBF_SLSB_OUT_NR_AREAS 1
#define QDIO_DBF_SLSB_OUT_LEVEL 6
#define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in"
#define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q
-#define QDIO_DBF_SLSB_IN_INDEX 8
+#define QDIO_DBF_SLSB_IN_PAGES 256
#define QDIO_DBF_SLSB_IN_NR_AREAS 1
#define QDIO_DBF_SLSB_IN_LEVEL 6
#endif /* CONFIG_QDIO_DEBUG */
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index a99927d54eb..60440dbe3a2 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -146,8 +146,8 @@ claw_unregister_debug_facility(void)
static int
claw_register_debug_facility(void)
{
- claw_dbf_setup = debug_register("claw_setup", 1, 1, 8);
- claw_dbf_trace = debug_register("claw_trace", 1, 2, 8);
+ claw_dbf_setup = debug_register("claw_setup", 2, 1, 8);
+ claw_dbf_trace = debug_register("claw_trace", 2, 2, 8);
if (claw_dbf_setup == NULL || claw_dbf_trace == NULL) {
printk(KERN_WARNING "Not enough memory for debug facility.\n");
claw_unregister_debug_facility();
diff --git a/drivers/s390/net/ctcdbug.c b/drivers/s390/net/ctcdbug.c
index 2c86bfa11b2..0e2a8bb9303 100644
--- a/drivers/s390/net/ctcdbug.c
+++ b/drivers/s390/net/ctcdbug.c
@@ -1,6 +1,6 @@
/*
*
- * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.4 $)
+ * linux/drivers/s390/net/ctcdbug.c ($Revision: 1.6 $)
*
* CTC / ESCON network driver - s390 dbf exploit.
*
@@ -9,7 +9,7 @@
* Author(s): Original Code written by
* Peter Tiedemann (ptiedem@de.ibm.com)
*
- * $Revision: 1.4 $ $Date: 2004/08/04 10:11:59 $
+ * $Revision: 1.6 $ $Date: 2005/05/11 08:10:17 $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -51,15 +51,15 @@ int
ctc_register_dbf_views(void)
{
ctc_dbf_setup = debug_register(CTC_DBF_SETUP_NAME,
- CTC_DBF_SETUP_INDEX,
+ CTC_DBF_SETUP_PAGES,
CTC_DBF_SETUP_NR_AREAS,
CTC_DBF_SETUP_LEN);
ctc_dbf_data = debug_register(CTC_DBF_DATA_NAME,
- CTC_DBF_DATA_INDEX,
+ CTC_DBF_DATA_PAGES,
CTC_DBF_DATA_NR_AREAS,
CTC_DBF_DATA_LEN);
ctc_dbf_trace = debug_register(CTC_DBF_TRACE_NAME,
- CTC_DBF_TRACE_INDEX,
+ CTC_DBF_TRACE_PAGES,
CTC_DBF_TRACE_NR_AREAS,
CTC_DBF_TRACE_LEN);
diff --git a/drivers/s390/net/ctcdbug.h b/drivers/s390/net/ctcdbug.h
index 7fe2ebd1792..7d6afa1627c 100644
--- a/drivers/s390/net/ctcdbug.h
+++ b/drivers/s390/net/ctcdbug.h
@@ -1,6 +1,6 @@
/*
*
- * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $)
+ * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.6 $)
*
* CTC / ESCON network driver - s390 dbf exploit.
*
@@ -9,7 +9,7 @@
* Author(s): Original Code written by
* Peter Tiedemann (ptiedem@de.ibm.com)
*
- * $Revision: 1.5 $ $Date: 2005/02/27 19:46:44 $
+ * $Revision: 1.6 $ $Date: 2005/05/11 08:10:17 $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,19 +35,19 @@
*/
#define CTC_DBF_SETUP_NAME "ctc_setup"
#define CTC_DBF_SETUP_LEN 16
-#define CTC_DBF_SETUP_INDEX 3
+#define CTC_DBF_SETUP_PAGES 8
#define CTC_DBF_SETUP_NR_AREAS 1
#define CTC_DBF_SETUP_LEVEL 3
#define CTC_DBF_DATA_NAME "ctc_data"
#define CTC_DBF_DATA_LEN 128
-#define CTC_DBF_DATA_INDEX 3
+#define CTC_DBF_DATA_PAGES 8
#define CTC_DBF_DATA_NR_AREAS 1
#define CTC_DBF_DATA_LEVEL 3
#define CTC_DBF_TRACE_NAME "ctc_trace"
#define CTC_DBF_TRACE_LEN 16
-#define CTC_DBF_TRACE_INDEX 2
+#define CTC_DBF_TRACE_PAGES 4
#define CTC_DBF_TRACE_NR_AREAS 2
#define CTC_DBF_TRACE_LEVEL 3
diff --git a/drivers/s390/net/iucv.h b/drivers/s390/net/iucv.h
index 198330217ef..0c4644d3d2f 100644
--- a/drivers/s390/net/iucv.h
+++ b/drivers/s390/net/iucv.h
@@ -37,19 +37,19 @@
*/
#define IUCV_DBF_SETUP_NAME "iucv_setup"
#define IUCV_DBF_SETUP_LEN 32
-#define IUCV_DBF_SETUP_INDEX 1
+#define IUCV_DBF_SETUP_PAGES 2
#define IUCV_DBF_SETUP_NR_AREAS 1
#define IUCV_DBF_SETUP_LEVEL 3
#define IUCV_DBF_DATA_NAME "iucv_data"
#define IUCV_DBF_DATA_LEN 128
-#define IUCV_DBF_DATA_INDEX 1
+#define IUCV_DBF_DATA_PAGES 2
#define IUCV_DBF_DATA_NR_AREAS 1
#define IUCV_DBF_DATA_LEVEL 2
#define IUCV_DBF_TRACE_NAME "iucv_trace"
#define IUCV_DBF_TRACE_LEN 16
-#define IUCV_DBF_TRACE_INDEX 2
+#define IUCV_DBF_TRACE_PAGES 4
#define IUCV_DBF_TRACE_NR_AREAS 1
#define IUCV_DBF_TRACE_LEVEL 3
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index ab086242d30..46f34ba93ac 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -11,7 +11,7 @@
* Frank Pavlic (pavlic@de.ibm.com) and
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*
- * $Revision: 1.98 $ $Date: 2005/04/18 13:41:29 $
+ * $Revision: 1.99 $ $Date: 2005/05/11 08:10:17 $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@
/**
* initialization string for output
*/
-#define VERSION_LCS_C "$Revision: 1.98 $"
+#define VERSION_LCS_C "$Revision: 1.99 $"
static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")";
static char debug_buffer[255];
@@ -93,8 +93,8 @@ lcs_unregister_debug_facility(void)
static int
lcs_register_debug_facility(void)
{
- lcs_dbf_setup = debug_register("lcs_setup", 1, 1, 8);
- lcs_dbf_trace = debug_register("lcs_trace", 1, 2, 8);
+ lcs_dbf_setup = debug_register("lcs_setup", 2, 1, 8);
+ lcs_dbf_trace = debug_register("lcs_trace", 2, 2, 8);
if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) {
PRINT_ERR("Not enough memory for debug facility.\n");
lcs_unregister_debug_facility();
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 3fd4fb754b2..69425a7a6e9 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1,5 +1,5 @@
/*
- * $Id: netiucv.c,v 1.63 2004/07/27 13:36:05 mschwide Exp $
+ * $Id: netiucv.c,v 1.66 2005/05/11 08:10:17 holzheu Exp $
*
* IUCV network driver
*
@@ -30,7 +30,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * RELEASE-TAG: IUCV network driver $Revision: 1.63 $
+ * RELEASE-TAG: IUCV network driver $Revision: 1.66 $
*
*/
@@ -391,15 +391,15 @@ static int
iucv_register_dbf_views(void)
{
iucv_dbf_setup = debug_register(IUCV_DBF_SETUP_NAME,
- IUCV_DBF_SETUP_INDEX,
+ IUCV_DBF_SETUP_PAGES,
IUCV_DBF_SETUP_NR_AREAS,
IUCV_DBF_SETUP_LEN);
iucv_dbf_data = debug_register(IUCV_DBF_DATA_NAME,
- IUCV_DBF_DATA_INDEX,
+ IUCV_DBF_DATA_PAGES,
IUCV_DBF_DATA_NR_AREAS,
IUCV_DBF_DATA_LEN);
iucv_dbf_trace = debug_register(IUCV_DBF_TRACE_NAME,
- IUCV_DBF_TRACE_INDEX,
+ IUCV_DBF_TRACE_PAGES,
IUCV_DBF_TRACE_NR_AREAS,
IUCV_DBF_TRACE_LEN);
@@ -2076,7 +2076,7 @@ DRIVER_ATTR(remove, 0200, NULL, remove_write);
static void
netiucv_banner(void)
{
- char vbuf[] = "$Revision: 1.63 $";
+ char vbuf[] = "$Revision: 1.66 $";
char *version = vbuf;
if ((version = strchr(version, ':'))) {
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index a755b57db46..008e0a5d2eb 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -42,44 +42,44 @@
*/
#define QETH_DBF_SETUP_NAME "qeth_setup"
#define QETH_DBF_SETUP_LEN 8
-#define QETH_DBF_SETUP_INDEX 3
+#define QETH_DBF_SETUP_PAGES 8
#define QETH_DBF_SETUP_NR_AREAS 1
#define QETH_DBF_SETUP_LEVEL 5
#define QETH_DBF_MISC_NAME "qeth_misc"
#define QETH_DBF_MISC_LEN 128
-#define QETH_DBF_MISC_INDEX 1
+#define QETH_DBF_MISC_PAGES 2
#define QETH_DBF_MISC_NR_AREAS 1
#define QETH_DBF_MISC_LEVEL 2
#define QETH_DBF_DATA_NAME "qeth_data"
#define QETH_DBF_DATA_LEN 96
-#define QETH_DBF_DATA_INDEX 3
+#define QETH_DBF_DATA_PAGES 8
#define QETH_DBF_DATA_NR_AREAS 1
#define QETH_DBF_DATA_LEVEL 2
#define QETH_DBF_CONTROL_NAME "qeth_control"
#define QETH_DBF_CONTROL_LEN 256
-#define QETH_DBF_CONTROL_INDEX 3
+#define QETH_DBF_CONTROL_PAGES 8
#define QETH_DBF_CONTROL_NR_AREAS 2
#define QETH_DBF_CONTROL_LEVEL 5
#define QETH_DBF_TRACE_NAME "qeth_trace"
#define QETH_DBF_TRACE_LEN 8
-#define QETH_DBF_TRACE_INDEX 2
+#define QETH_DBF_TRACE_PAGES 4
#define QETH_DBF_TRACE_NR_AREAS 2
#define QETH_DBF_TRACE_LEVEL 3
extern debug_info_t *qeth_dbf_trace;
#define QETH_DBF_SENSE_NAME "qeth_sense"
#define QETH_DBF_SENSE_LEN 64
-#define QETH_DBF_SENSE_INDEX 1
+#define QETH_DBF_SENSE_PAGES 2
#define QETH_DBF_SENSE_NR_AREAS 1
#define QETH_DBF_SENSE_LEVEL 2
#define QETH_DBF_QERR_NAME "qeth_qerr"
#define QETH_DBF_QERR_LEN 8
-#define QETH_DBF_QERR_INDEX 1
+#define QETH_DBF_QERR_PAGES 2
#define QETH_DBF_QERR_NR_AREAS 2
#define QETH_DBF_QERR_LEVEL 2
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 208127a5033..3cb88c77003 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -7639,31 +7639,31 @@ static int
qeth_register_dbf_views(void)
{
qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME,
- QETH_DBF_SETUP_INDEX,
+ QETH_DBF_SETUP_PAGES,
QETH_DBF_SETUP_NR_AREAS,
QETH_DBF_SETUP_LEN);
qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME,
- QETH_DBF_MISC_INDEX,
+ QETH_DBF_MISC_PAGES,
QETH_DBF_MISC_NR_AREAS,
QETH_DBF_MISC_LEN);
qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME,
- QETH_DBF_DATA_INDEX,
+ QETH_DBF_DATA_PAGES,
QETH_DBF_DATA_NR_AREAS,
QETH_DBF_DATA_LEN);
qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME,
- QETH_DBF_CONTROL_INDEX,
+ QETH_DBF_CONTROL_PAGES,
QETH_DBF_CONTROL_NR_AREAS,
QETH_DBF_CONTROL_LEN);
qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME,
- QETH_DBF_SENSE_INDEX,
+ QETH_DBF_SENSE_PAGES,
QETH_DBF_SENSE_NR_AREAS,
QETH_DBF_SENSE_LEN);
qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME,
- QETH_DBF_QERR_INDEX,
+ QETH_DBF_QERR_PAGES,
QETH_DBF_QERR_NR_AREAS,
QETH_DBF_QERR_LEN);
qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME,
- QETH_DBF_TRACE_INDEX,
+ QETH_DBF_TRACE_PAGES,
QETH_DBF_TRACE_NR_AREAS,
QETH_DBF_TRACE_LEN);
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 1e3f7f3c662..d6469baa7e1 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -138,7 +138,7 @@ static void __exit
smsg_exit(void)
{
if (smsg_handle > 0) {
- cpcmd("SET SMSG OFF", 0, 0);
+ cpcmd("SET SMSG OFF", NULL, 0, NULL);
iucv_sever(smsg_pathid, 0);
iucv_unregister_program(smsg_handle);
driver_unregister(&smsg_driver);
@@ -177,7 +177,7 @@ smsg_init(void)
smsg_handle = 0;
return -EIO;
}
- cpcmd("SET SMSG IUCV", 0, 0);
+ cpcmd("SET SMSG IUCV", NULL, 0, NULL);
return 0;
}
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index ffa996c8a90..5bb255e02ac 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -31,14 +31,14 @@ extern void css_reiterate_subchannels(void);
extern struct workqueue_struct *slow_path_wq;
extern struct work_struct slow_path_work;
-static void
+static NORET_TYPE void
s390_handle_damage(char *msg)
{
- printk(KERN_EMERG "%s\n", msg);
#ifdef CONFIG_SMP
smp_send_stop();
#endif
disabled_wait((unsigned long) __builtin_return_address(0));
+ for(;;);
}
/*
@@ -122,40 +122,39 @@ repeat:
return 0;
}
+struct mcck_struct {
+ int kill_task;
+ int channel_report;
+ int warning;
+ unsigned long long mcck_code;
+};
+
+static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
+
/*
- * machine check handler.
+ * Main machine check handler function. Will be called with interrupts enabled
+ * or disabled and machine checks enabled or disabled.
*/
void
-s390_do_machine_check(void)
+s390_handle_mcck(void)
{
- struct mci *mci;
-
- mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
+ unsigned long flags;
+ struct mcck_struct mcck;
- if (mci->sd) /* system damage */
- s390_handle_damage("received system damage machine check\n");
+ /*
+ * Disable machine checks and get the current state of accumulated
+ * machine checks. Afterwards delete the old state and enable machine
+ * checks again.
+ */
+ local_irq_save(flags);
+ local_mcck_disable();
+ mcck = __get_cpu_var(cpu_mcck);
+ memset(&__get_cpu_var(cpu_mcck), 0, sizeof(struct mcck_struct));
+ clear_thread_flag(TIF_MCCK_PENDING);
+ local_mcck_enable();
+ local_irq_restore(flags);
- if (mci->pd) /* instruction processing damage */
- s390_handle_damage("received instruction processing "
- "damage machine check\n");
-
- if (mci->se) /* storage error uncorrected */
- s390_handle_damage("received storage error uncorrected "
- "machine check\n");
-
- if (mci->sc) /* storage error corrected */
- printk(KERN_WARNING
- "received storage error corrected machine check\n");
-
- if (mci->ke) /* storage key-error uncorrected */
- s390_handle_damage("received storage key-error uncorrected "
- "machine check\n");
-
- if (mci->ds && mci->fa) /* storage degradation */
- s390_handle_damage("received storage degradation machine "
- "check\n");
-
- if (mci->cp) /* channel report word pending */
+ if (mcck.channel_report)
up(&m_sem);
#ifdef CONFIG_MACHCHK_WARNING
@@ -168,7 +167,7 @@ s390_do_machine_check(void)
* On VM we only get one interrupt per virtally presented machinecheck.
* Though one suffices, we may get one interrupt per (virtual) processor.
*/
- if (mci->w) { /* WARNING pending ? */
+ if (mcck.warning) { /* WARNING pending ? */
static int mchchk_wng_posted = 0;
/*
* Use single machine clear, as we cannot handle smp right now
@@ -178,6 +177,261 @@ s390_do_machine_check(void)
kill_proc(1, SIGPWR, 1);
}
#endif
+
+ if (mcck.kill_task) {
+ local_irq_enable();
+ printk(KERN_EMERG "mcck: Terminating task because of machine "
+ "malfunction (code 0x%016llx).\n", mcck.mcck_code);
+ printk(KERN_EMERG "mcck: task: %s, pid: %d.\n",
+ current->comm, current->pid);
+ do_exit(SIGSEGV);
+ }
+}
+
+/*
+ * returns 0 if all registers could be validated
+ * returns 1 otherwise
+ */
+static int
+s390_revalidate_registers(struct mci *mci)
+{
+ int kill_task;
+ u64 tmpclock;
+ u64 zero;
+ void *fpt_save_area, *fpt_creg_save_area;
+
+ kill_task = 0;
+ zero = 0;
+ /* General purpose registers */
+ if (!mci->gr)
+ /*
+ * General purpose registers couldn't be restored and have
+ * unknown contents. Process needs to be terminated.
+ */
+ kill_task = 1;
+
+ /* Revalidate floating point registers */
+ if (!mci->fp)
+ /*
+ * Floating point registers can't be restored and
+ * therefore the process needs to be terminated.
+ */
+ kill_task = 1;
+
+#ifndef __s390x__
+ asm volatile("ld 0,0(%0)\n"
+ "ld 2,8(%0)\n"
+ "ld 4,16(%0)\n"
+ "ld 6,24(%0)"
+ : : "a" (&S390_lowcore.floating_pt_save_area));
+#endif
+
+ if (MACHINE_HAS_IEEE) {
+#ifdef __s390x__
+ fpt_save_area = &S390_lowcore.floating_pt_save_area;
+ fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
+#else
+ fpt_save_area = (void *) S390_lowcore.extended_save_area_addr;
+ fpt_creg_save_area = fpt_save_area+128;
+#endif
+ /* Floating point control register */
+ if (!mci->fc) {
+ /*
+ * Floating point control register can't be restored.
+ * Task will be terminated.
+ */
+ asm volatile ("lfpc 0(%0)" : : "a" (&zero));
+ kill_task = 1;
+
+ }
+ else
+ asm volatile (
+ "lfpc 0(%0)"
+ : : "a" (fpt_creg_save_area));
+
+ asm volatile("ld 0,0(%0)\n"
+ "ld 1,8(%0)\n"
+ "ld 2,16(%0)\n"
+ "ld 3,24(%0)\n"
+ "ld 4,32(%0)\n"
+ "ld 5,40(%0)\n"
+ "ld 6,48(%0)\n"
+ "ld 7,56(%0)\n"
+ "ld 8,64(%0)\n"
+ "ld 9,72(%0)\n"
+ "ld 10,80(%0)\n"
+ "ld 11,88(%0)\n"
+ "ld 12,96(%0)\n"
+ "ld 13,104(%0)\n"
+ "ld 14,112(%0)\n"
+ "ld 15,120(%0)\n"
+ : : "a" (fpt_save_area));
+ }
+
+ /* Revalidate access registers */
+ asm volatile("lam 0,15,0(%0)"
+ : : "a" (&S390_lowcore.access_regs_save_area));
+ if (!mci->ar)
+ /*
+ * Access registers have unknown contents.
+ * Terminating task.
+ */
+ kill_task = 1;
+
+ /* Revalidate control registers */
+ if (!mci->cr)
+ /*
+ * Control registers have unknown contents.
+ * Can't recover and therefore stopping machine.
+ */
+ s390_handle_damage("invalid control registers.");
+ else
+#ifdef __s390x__
+ asm volatile("lctlg 0,15,0(%0)"
+ : : "a" (&S390_lowcore.cregs_save_area));
+#else
+ asm volatile("lctl 0,15,0(%0)"
+ : : "a" (&S390_lowcore.cregs_save_area));
+#endif
+
+ /*
+ * We don't even try to revalidate the TOD register, since we simply
+ * can't write something sensible into that register.
+ */
+
+#ifdef __s390x__
+ /*
+ * See if we can revalidate the TOD programmable register with its
+ * old contents (should be zero) otherwise set it to zero.
+ */
+ if (!mci->pr)
+ asm volatile("sr 0,0\n"
+ "sckpf"
+ : : : "0", "cc");
+ else
+ asm volatile(
+ "l 0,0(%0)\n"
+ "sckpf"
+ : : "a" (&S390_lowcore.tod_progreg_save_area) : "0", "cc");
+#endif
+
+ /* Revalidate clock comparator register */
+ asm volatile ("stck 0(%1)\n"
+ "sckc 0(%1)"
+ : "=m" (tmpclock) : "a" (&(tmpclock)) : "cc", "memory");
+
+ /* Check if old PSW is valid */
+ if (!mci->wp)
+ /*
+ * Can't tell if we come from user or kernel mode
+ * -> stopping machine.
+ */
+ s390_handle_damage("old psw invalid.");
+
+ if (!mci->ms || !mci->pm || !mci->ia)
+ kill_task = 1;
+
+ return kill_task;
+}
+
+/*
+ * machine check handler.
+ */
+void
+s390_do_machine_check(struct pt_regs *regs)
+{
+ struct mci *mci;
+ struct mcck_struct *mcck;
+ int umode;
+
+ mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
+ mcck = &__get_cpu_var(cpu_mcck);
+ umode = user_mode(regs);
+
+ if (mci->sd)
+ /* System damage -> stopping machine */
+ s390_handle_damage("received system damage machine check.");
+
+ if (mci->pd) {
+ if (mci->b) {
+ /* Processing backup -> verify if we can survive this */
+ u64 z_mcic, o_mcic, t_mcic;
+#ifdef __s390x__
+ z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
+ o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+ 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+ 1ULL<<30 | 1ULL<<21 | 1ULL<<20 | 1ULL<<17 |
+ 1ULL<<16);
+#else
+ z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<57 | 1ULL<<50 |
+ 1ULL<<29);
+ o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
+ 1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
+ 1ULL<<30 | 1ULL<<20 | 1ULL<<17 | 1ULL<<16);
+#endif
+ t_mcic = *(u64 *)mci;
+
+ if (((t_mcic & z_mcic) != 0) ||
+ ((t_mcic & o_mcic) != o_mcic)) {
+ s390_handle_damage("processing backup machine "
+ "check with damage.");
+ }
+ if (!umode)
+ s390_handle_damage("processing backup machine "
+ "check in kernel mode.");
+ mcck->kill_task = 1;
+ mcck->mcck_code = *(unsigned long long *) mci;
+ }
+ else {
+ /* Processing damage -> stopping machine */
+ s390_handle_damage("received instruction processing "
+ "damage machine check.");
+ }
+ }
+ if (s390_revalidate_registers(mci)) {
+ if (umode) {
+ /*
+ * Couldn't restore all register contents while in
+ * user mode -> mark task for termination.
+ */
+ mcck->kill_task = 1;
+ mcck->mcck_code = *(unsigned long long *) mci;
+ set_thread_flag(TIF_MCCK_PENDING);
+ }
+ else
+ /*
+ * Couldn't restore all register contents while in
+ * kernel mode -> stopping machine.
+ */
+ s390_handle_damage("unable to revalidate registers.");
+ }
+
+ if (mci->se)
+ /* Storage error uncorrected */
+ s390_handle_damage("received storage error uncorrected "
+ "machine check.");
+
+ if (mci->ke)
+ /* Storage key-error uncorrected */
+ s390_handle_damage("received storage key-error uncorrected "
+ "machine check.");
+
+ if (mci->ds && mci->fa)
+ /* Storage degradation */
+ s390_handle_damage("received storage degradation machine "
+ "check.");
+
+ if (mci->cp) {
+ /* Channel report word pending */
+ mcck->channel_report = 1;
+ set_thread_flag(TIF_MCCK_PENDING);
+ }
+
+ if (mci->w) {
+ /* Warning pending */
+ mcck->warning = 1;
+ set_thread_flag(TIF_MCCK_PENDING);
+ }
}
/*
@@ -189,9 +443,8 @@ static int
machine_check_init(void)
{
init_MUTEX_LOCKED(&m_sem);
- ctl_clear_bit(14, 25); /* disable damage MCH */
- ctl_set_bit(14, 26); /* enable degradation MCH */
- ctl_set_bit(14, 27); /* enable system recovery MCH */
+ ctl_clear_bit(14, 25); /* disable external damage MCH */
+ ctl_set_bit(14, 27); /* enable system recovery MCH */
#ifdef CONFIG_MACHCHK_WARNING
ctl_set_bit(14, 24); /* enable warning MCH */
#endif
diff --git a/drivers/s390/s390mach.h b/drivers/s390/s390mach.h
index 7e26f0f1b0d..4eaa7017918 100644
--- a/drivers/s390/s390mach.h
+++ b/drivers/s390/s390mach.h
@@ -16,20 +16,45 @@ struct mci {
__u32 sd : 1; /* 00 system damage */
__u32 pd : 1; /* 01 instruction-processing damage */
__u32 sr : 1; /* 02 system recovery */
- __u32 to_be_defined_1 : 4; /* 03-06 */
+ __u32 to_be_defined_1 : 1; /* 03 */
+ __u32 cd : 1; /* 04 timing-facility damage */
+ __u32 ed : 1; /* 05 external damage */
+ __u32 to_be_defined_2 : 1; /* 06 */
__u32 dg : 1; /* 07 degradation */
__u32 w : 1; /* 08 warning pending */
__u32 cp : 1; /* 09 channel-report pending */
- __u32 to_be_defined_2 : 6; /* 10-15 */
+ __u32 sp : 1; /* 10 service-processor damage */
+ __u32 ck : 1; /* 11 channel-subsystem damage */
+ __u32 to_be_defined_3 : 2; /* 12-13 */
+ __u32 b : 1; /* 14 backed up */
+ __u32 to_be_defined_4 : 1; /* 15 */
__u32 se : 1; /* 16 storage error uncorrected */
__u32 sc : 1; /* 17 storage error corrected */
__u32 ke : 1; /* 18 storage-key error uncorrected */
__u32 ds : 1; /* 19 storage degradation */
- __u32 to_be_defined_3 : 4; /* 20-23 */
+ __u32 wp : 1; /* 20 psw mwp validity */
+ __u32 ms : 1; /* 21 psw mask and key validity */
+ __u32 pm : 1; /* 22 psw program mask and cc validity */
+ __u32 ia : 1; /* 23 psw instruction address validity */
__u32 fa : 1; /* 24 failing storage address validity */
- __u32 to_be_defined_4 : 7; /* 25-31 */
+ __u32 to_be_defined_5 : 1; /* 25 */
+ __u32 ec : 1; /* 26 external damage code validity */
+ __u32 fp : 1; /* 27 floating point register validity */
+ __u32 gr : 1; /* 28 general register validity */
+ __u32 cr : 1; /* 29 control register validity */
+ __u32 to_be_defined_6 : 1; /* 30 */
+ __u32 st : 1; /* 31 storage logical validity */
__u32 ie : 1; /* 32 indirect storage error */
- __u32 to_be_defined_5 : 31; /* 33-63 */
+ __u32 ar : 1; /* 33 access register validity */
+ __u32 da : 1; /* 34 delayed access exception */
+ __u32 to_be_defined_7 : 7; /* 35-41 */
+ __u32 pr : 1; /* 42 tod programmable register validity */
+ __u32 fc : 1; /* 43 fp control register validity */
+ __u32 ap : 1; /* 44 ancillary report */
+ __u32 to_be_defined_8 : 1; /* 45 */
+ __u32 ct : 1; /* 46 cpu timer validity */
+ __u32 cc : 1; /* 47 clock comparator validity */
+ __u32 to_be_defined_9 : 16; /* 47-63 */
};
/*
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 9cc0015b717..bbe346bd3cb 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -34,7 +34,6 @@
#define ADDR32 (0)
-#include <linux/version.h>
#include <linux/module.h>
MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
@@ -1126,11 +1125,11 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
struct adpt_i2o_post_wait_data *p1, *p2;
struct adpt_i2o_post_wait_data *wait_data =
kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
- adpt_wait_queue_t wait;
+ DECLARE_WAITQUEUE(wait, current);
- if(!wait_data){
+ if (!wait_data)
return -ENOMEM;
- }
+
/*
* The spin locking is needed to keep anyone from playing
* with the queue pointers and id while we do the same
@@ -1148,12 +1147,7 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
wait_data->wq = &adpt_wq_i2o_post;
wait_data->status = -ETIMEDOUT;
- // this code is taken from kernel/sched.c:interruptible_sleep_on_timeout
- wait.task = current;
- init_waitqueue_entry(&wait, current);
- spin_lock_irqsave(&adpt_wq_i2o_post.lock, flags);
- __add_wait_queue(&adpt_wq_i2o_post, &wait);
- spin_unlock(&adpt_wq_i2o_post.lock);
+ add_wait_queue(&adpt_wq_i2o_post, &wait);
msg[2] |= 0x80000000 | ((u32)wait_data->id);
timeout *= HZ;
@@ -1175,9 +1169,7 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
if(pHba->host)
spin_lock_irq(pHba->host->host_lock);
}
- spin_lock_irq(&adpt_wq_i2o_post.lock);
- __remove_wait_queue(&adpt_wq_i2o_post, &wait);
- spin_unlock_irqrestore(&adpt_wq_i2o_post.lock, flags);
+ remove_wait_queue(&adpt_wq_i2o_post, &wait);
if(status == -ETIMEDOUT){
printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
@@ -1818,9 +1810,9 @@ static int adpt_system_info(void __user *buffer)
memset(&si, 0, sizeof(si));
si.osType = OS_LINUX;
- si.osMajorVersion = (u8) (LINUX_VERSION_CODE >> 16);
- si.osMinorVersion = (u8) (LINUX_VERSION_CODE >> 8 & 0x0ff);
- si.osRevision = (u8) (LINUX_VERSION_CODE & 0x0ff);
+ si.osMajorVersion = 0;
+ si.osMinorVersion = 0;
+ si.osRevision = 0;
si.busType = SI_PCI_BUS;
si.processorFamily = DPTI_sig.dsProcessorFamily;
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index 9821783c016..489194af43d 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -20,15 +20,7 @@
#ifndef _DPT_H
#define _DPT_H
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,00)
-#define MAX_TO_IOP_MESSAGES (210)
-#else
#define MAX_TO_IOP_MESSAGES (255)
-#endif
#define MAX_FROM_IOP_MESSAGES (255)
@@ -321,10 +313,6 @@ static int adpt_close(struct inode *inode, struct file *file);
static void adpt_delay(int millisec);
#endif
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-static struct pci_dev* adpt_pci_find_device(uint vendor, struct pci_dev* from);
-#endif
-
#if defined __ia64__
static void adpt_ia64_info(sysInfo_S* si);
#endif
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index ba347576d99..d7a38b6713f 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -56,7 +56,7 @@ static struct class shost_class = {
* @shost: pointer to struct Scsi_Host
* recovery: recovery requested to run.
**/
-void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
+static void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
{
struct scsi_device *sdev;
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index f7ddc9f1ba4..2094d4811d6 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -223,7 +223,7 @@ static void tul_select_atn(HCS * pCurHcb, SCB * pCurScb);
static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb);
static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb);
static int int_tul_busfree(HCS * pCurHcb);
-int int_tul_scsi_rst(HCS * pCurHcb);
+static int int_tul_scsi_rst(HCS * pCurHcb);
static int int_tul_bad_seq(HCS * pCurHcb);
static int int_tul_resel(HCS * pCurHcb);
static int tul_sync_done(HCS * pCurHcb);
@@ -240,9 +240,8 @@ static int tul_se2_rd_all(WORD CurBase);
static void tul_se2_update_all(WORD CurBase); /* setup default pattern */
static void tul_read_eeprom(WORD CurBase);
- /* ---- EXTERNAL VARIABLES ---- */
-HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
/* ---- INTERNAL VARIABLES ---- */
+static HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS];
/*NVRAM nvram, *nvramp = &nvram; */
@@ -381,7 +380,7 @@ void tul_se2_wait(void)
******************************************************************/
-void tul_se2_instr(WORD CurBase, UCHAR instr)
+static void tul_se2_instr(WORD CurBase, UCHAR instr)
{
int i;
UCHAR b;
@@ -437,7 +436,7 @@ void tul_se2_ew_ds(WORD CurBase)
Input :address of Serial E2PROM
Output :value stored in Serial E2PROM
*******************************************************************/
-USHORT tul_se2_rd(WORD CurBase, ULONG adr)
+static USHORT tul_se2_rd(WORD CurBase, ULONG adr)
{
UCHAR instr, readByte;
USHORT readWord;
@@ -468,7 +467,7 @@ USHORT tul_se2_rd(WORD CurBase, ULONG adr)
/******************************************************************
Input: new value in Serial E2PROM, address of Serial E2PROM
*******************************************************************/
-void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
+static void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
{
UCHAR readByte;
UCHAR instr;
@@ -584,8 +583,8 @@ void tul_read_eeprom(WORD CurBase)
TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT);
} /* read_eeprom */
-int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
- BYTE bBus, BYTE bDevice)
+static int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
+ BYTE bBus, BYTE bDevice)
{
int i, j;
@@ -616,7 +615,7 @@ int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
return 1;
}
-void init_i91uAdapter_table(void)
+static void init_i91uAdapter_table(void)
{
int i;
@@ -630,7 +629,7 @@ void init_i91uAdapter_table(void)
return;
}
-void tul_stop_bm(HCS * pCurHcb)
+static void tul_stop_bm(HCS * pCurHcb)
{
if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* if DMA xfer is pending, abort DMA xfer */
@@ -642,7 +641,7 @@ void tul_stop_bm(HCS * pCurHcb)
}
/***************************************************************************/
-void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
+static void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
{
pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE; /* Supply base address */
pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */
@@ -651,7 +650,7 @@ void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
}
/***************************************************************************/
-int tul_reset_scsi(HCS * pCurHcb, int seconds)
+static int tul_reset_scsi(HCS * pCurHcb, int seconds)
{
TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS);
@@ -670,7 +669,8 @@ int tul_reset_scsi(HCS * pCurHcb, int seconds)
}
/***************************************************************************/
-int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, BYTE * pbBiosAdr, int seconds)
+static int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb,
+ BYTE * pbBiosAdr, int seconds)
{
int i;
BYTE *pwFlags;
@@ -788,7 +788,7 @@ int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, BYTE * pbBiosAdr, int
}
/***************************************************************************/
-SCB *tul_alloc_scb(HCS * hcsp)
+static SCB *tul_alloc_scb(HCS * hcsp)
{
SCB *pTmpScb;
ULONG flags;
@@ -807,7 +807,7 @@ SCB *tul_alloc_scb(HCS * hcsp)
}
/***************************************************************************/
-void tul_release_scb(HCS * hcsp, SCB * scbp)
+static void tul_release_scb(HCS * hcsp, SCB * scbp)
{
ULONG flags;
@@ -829,7 +829,7 @@ void tul_release_scb(HCS * hcsp, SCB * scbp)
}
/***************************************************************************/
-void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
{
#if DEBUG_QUEUE
@@ -847,7 +847,7 @@ void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
}
/***************************************************************************/
-void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
{
#if DEBUG_QUEUE
@@ -863,7 +863,7 @@ void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
}
/***************************************************************************/
-SCB *tul_find_first_pend_scb(HCS * pCurHcb)
+static SCB *tul_find_first_pend_scb(HCS * pCurHcb)
{
SCB *pFirstPend;
@@ -894,24 +894,7 @@ SCB *tul_find_first_pend_scb(HCS * pCurHcb)
return (pFirstPend);
}
/***************************************************************************/
-SCB *tul_pop_pend_scb(HCS * pCurHcb)
-{
- SCB *pTmpScb;
-
- if ((pTmpScb = pCurHcb->HCS_FirstPend) != NULL) {
- if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
- pCurHcb->HCS_LastPend = NULL;
- pTmpScb->SCB_NxtScb = NULL;
- }
-#if DEBUG_QUEUE
- printk("Pop pend SCB %lx; ", (ULONG) pTmpScb);
-#endif
- return (pTmpScb);
-}
-
-
-/***************************************************************************/
-void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
+static void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
{
SCB *pTmpScb, *pPrevScb;
@@ -939,7 +922,7 @@ void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
return;
}
/***************************************************************************/
-void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
{
#if DEBUG_QUEUE
@@ -961,7 +944,7 @@ void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
}
/***************************************************************************/
-SCB *tul_pop_busy_scb(HCS * pCurHcb)
+static SCB *tul_pop_busy_scb(HCS * pCurHcb)
{
SCB *pTmpScb;
@@ -982,7 +965,7 @@ SCB *tul_pop_busy_scb(HCS * pCurHcb)
}
/***************************************************************************/
-void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
+static void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
{
SCB *pTmpScb, *pPrevScb;
@@ -1037,7 +1020,7 @@ SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun)
}
/***************************************************************************/
-void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
+static void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
{
#if DEBUG_QUEUE
@@ -1073,7 +1056,7 @@ SCB *tul_find_done_scb(HCS * pCurHcb)
}
/***************************************************************************/
-int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
+static int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
{
ULONG flags;
SCB *pTmpScb, *pPrevScb;
@@ -1163,7 +1146,7 @@ int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
}
/***************************************************************************/
-int tul_bad_seq(HCS * pCurHcb)
+static int tul_bad_seq(HCS * pCurHcb)
{
SCB *pCurScb;
@@ -1182,9 +1165,11 @@ int tul_bad_seq(HCS * pCurHcb)
return (tul_post_scsi_rst(pCurHcb));
}
+#if 0
+
/************************************************************************/
-int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
- unsigned int target, unsigned int ResetFlags)
+static int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
+ unsigned int target, unsigned int ResetFlags)
{
ULONG flags;
SCB *pScb;
@@ -1255,7 +1240,7 @@ int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
return SCSI_RESET_PENDING;
}
-int tul_reset_scsi_bus(HCS * pCurHcb)
+static int tul_reset_scsi_bus(HCS * pCurHcb)
{
ULONG flags;
@@ -1284,8 +1269,10 @@ int tul_reset_scsi_bus(HCS * pCurHcb)
return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);
}
+#endif /* 0 */
+
/************************************************************************/
-void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
+static void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
{
ULONG flags;
@@ -1318,7 +1305,7 @@ void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
}
/***************************************************************************/
-int tul_isr(HCS * pCurHcb)
+static int tul_isr(HCS * pCurHcb)
{
/* Enter critical section */
@@ -2108,7 +2095,7 @@ int int_tul_busfree(HCS * pCurHcb)
/***************************************************************************/
/* scsi bus reset */
-int int_tul_scsi_rst(HCS * pCurHcb)
+static int int_tul_scsi_rst(HCS * pCurHcb)
{
SCB *pCurScb;
int i;
@@ -2214,7 +2201,7 @@ int int_tul_resel(HCS * pCurHcb)
/***************************************************************************/
-int int_tul_bad_seq(HCS * pCurHcb)
+static int int_tul_bad_seq(HCS * pCurHcb)
{ /* target wrong phase */
SCB *pCurScb;
int i;
diff --git a/drivers/scsi/initio.h b/drivers/scsi/initio.h
index df3ed7c1cee..3efb1184fc3 100644
--- a/drivers/scsi/initio.h
+++ b/drivers/scsi/initio.h
@@ -719,21 +719,3 @@ typedef struct _HCSinfo {
#define SCSI_RESET_HOST_RESET 0x200
#define SCSI_RESET_ACTION 0xff
-extern void init_i91uAdapter_table(void);
-extern int Addi91u_into_Adapter_table(WORD, WORD, BYTE, BYTE, BYTE);
-extern int tul_ReturnNumberOfAdapters(void);
-extern void get_tulipPCIConfig(HCS * pHCB, int iChannel_index);
-extern int init_tulip(HCS * pHCB, SCB * pSCB, int tul_num_scb, BYTE * pbBiosAdr, int reset_time);
-extern SCB *tul_alloc_scb(HCS * pHCB);
-extern int tul_abort_srb(HCS * pHCB, struct scsi_cmnd * pSRB);
-extern void tul_exec_scb(HCS * pHCB, SCB * pSCB);
-extern void tul_release_scb(HCS * pHCB, SCB * pSCB);
-extern void tul_stop_bm(HCS * pHCB);
-extern int tul_reset_scsi(HCS * pCurHcb, int seconds);
-extern int tul_isr(HCS * pHCB);
-extern int tul_reset(HCS * pHCB, struct scsi_cmnd * pSRB, unsigned char target);
-extern int tul_reset_scsi_bus(HCS * pCurHcb);
-extern int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
- unsigned int target, unsigned int ResetFlags);
- /* ---- EXTERNAL VARIABLES ---- */
-extern HCS tul_hcs[];
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 5578ae9a9e4..1cb5f7d4f27 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -68,6 +68,8 @@
#include "scsi_priv.h"
#include "scsi_logging.h"
+static void scsi_done(struct scsi_cmnd *cmd);
+static int scsi_retry_command(struct scsi_cmnd *cmd);
/*
* Definitions and constants.
@@ -741,7 +743,7 @@ static DEFINE_PER_CPU(struct list_head, scsi_done_q);
*
* This function is interrupt context safe.
*/
-void scsi_done(struct scsi_cmnd *cmd)
+static void scsi_done(struct scsi_cmnd *cmd)
{
/*
* We don't have to worry about this one timing out any more.
@@ -836,7 +838,7 @@ static void scsi_softirq(struct softirq_action *h)
* level drivers should not become re-entrant as a result of
* this.
*/
-int scsi_retry_command(struct scsi_cmnd *cmd)
+static int scsi_retry_command(struct scsi_cmnd *cmd)
{
/*
* Restore the SCSI command state.
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index e0208886b45..322b5a41a36 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1783,7 +1783,7 @@ static void __exit scsi_debug_exit(void)
device_initcall(scsi_debug_init);
module_exit(scsi_debug_exit);
-void pseudo_0_release(struct device * dev)
+static void pseudo_0_release(struct device * dev)
{
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n");
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9f996499fa9..621dee8b8cb 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -44,7 +44,7 @@ struct scsi_host_sg_pool {
#endif
#define SP(x) { x, "sgpool-" #x }
-struct scsi_host_sg_pool scsi_sg_pools[] = {
+static struct scsi_host_sg_pool scsi_sg_pools[] = {
SP(8),
SP(16),
SP(32),
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index c01580df447..96d4f745975 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -61,8 +61,6 @@ extern void scsi_exit_hosts(void);
extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
-extern void scsi_done(struct scsi_cmnd *cmd);
-extern int scsi_retry_command(struct scsi_cmnd *cmd);
extern int scsi_insert_special_req(struct scsi_request *sreq, int);
extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
struct scsi_request *sreq);
@@ -136,7 +134,6 @@ extern void scsi_exit_sysctl(void);
#endif /* CONFIG_SYSCTL */
/* scsi_sysfs.c */
-extern void scsi_device_dev_release(struct device *);
extern int scsi_sysfs_add_sdev(struct scsi_device *);
extern int scsi_sysfs_add_host(struct Scsi_Host *);
extern int scsi_sysfs_register(void);
@@ -145,7 +142,6 @@ extern void scsi_sysfs_device_initialize(struct scsi_device *);
extern int scsi_sysfs_target_initialize(struct scsi_device *);
extern struct scsi_transport_template blank_transport_template;
-extern struct class sdev_class;
extern struct bus_type scsi_bus_type;
/*
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 93b41100a6d..beed7fbe1cb 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -150,7 +150,7 @@ static void scsi_device_cls_release(struct class_device *class_dev)
put_device(&sdev->sdev_gendev);
}
-void scsi_device_dev_release(struct device *dev)
+static void scsi_device_dev_release(struct device *dev)
{
struct scsi_device *sdev;
struct device *parent;
@@ -185,7 +185,7 @@ void scsi_device_dev_release(struct device *dev)
put_device(parent);
}
-struct class sdev_class = {
+static struct class sdev_class = {
.name = "scsi_device",
.release = scsi_device_cls_release,
};
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index db92a0ceda7..feb8e73fc1c 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -992,18 +992,17 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value)
/*
* This routine sends a break character out the serial port.
*/
-static void send_break( struct m68k_serial * info, int duration)
+static void send_break(struct m68k_serial * info, unsigned int duration)
{
m68328_uart *uart = &uart_addr[info->line];
unsigned long flags;
if (!info->port)
return;
- set_current_state(TASK_INTERRUPTIBLE);
save_flags(flags);
cli();
#ifdef USE_INTS
uart->utx.w |= UTX_SEND_BREAK;
- schedule_timeout(duration);
+ msleep_interruptible(duration);
uart->utx.w &= ~UTX_SEND_BREAK;
#endif
restore_flags(flags);
@@ -1033,14 +1032,14 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
return retval;
tty_wait_until_sent(tty, 0);
if (!arg)
- send_break(info, HZ/4); /* 1/4 second */
+ send_break(info, 250); /* 1/4 second */
return 0;
case TCSBRKP: /* support for POSIX tcsendbreak() */
retval = tty_check_change(tty);
if (retval)
return retval;
tty_wait_until_sent(tty, 0);
- send_break(info, arg ? arg*(HZ/10) : HZ/4);
+ send_break(info, arg ? arg*(100) : 250);
return 0;
case TIOCGSOFTCAR:
error = put_user(C_CLOCAL(tty) ? 1 : 0,
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c
index f148022b6b4..b116122e569 100644
--- a/drivers/serial/68360serial.c
+++ b/drivers/serial/68360serial.c
@@ -1394,14 +1394,13 @@ static void end_break(ser_info_t *info)
/*
* This routine sends a break character out the serial port.
*/
-static void send_break(ser_info_t *info, int duration)
+static void send_break(ser_info_t *info, unsigned int duration)
{
- set_current_state(TASK_INTERRUPTIBLE);
#ifdef SERIAL_DEBUG_SEND_BREAK
printk("rs_send_break(%d) jiff=%lu...", duration, jiffies);
#endif
begin_break(info);
- schedule_timeout(duration);
+ msleep_interruptible(duration);
end_break(info);
#ifdef SERIAL_DEBUG_SEND_BREAK
printk("done jiffies=%lu\n", jiffies);
@@ -1436,7 +1435,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
if (signal_pending(current))
return -EINTR;
if (!arg) {
- send_break(info, HZ/4); /* 1/4 second */
+ send_break(info, 250); /* 1/4 second */
if (signal_pending(current))
return -EINTR;
}
@@ -1448,7 +1447,7 @@ static int rs_360_ioctl(struct tty_struct *tty, struct file * file,
tty_wait_until_sent(tty, 0);
if (signal_pending(current))
return -EINTR;
- send_break(info, arg ? arg*(HZ/10) : HZ/4);
+ send_break(info, arg ? arg*100 : 250);
if (signal_pending(current))
return -EINTR;
return 0;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 30e8beb7143..d8b9d2b8c20 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -132,9 +132,9 @@ struct uart_8250_port {
struct uart_port port;
struct timer_list timer; /* "no irq" timer */
struct list_head list; /* ports on this IRQ */
- unsigned int capabilities; /* port capabilities */
+ unsigned short capabilities; /* port capabilities */
+ unsigned short bugs; /* port bugs */
unsigned int tx_loadsz; /* transmit fifo load size */
- unsigned short rev;
unsigned char acr;
unsigned char ier;
unsigned char lcr;
@@ -560,7 +560,14 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
if (id1 == 0x16 && id2 == 0xC9 &&
(id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
up->port.type = PORT_16C950;
- up->rev = rev | (id3 << 8);
+
+ /*
+ * Enable work around for the Oxford Semiconductor 952 rev B
+ * chip which causes it to seriously miscalculate baud rates
+ * when DLL is 0.
+ */
+ if (id3 == 0x52 && rev == 0x01)
+ up->bugs |= UART_BUG_QUOT;
return;
}
@@ -577,8 +584,6 @@ static void autoconfig_has_efr(struct uart_8250_port *up)
id2 = id1 >> 8;
if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
- if (id2 == 0x10)
- up->rev = id1 & 255;
up->port.type = PORT_16850;
return;
}
@@ -809,6 +814,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
// save_flags(flags); cli();
up->capabilities = 0;
+ up->bugs = 0;
if (!(up->port.flags & UPF_BUGGY_UART)) {
/*
@@ -1021,6 +1027,8 @@ static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
}
}
+static void transmit_chars(struct uart_8250_port *up);
+
static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
@@ -1028,6 +1036,14 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
if (!(up->ier & UART_IER_THRI)) {
up->ier |= UART_IER_THRI;
serial_out(up, UART_IER, up->ier);
+
+ if (up->bugs & UART_BUG_TXEN) {
+ unsigned char lsr, iir;
+ lsr = serial_in(up, UART_LSR);
+ iir = serial_in(up, UART_IIR);
+ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)
+ transmit_chars(up);
+ }
}
/*
* We only do this from uart_start
@@ -1433,6 +1449,7 @@ static int serial8250_startup(struct uart_port *port)
{
struct uart_8250_port *up = (struct uart_8250_port *)port;
unsigned long flags;
+ unsigned char lsr, iir;
int retval;
up->capabilities = uart_config[up->port.type].flags;
@@ -1536,6 +1553,26 @@ static int serial8250_startup(struct uart_port *port)
up->port.mctrl |= TIOCM_OUT2;
serial8250_set_mctrl(&up->port, up->port.mctrl);
+
+ /*
+ * Do a quick test to see if we receive an
+ * interrupt when we enable the TX irq.
+ */
+ serial_outp(up, UART_IER, UART_IER_THRI);
+ lsr = serial_in(up, UART_LSR);
+ iir = serial_in(up, UART_IIR);
+ serial_outp(up, UART_IER, 0);
+
+ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
+ if (!(up->bugs & UART_BUG_TXEN)) {
+ up->bugs |= UART_BUG_TXEN;
+ pr_debug("ttyS%d - enabling bad tx status workarounds\n",
+ port->line);
+ }
+ } else {
+ up->bugs &= ~UART_BUG_TXEN;
+ }
+
spin_unlock_irqrestore(&up->port.lock, flags);
/*
@@ -1645,22 +1682,22 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
switch (termios->c_cflag & CSIZE) {
case CS5:
- cval = 0x00;
+ cval = UART_LCR_WLEN5;
break;
case CS6:
- cval = 0x01;
+ cval = UART_LCR_WLEN6;
break;
case CS7:
- cval = 0x02;
+ cval = UART_LCR_WLEN7;
break;
default:
case CS8:
- cval = 0x03;
+ cval = UART_LCR_WLEN8;
break;
}
if (termios->c_cflag & CSTOPB)
- cval |= 0x04;
+ cval |= UART_LCR_STOP;
if (termios->c_cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(termios->c_cflag & PARODD))
@@ -1677,12 +1714,9 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
quot = serial8250_get_divisor(port, baud);
/*
- * Work around a bug in the Oxford Semiconductor 952 rev B
- * chip which causes it to seriously miscalculate baud rates
- * when DLL is 0.
+ * Oxford Semi 952 rev B workaround
*/
- if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 &&
- up->rev == 0x5201)
+ if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
quot ++;
if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) {
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index 4f3d62f222f..9225c82faeb 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -51,6 +51,9 @@ struct serial8250_config {
#define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */
#define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */
+#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
+#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
+
#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
#define _INLINE_ inline
#else
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c
index b6d3d503494..5400dc2c087 100644
--- a/drivers/serial/au1x00_uart.c
+++ b/drivers/serial/au1x00_uart.c
@@ -773,22 +773,22 @@ serial8250_set_termios(struct uart_port *port, struct termios *termios,
switch (termios->c_cflag & CSIZE) {
case CS5:
- cval = 0x00;
+ cval = UART_LCR_WLEN5;
break;
case CS6:
- cval = 0x01;
+ cval = UART_LCR_WLEN6;
break;
case CS7:
- cval = 0x02;
+ cval = UART_LCR_WLEN7;
break;
default:
case CS8:
- cval = 0x03;
+ cval = UART_LCR_WLEN8;
break;
}
if (termios->c_cflag & CSTOPB)
- cval |= 0x04;
+ cval |= UART_LCR_STOP;
if (termios->c_cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/icom.h b/drivers/serial/icom.h
index 23dc0f7ddf8..798f1ef2371 100644
--- a/drivers/serial/icom.h
+++ b/drivers/serial/icom.h
@@ -286,5 +286,3 @@ struct lookup_int_table {
u32 __iomem *global_int_mask;
unsigned long processor_id;
};
-
-#define MSECS_TO_JIFFIES(ms) (((ms)*HZ+999)/1000)
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 08d61f13edc..0301feacbde 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -724,22 +724,22 @@ static void m32r_sio_set_termios(struct uart_port *port,
switch (termios->c_cflag & CSIZE) {
case CS5:
- cval = 0x00;
+ cval = UART_LCR_WLEN5;
break;
case CS6:
- cval = 0x01;
+ cval = UART_LCR_WLEN6;
break;
case CS7:
- cval = 0x02;
+ cval = UART_LCR_WLEN7;
break;
default:
case CS8:
- cval = 0x03;
+ cval = UART_LCR_WLEN8;
break;
}
if (termios->c_cflag & CSTOPB)
- cval |= 0x04;
+ cval |= UART_LCR_STOP;
if (termios->c_cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c
index a8314aee2ab..a2a64331800 100644
--- a/drivers/serial/mpsc.c
+++ b/drivers/serial/mpsc.c
@@ -67,7 +67,11 @@
static struct mpsc_port_info mpsc_ports[MPSC_NUM_CTLRS];
static struct mpsc_shared_regs mpsc_shared_regs;
+static struct uart_driver mpsc_reg;
+static void mpsc_start_rx(struct mpsc_port_info *pi);
+static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
+static void mpsc_release_port(struct uart_port *port);
/*
******************************************************************************
*
@@ -546,7 +550,6 @@ static int
mpsc_alloc_ring_mem(struct mpsc_port_info *pi)
{
int rc = 0;
- static void mpsc_free_ring_mem(struct mpsc_port_info *pi);
pr_debug("mpsc_alloc_ring_mem[%d]: Allocating ring mem\n",
pi->port.line);
@@ -745,7 +748,6 @@ mpsc_rx_intr(struct mpsc_port_info *pi, struct pt_regs *regs)
int rc = 0;
u8 *bp;
char flag = TTY_NORMAL;
- static void mpsc_start_rx(struct mpsc_port_info *pi);
pr_debug("mpsc_rx_intr[%d]: Handling Rx intr\n", pi->port.line);
@@ -1178,7 +1180,6 @@ static void
mpsc_shutdown(struct uart_port *port)
{
struct mpsc_port_info *pi = (struct mpsc_port_info *)port;
- static void mpsc_release_port(struct uart_port *port);
pr_debug("mpsc_shutdown[%d]: Shutting down MPSC\n", port->line);
@@ -1448,7 +1449,6 @@ mpsc_console_setup(struct console *co, char *options)
return uart_set_options(&pi->port, co, baud, parity, bits, flow);
}
-extern struct uart_driver mpsc_reg;
static struct console mpsc_console = {
.name = MPSC_DEV_NAME,
.write = mpsc_console_write,
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 9dc151d8fa6..08b08d6ae90 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -455,22 +455,22 @@ serial_pxa_set_termios(struct uart_port *port, struct termios *termios,
switch (termios->c_cflag & CSIZE) {
case CS5:
- cval = 0x00;
+ cval = UART_LCR_WLEN5;
break;
case CS6:
- cval = 0x01;
+ cval = UART_LCR_WLEN6;
break;
case CS7:
- cval = 0x02;
+ cval = UART_LCR_WLEN7;
break;
default:
case CS8:
- cval = 0x03;
+ cval = UART_LCR_WLEN8;
break;
}
if (termios->c_cflag & CSTOPB)
- cval |= 0x04;
+ cval |= UART_LCR_STOP;
if (termios->c_cflag & PARENB)
cval |= UART_LCR_PARITY;
if (!(termios->c_cflag & PARODD))
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 2a9f7ade2c9..5c4678478b1 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -198,7 +198,7 @@ static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port)
/* translate a port to the device name */
-static inline char *s3c24xx_serial_portname(struct uart_port *port)
+static inline const char *s3c24xx_serial_portname(struct uart_port *port)
{
return to_platform_device(port->dev)->name;
}
@@ -903,7 +903,7 @@ static void s3c24xx_serial_release_port(struct uart_port *port)
static int s3c24xx_serial_request_port(struct uart_port *port)
{
- char *name = s3c24xx_serial_portname(port);
+ const char *name = s3c24xx_serial_portname(port);
return request_mem_region(port->mapbase, MAP_SIZE, name) ? 0 : -EBUSY;
}
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index fee6418e84c..840815fde49 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -572,6 +572,7 @@ static void sn_transmit_chars(struct sn_cons_port *port, int raw)
if (uart_circ_empty(xmit) || uart_tx_stopped(&port->sc_port)) {
/* Nothing to do. */
+ ia64_sn_console_intr_disable(SAL_CONSOLE_INTR_XMIT);
return;
}
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 5c4231ae295..8e65206d3d7 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1071,7 +1071,7 @@ static void __init sunzilog_alloc_tables(void)
*/
static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
{
- unsigned long mapped_addr;
+ void __iomem *mapped_addr;
unsigned int sun4u_ino;
struct sbus_bus *sbus = NULL;
struct sbus_dev *sdev = NULL;
@@ -1111,9 +1111,9 @@ static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
apply_fhc_ranges(central_bus->child,
&zsregs[0], 1);
apply_central_ranges(central_bus, &zsregs[0], 1);
- mapped_addr =
- (((u64)zsregs[0].which_io)<<32UL) |
- ((u64)zsregs[0].phys_addr);
+ mapped_addr = (void __iomem *)
+ ((((u64)zsregs[0].which_io)<<32UL) |
+ ((u64)zsregs[0].phys_addr));
}
if (zilog_irq == -1) {
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index d5863b8b56e..f2c9fa423d4 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -329,10 +329,8 @@ static IXJ *ixj_alloc()
static void ixj_fsk_free(IXJ *j)
{
- if(j->fskdata != NULL) {
- kfree(j->fskdata);
- j->fskdata = NULL;
- }
+ kfree(j->fskdata);
+ j->fskdata = NULL;
}
static void ixj_fsk_alloc(IXJ *j)
@@ -3867,13 +3865,11 @@ static int set_rec_codec(IXJ *j, int rate)
j->rec_mode = 7;
break;
default:
+ kfree(j->read_buffer);
j->rec_frame_size = 0;
j->rec_mode = -1;
- if (j->read_buffer) {
- kfree(j->read_buffer);
- j->read_buffer = NULL;
- j->read_buffer_size = 0;
- }
+ j->read_buffer = NULL;
+ j->read_buffer_size = 0;
retval = 1;
break;
}
@@ -3991,14 +3987,12 @@ static int ixj_record_start(IXJ *j)
static void ixj_record_stop(IXJ *j)
{
- if(ixjdebug & 0x0002)
+ if (ixjdebug & 0x0002)
printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
- if (j->read_buffer) {
- kfree(j->read_buffer);
- j->read_buffer = NULL;
- j->read_buffer_size = 0;
- }
+ kfree(j->read_buffer);
+ j->read_buffer = NULL;
+ j->read_buffer_size = 0;
if (j->rec_mode > -1) {
ixj_WriteDSPCommand(0x5120, j);
j->rec_mode = -1;
@@ -4449,13 +4443,11 @@ static int set_play_codec(IXJ *j, int rate)
j->play_mode = 5;
break;
default:
+ kfree(j->write_buffer);
j->play_frame_size = 0;
j->play_mode = -1;
- if (j->write_buffer) {
- kfree(j->write_buffer);
- j->write_buffer = NULL;
- j->write_buffer_size = 0;
- }
+ j->write_buffer = NULL;
+ j->write_buffer_size = 0;
retval = 1;
break;
}
@@ -4578,14 +4570,12 @@ static int ixj_play_start(IXJ *j)
static void ixj_play_stop(IXJ *j)
{
- if(ixjdebug & 0x0002)
+ if (ixjdebug & 0x0002)
printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
- if (j->write_buffer) {
- kfree(j->write_buffer);
- j->write_buffer = NULL;
- j->write_buffer_size = 0;
- }
+ kfree(j->write_buffer);
+ j->write_buffer = NULL;
+ j->write_buffer_size = 0;
if (j->play_mode > -1) {
ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers. 8022 reference page 9-40 */
@@ -5810,9 +5800,7 @@ static void ixj_cpt_stop(IXJ *j)
ixj_play_tone(j, 0);
j->tone_state = j->tone_cadence_state = 0;
if (j->cadence_t) {
- if (j->cadence_t->ce) {
- kfree(j->cadence_t->ce);
- }
+ kfree(j->cadence_t->ce);
kfree(j->cadence_t);
j->cadence_t = NULL;
}
@@ -7497,10 +7485,8 @@ static void cleanup(void)
printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
release_region(j->XILINXbase, 4);
}
- if (j->read_buffer)
- kfree(j->read_buffer);
- if (j->write_buffer)
- kfree(j->write_buffer);
+ kfree(j->read_buffer);
+ kfree(j->write_buffer);
if (j->dev)
pnp_device_detach(j->dev);
if (ixjdebug & 0x0002)
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index d041782e0c8..0da23732e80 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1794,7 +1794,7 @@ EXPORT_SYMBOL (usb_remove_hcd);
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
+#if defined(CONFIG_USB_MON)
struct usb_mon_operations *mon_ops;
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index f67cf1e634f..325a51656c3 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -399,7 +399,7 @@ static inline void usbfs_cleanup(void) { }
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
+#if defined(CONFIG_USB_MON)
struct usb_mon_operations {
void (*urb_submit)(struct usb_bus *bus, struct urb *urb);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d2d648ee864..a8d879a85d0 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2808,7 +2808,7 @@ static int hub_thread(void *__unused)
do {
hub_events();
wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list));
- try_to_freeze(PF_FREEZE);
+ try_to_freeze();
} while (!signal_pending(current));
pr_debug ("%s: khubd exiting\n", usbcore_name);
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index f9f9561c6ba..c3e3a95d380 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -453,17 +453,6 @@ static int usbfs_fill_super(struct super_block *sb, void *data, int silent)
return 0;
}
-static struct dentry * get_dentry(struct dentry *parent, const char *name)
-{
- struct qstr qstr;
-
- qstr.name = name;
- qstr.len = strlen(name);
- qstr.hash = full_name_hash(name,qstr.len);
- return lookup_hash(&qstr,parent);
-}
-
-
/*
* fs_create_by_name - create a file, given a name
* @name: name of file
@@ -496,7 +485,7 @@ static int fs_create_by_name (const char *name, mode_t mode,
*dentry = NULL;
down(&parent->d_inode->i_sem);
- *dentry = get_dentry (parent, name);
+ *dentry = lookup_one_len(name, parent, strlen(name));
if (!IS_ERR(dentry)) {
if ((mode & S_IFMT) == S_IFDIR)
error = usbfs_mkdir (parent->d_inode, *dentry, mode);
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 037a7f16382..a9be85103d2 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -1554,8 +1554,7 @@ static int sleep_thread(struct fsg_dev *fsg)
rc = wait_event_interruptible(fsg->thread_wqh,
fsg->thread_wakeup_needed);
fsg->thread_wakeup_needed = 0;
- if (current->flags & PF_FREEZE)
- refrigerator(PF_FREEZE);
+ try_to_freeze();
return (rc ? -EINTR : 0);
}
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c
index bc3b1635eab..ef4204eab6c 100644
--- a/drivers/usb/media/pwc/pwc-uncompress.c
+++ b/drivers/usb/media/pwc/pwc-uncompress.c
@@ -118,9 +118,9 @@ int pwc_decompress(struct pwc_device *pdev)
return -ENXIO; /* No such device or address: missing decompressor */
}
+#if 0
switch (pdev->type)
{
-#if 0
case 675:
case 680:
case 690:
@@ -128,18 +128,17 @@ int pwc_decompress(struct pwc_device *pdev)
case 730:
case 740:
case 750:
- pwc_dec23_decompress(&pdev->image, &pdev->view, &pdev->offset,
- yuv, image,
- flags,
+ pwc_dec23_decompress(&pdev->image, &pdev->view,
+ &pdev->offset, yuv, image, flags,
pdev->decompress_data, pdev->vbandlength);
break;
case 645:
case 646:
/* TODO & FIXME */
-#endif
- return -ENXIO; /* No such device or address: missing decompressor */
+ return -ENXIO; /* Missing decompressor */
break;
}
+#endif
}
return 0;
}
diff --git a/drivers/usb/mon/Kconfig b/drivers/usb/mon/Kconfig
index 4e6152aa5f1..777642e26b9 100644
--- a/drivers/usb/mon/Kconfig
+++ b/drivers/usb/mon/Kconfig
@@ -2,13 +2,9 @@
# USB Monitor configuration
#
-# In normal life, it makes little sense to have usbmon as a module, and in fact
-# it is harmful, because there is no way to autoload the module.
-# The 'm' option is allowed for hackers who debug the usbmon itself,
-# and for those who have usbcore as a module.
config USB_MON
- tristate "USB Monitor"
- depends on USB
+ bool "USB Monitor"
+ depends on USB!=n
default y
help
If you say Y here, a component which captures the USB traffic
@@ -17,6 +13,5 @@ config USB_MON
Harding's USBMon.
This is somewhat experimental at this time, but it should be safe,
- as long as you aren't building this as a module and then removing it.
-
- If unsure, say Y. Do not say M.
+ as long as you aren't using modular USB and try to remove this
+ module.
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile
index 3cff8d444bb..f18d10ce91f 100644
--- a/drivers/usb/mon/Makefile
+++ b/drivers/usb/mon/Makefile
@@ -4,4 +4,4 @@
usbmon-objs := mon_main.o mon_stat.o mon_text.o
-obj-$(CONFIG_USB_MON) += usbmon.o
+obj-$(CONFIG_USB) += usbmon.o
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 35c1ca6b5a8..77e7fc258aa 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -847,10 +847,8 @@ retry:
wait_event_interruptible_timeout(us->delay_wait,
test_bit(US_FLIDX_DISCONNECTING, &us->flags),
delay_use * HZ);
- if (current->flags & PF_FREEZE) {
- refrigerator(PF_FREEZE);
+ if (try_to_freeze())
goto retry;
- }
}
/* If the device is still connected, perform the scanning */
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index cacd88cc84a..b6fe30c3ad6 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -111,15 +111,15 @@ static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
static struct fb_ops au1100fb_ops = {
- owner: THIS_MODULE,
- fb_get_fix: fbgen_get_fix,
- fb_get_var: fbgen_get_var,
- fb_set_var: fbgen_set_var,
- fb_get_cmap: fbgen_get_cmap,
- fb_set_cmap: fbgen_set_cmap,
- fb_pan_display: fbgen_pan_display,
- fb_ioctl: au1100fb_ioctl,
- fb_mmap: au1100fb_mmap,
+ .owner = THIS_MODULE,
+ .fb_get_fix = fbgen_get_fix,
+ .fb_get_var = fbgen_get_var,
+ .fb_set_var = fbgen_set_var,
+ .fb_get_cmap = fbgen_get_cmap,
+ .fb_set_cmap = fbgen_set_cmap,
+ .fb_pan_display = fbgen_pan_display,
+ .fb_ioctl = au1100fb_ioctl,
+ .fb_mmap = au1100fb_mmap,
};
static void au1100_detect(void)
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index e4b91a4b936..cbff98337aa 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -156,7 +156,6 @@ config FONT_6x11
config FONT_7x14
bool "console 7x14 font (not supported by all drivers)" if FONTS
depends on FRAMEBUFFER_CONSOLE
- default y if !SPARC32 && !SPARC64 && !FONTS
help
Console font with characters just a bit smaller than the default.
If the standard 8x16 font is a little too big for you, say Y.
@@ -197,8 +196,8 @@ config FONT_SUN12x22
standard font is unreadable for you, say Y, otherwise say N.
config FONT_10x18
- bool "console 10x18 font (not supported by all drivers)"
- depends on FONTS
+ bool "console 10x18 font (not supported by all drivers)" if FONTS
+ depends on FRAMEBUFFER_CONSOLE
help
This is a high resolution console font for machines with very
big letters. It fits between the sun 12x22 and the normal 8x16 font.
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 277d733c6d0..7dfbf39b4ed 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -228,8 +228,6 @@ static ssize_t store_virtual(struct class_device *class_device,
if (last - buf >= count)
return -EINVAL;
var.yres_virtual = simple_strtoul(last, &last, 0);
- printk(KERN_ERR "fb: xres %d yres %d\n", var.xres_virtual,
- var.yres_virtual);
if ((err = activate(fb_info, &var)))
return err;
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/matrox/matroxfb_misc.c
index 76fd3a519b8..a18dd024fc8 100644
--- a/drivers/video/matrox/matroxfb_misc.c
+++ b/drivers/video/matrox/matroxfb_misc.c
@@ -197,10 +197,7 @@ int matroxfb_vgaHWinit(WPMINFO struct my_timming* m) {
DBG(__FUNCTION__)
hw->SEQ[0] = 0x00;
- if (fwidth == 9)
- hw->SEQ[1] = 0x00;
- else
- hw->SEQ[1] = 0x01; /* or 0x09 */
+ hw->SEQ[1] = 0x01; /* or 0x09 */
hw->SEQ[2] = 0x0F; /* bitplanes */
hw->SEQ[3] = 0x00;
hw->SEQ[4] = 0x0E;
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 815fbc8317f..16e37a535d8 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -43,6 +43,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
+#include <asm/div64.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/bitfield.h>
#include <asm/arch/pxafb.h>
@@ -460,7 +461,7 @@ static inline unsigned int get_pcd(unsigned int pixclock)
* speeds */
pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock;
- pcd /= 100000000 * 2;
+ do_div(pcd, 100000000 * 2);
/* no need for this, since we should subtract 1 anyway. they cancel */
/* pcd += 1; */ /* make up for integer math truncations */
return (unsigned int)pcd;
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index f3069b01e24..9ed1a931dd3 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -389,10 +389,11 @@ static int __init vesafb_probe(struct device *device)
unsigned int temp_size = size_total;
/* Find the largest power-of-two */
while (temp_size & (temp_size - 1))
- temp_size &= (temp_size - 1);
-
- /* Try and find a power of two to add */
- while (temp_size && mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) {
+ temp_size &= (temp_size - 1);
+
+ /* Try and find a power of two to add */
+ while (temp_size > PAGE_SIZE &&
+ mtrr_add(vesafb_fix.smem_start, temp_size, MTRR_TYPE_WRCOMB, 1)==-EINVAL) {
temp_size >>= 1;
}
}
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index b460927ec32..312cf3220f1 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -646,7 +646,7 @@ static int w1_control(void *data)
while (!control_needs_exit || have_to_wait) {
have_to_wait = 0;
- try_to_freeze(PF_FREEZE);
+ try_to_freeze();
msleep_interruptible(w1_timeout * 1000);
if (signal_pending(current))
@@ -725,7 +725,7 @@ int w1_process(void *data)
allow_signal(SIGTERM);
while (!test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
- try_to_freeze(PF_FREEZE);
+ try_to_freeze();
msleep_interruptible(w1_timeout * 1000);
if (signal_pending(current))