summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2007-02-17 15:09:59 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-17 15:09:59 -0500
commit48c871c1f6a7c7044dd76774fb469e65c7e2e4e8 (patch)
treeda3aa535c98cc0957851354ceb0fbff7482d7a9d /drivers
parent1a1689344add3333d28d1b5495d8043a3877d01c (diff)
parent4409d28140d9a6e6e3f4f1fdaf7234c4b965d954 (diff)
Merge branch 'gfar' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc into upstream
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acorn/char/i2c.c2
-rw-r--r--drivers/ata/Kconfig41
-rw-r--r--drivers/ata/Makefile3
-rw-r--r--drivers/ata/ahci.c236
-rw-r--r--drivers/ata/ata_generic.c8
-rw-r--r--drivers/ata/ata_piix.c56
-rw-r--r--drivers/ata/libata-core.c591
-rw-r--r--drivers/ata/libata-eh.c7
-rw-r--r--drivers/ata/libata-scsi.c98
-rw-r--r--drivers/ata/libata-sff.c641
-rw-r--r--drivers/ata/libata.h4
-rw-r--r--drivers/ata/pata_ali.c32
-rw-r--r--drivers/ata/pata_amd.c36
-rw-r--r--drivers/ata/pata_artop.c12
-rw-r--r--drivers/ata/pata_atiixp.c6
-rw-r--r--drivers/ata/pata_cmd64x.c18
-rw-r--r--drivers/ata/pata_cs5520.c41
-rw-r--r--drivers/ata/pata_cs5530.c41
-rw-r--r--drivers/ata/pata_cs5535.c6
-rw-r--r--drivers/ata/pata_cypress.c6
-rw-r--r--drivers/ata/pata_efar.c6
-rw-r--r--drivers/ata/pata_hpt366.c26
-rw-r--r--drivers/ata/pata_hpt37x.c61
-rw-r--r--drivers/ata/pata_hpt3x2n.c26
-rw-r--r--drivers/ata/pata_hpt3x3.c8
-rw-r--r--drivers/ata/pata_isapnp.c21
-rw-r--r--drivers/ata/pata_it8213.c354
-rw-r--r--drivers/ata/pata_it821x.c58
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c50
-rw-r--r--drivers/ata/pata_jmicron.c8
-rw-r--r--drivers/ata/pata_legacy.c166
-rw-r--r--drivers/ata/pata_marvell.c12
-rw-r--r--drivers/ata/pata_mpc52xx.c538
-rw-r--r--drivers/ata/pata_mpiix.c113
-rw-r--r--drivers/ata/pata_netcell.c6
-rw-r--r--drivers/ata/pata_ns87410.c6
-rw-r--r--drivers/ata/pata_oldpiix.c24
-rw-r--r--drivers/ata/pata_opti.c24
-rw-r--r--drivers/ata/pata_optidma.c40
-rw-r--r--drivers/ata/pata_pcmcia.c27
-rw-r--r--drivers/ata/pata_pdc2027x.c122
-rw-r--r--drivers/ata/pata_pdc202xx_old.c41
-rw-r--r--drivers/ata/pata_platform.c67
-rw-r--r--drivers/ata/pata_qdi.c50
-rw-r--r--drivers/ata/pata_radisys.c6
-rw-r--r--drivers/ata/pata_rz1000.c6
-rw-r--r--drivers/ata/pata_sc1200.c6
-rw-r--r--drivers/ata/pata_serverworks.c31
-rw-r--r--drivers/ata/pata_sil680.c8
-rw-r--r--drivers/ata/pata_sis.c70
-rw-r--r--drivers/ata/pata_sl82c105.c10
-rw-r--r--drivers/ata/pata_triflex.c6
-rw-r--r--drivers/ata/pata_via.c22
-rw-r--r--drivers/ata/pata_winbond.c49
-rw-r--r--drivers/ata/pdc_adma.c120
-rw-r--r--drivers/ata/sata_inic162x.c781
-rw-r--r--drivers/ata/sata_mv.c200
-rw-r--r--drivers/ata/sata_nv.c629
-rw-r--r--drivers/ata/sata_promise.c379
-rw-r--r--drivers/ata/sata_qstor.c138
-rw-r--r--drivers/ata/sata_sil.c99
-rw-r--r--drivers/ata/sata_sil24.c178
-rw-r--r--drivers/ata/sata_sis.c161
-rw-r--r--drivers/ata/sata_svw.c127
-rw-r--r--drivers/ata/sata_sx4.c207
-rw-r--r--drivers/ata/sata_uli.c66
-rw-r--r--drivers/ata/sata_via.c193
-rw-r--r--drivers/ata/sata_vsc.c134
-rw-r--r--drivers/atm/eni.c1
-rw-r--r--drivers/auxdisplay/Kconfig109
-rw-r--r--drivers/auxdisplay/Makefile6
-rw-r--r--drivers/auxdisplay/cfag12864b.c383
-rw-r--r--drivers/auxdisplay/cfag12864bfb.c180
-rw-r--r--drivers/auxdisplay/ks0108.c166
-rw-r--r--drivers/base/Kconfig12
-rw-r--r--drivers/base/Makefile1
-rw-r--r--drivers/base/base.h1
-rw-r--r--drivers/base/core.c2
-rw-r--r--drivers/base/dd.c3
-rw-r--r--drivers/base/devres.c644
-rw-r--r--drivers/base/dma-mapping.c218
-rw-r--r--drivers/base/dmapool.c59
-rw-r--r--drivers/base/node.c9
-rw-r--r--drivers/block/DAC960.c101
-rw-r--r--drivers/block/DAC960.h495
-rw-r--r--drivers/block/Kconfig4
-rw-r--r--drivers/block/acsi_slm.c2
-rw-r--r--drivers/block/aoe/aoechr.c2
-rw-r--r--drivers/block/paride/Kconfig8
-rw-r--r--drivers/block/paride/pg.c2
-rw-r--r--drivers/block/paride/pt.c2
-rw-r--r--drivers/block/pktcdvd.c32
-rw-r--r--drivers/bluetooth/hci_vhci.c2
-rw-r--r--drivers/cdrom/viocd.c2
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/amiserial.c8
-rw-r--r--drivers/char/briq_panel.c2
-rw-r--r--drivers/char/cyclades.c24
-rw-r--r--drivers/char/drm/drm_drv.c2
-rw-r--r--drivers/char/drm/i810_dma.c2
-rw-r--r--drivers/char/drm/i830_dma.c2
-rw-r--r--drivers/char/drm/via_dmablit.c14
-rw-r--r--drivers/char/ds1302.c2
-rw-r--r--drivers/char/dtlk.c8
-rw-r--r--drivers/char/epca.c3
-rw-r--r--drivers/char/generic_nvram.c2
-rw-r--r--drivers/char/generic_serial.c1
-rw-r--r--drivers/char/hw_random/intel-rng.c76
-rw-r--r--drivers/char/ip2/i2lib.c40
-rw-r--r--drivers/char/ip2/ip2main.c4
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c30
-rw-r--r--drivers/char/isicom.c108
-rw-r--r--drivers/char/istallion.c1
-rw-r--r--drivers/char/keyboard.c12
-rw-r--r--drivers/char/mbcs.c2
-rw-r--r--drivers/char/moxa.c927
-rw-r--r--drivers/char/mspec.c6
-rw-r--r--drivers/char/mxser.c11
-rw-r--r--drivers/char/mxser.h8
-rw-r--r--drivers/char/mxser_new.c236
-rw-r--r--drivers/char/mxser_new.h477
-rw-r--r--drivers/char/n_r3964.c2095
-rw-r--r--drivers/char/n_tty.c14
-rw-r--r--drivers/char/nwbutton.c13
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c10
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c3
-rw-r--r--drivers/char/pcmcia/synclink_cs.c14
-rw-r--r--drivers/char/random.c4
-rw-r--r--drivers/char/raw.c2
-rw-r--r--drivers/char/rio/rio_linux.c12
-rw-r--r--drivers/char/rio/riointr.c9
-rw-r--r--drivers/char/riscom8.c5
-rw-r--r--drivers/char/rocket.c13
-rw-r--r--drivers/char/rtc.c12
-rw-r--r--drivers/char/scan_keyb.c149
-rw-r--r--drivers/char/scan_keyb.h15
-rw-r--r--drivers/char/serial167.c3322
-rw-r--r--drivers/char/specialix.c18
-rw-r--r--drivers/char/synclink.c15
-rw-r--r--drivers/char/synclink_gt.c24
-rw-r--r--drivers/char/synclinkmp.c27
-rw-r--r--drivers/char/sysrq.c6
-rw-r--r--drivers/char/toshiba.c35
-rw-r--r--drivers/char/tpm/tpm.c5
-rw-r--r--drivers/char/tpm/tpm_bios.c4
-rw-r--r--drivers/char/tty_io.c246
-rw-r--r--drivers/char/tty_ioctl.c45
-rw-r--r--drivers/char/viotape.c2
-rw-r--r--drivers/char/vt.c11
-rw-r--r--drivers/char/vt_ioctl.c28
-rw-r--r--drivers/char/watchdog/alim7101_wdt.c6
-rw-r--r--drivers/char/watchdog/iTCO_wdt.c2
-rw-r--r--drivers/char/watchdog/omap_wdt.c2
-rw-r--r--drivers/char/watchdog/pc87413_wdt.c2
-rw-r--r--drivers/char/watchdog/pnx4008_wdt.c2
-rw-r--r--drivers/char/watchdog/rm9k_wdt.c2
-rw-r--r--drivers/char/watchdog/smsc37b787_wdt.c2
-rw-r--r--drivers/char/watchdog/w83697hf_wdt.c2
-rw-r--r--drivers/edac/e752x_edac.c40
-rw-r--r--drivers/edac/edac_mc.c175
-rw-r--r--drivers/edac/edac_mc.h28
-rw-r--r--drivers/firmware/edd.c8
-rw-r--r--drivers/i2c/chips/tps65010.c2
-rw-r--r--drivers/i2c/i2c-dev.c2
-rw-r--r--drivers/ide/ide-proc.c3
-rw-r--r--drivers/ide/ide-tape.c2
-rw-r--r--drivers/ieee1394/dv1394.c2
-rw-r--r--drivers/ieee1394/raw1394.c2
-rw-r--r--drivers/ieee1394/video1394.c2
-rw-r--r--drivers/infiniband/core/ucm.c2
-rw-r--r--drivers/infiniband/core/ucma.c2
-rw-r--r--drivers/infiniband/core/user_mad.c4
-rw-r--r--drivers/infiniband/core/uverbs_main.c6
-rw-r--r--drivers/infiniband/hw/ehca/ehca_cq.c3
-rw-r--r--drivers/infiniband/hw/ehca/ehca_mrmw.c6
-rw-r--r--drivers/infiniband/hw/ehca/ehca_pd.c3
-rw-r--r--drivers/infiniband/hw/ehca/ehca_qp.c3
-rw-r--r--drivers/infiniband/hw/ipath/ipath_diag.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c6
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c14
-rw-r--r--drivers/infiniband/hw/ipath/ipath_kernel.h2
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_fs.c4
-rw-r--r--drivers/input/gameport/ns558.c1
-rw-r--r--drivers/input/input.c6
-rw-r--r--drivers/input/keyboard/Kconfig19
-rw-r--r--drivers/input/keyboard/Makefile5
-rw-r--r--drivers/input/keyboard/gpio_keys.c147
-rw-r--r--drivers/input/keyboard/hilkbd.c114
-rw-r--r--drivers/input/misc/Kconfig10
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/atlas_btns.c170
-rw-r--r--drivers/input/misc/hp_sdc_rtc.c2
-rw-r--r--drivers/input/misc/uinput.c2
-rw-r--r--drivers/input/misc/wistron_btns.c20
-rw-r--r--drivers/input/mouse/inport.c2
-rw-r--r--drivers/input/mouse/pc110pad.c2
-rw-r--r--drivers/input/serio/i8042.c12
-rw-r--r--drivers/input/serio/serio_raw.c2
-rw-r--r--drivers/input/touchscreen/Kconfig9
-rw-r--r--drivers/input/touchscreen/ads7846.c581
-rw-r--r--drivers/input/tsdev.c4
-rw-r--r--drivers/isdn/capi/capi.c41
-rw-r--r--drivers/isdn/capi/capidrv.c4
-rw-r--r--drivers/isdn/capi/kcapi_proc.c10
-rw-r--r--drivers/isdn/divert/divert_procfs.c2
-rw-r--r--drivers/isdn/gigaset/Kconfig25
-rw-r--r--drivers/isdn/gigaset/Makefile2
-rw-r--r--drivers/isdn/gigaset/asyncdata.c5
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c4
-rw-r--r--drivers/isdn/gigaset/common.c24
-rw-r--r--drivers/isdn/gigaset/ev-layer.c2
-rw-r--r--drivers/isdn/gigaset/interface.c17
-rw-r--r--drivers/isdn/gigaset/isocdata.c4
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c837
-rw-r--r--drivers/isdn/hardware/avm/b1dma.c14
-rw-r--r--drivers/isdn/hardware/avm/c4.c16
-rw-r--r--drivers/isdn/hardware/eicon/capifunc.c4
-rw-r--r--drivers/isdn/hardware/eicon/debug.c30
-rw-r--r--drivers/isdn/hardware/eicon/di.c16
-rw-r--r--drivers/isdn/hardware/eicon/divamnt.c2
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c2
-rw-r--r--drivers/isdn/hardware/eicon/divasmain.c2
-rw-r--r--drivers/isdn/hardware/eicon/divasproc.c2
-rw-r--r--drivers/isdn/hardware/eicon/message.c383
-rw-r--r--drivers/isdn/hardware/eicon/os_pri.c4
-rw-r--r--drivers/isdn/hardware/eicon/platform.h12
-rw-r--r--drivers/isdn/hisax/Kconfig2
-rw-r--r--drivers/isdn/hisax/Makefile1
-rw-r--r--drivers/isdn/hisax/config.c11
-rw-r--r--drivers/isdn/hisax/elsa_ser.c8
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c48
-rw-r--r--drivers/isdn/hisax/hfc_usb.c40
-rw-r--r--drivers/isdn/hisax/hfc_usb.h3
-rw-r--r--drivers/isdn/hisax/hisax.h25
-rw-r--r--drivers/isdn/hisax/isar.c1
-rw-r--r--drivers/isdn/hisax/isdnl1.h17
-rw-r--r--drivers/isdn/hisax/isdnl3.c12
-rw-r--r--drivers/isdn/hisax/isdnl3.h26
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c2
-rw-r--r--drivers/isdn/i4l/isdn_common.c2
-rw-r--r--drivers/isdn/i4l/isdn_tty.c1
-rw-r--r--drivers/isdn/pcbit/drv.c4
-rw-r--r--drivers/isdn/pcbit/edss1.c6
-rw-r--r--drivers/isdn/pcbit/edss1.h7
-rw-r--r--drivers/isdn/pcbit/layer2.c16
-rw-r--r--drivers/isdn/pcbit/module.c3
-rw-r--r--drivers/isdn/pcbit/pcbit.h8
-rw-r--r--drivers/isdn/sc/card.h30
-rw-r--r--drivers/isdn/sc/command.c17
-rw-r--r--drivers/isdn/sc/event.c3
-rw-r--r--drivers/isdn/sc/init.c6
-rw-r--r--drivers/isdn/sc/interrupt.c10
-rw-r--r--drivers/isdn/sc/ioctl.c10
-rw-r--r--drivers/isdn/sc/message.c10
-rw-r--r--drivers/isdn/sc/packet.c10
-rw-r--r--drivers/isdn/sc/scioc.h6
-rw-r--r--drivers/isdn/sc/shmem.c6
-rw-r--r--drivers/isdn/sc/timer.c8
-rw-r--r--drivers/kvm/kvm.h4
-rw-r--r--drivers/kvm/kvm_main.c123
-rw-r--r--drivers/kvm/paging_tmpl.h28
-rw-r--r--drivers/kvm/svm.c15
-rw-r--r--drivers/kvm/vmx.c43
-rw-r--r--drivers/kvm/vmx.h1
-rw-r--r--drivers/macintosh/adb.c2
-rw-r--r--drivers/macintosh/ans-lcd.c2
-rw-r--r--drivers/macintosh/apm_emu.c2
-rw-r--r--drivers/macintosh/nvram.c2
-rw-r--r--drivers/macintosh/smu.c2
-rw-r--r--drivers/macintosh/via-pmu.c3
-rw-r--r--drivers/macintosh/via-pmu68k.c2
-rw-r--r--drivers/md/bitmap.c2
-rw-r--r--drivers/md/dm-ioctl.c2
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/media/common/saa7146_fops.c2
-rw-r--r--drivers/media/radio/dsbr100.c2
-rw-r--r--drivers/media/radio/miropcm20-radio.c2
-rw-r--r--drivers/media/radio/miropcm20-rds.c2
-rw-r--r--drivers/media/radio/radio-aimslab.c2
-rw-r--r--drivers/media/radio/radio-aztech.c2
-rw-r--r--drivers/media/radio/radio-cadet.c2
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c2
-rw-r--r--drivers/media/radio/radio-gemtek.c2
-rw-r--r--drivers/media/radio/radio-maestro.c2
-rw-r--r--drivers/media/radio/radio-maxiradio.c2
-rw-r--r--drivers/media/radio/radio-rtrack2.c2
-rw-r--r--drivers/media/radio/radio-sf16fmi.c2
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c2
-rw-r--r--drivers/media/radio/radio-terratec.c2
-rw-r--r--drivers/media/radio/radio-trust.c2
-rw-r--r--drivers/media/radio/radio-typhoon.c2
-rw-r--r--drivers/media/radio/radio-zoltrix.c2
-rw-r--r--drivers/media/video/arv.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c4
-rw-r--r--drivers/media/video/bw-qcam.c2
-rw-r--r--drivers/media/video/c-qcam.c2
-rw-r--r--drivers/media/video/cafe_ccic.c6
-rw-r--r--drivers/media/video/cpia.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c2
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c2
-rw-r--r--drivers/media/video/cx88/cx88-video.c4
-rw-r--r--drivers/media/video/dabusb.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c2
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c2
-rw-r--r--drivers/media/video/meye.c2
-rw-r--r--drivers/media/video/ov511.c2
-rw-r--r--drivers/media/video/pms.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c2
-rw-r--r--drivers/media/video/pwc/pwc-if.c2
-rw-r--r--drivers/media/video/saa5246a.c2
-rw-r--r--drivers/media/video/saa5249.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-oss.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c4
-rw-r--r--drivers/media/video/saa7134/saa7134.h4
-rw-r--r--drivers/media/video/se401.c2
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c2
-rw-r--r--drivers/media/video/stradis.c2
-rw-r--r--drivers/media/video/stv680.c2
-rw-r--r--drivers/media/video/tvmixer.c2
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c2
-rw-r--r--drivers/media/video/usbvideo/vicam.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c6
-rw-r--r--drivers/media/video/videodev.c4
-rw-r--r--drivers/media/video/vino.c2
-rw-r--r--drivers/media/video/vivi.c2
-rw-r--r--drivers/media/video/w9966.c2
-rw-r--r--drivers/media/video/w9968cf.c4
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c2
-rw-r--r--drivers/media/video/zoran_driver.c3
-rw-r--r--drivers/media/video/zoran_procfs.c2
-rw-r--r--drivers/message/fusion/Kconfig2
-rw-r--r--drivers/message/fusion/Makefile7
-rw-r--r--drivers/message/fusion/lsi/mpi.h7
-rw-r--r--drivers/message/fusion/lsi/mpi_cnfg.h131
-rw-r--r--drivers/message/fusion/lsi/mpi_history.txt77
-rw-r--r--drivers/message/fusion/lsi/mpi_init.h7
-rw-r--r--drivers/message/fusion/lsi/mpi_ioc.h75
-rw-r--r--drivers/message/fusion/lsi/mpi_log_sas.h284
-rw-r--r--drivers/message/fusion/lsi/mpi_sas.h9
-rw-r--r--drivers/message/fusion/mptbase.c875
-rw-r--r--drivers/message/fusion/mptbase.h47
-rw-r--r--drivers/message/fusion/mptctl.c165
-rw-r--r--drivers/message/fusion/mptctl.h2
-rw-r--r--drivers/message/fusion/mptfc.c53
-rw-r--r--drivers/message/fusion/mptlan.c1
-rw-r--r--drivers/message/fusion/mptlan.h1
-rw-r--r--drivers/message/fusion/mptsas.c718
-rw-r--r--drivers/message/fusion/mptscsih.c997
-rw-r--r--drivers/message/fusion/mptscsih.h44
-rw-r--r--drivers/message/fusion/mptspi.c527
-rw-r--r--drivers/message/i2o/i2o_config.c2
-rw-r--r--drivers/message/i2o/i2o_proc.c38
-rw-r--r--drivers/misc/hdpuftrs/hdpu_cpustate.c2
-rw-r--r--drivers/misc/hdpuftrs/hdpu_nexus.c2
-rw-r--r--drivers/misc/ibmasm/ibmasmfs.c10
-rw-r--r--drivers/misc/ioc4.c6
-rw-r--r--drivers/mmc/sdhci.c40
-rw-r--r--drivers/mmc/tifm_sd.c11
-rw-r--r--drivers/mmc/wbsd.c6
-rw-r--r--drivers/mtd/devices/block2mtd.c3
-rw-r--r--drivers/mtd/mtdchar.c2
-rw-r--r--drivers/net/arcnet/com20020.c3
-rw-r--r--drivers/net/bonding/bond_main.c2
-rw-r--r--drivers/net/gianfar_sysfs.c108
-rw-r--r--drivers/net/hamradio/bpqether.c2
-rw-r--r--drivers/net/hamradio/scc.c2
-rw-r--r--drivers/net/hamradio/yam.c2
-rw-r--r--drivers/net/ibmveth.c2
-rw-r--r--drivers/net/irda/vlsi_ir.c2
-rw-r--r--drivers/net/ppp_generic.c4
-rw-r--r--drivers/net/pppoe.c2
-rw-r--r--drivers/net/tun.c2
-rw-r--r--drivers/net/wan/cosa.c2
-rw-r--r--drivers/net/wireless/airo.c16
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c12
-rw-r--r--drivers/net/wireless/strip.c2
-rw-r--r--drivers/oprofile/event_buffer.c2
-rw-r--r--drivers/oprofile/event_buffer.h2
-rw-r--r--drivers/oprofile/oprofile_files.c10
-rw-r--r--drivers/oprofile/oprofilefs.c6
-rw-r--r--drivers/parisc/ccio-dma.c4
-rw-r--r--drivers/parisc/eisa_eeprom.c2
-rw-r--r--drivers/parisc/led.c2
-rw-r--r--drivers/parisc/sba_iommu.c4
-rw-r--r--drivers/pci/Kconfig2
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c2
-rw-r--r--drivers/pci/pci.c127
-rw-r--r--drivers/pci/proc.c4
-rw-r--r--drivers/pci/quirks.c2
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c2
-rw-r--r--drivers/pnp/base.h1
-rw-r--r--drivers/pnp/isapnp/proc.c2
-rw-r--r--drivers/pnp/pnpbios/rsparser.c1
-rw-r--r--drivers/ps3/Makefile1
-rw-r--r--drivers/ps3/ps3av.c974
-rw-r--r--drivers/ps3/ps3av_cmd.c1020
-rw-r--r--drivers/ps3/vuart.c17
-rw-r--r--drivers/ps3/vuart.h1
-rw-r--r--drivers/rapidio/rio-scan.c118
-rw-r--r--drivers/rtc/Kconfig25
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-cmos.c725
-rw-r--r--drivers/rtc/rtc-dev.c2
-rw-r--r--drivers/rtc/rtc-ds1553.c2
-rw-r--r--drivers/rtc/rtc-ds1742.c2
-rw-r--r--drivers/rtc/rtc-proc.c2
-rw-r--r--drivers/rtc/rtc-sysfs.c103
-rw-r--r--drivers/s390/block/dasd_eer.c2
-rw-r--r--drivers/s390/block/dasd_proc.c2
-rw-r--r--drivers/s390/char/fs3270.c2
-rw-r--r--drivers/s390/char/monreader.c2
-rw-r--r--drivers/s390/char/monwriter.c2
-rw-r--r--drivers/s390/char/tape_char.c2
-rw-r--r--drivers/s390/char/tape_class.c2
-rw-r--r--drivers/s390/char/tape_class.h2
-rw-r--r--drivers/s390/char/tape_proc.c2
-rw-r--r--drivers/s390/char/vmcp.c2
-rw-r--r--drivers/s390/char/vmlogrdr.c2
-rw-r--r--drivers/s390/char/vmwatchdog.c2
-rw-r--r--drivers/s390/cio/blacklist.c2
-rw-r--r--drivers/s390/cio/device_id.c3
-rw-r--r--drivers/s390/cio/device_ops.c32
-rw-r--r--drivers/s390/cio/qdio.c2
-rw-r--r--drivers/s390/crypto/zcrypt_api.c3
-rw-r--r--drivers/s390/net/lcs.c6
-rw-r--r--drivers/s390/net/qeth_proc.c4
-rw-r--r--drivers/s390/scsi/zfcp_aux.c2
-rw-r--r--drivers/s390/scsi/zfcp_erp.c22
-rw-r--r--drivers/s390/scsi/zfcp_ext.h2
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c23
-rw-r--r--drivers/sbus/char/bpp.c2
-rw-r--r--drivers/sbus/char/cpwatchdog.c2
-rw-r--r--drivers/sbus/char/display7seg.c2
-rw-r--r--drivers/sbus/char/envctrl.c2
-rw-r--r--drivers/sbus/char/flash.c2
-rw-r--r--drivers/sbus/char/jsflash.c2
-rw-r--r--drivers/sbus/char/openprom.c2
-rw-r--r--drivers/sbus/char/riowatchdog.c2
-rw-r--r--drivers/sbus/char/rtc.c2
-rw-r--r--drivers/sbus/char/uctrl.c2
-rw-r--r--drivers/sbus/char/vfc_dev.c4
-rw-r--r--drivers/sbus/sbus.c18
-rw-r--r--drivers/scsi/3w-9xxx.c2
-rw-r--r--drivers/scsi/3w-xxxx.c2
-rw-r--r--drivers/scsi/53c700.c24
-rw-r--r--drivers/scsi/53c700.h2
-rw-r--r--drivers/scsi/53c7xx.c5
-rw-r--r--drivers/scsi/BusLogic.c46
-rw-r--r--drivers/scsi/BusLogic.h300
-rw-r--r--drivers/scsi/FlashPoint.c4
-rw-r--r--drivers/scsi/Kconfig9
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/NCR_D700.c1
-rw-r--r--drivers/scsi/aacraid/Makefile2
-rw-r--r--drivers/scsi/aacraid/aachba.c602
-rw-r--r--drivers/scsi/aacraid/aacraid.h46
-rw-r--r--drivers/scsi/aacraid/comminit.c14
-rw-r--r--drivers/scsi/aacraid/commsup.c40
-rw-r--r--drivers/scsi/aacraid/linit.c19
-rw-r--r--drivers/scsi/aacraid/nark.c87
-rw-r--r--drivers/scsi/aacraid/rkt.c64
-rw-r--r--drivers/scsi/aacraid/rx.c263
-rw-r--r--drivers/scsi/aacraid/sa.c33
-rw-r--r--drivers/scsi/advansys.c7
-rw-r--r--drivers/scsi/aic7xxx/aic79xx.h3
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c5
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c9
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h2
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm_pci.c19
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.c2
-rw-r--r--drivers/scsi/aic94xx/aic94xx_dev.c16
-rw-r--r--drivers/scsi/aic94xx/aic94xx_dump.c2
-rw-r--r--drivers/scsi/aic94xx/aic94xx_hwi.c3
-rw-r--r--drivers/scsi/aic94xx/aic94xx_init.c49
-rw-r--r--drivers/scsi/aic94xx/aic94xx_reg_def.h5
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sas.h1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_scb.c122
-rw-r--r--drivers/scsi/aic94xx/aic94xx_sds.c10
-rw-r--r--drivers/scsi/aic94xx/aic94xx_seq.c45
-rw-r--r--drivers/scsi/aic94xx/aic94xx_seq.h1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_task.c9
-rw-r--r--drivers/scsi/aic94xx/aic94xx_tmf.c4
-rw-r--r--drivers/scsi/ch.c2
-rw-r--r--drivers/scsi/dpt_i2o.c2
-rw-r--r--drivers/scsi/gdth.c2
-rw-r--r--drivers/scsi/ipr.c91
-rw-r--r--drivers/scsi/ipr.h4
-rw-r--r--drivers/scsi/lasi700.c1
-rw-r--r--drivers/scsi/libsas/sas_discover.c62
-rw-r--r--drivers/scsi/libsas/sas_event.c6
-rw-r--r--drivers/scsi/libsas/sas_expander.c48
-rw-r--r--drivers/scsi/libsas/sas_init.c52
-rw-r--r--drivers/scsi/libsas/sas_internal.h9
-rw-r--r--drivers/scsi/libsas/sas_port.c14
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c290
-rw-r--r--drivers/scsi/megaraid.c2
-rw-r--r--drivers/scsi/megaraid/mbox_defs.h2
-rw-r--r--drivers/scsi/megaraid/mega_common.h122
-rw-r--r--drivers/scsi/megaraid/megaraid_ioctl.h36
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c421
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.h46
-rw-r--r--drivers/scsi/megaraid/megaraid_mm.c67
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c2
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h14
-rw-r--r--drivers/scsi/osst.c2
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h66
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c68
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h38
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c218
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c245
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c18
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c24
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c348
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
-rw-r--r--drivers/scsi/scsi.c21
-rw-r--r--drivers/scsi/scsi_debug.c42
-rw-r--r--drivers/scsi/scsi_error.c256
-rw-r--r--drivers/scsi/scsi_lib.c7
-rw-r--r--drivers/scsi/scsi_priv.h6
-rw-r--r--drivers/scsi/scsi_proc.c2
-rw-r--r--drivers/scsi/scsi_scan.c2
-rw-r--r--drivers/scsi/scsi_tgt_if.c2
-rw-r--r--drivers/scsi/scsi_transport_sas.c118
-rw-r--r--drivers/scsi/scsi_transport_spi.c1
-rw-r--r--drivers/scsi/sim710.c1
-rw-r--r--drivers/scsi/sni_53c710.c159
-rw-r--r--drivers/scsi/st.c25
-rw-r--r--drivers/scsi/st.h3
-rw-r--r--drivers/serial/8250.c8
-rw-r--r--drivers/serial/8250_pci.c27
-rw-r--r--drivers/serial/Kconfig5
-rw-r--r--drivers/serial/atmel_serial.c54
-rw-r--r--drivers/serial/crisv10.c14
-rw-r--r--drivers/serial/ioc4_serial.c6
-rw-r--r--drivers/serial/serial_txx9.c23
-rw-r--r--drivers/sn/ioc3.c6
-rw-r--r--drivers/spi/Kconfig38
-rw-r--r--drivers/spi/Makefile3
-rw-r--r--drivers/spi/at25.c381
-rw-r--r--drivers/spi/omap_uwire.c572
-rw-r--r--drivers/spi/pxa2xx_spi.c4
-rw-r--r--drivers/spi/spi.c2
-rw-r--r--drivers/spi/spi_bitbang.c11
-rw-r--r--drivers/spi/spi_imx.c1769
-rw-r--r--drivers/tc/zs.c4
-rw-r--r--drivers/telephony/ixj.c41
-rw-r--r--drivers/telephony/ixj.h4
-rw-r--r--drivers/telephony/phonedev.c2
-rw-r--r--drivers/usb/gadget/file_storage.c2
-rw-r--r--drivers/usb/gadget/rndis.c1
-rw-r--r--drivers/usb/host/hc_crisv10.c3
-rw-r--r--drivers/usb/host/uhci-q.c4
-rw-r--r--drivers/usb/input/hid-ff.c1
-rw-r--r--drivers/usb/input/hid-lgff.c1
-rw-r--r--drivers/usb/misc/adutux.c2
-rw-r--r--drivers/usb/misc/appledisplay.c4
-rw-r--r--drivers/usb/misc/ftdi-elan.c2
-rw-r--r--drivers/usb/serial/digi_acceleport.c10
-rw-r--r--drivers/usb/serial/keyspan_pda.c7
-rw-r--r--drivers/usb/serial/mos7720.c14
-rw-r--r--drivers/usb/serial/mos7840.c14
-rw-r--r--drivers/video/Kconfig89
-rw-r--r--drivers/video/Makefile8
-rw-r--r--drivers/video/S3triofb.c790
-rw-r--r--drivers/video/aty/atyfb_base.c4
-rw-r--r--drivers/video/au1100fb.c6
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/console/fbcon.h2
-rw-r--r--drivers/video/controlfb.c3
-rw-r--r--drivers/video/cyber2000fb.c19
-rw-r--r--drivers/video/cyberfb.c2295
-rw-r--r--drivers/video/cyberfb.h415
-rw-r--r--drivers/video/fbsysfs.c2
-rw-r--r--drivers/video/geode/gx1fb_core.c29
-rw-r--r--drivers/video/i810/i810.h3
-rw-r--r--drivers/video/i810/i810_main.c32
-rw-r--r--drivers/video/igafb.c8
-rw-r--r--drivers/video/intelfb/intelfbdrv.c3
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c4
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c3
-rw-r--r--drivers/video/mbx/mbxdebugfs.c12
-rw-r--r--drivers/video/modedb.c47
-rw-r--r--drivers/video/neofb.c22
-rw-r--r--drivers/video/nvidia/nvidia.c16
-rw-r--r--drivers/video/pm3fb.c29
-rw-r--r--drivers/video/ps3fb.c1229
-rw-r--r--drivers/video/retz3fb.c1588
-rw-r--r--drivers/video/retz3fb.h286
-rw-r--r--drivers/video/riva/fbdev.c27
-rw-r--r--drivers/video/riva/rivafb.h3
-rw-r--r--drivers/video/s3fb.c1180
-rw-r--r--drivers/video/sa1100fb.h4
-rw-r--r--drivers/video/savage/savagefb_driver.c12
-rw-r--r--drivers/video/sis/init.c140
-rw-r--r--drivers/video/sis/init.h36
-rw-r--r--drivers/video/sis/init301.c260
-rw-r--r--drivers/video/sis/init301.h14
-rw-r--r--drivers/video/sis/initextlfb.c18
-rw-r--r--drivers/video/sis/sis.h2
-rw-r--r--drivers/video/sis/sis_main.c214
-rw-r--r--drivers/video/sis/sis_main.h112
-rw-r--r--drivers/video/sis/vgatypes.h12
-rw-r--r--drivers/video/sis/vstruct.h44
-rw-r--r--drivers/video/sun3fb.c702
-rw-r--r--drivers/video/svgalib.c632
-rw-r--r--drivers/video/tgafb.c185
-rw-r--r--drivers/video/vga16fb.c23
-rw-r--r--drivers/video/virgefb.c2526
-rw-r--r--drivers/video/virgefb.h288
-rw-r--r--drivers/w1/slaves/w1_therm.c6
-rw-r--r--drivers/zorro/proc.c2
616 files changed, 28479 insertions, 22089 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index e7da9fa724ec..050323fd79e9 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -80,6 +80,8 @@ source "drivers/rtc/Kconfig"
source "drivers/dma/Kconfig"
+source "drivers/auxdisplay/Kconfig"
+
source "drivers/kvm/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index f28dcb4ec8b3..3a718f51350e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_ATA) += ata/
obj-$(CONFIG_FUSION) += message/
obj-$(CONFIG_IEEE1394) += ieee1394/
obj-y += cdrom/
+obj-y += auxdisplay/
obj-$(CONFIG_MTD) += mtd/
obj-$(CONFIG_SPI) += spi/
obj-$(CONFIG_PCCARD) += pcmcia/
diff --git a/drivers/acorn/char/i2c.c b/drivers/acorn/char/i2c.c
index 9e584a7af434..157d8b73bb64 100644
--- a/drivers/acorn/char/i2c.c
+++ b/drivers/acorn/char/i2c.c
@@ -238,7 +238,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
}
-static struct file_operations rtc_fops = {
+static const struct file_operations rtc_fops = {
.ioctl = rtc_ioctl,
};
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 1c94b43d2c9b..3747457fee7a 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -41,12 +41,12 @@ config SATA_SVW
If unsure, say N.
config ATA_PIIX
- tristate "Intel PIIX/ICH SATA support"
+ tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support"
depends on PCI
help
This option enables support for ICH5/6/7/8 Serial ATA
- and support for PATA on the Intel PIIX3/PIIX4/ICH series
- PATA host controllers.
+ and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series
+ host controllers.
If unsure, say N.
@@ -116,11 +116,14 @@ config SATA_SIL24
If unsure, say N.
config SATA_SIS
- tristate "SiS 964/180 SATA support"
+ tristate "SiS 964/965/966/180 SATA support"
depends on PCI
+ select PATA_SIS
help
- This option enables support for SiS Serial ATA 964/180.
-
+ This option enables support for SiS Serial ATA on
+ SiS 964/965/966/180 and Parallel ATA on SiS 180.
+ The PATA support for SiS 180 requires additionally to
+ enable the PATA_SIS driver in the config.
If unsure, say N.
config SATA_ULI
@@ -147,6 +150,12 @@ config SATA_VITESSE
If unsure, say N.
+config SATA_INIC162X
+ tristate "Initio 162x SATA support (HIGHLY EXPERIMENTAL)"
+ depends on PCI && EXPERIMENTAL
+ help
+ This option enables support for Initio 162x Serial ATA.
+
config SATA_INTEL_COMBINED
bool
depends on IDE=y && !BLK_DEV_IDE_SATA && (SATA_AHCI || ATA_PIIX)
@@ -296,7 +305,7 @@ config PATA_ISAPNP
If unsure, say N.
config PATA_IT821X
- tristate "IT821x PATA support (Experimental)"
+ tristate "IT8211/2 PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
help
This option enables support for the ITE 8211 and 8212
@@ -305,6 +314,15 @@ config PATA_IT821X
If unsure, say N.
+config PATA_IT8213
+ tristate "IT8213 PATA support (Experimental)"
+ depends on PCI && EXPERIMENTAL
+ help
+ This option enables support for the ITE 821 PATA
+ controllers via the new ATA layer.
+
+ If unsure, say N.
+
config PATA_JMICRON
tristate "JMicron PATA support"
depends on PCI
@@ -341,6 +359,15 @@ config PATA_MARVELL
If unsure, say N.
+config PATA_MPC52xx
+ tristate "Freescale MPC52xx SoC internal IDE"
+ depends on PPC_MPC52xx
+ help
+ This option enables support for integrated IDE controller
+ of the Freescale MPC52xx SoC.
+
+ If unsure, say N.
+
config PATA_MPIIX
tristate "Intel PATA MPIIX support"
depends on PCI
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index bc3d81ae757e..cd096f0c78a1 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_SATA_SX4) += sata_sx4.o
obj-$(CONFIG_SATA_NV) += sata_nv.o
obj-$(CONFIG_SATA_ULI) += sata_uli.o
obj-$(CONFIG_SATA_MV) += sata_mv.o
+obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
obj-$(CONFIG_PATA_ALI) += pata_ali.o
@@ -33,11 +34,13 @@ obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o
obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o
obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o
obj-$(CONFIG_PATA_IT821X) += pata_it821x.o
+obj-$(CONFIG_PATA_IT8213) += pata_it8213.o
obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o
obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
obj-$(CONFIG_PATA_OPTI) += pata_opti.o
obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
+obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index e2796fb40eb7..92cdb0c5171f 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -45,7 +45,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "ahci"
#define DRV_VERSION "2.0"
@@ -166,9 +165,6 @@ enum {
PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
- /* hpriv->flags bits */
- AHCI_FLAG_MSI = (1 << 0),
-
/* ap->flags bits */
AHCI_FLAG_NO_NCQ = (1 << 24),
AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
@@ -191,7 +187,6 @@ struct ahci_sg {
};
struct ahci_host_priv {
- unsigned long flags;
u32 cap; /* cache of HOST_CAP register */
u32 port_map; /* cache of HOST_PORTS_IMPL reg */
};
@@ -229,7 +224,6 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
static int ahci_port_resume(struct ata_port *ap);
static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int ahci_pci_device_resume(struct pci_dev *pdev);
-static void ahci_remove_one (struct pci_dev *pdev);
static struct scsi_host_template ahci_sht = {
.module = THIS_MODULE,
@@ -266,6 +260,8 @@ static const struct ata_port_operations ahci_ops = {
.irq_handler = ahci_interrupt,
.irq_clear = ahci_irq_clear,
+ .irq_on = ata_dummy_irq_on,
+ .irq_ack = ata_dummy_irq_ack,
.scr_read = ahci_scr_read,
.scr_write = ahci_scr_write,
@@ -297,6 +293,8 @@ static const struct ata_port_operations ahci_vt8251_ops = {
.irq_handler = ahci_interrupt,
.irq_clear = ahci_irq_clear,
+ .irq_on = ata_dummy_irq_on,
+ .irq_ack = ata_dummy_irq_ack,
.scr_read = ahci_scr_read,
.scr_write = ahci_scr_write,
@@ -431,7 +429,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
/* Generic, PCI class code for AHCI */
{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
- 0x010601, 0xffffff, board_ahci },
+ PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
{ } /* terminate list */
};
@@ -441,9 +439,9 @@ static struct pci_driver ahci_pci_driver = {
.name = DRV_NAME,
.id_table = ahci_pci_tbl,
.probe = ahci_init_one,
+ .remove = ata_pci_remove_one,
.suspend = ahci_pci_device_suspend,
.resume = ahci_pci_device_resume,
- .remove = ahci_remove_one,
};
@@ -452,16 +450,12 @@ static inline int ahci_nr_ports(u32 cap)
return (cap & 0x1f) + 1;
}
-static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port)
+static inline void __iomem *ahci_port_base(void __iomem *base,
+ unsigned int port)
{
return base + 0x100 + (port * 0x80);
}
-static inline void __iomem *ahci_port_base (void __iomem *base, unsigned int port)
-{
- return (void __iomem *) ahci_port_base_ul((unsigned long)base, port);
-}
-
static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
{
unsigned int sc_reg;
@@ -475,7 +469,7 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
return 0xffffffffU;
}
- return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -493,7 +487,7 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
return;
}
- writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void ahci_start_engine(void __iomem *port_mmio)
@@ -735,7 +729,7 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
static unsigned int ahci_dev_classify(struct ata_port *ap)
{
- void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
struct ata_taskfile tf;
u32 tmp;
@@ -763,7 +757,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
static int ahci_clo(struct ata_port *ap)
{
- void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
struct ahci_host_priv *hpriv = ap->host->private_data;
u32 tmp;
@@ -785,7 +779,7 @@ static int ahci_clo(struct ata_port *ap)
static int ahci_softreset(struct ata_port *ap, unsigned int *class)
{
struct ahci_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
const u32 cmd_fis_len = 5; /* five dwords */
const char *reason = NULL;
@@ -893,7 +887,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
struct ahci_port_priv *pp = ap->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
struct ata_taskfile tf;
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
int rc;
@@ -921,7 +915,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
{
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
int rc;
@@ -946,7 +940,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
static void ahci_postreset(struct ata_port *ap, unsigned int *class)
{
- void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
u32 new_tmp, tmp;
ata_std_postreset(ap, class);
@@ -965,7 +959,7 @@ static void ahci_postreset(struct ata_port *ap, unsigned int *class)
static u8 ahci_check_status(struct ata_port *ap)
{
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *mmio = ap->ioaddr.cmd_addr;
return readl(mmio + PORT_TFDATA) & 0xFF;
}
@@ -1111,7 +1105,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
static void ahci_host_intr(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
struct ata_eh_info *ehi = &ap->eh_info;
struct ahci_port_priv *pp = ap->private_data;
@@ -1209,7 +1203,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
VPRINTK("ENTER\n");
hpriv = host->private_data;
- mmio = host->mmio_base;
+ mmio = host->iomap[AHCI_PCI_BAR];
/* sigh. 0xffffffff is a valid return from h/w */
irq_stat = readl(mmio + HOST_IRQ_STAT);
@@ -1254,7 +1248,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ap->ioaddr.cmd_addr;
if (qc->tf.protocol == ATA_PROT_NCQ)
writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
@@ -1266,7 +1260,7 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
static void ahci_freeze(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
/* turn IRQ off */
@@ -1275,7 +1269,7 @@ static void ahci_freeze(struct ata_port *ap)
static void ahci_thaw(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
u32 tmp;
@@ -1290,7 +1284,7 @@ static void ahci_thaw(struct ata_port *ap)
static void ahci_error_handler(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
@@ -1306,7 +1300,7 @@ static void ahci_error_handler(struct ata_port *ap)
static void ahci_vt8251_error_handler(struct ata_port *ap)
{
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
@@ -1323,7 +1317,7 @@ static void ahci_vt8251_error_handler(struct ata_port *ap)
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
if (qc->flags & ATA_QCFLAG_FAILED)
@@ -1340,7 +1334,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
{
struct ahci_host_priv *hpriv = ap->host->private_data;
struct ahci_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
const char *emsg = NULL;
int rc;
@@ -1361,7 +1355,7 @@ static int ahci_port_resume(struct ata_port *ap)
{
struct ahci_port_priv *pp = ap->private_data;
struct ahci_host_priv *hpriv = ap->host->private_data;
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
ahci_power_up(port_mmio, hpriv->cap);
@@ -1373,7 +1367,7 @@ static int ahci_port_resume(struct ata_port *ap)
static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
u32 ctl;
if (mesg.event == PM_EVENT_SUSPEND) {
@@ -1394,10 +1388,12 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
struct ahci_host_priv *hpriv = host->private_data;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
int rc;
- ata_pci_device_do_resume(pdev);
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
rc = ahci_reset_controller(mmio, pdev);
@@ -1418,29 +1414,24 @@ static int ahci_port_start(struct ata_port *ap)
struct device *dev = ap->host->dev;
struct ahci_host_priv *hpriv = ap->host->private_data;
struct ahci_port_priv *pp;
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
void *mem;
dma_addr_t mem_dma;
int rc;
- pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
- memset(pp, 0, sizeof(*pp));
rc = ata_pad_alloc(ap, dev);
- if (rc) {
- kfree(pp);
+ if (rc)
return rc;
- }
- mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
- if (!mem) {
- ata_pad_free(ap, dev);
- kfree(pp);
+ mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma,
+ GFP_KERNEL);
+ if (!mem)
return -ENOMEM;
- }
memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ);
/*
@@ -1482,10 +1473,8 @@ static int ahci_port_start(struct ata_port *ap)
static void ahci_port_stop(struct ata_port *ap)
{
- struct device *dev = ap->host->dev;
struct ahci_host_priv *hpriv = ap->host->private_data;
- struct ahci_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
const char *emsg = NULL;
int rc;
@@ -1494,19 +1483,13 @@ static void ahci_port_stop(struct ata_port *ap)
rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
if (rc)
ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc);
-
- ap->private_data = NULL;
- dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
- pp->cmd_slot, pp->cmd_slot_dma);
- ata_pad_free(ap, dev);
- kfree(pp);
}
-static void ahci_setup_port(struct ata_ioports *port, unsigned long base,
+static void ahci_setup_port(struct ata_ioports *port, void __iomem *base,
unsigned int port_idx)
{
VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx);
- base = ahci_port_base_ul(base, port_idx);
+ base = ahci_port_base(base, port_idx);
VPRINTK("base now==0x%lx\n", base);
port->cmd_addr = base;
@@ -1519,7 +1502,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
{
struct ahci_host_priv *hpriv = probe_ent->private_data;
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
- void __iomem *mmio = probe_ent->mmio_base;
+ void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
unsigned int i, cap_n_ports, using_dac;
int rc;
@@ -1586,7 +1569,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
}
for (i = 0; i < probe_ent->n_ports; i++)
- ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i);
+ ahci_setup_port(&probe_ent->port[i], mmio, i);
ahci_init_controller(mmio, pdev, probe_ent->n_ports,
probe_ent->port_flags, hpriv);
@@ -1600,7 +1583,7 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
{
struct ahci_host_priv *hpriv = probe_ent->private_data;
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
- void __iomem *mmio = probe_ent->mmio_base;
+ void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
u32 vers, cap, impl, speed;
const char *speed_s;
u16 cc;
@@ -1619,11 +1602,11 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
speed_s = "?";
pci_read_config_word(pdev, 0x0a, &cc);
- if (cc == 0x0101)
+ if (cc == PCI_CLASS_STORAGE_IDE)
scc_s = "IDE";
- else if (cc == 0x0106)
+ else if (cc == PCI_CLASS_STORAGE_SATA)
scc_s = "SATA";
- else if (cc == 0x0104)
+ else if (cc == PCI_CLASS_STORAGE_RAID)
scc_s = "RAID";
else
scc_s = "unknown";
@@ -1667,15 +1650,13 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
);
}
-static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- struct ahci_host_priv *hpriv;
- unsigned long base;
- void __iomem *mmio_base;
unsigned int board_idx = (unsigned int) ent->driver_data;
- int have_msi, pci_dev_busy = 0;
+ struct device *dev = &pdev->dev;
+ struct ata_probe_ent *probe_ent;
+ struct ahci_host_priv *hpriv;
int rc;
VPRINTK("ENTER\n");
@@ -1685,57 +1666,36 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- /* JMicron-specific fixup: make sure we're in AHCI mode */
- /* This is protected from races with ata_jmicron by the pci probe
- locking */
if (pdev->vendor == PCI_VENDOR_ID_JMICRON) {
- /* AHCI enable, AHCI on function 0 */
- pci_write_config_byte(pdev, 0x41, 0xa1);
- /* Function 1 is the PATA controller */
+ /* Function 1 is the PATA controller except on the 368, where
+ we are not AHCI anyway */
if (PCI_FUNC(pdev->devfn))
return -ENODEV;
}
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << AHCI_PCI_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
- if (pci_enable_msi(pdev) == 0)
- have_msi = 1;
- else {
+ if (pci_enable_msi(pdev))
pci_intx(pdev, 1);
- have_msi = 0;
- }
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_msi;
- }
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, AHCI_PCI_BAR, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
- hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
- memset(hpriv, 0, sizeof(*hpriv));
+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ return -ENOMEM;
probe_ent->sht = ahci_port_info[board_idx].sht;
probe_ent->port_flags = ahci_port_info[board_idx].flags;
@@ -1745,16 +1705,13 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
probe_ent->private_data = hpriv;
- if (have_msi)
- hpriv->flags |= AHCI_FLAG_MSI;
-
/* initialize adapter */
rc = ahci_host_init(probe_ent);
if (rc)
- goto err_out_hpriv;
+ return rc;
if (!(probe_ent->port_flags & AHCI_FLAG_NO_NCQ) &&
(hpriv->cap & HOST_CAP_NCQ))
@@ -1762,62 +1719,11 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
ahci_print_info(probe_ent);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(dev, probe_ent);
return 0;
-
-err_out_hpriv:
- kfree(hpriv);
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_free_ent:
- kfree(probe_ent);
-err_out_msi:
- if (have_msi)
- pci_disable_msi(pdev);
- else
- pci_intx(pdev, 0);
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
-}
-
-static void ahci_remove_one (struct pci_dev *pdev)
-{
- struct device *dev = pci_dev_to_dev(pdev);
- struct ata_host *host = dev_get_drvdata(dev);
- struct ahci_host_priv *hpriv = host->private_data;
- unsigned int i;
- int have_msi;
-
- for (i = 0; i < host->n_ports; i++)
- ata_port_detach(host->ports[i]);
-
- have_msi = hpriv->flags & AHCI_FLAG_MSI;
- free_irq(host->irq, host);
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- ata_scsi_release(ap->scsi_host);
- scsi_host_put(ap->scsi_host);
- }
-
- kfree(hpriv);
- pci_iounmap(pdev, host->mmio_base);
- kfree(host);
-
- if (have_msi)
- pci_disable_msi(pdev);
- else
- pci_intx(pdev, 0);
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- dev_set_drvdata(dev, NULL);
}
static int __init ahci_init(void)
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 24af56081b5d..be66ea08da55 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -79,7 +79,7 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused)
/* Bits 5 and 6 indicate if DMA is active on master/slave */
if (ap->ioaddr.bmdma_addr)
- dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
@@ -138,7 +138,7 @@ static struct ata_port_operations generic_port_ops = {
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -150,10 +150,10 @@ static struct ata_port_operations generic_port_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int all_generic_ide; /* Set to claim all devices */
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 47701b286f8b..4d716c7347e7 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -118,7 +118,7 @@ enum {
PIIX_80C_SEC = (1 << 7) | (1 << 6),
/* controller IDs */
- piix_pata_33 = 0, /* PIIX3 or 4 at 33Mhz */
+ piix_pata_33 = 0, /* PIIX4 at 33Mhz */
ich_pata_33 = 1, /* ICH up to UDMA 33 only */
ich_pata_66 = 2, /* ICH up to 66 Mhz */
ich_pata_100 = 3, /* ICH up to UDMA 100 */
@@ -128,6 +128,7 @@ enum {
ich6_sata_ahci = 7,
ich6m_sata_ahci = 8,
ich8_sata_ahci = 9,
+ piix_pata_mwdma = 10, /* PIIX3 MWDMA only */
/* constants for mapping table */
P0 = 0, /* port 0 */
@@ -153,7 +154,6 @@ struct piix_host_priv {
static int piix_init_one (struct pci_dev *pdev,
const struct pci_device_id *ent);
-static void piix_host_stop(struct ata_host *host);
static void piix_pata_error_handler(struct ata_port *ap);
static void ich_pata_error_handler(struct ata_port *ap);
static void piix_sata_error_handler(struct ata_port *ap);
@@ -164,7 +164,8 @@ static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev);
static unsigned int in_module_init = 1;
static const struct pci_device_id piix_pci_tbl[] = {
-#ifdef ATA_ENABLE_PATA
+ /* Intel PIIX3 for the 430HX etc */
+ { 0x8086, 0x7010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_mwdma },
/* Intel PIIX4 for the 430TX/440BX/MX chipset: UDMA 33 */
/* Also PIIX4E (fn3 rev 2) and PIIX4M (fn3 rev 3) */
{ 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix_pata_33 },
@@ -202,7 +203,6 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* ICH7/7-R (i945, i975) UDMA 100*/
{ 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
{ 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
-#endif
/* NOTE: The following PCI ids must be kept in sync with the
* list in drivers/pci/quirks.c.
@@ -297,7 +297,7 @@ static const struct ata_port_operations piix_pata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -306,10 +306,10 @@ static const struct ata_port_operations piix_pata_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = piix_host_stop,
};
static const struct ata_port_operations ich_pata_ops = {
@@ -330,7 +330,7 @@ static const struct ata_port_operations ich_pata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -339,10 +339,10 @@ static const struct ata_port_operations ich_pata_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = piix_host_stop,
};
static const struct ata_port_operations piix_sata_ops = {
@@ -360,7 +360,7 @@ static const struct ata_port_operations piix_sata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -369,10 +369,10 @@ static const struct ata_port_operations piix_sata_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = piix_host_stop,
};
static const struct piix_map_db ich5_map_db = {
@@ -441,7 +441,7 @@ static const struct piix_map_db *piix_map_db_table[] = {
};
static struct ata_port_info piix_port_info[] = {
- /* piix_pata_33: 0: PIIX3 or 4 at 33MHz */
+ /* piix_pata_33: 0: PIIX4 at 33MHz */
{
.sht = &piix_sht,
.flags = PIIX_PATA_FLAGS,
@@ -543,6 +543,14 @@ static struct ata_port_info piix_port_info[] = {
.port_ops = &piix_sata_ops,
},
+ /* piix_pata_mwdma: 10: PIIX3 MWDMA only */
+ {
+ .sht = &piix_sht,
+ .flags = PIIX_PATA_FLAGS,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
+ .port_ops = &piix_pata_ops,
+ },
};
static struct pci_bits piix_enable_bits[] = {
@@ -569,6 +577,7 @@ struct ich_laptop {
static const struct ich_laptop ich_laptop[] = {
/* devid, subvendor, subdev */
{ 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
+ { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */
/* end marker */
{ 0, }
};
@@ -632,7 +641,7 @@ static int piix_pata_prereset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
return -ENOENT;
-
+
ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
}
@@ -776,7 +785,7 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
u16 master_data;
u8 speed = adev->dma_mode;
int devid = adev->devno + 2 * ap->port_no;
- u8 udma_enable;
+ u8 udma_enable = 0;
static const /* ISP RTC */
u8 timings[][2] = { { 0, 0 },
@@ -786,7 +795,8 @@ static void do_pata_set_dmamode (struct ata_port *ap, struct ata_device *adev, i
{ 2, 3 }, };
pci_read_config_word(dev, master_port, &master_data);
- pci_read_config_byte(dev, 0x48, &udma_enable);
+ if (ap->udma_mask)
+ pci_read_config_byte(dev, 0x48, &udma_enable);
if (speed >= XFER_UDMA_0) {
unsigned int udma = adev->dma_mode - XFER_UDMA_0;
@@ -1059,6 +1069,7 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
+ struct device *dev = &pdev->dev;
struct ata_port_info port_info[2];
struct ata_port_info *ppinfo[2] = { &port_info[0], &port_info[1] };
struct piix_host_priv *hpriv;
@@ -1072,7 +1083,7 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (!in_module_init)
return -ENODEV;
- hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
return -ENOMEM;
@@ -1122,15 +1133,6 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return ata_pci_init_one(pdev, ppinfo, 2);
}
-static void piix_host_stop(struct ata_host *host)
-{
- struct piix_host_priv *hpriv = host->private_data;
-
- ata_host_stop(host);
-
- kfree(hpriv);
-}
-
static int __init piix_init(void)
{
int rc;
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 667acd283364..25d8d3f778a1 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -59,6 +59,9 @@
#include "libata.h"
+#define DRV_VERSION "2.10" /* must be exactly four chars */
+
+
/* debounce timing parameters in msecs { interval, duration, timeout } */
const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 };
const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 };
@@ -598,51 +601,7 @@ void ata_dev_disable(struct ata_device *dev)
}
/**
- * ata_pio_devchk - PATA device presence detection
- * @ap: ATA channel to examine
- * @device: Device to examine (starting at zero)
- *
- * This technique was originally described in
- * Hale Landis's ATADRVR (www.ata-atapi.com), and
- * later found its way into the ATA/ATAPI spec.
- *
- * Write a pattern to the ATA shadow registers,
- * and if a device is present, it will respond by
- * correctly storing and echoing back the
- * ATA shadow register contents.
- *
- * LOCKING:
- * caller.
- */
-
-static unsigned int ata_pio_devchk(struct ata_port *ap,
- unsigned int device)
-{
- struct ata_ioports *ioaddr = &ap->ioaddr;
- u8 nsect, lbal;
-
- ap->ops->dev_select(ap, device);
-
- outb(0x55, ioaddr->nsect_addr);
- outb(0xaa, ioaddr->lbal_addr);
-
- outb(0xaa, ioaddr->nsect_addr);
- outb(0x55, ioaddr->lbal_addr);
-
- outb(0x55, ioaddr->nsect_addr);
- outb(0xaa, ioaddr->lbal_addr);
-
- nsect = inb(ioaddr->nsect_addr);
- lbal = inb(ioaddr->lbal_addr);
-
- if ((nsect == 0x55) && (lbal == 0xaa))
- return 1; /* we found a device */
-
- return 0; /* nothing found */
-}
-
-/**
- * ata_mmio_devchk - PATA device presence detection
+ * ata_devchk - PATA device presence detection
* @ap: ATA channel to examine
* @device: Device to examine (starting at zero)
*
@@ -659,25 +618,24 @@ static unsigned int ata_pio_devchk(struct ata_port *ap,
* caller.
*/
-static unsigned int ata_mmio_devchk(struct ata_port *ap,
- unsigned int device)
+static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
u8 nsect, lbal;
ap->ops->dev_select(ap, device);
- writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
- writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+ iowrite8(0x55, ioaddr->nsect_addr);
+ iowrite8(0xaa, ioaddr->lbal_addr);
- writeb(0xaa, (void __iomem *) ioaddr->nsect_addr);
- writeb(0x55, (void __iomem *) ioaddr->lbal_addr);
+ iowrite8(0xaa, ioaddr->nsect_addr);
+ iowrite8(0x55, ioaddr->lbal_addr);
- writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
- writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+ iowrite8(0x55, ioaddr->nsect_addr);
+ iowrite8(0xaa, ioaddr->lbal_addr);
- nsect = readb((void __iomem *) ioaddr->nsect_addr);
- lbal = readb((void __iomem *) ioaddr->lbal_addr);
+ nsect = ioread8(ioaddr->nsect_addr);
+ lbal = ioread8(ioaddr->lbal_addr);
if ((nsect == 0x55) && (lbal == 0xaa))
return 1; /* we found a device */
@@ -686,27 +644,6 @@ static unsigned int ata_mmio_devchk(struct ata_port *ap,
}
/**
- * ata_devchk - PATA device presence detection
- * @ap: ATA channel to examine
- * @device: Device to examine (starting at zero)
- *
- * Dispatch ATA device presence detection, depending
- * on whether we are using PIO or MMIO to talk to the
- * ATA shadow registers.
- *
- * LOCKING:
- * caller.
- */
-
-static unsigned int ata_devchk(struct ata_port *ap,
- unsigned int device)
-{
- if (ap->flags & ATA_FLAG_MMIO)
- return ata_mmio_devchk(ap, device);
- return ata_pio_devchk(ap, device);
-}
-
-/**
* ata_dev_classify - determine device type based on ATA-spec signature
* @tf: ATA taskfile register set for device to be identified
*
@@ -923,11 +860,7 @@ void ata_std_dev_select (struct ata_port *ap, unsigned int device)
else
tmp = ATA_DEVICE_OBS | ATA_DEV1;
- if (ap->flags & ATA_FLAG_MMIO) {
- writeb(tmp, (void __iomem *) ap->ioaddr.device_addr);
- } else {
- outb(tmp, ap->ioaddr.device_addr);
- }
+ iowrite8(tmp, ap->ioaddr.device_addr);
ata_pause(ap); /* needed; also flushes, for mmio */
}
@@ -1156,7 +1089,7 @@ void ata_port_flush_task(struct ata_port *ap)
ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __FUNCTION__);
}
-void ata_qc_complete_internal(struct ata_queued_cmd *qc)
+static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
{
struct completion *waiting = qc->private_data;
@@ -1249,7 +1182,6 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
buflen += sg[i].length;
ata_sg_init(qc, sg, n_elem);
- qc->nsect = buflen / ATA_SECT_SIZE;
qc->nbytes = buflen;
}
@@ -1292,7 +1224,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
if (ap->ops->post_internal_cmd)
ap->ops->post_internal_cmd(qc);
- if (qc->flags & ATA_QCFLAG_FAILED && !qc->err_mask) {
+ if ((qc->flags & ATA_QCFLAG_FAILED) && !qc->err_mask) {
if (ata_msg_warn(ap))
ata_dev_printk(dev, KERN_WARNING,
"zero err_mask for failed "
@@ -1608,6 +1540,8 @@ int ata_dev_configure(struct ata_device *dev)
const u16 *id = dev->id;
unsigned int xfer_mask;
char revbuf[7]; /* XYZ-99\0 */
+ char fwrevbuf[ATA_ID_FW_REV_LEN+1];
+ char modelbuf[ATA_ID_PROD_LEN+1];
int rc;
if (!ata_dev_enabled(dev) && ata_msg_info(ap)) {
@@ -1662,6 +1596,16 @@ int ata_dev_configure(struct ata_device *dev)
dev->n_sectors = ata_id_n_sectors(id);
+ /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
+ ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
+ sizeof(fwrevbuf));
+
+ ata_id_c_string(dev->id, modelbuf, ATA_ID_PROD,
+ sizeof(modelbuf));
+
+ if (dev->id[59] & 0x100)
+ dev->multi_count = dev->id[59] & 0xff;
+
if (ata_id_has_lba(id)) {
const char *lba_desc;
char ncq_desc[20];
@@ -1681,13 +1625,16 @@ int ata_dev_configure(struct ata_device *dev)
ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
/* print device info to dmesg */
- if (ata_msg_drv(ap) && print_info)
- ata_dev_printk(dev, KERN_INFO, "%s, "
- "max %s, %Lu sectors: %s %s\n",
- revbuf,
- ata_mode_string(xfer_mask),
+ if (ata_msg_drv(ap) && print_info) {
+ ata_dev_printk(dev, KERN_INFO,
+ "%s: %s, %s, max %s\n",
+ revbuf, modelbuf, fwrevbuf,
+ ata_mode_string(xfer_mask));
+ ata_dev_printk(dev, KERN_INFO,
+ "%Lu sectors, multi %u: %s %s\n",
(unsigned long long)dev->n_sectors,
- lba_desc, ncq_desc);
+ dev->multi_count, lba_desc, ncq_desc);
+ }
} else {
/* CHS */
@@ -1704,22 +1651,17 @@ int ata_dev_configure(struct ata_device *dev)
}
/* print device info to dmesg */
- if (ata_msg_drv(ap) && print_info)
- ata_dev_printk(dev, KERN_INFO, "%s, "
- "max %s, %Lu sectors: CHS %u/%u/%u\n",
- revbuf,
- ata_mode_string(xfer_mask),
- (unsigned long long)dev->n_sectors,
- dev->cylinders, dev->heads,
- dev->sectors);
- }
-
- if (dev->id[59] & 0x100) {
- dev->multi_count = dev->id[59] & 0xff;
- if (ata_msg_drv(ap) && print_info)
+ if (ata_msg_drv(ap) && print_info) {
ata_dev_printk(dev, KERN_INFO,
- "ata%u: dev %u multi count %u\n",
- ap->id, dev->devno, dev->multi_count);
+ "%s: %s, %s, max %s\n",
+ revbuf, modelbuf, fwrevbuf,
+ ata_mode_string(xfer_mask));
+ ata_dev_printk(dev, KERN_INFO,
+ "%Lu sectors, multi %u, CHS %u/%u/%u\n",
+ (unsigned long long)dev->n_sectors,
+ dev->multi_count, dev->cylinders,
+ dev->heads, dev->sectors);
+ }
}
dev->cdb_len = 16;
@@ -2391,6 +2333,10 @@ static int ata_dev_set_mode(struct ata_device *dev)
dev->flags |= ATA_DFLAG_PIO;
err_mask = ata_dev_set_xfermode(dev);
+ /* Old CFA may refuse this command, which is just fine */
+ if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id))
+ err_mask &= ~AC_ERR_DEV;
+
if (err_mask) {
ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
"(err_mask=0x%x)\n", err_mask);
@@ -2493,7 +2439,7 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
for (i = 0; i < ATA_MAX_DEVICES; i++) {
dev = &ap->device[i];
- /* don't udpate suspended devices' xfer mode */
+ /* don't update suspended devices' xfer mode */
if (!ata_dev_ready(dev))
continue;
@@ -2614,13 +2560,8 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
u8 nsect, lbal;
ap->ops->dev_select(ap, 1);
- if (ap->flags & ATA_FLAG_MMIO) {
- nsect = readb((void __iomem *) ioaddr->nsect_addr);
- lbal = readb((void __iomem *) ioaddr->lbal_addr);
- } else {
- nsect = inb(ioaddr->nsect_addr);
- lbal = inb(ioaddr->lbal_addr);
- }
+ nsect = ioread8(ioaddr->nsect_addr);
+ lbal = ioread8(ioaddr->lbal_addr);
if ((nsect == 1) && (lbal == 1))
break;
if (time_after(jiffies, timeout)) {
@@ -2648,19 +2589,11 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
DPRINTK("ata%u: bus reset via SRST\n", ap->id);
/* software reset. causes dev0 to be selected */
- if (ap->flags & ATA_FLAG_MMIO) {
- writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
- writeb(ap->ctl | ATA_SRST, (void __iomem *) ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
- writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- } else {
- outb(ap->ctl, ioaddr->ctl_addr);
- udelay(10);
- outb(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
- udelay(10);
- outb(ap->ctl, ioaddr->ctl_addr);
- }
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
+ udelay(20); /* FIXME: flush */
+ iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
+ udelay(20); /* FIXME: flush */
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
/* spec mandates ">= 2ms" before checking status.
* We wait 150ms, because that was the magic delay used for
@@ -2745,8 +2678,7 @@ void ata_bus_reset(struct ata_port *ap)
ap->device[1].class = ata_dev_try_classify(ap, 1, &err);
/* re-enable interrupts */
- if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */
- ata_irq_on(ap);
+ ap->ops->irq_on(ap);
/* is double-select really necessary? */
if (ap->device[1].class != ATA_DEV_NONE)
@@ -2761,10 +2693,7 @@ void ata_bus_reset(struct ata_port *ap)
if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
/* set up device control for ATA_FLAG_SATA_RESET */
- if (ap->flags & ATA_FLAG_MMIO)
- writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- else
- outb(ap->ctl, ioaddr->ctl_addr);
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
}
DPRINTK("EXIT\n");
@@ -3098,6 +3027,9 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
return 0;
}
+ /* wait a while before checking status, see SRST for more info */
+ msleep(150);
+
if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
ata_port_printk(ap, KERN_ERR,
"COMRESET failed (device not ready)\n");
@@ -3138,11 +3070,8 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
sata_scr_write(ap, SCR_ERROR, serror);
/* re-enable interrupts */
- if (!ap->ops->error_handler) {
- /* FIXME: hack. create a hook instead */
- if (ap->ioaddr.ctl_addr)
- ata_irq_on(ap);
- }
+ if (!ap->ops->error_handler)
+ ap->ops->irq_on(ap);
/* is double-select really necessary? */
if (classes[0] != ATA_DEV_NONE)
@@ -3157,12 +3086,8 @@ void ata_std_postreset(struct ata_port *ap, unsigned int *classes)
}
/* set up device control */
- if (ap->ioaddr.ctl_addr) {
- if (ap->flags & ATA_FLAG_MMIO)
- writeb(ap->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
- else
- outb(ap->ctl, ap->ioaddr.ctl_addr);
- }
+ if (ap->ioaddr.ctl_addr)
+ iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
DPRINTK("EXIT\n");
}
@@ -3187,7 +3112,8 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
const u16 *new_id)
{
const u16 *old_id = dev->id;
- unsigned char model[2][41], serial[2][21];
+ unsigned char model[2][ATA_ID_PROD_LEN + 1];
+ unsigned char serial[2][ATA_ID_SERNO_LEN + 1];
u64 new_n_sectors;
if (dev->class != new_class) {
@@ -3196,10 +3122,10 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
return 0;
}
- ata_id_c_string(old_id, model[0], ATA_ID_PROD_OFS, sizeof(model[0]));
- ata_id_c_string(new_id, model[1], ATA_ID_PROD_OFS, sizeof(model[1]));
- ata_id_c_string(old_id, serial[0], ATA_ID_SERNO_OFS, sizeof(serial[0]));
- ata_id_c_string(new_id, serial[1], ATA_ID_SERNO_OFS, sizeof(serial[1]));
+ ata_id_c_string(old_id, model[0], ATA_ID_PROD, sizeof(model[0]));
+ ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1]));
+ ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0]));
+ ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1]));
new_n_sectors = ata_id_n_sectors(new_id);
if (strcmp(model[0], model[1])) {
@@ -3324,37 +3250,20 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ }
};
-static int ata_strim(char *s, size_t len)
-{
- len = strnlen(s, len);
-
- /* ATAPI specifies that empty space is blank-filled; remove blanks */
- while ((len > 0) && (s[len - 1] == ' ')) {
- len--;
- s[len] = 0;
- }
- return len;
-}
-
unsigned long ata_device_blacklisted(const struct ata_device *dev)
{
- unsigned char model_num[40];
- unsigned char model_rev[16];
- unsigned int nlen, rlen;
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
+ unsigned char model_rev[ATA_ID_FW_REV_LEN + 1];
const struct ata_blacklist_entry *ad = ata_device_blacklist;
- ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
- sizeof(model_num));
- ata_id_string(dev->id, model_rev, ATA_ID_FW_REV_OFS,
- sizeof(model_rev));
- nlen = ata_strim(model_num, sizeof(model_num));
- rlen = ata_strim(model_rev, sizeof(model_rev));
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
+ ata_id_c_string(dev->id, model_rev, ATA_ID_FW_REV, sizeof(model_rev));
while (ad->model_num) {
- if (!strncmp(ad->model_num, model_num, nlen)) {
+ if (!strcmp(ad->model_num, model_num)) {
if (ad->model_rev == NULL)
return ad->horkage;
- if (!strncmp(ad->model_rev, model_rev, rlen))
+ if (!strcmp(ad->model_rev, model_rev))
return ad->horkage;
}
ad++;
@@ -3894,53 +3803,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
}
/**
- * ata_mmio_data_xfer - Transfer data by MMIO
- * @adev: device for this I/O
- * @buf: data buffer
- * @buflen: buffer length
- * @write_data: read/write
- *
- * Transfer data from/to the device data register by MMIO.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
- unsigned int buflen, int write_data)
-{
- struct ata_port *ap = adev->ap;
- unsigned int i;
- unsigned int words = buflen >> 1;
- u16 *buf16 = (u16 *) buf;
- void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
-
- /* Transfer multiple of 2 bytes */
- if (write_data) {
- for (i = 0; i < words; i++)
- writew(le16_to_cpu(buf16[i]), mmio);
- } else {
- for (i = 0; i < words; i++)
- buf16[i] = cpu_to_le16(readw(mmio));
- }
-
- /* Transfer trailing 1 byte, if any. */
- if (unlikely(buflen & 0x01)) {
- u16 align_buf[1] = { 0 };
- unsigned char *trailing_buf = buf + buflen - 1;
-
- if (write_data) {
- memcpy(align_buf, trailing_buf, 1);
- writew(le16_to_cpu(align_buf[0]), mmio);
- } else {
- align_buf[0] = cpu_to_le16(readw(mmio));
- memcpy(trailing_buf, align_buf, 1);
- }
- }
-}
-
-/**
- * ata_pio_data_xfer - Transfer data by PIO
+ * ata_data_xfer - Transfer data by PIO
* @adev: device to target
* @buf: data buffer
* @buflen: buffer length
@@ -3951,18 +3814,17 @@ void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
* LOCKING:
* Inherited from caller.
*/
-
-void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
- unsigned int buflen, int write_data)
+void ata_data_xfer(struct ata_device *adev, unsigned char *buf,
+ unsigned int buflen, int write_data)
{
struct ata_port *ap = adev->ap;
unsigned int words = buflen >> 1;
/* Transfer multiple of 2 bytes */
if (write_data)
- outsw(ap->ioaddr.data_addr, buf, words);
+ iowrite16_rep(ap->ioaddr.data_addr, buf, words);
else
- insw(ap->ioaddr.data_addr, buf, words);
+ ioread16_rep(ap->ioaddr.data_addr, buf, words);
/* Transfer trailing 1 byte, if any. */
if (unlikely(buflen & 0x01)) {
@@ -3971,16 +3833,16 @@ void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
if (write_data) {
memcpy(align_buf, trailing_buf, 1);
- outw(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr);
+ iowrite16(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr);
} else {
- align_buf[0] = cpu_to_le16(inw(ap->ioaddr.data_addr));
+ align_buf[0] = cpu_to_le16(ioread16(ap->ioaddr.data_addr));
memcpy(trailing_buf, align_buf, 1);
}
}
}
/**
- * ata_pio_data_xfer_noirq - Transfer data by PIO
+ * ata_data_xfer_noirq - Transfer data by PIO
* @adev: device to target
* @buf: data buffer
* @buflen: buffer length
@@ -3992,13 +3854,12 @@ void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf,
* LOCKING:
* Inherited from caller.
*/
-
-void ata_pio_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
- unsigned int buflen, int write_data)
+void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
+ unsigned int buflen, int write_data)
{
unsigned long flags;
local_irq_save(flags);
- ata_pio_data_xfer(adev, buf, buflen, write_data);
+ ata_data_xfer(adev, buf, buflen, write_data);
local_irq_restore(flags);
}
@@ -4022,11 +3883,11 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
unsigned int offset;
unsigned char *buf;
- if (qc->cursect == (qc->nsect - 1))
+ if (qc->curbytes == qc->nbytes - ATA_SECT_SIZE)
ap->hsm_task_state = HSM_ST_LAST;
page = sg[qc->cursg].page;
- offset = sg[qc->cursg].offset + qc->cursg_ofs * ATA_SECT_SIZE;
+ offset = sg[qc->cursg].offset + qc->cursg_ofs;
/* get the current page and offset */
page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -4051,10 +3912,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write);
}
- qc->cursect++;
- qc->cursg_ofs++;
+ qc->curbytes += ATA_SECT_SIZE;
+ qc->cursg_ofs += ATA_SECT_SIZE;
- if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) {
+ if (qc->cursg_ofs == (&sg[qc->cursg])->length) {
qc->cursg++;
qc->cursg_ofs = 0;
}
@@ -4079,7 +3940,8 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc)
WARN_ON(qc->dev->multi_count == 0);
- nsect = min(qc->nsect - qc->cursect, qc->dev->multi_count);
+ nsect = min((qc->nbytes - qc->curbytes) / ATA_SECT_SIZE,
+ qc->dev->multi_count);
while (nsect--)
ata_pio_sector(qc);
} else
@@ -4320,7 +4182,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
qc = ata_qc_from_tag(ap, qc->tag);
if (qc) {
if (likely(!(qc->err_mask & AC_ERR_HSM))) {
- ata_irq_on(ap);
+ ap->ops->irq_on(ap);
ata_qc_complete(qc);
} else
ata_port_freeze(ap);
@@ -4336,7 +4198,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
} else {
if (in_wq) {
spin_lock_irqsave(ap->lock, flags);
- ata_irq_on(ap);
+ ap->ops->irq_on(ap);
ata_qc_complete(qc);
spin_unlock_irqrestore(ap->lock, flags);
} else
@@ -5161,7 +5023,7 @@ idle_irq:
#ifdef ATA_IRQ_TRAP
if ((ap->stats.idle_irq % 1000) == 0) {
- ata_irq_ack(ap, 0); /* debug trap */
+ ap->ops->irq_ack(ap, 0); /* debug trap */
ata_port_printk(ap, KERN_WARNING, "irq trap\n");
return 1;
}
@@ -5502,54 +5364,25 @@ void ata_host_resume(struct ata_host *host)
* LOCKING:
* Inherited from caller.
*/
-
-int ata_port_start (struct ata_port *ap)
+int ata_port_start(struct ata_port *ap)
{
struct device *dev = ap->dev;
int rc;
- ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
+ ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
+ GFP_KERNEL);
if (!ap->prd)
return -ENOMEM;
rc = ata_pad_alloc(ap, dev);
- if (rc) {
- dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
+ if (rc)
return rc;
- }
-
- DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma);
+ DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd,
+ (unsigned long long)ap->prd_dma);
return 0;
}
-
-/**
- * ata_port_stop - Undo ata_port_start()
- * @ap: Port to shut down
- *
- * Frees the PRD table.
- *
- * May be used as the port_stop() entry in ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-void ata_port_stop (struct ata_port *ap)
-{
- struct device *dev = ap->dev;
-
- dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
- ata_pad_free(ap, dev);
-}
-
-void ata_host_stop (struct ata_host *host)
-{
- if (host->mmio_base)
- iounmap(host->mmio_base);
-}
-
/**
* ata_dev_init - Initialize an ata_device structure
* @dev: Device structure to initialize
@@ -5723,6 +5556,27 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
return ap;
}
+static void ata_host_release(struct device *gendev, void *res)
+{
+ struct ata_host *host = dev_get_drvdata(gendev);
+ int i;
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (!ap)
+ continue;
+
+ if (ap->ops->port_stop)
+ ap->ops->port_stop(ap);
+
+ scsi_host_put(ap->scsi_host);
+ }
+
+ if (host->ops->host_stop)
+ host->ops->host_stop(host);
+}
+
/**
* ata_sas_host_init - Initialize a host struct
* @host: host to initialize
@@ -5770,22 +5624,28 @@ int ata_device_add(const struct ata_probe_ent *ent)
int rc;
DPRINTK("ENTER\n");
-
+
if (ent->irq == 0) {
dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n");
return 0;
}
+
+ if (!devres_open_group(dev, ata_device_add, GFP_KERNEL))
+ return 0;
+
/* alloc a container for our list of ATA ports (buses) */
- host = kzalloc(sizeof(struct ata_host) +
- (ent->n_ports * sizeof(void *)), GFP_KERNEL);
+ host = devres_alloc(ata_host_release, sizeof(struct ata_host) +
+ (ent->n_ports * sizeof(void *)), GFP_KERNEL);
if (!host)
- return 0;
+ goto err_out;
+ devres_add(dev, host);
+ dev_set_drvdata(dev, host);
ata_host_init(host, dev, ent->_host_flags, ent->port_ops);
host->n_ports = ent->n_ports;
host->irq = ent->irq;
host->irq2 = ent->irq2;
- host->mmio_base = ent->mmio_base;
+ host->iomap = ent->iomap;
host->private_data = ent->private_data;
/* register each port bound to this device */
@@ -5823,8 +5683,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
(ap->pio_mask << ATA_SHIFT_PIO);
/* print per-port info to dmesg */
- ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX "
- "ctl 0x%lX bmdma 0x%lX irq %d\n",
+ ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
+ "ctl 0x%p bmdma 0x%p irq %d\n",
ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
ata_mode_string(xfer_mode_mask),
ap->ioaddr.cmd_addr,
@@ -5837,8 +5697,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
}
/* obtain irq, that may be shared between channels */
- rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
- DRV_NAME, host);
+ rc = devm_request_irq(dev, ent->irq, ent->port_ops->irq_handler,
+ ent->irq_flags, DRV_NAME, host);
if (rc) {
dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
ent->irq, rc);
@@ -5851,15 +5711,19 @@ int ata_device_add(const struct ata_probe_ent *ent)
so trap it now */
BUG_ON(ent->irq == ent->irq2);
- rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags,
- DRV_NAME, host);
+ rc = devm_request_irq(dev, ent->irq2,
+ ent->port_ops->irq_handler, ent->irq_flags,
+ DRV_NAME, host);
if (rc) {
dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
ent->irq2, rc);
- goto err_out_free_irq;
+ goto err_out;
}
}
+ /* resource acquisition complete */
+ devres_remove_group(dev, ata_device_add);
+
/* perform each probe synchronously */
DPRINTK("probe begin\n");
for (i = 0; i < host->n_ports; i++) {
@@ -5928,24 +5792,13 @@ int ata_device_add(const struct ata_probe_ent *ent)
ata_scsi_scan_host(ap);
}
- dev_set_drvdata(dev, host);
-
VPRINTK("EXIT, returning %u\n", ent->n_ports);
return ent->n_ports; /* success */
-err_out_free_irq:
- free_irq(ent->irq, host);
-err_out:
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
- if (ap) {
- ap->ops->port_stop(ap);
- scsi_host_put(ap->scsi_host);
- }
- }
-
- kfree(host);
- VPRINTK("EXIT, returning 0\n");
+ err_out:
+ devres_release_group(dev, ata_device_add);
+ dev_set_drvdata(dev, NULL);
+ VPRINTK("EXIT, returning %d\n", rc);
return 0;
}
@@ -6008,76 +5861,20 @@ void ata_port_detach(struct ata_port *ap)
}
/**
- * ata_host_remove - PCI layer callback for device removal
- * @host: ATA host set that was removed
+ * ata_host_detach - Detach all ports of an ATA host
+ * @host: Host to detach
*
- * Unregister all objects associated with this host set. Free those
- * objects.
+ * Detach all ports of @host.
*
* LOCKING:
- * Inherited from calling layer (may sleep).
+ * Kernel thread context (may sleep).
*/
-
-void ata_host_remove(struct ata_host *host)
+void ata_host_detach(struct ata_host *host)
{
- unsigned int i;
+ int i;
for (i = 0; i < host->n_ports; i++)
ata_port_detach(host->ports[i]);
-
- free_irq(host->irq, host);
- if (host->irq2)
- free_irq(host->irq2, host);
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- ata_scsi_release(ap->scsi_host);
-
- if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
- struct ata_ioports *ioaddr = &ap->ioaddr;
-
- /* FIXME: Add -ac IDE pci mods to remove these special cases */
- if (ioaddr->cmd_addr == ATA_PRIMARY_CMD)
- release_region(ATA_PRIMARY_CMD, 8);
- else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD)
- release_region(ATA_SECONDARY_CMD, 8);
- }
-
- scsi_host_put(ap->scsi_host);
- }
-
- if (host->ops->host_stop)
- host->ops->host_stop(host);
-
- kfree(host);
-}
-
-/**
- * ata_scsi_release - SCSI layer callback hook for host unload
- * @shost: libata host to be unloaded
- *
- * Performs all duties necessary to shut down a libata port...
- * Kill port kthread, disable port, and release resources.
- *
- * LOCKING:
- * Inherited from SCSI layer.
- *
- * RETURNS:
- * One.
- */
-
-int ata_scsi_release(struct Scsi_Host *shost)
-{
- struct ata_port *ap = ata_shost_to_port(shost);
-
- DPRINTK("ENTER\n");
-
- ap->ops->port_disable(ap);
- ap->ops->port_stop(ap);
-
- DPRINTK("EXIT\n");
- return 1;
}
struct ata_probe_ent *
@@ -6085,7 +5882,11 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
{
struct ata_probe_ent *probe_ent;
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
+ /* XXX - the following if can go away once all LLDs are managed */
+ if (!list_empty(&dev->devres_head))
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ else
+ probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent) {
printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
kobject_name(&(dev->kobj)));
@@ -6135,37 +5936,23 @@ void ata_std_ports(struct ata_ioports *ioaddr)
#ifdef CONFIG_PCI
-void ata_pci_host_stop (struct ata_host *host)
-{
- struct pci_dev *pdev = to_pci_dev(host->dev);
-
- pci_iounmap(pdev, host->mmio_base);
-}
-
/**
* ata_pci_remove_one - PCI layer callback for device removal
* @pdev: PCI device that was removed
*
- * PCI layer indicates to libata via this hook that
- * hot-unplug or module unload event has occurred.
- * Handle this by unregistering all objects associated
- * with this PCI device. Free those objects. Then finally
- * release PCI resources and disable device.
+ * PCI layer indicates to libata via this hook that hot-unplug or
+ * module unload event has occurred. Detach all ports. Resource
+ * release is handled via devres.
*
* LOCKING:
* Inherited from PCI layer (may sleep).
*/
-
-void ata_pci_remove_one (struct pci_dev *pdev)
+void ata_pci_remove_one(struct pci_dev *pdev)
{
struct device *dev = pci_dev_to_dev(pdev);
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
-
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- dev_set_drvdata(dev, NULL);
+ ata_host_detach(host);
}
/* move to PCI subsystem */
@@ -6212,12 +5999,22 @@ void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
}
}
-void ata_pci_device_do_resume(struct pci_dev *pdev)
+int ata_pci_device_do_resume(struct pci_dev *pdev)
{
+ int rc;
+
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- pci_enable_device(pdev);
+
+ rc = pcim_enable_device(pdev);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to enable device after resume (%d)\n", rc);
+ return rc;
+ }
+
pci_set_master(pdev);
+ return 0;
}
int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
@@ -6237,10 +6034,12 @@ int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
int ata_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
- ata_pci_device_do_resume(pdev);
- ata_host_resume(host);
- return 0;
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc == 0)
+ ata_host_resume(host);
+ return rc;
}
#endif /* CONFIG_PCI */
@@ -6386,8 +6185,7 @@ EXPORT_SYMBOL_GPL(ata_std_bios_param);
EXPORT_SYMBOL_GPL(ata_std_ports);
EXPORT_SYMBOL_GPL(ata_host_init);
EXPORT_SYMBOL_GPL(ata_device_add);
-EXPORT_SYMBOL_GPL(ata_port_detach);
-EXPORT_SYMBOL_GPL(ata_host_remove);
+EXPORT_SYMBOL_GPL(ata_host_detach);
EXPORT_SYMBOL_GPL(ata_sg_init);
EXPORT_SYMBOL_GPL(ata_sg_init_one);
EXPORT_SYMBOL_GPL(ata_hsm_move);
@@ -6404,12 +6202,9 @@ EXPORT_SYMBOL_GPL(ata_check_status);
EXPORT_SYMBOL_GPL(ata_altstatus);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
-EXPORT_SYMBOL_GPL(ata_port_stop);
-EXPORT_SYMBOL_GPL(ata_host_stop);
EXPORT_SYMBOL_GPL(ata_interrupt);
-EXPORT_SYMBOL_GPL(ata_mmio_data_xfer);
-EXPORT_SYMBOL_GPL(ata_pio_data_xfer);
-EXPORT_SYMBOL_GPL(ata_pio_data_xfer_noirq);
+EXPORT_SYMBOL_GPL(ata_data_xfer);
+EXPORT_SYMBOL_GPL(ata_data_xfer_noirq);
EXPORT_SYMBOL_GPL(ata_qc_prep);
EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
@@ -6446,7 +6241,6 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
-EXPORT_SYMBOL_GPL(ata_scsi_release);
EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(sata_scr_valid);
EXPORT_SYMBOL_GPL(sata_scr_read);
@@ -6467,7 +6261,6 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_host_stop);
EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
EXPORT_SYMBOL_GPL(ata_pci_init_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
@@ -6491,3 +6284,7 @@ EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
EXPORT_SYMBOL_GPL(ata_do_eh);
+EXPORT_SYMBOL_GPL(ata_irq_on);
+EXPORT_SYMBOL_GPL(ata_dummy_irq_on);
+EXPORT_SYMBOL_GPL(ata_irq_ack);
+EXPORT_SYMBOL_GPL(ata_dummy_irq_ack);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 748435807d68..52c85af7fe99 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1443,15 +1443,10 @@ static void ata_eh_report(struct ata_port *ap)
};
struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
- unsigned int nbytes;
if (!(qc->flags & ATA_QCFLAG_FAILED) || !qc->err_mask)
continue;
- nbytes = qc->nbytes;
- if (!nbytes)
- nbytes = qc->nsect << 9;
-
ata_dev_printk(qc->dev, KERN_ERR,
"cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
"tag %d cdb 0x%x data %u %s\n "
@@ -1461,7 +1456,7 @@ static void ata_eh_report(struct ata_port *ap)
cmd->lbal, cmd->lbam, cmd->lbah,
cmd->hob_feature, cmd->hob_nsect,
cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
- cmd->device, qc->tag, qc->cdb[0], nbytes,
+ cmd->device, qc->tag, qc->cdb[0], qc->nbytes,
dma_str[qc->dma_dir],
res->command, res->feature, res->nsect,
res->lbal, res->lbam, res->lbah,
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 73902d335767..0009818a4306 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -149,6 +149,45 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
}
/**
+ * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
+ * @sdev: SCSI device to get identify data for
+ * @arg: User buffer area for identify data
+ *
+ * LOCKING:
+ * Defined by the SCSI layer. We don't really care.
+ *
+ * RETURNS:
+ * Zero on success, negative errno on error.
+ */
+static int ata_get_identity(struct scsi_device *sdev, void __user *arg)
+{
+ struct ata_port *ap = ata_shost_to_port(sdev->host);
+ struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
+ u16 __user *dst = arg;
+ char buf[40];
+
+ if (!dev)
+ return -ENOMSG;
+
+ if (copy_to_user(dst, dev->id, ATA_ID_WORDS * sizeof(u16)))
+ return -EFAULT;
+
+ ata_id_string(dev->id, buf, ATA_ID_PROD, ATA_ID_PROD_LEN);
+ if (copy_to_user(dst + ATA_ID_PROD, buf, ATA_ID_PROD_LEN))
+ return -EFAULT;
+
+ ata_id_string(dev->id, buf, ATA_ID_FW_REV, ATA_ID_FW_REV_LEN);
+ if (copy_to_user(dst + ATA_ID_FW_REV, buf, ATA_ID_FW_REV_LEN))
+ return -EFAULT;
+
+ ata_id_string(dev->id, buf, ATA_ID_SERNO, ATA_ID_SERNO_LEN);
+ if (copy_to_user(dst + ATA_ID_SERNO, buf, ATA_ID_SERNO_LEN))
+ return -EFAULT;
+
+ return 0;
+}
+
+/**
* ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
* @scsidev: Device to which we are issuing command
* @arg: User provided data for issuing command
@@ -159,7 +198,6 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
* RETURNS:
* Zero on success, negative errno on error.
*/
-
int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
{
int rc = 0;
@@ -359,6 +397,9 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
return -EINVAL;
return 0;
+ case HDIO_GET_IDENTITY:
+ return ata_get_identity(scsidev, arg);
+
case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
@@ -397,9 +438,9 @@ int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
* RETURNS:
* Command allocated, or %NULL if none available.
*/
-struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
- struct scsi_cmnd *cmd,
- void (*done)(struct scsi_cmnd *))
+static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
+ struct scsi_cmnd *cmd,
+ void (*done)(struct scsi_cmnd *))
{
struct ata_queued_cmd *qc;
@@ -435,7 +476,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
* LOCKING:
* inherited from caller
*/
-void ata_dump_status(unsigned id, struct ata_taskfile *tf)
+static void ata_dump_status(unsigned id, struct ata_taskfile *tf)
{
u8 stat = tf->command, err = tf->feature;
@@ -610,8 +651,8 @@ int ata_scsi_device_resume(struct scsi_device *sdev)
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
- u8 *ascq, int verbose)
+static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
+ u8 *asc, u8 *ascq, int verbose)
{
int i;
@@ -1359,7 +1400,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
goto nothing_to_do;
qc->flags |= ATA_QCFLAG_IO;
- qc->nsect = n_block;
+ qc->nbytes = n_block * ATA_SECT_SIZE;
rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags,
qc->tag);
@@ -1698,8 +1739,8 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
if (buflen > 35) {
memcpy(&rbuf[8], "ATA ", 8);
- ata_id_string(args->id, &rbuf[16], ATA_ID_PROD_OFS, 16);
- ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV_OFS, 4);
+ ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16);
+ ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4);
if (rbuf[32] == 0 || rbuf[32] == ' ')
memcpy(&rbuf[32], "n/a ", 4);
}
@@ -1768,13 +1809,13 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
0,
0x80, /* this page code */
0,
- ATA_SERNO_LEN, /* page len */
+ ATA_ID_SERNO_LEN, /* page len */
};
memcpy(rbuf, hdr, sizeof(hdr));
- if (buflen > (ATA_SERNO_LEN + 4 - 1))
+ if (buflen > (ATA_ID_SERNO_LEN + 4 - 1))
ata_id_string(args->id, (unsigned char *) &rbuf[4],
- ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
+ ATA_ID_SERNO, ATA_ID_SERNO_LEN);
return 0;
}
@@ -1799,19 +1840,18 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
{
int num;
const int sat_model_serial_desc_len = 68;
- const int ata_model_byte_len = 40;
rbuf[1] = 0x83; /* this page code */
num = 4;
- if (buflen > (ATA_SERNO_LEN + num + 3)) {
+ if (buflen > (ATA_ID_SERNO_LEN + num + 3)) {
/* piv=0, assoc=lu, code_set=ACSII, designator=vendor */
rbuf[num + 0] = 2;
- rbuf[num + 3] = ATA_SERNO_LEN;
+ rbuf[num + 3] = ATA_ID_SERNO_LEN;
num += 4;
ata_id_string(args->id, (unsigned char *) rbuf + num,
- ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
- num += ATA_SERNO_LEN;
+ ATA_ID_SERNO, ATA_ID_SERNO_LEN);
+ num += ATA_ID_SERNO_LEN;
}
if (buflen > (sat_model_serial_desc_len + num + 3)) {
/* SAT defined lu model and serial numbers descriptor */
@@ -1823,11 +1863,11 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
memcpy(rbuf + num, "ATA ", 8);
num += 8;
ata_id_string(args->id, (unsigned char *) rbuf + num,
- ATA_ID_PROD_OFS, ata_model_byte_len);
- num += ata_model_byte_len;
+ ATA_ID_PROD, ATA_ID_PROD_LEN);
+ num += ATA_ID_PROD_LEN;
ata_id_string(args->id, (unsigned char *) rbuf + num,
- ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
- num += ATA_SERNO_LEN;
+ ATA_ID_SERNO, ATA_ID_SERNO_LEN);
+ num += ATA_ID_SERNO_LEN;
}
rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */
return 0;
@@ -1955,15 +1995,15 @@ static unsigned int ata_msense_rw_recovery(u8 **ptr_io, const u8 *last)
*/
static int ata_dev_supports_fua(u16 *id)
{
- unsigned char model[41], fw[9];
+ unsigned char model[ATA_ID_PROD_LEN + 1], fw[ATA_ID_FW_REV_LEN + 1];
if (!libata_fua)
return 0;
if (!ata_id_has_fua(id))
return 0;
- ata_id_c_string(id, model, ATA_ID_PROD_OFS, sizeof(model));
- ata_id_c_string(id, fw, ATA_ID_FW_REV_OFS, sizeof(fw));
+ ata_id_c_string(id, model, ATA_ID_PROD, sizeof(model));
+ ata_id_c_string(id, fw, ATA_ID_FW_REV, sizeof(fw));
if (strcmp(model, "Maxtor"))
return 1;
@@ -2661,7 +2701,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
* TODO: find out if we need to do more here to
* cover scatter/gather case.
*/
- qc->nsect = scmd->request_bufflen / ATA_SECT_SIZE;
+ qc->nbytes = scmd->request_bufflen;
/* request result TF */
qc->flags |= ATA_QCFLAG_RESULT_TF;
@@ -3059,7 +3099,8 @@ void ata_scsi_hotplug(struct work_struct *work)
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
if (ata_dev_enabled(dev) && !dev->sdev) {
- queue_delayed_work(ata_aux_wq, &ap->hotplug_task, HZ);
+ queue_delayed_work(ata_aux_wq, &ap->hotplug_task,
+ round_jiffies_relative(HZ));
break;
}
}
@@ -3264,7 +3305,8 @@ EXPORT_SYMBOL_GPL(ata_sas_port_init);
void ata_sas_port_destroy(struct ata_port *ap)
{
- ap->ops->port_stop(ap);
+ if (ap->ops->port_stop)
+ ap->ops->port_stop(ap);
kfree(ap);
}
EXPORT_SYMBOL_GPL(ata_sas_port_destroy);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 12c88c588039..16bc3e35bdd4 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -56,10 +56,7 @@ u8 ata_irq_on(struct ata_port *ap)
ap->ctl &= ~ATA_NIEN;
ap->last_ctl = ap->ctl;
- if (ap->flags & ATA_FLAG_MMIO)
- writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
- else
- outb(ap->ctl, ioaddr->ctl_addr);
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
tmp = ata_wait_idle(ap);
ap->ops->irq_clear(ap);
@@ -67,92 +64,74 @@ u8 ata_irq_on(struct ata_port *ap)
return tmp;
}
+u8 ata_dummy_irq_on (struct ata_port *ap) { return 0; }
+
/**
- * ata_tf_load_pio - send taskfile registers to host controller
- * @ap: Port to which output is sent
- * @tf: ATA taskfile register set
+ * ata_irq_ack - Acknowledge a device interrupt.
+ * @ap: Port on which interrupts are enabled.
*
- * Outputs ATA taskfile to standard ATA host controller.
+ * Wait up to 10 ms for legacy IDE device to become idle (BUSY
+ * or BUSY+DRQ clear). Obtain dma status and port status from
+ * device. Clear the interrupt. Return port status.
*
* LOCKING:
- * Inherited from caller.
*/
-static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf)
+u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq)
{
- struct ata_ioports *ioaddr = &ap->ioaddr;
- unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+ unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY;
+ u8 host_stat, post_stat, status;
- if (tf->ctl != ap->last_ctl) {
- outb(tf->ctl, ioaddr->ctl_addr);
- ap->last_ctl = tf->ctl;
- ata_wait_idle(ap);
- }
+ status = ata_busy_wait(ap, bits, 1000);
+ if (status & bits)
+ if (ata_msg_err(ap))
+ printk(KERN_ERR "abnormal status 0x%X\n", status);
- if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- outb(tf->hob_feature, ioaddr->feature_addr);
- outb(tf->hob_nsect, ioaddr->nsect_addr);
- outb(tf->hob_lbal, ioaddr->lbal_addr);
- outb(tf->hob_lbam, ioaddr->lbam_addr);
- outb(tf->hob_lbah, ioaddr->lbah_addr);
- VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
- tf->hob_feature,
- tf->hob_nsect,
- tf->hob_lbal,
- tf->hob_lbam,
- tf->hob_lbah);
- }
+ /* get controller status; clear intr, err bits */
+ host_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ iowrite8(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
+ ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- if (is_addr) {
- outb(tf->feature, ioaddr->feature_addr);
- outb(tf->nsect, ioaddr->nsect_addr);
- outb(tf->lbal, ioaddr->lbal_addr);
- outb(tf->lbam, ioaddr->lbam_addr);
- outb(tf->lbah, ioaddr->lbah_addr);
- VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
- tf->feature,
- tf->nsect,
- tf->lbal,
- tf->lbam,
- tf->lbah);
- }
+ post_stat = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- if (tf->flags & ATA_TFLAG_DEVICE) {
- outb(tf->device, ioaddr->device_addr);
- VPRINTK("device 0x%X\n", tf->device);
- }
+ if (ata_msg_intr(ap))
+ printk(KERN_INFO "%s: irq ack: host_stat 0x%X, new host_stat 0x%X, drv_stat 0x%X\n",
+ __FUNCTION__,
+ host_stat, post_stat, status);
- ata_wait_idle(ap);
+ return status;
}
+u8 ata_dummy_irq_ack(struct ata_port *ap, unsigned int chk_drq) { return 0; }
+
/**
- * ata_tf_load_mmio - send taskfile registers to host controller
+ * ata_tf_load - send taskfile registers to host controller
* @ap: Port to which output is sent
* @tf: ATA taskfile register set
*
- * Outputs ATA taskfile to standard ATA host controller using MMIO.
+ * Outputs ATA taskfile to standard ATA host controller.
*
* LOCKING:
* Inherited from caller.
*/
-static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
if (tf->ctl != ap->last_ctl) {
- writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
+ iowrite8(tf->ctl, ioaddr->ctl_addr);
ap->last_ctl = tf->ctl;
ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
- writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr);
- writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr);
- writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr);
- writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr);
- writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr);
+ iowrite8(tf->hob_feature, ioaddr->feature_addr);
+ iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
+ iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
+ iowrite8(tf->hob_lbam, ioaddr->lbam_addr);
+ iowrite8(tf->hob_lbah, ioaddr->lbah_addr);
VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
tf->hob_feature,
tf->hob_nsect,
@@ -162,11 +141,11 @@ static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
}
if (is_addr) {
- writeb(tf->feature, (void __iomem *) ioaddr->feature_addr);
- writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
- writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
- writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
- writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
+ iowrite8(tf->feature, ioaddr->feature_addr);
+ iowrite8(tf->nsect, ioaddr->nsect_addr);
+ iowrite8(tf->lbal, ioaddr->lbal_addr);
+ iowrite8(tf->lbam, ioaddr->lbam_addr);
+ iowrite8(tf->lbah, ioaddr->lbah_addr);
VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
tf->feature,
tf->nsect,
@@ -176,108 +155,34 @@ static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
}
if (tf->flags & ATA_TFLAG_DEVICE) {
- writeb(tf->device, (void __iomem *) ioaddr->device_addr);
+ iowrite8(tf->device, ioaddr->device_addr);
VPRINTK("device 0x%X\n", tf->device);
}
ata_wait_idle(ap);
}
-
-/**
- * ata_tf_load - send taskfile registers to host controller
- * @ap: Port to which output is sent
- * @tf: ATA taskfile register set
- *
- * Outputs ATA taskfile to standard ATA host controller using MMIO
- * or PIO as indicated by the ATA_FLAG_MMIO flag.
- * Writes the control, feature, nsect, lbal, lbam, and lbah registers.
- * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect,
- * hob_lbal, hob_lbam, and hob_lbah.
- *
- * This function waits for idle (!BUSY and !DRQ) after writing
- * registers. If the control register has a new value, this
- * function also waits for idle after writing control and before
- * writing the remaining registers.
- *
- * May be used as the tf_load() entry in ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
-{
- if (ap->flags & ATA_FLAG_MMIO)
- ata_tf_load_mmio(ap, tf);
- else
- ata_tf_load_pio(ap, tf);
-}
-
/**
- * ata_exec_command_pio - issue ATA command to host controller
- * @ap: port to which command is being issued
- * @tf: ATA taskfile register set
- *
- * Issues PIO write to ATA command register, with proper
- * synchronization with interrupt handler / other threads.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-
-static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf)
-{
- DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
-
- outb(tf->command, ap->ioaddr.command_addr);
- ata_pause(ap);
-}
-
-
-/**
- * ata_exec_command_mmio - issue ATA command to host controller
+ * ata_exec_command - issue ATA command to host controller
* @ap: port to which command is being issued
* @tf: ATA taskfile register set
*
- * Issues MMIO write to ATA command register, with proper
- * synchronization with interrupt handler / other threads.
- *
- * FIXME: missing write posting for 400nS delay enforcement
+ * Issues ATA command, with proper synchronization with interrupt
+ * handler / other threads.
*
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
-static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
{
DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
- writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr);
+ iowrite8(tf->command, ap->ioaddr.command_addr);
ata_pause(ap);
}
-
-/**
- * ata_exec_command - issue ATA command to host controller
- * @ap: port to which command is being issued
- * @tf: ATA taskfile register set
- *
- * Issues PIO/MMIO write to ATA command register, with proper
- * synchronization with interrupt handler / other threads.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
-{
- if (ap->flags & ATA_FLAG_MMIO)
- ata_exec_command_mmio(ap, tf);
- else
- ata_exec_command_pio(ap, tf);
-}
-
/**
- * ata_tf_read_pio - input device's ATA taskfile shadow registers
+ * ata_tf_read - input device's ATA taskfile shadow registers
* @ap: Port from which input is read
* @tf: ATA taskfile register set for storing input
*
@@ -287,121 +192,28 @@ void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
* LOCKING:
* Inherited from caller.
*/
-
-static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf)
-{
- struct ata_ioports *ioaddr = &ap->ioaddr;
-
- tf->command = ata_check_status(ap);
- tf->feature = inb(ioaddr->error_addr);
- tf->nsect = inb(ioaddr->nsect_addr);
- tf->lbal = inb(ioaddr->lbal_addr);
- tf->lbam = inb(ioaddr->lbam_addr);
- tf->lbah = inb(ioaddr->lbah_addr);
- tf->device = inb(ioaddr->device_addr);
-
- if (tf->flags & ATA_TFLAG_LBA48) {
- outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
- tf->hob_feature = inb(ioaddr->error_addr);
- tf->hob_nsect = inb(ioaddr->nsect_addr);
- tf->hob_lbal = inb(ioaddr->lbal_addr);
- tf->hob_lbam = inb(ioaddr->lbam_addr);
- tf->hob_lbah = inb(ioaddr->lbah_addr);
- }
-}
-
-/**
- * ata_tf_read_mmio - input device's ATA taskfile shadow registers
- * @ap: Port from which input is read
- * @tf: ATA taskfile register set for storing input
- *
- * Reads ATA taskfile registers for currently-selected device
- * into @tf via MMIO.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
+void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
tf->command = ata_check_status(ap);
- tf->feature = readb((void __iomem *)ioaddr->error_addr);
- tf->nsect = readb((void __iomem *)ioaddr->nsect_addr);
- tf->lbal = readb((void __iomem *)ioaddr->lbal_addr);
- tf->lbam = readb((void __iomem *)ioaddr->lbam_addr);
- tf->lbah = readb((void __iomem *)ioaddr->lbah_addr);
- tf->device = readb((void __iomem *)ioaddr->device_addr);
+ tf->feature = ioread8(ioaddr->error_addr);
+ tf->nsect = ioread8(ioaddr->nsect_addr);
+ tf->lbal = ioread8(ioaddr->lbal_addr);
+ tf->lbam = ioread8(ioaddr->lbam_addr);
+ tf->lbah = ioread8(ioaddr->lbah_addr);
+ tf->device = ioread8(ioaddr->device_addr);
if (tf->flags & ATA_TFLAG_LBA48) {
- writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr);
- tf->hob_feature = readb((void __iomem *)ioaddr->error_addr);
- tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr);
- tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr);
- tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr);
- tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr);
+ iowrite8(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
+ tf->hob_feature = ioread8(ioaddr->error_addr);
+ tf->hob_nsect = ioread8(ioaddr->nsect_addr);
+ tf->hob_lbal = ioread8(ioaddr->lbal_addr);
+ tf->hob_lbam = ioread8(ioaddr->lbam_addr);
+ tf->hob_lbah = ioread8(ioaddr->lbah_addr);
}
}
-
-/**
- * ata_tf_read - input device's ATA taskfile shadow registers
- * @ap: Port from which input is read
- * @tf: ATA taskfile register set for storing input
- *
- * Reads ATA taskfile registers for currently-selected device
- * into @tf.
- *
- * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48
- * is set, also reads the hob registers.
- *
- * May be used as the tf_read() entry in ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
- if (ap->flags & ATA_FLAG_MMIO)
- ata_tf_read_mmio(ap, tf);
- else
- ata_tf_read_pio(ap, tf);
-}
-
-/**
- * ata_check_status_pio - Read device status reg & clear interrupt
- * @ap: port where the device is
- *
- * Reads ATA taskfile status register for currently-selected device
- * and return its value. This also clears pending interrupts
- * from this device
- *
- * LOCKING:
- * Inherited from caller.
- */
-static u8 ata_check_status_pio(struct ata_port *ap)
-{
- return inb(ap->ioaddr.status_addr);
-}
-
-/**
- * ata_check_status_mmio - Read device status reg & clear interrupt
- * @ap: port where the device is
- *
- * Reads ATA taskfile status register for currently-selected device
- * via MMIO and return its value. This also clears pending interrupts
- * from this device
- *
- * LOCKING:
- * Inherited from caller.
- */
-static u8 ata_check_status_mmio(struct ata_port *ap)
-{
- return readb((void __iomem *) ap->ioaddr.status_addr);
-}
-
-
/**
* ata_check_status - Read device status reg & clear interrupt
* @ap: port where the device is
@@ -410,19 +222,14 @@ static u8 ata_check_status_mmio(struct ata_port *ap)
* and return its value. This also clears pending interrupts
* from this device
*
- * May be used as the check_status() entry in ata_port_operations.
- *
* LOCKING:
* Inherited from caller.
*/
u8 ata_check_status(struct ata_port *ap)
{
- if (ap->flags & ATA_FLAG_MMIO)
- return ata_check_status_mmio(ap);
- return ata_check_status_pio(ap);
+ return ioread8(ap->ioaddr.status_addr);
}
-
/**
* ata_altstatus - Read device alternate status reg
* @ap: port where the device is
@@ -441,58 +248,52 @@ u8 ata_altstatus(struct ata_port *ap)
if (ap->ops->check_altstatus)
return ap->ops->check_altstatus(ap);
- if (ap->flags & ATA_FLAG_MMIO)
- return readb((void __iomem *)ap->ioaddr.altstatus_addr);
- return inb(ap->ioaddr.altstatus_addr);
+ return ioread8(ap->ioaddr.altstatus_addr);
}
/**
- * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction
+ * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
* @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
-static void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc)
+void ata_bmdma_setup(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
u8 dmactl;
- void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
/* load PRD table addr. */
mb(); /* make sure PRD table writes are visible to controller */
- writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
+ iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
/* specify data direction, triple-check start bit is clear */
- dmactl = readb(mmio + ATA_DMA_CMD);
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
if (!rw)
dmactl |= ATA_DMA_WR;
- writeb(dmactl, mmio + ATA_DMA_CMD);
+ iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
/* issue r/w command */
ap->ops->exec_command(ap, &qc->tf);
}
/**
- * ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction
+ * ata_bmdma_start - Start a PCI IDE BMDMA transaction
* @qc: Info associated with this ATA transaction.
*
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
-static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
+void ata_bmdma_start (struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
u8 dmactl;
/* start host DMA transaction */
- dmactl = readb(mmio + ATA_DMA_CMD);
- writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD);
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
/* Strictly, one may wish to issue a readb() here, to
* flush the mmio write. However, control also passes
@@ -508,96 +309,6 @@ static void ata_bmdma_start_mmio (struct ata_queued_cmd *qc)
}
/**
- * ata_bmdma_setup_pio - Set up PCI IDE BMDMA transaction (PIO)
- * @qc: Info associated with this ATA transaction.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-
-static void ata_bmdma_setup_pio (struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
- u8 dmactl;
-
- /* load PRD table addr. */
- outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
-
- /* specify data direction, triple-check start bit is clear */
- dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
- if (!rw)
- dmactl |= ATA_DMA_WR;
- outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
- /* issue r/w command */
- ap->ops->exec_command(ap, &qc->tf);
-}
-
-/**
- * ata_bmdma_start_pio - Start a PCI IDE BMDMA transaction (PIO)
- * @qc: Info associated with this ATA transaction.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-
-static void ata_bmdma_start_pio (struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- u8 dmactl;
-
- /* start host DMA transaction */
- dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- outb(dmactl | ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-}
-
-
-/**
- * ata_bmdma_start - Start a PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
- *
- * Writes the ATA_DMA_START flag to the DMA command register.
- *
- * May be used as the bmdma_start() entry in ata_port_operations.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_bmdma_start(struct ata_queued_cmd *qc)
-{
- if (qc->ap->flags & ATA_FLAG_MMIO)
- ata_bmdma_start_mmio(qc);
- else
- ata_bmdma_start_pio(qc);
-}
-
-
-/**
- * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
- *
- * Writes address of PRD table to device's PRD Table Address
- * register, sets the DMA control register, and calls
- * ops->exec_command() to start the transfer.
- *
- * May be used as the bmdma_setup() entry in ata_port_operations.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_bmdma_setup(struct ata_queued_cmd *qc)
-{
- if (qc->ap->flags & ATA_FLAG_MMIO)
- ata_bmdma_setup_mmio(qc);
- else
- ata_bmdma_setup_pio(qc);
-}
-
-
-/**
* ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
* @ap: Port associated with this ATA transaction.
*
@@ -608,23 +319,16 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
void ata_bmdma_irq_clear(struct ata_port *ap)
{
- if (!ap->ioaddr.bmdma_addr)
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+ if (!mmio)
return;
- if (ap->flags & ATA_FLAG_MMIO) {
- void __iomem *mmio =
- ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
- writeb(readb(mmio), mmio);
- } else {
- unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
- outb(inb(addr), addr);
- }
+ iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS);
}
-
/**
* ata_bmdma_status - Read PCI IDE BMDMA status
* @ap: Port associated with this ATA transaction.
@@ -636,19 +340,11 @@ void ata_bmdma_irq_clear(struct ata_port *ap)
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
u8 ata_bmdma_status(struct ata_port *ap)
{
- u8 host_stat;
- if (ap->flags & ATA_FLAG_MMIO) {
- void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
- host_stat = readb(mmio + ATA_DMA_STATUS);
- } else
- host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
- return host_stat;
+ return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
}
-
/**
* ata_bmdma_stop - Stop PCI IDE BMDMA transfer
* @qc: Command we are ending DMA for
@@ -660,21 +356,14 @@ u8 ata_bmdma_status(struct ata_port *ap)
* LOCKING:
* spin_lock_irqsave(host lock)
*/
-
void ata_bmdma_stop(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- if (ap->flags & ATA_FLAG_MMIO) {
- void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
- /* clear start/stop bit */
- writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
- mmio + ATA_DMA_CMD);
- } else {
- /* clear start/stop bit */
- outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- }
+ /* clear start/stop bit */
+ iowrite8(ioread8(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
+ mmio + ATA_DMA_CMD);
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_altstatus(ap); /* dummy read */
@@ -696,10 +385,7 @@ void ata_bmdma_freeze(struct ata_port *ap)
ap->ctl |= ATA_NIEN;
ap->last_ctl = ap->ctl;
- if (ap->flags & ATA_FLAG_MMIO)
- writeb(ap->ctl, (void __iomem *)ioaddr->ctl_addr);
- else
- outb(ap->ctl, ioaddr->ctl_addr);
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
/* Under certain circumstances, some controllers raise IRQ on
* ATA_NIEN manipulation. Also, many controllers fail to mask
@@ -724,8 +410,7 @@ void ata_bmdma_thaw(struct ata_port *ap)
/* clear & re-enable interrupts */
ata_chk_status(ap);
ap->ops->irq_clear(ap);
- if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */
- ata_irq_on(ap);
+ ap->ops->irq_on(ap);
}
/**
@@ -775,7 +460,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
* really a timeout event, adjust error mask and
* cancel frozen state.
*/
- if (qc->err_mask == AC_ERR_TIMEOUT && host_stat & ATA_DMA_ERR) {
+ if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
qc->err_mask = AC_ERR_HOST_BUS;
thaw = 1;
}
@@ -832,6 +517,21 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
}
#ifdef CONFIG_PCI
+
+static int ata_resources_present(struct pci_dev *pdev, int port)
+{
+ int i;
+
+ /* Check the PCI resources for this channel are enabled */
+ port = port * 2;
+ for (i = 0; i < 2; i ++) {
+ if (pci_resource_start(pdev, port + i) == 0 ||
+ pci_resource_len(pdev, port + i) == 0)
+ return 0;
+ }
+ return 1;
+}
+
/**
* ata_pci_init_native_mode - Initialize native-mode driver
* @pdev: pci device to be initialized
@@ -853,45 +553,62 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
struct ata_probe_ent *
ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
{
- struct ata_probe_ent *probe_ent =
- ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
- int p = 0;
- unsigned long bmdma;
+ struct ata_probe_ent *probe_ent;
+ int i, p = 0;
+ void __iomem * const *iomap;
+
+ /* iomap BARs */
+ for (i = 0; i < 4; i++) {
+ if (pcim_iomap(pdev, i, 0) == NULL) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to iomap PCI BAR %d\n", i);
+ return NULL;
+ }
+ }
+ pcim_iomap(pdev, 4, 0); /* may fail */
+ iomap = pcim_iomap_table(pdev);
+
+ /* alloc and init probe_ent */
+ probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
if (!probe_ent)
return NULL;
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
+
+ /* Discard disabled ports. Some controllers show their
+ unused channels this way */
+ if (ata_resources_present(pdev, 0) == 0)
+ ports &= ~ATA_PORT_PRIMARY;
+ if (ata_resources_present(pdev, 1) == 0)
+ ports &= ~ATA_PORT_SECONDARY;
if (ports & ATA_PORT_PRIMARY) {
- probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0);
+ probe_ent->port[p].cmd_addr = iomap[0];
probe_ent->port[p].altstatus_addr =
- probe_ent->port[p].ctl_addr =
- pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS;
- bmdma = pci_resource_start(pdev, 4);
- if (bmdma) {
+ probe_ent->port[p].ctl_addr = (void __iomem *)
+ ((unsigned long)iomap[1] | ATA_PCI_CTL_OFS);
+ if (iomap[4]) {
if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
- (inb(bmdma + 2) & 0x80))
+ (ioread8(iomap[4] + 2) & 0x80))
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
- probe_ent->port[p].bmdma_addr = bmdma;
+ probe_ent->port[p].bmdma_addr = iomap[4];
}
ata_std_ports(&probe_ent->port[p]);
p++;
}
if (ports & ATA_PORT_SECONDARY) {
- probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2);
+ probe_ent->port[p].cmd_addr = iomap[2];
probe_ent->port[p].altstatus_addr =
- probe_ent->port[p].ctl_addr =
- pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS;
- bmdma = pci_resource_start(pdev, 4);
- if (bmdma) {
- bmdma += 8;
+ probe_ent->port[p].ctl_addr = (void __iomem *)
+ ((unsigned long)iomap[3] | ATA_PCI_CTL_OFS);
+ if (iomap[4]) {
if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
- (inb(bmdma + 2) & 0x80))
+ (ioread8(iomap[4] + 10) & 0x80))
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
- probe_ent->port[p].bmdma_addr = bmdma;
+ probe_ent->port[p].bmdma_addr = iomap[4] + 8;
}
ata_std_ports(&probe_ent->port[p]);
probe_ent->pinfo2 = port[1];
@@ -902,13 +619,29 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
return probe_ent;
}
-
static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
struct ata_port_info **port, int port_mask)
{
struct ata_probe_ent *probe_ent;
- unsigned long bmdma = pci_resource_start(pdev, 4);
+ void __iomem *iomap[5] = { }, *bmdma;
+
+ if (port_mask & ATA_PORT_PRIMARY) {
+ iomap[0] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CMD, 8);
+ iomap[1] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CTL, 1);
+ if (!iomap[0] || !iomap[1])
+ return NULL;
+ }
+
+ if (port_mask & ATA_PORT_SECONDARY) {
+ iomap[2] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CMD, 8);
+ iomap[3] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CTL, 1);
+ if (!iomap[2] || !iomap[3])
+ return NULL;
+ }
+ bmdma = pcim_iomap(pdev, 4, 16); /* may fail */
+
+ /* alloc and init probe_ent */
probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
if (!probe_ent)
return NULL;
@@ -918,13 +651,13 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
if (port_mask & ATA_PORT_PRIMARY) {
probe_ent->irq = ATA_PRIMARY_IRQ(pdev);
- probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD;
+ probe_ent->port[0].cmd_addr = iomap[0];
probe_ent->port[0].altstatus_addr =
- probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL;
+ probe_ent->port[0].ctl_addr = iomap[1];
if (bmdma) {
probe_ent->port[0].bmdma_addr = bmdma;
if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
- (inb(bmdma + 2) & 0x80))
+ (ioread8(bmdma + 2) & 0x80))
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
}
ata_std_ports(&probe_ent->port[0]);
@@ -936,13 +669,13 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev);
else
probe_ent->irq = ATA_SECONDARY_IRQ(pdev);
- probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD;
+ probe_ent->port[1].cmd_addr = iomap[2];
probe_ent->port[1].altstatus_addr =
- probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL;
+ probe_ent->port[1].ctl_addr = iomap[3];
if (bmdma) {
probe_ent->port[1].bmdma_addr = bmdma + 8;
if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
- (inb(bmdma + 10) & 0x80))
+ (ioread8(bmdma + 10) & 0x80))
probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
}
ata_std_ports(&probe_ent->port[1]);
@@ -984,15 +717,18 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
unsigned int n_ports)
{
+ struct device *dev = &pdev->dev;
struct ata_probe_ent *probe_ent = NULL;
struct ata_port_info *port[2];
u8 mask;
unsigned int legacy_mode = 0;
- int disable_dev_on_err = 1;
int rc;
DPRINTK("ENTER\n");
+ if (!devres_open_group(dev, NULL, GFP_KERNEL))
+ return -ENOMEM;
+
BUG_ON(n_ports < 1 || n_ports > 2);
port[0] = port_info[0];
@@ -1009,9 +745,9 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
boot for the primary video which is BIOS enabled
*/
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
- return rc;
+ goto err_out;
if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
u8 tmp8;
@@ -1027,7 +763,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
left a device in compatibility mode */
if (legacy_mode) {
printk(KERN_ERR "ata: Compatibility mode ATA is not supported on this platform, skipping.\n");
- return -EOPNOTSUPP;
+ rc = -EOPNOTSUPP;
+ goto err_out;
}
#endif
}
@@ -1035,13 +772,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (!legacy_mode) {
rc = pci_request_regions(pdev, DRV_NAME);
if (rc) {
- disable_dev_on_err = 0;
+ pcim_pin_device(pdev);
goto err_out;
}
} else {
/* Deal with combined mode hack. This side of the logic all
goes away once the combined mode hack is killed in 2.6.21 */
- if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) {
+ if (!devm_request_region(dev, ATA_PRIMARY_CMD, 8, "libata")) {
struct resource *conflict, res;
res.start = ATA_PRIMARY_CMD;
res.end = ATA_PRIMARY_CMD + 8 - 1;
@@ -1051,7 +788,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (!strcmp(conflict->name, "libata"))
legacy_mode |= ATA_PORT_PRIMARY;
else {
- disable_dev_on_err = 0;
+ pcim_pin_device(pdev);
printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \
"ata: conflict with %s\n",
ATA_PRIMARY_CMD,
@@ -1060,7 +797,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
} else
legacy_mode |= ATA_PORT_PRIMARY;
- if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) {
+ if (!devm_request_region(dev, ATA_SECONDARY_CMD, 8, "libata")) {
struct resource *conflict, res;
res.start = ATA_SECONDARY_CMD;
res.end = ATA_SECONDARY_CMD + 8 - 1;
@@ -1070,7 +807,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if (!strcmp(conflict->name, "libata"))
legacy_mode |= ATA_PORT_SECONDARY;
else {
- disable_dev_on_err = 0;
+ pcim_pin_device(pdev);
printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \
"ata: conflict with %s\n",
ATA_SECONDARY_CMD,
@@ -1090,16 +827,16 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
/* we have legacy mode, but all ports are unavailable */
if (legacy_mode == (1 << 3)) {
rc = -EBUSY;
- goto err_out_regions;
+ goto err_out;
}
/* TODO: If we get no DMA mask we should fall back to PIO */
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ goto err_out;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ goto err_out;
if (legacy_mode) {
probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode);
@@ -1111,40 +848,22 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
if (!probe_ent) {
rc = -ENOMEM;
- goto err_out_regions;
+ goto err_out;
}
pci_set_master(pdev);
if (!ata_device_add(probe_ent)) {
rc = -ENODEV;
- goto err_out_ent;
+ goto err_out;
}
- kfree(probe_ent);
-
+ devm_kfree(dev, probe_ent);
+ devres_remove_group(dev, NULL);
return 0;
-err_out_ent:
- kfree(probe_ent);
-err_out_regions:
- /* All this conditional stuff is needed for the combined mode hack
- until 2.6.21 when it can go */
- if (legacy_mode) {
- pci_release_region(pdev, 4);
- if (legacy_mode & ATA_PORT_PRIMARY) {
- release_region(ATA_PRIMARY_CMD, 8);
- pci_release_region(pdev, 1);
- }
- if (legacy_mode & ATA_PORT_SECONDARY) {
- release_region(ATA_SECONDARY_CMD, 8);
- pci_release_region(pdev, 3);
- }
- } else
- pci_release_regions(pdev);
err_out:
- if (disable_dev_on_err)
- pci_disable_device(pdev);
+ devres_release_group(dev, NULL);
return rc;
}
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 81ae41d5f23f..06ccf230e3c2 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -29,7 +29,6 @@
#define __LIBATA_H__
#define DRV_NAME "libata"
-#define DRV_VERSION "2.00" /* must be exactly four chars */
struct ata_scsi_args {
struct ata_device *dev;
@@ -136,4 +135,7 @@ extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
/* libata-sff.c */
extern u8 ata_irq_on(struct ata_port *ap);
+/* pata_sis.c */
+extern struct ata_port_info sis_info133;
+
#endif /* __LIBATA_H__ */
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index c5d61d1911a5..ab44d18850f6 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -153,11 +153,11 @@ static void ali_early_error_handler(struct ata_port *ap)
static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
{
- char model_num[40];
+ char model_num[ATA_ID_PROD_LEN + 1];
/* No DMA on anything but a disk for now */
if (adev->class != ATA_DEV_ATA)
mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
- ata_id_string(adev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
+ ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
if (strstr(model_num, "WDC"))
return mask &= ~ATA_MASK_UDMA;
return ata_pci_default_filter(ap, adev, mask);
@@ -370,14 +370,14 @@ static struct ata_port_operations ali_early_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -411,14 +411,14 @@ static struct ata_port_operations ali_20_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -449,14 +449,14 @@ static struct ata_port_operations ali_c2_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -486,14 +486,14 @@ static struct ata_port_operations ali_c5_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
@@ -504,7 +504,7 @@ static struct ata_port_operations ali_c5_port_ops = {
* Perform the setup on the device that must be done both at boot
* and at resume time.
*/
-
+
static void ali_init_chipset(struct pci_dev *pdev)
{
u8 rev, tmp;
@@ -655,7 +655,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
port_info[0] = port_info[1] = &info_c5;
ali_init_chipset(pdev);
-
+
isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
if (isa_bridge && rev >= 0x20 && rev < 0xC2) {
/* Are we paired with a UDMA capable chip */
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index a6b330089f22..619e44b04032 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -362,14 +362,14 @@ static struct ata_port_operations amd33_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations amd66_port_ops = {
@@ -396,14 +396,14 @@ static struct ata_port_operations amd66_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations amd100_port_ops = {
@@ -430,14 +430,14 @@ static struct ata_port_operations amd100_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations amd133_port_ops = {
@@ -464,14 +464,14 @@ static struct ata_port_operations amd133_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations nv100_port_ops = {
@@ -498,14 +498,14 @@ static struct ata_port_operations nv100_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations nv133_port_ops = {
@@ -532,14 +532,14 @@ static struct ata_port_operations nv133_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 37bc1323bda7..21c30282717c 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -341,14 +341,14 @@ static const struct ata_port_operations artop6210_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations artop6260_ops = {
@@ -373,14 +373,14 @@ static const struct ata_port_operations artop6260_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 504e1dbfffd7..c3eb40c91c80 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -252,14 +252,14 @@ static struct ata_port_operations atiixp_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 449162cbf93e..da098282b5f6 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -313,14 +313,14 @@ static struct ata_port_operations cmd64x_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations cmd646r1_port_ops = {
@@ -347,14 +347,14 @@ static struct ata_port_operations cmd646r1_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations cmd648_port_ops = {
@@ -381,14 +381,14 @@ static struct ata_port_operations cmd648_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 9f165a8e032d..1ce8fcfd7826 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -99,9 +99,9 @@ static void cs5520_set_timings(struct ata_port *ap, struct ata_device *adev, int
static void cs5520_enable_dma(struct ata_port *ap, struct ata_device *adev)
{
/* Set the DMA enable/disable flag */
- u8 reg = inb(ap->ioaddr.bmdma_addr + 0x02);
+ u8 reg = ioread8(ap->ioaddr.bmdma_addr + 0x02);
reg |= 1<<(adev->devno + 5);
- outb(reg, ap->ioaddr.bmdma_addr + 0x02);
+ iowrite8(reg, ap->ioaddr.bmdma_addr + 0x02);
}
/**
@@ -193,19 +193,20 @@ static struct ata_port_operations cs5520_port_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
u8 pcicfg;
+ void *iomap[5];
static struct ata_probe_ent probe[2];
int ports = 0;
@@ -236,6 +237,16 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
return -ENODEV;
}
+ /* Map IO ports */
+ iomap[0] = devm_ioport_map(&dev->dev, 0x1F0, 8);
+ iomap[1] = devm_ioport_map(&dev->dev, 0x3F6, 1);
+ iomap[2] = devm_ioport_map(&dev->dev, 0x170, 8);
+ iomap[3] = devm_ioport_map(&dev->dev, 0x376, 1);
+ iomap[4] = pcim_iomap(dev, 2, 0);
+
+ if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
+ return -ENOMEM;
+
/* We have to do our own plumbing as the PCI setup for this
chipset is non-standard so we can't punt to the libata code */
@@ -249,10 +260,10 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
probe[0].irq_flags = 0;
probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
probe[0].n_ports = 1;
- probe[0].port[0].cmd_addr = 0x1F0;
- probe[0].port[0].ctl_addr = 0x3F6;
- probe[0].port[0].altstatus_addr = 0x3F6;
- probe[0].port[0].bmdma_addr = pci_resource_start(dev, 2);
+ probe[0].port[0].cmd_addr = iomap[0];
+ probe[0].port[0].ctl_addr = iomap[1];
+ probe[0].port[0].altstatus_addr = iomap[1];
+ probe[0].port[0].bmdma_addr = iomap[4];
/* The secondary lurks at different addresses but is otherwise
the same beastie */
@@ -260,10 +271,10 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
probe[1] = probe[0];
INIT_LIST_HEAD(&probe[1].node);
probe[1].irq = 15;
- probe[1].port[0].cmd_addr = 0x170;
- probe[1].port[0].ctl_addr = 0x376;
- probe[1].port[0].altstatus_addr = 0x376;
- probe[1].port[0].bmdma_addr = pci_resource_start(dev, 2) + 8;
+ probe[1].port[0].cmd_addr = iomap[2];
+ probe[1].port[0].ctl_addr = iomap[3];
+ probe[1].port[0].altstatus_addr = iomap[3];
+ probe[1].port[0].bmdma_addr = iomap[4] + 8;
/* Let libata fill in the port details */
ata_std_ports(&probe[0].port[0]);
@@ -294,7 +305,7 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev)
struct device *dev = pci_dev_to_dev(pdev);
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
+ ata_host_detach(host);
dev_set_drvdata(dev, NULL);
}
@@ -305,7 +316,7 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev)
* Do any reconfiguration work needed by a resume from RAM. We need
* to restore DMA mode support on BIOSen which disabled it
*/
-
+
static int cs5520_reinit_one(struct pci_dev *pdev)
{
u8 pcicfg;
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index b1ca207e3545..3d7b7d87ec6f 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -37,6 +37,13 @@
#define DRV_NAME "pata_cs5530"
#define DRV_VERSION "0.7.1"
+static void __iomem *cs5530_port_base(struct ata_port *ap)
+{
+ unsigned long bmdma = (unsigned long)ap->ioaddr.bmdma_addr;
+
+ return (void __iomem *)((bmdma & ~0x0F) + 0x20 + 0x10 * ap->port_no);
+}
+
/**
* cs5530_set_piomode - PIO setup
* @ap: ATA interface
@@ -52,19 +59,19 @@ static void cs5530_set_piomode(struct ata_port *ap, struct ata_device *adev)
{0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010},
{0xd1329172, 0x71212171, 0x30200080, 0x20102010, 0x00100010}
};
- unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->port_no;
+ void __iomem *base = cs5530_port_base(ap);
u32 tuning;
int format;
/* Find out which table to use */
- tuning = inl(base + 0x04);
+ tuning = ioread32(base + 0x04);
format = (tuning & 0x80000000UL) ? 1 : 0;
/* Now load the right timing register */
if (adev->devno)
base += 0x08;
- outl(cs5530_pio_timings[format][adev->pio_mode - XFER_PIO_0], base);
+ iowrite32(cs5530_pio_timings[format][adev->pio_mode - XFER_PIO_0], base);
}
/**
@@ -79,12 +86,12 @@ static void cs5530_set_piomode(struct ata_port *ap, struct ata_device *adev)
static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
- unsigned long base = ( ap->ioaddr.bmdma_addr & ~0x0F) + 0x20 + 0x10 * ap->port_no;
+ void __iomem *base = cs5530_port_base(ap);
u32 tuning, timing = 0;
u8 reg;
/* Find out which table to use */
- tuning = inl(base + 0x04);
+ tuning = ioread32(base + 0x04);
switch(adev->dma_mode) {
case XFER_UDMA_0:
@@ -105,20 +112,20 @@ static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev)
/* Merge in the PIO format bit */
timing |= (tuning & 0x80000000UL);
if (adev->devno == 0) /* Master */
- outl(timing, base + 0x04);
+ iowrite32(timing, base + 0x04);
else {
if (timing & 0x00100000)
tuning |= 0x00100000; /* UDMA for both */
else
tuning &= ~0x00100000; /* MWDMA for both */
- outl(tuning, base + 0x04);
- outl(timing, base + 0x0C);
+ iowrite32(tuning, base + 0x04);
+ iowrite32(timing, base + 0x0C);
}
/* Set the DMA capable bit in the BMDMA area */
- reg = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ reg = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
reg |= (1 << (5 + adev->devno));
- outb(reg, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ iowrite8(reg, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
/* Remember the last DMA setup we did */
@@ -210,14 +217,14 @@ static struct ata_port_operations cs5530_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = cs5530_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct dmi_system_id palmax_dmi_table[] = {
@@ -247,7 +254,7 @@ static int cs5530_is_palmax(void)
* Perform the chip initialisation work that is shared between both
* setup and resume paths
*/
-
+
static int cs5530_init_chip(void)
{
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL, *dev = NULL;
@@ -357,11 +364,11 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &cs5530_port_ops
};
static struct ata_port_info *port_info[2] = { &info, &info };
-
+
/* Chip initialisation */
if (cs5530_init_chip())
return -ENODEV;
-
+
if (cs5530_is_palmax())
port_info[1] = &info_palmax_secondary;
@@ -376,7 +383,7 @@ static int cs5530_reinit_one(struct pci_dev *pdev)
BUG();
return ata_pci_device_resume(pdev);
}
-
+
static const struct pci_device_id cs5530[] = {
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index e3efec4ffc79..17bc693cc514 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -214,14 +214,14 @@ static struct ata_port_operations cs5535_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index e2a95699bae7..63f48f08763d 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -165,14 +165,14 @@ static struct ata_port_operations cy82c693_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index edf8a63f50af..c19b6a8a7dc6 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -261,14 +261,14 @@ static const struct ata_port_operations efar_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index 2663599a7c02..27d724b5eea2 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -151,23 +151,13 @@ static const char *bad_ata66_3[] = {
static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[])
{
- unsigned char model_num[40];
- char *s;
- unsigned int len;
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
int i = 0;
- ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
- s = &model_num[0];
- len = strnlen(s, sizeof(model_num));
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
- /* ATAPI specifies that empty space is blank-filled; remove blanks */
- while ((len > 0) && (s[len - 1] == ' ')) {
- len--;
- s[len] = 0;
- }
-
- while(list[i] != NULL) {
- if (!strncmp(list[i], s, len)) {
+ while (list[i] != NULL) {
+ if (!strcmp(list[i], model_num)) {
printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
modestr, list[i]);
return 1;
@@ -232,7 +222,7 @@ static int hpt36x_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no]))
return -ENOENT;
-
+
pci_read_config_byte(pdev, 0x5A, &ata66);
if (ata66 & (1 << ap->port_no))
ap->cbl = ATA_CBL_PATA40;
@@ -371,14 +361,14 @@ static struct ata_port_operations hpt366_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index dfb306057cf4..4ffc392052c0 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -349,24 +349,13 @@ static u32 hpt37x_find_mode(struct ata_port *ap, int speed)
static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char *list[])
{
- unsigned char model_num[40];
- char *s;
- unsigned int len;
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
int i = 0;
- ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
- sizeof(model_num));
- s = &model_num[0];
- len = strnlen(s, sizeof(model_num));
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
- /* ATAPI specifies that empty space is blank-filled; remove blanks */
- while ((len > 0) && (s[len - 1] == ' ')) {
- len--;
- s[len] = 0;
- }
-
- while(list[i] != NULL) {
- if (!strncmp(list[i], s, len)) {
+ while (list[i] != NULL) {
+ if (!strcmp(list[i], model_num)) {
printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
modestr, list[i]);
return 1;
@@ -459,7 +448,7 @@ static int hpt37x_pre_reset(struct ata_port *ap)
};
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
return -ENOENT;
-
+
pci_read_config_byte(pdev, 0x5B, &scr2);
pci_write_config_byte(pdev, 0x5B, scr2 & ~0x01);
/* Cable register now active */
@@ -504,7 +493,7 @@ static int hpt374_pre_reset(struct ata_port *ap)
if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no]))
return -ENOENT;
-
+
/* Do the extra channel work */
pci_read_config_word(pdev, 0x52, &mcr3);
pci_read_config_word(pdev, 0x56, &mcr6);
@@ -645,24 +634,24 @@ static void hpt370_bmdma_stop(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u8 dma_stat = inb(ap->ioaddr.bmdma_addr + 2);
+ u8 dma_stat = ioread8(ap->ioaddr.bmdma_addr + 2);
u8 dma_cmd;
- unsigned long bmdma = ap->ioaddr.bmdma_addr;
+ void __iomem *bmdma = ap->ioaddr.bmdma_addr;
if (dma_stat & 0x01) {
udelay(20);
- dma_stat = inb(bmdma + 2);
+ dma_stat = ioread8(bmdma + 2);
}
if (dma_stat & 0x01) {
/* Clear the engine */
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(10);
/* Stop DMA */
- dma_cmd = inb(bmdma );
- outb(dma_cmd & 0xFE, bmdma);
+ dma_cmd = ioread8(bmdma );
+ iowrite8(dma_cmd & 0xFE, bmdma);
/* Clear Error */
- dma_stat = inb(bmdma + 2);
- outb(dma_stat | 0x06 , bmdma + 2);
+ dma_stat = ioread8(bmdma + 2);
+ iowrite8(dma_stat | 0x06 , bmdma + 2);
/* Clear the engine */
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(10);
@@ -807,14 +796,14 @@ static struct ata_port_operations hpt370_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -846,14 +835,14 @@ static struct ata_port_operations hpt370a_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -886,14 +875,14 @@ static struct ata_port_operations hpt372_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -926,14 +915,14 @@ static struct ata_port_operations hpt374_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 886fab9aa62c..65f2e180e7fa 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -263,26 +263,26 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc)
static void hpt3x2n_set_clock(struct ata_port *ap, int source)
{
- unsigned long bmdma = ap->ioaddr.bmdma_addr;
+ void __iomem *bmdma = ap->ioaddr.bmdma_addr;
/* Tristate the bus */
- outb(0x80, bmdma+0x73);
- outb(0x80, bmdma+0x77);
+ iowrite8(0x80, bmdma+0x73);
+ iowrite8(0x80, bmdma+0x77);
/* Switch clock and reset channels */
- outb(source, bmdma+0x7B);
- outb(0xC0, bmdma+0x79);
+ iowrite8(source, bmdma+0x7B);
+ iowrite8(0xC0, bmdma+0x79);
/* Reset state machines */
- outb(0x37, bmdma+0x70);
- outb(0x37, bmdma+0x74);
+ iowrite8(0x37, bmdma+0x70);
+ iowrite8(0x37, bmdma+0x74);
/* Complete reset */
- outb(0x00, bmdma+0x79);
+ iowrite8(0x00, bmdma+0x79);
/* Reconnect channels to bus */
- outb(0x00, bmdma+0x73);
- outb(0x00, bmdma+0x77);
+ iowrite8(0x00, bmdma+0x73);
+ iowrite8(0x00, bmdma+0x77);
}
/* Check if our partner interface is busy */
@@ -373,14 +373,14 @@ static struct ata_port_operations hpt3x2n_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = hpt3x2n_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index 5f1d385eb592..483ce7c12c9a 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -148,14 +148,14 @@ static struct ata_port_operations hpt3x3_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -164,7 +164,7 @@ static struct ata_port_operations hpt3x3_port_ops = {
*
* Perform the setup required at boot and on resume.
*/
-
+
static void hpt3x3_init_chipset(struct pci_dev *dev)
{
u16 cmd;
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index a97d55ae95c9..1bf5ec18b2e3 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -53,14 +53,14 @@ static struct ata_port_operations isapnp_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -75,6 +75,7 @@ static struct ata_port_operations isapnp_port_ops = {
static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id)
{
struct ata_probe_ent ae;
+ void __iomem *cmd_addr, *ctl_addr;
if (pnp_port_valid(idev, 0) == 0)
return -ENODEV;
@@ -83,6 +84,10 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
if (pnp_irq_valid(idev, 0) == 0)
return -ENODEV;
+ cmd_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 0), 8);
+ if (!cmd_addr)
+ return -ENOMEM;
+
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
ae.dev = &idev->dev;
@@ -93,11 +98,13 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
ae.irq = pnp_irq(idev, 0);
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS;
- ae.port[0].cmd_addr = pnp_port_start(idev, 0);
+ ae.port[0].cmd_addr = cmd_addr;
if (pnp_port_valid(idev, 1) == 0) {
- ae.port[0].altstatus_addr = pnp_port_start(idev, 1);
- ae.port[0].ctl_addr = pnp_port_start(idev, 1);
+ ctl_addr = devm_ioport_map(&idev->dev,
+ pnp_port_start(idev, 1), 1);
+ ae.port[0].altstatus_addr = ctl_addr;
+ ae.port[0].ctl_addr = ctl_addr;
ae.port_flags |= ATA_FLAG_SRST;
}
ata_std_ports(&ae.port[0]);
@@ -120,7 +127,7 @@ static void isapnp_remove_one(struct pnp_dev *idev)
struct device *dev = &idev->dev;
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
+ ata_host_detach(host);
dev_set_drvdata(dev, NULL);
}
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
new file mode 100644
index 000000000000..7eac869dfcd3
--- /dev/null
+++ b/drivers/ata/pata_it8213.c
@@ -0,0 +1,354 @@
+/*
+ * pata_it8213.c - iTE Tech. Inc. IT8213 PATA driver
+ *
+ * The IT8213 is a very Intel ICH like device for timing purposes, having
+ * a similar register layout and the same split clock arrangement. Cable
+ * detection is different, and it does not have slave channels or all the
+ * clutter of later ICH/SATA setups.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/ata.h>
+
+#define DRV_NAME "pata_it8213"
+#define DRV_VERSION "0.0.2"
+
+/**
+ * it8213_pre_reset - check for 40/80 pin
+ * @ap: Port
+ *
+ * Perform cable detection for the 8213 ATA interface. This is
+ * different to the PIIX arrangement
+ */
+
+static int it8213_pre_reset(struct ata_port *ap)
+{
+ static const struct pci_bits it8213_enable_bits[] = {
+ { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */
+ };
+
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u8 tmp;
+
+ if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no]))
+ return -ENOENT;
+
+ pci_read_config_byte(pdev, 0x42, &tmp);
+ if (tmp & 2) /* The initial docs are incorrect */
+ ap->cbl = ATA_CBL_PATA40;
+ else
+ ap->cbl = ATA_CBL_PATA80;
+ return ata_std_prereset(ap);
+}
+
+/**
+ * it8213_probe_reset - Probe specified port on PATA host controller
+ * @ap: Port to probe
+ *
+ * LOCKING:
+ * None (inherited from caller).
+ */
+
+static void it8213_error_handler(struct ata_port *ap)
+{
+ ata_bmdma_drive_eh(ap, it8213_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+}
+
+/**
+ * it8213_set_piomode - Initialize host controller PATA PIO timings
+ * @ap: Port whose timings we are configuring
+ * @adev: um
+ *
+ * Set PIO mode for device, in host controller PCI config space.
+ *
+ * LOCKING:
+ * None (inherited from caller).
+ */
+
+static void it8213_set_piomode (struct ata_port *ap, struct ata_device *adev)
+{
+ unsigned int pio = adev->pio_mode - XFER_PIO_0;
+ struct pci_dev *dev = to_pci_dev(ap->host->dev);
+ unsigned int idetm_port= ap->port_no ? 0x42 : 0x40;
+ u16 idetm_data;
+ int control = 0;
+
+ /*
+ * See Intel Document 298600-004 for the timing programing rules
+ * for PIIX/ICH. The 8213 is a clone so very similar
+ */
+
+ static const /* ISP RTC */
+ u8 timings[][2] = { { 0, 0 },
+ { 0, 0 },
+ { 1, 0 },
+ { 2, 1 },
+ { 2, 3 }, };
+
+ if (pio > 2)
+ control |= 1; /* TIME1 enable */
+ if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */
+ control |= 2; /* IORDY enable */
+ /* Bit 2 is set for ATAPI on the IT8213 - reverse of ICH/PIIX */
+ if (adev->class != ATA_DEV_ATA)
+ control |= 4;
+
+ pci_read_config_word(dev, idetm_port, &idetm_data);
+
+ /* Enable PPE, IE and TIME as appropriate */
+
+ if (adev->devno == 0) {
+ idetm_data &= 0xCCF0;
+ idetm_data |= control;
+ idetm_data |= (timings[pio][0] << 12) |
+ (timings[pio][1] << 8);
+ } else {
+ u8 slave_data;
+
+ idetm_data &= 0xCC0F;
+ idetm_data |= (control << 4);
+
+ /* Slave timing in seperate register */
+ pci_read_config_byte(dev, 0x44, &slave_data);
+ slave_data &= 0xF0;
+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << 4;
+ pci_write_config_byte(dev, 0x44, slave_data);
+ }
+
+ idetm_data |= 0x4000; /* Ensure SITRE is enabled */
+ pci_write_config_word(dev, idetm_port, idetm_data);
+}
+
+/**
+ * it8213_set_dmamode - Initialize host controller PATA DMA timings
+ * @ap: Port whose timings we are configuring
+ * @adev: Device to program
+ *
+ * Set UDMA/MWDMA mode for device, in host controller PCI config space.
+ * This device is basically an ICH alike.
+ *
+ * LOCKING:
+ * None (inherited from caller).
+ */
+
+static void it8213_set_dmamode (struct ata_port *ap, struct ata_device *adev)
+{
+ struct pci_dev *dev = to_pci_dev(ap->host->dev);
+ u16 master_data;
+ u8 speed = adev->dma_mode;
+ int devid = adev->devno;
+ u8 udma_enable;
+
+ static const /* ISP RTC */
+ u8 timings[][2] = { { 0, 0 },
+ { 0, 0 },
+ { 1, 0 },
+ { 2, 1 },
+ { 2, 3 }, };
+
+ pci_read_config_word(dev, 0x40, &master_data);
+ pci_read_config_byte(dev, 0x48, &udma_enable);
+
+ if (speed >= XFER_UDMA_0) {
+ unsigned int udma = adev->dma_mode - XFER_UDMA_0;
+ u16 udma_timing;
+ u16 ideconf;
+ int u_clock, u_speed;
+
+ /* Clocks follow the PIIX style */
+ u_speed = min(2 - (udma & 1), udma);
+ if (udma == 5)
+ u_clock = 0x1000; /* 100Mhz */
+ else if (udma > 2)
+ u_clock = 1; /* 66Mhz */
+ else
+ u_clock = 0; /* 33Mhz */
+
+ udma_enable |= (1 << devid);
+
+ /* Load the UDMA mode number */
+ pci_read_config_word(dev, 0x4A, &udma_timing);
+ udma_timing &= ~(3 << (4 * devid));
+ udma_timing |= (udma & 3) << (4 * devid);
+ pci_write_config_word(dev, 0x4A, udma_timing);
+
+ /* Load the clock selection */
+ pci_read_config_word(dev, 0x54, &ideconf);
+ ideconf &= ~(0x1001 << devid);
+ ideconf |= u_clock << devid;
+ pci_write_config_word(dev, 0x54, ideconf);
+ } else {
+ /*
+ * MWDMA is driven by the PIO timings. We must also enable
+ * IORDY unconditionally along with TIME1. PPE has already
+ * been set when the PIO timing was set.
+ */
+ unsigned int mwdma = adev->dma_mode - XFER_MW_DMA_0;
+ unsigned int control;
+ u8 slave_data;
+ static const unsigned int needed_pio[3] = {
+ XFER_PIO_0, XFER_PIO_3, XFER_PIO_4
+ };
+ int pio = needed_pio[mwdma] - XFER_PIO_0;
+
+ control = 3; /* IORDY|TIME1 */
+
+ /* If the drive MWDMA is faster than it can do PIO then
+ we must force PIO into PIO0 */
+
+ if (adev->pio_mode < needed_pio[mwdma])
+ /* Enable DMA timing only */
+ control |= 8; /* PIO cycles in PIO0 */
+
+ if (devid) { /* Slave */
+ master_data &= 0xFF4F; /* Mask out IORDY|TIME1|DMAONLY */
+ master_data |= control << 4;
+ pci_read_config_byte(dev, 0x44, &slave_data);
+ slave_data &= (0x0F + 0xE1 * ap->port_no);
+ /* Load the matching timing */
+ slave_data |= ((timings[pio][0] << 2) | timings[pio][1]) << (ap->port_no ? 4 : 0);
+ pci_write_config_byte(dev, 0x44, slave_data);
+ } else { /* Master */
+ master_data &= 0xCCF4; /* Mask out IORDY|TIME1|DMAONLY
+ and master timing bits */
+ master_data |= control;
+ master_data |=
+ (timings[pio][0] << 12) |
+ (timings[pio][1] << 8);
+ }
+ udma_enable &= ~(1 << devid);
+ pci_write_config_word(dev, 0x40, master_data);
+ }
+ pci_write_config_byte(dev, 0x48, udma_enable);
+}
+
+static struct scsi_host_template it8213_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .max_sectors = ATA_MAX_SECTORS,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .bios_param = ata_std_bios_param,
+ .resume = ata_scsi_device_resume,
+ .suspend = ata_scsi_device_suspend,
+};
+
+static const struct ata_port_operations it8213_ops = {
+ .port_disable = ata_port_disable,
+ .set_piomode = it8213_set_piomode,
+ .set_dmamode = it8213_set_dmamode,
+ .mode_filter = ata_pci_default_filter,
+
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = it8213_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+ .data_xfer = ata_data_xfer,
+
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
+
+ .port_start = ata_port_start,
+};
+
+
+/**
+ * it8213_init_one - Register 8213 ATA PCI device with kernel services
+ * @pdev: PCI device to register
+ * @ent: Entry in it8213_pci_tbl matching with @pdev
+ *
+ * Called from kernel PCI layer.
+ *
+ * LOCKING:
+ * Inherited from PCI layer (may sleep).
+ *
+ * RETURNS:
+ * Zero on success, or -ERRNO value.
+ */
+
+static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ static int printed_version;
+ static struct ata_port_info info = {
+ .sht = &it8213_sht,
+ .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x1f, /* UDMA 100 */
+ .port_ops = &it8213_ops,
+ };
+ static struct ata_port_info *port_info[2] = { &info, &info };
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev,
+ "version " DRV_VERSION "\n");
+
+ /* Current IT8213 stuff is single port */
+ return ata_pci_init_one(pdev, port_info, 1);
+}
+
+static const struct pci_device_id it8213_pci_tbl[] = {
+ { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8213), },
+
+ { } /* terminate list */
+};
+
+static struct pci_driver it8213_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = it8213_pci_tbl,
+ .probe = it8213_init_one,
+ .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
+};
+
+static int __init it8213_init(void)
+{
+ return pci_register_driver(&it8213_pci_driver);
+}
+
+static void __exit it8213_exit(void)
+{
+ pci_unregister_driver(&it8213_pci_driver);
+}
+
+module_init(it8213_init);
+module_exit(it8213_exit);
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("SCSI low-level driver for the ITE 8213");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, it8213_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index e8afd486434a..73394c75be42 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -492,7 +492,7 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
/* Bits 5 and 6 indicate if DMA is active on master/slave */
/* It is possible that BMDMA isn't allocated */
if (ap->ioaddr.bmdma_addr)
- dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
for (i = 0; i < ATA_MAX_DEVICES; i++) {
struct ata_device *dev = &ap->device[i];
@@ -531,23 +531,9 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
static void it821x_dev_config(struct ata_port *ap, struct ata_device *adev)
{
- unsigned char model_num[40];
- char *s;
- unsigned int len;
-
- /* This block ought to be a library routine as it is in several
- drivers now */
-
- ata_id_string(adev->id, model_num, ATA_ID_PROD_OFS,
- sizeof(model_num));
- s = &model_num[0];
- len = strnlen(s, sizeof(model_num));
-
- /* ATAPI specifies that empty space is blank-filled; remove blanks */
- while ((len > 0) && (s[len - 1] == ' ')) {
- len--;
- s[len] = 0;
- }
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
+
+ ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
if (adev->max_sectors > 255)
adev->max_sectors = 255;
@@ -608,14 +594,10 @@ static int it821x_port_start(struct ata_port *ap)
if (ret < 0)
return ret;
- ap->private_data = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL);
- if (ap->private_data == NULL) {
- ata_port_stop(ap);
+ itdev = devm_kzalloc(&pdev->dev, sizeof(struct it821x_dev), GFP_KERNEL);
+ if (itdev == NULL)
return -ENOMEM;
- }
-
- itdev = ap->private_data;
- memset(itdev, 0, sizeof(struct it821x_dev));
+ ap->private_data = itdev;
pci_read_config_byte(pdev, 0x50, &conf);
@@ -646,20 +628,6 @@ static int it821x_port_start(struct ata_port *ap)
return 0;
}
-/**
- * it821x_port_stop - port shutdown
- * @ap: ATA port being removed
- *
- * Release the private objects we added in it821x_port_start
- */
-
-static void it821x_port_stop(struct ata_port *ap) {
- kfree(ap->private_data);
- ap->private_data = NULL; /* We want an OOPS if we reuse this
- too late! */
- ata_port_stop(ap);
-}
-
static struct scsi_host_template it821x_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -706,14 +674,14 @@ static struct ata_port_operations it821x_smart_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = it821x_smart_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = it821x_port_start,
- .port_stop = it821x_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations it821x_passthru_port_ops = {
@@ -742,14 +710,14 @@ static struct ata_port_operations it821x_passthru_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = it821x_passthru_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_clear = ata_bmdma_irq_clear,
.irq_handler = ata_interrupt,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = it821x_port_start,
- .port_stop = it821x_port_stop,
- .host_stop = ata_host_stop
};
static void __devinit it821x_disable_raid(struct pci_dev *pdev)
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 23b8aab3ebd8..3222ac7b945d 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -95,14 +95,6 @@ static void ixp4xx_irq_clear(struct ata_port *ap)
{
}
-static void ixp4xx_host_stop (struct ata_host *host)
-{
- struct ixp4xx_pata_data *data = host->dev->platform_data;
-
- iounmap(data->cs0);
- iounmap(data->cs1);
-}
-
static struct scsi_host_template ixp4xx_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -139,10 +131,10 @@ static struct ata_port_operations ixp4xx_port_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ixp4xx_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ixp4xx_host_stop,
.phy_reset = ixp4xx_phy_reset,
};
@@ -150,9 +142,9 @@ static struct ata_port_operations ixp4xx_port_ops = {
static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
struct ixp4xx_pata_data *data)
{
- ioaddr->cmd_addr = (unsigned long) data->cs0;
- ioaddr->altstatus_addr = (unsigned long) data->cs1 + 0x06;
- ioaddr->ctl_addr = (unsigned long) data->cs1 + 0x06;
+ ioaddr->cmd_addr = data->cs0;
+ ioaddr->altstatus_addr = data->cs1 + 0x06;
+ ioaddr->ctl_addr = data->cs1 + 0x06;
ata_std_ports(ioaddr);
@@ -162,19 +154,19 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
* ixp4xx in little endian mode.
*/
- ioaddr->data_addr ^= 0x02;
- ioaddr->cmd_addr ^= 0x03;
- ioaddr->altstatus_addr ^= 0x03;
- ioaddr->ctl_addr ^= 0x03;
- ioaddr->error_addr ^= 0x03;
- ioaddr->feature_addr ^= 0x03;
- ioaddr->nsect_addr ^= 0x03;
- ioaddr->lbal_addr ^= 0x03;
- ioaddr->lbam_addr ^= 0x03;
- ioaddr->lbah_addr ^= 0x03;
- ioaddr->device_addr ^= 0x03;
- ioaddr->status_addr ^= 0x03;
- ioaddr->command_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->data_addr ^= 0x02;
+ *(unsigned long *)&ioaddr->cmd_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->altstatus_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->ctl_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->error_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->feature_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->nsect_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->lbal_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->lbam_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->lbah_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->device_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->status_addr ^= 0x03;
+ *(unsigned long *)&ioaddr->command_addr ^= 0x03;
#endif
}
@@ -195,8 +187,8 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
- data->cs0 = ioremap(cs0->start, 0x1000);
- data->cs1 = ioremap(cs1->start, 0x1000);
+ data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
+ data->cs1 = devm_ioremap(&pdev->dev, cs1->start, 0x1000);
irq = platform_get_irq(pdev, 0);
if (irq)
@@ -238,7 +230,7 @@ static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
{
struct ata_host *host = platform_get_drvdata(dev);
- ata_host_remove(host);
+ ata_host_detach(host);
platform_set_drvdata(dev, NULL);
return 0;
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index d50264af2848..7a635dd326f8 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -161,16 +161,16 @@ static const struct ata_port_operations jmicron_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
/* IRQ-related hooks */
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
/* Generic PATA PCI ATA helpers */
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
@@ -221,7 +221,7 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
static int jmicron_reinit_one(struct pci_dev *pdev)
{
u32 reg;
-
+
switch(pdev->device) {
case PCI_DEVICE_ID_JMICRON_JMB368:
break;
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 581cb33c6f45..4223e10de6a0 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -164,14 +164,14 @@ static struct ata_port_operations simple_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .data_xfer = ata_data_xfer_noirq,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations legacy_port_ops = {
@@ -189,14 +189,14 @@ static struct ata_port_operations legacy_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .data_xfer = ata_data_xfer_noirq,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -257,31 +257,33 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig
local_irq_save(flags);
/* Perform the 32bit I/O synchronization sequence */
- inb(ap->ioaddr.nsect_addr);
- inb(ap->ioaddr.nsect_addr);
- inb(ap->ioaddr.nsect_addr);
+ ioread8(ap->ioaddr.nsect_addr);
+ ioread8(ap->ioaddr.nsect_addr);
+ ioread8(ap->ioaddr.nsect_addr);
/* Now the data */
if (write_data)
- outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
- insl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
if (unlikely(slop)) {
u32 pad;
if (write_data) {
memcpy(&pad, buf + buflen - slop, slop);
- outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ pad = le32_to_cpu(pad);
+ iowrite32(pad, ap->ioaddr.data_addr);
} else {
- pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
+ pad = ioread32(ap->ioaddr.data_addr);
+ pad = cpu_to_le16(pad);
memcpy(buf + buflen - slop, &pad, slop);
}
}
local_irq_restore(flags);
}
else
- ata_pio_data_xfer_noirq(adev, buf, buflen, write_data);
+ ata_data_xfer_noirq(adev, buf, buflen, write_data);
}
static struct ata_port_operations pdc20230_port_ops = {
@@ -303,10 +305,10 @@ static struct ata_port_operations pdc20230_port_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -332,8 +334,8 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev)
inb(0x3E6);
inb(0x3E6);
- outb(recover << 4 | active, ap->ioaddr.device_addr);
- inb(ap->ioaddr.status_addr);
+ iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
+ ioread8(ap->ioaddr.status_addr);
}
static struct ata_port_operations ht6560a_port_ops = {
@@ -351,14 +353,14 @@ static struct ata_port_operations ht6560a_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer, /* Check vlb/noirq */
+ .data_xfer = ata_data_xfer, /* Check vlb/noirq */
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -387,7 +389,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
inb(0x3E6);
inb(0x3E6);
- outb(recover << 4 | active, ap->ioaddr.device_addr);
+ iowrite8(recover << 4 | active, ap->ioaddr.device_addr);
if (adev->class != ATA_DEV_ATA) {
u8 rconf = inb(0x3E6);
@@ -396,7 +398,7 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
outb(rconf, 0x3E6);
}
}
- inb(ap->ioaddr.status_addr);
+ ioread8(ap->ioaddr.status_addr);
}
static struct ata_port_operations ht6560b_port_ops = {
@@ -414,14 +416,14 @@ static struct ata_port_operations ht6560b_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer, /* FIXME: Check 32bit and noirq */
+ .data_xfer = ata_data_xfer, /* FIXME: Check 32bit and noirq */
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -464,12 +466,12 @@ static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev
u8 rc;
/* Enter configuration mode */
- inw(ap->ioaddr.error_addr);
- inw(ap->ioaddr.error_addr);
- outb(3, ap->ioaddr.nsect_addr);
+ ioread16(ap->ioaddr.error_addr);
+ ioread16(ap->ioaddr.error_addr);
+ iowrite8(3, ap->ioaddr.nsect_addr);
/* Read VLB clock strapping */
- clock = 1000000000 / khz[inb(ap->ioaddr.lbah_addr) & 0x03];
+ clock = 1000000000 / khz[ioread8(ap->ioaddr.lbah_addr) & 0x03];
/* Get the timing data in cycles */
ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000);
@@ -487,33 +489,33 @@ static void opti82c611a_set_piomode(struct ata_port *ap, struct ata_device *adev
setup = FIT(t.setup, 1, 4) - 1;
/* Select the right timing bank for write timing */
- rc = inb(ap->ioaddr.lbal_addr);
+ rc = ioread8(ap->ioaddr.lbal_addr);
rc &= 0x7F;
rc |= (adev->devno << 7);
- outb(rc, ap->ioaddr.lbal_addr);
+ iowrite8(rc, ap->ioaddr.lbal_addr);
/* Write the timings */
- outb(active << 4 | recover, ap->ioaddr.error_addr);
+ iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
/* Select the right bank for read timings, also
load the shared timings for address */
- rc = inb(ap->ioaddr.device_addr);
+ rc = ioread8(ap->ioaddr.device_addr);
rc &= 0xC0;
rc |= adev->devno; /* Index select */
rc |= (setup << 4) | 0x04;
- outb(rc, ap->ioaddr.device_addr);
+ iowrite8(rc, ap->ioaddr.device_addr);
/* Load the read timings */
- outb(active << 4 | recover, ap->ioaddr.data_addr);
+ iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
/* Ensure the timing register mode is right */
- rc = inb (ap->ioaddr.lbal_addr);
+ rc = ioread8(ap->ioaddr.lbal_addr);
rc &= 0x73;
rc |= 0x84;
- outb(rc, ap->ioaddr.lbal_addr);
+ iowrite8(rc, ap->ioaddr.lbal_addr);
/* Exit command mode */
- outb(0x83, ap->ioaddr.nsect_addr);
+ iowrite8(0x83, ap->ioaddr.nsect_addr);
}
@@ -532,14 +534,14 @@ static struct ata_port_operations opti82c611a_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/*
@@ -563,9 +565,9 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
sysclk = opti_syscfg(0xAC) & 0xC0; /* BIOS set */
/* Enter configuration mode */
- inw(ap->ioaddr.error_addr);
- inw(ap->ioaddr.error_addr);
- outb(3, ap->ioaddr.nsect_addr);
+ ioread16(ap->ioaddr.error_addr);
+ ioread16(ap->ioaddr.error_addr);
+ iowrite8(3, ap->ioaddr.nsect_addr);
/* Read VLB clock strapping */
clock = 1000000000 / khz[sysclk];
@@ -586,33 +588,33 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
setup = FIT(t.setup, 1, 4) - 1;
/* Select the right timing bank for write timing */
- rc = inb(ap->ioaddr.lbal_addr);
+ rc = ioread8(ap->ioaddr.lbal_addr);
rc &= 0x7F;
rc |= (adev->devno << 7);
- outb(rc, ap->ioaddr.lbal_addr);
+ iowrite8(rc, ap->ioaddr.lbal_addr);
/* Write the timings */
- outb(active << 4 | recover, ap->ioaddr.error_addr);
+ iowrite8(active << 4 | recover, ap->ioaddr.error_addr);
/* Select the right bank for read timings, also
load the shared timings for address */
- rc = inb(ap->ioaddr.device_addr);
+ rc = ioread8(ap->ioaddr.device_addr);
rc &= 0xC0;
rc |= adev->devno; /* Index select */
rc |= (setup << 4) | 0x04;
- outb(rc, ap->ioaddr.device_addr);
+ iowrite8(rc, ap->ioaddr.device_addr);
/* Load the read timings */
- outb(active << 4 | recover, ap->ioaddr.data_addr);
+ iowrite8(active << 4 | recover, ap->ioaddr.data_addr);
/* Ensure the timing register mode is right */
- rc = inb (ap->ioaddr.lbal_addr);
+ rc = ioread8(ap->ioaddr.lbal_addr);
rc &= 0x73;
rc |= 0x84;
- outb(rc, ap->ioaddr.lbal_addr);
+ iowrite8(rc, ap->ioaddr.lbal_addr);
/* Exit command mode */
- outb(0x83, ap->ioaddr.nsect_addr);
+ iowrite8(0x83, ap->ioaddr.nsect_addr);
/* We need to know this for quad device on the MVB */
ap->host->private_data = ap;
@@ -662,14 +664,14 @@ static struct ata_port_operations opti82c46x_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = opti82c46x_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
@@ -689,21 +691,26 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
struct legacy_data *ld = &legacy_data[nr_legacy_host];
struct ata_probe_ent ae;
struct platform_device *pdev;
- int ret = -EBUSY;
struct ata_port_operations *ops = &legacy_port_ops;
+ void __iomem *io_addr, *ctrl_addr;
int pio_modes = pio_mask;
u32 mask = (1 << port);
-
- if (request_region(io, 8, "pata_legacy") == NULL)
- return -EBUSY;
- if (request_region(ctrl, 1, "pata_legacy") == NULL)
- goto fail_io;
+ int ret;
pdev = platform_device_register_simple(DRV_NAME, nr_legacy_host, NULL, 0);
- if (IS_ERR(pdev)) {
- ret = PTR_ERR(pdev);
- goto fail_dev;
- }
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ ret = -EBUSY;
+ if (devm_request_region(&pdev->dev, io, 8, "pata_legacy") == NULL ||
+ devm_request_region(&pdev->dev, ctrl, 1, "pata_legacy") == NULL)
+ goto fail;
+
+ ret = -ENOMEM;
+ io_addr = devm_ioport_map(&pdev->dev, io, 8);
+ ctrl_addr = devm_ioport_map(&pdev->dev, ctrl, 1);
+ if (!io_addr || !ctrl_addr)
+ goto fail;
if (ht6560a & mask) {
ops = &ht6560a_port_ops;
@@ -770,27 +777,22 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
ae.irq = irq;
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
- ae.port[0].cmd_addr = io;
- ae.port[0].altstatus_addr = ctrl;
- ae.port[0].ctl_addr = ctrl;
+ ae.port[0].cmd_addr = io_addr;
+ ae.port[0].altstatus_addr = ctrl_addr;
+ ae.port[0].ctl_addr = ctrl_addr;
ata_std_ports(&ae.port[0]);
ae.private_data = ld;
- ret = ata_device_add(&ae);
- if (ret == 0) {
- ret = -ENODEV;
+ ret = -ENODEV;
+ if (!ata_device_add(&ae))
goto fail;
- }
+
legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev);
ld->platform_dev = pdev;
return 0;
fail:
platform_device_unregister(pdev);
-fail_dev:
- release_region(ctrl, 1);
-fail_io:
- release_region(io, 8);
return ret;
}
@@ -923,15 +925,11 @@ static __exit void legacy_exit(void)
for (i = 0; i < nr_legacy_host; i++) {
struct legacy_data *ld = &legacy_data[i];
- struct ata_port *ap =legacy_host[i]->ports[0];
- unsigned long io = ap->ioaddr.cmd_addr;
- unsigned long ctrl = ap->ioaddr.ctl_addr;
- ata_host_remove(legacy_host[i]);
+
+ ata_host_detach(legacy_host[i]);
platform_device_unregister(ld->platform_dev);
if (ld->timing)
release_region(ld->timing, 2);
- release_region(io, 8);
- release_region(ctrl, 1);
}
}
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 1c810ea00253..13a70ac6f1dc 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -45,10 +45,10 @@ static int marvell_pre_reset(struct ata_port *ap)
for(i = 0; i <= 0x0F; i++)
printk("%02X:%02X ", i, readb(barp + i));
printk("\n");
-
+
devices = readl(barp + 0x0C);
pci_iounmap(pdev, barp);
-
+
if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
(!(devices & 0x10))) /* PATA enable ? */
return -ENOENT;
@@ -57,7 +57,7 @@ static int marvell_pre_reset(struct ata_port *ap)
switch(ap->port_no)
{
case 0:
- if (inb(ap->ioaddr.bmdma_addr + 1) & 1)
+ if (ioread8(ap->ioaddr.bmdma_addr + 1) & 1)
ap->cbl = ATA_CBL_PATA40;
else
ap->cbl = ATA_CBL_PATA80;
@@ -129,16 +129,16 @@ static const struct ata_port_operations marvell_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
/* Timeout handling */
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
/* Generic PATA PCI ATA helpers */
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
new file mode 100644
index 000000000000..d7378df44970
--- /dev/null
+++ b/drivers/ata/pata_mpc52xx.c
@@ -0,0 +1,538 @@
+/*
+ * drivers/ata/pata_mpc52xx.c
+ *
+ * libata driver for the Freescale MPC52xx on-chip IDE interface
+ *
+ * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003 Mipsys - Benjamin Herrenschmidt
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/libata.h>
+
+#include <asm/types.h>
+#include <asm/prom.h>
+#include <asm/of_platform.h>
+#include <asm/mpc52xx.h>
+
+
+#define DRV_NAME "mpc52xx_ata"
+#define DRV_VERSION "0.1.0"
+
+
+/* Private structures used by the driver */
+struct mpc52xx_ata_timings {
+ u32 pio1;
+ u32 pio2;
+};
+
+struct mpc52xx_ata_priv {
+ unsigned int ipb_period;
+ struct mpc52xx_ata __iomem * ata_regs;
+ int ata_irq;
+ struct mpc52xx_ata_timings timings[2];
+ int csel;
+};
+
+
+/* ATAPI-4 PIO specs (in ns) */
+static const int ataspec_t0[5] = {600, 383, 240, 180, 120};
+static const int ataspec_t1[5] = { 70, 50, 30, 30, 25};
+static const int ataspec_t2_8[5] = {290, 290, 290, 80, 70};
+static const int ataspec_t2_16[5] = {165, 125, 100, 80, 70};
+static const int ataspec_t2i[5] = { 0, 0, 0, 70, 25};
+static const int ataspec_t4[5] = { 30, 20, 15, 10, 10};
+static const int ataspec_ta[5] = { 35, 35, 35, 35, 35};
+
+#define CALC_CLKCYC(c,v) ((((v)+(c)-1)/(c)))
+
+
+/* Bit definitions inside the registers */
+#define MPC52xx_ATA_HOSTCONF_SMR 0x80000000UL /* State machine reset */
+#define MPC52xx_ATA_HOSTCONF_FR 0x40000000UL /* FIFO Reset */
+#define MPC52xx_ATA_HOSTCONF_IE 0x02000000UL /* Enable interrupt in PIO */
+#define MPC52xx_ATA_HOSTCONF_IORDY 0x01000000UL /* Drive supports IORDY protocol */
+
+#define MPC52xx_ATA_HOSTSTAT_TIP 0x80000000UL /* Transaction in progress */
+#define MPC52xx_ATA_HOSTSTAT_UREP 0x40000000UL /* UDMA Read Extended Pause */
+#define MPC52xx_ATA_HOSTSTAT_RERR 0x02000000UL /* Read Error */
+#define MPC52xx_ATA_HOSTSTAT_WERR 0x01000000UL /* Write Error */
+
+#define MPC52xx_ATA_FIFOSTAT_EMPTY 0x01 /* FIFO Empty */
+
+#define MPC52xx_ATA_DMAMODE_WRITE 0x01 /* Write DMA */
+#define MPC52xx_ATA_DMAMODE_READ 0x02 /* Read DMA */
+#define MPC52xx_ATA_DMAMODE_UDMA 0x04 /* UDMA enabled */
+#define MPC52xx_ATA_DMAMODE_IE 0x08 /* Enable drive interrupt to CPU in DMA mode */
+#define MPC52xx_ATA_DMAMODE_FE 0x10 /* FIFO Flush enable in Rx mode */
+#define MPC52xx_ATA_DMAMODE_FR 0x20 /* FIFO Reset */
+#define MPC52xx_ATA_DMAMODE_HUT 0x40 /* Host UDMA burst terminate */
+
+
+/* Structure of the hardware registers */
+struct mpc52xx_ata {
+
+ /* Host interface registers */
+ u32 config; /* ATA + 0x00 Host configuration */
+ u32 host_status; /* ATA + 0x04 Host controller status */
+ u32 pio1; /* ATA + 0x08 PIO Timing 1 */
+ u32 pio2; /* ATA + 0x0c PIO Timing 2 */
+ u32 mdma1; /* ATA + 0x10 MDMA Timing 1 */
+ u32 mdma2; /* ATA + 0x14 MDMA Timing 2 */
+ u32 udma1; /* ATA + 0x18 UDMA Timing 1 */
+ u32 udma2; /* ATA + 0x1c UDMA Timing 2 */
+ u32 udma3; /* ATA + 0x20 UDMA Timing 3 */
+ u32 udma4; /* ATA + 0x24 UDMA Timing 4 */
+ u32 udma5; /* ATA + 0x28 UDMA Timing 5 */
+ u32 share_cnt; /* ATA + 0x2c ATA share counter */
+ u32 reserved0[3];
+
+ /* FIFO registers */
+ u32 fifo_data; /* ATA + 0x3c */
+ u8 fifo_status_frame; /* ATA + 0x40 */
+ u8 fifo_status; /* ATA + 0x41 */
+ u16 reserved7[1];
+ u8 fifo_control; /* ATA + 0x44 */
+ u8 reserved8[5];
+ u16 fifo_alarm; /* ATA + 0x4a */
+ u16 reserved9;
+ u16 fifo_rdp; /* ATA + 0x4e */
+ u16 reserved10;
+ u16 fifo_wrp; /* ATA + 0x52 */
+ u16 reserved11;
+ u16 fifo_lfrdp; /* ATA + 0x56 */
+ u16 reserved12;
+ u16 fifo_lfwrp; /* ATA + 0x5a */
+
+ /* Drive TaskFile registers */
+ u8 tf_control; /* ATA + 0x5c TASKFILE Control/Alt Status */
+ u8 reserved13[3];
+ u16 tf_data; /* ATA + 0x60 TASKFILE Data */
+ u16 reserved14;
+ u8 tf_features; /* ATA + 0x64 TASKFILE Features/Error */
+ u8 reserved15[3];
+ u8 tf_sec_count; /* ATA + 0x68 TASKFILE Sector Count */
+ u8 reserved16[3];
+ u8 tf_sec_num; /* ATA + 0x6c TASKFILE Sector Number */
+ u8 reserved17[3];
+ u8 tf_cyl_low; /* ATA + 0x70 TASKFILE Cylinder Low */
+ u8 reserved18[3];
+ u8 tf_cyl_high; /* ATA + 0x74 TASKFILE Cylinder High */
+ u8 reserved19[3];
+ u8 tf_dev_head; /* ATA + 0x78 TASKFILE Device/Head */
+ u8 reserved20[3];
+ u8 tf_command; /* ATA + 0x7c TASKFILE Command/Status */
+ u8 dma_mode; /* ATA + 0x7d ATA Host DMA Mode configuration */
+ u8 reserved21[2];
+};
+
+
+/* ======================================================================== */
+/* Aux fns */
+/* ======================================================================== */
+
+
+/* MPC52xx low level hw control */
+
+static int
+mpc52xx_ata_compute_pio_timings(struct mpc52xx_ata_priv *priv, int dev, int pio)
+{
+ struct mpc52xx_ata_timings *timing = &priv->timings[dev];
+ unsigned int ipb_period = priv->ipb_period;
+ unsigned int t0, t1, t2_8, t2_16, t2i, t4, ta;
+
+ if ((pio<0) || (pio>4))
+ return -EINVAL;
+
+ t0 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t0[pio]);
+ t1 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t1[pio]);
+ t2_8 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2_8[pio]);
+ t2_16 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2_16[pio]);
+ t2i = CALC_CLKCYC(ipb_period, 1000 * ataspec_t2i[pio]);
+ t4 = CALC_CLKCYC(ipb_period, 1000 * ataspec_t4[pio]);
+ ta = CALC_CLKCYC(ipb_period, 1000 * ataspec_ta[pio]);
+
+ timing->pio1 = (t0 << 24) | (t2_8 << 16) | (t2_16 << 8) | (t2i);
+ timing->pio2 = (t4 << 24) | (t1 << 16) | (ta << 8);
+
+ return 0;
+}
+
+static void
+mpc52xx_ata_apply_timings(struct mpc52xx_ata_priv *priv, int device)
+{
+ struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+ struct mpc52xx_ata_timings *timing = &priv->timings[device];
+
+ out_be32(&regs->pio1, timing->pio1);
+ out_be32(&regs->pio2, timing->pio2);
+ out_be32(&regs->mdma1, 0);
+ out_be32(&regs->mdma2, 0);
+ out_be32(&regs->udma1, 0);
+ out_be32(&regs->udma2, 0);
+ out_be32(&regs->udma3, 0);
+ out_be32(&regs->udma4, 0);
+ out_be32(&regs->udma5, 0);
+
+ priv->csel = device;
+}
+
+static int
+mpc52xx_ata_hw_init(struct mpc52xx_ata_priv *priv)
+{
+ struct mpc52xx_ata __iomem *regs = priv->ata_regs;
+ int tslot;
+
+ /* Clear share_cnt (all sample code do this ...) */
+ out_be32(&regs->share_cnt, 0);
+
+ /* Configure and reset host */
+ out_be32(&regs->config,
+ MPC52xx_ATA_HOSTCONF_IE |
+ MPC52xx_ATA_HOSTCONF_IORDY |
+ MPC52xx_ATA_HOSTCONF_SMR |
+ MPC52xx_ATA_HOSTCONF_FR);
+
+ udelay(10);
+
+ out_be32(&regs->config,
+ MPC52xx_ATA_HOSTCONF_IE |
+ MPC52xx_ATA_HOSTCONF_IORDY);
+
+ /* Set the time slot to 1us */
+ tslot = CALC_CLKCYC(priv->ipb_period, 1000000);
+ out_be32(&regs->share_cnt, tslot << 16 );
+
+ /* Init timings to PIO0 */
+ memset(priv->timings, 0x00, 2*sizeof(struct mpc52xx_ata_timings));
+
+ mpc52xx_ata_compute_pio_timings(priv, 0, 0);
+ mpc52xx_ata_compute_pio_timings(priv, 1, 0);
+
+ mpc52xx_ata_apply_timings(priv, 0);
+
+ return 0;
+}
+
+
+/* ======================================================================== */
+/* libata driver */
+/* ======================================================================== */
+
+static void
+mpc52xx_ata_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+ int pio, rv;
+
+ pio = adev->pio_mode - XFER_PIO_0;
+
+ rv = mpc52xx_ata_compute_pio_timings(priv, adev->devno, pio);
+
+ if (rv) {
+ printk(KERN_ERR DRV_NAME
+ ": Trying to select invalid PIO mode %d\n", pio);
+ return;
+ }
+
+ mpc52xx_ata_apply_timings(priv, adev->devno);
+}
+static void
+mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
+{
+ struct mpc52xx_ata_priv *priv = ap->host->private_data;
+
+ if (device != priv->csel)
+ mpc52xx_ata_apply_timings(priv, device);
+
+ ata_std_dev_select(ap,device);
+}
+
+static void
+mpc52xx_ata_error_handler(struct ata_port *ap)
+{
+ ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
+ ata_std_postreset);
+}
+
+
+
+static struct scsi_host_template mpc52xx_ata_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .max_sectors = ATA_MAX_SECTORS,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = ata_scsi_slave_config,
+ .bios_param = ata_std_bios_param,
+};
+
+static struct ata_port_operations mpc52xx_ata_port_ops = {
+ .port_disable = ata_port_disable,
+ .set_piomode = mpc52xx_ata_set_piomode,
+ .dev_select = mpc52xx_ata_dev_select,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = mpc52xx_ata_error_handler,
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+ .data_xfer = ata_data_xfer,
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
+ .port_start = ata_port_start,
+};
+
+static struct ata_probe_ent mpc52xx_ata_probe_ent = {
+ .port_ops = &mpc52xx_ata_port_ops,
+ .sht = &mpc52xx_ata_sht,
+ .n_ports = 1,
+ .pio_mask = 0x1f, /* Up to PIO4 */
+ .mwdma_mask = 0x00, /* No MWDMA */
+ .udma_mask = 0x00, /* No UDMA */
+ .port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+ .irq_flags = 0,
+};
+
+static int __devinit
+mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
+{
+ struct ata_probe_ent *ae = &mpc52xx_ata_probe_ent;
+ struct ata_ioports *aio = &ae->port[0];
+ int rv;
+
+ INIT_LIST_HEAD(&ae->node);
+ ae->dev = dev;
+ ae->irq = priv->ata_irq;
+
+ aio->cmd_addr = 0; /* Don't have a classic reg block */
+ aio->altstatus_addr = &priv->ata_regs->tf_control;
+ aio->ctl_addr = &priv->ata_regs->tf_control;
+ aio->data_addr = &priv->ata_regs->tf_data;
+ aio->error_addr = &priv->ata_regs->tf_features;
+ aio->feature_addr = &priv->ata_regs->tf_features;
+ aio->nsect_addr = &priv->ata_regs->tf_sec_count;
+ aio->lbal_addr = &priv->ata_regs->tf_sec_num;
+ aio->lbam_addr = &priv->ata_regs->tf_cyl_low;
+ aio->lbah_addr = &priv->ata_regs->tf_cyl_high;
+ aio->device_addr = &priv->ata_regs->tf_dev_head;
+ aio->status_addr = &priv->ata_regs->tf_command;
+ aio->command_addr = &priv->ata_regs->tf_command;
+
+ ae->private_data = priv;
+
+ rv = ata_device_add(ae);
+
+ return rv ? 0 : -EINVAL;
+}
+
+static struct mpc52xx_ata_priv *
+mpc52xx_ata_remove_one(struct device *dev)
+{
+ struct ata_host *host = dev_get_drvdata(dev);
+ struct mpc52xx_ata_priv *priv = host->private_data;
+
+ ata_host_detach(host);
+
+ return priv;
+}
+
+
+/* ======================================================================== */
+/* OF Platform driver */
+/* ======================================================================== */
+
+static int __devinit
+mpc52xx_ata_probe(struct of_device *op, const struct of_device_id *match)
+{
+ unsigned int ipb_freq;
+ struct resource res_mem;
+ int ata_irq = NO_IRQ;
+ struct mpc52xx_ata __iomem *ata_regs;
+ struct mpc52xx_ata_priv *priv;
+ int rv;
+
+ /* Get ipb frequency */
+ ipb_freq = mpc52xx_find_ipb_freq(op->node);
+ if (!ipb_freq) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Unable to find IPB Bus frequency\n" );
+ return -ENODEV;
+ }
+
+ /* Get IRQ and register */
+ rv = of_address_to_resource(op->node, 0, &res_mem);
+ if (rv) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while parsing device node resource\n" );
+ return rv;
+ }
+
+ ata_irq = irq_of_parse_and_map(op->node, 0);
+ if (ata_irq == NO_IRQ) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while mapping the irq\n");
+ return -EINVAL;
+ }
+
+ /* Request mem region */
+ if (!devm_request_mem_region(&op->dev, res_mem.start,
+ sizeof(struct mpc52xx_ata), DRV_NAME)) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while requesting mem region\n");
+ rv = -EBUSY;
+ goto err;
+ }
+
+ /* Remap registers */
+ ata_regs = devm_ioremap(&op->dev, res_mem.start,
+ sizeof(struct mpc52xx_ata));
+ if (!ata_regs) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while mapping register set\n");
+ rv = -ENOMEM;
+ goto err;
+ }
+
+ /* Prepare our private structure */
+ priv = devm_kzalloc(&op->dev, sizeof(struct mpc52xx_ata_priv),
+ GFP_ATOMIC);
+ if (!priv) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while allocating private structure\n");
+ rv = -ENOMEM;
+ goto err;
+ }
+
+ priv->ipb_period = 1000000000 / (ipb_freq / 1000);
+ priv->ata_regs = ata_regs;
+ priv->ata_irq = ata_irq;
+ priv->csel = -1;
+
+ /* Init the hw */
+ rv = mpc52xx_ata_hw_init(priv);
+ if (rv) {
+ printk(KERN_ERR DRV_NAME ": Error during HW init\n");
+ goto err;
+ }
+
+ /* Register ourselves to libata */
+ rv = mpc52xx_ata_init_one(&op->dev, priv);
+ if (rv) {
+ printk(KERN_ERR DRV_NAME ": "
+ "Error while registering to ATA layer\n");
+ return rv;
+ }
+
+ /* Done */
+ return 0;
+
+ /* Error path */
+err:
+ irq_dispose_mapping(ata_irq);
+ return rv;
+}
+
+static int
+mpc52xx_ata_remove(struct of_device *op)
+{
+ struct mpc52xx_ata_priv *priv;
+
+ priv = mpc52xx_ata_remove_one(&op->dev);
+ irq_dispose_mapping(priv->ata_irq);
+
+ return 0;
+}
+
+
+#ifdef CONFIG_PM
+
+static int
+mpc52xx_ata_suspend(struct of_device *op, pm_message_t state)
+{
+ return 0; /* FIXME : What to do here ? */
+}
+
+static int
+mpc52xx_ata_resume(struct of_device *op)
+{
+ return 0; /* FIXME : What to do here ? */
+}
+
+#endif
+
+
+static struct of_device_id mpc52xx_ata_of_match[] = {
+ {
+ .compatible = "mpc5200-ata",
+ },
+ {
+ .compatible = "mpc52xx-ata",
+ },
+ {},
+};
+
+
+static struct of_platform_driver mpc52xx_ata_of_platform_driver = {
+ .owner = THIS_MODULE,
+ .name = DRV_NAME,
+ .match_table = mpc52xx_ata_of_match,
+ .probe = mpc52xx_ata_probe,
+ .remove = mpc52xx_ata_remove,
+#ifdef CONFIG_PM
+ .suspend = mpc52xx_ata_suspend,
+ .resume = mpc52xx_ata_resume,
+#endif
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+
+/* ======================================================================== */
+/* Module */
+/* ======================================================================== */
+
+static int __init
+mpc52xx_ata_init(void)
+{
+ printk(KERN_INFO "ata: MPC52xx IDE/ATA libata driver\n");
+ return of_register_platform_driver(&mpc52xx_ata_of_platform_driver);
+}
+
+static void __exit
+mpc52xx_ata_exit(void)
+{
+ of_unregister_platform_driver(&mpc52xx_ata_of_platform_driver);
+}
+
+module_init(mpc52xx_ata_init);
+module_exit(mpc52xx_ata_exit);
+
+MODULE_AUTHOR("Sylvain Munaut <tnt@246tNt.com>");
+MODULE_DESCRIPTION("Freescale MPC52xx IDE/ATA libata driver");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(of, mpc52xx_ata_of_match);
+MODULE_VERSION(DRV_VERSION);
+
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index 4ccca938675e..ca8c965179b1 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -35,7 +35,7 @@
#include <linux/libata.h>
#define DRV_NAME "pata_mpiix"
-#define DRV_VERSION "0.7.3"
+#define DRV_VERSION "0.7.5"
enum {
IDETIM = 0x6C, /* IDE control register */
@@ -49,12 +49,9 @@ enum {
static int mpiix_pre_reset(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- static const struct pci_bits mpiix_enable_bits[] = {
- { 0x6D, 1, 0x80, 0x80 },
- { 0x6F, 1, 0x80, 0x80 }
- };
+ static const struct pci_bits mpiix_enable_bits = { 0x6D, 1, 0x80, 0x80 };
- if (!pci_test_config_bits(pdev, &mpiix_enable_bits[ap->port_no]))
+ if (!pci_test_config_bits(pdev, &mpiix_enable_bits))
return -ENOENT;
ap->cbl = ATA_CBL_PATA40;
return ata_std_prereset(ap);
@@ -80,8 +77,8 @@ static void mpiix_error_handler(struct ata_port *ap)
* @adev: ATA device
*
* Called to do the PIO mode setup. The MPIIX allows us to program the
- * IORDY sample point (2-5 clocks), recovery 1-4 clocks and whether
- * prefetching or iordy are used.
+ * IORDY sample point (2-5 clocks), recovery (1-4 clocks) and whether
+ * prefetching or IORDY are used.
*
* This would get very ugly because we can only program timing for one
* device at a time, the other gets PIO0. Fortunately libata calls
@@ -103,18 +100,19 @@ static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev)
{ 2, 3 }, };
pci_read_config_word(pdev, IDETIM, &idetim);
- /* Mask the IORDY/TIME/PPE0 bank for this device */
+
+ /* Mask the IORDY/TIME/PPE for this device */
if (adev->class == ATA_DEV_ATA)
- control |= PPE; /* PPE enable for disk */
+ control |= PPE; /* Enable prefetch/posting for disk */
if (ata_pio_need_iordy(adev))
- control |= IORDY; /* IORDY */
- if (pio > 0)
+ control |= IORDY;
+ if (pio > 1)
control |= FTIM; /* This drive is on the fast timing bank */
/* Mask out timing and clear both TIME bank selects */
idetim &= 0xCCEE;
- idetim &= ~(0x07 << (2 * adev->devno));
- idetim |= (control << (2 * adev->devno));
+ idetim &= ~(0x07 << (4 * adev->devno));
+ idetim |= control << (4 * adev->devno);
idetim |= (timings[pio][0] << 12) | (timings[pio][1] << 8);
pci_write_config_word(pdev, IDETIM, idetim);
@@ -188,23 +186,24 @@ static struct ata_port_operations mpiix_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = mpiix_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
/* Single threaded by the PCI probe logic */
- static struct ata_probe_ent probe[2];
+ static struct ata_probe_ent probe;
static int printed_version;
+ void __iomem *cmd_addr, *ctl_addr;
u16 idetim;
- int enabled;
+ int irq;
if (!printed_version++)
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
@@ -217,65 +216,49 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (!(idetim & ENABLED))
return -ENODEV;
+ /* See if it's primary or secondary channel... */
+ if (!(idetim & SECONDARY)) {
+ irq = 14;
+ cmd_addr = devm_ioport_map(&dev->dev, 0x1F0, 8);
+ ctl_addr = devm_ioport_map(&dev->dev, 0x3F6, 1);
+ } else {
+ irq = 15;
+ cmd_addr = devm_ioport_map(&dev->dev, 0x170, 8);
+ ctl_addr = devm_ioport_map(&dev->dev, 0x376, 1);
+ }
+
+ if (!cmd_addr || !ctl_addr)
+ return -ENOMEM;
+
/* We do our own plumbing to avoid leaking special cases for whacko
ancient hardware into the core code. There are two issues to
worry about. #1 The chip is a bridge so if in legacy mode and
without BARs set fools the setup. #2 If you pci_disable_device
the MPIIX your box goes castors up */
- INIT_LIST_HEAD(&probe[0].node);
- probe[0].dev = pci_dev_to_dev(dev);
- probe[0].port_ops = &mpiix_port_ops;
- probe[0].sht = &mpiix_sht;
- probe[0].pio_mask = 0x1F;
- probe[0].irq = 14;
- probe[0].irq_flags = SA_SHIRQ;
- probe[0].port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- probe[0].n_ports = 1;
- probe[0].port[0].cmd_addr = 0x1F0;
- probe[0].port[0].ctl_addr = 0x3F6;
- probe[0].port[0].altstatus_addr = 0x3F6;
-
- /* The secondary lurks at different addresses but is otherwise
- the same beastie */
-
- INIT_LIST_HEAD(&probe[1].node);
- probe[1] = probe[0];
- probe[1].irq = 15;
- probe[1].port[0].cmd_addr = 0x170;
- probe[1].port[0].ctl_addr = 0x376;
- probe[1].port[0].altstatus_addr = 0x376;
+ INIT_LIST_HEAD(&probe.node);
+ probe.dev = pci_dev_to_dev(dev);
+ probe.port_ops = &mpiix_port_ops;
+ probe.sht = &mpiix_sht;
+ probe.pio_mask = 0x1F;
+ probe.irq_flags = SA_SHIRQ;
+ probe.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+ probe.n_ports = 1;
+
+ probe.irq = irq;
+ probe.port[0].cmd_addr = cmd_addr;
+ probe.port[0].ctl_addr = ctl_addr;
+ probe.port[0].altstatus_addr = ctl_addr;
/* Let libata fill in the port details */
- ata_std_ports(&probe[0].port[0]);
- ata_std_ports(&probe[1].port[0]);
+ ata_std_ports(&probe.port[0]);
/* Now add the port that is active */
- enabled = (idetim & SECONDARY) ? 1 : 0;
-
- if (ata_device_add(&probe[enabled]))
+ if (ata_device_add(&probe))
return 0;
return -ENODEV;
}
-/**
- * mpiix_remove_one - device unload
- * @pdev: PCI device being removed
- *
- * Handle an unplug/unload event for a PCI device. Unload the
- * PCI driver but do not use the default handler as we *MUST NOT*
- * disable the device as it has other functions.
- */
-
-static void __devexit mpiix_remove_one(struct pci_dev *pdev)
-{
- struct device *dev = pci_dev_to_dev(pdev);
- struct ata_host *host = dev_get_drvdata(dev);
-
- ata_host_remove(host);
- dev_set_drvdata(dev, NULL);
-}
-
static const struct pci_device_id mpiix[] = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82371MX), },
@@ -286,7 +269,7 @@ static struct pci_driver mpiix_pci_driver = {
.name = DRV_NAME,
.id_table = mpiix,
.probe = mpiix_init_one,
- .remove = mpiix_remove_one,
+ .remove = ata_pci_remove_one,
.suspend = ata_pci_device_suspend,
.resume = ata_pci_device_resume,
};
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index cf7fe037471c..e8393e19be47 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -89,16 +89,16 @@ static const struct ata_port_operations netcell_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
/* IRQ-related hooks */
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
/* Generic PATA PCI ATA helpers */
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index c3032eb9010d..3d1fa487c486 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -179,14 +179,14 @@ static struct ata_port_operations ns87410_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ns87410_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 10ac3cc10181..45215aa05e72 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -25,7 +25,7 @@
#include <linux/ata.h>
#define DRV_NAME "pata_oldpiix"
-#define DRV_VERSION "0.5.2"
+#define DRV_VERSION "0.5.3"
/**
* oldpiix_pre_reset - probe begin
@@ -94,19 +94,21 @@ static void oldpiix_set_piomode (struct ata_port *ap, struct ata_device *adev)
{ 2, 1 },
{ 2, 3 }, };
- if (pio > 2)
- control |= 1; /* TIME1 enable */
+ if (pio > 1)
+ control |= 1; /* TIME */
if (ata_pio_need_iordy(adev))
- control |= 2; /* IE IORDY */
+ control |= 2; /* IE */
- /* Intel specifies that the PPE functionality is for disk only */
+ /* Intel specifies that the prefetch/posting is for disk only */
if (adev->class == ATA_DEV_ATA)
- control |= 4; /* PPE enable */
+ control |= 4; /* PPE */
pci_read_config_word(dev, idetm_port, &idetm_data);
- /* Enable PPE, IE and TIME as appropriate. Clear the other
- drive timing bits */
+ /*
+ * Set PPE, IE and TIME as appropriate.
+ * Clear the other drive's timing bits.
+ */
if (adev->devno == 0) {
idetm_data &= 0xCCE0;
idetm_data |= control;
@@ -259,14 +261,14 @@ static const struct ata_port_operations oldpiix_pata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = oldpiix_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index c2988b0aa8ea..da1aa148b37d 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -95,18 +95,18 @@ static void opti_error_handler(struct ata_port *ap)
static void opti_write_reg(struct ata_port *ap, u8 val, int reg)
{
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
/* These 3 unlock the control register access */
- inw(regio + 1);
- inw(regio + 1);
- outb(3, regio + 2);
+ ioread16(regio + 1);
+ ioread16(regio + 1);
+ iowrite8(3, regio + 2);
/* Do the I/O */
- outb(val, regio + reg);
+ iowrite8(val, regio + reg);
/* Relock */
- outb(0x83, regio + 2);
+ iowrite8(0x83, regio + 2);
}
/**
@@ -124,7 +124,7 @@ static void opti_set_piomode(struct ata_port *ap, struct ata_device *adev)
struct ata_device *pair = ata_dev_pair(adev);
int clock;
int pio = adev->pio_mode - XFER_PIO_0;
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
u8 addr;
/* Address table precomputed with prefetch off and a DCLK of 2 */
@@ -137,8 +137,8 @@ static void opti_set_piomode(struct ata_port *ap, struct ata_device *adev)
{ 0x58, 0x44, 0x32, 0x22, 0x21 }
};
- outb(0xff, regio + 5);
- clock = inw(regio + 5) & 1;
+ iowrite8(0xff, regio + 5);
+ clock = ioread16(regio + 5) & 1;
/*
* As with many controllers the address setup time is shared
@@ -205,14 +205,14 @@ static struct ata_port_operations opti_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 80d111c569dc..d80b36e209cc 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -91,12 +91,12 @@ static void optidma_error_handler(struct ata_port *ap)
static void optidma_unlock(struct ata_port *ap)
{
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
/* These 3 unlock the control register access */
- inw(regio + 1);
- inw(regio + 1);
- outb(3, regio + 2);
+ ioread16(regio + 1);
+ ioread16(regio + 1);
+ iowrite8(3, regio + 2);
}
/**
@@ -108,10 +108,10 @@ static void optidma_unlock(struct ata_port *ap)
static void optidma_lock(struct ata_port *ap)
{
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
/* Relock */
- outb(0x83, regio + 2);
+ iowrite8(0x83, regio + 2);
}
/**
@@ -133,7 +133,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
struct ata_device *pair = ata_dev_pair(adev);
int pio = adev->pio_mode - XFER_PIO_0;
int dma = adev->dma_mode - XFER_MW_DMA_0;
- unsigned long regio = ap->ioaddr.cmd_addr;
+ void __iomem *regio = ap->ioaddr.cmd_addr;
u8 addr;
/* Address table precomputed with a DCLK of 2 */
@@ -178,20 +178,20 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
/* Commence primary programming sequence */
/* First we load the device number into the timing select */
- outb(adev->devno, regio + MISC_REG);
+ iowrite8(adev->devno, regio + MISC_REG);
/* Now we load the data timings into read data/write data */
if (mode < XFER_MW_DMA_0) {
- outb(data_rec_timing[pci_clock][pio], regio + READ_REG);
- outb(data_rec_timing[pci_clock][pio], regio + WRITE_REG);
+ iowrite8(data_rec_timing[pci_clock][pio], regio + READ_REG);
+ iowrite8(data_rec_timing[pci_clock][pio], regio + WRITE_REG);
} else if (mode < XFER_UDMA_0) {
- outb(dma_data_rec_timing[pci_clock][dma], regio + READ_REG);
- outb(dma_data_rec_timing[pci_clock][dma], regio + WRITE_REG);
+ iowrite8(dma_data_rec_timing[pci_clock][dma], regio + READ_REG);
+ iowrite8(dma_data_rec_timing[pci_clock][dma], regio + WRITE_REG);
}
/* Finally we load the address setup into the misc register */
- outb(addr | adev->devno, regio + MISC_REG);
+ iowrite8(addr | adev->devno, regio + MISC_REG);
/* Programming sequence complete, timing 0 dev 0, timing 1 dev 1 */
- outb(0x85, regio + CNTRL_REG);
+ iowrite8(0x85, regio + CNTRL_REG);
/* Switch back to IDE mode */
optidma_lock(ap);
@@ -389,14 +389,14 @@ static struct ata_port_operations optidma_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations optiplus_port_ops = {
@@ -424,14 +424,14 @@ static struct ata_port_operations optiplus_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 9ed7f58424a3..acfc09f9abd9 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -88,14 +88,14 @@ static struct ata_port_operations pcmcia_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .data_xfer = ata_data_xfer_noirq,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
#define CS_CHECK(fn, ret) \
@@ -123,6 +123,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
cistpl_cftable_entry_t *cfg;
int pass, last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM;
unsigned long io_base, ctl_base;
+ void __iomem *io_addr, *ctl_addr;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL)
@@ -233,10 +234,17 @@ next_entry:
CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
+ /* iomap */
+ ret = -ENOMEM;
+ io_addr = devm_ioport_map(&pdev->dev, io_base, 8);
+ ctl_addr = devm_ioport_map(&pdev->dev, ctl_base, 1);
+ if (!io_addr || !ctl_addr)
+ goto failed;
+
/* Success. Disable the IRQ nIEN line, do quirks */
- outb(0x02, ctl_base);
+ iowrite8(0x02, ctl_addr);
if (is_kme)
- outb(0x81, ctl_base + 0x01);
+ iowrite8(0x81, ctl_addr + 0x01);
/* FIXME: Could be more ports at base + 0x10 but we only deal with
one right now */
@@ -258,11 +266,12 @@ next_entry:
ae.irq = pdev->irq.AssignedIRQ;
ae.irq_flags = SA_SHIRQ;
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- ae.port[0].cmd_addr = io_base;
- ae.port[0].altstatus_addr = ctl_base;
- ae.port[0].ctl_addr = ctl_base;
+ ae.port[0].cmd_addr = io_addr;
+ ae.port[0].altstatus_addr = ctl_addr;
+ ae.port[0].ctl_addr = ctl_addr;
ata_std_ports(&ae.port[0]);
+ ret = -ENODEV;
if (ata_device_add(&ae) == 0)
goto failed;
@@ -298,7 +307,7 @@ static void pcmcia_remove_one(struct pcmcia_device *pdev)
/* If we have attached the device to the ATA layer, detach it */
if (info->ndev) {
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
+ ata_host_detach(host);
dev_set_drvdata(dev, NULL);
}
info->ndev = 0;
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index 76dd1c935dbd..ffa7f47fbb20 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -33,7 +33,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "pata_pdc2027x"
#define DRV_VERSION "0.74-ac5"
@@ -46,6 +45,8 @@
#endif
enum {
+ PDC_MMIO_BAR = 5,
+
PDC_UDMA_100 = 0,
PDC_UDMA_133 = 1,
@@ -62,7 +63,6 @@ enum {
};
static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static void pdc2027x_remove_one(struct pci_dev *pdev);
static void pdc2027x_error_handler(struct ata_port *ap);
static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev);
static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);
@@ -123,7 +123,7 @@ static struct pci_driver pdc2027x_pci_driver = {
.name = DRV_NAME,
.id_table = pdc2027x_pci_tbl,
.probe = pdc2027x_init_one,
- .remove = __devexit_p(pdc2027x_remove_one),
+ .remove = ata_pci_remove_one,
};
static struct scsi_host_template pdc2027x_sht = {
@@ -160,7 +160,7 @@ static struct ata_port_operations pdc2027x_pata100_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -169,10 +169,10 @@ static struct ata_port_operations pdc2027x_pata100_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static struct ata_port_operations pdc2027x_pata133_ops = {
@@ -194,7 +194,7 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -203,10 +203,10 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static struct ata_port_info pdc2027x_port_info[] = {
@@ -245,7 +245,7 @@ MODULE_DEVICE_TABLE(pci, pdc2027x_pci_tbl);
*/
static inline void __iomem *port_mmio(struct ata_port *ap, unsigned int offset)
{
- return ap->host->mmio_base + ap->port_no * 0x100 + offset;
+ return ap->host->iomap[PDC_MMIO_BAR] + ap->port_no * 0x100 + offset;
}
/**
@@ -526,18 +526,19 @@ static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc)
static long pdc_read_counter(struct ata_probe_ent *probe_ent)
{
+ void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
long counter;
int retry = 1;
u32 bccrl, bccrh, bccrlv, bccrhv;
retry:
- bccrl = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff;
- bccrh = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
+ bccrl = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff;
+ bccrh = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
rmb();
/* Read the counter values again for verification */
- bccrlv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT) & 0xffff;
- bccrhv = readl(probe_ent->mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
+ bccrlv = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff;
+ bccrhv = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff;
rmb();
counter = (bccrh << 15) | bccrl;
@@ -568,7 +569,7 @@ retry:
*/
static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsigned int board_idx)
{
-
+ void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
u16 pll_ctl;
long pll_clock_khz = pll_clock / 1000;
long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ;
@@ -587,7 +588,7 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
/* Show the current clock value of PLL control register
* (maybe already configured by the firmware)
*/
- pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL);
+ pll_ctl = readw(mmio_base + PDC_PLL_CTL);
PDPRINTK("pll_ctl[%X]\n", pll_ctl);
#endif
@@ -627,8 +628,8 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
PDPRINTK("Writing pll_ctl[%X]\n", pll_ctl);
- writew(pll_ctl, probe_ent->mmio_base + PDC_PLL_CTL);
- readw(probe_ent->mmio_base + PDC_PLL_CTL); /* flush */
+ writew(pll_ctl, mmio_base + PDC_PLL_CTL);
+ readw(mmio_base + PDC_PLL_CTL); /* flush */
/* Wait the PLL circuit to be stable */
mdelay(30);
@@ -638,7 +639,7 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
* Show the current clock value of PLL control register
* (maybe configured by the firmware)
*/
- pll_ctl = readw(probe_ent->mmio_base + PDC_PLL_CTL);
+ pll_ctl = readw(mmio_base + PDC_PLL_CTL);
PDPRINTK("pll_ctl[%X]\n", pll_ctl);
#endif
@@ -654,6 +655,7 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
*/
static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
{
+ void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
u32 scr;
long start_count, end_count;
long pll_clock;
@@ -662,10 +664,10 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
start_count = pdc_read_counter(probe_ent);
/* Start the test mode */
- scr = readl(probe_ent->mmio_base + PDC_SYS_CTL);
+ scr = readl(mmio_base + PDC_SYS_CTL);
PDPRINTK("scr[%X]\n", scr);
- writel(scr | (0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL);
- readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */
+ writel(scr | (0x01 << 14), mmio_base + PDC_SYS_CTL);
+ readl(mmio_base + PDC_SYS_CTL); /* flush */
/* Let the counter run for 100 ms. */
mdelay(100);
@@ -674,10 +676,10 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
end_count = pdc_read_counter(probe_ent);
/* Stop the test mode */
- scr = readl(probe_ent->mmio_base + PDC_SYS_CTL);
+ scr = readl(mmio_base + PDC_SYS_CTL);
PDPRINTK("scr[%X]\n", scr);
- writel(scr & ~(0x01 << 14), probe_ent->mmio_base + PDC_SYS_CTL);
- readl(probe_ent->mmio_base + PDC_SYS_CTL); /* flush */
+ writel(scr & ~(0x01 << 14), mmio_base + PDC_SYS_CTL);
+ readl(mmio_base + PDC_SYS_CTL); /* flush */
/* calculate the input clock in Hz */
pll_clock = (start_count - end_count) * 10;
@@ -722,7 +724,7 @@ static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, uns
* @port: ata ioports to setup
* @base: base address
*/
-static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
+static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr =
port->data_addr = base;
@@ -755,48 +757,37 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
static int printed_version;
unsigned int board_idx = (unsigned int) ent->driver_data;
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
+ struct ata_probe_ent *probe_ent;
void __iomem *mmio_base;
int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
+ rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME);
if (rc)
- goto err_out;
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
/* Prepare the probe entry */
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, 5, 0);
- if (!mmio_base) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
-
- base = (unsigned long) mmio_base;
-
probe_ent->sht = pdc2027x_port_info[board_idx].sht;
probe_ent->port_flags = pdc2027x_port_info[board_idx].flags;
probe_ent->pio_mask = pdc2027x_port_info[board_idx].pio_mask;
@@ -806,12 +797,14 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
- pdc_ata_setup_port(&probe_ent->port[0], base + 0x17c0);
- probe_ent->port[0].bmdma_addr = base + 0x1000;
- pdc_ata_setup_port(&probe_ent->port[1], base + 0x15c0);
- probe_ent->port[1].bmdma_addr = base + 0x1008;
+ mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
+
+ pdc_ata_setup_port(&probe_ent->port[0], mmio_base + 0x17c0);
+ probe_ent->port[0].bmdma_addr = mmio_base + 0x1000;
+ pdc_ata_setup_port(&probe_ent->port[1], mmio_base + 0x15c0);
+ probe_ent->port[1].bmdma_addr = mmio_base + 0x1008;
probe_ent->n_ports = 2;
@@ -820,32 +813,13 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
/* initialize adapter */
if (pdc_hardware_init(pdev, probe_ent, board_idx) != 0)
- goto err_out_free_ent;
+ return -EIO;
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- pci_disable_device(pdev);
- return rc;
-}
-
-/**
- * pdc2027x_remove_one - Called to remove a single instance of the
- * adapter.
- *
- * @dev: The PCI device to remove.
- * FIXME: module load/unload not working yet
- */
-static void __devexit pdc2027x_remove_one(struct pci_dev *pdev)
-{
- ata_pci_remove_one(pdev);
}
/**
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index ad691b9e7743..6dd63413a523 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -170,17 +170,17 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
struct ata_taskfile *tf = &qc->tf;
int sel66 = ap->port_no ? 0x08: 0x02;
- unsigned long master = ap->host->ports[0]->ioaddr.bmdma_addr;
- unsigned long clock = master + 0x11;
- unsigned long atapi_reg = master + 0x20 + (4 * ap->port_no);
+ void __iomem *master = ap->host->ports[0]->ioaddr.bmdma_addr;
+ void __iomem *clock = master + 0x11;
+ void __iomem *atapi_reg = master + 0x20 + (4 * ap->port_no);
u32 len;
/* Check we keep host level locking here */
if (adev->dma_mode >= XFER_UDMA_2)
- outb(inb(clock) | sel66, clock);
+ iowrite8(ioread8(clock) | sel66, clock);
else
- outb(inb(clock) & ~sel66, clock);
+ iowrite8(ioread8(clock) & ~sel66, clock);
/* The DMA clocks may have been trashed by a reset. FIXME: make conditional
and move to qc_issue ? */
@@ -189,17 +189,14 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
/* Cases the state machine will not complete correctly without help */
if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATA_PROT_ATAPI_DMA)
{
- if (tf->flags & ATA_TFLAG_LBA48)
- len = qc->nsect * 512;
- else
- len = qc->nbytes;
+ len = qc->nbytes;
if (tf->flags & ATA_TFLAG_WRITE)
len |= 0x06000000;
else
len |= 0x05000000;
- outl(len, atapi_reg);
+ iowrite32(len, atapi_reg);
}
/* Activate DMA */
@@ -222,19 +219,19 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
int sel66 = ap->port_no ? 0x08: 0x02;
/* The clock bits are in the same register for both channels */
- unsigned long master = ap->host->ports[0]->ioaddr.bmdma_addr;
- unsigned long clock = master + 0x11;
- unsigned long atapi_reg = master + 0x20 + (4 * ap->port_no);
+ void __iomem *master = ap->host->ports[0]->ioaddr.bmdma_addr;
+ void __iomem *clock = master + 0x11;
+ void __iomem *atapi_reg = master + 0x20 + (4 * ap->port_no);
/* Cases the state machine will not complete correctly */
if (tf->protocol == ATA_PROT_ATAPI_DMA || ( tf->flags & ATA_TFLAG_LBA48)) {
- outl(0, atapi_reg);
- outb(inb(clock) & ~sel66, clock);
+ iowrite32(0, atapi_reg);
+ iowrite8(ioread8(clock) & ~sel66, clock);
}
/* Check we keep host level locking here */
/* Flip back to 33Mhz for PIO */
if (adev->dma_mode >= XFER_UDMA_2)
- outb(inb(clock) & ~sel66, clock);
+ iowrite8(ioread8(clock) & ~sel66, clock);
ata_bmdma_stop(qc);
}
@@ -297,14 +294,14 @@ static struct ata_port_operations pdc2024x_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations pdc2026x_port_ops = {
@@ -331,14 +328,14 @@ static struct ata_port_operations pdc2026x_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index 40ae11cbfda4..479a326114e0 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -47,23 +47,6 @@ static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unuse
return 0;
}
-static void pata_platform_host_stop(struct ata_host *host)
-{
- int i;
-
- /*
- * Unmap the bases for MMIO
- */
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- if (ap->flags & ATA_FLAG_MMIO) {
- iounmap((void __iomem *)ap->ioaddr.ctl_addr);
- iounmap((void __iomem *)ap->ioaddr.cmd_addr);
- }
- }
-}
-
static struct scsi_host_template pata_platform_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
@@ -100,14 +83,14 @@ static struct ata_port_operations pata_platform_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .data_xfer = ata_data_xfer_noirq,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = pata_platform_host_stop
};
static void pata_platform_setup_port(struct ata_ioports *ioaddr,
@@ -153,7 +136,6 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
struct resource *io_res, *ctl_res;
struct ata_probe_ent ae;
unsigned int mmio;
- int ret;
/*
* Simple resource validation ..
@@ -207,46 +189,29 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
* Handle the MMIO case
*/
if (mmio) {
- ae.port_flags |= ATA_FLAG_MMIO;
-
- ae.port[0].cmd_addr = (unsigned long)ioremap(io_res->start,
+ ae.port[0].cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
io_res->end - io_res->start + 1);
- if (unlikely(!ae.port[0].cmd_addr)) {
- dev_err(&pdev->dev, "failed to remap IO base\n");
- return -ENXIO;
- }
-
- ae.port[0].ctl_addr = (unsigned long)ioremap(ctl_res->start,
+ ae.port[0].ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
ctl_res->end - ctl_res->start + 1);
- if (unlikely(!ae.port[0].ctl_addr)) {
- dev_err(&pdev->dev, "failed to remap CTL base\n");
- ret = -ENXIO;
- goto bad_remap;
- }
} else {
- ae.port[0].cmd_addr = io_res->start;
- ae.port[0].ctl_addr = ctl_res->start;
+ ae.port[0].cmd_addr = devm_ioport_map(&pdev->dev, io_res->start,
+ io_res->end - io_res->start + 1);
+ ae.port[0].ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start,
+ ctl_res->end - ctl_res->start + 1);
+ }
+ if (!ae.port[0].cmd_addr || !ae.port[0].ctl_addr) {
+ dev_err(&pdev->dev, "failed to map IO/CTL base\n");
+ return -ENOMEM;
}
ae.port[0].altstatus_addr = ae.port[0].ctl_addr;
pata_platform_setup_port(&ae.port[0], pdev->dev.platform_data);
- if (unlikely(ata_device_add(&ae) == 0)) {
- ret = -ENODEV;
- goto add_failed;
- }
+ if (unlikely(ata_device_add(&ae) == 0))
+ return -ENODEV;
return 0;
-
-add_failed:
- if (ae.port[0].ctl_addr && mmio)
- iounmap((void __iomem *)ae.port[0].ctl_addr);
-bad_remap:
- if (ae.port[0].cmd_addr && mmio)
- iounmap((void __iomem *)ae.port[0].cmd_addr);
-
- return ret;
}
/**
@@ -261,7 +226,7 @@ static int __devexit pata_platform_remove(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct ata_host *host = dev_get_drvdata(dev);
- ata_host_remove(host);
+ ata_host_detach(host);
dev_set_drvdata(dev, NULL);
return 0;
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index afc0d990e7d6..1b3b4ed8eb19 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -131,22 +131,24 @@ static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned
if (ata_id_has_dword_io(adev->id)) {
if (write_data)
- outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
- insl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
if (unlikely(slop)) {
u32 pad;
if (write_data) {
memcpy(&pad, buf + buflen - slop, slop);
- outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ pad = le32_to_cpu(pad);
+ iowrite32(pad, ap->ioaddr.data_addr);
} else {
- pad = cpu_to_le32(inl(ap->ioaddr.data_addr));
+ pad = ioread32(ap->ioaddr.data_addr);
+ pad = cpu_to_le32(pad);
memcpy(buf + buflen - slop, &pad, slop);
}
}
} else
- ata_pio_data_xfer(adev, buf, buflen, write_data);
+ ata_data_xfer(adev, buf, buflen, write_data);
}
static struct scsi_host_template qdi_sht = {
@@ -189,10 +191,10 @@ static struct ata_port_operations qdi6500_port_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations qdi6580_port_ops = {
@@ -217,10 +219,10 @@ static struct ata_port_operations qdi6580_port_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -238,10 +240,9 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
{
struct ata_probe_ent ae;
struct platform_device *pdev;
+ void __iomem *io_addr, *ctl_addr;
int ret;
- unsigned long ctrl = io + 0x206;
-
/*
* Fill in a probe structure first of all
*/
@@ -250,6 +251,12 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
if (IS_ERR(pdev))
return PTR_ERR(pdev);
+ ret = -ENOMEM;
+ io_addr = devm_ioport_map(&pdev->dev, io, 8);
+ ctl_addr = devm_ioport_map(&pdev->dev, io + 0x206, 1);
+ if (!io_addr || !ctl_addr)
+ goto fail;
+
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
ae.dev = &pdev->dev;
@@ -267,9 +274,9 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
ae.irq = irq;
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- ae.port[0].cmd_addr = io;
- ae.port[0].altstatus_addr = ctrl;
- ae.port[0].ctl_addr = ctrl;
+ ae.port[0].cmd_addr = io_addr;
+ ae.port[0].altstatus_addr = ctl_addr;
+ ae.port[0].ctl_addr = ctl_addr;
ata_std_ports(&ae.port[0]);
/*
@@ -282,14 +289,17 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
qdi_data[nr_qdi_host].platform_dev = pdev;
printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io);
- ret = ata_device_add(&ae);
- if (ret == 0) {
- platform_device_unregister(pdev);
- return -ENODEV;
- }
+
+ ret = -ENODEV;
+ if (!ata_device_add(&ae))
+ goto fail;
qdi_host[nr_qdi_host++] = dev_get_drvdata(&pdev->dev);
return 0;
+
+ fail:
+ platform_device_unregister(pdev);
+ return ret;
}
/**
@@ -382,7 +392,7 @@ static __exit void qdi_exit(void)
int i;
for (i = 0; i < nr_qdi_host; i++) {
- ata_host_remove(qdi_host[i]);
+ ata_host_detach(qdi_host[i]);
/* Free the control resource. The 6580 dual channel has the resources
* claimed as a pair of 2 byte resources so we need no special cases...
*/
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 065541d034ad..0d1e571ef633 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -255,14 +255,14 @@ static const struct ata_port_operations radisys_pata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = radisys_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index cec0729225e1..71a2bac09e0d 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -115,7 +115,7 @@ static struct ata_port_operations rz1000_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -124,10 +124,10 @@ static struct ata_port_operations rz1000_port_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int rz1000_fifo_disable(struct pci_dev *pdev)
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index a3b35bc50394..58e42fbd14f9 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -220,14 +220,14 @@ static struct ata_port_operations sc1200_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = sc1200_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index f02b6a3b0f10..ad5b43fef3d1 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -218,25 +218,18 @@ static unsigned long serverworks_osb4_filter(const struct ata_port *ap, struct a
static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
{
const char *p;
- char model_num[40];
- int len, i;
+ char model_num[ATA_ID_PROD_LEN + 1];
+ int i;
/* Disk, UDMA */
if (adev->class != ATA_DEV_ATA)
return ata_pci_default_filter(ap, adev, mask);
/* Actually do need to check */
- ata_id_string(adev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
- /* Precuationary - why not do this in the libata core ?? */
+ ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
- len = strlen(model_num);
- while ((len > 0) && (model_num[len - 1] == ' ')) {
- len--;
- model_num[len] = 0;
- }
-
- for(i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
- if (!strncmp(p, model_num, len))
+ for (i = 0; (p = csb_bad_ata100[i]) != NULL; i++) {
+ if (!strcmp(p, model_num))
mask &= ~(0x1F << ATA_SHIFT_UDMA);
}
return ata_pci_default_filter(ap, adev, mask);
@@ -355,14 +348,14 @@ static struct ata_port_operations serverworks_osb4_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations serverworks_csb_port_ops = {
@@ -390,14 +383,14 @@ static struct ata_port_operations serverworks_csb_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int serverworks_fixup_osb4(struct pci_dev *pdev)
@@ -559,7 +552,7 @@ static int serverworks_reinit_one(struct pci_dev *pdev)
{
/* Force master latency timer to 64 PCI clocks */
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
-
+
switch (pdev->device)
{
case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index e8dfd8fc3ff7..ed79fabe025c 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -252,14 +252,14 @@ static struct ata_port_operations sil680_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -270,7 +270,7 @@ static struct ata_port_operations sil680_port_ops = {
* is powered up on boot and when we resume in case we resumed from RAM.
* Returns the final clock settings.
*/
-
+
static u8 sil680_init_chip(struct pci_dev *pdev)
{
u32 class_rev = 0;
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 916cedb3d755..560103d55b2e 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -32,7 +32,9 @@
#include <scsi/scsi_host.h>
#include <linux/libata.h>
#include <linux/ata.h>
+#include "libata.h"
+#undef DRV_NAME /* already defined in libata.h, for libata-core */
#define DRV_NAME "pata_sis"
#define DRV_VERSION "0.4.5"
@@ -43,6 +45,34 @@ struct sis_chipset {
up code later */
};
+struct sis_laptop {
+ u16 device;
+ u16 subvendor;
+ u16 subdevice;
+};
+
+static const struct sis_laptop sis_laptop[] = {
+ /* devid, subvendor, subdev */
+ { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */
+ /* end marker */
+ { 0, }
+};
+
+static int sis_short_ata40(struct pci_dev *dev)
+{
+ const struct sis_laptop *lap = &sis_laptop[0];
+
+ while (lap->device) {
+ if (lap->device == dev->device &&
+ lap->subvendor == dev->subsystem_vendor &&
+ lap->subdevice == dev->subsystem_device)
+ return 1;
+ lap++;
+ }
+
+ return 0;
+}
+
/**
* sis_port_base - return PCI configuration base for dev
* @adev: device
@@ -79,7 +109,7 @@ static int sis_133_pre_reset(struct ata_port *ap)
/* The top bit of this register is the cable detect bit */
pci_read_config_word(pdev, 0x50 + 2 * ap->port_no, &tmp);
- if (tmp & 0x8000)
+ if ((tmp & 0x8000) && !sis_short_ata40(pdev))
ap->cbl = ATA_CBL_PATA40;
else
ap->cbl = ATA_CBL_PATA80;
@@ -127,7 +157,7 @@ static int sis_66_pre_reset(struct ata_port *ap)
/* Older chips keep cable detect in bits 4/5 of reg 0x48 */
pci_read_config_byte(pdev, 0x48, &tmp);
tmp >>= ap->port_no;
- if (tmp & 0x10)
+ if ((tmp & 0x10) && !sis_short_ata40(pdev))
ap->cbl = ATA_CBL_PATA40;
else
ap->cbl = ATA_CBL_PATA80;
@@ -573,14 +603,14 @@ static const struct ata_port_operations sis_133_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations sis_133_early_ops = {
@@ -606,14 +636,14 @@ static const struct ata_port_operations sis_133_early_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations sis_100_ops = {
@@ -640,14 +670,14 @@ static const struct ata_port_operations sis_100_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations sis_66_ops = {
@@ -673,14 +703,14 @@ static const struct ata_port_operations sis_66_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static const struct ata_port_operations sis_old_ops = {
@@ -706,14 +736,14 @@ static const struct ata_port_operations sis_old_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static struct ata_port_info sis_info = {
@@ -753,7 +783,7 @@ static struct ata_port_info sis_info100_early = {
.pio_mask = 0x1f, /* pio0-4 */
.port_ops = &sis_66_ops,
};
-static struct ata_port_info sis_info133 = {
+struct ata_port_info sis_info133 = {
.sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
@@ -768,6 +798,8 @@ static struct ata_port_info sis_info133_early = {
.port_ops = &sis_133_early_ops,
};
+/* Privately shared with the SiS180 SATA driver, not for use elsewhere */
+EXPORT_SYMBOL_GPL(sis_info133);
static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis)
{
@@ -847,7 +879,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct sis_chipset *chipset = NULL;
static struct sis_chipset sis_chipsets[] = {
-
+
{ 0x0968, &sis_info133 },
{ 0x0966, &sis_info133 },
{ 0x0965, &sis_info133 },
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index e94f515ef54b..f2fa158d07ca 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -139,13 +139,13 @@ static void sl82c105_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
switch(adev->dma_mode) {
case XFER_MW_DMA_0:
- sl82c105_configure_piomode(ap, adev, 1);
+ sl82c105_configure_piomode(ap, adev, 0);
break;
case XFER_MW_DMA_1:
sl82c105_configure_piomode(ap, adev, 3);
break;
case XFER_MW_DMA_2:
- sl82c105_configure_piomode(ap, adev, 3);
+ sl82c105_configure_piomode(ap, adev, 4);
break;
default:
BUG();
@@ -262,14 +262,14 @@ static struct ata_port_operations sl82c105_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index a142971f1307..453ab90b721e 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -221,14 +221,14 @@ static struct ata_port_operations triflex_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index f0b6c3b71429..220fcd6c5492 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -334,14 +334,14 @@ static struct ata_port_operations via_port_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
static struct ata_port_operations via_port_ops_noirq = {
@@ -369,14 +369,14 @@ static struct ata_port_operations via_port_ops_noirq = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer_noirq,
+ .data_xfer = ata_data_xfer_noirq,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -391,11 +391,11 @@ static struct ata_port_operations via_port_ops_noirq = {
static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
{
u8 enable;
-
+
/* 0x40 low bits indicate enabled channels */
pci_read_config_byte(pdev, 0x40 , &enable);
enable &= 3;
-
+
if (flags & VIA_SET_FIFO) {
static const u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
u8 fifo;
@@ -516,7 +516,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/* Initialise the FIFO for the enabled channels. */
via_config_fifo(pdev, config->flags);
-
+
/* Clock set up */
switch(config->flags & VIA_UDMA) {
case VIA_UDMA_NONE:
@@ -575,7 +575,7 @@ static int via_reinit_one(struct pci_dev *pdev)
u32 timing;
struct ata_host *host = dev_get_drvdata(&pdev->dev);
const struct via_isa_bridge *config = host->private_data;
-
+
via_config_fifo(pdev, config->flags);
if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {
@@ -590,7 +590,7 @@ static int via_reinit_one(struct pci_dev *pdev)
timing &= ~0x80008;
pci_write_config_dword(pdev, 0x50, timing);
}
- return ata_pci_device_resume(pdev);
+ return ata_pci_device_resume(pdev);
}
static const struct pci_device_id via[] = {
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index 5d1f518e1cc7..0888b4f19f4c 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -5,7 +5,7 @@
* Support for the Winbond 83759A when operating in advanced mode.
* Multichip mode is not currently supported.
*/
-
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -69,7 +69,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
reg = winbond_readcfg(winbond->config, 0x81);
-
+
/* Get the timing data in cycles */
if (reg & 0x40) /* Fast VLB bus, assume 50MHz */
ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
@@ -80,9 +80,9 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F;
timing = (active << 4) | recovery;
winbond_writecfg(winbond->config, timing, reg);
-
+
/* Load the setup timing */
-
+
reg = 0x35;
if (adev->class != ATA_DEV_ATA)
reg |= 0x08; /* FIFO off */
@@ -100,22 +100,24 @@ static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsig
if (ata_id_has_dword_io(adev->id)) {
if (write_data)
- outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
else
- insl(ap->ioaddr.data_addr, buf, buflen >> 2);
+ ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
if (unlikely(slop)) {
u32 pad;
if (write_data) {
memcpy(&pad, buf + buflen - slop, slop);
- outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
+ pad = le32_to_cpu(pad);
+ iowrite32(pad, ap->ioaddr.data_addr);
} else {
- pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
+ pad = ioread32(ap->ioaddr.data_addr);
+ pad = cpu_to_le16(pad);
memcpy(buf + buflen - slop, &pad, slop);
}
}
} else
- ata_pio_data_xfer(adev, buf, buflen, write_data);
+ ata_data_xfer(adev, buf, buflen, write_data);
}
static struct scsi_host_template winbond_sht = {
@@ -158,10 +160,10 @@ static struct ata_port_operations winbond_port_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop
};
/**
@@ -194,13 +196,15 @@ static __init int winbond_init_one(unsigned long port)
winbond_writecfg(port, 0x85, reg);
reg = winbond_readcfg(port, 0x81);
-
+
if (!(reg & 0x03)) /* Disabled */
return 0;
for (i = 0; i < 2 ; i ++) {
+ unsigned long cmd_port = 0x1F0 - (0x80 * i);
+ void __iomem *cmd_addr, *ctl_addr;
- if (reg & (1 << i)) {
+ if (reg & (1 << i)) {
/*
* Fill in a probe structure first of all
*/
@@ -209,6 +213,13 @@ static __init int winbond_init_one(unsigned long port)
if (IS_ERR(pdev))
return PTR_ERR(pdev);
+ cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8);
+ ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1);
+ if (!cmd_addr || !ctl_addr) {
+ platform_device_unregister(pdev);
+ return -ENOMEM;
+ }
+
memset(&ae, 0, sizeof(struct ata_probe_ent));
INIT_LIST_HEAD(&ae.node);
ae.dev = &pdev->dev;
@@ -217,14 +228,14 @@ static __init int winbond_init_one(unsigned long port)
ae.pio_mask = 0x1F;
ae.sht = &winbond_sht;
-
+
ae.n_ports = 1;
ae.irq = 14 + i;
ae.irq_flags = 0;
ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
- ae.port[0].cmd_addr = 0x1F0 - (0x80 * i);
- ae.port[0].altstatus_addr = ae.port[0].cmd_addr + 0x0206;
- ae.port[0].ctl_addr = ae.port[0].altstatus_addr;
+ ae.port[0].cmd_addr = cmd_addr;
+ ae.port[0].altstatus_addr = ctl_addr;
+ ae.port[0].ctl_addr = ctl_addr;
ata_std_ports(&ae.port[0]);
/*
* Hook in a private data structure per channel
@@ -257,7 +268,7 @@ static __init int winbond_init(void)
int ct = 0;
int i;
-
+
if (probe_winbond == 0)
return -ENODEV;
@@ -288,7 +299,7 @@ static __exit void winbond_exit(void)
int i;
for (i = 0; i < nr_winbond_host; i++) {
- ata_host_remove(winbond_host[i]);
+ ata_host_detach(winbond_host[i]);
release_region(winbond_data[i].config, 2);
platform_device_unregister(winbond_data[i].platform_dev);
}
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 90786d7a20bb..b4ed8ce553e6 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -42,7 +42,6 @@
#include <linux/sched.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
-#include <asm/io.h>
#include <linux/libata.h>
#define DRV_NAME "pdc_adma"
@@ -52,9 +51,15 @@
#define ADMA_ATA_REGS(base,port_no) ((base) + ((port_no) * 0x40))
/* macro to calculate base address for ADMA regs */
-#define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20))
+#define ADMA_REGS(base,port_no) ((base) + 0x80 + ((port_no) * 0x20))
+
+/* macro to obtain addresses from ata_host */
+#define ADMA_HOST_REGS(host,port_no) \
+ ADMA_REGS((host)->iomap[ADMA_MMIO_BAR], port_no)
enum {
+ ADMA_MMIO_BAR = 4,
+
ADMA_PORTS = 2,
ADMA_CPB_BYTES = 40,
ADMA_PRD_BYTES = LIBATA_MAX_PRD * 16,
@@ -167,9 +172,11 @@ static const struct ata_port_operations adma_ata_ops = {
.qc_prep = adma_qc_prep,
.qc_issue = adma_qc_issue,
.eng_timeout = adma_eng_timeout,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = adma_intr,
.irq_clear = adma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = adma_port_start,
.port_stop = adma_port_stop,
.host_stop = adma_host_stop,
@@ -235,11 +242,10 @@ static void adma_reset_engine(void __iomem *chan)
static void adma_reinit_engine(struct ata_port *ap)
{
struct adma_port_priv *pp = ap->private_data;
- void __iomem *mmio_base = ap->host->mmio_base;
- void __iomem *chan = ADMA_REGS(mmio_base, ap->port_no);
+ void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
/* mask/clear ATA interrupts */
- writeb(ATA_NIEN, (void __iomem *)ap->ioaddr.ctl_addr);
+ writeb(ATA_NIEN, ap->ioaddr.ctl_addr);
ata_check_status(ap);
/* reset the ADMA engine */
@@ -263,7 +269,7 @@ static void adma_reinit_engine(struct ata_port *ap)
static inline void adma_enter_reg_mode(struct ata_port *ap)
{
- void __iomem *chan = ADMA_REGS(ap->host->mmio_base, ap->port_no);
+ void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
writew(aPIOMD4, chan + ADMA_CONTROL);
readb(chan + ADMA_STATUS); /* flush */
@@ -410,7 +416,7 @@ static void adma_qc_prep(struct ata_queued_cmd *qc)
static inline void adma_packet_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- void __iomem *chan = ADMA_REGS(ap->host->mmio_base, ap->port_no);
+ void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
VPRINTK("ENTER, ap %p\n", ap);
@@ -443,13 +449,12 @@ static unsigned int adma_qc_issue(struct ata_queued_cmd *qc)
static inline unsigned int adma_intr_pkt(struct ata_host *host)
{
unsigned int handled = 0, port_no;
- u8 __iomem *mmio_base = host->mmio_base;
for (port_no = 0; port_no < host->n_ports; ++port_no) {
struct ata_port *ap = host->ports[port_no];
struct adma_port_priv *pp;
struct ata_queued_cmd *qc;
- void __iomem *chan = ADMA_REGS(mmio_base, port_no);
+ void __iomem *chan = ADMA_HOST_REGS(host, port_no);
u8 status = readb(chan + ADMA_STATUS);
if (status == 0)
@@ -523,7 +528,7 @@ static irqreturn_t adma_intr(int irq, void *dev_instance)
return IRQ_RETVAL(handled);
}
-static void adma_ata_setup_port(struct ata_ioports *port, unsigned long base)
+static void adma_ata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr =
port->data_addr = base + 0x000;
@@ -550,48 +555,28 @@ static int adma_port_start(struct ata_port *ap)
if (rc)
return rc;
adma_enter_reg_mode(ap);
- rc = -ENOMEM;
- pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
- goto err_out;
- pp->pkt = dma_alloc_coherent(dev, ADMA_PKT_BYTES, &pp->pkt_dma,
- GFP_KERNEL);
+ return -ENOMEM;
+ pp->pkt = dmam_alloc_coherent(dev, ADMA_PKT_BYTES, &pp->pkt_dma,
+ GFP_KERNEL);
if (!pp->pkt)
- goto err_out_kfree;
+ return -ENOMEM;
/* paranoia? */
if ((pp->pkt_dma & 7) != 0) {
printk("bad alignment for pp->pkt_dma: %08x\n",
(u32)pp->pkt_dma);
- dma_free_coherent(dev, ADMA_PKT_BYTES,
- pp->pkt, pp->pkt_dma);
- goto err_out_kfree;
+ return -ENOMEM;
}
memset(pp->pkt, 0, ADMA_PKT_BYTES);
ap->private_data = pp;
adma_reinit_engine(ap);
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
}
static void adma_port_stop(struct ata_port *ap)
{
- struct device *dev = ap->host->dev;
- struct adma_port_priv *pp = ap->private_data;
-
- adma_reset_engine(ADMA_REGS(ap->host->mmio_base, ap->port_no));
- if (pp != NULL) {
- ap->private_data = NULL;
- if (pp->pkt != NULL)
- dma_free_coherent(dev, ADMA_PKT_BYTES,
- pp->pkt, pp->pkt_dma);
- kfree(pp);
- }
- ata_port_stop(ap);
+ adma_reset_engine(ADMA_HOST_REGS(ap->host, ap->port_no));
}
static void adma_host_stop(struct ata_host *host)
@@ -599,16 +584,14 @@ static void adma_host_stop(struct ata_host *host)
unsigned int port_no;
for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
- adma_reset_engine(ADMA_REGS(host->mmio_base, port_no));
-
- ata_pci_host_stop(host);
+ adma_reset_engine(ADMA_HOST_REGS(host, port_no));
}
static void adma_host_init(unsigned int chip_id,
struct ata_probe_ent *probe_ent)
{
unsigned int port_no;
- void __iomem *mmio_base = probe_ent->mmio_base;
+ void __iomem *mmio_base = probe_ent->iomap[ADMA_MMIO_BAR];
/* enable/lock aGO operation */
writeb(7, mmio_base + ADMA_MODE_LOCK);
@@ -638,7 +621,7 @@ static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
}
static int adma_ata_init_one(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+ const struct pci_device_id *ent)
{
static int printed_version;
struct ata_probe_ent *probe_ent = NULL;
@@ -649,34 +632,25 @@ static int adma_ata_init_one(struct pci_dev *pdev,
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc)
- goto err_out;
-
- if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) {
- rc = -ENODEV;
- goto err_out_regions;
- }
+ if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0)
+ return -ENODEV;
- mmio_base = pci_iomap(pdev, 4, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ rc = pcim_iomap_regions(pdev, 1 << ADMA_MMIO_BAR, DRV_NAME);
+ if (rc)
+ return rc;
+ mmio_base = pcim_iomap_table(pdev)[ADMA_MMIO_BAR];
rc = adma_set_dma_masks(pdev, mmio_base);
if (rc)
- goto err_out_iounmap;
+ return rc;
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
@@ -690,12 +664,12 @@ static int adma_ata_init_one(struct pci_dev *pdev,
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
probe_ent->n_ports = ADMA_PORTS;
+ probe_ent->iomap = pcim_iomap_table(pdev);
for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
adma_ata_setup_port(&probe_ent->port[port_no],
- ADMA_ATA_REGS((unsigned long)mmio_base, port_no));
+ ADMA_ATA_REGS(mmio_base, port_no));
}
pci_set_master(pdev);
@@ -703,19 +677,11 @@ static int adma_ata_init_one(struct pci_dev *pdev,
/* initialize adapter */
adma_host_init(board_idx, probe_ent);
- rc = ata_device_add(probe_ent);
- kfree(probe_ent);
- if (rc != ADMA_PORTS)
- goto err_out_iounmap;
- return 0;
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- pci_disable_device(pdev);
- return rc;
+ devm_kfree(&pdev->dev, probe_ent);
+ return 0;
}
static int __init adma_ata_init(void)
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
new file mode 100644
index 000000000000..c5335f422801
--- /dev/null
+++ b/drivers/ata/sata_inic162x.c
@@ -0,0 +1,781 @@
+/*
+ * sata_inic162x.c - Driver for Initio 162x SATA controllers
+ *
+ * Copyright 2006 SUSE Linux Products GmbH
+ * Copyright 2006 Tejun Heo <teheo@novell.com>
+ *
+ * This file is released under GPL v2.
+ *
+ * This controller is eccentric and easily locks up if something isn't
+ * right. Documentation is available at initio's website but it only
+ * documents registers (not programming model).
+ *
+ * - ATA disks work.
+ * - Hotplug works.
+ * - ATAPI read works but burning doesn't. This thing is really
+ * peculiar about ATAPI and I couldn't figure out how ATAPI PIO and
+ * ATAPI DMA WRITE should be programmed. If you've got a clue, be
+ * my guest.
+ * - Both STR and STD work.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/blkdev.h>
+#include <scsi/scsi_device.h>
+
+#define DRV_NAME "sata_inic162x"
+#define DRV_VERSION "0.1"
+
+enum {
+ MMIO_BAR = 5,
+
+ NR_PORTS = 2,
+
+ HOST_CTL = 0x7c,
+ HOST_STAT = 0x7e,
+ HOST_IRQ_STAT = 0xbc,
+ HOST_IRQ_MASK = 0xbe,
+
+ PORT_SIZE = 0x40,
+
+ /* registers for ATA TF operation */
+ PORT_TF = 0x00,
+ PORT_ALT_STAT = 0x08,
+ PORT_IRQ_STAT = 0x09,
+ PORT_IRQ_MASK = 0x0a,
+ PORT_PRD_CTL = 0x0b,
+ PORT_PRD_ADDR = 0x0c,
+ PORT_PRD_XFERLEN = 0x10,
+
+ /* IDMA register */
+ PORT_IDMA_CTL = 0x14,
+
+ PORT_SCR = 0x20,
+
+ /* HOST_CTL bits */
+ HCTL_IRQOFF = (1 << 8), /* global IRQ off */
+ HCTL_PWRDWN = (1 << 13), /* power down PHYs */
+ HCTL_SOFTRST = (1 << 13), /* global reset (no phy reset) */
+ HCTL_RPGSEL = (1 << 15), /* register page select */
+
+ HCTL_KNOWN_BITS = HCTL_IRQOFF | HCTL_PWRDWN | HCTL_SOFTRST |
+ HCTL_RPGSEL,
+
+ /* HOST_IRQ_(STAT|MASK) bits */
+ HIRQ_PORT0 = (1 << 0),
+ HIRQ_PORT1 = (1 << 1),
+ HIRQ_SOFT = (1 << 14),
+ HIRQ_GLOBAL = (1 << 15), /* STAT only */
+
+ /* PORT_IRQ_(STAT|MASK) bits */
+ PIRQ_OFFLINE = (1 << 0), /* device unplugged */
+ PIRQ_ONLINE = (1 << 1), /* device plugged */
+ PIRQ_COMPLETE = (1 << 2), /* completion interrupt */
+ PIRQ_FATAL = (1 << 3), /* fatal error */
+ PIRQ_ATA = (1 << 4), /* ATA interrupt */
+ PIRQ_REPLY = (1 << 5), /* reply FIFO not empty */
+ PIRQ_PENDING = (1 << 7), /* port IRQ pending (STAT only) */
+
+ PIRQ_ERR = PIRQ_OFFLINE | PIRQ_ONLINE | PIRQ_FATAL,
+
+ PIRQ_MASK_DMA_READ = PIRQ_REPLY | PIRQ_ATA,
+ PIRQ_MASK_OTHER = PIRQ_REPLY | PIRQ_COMPLETE,
+ PIRQ_MASK_FREEZE = 0xff,
+
+ /* PORT_PRD_CTL bits */
+ PRD_CTL_START = (1 << 0),
+ PRD_CTL_WR = (1 << 3),
+ PRD_CTL_DMAEN = (1 << 7), /* DMA enable */
+
+ /* PORT_IDMA_CTL bits */
+ IDMA_CTL_RST_ATA = (1 << 2), /* hardreset ATA bus */
+ IDMA_CTL_RST_IDMA = (1 << 5), /* reset IDMA machinary */
+ IDMA_CTL_GO = (1 << 7), /* IDMA mode go */
+ IDMA_CTL_ATA_NIEN = (1 << 8), /* ATA IRQ disable */
+};
+
+struct inic_host_priv {
+ u16 cached_hctl;
+};
+
+struct inic_port_priv {
+ u8 dfl_prdctl;
+ u8 cached_prdctl;
+ u8 cached_pirq_mask;
+};
+
+static int inic_slave_config(struct scsi_device *sdev)
+{
+ /* This controller is braindamaged. dma_boundary is 0xffff
+ * like others but it will lock up the whole machine HARD if
+ * 65536 byte PRD entry is fed. Reduce maximum segment size.
+ */
+ blk_queue_max_segment_size(sdev->request_queue, 65536 - 512);
+
+ return ata_scsi_slave_config(sdev);
+}
+
+static struct scsi_host_template inic_sht = {
+ .module = THIS_MODULE,
+ .name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
+ .queuecommand = ata_scsi_queuecmd,
+ .can_queue = ATA_DEF_QUEUE,
+ .this_id = ATA_SHT_THIS_ID,
+ .sg_tablesize = LIBATA_MAX_PRD,
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
+ .emulated = ATA_SHT_EMULATED,
+ .use_clustering = ATA_SHT_USE_CLUSTERING,
+ .proc_name = DRV_NAME,
+ .dma_boundary = ATA_DMA_BOUNDARY,
+ .slave_configure = inic_slave_config,
+ .slave_destroy = ata_scsi_slave_destroy,
+ .bios_param = ata_std_bios_param,
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
+};
+
+static const int scr_map[] = {
+ [SCR_STATUS] = 0,
+ [SCR_ERROR] = 1,
+ [SCR_CONTROL] = 2,
+};
+
+static void __iomem * inic_port_base(struct ata_port *ap)
+{
+ return ap->host->iomap[MMIO_BAR] + ap->port_no * PORT_SIZE;
+}
+
+static void __inic_set_pirq_mask(struct ata_port *ap, u8 mask)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ struct inic_port_priv *pp = ap->private_data;
+
+ writeb(mask, port_base + PORT_IRQ_MASK);
+ pp->cached_pirq_mask = mask;
+}
+
+static void inic_set_pirq_mask(struct ata_port *ap, u8 mask)
+{
+ struct inic_port_priv *pp = ap->private_data;
+
+ if (pp->cached_pirq_mask != mask)
+ __inic_set_pirq_mask(ap, mask);
+}
+
+static void inic_reset_port(void __iomem *port_base)
+{
+ void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
+ u16 ctl;
+
+ ctl = readw(idma_ctl);
+ ctl &= ~(IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN | IDMA_CTL_GO);
+
+ /* mask IRQ and assert reset */
+ writew(ctl | IDMA_CTL_RST_IDMA | IDMA_CTL_ATA_NIEN, idma_ctl);
+ readw(idma_ctl); /* flush */
+
+ /* give it some time */
+ msleep(1);
+
+ /* release reset */
+ writew(ctl | IDMA_CTL_ATA_NIEN, idma_ctl);
+
+ /* clear irq */
+ writeb(0xff, port_base + PORT_IRQ_STAT);
+
+ /* reenable ATA IRQ, turn off IDMA mode */
+ writew(ctl, idma_ctl);
+}
+
+static u32 inic_scr_read(struct ata_port *ap, unsigned sc_reg)
+{
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *addr;
+ u32 val;
+
+ if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
+ return 0xffffffffU;
+
+ addr = scr_addr + scr_map[sc_reg] * 4;
+ val = readl(scr_addr + scr_map[sc_reg] * 4);
+
+ /* this controller has stuck DIAG.N, ignore it */
+ if (sc_reg == SCR_ERROR)
+ val &= ~SERR_PHYRDY_CHG;
+ return val;
+}
+
+static void inic_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
+{
+ void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *addr;
+
+ if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
+ return;
+
+ addr = scr_addr + scr_map[sc_reg] * 4;
+ writel(val, scr_addr + scr_map[sc_reg] * 4);
+}
+
+/*
+ * In TF mode, inic162x is very similar to SFF device. TF registers
+ * function the same. DMA engine behaves similary using the same PRD
+ * format as BMDMA but different command register, interrupt and event
+ * notification methods are used. The following inic_bmdma_*()
+ * functions do the impedance matching.
+ */
+static void inic_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct inic_port_priv *pp = ap->private_data;
+ void __iomem *port_base = inic_port_base(ap);
+ int rw = qc->tf.flags & ATA_TFLAG_WRITE;
+
+ /* make sure device sees PRD table writes */
+ wmb();
+
+ /* load transfer length */
+ writel(qc->nbytes, port_base + PORT_PRD_XFERLEN);
+
+ /* turn on DMA and specify data direction */
+ pp->cached_prdctl = pp->dfl_prdctl | PRD_CTL_DMAEN;
+ if (!rw)
+ pp->cached_prdctl |= PRD_CTL_WR;
+ writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL);
+
+ /* issue r/w command */
+ ap->ops->exec_command(ap, &qc->tf);
+}
+
+static void inic_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct inic_port_priv *pp = ap->private_data;
+ void __iomem *port_base = inic_port_base(ap);
+
+ /* start host DMA transaction */
+ pp->cached_prdctl |= PRD_CTL_START;
+ writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL);
+}
+
+static void inic_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct inic_port_priv *pp = ap->private_data;
+ void __iomem *port_base = inic_port_base(ap);
+
+ /* stop DMA engine */
+ writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL);
+}
+
+static u8 inic_bmdma_status(struct ata_port *ap)
+{
+ /* event is already verified by the interrupt handler */
+ return ATA_DMA_INTR;
+}
+
+static void inic_irq_clear(struct ata_port *ap)
+{
+ /* noop */
+}
+
+static void inic_host_intr(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ struct ata_eh_info *ehi = &ap->eh_info;
+ u8 irq_stat;
+
+ /* fetch and clear irq */
+ irq_stat = readb(port_base + PORT_IRQ_STAT);
+ writeb(irq_stat, port_base + PORT_IRQ_STAT);
+
+ if (likely(!(irq_stat & PIRQ_ERR))) {
+ struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+
+ if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
+ ata_chk_status(ap); /* clear ATA interrupt */
+ return;
+ }
+
+ if (likely(ata_host_intr(ap, qc)))
+ return;
+
+ ata_chk_status(ap); /* clear ATA interrupt */
+ ata_port_printk(ap, KERN_WARNING, "unhandled "
+ "interrupt, irq_stat=%x\n", irq_stat);
+ return;
+ }
+
+ /* error */
+ ata_ehi_push_desc(ehi, "irq_stat=0x%x", irq_stat);
+
+ if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) {
+ ata_ehi_hotplugged(ehi);
+ ata_port_freeze(ap);
+ } else
+ ata_port_abort(ap);
+}
+
+static irqreturn_t inic_interrupt(int irq, void *dev_instance)
+{
+ struct ata_host *host = dev_instance;
+ void __iomem *mmio_base = host->iomap[MMIO_BAR];
+ u16 host_irq_stat;
+ int i, handled = 0;;
+
+ host_irq_stat = readw(mmio_base + HOST_IRQ_STAT);
+
+ if (unlikely(!(host_irq_stat & HIRQ_GLOBAL)))
+ goto out;
+
+ spin_lock(&host->lock);
+
+ for (i = 0; i < NR_PORTS; i++) {
+ struct ata_port *ap = host->ports[i];
+
+ if (!(host_irq_stat & (HIRQ_PORT0 << i)))
+ continue;
+
+ if (likely(ap && !(ap->flags & ATA_FLAG_DISABLED))) {
+ inic_host_intr(ap);
+ handled++;
+ } else {
+ if (ata_ratelimit())
+ dev_printk(KERN_ERR, host->dev, "interrupt "
+ "from disabled port %d (0x%x)\n",
+ i, host_irq_stat);
+ }
+ }
+
+ spin_unlock(&host->lock);
+
+ out:
+ return IRQ_RETVAL(handled);
+}
+
+static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+
+ /* ATA IRQ doesn't wait for DMA transfer completion and vice
+ * versa. Mask IRQ selectively to detect command completion.
+ * Without it, ATA DMA read command can cause data corruption.
+ *
+ * Something similar might be needed for ATAPI writes. I
+ * tried a lot of combinations but couldn't find the solution.
+ */
+ if (qc->tf.protocol == ATA_PROT_DMA &&
+ !(qc->tf.flags & ATA_TFLAG_WRITE))
+ inic_set_pirq_mask(ap, PIRQ_MASK_DMA_READ);
+ else
+ inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
+
+ /* Issuing a command to yet uninitialized port locks up the
+ * controller. Most of the time, this happens for the first
+ * command after reset which are ATA and ATAPI IDENTIFYs.
+ * Fast fail if stat is 0x7f or 0xff for those commands.
+ */
+ if (unlikely(qc->tf.command == ATA_CMD_ID_ATA ||
+ qc->tf.command == ATA_CMD_ID_ATAPI)) {
+ u8 stat = ata_chk_status(ap);
+ if (stat == 0x7f || stat == 0xff)
+ return AC_ERR_HSM;
+ }
+
+ return ata_qc_issue_prot(qc);
+}
+
+static void inic_freeze(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+
+ __inic_set_pirq_mask(ap, PIRQ_MASK_FREEZE);
+
+ ata_chk_status(ap);
+ writeb(0xff, port_base + PORT_IRQ_STAT);
+
+ readb(port_base + PORT_IRQ_STAT); /* flush */
+}
+
+static void inic_thaw(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+
+ ata_chk_status(ap);
+ writeb(0xff, port_base + PORT_IRQ_STAT);
+
+ __inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
+
+ readb(port_base + PORT_IRQ_STAT); /* flush */
+}
+
+/*
+ * SRST and SControl hardreset don't give valid signature on this
+ * controller. Only controller specific hardreset mechanism works.
+ */
+static int inic_hardreset(struct ata_port *ap, unsigned int *class)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
+ const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
+ u16 val;
+ int rc;
+
+ /* hammer it into sane state */
+ inic_reset_port(port_base);
+
+ val = readw(idma_ctl);
+ writew(val | IDMA_CTL_RST_ATA, idma_ctl);
+ readw(idma_ctl); /* flush */
+ msleep(1);
+ writew(val & ~IDMA_CTL_RST_ATA, idma_ctl);
+
+ rc = sata_phy_resume(ap, timing);
+ if (rc) {
+ ata_port_printk(ap, KERN_WARNING, "failed to resume "
+ "link after reset (errno=%d)\n", rc);
+ return rc;
+ }
+
+ *class = ATA_DEV_NONE;
+ if (ata_port_online(ap)) {
+ struct ata_taskfile tf;
+
+ /* wait a while before checking status */
+ msleep(150);
+
+ if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
+ ata_port_printk(ap, KERN_WARNING,
+ "device busy after hardreset\n");
+ return -EIO;
+ }
+
+ ata_tf_read(ap, &tf);
+ *class = ata_dev_classify(&tf);
+ if (*class == ATA_DEV_UNKNOWN)
+ *class = ATA_DEV_NONE;
+ }
+
+ return 0;
+}
+
+static void inic_error_handler(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ struct inic_port_priv *pp = ap->private_data;
+ unsigned long flags;
+
+ /* reset PIO HSM and stop DMA engine */
+ inic_reset_port(port_base);
+
+ spin_lock_irqsave(ap->lock, flags);
+ ap->hsm_task_state = HSM_ST_IDLE;
+ writeb(pp->dfl_prdctl, port_base + PORT_PRD_CTL);
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ /* PIO and DMA engines have been stopped, perform recovery */
+ ata_do_eh(ap, ata_std_prereset, NULL, inic_hardreset,
+ ata_std_postreset);
+}
+
+static void inic_post_internal_cmd(struct ata_queued_cmd *qc)
+{
+ /* make DMA engine forget about the failed command */
+ if (qc->err_mask)
+ inic_reset_port(inic_port_base(qc->ap));
+}
+
+static void inic_dev_config(struct ata_port *ap, struct ata_device *dev)
+{
+ /* inic can only handle upto LBA28 max sectors */
+ if (dev->max_sectors > ATA_MAX_SECTORS)
+ dev->max_sectors = ATA_MAX_SECTORS;
+}
+
+static void init_port(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+
+ /* Setup PRD address */
+ writel(ap->prd_dma, port_base + PORT_PRD_ADDR);
+}
+
+static int inic_port_resume(struct ata_port *ap)
+{
+ init_port(ap);
+ return 0;
+}
+
+static int inic_port_start(struct ata_port *ap)
+{
+ void __iomem *port_base = inic_port_base(ap);
+ struct inic_port_priv *pp;
+ u8 tmp;
+ int rc;
+
+ /* alloc and initialize private data */
+ pp = devm_kzalloc(ap->host->dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+ ap->private_data = pp;
+
+ /* default PRD_CTL value, DMAEN, WR and START off */
+ tmp = readb(port_base + PORT_PRD_CTL);
+ tmp &= ~(PRD_CTL_DMAEN | PRD_CTL_WR | PRD_CTL_START);
+ pp->dfl_prdctl = tmp;
+
+ /* Alloc resources */
+ rc = ata_port_start(ap);
+ if (rc) {
+ kfree(pp);
+ return rc;
+ }
+
+ init_port(ap);
+
+ return 0;
+}
+
+static struct ata_port_operations inic_port_ops = {
+ .port_disable = ata_port_disable,
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .scr_read = inic_scr_read,
+ .scr_write = inic_scr_write,
+
+ .bmdma_setup = inic_bmdma_setup,
+ .bmdma_start = inic_bmdma_start,
+ .bmdma_stop = inic_bmdma_stop,
+ .bmdma_status = inic_bmdma_status,
+
+ .irq_handler = inic_interrupt,
+ .irq_clear = inic_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = inic_qc_issue,
+ .data_xfer = ata_data_xfer,
+
+ .freeze = inic_freeze,
+ .thaw = inic_thaw,
+ .error_handler = inic_error_handler,
+ .post_internal_cmd = inic_post_internal_cmd,
+ .dev_config = inic_dev_config,
+
+ .port_resume = inic_port_resume,
+
+ .port_start = inic_port_start,
+};
+
+static struct ata_port_info inic_port_info = {
+ .sht = &inic_sht,
+ /* For some reason, ATA_PROT_ATAPI is broken on this
+ * controller, and no, PIO_POLLING does't fix it. It somehow
+ * manages to report the wrong ireason and ignoring ireason
+ * results in machine lock up. Tell libata to always prefer
+ * DMA.
+ */
+ .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .mwdma_mask = 0x07, /* mwdma0-2 */
+ .udma_mask = 0x7f, /* udma0-6 */
+ .port_ops = &inic_port_ops
+};
+
+static int init_controller(void __iomem *mmio_base, u16 hctl)
+{
+ int i;
+ u16 val;
+
+ hctl &= ~HCTL_KNOWN_BITS;
+
+ /* Soft reset whole controller. Spec says reset duration is 3
+ * PCI clocks, be generous and give it 10ms.
+ */
+ writew(hctl | HCTL_SOFTRST, mmio_base + HOST_CTL);
+ readw(mmio_base + HOST_CTL); /* flush */
+
+ for (i = 0; i < 10; i++) {
+ msleep(1);
+ val = readw(mmio_base + HOST_CTL);
+ if (!(val & HCTL_SOFTRST))
+ break;
+ }
+
+ if (val & HCTL_SOFTRST)
+ return -EIO;
+
+ /* mask all interrupts and reset ports */
+ for (i = 0; i < NR_PORTS; i++) {
+ void __iomem *port_base = mmio_base + i * PORT_SIZE;
+
+ writeb(0xff, port_base + PORT_IRQ_MASK);
+ inic_reset_port(port_base);
+ }
+
+ /* port IRQ is masked now, unmask global IRQ */
+ writew(hctl & ~HCTL_IRQOFF, mmio_base + HOST_CTL);
+ val = readw(mmio_base + HOST_IRQ_MASK);
+ val &= ~(HIRQ_PORT0 | HIRQ_PORT1);
+ writew(val, mmio_base + HOST_IRQ_MASK);
+
+ return 0;
+}
+
+static int inic_pci_device_resume(struct pci_dev *pdev)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ struct inic_host_priv *hpriv = host->private_data;
+ void __iomem *mmio_base = host->iomap[MMIO_BAR];
+ int rc;
+
+ ata_pci_device_do_resume(pdev);
+
+ if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
+ printk("XXX\n");
+ rc = init_controller(mmio_base, hpriv->cached_hctl);
+ if (rc)
+ return rc;
+ }
+
+ ata_host_resume(host);
+
+ return 0;
+}
+
+static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ static int printed_version;
+ struct ata_port_info *pinfo = &inic_port_info;
+ struct ata_probe_ent *probe_ent;
+ struct inic_host_priv *hpriv;
+ void __iomem * const *iomap;
+ int i, rc;
+
+ if (!printed_version++)
+ dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ return rc;
+
+ rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME);
+ if (rc)
+ return rc;
+ iomap = pcim_iomap_table(pdev);
+
+ /* Set dma_mask. This devices doesn't support 64bit addressing. */
+ rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit DMA enable failed\n");
+ return rc;
+ }
+
+ rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "32-bit consistent DMA enable failed\n");
+ return rc;
+ }
+
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+ hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!probe_ent || !hpriv)
+ return -ENOMEM;
+
+ probe_ent->dev = &pdev->dev;
+ INIT_LIST_HEAD(&probe_ent->node);
+
+ probe_ent->sht = pinfo->sht;
+ probe_ent->port_flags = pinfo->flags;
+ probe_ent->pio_mask = pinfo->pio_mask;
+ probe_ent->mwdma_mask = pinfo->mwdma_mask;
+ probe_ent->udma_mask = pinfo->udma_mask;
+ probe_ent->port_ops = pinfo->port_ops;
+ probe_ent->n_ports = NR_PORTS;
+
+ probe_ent->irq = pdev->irq;
+ probe_ent->irq_flags = SA_SHIRQ;
+
+ probe_ent->iomap = iomap;
+
+ for (i = 0; i < NR_PORTS; i++) {
+ struct ata_ioports *port = &probe_ent->port[i];
+ void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
+
+ port->cmd_addr = iomap[2 * i];
+ port->altstatus_addr =
+ port->ctl_addr = (void __iomem *)
+ ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
+ port->scr_addr = port_base + PORT_SCR;
+
+ ata_std_ports(port);
+ }
+
+ probe_ent->private_data = hpriv;
+ hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
+
+ rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl);
+ if (rc) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "failed to initialize controller\n");
+ return rc;
+ }
+
+ pci_set_master(pdev);
+
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+
+ devm_kfree(&pdev->dev, probe_ent);
+
+ return 0;
+}
+
+static const struct pci_device_id inic_pci_tbl[] = {
+ { PCI_VDEVICE(INIT, 0x1622), },
+ { },
+};
+
+static struct pci_driver inic_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = inic_pci_tbl,
+ .suspend = ata_pci_device_suspend,
+ .resume = inic_pci_device_resume,
+ .probe = inic_init_one,
+ .remove = ata_pci_remove_one,
+};
+
+static int __init inic_init(void)
+{
+ return pci_register_driver(&inic_pci_driver);
+}
+
+static void __exit inic_exit(void)
+{
+ pci_unregister_driver(&inic_pci_driver);
+}
+
+MODULE_AUTHOR("Tejun Heo");
+MODULE_DESCRIPTION("low-level driver for Initio 162x SATA");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(pci, inic_pci_tbl);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(inic_init);
+module_exit(inic_exit);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index aae0b5201c1e..769eca52442c 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -34,7 +34,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "sata_mv"
#define DRV_VERSION "0.7"
@@ -342,7 +341,6 @@ static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in);
static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
static void mv_phy_reset(struct ata_port *ap);
static void __mv_phy_reset(struct ata_port *ap, int can_sleep);
-static void mv_host_stop(struct ata_host *host);
static int mv_port_start(struct ata_port *ap);
static void mv_port_stop(struct ata_port *ap);
static void mv_qc_prep(struct ata_queued_cmd *qc);
@@ -406,19 +404,20 @@ static const struct ata_port_operations mv5_ops = {
.qc_prep = mv_qc_prep,
.qc_issue = mv_qc_issue,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = mv_eng_timeout,
.irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = mv5_scr_read,
.scr_write = mv5_scr_write,
.port_start = mv_port_start,
.port_stop = mv_port_stop,
- .host_stop = mv_host_stop,
};
static const struct ata_port_operations mv6_ops = {
@@ -434,19 +433,20 @@ static const struct ata_port_operations mv6_ops = {
.qc_prep = mv_qc_prep,
.qc_issue = mv_qc_issue,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = mv_eng_timeout,
.irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = mv_scr_read,
.scr_write = mv_scr_write,
.port_start = mv_port_start,
.port_stop = mv_port_stop,
- .host_stop = mv_host_stop,
};
static const struct ata_port_operations mv_iie_ops = {
@@ -462,19 +462,20 @@ static const struct ata_port_operations mv_iie_ops = {
.qc_prep = mv_qc_prep_iie,
.qc_issue = mv_qc_issue,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = mv_eng_timeout,
.irq_handler = mv_interrupt,
.irq_clear = mv_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = mv_scr_read,
.scr_write = mv_scr_write,
.port_start = mv_port_start,
.port_stop = mv_port_stop,
- .host_stop = mv_host_stop,
};
static const struct ata_port_info mv_port_info[] = {
@@ -620,7 +621,7 @@ static inline void __iomem *mv_port_base(void __iomem *base, unsigned int port)
static inline void __iomem *mv_ap_base(struct ata_port *ap)
{
- return mv_port_base(ap->host->mmio_base, ap->port_no);
+ return mv_port_base(ap->host->iomap[MV_PRIMARY_BAR], ap->port_no);
}
static inline int mv_get_hc_count(unsigned long port_flags)
@@ -809,35 +810,6 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
}
}
-/**
- * mv_host_stop - Host specific cleanup/stop routine.
- * @host: host data structure
- *
- * Disable ints, cleanup host memory, call general purpose
- * host_stop.
- *
- * LOCKING:
- * Inherited from caller.
- */
-static void mv_host_stop(struct ata_host *host)
-{
- struct mv_host_priv *hpriv = host->private_data;
- struct pci_dev *pdev = to_pci_dev(host->dev);
-
- if (hpriv->hp_flags & MV_HP_FLAG_MSI) {
- pci_disable_msi(pdev);
- } else {
- pci_intx(pdev, 0);
- }
- kfree(hpriv);
- ata_host_stop(host);
-}
-
-static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev)
-{
- dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma);
-}
-
static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
{
u32 cfg = readl(port_mmio + EDMA_CFG_OFS);
@@ -883,22 +855,21 @@ static int mv_port_start(struct ata_port *ap)
void __iomem *port_mmio = mv_ap_base(ap);
void *mem;
dma_addr_t mem_dma;
- int rc = -ENOMEM;
+ int rc;
- pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
- goto err_out;
- memset(pp, 0, sizeof(*pp));
+ return -ENOMEM;
- mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma,
- GFP_KERNEL);
+ mem = dmam_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma,
+ GFP_KERNEL);
if (!mem)
- goto err_out_pp;
+ return -ENOMEM;
memset(mem, 0, MV_PORT_PRIV_DMA_SZ);
rc = ata_pad_alloc(ap, dev);
if (rc)
- goto err_out_priv;
+ return rc;
/* First item in chunk of DMA memory:
* 32-slot command request table (CRQB), 32 bytes each in size
@@ -951,13 +922,6 @@ static int mv_port_start(struct ata_port *ap)
*/
ap->private_data = pp;
return 0;
-
-err_out_priv:
- mv_priv_free(pp, dev);
-err_out_pp:
- kfree(pp);
-err_out:
- return rc;
}
/**
@@ -971,18 +935,11 @@ err_out:
*/
static void mv_port_stop(struct ata_port *ap)
{
- struct device *dev = ap->host->dev;
- struct mv_port_priv *pp = ap->private_data;
unsigned long flags;
spin_lock_irqsave(&ap->host->lock, flags);
mv_stop_dma(ap);
spin_unlock_irqrestore(&ap->host->lock, flags);
-
- ap->private_data = NULL;
- ata_pad_free(ap, dev);
- mv_priv_free(pp, dev);
- kfree(pp);
}
/**
@@ -1348,7 +1305,7 @@ static void mv_err_intr(struct ata_port *ap, int reset_allowed)
*/
static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
{
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
void __iomem *hc_mmio = mv_hc_base(mmio, hc);
struct ata_queued_cmd *qc;
u32 hc_irq_cause;
@@ -1391,8 +1348,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
} else {
/* PIO: check for device (drive) interrupt */
if ((DEV_IRQ << hard_port) & hc_irq_cause) {
- ata_status = readb((void __iomem *)
- ap->ioaddr.status_addr);
+ ata_status = readb(ap->ioaddr.status_addr);
handled = 1;
/* ignore spurious intr if drive still BUSY */
if (ata_status & ATA_BUSY) {
@@ -1452,7 +1408,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
unsigned int hc, handled = 0, n_hcs;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
struct mv_host_priv *hpriv;
u32 irq_stat;
@@ -1528,22 +1484,24 @@ static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in)
{
- void __iomem *mmio = mv5_phy_base(ap->host->mmio_base, ap->port_no);
+ void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
+ void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU)
- return readl(mmio + ofs);
+ return readl(addr + ofs);
else
return (u32) ofs;
}
static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
{
- void __iomem *mmio = mv5_phy_base(ap->host->mmio_base, ap->port_no);
+ void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
+ void __iomem *addr = mv5_phy_base(mmio, ap->port_no);
unsigned int ofs = mv5_scr_offset(sc_reg_in);
if (ofs != 0xffffffffU)
- writelfl(val, mmio + ofs);
+ writelfl(val, addr + ofs);
}
static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio)
@@ -1905,7 +1863,7 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
static void mv_stop_and_reset(struct ata_port *ap)
{
struct mv_host_priv *hpriv = ap->host->private_data;
- void __iomem *mmio = ap->host->mmio_base;
+ void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
mv_stop_dma(ap);
@@ -2003,10 +1961,10 @@ comreset_retry:
break;
}
- tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr);
- tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr);
- tf.lbal = readb((void __iomem *) ap->ioaddr.lbal_addr);
- tf.nsect = readb((void __iomem *) ap->ioaddr.nsect_addr);
+ tf.lbah = readb(ap->ioaddr.lbah_addr);
+ tf.lbam = readb(ap->ioaddr.lbam_addr);
+ tf.lbal = readb(ap->ioaddr.lbal_addr);
+ tf.nsect = readb(ap->ioaddr.nsect_addr);
dev->class = ata_dev_classify(&tf);
if (!ata_dev_enabled(dev)) {
@@ -2038,17 +1996,17 @@ static void mv_phy_reset(struct ata_port *ap)
*/
static void mv_eng_timeout(struct ata_port *ap)
{
+ void __iomem *mmio = ap->host->iomap[MV_PRIMARY_BAR];
struct ata_queued_cmd *qc;
unsigned long flags;
ata_port_printk(ap, KERN_ERR, "Entering mv_eng_timeout\n");
DPRINTK("All regs @ start of eng_timeout\n");
- mv_dump_all_regs(ap->host->mmio_base, ap->port_no,
- to_pci_dev(ap->host->dev));
+ mv_dump_all_regs(mmio, ap->port_no, to_pci_dev(ap->host->dev));
qc = ata_qc_from_tag(ap, ap->active_tag);
printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n",
- ap->host->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd);
+ mmio, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd);
spin_lock_irqsave(&ap->host->lock, flags);
mv_err_intr(ap, 0);
@@ -2076,7 +2034,7 @@ static void mv_eng_timeout(struct ata_port *ap)
*/
static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
{
- unsigned long shd_base = (unsigned long) port_mmio + SHD_BLK_OFS;
+ void __iomem *shd_base = port_mmio + SHD_BLK_OFS;
unsigned serr_ofs;
/* PIO related setup
@@ -2224,7 +2182,7 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
unsigned int board_idx)
{
int rc = 0, n_hc, port, hc;
- void __iomem *mmio = probe_ent->mmio_base;
+ void __iomem *mmio = probe_ent->iomap[MV_PRIMARY_BAR];
struct mv_host_priv *hpriv = probe_ent->private_data;
/* global interrupt mask */
@@ -2342,49 +2300,36 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
- struct ata_probe_ent *probe_ent = NULL;
+ struct device *dev = &pdev->dev;
+ struct ata_probe_ent *probe_ent;
struct mv_host_priv *hpriv;
unsigned int board_idx = (unsigned int)ent->driver_data;
- void __iomem *mmio_base;
- int pci_dev_busy = 0, rc;
+ int rc;
if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
- if (rc) {
+ rc = pcim_enable_device(pdev);
+ if (rc)
return rc;
- }
pci_set_master(pdev);
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << MV_PRIMARY_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, MV_PRIMARY_BAR, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
-
- hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
- memset(hpriv, 0, sizeof(*hpriv));
+ hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ return -ENOMEM;
probe_ent->sht = mv_port_info[board_idx].sht;
probe_ent->port_flags = mv_port_info[board_idx].flags;
@@ -2394,53 +2339,26 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
probe_ent->private_data = hpriv;
/* initialize adapter */
rc = mv_init_host(pdev, probe_ent, board_idx);
- if (rc) {
- goto err_out_hpriv;
- }
+ if (rc)
+ return rc;
/* Enable interrupts */
- if (msi && pci_enable_msi(pdev) == 0) {
- hpriv->hp_flags |= MV_HP_FLAG_MSI;
- } else {
+ if (msi && !pci_enable_msi(pdev))
pci_intx(pdev, 1);
- }
mv_dump_pci_cfg(pdev, 0x68);
mv_print_info(probe_ent);
- if (ata_device_add(probe_ent) == 0) {
- rc = -ENODEV; /* No devices discovered */
- goto err_out_dev_add;
- }
+ if (ata_device_add(probe_ent) == 0)
+ return -ENODEV;
- kfree(probe_ent);
+ devm_kfree(dev, probe_ent);
return 0;
-
-err_out_dev_add:
- if (MV_HP_FLAG_MSI & hpriv->hp_flags) {
- pci_disable_msi(pdev);
- } else {
- pci_intx(pdev, 0);
- }
-err_out_hpriv:
- kfree(hpriv);
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy) {
- pci_disable_device(pdev);
- }
-
- return rc;
}
static int __init mv_init(void)
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index f7a963eb1f02..095ef1b2cd0e 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -49,11 +49,13 @@
#include <linux/libata.h>
#define DRV_NAME "sata_nv"
-#define DRV_VERSION "3.2"
+#define DRV_VERSION "3.3"
#define NV_ADMA_DMA_BOUNDARY 0xffffffffUL
enum {
+ NV_MMIO_BAR = 5,
+
NV_PORTS = 2,
NV_PIO_MASK = 0x1f,
NV_MWDMA_MASK = 0x07,
@@ -213,12 +215,21 @@ struct nv_adma_port_priv {
dma_addr_t cpb_dma;
struct nv_adma_prd *aprd;
dma_addr_t aprd_dma;
+ void __iomem * ctl_block;
+ void __iomem * gen_block;
+ void __iomem * notifier_clear_block;
u8 flags;
};
+struct nv_host_priv {
+ unsigned long type;
+};
+
#define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT)))))
static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static void nv_remove_one (struct pci_dev *pdev);
+static int nv_pci_device_resume(struct pci_dev *pdev);
static void nv_ck804_host_stop(struct ata_host *host);
static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance);
static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance);
@@ -239,6 +250,8 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance);
static void nv_adma_irq_clear(struct ata_port *ap);
static int nv_adma_port_start(struct ata_port *ap);
static void nv_adma_port_stop(struct ata_port *ap);
+static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg);
+static int nv_adma_port_resume(struct ata_port *ap);
static void nv_adma_error_handler(struct ata_port *ap);
static void nv_adma_host_stop(struct ata_host *host);
static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc);
@@ -284,7 +297,9 @@ static struct pci_driver nv_pci_driver = {
.name = DRV_NAME,
.id_table = nv_pci_tbl,
.probe = nv_init_one,
- .remove = ata_pci_remove_one,
+ .suspend = ata_pci_device_suspend,
+ .resume = nv_pci_device_resume,
+ .remove = nv_remove_one,
};
static struct scsi_host_template nv_sht = {
@@ -303,6 +318,8 @@ static struct scsi_host_template nv_sht = {
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
};
static struct scsi_host_template nv_adma_sht = {
@@ -321,6 +338,8 @@ static struct scsi_host_template nv_adma_sht = {
.slave_configure = nv_adma_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+ .suspend = ata_scsi_device_suspend,
+ .resume = ata_scsi_device_resume,
};
static const struct ata_port_operations nv_generic_ops = {
@@ -340,14 +359,14 @@ static const struct ata_port_operations nv_generic_ops = {
.thaw = ata_bmdma_thaw,
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = nv_generic_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static const struct ata_port_operations nv_nf2_ops = {
@@ -367,14 +386,14 @@ static const struct ata_port_operations nv_nf2_ops = {
.thaw = nv_nf2_thaw,
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = nv_nf2_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static const struct ata_port_operations nv_ck804_ops = {
@@ -394,13 +413,14 @@ static const struct ata_port_operations nv_ck804_ops = {
.thaw = nv_ck804_thaw,
.error_handler = nv_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = nv_ck804_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
.host_stop = nv_ck804_host_stop,
};
@@ -422,13 +442,17 @@ static const struct ata_port_operations nv_adma_ops = {
.thaw = nv_ck804_thaw,
.error_handler = nv_adma_error_handler,
.post_internal_cmd = nv_adma_bmdma_stop,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = nv_adma_interrupt,
.irq_clear = nv_adma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
.port_start = nv_adma_port_start,
.port_stop = nv_adma_port_stop,
+ .port_suspend = nv_adma_port_suspend,
+ .port_resume = nv_adma_port_resume,
.host_stop = nv_adma_host_stop,
};
@@ -467,6 +491,7 @@ static struct ata_port_info nv_port_info[] = {
{
.sht = &nv_adma_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+ ATA_FLAG_HRST_TO_RESUME |
ATA_FLAG_MMIO | ATA_FLAG_NCQ,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
@@ -483,57 +508,72 @@ MODULE_VERSION(DRV_VERSION);
static int adma_enabled = 1;
-static inline void __iomem *__nv_adma_ctl_block(void __iomem *mmio,
- unsigned int port_no)
-{
- mmio += NV_ADMA_PORT + port_no * NV_ADMA_PORT_SIZE;
- return mmio;
-}
-
-static inline void __iomem *nv_adma_ctl_block(struct ata_port *ap)
-{
- return __nv_adma_ctl_block(ap->host->mmio_base, ap->port_no);
-}
-
-static inline void __iomem *nv_adma_gen_block(struct ata_port *ap)
-{
- return (ap->host->mmio_base + NV_ADMA_GEN);
-}
-
-static inline void __iomem *nv_adma_notifier_clear_block(struct ata_port *ap)
-{
- return (nv_adma_gen_block(ap) + NV_ADMA_NOTIFIER_CLEAR + (4 * ap->port_no));
-}
-
static void nv_adma_register_mode(struct ata_port *ap)
{
- void __iomem *mmio = nv_adma_ctl_block(ap);
struct nv_adma_port_priv *pp = ap->private_data;
- u16 tmp;
+ void __iomem *mmio = pp->ctl_block;
+ u16 tmp, status;
+ int count = 0;
if (pp->flags & NV_ADMA_PORT_REGISTER_MODE)
return;
+ status = readw(mmio + NV_ADMA_STAT);
+ while(!(status & NV_ADMA_STAT_IDLE) && count < 20) {
+ ndelay(50);
+ status = readw(mmio + NV_ADMA_STAT);
+ count++;
+ }
+ if(count == 20)
+ ata_port_printk(ap, KERN_WARNING,
+ "timeout waiting for ADMA IDLE, stat=0x%hx\n",
+ status);
+
tmp = readw(mmio + NV_ADMA_CTL);
writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
+ count = 0;
+ status = readw(mmio + NV_ADMA_STAT);
+ while(!(status & NV_ADMA_STAT_LEGACY) && count < 20) {
+ ndelay(50);
+ status = readw(mmio + NV_ADMA_STAT);
+ count++;
+ }
+ if(count == 20)
+ ata_port_printk(ap, KERN_WARNING,
+ "timeout waiting for ADMA LEGACY, stat=0x%hx\n",
+ status);
+
pp->flags |= NV_ADMA_PORT_REGISTER_MODE;
}
static void nv_adma_mode(struct ata_port *ap)
{
- void __iomem *mmio = nv_adma_ctl_block(ap);
struct nv_adma_port_priv *pp = ap->private_data;
- u16 tmp;
+ void __iomem *mmio = pp->ctl_block;
+ u16 tmp, status;
+ int count = 0;
if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE))
return;
-
+
WARN_ON(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
tmp = readw(mmio + NV_ADMA_CTL);
writew(tmp | NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
+ status = readw(mmio + NV_ADMA_STAT);
+ while(((status & NV_ADMA_STAT_LEGACY) ||
+ !(status & NV_ADMA_STAT_IDLE)) && count < 20) {
+ ndelay(50);
+ status = readw(mmio + NV_ADMA_STAT);
+ count++;
+ }
+ if(count == 20)
+ ata_port_printk(ap, KERN_WARNING,
+ "timeout waiting for ADMA LEGACY clear and IDLE, stat=0x%hx\n",
+ status);
+
pp->flags &= ~NV_ADMA_PORT_REGISTER_MODE;
}
@@ -568,7 +608,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
/* Subtract 1 since an extra entry may be needed for padding, see
libata-scsi.c */
sg_tablesize = LIBATA_MAX_PRD - 1;
-
+
/* Since the legacy DMA engine is in use, we need to disable ADMA
on the port. */
adma_enable = 0;
@@ -580,7 +620,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN;
adma_enable = 1;
}
-
+
pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &current_reg);
if(ap->port_no == 1)
@@ -589,7 +629,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
else
config_mask = NV_MCP_SATA_CFG_20_PORT0_EN |
NV_MCP_SATA_CFG_20_PORT0_PWB_EN;
-
+
if(adma_enable) {
new_reg = current_reg | config_mask;
pp->flags &= ~NV_ADMA_ATAPI_SETUP_COMPLETE;
@@ -598,10 +638,10 @@ static int nv_adma_slave_config(struct scsi_device *sdev)
new_reg = current_reg & ~config_mask;
pp->flags |= NV_ADMA_ATAPI_SETUP_COMPLETE;
}
-
+
if(current_reg != new_reg)
pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, new_reg);
-
+
blk_queue_bounce_limit(sdev->request_queue, bounce_limit);
blk_queue_segment_boundary(sdev->request_queue, segment_boundary);
blk_queue_max_hw_segments(sdev->request_queue, sg_tablesize);
@@ -648,53 +688,62 @@ static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
return idx;
}
-static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
+static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
{
struct nv_adma_port_priv *pp = ap->private_data;
- int complete = 0, have_err = 0;
u8 flags = pp->cpb[cpb_num].resp_flags;
VPRINTK("CPB %d, flags=0x%x\n", cpb_num, flags);
- if (flags & NV_CPB_RESP_DONE) {
- VPRINTK("CPB flags done, flags=0x%x\n", flags);
- complete = 1;
- }
- if (flags & NV_CPB_RESP_ATA_ERR) {
- ata_port_printk(ap, KERN_ERR, "CPB flags ATA err, flags=0x%x\n", flags);
- have_err = 1;
- complete = 1;
- }
- if (flags & NV_CPB_RESP_CMD_ERR) {
- ata_port_printk(ap, KERN_ERR, "CPB flags CMD err, flags=0x%x\n", flags);
- have_err = 1;
- complete = 1;
- }
- if (flags & NV_CPB_RESP_CPB_ERR) {
- ata_port_printk(ap, KERN_ERR, "CPB flags CPB err, flags=0x%x\n", flags);
- have_err = 1;
- complete = 1;
+ if (unlikely((force_err ||
+ flags & (NV_CPB_RESP_ATA_ERR |
+ NV_CPB_RESP_CMD_ERR |
+ NV_CPB_RESP_CPB_ERR)))) {
+ struct ata_eh_info *ehi = &ap->eh_info;
+ int freeze = 0;
+
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "CPB resp_flags 0x%x", flags );
+ if (flags & NV_CPB_RESP_ATA_ERR) {
+ ata_ehi_push_desc(ehi, ": ATA error");
+ ehi->err_mask |= AC_ERR_DEV;
+ } else if (flags & NV_CPB_RESP_CMD_ERR) {
+ ata_ehi_push_desc(ehi, ": CMD error");
+ ehi->err_mask |= AC_ERR_DEV;
+ } else if (flags & NV_CPB_RESP_CPB_ERR) {
+ ata_ehi_push_desc(ehi, ": CPB error");
+ ehi->err_mask |= AC_ERR_SYSTEM;
+ freeze = 1;
+ } else {
+ /* notifier error, but no error in CPB flags? */
+ ehi->err_mask |= AC_ERR_OTHER;
+ freeze = 1;
+ }
+ /* Kill all commands. EH will determine what actually failed. */
+ if (freeze)
+ ata_port_freeze(ap);
+ else
+ ata_port_abort(ap);
+ return 1;
}
- if(complete || force_err)
- {
+
+ if (flags & NV_CPB_RESP_DONE) {
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
- if(likely(qc)) {
- u8 ata_status = 0;
- /* Only use the ATA port status for non-NCQ commands.
+ VPRINTK("CPB flags done, flags=0x%x\n", flags);
+ if (likely(qc)) {
+ /* Grab the ATA port status for non-NCQ commands.
For NCQ commands the current status may have nothing to do with
the command just completed. */
- if(qc->tf.protocol != ATA_PROT_NCQ)
- ata_status = readb(nv_adma_ctl_block(ap) + (ATA_REG_STATUS * 4));
-
- if(have_err || force_err)
- ata_status |= ATA_ERR;
-
- qc->err_mask |= ac_err_mask(ata_status);
+ if (qc->tf.protocol != ATA_PROT_NCQ) {
+ u8 ata_status = readb(pp->ctl_block + (ATA_REG_STATUS * 4));
+ qc->err_mask |= ac_err_mask(ata_status);
+ }
DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
qc->err_mask);
ata_qc_complete(qc);
}
}
+ return 0;
}
static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
@@ -735,15 +784,14 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
struct nv_adma_port_priv *pp = ap->private_data;
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ void __iomem *mmio = pp->ctl_block;
u16 status;
u32 gen_ctl;
- int have_global_err = 0;
u32 notifier, notifier_error;
/* if in ATA register mode, use standard ata interrupt handler */
if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) {
- u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804)
+ u8 irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804)
>> (NV_INT_PORT_SHIFT * i);
if(ata_tag_valid(ap->active_tag))
/** NV_INT_DEV indication seems unreliable at times
@@ -758,7 +806,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
notifier_clears[i] = notifier | notifier_error;
- gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL);
+ gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL);
if( !NV_ADMA_CHECK_INTR(gen_ctl, ap->port_no) && !notifier &&
!notifier_error)
@@ -774,52 +822,60 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
readw(mmio + NV_ADMA_STAT); /* flush posted write */
rmb();
- /* freeze if hotplugged */
- if (unlikely(status & (NV_ADMA_STAT_HOTPLUG | NV_ADMA_STAT_HOTUNPLUG))) {
- ata_port_printk(ap, KERN_NOTICE, "Hotplug event, freezing\n");
+ handled++; /* irq handled if we got here */
+
+ /* freeze if hotplugged or controller error */
+ if (unlikely(status & (NV_ADMA_STAT_HOTPLUG |
+ NV_ADMA_STAT_HOTUNPLUG |
+ NV_ADMA_STAT_TIMEOUT))) {
+ struct ata_eh_info *ehi = &ap->eh_info;
+
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "ADMA status 0x%08x", status );
+ if (status & NV_ADMA_STAT_TIMEOUT) {
+ ehi->err_mask |= AC_ERR_SYSTEM;
+ ata_ehi_push_desc(ehi, ": timeout");
+ } else if (status & NV_ADMA_STAT_HOTPLUG) {
+ ata_ehi_hotplugged(ehi);
+ ata_ehi_push_desc(ehi, ": hotplug");
+ } else if (status & NV_ADMA_STAT_HOTUNPLUG) {
+ ata_ehi_hotplugged(ehi);
+ ata_ehi_push_desc(ehi, ": hot unplug");
+ }
ata_port_freeze(ap);
- handled++;
continue;
}
- if (status & NV_ADMA_STAT_TIMEOUT) {
- ata_port_printk(ap, KERN_ERR, "timeout, stat=0x%x\n", status);
- have_global_err = 1;
- }
- if (status & NV_ADMA_STAT_CPBERR) {
- ata_port_printk(ap, KERN_ERR, "CPB error, stat=0x%x\n", status);
- have_global_err = 1;
- }
- if ((status & NV_ADMA_STAT_DONE) || have_global_err) {
+ if (status & (NV_ADMA_STAT_DONE |
+ NV_ADMA_STAT_CPBERR)) {
/** Check CPBs for completed commands */
- if(ata_tag_valid(ap->active_tag))
+ if (ata_tag_valid(ap->active_tag)) {
/* Non-NCQ command */
- nv_adma_check_cpb(ap, ap->active_tag, have_global_err ||
- (notifier_error & (1 << ap->active_tag)));
- else {
- int pos;
+ nv_adma_check_cpb(ap, ap->active_tag,
+ notifier_error & (1 << ap->active_tag));
+ } else {
+ int pos, error = 0;
u32 active = ap->sactive;
- while( (pos = ffs(active)) ) {
+
+ while ((pos = ffs(active)) && !error) {
pos--;
- nv_adma_check_cpb(ap, pos, have_global_err ||
- (notifier_error & (1 << pos)) );
+ error = nv_adma_check_cpb(ap, pos,
+ notifier_error & (1 << pos) );
active &= ~(1 << pos );
}
}
}
-
- handled++; /* irq handled if we got here */
}
}
-
+
if(notifier_clears[0] || notifier_clears[1]) {
/* Note: Both notifier clear registers must be written
if either is set, even if one is zero, according to NVIDIA. */
- writel(notifier_clears[0],
- nv_adma_notifier_clear_block(host->ports[0]));
- writel(notifier_clears[1],
- nv_adma_notifier_clear_block(host->ports[1]));
+ struct nv_adma_port_priv *pp = host->ports[0]->private_data;
+ writel(notifier_clears[0], pp->notifier_clear_block);
+ pp = host->ports[1]->private_data;
+ writel(notifier_clears[1], pp->notifier_clear_block);
}
spin_unlock(&host->lock);
@@ -829,19 +885,20 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
static void nv_adma_irq_clear(struct ata_port *ap)
{
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ struct nv_adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio = pp->ctl_block;
u16 status = readw(mmio + NV_ADMA_STAT);
u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
- unsigned long dma_stat_addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
+ void __iomem *dma_stat_addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
/* clear ADMA status */
writew(status, mmio + NV_ADMA_STAT);
writel(notifier | notifier_error,
- nv_adma_notifier_clear_block(ap));
+ pp->notifier_clear_block);
/** clear legacy status */
- outb(inb(dma_stat_addr), dma_stat_addr);
+ iowrite8(ioread8(dma_stat_addr), dma_stat_addr);
}
static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc)
@@ -857,15 +914,15 @@ static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc)
}
/* load PRD table addr. */
- outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
+ iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
/* specify data direction, triple-check start bit is clear */
- dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
if (!rw)
dmactl |= ATA_DMA_WR;
- outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
/* issue r/w command */
ata_exec_command(ap, &qc->tf);
@@ -883,9 +940,9 @@ static void nv_adma_bmdma_start(struct ata_queued_cmd *qc)
}
/* start host DMA transaction */
- dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- outb(dmactl | ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ iowrite8(dmactl | ATA_DMA_START,
+ ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
}
static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc)
@@ -897,8 +954,8 @@ static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc)
return;
/* clear start/stop bit */
- outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
- ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ iowrite8(ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
+ ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_altstatus(ap); /* dummy read */
@@ -910,7 +967,7 @@ static u8 nv_adma_bmdma_status(struct ata_port *ap)
WARN_ON(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE));
- return inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
}
static int nv_adma_port_start(struct ata_port *ap)
@@ -920,7 +977,7 @@ static int nv_adma_port_start(struct ata_port *ap)
int rc;
void *mem;
dma_addr_t mem_dma;
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ void __iomem *mmio;
u16 tmp;
VPRINTK("ENTER\n");
@@ -929,19 +986,21 @@ static int nv_adma_port_start(struct ata_port *ap)
if (rc)
return rc;
- pp = kzalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
-
- mem = dma_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ,
- &mem_dma, GFP_KERNEL);
-
- if (!mem) {
- rc = -ENOMEM;
- goto err_out_kfree;
- }
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+
+ mmio = ap->host->iomap[NV_MMIO_BAR] + NV_ADMA_PORT +
+ ap->port_no * NV_ADMA_PORT_SIZE;
+ pp->ctl_block = mmio;
+ pp->gen_block = ap->host->iomap[NV_MMIO_BAR] + NV_ADMA_GEN;
+ pp->notifier_clear_block = pp->gen_block +
+ NV_ADMA_NOTIFIER_CLEAR + (4 * ap->port_no);
+
+ mem = dmam_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ,
+ &mem_dma, GFP_KERNEL);
+ if (!mem)
+ return -ENOMEM;
memset(mem, 0, NV_ADMA_PORT_PRIV_DMA_SZ);
/*
@@ -975,9 +1034,9 @@ static int nv_adma_port_start(struct ata_port *ap)
/* clear CPB fetch count */
writew(0, mmio + NV_ADMA_CPB_COUNT);
- /* clear GO for register mode */
+ /* clear GO for register mode, enable interrupt */
tmp = readw(mmio + NV_ADMA_CTL);
- writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
+ writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
tmp = readw(mmio + NV_ADMA_CTL);
writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
@@ -987,53 +1046,89 @@ static int nv_adma_port_start(struct ata_port *ap)
readl( mmio + NV_ADMA_CTL ); /* flush posted write */
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
}
static void nv_adma_port_stop(struct ata_port *ap)
{
- struct device *dev = ap->host->dev;
struct nv_adma_port_priv *pp = ap->private_data;
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ void __iomem *mmio = pp->ctl_block;
VPRINTK("ENTER\n");
+ writew(0, mmio + NV_ADMA_CTL);
+}
+
+static int nv_adma_port_suspend(struct ata_port *ap, pm_message_t mesg)
+{
+ struct nv_adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio = pp->ctl_block;
+ /* Go to register mode - clears GO */
+ nv_adma_register_mode(ap);
+
+ /* clear CPB fetch count */
+ writew(0, mmio + NV_ADMA_CPB_COUNT);
+
+ /* disable interrupt, shut down port */
writew(0, mmio + NV_ADMA_CTL);
- ap->private_data = NULL;
- dma_free_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ, pp->cpb, pp->cpb_dma);
- kfree(pp);
- ata_port_stop(ap);
+ return 0;
}
+static int nv_adma_port_resume(struct ata_port *ap)
+{
+ struct nv_adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio = pp->ctl_block;
+ u16 tmp;
+
+ /* set CPB block location */
+ writel(pp->cpb_dma & 0xFFFFFFFF, mmio + NV_ADMA_CPB_BASE_LOW);
+ writel((pp->cpb_dma >> 16 ) >> 16, mmio + NV_ADMA_CPB_BASE_HIGH);
+
+ /* clear any outstanding interrupt conditions */
+ writew(0xffff, mmio + NV_ADMA_STAT);
+
+ /* initialize port variables */
+ pp->flags |= NV_ADMA_PORT_REGISTER_MODE;
+
+ /* clear CPB fetch count */
+ writew(0, mmio + NV_ADMA_CPB_COUNT);
+
+ /* clear GO for register mode, enable interrupt */
+ tmp = readw(mmio + NV_ADMA_CTL);
+ writew((tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
+
+ tmp = readw(mmio + NV_ADMA_CTL);
+ writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
+ readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+ udelay(1);
+ writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
+ readl( mmio + NV_ADMA_CTL ); /* flush posted write */
+
+ return 0;
+}
static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port)
{
- void __iomem *mmio = probe_ent->mmio_base;
+ void __iomem *mmio = probe_ent->iomap[NV_MMIO_BAR];
struct ata_ioports *ioport = &probe_ent->port[port];
VPRINTK("ENTER\n");
mmio += NV_ADMA_PORT + port * NV_ADMA_PORT_SIZE;
- ioport->cmd_addr = (unsigned long) mmio;
- ioport->data_addr = (unsigned long) mmio + (ATA_REG_DATA * 4);
+ ioport->cmd_addr = mmio;
+ ioport->data_addr = mmio + (ATA_REG_DATA * 4);
ioport->error_addr =
- ioport->feature_addr = (unsigned long) mmio + (ATA_REG_ERR * 4);
- ioport->nsect_addr = (unsigned long) mmio + (ATA_REG_NSECT * 4);
- ioport->lbal_addr = (unsigned long) mmio + (ATA_REG_LBAL * 4);
- ioport->lbam_addr = (unsigned long) mmio + (ATA_REG_LBAM * 4);
- ioport->lbah_addr = (unsigned long) mmio + (ATA_REG_LBAH * 4);
- ioport->device_addr = (unsigned long) mmio + (ATA_REG_DEVICE * 4);
+ ioport->feature_addr = mmio + (ATA_REG_ERR * 4);
+ ioport->nsect_addr = mmio + (ATA_REG_NSECT * 4);
+ ioport->lbal_addr = mmio + (ATA_REG_LBAL * 4);
+ ioport->lbam_addr = mmio + (ATA_REG_LBAM * 4);
+ ioport->lbah_addr = mmio + (ATA_REG_LBAH * 4);
+ ioport->device_addr = mmio + (ATA_REG_DEVICE * 4);
ioport->status_addr =
- ioport->command_addr = (unsigned long) mmio + (ATA_REG_STATUS * 4);
+ ioport->command_addr = mmio + (ATA_REG_STATUS * 4);
ioport->altstatus_addr =
- ioport->ctl_addr = (unsigned long) mmio + 0x20;
+ ioport->ctl_addr = mmio + 0x20;
}
static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
@@ -1056,15 +1151,6 @@ static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
for (i = 0; i < probe_ent->n_ports; i++)
nv_adma_setup_port(probe_ent, i);
- for (i = 0; i < probe_ent->n_ports; i++) {
- void __iomem *mmio = __nv_adma_ctl_block(probe_ent->mmio_base, i);
- u16 tmp;
-
- /* enable interrupt, clear reset if not already clear */
- tmp = readw(mmio + NV_ADMA_CTL);
- writew(tmp | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
- }
-
return 0;
}
@@ -1110,18 +1196,31 @@ static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb)
cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag)));
}
+static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
+{
+ struct nv_adma_port_priv *pp = qc->ap->private_data;
+
+ /* ADMA engine can only be used for non-ATAPI DMA commands,
+ or interrupt-driven no-data commands. */
+ if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
+ (qc->tf.flags & ATA_TFLAG_POLLING))
+ return 1;
+
+ if((qc->flags & ATA_QCFLAG_DMAMAP) ||
+ (qc->tf.protocol == ATA_PROT_NODATA))
+ return 0;
+
+ return 1;
+}
+
static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
{
struct nv_adma_port_priv *pp = qc->ap->private_data;
struct nv_adma_cpb *cpb = &pp->cpb[qc->tag];
u8 ctl_flags = NV_CPB_CTL_CPB_VALID |
- NV_CPB_CTL_APRD_VALID |
NV_CPB_CTL_IEN;
- VPRINTK("qc->flags = 0x%lx\n", qc->flags);
-
- if (!(qc->flags & ATA_QCFLAG_DMAMAP) ||
- (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
+ if (nv_adma_use_reg_mode(qc)) {
nv_adma_register_mode(qc->ap);
ata_qc_prep(qc);
return;
@@ -1137,9 +1236,15 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
if (qc->tf.protocol == ATA_PROT_NCQ)
ctl_flags |= NV_CPB_CTL_QUEUE | NV_CPB_CTL_FPDMA;
+ VPRINTK("qc->flags = 0x%lx\n", qc->flags);
+
nv_adma_tf_to_cpb(&qc->tf, cpb->tf);
- nv_adma_fill_sg(qc, cpb);
+ if(qc->flags & ATA_QCFLAG_DMAMAP) {
+ nv_adma_fill_sg(qc, cpb);
+ ctl_flags |= NV_CPB_CTL_APRD_VALID;
+ } else
+ memset(&cpb->aprd[0], 0, sizeof(struct nv_adma_prd) * 5);
/* Be paranoid and don't let the device see NV_CPB_CTL_CPB_VALID until we are
finished filling in all of the contents */
@@ -1150,14 +1255,13 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
{
struct nv_adma_port_priv *pp = qc->ap->private_data;
- void __iomem *mmio = nv_adma_ctl_block(qc->ap);
+ void __iomem *mmio = pp->ctl_block;
VPRINTK("ENTER\n");
- if (!(qc->flags & ATA_QCFLAG_DMAMAP) ||
- (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
+ if (nv_adma_use_reg_mode(qc)) {
/* use ATA register mode */
- VPRINTK("no dmamap or ATAPI, using ATA register mode: 0x%lx\n", qc->flags);
+ VPRINTK("using ATA register mode: 0x%lx\n", qc->flags);
nv_adma_register_mode(qc->ap);
return ata_qc_issue_prot(qc);
} else
@@ -1229,7 +1333,7 @@ static irqreturn_t nv_nf2_interrupt(int irq, void *dev_instance)
irqreturn_t ret;
spin_lock(&host->lock);
- irq_stat = inb(host->ports[0]->ioaddr.scr_addr + NV_INT_STATUS);
+ irq_stat = ioread8(host->ports[0]->ioaddr.scr_addr + NV_INT_STATUS);
ret = nv_do_interrupt(host, irq_stat);
spin_unlock(&host->lock);
@@ -1243,7 +1347,7 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance)
irqreturn_t ret;
spin_lock(&host->lock);
- irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804);
+ irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804);
ret = nv_do_interrupt(host, irq_stat);
spin_unlock(&host->lock);
@@ -1255,7 +1359,7 @@ static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg)
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return ioread32((void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
+ return ioread32(ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
@@ -1263,36 +1367,36 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
if (sc_reg > SCR_CONTROL)
return;
- iowrite32(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
+ iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void nv_nf2_freeze(struct ata_port *ap)
{
- unsigned long scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
int shift = ap->port_no * NV_INT_PORT_SHIFT;
u8 mask;
- mask = inb(scr_addr + NV_INT_ENABLE);
+ mask = ioread8(scr_addr + NV_INT_ENABLE);
mask &= ~(NV_INT_ALL << shift);
- outb(mask, scr_addr + NV_INT_ENABLE);
+ iowrite8(mask, scr_addr + NV_INT_ENABLE);
}
static void nv_nf2_thaw(struct ata_port *ap)
{
- unsigned long scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr;
int shift = ap->port_no * NV_INT_PORT_SHIFT;
u8 mask;
- outb(NV_INT_ALL << shift, scr_addr + NV_INT_STATUS);
+ iowrite8(NV_INT_ALL << shift, scr_addr + NV_INT_STATUS);
- mask = inb(scr_addr + NV_INT_ENABLE);
+ mask = ioread8(scr_addr + NV_INT_ENABLE);
mask |= (NV_INT_MASK << shift);
- outb(mask, scr_addr + NV_INT_ENABLE);
+ iowrite8(mask, scr_addr + NV_INT_ENABLE);
}
static void nv_ck804_freeze(struct ata_port *ap)
{
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
int shift = ap->port_no * NV_INT_PORT_SHIFT;
u8 mask;
@@ -1303,7 +1407,7 @@ static void nv_ck804_freeze(struct ata_port *ap)
static void nv_ck804_thaw(struct ata_port *ap)
{
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR];
int shift = ap->port_no * NV_INT_PORT_SHIFT;
u8 mask;
@@ -1335,32 +1439,13 @@ static void nv_adma_error_handler(struct ata_port *ap)
{
struct nv_adma_port_priv *pp = ap->private_data;
if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
- void __iomem *mmio = nv_adma_ctl_block(ap);
+ void __iomem *mmio = pp->ctl_block;
int i;
u16 tmp;
- u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
- u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
- u32 gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL);
- u32 status = readw(mmio + NV_ADMA_STAT);
-
- ata_port_printk(ap, KERN_ERR, "EH in ADMA mode, notifier 0x%X "
- "notifier_error 0x%X gen_ctl 0x%X status 0x%X\n",
- notifier, notifier_error, gen_ctl, status);
-
- for( i=0;i<NV_ADMA_MAX_CPBS;i++) {
- struct nv_adma_cpb *cpb = &pp->cpb[i];
- if( cpb->ctl_flags || cpb->resp_flags )
- ata_port_printk(ap, KERN_ERR,
- "CPB %d: ctl_flags 0x%x, resp_flags 0x%x\n",
- i, cpb->ctl_flags, cpb->resp_flags);
- }
-
/* Push us back into port register mode for error handling. */
nv_adma_register_mode(ap);
- ata_port_printk(ap, KERN_ERR, "Resetting port\n");
-
/* Mark all of the CPBs as invalid to prevent them from being executed */
for( i=0;i<NV_ADMA_MAX_CPBS;i++)
pp->cpb[i].ctl_flags &= ~NV_CPB_CTL_CPB_VALID;
@@ -1386,10 +1471,10 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
static int printed_version = 0;
struct ata_port_info *ppi[2];
struct ata_probe_ent *probe_ent;
- int pci_dev_busy = 0;
+ struct nv_host_priv *hpriv;
int rc;
u32 bar;
- unsigned long base;
+ void __iomem *base;
unsigned long type = ent->driver_data;
int mask_set = 0;
@@ -1400,17 +1485,17 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_resource_start(pdev, bar) == 0)
return -ENODEV;
- if ( !printed_version++)
+ if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
- goto err_out;
+ return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc) {
- pci_dev_busy = 1;
- goto err_out_disable;
+ pcim_pin_device(pdev);
+ return rc;
}
if(type >= CK804 && adma_enabled) {
@@ -1424,27 +1509,31 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if(!mask_set) {
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
}
rc = -ENOMEM;
+ hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ return -ENOMEM;
+
ppi[0] = ppi[1] = &nv_port_info[type];
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent)
- goto err_out_regions;
+ return -ENOMEM;
- probe_ent->mmio_base = pci_iomap(pdev, 5, 0);
- if (!probe_ent->mmio_base) {
- rc = -EIO;
- goto err_out_free_ent;
- }
+ if (!pcim_iomap(pdev, NV_MMIO_BAR, 0))
+ return -EIO;
+ probe_ent->iomap = pcim_iomap_table(pdev);
- base = (unsigned long)probe_ent->mmio_base;
+ probe_ent->private_data = hpriv;
+ hpriv->type = type;
+ base = probe_ent->iomap[NV_MMIO_BAR];
probe_ent->port[0].scr_addr = base + NV_PORT0_SCR_REG_OFFSET;
probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
@@ -1462,28 +1551,72 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (type == ADMA) {
rc = nv_adma_host_init(probe_ent);
if (rc)
- goto err_out_iounmap;
+ return rc;
}
rc = ata_device_add(probe_ent);
if (rc != NV_PORTS)
- goto err_out_iounmap;
-
- kfree(probe_ent);
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
+}
-err_out_iounmap:
- pci_iounmap(pdev, probe_ent->mmio_base);
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out_disable:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
-err_out:
- return rc;
+static void nv_remove_one (struct pci_dev *pdev)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ struct nv_host_priv *hpriv = host->private_data;
+
+ ata_pci_remove_one(pdev);
+ kfree(hpriv);
+}
+
+static int nv_pci_device_resume(struct pci_dev *pdev)
+{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ struct nv_host_priv *hpriv = host->private_data;
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if(rc)
+ return rc;
+
+ if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
+ if(hpriv->type >= CK804) {
+ u8 regval;
+
+ pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
+ regval |= NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
+ pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
+ }
+ if(hpriv->type == ADMA) {
+ u32 tmp32;
+ struct nv_adma_port_priv *pp;
+ /* enable/disable ADMA on the ports appropriately */
+ pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32);
+
+ pp = host->ports[0]->private_data;
+ if(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)
+ tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT0_EN |
+ NV_MCP_SATA_CFG_20_PORT0_PWB_EN);
+ else
+ tmp32 |= (NV_MCP_SATA_CFG_20_PORT0_EN |
+ NV_MCP_SATA_CFG_20_PORT0_PWB_EN);
+ pp = host->ports[1]->private_data;
+ if(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)
+ tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT1_EN |
+ NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
+ else
+ tmp32 |= (NV_MCP_SATA_CFG_20_PORT1_EN |
+ NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
+
+ pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
+ }
+ }
+
+ ata_host_resume(host);
+
+ return 0;
}
static void nv_ck804_host_stop(struct ata_host *host)
@@ -1495,25 +1628,13 @@ static void nv_ck804_host_stop(struct ata_host *host)
pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
regval &= ~NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
-
- ata_pci_host_stop(host);
}
static void nv_adma_host_stop(struct ata_host *host)
{
struct pci_dev *pdev = to_pci_dev(host->dev);
- int i;
u32 tmp32;
- for (i = 0; i < host->n_ports; i++) {
- void __iomem *mmio = __nv_adma_ctl_block(host->mmio_base, i);
- u16 tmp;
-
- /* disable interrupt */
- tmp = readw(mmio + NV_ADMA_CTL);
- writew(tmp & ~NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
- }
-
/* disable ADMA on the ports */
pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32);
tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT0_EN |
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index f055874a6ec5..3be4cc338d7b 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -39,10 +39,10 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/device.h>
+#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#include "sata_promise.h"
#define DRV_NAME "sata_promise"
@@ -50,6 +50,17 @@
enum {
+ PDC_MMIO_BAR = 3,
+
+ /* register offsets */
+ PDC_FEATURE = 0x04, /* Feature/Error reg (per port) */
+ PDC_SECTOR_COUNT = 0x08, /* Sector count reg (per port) */
+ PDC_SECTOR_NUMBER = 0x0C, /* Sector number reg (per port) */
+ PDC_CYLINDER_LOW = 0x10, /* Cylinder low reg (per port) */
+ PDC_CYLINDER_HIGH = 0x14, /* Cylinder high reg (per port) */
+ PDC_DEVICE = 0x18, /* Device/Head reg (per port) */
+ PDC_COMMAND = 0x1C, /* Command/status reg (per port) */
+ PDC_ALTSTATUS = 0x38, /* Alternate-status/device-control reg (per port) */
PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */
PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
PDC_FLASH_CTL = 0x44, /* Flash control register */
@@ -71,13 +82,23 @@ enum {
PDC_HAS_PATA = (1 << 1), /* PDC20375/20575 has PATA */
+ /* Sequence counter control registers bit definitions */
+ PDC_SEQCNTRL_INT_MASK = (1 << 5), /* Sequence Interrupt Mask */
+
+ /* Feature register values */
+ PDC_FEATURE_ATAPI_PIO = 0x00, /* ATAPI data xfer by PIO */
+ PDC_FEATURE_ATAPI_DMA = 0x01, /* ATAPI data xfer by DMA */
+
+ /* Device/Head register values */
+ PDC_DEVICE_SATA = 0xE0, /* Device/Head value for SATA devices */
+
/* PDC_CTLSTAT bit definitions */
PDC_DMA_ENABLE = (1 << 7),
PDC_IRQ_DISABLE = (1 << 10),
PDC_RESET = (1 << 11), /* HDMA reset */
PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY |
- ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
+ ATA_FLAG_MMIO |
ATA_FLAG_PIO_POLLING,
/* hp->flags bits */
@@ -92,6 +113,7 @@ struct pdc_port_priv {
struct pdc_host_priv {
unsigned long flags;
+ unsigned long port_flags[ATA_MAX_PORTS];
};
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
@@ -100,14 +122,14 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
static irqreturn_t pdc_interrupt (int irq, void *dev_instance);
static void pdc_eng_timeout(struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
-static void pdc_port_stop(struct ata_port *ap);
static void pdc_pata_phy_reset(struct ata_port *ap);
static void pdc_qc_prep(struct ata_queued_cmd *qc);
static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
+static int pdc_check_atapi_dma(struct ata_queued_cmd *qc);
+static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc);
static void pdc_irq_clear(struct ata_port *ap);
static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
-static void pdc_host_stop(struct ata_host *host);
static void pdc_freeze(struct ata_port *ap);
static void pdc_thaw(struct ata_port *ap);
static void pdc_error_handler(struct ata_port *ap);
@@ -139,6 +161,34 @@ static const struct ata_port_operations pdc_sata_ops = {
.check_status = ata_check_status,
.exec_command = pdc_exec_command_mmio,
.dev_select = ata_std_dev_select,
+ .check_atapi_dma = pdc_check_atapi_dma,
+
+ .qc_prep = pdc_qc_prep,
+ .qc_issue = pdc_qc_issue_prot,
+ .freeze = pdc_freeze,
+ .thaw = pdc_thaw,
+ .error_handler = pdc_error_handler,
+ .post_internal_cmd = pdc_post_internal_cmd,
+ .data_xfer = ata_data_xfer,
+ .irq_handler = pdc_interrupt,
+ .irq_clear = pdc_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
+
+ .scr_read = pdc_sata_scr_read,
+ .scr_write = pdc_sata_scr_write,
+ .port_start = pdc_port_start,
+};
+
+/* First-generation chips need a more restrictive ->check_atapi_dma op */
+static const struct ata_port_operations pdc_old_sata_ops = {
+ .port_disable = ata_port_disable,
+ .tf_load = pdc_tf_load_mmio,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = pdc_exec_command_mmio,
+ .dev_select = ata_std_dev_select,
+ .check_atapi_dma = pdc_old_check_atapi_dma,
.qc_prep = pdc_qc_prep,
.qc_issue = pdc_qc_issue_prot,
@@ -146,15 +196,15 @@ static const struct ata_port_operations pdc_sata_ops = {
.thaw = pdc_thaw,
.error_handler = pdc_error_handler,
.post_internal_cmd = pdc_post_internal_cmd,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.irq_handler = pdc_interrupt,
.irq_clear = pdc_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = pdc_sata_scr_read,
.scr_write = pdc_sata_scr_write,
.port_start = pdc_port_start,
- .port_stop = pdc_port_stop,
- .host_stop = pdc_host_stop,
};
static const struct ata_port_operations pdc_pata_ops = {
@@ -164,30 +214,31 @@ static const struct ata_port_operations pdc_pata_ops = {
.check_status = ata_check_status,
.exec_command = pdc_exec_command_mmio,
.dev_select = ata_std_dev_select,
+ .check_atapi_dma = pdc_check_atapi_dma,
.phy_reset = pdc_pata_phy_reset,
.qc_prep = pdc_qc_prep,
.qc_issue = pdc_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = pdc_eng_timeout,
.irq_handler = pdc_interrupt,
.irq_clear = pdc_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = pdc_port_start,
- .port_stop = pdc_port_stop,
- .host_stop = pdc_host_stop,
};
static const struct ata_port_info pdc_port_info[] = {
/* board_2037x */
{
.sht = &pdc_ata_sht,
- .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+ .flags = PDC_COMMON_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
- .port_ops = &pdc_sata_ops,
+ .port_ops = &pdc_old_sata_ops,
},
/* board_20319 */
@@ -197,7 +248,7 @@ static const struct ata_port_info pdc_port_info[] = {
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
- .port_ops = &pdc_sata_ops,
+ .port_ops = &pdc_old_sata_ops,
},
/* board_20619 */
@@ -213,7 +264,7 @@ static const struct ata_port_info pdc_port_info[] = {
/* board_2057x */
{
.sht = &pdc_ata_sht,
- .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+ .flags = PDC_COMMON_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
@@ -271,21 +322,22 @@ static int pdc_port_start(struct ata_port *ap)
struct pdc_port_priv *pp;
int rc;
+ /* fix up port flags and cable type for SATA+PATA chips */
+ ap->flags |= hp->port_flags[ap->port_no];
+ if (ap->flags & ATA_FLAG_SATA)
+ ap->cbl = ATA_CBL_SATA;
+
rc = ata_port_start(ap);
if (rc)
return rc;
- pp = kzalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
- pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
- if (!pp->pkt) {
- rc = -ENOMEM;
- goto err_out_kfree;
- }
+ pp->pkt = dmam_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
+ if (!pp->pkt)
+ return -ENOMEM;
ap->private_data = pp;
@@ -300,40 +352,11 @@ static int pdc_port_start(struct ata_port *ap)
}
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
-}
-
-
-static void pdc_port_stop(struct ata_port *ap)
-{
- struct device *dev = ap->host->dev;
- struct pdc_port_priv *pp = ap->private_data;
-
- ap->private_data = NULL;
- dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
- kfree(pp);
- ata_port_stop(ap);
}
-
-static void pdc_host_stop(struct ata_host *host)
-{
- struct pdc_host_priv *hp = host->private_data;
-
- ata_pci_host_stop(host);
-
- kfree(hp);
-}
-
-
static void pdc_reset_port(struct ata_port *ap)
{
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT;
+ void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT;
unsigned int i;
u32 tmp;
@@ -377,18 +400,102 @@ static void pdc_pata_phy_reset(struct ata_port *ap)
static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
- if (sc_reg > SCR_CONTROL)
+ if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
return 0xffffffffU;
- return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
u32 val)
{
- if (sc_reg > SCR_CONTROL)
+ if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
return;
- writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+}
+
+static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ dma_addr_t sg_table = ap->prd_dma;
+ unsigned int cdb_len = qc->dev->cdb_len;
+ u8 *cdb = qc->cdb;
+ struct pdc_port_priv *pp = ap->private_data;
+ u8 *buf = pp->pkt;
+ u32 *buf32 = (u32 *) buf;
+ unsigned int dev_sel, feature, nbytes;
+
+ /* set control bits (byte 0), zero delay seq id (byte 3),
+ * and seq id (byte 2)
+ */
+ switch (qc->tf.protocol) {
+ case ATA_PROT_ATAPI_DMA:
+ if (!(qc->tf.flags & ATA_TFLAG_WRITE))
+ buf32[0] = cpu_to_le32(PDC_PKT_READ);
+ else
+ buf32[0] = 0;
+ break;
+ case ATA_PROT_ATAPI_NODATA:
+ buf32[0] = cpu_to_le32(PDC_PKT_NODATA);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ buf32[1] = cpu_to_le32(sg_table); /* S/G table addr */
+ buf32[2] = 0; /* no next-packet */
+
+ /* select drive */
+ if (sata_scr_valid(ap)) {
+ dev_sel = PDC_DEVICE_SATA;
+ } else {
+ dev_sel = ATA_DEVICE_OBS;
+ if (qc->dev->devno != 0)
+ dev_sel |= ATA_DEV1;
+ }
+ buf[12] = (1 << 5) | ATA_REG_DEVICE;
+ buf[13] = dev_sel;
+ buf[14] = (1 << 5) | ATA_REG_DEVICE | PDC_PKT_CLEAR_BSY;
+ buf[15] = dev_sel; /* once more, waiting for BSY to clear */
+
+ buf[16] = (1 << 5) | ATA_REG_NSECT;
+ buf[17] = 0x00;
+ buf[18] = (1 << 5) | ATA_REG_LBAL;
+ buf[19] = 0x00;
+
+ /* set feature and byte counter registers */
+ if (qc->tf.protocol != ATA_PROT_ATAPI_DMA) {
+ feature = PDC_FEATURE_ATAPI_PIO;
+ /* set byte counter register to real transfer byte count */
+ nbytes = qc->nbytes;
+ if (nbytes > 0xffff)
+ nbytes = 0xffff;
+ } else {
+ feature = PDC_FEATURE_ATAPI_DMA;
+ /* set byte counter register to 0 */
+ nbytes = 0;
+ }
+ buf[20] = (1 << 5) | ATA_REG_FEATURE;
+ buf[21] = feature;
+ buf[22] = (1 << 5) | ATA_REG_BYTEL;
+ buf[23] = nbytes & 0xFF;
+ buf[24] = (1 << 5) | ATA_REG_BYTEH;
+ buf[25] = (nbytes >> 8) & 0xFF;
+
+ /* send ATAPI packet command 0xA0 */
+ buf[26] = (1 << 5) | ATA_REG_CMD;
+ buf[27] = ATA_CMD_PACKET;
+
+ /* select drive and check DRQ */
+ buf[28] = (1 << 5) | ATA_REG_DEVICE | PDC_PKT_WAIT_DRDY;
+ buf[29] = dev_sel;
+
+ /* we can represent cdb lengths 2/4/6/8/10/12/14/16 */
+ BUG_ON(cdb_len & ~0x1E);
+
+ /* append the CDB as the final part */
+ buf[30] = (((cdb_len >> 1) & 7) << 5) | ATA_REG_DATA | PDC_LAST_REG;
+ memcpy(buf+31, cdb, cdb_len);
}
static void pdc_qc_prep(struct ata_queued_cmd *qc)
@@ -415,6 +522,17 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
pdc_pkt_footer(&qc->tf, pp->pkt, i);
break;
+ case ATA_PROT_ATAPI:
+ ata_qc_prep(qc);
+ break;
+
+ case ATA_PROT_ATAPI_DMA:
+ ata_qc_prep(qc);
+ /*FALLTHROUGH*/
+ case ATA_PROT_ATAPI_NODATA:
+ pdc_atapi_pkt(qc);
+ break;
+
default:
break;
}
@@ -517,7 +635,7 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
{
unsigned int handled = 0;
u32 tmp;
- void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
+ void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
tmp = readl(mmio);
if (tmp & PDC_ERR_MASK) {
@@ -528,6 +646,8 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
switch (qc->tf.protocol) {
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
+ case ATA_PROT_ATAPI_DMA:
+ case ATA_PROT_ATAPI_NODATA:
qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
ata_qc_complete(qc);
handled = 1;
@@ -544,7 +664,7 @@ static inline unsigned int pdc_host_intr( struct ata_port *ap,
static void pdc_irq_clear(struct ata_port *ap)
{
struct ata_host *host = ap->host;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
readl(mmio + PDC_INT_SEQMASK);
}
@@ -560,12 +680,12 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance)
VPRINTK("ENTER\n");
- if (!host || !host->mmio_base) {
+ if (!host || !host->iomap[PDC_MMIO_BAR]) {
VPRINTK("QUICK EXIT\n");
return IRQ_NONE;
}
- mmio_base = host->mmio_base;
+ mmio_base = host->iomap[PDC_MMIO_BAR];
/* reading should also clear interrupts */
mask = readl(mmio_base + PDC_INT_SEQMASK);
@@ -610,32 +730,34 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pdc_port_priv *pp = ap->private_data;
+ void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR];
unsigned int port_no = ap->port_no;
u8 seq = (u8) (port_no + 1);
VPRINTK("ENTER, ap %p\n", ap);
- writel(0x00000001, ap->host->mmio_base + (seq * 4));
- readl(ap->host->mmio_base + (seq * 4)); /* flush */
+ writel(0x00000001, mmio + (seq * 4));
+ readl(mmio + (seq * 4)); /* flush */
pp->pkt[2] = seq;
wmb(); /* flush PRD, pkt writes */
- writel(pp->pkt_dma, (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
+ writel(pp->pkt_dma, ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
}
static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
{
switch (qc->tf.protocol) {
+ case ATA_PROT_ATAPI_NODATA:
+ if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
+ break;
+ /*FALLTHROUGH*/
+ case ATA_PROT_ATAPI_DMA:
case ATA_PROT_DMA:
case ATA_PROT_NODATA:
pdc_packet_start(qc);
return 0;
- case ATA_PROT_ATAPI_DMA:
- BUG();
- break;
-
default:
break;
}
@@ -658,8 +780,44 @@ static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile
ata_exec_command(ap, tf);
}
+static int pdc_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ u8 *scsicmd = qc->scsicmd->cmnd;
+ int pio = 1; /* atapi dma off by default */
+
+ /* Whitelist commands that may use DMA. */
+ switch (scsicmd[0]) {
+ case WRITE_12:
+ case WRITE_10:
+ case WRITE_6:
+ case READ_12:
+ case READ_10:
+ case READ_6:
+ case 0xad: /* READ_DVD_STRUCTURE */
+ case 0xbe: /* READ_CD */
+ pio = 0;
+ }
+ /* -45150 (FFFF4FA2) to -1 (FFFFFFFF) shall use PIO mode */
+ if (scsicmd[0] == WRITE_10) {
+ unsigned int lba;
+ lba = (scsicmd[2] << 24) | (scsicmd[3] << 16) | (scsicmd[4] << 8) | scsicmd[5];
+ if (lba >= 0xFFFF4FA2)
+ pio = 1;
+ }
+ return pio;
+}
-static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
+static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+
+ /* First generation chips cannot use ATAPI DMA on SATA ports */
+ if (sata_scr_valid(ap))
+ return 1;
+ return pdc_check_atapi_dma(qc);
+}
+
+static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr = base;
port->data_addr = base;
@@ -679,7 +837,7 @@ static void pdc_ata_setup_port(struct ata_ioports *port, unsigned long base)
static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
{
- void __iomem *mmio = pe->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
struct pdc_host_priv *hp = pe->private_data;
int hotplug_offset;
u32 tmp;
@@ -733,55 +891,43 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
+ struct ata_probe_ent *probe_ent;
struct pdc_host_priv *hp;
- unsigned long base;
- void __iomem *mmio_base;
+ void __iomem *base;
unsigned int board_idx = (unsigned int) ent->driver_data;
- int pci_dev_busy = 0;
int rc;
+ u8 tmp;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, 3, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
- hp = kzalloc(sizeof(*hp), GFP_KERNEL);
- if (hp == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
+ hp = devm_kzalloc(&pdev->dev, sizeof(*hp), GFP_KERNEL);
+ if (hp == NULL)
+ return -ENOMEM;
probe_ent->private_data = hp;
@@ -794,7 +940,9 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
+
+ base = probe_ent->iomap[PDC_MMIO_BAR];
pdc_ata_setup_port(&probe_ent->port[0], base + 0x200);
pdc_ata_setup_port(&probe_ent->port[1], base + 0x280);
@@ -820,7 +968,17 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
hp->flags |= PDC_FLAG_GEN_II;
/* Fall through */
case board_2037x:
- probe_ent->n_ports = 2;
+ /* TX2plus boards also have a PATA port */
+ tmp = readb(base + PDC_FLASH_CTL+1);
+ if (!(tmp & 0x80)) {
+ probe_ent->n_ports = 3;
+ pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);
+ hp->port_flags[2] = ATA_FLAG_SLAVE_POSS;
+ printk(KERN_INFO DRV_NAME " PATA port found\n");
+ } else
+ probe_ent->n_ports = 2;
+ hp->port_flags[0] = ATA_FLAG_SATA;
+ hp->port_flags[1] = ATA_FLAG_SATA;
break;
case board_20619:
probe_ent->n_ports = 4;
@@ -841,22 +999,11 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
/* initialize adapter */
pdc_host_init(board_idx, probe_ent);
- /* FIXME: Need any other frees than hp? */
if (!ata_device_add(probe_ent))
- kfree(hp);
-
- kfree(probe_ent);
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 710909df4eaf..bfa35ede6551 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -37,13 +37,14 @@
#include <linux/sched.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
-#include <asm/io.h>
#include <linux/libata.h>
#define DRV_NAME "sata_qstor"
#define DRV_VERSION "0.06"
enum {
+ QS_MMIO_BAR = 4,
+
QS_PORTS = 4,
QS_MAX_PRD = LIBATA_MAX_PRD,
QS_CPB_ORDER = 6,
@@ -117,7 +118,6 @@ static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *en
static irqreturn_t qs_intr (int irq, void *dev_instance);
static int qs_port_start(struct ata_port *ap);
static void qs_host_stop(struct ata_host *host);
-static void qs_port_stop(struct ata_port *ap);
static void qs_phy_reset(struct ata_port *ap);
static void qs_qc_prep(struct ata_queued_cmd *qc);
static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
@@ -157,14 +157,15 @@ static const struct ata_port_operations qs_ata_ops = {
.phy_reset = qs_phy_reset,
.qc_prep = qs_qc_prep,
.qc_issue = qs_qc_issue,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = qs_eng_timeout,
.irq_handler = qs_intr,
.irq_clear = qs_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = qs_scr_read,
.scr_write = qs_scr_write,
.port_start = qs_port_start,
- .port_stop = qs_port_stop,
.host_stop = qs_host_stop,
.bmdma_stop = qs_bmdma_stop,
.bmdma_status = qs_bmdma_status,
@@ -197,6 +198,11 @@ static struct pci_driver qs_ata_pci_driver = {
.remove = ata_pci_remove_one,
};
+static void __iomem *qs_mmio_base(struct ata_host *host)
+{
+ return host->iomap[QS_MMIO_BAR];
+}
+
static int qs_check_atapi_dma(struct ata_queued_cmd *qc)
{
return 1; /* ATAPI DMA not supported */
@@ -219,7 +225,7 @@ static void qs_irq_clear(struct ata_port *ap)
static inline void qs_enter_reg_mode(struct ata_port *ap)
{
- u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000);
+ u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
readb(chan + QS_CCT_CTR0); /* flush */
@@ -227,7 +233,7 @@ static inline void qs_enter_reg_mode(struct ata_port *ap)
static inline void qs_reset_channel_logic(struct ata_port *ap)
{
- u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000);
+ u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
writeb(QS_CTR1_RCHN, chan + QS_CCT_CTR1);
readb(chan + QS_CCT_CTR0); /* flush */
@@ -257,14 +263,14 @@ static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return ~0U;
- return readl((void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8)));
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 8));
}
static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8)));
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 8));
}
static unsigned int qs_fill_sg(struct ata_queued_cmd *qc)
@@ -325,7 +331,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
/* host control block (HCB) */
buf[ 0] = QS_HCB_HDR;
buf[ 1] = hflags;
- *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE);
+ *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nbytes);
*(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem);
addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES;
*(__le64 *)(&buf[16]) = cpu_to_le64(addr);
@@ -341,7 +347,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
static inline void qs_packet_start(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000);
+ u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
VPRINTK("ENTER, ap %p\n", ap);
@@ -378,7 +384,7 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host)
{
unsigned int handled = 0;
u8 sFFE;
- u8 __iomem *mmio_base = host->mmio_base;
+ u8 __iomem *mmio_base = qs_mmio_base(host);
do {
u32 sff0 = readl(mmio_base + QS_HST_SFF);
@@ -470,7 +476,7 @@ static irqreturn_t qs_intr(int irq, void *dev_instance)
return IRQ_RETVAL(handled);
}
-static void qs_ata_setup_port(struct ata_ioports *port, unsigned long base)
+static void qs_ata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr =
port->data_addr = base + 0x400;
@@ -492,7 +498,7 @@ static int qs_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
struct qs_port_priv *pp;
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = qs_mmio_base(ap->host);
void __iomem *chan = mmio_base + (ap->port_no * 0x4000);
u64 addr;
int rc;
@@ -501,17 +507,13 @@ static int qs_port_start(struct ata_port *ap)
if (rc)
return rc;
qs_enter_reg_mode(ap);
- pp = kzalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
- pp->pkt = dma_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma,
- GFP_KERNEL);
- if (!pp->pkt) {
- rc = -ENOMEM;
- goto err_out_kfree;
- }
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
+ pp->pkt = dmam_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma,
+ GFP_KERNEL);
+ if (!pp->pkt)
+ return -ENOMEM;
memset(pp->pkt, 0, QS_PKT_BYTES);
ap->private_data = pp;
@@ -519,43 +521,19 @@ static int qs_port_start(struct ata_port *ap)
writel((u32) addr, chan + QS_CCF_CPBA);
writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4);
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
-}
-
-static void qs_port_stop(struct ata_port *ap)
-{
- struct device *dev = ap->host->dev;
- struct qs_port_priv *pp = ap->private_data;
-
- if (pp != NULL) {
- ap->private_data = NULL;
- if (pp->pkt != NULL)
- dma_free_coherent(dev, QS_PKT_BYTES, pp->pkt,
- pp->pkt_dma);
- kfree(pp);
- }
- ata_port_stop(ap);
}
static void qs_host_stop(struct ata_host *host)
{
- void __iomem *mmio_base = host->mmio_base;
- struct pci_dev *pdev = to_pci_dev(host->dev);
+ void __iomem *mmio_base = qs_mmio_base(host);
writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
-
- pci_iounmap(pdev, mmio_base);
}
static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
{
- void __iomem *mmio_base = pe->mmio_base;
+ void __iomem *mmio_base = pe->iomap[QS_MMIO_BAR];
unsigned int port_no;
writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
@@ -630,44 +608,34 @@ static int qs_ata_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- void __iomem *mmio_base;
+ struct ata_probe_ent *probe_ent;
+ void __iomem * const *iomap;
unsigned int board_idx = (unsigned int) ent->driver_data;
int rc, port_no;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc)
- goto err_out;
-
- if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) {
- rc = -ENODEV;
- goto err_out_regions;
- }
+ if ((pci_resource_flags(pdev, QS_MMIO_BAR) & IORESOURCE_MEM) == 0)
+ return -ENODEV;
- mmio_base = pci_iomap(pdev, 4, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME);
+ if (rc)
+ return rc;
+ iomap = pcim_iomap_table(pdev);
- rc = qs_set_dma_masks(pdev, mmio_base);
+ rc = qs_set_dma_masks(pdev, iomap[QS_MMIO_BAR]);
if (rc)
- goto err_out_iounmap;
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
@@ -680,12 +648,12 @@ static int qs_ata_init_one(struct pci_dev *pdev,
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = iomap;
probe_ent->n_ports = QS_PORTS;
for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
- unsigned long chan = (unsigned long)mmio_base +
- (port_no * 0x4000);
+ void __iomem *chan =
+ probe_ent->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
qs_ata_setup_port(&probe_ent->port[port_no], chan);
}
@@ -694,19 +662,11 @@ static int qs_ata_init_one(struct pci_dev *pdev,
/* initialize adapter */
qs_host_init(board_idx, probe_ent);
- rc = ata_device_add(probe_ent);
- kfree(probe_ent);
- if (rc != QS_PORTS)
- goto err_out_iounmap;
- return 0;
+ if (ata_device_add(probe_ent) != QS_PORTS)
+ return -EIO;
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- pci_disable_device(pdev);
- return rc;
+ devm_kfree(&pdev->dev, probe_ent);
+ return 0;
}
static int __init qs_ata_init(void)
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 7808d0369d91..dca3d3749f06 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -49,6 +49,8 @@
#define DRV_VERSION "2.0"
enum {
+ SIL_MMIO_BAR = 5,
+
/*
* host flags
*/
@@ -200,18 +202,18 @@ static const struct ata_port_operations sil_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = sil_freeze,
.thaw = sil_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.irq_handler = sil_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = sil_scr_read,
.scr_write = sil_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
static const struct ata_port_info sil_port_info[] = {
@@ -297,7 +299,8 @@ static void sil_post_set_mode (struct ata_port *ap)
{
struct ata_host *host = ap->host;
struct ata_device *dev;
- void __iomem *addr = host->mmio_base + sil_port[ap->port_no].xfer_mode;
+ void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
+ void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode;
u32 tmp, dev_mode[2];
unsigned int i;
@@ -320,9 +323,9 @@ static void sil_post_set_mode (struct ata_port *ap)
readl(addr); /* flush */
}
-static inline unsigned long sil_scr_addr(struct ata_port *ap, unsigned int sc_reg)
+static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg)
{
- unsigned long offset = ap->ioaddr.scr_addr;
+ void __iomem *offset = ap->ioaddr.scr_addr;
switch (sc_reg) {
case SCR_STATUS:
@@ -341,7 +344,7 @@ static inline unsigned long sil_scr_addr(struct ata_port *ap, unsigned int sc_re
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
- void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
+ void __iomem *mmio = sil_scr_addr(ap, sc_reg);
if (mmio)
return readl(mmio);
return 0xffffffffU;
@@ -349,7 +352,7 @@ static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
- void __iomem *mmio = (void __iomem *) sil_scr_addr(ap, sc_reg);
+ void __iomem *mmio = sil_scr_addr(ap, sc_reg);
if (mmio)
writel(val, mmio);
}
@@ -444,7 +447,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
static irqreturn_t sil_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
- void __iomem *mmio_base = host->mmio_base;
+ void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
int handled = 0;
int i;
@@ -476,7 +479,7 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance)
static void sil_freeze(struct ata_port *ap)
{
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
u32 tmp;
/* global IRQ mask doesn't block SATA IRQ, turn off explicitly */
@@ -491,7 +494,7 @@ static void sil_freeze(struct ata_port *ap)
static void sil_thaw(struct ata_port *ap)
{
- void __iomem *mmio_base = ap->host->mmio_base;
+ void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
u32 tmp;
/* clear IRQ */
@@ -541,9 +544,9 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
{
int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
unsigned int n, quirks = 0;
- unsigned char model_num[41];
+ unsigned char model_num[ATA_ID_PROD_LEN + 1];
- ata_id_c_string(dev->id, model_num, ATA_ID_PROD_OFS, sizeof(model_num));
+ ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
for (n = 0; sil_blacklist[n].product; n++)
if (!strcmp(sil_blacklist[n].product, model_num)) {
@@ -621,38 +624,35 @@ static void sil_init_controller(struct pci_dev *pdev,
static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
+ struct device *dev = &pdev->dev;
+ struct ata_probe_ent *probe_ent;
void __iomem *mmio_base;
int rc;
unsigned int i;
- int pci_dev_busy = 0;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << SIL_MMIO_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->dev = pci_dev_to_dev(pdev);
@@ -666,22 +666,16 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->irq_flags = IRQF_SHARED;
probe_ent->port_flags = sil_port_info[ent->driver_data].flags;
- mmio_base = pci_iomap(pdev, 5, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
-
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
- base = (unsigned long) mmio_base;
+ mmio_base = probe_ent->iomap[SIL_MMIO_BAR];
for (i = 0; i < probe_ent->n_ports; i++) {
- probe_ent->port[i].cmd_addr = base + sil_port[i].tf;
+ probe_ent->port[i].cmd_addr = mmio_base + sil_port[i].tf;
probe_ent->port[i].altstatus_addr =
- probe_ent->port[i].ctl_addr = base + sil_port[i].ctl;
- probe_ent->port[i].bmdma_addr = base + sil_port[i].bmdma;
- probe_ent->port[i].scr_addr = base + sil_port[i].scr;
+ probe_ent->port[i].ctl_addr = mmio_base + sil_port[i].ctl;
+ probe_ent->port[i].bmdma_addr = mmio_base + sil_port[i].bmdma;
+ probe_ent->port[i].scr_addr = mmio_base + sil_port[i].scr;
ata_std_ports(&probe_ent->port[i]);
}
@@ -690,30 +684,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
#ifdef CONFIG_PM
static int sil_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
- ata_pci_device_do_resume(pdev);
sil_init_controller(pdev, host->n_ports, host->ports[0]->flags,
- host->mmio_base);
+ host->iomap[SIL_MMIO_BAR]);
ata_host_resume(host);
return 0;
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 5aa288d2fb86..e65e8d55da3e 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -28,7 +28,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "sata_sil24"
#define DRV_VERSION "0.3"
@@ -61,6 +60,9 @@ struct sil24_port_multiplier {
};
enum {
+ SIL24_HOST_BAR = 0,
+ SIL24_PORT_BAR = 2,
+
/*
* Global controller registers (128 bytes @ BAR0)
*/
@@ -321,12 +323,6 @@ struct sil24_port_priv {
struct ata_taskfile tf; /* Cached taskfile registers */
};
-/* ap->host->private_data */
-struct sil24_host_priv {
- void __iomem *host_base; /* global controller control (128 bytes @BAR0) */
- void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */
-};
-
static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev);
static u8 sil24_check_status(struct ata_port *ap);
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
@@ -341,8 +337,6 @@ static void sil24_thaw(struct ata_port *ap);
static void sil24_error_handler(struct ata_port *ap);
static void sil24_post_internal_cmd(struct ata_queued_cmd *qc);
static int sil24_port_start(struct ata_port *ap);
-static void sil24_port_stop(struct ata_port *ap);
-static void sil24_host_stop(struct ata_host *host);
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
#ifdef CONFIG_PM
static int sil24_pci_device_resume(struct pci_dev *pdev);
@@ -362,7 +356,7 @@ static struct pci_driver sil24_pci_driver = {
.name = DRV_NAME,
.id_table = sil24_pci_tbl,
.probe = sil24_init_one,
- .remove = ata_pci_remove_one, /* safe? */
+ .remove = ata_pci_remove_one,
#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
.resume = sil24_pci_device_resume,
@@ -406,6 +400,8 @@ static const struct ata_port_operations sil24_ops = {
.irq_handler = sil24_interrupt,
.irq_clear = sil24_irq_clear,
+ .irq_on = ata_dummy_irq_on,
+ .irq_ack = ata_dummy_irq_ack,
.scr_read = sil24_scr_read,
.scr_write = sil24_scr_write,
@@ -416,8 +412,6 @@ static const struct ata_port_operations sil24_ops = {
.post_internal_cmd = sil24_post_internal_cmd,
.port_start = sil24_port_start,
- .port_stop = sil24_port_stop,
- .host_stop = sil24_host_stop,
};
/*
@@ -467,7 +461,7 @@ static int sil24_tag(int tag)
static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
if (dev->cdb_len == 16)
writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
@@ -478,7 +472,7 @@ static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
static inline void sil24_update_tf(struct ata_port *ap)
{
struct sil24_port_priv *pp = ap->private_data;
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
struct sil24_prb __iomem *prb = port;
u8 fis[6 * 4];
@@ -501,7 +495,7 @@ static int sil24_scr_map[] = {
static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
{
- void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
@@ -512,7 +506,7 @@ static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg)
static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
{
- void __iomem *scr_addr = (void __iomem *)ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = ap->ioaddr.scr_addr;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr;
addr = scr_addr + sil24_scr_map[sc_reg] * 4;
@@ -528,7 +522,7 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
static int sil24_init_port(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
u32 tmp;
writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
@@ -544,7 +538,7 @@ static int sil24_init_port(struct ata_port *ap)
static int sil24_softreset(struct ata_port *ap, unsigned int *class)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
struct sil24_port_priv *pp = ap->private_data;
struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
dma_addr_t paddr = pp->cmd_block_dma;
@@ -604,7 +598,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
const char *reason;
int tout_msec, rc;
u32 tmp;
@@ -721,7 +715,7 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct sil24_port_priv *pp = ap->private_data;
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
unsigned int tag = sil24_tag(qc->tag);
dma_addr_t paddr;
void __iomem *activate;
@@ -742,7 +736,7 @@ static void sil24_irq_clear(struct ata_port *ap)
static void sil24_freeze(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
/* Port-wide IRQ mask in HOST_CTRL doesn't really work, clear
* PORT_IRQ_ENABLE instead.
@@ -752,7 +746,7 @@ static void sil24_freeze(struct ata_port *ap)
static void sil24_thaw(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
u32 tmp;
/* clear IRQ */
@@ -765,7 +759,7 @@ static void sil24_thaw(struct ata_port *ap)
static void sil24_error_intr(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
struct ata_eh_info *ehi = &ap->eh_info;
int freeze = 0;
u32 irq_stat;
@@ -843,7 +837,7 @@ static void sil24_finish_qc(struct ata_queued_cmd *qc)
static inline void sil24_host_intr(struct ata_port *ap)
{
- void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
+ void __iomem *port = ap->ioaddr.cmd_addr;
u32 slot_stat, qc_active;
int rc;
@@ -878,12 +872,12 @@ static inline void sil24_host_intr(struct ata_port *ap)
static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
- struct sil24_host_priv *hpriv = host->private_data;
+ void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
unsigned handled = 0;
u32 status;
int i;
- status = readl(hpriv->host_base + HOST_IRQ_STAT);
+ status = readl(host_base + HOST_IRQ_STAT);
if (status == 0xffffffff) {
printk(KERN_ERR DRV_NAME ": IRQ status == 0xffffffff, "
@@ -938,13 +932,6 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
sil24_init_port(ap);
}
-static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev)
-{
- const size_t cb_size = sizeof(*pp->cmd_block) * SIL24_MAX_CMDS;
-
- dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
-}
-
static int sil24_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
@@ -952,22 +939,22 @@ static int sil24_port_start(struct ata_port *ap)
union sil24_cmd_block *cb;
size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS;
dma_addr_t cb_dma;
- int rc = -ENOMEM;
+ int rc;
- pp = kzalloc(sizeof(*pp), GFP_KERNEL);
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
- goto err_out;
+ return -ENOMEM;
pp->tf.command = ATA_DRDY;
- cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
+ cb = dmam_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
if (!cb)
- goto err_out_pp;
+ return -ENOMEM;
memset(cb, 0, cb_size);
rc = ata_pad_alloc(ap, dev);
if (rc)
- goto err_out_pad;
+ return rc;
pp->cmd_block = cb;
pp->cmd_block_dma = cb_dma;
@@ -975,33 +962,6 @@ static int sil24_port_start(struct ata_port *ap)
ap->private_data = pp;
return 0;
-
-err_out_pad:
- sil24_cblk_free(pp, dev);
-err_out_pp:
- kfree(pp);
-err_out:
- return rc;
-}
-
-static void sil24_port_stop(struct ata_port *ap)
-{
- struct device *dev = ap->host->dev;
- struct sil24_port_priv *pp = ap->private_data;
-
- sil24_cblk_free(pp, dev);
- ata_pad_free(ap, dev);
- kfree(pp);
-}
-
-static void sil24_host_stop(struct ata_host *host)
-{
- struct sil24_host_priv *hpriv = host->private_data;
- struct pci_dev *pdev = to_pci_dev(host->dev);
-
- pci_iounmap(pdev, hpriv->host_base);
- pci_iounmap(pdev, hpriv->port_base);
- kfree(hpriv);
}
static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
@@ -1066,43 +1026,32 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version = 0;
+ struct device *dev = &pdev->dev;
unsigned int board_id = (unsigned int)ent->driver_data;
struct ata_port_info *pinfo = &sil24_port_info[board_id];
- struct ata_probe_ent *probe_ent = NULL;
- struct sil24_host_priv *hpriv = NULL;
- void __iomem *host_base = NULL;
- void __iomem *port_base = NULL;
+ struct ata_probe_ent *probe_ent;
+ void __iomem *host_base;
+ void __iomem *port_base;
int i, rc;
u32 tmp;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
+ rc = pcim_iomap_regions(pdev,
+ (1 << SIL24_HOST_BAR) | (1 << SIL24_PORT_BAR),
+ DRV_NAME);
if (rc)
- goto out_disable;
-
- rc = -ENOMEM;
- /* map mmio registers */
- host_base = pci_iomap(pdev, 0, 0);
- if (!host_base)
- goto out_free;
- port_base = pci_iomap(pdev, 2, 0);
- if (!port_base)
- goto out_free;
-
- /* allocate & init probe_ent and hpriv */
- probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (!probe_ent)
- goto out_free;
+ return rc;
- hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv)
- goto out_free;
+ /* allocate & init probe_ent */
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (!probe_ent)
+ return -ENOMEM;
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
@@ -1117,10 +1066,10 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->private_data = hpriv;
+ probe_ent->iomap = pcim_iomap_table(pdev);
- hpriv->host_base = host_base;
- hpriv->port_base = port_base;
+ host_base = probe_ent->iomap[SIL24_HOST_BAR];
+ port_base = probe_ent->iomap[SIL24_PORT_BAR];
/*
* Configure the device
@@ -1132,7 +1081,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"64-bit DMA enable failed\n");
- goto out_free;
+ return rc;
}
}
} else {
@@ -1140,13 +1089,13 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit DMA enable failed\n");
- goto out_free;
+ return rc;
}
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
dev_printk(KERN_ERR, &pdev->dev,
"32-bit consistent DMA enable failed\n");
- goto out_free;
+ return rc;
}
}
@@ -1162,11 +1111,10 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
for (i = 0; i < probe_ent->n_ports; i++) {
- unsigned long portu =
- (unsigned long)port_base + i * PORT_REGS_SIZE;
+ void __iomem *port = port_base + i * PORT_REGS_SIZE;
- probe_ent->port[i].cmd_addr = portu;
- probe_ent->port[i].scr_addr = portu + PORT_SCONTROL;
+ probe_ent->port[i].cmd_addr = port;
+ probe_ent->port[i].scr_addr = port + PORT_SCONTROL;
ata_std_ports(&probe_ent->port[i]);
}
@@ -1176,38 +1124,30 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
- kfree(probe_ent);
+ devm_kfree(dev, probe_ent);
return 0;
-
- out_free:
- if (host_base)
- pci_iounmap(pdev, host_base);
- if (port_base)
- pci_iounmap(pdev, port_base);
- kfree(probe_ent);
- kfree(hpriv);
- pci_release_regions(pdev);
- out_disable:
- pci_disable_device(pdev);
- return rc;
}
#ifdef CONFIG_PM
static int sil24_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host *host = dev_get_drvdata(&pdev->dev);
- struct sil24_host_priv *hpriv = host->private_data;
+ void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
+ void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
+ int rc;
- ata_pci_device_do_resume(pdev);
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
- writel(HOST_CTRL_GLOBAL_RST, hpriv->host_base + HOST_CTRL);
+ writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL);
sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags,
- hpriv->host_base, hpriv->port_base);
+ host_base, port_base);
ata_host_resume(host);
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 9c25a1e91730..49c9e2bd706f 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -40,9 +40,11 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include "libata.h"
+#undef DRV_NAME /* already defined in libata.h, for libata-core */
#define DRV_NAME "sata_sis"
-#define DRV_VERSION "0.6"
+#define DRV_VERSION "0.7"
enum {
sis_180 = 0,
@@ -67,9 +69,12 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static const struct pci_device_id sis_pci_tbl[] = {
- { PCI_VDEVICE(SI, 0x180), sis_180 },
- { PCI_VDEVICE(SI, 0x181), sis_180 },
- { PCI_VDEVICE(SI, 0x182), sis_180 },
+ { PCI_VDEVICE(SI, 0x0180), sis_180 }, /* SiS 964/180 */
+ { PCI_VDEVICE(SI, 0x0181), sis_180 }, /* SiS 964/180 */
+ { PCI_VDEVICE(SI, 0x0182), sis_180 }, /* SiS 965/965L */
+ { PCI_VDEVICE(SI, 0x0183), sis_180 }, /* SiS 965/965L */
+ { PCI_VDEVICE(SI, 0x1182), sis_180 }, /* SiS 966/966L */
+ { PCI_VDEVICE(SI, 0x1183), sis_180 }, /* SiS 966/966L */
{ } /* terminate list */
};
@@ -112,18 +117,18 @@ static const struct ata_port_operations sis_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = sis_scr_read,
.scr_write = sis_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static struct ata_port_info sis_port_info = {
@@ -135,31 +140,42 @@ static struct ata_port_info sis_port_info = {
.port_ops = &sis_ops,
};
-
MODULE_AUTHOR("Uwe Koziolek");
MODULE_DESCRIPTION("low-level driver for Silicon Integratad Systems SATA controller");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, sis_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-static unsigned int get_scr_cfg_addr(unsigned int port_no, unsigned int sc_reg, int device)
+static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned int addr = SIS_SCR_BASE + (4 * sc_reg);
+ u8 pmr;
- if (port_no) {
- if (device == 0x182)
- addr += SIS182_SATA1_OFS;
- else
- addr += SIS180_SATA1_OFS;
+ if (ap->port_no) {
+ switch (pdev->device) {
+ case 0x0180:
+ case 0x0181:
+ pci_read_config_byte(pdev, SIS_PMR, &pmr);
+ if ((pmr & SIS_PMR_COMBINED) == 0)
+ addr += SIS180_SATA1_OFS;
+ break;
+
+ case 0x0182:
+ case 0x0183:
+ case 0x1182:
+ case 0x1183:
+ addr += SIS182_SATA1_OFS;
+ break;
+ }
}
-
return addr;
}
static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device);
+ unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
u32 val, val2 = 0;
u8 pmr;
@@ -170,26 +186,28 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
pci_read_config_dword(pdev, cfg_addr, &val);
- if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
+ if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) ||
+ (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED))
pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
return (val|val2) & 0xfffffffb; /* avoid problems with powerdowned ports */
}
-static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
+static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, scr, pdev->device);
+ unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
u8 pmr;
- if (scr == SCR_ERROR) /* doesn't exist in PCI cfg space */
+ if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
return;
pci_read_config_byte(pdev, SIS_PMR, &pmr);
pci_write_config_dword(pdev, cfg_addr, val);
- if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
+ if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) ||
+ (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED))
pci_write_config_dword(pdev, cfg_addr+0x10, val);
}
@@ -207,10 +225,11 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
pci_read_config_byte(pdev, SIS_PMR, &pmr);
- val = inl(ap->ioaddr.scr_addr + (sc_reg * 4));
+ val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4));
- if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
- val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
+ if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) ||
+ (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED))
+ val2 = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
return (val | val2) & 0xfffffffb;
}
@@ -228,9 +247,10 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
if (ap->flags & SIS_FLAG_CFGSCR)
sis_scr_cfg_write(ap, sc_reg, val);
else {
- outl(val, ap->ioaddr.scr_addr + (sc_reg * 4));
- if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
- outl(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10);
+ iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4));
+ if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) ||
+ (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED))
+ iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10);
}
}
@@ -241,29 +261,28 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
int rc;
u32 genctl, val;
struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
- int pci_dev_busy = 0;
u8 pmr;
- u8 port2_start;
+ u8 port2_start = 0x20;
if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc) {
- pci_dev_busy = 1;
- goto err_out;
+ pcim_pin_device(pdev);
+ return rc;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
/* check and see if the SCRs are in IO space or PCI cfg space */
pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
@@ -282,60 +301,79 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
}
pci_read_config_byte(pdev, SIS_PMR, &pmr);
- if (ent->device != 0x182) {
+ switch (ent->device) {
+ case 0x0180:
+ case 0x0181:
+
+ /* The PATA-handling is provided by pata_sis */
+ switch (pmr & 0x30) {
+ case 0x10:
+ ppi[1] = &sis_info133;
+ break;
+
+ case 0x30:
+ ppi[0] = &sis_info133;
+ break;
+ }
if ((pmr & SIS_PMR_COMBINED) == 0) {
dev_printk(KERN_INFO, &pdev->dev,
"Detected SiS 180/181/964 chipset in SATA mode\n");
port2_start = 64;
- }
- else {
+ } else {
dev_printk(KERN_INFO, &pdev->dev,
"Detected SiS 180/181 chipset in combined mode\n");
port2_start=0;
pi.flags |= ATA_FLAG_SLAVE_POSS;
}
- }
- else {
+ break;
+
+ case 0x0182:
+ case 0x0183:
pci_read_config_dword ( pdev, 0x6C, &val);
if (val & (1L << 31)) {
dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965 chipset\n");
pi.flags |= ATA_FLAG_SLAVE_POSS;
- }
- else
+ } else {
dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965L chipset\n");
- port2_start = 0x20;
+ }
+ break;
+
+ case 0x1182:
+ case 0x1183:
+ pci_read_config_dword(pdev, 0x64, &val);
+ if (val & 0x10000000) {
+ dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/1183/966L SATA controller\n");
+ } else {
+ dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/1183/966 SATA controller\n");
+ pi.flags |= ATA_FLAG_SLAVE_POSS;
+ }
+ break;
}
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
- if (!probe_ent) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ if (!probe_ent)
+ return -ENOMEM;
if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
- probe_ent->port[0].scr_addr =
- pci_resource_start(pdev, SIS_SCR_PCI_BAR);
- probe_ent->port[1].scr_addr =
- pci_resource_start(pdev, SIS_SCR_PCI_BAR) + port2_start;
+ void *mmio;
+
+ mmio = pcim_iomap(pdev, SIS_SCR_PCI_BAR, 0);
+ if (!mmio)
+ return -ENOMEM;
+
+ probe_ent->port[0].scr_addr = mmio;
+ probe_ent->port[1].scr_addr = mmio + port2_start;
}
pci_set_master(pdev);
pci_intx(pdev, 1);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -EIO;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-err_out_regions:
- pci_release_regions(pdev);
-
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
-
}
static int __init sis_init(void)
@@ -350,4 +388,3 @@ static void __exit sis_exit(void)
module_init(sis_init);
module_exit(sis_exit);
-
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 5f4e82ade6cd..4e4289994204 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -135,31 +135,31 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
if (tf->ctl != ap->last_ctl) {
- writeb(tf->ctl, (void __iomem *) ioaddr->ctl_addr);
+ writeb(tf->ctl, ioaddr->ctl_addr);
ap->last_ctl = tf->ctl;
ata_wait_idle(ap);
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
writew(tf->feature | (((u16)tf->hob_feature) << 8),
- (void __iomem *) ioaddr->feature_addr);
+ ioaddr->feature_addr);
writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
- (void __iomem *) ioaddr->nsect_addr);
+ ioaddr->nsect_addr);
writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
- (void __iomem *) ioaddr->lbal_addr);
+ ioaddr->lbal_addr);
writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
- (void __iomem *) ioaddr->lbam_addr);
+ ioaddr->lbam_addr);
writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
- (void __iomem *) ioaddr->lbah_addr);
+ ioaddr->lbah_addr);
} else if (is_addr) {
- writew(tf->feature, (void __iomem *) ioaddr->feature_addr);
- writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
- writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
- writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
- writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
+ writew(tf->feature, ioaddr->feature_addr);
+ writew(tf->nsect, ioaddr->nsect_addr);
+ writew(tf->lbal, ioaddr->lbal_addr);
+ writew(tf->lbam, ioaddr->lbam_addr);
+ writew(tf->lbah, ioaddr->lbah_addr);
}
if (tf->flags & ATA_TFLAG_DEVICE)
- writeb(tf->device, (void __iomem *) ioaddr->device_addr);
+ writeb(tf->device, ioaddr->device_addr);
ata_wait_idle(ap);
}
@@ -171,12 +171,12 @@ static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
u16 nsect, lbal, lbam, lbah, feature;
tf->command = k2_stat_check_status(ap);
- tf->device = readw((void __iomem *)ioaddr->device_addr);
- feature = readw((void __iomem *)ioaddr->error_addr);
- nsect = readw((void __iomem *)ioaddr->nsect_addr);
- lbal = readw((void __iomem *)ioaddr->lbal_addr);
- lbam = readw((void __iomem *)ioaddr->lbam_addr);
- lbah = readw((void __iomem *)ioaddr->lbah_addr);
+ tf->device = readw(ioaddr->device_addr);
+ feature = readw(ioaddr->error_addr);
+ nsect = readw(ioaddr->nsect_addr);
+ lbal = readw(ioaddr->lbal_addr);
+ lbam = readw(ioaddr->lbam_addr);
+ lbah = readw(ioaddr->lbah_addr);
tf->feature = feature;
tf->nsect = nsect;
@@ -349,21 +349,21 @@ static const struct ata_port_operations k2_sata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = k2_sata_scr_read,
.scr_write = k2_sata_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
-static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base)
+static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr = base + K2_SATA_TF_CMD_OFFSET;
port->data_addr = base + K2_SATA_TF_DATA_OFFSET;
@@ -386,12 +386,11 @@ static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base)
static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
+ struct device *dev = &pdev->dev;
+ struct ata_probe_ent *probe_ent;
void __iomem *mmio_base;
const struct k2_board_info *board_info =
&k2_board_info[ent->driver_data];
- int pci_dev_busy = 0;
int rc;
int i;
@@ -402,7 +401,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
* If this driver happens to only be useful on Apple's K2, then
* we should check that here as it has a normal Serverworks ID
*/
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
/*
@@ -412,48 +411,27 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
if (pci_resource_len(pdev, 5) == 0)
return -ENODEV;
- /* Request PCI regions */
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ /* Request and iomap PCI regions */
+ rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, 5, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
- /* Clear a magic bit in SCR1 according to Darwin, those help
- * some funky seagate drives (though so far, those were already
- * set by the firmware on the machines I had access to)
- */
- writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000,
- mmio_base + K2_SATA_SICR1_OFFSET);
-
- /* Clear SATA error & interrupts we don't use */
- writel(0xffffffff, mmio_base + K2_SATA_SCR_ERROR_OFFSET);
- writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
-
probe_ent->sht = &k2_sata_sht;
probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | board_info->port_flags;
@@ -461,7 +439,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
probe_ent->n_ports = 4;
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
/* We don't care much about the PIO/UDMA masks, but the core won't like us
* if we don't fill these
@@ -470,28 +448,33 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
probe_ent->mwdma_mask = 0x7;
probe_ent->udma_mask = 0x7f;
+ mmio_base = probe_ent->iomap[5];
+
/* different controllers have different number of ports - currently 4 or 8 */
/* All ports are on the same function. Multi-function device is no
* longer available. This should not be seen in any system. */
for (i = 0; i < board_info->n_ports; i++)
- k2_sata_setup_port(&probe_ent->port[i], base + i * K2_SATA_PORT_OFFSET);
+ k2_sata_setup_port(&probe_ent->port[i],
+ mmio_base + i * K2_SATA_PORT_OFFSET);
+
+ /* Clear a magic bit in SCR1 according to Darwin, those help
+ * some funky seagate drives (though so far, those were already
+ * set by the firmware on the machines I had access to)
+ */
+ writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000,
+ mmio_base + K2_SATA_SICR1_OFFSET);
+
+ /* Clear SATA error & interrupts we don't use */
+ writel(0xffffffff, mmio_base + K2_SATA_SCR_ERROR_OFFSET);
+ writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
pci_set_master(pdev);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
/* 0x240 is device ID for Apple K2 device
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index ae7992de4b08..06e87a377382 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -42,7 +42,6 @@
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
-#include <asm/io.h>
#include "sata_promise.h"
#define DRV_NAME "sata_sx4"
@@ -50,6 +49,9 @@
enum {
+ PDC_MMIO_BAR = 3,
+ PDC_DIMM_BAR = 4,
+
PDC_PRD_TBL = 0x44, /* Direct command DMA table addr */
PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */
@@ -138,8 +140,6 @@ struct pdc_port_priv {
};
struct pdc_host_priv {
- void __iomem *dimm_mmio;
-
unsigned int doing_hdma;
unsigned int hdma_prod;
unsigned int hdma_cons;
@@ -156,11 +156,9 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance);
static void pdc_eng_timeout(struct ata_port *ap);
static void pdc_20621_phy_reset (struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
-static void pdc_port_stop(struct ata_port *ap);
static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
-static void pdc20621_host_stop(struct ata_host *host);
static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe,
@@ -205,13 +203,13 @@ static const struct ata_port_operations pdc_20621_ops = {
.phy_reset = pdc_20621_phy_reset,
.qc_prep = pdc20621_qc_prep,
.qc_issue = pdc20621_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.eng_timeout = pdc_eng_timeout,
.irq_handler = pdc20621_interrupt,
.irq_clear = pdc20621_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = pdc_port_start,
- .port_stop = pdc_port_stop,
- .host_stop = pdc20621_host_stop,
};
static const struct ata_port_info pdc_port_info[] = {
@@ -243,18 +241,6 @@ static struct pci_driver pdc_sata_pci_driver = {
};
-static void pdc20621_host_stop(struct ata_host *host)
-{
- struct pci_dev *pdev = to_pci_dev(host->dev);
- struct pdc_host_priv *hpriv = host->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
-
- pci_iounmap(pdev, dimm_mmio);
- kfree(hpriv);
-
- pci_iounmap(pdev, host->mmio_base);
-}
-
static int pdc_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
@@ -265,43 +251,19 @@ static int pdc_port_start(struct ata_port *ap)
if (rc)
return rc;
- pp = kmalloc(sizeof(*pp), GFP_KERNEL);
- if (!pp) {
- rc = -ENOMEM;
- goto err_out;
- }
- memset(pp, 0, sizeof(*pp));
+ pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
+ if (!pp)
+ return -ENOMEM;
- pp->pkt = dma_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
- if (!pp->pkt) {
- rc = -ENOMEM;
- goto err_out_kfree;
- }
+ pp->pkt = dmam_alloc_coherent(dev, 128, &pp->pkt_dma, GFP_KERNEL);
+ if (!pp->pkt)
+ return -ENOMEM;
ap->private_data = pp;
return 0;
-
-err_out_kfree:
- kfree(pp);
-err_out:
- ata_port_stop(ap);
- return rc;
-}
-
-
-static void pdc_port_stop(struct ata_port *ap)
-{
- struct device *dev = ap->host->dev;
- struct pdc_port_priv *pp = ap->private_data;
-
- ap->private_data = NULL;
- dma_free_coherent(dev, 128, pp->pkt, pp->pkt_dma);
- kfree(pp);
- ata_port_stop(ap);
}
-
static void pdc_20621_phy_reset (struct ata_port *ap)
{
VPRINTK("ENTER\n");
@@ -452,9 +414,8 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
struct scatterlist *sg;
struct ata_port *ap = qc->ap;
struct pdc_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->mmio_base;
- struct pdc_host_priv *hpriv = ap->host->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
unsigned int portno = ap->port_no;
unsigned int i, idx, total_len = 0, sgt_len;
u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
@@ -513,9 +474,8 @@ static void pdc20621_nodata_prep(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct pdc_port_priv *pp = ap->private_data;
- void __iomem *mmio = ap->host->mmio_base;
- struct pdc_host_priv *hpriv = ap->host->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *mmio = ap->host->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
unsigned int portno = ap->port_no;
unsigned int i;
@@ -565,7 +525,7 @@ static void __pdc20621_push_hdma(struct ata_queued_cmd *qc,
{
struct ata_port *ap = qc->ap;
struct ata_host *host = ap->host;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -619,8 +579,7 @@ static void pdc20621_dump_hdma(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
unsigned int port_no = ap->port_no;
- struct pdc_host_priv *hpriv = ap->host->private_data;
- void *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
dimm_mmio += (port_no * PDC_DIMM_WINDOW_STEP);
dimm_mmio += PDC_DIMM_HOST_PKT;
@@ -639,7 +598,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct ata_host *host = ap->host;
unsigned int port_no = ap->port_no;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
u8 seq = (u8) (port_no + 1);
unsigned int port_ofs;
@@ -668,8 +627,8 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
readl(mmio + PDC_20621_SEQCTL + (seq * 4)); /* flush */
writel(port_ofs + PDC_DIMM_ATA_PKT,
- (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
VPRINTK("submitted ofs 0x%x (%u), seq %u\n",
port_ofs + PDC_DIMM_ATA_PKT,
port_ofs + PDC_DIMM_ATA_PKT,
@@ -747,8 +706,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4));
readl(mmio + PDC_20621_SEQCTL + (seq * 4));
writel(port_ofs + PDC_DIMM_ATA_PKT,
- (void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
- readl((void __iomem *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
+ readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT);
}
/* step two - execute ATA command */
@@ -781,7 +740,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
static void pdc20621_irq_clear(struct ata_port *ap)
{
struct ata_host *host = ap->host;
- void __iomem *mmio = host->mmio_base;
+ void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
mmio += PDC_CHIP0_OFS;
@@ -799,12 +758,12 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance)
VPRINTK("ENTER\n");
- if (!host || !host->mmio_base) {
+ if (!host || !host->iomap[PDC_MMIO_BAR]) {
VPRINTK("QUICK EXIT\n");
return IRQ_NONE;
}
- mmio_base = host->mmio_base;
+ mmio_base = host->iomap[PDC_MMIO_BAR];
/* reading should also clear interrupts */
mmio_base += PDC_CHIP0_OFS;
@@ -905,7 +864,7 @@ static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile
}
-static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
+static void pdc_sata_setup_port(struct ata_ioports *port, void __iomem *base)
{
port->cmd_addr = base;
port->data_addr = base;
@@ -931,9 +890,8 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
u16 idx;
u8 page_mask;
long dist;
- void __iomem *mmio = pe->mmio_base;
- struct pdc_host_priv *hpriv = pe->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -987,9 +945,8 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
u16 idx;
u8 page_mask;
long dist;
- void __iomem *mmio = pe->mmio_base;
- struct pdc_host_priv *hpriv = pe->private_data;
- void __iomem *dimm_mmio = hpriv->dimm_mmio;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+ void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1034,7 +991,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device,
u32 subaddr, u32 *pdata)
{
- void __iomem *mmio = pe->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
u32 i2creg = 0;
u32 status;
u32 count =0;
@@ -1093,7 +1050,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
u32 data = 0;
int size, i;
u8 bdimmsize;
- void __iomem *mmio = pe->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
static const struct {
unsigned int reg;
unsigned int ofs;
@@ -1155,8 +1112,8 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
{
u32 data, spd0;
- int error, i;
- void __iomem *mmio = pe->mmio_base;
+ int error, i;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1210,7 +1167,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
u32 ticks=0;
u32 clock=0;
u32 fparam=0;
- void __iomem *mmio = pe->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1334,7 +1291,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
static void pdc_20621_init(struct ata_probe_ent *pe)
{
u32 tmp;
- void __iomem *mmio = pe->mmio_base;
+ void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
/* hard-code chip #0 */
mmio += PDC_CHIP0_OFS;
@@ -1365,67 +1322,43 @@ static void pdc_20621_init(struct ata_probe_ent *pe)
static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
- void __iomem *mmio_base;
- void __iomem *dimm_mmio = NULL;
- struct pdc_host_priv *hpriv = NULL;
+ struct ata_probe_ent *probe_ent;
+ void __iomem *base;
+ struct pdc_host_priv *hpriv;
unsigned int board_idx = (unsigned int) ent->driver_data;
- int pci_dev_busy = 0;
int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, (1 << PDC_MMIO_BAR) | (1 << PDC_DIMM_BAR),
+ DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
- memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, 3, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
- hpriv = kmalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv) {
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
- memset(hpriv, 0, sizeof(*hpriv));
-
- dimm_mmio = pci_iomap(pdev, 4, 0);
- if (!dimm_mmio) {
- kfree(hpriv);
- rc = -ENOMEM;
- goto err_out_iounmap;
- }
-
- hpriv->dimm_mmio = dimm_mmio;
+ hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ return -ENOMEM;
probe_ent->sht = pdc_port_info[board_idx].sht;
probe_ent->port_flags = pdc_port_info[board_idx].flags;
@@ -1436,10 +1369,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
probe_ent->private_data = hpriv;
- base += PDC_CHIP0_OFS;
+ base = probe_ent->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
probe_ent->n_ports = 4;
pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
@@ -1451,31 +1384,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
/* initialize adapter */
/* initialize local dimm */
- if (pdc20621_dimm_init(probe_ent)) {
- rc = -ENOMEM;
- goto err_out_iounmap_dimm;
- }
+ if (pdc20621_dimm_init(probe_ent))
+ return -ENOMEM;
pdc_20621_init(probe_ent);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_iounmap_dimm: /* only get to this label if 20621 */
- kfree(hpriv);
- pci_iounmap(pdev, dimm_mmio);
-err_out_iounmap:
- pci_iounmap(pdev, mmio_base);
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index a43aec62d505..80131eec68f4 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -108,7 +108,7 @@ static const struct ata_port_operations uli_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
@@ -117,13 +117,13 @@ static const struct ata_port_operations uli_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = uli_scr_read,
.scr_write = uli_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
static struct ata_port_info uli_port_info = {
@@ -189,62 +189,60 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_port_info *ppi[2];
int rc;
unsigned int board_idx = (unsigned int) ent->driver_data;
- int pci_dev_busy = 0;
struct uli_priv *hpriv;
+ void __iomem * const *iomap;
if (!printed_version++)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc) {
- pci_dev_busy = 1;
- goto err_out;
+ pcim_pin_device(pdev);
+ return rc;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
ppi[0] = ppi[1] = &uli_port_info;
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
- if (!probe_ent) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
+ if (!probe_ent)
+ return -ENOMEM;
- hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL);
- if (!hpriv) {
- rc = -ENOMEM;
- goto err_out_probe_ent;
- }
+ hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+ if (!hpriv)
+ return -ENOMEM;
probe_ent->private_data = hpriv;
+ iomap = pcim_iomap_table(pdev);
+
switch (board_idx) {
case uli_5287:
hpriv->scr_cfg_addr[0] = ULI5287_BASE;
hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
probe_ent->n_ports = 4;
- probe_ent->port[2].cmd_addr = pci_resource_start(pdev, 0) + 8;
+ probe_ent->port[2].cmd_addr = iomap[0] + 8;
probe_ent->port[2].altstatus_addr =
- probe_ent->port[2].ctl_addr =
- (pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS) + 4;
- probe_ent->port[2].bmdma_addr = pci_resource_start(pdev, 4) + 16;
+ probe_ent->port[2].ctl_addr = (void __iomem *)
+ ((unsigned long)iomap[1] | ATA_PCI_CTL_OFS) + 4;
+ probe_ent->port[2].bmdma_addr = iomap[4] + 16;
hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4;
- probe_ent->port[3].cmd_addr = pci_resource_start(pdev, 2) + 8;
+ probe_ent->port[3].cmd_addr = iomap[2] + 8;
probe_ent->port[3].altstatus_addr =
- probe_ent->port[3].ctl_addr =
- (pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS) + 4;
- probe_ent->port[3].bmdma_addr = pci_resource_start(pdev, 4) + 24;
+ probe_ent->port[3].ctl_addr = (void __iomem *)
+ ((unsigned long)iomap[3] | ATA_PCI_CTL_OFS) + 4;
+ probe_ent->port[3].bmdma_addr = iomap[4] + 24;
hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5;
ata_std_ports(&probe_ent->port[2]);
@@ -269,21 +267,11 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
pci_intx(pdev, 1);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_probe_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
-
}
static int __init uli_init(void)
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index d3d5c0d57032..baca6d79bb0b 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -44,7 +44,6 @@
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>
-#include <asm/io.h>
#define DRV_NAME "sata_via"
#define DRV_VERSION "2.0"
@@ -59,11 +58,14 @@ enum {
SATA_INT_GATE = 0x41, /* SATA interrupt gating */
SATA_NATIVE_MODE = 0x42, /* Native mode enable */
SATA_PATA_SHARING = 0x49, /* PATA/SATA sharing func ctrl */
-
+ PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */
+ PATA_PIO_TIMING = 0xAB, /* PATA timing register */
+
PORT0 = (1 << 1),
PORT1 = (1 << 0),
ALL_PORTS = PORT0 | PORT1,
- N_PORTS = 2,
+ PATA_PORT = 2, /* PATA is port 2 */
+ N_PORTS = 3,
NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
@@ -76,6 +78,11 @@ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static void svia_noop_freeze(struct ata_port *ap);
static void vt6420_error_handler(struct ata_port *ap);
+static void vt6421_sata_error_handler(struct ata_port *ap);
+static void vt6421_pata_error_handler(struct ata_port *ap);
+static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev);
+static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
+static int vt6421_port_start(struct ata_port *ap);
static const struct pci_device_id svia_pci_tbl[] = {
{ PCI_VDEVICE(VIA, 0x5337), vt6420 },
@@ -127,7 +134,7 @@ static const struct ata_port_operations vt6420_sata_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = svia_noop_freeze,
.thaw = ata_bmdma_thaw,
@@ -136,15 +143,49 @@ static const struct ata_port_operations vt6420_sata_ops = {
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
};
-static const struct ata_port_operations vt6421_sata_ops = {
+static const struct ata_port_operations vt6421_pata_ops = {
.port_disable = ata_port_disable,
+
+ .set_piomode = vt6421_set_pio_mode,
+ .set_dmamode = vt6421_set_dma_mode,
+
+ .tf_load = ata_tf_load,
+ .tf_read = ata_tf_read,
+ .check_status = ata_check_status,
+ .exec_command = ata_exec_command,
+ .dev_select = ata_std_dev_select,
+
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+
+ .qc_prep = ata_qc_prep,
+ .qc_issue = ata_qc_issue_prot,
+ .data_xfer = ata_data_xfer,
+
+ .freeze = ata_bmdma_freeze,
+ .thaw = ata_bmdma_thaw,
+ .error_handler = vt6421_pata_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .irq_handler = ata_interrupt,
+ .irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
+
+ .port_start = vt6421_port_start,
+};
+
+static const struct ata_port_operations vt6421_sata_ops = {
+ .port_disable = ata_port_disable,
+
.tf_load = ata_tf_load,
.tf_read = ata_tf_read,
.check_status = ata_check_status,
@@ -158,22 +199,22 @@ static const struct ata_port_operations vt6421_sata_ops = {
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_pio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
+ .error_handler = vt6421_sata_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.irq_handler = ata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = svia_scr_read,
.scr_write = svia_scr_write,
- .port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_host_stop,
+ .port_start = vt6421_port_start,
};
static struct ata_port_info vt6420_port_info = {
@@ -195,14 +236,14 @@ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return inl(ap->ioaddr.scr_addr + (4 * sc_reg));
+ return ioread32(ap->ioaddr.scr_addr + (4 * sc_reg));
}
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
{
if (sc_reg > SCR_CONTROL)
return;
- outl(val, ap->ioaddr.scr_addr + (4 * sc_reg));
+ iowrite32(val, ap->ioaddr.scr_addr + (4 * sc_reg));
}
static void svia_noop_freeze(struct ata_port *ap)
@@ -289,6 +330,61 @@ static void vt6420_error_handler(struct ata_port *ap)
NULL, ata_std_postreset);
}
+static int vt6421_pata_prereset(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u8 tmp;
+
+ pci_read_config_byte(pdev, PATA_UDMA_TIMING, &tmp);
+ if (tmp & 0x10)
+ ap->cbl = ATA_CBL_PATA40;
+ else
+ ap->cbl = ATA_CBL_PATA80;
+ return 0;
+}
+
+static void vt6421_pata_error_handler(struct ata_port *ap)
+{
+ return ata_bmdma_drive_eh(ap, vt6421_pata_prereset, ata_std_softreset,
+ NULL, ata_std_postreset);
+}
+
+static int vt6421_sata_prereset(struct ata_port *ap)
+{
+ ap->cbl = ATA_CBL_SATA;
+ return 0;
+}
+
+static void vt6421_sata_error_handler(struct ata_port *ap)
+{
+ return ata_bmdma_drive_eh(ap, vt6421_sata_prereset, ata_std_softreset,
+ NULL, ata_std_postreset);
+}
+
+static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ static const u8 pio_bits[] = { 0xA8, 0x65, 0x65, 0x31, 0x20 };
+ pci_write_config_byte(pdev, PATA_PIO_TIMING, pio_bits[adev->pio_mode - XFER_PIO_0]);
+}
+
+static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ static const u8 udma_bits[] = { 0xEE, 0xE8, 0xE6, 0xE4, 0xE2, 0xE1, 0xE0, 0xE0 };
+ pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->pio_mode - XFER_UDMA_0]);
+}
+
+static int vt6421_port_start(struct ata_port *ap)
+{
+ if (ap->port_no == PATA_PORT) {
+ ap->ops = &vt6421_pata_ops;
+ ap->mwdma_mask = 0;
+ ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST;
+ }
+ return ata_port_start(ap);
+}
+
static const unsigned int svia_bar_sizes[] = {
8, 4, 8, 4, 16, 256
};
@@ -297,31 +393,28 @@ static const unsigned int vt6421_bar_sizes[] = {
16, 16, 16, 16, 32, 128
};
-static unsigned long svia_scr_addr(unsigned long addr, unsigned int port)
+static void __iomem * svia_scr_addr(void __iomem *addr, unsigned int port)
{
return addr + (port * 128);
}
-static unsigned long vt6421_scr_addr(unsigned long addr, unsigned int port)
+static void __iomem * vt6421_scr_addr(void __iomem *addr, unsigned int port)
{
return addr + (port * 64);
}
static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
- struct pci_dev *pdev,
- unsigned int port)
+ void __iomem * const *iomap, unsigned int port)
{
- unsigned long reg_addr = pci_resource_start(pdev, port);
- unsigned long bmdma_addr = pci_resource_start(pdev, 4) + (port * 8);
- unsigned long scr_addr;
+ void __iomem *reg_addr = iomap[port];
+ void __iomem *bmdma_addr = iomap[4] + (port * 8);
probe_ent->port[port].cmd_addr = reg_addr;
probe_ent->port[port].altstatus_addr =
- probe_ent->port[port].ctl_addr = (reg_addr + 8) | ATA_PCI_CTL_OFS;
+ probe_ent->port[port].ctl_addr = (void __iomem *)
+ ((unsigned long)(reg_addr + 8) | ATA_PCI_CTL_OFS);
probe_ent->port[port].bmdma_addr = bmdma_addr;
-
- scr_addr = vt6421_scr_addr(pci_resource_start(pdev, 5), port);
- probe_ent->port[port].scr_addr = scr_addr;
+ probe_ent->port[port].scr_addr = vt6421_scr_addr(iomap[5], port);
ata_std_ports(&probe_ent->port[port]);
}
@@ -330,16 +423,16 @@ static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
{
struct ata_probe_ent *probe_ent;
struct ata_port_info *ppi[2];
-
+ void __iomem * const *iomap;
+
ppi[0] = ppi[1] = &vt6420_port_info;
probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
if (!probe_ent)
return NULL;
- probe_ent->port[0].scr_addr =
- svia_scr_addr(pci_resource_start(pdev, 5), 0);
- probe_ent->port[1].scr_addr =
- svia_scr_addr(pci_resource_start(pdev, 5), 1);
+ iomap = pcim_iomap_table(pdev);
+ probe_ent->port[0].scr_addr = svia_scr_addr(iomap[5], 0);
+ probe_ent->port[1].scr_addr = svia_scr_addr(iomap[5], 1);
return probe_ent;
}
@@ -349,7 +442,7 @@ static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
struct ata_probe_ent *probe_ent;
unsigned int i;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent)
return NULL;
@@ -368,7 +461,7 @@ static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
probe_ent->udma_mask = 0x7f;
for (i = 0; i < N_PORTS; i++)
- vt6421_init_addrs(probe_ent, pdev, i);
+ vt6421_init_addrs(probe_ent, pcim_iomap_table(pdev), i);
return probe_ent;
}
@@ -420,20 +513,19 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_probe_ent *probe_ent;
int board_id = (int) ent->driver_data;
const int *bar_sizes;
- int pci_dev_busy = 0;
u8 tmp8;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
- rc = pci_request_regions(pdev, DRV_NAME);
+ rc = pcim_iomap_regions(pdev, 0x1f, DRV_NAME);
if (rc) {
- pci_dev_busy = 1;
- goto err_out;
+ pcim_pin_device(pdev);
+ return rc;
}
if (board_id == vt6420) {
@@ -442,8 +534,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
dev_printk(KERN_ERR, &pdev->dev,
"SATA master/slave not supported (0x%x)\n",
(int) tmp8);
- rc = -EIO;
- goto err_out_regions;
+ return -EIO;
}
bar_sizes = &svia_bar_sizes[0];
@@ -459,16 +550,15 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
i,
(unsigned long long)pci_resource_start(pdev, i),
(unsigned long long)pci_resource_len(pdev, i));
- rc = -ENODEV;
- goto err_out_regions;
+ return -ENODEV;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
if (board_id == vt6420)
probe_ent = vt6420_init_probe_ent(pdev);
@@ -477,26 +567,18 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (!probe_ent) {
dev_printk(KERN_ERR, &pdev->dev, "out of memory\n");
- rc = -ENOMEM;
- goto err_out_regions;
+ return -ENOMEM;
}
svia_configure(pdev);
pci_set_master(pdev);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
static int __init svia_init(void)
@@ -511,4 +593,3 @@ static void __exit svia_exit(void)
module_init(svia_init);
module_exit(svia_exit);
-
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index 0fa1b89f76d5..3d9daf231115 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -50,6 +50,8 @@
#define DRV_VERSION "2.0"
enum {
+ VSC_MMIO_BAR = 0,
+
/* Interrupt register offsets (from chip base address) */
VSC_SATA_INT_STAT_OFFSET = 0x00,
VSC_SATA_INT_MASK_OFFSET = 0x04,
@@ -96,7 +98,6 @@ enum {
VSC_SATA_INT_PHY_CHANGE),
};
-
#define is_vsc_sata_int_err(port_idx, int_status) \
(int_status & (VSC_SATA_INT_ERROR << (8 * port_idx)))
@@ -105,7 +106,7 @@ static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
{
if (sc_reg > SCR_CONTROL)
return 0xffffffffU;
- return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -114,7 +115,7 @@ static void vsc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
{
if (sc_reg > SCR_CONTROL)
return;
- writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4));
+ writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
}
@@ -123,7 +124,7 @@ static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
void __iomem *mask_addr;
u8 mask;
- mask_addr = ap->host->mmio_base +
+ mask_addr = ap->host->iomap[VSC_MMIO_BAR] +
VSC_SATA_INT_MASK_OFFSET + ap->port_no;
mask = readb(mask_addr);
if (ctl & ATA_NIEN)
@@ -150,25 +151,25 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
}
if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
writew(tf->feature | (((u16)tf->hob_feature) << 8),
- (void __iomem *) ioaddr->feature_addr);
+ ioaddr->feature_addr);
writew(tf->nsect | (((u16)tf->hob_nsect) << 8),
- (void __iomem *) ioaddr->nsect_addr);
+ ioaddr->nsect_addr);
writew(tf->lbal | (((u16)tf->hob_lbal) << 8),
- (void __iomem *) ioaddr->lbal_addr);
+ ioaddr->lbal_addr);
writew(tf->lbam | (((u16)tf->hob_lbam) << 8),
- (void __iomem *) ioaddr->lbam_addr);
+ ioaddr->lbam_addr);
writew(tf->lbah | (((u16)tf->hob_lbah) << 8),
- (void __iomem *) ioaddr->lbah_addr);
+ ioaddr->lbah_addr);
} else if (is_addr) {
- writew(tf->feature, (void __iomem *) ioaddr->feature_addr);
- writew(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
- writew(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
- writew(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
- writew(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
+ writew(tf->feature, ioaddr->feature_addr);
+ writew(tf->nsect, ioaddr->nsect_addr);
+ writew(tf->lbal, ioaddr->lbal_addr);
+ writew(tf->lbam, ioaddr->lbam_addr);
+ writew(tf->lbah, ioaddr->lbah_addr);
}
if (tf->flags & ATA_TFLAG_DEVICE)
- writeb(tf->device, (void __iomem *) ioaddr->device_addr);
+ writeb(tf->device, ioaddr->device_addr);
ata_wait_idle(ap);
}
@@ -180,12 +181,12 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
u16 nsect, lbal, lbam, lbah, feature;
tf->command = ata_check_status(ap);
- tf->device = readw((void __iomem *) ioaddr->device_addr);
- feature = readw((void __iomem *) ioaddr->error_addr);
- nsect = readw((void __iomem *) ioaddr->nsect_addr);
- lbal = readw((void __iomem *) ioaddr->lbal_addr);
- lbam = readw((void __iomem *) ioaddr->lbam_addr);
- lbah = readw((void __iomem *) ioaddr->lbah_addr);
+ tf->device = readw(ioaddr->device_addr);
+ feature = readw(ioaddr->error_addr);
+ nsect = readw(ioaddr->nsect_addr);
+ lbal = readw(ioaddr->lbal_addr);
+ lbam = readw(ioaddr->lbam_addr);
+ lbah = readw(ioaddr->lbah_addr);
tf->feature = feature;
tf->nsect = nsect;
@@ -217,7 +218,8 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance)
spin_lock(&host->lock);
- int_status = readl(host->mmio_base + VSC_SATA_INT_STAT_OFFSET);
+ int_status = readl(host->iomap[VSC_MMIO_BAR] +
+ VSC_SATA_INT_STAT_OFFSET);
for (i = 0; i < host->n_ports; i++) {
if (int_status & ((u32) 0xFF << (8 * i))) {
@@ -301,21 +303,22 @@ static const struct ata_port_operations vsc_sata_ops = {
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_mmio_data_xfer,
+ .data_xfer = ata_data_xfer,
.freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.irq_handler = vsc_sata_interrupt,
.irq_clear = ata_bmdma_irq_clear,
+ .irq_on = ata_irq_on,
+ .irq_ack = ata_irq_ack,
.scr_read = vsc_sata_scr_read,
.scr_write = vsc_sata_scr_write,
.port_start = ata_port_start,
- .port_stop = ata_port_stop,
- .host_stop = ata_pci_host_stop,
};
-static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base)
+static void __devinit vsc_sata_setup_port(struct ata_ioports *port,
+ void __iomem *base)
{
port->cmd_addr = base + VSC_SATA_TF_CMD_OFFSET;
port->data_addr = base + VSC_SATA_TF_DATA_OFFSET;
@@ -332,80 +335,70 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned lon
port->ctl_addr = base + VSC_SATA_TF_CTL_OFFSET;
port->bmdma_addr = base + VSC_SATA_DMA_CMD_OFFSET;
port->scr_addr = base + VSC_SATA_SCR_STATUS_OFFSET;
- writel(0, (void __iomem *) base + VSC_SATA_UP_DESCRIPTOR_OFFSET);
- writel(0, (void __iomem *) base + VSC_SATA_UP_DATA_BUFFER_OFFSET);
+ writel(0, base + VSC_SATA_UP_DESCRIPTOR_OFFSET);
+ writel(0, base + VSC_SATA_UP_DATA_BUFFER_OFFSET);
}
static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_probe_ent *probe_ent = NULL;
- unsigned long base;
- int pci_dev_busy = 0;
+ struct ata_probe_ent *probe_ent;
void __iomem *mmio_base;
int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
- rc = pci_enable_device(pdev);
+ rc = pcim_enable_device(pdev);
if (rc)
return rc;
/*
* Check if we have needed resource mapped.
*/
- if (pci_resource_len(pdev, 0) == 0) {
- rc = -ENODEV;
- goto err_out;
- }
+ if (pci_resource_len(pdev, 0) == 0)
+ return -ENODEV;
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc) {
- pci_dev_busy = 1;
- goto err_out;
- }
+ rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME);
+ if (rc == -EBUSY)
+ pcim_pin_device(pdev);
+ if (rc)
+ return rc;
/*
* Use 32 bit DMA mask, because 64 bit address support is poor.
*/
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
if (rc)
- goto err_out_regions;
+ return rc;
- probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
- if (probe_ent == NULL) {
- rc = -ENOMEM;
- goto err_out_regions;
- }
- memset(probe_ent, 0, sizeof(*probe_ent));
+ probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
+ if (probe_ent == NULL)
+ return -ENOMEM;
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
- mmio_base = pci_iomap(pdev, 0, 0);
- if (mmio_base == NULL) {
- rc = -ENOMEM;
- goto err_out_free_ent;
- }
- base = (unsigned long) mmio_base;
-
/*
* Due to a bug in the chip, the default cache line size can't be used
*/
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 0x80);
+ if (pci_enable_msi(pdev) == 0)
+ pci_intx(pdev, 0);
+ else
+ probe_ent->irq_flags = IRQF_SHARED;
+
probe_ent->sht = &vsc_sata_sht;
probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO;
probe_ent->port_ops = &vsc_sata_ops;
probe_ent->n_ports = 4;
probe_ent->irq = pdev->irq;
- probe_ent->irq_flags = IRQF_SHARED;
- probe_ent->mmio_base = mmio_base;
+ probe_ent->iomap = pcim_iomap_table(pdev);
/* We don't care much about the PIO/UDMA masks, but the core won't like us
* if we don't fill these
@@ -414,11 +407,13 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
probe_ent->mwdma_mask = 0x07;
probe_ent->udma_mask = 0x7f;
+ mmio_base = probe_ent->iomap[VSC_MMIO_BAR];
+
/* We have 4 ports per PCI function */
- vsc_sata_setup_port(&probe_ent->port[0], base + 1 * VSC_SATA_PORT_OFFSET);
- vsc_sata_setup_port(&probe_ent->port[1], base + 2 * VSC_SATA_PORT_OFFSET);
- vsc_sata_setup_port(&probe_ent->port[2], base + 3 * VSC_SATA_PORT_OFFSET);
- vsc_sata_setup_port(&probe_ent->port[3], base + 4 * VSC_SATA_PORT_OFFSET);
+ vsc_sata_setup_port(&probe_ent->port[0], mmio_base + 1 * VSC_SATA_PORT_OFFSET);
+ vsc_sata_setup_port(&probe_ent->port[1], mmio_base + 2 * VSC_SATA_PORT_OFFSET);
+ vsc_sata_setup_port(&probe_ent->port[2], mmio_base + 3 * VSC_SATA_PORT_OFFSET);
+ vsc_sata_setup_port(&probe_ent->port[3], mmio_base + 4 * VSC_SATA_PORT_OFFSET);
pci_set_master(pdev);
@@ -430,20 +425,11 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
*/
pci_write_config_dword(pdev, 0x98, 0);
- /* FIXME: check ata_device_add return value */
- ata_device_add(probe_ent);
- kfree(probe_ent);
+ if (!ata_device_add(probe_ent))
+ return -ENODEV;
+ devm_kfree(&pdev->dev, probe_ent);
return 0;
-
-err_out_free_ent:
- kfree(probe_ent);
-err_out_regions:
- pci_release_regions(pdev);
-err_out:
- if (!pci_dev_busy)
- pci_disable_device(pdev);
- return rc;
}
static const struct pci_device_id vsc_sata_pci_tbl[] = {
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 5aab7bd473ac..8fccf018f165 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -912,7 +912,6 @@ static int start_rx(struct atm_dev *dev)
free_page((unsigned long) eni_dev->free_list);
return -ENOMEM;
}
- memset(eni_dev->rx_map,0,PAGE_SIZE);
eni_dev->rx_mult = DEFAULT_RX_MULT;
eni_dev->fast = eni_dev->last_fast = NULL;
eni_dev->slow = eni_dev->last_slow = NULL;
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
new file mode 100644
index 000000000000..0300e7f54cc4
--- /dev/null
+++ b/drivers/auxdisplay/Kconfig
@@ -0,0 +1,109 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+# Auxiliary display drivers configuration.
+#
+
+menu "Auxiliary Display support"
+
+config KS0108
+ tristate "KS0108 LCD Controller"
+ depends on PARPORT_PC
+ default n
+ ---help---
+ If you have a LCD controlled by one or more KS0108
+ controllers, say Y. You will need also another more specific
+ driver for your LCD.
+
+ Depends on Parallel Port support. If you say Y at
+ parport, you will be able to compile this as a module (M)
+ and built-in as well (Y).
+
+ To compile this as a module, choose M here:
+ the module will be called ks0108.
+
+ If unsure, say N.
+
+config KS0108_PORT
+ hex "Parallel port where the LCD is connected"
+ depends on KS0108
+ default 0x378
+ ---help---
+ The address of the parallel port where the LCD is connected.
+
+ The first standard parallel port address is 0x378.
+ The second standard parallel port address is 0x278.
+ The third standard parallel port address is 0x3BC.
+
+ You can specify a different address if you need.
+
+ If you don't know what I'm talking about, load the parport module,
+ and execute "dmesg" or "cat /proc/ioports". You can see there how
+ many parallel ports are present and which address each one has.
+
+ Usually you only need to use 0x378.
+
+ If you compile this as a module, you can still override this
+ using the module parameters.
+
+config KS0108_DELAY
+ int "Delay between each control writing (microseconds)"
+ depends on KS0108
+ default "2"
+ ---help---
+ Amount of time the ks0108 should wait between each control write
+ to the parallel port.
+
+ If your driver seems to miss random writings, increment this.
+
+ If you don't know what I'm talking about, ignore it.
+
+ If you compile this as a module, you can still override this
+ value using the module parameters.
+
+config CFAG12864B
+ tristate "CFAG12864B LCD"
+ depends on X86
+ depends on FB
+ depends on KS0108
+ default n
+ ---help---
+ If you have a Crystalfontz 128x64 2-color LCD, cfag12864b Series,
+ say Y. You also need the ks0108 LCD Controller driver.
+
+ For help about how to wire your LCD to the parallel port,
+ check Documentation/auxdisplay/cfag12864b
+
+ Depends on the x86 arch and the framebuffer support.
+
+ The LCD framebuffer driver can be attached to a console.
+ It will work fine. However, you can't attach it to the fbdev driver
+ of the xorg server.
+
+ To compile this as a module, choose M here:
+ the modules will be called cfag12864b and cfag12864bfb.
+
+ If unsure, say N.
+
+config CFAG12864B_RATE
+ int "Refresh rate (hertz)"
+ depends on CFAG12864B
+ default "20"
+ ---help---
+ Refresh rate of the LCD.
+
+ As the LCD is not memory mapped, the driver has to make the work by
+ software. This means you should be careful setting this value higher.
+ If your CPUs are really slow or you feel the system is slowed down,
+ decrease the value.
+
+ Be careful modifying this value to a very high value:
+ You can freeze the computer, or the LCD maybe can't draw as fast as you
+ are requesting.
+
+ If you don't know what I'm talking about, ignore it.
+
+ If you compile this as a module, you can still override this
+ value using the module parameters.
+endmenu
diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile
new file mode 100644
index 000000000000..8a8936a468b9
--- /dev/null
+++ b/drivers/auxdisplay/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the kernel auxiliary displays device drivers.
+#
+
+obj-$(CONFIG_KS0108) += ks0108.o
+obj-$(CONFIG_CFAG12864B) += cfag12864b.o cfag12864bfb.o
diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c
new file mode 100644
index 000000000000..889583dfc1a6
--- /dev/null
+++ b/drivers/auxdisplay/cfag12864b.c
@@ -0,0 +1,383 @@
+/*
+ * Filename: cfag12864b.c
+ * Version: 0.1.0
+ * Description: cfag12864b LCD driver
+ * License: GPLv2
+ * Depends: ks0108
+ *
+ * Author: Copyright (C) Miguel Ojeda Sandonis <maxextreme@gmail.com>
+ * Date: 2006-10-31
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+#include <linux/ks0108.h>
+#include <linux/cfag12864b.h>
+
+
+#define CFAG12864B_NAME "cfag12864b"
+
+/*
+ * Module Parameters
+ */
+
+static unsigned int cfag12864b_rate = CONFIG_CFAG12864B_RATE;
+module_param(cfag12864b_rate, uint, S_IRUGO);
+MODULE_PARM_DESC(cfag12864b_rate,
+ "Refresh rate (hertzs)");
+
+unsigned int cfag12864b_getrate(void)
+{
+ return cfag12864b_rate;
+}
+
+/*
+ * cfag12864b Commands
+ *
+ * E = Enable signal
+ * Everytime E switch from low to high,
+ * cfag12864b/ks0108 reads the command/data.
+ *
+ * CS1 = First ks0108controller.
+ * If high, the first ks0108 controller receives commands/data.
+ *
+ * CS2 = Second ks0108 controller
+ * If high, the second ks0108 controller receives commands/data.
+ *
+ * DI = Data/Instruction
+ * If low, cfag12864b will expect commands.
+ * If high, cfag12864b will expect data.
+ *
+ */
+
+#define bit(n) (((unsigned char)1)<<(n))
+
+#define CFAG12864B_BIT_E (0)
+#define CFAG12864B_BIT_CS1 (2)
+#define CFAG12864B_BIT_CS2 (1)
+#define CFAG12864B_BIT_DI (3)
+
+static unsigned char cfag12864b_state;
+
+static void cfag12864b_set(void)
+{
+ ks0108_writecontrol(cfag12864b_state);
+}
+
+static void cfag12864b_setbit(unsigned char state, unsigned char n)
+{
+ if (state)
+ cfag12864b_state |= bit(n);
+ else
+ cfag12864b_state &= ~bit(n);
+}
+
+static void cfag12864b_e(unsigned char state)
+{
+ cfag12864b_setbit(state, CFAG12864B_BIT_E);
+ cfag12864b_set();
+}
+
+static void cfag12864b_cs1(unsigned char state)
+{
+ cfag12864b_setbit(state, CFAG12864B_BIT_CS1);
+}
+
+static void cfag12864b_cs2(unsigned char state)
+{
+ cfag12864b_setbit(state, CFAG12864B_BIT_CS2);
+}
+
+static void cfag12864b_di(unsigned char state)
+{
+ cfag12864b_setbit(state, CFAG12864B_BIT_DI);
+}
+
+static void cfag12864b_setcontrollers(unsigned char first,
+ unsigned char second)
+{
+ if (first)
+ cfag12864b_cs1(0);
+ else
+ cfag12864b_cs1(1);
+
+ if (second)
+ cfag12864b_cs2(0);
+ else
+ cfag12864b_cs2(1);
+}
+
+static void cfag12864b_controller(unsigned char which)
+{
+ if (which == 0)
+ cfag12864b_setcontrollers(1, 0);
+ else if (which == 1)
+ cfag12864b_setcontrollers(0, 1);
+}
+
+static void cfag12864b_displaystate(unsigned char state)
+{
+ cfag12864b_di(0);
+ cfag12864b_e(1);
+ ks0108_displaystate(state);
+ cfag12864b_e(0);
+}
+
+static void cfag12864b_address(unsigned char address)
+{
+ cfag12864b_di(0);
+ cfag12864b_e(1);
+ ks0108_address(address);
+ cfag12864b_e(0);
+}
+
+static void cfag12864b_page(unsigned char page)
+{
+ cfag12864b_di(0);
+ cfag12864b_e(1);
+ ks0108_page(page);
+ cfag12864b_e(0);
+}
+
+static void cfag12864b_startline(unsigned char startline)
+{
+ cfag12864b_di(0);
+ cfag12864b_e(1);
+ ks0108_startline(startline);
+ cfag12864b_e(0);
+}
+
+static void cfag12864b_writebyte(unsigned char byte)
+{
+ cfag12864b_di(1);
+ cfag12864b_e(1);
+ ks0108_writedata(byte);
+ cfag12864b_e(0);
+}
+
+static void cfag12864b_nop(void)
+{
+ cfag12864b_startline(0);
+}
+
+/*
+ * cfag12864b Internal Commands
+ */
+
+static void cfag12864b_on(void)
+{
+ cfag12864b_setcontrollers(1, 1);
+ cfag12864b_displaystate(1);
+}
+
+static void cfag12864b_off(void)
+{
+ cfag12864b_setcontrollers(1, 1);
+ cfag12864b_displaystate(0);
+}
+
+static void cfag12864b_clear(void)
+{
+ unsigned char i, j;
+
+ cfag12864b_setcontrollers(1, 1);
+ for (i = 0; i < CFAG12864B_PAGES; i++) {
+ cfag12864b_page(i);
+ cfag12864b_address(0);
+ for (j = 0; j < CFAG12864B_ADDRESSES; j++)
+ cfag12864b_writebyte(0);
+ }
+}
+
+/*
+ * Update work
+ */
+
+unsigned char *cfag12864b_buffer;
+static unsigned char *cfag12864b_cache;
+static DEFINE_MUTEX(cfag12864b_mutex);
+static unsigned char cfag12864b_updating;
+static void cfag12864b_update(struct work_struct *delayed_work);
+static struct workqueue_struct *cfag12864b_workqueue;
+static DECLARE_DELAYED_WORK(cfag12864b_work, cfag12864b_update);
+
+static void cfag12864b_queue(void)
+{
+ queue_delayed_work(cfag12864b_workqueue, &cfag12864b_work,
+ HZ / cfag12864b_rate);
+}
+
+unsigned char cfag12864b_enable(void)
+{
+ unsigned char ret;
+
+ mutex_lock(&cfag12864b_mutex);
+
+ if (!cfag12864b_updating) {
+ cfag12864b_updating = 1;
+ cfag12864b_queue();
+ ret = 0;
+ } else
+ ret = 1;
+
+ mutex_unlock(&cfag12864b_mutex);
+
+ return ret;
+}
+
+void cfag12864b_disable(void)
+{
+ mutex_lock(&cfag12864b_mutex);
+
+ if (cfag12864b_updating) {
+ cfag12864b_updating = 0;
+ cancel_delayed_work(&cfag12864b_work);
+ flush_workqueue(cfag12864b_workqueue);
+ }
+
+ mutex_unlock(&cfag12864b_mutex);
+}
+
+unsigned char cfag12864b_isenabled(void)
+{
+ return cfag12864b_updating;
+}
+
+static void cfag12864b_update(struct work_struct *work)
+{
+ unsigned char c;
+ unsigned short i, j, k, b;
+
+ if (memcmp(cfag12864b_cache, cfag12864b_buffer, CFAG12864B_SIZE)) {
+ for (i = 0; i < CFAG12864B_CONTROLLERS; i++) {
+ cfag12864b_controller(i);
+ cfag12864b_nop();
+ for (j = 0; j < CFAG12864B_PAGES; j++) {
+ cfag12864b_page(j);
+ cfag12864b_nop();
+ cfag12864b_address(0);
+ cfag12864b_nop();
+ for (k = 0; k < CFAG12864B_ADDRESSES; k++) {
+ for (c = 0, b = 0; b < 8; b++)
+ if (cfag12864b_buffer
+ [i * CFAG12864B_ADDRESSES / 8
+ + k / 8 + (j * 8 + b) *
+ CFAG12864B_WIDTH / 8]
+ & bit(k % 8))
+ c |= bit(b);
+ cfag12864b_writebyte(c);
+ }
+ }
+ }
+
+ memcpy(cfag12864b_cache, cfag12864b_buffer, CFAG12864B_SIZE);
+ }
+
+ if (cfag12864b_updating)
+ cfag12864b_queue();
+}
+
+/*
+ * cfag12864b Exported Symbols
+ */
+
+EXPORT_SYMBOL_GPL(cfag12864b_buffer);
+EXPORT_SYMBOL_GPL(cfag12864b_getrate);
+EXPORT_SYMBOL_GPL(cfag12864b_enable);
+EXPORT_SYMBOL_GPL(cfag12864b_disable);
+EXPORT_SYMBOL_GPL(cfag12864b_isenabled);
+
+/*
+ * Module Init & Exit
+ */
+
+static int __init cfag12864b_init(void)
+{
+ int ret = -EINVAL;
+
+ if (PAGE_SIZE < CFAG12864B_SIZE) {
+ printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
+ "page size (%i) < cfag12864b size (%i)\n",
+ (unsigned int)PAGE_SIZE, CFAG12864B_SIZE);
+ ret = -ENOMEM;
+ goto none;
+ }
+
+ cfag12864b_buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
+ if (cfag12864b_buffer == NULL) {
+ printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
+ "can't get a free page\n");
+ ret = -ENOMEM;
+ goto none;
+ }
+
+ cfag12864b_cache = kmalloc(sizeof(unsigned char) *
+ CFAG12864B_SIZE, GFP_KERNEL);
+ if (cfag12864b_buffer == NULL) {
+ printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
+ "can't alloc cache buffer (%i bytes)\n",
+ CFAG12864B_SIZE);
+ ret = -ENOMEM;
+ goto bufferalloced;
+ }
+
+ cfag12864b_workqueue = create_singlethread_workqueue(CFAG12864B_NAME);
+ if (cfag12864b_workqueue == NULL)
+ goto cachealloced;
+
+ memset(cfag12864b_buffer, 0, CFAG12864B_SIZE);
+
+ cfag12864b_clear();
+ cfag12864b_on();
+
+ return 0;
+
+cachealloced:
+ kfree(cfag12864b_cache);
+
+bufferalloced:
+ free_page((unsigned long) cfag12864b_buffer);
+
+none:
+ return ret;
+}
+
+static void __exit cfag12864b_exit(void)
+{
+ cfag12864b_disable();
+ cfag12864b_off();
+ destroy_workqueue(cfag12864b_workqueue);
+ kfree(cfag12864b_cache);
+ free_page((unsigned long) cfag12864b_buffer);
+}
+
+module_init(cfag12864b_init);
+module_exit(cfag12864b_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Miguel Ojeda Sandonis <maxextreme@gmail.com>");
+MODULE_DESCRIPTION("cfag12864b LCD driver");
diff --git a/drivers/auxdisplay/cfag12864bfb.c b/drivers/auxdisplay/cfag12864bfb.c
new file mode 100644
index 000000000000..94765e78315f
--- /dev/null
+++ b/drivers/auxdisplay/cfag12864bfb.c
@@ -0,0 +1,180 @@
+/*
+ * Filename: cfag12864bfb.c
+ * Version: 0.1.0
+ * Description: cfag12864b LCD framebuffer driver
+ * License: GPLv2
+ * Depends: cfag12864b
+ *
+ * Author: Copyright (C) Miguel Ojeda Sandonis <maxextreme@gmail.com>
+ * Date: 2006-10-31
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/cfag12864b.h>
+
+#define CFAG12864BFB_NAME "cfag12864bfb"
+
+static struct fb_fix_screeninfo cfag12864bfb_fix __initdata = {
+ .id = "cfag12864b",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_MONO10,
+ .xpanstep = 0,
+ .ypanstep = 0,
+ .ywrapstep = 0,
+ .line_length = CFAG12864B_WIDTH / 8,
+ .accel = FB_ACCEL_NONE,
+};
+
+static struct fb_var_screeninfo cfag12864bfb_var __initdata = {
+ .xres = CFAG12864B_WIDTH,
+ .yres = CFAG12864B_HEIGHT,
+ .xres_virtual = CFAG12864B_WIDTH,
+ .yres_virtual = CFAG12864B_HEIGHT,
+ .bits_per_pixel = 1,
+ .red = { 0, 1, 0 },
+ .green = { 0, 1, 0 },
+ .blue = { 0, 1, 0 },
+ .left_margin = 0,
+ .right_margin = 0,
+ .upper_margin = 0,
+ .lower_margin = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+};
+
+static int cfag12864bfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ return vm_insert_page(vma, vma->vm_start,
+ virt_to_page(cfag12864b_buffer));
+}
+
+static struct fb_ops cfag12864bfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_mmap = cfag12864bfb_mmap,
+};
+
+static int __init cfag12864bfb_probe(struct platform_device *device)
+{
+ int ret = -EINVAL;
+ struct fb_info *info = framebuffer_alloc(0, &device->dev);
+
+ if (!info)
+ goto none;
+
+ info->screen_base = (char __iomem *) cfag12864b_buffer;
+ info->screen_size = CFAG12864B_SIZE;
+ info->fbops = &cfag12864bfb_ops;
+ info->fix = cfag12864bfb_fix;
+ info->var = cfag12864bfb_var;
+ info->pseudo_palette = NULL;
+ info->par = NULL;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ if (register_framebuffer(info) < 0)
+ goto fballoced;
+
+ platform_set_drvdata(device, info);
+
+ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
+ info->fix.id);
+
+ return 0;
+
+fballoced:
+ framebuffer_release(info);
+
+none:
+ return ret;
+}
+
+static int cfag12864bfb_remove(struct platform_device *device)
+{
+ struct fb_info *info = platform_get_drvdata(device);
+
+ if (info) {
+ unregister_framebuffer(info);
+ framebuffer_release(info);
+ }
+
+ return 0;
+}
+
+static struct platform_driver cfag12864bfb_driver = {
+ .probe = cfag12864bfb_probe,
+ .remove = cfag12864bfb_remove,
+ .driver = {
+ .name = CFAG12864BFB_NAME,
+ },
+};
+
+static struct platform_device *cfag12864bfb_device;
+
+static int __init cfag12864bfb_init(void)
+{
+ int ret;
+
+ if (cfag12864b_enable()) {
+ printk(KERN_ERR CFAG12864BFB_NAME ": ERROR: "
+ "can't enable cfag12864b refreshing (being used)\n");
+ return -ENODEV;
+ }
+
+ ret = platform_driver_register(&cfag12864bfb_driver);
+
+ if (!ret) {
+ cfag12864bfb_device =
+ platform_device_alloc(CFAG12864BFB_NAME, 0);
+
+ if (cfag12864bfb_device)
+ ret = platform_device_add(cfag12864bfb_device);
+ else
+ ret = -ENOMEM;
+
+ if (ret) {
+ platform_device_put(cfag12864bfb_device);
+ platform_driver_unregister(&cfag12864bfb_driver);
+ }
+ }
+
+ return ret;
+}
+
+static void __exit cfag12864bfb_exit(void)
+{
+ platform_device_unregister(cfag12864bfb_device);
+ platform_driver_unregister(&cfag12864bfb_driver);
+ cfag12864b_disable();
+}
+
+module_init(cfag12864bfb_init);
+module_exit(cfag12864bfb_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Miguel Ojeda Sandonis <maxextreme@gmail.com>");
+MODULE_DESCRIPTION("cfag12864b LCD framebuffer driver");
diff --git a/drivers/auxdisplay/ks0108.c b/drivers/auxdisplay/ks0108.c
new file mode 100644
index 000000000000..a637575b9106
--- /dev/null
+++ b/drivers/auxdisplay/ks0108.c
@@ -0,0 +1,166 @@
+/*
+ * Filename: ks0108.c
+ * Version: 0.1.0
+ * Description: ks0108 LCD Controller driver
+ * License: GPLv2
+ * Depends: parport
+ *
+ * Author: Copyright (C) Miguel Ojeda Sandonis <maxextreme@gmail.com>
+ * Date: 2006-10-31
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/parport.h>
+#include <linux/uaccess.h>
+#include <linux/ks0108.h>
+
+#define KS0108_NAME "ks0108"
+
+/*
+ * Module Parameters
+ */
+
+static unsigned int ks0108_port = CONFIG_KS0108_PORT;
+module_param(ks0108_port, uint, S_IRUGO);
+MODULE_PARM_DESC(ks0108_port, "Parallel port where the LCD is connected");
+
+static unsigned int ks0108_delay = CONFIG_KS0108_DELAY;
+module_param(ks0108_delay, uint, S_IRUGO);
+MODULE_PARM_DESC(ks0108_delay, "Delay between each control writing (microseconds)");
+
+/*
+ * Device
+ */
+
+static struct parport *ks0108_parport;
+static struct pardevice *ks0108_pardevice;
+
+/*
+ * ks0108 Exported Commands (don't lock)
+ *
+ * You _should_ lock in the top driver: This functions _should not_
+ * get race conditions in any way. Locking for each byte here would be
+ * so slow and useless.
+ *
+ * There are not bit definitions because they are not flags,
+ * just arbitrary combinations defined by the documentation for each
+ * function in the ks0108 LCD controller. If you want to know what means
+ * a specific combination, look at the function's name.
+ *
+ * The ks0108_writecontrol bits need to be reverted ^(0,1,3) because
+ * the parallel port also revert them using a "not" logic gate.
+ */
+
+#define bit(n) (((unsigned char)1)<<(n))
+
+void ks0108_writedata(unsigned char byte)
+{
+ parport_write_data(ks0108_parport, byte);
+}
+
+void ks0108_writecontrol(unsigned char byte)
+{
+ udelay(ks0108_delay);
+ parport_write_control(ks0108_parport, byte ^ (bit(0) | bit(1) | bit(3)));
+}
+
+void ks0108_displaystate(unsigned char state)
+{
+ ks0108_writedata((state ? bit(0) : 0) | bit(1) | bit(2) | bit(3) | bit(4) | bit(5));
+}
+
+void ks0108_startline(unsigned char startline)
+{
+ ks0108_writedata(min(startline,(unsigned char)63) | bit(6) | bit(7));
+}
+
+void ks0108_address(unsigned char address)
+{
+ ks0108_writedata(min(address,(unsigned char)63) | bit(6));
+}
+
+void ks0108_page(unsigned char page)
+{
+ ks0108_writedata(min(page,(unsigned char)7) | bit(3) | bit(4) | bit(5) | bit(7));
+}
+
+EXPORT_SYMBOL_GPL(ks0108_writedata);
+EXPORT_SYMBOL_GPL(ks0108_writecontrol);
+EXPORT_SYMBOL_GPL(ks0108_displaystate);
+EXPORT_SYMBOL_GPL(ks0108_startline);
+EXPORT_SYMBOL_GPL(ks0108_address);
+EXPORT_SYMBOL_GPL(ks0108_page);
+
+/*
+ * Module Init & Exit
+ */
+
+static int __init ks0108_init(void)
+{
+ int result;
+ int ret = -EINVAL;
+
+ ks0108_parport = parport_find_base(ks0108_port);
+ if (ks0108_parport == NULL) {
+ printk(KERN_ERR KS0108_NAME ": ERROR: "
+ "parport didn't find %i port\n", ks0108_port);
+ goto none;
+ }
+
+ ks0108_pardevice = parport_register_device(ks0108_parport, KS0108_NAME,
+ NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+ if (ks0108_pardevice == NULL) {
+ printk(KERN_ERR KS0108_NAME ": ERROR: "
+ "parport didn't register new device\n");
+ goto none;
+ }
+
+ result = parport_claim(ks0108_pardevice);
+ if (result != 0) {
+ printk(KERN_ERR KS0108_NAME ": ERROR: "
+ "can't claim %i parport, maybe in use\n", ks0108_port);
+ ret = result;
+ goto registered;
+ }
+
+ return 0;
+
+registered:
+ parport_unregister_device(ks0108_pardevice);
+
+none:
+ return ret;
+}
+
+static void __exit ks0108_exit(void)
+{
+ parport_release(ks0108_pardevice);
+ parport_unregister_device(ks0108_pardevice);
+}
+
+module_init(ks0108_init);
+module_exit(ks0108_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Miguel Ojeda Sandonis <maxextreme@gmail.com>");
+MODULE_DESCRIPTION("ks0108 LCD Controller driver");
+
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 1429f3a2629e..5d6312e33490 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -37,6 +37,18 @@ config DEBUG_DRIVER
If you are unsure about this, say N here.
+config DEBUG_DEVRES
+ bool "Managed device resources verbose debug messages"
+ depends on DEBUG_KERNEL
+ help
+ This option enables kernel parameter devres.log. If set to
+ non-zero, devres debug messages are printed. Select this if
+ you are having a problem with devres or want to debug
+ resource management for a managed device. devres.log can be
+ switched on and off from sysfs node.
+
+ If you are unsure about this, Say N here.
+
config SYS_HYPERVISOR
bool
default n
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 7bbb9eeda235..e9eb7382ac3a 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -3,6 +3,7 @@
obj-y := core.o sys.o bus.o dd.o \
driver.o class.o platform.o \
cpu.o firmware.o init.o map.o dmapool.o \
+ dma-mapping.o devres.o \
attribute_container.o transport_class.o
obj-y += power/
obj-$(CONFIG_ISA) += isa.o
diff --git a/drivers/base/base.h b/drivers/base/base.h
index d26644a59537..de7e1442ce60 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -44,3 +44,4 @@ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr)
extern char *make_class_name(const char *name, struct kobject *kobj);
+extern void devres_release_all(struct device *dev);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index e13614241c9e..a8ac34ba6107 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -428,6 +428,8 @@ void device_initialize(struct device *dev)
INIT_LIST_HEAD(&dev->dma_pools);
INIT_LIST_HEAD(&dev->node);
init_MUTEX(&dev->sem);
+ spin_lock_init(&dev->devres_lock);
+ INIT_LIST_HEAD(&dev->devres_head);
device_init_wakeup(dev, 0);
set_dev_node(dev, -1);
}
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index b5bf243d9cd6..6a48824e43ff 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -112,6 +112,7 @@ static int really_probe(void *void_data)
atomic_inc(&probe_count);
pr_debug("%s: Probing driver %s with device %s\n",
drv->bus->name, drv->name, dev->bus_id);
+ WARN_ON(!list_empty(&dev->devres_head));
dev->driver = drv;
if (driver_sysfs_add(dev)) {
@@ -137,6 +138,7 @@ static int really_probe(void *void_data)
goto done;
probe_failed:
+ devres_release_all(dev);
driver_sysfs_remove(dev);
dev->driver = NULL;
@@ -327,6 +329,7 @@ static void __device_release_driver(struct device * dev)
dev->bus->remove(dev);
else if (drv->remove)
drv->remove(dev);
+ devres_release_all(dev);
dev->driver = NULL;
put_driver(drv);
}
diff --git a/drivers/base/devres.c b/drivers/base/devres.c
new file mode 100644
index 000000000000..e177c9533b6c
--- /dev/null
+++ b/drivers/base/devres.c
@@ -0,0 +1,644 @@
+/*
+ * drivers/base/devres.c - device resource management
+ *
+ * Copyright (c) 2006 SUSE Linux Products GmbH
+ * Copyright (c) 2006 Tejun Heo <teheo@suse.de>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+
+struct devres_node {
+ struct list_head entry;
+ dr_release_t release;
+#ifdef CONFIG_DEBUG_DEVRES
+ const char *name;
+ size_t size;
+#endif
+};
+
+struct devres {
+ struct devres_node node;
+ /* -- 3 pointers */
+ unsigned long long data[]; /* guarantee ull alignment */
+};
+
+struct devres_group {
+ struct devres_node node[2];
+ void *id;
+ int color;
+ /* -- 8 pointers */
+};
+
+#ifdef CONFIG_DEBUG_DEVRES
+static int log_devres = 0;
+module_param_named(log, log_devres, int, S_IRUGO | S_IWUSR);
+
+static void set_node_dbginfo(struct devres_node *node, const char *name,
+ size_t size)
+{
+ node->name = name;
+ node->size = size;
+}
+
+static void devres_log(struct device *dev, struct devres_node *node,
+ const char *op)
+{
+ if (unlikely(log_devres))
+ dev_printk(KERN_ERR, dev, "DEVRES %3s %p %s (%lu bytes)\n",
+ op, node, node->name, (unsigned long)node->size);
+}
+#else /* CONFIG_DEBUG_DEVRES */
+#define set_node_dbginfo(node, n, s) do {} while (0)
+#define devres_log(dev, node, op) do {} while (0)
+#endif /* CONFIG_DEBUG_DEVRES */
+
+/*
+ * Release functions for devres group. These callbacks are used only
+ * for identification.
+ */
+static void group_open_release(struct device *dev, void *res)
+{
+ /* noop */
+}
+
+static void group_close_release(struct device *dev, void *res)
+{
+ /* noop */
+}
+
+static struct devres_group * node_to_group(struct devres_node *node)
+{
+ if (node->release == &group_open_release)
+ return container_of(node, struct devres_group, node[0]);
+ if (node->release == &group_close_release)
+ return container_of(node, struct devres_group, node[1]);
+ return NULL;
+}
+
+static __always_inline struct devres * alloc_dr(dr_release_t release,
+ size_t size, gfp_t gfp)
+{
+ size_t tot_size = sizeof(struct devres) + size;
+ struct devres *dr;
+
+ dr = kmalloc_track_caller(tot_size, gfp);
+ if (unlikely(!dr))
+ return NULL;
+
+ memset(dr, 0, tot_size);
+ INIT_LIST_HEAD(&dr->node.entry);
+ dr->node.release = release;
+ return dr;
+}
+
+static void add_dr(struct device *dev, struct devres_node *node)
+{
+ devres_log(dev, node, "ADD");
+ BUG_ON(!list_empty(&node->entry));
+ list_add_tail(&node->entry, &dev->devres_head);
+}
+
+/**
+ * devres_alloc - Allocate device resource data
+ * @release: Release function devres will be associated with
+ * @size: Allocation size
+ * @gfp: Allocation flags
+ *
+ * allocate devres of @size bytes. The allocated area is zeroed, then
+ * associated with @release. The returned pointer can be passed to
+ * other devres_*() functions.
+ *
+ * RETURNS:
+ * Pointer to allocated devres on success, NULL on failure.
+ */
+#ifdef CONFIG_DEBUG_DEVRES
+void * __devres_alloc(dr_release_t release, size_t size, gfp_t gfp,
+ const char *name)
+{
+ struct devres *dr;
+
+ dr = alloc_dr(release, size, gfp);
+ if (unlikely(!dr))
+ return NULL;
+ set_node_dbginfo(&dr->node, name, size);
+ return dr->data;
+}
+EXPORT_SYMBOL_GPL(__devres_alloc);
+#else
+void * devres_alloc(dr_release_t release, size_t size, gfp_t gfp)
+{
+ struct devres *dr;
+
+ dr = alloc_dr(release, size, gfp);
+ if (unlikely(!dr))
+ return NULL;
+ return dr->data;
+}
+EXPORT_SYMBOL_GPL(devres_alloc);
+#endif
+
+/**
+ * devres_free - Free device resource data
+ * @res: Pointer to devres data to free
+ *
+ * Free devres created with devres_alloc().
+ */
+void devres_free(void *res)
+{
+ if (res) {
+ struct devres *dr = container_of(res, struct devres, data);
+
+ BUG_ON(!list_empty(&dr->node.entry));
+ kfree(dr);
+ }
+}
+EXPORT_SYMBOL_GPL(devres_free);
+
+/**
+ * devres_add - Register device resource
+ * @dev: Device to add resource to
+ * @res: Resource to register
+ *
+ * Register devres @res to @dev. @res should have been allocated
+ * using devres_alloc(). On driver detach, the associated release
+ * function will be invoked and devres will be freed automatically.
+ */
+void devres_add(struct device *dev, void *res)
+{
+ struct devres *dr = container_of(res, struct devres, data);
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->devres_lock, flags);
+ add_dr(dev, &dr->node);
+ spin_unlock_irqrestore(&dev->devres_lock, flags);
+}
+EXPORT_SYMBOL_GPL(devres_add);
+
+static struct devres *find_dr(struct device *dev, dr_release_t release,
+ dr_match_t match, void *match_data)
+{
+ struct devres_node *node;
+
+ list_for_each_entry_reverse(node, &dev->devres_head, entry) {
+ struct devres *dr = container_of(node, struct devres, node);
+
+ if (node->release != release)
+ continue;
+ if (match && !match(dev, dr->data, match_data))
+ continue;
+ return dr;
+ }
+
+ return NULL;
+}
+
+/**
+ * devres_find - Find device resource
+ * @dev: Device to lookup resource from
+ * @release: Look for resources associated with this release function
+ * @match: Match function (optional)
+ * @match_data: Data for the match function
+ *
+ * Find the latest devres of @dev which is associated with @release
+ * and for which @match returns 1. If @match is NULL, it's considered
+ * to match all.
+ *
+ * RETURNS:
+ * Pointer to found devres, NULL if not found.
+ */
+void * devres_find(struct device *dev, dr_release_t release,
+ dr_match_t match, void *match_data)
+{
+ struct devres *dr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->devres_lock, flags);
+ dr = find_dr(dev, release, match, match_data);
+ spin_unlock_irqrestore(&dev->devres_lock, flags);
+
+ if (dr)
+ return dr->data;
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(devres_find);
+
+/**
+ * devres_get - Find devres, if non-existent, add one atomically
+ * @dev: Device to lookup or add devres for
+ * @new_res: Pointer to new initialized devres to add if not found
+ * @match: Match function (optional)
+ * @match_data: Data for the match function
+ *
+ * Find the latest devres of @dev which has the same release function
+ * as @new_res and for which @match return 1. If found, @new_res is
+ * freed; otherwise, @new_res is added atomically.
+ *
+ * RETURNS:
+ * Pointer to found or added devres.
+ */
+void * devres_get(struct device *dev, void *new_res,
+ dr_match_t match, void *match_data)
+{
+ struct devres *new_dr = container_of(new_res, struct devres, data);
+ struct devres *dr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->devres_lock, flags);
+ dr = find_dr(dev, new_dr->node.release, match, match_data);
+ if (!dr) {
+ add_dr(dev, &new_dr->node);
+ dr = new_dr;
+ new_dr = NULL;
+ }
+ spin_unlock_irqrestore(&dev->devres_lock, flags);
+ devres_free(new_dr);
+
+ return dr->data;
+}
+EXPORT_SYMBOL_GPL(devres_get);
+
+/**
+ * devres_remove - Find a device resource and remove it
+ * @dev: Device to find resource from
+ * @release: Look for resources associated with this release function
+ * @match: Match function (optional)
+ * @match_data: Data for the match function
+ *
+ * Find the latest devres of @dev associated with @release and for
+ * which @match returns 1. If @match is NULL, it's considered to
+ * match all. If found, the resource is removed atomically and
+ * returned.
+ *
+ * RETURNS:
+ * Pointer to removed devres on success, NULL if not found.
+ */
+void * devres_remove(struct device *dev, dr_release_t release,
+ dr_match_t match, void *match_data)
+{
+ struct devres *dr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->devres_lock, flags);
+ dr = find_dr(dev, release, match, match_data);
+ if (dr) {
+ list_del_init(&dr->node.entry);
+ devres_log(dev, &dr->node, "REM");
+ }
+ spin_unlock_irqrestore(&dev->devres_lock, flags);
+
+ if (dr)
+ return dr->data;
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(devres_remove);
+
+/**
+ * devres_destroy - Find a device resource and destroy it
+ * @dev: Device to find resource from
+ * @release: Look for resources associated with this release function
+ * @match: Match function (optional)
+ * @match_data: Data for the match function
+ *
+ * Find the latest devres of @dev associated with @release and for
+ * which @match returns 1. If @match is NULL, it's considered to
+ * match all. If found, the resource is removed atomically and freed.
+ *
+ * RETURNS:
+ * 0 if devres is found and freed, -ENOENT if not found.
+ */
+int devres_destroy(struct device *dev, dr_release_t release,
+ dr_match_t match, void *match_data)
+{
+ void *res;
+
+ res = devres_remove(dev, release, match, match_data);
+ if (unlikely(!res))
+ return -ENOENT;
+
+ devres_free(res);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(devres_destroy);
+
+static int remove_nodes(struct device *dev,
+ struct list_head *first, struct list_head *end,
+ struct list_head *todo)
+{
+ int cnt = 0, nr_groups = 0;
+ struct list_head *cur;
+
+ /* First pass - move normal devres entries to @todo and clear
+ * devres_group colors.
+ */
+ cur = first;
+ while (cur != end) {
+ struct devres_node *node;
+ struct devres_group *grp;
+
+ node = list_entry(cur, struct devres_node, entry);
+ cur = cur->next;
+
+ grp = node_to_group(node);
+ if (grp) {
+ /* clear color of group markers in the first pass */
+ grp->color = 0;
+ nr_groups++;
+ } else {
+ /* regular devres entry */
+ if (&node->entry == first)
+ first = first->next;
+ list_move_tail(&node->entry, todo);
+ cnt++;
+ }
+ }
+
+ if (!nr_groups)
+ return cnt;
+
+ /* Second pass - Scan groups and color them. A group gets
+ * color value of two iff the group is wholly contained in
+ * [cur, end). That is, for a closed group, both opening and
+ * closing markers should be in the range, while just the
+ * opening marker is enough for an open group.
+ */
+ cur = first;
+ while (cur != end) {
+ struct devres_node *node;
+ struct devres_group *grp;
+
+ node = list_entry(cur, struct devres_node, entry);
+ cur = cur->next;
+
+ grp = node_to_group(node);
+ BUG_ON(!grp || list_empty(&grp->node[0].entry));
+
+ grp->color++;
+ if (list_empty(&grp->node[1].entry))
+ grp->color++;
+
+ BUG_ON(grp->color <= 0 || grp->color > 2);
+ if (grp->color == 2) {
+ /* No need to update cur or end. The removed
+ * nodes are always before both.
+ */
+ list_move_tail(&grp->node[0].entry, todo);
+ list_del_init(&grp->node[1].entry);
+ }
+ }
+
+ return cnt;
+}
+
+static int release_nodes(struct device *dev, struct list_head *first,
+ struct list_head *end, unsigned long flags)
+{
+ LIST_HEAD(todo);
+ int cnt;
+ struct devres *dr, *tmp;
+
+ cnt = remove_nodes(dev, first, end, &todo);
+
+ spin_unlock_irqrestore(&dev->devres_lock, flags);
+
+ /* Release. Note that both devres and devres_group are
+ * handled as devres in the following loop. This is safe.
+ */
+ list_for_each_entry_safe_reverse(dr, tmp, &todo, node.entry) {
+ devres_log(dev, &dr->node, "REL");
+ dr->node.release(dev, dr->data);
+ kfree(dr);
+ }
+
+ return cnt;
+}
+
+/**
+ * devres_release_all - Release all resources
+ * @dev: Device to release resources for
+ *
+ * Release all resources associated with @dev. This function is
+ * called on driver detach.
+ */
+int devres_release_all(struct device *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->devres_lock, flags);
+ return release_nodes(dev, dev->devres_head.next, &dev->devres_head,
+ flags);
+}
+
+/**
+ * devres_open_group - Open a new devres group
+ * @dev: Device to open devres group for
+ * @id: Separator ID
+ * @gfp: Allocation flags
+ *
+ * Open a new devres group for @dev with @id. For @id, using a
+ * pointer to an object which won't be used for another group is
+ * recommended. If @id is NULL, address-wise unique ID is created.
+ *
+ * RETURNS:
+ * ID of the new group, NULL on failure.
+ */
+void * devres_open_group(struct device *dev, void *id, gfp_t gfp)
+{
+ struct devres_group *grp;
+ unsigned long flags;
+
+ grp = kmalloc(sizeof(*grp), gfp);
+ if (unlikely(!grp))
+ return NULL;
+
+ grp->node[0].release = &group_open_release;
+ grp->node[1].release = &group_close_release;
+ INIT_LIST_HEAD(&grp->node[0].entry);
+ INIT_LIST_HEAD(&grp->node[1].entry);
+ set_node_dbginfo(&grp->node[0], "grp<", 0);
+ set_node_dbginfo(&grp->node[1], "grp>", 0);
+ grp->id = grp;
+ if (id)
+ grp->id = id;
+
+ spin_lock_irqsave(&dev->devres_lock, flags);
+ add_dr(dev, &grp->node[0]);
+ spin_unlock_irqrestore(&dev->devres_lock, flags);
+ return grp->id;
+}
+EXPORT_SYMBOL_GPL(devres_open_group);
+
+/* Find devres group with ID @id. If @id is NULL, look for the latest. */
+static struct devres_group * find_group(struct device *dev, void *id)
+{
+ struct devres_node *node;
+
+ list_for_each_entry_reverse(node, &dev->devres_head, entry) {
+ struct devres_group *grp;
+
+ if (node->release != &group_open_release)
+ continue;
+
+ grp = container_of(node, struct devres_group, node[0]);
+
+ if (id) {
+ if (grp->id == id)
+ return grp;
+ } else if (list_empty(&grp->node[1].entry))
+ return grp;
+ }
+
+ return NULL;
+}
+
+/**
+ * devres_close_group - Close a devres group
+ * @dev: Device to close devres group for
+ * @id: ID of target group, can be NULL
+ *
+ * Close the group identified by @id. If @id is NULL, the latest open
+ * group is selected.
+ */
+void devres_close_group(struct device *dev, void *id)
+{
+ struct devres_group *grp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->devres_lock, flags);
+
+ grp = find_group(dev, id);
+ if (grp)
+ add_dr(dev, &grp->node[1]);
+ else
+ WARN_ON(1);
+
+ spin_unlock_irqrestore(&dev->devres_lock, flags);
+}
+EXPORT_SYMBOL_GPL(devres_close_group);
+
+/**
+ * devres_remove_group - Remove a devres group
+ * @dev: Device to remove group for
+ * @id: ID of target group, can be NULL
+ *
+ * Remove the group identified by @id. If @id is NULL, the latest
+ * open group is selected. Note that removing a group doesn't affect
+ * any other resources.
+ */
+void devres_remove_group(struct device *dev, void *id)
+{
+ struct devres_group *grp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->devres_lock, flags);
+
+ grp = find_group(dev, id);
+ if (grp) {
+ list_del_init(&grp->node[0].entry);
+ list_del_init(&grp->node[1].entry);
+ devres_log(dev, &grp->node[0], "REM");
+ } else
+ WARN_ON(1);
+
+ spin_unlock_irqrestore(&dev->devres_lock, flags);
+
+ kfree(grp);
+}
+EXPORT_SYMBOL_GPL(devres_remove_group);
+
+/**
+ * devres_release_group - Release resources in a devres group
+ * @dev: Device to release group for
+ * @id: ID of target group, can be NULL
+ *
+ * Release all resources in the group identified by @id. If @id is
+ * NULL, the latest open group is selected. The selected group and
+ * groups properly nested inside the selected group are removed.
+ *
+ * RETURNS:
+ * The number of released non-group resources.
+ */
+int devres_release_group(struct device *dev, void *id)
+{
+ struct devres_group *grp;
+ unsigned long flags;
+ int cnt = 0;
+
+ spin_lock_irqsave(&dev->devres_lock, flags);
+
+ grp = find_group(dev, id);
+ if (grp) {
+ struct list_head *first = &grp->node[0].entry;
+ struct list_head *end = &dev->devres_head;
+
+ if (!list_empty(&grp->node[1].entry))
+ end = grp->node[1].entry.next;
+
+ cnt = release_nodes(dev, first, end, flags);
+ } else {
+ WARN_ON(1);
+ spin_unlock_irqrestore(&dev->devres_lock, flags);
+ }
+
+ return cnt;
+}
+EXPORT_SYMBOL_GPL(devres_release_group);
+
+/*
+ * Managed kzalloc/kfree
+ */
+static void devm_kzalloc_release(struct device *dev, void *res)
+{
+ /* noop */
+}
+
+static int devm_kzalloc_match(struct device *dev, void *res, void *data)
+{
+ return res == data;
+}
+
+/**
+ * devm_kzalloc - Managed kzalloc
+ * @dev: Device to allocate memory for
+ * @size: Allocation size
+ * @gfp: Allocation gfp flags
+ *
+ * Managed kzalloc. Memory allocated with this function is
+ * automatically freed on driver detach. Like all other devres
+ * resources, guaranteed alignment is unsigned long long.
+ *
+ * RETURNS:
+ * Pointer to allocated memory on success, NULL on failure.
+ */
+void * devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
+{
+ struct devres *dr;
+
+ /* use raw alloc_dr for kmalloc caller tracing */
+ dr = alloc_dr(devm_kzalloc_release, size, gfp);
+ if (unlikely(!dr))
+ return NULL;
+
+ set_node_dbginfo(&dr->node, "devm_kzalloc_release", size);
+ devres_add(dev, dr->data);
+ return dr->data;
+}
+EXPORT_SYMBOL_GPL(devm_kzalloc);
+
+/**
+ * devm_kfree - Managed kfree
+ * @dev: Device this memory belongs to
+ * @p: Memory to free
+ *
+ * Free memory allocated with dev_kzalloc().
+ */
+void devm_kfree(struct device *dev, void *p)
+{
+ int rc;
+
+ rc = devres_destroy(dev, devm_kzalloc_release, devm_kzalloc_match, p);
+ WARN_ON(rc);
+}
+EXPORT_SYMBOL_GPL(devm_kfree);
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
new file mode 100644
index 000000000000..ca9186f70a69
--- /dev/null
+++ b/drivers/base/dma-mapping.c
@@ -0,0 +1,218 @@
+/*
+ * drivers/base/dma-mapping.c - arch-independent dma-mapping routines
+ *
+ * Copyright (c) 2006 SUSE Linux Products GmbH
+ * Copyright (c) 2006 Tejun Heo <teheo@suse.de>
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/dma-mapping.h>
+
+/*
+ * Managed DMA API
+ */
+struct dma_devres {
+ size_t size;
+ void *vaddr;
+ dma_addr_t dma_handle;
+};
+
+static void dmam_coherent_release(struct device *dev, void *res)
+{
+ struct dma_devres *this = res;
+
+ dma_free_coherent(dev, this->size, this->vaddr, this->dma_handle);
+}
+
+static void dmam_noncoherent_release(struct device *dev, void *res)
+{
+ struct dma_devres *this = res;
+
+ dma_free_noncoherent(dev, this->size, this->vaddr, this->dma_handle);
+}
+
+static int dmam_match(struct device *dev, void *res, void *match_data)
+{
+ struct dma_devres *this = res, *match = match_data;
+
+ if (this->vaddr == match->vaddr) {
+ WARN_ON(this->size != match->size ||
+ this->dma_handle != match->dma_handle);
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * dmam_alloc_coherent - Managed dma_alloc_coherent()
+ * @dev: Device to allocate coherent memory for
+ * @size: Size of allocation
+ * @dma_handle: Out argument for allocated DMA handle
+ * @gfp: Allocation flags
+ *
+ * Managed dma_alloc_coherent(). Memory allocated using this function
+ * will be automatically released on driver detach.
+ *
+ * RETURNS:
+ * Pointer to allocated memory on success, NULL on failure.
+ */
+void * dmam_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ struct dma_devres *dr;
+ void *vaddr;
+
+ dr = devres_alloc(dmam_coherent_release, sizeof(*dr), gfp);
+ if (!dr)
+ return NULL;
+
+ vaddr = dma_alloc_coherent(dev, size, dma_handle, gfp);
+ if (!vaddr) {
+ devres_free(dr);
+ return NULL;
+ }
+
+ dr->vaddr = vaddr;
+ dr->dma_handle = *dma_handle;
+ dr->size = size;
+
+ devres_add(dev, dr);
+
+ return vaddr;
+}
+EXPORT_SYMBOL(dmam_alloc_coherent);
+
+/**
+ * dmam_free_coherent - Managed dma_free_coherent()
+ * @dev: Device to free coherent memory for
+ * @size: Size of allocation
+ * @vaddr: Virtual address of the memory to free
+ * @dma_handle: DMA handle of the memory to free
+ *
+ * Managed dma_free_coherent().
+ */
+void dmam_free_coherent(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
+{
+ struct dma_devres match_data = { size, vaddr, dma_handle };
+
+ dma_free_coherent(dev, size, vaddr, dma_handle);
+ WARN_ON(devres_destroy(dev, dmam_coherent_release, dmam_match,
+ &match_data));
+}
+EXPORT_SYMBOL(dmam_free_coherent);
+
+/**
+ * dmam_alloc_non_coherent - Managed dma_alloc_non_coherent()
+ * @dev: Device to allocate non_coherent memory for
+ * @size: Size of allocation
+ * @dma_handle: Out argument for allocated DMA handle
+ * @gfp: Allocation flags
+ *
+ * Managed dma_alloc_non_coherent(). Memory allocated using this
+ * function will be automatically released on driver detach.
+ *
+ * RETURNS:
+ * Pointer to allocated memory on success, NULL on failure.
+ */
+void *dmam_alloc_noncoherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ struct dma_devres *dr;
+ void *vaddr;
+
+ dr = devres_alloc(dmam_noncoherent_release, sizeof(*dr), gfp);
+ if (!dr)
+ return NULL;
+
+ vaddr = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
+ if (!vaddr) {
+ devres_free(dr);
+ return NULL;
+ }
+
+ dr->vaddr = vaddr;
+ dr->dma_handle = *dma_handle;
+ dr->size = size;
+
+ devres_add(dev, dr);
+
+ return vaddr;
+}
+EXPORT_SYMBOL(dmam_alloc_noncoherent);
+
+/**
+ * dmam_free_coherent - Managed dma_free_noncoherent()
+ * @dev: Device to free noncoherent memory for
+ * @size: Size of allocation
+ * @vaddr: Virtual address of the memory to free
+ * @dma_handle: DMA handle of the memory to free
+ *
+ * Managed dma_free_noncoherent().
+ */
+void dmam_free_noncoherent(struct device *dev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
+{
+ struct dma_devres match_data = { size, vaddr, dma_handle };
+
+ dma_free_noncoherent(dev, size, vaddr, dma_handle);
+ WARN_ON(!devres_destroy(dev, dmam_noncoherent_release, dmam_match,
+ &match_data));
+}
+EXPORT_SYMBOL(dmam_free_noncoherent);
+
+#ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
+
+static void dmam_coherent_decl_release(struct device *dev, void *res)
+{
+ dma_release_declared_memory(dev);
+}
+
+/**
+ * dmam_declare_coherent_memory - Managed dma_declare_coherent_memory()
+ * @dev: Device to declare coherent memory for
+ * @bus_addr: Bus address of coherent memory to be declared
+ * @device_addr: Device address of coherent memory to be declared
+ * @size: Size of coherent memory to be declared
+ * @flags: Flags
+ *
+ * Managed dma_declare_coherent_memory().
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int dmam_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
+ dma_addr_t device_addr, size_t size, int flags)
+{
+ void *res;
+ int rc;
+
+ res = devres_alloc(dmam_coherent_decl_release, 0, GFP_KERNEL);
+ if (!res)
+ return -ENOMEM;
+
+ rc = dma_declare_coherent_memory(dev, bus_addr, device_addr, size,
+ flags);
+ if (rc == 0)
+ devres_add(dev, res);
+ else
+ devres_free(res);
+
+ return rc;
+}
+EXPORT_SYMBOL(dmam_declare_coherent_memory);
+
+/**
+ * dmam_release_declared_memory - Managed dma_release_declared_memory().
+ * @dev: Device to release declared coherent memory for
+ *
+ * Managed dmam_release_declared_memory().
+ */
+void dmam_release_declared_memory(struct device *dev)
+{
+ WARN_ON(devres_destroy(dev, dmam_coherent_decl_release, NULL, NULL));
+}
+EXPORT_SYMBOL(dmam_release_declared_memory);
+
+#endif
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c
index f95d50277274..cd467c9f33b3 100644
--- a/drivers/base/dmapool.c
+++ b/drivers/base/dmapool.c
@@ -415,8 +415,67 @@ dma_pool_free (struct dma_pool *pool, void *vaddr, dma_addr_t dma)
spin_unlock_irqrestore (&pool->lock, flags);
}
+/*
+ * Managed DMA pool
+ */
+static void dmam_pool_release(struct device *dev, void *res)
+{
+ struct dma_pool *pool = *(struct dma_pool **)res;
+
+ dma_pool_destroy(pool);
+}
+
+static int dmam_pool_match(struct device *dev, void *res, void *match_data)
+{
+ return *(struct dma_pool **)res == match_data;
+}
+
+/**
+ * dmam_pool_create - Managed dma_pool_create()
+ * @name: name of pool, for diagnostics
+ * @dev: device that will be doing the DMA
+ * @size: size of the blocks in this pool.
+ * @align: alignment requirement for blocks; must be a power of two
+ * @allocation: returned blocks won't cross this boundary (or zero)
+ *
+ * Managed dma_pool_create(). DMA pool created with this function is
+ * automatically destroyed on driver detach.
+ */
+struct dma_pool *dmam_pool_create(const char *name, struct device *dev,
+ size_t size, size_t align, size_t allocation)
+{
+ struct dma_pool **ptr, *pool;
+
+ ptr = devres_alloc(dmam_pool_release, sizeof(*ptr), GFP_KERNEL);
+ if (!ptr)
+ return NULL;
+
+ pool = *ptr = dma_pool_create(name, dev, size, align, allocation);
+ if (pool)
+ devres_add(dev, ptr);
+ else
+ devres_free(ptr);
+
+ return pool;
+}
+
+/**
+ * dmam_pool_destroy - Managed dma_pool_destroy()
+ * @pool: dma pool that will be destroyed
+ *
+ * Managed dma_pool_destroy().
+ */
+void dmam_pool_destroy(struct dma_pool *pool)
+{
+ struct device *dev = pool->dev;
+
+ dma_pool_destroy(pool);
+ WARN_ON(devres_destroy(dev, dmam_pool_release, dmam_pool_match, pool));
+}
EXPORT_SYMBOL (dma_pool_create);
EXPORT_SYMBOL (dma_pool_destroy);
EXPORT_SYMBOL (dma_pool_alloc);
EXPORT_SYMBOL (dma_pool_free);
+EXPORT_SYMBOL (dmam_pool_create);
+EXPORT_SYMBOL (dmam_pool_destroy);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 001e6f6b9c1b..475e33f76e0d 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -40,13 +40,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
int n;
int nid = dev->id;
struct sysinfo i;
- unsigned long inactive;
- unsigned long active;
- unsigned long free;
si_meminfo_node(&i, nid);
- __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid));
-
n = sprintf(buf, "\n"
"Node %d MemTotal: %8lu kB\n"
@@ -74,8 +69,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
nid, K(i.totalram),
nid, K(i.freeram),
nid, K(i.totalram - i.freeram),
- nid, K(active),
- nid, K(inactive),
+ nid, node_page_state(nid, NR_ACTIVE),
+ nid, node_page_state(nid, NR_INACTIVE),
#ifdef CONFIG_HIGHMEM
nid, K(i.totalhigh),
nid, K(i.freehigh),
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 8d81a3a64c07..92bf868ca056 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -177,7 +177,7 @@ static void DAC960_AnnounceDriver(DAC960_Controller_T *Controller)
DAC960_Failure prints a standardized error message, and then returns false.
*/
-static boolean DAC960_Failure(DAC960_Controller_T *Controller,
+static bool DAC960_Failure(DAC960_Controller_T *Controller,
unsigned char *ErrorMessage)
{
DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",
@@ -206,7 +206,7 @@ static boolean DAC960_Failure(DAC960_Controller_T *Controller,
that are passed in.
*/
-static boolean init_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf,
+static bool init_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf,
size_t len)
{
void *cpu_addr;
@@ -250,7 +250,7 @@ static void free_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf_handle)
failure.
*/
-static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
+static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
{
int CommandAllocationLength, CommandAllocationGroupSize;
int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount;
@@ -790,7 +790,7 @@ static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
on failure.
*/
-static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
+static bool DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
DAC960_V1_CommandOpcode_T CommandOpcode,
dma_addr_t DataDMA)
{
@@ -814,7 +814,7 @@ static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
on failure.
*/
-static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
+static bool DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
DAC960_V1_CommandOpcode_T CommandOpcode,
unsigned char CommandOpcode2,
dma_addr_t DataDMA)
@@ -840,7 +840,7 @@ static boolean DAC960_V1_ExecuteType3B(DAC960_Controller_T *Controller,
on failure.
*/
-static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
+static bool DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
DAC960_V1_CommandOpcode_T CommandOpcode,
unsigned char Channel,
unsigned char TargetID,
@@ -870,7 +870,7 @@ static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
Return data in The controller's HealthStatusBuffer, which is dma-able memory
*/
-static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller)
+static bool DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
@@ -908,7 +908,7 @@ static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller)
memory buffer.
*/
-static boolean DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller)
+static bool DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
@@ -946,7 +946,7 @@ static boolean DAC960_V2_NewControllerInfo(DAC960_Controller_T *Controller)
Data is returned in the controller's V2.NewLogicalDeviceInformation
*/
-static boolean DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller,
+static bool DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller,
unsigned short LogicalDeviceNumber)
{
DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
@@ -997,7 +997,7 @@ static boolean DAC960_V2_NewLogicalDeviceInfo(DAC960_Controller_T *Controller,
*/
-static boolean DAC960_V2_NewPhysicalDeviceInfo(DAC960_Controller_T *Controller,
+static bool DAC960_V2_NewPhysicalDeviceInfo(DAC960_Controller_T *Controller,
unsigned char Channel,
unsigned char TargetID,
unsigned char LogicalUnit)
@@ -1082,7 +1082,7 @@ static void DAC960_V2_ConstructNewUnitSerialNumber(
memory buffer.
*/
-static boolean DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Controller,
+static bool DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Controller,
int Channel, int TargetID, int LogicalUnit)
{
DAC960_Command_T *Command;
@@ -1110,7 +1110,7 @@ static boolean DAC960_V2_NewInquiryUnitSerialNumber(DAC960_Controller_T *Control
success and false on failure.
*/
-static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
+static bool DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
DAC960_V2_OperationDevice_T
OperationDevice)
@@ -1142,7 +1142,7 @@ static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
other dma mapped memory.
*/
-static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
+static bool DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
*Controller)
{
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
@@ -1348,7 +1348,7 @@ skip_mailboxes:
the structures that are contained in that region.
*/
-static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
+static bool DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
*Controller)
{
void __iomem *ControllerBaseAddress = Controller->BaseAddress;
@@ -1373,8 +1373,7 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
Controller->BounceBufferLimit = DAC690_V2_PciDmaMask;
/* This is a temporary dma mapping, used only in the scope of this function */
- CommandMailbox =
- (DAC960_V2_CommandMailbox_T *)pci_alloc_consistent( PCI_Device,
+ CommandMailbox = pci_alloc_consistent(PCI_Device,
sizeof(DAC960_V2_CommandMailbox_T), &CommandMailboxDMA);
if (CommandMailbox == NULL)
return false;
@@ -1526,7 +1525,7 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
from DAC960 V1 Firmware Controllers and initializes the Controller structure.
*/
-static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
+static bool DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
*Controller)
{
DAC960_V1_Enquiry2_T *Enquiry2;
@@ -1767,7 +1766,7 @@ static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
from DAC960 V2 Firmware Controllers and initializes the Controller structure.
*/
-static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
+static bool DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
*Controller)
{
DAC960_V2_ControllerInfo_T *ControllerInfo =
@@ -1879,8 +1878,8 @@ static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
if (NewLogicalDeviceInfo->LogicalDeviceState !=
DAC960_V2_LogicalDevice_Offline)
Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true;
- LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
- kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+ LogicalDeviceInfo = kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T),
+ GFP_ATOMIC);
if (LogicalDeviceInfo == NULL)
return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION");
Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
@@ -1898,7 +1897,7 @@ static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
for Controller.
*/
-static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
+static bool DAC960_ReportControllerConfiguration(DAC960_Controller_T
*Controller)
{
DAC960_Info("Configuring Mylex %s PCI RAID Controller\n",
@@ -1947,7 +1946,7 @@ static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
Controller.
*/
-static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
+static bool DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
*Controller)
{
struct dma_loaf local_dma;
@@ -2095,7 +2094,7 @@ static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
device connected to Controller.
*/
-static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
+static bool DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
*Controller)
{
unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0;
@@ -2113,8 +2112,8 @@ static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
if (!DAC960_V2_NewPhysicalDeviceInfo(Controller, Channel, TargetID, LogicalUnit))
break;
- PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
- kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
+ PhysicalDeviceInfo = kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T),
+ GFP_ATOMIC);
if (PhysicalDeviceInfo == NULL)
return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] =
@@ -2122,8 +2121,8 @@ static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
sizeof(DAC960_V2_PhysicalDeviceInfo_T));
- InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
- kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
+ InquiryUnitSerialNumber = kmalloc(
+ sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
if (InquiryUnitSerialNumber == NULL) {
kfree(PhysicalDeviceInfo);
return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION");
@@ -2219,7 +2218,7 @@ static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T
Information for DAC960 V1 Firmware Controllers.
*/
-static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
+static bool DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
*Controller)
{
int LogicalDriveNumber, Channel, TargetID;
@@ -2316,7 +2315,7 @@ static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
Information for DAC960 V2 Firmware Controllers.
*/
-static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
+static bool DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
*Controller)
{
int PhysicalDeviceIndex, LogicalDriveNumber;
@@ -2501,7 +2500,7 @@ static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
associated with Controller.
*/
-static boolean DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
+static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller)
{
int MajorNumber = DAC960_MAJOR + Controller->ControllerNumber;
int n;
@@ -2582,7 +2581,7 @@ static void DAC960_ComputeGenericDiskInfo(DAC960_Controller_T *Controller)
It returns true for fatal errors and false otherwise.
*/
-static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
+static bool DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
unsigned char ErrorStatus,
unsigned char Parameter0,
unsigned char Parameter1)
@@ -3048,7 +3047,7 @@ Failure:
DAC960_InitializeController initializes Controller.
*/
-static boolean
+static bool
DAC960_InitializeController(DAC960_Controller_T *Controller)
{
if (DAC960_ReadControllerConfiguration(Controller) &&
@@ -3445,8 +3444,8 @@ static void DAC960_RequestFunction(struct request_queue *RequestQueue)
individual Buffer.
*/
-static inline boolean DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
- boolean SuccessfulIO)
+static inline bool DAC960_ProcessCompletedRequest(DAC960_Command_T *Command,
+ bool SuccessfulIO)
{
struct request *Request = Command->Request;
int UpToDate;
@@ -3572,7 +3571,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
else if (CommandType == DAC960_ReadRetryCommand ||
CommandType == DAC960_WriteRetryCommand)
{
- boolean normal_completion;
+ bool normal_completion;
#ifdef FORCE_RETRY_FAILURE_DEBUG
static int retry_count = 1;
#endif
@@ -4659,7 +4658,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
else if (CommandType == DAC960_ReadRetryCommand ||
CommandType == DAC960_WriteRetryCommand)
{
- boolean normal_completion;
+ bool normal_completion;
#ifdef FORCE_RETRY_FAILURE_DEBUG
static int retry_count = 1;
@@ -4949,8 +4948,8 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
PhysicalDevice;
- LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
- kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+ LogicalDeviceInfo = kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T),
+ GFP_ATOMIC);
Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
LogicalDeviceInfo;
DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -5632,7 +5631,7 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
&Controller->V2.ControllerInformation;
unsigned int StatusChangeCounter =
Controller->V2.HealthStatusBuffer->StatusChangeCounter;
- boolean ForceMonitoringCommand = false;
+ bool ForceMonitoringCommand = false;
if (time_after(jiffies, Controller->SecondaryMonitoringTime
+ DAC960_SecondaryMonitoringInterval))
{
@@ -5696,7 +5695,7 @@ static void DAC960_MonitoringTimerFunction(unsigned long TimerData)
necessary. It returns true if there is enough room and false otherwise.
*/
-static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
+static bool DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
unsigned int ByteCount)
{
unsigned char *NewStatusBuffer;
@@ -5709,14 +5708,14 @@ static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
while (NewStatusBufferLength < ByteCount)
NewStatusBufferLength *= 2;
- Controller->CombinedStatusBuffer =
- (unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
+ Controller->CombinedStatusBuffer = kmalloc(NewStatusBufferLength,
+ GFP_ATOMIC);
if (Controller->CombinedStatusBuffer == NULL) return false;
Controller->CombinedStatusBufferLength = NewStatusBufferLength;
return true;
}
- NewStatusBuffer = (unsigned char *)
- kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
+ NewStatusBuffer = kmalloc(2 * Controller->CombinedStatusBufferLength,
+ GFP_ATOMIC);
if (NewStatusBuffer == NULL)
{
DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n",
@@ -5744,7 +5743,7 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
...)
{
static unsigned char Buffer[DAC960_LineBufferSize];
- static boolean BeginningOfLine = true;
+ static bool BeginningOfLine = true;
va_list Arguments;
int Length = 0;
va_start(Arguments, Controller);
@@ -5837,7 +5836,7 @@ static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
Channel and TargetID and returns true on success and false on failure.
*/
-static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
+static bool DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
char *UserCommandString,
unsigned char *Channel,
unsigned char *TargetID)
@@ -5870,7 +5869,7 @@ static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
returns true on success and false on failure.
*/
-static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
+static bool DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
char *UserCommandString,
unsigned char *LogicalDriveNumber)
{
@@ -5951,7 +5950,7 @@ static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
Controllers.
*/
-static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
+static bool DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
unsigned char *UserCommand)
{
DAC960_Command_T *Command;
@@ -6166,7 +6165,7 @@ failure:
on failure.
*/
-static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
+static bool DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
unsigned char Channel,
unsigned char TargetID,
unsigned short
@@ -6213,7 +6212,7 @@ static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
Controllers.
*/
-static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
+static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
unsigned char *UserCommand)
{
DAC960_Command_T *Command;
@@ -7025,7 +7024,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file,
return -EINVAL;
}
-static struct file_operations DAC960_gam_fops = {
+static const struct file_operations DAC960_gam_fops = {
.owner = THIS_MODULE,
.ioctl = DAC960_gam_ioctl
};
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index 6148073532b2..f5e2436c39aa 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -68,13 +68,6 @@
#define DAC690_V2_PciDmaMask 0xffffffffffffffffULL
/*
- Define a Boolean data type.
-*/
-
-typedef bool boolean;
-
-
-/*
Define a 32/64 bit I/O Address data type.
*/
@@ -139,25 +132,25 @@ typedef struct DAC960_SCSI_Inquiry
unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */
unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */
unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */
- boolean RMB:1; /* Byte 1 Bit 7 */
+ bool RMB:1; /* Byte 1 Bit 7 */
unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */
unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */
unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */
unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */
unsigned char :2; /* Byte 3 Bits 4-5 */
- boolean TrmIOP:1; /* Byte 3 Bit 6 */
- boolean AENC:1; /* Byte 3 Bit 7 */
+ bool TrmIOP:1; /* Byte 3 Bit 6 */
+ bool AENC:1; /* Byte 3 Bit 7 */
unsigned char AdditionalLength; /* Byte 4 */
unsigned char :8; /* Byte 5 */
unsigned char :8; /* Byte 6 */
- boolean SftRe:1; /* Byte 7 Bit 0 */
- boolean CmdQue:1; /* Byte 7 Bit 1 */
- boolean :1; /* Byte 7 Bit 2 */
- boolean Linked:1; /* Byte 7 Bit 3 */
- boolean Sync:1; /* Byte 7 Bit 4 */
- boolean WBus16:1; /* Byte 7 Bit 5 */
- boolean WBus32:1; /* Byte 7 Bit 6 */
- boolean RelAdr:1; /* Byte 7 Bit 7 */
+ bool SftRe:1; /* Byte 7 Bit 0 */
+ bool CmdQue:1; /* Byte 7 Bit 1 */
+ bool :1; /* Byte 7 Bit 2 */
+ bool Linked:1; /* Byte 7 Bit 3 */
+ bool Sync:1; /* Byte 7 Bit 4 */
+ bool WBus16:1; /* Byte 7 Bit 5 */
+ bool WBus32:1; /* Byte 7 Bit 6 */
+ bool RelAdr:1; /* Byte 7 Bit 7 */
unsigned char VendorIdentification[8]; /* Bytes 8-15 */
unsigned char ProductIdentification[16]; /* Bytes 16-31 */
unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */
@@ -215,13 +208,13 @@ DAC960_SCSI_RequestSenseKey_T;
typedef struct DAC960_SCSI_RequestSense
{
unsigned char ErrorCode:7; /* Byte 0 Bits 0-6 */
- boolean Valid:1; /* Byte 0 Bit 7 */
+ bool Valid:1; /* Byte 0 Bit 7 */
unsigned char SegmentNumber; /* Byte 1 */
DAC960_SCSI_RequestSenseKey_T SenseKey:4; /* Byte 2 Bits 0-3 */
unsigned char :1; /* Byte 2 Bit 4 */
- boolean ILI:1; /* Byte 2 Bit 5 */
- boolean EOM:1; /* Byte 2 Bit 6 */
- boolean Filemark:1; /* Byte 2 Bit 7 */
+ bool ILI:1; /* Byte 2 Bit 5 */
+ bool EOM:1; /* Byte 2 Bit 6 */
+ bool Filemark:1; /* Byte 2 Bit 7 */
unsigned char Information[4]; /* Bytes 3-6 */
unsigned char AdditionalSenseLength; /* Byte 7 */
unsigned char CommandSpecificInformation[4]; /* Bytes 8-11 */
@@ -381,8 +374,8 @@ typedef struct DAC960_V1_Enquiry
unsigned int LogicalDriveSizes[32]; /* Bytes 4-131 */
unsigned short FlashAge; /* Bytes 132-133 */
struct {
- boolean DeferredWriteError:1; /* Byte 134 Bit 0 */
- boolean BatteryLow:1; /* Byte 134 Bit 1 */
+ bool DeferredWriteError:1; /* Byte 134 Bit 0 */
+ bool BatteryLow:1; /* Byte 134 Bit 1 */
unsigned char :6; /* Byte 134 Bits 2-7 */
} StatusFlags;
unsigned char :8; /* Byte 135 */
@@ -410,7 +403,7 @@ typedef struct DAC960_V1_Enquiry
unsigned char RebuildCount; /* Byte 150 */
struct {
unsigned char :3; /* Byte 151 Bits 0-2 */
- boolean BatteryBackupUnitPresent:1; /* Byte 151 Bit 3 */
+ bool BatteryBackupUnitPresent:1; /* Byte 151 Bit 3 */
unsigned char :3; /* Byte 151 Bits 4-6 */
unsigned char :1; /* Byte 151 Bit 7 */
} MiscFlags;
@@ -492,8 +485,8 @@ typedef struct DAC960_V1_Enquiry2
DAC960_V1_ErrorCorrection_ECC = 0x2,
DAC960_V1_ErrorCorrection_Last = 0x7
} __attribute__ ((packed)) ErrorCorrection:3; /* Byte 40 Bits 3-5 */
- boolean FastPageMode:1; /* Byte 40 Bit 6 */
- boolean LowPowerMemory:1; /* Byte 40 Bit 7 */
+ bool FastPageMode:1; /* Byte 40 Bit 6 */
+ bool LowPowerMemory:1; /* Byte 40 Bit 7 */
unsigned char :8; /* Bytes 41 */
} MemoryType;
unsigned short ClockSpeed; /* Bytes 42-43 */
@@ -538,7 +531,7 @@ typedef struct DAC960_V1_Enquiry2
DAC960_V1_Ultra = 0x1,
DAC960_V1_Ultra2 = 0x2
} __attribute__ ((packed)) BusSpeed:2; /* Byte 106 Bits 2-3 */
- boolean Differential:1; /* Byte 106 Bit 4 */
+ bool Differential:1; /* Byte 106 Bit 4 */
unsigned char :3; /* Byte 106 Bits 5-7 */
} SCSICapability;
unsigned char :8; /* Byte 107 */
@@ -554,10 +547,10 @@ typedef struct DAC960_V1_Enquiry2
} __attribute__ ((packed)) FaultManagementType; /* Byte 114 */
unsigned char :8; /* Byte 115 */
struct {
- boolean Clustering:1; /* Byte 116 Bit 0 */
- boolean MylexOnlineRAIDExpansion:1; /* Byte 116 Bit 1 */
- boolean ReadAhead:1; /* Byte 116 Bit 2 */
- boolean BackgroundInitialization:1; /* Byte 116 Bit 3 */
+ bool Clustering:1; /* Byte 116 Bit 0 */
+ bool MylexOnlineRAIDExpansion:1; /* Byte 116 Bit 1 */
+ bool ReadAhead:1; /* Byte 116 Bit 2 */
+ bool BackgroundInitialization:1; /* Byte 116 Bit 3 */
unsigned int :28; /* Bytes 116-119 */
} FirmwareFeatures;
unsigned int :32; /* Bytes 120-123 */
@@ -589,7 +582,7 @@ typedef struct DAC960_V1_LogicalDriveInformation
unsigned int LogicalDriveSize; /* Bytes 0-3 */
DAC960_V1_LogicalDriveState_T LogicalDriveState; /* Byte 4 */
unsigned char RAIDLevel:7; /* Byte 5 Bits 0-6 */
- boolean WriteBack:1; /* Byte 5 Bit 7 */
+ bool WriteBack:1; /* Byte 5 Bit 7 */
unsigned short :16; /* Bytes 6-7 */
}
DAC960_V1_LogicalDriveInformation_T;
@@ -630,13 +623,13 @@ typedef struct DAC960_V1_EventLogEntry
unsigned char :2; /* Byte 3 Bits 6-7 */
unsigned short SequenceNumber; /* Bytes 4-5 */
unsigned char ErrorCode:7; /* Byte 6 Bits 0-6 */
- boolean Valid:1; /* Byte 6 Bit 7 */
+ bool Valid:1; /* Byte 6 Bit 7 */
unsigned char SegmentNumber; /* Byte 7 */
DAC960_SCSI_RequestSenseKey_T SenseKey:4; /* Byte 8 Bits 0-3 */
unsigned char :1; /* Byte 8 Bit 4 */
- boolean ILI:1; /* Byte 8 Bit 5 */
- boolean EOM:1; /* Byte 8 Bit 6 */
- boolean Filemark:1; /* Byte 8 Bit 7 */
+ bool ILI:1; /* Byte 8 Bit 5 */
+ bool EOM:1; /* Byte 8 Bit 6 */
+ bool Filemark:1; /* Byte 8 Bit 7 */
unsigned char Information[4]; /* Bytes 9-12 */
unsigned char AdditionalSenseLength; /* Byte 13 */
unsigned char CommandSpecificInformation[4]; /* Bytes 14-17 */
@@ -670,7 +663,7 @@ DAC960_V1_PhysicalDeviceState_T;
typedef struct DAC960_V1_DeviceState
{
- boolean Present:1; /* Byte 0 Bit 0 */
+ bool Present:1; /* Byte 0 Bit 0 */
unsigned char :7; /* Byte 0 Bits 1-7 */
enum {
DAC960_V1_OtherType = 0x0,
@@ -678,12 +671,12 @@ typedef struct DAC960_V1_DeviceState
DAC960_V1_SequentialType = 0x2,
DAC960_V1_CDROM_or_WORM_Type = 0x3
} __attribute__ ((packed)) DeviceType:2; /* Byte 1 Bits 0-1 */
- boolean :1; /* Byte 1 Bit 2 */
- boolean Fast20:1; /* Byte 1 Bit 3 */
- boolean Sync:1; /* Byte 1 Bit 4 */
- boolean Fast:1; /* Byte 1 Bit 5 */
- boolean Wide:1; /* Byte 1 Bit 6 */
- boolean TaggedQueuingSupported:1; /* Byte 1 Bit 7 */
+ bool :1; /* Byte 1 Bit 2 */
+ bool Fast20:1; /* Byte 1 Bit 3 */
+ bool Sync:1; /* Byte 1 Bit 4 */
+ bool Fast:1; /* Byte 1 Bit 5 */
+ bool Wide:1; /* Byte 1 Bit 6 */
+ bool TaggedQueuingSupported:1; /* Byte 1 Bit 7 */
DAC960_V1_PhysicalDeviceState_T DeviceState; /* Byte 2 */
unsigned char :8; /* Byte 3 */
unsigned char SynchronousMultiplier; /* Byte 4 */
@@ -765,15 +758,15 @@ DAC960_V1_ErrorTable_T;
typedef struct DAC960_V1_Config2
{
unsigned char :1; /* Byte 0 Bit 0 */
- boolean ActiveNegationEnabled:1; /* Byte 0 Bit 1 */
+ bool ActiveNegationEnabled:1; /* Byte 0 Bit 1 */
unsigned char :5; /* Byte 0 Bits 2-6 */
- boolean NoRescanIfResetReceivedDuringScan:1; /* Byte 0 Bit 7 */
- boolean StorageWorksSupportEnabled:1; /* Byte 1 Bit 0 */
- boolean HewlettPackardSupportEnabled:1; /* Byte 1 Bit 1 */
- boolean NoDisconnectOnFirstCommand:1; /* Byte 1 Bit 2 */
+ bool NoRescanIfResetReceivedDuringScan:1; /* Byte 0 Bit 7 */
+ bool StorageWorksSupportEnabled:1; /* Byte 1 Bit 0 */
+ bool HewlettPackardSupportEnabled:1; /* Byte 1 Bit 1 */
+ bool NoDisconnectOnFirstCommand:1; /* Byte 1 Bit 2 */
unsigned char :2; /* Byte 1 Bits 3-4 */
- boolean AEMI_ARM:1; /* Byte 1 Bit 5 */
- boolean AEMI_OFM:1; /* Byte 1 Bit 6 */
+ bool AEMI_ARM:1; /* Byte 1 Bit 5 */
+ bool AEMI_OFM:1; /* Byte 1 Bit 6 */
unsigned char :1; /* Byte 1 Bit 7 */
enum {
DAC960_V1_OEMID_Mylex = 0x00,
@@ -787,13 +780,13 @@ typedef struct DAC960_V1_Config2
unsigned char PhysicalSector; /* Byte 4 */
unsigned char LogicalSector; /* Byte 5 */
unsigned char BlockFactor; /* Byte 6 */
- boolean ReadAheadEnabled:1; /* Byte 7 Bit 0 */
- boolean LowBIOSDelay:1; /* Byte 7 Bit 1 */
+ bool ReadAheadEnabled:1; /* Byte 7 Bit 0 */
+ bool LowBIOSDelay:1; /* Byte 7 Bit 1 */
unsigned char :2; /* Byte 7 Bits 2-3 */
- boolean ReassignRestrictedToOneSector:1; /* Byte 7 Bit 4 */
+ bool ReassignRestrictedToOneSector:1; /* Byte 7 Bit 4 */
unsigned char :1; /* Byte 7 Bit 5 */
- boolean ForceUnitAccessDuringWriteRecovery:1; /* Byte 7 Bit 6 */
- boolean EnableLeftSymmetricRAID5Algorithm:1; /* Byte 7 Bit 7 */
+ bool ForceUnitAccessDuringWriteRecovery:1; /* Byte 7 Bit 6 */
+ bool EnableLeftSymmetricRAID5Algorithm:1; /* Byte 7 Bit 7 */
unsigned char DefaultRebuildRate; /* Byte 8 */
unsigned char :8; /* Byte 9 */
unsigned char BlocksPerCacheLine; /* Byte 10 */
@@ -805,10 +798,10 @@ typedef struct DAC960_V1_Config2
DAC960_V1_Sync_5MHz = 0x2,
DAC960_V1_Sync_10or20MHz = 0x3 /* Byte 11 Bits 0-1 */
} __attribute__ ((packed)) Speed:2;
- boolean Force8Bit:1; /* Byte 11 Bit 2 */
- boolean DisableFast20:1; /* Byte 11 Bit 3 */
+ bool Force8Bit:1; /* Byte 11 Bit 2 */
+ bool DisableFast20:1; /* Byte 11 Bit 3 */
unsigned char :3; /* Byte 11 Bits 4-6 */
- boolean EnableTaggedQueuing:1; /* Byte 11 Bit 7 */
+ bool EnableTaggedQueuing:1; /* Byte 11 Bit 7 */
} __attribute__ ((packed)) ChannelParameters[6]; /* Bytes 12-17 */
unsigned char SCSIInitiatorID; /* Byte 18 */
unsigned char :8; /* Byte 19 */
@@ -819,8 +812,8 @@ typedef struct DAC960_V1_Config2
unsigned char SimultaneousDeviceSpinUpCount; /* Byte 21 */
unsigned char SecondsDelayBetweenSpinUps; /* Byte 22 */
unsigned char Reserved1[29]; /* Bytes 23-51 */
- boolean BIOSDisabled:1; /* Byte 52 Bit 0 */
- boolean CDROMBootEnabled:1; /* Byte 52 Bit 1 */
+ bool BIOSDisabled:1; /* Byte 52 Bit 0 */
+ bool CDROMBootEnabled:1; /* Byte 52 Bit 1 */
unsigned char :3; /* Byte 52 Bits 2-4 */
enum {
DAC960_V1_Geometry_128_32 = 0x0,
@@ -849,7 +842,7 @@ typedef struct DAC960_V1_DCDB
DAC960_V1_DCDB_DataTransferSystemToDevice = 2,
DAC960_V1_DCDB_IllegalDataTransfer = 3
} __attribute__ ((packed)) Direction:2; /* Byte 1 Bits 0-1 */
- boolean EarlyStatus:1; /* Byte 1 Bit 2 */
+ bool EarlyStatus:1; /* Byte 1 Bit 2 */
unsigned char :1; /* Byte 1 Bit 3 */
enum {
DAC960_V1_DCDB_Timeout_24_hours = 0,
@@ -857,8 +850,8 @@ typedef struct DAC960_V1_DCDB
DAC960_V1_DCDB_Timeout_60_seconds = 2,
DAC960_V1_DCDB_Timeout_10_minutes = 3
} __attribute__ ((packed)) Timeout:2; /* Byte 1 Bits 4-5 */
- boolean NoAutomaticRequestSense:1; /* Byte 1 Bit 6 */
- boolean DisconnectPermitted:1; /* Byte 1 Bit 7 */
+ bool NoAutomaticRequestSense:1; /* Byte 1 Bit 6 */
+ bool DisconnectPermitted:1; /* Byte 1 Bit 7 */
unsigned short TransferLength; /* Bytes 2-3 */
DAC960_BusAddress32_T BusAddress; /* Bytes 4-7 */
unsigned char CDBLength:4; /* Byte 8 Bits 0-3 */
@@ -920,7 +913,7 @@ typedef union DAC960_V1_CommandMailbox
DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 1 */
unsigned char Dummy1[5]; /* Bytes 2-6 */
unsigned char LogicalDriveNumber:6; /* Byte 7 Bits 0-6 */
- boolean AutoRestore:1; /* Byte 7 Bit 7 */
+ bool AutoRestore:1; /* Byte 7 Bit 7 */
unsigned char Dummy2[8]; /* Bytes 8-15 */
} __attribute__ ((packed)) Type3C;
struct {
@@ -1070,9 +1063,9 @@ typedef struct DAC960_V2_MemoryType
DAC960_V2_MemoryType_SDRAM = 0x04,
DAC960_V2_MemoryType_Last = 0x1F
} __attribute__ ((packed)) MemoryType:5; /* Byte 0 Bits 0-4 */
- boolean :1; /* Byte 0 Bit 5 */
- boolean MemoryParity:1; /* Byte 0 Bit 6 */
- boolean MemoryECC:1; /* Byte 0 Bit 7 */
+ bool :1; /* Byte 0 Bit 5 */
+ bool MemoryParity:1; /* Byte 0 Bit 6 */
+ bool MemoryECC:1; /* Byte 0 Bit 7 */
}
DAC960_V2_MemoryType_T;
@@ -1187,13 +1180,13 @@ typedef struct DAC960_V2_ControllerInfo
unsigned char OEM_Code; /* Byte 131 */
unsigned char VendorName[16]; /* Bytes 132-147 */
/* Other Physical/Controller/Operation Information */
- boolean BBU_Present:1; /* Byte 148 Bit 0 */
- boolean ActiveActiveClusteringMode:1; /* Byte 148 Bit 1 */
+ bool BBU_Present:1; /* Byte 148 Bit 0 */
+ bool ActiveActiveClusteringMode:1; /* Byte 148 Bit 1 */
unsigned char :6; /* Byte 148 Bits 2-7 */
unsigned char :8; /* Byte 149 */
unsigned short :16; /* Bytes 150-151 */
/* Physical Device Scan Information */
- boolean PhysicalScanActive:1; /* Byte 152 Bit 0 */
+ bool PhysicalScanActive:1; /* Byte 152 Bit 0 */
unsigned char :7; /* Byte 152 Bits 1-7 */
unsigned char PhysicalDeviceChannelNumber; /* Byte 153 */
unsigned char PhysicalDeviceTargetID; /* Byte 154 */
@@ -1305,8 +1298,8 @@ typedef struct DAC960_V2_ControllerInfo
unsigned int FreeIOP; /* Bytes 468-471 */
unsigned short MaximumCombLengthInBlocks; /* Bytes 472-473 */
unsigned short NumberOfConfigurationGroups; /* Bytes 474-475 */
- boolean InstallationAbortStatus:1; /* Byte 476 Bit 0 */
- boolean MaintenanceModeStatus:1; /* Byte 476 Bit 1 */
+ bool InstallationAbortStatus:1; /* Byte 476 Bit 0 */
+ bool MaintenanceModeStatus:1; /* Byte 476 Bit 1 */
unsigned int :24; /* Bytes 476-479 */
unsigned char Reserved10[32]; /* Bytes 480-511 */
unsigned char Reserved11[512]; /* Bytes 512-1023 */
@@ -1357,33 +1350,33 @@ typedef struct DAC960_V2_LogicalDeviceInfo
DAC960_V2_IntelligentWriteCacheEnabled = 0x3,
DAC960_V2_WriteCache_Last = 0x7
} __attribute__ ((packed)) WriteCache:3; /* Byte 8 Bits 3-5 */
- boolean :1; /* Byte 8 Bit 6 */
- boolean LogicalDeviceInitialized:1; /* Byte 8 Bit 7 */
+ bool :1; /* Byte 8 Bit 6 */
+ bool LogicalDeviceInitialized:1; /* Byte 8 Bit 7 */
} LogicalDeviceControl; /* Byte 8 */
/* Logical Device Operations Status */
- boolean ConsistencyCheckInProgress:1; /* Byte 9 Bit 0 */
- boolean RebuildInProgress:1; /* Byte 9 Bit 1 */
- boolean BackgroundInitializationInProgress:1; /* Byte 9 Bit 2 */
- boolean ForegroundInitializationInProgress:1; /* Byte 9 Bit 3 */
- boolean DataMigrationInProgress:1; /* Byte 9 Bit 4 */
- boolean PatrolOperationInProgress:1; /* Byte 9 Bit 5 */
+ bool ConsistencyCheckInProgress:1; /* Byte 9 Bit 0 */
+ bool RebuildInProgress:1; /* Byte 9 Bit 1 */
+ bool BackgroundInitializationInProgress:1; /* Byte 9 Bit 2 */
+ bool ForegroundInitializationInProgress:1; /* Byte 9 Bit 3 */
+ bool DataMigrationInProgress:1; /* Byte 9 Bit 4 */
+ bool PatrolOperationInProgress:1; /* Byte 9 Bit 5 */
unsigned char :2; /* Byte 9 Bits 6-7 */
unsigned char RAID5WriteUpdate; /* Byte 10 */
unsigned char RAID5Algorithm; /* Byte 11 */
unsigned short LogicalDeviceNumber; /* Bytes 12-13 */
/* BIOS Info */
- boolean BIOSDisabled:1; /* Byte 14 Bit 0 */
- boolean CDROMBootEnabled:1; /* Byte 14 Bit 1 */
- boolean DriveCoercionEnabled:1; /* Byte 14 Bit 2 */
- boolean WriteSameDisabled:1; /* Byte 14 Bit 3 */
- boolean HBA_ModeEnabled:1; /* Byte 14 Bit 4 */
+ bool BIOSDisabled:1; /* Byte 14 Bit 0 */
+ bool CDROMBootEnabled:1; /* Byte 14 Bit 1 */
+ bool DriveCoercionEnabled:1; /* Byte 14 Bit 2 */
+ bool WriteSameDisabled:1; /* Byte 14 Bit 3 */
+ bool HBA_ModeEnabled:1; /* Byte 14 Bit 4 */
enum {
DAC960_V2_Geometry_128_32 = 0x0,
DAC960_V2_Geometry_255_63 = 0x1,
DAC960_V2_Geometry_Reserved1 = 0x2,
DAC960_V2_Geometry_Reserved2 = 0x3
} __attribute__ ((packed)) DriveGeometry:2; /* Byte 14 Bits 5-6 */
- boolean SuperReadAheadEnabled:1; /* Byte 14 Bit 7 */
+ bool SuperReadAheadEnabled:1; /* Byte 14 Bit 7 */
unsigned char :8; /* Byte 15 */
/* Error Counters */
unsigned short SoftErrors; /* Bytes 16-17 */
@@ -1446,13 +1439,13 @@ typedef struct DAC960_V2_PhysicalDeviceInfo
unsigned char TargetID; /* Byte 2 */
unsigned char LogicalUnit; /* Byte 3 */
/* Configuration Status Bits */
- boolean PhysicalDeviceFaultTolerant:1; /* Byte 4 Bit 0 */
- boolean PhysicalDeviceConnected:1; /* Byte 4 Bit 1 */
- boolean PhysicalDeviceLocalToController:1; /* Byte 4 Bit 2 */
+ bool PhysicalDeviceFaultTolerant:1; /* Byte 4 Bit 0 */
+ bool PhysicalDeviceConnected:1; /* Byte 4 Bit 1 */
+ bool PhysicalDeviceLocalToController:1; /* Byte 4 Bit 2 */
unsigned char :5; /* Byte 4 Bits 3-7 */
/* Multiple Host/Controller Status Bits */
- boolean RemoteHostSystemDead:1; /* Byte 5 Bit 0 */
- boolean RemoteControllerDead:1; /* Byte 5 Bit 1 */
+ bool RemoteHostSystemDead:1; /* Byte 5 Bit 0 */
+ bool RemoteControllerDead:1; /* Byte 5 Bit 1 */
unsigned char :6; /* Byte 5 Bits 2-7 */
DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState; /* Byte 6 */
unsigned char NegotiatedDataWidthBits; /* Byte 7 */
@@ -1464,12 +1457,12 @@ typedef struct DAC960_V2_PhysicalDeviceInfo
unsigned char NetworkAddress[16]; /* Bytes 16-31 */
unsigned short MaximumTags; /* Bytes 32-33 */
/* Physical Device Operations Status */
- boolean ConsistencyCheckInProgress:1; /* Byte 34 Bit 0 */
- boolean RebuildInProgress:1; /* Byte 34 Bit 1 */
- boolean MakingDataConsistentInProgress:1; /* Byte 34 Bit 2 */
- boolean PhysicalDeviceInitializationInProgress:1; /* Byte 34 Bit 3 */
- boolean DataMigrationInProgress:1; /* Byte 34 Bit 4 */
- boolean PatrolOperationInProgress:1; /* Byte 34 Bit 5 */
+ bool ConsistencyCheckInProgress:1; /* Byte 34 Bit 0 */
+ bool RebuildInProgress:1; /* Byte 34 Bit 1 */
+ bool MakingDataConsistentInProgress:1; /* Byte 34 Bit 2 */
+ bool PhysicalDeviceInitializationInProgress:1; /* Byte 34 Bit 3 */
+ bool DataMigrationInProgress:1; /* Byte 34 Bit 4 */
+ bool PatrolOperationInProgress:1; /* Byte 34 Bit 5 */
unsigned char :2; /* Byte 34 Bits 6-7 */
unsigned char LongOperationStatus; /* Byte 35 */
unsigned char ParityErrors; /* Byte 36 */
@@ -1555,14 +1548,14 @@ DAC960_V2_Event_T;
typedef struct DAC960_V2_CommandControlBits
{
- boolean ForceUnitAccess:1; /* Byte 0 Bit 0 */
- boolean DisablePageOut:1; /* Byte 0 Bit 1 */
- boolean :1; /* Byte 0 Bit 2 */
- boolean AdditionalScatterGatherListMemory:1; /* Byte 0 Bit 3 */
- boolean DataTransferControllerToHost:1; /* Byte 0 Bit 4 */
- boolean :1; /* Byte 0 Bit 5 */
- boolean NoAutoRequestSense:1; /* Byte 0 Bit 6 */
- boolean DisconnectProhibited:1; /* Byte 0 Bit 7 */
+ bool ForceUnitAccess:1; /* Byte 0 Bit 0 */
+ bool DisablePageOut:1; /* Byte 0 Bit 1 */
+ bool :1; /* Byte 0 Bit 2 */
+ bool AdditionalScatterGatherListMemory:1; /* Byte 0 Bit 3 */
+ bool DataTransferControllerToHost:1; /* Byte 0 Bit 4 */
+ bool :1; /* Byte 0 Bit 5 */
+ bool NoAutoRequestSense:1; /* Byte 0 Bit 6 */
+ bool DisconnectProhibited:1; /* Byte 0 Bit 7 */
}
DAC960_V2_CommandControlBits_T;
@@ -1825,8 +1818,8 @@ typedef union DAC960_V2_CommandMailbox
DAC960_V2_CommandTimeout_T CommandTimeout; /* Byte 19 */
unsigned char RequestSenseSize; /* Byte 20 */
unsigned char IOCTL_Opcode; /* Byte 21 */
- boolean RestoreConsistency:1; /* Byte 22 Bit 0 */
- boolean InitializedAreaOnly:1; /* Byte 22 Bit 1 */
+ bool RestoreConsistency:1; /* Byte 22 Bit 0 */
+ bool InitializedAreaOnly:1; /* Byte 22 Bit 1 */
unsigned char :6; /* Byte 22 Bits 2-7 */
unsigned char Reserved[9]; /* Bytes 23-31 */
DAC960_V2_DataTransferMemoryAddress_T
@@ -2190,7 +2183,7 @@ typedef union DAC960_V1_StatusMailbox
struct {
DAC960_V1_CommandIdentifier_T CommandIdentifier; /* Byte 0 */
unsigned char :7; /* Byte 1 Bits 0-6 */
- boolean Valid:1; /* Byte 1 Bit 7 */
+ bool Valid:1; /* Byte 1 Bit 7 */
DAC960_V1_CommandStatus_T CommandStatus; /* Bytes 2-3 */
} Fields;
}
@@ -2322,12 +2315,12 @@ typedef struct DAC960_Controller
unsigned long ShutdownMonitoringTimer;
unsigned long LastProgressReportTime;
unsigned long LastCurrentStatusTime;
- boolean ControllerInitialized;
- boolean MonitoringCommandDeferred;
- boolean EphemeralProgressMessage;
- boolean DriveSpinUpMessageDisplayed;
- boolean MonitoringAlertMode;
- boolean SuppressEnclosureMessages;
+ bool ControllerInitialized;
+ bool MonitoringCommandDeferred;
+ bool EphemeralProgressMessage;
+ bool DriveSpinUpMessageDisplayed;
+ bool MonitoringAlertMode;
+ bool SuppressEnclosureMessages;
struct timer_list MonitoringTimer;
struct gendisk *disks[DAC960_MaxLogicalDrives];
struct pci_pool *ScatterGatherPool;
@@ -2342,11 +2335,11 @@ typedef struct DAC960_Controller
DAC960_Command_T InitialCommand;
DAC960_Command_T *Commands[DAC960_MaxDriverQueueDepth];
struct proc_dir_entry *ControllerProcEntry;
- boolean LogicalDriveInitiallyAccessible[DAC960_MaxLogicalDrives];
+ bool LogicalDriveInitiallyAccessible[DAC960_MaxLogicalDrives];
void (*QueueCommand)(DAC960_Command_T *Command);
- boolean (*ReadControllerConfiguration)(struct DAC960_Controller *);
- boolean (*ReadDeviceConfiguration)(struct DAC960_Controller *);
- boolean (*ReportDeviceConfiguration)(struct DAC960_Controller *);
+ bool (*ReadControllerConfiguration)(struct DAC960_Controller *);
+ bool (*ReadDeviceConfiguration)(struct DAC960_Controller *);
+ bool (*ReportDeviceConfiguration)(struct DAC960_Controller *);
void (*QueueReadWriteCommand)(DAC960_Command_T *Command);
union {
struct {
@@ -2359,21 +2352,21 @@ typedef struct DAC960_Controller
unsigned short OldEventLogSequenceNumber;
unsigned short DeviceStateChannel;
unsigned short DeviceStateTargetID;
- boolean DualModeMemoryMailboxInterface;
- boolean BackgroundInitializationStatusSupported;
- boolean SAFTE_EnclosureManagementEnabled;
- boolean NeedLogicalDriveInformation;
- boolean NeedErrorTableInformation;
- boolean NeedDeviceStateInformation;
- boolean NeedDeviceInquiryInformation;
- boolean NeedDeviceSerialNumberInformation;
- boolean NeedRebuildProgress;
- boolean NeedConsistencyCheckProgress;
- boolean NeedBackgroundInitializationStatus;
- boolean StartDeviceStateScan;
- boolean RebuildProgressFirst;
- boolean RebuildFlagPending;
- boolean RebuildStatusPending;
+ bool DualModeMemoryMailboxInterface;
+ bool BackgroundInitializationStatusSupported;
+ bool SAFTE_EnclosureManagementEnabled;
+ bool NeedLogicalDriveInformation;
+ bool NeedErrorTableInformation;
+ bool NeedDeviceStateInformation;
+ bool NeedDeviceInquiryInformation;
+ bool NeedDeviceSerialNumberInformation;
+ bool NeedRebuildProgress;
+ bool NeedConsistencyCheckProgress;
+ bool NeedBackgroundInitializationStatus;
+ bool StartDeviceStateScan;
+ bool RebuildProgressFirst;
+ bool RebuildFlagPending;
+ bool RebuildStatusPending;
dma_addr_t FirstCommandMailboxDMA;
DAC960_V1_CommandMailbox_T *FirstCommandMailbox;
@@ -2432,17 +2425,17 @@ typedef struct DAC960_Controller
dma_addr_t NewInquiryUnitSerialNumberDMA;
int DeviceResetCount[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
- boolean DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+ bool DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
} V1;
struct {
unsigned int StatusChangeCounter;
unsigned int NextEventSequenceNumber;
unsigned int PhysicalDeviceIndex;
- boolean NeedLogicalDeviceInformation;
- boolean NeedPhysicalDeviceInformation;
- boolean NeedDeviceSerialNumberInformation;
- boolean StartLogicalDeviceInformationScan;
- boolean StartPhysicalDeviceInformationScan;
+ bool NeedLogicalDeviceInformation;
+ bool NeedPhysicalDeviceInformation;
+ bool NeedDeviceSerialNumberInformation;
+ bool StartLogicalDeviceInformationScan;
+ bool StartPhysicalDeviceInformationScan;
struct pci_pool *RequestSensePool;
dma_addr_t FirstCommandMailboxDMA;
@@ -2487,7 +2480,7 @@ typedef struct DAC960_Controller
DAC960_V2_PhysicalDevice_T
LogicalDriveToVirtualDevice[DAC960_MaxLogicalDrives];
- boolean LogicalDriveFoundDuringScan[DAC960_MaxLogicalDrives];
+ bool LogicalDriveFoundDuringScan[DAC960_MaxLogicalDrives];
} V2;
} FW;
unsigned char ProgressBuffer[DAC960_ProgressBufferSize];
@@ -2572,17 +2565,17 @@ typedef union DAC960_GEM_InboundDoorBellRegister
unsigned int All;
struct {
unsigned int :24;
- boolean HardwareMailboxNewCommand:1;
- boolean AcknowledgeHardwareMailboxStatus:1;
- boolean GenerateInterrupt:1;
- boolean ControllerReset:1;
- boolean MemoryMailboxNewCommand:1;
+ bool HardwareMailboxNewCommand:1;
+ bool AcknowledgeHardwareMailboxStatus:1;
+ bool GenerateInterrupt:1;
+ bool ControllerReset:1;
+ bool MemoryMailboxNewCommand:1;
unsigned int :3;
} Write;
struct {
unsigned int :24;
- boolean HardwareMailboxFull:1;
- boolean InitializationInProgress:1;
+ bool HardwareMailboxFull:1;
+ bool InitializationInProgress:1;
unsigned int :6;
} Read;
}
@@ -2596,14 +2589,14 @@ typedef union DAC960_GEM_OutboundDoorBellRegister
unsigned int All;
struct {
unsigned int :24;
- boolean AcknowledgeHardwareMailboxInterrupt:1;
- boolean AcknowledgeMemoryMailboxInterrupt:1;
+ bool AcknowledgeHardwareMailboxInterrupt:1;
+ bool AcknowledgeMemoryMailboxInterrupt:1;
unsigned int :6;
} Write;
struct {
unsigned int :24;
- boolean HardwareMailboxStatusAvailable:1;
- boolean MemoryMailboxStatusAvailable:1;
+ bool HardwareMailboxStatusAvailable:1;
+ bool MemoryMailboxStatusAvailable:1;
unsigned int :6;
} Read;
}
@@ -2635,7 +2628,7 @@ typedef union DAC960_GEM_ErrorStatusRegister
struct {
unsigned int :24;
unsigned int :5;
- boolean ErrorStatusPending:1;
+ bool ErrorStatusPending:1;
unsigned int :2;
} Bits;
}
@@ -2697,7 +2690,7 @@ void DAC960_GEM_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
+bool DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
{
DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -2707,7 +2700,7 @@ boolean DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_GEM_InitializationInProgressP(void __iomem *ControllerBaseAddress)
+bool DAC960_GEM_InitializationInProgressP(void __iomem *ControllerBaseAddress)
{
DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -2748,7 +2741,7 @@ void DAC960_GEM_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -2758,7 +2751,7 @@ boolean DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseA
}
static inline
-boolean DAC960_GEM_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_GEM_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -2790,7 +2783,7 @@ void DAC960_GEM_DisableInterrupts(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_GEM_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
+bool DAC960_GEM_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
{
DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister;
InterruptMaskRegister.All =
@@ -2834,7 +2827,7 @@ DAC960_GEM_ReadCommandStatus(void __iomem *ControllerBaseAddress)
return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset + 2);
}
-static inline boolean
+static inline bool
DAC960_GEM_ReadErrorStatus(void __iomem *ControllerBaseAddress,
unsigned char *ErrorStatus,
unsigned char *Parameter0,
@@ -2882,16 +2875,16 @@ typedef union DAC960_BA_InboundDoorBellRegister
{
unsigned char All;
struct {
- boolean HardwareMailboxNewCommand:1; /* Bit 0 */
- boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
- boolean GenerateInterrupt:1; /* Bit 2 */
- boolean ControllerReset:1; /* Bit 3 */
- boolean MemoryMailboxNewCommand:1; /* Bit 4 */
+ bool HardwareMailboxNewCommand:1; /* Bit 0 */
+ bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
+ bool GenerateInterrupt:1; /* Bit 2 */
+ bool ControllerReset:1; /* Bit 3 */
+ bool MemoryMailboxNewCommand:1; /* Bit 4 */
unsigned char :3; /* Bits 5-7 */
} Write;
struct {
- boolean HardwareMailboxEmpty:1; /* Bit 0 */
- boolean InitializationNotInProgress:1; /* Bit 1 */
+ bool HardwareMailboxEmpty:1; /* Bit 0 */
+ bool InitializationNotInProgress:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Read;
}
@@ -2906,13 +2899,13 @@ typedef union DAC960_BA_OutboundDoorBellRegister
{
unsigned char All;
struct {
- boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
- boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
+ bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
+ bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Write;
struct {
- boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */
- boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */
+ bool HardwareMailboxStatusAvailable:1; /* Bit 0 */
+ bool MemoryMailboxStatusAvailable:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Read;
}
@@ -2928,8 +2921,8 @@ typedef union DAC960_BA_InterruptMaskRegister
unsigned char All;
struct {
unsigned int :2; /* Bits 0-1 */
- boolean DisableInterrupts:1; /* Bit 2 */
- boolean DisableInterruptsI2O:1; /* Bit 3 */
+ bool DisableInterrupts:1; /* Bit 2 */
+ bool DisableInterruptsI2O:1; /* Bit 3 */
unsigned int :4; /* Bits 4-7 */
} Bits;
}
@@ -2945,7 +2938,7 @@ typedef union DAC960_BA_ErrorStatusRegister
unsigned char All;
struct {
unsigned int :2; /* Bits 0-1 */
- boolean ErrorStatusPending:1; /* Bit 2 */
+ bool ErrorStatusPending:1; /* Bit 2 */
unsigned int :5; /* Bits 3-7 */
} Bits;
}
@@ -3008,7 +3001,7 @@ void DAC960_BA_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_BA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
+bool DAC960_BA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
{
DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -3017,7 +3010,7 @@ boolean DAC960_BA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_BA_InitializationInProgressP(void __iomem *ControllerBaseAddress)
+bool DAC960_BA_InitializationInProgressP(void __iomem *ControllerBaseAddress)
{
DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -3057,7 +3050,7 @@ void DAC960_BA_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_BA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_BA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -3066,7 +3059,7 @@ boolean DAC960_BA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAd
}
static inline
-boolean DAC960_BA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_BA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -3097,7 +3090,7 @@ void DAC960_BA_DisableInterrupts(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_BA_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
+bool DAC960_BA_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
{
DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
InterruptMaskRegister.All =
@@ -3140,7 +3133,7 @@ DAC960_BA_ReadCommandStatus(void __iomem *ControllerBaseAddress)
return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset + 2);
}
-static inline boolean
+static inline bool
DAC960_BA_ReadErrorStatus(void __iomem *ControllerBaseAddress,
unsigned char *ErrorStatus,
unsigned char *Parameter0,
@@ -3188,16 +3181,16 @@ typedef union DAC960_LP_InboundDoorBellRegister
{
unsigned char All;
struct {
- boolean HardwareMailboxNewCommand:1; /* Bit 0 */
- boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
- boolean GenerateInterrupt:1; /* Bit 2 */
- boolean ControllerReset:1; /* Bit 3 */
- boolean MemoryMailboxNewCommand:1; /* Bit 4 */
+ bool HardwareMailboxNewCommand:1; /* Bit 0 */
+ bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
+ bool GenerateInterrupt:1; /* Bit 2 */
+ bool ControllerReset:1; /* Bit 3 */
+ bool MemoryMailboxNewCommand:1; /* Bit 4 */
unsigned char :3; /* Bits 5-7 */
} Write;
struct {
- boolean HardwareMailboxFull:1; /* Bit 0 */
- boolean InitializationInProgress:1; /* Bit 1 */
+ bool HardwareMailboxFull:1; /* Bit 0 */
+ bool InitializationInProgress:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Read;
}
@@ -3212,13 +3205,13 @@ typedef union DAC960_LP_OutboundDoorBellRegister
{
unsigned char All;
struct {
- boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
- boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
+ bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
+ bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Write;
struct {
- boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */
- boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */
+ bool HardwareMailboxStatusAvailable:1; /* Bit 0 */
+ bool MemoryMailboxStatusAvailable:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Read;
}
@@ -3234,7 +3227,7 @@ typedef union DAC960_LP_InterruptMaskRegister
unsigned char All;
struct {
unsigned int :2; /* Bits 0-1 */
- boolean DisableInterrupts:1; /* Bit 2 */
+ bool DisableInterrupts:1; /* Bit 2 */
unsigned int :5; /* Bits 3-7 */
} Bits;
}
@@ -3250,7 +3243,7 @@ typedef union DAC960_LP_ErrorStatusRegister
unsigned char All;
struct {
unsigned int :2; /* Bits 0-1 */
- boolean ErrorStatusPending:1; /* Bit 2 */
+ bool ErrorStatusPending:1; /* Bit 2 */
unsigned int :5; /* Bits 3-7 */
} Bits;
}
@@ -3313,7 +3306,7 @@ void DAC960_LP_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_LP_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
+bool DAC960_LP_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
{
DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -3322,7 +3315,7 @@ boolean DAC960_LP_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_LP_InitializationInProgressP(void __iomem *ControllerBaseAddress)
+bool DAC960_LP_InitializationInProgressP(void __iomem *ControllerBaseAddress)
{
DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -3362,7 +3355,7 @@ void DAC960_LP_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_LP_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_LP_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -3371,7 +3364,7 @@ boolean DAC960_LP_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAd
}
static inline
-boolean DAC960_LP_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_LP_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -3400,7 +3393,7 @@ void DAC960_LP_DisableInterrupts(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_LP_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
+bool DAC960_LP_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
{
DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
InterruptMaskRegister.All =
@@ -3442,7 +3435,7 @@ DAC960_LP_ReadCommandStatus(void __iomem *ControllerBaseAddress)
return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset + 2);
}
-static inline boolean
+static inline bool
DAC960_LP_ReadErrorStatus(void __iomem *ControllerBaseAddress,
unsigned char *ErrorStatus,
unsigned char *Parameter0,
@@ -3502,16 +3495,16 @@ typedef union DAC960_LA_InboundDoorBellRegister
{
unsigned char All;
struct {
- boolean HardwareMailboxNewCommand:1; /* Bit 0 */
- boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
- boolean GenerateInterrupt:1; /* Bit 2 */
- boolean ControllerReset:1; /* Bit 3 */
- boolean MemoryMailboxNewCommand:1; /* Bit 4 */
+ bool HardwareMailboxNewCommand:1; /* Bit 0 */
+ bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
+ bool GenerateInterrupt:1; /* Bit 2 */
+ bool ControllerReset:1; /* Bit 3 */
+ bool MemoryMailboxNewCommand:1; /* Bit 4 */
unsigned char :3; /* Bits 5-7 */
} Write;
struct {
- boolean HardwareMailboxEmpty:1; /* Bit 0 */
- boolean InitializationNotInProgress:1; /* Bit 1 */
+ bool HardwareMailboxEmpty:1; /* Bit 0 */
+ bool InitializationNotInProgress:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Read;
}
@@ -3526,13 +3519,13 @@ typedef union DAC960_LA_OutboundDoorBellRegister
{
unsigned char All;
struct {
- boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
- boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
+ bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
+ bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Write;
struct {
- boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */
- boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */
+ bool HardwareMailboxStatusAvailable:1; /* Bit 0 */
+ bool MemoryMailboxStatusAvailable:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Read;
}
@@ -3548,7 +3541,7 @@ typedef union DAC960_LA_InterruptMaskRegister
unsigned char All;
struct {
unsigned char :2; /* Bits 0-1 */
- boolean DisableInterrupts:1; /* Bit 2 */
+ bool DisableInterrupts:1; /* Bit 2 */
unsigned char :5; /* Bits 3-7 */
} Bits;
}
@@ -3564,7 +3557,7 @@ typedef union DAC960_LA_ErrorStatusRegister
unsigned char All;
struct {
unsigned int :2; /* Bits 0-1 */
- boolean ErrorStatusPending:1; /* Bit 2 */
+ bool ErrorStatusPending:1; /* Bit 2 */
unsigned int :5; /* Bits 3-7 */
} Bits;
}
@@ -3627,7 +3620,7 @@ void DAC960_LA_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_LA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
+bool DAC960_LA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
{
DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -3636,7 +3629,7 @@ boolean DAC960_LA_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_LA_InitializationInProgressP(void __iomem *ControllerBaseAddress)
+bool DAC960_LA_InitializationInProgressP(void __iomem *ControllerBaseAddress)
{
DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -3676,7 +3669,7 @@ void DAC960_LA_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_LA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_LA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -3685,7 +3678,7 @@ boolean DAC960_LA_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAd
}
static inline
-boolean DAC960_LA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_LA_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -3714,7 +3707,7 @@ void DAC960_LA_DisableInterrupts(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_LA_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
+bool DAC960_LA_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
{
DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
InterruptMaskRegister.All =
@@ -3763,7 +3756,7 @@ DAC960_LA_ReadStatusRegister(void __iomem *ControllerBaseAddress)
return readw(ControllerBaseAddress + DAC960_LA_StatusRegisterOffset);
}
-static inline boolean
+static inline bool
DAC960_LA_ReadErrorStatus(void __iomem *ControllerBaseAddress,
unsigned char *ErrorStatus,
unsigned char *Parameter0,
@@ -3822,16 +3815,16 @@ typedef union DAC960_PG_InboundDoorBellRegister
{
unsigned int All;
struct {
- boolean HardwareMailboxNewCommand:1; /* Bit 0 */
- boolean AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
- boolean GenerateInterrupt:1; /* Bit 2 */
- boolean ControllerReset:1; /* Bit 3 */
- boolean MemoryMailboxNewCommand:1; /* Bit 4 */
+ bool HardwareMailboxNewCommand:1; /* Bit 0 */
+ bool AcknowledgeHardwareMailboxStatus:1; /* Bit 1 */
+ bool GenerateInterrupt:1; /* Bit 2 */
+ bool ControllerReset:1; /* Bit 3 */
+ bool MemoryMailboxNewCommand:1; /* Bit 4 */
unsigned int :27; /* Bits 5-31 */
} Write;
struct {
- boolean HardwareMailboxFull:1; /* Bit 0 */
- boolean InitializationInProgress:1; /* Bit 1 */
+ bool HardwareMailboxFull:1; /* Bit 0 */
+ bool InitializationInProgress:1; /* Bit 1 */
unsigned int :30; /* Bits 2-31 */
} Read;
}
@@ -3846,13 +3839,13 @@ typedef union DAC960_PG_OutboundDoorBellRegister
{
unsigned int All;
struct {
- boolean AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
- boolean AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
+ bool AcknowledgeHardwareMailboxInterrupt:1; /* Bit 0 */
+ bool AcknowledgeMemoryMailboxInterrupt:1; /* Bit 1 */
unsigned int :30; /* Bits 2-31 */
} Write;
struct {
- boolean HardwareMailboxStatusAvailable:1; /* Bit 0 */
- boolean MemoryMailboxStatusAvailable:1; /* Bit 1 */
+ bool HardwareMailboxStatusAvailable:1; /* Bit 0 */
+ bool MemoryMailboxStatusAvailable:1; /* Bit 1 */
unsigned int :30; /* Bits 2-31 */
} Read;
}
@@ -3868,7 +3861,7 @@ typedef union DAC960_PG_InterruptMaskRegister
unsigned int All;
struct {
unsigned int MessageUnitInterruptMask1:2; /* Bits 0-1 */
- boolean DisableInterrupts:1; /* Bit 2 */
+ bool DisableInterrupts:1; /* Bit 2 */
unsigned int MessageUnitInterruptMask2:5; /* Bits 3-7 */
unsigned int Reserved0:24; /* Bits 8-31 */
} Bits;
@@ -3885,7 +3878,7 @@ typedef union DAC960_PG_ErrorStatusRegister
unsigned char All;
struct {
unsigned int :2; /* Bits 0-1 */
- boolean ErrorStatusPending:1; /* Bit 2 */
+ bool ErrorStatusPending:1; /* Bit 2 */
unsigned int :5; /* Bits 3-7 */
} Bits;
}
@@ -3948,7 +3941,7 @@ void DAC960_PG_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_PG_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
+bool DAC960_PG_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
{
DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -3957,7 +3950,7 @@ boolean DAC960_PG_HardwareMailboxFullP(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_PG_InitializationInProgressP(void __iomem *ControllerBaseAddress)
+bool DAC960_PG_InitializationInProgressP(void __iomem *ControllerBaseAddress)
{
DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -3997,7 +3990,7 @@ void DAC960_PG_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_PG_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_PG_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -4006,7 +3999,7 @@ boolean DAC960_PG_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAd
}
static inline
-boolean DAC960_PG_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_PG_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -4039,7 +4032,7 @@ void DAC960_PG_DisableInterrupts(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_PG_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
+bool DAC960_PG_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
{
DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
InterruptMaskRegister.All =
@@ -4088,7 +4081,7 @@ DAC960_PG_ReadStatusRegister(void __iomem *ControllerBaseAddress)
return readw(ControllerBaseAddress + DAC960_PG_StatusRegisterOffset);
}
-static inline boolean
+static inline bool
DAC960_PG_ReadErrorStatus(void __iomem *ControllerBaseAddress,
unsigned char *ErrorStatus,
unsigned char *Parameter0,
@@ -4147,15 +4140,15 @@ typedef union DAC960_PD_InboundDoorBellRegister
{
unsigned char All;
struct {
- boolean NewCommand:1; /* Bit 0 */
- boolean AcknowledgeStatus:1; /* Bit 1 */
- boolean GenerateInterrupt:1; /* Bit 2 */
- boolean ControllerReset:1; /* Bit 3 */
+ bool NewCommand:1; /* Bit 0 */
+ bool AcknowledgeStatus:1; /* Bit 1 */
+ bool GenerateInterrupt:1; /* Bit 2 */
+ bool ControllerReset:1; /* Bit 3 */
unsigned char :4; /* Bits 4-7 */
} Write;
struct {
- boolean MailboxFull:1; /* Bit 0 */
- boolean InitializationInProgress:1; /* Bit 1 */
+ bool MailboxFull:1; /* Bit 0 */
+ bool InitializationInProgress:1; /* Bit 1 */
unsigned char :6; /* Bits 2-7 */
} Read;
}
@@ -4170,11 +4163,11 @@ typedef union DAC960_PD_OutboundDoorBellRegister
{
unsigned char All;
struct {
- boolean AcknowledgeInterrupt:1; /* Bit 0 */
+ bool AcknowledgeInterrupt:1; /* Bit 0 */
unsigned char :7; /* Bits 1-7 */
} Write;
struct {
- boolean StatusAvailable:1; /* Bit 0 */
+ bool StatusAvailable:1; /* Bit 0 */
unsigned char :7; /* Bits 1-7 */
} Read;
}
@@ -4189,7 +4182,7 @@ typedef union DAC960_PD_InterruptEnableRegister
{
unsigned char All;
struct {
- boolean EnableInterrupts:1; /* Bit 0 */
+ bool EnableInterrupts:1; /* Bit 0 */
unsigned char :7; /* Bits 1-7 */
} Bits;
}
@@ -4205,7 +4198,7 @@ typedef union DAC960_PD_ErrorStatusRegister
unsigned char All;
struct {
unsigned int :2; /* Bits 0-1 */
- boolean ErrorStatusPending:1; /* Bit 2 */
+ bool ErrorStatusPending:1; /* Bit 2 */
unsigned int :5; /* Bits 3-7 */
} Bits;
}
@@ -4258,7 +4251,7 @@ void DAC960_PD_ControllerReset(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_PD_MailboxFullP(void __iomem *ControllerBaseAddress)
+bool DAC960_PD_MailboxFullP(void __iomem *ControllerBaseAddress)
{
DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -4267,7 +4260,7 @@ boolean DAC960_PD_MailboxFullP(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_PD_InitializationInProgressP(void __iomem *ControllerBaseAddress)
+bool DAC960_PD_InitializationInProgressP(void __iomem *ControllerBaseAddress)
{
DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
InboundDoorBellRegister.All =
@@ -4286,7 +4279,7 @@ void DAC960_PD_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_PD_StatusAvailableP(void __iomem *ControllerBaseAddress)
+bool DAC960_PD_StatusAvailableP(void __iomem *ControllerBaseAddress)
{
DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister;
OutboundDoorBellRegister.All =
@@ -4315,7 +4308,7 @@ void DAC960_PD_DisableInterrupts(void __iomem *ControllerBaseAddress)
}
static inline
-boolean DAC960_PD_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
+bool DAC960_PD_InterruptsEnabledP(void __iomem *ControllerBaseAddress)
{
DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
InterruptEnableRegister.All =
@@ -4350,7 +4343,7 @@ DAC960_PD_ReadStatusRegister(void __iomem *ControllerBaseAddress)
return readw(ControllerBaseAddress + DAC960_PD_StatusRegisterOffset);
}
-static inline boolean
+static inline bool
DAC960_PD_ReadErrorStatus(void __iomem *ControllerBaseAddress,
unsigned char *ErrorStatus,
unsigned char *Parameter0,
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 58c1debf86f1..cacb1c816e35 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -417,8 +417,10 @@ config BLK_DEV_INITRD
etc. See <file:Documentation/initrd.txt> for details.
If RAM disk support (BLK_DEV_RAM) is also included, this
- also enables initial RAM disk (initrd) support.
+ also enables initial RAM disk (initrd) support and adds
+ 15 Kbytes (more on some other architectures) to the kernel size.
+ If unsure say Y.
config CDROM_PKTCDVD
tristate "Packet writing on CD/DVD media"
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index e04be94d195c..e2e043290963 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -269,7 +269,7 @@ static int slm_get_pagesize( int device, int *w, int *h );
static DEFINE_TIMER(slm_timer, slm_test_ready, 0, 0);
-static struct file_operations slm_fops = {
+static const struct file_operations slm_fops = {
.owner = THIS_MODULE,
.read = slm_read,
.write = slm_write,
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index e22b4c9520a9..39e563ea0878 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -233,7 +233,7 @@ loop:
}
}
-static struct file_operations aoe_fops = {
+static const struct file_operations aoe_fops = {
.write = aoechr_write,
.read = aoechr_read,
.open = aoechr_open,
diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
index c0d2854dd097..28cf3082d442 100644
--- a/drivers/block/paride/Kconfig
+++ b/drivers/block/paride/Kconfig
@@ -2,14 +2,8 @@
# PARIDE configuration
#
# PARIDE doesn't need PARPORT, but if PARPORT is configured as a module,
-# PARIDE must also be a module. The bogus CONFIG_PARIDE_PARPORT option
-# controls the choices given to the user ...
+# PARIDE must also be a module.
# PARIDE only supports PC style parports. Tough for USB or other parports...
-config PARIDE_PARPORT
- tristate
- depends on PARIDE!=n
- default m if PARPORT_PC=m
- default y if PARPORT_PC!=m
comment "Parallel IDE high-level drivers"
depends on PARIDE
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index 9970aedbb5d9..d89e7d32a3b6 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -227,7 +227,7 @@ static struct class *pg_class;
/* kernel glue structures */
-static struct file_operations pg_fops = {
+static const struct file_operations pg_fops = {
.owner = THIS_MODULE,
.read = pg_read,
.write = pg_write,
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index c902b25e4869..9f4e67ee1eb0 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -232,7 +232,7 @@ static char pt_scratch[512]; /* scratch block buffer */
/* kernel glue structures */
-static struct file_operations pt_fops = {
+static const struct file_operations pt_fops = {
.owner = THIS_MODULE,
.read = pt_read,
.write = pt_write,
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 62462190e07e..93fb6ed4ed52 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -190,15 +190,6 @@ static struct attribute *kobj_pkt_attrs_wqueue[] = {
NULL
};
-/* declares a char buffer[64] _dbuf, copies data from
- * _b with length _l into it and ensures that _dbuf ends
- * with a \0 character.
- */
-#define DECLARE_BUF_AS_STRING(_dbuf, _b, _l) \
- char _dbuf[64]; int dlen = (_l) < 0 ? 0 : (_l); \
- if (dlen >= sizeof(_dbuf)) dlen = sizeof(_dbuf)-1; \
- memcpy(_dbuf, _b, dlen); _dbuf[dlen] = 0
-
static ssize_t kobj_pkt_show(struct kobject *kobj,
struct attribute *attr, char *data)
{
@@ -264,9 +255,8 @@ static ssize_t kobj_pkt_store(struct kobject *kobj,
{
struct pktcdvd_device *pd = to_pktcdvdkobj(kobj)->pd;
int val;
- DECLARE_BUF_AS_STRING(dbuf, data, len); /* ensure sscanf scans a string */
- if (strcmp(attr->name, "reset") == 0 && dlen > 0) {
+ if (strcmp(attr->name, "reset") == 0 && len > 0) {
pd->stats.pkt_started = 0;
pd->stats.pkt_ended = 0;
pd->stats.secs_w = 0;
@@ -274,7 +264,7 @@ static ssize_t kobj_pkt_store(struct kobject *kobj,
pd->stats.secs_r = 0;
} else if (strcmp(attr->name, "congestion_off") == 0
- && sscanf(dbuf, "%d", &val) == 1) {
+ && sscanf(data, "%d", &val) == 1) {
spin_lock(&pd->lock);
pd->write_congestion_off = val;
init_write_congestion_marks(&pd->write_congestion_off,
@@ -282,7 +272,7 @@ static ssize_t kobj_pkt_store(struct kobject *kobj,
spin_unlock(&pd->lock);
} else if (strcmp(attr->name, "congestion_on") == 0
- && sscanf(dbuf, "%d", &val) == 1) {
+ && sscanf(data, "%d", &val) == 1) {
spin_lock(&pd->lock);
pd->write_congestion_on = val;
init_write_congestion_marks(&pd->write_congestion_off,
@@ -369,8 +359,7 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
size_t count)
{
unsigned int major, minor;
- DECLARE_BUF_AS_STRING(dbuf, buf, count);
- if (sscanf(dbuf, "%u:%u", &major, &minor) == 2) {
+ if (sscanf(buf, "%u:%u", &major, &minor) == 2) {
pkt_setup_dev(MKDEV(major, minor), NULL);
return count;
}
@@ -381,8 +370,7 @@ static ssize_t class_pktcdvd_store_remove(struct class *c, const char *buf,
size_t count)
{
unsigned int major, minor;
- DECLARE_BUF_AS_STRING(dbuf, buf, count);
- if (sscanf(dbuf, "%u:%u", &major, &minor) == 2) {
+ if (sscanf(buf, "%u:%u", &major, &minor) == 2) {
pkt_remove_dev(MKDEV(major, minor));
return count;
}
@@ -447,7 +435,7 @@ static int pkt_debugfs_fops_open(struct inode *inode, struct file *file)
return single_open(file, pkt_debugfs_seq_show, inode->i_private);
}
-static struct file_operations debug_fops = {
+static const struct file_operations debug_fops = {
.open = pkt_debugfs_fops_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -1377,7 +1365,7 @@ try_next_bio:
&& pd->bio_queue_size <= pd->write_congestion_off);
spin_unlock(&pd->lock);
if (wakeup)
- blk_clear_queue_congested(pd->disk->queue, WRITE);
+ clear_bdi_congested(&pd->disk->queue->backing_dev_info, WRITE);
pkt->sleep_time = max(PACKET_WAIT_TIME, 1);
pkt_set_state(pkt, PACKET_WAITING_STATE);
@@ -2598,7 +2586,7 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
spin_lock(&pd->lock);
if (pd->write_congestion_on > 0
&& pd->bio_queue_size >= pd->write_congestion_on) {
- blk_set_queue_congested(q, WRITE);
+ set_bdi_congested(&q->backing_dev_info, WRITE);
do {
spin_unlock(&pd->lock);
congestion_wait(WRITE, HZ);
@@ -2737,7 +2725,7 @@ static int pkt_seq_open(struct inode *inode, struct file *file)
return single_open(file, pkt_seq_show, PDE(inode)->data);
}
-static struct file_operations pkt_proc_fops = {
+static const struct file_operations pkt_proc_fops = {
.open = pkt_seq_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -3064,7 +3052,7 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
}
-static struct file_operations pkt_ctl_fops = {
+static const struct file_operations pkt_ctl_fops = {
.ioctl = pkt_ctl_ioctl,
.owner = THIS_MODULE,
};
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index a278d98a9151..b71a5ccc587f 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -332,7 +332,7 @@ static int vhci_fasync(int fd, struct file *file, int on)
return 0;
}
-static struct file_operations vhci_fops = {
+static const struct file_operations vhci_fops = {
.owner = THIS_MODULE,
.llseek = vhci_llseek,
.read = vhci_read,
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index 93fbf84dcc4a..dc13ebacedfb 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -176,7 +176,7 @@ static int proc_viocd_open(struct inode *inode, struct file *file)
return single_open(file, proc_viocd_show, NULL);
}
-static struct file_operations proc_viocd_operations = {
+static const struct file_operations proc_viocd_operations = {
.open = proc_viocd_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index d08bb4ee1307..d0a6dc53213c 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -191,7 +191,7 @@ config MOXA_INTELLIO
module will be called moxa.
config MOXA_SMARTIO
- tristate "Moxa SmartIO support"
+ tristate "Moxa SmartIO support (OBSOLETE)"
depends on SERIAL_NONSTANDARD
help
Say Y here if you have a Moxa SmartIO multiport serial card.
@@ -202,7 +202,7 @@ config MOXA_SMARTIO
here.
config MOXA_SMARTIO_NEW
- tristate "Moxa SmartIO support v. 2.0 (EXPERIMENTAL)"
+ tristate "Moxa SmartIO support v. 2.0"
depends on SERIAL_NONSTANDARD && (PCI || EISA || ISA)
help
Say Y here if you have a Moxa SmartIO multiport serial card and/or
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index feb4ac802a0d..0e2b72f2b887 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -527,10 +527,8 @@ static void do_softint(unsigned long private_)
if (!tty)
return;
- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event))
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
- }
}
/*
@@ -904,8 +902,7 @@ static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count
if (!info->xmit.buf)
return 0;
- local_save_flags(flags);
- local_irq_disable();
+ local_irq_save(flags);
while (1) {
c = CIRC_SPACE_TO_END(info->xmit.head,
info->xmit.tail,
@@ -968,7 +965,6 @@ static void rs_flush_buffer(struct tty_struct *tty)
local_irq_save(flags);
info->xmit.head = info->xmit.tail = 0;
local_irq_restore(flags);
- wake_up_interruptible(&tty->write_wait);
tty_wakeup(tty);
}
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index 9f8082f8dd29..7f60a18ef76b 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -187,7 +187,7 @@ static ssize_t briq_panel_write(struct file *file, const char __user *buf, size_
return len;
}
-static struct file_operations briq_panel_fops = {
+static const struct file_operations briq_panel_fops = {
.owner = THIS_MODULE,
.read = briq_panel_read,
.write = briq_panel_write,
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 3ffa0807754c..54df35527bc5 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -829,17 +829,18 @@ static unsigned short cy_pci_nboard;
static unsigned short cy_isa_nboard;
static unsigned short cy_nboard;
#ifdef CONFIG_PCI
-static unsigned short cy_pci_dev_id[] = {
- PCI_DEVICE_ID_CYCLOM_Y_Lo, /* PCI < 1Mb */
- PCI_DEVICE_ID_CYCLOM_Y_Hi, /* PCI > 1Mb */
- PCI_DEVICE_ID_CYCLOM_4Y_Lo, /* 4Y PCI < 1Mb */
- PCI_DEVICE_ID_CYCLOM_4Y_Hi, /* 4Y PCI > 1Mb */
- PCI_DEVICE_ID_CYCLOM_8Y_Lo, /* 8Y PCI < 1Mb */
- PCI_DEVICE_ID_CYCLOM_8Y_Hi, /* 8Y PCI > 1Mb */
- PCI_DEVICE_ID_CYCLOM_Z_Lo, /* Z PCI < 1Mb */
- PCI_DEVICE_ID_CYCLOM_Z_Hi, /* Z PCI > 1Mb */
- 0 /* end of table */
+static struct pci_device_id cy_pci_dev_id[] __devinitdata = {
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Hi) }, /* PCI > 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Lo) }, /* 4Y PCI < 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_4Y_Hi) }, /* 4Y PCI > 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Lo) }, /* 8Y PCI < 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_8Y_Hi) }, /* 8Y PCI > 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Lo) }, /* Z PCI < 1Mb */
+ { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Z_Hi) }, /* Z PCI > 1Mb */
+ { } /* end of table */
};
+MODULE_DEVICE_TABLE(pci, cy_pci_dev_id);
#endif
static void cy_start(struct tty_struct *);
@@ -4488,7 +4489,6 @@ static void cy_flush_buffer(struct tty_struct *tty)
CY_UNLOCK(info, flags);
}
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
} /* cy_flush_buffer */
/*
@@ -4759,7 +4759,7 @@ static int __init cy_detect_pci(void)
for (i = 0; i < NR_CARDS; i++) {
/* look for a Cyclades card by vendor and device id */
- while ((device_id = cy_pci_dev_id[dev_index]) != 0) {
+ while ((device_id = cy_pci_dev_id[dev_index].device) != 0) {
if ((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES,
device_id, pdev)) == NULL) {
dev_index++; /* try next device id */
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index a70af0de4453..f5b9b2480c14 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -371,7 +371,7 @@ void drm_exit(struct drm_driver *driver)
EXPORT_SYMBOL(drm_exit);
/** File operations structure */
-static struct file_operations drm_stub_fops = {
+static const struct file_operations drm_stub_fops = {
.owner = THIS_MODULE,
.open = drm_stub_open
};
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index 60cb4e45a75e..603d17fd2d69 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -112,7 +112,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
return 0;
}
-static struct file_operations i810_buffer_fops = {
+static const struct file_operations i810_buffer_fops = {
.open = drm_open,
.release = drm_release,
.ioctl = drm_ioctl,
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 95224455ec0c..3314a9fea9e5 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -114,7 +114,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
return 0;
}
-static struct file_operations i830_buffer_fops = {
+static const struct file_operations i830_buffer_fops = {
.open = drm_open,
.release = drm_release,
.ioctl = drm_ioctl,
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
index 2054d5773717..2881a06b6f55 100644
--- a/drivers/char/drm/via_dmablit.c
+++ b/drivers/char/drm/via_dmablit.c
@@ -376,10 +376,8 @@ via_dmablit_handler(drm_device_t *dev, int engine, int from_irq)
blitq->cur = cur;
blitq->num_outstanding--;
blitq->end = jiffies + DRM_HZ;
- if (!timer_pending(&blitq->poll_timer)) {
- blitq->poll_timer.expires = jiffies+1;
- add_timer(&blitq->poll_timer);
- }
+ if (!timer_pending(&blitq->poll_timer))
+ mod_timer(&blitq->poll_timer, jiffies + 1);
} else {
if (timer_pending(&blitq->poll_timer)) {
del_timer(&blitq->poll_timer);
@@ -478,8 +476,7 @@ via_dmablit_timer(unsigned long data)
via_dmablit_handler(dev, engine, 0);
if (!timer_pending(&blitq->poll_timer)) {
- blitq->poll_timer.expires = jiffies+1;
- add_timer(&blitq->poll_timer);
+ mod_timer(&blitq->poll_timer, jiffies + 1);
/*
* Rerun handler to delete timer if engines are off, and
@@ -574,9 +571,8 @@ via_init_dmablit(drm_device_t *dev)
}
DRM_INIT_WAITQUEUE(&blitq->busy_queue);
INIT_WORK(&blitq->wq, via_dmablit_workqueue);
- init_timer(&blitq->poll_timer);
- blitq->poll_timer.function = &via_dmablit_timer;
- blitq->poll_timer.data = (unsigned long) blitq;
+ setup_timer(&blitq->poll_timer, via_dmablit_timer,
+ (unsigned long)blitq);
}
}
diff --git a/drivers/char/ds1302.c b/drivers/char/ds1302.c
index bcdb107aa967..fada6ddefbae 100644
--- a/drivers/char/ds1302.c
+++ b/drivers/char/ds1302.c
@@ -120,7 +120,6 @@ get_rtc_time(struct rtc_time *rtc_tm)
unsigned long flags;
local_irq_save(flags);
- local_irq_disable();
rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
@@ -219,7 +218,6 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
BIN_TO_BCD(yrs);
local_irq_save(flags);
- local_irq_disable();
CMOS_WRITE(yrs, RTC_YEAR);
CMOS_WRITE(mon, RTC_MONTH);
CMOS_WRITE(day, RTC_DAY_OF_MONTH);
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index d4005e94fe5f..d8dbdb916232 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -72,6 +72,7 @@
#define TRACE_RET ((void) 0)
#endif /* TRACING */
+static void dtlk_timer_tick(unsigned long data);
static int dtlk_major;
static int dtlk_port_lpc;
@@ -81,7 +82,7 @@ static int dtlk_has_indexing;
static unsigned int dtlk_portlist[] =
{0x25e, 0x29e, 0x2de, 0x31e, 0x35e, 0x39e, 0};
static wait_queue_head_t dtlk_process_list;
-static struct timer_list dtlk_timer;
+static DEFINE_TIMER(dtlk_timer, dtlk_timer_tick, 0, 0);
/* prototypes for file_operations struct */
static ssize_t dtlk_read(struct file *, char __user *,
@@ -117,7 +118,6 @@ static char dtlk_write_tts(char);
/*
static void dtlk_handle_error(char, char, unsigned int);
*/
-static void dtlk_timer_tick(unsigned long data);
static ssize_t dtlk_read(struct file *file, char __user *buf,
size_t count, loff_t * ppos)
@@ -318,7 +318,7 @@ static int dtlk_release(struct inode *inode, struct file *file)
}
TRACE_RET;
- del_timer(&dtlk_timer);
+ del_timer_sync(&dtlk_timer);
return 0;
}
@@ -336,8 +336,6 @@ static int __init dtlk_init(void)
if (dtlk_dev_probe() == 0)
printk(", MAJOR %d\n", dtlk_major);
- init_timer(&dtlk_timer);
- dtlk_timer.function = dtlk_timer_tick;
init_waitqueue_head(&dtlk_process_list);
return 0;
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index a0f822c9d74d..88fc24fc4392 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -844,7 +844,6 @@ static void pc_flush_buffer(struct tty_struct *tty)
fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0);
memoff(ch);
spin_unlock_irqrestore(&epca_lock, flags);
- wake_up_interruptible(&tty->write_wait);
tty_wakeup(tty);
} /* End pc_flush_buffer */
@@ -1795,7 +1794,6 @@ static void doevent(int crd)
{ /* Begin if LOWWAIT */
ch->statusflags &= ~LOWWAIT;
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
} /* End if LOWWAIT */
} else if (event & EMPTYTX_IND) { /* Begin EMPTYTX_IND */
/* This event is generated by setup_empty_event */
@@ -1803,7 +1801,6 @@ static void doevent(int crd)
if (ch->statusflags & EMPTYWAIT) { /* Begin if EMPTYWAIT */
ch->statusflags &= ~EMPTYWAIT;
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
} /* End if EMPTYWAIT */
} /* End EMPTYTX_IND */
} /* End if valid tty */
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
index 43ff59816511..2398e864c28d 100644
--- a/drivers/char/generic_nvram.c
+++ b/drivers/char/generic_nvram.c
@@ -117,7 +117,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file,
return 0;
}
-struct file_operations nvram_fops = {
+const struct file_operations nvram_fops = {
.owner = THIS_MODULE,
.llseek = nvram_llseek,
.read = read_nvram,
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index e769811e7417..337bbcdcf13d 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -382,7 +382,6 @@ void gs_flush_buffer(struct tty_struct *tty)
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
spin_unlock_irqrestore (&port->driver_lock, flags);
- wake_up_interruptible(&tty->write_wait);
tty_wakeup(tty);
func_exit ();
}
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index f22e78e3c70f..cc1046e6ee02 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -96,49 +96,49 @@
*/
static const struct pci_device_id pci_tbl[] = {
/* AA
- { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
- { 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AA */
+ { PCI_DEVICE(0x8086, 0x2418) }, */
+ { PCI_DEVICE(0x8086, 0x2410) }, /* AA */
/* AB
- { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
- { 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AB */
+ { PCI_DEVICE(0x8086, 0x2428) }, */
+ { PCI_DEVICE(0x8086, 0x2420) }, /* AB */
/* ??
- { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { PCI_DEVICE(0x8086, 0x2430) }, */
/* BAM, CAM, DBM, FBM, GxM
- { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
- { 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BAM */
- { 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CAM */
- { 0x8086, 0x24cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DBM */
- { 0x8086, 0x2641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* FBM */
- { 0x8086, 0x27b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM */
- { 0x8086, 0x27bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM DH */
+ { PCI_DEVICE(0x8086, 0x2448) }, */
+ { PCI_DEVICE(0x8086, 0x244c) }, /* BAM */
+ { PCI_DEVICE(0x8086, 0x248c) }, /* CAM */
+ { PCI_DEVICE(0x8086, 0x24cc) }, /* DBM */
+ { PCI_DEVICE(0x8086, 0x2641) }, /* FBM */
+ { PCI_DEVICE(0x8086, 0x27b9) }, /* GxM */
+ { PCI_DEVICE(0x8086, 0x27bd) }, /* GxM DH */
/* BA, CA, DB, Ex, 6300, Fx, 631x/632x, Gx
- { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
- { 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BA */
- { 0x8086, 0x2480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CA */
- { 0x8086, 0x24c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DB */
- { 0x8086, 0x24d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ex */
- { 0x8086, 0x25a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 6300 */
- { 0x8086, 0x2640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Fx */
- { 0x8086, 0x2670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
- { 0x8086, 0x27b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Gx */
+ { PCI_DEVICE(0x8086, 0x244e) }, */
+ { PCI_DEVICE(0x8086, 0x2440) }, /* BA */
+ { PCI_DEVICE(0x8086, 0x2480) }, /* CA */
+ { PCI_DEVICE(0x8086, 0x24c0) }, /* DB */
+ { PCI_DEVICE(0x8086, 0x24d0) }, /* Ex */
+ { PCI_DEVICE(0x8086, 0x25a1) }, /* 6300 */
+ { PCI_DEVICE(0x8086, 0x2640) }, /* Fx */
+ { PCI_DEVICE(0x8086, 0x2670) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x2671) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x2672) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x2673) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x2674) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x2675) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x2676) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x2677) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x2678) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x2679) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x267a) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x267b) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x267c) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x267d) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x267e) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x267f) }, /* 631x/632x */
+ { PCI_DEVICE(0x8086, 0x27b8) }, /* Gx */
/* E
- { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
- { 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E */
+ { PCI_DEVICE(0x8086, 0x245e) }, */
+ { PCI_DEVICE(0x8086, 0x2450) }, /* E */
{ 0, }, /* terminate list */
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index 78045767ec33..f86fa0c55d36 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -80,7 +80,7 @@ static int i2RetryFlushOutput(i2ChanStrPtr);
// Not a documented part of the library routines (careful...) but the Diagnostic
// i2diag.c finds them useful to help the throughput in certain limited
// single-threaded operations.
-static void iiSendPendingMail(i2eBordStrPtr);
+static inline void iiSendPendingMail(i2eBordStrPtr);
static void serviceOutgoingFifo(i2eBordStrPtr);
// Functions defined in ip2.c as part of interrupt handling
@@ -150,6 +150,13 @@ i2Validate ( i2ChanStrPtr pCh )
== (CHANNEL_MAGIC | CHANNEL_SUPPORT));
}
+static void iiSendPendingMail_t(unsigned long data)
+{
+ i2eBordStrPtr pB = (i2eBordStrPtr)data;
+
+ iiSendPendingMail(pB);
+}
+
//******************************************************************************
// Function: iiSendPendingMail(pB)
// Parameters: Pointer to a board structure
@@ -184,12 +191,9 @@ iiSendPendingMail(i2eBordStrPtr pB)
/\/\|=mhw=|\/\/ */
if( ++pB->SendPendingRetry < 16 ) {
-
- init_timer( &(pB->SendPendingTimer) );
- pB->SendPendingTimer.expires = jiffies + 1;
- pB->SendPendingTimer.function = (void*)(unsigned long)iiSendPendingMail;
- pB->SendPendingTimer.data = (unsigned long)pB;
- add_timer( &(pB->SendPendingTimer) );
+ setup_timer(&pB->SendPendingTimer,
+ iiSendPendingMail_t, (unsigned long)pB);
+ mod_timer(&pB->SendPendingTimer, jiffies + 1);
} else {
printk( KERN_ERR "IP2: iiSendPendingMail unable to queue outbound mail\n" );
}
@@ -1265,8 +1269,10 @@ i2RetryFlushOutput(i2ChanStrPtr pCh)
// soon as all the data is completely sent.
//******************************************************************************
static void
-i2DrainWakeup(i2ChanStrPtr pCh)
+i2DrainWakeup(unsigned long d)
{
+ i2ChanStrPtr pCh = (i2ChanStrPtr)d;
+
ip2trace (CHANN, ITRC_DRAIN, 10, 1, pCh->BookmarkTimer.expires );
pCh->BookmarkTimer.expires = 0;
@@ -1292,14 +1298,12 @@ i2DrainOutput(i2ChanStrPtr pCh, int timeout)
}
if ((timeout > 0) && (pCh->BookmarkTimer.expires == 0 )) {
// One per customer (channel)
- init_timer( &(pCh->BookmarkTimer) );
- pCh->BookmarkTimer.expires = jiffies + timeout;
- pCh->BookmarkTimer.function = (void*)(unsigned long)i2DrainWakeup;
- pCh->BookmarkTimer.data = (unsigned long)pCh;
+ setup_timer(&pCh->BookmarkTimer, i2DrainWakeup,
+ (unsigned long)pCh);
ip2trace (CHANN, ITRC_DRAIN, 1, 1, pCh->BookmarkTimer.expires );
- add_timer( &(pCh->BookmarkTimer) );
+ mod_timer(&pCh->BookmarkTimer, jiffies + timeout);
}
i2QueueCommands( PTYPE_INLINE, pCh, -1, 1, CMD_BMARK_REQ );
@@ -1373,15 +1377,7 @@ ip2_owake( PTTY tp)
ip2trace (CHANN, ITRC_SICMD, 10, 2, tp->flags,
(1 << TTY_DO_WRITE_WAKEUP) );
- wake_up_interruptible ( &tp->write_wait );
- if ( ( tp->flags & (1 << TTY_DO_WRITE_WAKEUP) )
- && tp->ldisc.write_wakeup )
- {
- (tp->ldisc.write_wakeup) ( tp );
-
- ip2trace (CHANN, ITRC_SICMD, 11, 0 );
-
- }
+ tty_wakeup(tp);
}
static inline void
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 7c70310a49b5..83c7258d3580 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -1271,8 +1271,8 @@ static void do_input(struct work_struct *work)
// code duplicated from n_tty (ldisc)
static inline void isig(int sig, struct tty_struct *tty, int flush)
{
- if (tty->pgrp > 0)
- kill_pg(tty->pgrp, sig, 1);
+ if (tty->pgrp)
+ kill_pgrp(tty->pgrp, sig, 1);
if (flush || !L_NOFLSH(tty)) {
if ( tty->ldisc.flush_buffer )
tty->ldisc.flush_buffer(tty);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 53582b53da95..3aff5e99b674 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -406,13 +406,14 @@ static void clean_up_interface_data(ipmi_smi_t intf)
free_smi_msg_list(&intf->waiting_msgs);
free_recv_msg_list(&intf->waiting_events);
- /* Wholesale remove all the entries from the list in the
- * interface and wait for RCU to know that none are in use. */
+ /*
+ * Wholesale remove all the entries from the list in the
+ * interface and wait for RCU to know that none are in use.
+ */
mutex_lock(&intf->cmd_rcvrs_mutex);
- list_add_rcu(&list, &intf->cmd_rcvrs);
- list_del_rcu(&intf->cmd_rcvrs);
+ INIT_LIST_HEAD(&list);
+ list_splice_init_rcu(&intf->cmd_rcvrs, &list, synchronize_rcu);
mutex_unlock(&intf->cmd_rcvrs_mutex);
- synchronize_rcu();
list_for_each_entry_safe(rcvr, rcvr2, &list, link)
kfree(rcvr);
@@ -451,7 +452,7 @@ int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
mutex_lock(&ipmi_interfaces_mutex);
/* Build a list of things to deliver. */
- list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+ list_for_each_entry(intf, &ipmi_interfaces, link) {
if (intf->intf_num == -1)
continue;
e = kmalloc(sizeof(*e), GFP_KERNEL);
@@ -1886,7 +1887,6 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
kfree(entry);
rv = -ENOMEM;
} else {
- file->nlink = 1;
file->data = data;
file->read_proc = read_proc;
file->write_proc = write_proc;
@@ -2760,9 +2760,15 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
synchronize_rcu();
kref_put(&intf->refcount, intf_free);
} else {
- /* After this point the interface is legal to use. */
+ /*
+ * Keep memory order straight for RCU readers. Make
+ * sure everything else is committed to memory before
+ * setting intf_num to mark the interface valid.
+ */
+ smp_wmb();
intf->intf_num = i;
mutex_unlock(&ipmi_interfaces_mutex);
+ /* After this point the interface is legal to use. */
call_smi_watchers(i, intf->si_dev);
mutex_unlock(&smi_watchers_mutex);
}
@@ -3923,6 +3929,14 @@ static void send_panic_events(char *str)
/* Interface was not ready yet. */
continue;
+ /*
+ * intf_num is used as an marker to tell if the
+ * interface is valid. Thus we need a read barrier to
+ * make sure data fetched before checking intf_num
+ * won't be used.
+ */
+ smp_rmb();
+
/* First job here is to figure out where to send the
OEM events. There's no way in IPMI to send OEM
events using an event send command, so we have to
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 01084abffddf..43ab9edc76f5 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -183,7 +183,7 @@ static DEFINE_TIMER(tx, isicom_tx, 0, 0);
/* baud index mappings from linux defns to isi */
static signed char linuxb_to_isib[] = {
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21
};
struct isi_board {
@@ -213,8 +213,6 @@ struct isi_port {
struct tty_struct * tty;
wait_queue_head_t close_wait;
wait_queue_head_t open_wait;
- struct work_struct hangup_tq;
- struct work_struct bh_tqueue;
unsigned char * xmit_buf;
int xmit_head;
int xmit_tail;
@@ -510,7 +508,7 @@ static void isicom_tx(unsigned long _data)
if (port->xmit_cnt <= 0)
port->status &= ~ISI_TXOK;
if (port->xmit_cnt <= WAKEUP_CHARS)
- schedule_work(&port->bh_tqueue);
+ tty_wakeup(tty);
unlock_card(&isi_card[card]);
}
@@ -524,21 +522,6 @@ sched_again:
mod_timer(&tx, jiffies + msecs_to_jiffies(10));
}
-/* Interrupt handlers */
-
-
-static void isicom_bottomhalf(struct work_struct *work)
-{
- struct isi_port *port = container_of(work, struct isi_port, bh_tqueue);
- struct tty_struct *tty = port->tty;
-
- if (!tty)
- return;
-
- tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
-}
-
/*
* Main interrupt handler routine
*/
@@ -557,6 +540,11 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
return IRQ_NONE;
base = card->base;
+
+ /* did the card interrupt us? */
+ if (!(inw(base + 0x0e) & 0x02))
+ return IRQ_NONE;
+
spin_lock(&card->card_lock);
/*
@@ -581,6 +569,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
port = card->ports + channel;
if (!(port->flags & ASYNC_INITIALIZED)) {
outw(0x0000, base+0x04); /* enable interrupts */
+ spin_unlock(&card->card_lock);
return IRQ_HANDLED;
}
@@ -609,7 +598,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
pr_dbg("interrupt: DCD->low.\n"
);
port->status &= ~ISI_DCD;
- schedule_work(&port->hangup_tq);
+ tty_hangup(tty);
}
} else if (header & ISI_DCD) {
/* Carrier has been detected */
@@ -631,7 +620,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
/* start tx ing */
port->status |= (ISI_TXOK
| ISI_CTS);
- schedule_work(&port->bh_tqueue);
+ tty_wakeup(tty);
}
} else if (!(header & ISI_CTS)) {
port->tty->hw_stopped = 1;
@@ -695,6 +684,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
tty_flip_buffer_push(tty);
}
outw(0x0000, base+0x04); /* enable interrupts */
+ spin_unlock(&card->card_lock);
return IRQ_HANDLED;
}
@@ -720,7 +710,8 @@ static void isicom_config_port(struct isi_port *port)
* respectively.
*/
- if (baud < 1 || baud > 2)
+ /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
+ if (baud < 1 || baud > 4)
port->tty->termios->c_cflag &= ~CBAUDEX;
else
baud += 15;
@@ -736,6 +727,10 @@ static void isicom_config_port(struct isi_port *port)
baud++; /* 57.6 Kbps */
if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
baud +=2; /* 115 Kbps */
+ if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+ baud += 3; /* 230 kbps*/
+ if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+ baud += 4; /* 460 kbps*/
}
if (linuxb_to_isib[baud] == -1) {
/* hang up */
@@ -1460,17 +1455,6 @@ static void isicom_start(struct tty_struct *tty)
port->status |= ISI_TXOK;
}
-/* hangup et all */
-static void do_isicom_hangup(struct work_struct *work)
-{
- struct isi_port *port = container_of(work, struct isi_port, hangup_tq);
- struct tty_struct *tty;
-
- tty = port->tty;
- if (tty)
- tty_hangup(tty);
-}
-
static void isicom_hangup(struct tty_struct *tty)
{
struct isi_port *port = tty->driver_data;
@@ -1503,7 +1487,6 @@ static void isicom_flush_buffer(struct tty_struct *tty)
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
spin_unlock_irqrestore(&card->card_lock, flags);
- wake_up_interruptible(&tty->write_wait);
tty_wakeup(tty);
}
@@ -1536,7 +1519,7 @@ static int __devinit reset_card(struct pci_dev *pdev,
{
struct isi_board *board = pci_get_drvdata(pdev);
unsigned long base = board->base;
- unsigned int portcount = 0;
+ unsigned int sig, portcount = 0;
int retval = 0;
dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx\n", card + 1,
@@ -1544,27 +1527,35 @@ static int __devinit reset_card(struct pci_dev *pdev,
inw(base + 0x8);
- mdelay(10);
+ msleep(10);
outw(0, base + 0x8); /* Reset */
- msleep(3000);
+ msleep(1000);
- *signature = inw(base + 0x4) & 0xff;
+ sig = inw(base + 0x4) & 0xff;
+
+ if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
+ sig != 0xee) {
+ dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
+ "bad I/O Port Address 0x%lx).\n", card + 1, base);
+ dev_dbg(&pdev->dev, "Sig=0x%x\n", sig);
+ retval = -EIO;
+ goto end;
+ }
+
+ msleep(10);
portcount = inw(base + 0x2);
- if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) &&
- (portcount != 4) && (portcount != 8))) {
- dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n",
- inw(base + 0x2), inw(base + 0xe));
- dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure "
- "(Possible bad I/O Port Address 0x%lx).\n",
- card + 1, base);
+ if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 &&
+ portcount != 8 && portcount != 16)) {
+ dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.",
+ card + 1);
retval = -EIO;
goto end;
}
- switch (*signature) {
+ switch (sig) {
case 0xa5:
case 0xbb:
case 0xdd:
@@ -1572,16 +1563,13 @@ static int __devinit reset_card(struct pci_dev *pdev,
board->shift_count = 12;
break;
case 0xcc:
+ case 0xee:
board->port_count = 16;
board->shift_count = 11;
break;
- default:
- dev_warn(&pdev->dev, "ISILoad:Card%d reset failure (Possible "
- "bad I/O Port Address 0x%lx).\n", card + 1, base);
- dev_dbg(&pdev->dev, "Sig=0x%lx\n", signature);
- retval = -EIO;
}
dev_info(&pdev->dev, "-Done\n");
+ *signature = sig;
end:
return retval;
@@ -1757,7 +1745,7 @@ end:
/*
* Insmod can set static symbols so keep these static
*/
-static int card;
+static unsigned int card_count;
static int __devinit isicom_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
@@ -1767,7 +1755,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
u8 pciirq;
struct isi_board *board = NULL;
- if (card >= BOARD_COUNT)
+ if (card_count >= BOARD_COUNT)
goto err;
ioaddr = pci_resource_start(pdev, 3);
@@ -1785,7 +1773,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
board->index = index;
board->base = ioaddr;
board->irq = pciirq;
- card++;
+ card_count++;
pci_set_drvdata(pdev, board);
@@ -1795,7 +1783,7 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
"will be disabled.\n", board->base, board->base + 15,
index + 1);
retval = -EBUSY;
- goto err;
+ goto errdec;
}
retval = request_irq(board->irq, isicom_interrupt,
@@ -1824,8 +1812,10 @@ errunri:
free_irq(board->irq, board);
errunrr:
pci_release_region(pdev, 3);
-err:
+errdec:
board->base = 0;
+ card_count--;
+err:
return retval;
}
@@ -1839,6 +1829,8 @@ static void __devexit isicom_remove(struct pci_dev *pdev)
free_irq(board->irq, board);
pci_release_region(pdev, 3);
+ board->base = 0;
+ card_count--;
}
static int __init isicom_init(void)
@@ -1846,8 +1838,6 @@ static int __init isicom_init(void)
int retval, idx, channel;
struct isi_port *port;
- card = 0;
-
for(idx = 0; idx < BOARD_COUNT; idx++) {
port = &isi_ports[idx * 16];
isi_card[idx].ports = port;
@@ -1858,8 +1848,6 @@ static int __init isicom_init(void)
port->channel = channel;
port->close_delay = 50 * HZ/100;
port->closing_wait = 3000 * HZ/100;
- INIT_WORK(&port->hangup_tq, do_isicom_hangup);
- INIT_WORK(&port->bh_tqueue, isicom_bottomhalf);
port->status = 0;
init_waitqueue_head(&port->open_wait);
init_waitqueue_head(&port->close_wait);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 68645d351873..7b279d1de4a2 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -2424,7 +2424,6 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
if (tty != NULL) {
tty_wakeup(tty);
EBRDENABLE(brdp);
- wake_up_interruptible(&tty->write_wait);
}
}
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 7a6c1c0b7a95..c654a3e0c697 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -595,15 +595,9 @@ static void fn_spawn_con(struct vc_data *vc)
static void fn_SAK(struct vc_data *vc)
{
- struct tty_struct *tty = vc->vc_tty;
-
- /*
- * SAK should also work in all raw modes and reset
- * them properly.
- */
- if (tty)
- do_SAK(tty);
- reset_vc(vc);
+ struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
+ PREPARE_WORK(SAK_work, vc_SAK);
+ schedule_work(SAK_work);
}
static void fn_null(struct vc_data *vc)
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index 0afb7ba999cf..57f9115a456c 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -46,7 +46,7 @@ LIST_HEAD(soft_list);
/*
* file operations
*/
-struct file_operations mbcs_ops = {
+const struct file_operations mbcs_ops = {
.open = mbcs_open,
.llseek = mbcs_sram_llseek,
.read = mbcs_sram_read,
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index f391a24a1b44..7dbaee8d9402 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -11,15 +11,6 @@
* 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.
*/
/*
@@ -55,36 +46,20 @@
#include <asm/io.h>
#include <asm/uaccess.h>
-#define MOXA_VERSION "5.1k"
+#define MOXA_VERSION "5.1k"
-#define MOXAMAJOR 172
-#define MOXACUMAJOR 173
+#define MOXAMAJOR 172
+#define MOXACUMAJOR 173
-#define put_to_user(arg1, arg2) put_user(arg1, (unsigned long *)arg2)
-#define get_from_user(arg1, arg2) get_user(arg1, (unsigned int *)arg2)
-
-#define MAX_BOARDS 4 /* Don't change this value */
+#define MAX_BOARDS 4 /* Don't change this value */
#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */
-#define MAX_PORTS 128 /* Don't change this value */
+#define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD)
/*
* Define the Moxa PCI vendor and device IDs.
*/
-#define MOXA_BUS_TYPE_ISA 0
-#define MOXA_BUS_TYPE_PCI 1
-
-#ifndef PCI_VENDOR_ID_MOXA
-#define PCI_VENDOR_ID_MOXA 0x1393
-#endif
-#ifndef PCI_DEVICE_ID_CP204J
-#define PCI_DEVICE_ID_CP204J 0x2040
-#endif
-#ifndef PCI_DEVICE_ID_C218
-#define PCI_DEVICE_ID_C218 0x2180
-#endif
-#ifndef PCI_DEVICE_ID_C320
-#define PCI_DEVICE_ID_C320 0x3200
-#endif
+#define MOXA_BUS_TYPE_ISA 0
+#define MOXA_BUS_TYPE_PCI 1
enum {
MOXA_BOARD_C218_PCI = 1,
@@ -105,47 +80,56 @@ static char *moxa_brdname[] =
#ifdef CONFIG_PCI
static struct pci_device_id moxa_pcibrds[] = {
- { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C218, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, MOXA_BOARD_C218_PCI },
- { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C320, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, MOXA_BOARD_C320_PCI },
- { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CP204J, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, MOXA_BOARD_CP204J },
+ { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218),
+ .driver_data = MOXA_BOARD_C218_PCI },
+ { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320),
+ .driver_data = MOXA_BOARD_C320_PCI },
+ { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP204J),
+ .driver_data = MOXA_BOARD_CP204J },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, moxa_pcibrds);
#endif /* CONFIG_PCI */
-typedef struct _moxa_isa_board_conf {
+struct moxa_isa_board_conf {
int boardType;
int numPorts;
unsigned long baseAddr;
-} moxa_isa_board_conf;
+};
-static moxa_isa_board_conf moxa_isa_boards[] =
+static struct moxa_isa_board_conf moxa_isa_boards[] =
{
/* {MOXA_BOARD_C218_ISA,8,0xDC000}, */
};
-typedef struct _moxa_pci_devinfo {
- ushort busNum;
- ushort devNum;
- struct pci_dev *pdev;
-} moxa_pci_devinfo;
-
-typedef struct _moxa_board_conf {
+static struct moxa_board_conf {
int boardType;
int numPorts;
unsigned long baseAddr;
int busType;
- moxa_pci_devinfo pciInfo;
-} moxa_board_conf;
-static moxa_board_conf moxa_boards[MAX_BOARDS];
-static void __iomem *moxaBaseAddr[MAX_BOARDS];
-static int loadstat[MAX_BOARDS];
+ int loadstat;
+
+ void __iomem *basemem;
+ void __iomem *intNdx;
+ void __iomem *intPend;
+ void __iomem *intTable;
+} moxa_boards[MAX_BOARDS];
+
+struct mxser_mstatus {
+ tcflag_t cflag;
+ int cts;
+ int dsr;
+ int ri;
+ int dcd;
+};
+
+struct moxaq_str {
+ int inq;
+ int outq;
+};
-struct moxa_str {
+struct moxa_port {
int type;
int port;
int close_delay;
@@ -159,18 +143,18 @@ struct moxa_str {
int cflag;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
- struct work_struct tqueue;
-};
-struct mxser_mstatus {
- tcflag_t cflag;
- int cts;
- int dsr;
- int ri;
- int dcd;
-};
+ struct timer_list emptyTimer;
-static struct mxser_mstatus GMStatus[MAX_PORTS];
+ char chkPort;
+ char lineCtrl;
+ void __iomem *tableAddr;
+ long curBaud;
+ char DCDState;
+ char lowChkFlag;
+
+ ushort breakCnt;
+};
/* statusflags */
#define TXSTOPPED 0x1
@@ -178,25 +162,17 @@ static struct mxser_mstatus GMStatus[MAX_PORTS];
#define EMPTYWAIT 0x4
#define THROTTLE 0x8
-/* event */
-#define MOXA_EVENT_HANGUP 1
-
#define SERIAL_DO_RESTART
-
-#define SERIAL_TYPE_NORMAL 1
-
#define WAKEUP_CHARS 256
-#define PORTNO(x) ((x)->index)
-
static int verbose = 0;
static int ttymajor = MOXAMAJOR;
/* Variables for insmod */
#ifdef MODULE
-static int baseaddr[] = {0, 0, 0, 0};
-static int type[] = {0, 0, 0, 0};
-static int numports[] = {0, 0, 0, 0};
+static int baseaddr[4];
+static int type[4];
+static int numports[4];
#endif
MODULE_AUTHOR("William Chen");
@@ -210,19 +186,9 @@ module_param_array(numports, int, NULL, 0);
module_param(ttymajor, int, 0);
module_param(verbose, bool, 0644);
-static struct tty_driver *moxaDriver;
-static struct moxa_str moxaChannels[MAX_PORTS];
-static unsigned char *moxaXmitBuff;
-static int moxaTimer_on;
-static struct timer_list moxaTimer;
-static int moxaEmptyTimer_on[MAX_PORTS];
-static struct timer_list moxaEmptyTimer[MAX_PORTS];
-static struct semaphore moxaBuffSem;
-
/*
* static functions:
*/
-static void do_moxa_softint(struct work_struct *);
static int moxa_open(struct tty_struct *, struct file *);
static void moxa_close(struct tty_struct *, struct file *);
static int moxa_write(struct tty_struct *, const unsigned char *, int);
@@ -244,11 +210,11 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
static void moxa_poll(unsigned long);
static void set_tty_param(struct tty_struct *);
static int block_till_ready(struct tty_struct *, struct file *,
- struct moxa_str *);
+ struct moxa_port *);
static void setup_empty_event(struct tty_struct *);
static void check_xmit_empty(unsigned long);
-static void shut_down(struct moxa_str *);
-static void receive_data(struct moxa_str *);
+static void shut_down(struct moxa_port *);
+static void receive_data(struct moxa_port *);
/*
* moxa board interface functions:
*/
@@ -278,8 +244,8 @@ static void MoxaPortTxDisable(int);
static void MoxaPortTxEnable(int);
static int MoxaPortResetBrkCnt(int);
static void MoxaPortSendBreak(int, int);
-static int moxa_get_serial_info(struct moxa_str *, struct serial_struct __user *);
-static int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *);
+static int moxa_get_serial_info(struct moxa_port *, struct serial_struct __user *);
+static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *);
static void MoxaSetFifo(int port, int enable);
static const struct tty_operations moxa_ops = {
@@ -302,12 +268,41 @@ static const struct tty_operations moxa_ops = {
.tiocmset = moxa_tiocmset,
};
+static struct tty_driver *moxaDriver;
+static struct moxa_port moxa_ports[MAX_PORTS];
+static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
static DEFINE_SPINLOCK(moxa_lock);
#ifdef CONFIG_PCI
-static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board)
+static int __devinit moxa_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
- board->baseAddr = pci_resource_start (p, 2);
+ struct moxa_board_conf *board;
+ unsigned int i;
+ int board_type = ent->driver_data;
+ int retval;
+
+ retval = pci_enable_device(pdev);
+ if (retval)
+ goto err;
+
+ for (i = 0; i < MAX_BOARDS; i++)
+ if (moxa_boards[i].basemem == NULL)
+ break;
+
+ retval = -ENODEV;
+ if (i >= MAX_BOARDS) {
+ if (verbose)
+ printk("More than %d MOXA Intellio family boards "
+ "found. Board is ignored.\n", MAX_BOARDS);
+ goto err;
+ }
+
+ board = &moxa_boards[i];
+ board->basemem = pci_iomap(pdev, 2, 0x4000);
+ if (board->basemem == NULL)
+ goto err;
+
board->boardType = board_type;
switch (board_type) {
case MOXA_BOARD_C218_ISA:
@@ -323,27 +318,40 @@ static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf
break;
}
board->busType = MOXA_BUS_TYPE_PCI;
- board->pciInfo.busNum = p->bus->number;
- board->pciInfo.devNum = p->devfn >> 3;
- board->pciInfo.pdev = p;
- /* don't lose the reference in the next pci_get_device iteration */
- pci_dev_get(p);
+
+ pci_set_drvdata(pdev, board);
return (0);
+err:
+ return retval;
}
+
+static void __devexit moxa_pci_remove(struct pci_dev *pdev)
+{
+ struct moxa_board_conf *brd = pci_get_drvdata(pdev);
+
+ pci_iounmap(pdev, brd->basemem);
+ brd->basemem = NULL;
+}
+
+static struct pci_driver moxa_pci_driver = {
+ .name = "moxa",
+ .id_table = moxa_pcibrds,
+ .probe = moxa_pci_probe,
+ .remove = __devexit_p(moxa_pci_remove)
+};
#endif /* CONFIG_PCI */
static int __init moxa_init(void)
{
- int i, numBoards;
- struct moxa_str *ch;
+ int i, numBoards, retval = 0;
+ struct moxa_port *ch;
printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);
moxaDriver = alloc_tty_driver(MAX_PORTS + 1);
if (!moxaDriver)
return -ENOMEM;
- init_MUTEX(&moxaBuffSem);
moxaDriver->owner = THIS_MODULE;
moxaDriver->name = "ttyMX";
moxaDriver->major = ttymajor;
@@ -351,40 +359,25 @@ static int __init moxa_init(void)
moxaDriver->type = TTY_DRIVER_TYPE_SERIAL;
moxaDriver->subtype = SERIAL_TYPE_NORMAL;
moxaDriver->init_termios = tty_std_termios;
- moxaDriver->init_termios.c_iflag = 0;
- moxaDriver->init_termios.c_oflag = 0;
moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
- moxaDriver->init_termios.c_lflag = 0;
moxaDriver->init_termios.c_ispeed = 9600;
moxaDriver->init_termios.c_ospeed = 9600;
moxaDriver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(moxaDriver, &moxa_ops);
- moxaXmitBuff = NULL;
-
- for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) {
+ for (i = 0, ch = moxa_ports; i < MAX_PORTS; i++, ch++) {
ch->type = PORT_16550A;
ch->port = i;
- INIT_WORK(&ch->tqueue, do_moxa_softint);
- ch->tty = NULL;
ch->close_delay = 5 * HZ / 10;
ch->closing_wait = 30 * HZ;
- ch->count = 0;
- ch->blocked_open = 0;
ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
init_waitqueue_head(&ch->open_wait);
init_waitqueue_head(&ch->close_wait);
- }
- for (i = 0; i < MAX_BOARDS; i++) {
- moxa_boards[i].boardType = 0;
- moxa_boards[i].numPorts = 0;
- moxa_boards[i].baseAddr = 0;
- moxa_boards[i].busType = 0;
- moxa_boards[i].pciInfo.busNum = 0;
- moxa_boards[i].pciInfo.devNum = 0;
+ setup_timer(&ch->emptyTimer, check_xmit_empty,
+ (unsigned long)ch);
}
- MoxaDriverInit();
+
printk("Tty devices major number = %d\n", ttymajor);
if (tty_register_driver(moxaDriver)) {
@@ -392,18 +385,8 @@ static int __init moxa_init(void)
put_tty_driver(moxaDriver);
return -1;
}
- for (i = 0; i < MAX_PORTS; i++) {
- init_timer(&moxaEmptyTimer[i]);
- moxaEmptyTimer[i].function = check_xmit_empty;
- moxaEmptyTimer[i].data = (unsigned long) & moxaChannels[i];
- moxaEmptyTimer_on[i] = 0;
- }
- init_timer(&moxaTimer);
- moxaTimer.function = moxa_poll;
- moxaTimer.expires = jiffies + (HZ / 50);
- moxaTimer_on = 1;
- add_timer(&moxaTimer);
+ mod_timer(&moxaTimer, jiffies + HZ / 50);
/* Find the boards defined in source code */
numBoards = 0;
@@ -451,35 +434,22 @@ static int __init moxa_init(void)
}
}
#endif
- /* Find PCI boards here */
+
#ifdef CONFIG_PCI
- {
- struct pci_dev *p = NULL;
- int n = ARRAY_SIZE(moxa_pcibrds) - 1;
- i = 0;
- while (i < n) {
- while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
- {
- if (pci_enable_device(p))
- continue;
- if (numBoards >= MAX_BOARDS) {
- if (verbose)
- printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);
- } else {
- moxa_get_PCI_conf(p, moxa_pcibrds[i].driver_data,
- &moxa_boards[numBoards]);
- numBoards++;
- }
- }
- i++;
- }
+ retval = pci_register_driver(&moxa_pci_driver);
+ if (retval) {
+ printk(KERN_ERR "Can't register moxa pci driver!\n");
+ if (numBoards)
+ retval = 0;
}
#endif
+
for (i = 0; i < numBoards; i++) {
- moxaBaseAddr[i] = ioremap((unsigned long) moxa_boards[i].baseAddr, 0x4000);
+ moxa_boards[i].basemem = ioremap(moxa_boards[i].baseAddr,
+ 0x4000);
}
- return (0);
+ return retval;
}
static void __exit moxa_exit(void)
@@ -489,23 +459,22 @@ static void __exit moxa_exit(void)
if (verbose)
printk("Unloading module moxa ...\n");
- if (moxaTimer_on)
- del_timer(&moxaTimer);
+ del_timer_sync(&moxaTimer);
for (i = 0; i < MAX_PORTS; i++)
- if (moxaEmptyTimer_on[i])
- del_timer(&moxaEmptyTimer[i]);
+ del_timer_sync(&moxa_ports[i].emptyTimer);
if (tty_unregister_driver(moxaDriver))
printk("Couldn't unregister MOXA Intellio family serial driver\n");
put_tty_driver(moxaDriver);
- for (i = 0; i < MAX_BOARDS; i++) {
- if (moxaBaseAddr[i])
- iounmap(moxaBaseAddr[i]);
- if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
- pci_dev_put(moxa_boards[i].pciInfo.pdev);
- }
+#ifdef CONFIG_PCI
+ pci_unregister_driver(&moxa_pci_driver);
+#endif
+
+ for (i = 0; i < MAX_BOARDS; i++)
+ if (moxa_boards[i].basemem)
+ iounmap(moxa_boards[i].basemem);
if (verbose)
printk("Done\n");
@@ -514,28 +483,13 @@ static void __exit moxa_exit(void)
module_init(moxa_init);
module_exit(moxa_exit);
-static void do_moxa_softint(struct work_struct *work)
-{
- struct moxa_str *ch = container_of(work, struct moxa_str, tqueue);
- struct tty_struct *tty;
-
- if (ch && (tty = ch->tty)) {
- if (test_and_clear_bit(MOXA_EVENT_HANGUP, &ch->event)) {
- tty_hangup(tty); /* FIXME: module removal race here - AKPM */
- wake_up_interruptible(&ch->open_wait);
- ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
- }
- }
-}
-
static int moxa_open(struct tty_struct *tty, struct file *filp)
{
- struct moxa_str *ch;
+ struct moxa_port *ch;
int port;
int retval;
- unsigned long page;
- port = PORTNO(tty);
+ port = tty->index;
if (port == MAX_PORTS) {
return (0);
}
@@ -543,23 +497,8 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
tty->driver_data = NULL;
return (-ENODEV);
}
- down(&moxaBuffSem);
- if (!moxaXmitBuff) {
- page = get_zeroed_page(GFP_KERNEL);
- if (!page) {
- up(&moxaBuffSem);
- return (-ENOMEM);
- }
- /* This test is guarded by the BuffSem so no longer needed
- delete me in 2.5 */
- if (moxaXmitBuff)
- free_page(page);
- else
- moxaXmitBuff = (unsigned char *) page;
- }
- up(&moxaBuffSem);
- ch = &moxaChannels[port];
+ ch = &moxa_ports[port];
ch->count++;
tty->driver_data = ch;
ch->tty = tty;
@@ -585,10 +524,10 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
static void moxa_close(struct tty_struct *tty, struct file *filp)
{
- struct moxa_str *ch;
+ struct moxa_port *ch;
int port;
- port = PORTNO(tty);
+ port = tty->index;
if (port == MAX_PORTS) {
return;
}
@@ -605,7 +544,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
if (tty_hung_up_p(filp)) {
return;
}
- ch = (struct moxa_str *) tty->driver_data;
+ ch = (struct moxa_port *) tty->driver_data;
if ((tty->count == 1) && (ch->count != 1)) {
printk("moxa_close: bad serial port count; tty->count is 1, "
@@ -626,8 +565,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
if (ch->asyncflags & ASYNC_INITIALIZED) {
setup_empty_event(tty);
tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
- moxaEmptyTimer_on[ch->port] = 0;
- del_timer(&moxaEmptyTimer[ch->port]);
+ del_timer_sync(&moxa_ports[ch->port].emptyTimer);
}
shut_down(ch);
MoxaPortFlushData(port, 2);
@@ -652,11 +590,11 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
static int moxa_write(struct tty_struct *tty,
const unsigned char *buf, int count)
{
- struct moxa_str *ch;
+ struct moxa_port *ch;
int len, port;
unsigned long flags;
- ch = (struct moxa_str *) tty->driver_data;
+ ch = (struct moxa_port *) tty->driver_data;
if (ch == NULL)
return (0);
port = ch->port;
@@ -675,11 +613,11 @@ static int moxa_write(struct tty_struct *tty,
static int moxa_write_room(struct tty_struct *tty)
{
- struct moxa_str *ch;
+ struct moxa_port *ch;
if (tty->stopped)
return (0);
- ch = (struct moxa_str *) tty->driver_data;
+ ch = (struct moxa_port *) tty->driver_data;
if (ch == NULL)
return (0);
return (MoxaPortTxFree(ch->port));
@@ -687,7 +625,7 @@ static int moxa_write_room(struct tty_struct *tty)
static void moxa_flush_buffer(struct tty_struct *tty)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
if (ch == NULL)
return;
@@ -698,7 +636,7 @@ static void moxa_flush_buffer(struct tty_struct *tty)
static int moxa_chars_in_buffer(struct tty_struct *tty)
{
int chars;
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
/*
* Sigh...I have to check if driver_data is NULL here, because
@@ -730,17 +668,16 @@ static void moxa_flush_chars(struct tty_struct *tty)
static void moxa_put_char(struct tty_struct *tty, unsigned char c)
{
- struct moxa_str *ch;
+ struct moxa_port *ch;
int port;
unsigned long flags;
- ch = (struct moxa_str *) tty->driver_data;
+ ch = (struct moxa_port *) tty->driver_data;
if (ch == NULL)
return;
port = ch->port;
spin_lock_irqsave(&moxa_lock, flags);
- moxaXmitBuff[0] = c;
- MoxaPortWriteData(port, moxaXmitBuff, 1);
+ MoxaPortWriteData(port, &c, 1);
spin_unlock_irqrestore(&moxa_lock, flags);
/************************************************
if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
@@ -750,11 +687,11 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c)
static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
int port;
int flag = 0, dtr, rts;
- port = PORTNO(tty);
+ port = tty->index;
if ((port != MAX_PORTS) && (!ch))
return (-EINVAL);
@@ -776,11 +713,11 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
int port;
int dtr, rts;
- port = PORTNO(tty);
+ port = tty->index;
if ((port != MAX_PORTS) && (!ch))
return (-EINVAL);
@@ -800,12 +737,12 @@ static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
static int moxa_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
register int port;
void __user *argp = (void __user *)arg;
int retval;
- port = PORTNO(tty);
+ port = tty->index;
if ((port != MAX_PORTS) && (!ch))
return (-EINVAL);
@@ -853,14 +790,14 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
static void moxa_throttle(struct tty_struct *tty)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
ch->statusflags |= THROTTLE;
}
static void moxa_unthrottle(struct tty_struct *tty)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
ch->statusflags &= ~THROTTLE;
}
@@ -868,7 +805,7 @@ static void moxa_unthrottle(struct tty_struct *tty)
static void moxa_set_termios(struct tty_struct *tty,
struct ktermios *old_termios)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
if (ch == NULL)
return;
@@ -880,7 +817,7 @@ static void moxa_set_termios(struct tty_struct *tty,
static void moxa_stop(struct tty_struct *tty)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
if (ch == NULL)
return;
@@ -891,7 +828,7 @@ static void moxa_stop(struct tty_struct *tty)
static void moxa_start(struct tty_struct *tty)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
if (ch == NULL)
return;
@@ -905,7 +842,7 @@ static void moxa_start(struct tty_struct *tty)
static void moxa_hangup(struct tty_struct *tty)
{
- struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
+ struct moxa_port *ch = (struct moxa_port *) tty->driver_data;
moxa_flush_buffer(tty);
shut_down(ch);
@@ -919,24 +856,20 @@ static void moxa_hangup(struct tty_struct *tty)
static void moxa_poll(unsigned long ignored)
{
register int card;
- struct moxa_str *ch;
+ struct moxa_port *ch;
struct tty_struct *tp;
int i, ports;
- moxaTimer_on = 0;
del_timer(&moxaTimer);
if (MoxaDriverPoll() < 0) {
- moxaTimer.function = moxa_poll;
- moxaTimer.expires = jiffies + (HZ / 50);
- moxaTimer_on = 1;
- add_timer(&moxaTimer);
+ mod_timer(&moxaTimer, jiffies + HZ / 50);
return;
}
for (card = 0; card < MAX_BOARDS; card++) {
if ((ports = MoxaPortsOfCard(card)) <= 0)
continue;
- ch = &moxaChannels[card * MAX_PORTS_PER_BOARD];
+ ch = &moxa_ports[card * MAX_PORTS_PER_BOARD];
for (i = 0; i < ports; i++, ch++) {
if ((ch->asyncflags & ASYNC_INITIALIZED) == 0)
continue;
@@ -962,18 +895,16 @@ static void moxa_poll(unsigned long ignored)
if (MoxaPortDCDON(ch->port))
wake_up_interruptible(&ch->open_wait);
else {
- set_bit(MOXA_EVENT_HANGUP, &ch->event);
- schedule_work(&ch->tqueue);
+ tty_hangup(tp);
+ wake_up_interruptible(&ch->open_wait);
+ ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
}
}
}
}
}
- moxaTimer.function = moxa_poll;
- moxaTimer.expires = jiffies + (HZ / 50);
- moxaTimer_on = 1;
- add_timer(&moxaTimer);
+ mod_timer(&moxaTimer, jiffies + HZ / 50);
}
/******************************************************************************/
@@ -981,10 +912,10 @@ static void moxa_poll(unsigned long ignored)
static void set_tty_param(struct tty_struct *tty)
{
register struct ktermios *ts;
- struct moxa_str *ch;
+ struct moxa_port *ch;
int rts, cts, txflow, rxflow, xany;
- ch = (struct moxa_str *) tty->driver_data;
+ ch = (struct moxa_port *) tty->driver_data;
ts = tty->termios;
if (ts->c_cflag & CLOCAL)
ch->asyncflags &= ~ASYNC_CHECK_CD;
@@ -1004,7 +935,7 @@ static void set_tty_param(struct tty_struct *tty)
}
static int block_till_ready(struct tty_struct *tty, struct file *filp,
- struct moxa_str *ch)
+ struct moxa_port *ch)
{
DECLARE_WAITQUEUE(wait,current);
unsigned long flags;
@@ -1095,40 +1026,33 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
static void setup_empty_event(struct tty_struct *tty)
{
- struct moxa_str *ch = tty->driver_data;
+ struct moxa_port *ch = tty->driver_data;
unsigned long flags;
spin_lock_irqsave(&moxa_lock, flags);
ch->statusflags |= EMPTYWAIT;
- moxaEmptyTimer_on[ch->port] = 0;
- del_timer(&moxaEmptyTimer[ch->port]);
- moxaEmptyTimer[ch->port].expires = jiffies + HZ;
- moxaEmptyTimer_on[ch->port] = 1;
- add_timer(&moxaEmptyTimer[ch->port]);
+ mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ);
spin_unlock_irqrestore(&moxa_lock, flags);
}
static void check_xmit_empty(unsigned long data)
{
- struct moxa_str *ch;
+ struct moxa_port *ch;
- ch = (struct moxa_str *) data;
- moxaEmptyTimer_on[ch->port] = 0;
- del_timer(&moxaEmptyTimer[ch->port]);
+ ch = (struct moxa_port *) data;
+ del_timer_sync(&moxa_ports[ch->port].emptyTimer);
if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
if (MoxaPortTxQueue(ch->port) == 0) {
ch->statusflags &= ~EMPTYWAIT;
tty_wakeup(ch->tty);
return;
}
- moxaEmptyTimer[ch->port].expires = jiffies + HZ;
- moxaEmptyTimer_on[ch->port] = 1;
- add_timer(&moxaEmptyTimer[ch->port]);
+ mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ);
} else
ch->statusflags &= ~EMPTYWAIT;
}
-static void shut_down(struct moxa_str *ch)
+static void shut_down(struct moxa_port *ch)
{
struct tty_struct *tp;
@@ -1148,7 +1072,7 @@ static void shut_down(struct moxa_str *ch)
ch->asyncflags &= ~ASYNC_INITIALIZED;
}
-static void receive_data(struct moxa_str *ch)
+static void receive_data(struct moxa_port *ch)
{
struct tty_struct *tp;
struct ktermios *ts;
@@ -1465,35 +1389,21 @@ static void receive_data(struct moxa_str *ch)
/*
* Query
*/
-#define QueryPort MAX_PORTS
-
-
struct mon_str {
int tick;
int rxcnt[MAX_PORTS];
int txcnt[MAX_PORTS];
};
-typedef struct mon_str mon_st;
#define DCD_changed 0x01
#define DCD_oldstate 0x80
static unsigned char moxaBuff[10240];
-static void __iomem *moxaIntNdx[MAX_BOARDS];
-static void __iomem *moxaIntPend[MAX_BOARDS];
-static void __iomem *moxaIntTable[MAX_BOARDS];
-static char moxaChkPort[MAX_PORTS];
-static char moxaLineCtrl[MAX_PORTS];
-static void __iomem *moxaTableAddr[MAX_PORTS];
-static long moxaCurBaud[MAX_PORTS];
-static char moxaDCDState[MAX_PORTS];
-static char moxaLowChkFlag[MAX_PORTS];
static int moxaLowWaterChk;
static int moxaCard;
-static mon_st moxaLog;
-static int moxaFuncTout;
-static ushort moxaBreakCnt[MAX_PORTS];
+static struct mon_str moxaLog;
+static int moxaFuncTout = HZ / 2;
static void moxadelay(int);
static void moxafunc(void __iomem *, int, ushort);
@@ -1514,16 +1424,18 @@ static int moxaloadc320(int, void __iomem *, int, int *);
*****************************************************************************/
void MoxaDriverInit(void)
{
- int i;
+ struct moxa_port *p;
+ unsigned int i;
moxaFuncTout = HZ / 2; /* 500 mini-seconds */
moxaCard = 0;
moxaLog.tick = 0;
moxaLowWaterChk = 0;
for (i = 0; i < MAX_PORTS; i++) {
- moxaChkPort[i] = 0;
- moxaLowChkFlag[i] = 0;
- moxaLineCtrl[i] = 0;
+ p = &moxa_ports[i];
+ p->chkPort = 0;
+ p->lowChkFlag = 0;
+ p->lineCtrl = 0;
moxaLog.rxcnt[i] = 0;
moxaLog.txcnt[i] = 0;
}
@@ -1545,19 +1457,12 @@ void MoxaDriverInit(void)
#define MOXA_GET_CUMAJOR (MOXA + 64)
#define MOXA_GETMSTATUS (MOXA + 65)
-
-struct moxaq_str {
- int inq;
- int outq;
-};
-
struct dl_str {
char __user *buf;
int len;
int cardno;
};
-static struct moxaq_str temp_queue[MAX_PORTS];
static struct dl_str dltmp;
void MoxaPortFlushData(int port, int mode)
@@ -1565,10 +1470,10 @@ void MoxaPortFlushData(int port, int mode)
void __iomem *ofsAddr;
if ((mode < 0) || (mode > 2))
return;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
moxafunc(ofsAddr, FC_FlushQueue, mode);
if (mode != 1) {
- moxaLowChkFlag[port] = 0;
+ moxa_ports[port].lowChkFlag = 0;
low_water_check(ofsAddr);
}
}
@@ -1580,7 +1485,7 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
int MoxaPortTxQueue(int), MoxaPortRxQueue(int);
void __user *argp = (void __user *)arg;
- if (port == QueryPort) {
+ if (port == MAX_PORTS) {
if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) &&
(cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) &&
(cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) &&
@@ -1590,7 +1495,8 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
}
switch (cmd) {
case MOXA_GET_CONF:
- if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * sizeof(moxa_board_conf)))
+ if(copy_to_user(argp, &moxa_boards, MAX_BOARDS *
+ sizeof(struct moxa_board_conf)))
return -EFAULT;
return (0);
case MOXA_INIT_DRIVER:
@@ -1599,23 +1505,27 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
return (0);
case MOXA_GETDATACOUNT:
moxaLog.tick = jiffies;
- if(copy_to_user(argp, &moxaLog, sizeof(mon_st)))
+ if(copy_to_user(argp, &moxaLog, sizeof(struct mon_str)))
return -EFAULT;
return (0);
case MOXA_FLUSH_QUEUE:
MoxaPortFlushData(port, arg);
return (0);
- case MOXA_GET_IOQUEUE:
- for (i = 0; i < MAX_PORTS; i++) {
- if (moxaChkPort[i]) {
- temp_queue[i].inq = MoxaPortRxQueue(i);
- temp_queue[i].outq = MoxaPortTxQueue(i);
+ case MOXA_GET_IOQUEUE: {
+ struct moxaq_str __user *argm = argp;
+ struct moxaq_str tmp;
+
+ for (i = 0; i < MAX_PORTS; i++, argm++) {
+ memset(&tmp, 0, sizeof(tmp));
+ if (moxa_ports[i].chkPort) {
+ tmp.inq = MoxaPortRxQueue(i);
+ tmp.outq = MoxaPortTxQueue(i);
}
+ if (copy_to_user(argm, &tmp, sizeof(tmp)))
+ return -EFAULT;
}
- if(copy_to_user(argp, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS))
- return -EFAULT;
return (0);
- case MOXA_GET_OQUEUE:
+ } case MOXA_GET_OQUEUE:
i = MoxaPortTxQueue(port);
return put_user(i, (unsigned long __user *)argp);
case MOXA_GET_IQUEUE:
@@ -1630,33 +1540,36 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
if(copy_to_user(argp, &i, sizeof(int)))
return -EFAULT;
return 0;
- case MOXA_GETMSTATUS:
- for (i = 0; i < MAX_PORTS; i++) {
- GMStatus[i].ri = 0;
- GMStatus[i].dcd = 0;
- GMStatus[i].dsr = 0;
- GMStatus[i].cts = 0;
- if (!moxaChkPort[i]) {
- continue;
+ case MOXA_GETMSTATUS: {
+ struct mxser_mstatus __user *argm = argp;
+ struct mxser_mstatus tmp;
+ struct moxa_port *p;
+
+ for (i = 0; i < MAX_PORTS; i++, argm++) {
+ p = &moxa_ports[i];
+ memset(&tmp, 0, sizeof(tmp));
+ if (!p->chkPort) {
+ goto copy;
} else {
- status = MoxaPortLineStatus(moxaChannels[i].port);
+ status = MoxaPortLineStatus(p->port);
if (status & 1)
- GMStatus[i].cts = 1;
+ tmp.cts = 1;
if (status & 2)
- GMStatus[i].dsr = 1;
+ tmp.dsr = 1;
if (status & 4)
- GMStatus[i].dcd = 1;
+ tmp.dcd = 1;
}
- if (!moxaChannels[i].tty || !moxaChannels[i].tty->termios)
- GMStatus[i].cflag = moxaChannels[i].cflag;
+ if (!p->tty || !p->tty->termios)
+ tmp.cflag = p->cflag;
else
- GMStatus[i].cflag = moxaChannels[i].tty->termios->c_cflag;
+ tmp.cflag = p->tty->termios->c_cflag;
+copy:
+ if (copy_to_user(argm, &tmp, sizeof(tmp)))
+ return -EFAULT;
}
- if(copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS))
- return -EFAULT;
return 0;
- default:
+ } default:
return (-ENOIOCTLCMD);
case MOXA_LOAD_BIOS:
case MOXA_FIND_BOARD:
@@ -1694,6 +1607,7 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
int MoxaDriverPoll(void)
{
+ struct moxa_board_conf *brd;
register ushort temp;
register int card;
void __iomem *ofsAddr;
@@ -1703,43 +1617,44 @@ int MoxaDriverPoll(void)
if (moxaCard == 0)
return (-1);
for (card = 0; card < MAX_BOARDS; card++) {
- if (loadstat[card] == 0)
+ brd = &moxa_boards[card];
+ if (brd->loadstat == 0)
continue;
- if ((ports = moxa_boards[card].numPorts) == 0)
+ if ((ports = brd->numPorts) == 0)
continue;
- if (readb(moxaIntPend[card]) == 0xff) {
- ip = moxaIntTable[card] + readb(moxaIntNdx[card]);
+ if (readb(brd->intPend) == 0xff) {
+ ip = brd->intTable + readb(brd->intNdx);
p = card * MAX_PORTS_PER_BOARD;
ports <<= 1;
for (port = 0; port < ports; port += 2, p++) {
if ((temp = readw(ip + port)) != 0) {
writew(0, ip + port);
- ofsAddr = moxaTableAddr[p];
+ ofsAddr = moxa_ports[p].tableAddr;
if (temp & IntrTx)
writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat);
if (temp & IntrBreak) {
- moxaBreakCnt[p]++;
+ moxa_ports[p].breakCnt++;
}
if (temp & IntrLine) {
if (readb(ofsAddr + FlagStat) & DCD_state) {
- if ((moxaDCDState[p] & DCD_oldstate) == 0)
- moxaDCDState[p] = (DCD_oldstate |
+ if ((moxa_ports[p].DCDState & DCD_oldstate) == 0)
+ moxa_ports[p].DCDState = (DCD_oldstate |
DCD_changed);
} else {
- if (moxaDCDState[p] & DCD_oldstate)
- moxaDCDState[p] = DCD_changed;
+ if (moxa_ports[p].DCDState & DCD_oldstate)
+ moxa_ports[p].DCDState = DCD_changed;
}
}
}
}
- writeb(0, moxaIntPend[card]);
+ writeb(0, brd->intPend);
}
if (moxaLowWaterChk) {
p = card * MAX_PORTS_PER_BOARD;
for (port = 0; port < ports; port++, p++) {
- if (moxaLowChkFlag[p]) {
- moxaLowChkFlag[p] = 0;
- ofsAddr = moxaTableAddr[p];
+ if (moxa_ports[p].lowChkFlag) {
+ moxa_ports[p].lowChkFlag = 0;
+ ofsAddr = moxa_ports[p].tableAddr;
low_water_check(ofsAddr);
}
}
@@ -1767,9 +1682,7 @@ int MoxaPortsOfCard(int cardno)
* 2. MoxaPortEnable(int port); *
* 3. MoxaPortDisable(int port); *
* 4. MoxaPortGetMaxBaud(int port); *
- * 5. MoxaPortGetCurBaud(int port); *
* 6. MoxaPortSetBaud(int port, long baud); *
- * 7. MoxaPortSetMode(int port, int databit, int stopbit, int parity); *
* 8. MoxaPortSetTermio(int port, unsigned char *termio); *
* 9. MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); *
* 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); *
@@ -1780,18 +1693,12 @@ int MoxaPortsOfCard(int cardno)
* 15. MoxaPortFlushData(int port, int mode); *
* 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
* 17. MoxaPortReadData(int port, struct tty_struct *tty); *
- * 18. MoxaPortTxBufSize(int port); *
- * 19. MoxaPortRxBufSize(int port); *
* 20. MoxaPortTxQueue(int port); *
* 21. MoxaPortTxFree(int port); *
* 22. MoxaPortRxQueue(int port); *
- * 23. MoxaPortRxFree(int port); *
* 24. MoxaPortTxDisable(int port); *
* 25. MoxaPortTxEnable(int port); *
- * 26. MoxaPortGetBrkCnt(int port); *
* 27. MoxaPortResetBrkCnt(int port); *
- * 28. MoxaPortSetXonXoff(int port, int xonValue, int xoffValue); *
- * 29. MoxaPortIsTxHold(int port); *
* 30. MoxaPortSendBreak(int port, int ticks); *
*****************************************************************************/
/*
@@ -1878,15 +1785,6 @@ int MoxaPortsOfCard(int cardno)
* 38400/57600/115200 bps
*
*
- * Function 9: Get the current baud rate of this port.
- * Syntax:
- * long MoxaPortGetCurBaud(int port);
- * int port : port number (0 - 127)
- *
- * return: 0 : this port is invalid
- * 50 - 115200 bps
- *
- *
* Function 10: Setting baud rate of this port.
* Syntax:
* long MoxaPortSetBaud(int port, long baud);
@@ -1900,18 +1798,6 @@ int MoxaPortsOfCard(int cardno)
* baud rate will be the maximun baud rate.
*
*
- * Function 11: Setting the data-bits/stop-bits/parity of this port
- * Syntax:
- * int MoxaPortSetMode(int port, int databits, int stopbits, int parity);
- * int port : port number (0 - 127)
- * int databits : data bits (8/7/6/5)
- * int stopbits : stop bits (2/1/0, 0 show 1.5 stop bits)
- int parity : parity (0:None,1:Odd,2:Even,3:Mark,4:Space)
- *
- * return: -1 : invalid parameter
- * 0 : setting O.K.
- *
- *
* Function 12: Configure the port.
* Syntax:
* int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud);
@@ -2016,22 +1902,6 @@ int MoxaPortsOfCard(int cardno)
* return: 0 - length : real read data length
*
*
- * Function 22: Get the Tx buffer size of this port
- * Syntax:
- * int MoxaPortTxBufSize(int port);
- * int port : port number (0 - 127)
- *
- * return: .. : Tx buffer size
- *
- *
- * Function 23: Get the Rx buffer size of this port
- * Syntax:
- * int MoxaPortRxBufSize(int port);
- * int port : port number (0 - 127)
- *
- * return: .. : Rx buffer size
- *
- *
* Function 24: Get the Tx buffer current queued data bytes
* Syntax:
* int MoxaPortTxQueue(int port);
@@ -2056,14 +1926,6 @@ int MoxaPortsOfCard(int cardno)
* return: .. : Rx buffer current queued data bytes
*
*
- * Function 27: Get the Rx buffer current free space
- * Syntax:
- * int MoxaPortRxFree(int port);
- * int port : port number (0 - 127)
- *
- * return: .. : Rx buffer current free space
- *
- *
* Function 28: Disable port data transmission.
* Syntax:
* void MoxaPortTxDisable(int port);
@@ -2076,14 +1938,6 @@ int MoxaPortsOfCard(int cardno)
* int port : port number (0 - 127)
*
*
- * Function 30: Get the received BREAK signal count.
- * Syntax:
- * int MoxaPortGetBrkCnt(int port);
- * int port : port number (0 - 127)
- *
- * return: 0 - .. : BREAK signal count
- *
- *
* Function 31: Get the received BREAK signal count and reset it.
* Syntax:
* int MoxaPortResetBrkCnt(int port);
@@ -2092,25 +1946,6 @@ int MoxaPortsOfCard(int cardno)
* return: 0 - .. : BREAK signal count
*
*
- * Function 32: Set the S/W flow control new XON/XOFF value, default
- * XON is 0x11 & XOFF is 0x13.
- * Syntax:
- * void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue);
- * int port : port number (0 - 127)
- * int xonValue : new XON value (0 - 255)
- * int xoffValue : new XOFF value (0 - 255)
- *
- *
- * Function 33: Check this port's transmission is hold by remote site
- * because the flow control.
- * Syntax:
- * int MoxaPortIsTxHold(int port);
- * int port : port number (0 - 127)
- *
- * return: 0 : normal
- * 1 : hold by remote site
- *
- *
* Function 34: Send out a BREAK signal.
* Syntax:
* void MoxaPortSendBreak(int port, int ms100);
@@ -2125,7 +1960,7 @@ int MoxaPortIsValid(int port)
if (moxaCard == 0)
return (0);
- if (moxaChkPort[port] == 0)
+ if (moxa_ports[port].chkPort == 0)
return (0);
return (1);
}
@@ -2136,9 +1971,9 @@ void MoxaPortEnable(int port)
int MoxaPortLineStatus(int);
short lowwater = 512;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
writew(lowwater, ofsAddr + Low_water);
- moxaBreakCnt[port] = 0;
+ moxa_ports[port].breakCnt = 0;
if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
(moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
moxafunc(ofsAddr, FC_SetBreakIrq, 0);
@@ -2155,7 +1990,7 @@ void MoxaPortEnable(int port)
void MoxaPortDisable(int port)
{
- void __iomem *ofsAddr = moxaTableAddr[port];
+ void __iomem *ofsAddr = moxa_ports[port].tableAddr;
moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */
moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code);
@@ -2181,7 +2016,7 @@ long MoxaPortSetBaud(int port, long baud)
if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0))
return (0);
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
if (baud > max)
baud = max;
if (max == 38400L)
@@ -2193,7 +2028,7 @@ long MoxaPortSetBaud(int port, long baud)
val = clock / baud;
moxafunc(ofsAddr, FC_SetBaud, val);
baud = clock / val;
- moxaCurBaud[port] = baud;
+ moxa_ports[port].curBaud = baud;
return (baud);
}
@@ -2203,9 +2038,9 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
tcflag_t cflag;
tcflag_t mode = 0;
- if (moxaChkPort[port] == 0 || termio == 0)
+ if (moxa_ports[port].chkPort == 0 || termio == 0)
return (-1);
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
cflag = termio->c_cflag; /* termio->c_cflag */
mode = termio->c_cflag & CSIZE;
@@ -2259,13 +2094,13 @@ int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState)
if (!MoxaPortIsValid(port))
return (-1);
if (dtrState) {
- if (moxaLineCtrl[port] & DTR_ON)
+ if (moxa_ports[port].lineCtrl & DTR_ON)
*dtrState = 1;
else
*dtrState = 0;
}
if (rtsState) {
- if (moxaLineCtrl[port] & RTS_ON)
+ if (moxa_ports[port].lineCtrl & RTS_ON)
*rtsState = 1;
else
*rtsState = 0;
@@ -2278,13 +2113,13 @@ void MoxaPortLineCtrl(int port, int dtr, int rts)
void __iomem *ofsAddr;
int mode;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
mode = 0;
if (dtr)
mode |= DTR_ON;
if (rts)
mode |= RTS_ON;
- moxaLineCtrl[port] = mode;
+ moxa_ports[port].lineCtrl = mode;
moxafunc(ofsAddr, FC_LineControl, mode);
}
@@ -2293,7 +2128,7 @@ void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int tx
void __iomem *ofsAddr;
int mode;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
mode = 0;
if (rts)
mode |= RTS_FlowCtl;
@@ -2313,7 +2148,7 @@ int MoxaPortLineStatus(int port)
void __iomem *ofsAddr;
int val;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
(moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
moxafunc(ofsAddr, FC_LineStatus, 0);
@@ -2324,11 +2159,11 @@ int MoxaPortLineStatus(int port)
val &= 0x0B;
if (val & 8) {
val |= 4;
- if ((moxaDCDState[port] & DCD_oldstate) == 0)
- moxaDCDState[port] = (DCD_oldstate | DCD_changed);
+ if ((moxa_ports[port].DCDState & DCD_oldstate) == 0)
+ moxa_ports[port].DCDState = (DCD_oldstate | DCD_changed);
} else {
- if (moxaDCDState[port] & DCD_oldstate)
- moxaDCDState[port] = DCD_changed;
+ if (moxa_ports[port].DCDState & DCD_oldstate)
+ moxa_ports[port].DCDState = DCD_changed;
}
val &= 7;
return (val);
@@ -2338,10 +2173,10 @@ int MoxaPortDCDChange(int port)
{
int n;
- if (moxaChkPort[port] == 0)
+ if (moxa_ports[port].chkPort == 0)
return (0);
- n = moxaDCDState[port];
- moxaDCDState[port] &= ~DCD_changed;
+ n = moxa_ports[port].DCDState;
+ moxa_ports[port].DCDState &= ~DCD_changed;
n &= DCD_changed;
return (n);
}
@@ -2350,32 +2185,15 @@ int MoxaPortDCDON(int port)
{
int n;
- if (moxaChkPort[port] == 0)
+ if (moxa_ports[port].chkPort == 0)
return (0);
- if (moxaDCDState[port] & DCD_oldstate)
+ if (moxa_ports[port].DCDState & DCD_oldstate)
n = 1;
else
n = 0;
return (n);
}
-
-/*
- int MoxaDumpMem(int port, unsigned char * buffer, int len)
- {
- int i;
- unsigned long baseAddr,ofsAddr,ofs;
-
- baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
- ofs = baseAddr + DynPage_addr + pageofs;
- if (len > 0x2000L)
- len = 0x2000L;
- for (i = 0; i < len; i++)
- buffer[i] = readb(ofs+i);
- }
- */
-
-
int MoxaPortWriteData(int port, unsigned char * buffer, int len)
{
int c, total, i;
@@ -2385,8 +2203,8 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len)
ushort pageno, pageofs, bufhead;
void __iomem *baseAddr, *ofsAddr, *ofs;
- ofsAddr = moxaTableAddr[port];
- baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
+ ofsAddr = moxa_ports[port].tableAddr;
+ baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem;
tx_mask = readw(ofsAddr + TX_mask);
spage = readw(ofsAddr + Page_txb);
epage = readw(ofsAddr + EndPage_txb);
@@ -2448,8 +2266,8 @@ int MoxaPortReadData(int port, struct tty_struct *tty)
ushort pageno, bufhead;
void __iomem *baseAddr, *ofsAddr, *ofs;
- ofsAddr = moxaTableAddr[port];
- baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
+ ofsAddr = moxa_ports[port].tableAddr;
+ baseAddr = moxa_boards[port / MAX_PORTS_PER_BOARD].basemem;
head = readw(ofsAddr + RXrptr);
tail = readw(ofsAddr + RXwptr);
rx_mask = readw(ofsAddr + RX_mask);
@@ -2504,7 +2322,7 @@ int MoxaPortReadData(int port, struct tty_struct *tty)
}
if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) {
moxaLowWaterChk = 1;
- moxaLowChkFlag[port] = 1;
+ moxa_ports[port].lowChkFlag = 1;
}
return (total);
}
@@ -2516,7 +2334,7 @@ int MoxaPortTxQueue(int port)
ushort rptr, wptr, mask;
int len;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
rptr = readw(ofsAddr + TXrptr);
wptr = readw(ofsAddr + TXwptr);
mask = readw(ofsAddr + TX_mask);
@@ -2530,7 +2348,7 @@ int MoxaPortTxFree(int port)
ushort rptr, wptr, mask;
int len;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
rptr = readw(ofsAddr + TXrptr);
wptr = readw(ofsAddr + TXwptr);
mask = readw(ofsAddr + TX_mask);
@@ -2544,7 +2362,7 @@ int MoxaPortRxQueue(int port)
ushort rptr, wptr, mask;
int len;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
rptr = readw(ofsAddr + RXrptr);
wptr = readw(ofsAddr + RXwptr);
mask = readw(ofsAddr + RX_mask);
@@ -2557,7 +2375,7 @@ void MoxaPortTxDisable(int port)
{
void __iomem *ofsAddr;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
moxafunc(ofsAddr, FC_SetXoffState, Magic_code);
}
@@ -2565,7 +2383,7 @@ void MoxaPortTxEnable(int port)
{
void __iomem *ofsAddr;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
moxafunc(ofsAddr, FC_SetXonState, Magic_code);
}
@@ -2573,8 +2391,8 @@ void MoxaPortTxEnable(int port)
int MoxaPortResetBrkCnt(int port)
{
ushort cnt;
- cnt = moxaBreakCnt[port];
- moxaBreakCnt[port] = 0;
+ cnt = moxa_ports[port].breakCnt;
+ moxa_ports[port].breakCnt = 0;
return (cnt);
}
@@ -2583,7 +2401,7 @@ void MoxaPortSendBreak(int port, int ms100)
{
void __iomem *ofsAddr;
- ofsAddr = moxaTableAddr[port];
+ ofsAddr = moxa_ports[port].tableAddr;
if (ms100) {
moxafunc(ofsAddr, FC_SendBreak, Magic_code);
moxadelay(ms100 * (HZ / 10));
@@ -2594,7 +2412,7 @@ void MoxaPortSendBreak(int port, int ms100)
moxafunc(ofsAddr, FC_StopBreak, Magic_code);
}
-static int moxa_get_serial_info(struct moxa_str *info,
+static int moxa_get_serial_info(struct moxa_port *info,
struct serial_struct __user *retinfo)
{
struct serial_struct tmp;
@@ -2616,7 +2434,7 @@ static int moxa_get_serial_info(struct moxa_str *info,
}
-static int moxa_set_serial_info(struct moxa_str *info,
+static int moxa_set_serial_info(struct moxa_port *info,
struct serial_struct __user *new_info)
{
struct serial_struct new_serial;
@@ -2713,7 +2531,7 @@ static int moxaloadbios(int cardno, unsigned char __user *tmp, int len)
if(copy_from_user(moxaBuff, tmp, len))
return -EFAULT;
- baseAddr = moxaBaseAddr[cardno];
+ baseAddr = moxa_boards[cardno].basemem;
writeb(HW_reset, baseAddr + Control_reg); /* reset */
moxadelay(1); /* delay 10 ms */
for (i = 0; i < 4096; i++)
@@ -2729,7 +2547,7 @@ static int moxafindcard(int cardno)
void __iomem *baseAddr;
ushort tmp;
- baseAddr = moxaBaseAddr[cardno];
+ baseAddr = moxa_boards[cardno].basemem;
switch (moxa_boards[cardno].boardType) {
case MOXA_BOARD_C218_ISA:
case MOXA_BOARD_C218_PCI:
@@ -2762,7 +2580,7 @@ static int moxaload320b(int cardno, unsigned char __user *tmp, int len)
return -EINVAL;
if(copy_from_user(moxaBuff, tmp, len))
return -EFAULT;
- baseAddr = moxaBaseAddr[cardno];
+ baseAddr = moxa_boards[cardno].basemem;
writew(len - 7168 - 2, baseAddr + C320bapi_len);
writeb(1, baseAddr + Control_reg); /* Select Page 1 */
for (i = 0; i < 7168; i++)
@@ -2780,7 +2598,7 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
if(copy_from_user(moxaBuff, tmp, len))
return -EFAULT;
- baseAddr = moxaBaseAddr[cardno];
+ baseAddr = moxa_boards[cardno].basemem;
switch (moxa_boards[cardno].boardType) {
case MOXA_BOARD_C218_ISA:
case MOXA_BOARD_C218_PCI:
@@ -2790,11 +2608,13 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
return (retval);
port = cardno * MAX_PORTS_PER_BOARD;
for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
- moxaChkPort[port] = 1;
- moxaCurBaud[port] = 9600L;
- moxaDCDState[port] = 0;
- moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i;
- ofsAddr = moxaTableAddr[port];
+ struct moxa_port *p = &moxa_ports[port];
+
+ p->chkPort = 1;
+ p->curBaud = 9600L;
+ p->DCDState = 0;
+ p->tableAddr = baseAddr + Extern_table + Extern_size * i;
+ ofsAddr = p->tableAddr;
writew(C218rx_mask, ofsAddr + RX_mask);
writew(C218tx_mask, ofsAddr + TX_mask);
writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb);
@@ -2812,11 +2632,13 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
return (retval);
port = cardno * MAX_PORTS_PER_BOARD;
for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
- moxaChkPort[port] = 1;
- moxaCurBaud[port] = 9600L;
- moxaDCDState[port] = 0;
- moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i;
- ofsAddr = moxaTableAddr[port];
+ struct moxa_port *p = &moxa_ports[port];
+
+ p->chkPort = 1;
+ p->curBaud = 9600L;
+ p->DCDState = 0;
+ p->tableAddr = baseAddr + Extern_table + Extern_size * i;
+ ofsAddr = p->tableAddr;
if (moxa_boards[cardno].numPorts == 8) {
writew(C320p8rx_mask, ofsAddr + RX_mask);
writew(C320p8tx_mask, ofsAddr + TX_mask);
@@ -2852,7 +2674,7 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
}
break;
}
- loadstat[cardno] = 1;
+ moxa_boards[cardno].loadstat = 1;
return (0);
}
@@ -2926,9 +2748,9 @@ static int moxaloadc218(int cardno, void __iomem *baseAddr, int len)
return (-1);
}
moxaCard = 1;
- moxaIntNdx[cardno] = baseAddr + IRQindex;
- moxaIntPend[cardno] = baseAddr + IRQpending;
- moxaIntTable[cardno] = baseAddr + IRQtable;
+ moxa_boards[cardno].intNdx = baseAddr + IRQindex;
+ moxa_boards[cardno].intPend = baseAddr + IRQpending;
+ moxa_boards[cardno].intTable = baseAddr + IRQtable;
return (0);
}
@@ -3021,25 +2843,15 @@ static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPor
if (readw(baseAddr + Magic_no) != Magic_code)
return (-102);
moxaCard = 1;
- moxaIntNdx[cardno] = baseAddr + IRQindex;
- moxaIntPend[cardno] = baseAddr + IRQpending;
- moxaIntTable[cardno] = baseAddr + IRQtable;
+ moxa_boards[cardno].intNdx = baseAddr + IRQindex;
+ moxa_boards[cardno].intPend = baseAddr + IRQpending;
+ moxa_boards[cardno].intTable = baseAddr + IRQtable;
return (0);
}
-#if 0
-long MoxaPortGetCurBaud(int port)
-{
-
- if (moxaChkPort[port] == 0)
- return (0);
- return (moxaCurBaud[port]);
-}
-#endif /* 0 */
-
static void MoxaSetFifo(int port, int enable)
{
- void __iomem *ofsAddr = moxaTableAddr[port];
+ void __iomem *ofsAddr = moxa_ports[port].tableAddr;
if (!enable) {
moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0);
@@ -3049,132 +2861,3 @@ static void MoxaSetFifo(int port, int enable)
moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16);
}
}
-
-#if 0
-int MoxaPortSetMode(int port, int databits, int stopbits, int parity)
-{
- void __iomem *ofsAddr;
- int val;
-
- val = 0;
- switch (databits) {
- case 5:
- val |= 0;
- break;
- case 6:
- val |= 1;
- break;
- case 7:
- val |= 2;
- break;
- case 8:
- val |= 3;
- break;
- default:
- return (-1);
- }
- switch (stopbits) {
- case 0:
- val |= 0;
- break; /* stop bits 1.5 */
- case 1:
- val |= 0;
- break;
- case 2:
- val |= 4;
- break;
- default:
- return (-1);
- }
- switch (parity) {
- case 0:
- val |= 0x00;
- break; /* None */
- case 1:
- val |= 0x08;
- break; /* Odd */
- case 2:
- val |= 0x18;
- break; /* Even */
- case 3:
- val |= 0x28;
- break; /* Mark */
- case 4:
- val |= 0x38;
- break; /* Space */
- default:
- return (-1);
- }
- ofsAddr = moxaTableAddr[port];
- moxafunc(ofsAddr, FC_SetMode, val);
- return (0);
-}
-
-int MoxaPortTxBufSize(int port)
-{
- void __iomem *ofsAddr;
- int size;
-
- ofsAddr = moxaTableAddr[port];
- size = readw(ofsAddr + TX_mask);
- return (size);
-}
-
-int MoxaPortRxBufSize(int port)
-{
- void __iomem *ofsAddr;
- int size;
-
- ofsAddr = moxaTableAddr[port];
- size = readw(ofsAddr + RX_mask);
- return (size);
-}
-
-int MoxaPortRxFree(int port)
-{
- void __iomem *ofsAddr;
- ushort rptr, wptr, mask;
- int len;
-
- ofsAddr = moxaTableAddr[port];
- rptr = readw(ofsAddr + RXrptr);
- wptr = readw(ofsAddr + RXwptr);
- mask = readw(ofsAddr + RX_mask);
- len = mask - ((wptr - rptr) & mask);
- return (len);
-}
-int MoxaPortGetBrkCnt(int port)
-{
- return (moxaBreakCnt[port]);
-}
-
-void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue)
-{
- void __iomem *ofsAddr;
-
- ofsAddr = moxaTableAddr[port];
- writew(xonValue, ofsAddr + FuncArg);
- writew(xoffValue, ofsAddr + FuncArg1);
- writew(FC_SetXonXoff, ofsAddr + FuncCode);
- wait_finish(ofsAddr);
-}
-
-int MoxaPortIsTxHold(int port)
-{
- void __iomem *ofsAddr;
- int val;
-
- ofsAddr = moxaTableAddr[port];
- if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
- (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
- moxafunc(ofsAddr, FC_GetCCSR, 0);
- val = readw(ofsAddr + FuncArg);
- if (val & 0x04)
- return (1);
- } else {
- if (readw(ofsAddr + FlagStat) & Tx_flowOff)
- return (1);
- }
- return (0);
-}
-#endif
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index 235e89226112..7ac30612068b 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -291,7 +291,7 @@ uncached_mmap(struct file *file, struct vm_area_struct *vma)
return mspec_mmap(file, vma, MSPEC_UNCACHED);
}
-static struct file_operations fetchop_fops = {
+static const struct file_operations fetchop_fops = {
.owner = THIS_MODULE,
.mmap = fetchop_mmap
};
@@ -302,7 +302,7 @@ static struct miscdevice fetchop_miscdev = {
.fops = &fetchop_fops
};
-static struct file_operations cached_fops = {
+static const struct file_operations cached_fops = {
.owner = THIS_MODULE,
.mmap = cached_mmap
};
@@ -313,7 +313,7 @@ static struct miscdevice cached_miscdev = {
.fops = &cached_fops
};
-static struct file_operations uncached_fops = {
+static const struct file_operations uncached_fops = {
.owner = THIS_MODULE,
.mmap = uncached_mmap
};
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 83f604b19290..a61fb6da5d03 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -321,8 +321,6 @@ struct mxser_struct {
unsigned long event;
int count; /* # of fd on device */
int blocked_open; /* # of blocked opens */
- long session; /* Session of opening process */
- long pgrp; /* pgrp of opening process */
unsigned char *xmit_buf;
int xmit_head;
int xmit_tail;
@@ -1001,15 +999,12 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
mxser_change_speed(info, NULL);
}
- info->session = process_session(current);
- info->pgrp = process_group(current);
-
/*
status = mxser_get_msr(info->base, 0, info->port);
mxser_check_modem_status(info, status);
*/
-/* unmark here for very high baud rate (ex. 921600 bps) used */
+ /* unmark here for very high baud rate (ex. 921600 bps) used */
tty->low_latency = 1;
return 0;
}
@@ -1254,9 +1249,7 @@ static void mxser_flush_buffer(struct tty_struct *tty)
spin_unlock_irqrestore(&info->slock, flags);
/* above added by shinhay */
- wake_up_interruptible(&tty->write_wait);
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup) (tty);
+ tty_wakeup(tty);
}
static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
diff --git a/drivers/char/mxser.h b/drivers/char/mxser.h
index 7e188a4d602a..9fe28497eae9 100644
--- a/drivers/char/mxser.h
+++ b/drivers/char/mxser.h
@@ -439,12 +439,4 @@
#define READ_MOXA_MUST_GDL(baseio) inb((baseio)+MOXA_MUST_GDL_REGISTER)
-
-#ifndef INIT_WORK
-#define INIT_WORK(_work, _func, _data){ \
- _data->tqueue.routine = _func;\
- _data->tqueue.data = _data;\
- }
-#endif
-
#endif
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index 1bb030b3a51a..9af07e4999d5 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -49,22 +49,25 @@
#include "mxser_new.h"
-#define MXSER_VERSION "2.0"
+#define MXSER_VERSION "2.0.1" /* 1.9.15 */
#define MXSERMAJOR 174
#define MXSERCUMAJOR 175
-#define MXSER_EVENT_TXLOW 1
-
#define MXSER_BOARDS 4 /* Max. boards */
#define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */
#define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD)
-#define MXSER_ISR_PASS_LIMIT 99999L
+#define MXSER_ISR_PASS_LIMIT 100
#define MXSER_ERR_IOADDR -1
#define MXSER_ERR_IRQ -2
#define MXSER_ERR_IRQ_CONFLIT -3
#define MXSER_ERR_VECTOR -4
+/*CheckIsMoxaMust return value*/
+#define MOXA_OTHER_UART 0x00
+#define MOXA_MUST_MU150_HWID 0x01
+#define MOXA_MUST_MU860_HWID 0x02
+
#define WAKEUP_CHARS 256
#define UART_MCR_AFE 0x20
@@ -176,6 +179,18 @@ static struct pci_device_id mxser_pcibrds[] = {
};
MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
+static int mxvar_baud_table[] = {
+ 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
+ 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
+};
+static unsigned int mxvar_baud_table1[] = {
+ 0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400,
+ B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B921600
+};
+#define BAUD_TABLE_NO ARRAY_SIZE(mxvar_baud_table)
+
+#define B_SPEC B2000000
+
static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 };
static int ttymajor = MXSERMAJOR;
static int calloutmajor = MXSERCUMAJOR;
@@ -237,8 +252,7 @@ struct mxser_port {
long realbaud;
int type; /* UART type */
int flags; /* defined in tty.h */
- long session; /* Session of opening process */
- long pgrp; /* pgrp of opening process */
+ int speed;
int x_char; /* xon/xoff character */
int IER; /* Interrupt Enable Register */
@@ -267,14 +281,11 @@ struct mxser_port {
int xmit_cnt;
struct ktermios normal_termios;
- struct ktermios callout_termios;
struct mxser_mon mon_data;
spinlock_t slock;
- struct work_struct tqueue;
wait_queue_head_t open_wait;
- wait_queue_head_t close_wait;
wait_queue_head_t delta_msr_wait;
};
@@ -313,10 +324,9 @@ static int mxvar_diagflag;
static unsigned char mxser_msr[MXSER_PORTS + 1];
static struct mxser_mon_ext mon_data_ext;
static int mxser_set_baud_method[MXSER_PORTS + 1];
-static spinlock_t gm_lock;
#ifdef CONFIG_PCI
-static int CheckIsMoxaMust(int io)
+static int __devinit CheckIsMoxaMust(int io)
{
u8 oldmcr, hwid;
int i;
@@ -360,15 +370,6 @@ static void process_txrx_fifo(struct mxser_port *info)
}
}
-static void mxser_do_softint(struct work_struct *work)
-{
- struct mxser_port *info = container_of(work, struct mxser_port, tqueue);
- struct tty_struct *tty = info->tty;
-
- if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event))
- tty_wakeup(tty);
-}
-
static unsigned char mxser_get_msr(int baseaddr, int mode, int port)
{
unsigned char status = 0;
@@ -456,10 +457,10 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
static int mxser_set_baud(struct mxser_port *info, long newspd)
{
+ unsigned int i;
int quot = 0;
unsigned char cval;
int ret = 0;
- unsigned long flags;
if (!info->tty || !info->tty->termios)
return ret;
@@ -471,29 +472,34 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
return 0;
info->realbaud = newspd;
- if (newspd == 134) {
- quot = (2 * info->baud_base / 269);
- } else if (newspd) {
- quot = info->baud_base / newspd;
- if (quot == 0)
- quot = 1;
+ for (i = 0; i < BAUD_TABLE_NO; i++)
+ if (newspd == mxvar_baud_table[i])
+ break;
+ if (i == BAUD_TABLE_NO) {
+ quot = info->baud_base / info->speed;
+ if (info->speed <= 0 || info->speed > info->max_baud)
+ quot = 0;
} else {
- quot = 0;
+ if (newspd == 134) {
+ quot = (2 * info->baud_base / 269);
+ } else if (newspd) {
+ quot = info->baud_base / newspd;
+ if (quot == 0)
+ quot = 1;
+ } else {
+ quot = 0;
+ }
}
info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base);
info->timeout += HZ / 50; /* Add .02 seconds of slop */
if (quot) {
- spin_lock_irqsave(&info->slock, flags);
info->MCR |= UART_MCR_DTR;
outb(info->MCR, info->ioaddr + UART_MCR);
- spin_unlock_irqrestore(&info->slock, flags);
} else {
- spin_lock_irqsave(&info->slock, flags);
info->MCR &= ~UART_MCR_DTR;
outb(info->MCR, info->ioaddr + UART_MCR);
- spin_unlock_irqrestore(&info->slock, flags);
return ret;
}
@@ -505,6 +511,18 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
outb(quot >> 8, info->ioaddr + UART_DLM); /* MS of divisor */
outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */
+ if (i == BAUD_TABLE_NO) {
+ quot = info->baud_base % info->speed;
+ quot *= 8;
+ if ((quot % info->speed) > (info->speed / 2)) {
+ quot /= info->speed;
+ quot++;
+ } else {
+ quot /= info->speed;
+ }
+ SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, quot);
+ } else
+ SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, 0);
return ret;
}
@@ -520,7 +538,6 @@ static int mxser_change_speed(struct mxser_port *info,
int ret = 0;
unsigned char status;
long baud;
- unsigned long flags;
if (!info->tty || !info->tty->termios)
return ret;
@@ -529,7 +546,10 @@ static int mxser_change_speed(struct mxser_port *info,
return ret;
if (mxser_set_baud_method[info->tty->index] == 0) {
- baud = tty_get_baud_rate(info->tty);
+ if ((cflag & CBAUD) == B_SPEC)
+ baud = info->speed;
+ else
+ baud = tty_get_baud_rate(info->tty);
mxser_set_baud(info, baud);
}
@@ -612,8 +632,8 @@ static int mxser_change_speed(struct mxser_port *info,
outb(info->IER, info->ioaddr +
UART_IER);
}
- set_bit(MXSER_EVENT_TXLOW, &info->event);
- schedule_work(&info->tqueue); }
+ tty_wakeup(info->tty);
+ }
} else {
if (!(status & UART_MSR_CTS)) {
info->tty->hw_stopped = 1;
@@ -668,7 +688,6 @@ static int mxser_change_speed(struct mxser_port *info,
}
}
if (info->board->chip_flag) {
- spin_lock_irqsave(&info->slock, flags);
SET_MOXA_MUST_XON1_VALUE(info->ioaddr, START_CHAR(info->tty));
SET_MOXA_MUST_XOFF1_VALUE(info->ioaddr, STOP_CHAR(info->tty));
if (I_IXON(info->tty)) {
@@ -681,7 +700,6 @@ static int mxser_change_speed(struct mxser_port *info,
} else {
DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr);
}
- spin_unlock_irqrestore(&info->slock, flags);
}
@@ -708,7 +726,6 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
if (status & UART_MSR_DCD)
wake_up_interruptible(&port->open_wait);
- schedule_work(&port->tqueue);
}
if (port->flags & ASYNC_CTS_FLOW) {
@@ -724,8 +741,7 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
outb(port->IER, port->ioaddr +
UART_IER);
}
- set_bit(MXSER_EVENT_TXLOW, &port->event);
- schedule_work(&port->tqueue);
+ tty_wakeup(port->tty);
}
} else {
if (!(status & UART_MSR_CTS)) {
@@ -836,10 +852,10 @@ static int mxser_startup(struct mxser_port *info)
/*
* and set the speed of the serial port
*/
- spin_unlock_irqrestore(&info->slock, flags);
mxser_change_speed(info, NULL);
-
info->flags |= ASYNC_INITIALIZED;
+ spin_unlock_irqrestore(&info->slock, flags);
+
return 0;
}
@@ -909,11 +925,9 @@ static void mxser_shutdown(struct mxser_port *info)
static int mxser_open(struct tty_struct *tty, struct file *filp)
{
struct mxser_port *info;
+ unsigned long flags;
int retval, line;
- /* initialize driver_data in case something fails */
- tty->driver_data = NULL;
-
line = tty->index;
if (line == MXSER_PORTS)
return 0;
@@ -928,7 +942,9 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
/*
* Start up serial port
*/
+ spin_lock_irqsave(&info->slock, flags);
info->count++;
+ spin_unlock_irqrestore(&info->slock, flags);
retval = mxser_startup(info);
if (retval)
return retval;
@@ -937,17 +953,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
if (retval)
return retval;
- if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
- if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
- *tty->termios = info->normal_termios;
- else
- *tty->termios = info->callout_termios;
- mxser_change_speed(info, NULL);
- }
-
- info->session = process_session(current);
- info->pgrp = process_group(current);
-
/* unmark here for very high baud rate (ex. 921600 bps) used */
tty->low_latency = 1;
return 0;
@@ -1054,8 +1059,6 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
}
info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
-
}
static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1222,6 +1225,7 @@ static int mxser_set_serial_info(struct mxser_port *info,
struct serial_struct __user *new_info)
{
struct serial_struct new_serial;
+ unsigned long sl_flags;
unsigned int flags;
int retval = 0;
@@ -1264,8 +1268,11 @@ static int mxser_set_serial_info(struct mxser_port *info,
process_txrx_fifo(info);
if (info->flags & ASYNC_INITIALIZED) {
- if (flags != (info->flags & ASYNC_SPD_MASK))
+ if (flags != (info->flags & ASYNC_SPD_MASK)) {
+ spin_lock_irqsave(&info->slock, sl_flags);
mxser_change_speed(info, NULL);
+ spin_unlock_irqrestore(&info->slock, sl_flags);
+ }
} else
retval = mxser_startup(info);
@@ -1373,11 +1380,10 @@ static int mxser_tiocmset(struct tty_struct *tty, struct file *file,
return 0;
}
-static int mxser_program_mode(int port)
+static int __init mxser_program_mode(int port)
{
int id, i, j, n;
- spin_lock(&gm_lock);
outb(0, port);
outb(0, port);
outb(0, port);
@@ -1385,7 +1391,6 @@ static int mxser_program_mode(int port)
(void)inb(port);
outb(0, port);
(void)inb(port);
- spin_unlock(&gm_lock);
id = inb(port + 1) & 0x1F;
if ((id != C168_ASIC_ID) &&
@@ -1410,7 +1415,7 @@ static int mxser_program_mode(int port)
return id;
}
-static void mxser_normal_mode(int port)
+static void __init mxser_normal_mode(int port)
{
int i, n;
@@ -1443,7 +1448,7 @@ static void mxser_normal_mode(int port)
#define EN0_PORT 0x010 /* Rcv missed frame error counter RD */
#define ENC_PAGE0 0x000 /* Select page 0 of chip registers */
#define ENC_PAGE3 0x0C0 /* Select page 3 of chip registers */
-static int mxser_read_register(int port, unsigned short *regs)
+static int __init mxser_read_register(int port, unsigned short *regs)
{
int i, k, value, id;
unsigned int j;
@@ -1644,6 +1649,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
struct serial_icounter_struct __user *p_cuser;
unsigned long templ;
unsigned long flags;
+ unsigned int i;
void __user *argp = (void __user *)arg;
int retval;
@@ -1682,6 +1688,36 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
return 0;
}
+ if (cmd == MOXA_SET_SPECIAL_BAUD_RATE) {
+ int speed;
+
+ if (get_user(speed, (int __user *)argp))
+ return -EFAULT;
+ if (speed <= 0 || speed > info->max_baud)
+ return -EFAULT;
+ if (!info->tty || !info->tty->termios || !info->ioaddr)
+ return 0;
+ info->tty->termios->c_cflag &= ~(CBAUD | CBAUDEX);
+ for (i = 0; i < BAUD_TABLE_NO; i++)
+ if (speed == mxvar_baud_table[i])
+ break;
+ if (i == BAUD_TABLE_NO) {
+ info->tty->termios->c_cflag |= B_SPEC;
+ } else if (speed != 0)
+ info->tty->termios->c_cflag |= mxvar_baud_table1[i];
+
+ info->speed = speed;
+ spin_lock_irqsave(&info->slock, flags);
+ mxser_change_speed(info, NULL);
+ spin_unlock_irqrestore(&info->slock, flags);
+
+ return 0;
+ } else if (cmd == MOXA_GET_SPECIAL_BAUD_RATE) {
+ if (copy_to_user(argp, &info->speed, sizeof(int)))
+ return -EFAULT;
+ return 0;
+ }
+
if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT &&
test_bit(TTY_IO_ERROR, &tty->flags))
return -EIO;
@@ -1799,7 +1835,9 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
long baud;
if (get_user(baud, (long __user *)argp))
return -EFAULT;
+ spin_lock_irqsave(&info->slock, flags);
mxser_set_baud(info, baud);
+ spin_unlock_irqrestore(&info->slock, flags);
return 0;
}
case MOXA_ASPP_GETBAUD:
@@ -1976,7 +2014,9 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi
if ((tty->termios->c_cflag != old_termios->c_cflag) ||
(RELEVANT_IFLAG(tty->termios->c_iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) {
+ spin_lock_irqsave(&info->slock, flags);
mxser_change_speed(info, old_termios);
+ spin_unlock_irqrestore(&info->slock, flags);
if ((old_termios->c_cflag & CRTSCTS) &&
!(tty->termios->c_cflag & CRTSCTS)) {
@@ -2066,7 +2106,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
/*
* This routine is called by tty_hangup() when a hangup is signaled.
*/
-void mxser_hangup(struct tty_struct *tty)
+static void mxser_hangup(struct tty_struct *tty)
{
struct mxser_port *info = tty->driver_data;
@@ -2105,9 +2145,6 @@ static void mxser_receive_chars(struct mxser_port *port, int *status)
int cnt = 0;
int recv_room;
int max = 256;
- unsigned long flags;
-
- spin_lock_irqsave(&port->slock, flags);
recv_room = tty->receive_room;
if ((recv_room == 0) && (!port->ldisc_stop_rx))
@@ -2169,7 +2206,8 @@ intr_old:
} else if (*status & UART_LSR_OE) {
flag = TTY_OVERRUN;
port->icount.overrun++;
- }
+ } else
+ flag = TTY_BREAK;
}
tty_insert_flip_char(tty, ch, flag);
cnt++;
@@ -2191,7 +2229,6 @@ end_intr:
mxvar_log.rxcnt[port->tty->index] += cnt;
port->mon_data.rxcnt += cnt;
port->mon_data.up_rxcnt += cnt;
- spin_unlock_irqrestore(&port->slock, flags);
tty_flip_buffer_push(tty);
}
@@ -2199,9 +2236,6 @@ end_intr:
static void mxser_transmit_chars(struct mxser_port *port)
{
int count, cnt;
- unsigned long flags;
-
- spin_lock_irqsave(&port->slock, flags);
if (port->x_char) {
outb(port->x_char, port->ioaddr + UART_TX);
@@ -2210,11 +2244,11 @@ static void mxser_transmit_chars(struct mxser_port *port)
port->mon_data.txcnt++;
port->mon_data.up_txcnt++;
port->icount.tx++;
- goto unlock;
+ return;
}
if (port->xmit_buf == 0)
- goto unlock;
+ return;
if ((port->xmit_cnt <= 0) || port->tty->stopped ||
(port->tty->hw_stopped &&
@@ -2222,7 +2256,7 @@ static void mxser_transmit_chars(struct mxser_port *port)
(!port->board->chip_flag))) {
port->IER &= ~UART_IER_THRI;
outb(port->IER, port->ioaddr + UART_IER);
- goto unlock;
+ return;
}
cnt = port->xmit_cnt;
@@ -2240,16 +2274,13 @@ static void mxser_transmit_chars(struct mxser_port *port)
port->mon_data.up_txcnt += (cnt - port->xmit_cnt);
port->icount.tx += (cnt - port->xmit_cnt);
- if (port->xmit_cnt < WAKEUP_CHARS) {
- set_bit(MXSER_EVENT_TXLOW, &port->event);
- schedule_work(&port->tqueue);
- }
+ if (port->xmit_cnt < WAKEUP_CHARS)
+ tty_wakeup(port->tty);
+
if (port->xmit_cnt <= 0) {
port->IER &= ~UART_IER_THRI;
outb(port->IER, port->ioaddr + UART_IER);
}
-unlock:
- spin_unlock_irqrestore(&port->slock, flags);
}
/*
@@ -2261,8 +2292,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
struct mxser_board *brd = NULL;
struct mxser_port *port;
int max, irqbits, bits, msr;
- int pass_counter = 0;
- unsigned int int_cnt;
+ unsigned int int_cnt, pass_counter = 0;
int handled = IRQ_NONE;
for (i = 0; i < MXSER_BOARDS; i++)
@@ -2276,7 +2306,7 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
if (brd == NULL)
goto irq_stop;
max = brd->info->nports;
- while (1) {
+ while (pass_counter++ < MXSER_ISR_PASS_LIMIT) {
irqbits = inb(brd->vector) & brd->vector_mask;
if (irqbits == brd->vector_mask)
break;
@@ -2290,12 +2320,16 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
port = &brd->ports[i];
int_cnt = 0;
+ spin_lock(&port->slock);
do {
iir = inb(port->ioaddr + UART_IIR);
if (iir & UART_IIR_NO_INT)
break;
iir &= MOXA_MUST_IIR_MASK;
- if (!port->tty) {
+ if (!port->tty ||
+ (port->flags & ASYNC_CLOSING) ||
+ !(port->flags &
+ ASYNC_INITIALIZED)) {
status = inb(port->ioaddr + UART_LSR);
outb(0x27, port->ioaddr + UART_FCR);
inb(port->ioaddr + UART_MSR);
@@ -2341,9 +2375,8 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
mxser_transmit_chars(port);
}
} while (int_cnt++ < MXSER_ISR_PASS_LIMIT);
+ spin_unlock(&port->slock);
}
- if (pass_counter++ > MXSER_ISR_PASS_LIMIT)
- break; /* Prevent infinite loops */
}
irq_stop:
@@ -2385,7 +2418,6 @@ static void mxser_release_res(struct mxser_board *brd, struct pci_dev *pdev,
#ifdef CONFIG_PCI
pci_release_region(pdev, 2);
pci_release_region(pdev, 3);
- pci_dev_put(pdev);
#endif
} else {
release_region(brd->ports[0].ioaddr, 8 * brd->info->nports);
@@ -2420,11 +2452,10 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
info->custom_divisor = info->baud_base * 16;
info->close_delay = 5 * HZ / 10;
info->closing_wait = 30 * HZ;
- INIT_WORK(&info->tqueue, mxser_do_softint);
info->normal_termios = mxvar_sdriver->init_termios;
init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
init_waitqueue_head(&info->delta_msr_wait);
+ info->speed = 9600;
memset(&info->mon_data, 0, sizeof(struct mxser_mon));
info->err_shadow = 0;
spin_lock_init(&info->slock);
@@ -2433,22 +2464,17 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
outb(inb(info->ioaddr + UART_IER) & 0xf0,
info->ioaddr + UART_IER);
}
- /*
- * Allocate the IRQ if necessary
- */
- retval = request_irq(brd->irq, mxser_interrupt,
- (brd->ports[0].flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED :
- IRQF_DISABLED, "mxser", brd);
+ retval = request_irq(brd->irq, mxser_interrupt, IRQF_SHARED, "mxser",
+ brd);
if (retval) {
printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may "
"conflict with another device.\n",
brd->info->name, brd->irq);
/* We hold resources, we need to release them. */
mxser_release_res(brd, pdev, 0);
- return retval;
}
- return 0;
+ return retval;
}
static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd)
@@ -2633,8 +2659,9 @@ static int __devinit mxser_probe(struct pci_dev *pdev,
}
/* mxser_initbrd will hook ISR. */
- if (mxser_initbrd(brd, pdev) < 0)
- goto err_relvec;
+ retval = mxser_initbrd(brd, pdev);
+ if (retval)
+ goto err_null;
for (i = 0; i < brd->info->nports; i++)
tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev);
@@ -2642,10 +2669,9 @@ static int __devinit mxser_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, brd);
return 0;
-err_relvec:
- pci_release_region(pdev, 3);
err_relio:
pci_release_region(pdev, 2);
+err_null:
brd->info = NULL;
err:
return retval;
@@ -2663,6 +2689,7 @@ static void __devexit mxser_remove(struct pci_dev *pdev)
tty_unregister_device(mxvar_sdriver, brd->idx + i);
mxser_release_res(brd, pdev, 1);
+ brd->info = NULL;
}
static struct pci_driver mxser_driver = {
@@ -2684,7 +2711,6 @@ static int __init mxser_module_init(void)
mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1);
if (!mxvar_sdriver)
return -ENOMEM;
- spin_lock_init(&gm_lock);
printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n",
MXSER_VERSION);
diff --git a/drivers/char/mxser_new.h b/drivers/char/mxser_new.h
index a08f0ecb09ba..d42f7766c652 100644
--- a/drivers/char/mxser_new.h
+++ b/drivers/char/mxser_new.h
@@ -26,18 +26,8 @@
#define RS422_MODE 2
#define RS485_4WIRE_MODE 3
#define OP_MODE_MASK 3
-// above add by Victor Yu. 01-05-2004
-
-#define TTY_THRESHOLD_THROTTLE 128
-
-#define LO_WATER (TTY_FLIPBUF_SIZE)
-#define HI_WATER (TTY_FLIPBUF_SIZE*2*3/4)
-
-// added by James. 03-11-2004.
-#define MOXA_SDS_GETICOUNTER (MOXA + 68)
-#define MOXA_SDS_RSTICOUNTER (MOXA + 69)
-// (above) added by James.
+#define MOXA_SDS_RSTICOUNTER (MOXA + 69)
#define MOXA_ASPP_OQUEUE (MOXA + 70)
#define MOXA_ASPP_SETBAUD (MOXA + 71)
#define MOXA_ASPP_GETBAUD (MOXA + 72)
@@ -45,7 +35,8 @@
#define MOXA_ASPP_LSTATUS (MOXA + 74)
#define MOXA_ASPP_MON_EXT (MOXA + 75)
#define MOXA_SET_BAUD_METHOD (MOXA + 76)
-
+#define MOXA_SET_SPECIAL_BAUD_RATE (MOXA + 77)
+#define MOXA_GET_SPECIAL_BAUD_RATE (MOXA + 78)
/* --------------------------------------------------- */
@@ -55,51 +46,46 @@
#define NPPI_NOTIFY_SW_OVERRUN 0x08
#define NPPI_NOTIFY_BREAK 0x10
-#define NPPI_NOTIFY_CTSHOLD 0x01 // Tx hold by CTS low
-#define NPPI_NOTIFY_DSRHOLD 0x02 // Tx hold by DSR low
-#define NPPI_NOTIFY_XOFFHOLD 0x08 // Tx hold by Xoff received
-#define NPPI_NOTIFY_XOFFXENT 0x10 // Xoff Sent
-
-//CheckIsMoxaMust return value
-#define MOXA_OTHER_UART 0x00
-#define MOXA_MUST_MU150_HWID 0x01
-#define MOXA_MUST_MU860_HWID 0x02
-
-// follow just for Moxa Must chip define.
-//
-// when LCR register (offset 0x03) write following value,
-// the Must chip will enter enchance mode. And write value
-// on EFR (offset 0x02) bit 6,7 to change bank.
+#define NPPI_NOTIFY_CTSHOLD 0x01 /* Tx hold by CTS low */
+#define NPPI_NOTIFY_DSRHOLD 0x02 /* Tx hold by DSR low */
+#define NPPI_NOTIFY_XOFFHOLD 0x08 /* Tx hold by Xoff received */
+#define NPPI_NOTIFY_XOFFXENT 0x10 /* Xoff Sent */
+
+/* follow just for Moxa Must chip define. */
+/* */
+/* when LCR register (offset 0x03) write following value, */
+/* the Must chip will enter enchance mode. And write value */
+/* on EFR (offset 0x02) bit 6,7 to change bank. */
#define MOXA_MUST_ENTER_ENCHANCE 0xBF
-// when enhance mode enable, access on general bank register
+/* when enhance mode enable, access on general bank register */
#define MOXA_MUST_GDL_REGISTER 0x07
#define MOXA_MUST_GDL_MASK 0x7F
#define MOXA_MUST_GDL_HAS_BAD_DATA 0x80
-#define MOXA_MUST_LSR_RERR 0x80 // error in receive FIFO
-// enchance register bank select and enchance mode setting register
-// when LCR register equal to 0xBF
+#define MOXA_MUST_LSR_RERR 0x80 /* error in receive FIFO */
+/* enchance register bank select and enchance mode setting register */
+/* when LCR register equal to 0xBF */
#define MOXA_MUST_EFR_REGISTER 0x02
-// enchance mode enable
+/* enchance mode enable */
#define MOXA_MUST_EFR_EFRB_ENABLE 0x10
-// enchance reister bank set 0, 1, 2
+/* enchance reister bank set 0, 1, 2 */
#define MOXA_MUST_EFR_BANK0 0x00
#define MOXA_MUST_EFR_BANK1 0x40
#define MOXA_MUST_EFR_BANK2 0x80
#define MOXA_MUST_EFR_BANK3 0xC0
#define MOXA_MUST_EFR_BANK_MASK 0xC0
-// set XON1 value register, when LCR=0xBF and change to bank0
+/* set XON1 value register, when LCR=0xBF and change to bank0 */
#define MOXA_MUST_XON1_REGISTER 0x04
-// set XON2 value register, when LCR=0xBF and change to bank0
+/* set XON2 value register, when LCR=0xBF and change to bank0 */
#define MOXA_MUST_XON2_REGISTER 0x05
-// set XOFF1 value register, when LCR=0xBF and change to bank0
+/* set XOFF1 value register, when LCR=0xBF and change to bank0 */
#define MOXA_MUST_XOFF1_REGISTER 0x06
-// set XOFF2 value register, when LCR=0xBF and change to bank0
+/* set XOFF2 value register, when LCR=0xBF and change to bank0 */
#define MOXA_MUST_XOFF2_REGISTER 0x07
#define MOXA_MUST_RBRTL_REGISTER 0x04
@@ -111,32 +97,32 @@
#define MOXA_MUST_ECR_REGISTER 0x06
#define MOXA_MUST_CSR_REGISTER 0x07
-// good data mode enable
+/* good data mode enable */
#define MOXA_MUST_FCR_GDA_MODE_ENABLE 0x20
-// only good data put into RxFIFO
+/* only good data put into RxFIFO */
#define MOXA_MUST_FCR_GDA_ONLY_ENABLE 0x10
-// enable CTS interrupt
+/* enable CTS interrupt */
#define MOXA_MUST_IER_ECTSI 0x80
-// enable RTS interrupt
+/* enable RTS interrupt */
#define MOXA_MUST_IER_ERTSI 0x40
-// enable Xon/Xoff interrupt
+/* enable Xon/Xoff interrupt */
#define MOXA_MUST_IER_XINT 0x20
-// enable GDA interrupt
+/* enable GDA interrupt */
#define MOXA_MUST_IER_EGDAI 0x10
#define MOXA_MUST_RECV_ISR (UART_IER_RDI | MOXA_MUST_IER_EGDAI)
-// GDA interrupt pending
+/* GDA interrupt pending */
#define MOXA_MUST_IIR_GDA 0x1C
#define MOXA_MUST_IIR_RDA 0x04
#define MOXA_MUST_IIR_RTO 0x0C
#define MOXA_MUST_IIR_LSR 0x06
-// recieved Xon/Xoff or specical interrupt pending
+/* recieved Xon/Xoff or specical interrupt pending */
#define MOXA_MUST_IIR_XSC 0x10
-// RTS/CTS change state interrupt pending
+/* RTS/CTS change state interrupt pending */
#define MOXA_MUST_IIR_RTSCTS 0x20
#define MOXA_MUST_IIR_MASK 0x3E
@@ -144,307 +130,164 @@
#define MOXA_MUST_MCR_XON_ANY 0x80
#define MOXA_MUST_MCR_TX_XON 0x08
-
-// software flow control on chip mask value
+/* software flow control on chip mask value */
#define MOXA_MUST_EFR_SF_MASK 0x0F
-// send Xon1/Xoff1
+/* send Xon1/Xoff1 */
#define MOXA_MUST_EFR_SF_TX1 0x08
-// send Xon2/Xoff2
+/* send Xon2/Xoff2 */
#define MOXA_MUST_EFR_SF_TX2 0x04
-// send Xon1,Xon2/Xoff1,Xoff2
+/* send Xon1,Xon2/Xoff1,Xoff2 */
#define MOXA_MUST_EFR_SF_TX12 0x0C
-// don't send Xon/Xoff
+/* don't send Xon/Xoff */
#define MOXA_MUST_EFR_SF_TX_NO 0x00
-// Tx software flow control mask
+/* Tx software flow control mask */
#define MOXA_MUST_EFR_SF_TX_MASK 0x0C
-// don't receive Xon/Xoff
+/* don't receive Xon/Xoff */
#define MOXA_MUST_EFR_SF_RX_NO 0x00
-// receive Xon1/Xoff1
+/* receive Xon1/Xoff1 */
#define MOXA_MUST_EFR_SF_RX1 0x02
-// receive Xon2/Xoff2
+/* receive Xon2/Xoff2 */
#define MOXA_MUST_EFR_SF_RX2 0x01
-// receive Xon1,Xon2/Xoff1,Xoff2
+/* receive Xon1,Xon2/Xoff1,Xoff2 */
#define MOXA_MUST_EFR_SF_RX12 0x03
-// Rx software flow control mask
+/* Rx software flow control mask */
#define MOXA_MUST_EFR_SF_RX_MASK 0x03
-//#define MOXA_MUST_MIN_XOFFLIMIT 66
-//#define MOXA_MUST_MIN_XONLIMIT 20
-//#define ID1_RX_TRIG 120
-
-
-#define CHECK_MOXA_MUST_XOFFLIMIT(info) { \
- if ( (info)->IsMoxaMustChipFlag && \
- (info)->HandFlow.XoffLimit < MOXA_MUST_MIN_XOFFLIMIT ) { \
- (info)->HandFlow.XoffLimit = MOXA_MUST_MIN_XOFFLIMIT; \
- (info)->HandFlow.XonLimit = MOXA_MUST_MIN_XONLIMIT; \
- } \
-}
-
-#define ENABLE_MOXA_MUST_ENCHANCE_MODE(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+#define ENABLE_MOXA_MUST_ENCHANCE_MODE(baseio) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr |= MOXA_MUST_EFR_EFRB_ENABLE; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define DISABLE_MOXA_MUST_ENCHANCE_MODE(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr |= MOXA_MUST_EFR_EFRB_ENABLE; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
+
+#define DISABLE_MOXA_MUST_ENCHANCE_MODE(baseio) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define SET_MOXA_MUST_XON1_VALUE(baseio, Value) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
+
+#define SET_MOXA_MUST_XON1_VALUE(baseio, Value) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK0; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
+ __efr |= MOXA_MUST_EFR_BANK0; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
outb((u8)(Value), (baseio)+MOXA_MUST_XON1_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
-#define SET_MOXA_MUST_XON2_VALUE(baseio, Value) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+#define SET_MOXA_MUST_XOFF1_VALUE(baseio, Value) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK0; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb((u8)(Value), (baseio)+MOXA_MUST_XON2_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define SET_MOXA_MUST_XOFF1_VALUE(baseio, Value) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK0; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
+ __efr |= MOXA_MUST_EFR_BANK0; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
outb((u8)(Value), (baseio)+MOXA_MUST_XOFF1_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
-#define SET_MOXA_MUST_XOFF2_VALUE(baseio, Value) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK0; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb((u8)(Value), (baseio)+MOXA_MUST_XOFF2_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define SET_MOXA_MUST_RBRTL_VALUE(baseio, Value) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK1; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb((u8)(Value), (baseio)+MOXA_MUST_RBRTL_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define SET_MOXA_MUST_RBRTH_VALUE(baseio, Value) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK1; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb((u8)(Value), (baseio)+MOXA_MUST_RBRTH_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define SET_MOXA_MUST_RBRTI_VALUE(baseio, Value) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK1; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb((u8)(Value), (baseio)+MOXA_MUST_RBRTI_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define SET_MOXA_MUST_THRTL_VALUE(baseio, Value) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK1; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb((u8)(Value), (baseio)+MOXA_MUST_THRTL_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-//#define MOXA_MUST_RBRL_VALUE 4
-#define SET_MOXA_MUST_FIFO_VALUE(info) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((info)->ioaddr+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (info)->ioaddr+UART_LCR); \
+#define SET_MOXA_MUST_FIFO_VALUE(info) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((info)->ioaddr+UART_LCR); \
+ outb(MOXA_MUST_ENTER_ENCHANCE, (info)->ioaddr+UART_LCR);\
__efr = inb((info)->ioaddr+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK1; \
+ __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
+ __efr |= MOXA_MUST_EFR_BANK1; \
outb(__efr, (info)->ioaddr+MOXA_MUST_EFR_REGISTER); \
- outb((u8)((info)->rx_high_water), (info)->ioaddr+MOXA_MUST_RBRTH_REGISTER); \
- outb((u8)((info)->rx_trigger), (info)->ioaddr+MOXA_MUST_RBRTI_REGISTER); \
- outb((u8)((info)->rx_low_water), (info)->ioaddr+MOXA_MUST_RBRTL_REGISTER); \
- outb(__oldlcr, (info)->ioaddr+UART_LCR); \
-}
-
-
-
-#define SET_MOXA_MUST_ENUM_VALUE(baseio, Value) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+ outb((u8)((info)->rx_high_water), (info)->ioaddr+ \
+ MOXA_MUST_RBRTH_REGISTER); \
+ outb((u8)((info)->rx_trigger), (info)->ioaddr+ \
+ MOXA_MUST_RBRTI_REGISTER); \
+ outb((u8)((info)->rx_low_water), (info)->ioaddr+ \
+ MOXA_MUST_RBRTL_REGISTER); \
+ outb(__oldlcr, (info)->ioaddr+UART_LCR); \
+} while (0)
+
+#define SET_MOXA_MUST_ENUM_VALUE(baseio, Value) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK2; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
+ __efr |= MOXA_MUST_EFR_BANK2; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
outb((u8)(Value), (baseio)+MOXA_MUST_ENUM_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
-#define GET_MOXA_MUST_HARDWARE_ID(baseio, pId) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
- __efr |= MOXA_MUST_EFR_BANK2; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- *pId = inb((baseio)+MOXA_MUST_HWID_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_SF_MASK; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define SET_MOXA_MUST_JUST_TX_SOFTWARE_FLOW_CONTROL(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+#define GET_MOXA_MUST_HARDWARE_ID(baseio, pId) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_SF_MASK; \
- __efr |= MOXA_MUST_EFR_SF_TX1; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_BANK_MASK; \
+ __efr |= MOXA_MUST_EFR_BANK2; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ *pId = inb((baseio)+MOXA_MUST_HWID_REGISTER); \
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
+
+#define SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(baseio) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \
- __efr |= MOXA_MUST_EFR_SF_TX1; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_SF_MASK; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
+
+#define ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define SET_MOXA_MUST_JUST_RX_SOFTWARE_FLOW_CONTROL(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \
+ __efr |= MOXA_MUST_EFR_SF_TX1; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
+
+#define DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_SF_MASK; \
- __efr |= MOXA_MUST_EFR_SF_RX1; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
+
+#define ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \
- __efr |= MOXA_MUST_EFR_SF_RX1; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \
+ __efr |= MOXA_MUST_EFR_SF_RX1; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
+
+#define DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) do { \
+ u8 __oldlcr, __efr; \
+ __oldlcr = inb((baseio)+UART_LCR); \
outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define ENABLE_MOXA_MUST_TX_RX_SOFTWARE_FLOW_CONTROL(baseio) { \
- u8 __oldlcr, __efr; \
- __oldlcr = inb((baseio)+UART_LCR); \
- outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \
- __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
- __efr &= ~MOXA_MUST_EFR_SF_MASK; \
- __efr |= (MOXA_MUST_EFR_SF_RX1|MOXA_MUST_EFR_SF_TX1); \
- outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
- outb(__oldlcr, (baseio)+UART_LCR); \
-}
-
-#define ENABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(baseio) { \
- u8 __oldmcr; \
- __oldmcr = inb((baseio)+UART_MCR); \
- __oldmcr |= MOXA_MUST_MCR_XON_ANY; \
- outb(__oldmcr, (baseio)+UART_MCR); \
-}
-
-#define DISABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(baseio) { \
- u8 __oldmcr; \
- __oldmcr = inb((baseio)+UART_MCR); \
- __oldmcr &= ~MOXA_MUST_MCR_XON_ANY; \
- outb(__oldmcr, (baseio)+UART_MCR); \
-}
-
-#define READ_MOXA_MUST_GDL(baseio) inb((baseio)+MOXA_MUST_GDL_REGISTER)
-
-
-#ifndef INIT_WORK
-#define INIT_WORK(_work, _func, _data){ \
- _data->tqueue.routine = _func;\
- _data->tqueue.data = _data;\
- }
-#endif
+ __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \
+ __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \
+ outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \
+ outb(__oldlcr, (baseio)+UART_LCR); \
+} while (0)
#endif
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index dc6d41841457..65f2d3a96b85 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -60,62 +60,56 @@
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/errno.h>
-#include <linux/string.h> /* used in new tty drivers */
-#include <linux/signal.h> /* used in new tty drivers */
+#include <linux/string.h> /* used in new tty drivers */
+#include <linux/signal.h> /* used in new tty drivers */
#include <linux/ioctl.h>
#include <linux/n_r3964.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <asm/uaccess.h>
-
-//#define DEBUG_QUEUE
+/*#define DEBUG_QUEUE*/
/* Log successful handshake and protocol operations */
-//#define DEBUG_PROTO_S
+/*#define DEBUG_PROTO_S*/
/* Log handshake and protocol errors: */
-//#define DEBUG_PROTO_E
+/*#define DEBUG_PROTO_E*/
/* Log Linediscipline operations (open, close, read, write...): */
-//#define DEBUG_LDISC
+/*#define DEBUG_LDISC*/
/* Log module and memory operations (init, cleanup; kmalloc, kfree): */
-//#define DEBUG_MODUL
+/*#define DEBUG_MODUL*/
/* Macro helpers for debug output: */
-#define TRACE(format, args...) printk("r3964: " format "\n" , ## args);
+#define TRACE(format, args...) printk("r3964: " format "\n" , ## args)
#ifdef DEBUG_MODUL
-#define TRACE_M(format, args...) printk("r3964: " format "\n" , ## args);
+#define TRACE_M(format, args...) printk("r3964: " format "\n" , ## args)
#else
-#define TRACE_M(fmt, arg...) /**/
+#define TRACE_M(fmt, arg...) do {} while (0)
#endif
-
#ifdef DEBUG_PROTO_S
-#define TRACE_PS(format, args...) printk("r3964: " format "\n" , ## args);
+#define TRACE_PS(format, args...) printk("r3964: " format "\n" , ## args)
#else
-#define TRACE_PS(fmt, arg...) /**/
+#define TRACE_PS(fmt, arg...) do {} while (0)
#endif
-
#ifdef DEBUG_PROTO_E
-#define TRACE_PE(format, args...) printk("r3964: " format "\n" , ## args);
+#define TRACE_PE(format, args...) printk("r3964: " format "\n" , ## args)
#else
-#define TRACE_PE(fmt, arg...) /**/
+#define TRACE_PE(fmt, arg...) do {} while (0)
#endif
-
#ifdef DEBUG_LDISC
-#define TRACE_L(format, args...) printk("r3964: " format "\n" , ## args);
+#define TRACE_L(format, args...) printk("r3964: " format "\n" , ## args)
#else
-#define TRACE_L(fmt, arg...) /**/
+#define TRACE_L(fmt, arg...) do {} while (0)
#endif
-
#ifdef DEBUG_QUEUE
-#define TRACE_Q(format, args...) printk("r3964: " format "\n" , ## args);
+#define TRACE_Q(format, args...) printk("r3964: " format "\n" , ## args)
#else
-#define TRACE_Q(fmt, arg...) /**/
+#define TRACE_Q(fmt, arg...) do {} while (0)
#endif
-
static void add_tx_queue(struct r3964_info *, struct r3964_block_header *);
static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code);
static void put_char(struct r3964_info *pInfo, unsigned char ch);
@@ -126,937 +120,830 @@ static void receive_char(struct r3964_info *pInfo, const unsigned char c);
static void receive_error(struct r3964_info *pInfo, const char flag);
static void on_timeout(unsigned long priv);
static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg);
-static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf);
+static int read_telegram(struct r3964_info *pInfo, struct pid *pid,
+ unsigned char __user * buf);
static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
- int error_code, struct r3964_block_header *pBlock);
-static struct r3964_message* remove_msg(struct r3964_info *pInfo,
- struct r3964_client_info *pClient);
-static void remove_client_block(struct r3964_info *pInfo,
- struct r3964_client_info *pClient);
+ int error_code, struct r3964_block_header *pBlock);
+static struct r3964_message *remove_msg(struct r3964_info *pInfo,
+ struct r3964_client_info *pClient);
+static void remove_client_block(struct r3964_info *pInfo,
+ struct r3964_client_info *pClient);
-static int r3964_open(struct tty_struct *tty);
+static int r3964_open(struct tty_struct *tty);
static void r3964_close(struct tty_struct *tty);
static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
- unsigned char __user *buf, size_t nr);
-static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
- const unsigned char * buf, size_t nr);
-static int r3964_ioctl(struct tty_struct * tty, struct file * file,
- unsigned int cmd, unsigned long arg);
-static void r3964_set_termios(struct tty_struct *tty, struct ktermios * old);
-static unsigned int r3964_poll(struct tty_struct * tty, struct file * file,
- struct poll_table_struct *wait);
+ unsigned char __user * buf, size_t nr);
+static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
+ const unsigned char *buf, size_t nr);
+static int r3964_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old);
+static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
+ struct poll_table_struct *wait);
static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
- char *fp, int count);
+ char *fp, int count);
static struct tty_ldisc tty_ldisc_N_R3964 = {
- .owner = THIS_MODULE,
- .magic = TTY_LDISC_MAGIC,
- .name = "R3964",
- .open = r3964_open,
- .close = r3964_close,
- .read = r3964_read,
- .write = r3964_write,
- .ioctl = r3964_ioctl,
+ .owner = THIS_MODULE,
+ .magic = TTY_LDISC_MAGIC,
+ .name = "R3964",
+ .open = r3964_open,
+ .close = r3964_close,
+ .read = r3964_read,
+ .write = r3964_write,
+ .ioctl = r3964_ioctl,
.set_termios = r3964_set_termios,
- .poll = r3964_poll,
+ .poll = r3964_poll,
.receive_buf = r3964_receive_buf,
};
-
-
static void dump_block(const unsigned char *block, unsigned int length)
{
- unsigned int i,j;
- char linebuf[16*3+1];
-
- for(i=0;i<length;i+=16)
- {
- for(j=0;(j<16) && (j+i<length);j++)
- {
- sprintf(linebuf+3*j,"%02x ",block[i+j]);
- }
- linebuf[3*j]='\0';
- TRACE_PS("%s",linebuf);
- }
+ unsigned int i, j;
+ char linebuf[16 * 3 + 1];
+
+ for (i = 0; i < length; i += 16) {
+ for (j = 0; (j < 16) && (j + i < length); j++) {
+ sprintf(linebuf + 3 * j, "%02x ", block[i + j]);
+ }
+ linebuf[3 * j] = '\0';
+ TRACE_PS("%s", linebuf);
+ }
}
-
-
-
/*************************************************************
* Driver initialisation
*************************************************************/
-
/*************************************************************
* Module support routines
*************************************************************/
static void __exit r3964_exit(void)
{
- int status;
-
- TRACE_M ("cleanup_module()");
-
- status=tty_unregister_ldisc(N_R3964);
-
- if(status!=0)
- {
- printk(KERN_ERR "r3964: error unregistering linediscipline: %d\n", status);
- }
- else
- {
- TRACE_L("linediscipline successfully unregistered");
- }
-
+ int status;
+
+ TRACE_M("cleanup_module()");
+
+ status = tty_unregister_ldisc(N_R3964);
+
+ if (status != 0) {
+ printk(KERN_ERR "r3964: error unregistering linediscipline: "
+ "%d\n", status);
+ } else {
+ TRACE_L("linediscipline successfully unregistered");
+ }
}
static int __init r3964_init(void)
{
- int status;
-
- printk ("r3964: Philips r3964 Driver $Revision: 1.10 $\n");
-
- /*
- * Register the tty line discipline
- */
-
- status = tty_register_ldisc (N_R3964, &tty_ldisc_N_R3964);
- if (status == 0)
- {
- TRACE_L("line discipline %d registered", N_R3964);
- TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags,
- tty_ldisc_N_R3964.num);
- TRACE_L("open=%p", tty_ldisc_N_R3964.open);
- TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964);
- }
- else
- {
- printk (KERN_ERR "r3964: error registering line discipline: %d\n", status);
- }
- return status;
+ int status;
+
+ printk("r3964: Philips r3964 Driver $Revision: 1.10 $\n");
+
+ /*
+ * Register the tty line discipline
+ */
+
+ status = tty_register_ldisc(N_R3964, &tty_ldisc_N_R3964);
+ if (status == 0) {
+ TRACE_L("line discipline %d registered", N_R3964);
+ TRACE_L("flags=%x num=%x", tty_ldisc_N_R3964.flags,
+ tty_ldisc_N_R3964.num);
+ TRACE_L("open=%p", tty_ldisc_N_R3964.open);
+ TRACE_L("tty_ldisc_N_R3964 = %p", &tty_ldisc_N_R3964);
+ } else {
+ printk(KERN_ERR "r3964: error registering line discipline: "
+ "%d\n", status);
+ }
+ return status;
}
module_init(r3964_init);
module_exit(r3964_exit);
-
/*************************************************************
* Protocol implementation routines
*************************************************************/
-static void add_tx_queue(struct r3964_info *pInfo, struct r3964_block_header *pHeader)
+static void add_tx_queue(struct r3964_info *pInfo,
+ struct r3964_block_header *pHeader)
{
- unsigned long flags;
-
- spin_lock_irqsave(&pInfo->lock, flags);
-
- pHeader->next = NULL;
-
- if(pInfo->tx_last == NULL)
- {
- pInfo->tx_first = pInfo->tx_last = pHeader;
- }
- else
- {
- pInfo->tx_last->next = pHeader;
- pInfo->tx_last = pHeader;
- }
-
- spin_unlock_irqrestore(&pInfo->lock, flags);
-
- TRACE_Q("add_tx_queue %p, length %d, tx_first = %p",
- pHeader, pHeader->length, pInfo->tx_first );
+ unsigned long flags;
+
+ spin_lock_irqsave(&pInfo->lock, flags);
+
+ pHeader->next = NULL;
+
+ if (pInfo->tx_last == NULL) {
+ pInfo->tx_first = pInfo->tx_last = pHeader;
+ } else {
+ pInfo->tx_last->next = pHeader;
+ pInfo->tx_last = pHeader;
+ }
+
+ spin_unlock_irqrestore(&pInfo->lock, flags);
+
+ TRACE_Q("add_tx_queue %p, length %d, tx_first = %p",
+ pHeader, pHeader->length, pInfo->tx_first);
}
static void remove_from_tx_queue(struct r3964_info *pInfo, int error_code)
{
- struct r3964_block_header *pHeader;
- unsigned long flags;
+ struct r3964_block_header *pHeader;
+ unsigned long flags;
#ifdef DEBUG_QUEUE
- struct r3964_block_header *pDump;
+ struct r3964_block_header *pDump;
#endif
-
- pHeader = pInfo->tx_first;
- if(pHeader==NULL)
- return;
+ pHeader = pInfo->tx_first;
+
+ if (pHeader == NULL)
+ return;
#ifdef DEBUG_QUEUE
- printk("r3964: remove_from_tx_queue: %p, length %u - ",
- pHeader, pHeader->length );
- for(pDump=pHeader;pDump;pDump=pDump->next)
- printk("%p ", pDump);
- printk("\n");
+ printk("r3964: remove_from_tx_queue: %p, length %u - ",
+ pHeader, pHeader->length);
+ for (pDump = pHeader; pDump; pDump = pDump->next)
+ printk("%p ", pDump);
+ printk("\n");
#endif
+ if (pHeader->owner) {
+ if (error_code) {
+ add_msg(pHeader->owner, R3964_MSG_ACK, 0,
+ error_code, NULL);
+ } else {
+ add_msg(pHeader->owner, R3964_MSG_ACK, pHeader->length,
+ error_code, NULL);
+ }
+ wake_up_interruptible(&pInfo->read_wait);
+ }
+
+ spin_lock_irqsave(&pInfo->lock, flags);
+
+ pInfo->tx_first = pHeader->next;
+ if (pInfo->tx_first == NULL) {
+ pInfo->tx_last = NULL;
+ }
+
+ spin_unlock_irqrestore(&pInfo->lock, flags);
+
+ kfree(pHeader);
+ TRACE_M("remove_from_tx_queue - kfree %p", pHeader);
- if(pHeader->owner)
- {
- if(error_code)
- {
- add_msg(pHeader->owner, R3964_MSG_ACK, 0,
- error_code, NULL);
- }
- else
- {
- add_msg(pHeader->owner, R3964_MSG_ACK, pHeader->length,
- error_code, NULL);
- }
- wake_up_interruptible (&pInfo->read_wait);
- }
-
- spin_lock_irqsave(&pInfo->lock, flags);
-
- pInfo->tx_first = pHeader->next;
- if(pInfo->tx_first==NULL)
- {
- pInfo->tx_last = NULL;
- }
-
- spin_unlock_irqrestore(&pInfo->lock, flags);
-
- kfree(pHeader);
- TRACE_M("remove_from_tx_queue - kfree %p",pHeader);
-
- TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p",
- pInfo->tx_first, pInfo->tx_last );
+ TRACE_Q("remove_from_tx_queue: tx_first = %p, tx_last = %p",
+ pInfo->tx_first, pInfo->tx_last);
}
-static void add_rx_queue(struct r3964_info *pInfo, struct r3964_block_header *pHeader)
+static void add_rx_queue(struct r3964_info *pInfo,
+ struct r3964_block_header *pHeader)
{
- unsigned long flags;
-
- spin_lock_irqsave(&pInfo->lock, flags);
-
- pHeader->next = NULL;
-
- if(pInfo->rx_last == NULL)
- {
- pInfo->rx_first = pInfo->rx_last = pHeader;
- }
- else
- {
- pInfo->rx_last->next = pHeader;
- pInfo->rx_last = pHeader;
- }
- pInfo->blocks_in_rx_queue++;
-
- spin_unlock_irqrestore(&pInfo->lock, flags);
-
- TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d",
- pHeader, pHeader->length,
- pInfo->rx_first, pInfo->blocks_in_rx_queue);
+ unsigned long flags;
+
+ spin_lock_irqsave(&pInfo->lock, flags);
+
+ pHeader->next = NULL;
+
+ if (pInfo->rx_last == NULL) {
+ pInfo->rx_first = pInfo->rx_last = pHeader;
+ } else {
+ pInfo->rx_last->next = pHeader;
+ pInfo->rx_last = pHeader;
+ }
+ pInfo->blocks_in_rx_queue++;
+
+ spin_unlock_irqrestore(&pInfo->lock, flags);
+
+ TRACE_Q("add_rx_queue: %p, length = %d, rx_first = %p, count = %d",
+ pHeader, pHeader->length,
+ pInfo->rx_first, pInfo->blocks_in_rx_queue);
}
static void remove_from_rx_queue(struct r3964_info *pInfo,
- struct r3964_block_header *pHeader)
+ struct r3964_block_header *pHeader)
{
- unsigned long flags;
- struct r3964_block_header *pFind;
-
- if(pHeader==NULL)
- return;
-
- TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
- pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue );
- TRACE_Q("remove_from_rx_queue: %p, length %u",
- pHeader, pHeader->length );
-
- spin_lock_irqsave(&pInfo->lock, flags);
-
- if(pInfo->rx_first == pHeader)
- {
- /* Remove the first block in the linked list: */
- pInfo->rx_first = pHeader->next;
-
- if(pInfo->rx_first==NULL)
- {
- pInfo->rx_last = NULL;
- }
- pInfo->blocks_in_rx_queue--;
- }
- else
- {
- /* Find block to remove: */
- for(pFind=pInfo->rx_first; pFind; pFind=pFind->next)
- {
- if(pFind->next == pHeader)
- {
- /* Got it. */
- pFind->next = pHeader->next;
- pInfo->blocks_in_rx_queue--;
- if(pFind->next==NULL)
- {
- /* Oh, removed the last one! */
- pInfo->rx_last = pFind;
- }
- break;
- }
- }
- }
-
- spin_unlock_irqrestore(&pInfo->lock, flags);
-
- kfree(pHeader);
- TRACE_M("remove_from_rx_queue - kfree %p",pHeader);
-
- TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
- pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue );
+ unsigned long flags;
+ struct r3964_block_header *pFind;
+
+ if (pHeader == NULL)
+ return;
+
+ TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
+ pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue);
+ TRACE_Q("remove_from_rx_queue: %p, length %u",
+ pHeader, pHeader->length);
+
+ spin_lock_irqsave(&pInfo->lock, flags);
+
+ if (pInfo->rx_first == pHeader) {
+ /* Remove the first block in the linked list: */
+ pInfo->rx_first = pHeader->next;
+
+ if (pInfo->rx_first == NULL) {
+ pInfo->rx_last = NULL;
+ }
+ pInfo->blocks_in_rx_queue--;
+ } else {
+ /* Find block to remove: */
+ for (pFind = pInfo->rx_first; pFind; pFind = pFind->next) {
+ if (pFind->next == pHeader) {
+ /* Got it. */
+ pFind->next = pHeader->next;
+ pInfo->blocks_in_rx_queue--;
+ if (pFind->next == NULL) {
+ /* Oh, removed the last one! */
+ pInfo->rx_last = pFind;
+ }
+ break;
+ }
+ }
+ }
+
+ spin_unlock_irqrestore(&pInfo->lock, flags);
+
+ kfree(pHeader);
+ TRACE_M("remove_from_rx_queue - kfree %p", pHeader);
+
+ TRACE_Q("remove_from_rx_queue: rx_first = %p, rx_last = %p, count = %d",
+ pInfo->rx_first, pInfo->rx_last, pInfo->blocks_in_rx_queue);
}
static void put_char(struct r3964_info *pInfo, unsigned char ch)
{
- struct tty_struct *tty = pInfo->tty;
+ struct tty_struct *tty = pInfo->tty;
- if(tty==NULL)
- return;
+ if (tty == NULL)
+ return;
- if(tty->driver->put_char)
- {
- tty->driver->put_char(tty, ch);
- }
- pInfo->bcc ^= ch;
+ if (tty->driver->put_char) {
+ tty->driver->put_char(tty, ch);
+ }
+ pInfo->bcc ^= ch;
}
static void flush(struct r3964_info *pInfo)
{
- struct tty_struct *tty = pInfo->tty;
+ struct tty_struct *tty = pInfo->tty;
- if(tty==NULL)
- return;
+ if (tty == NULL)
+ return;
- if(tty->driver->flush_chars)
- {
- tty->driver->flush_chars(tty);
- }
+ if (tty->driver->flush_chars) {
+ tty->driver->flush_chars(tty);
+ }
}
static void trigger_transmit(struct r3964_info *pInfo)
{
- unsigned long flags;
-
+ unsigned long flags;
- spin_lock_irqsave(&pInfo->lock, flags);
+ spin_lock_irqsave(&pInfo->lock, flags);
- if((pInfo->state == R3964_IDLE) && (pInfo->tx_first!=NULL))
- {
- pInfo->state = R3964_TX_REQUEST;
- pInfo->nRetry=0;
- pInfo->flags &= ~R3964_ERROR;
- mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+ if ((pInfo->state == R3964_IDLE) && (pInfo->tx_first != NULL)) {
+ pInfo->state = R3964_TX_REQUEST;
+ pInfo->nRetry = 0;
+ pInfo->flags &= ~R3964_ERROR;
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
- spin_unlock_irqrestore(&pInfo->lock, flags);
+ spin_unlock_irqrestore(&pInfo->lock, flags);
- TRACE_PS("trigger_transmit - sent STX");
+ TRACE_PS("trigger_transmit - sent STX");
- put_char(pInfo, STX);
- flush(pInfo);
+ put_char(pInfo, STX);
+ flush(pInfo);
- pInfo->bcc = 0;
- }
- else
- {
- spin_unlock_irqrestore(&pInfo->lock, flags);
- }
+ pInfo->bcc = 0;
+ } else {
+ spin_unlock_irqrestore(&pInfo->lock, flags);
+ }
}
static void retry_transmit(struct r3964_info *pInfo)
{
- if(pInfo->nRetry<R3964_MAX_RETRIES)
- {
- TRACE_PE("transmission failed. Retry #%d",
- pInfo->nRetry);
- pInfo->bcc = 0;
- put_char(pInfo, STX);
- flush(pInfo);
- pInfo->state = R3964_TX_REQUEST;
- pInfo->nRetry++;
- mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
- }
- else
- {
- TRACE_PE("transmission failed after %d retries",
- R3964_MAX_RETRIES);
-
- remove_from_tx_queue(pInfo, R3964_TX_FAIL);
-
- put_char(pInfo, NAK);
- flush(pInfo);
- pInfo->state = R3964_IDLE;
-
- trigger_transmit(pInfo);
- }
+ if (pInfo->nRetry < R3964_MAX_RETRIES) {
+ TRACE_PE("transmission failed. Retry #%d", pInfo->nRetry);
+ pInfo->bcc = 0;
+ put_char(pInfo, STX);
+ flush(pInfo);
+ pInfo->state = R3964_TX_REQUEST;
+ pInfo->nRetry++;
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+ } else {
+ TRACE_PE("transmission failed after %d retries",
+ R3964_MAX_RETRIES);
+
+ remove_from_tx_queue(pInfo, R3964_TX_FAIL);
+
+ put_char(pInfo, NAK);
+ flush(pInfo);
+ pInfo->state = R3964_IDLE;
+
+ trigger_transmit(pInfo);
+ }
}
-
static void transmit_block(struct r3964_info *pInfo)
{
- struct tty_struct *tty = pInfo->tty;
- struct r3964_block_header *pBlock = pInfo->tx_first;
- int room=0;
-
- if((tty==NULL) || (pBlock==NULL))
- {
- return;
- }
-
- if(tty->driver->write_room)
- room=tty->driver->write_room(tty);
-
- TRACE_PS("transmit_block %p, room %d, length %d",
- pBlock, room, pBlock->length);
-
- while(pInfo->tx_position < pBlock->length)
- {
- if(room<2)
- break;
-
- if(pBlock->data[pInfo->tx_position]==DLE)
- {
- /* send additional DLE char: */
- put_char(pInfo, DLE);
- }
- put_char(pInfo, pBlock->data[pInfo->tx_position++]);
-
- room--;
- }
-
- if((pInfo->tx_position == pBlock->length) && (room>=3))
- {
- put_char(pInfo, DLE);
- put_char(pInfo, ETX);
- if(pInfo->flags & R3964_BCC)
- {
- put_char(pInfo, pInfo->bcc);
- }
- pInfo->state = R3964_WAIT_FOR_TX_ACK;
- mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
- }
- flush(pInfo);
+ struct tty_struct *tty = pInfo->tty;
+ struct r3964_block_header *pBlock = pInfo->tx_first;
+ int room = 0;
+
+ if ((tty == NULL) || (pBlock == NULL)) {
+ return;
+ }
+
+ if (tty->driver->write_room)
+ room = tty->driver->write_room(tty);
+
+ TRACE_PS("transmit_block %p, room %d, length %d",
+ pBlock, room, pBlock->length);
+
+ while (pInfo->tx_position < pBlock->length) {
+ if (room < 2)
+ break;
+
+ if (pBlock->data[pInfo->tx_position] == DLE) {
+ /* send additional DLE char: */
+ put_char(pInfo, DLE);
+ }
+ put_char(pInfo, pBlock->data[pInfo->tx_position++]);
+
+ room--;
+ }
+
+ if ((pInfo->tx_position == pBlock->length) && (room >= 3)) {
+ put_char(pInfo, DLE);
+ put_char(pInfo, ETX);
+ if (pInfo->flags & R3964_BCC) {
+ put_char(pInfo, pInfo->bcc);
+ }
+ pInfo->state = R3964_WAIT_FOR_TX_ACK;
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_QVZ);
+ }
+ flush(pInfo);
}
static void on_receive_block(struct r3964_info *pInfo)
{
- unsigned int length;
- struct r3964_client_info *pClient;
- struct r3964_block_header *pBlock;
-
- length=pInfo->rx_position;
-
- /* compare byte checksum characters: */
- if(pInfo->flags & R3964_BCC)
- {
- if(pInfo->bcc!=pInfo->last_rx)
- {
- TRACE_PE("checksum error - got %x but expected %x",
- pInfo->last_rx, pInfo->bcc);
- pInfo->flags |= R3964_CHECKSUM;
- }
- }
-
- /* check for errors (parity, overrun,...): */
- if(pInfo->flags & R3964_ERROR)
- {
- TRACE_PE("on_receive_block - transmission failed error %x",
- pInfo->flags & R3964_ERROR);
-
- put_char(pInfo, NAK);
- flush(pInfo);
- if(pInfo->nRetry<R3964_MAX_RETRIES)
- {
- pInfo->state=R3964_WAIT_FOR_RX_REPEAT;
- pInfo->nRetry++;
- mod_timer(&pInfo->tmr, jiffies + R3964_TO_RX_PANIC);
- }
- else
- {
- TRACE_PE("on_receive_block - failed after max retries");
- pInfo->state=R3964_IDLE;
- }
- return;
- }
-
-
- /* received block; submit DLE: */
- put_char(pInfo, DLE);
- flush(pInfo);
- del_timer_sync(&pInfo->tmr);
- TRACE_PS(" rx success: got %d chars", length);
-
- /* prepare struct r3964_block_header: */
- pBlock = kmalloc(length+sizeof(struct r3964_block_header), GFP_KERNEL);
- TRACE_M("on_receive_block - kmalloc %p",pBlock);
-
- if(pBlock==NULL)
- return;
-
- pBlock->length = length;
- pBlock->data = ((unsigned char*)pBlock)+sizeof(struct r3964_block_header);
- pBlock->locks = 0;
- pBlock->next = NULL;
- pBlock->owner = NULL;
-
- memcpy(pBlock->data, pInfo->rx_buf, length);
-
- /* queue block into rx_queue: */
- add_rx_queue(pInfo, pBlock);
-
- /* notify attached client processes: */
- for(pClient=pInfo->firstClient; pClient; pClient=pClient->next)
- {
- if(pClient->sig_flags & R3964_SIG_DATA)
- {
- add_msg(pClient, R3964_MSG_DATA, length, R3964_OK, pBlock);
- }
- }
- wake_up_interruptible (&pInfo->read_wait);
-
- pInfo->state = R3964_IDLE;
-
- trigger_transmit(pInfo);
-}
+ unsigned int length;
+ struct r3964_client_info *pClient;
+ struct r3964_block_header *pBlock;
+
+ length = pInfo->rx_position;
+
+ /* compare byte checksum characters: */
+ if (pInfo->flags & R3964_BCC) {
+ if (pInfo->bcc != pInfo->last_rx) {
+ TRACE_PE("checksum error - got %x but expected %x",
+ pInfo->last_rx, pInfo->bcc);
+ pInfo->flags |= R3964_CHECKSUM;
+ }
+ }
+
+ /* check for errors (parity, overrun,...): */
+ if (pInfo->flags & R3964_ERROR) {
+ TRACE_PE("on_receive_block - transmission failed error %x",
+ pInfo->flags & R3964_ERROR);
+
+ put_char(pInfo, NAK);
+ flush(pInfo);
+ if (pInfo->nRetry < R3964_MAX_RETRIES) {
+ pInfo->state = R3964_WAIT_FOR_RX_REPEAT;
+ pInfo->nRetry++;
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_RX_PANIC);
+ } else {
+ TRACE_PE("on_receive_block - failed after max retries");
+ pInfo->state = R3964_IDLE;
+ }
+ return;
+ }
+
+ /* received block; submit DLE: */
+ put_char(pInfo, DLE);
+ flush(pInfo);
+ del_timer_sync(&pInfo->tmr);
+ TRACE_PS(" rx success: got %d chars", length);
+
+ /* prepare struct r3964_block_header: */
+ pBlock = kmalloc(length + sizeof(struct r3964_block_header),
+ GFP_KERNEL);
+ TRACE_M("on_receive_block - kmalloc %p", pBlock);
+
+ if (pBlock == NULL)
+ return;
+
+ pBlock->length = length;
+ pBlock->data = ((unsigned char *)pBlock) +
+ sizeof(struct r3964_block_header);
+ pBlock->locks = 0;
+ pBlock->next = NULL;
+ pBlock->owner = NULL;
+
+ memcpy(pBlock->data, pInfo->rx_buf, length);
+
+ /* queue block into rx_queue: */
+ add_rx_queue(pInfo, pBlock);
+
+ /* notify attached client processes: */
+ for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) {
+ if (pClient->sig_flags & R3964_SIG_DATA) {
+ add_msg(pClient, R3964_MSG_DATA, length, R3964_OK,
+ pBlock);
+ }
+ }
+ wake_up_interruptible(&pInfo->read_wait);
+ pInfo->state = R3964_IDLE;
+
+ trigger_transmit(pInfo);
+}
static void receive_char(struct r3964_info *pInfo, const unsigned char c)
{
- switch(pInfo->state)
- {
- case R3964_TX_REQUEST:
- if(c==DLE)
- {
- TRACE_PS("TX_REQUEST - got DLE");
-
- pInfo->state = R3964_TRANSMITTING;
- pInfo->tx_position = 0;
-
- transmit_block(pInfo);
- }
- else if(c==STX)
- {
- if(pInfo->nRetry==0)
- {
- TRACE_PE("TX_REQUEST - init conflict");
- if(pInfo->priority == R3964_SLAVE)
- {
- goto start_receiving;
- }
- }
- else
- {
- TRACE_PE("TX_REQUEST - secondary init conflict!?"
- " Switching to SLAVE mode for next rx.");
- goto start_receiving;
- }
- }
- else
- {
- TRACE_PE("TX_REQUEST - char != DLE: %x", c);
- retry_transmit(pInfo);
- }
- break;
- case R3964_TRANSMITTING:
- if(c==NAK)
- {
- TRACE_PE("TRANSMITTING - got NAK");
- retry_transmit(pInfo);
- }
- else
- {
- TRACE_PE("TRANSMITTING - got invalid char");
-
- pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY;
- mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
- }
- break;
- case R3964_WAIT_FOR_TX_ACK:
- if(c==DLE)
- {
- TRACE_PS("WAIT_FOR_TX_ACK - got DLE");
- remove_from_tx_queue(pInfo, R3964_OK);
-
- pInfo->state = R3964_IDLE;
- trigger_transmit(pInfo);
- }
- else
- {
- retry_transmit(pInfo);
- }
- break;
- case R3964_WAIT_FOR_RX_REPEAT:
- /* FALLTROUGH */
- case R3964_IDLE:
- if(c==STX)
- {
- /* Prevent rx_queue from overflow: */
- if(pInfo->blocks_in_rx_queue >= R3964_MAX_BLOCKS_IN_RX_QUEUE)
- {
- TRACE_PE("IDLE - got STX but no space in rx_queue!");
- pInfo->state=R3964_WAIT_FOR_RX_BUF;
- mod_timer(&pInfo->tmr, jiffies + R3964_TO_NO_BUF);
- break;
- }
+ switch (pInfo->state) {
+ case R3964_TX_REQUEST:
+ if (c == DLE) {
+ TRACE_PS("TX_REQUEST - got DLE");
+
+ pInfo->state = R3964_TRANSMITTING;
+ pInfo->tx_position = 0;
+
+ transmit_block(pInfo);
+ } else if (c == STX) {
+ if (pInfo->nRetry == 0) {
+ TRACE_PE("TX_REQUEST - init conflict");
+ if (pInfo->priority == R3964_SLAVE) {
+ goto start_receiving;
+ }
+ } else {
+ TRACE_PE("TX_REQUEST - secondary init "
+ "conflict!? Switching to SLAVE mode "
+ "for next rx.");
+ goto start_receiving;
+ }
+ } else {
+ TRACE_PE("TX_REQUEST - char != DLE: %x", c);
+ retry_transmit(pInfo);
+ }
+ break;
+ case R3964_TRANSMITTING:
+ if (c == NAK) {
+ TRACE_PE("TRANSMITTING - got NAK");
+ retry_transmit(pInfo);
+ } else {
+ TRACE_PE("TRANSMITTING - got invalid char");
+
+ pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY;
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
+ }
+ break;
+ case R3964_WAIT_FOR_TX_ACK:
+ if (c == DLE) {
+ TRACE_PS("WAIT_FOR_TX_ACK - got DLE");
+ remove_from_tx_queue(pInfo, R3964_OK);
+
+ pInfo->state = R3964_IDLE;
+ trigger_transmit(pInfo);
+ } else {
+ retry_transmit(pInfo);
+ }
+ break;
+ case R3964_WAIT_FOR_RX_REPEAT:
+ /* FALLTROUGH */
+ case R3964_IDLE:
+ if (c == STX) {
+ /* Prevent rx_queue from overflow: */
+ if (pInfo->blocks_in_rx_queue >=
+ R3964_MAX_BLOCKS_IN_RX_QUEUE) {
+ TRACE_PE("IDLE - got STX but no space in "
+ "rx_queue!");
+ pInfo->state = R3964_WAIT_FOR_RX_BUF;
+ mod_timer(&pInfo->tmr,
+ jiffies + R3964_TO_NO_BUF);
+ break;
+ }
start_receiving:
- /* Ok, start receiving: */
- TRACE_PS("IDLE - got STX");
- pInfo->rx_position = 0;
- pInfo->last_rx = 0;
- pInfo->flags &= ~R3964_ERROR;
- pInfo->state=R3964_RECEIVING;
- mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
- pInfo->nRetry = 0;
- put_char(pInfo, DLE);
- flush(pInfo);
- pInfo->bcc = 0;
- }
- break;
- case R3964_RECEIVING:
- if(pInfo->rx_position < RX_BUF_SIZE)
- {
- pInfo->bcc ^= c;
-
- if(c==DLE)
- {
- if(pInfo->last_rx==DLE)
- {
- pInfo->last_rx = 0;
- goto char_to_buf;
- }
- pInfo->last_rx = DLE;
- break;
- }
- else if((c==ETX) && (pInfo->last_rx==DLE))
- {
- if(pInfo->flags & R3964_BCC)
- {
- pInfo->state = R3964_WAIT_FOR_BCC;
- mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
- }
- else
- {
- on_receive_block(pInfo);
- }
- }
- else
- {
- pInfo->last_rx = c;
+ /* Ok, start receiving: */
+ TRACE_PS("IDLE - got STX");
+ pInfo->rx_position = 0;
+ pInfo->last_rx = 0;
+ pInfo->flags &= ~R3964_ERROR;
+ pInfo->state = R3964_RECEIVING;
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
+ pInfo->nRetry = 0;
+ put_char(pInfo, DLE);
+ flush(pInfo);
+ pInfo->bcc = 0;
+ }
+ break;
+ case R3964_RECEIVING:
+ if (pInfo->rx_position < RX_BUF_SIZE) {
+ pInfo->bcc ^= c;
+
+ if (c == DLE) {
+ if (pInfo->last_rx == DLE) {
+ pInfo->last_rx = 0;
+ goto char_to_buf;
+ }
+ pInfo->last_rx = DLE;
+ break;
+ } else if ((c == ETX) && (pInfo->last_rx == DLE)) {
+ if (pInfo->flags & R3964_BCC) {
+ pInfo->state = R3964_WAIT_FOR_BCC;
+ mod_timer(&pInfo->tmr,
+ jiffies + R3964_TO_ZVZ);
+ } else {
+ on_receive_block(pInfo);
+ }
+ } else {
+ pInfo->last_rx = c;
char_to_buf:
- pInfo->rx_buf[pInfo->rx_position++] = c;
- mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
- }
- }
- /* else: overflow-msg? BUF_SIZE>MTU; should not happen? */
- break;
- case R3964_WAIT_FOR_BCC:
- pInfo->last_rx = c;
- on_receive_block(pInfo);
- break;
- }
+ pInfo->rx_buf[pInfo->rx_position++] = c;
+ mod_timer(&pInfo->tmr, jiffies + R3964_TO_ZVZ);
+ }
+ }
+ /* else: overflow-msg? BUF_SIZE>MTU; should not happen? */
+ break;
+ case R3964_WAIT_FOR_BCC:
+ pInfo->last_rx = c;
+ on_receive_block(pInfo);
+ break;
+ }
}
static void receive_error(struct r3964_info *pInfo, const char flag)
{
- switch (flag)
- {
- case TTY_NORMAL:
- break;
- case TTY_BREAK:
- TRACE_PE("received break")
- pInfo->flags |= R3964_BREAK;
- break;
- case TTY_PARITY:
- TRACE_PE("parity error")
- pInfo->flags |= R3964_PARITY;
- break;
- case TTY_FRAME:
- TRACE_PE("frame error")
- pInfo->flags |= R3964_FRAME;
- break;
- case TTY_OVERRUN:
- TRACE_PE("frame overrun")
- pInfo->flags |= R3964_OVERRUN;
- break;
- default:
- TRACE_PE("receive_error - unknown flag %d", flag);
- pInfo->flags |= R3964_UNKNOWN;
- break;
- }
+ switch (flag) {
+ case TTY_NORMAL:
+ break;
+ case TTY_BREAK:
+ TRACE_PE("received break");
+ pInfo->flags |= R3964_BREAK;
+ break;
+ case TTY_PARITY:
+ TRACE_PE("parity error");
+ pInfo->flags |= R3964_PARITY;
+ break;
+ case TTY_FRAME:
+ TRACE_PE("frame error");
+ pInfo->flags |= R3964_FRAME;
+ break;
+ case TTY_OVERRUN:
+ TRACE_PE("frame overrun");
+ pInfo->flags |= R3964_OVERRUN;
+ break;
+ default:
+ TRACE_PE("receive_error - unknown flag %d", flag);
+ pInfo->flags |= R3964_UNKNOWN;
+ break;
+ }
}
static void on_timeout(unsigned long priv)
{
- struct r3964_info *pInfo = (void *)priv;
-
- switch(pInfo->state)
- {
- case R3964_TX_REQUEST:
- TRACE_PE("TX_REQUEST - timeout");
- retry_transmit(pInfo);
- break;
- case R3964_WAIT_ZVZ_BEFORE_TX_RETRY:
- put_char(pInfo, NAK);
- flush(pInfo);
- retry_transmit(pInfo);
- break;
- case R3964_WAIT_FOR_TX_ACK:
- TRACE_PE("WAIT_FOR_TX_ACK - timeout");
- retry_transmit(pInfo);
- break;
- case R3964_WAIT_FOR_RX_BUF:
- TRACE_PE("WAIT_FOR_RX_BUF - timeout");
- put_char(pInfo, NAK);
- flush(pInfo);
- pInfo->state=R3964_IDLE;
- break;
- case R3964_RECEIVING:
- TRACE_PE("RECEIVING - timeout after %d chars",
- pInfo->rx_position);
- put_char(pInfo, NAK);
- flush(pInfo);
- pInfo->state=R3964_IDLE;
- break;
- case R3964_WAIT_FOR_RX_REPEAT:
- TRACE_PE("WAIT_FOR_RX_REPEAT - timeout");
- pInfo->state=R3964_IDLE;
- break;
- case R3964_WAIT_FOR_BCC:
- TRACE_PE("WAIT_FOR_BCC - timeout");
- put_char(pInfo, NAK);
- flush(pInfo);
- pInfo->state=R3964_IDLE;
- break;
- }
+ struct r3964_info *pInfo = (void *)priv;
+
+ switch (pInfo->state) {
+ case R3964_TX_REQUEST:
+ TRACE_PE("TX_REQUEST - timeout");
+ retry_transmit(pInfo);
+ break;
+ case R3964_WAIT_ZVZ_BEFORE_TX_RETRY:
+ put_char(pInfo, NAK);
+ flush(pInfo);
+ retry_transmit(pInfo);
+ break;
+ case R3964_WAIT_FOR_TX_ACK:
+ TRACE_PE("WAIT_FOR_TX_ACK - timeout");
+ retry_transmit(pInfo);
+ break;
+ case R3964_WAIT_FOR_RX_BUF:
+ TRACE_PE("WAIT_FOR_RX_BUF - timeout");
+ put_char(pInfo, NAK);
+ flush(pInfo);
+ pInfo->state = R3964_IDLE;
+ break;
+ case R3964_RECEIVING:
+ TRACE_PE("RECEIVING - timeout after %d chars",
+ pInfo->rx_position);
+ put_char(pInfo, NAK);
+ flush(pInfo);
+ pInfo->state = R3964_IDLE;
+ break;
+ case R3964_WAIT_FOR_RX_REPEAT:
+ TRACE_PE("WAIT_FOR_RX_REPEAT - timeout");
+ pInfo->state = R3964_IDLE;
+ break;
+ case R3964_WAIT_FOR_BCC:
+ TRACE_PE("WAIT_FOR_BCC - timeout");
+ put_char(pInfo, NAK);
+ flush(pInfo);
+ pInfo->state = R3964_IDLE;
+ break;
+ }
}
-static struct r3964_client_info *findClient(
- struct r3964_info *pInfo, struct pid *pid)
+static struct r3964_client_info *findClient(struct r3964_info *pInfo,
+ struct pid *pid)
{
- struct r3964_client_info *pClient;
-
- for(pClient=pInfo->firstClient; pClient; pClient=pClient->next)
- {
- if(pClient->pid == pid)
- {
- return pClient;
- }
- }
- return NULL;
+ struct r3964_client_info *pClient;
+
+ for (pClient = pInfo->firstClient; pClient; pClient = pClient->next) {
+ if (pClient->pid == pid) {
+ return pClient;
+ }
+ }
+ return NULL;
}
static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg)
{
- struct r3964_client_info *pClient;
- struct r3964_client_info **ppClient;
- struct r3964_message *pMsg;
-
- if((arg & R3964_SIG_ALL)==0)
- {
- /* Remove client from client list */
- for(ppClient=&pInfo->firstClient; *ppClient; ppClient=&(*ppClient)->next)
- {
- pClient = *ppClient;
-
- if(pClient->pid == pid)
- {
- TRACE_PS("removing client %d from client list", pid_nr(pid));
- *ppClient = pClient->next;
- while(pClient->msg_count)
- {
- pMsg=remove_msg(pInfo, pClient);
- if(pMsg)
- {
- kfree(pMsg);
- TRACE_M("enable_signals - msg kfree %p",pMsg);
- }
- }
- put_pid(pClient->pid);
- kfree(pClient);
- TRACE_M("enable_signals - kfree %p",pClient);
- return 0;
- }
- }
- return -EINVAL;
- }
- else
- {
- pClient=findClient(pInfo, pid);
- if(pClient)
- {
- /* update signal options */
- pClient->sig_flags=arg;
- }
- else
- {
- /* add client to client list */
- pClient=kmalloc(sizeof(struct r3964_client_info), GFP_KERNEL);
- TRACE_M("enable_signals - kmalloc %p",pClient);
- if(pClient==NULL)
- return -ENOMEM;
-
- TRACE_PS("add client %d to client list", pid_nr(pid));
- spin_lock_init(&pClient->lock);
- pClient->sig_flags=arg;
- pClient->pid = get_pid(pid);
- pClient->next=pInfo->firstClient;
- pClient->first_msg = NULL;
- pClient->last_msg = NULL;
- pClient->next_block_to_read = NULL;
- pClient->msg_count = 0;
- pInfo->firstClient=pClient;
- }
- }
-
- return 0;
+ struct r3964_client_info *pClient;
+ struct r3964_client_info **ppClient;
+ struct r3964_message *pMsg;
+
+ if ((arg & R3964_SIG_ALL) == 0) {
+ /* Remove client from client list */
+ for (ppClient = &pInfo->firstClient; *ppClient;
+ ppClient = &(*ppClient)->next) {
+ pClient = *ppClient;
+
+ if (pClient->pid == pid) {
+ TRACE_PS("removing client %d from client list",
+ pid_nr(pid));
+ *ppClient = pClient->next;
+ while (pClient->msg_count) {
+ pMsg = remove_msg(pInfo, pClient);
+ if (pMsg) {
+ kfree(pMsg);
+ TRACE_M("enable_signals - msg "
+ "kfree %p", pMsg);
+ }
+ }
+ put_pid(pClient->pid);
+ kfree(pClient);
+ TRACE_M("enable_signals - kfree %p", pClient);
+ return 0;
+ }
+ }
+ return -EINVAL;
+ } else {
+ pClient = findClient(pInfo, pid);
+ if (pClient) {
+ /* update signal options */
+ pClient->sig_flags = arg;
+ } else {
+ /* add client to client list */
+ pClient = kmalloc(sizeof(struct r3964_client_info),
+ GFP_KERNEL);
+ TRACE_M("enable_signals - kmalloc %p", pClient);
+ if (pClient == NULL)
+ return -ENOMEM;
+
+ TRACE_PS("add client %d to client list", pid_nr(pid));
+ spin_lock_init(&pClient->lock);
+ pClient->sig_flags = arg;
+ pClient->pid = get_pid(pid);
+ pClient->next = pInfo->firstClient;
+ pClient->first_msg = NULL;
+ pClient->last_msg = NULL;
+ pClient->next_block_to_read = NULL;
+ pClient->msg_count = 0;
+ pInfo->firstClient = pClient;
+ }
+ }
+
+ return 0;
}
-static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf)
+static int read_telegram(struct r3964_info *pInfo, struct pid *pid,
+ unsigned char __user * buf)
{
- struct r3964_client_info *pClient;
- struct r3964_block_header *block;
-
- if(!buf)
- {
- return -EINVAL;
- }
-
- pClient=findClient(pInfo,pid);
- if(pClient==NULL)
- {
- return -EINVAL;
- }
-
- block=pClient->next_block_to_read;
- if(!block)
- {
- return 0;
- }
- else
- {
- if (copy_to_user (buf, block->data, block->length))
- return -EFAULT;
-
- remove_client_block(pInfo, pClient);
- return block->length;
- }
-
- return -EINVAL;
+ struct r3964_client_info *pClient;
+ struct r3964_block_header *block;
+
+ if (!buf) {
+ return -EINVAL;
+ }
+
+ pClient = findClient(pInfo, pid);
+ if (pClient == NULL) {
+ return -EINVAL;
+ }
+
+ block = pClient->next_block_to_read;
+ if (!block) {
+ return 0;
+ } else {
+ if (copy_to_user(buf, block->data, block->length))
+ return -EFAULT;
+
+ remove_client_block(pInfo, pClient);
+ return block->length;
+ }
+
+ return -EINVAL;
}
static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,
- int error_code, struct r3964_block_header *pBlock)
+ int error_code, struct r3964_block_header *pBlock)
{
- struct r3964_message *pMsg;
- unsigned long flags;
-
- if(pClient->msg_count<R3964_MAX_MSG_COUNT-1)
- {
+ struct r3964_message *pMsg;
+ unsigned long flags;
+
+ if (pClient->msg_count < R3964_MAX_MSG_COUNT - 1) {
queue_the_message:
- pMsg = kmalloc(sizeof(struct r3964_message),
- error_code?GFP_ATOMIC:GFP_KERNEL);
- TRACE_M("add_msg - kmalloc %p",pMsg);
- if(pMsg==NULL) {
- return;
- }
-
- spin_lock_irqsave(&pClient->lock, flags);
-
- pMsg->msg_id = msg_id;
- pMsg->arg = arg;
- pMsg->error_code = error_code;
- pMsg->block = pBlock;
- pMsg->next = NULL;
-
- if(pClient->last_msg==NULL)
- {
- pClient->first_msg=pClient->last_msg=pMsg;
- }
- else
- {
- pClient->last_msg->next = pMsg;
- pClient->last_msg=pMsg;
- }
-
- pClient->msg_count++;
-
- if(pBlock!=NULL)
- {
- pBlock->locks++;
- }
- spin_unlock_irqrestore(&pClient->lock, flags);
- }
- else
- {
- if((pClient->last_msg->msg_id == R3964_MSG_ACK)
- && (pClient->last_msg->error_code==R3964_OVERFLOW))
- {
- pClient->last_msg->arg++;
- TRACE_PE("add_msg - inc prev OVERFLOW-msg");
- }
- else
- {
- msg_id = R3964_MSG_ACK;
- arg = 0;
- error_code = R3964_OVERFLOW;
- pBlock = NULL;
- TRACE_PE("add_msg - queue OVERFLOW-msg");
- goto queue_the_message;
- }
- }
- /* Send SIGIO signal to client process: */
- if(pClient->sig_flags & R3964_USE_SIGIO)
- {
- kill_pid(pClient->pid, SIGIO, 1);
- }
+ pMsg = kmalloc(sizeof(struct r3964_message),
+ error_code ? GFP_ATOMIC : GFP_KERNEL);
+ TRACE_M("add_msg - kmalloc %p", pMsg);
+ if (pMsg == NULL) {
+ return;
+ }
+
+ spin_lock_irqsave(&pClient->lock, flags);
+
+ pMsg->msg_id = msg_id;
+ pMsg->arg = arg;
+ pMsg->error_code = error_code;
+ pMsg->block = pBlock;
+ pMsg->next = NULL;
+
+ if (pClient->last_msg == NULL) {
+ pClient->first_msg = pClient->last_msg = pMsg;
+ } else {
+ pClient->last_msg->next = pMsg;
+ pClient->last_msg = pMsg;
+ }
+
+ pClient->msg_count++;
+
+ if (pBlock != NULL) {
+ pBlock->locks++;
+ }
+ spin_unlock_irqrestore(&pClient->lock, flags);
+ } else {
+ if ((pClient->last_msg->msg_id == R3964_MSG_ACK)
+ && (pClient->last_msg->error_code == R3964_OVERFLOW)) {
+ pClient->last_msg->arg++;
+ TRACE_PE("add_msg - inc prev OVERFLOW-msg");
+ } else {
+ msg_id = R3964_MSG_ACK;
+ arg = 0;
+ error_code = R3964_OVERFLOW;
+ pBlock = NULL;
+ TRACE_PE("add_msg - queue OVERFLOW-msg");
+ goto queue_the_message;
+ }
+ }
+ /* Send SIGIO signal to client process: */
+ if (pClient->sig_flags & R3964_USE_SIGIO) {
+ kill_pid(pClient->pid, SIGIO, 1);
+ }
}
static struct r3964_message *remove_msg(struct r3964_info *pInfo,
- struct r3964_client_info *pClient)
+ struct r3964_client_info *pClient)
{
- struct r3964_message *pMsg=NULL;
- unsigned long flags;
-
- if(pClient->first_msg)
- {
- spin_lock_irqsave(&pClient->lock, flags);
-
- pMsg = pClient->first_msg;
- pClient->first_msg = pMsg->next;
- if(pClient->first_msg==NULL)
- {
- pClient->last_msg = NULL;
- }
-
- pClient->msg_count--;
- if(pMsg->block)
- {
- remove_client_block(pInfo, pClient);
- pClient->next_block_to_read = pMsg->block;
- }
- spin_unlock_irqrestore(&pClient->lock, flags);
- }
- return pMsg;
+ struct r3964_message *pMsg = NULL;
+ unsigned long flags;
+
+ if (pClient->first_msg) {
+ spin_lock_irqsave(&pClient->lock, flags);
+
+ pMsg = pClient->first_msg;
+ pClient->first_msg = pMsg->next;
+ if (pClient->first_msg == NULL) {
+ pClient->last_msg = NULL;
+ }
+
+ pClient->msg_count--;
+ if (pMsg->block) {
+ remove_client_block(pInfo, pClient);
+ pClient->next_block_to_read = pMsg->block;
+ }
+ spin_unlock_irqrestore(&pClient->lock, flags);
+ }
+ return pMsg;
}
-static void remove_client_block(struct r3964_info *pInfo,
- struct r3964_client_info *pClient)
+static void remove_client_block(struct r3964_info *pInfo,
+ struct r3964_client_info *pClient)
{
- struct r3964_block_header *block;
-
- TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid));
-
- block=pClient->next_block_to_read;
- if(block)
- {
- block->locks--;
- if(block->locks==0)
- {
- remove_from_rx_queue(pInfo, block);
- }
- }
- pClient->next_block_to_read = NULL;
-}
+ struct r3964_block_header *block;
+
+ TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid));
+ block = pClient->next_block_to_read;
+ if (block) {
+ block->locks--;
+ if (block->locks == 0) {
+ remove_from_rx_queue(pInfo, block);
+ }
+ }
+ pClient->next_block_to_read = NULL;
+}
/*************************************************************
* Line discipline routines
@@ -1064,342 +951,318 @@ static void remove_client_block(struct r3964_info *pInfo,
static int r3964_open(struct tty_struct *tty)
{
- struct r3964_info *pInfo;
-
- TRACE_L("open");
- TRACE_L("tty=%p, PID=%d, disc_data=%p",
- tty, current->pid, tty->disc_data);
-
- pInfo=kmalloc(sizeof(struct r3964_info), GFP_KERNEL);
- TRACE_M("r3964_open - info kmalloc %p",pInfo);
-
- if(!pInfo)
- {
- printk(KERN_ERR "r3964: failed to alloc info structure\n");
- return -ENOMEM;
- }
-
- pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
- TRACE_M("r3964_open - rx_buf kmalloc %p",pInfo->rx_buf);
-
- if(!pInfo->rx_buf)
- {
- printk(KERN_ERR "r3964: failed to alloc receive buffer\n");
- kfree(pInfo);
- TRACE_M("r3964_open - info kfree %p",pInfo);
- return -ENOMEM;
- }
-
- pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL);
- TRACE_M("r3964_open - tx_buf kmalloc %p",pInfo->tx_buf);
-
- if(!pInfo->tx_buf)
- {
- printk(KERN_ERR "r3964: failed to alloc transmit buffer\n");
- kfree(pInfo->rx_buf);
- TRACE_M("r3964_open - rx_buf kfree %p",pInfo->rx_buf);
- kfree(pInfo);
- TRACE_M("r3964_open - info kfree %p",pInfo);
- return -ENOMEM;
- }
-
- spin_lock_init(&pInfo->lock);
- pInfo->tty = tty;
- init_waitqueue_head (&pInfo->read_wait);
- pInfo->priority = R3964_MASTER;
- pInfo->rx_first = pInfo->rx_last = NULL;
- pInfo->tx_first = pInfo->tx_last = NULL;
- pInfo->rx_position = 0;
- pInfo->tx_position = 0;
- pInfo->last_rx = 0;
- pInfo->blocks_in_rx_queue = 0;
- pInfo->firstClient=NULL;
- pInfo->state=R3964_IDLE;
- pInfo->flags = R3964_DEBUG;
- pInfo->nRetry = 0;
-
- tty->disc_data = pInfo;
- tty->receive_room = 65536;
-
- init_timer(&pInfo->tmr);
- pInfo->tmr.data = (unsigned long)pInfo;
- pInfo->tmr.function = on_timeout;
-
- return 0;
+ struct r3964_info *pInfo;
+
+ TRACE_L("open");
+ TRACE_L("tty=%p, PID=%d, disc_data=%p",
+ tty, current->pid, tty->disc_data);
+
+ pInfo = kmalloc(sizeof(struct r3964_info), GFP_KERNEL);
+ TRACE_M("r3964_open - info kmalloc %p", pInfo);
+
+ if (!pInfo) {
+ printk(KERN_ERR "r3964: failed to alloc info structure\n");
+ return -ENOMEM;
+ }
+
+ pInfo->rx_buf = kmalloc(RX_BUF_SIZE, GFP_KERNEL);
+ TRACE_M("r3964_open - rx_buf kmalloc %p", pInfo->rx_buf);
+
+ if (!pInfo->rx_buf) {
+ printk(KERN_ERR "r3964: failed to alloc receive buffer\n");
+ kfree(pInfo);
+ TRACE_M("r3964_open - info kfree %p", pInfo);
+ return -ENOMEM;
+ }
+
+ pInfo->tx_buf = kmalloc(TX_BUF_SIZE, GFP_KERNEL);
+ TRACE_M("r3964_open - tx_buf kmalloc %p", pInfo->tx_buf);
+
+ if (!pInfo->tx_buf) {
+ printk(KERN_ERR "r3964: failed to alloc transmit buffer\n");
+ kfree(pInfo->rx_buf);
+ TRACE_M("r3964_open - rx_buf kfree %p", pInfo->rx_buf);
+ kfree(pInfo);
+ TRACE_M("r3964_open - info kfree %p", pInfo);
+ return -ENOMEM;
+ }
+
+ spin_lock_init(&pInfo->lock);
+ pInfo->tty = tty;
+ init_waitqueue_head(&pInfo->read_wait);
+ pInfo->priority = R3964_MASTER;
+ pInfo->rx_first = pInfo->rx_last = NULL;
+ pInfo->tx_first = pInfo->tx_last = NULL;
+ pInfo->rx_position = 0;
+ pInfo->tx_position = 0;
+ pInfo->last_rx = 0;
+ pInfo->blocks_in_rx_queue = 0;
+ pInfo->firstClient = NULL;
+ pInfo->state = R3964_IDLE;
+ pInfo->flags = R3964_DEBUG;
+ pInfo->nRetry = 0;
+
+ tty->disc_data = pInfo;
+ tty->receive_room = 65536;
+
+ setup_timer(&pInfo->tmr, on_timeout, (unsigned long)pInfo);
+
+ return 0;
}
static void r3964_close(struct tty_struct *tty)
{
- struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
- struct r3964_client_info *pClient, *pNext;
- struct r3964_message *pMsg;
- struct r3964_block_header *pHeader, *pNextHeader;
- unsigned long flags;
-
- TRACE_L("close");
-
- /*
- * Make sure that our task queue isn't activated. If it
- * is, take it out of the linked list.
- */
- del_timer_sync(&pInfo->tmr);
-
- /* Remove client-structs and message queues: */
- pClient=pInfo->firstClient;
- while(pClient)
- {
- pNext=pClient->next;
- while(pClient->msg_count)
- {
- pMsg=remove_msg(pInfo, pClient);
- if(pMsg)
- {
- kfree(pMsg);
- TRACE_M("r3964_close - msg kfree %p",pMsg);
- }
- }
- put_pid(pClient->pid);
- kfree(pClient);
- TRACE_M("r3964_close - client kfree %p",pClient);
- pClient=pNext;
- }
- /* Remove jobs from tx_queue: */
- spin_lock_irqsave(&pInfo->lock, flags);
- pHeader=pInfo->tx_first;
- pInfo->tx_first=pInfo->tx_last=NULL;
+ struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data;
+ struct r3964_client_info *pClient, *pNext;
+ struct r3964_message *pMsg;
+ struct r3964_block_header *pHeader, *pNextHeader;
+ unsigned long flags;
+
+ TRACE_L("close");
+
+ /*
+ * Make sure that our task queue isn't activated. If it
+ * is, take it out of the linked list.
+ */
+ del_timer_sync(&pInfo->tmr);
+
+ /* Remove client-structs and message queues: */
+ pClient = pInfo->firstClient;
+ while (pClient) {
+ pNext = pClient->next;
+ while (pClient->msg_count) {
+ pMsg = remove_msg(pInfo, pClient);
+ if (pMsg) {
+ kfree(pMsg);
+ TRACE_M("r3964_close - msg kfree %p", pMsg);
+ }
+ }
+ put_pid(pClient->pid);
+ kfree(pClient);
+ TRACE_M("r3964_close - client kfree %p", pClient);
+ pClient = pNext;
+ }
+ /* Remove jobs from tx_queue: */
+ spin_lock_irqsave(&pInfo->lock, flags);
+ pHeader = pInfo->tx_first;
+ pInfo->tx_first = pInfo->tx_last = NULL;
spin_unlock_irqrestore(&pInfo->lock, flags);
-
- while(pHeader)
- {
- pNextHeader=pHeader->next;
- kfree(pHeader);
- pHeader=pNextHeader;
+
+ while (pHeader) {
+ pNextHeader = pHeader->next;
+ kfree(pHeader);
+ pHeader = pNextHeader;
}
- /* Free buffers: */
- wake_up_interruptible(&pInfo->read_wait);
- kfree(pInfo->rx_buf);
- TRACE_M("r3964_close - rx_buf kfree %p",pInfo->rx_buf);
- kfree(pInfo->tx_buf);
- TRACE_M("r3964_close - tx_buf kfree %p",pInfo->tx_buf);
- kfree(pInfo);
- TRACE_M("r3964_close - info kfree %p",pInfo);
+ /* Free buffers: */
+ wake_up_interruptible(&pInfo->read_wait);
+ kfree(pInfo->rx_buf);
+ TRACE_M("r3964_close - rx_buf kfree %p", pInfo->rx_buf);
+ kfree(pInfo->tx_buf);
+ TRACE_M("r3964_close - tx_buf kfree %p", pInfo->tx_buf);
+ kfree(pInfo);
+ TRACE_M("r3964_close - info kfree %p", pInfo);
}
static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
- unsigned char __user *buf, size_t nr)
+ unsigned char __user * buf, size_t nr)
{
- struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
- struct r3964_client_info *pClient;
- struct r3964_message *pMsg;
- struct r3964_client_message theMsg;
- DECLARE_WAITQUEUE (wait, current);
-
- int count;
-
- TRACE_L("read()");
-
- pClient=findClient(pInfo, task_pid(current));
- if(pClient)
- {
- pMsg = remove_msg(pInfo, pClient);
- if(pMsg==NULL)
- {
- /* no messages available. */
- if (file->f_flags & O_NONBLOCK)
- {
- return -EAGAIN;
- }
- /* block until there is a message: */
- add_wait_queue(&pInfo->read_wait, &wait);
+ struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data;
+ struct r3964_client_info *pClient;
+ struct r3964_message *pMsg;
+ struct r3964_client_message theMsg;
+ DECLARE_WAITQUEUE(wait, current);
+
+ int count;
+
+ TRACE_L("read()");
+
+ pClient = findClient(pInfo, task_pid(current));
+ if (pClient) {
+ pMsg = remove_msg(pInfo, pClient);
+ if (pMsg == NULL) {
+ /* no messages available. */
+ if (file->f_flags & O_NONBLOCK) {
+ return -EAGAIN;
+ }
+ /* block until there is a message: */
+ add_wait_queue(&pInfo->read_wait, &wait);
repeat:
- current->state = TASK_INTERRUPTIBLE;
- pMsg = remove_msg(pInfo, pClient);
- if (!pMsg && !signal_pending(current))
- {
- schedule();
- goto repeat;
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&pInfo->read_wait, &wait);
- }
-
- /* If we still haven't got a message, we must have been signalled */
-
- if (!pMsg) return -EINTR;
-
- /* deliver msg to client process: */
- theMsg.msg_id = pMsg->msg_id;
- theMsg.arg = pMsg->arg;
- theMsg.error_code = pMsg->error_code;
- count = sizeof(struct r3964_client_message);
-
- kfree(pMsg);
- TRACE_M("r3964_read - msg kfree %p",pMsg);
-
- if (copy_to_user(buf,&theMsg, count))
- return -EFAULT;
-
- TRACE_PS("read - return %d", count);
- return count;
- }
- return -EPERM;
+ current->state = TASK_INTERRUPTIBLE;
+ pMsg = remove_msg(pInfo, pClient);
+ if (!pMsg && !signal_pending(current)) {
+ schedule();
+ goto repeat;
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&pInfo->read_wait, &wait);
+ }
+
+ /* If we still haven't got a message, we must have been signalled */
+
+ if (!pMsg)
+ return -EINTR;
+
+ /* deliver msg to client process: */
+ theMsg.msg_id = pMsg->msg_id;
+ theMsg.arg = pMsg->arg;
+ theMsg.error_code = pMsg->error_code;
+ count = sizeof(struct r3964_client_message);
+
+ kfree(pMsg);
+ TRACE_M("r3964_read - msg kfree %p", pMsg);
+
+ if (copy_to_user(buf, &theMsg, count))
+ return -EFAULT;
+
+ TRACE_PS("read - return %d", count);
+ return count;
+ }
+ return -EPERM;
}
-static ssize_t r3964_write(struct tty_struct * tty, struct file * file,
+static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
const unsigned char *data, size_t count)
{
- struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
- struct r3964_block_header *pHeader;
- struct r3964_client_info *pClient;
- unsigned char *new_data;
-
- TRACE_L("write request, %d characters", count);
+ struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data;
+ struct r3964_block_header *pHeader;
+ struct r3964_client_info *pClient;
+ unsigned char *new_data;
+
+ TRACE_L("write request, %d characters", count);
/*
* Verify the pointers
*/
- if(!pInfo)
- return -EIO;
+ if (!pInfo)
+ return -EIO;
/*
* Ensure that the caller does not wish to send too much.
*/
- if (count > R3964_MTU)
- {
- if (pInfo->flags & R3964_DEBUG)
- {
- TRACE_L (KERN_WARNING
- "r3964_write: truncating user packet "
- "from %u to mtu %d", count, R3964_MTU);
- }
- count = R3964_MTU;
- }
+ if (count > R3964_MTU) {
+ if (pInfo->flags & R3964_DEBUG) {
+ TRACE_L(KERN_WARNING "r3964_write: truncating user "
+ "packet from %u to mtu %d", count, R3964_MTU);
+ }
+ count = R3964_MTU;
+ }
/*
* Allocate a buffer for the data and copy it from the buffer with header prepended
*/
- new_data = kmalloc (count+sizeof(struct r3964_block_header), GFP_KERNEL);
- TRACE_M("r3964_write - kmalloc %p",new_data);
- if (new_data == NULL) {
- if (pInfo->flags & R3964_DEBUG)
- {
- printk (KERN_ERR
- "r3964_write: no memory\n");
- }
- return -ENOSPC;
- }
-
- pHeader = (struct r3964_block_header *)new_data;
- pHeader->data = new_data + sizeof(struct r3964_block_header);
- pHeader->length = count;
- pHeader->locks = 0;
- pHeader->owner = NULL;
-
- pClient=findClient(pInfo, task_pid(current));
- if(pClient)
- {
- pHeader->owner = pClient;
- }
-
- memcpy(pHeader->data, data, count); /* We already verified this */
-
- if(pInfo->flags & R3964_DEBUG)
- {
- dump_block(pHeader->data, count);
- }
+ new_data = kmalloc(count + sizeof(struct r3964_block_header),
+ GFP_KERNEL);
+ TRACE_M("r3964_write - kmalloc %p", new_data);
+ if (new_data == NULL) {
+ if (pInfo->flags & R3964_DEBUG) {
+ printk(KERN_ERR "r3964_write: no memory\n");
+ }
+ return -ENOSPC;
+ }
+
+ pHeader = (struct r3964_block_header *)new_data;
+ pHeader->data = new_data + sizeof(struct r3964_block_header);
+ pHeader->length = count;
+ pHeader->locks = 0;
+ pHeader->owner = NULL;
+
+ pClient = findClient(pInfo, task_pid(current));
+ if (pClient) {
+ pHeader->owner = pClient;
+ }
+
+ memcpy(pHeader->data, data, count); /* We already verified this */
+
+ if (pInfo->flags & R3964_DEBUG) {
+ dump_block(pHeader->data, count);
+ }
/*
* Add buffer to transmit-queue:
*/
- add_tx_queue(pInfo, pHeader);
- trigger_transmit(pInfo);
-
- return 0;
+ add_tx_queue(pInfo, pHeader);
+ trigger_transmit(pInfo);
+
+ return 0;
}
-static int r3964_ioctl(struct tty_struct * tty, struct file * file,
- unsigned int cmd, unsigned long arg)
+static int r3964_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
- struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
- if(pInfo==NULL)
- return -EINVAL;
- switch(cmd)
- {
- case R3964_ENABLE_SIGNALS:
- return enable_signals(pInfo, task_pid(current), arg);
- case R3964_SETPRIORITY:
- if(arg<R3964_MASTER || arg>R3964_SLAVE)
- return -EINVAL;
- pInfo->priority = arg & 0xff;
- return 0;
- case R3964_USE_BCC:
- if(arg)
- pInfo->flags |= R3964_BCC;
- else
- pInfo->flags &= ~R3964_BCC;
- return 0;
- case R3964_READ_TELEGRAM:
- return read_telegram(pInfo, task_pid(current), (unsigned char __user *)arg);
- default:
- return -ENOIOCTLCMD;
- }
+ struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data;
+ if (pInfo == NULL)
+ return -EINVAL;
+ switch (cmd) {
+ case R3964_ENABLE_SIGNALS:
+ return enable_signals(pInfo, task_pid(current), arg);
+ case R3964_SETPRIORITY:
+ if (arg < R3964_MASTER || arg > R3964_SLAVE)
+ return -EINVAL;
+ pInfo->priority = arg & 0xff;
+ return 0;
+ case R3964_USE_BCC:
+ if (arg)
+ pInfo->flags |= R3964_BCC;
+ else
+ pInfo->flags &= ~R3964_BCC;
+ return 0;
+ case R3964_READ_TELEGRAM:
+ return read_telegram(pInfo, task_pid(current),
+ (unsigned char __user *)arg);
+ default:
+ return -ENOIOCTLCMD;
+ }
}
-static void r3964_set_termios(struct tty_struct *tty, struct ktermios * old)
+static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old)
{
- TRACE_L("set_termios");
+ TRACE_L("set_termios");
}
/* Called without the kernel lock held - fine */
-static unsigned int r3964_poll(struct tty_struct * tty, struct file * file,
- struct poll_table_struct *wait)
+static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
+ struct poll_table_struct *wait)
{
- struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
- struct r3964_client_info *pClient;
- struct r3964_message *pMsg=NULL;
- unsigned long flags;
- int result = POLLOUT;
-
- TRACE_L("POLL");
-
- pClient=findClient(pInfo, task_pid(current));
- if(pClient)
- {
- poll_wait(file, &pInfo->read_wait, wait);
- spin_lock_irqsave(&pInfo->lock, flags);
- pMsg=pClient->first_msg;
- spin_unlock_irqrestore(&pInfo->lock, flags);
- if(pMsg)
- result |= POLLIN | POLLRDNORM;
- }
- else
- {
- result = -EINVAL;
- }
- return result;
+ struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data;
+ struct r3964_client_info *pClient;
+ struct r3964_message *pMsg = NULL;
+ unsigned long flags;
+ int result = POLLOUT;
+
+ TRACE_L("POLL");
+
+ pClient = findClient(pInfo, task_pid(current));
+ if (pClient) {
+ poll_wait(file, &pInfo->read_wait, wait);
+ spin_lock_irqsave(&pInfo->lock, flags);
+ pMsg = pClient->first_msg;
+ spin_unlock_irqrestore(&pInfo->lock, flags);
+ if (pMsg)
+ result |= POLLIN | POLLRDNORM;
+ } else {
+ result = -EINVAL;
+ }
+ return result;
}
static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
- char *fp, int count)
+ char *fp, int count)
{
- struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data;
- const unsigned char *p;
- char *f, flags = 0;
- int i;
-
- for (i=count, p = cp, f = fp; i; i--, p++) {
- if (f)
- flags = *f++;
- if(flags==TTY_NORMAL)
- {
- receive_char(pInfo, *p);
- }
- else
- {
- receive_error(pInfo, flags);
- }
-
- }
+ struct r3964_info *pInfo = (struct r3964_info *)tty->disc_data;
+ const unsigned char *p;
+ char *f, flags = 0;
+ int i;
+
+ for (i = count, p = cp, f = fp; i; i--, p++) {
+ if (f)
+ flags = *f++;
+ if (flags == TTY_NORMAL) {
+ receive_char(pInfo, *p);
+ } else {
+ receive_error(pInfo, flags);
+ }
+
+ }
}
MODULE_LICENSE("GPL");
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 2bdb0144a22e..6ac3ca4c723c 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -579,8 +579,8 @@ static void eraser(unsigned char c, struct tty_struct *tty)
static inline void isig(int sig, struct tty_struct *tty, int flush)
{
- if (tty->pgrp > 0)
- kill_pg(tty->pgrp, sig, 1);
+ if (tty->pgrp)
+ kill_pgrp(tty->pgrp, sig, 1);
if (flush || !L_NOFLSH(tty)) {
n_tty_flush_buffer(tty);
if (tty->driver->flush_buffer)
@@ -1184,13 +1184,13 @@ static int job_control(struct tty_struct *tty, struct file *file)
/* don't stop on /dev/console */
if (file->f_op->write != redirected_tty_write &&
current->signal->tty == tty) {
- if (tty->pgrp <= 0)
- printk("read_chan: tty->pgrp <= 0!\n");
- else if (process_group(current) != tty->pgrp) {
+ if (!tty->pgrp)
+ printk("read_chan: no tty->pgrp!\n");
+ else if (task_pgrp(current) != tty->pgrp) {
if (is_ignored(SIGTTIN) ||
- is_orphaned_pgrp(process_group(current)))
+ is_current_pgrp_orphaned())
return -EIO;
- kill_pg(process_group(current), SIGTTIN, 1);
+ kill_pgrp(task_pgrp(current), SIGTTIN, 1);
return -ERESTARTSYS;
}
}
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index 2d264971d839..2604246501e4 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -23,8 +23,11 @@
#define __NWBUTTON_C /* Tell the header file who we are */
#include "nwbutton.h"
+static void button_sequence_finished (unsigned long parameters);
+
static int button_press_count; /* The count of button presses */
-static struct timer_list button_timer; /* Times for the end of a sequence */
+/* Times for the end of a sequence */
+static DEFINE_TIMER(button_timer, button_sequence_finished, 0, 0);
static DECLARE_WAIT_QUEUE_HEAD(button_wait_queue); /* Used for blocking read */
static char button_output_buffer[32]; /* Stores data to write out of device */
static int bcount; /* The number of bytes in the buffer */
@@ -146,14 +149,8 @@ static void button_sequence_finished (unsigned long parameters)
static irqreturn_t button_handler (int irq, void *dev_id)
{
- if (button_press_count) {
- del_timer (&button_timer);
- }
button_press_count++;
- init_timer (&button_timer);
- button_timer.function = button_sequence_finished;
- button_timer.expires = (jiffies + bdelay);
- add_timer (&button_timer);
+ mod_timer(&button_timer, jiffies + bdelay);
return IRQ_HANDLED;
}
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 211c93fda6fc..e91b43a014b0 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -946,8 +946,7 @@ release_io:
return_with_timer:
DEBUGP(7, dev, "<- monitor_card (returns with timer)\n");
- dev->timer.expires = jiffies + dev->mdelay;
- add_timer(&dev->timer);
+ mod_timer(&dev->timer, jiffies + dev->mdelay);
clear_bit(LOCK_MONITOR, &dev->flags);
}
@@ -1406,12 +1405,9 @@ static void start_monitor(struct cm4000_dev *dev)
DEBUGP(3, dev, "-> start_monitor\n");
if (!dev->monitor_running) {
DEBUGP(5, dev, "create, init and add timer\n");
- init_timer(&dev->timer);
+ setup_timer(&dev->timer, monitor_card, (unsigned long)dev);
dev->monitor_running = 1;
- dev->timer.expires = jiffies;
- dev->timer.data = (unsigned long) dev;
- dev->timer.function = monitor_card;
- add_timer(&dev->timer);
+ mod_timer(&dev->timer, jiffies);
} else
DEBUGP(5, dev, "monitor already running\n");
DEBUGP(3, dev, "<- start_monitor\n");
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 9b1ff7e8f896..0e82968c2f38 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -632,8 +632,7 @@ static int reader_probe(struct pcmcia_device *link)
init_waitqueue_head(&dev->poll_wait);
init_waitqueue_head(&dev->read_wait);
init_waitqueue_head(&dev->write_wait);
- init_timer(&dev->poll_timer);
- dev->poll_timer.function = &cm4040_do_poll;
+ setup_timer(&dev->poll_timer, cm4040_do_poll, 0);
ret = reader_config(link, i);
if (ret)
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index f108c136800a..8d025e9b5bce 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -887,10 +887,8 @@ static void bh_transmit(MGSLPC_INFO *info)
if (debug_level >= DEBUG_LEVEL_BH)
printk("bh_transmit() entry on %s\n", info->device_name);
- if (tty) {
+ if (tty)
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
- }
}
static void bh_status(MGSLPC_INFO *info)
@@ -1363,9 +1361,7 @@ static int startup(MGSLPC_INFO * info)
memset(&info->icount, 0, sizeof(info->icount));
- init_timer(&info->tx_timer);
- info->tx_timer.data = (unsigned long)info;
- info->tx_timer.function = tx_timeout;
+ setup_timer(&info->tx_timer, tx_timeout, (unsigned long)info);
/* Allocate and claim adapter resources */
retval = claim_resources(info);
@@ -1410,7 +1406,7 @@ static void shutdown(MGSLPC_INFO * info)
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
- del_timer(&info->tx_timer);
+ del_timer_sync(&info->tx_timer);
if (info->tx_buf) {
free_page((unsigned long) info->tx_buf);
@@ -3551,8 +3547,8 @@ static void tx_start(MGSLPC_INFO *info)
} else {
info->tx_active = 1;
tx_ready(info);
- info->tx_timer.expires = jiffies + msecs_to_jiffies(5000);
- add_timer(&info->tx_timer);
+ mod_timer(&info->tx_timer, jiffies +
+ msecs_to_jiffies(5000));
}
}
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 13d0b1350a62..b9dc7aa1dfb3 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1117,14 +1117,14 @@ random_ioctl(struct inode * inode, struct file * file,
}
}
-struct file_operations random_fops = {
+const struct file_operations random_fops = {
.read = random_read,
.write = random_write,
.poll = random_poll,
.ioctl = random_ioctl,
};
-struct file_operations urandom_fops = {
+const struct file_operations urandom_fops = {
.read = urandom_read,
.write = random_write,
.ioctl = random_ioctl,
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 645e20a06ece..1f0d7c60c944 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -154,7 +154,7 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
goto out;
}
- if (rq.raw_minor < 0 || rq.raw_minor >= MAX_RAW_MINORS) {
+ if (rq.raw_minor <= 0 || rq.raw_minor >= MAX_RAW_MINORS) {
err = -EINVAL;
goto out;
}
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index e79b2ede8510..85c161845260 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -418,8 +418,7 @@ static void rio_pollfunc(unsigned long data)
func_enter();
rio_interrupt(0, &p->RIOHosts[data]);
- p->RIOHosts[data].timer.expires = jiffies + rio_poll;
- add_timer(&p->RIOHosts[data].timer);
+ mod_timer(&p->RIOHosts[data].timer, jiffies + rio_poll);
func_exit();
}
@@ -1154,13 +1153,10 @@ static int __init rio_init(void)
/* Init the timer "always" to make sure that it can safely be
deleted when we unload... */
- init_timer(&hp->timer);
+ setup_timer(&hp->timer, rio_pollfunc, i);
if (!hp->Ivec) {
rio_dprintk(RIO_DEBUG_INIT, "Starting polling at %dj intervals.\n", rio_poll);
- hp->timer.data = i;
- hp->timer.function = rio_pollfunc;
- hp->timer.expires = jiffies + rio_poll;
- add_timer(&hp->timer);
+ mod_timer(&hp->timer, jiffies + rio_poll);
}
}
@@ -1191,7 +1187,7 @@ static void __exit rio_exit(void)
rio_dprintk(RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec);
}
/* It is safe/allowed to del_timer a non-active timer */
- del_timer(&hp->timer);
+ del_timer_sync(&hp->timer);
if (hp->Caddr)
iounmap(hp->Caddr);
if (hp->Type == RIO_PCI)
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
index eeda40c5e189..ebc76342712c 100644
--- a/drivers/char/rio/riointr.c
+++ b/drivers/char/rio/riointr.c
@@ -162,13 +162,8 @@ void RIOTxEnable(char *en)
rio_spin_unlock_irqrestore(&PortP->portSem, flags);
- if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) {
- rio_dprintk(RIO_DEBUG_INTR, "Waking up.... ldisc:%d (%d/%d)....", (int) (PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)), PortP->gs.wakeup_chars, PortP->gs.xmit_cnt);
- if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && PortP->gs.tty->ldisc.write_wakeup)
- (PortP->gs.tty->ldisc.write_wakeup) (PortP->gs.tty);
- rio_dprintk(RIO_DEBUG_INTR, "(%d/%d)\n", PortP->gs.wakeup_chars, PortP->gs.xmit_cnt);
- wake_up_interruptible(&PortP->gs.tty->write_wait);
- }
+ if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN))
+ tty_wakeup(PortP->gs.tty);
}
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index e2a94bfb2a43..70145254fb9d 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -1229,7 +1229,6 @@ static void rc_flush_buffer(struct tty_struct *tty)
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
restore_flags(flags);
- wake_up_interruptible(&tty->write_wait);
tty_wakeup(tty);
}
@@ -1570,10 +1569,8 @@ static void do_softint(struct work_struct *ugly_api)
if(!(tty = port->tty))
return;
- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event))
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
- }
}
static const struct tty_operations riscom_ops = {
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index e94a62e30fc4..76357c855ce3 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -106,6 +106,8 @@
/****** RocketPort Local Variables ******/
+static void rp_do_poll(unsigned long dummy);
+
static struct tty_driver *rocket_driver;
static struct rocket_version driver_version = {
@@ -116,7 +118,7 @@ static struct r_port *rp_table[MAX_RP_PORTS]; /* The main repository of
static unsigned int xmit_flags[NUM_BOARDS]; /* Bit significant, indicates port had data to transmit. */
/* eg. Bit 0 indicates port 0 has xmit data, ... */
static atomic_t rp_num_ports_open; /* Number of serial ports open */
-static struct timer_list rocket_timer;
+static DEFINE_TIMER(rocket_timer, rp_do_poll, 0, 0);
static unsigned long board1; /* ISA addresses, retrieved from rocketport.conf */
static unsigned long board2;
@@ -474,7 +476,6 @@ static void rp_do_transmit(struct r_port *info)
if (info->xmit_cnt < WAKEUP_CHARS) {
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
#ifdef ROCKETPORT_HAVE_POLL_WAIT
wake_up_interruptible(&tty->poll_wait);
#endif
@@ -1772,7 +1773,6 @@ static int rp_write(struct tty_struct *tty,
end:
if (info->xmit_cnt < WAKEUP_CHARS) {
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
#ifdef ROCKETPORT_HAVE_POLL_WAIT
wake_up_interruptible(&tty->poll_wait);
#endif
@@ -1841,7 +1841,6 @@ static void rp_flush_buffer(struct tty_struct *tty)
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
spin_unlock_irqrestore(&info->slock, flags);
- wake_up_interruptible(&tty->write_wait);
#ifdef ROCKETPORT_HAVE_POLL_WAIT
wake_up_interruptible(&tty->poll_wait);
#endif
@@ -2371,12 +2370,6 @@ static int __init rp_init(void)
return -ENOMEM;
/*
- * Set up the timer channel.
- */
- init_timer(&rocket_timer);
- rocket_timer.function = rp_do_poll;
-
- /*
* Initialize the array of pointers to our own internal state
* structures.
*/
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 664f36c98e6a..b6d3072dce5a 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -135,7 +135,9 @@ static struct fasync_struct *rtc_async_queue;
static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
#ifdef RTC_IRQ
-static struct timer_list rtc_irq_timer;
+static void rtc_dropped_irq(unsigned long data);
+
+static DEFINE_TIMER(rtc_irq_timer, rtc_dropped_irq, 0, 0);
#endif
static ssize_t rtc_read(struct file *file, char __user *buf,
@@ -150,8 +152,6 @@ static unsigned int rtc_poll(struct file *file, poll_table *wait);
static void get_rtc_alm_time (struct rtc_time *alm_tm);
#ifdef RTC_IRQ
-static void rtc_dropped_irq(unsigned long data);
-
static void set_rtc_irq_bit_locked(unsigned char bit);
static void mask_rtc_irq_bit_locked(unsigned char bit);
@@ -454,8 +454,8 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
spin_lock_irqsave (&rtc_lock, flags);
if (!(rtc_status & RTC_TIMER_ON)) {
- rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
- add_timer(&rtc_irq_timer);
+ mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq +
+ 2*HZ/100);
rtc_status |= RTC_TIMER_ON;
}
set_rtc_irq_bit_locked(RTC_PIE);
@@ -1084,8 +1084,6 @@ no_irq:
if (rtc_has_irq == 0)
goto no_irq2;
- init_timer(&rtc_irq_timer);
- rtc_irq_timer.function = rtc_dropped_irq;
spin_lock_irq(&rtc_lock);
rtc_freq = 1024;
if (!hpet_set_periodic_freq(rtc_freq)) {
diff --git a/drivers/char/scan_keyb.c b/drivers/char/scan_keyb.c
deleted file mode 100644
index 2b5bb4f5754d..000000000000
--- a/drivers/char/scan_keyb.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * $Id: scan_keyb.c,v 1.2 2000/07/04 06:24:42 yaegashi Exp $
- * Copyright (C) 2000 YAEGASHI Takeshi
- * Generic scan keyboard driver
- */
-
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <linux/init.h>
-#include <linux/kbd_ll.h>
-#include <linux/delay.h>
-#include <linux/random.h>
-#include <linux/poll.h>
-#include <linux/miscdevice.h>
-#include <linux/slab.h>
-#include <linux/kbd_kern.h>
-#include <linux/timer.h>
-
-#define SCANHZ (HZ/20)
-
-struct scan_keyboard {
- struct scan_keyboard *next;
- int (*scan)(unsigned char *buffer);
- const unsigned char *table;
- unsigned char *s0, *s1;
- int length;
-};
-
-static int scan_jiffies=0;
-static struct scan_keyboard *keyboards=NULL;
-struct timer_list scan_timer;
-
-static void check_kbd(const unsigned char *table,
- unsigned char *new, unsigned char *old, int length)
-{
- int need_tasklet_schedule=0;
- unsigned int xor, bit;
-
- while(length-->0) {
- if((xor=*new^*old)==0) {
- table+=8;
- }
- else {
- for(bit=0x01; bit<0x100; bit<<=1) {
- if(xor&bit) {
- handle_scancode(*table, !(*new&bit));
- need_tasklet_schedule=1;
-#if 0
- printk("0x%x %s\n", *table, (*new&bit)?"released":"pressed");
-#endif
- }
- table++;
- }
- }
- new++; old++;
- }
-
- if(need_tasklet_schedule)
- tasklet_schedule(&keyboard_tasklet);
-}
-
-
-static void scan_kbd(unsigned long dummy)
-{
- struct scan_keyboard *kbd;
-
- scan_jiffies++;
-
- for(kbd=keyboards; kbd!=NULL; kbd=kbd->next) {
- if(scan_jiffies&1) {
- if(!kbd->scan(kbd->s0))
- check_kbd(kbd->table,
- kbd->s0, kbd->s1, kbd->length);
- else
- memcpy(kbd->s0, kbd->s1, kbd->length);
- }
- else {
- if(!kbd->scan(kbd->s1))
- check_kbd(kbd->table,
- kbd->s1, kbd->s0, kbd->length);
- else
- memcpy(kbd->s1, kbd->s0, kbd->length);
- }
-
- }
-
- init_timer(&scan_timer);
- scan_timer.expires = jiffies + SCANHZ;
- scan_timer.data = 0;
- scan_timer.function = scan_kbd;
- add_timer(&scan_timer);
-}
-
-
-int register_scan_keyboard(int (*scan)(unsigned char *buffer),
- const unsigned char *table,
- int length)
-{
- struct scan_keyboard *kbd;
-
- kbd = kmalloc(sizeof(struct scan_keyboard), GFP_KERNEL);
- if (kbd == NULL)
- goto error_out;
-
- kbd->scan=scan;
- kbd->table=table;
- kbd->length=length;
-
- kbd->s0 = kmalloc(length, GFP_KERNEL);
- if (kbd->s0 == NULL)
- goto error_free_kbd;
-
- kbd->s1 = kmalloc(length, GFP_KERNEL);
- if (kbd->s1 == NULL)
- goto error_free_s0;
-
- memset(kbd->s0, -1, kbd->length);
- memset(kbd->s1, -1, kbd->length);
-
- kbd->next=keyboards;
- keyboards=kbd;
-
- return 0;
-
- error_free_s0:
- kfree(kbd->s0);
-
- error_free_kbd:
- kfree(kbd);
-
- error_out:
- return -ENOMEM;
-}
-
-
-void __init scan_kbd_init(void)
-{
- init_timer(&scan_timer);
- scan_timer.expires = jiffies + SCANHZ;
- scan_timer.data = 0;
- scan_timer.function = scan_kbd;
- add_timer(&scan_timer);
-
- printk(KERN_INFO "Generic scan keyboard driver initialized\n");
-}
diff --git a/drivers/char/scan_keyb.h b/drivers/char/scan_keyb.h
deleted file mode 100644
index b4b611290a00..000000000000
--- a/drivers/char/scan_keyb.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __DRIVER_CHAR_SCAN_KEYB_H
-#define __DRIVER_CHAR_SCAN_KEYB_H
-/*
- * $Id: scan_keyb.h,v 1.1 2000/06/10 21:45:30 yaegashi Exp $
- * Copyright (C) 2000 YAEGASHI Takeshi
- * Generic scan keyboard driver
- */
-
-int register_scan_keyboard(int (*scan)(unsigned char *buffer),
- const unsigned char *table,
- int length);
-
-void __init scan_kbd_init(void);
-
-#endif
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index af50d32ae2c7..5fd314adc1f2 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -111,12 +111,13 @@ u_char initial_console_speed;
/* This is the per-port data structure */
struct cyclades_port cy_port[] = {
- /* CARD# */
- {-1 }, /* ttyS0 */
- {-1 }, /* ttyS1 */
- {-1 }, /* ttyS2 */
- {-1 }, /* ttyS3 */
+ /* CARD# */
+ {-1}, /* ttyS0 */
+ {-1}, /* ttyS1 */
+ {-1}, /* ttyS2 */
+ {-1}, /* ttyS3 */
};
+
#define NR_PORTS ARRAY_SIZE(cy_port)
/*
@@ -128,42 +129,46 @@ struct cyclades_port cy_port[] = {
* HI VHI
*/
static int baud_table[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
- 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,115200,150000,
- 0};
+ 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200,
+ 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000,
+ 0
+};
#if 0
-static char baud_co[] = { /* 25 MHz clock option table */
- /* value => 00 01 02 03 04 */
- /* divide by 8 32 128 512 2048 */
- 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
- 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static char baud_co[] = { /* 25 MHz clock option table */
+ /* value => 00 01 02 03 04 */
+ /* divide by 8 32 128 512 2048 */
+ 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02,
+ 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
-static char baud_bpr[] = { /* 25 MHz baud rate period table */
- 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
- 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15};
+static char baud_bpr[] = { /* 25 MHz baud rate period table */
+ 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3,
+ 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15
+};
#endif
/* I think 166 brd clocks 2401 at 20MHz.... */
/* These values are written directly to tcor, and >> 5 for writing to rcor */
-static u_char baud_co[] = { /* 20 MHz clock option table */
- 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40,
- 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+static u_char baud_co[] = { /* 20 MHz clock option table */
+ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x60, 0x60, 0x40,
+ 0x40, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
/* These values written directly to tbpr/rbpr */
-static u_char baud_bpr[] = { /* 20 MHz baud rate period table */
- 0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81,
- 0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10};
-
-static u_char baud_cor4[] = { /* receive threshold */
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07};
-
+static u_char baud_bpr[] = { /* 20 MHz baud rate period table */
+ 0x00, 0xc0, 0x80, 0x58, 0x6c, 0x40, 0xc0, 0x81, 0x40, 0x81,
+ 0x57, 0x40, 0x81, 0x40, 0x81, 0x40, 0x2b, 0x20, 0x15, 0x10
+};
+static u_char baud_cor4[] = { /* receive threshold */
+ 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
+ 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07
+};
static void shutdown(struct cyclades_port *);
-static int startup (struct cyclades_port *);
+static int startup(struct cyclades_port *);
static void cy_throttle(struct tty_struct *);
static void cy_unthrottle(struct tty_struct *);
static void config_setup(struct cyclades_port *);
@@ -174,16 +179,16 @@ static void show_status(int);
#ifdef CONFIG_REMOTE_DEBUG
static void debug_setup(void);
-void queueDebugChar (int c);
+void queueDebugChar(int c);
int getDebugChar(void);
#define DEBUG_PORT 1
#define DEBUG_LEN 256
typedef struct {
- int in;
- int out;
- unsigned char buf[DEBUG_LEN];
+ int in;
+ int out;
+ unsigned char buf[DEBUG_LEN];
} debugq;
debugq debugiq;
@@ -196,7 +201,7 @@ debugq debugiq;
* delay, but this wild guess will do for now.
*/
-void my_udelay (long us)
+void my_udelay(long us)
{
u_char x;
volatile u_char *p = &x;
@@ -207,62 +212,73 @@ void my_udelay (long us)
x |= *p;
}
-static inline int
-serial_paranoia_check(struct cyclades_port *info, char *name,
- const char *routine)
+static inline int serial_paranoia_check(struct cyclades_port *info, char *name,
+ const char *routine)
{
#ifdef SERIAL_PARANOIA_CHECK
- static const char *badmagic =
- "Warning: bad magic number for serial struct (%s) in %s\n";
- static const char *badinfo =
- "Warning: null cyclades_port for (%s) in %s\n";
- static const char *badrange =
- "Warning: cyclades_port out of range for (%s) in %s\n";
-
- if (!info) {
- printk(badinfo, name, routine);
- return 1;
- }
-
- if( (long)info < (long)(&cy_port[0])
- || (long)(&cy_port[NR_PORTS]) < (long)info ){
- printk(badrange, name, routine);
- return 1;
- }
-
- if (info->magic != CYCLADES_MAGIC) {
- printk(badmagic, name, routine);
- return 1;
- }
+ if (!info) {
+ printk("Warning: null cyclades_port for (%s) in %s\n", name,
+ routine);
+ return 1;
+ }
+
+ if ((long)info < (long)(&cy_port[0])
+ || (long)(&cy_port[NR_PORTS]) < (long)info) {
+ printk("Warning: cyclades_port out of range for (%s) in %s\n",
+ name, routine);
+ return 1;
+ }
+
+ if (info->magic != CYCLADES_MAGIC) {
+ printk("Warning: bad magic number for serial struct (%s) in "
+ "%s\n", name, routine);
+ return 1;
+ }
#endif
return 0;
-} /* serial_paranoia_check */
+} /* serial_paranoia_check */
#if 0
/* The following diagnostic routines allow the driver to spew
information on the screen, even (especially!) during interrupts.
*/
-void
-SP(char *data){
- unsigned long flags;
- local_irq_save(flags);
- console_print(data);
- local_irq_restore(flags);
+void SP(char *data)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ console_print(data);
+ local_irq_restore(flags);
}
+
char scrn[2];
-void
-CP(char data){
- unsigned long flags;
- local_irq_save(flags);
- scrn[0] = data;
- console_print(scrn);
- local_irq_restore(flags);
-}/* CP */
+void CP(char data)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ scrn[0] = data;
+ console_print(scrn);
+ local_irq_restore(flags);
+} /* CP */
-void CP1(int data) { (data<10)? CP(data+'0'): CP(data+'A'-10); }/* CP1 */
-void CP2(int data) { CP1((data>>4) & 0x0f); CP1( data & 0x0f); }/* CP2 */
-void CP4(int data) { CP2((data>>8) & 0xff); CP2(data & 0xff); }/* CP4 */
-void CP8(long data) { CP4((data>>16) & 0xffff); CP4(data & 0xffff); }/* CP8 */
+void CP1(int data)
+{
+ (data < 10) ? CP(data + '0') : CP(data + 'A' - 10);
+} /* CP1 */
+void CP2(int data)
+{
+ CP1((data >> 4) & 0x0f);
+ CP1(data & 0x0f);
+} /* CP2 */
+void CP4(int data)
+{
+ CP2((data >> 8) & 0xff);
+ CP2(data & 0xff);
+} /* CP4 */
+void CP8(long data)
+{
+ CP4((data >> 16) & 0xffff);
+ CP4(data & 0xffff);
+} /* CP8 */
#endif
/* This routine waits up to 1000 micro-seconds for the previous
@@ -270,87 +286,78 @@ void CP8(long data) { CP4((data>>16) & 0xffff); CP4(data & 0xffff); }/* CP8 */
new command. An error is returned if the previous command
didn't finish within the time limit.
*/
-u_short
-write_cy_cmd(volatile u_char *base_addr, u_char cmd)
+u_short write_cy_cmd(volatile u_char * base_addr, u_char cmd)
{
- unsigned long flags;
- volatile int i;
+ unsigned long flags;
+ volatile int i;
- local_irq_save(flags);
+ local_irq_save(flags);
/* Check to see that the previous command has completed */
- for(i = 0 ; i < 100 ; i++){
- if (base_addr[CyCCR] == 0){
- break;
- }
- my_udelay(10L);
+ for (i = 0; i < 100; i++) {
+ if (base_addr[CyCCR] == 0) {
+ break;
+ }
+ my_udelay(10L);
}
/* if the CCR never cleared, the previous command
- didn't finish within the "reasonable time" */
- if ( i == 10 ) {
- local_irq_restore(flags);
- return (-1);
+ didn't finish within the "reasonable time" */
+ if (i == 10) {
+ local_irq_restore(flags);
+ return (-1);
}
/* Issue the new command */
base_addr[CyCCR] = cmd;
- local_irq_restore(flags);
- return(0);
-} /* write_cy_cmd */
-
+ local_irq_restore(flags);
+ return (0);
+} /* write_cy_cmd */
/* cy_start and cy_stop provide software output flow control as a
function of XON/XOFF, software CTS, and other such stuff. */
-static void
-cy_stop(struct tty_struct *tty)
+static void cy_stop(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
- int channel;
- unsigned long flags;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
+ int channel;
+ unsigned long flags;
#ifdef SERIAL_DEBUG_OTHER
- printk("cy_stop %s\n", tty->name); /* */
+ printk("cy_stop %s\n", tty->name); /* */
#endif
- if (serial_paranoia_check(info, tty->name, "cy_stop"))
- return;
-
- channel = info->line;
+ if (serial_paranoia_check(info, tty->name, "cy_stop"))
+ return;
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)(channel); /* index channel */
- base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
- local_irq_restore(flags);
+ channel = info->line;
- return;
-} /* cy_stop */
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) (channel); /* index channel */
+ base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
+ local_irq_restore(flags);
+} /* cy_stop */
-static void
-cy_start(struct tty_struct *tty)
+static void cy_start(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
- int channel;
- unsigned long flags;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
+ int channel;
+ unsigned long flags;
#ifdef SERIAL_DEBUG_OTHER
- printk("cy_start %s\n", tty->name); /* */
+ printk("cy_start %s\n", tty->name); /* */
#endif
- if (serial_paranoia_check(info, tty->name, "cy_start"))
- return;
-
- channel = info->line;
+ if (serial_paranoia_check(info, tty->name, "cy_start"))
+ return;
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)(channel);
- base_addr[CyIER] |= CyTxMpty;
- local_irq_restore(flags);
-
- return;
-} /* cy_start */
+ channel = info->line;
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) (channel);
+ base_addr[CyIER] |= CyTxMpty;
+ local_irq_restore(flags);
+} /* cy_start */
/*
* This routine is used by the interrupt handler to schedule
@@ -358,332 +365,332 @@ cy_start(struct tty_struct *tty)
* (also known as the "bottom half"). This can be called any
* number of times for any channel without harm.
*/
-static inline void
-cy_sched_event(struct cyclades_port *info, int event)
+static inline void cy_sched_event(struct cyclades_port *info, int event)
{
- info->event |= 1 << event; /* remember what kind of event and who */
- schedule_work(&info->tqueue);
-} /* cy_sched_event */
-
+ info->event |= 1 << event; /* remember what kind of event and who */
+ schedule_work(&info->tqueue);
+} /* cy_sched_event */
/* The real interrupt service routines are called
whenever the card wants its hand held--chars
received, out buffer empty, modem change, etc.
*/
-static irqreturn_t
-cd2401_rxerr_interrupt(int irq, void *dev_id)
+static irqreturn_t cd2401_rxerr_interrupt(int irq, void *dev_id)
{
- struct tty_struct *tty;
- struct cyclades_port *info;
- volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
- unsigned char err, rfoc;
- int channel;
- char data;
-
- /* determine the channel and change to that context */
- channel = (u_short ) (base_addr[CyLICR] >> 2);
- info = &cy_port[channel];
- info->last_active = jiffies;
-
- if ((err = base_addr[CyRISR]) & CyTIMEOUT) {
- /* This is a receive timeout interrupt, ignore it */
- base_addr[CyREOIR] = CyNOTRANS;
- return IRQ_HANDLED;
- }
-
- /* Read a byte of data if there is any - assume the error
- * is associated with this character */
+ struct tty_struct *tty;
+ struct cyclades_port *info;
+ volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
+ unsigned char err, rfoc;
+ int channel;
+ char data;
+
+ /* determine the channel and change to that context */
+ channel = (u_short) (base_addr[CyLICR] >> 2);
+ info = &cy_port[channel];
+ info->last_active = jiffies;
+
+ if ((err = base_addr[CyRISR]) & CyTIMEOUT) {
+ /* This is a receive timeout interrupt, ignore it */
+ base_addr[CyREOIR] = CyNOTRANS;
+ return IRQ_HANDLED;
+ }
- if ((rfoc = base_addr[CyRFOC]) != 0)
- data = base_addr[CyRDR];
- else
- data = 0;
+ /* Read a byte of data if there is any - assume the error
+ * is associated with this character */
- /* if there is nowhere to put the data, discard it */
- if(info->tty == 0) {
+ if ((rfoc = base_addr[CyRFOC]) != 0)
+ data = base_addr[CyRDR];
+ else
+ data = 0;
+
+ /* if there is nowhere to put the data, discard it */
+ if (info->tty == 0) {
+ base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
+ return IRQ_HANDLED;
+ } else { /* there is an open port for this data */
+ tty = info->tty;
+ if (err & info->ignore_status_mask) {
+ base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
+ return IRQ_HANDLED;
+ }
+ if (tty_buffer_request_room(tty, 1) != 0) {
+ if (err & info->read_status_mask) {
+ if (err & CyBREAK) {
+ tty_insert_flip_char(tty, data,
+ TTY_BREAK);
+ if (info->flags & ASYNC_SAK) {
+ do_SAK(tty);
+ }
+ } else if (err & CyFRAME) {
+ tty_insert_flip_char(tty, data,
+ TTY_FRAME);
+ } else if (err & CyPARITY) {
+ tty_insert_flip_char(tty, data,
+ TTY_PARITY);
+ } else if (err & CyOVERRUN) {
+ tty_insert_flip_char(tty, 0,
+ TTY_OVERRUN);
+ /*
+ If the flip buffer itself is
+ overflowing, we still loose
+ the next incoming character.
+ */
+ if (tty_buffer_request_room(tty, 1) !=
+ 0) {
+ tty_insert_flip_char(tty, data,
+ TTY_FRAME);
+ }
+ /* These two conditions may imply */
+ /* a normal read should be done. */
+ /* else if(data & CyTIMEOUT) */
+ /* else if(data & CySPECHAR) */
+ } else {
+ tty_insert_flip_char(tty, 0,
+ TTY_NORMAL);
+ }
+ } else {
+ tty_insert_flip_char(tty, data, TTY_NORMAL);
+ }
+ } else {
+ /* there was a software buffer overrun
+ and nothing could be done about it!!! */
+ }
+ }
+ tty_schedule_flip(tty);
+ /* end of service */
base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
return IRQ_HANDLED;
- }
- else { /* there is an open port for this data */
- tty = info->tty;
- if(err & info->ignore_status_mask){
- base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
- return IRQ_HANDLED;
- }
- if (tty_buffer_request_room(tty, 1) != 0){
- if (err & info->read_status_mask){
- if(err & CyBREAK){
- tty_insert_flip_char(tty, data, TTY_BREAK);
- if (info->flags & ASYNC_SAK){
- do_SAK(tty);
- }
- }else if(err & CyFRAME){
- tty_insert_flip_char(tty, data, TTY_FRAME);
- }else if(err & CyPARITY){
- tty_insert_flip_char(tty, data, TTY_PARITY);
- }else if(err & CyOVERRUN){
- tty_insert_flip_char(tty, 0, TTY_OVERRUN);
- /*
- If the flip buffer itself is
- overflowing, we still loose
- the next incoming character.
- */
- if (tty_buffer_request_room(tty, 1) != 0){
- tty_insert_flip_char(tty, data, TTY_FRAME);
- }
- /* These two conditions may imply */
- /* a normal read should be done. */
- /* else if(data & CyTIMEOUT) */
- /* else if(data & CySPECHAR) */
- }else{
- tty_insert_flip_char(tty, 0, TTY_NORMAL);
- }
- }else{
- tty_insert_flip_char(tty, data, TTY_NORMAL);
- }
- }else{
- /* there was a software buffer overrun
- and nothing could be done about it!!! */
- }
- }
- tty_schedule_flip(tty);
- /* end of service */
- base_addr[CyREOIR] = rfoc ? 0 : CyNOTRANS;
- return IRQ_HANDLED;
-} /* cy_rxerr_interrupt */
-
-static irqreturn_t
-cd2401_modem_interrupt(int irq, void *dev_id)
+} /* cy_rxerr_interrupt */
+
+static irqreturn_t cd2401_modem_interrupt(int irq, void *dev_id)
{
- struct cyclades_port *info;
- volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
- int channel;
- int mdm_change;
- int mdm_status;
-
-
- /* determine the channel and change to that context */
- channel = (u_short ) (base_addr[CyLICR] >> 2);
- info = &cy_port[channel];
- info->last_active = jiffies;
-
- mdm_change = base_addr[CyMISR];
- mdm_status = base_addr[CyMSVR1];
-
- if(info->tty == 0){ /* nowhere to put the data, ignore it */
- ;
- }else{
- if((mdm_change & CyDCD)
- && (info->flags & ASYNC_CHECK_CD)){
- if(mdm_status & CyDCD){
+ struct cyclades_port *info;
+ volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
+ int channel;
+ int mdm_change;
+ int mdm_status;
+
+ /* determine the channel and change to that context */
+ channel = (u_short) (base_addr[CyLICR] >> 2);
+ info = &cy_port[channel];
+ info->last_active = jiffies;
+
+ mdm_change = base_addr[CyMISR];
+ mdm_status = base_addr[CyMSVR1];
+
+ if (info->tty == 0) { /* nowhere to put the data, ignore it */
+ ;
+ } else {
+ if ((mdm_change & CyDCD)
+ && (info->flags & ASYNC_CHECK_CD)) {
+ if (mdm_status & CyDCD) {
/* CP('!'); */
- cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
- } else {
+ cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP);
+ } else {
/* CP('@'); */
- cy_sched_event(info, Cy_EVENT_HANGUP);
- }
- }
- if((mdm_change & CyCTS)
- && (info->flags & ASYNC_CTS_FLOW)){
- if(info->tty->stopped){
- if(mdm_status & CyCTS){
- /* !!! cy_start isn't used because... */
- info->tty->stopped = 0;
- base_addr[CyIER] |= CyTxMpty;
- cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
+ cy_sched_event(info, Cy_EVENT_HANGUP);
+ }
}
- }else{
- if(!(mdm_status & CyCTS)){
- /* !!! cy_stop isn't used because... */
- info->tty->stopped = 1;
- base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
+ if ((mdm_change & CyCTS)
+ && (info->flags & ASYNC_CTS_FLOW)) {
+ if (info->tty->stopped) {
+ if (mdm_status & CyCTS) {
+ /* !!! cy_start isn't used because... */
+ info->tty->stopped = 0;
+ base_addr[CyIER] |= CyTxMpty;
+ cy_sched_event(info,
+ Cy_EVENT_WRITE_WAKEUP);
+ }
+ } else {
+ if (!(mdm_status & CyCTS)) {
+ /* !!! cy_stop isn't used because... */
+ info->tty->stopped = 1;
+ base_addr[CyIER] &=
+ ~(CyTxMpty | CyTxRdy);
+ }
+ }
+ }
+ if (mdm_status & CyDSR) {
}
- }
- }
- if(mdm_status & CyDSR){
}
- }
- base_addr[CyMEOIR] = 0;
- return IRQ_HANDLED;
-} /* cy_modem_interrupt */
+ base_addr[CyMEOIR] = 0;
+ return IRQ_HANDLED;
+} /* cy_modem_interrupt */
-static irqreturn_t
-cd2401_tx_interrupt(int irq, void *dev_id)
+static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id)
{
- struct cyclades_port *info;
- volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
- int channel;
- int char_count, saved_cnt;
- int outch;
+ struct cyclades_port *info;
+ volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
+ int channel;
+ int char_count, saved_cnt;
+ int outch;
- /* determine the channel and change to that context */
- channel = (u_short ) (base_addr[CyLICR] >> 2);
+ /* determine the channel and change to that context */
+ channel = (u_short) (base_addr[CyLICR] >> 2);
#ifdef CONFIG_REMOTE_DEBUG
- if (channel == DEBUG_PORT) {
- panic ("TxInt on debug port!!!");
- }
+ if (channel == DEBUG_PORT) {
+ panic("TxInt on debug port!!!");
+ }
#endif
- info = &cy_port[channel];
+ info = &cy_port[channel];
- /* validate the port number (as configured and open) */
- if( (channel < 0) || (NR_PORTS <= channel) ){
- base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
- base_addr[CyTEOIR] = CyNOTRANS;
- return IRQ_HANDLED;
- }
- info->last_active = jiffies;
- if(info->tty == 0){
- base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
- if (info->xmit_cnt < WAKEUP_CHARS) {
- cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
- }
- base_addr[CyTEOIR] = CyNOTRANS;
- return IRQ_HANDLED;
- }
-
- /* load the on-chip space available for outbound data */
- saved_cnt = char_count = base_addr[CyTFTC];
-
- if(info->x_char) { /* send special char */
- outch = info->x_char;
- base_addr[CyTDR] = outch;
- char_count--;
- info->x_char = 0;
- }
-
- if (info->x_break){
- /* The Cirrus chip requires the "Embedded Transmit
- Commands" of start break, delay, and end break
- sequences to be sent. The duration of the
- break is given in TICs, which runs at HZ
- (typically 100) and the PPR runs at 200 Hz,
- so the delay is duration * 200/HZ, and thus a
- break can run from 1/100 sec to about 5/4 sec.
- Need to check these values - RGH 141095.
- */
- base_addr[CyTDR] = 0; /* start break */
- base_addr[CyTDR] = 0x81;
- base_addr[CyTDR] = 0; /* delay a bit */
- base_addr[CyTDR] = 0x82;
- base_addr[CyTDR] = info->x_break*200/HZ;
- base_addr[CyTDR] = 0; /* terminate break */
- base_addr[CyTDR] = 0x83;
- char_count -= 7;
- info->x_break = 0;
- }
-
- while (char_count > 0){
- if (!info->xmit_cnt){
- base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
- break;
- }
- if (info->xmit_buf == 0){
- base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
- break;
- }
- if (info->tty->stopped || info->tty->hw_stopped){
- base_addr[CyIER] &= ~(CyTxMpty|CyTxRdy);
- break;
- }
- /* Because the Embedded Transmit Commands have been
- enabled, we must check to see if the escape
- character, NULL, is being sent. If it is, we
- must ensure that there is room for it to be
- doubled in the output stream. Therefore we
- no longer advance the pointer when the character
- is fetched, but rather wait until after the check
- for a NULL output character. (This is necessary
- because there may not be room for the two chars
- needed to send a NULL.
- */
- outch = info->xmit_buf[info->xmit_tail];
- if( outch ){
- info->xmit_cnt--;
- info->xmit_tail = (info->xmit_tail + 1)
- & (PAGE_SIZE - 1);
- base_addr[CyTDR] = outch;
- char_count--;
- }else{
- if(char_count > 1){
- info->xmit_cnt--;
- info->xmit_tail = (info->xmit_tail + 1)
- & (PAGE_SIZE - 1);
+ /* validate the port number (as configured and open) */
+ if ((channel < 0) || (NR_PORTS <= channel)) {
+ base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
+ base_addr[CyTEOIR] = CyNOTRANS;
+ return IRQ_HANDLED;
+ }
+ info->last_active = jiffies;
+ if (info->tty == 0) {
+ base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
+ if (info->xmit_cnt < WAKEUP_CHARS) {
+ cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
+ }
+ base_addr[CyTEOIR] = CyNOTRANS;
+ return IRQ_HANDLED;
+ }
+
+ /* load the on-chip space available for outbound data */
+ saved_cnt = char_count = base_addr[CyTFTC];
+
+ if (info->x_char) { /* send special char */
+ outch = info->x_char;
base_addr[CyTDR] = outch;
- base_addr[CyTDR] = 0;
char_count--;
- char_count--;
- }else{
- break;
- }
+ info->x_char = 0;
}
- }
- if (info->xmit_cnt < WAKEUP_CHARS) {
- cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
- }
- base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS;
- return IRQ_HANDLED;
-} /* cy_tx_interrupt */
+ if (info->x_break) {
+ /* The Cirrus chip requires the "Embedded Transmit
+ Commands" of start break, delay, and end break
+ sequences to be sent. The duration of the
+ break is given in TICs, which runs at HZ
+ (typically 100) and the PPR runs at 200 Hz,
+ so the delay is duration * 200/HZ, and thus a
+ break can run from 1/100 sec to about 5/4 sec.
+ Need to check these values - RGH 141095.
+ */
+ base_addr[CyTDR] = 0; /* start break */
+ base_addr[CyTDR] = 0x81;
+ base_addr[CyTDR] = 0; /* delay a bit */
+ base_addr[CyTDR] = 0x82;
+ base_addr[CyTDR] = info->x_break * 200 / HZ;
+ base_addr[CyTDR] = 0; /* terminate break */
+ base_addr[CyTDR] = 0x83;
+ char_count -= 7;
+ info->x_break = 0;
+ }
+
+ while (char_count > 0) {
+ if (!info->xmit_cnt) {
+ base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
+ break;
+ }
+ if (info->xmit_buf == 0) {
+ base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
+ break;
+ }
+ if (info->tty->stopped || info->tty->hw_stopped) {
+ base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
+ break;
+ }
+ /* Because the Embedded Transmit Commands have been
+ enabled, we must check to see if the escape
+ character, NULL, is being sent. If it is, we
+ must ensure that there is room for it to be
+ doubled in the output stream. Therefore we
+ no longer advance the pointer when the character
+ is fetched, but rather wait until after the check
+ for a NULL output character. (This is necessary
+ because there may not be room for the two chars
+ needed to send a NULL.
+ */
+ outch = info->xmit_buf[info->xmit_tail];
+ if (outch) {
+ info->xmit_cnt--;
+ info->xmit_tail = (info->xmit_tail + 1)
+ & (PAGE_SIZE - 1);
+ base_addr[CyTDR] = outch;
+ char_count--;
+ } else {
+ if (char_count > 1) {
+ info->xmit_cnt--;
+ info->xmit_tail = (info->xmit_tail + 1)
+ & (PAGE_SIZE - 1);
+ base_addr[CyTDR] = outch;
+ base_addr[CyTDR] = 0;
+ char_count--;
+ char_count--;
+ } else {
+ break;
+ }
+ }
+ }
+
+ if (info->xmit_cnt < WAKEUP_CHARS) {
+ cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP);
+ }
+ base_addr[CyTEOIR] = (char_count != saved_cnt) ? 0 : CyNOTRANS;
+ return IRQ_HANDLED;
+} /* cy_tx_interrupt */
-static irqreturn_t
-cd2401_rx_interrupt(int irq, void *dev_id)
+static irqreturn_t cd2401_rx_interrupt(int irq, void *dev_id)
{
- struct tty_struct *tty;
- struct cyclades_port *info;
- volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
- int channel;
- char data;
- int char_count;
- int save_cnt;
- int len;
-
- /* determine the channel and change to that context */
- channel = (u_short ) (base_addr[CyLICR] >> 2);
- info = &cy_port[channel];
- info->last_active = jiffies;
- save_cnt = char_count = base_addr[CyRFOC];
+ struct tty_struct *tty;
+ struct cyclades_port *info;
+ volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
+ int channel;
+ char data;
+ int char_count;
+ int save_cnt;
+ int len;
+
+ /* determine the channel and change to that context */
+ channel = (u_short) (base_addr[CyLICR] >> 2);
+ info = &cy_port[channel];
+ info->last_active = jiffies;
+ save_cnt = char_count = base_addr[CyRFOC];
#ifdef CONFIG_REMOTE_DEBUG
- if (channel == DEBUG_PORT) {
- while (char_count--) {
- data = base_addr[CyRDR];
- queueDebugChar(data);
- }
- }
- else
+ if (channel == DEBUG_PORT) {
+ while (char_count--) {
+ data = base_addr[CyRDR];
+ queueDebugChar(data);
+ }
+ } else
#endif
- /* if there is nowhere to put the data, discard it */
- if(info->tty == 0){
- while(char_count--){
- data = base_addr[CyRDR];
- }
- }else{ /* there is an open port for this data */
- tty = info->tty;
- /* load # characters available from the chip */
+ /* if there is nowhere to put the data, discard it */
+ if (info->tty == 0) {
+ while (char_count--) {
+ data = base_addr[CyRDR];
+ }
+ } else { /* there is an open port for this data */
+ tty = info->tty;
+ /* load # characters available from the chip */
#ifdef CYCLOM_ENABLE_MONITORING
- ++info->mon.int_count;
- info->mon.char_count += char_count;
- if (char_count > info->mon.char_max)
- info->mon.char_max = char_count;
- info->mon.char_last = char_count;
-#endif
- len = tty_buffer_request_room(tty, char_count);
- while(len--){
- data = base_addr[CyRDR];
- tty_insert_flip_char(tty, data, TTY_NORMAL);
+ ++info->mon.int_count;
+ info->mon.char_count += char_count;
+ if (char_count > info->mon.char_max)
+ info->mon.char_max = char_count;
+ info->mon.char_last = char_count;
+#endif
+ len = tty_buffer_request_room(tty, char_count);
+ while (len--) {
+ data = base_addr[CyRDR];
+ tty_insert_flip_char(tty, data, TTY_NORMAL);
#ifdef CYCLOM_16Y_HACK
- udelay(10L);
+ udelay(10L);
#endif
- }
- tty_schedule_flip(tty);
- }
- /* end of service */
- base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
- return IRQ_HANDLED;
-} /* cy_rx_interrupt */
+ }
+ tty_schedule_flip(tty);
+ }
+ /* end of service */
+ base_addr[CyREOIR] = save_cnt ? 0 : CyNOTRANS;
+ return IRQ_HANDLED;
+} /* cy_rx_interrupt */
/*
* This routine is used to handle the "bottom half" processing for the
@@ -705,192 +712,188 @@ cd2401_rx_interrupt(int irq, void *dev_id)
* structure) to the bottom half of the driver. Previous kernels
* had to poll every port to see if that port needed servicing.
*/
-static void
-do_softint(struct work_struct *ugly_api)
+static void do_softint(struct work_struct *ugly_api)
{
- struct cyclades_port *info = container_of(ugly_api, struct cyclades_port, tqueue);
- struct tty_struct *tty;
-
- tty = info->tty;
- if (!tty)
- return;
+ struct cyclades_port *info =
+ container_of(ugly_api, struct cyclades_port, tqueue);
+ struct tty_struct *tty;
- if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
- tty_hangup(info->tty);
- wake_up_interruptible(&info->open_wait);
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- }
- if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
- wake_up_interruptible(&info->open_wait);
- }
- if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
- tty_wakeup(tty);
- }
-} /* do_softint */
+ tty = info->tty;
+ if (!tty)
+ return;
+ if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) {
+ tty_hangup(info->tty);
+ wake_up_interruptible(&info->open_wait);
+ info->flags &= ~ASYNC_NORMAL_ACTIVE;
+ }
+ if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) {
+ wake_up_interruptible(&info->open_wait);
+ }
+ if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) {
+ tty_wakeup(tty);
+ }
+} /* do_softint */
/* This is called whenever a port becomes active;
interrupts are enabled and DTR & RTS are turned on.
*/
-static int
-startup(struct cyclades_port * info)
+static int startup(struct cyclades_port *info)
{
- unsigned long flags;
- volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
- int channel;
+ unsigned long flags;
+ volatile unsigned char *base_addr = (unsigned char *)BASE_ADDR;
+ int channel;
- if (info->flags & ASYNC_INITIALIZED){
- return 0;
- }
+ if (info->flags & ASYNC_INITIALIZED) {
+ return 0;
+ }
- if (!info->type){
- if (info->tty){
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (!info->type) {
+ if (info->tty) {
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
+ }
+ return 0;
}
- return 0;
- }
- if (!info->xmit_buf){
- info->xmit_buf = (unsigned char *) get_zeroed_page (GFP_KERNEL);
- if (!info->xmit_buf){
- return -ENOMEM;
+ if (!info->xmit_buf) {
+ info->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
+ if (!info->xmit_buf) {
+ return -ENOMEM;
+ }
}
- }
- config_setup(info);
+ config_setup(info);
- channel = info->line;
+ channel = info->line;
#ifdef SERIAL_DEBUG_OPEN
- printk("startup channel %d\n", channel);
+ printk("startup channel %d\n", channel);
#endif
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
- write_cy_cmd(base_addr,CyENB_RCVR|CyENB_XMTR);
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
+ write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR);
- base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */
+ base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */
base_addr[CyMSVR1] = CyRTS;
/* CP('S');CP('1'); */
base_addr[CyMSVR2] = CyDTR;
#ifdef SERIAL_DEBUG_DTR
- printk("cyc: %d: raising DTR\n", __LINE__);
- printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
+ printk("cyc: %d: raising DTR\n", __LINE__);
+ printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
+ base_addr[CyMSVR2]);
#endif
base_addr[CyIER] |= CyRxData;
info->flags |= ASYNC_INITIALIZED;
- if (info->tty){
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->tty) {
+ clear_bit(TTY_IO_ERROR, &info->tty->flags);
}
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- local_irq_restore(flags);
+ local_irq_restore(flags);
#ifdef SERIAL_DEBUG_OPEN
- printk(" done\n");
+ printk(" done\n");
#endif
- return 0;
-} /* startup */
+ return 0;
+} /* startup */
-void
-start_xmit( struct cyclades_port *info )
+void start_xmit(struct cyclades_port *info)
{
- unsigned long flags;
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
+ unsigned long flags;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
- channel = info->line;
- local_irq_save(flags);
+ channel = info->line;
+ local_irq_save(flags);
base_addr[CyCAR] = channel;
base_addr[CyIER] |= CyTxMpty;
- local_irq_restore(flags);
-} /* start_xmit */
+ local_irq_restore(flags);
+} /* start_xmit */
/*
* This routine shuts down a serial port; interrupts are disabled,
* and DTR is dropped if the hangup on close termio flag is on.
*/
-static void
-shutdown(struct cyclades_port * info)
+static void shutdown(struct cyclades_port *info)
{
- unsigned long flags;
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
+ unsigned long flags;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
- if (!(info->flags & ASYNC_INITIALIZED)){
+ if (!(info->flags & ASYNC_INITIALIZED)) {
/* CP('$'); */
- return;
- }
+ return;
+ }
- channel = info->line;
+ channel = info->line;
#ifdef SERIAL_DEBUG_OPEN
- printk("shutdown channel %d\n", channel);
+ printk("shutdown channel %d\n", channel);
#endif
- /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE
- SENT BEFORE DROPPING THE LINE !!! (Perhaps
- set some flag that is read when XMTY happens.)
- Other choices are to delay some fixed interval
- or schedule some later processing.
- */
- local_irq_save(flags);
- if (info->xmit_buf){
- free_page((unsigned long) info->xmit_buf);
- info->xmit_buf = NULL;
+ /* !!! REALLY MUST WAIT FOR LAST CHARACTER TO BE
+ SENT BEFORE DROPPING THE LINE !!! (Perhaps
+ set some flag that is read when XMTY happens.)
+ Other choices are to delay some fixed interval
+ or schedule some later processing.
+ */
+ local_irq_save(flags);
+ if (info->xmit_buf) {
+ free_page((unsigned long)info->xmit_buf);
+ info->xmit_buf = NULL;
}
- base_addr[CyCAR] = (u_char)channel;
+ base_addr[CyCAR] = (u_char) channel;
if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
- base_addr[CyMSVR1] = 0;
+ base_addr[CyMSVR1] = 0;
/* CP('C');CP('1'); */
- base_addr[CyMSVR2] = 0;
+ base_addr[CyMSVR2] = 0;
#ifdef SERIAL_DEBUG_DTR
- printk("cyc: %d: dropping DTR\n", __LINE__);
- printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
+ printk("cyc: %d: dropping DTR\n", __LINE__);
+ printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
+ base_addr[CyMSVR2]);
#endif
- }
- write_cy_cmd(base_addr,CyDIS_RCVR);
- /* it may be appropriate to clear _XMIT at
- some later date (after testing)!!! */
+ }
+ write_cy_cmd(base_addr, CyDIS_RCVR);
+ /* it may be appropriate to clear _XMIT at
+ some later date (after testing)!!! */
- if (info->tty){
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->tty) {
+ set_bit(TTY_IO_ERROR, &info->tty->flags);
}
info->flags &= ~ASYNC_INITIALIZED;
- local_irq_restore(flags);
+ local_irq_restore(flags);
#ifdef SERIAL_DEBUG_OPEN
- printk(" done\n");
+ printk(" done\n");
#endif
- return;
-} /* shutdown */
+} /* shutdown */
/*
* This routine finds or computes the various line characteristics.
*/
-static void
-config_setup(struct cyclades_port * info)
+static void config_setup(struct cyclades_port *info)
{
- unsigned long flags;
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
- unsigned cflag;
- int i;
- unsigned char ti, need_init_chan = 0;
-
- if (!info->tty || !info->tty->termios){
- return;
- }
- if (info->line == -1){
- return;
- }
- cflag = info->tty->termios->c_cflag;
-
- /* baud rate */
- i = cflag & CBAUD;
+ unsigned long flags;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
+ unsigned cflag;
+ int i;
+ unsigned char ti, need_init_chan = 0;
+
+ if (!info->tty || !info->tty->termios) {
+ return;
+ }
+ if (info->line == -1) {
+ return;
+ }
+ cflag = info->tty->termios->c_cflag;
+
+ /* baud rate */
+ i = cflag & CBAUD;
#ifdef CBAUDEX
/* Starting with kernel 1.1.65, there is direct support for
higher baud rates. The following code supports those
@@ -900,120 +903,123 @@ config_setup(struct cyclades_port * info)
is still the possibility of supporting 75 kbit/sec with
the Cyclades board.)
*/
- if (i & CBAUDEX) {
- if (i == B57600)
- i = 16;
- else if(i == B115200)
- i = 18;
+ if (i & CBAUDEX) {
+ if (i == B57600)
+ i = 16;
+ else if (i == B115200)
+ i = 18;
#ifdef B78600
- else if(i == B78600)
- i = 17;
+ else if (i == B78600)
+ i = 17;
#endif
- else
- info->tty->termios->c_cflag &= ~CBAUDEX;
- }
-#endif
- if (i == 15) {
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- i += 1;
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
- i += 3;
- }
- /* Don't ever change the speed of the console port. It will
- * run at the speed specified in bootinfo, or at 19.2K */
- /* Actually, it should run at whatever speed 166Bug was using */
- /* Note info->timeout isn't used at present */
- if (info != serial_console_info) {
- info->tbpr = baud_bpr[i]; /* Tx BPR */
- info->tco = baud_co[i]; /* Tx CO */
- info->rbpr = baud_bpr[i]; /* Rx BPR */
- info->rco = baud_co[i] >> 5; /* Rx CO */
- if (baud_table[i] == 134) {
- info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
- /* get it right for 134.5 baud */
- } else if (baud_table[i]) {
- info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
- /* this needs to be propagated into the card info */
+ else
+ info->tty->termios->c_cflag &= ~CBAUDEX;
+ }
+#endif
+ if (i == 15) {
+ if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+ i += 1;
+ if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+ i += 3;
+ }
+ /* Don't ever change the speed of the console port. It will
+ * run at the speed specified in bootinfo, or at 19.2K */
+ /* Actually, it should run at whatever speed 166Bug was using */
+ /* Note info->timeout isn't used at present */
+ if (info != serial_console_info) {
+ info->tbpr = baud_bpr[i]; /* Tx BPR */
+ info->tco = baud_co[i]; /* Tx CO */
+ info->rbpr = baud_bpr[i]; /* Rx BPR */
+ info->rco = baud_co[i] >> 5; /* Rx CO */
+ if (baud_table[i] == 134) {
+ info->timeout =
+ (info->xmit_fifo_size * HZ * 30 / 269) + 2;
+ /* get it right for 134.5 baud */
+ } else if (baud_table[i]) {
+ info->timeout =
+ (info->xmit_fifo_size * HZ * 15 / baud_table[i]) +
+ 2;
+ /* this needs to be propagated into the card info */
+ } else {
+ info->timeout = 0;
+ }
+ }
+ /* By tradition (is it a standard?) a baud rate of zero
+ implies the line should be/has been closed. A bit
+ later in this routine such a test is performed. */
+
+ /* byte size and parity */
+ info->cor7 = 0;
+ info->cor6 = 0;
+ info->cor5 = 0;
+ info->cor4 = (info->default_threshold ? info->default_threshold : baud_cor4[i]); /* receive threshold */
+ /* Following two lines added 101295, RGH. */
+ /* It is obviously wrong to access CyCORx, and not info->corx here,
+ * try and remember to fix it later! */
+ channel = info->line;
+ base_addr[CyCAR] = (u_char) channel;
+ if (C_CLOCAL(info->tty)) {
+ if (base_addr[CyIER] & CyMdmCh)
+ base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */
+ /* ignore 1->0 modem transitions */
+ if (base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD))
+ base_addr[CyCOR4] &= ~(CyDSR | CyCTS | CyDCD);
+ /* ignore 0->1 modem transitions */
+ if (base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD))
+ base_addr[CyCOR5] &= ~(CyDSR | CyCTS | CyDCD);
} else {
- info->timeout = 0;
- }
- }
- /* By tradition (is it a standard?) a baud rate of zero
- implies the line should be/has been closed. A bit
- later in this routine such a test is performed. */
-
- /* byte size and parity */
- info->cor7 = 0;
- info->cor6 = 0;
- info->cor5 = 0;
- info->cor4 = (info->default_threshold
- ? info->default_threshold
- : baud_cor4[i]); /* receive threshold */
- /* Following two lines added 101295, RGH. */
- /* It is obviously wrong to access CyCORx, and not info->corx here,
- * try and remember to fix it later! */
- channel = info->line;
- base_addr[CyCAR] = (u_char)channel;
- if (C_CLOCAL(info->tty)) {
- if (base_addr[CyIER] & CyMdmCh)
- base_addr[CyIER] &= ~CyMdmCh; /* without modem intr */
- /* ignore 1->0 modem transitions */
- if (base_addr[CyCOR4] & (CyDSR|CyCTS|CyDCD))
- base_addr[CyCOR4] &= ~(CyDSR|CyCTS|CyDCD);
- /* ignore 0->1 modem transitions */
- if (base_addr[CyCOR5] & (CyDSR|CyCTS|CyDCD))
- base_addr[CyCOR5] &= ~(CyDSR|CyCTS|CyDCD);
- } else {
- if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh)
- base_addr[CyIER] |= CyMdmCh; /* with modem intr */
- /* act on 1->0 modem transitions */
- if ((base_addr[CyCOR4] & (CyDSR|CyCTS|CyDCD)) != (CyDSR|CyCTS|CyDCD))
- base_addr[CyCOR4] |= CyDSR|CyCTS|CyDCD;
- /* act on 0->1 modem transitions */
- if ((base_addr[CyCOR5] & (CyDSR|CyCTS|CyDCD)) != (CyDSR|CyCTS|CyDCD))
- base_addr[CyCOR5] |= CyDSR|CyCTS|CyDCD;
- }
- info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP;
- info->cor2 = CyETC;
- switch(cflag & CSIZE){
- case CS5:
- info->cor1 = Cy_5_BITS;
- break;
- case CS6:
- info->cor1 = Cy_6_BITS;
- break;
- case CS7:
- info->cor1 = Cy_7_BITS;
- break;
- case CS8:
- info->cor1 = Cy_8_BITS;
- break;
- }
- if (cflag & PARENB){
- if (cflag & PARODD){
- info->cor1 |= CyPARITY_O;
- }else{
- info->cor1 |= CyPARITY_E;
- }
- }else{
- info->cor1 |= CyPARITY_NONE;
- }
-
- /* CTS flow control flag */
+ if ((base_addr[CyIER] & CyMdmCh) != CyMdmCh)
+ base_addr[CyIER] |= CyMdmCh; /* with modem intr */
+ /* act on 1->0 modem transitions */
+ if ((base_addr[CyCOR4] & (CyDSR | CyCTS | CyDCD)) !=
+ (CyDSR | CyCTS | CyDCD))
+ base_addr[CyCOR4] |= CyDSR | CyCTS | CyDCD;
+ /* act on 0->1 modem transitions */
+ if ((base_addr[CyCOR5] & (CyDSR | CyCTS | CyDCD)) !=
+ (CyDSR | CyCTS | CyDCD))
+ base_addr[CyCOR5] |= CyDSR | CyCTS | CyDCD;
+ }
+ info->cor3 = (cflag & CSTOPB) ? Cy_2_STOP : Cy_1_STOP;
+ info->cor2 = CyETC;
+ switch (cflag & CSIZE) {
+ case CS5:
+ info->cor1 = Cy_5_BITS;
+ break;
+ case CS6:
+ info->cor1 = Cy_6_BITS;
+ break;
+ case CS7:
+ info->cor1 = Cy_7_BITS;
+ break;
+ case CS8:
+ info->cor1 = Cy_8_BITS;
+ break;
+ }
+ if (cflag & PARENB) {
+ if (cflag & PARODD) {
+ info->cor1 |= CyPARITY_O;
+ } else {
+ info->cor1 |= CyPARITY_E;
+ }
+ } else {
+ info->cor1 |= CyPARITY_NONE;
+ }
+
+ /* CTS flow control flag */
#if 0
- /* Don't complcate matters for now! RGH 141095 */
- if (cflag & CRTSCTS){
- info->flags |= ASYNC_CTS_FLOW;
- info->cor2 |= CyCtsAE;
- }else{
- info->flags &= ~ASYNC_CTS_FLOW;
- info->cor2 &= ~CyCtsAE;
- }
-#endif
- if (cflag & CLOCAL)
- info->flags &= ~ASYNC_CHECK_CD;
- else
- info->flags |= ASYNC_CHECK_CD;
+ /* Don't complcate matters for now! RGH 141095 */
+ if (cflag & CRTSCTS) {
+ info->flags |= ASYNC_CTS_FLOW;
+ info->cor2 |= CyCtsAE;
+ } else {
+ info->flags &= ~ASYNC_CTS_FLOW;
+ info->cor2 &= ~CyCtsAE;
+ }
+#endif
+ if (cflag & CLOCAL)
+ info->flags &= ~ASYNC_CHECK_CD;
+ else
+ info->flags |= ASYNC_CHECK_CD;
/***********************************************
The hardware option, CyRtsAO, presents RTS when
@@ -1025,149 +1031,146 @@ config_setup(struct cyclades_port * info)
cable. Contact Marcio Saito for details.
***********************************************/
- channel = info->line;
+ channel = info->line;
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
/* CyCMR set once only in mvme167_init_serial() */
if (base_addr[CyLICR] != channel << 2)
- base_addr[CyLICR] = channel << 2;
+ base_addr[CyLICR] = channel << 2;
if (base_addr[CyLIVR] != 0x5c)
- base_addr[CyLIVR] = 0x5c;
+ base_addr[CyLIVR] = 0x5c;
- /* tx and rx baud rate */
+ /* tx and rx baud rate */
if (base_addr[CyCOR1] != info->cor1)
- need_init_chan = 1;
+ need_init_chan = 1;
if (base_addr[CyTCOR] != info->tco)
- base_addr[CyTCOR] = info->tco;
+ base_addr[CyTCOR] = info->tco;
if (base_addr[CyTBPR] != info->tbpr)
- base_addr[CyTBPR] = info->tbpr;
+ base_addr[CyTBPR] = info->tbpr;
if (base_addr[CyRCOR] != info->rco)
- base_addr[CyRCOR] = info->rco;
+ base_addr[CyRCOR] = info->rco;
if (base_addr[CyRBPR] != info->rbpr)
- base_addr[CyRBPR] = info->rbpr;
+ base_addr[CyRBPR] = info->rbpr;
/* set line characteristics according configuration */
if (base_addr[CySCHR1] != START_CHAR(info->tty))
- base_addr[CySCHR1] = START_CHAR(info->tty);
+ base_addr[CySCHR1] = START_CHAR(info->tty);
if (base_addr[CySCHR2] != STOP_CHAR(info->tty))
- base_addr[CySCHR2] = STOP_CHAR(info->tty);
+ base_addr[CySCHR2] = STOP_CHAR(info->tty);
if (base_addr[CySCRL] != START_CHAR(info->tty))
- base_addr[CySCRL] = START_CHAR(info->tty);
+ base_addr[CySCRL] = START_CHAR(info->tty);
if (base_addr[CySCRH] != START_CHAR(info->tty))
- base_addr[CySCRH] = START_CHAR(info->tty);
+ base_addr[CySCRH] = START_CHAR(info->tty);
if (base_addr[CyCOR1] != info->cor1)
- base_addr[CyCOR1] = info->cor1;
+ base_addr[CyCOR1] = info->cor1;
if (base_addr[CyCOR2] != info->cor2)
- base_addr[CyCOR2] = info->cor2;
+ base_addr[CyCOR2] = info->cor2;
if (base_addr[CyCOR3] != info->cor3)
- base_addr[CyCOR3] = info->cor3;
+ base_addr[CyCOR3] = info->cor3;
if (base_addr[CyCOR4] != info->cor4)
- base_addr[CyCOR4] = info->cor4;
+ base_addr[CyCOR4] = info->cor4;
if (base_addr[CyCOR5] != info->cor5)
- base_addr[CyCOR5] = info->cor5;
+ base_addr[CyCOR5] = info->cor5;
if (base_addr[CyCOR6] != info->cor6)
- base_addr[CyCOR6] = info->cor6;
+ base_addr[CyCOR6] = info->cor6;
if (base_addr[CyCOR7] != info->cor7)
- base_addr[CyCOR7] = info->cor7;
+ base_addr[CyCOR7] = info->cor7;
if (need_init_chan)
- write_cy_cmd(base_addr,CyINIT_CHAN);
+ write_cy_cmd(base_addr, CyINIT_CHAN);
- base_addr[CyCAR] = (u_char)channel; /* !!! Is this needed? */
+ base_addr[CyCAR] = (u_char) channel; /* !!! Is this needed? */
/* 2ms default rx timeout */
ti = info->default_timeout ? info->default_timeout : 0x02;
if (base_addr[CyRTPRL] != ti)
- base_addr[CyRTPRL] = ti;
+ base_addr[CyRTPRL] = ti;
if (base_addr[CyRTPRH] != 0)
- base_addr[CyRTPRH] = 0;
+ base_addr[CyRTPRH] = 0;
/* Set up RTS here also ????? RGH 141095 */
- if(i == 0){ /* baud rate is zero, turn off line */
- if ((base_addr[CyMSVR2] & CyDTR) == CyDTR)
- base_addr[CyMSVR2] = 0;
+ if (i == 0) { /* baud rate is zero, turn off line */
+ if ((base_addr[CyMSVR2] & CyDTR) == CyDTR)
+ base_addr[CyMSVR2] = 0;
#ifdef SERIAL_DEBUG_DTR
- printk("cyc: %d: dropping DTR\n", __LINE__);
- printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
+ printk("cyc: %d: dropping DTR\n", __LINE__);
+ printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
+ base_addr[CyMSVR2]);
#endif
- }else{
- if ((base_addr[CyMSVR2] & CyDTR) != CyDTR)
- base_addr[CyMSVR2] = CyDTR;
+ } else {
+ if ((base_addr[CyMSVR2] & CyDTR) != CyDTR)
+ base_addr[CyMSVR2] = CyDTR;
#ifdef SERIAL_DEBUG_DTR
- printk("cyc: %d: raising DTR\n", __LINE__);
- printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
+ printk("cyc: %d: raising DTR\n", __LINE__);
+ printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
+ base_addr[CyMSVR2]);
#endif
}
- if (info->tty){
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->tty) {
+ clear_bit(TTY_IO_ERROR, &info->tty->flags);
}
- local_irq_restore(flags);
-
-} /* config_setup */
+ local_irq_restore(flags);
+} /* config_setup */
-static void
-cy_put_char(struct tty_struct *tty, unsigned char ch)
+static void cy_put_char(struct tty_struct *tty, unsigned char ch)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- unsigned long flags;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ unsigned long flags;
#ifdef SERIAL_DEBUG_IO
- printk("cy_put_char %s(0x%02x)\n", tty->name, ch);
+ printk("cy_put_char %s(0x%02x)\n", tty->name, ch);
#endif
- if (serial_paranoia_check(info, tty->name, "cy_put_char"))
- return;
+ if (serial_paranoia_check(info, tty->name, "cy_put_char"))
+ return;
- if (!info->xmit_buf)
- return;
+ if (!info->xmit_buf)
+ return;
- local_irq_save(flags);
+ local_irq_save(flags);
if (info->xmit_cnt >= PAGE_SIZE - 1) {
- local_irq_restore(flags);
- return;
+ local_irq_restore(flags);
+ return;
}
info->xmit_buf[info->xmit_head++] = ch;
info->xmit_head &= PAGE_SIZE - 1;
info->xmit_cnt++;
- local_irq_restore(flags);
-} /* cy_put_char */
-
+ local_irq_restore(flags);
+} /* cy_put_char */
-static void
-cy_flush_chars(struct tty_struct *tty)
+static void cy_flush_chars(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- unsigned long flags;
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
-
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ unsigned long flags;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
+
#ifdef SERIAL_DEBUG_IO
- printk("cy_flush_chars %s\n", tty->name); /* */
+ printk("cy_flush_chars %s\n", tty->name); /* */
#endif
- if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
- return;
+ if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
+ return;
- if (info->xmit_cnt <= 0 || tty->stopped
- || tty->hw_stopped || !info->xmit_buf)
- return;
+ if (info->xmit_cnt <= 0 || tty->stopped
+ || tty->hw_stopped || !info->xmit_buf)
+ return;
- channel = info->line;
+ channel = info->line;
- local_irq_save(flags);
+ local_irq_save(flags);
base_addr[CyCAR] = channel;
base_addr[CyIER] |= CyTxMpty;
- local_irq_restore(flags);
-} /* cy_flush_chars */
-
+ local_irq_restore(flags);
+} /* cy_flush_chars */
/* This routine gets called when tty_write has put something into
the write_queue. If the port is not already transmitting stuff,
@@ -1175,650 +1178,616 @@ cy_flush_chars(struct tty_struct *tty)
routine will then ensure that the characters are sent. If the
port is already active, there is no need to kick it.
*/
-static int
-cy_write(struct tty_struct * tty,
- const unsigned char *buf, int count)
+static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- unsigned long flags;
- int c, total = 0;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ unsigned long flags;
+ int c, total = 0;
#ifdef SERIAL_DEBUG_IO
- printk("cy_write %s\n", tty->name); /* */
+ printk("cy_write %s\n", tty->name); /* */
#endif
- if (serial_paranoia_check(info, tty->name, "cy_write")){
- return 0;
- }
-
- if (!info->xmit_buf){
- return 0;
- }
-
- while (1) {
- local_irq_save(flags);
- c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - info->xmit_head));
- if (c <= 0) {
- local_irq_restore(flags);
- break;
- }
-
- memcpy(info->xmit_buf + info->xmit_head, buf, c);
- info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
- info->xmit_cnt += c;
- local_irq_restore(flags);
-
- buf += c;
- count -= c;
- total += c;
- }
-
- if (info->xmit_cnt
- && !tty->stopped
- && !tty->hw_stopped ) {
- start_xmit(info);
- }
- return total;
-} /* cy_write */
+ if (serial_paranoia_check(info, tty->name, "cy_write")) {
+ return 0;
+ }
+ if (!info->xmit_buf) {
+ return 0;
+ }
-static int
-cy_write_room(struct tty_struct *tty)
+ while (1) {
+ local_irq_save(flags);
+ c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+ SERIAL_XMIT_SIZE - info->xmit_head));
+ if (c <= 0) {
+ local_irq_restore(flags);
+ break;
+ }
+
+ memcpy(info->xmit_buf + info->xmit_head, buf, c);
+ info->xmit_head =
+ (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+ info->xmit_cnt += c;
+ local_irq_restore(flags);
+
+ buf += c;
+ count -= c;
+ total += c;
+ }
+
+ if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
+ start_xmit(info);
+ }
+ return total;
+} /* cy_write */
+
+static int cy_write_room(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- int ret;
-
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ int ret;
+
#ifdef SERIAL_DEBUG_IO
- printk("cy_write_room %s\n", tty->name); /* */
+ printk("cy_write_room %s\n", tty->name); /* */
#endif
- if (serial_paranoia_check(info, tty->name, "cy_write_room"))
- return 0;
- ret = PAGE_SIZE - info->xmit_cnt - 1;
- if (ret < 0)
- ret = 0;
- return ret;
-} /* cy_write_room */
-
+ if (serial_paranoia_check(info, tty->name, "cy_write_room"))
+ return 0;
+ ret = PAGE_SIZE - info->xmit_cnt - 1;
+ if (ret < 0)
+ ret = 0;
+ return ret;
+} /* cy_write_room */
-static int
-cy_chars_in_buffer(struct tty_struct *tty)
+static int cy_chars_in_buffer(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
-
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+
#ifdef SERIAL_DEBUG_IO
- printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */
+ printk("cy_chars_in_buffer %s %d\n", tty->name, info->xmit_cnt); /* */
#endif
- if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
- return 0;
-
- return info->xmit_cnt;
-} /* cy_chars_in_buffer */
+ if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
+ return 0;
+ return info->xmit_cnt;
+} /* cy_chars_in_buffer */
-static void
-cy_flush_buffer(struct tty_struct *tty)
+static void cy_flush_buffer(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- unsigned long flags;
-
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ unsigned long flags;
+
#ifdef SERIAL_DEBUG_IO
- printk("cy_flush_buffer %s\n", tty->name); /* */
+ printk("cy_flush_buffer %s\n", tty->name); /* */
#endif
- if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
- return;
- local_irq_save(flags);
+ if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
+ return;
+ local_irq_save(flags);
info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
- local_irq_restore(flags);
- tty_wakeup(tty);
-} /* cy_flush_buffer */
-
+ local_irq_restore(flags);
+ tty_wakeup(tty);
+} /* cy_flush_buffer */
/* This routine is called by the upper-layer tty layer to signal
that incoming characters should be throttled or that the
throttle should be released.
*/
-static void
-cy_throttle(struct tty_struct * tty)
+static void cy_throttle(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- unsigned long flags;
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ unsigned long flags;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
#ifdef SERIAL_DEBUG_THROTTLE
- char buf[64];
-
- printk("throttle %s: %d....\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
- printk("cy_throttle %s\n", tty->name);
+ char buf[64];
+
+ printk("throttle %s: %d....\n", tty_name(tty, buf),
+ tty->ldisc.chars_in_buffer(tty));
+ printk("cy_throttle %s\n", tty->name);
#endif
- if (serial_paranoia_check(info, tty->name, "cy_nthrottle")){
- return;
- }
+ if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) {
+ return;
+ }
- if (I_IXOFF(tty)) {
- info->x_char = STOP_CHAR(tty);
- /* Should use the "Send Special Character" feature!!! */
- }
+ if (I_IXOFF(tty)) {
+ info->x_char = STOP_CHAR(tty);
+ /* Should use the "Send Special Character" feature!!! */
+ }
- channel = info->line;
+ channel = info->line;
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
base_addr[CyMSVR1] = 0;
- local_irq_restore(flags);
-
- return;
-} /* cy_throttle */
-
+ local_irq_restore(flags);
+} /* cy_throttle */
-static void
-cy_unthrottle(struct tty_struct * tty)
+static void cy_unthrottle(struct tty_struct *tty)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
- unsigned long flags;
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ unsigned long flags;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
#ifdef SERIAL_DEBUG_THROTTLE
- char buf[64];
-
- printk("throttle %s: %d....\n", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
- printk("cy_unthrottle %s\n", tty->name);
+ char buf[64];
+
+ printk("throttle %s: %d....\n", tty_name(tty, buf),
+ tty->ldisc.chars_in_buffer(tty));
+ printk("cy_unthrottle %s\n", tty->name);
#endif
- if (serial_paranoia_check(info, tty->name, "cy_nthrottle")){
- return;
- }
+ if (serial_paranoia_check(info, tty->name, "cy_nthrottle")) {
+ return;
+ }
- if (I_IXOFF(tty)) {
- info->x_char = START_CHAR(tty);
- /* Should use the "Send Special Character" feature!!! */
- }
+ if (I_IXOFF(tty)) {
+ info->x_char = START_CHAR(tty);
+ /* Should use the "Send Special Character" feature!!! */
+ }
- channel = info->line;
+ channel = info->line;
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
base_addr[CyMSVR1] = CyRTS;
- local_irq_restore(flags);
-
- return;
-} /* cy_unthrottle */
+ local_irq_restore(flags);
+} /* cy_unthrottle */
static int
-get_serial_info(struct cyclades_port * info,
- struct serial_struct __user * retinfo)
+get_serial_info(struct cyclades_port *info,
+ struct serial_struct __user * retinfo)
{
- struct serial_struct tmp;
+ struct serial_struct tmp;
/* CP('g'); */
- if (!retinfo)
- return -EFAULT;
- memset(&tmp, 0, sizeof(tmp));
- tmp.type = info->type;
- tmp.line = info->line;
- tmp.port = info->line;
- tmp.irq = 0;
- tmp.flags = info->flags;
- tmp.baud_base = 0; /*!!!*/
- tmp.close_delay = info->close_delay;
- tmp.custom_divisor = 0; /*!!!*/
- tmp.hub6 = 0; /*!!!*/
- return copy_to_user(retinfo,&tmp,sizeof(*retinfo)) ? -EFAULT : 0;
-} /* get_serial_info */
+ if (!retinfo)
+ return -EFAULT;
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.type = info->type;
+ tmp.line = info->line;
+ tmp.port = info->line;
+ tmp.irq = 0;
+ tmp.flags = info->flags;
+ tmp.baud_base = 0; /*!!! */
+ tmp.close_delay = info->close_delay;
+ tmp.custom_divisor = 0; /*!!! */
+ tmp.hub6 = 0; /*!!! */
+ return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
+} /* get_serial_info */
static int
-set_serial_info(struct cyclades_port * info,
- struct serial_struct __user * new_info)
+set_serial_info(struct cyclades_port *info,
+ struct serial_struct __user * new_info)
{
- struct serial_struct new_serial;
- struct cyclades_port old_info;
+ struct serial_struct new_serial;
+ struct cyclades_port old_info;
/* CP('s'); */
- if (!new_info)
- return -EFAULT;
- if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
- return -EFAULT;
- old_info = *info;
+ if (!new_info)
+ return -EFAULT;
+ if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+ return -EFAULT;
+ old_info = *info;
+
+ if (!capable(CAP_SYS_ADMIN)) {
+ if ((new_serial.close_delay != info->close_delay) ||
+ ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
+ (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
+ return -EPERM;
+ info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+ (new_serial.flags & ASYNC_USR_MASK));
+ goto check_and_exit;
+ }
- if (!capable(CAP_SYS_ADMIN)) {
- if ((new_serial.close_delay != info->close_delay) ||
- ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) !=
- (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)))
- return -EPERM;
- info->flags = ((info->flags & ~ASYNC_USR_MASK) |
- (new_serial.flags & ASYNC_USR_MASK));
- goto check_and_exit;
- }
+ /*
+ * OK, past this point, all the error checking has been done.
+ * At this point, we start making changes.....
+ */
+ info->flags = ((info->flags & ~ASYNC_FLAGS) |
+ (new_serial.flags & ASYNC_FLAGS));
+ info->close_delay = new_serial.close_delay;
- /*
- * OK, past this point, all the error checking has been done.
- * At this point, we start making changes.....
- */
+check_and_exit:
+ if (info->flags & ASYNC_INITIALIZED) {
+ config_setup(info);
+ return 0;
+ }
+ return startup(info);
+} /* set_serial_info */
- info->flags = ((info->flags & ~ASYNC_FLAGS) |
- (new_serial.flags & ASYNC_FLAGS));
- info->close_delay = new_serial.close_delay;
+static int cy_tiocmget(struct tty_struct *tty, struct file *file)
+{
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ int channel;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ unsigned long flags;
+ unsigned char status;
+ channel = info->line;
-check_and_exit:
- if (info->flags & ASYNC_INITIALIZED){
- config_setup(info);
- return 0;
- }else{
- return startup(info);
- }
-} /* set_serial_info */
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
+ status = base_addr[CyMSVR1] | base_addr[CyMSVR2];
+ local_irq_restore(flags);
-static int
-cy_tiocmget(struct tty_struct *tty, struct file *file)
-{
- struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
- int channel;
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- unsigned long flags;
- unsigned char status;
-
- channel = info->line;
-
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
- status = base_addr[CyMSVR1] | base_addr[CyMSVR2];
- local_irq_restore(flags);
-
- return ((status & CyRTS) ? TIOCM_RTS : 0)
- | ((status & CyDTR) ? TIOCM_DTR : 0)
- | ((status & CyDCD) ? TIOCM_CAR : 0)
- | ((status & CyDSR) ? TIOCM_DSR : 0)
- | ((status & CyCTS) ? TIOCM_CTS : 0);
-} /* cy_tiocmget */
+ return ((status & CyRTS) ? TIOCM_RTS : 0)
+ | ((status & CyDTR) ? TIOCM_DTR : 0)
+ | ((status & CyDCD) ? TIOCM_CAR : 0)
+ | ((status & CyDSR) ? TIOCM_DSR : 0)
+ | ((status & CyCTS) ? TIOCM_CTS : 0);
+} /* cy_tiocmget */
static int
cy_tiocmset(struct tty_struct *tty, struct file *file,
unsigned int set, unsigned int clear)
{
- struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
- int channel;
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- unsigned long flags;
-
- channel = info->line;
-
- if (set & TIOCM_RTS){
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ int channel;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ unsigned long flags;
+
+ channel = info->line;
+
+ if (set & TIOCM_RTS) {
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
base_addr[CyMSVR1] = CyRTS;
- local_irq_restore(flags);
+ local_irq_restore(flags);
}
- if (set & TIOCM_DTR){
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
+ if (set & TIOCM_DTR) {
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
/* CP('S');CP('2'); */
- base_addr[CyMSVR2] = CyDTR;
+ base_addr[CyMSVR2] = CyDTR;
#ifdef SERIAL_DEBUG_DTR
- printk("cyc: %d: raising DTR\n", __LINE__);
- printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
+ printk("cyc: %d: raising DTR\n", __LINE__);
+ printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
+ base_addr[CyMSVR2]);
#endif
- local_irq_restore(flags);
+ local_irq_restore(flags);
}
- if (clear & TIOCM_RTS){
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
+ if (clear & TIOCM_RTS) {
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
base_addr[CyMSVR1] = 0;
- local_irq_restore(flags);
+ local_irq_restore(flags);
}
- if (clear & TIOCM_DTR){
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
+ if (clear & TIOCM_DTR) {
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
/* CP('C');CP('2'); */
- base_addr[CyMSVR2] = 0;
+ base_addr[CyMSVR2] = 0;
#ifdef SERIAL_DEBUG_DTR
- printk("cyc: %d: dropping DTR\n", __LINE__);
- printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
+ printk("cyc: %d: dropping DTR\n", __LINE__);
+ printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
+ base_addr[CyMSVR2]);
#endif
- local_irq_restore(flags);
+ local_irq_restore(flags);
}
- return 0;
-} /* set_modem_info */
-
-static void
-send_break( struct cyclades_port * info, int duration)
-{ /* Let the transmit ISR take care of this (since it
- requires stuffing characters into the output stream).
- */
- info->x_break = duration;
- if (!info->xmit_cnt ) {
- start_xmit(info);
- }
-} /* send_break */
+ return 0;
+} /* set_modem_info */
+
+static void send_break(struct cyclades_port *info, int duration)
+{ /* Let the transmit ISR take care of this (since it
+ requires stuffing characters into the output stream).
+ */
+ info->x_break = duration;
+ if (!info->xmit_cnt) {
+ start_xmit(info);
+ }
+} /* send_break */
static int
-get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon)
+get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon)
{
- if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
- return -EFAULT;
- info->mon.int_count = 0;
- info->mon.char_count = 0;
- info->mon.char_max = 0;
- info->mon.char_last = 0;
- return 0;
+ if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor)))
+ return -EFAULT;
+ info->mon.int_count = 0;
+ info->mon.char_count = 0;
+ info->mon.char_max = 0;
+ info->mon.char_last = 0;
+ return 0;
}
-static int
-set_threshold(struct cyclades_port * info, unsigned long __user *arg)
+static int set_threshold(struct cyclades_port *info, unsigned long __user * arg)
{
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- unsigned long value;
- int channel;
-
- if (get_user(value, arg))
- return -EFAULT;
-
- channel = info->line;
- info->cor4 &= ~CyREC_FIFO;
- info->cor4 |= value & CyREC_FIFO;
- base_addr[CyCOR4] = info->cor4;
- return 0;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ unsigned long value;
+ int channel;
+
+ if (get_user(value, arg))
+ return -EFAULT;
+
+ channel = info->line;
+ info->cor4 &= ~CyREC_FIFO;
+ info->cor4 |= value & CyREC_FIFO;
+ base_addr[CyCOR4] = info->cor4;
+ return 0;
}
static int
-get_threshold(struct cyclades_port * info, unsigned long __user *value)
+get_threshold(struct cyclades_port *info, unsigned long __user * value)
{
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
- unsigned long tmp;
-
- channel = info->line;
-
- tmp = base_addr[CyCOR4] & CyREC_FIFO;
- return put_user(tmp,value);
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
+ unsigned long tmp;
+
+ channel = info->line;
+
+ tmp = base_addr[CyCOR4] & CyREC_FIFO;
+ return put_user(tmp, value);
}
static int
-set_default_threshold(struct cyclades_port * info, unsigned long __user *arg)
+set_default_threshold(struct cyclades_port *info, unsigned long __user * arg)
{
- unsigned long value;
+ unsigned long value;
- if (get_user(value, arg))
- return -EFAULT;
+ if (get_user(value, arg))
+ return -EFAULT;
- info->default_threshold = value & 0x0f;
- return 0;
+ info->default_threshold = value & 0x0f;
+ return 0;
}
static int
-get_default_threshold(struct cyclades_port * info, unsigned long __user *value)
+get_default_threshold(struct cyclades_port *info, unsigned long __user * value)
{
- return put_user(info->default_threshold,value);
+ return put_user(info->default_threshold, value);
}
-static int
-set_timeout(struct cyclades_port * info, unsigned long __user *arg)
+static int set_timeout(struct cyclades_port *info, unsigned long __user * arg)
{
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
- unsigned long value;
-
- if (get_user(value, arg))
- return -EFAULT;
-
- channel = info->line;
-
- base_addr[CyRTPRL] = value & 0xff;
- base_addr[CyRTPRH] = (value >> 8) & 0xff;
- return 0;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
+ unsigned long value;
+
+ if (get_user(value, arg))
+ return -EFAULT;
+
+ channel = info->line;
+
+ base_addr[CyRTPRL] = value & 0xff;
+ base_addr[CyRTPRH] = (value >> 8) & 0xff;
+ return 0;
}
-static int
-get_timeout(struct cyclades_port * info, unsigned long __user *value)
+static int get_timeout(struct cyclades_port *info, unsigned long __user * value)
{
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
- unsigned long tmp;
-
- channel = info->line;
-
- tmp = base_addr[CyRTPRL];
- return put_user(tmp,value);
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
+ unsigned long tmp;
+
+ channel = info->line;
+
+ tmp = base_addr[CyRTPRL];
+ return put_user(tmp, value);
}
-static int
-set_default_timeout(struct cyclades_port * info, unsigned long value)
+static int set_default_timeout(struct cyclades_port *info, unsigned long value)
{
- info->default_timeout = value & 0xff;
- return 0;
+ info->default_timeout = value & 0xff;
+ return 0;
}
static int
-get_default_timeout(struct cyclades_port * info, unsigned long __user *value)
+get_default_timeout(struct cyclades_port *info, unsigned long __user * value)
{
- return put_user(info->default_timeout,value);
+ return put_user(info->default_timeout, value);
}
static int
-cy_ioctl(struct tty_struct *tty, struct file * file,
- unsigned int cmd, unsigned long arg)
+cy_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
{
- unsigned long val;
- struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
- int ret_val = 0;
- void __user *argp = (void __user *)arg;
+ unsigned long val;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ int ret_val = 0;
+ void __user *argp = (void __user *)arg;
#ifdef SERIAL_DEBUG_OTHER
- printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */
-#endif
-
- switch (cmd) {
- case CYGETMON:
- ret_val = get_mon_info(info, argp);
- break;
- case CYGETTHRESH:
- ret_val = get_threshold(info, argp);
- break;
- case CYSETTHRESH:
- ret_val = set_threshold(info, argp);
- break;
- case CYGETDEFTHRESH:
- ret_val = get_default_threshold(info, argp);
- break;
- case CYSETDEFTHRESH:
- ret_val = set_default_threshold(info, argp);
- break;
- case CYGETTIMEOUT:
- ret_val = get_timeout(info, argp);
- break;
- case CYSETTIMEOUT:
- ret_val = set_timeout(info, argp);
- break;
- case CYGETDEFTIMEOUT:
- ret_val = get_default_timeout(info, argp);
- break;
- case CYSETDEFTIMEOUT:
- ret_val = set_default_timeout(info, (unsigned long)arg);
- break;
- case TCSBRK: /* SVID version: non-zero arg --> no break */
- ret_val = tty_check_change(tty);
- if (ret_val)
- break;
- tty_wait_until_sent(tty,0);
- if (!arg)
- send_break(info, HZ/4); /* 1/4 second */
- break;
- case TCSBRKP: /* support for POSIX tcsendbreak() */
- ret_val = tty_check_change(tty);
- if (ret_val)
+ printk("cy_ioctl %s, cmd = %x arg = %lx\n", tty->name, cmd, arg); /* */
+#endif
+
+ switch (cmd) {
+ case CYGETMON:
+ ret_val = get_mon_info(info, argp);
+ break;
+ case CYGETTHRESH:
+ ret_val = get_threshold(info, argp);
+ break;
+ case CYSETTHRESH:
+ ret_val = set_threshold(info, argp);
+ break;
+ case CYGETDEFTHRESH:
+ ret_val = get_default_threshold(info, argp);
+ break;
+ case CYSETDEFTHRESH:
+ ret_val = set_default_threshold(info, argp);
+ break;
+ case CYGETTIMEOUT:
+ ret_val = get_timeout(info, argp);
+ break;
+ case CYSETTIMEOUT:
+ ret_val = set_timeout(info, argp);
+ break;
+ case CYGETDEFTIMEOUT:
+ ret_val = get_default_timeout(info, argp);
+ break;
+ case CYSETDEFTIMEOUT:
+ ret_val = set_default_timeout(info, (unsigned long)arg);
+ break;
+ case TCSBRK: /* SVID version: non-zero arg --> no break */
+ ret_val = tty_check_change(tty);
+ if (ret_val)
+ break;
+ tty_wait_until_sent(tty, 0);
+ if (!arg)
+ send_break(info, HZ / 4); /* 1/4 second */
+ break;
+ case TCSBRKP: /* support for POSIX tcsendbreak() */
+ ret_val = tty_check_change(tty);
+ if (ret_val)
+ break;
+ tty_wait_until_sent(tty, 0);
+ send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
break;
- tty_wait_until_sent(tty,0);
- send_break(info, arg ? arg*(HZ/10) : HZ/4);
- break;
/* The following commands are incompletely implemented!!! */
- case TIOCGSOFTCAR:
- ret_val = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
- break;
- case TIOCSSOFTCAR:
- ret_val = get_user(val, (unsigned long __user *) argp);
- if (ret_val)
- break;
- tty->termios->c_cflag =
- ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0));
- break;
- case TIOCGSERIAL:
- ret_val = get_serial_info(info, argp);
- break;
- case TIOCSSERIAL:
- ret_val = set_serial_info(info, argp);
- break;
- default:
- ret_val = -ENOIOCTLCMD;
- }
+ case TIOCGSOFTCAR:
+ ret_val =
+ put_user(C_CLOCAL(tty) ? 1 : 0,
+ (unsigned long __user *)argp);
+ break;
+ case TIOCSSOFTCAR:
+ ret_val = get_user(val, (unsigned long __user *)argp);
+ if (ret_val)
+ break;
+ tty->termios->c_cflag =
+ ((tty->termios->c_cflag & ~CLOCAL) | (val ? CLOCAL : 0));
+ break;
+ case TIOCGSERIAL:
+ ret_val = get_serial_info(info, argp);
+ break;
+ case TIOCSSERIAL:
+ ret_val = set_serial_info(info, argp);
+ break;
+ default:
+ ret_val = -ENOIOCTLCMD;
+ }
#ifdef SERIAL_DEBUG_OTHER
- printk("cy_ioctl done\n");
+ printk("cy_ioctl done\n");
#endif
- return ret_val;
-} /* cy_ioctl */
-
+ return ret_val;
+} /* cy_ioctl */
-
-
-static void
-cy_set_termios(struct tty_struct *tty, struct ktermios * old_termios)
+static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
{
- struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
#ifdef SERIAL_DEBUG_OTHER
- printk("cy_set_termios %s\n", tty->name);
+ printk("cy_set_termios %s\n", tty->name);
#endif
- if (tty->termios->c_cflag == old_termios->c_cflag)
- return;
- config_setup(info);
+ if (tty->termios->c_cflag == old_termios->c_cflag)
+ return;
+ config_setup(info);
- if ((old_termios->c_cflag & CRTSCTS) &&
- !(tty->termios->c_cflag & CRTSCTS)) {
- tty->stopped = 0;
- cy_start(tty);
- }
+ if ((old_termios->c_cflag & CRTSCTS) &&
+ !(tty->termios->c_cflag & CRTSCTS)) {
+ tty->stopped = 0;
+ cy_start(tty);
+ }
#ifdef tytso_patch_94Nov25_1726
- if (!(old_termios->c_cflag & CLOCAL) &&
- (tty->termios->c_cflag & CLOCAL))
- wake_up_interruptible(&info->open_wait);
+ if (!(old_termios->c_cflag & CLOCAL) &&
+ (tty->termios->c_cflag & CLOCAL))
+ wake_up_interruptible(&info->open_wait);
#endif
+} /* cy_set_termios */
- return;
-} /* cy_set_termios */
-
-
-static void
-cy_close(struct tty_struct * tty, struct file * filp)
+static void cy_close(struct tty_struct *tty, struct file *filp)
{
- struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
/* CP('C'); */
#ifdef SERIAL_DEBUG_OTHER
- printk("cy_close %s\n", tty->name);
+ printk("cy_close %s\n", tty->name);
#endif
- if (!info
- || serial_paranoia_check(info, tty->name, "cy_close")){
- return;
- }
+ if (!info || serial_paranoia_check(info, tty->name, "cy_close")) {
+ return;
+ }
#ifdef SERIAL_DEBUG_OPEN
- printk("cy_close %s, count = %d\n", tty->name, info->count);
-#endif
-
- if ((tty->count == 1) && (info->count != 1)) {
- /*
- * Uh, oh. tty->count is 1, which means that the tty
- * structure will be freed. Info->count should always
- * be one in these conditions. If it's greater than
- * one, we've got real problems, since it means the
- * serial port won't be shutdown.
- */
- printk("cy_close: bad serial port count; tty->count is 1, "
- "info->count is %d\n", info->count);
- info->count = 1;
- }
+ printk("cy_close %s, count = %d\n", tty->name, info->count);
+#endif
+
+ if ((tty->count == 1) && (info->count != 1)) {
+ /*
+ * Uh, oh. tty->count is 1, which means that the tty
+ * structure will be freed. Info->count should always
+ * be one in these conditions. If it's greater than
+ * one, we've got real problems, since it means the
+ * serial port won't be shutdown.
+ */
+ printk("cy_close: bad serial port count; tty->count is 1, "
+ "info->count is %d\n", info->count);
+ info->count = 1;
+ }
#ifdef SERIAL_DEBUG_COUNT
- printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count - 1);
+ printk("cyc: %d: decrementing count to %d\n", __LINE__,
+ info->count - 1);
#endif
- if (--info->count < 0) {
- printk("cy_close: bad serial port count for ttys%d: %d\n",
- info->line, info->count);
+ if (--info->count < 0) {
+ printk("cy_close: bad serial port count for ttys%d: %d\n",
+ info->line, info->count);
#ifdef SERIAL_DEBUG_COUNT
- printk("cyc: %d: setting count to 0\n", __LINE__);
+ printk("cyc: %d: setting count to 0\n", __LINE__);
#endif
- info->count = 0;
- }
- if (info->count)
- return;
- info->flags |= ASYNC_CLOSING;
- if (info->flags & ASYNC_INITIALIZED)
- tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
- shutdown(info);
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- tty_ldisc_flush(tty);
- info->event = 0;
- info->tty = NULL;
- if (info->blocked_open) {
- if (info->close_delay) {
- msleep_interruptible(jiffies_to_msecs(info->close_delay));
+ info->count = 0;
}
- wake_up_interruptible(&info->open_wait);
- }
- info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
+ if (info->count)
+ return;
+ info->flags |= ASYNC_CLOSING;
+ if (info->flags & ASYNC_INITIALIZED)
+ tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
+ shutdown(info);
+ if (tty->driver->flush_buffer)
+ tty->driver->flush_buffer(tty);
+ tty_ldisc_flush(tty);
+ info->event = 0;
+ info->tty = NULL;
+ if (info->blocked_open) {
+ if (info->close_delay) {
+ msleep_interruptible(jiffies_to_msecs
+ (info->close_delay));
+ }
+ wake_up_interruptible(&info->open_wait);
+ }
+ info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
+ wake_up_interruptible(&info->close_wait);
#ifdef SERIAL_DEBUG_OTHER
- printk("cy_close done\n");
+ printk("cy_close done\n");
#endif
-
- return;
-} /* cy_close */
+} /* cy_close */
/*
* cy_hangup() --- called by tty_hangup() when a hangup is signaled.
*/
-void
-cy_hangup(struct tty_struct *tty)
+void cy_hangup(struct tty_struct *tty)
{
- struct cyclades_port * info = (struct cyclades_port *)tty->driver_data;
-
+ struct cyclades_port *info = (struct cyclades_port *)tty->driver_data;
+
#ifdef SERIAL_DEBUG_OTHER
- printk("cy_hangup %s\n", tty->name); /* */
+ printk("cy_hangup %s\n", tty->name); /* */
#endif
- if (serial_paranoia_check(info, tty->name, "cy_hangup"))
- return;
-
- shutdown(info);
+ if (serial_paranoia_check(info, tty->name, "cy_hangup"))
+ return;
+
+ shutdown(info);
#if 0
- info->event = 0;
- info->count = 0;
+ info->event = 0;
+ info->count = 0;
#ifdef SERIAL_DEBUG_COUNT
- printk("cyc: %d: setting count to 0\n", __LINE__);
+ printk("cyc: %d: setting count to 0\n", __LINE__);
#endif
- info->tty = 0;
+ info->tty = 0;
#endif
- info->flags &= ~ASYNC_NORMAL_ACTIVE;
- wake_up_interruptible(&info->open_wait);
-} /* cy_hangup */
-
-
+ info->flags &= ~ASYNC_NORMAL_ACTIVE;
+ wake_up_interruptible(&info->open_wait);
+} /* cy_hangup */
/*
* ------------------------------------------------------------
@@ -1827,177 +1796,180 @@ cy_hangup(struct tty_struct *tty)
*/
static int
-block_til_ready(struct tty_struct *tty, struct file * filp,
- struct cyclades_port *info)
+block_til_ready(struct tty_struct *tty, struct file *filp,
+ struct cyclades_port *info)
{
- DECLARE_WAITQUEUE(wait, current);
- unsigned long flags;
- int channel;
- int retval;
- volatile u_char *base_addr = (u_char *)BASE_ADDR;
-
- /*
- * If the device is in the middle of being closed, then block
- * until it's done, and then try again.
- */
- if (info->flags & ASYNC_CLOSING) {
- interruptible_sleep_on(&info->close_wait);
- if (info->flags & ASYNC_HUP_NOTIFY){
- return -EAGAIN;
- }else{
- return -ERESTARTSYS;
- }
- }
-
- /*
- * If non-blocking mode is set, then make the check up front
- * and then exit.
- */
- if (filp->f_flags & O_NONBLOCK) {
- info->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;
- }
-
- /*
- * Block waiting for the carrier detect and the line to become
- * free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
- * cy_close() knows when to free things. We restore it upon
- * exit, either normal or abnormal.
- */
- retval = 0;
- add_wait_queue(&info->open_wait, &wait);
+ DECLARE_WAITQUEUE(wait, current);
+ unsigned long flags;
+ int channel;
+ int retval;
+ volatile u_char *base_addr = (u_char *) BASE_ADDR;
+
+ /*
+ * If the device is in the middle of being closed, then block
+ * until it's done, and then try again.
+ */
+ if (info->flags & ASYNC_CLOSING) {
+ interruptible_sleep_on(&info->close_wait);
+ if (info->flags & ASYNC_HUP_NOTIFY) {
+ return -EAGAIN;
+ } else {
+ return -ERESTARTSYS;
+ }
+ }
+
+ /*
+ * If non-blocking mode is set, then make the check up front
+ * and then exit.
+ */
+ if (filp->f_flags & O_NONBLOCK) {
+ info->flags |= ASYNC_NORMAL_ACTIVE;
+ return 0;
+ }
+
+ /*
+ * Block waiting for the carrier detect and the line to become
+ * free (i.e., not in use by the callout). While we are in
+ * this loop, info->count is dropped by one, so that
+ * cy_close() knows when to free things. We restore it upon
+ * exit, either normal or abnormal.
+ */
+ retval = 0;
+ add_wait_queue(&info->open_wait, &wait);
#ifdef SERIAL_DEBUG_OPEN
- printk("block_til_ready before block: %s, count = %d\n",
- tty->name, info->count);/**/
+ printk("block_til_ready before block: %s, count = %d\n",
+ tty->name, info->count);
+ /**/
#endif
- info->count--;
+ info->count--;
#ifdef SERIAL_DEBUG_COUNT
- printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count);
+ printk("cyc: %d: decrementing count to %d\n", __LINE__, info->count);
#endif
- info->blocked_open++;
+ info->blocked_open++;
- channel = info->line;
+ channel = info->line;
- while (1) {
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
- base_addr[CyMSVR1] = CyRTS;
+ while (1) {
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
+ base_addr[CyMSVR1] = CyRTS;
/* CP('S');CP('4'); */
- base_addr[CyMSVR2] = CyDTR;
+ base_addr[CyMSVR2] = CyDTR;
#ifdef SERIAL_DEBUG_DTR
- printk("cyc: %d: raising DTR\n", __LINE__);
- printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1], base_addr[CyMSVR2]);
-#endif
- local_irq_restore(flags);
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp)
- || !(info->flags & ASYNC_INITIALIZED) ){
- if (info->flags & ASYNC_HUP_NOTIFY) {
- retval = -EAGAIN;
- }else{
- retval = -ERESTARTSYS;
- }
- break;
- }
- local_irq_save(flags);
- base_addr[CyCAR] = (u_char)channel;
+ printk("cyc: %d: raising DTR\n", __LINE__);
+ printk(" status: 0x%x, 0x%x\n", base_addr[CyMSVR1],
+ base_addr[CyMSVR2]);
+#endif
+ local_irq_restore(flags);
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (tty_hung_up_p(filp)
+ || !(info->flags & ASYNC_INITIALIZED)) {
+ if (info->flags & ASYNC_HUP_NOTIFY) {
+ retval = -EAGAIN;
+ } else {
+ retval = -ERESTARTSYS;
+ }
+ break;
+ }
+ local_irq_save(flags);
+ base_addr[CyCAR] = (u_char) channel;
/* CP('L');CP1(1 && C_CLOCAL(tty)); CP1(1 && (base_addr[CyMSVR1] & CyDCD) ); */
- if (!(info->flags & ASYNC_CLOSING)
- && (C_CLOCAL(tty)
- || (base_addr[CyMSVR1] & CyDCD))) {
- local_irq_restore(flags);
- break;
- }
- local_irq_restore(flags);
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
+ if (!(info->flags & ASYNC_CLOSING)
+ && (C_CLOCAL(tty)
+ || (base_addr[CyMSVR1] & CyDCD))) {
+ local_irq_restore(flags);
+ break;
+ }
+ local_irq_restore(flags);
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ }
#ifdef SERIAL_DEBUG_OPEN
- printk("block_til_ready blocking: %s, count = %d\n",
- tty->name, info->count);/**/
-#endif
- schedule();
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&info->open_wait, &wait);
- if (!tty_hung_up_p(filp)){
- info->count++;
+ printk("block_til_ready blocking: %s, count = %d\n",
+ tty->name, info->count);
+ /**/
+#endif
+ schedule();
+ }
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&info->open_wait, &wait);
+ if (!tty_hung_up_p(filp)) {
+ info->count++;
#ifdef SERIAL_DEBUG_COUNT
- printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
+ printk("cyc: %d: incrementing count to %d\n", __LINE__,
+ info->count);
#endif
- }
- info->blocked_open--;
+ }
+ info->blocked_open--;
#ifdef SERIAL_DEBUG_OPEN
- printk("block_til_ready after blocking: %s, count = %d\n",
- tty->name, info->count);/**/
+ printk("block_til_ready after blocking: %s, count = %d\n",
+ tty->name, info->count);
+ /**/
#endif
- if (retval)
- return retval;
- info->flags |= ASYNC_NORMAL_ACTIVE;
- return 0;
-} /* block_til_ready */
+ if (retval)
+ return retval;
+ info->flags |= ASYNC_NORMAL_ACTIVE;
+ return 0;
+} /* block_til_ready */
/*
* This routine is called whenever a serial port is opened. It
* performs the serial-specific initialization for the tty structure.
*/
-int
-cy_open(struct tty_struct *tty, struct file * filp)
+int cy_open(struct tty_struct *tty, struct file *filp)
{
- struct cyclades_port *info;
- int retval, line;
+ struct cyclades_port *info;
+ int retval, line;
/* CP('O'); */
- line = tty->index;
- if ((line < 0) || (NR_PORTS <= line)){
- return -ENODEV;
- }
- info = &cy_port[line];
- if (info->line < 0){
- return -ENODEV;
- }
+ line = tty->index;
+ if ((line < 0) || (NR_PORTS <= line)) {
+ return -ENODEV;
+ }
+ info = &cy_port[line];
+ if (info->line < 0) {
+ return -ENODEV;
+ }
#ifdef SERIAL_DEBUG_OTHER
- printk("cy_open %s\n", tty->name); /* */
+ printk("cy_open %s\n", tty->name); /* */
#endif
- if (serial_paranoia_check(info, tty->name, "cy_open")){
- return -ENODEV;
- }
+ if (serial_paranoia_check(info, tty->name, "cy_open")) {
+ return -ENODEV;
+ }
#ifdef SERIAL_DEBUG_OPEN
- printk("cy_open %s, count = %d\n", tty->name, info->count);/**/
+ printk("cy_open %s, count = %d\n", tty->name, info->count);
+ /**/
#endif
- info->count++;
+ info->count++;
#ifdef SERIAL_DEBUG_COUNT
- printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
+ printk("cyc: %d: incrementing count to %d\n", __LINE__, info->count);
#endif
- tty->driver_data = info;
- info->tty = tty;
+ tty->driver_data = info;
+ info->tty = tty;
- /*
- * Start up serial port
- */
- retval = startup(info);
- if (retval){
- return retval;
- }
+ /*
+ * Start up serial port
+ */
+ retval = startup(info);
+ if (retval) {
+ return retval;
+ }
- retval = block_til_ready(tty, filp, info);
- if (retval) {
+ retval = block_til_ready(tty, filp, info);
+ if (retval) {
#ifdef SERIAL_DEBUG_OPEN
- printk("cy_open returning after block_til_ready with %d\n",
- retval);
+ printk("cy_open returning after block_til_ready with %d\n",
+ retval);
#endif
- return retval;
- }
-
+ return retval;
+ }
#ifdef SERIAL_DEBUG_OPEN
- printk("cy_open done\n");/**/
+ printk("cy_open done\n");
+ /**/
#endif
- return 0;
-} /* cy_open */
-
-
+ return 0;
+} /* cy_open */
/*
* ---------------------------------------------------------------------
@@ -2012,11 +1984,10 @@ cy_open(struct tty_struct *tty, struct file * filp)
* number, and identifies which options were configured into this
* driver.
*/
-static void
-show_version(void)
+static void show_version(void)
{
- printk("MVME166/167 cd2401 driver\n");
-} /* show_version */
+ printk("MVME166/167 cd2401 driver\n");
+} /* show_version */
/* initialize chips on card -- return number of valid
chips (which is number of ports/4) */
@@ -2030,10 +2001,9 @@ show_version(void)
* ... I wonder what I should do if this fails ...
*/
-void
-mvme167_serial_console_setup(int cflag)
+void mvme167_serial_console_setup(int cflag)
{
- volatile unsigned char* base_addr = (u_char *)BASE_ADDR;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
int ch;
u_char spd;
u_char rcor, rbpr, badspeed = 0;
@@ -2062,21 +2032,21 @@ mvme167_serial_console_setup(int cflag)
/* OK, we have chosen a speed, now reset and reinitialise */
- my_udelay(20000L); /* Allow time for any active o/p to complete */
- if(base_addr[CyCCR] != 0x00){
- local_irq_restore(flags);
- /* printk(" chip is never idle (CCR != 0)\n"); */
- return;
- }
+ my_udelay(20000L); /* Allow time for any active o/p to complete */
+ if (base_addr[CyCCR] != 0x00) {
+ local_irq_restore(flags);
+ /* printk(" chip is never idle (CCR != 0)\n"); */
+ return;
+ }
- base_addr[CyCCR] = CyCHIP_RESET; /* Reset the chip */
- my_udelay(1000L);
+ base_addr[CyCCR] = CyCHIP_RESET; /* Reset the chip */
+ my_udelay(1000L);
- if(base_addr[CyGFRCR] == 0x00){
- local_irq_restore(flags);
- /* printk(" chip is not responding (GFRCR stayed 0)\n"); */
- return;
- }
+ if (base_addr[CyGFRCR] == 0x00) {
+ local_irq_restore(flags);
+ /* printk(" chip is not responding (GFRCR stayed 0)\n"); */
+ return;
+ }
/*
* System clock is 20Mhz, divided by 2048, so divide by 10 for a 1.0ms
@@ -2085,9 +2055,9 @@ mvme167_serial_console_setup(int cflag)
base_addr[CyTPR] = 10;
- base_addr[CyPILR1] = 0x01; /* Interrupt level for modem change */
- base_addr[CyPILR2] = 0x02; /* Interrupt level for tx ints */
- base_addr[CyPILR3] = 0x03; /* Interrupt level for rx ints */
+ base_addr[CyPILR1] = 0x01; /* Interrupt level for modem change */
+ base_addr[CyPILR2] = 0x02; /* Interrupt level for tx ints */
+ base_addr[CyPILR3] = 0x03; /* Interrupt level for rx ints */
/*
* Attempt to set up all channels to something reasonable, and
@@ -2095,11 +2065,11 @@ mvme167_serial_console_setup(int cflag)
* the ammount of fiddling we have to do in normal running.
*/
- for (ch = 3; ch >= 0 ; ch--) {
- base_addr[CyCAR] = (u_char)ch;
+ for (ch = 3; ch >= 0; ch--) {
+ base_addr[CyCAR] = (u_char) ch;
base_addr[CyIER] = 0;
base_addr[CyCMR] = CyASYNC;
- base_addr[CyLICR] = (u_char)ch << 2;
+ base_addr[CyLICR] = (u_char) ch << 2;
base_addr[CyLIVR] = 0x5c;
base_addr[CyTCOR] = baud_co[spd];
base_addr[CyTBPR] = baud_bpr[spd];
@@ -2118,29 +2088,30 @@ mvme167_serial_console_setup(int cflag)
base_addr[CyCOR7] = 0;
base_addr[CyRTPRL] = 2;
base_addr[CyRTPRH] = 0;
- base_addr[CyMSVR1] = 0;
- base_addr[CyMSVR2] = 0;
- write_cy_cmd(base_addr,CyINIT_CHAN|CyDIS_RCVR|CyDIS_XMTR);
+ base_addr[CyMSVR1] = 0;
+ base_addr[CyMSVR2] = 0;
+ write_cy_cmd(base_addr, CyINIT_CHAN | CyDIS_RCVR | CyDIS_XMTR);
}
/*
* Now do specials for channel zero....
*/
- base_addr[CyMSVR1] = CyRTS;
- base_addr[CyMSVR2] = CyDTR;
+ base_addr[CyMSVR1] = CyRTS;
+ base_addr[CyMSVR2] = CyDTR;
base_addr[CyIER] = CyRxData;
- write_cy_cmd(base_addr,CyENB_RCVR|CyENB_XMTR);
+ write_cy_cmd(base_addr, CyENB_RCVR | CyENB_XMTR);
local_irq_restore(flags);
my_udelay(20000L); /* Let it all settle down */
- printk("CD2401 initialised, chip is rev 0x%02x\n", base_addr[CyGFRCR]);
+ printk("CD2401 initialised, chip is rev 0x%02x\n", base_addr[CyGFRCR]);
if (badspeed)
- printk(" WARNING: Failed to identify line speed, rcor=%02x,rbpr=%02x\n",
- rcor >> 5, rbpr);
-} /* serial_console_init */
+ printk
+ (" WARNING: Failed to identify line speed, rcor=%02x,rbpr=%02x\n",
+ rcor >> 5, rbpr);
+} /* serial_console_init */
static const struct tty_operations cy_ops = {
.open = cy_open,
@@ -2161,6 +2132,7 @@ static const struct tty_operations cy_ops = {
.tiocmget = cy_tiocmget,
.tiocmset = cy_tiocmset,
};
+
/* The serial driver boot-time initialization code!
Hardware I/O ports are mapped to character special devices on a
first found, first allocated manner. That is, this code searches
@@ -2177,214 +2149,214 @@ static const struct tty_operations cy_ops = {
If there are more cards with more ports than have been statically
allocated above, a warning is printed and the extra ports are ignored.
*/
-static int __init
-serial167_init(void)
+static int __init serial167_init(void)
{
- struct cyclades_port *info;
- int ret = 0;
- int good_ports = 0;
- int port_num = 0;
- int index;
- int DefSpeed;
+ struct cyclades_port *info;
+ int ret = 0;
+ int good_ports = 0;
+ int port_num = 0;
+ int index;
+ int DefSpeed;
#ifdef notyet
- struct sigaction sa;
+ struct sigaction sa;
#endif
- if (!(mvme16x_config &MVME16x_CONFIG_GOT_CD2401))
- return 0;
+ if (!(mvme16x_config & MVME16x_CONFIG_GOT_CD2401))
+ return 0;
- cy_serial_driver = alloc_tty_driver(NR_PORTS);
- if (!cy_serial_driver)
- return -ENOMEM;
+ cy_serial_driver = alloc_tty_driver(NR_PORTS);
+ if (!cy_serial_driver)
+ return -ENOMEM;
#if 0
-scrn[1] = '\0';
+ scrn[1] = '\0';
#endif
- show_version();
+ show_version();
- /* Has "console=0,9600n8" been used in bootinfo to change speed? */
- if (serial_console_cflag)
- DefSpeed = serial_console_cflag & 0017;
- else {
- DefSpeed = initial_console_speed;
- serial_console_info = &cy_port[0];
- serial_console_cflag = DefSpeed | CS8;
+ /* Has "console=0,9600n8" been used in bootinfo to change speed? */
+ if (serial_console_cflag)
+ DefSpeed = serial_console_cflag & 0017;
+ else {
+ DefSpeed = initial_console_speed;
+ serial_console_info = &cy_port[0];
+ serial_console_cflag = DefSpeed | CS8;
#if 0
- serial_console = 64; /*callout_driver.minor_start*/
-#endif
- }
-
- /* Initialize the tty_driver structure */
-
- cy_serial_driver->owner = THIS_MODULE;
- cy_serial_driver->name = "ttyS";
- cy_serial_driver->major = TTY_MAJOR;
- cy_serial_driver->minor_start = 64;
- cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
- cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
- cy_serial_driver->init_termios = tty_std_termios;
- cy_serial_driver->init_termios.c_cflag =
- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
- tty_set_operations(cy_serial_driver, &cy_ops);
+ serial_console = 64; /*callout_driver.minor_start */
+#endif
+ }
- ret = tty_register_driver(cy_serial_driver);
- if (ret) {
- printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n");
- put_tty_driver(cy_serial_driver);
- return ret;
- }
+ /* Initialize the tty_driver structure */
- port_num = 0;
- info = cy_port;
- for (index = 0; index < 1; index++) {
+ cy_serial_driver->owner = THIS_MODULE;
+ cy_serial_driver->name = "ttyS";
+ cy_serial_driver->major = TTY_MAJOR;
+ cy_serial_driver->minor_start = 64;
+ cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
+ cy_serial_driver->subtype = SERIAL_TYPE_NORMAL;
+ cy_serial_driver->init_termios = tty_std_termios;
+ cy_serial_driver->init_termios.c_cflag =
+ B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+ cy_serial_driver->flags = TTY_DRIVER_REAL_RAW;
+ tty_set_operations(cy_serial_driver, &cy_ops);
+
+ ret = tty_register_driver(cy_serial_driver);
+ if (ret) {
+ printk(KERN_ERR "Couldn't register MVME166/7 serial driver\n");
+ put_tty_driver(cy_serial_driver);
+ return ret;
+ }
- good_ports = 4;
+ port_num = 0;
+ info = cy_port;
+ for (index = 0; index < 1; index++) {
- if(port_num < NR_PORTS){
- while( good_ports-- && port_num < NR_PORTS){
+ good_ports = 4;
+
+ if (port_num < NR_PORTS) {
+ while (good_ports-- && port_num < NR_PORTS) {
/*** initialize port ***/
- info->magic = CYCLADES_MAGIC;
- info->type = PORT_CIRRUS;
- info->card = index;
- info->line = port_num;
- info->flags = STD_COM_FLAGS;
- info->tty = NULL;
- info->xmit_fifo_size = 12;
- info->cor1 = CyPARITY_NONE|Cy_8_BITS;
- info->cor2 = CyETC;
- info->cor3 = Cy_1_STOP;
- info->cor4 = 0x08; /* _very_ small receive threshold */
- info->cor5 = 0;
- info->cor6 = 0;
- info->cor7 = 0;
- info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */
- info->tco = baud_co[DefSpeed]; /* Tx CO */
- info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */
- info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */
- info->close_delay = 0;
- info->x_char = 0;
- info->event = 0;
- info->count = 0;
+ info->magic = CYCLADES_MAGIC;
+ info->type = PORT_CIRRUS;
+ info->card = index;
+ info->line = port_num;
+ info->flags = STD_COM_FLAGS;
+ info->tty = NULL;
+ info->xmit_fifo_size = 12;
+ info->cor1 = CyPARITY_NONE | Cy_8_BITS;
+ info->cor2 = CyETC;
+ info->cor3 = Cy_1_STOP;
+ info->cor4 = 0x08; /* _very_ small receive threshold */
+ info->cor5 = 0;
+ info->cor6 = 0;
+ info->cor7 = 0;
+ info->tbpr = baud_bpr[DefSpeed]; /* Tx BPR */
+ info->tco = baud_co[DefSpeed]; /* Tx CO */
+ info->rbpr = baud_bpr[DefSpeed]; /* Rx BPR */
+ info->rco = baud_co[DefSpeed] >> 5; /* Rx CO */
+ info->close_delay = 0;
+ info->x_char = 0;
+ info->event = 0;
+ info->count = 0;
#ifdef SERIAL_DEBUG_COUNT
- printk("cyc: %d: setting count to 0\n", __LINE__);
-#endif
- info->blocked_open = 0;
- info->default_threshold = 0;
- info->default_timeout = 0;
- INIT_WORK(&info->tqueue, do_softint);
- init_waitqueue_head(&info->open_wait);
- init_waitqueue_head(&info->close_wait);
- /* info->session */
- /* info->pgrp */
+ printk("cyc: %d: setting count to 0\n",
+ __LINE__);
+#endif
+ info->blocked_open = 0;
+ info->default_threshold = 0;
+ info->default_timeout = 0;
+ INIT_WORK(&info->tqueue, do_softint);
+ init_waitqueue_head(&info->open_wait);
+ init_waitqueue_head(&info->close_wait);
+ /* info->session */
+ /* info->pgrp */
/*** !!!!!!!! this may expose new bugs !!!!!!!!! *********/
- info->read_status_mask = CyTIMEOUT| CySPECHAR| CyBREAK
- | CyPARITY| CyFRAME| CyOVERRUN;
- /* info->timeout */
-
- printk("ttyS%d ", info->line);
- port_num++;info++;
- if(!(port_num & 7)){
- printk("\n ");
+ info->read_status_mask =
+ CyTIMEOUT | CySPECHAR | CyBREAK | CyPARITY |
+ CyFRAME | CyOVERRUN;
+ /* info->timeout */
+
+ printk("ttyS%d ", info->line);
+ port_num++;
+ info++;
+ if (!(port_num & 7)) {
+ printk("\n ");
+ }
+ }
}
- }
- }
- printk("\n");
- }
- while( port_num < NR_PORTS){
- info->line = -1;
- port_num++;info++;
- }
+ printk("\n");
+ }
+ while (port_num < NR_PORTS) {
+ info->line = -1;
+ port_num++;
+ info++;
+ }
#ifdef CONFIG_REMOTE_DEBUG
- debug_setup();
-#endif
- ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0,
- "cd2401_errors", cd2401_rxerr_interrupt);
- if (ret) {
- printk(KERN_ERR "Could't get cd2401_errors IRQ");
- goto cleanup_serial_driver;
- }
-
- ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0,
- "cd2401_modem", cd2401_modem_interrupt);
- if (ret) {
- printk(KERN_ERR "Could't get cd2401_modem IRQ");
- goto cleanup_irq_cd2401_errors;
- }
-
- ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0,
- "cd2401_txints", cd2401_tx_interrupt);
- if (ret) {
- printk(KERN_ERR "Could't get cd2401_txints IRQ");
- goto cleanup_irq_cd2401_modem;
- }
-
- ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0,
- "cd2401_rxints", cd2401_rx_interrupt);
- if (ret) {
- printk(KERN_ERR "Could't get cd2401_rxints IRQ");
- goto cleanup_irq_cd2401_txints;
- }
-
- /* Now we have registered the interrupt handlers, allow the interrupts */
-
- pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */
- pcc2chip[PccSCCTICR] = 0x15;
- pcc2chip[PccSCCRICR] = 0x15;
-
- pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */
-
- return 0;
+ debug_setup();
+#endif
+ ret = request_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt, 0,
+ "cd2401_errors", cd2401_rxerr_interrupt);
+ if (ret) {
+ printk(KERN_ERR "Could't get cd2401_errors IRQ");
+ goto cleanup_serial_driver;
+ }
+
+ ret = request_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt, 0,
+ "cd2401_modem", cd2401_modem_interrupt);
+ if (ret) {
+ printk(KERN_ERR "Could't get cd2401_modem IRQ");
+ goto cleanup_irq_cd2401_errors;
+ }
+
+ ret = request_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt, 0,
+ "cd2401_txints", cd2401_tx_interrupt);
+ if (ret) {
+ printk(KERN_ERR "Could't get cd2401_txints IRQ");
+ goto cleanup_irq_cd2401_modem;
+ }
+
+ ret = request_irq(MVME167_IRQ_SER_RX, cd2401_rx_interrupt, 0,
+ "cd2401_rxints", cd2401_rx_interrupt);
+ if (ret) {
+ printk(KERN_ERR "Could't get cd2401_rxints IRQ");
+ goto cleanup_irq_cd2401_txints;
+ }
+
+ /* Now we have registered the interrupt handlers, allow the interrupts */
+
+ pcc2chip[PccSCCMICR] = 0x15; /* Serial ints are level 5 */
+ pcc2chip[PccSCCTICR] = 0x15;
+ pcc2chip[PccSCCRICR] = 0x15;
+
+ pcc2chip[PccIMLR] = 3; /* Allow PCC2 ints above 3!? */
+
+ return 0;
cleanup_irq_cd2401_txints:
- free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt);
+ free_irq(MVME167_IRQ_SER_TX, cd2401_tx_interrupt);
cleanup_irq_cd2401_modem:
- free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt);
+ free_irq(MVME167_IRQ_SER_MODEM, cd2401_modem_interrupt);
cleanup_irq_cd2401_errors:
- free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt);
+ free_irq(MVME167_IRQ_SER_ERR, cd2401_rxerr_interrupt);
cleanup_serial_driver:
- if (tty_unregister_driver(cy_serial_driver))
- printk(KERN_ERR "Couldn't unregister MVME166/7 serial driver\n");
- put_tty_driver(cy_serial_driver);
- return ret;
-} /* serial167_init */
+ if (tty_unregister_driver(cy_serial_driver))
+ printk(KERN_ERR
+ "Couldn't unregister MVME166/7 serial driver\n");
+ put_tty_driver(cy_serial_driver);
+ return ret;
+} /* serial167_init */
module_init(serial167_init);
-
#ifdef CYCLOM_SHOW_STATUS
-static void
-show_status(int line_num)
+static void show_status(int line_num)
{
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int channel;
- struct cyclades_port * info;
- unsigned long flags;
-
- info = &cy_port[line_num];
- channel = info->line;
- printk(" channel %d\n", channel);/**/
-
- printk(" cy_port\n");
- printk(" card line flags = %d %d %x\n",
- info->card, info->line, info->flags);
- printk(" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n",
- (long)info->tty, info->read_status_mask,
- info->timeout, info->xmit_fifo_size);
- printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n",
- info->cor1, info->cor2, info->cor3, info->cor4, info->cor5,
- info->cor6, info->cor7);
- printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n",
- info->tbpr, info->tco, info->rbpr, info->rco);
- printk(" close_delay event count = %d %d %d\n",
- info->close_delay, info->event, info->count);
- printk(" x_char blocked_open = %x %x\n",
- info->x_char, info->blocked_open);
- printk(" open_wait = %lx %lx %lx\n",
- (long)info->open_wait);
-
-
- local_irq_save(flags);
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int channel;
+ struct cyclades_port *info;
+ unsigned long flags;
+
+ info = &cy_port[line_num];
+ channel = info->line;
+ printk(" channel %d\n", channel);
+ /**/ printk(" cy_port\n");
+ printk(" card line flags = %d %d %x\n",
+ info->card, info->line, info->flags);
+ printk
+ (" *tty read_status_mask timeout xmit_fifo_size = %lx %x %x %x\n",
+ (long)info->tty, info->read_status_mask, info->timeout,
+ info->xmit_fifo_size);
+ printk(" cor1,cor2,cor3,cor4,cor5,cor6,cor7 = %x %x %x %x %x %x %x\n",
+ info->cor1, info->cor2, info->cor3, info->cor4, info->cor5,
+ info->cor6, info->cor7);
+ printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n", info->tbpr, info->tco,
+ info->rbpr, info->rco);
+ printk(" close_delay event count = %d %d %d\n", info->close_delay,
+ info->event, info->count);
+ printk(" x_char blocked_open = %x %x\n", info->x_char,
+ info->blocked_open);
+ printk(" open_wait = %lx %lx %lx\n", (long)info->open_wait);
+
+ local_irq_save(flags);
/* Global Registers */
@@ -2398,7 +2370,7 @@ show_status(int line_num)
printk(" CyMIR %x\n", base_addr[CyMIR]);
printk(" CyTPR %x\n", base_addr[CyTPR]);
- base_addr[CyCAR] = (u_char)channel;
+ base_addr[CyCAR] = (u_char) channel;
/* Virtual Registers */
@@ -2442,11 +2414,10 @@ show_status(int line_num)
printk(" CyTBPR %x\n", base_addr[CyTBPR]);
printk(" CyTCOR %x\n", base_addr[CyTCOR]);
- local_irq_restore(flags);
-} /* show_status */
+ local_irq_restore(flags);
+} /* show_status */
#endif
-
#if 0
/* Dummy routine in mvme16x/config.c for now */
@@ -2459,61 +2430,67 @@ void console_setup(char *str, int *ints)
int cflag = 0;
/* Sanity check. */
- if (ints[0] > 3 || ints[1] > 3) return;
+ if (ints[0] > 3 || ints[1] > 3)
+ return;
/* Get baud, bits and parity */
baud = 2400;
bits = 8;
parity = 'n';
- if (ints[2]) baud = ints[2];
+ if (ints[2])
+ baud = ints[2];
if ((s = strchr(str, ','))) {
do {
s++;
- } while(*s >= '0' && *s <= '9');
- if (*s) parity = *s++;
- if (*s) bits = *s - '0';
+ } while (*s >= '0' && *s <= '9');
+ if (*s)
+ parity = *s++;
+ if (*s)
+ bits = *s - '0';
}
/* Now construct a cflag setting. */
- switch(baud) {
- case 1200:
- cflag |= B1200;
- break;
- case 9600:
- cflag |= B9600;
- break;
- case 19200:
- cflag |= B19200;
- break;
- case 38400:
- cflag |= B38400;
- break;
- case 2400:
- default:
- cflag |= B2400;
- break;
+ switch (baud) {
+ case 1200:
+ cflag |= B1200;
+ break;
+ case 9600:
+ cflag |= B9600;
+ break;
+ case 19200:
+ cflag |= B19200;
+ break;
+ case 38400:
+ cflag |= B38400;
+ break;
+ case 2400:
+ default:
+ cflag |= B2400;
+ break;
}
- switch(bits) {
- case 7:
- cflag |= CS7;
- break;
- default:
- case 8:
- cflag |= CS8;
- break;
+ switch (bits) {
+ case 7:
+ cflag |= CS7;
+ break;
+ default:
+ case 8:
+ cflag |= CS8;
+ break;
}
- switch(parity) {
- case 'o': case 'O':
- cflag |= PARODD;
- break;
- case 'e': case 'E':
- cflag |= PARENB;
- break;
+ switch (parity) {
+ case 'o':
+ case 'O':
+ cflag |= PARODD;
+ break;
+ case 'e':
+ case 'E':
+ cflag |= PARENB;
+ break;
}
serial_console_info = &cy_port[ints[1]];
serial_console_cflag = cflag;
- serial_console = ints[1] + 64; /*callout_driver.minor_start*/
+ serial_console = ints[1] + 64; /*callout_driver.minor_start */
}
#endif
@@ -2532,9 +2509,10 @@ void console_setup(char *str, int *ints)
* The console must be locked when we get here.
*/
-void serial167_console_write(struct console *co, const char *str, unsigned count)
+void serial167_console_write(struct console *co, const char *str,
+ unsigned count)
{
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
unsigned long flags;
volatile u_char sink;
u_char ier;
@@ -2547,7 +2525,7 @@ void serial167_console_write(struct console *co, const char *str, unsigned count
/* Ensure transmitter is enabled! */
port = 0;
- base_addr[CyCAR] = (u_char)port;
+ base_addr[CyCAR] = (u_char) port;
while (base_addr[CyCCR])
;
base_addr[CyCCR] = CyENB_XMTR;
@@ -2556,8 +2534,7 @@ void serial167_console_write(struct console *co, const char *str, unsigned count
base_addr[CyIER] = CyTxMpty;
while (1) {
- if (pcc2chip[PccSCCTICR] & 0x20)
- {
+ if (pcc2chip[PccSCCTICR] & 0x20) {
/* We have a Tx int. Acknowledge it */
sink = pcc2chip[PccTPIACKR];
if ((base_addr[CyLICR] >> 2) == port) {
@@ -2571,18 +2548,15 @@ void serial167_console_write(struct console *co, const char *str, unsigned count
str++;
i++;
do_lf = 0;
- }
- else if (*str == '\n') {
+ } else if (*str == '\n') {
base_addr[CyTDR] = '\r';
do_lf = 1;
- }
- else {
+ } else {
base_addr[CyTDR] = *str++;
i++;
}
base_addr[CyTEOIR] = 0;
- }
- else
+ } else
base_addr[CyTEOIR] = CyNOTRANS;
}
}
@@ -2592,45 +2566,44 @@ void serial167_console_write(struct console *co, const char *str, unsigned count
local_irq_restore(flags);
}
-static struct tty_driver *serial167_console_device(struct console *c, int *index)
+static struct tty_driver *serial167_console_device(struct console *c,
+ int *index)
{
*index = c->index;
return cy_serial_driver;
}
-
static int __init serial167_console_setup(struct console *co, char *options)
{
return 0;
}
-
static struct console sercons = {
- .name = "ttyS",
- .write = serial167_console_write,
- .device = serial167_console_device,
- .setup = serial167_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
+ .name = "ttyS",
+ .write = serial167_console_write,
+ .device = serial167_console_device,
+ .setup = serial167_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
};
-
static int __init serial167_console_init(void)
{
if (vme_brdtype == VME_TYPE_MVME166 ||
- vme_brdtype == VME_TYPE_MVME167 ||
- vme_brdtype == VME_TYPE_MVME177) {
+ vme_brdtype == VME_TYPE_MVME167 ||
+ vme_brdtype == VME_TYPE_MVME177) {
mvme167_serial_console_setup(0);
register_console(&sercons);
}
return 0;
}
+
console_initcall(serial167_console_init);
#ifdef CONFIG_REMOTE_DEBUG
-void putDebugChar (int c)
+void putDebugChar(int c)
{
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
unsigned long flags;
volatile u_char sink;
u_char ier;
@@ -2641,7 +2614,7 @@ void putDebugChar (int c)
/* Ensure transmitter is enabled! */
port = DEBUG_PORT;
- base_addr[CyCAR] = (u_char)port;
+ base_addr[CyCAR] = (u_char) port;
while (base_addr[CyCCR])
;
base_addr[CyCCR] = CyENB_XMTR;
@@ -2650,16 +2623,14 @@ void putDebugChar (int c)
base_addr[CyIER] = CyTxMpty;
while (1) {
- if (pcc2chip[PccSCCTICR] & 0x20)
- {
+ if (pcc2chip[PccSCCTICR] & 0x20) {
/* We have a Tx int. Acknowledge it */
sink = pcc2chip[PccTPIACKR];
if ((base_addr[CyLICR] >> 2) == port) {
base_addr[CyTDR] = c;
base_addr[CyTEOIR] = 0;
break;
- }
- else
+ } else
base_addr[CyTEOIR] = CyNOTRANS;
}
}
@@ -2671,7 +2642,7 @@ void putDebugChar (int c)
int getDebugChar()
{
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
unsigned long flags;
volatile u_char sink;
u_char ier;
@@ -2693,7 +2664,7 @@ int getDebugChar()
/* Ensure receiver is enabled! */
port = DEBUG_PORT;
- base_addr[CyCAR] = (u_char)port;
+ base_addr[CyCAR] = (u_char) port;
#if 0
while (base_addr[CyCCR])
;
@@ -2703,31 +2674,30 @@ int getDebugChar()
base_addr[CyIER] = CyRxData;
while (1) {
- if (pcc2chip[PccSCCRICR] & 0x20)
- {
+ if (pcc2chip[PccSCCRICR] & 0x20) {
/* We have a Rx int. Acknowledge it */
sink = pcc2chip[PccRPIACKR];
if ((base_addr[CyLICR] >> 2) == port) {
int cnt = base_addr[CyRFOC];
- while (cnt-- > 0)
- {
+ while (cnt-- > 0) {
c = base_addr[CyRDR];
if (c == 0)
- printk ("!! debug char is null (cnt=%d) !!", cnt);
+ printk
+ ("!! debug char is null (cnt=%d) !!",
+ cnt);
else
- queueDebugChar (c);
+ queueDebugChar(c);
}
base_addr[CyREOIR] = 0;
i = debugiq.out;
if (i == debugiq.in)
- panic ("Debug input queue empty!");
+ panic("Debug input queue empty!");
c = debugiq.buf[i];
if (++i == DEBUG_LEN)
i = 0;
debugiq.out = i;
break;
- }
- else
+ } else
base_addr[CyREOIR] = CyNOTRANS;
}
}
@@ -2739,7 +2709,7 @@ int getDebugChar()
return (c);
}
-void queueDebugChar (int c)
+void queueDebugChar(int c)
{
int i;
@@ -2751,73 +2721,71 @@ void queueDebugChar (int c)
debugiq.in = i;
}
-static void
-debug_setup()
+static void debug_setup()
{
- unsigned long flags;
- volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
- int i, cflag;
+ unsigned long flags;
+ volatile unsigned char *base_addr = (u_char *) BASE_ADDR;
+ int i, cflag;
- cflag = B19200;
+ cflag = B19200;
- local_irq_save(flags);
+ local_irq_save(flags);
- for (i = 0; i < 4; i++)
- {
- base_addr[CyCAR] = i;
- base_addr[CyLICR] = i << 2;
- }
+ for (i = 0; i < 4; i++) {
+ base_addr[CyCAR] = i;
+ base_addr[CyLICR] = i << 2;
+ }
- debugiq.in = debugiq.out = 0;
+ debugiq.in = debugiq.out = 0;
- base_addr[CyCAR] = DEBUG_PORT;
+ base_addr[CyCAR] = DEBUG_PORT;
- /* baud rate */
- i = cflag & CBAUD;
+ /* baud rate */
+ i = cflag & CBAUD;
- base_addr[CyIER] = 0;
+ base_addr[CyIER] = 0;
- base_addr[CyCMR] = CyASYNC;
- base_addr[CyLICR] = DEBUG_PORT << 2;
- base_addr[CyLIVR] = 0x5c;
+ base_addr[CyCMR] = CyASYNC;
+ base_addr[CyLICR] = DEBUG_PORT << 2;
+ base_addr[CyLIVR] = 0x5c;
- /* tx and rx baud rate */
+ /* tx and rx baud rate */
- base_addr[CyTCOR] = baud_co[i];
- base_addr[CyTBPR] = baud_bpr[i];
- base_addr[CyRCOR] = baud_co[i] >> 5;
- base_addr[CyRBPR] = baud_bpr[i];
+ base_addr[CyTCOR] = baud_co[i];
+ base_addr[CyTBPR] = baud_bpr[i];
+ base_addr[CyRCOR] = baud_co[i] >> 5;
+ base_addr[CyRBPR] = baud_bpr[i];
- /* set line characteristics according configuration */
+ /* set line characteristics according configuration */
- base_addr[CySCHR1] = 0;
- base_addr[CySCHR2] = 0;
- base_addr[CySCRL] = 0;
- base_addr[CySCRH] = 0;
- base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
- base_addr[CyCOR2] = 0;
- base_addr[CyCOR3] = Cy_1_STOP;
- base_addr[CyCOR4] = baud_cor4[i];
- base_addr[CyCOR5] = 0;
- base_addr[CyCOR6] = 0;
- base_addr[CyCOR7] = 0;
+ base_addr[CySCHR1] = 0;
+ base_addr[CySCHR2] = 0;
+ base_addr[CySCRL] = 0;
+ base_addr[CySCRH] = 0;
+ base_addr[CyCOR1] = Cy_8_BITS | CyPARITY_NONE;
+ base_addr[CyCOR2] = 0;
+ base_addr[CyCOR3] = Cy_1_STOP;
+ base_addr[CyCOR4] = baud_cor4[i];
+ base_addr[CyCOR5] = 0;
+ base_addr[CyCOR6] = 0;
+ base_addr[CyCOR7] = 0;
- write_cy_cmd(base_addr,CyINIT_CHAN);
- write_cy_cmd(base_addr,CyENB_RCVR);
+ write_cy_cmd(base_addr, CyINIT_CHAN);
+ write_cy_cmd(base_addr, CyENB_RCVR);
- base_addr[CyCAR] = DEBUG_PORT; /* !!! Is this needed? */
+ base_addr[CyCAR] = DEBUG_PORT; /* !!! Is this needed? */
- base_addr[CyRTPRL] = 2;
- base_addr[CyRTPRH] = 0;
+ base_addr[CyRTPRL] = 2;
+ base_addr[CyRTPRH] = 0;
- base_addr[CyMSVR1] = CyRTS;
- base_addr[CyMSVR2] = CyDTR;
+ base_addr[CyMSVR1] = CyRTS;
+ base_addr[CyMSVR2] = CyDTR;
- base_addr[CyIER] = CyRxData;
+ base_addr[CyIER] = CyRxData;
- local_irq_restore(flags);
+ local_irq_restore(flags);
-} /* debug_setup */
+} /* debug_setup */
#endif
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 20946f5127e0..baf7234b6e66 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -459,10 +459,9 @@ void missed_irq (unsigned long data)
if (irq) {
printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
sx_interrupt (((struct specialix_board *)data)->irq,
- (void*)data, NULL);
+ (void*)data);
}
- missed_irq_timer.expires = jiffies + sx_poll;
- add_timer (&missed_irq_timer);
+ mod_timer(&missed_irq_timer, jiffies + sx_poll);
}
#endif
@@ -597,11 +596,8 @@ static int sx_probe(struct specialix_board *bp)
dprintk (SX_DEBUG_INIT, " GFCR = 0x%02x\n", sx_in_off(bp, CD186x_GFRCR) );
#ifdef SPECIALIX_TIMER
- init_timer (&missed_irq_timer);
- missed_irq_timer.function = missed_irq;
- missed_irq_timer.data = (unsigned long) bp;
- missed_irq_timer.expires = jiffies + sx_poll;
- add_timer (&missed_irq_timer);
+ setup_timer(&missed_irq_timer, missed_irq, (unsigned long)bp);
+ mod_timer(&missed_irq_timer, jiffies + sx_poll);
#endif
printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.\n",
@@ -2350,10 +2346,8 @@ static void do_softint(struct work_struct *work)
return;
}
- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event))
tty_wakeup(tty);
- //wake_up_interruptible(&tty->write_wait);
- }
func_exit();
}
@@ -2561,7 +2555,7 @@ static void __exit specialix_exit_module(void)
if (sx_board[i].flags & SX_BOARD_PRESENT)
sx_release_io_range(&sx_board[i]);
#ifdef SPECIALIX_TIMER
- del_timer (&missed_irq_timer);
+ del_timer_sync(&missed_irq_timer);
#endif
func_exit();
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 3fa625db9e4b..ce4db6f52362 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -1148,10 +1148,8 @@ static void mgsl_bh_transmit(struct mgsl_struct *info)
printk( "%s(%d):mgsl_bh_transmit() entry on %s\n",
__FILE__,__LINE__,info->device_name);
- if (tty) {
+ if (tty)
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
- }
/* if transmitter idle and loopmode_send_done_requested
* then start echoing RxD to TxD
@@ -1800,9 +1798,7 @@ static int startup(struct mgsl_struct * info)
memset(&info->icount, 0, sizeof(info->icount));
- init_timer(&info->tx_timer);
- info->tx_timer.data = (unsigned long)info;
- info->tx_timer.function = mgsl_tx_timeout;
+ setup_timer(&info->tx_timer, mgsl_tx_timeout, (unsigned long)info);
/* Allocate and claim adapter resources */
retval = mgsl_claim_resources(info);
@@ -1853,7 +1849,7 @@ static void shutdown(struct mgsl_struct * info)
wake_up_interruptible(&info->status_event_wait_q);
wake_up_interruptible(&info->event_wait_q);
- del_timer(&info->tx_timer);
+ del_timer_sync(&info->tx_timer);
if (info->xmit_buf) {
free_page((unsigned long) info->xmit_buf);
@@ -2340,7 +2336,6 @@ static void mgsl_flush_buffer(struct tty_struct *tty)
del_timer(&info->tx_timer);
spin_unlock_irqrestore(&info->irq_spinlock,flags);
- wake_up_interruptible(&tty->write_wait);
tty_wakeup(tty);
}
@@ -5713,8 +5708,8 @@ static void usc_start_transmitter( struct mgsl_struct *info )
usc_TCmd( info, TCmd_SendFrame );
- info->tx_timer.expires = jiffies + msecs_to_jiffies(5000);
- add_timer(&info->tx_timer);
+ mod_timer(&info->tx_timer, jiffies +
+ msecs_to_jiffies(5000));
}
info->tx_active = 1;
}
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 792c79c315e0..0a367cd4121f 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1045,7 +1045,6 @@ static void flush_buffer(struct tty_struct *tty)
info->tx_count = 0;
spin_unlock_irqrestore(&info->lock,flags);
- wake_up_interruptible(&tty->write_wait);
tty_wakeup(tty);
}
@@ -1826,8 +1825,7 @@ static void rx_async(struct slgt_info *info)
if (i < count) {
/* receive buffer not completed */
info->rbuf_index += i;
- info->rx_timer.expires = jiffies + 1;
- add_timer(&info->rx_timer);
+ mod_timer(&info->rx_timer, jiffies + 1);
break;
}
@@ -1933,10 +1931,8 @@ static void bh_transmit(struct slgt_info *info)
struct tty_struct *tty = info->tty;
DBGBH(("%s bh_transmit\n", info->device_name));
- if (tty) {
+ if (tty)
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
- }
}
static void dsr_change(struct slgt_info *info)
@@ -3343,13 +3339,8 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
info->adapter_num = adapter_num;
info->port_num = port_num;
- init_timer(&info->tx_timer);
- info->tx_timer.data = (unsigned long)info;
- info->tx_timer.function = tx_timeout;
-
- init_timer(&info->rx_timer);
- info->rx_timer.data = (unsigned long)info;
- info->rx_timer.function = rx_timeout;
+ setup_timer(&info->tx_timer, tx_timeout, (unsigned long)info);
+ setup_timer(&info->rx_timer, rx_timeout, (unsigned long)info);
/* Copy configuration info to device instance data */
info->pdev = pdev;
@@ -3797,10 +3788,9 @@ static void tx_start(struct slgt_info *info)
}
}
- if (info->params.mode == MGSL_MODE_HDLC) {
- info->tx_timer.expires = jiffies + msecs_to_jiffies(5000);
- add_timer(&info->tx_timer);
- }
+ if (info->params.mode == MGSL_MODE_HDLC)
+ mod_timer(&info->tx_timer, jiffies +
+ msecs_to_jiffies(5000));
} else {
tdma_reset(info);
/* set 1st descriptor address */
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 8f4d67afe5bf..ef93d055bdd7 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -1258,7 +1258,6 @@ static void flush_buffer(struct tty_struct *tty)
del_timer(&info->tx_timer);
spin_unlock_irqrestore(&info->lock,flags);
- wake_up_interruptible(&tty->write_wait);
tty_wakeup(tty);
}
@@ -2127,10 +2126,8 @@ void bh_transmit(SLMP_INFO *info)
printk( "%s(%d):%s bh_transmit() entry\n",
__FILE__,__LINE__,info->device_name);
- if (tty) {
+ if (tty)
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
- }
}
void bh_status(SLMP_INFO *info)
@@ -2747,8 +2744,7 @@ static int startup(SLMP_INFO * info)
change_params(info);
- info->status_timer.expires = jiffies + msecs_to_jiffies(10);
- add_timer(&info->status_timer);
+ mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10));
if (info->tty)
clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -3844,13 +3840,9 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
info->bus_type = MGSL_BUS_TYPE_PCI;
info->irq_flags = IRQF_SHARED;
- init_timer(&info->tx_timer);
- info->tx_timer.data = (unsigned long)info;
- info->tx_timer.function = tx_timeout;
-
- init_timer(&info->status_timer);
- info->status_timer.data = (unsigned long)info;
- info->status_timer.function = status_timeout;
+ setup_timer(&info->tx_timer, tx_timeout, (unsigned long)info);
+ setup_timer(&info->status_timer, status_timeout,
+ (unsigned long)info);
/* Store the PCI9050 misc control register value because a flaw
* in the PCI9050 prevents LCR registers from being read if
@@ -4294,8 +4286,8 @@ void tx_start(SLMP_INFO *info)
write_reg(info, TXDMA + DIR, 0x40); /* enable Tx DMA interrupts (EOM) */
write_reg(info, TXDMA + DSR, 0xf2); /* clear Tx DMA IRQs, enable Tx DMA */
- info->tx_timer.expires = jiffies + msecs_to_jiffies(5000);
- add_timer(&info->tx_timer);
+ mod_timer(&info->tx_timer, jiffies +
+ msecs_to_jiffies(5000));
}
else {
tx_load_fifo(info);
@@ -5577,10 +5569,7 @@ void status_timeout(unsigned long context)
if (status)
isr_io_pin(info,status);
- info->status_timer.data = (unsigned long)info;
- info->status_timer.function = status_timeout;
- info->status_timer.expires = jiffies + msecs_to_jiffies(10);
- add_timer(&info->status_timer);
+ mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10));
}
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 7fd3cd5ddf21..3757610b7835 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -88,9 +88,9 @@ static struct sysrq_key_op sysrq_loglevel_op = {
#ifdef CONFIG_VT
static void sysrq_handle_SAK(int key, struct tty_struct *tty)
{
- if (tty)
- do_SAK(tty);
- reset_vc(vc_cons[fg_console].d);
+ struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
+ PREPARE_WORK(SAK_work, vc_SAK);
+ schedule_work(SAK_work);
}
static struct sysrq_key_op sysrq_SAK_op = {
.handler = sysrq_handle_SAK,
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index 07067c31c4ec..c346ec5a3dc9 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -68,6 +68,7 @@
#include <linux/init.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/toshiba.h>
@@ -298,12 +299,10 @@ static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
* Print the information for /proc/toshiba
*/
#ifdef CONFIG_PROC_FS
-static int tosh_get_info(char *buffer, char **start, off_t fpos, int length)
+static int proc_toshiba_show(struct seq_file *m, void *v)
{
- char *temp;
int key;
- temp = buffer;
key = tosh_fn_status();
/* Arguments
@@ -314,8 +313,7 @@ static int tosh_get_info(char *buffer, char **start, off_t fpos, int length)
4) BIOS date (in SCI date format)
5) Fn Key status
*/
-
- temp += sprintf(temp, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n",
+ seq_printf(m, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n",
tosh_id,
(tosh_sci & 0xff00)>>8,
tosh_sci & 0xff,
@@ -323,9 +321,21 @@ static int tosh_get_info(char *buffer, char **start, off_t fpos, int length)
tosh_bios & 0xff,
tosh_date,
key);
+ return 0;
+}
- return temp-buffer;
+static int proc_toshiba_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_toshiba_show, NULL);
}
+
+static const struct file_operations proc_toshiba_fops = {
+ .owner = THIS_MODULE,
+ .open = proc_toshiba_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
#endif
@@ -508,10 +518,15 @@ static int __init toshiba_init(void)
return retval;
#ifdef CONFIG_PROC_FS
- /* register the proc entry */
- if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) {
- misc_deregister(&tosh_device);
- return -ENOMEM;
+ {
+ struct proc_dir_entry *pde;
+
+ pde = create_proc_entry("toshiba", 0, NULL);
+ if (!pde) {
+ misc_deregister(&tosh_device);
+ return -ENOMEM;
+ }
+ pde->proc_fops = &proc_toshiba_fops;
}
#endif
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 33e1f66e39cb..2f572b97c16d 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1107,9 +1107,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
INIT_WORK(&chip->work, timeout_work);
- init_timer(&chip->user_read_timer);
- chip->user_read_timer.function = user_reader_timeout;
- chip->user_read_timer.data = (unsigned long) chip;
+ setup_timer(&chip->user_read_timer, user_reader_timeout,
+ (unsigned long)chip);
memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index 7fca5f470beb..4eba32b23b29 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -441,7 +441,7 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode,
return err;
}
-struct file_operations tpm_ascii_bios_measurements_ops = {
+const struct file_operations tpm_ascii_bios_measurements_ops = {
.open = tpm_ascii_bios_measurements_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -474,7 +474,7 @@ static int tpm_binary_bios_measurements_open(struct inode *inode,
return err;
}
-struct file_operations tpm_binary_bios_measurements_ops = {
+const struct file_operations tpm_binary_bios_measurements_ops = {
.open = tpm_binary_bios_measurements_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 47a6eacb10bc..65672c57470b 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -154,7 +154,9 @@ static int tty_release(struct inode *, struct file *);
int tty_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg);
static int tty_fasync(int fd, struct file * filp, int on);
-static void release_mem(struct tty_struct *tty, int idx);
+static void release_tty(struct tty_struct *tty, int idx);
+static struct pid *__proc_set_tty(struct task_struct *tsk,
+ struct tty_struct *tty);
/**
* alloc_tty_struct - allocate a tty object
@@ -1109,17 +1111,17 @@ int tty_check_change(struct tty_struct * tty)
{
if (current->signal->tty != tty)
return 0;
- if (tty->pgrp <= 0) {
- printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n");
+ if (!tty->pgrp) {
+ printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
return 0;
}
- if (process_group(current) == tty->pgrp)
+ if (task_pgrp(current) == tty->pgrp)
return 0;
if (is_ignored(SIGTTOU))
return 0;
- if (is_orphaned_pgrp(process_group(current)))
+ if (is_current_pgrp_orphaned())
return -EIO;
- (void) kill_pg(process_group(current), SIGTTOU, 1);
+ (void) kill_pgrp(task_pgrp(current), SIGTTOU, 1);
return -ERESTARTSYS;
}
@@ -1354,8 +1356,8 @@ static void do_tty_hangup(struct work_struct *work)
tty_release is called */
read_lock(&tasklist_lock);
- if (tty->session > 0) {
- do_each_task_pid(tty->session, PIDTYPE_SID, p) {
+ if (tty->session) {
+ do_each_pid_task(tty->session, PIDTYPE_SID, p) {
spin_lock_irq(&p->sighand->siglock);
if (p->signal->tty == tty)
p->signal->tty = NULL;
@@ -1365,16 +1367,17 @@ static void do_tty_hangup(struct work_struct *work)
}
__group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
__group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
- if (tty->pgrp > 0)
- p->signal->tty_old_pgrp = tty->pgrp;
+ put_pid(p->signal->tty_old_pgrp); /* A noop */
+ if (tty->pgrp)
+ p->signal->tty_old_pgrp = get_pid(tty->pgrp);
spin_unlock_irq(&p->sighand->siglock);
- } while_each_task_pid(tty->session, PIDTYPE_SID, p);
+ } while_each_pid_task(tty->session, PIDTYPE_SID, p);
}
read_unlock(&tasklist_lock);
tty->flags = 0;
- tty->session = 0;
- tty->pgrp = -1;
+ tty->session = NULL;
+ tty->pgrp = NULL;
tty->ctrl_status = 0;
/*
* If one of the devices matches a console pointer, we
@@ -1459,12 +1462,12 @@ int tty_hung_up_p(struct file * filp)
EXPORT_SYMBOL(tty_hung_up_p);
-static void session_clear_tty(pid_t session)
+static void session_clear_tty(struct pid *session)
{
struct task_struct *p;
- do_each_task_pid(session, PIDTYPE_SID, p) {
+ do_each_pid_task(session, PIDTYPE_SID, p) {
proc_clear_tty(p);
- } while_each_task_pid(session, PIDTYPE_SID, p);
+ } while_each_pid_task(session, PIDTYPE_SID, p);
}
/**
@@ -1494,46 +1497,54 @@ static void session_clear_tty(pid_t session)
void disassociate_ctty(int on_exit)
{
struct tty_struct *tty;
- int tty_pgrp = -1;
- int session;
+ struct pid *tty_pgrp = NULL;
lock_kernel();
mutex_lock(&tty_mutex);
tty = get_current_tty();
if (tty) {
- tty_pgrp = tty->pgrp;
+ tty_pgrp = get_pid(tty->pgrp);
mutex_unlock(&tty_mutex);
/* XXX: here we race, there is nothing protecting tty */
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty);
- } else {
- pid_t old_pgrp = current->signal->tty_old_pgrp;
+ } else if (on_exit) {
+ struct pid *old_pgrp;
+ spin_lock_irq(&current->sighand->siglock);
+ old_pgrp = current->signal->tty_old_pgrp;
+ current->signal->tty_old_pgrp = NULL;
+ spin_unlock_irq(&current->sighand->siglock);
if (old_pgrp) {
- kill_pg(old_pgrp, SIGHUP, on_exit);
- kill_pg(old_pgrp, SIGCONT, on_exit);
+ kill_pgrp(old_pgrp, SIGHUP, on_exit);
+ kill_pgrp(old_pgrp, SIGCONT, on_exit);
+ put_pid(old_pgrp);
}
mutex_unlock(&tty_mutex);
unlock_kernel();
return;
}
- if (tty_pgrp > 0) {
- kill_pg(tty_pgrp, SIGHUP, on_exit);
+ if (tty_pgrp) {
+ kill_pgrp(tty_pgrp, SIGHUP, on_exit);
if (!on_exit)
- kill_pg(tty_pgrp, SIGCONT, on_exit);
+ kill_pgrp(tty_pgrp, SIGCONT, on_exit);
+ put_pid(tty_pgrp);
}
spin_lock_irq(&current->sighand->siglock);
+ tty_pgrp = current->signal->tty_old_pgrp;
current->signal->tty_old_pgrp = 0;
- session = process_session(current);
spin_unlock_irq(&current->sighand->siglock);
+ put_pid(tty_pgrp);
mutex_lock(&tty_mutex);
/* It is possible that do_tty_hangup has free'd this tty */
tty = get_current_tty();
if (tty) {
- tty->session = 0;
- tty->pgrp = 0;
+ put_pid(tty->session);
+ put_pid(tty->pgrp);
+ tty->session = NULL;
+ tty->pgrp = NULL;
} else {
#ifdef TTY_DEBUG_HANGUP
printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
@@ -1544,7 +1555,7 @@ void disassociate_ctty(int on_exit)
/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
- session_clear_tty(session);
+ session_clear_tty(task_session(current));
read_unlock(&tasklist_lock);
unlock_kernel();
}
@@ -1612,7 +1623,6 @@ void start_tty(struct tty_struct *tty)
/* If we have a running line discipline it may need kicking */
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
}
EXPORT_SYMBOL(start_tty);
@@ -2003,7 +2013,7 @@ static int init_dev(struct tty_driver *driver, int idx,
/*
* All structures have been allocated, so now we install them.
- * Failures after this point use release_mem to clean up, so
+ * Failures after this point use release_tty to clean up, so
* there's no need to null out the local pointers.
*/
if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) {
@@ -2024,8 +2034,8 @@ static int init_dev(struct tty_driver *driver, int idx,
/*
* Structures all installed ... call the ldisc open routines.
- * If we fail here just call release_mem to clean up. No need
- * to decrement the use counts, as release_mem doesn't care.
+ * If we fail here just call release_tty to clean up. No need
+ * to decrement the use counts, as release_tty doesn't care.
*/
if (tty->ldisc.open) {
@@ -2095,17 +2105,17 @@ fail_no_mem:
retval = -ENOMEM;
goto end_init;
- /* call the tty release_mem routine to clean out this slot */
+ /* call the tty release_tty routine to clean out this slot */
release_mem_out:
if (printk_ratelimit())
printk(KERN_INFO "init_dev: ldisc open failed, "
"clearing slot %d\n", idx);
- release_mem(tty, idx);
+ release_tty(tty, idx);
goto end_init;
}
/**
- * release_mem - release tty structure memory
+ * release_one_tty - release tty structure memory
*
* Releases memory associated with a tty structure, and clears out the
* driver table slots. This function is called when a device is no longer
@@ -2117,37 +2127,14 @@ release_mem_out:
* of ttys that the driver keeps.
* FIXME: should we require tty_mutex is held here ??
*/
-
-static void release_mem(struct tty_struct *tty, int idx)
+static void release_one_tty(struct tty_struct *tty, int idx)
{
- struct tty_struct *o_tty;
- struct ktermios *tp;
int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM;
-
- if ((o_tty = tty->link) != NULL) {
- if (!devpts)
- o_tty->driver->ttys[idx] = NULL;
- if (o_tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
- tp = o_tty->termios;
- if (!devpts)
- o_tty->driver->termios[idx] = NULL;
- kfree(tp);
-
- tp = o_tty->termios_locked;
- if (!devpts)
- o_tty->driver->termios_locked[idx] = NULL;
- kfree(tp);
- }
- o_tty->magic = 0;
- o_tty->driver->refcount--;
- file_list_lock();
- list_del_init(&o_tty->tty_files);
- file_list_unlock();
- free_tty_struct(o_tty);
- }
+ struct ktermios *tp;
if (!devpts)
tty->driver->ttys[idx] = NULL;
+
if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
tp = tty->termios;
if (!devpts)
@@ -2160,15 +2147,39 @@ static void release_mem(struct tty_struct *tty, int idx)
kfree(tp);
}
+
tty->magic = 0;
tty->driver->refcount--;
+
file_list_lock();
list_del_init(&tty->tty_files);
file_list_unlock();
- module_put(tty->driver->owner);
+
free_tty_struct(tty);
}
+/**
+ * release_tty - release tty structure memory
+ *
+ * Release both @tty and a possible linked partner (think pty pair),
+ * and decrement the refcount of the backing module.
+ *
+ * Locking:
+ * tty_mutex - sometimes only
+ * takes the file list lock internally when working on the list
+ * of ttys that the driver keeps.
+ * FIXME: should we require tty_mutex is held here ??
+ */
+static void release_tty(struct tty_struct *tty, int idx)
+{
+ struct tty_driver *driver = tty->driver;
+
+ if (tty->link)
+ release_one_tty(tty->link, idx);
+ release_one_tty(tty, idx);
+ module_put(driver->owner);
+}
+
/*
* Even releasing the tty structures is a tricky business.. We have
* to be very careful that the structures are all released at the
@@ -2436,10 +2447,10 @@ static void release_dev(struct file * filp)
tty_set_termios_ldisc(o_tty,N_TTY);
}
/*
- * The release_mem function takes care of the details of clearing
+ * The release_tty function takes care of the details of clearing
* the slots and preserving the termios structure.
*/
- release_mem(tty, idx);
+ release_tty(tty, idx);
#ifdef CONFIG_UNIX98_PTYS
/* Make this pty number available for reallocation */
@@ -2481,6 +2492,7 @@ static int tty_open(struct inode * inode, struct file * filp)
int index;
dev_t device = inode->i_rdev;
unsigned short saved_flags = filp->f_flags;
+ struct pid *old_pgrp;
nonseekable_open(inode, filp);
@@ -2574,15 +2586,17 @@ got_driver:
goto retry_open;
}
+ old_pgrp = NULL;
mutex_lock(&tty_mutex);
spin_lock_irq(&current->sighand->siglock);
if (!noctty &&
current->signal->leader &&
!current->signal->tty &&
- tty->session == 0)
- __proc_set_tty(current, tty);
+ tty->session == NULL)
+ old_pgrp = __proc_set_tty(current, tty);
spin_unlock_irq(&current->sighand->siglock);
mutex_unlock(&tty_mutex);
+ put_pid(old_pgrp);
return 0;
}
@@ -2721,9 +2735,18 @@ static int tty_fasync(int fd, struct file * filp, int on)
return retval;
if (on) {
+ enum pid_type type;
+ struct pid *pid;
if (!waitqueue_active(&tty->read_wait))
tty->minimum_to_wake = 1;
- retval = f_setown(filp, (-tty->pgrp) ? : current->pid, 0);
+ if (tty->pgrp) {
+ pid = tty->pgrp;
+ type = PIDTYPE_PGID;
+ } else {
+ pid = task_pid(current);
+ type = PIDTYPE_PID;
+ }
+ retval = __f_setown(filp, pid, type, 0);
if (retval)
return retval;
} else {
@@ -2825,10 +2848,10 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
}
}
#endif
- if (tty->pgrp > 0)
- kill_pg(tty->pgrp, SIGWINCH, 1);
- if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0))
- kill_pg(real_tty->pgrp, SIGWINCH, 1);
+ if (tty->pgrp)
+ kill_pgrp(tty->pgrp, SIGWINCH, 1);
+ if ((real_tty->pgrp != tty->pgrp) && real_tty->pgrp)
+ kill_pgrp(real_tty->pgrp, SIGWINCH, 1);
tty->winsize = tmp_ws;
real_tty->winsize = tmp_ws;
done:
@@ -2913,8 +2936,7 @@ static int fionbio(struct file *file, int __user *p)
static int tiocsctty(struct tty_struct *tty, int arg)
{
int ret = 0;
- if (current->signal->leader &&
- (process_session(current) == tty->session))
+ if (current->signal->leader && (task_session(current) == tty->session))
return ret;
mutex_lock(&tty_mutex);
@@ -2927,7 +2949,7 @@ static int tiocsctty(struct tty_struct *tty, int arg)
goto unlock;
}
- if (tty->session > 0) {
+ if (tty->session) {
/*
* This tty is already the controlling
* tty for another session group!
@@ -2970,7 +2992,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
- return put_user(real_tty->pgrp, p);
+ return put_user(pid_nr(real_tty->pgrp), p);
}
/**
@@ -2987,7 +3009,8 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
- pid_t pgrp;
+ struct pid *pgrp;
+ pid_t pgrp_nr;
int retval = tty_check_change(real_tty);
if (retval == -EIO)
@@ -2996,16 +3019,26 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
return retval;
if (!current->signal->tty ||
(current->signal->tty != real_tty) ||
- (real_tty->session != process_session(current)))
+ (real_tty->session != task_session(current)))
return -ENOTTY;
- if (get_user(pgrp, p))
+ if (get_user(pgrp_nr, p))
return -EFAULT;
- if (pgrp < 0)
+ if (pgrp_nr < 0)
return -EINVAL;
- if (session_of_pgrp(pgrp) != process_session(current))
- return -EPERM;
- real_tty->pgrp = pgrp;
- return 0;
+ rcu_read_lock();
+ pgrp = find_pid(pgrp_nr);
+ retval = -ESRCH;
+ if (!pgrp)
+ goto out_unlock;
+ retval = -EPERM;
+ if (session_of_pgrp(pgrp) != task_session(current))
+ goto out_unlock;
+ retval = 0;
+ put_pid(real_tty->pgrp);
+ real_tty->pgrp = get_pid(pgrp);
+out_unlock:
+ rcu_read_unlock();
+ return retval;
}
/**
@@ -3028,9 +3061,9 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
- if (real_tty->session <= 0)
+ if (!real_tty->session)
return -ENOTTY;
- return put_user(real_tty->session, p);
+ return put_user(pid_nr(real_tty->session), p);
}
/**
@@ -3324,15 +3357,13 @@ int tty_ioctl(struct inode * inode, struct file * file,
* Nasty bug: do_SAK is being called in interrupt context. This can
* deadlock. We punt it up to process context. AKPM - 16Mar2001
*/
-static void __do_SAK(struct work_struct *work)
+void __do_SAK(struct tty_struct *tty)
{
- struct tty_struct *tty =
- container_of(work, struct tty_struct, SAK_work);
#ifdef TTY_SOFT_SAK
tty_hangup(tty);
#else
struct task_struct *g, *p;
- int session;
+ struct pid *session;
int i;
struct file *filp;
struct fdtable *fdt;
@@ -3348,12 +3379,12 @@ static void __do_SAK(struct work_struct *work)
read_lock(&tasklist_lock);
/* Kill the entire session */
- do_each_task_pid(session, PIDTYPE_SID, p) {
+ do_each_pid_task(session, PIDTYPE_SID, p) {
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): process_session(p)==tty->session\n",
p->pid, p->comm);
send_sig(SIGKILL, p, 1);
- } while_each_task_pid(session, PIDTYPE_SID, p);
+ } while_each_pid_task(session, PIDTYPE_SID, p);
/* Now kill any processes that happen to have the
* tty open.
*/
@@ -3394,6 +3425,13 @@ static void __do_SAK(struct work_struct *work)
#endif
}
+static void do_SAK_work(struct work_struct *work)
+{
+ struct tty_struct *tty =
+ container_of(work, struct tty_struct, SAK_work);
+ __do_SAK(tty);
+}
+
/*
* The tq handling here is a little racy - tty->SAK_work may already be queued.
* Fortunately we don't need to worry, because if ->SAK_work is already queued,
@@ -3404,7 +3442,7 @@ void do_SAK(struct tty_struct *tty)
{
if (!tty)
return;
- PREPARE_WORK(&tty->SAK_work, __do_SAK);
+ PREPARE_WORK(&tty->SAK_work, do_SAK_work);
schedule_work(&tty->SAK_work);
}
@@ -3515,7 +3553,8 @@ static void initialize_tty_struct(struct tty_struct *tty)
memset(tty, 0, sizeof(struct tty_struct));
tty->magic = TTY_MAGIC;
tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
- tty->pgrp = -1;
+ tty->session = NULL;
+ tty->pgrp = NULL;
tty->overrun_time = jiffies;
tty->buf.head = tty->buf.tail = NULL;
tty_buffer_init(tty);
@@ -3786,21 +3825,28 @@ void proc_clear_tty(struct task_struct *p)
}
EXPORT_SYMBOL(proc_clear_tty);
-void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
+static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
+ struct pid *old_pgrp;
if (tty) {
- tty->session = process_session(tsk);
- tty->pgrp = process_group(tsk);
+ tty->session = get_pid(task_session(tsk));
+ tty->pgrp = get_pid(task_pgrp(tsk));
}
+ old_pgrp = tsk->signal->tty_old_pgrp;
tsk->signal->tty = tty;
- tsk->signal->tty_old_pgrp = 0;
+ tsk->signal->tty_old_pgrp = NULL;
+ return old_pgrp;
}
void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{
+ struct pid *old_pgrp;
+
spin_lock_irq(&tsk->sighand->siglock);
- __proc_set_tty(tsk, tty);
+ old_pgrp = __proc_set_tty(tsk, tty);
spin_unlock_irq(&tsk->sighand->siglock);
+
+ put_pid(old_pgrp);
}
struct tty_struct *get_current_tty(void)
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index dee47f40c6a3..fd471cb3338f 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -225,7 +225,7 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate);
/**
* tty_termios_encode_baud_rate
- * @termios: termios structure
+ * @termios: ktermios structure holding user requested state
* @ispeed: input speed
* @ospeed: output speed
*
@@ -233,7 +233,10 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate);
* used as a library helper for drivers os that they can report back
* the actual speed selected when it differs from the speed requested
*
- * For now input and output speed must agree.
+ * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
+ * we need to carefully set the bits when the user does not get the
+ * desired speed. We allow small margins and preserve as much of possible
+ * of the input intent to keep compatiblity.
*
* Locking: Caller should hold termios lock. This is already held
* when calling this function from the driver termios handler.
@@ -242,32 +245,44 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate);
void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud)
{
int i = 0;
- int ifound = 0, ofound = 0;
+ int ifound = -1, ofound = -1;
+ int iclose = ibaud/50, oclose = obaud/50;
+ int ibinput = 0;
termios->c_ispeed = ibaud;
termios->c_ospeed = obaud;
+ /* If the user asked for a precise weird speed give a precise weird
+ answer. If they asked for a Bfoo speed they many have problems
+ digesting non-exact replies so fuzz a bit */
+
+ if ((termios->c_cflag & CBAUD) == BOTHER)
+ oclose = 0;
+ if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
+ iclose = 0;
+ if ((termios->c_cflag >> IBSHIFT) & CBAUD)
+ ibinput = 1; /* An input speed was specified */
+
termios->c_cflag &= ~CBAUD;
- /* Identical speed means no input encoding (ie B0 << IBSHIFT)*/
- if (termios->c_ispeed == termios->c_ospeed)
- ifound = 1;
do {
- if (obaud == baud_table[i]) {
+ if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) {
termios->c_cflag |= baud_bits[i];
- ofound = 1;
- /* So that if ibaud == obaud we don't set it */
- continue;
+ ofound = i;
}
- if (ibaud == baud_table[i]) {
- termios->c_cflag |= (baud_bits[i] << IBSHIFT);
- ifound = 1;
+ if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) {
+ /* For the case input == output don't set IBAUD bits if the user didn't do so */
+ if (ofound != i || ibinput)
+ termios->c_cflag |= (baud_bits[i] << IBSHIFT);
+ ifound = i;
}
}
while(++i < n_baud_table);
- if (!ofound)
+ if (ofound == -1)
termios->c_cflag |= BOTHER;
- if (!ifound)
+ /* Set exact input bits only if the input and output differ or the
+ user already did */
+ if (ifound == -1 && (ibaud != obaud || ibinput))
termios->c_cflag |= (BOTHER << IBSHIFT);
}
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 9438512b17f1..13faf8d17482 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -872,7 +872,7 @@ free_op:
return ret;
}
-struct file_operations viotap_fops = {
+const struct file_operations viotap_fops = {
owner: THIS_MODULE,
read: viotap_read,
write: viotap_write,
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 06c32a3e3ca4..94ce3e7fc9e4 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -136,9 +136,6 @@ const struct consw *conswitchp;
#define DEFAULT_BELL_PITCH 750
#define DEFAULT_BELL_DURATION (HZ/8)
-extern void vcs_make_sysfs(struct tty_struct *tty);
-extern void vcs_remove_sysfs(struct tty_struct *tty);
-
struct vc vc_cons [MAX_NR_CONSOLES];
#ifndef VT_SINGLE_DRIVER
@@ -213,7 +210,7 @@ static int scrollback_delta;
*/
int (*console_blank_hook)(int);
-static struct timer_list console_timer;
+static DEFINE_TIMER(console_timer, blank_screen_t, 0, 0);
static int blank_state;
static int blank_timer_expired;
enum {
@@ -869,8 +866,8 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
ws.ws_col = vc->vc_cols;
ws.ws_ypixel = vc->vc_scan_lines;
if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
- vc->vc_tty->pgrp > 0)
- kill_pg(vc->vc_tty->pgrp, SIGWINCH, 1);
+ vc->vc_tty->pgrp)
+ kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1);
*cws = ws;
}
@@ -2628,8 +2625,6 @@ static int __init con_init(void)
for (i = 0; i < MAX_NR_CONSOLES; i++)
con_driver_map[i] = conswitchp;
- init_timer(&console_timer);
- console_timer.function = blank_screen_t;
if (blankinterval) {
blank_state = blank_normal_wait;
mod_timer(&console_timer, jiffies + blankinterval);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index dc8368ebb1ac..3a5d301e783b 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -672,7 +672,8 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
vc->vt_mode = tmp;
/* the frsig is ignored, so we set it to 0 */
vc->vt_mode.frsig = 0;
- put_pid(xchg(&vc->vt_pid, get_pid(task_pid(current))));
+ put_pid(vc->vt_pid);
+ vc->vt_pid = get_pid(task_pid(current));
/* no switch is required -- saw@shade.msu.ru */
vc->vt_newvt = -1;
release_console_sem();
@@ -1063,12 +1064,35 @@ void reset_vc(struct vc_data *vc)
vc->vt_mode.relsig = 0;
vc->vt_mode.acqsig = 0;
vc->vt_mode.frsig = 0;
- put_pid(xchg(&vc->vt_pid, NULL));
+ put_pid(vc->vt_pid);
+ vc->vt_pid = NULL;
vc->vt_newvt = -1;
if (!in_interrupt()) /* Via keyboard.c:SAK() - akpm */
reset_palette(vc);
}
+void vc_SAK(struct work_struct *work)
+{
+ struct vc *vc_con =
+ container_of(work, struct vc, SAK_work);
+ struct vc_data *vc;
+ struct tty_struct *tty;
+
+ acquire_console_sem();
+ vc = vc_con->d;
+ if (vc) {
+ tty = vc->vc_tty;
+ /*
+ * SAK should also work in all raw modes and reset
+ * them properly.
+ */
+ if (tty)
+ __do_SAK(tty);
+ reset_vc(vc);
+ }
+ release_console_sem();
+}
+
/*
* Performs the back end of a vt switch
*/
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
index bf25d0a55a99..e5b2c2ee292c 100644
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/char/watchdog/alim7101_wdt.c
@@ -417,10 +417,8 @@ module_init(alim7101_wdt_init);
module_exit(alim7101_wdt_unload);
static struct pci_device_id alim7101_pci_tbl[] __devinitdata = {
- { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533) },
+ { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
{ }
};
diff --git a/drivers/char/watchdog/iTCO_wdt.c b/drivers/char/watchdog/iTCO_wdt.c
index 7eac922df867..fd8a44a08cd3 100644
--- a/drivers/char/watchdog/iTCO_wdt.c
+++ b/drivers/char/watchdog/iTCO_wdt.c
@@ -539,7 +539,7 @@ static int iTCO_wdt_ioctl (struct inode *inode, struct file *file,
* Kernel Interfaces
*/
-static struct file_operations iTCO_wdt_fops = {
+static const struct file_operations iTCO_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = iTCO_wdt_write,
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/char/watchdog/omap_wdt.c
index 6c6f97332dbb..84074a697dce 100644
--- a/drivers/char/watchdog/omap_wdt.c
+++ b/drivers/char/watchdog/omap_wdt.c
@@ -230,7 +230,7 @@ omap_wdt_ioctl(struct inode *inode, struct file *file,
}
}
-static struct file_operations omap_wdt_fops = {
+static const struct file_operations omap_wdt_fops = {
.owner = THIS_MODULE,
.write = omap_wdt_write,
.ioctl = omap_wdt_ioctl,
diff --git a/drivers/char/watchdog/pc87413_wdt.c b/drivers/char/watchdog/pc87413_wdt.c
index 1d447e32af41..a77a90717ad2 100644
--- a/drivers/char/watchdog/pc87413_wdt.c
+++ b/drivers/char/watchdog/pc87413_wdt.c
@@ -526,7 +526,7 @@ static int pc87413_notify_sys(struct notifier_block *this,
/* -- Module's structures ---------------------------------------*/
-static struct file_operations pc87413_fops = {
+static const struct file_operations pc87413_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = pc87413_write,
diff --git a/drivers/char/watchdog/pnx4008_wdt.c b/drivers/char/watchdog/pnx4008_wdt.c
index 3a55fc6abcd8..ff6f1ca1e5e7 100644
--- a/drivers/char/watchdog/pnx4008_wdt.c
+++ b/drivers/char/watchdog/pnx4008_wdt.c
@@ -238,7 +238,7 @@ static int pnx4008_wdt_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations pnx4008_wdt_fops = {
+static const struct file_operations pnx4008_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = pnx4008_wdt_write,
diff --git a/drivers/char/watchdog/rm9k_wdt.c b/drivers/char/watchdog/rm9k_wdt.c
index 7576a13e86bc..b4678839d3bb 100644
--- a/drivers/char/watchdog/rm9k_wdt.c
+++ b/drivers/char/watchdog/rm9k_wdt.c
@@ -95,7 +95,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be disabled once started");
/* Kernel interfaces */
-static struct file_operations fops = {
+static const struct file_operations fops = {
.owner = THIS_MODULE,
.open = wdt_gpi_open,
.release = wdt_gpi_release,
diff --git a/drivers/char/watchdog/smsc37b787_wdt.c b/drivers/char/watchdog/smsc37b787_wdt.c
index 9f56913b484f..a9681d580dd3 100644
--- a/drivers/char/watchdog/smsc37b787_wdt.c
+++ b/drivers/char/watchdog/smsc37b787_wdt.c
@@ -510,7 +510,7 @@ static int wb_smsc_wdt_notify_sys(struct notifier_block *this, unsigned long cod
/* -- Module's structures ---------------------------------------*/
-static struct file_operations wb_smsc_wdt_fops =
+static const struct file_operations wb_smsc_wdt_fops =
{
.owner = THIS_MODULE,
.llseek = no_llseek,
diff --git a/drivers/char/watchdog/w83697hf_wdt.c b/drivers/char/watchdog/w83697hf_wdt.c
index 7768b55487c8..c960ec110dd7 100644
--- a/drivers/char/watchdog/w83697hf_wdt.c
+++ b/drivers/char/watchdog/w83697hf_wdt.c
@@ -323,7 +323,7 @@ wdt_notify_sys(struct notifier_block *this, unsigned long code,
* Kernel Interfaces
*/
-static struct file_operations wdt_fops = {
+static const struct file_operations wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = wdt_write,
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c
index c82bc0ed7f14..8bcc887692ab 100644
--- a/drivers/edac/e752x_edac.c
+++ b/drivers/edac/e752x_edac.c
@@ -285,8 +285,9 @@ static void do_process_ce(struct mem_ctl_info *mci, u16 error_one,
if (!pvt->map_type)
row = 7 - row;
- edac_mc_handle_ce(mci, page, 0, sec1_syndrome, row, channel,
- "e752x CE");
+ /* e752x mc reads 34:6 of the DRAM linear address */
+ edac_mc_handle_ce(mci, page, offset_in_page(sec1_add << 4),
+ sec1_syndrome, row, channel, "e752x CE");
}
static inline void process_ce(struct mem_ctl_info *mci, u16 error_one,
@@ -319,8 +320,10 @@ static void do_process_ue(struct mem_ctl_info *mci, u16 error_one,
((block_page >> 1) & 3) :
edac_mc_find_csrow_by_page(mci, block_page);
- edac_mc_handle_ue(mci, block_page, 0, row,
- "e752x UE from Read");
+ /* e752x mc reads 34:6 of the DRAM linear address */
+ edac_mc_handle_ue(mci, block_page,
+ offset_in_page(error_2b << 4),
+ row, "e752x UE from Read");
}
if (error_one & 0x0404) {
error_2b = scrb_add;
@@ -333,8 +336,10 @@ static void do_process_ue(struct mem_ctl_info *mci, u16 error_one,
((block_page >> 1) & 3) :
edac_mc_find_csrow_by_page(mci, block_page);
- edac_mc_handle_ue(mci, block_page, 0, row,
- "e752x UE from Scruber");
+ /* e752x mc reads 34:6 of the DRAM linear address */
+ edac_mc_handle_ue(mci, block_page,
+ offset_in_page(error_2b << 4),
+ row, "e752x UE from Scruber");
}
}
@@ -556,17 +561,17 @@ static void e752x_check_sysbus(struct e752x_error_info *info,
error32 = (stat32 >> 16) & 0x3ff;
stat32 = stat32 & 0x3ff;
- if(stat32 & 0x083)
- sysbus_error(1, stat32 & 0x083, error_found, handle_error);
+ if(stat32 & 0x087)
+ sysbus_error(1, stat32 & 0x087, error_found, handle_error);
- if(stat32 & 0x37c)
- sysbus_error(0, stat32 & 0x37c, error_found, handle_error);
+ if(stat32 & 0x378)
+ sysbus_error(0, stat32 & 0x378, error_found, handle_error);
- if(error32 & 0x083)
- sysbus_error(1, error32 & 0x083, error_found, handle_error);
+ if(error32 & 0x087)
+ sysbus_error(1, error32 & 0x087, error_found, handle_error);
- if(error32 & 0x37c)
- sysbus_error(0, error32 & 0x37c, error_found, handle_error);
+ if(error32 & 0x378)
+ sysbus_error(0, error32 & 0x378, error_found, handle_error);
}
static void e752x_check_membuf (struct e752x_error_info *info,
@@ -782,7 +787,12 @@ static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
u8 value;
u32 dra, drc, cumul_size;
- pci_read_config_dword(pdev, E752X_DRA, &dra);
+ dra = 0;
+ for (index=0; index < 4; index++) {
+ u8 dra_reg;
+ pci_read_config_byte(pdev, E752X_DRA+index, &dra_reg);
+ dra |= dra_reg << (index * 8);
+ }
pci_read_config_dword(pdev, E752X_DRC, &drc);
drc_chan = dual_channel_active(ddrcsr);
drc_drbg = drc_chan + 1; /* 128 in dual mode, 64 in single */
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 1b4fc9221803..7b622300d0e5 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -927,6 +927,57 @@ static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci,
return count;
}
+/* memory scrubbing */
+static ssize_t mci_sdram_scrub_rate_store(struct mem_ctl_info *mci,
+ const char *data, size_t count)
+{
+ u32 bandwidth = -1;
+
+ if (mci->set_sdram_scrub_rate) {
+
+ memctrl_int_store(&bandwidth, data, count);
+
+ if (!(*mci->set_sdram_scrub_rate)(mci, &bandwidth)) {
+ edac_printk(KERN_DEBUG, EDAC_MC,
+ "Scrub rate set successfully, applied: %d\n",
+ bandwidth);
+ } else {
+ /* FIXME: error codes maybe? */
+ edac_printk(KERN_DEBUG, EDAC_MC,
+ "Scrub rate set FAILED, could not apply: %d\n",
+ bandwidth);
+ }
+ } else {
+ /* FIXME: produce "not implemented" ERROR for user-side. */
+ edac_printk(KERN_WARNING, EDAC_MC,
+ "Memory scrubbing 'set'control is not implemented!\n");
+ }
+ return count;
+}
+
+static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data)
+{
+ u32 bandwidth = -1;
+
+ if (mci->get_sdram_scrub_rate) {
+ if (!(*mci->get_sdram_scrub_rate)(mci, &bandwidth)) {
+ edac_printk(KERN_DEBUG, EDAC_MC,
+ "Scrub rate successfully, fetched: %d\n",
+ bandwidth);
+ } else {
+ /* FIXME: error codes maybe? */
+ edac_printk(KERN_DEBUG, EDAC_MC,
+ "Scrub rate fetch FAILED, got: %d\n",
+ bandwidth);
+ }
+ } else {
+ /* FIXME: produce "not implemented" ERROR for user-side. */
+ edac_printk(KERN_WARNING, EDAC_MC,
+ "Memory scrubbing 'get' control is not implemented!\n");
+ }
+ return sprintf(data, "%d\n", bandwidth);
+}
+
/* default attribute files for the MCI object */
static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data)
{
@@ -1033,6 +1084,9 @@ MCIDEV_ATTR(ce_noinfo_count,S_IRUGO,mci_ce_noinfo_show,NULL);
MCIDEV_ATTR(ue_count,S_IRUGO,mci_ue_count_show,NULL);
MCIDEV_ATTR(ce_count,S_IRUGO,mci_ce_count_show,NULL);
+/* memory scrubber attribute file */
+MCIDEV_ATTR(sdram_scrub_rate,S_IRUGO|S_IWUSR,mci_sdram_scrub_rate_show,mci_sdram_scrub_rate_store);
+
static struct mcidev_attribute *mci_attr[] = {
&mci_attr_reset_counters,
&mci_attr_mc_name,
@@ -1042,6 +1096,7 @@ static struct mcidev_attribute *mci_attr[] = {
&mci_attr_ce_noinfo_count,
&mci_attr_ue_count,
&mci_attr_ce_count,
+ &mci_attr_sdram_scrub_rate,
NULL
};
@@ -1442,11 +1497,11 @@ int edac_mc_add_mc(struct mem_ctl_info *mci, int mc_idx)
/* set load time so that error rate can be tracked */
mci->start_time = jiffies;
- if (edac_create_sysfs_mci_device(mci)) {
- edac_mc_printk(mci, KERN_WARNING,
+ if (edac_create_sysfs_mci_device(mci)) {
+ edac_mc_printk(mci, KERN_WARNING,
"failed to create sysfs device\n");
- goto fail1;
- }
+ goto fail1;
+ }
/* Report action taken */
edac_mc_printk(mci, KERN_INFO, "Giving out device to %s %s: DEV %s\n",
@@ -1703,6 +1758,116 @@ void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg)
EXPORT_SYMBOL_GPL(edac_mc_handle_ue_no_info);
+/*************************************************************
+ * On Fully Buffered DIMM modules, this help function is
+ * called to process UE events
+ */
+void edac_mc_handle_fbd_ue(struct mem_ctl_info *mci,
+ unsigned int csrow,
+ unsigned int channela,
+ unsigned int channelb,
+ char *msg)
+{
+ int len = EDAC_MC_LABEL_LEN * 4;
+ char labels[len + 1];
+ char *pos = labels;
+ int chars;
+
+ if (csrow >= mci->nr_csrows) {
+ /* something is wrong */
+ edac_mc_printk(mci, KERN_ERR,
+ "INTERNAL ERROR: row out of range (%d >= %d)\n",
+ csrow, mci->nr_csrows);
+ edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR");
+ return;
+ }
+
+ if (channela >= mci->csrows[csrow].nr_channels) {
+ /* something is wrong */
+ edac_mc_printk(mci, KERN_ERR,
+ "INTERNAL ERROR: channel-a out of range "
+ "(%d >= %d)\n",
+ channela, mci->csrows[csrow].nr_channels);
+ edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR");
+ return;
+ }
+
+ if (channelb >= mci->csrows[csrow].nr_channels) {
+ /* something is wrong */
+ edac_mc_printk(mci, KERN_ERR,
+ "INTERNAL ERROR: channel-b out of range "
+ "(%d >= %d)\n",
+ channelb, mci->csrows[csrow].nr_channels);
+ edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR");
+ return;
+ }
+
+ mci->ue_count++;
+ mci->csrows[csrow].ue_count++;
+
+ /* Generate the DIMM labels from the specified channels */
+ chars = snprintf(pos, len + 1, "%s",
+ mci->csrows[csrow].channels[channela].label);
+ len -= chars; pos += chars;
+ chars = snprintf(pos, len + 1, "-%s",
+ mci->csrows[csrow].channels[channelb].label);
+
+ if (log_ue)
+ edac_mc_printk(mci, KERN_EMERG,
+ "UE row %d, channel-a= %d channel-b= %d "
+ "labels \"%s\": %s\n", csrow, channela, channelb,
+ labels, msg);
+
+ if (panic_on_ue)
+ panic("UE row %d, channel-a= %d channel-b= %d "
+ "labels \"%s\": %s\n", csrow, channela,
+ channelb, labels, msg);
+}
+EXPORT_SYMBOL(edac_mc_handle_fbd_ue);
+
+/*************************************************************
+ * On Fully Buffered DIMM modules, this help function is
+ * called to process CE events
+ */
+void edac_mc_handle_fbd_ce(struct mem_ctl_info *mci,
+ unsigned int csrow,
+ unsigned int channel,
+ char *msg)
+{
+
+ /* Ensure boundary values */
+ if (csrow >= mci->nr_csrows) {
+ /* something is wrong */
+ edac_mc_printk(mci, KERN_ERR,
+ "INTERNAL ERROR: row out of range (%d >= %d)\n",
+ csrow, mci->nr_csrows);
+ edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
+ return;
+ }
+ if (channel >= mci->csrows[csrow].nr_channels) {
+ /* something is wrong */
+ edac_mc_printk(mci, KERN_ERR,
+ "INTERNAL ERROR: channel out of range (%d >= %d)\n",
+ channel, mci->csrows[csrow].nr_channels);
+ edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR");
+ return;
+ }
+
+ if (log_ce)
+ /* FIXME - put in DIMM location */
+ edac_mc_printk(mci, KERN_WARNING,
+ "CE row %d, channel %d, label \"%s\": %s\n",
+ csrow, channel,
+ mci->csrows[csrow].channels[channel].label,
+ msg);
+
+ mci->ce_count++;
+ mci->csrows[csrow].ce_count++;
+ mci->csrows[csrow].channels[channel].ce_count++;
+}
+EXPORT_SYMBOL(edac_mc_handle_fbd_ce);
+
+
/*
* Iterate over all MC instances and check for ECC, et al, errors
*/
@@ -1806,7 +1971,7 @@ static void __exit edac_mc_exit(void)
debugf0("%s()\n", __func__);
kthread_stop(edac_thread);
- /* tear down the sysfs device */
+ /* tear down the sysfs device */
edac_sysfs_memctrl_teardown();
edac_sysfs_pci_teardown();
}
diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h
index a1cfd4e3c97d..713444cc4105 100644
--- a/drivers/edac/edac_mc.h
+++ b/drivers/edac/edac_mc.h
@@ -123,7 +123,9 @@ enum mem_type {
MEM_RDR, /* Registered single data rate SDRAM */
MEM_DDR, /* Double data rate SDRAM */
MEM_RDDR, /* Registered Double data rate SDRAM */
- MEM_RMBS /* Rambus DRAM */
+ MEM_RMBS, /* Rambus DRAM */
+ MEM_DDR2, /* DDR2 RAM */
+ MEM_FB_DDR2, /* fully buffered DDR2 */
};
#define MEM_FLAG_EMPTY BIT(MEM_EMPTY)
@@ -137,6 +139,8 @@ enum mem_type {
#define MEM_FLAG_DDR BIT(MEM_DDR)
#define MEM_FLAG_RDDR BIT(MEM_RDDR)
#define MEM_FLAG_RMBS BIT(MEM_RMBS)
+#define MEM_FLAG_DDR2 BIT(MEM_DDR2)
+#define MEM_FLAG_FB_DDR2 BIT(MEM_FB_DDR2)
/* chipset Error Detection and Correction capabilities and mode */
enum edac_type {
@@ -315,8 +319,21 @@ struct mem_ctl_info {
unsigned long scrub_cap; /* chipset scrub capabilities */
enum scrub_type scrub_mode; /* current scrub mode */
+ /* Translates sdram memory scrub rate given in bytes/sec to the
+ internal representation and configures whatever else needs
+ to be configured.
+ */
+ int (*set_sdram_scrub_rate) (struct mem_ctl_info *mci, u32 *bw);
+
+ /* Get the current sdram memory scrub rate from the internal
+ representation and converts it to the closest matching
+ bandwith in bytes/sec.
+ */
+ int (*get_sdram_scrub_rate) (struct mem_ctl_info *mci, u32 *bw);
+
/* pointer to edac checking routine */
void (*edac_check) (struct mem_ctl_info * mci);
+
/*
* Remaps memory pages: controller pages to physical pages.
* For most MC's, this will be NULL.
@@ -441,6 +458,15 @@ extern void edac_mc_handle_ue(struct mem_ctl_info *mci,
int row, const char *msg);
extern void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
const char *msg);
+extern void edac_mc_handle_fbd_ue(struct mem_ctl_info *mci,
+ unsigned int csrow,
+ unsigned int channel0,
+ unsigned int channel1,
+ char *msg);
+extern void edac_mc_handle_fbd_ce(struct mem_ctl_info *mci,
+ unsigned int csrow,
+ unsigned int channel,
+ char *msg);
/*
* This kmalloc's and initializes all the structures.
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 5c261e1f92b2..d8806e4f1829 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -233,6 +233,8 @@ edd_show_interface(struct edd_device *edev, char *buf)
/**
* edd_show_raw_data() - copies raw data to buffer for userspace to parse
+ * @edev: target edd_device
+ * @buf: output buffer
*
* Returns: number of bytes written, or -EINVAL on failure
*/
@@ -634,8 +636,8 @@ static decl_subsys(edd,&ktype_edd,NULL);
/**
* edd_dev_is_type() - is this EDD device a 'type' device?
- * @edev
- * @type - a host bus or interface identifier string per the EDD spec
+ * @edev: target edd_device
+ * @type: a host bus or interface identifier string per the EDD spec
*
* Returns 1 (TRUE) if it is a 'type' device, 0 otherwise.
*/
@@ -657,7 +659,7 @@ edd_dev_is_type(struct edd_device *edev, const char *type)
/**
* edd_get_pci_dev() - finds pci_dev that matches edev
- * @edev - edd_device
+ * @edev: edd_device
*
* Returns pci_dev if found, or NULL
*/
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index 4ee56def61f2..214fbb1423c5 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -308,7 +308,7 @@ static int dbg_tps_open(struct inode *inode, struct file *file)
return single_open(file, dbg_show, inode->i_private);
}
-static struct file_operations debug_fops = {
+static const struct file_operations debug_fops = {
.open = dbg_tps_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index ac5bd2a7ca99..cb4fa9bef8cd 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -392,7 +392,7 @@ static int i2cdev_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations i2cdev_fops = {
+static const struct file_operations i2cdev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = i2cdev_read,
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index aa049dab3d95..30a5780f4185 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -413,7 +413,6 @@ void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void
while (p->name != NULL) {
ent = create_proc_entry(p->name, p->mode, dir);
if (!ent) return;
- ent->nlink = 1;
ent->data = data;
ent->read_proc = p->read_proc;
ent->write_proc = p->write_proc;
@@ -549,7 +548,7 @@ static int ide_drivers_open(struct inode *inode, struct file *file)
return single_open(file, &ide_drivers_show, NULL);
}
-static struct file_operations ide_drivers_operations = {
+static const struct file_operations ide_drivers_operations = {
.open = ide_drivers_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index b3bcd1d7315e..c6eec0413a6c 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -4779,7 +4779,7 @@ static ide_driver_t idetape_driver = {
/*
* Our character device supporting functions, passed to register_chrdev.
*/
-static struct file_operations idetape_fops = {
+static const struct file_operations idetape_fops = {
.owner = THIS_MODULE,
.read = idetape_chrdev_read,
.write = idetape_chrdev_write,
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 55d6ae664fd6..dee9529aa8e7 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2147,7 +2147,7 @@ out:
}
static struct cdev dv1394_cdev;
-static struct file_operations dv1394_fops=
+static const struct file_operations dv1394_fops=
{
.owner = THIS_MODULE,
.poll = dv1394_poll,
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index a77a832828c8..aa9ca8385ec7 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -3013,7 +3013,7 @@ static struct hpsb_highlevel raw1394_highlevel = {
};
static struct cdev raw1394_cdev;
-static struct file_operations raw1394_fops = {
+static const struct file_operations raw1394_fops = {
.owner = THIS_MODULE,
.read = raw1394_read,
.write = raw1394_write,
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index f4d1ec00af65..95ca26d75272 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -1277,7 +1277,7 @@ static long video1394_compat_ioctl(struct file *f, unsigned cmd, unsigned long a
#endif
static struct cdev video1394_cdev;
-static struct file_operations video1394_fops=
+static const struct file_operations video1394_fops=
{
.owner = THIS_MODULE,
.unlocked_ioctl = video1394_ioctl,
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index f15220a0ee75..ee51d79a7ad5 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -1221,7 +1221,7 @@ static void ib_ucm_release_class_dev(struct class_device *class_dev)
kfree(dev);
}
-static struct file_operations ucm_fops = {
+static const struct file_operations ucm_fops = {
.owner = THIS_MODULE,
.open = ib_ucm_open,
.release = ib_ucm_close,
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index e2e8d329b443..6b81b98961c7 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -833,7 +833,7 @@ static int ucma_close(struct inode *inode, struct file *filp)
return 0;
}
-static struct file_operations ucma_fops = {
+static const struct file_operations ucma_fops = {
.owner = THIS_MODULE,
.open = ucma_open,
.release = ucma_close,
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 807fbd6b8414..c069ebeba8e3 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -771,7 +771,7 @@ static int ib_umad_close(struct inode *inode, struct file *filp)
return 0;
}
-static struct file_operations umad_fops = {
+static const struct file_operations umad_fops = {
.owner = THIS_MODULE,
.read = ib_umad_read,
.write = ib_umad_write,
@@ -846,7 +846,7 @@ static int ib_umad_sm_close(struct inode *inode, struct file *filp)
return ret;
}
-static struct file_operations umad_sm_fops = {
+static const struct file_operations umad_sm_fops = {
.owner = THIS_MODULE,
.open = ib_umad_sm_open,
.release = ib_umad_sm_close
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index a617ca7b6923..f8bc822a3cc3 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -375,7 +375,7 @@ static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
return 0;
}
-static struct file_operations uverbs_event_fops = {
+static const struct file_operations uverbs_event_fops = {
.owner = THIS_MODULE,
.read = ib_uverbs_event_read,
.poll = ib_uverbs_event_poll,
@@ -679,14 +679,14 @@ static int ib_uverbs_close(struct inode *inode, struct file *filp)
return 0;
}
-static struct file_operations uverbs_fops = {
+static const struct file_operations uverbs_fops = {
.owner = THIS_MODULE,
.write = ib_uverbs_write,
.open = ib_uverbs_open,
.release = ib_uverbs_close
};
-static struct file_operations uverbs_mmap_fops = {
+static const struct file_operations uverbs_mmap_fops = {
.owner = THIS_MODULE,
.write = ib_uverbs_write,
.mmap = ib_uverbs_mmap,
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c
index 9291a86ca053..6ebfa27e4e16 100644
--- a/drivers/infiniband/hw/ehca/ehca_cq.c
+++ b/drivers/infiniband/hw/ehca/ehca_cq.c
@@ -134,14 +134,13 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe,
if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
return ERR_PTR(-EINVAL);
- my_cq = kmem_cache_alloc(cq_cache, GFP_KERNEL);
+ my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL);
if (!my_cq) {
ehca_err(device, "Out of memory for ehca_cq struct device=%p",
device);
return ERR_PTR(-ENOMEM);
}
- memset(my_cq, 0, sizeof(struct ehca_cq));
memset(&param, 0, sizeof(struct ehca_alloc_cq_parms));
spin_lock_init(&my_cq->spinlock);
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c
index cfb362a1029c..d22ab563633f 100644
--- a/drivers/infiniband/hw/ehca/ehca_mrmw.c
+++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c
@@ -53,9 +53,8 @@ static struct ehca_mr *ehca_mr_new(void)
{
struct ehca_mr *me;
- me = kmem_cache_alloc(mr_cache, GFP_KERNEL);
+ me = kmem_cache_zalloc(mr_cache, GFP_KERNEL);
if (me) {
- memset(me, 0, sizeof(struct ehca_mr));
spin_lock_init(&me->mrlock);
} else
ehca_gen_err("alloc failed");
@@ -72,9 +71,8 @@ static struct ehca_mw *ehca_mw_new(void)
{
struct ehca_mw *me;
- me = kmem_cache_alloc(mw_cache, GFP_KERNEL);
+ me = kmem_cache_zalloc(mw_cache, GFP_KERNEL);
if (me) {
- memset(me, 0, sizeof(struct ehca_mw));
spin_lock_init(&me->mwlock);
} else
ehca_gen_err("alloc failed");
diff --git a/drivers/infiniband/hw/ehca/ehca_pd.c b/drivers/infiniband/hw/ehca/ehca_pd.c
index d5345e5b3cd6..79d0591a8043 100644
--- a/drivers/infiniband/hw/ehca/ehca_pd.c
+++ b/drivers/infiniband/hw/ehca/ehca_pd.c
@@ -50,14 +50,13 @@ struct ib_pd *ehca_alloc_pd(struct ib_device *device,
{
struct ehca_pd *pd;
- pd = kmem_cache_alloc(pd_cache, GFP_KERNEL);
+ pd = kmem_cache_zalloc(pd_cache, GFP_KERNEL);
if (!pd) {
ehca_err(device, "device=%p context=%p out of memory",
device, context);
return ERR_PTR(-ENOMEM);
}
- memset(pd, 0, sizeof(struct ehca_pd));
pd->ownpid = current->tgid;
/*
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c
index 95efef921f1d..df0516f24379 100644
--- a/drivers/infiniband/hw/ehca/ehca_qp.c
+++ b/drivers/infiniband/hw/ehca/ehca_qp.c
@@ -450,13 +450,12 @@ struct ib_qp *ehca_create_qp(struct ib_pd *pd,
if (pd->uobject && udata)
context = pd->uobject->context;
- my_qp = kmem_cache_alloc(qp_cache, GFP_KERNEL);
+ my_qp = kmem_cache_zalloc(qp_cache, GFP_KERNEL);
if (!my_qp) {
ehca_err(pd->device, "pd=%p not enough memory to alloc qp", pd);
return ERR_PTR(-ENOMEM);
}
- memset(my_qp, 0, sizeof(struct ehca_qp));
memset (&parms, 0, sizeof(struct ehca_alloc_qp_parms));
spin_lock_init(&my_qp->spinlock_s);
spin_lock_init(&my_qp->spinlock_r);
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c
index 28c087b824c2..0f13a2182cc7 100644
--- a/drivers/infiniband/hw/ipath/ipath_diag.c
+++ b/drivers/infiniband/hw/ipath/ipath_diag.c
@@ -59,7 +59,7 @@ static ssize_t ipath_diag_read(struct file *fp, char __user *data,
static ssize_t ipath_diag_write(struct file *fp, const char __user *data,
size_t count, loff_t *off);
-static struct file_operations diag_file_ops = {
+static const struct file_operations diag_file_ops = {
.owner = THIS_MODULE,
.write = ipath_diag_write,
.read = ipath_diag_read,
@@ -71,7 +71,7 @@ static ssize_t ipath_diagpkt_write(struct file *fp,
const char __user *data,
size_t count, loff_t *off);
-static struct file_operations diagpkt_file_ops = {
+static const struct file_operations diagpkt_file_ops = {
.owner = THIS_MODULE,
.write = ipath_diagpkt_write,
};
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index b932bcb67a5e..5d64ff875297 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -54,7 +54,7 @@ static ssize_t ipath_write(struct file *, const char __user *, size_t,
static unsigned int ipath_poll(struct file *, struct poll_table_struct *);
static int ipath_mmap(struct file *, struct vm_area_struct *);
-static struct file_operations ipath_file_ops = {
+static const struct file_operations ipath_file_ops = {
.owner = THIS_MODULE,
.write = ipath_write,
.open = ipath_open,
@@ -2153,7 +2153,7 @@ bail:
static struct class *ipath_class;
-static int init_cdev(int minor, char *name, struct file_operations *fops,
+static int init_cdev(int minor, char *name, const struct file_operations *fops,
struct cdev **cdevp, struct class_device **class_devp)
{
const dev_t dev = MKDEV(IPATH_MAJOR, minor);
@@ -2210,7 +2210,7 @@ done:
return ret;
}
-int ipath_cdev_init(int minor, char *name, struct file_operations *fops,
+int ipath_cdev_init(int minor, char *name, const struct file_operations *fops,
struct cdev **cdevp, struct class_device **class_devp)
{
return init_cdev(minor, name, fops, cdevp, class_devp);
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 79a60f020a21..5b40a846ff95 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -47,7 +47,7 @@
static struct super_block *ipath_super;
static int ipathfs_mknod(struct inode *dir, struct dentry *dentry,
- int mode, struct file_operations *fops,
+ int mode, const struct file_operations *fops,
void *data)
{
int error;
@@ -81,7 +81,7 @@ bail:
static int create_file(const char *name, mode_t mode,
struct dentry *parent, struct dentry **dentry,
- struct file_operations *fops, void *data)
+ const struct file_operations *fops, void *data)
{
int error;
@@ -105,7 +105,7 @@ static ssize_t atomic_stats_read(struct file *file, char __user *buf,
sizeof ipath_stats);
}
-static struct file_operations atomic_stats_ops = {
+static const struct file_operations atomic_stats_ops = {
.read = atomic_stats_read,
};
@@ -127,7 +127,7 @@ static ssize_t atomic_counters_read(struct file *file, char __user *buf,
sizeof counters);
}
-static struct file_operations atomic_counters_ops = {
+static const struct file_operations atomic_counters_ops = {
.read = atomic_counters_read,
};
@@ -166,7 +166,7 @@ static ssize_t atomic_node_info_read(struct file *file, char __user *buf,
sizeof nodeinfo);
}
-static struct file_operations atomic_node_info_ops = {
+static const struct file_operations atomic_node_info_ops = {
.read = atomic_node_info_read,
};
@@ -291,7 +291,7 @@ static ssize_t atomic_port_info_read(struct file *file, char __user *buf,
sizeof portinfo);
}
-static struct file_operations atomic_port_info_ops = {
+static const struct file_operations atomic_port_info_ops = {
.read = atomic_port_info_read,
};
@@ -394,7 +394,7 @@ bail:
return ret;
}
-static struct file_operations flash_ops = {
+static const struct file_operations flash_ops = {
.read = flash_read,
.write = flash_write,
};
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h
index 986b2125b8f5..6d8d05fb5999 100644
--- a/drivers/infiniband/hw/ipath/ipath_kernel.h
+++ b/drivers/infiniband/hw/ipath/ipath_kernel.h
@@ -593,7 +593,7 @@ void ipath_shutdown_device(struct ipath_devdata *);
void ipath_disarm_senderrbufs(struct ipath_devdata *);
struct file_operations;
-int ipath_cdev_init(int minor, char *name, struct file_operations *fops,
+int ipath_cdev_init(int minor, char *name, const struct file_operations *fops,
struct cdev **cdevp, struct class_device **class_devp);
void ipath_cdev_cleanup(struct cdev **cdevp,
struct class_device **class_devp);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
index f1cb83688b31..44c174182a82 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
@@ -146,7 +146,7 @@ static int ipoib_mcg_open(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations ipoib_mcg_fops = {
+static const struct file_operations ipoib_mcg_fops = {
.owner = THIS_MODULE,
.open = ipoib_mcg_open,
.read = seq_read,
@@ -252,7 +252,7 @@ static int ipoib_path_open(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations ipoib_path_fops = {
+static const struct file_operations ipoib_path_fops = {
.owner = THIS_MODULE,
.open = ipoib_path_open,
.read = seq_read,
diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c
index f68dbe6f7f04..7b7a546323cf 100644
--- a/drivers/input/gameport/ns558.c
+++ b/drivers/input/gameport/ns558.c
@@ -151,7 +151,6 @@ static int ns558_isa_probe(int io)
return -ENOMEM;
}
- memset(ns558, 0, sizeof(struct ns558));
ns558->io = io;
ns558->size = 1 << i;
ns558->gameport = port;
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 7cf2b4f603a3..14d4c0493c36 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -482,7 +482,7 @@ static int input_proc_devices_open(struct inode *inode, struct file *file)
return seq_open(file, &input_devices_seq_ops);
}
-static struct file_operations input_devices_fileops = {
+static const struct file_operations input_devices_fileops = {
.owner = THIS_MODULE,
.open = input_proc_devices_open,
.poll = input_proc_devices_poll,
@@ -533,7 +533,7 @@ static int input_proc_handlers_open(struct inode *inode, struct file *file)
return seq_open(file, &input_handlers_seq_ops);
}
-static struct file_operations input_handlers_fileops = {
+static const struct file_operations input_handlers_fileops = {
.owner = THIS_MODULE,
.open = input_proc_handlers_open,
.read = seq_read,
@@ -1142,7 +1142,7 @@ static int input_open_file(struct inode *inode, struct file *file)
return err;
}
-static struct file_operations input_fops = {
+static const struct file_operations input_fops = {
.owner = THIS_MODULE,
.open = input_open_file,
};
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 049f2f544e75..1b81a72e19d9 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -135,12 +135,12 @@ config KEYBOARD_STOWAWAY
config KEYBOARD_CORGI
tristate "Corgi keyboard"
depends on PXA_SHARPSL
- default y
+ default y
help
- Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
+ Say Y here to enable the keyboard on the Sharp Zaurus SL-C7xx
series of PDAs.
- To compile this driver as a module, choose M here: the
+ To compile this driver as a module, choose M here: the
module will be called corgikbd.
config KEYBOARD_SPITZ
@@ -214,4 +214,17 @@ config KEYBOARD_AAED2000
To compile this driver as a module, choose M here: the
module will be called aaed2000_kbd.
+config KEYBOARD_GPIO
+ tristate "Buttons on CPU GPIOs (PXA)"
+ depends on ARCH_PXA
+ help
+ This driver implements support for buttons connected
+ directly to GPIO pins of PXA CPUs.
+
+ Say Y here if your device has buttons connected
+ directly to GPIO pins of the CPU.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gpio-keys.
+
endif
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 568797907347..586a0fe53be6 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
-obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
-obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
+obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
+obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
+obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
new file mode 100644
index 000000000000..3a8f1b427a7f
--- /dev/null
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -0,0 +1,147 @@
+/*
+ * Driver for keys on GPIO lines capable of generating interrupts.
+ *
+ * Copyright 2005 Phil Blundell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/hardware.h>
+
+#include <asm/hardware/gpio_keys.h>
+
+static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
+{
+ int i;
+ struct platform_device *pdev = dev_id;
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ struct input_dev *input = platform_get_drvdata(pdev);
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ int gpio = pdata->buttons[i].gpio;
+ if (irq == IRQ_GPIO(gpio)) {
+ int state = ((GPLR(gpio) & GPIO_bit(gpio)) ? 1 : 0) ^ (pdata->buttons[i].active_low);
+
+ input_report_key(input, pdata->buttons[i].keycode, state);
+ input_sync(input);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit gpio_keys_probe(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ struct input_dev *input;
+ int i, error;
+
+ input = input_allocate_device();
+ if (!input)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, input);
+
+ input->evbit[0] = BIT(EV_KEY);
+
+ input->name = pdev->name;
+ input->phys = "gpio-keys/input0";
+ input->cdev.dev = &pdev->dev;
+ input->private = pdata;
+
+ input->id.bustype = BUS_HOST;
+ input->id.vendor = 0x0001;
+ input->id.product = 0x0001;
+ input->id.version = 0x0100;
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ int code = pdata->buttons[i].keycode;
+ int irq = IRQ_GPIO(pdata->buttons[i].gpio);
+
+ set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
+ error = request_irq(irq, gpio_keys_isr, SA_SAMPLE_RANDOM,
+ pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys",
+ pdev);
+ if (error) {
+ printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", irq, ret);
+ goto fail;
+ }
+ set_bit(code, input->keybit);
+ }
+
+ error = input_register_device(input);
+ if (error) {
+ printk(KERN_ERR "Unable to register gpio-keys input device\n");
+ goto fail;
+ }
+
+ return 0;
+
+ fail:
+ for (i = i - 1; i >= 0; i--)
+ free_irq(IRQ_GPIO(pdata->buttons[i].gpio), pdev);
+
+ input_free_device(input);
+
+ return error;
+}
+
+static int __devexit gpio_keys_remove(struct platform_device *pdev)
+{
+ struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
+ struct input_dev *input = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < pdata->nbuttons; i++) {
+ int irq = IRQ_GPIO(pdata->buttons[i].gpio);
+ free_irq(irq, pdev);
+ }
+
+ input_unregister_device(input);
+
+ return 0;
+}
+
+struct platform_driver gpio_keys_device_driver = {
+ .probe = gpio_keys_probe,
+ .remove = __devexit_p(gpio_keys_remove),
+ .driver = {
+ .name = "gpio-keys",
+ }
+};
+
+static int __init gpio_keys_init(void)
+{
+ return platform_driver_register(&gpio_keys_device_driver);
+}
+
+static void __exit gpio_keys_exit(void)
+{
+ platform_driver_unregister(&gpio_keys_device_driver);
+}
+
+module_init(gpio_keys_init);
+module_exit(gpio_keys_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>");
+MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index 35461eab2faf..255a6ec75a48 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -6,10 +6,10 @@
* Copyright (C) 1999-2006 Helge Deller <deller@gmx.de>
*
* Very basic HP Human Interface Loop (HIL) driver.
- * This driver handles the keyboard on HP300 (m68k) and on some
+ * This driver handles the keyboard on HP300 (m68k) and on some
* HP700 (parisc) series machines.
*
- *
+ *
* This file is subject to the terms and conditions of the GNU General Public
* License version 2. See the file COPYING in the main directory of this
* archive for more details.
@@ -64,9 +64,9 @@ MODULE_LICENSE("GPL v2");
#endif
-
+
/* HIL helper functions */
-
+
#define hil_busy() (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY)
#define hil_data_available() (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY)
#define hil_status() (hil_readb(HILBASE + HIL_CMD))
@@ -75,7 +75,7 @@ MODULE_LICENSE("GPL v2");
#define hil_write_data(x) do { hil_writeb((x), HILBASE + HIL_DATA); } while (0)
/* HIL constants */
-
+
#define HIL_BUSY 0x02
#define HIL_DATA_RDY 0x01
@@ -86,10 +86,10 @@ MODULE_LICENSE("GPL v2");
#define HIL_INTON 0x5C /* Turn on interrupts. */
#define HIL_INTOFF 0x5D /* Turn off interrupts. */
-#define HIL_READKBDSADR 0xF9
-#define HIL_WRITEKBDSADR 0xE9
+#define HIL_READKBDSADR 0xF9
+#define HIL_WRITEKBDSADR 0xE9
-static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] =
+static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] =
{ HIL_KEYCODES_SET1 };
/* HIL structure */
@@ -97,11 +97,11 @@ static struct {
struct input_dev *dev;
unsigned int curdev;
-
+
unsigned char s;
unsigned char c;
int valid;
-
+
unsigned char data[16];
unsigned int ptr;
spinlock_t lock;
@@ -115,7 +115,7 @@ static void poll_finished(void)
int down;
int key;
unsigned char scode;
-
+
switch (hil_dev.data[0]) {
case 0x40:
down = (hil_dev.data[1] & 1) == 0;
@@ -127,6 +127,7 @@ static void poll_finished(void)
hil_dev.curdev = 0;
}
+
static inline void handle_status(unsigned char s, unsigned char c)
{
if (c & 0x8) {
@@ -143,6 +144,7 @@ static inline void handle_status(unsigned char s, unsigned char c)
}
}
+
static inline void handle_data(unsigned char s, unsigned char c)
{
if (hil_dev.curdev) {
@@ -152,13 +154,11 @@ static inline void handle_data(unsigned char s, unsigned char c)
}
-/*
- * Handle HIL interrupts.
- */
+/* handle HIL interrupts */
static irqreturn_t hil_interrupt(int irq, void *handle)
{
unsigned char s, c;
-
+
s = hil_status();
c = hil_read_data();
@@ -179,10 +179,8 @@ static irqreturn_t hil_interrupt(int irq, void *handle)
return IRQ_HANDLED;
}
-/*
- * Send a command to the HIL
- */
+/* send a command to the HIL */
static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
{
unsigned long flags;
@@ -200,16 +198,14 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
}
-/*
- * Initialise HIL.
- */
-
+/* initialise HIL */
static int __init
hil_keyb_init(void)
{
unsigned char c;
unsigned int i, kbid;
wait_queue_head_t hil_wait;
+ int err;
if (hil_dev.dev) {
return -ENODEV; /* already initialized */
@@ -219,15 +215,25 @@ hil_keyb_init(void)
if (!hil_dev.dev)
return -ENOMEM;
hil_dev.dev->private = &hil_dev;
-
+
#if defined(CONFIG_HP300)
- if (!hwreg_present((void *)(HILBASE + HIL_DATA)))
- return -ENODEV;
-
- request_region(HILBASE+HIL_DATA, 2, "hil");
+ if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
+ printk(KERN_ERR "HIL: hardware register was not found\n");
+ err = -ENODEV;
+ goto err1;
+ }
+ if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
+ printk(KERN_ERR "HIL: IOPORT region already used\n");
+ err = -EIO;
+ goto err1;
+ }
#endif
-
- request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
+
+ err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
+ if (err) {
+ printk(KERN_ERR "HIL: Can't get IRQ\n");
+ goto err2;
+ }
/* Turn on interrupts */
hil_do(HIL_INTON, NULL, 0);
@@ -239,47 +245,63 @@ hil_keyb_init(void)
init_waitqueue_head(&hil_wait);
wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ);
if (!hil_dev.valid) {
- printk(KERN_WARNING "HIL: timed out, assuming no keyboard present.\n");
+ printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n");
}
- c = hil_dev.c;
+ c = hil_dev.c;
hil_dev.valid = 0;
if (c == 0) {
kbid = -1;
- printk(KERN_WARNING "HIL: no keyboard present.\n");
+ printk(KERN_WARNING "HIL: no keyboard present\n");
} else {
kbid = ffz(~c);
- /* printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid); */
+ printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid);
}
/* set it to raw mode */
c = 0;
hil_do(HIL_WRITEKBDSADR, &c, 1);
-
+
for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
if (hphilkeyb_keycode[i] != KEY_RESERVED)
set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
- hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
- hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
- hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
- hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]);
- hil_dev.dev->keycode = hphilkeyb_keycode;
- hil_dev.dev->name = "HIL keyboard";
- hil_dev.dev->phys = "hpkbd/input0";
+ hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+ hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
+ hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]);
+ hil_dev.dev->keycode = hphilkeyb_keycode;
+ hil_dev.dev->name = "HIL keyboard";
+ hil_dev.dev->phys = "hpkbd/input0";
hil_dev.dev->id.bustype = BUS_HIL;
hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP;
hil_dev.dev->id.product = 0x0001;
hil_dev.dev->id.version = 0x0010;
- input_register_device(hil_dev.dev);
+ err = input_register_device(hil_dev.dev);
+ if (err) {
+ printk(KERN_ERR "HIL: Can't register device\n");
+ goto err3;
+ }
printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
- hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
+ hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
return 0;
+
+err3:
+ hil_do(HIL_INTOFF, NULL, 0);
+ disable_irq(HIL_IRQ);
+ free_irq(HIL_IRQ, hil_dev.dev_id);
+err2:
+ release_region(HILBASE + HIL_DATA, 2);
+err1:
+ input_free_device(hil_dev.dev);
+ hil_dev.dev = NULL;
+ return err;
}
+
#if defined(CONFIG_PARISC)
static int __init
hil_init_chip(struct parisc_device *dev)
@@ -292,7 +314,7 @@ hil_init_chip(struct parisc_device *dev)
hil_base = dev->hpa.start;
hil_irq = dev->irq;
hil_dev.dev_id = dev;
-
+
printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq);
return hil_keyb_init();
@@ -313,9 +335,6 @@ static struct parisc_driver hil_driver = {
#endif /* CONFIG_PARISC */
-
-
-
static int __init hil_init(void)
{
#if defined(CONFIG_PARISC)
@@ -349,4 +368,3 @@ static void __exit hil_exit(void)
module_init(hil_init);
module_exit(hil_exit);
-
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index ba0e88c64e1e..41b42587f5e9 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -50,6 +50,16 @@ config INPUT_WISTRON_BTNS
To compile this driver as a module, choose M here: the module will
be called wistron_btns.
+config INPUT_ATLAS_BTNS
+ tristate "x86 Atlas button interface"
+ depends on X86 && ACPI
+ help
+ Say Y here for support of Atlas wallmount touchscreen buttons.
+ The events will show up as scancodes F1 through F9 via evdev.
+
+ To compile this driver as a module, choose M here: the module will
+ be called atlas_btns.
+
config INPUT_IXP4XX_BEEPER
tristate "IXP4XX Beeper support"
depends on ARCH_IXP4XX
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 415c49178985..e0a8d58c9e9b 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -9,5 +9,6 @@ obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o
+obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
new file mode 100644
index 000000000000..0acc3a123604
--- /dev/null
+++ b/drivers/input/misc/atlas_btns.c
@@ -0,0 +1,170 @@
+/*
+ * atlas_btns.c - Atlas Wallmount Touchscreen ACPI Extras
+ *
+ * Copyright (C) 2006 Jaya Kumar
+ * Based on Toshiba ACPI by John Belmonte and ASUS ACPI
+ * This work was sponsored by CIS(M) Sdn Bhd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <acpi/acpi_drivers.h>
+
+#define ACPI_ATLAS_NAME "Atlas ACPI"
+#define ACPI_ATLAS_CLASS "Atlas"
+#define ACPI_ATLAS_BUTTON_HID "ASIM0000"
+
+static struct input_dev *input_dev;
+
+/* button handling code */
+static acpi_status acpi_atlas_button_setup(acpi_handle region_handle,
+ u32 function, void *handler_context, void **return_context)
+{
+ *return_context =
+ (function != ACPI_REGION_DEACTIVATE) ? handler_context : NULL;
+
+ return AE_OK;
+}
+
+static acpi_status acpi_atlas_button_handler(u32 function,
+ acpi_physical_address address,
+ u32 bit_width, acpi_integer *value,
+ void *handler_context, void *region_context)
+{
+ acpi_status status;
+ int keycode;
+
+ if (function == ACPI_WRITE) {
+ keycode = KEY_F1 + (address & 0x0F);
+ input_report_key(input_dev, keycode, !(address & 0x10));
+ input_sync(input_dev);
+ status = 0;
+ } else {
+ printk(KERN_WARNING "atlas: shrugged on unexpected function"
+ ":function=%x,address=%lx,value=%x\n",
+ function, (unsigned long)address, (u32)*value);
+ status = -EINVAL;
+ }
+
+ return status;
+}
+
+static int atlas_acpi_button_add(struct acpi_device *device)
+{
+ acpi_status status;
+ int err;
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ printk(KERN_ERR "atlas: unable to allocate input device\n");
+ return -ENOMEM;
+ }
+
+ input_dev->name = "Atlas ACPI button driver";
+ input_dev->phys = "ASIM0000/atlas/input0";
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
+
+ set_bit(KEY_F1, input_dev->keybit);
+ set_bit(KEY_F2, input_dev->keybit);
+ set_bit(KEY_F3, input_dev->keybit);
+ set_bit(KEY_F4, input_dev->keybit);
+ set_bit(KEY_F5, input_dev->keybit);
+ set_bit(KEY_F6, input_dev->keybit);
+ set_bit(KEY_F7, input_dev->keybit);
+ set_bit(KEY_F8, input_dev->keybit);
+ set_bit(KEY_F9, input_dev->keybit);
+
+ err = input_register_device(input_dev);
+ if (err) {
+ printk(KERN_ERR "atlas: couldn't register input device\n");
+ input_free_device(input_dev);
+ return err;
+ }
+
+ /* hookup button handler */
+ status = acpi_install_address_space_handler(device->handle,
+ 0x81, &acpi_atlas_button_handler,
+ &acpi_atlas_button_setup, device);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR "Atlas: Error installing addr spc handler\n");
+ input_unregister_device(input_dev);
+ status = -EINVAL;
+ }
+
+ return status;
+}
+
+static int atlas_acpi_button_remove(struct acpi_device *device, int type)
+{
+ acpi_status status;
+
+ status = acpi_remove_address_space_handler(device->handle,
+ 0x81, &acpi_atlas_button_handler);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR "Atlas: Error removing addr spc handler\n");
+ status = -EINVAL;
+ }
+
+ input_unregister_device(input_dev);
+
+ return status;
+}
+
+static struct acpi_driver atlas_acpi_driver = {
+ .name = ACPI_ATLAS_NAME,
+ .class = ACPI_ATLAS_CLASS,
+ .ids = ACPI_ATLAS_BUTTON_HID,
+ .ops = {
+ .add = atlas_acpi_button_add,
+ .remove = atlas_acpi_button_remove,
+ },
+};
+
+static int __init atlas_acpi_init(void)
+{
+ int result;
+
+ if (acpi_disabled)
+ return -ENODEV;
+
+ result = acpi_bus_register_driver(&atlas_acpi_driver);
+ if (result < 0) {
+ printk(KERN_ERR "Atlas ACPI: Unable to register driver\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void __exit atlas_acpi_exit(void)
+{
+ acpi_bus_unregister_driver(&atlas_acpi_driver);
+}
+
+module_init(atlas_acpi_init);
+module_exit(atlas_acpi_exit);
+
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Atlas button driver");
+
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index 31d5a13bfd6b..ab76ea442fa5 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -670,7 +670,7 @@ static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file,
#endif
}
-static struct file_operations hp_sdc_rtc_fops = {
+static const struct file_operations hp_sdc_rtc_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = hp_sdc_rtc_read,
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 9516439b7c78..42556232c523 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -627,7 +627,7 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return retval;
}
-static struct file_operations uinput_fops = {
+static const struct file_operations uinput_fops = {
.owner = THIS_MODULE,
.open = uinput_open,
.release = uinput_release,
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 7b9d1c1da41a..e1183aeb8ed5 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -335,6 +335,17 @@ static struct key_entry keymap_aopen_1559as[] = {
{ KE_END, 0 },
};
+static struct key_entry keymap_fs_amilo_d88x0[] = {
+ { KE_KEY, 0x01, KEY_HELP },
+ { KE_KEY, 0x08, KEY_MUTE },
+ { KE_KEY, 0x31, KEY_MAIL },
+ { KE_KEY, 0x36, KEY_WWW },
+ { KE_KEY, 0x11, KEY_PROG1 },
+ { KE_KEY, 0x12, KEY_PROG2 },
+ { KE_KEY, 0x13, KEY_PROG3 },
+ { KE_END, 0 }
+};
+
/*
* If your machine is not here (which is currently rather likely), please send
* a list of buttons and their key codes (reported when loading this module
@@ -413,6 +424,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
},
.driver_data = keymap_wistron_ms2111
},
+ {
+ .callback = dmi_matched,
+ .ident = "Fujitsu Siemens Amilo D88x0",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO D"),
+ },
+ .driver_data = keymap_fs_amilo_d88x0
+ },
{ NULL, }
};
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
index 13dd96785e39..701ebd5473cf 100644
--- a/drivers/input/mouse/inport.c
+++ b/drivers/input/mouse/inport.c
@@ -61,7 +61,7 @@ MODULE_LICENSE("GPL");
#define INPORT_REG_MODE 0x07
#define INPORT_RESET 0x80
-#ifdef CONFIG_INPUT_ATIXL
+#ifdef CONFIG_MOUSE_ATIXL
#define INPORT_NAME "ATI XL Mouse"
#define INPORT_VENDOR 0x0002
#define INPORT_SPEED_30HZ 0x01
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
index f155c1fea04e..05d992e514f0 100644
--- a/drivers/input/mouse/pc110pad.c
+++ b/drivers/input/mouse/pc110pad.c
@@ -113,7 +113,7 @@ static int __init pc110pad_init(void)
dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
if (dev) {
pci_dev_put(dev);
- return -ENOENT;
+ return -ENODEV;
}
if (!request_region(pc110pad_io, 4, "pc110pad")) {
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index debe9445488c..c3fdfc1f342a 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -371,7 +371,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
if (unlikely(i8042_suppress_kbd_ack))
if (port_no == I8042_KBD_PORT_NO &&
(data == 0xfa || data == 0xfe)) {
- i8042_suppress_kbd_ack = 0;
+ i8042_suppress_kbd_ack--;
goto out;
}
@@ -543,6 +543,7 @@ static int __devinit i8042_check_aux(void)
{
int retval = -1;
int irq_registered = 0;
+ int aux_loop_broken = 0;
unsigned long flags;
unsigned char param;
@@ -572,6 +573,8 @@ static int __devinit i8042_check_aux(void)
if (i8042_command(&param, I8042_CMD_AUX_TEST) ||
(param && param != 0xfa && param != 0xff))
return -1;
+
+ aux_loop_broken = 1;
}
/*
@@ -595,7 +598,7 @@ static int __devinit i8042_check_aux(void)
* used it for a PCI card or somethig else.
*/
- if (i8042_noloop) {
+ if (i8042_noloop || aux_loop_broken) {
/*
* Without LOOP command we can't test AUX IRQ delivery. Assume the port
* is working and hope we are right.
@@ -838,13 +841,14 @@ static long i8042_panic_blink(long count)
led ^= 0x01 | 0x04;
while (i8042_read_status() & I8042_STR_IBF)
DELAY;
- i8042_suppress_kbd_ack = 1;
+ dbg("%02x -> i8042 (panic blink)", 0xed);
+ i8042_suppress_kbd_ack = 2;
i8042_write_data(0xed); /* set leds */
DELAY;
while (i8042_read_status() & I8042_STR_IBF)
DELAY;
DELAY;
- i8042_suppress_kbd_ack = 1;
+ dbg("%02x -> i8042 (panic blink)", led);
i8042_write_data(led);
DELAY;
last_blink = count;
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index 088ebc348ba3..887357666c68 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -234,7 +234,7 @@ static unsigned int serio_raw_poll(struct file *file, poll_table *wait)
return 0;
}
-static struct file_operations serio_raw_fops = {
+static const struct file_operations serio_raw_fops = {
.owner = THIS_MODULE,
.open = serio_raw_open,
.release = serio_raw_release,
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 6b46c9bf1d20..971618059a6f 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -12,13 +12,18 @@ menuconfig INPUT_TOUCHSCREEN
if INPUT_TOUCHSCREEN
config TOUCHSCREEN_ADS7846
- tristate "ADS 7846 based touchscreens"
+ tristate "ADS 7846/7843 based touchscreens"
depends on SPI_MASTER
+ depends on HWMON = n || HWMON
help
Say Y here if you have a touchscreen interface using the
- ADS7846 controller, and your board-specific initialization
+ ADS7846 or ADS7843 controller, and your board-specific setup
code includes that in its table of SPI devices.
+ If HWMON is selected, and the driver is told the reference voltage
+ on your board, you will also get hwmon interfaces for the voltage
+ (and on ads7846, temperature) sensors of this chip.
+
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index c6164b6f476a..cd251efda410 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -17,8 +17,9 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/device.h>
+#include <linux/hwmon.h>
#include <linux/init.h>
+#include <linux/err.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/interrupt.h>
@@ -54,7 +55,8 @@
* files.
*/
-#define TS_POLL_PERIOD msecs_to_jiffies(10)
+#define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */
+#define TS_POLL_PERIOD (5 * 1000000) /* ns delay between samples */
/* this driver doesn't aim at the peak continuous sample rate */
#define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
@@ -63,12 +65,12 @@ struct ts_event {
/* For portability, we can't read 12 bit values using SPI (which
* would make the controller deliver them as native byteorder u16
* with msbs zeroed). Instead, we read them as two 8-bit values,
- * which need byteswapping then range adjustment.
+ * *** WHICH NEED BYTESWAPPING *** and range adjustment.
*/
- __be16 x;
- __be16 y;
- __be16 z1, z2;
- int ignore;
+ u16 x;
+ u16 y;
+ u16 z1, z2;
+ int ignore;
};
struct ads7846 {
@@ -76,7 +78,12 @@ struct ads7846 {
char phys[32];
struct spi_device *spi;
+
+#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
struct attribute_group *attr_group;
+ struct class_device *hwmon;
+#endif
+
u16 model;
u16 vref_delay_usecs;
u16 x_plate_ohms;
@@ -99,13 +106,16 @@ struct ads7846 {
u16 debounce_rep;
spinlock_t lock;
- struct timer_list timer; /* P: lock */
+ struct hrtimer timer;
unsigned pendown:1; /* P: lock */
unsigned pending:1; /* P: lock */
// FIXME remove "irq_disabled"
unsigned irq_disabled:1; /* P: lock */
unsigned disabled:1;
+ int (*filter)(void *data, int data_idx, int *val);
+ void *filter_data;
+ void (*filter_cleanup)(void *data);
int (*get_pendown_state)(void);
};
@@ -142,15 +152,16 @@ struct ads7846 {
#define MAX_12BIT ((1<<12)-1)
/* leave ADC powered up (disables penirq) between differential samples */
-#define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \
- | ADS_12_BIT | ADS_DFR)
+#define READ_12BIT_DFR(x, adc, vref) (ADS_START | ADS_A2A1A0_d_ ## x \
+ | ADS_12_BIT | ADS_DFR | \
+ (adc ? ADS_PD10_ADC_ON : 0) | (vref ? ADS_PD10_REF_ON : 0))
-#define READ_Y (READ_12BIT_DFR(y) | ADS_PD10_ADC_ON)
-#define READ_Z1 (READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON)
-#define READ_Z2 (READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON)
+#define READ_Y(vref) (READ_12BIT_DFR(y, 1, vref))
+#define READ_Z1(vref) (READ_12BIT_DFR(z1, 1, vref))
+#define READ_Z2(vref) (READ_12BIT_DFR(z2, 1, vref))
-#define READ_X (READ_12BIT_DFR(x) | ADS_PD10_ADC_ON)
-#define PWRDOWN (READ_12BIT_DFR(y) | ADS_PD10_PDOWN) /* LAST */
+#define READ_X(vref) (READ_12BIT_DFR(x, 1, vref))
+#define PWRDOWN (READ_12BIT_DFR(y, 0, 0)) /* LAST */
/* single-ended samples need to first power up reference voltage;
* we leave both ADC and VREF powered
@@ -158,14 +169,19 @@ struct ads7846 {
#define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
| ADS_12_BIT | ADS_SER)
-#define REF_ON (READ_12BIT_DFR(x) | ADS_PD10_ALL_ON)
-#define REF_OFF (READ_12BIT_DFR(y) | ADS_PD10_PDOWN)
+#define REF_ON (READ_12BIT_DFR(x, 1, 1))
+#define REF_OFF (READ_12BIT_DFR(y, 0, 0))
/*--------------------------------------------------------------------------*/
/*
* Non-touchscreen sensors only use single-ended conversions.
+ * The range is GND..vREF. The ads7843 and ads7835 must use external vREF;
+ * ads7846 lets that pin be unconnected, to use internal vREF.
*/
+static unsigned vREF_mV;
+module_param(vREF_mV, uint, 0);
+MODULE_PARM_DESC(vREF_mV, "external vREF voltage, in milliVolts");
struct ser_req {
u8 ref_on;
@@ -193,50 +209,55 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL);
int status;
int sample;
- int i;
+ int use_internal;
if (!req)
return -ENOMEM;
spi_message_init(&req->msg);
- /* activate reference, so it has time to settle; */
- req->ref_on = REF_ON;
- req->xfer[0].tx_buf = &req->ref_on;
- req->xfer[0].len = 1;
- req->xfer[1].rx_buf = &req->scratch;
- req->xfer[1].len = 2;
-
- /*
- * for external VREF, 0 usec (and assume it's always on);
- * for 1uF, use 800 usec;
- * no cap, 100 usec.
- */
- req->xfer[1].delay_usecs = ts->vref_delay_usecs;
+ /* FIXME boards with ads7846 might use external vref instead ... */
+ use_internal = (ts->model == 7846);
+
+ /* maybe turn on internal vREF, and let it settle */
+ if (use_internal) {
+ req->ref_on = REF_ON;
+ req->xfer[0].tx_buf = &req->ref_on;
+ req->xfer[0].len = 1;
+ spi_message_add_tail(&req->xfer[0], &req->msg);
+
+ req->xfer[1].rx_buf = &req->scratch;
+ req->xfer[1].len = 2;
+
+ /* for 1uF, settle for 800 usec; no cap, 100 usec. */
+ req->xfer[1].delay_usecs = ts->vref_delay_usecs;
+ spi_message_add_tail(&req->xfer[1], &req->msg);
+ }
/* take sample */
req->command = (u8) command;
req->xfer[2].tx_buf = &req->command;
req->xfer[2].len = 1;
+ spi_message_add_tail(&req->xfer[2], &req->msg);
+
req->xfer[3].rx_buf = &req->sample;
req->xfer[3].len = 2;
+ spi_message_add_tail(&req->xfer[3], &req->msg);
/* REVISIT: take a few more samples, and compare ... */
- /* turn off reference */
- req->ref_off = REF_OFF;
- req->xfer[4].tx_buf = &req->ref_off;
- req->xfer[4].len = 1;
- req->xfer[5].rx_buf = &req->scratch;
- req->xfer[5].len = 2;
-
- CS_CHANGE(req->xfer[5]);
-
- /* group all the transfers together, so we can't interfere with
- * reading touchscreen state; disable penirq while sampling
- */
- for (i = 0; i < 6; i++)
- spi_message_add_tail(&req->xfer[i], &req->msg);
+ /* maybe off internal vREF */
+ if (use_internal) {
+ req->ref_off = REF_OFF;
+ req->xfer[4].tx_buf = &req->ref_off;
+ req->xfer[4].len = 1;
+ spi_message_add_tail(&req->xfer[4], &req->msg);
+
+ req->xfer[5].rx_buf = &req->scratch;
+ req->xfer[5].len = 2;
+ CS_CHANGE(req->xfer[5]);
+ spi_message_add_tail(&req->xfer[5], &req->msg);
+ }
ts->irq_disabled = 1;
disable_irq(spi->irq);
@@ -256,25 +277,173 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
return status ? status : sample;
}
-#define SHOW(name) static ssize_t \
+#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
+
+#define SHOW(name, var, adjust) static ssize_t \
name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
+ struct ads7846 *ts = dev_get_drvdata(dev); \
ssize_t v = ads7846_read12_ser(dev, \
- READ_12BIT_SER(name) | ADS_PD10_ALL_ON); \
+ READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \
if (v < 0) \
return v; \
- return sprintf(buf, "%u\n", (unsigned) v); \
+ return sprintf(buf, "%u\n", adjust(ts, v)); \
} \
static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
-SHOW(temp0)
-SHOW(temp1)
-SHOW(vaux)
-SHOW(vbatt)
+
+/* Sysfs conventions report temperatures in millidegrees Celcius.
+ * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high
+ * accuracy scheme without calibration data. For now we won't try either;
+ * userspace sees raw sensor values, and must scale/calibrate appropriately.
+ */
+static inline unsigned null_adjust(struct ads7846 *ts, ssize_t v)
+{
+ return v;
+}
+
+SHOW(temp0, temp0, null_adjust) /* temp1_input */
+SHOW(temp1, temp1, null_adjust) /* temp2_input */
+
+
+/* sysfs conventions report voltages in millivolts. We can convert voltages
+ * if we know vREF. userspace may need to scale vAUX to match the board's
+ * external resistors; we assume that vBATT only uses the internal ones.
+ */
+static inline unsigned vaux_adjust(struct ads7846 *ts, ssize_t v)
+{
+ unsigned retval = v;
+
+ /* external resistors may scale vAUX into 0..vREF */
+ retval *= vREF_mV;
+ retval = retval >> 12;
+ return retval;
+}
+
+static inline unsigned vbatt_adjust(struct ads7846 *ts, ssize_t v)
+{
+ unsigned retval = vaux_adjust(ts, v);
+
+ /* ads7846 has a resistor ladder to scale this signal down */
+ if (ts->model == 7846)
+ retval *= 4;
+ return retval;
+}
+
+SHOW(in0_input, vaux, vaux_adjust)
+SHOW(in1_input, vbatt, vbatt_adjust)
+
+
+static struct attribute *ads7846_attributes[] = {
+ &dev_attr_temp0.attr,
+ &dev_attr_temp1.attr,
+ &dev_attr_in0_input.attr,
+ &dev_attr_in1_input.attr,
+ NULL,
+};
+
+static struct attribute_group ads7846_attr_group = {
+ .attrs = ads7846_attributes,
+};
+
+static struct attribute *ads7843_attributes[] = {
+ &dev_attr_in0_input.attr,
+ &dev_attr_in1_input.attr,
+ NULL,
+};
+
+static struct attribute_group ads7843_attr_group = {
+ .attrs = ads7843_attributes,
+};
+
+static struct attribute *ads7845_attributes[] = {
+ &dev_attr_in0_input.attr,
+ NULL,
+};
+
+static struct attribute_group ads7845_attr_group = {
+ .attrs = ads7845_attributes,
+};
+
+static int ads784x_hwmon_register(struct spi_device *spi, struct ads7846 *ts)
+{
+ struct class_device *hwmon;
+ int err;
+
+ /* hwmon sensors need a reference voltage */
+ switch (ts->model) {
+ case 7846:
+ if (!vREF_mV) {
+ dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n");
+ vREF_mV = 2500;
+ }
+ break;
+ case 7845:
+ case 7843:
+ if (!vREF_mV) {
+ dev_warn(&spi->dev,
+ "external vREF for ADS%d not specified\n",
+ ts->model);
+ return 0;
+ }
+ break;
+ }
+
+ /* different chips have different sensor groups */
+ switch (ts->model) {
+ case 7846:
+ ts->attr_group = &ads7846_attr_group;
+ break;
+ case 7845:
+ ts->attr_group = &ads7845_attr_group;
+ break;
+ case 7843:
+ ts->attr_group = &ads7843_attr_group;
+ break;
+ default:
+ dev_dbg(&spi->dev, "ADS%d not recognized\n", ts->model);
+ return 0;
+ }
+
+ err = sysfs_create_group(&spi->dev.kobj, ts->attr_group);
+ if (err)
+ return err;
+
+ hwmon = hwmon_device_register(&spi->dev);
+ if (IS_ERR(hwmon)) {
+ sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
+ return PTR_ERR(hwmon);
+ }
+
+ ts->hwmon = hwmon;
+ return 0;
+}
+
+static void ads784x_hwmon_unregister(struct spi_device *spi,
+ struct ads7846 *ts)
+{
+ if (ts->hwmon) {
+ sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
+ hwmon_device_unregister(ts->hwmon);
+ }
+}
+
+#else
+static inline int ads784x_hwmon_register(struct spi_device *spi,
+ struct ads7846 *ts)
+{
+ return 0;
+}
+
+static inline void ads784x_hwmon_unregister(struct spi_device *spi,
+ struct ads7846 *ts)
+{
+}
+#endif
static int is_pen_down(struct device *dev)
{
- struct ads7846 *ts = dev_get_drvdata(dev);
+ struct ads7846 *ts = dev_get_drvdata(dev);
return ts->pendown;
}
@@ -318,46 +487,14 @@ static ssize_t ads7846_disable_store(struct device *dev,
static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store);
-static struct attribute *ads7846_attributes[] = {
- &dev_attr_temp0.attr,
- &dev_attr_temp1.attr,
- &dev_attr_vbatt.attr,
- &dev_attr_vaux.attr,
- &dev_attr_pen_down.attr,
- &dev_attr_disable.attr,
- NULL,
-};
-
-static struct attribute_group ads7846_attr_group = {
- .attrs = ads7846_attributes,
-};
-
-/*
- * ads7843/7845 don't have temperature sensors, and
- * use the other sensors a bit differently too
- */
-
-static struct attribute *ads7843_attributes[] = {
- &dev_attr_vbatt.attr,
- &dev_attr_vaux.attr,
+static struct attribute *ads784x_attributes[] = {
&dev_attr_pen_down.attr,
&dev_attr_disable.attr,
NULL,
};
-static struct attribute_group ads7843_attr_group = {
- .attrs = ads7843_attributes,
-};
-
-static struct attribute *ads7845_attributes[] = {
- &dev_attr_vaux.attr,
- &dev_attr_pen_down.attr,
- &dev_attr_disable.attr,
- NULL,
-};
-
-static struct attribute_group ads7845_attr_group = {
- .attrs = ads7845_attributes,
+static struct attribute_group ads784x_attr_group = {
+ .attrs = ads784x_attributes,
};
/*--------------------------------------------------------------------------*/
@@ -373,25 +510,22 @@ static struct attribute_group ads7845_attr_group = {
static void ads7846_rx(void *ads)
{
struct ads7846 *ts = ads;
- struct input_dev *input_dev = ts->input;
unsigned Rt;
- unsigned sync = 0;
u16 x, y, z1, z2;
- unsigned long flags;
- /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding;
- * built from two 8 bit values written msb-first.
+ /* ads7846_rx_val() did in-place conversion (including byteswap) from
+ * on-the-wire format as part of debouncing to get stable readings.
*/
- x = (be16_to_cpu(ts->tc.x) >> 3) & 0x0fff;
- y = (be16_to_cpu(ts->tc.y) >> 3) & 0x0fff;
- z1 = (be16_to_cpu(ts->tc.z1) >> 3) & 0x0fff;
- z2 = (be16_to_cpu(ts->tc.z2) >> 3) & 0x0fff;
+ x = ts->tc.x;
+ y = ts->tc.y;
+ z1 = ts->tc.z1;
+ z2 = ts->tc.z2;
/* range filtering */
if (x == MAX_12BIT)
x = 0;
- if (likely(x && z1 && !device_suspended(&ts->spi->dev))) {
+ if (likely(x && z1)) {
/* compute touch pressure resistance using equation #2 */
Rt = z2;
Rt -= z1;
@@ -403,100 +537,129 @@ static void ads7846_rx(void *ads)
Rt = 0;
/* Sample found inconsistent by debouncing or pressure is beyond
- * the maximum. Don't report it to user space, repeat at least
- * once more the measurement */
+ * the maximum. Don't report it to user space, repeat at least
+ * once more the measurement
+ */
if (ts->tc.ignore || Rt > ts->pressure_max) {
- mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
+#ifdef VERBOSE
+ pr_debug("%s: ignored %d pressure %d\n",
+ ts->spi->dev.bus_id, ts->tc.ignore, Rt);
+#endif
+ hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
+ HRTIMER_REL);
return;
}
- /* NOTE: "pendown" is inferred from pressure; we don't rely on
- * being able to check nPENIRQ status, or "friendly" trigger modes
- * (both-edges is much better than just-falling or low-level).
+ /* NOTE: We can't rely on the pressure to determine the pen down
+ * state, even this controller has a pressure sensor. The pressure
+ * value can fluctuate for quite a while after lifting the pen and
+ * in some cases may not even settle at the expected value.
*
- * REVISIT: some boards may require reading nPENIRQ; it's
- * needed on 7843. and 7845 reads pressure differently...
- *
- * REVISIT: the touchscreen might not be connected; this code
- * won't notice that, even if nPENIRQ never fires ...
+ * The only safe way to check for the pen up condition is in the
+ * timer by reading the pen signal state (it's a GPIO _and_ IRQ).
*/
- if (!ts->pendown && Rt != 0) {
- input_report_key(input_dev, BTN_TOUCH, 1);
- sync = 1;
- } else if (ts->pendown && Rt == 0) {
- input_report_key(input_dev, BTN_TOUCH, 0);
- sync = 1;
- }
-
if (Rt) {
- input_report_abs(input_dev, ABS_X, x);
- input_report_abs(input_dev, ABS_Y, y);
- sync = 1;
- }
-
- if (sync) {
- input_report_abs(input_dev, ABS_PRESSURE, Rt);
- input_sync(input_dev);
- }
+ struct input_dev *input = ts->input;
-#ifdef VERBOSE
- if (Rt || ts->pendown)
- pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id,
- x, y, Rt, Rt ? "" : " UP");
+ if (!ts->pendown) {
+ input_report_key(input, BTN_TOUCH, 1);
+ ts->pendown = 1;
+#ifdef VERBOSE
+ dev_dbg(&ts->spi->dev, "DOWN\n");
#endif
+ }
+ input_report_abs(input, ABS_X, x);
+ input_report_abs(input, ABS_Y, y);
+ input_report_abs(input, ABS_PRESSURE, Rt);
- spin_lock_irqsave(&ts->lock, flags);
-
- ts->pendown = (Rt != 0);
- mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD);
+ input_sync(input);
+#ifdef VERBOSE
+ dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt);
+#endif
+ }
- spin_unlock_irqrestore(&ts->lock, flags);
+ hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_REL);
}
-static void ads7846_debounce(void *ads)
+static int ads7846_debounce(void *ads, int data_idx, int *val)
{
struct ads7846 *ts = ads;
- struct spi_message *m;
- struct spi_transfer *t;
- int val;
- int status;
- m = &ts->msg[ts->msg_idx];
- t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
- val = (be16_to_cpu(*(__be16 *)t->rx_buf) >> 3) & 0x0fff;
- if (!ts->read_cnt || (abs(ts->last_read - val) > ts->debounce_tol)) {
+ if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) {
+ /* Start over collecting consistent readings. */
+ ts->read_rep = 0;
/* Repeat it, if this was the first read or the read
* wasn't consistent enough. */
if (ts->read_cnt < ts->debounce_max) {
- ts->last_read = val;
+ ts->last_read = *val;
ts->read_cnt++;
+ return ADS7846_FILTER_REPEAT;
} else {
/* Maximum number of debouncing reached and still
* not enough number of consistent readings. Abort
* the whole sample, repeat it in the next sampling
* period.
*/
- ts->tc.ignore = 1;
ts->read_cnt = 0;
- /* Last message will contain ads7846_rx() as the
- * completion function.
- */
- m = ts->last_msg;
+ return ADS7846_FILTER_IGNORE;
}
- /* Start over collecting consistent readings. */
- ts->read_rep = 0;
} else {
if (++ts->read_rep > ts->debounce_rep) {
/* Got a good reading for this coordinate,
* go for the next one. */
- ts->tc.ignore = 0;
- ts->msg_idx++;
ts->read_cnt = 0;
ts->read_rep = 0;
- m++;
- } else
+ return ADS7846_FILTER_OK;
+ } else {
/* Read more values that are consistent. */
ts->read_cnt++;
+ return ADS7846_FILTER_REPEAT;
+ }
+ }
+}
+
+static int ads7846_no_filter(void *ads, int data_idx, int *val)
+{
+ return ADS7846_FILTER_OK;
+}
+
+static void ads7846_rx_val(void *ads)
+{
+ struct ads7846 *ts = ads;
+ struct spi_message *m;
+ struct spi_transfer *t;
+ u16 *rx_val;
+ int val;
+ int action;
+ int status;
+
+ m = &ts->msg[ts->msg_idx];
+ t = list_entry(m->transfers.prev, struct spi_transfer, transfer_list);
+ rx_val = t->rx_buf;
+
+ /* adjust: on-wire is a must-ignore bit, a BE12 value, then padding;
+ * built from two 8 bit values written msb-first.
+ */
+ val = be16_to_cpu(*rx_val) >> 3;
+
+ action = ts->filter(ts->filter_data, ts->msg_idx, &val);
+ switch (action) {
+ case ADS7846_FILTER_REPEAT:
+ break;
+ case ADS7846_FILTER_IGNORE:
+ ts->tc.ignore = 1;
+ /* Last message will contain ads7846_rx() as the
+ * completion function.
+ */
+ m = ts->last_msg;
+ break;
+ case ADS7846_FILTER_OK:
+ *rx_val = val;
+ ts->tc.ignore = 0;
+ m = &ts->msg[++ts->msg_idx];
+ break;
+ default:
+ BUG();
}
status = spi_async(ts->spi, m);
if (status)
@@ -504,21 +667,34 @@ static void ads7846_debounce(void *ads)
status);
}
-static void ads7846_timer(unsigned long handle)
+static int ads7846_timer(struct hrtimer *handle)
{
- struct ads7846 *ts = (void *)handle;
+ struct ads7846 *ts = container_of(handle, struct ads7846, timer);
int status = 0;
spin_lock_irq(&ts->lock);
- if (unlikely(ts->msg_idx && !ts->pendown)) {
+ if (unlikely(!ts->get_pendown_state() ||
+ device_suspended(&ts->spi->dev))) {
+ if (ts->pendown) {
+ struct input_dev *input = ts->input;
+
+ input_report_key(input, BTN_TOUCH, 0);
+ input_report_abs(input, ABS_PRESSURE, 0);
+ input_sync(input);
+
+ ts->pendown = 0;
+#ifdef VERBOSE
+ dev_dbg(&ts->spi->dev, "UP\n");
+#endif
+ }
+
/* measurement cycle ended */
if (!device_suspended(&ts->spi->dev)) {
ts->irq_disabled = 0;
enable_irq(ts->spi->irq);
}
ts->pending = 0;
- ts->msg_idx = 0;
} else {
/* pen is still down, continue with the measurement */
ts->msg_idx = 0;
@@ -528,6 +704,7 @@ static void ads7846_timer(unsigned long handle)
}
spin_unlock_irq(&ts->lock);
+ return HRTIMER_NORESTART;
}
static irqreturn_t ads7846_irq(int irq, void *handle)
@@ -546,7 +723,8 @@ static irqreturn_t ads7846_irq(int irq, void *handle)
ts->irq_disabled = 1;
disable_irq(ts->spi->irq);
ts->pending = 1;
- mod_timer(&ts->timer, jiffies);
+ hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY),
+ HRTIMER_REL);
}
}
spin_unlock_irqrestore(&ts->lock, flags);
@@ -632,6 +810,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
struct ads7846_platform_data *pdata = spi->dev.platform_data;
struct spi_message *m;
struct spi_transfer *x;
+ int vref;
int err;
if (!spi->irq) {
@@ -665,6 +844,10 @@ static int __devinit ads7846_probe(struct spi_device *spi)
* may not. So we stick to very-portable 8 bit words, both RX and TX.
*/
spi->bits_per_word = 8;
+ spi->mode = SPI_MODE_1;
+ err = spi_setup(spi);
+ if (err < 0)
+ return err;
ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
input_dev = input_allocate_device();
@@ -679,8 +862,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
ts->spi = spi;
ts->input = input_dev;
- init_timer(&ts->timer);
- ts->timer.data = (unsigned long) ts;
+ hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_REL);
ts->timer.function = ads7846_timer;
spin_lock_init(&ts->lock);
@@ -689,14 +871,25 @@ static int __devinit ads7846_probe(struct spi_device *spi)
ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100;
ts->x_plate_ohms = pdata->x_plate_ohms ? : 400;
ts->pressure_max = pdata->pressure_max ? : ~0;
- if (pdata->debounce_max) {
+
+ if (pdata->filter != NULL) {
+ if (pdata->filter_init != NULL) {
+ err = pdata->filter_init(pdata, &ts->filter_data);
+ if (err < 0)
+ goto err_free_mem;
+ }
+ ts->filter = pdata->filter;
+ ts->filter_cleanup = pdata->filter_cleanup;
+ } else if (pdata->debounce_max) {
ts->debounce_max = pdata->debounce_max;
+ if (ts->debounce_max < 2)
+ ts->debounce_max = 2;
ts->debounce_tol = pdata->debounce_tol;
ts->debounce_rep = pdata->debounce_rep;
- if (ts->debounce_rep > ts->debounce_max + 1)
- ts->debounce_rep = ts->debounce_max - 1;
+ ts->filter = ads7846_debounce;
+ ts->filter_data = ts;
} else
- ts->debounce_tol = ~0;
+ ts->filter = ads7846_no_filter;
ts->get_pendown_state = pdata->get_pendown_state;
snprintf(ts->phys, sizeof(ts->phys), "%s/input0", spi->dev.bus_id);
@@ -718,6 +911,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
input_set_abs_params(input_dev, ABS_PRESSURE,
pdata->pressure_min, pdata->pressure_max, 0, 0);
+ vref = pdata->keep_vref_on;
+
/* set up the transfers to read touchscreen state; this assumes we
* use formula #2 for pressure, not #3.
*/
@@ -727,7 +922,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
/* y- still on; turn on only y+ (and ADC) */
- ts->read_y = READ_Y;
+ ts->read_y = READ_Y(vref);
x->tx_buf = &ts->read_y;
x->len = 1;
spi_message_add_tail(x, m);
@@ -737,7 +932,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->len = 2;
spi_message_add_tail(x, m);
- m->complete = ads7846_debounce;
+ m->complete = ads7846_rx_val;
m->context = ts;
m++;
@@ -745,7 +940,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
/* turn y- off, x+ on, then leave in lowpower */
x++;
- ts->read_x = READ_X;
+ ts->read_x = READ_X(vref);
x->tx_buf = &ts->read_x;
x->len = 1;
spi_message_add_tail(x, m);
@@ -755,7 +950,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->len = 2;
spi_message_add_tail(x, m);
- m->complete = ads7846_debounce;
+ m->complete = ads7846_rx_val;
m->context = ts;
/* turn y+ off, x- on; we'll use formula #2 */
@@ -764,7 +959,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
x++;
- ts->read_z1 = READ_Z1;
+ ts->read_z1 = READ_Z1(vref);
x->tx_buf = &ts->read_z1;
x->len = 1;
spi_message_add_tail(x, m);
@@ -774,14 +969,14 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->len = 2;
spi_message_add_tail(x, m);
- m->complete = ads7846_debounce;
+ m->complete = ads7846_rx_val;
m->context = ts;
m++;
spi_message_init(m);
x++;
- ts->read_z2 = READ_Z2;
+ ts->read_z2 = READ_Z2(vref);
x->tx_buf = &ts->read_z2;
x->len = 1;
spi_message_add_tail(x, m);
@@ -791,7 +986,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->len = 2;
spi_message_add_tail(x, m);
- m->complete = ads7846_debounce;
+ m->complete = ads7846_rx_val;
m->context = ts;
}
@@ -820,31 +1015,24 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi->dev.driver->name, ts)) {
dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq);
err = -EBUSY;
- goto err_free_mem;
+ goto err_cleanup_filter;
}
+ err = ads784x_hwmon_register(spi, ts);
+ if (err)
+ goto err_free_irq;
+
dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq);
- /* take a first sample, leaving nPENIRQ active; avoid
+ /* take a first sample, leaving nPENIRQ active and vREF off; avoid
* the touchscreen, in case it's not connected.
*/
(void) ads7846_read12_ser(&spi->dev,
READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
- switch (ts->model) {
- case 7846:
- ts->attr_group = &ads7846_attr_group;
- break;
- case 7845:
- ts->attr_group = &ads7845_attr_group;
- break;
- default:
- ts->attr_group = &ads7843_attr_group;
- break;
- }
- err = sysfs_create_group(&spi->dev.kobj, ts->attr_group);
+ err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
if (err)
- goto err_free_irq;
+ goto err_remove_hwmon;
err = input_register_device(input_dev);
if (err)
@@ -853,9 +1041,14 @@ static int __devinit ads7846_probe(struct spi_device *spi)
return 0;
err_remove_attr_group:
- sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
+ sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group);
+ err_remove_hwmon:
+ ads784x_hwmon_unregister(spi, ts);
err_free_irq:
free_irq(spi->irq, ts);
+ err_cleanup_filter:
+ if (ts->filter_cleanup)
+ ts->filter_cleanup(ts->filter_data);
err_free_mem:
input_free_device(input_dev);
kfree(ts);
@@ -866,16 +1059,20 @@ static int __devexit ads7846_remove(struct spi_device *spi)
{
struct ads7846 *ts = dev_get_drvdata(&spi->dev);
+ ads784x_hwmon_unregister(spi, ts);
input_unregister_device(ts->input);
ads7846_suspend(spi, PMSG_SUSPEND);
- sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
+ sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group);
free_irq(ts->spi->irq, ts);
/* suspend left the IRQ disabled */
enable_irq(ts->spi->irq);
+ if (ts->filter_cleanup)
+ ts->filter_cleanup(ts->filter_data);
+
kfree(ts);
dev_dbg(&spi->dev, "unregistered touchscreen\n");
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index a730c461227f..0300dca8591d 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -151,6 +151,10 @@ static int tsdev_open(struct inode *inode, struct file *file)
int i = iminor(inode) - TSDEV_MINOR_BASE;
struct tsdev_list *list;
+ printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled "
+ "for removal.\nSee Documentation/feature-removal-schedule.txt "
+ "for details.\n");
+
if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK])
return -ENODEV;
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index d22c0224fde6..db1260f73f10 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -118,6 +118,15 @@ struct capiminor {
};
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+/* FIXME: The following lock is a sledgehammer-workaround to a
+ * locking issue with the capiminor (and maybe other) data structure(s).
+ * Access to this data is done in a racy way and crashes the machine with
+ * a FritzCard DSL driver; sooner or later. This is a workaround
+ * which trades scalability vs stability, so it doesn't crash the kernel anymore.
+ * The correct (and scalable) fix for the issue seems to require
+ * an API change to the drivers... . */
+static DEFINE_SPINLOCK(workaround_lock);
+
struct capincci {
struct capincci *next;
u32 ncci;
@@ -589,6 +598,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
struct capincci *np;
u32 ncci;
+ unsigned long flags;
if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field
@@ -603,9 +613,11 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
up(&cdev->ncci_list_sem);
}
+ spin_lock_irqsave(&workaround_lock, flags);
if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
skb_queue_tail(&cdev->recvqueue, skb);
wake_up_interruptible(&cdev->recvwait);
+ spin_unlock_irqrestore(&workaround_lock, flags);
return;
}
ncci = CAPIMSG_CONTROL(skb->data);
@@ -615,6 +627,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
printk(KERN_ERR "BUG: capi_signal: ncci not found\n");
skb_queue_tail(&cdev->recvqueue, skb);
wake_up_interruptible(&cdev->recvwait);
+ spin_unlock_irqrestore(&workaround_lock, flags);
return;
}
#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -625,6 +638,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
if (!mp) {
skb_queue_tail(&cdev->recvqueue, skb);
wake_up_interruptible(&cdev->recvwait);
+ spin_unlock_irqrestore(&workaround_lock, flags);
return;
}
@@ -660,6 +674,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
wake_up_interruptible(&cdev->recvwait);
}
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+ spin_unlock_irqrestore(&workaround_lock, flags);
}
/* -------- file_operations for capidev ----------------------------- */
@@ -988,7 +1003,7 @@ capi_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations capi_fops =
+static const struct file_operations capi_fops =
{
.owner = THIS_MODULE,
.llseek = no_llseek,
@@ -1006,6 +1021,7 @@ static struct file_operations capi_fops =
static int capinc_tty_open(struct tty_struct * tty, struct file * file)
{
struct capiminor *mp;
+ unsigned long flags;
if ((mp = capiminor_find(iminor(file->f_path.dentry->d_inode))) == 0)
return -ENXIO;
@@ -1014,6 +1030,7 @@ static int capinc_tty_open(struct tty_struct * tty, struct file * file)
tty->driver_data = (void *)mp;
+ spin_lock_irqsave(&workaround_lock, flags);
if (atomic_read(&mp->ttyopencount) == 0)
mp->tty = tty;
atomic_inc(&mp->ttyopencount);
@@ -1021,6 +1038,7 @@ static int capinc_tty_open(struct tty_struct * tty, struct file * file)
printk(KERN_DEBUG "capinc_tty_open ocount=%d\n", atomic_read(&mp->ttyopencount));
#endif
handle_minor_recv(mp);
+ spin_unlock_irqrestore(&workaround_lock, flags);
return 0;
}
@@ -1054,6 +1072,7 @@ static int capinc_tty_write(struct tty_struct * tty,
{
struct capiminor *mp = (struct capiminor *)tty->driver_data;
struct sk_buff *skb;
+ unsigned long flags;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count);
@@ -1066,6 +1085,7 @@ static int capinc_tty_write(struct tty_struct * tty,
return 0;
}
+ spin_lock_irqsave(&workaround_lock, flags);
skb = mp->ttyskb;
if (skb) {
mp->ttyskb = NULL;
@@ -1076,6 +1096,7 @@ static int capinc_tty_write(struct tty_struct * tty,
skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_ATOMIC);
if (!skb) {
printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n");
+ spin_unlock_irqrestore(&workaround_lock, flags);
return -ENOMEM;
}
@@ -1086,6 +1107,7 @@ static int capinc_tty_write(struct tty_struct * tty,
mp->outbytes += skb->len;
(void)handle_minor_send(mp);
(void)handle_minor_recv(mp);
+ spin_unlock_irqrestore(&workaround_lock, flags);
return count;
}
@@ -1093,6 +1115,7 @@ static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
{
struct capiminor *mp = (struct capiminor *)tty->driver_data;
struct sk_buff *skb;
+ unsigned long flags;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);
@@ -1105,10 +1128,12 @@ static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
return;
}
+ spin_lock_irqsave(&workaround_lock, flags);
skb = mp->ttyskb;
if (skb) {
if (skb_tailroom(skb) > 0) {
*(skb_put(skb, 1)) = ch;
+ spin_unlock_irqrestore(&workaround_lock, flags);
return;
}
mp->ttyskb = NULL;
@@ -1124,12 +1149,14 @@ static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
} else {
printk(KERN_ERR "capinc_put_char: char %u lost\n", ch);
}
+ spin_unlock_irqrestore(&workaround_lock, flags);
}
static void capinc_tty_flush_chars(struct tty_struct *tty)
{
struct capiminor *mp = (struct capiminor *)tty->driver_data;
struct sk_buff *skb;
+ unsigned long flags;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_flush_chars\n");
@@ -1142,6 +1169,7 @@ static void capinc_tty_flush_chars(struct tty_struct *tty)
return;
}
+ spin_lock_irqsave(&workaround_lock, flags);
skb = mp->ttyskb;
if (skb) {
mp->ttyskb = NULL;
@@ -1150,6 +1178,7 @@ static void capinc_tty_flush_chars(struct tty_struct *tty)
(void)handle_minor_send(mp);
}
(void)handle_minor_recv(mp);
+ spin_unlock_irqrestore(&workaround_lock, flags);
}
static int capinc_tty_write_room(struct tty_struct *tty)
@@ -1220,12 +1249,15 @@ static void capinc_tty_throttle(struct tty_struct * tty)
static void capinc_tty_unthrottle(struct tty_struct * tty)
{
struct capiminor *mp = (struct capiminor *)tty->driver_data;
+ unsigned long flags;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_unthrottle\n");
#endif
if (mp) {
+ spin_lock_irqsave(&workaround_lock, flags);
mp->ttyinstop = 0;
handle_minor_recv(mp);
+ spin_unlock_irqrestore(&workaround_lock, flags);
}
}
@@ -1243,12 +1275,15 @@ static void capinc_tty_stop(struct tty_struct *tty)
static void capinc_tty_start(struct tty_struct *tty)
{
struct capiminor *mp = (struct capiminor *)tty->driver_data;
+ unsigned long flags;
#ifdef _DEBUG_TTYFUNCS
printk(KERN_DEBUG "capinc_tty_start\n");
#endif
if (mp) {
+ spin_lock_irqsave(&workaround_lock, flags);
mp->ttyoutstop = 0;
(void)handle_minor_send(mp);
+ spin_unlock_irqrestore(&workaround_lock, flags);
}
}
@@ -1456,7 +1491,7 @@ static struct procfsentries {
static void __init proc_init(void)
{
- int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
+ int nelem = ARRAY_SIZE(procfsentries);
int i;
for (i=0; i < nelem; i++) {
@@ -1468,7 +1503,7 @@ static void __init proc_init(void)
static void __exit proc_exit(void)
{
- int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
+ int nelem = ARRAY_SIZE(procfsentries);
int i;
for (i=nelem-1; i >= 0; i--) {
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index c4d438c17dab..8cec9c3898ec 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -2218,7 +2218,7 @@ static struct procfsentries {
static void __init proc_init(void)
{
- int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
+ int nelem = ARRAY_SIZE(procfsentries);
int i;
for (i=0; i < nelem; i++) {
@@ -2230,7 +2230,7 @@ static void __init proc_init(void)
static void __exit proc_exit(void)
{
- int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
+ int nelem = ARRAY_SIZE(procfsentries);
int i;
for (i=nelem-1; i >= 0; i--) {
diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c
index ca9dc00a45c4..31f4fd8b8b0a 100644
--- a/drivers/isdn/capi/kcapi_proc.c
+++ b/drivers/isdn/capi/kcapi_proc.c
@@ -113,14 +113,14 @@ static int seq_contrstats_open(struct inode *inode, struct file *file)
return seq_open(file, &seq_contrstats_ops);
}
-static struct file_operations proc_controller_ops = {
+static const struct file_operations proc_controller_ops = {
.open = seq_controller_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
-static struct file_operations proc_contrstats_ops = {
+static const struct file_operations proc_contrstats_ops = {
.open = seq_contrstats_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -218,14 +218,14 @@ seq_applstats_open(struct inode *inode, struct file *file)
return seq_open(file, &seq_applstats_ops);
}
-static struct file_operations proc_applications_ops = {
+static const struct file_operations proc_applications_ops = {
.open = seq_applications_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
-static struct file_operations proc_applstats_ops = {
+static const struct file_operations proc_applstats_ops = {
.open = seq_applstats_open,
.read = seq_read,
.llseek = seq_lseek,
@@ -302,7 +302,7 @@ seq_capi_driver_open(struct inode *inode, struct file *file)
return err;
}
-static struct file_operations proc_driver_ops = {
+static const struct file_operations proc_driver_ops = {
.open = seq_capi_driver_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 06967da7c4a8..53a189003355 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -256,7 +256,7 @@ isdn_divert_ioctl(struct inode *inode, struct file *file,
#ifdef CONFIG_PROC_FS
-static struct file_operations isdn_fops =
+static const struct file_operations isdn_fops =
{
.owner = THIS_MODULE,
.llseek = no_llseek,
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig
index 708d47a6484b..bcbb6502a773 100644
--- a/drivers/isdn/gigaset/Kconfig
+++ b/drivers/isdn/gigaset/Kconfig
@@ -7,7 +7,13 @@ config ISDN_DRV_GIGASET
select CRC_CCITT
select BITREVERSE
help
- Say m here if you have a Gigaset or Sinus isdn device.
+ This driver supports the Siemens Gigaset SX205/255 family of
+ ISDN DECT bases, including the predecessors Gigaset 3070/3075
+ and 4170/4175 and their T-Com versions Sinus 45isdn and Sinus
+ 721X.
+ If you have one of these devices, say M here and for at least
+ one of the connection specific parts that follow.
+ This will build a module called "gigaset".
if ISDN_DRV_GIGASET!=n
@@ -15,14 +21,25 @@ config GIGASET_BASE
tristate "Gigaset base station support"
depends on ISDN_DRV_GIGASET && USB
help
- Say m here if you need to communicate with the base
- directly via USB.
+ Say M here if you want to use the USB interface of the Gigaset
+ base for connection to your system.
+ This will build a module called "bas_gigaset".
config GIGASET_M105
tristate "Gigaset M105 support"
depends on ISDN_DRV_GIGASET && USB
help
- Say m here if you need the driver for the Gigaset M105 device.
+ Say M here if you want to connect to the Gigaset base via DECT
+ using a Gigaset M105 (Sinus 45 Data 2) USB DECT device.
+ This will build a module called "usb_gigaset".
+
+config GIGASET_M101
+ tristate "Gigaset M101 support"
+ depends on ISDN_DRV_GIGASET
+ help
+ Say M here if you want to connect to the Gigaset base via DECT
+ using a Gigaset M101 (Sinus 45 Data 1) RS232 DECT device.
+ This will build a module called "ser_gigaset".
config GIGASET_DEBUG
bool "Gigaset debugging"
diff --git a/drivers/isdn/gigaset/Makefile b/drivers/isdn/gigaset/Makefile
index 9b9acf1a21ad..835b806a9de7 100644
--- a/drivers/isdn/gigaset/Makefile
+++ b/drivers/isdn/gigaset/Makefile
@@ -1,6 +1,8 @@
gigaset-y := common.o interface.o proc.o ev-layer.o i4l.o
usb_gigaset-y := usb-gigaset.o asyncdata.o
bas_gigaset-y := bas-gigaset.o isocdata.o
+ser_gigaset-y := ser-gigaset.o asyncdata.o
obj-$(CONFIG_GIGASET_M105) += usb_gigaset.o gigaset.o
obj-$(CONFIG_GIGASET_BASE) += bas_gigaset.o gigaset.o
+obj-$(CONFIG_GIGASET_M105) += ser_gigaset.o gigaset.o
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index 88e958f176d2..ddf5e92be444 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -13,6 +13,11 @@
* =====================================================================
*/
+/* not set by Kbuild when building both ser_gigaset and usb_gigaset */
+#ifndef KBUILD_MODNAME
+#define KBUILD_MODNAME "asy_gigaset"
+#endif
+
#include "gigaset.h"
#include <linux/crc-ccitt.h>
#include <linux/bitrev.h>
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index b5e7f9c7d74e..63e51dd6debe 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -257,10 +257,10 @@ static inline void dump_urb(enum debuglevel level, const char *tag,
urb->transfer_flags);
gig_dbg(level,
" transfer_buffer=0x%08lx[%d], actual_length=%d, "
- "bandwidth=%d, setup_packet=0x%08lx,",
+ "setup_packet=0x%08lx,",
(unsigned long) urb->transfer_buffer,
urb->transfer_buffer_length, urb->actual_length,
- urb->bandwidth, (unsigned long) urb->setup_packet);
+ (unsigned long) urb->setup_packet);
gig_dbg(level,
" start_frame=%d, number_of_packets=%d, interval=%d, "
"error_count=%d,",
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 4f75cce6fdff..b460a73a7c85 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -640,7 +640,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
return NULL;
}
mutex_init(&cs->mutex);
- mutex_lock(&cs->mutex);
gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1);
cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL);
@@ -738,6 +737,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
++cs->cs_init;
+ /* set up character device */
gigaset_if_init(cs);
/* set up device sysfs */
@@ -753,11 +753,9 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
add_timer(&cs->timer);
gig_dbg(DEBUG_INIT, "cs initialized");
- mutex_unlock(&cs->mutex);
return cs;
error:
- mutex_unlock(&cs->mutex);
gig_dbg(DEBUG_INIT, "failed");
gigaset_freecs(cs);
return NULL;
@@ -908,20 +906,7 @@ void gigaset_shutdown(struct cardstate *cs)
gig_dbg(DEBUG_CMD, "scheduling SHUTDOWN");
gigaset_schedule_event(cs);
- if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) {
- warn("%s: aborted", __func__);
- //FIXME
- }
-
- if (atomic_read(&cs->mstate) != MS_LOCKED) {
- //FIXME?
- //gigaset_baud_rate(cs, B115200);
- //gigaset_set_line_ctrl(cs, CS8);
- //gigaset_set_modem_ctrl(cs, TIOCM_DTR|TIOCM_RTS, 0);
- //cs->control_state = 0;
- } else {
- //FIXME use some saved values?
- }
+ wait_event(cs->waitqueue, !cs->waiting);
cleanup_cs(cs);
@@ -944,10 +929,7 @@ void gigaset_stop(struct cardstate *cs)
gig_dbg(DEBUG_CMD, "scheduling STOP");
gigaset_schedule_event(cs);
- if (wait_event_interruptible(cs->waitqueue, !cs->waiting)) {
- warn("%s: aborted", __func__);
- //FIXME
- }
+ wait_event(cs->waitqueue, !cs->waiting);
cleanup_cs(cs);
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 44f02dbd1111..4661e2c722bc 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -1015,7 +1015,7 @@ static void finish_shutdown(struct cardstate *cs)
cs->cmd_result = -ENODEV;
cs->waiting = 0;
- wake_up_interruptible(&cs->waitqueue);
+ wake_up(&cs->waitqueue);
}
static void do_shutdown(struct cardstate *cs)
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index 458b6462f937..eb50f3dab5f7 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -599,19 +599,9 @@ out:
static void if_wake(unsigned long data)
{
struct cardstate *cs = (struct cardstate *) data;
- struct tty_struct *tty;
-
- tty = cs->tty;
- if (!tty)
- return;
-
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup) {
- gig_dbg(DEBUG_IF, "write wakeup call");
- tty->ldisc.write_wakeup(tty);
- }
- wake_up_interruptible(&tty->write_wait);
+ if (cs->tty)
+ tty_wakeup(cs->tty);
}
/*** interface to common ***/
@@ -625,6 +615,8 @@ void gigaset_if_init(struct cardstate *cs)
return;
tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs);
+
+ mutex_lock(&cs->mutex);
cs->tty_dev = tty_register_device(drv->tty, cs->minor_index, NULL);
if (!IS_ERR(cs->tty_dev))
@@ -633,6 +625,7 @@ void gigaset_if_init(struct cardstate *cs)
warn("could not register device to the tty subsystem");
cs->tty_dev = NULL;
}
+ mutex_unlock(&cs->mutex);
}
void gigaset_if_free(struct cardstate *cs)
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index df988eb0e36f..8c0eb522dab1 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -921,6 +921,8 @@ static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf)
/* end of line */
gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)",
__func__, cbytes);
+ if (cbytes >= MAX_RESP_SIZE - 1)
+ dev_warn(cs->dev, "response too large\n");
cs->cbytes = cbytes;
gigaset_handle_modem_response(cs);
cbytes = 0;
@@ -929,8 +931,6 @@ static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf)
/* advance in line buffer, checking for overflow */
if (cbytes < MAX_RESP_SIZE - 1)
cbytes++;
- else
- dev_warn(cs->dev, "response too large\n");
}
}
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
new file mode 100644
index 000000000000..c8b7db65e48f
--- /dev/null
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -0,0 +1,837 @@
+/* This is the serial hardware link layer (HLL) for the Gigaset 307x isdn
+ * DECT base (aka Sinus 45 isdn) using the RS232 DECT data module M101,
+ * written as a line discipline.
+ *
+ * =====================================================================
+ * 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.
+ * =====================================================================
+ */
+
+#include "gigaset.h"
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/poll.h>
+
+/* Version Information */
+#define DRIVER_AUTHOR "Tilman Schmidt"
+#define DRIVER_DESC "Serial Driver for Gigaset 307x using Siemens M101"
+
+#define GIGASET_MINORS 1
+#define GIGASET_MINOR 0
+#define GIGASET_MODULENAME "ser_gigaset"
+#define GIGASET_DEVNAME "ttyGS"
+
+/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
+#define IF_WRITEBUF 264
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_LDISC(N_GIGASET_M101);
+
+static int startmode = SM_ISDN;
+module_param(startmode, int, S_IRUGO);
+MODULE_PARM_DESC(startmode, "initial operation mode");
+static int cidmode = 1;
+module_param(cidmode, int, S_IRUGO);
+MODULE_PARM_DESC(cidmode, "stay in CID mode when idle");
+
+static struct gigaset_driver *driver;
+
+struct ser_cardstate {
+ struct platform_device dev;
+ struct tty_struct *tty;
+ atomic_t refcnt;
+ struct mutex dead_mutex;
+};
+
+static struct platform_driver device_driver = {
+ .driver = {
+ .name = GIGASET_MODULENAME,
+ },
+};
+
+static void flush_send_queue(struct cardstate *);
+
+/* transmit data from current open skb
+ * result: number of bytes sent or error code < 0
+ */
+static int write_modem(struct cardstate *cs)
+{
+ struct tty_struct *tty = cs->hw.ser->tty;
+ struct bc_state *bcs = &cs->bcs[0]; /* only one channel */
+ struct sk_buff *skb = bcs->tx_skb;
+ int sent;
+
+ if (!tty || !tty->driver || !skb)
+ return -EFAULT;
+
+ if (!skb->len) {
+ dev_kfree_skb_any(skb);
+ bcs->tx_skb = NULL;
+ return -EINVAL;
+ }
+
+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+ sent = tty->driver->write(tty, skb->data, skb->len);
+ gig_dbg(DEBUG_OUTPUT, "write_modem: sent %d", sent);
+ if (sent < 0) {
+ /* error */
+ flush_send_queue(cs);
+ return sent;
+ }
+ skb_pull(skb, sent);
+ if (!skb->len) {
+ /* skb sent completely */
+ gigaset_skb_sent(bcs, skb);
+
+ gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!",
+ (unsigned long) skb);
+ dev_kfree_skb_any(skb);
+ bcs->tx_skb = NULL;
+ }
+ return sent;
+}
+
+/*
+ * transmit first queued command buffer
+ * result: number of bytes sent or error code < 0
+ */
+static int send_cb(struct cardstate *cs)
+{
+ struct tty_struct *tty = cs->hw.ser->tty;
+ struct cmdbuf_t *cb, *tcb;
+ unsigned long flags;
+ int sent = 0;
+
+ if (!tty || !tty->driver)
+ return -EFAULT;
+
+ cb = cs->cmdbuf;
+ if (!cb)
+ return 0; /* nothing to do */
+
+ if (cb->len) {
+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+ sent = tty->driver->write(tty, cb->buf + cb->offset, cb->len);
+ if (sent < 0) {
+ /* error */
+ gig_dbg(DEBUG_OUTPUT, "send_cb: write error %d", sent);
+ flush_send_queue(cs);
+ return sent;
+ }
+ cb->offset += sent;
+ cb->len -= sent;
+ gig_dbg(DEBUG_OUTPUT, "send_cb: sent %d, left %u, queued %u",
+ sent, cb->len, cs->cmdbytes);
+ }
+
+ while (cb && !cb->len) {
+ spin_lock_irqsave(&cs->cmdlock, flags);
+ cs->cmdbytes -= cs->curlen;
+ tcb = cb;
+ cs->cmdbuf = cb = cb->next;
+ if (cb) {
+ cb->prev = NULL;
+ cs->curlen = cb->len;
+ } else {
+ cs->lastcmdbuf = NULL;
+ cs->curlen = 0;
+ }
+ spin_unlock_irqrestore(&cs->cmdlock, flags);
+
+ if (tcb->wake_tasklet)
+ tasklet_schedule(tcb->wake_tasklet);
+ kfree(tcb);
+ }
+ return sent;
+}
+
+/*
+ * send queue tasklet
+ * If there is already a skb opened, put data to the transfer buffer
+ * by calling "write_modem".
+ * Otherwise take a new skb out of the queue.
+ */
+static void gigaset_modem_fill(unsigned long data)
+{
+ struct cardstate *cs = (struct cardstate *) data;
+ struct bc_state *bcs;
+ int sent = 0;
+
+ if (!cs || !(bcs = cs->bcs)) {
+ gig_dbg(DEBUG_OUTPUT, "%s: no cardstate", __func__);
+ return;
+ }
+ if (!bcs->tx_skb) {
+ /* no skb is being sent; send command if any */
+ sent = send_cb(cs);
+ gig_dbg(DEBUG_OUTPUT, "%s: send_cb -> %d", __func__, sent);
+ if (sent)
+ /* something sent or error */
+ return;
+
+ /* no command to send; get skb */
+ if (!(bcs->tx_skb = skb_dequeue(&bcs->squeue)))
+ /* no skb either, nothing to do */
+ return;
+
+ gig_dbg(DEBUG_INTR, "Dequeued skb (Adr: %lx)",
+ (unsigned long) bcs->tx_skb);
+ }
+
+ /* send skb */
+ gig_dbg(DEBUG_OUTPUT, "%s: tx_skb", __func__);
+ if (write_modem(cs) < 0)
+ gig_dbg(DEBUG_OUTPUT, "%s: write_modem failed", __func__);
+}
+
+/*
+ * throw away all data queued for sending
+ */
+static void flush_send_queue(struct cardstate *cs)
+{
+ struct sk_buff *skb;
+ struct cmdbuf_t *cb;
+ unsigned long flags;
+
+ /* command queue */
+ spin_lock_irqsave(&cs->cmdlock, flags);
+ while ((cb = cs->cmdbuf) != NULL) {
+ cs->cmdbuf = cb->next;
+ if (cb->wake_tasklet)
+ tasklet_schedule(cb->wake_tasklet);
+ kfree(cb);
+ }
+ cs->cmdbuf = cs->lastcmdbuf = NULL;
+ cs->cmdbytes = cs->curlen = 0;
+ spin_unlock_irqrestore(&cs->cmdlock, flags);
+
+ /* data queue */
+ if (cs->bcs->tx_skb)
+ dev_kfree_skb_any(cs->bcs->tx_skb);
+ while ((skb = skb_dequeue(&cs->bcs->squeue)) != NULL)
+ dev_kfree_skb_any(skb);
+}
+
+
+/* Gigaset Driver Interface */
+/* ======================== */
+
+/*
+ * queue an AT command string for transmission to the Gigaset device
+ * parameters:
+ * cs controller state structure
+ * buf buffer containing the string to send
+ * len number of characters to send
+ * wake_tasklet tasklet to run when transmission is complete, or NULL
+ * return value:
+ * number of bytes queued, or error code < 0
+ */
+static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
+ int len, struct tasklet_struct *wake_tasklet)
+{
+ struct cmdbuf_t *cb;
+ unsigned long flags;
+
+ gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ?
+ DEBUG_TRANSCMD : DEBUG_LOCKCMD,
+ "CMD Transmit", len, buf);
+
+ if (len <= 0)
+ return 0;
+
+ if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
+ dev_err(cs->dev, "%s: out of memory!\n", __func__);
+ return -ENOMEM;
+ }
+
+ memcpy(cb->buf, buf, len);
+ cb->len = len;
+ cb->offset = 0;
+ cb->next = NULL;
+ cb->wake_tasklet = wake_tasklet;
+
+ spin_lock_irqsave(&cs->cmdlock, flags);
+ cb->prev = cs->lastcmdbuf;
+ if (cs->lastcmdbuf)
+ cs->lastcmdbuf->next = cb;
+ else {
+ cs->cmdbuf = cb;
+ cs->curlen = len;
+ }
+ cs->cmdbytes += len;
+ cs->lastcmdbuf = cb;
+ spin_unlock_irqrestore(&cs->cmdlock, flags);
+
+ spin_lock_irqsave(&cs->lock, flags);
+ if (cs->connected)
+ tasklet_schedule(&cs->write_tasklet);
+ spin_unlock_irqrestore(&cs->lock, flags);
+ return len;
+}
+
+/*
+ * tty_driver.write_room interface routine
+ * return number of characters the driver will accept to be written
+ * parameter:
+ * controller state structure
+ * return value:
+ * number of characters
+ */
+static int gigaset_write_room(struct cardstate *cs)
+{
+ unsigned bytes;
+
+ bytes = cs->cmdbytes;
+ return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0;
+}
+
+/*
+ * tty_driver.chars_in_buffer interface routine
+ * return number of characters waiting to be sent
+ * parameter:
+ * controller state structure
+ * return value:
+ * number of characters
+ */
+static int gigaset_chars_in_buffer(struct cardstate *cs)
+{
+ return cs->cmdbytes;
+}
+
+/*
+ * implementation of ioctl(GIGASET_BRKCHARS)
+ * parameter:
+ * controller state structure
+ * return value:
+ * -EINVAL (unimplemented function)
+ */
+static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
+{
+ /* not implemented */
+ return -EINVAL;
+}
+
+/*
+ * Open B channel
+ * Called by "do_action" in ev-layer.c
+ */
+static int gigaset_init_bchannel(struct bc_state *bcs)
+{
+ /* nothing to do for M10x */
+ gigaset_bchannel_up(bcs);
+ return 0;
+}
+
+/*
+ * Close B channel
+ * Called by "do_action" in ev-layer.c
+ */
+static int gigaset_close_bchannel(struct bc_state *bcs)
+{
+ /* nothing to do for M10x */
+ gigaset_bchannel_down(bcs);
+ return 0;
+}
+
+/*
+ * Set up B channel structure
+ * This is called by "gigaset_initcs" in common.c
+ */
+static int gigaset_initbcshw(struct bc_state *bcs)
+{
+ /* unused */
+ bcs->hw.ser = NULL;
+ return 1;
+}
+
+/*
+ * Free B channel structure
+ * Called by "gigaset_freebcs" in common.c
+ */
+static int gigaset_freebcshw(struct bc_state *bcs)
+{
+ /* unused */
+ return 1;
+}
+
+/*
+ * Reinitialize B channel structure
+ * This is called by "bcs_reinit" in common.c
+ */
+static void gigaset_reinitbcshw(struct bc_state *bcs)
+{
+ /* nothing to do for M10x */
+}
+
+/*
+ * Free hardware specific device data
+ * This will be called by "gigaset_freecs" in common.c
+ */
+static void gigaset_freecshw(struct cardstate *cs)
+{
+ tasklet_kill(&cs->write_tasklet);
+ if (!cs->hw.ser)
+ return;
+ dev_set_drvdata(&cs->hw.ser->dev.dev, NULL);
+ platform_device_unregister(&cs->hw.ser->dev);
+ kfree(cs->hw.ser);
+ cs->hw.ser = NULL;
+}
+
+static void gigaset_device_release(struct device *dev)
+{
+ struct platform_device *pdev =
+ container_of(dev, struct platform_device, dev);
+
+ /* adapted from platform_device_release() in drivers/base/platform.c */
+ //FIXME is this actually necessary?
+ kfree(dev->platform_data);
+ kfree(pdev->resource);
+}
+
+/*
+ * Set up hardware specific device data
+ * This is called by "gigaset_initcs" in common.c
+ */
+static int gigaset_initcshw(struct cardstate *cs)
+{
+ int rc;
+
+ if (!(cs->hw.ser = kzalloc(sizeof(struct ser_cardstate), GFP_KERNEL))) {
+ err("%s: out of memory!", __func__);
+ return 0;
+ }
+
+ cs->hw.ser->dev.name = GIGASET_MODULENAME;
+ cs->hw.ser->dev.id = cs->minor_index;
+ cs->hw.ser->dev.dev.release = gigaset_device_release;
+ if ((rc = platform_device_register(&cs->hw.ser->dev)) != 0) {
+ err("error %d registering platform device", rc);
+ kfree(cs->hw.ser);
+ cs->hw.ser = NULL;
+ return 0;
+ }
+ dev_set_drvdata(&cs->hw.ser->dev.dev, cs);
+
+ tasklet_init(&cs->write_tasklet,
+ &gigaset_modem_fill, (unsigned long) cs);
+ return 1;
+}
+
+/*
+ * set modem control lines
+ * Parameters:
+ * card state structure
+ * modem control line state ([TIOCM_DTR]|[TIOCM_RTS])
+ * Called by "gigaset_start" and "gigaset_enterconfigmode" in common.c
+ * and by "if_lock" and "if_termios" in interface.c
+ */
+static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, unsigned new_state)
+{
+ struct tty_struct *tty = cs->hw.ser->tty;
+ unsigned int set, clear;
+
+ if (!tty || !tty->driver || !tty->driver->tiocmset)
+ return -EFAULT;
+ set = new_state & ~old_state;
+ clear = old_state & ~new_state;
+ if (!set && !clear)
+ return 0;
+ gig_dbg(DEBUG_IF, "tiocmset set %x clear %x", set, clear);
+ return tty->driver->tiocmset(tty, NULL, set, clear);
+}
+
+static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
+{
+ return -EINVAL;
+}
+
+static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
+{
+ return -EINVAL;
+}
+
+static struct gigaset_ops ops = {
+ gigaset_write_cmd,
+ gigaset_write_room,
+ gigaset_chars_in_buffer,
+ gigaset_brkchars,
+ gigaset_init_bchannel,
+ gigaset_close_bchannel,
+ gigaset_initbcshw,
+ gigaset_freebcshw,
+ gigaset_reinitbcshw,
+ gigaset_initcshw,
+ gigaset_freecshw,
+ gigaset_set_modem_ctrl,
+ gigaset_baud_rate,
+ gigaset_set_line_ctrl,
+ gigaset_m10x_send_skb, /* asyncdata.c */
+ gigaset_m10x_input, /* asyncdata.c */
+};
+
+
+/* Line Discipline Interface */
+/* ========================= */
+
+/* helper functions for cardstate refcounting */
+static struct cardstate *cs_get(struct tty_struct *tty)
+{
+ struct cardstate *cs = tty->disc_data;
+
+ if (!cs || !cs->hw.ser) {
+ gig_dbg(DEBUG_ANY, "%s: no cardstate", __func__);
+ return NULL;
+ }
+ atomic_inc(&cs->hw.ser->refcnt);
+ return cs;
+}
+
+static void cs_put(struct cardstate *cs)
+{
+ if (atomic_dec_and_test(&cs->hw.ser->refcnt))
+ mutex_unlock(&cs->hw.ser->dead_mutex);
+}
+
+/*
+ * Called by the tty driver when the line discipline is pushed onto the tty.
+ * Called in process context.
+ */
+static int
+gigaset_tty_open(struct tty_struct *tty)
+{
+ struct cardstate *cs;
+
+ gig_dbg(DEBUG_INIT, "Starting HLL for Gigaset M101");
+
+ info(DRIVER_AUTHOR);
+ info(DRIVER_DESC);
+
+ if (!driver) {
+ err("%s: no driver structure", __func__);
+ return -ENODEV;
+ }
+
+ /* allocate memory for our device state and intialize it */
+ if (!(cs = gigaset_initcs(driver, 1, 1, 0, cidmode,
+ GIGASET_MODULENAME)))
+ goto error;
+
+ cs->dev = &cs->hw.ser->dev.dev;
+ cs->hw.ser->tty = tty;
+ mutex_init(&cs->hw.ser->dead_mutex);
+ atomic_set(&cs->hw.ser->refcnt, 1);
+
+ tty->disc_data = cs;
+
+ /* OK.. Initialization of the datastructures and the HW is done.. Now
+ * startup system and notify the LL that we are ready to run
+ */
+ if (startmode == SM_LOCKED)
+ atomic_set(&cs->mstate, MS_LOCKED);
+ if (!gigaset_start(cs)) {
+ tasklet_kill(&cs->write_tasklet);
+ goto error;
+ }
+
+ gig_dbg(DEBUG_INIT, "Startup of HLL done");
+ mutex_lock(&cs->hw.ser->dead_mutex);
+ return 0;
+
+error:
+ gig_dbg(DEBUG_INIT, "Startup of HLL failed");
+ tty->disc_data = NULL;
+ gigaset_freecs(cs);
+ return -ENODEV;
+}
+
+/*
+ * Called by the tty driver when the line discipline is removed.
+ * Called from process context.
+ */
+static void
+gigaset_tty_close(struct tty_struct *tty)
+{
+ struct cardstate *cs = tty->disc_data;
+
+ gig_dbg(DEBUG_INIT, "Stopping HLL for Gigaset M101");
+
+ if (!cs) {
+ gig_dbg(DEBUG_INIT, "%s: no cardstate", __func__);
+ return;
+ }
+
+ /* prevent other callers from entering ldisc methods */
+ tty->disc_data = NULL;
+
+ if (!cs->hw.ser)
+ err("%s: no hw cardstate", __func__);
+ else {
+ /* wait for running methods to finish */
+ if (!atomic_dec_and_test(&cs->hw.ser->refcnt))
+ mutex_lock(&cs->hw.ser->dead_mutex);
+ }
+
+ /* stop operations */
+ gigaset_stop(cs);
+ tasklet_kill(&cs->write_tasklet);
+ flush_send_queue(cs);
+ cs->dev = NULL;
+ gigaset_freecs(cs);
+
+ gig_dbg(DEBUG_INIT, "Shutdown of HLL done");
+}
+
+/*
+ * Called by the tty driver when the tty line is hung up.
+ * Wait for I/O to driver to complete and unregister ISDN device.
+ * This is already done by the close routine, so just call that.
+ * Called from process context.
+ */
+static int gigaset_tty_hangup(struct tty_struct *tty)
+{
+ gigaset_tty_close(tty);
+ return 0;
+}
+
+/*
+ * Read on the tty.
+ * Unused, received data goes only to the Gigaset driver.
+ */
+static ssize_t
+gigaset_tty_read(struct tty_struct *tty, struct file *file,
+ unsigned char __user *buf, size_t count)
+{
+ return -EAGAIN;
+}
+
+/*
+ * Write on the tty.
+ * Unused, transmit data comes only from the Gigaset driver.
+ */
+static ssize_t
+gigaset_tty_write(struct tty_struct *tty, struct file *file,
+ const unsigned char *buf, size_t count)
+{
+ return -EAGAIN;
+}
+
+/*
+ * Ioctl on the tty.
+ * Called in process context only.
+ * May be re-entered by multiple ioctl calling threads.
+ */
+static int
+gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct cardstate *cs = cs_get(tty);
+ int rc, val;
+ int __user *p = (int __user *)arg;
+
+ if (!cs)
+ return -ENXIO;
+
+ switch (cmd) {
+ case TCGETS:
+ case TCGETA:
+ /* pass through to underlying serial device */
+ rc = n_tty_ioctl(tty, file, cmd, arg);
+ break;
+
+ case TCFLSH:
+ /* flush our buffers and the serial port's buffer */
+ switch (arg) {
+ case TCIFLUSH:
+ /* no own input buffer to flush */
+ break;
+ case TCIOFLUSH:
+ case TCOFLUSH:
+ flush_send_queue(cs);
+ break;
+ }
+ /* flush the serial port's buffer */
+ rc = n_tty_ioctl(tty, file, cmd, arg);
+ break;
+
+ case FIONREAD:
+ /* unused, always return zero */
+ val = 0;
+ rc = put_user(val, p);
+ break;
+
+ default:
+ rc = -ENOIOCTLCMD;
+ }
+
+ cs_put(cs);
+ return rc;
+}
+
+/*
+ * Poll on the tty.
+ * Unused, always return zero.
+ */
+static unsigned int
+gigaset_tty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
+{
+ return 0;
+}
+
+/*
+ * Called by the tty driver when a block of data has been received.
+ * Will not be re-entered while running but other ldisc functions
+ * may be called in parallel.
+ * Can be called from hard interrupt level as well as soft interrupt
+ * level or mainline.
+ * Parameters:
+ * tty tty structure
+ * buf buffer containing received characters
+ * cflags buffer containing error flags for received characters (ignored)
+ * count number of received characters
+ */
+static void
+gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
+ char *cflags, int count)
+{
+ struct cardstate *cs = cs_get(tty);
+ unsigned tail, head, n;
+ struct inbuf_t *inbuf;
+
+ if (!cs)
+ return;
+ if (!(inbuf = cs->inbuf)) {
+ dev_err(cs->dev, "%s: no inbuf\n", __func__);
+ cs_put(cs);
+ return;
+ }
+
+ tail = atomic_read(&inbuf->tail);
+ head = atomic_read(&inbuf->head);
+ gig_dbg(DEBUG_INTR, "buffer state: %u -> %u, receive %u bytes",
+ head, tail, count);
+
+ if (head <= tail) {
+ /* possible buffer wraparound */
+ n = min_t(unsigned, count, RBUFSIZE - tail);
+ memcpy(inbuf->data + tail, buf, n);
+ tail = (tail + n) % RBUFSIZE;
+ buf += n;
+ count -= n;
+ }
+
+ if (count > 0) {
+ /* tail < head and some data left */
+ n = head - tail - 1;
+ if (count > n) {
+ dev_err(cs->dev,
+ "inbuf overflow, discarding %d bytes\n",
+ count - n);
+ count = n;
+ }
+ memcpy(inbuf->data + tail, buf, count);
+ tail += count;
+ }
+
+ gig_dbg(DEBUG_INTR, "setting tail to %u", tail);
+ atomic_set(&inbuf->tail, tail);
+
+ /* Everything was received .. Push data into handler */
+ gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
+ gigaset_schedule_event(cs);
+ cs_put(cs);
+}
+
+/*
+ * Called by the tty driver when there's room for more data to send.
+ */
+static void
+gigaset_tty_wakeup(struct tty_struct *tty)
+{
+ struct cardstate *cs = cs_get(tty);
+
+ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+ if (!cs)
+ return;
+ tasklet_schedule(&cs->write_tasklet);
+ cs_put(cs);
+}
+
+static struct tty_ldisc gigaset_ldisc = {
+ .owner = THIS_MODULE,
+ .magic = TTY_LDISC_MAGIC,
+ .name = "ser_gigaset",
+ .open = gigaset_tty_open,
+ .close = gigaset_tty_close,
+ .hangup = gigaset_tty_hangup,
+ .read = gigaset_tty_read,
+ .write = gigaset_tty_write,
+ .ioctl = gigaset_tty_ioctl,
+ .poll = gigaset_tty_poll,
+ .receive_buf = gigaset_tty_receive,
+ .write_wakeup = gigaset_tty_wakeup,
+};
+
+
+/* Initialization / Shutdown */
+/* ========================= */
+
+static int __init ser_gigaset_init(void)
+{
+ int rc;
+
+ gig_dbg(DEBUG_INIT, "%s", __func__);
+ if ((rc = platform_driver_register(&device_driver)) != 0) {
+ err("error %d registering platform driver", rc);
+ return rc;
+ }
+
+ /* allocate memory for our driver state and intialize it */
+ if (!(driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
+ GIGASET_MODULENAME, GIGASET_DEVNAME,
+ &ops, THIS_MODULE)))
+ goto error;
+
+ if ((rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc)) != 0) {
+ err("error %d registering line discipline", rc);
+ goto error;
+ }
+
+ return 0;
+
+error:
+ if (driver) {
+ gigaset_freedriver(driver);
+ driver = NULL;
+ }
+ platform_driver_unregister(&device_driver);
+ return rc;
+}
+
+static void __exit ser_gigaset_exit(void)
+{
+ int rc;
+
+ gig_dbg(DEBUG_INIT, "%s", __func__);
+
+ if (driver) {
+ gigaset_freedriver(driver);
+ driver = NULL;
+ }
+
+ if ((rc = tty_unregister_ldisc(N_GIGASET_M101)) != 0)
+ err("error %d unregistering line discipline", rc);
+
+ platform_driver_unregister(&device_driver);
+}
+
+module_init(ser_gigaset_init);
+module_exit(ser_gigaset_exit);
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
index ddd47cdfdb1f..1e2d38e3d68c 100644
--- a/drivers/isdn/hardware/avm/b1dma.c
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -29,7 +29,7 @@
static char *revision = "$Revision: 1.1.2.3 $";
-#undef CONFIG_B1DMA_DEBUG
+#undef AVM_B1DMA_DEBUG
/* ------------------------------------------------------------- */
@@ -391,16 +391,16 @@ static void b1dma_dispatch_tx(avmcard *card)
_put_slice(&p, skb->data, len);
}
txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf;
-#ifdef CONFIG_B1DMA_DEBUG
+#ifdef AVM_B1DMA_DEBUG
printk(KERN_DEBUG "tx: put msg len=%d\n", txlen);
#endif
} else {
txlen = skb->len-2;
-#ifdef CONFIG_B1DMA_POLLDEBUG
+#ifdef AVM_B1DMA_POLLDEBUG
if (skb->data[2] == SEND_POLLACK)
printk(KERN_INFO "%s: send ack\n", card->name);
#endif
-#ifdef CONFIG_B1DMA_DEBUG
+#ifdef AVM_B1DMA_DEBUG
printk(KERN_DEBUG "tx: put 0x%x len=%d\n",
skb->data[2], txlen);
#endif
@@ -450,7 +450,7 @@ static void b1dma_handle_rx(avmcard *card)
u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
u8 b1cmd = _get_byte(&p);
-#ifdef CONFIG_B1DMA_DEBUG
+#ifdef AVM_B1DMA_DEBUG
printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen);
#endif
@@ -515,7 +515,7 @@ static void b1dma_handle_rx(avmcard *card)
break;
case RECEIVE_START:
-#ifdef CONFIG_B1DMA_POLLDEBUG
+#ifdef AVM_B1DMA_POLLDEBUG
printk(KERN_INFO "%s: receive poll\n", card->name);
#endif
if (!suppress_pollack)
@@ -601,7 +601,7 @@ static void b1dma_handle_interrupt(avmcard *card)
rxlen = (dma->recvlen + 3) & ~3;
b1dma_writel(card, dma->recvbuf.dmaaddr+4, AMCC_RXPTR);
b1dma_writel(card, rxlen, AMCC_RXLEN);
-#ifdef CONFIG_B1DMA_DEBUG
+#ifdef AVM_B1DMA_DEBUG
} else {
printk(KERN_ERR "%s: rx not complete (%d).\n",
card->name, rxlen);
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index 2a3eb38f0ebb..6f5efa8d78cb 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -28,8 +28,8 @@
#include <linux/isdn/capilli.h>
#include "avmcard.h"
-#undef CONFIG_C4_DEBUG
-#undef CONFIG_C4_POLLDEBUG
+#undef AVM_C4_DEBUG
+#undef AVM_C4_POLLDEBUG
/* ------------------------------------------------------------- */
@@ -420,7 +420,7 @@ static void c4_dispatch_tx(avmcard *card)
skb = skb_dequeue(&dma->send_queue);
if (!skb) {
-#ifdef CONFIG_C4_DEBUG
+#ifdef AVM_C4_DEBUG
printk(KERN_DEBUG "%s: tx underrun\n", card->name);
#endif
return;
@@ -444,16 +444,16 @@ static void c4_dispatch_tx(avmcard *card)
_put_slice(&p, skb->data, len);
}
txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf;
-#ifdef CONFIG_C4_DEBUG
+#ifdef AVM_C4_DEBUG
printk(KERN_DEBUG "%s: tx put msg len=%d\n", card->name, txlen);
#endif
} else {
txlen = skb->len-2;
-#ifdef CONFIG_C4_POLLDEBUG
+#ifdef AVM_C4_POLLDEBUG
if (skb->data[2] == SEND_POLLACK)
printk(KERN_INFO "%s: ack to c4\n", card->name);
#endif
-#ifdef CONFIG_C4_DEBUG
+#ifdef AVM_C4_DEBUG
printk(KERN_DEBUG "%s: tx put 0x%x len=%d\n",
card->name, skb->data[2], txlen);
#endif
@@ -508,7 +508,7 @@ static void c4_handle_rx(avmcard *card)
u32 cidx;
-#ifdef CONFIG_C4_DEBUG
+#ifdef AVM_C4_DEBUG
printk(KERN_DEBUG "%s: rx 0x%x len=%lu\n", card->name,
b1cmd, (unsigned long)dma->recvlen);
#endif
@@ -586,7 +586,7 @@ static void c4_handle_rx(avmcard *card)
break;
case RECEIVE_START:
-#ifdef CONFIG_C4_POLLDEBUG
+#ifdef AVM_C4_POLLDEBUG
printk(KERN_INFO "%s: poll from c4\n", card->name);
#endif
if (!suppress_pollack)
diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
index 0afd7633556d..ff284aeb8fbb 100644
--- a/drivers/isdn/hardware/eicon/capifunc.c
+++ b/drivers/isdn/hardware/eicon/capifunc.c
@@ -187,7 +187,7 @@ static diva_card *find_card_by_ctrl(word controller)
*/
void *TransmitBufferSet(APPL * appl, dword ref)
{
- appl->xbuffer_used[ref] = TRUE;
+ appl->xbuffer_used[ref] = true;
DBG_PRV1(("%d:xbuf_used(%d)", appl->Id, ref + 1))
return (void *) ref;
}
@@ -202,7 +202,7 @@ void *TransmitBufferGet(APPL * appl, void *p)
void TransmitBufferFree(APPL * appl, void *p)
{
- appl->xbuffer_used[(dword) p] = FALSE;
+ appl->xbuffer_used[(dword) p] = false;
DBG_PRV1(("%d:xbuf_free(%d)", appl->Id, ((dword) p) + 1))
}
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c
index d835e74ecf18..0db9cc661e28 100644
--- a/drivers/isdn/hardware/eicon/debug.c
+++ b/drivers/isdn/hardware/eicon/debug.c
@@ -287,7 +287,7 @@ void* diva_maint_finit (void) {
}
external_dbg_queue = 0;
- for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) {
+ for (i = 1; i < ARRAY_SIZE(clients); i++) {
if (clients[i].pmem) {
diva_os_free (0, clients[i].pmem);
}
@@ -391,7 +391,7 @@ static void DI_register (void *arg) {
diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "register");
- for (id = 1; id < (sizeof(clients)/sizeof(clients[0])); id++) {
+ for (id = 1; id < ARRAY_SIZE(clients); id++) {
if (clients[id].hDbg == hDbg) {
/*
driver already registered
@@ -494,7 +494,7 @@ static void DI_deregister (pDbgHandle hDbg) {
diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "read");
diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read");
- for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) {
+ for (i = 1; i < ARRAY_SIZE(clients); i++) {
if (clients[i].hDbg == hDbg) {
diva_dbg_entry_head_t* pmsg;
char tmp[256];
@@ -736,7 +736,7 @@ int diva_get_driver_info (dword id, byte* data, int data_length) {
int to_copy;
if (!data || !id || (data_length < 17) ||
- (id >= (sizeof(clients)/sizeof(clients[0])))) {
+ (id >= ARRAY_SIZE(clients))) {
return (-1);
}
@@ -786,7 +786,7 @@ int diva_get_driver_dbg_mask (dword id, byte* data) {
diva_os_spin_lock_magic_t old_irql;
int ret = -1;
- if (!data || !id || (id >= (sizeof(clients)/sizeof(clients[0])))) {
+ if (!data || !id || (id >= ARRAY_SIZE(clients))) {
return (-1);
}
diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "driver info");
@@ -809,7 +809,7 @@ int diva_set_driver_dbg_mask (dword id, dword mask) {
int ret = -1;
- if (!id || (id >= (sizeof(clients)/sizeof(clients[0])))) {
+ if (!id || (id >= ARRAY_SIZE(clients))) {
return (-1);
}
@@ -887,7 +887,7 @@ void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) {
diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "register");
diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "register");
- for (id = 1; id < (sizeof(clients)/sizeof(clients[0])); id++) {
+ for (id = 1; id < ARRAY_SIZE(clients); id++) {
if (clients[id].hDbg && (clients[id].request == d->request)) {
diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "register");
diva_os_leave_spin_lock (&dbg_adapter_lock, &old_irql1, "register");
@@ -1037,7 +1037,7 @@ void diva_mnt_remove_xdi_adapter (const DESCRIPTOR* d) {
diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "read");
diva_os_enter_spin_lock (&dbg_q_lock, &old_irql, "read");
- for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) {
+ for (i = 1; i < ARRAY_SIZE(clients); i++) {
if (clients[i].hDbg && (clients[i].request == d->request)) {
diva_dbg_entry_head_t* pmsg;
char tmp[256];
@@ -1115,7 +1115,7 @@ void diva_mnt_remove_xdi_adapter (const DESCRIPTOR* d) {
void* SuperTraceOpenAdapter (int AdapterNumber) {
int i;
- for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) {
+ for (i = 1; i < ARRAY_SIZE(clients); i++) {
if (clients[i].hDbg && clients[i].request && (clients[i].logical == AdapterNumber)) {
return (&clients[i]);
}
@@ -1508,7 +1508,7 @@ static void diva_maint_state_change_notify (void* user_context,
int ch = TraceFilterChannel;
int id = TraceFilterIdent;
- if ((id >= 0) && (ch >= 0) && (id < sizeof(clients)/sizeof(clients[0])) &&
+ if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
(clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
if (ch != (int)modem->ChannelNumber) {
break;
@@ -1555,7 +1555,7 @@ static void diva_maint_state_change_notify (void* user_context,
int ch = TraceFilterChannel;
int id = TraceFilterIdent;
- if ((id >= 0) && (ch >= 0) && (id < sizeof(clients)/sizeof(clients[0])) &&
+ if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
(clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
if (ch != (int)fax->ChannelNumber) {
break;
@@ -1803,7 +1803,7 @@ static void diva_maint_trace_notify (void* user_context,
/*
Selective trace
*/
- if ((id >= 0) && (ch >= 0) && (id < sizeof(clients)/sizeof(clients[0])) &&
+ if ((id >= 0) && (ch >= 0) && (id < ARRAY_SIZE(clients)) &&
(clients[id].Dbg.id == (byte)id) && (clients[id].pIdiLib == hLib)) {
const char* p = NULL;
int ch_value = -1;
@@ -1925,7 +1925,7 @@ int diva_mnt_shutdown_xdi_adapters (void) {
byte * pmem;
- for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) {
+ for (i = 1; i < ARRAY_SIZE(clients); i++) {
pmem = NULL;
diva_os_enter_spin_lock (&dbg_adapter_lock, &old_irql1, "unload");
@@ -2006,7 +2006,7 @@ int diva_set_trace_filter (int filter_length, const char* filter) {
on = (TraceFilter[0] == 0);
- for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) {
+ for (i = 1; i < ARRAY_SIZE(clients); i++) {
if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request) {
client_b_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_BCHANNEL) != 0);
client_atap_on = on && ((clients[i].hDbg->dbgMask & DIVA_MGT_DBG_IFC_AUDIO) != 0);
@@ -2017,7 +2017,7 @@ int diva_set_trace_filter (int filter_length, const char* filter) {
}
}
- for (i = 1; i < (sizeof(clients)/sizeof(clients[0])); i++) {
+ for (i = 1; i < ARRAY_SIZE(clients); i++) {
if (clients[i].hDbg && clients[i].pIdiLib && clients[i].request && clients[i].request_pending) {
diva_os_leave_spin_lock (&dbg_q_lock, &old_irql, "write_filter");
clients[i].request_pending = 0;
diff --git a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c
index e1df8d98c311..ce8df3878908 100644
--- a/drivers/isdn/hardware/eicon/di.c
+++ b/drivers/isdn/hardware/eicon/di.c
@@ -173,16 +173,16 @@ void pr_out(ADAPTER * a)
xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->MInd,
a->IdTypeTable[this->No]);
a->ram_out(a, &ReqOut->Req, this->MInd);
- more = TRUE;
+ more = true;
}
else {
xdi_xlog_request (XDI_A_NR(a), this->Id, this->ReqCh, this->Req,
a->IdTypeTable[this->No]);
this->More |=XMOREF;
a->ram_out(a, &ReqOut->Req, this->Req);
- more = FALSE;
+ more = false;
if (a->FlowControlIdTable[this->ReqCh] == this->Id)
- a->FlowControlSkipTable[this->ReqCh] = TRUE;
+ a->FlowControlSkipTable[this->ReqCh] = true;
/*
Note that remove request was sent to the card
*/
@@ -311,7 +311,7 @@ byte pr_dpc(ADAPTER * a)
/* are marked RNR */
if(RNRId && RNRId==a->ram_in(a, &IndIn->IndId)) {
a->ram_out(a, &IndIn->Ind, 0);
- a->ram_out(a, &IndIn->RNR, TRUE);
+ a->ram_out(a, &IndIn->RNR, true);
}
else {
Ind = a->ram_in(a, &IndIn->Ind);
@@ -331,7 +331,7 @@ byte pr_dpc(ADAPTER * a)
dtrc(dprintf("RNR"));
a->ram_out(a, &IndIn->Ind, 0);
RNRId = a->ram_in(a, &IndIn->IndId);
- a->ram_out(a, &IndIn->RNR, TRUE);
+ a->ram_out(a, &IndIn->RNR, true);
}
}
}
@@ -340,7 +340,7 @@ byte pr_dpc(ADAPTER * a)
}
a->ram_out(a, &PR_RAM->IndOutput, 0);
}
- return FALSE;
+ return false;
}
byte scom_test_int(ADAPTER * a)
{
@@ -399,7 +399,7 @@ byte isdn_rc(ADAPTER * a,
return (0);
}
if (extended_info_type == DIVA_RC_TYPE_REMOVE_COMPLETE)
- a->RcExtensionSupported = TRUE;
+ a->RcExtensionSupported = true;
}
a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_REMOVE_PENDING;
a->misc_flags_table[e_no] &= ~DIVA_MISC_FLAGS_NO_RC_CANCELLING;
@@ -428,7 +428,7 @@ byte isdn_rc(ADAPTER * a,
}
if (Rc==OK_FC) {
a->FlowControlIdTable[Ch] = Id;
- a->FlowControlSkipTable[Ch] = FALSE;
+ a->FlowControlSkipTable[Ch] = false;
this->Rc = Rc;
this->More &= ~(XBUSY | XMOREC);
this->complete=0xff;
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
index 77155d9f399b..6b2940ed0776 100644
--- a/drivers/isdn/hardware/eicon/divamnt.c
+++ b/drivers/isdn/hardware/eicon/divamnt.c
@@ -164,7 +164,7 @@ static ssize_t divas_maint_read(struct file *file, char __user *buf,
return (maint_read_write(buf, (int) count));
}
-static struct file_operations divas_maint_fops = {
+static const struct file_operations divas_maint_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = divas_maint_read,
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index fff0d89c806b..556b19615bc7 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -131,7 +131,7 @@ static void remove_um_idi_proc(void)
}
}
-static struct file_operations divas_idi_fops = {
+static const struct file_operations divas_idi_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = um_idi_read,
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index 91fc92c01afe..b365e44072c0 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -663,7 +663,7 @@ static unsigned int divas_poll(struct file *file, poll_table * wait)
return (POLLIN | POLLRDNORM);
}
-static struct file_operations divas_fops = {
+static const struct file_operations divas_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = divas_read,
diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c
index 6a4373a4f1e8..0632a2606998 100644
--- a/drivers/isdn/hardware/eicon/divasproc.c
+++ b/drivers/isdn/hardware/eicon/divasproc.c
@@ -113,7 +113,7 @@ static int divas_close(struct inode *inode, struct file *file)
return (0);
}
-static struct file_operations divas_fops = {
+static const struct file_operations divas_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = divas_read,
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index f9b00f19afd2..784232a144c8 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -253,7 +253,7 @@ extern APPL * application;
-static byte remove_started = FALSE;
+static byte remove_started = false;
static PLCI dummy_plci;
@@ -456,12 +456,12 @@ word api_put(APPL * appl, CAPI_MSG * msg)
return _QUEUE_FULL;
}
- c = FALSE;
+ c = false;
if ((((byte *) msg) < ((byte *)(plci->msg_in_queue)))
|| (((byte *) msg) >= ((byte *)(plci->msg_in_queue)) + sizeof(plci->msg_in_queue)))
{
if (plci->msg_in_write_pos != plci->msg_in_read_pos)
- c = TRUE;
+ c = true;
}
if (msg->header.command == _DATA_B3_R)
{
@@ -506,13 +506,13 @@ word api_put(APPL * appl, CAPI_MSG * msg)
return _QUEUE_FULL;
}
- c = TRUE;
+ c = true;
}
}
else
{
if (plci->req_in || plci->internal_command)
- c = TRUE;
+ c = true;
else
{
plci->command = msg->header.command;
@@ -626,10 +626,10 @@ word api_parse(byte * msg, word length, byte * format, API_PARSE * parms)
break;
}
- if(p>length) return TRUE;
+ if(p>length) return true;
}
if(parms) parms[i].info = NULL;
- return FALSE;
+ return false;
}
void api_save_msg(API_PARSE *in, byte *format, API_SAVE *out)
@@ -687,7 +687,7 @@ word api_remove_start(void)
word j;
if(!remove_started) {
- remove_started = TRUE;
+ remove_started = true;
for(i=0;i<max_adapter;i++) {
if(adapter[i].request) {
for(j=0;j<adapter[i].max_plci;j++) {
@@ -1080,7 +1080,7 @@ static void plci_remove(PLCI * plci)
send_req(plci);
}
}
- ncci_remove (plci, 0, FALSE);
+ ncci_remove (plci, 0, false);
plci_free_msg_in_queue (plci);
plci->channels = 0;
@@ -1226,7 +1226,7 @@ byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
Id = ((word)1<<8)|a->Id;
sendf(appl,_CONNECT_R|CONFIRM,Id,Number,"w",0);
sendf(appl, _DISCONNECT_I, Id, 0, "w", _L1_ERROR);
- return FALSE;
+ return false;
}
Info = _OUT_OF_PLCI;
if((i=get_plci(a)))
@@ -1330,7 +1330,7 @@ byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
plci->command = _CONNECT_R;
plci->number = Number;
/* x.31 or D-ch free SAPI in LinkLayer? */
- if(ch==1 && LinkLayer!=3 && LinkLayer!=12) noCh = TRUE;
+ if(ch==1 && LinkLayer!=3 && LinkLayer!=12) noCh = true;
if((ch==0 || ch==2 || noCh || ch==3 || ch==4) && !Info)
{
/* B-channel used for B3 connections (ch==0), or no B channel */
@@ -1381,7 +1381,7 @@ byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
plci->command = 0;
dbug(1,dprintf("Spoof"));
send_req(plci);
- return FALSE;
+ return false;
}
if(ch==4)add_p(plci,CHI,p_chi);
add_s(plci,CPN,&parms[1]);
@@ -1395,11 +1395,11 @@ byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
plci->appl = appl;
sig_req(plci,LISTEN_REQ,0);
send_req(plci);
- return FALSE;
+ return false;
}
}
send_req(plci);
- return FALSE;
+ return false;
}
plci->Id = 0;
}
@@ -1571,7 +1571,7 @@ byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
{
dbug(1,dprintf("connect_a_res"));
- return FALSE;
+ return false;
}
byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
@@ -1624,9 +1624,9 @@ byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
}
}
- if(!appl) return FALSE;
+ if(!appl) return false;
sendf(appl, _DISCONNECT_R|CONFIRM, Id, Number, "w",Info);
- return FALSE;
+ return false;
}
byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
@@ -1702,7 +1702,7 @@ byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, A
"w",Info);
if (a) listen_check(a);
- return FALSE;
+ return false;
}
byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
@@ -1739,7 +1739,7 @@ byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APP
add_s(plci,KEY,&ai_parms[1]);
sig_req(plci,INFO_REQ,0);
send_req(plci);
- return FALSE;
+ return false;
}
if(plci->State && ai_parms[2].length)
@@ -1769,7 +1769,7 @@ byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APP
if((i=get_plci(a)))
{
rc_plci = &a->plci[i-1];
- appl->NullCREnable = TRUE;
+ appl->NullCREnable = true;
rc_plci->internal_command = C_NCR_FAC_REQ;
rc_plci->appl = appl;
add_p(rc_plci,CAI,"\x01\x80");
@@ -1788,7 +1788,7 @@ byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APP
add_ai(rc_plci, &msg[1]);
sig_req(rc_plci,NCR_FACILITY,0);
send_req(rc_plci);
- return FALSE;
+ return false;
/* for application controlled supplementary services */
}
}
@@ -1811,13 +1811,13 @@ byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APP
Number,
"w",Info);
}
- return FALSE;
+ return false;
}
byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
{
dbug(1,dprintf("info_res"));
- return FALSE;
+ return false;
}
byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
@@ -1828,7 +1828,7 @@ byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, AP
dbug(1,dprintf("alert_req"));
Info = _WRONG_IDENTIFIER;
- ret = FALSE;
+ ret = false;
if(plci) {
Info = _ALERT_IGNORED;
if(plci->State!=INC_CON_ALERT) {
@@ -1922,7 +1922,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
rplci->appl = appl;
sig_req(rplci,S_SUPPORTED,0);
send_req(rplci);
- return FALSE;
+ return false;
break;
case S_LISTEN:
@@ -1972,7 +1972,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
add_s(plci,CAI,&ss_parms[1]);
sig_req(plci,CALL_HOLD,0);
send_req(plci);
- return FALSE;
+ return false;
}
else Info = 0x3010; /* wrong state */
break;
@@ -1997,13 +1997,13 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
plci->internal_command = BLOCK_PLCI;
plci->command = 0;
dbug(1,dprintf("Spoof"));
- return FALSE;
+ return false;
}
else
{
sig_req(plci,CALL_RETRIEVE,0);
send_req(plci);
- return FALSE;
+ return false;
}
}
else Info = 0x3010; /* wrong state */
@@ -2123,7 +2123,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
add_p(plci,CAI,cai);
sig_req(plci,S_SERVICE,0);
send_req(plci);
- return FALSE;
+ return false;
}
else Info = 0x3010; /* wrong state */
break;
@@ -2265,7 +2265,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
add_p(rplci,CAI,cai);
sig_req(rplci,S_SERVICE,0);
send_req(rplci);
- return FALSE;
+ return false;
}
else
{
@@ -2291,14 +2291,14 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
ss_parms[3].info[3] = (byte)GET_WORD(&(ss_parms[2].info[0]));
plci->command = 0;
plci->internal_command = CD_REQ_PEND;
- appl->CDEnable = TRUE;
+ appl->CDEnable = true;
cai[0] = 1;
cai[1] = CALL_DEFLECTION;
add_p(plci,CAI,cai);
add_p(plci,CPN,ss_parms[3].info);
sig_req(plci,S_SERVICE,0);
send_req(plci);
- return FALSE;
+ return false;
break;
case S_CALL_FORWARDING_START:
@@ -2337,7 +2337,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
add_p(rplci,CPN,ss_parms[6].info);
sig_req(rplci,S_SERVICE,0);
send_req(rplci);
- return FALSE;
+ return false;
break;
case S_INTERROGATE_DIVERSION:
@@ -2456,7 +2456,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
sig_req(rplci,S_SERVICE,0);
send_req(rplci);
- return FALSE;
+ return false;
break;
case S_MWI_ACTIVATE:
@@ -2472,7 +2472,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
{
rplci = &a->plci[i-1];
rplci->appl = appl;
- rplci->cr_enquiry=TRUE;
+ rplci->cr_enquiry=true;
add_p(rplci,CAI,"\x01\x80");
add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
sig_req(rplci,ASSIGN,DSIG_ID);
@@ -2487,7 +2487,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
else
{
rplci = plci;
- rplci->cr_enquiry=FALSE;
+ rplci->cr_enquiry=false;
}
rplci->command = 0;
@@ -2509,7 +2509,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
add_p(rplci,UID,ss_parms[10].info); /* Time */
sig_req(rplci,S_SERVICE,0);
send_req(rplci);
- return FALSE;
+ return false;
case S_MWI_DEACTIVATE:
if(api_parse(&parms->info[1],(word)parms->length,"wbwwss",ss_parms))
@@ -2524,7 +2524,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
{
rplci = &a->plci[i-1];
rplci->appl = appl;
- rplci->cr_enquiry=TRUE;
+ rplci->cr_enquiry=true;
add_p(rplci,CAI,"\x01\x80");
add_p(rplci,UID,"\x06\x43\x61\x70\x69\x32\x30");
sig_req(rplci,ASSIGN,DSIG_ID);
@@ -2539,7 +2539,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
else
{
rplci = plci;
- rplci->cr_enquiry=FALSE;
+ rplci->cr_enquiry=false;
}
rplci->command = 0;
@@ -2556,7 +2556,7 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
add_p(rplci,OAD,ss_parms[5].info); /* Controlling User Number */
sig_req(rplci,S_SERVICE,0);
send_req(rplci);
- return FALSE;
+ return false;
default:
Info = 0x300E; /* not supported */
@@ -2597,13 +2597,13 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
Id,
Number,
"wws",Info,selector,SSparms);
- return FALSE;
+ return false;
}
byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
{
dbug(1,dprintf("facility_res"));
- return FALSE;
+ return false;
}
byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -2649,7 +2649,7 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
Id,
Number,
"w",Info);
- return FALSE;
+ return false;
}
plci->requested_options_conn = 0;
@@ -2684,7 +2684,7 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
|| (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS))
{
len = (byte)(&(((T30_INFO *) 0)->universal_6));
- fax_info_change = FALSE;
+ fax_info_change = false;
if (ncpi->length >= 4)
{
w = GET_WORD(&ncpi->info[3]);
@@ -2693,7 +2693,7 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
((T30_INFO *)(plci->fax_connect_info_buffer))->resolution =
(byte)((((T30_INFO *)(plci->fax_connect_info_buffer))->resolution & ~T30_RESOLUTION_R8_0770_OR_200) |
((w & 0x0001) ? T30_RESOLUTION_R8_0770_OR_200 : 0));
- fax_info_change = TRUE;
+ fax_info_change = true;
}
fax_control_bits &= ~(T30_CONTROL_BIT_REQUEST_POLLING | T30_CONTROL_BIT_MORE_DOCUMENTS);
if (w & 0x0002) /* Fax-polling request */
@@ -2709,7 +2709,7 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
if (((byte) w) != ((T30_INFO *)(plci->fax_connect_info_buffer))->data_format)
{
((T30_INFO *)(plci->fax_connect_info_buffer))->data_format = (byte) w;
- fax_info_change = TRUE;
+ fax_info_change = true;
}
if ((a->man_profile.private_options & (1L << PRIVATE_FAX_SUB_SEP_PWD))
@@ -2781,13 +2781,13 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
{
len = (byte)(&(((T30_INFO *) 0)->universal_6));
}
- fax_info_change = TRUE;
+ fax_info_change = true;
}
if (fax_control_bits != GET_WORD(&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low))
{
PUT_WORD (&((T30_INFO *)plci->fax_connect_info_buffer)->control_bits_low, fax_control_bits);
- fax_info_change = TRUE;
+ fax_info_change = true;
}
}
if (Info == GOOD)
@@ -2798,12 +2798,12 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
if (fax_feature_bits & T30_FEATURE_BIT_MORE_DOCUMENTS)
{
start_internal_command (Id, plci, fax_connect_info_command);
- return FALSE;
+ return false;
}
else
{
start_internal_command (Id, plci, fax_adjust_b23_command);
- return FALSE;
+ return false;
}
}
}
@@ -2820,7 +2820,7 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
for (w = 0; w < ncpi->length; w++)
plci->internal_req_buffer[2+w] = ncpi->info[1+w];
start_internal_command (Id, plci, rtp_connect_b3_req_command);
- return FALSE;
+ return false;
}
if(!Info)
@@ -2837,7 +2837,7 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
Id,
Number,
"w",Info);
- return FALSE;
+ return false;
}
byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -2909,7 +2909,7 @@ byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
plci->fax_connect_info_length = len;
((T30_INFO *)(plci->fax_connect_info_buffer))->code = 0;
start_internal_command (Id, plci, fax_connect_ack_command);
- return FALSE;
+ return false;
}
}
@@ -2932,7 +2932,7 @@ byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
for (w = 0; w < ncpi->length; w++)
plci->internal_req_buffer[2+w] = ncpi->info[1+w];
start_internal_command (Id, plci, rtp_connect_b3_res_command);
- return FALSE;
+ return false;
}
else
@@ -2945,14 +2945,14 @@ byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
sendf(appl,_CONNECT_B3_ACTIVE_I,Id,0,"s","");
if (plci->adjust_b_restore)
{
- plci->adjust_b_restore = FALSE;
+ plci->adjust_b_restore = false;
start_internal_command (Id, plci, adjust_b_restore);
}
}
return 1;
}
}
- return FALSE;
+ return false;
}
byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -2972,7 +2972,7 @@ byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
channel_xmit_xon (plci);
}
}
- return FALSE;
+ return false;
}
byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -3004,7 +3004,7 @@ byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI *
{
plci->send_disc = (byte)ncci;
plci->command = 0;
- return FALSE;
+ return false;
}
else
{
@@ -3028,7 +3028,7 @@ byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI *
Id,
Number,
"w",Info);
- return FALSE;
+ return false;
}
byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -3084,7 +3084,7 @@ byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI *
}
}
}
- return FALSE;
+ return false;
}
byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -3140,7 +3140,7 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
}
send_data(plci);
- return FALSE;
+ return false;
}
}
if (appl)
@@ -3161,7 +3161,7 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
Number,
"ww",GET_WORD(parms[2].info),Info);
}
- return FALSE;
+ return false;
}
byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -3194,7 +3194,7 @@ byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
}
}
}
- return FALSE;
+ return false;
}
byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -3235,7 +3235,7 @@ byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
Id,
Number,
"w",Info);
- return FALSE;
+ return false;
}
byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -3254,12 +3254,12 @@ byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
{
a->ncci_state[ncci] = CONNECTED;
nl_req_ncci(plci,N_RESET_ACK,(byte)ncci);
- return TRUE;
+ return true;
}
break;
}
}
- return FALSE;
+ return false;
}
byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -3292,7 +3292,7 @@ byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI
return 1;
}
}
- return FALSE;
+ return false;
}
@@ -3378,7 +3378,7 @@ byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
plci->internal_command = BLOCK_PLCI; /* lock other commands */
plci->command = 0;
dbug(1,dprintf("continue if codec loaded"));
- return FALSE;
+ return false;
}
}
}
@@ -3407,12 +3407,12 @@ byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
else if (plci->call_dir & CALL_DIR_IN)
plci->call_dir = CALL_DIR_IN | CALL_DIR_ANSWER;
start_internal_command (Id, plci, select_b_command);
- return FALSE;
+ return false;
}
}
}
sendf(appl, _SELECT_B_REQ|CONFIRM, Id, Number, "w", Info);
- return FALSE;
+ return false;
}
byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
@@ -3489,7 +3489,7 @@ byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
}
plci->State = LOCAL_CONNECT;
- plci->manufacturer = TRUE;
+ plci->manufacturer = true;
plci->command = _MANUFACTURER_R;
plci->m_command = command;
plci->number = Number;
@@ -3520,7 +3520,7 @@ byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
plci->internal_command = BLOCK_PLCI; /* reject other req meanwhile */
plci->command = 0;
send_req(plci);
- return FALSE;
+ return false;
}
if(dir==1) {
sig_req(plci,CALL_REQ,0);
@@ -3573,7 +3573,7 @@ byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
}
else if(req==LAW_REQ)
{
- plci->cr_enquiry = TRUE;
+ plci->cr_enquiry = true;
}
add_ss(plci,FTY,&m_parms[1]);
sig_req(plci,req,0);
@@ -3739,7 +3739,7 @@ byte manufacturer_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
Id,
Number,
"dww",_DI_MANU_ID,command,Info);
- return FALSE;
+ return false;
}
@@ -3760,7 +3760,7 @@ byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
|| (msg[1].length == 0)
|| (GET_DWORD(msg[0].info)!=_DI_MANU_ID))
{
- return FALSE;
+ return false;
}
indication = GET_WORD(msg[1].info);
switch (indication)
@@ -3811,7 +3811,7 @@ byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
break;
}
- return FALSE;
+ return false;
}
/*------------------------------------------------------------------*/
@@ -3908,14 +3908,14 @@ void callback(ENTITY * e)
plci->nl_req = 0;
}
if (plci->nl_req)
- control_rc (plci, 0, rc, ch, 0, TRUE);
+ control_rc (plci, 0, rc, ch, 0, true);
else
{
if (req == N_XON)
{
channel_x_on (plci, ch);
if (plci->internal_command)
- control_rc (plci, req, rc, ch, 0, TRUE);
+ control_rc (plci, req, rc, ch, 0, true);
}
else
{
@@ -3931,21 +3931,21 @@ void callback(ENTITY * e)
}
}
channel_xmit_xon (plci);
- control_rc (plci, 0, rc, ch, global_req, TRUE);
+ control_rc (plci, 0, rc, ch, global_req, true);
}
else if (plci->data_sent)
{
channel_xmit_xon (plci);
- plci->data_sent = FALSE;
+ plci->data_sent = false;
plci->NL.XNum = 1;
data_rc (plci, ch);
if (plci->internal_command)
- control_rc (plci, req, rc, ch, 0, TRUE);
+ control_rc (plci, req, rc, ch, 0, true);
}
else
{
channel_xmit_xon (plci);
- control_rc (plci, req, rc, ch, 0, TRUE);
+ control_rc (plci, req, rc, ch, 0, true);
}
}
}
@@ -3974,12 +3974,12 @@ void callback(ENTITY * e)
if (rc != ASSIGN_OK)
e->Id = 0;
channel_xmit_xon (plci);
- control_rc (plci, 0, rc, ch, global_req, FALSE);
+ control_rc (plci, 0, rc, ch, global_req, false);
}
else
{
channel_xmit_xon (plci);
- control_rc (plci, req, rc, ch, 0, FALSE);
+ control_rc (plci, req, rc, ch, 0, false);
}
}
/*
@@ -4065,8 +4065,8 @@ capi_callback_suffix:
if (plci->li_notify_update)
{
- plci->li_notify_update = FALSE;
- mixer_notify_update (plci, FALSE);
+ plci->li_notify_update = false;
+ mixer_notify_update (plci, false);
}
}
@@ -4428,7 +4428,7 @@ void control_rc(PLCI * plci, byte req, byte rc, byte ch, byte global_req, byte
else
{
sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE);
- appl->NullCREnable = FALSE;
+ appl->NullCREnable = false;
plci_remove(plci);
}
}
@@ -4441,7 +4441,7 @@ void control_rc(PLCI * plci, byte req, byte rc, byte ch, byte global_req, byte
else
{
sendf(appl,_INFO_R|CONFIRM,Id&0xf,Number,"w",_WRONG_STATE);
- appl->NullCREnable = FALSE;
+ appl->NullCREnable = false;
}
plci_remove(plci);
}
@@ -4862,7 +4862,7 @@ void sig_ind(PLCI * plci)
byte CF_Ind[] = "\x09\x02\x00\x06\x00\x00\x00\x00\x00\x00";
byte Interr_Err_Ind[] = "\x0a\x02\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
byte CONF_Ind[] = "\x09\x16\x00\x06\x00\x00\0x00\0x00\0x00\0x00";
- byte force_mt_info = FALSE;
+ byte force_mt_info = false;
byte dir;
dword d;
word w;
@@ -4933,7 +4933,7 @@ void sig_ind(PLCI * plci)
{
if(plci->cr_enquiry && plci->appl)
{
- plci->cr_enquiry = FALSE;
+ plci->cr_enquiry = false;
/* d = MANU_ID */
/* w = m_command */
/* b = total length */
@@ -5158,7 +5158,7 @@ void sig_ind(PLCI * plci)
if(application[i].CDEnable)
{
if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind);
- application[i].CDEnable = FALSE;
+ application[i].CDEnable = false;
}
}
break;
@@ -5375,7 +5375,7 @@ void sig_ind(PLCI * plci)
if(application[i].CDEnable)
{
if(application[i].Id) sendf(&application[i],_FACILITY_I,Id,0,"ws",3, SS_Ind);
- application[i].CDEnable = FALSE;
+ application[i].CDEnable = false;
}
}
break;
@@ -5730,7 +5730,7 @@ void sig_ind(PLCI * plci)
plci,
Id,
parms,
- SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, TRUE));
+ SendMultiIE(plci,Id,multi_pi_parms, PI, 0x210, true));
}
}
clear_c_ind_mask_bit (plci, MAX_APPL);
@@ -6117,38 +6117,38 @@ static void SendSetupInfo(APPL * appl, PLCI * plci, dword Id, byte * * par
dbug(1,dprintf("CPN "));
Info_Number = 0x0070;
Info_Mask = 0x80;
- Info_Sent_Flag = TRUE;
+ Info_Sent_Flag = true;
break;
case 8: /* display */
dbug(1,dprintf("display(%d)",i));
Info_Number = 0x0028;
Info_Mask = 0x04;
- Info_Sent_Flag = TRUE;
+ Info_Sent_Flag = true;
break;
case 16: /* Channel Id */
dbug(1,dprintf("CHI"));
Info_Number = 0x0018;
Info_Mask = 0x100;
- Info_Sent_Flag = TRUE;
+ Info_Sent_Flag = true;
mixer_set_bchannel_id (plci, Info_Element);
break;
case 19: /* Redirected Number */
dbug(1,dprintf("RDN"));
Info_Number = 0x0074;
Info_Mask = 0x400;
- Info_Sent_Flag = TRUE;
+ Info_Sent_Flag = true;
break;
case 20: /* Redirected Number extended */
dbug(1,dprintf("RDX"));
Info_Number = 0x0073;
Info_Mask = 0x400;
- Info_Sent_Flag = TRUE;
+ Info_Sent_Flag = true;
break;
case 22: /* Redirecing Number */
dbug(1,dprintf("RIN"));
Info_Number = 0x0076;
Info_Mask = 0x400;
- Info_Sent_Flag = TRUE;
+ Info_Sent_Flag = true;
break;
default:
Info_Number = 0;
@@ -6312,7 +6312,7 @@ void SendInfo(PLCI * plci, dword Id, byte * * parms, byte iesent)
&& plci->adapter->Info_Mask[appl->Id-1] &Info_Mask)
{
dbug(1,dprintf("NCR_Ind"));
- iesent=TRUE;
+ iesent=true;
sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element);
}
}
@@ -6330,7 +6330,7 @@ void SendInfo(PLCI * plci, dword Id, byte * * parms, byte iesent)
if(test_c_ind_mask_bit (plci, j))
{
dbug(1,dprintf("Ovl_Ind"));
- iesent=TRUE;
+ iesent=true;
sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element);
}
}
@@ -6340,7 +6340,7 @@ void SendInfo(PLCI * plci, dword Id, byte * * parms, byte iesent)
&& plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask)
{
dbug(1,dprintf("Std_Ind"));
- iesent=TRUE;
+ iesent=true;
sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element);
}
}
@@ -6391,7 +6391,7 @@ byte SendMultiIE(PLCI * plci, dword Id, byte * * parms, byte ie_type, dword
&& appl->Id
&& plci->adapter->Info_Mask[appl->Id-1] &Info_Mask)
{
- iesent = TRUE;
+ iesent = true;
dbug(1,dprintf("Mlt_NCR_Ind"));
sendf(&application[j],_INFO_I,Id&0x0f,0,"wS",Info_Number,Info_Element);
}
@@ -6403,7 +6403,7 @@ byte SendMultiIE(PLCI * plci, dword Id, byte * * parms, byte ie_type, dword
{
if(test_c_ind_mask_bit (plci, j))
{
- iesent = TRUE;
+ iesent = true;
dbug(1,dprintf("Mlt_Ovl_Ind"));
sendf(&application[j],_INFO_I,Id,0,"wS",Info_Number,Info_Element);
}
@@ -6412,7 +6412,7 @@ byte SendMultiIE(PLCI * plci, dword Id, byte * * parms, byte ie_type, dword
else if(Info_Number
&& plci->adapter->Info_Mask[plci->appl->Id-1] &Info_Mask)
{
- iesent = TRUE;
+ iesent = true;
dbug(1,dprintf("Mlt_Std_Ind"));
sendf(plci->appl,_INFO_I,Id,0,"wS",Info_Number,Info_Element);
}
@@ -6812,7 +6812,7 @@ void nl_ind(PLCI * plci)
}
if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
{
- if (((T30_INFO *)plci->NL.RBuffer->P)->code < sizeof(fax_info) / sizeof(fax_info[0]))
+ if (((T30_INFO *)plci->NL.RBuffer->P)->code < ARRAY_SIZE(fax_info))
info = fax_info[((T30_INFO *)plci->NL.RBuffer->P)->code];
else
info = _FAX_PROTOCOL_ERROR;
@@ -6887,7 +6887,7 @@ void nl_ind(PLCI * plci)
(byte)(plci->ncpi_buffer[0] + 1), plci->ncpi_buffer);
plci->ncpi_state |= NCPI_NEGOTIATE_B3_SENT;
if (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)
- fax_send_edata_ack = FALSE;
+ fax_send_edata_ack = false;
}
if (a->manufacturer_features & MANUFACTURER_FEATURE_FAX_PAPER_FORMATS)
@@ -6928,7 +6928,7 @@ void nl_ind(PLCI * plci)
sendf(plci->appl,_DISCONNECT_B3_I,Id,0,"wS",GOOD,plci->ncpi_buffer);
a->ncci_state[ncci] = INC_DIS_PENDING;
plci->ncpi_state = 0;
- fax_send_edata_ack = FALSE;
+ fax_send_edata_ack = false;
}
break;
}
@@ -7025,7 +7025,7 @@ void nl_ind(PLCI * plci)
}
if (plci->adjust_b_restore)
{
- plci->adjust_b_restore = FALSE;
+ plci->adjust_b_restore = false;
start_internal_command (Id, plci, adjust_b_restore);
}
break;
@@ -7041,7 +7041,7 @@ void nl_ind(PLCI * plci)
next_internal_command (Id, plci);
}
ncci_state = a->ncci_state[ncci];
- ncci_remove (plci, ncci, FALSE);
+ ncci_remove (plci, ncci, false);
/* with N_DISC or N_DISC_ACK the IDI frees the respective */
/* channel, so we cannot store the state in ncci_state! The */
@@ -7288,18 +7288,18 @@ word get_plci(DIVA_CAPI_ADAPTER * a)
plci->msg_in_read_pos = MSG_IN_QUEUE_SIZE;
plci->msg_in_wrap_pos = MSG_IN_QUEUE_SIZE;
- plci->data_sent = FALSE;
+ plci->data_sent = false;
plci->send_disc = 0;
plci->sig_global_req = 0;
plci->sig_remove_id = 0;
plci->nl_global_req = 0;
plci->nl_remove_id = 0;
plci->adv_nl = 0;
- plci->manufacturer = FALSE;
+ plci->manufacturer = false;
plci->call_dir = CALL_DIR_OUT | CALL_DIR_ORIGINATE;
plci->spoofed_msg = 0;
plci->ptyState = 0;
- plci->cr_enquiry = FALSE;
+ plci->cr_enquiry = false;
plci->hangup_flow_ctrl_timer = 0;
plci->ncci_ring_list = 0;
@@ -7972,7 +7972,7 @@ word add_b23(PLCI * plci, API_PARSE * bp)
if(!bp->length && plci->tel)
{
- plci->adv_nl = TRUE;
+ plci->adv_nl = true;
dbug(1,dprintf("Default adv.Nl"));
add_p(plci,LLI,lli);
plci->B2_prot = 1 /*XPARENT*/;
@@ -8022,7 +8022,7 @@ word add_b23(PLCI * plci, API_PARSE * bp)
{
if(GET_WORD(bp_parms[1].info)!=1
|| GET_WORD(bp_parms[2].info)!=0) return _B2_NOT_SUPPORTED;
- plci->adv_nl = TRUE;
+ plci->adv_nl = true;
}
else if(plci->tel) return _B2_NOT_SUPPORTED;
@@ -8840,7 +8840,7 @@ void send_data(PLCI * plci)
plci->NL.X = plci->NData;
plci->NL.ReqCh = a->ncci_ch[ncci];
dbug(1,dprintf("%x:DREQ(%x:%x)",a->Id,plci->NL.Id,plci->NL.Req));
- plci->data_sent = TRUE;
+ plci->data_sent = true;
plci->data_sent_ptr = data->P;
a->request(&plci->NL);
}
@@ -8995,10 +8995,10 @@ void IndParse(PLCI * plci, word * parms_id, byte ** parms, byte multiIEsize)
byte ie_compare(byte * ie1, byte * ie2)
{
word i;
- if(!ie1 || ! ie2) return FALSE;
- if(!ie1[0]) return FALSE;
- for(i=0;i<(word)(ie1[0]+1);i++) if(ie1[i]!=ie2[i]) return FALSE;
- return TRUE;
+ if(!ie1 || ! ie2) return false;
+ if(!ie1[0]) return false;
+ for(i=0;i<(word)(ie1[0]+1);i++) if(ie1[i]!=ie2[i]) return false;
+ return true;
}
word find_cip(DIVA_CAPI_ADAPTER * a, byte * bc, byte * hlc)
@@ -9151,7 +9151,7 @@ word AdvCodecSupport(DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, byte ho
plci->tel=ADV_VOICE;
}
a->AdvSignalAppl = appl;
- a->AdvCodecFLAG = TRUE;
+ a->AdvCodecFLAG = true;
a->AdvCodecPLCI = splci;
add_p(splci,CAI,"\x01\x15");
add_p(splci,LLI,"\x01\x00");
@@ -9183,7 +9183,7 @@ word AdvCodecSupport(DIVA_CAPI_ADAPTER *a, PLCI *plci, APPL *appl, byte ho
add_p(splci,UID,"\x06\x43\x61\x70\x69\x32\x30");
sig_req(splci,ASSIGN,0xC0); /* 0xc0 is the TEL_ID */
send_req(splci);
- a->scom_appl_disable = TRUE;
+ a->scom_appl_disable = true;
}
else{
return 0x2001; /* wrong state, no more plcis */
@@ -9411,7 +9411,7 @@ word CapiRelease(word Id)
}
if(a->AdvSignalAppl==this)
{
- this->NullCREnable = FALSE;
+ this->NullCREnable = false;
if (a->AdvCodecPLCI)
{
plci_remove(a->AdvCodecPLCI);
@@ -9433,7 +9433,7 @@ word CapiRelease(word Id)
static word plci_remove_check(PLCI *plci)
{
- if(!plci) return TRUE;
+ if(!plci) return true;
if(!plci->NL.Id && c_ind_mask_empty (plci))
{
if(plci->Sig.Id == 0xff)
@@ -9446,7 +9446,7 @@ static word plci_remove_check(PLCI *plci)
{
CodecIdCheck(plci->adapter, plci);
clear_b1_config (plci);
- ncci_remove (plci, 0, FALSE);
+ ncci_remove (plci, 0, false);
plci_free_msg_in_queue (plci);
channel_flow_control_remove (plci);
plci->Id = 0;
@@ -9456,10 +9456,10 @@ static word plci_remove_check(PLCI *plci)
plci->notifiedcall = 0;
}
listen_check(plci->adapter);
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
@@ -9564,7 +9564,7 @@ static struct
};
-#define DTMF_DIGIT_MAP_ENTRIES (sizeof(dtmf_digit_map) / sizeof(dtmf_digit_map[0]))
+#define DTMF_DIGIT_MAP_ENTRIES ARRAY_SIZE(dtmf_digit_map)
static void dtmf_enable_receiver (PLCI *plci, byte enable_mask)
@@ -9815,7 +9815,7 @@ static void dtmf_command (dword Id, PLCI *plci, byte Rc)
}
plci->dtmf_rec_active &= ~mask;
plci->internal_command = DTMF_COMMAND_2;
- dtmf_enable_receiver (plci, FALSE);
+ dtmf_enable_receiver (plci, false);
return;
}
Rc = OK;
@@ -10020,7 +10020,7 @@ static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
}
}
start_internal_command (Id, plci, dtmf_command);
- return (FALSE);
+ return (false);
case DTMF_SEND_TONE:
@@ -10069,8 +10069,7 @@ static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
PUT_WORD (&result[1], DTMF_INCORRECT_DIGIT);
break;
}
- if (plci->dtmf_send_requests >=
- sizeof(plci->dtmf_msg_number_queue) / sizeof(plci->dtmf_msg_number_queue[0]))
+ if (plci->dtmf_send_requests >= ARRAY_SIZE(plci->dtmf_msg_number_queue))
{
dbug (1, dprintf ("[%06lx] %s,%d: DTMF request overrun",
UnMapId (Id), (char *)(FILE_), __LINE__));
@@ -10079,7 +10078,7 @@ static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
}
api_save_msg (dtmf_parms, "wwws", &plci->saved_msg);
start_internal_command (Id, plci, dtmf_command);
- return (FALSE);
+ return (false);
default:
dbug (1, dprintf ("[%06lx] %s,%d: DTMF unknown request %04x",
@@ -10090,7 +10089,7 @@ static byte dtmf_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
}
sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
"wws", Info, SELECTOR_DTMF, result);
- return (FALSE);
+ return (false);
}
@@ -10842,10 +10841,10 @@ static struct
byte to_pc;
} xconnect_write_prog[] =
{
- { LI_COEF_CH_CH, FALSE, FALSE },
- { LI_COEF_CH_PC, FALSE, TRUE },
- { LI_COEF_PC_CH, TRUE, FALSE },
- { LI_COEF_PC_PC, TRUE, TRUE }
+ { LI_COEF_CH_CH, false, false },
+ { LI_COEF_CH_PC, false, true },
+ { LI_COEF_PC_CH, true, false },
+ { LI_COEF_PC_PC, true, true }
};
@@ -10916,7 +10915,7 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
{
dbug (1, dprintf ("[%06x] %s,%d: Channel id wiped out",
UnMapId (Id), (char *)(FILE_), __LINE__));
- return (TRUE);
+ return (true);
}
i = a->li_base + (plci->li_bchannel_id - 1);
j = plci->li_write_channel;
@@ -10927,7 +10926,7 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
{
dbug (1, dprintf ("[%06lx] %s,%d: LI write coefs failed %02x",
UnMapId (Id), (char *)(FILE_), __LINE__, Rc));
- return (FALSE);
+ return (false);
}
}
if (li_config_table[i].adapter->manufacturer_features & MANUFACTURER_FEATURE_XCONNECT)
@@ -10969,7 +10968,7 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
{
plci->internal_command = plci->li_write_command;
if (plci_nl_busy (plci))
- return (TRUE);
+ return (true);
to_ch = (a->li_pri) ? plci->li_bchannel_id - 1 : 0;
*(p++) = UDATA_REQUEST_XCONNECT_TO;
do
@@ -11018,9 +11017,9 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
li_config_table[i].coef_table[j] ^= xconnect_write_prog[n].mask << 4;
}
n++;
- } while ((n < sizeof(xconnect_write_prog) / sizeof(xconnect_write_prog[0]))
+ } while ((n < ARRAY_SIZE(xconnect_write_prog))
&& ((p - plci->internal_req_buffer) + 16 < INTERNAL_REQ_BUFFER_SIZE));
- if (n == sizeof(xconnect_write_prog) / sizeof(xconnect_write_prog[0]))
+ if (n == ARRAY_SIZE(xconnect_write_prog))
{
do
{
@@ -11050,7 +11049,7 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
{
plci->internal_command = plci->li_write_command;
if (plci_nl_busy (plci))
- return (TRUE);
+ return (true);
if (a->li_pri)
{
*(p++) = UDATA_REQUEST_SET_MIXER_COEFS_PRI_SYNC;
@@ -11090,7 +11089,7 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
ch_map[j+1] = (byte)(j+1);
}
}
- for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++)
+ for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
{
i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
@@ -11127,7 +11126,7 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
{
plci->internal_command = plci->li_write_command;
if (plci_nl_busy (plci))
- return (TRUE);
+ return (true);
if (j < a->li_base)
j = a->li_base;
if (a->li_pri)
@@ -11140,7 +11139,7 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
w |= MIXER_FEATURE_ENABLE_RX_DATA;
*(p++) = (byte) w;
*(p++) = (byte)(w >> 8);
- for (n = 0; n < sizeof(mixer_write_prog_pri) / sizeof(mixer_write_prog_pri[0]); n++)
+ for (n = 0; n < ARRAY_SIZE(mixer_write_prog_pri); n++)
{
*(p++) = (byte)((plci->li_bchannel_id - 1) | mixer_write_prog_pri[n].line_flags);
for (j = a->li_base; j < a->li_base + MIXER_CHANNELS_PRI; j++)
@@ -11196,7 +11195,7 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
ch_map[j+1] = (byte)(j+1);
}
}
- for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++)
+ for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
{
i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
@@ -11232,7 +11231,7 @@ static byte xconnect_write_coefs_process (dword Id, PLCI *plci, byte Rc)
plci->NL.Req = plci->nl_req = (byte) N_UDATA;
plci->adapter->request (&plci->NL);
}
- return (TRUE);
+ return (true);
}
@@ -11251,7 +11250,7 @@ static void mixer_notify_update (PLCI *plci, byte others)
if (a->profile.Global_Options & GL_LINE_INTERCONNECT_SUPPORTED)
{
if (others)
- plci->li_notify_update = TRUE;
+ plci->li_notify_update = true;
i = 0;
do
{
@@ -11277,7 +11276,7 @@ static void mixer_notify_update (PLCI *plci, byte others)
&& (notify_plci->State)
&& notify_plci->NL.Id && !notify_plci->nl_remove_id)
{
- notify_plci->li_notify_update = TRUE;
+ notify_plci->li_notify_update = true;
((CAPI_MSG *) msg)->header.length = 18;
((CAPI_MSG *) msg)->header.appl_id = notify_plci->appl->Id;
((CAPI_MSG *) msg)->header.command = _FACILITY_R;
@@ -11299,12 +11298,12 @@ static void mixer_notify_update (PLCI *plci, byte others)
(char *)(FILE_), __LINE__,
(dword)((notify_plci->Id << 8) | UnMapController (notify_plci->adapter->Id)), w));
}
- notify_plci->li_notify_update = FALSE;
+ notify_plci->li_notify_update = false;
}
}
} while (others && (notify_plci != NULL));
if (others)
- plci->li_notify_update = FALSE;
+ plci->li_notify_update = false;
}
}
@@ -11318,7 +11317,7 @@ static void mixer_clear_config (PLCI *plci)
(dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
(char *)(FILE_), __LINE__));
- plci->li_notify_update = FALSE;
+ plci->li_notify_update = false;
plci->li_plci_b_write_pos = 0;
plci->li_plci_b_read_pos = 0;
plci->li_plci_b_req_pos = 0;
@@ -12159,7 +12158,7 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
plci_b = li_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
if (plci_b == NULL)
break;
- li_update_connect (Id, a, plci, plci_b_id, TRUE, li_flags);
+ li_update_connect (Id, a, plci, plci_b_id, true, li_flags);
plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_LAST_FLAG;
plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
plci->li_plci_b_write_pos = plci_b_write_pos;
@@ -12188,7 +12187,7 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
plci_b_write_pos = plci->li_plci_b_write_pos;
participant_parms_pos = 0;
result_pos = 7;
- li2_update_connect (Id, a, plci, UnMapId (Id), TRUE, li_flags);
+ li2_update_connect (Id, a, plci, UnMapId (Id), true, li_flags);
while (participant_parms_pos < li_req_parms[1].length)
{
result[result_pos] = 6;
@@ -12224,7 +12223,7 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
plci_b = li2_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
if (plci_b != NULL)
{
- li2_update_connect (Id, a, plci, plci_b_id, TRUE, li_flags);
+ li2_update_connect (Id, a, plci, plci_b_id, true, li_flags);
plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id |
((li_flags & (LI2_FLAG_INTERCONNECT_A_B | LI2_FLAG_INTERCONNECT_B_A |
LI2_FLAG_PCCONNECT_A_B | LI2_FLAG_PCCONNECT_B_A)) ? 0 : LI_PLCI_B_DISC_FLAG);
@@ -12249,13 +12248,13 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
}
mixer_calculate_coefs (a);
plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
- mixer_notify_update (plci, TRUE);
+ mixer_notify_update (plci, true);
sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
"wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
plci->command = 0;
plci->li_cmd = GET_WORD (li_parms[0].info);
start_internal_command (Id, plci, mixer_command);
- return (FALSE);
+ return (false);
case LI_REQ_DISCONNECT:
if (li_parms[1].length == 4)
@@ -12283,7 +12282,7 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
plci_b = li_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[8]);
if (plci_b == NULL)
break;
- li_update_connect (Id, a, plci, plci_b_id, FALSE, 0);
+ li_update_connect (Id, a, plci, plci_b_id, false, 0);
plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG | LI_PLCI_B_LAST_FLAG;
plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
plci->li_plci_b_write_pos = plci_b_write_pos;
@@ -12345,7 +12344,7 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
plci_b = li2_check_plci_b (Id, plci, plci_b_id, plci_b_write_pos, &result[result_pos - 2]);
if (plci_b != NULL)
{
- li2_update_connect (Id, a, plci, plci_b_id, FALSE, 0);
+ li2_update_connect (Id, a, plci, plci_b_id, false, 0);
plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
}
@@ -12368,13 +12367,13 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
}
mixer_calculate_coefs (a);
plci->li_channel_bits = li_config_table[a->li_base + (plci->li_bchannel_id - 1)].channel;
- mixer_notify_update (plci, TRUE);
+ mixer_notify_update (plci, true);
sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
"wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
plci->command = 0;
plci->li_cmd = GET_WORD (li_parms[0].info);
start_internal_command (Id, plci, mixer_command);
- return (FALSE);
+ return (false);
case LI_REQ_SILENT_UPDATE:
if (!plci || !plci->State
@@ -12384,7 +12383,7 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
{
dbug (1, dprintf ("[%06lx] %s,%d: Wrong state",
UnMapId (Id), (char *)(FILE_), __LINE__));
- return (FALSE);
+ return (false);
}
plci_b_write_pos = plci->li_plci_b_write_pos;
if (((plci->li_plci_b_read_pos > plci_b_write_pos) ? plci->li_plci_b_read_pos :
@@ -12392,7 +12391,7 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
{
dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
UnMapId (Id), (char *)(FILE_), __LINE__));
- return (FALSE);
+ return (false);
}
i = (plci_b_write_pos == 0) ? LI_PLCI_B_QUEUE_ENTRIES-1 : plci_b_write_pos - 1;
if ((plci_b_write_pos == plci->li_plci_b_read_pos)
@@ -12408,7 +12407,7 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
plci->command = 0;
plci->li_cmd = GET_WORD (li_parms[0].info);
start_internal_command (Id, plci, mixer_command);
- return (FALSE);
+ return (false);
default:
dbug (1, dprintf ("[%06lx] %s,%d: LI unknown request %04x",
@@ -12418,7 +12417,7 @@ static byte mixer_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI
}
sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
"wwS", Info, SELECTOR_LINE_INTERCONNECT, result);
- return (FALSE);
+ return (false);
}
@@ -12523,7 +12522,7 @@ static void mixer_indication_xconnect_from (dword Id, PLCI *plci, byte *msg,
if (!plci->internal_command)
next_internal_command (Id, plci);
}
- mixer_notify_update (plci, TRUE);
+ mixer_notify_update (plci, true);
}
@@ -12547,12 +12546,12 @@ static byte mixer_notify_source_removed (PLCI *plci, dword plci_b_id)
dbug (1, dprintf ("[%06lx] %s,%d: LI request overrun",
(dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
(char *)(FILE_), __LINE__));
- return (FALSE);
+ return (false);
}
plci->li_plci_b_queue[plci_b_write_pos] = plci_b_id | LI_PLCI_B_DISC_FLAG;
plci_b_write_pos = (plci_b_write_pos == LI_PLCI_B_QUEUE_ENTRIES-1) ? 0 : plci_b_write_pos + 1;
plci->li_plci_b_write_pos = plci_b_write_pos;
- return (TRUE);
+ return (true);
}
@@ -12596,7 +12595,7 @@ static void mixer_remove (PLCI *plci)
}
mixer_clear_config (plci);
mixer_calculate_coefs (a);
- mixer_notify_update (plci, TRUE);
+ mixer_notify_update (plci, true);
}
li_config_table[i].plci = NULL;
plci->li_bchannel_id = 0;
@@ -12883,29 +12882,29 @@ static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *p
case EC_ENABLE_OPERATION:
plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
start_internal_command (Id, plci, ec_command);
- return (FALSE);
+ return (false);
case EC_DISABLE_OPERATION:
plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
LEC_RESET_COEFFICIENTS;
start_internal_command (Id, plci, ec_command);
- return (FALSE);
+ return (false);
case EC_FREEZE_COEFFICIENTS:
plci->ec_idi_options |= LEC_FREEZE_COEFFICIENTS;
start_internal_command (Id, plci, ec_command);
- return (FALSE);
+ return (false);
case EC_RESUME_COEFFICIENT_UPDATE:
plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
start_internal_command (Id, plci, ec_command);
- return (FALSE);
+ return (false);
case EC_RESET_COEFFICIENTS:
plci->ec_idi_options |= LEC_RESET_COEFFICIENTS;
start_internal_command (Id, plci, ec_command);
- return (FALSE);
+ return (false);
default:
dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x",
@@ -12978,14 +12977,14 @@ static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *p
case EC_ENABLE_OPERATION:
plci->ec_idi_options &= ~LEC_FREEZE_COEFFICIENTS;
start_internal_command (Id, plci, ec_command);
- return (FALSE);
+ return (false);
case EC_DISABLE_OPERATION:
plci->ec_idi_options = LEC_ENABLE_ECHO_CANCELLER |
LEC_MANUAL_DISABLE | LEC_ENABLE_NONLINEAR_PROCESSING |
LEC_RESET_COEFFICIENTS;
start_internal_command (Id, plci, ec_command);
- return (FALSE);
+ return (false);
default:
dbug (1, dprintf ("[%06lx] %s,%d: EC unknown request %04x",
@@ -12999,7 +12998,7 @@ static byte ec_request (dword Id, word Number, DIVA_CAPI_ADAPTER *a, PLCI *p
sendf (appl, _FACILITY_R | CONFIRM, Id & 0xffffL, Number,
"wws", Info, (appl->appl_flags & APPL_FLAG_PRIV_EC_SPEC) ?
PRIV_SELECTOR_ECHO_CANCELLER : SELECTOR_ECHO_CANCELLER, result);
- return (FALSE);
+ return (false);
}
@@ -13178,7 +13177,7 @@ static void adv_voice_write_coefs (PLCI *plci, word write_command)
ch_map[j] = (byte)(j + (plci->li_bchannel_id - 1));
ch_map[j+1] = (byte)(j + (2 - plci->li_bchannel_id));
}
- for (n = 0; n < sizeof(mixer_write_prog_bri) / sizeof(mixer_write_prog_bri[0]); n++)
+ for (n = 0; n < ARRAY_SIZE(mixer_write_prog_bri); n++)
{
i = a->li_base + ch_map[mixer_write_prog_bri[n].to_ch];
j = a->li_base + ch_map[mixer_write_prog_bri[n].from_ch];
@@ -13563,7 +13562,7 @@ static void adjust_b_clear (PLCI *plci)
(dword)((plci->Id << 8) | UnMapController (plci->adapter->Id)),
(char *)(FILE_), __LINE__));
- plci->adjust_b_restore = FALSE;
+ plci->adjust_b_restore = false;
}
@@ -13832,7 +13831,7 @@ static word adjust_b_process (dword Id, PLCI *plci, byte Rc)
}
if (plci->adjust_b_mode & ADJUST_B_MODE_USER_CONNECT)
{
- plci->adjust_b_restore = TRUE;
+ plci->adjust_b_restore = true;
break;
}
plci->adjust_b_state = ADJUST_B_CONNECT_1;
@@ -14603,7 +14602,7 @@ static void channel_request_xon (PLCI * plci, byte ch) {
static void channel_xmit_extended_xon (PLCI * plci) {
DIVA_CAPI_ADAPTER * a;
- int max_ch = sizeof(a->ch_flow_control)/sizeof(a->ch_flow_control[0]);
+ int max_ch = ARRAY_SIZE(a->ch_flow_control);
int i, one_requested = 0;
if ((!plci) || (!plci->Id) || ((a = plci->adapter) == 0)) {
@@ -14628,7 +14627,7 @@ static void channel_xmit_extended_xon (PLCI * plci) {
Try to xmit next X_ON
*/
static int find_channel_with_pending_x_on (DIVA_CAPI_ADAPTER * a, PLCI * plci) {
- int max_ch = sizeof(a->ch_flow_control)/sizeof(a->ch_flow_control[0]);
+ int max_ch = ARRAY_SIZE(a->ch_flow_control);
int i;
if (!(plci->adapter->manufacturer_features & MANUFACTURER_FEATURE_XONOFF_FLOW_CONTROL)) {
@@ -14768,19 +14767,19 @@ static void group_optimization(DIVA_CAPI_ADAPTER * a, PLCI * plci)
{
if(application[i].Id && a->CIP_Mask[i] )
{
- for(k=0,busy=FALSE; k<a->max_plci; k++)
+ for(k=0,busy=false; k<a->max_plci; k++)
{
if(a->plci[k].Id)
{
auxplci = &a->plci[k];
if(auxplci->appl == &application[i]) /* application has a busy PLCI */
{
- busy = TRUE;
+ busy = true;
dbug(1,dprintf("Appl 0x%x is busy",i+1));
}
else if(test_c_ind_mask_bit (auxplci, i)) /* application has an incoming call pending */
{
- busy = TRUE;
+ busy = true;
dbug(1,dprintf("Appl 0x%x has inc. call pending",i+1));
}
}
@@ -14791,13 +14790,13 @@ static void group_optimization(DIVA_CAPI_ADAPTER * a, PLCI * plci)
if(j==MAX_CIP_TYPES) /* all groups are in use but group still not found */
{ /* the MAX_CIP_TYPES group enables all calls because of field overflow */
appl_number_group_type[i] = MAX_CIP_TYPES;
- group_found=TRUE;
+ group_found=true;
dbug(1,dprintf("Field overflow appl 0x%x",i+1));
}
else if( (info_mask_group[j]==a->CIP_Mask[i]) && (cip_mask_group[j]==a->Info_Mask[i]) )
{ /* is group already present ? */
appl_number_group_type[i] = j|0x80; /* store the group number for each application */
- group_found=TRUE;
+ group_found=true;
dbug(1,dprintf("Group 0x%x found with appl 0x%x, CIP=0x%lx",appl_number_group_type[i],i+1,info_mask_group[j]));
}
else if(!info_mask_group[j])
@@ -14805,7 +14804,7 @@ static void group_optimization(DIVA_CAPI_ADAPTER * a, PLCI * plci)
appl_number_group_type[i] = j|0x80; /* store the group number for each application */
info_mask_group[j] = a->CIP_Mask[i]; /* store the new CIP mask for the new group */
cip_mask_group[j] = a->Info_Mask[i]; /* store the new Info_Mask for this new group */
- group_found=TRUE;
+ group_found=true;
dbug(1,dprintf("New Group 0x%x established with appl 0x%x, CIP=0x%lx",appl_number_group_type[i],i+1,info_mask_group[j]));
}
}
@@ -14860,7 +14859,7 @@ word CapiRegister(word id)
}
}
- if(appls_found) return TRUE;
+ if(appls_found) return true;
for(i=0; i<max_adapter; i++) /* scan all adapters... */
{
a = &adapter[i];
@@ -14889,7 +14888,7 @@ word CapiRegister(word id)
}
}
}
- return FALSE;
+ return false;
}
/*------------------------------------------------------------------*/
diff --git a/drivers/isdn/hardware/eicon/os_pri.c b/drivers/isdn/hardware/eicon/os_pri.c
index a296a846f296..903356547b79 100644
--- a/drivers/isdn/hardware/eicon/os_pri.c
+++ b/drivers/isdn/hardware/eicon/os_pri.c
@@ -487,7 +487,7 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
}
DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
- IoAdapter->Initialized = TRUE;
+ IoAdapter->Initialized = true;
/*
Check Interrupt
@@ -504,7 +504,7 @@ diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
if (!IoAdapter->IrqCount) {
DBG_ERR(("A: A(%d) interrupt test failed",
IoAdapter->ANum))
- IoAdapter->Initialized = FALSE;
+ IoAdapter->Initialized = false;
IoAdapter->stop(IoAdapter);
return (-1);
}
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
index 2444811e0b38..ff09f07f440a 100644
--- a/drivers/isdn/hardware/eicon/platform.h
+++ b/drivers/isdn/hardware/eicon/platform.h
@@ -71,14 +71,6 @@
#define qword u64
#endif
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
#ifndef NULL
#define NULL ((void *) 0)
#endif
@@ -131,10 +123,6 @@
#define DIVA_OS_MEM_DETACH_CONFIG(a, x) do { } while(0)
#define DIVA_OS_MEM_DETACH_CONTROL(a, x) do { } while(0)
-#if !defined(DIM)
-#define DIM(array) (sizeof (array)/sizeof ((array)[0]))
-#endif
-
#define DIVA_INVALID_FILE_HANDLE ((dword)(-1))
#define DIVAS_CONTAINING_RECORD(address, type, field) \
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 34ab5f7dcabc..12d91fb9f8cb 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -340,8 +340,6 @@ config HISAX_HFC_SX
This enables HiSax support for the HFC-S+, HFC-SP and HFC-PCMCIA
cards. This code is not finished yet.
-# bool ' TESTEMULATOR (EXPERIMENTAL)' CONFIG_HISAX_TESTEMU
-
config HISAX_ENTERNOW_PCI
bool "Formula-n enter:now PCI card"
depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile
index 293e27789d54..c7a3794bdae4 100644
--- a/drivers/isdn/hisax/Makefile
+++ b/drivers/isdn/hisax/Makefile
@@ -60,5 +60,4 @@ hisax-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o isac.o arcofi.o hscx.o
hisax-$(CONFIG_HISAX_GAZEL) += gazel.o isac.o arcofi.o hscx.o
hisax-$(CONFIG_HISAX_W6692) += w6692.o
hisax-$(CONFIG_HISAX_ENTERNOW_PCI) += enternow_pci.o amd7930_fn.o
-#hisax-$(CONFIG_HISAX_TESTEMU) += testemu.o
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index 17ec0b70ba1d..da4196f21e0f 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -549,10 +549,6 @@ extern int setup_isurf(struct IsdnCard *card);
extern int setup_saphir(struct IsdnCard *card);
#endif
-#if CARD_TESTEMU
-extern int setup_testemu(struct IsdnCard *card);
-#endif
-
#if CARD_BKM_A4T
extern int setup_bkm_a4t(struct IsdnCard *card);
#endif
@@ -1061,11 +1057,6 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow
ret = setup_saphir(card);
break;
#endif
-#if CARD_TESTEMU
- case ISDN_CTYPE_TESTEMU:
- ret = setup_testemu(card);
- break;
-#endif
#if CARD_BKM_A4T
case ISDN_CTYPE_BKM_A4T:
ret = setup_bkm_a4t(card);
@@ -1881,7 +1872,7 @@ static struct pci_device_id hisax_pci_tbl[] __devinitdata = {
{PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO, PCI_ANY_ID, PCI_ANY_ID},
{PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_OLITEC, PCI_ANY_ID, PCI_ANY_ID},
#endif
-#ifdef CONFIG_HISAX_QUADRO
+#ifdef CONFIG_HISAX_SCT_QUADRO
{PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_ANY_ID, PCI_ANY_ID},
#endif
#ifdef CONFIG_HISAX_NICCY
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c
index 0279fb323cb1..ae377e812775 100644
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -58,7 +58,7 @@ static inline unsigned int serial_in(struct IsdnCardState *cs, int offset)
static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset)
{
#ifdef SERIAL_DEBUG_REG
-#ifdef CONFIG_SERIAL_NOPAUSE_IO
+#ifdef ELSA_SERIAL_NOPAUSE_IO
u_int val = inb(cs->hw.elsa.base + 8 + offset);
debugl1(cs,"inp %s %02x",ModemIn[offset], val);
#else
@@ -67,7 +67,7 @@ static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset)
#endif
return(val);
#else
-#ifdef CONFIG_SERIAL_NOPAUSE_IO
+#ifdef ELSA_SERIAL_NOPAUSE_IO
return inb(cs->hw.elsa.base + 8 + offset);
#else
return inb_p(cs->hw.elsa.base + 8 + offset);
@@ -87,13 +87,13 @@ static inline void serial_outp(struct IsdnCardState *cs, int offset,
int value)
{
#ifdef SERIAL_DEBUG_REG
-#ifdef CONFIG_SERIAL_NOPAUSE_IO
+#ifdef ELSA_SERIAL_NOPAUSE_IO
debugl1(cs,"outp %s %02x",ModemOut[offset], value);
#else
debugl1(cs,"outP %s %02x",ModemOut[offset], value);
#endif
#endif
-#ifdef CONFIG_SERIAL_NOPAUSE_IO
+#ifdef ELSA_SERIAL_NOPAUSE_IO
outb(value, cs->hw.elsa.base + 8 + offset);
#else
outb_p(value, cs->hw.elsa.base + 8 + offset);
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index a2fa4ecb8c88..ab98e135bcbb 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -199,7 +199,7 @@ typedef struct _hfc4s8s_hw {
/***************************/
/* inline function defines */
/***************************/
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM /* inline functions mempry mapped */
+#ifdef HISAX_HFC4S8S_PCIMEM /* inline functions memory mapped */
/* memory write and dummy IO read to avoid PCI byte merge problems */
#define Write_hfc8(a,b,c) {(*((volatile u_char *)(a->membase+b)) = c); inb(a->iobase+4);}
@@ -305,7 +305,7 @@ wait_busy(hfc4s8s_hw * a)
#define PCI_ENA_REGIO 0x01
-#endif /* CONFIG_HISAX_HFC4S8S_PCIMEM */
+#endif /* HISAX_HFC4S8S_PCIMEM */
/******************************************************/
/* function to read critical counter registers that */
@@ -724,12 +724,12 @@ rx_d_frame(struct hfc4s8s_l1 *l1p, int ech)
} else {
/* read errornous D frame */
-#ifndef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifndef HISAX_HFC4S8S_PCIMEM
SetRegAddr(l1p->hw, A_FIFO_DATA0);
#endif
while (z1 >= 4) {
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
Read_hfc32(l1p->hw, A_FIFO_DATA0);
#else
fRead_hfc32(l1p->hw);
@@ -738,7 +738,7 @@ rx_d_frame(struct hfc4s8s_l1 *l1p, int ech)
}
while (z1--)
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
Read_hfc8(l1p->hw, A_FIFO_DATA0);
#else
fRead_hfc8(l1p->hw);
@@ -752,12 +752,12 @@ rx_d_frame(struct hfc4s8s_l1 *l1p, int ech)
cp = skb->data;
-#ifndef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifndef HISAX_HFC4S8S_PCIMEM
SetRegAddr(l1p->hw, A_FIFO_DATA0);
#endif
while (z1 >= 4) {
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
*((unsigned long *) cp) =
Read_hfc32(l1p->hw, A_FIFO_DATA0);
#else
@@ -768,7 +768,7 @@ rx_d_frame(struct hfc4s8s_l1 *l1p, int ech)
}
while (z1--)
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
*cp++ = Read_hfc8(l1p->hw, A_FIFO_DATA0);
#else
*cp++ = fRead_hfc8(l1p->hw);
@@ -858,12 +858,12 @@ rx_b_frame(struct hfc4s8s_btype *bch)
wait_busy(l1->hw);
return;
}
-#ifndef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifndef HISAX_HFC4S8S_PCIMEM
SetRegAddr(l1->hw, A_FIFO_DATA0);
#endif
while (z1 >= 4) {
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
*((unsigned long *) bch->rx_ptr) =
Read_hfc32(l1->hw, A_FIFO_DATA0);
#else
@@ -875,7 +875,7 @@ rx_b_frame(struct hfc4s8s_btype *bch)
}
while (z1--)
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
*(bch->rx_ptr++) = Read_hfc8(l1->hw, A_FIFO_DATA0);
#else
*(bch->rx_ptr++) = fRead_hfc8(l1->hw);
@@ -939,12 +939,12 @@ tx_d_frame(struct hfc4s8s_l1 *l1p)
if ((skb = skb_dequeue(&l1p->d_tx_queue))) {
cp = skb->data;
cnt = skb->len;
-#ifndef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifndef HISAX_HFC4S8S_PCIMEM
SetRegAddr(l1p->hw, A_FIFO_DATA0);
#endif
while (cnt >= 4) {
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
fWrite_hfc32(l1p->hw, A_FIFO_DATA0,
*(unsigned long *) cp);
#else
@@ -955,7 +955,7 @@ tx_d_frame(struct hfc4s8s_l1 *l1p)
cnt -= 4;
}
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
while (cnt--)
fWrite_hfc8(l1p->hw, A_FIFO_DATA0, *cp++);
#else
@@ -1036,11 +1036,11 @@ tx_b_frame(struct hfc4s8s_btype *bch)
cp = skb->data + bch->tx_cnt;
bch->tx_cnt += cnt;
-#ifndef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifndef HISAX_HFC4S8S_PCIMEM
SetRegAddr(l1->hw, A_FIFO_DATA0);
#endif
while (cnt >= 4) {
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
fWrite_hfc32(l1->hw, A_FIFO_DATA0,
*(unsigned long *) cp);
#else
@@ -1051,7 +1051,7 @@ tx_b_frame(struct hfc4s8s_btype *bch)
}
while (cnt--)
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
fWrite_hfc8(l1->hw, A_FIFO_DATA0, *cp++);
#else
fWrite_hfc8(l1->hw, *cp++);
@@ -1280,7 +1280,7 @@ hfc4s8s_interrupt(int intno, void *dev_id)
if (!hw || !(hw->mr.r_irq_ctrl & M_GLOB_IRQ_EN))
return IRQ_NONE;
-#ifndef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifndef HISAX_HFC4S8S_PCIMEM
/* read current selected regsister */
old_ioreg = GetRegAddr(hw);
#endif
@@ -1291,7 +1291,7 @@ hfc4s8s_interrupt(int intno, void *dev_id)
if (!
(b = (Read_hfc8(hw, R_STATUS) & (M_MISC_IRQSTA | M_FR_IRQSTA)))
&& !hw->mr.r_irq_statech) {
-#ifndef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifndef HISAX_HFC4S8S_PCIMEM
SetRegAddr(hw, old_ioreg);
#endif
return IRQ_NONE;
@@ -1321,7 +1321,7 @@ hfc4s8s_interrupt(int intno, void *dev_id)
/* queue the request to allow other cards to interrupt */
schedule_work(&hw->tqueue);
-#ifndef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifndef HISAX_HFC4S8S_PCIMEM
SetRegAddr(hw, old_ioreg);
#endif
return IRQ_HANDLED;
@@ -1470,7 +1470,7 @@ static void
release_pci_ports(hfc4s8s_hw * hw)
{
pci_write_config_word(hw->pdev, PCI_COMMAND, 0);
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
if (hw->membase)
iounmap((void *) hw->membase);
#else
@@ -1485,7 +1485,7 @@ release_pci_ports(hfc4s8s_hw * hw)
static void
enable_pci_ports(hfc4s8s_hw * hw)
{
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
pci_write_config_word(hw->pdev, PCI_COMMAND, PCI_ENA_MEMIO);
#else
pci_write_config_word(hw->pdev, PCI_COMMAND, PCI_ENA_REGIO);
@@ -1560,7 +1560,7 @@ setup_instance(hfc4s8s_hw * hw)
hw->irq);
goto out;
}
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
printk(KERN_INFO
"HFC-4S/8S: found PCI card at membase 0x%p, irq %d\n",
hw->hw_membase, hw->irq);
@@ -1613,7 +1613,7 @@ hfc4s8s_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw->irq = pdev->irq;
hw->iobase = pci_resource_start(pdev, 0);
-#ifdef CONFIG_HISAX_HFC4S8S_PCIMEM
+#ifdef HISAX_HFC4S8S_PCIMEM
hw->hw_membase = (u_char *) pci_resource_start(pdev, 1);
hw->membase = ioremap((ulong) hw->hw_membase, 256);
#else
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 5a6989f23fcf..42bbae2a646c 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -183,7 +183,7 @@ typedef struct hfcusb_data {
int vend_idx; /* vendor found */
int b_mode[2]; /* B-channel mode */
int l1_activated; /* layer 1 activated */
- int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */
+ int disc_flag; /* 'true' if device was disonnected to avoid some USB actions */
int packet_size, iso_packet_size;
/* control pipe background handling */
@@ -392,7 +392,7 @@ l1_timer_expire_t3(hfcusb_data * hfc)
DBG(ISDN_DBG,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)");
#endif
- hfc->l1_activated = FALSE;
+ hfc->l1_activated = false;
handle_led(hfc, LED_S0_OFF);
/* deactivate : */
queue_control_request(hfc, HFCUSB_STATES, 0x10, 1);
@@ -411,7 +411,7 @@ l1_timer_expire_t4(hfcusb_data * hfc)
DBG(ISDN_DBG,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)");
#endif
- hfc->l1_activated = FALSE;
+ hfc->l1_activated = false;
handle_led(hfc, LED_S0_OFF);
}
@@ -452,7 +452,7 @@ state_handler(hfcusb_data * hfc, __u8 state)
#ifdef CONFIG_HISAX_DEBUG
DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent");
#endif
- hfc->l1_activated = TRUE;
+ hfc->l1_activated = true;
handle_led(hfc, LED_S0_ON);
} else if (state <= 3 /* && activated */ ) {
if (old_state == 7 || old_state == 8) {
@@ -472,7 +472,7 @@ state_handler(hfcusb_data * hfc, __u8 state)
DBG(ISDN_DBG,
"HFC-S USB: PH_DEACTIVATE | INDICATION sent");
#endif
- hfc->l1_activated = FALSE;
+ hfc->l1_activated = false;
handle_led(hfc, LED_S0_OFF);
}
}
@@ -622,7 +622,7 @@ tx_iso_complete(struct urb *urb)
if (fifo->active && !status) {
transp_mode = 0;
if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS)
- transp_mode = TRUE;
+ transp_mode = true;
/* is FifoFull-threshold set for our channel? */
threshbit = threshtable[fifon] & hfc->threshold_mask;
@@ -640,7 +640,7 @@ tx_iso_complete(struct urb *urb)
tx_iso_complete, urb->context);
memset(context_iso_urb->buffer, 0,
sizeof(context_iso_urb->buffer));
- frame_complete = FALSE;
+ frame_complete = false;
/* Generate next Iso Packets */
for (k = 0; k < num_isoc_packets; ++k) {
if (fifo->skbuff) {
@@ -666,7 +666,7 @@ tx_iso_complete(struct urb *urb)
/* add 2 byte flags and 16bit CRC at end of ISDN frame */
fifo->bit_line += 32;
}
- frame_complete = TRUE;
+ frame_complete = true;
}
memcpy(context_iso_urb->buffer +
@@ -693,7 +693,7 @@ tx_iso_complete(struct urb *urb)
}
if (frame_complete) {
- fifo->delete_flg = TRUE;
+ fifo->delete_flg = true;
fifo->hif->l1l2(fifo->hif,
PH_DATA | CONFIRM,
(void *) (unsigned long) fifo->skbuff->
@@ -701,9 +701,9 @@ tx_iso_complete(struct urb *urb)
if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff);
fifo->skbuff = NULL;
- fifo->delete_flg = FALSE;
+ fifo->delete_flg = false;
}
- frame_complete = FALSE;
+ frame_complete = false;
}
}
errcode = usb_submit_urb(urb, GFP_ATOMIC);
@@ -837,7 +837,7 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
fifon = fifo->fifonum;
transp_mode = 0;
if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS)
- transp_mode = TRUE;
+ transp_mode = true;
if (!fifo->skbuff) {
fifo->skbuff = dev_alloc_skb(fifo->max_size + 3);
@@ -1176,7 +1176,7 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff);
fifo->skbuff = NULL;
- fifo->delete_flg = FALSE;
+ fifo->delete_flg = false;
}
fifo->skbuff = arg; /* we have a new buffer */
break;
@@ -1262,8 +1262,8 @@ usb_init(hfcusb_data * hfc)
hfc->b_mode[0] = L1_MODE_NULL;
hfc->b_mode[1] = L1_MODE_NULL;
- hfc->l1_activated = FALSE;
- hfc->disc_flag = FALSE;
+ hfc->l1_activated = false;
+ hfc->disc_flag = false;
hfc->led_state = 0;
hfc->led_new_data = 0;
hfc->old_led_state = 0;
@@ -1404,7 +1404,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* check for config EOL element */
while (validconf[cfg_used][0]) {
- cfg_found = TRUE;
+ cfg_found = true;
vcf = validconf[cfg_used];
/* first endpoint descriptor */
ep = iface->endpoint;
@@ -1426,7 +1426,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
idx++;
attr = ep->desc.bmAttributes;
if (cmptbl[idx] == EP_NUL) {
- cfg_found = FALSE;
+ cfg_found = false;
}
if (attr == USB_ENDPOINT_XFER_INT
&& cmptbl[idx] == EP_INT)
@@ -1448,7 +1448,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
"HFC-S USB: Interrupt Endpoint interval < %d found - skipping config",
vcf[17]);
#endif
- cfg_found = FALSE;
+ cfg_found = false;
}
ep++;
}
@@ -1456,7 +1456,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* all entries must be EP_NOP or EP_NUL for a valid config */
if (cmptbl[i] != EP_NOP
&& cmptbl[i] != EP_NUL)
- cfg_found = FALSE;
+ cfg_found = false;
}
if (cfg_found) {
if (cfg_used < small_match) {
@@ -1656,7 +1656,7 @@ hfc_usb_disconnect(struct usb_interface
hfcusb_data *context = usb_get_intfdata(intf);
int i;
printk(KERN_INFO "HFC-S USB: device disconnect\n");
- context->disc_flag = TRUE;
+ context->disc_flag = true;
usb_set_intfdata(intf, NULL);
if (!context)
return;
diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h
index 6349367ed480..471f2354dfde 100644
--- a/drivers/isdn/hisax/hfc_usb.h
+++ b/drivers/isdn/hisax/hfc_usb.h
@@ -12,9 +12,6 @@
#define VERBOSE_USB_DEBUG
-#define TRUE 1
-#define FALSE 0
-
/***********/
/* defines */
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 3f1137e34678..3cd8d5ba239b 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -795,19 +795,6 @@ struct w6692_hw {
struct timer_list timer;
};
-#ifdef CONFIG_HISAX_TESTEMU
-struct te_hw {
- unsigned char *sfifo;
- unsigned char *sfifo_w;
- unsigned char *sfifo_r;
- unsigned char *sfifo_e;
- int sfifo_cnt;
- unsigned int stat;
- wait_queue_head_t rwaitq;
- wait_queue_head_t swaitq;
-};
-#endif
-
struct arcofi_msg {
struct arcofi_msg *next;
u_char receive;
@@ -916,9 +903,6 @@ struct IsdnCardState {
struct ix1_hw niccy;
struct isurf_hw isurf;
struct saphir_hw saphir;
-#ifdef CONFIG_HISAX_TESTEMU
- struct te_hw te;
-#endif
struct bkm_hw ax;
struct gazel_hw gazel;
struct w6692_hw w6692;
@@ -1175,15 +1159,6 @@ struct IsdnCardState {
#define CARD_HSTSAPHIR 0
#endif
-#ifdef CONFIG_HISAX_TESTEMU
-#define CARD_TESTEMU 1
-#define ISDN_CTYPE_TESTEMU 99
-#undef ISDN_CTYPE_COUNT
-#define ISDN_CTYPE_COUNT ISDN_CTYPE_TESTEMU
-#else
-#define CARD_TESTEMU 0
-#endif
-
#ifdef CONFIG_HISAX_BKM_A4T
#define CARD_BKM_A4T 1
#ifndef ISDN_CHIP_ISAC
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index 6f1a6583b17d..9df9e3548cf1 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -431,7 +431,6 @@ reterror:
return(ret);
}
-extern void BChannel_bh(struct BCState *);
#define B_LL_NOCARRIER 8
#define B_LL_CONNECT 9
#define B_LL_OK 10
diff --git a/drivers/isdn/hisax/isdnl1.h b/drivers/isdn/hisax/isdnl1.h
index 0e88cfabdf10..172ad4c8c961 100644
--- a/drivers/isdn/hisax/isdnl1.h
+++ b/drivers/isdn/hisax/isdnl1.h
@@ -21,12 +21,11 @@
#define B_XMTBUFREADY 1
#define B_ACKPENDING 2
-extern void debugl1(struct IsdnCardState *cs, char *fmt, ...);
-extern void DChannel_proc_xmt(struct IsdnCardState *cs);
-extern void DChannel_proc_rcv(struct IsdnCardState *cs);
-extern void l1_msg(struct IsdnCardState *cs, int pr, void *arg);
-extern void l1_msg_b(struct PStack *st, int pr, void *arg);
-
-#ifdef L2FRAME_DEBUG
-extern void Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, int dir);
-#endif
+void debugl1(struct IsdnCardState *cs, char *fmt, ...);
+void DChannel_proc_xmt(struct IsdnCardState *cs);
+void DChannel_proc_rcv(struct IsdnCardState *cs);
+void l1_msg(struct IsdnCardState *cs, int pr, void *arg);
+void l1_msg_b(struct PStack *st, int pr, void *arg);
+void Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf,
+ int dir);
+void BChannel_bh(struct work_struct *work);
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
index 281fa27d9f00..935f23356fae 100644
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -231,18 +231,6 @@ no_l3_proto_spec(struct PStack *st, isdn_ctrl *ic)
return(-1);
}
-#ifdef CONFIG_HISAX_EURO
-extern void setstack_dss1(struct PStack *st);
-#endif
-
-#ifdef CONFIG_HISAX_NI1
-extern void setstack_ni1(struct PStack *st);
-#endif
-
-#ifdef CONFIG_HISAX_1TR6
-extern void setstack_1tr6(struct PStack *st);
-#endif
-
struct l3_process
*getl3proc(struct PStack *st, int cr)
{
diff --git a/drivers/isdn/hisax/isdnl3.h b/drivers/isdn/hisax/isdnl3.h
index 1dbe0297a506..749498fe6c4b 100644
--- a/drivers/isdn/hisax/isdnl3.h
+++ b/drivers/isdn/hisax/isdnl3.h
@@ -25,13 +25,19 @@ struct stateentry {
#define l3_debug(st, fmt, args...) HiSax_putstatus(st->l1.hardware, "l3 ", fmt, ## args)
-extern void newl3state(struct l3_process *pc, int state);
-extern void L3InitTimer(struct l3_process *pc, struct L3Timer *t);
-extern void L3DelTimer(struct L3Timer *t);
-extern int L3AddTimer(struct L3Timer *t, int millisec, int event);
-extern void StopAllL3Timer(struct l3_process *pc);
-extern struct sk_buff *l3_alloc_skb(int len);
-extern struct l3_process *new_l3_process(struct PStack *st, int cr);
-extern void release_l3_process(struct l3_process *p);
-extern struct l3_process *getl3proc(struct PStack *st, int cr);
-extern void l3_msg(struct PStack *st, int pr, void *arg);
+struct PStack;
+
+void newl3state(struct l3_process *pc, int state);
+void L3InitTimer(struct l3_process *pc, struct L3Timer *t);
+void L3DelTimer(struct L3Timer *t);
+int L3AddTimer(struct L3Timer *t, int millisec, int event);
+void StopAllL3Timer(struct l3_process *pc);
+struct sk_buff *l3_alloc_skb(int len);
+struct l3_process *new_l3_process(struct PStack *st, int cr);
+void release_l3_process(struct l3_process *p);
+struct l3_process *getl3proc(struct PStack *st, int cr);
+void l3_msg(struct PStack *st, int pr, void *arg);
+void setstack_dss1(struct PStack *st);
+void setstack_ni1(struct PStack *st);
+void setstack_1tr6(struct PStack *st);
+
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 94a935089119..dc477e0aab0e 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -367,7 +367,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
/******************************************************/
/* table for conf filesystem functions defined above. */
/******************************************************/
-static struct file_operations conf_fops =
+static const struct file_operations conf_fops =
{
.llseek = no_llseek,
.read = hysdn_conf_read,
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 375d956884d7..f7e83a86f444 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -383,7 +383,7 @@ hysdn_log_poll(struct file *file, poll_table * wait)
/**************************************************/
/* table for log filesystem functions defined above. */
/**************************************************/
-static struct file_operations log_fops =
+static const struct file_operations log_fops =
{
.llseek = no_llseek,
.read = hysdn_log_read,
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 6a2ef0a87ed9..9c926e41b114 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1822,7 +1822,7 @@ isdn_close(struct inode *ino, struct file *filep)
return 0;
}
-static struct file_operations isdn_fops =
+static const struct file_operations isdn_fops =
{
.owner = THIS_MODULE,
.llseek = no_llseek,
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index fc80afe555b9..ea5f30d4a5a2 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1261,7 +1261,6 @@ isdn_tty_flush_buffer(struct tty_struct *tty)
}
isdn_tty_cleanup_xmit(info);
info->xmit_count = 0;
- wake_up_interruptible(&tty->write_wait);
tty_wakeup(tty);
}
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index 11c1b0b6e390..386c5ce64844 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -774,10 +774,6 @@ static void pcbit_logstat(struct pcbit_dev *dev, char *str)
dev->dev_if->statcallb(&ictl);
}
-extern char * isdn_state_table[];
-extern char * strisdnevent(unsigned short);
-
-
void pcbit_state_change(struct pcbit_dev * dev, struct pcbit_chan * chan,
unsigned short i, unsigned short ev, unsigned short f)
{
diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c
index 93ca7de5670b..1ad8b07efd8b 100644
--- a/drivers/isdn/pcbit/edss1.c
+++ b/drivers/isdn/pcbit/edss1.c
@@ -35,12 +35,6 @@
#include "callbacks.h"
-extern void pcbit_state_change(struct pcbit_dev *, struct pcbit_chan *,
- unsigned short i, unsigned short ev,
- unsigned short f);
-
-extern struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS];
-
char * isdn_state_table[] = {
"Closed",
"Call initiated",
diff --git a/drivers/isdn/pcbit/edss1.h b/drivers/isdn/pcbit/edss1.h
index 6bb587005b86..0b64f97015d8 100644
--- a/drivers/isdn/pcbit/edss1.h
+++ b/drivers/isdn/pcbit/edss1.h
@@ -90,9 +90,12 @@ struct fsm_timer_entry {
unsigned long timeout; /* in seconds */
};
+extern char * isdn_state_table[];
+
+void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *,
+ unsigned short event, struct callb_data *);
+char * strisdnevent(ushort ev);
-extern void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *,
- unsigned short event, struct callb_data *);
#endif
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c
index eafcce5e656a..58eee50c8e26 100644
--- a/drivers/isdn/pcbit/layer2.c
+++ b/drivers/isdn/pcbit/layer2.c
@@ -47,22 +47,6 @@
#undef DEBUG_FRAG
-
-/*
- * task queue struct
- */
-
-
-
-/*
- * Layer 3 packet demultiplexer
- * drv.c
- */
-
-extern void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg,
- struct sk_buff *skb,
- ushort hdr_len, ushort refnum);
-
/*
* Prototypes
*/
diff --git a/drivers/isdn/pcbit/module.c b/drivers/isdn/pcbit/module.c
index 282073a35d6a..7b7b1777f09b 100644
--- a/drivers/isdn/pcbit/module.c
+++ b/drivers/isdn/pcbit/module.c
@@ -32,9 +32,6 @@ module_param_array(irq, int, NULL, 0);
static int num_boards;
struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS];
-extern void pcbit_terminate(int board);
-extern int pcbit_init_dev(int board, int mem_base, int irq);
-
static int __init pcbit_init(void)
{
int board;
diff --git a/drivers/isdn/pcbit/pcbit.h b/drivers/isdn/pcbit/pcbit.h
index 19c18e88ff16..d76fffc88b82 100644
--- a/drivers/isdn/pcbit/pcbit.h
+++ b/drivers/isdn/pcbit/pcbit.h
@@ -166,6 +166,12 @@ struct pcbit_ioctl {
#define L2_RUNNING 5
#define L2_ERROR 6
-extern void pcbit_deliver(struct work_struct *work);
+void pcbit_deliver(struct work_struct *work);
+int pcbit_init_dev(int board, int mem_base, int irq);
+void pcbit_terminate(int board);
+void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg, struct sk_buff * skb,
+ ushort hdr_len, ushort refnum);
+void pcbit_state_change(struct pcbit_dev * dev, struct pcbit_chan * chan,
+ unsigned short i, unsigned short ev, unsigned short f);
#endif
diff --git a/drivers/isdn/sc/card.h b/drivers/isdn/sc/card.h
index 8e44928cdf1c..4fbfa825c3a2 100644
--- a/drivers/isdn/sc/card.h
+++ b/drivers/isdn/sc/card.h
@@ -26,7 +26,9 @@
#include <linux/timer.h>
#include <linux/time.h>
#include <linux/isdnif.h>
+#include <linux/irqreturn.h>
#include "message.h"
+#include "scioc.h"
/*
* Amount of time to wait for a reset to complete
@@ -98,4 +100,32 @@ typedef struct {
spinlock_t lock; /* local lock */
} board;
+
+extern board *sc_adapter[];
+extern int cinst;
+
+void memcpy_toshmem(int card, void *dest, const void *src, size_t n);
+void memcpy_fromshmem(int card, void *dest, const void *src, size_t n);
+int get_card_from_id(int driver);
+int indicate_status(int card, int event, ulong Channel, char *Data);
+irqreturn_t interrupt_handler(int interrupt, void *cardptr);
+int sndpkt(int devId, int channel, struct sk_buff *data);
+void rcvpkt(int card, RspMessage *rcvmsg);
+int command(isdn_ctrl *cmd);
+int reset(int card);
+int startproc(int card);
+int send_and_receive(int card, unsigned int procid, unsigned char type,
+ unsigned char class, unsigned char code,
+ unsigned char link, unsigned char data_len,
+ unsigned char *data, RspMessage *mesgdata, int timeout);
+void flushreadfifo (int card);
+int sendmessage(int card, unsigned int procid, unsigned int type,
+ unsigned int class, unsigned int code, unsigned int link,
+ unsigned int data_len, unsigned int *data);
+int receivemessage(int card, RspMessage *rspmsg);
+int sc_ioctl(int card, scs_ioctl *data);
+int setup_buffers(int card, int c);
+void check_reset(unsigned long data);
+void check_phystat(unsigned long data);
+
#endif /* CARD_H */
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c
index 04b8a58f03b5..b7bb7cbcf503 100644
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -31,19 +31,6 @@ 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[];
-
-extern int sc_ioctl(int, scs_ioctl *);
-extern int setup_buffers(int, int, unsigned int);
-extern int indicate_status(int, int,ulong,char*);
-extern void check_reset(unsigned long);
-extern int send_and_receive(int, unsigned int, unsigned char, unsigned char,
- unsigned char, unsigned char, unsigned char, unsigned char *,
- RspMessage *, int);
-extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
- unsigned int, unsigned int, unsigned int, unsigned int *);
-
#ifdef DEBUG
/*
* Translate command codes to strings
@@ -208,7 +195,7 @@ static int answer(int card, unsigned long channel)
return -ENODEV;
}
- if(setup_buffers(card, channel+1, BUFFER_SIZE)) {
+ if(setup_buffers(card, channel+1)) {
hangup(card, channel+1);
return -ENOBUFS;
}
@@ -297,7 +284,7 @@ static int acceptb(int card, unsigned long channel)
return -ENODEV;
}
- if(setup_buffers(card, channel+1, BUFFER_SIZE))
+ if(setup_buffers(card, channel+1))
{
hangup(card, channel+1);
return -ENOBUFS;
diff --git a/drivers/isdn/sc/event.c b/drivers/isdn/sc/event.c
index 57367325ef04..498f4039ece2 100644
--- a/drivers/isdn/sc/event.c
+++ b/drivers/isdn/sc/event.c
@@ -20,9 +20,6 @@
#include "message.h"
#include "card.h"
-extern int cinst;
-extern board *sc_adapter[];
-
#ifdef DEBUG
static char *events[] = { "ISDN_STAT_STAVAIL",
"ISDN_STAT_ICALL",
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 150759a5cddf..0bf76344a0d5 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -35,12 +35,6 @@ module_param_array(irq, int, NULL, 0);
module_param_array(ram, int, NULL, 0);
module_param(do_reset, bool, 0);
-extern irqreturn_t interrupt_handler(int, void *);
-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);
-
static int identify_board(unsigned long, unsigned int);
static int __init sc_init(void)
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c
index cd17de18cb76..bef7963cdd02 100644
--- a/drivers/isdn/sc/interrupt.c
+++ b/drivers/isdn/sc/interrupt.c
@@ -21,16 +21,6 @@
#include "card.h"
#include <linux/interrupt.h>
-extern int indicate_status(int, int, ulong, char *);
-extern void check_phystat(unsigned long);
-extern int receivemessage(int, RspMessage *);
-extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
- unsigned int, unsigned int, unsigned int, unsigned int *);
-extern void rcvpkt(int, RspMessage *);
-
-extern int cinst;
-extern board *sc_adapter[];
-
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 57c4ab96d136..7817d2244921 100644
--- a/drivers/isdn/sc/ioctl.c
+++ b/drivers/isdn/sc/ioctl.c
@@ -12,16 +12,6 @@
#include "card.h"
#include "scioc.h"
-extern int indicate_status(int, int, unsigned long, char *);
-extern int startproc(int);
-extern int reset(int);
-extern int send_and_receive(int, unsigned int, unsigned char,unsigned char,
- unsigned char,unsigned char,
- unsigned char, unsigned char *, RspMessage *, int);
-
-extern board *sc_adapter[];
-
-
static int GetStatus(int card, boardInfo *);
/*
diff --git a/drivers/isdn/sc/message.c b/drivers/isdn/sc/message.c
index 0a0fe6b8039b..c5a307e3c496 100644
--- a/drivers/isdn/sc/message.c
+++ b/drivers/isdn/sc/message.c
@@ -22,16 +22,6 @@
#include "message.h"
#include "card.h"
-extern board *sc_adapter[];
-extern unsigned int cinst;
-
-/*
- * Obligatory function prototypes
- */
-extern int indicate_status(int,ulong,char*);
-extern int scm_command(isdn_ctrl *);
-
-
/*
* receive a message from the board
*/
diff --git a/drivers/isdn/sc/packet.c b/drivers/isdn/sc/packet.c
index 1e04676b016b..92016a2608e9 100644
--- a/drivers/isdn/sc/packet.c
+++ b/drivers/isdn/sc/packet.c
@@ -20,16 +20,6 @@
#include "message.h"
#include "card.h"
-extern board *sc_adapter[];
-extern unsigned int cinst;
-
-extern int get_card_from_id(int);
-extern int indicate_status(int, int,ulong, char*);
-extern void memcpy_toshmem(int, void *, const void *, size_t);
-extern void memcpy_fromshmem(int, void *, const void *, size_t);
-extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
- unsigned int, unsigned int, unsigned int, unsigned int *);
-
int sndpkt(int devId, int channel, struct sk_buff *data)
{
LLData ReqLnkWrite;
diff --git a/drivers/isdn/sc/scioc.h b/drivers/isdn/sc/scioc.h
index d08e650c7b6a..dfb107a6de44 100644
--- a/drivers/isdn/sc/scioc.h
+++ b/drivers/isdn/sc/scioc.h
@@ -1,3 +1,6 @@
+#ifndef __ISDN_SC_SCIOC_H__
+#define __ISDN_SC_SCIOC_H__
+
/*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
@@ -103,3 +106,6 @@ typedef struct {
POTInfo potsinfo;
} info;
} boardInfo;
+
+#endif /* __ISDN_SC_SCIOC_H__ */
+
diff --git a/drivers/isdn/sc/shmem.c b/drivers/isdn/sc/shmem.c
index 6f58862992db..034d41a61ae1 100644
--- a/drivers/isdn/sc/shmem.c
+++ b/drivers/isdn/sc/shmem.c
@@ -22,12 +22,6 @@
#include "card.h"
/*
- * Main adapter array
- */
-extern board *sc_adapter[];
-extern int cinst;
-
-/*
*
*/
void memcpy_toshmem(int card, void *dest, const void *src, size_t n)
diff --git a/drivers/isdn/sc/timer.c b/drivers/isdn/sc/timer.c
index f43282be0ada..cc1b8861be2a 100644
--- a/drivers/isdn/sc/timer.c
+++ b/drivers/isdn/sc/timer.c
@@ -20,14 +20,6 @@
#include "message.h"
#include "card.h"
-extern board *sc_adapter[];
-
-extern void flushreadfifo(int);
-extern int startproc(int);
-extern int indicate_status(int, int, unsigned long, char *);
-extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
- unsigned int, unsigned int, unsigned int, unsigned int *);
-
/*
* Write the proper values into the I/O ports following a reset
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 2db1ca4c6800..04574a9d4430 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -304,6 +304,7 @@ struct kvm {
int memory_config_version;
int busy;
unsigned long rmap_overflow;
+ struct list_head vm_list;
};
struct kvm_stat {
@@ -340,6 +341,7 @@ struct kvm_arch_ops {
struct kvm_vcpu *(*vcpu_load)(struct kvm_vcpu *vcpu);
void (*vcpu_put)(struct kvm_vcpu *vcpu);
+ void (*vcpu_decache)(struct kvm_vcpu *vcpu);
int (*set_guest_debug)(struct kvm_vcpu *vcpu,
struct kvm_debug_guest *dbg);
@@ -558,7 +560,7 @@ static inline void load_gs(u16 sel)
#ifndef load_ldt
static inline void load_ldt(u16 sel)
{
- asm ("lldt %0" : : "g"(sel));
+ asm ("lldt %0" : : "rm"(sel));
}
#endif
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 099f0afd394d..af866147ff25 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -34,6 +34,8 @@
#include <linux/highmem.h>
#include <linux/file.h>
#include <asm/desc.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
#include "x86_emulate.h"
#include "segment_descriptor.h"
@@ -41,6 +43,9 @@
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
+static DEFINE_SPINLOCK(kvm_lock);
+static LIST_HEAD(vm_list);
+
struct kvm_arch_ops *kvm_arch_ops;
struct kvm_stat kvm_stat;
EXPORT_SYMBOL_GPL(kvm_stat);
@@ -230,9 +235,13 @@ static int kvm_dev_open(struct inode *inode, struct file *filp)
struct kvm_vcpu *vcpu = &kvm->vcpus[i];
mutex_init(&vcpu->mutex);
+ vcpu->cpu = -1;
vcpu->kvm = kvm;
vcpu->mmu.root_hpa = INVALID_PAGE;
INIT_LIST_HEAD(&vcpu->free_pages);
+ spin_lock(&kvm_lock);
+ list_add(&kvm->vm_list, &vm_list);
+ spin_unlock(&kvm_lock);
}
filp->private_data = kvm;
return 0;
@@ -272,7 +281,9 @@ static void kvm_free_physmem(struct kvm *kvm)
static void kvm_free_vcpu(struct kvm_vcpu *vcpu)
{
- vcpu_load(vcpu->kvm, vcpu_slot(vcpu));
+ if (!vcpu_load(vcpu->kvm, vcpu_slot(vcpu)))
+ return;
+
kvm_mmu_destroy(vcpu);
vcpu_put(vcpu);
kvm_arch_ops->vcpu_free(vcpu);
@@ -290,6 +301,9 @@ static int kvm_dev_release(struct inode *inode, struct file *filp)
{
struct kvm *kvm = filp->private_data;
+ spin_lock(&kvm_lock);
+ list_del(&kvm->vm_list);
+ spin_unlock(&kvm_lock);
kvm_free_vcpus(kvm);
kvm_free_physmem(kvm);
kfree(kvm);
@@ -544,7 +558,6 @@ static int kvm_dev_ioctl_create_vcpu(struct kvm *kvm, int n)
FX_IMAGE_ALIGN);
vcpu->guest_fx_image = vcpu->host_fx_image + FX_IMAGE_SIZE;
- vcpu->cpu = -1; /* First load will set up TR */
r = kvm_arch_ops->vcpu_create(vcpu);
if (r < 0)
goto out_free_vcpus;
@@ -1360,6 +1373,9 @@ static int kvm_dev_ioctl_run(struct kvm *kvm, struct kvm_run *kvm_run)
if (!vcpu)
return -ENOENT;
+ /* re-sync apic's tpr */
+ vcpu->cr8 = kvm_run->cr8;
+
if (kvm_run->emulated) {
kvm_arch_ops->skip_emulated_instruction(vcpu);
kvm_run->emulated = 0;
@@ -2025,6 +2041,64 @@ static struct notifier_block kvm_reboot_notifier = {
.priority = 0,
};
+/*
+ * Make sure that a cpu that is being hot-unplugged does not have any vcpus
+ * cached on it.
+ */
+static void decache_vcpus_on_cpu(int cpu)
+{
+ struct kvm *vm;
+ struct kvm_vcpu *vcpu;
+ int i;
+
+ spin_lock(&kvm_lock);
+ list_for_each_entry(vm, &vm_list, vm_list)
+ for (i = 0; i < KVM_MAX_VCPUS; ++i) {
+ vcpu = &vm->vcpus[i];
+ /*
+ * If the vcpu is locked, then it is running on some
+ * other cpu and therefore it is not cached on the
+ * cpu in question.
+ *
+ * If it's not locked, check the last cpu it executed
+ * on.
+ */
+ if (mutex_trylock(&vcpu->mutex)) {
+ if (vcpu->cpu == cpu) {
+ kvm_arch_ops->vcpu_decache(vcpu);
+ vcpu->cpu = -1;
+ }
+ mutex_unlock(&vcpu->mutex);
+ }
+ }
+ spin_unlock(&kvm_lock);
+}
+
+static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
+ void *v)
+{
+ int cpu = (long)v;
+
+ switch (val) {
+ case CPU_DEAD:
+ case CPU_UP_CANCELED:
+ decache_vcpus_on_cpu(cpu);
+ smp_call_function_single(cpu, kvm_arch_ops->hardware_disable,
+ NULL, 0, 1);
+ break;
+ case CPU_UP_PREPARE:
+ smp_call_function_single(cpu, kvm_arch_ops->hardware_enable,
+ NULL, 0, 1);
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block kvm_cpu_notifier = {
+ .notifier_call = kvm_cpu_hotplug,
+ .priority = 20, /* must be > scheduler priority */
+};
+
static __init void kvm_init_debug(void)
{
struct kvm_stats_debugfs_item *p;
@@ -2044,6 +2118,30 @@ static void kvm_exit_debug(void)
debugfs_remove(debugfs_dir);
}
+static int kvm_suspend(struct sys_device *dev, pm_message_t state)
+{
+ decache_vcpus_on_cpu(raw_smp_processor_id());
+ on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1);
+ return 0;
+}
+
+static int kvm_resume(struct sys_device *dev)
+{
+ on_each_cpu(kvm_arch_ops->hardware_enable, 0, 0, 1);
+ return 0;
+}
+
+static struct sysdev_class kvm_sysdev_class = {
+ set_kset_name("kvm"),
+ .suspend = kvm_suspend,
+ .resume = kvm_resume,
+};
+
+static struct sys_device kvm_sysdev = {
+ .id = 0,
+ .cls = &kvm_sysdev_class,
+};
+
hpa_t bad_page_address;
int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)
@@ -2071,8 +2169,19 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)
return r;
on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1);
+ r = register_cpu_notifier(&kvm_cpu_notifier);
+ if (r)
+ goto out_free_1;
register_reboot_notifier(&kvm_reboot_notifier);
+ r = sysdev_class_register(&kvm_sysdev_class);
+ if (r)
+ goto out_free_2;
+
+ r = sysdev_register(&kvm_sysdev);
+ if (r)
+ goto out_free_3;
+
kvm_chardev_ops.owner = module;
r = misc_register(&kvm_dev);
@@ -2084,7 +2193,13 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)
return r;
out_free:
+ sysdev_unregister(&kvm_sysdev);
+out_free_3:
+ sysdev_class_unregister(&kvm_sysdev_class);
+out_free_2:
unregister_reboot_notifier(&kvm_reboot_notifier);
+ unregister_cpu_notifier(&kvm_cpu_notifier);
+out_free_1:
on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1);
kvm_arch_ops->hardware_unsetup();
return r;
@@ -2093,8 +2208,10 @@ out_free:
void kvm_exit_arch(void)
{
misc_deregister(&kvm_dev);
-
+ sysdev_unregister(&kvm_sysdev);
+ sysdev_class_unregister(&kvm_sysdev_class);
unregister_reboot_notifier(&kvm_reboot_notifier);
+ unregister_cpu_notifier(&kvm_cpu_notifier);
on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1);
kvm_arch_ops->hardware_unsetup();
kvm_arch_ops = NULL;
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h
index 149fa45fd9a5..b6b90e9e1301 100644
--- a/drivers/kvm/paging_tmpl.h
+++ b/drivers/kvm/paging_tmpl.h
@@ -443,31 +443,17 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
{
struct guest_walker walker;
- pt_element_t guest_pte;
- gpa_t gpa;
-
- FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0);
- guest_pte = *walker.ptep;
- FNAME(release_walker)(&walker);
-
- if (!is_present_pte(guest_pte))
- return UNMAPPED_GVA;
-
- if (walker.level == PT_DIRECTORY_LEVEL) {
- ASSERT((guest_pte & PT_PAGE_SIZE_MASK));
- ASSERT(PTTYPE == 64 || is_pse(vcpu));
+ gpa_t gpa = UNMAPPED_GVA;
+ int r;
- gpa = (guest_pte & PT_DIR_BASE_ADDR_MASK) | (vaddr &
- (PT_LEVEL_MASK(PT_PAGE_TABLE_LEVEL) | ~PAGE_MASK));
+ r = FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0);
- if (PTTYPE == 32 && is_cpuid_PSE36())
- gpa |= (guest_pte & PT32_DIR_PSE36_MASK) <<
- (32 - PT32_DIR_PSE36_SHIFT);
- } else {
- gpa = (guest_pte & PT_BASE_ADDR_MASK);
- gpa |= (vaddr & ~PAGE_MASK);
+ if (r) {
+ gpa = (gpa_t)walker.gfn << PAGE_SHIFT;
+ gpa |= vaddr & ~PAGE_MASK;
}
+ FNAME(release_walker)(&walker);
return gpa;
}
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 85f61dd1e936..83da4ea150a3 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -528,7 +528,13 @@ static void init_vmcb(struct vmcb *vmcb)
save->cs.attrib = SVM_SELECTOR_READ_MASK | SVM_SELECTOR_P_MASK |
SVM_SELECTOR_S_MASK | SVM_SELECTOR_CODE_MASK;
save->cs.limit = 0xffff;
- save->cs.base = 0xffff0000;
+ /*
+ * cs.base should really be 0xffff0000, but vmx can't handle that, so
+ * be consistent with it.
+ *
+ * Replace when we have real mode working for vmx.
+ */
+ save->cs.base = 0xf0000;
save->gdtr.limit = 0xffff;
save->idtr.limit = 0xffff;
@@ -603,6 +609,10 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu)
put_cpu();
}
+static void svm_vcpu_decache(struct kvm_vcpu *vcpu)
+{
+}
+
static void svm_cache_regs(struct kvm_vcpu *vcpu)
{
vcpu->regs[VCPU_REGS_RAX] = vcpu->svm->vmcb->save.rax;
@@ -723,7 +733,7 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
}
#endif
vcpu->svm->cr0 = cr0;
- vcpu->svm->vmcb->save.cr0 = cr0 | CR0_PG_MASK;
+ vcpu->svm->vmcb->save.cr0 = cr0 | CR0_PG_MASK | CR0_WP_MASK;
vcpu->cr0 = cr0;
}
@@ -1671,6 +1681,7 @@ static struct kvm_arch_ops svm_arch_ops = {
.vcpu_load = svm_vcpu_load,
.vcpu_put = svm_vcpu_put,
+ .vcpu_decache = svm_vcpu_decache,
.set_guest_debug = svm_guest_debug,
.get_msr = svm_get_msr,
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 27e05a77e21a..1e640b899175 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -125,6 +125,15 @@ static void __vcpu_clear(void *arg)
per_cpu(current_vmcs, cpu) = NULL;
}
+static void vcpu_clear(struct kvm_vcpu *vcpu)
+{
+ if (vcpu->cpu != raw_smp_processor_id() && vcpu->cpu != -1)
+ smp_call_function_single(vcpu->cpu, __vcpu_clear, vcpu, 0, 1);
+ else
+ __vcpu_clear(vcpu);
+ vcpu->launched = 0;
+}
+
static unsigned long vmcs_readl(unsigned long field)
{
unsigned long value;
@@ -202,10 +211,8 @@ static struct kvm_vcpu *vmx_vcpu_load(struct kvm_vcpu *vcpu)
cpu = get_cpu();
- if (vcpu->cpu != cpu) {
- smp_call_function(__vcpu_clear, vcpu, 0, 1);
- vcpu->launched = 0;
- }
+ if (vcpu->cpu != cpu)
+ vcpu_clear(vcpu);
if (per_cpu(current_vmcs, cpu) != vcpu->vmcs) {
u8 error;
@@ -243,6 +250,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
put_cpu();
}
+static void vmx_vcpu_decache(struct kvm_vcpu *vcpu)
+{
+ vcpu_clear(vcpu);
+}
+
static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
{
return vmcs_readl(GUEST_RFLAGS);
@@ -502,7 +514,7 @@ static __init int vmx_disabled_by_bios(void)
return (msr & 5) == 1; /* locked but not enabled */
}
-static __init void hardware_enable(void *garbage)
+static void hardware_enable(void *garbage)
{
int cpu = raw_smp_processor_id();
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
@@ -1375,6 +1387,11 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu,
return 1;
}
+static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+ kvm_run->exit_reason = KVM_EXIT_SHUTDOWN;
+ return 0;
+}
static int get_io_count(struct kvm_vcpu *vcpu, u64 *count)
{
@@ -1635,6 +1652,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
struct kvm_run *kvm_run) = {
[EXIT_REASON_EXCEPTION_NMI] = handle_exception,
[EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt,
+ [EXIT_REASON_TRIPLE_FAULT] = handle_triple_fault,
[EXIT_REASON_IO_INSTRUCTION] = handle_io,
[EXIT_REASON_CR_ACCESS] = handle_cr,
[EXIT_REASON_DR_ACCESS] = handle_dr,
@@ -1786,10 +1804,10 @@ again:
"kvm_vmx_return: "
/* Save guest registers, load host registers, keep flags */
#ifdef CONFIG_X86_64
- "xchg %3, 0(%%rsp) \n\t"
+ "xchg %3, (%%rsp) \n\t"
"mov %%rax, %c[rax](%3) \n\t"
"mov %%rbx, %c[rbx](%3) \n\t"
- "pushq 0(%%rsp); popq %c[rcx](%3) \n\t"
+ "pushq (%%rsp); popq %c[rcx](%3) \n\t"
"mov %%rdx, %c[rdx](%3) \n\t"
"mov %%rsi, %c[rsi](%3) \n\t"
"mov %%rdi, %c[rdi](%3) \n\t"
@@ -1804,24 +1822,24 @@ again:
"mov %%r15, %c[r15](%3) \n\t"
"mov %%cr2, %%rax \n\t"
"mov %%rax, %c[cr2](%3) \n\t"
- "mov 0(%%rsp), %3 \n\t"
+ "mov (%%rsp), %3 \n\t"
"pop %%rcx; pop %%r15; pop %%r14; pop %%r13; pop %%r12;"
"pop %%r11; pop %%r10; pop %%r9; pop %%r8;"
"pop %%rbp; pop %%rdi; pop %%rsi;"
"pop %%rdx; pop %%rbx; pop %%rax \n\t"
#else
- "xchg %3, 0(%%esp) \n\t"
+ "xchg %3, (%%esp) \n\t"
"mov %%eax, %c[rax](%3) \n\t"
"mov %%ebx, %c[rbx](%3) \n\t"
- "pushl 0(%%esp); popl %c[rcx](%3) \n\t"
+ "pushl (%%esp); popl %c[rcx](%3) \n\t"
"mov %%edx, %c[rdx](%3) \n\t"
"mov %%esi, %c[rsi](%3) \n\t"
"mov %%edi, %c[rdi](%3) \n\t"
"mov %%ebp, %c[rbp](%3) \n\t"
"mov %%cr2, %%eax \n\t"
"mov %%eax, %c[cr2](%3) \n\t"
- "mov 0(%%esp), %3 \n\t"
+ "mov (%%esp), %3 \n\t"
"pop %%ecx; popa \n\t"
#endif
@@ -1859,9 +1877,7 @@ again:
fx_restore(vcpu->host_fx_image);
vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
-#ifndef CONFIG_X86_64
asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
-#endif
/*
* Profile KVM exit RIPs:
@@ -2012,6 +2028,7 @@ static struct kvm_arch_ops vmx_arch_ops = {
.vcpu_load = vmx_vcpu_load,
.vcpu_put = vmx_vcpu_put,
+ .vcpu_decache = vmx_vcpu_decache,
.set_guest_debug = set_guest_debug,
.get_msr = vmx_get_msr,
diff --git a/drivers/kvm/vmx.h b/drivers/kvm/vmx.h
index 4c0ab151836a..d0dc93df411b 100644
--- a/drivers/kvm/vmx.h
+++ b/drivers/kvm/vmx.h
@@ -180,6 +180,7 @@ enum vmcs_field {
#define EXIT_REASON_EXCEPTION_NMI 0
#define EXIT_REASON_EXTERNAL_INTERRUPT 1
+#define EXIT_REASON_TRIPLE_FAULT 2
#define EXIT_REASON_PENDING_INTERRUPT 7
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 7cec6de5e2b0..f729eebf771f 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -885,7 +885,7 @@ out:
return ret;
}
-static struct file_operations adb_fops = {
+static const struct file_operations adb_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = adb_read,
diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c
index 2b8a6e821d44..cdd5a0f72e3c 100644
--- a/drivers/macintosh/ans-lcd.c
+++ b/drivers/macintosh/ans-lcd.c
@@ -121,7 +121,7 @@ anslcd_open( struct inode * inode, struct file * file )
return 0;
}
-struct file_operations anslcd_fops = {
+const struct file_operations anslcd_fops = {
.write = anslcd_write,
.ioctl = anslcd_ioctl,
.open = anslcd_open,
diff --git a/drivers/macintosh/apm_emu.c b/drivers/macintosh/apm_emu.c
index 4300c628f8af..a6d50f4fabd7 100644
--- a/drivers/macintosh/apm_emu.c
+++ b/drivers/macintosh/apm_emu.c
@@ -501,7 +501,7 @@ static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length)
return p - buf;
}
-static struct file_operations apm_bios_fops = {
+static const struct file_operations apm_bios_fops = {
.owner = THIS_MODULE,
.read = do_read,
.poll = do_poll,
diff --git a/drivers/macintosh/nvram.c b/drivers/macintosh/nvram.c
index 30791875fc97..b195d753d2ed 100644
--- a/drivers/macintosh/nvram.c
+++ b/drivers/macintosh/nvram.c
@@ -100,7 +100,7 @@ static int nvram_ioctl(struct inode *inode, struct file *file,
return 0;
}
-struct file_operations nvram_fops = {
+const struct file_operations nvram_fops = {
.owner = THIS_MODULE,
.llseek = nvram_llseek,
.read = read_nvram,
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 6f30459b9385..3096836d8bd3 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -1277,7 +1277,7 @@ static int smu_release(struct inode *inode, struct file *file)
}
-static struct file_operations smu_device_fops = {
+static const struct file_operations smu_device_fops = {
.llseek = no_llseek,
.read = smu_read,
.write = smu_write,
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 8ca75e52f637..96bea4b62c43 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -516,7 +516,6 @@ static int __init via_pmu_dev_init(void)
proc_get_irqstats, NULL);
proc_pmu_options = create_proc_entry("options", 0600, proc_pmu_root);
if (proc_pmu_options) {
- proc_pmu_options->nlink = 1;
proc_pmu_options->read_proc = proc_read_options;
proc_pmu_options->write_proc = proc_write_options;
}
@@ -2673,7 +2672,7 @@ pmu_ioctl(struct inode * inode, struct file *filp,
return error;
}
-static struct file_operations pmu_device_fops = {
+static const struct file_operations pmu_device_fops = {
.read = pmu_read,
.write = pmu_write,
.poll = pmu_fpoll,
diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c
index 93e6ef9233f9..4f5b6fa196c5 100644
--- a/drivers/macintosh/via-pmu68k.c
+++ b/drivers/macintosh/via-pmu68k.c
@@ -1040,7 +1040,7 @@ static int pmu_ioctl(struct inode * inode, struct file *filp,
return -EINVAL;
}
-static struct file_operations pmu_device_fops = {
+static const struct file_operations pmu_device_fops = {
.read = pmu_read,
.write = pmu_write,
.ioctl = pmu_ioctl,
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 059704fbb753..5554adaa58f9 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -666,7 +666,7 @@ static void bitmap_file_put(struct bitmap *bitmap)
if (file) {
struct inode *inode = file->f_path.dentry->d_inode;
- invalidate_inode_pages(inode->i_mapping);
+ invalidate_mapping_pages(inode->i_mapping, 0, -1);
fput(file);
}
}
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index cd6a184536a1..b441d82c338a 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1473,7 +1473,7 @@ static int ctl_ioctl(struct inode *inode, struct file *file,
return r;
}
-static struct file_operations _ctl_fops = {
+static const struct file_operations _ctl_fops = {
.ioctl = ctl_ioctl,
.owner = THIS_MODULE,
};
diff --git a/drivers/md/md.c b/drivers/md/md.c
index e8807ea5377d..e85fa75a7912 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4920,7 +4920,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
return mask;
}
-static struct file_operations md_seq_fops = {
+static const struct file_operations md_seq_fops = {
.owner = THIS_MODULE,
.open = md_seq_open,
.read = seq_read,
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index d867a6a9e430..b8dcfa165266 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -416,7 +416,7 @@ static ssize_t fops_write(struct file *file, const char __user *data, size_t cou
}
}
-static struct file_operations video_fops =
+static const struct file_operations video_fops =
{
.owner = THIS_MODULE,
.open = fops_open,
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index db865a0667e5..df8d0520d1d1 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -144,7 +144,7 @@ struct dsbr100_device {
/* File system interface */
-static struct file_operations usb_dsbr100_fops = {
+static const struct file_operations usb_dsbr100_fops = {
.owner = THIS_MODULE,
.open = usb_dsbr100_open,
.release = usb_dsbr100_close,
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
index c4312fa0e2f5..c7c9d1dc0690 100644
--- a/drivers/media/radio/miropcm20-radio.c
+++ b/drivers/media/radio/miropcm20-radio.c
@@ -216,7 +216,7 @@ static struct pcm20_device pcm20_unit = {
.muted = 1,
};
-static struct file_operations pcm20_fops = {
+static const struct file_operations pcm20_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/miropcm20-rds.c b/drivers/media/radio/miropcm20-rds.c
index c1b1db65e668..c93490ec96bb 100644
--- a/drivers/media/radio/miropcm20-rds.c
+++ b/drivers/media/radio/miropcm20-rds.c
@@ -105,7 +105,7 @@ static ssize_t rds_f_read(struct file *file, char __user *buffer, size_t length,
}
}
-static struct file_operations rds_fops = {
+static const struct file_operations rds_fops = {
.owner = THIS_MODULE,
.read = rds_f_read,
.open = rds_f_open,
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index 3368a89bfadb..b2e88ad28977 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -358,7 +358,7 @@ static int rt_ioctl(struct inode *inode, struct file *file,
static struct rt_device rtrack_unit;
-static struct file_operations rtrack_fops = {
+static const struct file_operations rtrack_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 3ba5fa8cf7e6..19d45cc940b5 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -314,7 +314,7 @@ static int az_ioctl(struct inode *inode, struct file *file,
static struct az_device aztech_unit;
-static struct file_operations aztech_fops = {
+static const struct file_operations aztech_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 69d4b7919c5a..8fbf0d8bd278 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -507,7 +507,7 @@ cadet_poll(struct file *file, struct poll_table_struct *wait)
}
-static struct file_operations cadet_fops = {
+static const struct file_operations cadet_fops = {
.owner = THIS_MODULE,
.open = cadet_open,
.release = cadet_release,
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index eb14106f66fa..05e5aa77025f 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -346,7 +346,7 @@ MODULE_DEVICE_TABLE( pci, gemtek_pci_id );
static int mx = 1;
-static struct file_operations gemtek_pci_fops = {
+static const struct file_operations gemtek_pci_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 730fe16126cb..36c4be6622c7 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -296,7 +296,7 @@ static int gemtek_ioctl(struct inode *inode, struct file *file,
static struct gemtek_device gemtek_unit;
-static struct file_operations gemtek_fops = {
+static const struct file_operations gemtek_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index e8ce5f75cf12..9bba6eb10925 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -99,7 +99,7 @@ static struct pci_driver maestro_r_driver = {
.remove = __devexit_p(maestro_remove),
};
-static struct file_operations maestro_fops = {
+static const struct file_operations maestro_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index c2eeae7a10d0..00a2f31d2af3 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -91,7 +91,7 @@ module_param(radio_nr, int, 0);
static int radio_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
-static struct file_operations maxiradio_fops = {
+static const struct file_operations maxiradio_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index b9e98483e58d..f6683872251e 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -262,7 +262,7 @@ static int rt_ioctl(struct inode *inode, struct file *file,
static struct rt_device rtrack2_unit;
-static struct file_operations rtrack2_fops = {
+static const struct file_operations rtrack2_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index ecc854b4ba38..f4619e4dda4f 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -265,7 +265,7 @@ static int fmi_ioctl(struct inode *inode, struct file *file,
static struct fmi_device fmi_unit;
-static struct file_operations fmi_fops = {
+static const struct file_operations fmi_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 4444dce864a9..b96fafe1f9da 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -410,7 +410,7 @@ static int fmr2_ioctl(struct inode *inode, struct file *file,
static struct fmr2_device fmr2_unit;
-static struct file_operations fmr2_fops = {
+static const struct file_operations fmr2_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index f539491a0d76..d59a27accb84 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -338,7 +338,7 @@ static int tt_ioctl(struct inode *inode, struct file *file,
static struct tt_device terratec_unit;
-static struct file_operations terratec_fops = {
+static const struct file_operations terratec_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index bb03ad5a2033..6d7f1e7116ea 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -325,7 +325,7 @@ static int tr_ioctl(struct inode *inode, struct file *file,
return video_usercopy(inode, file, cmd, arg, tr_do_ioctl);
}
-static struct file_operations trust_fops = {
+static const struct file_operations trust_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index 4a72b4d4e62a..3031fef178cb 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -318,7 +318,7 @@ static struct typhoon_device typhoon_unit =
.mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ,
};
-static struct file_operations typhoon_fops = {
+static const struct file_operations typhoon_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index 671fe1b1e5bc..ec08491fb7c5 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -373,7 +373,7 @@ static int zol_ioctl(struct inode *inode, struct file *file,
static struct zol_device zoltrix_unit;
-static struct file_operations zoltrix_fops =
+static const struct file_operations zoltrix_fops =
{
.owner = THIS_MODULE,
.open = video_exclusive_open,
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 4861799eb430..649f52f9ad27 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -742,7 +742,7 @@ void ar_release(struct video_device *vfd)
* Video4Linux Module functions
*
****************************************************************************/
-static struct file_operations ar_fops = {
+static const struct file_operations ar_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index ab8f970760f2..41fd09d7d11e 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3174,7 +3174,7 @@ bttv_mmap(struct file *file, struct vm_area_struct *vma)
return videobuf_mmap_mapper(bttv_queue(fh),vma);
}
-static struct file_operations bttv_fops =
+static const struct file_operations bttv_fops =
{
.owner = THIS_MODULE,
.open = bttv_open,
@@ -3332,7 +3332,7 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)
return cmd.result;
}
-static struct file_operations radio_fops =
+static const struct file_operations radio_fops =
{
.owner = THIS_MODULE,
.open = radio_open,
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 7d0b6e59c6e2..7d47cbe6ad25 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -871,7 +871,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
return len;
}
-static struct file_operations qcam_fops = {
+static const struct file_operations qcam_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index a3989bd2f81b..925ff17efbbc 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -684,7 +684,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf,
}
/* video device template */
-static struct file_operations qcam_fops = {
+static const struct file_operations qcam_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 3083c8075d13..fb1410c6f864 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1715,7 +1715,7 @@ static void cafe_v4l_dev_release(struct video_device *vd)
* clone it for specific real devices.
*/
-static struct file_operations cafe_v4l_fops = {
+static const struct file_operations cafe_v4l_fops = {
.owner = THIS_MODULE,
.open = cafe_v4l_open,
.release = cafe_v4l_release,
@@ -1969,7 +1969,7 @@ static ssize_t cafe_dfs_read_regs(struct file *file,
s - cafe_debug_buf);
}
-static struct file_operations cafe_dfs_reg_ops = {
+static const struct file_operations cafe_dfs_reg_ops = {
.owner = THIS_MODULE,
.read = cafe_dfs_read_regs,
.open = cafe_dfs_open
@@ -1995,7 +1995,7 @@ static ssize_t cafe_dfs_read_cam(struct file *file,
s - cafe_debug_buf);
}
-static struct file_operations cafe_dfs_cam_ops = {
+static const struct file_operations cafe_dfs_cam_ops = {
.owner = THIS_MODULE,
.read = cafe_dfs_read_cam,
.open = cafe_dfs_open
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 3b31a0dd2f0c..7e8d5ef58b61 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -3791,7 +3791,7 @@ static int cpia_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
-static struct file_operations cpia_fops = {
+static const struct file_operations cpia_fops = {
.owner = THIS_MODULE,
.open = cpia_open,
.release = cpia_close,
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index d09f49950f2a..1bda7ad9de11 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -1924,7 +1924,7 @@ static void reset_camera_struct_v4l(struct camera_data *cam)
/***
* The v4l video device structure initialized for this device
***/
-static struct file_operations fops_template = {
+static const struct file_operations fops_template = {
.owner = THIS_MODULE,
.open = cpia2_open,
.release = cpia2_close,
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 0cf0360588e6..9a7a2996f20f 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1051,7 +1051,7 @@ mpeg_mmap(struct file *file, struct vm_area_struct * vma)
return videobuf_mmap_mapper(&fh->mpegq, vma);
}
-static struct file_operations mpeg_fops =
+static const struct file_operations mpeg_fops =
{
.owner = THIS_MODULE,
.open = mpeg_open,
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 8613378428fd..c86a7e06235b 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1808,7 +1808,7 @@ static irqreturn_t cx8800_irq(int irq, void *dev_id)
/* ----------------------------------------------------------- */
/* exported stuff */
-static struct file_operations video_fops =
+static const struct file_operations video_fops =
{
.owner = THIS_MODULE,
.open = video_open,
@@ -1839,7 +1839,7 @@ static struct video_device cx8800_vbi_template =
.minor = -1,
};
-static struct file_operations radio_fops =
+static const struct file_operations radio_fops =
{
.owner = THIS_MODULE,
.open = video_open,
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index 917021fc2993..ff4b238090ac 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -696,7 +696,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
return ret;
}
-static struct file_operations dabusb_fops =
+static const struct file_operations dabusb_fops =
{
.owner = THIS_MODULE,
.llseek = no_llseek,
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 36e72c207a8f..bec67609500f 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1480,7 +1480,7 @@ static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
return ret;
}
-static struct file_operations em28xx_v4l_fops = {
+static const struct file_operations em28xx_v4l_fops = {
.owner = THIS_MODULE,
.open = em28xx_v4l2_open,
.release = em28xx_v4l2_close,
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index 86e353b26b53..49792ae8c61c 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -2454,7 +2454,7 @@ static int et61x251_ioctl(struct inode* inode, struct file* filp,
}
-static struct file_operations et61x251_fops = {
+static const struct file_operations et61x251_fops = {
.owner = THIS_MODULE,
.open = et61x251_open,
.release = et61x251_release,
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 616a35da191d..9528e10c2828 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1748,7 +1748,7 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
-static struct file_operations meye_fops = {
+static const struct file_operations meye_fops = {
.owner = THIS_MODULE,
.open = meye_open,
.release = meye_release,
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index b4db2cbb5a84..e5edff1059a2 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -4653,7 +4653,7 @@ ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
-static struct file_operations ov511_fops = {
+static const struct file_operations ov511_fops = {
.owner = THIS_MODULE,
.open = ov51x_v4l1_open,
.release = ov51x_v4l1_close,
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index 5d681fa8bcb1..d38d3dc4a012 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -881,7 +881,7 @@ static ssize_t pms_read(struct file *file, char __user *buf,
return len;
}
-static struct file_operations pms_fops = {
+static const struct file_operations pms_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index bb40e9085977..6cf17080eb49 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -986,7 +986,7 @@ static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
}
-static struct file_operations vdev_fops = {
+static const struct file_operations vdev_fops = {
.owner = THIS_MODULE,
.open = pvr2_v4l2_open,
.release = pvr2_v4l2_release,
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index a996aad79276..9825fd348108 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -152,7 +152,7 @@ static int pwc_video_ioctl(struct inode *inode, struct file *file,
unsigned int ioctlnr, unsigned long arg);
static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
-static struct file_operations pwc_fops = {
+static const struct file_operations pwc_fops = {
.owner = THIS_MODULE,
.open = pwc_video_open,
.release = pwc_video_close,
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 77bb940a1a4f..0b5d159895bf 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -817,7 +817,7 @@ static void __exit cleanup_saa_5246a (void)
module_init(init_saa_5246a);
module_exit(cleanup_saa_5246a);
-static struct file_operations saa_fops = {
+static const struct file_operations saa_fops = {
.owner = THIS_MODULE,
.open = saa5246a_open,
.release = saa5246a_release,
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index bb3fb4387f65..3e84737878a8 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -699,7 +699,7 @@ static void __exit cleanup_saa_5249 (void)
module_init(init_saa_5249);
module_exit(cleanup_saa_5249);
-static struct file_operations saa_fops = {
+static const struct file_operations saa_fops = {
.owner = THIS_MODULE,
.open = saa5249_open,
.release = saa5249_release,
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index daaae870a2c4..f521603482ca 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -319,7 +319,7 @@ static int ts_ioctl(struct inode *inode, struct file *file,
return video_usercopy(inode, file, cmd, arg, ts_do_ioctl);
}
-static struct file_operations ts_fops =
+static const struct file_operations ts_fops =
{
.owner = THIS_MODULE,
.open = ts_open,
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index bfcb860d14cc..72444f039e3d 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -563,7 +563,7 @@ static unsigned int dsp_poll(struct file *file, struct poll_table_struct *wait)
return mask;
}
-struct file_operations saa7134_dsp_fops = {
+const struct file_operations saa7134_dsp_fops = {
.owner = THIS_MODULE,
.open = dsp_open,
.release = dsp_release,
@@ -804,7 +804,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file,
}
}
-struct file_operations saa7134_mixer_fops = {
+const struct file_operations saa7134_mixer_fops = {
.owner = THIS_MODULE,
.open = mixer_open,
.release = mixer_release,
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 830617ea81cc..f2cb63053041 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -2336,7 +2336,7 @@ static int radio_ioctl(struct inode *inode, struct file *file,
return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
}
-static struct file_operations video_fops =
+static const struct file_operations video_fops =
{
.owner = THIS_MODULE,
.open = video_open,
@@ -2349,7 +2349,7 @@ static struct file_operations video_fops =
.llseek = no_llseek,
};
-static struct file_operations radio_fops =
+static const struct file_operations radio_fops =
{
.owner = THIS_MODULE,
.open = video_open,
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index e88ad7b40c47..88cd1297df13 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -683,8 +683,8 @@ int saa_dsp_writel(struct saa7134_dev *dev, int reg, u32 value);
/* ----------------------------------------------------------- */
/* saa7134-oss.c */
-extern struct file_operations saa7134_dsp_fops;
-extern struct file_operations saa7134_mixer_fops;
+extern const struct file_operations saa7134_dsp_fops;
+extern const struct file_operations saa7134_mixer_fops;
int saa7134_oss_init1(struct saa7134_dev *dev);
int saa7134_oss_fini(struct saa7134_dev *dev);
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 7aeec574d7ce..038448f5a978 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -1185,7 +1185,7 @@ static int se401_mmap(struct file *file, struct vm_area_struct *vma)
return 0;
}
-static struct file_operations se401_fops = {
+static const struct file_operations se401_fops = {
.owner = THIS_MODULE,
.open = se401_open,
.release = se401_close,
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 18458d46c0ff..04d4c8f28b89 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -2736,7 +2736,7 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp,
/*****************************************************************************/
-static struct file_operations sn9c102_fops = {
+static const struct file_operations sn9c102_fops = {
.owner = THIS_MODULE,
.open = sn9c102_open,
.release = sn9c102_release,
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index 525d81288d55..3e736be5de84 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -1901,7 +1901,7 @@ static int saa_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations saa_fops = {
+static const struct file_operations saa_fops = {
.owner = THIS_MODULE,
.open = saa_open,
.release = saa_release,
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index a1ec3aca3f91..bf3aa8d2d57e 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -1380,7 +1380,7 @@ static ssize_t stv680_read (struct file *file, char __user *buf,
return realcount;
} /* stv680_read */
-static struct file_operations stv680_fops = {
+static const struct file_operations stv680_fops = {
.owner = THIS_MODULE,
.open = stv_open,
.release = stv_close,
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index 1654576de10e..e2747bd373fd 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -228,7 +228,7 @@ static struct i2c_driver driver = {
.detach_client = tvmixer_clients,
};
-static struct file_operations tvmixer_fops = {
+static const struct file_operations tvmixer_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = tvmixer_ioctl,
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index b560c9d7c516..d34d8c8b7376 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -945,7 +945,7 @@ static int usbvideo_find_struct(struct usbvideo *cams)
return rv;
}
-static struct file_operations usbvideo_fops = {
+static const struct file_operations usbvideo_fops = {
.owner = THIS_MODULE,
.open = usbvideo_v4l_open,
.release =usbvideo_v4l_close,
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 08f9559a6bfa..876fd2768242 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -1234,7 +1234,7 @@ static inline void vicam_create_proc_entry(struct vicam_camera *cam) { }
static inline void vicam_destroy_proc_entry(void *ptr) { }
#endif
-static struct file_operations vicam_fops = {
+static const struct file_operations vicam_fops = {
.owner = THIS_MODULE,
.open = vicam_open,
.release = vicam_close,
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index bdd6301d2a47..4eb7330b96f8 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1475,7 +1475,7 @@ static int usbvision_vbi_ioctl(struct inode *inode, struct file *file,
//
// Video template
-static struct file_operations usbvision_fops = {
+static const struct file_operations usbvision_fops = {
.owner = THIS_MODULE,
.open = usbvision_v4l2_open,
.release = usbvision_v4l2_close,
@@ -1496,7 +1496,7 @@ static struct video_device usbvision_video_template = {
// Radio template
-static struct file_operations usbvision_radio_fops = {
+static const struct file_operations usbvision_radio_fops = {
.owner = THIS_MODULE,
.open = usbvision_radio_open,
.release = usbvision_radio_close,
@@ -1517,7 +1517,7 @@ static struct video_device usbvision_radio_template=
// vbi template
-static struct file_operations usbvision_vbi_fops = {
+static const struct file_operations usbvision_vbi_fops = {
.owner = THIS_MODULE,
.open = usbvision_vbi_open,
.release = usbvision_vbi_close,
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 6a0e8ca72948..30c3822692fb 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -1561,7 +1561,7 @@ out:
}
-static struct file_operations video_fops;
+static const struct file_operations video_fops;
/**
* video_register_device - register video4linux devices
@@ -1709,7 +1709,7 @@ void video_unregister_device(struct video_device *vfd)
/*
* Video fs operations
*/
-static struct file_operations video_fops=
+static const struct file_operations video_fops=
{
.owner = THIS_MODULE,
.llseek = no_llseek,
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index a373c142e742..0c658b74f2c4 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -4390,7 +4390,7 @@ static int vino_ioctl(struct inode *inode, struct file *file,
// __initdata
static int vino_init_stage = 0;
-static struct file_operations vino_fops = {
+static const struct file_operations vino_fops = {
.owner = THIS_MODULE,
.open = vino_open,
.release = vino_close,
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index d4cf55666731..cfb6b1f0402c 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1292,7 +1292,7 @@ vivi_mmap(struct file *file, struct vm_area_struct * vma)
return ret;
}
-static struct file_operations vivi_fops = {
+static const struct file_operations vivi_fops = {
.owner = THIS_MODULE,
.open = vivi_open,
.release = vivi_release,
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 8d14f308f171..47366408637c 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -183,7 +183,7 @@ static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos);
-static struct file_operations w9966_fops = {
+static const struct file_operations w9966_fops = {
.owner = THIS_MODULE,
.open = video_exclusive_open,
.release = video_exclusive_release,
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 9f403af7b040..6e64af293be5 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -399,7 +399,7 @@ MODULE_PARM_DESC(specific_debug,
****************************************************************************/
/* Video4linux interface */
-static struct file_operations w9968cf_fops;
+static const struct file_operations w9968cf_fops;
static int w9968cf_open(struct inode*, struct file*);
static int w9968cf_release(struct inode*, struct file*);
static int w9968cf_mmap(struct file*, struct vm_area_struct*);
@@ -3466,7 +3466,7 @@ ioctl_fail:
}
-static struct file_operations w9968cf_fops = {
+static const struct file_operations w9968cf_fops = {
.owner = THIS_MODULE,
.open = w9968cf_open,
.release = w9968cf_release,
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 52d0f759ee00..8da7f15f6290 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1871,7 +1871,7 @@ static int zc0301_ioctl(struct inode* inode, struct file* filp,
}
-static struct file_operations zc0301_fops = {
+static const struct file_operations zc0301_fops = {
.owner = THIS_MODULE,
.open = zc0301_open,
.release = zc0301_release,
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 862a984c2155..074323733352 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -562,7 +562,6 @@ jpg_fbuffer_alloc (struct file *file)
jpg_fbuffer_free(file);
return -ENOBUFS;
}
- memset((void *) mem, 0, PAGE_SIZE);
fh->jpg_buffers.buffer[i].frag_tab = (u32 *) mem;
fh->jpg_buffers.buffer[i].frag_tab_bus =
virt_to_bus((void *) mem);
@@ -4680,7 +4679,7 @@ zoran_mmap (struct file *file,
return 0;
}
-static struct file_operations zoran_fops = {
+static const struct file_operations zoran_fops = {
.owner = THIS_MODULE,
.open = zoran_open,
.release = zoran_close,
diff --git a/drivers/media/video/zoran_procfs.c b/drivers/media/video/zoran_procfs.c
index c374c76b3753..446ae8d5c3df 100644
--- a/drivers/media/video/zoran_procfs.c
+++ b/drivers/media/video/zoran_procfs.c
@@ -186,7 +186,7 @@ static ssize_t zoran_write(struct file *file, const char __user *buffer,
return count;
}
-static struct file_operations zoran_operations = {
+static const struct file_operations zoran_operations = {
.open = zoran_open,
.read = seq_read,
.write = zoran_write,
diff --git a/drivers/message/fusion/Kconfig b/drivers/message/fusion/Kconfig
index ea31d8470510..71037f91c222 100644
--- a/drivers/message/fusion/Kconfig
+++ b/drivers/message/fusion/Kconfig
@@ -66,7 +66,7 @@ config FUSION_MAX_SGE
config FUSION_CTL
tristate "Fusion MPT misc device (ioctl) driver"
- depends on FUSION_SPI || FUSION_FC
+ depends on FUSION_SPI || FUSION_FC || FUSION_SAS
---help---
The Fusion MPT misc device driver provides specialized control
of MPT adapters via system ioctl calls. Use of ioctl calls to
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile
index 341691390e86..6003b46c8438 100644
--- a/drivers/message/fusion/Makefile
+++ b/drivers/message/fusion/Makefile
@@ -8,6 +8,9 @@
#EXTRA_CFLAGS += -DMPT_DEBUG_INIT
#EXTRA_CFLAGS += -DMPT_DEBUG_EXIT
#EXTRA_CFLAGS += -DMPT_DEBUG_FAIL
+#EXTRA_CFLAGS += -DMPT_DEBUG_DV
+#EXTRA_CFLAGS += -DMPT_DEBUG_TM
+#EXTRA_CFLAGS += -DMPT_DEBUG_REPLY
#
# driver/module specifics...
@@ -20,11 +23,7 @@
#CFLAGS_mptbase.o += -DMPT_DEBUG_RESET
#
# For mptscsih:
-#CFLAGS_mptscsih.o += -DMPT_DEBUG_DV
-#CFLAGS_mptscsih.o += -DMPT_DEBUG_NEGO
-#CFLAGS_mptscsih.o += -DMPT_DEBUG_TM
#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCSI
-#CFLAGS_mptscsih.o += -DMPT_DEBUG_REPLY
#
# For mptctl:
#CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL
diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h
index 81ad77622dac..75223bf24ae8 100644
--- a/drivers/message/fusion/lsi/mpi.h
+++ b/drivers/message/fusion/lsi/mpi.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2005 LSI Logic Corporation.
+ * Copyright (c) 2000-2006 LSI Logic Corporation.
*
*
* Name: mpi.h
* Title: MPI Message independent structures and definitions
* Creation Date: July 27, 2000
*
- * mpi.h Version: 01.05.11
+ * mpi.h Version: 01.05.12
*
* Version History
* ---------------
@@ -77,6 +77,7 @@
* 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
* 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
* 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
+ * 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT.
* --------------------------------------------------------------------------
*/
@@ -107,7 +108,7 @@
/* Note: The major versions of 0xe0 through 0xff are reserved */
/* versioning for this MPI header set */
-#define MPI_HEADER_VERSION_UNIT (0x0D)
+#define MPI_HEADER_VERSION_UNIT (0x0E)
#define MPI_HEADER_VERSION_DEV (0x00)
#define MPI_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI_HEADER_VERSION_UNIT_SHIFT (8)
diff --git a/drivers/message/fusion/lsi/mpi_cnfg.h b/drivers/message/fusion/lsi/mpi_cnfg.h
index 47e13e360c10..0e4c8e77a81d 100644
--- a/drivers/message/fusion/lsi/mpi_cnfg.h
+++ b/drivers/message/fusion/lsi/mpi_cnfg.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2005 LSI Logic Corporation.
+ * Copyright (c) 2000-2006 LSI Logic Corporation.
*
*
* Name: mpi_cnfg.h
* Title: MPI Config message, structures, and Pages
* Creation Date: July 27, 2000
*
- * mpi_cnfg.h Version: 01.05.12
+ * mpi_cnfg.h Version: 01.05.13
*
* Version History
* ---------------
@@ -276,6 +276,23 @@
* Added AdditionalControlFlags, MaxTargetPortConnectTime,
* ReportDeviceMissingDelay, and IODeviceMissingDelay
* fields to SAS IO Unit Page 1.
+ * 10-11-06 01.05.13 Added NumForceWWID field and ForceWWID array to
+ * Manufacturing Page 5.
+ * Added Manufacturing pages 8 through 10.
+ * Added defines for supported metadata size bits in
+ * CapabilitiesFlags field of IOC Page 6.
+ * Added defines for metadata size bits in VolumeSettings
+ * field of RAID Volume Page 0.
+ * Added SATA Link Reset settings, Enable SATA Asynchronous
+ * Notification bit, and HideNonZeroAttachedPhyIdentifiers
+ * bit to AdditionalControlFlags field of SAS IO Unit
+ * Page 1.
+ * Added defines for Enclosure Devices Unmapped and
+ * Device Limit Exceeded bits in Status field of SAS IO
+ * Unit Page 2.
+ * Added more AccessStatus values for SAS Device Page 0.
+ * Added bit for SATA Asynchronous Notification Support in
+ * Flags field of SAS Device Page 0.
* --------------------------------------------------------------------------
*/
@@ -654,17 +671,24 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_4
#define MPI_MANPAGE4_IR_NO_MIX_SAS_SATA (0x01)
+#ifndef MPI_MANPAGE5_NUM_FORCEWWID
+#define MPI_MANPAGE5_NUM_FORCEWWID (1)
+#endif
+
typedef struct _CONFIG_PAGE_MANUFACTURING_5
{
CONFIG_PAGE_HEADER Header; /* 00h */
U64 BaseWWID; /* 04h */
U8 Flags; /* 0Ch */
- U8 Reserved1; /* 0Dh */
+ U8 NumForceWWID; /* 0Dh */
U16 Reserved2; /* 0Eh */
+ U32 Reserved3; /* 10h */
+ U32 Reserved4; /* 14h */
+ U64 ForceWWID[MPI_MANPAGE5_NUM_FORCEWWID]; /* 18h */
} CONFIG_PAGE_MANUFACTURING_5, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_5,
ManufacturingPage5_t, MPI_POINTER pManufacturingPage5_t;
-#define MPI_MANUFACTURING5_PAGEVERSION (0x01)
+#define MPI_MANUFACTURING5_PAGEVERSION (0x02)
/* defines for the Flags field */
#define MPI_MANPAGE5_TWO_WWID_PER_PHY (0x01)
@@ -740,6 +764,36 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_7
#define MPI_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001)
+typedef struct _CONFIG_PAGE_MANUFACTURING_8
+{
+ CONFIG_PAGE_HEADER Header; /* 00h */
+ U32 ProductSpecificInfo;/* 04h */
+} CONFIG_PAGE_MANUFACTURING_8, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_8,
+ ManufacturingPage8_t, MPI_POINTER pManufacturingPage8_t;
+
+#define MPI_MANUFACTURING8_PAGEVERSION (0x00)
+
+
+typedef struct _CONFIG_PAGE_MANUFACTURING_9
+{
+ CONFIG_PAGE_HEADER Header; /* 00h */
+ U32 ProductSpecificInfo;/* 04h */
+} CONFIG_PAGE_MANUFACTURING_9, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_9,
+ ManufacturingPage9_t, MPI_POINTER pManufacturingPage9_t;
+
+#define MPI_MANUFACTURING6_PAGEVERSION (0x00)
+
+
+typedef struct _CONFIG_PAGE_MANUFACTURING_10
+{
+ CONFIG_PAGE_HEADER Header; /* 00h */
+ U32 ProductSpecificInfo;/* 04h */
+} CONFIG_PAGE_MANUFACTURING_10, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_10,
+ ManufacturingPage10_t, MPI_POINTER pManufacturingPage10_t;
+
+#define MPI_MANUFACTURING10_PAGEVERSION (0x00)
+
+
/****************************************************************************
* IO Unit Config Pages
****************************************************************************/
@@ -1080,10 +1134,14 @@ typedef struct _CONFIG_PAGE_IOC_6
} CONFIG_PAGE_IOC_6, MPI_POINTER PTR_CONFIG_PAGE_IOC_6,
IOCPage6_t, MPI_POINTER pIOCPage6_t;
-#define MPI_IOCPAGE6_PAGEVERSION (0x00)
+#define MPI_IOCPAGE6_PAGEVERSION (0x01)
/* IOC Page 6 Capabilities Flags */
+#define MPI_IOCPAGE6_CAP_FLAGS_MASK_METADATA_SIZE (0x00000006)
+#define MPI_IOCPAGE6_CAP_FLAGS_64MB_METADATA_SIZE (0x00000000)
+#define MPI_IOCPAGE6_CAP_FLAGS_512MB_METADATA_SIZE (0x00000002)
+
#define MPI_IOCPAGE6_CAP_FLAGS_GLOBAL_HOT_SPARE (0x00000001)
@@ -2160,6 +2218,11 @@ typedef struct _RAID_VOL0_SETTINGS
#define MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE (0x0004)
#define MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC (0x0008)
#define MPI_RAIDVOL0_SETTING_FAST_DATA_SCRUBBING_0102 (0x0020) /* obsolete */
+
+#define MPI_RAIDVOL0_SETTING_MASK_METADATA_SIZE (0x00C0)
+#define MPI_RAIDVOL0_SETTING_64MB_METADATA_SIZE (0x0000)
+#define MPI_RAIDVOL0_SETTING_512MB_METADATA_SIZE (0x0040)
+
#define MPI_RAIDVOL0_SETTING_USE_PRODUCT_ID_SUFFIX (0x0010)
#define MPI_RAIDVOL0_SETTING_USE_DEFAULTS (0x8000)
@@ -2203,7 +2266,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_0
} CONFIG_PAGE_RAID_VOL_0, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_0,
RaidVolumePage0_t, MPI_POINTER pRaidVolumePage0_t;
-#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x06)
+#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x07)
/* values for RAID Volume Page 0 InactiveStatus field */
#define MPI_RAIDVOLPAGE0_UNKNOWN_INACTIVE (0x00)
@@ -2518,7 +2581,7 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
} CONFIG_PAGE_SAS_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_1,
SasIOUnitPage1_t, MPI_POINTER pSasIOUnitPage1_t;
-#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x06)
+#define MPI_SASIOUNITPAGE1_PAGEVERSION (0x07)
/* values for SAS IO Unit Page 1 ControlFlags */
#define MPI_SAS_IOUNIT1_CONTROL_DEVICE_SELF_TEST (0x8000)
@@ -2544,7 +2607,13 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_1
#define MPI_SAS_IOUNIT1_CONTROL_CLEAR_AFFILIATION (0x0001)
/* values for SAS IO Unit Page 1 AdditionalControlFlags */
-#define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001)
+#define MPI_SAS_IOUNIT1_ACONTROL_SATA_ASYNCHROUNOUS_NOTIFICATION (0x0040)
+#define MPI_SAS_IOUNIT1_ACONTROL_HIDE_NONZERO_ATTACHED_PHY_IDENT (0x0020)
+#define MPI_SAS_IOUNIT1_ACONTROL_PORT_ENABLE_ONLY_SATA_LINK_RESET (0x0010)
+#define MPI_SAS_IOUNIT1_ACONTROL_OTHER_AFFILIATION_SATA_LINK_RESET (0x0008)
+#define MPI_SAS_IOUNIT1_ACONTROL_SELF_AFFILIATION_SATA_LINK_RESET (0x0004)
+#define MPI_SAS_IOUNIT1_ACONTROL_NO_AFFILIATION_SATA_LINK_RESET (0x0002)
+#define MPI_SAS_IOUNIT1_ACONTROL_ALLOW_TABLE_TO_TABLE (0x0001)
/* defines for SAS IO Unit Page 1 ReportDeviceMissingDelay */
#define MPI_SAS_IOUNIT1_REPORT_MISSING_TIMEOUT_MASK (0x7F)
@@ -2585,9 +2654,11 @@ typedef struct _CONFIG_PAGE_SAS_IO_UNIT_2
} CONFIG_PAGE_SAS_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_SAS_IO_UNIT_2,
SasIOUnitPage2_t, MPI_POINTER pSasIOUnitPage2_t;
-#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x05)
+#define MPI_SASIOUNITPAGE2_PAGEVERSION (0x06)
/* values for SAS IO Unit Page 2 Status field */
+#define MPI_SAS_IOUNIT2_STATUS_DEVICE_LIMIT_EXCEEDED (0x08)
+#define MPI_SAS_IOUNIT2_STATUS_ENCLOSURE_DEVICES_UNMAPPED (0x04)
#define MPI_SAS_IOUNIT2_STATUS_DISABLED_PERSISTENT_MAPPINGS (0x02)
#define MPI_SAS_IOUNIT2_STATUS_FULL_PERSISTENT_MAPPINGS (0x01)
@@ -2739,24 +2810,38 @@ typedef struct _CONFIG_PAGE_SAS_DEVICE_0
} CONFIG_PAGE_SAS_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SAS_DEVICE_0,
SasDevicePage0_t, MPI_POINTER pSasDevicePage0_t;
-#define MPI_SASDEVICE0_PAGEVERSION (0x04)
+#define MPI_SASDEVICE0_PAGEVERSION (0x05)
/* values for SAS Device Page 0 AccessStatus field */
-#define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00)
-#define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01)
-#define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02)
+#define MPI_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00)
+#define MPI_SAS_DEVICE0_ASTATUS_SATA_INIT_FAILED (0x01)
+#define MPI_SAS_DEVICE0_ASTATUS_SATA_CAPABILITY_FAILED (0x02)
+#define MPI_SAS_DEVICE0_ASTATUS_SATA_AFFILIATION_CONFLICT (0x03)
+/* specific values for SATA Init failures */
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_UNKNOWN (0x10)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_AFFILIATION_CONFLICT (0x11)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_DIAG (0x12)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_IDENTIFICATION (0x13)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_CHECK_POWER (0x14)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_PIO_SN (0x15)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_MDMA_SN (0x16)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_UDMA_SN (0x17)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_ZONING_VIOLATION (0x18)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_NOT_ADDRESSABLE (0x19)
+#define MPI_SAS_DEVICE0_ASTATUS_SIF_MAX (0x1F)
/* values for SAS Device Page 0 Flags field */
-#define MPI_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200)
-#define MPI_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100)
-#define MPI_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED (0x0080)
-#define MPI_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED (0x0040)
-#define MPI_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020)
-#define MPI_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010)
-#define MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008)
-#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT (0x0004)
-#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED (0x0002)
-#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_ASYNCHRONOUS_NOTIFY (0x0400)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_SW_PRESERVE (0x0200)
+#define MPI_SAS_DEVICE0_FLAGS_UNSUPPORTED_DEVICE (0x0100)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_48BIT_LBA_SUPPORTED (0x0080)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_SMART_SUPPORTED (0x0040)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020)
+#define MPI_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010)
+#define MPI_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008)
+#define MPI_SAS_DEVICE0_FLAGS_MAPPING_PERSISTENT (0x0004)
+#define MPI_SAS_DEVICE0_FLAGS_DEVICE_MAPPED (0x0002)
+#define MPI_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001)
/* see mpi_sas.h for values for SAS Device Page 0 DeviceInfo values */
diff --git a/drivers/message/fusion/lsi/mpi_history.txt b/drivers/message/fusion/lsi/mpi_history.txt
index 582cfe7c2aa1..d6b4c607453b 100644
--- a/drivers/message/fusion/lsi/mpi_history.txt
+++ b/drivers/message/fusion/lsi/mpi_history.txt
@@ -3,28 +3,28 @@
MPI Header File Change History
==============================
- Copyright (c) 2000-2005 LSI Logic Corporation.
+ Copyright (c) 2000-2006 LSI Logic Corporation.
---------------------------------------
- Header Set Release Version: 01.05.13
- Header Set Release Date: 03-27-06
+ Header Set Release Version: 01.05.14
+ Header Set Release Date: 10-11-06
---------------------------------------
Filename Current version Prior version
---------- --------------- -------------
- mpi.h 01.05.11 01.05.10
- mpi_ioc.h 01.05.11 01.05.10
- mpi_cnfg.h 01.05.12 01.05.11
- mpi_init.h 01.05.07 01.05.06
- mpi_targ.h 01.05.06 01.05.05
+ mpi.h 01.05.12 01.05.11
+ mpi_ioc.h 01.05.12 01.05.11
+ mpi_cnfg.h 01.05.13 01.05.12
+ mpi_init.h 01.05.08 01.05.07
+ mpi_targ.h 01.05.06 01.05.06
mpi_fc.h 01.05.01 01.05.01
mpi_lan.h 01.05.01 01.05.01
mpi_raid.h 01.05.02 01.05.02
mpi_tool.h 01.05.03 01.05.03
mpi_inb.h 01.05.01 01.05.01
- mpi_sas.h 01.05.03 01.05.02
+ mpi_sas.h 01.05.04 01.05.03
mpi_type.h 01.05.02 01.05.02
- mpi_history.txt 01.05.13 01.05.12
+ mpi_history.txt 01.05.14 01.05.13
* Date Version Description
@@ -94,6 +94,7 @@ mpi.h
* 08-03-05 01.05.09 Bumped MPI_HEADER_VERSION_UNIT.
* 08-30-05 01.05.10 Added 2 new IOCStatus codes for Target.
* 03-27-06 01.05.11 Bumped MPI_HEADER_VERSION_UNIT.
+ * 10-11-06 01.05.12 Bumped MPI_HEADER_VERSION_UNIT.
* --------------------------------------------------------------------------
mpi_ioc.h
@@ -182,6 +183,14 @@ mpi_ioc.h
* Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event
* data structure.
* Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.
+ * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED.
+ * Added MaxInitiators field to PortFacts reply.
+ * Added SAS Device Status Change ReasonCode for
+ * asynchronous notificaiton.
+ * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event
+ * data structure.
+ * Added new ImageType values for FWDownload and FWUpload
+ * requests.
* --------------------------------------------------------------------------
mpi_cnfg.h
@@ -447,6 +456,23 @@ mpi_cnfg.h
* Added AdditionalControlFlags, MaxTargetPortConnectTime,
* ReportDeviceMissingDelay, and IODeviceMissingDelay
* fields to SAS IO Unit Page 1.
+ * 10-11-06 01.05.13 Added NumForceWWID field and ForceWWID array to
+ * Manufacturing Page 5.
+ * Added Manufacturing pages 8 through 10.
+ * Added defines for supported metadata size bits in
+ * CapabilitiesFlags field of IOC Page 6.
+ * Added defines for metadata size bits in VolumeSettings
+ * field of RAID Volume Page 0.
+ * Added SATA Link Reset settings, Enable SATA Asynchronous
+ * Notification bit, and HideNonZeroAttachedPhyIdentifiers
+ * bit to AdditionalControlFlags field of SAS IO Unit
+ * Page 1.
+ * Added defines for Enclosure Devices Unmapped and
+ * Device Limit Exceeded bits in Status field of SAS IO
+ * Unit Page 2.
+ * Added more AccessStatus values for SAS Device Page 0.
+ * Added bit for SATA Asynchronous Notification Support in
+ * Flags field of SAS Device Page 0.
* --------------------------------------------------------------------------
mpi_init.h
@@ -490,6 +516,7 @@ mpi_init.h
* 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
* unique in the first 32 characters.
* 03-27-06 01.05.07 Added Task Management type of Clear ACA.
+ * 10-11-06 01.05.08 Shortened define for Task Management type of Clear ACA.
* --------------------------------------------------------------------------
mpi_targ.h
@@ -638,6 +665,8 @@ mpi_sas.h
* and Remove Device operations to SAS IO Unit Control.
* Added DevHandle field to SAS IO Unit Control request and
* reply.
+ * 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO
+ * Unit Control request.
* --------------------------------------------------------------------------
mpi_type.h
@@ -653,20 +682,20 @@ mpi_type.h
mpi_history.txt Parts list history
-Filename 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09
----------- -------- -------- -------- -------- --------
-mpi.h 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07
-mpi_ioc.h 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08
-mpi_cnfg.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08
-mpi_init.h 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04
-mpi_targ.h 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04
-mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
-mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
-mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02
-mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03
-mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
-mpi_sas.h 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01
-mpi_type.h 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01
+Filename 01.05.13 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09
+---------- -------- -------- -------- -------- -------- --------
+mpi.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08 01.05.07
+mpi_ioc.h 01.05.12 01.05.11 01.05.10 01.05.09 01.05.09 01.05.08
+mpi_cnfg.h 01.05.13 01.05.12 01.05.11 01.05.10 01.05.09 01.05.08
+mpi_init.h 01.05.08 01.05.07 01.05.06 01.05.06 01.05.05 01.05.04
+mpi_targ.h 01.05.06 01.05.06 01.05.05 01.05.05 01.05.05 01.05.04
+mpi_fc.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
+mpi_lan.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
+mpi_raid.h 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02 01.05.02
+mpi_tool.h 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03 01.05.03
+mpi_inb.h 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01 01.05.01
+mpi_sas.h 01.05.04 01.05.03 01.05.02 01.05.01 01.05.01 01.05.01
+mpi_type.h 01.05.02 01.05.02 01.05.02 01.05.01 01.05.01 01.05.01
Filename 01.05.08 01.05.07 01.05.06 01.05.05 01.05.04 01.05.03
---------- -------- -------- -------- -------- -------- --------
diff --git a/drivers/message/fusion/lsi/mpi_init.h b/drivers/message/fusion/lsi/mpi_init.h
index c1c678989a23..ec9dff2249a7 100644
--- a/drivers/message/fusion/lsi/mpi_init.h
+++ b/drivers/message/fusion/lsi/mpi_init.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2005 LSI Logic Corporation.
+ * Copyright (c) 2000-2006 LSI Logic Corporation.
*
*
* Name: mpi_init.h
* Title: MPI initiator mode messages and structures
* Creation Date: June 8, 2000
*
- * mpi_init.h Version: 01.05.07
+ * mpi_init.h Version: 01.05.08
*
* Version History
* ---------------
@@ -53,6 +53,7 @@
* 08-03-05 01.05.06 Fixed some MPI_SCSIIO32_MSGFLGS_ defines to make them
* unique in the first 32 characters.
* 03-27-06 01.05.07 Added Task Management type of Clear ACA.
+ * 10-11-06 01.05.08 Shortened define for Task Management type of Clear ACA.
* --------------------------------------------------------------------------
*/
@@ -428,7 +429,7 @@ typedef struct _MSG_SCSI_TASK_MGMT
#define MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05)
#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06)
#define MPI_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
-#define MPI_SCSITASKMGMT_TASKTYPE_CLEAR_ACA (0x08)
+#define MPI_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08)
/* MsgFlags bits */
#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00)
diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h
index 18ba407fd399..6c33e3353375 100644
--- a/drivers/message/fusion/lsi/mpi_ioc.h
+++ b/drivers/message/fusion/lsi/mpi_ioc.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2000-2005 LSI Logic Corporation.
+ * Copyright (c) 2000-2006 LSI Logic Corporation.
*
*
* Name: mpi_ioc.h
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: August 11, 2000
*
- * mpi_ioc.h Version: 01.05.11
+ * mpi_ioc.h Version: 01.05.12
*
* Version History
* ---------------
@@ -98,6 +98,14 @@
* Added MPI_EVENT_SAS_INIT_TABLE_OVERFLOW and event
* data structure.
* Added MPI_EXT_IMAGE_TYPE_INITIALIZATION.
+ * 10-11-06 01.05.12 Added MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED.
+ * Added MaxInitiators field to PortFacts reply.
+ * Added SAS Device Status Change ReasonCode for
+ * asynchronous notificaiton.
+ * Added MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE and event
+ * data structure.
+ * Added new ImageType values for FWDownload and FWUpload
+ * requests.
* --------------------------------------------------------------------------
*/
@@ -264,6 +272,7 @@ typedef struct _MSG_IOC_FACTS_REPLY
#define MPI_IOCFACTS_EXCEPT_RAID_CONFIG_INVALID (0x0002)
#define MPI_IOCFACTS_EXCEPT_FW_CHECKSUM_FAIL (0x0004)
#define MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL (0x0008)
+#define MPI_IOCFACTS_EXCEPT_METADATA_UNSUPPORTED (0x0010)
#define MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT (0x01)
#define MPI_IOCFACTS_FLAGS_REPLY_FIFO_HOST_SIGNAL (0x02)
@@ -328,7 +337,8 @@ typedef struct _MSG_PORT_FACTS_REPLY
U16 MaxPostedCmdBuffers; /* 1Ch */
U16 MaxPersistentIDs; /* 1Eh */
U16 MaxLanBuckets; /* 20h */
- U16 Reserved4; /* 22h */
+ U8 MaxInitiators; /* 22h */
+ U8 Reserved4; /* 23h */
U32 Reserved5; /* 24h */
} MSG_PORT_FACTS_REPLY, MPI_POINTER PTR_MSG_PORT_FACTS_REPLY,
PortFactsReply_t, MPI_POINTER pPortFactsReply_t;
@@ -487,6 +497,7 @@ typedef struct _MSG_EVENT_ACK_REPLY
#define MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE (0x00000018)
#define MPI_EVENT_SAS_INIT_TABLE_OVERFLOW (0x00000019)
#define MPI_EVENT_SAS_SMP_ERROR (0x0000001A)
+#define MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE (0x0000001B)
#define MPI_EVENT_LOG_ENTRY_ADDED (0x00000021)
/* AckRequired field values */
@@ -593,6 +604,7 @@ typedef struct _EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
#define MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A)
#define MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B)
#define MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C)
+#define MPI_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D)
/* SCSI Event data for Queue Full event */
@@ -895,6 +907,54 @@ typedef struct _EVENT_DATA_SAS_INIT_TABLE_OVERFLOW
MpiEventDataSasInitTableOverflow_t,
MPI_POINTER pMpiEventDataSasInitTableOverflow_t;
+/* SAS Expander Status Change Event data */
+
+typedef struct _EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE
+{
+ U8 ReasonCode; /* 00h */
+ U8 Reserved1; /* 01h */
+ U16 Reserved2; /* 02h */
+ U8 PhysicalPort; /* 04h */
+ U8 Reserved3; /* 05h */
+ U16 EnclosureHandle; /* 06h */
+ U64 SASAddress; /* 08h */
+ U32 DiscoveryStatus; /* 10h */
+ U16 DevHandle; /* 14h */
+ U16 ParentDevHandle; /* 16h */
+ U16 ExpanderChangeCount; /* 18h */
+ U16 ExpanderRouteIndexes; /* 1Ah */
+ U8 NumPhys; /* 1Ch */
+ U8 SASLevel; /* 1Dh */
+ U8 Flags; /* 1Eh */
+ U8 Reserved4; /* 1Fh */
+} EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE,
+ MPI_POINTER PTR_EVENT_DATA_SAS_EXPANDER_STATUS_CHANGE,
+ MpiEventDataSasExpanderStatusChange_t,
+ MPI_POINTER pMpiEventDataSasExpanderStatusChange_t;
+
+/* values for ReasonCode field of SAS Expander Status Change Event data */
+#define MPI_EVENT_SAS_EXP_RC_ADDED (0x00)
+#define MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING (0x01)
+
+/* values for DiscoveryStatus field of SAS Expander Status Change Event data */
+#define MPI_EVENT_SAS_EXP_DS_LOOP_DETECTED (0x00000001)
+#define MPI_EVENT_SAS_EXP_DS_UNADDRESSABLE_DEVICE (0x00000002)
+#define MPI_EVENT_SAS_EXP_DS_MULTIPLE_PORTS (0x00000004)
+#define MPI_EVENT_SAS_EXP_DS_EXPANDER_ERR (0x00000008)
+#define MPI_EVENT_SAS_EXP_DS_SMP_TIMEOUT (0x00000010)
+#define MPI_EVENT_SAS_EXP_DS_OUT_ROUTE_ENTRIES (0x00000020)
+#define MPI_EVENT_SAS_EXP_DS_INDEX_NOT_EXIST (0x00000040)
+#define MPI_EVENT_SAS_EXP_DS_SMP_FUNCTION_FAILED (0x00000080)
+#define MPI_EVENT_SAS_EXP_DS_SMP_CRC_ERROR (0x00000100)
+#define MPI_EVENT_SAS_EXP_DS_SUBTRACTIVE_LINK (0x00000200)
+#define MPI_EVENT_SAS_EXP_DS_TABLE_LINK (0x00000400)
+#define MPI_EVENT_SAS_EXP_DS_UNSUPPORTED_DEVICE (0x00000800)
+
+/* values for Flags field of SAS Expander Status Change Event data */
+#define MPI_EVENT_SAS_EXP_FLAGS_ROUTE_TABLE_CONFIG (0x02)
+#define MPI_EVENT_SAS_EXP_FLAGS_CONFIG_IN_PROGRESS (0x01)
+
+
/*****************************************************************************
*
@@ -926,6 +986,10 @@ typedef struct _MSG_FW_DOWNLOAD
#define MPI_FW_DOWNLOAD_ITYPE_BIOS (0x02)
#define MPI_FW_DOWNLOAD_ITYPE_NVDATA (0x03)
#define MPI_FW_DOWNLOAD_ITYPE_BOOTLOADER (0x04)
+#define MPI_FW_DOWNLOAD_ITYPE_MANUFACTURING (0x06)
+#define MPI_FW_DOWNLOAD_ITYPE_CONFIG_1 (0x07)
+#define MPI_FW_DOWNLOAD_ITYPE_CONFIG_2 (0x08)
+#define MPI_FW_DOWNLOAD_ITYPE_MEGARAID (0x09)
typedef struct _FWDownloadTCSGE
@@ -980,6 +1044,11 @@ typedef struct _MSG_FW_UPLOAD
#define MPI_FW_UPLOAD_ITYPE_NVDATA (0x03)
#define MPI_FW_UPLOAD_ITYPE_BOOTLOADER (0x04)
#define MPI_FW_UPLOAD_ITYPE_FW_BACKUP (0x05)
+#define MPI_FW_UPLOAD_ITYPE_MANUFACTURING (0x06)
+#define MPI_FW_UPLOAD_ITYPE_CONFIG_1 (0x07)
+#define MPI_FW_UPLOAD_ITYPE_CONFIG_2 (0x08)
+#define MPI_FW_UPLOAD_ITYPE_MEGARAID (0x09)
+#define MPI_FW_UPLOAD_ITYPE_COMPLETE (0x0A)
typedef struct _FWUploadTCSGE
{
diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h
index 871ebc08b706..635bbe04513e 100644
--- a/drivers/message/fusion/lsi/mpi_log_sas.h
+++ b/drivers/message/fusion/lsi/mpi_log_sas.h
@@ -1,4 +1,3 @@
-
/***************************************************************************
* *
* Copyright 2003 LSI Logic Corporation. All rights reserved. *
@@ -14,7 +13,7 @@
#define IOPI_IOCLOGINFO_H_INCLUDED
#define SAS_LOGINFO_NEXUS_LOSS 0x31170000
-#define SAS_LOGINFO_MASK 0xFFFF0000
+#define SAS_LOGINFO_MASK 0xFFFF0000
/****************************************************************************/
/* IOC LOGINFO defines, 0x00000000 - 0x0FFFFFFF */
@@ -43,129 +42,172 @@
/****************************************************************************/
/* IOP LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = IOP */
/****************************************************************************/
-#define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS (0x00010000)
-#define IOP_LOGINFO_CODE_UNUSED2 (0x00020000)
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x00030000)
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT (0x00030100) /* Route Table Entry not found */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN (0x00030200) /* Invalid Page Number */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x00030300) /* Invalid FORM */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x00030400) /* Invalid Page Type */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */
-#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
-
-#define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */
-
-#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
-
-#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */
-#define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */
-
-#define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001)
-#define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002)
-#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003)
-#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004)
-#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005)
+#define IOP_LOGINFO_CODE_INVALID_SAS_ADDRESS (0x00010000)
+#define IOP_LOGINFO_CODE_UNUSED2 (0x00020000)
+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x00030000)
+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_RT (0x00030100) /* Route Table Entry not found */
+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PN (0x00030200) /* Invalid Page Number */
+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x00030300) /* Invalid FORM */
+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x00030400) /* Invalid Page Type */
+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DNM (0x00030500) /* Device Not Mapped */
+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_PERSIST (0x00030600) /* Persistent Page not found */
+#define IOP_LOGINFO_CODE_CONFIG_INVALID_PAGE_DEFAULT (0x00030700) /* Default Page not found */
+
+#define IOP_LOGINFO_CODE_FWUPLOAD_NO_FLASH_AVAILABLE (0x0003E000) /* Tried to upload from flash, but there is none */
+#define IOP_LOGINFO_CODE_FWUPLOAD_UNKNOWN_IMAGE_TYPE (0x0003E001) /* ImageType field contents were invalid */
+#define IOP_LOGINFO_CODE_FWUPLOAD_WRONG_IMAGE_SIZE (0x0003E002) /* ImageSize field in TCSGE was bad/offset in MfgPg 4 was wrong */
+#define IOP_LOGINFO_CODE_FWUPLOAD_ENTIRE_FLASH_UPLOAD_FAILED (0x0003E003) /* Error occured while attempting to upload the entire flash */
+#define IOP_LOGINFO_CODE_FWUPLOAD_REGION_UPLOAD_FAILED (0x0003E004) /* Error occured while attempting to upload single flash region */
+#define IOP_LOGINFO_CODE_FWUPLOAD_DMA_FAILURE (0x0003E005) /* Problem occured while DMAing FW to host memory */
+
+#define IOP_LOGINFO_CODE_DIAG_MSG_ERROR (0x00040000) /* Error handling diag msg - or'd with diag status */
+
+#define IOP_LOGINFO_CODE_TASK_TERMINATED (0x00050000)
+
+#define IOP_LOGINFO_CODE_ENCL_MGMT_READ_ACTION_ERR0R (0x00060001) /* Read Action not supported for SEP msg */
+#define IOP_LOGINFO_CODE_ENCL_MGMT_INVALID_BUS_ID_ERR0R (0x00060002) /* Invalid Bus/ID in SEP msg */
+
+#define IOP_LOGINFO_CODE_TARGET_ASSIST_TERMINATED (0x00070001)
+#define IOP_LOGINFO_CODE_TARGET_STATUS_SEND_TERMINATED (0x00070002)
+#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_ALL_IO (0x00070003)
+#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO (0x00070004)
+#define IOP_LOGINFO_CODE_TARGET_MODE_ABORT_EXACT_IO_REQ (0x00070005)
/****************************************************************************/
/* PL LOGINFO_CODE defines, valid if IOC_LOGINFO_ORIGINATOR = PL */
/****************************************************************************/
-#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000)
-#define PL_LOG_INFO_CODE_OPEN_FAILURE_NO_DEST_TIME_OUT (0x00010001)
-#define PL_LOGINFO_CODE_OPEN_FAILURE_BAD_DESTINATION (0x00010011)
-#define PL_LOGINFO_CODE_OPEN_FAILURE_PROTOCOL_NOT_SUPPORTED (0x00010013)
-#define PL_LOGINFO_CODE_OPEN_FAILURE_STP_RESOURCES_BSY (0x00010018)
-#define PL_LOGINFO_CODE_OPEN_FAILURE_WRONG_DESTINATION (0x00010019)
-#define PL_LOGINFO_CODE_OPEN_FAILURE_ORR_TIMEOUT (0X0001001A)
-#define PL_LOGINFO_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0001001B)
-#define PL_LOGINFO_CODE_OPEN_FAILURE_AWT_MAXED (0x0001001C)
-#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)
-#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)
-#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)
-#define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW (0x00050000)
-#define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00060000)
-#define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00070000)
-#define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00080000)
-#define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00090000)
-#define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE (0x000A0000)
-#define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x000B0000)
-#define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR (0x000C0000)
-#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)
-#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)
-#define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV (0x000F0400) /* No Device Found */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x000F0500) /* Invalid FORM */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */
-#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */
-#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)
-#define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below */
-#define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below */
-#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)
-#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
-#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000)
-#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000)
-#define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000)
-#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
-#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101)
-#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */
-#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATHWAY_BLOCKED (0x0000011B)
-#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */
-
-#define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120)
-#define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */
-#define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */
-
-
-#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
-#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
-#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400)
-#define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500)
-#define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600)
-#define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00000700)
-#define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800)
-#define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900)
-#define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE (0x00000A00)
-#define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x00000B00)
-#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)
-#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)
-#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)
-#define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01)
-#define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00)
-#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
-
-
-#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */
-#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */
-#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */
-#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */
-#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */
-#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */
-#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */
-#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */
-
-#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */
-#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */
-#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */
-#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */
-#define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */
-#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */
-#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */
-#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */
-#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */
-#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */
-#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */
-#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/
-#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode */
+#define PL_LOGINFO_CODE_OPEN_FAILURE (0x00010000) /* see SUB_CODE_OPEN_FAIL_ below */
+
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_NO_DEST_TIME_OUT (0x00000001)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PATHWAY_BLOCKED (0x00000002)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_CONTINUE0 (0x00000003)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_CONTINUE1 (0x00000004)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_INITIALIZE0 (0x00000005)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_INITIALIZE1 (0x00000006)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_STOP0 (0x00000007)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RES_STOP1 (0x00000008)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RETRY (0x00000009)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_BREAK (0x0000000A)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_UNUSED_0B (0x0000000B)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_OPEN_TIMEOUT_EXP (0x0000000C)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_UNUSED_0D (0x0000000D)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_DVTBLE_ACCSS_FAIL (0x0000000E)
+#define PL_LOGINFO_SUB CODE_OPEN_FAIL_BAD_DEST (0x00000011)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RATE_NOT_SUPP (0x00000012)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PROT_NOT_SUPP (0x00000013)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON0 (0x00000014)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON1 (0x00000015)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON2 (0x00000016)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_RESERVED_ABANDON3 (0x00000017)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_STP_RESOURCES_BSY (0x00000018)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_WRONG_DESTINATION (0x00000019)
+
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_PATH_BLOCKED (0x0000001B) /* Retry Timeout */
+#define PL_LOGINFO_SUB_CODE_OPEN_FAIL_AWT_MAXED (0x0000001C) /* Retry Timeout */
+
+
+
+#define PL_LOGINFO_CODE_INVALID_SGL (0x00020000)
+#define PL_LOGINFO_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00030000)
+#define PL_LOGINFO_CODE_FRAME_XFER_ERROR (0x00040000)
+#define PL_LOGINFO_CODE_TX_FM_CONNECTED_LOW (0x00050000)
+#define PL_LOGINFO_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00060000)
+#define PL_LOGINFO_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00070000)
+#define PL_LOGINFO_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00080000)
+#define PL_LOGINFO_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00090000)
+#define PL_LOGINFO_CODE_RX_FM_INVALID_MESSAGE (0x000A0000)
+#define PL_LOGINFO_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x000B0000)
+#define PL_LOGINFO_CODE_RX_FM_CURRENT_FRAME_ERROR (0x000C0000)
+#define PL_LOGINFO_CODE_SATA_LINK_DOWN (0x000D0000)
+#define PL_LOGINFO_CODE_DISCOVERY_SATA_INIT_W_IOS (0x000E0000)
+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE (0x000F0000)
+#define PL_LOGINFO_CODE_CONFIG_PL_NOT_INITIALIZED (0x000F0001) /* PL not yet initialized, can't do config page req. */
+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PT (0x000F0100) /* Invalid Page Type */
+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NUM_PHYS (0x000F0200) /* Invalid Number of Phys */
+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NOT_IMP (0x000F0300) /* Case Not Handled */
+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_DEV (0x000F0400) /* No Device Found */
+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_FORM (0x000F0500) /* Invalid FORM */
+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_PHY (0x000F0600) /* Invalid Phy */
+#define PL_LOGINFO_CODE_CONFIG_INVALID_PAGE_NO_OWNER (0x000F0700) /* No Owner Found */
+#define PL_LOGINFO_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00100000)
+#define PL_LOGINFO_CODE_RESET (0x00110000) /* See Sub-Codes below (PL_LOGINFO_SUB_CODE) */
+#define PL_LOGINFO_CODE_ABORT (0x00120000) /* See Sub-Codes below (PL_LOGINFO_SUB_CODE)*/
+#define PL_LOGINFO_CODE_IO_NOT_YET_EXECUTED (0x00130000)
+#define PL_LOGINFO_CODE_IO_EXECUTED (0x00140000)
+#define PL_LOGINFO_CODE_PERS_RESV_OUT_NOT_AFFIL_OWNER (0x00150000)
+#define PL_LOGINFO_CODE_OPEN_TXDMA_ABORT (0x00160000)
+#define PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY (0x00170000)
+#define PL_LOGINFO_CODE_IO_CANCELLED_DUE_TO_R_ERR (0x00180000)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE (0x00000100)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_NO_DEST_TIMEOUT (0x00000101)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_SATA_NEG_RATE_2HI (0x00000102)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_RATE_NOT_SUPPORTED (0x00000103)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_BREAK (0x00000104)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ZONE_VIOLATION (0x00000114)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON0 (0x00000114) /* Open Reject (Zone Violation) - available on SAS-2 devices */
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON1 (0x00000115)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON2 (0x00000116)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ABANDON3 (0x00000117)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_ORR_TIMEOUT (0x0000011A) /* Open Reject (Retry) Timeout */
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_PATH_BLOCKED (0x0000011B)
+#define PL_LOGINFO_SUB_CODE_OPEN_FAILURE_AWT_MAXED (0x0000011C) /* Arbitration Wait Timer Maxed */
+
+#define PL_LOGINFO_SUB_CODE_TARGET_BUS_RESET (0x00000120)
+#define PL_LOGINFO_SUB_CODE_TRANSPORT_LAYER (0x00000130) /* Leave lower nibble (1-f) reserved. */
+#define PL_LOGINFO_SUB_CODE_PORT_LAYER (0x00000140) /* Leave lower nibble (1-f) reserved. */
+
+
+#define PL_LOGINFO_SUB_CODE_INVALID_SGL (0x00000200)
+#define PL_LOGINFO_SUB_CODE_WRONG_REL_OFF_OR_FRAME_LENGTH (0x00000300)
+#define PL_LOGINFO_SUB_CODE_FRAME_XFER_ERROR (0x00000400) /* Bits 0-3 encode Transport Status Register (offset 0x08) */
+ /* Bit 0 is Status Bit 0: FrameXferErr */
+ /* Bit 1 & 2 are Status Bits 16 and 17: FrameXmitErrStatus */
+ /* Bit 3 is Status Bit 18 WriteDataLenghtGTDataLengthErr */
+
+#define PL_LOGINFO_SUB_CODE_TX_FM_CONNECTED_LOW (0x00000500)
+#define PL_LOGINFO_SUB_CODE_SATA_NON_NCQ_RW_ERR_BIT_SET (0x00000600)
+#define PL_LOGINFO_SUB_CODE_SATA_READ_LOG_RECEIVE_DATA_ERR (0x00000700)
+#define PL_LOGINFO_SUB_CODE_SATA_NCQ_FAIL_ALL_CMDS_AFTR_ERR (0x00000800)
+#define PL_LOGINFO_SUB_CODE_SATA_ERR_IN_RCV_SET_DEV_BIT_FIS (0x00000900)
+#define PL_LOGINFO_SUB_CODE_RX_FM_INVALID_MESSAGE (0x00000A00)
+#define PL_LOGINFO_SUB_CODE_RX_CTX_MESSAGE_VALID_ERROR (0x00000B00)
+#define PL_LOGINFO_SUB_CODE_RX_FM_CURRENT_FRAME_ERROR (0x00000C00)
+#define PL_LOGINFO_SUB_CODE_SATA_LINK_DOWN (0x00000D00)
+#define PL_LOGINFO_SUB_CODE_DISCOVERY_SATA_INIT_W_IOS (0x00000E00)
+#define PL_LOGINFO_SUB_CODE_DISCOVERY_REMOTE_SEP_RESET (0x00000E01)
+#define PL_LOGINFO_SUB_CODE_SECOND_OPEN (0x00000F00)
+#define PL_LOGINFO_SUB_CODE_DSCVRY_SATA_INIT_TIMEOUT (0x00001000)
+
+#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_FAILURE (0x00200000) /* Can't get SMP Frame */
+#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_READ_ERROR (0x00200010) /* Error occured on SMP Read */
+#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_WRITE_ERROR (0x00200020) /* Error occured on SMP Write */
+#define PL_LOGINFO_CODE_ENCL_MGMT_NOT_SUPPORTED_ON_ENCL (0x00200040) /* Encl Mgmt services not available for this WWID */
+#define PL_LOGINFO_CODE_ENCL_MGMT_ADDR_MODE_NOT_SUPPORTED (0x00200050) /* Address Mode not suppored */
+#define PL_LOGINFO_CODE_ENCL_MGMT_BAD_SLOT_NUM (0x00200060) /* Invalid Slot Number in SEP Msg */
+#define PL_LOGINFO_CODE_ENCL_MGMT_SGPIO_NOT_PRESENT (0x00200070) /* SGPIO not present/enabled */
+#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_NOT_CONFIGURED (0x00200080) /* GPIO not configured */
+#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_FRAME_ERROR (0x00200090) /* GPIO can't allocate a frame */
+#define PL_LOGINFO_CODE_ENCL_MGMT_GPIO_CONFIG_PAGE_ERROR (0x002000A0) /* GPIO failed config page request */
+#define PL_LOGINFO_CODE_ENCL_MGMT_SES_FRAME_ALLOC_ERROR (0x002000B0) /* Can't get frame for SES command */
+#define PL_LOGINFO_CODE_ENCL_MGMT_SES_IO_ERROR (0x002000C0) /* I/O execution error */
+#define PL_LOGINFO_CODE_ENCL_MGMT_SES_RETRIES_EXHAUSTED (0x002000D0) /* SEP I/O retries exhausted */
+#define PL_LOGINFO_CODE_ENCL_MGMT_SMP_FRAME_ALLOC_ERROR (0x002000E0) /* Can't get frame for SMP command */
+
+#define PL_LOGINFO_DA_SEP_NOT_PRESENT (0x00200100) /* SEP not present when msg received */
+#define PL_LOGINFO_DA_SEP_SINGLE_THREAD_ERROR (0x00200101) /* Can only accept 1 msg at a time */
+#define PL_LOGINFO_DA_SEP_ISTWI_INTR_IN_IDLE_STATE (0x00200102) /* ISTWI interrupt recvd. while IDLE */
+#define PL_LOGINFO_DA_SEP_RECEIVED_NACK_FROM_SLAVE (0x00200103) /* SEP NACK'd, it is busy */
+#define PL_LOGINFO_DA_SEP_DID_NOT_RECEIVE_ACK (0x00200104) /* SEP didn't rcv. ACK (Last Rcvd Bit = 1) */
+#define PL_LOGINFO_DA_SEP_BAD_STATUS_HDR_CHKSUM (0x00200105) /* SEP stopped or sent bad chksum in Hdr */
+#define PL_LOGINFO_DA_SEP_STOP_ON_DATA (0x00200106) /* SEP stopped while transfering data */
+#define PL_LOGINFO_DA_SEP_STOP_ON_SENSE_DATA (0x00200107) /* SEP stopped while transfering sense data */
+#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_1 (0x00200108) /* SEP returned unknown scsi status */
+#define PL_LOGINFO_DA_SEP_UNSUPPORTED_SCSI_STATUS_2 (0x00200109) /* SEP returned unknown scsi status */
+#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP (0x0020010A) /* SEP returned bad chksum after STOP */
+#define PL_LOGINFO_DA_SEP_CHKSUM_ERROR_AFTER_STOP_GETDATA (0x0020010B) /* SEP returned bad chksum after STOP while gettin data*/
+#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND (0x0020010C) /* SEP doesn't support CDB opcode f/w location 1 */
+#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND_2 (0x0020010D) /* SEP doesn't support CDB opcode f/w location 2 */
+#define PL_LOGINFO_DA_SEP_UNSUPPORTED_COMMAND_3 (0x0020010E) /* SEP doesn't support CDB opcode f/w location 3 */
/****************************************************************************/
diff --git a/drivers/message/fusion/lsi/mpi_sas.h b/drivers/message/fusion/lsi/mpi_sas.h
index 50b8f0a8f456..8e990a0fa7a2 100644
--- a/drivers/message/fusion/lsi/mpi_sas.h
+++ b/drivers/message/fusion/lsi/mpi_sas.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2004 LSI Logic Corporation.
+ * Copyright (c) 2004-2006 LSI Logic Corporation.
*
*
* Name: mpi_sas.h
* Title: MPI Serial Attached SCSI structures and definitions
* Creation Date: August 19, 2004
*
- * mpi_sas.h Version: 01.05.03
+ * mpi_sas.h Version: 01.05.04
*
* Version History
* ---------------
@@ -21,6 +21,8 @@
* and Remove Device operations to SAS IO Unit Control.
* Added DevHandle field to SAS IO Unit Control request and
* reply.
+ * 10-11-06 01.05.04 Fixed the name of a define for Operation field of SAS IO
+ * Unit Control request.
* --------------------------------------------------------------------------
*/
@@ -237,7 +239,8 @@ typedef struct _MSG_SAS_IOUNIT_CONTROL_REQUEST
#define MPI_SAS_OP_SEND_PRIMITIVE (0x0A)
#define MPI_SAS_OP_FORCE_FULL_DISCOVERY (0x0B)
#define MPI_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C)
-#define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D)
+#define MPI_SAS_OP_TRANSMIT_REMOVE_DEVICE (0x0D) /* obsolete name */
+#define MPI_SAS_OP_REMOVE_DEVICE (0x0D)
/* values for the PrimFlags field */
#define MPI_SAS_PRIMFLAGS_SINGLE (0x08)
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index b3f28a03b6a9..083acfd91d8b 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -6,7 +6,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -82,6 +82,10 @@ static int mpt_msi_enable;
module_param(mpt_msi_enable, int, 0);
MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
+static int mpt_channel_mapping;
+module_param(mpt_channel_mapping, int, 0);
+MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
+
#ifdef MFCNT
static int mfcounter = 0;
#define PRINT_MF_COUNT 20000
@@ -173,11 +177,14 @@ static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
//int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
-static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
+#ifdef MPT_DEBUG_REPLY
+static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
+#endif
static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
+static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
/* module entry point */
static int __init fusion_init (void);
@@ -319,13 +326,11 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
else if (ioc->bus_type == SAS)
mpt_sas_log_info(ioc, log_info);
}
- if (ioc_stat & MPI_IOCSTATUS_MASK) {
- if (ioc->bus_type == SPI &&
- cb_idx != mpt_stm_index &&
- cb_idx != mpt_lan_index)
- mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
- }
+#ifdef MPT_DEBUG_REPLY
+ if (ioc_stat & MPI_IOCSTATUS_MASK)
+ mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
+#endif
/* Check for (valid) IO callback! */
if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
@@ -911,7 +916,7 @@ mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
int
mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
{
- int r = 0;
+ int r = 0;
u8 *req_as_bytes;
int ii;
@@ -1811,6 +1816,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* and we try GetLanConfigPages again...
*/
if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
+
+ /*
+ * Initalize link list for inactive raid volumes.
+ */
+ init_MUTEX(&ioc->raid_data.inactive_list_mutex);
+ INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
+
if (ioc->bus_type == SAS) {
/* clear persistency table */
@@ -2017,6 +2029,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
}
kfree(ioc->spi_data.nvram);
+ mpt_inactive_raid_list_free(ioc);
+ kfree(ioc->raid_data.pIocPg2);
kfree(ioc->raid_data.pIocPg3);
ioc->spi_data.nvram = NULL;
ioc->raid_data.pIocPg3 = NULL;
@@ -2413,6 +2427,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
facts->ProductID = le16_to_cpu(facts->ProductID);
+ if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
+ > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
+ ioc->ir_firmware = 1;
facts->CurrentHostMfaHighAddr =
le32_to_cpu(facts->CurrentHostMfaHighAddr);
facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
@@ -2505,6 +2522,7 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
int ii;
int req_sz;
int reply_sz;
+ int max_id;
/* IOC *must* NOT be in RESET state! */
if (ioc->last_state == MPI_IOC_STATE_RESET) {
@@ -2552,6 +2570,21 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
+ max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
+ pfacts->MaxDevices;
+ ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
+ ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
+
+ /*
+ * Place all the devices on channels
+ *
+ * (for debuging)
+ */
+ if (mpt_channel_mapping) {
+ ioc->devices_per_bus = 1;
+ ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
+ }
+
return 0;
}
@@ -2592,13 +2625,8 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
ioc->name, ioc->upload_fw, ioc->facts.Flags));
- if(ioc->bus_type == SAS)
- ioc_init.MaxDevices = ioc->facts.MaxDevices;
- else if(ioc->bus_type == FC)
- ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
- else
- ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
- ioc_init.MaxBuses = MPT_MAX_BUS;
+ ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
+ ioc_init.MaxBuses = (U8)ioc->number_of_buses;
dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
ioc->name, ioc->facts.MsgVersion));
if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
@@ -2720,9 +2748,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
/* RAID FW may take a long time to enable
*/
- if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
- > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
- (ioc->bus_type == SAS)) {
+ if (ioc->ir_firmware || ioc->bus_type == SAS) {
rc = mpt_handshake_req_reply_wait(ioc, req_sz,
(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
300 /*seconds*/, sleepFlag);
@@ -3193,6 +3219,9 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
u32 diag1val = 0;
#endif
+ /* Clear any existing interrupts */
+ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+
if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
"address=%p\n", ioc->name, __FUNCTION__,
@@ -3212,7 +3241,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
" count=%d\n",
ioc->name, doorbell, count));
if (doorbell == MPI_IOC_STATE_READY) {
- return 0;
+ return 1;
}
/* wait 1 sec */
@@ -3224,9 +3253,6 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
return -1;
}
- /* Clear any existing interrupts */
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-
/* Use "Diagnostic reset" method! (only thing available!) */
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
@@ -3942,7 +3968,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
}
} else {
while (--cntdn) {
- mdelay (1);
+ udelay (1000);
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
break;
@@ -3994,7 +4020,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
break;
- mdelay(1);
+ udelay (1000);
count++;
}
}
@@ -4310,8 +4336,8 @@ mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
(reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
- printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
- ioc->name, disk);
+ printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
+ ioc->name, disk, volume);
} else {
printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
ioc->name, volume);
@@ -4712,7 +4738,187 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
return 0;
}
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ * mpt_inactive_raid_list_free
+ *
+ * This clears this link list.
+ *
+ * @ioc - pointer to per adapter structure
+ *
+ **/
+static void
+mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
+{
+ struct inactive_raid_component_info *component_info, *pNext;
+
+ if (list_empty(&ioc->raid_data.inactive_list))
+ return;
+
+ down(&ioc->raid_data.inactive_list_mutex);
+ list_for_each_entry_safe(component_info, pNext,
+ &ioc->raid_data.inactive_list, list) {
+ list_del(&component_info->list);
+ kfree(component_info);
+ }
+ up(&ioc->raid_data.inactive_list_mutex);
+}
+
+/**
+ * mpt_inactive_raid_volumes
+ *
+ * This sets up link list of phy_disk_nums for devices belonging in an inactive volume
+ *
+ * @ioc - pointer to per adapter structure
+ * @channel - volume channel
+ * @id - volume target id
+ *
+ *
+ **/
+static void
+mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
+{
+ CONFIGPARMS cfg;
+ ConfigPageHeader_t hdr;
+ dma_addr_t dma_handle;
+ pRaidVolumePage0_t buffer = NULL;
+ int i;
+ RaidPhysDiskPage0_t phys_disk;
+ struct inactive_raid_component_info *component_info;
+ int handle_inactive_volumes;
+
+ memset(&cfg, 0 , sizeof(CONFIGPARMS));
+ memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
+ hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
+ cfg.pageAddr = (channel << 8) + id;
+ cfg.cfghdr.hdr = &hdr;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+
+ if (mpt_config(ioc, &cfg) != 0)
+ goto out;
+
+ if (!hdr.PageLength)
+ goto out;
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
+ &dma_handle);
+
+ if (!buffer)
+ goto out;
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ if (mpt_config(ioc, &cfg) != 0)
+ goto out;
+
+ if (!buffer->NumPhysDisks)
+ goto out;
+
+ handle_inactive_volumes =
+ (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
+ (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
+ buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
+ buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
+
+ if (!handle_inactive_volumes)
+ goto out;
+
+ down(&ioc->raid_data.inactive_list_mutex);
+ for (i = 0; i < buffer->NumPhysDisks; i++) {
+ if(mpt_raid_phys_disk_pg0(ioc,
+ buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
+ continue;
+
+ if ((component_info = kmalloc(sizeof (*component_info),
+ GFP_KERNEL)) == NULL)
+ continue;
+
+ component_info->volumeID = id;
+ component_info->volumeBus = channel;
+ component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
+ component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
+ component_info->d.PhysDiskID = phys_disk.PhysDiskID;
+ component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
+
+ list_add_tail(&component_info->list,
+ &ioc->raid_data.inactive_list);
+ }
+ up(&ioc->raid_data.inactive_list_mutex);
+
+ out:
+ if (buffer)
+ pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
+ dma_handle);
+}
+
+/**
+ * mpt_raid_phys_disk_pg0 - returns phys disk page zero
+ * @ioc: Pointer to a Adapter Structure
+ * @phys_disk_num: io unit unique phys disk num generated by the ioc
+ * @phys_disk: requested payload data returned
+ *
+ * Return:
+ * 0 on success
+ * -EFAULT if read of config page header fails or data pointer not NULL
+ * -ENOMEM if pci_alloc failed
+ **/
+int
+mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
+{
+ CONFIGPARMS cfg;
+ ConfigPageHeader_t hdr;
+ dma_addr_t dma_handle;
+ pRaidPhysDiskPage0_t buffer = NULL;
+ int rc;
+
+ memset(&cfg, 0 , sizeof(CONFIGPARMS));
+ memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
+
+ hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
+ cfg.cfghdr.hdr = &hdr;
+ cfg.physAddr = -1;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+
+ if (mpt_config(ioc, &cfg) != 0) {
+ rc = -EFAULT;
+ goto out;
+ }
+
+ if (!hdr.PageLength) {
+ rc = -EFAULT;
+ goto out;
+ }
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
+ &dma_handle);
+
+ if (!buffer) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+ cfg.pageAddr = phys_disk_num;
+
+ if (mpt_config(ioc, &cfg) != 0) {
+ rc = -EFAULT;
+ goto out;
+ }
+
+ rc = 0;
+ memcpy(phys_disk, buffer, sizeof(*buffer));
+ phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
+
+ out:
+
+ if (buffer)
+ pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
+ dma_handle);
+
+ return rc;
+}
+
/**
* mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
* @ioc: Pointer to a Adapter Strucutre
@@ -4722,21 +4928,27 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
* 0 on success
* -EFAULT if read of config page header fails or data pointer not NULL
* -ENOMEM if pci_alloc failed
- */
+ **/
int
mpt_findImVolumes(MPT_ADAPTER *ioc)
{
IOCPage2_t *pIoc2;
u8 *mem;
- ConfigPageIoc2RaidVol_t *pIocRv;
dma_addr_t ioc2_dma;
CONFIGPARMS cfg;
ConfigPageHeader_t header;
- int jj;
int rc = 0;
int iocpage2sz;
- u8 nVols, nPhys;
- u8 vid, vbus, vioc;
+ int i;
+
+ if (!ioc->ir_firmware)
+ return 0;
+
+ /* Free the old page
+ */
+ kfree(ioc->raid_data.pIocPg2);
+ ioc->raid_data.pIocPg2 = NULL;
+ mpt_inactive_raid_list_free(ioc);
/* Read IOCP2 header then the page.
*/
@@ -4764,55 +4976,23 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.physAddr = ioc2_dma;
if (mpt_config(ioc, &cfg) != 0)
- goto done_and_free;
+ goto out;
+
+ mem = kmalloc(iocpage2sz, GFP_KERNEL);
+ if (!mem)
+ goto out;
- if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
- mem = kmalloc(iocpage2sz, GFP_ATOMIC);
- if (mem) {
- ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
- } else {
- goto done_and_free;
- }
- }
memcpy(mem, (u8 *)pIoc2, iocpage2sz);
+ ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
- /* Identify RAID Volume Id's */
- nVols = pIoc2->NumActiveVolumes;
- if ( nVols == 0) {
- /* No RAID Volume.
- */
- goto done_and_free;
- } else {
- /* At least 1 RAID Volume
- */
- pIocRv = pIoc2->RaidVolume;
- ioc->raid_data.isRaid = 0;
- for (jj = 0; jj < nVols; jj++, pIocRv++) {
- vid = pIocRv->VolumeID;
- vbus = pIocRv->VolumeBus;
- vioc = pIocRv->VolumeIOC;
-
- /* find the match
- */
- if (vbus == 0) {
- ioc->raid_data.isRaid |= (1 << vid);
- } else {
- /* Error! Always bus 0
- */
- }
- }
- }
+ mpt_read_ioc_pg_3(ioc);
- /* Identify Hidden Physical Disk Id's */
- nPhys = pIoc2->NumActivePhysDisks;
- if (nPhys == 0) {
- /* No physical disks.
- */
- } else {
- mpt_read_ioc_pg_3(ioc);
- }
+ for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
+ mpt_inactive_raid_volumes(ioc,
+ pIoc2->RaidVolume[i].VolumeBus,
+ pIoc2->RaidVolume[i].VolumeID);
-done_and_free:
+ out:
pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
return rc;
@@ -4865,7 +5045,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
cfg.physAddr = ioc3_dma;
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
if (mpt_config(ioc, &cfg) == 0) {
- mem = kmalloc(iocpage3sz, GFP_ATOMIC);
+ mem = kmalloc(iocpage3sz, GFP_KERNEL);
if (mem) {
memcpy(mem, (u8 *)pIoc3, iocpage3sz);
ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
@@ -5679,8 +5859,6 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
return rc;
}
-# define EVENT_DESCR_STR_SZ 100
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static void
EventDescriptionStr(u8 event, u32 evData0, char *evStr)
@@ -5708,9 +5886,6 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
break;
case MPI_EVENT_RESCAN:
ds = "Bus Rescan Event";
- /* Ok, do we need to do anything here? As far as
- I can tell, this is when a new device gets added
- to the loop. */
break;
case MPI_EVENT_LINK_STATUS_CHANGE:
if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
@@ -5787,48 +5962,63 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
{
u8 id = (u8)(evData0);
+ u8 channel = (u8)(evData0 >> 8);
u8 ReasonCode = (u8)(evData0 >> 16);
switch (ReasonCode) {
case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: Added: id=%d", id);
+ "SAS Device Status Change: Added: "
+ "id=%d channel=%d", id, channel);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: Deleted: id=%d", id);
+ "SAS Device Status Change: Deleted: "
+ "id=%d channel=%d", id, channel);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: SMART Data: id=%d",
- id);
+ "SAS Device Status Change: SMART Data: "
+ "id=%d channel=%d", id, channel);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: No Persistancy: id=%d", id);
+ "SAS Device Status Change: No Persistancy: "
+ "id=%d channel=%d", id, channel);
+ break;
+ case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS Device Status Change: Unsupported Device "
+ "Discovered : id=%d channel=%d", id, channel);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: Internal Device Reset : id=%d", id);
+ "SAS Device Status Change: Internal Device "
+ "Reset : id=%d channel=%d", id, channel);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: Internal Task Abort : id=%d", id);
+ "SAS Device Status Change: Internal Task "
+ "Abort : id=%d channel=%d", id, channel);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: Internal Abort Task Set : id=%d", id);
+ "SAS Device Status Change: Internal Abort "
+ "Task Set : id=%d channel=%d", id, channel);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: Internal Clear Task Set : id=%d", id);
+ "SAS Device Status Change: Internal Clear "
+ "Task Set : id=%d channel=%d", id, channel);
break;
case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: Internal Query Task : id=%d", id);
+ "SAS Device Status Change: Internal Query "
+ "Task : id=%d channel=%d", id, channel);
break;
default:
snprintf(evStr, EVENT_DESCR_STR_SZ,
- "SAS Device Status Change: Unknown: id=%d", id);
+ "SAS Device Status Change: Unknown: "
+ "id=%d channel=%d", id, channel);
break;
}
break;
@@ -5837,8 +6027,16 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
ds = "Bus Timer Expired";
break;
case MPI_EVENT_QUEUE_FULL:
- ds = "Queue Full";
+ {
+ u16 curr_depth = (u16)(evData0 >> 16);
+ u8 channel = (u8)(evData0 >> 8);
+ u8 id = (u8)(evData0);
+
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "Queue Full: channel=%d id=%d depth=%d",
+ channel, id, curr_depth);
break;
+ }
case MPI_EVENT_SAS_SES:
ds = "SAS SES Event";
break;
@@ -5942,6 +6140,76 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
ds = "SAS Log Entry Added";
break;
+ case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
+ {
+ u8 phy_num = (u8)(evData0);
+ u8 port_num = (u8)(evData0 >> 8);
+ u8 port_width = (u8)(evData0 >> 16);
+ u8 primative = (u8)(evData0 >> 24);
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS Broadcase Primative: phy=%d port=%d "
+ "width=%d primative=0x%02x",
+ phy_num, port_num, port_width, primative);
+ break;
+ }
+
+ case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
+ {
+ u8 reason = (u8)(evData0);
+ u8 port_num = (u8)(evData0 >> 8);
+ u16 handle = le16_to_cpu(evData0 >> 16);
+
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS Initiator Device Status Change: reason=0x%02x "
+ "port=%d handle=0x%04x",
+ reason, port_num, handle);
+ break;
+ }
+
+ case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
+ {
+ u8 max_init = (u8)(evData0);
+ u8 current_init = (u8)(evData0 >> 8);
+
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS Initiator Device Table Overflow: max initiators=%02d "
+ "current initators=%02d",
+ max_init, current_init);
+ break;
+ }
+ case MPI_EVENT_SAS_SMP_ERROR:
+ {
+ u8 status = (u8)(evData0);
+ u8 port_num = (u8)(evData0 >> 8);
+ u8 result = (u8)(evData0 >> 16);
+
+ if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS SMP Error: port=%d result=0x%02x",
+ port_num, result);
+ else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS SMP Error: port=%d : CRC Error",
+ port_num);
+ else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS SMP Error: port=%d : Timeout",
+ port_num);
+ else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS SMP Error: port=%d : No Destination",
+ port_num);
+ else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS SMP Error: port=%d : Bad Destination",
+ port_num);
+ else
+ snprintf(evStr, EVENT_DESCR_STR_SZ,
+ "SAS SMP Error: port=%d : status=0x%02x",
+ port_num, status);
+ break;
+ }
+
/*
* MPT base "custom" events may be added here...
*/
@@ -6205,10 +6473,11 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
"Abort", /* 12h */
"IO Not Yet Executed", /* 13h */
"IO Executed", /* 14h */
- "Persistent Reservation Out Not Affiliation Owner", /* 15h */
+ "Persistent Reservation Out Not Affiliation "
+ "Owner", /* 15h */
"Open Transmit DMA Abort", /* 16h */
"IO Device Missing Delay Retry", /* 17h */
- NULL, /* 18h */
+ "IO Cancelled Due to Recieve Error", /* 18h */
NULL, /* 19h */
NULL, /* 1Ah */
NULL, /* 1Bh */
@@ -6218,6 +6487,96 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
NULL, /* 1Fh */
"Enclosure Management" /* 20h */
};
+ static char *ir_code_str[] = {
+ "Raid Action Error", /* 00h */
+ NULL, /* 00h */
+ NULL, /* 01h */
+ NULL, /* 02h */
+ NULL, /* 03h */
+ NULL, /* 04h */
+ NULL, /* 05h */
+ NULL, /* 06h */
+ NULL /* 07h */
+ };
+ static char *raid_sub_code_str[] = {
+ NULL, /* 00h */
+ "Volume Creation Failed: Data Passed too "
+ "Large", /* 01h */
+ "Volume Creation Failed: Duplicate Volumes "
+ "Attempted", /* 02h */
+ "Volume Creation Failed: Max Number "
+ "Supported Volumes Exceeded", /* 03h */
+ "Volume Creation Failed: DMA Error", /* 04h */
+ "Volume Creation Failed: Invalid Volume Type", /* 05h */
+ "Volume Creation Failed: Error Reading "
+ "MFG Page 4", /* 06h */
+ "Volume Creation Failed: Creating Internal "
+ "Structures", /* 07h */
+ NULL, /* 08h */
+ NULL, /* 09h */
+ NULL, /* 0Ah */
+ NULL, /* 0Bh */
+ NULL, /* 0Ch */
+ NULL, /* 0Dh */
+ NULL, /* 0Eh */
+ NULL, /* 0Fh */
+ "Activation failed: Already Active Volume", /* 10h */
+ "Activation failed: Unsupported Volume Type", /* 11h */
+ "Activation failed: Too Many Active Volumes", /* 12h */
+ "Activation failed: Volume ID in Use", /* 13h */
+ "Activation failed: Reported Failure", /* 14h */
+ "Activation failed: Importing a Volume", /* 15h */
+ NULL, /* 16h */
+ NULL, /* 17h */
+ NULL, /* 18h */
+ NULL, /* 19h */
+ NULL, /* 1Ah */
+ NULL, /* 1Bh */
+ NULL, /* 1Ch */
+ NULL, /* 1Dh */
+ NULL, /* 1Eh */
+ NULL, /* 1Fh */
+ "Phys Disk failed: Too Many Phys Disks", /* 20h */
+ "Phys Disk failed: Data Passed too Large", /* 21h */
+ "Phys Disk failed: DMA Error", /* 22h */
+ "Phys Disk failed: Invalid <channel:id>", /* 23h */
+ "Phys Disk failed: Creating Phys Disk Config "
+ "Page", /* 24h */
+ NULL, /* 25h */
+ NULL, /* 26h */
+ NULL, /* 27h */
+ NULL, /* 28h */
+ NULL, /* 29h */
+ NULL, /* 2Ah */
+ NULL, /* 2Bh */
+ NULL, /* 2Ch */
+ NULL, /* 2Dh */
+ NULL, /* 2Eh */
+ NULL, /* 2Fh */
+ "Compatibility Error: IR Disabled", /* 30h */
+ "Compatibility Error: Inquiry Comand Failed", /* 31h */
+ "Compatibility Error: Device not Direct Access "
+ "Device ", /* 32h */
+ "Compatibility Error: Removable Device Found", /* 33h */
+ "Compatibility Error: Device SCSI Version not "
+ "2 or Higher", /* 34h */
+ "Compatibility Error: SATA Device, 48 BIT LBA "
+ "not Supported", /* 35h */
+ "Compatibility Error: Device doesn't have "
+ "512 Byte Block Sizes", /* 36h */
+ "Compatibility Error: Volume Type Check Failed", /* 37h */
+ "Compatibility Error: Volume Type is "
+ "Unsupported by FW", /* 38h */
+ "Compatibility Error: Disk Drive too Small for "
+ "use in Volume", /* 39h */
+ "Compatibility Error: Phys Disk for Create "
+ "Volume not Found", /* 3Ah */
+ "Compatibility Error: Too Many or too Few "
+ "Disks for Volume Type", /* 3Bh */
+ "Compatibility Error: Disk stripe Sizes "
+ "Must be 64KB", /* 3Ch */
+ "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
+ };
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
@@ -6226,7 +6585,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
* @log_info: U32 LogInfo reply word from the IOC
*
* Refer to lsi/mpi_log_sas.h.
- */
+ **/
static void
mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
{
@@ -6240,56 +6599,165 @@ union loginfo_type {
}dw;
};
union loginfo_type sas_loginfo;
+ char *originator_desc = NULL;
char *code_desc = NULL;
+ char *sub_code_desc = NULL;
sas_loginfo.loginfo = log_info;
if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
(sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
return;
- if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
- (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
- code_desc = iop_code_str[sas_loginfo.dw.code];
- }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
- (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
- code_desc = pl_code_str[sas_loginfo.dw.code];
+
+ originator_desc = originator_str[sas_loginfo.dw.originator];
+
+ switch (sas_loginfo.dw.originator) {
+
+ case 0: /* IOP */
+ if (sas_loginfo.dw.code <
+ sizeof(iop_code_str)/sizeof(char*))
+ code_desc = iop_code_str[sas_loginfo.dw.code];
+ break;
+ case 1: /* PL */
+ if (sas_loginfo.dw.code <
+ sizeof(pl_code_str)/sizeof(char*))
+ code_desc = pl_code_str[sas_loginfo.dw.code];
+ break;
+ case 2: /* IR */
+ if (sas_loginfo.dw.code >=
+ sizeof(ir_code_str)/sizeof(char*))
+ break;
+ code_desc = ir_code_str[sas_loginfo.dw.code];
+ if (sas_loginfo.dw.subcode >=
+ sizeof(raid_sub_code_str)/sizeof(char*))
+ break;
+ if (sas_loginfo.dw.code == 0)
+ sub_code_desc =
+ raid_sub_code_str[sas_loginfo.dw.subcode];
+ break;
+ default:
+ return;
}
- if (code_desc != NULL)
+ if (sub_code_desc != NULL)
+ printk(MYIOC_s_INFO_FMT
+ "LogInfo(0x%08x): Originator={%s}, Code={%s},"
+ " SubCode={%s}\n",
+ ioc->name, log_info, originator_desc, code_desc,
+ sub_code_desc);
+ else if (code_desc != NULL)
printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): Originator={%s}, Code={%s},"
" SubCode(0x%04x)\n",
- ioc->name,
- log_info,
- originator_str[sas_loginfo.dw.originator],
- code_desc,
+ ioc->name, log_info, originator_desc, code_desc,
sas_loginfo.dw.subcode);
else
printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
" SubCode(0x%04x)\n",
- ioc->name,
- log_info,
- originator_str[sas_loginfo.dw.originator],
- sas_loginfo.dw.code,
- sas_loginfo.dw.subcode);
+ ioc->name, log_info, originator_desc,
+ sas_loginfo.dw.code, sas_loginfo.dw.subcode);
}
+#ifdef MPT_DEBUG_REPLY
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
+ * mpt_iocstatus_info_config - IOCSTATUS information for config pages
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * ioc_status: U32 IOCStatus word from IOC
+ * @mf: Pointer to MPT request frame
+ *
+ * Refer to lsi/mpi.h.
+ **/
+static void
+mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
+{
+ Config_t *pReq = (Config_t *)mf;
+ char extend_desc[EVENT_DESCR_STR_SZ];
+ char *desc = NULL;
+ u32 form;
+ u8 page_type;
+
+ if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
+ page_type = pReq->ExtPageType;
+ else
+ page_type = pReq->Header.PageType;
+
+ /*
+ * ignore invalid page messages for GET_NEXT_HANDLE
+ */
+ form = le32_to_cpu(pReq->PageAddress);
+ if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
+ if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
+ page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
+ page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
+ if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
+ MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
+ return;
+ }
+ if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
+ if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
+ MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
+ return;
+ }
+
+ snprintf(extend_desc, EVENT_DESCR_STR_SZ,
+ "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
+ page_type, pReq->Header.PageNumber, pReq->Action, form);
+
+ switch (ioc_status) {
+
+ case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
+ desc = "Config Page Invalid Action";
+ break;
+
+ case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
+ desc = "Config Page Invalid Type";
+ break;
+
+ case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
+ desc = "Config Page Invalid Page";
+ break;
+
+ case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
+ desc = "Config Page Invalid Data";
+ break;
+
+ case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
+ desc = "Config Page No Defaults";
+ break;
+
+ case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
+ desc = "Config Page Can't Commit";
+ break;
+ }
+
+ if (!desc)
+ return;
+
+ printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
+ ioc->name, ioc_status, desc, extend_desc);
+}
+
+/**
+ * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
* @ioc: Pointer to MPT_ADAPTER structure
* @ioc_status: U32 IOCStatus word from IOC
* @mf: Pointer to MPT request frame
*
* Refer to lsi/mpi.h.
- */
+ **/
static void
-mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
+mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
{
u32 status = ioc_status & MPI_IOCSTATUS_MASK;
char *desc = NULL;
switch (status) {
+
+/****************************************************************************/
+/* Common IOCStatus values for all replies */
+/****************************************************************************/
+
case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
desc = "Invalid Function";
break;
@@ -6322,84 +6790,180 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
desc = "Invalid State";
break;
+/****************************************************************************/
+/* Config IOCStatus values */
+/****************************************************************************/
+
case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
- /* No message for Config IOCStatus values */
+ mpt_iocstatus_info_config(ioc, status, mf);
break;
+/****************************************************************************/
+/* SCSIIO Reply (SPI, FCP, SAS) initiator values */
+/* */
+/* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
+/* */
+/****************************************************************************/
+
case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
- /* No message for recovered error
- desc = "SCSI Recovered Error";
- */
+ case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
+ case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
+ case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
+ case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
+ case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
+ case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
+ case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
+ case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
+ case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
+ case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
+ case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
+ case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
break;
- case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
- desc = "SCSI Invalid Bus";
+/****************************************************************************/
+/* SCSI Target values */
+/****************************************************************************/
+
+ case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
+ desc = "Target: Priority IO";
break;
- case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
- desc = "SCSI Invalid TargetID";
+ case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
+ desc = "Target: Invalid Port";
break;
- case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
- {
- SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
- U8 cdb = pScsiReq->CDB[0];
- if (cdb != 0x12) { /* Inquiry is issued for device scanning */
- desc = "SCSI Device Not There";
- }
+ case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
+ desc = "Target Invalid IO Index:";
break;
- }
- case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
- desc = "SCSI Data Overrun";
+ case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
+ desc = "Target: Aborted";
break;
- case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
- /* This error is checked in scsi_io_done(). Skip.
- desc = "SCSI Data Underrun";
- */
+ case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
+ desc = "Target: No Conn Retryable";
break;
- case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
- desc = "SCSI I/O Data Error";
+ case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
+ desc = "Target: No Connection";
break;
- case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
- desc = "SCSI Protocol Error";
+ case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
+ desc = "Target: Transfer Count Mismatch";
break;
- case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
- desc = "SCSI Task Terminated";
+ case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
+ desc = "Target: STS Data not Sent";
break;
- case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
- desc = "SCSI Residual Mismatch";
+ case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
+ desc = "Target: Data Offset Error";
break;
- case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
- desc = "SCSI Task Management Failed";
+ case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
+ desc = "Target: Too Much Write Data";
break;
- case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
- desc = "SCSI IOC Terminated";
+ case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
+ desc = "Target: IU Too Short";
break;
- case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
- desc = "SCSI Ext Terminated";
+ case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
+ desc = "Target: ACK NAK Timeout";
+ break;
+
+ case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
+ desc = "Target: Nak Received";
+ break;
+
+/****************************************************************************/
+/* Fibre Channel Direct Access values */
+/****************************************************************************/
+
+ case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
+ desc = "FC: Aborted";
+ break;
+
+ case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
+ desc = "FC: RX ID Invalid";
+ break;
+
+ case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
+ desc = "FC: DID Invalid";
+ break;
+
+ case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
+ desc = "FC: Node Logged Out";
+ break;
+
+ case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
+ desc = "FC: Exchange Canceled";
+ break;
+
+/****************************************************************************/
+/* LAN values */
+/****************************************************************************/
+
+ case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
+ desc = "LAN: Device not Found";
+ break;
+
+ case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
+ desc = "LAN: Device Failure";
+ break;
+
+ case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
+ desc = "LAN: Transmit Error";
+ break;
+
+ case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
+ desc = "LAN: Transmit Aborted";
+ break;
+
+ case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
+ desc = "LAN: Receive Error";
+ break;
+
+ case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
+ desc = "LAN: Receive Aborted";
+ break;
+
+ case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
+ desc = "LAN: Partial Packet";
+ break;
+
+ case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
+ desc = "LAN: Canceled";
+ break;
+
+/****************************************************************************/
+/* Serial Attached SCSI values */
+/****************************************************************************/
+
+ case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
+ desc = "SAS: SMP Request Failed";
+ break;
+
+ case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
+ desc = "SAS: SMP Data Overrun";
break;
default:
desc = "Others";
break;
}
- if (desc != NULL)
- printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
+
+ if (!desc)
+ return;
+
+ printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
}
+#endif
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
EXPORT_SYMBOL(mpt_attach);
@@ -6434,6 +6998,7 @@ EXPORT_SYMBOL(mpt_findImVolumes);
EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory);
EXPORT_SYMBOL(mptbase_sas_persist_operation);
+EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index e316708f76bd..e3a39272aad6 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -6,7 +6,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -75,8 +75,8 @@
#define COPYRIGHT "Copyright (c) 1999-2007 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.04.03"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.03"
+#define MPT_LINUX_VERSION_COMMON "3.04.04"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.04"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@@ -172,6 +172,9 @@
#define MPT_SCSI_SG_DEPTH 40
#endif
+/* debug print string length used for events and iocstatus */
+# define EVENT_DESCR_STR_SZ 100
+
#ifdef __KERNEL__ /* { */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -334,8 +337,8 @@ typedef struct _VirtTarget {
struct scsi_target *starget;
u8 tflags;
u8 ioc_id;
- u8 target_id;
- u8 bus_id;
+ u8 id;
+ u8 channel;
u8 minSyncFactor; /* 0xFF is async */
u8 maxOffset; /* 0 if async */
u8 maxWidth; /* 0 if narrow, 1 if wide */
@@ -344,13 +347,12 @@ typedef struct _VirtTarget {
u8 type; /* byte 0 of Inquiry data */
u8 deleted; /* target in process of being removed */
u32 num_luns;
- u32 luns[8]; /* Max LUNs is 256 */
} VirtTarget;
typedef struct _VirtDevice {
VirtTarget *vtarget;
u8 configured_lun;
- u32 lun;
+ int lun;
} VirtDevice;
/*
@@ -412,7 +414,7 @@ typedef struct _MPT_IOCTL {
u8 rsvd;
u8 status; /* current command status */
u8 reset; /* 1 if bus reset allowed */
- u8 target; /* target for reset */
+ u8 id; /* target for reset */
struct mutex ioctl_mutex;
} MPT_IOCTL;
@@ -483,10 +485,24 @@ typedef struct _SasCfgData {
*/
}SasCfgData;
+/*
+ * Inactive volume link list of raid component data
+ * @inactive_list
+ */
+struct inactive_raid_component_info {
+ struct list_head list;
+ u8 volumeID; /* volume target id */
+ u8 volumeBus; /* volume channel */
+ IOC_3_PHYS_DISK d; /* phys disk info */
+};
+
typedef struct _RaidCfgData {
IOCPage2_t *pIocPg2; /* table of Raid Volumes */
IOCPage3_t *pIocPg3; /* table of physical disks */
- int isRaid; /* bit field, 1 if RAID */
+ struct semaphore inactive_list_mutex;
+ struct list_head inactive_list; /* link list for physical
+ disk that belong in
+ inactive volumes */
}RaidCfgData;
typedef struct _FcCfgData {
@@ -528,6 +544,8 @@ typedef struct _MPT_ADAPTER
u32 mem_phys; /* == f4020000 (mmap) */
u32 pio_mem_phys; /* Programmed IO (downloadboot) */
int mem_size; /* mmap memory size */
+ int number_of_buses;
+ int devices_per_bus;
int alloc_total;
u32 last_state;
int active;
@@ -607,6 +625,8 @@ typedef struct _MPT_ADAPTER
u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */
LANPage0_t lan_cnfg_page0;
LANPage1_t lan_cnfg_page1;
+
+ u8 ir_firmware; /* =1 if IR firmware detected */
/*
* Description: errata_flag_1064
* If a PCIX read occurs within 1 or 2 cycles after the chip receives
@@ -790,12 +810,6 @@ typedef struct _mpt_sge {
#define ddvprintk(x)
#endif
-#ifdef MPT_DEBUG_NEGO
-#define dnegoprintk(x) printk x
-#else
-#define dnegoprintk(x)
-#endif
-
#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
#define ddvtprintk(x) printk x
#else
@@ -957,7 +971,6 @@ typedef struct _MPT_SCSI_HOST {
int port;
u32 pad0;
struct scsi_cmnd **ScsiLookup;
- VirtTarget **Targets;
MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
struct timer_list timer;
/* Pool of memory for holding SCpnts before doing
@@ -981,6 +994,7 @@ typedef struct _MPT_SCSI_HOST {
int scandv_wait_done;
long last_queue_full;
u16 tm_iocstatus;
+ struct list_head target_reset_list;
} MPT_SCSI_HOST;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1046,6 +1060,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
+extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk);
/*
* Public data decl's...
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 504632da4347..9d0f30478e46 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -5,7 +5,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -313,7 +313,7 @@ static void mptctl_timeout_expired (MPT_IOCTL *ioctl)
*/
dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
ioctl->ioc->name));
- mpt_HardResetHandler(ioctl->ioc, NO_SLEEP);
+ mpt_HardResetHandler(ioctl->ioc, CAN_SLEEP);
}
return;
@@ -361,7 +361,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
ioctl->ioc->name, mf));
pScsiTm = (SCSITaskMgmt_t *) mf;
- pScsiTm->TargetID = ioctl->target;
+ pScsiTm->TargetID = ioctl->id;
pScsiTm->Bus = hd->port; /* 0 */
pScsiTm->ChainOffset = 0;
pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
@@ -1159,15 +1159,12 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
struct mpt_ioctl_iocinfo *karg;
MPT_ADAPTER *ioc;
struct pci_dev *pdev;
- struct Scsi_Host *sh;
- MPT_SCSI_HOST *hd;
int iocnum;
- int numDevices = 0;
- unsigned int max_id;
- int ii;
unsigned int port;
int cim_rev;
u8 revision;
+ struct scsi_device *sdev;
+ VirtDevice *vdev;
dctlprintk((": mptctl_getiocinfo called.\n"));
/* Add of PCI INFO results in unaligned access for
@@ -1257,23 +1254,16 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
/* Get number of devices
*/
- if ((sh = ioc->sh) != NULL) {
- /* sh->max_id = maximum target ID + 1
- */
- max_id = sh->max_id - 1;
- hd = (MPT_SCSI_HOST *) sh->hostdata;
-
- /* Check all of the target structures and
- * keep a counter.
- */
- if (hd && hd->Targets) {
- for (ii = 0; ii <= max_id; ii++) {
- if (hd->Targets[ii])
- numDevices++;
- }
+ karg->numDevices = 0;
+ if (ioc->sh) {
+ shost_for_each_device(sdev, ioc->sh) {
+ vdev = sdev->hostdata;
+ if (vdev->vtarget->tflags &
+ MPT_TARGET_FLAGS_RAID_COMPONENT)
+ continue;
+ karg->numDevices++;
}
}
- karg->numDevices = numDevices;
/* Set the BIOS and FW Version
*/
@@ -1319,21 +1309,16 @@ mptctl_gettargetinfo (unsigned long arg)
struct mpt_ioctl_targetinfo __user *uarg = (void __user *) arg;
struct mpt_ioctl_targetinfo karg;
MPT_ADAPTER *ioc;
- struct Scsi_Host *sh;
- MPT_SCSI_HOST *hd;
- VirtTarget *vdev;
+ VirtDevice *vdev;
char *pmem;
int *pdata;
- IOCPage2_t *pIoc2;
- IOCPage3_t *pIoc3;
int iocnum;
int numDevices = 0;
- unsigned int max_id;
- int id, jj, indexed_lun, lun_index;
- u32 lun;
+ int lun;
int maxWordsLeft;
int numBytes;
- u8 port, devType, bus_id;
+ u8 port;
+ struct scsi_device *sdev;
dctlprintk(("mptctl_gettargetinfo called.\n"));
if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) {
@@ -1389,74 +1374,22 @@ mptctl_gettargetinfo (unsigned long arg)
/* Get number of devices
*/
- if ((sh = ioc->sh) != NULL) {
-
- max_id = sh->max_id - 1;
- hd = (MPT_SCSI_HOST *) sh->hostdata;
-
- /* Check all of the target structures.
- * Save the Id and increment the counter,
- * if ptr non-null.
- * sh->max_id = maximum target ID + 1
- */
- if (hd && hd->Targets) {
- mpt_findImVolumes(ioc);
- pIoc2 = ioc->raid_data.pIocPg2;
- for ( id = 0; id <= max_id; ) {
- if ( pIoc2 && pIoc2->NumActiveVolumes ) {
- if ( id == pIoc2->RaidVolume[0].VolumeID ) {
- if (maxWordsLeft <= 0) {
- printk(KERN_ERR "mptctl_gettargetinfo - "
- "buffer is full but volume is available on ioc %d\n, numDevices=%d", iocnum, numDevices);
- goto data_space_full;
- }
- if ( ( pIoc2->RaidVolume[0].Flags & MPI_IOCPAGE2_FLAG_VOLUME_INACTIVE ) == 0 )
- devType = 0x80;
- else
- devType = 0xC0;
- bus_id = pIoc2->RaidVolume[0].VolumeBus;
- numDevices++;
- *pdata = ( (devType << 24) | (bus_id << 8) | id );
- dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
- "volume ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
- pdata++;
- --maxWordsLeft;
- goto next_id;
- } else {
- pIoc3 = ioc->raid_data.pIocPg3;
- for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
- if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
- goto next_id;
- }
- }
- }
- if ( (vdev = hd->Targets[id]) ) {
- for (jj = 0; jj <= MPT_LAST_LUN; jj++) {
- lun_index = (jj >> 5);
- indexed_lun = (jj % 32);
- lun = (1 << indexed_lun);
- if (vdev->luns[lun_index] & lun) {
- if (maxWordsLeft <= 0) {
- printk(KERN_ERR "mptctl_gettargetinfo - "
- "buffer is full but more targets are available on ioc %d numDevices=%d\n", iocnum, numDevices);
- goto data_space_full;
- }
- bus_id = vdev->bus_id;
- numDevices++;
- *pdata = ( (jj << 16) | (bus_id << 8) | id );
- dctlprintk((KERN_ERR "mptctl_gettargetinfo - "
- "target ioc=%d target=%x numDevices=%d pdata=%p\n", iocnum, *pdata, numDevices, pdata));
- pdata++;
- --maxWordsLeft;
- }
- }
- }
-next_id:
- id++;
- }
+ if (ioc->sh){
+ shost_for_each_device(sdev, ioc->sh) {
+ if (!maxWordsLeft)
+ continue;
+ vdev = sdev->hostdata;
+ if (vdev->vtarget->tflags &
+ MPT_TARGET_FLAGS_RAID_COMPONENT)
+ continue;
+ lun = (vdev->vtarget->raidVolume) ? 0x80 : vdev->lun;
+ *pdata = (((u8)lun << 16) + (vdev->vtarget->channel << 8) +
+ (vdev->vtarget->id ));
+ pdata++;
+ numDevices++;
+ --maxWordsLeft;
}
}
-data_space_full:
karg.numDevices = numDevices;
/* Copy part of the data from kernel memory to user memory
@@ -1821,6 +1754,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
int msgContext;
u16 req_idx;
ulong timeout;
+ struct scsi_device *sdev;
dctlprintk(("mptctl_do_mpt_command called.\n"));
bufIn.kptr = bufOut.kptr = NULL;
@@ -1902,14 +1836,13 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
case MPI_FUNCTION_SCSI_IO_REQUEST:
if (ioc->sh) {
SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
- VirtTarget *pTarget = NULL;
- MPT_SCSI_HOST *hd = NULL;
int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
int scsidir = 0;
- int target = (int) pScsiReq->TargetID;
int dataSize;
+ u32 id;
- if ((target < 0) || (target >= ioc->sh->max_id)) {
+ id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
+ if (pScsiReq->TargetID > id) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"Target ID out of bounds. \n",
__FILE__, __LINE__);
@@ -1917,6 +1850,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
goto done_free_mem;
}
+ if (pScsiReq->Bus >= ioc->number_of_buses) {
+ printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
+ "Target Bus out of bounds. \n",
+ __FILE__, __LINE__);
+ rc = -ENODEV;
+ goto done_free_mem;
+ }
+
pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
pScsiReq->MsgFlags |= mpt_msg_flags();
@@ -1936,13 +1877,15 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
cpu_to_le32(ioc->sense_buf_low_dma
+ (req_idx * MPT_SENSE_BUFFER_ALLOC));
- if ((hd = (MPT_SCSI_HOST *) ioc->sh->hostdata)) {
- if (hd->Targets)
- pTarget = hd->Targets[target];
- }
+ shost_for_each_device(sdev, ioc->sh) {
+ struct scsi_target *starget = scsi_target(sdev);
+ VirtTarget *vtarget = starget->hostdata;
- if (pTarget &&(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
- qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
+ if ((pScsiReq->TargetID == vtarget->id) &&
+ (pScsiReq->Bus == vtarget->channel) &&
+ (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
+ qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
+ }
/* Have the IOCTL driver set the direction based
* on the dataOutSize (ordering issue with Sparc).
@@ -1959,7 +1902,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
pScsiReq->DataLength = cpu_to_le32(dataSize);
ioc->ioctl->reset = MPTCTL_RESET_OK;
- ioc->ioctl->target = target;
+ ioc->ioctl->id = pScsiReq->TargetID;
} else {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
@@ -2038,7 +1981,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
pScsiReq->DataLength = cpu_to_le32(dataSize);
ioc->ioctl->reset = MPTCTL_RESET_OK;
- ioc->ioctl->target = pScsiReq->TargetID;
+ ioc->ioctl->id = pScsiReq->TargetID;
} else {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"SCSI driver is not loaded. \n",
@@ -2719,7 +2662,7 @@ mptctl_hp_targetinfo(unsigned long arg)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static struct file_operations mptctl_fops = {
+static const struct file_operations mptctl_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.release = mptctl_release,
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h
index e65a1cf5eb0b..f7e72c5e47de 100644
--- a/drivers/message/fusion/mptctl.h
+++ b/drivers/message/fusion/mptctl.h
@@ -6,7 +6,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index c819c23b55b1..b7d4c7265ec6 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -4,7 +4,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -86,6 +86,12 @@ MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
" return following a device loss event."
" Default=60.");
+/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
+#define MPTFC_MAX_LUN (16895)
+static int max_lun = MPTFC_MAX_LUN;
+module_param(max_lun, int, 0);
+MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
+
static int mptfcDoneCtx = -1;
static int mptfcTaskCtx = -1;
static int mptfcInternalCtx = -1; /* Used only for internal commands */
@@ -292,10 +298,9 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
U32 port_id = 0xffffff;
int num_targ = 0;
int max_bus = ioc->facts.MaxBuses;
- int max_targ = ioc->facts.MaxDevices;
+ int max_targ;
- if (max_bus == 0 || max_targ == 0)
- goto out;
+ max_targ = (ioc->facts.MaxDevices == 0) ? 256 : ioc->facts.MaxDevices;
data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
p_p0 = p0_array = kzalloc(data_sz, GFP_KERNEL);
@@ -467,8 +472,8 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
if (ri->starget) {
vtarget = ri->starget->hostdata;
if (vtarget) {
- vtarget->target_id = pg0->CurrentTargetID;
- vtarget->bus_id = pg0->CurrentBus;
+ vtarget->id = pg0->CurrentTargetID;
+ vtarget->channel = pg0->CurrentBus;
}
}
*((struct mptfc_rport_info **)rport->dd_data) = ri;
@@ -540,8 +545,8 @@ mptfc_target_alloc(struct scsi_target *starget)
if (rport) {
ri = *((struct mptfc_rport_info **)rport->dd_data);
if (ri) { /* better be! */
- vtarget->target_id = ri->pg0.CurrentTargetID;
- vtarget->bus_id = ri->pg0.CurrentBus;
+ vtarget->id = ri->pg0.CurrentTargetID;
+ vtarget->channel = ri->pg0.CurrentBus;
ri->starget = starget;
rc = 0;
}
@@ -592,7 +597,6 @@ mptfc_slave_alloc(struct scsi_device *sdev)
if (vtarget->num_luns == 0) {
vtarget->ioc_id = hd->ioc->id;
vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
- hd->Targets[sdev->id] = vtarget;
}
vdev->vtarget = vtarget;
@@ -630,16 +634,17 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
struct mptfc_rport_info *ri;
struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
int err;
+ VirtDevice *vdev = SCpnt->device->hostdata;
- err = fc_remote_port_chkready(rport);
- if (unlikely(err)) {
- SCpnt->result = err;
+ if (!vdev || !vdev->vtarget) {
+ SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt);
return 0;
}
- if (!SCpnt->device->hostdata) { /* vdev */
- SCpnt->result = DID_NO_CONNECT << 16;
+ err = fc_remote_port_chkready(rport);
+ if (unlikely(err)) {
+ SCpnt->result = err;
done(SCpnt);
return 0;
}
@@ -1143,7 +1148,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc);
- return -ENODEV;
+ return 0;
}
sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
@@ -1173,10 +1178,9 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* set 16 byte cdb's */
sh->max_cmd_len = 16;
- sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
+ sh->max_id = ioc->pfacts->MaxDevices;
+ sh->max_lun = max_lun;
- sh->max_lun = MPT_LAST_LUN + 1;
- sh->max_channel = 0;
sh->this_id = ioc->pfacts[0].PortSCSIID;
/* Required entry.
@@ -1230,19 +1234,6 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
ioc->name, hd->ScsiLookup));
- /* Allocate memory for the device structures.
- * A non-Null pointer at an offset
- * indicates a device exists.
- * max_id = 1 + maximum id (hosts.h)
- */
- hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
- if (!hd->Targets) {
- error = -ENOMEM;
- goto out_mptfc_probe;
- }
-
- dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
-
/* Clear the TM flags
*/
hd->tmPending = 0;
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index 2936204d8ad6..b691292ff599 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -5,6 +5,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 2000-2007 LSI Logic Corporation
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptlan.h b/drivers/message/fusion/mptlan.h
index 70ab75e7c263..fe438bf119f6 100644
--- a/drivers/message/fusion/mptlan.h
+++ b/drivers/message/fusion/mptlan.h
@@ -5,6 +5,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 2000-2007 LSI Logic Corporation
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 09e9a9d96410..84b8b485e95b 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -4,7 +4,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
+ * (mailto:mpt_linux_developer@lsi.com)
* Copyright (c) 2005-2007 Dell
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -83,17 +83,31 @@ MODULE_PARM_DESC(mpt_pt_clear,
" Clear persistency table: enable=1 "
"(default=MPTSCSIH_PT_CLEAR=0)");
+/* scsi-mid layer global parmeter is max_report_luns, which is 511 */
+#define MPTSAS_MAX_LUN (16895)
+static int max_lun = MPTSAS_MAX_LUN;
+module_param(max_lun, int, 0);
+MODULE_PARM_DESC(max_lun, " max lun, default=16895 ");
+
static int mptsasDoneCtx = -1;
static int mptsasTaskCtx = -1;
static int mptsasInternalCtx = -1; /* Used only for internal commands */
static int mptsasMgmtCtx = -1;
+static void mptsas_hotplug_work(struct work_struct *work);
+
+struct mptsas_target_reset_event {
+ struct list_head list;
+ EVENT_DATA_SAS_DEVICE_STATUS_CHANGE sas_event_data;
+ u8 target_reset_issued;
+};
enum mptsas_hotplug_action {
MPTSAS_ADD_DEVICE,
MPTSAS_DEL_DEVICE,
MPTSAS_ADD_RAID,
MPTSAS_DEL_RAID,
+ MPTSAS_ADD_INACTIVE_VOLUME,
MPTSAS_IGNORE_EVENT,
};
@@ -102,14 +116,15 @@ struct mptsas_hotplug_event {
MPT_ADAPTER *ioc;
enum mptsas_hotplug_action event_type;
u64 sas_address;
- u32 channel;
- u32 id;
+ u8 channel;
+ u8 id;
u32 device_info;
u16 handle;
u16 parent_handle;
u8 phy_id;
- u8 phys_disk_num;
- u8 phys_disk_num_valid;
+ u8 phys_disk_num_valid; /* hrc (hidden raid component) */
+ u8 phys_disk_num; /* hrc - unique index*/
+ u8 hidden_raid_component; /* hrc - don't expose*/
};
struct mptsas_discovery_event {
@@ -134,6 +149,7 @@ struct mptsas_devinfo {
u8 port_id; /* sas physical port this device
is assoc'd with */
u8 id; /* logical target id of this device */
+ u32 phys_disk_num; /* phys disk id, for csmi-ioctls */
u8 channel; /* logical bus number of this device */
u64 sas_address; /* WWN of this device,
SATA is assigned by HBA,expander */
@@ -153,6 +169,7 @@ struct mptsas_portinfo_details{
};
struct mptsas_phyinfo {
+ u16 handle; /* unique id to address this */
u8 phy_id; /* phy index */
u8 port_id; /* firmware port identifier */
u8 negotiated_link_rate; /* nego'd link rate for this phy */
@@ -168,7 +185,6 @@ struct mptsas_phyinfo {
struct mptsas_portinfo {
struct list_head list;
- u16 handle; /* unique id to address this */
u16 num_phys; /* number of phys */
struct mptsas_phyinfo *phy_info;
};
@@ -561,22 +577,273 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
mutex_unlock(&ioc->sas_topology_mutex);
}
+/**
+ * csmisas_find_vtarget
+ *
+ * @ioc
+ * @volume_id
+ * @volume_bus
+ *
+ **/
+static VirtTarget *
+mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id)
+{
+ struct scsi_device *sdev;
+ VirtDevice *vdev;
+ VirtTarget *vtarget = NULL;
+
+ shost_for_each_device(sdev, ioc->sh) {
+ if ((vdev = sdev->hostdata) == NULL)
+ continue;
+ if (vdev->vtarget->id == id &&
+ vdev->vtarget->channel == channel)
+ vtarget = vdev->vtarget;
+ }
+ return vtarget;
+}
+
+/**
+ * mptsas_target_reset
+ *
+ * Issues TARGET_RESET to end device using handshaking method
+ *
+ * @ioc
+ * @channel
+ * @id
+ *
+ * Returns (1) success
+ * (0) failure
+ *
+ **/
+static int
+mptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id)
+{
+ MPT_FRAME_HDR *mf;
+ SCSITaskMgmt_t *pScsiTm;
+
+ if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
+ dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n",
+ ioc->name,__FUNCTION__, __LINE__));
+ return 0;
+ }
+
+ /* Format the Request
+ */
+ pScsiTm = (SCSITaskMgmt_t *) mf;
+ memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));
+ pScsiTm->TargetID = id;
+ pScsiTm->Bus = channel;
+ pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
+ pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
+ pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
+
+ DBG_DUMP_TM_REQUEST_FRAME(mf);
+
+ if (mpt_send_handshake_request(ioc->TaskCtx, ioc,
+ sizeof(SCSITaskMgmt_t), (u32 *)mf, NO_SLEEP)) {
+ mpt_free_msg_frame(ioc, mf);
+ dfailprintk((MYIOC_s_WARN_FMT "%s, tm handshake failed @%d!!\n",
+ ioc->name,__FUNCTION__, __LINE__));
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
+ * mptsas_target_reset_queue
+ *
+ * Receive request for TARGET_RESET after recieving an firmware
+ * event NOT_RESPONDING_EVENT, then put command in link list
+ * and queue if task_queue already in use.
+ *
+ * @ioc
+ * @sas_event_data
+ *
+ **/
static void
-mptsas_target_reset(MPT_ADAPTER *ioc, VirtTarget * vtarget)
+mptsas_target_reset_queue(MPT_ADAPTER *ioc,
+ EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data)
{
- MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+ VirtTarget *vtarget = NULL;
+ struct mptsas_target_reset_event *target_reset_list;
+ u8 id, channel;
- if (mptscsih_TMHandler(hd,
- MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
- vtarget->bus_id, vtarget->target_id, 0, 0, 5) < 0) {
- hd->tmPending = 0;
- hd->tmState = TM_STATE_NONE;
- printk(MYIOC_s_WARN_FMT
- "Error processing TaskMgmt id=%d TARGET_RESET\n",
- ioc->name, vtarget->target_id);
+ id = sas_event_data->TargetID;
+ channel = sas_event_data->Bus;
+
+ if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))
+ return;
+
+ vtarget->deleted = 1; /* block IO */
+
+ target_reset_list = kzalloc(sizeof(*target_reset_list),
+ GFP_ATOMIC);
+ if (!target_reset_list) {
+ dfailprintk((MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
+ ioc->name,__FUNCTION__, __LINE__));
+ return;
+ }
+
+ memcpy(&target_reset_list->sas_event_data, sas_event_data,
+ sizeof(*sas_event_data));
+ list_add_tail(&target_reset_list->list, &hd->target_reset_list);
+
+ if (hd->resetPending)
+ return;
+
+ if (mptsas_target_reset(ioc, channel, id)) {
+ target_reset_list->target_reset_issued = 1;
+ hd->resetPending = 1;
}
}
+/**
+ * mptsas_dev_reset_complete
+ *
+ * Completion for TARGET_RESET after NOT_RESPONDING_EVENT,
+ * enable work queue to finish off removing device from upper layers.
+ * then send next TARGET_RESET in the queue.
+ *
+ * @ioc
+ *
+ **/
+static void
+mptsas_dev_reset_complete(MPT_ADAPTER *ioc)
+{
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+ struct list_head *head = &hd->target_reset_list;
+ struct mptsas_target_reset_event *target_reset_list;
+ struct mptsas_hotplug_event *ev;
+ EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;
+ u8 id, channel;
+ __le64 sas_address;
+
+ if (list_empty(head))
+ return;
+
+ target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list);
+
+ sas_event_data = &target_reset_list->sas_event_data;
+ id = sas_event_data->TargetID;
+ channel = sas_event_data->Bus;
+ hd->resetPending = 0;
+
+ /*
+ * retry target reset
+ */
+ if (!target_reset_list->target_reset_issued) {
+ if (mptsas_target_reset(ioc, channel, id)) {
+ target_reset_list->target_reset_issued = 1;
+ hd->resetPending = 1;
+ }
+ return;
+ }
+
+ /*
+ * enable work queue to remove device from upper layers
+ */
+ list_del(&target_reset_list->list);
+
+ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+ if (!ev) {
+ dfailprintk((MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",
+ ioc->name,__FUNCTION__, __LINE__));
+ return;
+ }
+
+ INIT_WORK(&ev->work, mptsas_hotplug_work);
+ ev->ioc = ioc;
+ ev->handle = le16_to_cpu(sas_event_data->DevHandle);
+ ev->parent_handle =
+ le16_to_cpu(sas_event_data->ParentDevHandle);
+ ev->channel = channel;
+ ev->id =id;
+ ev->phy_id = sas_event_data->PhyNum;
+ memcpy(&sas_address, &sas_event_data->SASAddress,
+ sizeof(__le64));
+ ev->sas_address = le64_to_cpu(sas_address);
+ ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo);
+ ev->event_type = MPTSAS_DEL_DEVICE;
+ schedule_work(&ev->work);
+ kfree(target_reset_list);
+
+ /*
+ * issue target reset to next device in the queue
+ */
+
+ head = &hd->target_reset_list;
+ if (list_empty(head))
+ return;
+
+ target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,
+ list);
+
+ sas_event_data = &target_reset_list->sas_event_data;
+ id = sas_event_data->TargetID;
+ channel = sas_event_data->Bus;
+
+ if (mptsas_target_reset(ioc, channel, id)) {
+ target_reset_list->target_reset_issued = 1;
+ hd->resetPending = 1;
+ }
+}
+
+/**
+ * mptsas_taskmgmt_complete
+ *
+ * @ioc
+ * @mf
+ * @mr
+ *
+ **/
+static int
+mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
+{
+ mptsas_dev_reset_complete(ioc);
+ return mptscsih_taskmgmt_complete(ioc, mf, mr);
+}
+
+/**
+ * mptscsih_ioc_reset
+ *
+ * @ioc
+ * @reset_phase
+ *
+ **/
+static int
+mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+ MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+ struct mptsas_target_reset_event *target_reset_list, *n;
+ int rc;
+
+ rc = mptscsih_ioc_reset(ioc, reset_phase);
+
+ if (ioc->bus_type != SAS)
+ goto out;
+
+ if (reset_phase != MPT_IOC_POST_RESET)
+ goto out;
+
+ if (!hd || !hd->ioc)
+ goto out;
+
+ if (list_empty(&hd->target_reset_list))
+ goto out;
+
+ /* flush the target_reset_list */
+ list_for_each_entry_safe(target_reset_list, n,
+ &hd->target_reset_list, list) {
+ list_del(&target_reset_list->list);
+ kfree(target_reset_list);
+ }
+
+ out:
+ return rc;
+}
+
static int
mptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,
u32 form, u32 form_specific)
@@ -661,8 +928,7 @@ mptsas_target_alloc(struct scsi_target *starget)
struct Scsi_Host *host = dev_to_shost(&starget->dev);
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
VirtTarget *vtarget;
- u32 target_id;
- u32 channel;
+ u8 id, channel;
struct sas_rphy *rphy;
struct mptsas_portinfo *p;
int i;
@@ -673,15 +939,19 @@ mptsas_target_alloc(struct scsi_target *starget)
vtarget->starget = starget;
vtarget->ioc_id = hd->ioc->id;
- vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
-
- target_id = starget->id;
+ vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
+ id = starget->id;
channel = 0;
- hd->Targets[target_id] = vtarget;
-
- if (starget->channel == MPTSAS_RAID_CHANNEL)
+ /*
+ * RAID volumes placed beyond the last expected port.
+ */
+ if (starget->channel == MPTSAS_RAID_CHANNEL) {
+ for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++)
+ if (id == hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)
+ channel = hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;
goto out;
+ }
rphy = dev_to_rphy(starget->dev.parent);
mutex_lock(&hd->ioc->sas_topology_mutex);
@@ -690,18 +960,19 @@ mptsas_target_alloc(struct scsi_target *starget)
if (p->phy_info[i].attached.sas_address !=
rphy->identify.sas_address)
continue;
- target_id = p->phy_info[i].attached.id;
+ id = p->phy_info[i].attached.id;
channel = p->phy_info[i].attached.channel;
mptsas_set_starget(&p->phy_info[i], starget);
/*
* Exposing hidden raid components
*/
- if (mptscsih_is_phys_disk(hd->ioc, target_id)) {
- target_id = mptscsih_raid_id_to_num(hd,
- target_id);
+ if (mptscsih_is_phys_disk(hd->ioc, channel, id)) {
+ id = mptscsih_raid_id_to_num(hd->ioc,
+ channel, id);
vtarget->tflags |=
MPT_TARGET_FLAGS_RAID_COMPONENT;
+ p->phy_info[i].attached.phys_disk_num = id;
}
mutex_unlock(&hd->ioc->sas_topology_mutex);
goto out;
@@ -713,8 +984,8 @@ mptsas_target_alloc(struct scsi_target *starget)
return -ENXIO;
out:
- vtarget->target_id = target_id;
- vtarget->bus_id = channel;
+ vtarget->id = id;
+ vtarget->channel = channel;
starget->hostdata = vtarget;
return 0;
}
@@ -786,7 +1057,8 @@ mptsas_slave_alloc(struct scsi_device *sdev)
* Exposing hidden raid components
*/
if (mptscsih_is_phys_disk(hd->ioc,
- p->phy_info[i].attached.id))
+ p->phy_info[i].attached.channel,
+ p->phy_info[i].attached.id))
sdev->no_uld_attach = 1;
mutex_unlock(&hd->ioc->sas_topology_mutex);
goto out;
@@ -808,13 +1080,14 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
{
VirtDevice *vdev = SCpnt->device->hostdata;
-// scsi_print_command(SCpnt);
- if (vdev->vtarget->deleted) {
+ if (!vdev || !vdev->vtarget || vdev->vtarget->deleted) {
SCpnt->result = DID_NO_CONNECT << 16;
done(SCpnt);
return 0;
}
+// scsi_print_command(SCpnt);
+
return mptscsih_qcmd(SCpnt,done);
}
@@ -1114,9 +1387,6 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
goto out_free_consistent;
}
- if (port_info->num_phys)
- port_info->handle =
- le16_to_cpu(buffer->PhyData[0].ControllerDevHandle);
for (i = 0; i < port_info->num_phys; i++) {
mptsas_print_phy_data(&buffer->PhyData[i]);
port_info->phy_info[i].phy_id = i;
@@ -1125,6 +1395,8 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
port_info->phy_info[i].negotiated_link_rate =
buffer->PhyData[i].NegotiatedLinkRate;
port_info->phy_info[i].portinfo = port_info;
+ port_info->phy_info[i].handle =
+ le16_to_cpu(buffer->PhyData[i].ControllerDevHandle);
}
out_free_consistent:
@@ -1261,6 +1533,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
device_info->phy_id = buffer->PhyNum;
device_info->port_id = buffer->PhysicalPort;
device_info->id = buffer->TargetID;
+ device_info->phys_disk_num = ~0;
device_info->channel = buffer->Bus;
memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
device_info->sas_address = le64_to_cpu(sas_address);
@@ -1325,7 +1598,6 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
/* save config data */
port_info->num_phys = buffer->NumPhys;
- port_info->handle = le16_to_cpu(buffer->DevHandle);
port_info->phy_info = kcalloc(port_info->num_phys,
sizeof(*port_info->phy_info),GFP_KERNEL);
if (!port_info->phy_info) {
@@ -1333,8 +1605,11 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
goto out_free_consistent;
}
- for (i = 0; i < port_info->num_phys; i++)
+ for (i = 0; i < port_info->num_phys; i++) {
port_info->phy_info[i].portinfo = port_info;
+ port_info->phy_info[i].handle =
+ le16_to_cpu(buffer->DevHandle);
+ }
out_free_consistent:
pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
@@ -1702,7 +1977,6 @@ static int
mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
{
struct mptsas_portinfo *port_info, *hba;
- u32 handle = 0xFFFF;
int error = -ENOMEM, i;
hba = kzalloc(sizeof(*port_info), GFP_KERNEL);
@@ -1714,34 +1988,36 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
goto out_free_port_info;
mutex_lock(&ioc->sas_topology_mutex);
- ioc->handle = hba->handle;
- port_info = mptsas_find_portinfo_by_handle(ioc, hba->handle);
+ ioc->handle = hba->phy_info[0].handle;
+ port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
if (!port_info) {
port_info = hba;
list_add_tail(&port_info->list, &ioc->sas_topology);
} else {
- port_info->handle = hba->handle;
- for (i = 0; i < hba->num_phys; i++)
+ for (i = 0; i < hba->num_phys; i++) {
port_info->phy_info[i].negotiated_link_rate =
hba->phy_info[i].negotiated_link_rate;
+ port_info->phy_info[i].handle =
+ hba->phy_info[i].handle;
+ port_info->phy_info[i].port_id =
+ hba->phy_info[i].port_id;
+ }
kfree(hba->phy_info);
kfree(hba);
hba = NULL;
}
mutex_unlock(&ioc->sas_topology_mutex);
-
for (i = 0; i < port_info->num_phys; i++) {
mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
- (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
- MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
+ (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+ port_info->phy_info[i].handle);
port_info->phy_info[i].identify.phy_id =
- port_info->phy_info[i].phy_id;
- handle = port_info->phy_info[i].identify.handle;
-
+ port_info->phy_info[i].phy_id = i;
if (port_info->phy_info[i].attached.handle)
mptsas_sas_device_pg0(ioc,
&port_info->phy_info[i].attached,
@@ -1777,12 +2053,12 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
goto out;
error = mptsas_sas_expander_pg0(ioc, ex,
- (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
- MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
+ (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
+ MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
if (error)
goto out_free_port_info;
- *handle = ex->handle;
+ *handle = ex->phy_info[0].handle;
mutex_lock(&ioc->sas_topology_mutex);
port_info = mptsas_find_portinfo_by_handle(ioc, *handle);
@@ -1790,7 +2066,12 @@ mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle)
port_info = ex;
list_add_tail(&port_info->list, &ioc->sas_topology);
} else {
- port_info->handle = ex->handle;
+ for (i = 0; i < ex->num_phys; i++) {
+ port_info->phy_info[i].handle =
+ ex->phy_info[i].handle;
+ port_info->phy_info[i].port_id =
+ ex->phy_info[i].port_id;
+ }
kfree(ex->phy_info);
kfree(ex);
ex = NULL;
@@ -1868,8 +2149,6 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
struct mptsas_portinfo buffer;
struct mptsas_portinfo *port_info, *n, *parent;
struct mptsas_phyinfo *phy_info;
- struct scsi_target * starget;
- VirtTarget * vtarget;
struct sas_port * port;
int i;
u64 expander_sas_address;
@@ -1884,26 +2163,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
if (mptsas_sas_expander_pg0(ioc, &buffer,
(MPI_SAS_EXPAND_PGAD_FORM_HANDLE <<
- MPI_SAS_EXPAND_PGAD_FORM_SHIFT), port_info->handle)) {
-
- /*
- * Issue target reset to all child end devices
- * then mark them deleted to prevent further
- * IO going to them.
- */
- phy_info = port_info->phy_info;
- for (i = 0; i < port_info->num_phys; i++, phy_info++) {
- starget = mptsas_get_starget(phy_info);
- if (!starget)
- continue;
- vtarget = starget->hostdata;
- if(vtarget->deleted)
- continue;
- vtarget->deleted = 1;
- mptsas_target_reset(ioc, vtarget);
- sas_port_delete(mptsas_get_port(phy_info));
- mptsas_port_delete(phy_info->port_details);
- }
+ MPI_SAS_EXPAND_PGAD_FORM_SHIFT),
+ port_info->phy_info[0].handle)) {
/*
* Obtain the port_info instance to the parent port
@@ -1972,11 +2233,13 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
/*
Reporting RAID volumes.
*/
+ if (!ioc->ir_firmware)
+ goto out;
if (!ioc->raid_data.pIocPg2)
goto out;
if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
goto out;
- for (i=0; i<ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
+ for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
scsi_add_device(ioc->sh, MPTSAS_RAID_CHANNEL,
ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID, 0);
}
@@ -2030,12 +2293,37 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry(port_info, &ioc->sas_topology, list) {
for (i = 0; i < port_info->num_phys; i++) {
+ if (!mptsas_is_end_device(
+ &port_info->phy_info[i].attached))
+ continue;
if (port_info->phy_info[i].attached.sas_address
!= sas_address)
continue;
+ phy_info = &port_info->phy_info[i];
+ break;
+ }
+ }
+ mutex_unlock(&ioc->sas_topology_mutex);
+ return phy_info;
+}
+
+static struct mptsas_phyinfo *
+mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
+{
+ struct mptsas_portinfo *port_info;
+ struct mptsas_phyinfo *phy_info = NULL;
+ int i;
+
+ mutex_lock(&ioc->sas_topology_mutex);
+ list_for_each_entry(port_info, &ioc->sas_topology, list) {
+ for (i = 0; i < port_info->num_phys; i++) {
if (!mptsas_is_end_device(
&port_info->phy_info[i].attached))
continue;
+ if (port_info->phy_info[i].attached.id != id)
+ continue;
+ if (port_info->phy_info[i].attached.channel != channel)
+ continue;
phy_info = &port_info->phy_info[i];
break;
}
@@ -2045,7 +2333,7 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
}
static struct mptsas_phyinfo *
-mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
+mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
{
struct mptsas_portinfo *port_info;
struct mptsas_phyinfo *phy_info = NULL;
@@ -2054,11 +2342,15 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry(port_info, &ioc->sas_topology, list) {
for (i = 0; i < port_info->num_phys; i++) {
- if (port_info->phy_info[i].attached.id != id)
- continue;
if (!mptsas_is_end_device(
&port_info->phy_info[i].attached))
continue;
+ if (port_info->phy_info[i].attached.phys_disk_num == ~0)
+ continue;
+ if (port_info->phy_info[i].attached.phys_disk_num != id)
+ continue;
+ if (port_info->phy_info[i].attached.channel != channel)
+ continue;
phy_info = &port_info->phy_info[i];
break;
}
@@ -2094,6 +2386,76 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
mptsas_reprobe_lun);
}
+static void
+mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
+{
+ CONFIGPARMS cfg;
+ ConfigPageHeader_t hdr;
+ dma_addr_t dma_handle;
+ pRaidVolumePage0_t buffer = NULL;
+ RaidPhysDiskPage0_t phys_disk;
+ int i;
+ struct mptsas_hotplug_event *ev;
+
+ memset(&cfg, 0 , sizeof(CONFIGPARMS));
+ memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
+ hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
+ cfg.pageAddr = (channel << 8) + id;
+ cfg.cfghdr.hdr = &hdr;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+
+ if (mpt_config(ioc, &cfg) != 0)
+ goto out;
+
+ if (!hdr.PageLength)
+ goto out;
+
+ buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
+ &dma_handle);
+
+ if (!buffer)
+ goto out;
+
+ cfg.physAddr = dma_handle;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ if (mpt_config(ioc, &cfg) != 0)
+ goto out;
+
+ if (!(buffer->VolumeStatus.Flags &
+ MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
+ goto out;
+
+ if (!buffer->NumPhysDisks)
+ goto out;
+
+ for (i = 0; i < buffer->NumPhysDisks; i++) {
+
+ if (mpt_raid_phys_disk_pg0(ioc,
+ buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
+ continue;
+
+ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+ if (!ev) {
+ printk(KERN_WARNING "mptsas: lost hotplug event\n");
+ goto out;
+ }
+
+ INIT_WORK(&ev->work, mptsas_hotplug_work);
+ ev->ioc = ioc;
+ ev->id = phys_disk.PhysDiskID;
+ ev->channel = phys_disk.PhysDiskBus;
+ ev->phys_disk_num_valid = 1;
+ ev->phys_disk_num = phys_disk.PhysDiskNum;
+ ev->event_type = MPTSAS_ADD_DEVICE;
+ schedule_work(&ev->work);
+ }
+
+ out:
+ if (buffer)
+ pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
+ dma_handle);
+}
/*
* Work queue thread to handle SAS hotplug events
*/
@@ -2102,6 +2464,7 @@ mptsas_hotplug_work(struct work_struct *work)
{
struct mptsas_hotplug_event *ev =
container_of(work, struct mptsas_hotplug_event, work);
+
MPT_ADAPTER *ioc = ev->ioc;
struct mptsas_phyinfo *phy_info;
struct sas_rphy *rphy;
@@ -2114,17 +2477,43 @@ mptsas_hotplug_work(struct work_struct *work)
VirtTarget *vtarget;
VirtDevice *vdevice;
-
mutex_lock(&ioc->sas_discovery_mutex);
switch (ev->event_type) {
case MPTSAS_DEL_DEVICE:
- phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id);
+ phy_info = NULL;
+ if (ev->phys_disk_num_valid) {
+ if (ev->hidden_raid_component){
+ if (mptsas_sas_device_pg0(ioc, &sas_device,
+ (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+ (ev->channel << 8) + ev->id)) {
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
+ break;
+ }
+ phy_info = mptsas_find_phyinfo_by_sas_address(
+ ioc, sas_device.sas_address);
+ }else
+ phy_info = mptsas_find_phyinfo_by_phys_disk_num(
+ ioc, ev->channel, ev->phys_disk_num);
+ }
+
+ if (!phy_info)
+ phy_info = mptsas_find_phyinfo_by_target(ioc,
+ ev->channel, ev->id);
/*
* Sanity checks, for non-existing phys and remote rphys.
*/
- if (!phy_info || !phy_info->port_details) {
+ if (!phy_info){
+ dfailprintk((MYIOC_s_ERR_FMT
+ "%s: exit at line=%d\n", ioc->name,
+ __FUNCTION__, __LINE__));
+ break;
+ }
+ if (!phy_info->port_details) {
dfailprintk((MYIOC_s_ERR_FMT
"%s: exit at line=%d\n", ioc->name,
__FUNCTION__, __LINE__));
@@ -2137,6 +2526,7 @@ mptsas_hotplug_work(struct work_struct *work)
__FUNCTION__, __LINE__));
break;
}
+
port = mptsas_get_port(phy_info);
if (!port) {
dfailprintk((MYIOC_s_ERR_FMT
@@ -2159,28 +2549,35 @@ mptsas_hotplug_work(struct work_struct *work)
/*
* Handling RAID components
*/
- if (ev->phys_disk_num_valid) {
- vtarget->target_id = ev->phys_disk_num;
- vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
+ if (ev->phys_disk_num_valid &&
+ ev->hidden_raid_component) {
+ printk(MYIOC_s_INFO_FMT
+ "RAID Hidding: channel=%d, id=%d, "
+ "physdsk %d \n", ioc->name, ev->channel,
+ ev->id, ev->phys_disk_num);
+ vtarget->id = ev->phys_disk_num;
+ vtarget->tflags |=
+ MPT_TARGET_FLAGS_RAID_COMPONENT;
mptsas_reprobe_target(starget, 1);
- break;
+ phy_info->attached.phys_disk_num =
+ ev->phys_disk_num;
+ break;
}
-
- vtarget->deleted = 1;
- mptsas_target_reset(ioc, vtarget);
}
- if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
+ if (phy_info->attached.device_info &
+ MPI_SAS_DEVICE_INFO_SSP_TARGET)
ds = "ssp";
- if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
+ if (phy_info->attached.device_info &
+ MPI_SAS_DEVICE_INFO_STP_TARGET)
ds = "stp";
- if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
+ if (phy_info->attached.device_info &
+ MPI_SAS_DEVICE_INFO_SATA_DEVICE)
ds = "sata";
printk(MYIOC_s_INFO_FMT
"removing %s device, channel %d, id %d, phy %d\n",
ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
-
#ifdef MPT_DEBUG_SAS_WIDE
dev_printk(KERN_DEBUG, &port->dev,
"delete port (%d)\n", port->port_identifier);
@@ -2198,14 +2595,14 @@ mptsas_hotplug_work(struct work_struct *work)
*/
if (mptsas_sas_device_pg0(ioc, &sas_device,
(MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
- MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) {
+ MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
+ (ev->channel << 8) + ev->id)) {
dfailprintk((MYIOC_s_ERR_FMT
"%s: exit at line=%d\n", ioc->name,
__FUNCTION__, __LINE__));
break;
}
- ssleep(2);
__mptsas_discovery_work(ioc);
phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
@@ -2219,7 +2616,8 @@ mptsas_hotplug_work(struct work_struct *work)
}
starget = mptsas_get_starget(phy_info);
- if (starget) {
+ if (starget && (!ev->hidden_raid_component)){
+
vtarget = starget->hostdata;
if (!vtarget) {
@@ -2232,9 +2630,15 @@ mptsas_hotplug_work(struct work_struct *work)
* Handling RAID components
*/
if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
- vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT;
- vtarget->target_id = ev->id;
+ printk(MYIOC_s_INFO_FMT
+ "RAID Exposing: channel=%d, id=%d, "
+ "physdsk %d \n", ioc->name, ev->channel,
+ ev->id, ev->phys_disk_num);
+ vtarget->tflags &=
+ ~MPT_TARGET_FLAGS_RAID_COMPONENT;
+ vtarget->id = ev->id;
mptsas_reprobe_target(starget, 0);
+ phy_info->attached.phys_disk_num = ~0;
}
break;
}
@@ -2243,8 +2647,10 @@ mptsas_hotplug_work(struct work_struct *work)
dfailprintk((MYIOC_s_ERR_FMT
"%s: exit at line=%d\n", ioc->name,
__FUNCTION__, __LINE__));
+ if (ev->channel) printk("%d\n", __LINE__);
break;
}
+
port = mptsas_get_port(phy_info);
if (!port) {
dfailprintk((MYIOC_s_ERR_FMT
@@ -2252,15 +2658,17 @@ mptsas_hotplug_work(struct work_struct *work)
__FUNCTION__, __LINE__));
break;
}
-
memcpy(&phy_info->attached, &sas_device,
sizeof(struct mptsas_devinfo));
- if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET)
+ if (phy_info->attached.device_info &
+ MPI_SAS_DEVICE_INFO_SSP_TARGET)
ds = "ssp";
- if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET)
+ if (phy_info->attached.device_info &
+ MPI_SAS_DEVICE_INFO_STP_TARGET)
ds = "stp";
- if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
+ if (phy_info->attached.device_info &
+ MPI_SAS_DEVICE_INFO_SATA_DEVICE)
ds = "sata";
printk(MYIOC_s_INFO_FMT
@@ -2301,19 +2709,21 @@ mptsas_hotplug_work(struct work_struct *work)
break;
case MPTSAS_DEL_RAID:
sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
- ev->id, 0);
+ ev->id, 0);
if (!sdev)
break;
printk(MYIOC_s_INFO_FMT
"removing raid volume, channel %d, id %d\n",
ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
vdevice = sdev->hostdata;
- vdevice->vtarget->deleted = 1;
- mptsas_target_reset(ioc, vdevice->vtarget);
scsi_remove_device(sdev);
scsi_device_put(sdev);
mpt_findImVolumes(ioc);
break;
+ case MPTSAS_ADD_INACTIVE_VOLUME:
+ mptsas_adding_inactive_raid_components(ioc,
+ ev->channel, ev->id);
+ break;
case MPTSAS_IGNORE_EVENT:
default:
break;
@@ -2321,7 +2731,6 @@ mptsas_hotplug_work(struct work_struct *work)
mutex_unlock(&ioc->sas_discovery_mutex);
kfree(ev);
-
}
static void
@@ -2339,8 +2748,12 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc,
return;
switch (sas_event_data->ReasonCode) {
- case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
+
+ mptsas_target_reset_queue(ioc, sas_event_data);
+ break;
+
+ case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev) {
printk(KERN_WARNING "mptsas: lost hotplug event\n");
@@ -2375,15 +2788,20 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc,
mptsas_persist_clear_table);
schedule_work(&ioc->sas_persist_task);
break;
+ /*
+ * TODO, handle other events
+ */
case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
- /* TODO */
+ case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
- /* TODO */
+ case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
+ case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
+ case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
+ case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
default:
break;
}
}
-
static void
mptsas_send_raid_event(MPT_ADAPTER *ioc,
EVENT_DATA_RAID *raid_event_data)
@@ -2404,31 +2822,36 @@ mptsas_send_raid_event(MPT_ADAPTER *ioc,
INIT_WORK(&ev->work, mptsas_hotplug_work);
ev->ioc = ioc;
ev->id = raid_event_data->VolumeID;
+ ev->channel = raid_event_data->VolumeBus;
ev->event_type = MPTSAS_IGNORE_EVENT;
switch (raid_event_data->ReasonCode) {
case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
+ ev->phys_disk_num_valid = 1;
+ ev->phys_disk_num = raid_event_data->PhysDiskNum;
ev->event_type = MPTSAS_ADD_DEVICE;
break;
case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
- ioc->raid_data.isRaid = 1;
ev->phys_disk_num_valid = 1;
ev->phys_disk_num = raid_event_data->PhysDiskNum;
+ ev->hidden_raid_component = 1;
ev->event_type = MPTSAS_DEL_DEVICE;
break;
case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
switch (state) {
case MPI_PD_STATE_ONLINE:
- ioc->raid_data.isRaid = 1;
+ case MPI_PD_STATE_NOT_COMPATIBLE:
ev->phys_disk_num_valid = 1;
ev->phys_disk_num = raid_event_data->PhysDiskNum;
+ ev->hidden_raid_component = 1;
ev->event_type = MPTSAS_ADD_DEVICE;
break;
case MPI_PD_STATE_MISSING:
- case MPI_PD_STATE_NOT_COMPATIBLE:
case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
+ ev->phys_disk_num_valid = 1;
+ ev->phys_disk_num = raid_event_data->PhysDiskNum;
ev->event_type = MPTSAS_DEL_DEVICE;
break;
default:
@@ -2485,6 +2908,35 @@ mptsas_send_discovery_event(MPT_ADAPTER *ioc,
schedule_work(&ev->work);
};
+/*
+ * mptsas_send_ir2_event - handle exposing hidden disk when
+ * an inactive raid volume is added
+ *
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @ir2_data
+ *
+ */
+static void
+mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
+{
+ struct mptsas_hotplug_event *ev;
+
+ if (ir2_data->ReasonCode !=
+ MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
+ return;
+
+ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+ if (!ev)
+ return;
+
+ INIT_WORK(&ev->work, mptsas_hotplug_work);
+ ev->ioc = ioc;
+ ev->id = ir2_data->TargetID;
+ ev->channel = ir2_data->Bus;
+ ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
+
+ schedule_work(&ev->work);
+};
static int
mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
@@ -2524,6 +2976,10 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
mptsas_send_discovery_event(ioc,
(EVENT_DATA_SAS_DISCOVERY *)reply->Data);
break;
+ case MPI_EVENT_IR2:
+ mptsas_send_ir2_event(ioc,
+ (PTR_MPI_EVENT_DATA_IR2)reply->Data);
+ break;
default:
rc = mptscsih_event_process(ioc, reply);
break;
@@ -2611,12 +3067,11 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* set 16 byte cdb's */
sh->max_cmd_len = 16;
- sh->max_id = ioc->pfacts->MaxDevices + 1;
+ sh->max_id = ioc->pfacts[0].PortSCSIID;
+ sh->max_lun = max_lun;
sh->transportt = mptsas_transport_template;
- sh->max_lun = MPT_LAST_LUN + 1;
- sh->max_channel = 0;
sh->this_id = ioc->pfacts[0].PortSCSIID;
/* Required entry.
@@ -2659,8 +3114,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
sh->sg_tablesize = numSGE;
}
- spin_unlock_irqrestore(&ioc->FreeQlock, flags);
-
hd = (MPT_SCSI_HOST *) sh->hostdata;
hd->ioc = ioc;
@@ -2676,19 +3129,6 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
ioc->name, hd->ScsiLookup));
- /* Allocate memory for the device structures.
- * A non-Null pointer at an offset
- * indicates a device exists.
- * max_id = 1 + maximum id (hosts.h)
- */
- hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
- if (!hd->Targets) {
- error = -ENOMEM;
- goto out_mptsas_probe;
- }
-
- dprintk((KERN_INFO " vtarget @ %p\n", hd->Targets));
-
/* Clear the TM flags
*/
hd->tmPending = 0;
@@ -2713,15 +3153,17 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->sas_data.ptClear = mpt_pt_clear;
+ init_waitqueue_head(&hd->scandv_waitq);
+ hd->scandv_wait_done = 0;
+ hd->last_queue_full = 0;
+ INIT_LIST_HEAD(&hd->target_reset_list);
+ spin_unlock_irqrestore(&ioc->FreeQlock, flags);
+
if (ioc->sas_data.ptClear==1) {
mptbase_sas_persist_operation(
ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
}
- init_waitqueue_head(&hd->scandv_waitq);
- hd->scandv_wait_done = 0;
- hd->last_queue_full = 0;
-
error = scsi_add_host(sh, &ioc->pcidev->dev);
if (error) {
dprintk((KERN_ERR MYNAM
@@ -2745,7 +3187,7 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
struct mptsas_portinfo *p, *n;
int i;
- ioc->sas_discovery_ignore_events=1;
+ ioc->sas_discovery_ignore_events = 1;
sas_remove_host(ioc->sh);
mutex_lock(&ioc->sas_topology_mutex);
@@ -2800,7 +3242,7 @@ mptsas_init(void)
return -ENODEV;
mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
- mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
+ mptsasTaskCtx = mpt_register(mptsas_taskmgmt_complete, MPTSAS_DRIVER);
mptsasInternalCtx =
mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
mptsasMgmtCtx = mpt_register(mptsas_mgmt_done, MPTSAS_DRIVER);
@@ -2810,7 +3252,7 @@ mptsas_init(void)
": Registered for IOC event notifications\n"));
}
- if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
+ if (mpt_reset_register(mptsasDoneCtx, mptsas_ioc_reset) == 0) {
dprintk((KERN_INFO MYNAM
": Registered for IOC reset notifications\n"));
}
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index f0cca3ea93b2..c417ae0b5fe6 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -4,7 +4,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -79,43 +79,6 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(my_VERSION);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-typedef struct _BIG_SENSE_BUF {
- u8 data[MPT_SENSE_BUFFER_ALLOC];
-} BIG_SENSE_BUF;
-
-#define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
-#define MPT_SCANDV_DID_RESET (0x00000001)
-#define MPT_SCANDV_SENSE (0x00000002)
-#define MPT_SCANDV_SOME_ERROR (0x00000004)
-#define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
-#define MPT_SCANDV_ISSUE_SENSE (0x00000010)
-#define MPT_SCANDV_FALLBACK (0x00000020)
-
-#define MPT_SCANDV_MAX_RETRIES (10)
-
-#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
-#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
-#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
-#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
-#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
-#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
-#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
-
-typedef struct _internal_cmd {
- char *data; /* data pointer */
- dma_addr_t data_dma; /* data dma address */
- int size; /* transfer size */
- u8 cmd; /* SCSI Op Code */
- u8 bus; /* bus number */
- u8 id; /* SCSI ID (virtual) */
- u8 lun;
- u8 flags; /* Bit Field - See above */
- u8 physDiskNum; /* Phys disk number, -1 else */
- u8 rsvd2;
- u8 rsvd;
-} INTERNAL_CMD;
-
/*
* Other private/forward protos...
*/
@@ -131,14 +94,11 @@ static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
-static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
+static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
-static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
-static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
-static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
@@ -517,16 +477,100 @@ mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
SEPMsg = (SEPRequest_t *)mf;
SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
- SEPMsg->Bus = vtarget->bus_id;
- SEPMsg->TargetID = vtarget->target_id;
+ SEPMsg->Bus = vtarget->channel;
+ SEPMsg->TargetID = vtarget->id;
SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
SEPMsg->SlotStatus = SlotStatus;
devtverboseprintk((MYIOC_s_WARN_FMT
- "Sending SEP cmd=%x id=%d bus=%d\n",
- ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus));
+ "Sending SEP cmd=%x channel=%d id=%d\n",
+ ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
}
+#ifdef MPT_DEBUG_REPLY
+/**
+ * mptscsih_iocstatus_info_scsiio - IOCSTATUS information for SCSIIO
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @ioc_status: U32 IOCStatus word from IOC
+ * @scsi_status: U8 sam status from target
+ * @scsi_state: U8 scsi state
+ * @sc: original scsi cmnd pointer
+ * @mf: Pointer to MPT request frame
+ *
+ * Refer to lsi/mpi.h.
+ **/
+static void
+mptscsih_iocstatus_info_scsiio(MPT_ADAPTER *ioc, u32 ioc_status,
+ u8 scsi_status, u8 scsi_state, struct scsi_cmnd *sc)
+{
+ char extend_desc[EVENT_DESCR_STR_SZ];
+ char *desc = NULL;
+
+ switch (ioc_status) {
+
+ case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
+ desc = "SCSI Invalid Bus";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
+ desc = "SCSI Invalid TargetID";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
+ /*
+ * Inquiry is issued for device scanning
+ */
+ if (sc->cmnd[0] != 0x12)
+ desc = "SCSI Device Not There";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
+ desc = "SCSI Data Overrun";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
+ desc = "SCSI I/O Data Error";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
+ desc = "SCSI Protocol Error";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
+ desc = "SCSI Task Terminated";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
+ desc = "SCSI Residual Mismatch";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
+ desc = "SCSI Task Management Failed";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
+ desc = "SCSI IOC Terminated";
+ break;
+
+ case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
+ desc = "SCSI Ext Terminated";
+ break;
+ }
+
+ if (!desc)
+ return;
+
+ snprintf(extend_desc, EVENT_DESCR_STR_SZ,
+ "[%d:%d:%d:%d] cmd=%02Xh, sam_status=%02Xh state=%02Xh",
+ sc->device->host->host_no,
+ sc->device->channel, sc->device->id, sc->device->lun,
+ sc->cmnd[0], scsi_status, scsi_state);
+
+ printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
+ ioc->name, ioc_status, desc, extend_desc);
+}
+#endif
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_io_done - Main SCSI IO callback routine registered to
@@ -613,12 +657,14 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
u32 xfer_cnt;
u16 status;
u8 scsi_state, scsi_status;
+ u32 log_info;
status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
scsi_state = pScsiReply->SCSIState;
scsi_status = pScsiReply->SCSIStatus;
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
sc->resid = sc->request_bufflen - xfer_cnt;
+ log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
/*
* if we get a data underrun indication, yet no data was
@@ -633,13 +679,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
status = MPI_IOCSTATUS_SUCCESS;
}
- dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
- "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
- "resid=%d bufflen=%d xfer_cnt=%d\n",
- ioc->id, sc->device->id, sc->device->lun,
- status, scsi_state, scsi_status, sc->resid,
- sc->request_bufflen, xfer_cnt));
-
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
@@ -648,9 +687,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
*/
if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
pScsiReply->ResponseInfo) {
- printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
+ printk(KERN_NOTICE "[%d:%d:%d:%d] "
"FCP_ResponseInfo=%08xh\n",
- ioc->id, sc->device->id, sc->device->lun,
+ sc->device->host->host_no, sc->device->channel,
+ sc->device->id, sc->device->lun,
le32_to_cpu(pScsiReply->ResponseInfo));
}
@@ -695,9 +735,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
if ( ioc->bus_type == SAS ) {
u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
- u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
- log_info &=SAS_LOGINFO_MASK;
- if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
+ if ((log_info & SAS_LOGINFO_MASK)
+ == SAS_LOGINFO_NEXUS_LOSS) {
sc->result = (DID_BUS_BUSY << 16);
break;
}
@@ -735,7 +774,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
else /* Sufficient data transfer occurred */
sc->result = (DID_OK << 16) | scsi_status;
dreplyprintk((KERN_NOTICE
- "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
+ "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
+ sc->result, sc->device->channel, sc->device->id));
break;
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
@@ -848,7 +888,28 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
} /* switch(status) */
- dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
+#ifdef MPT_DEBUG_REPLY
+ if (sc->result) {
+
+ mptscsih_iocstatus_info_scsiio(ioc, status,
+ scsi_status, scsi_state, sc);
+
+ dreplyprintk(("%s: [%d:%d:%d:%d] cmd=0x%02x "
+ "result=0x%08x\n\tiocstatus=0x%04X "
+ "scsi_state=0x%02X scsi_status=0x%02X "
+ "loginfo=0x%08X\n", __FUNCTION__,
+ sc->device->host->host_no, sc->device->channel, sc->device->id,
+ sc->device->lun, sc->cmnd[0], sc->result, status,
+ scsi_state, scsi_status, log_info));
+
+ dreplyprintk(("%s: [%d:%d:%d:%d] resid=%d "
+ "bufflen=%d xfer_cnt=%d\n", __FUNCTION__,
+ sc->device->host->host_no, sc->device->channel, sc->device->id,
+ sc->device->lun, sc->resid, sc->request_bufflen,
+ xfer_cnt));
+ }
+#endif
+
} /* end of address reply case */
/* Unmap the DMA buffers, if any. */
@@ -955,9 +1016,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
int ii;
int max = hd->ioc->req_depth;
struct scsi_cmnd *sc;
+ struct scsi_lun lun;
- dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
- vdevice->vtarget->target_id, vdevice->lun, max));
+ dsprintk((KERN_INFO MYNAM ": search_running channel %d id %d lun %d max %d\n",
+ vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max));
for (ii=0; ii < max; ii++) {
if ((sc = hd->ScsiLookup[ii]) != NULL) {
@@ -965,10 +1027,14 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
if (mf == NULL)
continue;
- dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
- hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
- if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
+ int_to_scsilun(vdevice->lun, &lun);
+ if ((mf->Bus != vdevice->vtarget->channel) ||
+ (mf->TargetID != vdevice->vtarget->id) ||
+ memcmp(lun.scsi_lun, mf->LUN, 8))
continue;
+ dsprintk(( "search_running: found (sc=%p, mf = %p) "
+ "channel %d id %d, lun %d \n", hd->ScsiLookup[ii],
+ mf, mf->Bus, mf->TargetID, vdevice->lun));
/* Cleanup
*/
@@ -1065,12 +1131,6 @@ mptscsih_remove(struct pci_dev *pdev)
hd->ScsiLookup = NULL;
}
- /*
- * Free pointer array.
- */
- kfree(hd->Targets);
- hd->Targets = NULL;
-
dprintk((MYIOC_s_INFO_FMT
"Free'd ScsiLookup (%d) memory\n",
hd->ioc->name, sz1));
@@ -1317,14 +1377,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return SCSI_MLQUEUE_HOST_BUSY;
}
- if ((hd->ioc->bus_type == SPI) &&
- vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT &&
- mptscsih_raid_id_to_num(hd, SCpnt->device->id) < 0) {
- SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);
- return 0;
- }
-
/*
* Put together a MPT SCSI request...
*/
@@ -1368,8 +1420,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Use the above information to set up the message frame
*/
- pScsiReq->TargetID = (u8) vdev->vtarget->target_id;
- pScsiReq->Bus = vdev->vtarget->bus_id;
+ pScsiReq->TargetID = (u8) vdev->vtarget->id;
+ pScsiReq->Bus = vdev->vtarget->channel;
pScsiReq->ChainOffset = 0;
if (vdev->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
@@ -1379,14 +1431,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
pScsiReq->Reserved = 0;
pScsiReq->MsgFlags = mpt_msg_flags();
- pScsiReq->LUN[0] = 0;
- pScsiReq->LUN[1] = lun;
- pScsiReq->LUN[2] = 0;
- pScsiReq->LUN[3] = 0;
- pScsiReq->LUN[4] = 0;
- pScsiReq->LUN[5] = 0;
- pScsiReq->LUN[6] = 0;
- pScsiReq->LUN[7] = 0;
+ int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
pScsiReq->Control = cpu_to_le32(scsictl);
/*
@@ -1491,14 +1536,14 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mptscsih_TMHandler - Generic handler for SCSI Task Management.
* Fall through to mpt_HardResetHandler if: not operational, too many
* failed TM requests or handshake failure.
*
* @ioc: Pointer to MPT_ADAPTER structure
* @type: Task Management type
- * @target: Logical Target ID for reset (if appropriate)
+ * @id: Logical Target ID for reset (if appropriate)
* @lun: Logical Unit for reset (if appropriate)
* @ctx2abort: Context for the task to be aborted (if appropriate)
*
@@ -1507,28 +1552,17 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
* Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
* will be active.
*
- * Returns 0 for SUCCESS or -1 if FAILED.
- */
+ * Returns 0 for SUCCESS, or FAILED.
+ **/
int
-mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
+mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
{
MPT_ADAPTER *ioc;
int rc = -1;
- int doTask = 1;
u32 ioc_raw_state;
unsigned long flags;
- /* If FW is being reloaded currently, return success to
- * the calling function.
- */
- if (hd == NULL)
- return 0;
-
ioc = hd->ioc;
- if (ioc == NULL) {
- printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
- return FAILED;
- }
dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
// SJR - CHECKME - Can we avoid this here?
@@ -1541,8 +1575,10 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
spin_unlock_irqrestore(&ioc->diagLock, flags);
/* Wait a fixed amount of time for the TM pending flag to be cleared.
- * If we time out and not bus reset, then we return a FAILED status to the caller.
- * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
+ * If we time out and not bus reset, then we return a FAILED status
+ * to the caller.
+ * The call to mptscsih_tm_pending_wait() will set the pending flag
+ * if we are
* successful. Otherwise, reload the FW.
*/
if (mptscsih_tm_pending_wait(hd) == FAILED) {
@@ -1552,18 +1588,16 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
hd->ioc->name, hd->tmPending));
return FAILED;
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
- dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
- "Timed out waiting for last TM (%d) to complete! \n",
- hd->ioc->name, hd->tmPending));
+ dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target "
+ "reset: Timed out waiting for last TM (%d) "
+ "to complete! \n", hd->ioc->name,
+ hd->tmPending));
return FAILED;
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
"Timed out waiting for last TM (%d) to complete! \n",
hd->ioc->name, hd->tmPending));
- if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
- return FAILED;
-
- doTask = 0;
+ return FAILED;
}
} else {
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
@@ -1571,47 +1605,40 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
}
- /* Is operational?
- */
ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
-#ifdef MPT_DEBUG_RESET
if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
printk(MYIOC_s_WARN_FMT
- "TM Handler: IOC Not operational(0x%x)!\n",
- hd->ioc->name, ioc_raw_state);
- }
-#endif
-
- if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
- && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
-
- /* Isse the Task Mgmt request.
- */
- if (hd->hard_resets < -1)
- hd->hard_resets++;
- rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
- if (rc) {
- printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
- } else {
- dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
- }
+ "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
+ ioc->name, type, ioc_raw_state);
+ printk(KERN_WARNING " Issuing HardReset!!\n");
+ if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
+ printk((KERN_WARNING "TMHandler: HardReset "
+ "FAILED!!\n"));
+ return FAILED;
}
- /* Only fall through to the HRH if this is a bus reset
- */
- if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
- ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
- dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
- hd->ioc->name));
- rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
+ if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
+ printk(MYIOC_s_WARN_FMT
+ "TM Handler for type=%x: ioc_state: "
+ "DOORBELL_ACTIVE (0x%x)!\n",
+ ioc->name, type, ioc_raw_state);
+ return FAILED;
}
- /*
- * Check IOCStatus from TM reply message
+ /* Isse the Task Mgmt request.
*/
- if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
- rc = FAILED;
+ if (hd->hard_resets < -1)
+ hd->hard_resets++;
+
+ rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
+ ctx2abort, timeout);
+ if (rc)
+ printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
+ hd->ioc->name);
+ else
+ dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n",
+ hd->ioc->name));
dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
@@ -1620,11 +1647,11 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
+/**
* mptscsih_IssueTaskMgmt - Generic send Task Management function.
* @hd: Pointer to MPT_SCSI_HOST structure
* @type: Task Management type
- * @target: Logical Target ID for reset (if appropriate)
+ * @id: Logical Target ID for reset (if appropriate)
* @lun: Logical Unit for reset (if appropriate)
* @ctx2abort: Context for the task to be aborted (if appropriate)
*
@@ -1633,11 +1660,11 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
*
* Not all fields are meaningfull for all task types.
*
- * Returns 0 for SUCCESS, -999 for "no msg frames",
- * else other non-zero value returned.
- */
+ * Returns 0 for SUCCESS, or FAILED.
+ *
+ **/
static int
-mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
+mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
{
MPT_FRAME_HDR *mf;
SCSITaskMgmt_t *pScsiTm;
@@ -1657,7 +1684,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
/* Format the Request
*/
pScsiTm = (SCSITaskMgmt_t *) mf;
- pScsiTm->TargetID = target;
+ pScsiTm->TargetID = id;
pScsiTm->Bus = channel;
pScsiTm->ChainOffset = 0;
pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
@@ -1668,42 +1695,59 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
- for (ii= 0; ii < 8; ii++) {
- pScsiTm->LUN[ii] = 0;
- }
- pScsiTm->LUN[1] = lun;
+ int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
for (ii=0; ii < 7; ii++)
pScsiTm->Reserved2[ii] = 0;
pScsiTm->TaskMsgContext = ctx2abort;
- dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
- hd->ioc->name, ctx2abort, type));
+ dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
+ "type=%d\n", hd->ioc->name, ctx2abort, type));
DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
- sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
- CAN_SLEEP)) != 0) {
- dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
- " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
- hd->ioc, mf));
- mpt_free_msg_frame(hd->ioc, mf);
- return retval;
+ sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
+ dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!"
+ " (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd,
+ hd->ioc, mf, retval));
+ goto fail_out;
}
if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
- dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
+ dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!"
" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
hd->ioc, mf));
- mpt_free_msg_frame(hd->ioc, mf);
dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
hd->ioc->name));
retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
+ dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n",
+ hd->ioc->name, retval));
+ goto fail_out;
}
+ /*
+ * Handle success case, see if theres a non-zero ioc_status.
+ */
+ if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
+ hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
+ hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
+ retval = 0;
+ else
+ retval = FAILED;
+
return retval;
+
+ fail_out:
+
+ /*
+ * Free task managment mf, and corresponding tm flags
+ */
+ mpt_free_msg_frame(hd->ioc, mf);
+ hd->tmPending = 0;
+ hd->tmState = TM_STATE_NONE;
+ return FAILED;
}
static int
@@ -1728,7 +1772,7 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
* (linux scsi_host_template.eh_abort_handler routine)
*
* Returns SUCCESS or FAILED.
- */
+ **/
int
mptscsih_abort(struct scsi_cmnd * SCpnt)
{
@@ -1764,9 +1808,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
return SUCCESS;
}
- if (hd->resetPending) {
+ if (hd->resetPending)
return FAILED;
- }
if (hd->timeouts < -1)
hd->timeouts++;
@@ -1789,13 +1832,12 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
vdev = SCpnt->device->hostdata;
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
- vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
+ vdev->vtarget->channel, vdev->vtarget->id, vdev->lun,
ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
- SCpnt->serial_number == sn) {
+ SCpnt->serial_number == sn)
retval = FAILED;
- }
printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
hd->ioc->name,
@@ -1803,12 +1845,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
if (retval == 0)
return SUCCESS;
-
- if(retval != FAILED ) {
- hd->tmPending = 0;
- hd->tmState = TM_STATE_NONE;
- }
- return FAILED;
+ else
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1819,7 +1857,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
* (linux scsi_host_template.eh_dev_reset_handler routine)
*
* Returns SUCCESS or FAILED.
- */
+ **/
int
mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
{
@@ -1845,7 +1883,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
vdev = SCpnt->device->hostdata;
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
- vdev->vtarget->bus_id, vdev->vtarget->target_id,
+ vdev->vtarget->channel, vdev->vtarget->id,
0, 0, mptscsih_get_tm_timeout(hd->ioc));
printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
@@ -1854,14 +1892,11 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
if (retval == 0)
return SUCCESS;
-
- if(retval != FAILED ) {
- hd->tmPending = 0;
- hd->tmState = TM_STATE_NONE;
- }
- return FAILED;
+ else
+ return FAILED;
}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
@@ -1870,7 +1905,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
* (linux scsi_host_template.eh_bus_reset_handler routine)
*
* Returns SUCCESS or FAILED.
- */
+ **/
int
mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
{
@@ -1896,7 +1931,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
vdev = SCpnt->device->hostdata;
retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
- vdev->vtarget->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
+ vdev->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
hd->ioc->name,
@@ -1904,12 +1939,8 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
if (retval == 0)
return SUCCESS;
-
- if(retval != FAILED ) {
- hd->tmPending = 0;
- hd->tmState = TM_STATE_NONE;
- }
- return FAILED;
+ else
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1992,7 +2023,6 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
/**
* mptscsih_tm_wait_for_completion - wait for completion of TM task
* @hd: Pointer to MPT host structure.
- * @timeout: timeout in seconds
*
* Returns {SUCCESS,FAILED}.
*/
@@ -2066,7 +2096,7 @@ mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
* load/init time via the mpt_register() API call.
*
* Returns 1 indicating alloc'd request frame ptr should be freed.
- */
+ **/
int
mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
{
@@ -2076,78 +2106,85 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
unsigned long flags;
u16 iocstatus;
u8 tmType;
+ u32 termination_count;
dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
- ioc->name, mf, mr));
- if (ioc->sh) {
- /* Depending on the thread, a timer is activated for
- * the TM request. Delete this timer on completion of TM.
- * Decrement count of outstanding TM requests.
- */
- hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
- } else {
- dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
- ioc->name));
+ ioc->name, mf, mr));
+ if (!ioc->sh) {
+ dtmprintk((MYIOC_s_WARN_FMT
+ "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
return 1;
}
if (mr == NULL) {
- dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
- ioc->name, mf));
+ dtmprintk((MYIOC_s_WARN_FMT
+ "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
return 1;
- } else {
- pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
- pScsiTmReq = (SCSITaskMgmt_t*)mf;
-
- /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
- tmType = pScsiTmReq->TaskType;
+ }
- if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
- pScsiTmReply->ResponseCode)
- mptscsih_taskmgmt_response_code(ioc,
- pScsiTmReply->ResponseCode);
+ hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
+ pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
+ pScsiTmReq = (SCSITaskMgmt_t*)mf;
+ tmType = pScsiTmReq->TaskType;
+ iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+ termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
+
+ if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
+ pScsiTmReply->ResponseCode)
+ mptscsih_taskmgmt_response_code(ioc,
+ pScsiTmReply->ResponseCode);
+ DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
+
+#if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM)
+ printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
+ "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
+ "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
+ pScsiTmReply->TargetID, pScsiTmReq->TaskType,
+ le16_to_cpu(pScsiTmReply->IOCStatus),
+ le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
+ le32_to_cpu(pScsiTmReply->TerminationCount));
+#endif
+ if (!iocstatus) {
+ dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
+ hd->abortSCpnt = NULL;
+ goto out;
+ }
- dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
- ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
- DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
+ /* Error? (anything non-zero?) */
- iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
- hd->tm_iocstatus = iocstatus;
- dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
- ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
- /* Error? (anything non-zero?) */
- if (iocstatus) {
+ /* clear flags and continue.
+ */
+ switch (tmType) {
- /* clear flags and continue.
- */
- if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
- hd->abortSCpnt = NULL;
+ case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
+ if (termination_count == 1)
+ iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
+ hd->abortSCpnt = NULL;
+ break;
- /* If an internal command is present
- * or the TM failed - reload the FW.
- * FC FW may respond FAILED to an ABORT
- */
- if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
- if ((hd->cmdPtr) ||
- (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
- if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
- printk((KERN_WARNING
- " Firmware Reload FAILED!!\n"));
- }
- }
- }
- } else {
- dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
+ case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
- hd->abortSCpnt = NULL;
+ /* If an internal command is present
+ * or the TM failed - reload the FW.
+ * FC FW may respond FAILED to an ABORT
+ */
+ if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
+ hd->cmdPtr)
+ if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
+ printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
+ break;
- }
+ case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
+ default:
+ break;
}
+ out:
spin_lock_irqsave(&ioc->FreeQlock, flags);
hd->tmPending = 0;
- spin_unlock_irqrestore(&ioc->FreeQlock, flags);
hd->tmState = TM_STATE_NONE;
+ hd->tm_iocstatus = iocstatus;
+ spin_unlock_irqrestore(&ioc->FreeQlock, flags);
return 1;
}
@@ -2191,7 +2228,7 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
dprintk((KERN_NOTICE
": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
- sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
+ sdev->id, sdev->lun, sdev->channel, (int)cylinders, heads, sectors));
return 0;
}
@@ -2200,115 +2237,78 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
*
*/
int
-mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
+mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
{
+ struct inactive_raid_component_info *component_info;
int i;
+ int rc = 0;
- if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
- return 0;
+ if (!ioc->raid_data.pIocPg3)
+ goto out;
for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
- if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
- return 1;
- }
- return 0;
-}
-EXPORT_SYMBOL(mptscsih_is_phys_disk);
-
-int
-mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid)
-{
- int i;
-
- if (!hd->ioc->raid_data.isRaid || !hd->ioc->raid_data.pIocPg3)
- return -ENXIO;
-
- for (i = 0; i < hd->ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
- if (physdiskid ==
- hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
- return hd->ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
+ if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
+ (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
+ rc = 1;
+ goto out;
+ }
}
- return -ENXIO;
-}
-EXPORT_SYMBOL(mptscsih_raid_id_to_num);
+ /*
+ * Check inactive list for matching phys disks
+ */
+ if (list_empty(&ioc->raid_data.inactive_list))
+ goto out;
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * OS entry point to allow host driver to alloc memory
- * for each scsi target. Called once per device the bus scan.
- * Return non-zero if allocation fails.
- */
-int
-mptscsih_target_alloc(struct scsi_target *starget)
-{
- VirtTarget *vtarget;
+ down(&ioc->raid_data.inactive_list_mutex);
+ list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
+ list) {
+ if ((component_info->d.PhysDiskID == id) &&
+ (component_info->d.PhysDiskBus == channel))
+ rc = 1;
+ }
+ up(&ioc->raid_data.inactive_list_mutex);
- vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
- if (!vtarget)
- return -ENOMEM;
- starget->hostdata = vtarget;
- vtarget->starget = starget;
- return 0;
+ out:
+ return rc;
}
+EXPORT_SYMBOL(mptscsih_is_phys_disk);
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * OS entry point to allow host driver to alloc memory
- * for each scsi device. Called once per device the bus scan.
- * Return non-zero if allocation fails.
- */
-int
-mptscsih_slave_alloc(struct scsi_device *sdev)
+u8
+mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
{
- struct Scsi_Host *host = sdev->host;
- MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
- VirtTarget *vtarget;
- VirtDevice *vdev;
- struct scsi_target *starget;
+ struct inactive_raid_component_info *component_info;
+ int i;
+ int rc = -ENXIO;
- vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
- if (!vdev) {
- printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
- hd->ioc->name, sizeof(VirtDevice));
- return -ENOMEM;
+ if (!ioc->raid_data.pIocPg3)
+ goto out;
+ for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+ if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
+ (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
+ rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
+ goto out;
+ }
}
- vdev->lun = sdev->lun;
- sdev->hostdata = vdev;
-
- starget = scsi_target(sdev);
- vtarget = starget->hostdata;
+ /*
+ * Check inactive list for matching phys disks
+ */
+ if (list_empty(&ioc->raid_data.inactive_list))
+ goto out;
- vdev->vtarget = vtarget;
-
- if (vtarget->num_luns == 0) {
- hd->Targets[sdev->id] = vtarget;
- vtarget->ioc_id = hd->ioc->id;
- vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
- vtarget->target_id = sdev->id;
- vtarget->bus_id = sdev->channel;
- if (hd->ioc->bus_type == SPI && sdev->channel == 0 &&
- hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
- vtarget->raidVolume = 1;
- ddvtprintk((KERN_INFO
- "RAID Volume @ id %d\n", sdev->id));
- }
+ down(&ioc->raid_data.inactive_list_mutex);
+ list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
+ list) {
+ if ((component_info->d.PhysDiskID == id) &&
+ (component_info->d.PhysDiskBus == channel))
+ rc = component_info->d.PhysDiskNum;
}
- vtarget->num_luns++;
- return 0;
-}
+ up(&ioc->raid_data.inactive_list_mutex);
-/*
- * OS entry point to allow for host driver to free allocated memory
- * Called if no device present or device being unloaded
- */
-void
-mptscsih_target_destroy(struct scsi_target *starget)
-{
- if (starget->hostdata)
- kfree(starget->hostdata);
- starget->hostdata = NULL;
+ out:
+ return rc;
}
+EXPORT_SYMBOL(mptscsih_raid_id_to_num);
/*
* OS entry point to allow for host driver to free allocated memory
@@ -2328,11 +2328,7 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
vdevice = sdev->hostdata;
mptscsih_search_running_cmds(hd, vdevice);
- vtarget->luns[0] &= ~(1 << vdevice->lun);
vtarget->num_luns--;
- if (vtarget->num_luns == 0) {
- hd->Targets[sdev->id] = NULL;
- }
mptscsih_synchronize_cache(hd, vdevice);
kfree(vdevice);
sdev->hostdata = NULL;
@@ -2394,15 +2390,14 @@ mptscsih_slave_configure(struct scsi_device *sdev)
VirtDevice *vdevice;
struct scsi_target *starget;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
- int indexed_lun, lun_index;
starget = scsi_target(sdev);
vtarget = starget->hostdata;
vdevice = sdev->hostdata;
dsprintk((MYIOC_s_INFO_FMT
- "device @ %p, id=%d, LUN=%d, channel=%d\n",
- hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
+ "device @ %p, channel=%d, id=%d, lun=%d\n",
+ hd->ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
if (hd->ioc->bus_type == SPI)
dsprintk((MYIOC_s_INFO_FMT
"sdtr %d wdtr %d ppr %d inq length=%d\n",
@@ -2415,11 +2410,7 @@ mptscsih_slave_configure(struct scsi_device *sdev)
goto slave_configure_exit;
}
- vdevice->configured_lun=1;
- lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
- indexed_lun = (vdevice->lun % 32);
- vtarget->luns[lun_index] |= (1 << indexed_lun);
- mptscsih_initTarget(hd, vtarget, sdev);
+ vdevice->configured_lun = 1;
mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
dsprintk((MYIOC_s_INFO_FMT
@@ -2683,285 +2674,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
- * mptscsih_initTarget - Target, LUN alloc/free functionality.
- * @hd: Pointer to MPT_SCSI_HOST structure
- * @vtarget: per target private data
- * @sdev: SCSI device
- *
- * NOTE: It's only SAFE to call this routine if data points to
- * sane & valid STANDARD INQUIRY data!
- *
- * Allocate and initialize memory for this target.
- * Save inquiry data.
- *
- */
-static void
-mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
- struct scsi_device *sdev)
-{
- dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
- hd->ioc->name, vtarget->bus_id, vtarget->target_id,
- sdev->lun, hd));
-
- /* Is LUN supported? If so, upper 2 bits will be 0
- * in first byte of inquiry data.
- */
- if (sdev->inq_periph_qual != 0)
- return;
-
- if (vtarget == NULL)
- return;
-
- vtarget->type = sdev->type;
-
- if (hd->ioc->bus_type != SPI)
- return;
-
- if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
- /* Treat all Processors as SAF-TE if
- * command line option is set */
- vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
- mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
- }else if ((sdev->type == TYPE_PROCESSOR) &&
- !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
- if (sdev->inquiry_len > 49 ) {
- if (sdev->inquiry[44] == 'S' &&
- sdev->inquiry[45] == 'A' &&
- sdev->inquiry[46] == 'F' &&
- sdev->inquiry[47] == '-' &&
- sdev->inquiry[48] == 'T' &&
- sdev->inquiry[49] == 'E' ) {
- vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
- mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
- }
- }
- }
- mptscsih_setTargetNegoParms(hd, vtarget, sdev);
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * Update the target negotiation parameters based on the
- * the Inquiry data, adapter capabilities, and NVRAM settings.
- *
- */
-static void
-mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
- struct scsi_device *sdev)
-{
- SpiCfgData *pspi_data = &hd->ioc->spi_data;
- int id = (int) target->target_id;
- int nvram;
- u8 width = MPT_NARROW;
- u8 factor = MPT_ASYNC;
- u8 offset = 0;
- u8 nfactor;
- u8 noQas = 1;
-
- target->negoFlags = pspi_data->noQas;
-
- /* noQas == 0 => device supports QAS. */
-
- if (sdev->scsi_level < SCSI_2) {
- width = 0;
- factor = MPT_ULTRA2;
- offset = pspi_data->maxSyncOffset;
- target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
- } else {
- if (scsi_device_wide(sdev)) {
- width = 1;
- }
-
- if (scsi_device_sync(sdev)) {
- factor = pspi_data->minSyncFactor;
- if (!scsi_device_dt(sdev))
- factor = MPT_ULTRA2;
- else {
- if (!scsi_device_ius(sdev) &&
- !scsi_device_qas(sdev))
- factor = MPT_ULTRA160;
- else {
- factor = MPT_ULTRA320;
- if (scsi_device_qas(sdev)) {
- ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id));
- noQas = 0;
- }
- if (sdev->type == TYPE_TAPE &&
- scsi_device_ius(sdev))
- target->negoFlags |= MPT_TAPE_NEGO_IDP;
- }
- }
- offset = pspi_data->maxSyncOffset;
-
- /* If RAID, never disable QAS
- * else if non RAID, do not disable
- * QAS if bit 1 is set
- * bit 1 QAS support, non-raid only
- * bit 0 IU support
- */
- if (target->raidVolume == 1) {
- noQas = 0;
- }
- } else {
- factor = MPT_ASYNC;
- offset = 0;
- }
- }
-
- if (!sdev->tagged_supported) {
- target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
- }
-
- /* Update tflags based on NVRAM settings. (SCSI only)
- */
- if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
- nvram = pspi_data->nvram[id];
- nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
-
- if (width)
- width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
-
- if (offset > 0) {
- /* Ensure factor is set to the
- * maximum of: adapter, nvram, inquiry
- */
- if (nfactor) {
- if (nfactor < pspi_data->minSyncFactor )
- nfactor = pspi_data->minSyncFactor;
-
- factor = max(factor, nfactor);
- if (factor == MPT_ASYNC)
- offset = 0;
- } else {
- offset = 0;
- factor = MPT_ASYNC;
- }
- } else {
- factor = MPT_ASYNC;
- }
- }
-
- /* Make sure data is consistent
- */
- if ((!width) && (factor < MPT_ULTRA2)) {
- factor = MPT_ULTRA2;
- }
-
- /* Save the data to the target structure.
- */
- target->minSyncFactor = factor;
- target->maxOffset = offset;
- target->maxWidth = width;
-
- target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
-
- /* Disable unused features.
- */
- if (!width)
- target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
-
- if (!offset)
- target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
-
- if ( factor > MPT_ULTRA320 )
- noQas = 0;
-
- if (noQas && (pspi_data->noQas == 0)) {
- pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
- target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
-
- /* Disable QAS in a mixed configuration case
- */
-
- ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
- }
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * SCSI Config Page functionality ...
- */
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* mptscsih_writeIOCPage4 - write IOC Page 4
- * @hd: Pointer to a SCSI Host Structure
- * @target_id: write IOC Page4 for this ID & Bus
- *
- * Return: -EAGAIN if unable to obtain a Message Frame
- * or 0 if success.
- *
- * Remark: We do not wait for a return, write pages sequentially.
- */
-static int
-mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
-{
- MPT_ADAPTER *ioc = hd->ioc;
- Config_t *pReq;
- IOCPage4_t *IOCPage4Ptr;
- MPT_FRAME_HDR *mf;
- dma_addr_t dataDma;
- u16 req_idx;
- u32 frameOffset;
- u32 flagsLength;
- int ii;
-
- /* Get a MF for this command.
- */
- if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
- dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
- ioc->name));
- return -EAGAIN;
- }
-
- /* Set the request and the data pointers.
- * Place data at end of MF.
- */
- pReq = (Config_t *)mf;
-
- req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
- frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
-
- /* Complete the request frame (same for all requests).
- */
- pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
- pReq->Reserved = 0;
- pReq->ChainOffset = 0;
- pReq->Function = MPI_FUNCTION_CONFIG;
- pReq->ExtPageLength = 0;
- pReq->ExtPageType = 0;
- pReq->MsgFlags = 0;
- for (ii=0; ii < 8; ii++) {
- pReq->Reserved2[ii] = 0;
- }
-
- IOCPage4Ptr = ioc->spi_data.pIocPg4;
- dataDma = ioc->spi_data.IocPg4_dma;
- ii = IOCPage4Ptr->ActiveSEP++;
- IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
- IOCPage4Ptr->SEP[ii].SEPBus = bus;
- pReq->Header = IOCPage4Ptr->Header;
- pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
-
- /* Add a SGE to the config request.
- */
- flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
- (IOCPage4Ptr->Header.PageLength + ii) * 4;
-
- mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
-
- dinitprintk((MYIOC_s_INFO_FMT
- "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
- ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
-
- mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
-
- return 0;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
* Bus Scan and Domain Validation functionality ...
*/
@@ -3343,7 +3055,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
} else {
pScsiReq->TargetID = io->id;
- pScsiReq->Bus = io->bus;
+ pScsiReq->Bus = io->channel;
pScsiReq->ChainOffset = 0;
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
}
@@ -3356,9 +3068,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
pScsiReq->MsgFlags = mpt_msg_flags();
/* MsgContext set in mpt_get_msg_fram call */
- for (ii=0; ii < 8; ii++)
- pScsiReq->LUN[ii] = 0;
- pScsiReq->LUN[1] = io->lun;
+ int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
if (io->flags & MPT_ICFLAG_TAGGED_CMD)
pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
@@ -3379,7 +3089,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
+ (my_idx * MPT_SENSE_BUFFER_ALLOC));
ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
- hd->ioc->name, cmd, io->bus, io->id, io->lun));
+ hd->ioc->name, cmd, io->channel, io->id, io->lun));
if (dir == MPI_SCSIIO_CONTROL_READ) {
mpt_add_sge((char *) &pScsiReq->SGL,
@@ -3462,9 +3172,9 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
iocmd.data_dma = -1;
iocmd.size = 0;
iocmd.rsvd = iocmd.rsvd2 = 0;
- iocmd.bus = vdevice->vtarget->bus_id;
- iocmd.id = vdevice->vtarget->target_id;
- iocmd.lun = (u8)vdevice->lun;
+ iocmd.channel = vdevice->vtarget->channel;
+ iocmd.id = vdevice->vtarget->id;
+ iocmd.lun = vdevice->lun;
if ((vdevice->vtarget->type == TYPE_DISK) &&
(vdevice->configured_lun))
@@ -3480,9 +3190,6 @@ EXPORT_SYMBOL(mptscsih_resume);
EXPORT_SYMBOL(mptscsih_proc_info);
EXPORT_SYMBOL(mptscsih_info);
EXPORT_SYMBOL(mptscsih_qcmd);
-EXPORT_SYMBOL(mptscsih_target_alloc);
-EXPORT_SYMBOL(mptscsih_slave_alloc);
-EXPORT_SYMBOL(mptscsih_target_destroy);
EXPORT_SYMBOL(mptscsih_slave_destroy);
EXPORT_SYMBOL(mptscsih_slave_configure);
EXPORT_SYMBOL(mptscsih_abort);
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 187c8af0890b..843c01a6aa0e 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -6,7 +6,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -53,6 +53,24 @@
* SCSI Public stuff...
*/
+#define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
+#define MPT_SCANDV_DID_RESET (0x00000001)
+#define MPT_SCANDV_SENSE (0x00000002)
+#define MPT_SCANDV_SOME_ERROR (0x00000004)
+#define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
+#define MPT_SCANDV_ISSUE_SENSE (0x00000010)
+#define MPT_SCANDV_FALLBACK (0x00000020)
+
+#define MPT_SCANDV_MAX_RETRIES (10)
+
+#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
+#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
+#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
+#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
+#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
+#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
+#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
+
#define MPT_SCSI_CMD_PER_DEV_HIGH 64
#define MPT_SCSI_CMD_PER_DEV_LOW 32
@@ -69,9 +87,22 @@
#define MPTSCSIH_SAF_TE 0
#define MPTSCSIH_PT_CLEAR 0
-
#endif
+typedef struct _internal_cmd {
+ char *data; /* data pointer */
+ dma_addr_t data_dma; /* data dma address */
+ int size; /* transfer size */
+ u8 cmd; /* SCSI Op Code */
+ u8 channel; /* bus number */
+ u8 id; /* SCSI ID (virtual) */
+ int lun;
+ u8 flags; /* Bit Field - See above */
+ u8 physDiskNum; /* Phys disk number, -1 else */
+ u8 rsvd2;
+ u8 rsvd;
+} INTERNAL_CMD;
+
extern void mptscsih_remove(struct pci_dev *);
extern void mptscsih_shutdown(struct pci_dev *);
#ifdef CONFIG_PM
@@ -81,9 +112,6 @@ extern int mptscsih_resume(struct pci_dev *pdev);
extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
extern const char * mptscsih_info(struct Scsi_Host *SChost);
extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
-extern int mptscsih_target_alloc(struct scsi_target *starget);
-extern int mptscsih_slave_alloc(struct scsi_device *device);
-extern void mptscsih_target_destroy(struct scsi_target *starget);
extern void mptscsih_slave_destroy(struct scsi_device *device);
extern int mptscsih_slave_configure(struct scsi_device *device);
extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
@@ -98,6 +126,6 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE
extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth);
extern void mptscsih_timer_expired(unsigned long data);
-extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
-extern int mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid);
-extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
+extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
+extern u8 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id);
+extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 203c661d2c79..c31a9e3c8a26 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -4,7 +4,7 @@
* running LSI Logic Fusion MPT (Message Passing Technology) firmware.
*
* Copyright (c) 1999-2007 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
+ * (mailto:mpt_linux_developer@lsi.com)
*
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -65,6 +65,7 @@
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_transport.h>
#include <scsi/scsi_transport_spi.h>
+#include <scsi/scsi_dbg.h>
#include "mptbase.h"
#include "mptscsih.h"
@@ -95,25 +96,339 @@ static int mptspiDoneCtx = -1;
static int mptspiTaskCtx = -1;
static int mptspiInternalCtx = -1; /* Used only for internal commands */
+/**
+ * mptspi_setTargetNegoParms - Update the target negotiation
+ * parameters based on the the Inquiry data, adapter capabilities,
+ * and NVRAM settings
+ *
+ * @hd: Pointer to a SCSI Host Structure
+ * @vtarget: per target private data
+ * @sdev: SCSI device
+ *
+ **/
+static void
+mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
+ struct scsi_device *sdev)
+{
+ SpiCfgData *pspi_data = &hd->ioc->spi_data;
+ int id = (int) target->id;
+ int nvram;
+ u8 width = MPT_NARROW;
+ u8 factor = MPT_ASYNC;
+ u8 offset = 0;
+ u8 nfactor;
+ u8 noQas = 1;
+
+ target->negoFlags = pspi_data->noQas;
+
+ if (sdev->scsi_level < SCSI_2) {
+ width = 0;
+ factor = MPT_ULTRA2;
+ offset = pspi_data->maxSyncOffset;
+ target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
+ } else {
+ if (scsi_device_wide(sdev))
+ width = 1;
+
+ if (scsi_device_sync(sdev)) {
+ factor = pspi_data->minSyncFactor;
+ if (!scsi_device_dt(sdev))
+ factor = MPT_ULTRA2;
+ else {
+ if (!scsi_device_ius(sdev) &&
+ !scsi_device_qas(sdev))
+ factor = MPT_ULTRA160;
+ else {
+ factor = MPT_ULTRA320;
+ if (scsi_device_qas(sdev)) {
+ ddvprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id));
+ noQas = 0;
+ }
+ if (sdev->type == TYPE_TAPE &&
+ scsi_device_ius(sdev))
+ target->negoFlags |= MPT_TAPE_NEGO_IDP;
+ }
+ }
+ offset = pspi_data->maxSyncOffset;
+
+ /* If RAID, never disable QAS
+ * else if non RAID, do not disable
+ * QAS if bit 1 is set
+ * bit 1 QAS support, non-raid only
+ * bit 0 IU support
+ */
+ if (target->raidVolume == 1)
+ noQas = 0;
+ } else {
+ factor = MPT_ASYNC;
+ offset = 0;
+ }
+ }
+
+ if (!sdev->tagged_supported)
+ target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
+
+ /* Update tflags based on NVRAM settings. (SCSI only)
+ */
+ if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+ nvram = pspi_data->nvram[id];
+ nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
+
+ if (width)
+ width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
+
+ if (offset > 0) {
+ /* Ensure factor is set to the
+ * maximum of: adapter, nvram, inquiry
+ */
+ if (nfactor) {
+ if (nfactor < pspi_data->minSyncFactor )
+ nfactor = pspi_data->minSyncFactor;
+
+ factor = max(factor, nfactor);
+ if (factor == MPT_ASYNC)
+ offset = 0;
+ } else {
+ offset = 0;
+ factor = MPT_ASYNC;
+ }
+ } else {
+ factor = MPT_ASYNC;
+ }
+ }
+
+ /* Make sure data is consistent
+ */
+ if ((!width) && (factor < MPT_ULTRA2))
+ factor = MPT_ULTRA2;
+
+ /* Save the data to the target structure.
+ */
+ target->minSyncFactor = factor;
+ target->maxOffset = offset;
+ target->maxWidth = width;
+
+ target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
+
+ /* Disable unused features.
+ */
+ if (!width)
+ target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
+
+ if (!offset)
+ target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
+
+ if ( factor > MPT_ULTRA320 )
+ noQas = 0;
+
+ if (noQas && (pspi_data->noQas == 0)) {
+ pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
+ target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+
+ /* Disable QAS in a mixed configuration case
+ */
+
+ ddvprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
+ }
+}
+
+/**
+ * mptspi_writeIOCPage4 - write IOC Page 4
+ * @hd: Pointer to a SCSI Host Structure
+ * @channel:
+ * @id: write IOC Page4 for this ID & Bus
+ *
+ * Return: -EAGAIN if unable to obtain a Message Frame
+ * or 0 if success.
+ *
+ * Remark: We do not wait for a return, write pages sequentially.
+ **/
+static int
+mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id)
+{
+ MPT_ADAPTER *ioc = hd->ioc;
+ Config_t *pReq;
+ IOCPage4_t *IOCPage4Ptr;
+ MPT_FRAME_HDR *mf;
+ dma_addr_t dataDma;
+ u16 req_idx;
+ u32 frameOffset;
+ u32 flagsLength;
+ int ii;
+
+ /* Get a MF for this command.
+ */
+ if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
+ dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
+ ioc->name));
+ return -EAGAIN;
+ }
+
+ /* Set the request and the data pointers.
+ * Place data at end of MF.
+ */
+ pReq = (Config_t *)mf;
+
+ req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+ frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
+
+ /* Complete the request frame (same for all requests).
+ */
+ pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+ pReq->Reserved = 0;
+ pReq->ChainOffset = 0;
+ pReq->Function = MPI_FUNCTION_CONFIG;
+ pReq->ExtPageLength = 0;
+ pReq->ExtPageType = 0;
+ pReq->MsgFlags = 0;
+ for (ii=0; ii < 8; ii++) {
+ pReq->Reserved2[ii] = 0;
+ }
+
+ IOCPage4Ptr = ioc->spi_data.pIocPg4;
+ dataDma = ioc->spi_data.IocPg4_dma;
+ ii = IOCPage4Ptr->ActiveSEP++;
+ IOCPage4Ptr->SEP[ii].SEPTargetID = id;
+ IOCPage4Ptr->SEP[ii].SEPBus = channel;
+ pReq->Header = IOCPage4Ptr->Header;
+ pReq->PageAddress = cpu_to_le32(id | (channel << 8 ));
+
+ /* Add a SGE to the config request.
+ */
+ flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
+ (IOCPage4Ptr->Header.PageLength + ii) * 4;
+
+ mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
+
+ ddvprintk((MYIOC_s_INFO_FMT
+ "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
+ ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel));
+
+ mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
+
+ return 0;
+}
+
+/**
+ * mptspi_initTarget - Target, LUN alloc/free functionality.
+ * @hd: Pointer to MPT_SCSI_HOST structure
+ * @vtarget: per target private data
+ * @sdev: SCSI device
+ *
+ * NOTE: It's only SAFE to call this routine if data points to
+ * sane & valid STANDARD INQUIRY data!
+ *
+ * Allocate and initialize memory for this target.
+ * Save inquiry data.
+ *
+ **/
+static void
+mptspi_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget,
+ struct scsi_device *sdev)
+{
+
+ /* Is LUN supported? If so, upper 2 bits will be 0
+ * in first byte of inquiry data.
+ */
+ if (sdev->inq_periph_qual != 0)
+ return;
+
+ if (vtarget == NULL)
+ return;
+
+ vtarget->type = sdev->type;
+
+ if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
+ /* Treat all Processors as SAF-TE if
+ * command line option is set */
+ vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+ mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id);
+ }else if ((sdev->type == TYPE_PROCESSOR) &&
+ !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
+ if (sdev->inquiry_len > 49 ) {
+ if (sdev->inquiry[44] == 'S' &&
+ sdev->inquiry[45] == 'A' &&
+ sdev->inquiry[46] == 'F' &&
+ sdev->inquiry[47] == '-' &&
+ sdev->inquiry[48] == 'T' &&
+ sdev->inquiry[49] == 'E' ) {
+ vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+ mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id);
+ }
+ }
+ }
+ mptspi_setTargetNegoParms(hd, vtarget, sdev);
+}
+
+/**
+ * mptspi_is_raid - Determines whether target is belonging to volume
+ * @hd: Pointer to a SCSI HOST structure
+ * @id: target device id
+ *
+ * Return:
+ * non-zero = true
+ * zero = false
+ *
+ */
+static int
+mptspi_is_raid(struct _MPT_SCSI_HOST *hd, u32 id)
+{
+ int i, rc = 0;
+
+ if (!hd->ioc->raid_data.pIocPg2)
+ goto out;
+
+ if (!hd->ioc->raid_data.pIocPg2->NumActiveVolumes)
+ goto out;
+ for (i=0; i < hd->ioc->raid_data.pIocPg2->NumActiveVolumes; i++) {
+ if (hd->ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) {
+ rc = 1;
+ goto out;
+ }
+ }
+
+ out:
+ return rc;
+}
+
static int mptspi_target_alloc(struct scsi_target *starget)
{
struct Scsi_Host *shost = dev_to_shost(&starget->dev);
struct _MPT_SCSI_HOST *hd = (struct _MPT_SCSI_HOST *)shost->hostdata;
- int ret;
+ VirtTarget *vtarget;
if (hd == NULL)
return -ENODEV;
- ret = mptscsih_target_alloc(starget);
- if (ret)
- return ret;
+ vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
+ if (!vtarget)
+ return -ENOMEM;
+
+ vtarget->ioc_id = hd->ioc->id;
+ vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
+ vtarget->id = (u8)starget->id;
+ vtarget->channel = (u8)starget->channel;
+ vtarget->starget = starget;
+ starget->hostdata = vtarget;
+
+ if (starget->channel == 1) {
+ if (mptscsih_is_phys_disk(hd->ioc, 0, starget->id) == 0)
+ return 0;
+ vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
+ /* The real channel for this device is zero */
+ vtarget->channel = 0;
+ /* The actual physdisknum (for RAID passthrough) */
+ vtarget->id = mptscsih_raid_id_to_num(hd->ioc, 0,
+ starget->id);
+ }
- /* if we're a device on virtual channel 1 and we're not part
- * of an array, just return here (otherwise the setup below
- * may actually affect a real physical device on channel 0 */
- if (starget->channel == 1 &&
- mptscsih_raid_id_to_num(hd, starget->id) < 0)
- return 0;
+ if (starget->channel == 0 &&
+ mptspi_is_raid(hd, starget->id)) {
+ vtarget->raidVolume = 1;
+ ddvprintk((KERN_INFO
+ "RAID Volume @ channel=%d id=%d\n", starget->channel,
+ starget->id));
+ }
if (hd->ioc->spi_data.nvram &&
hd->ioc->spi_data.nvram[starget->id] != MPT_HOST_NVRAM_INVALID) {
@@ -132,6 +447,64 @@ static int mptspi_target_alloc(struct scsi_target *starget)
return 0;
}
+void
+mptspi_target_destroy(struct scsi_target *starget)
+{
+ if (starget->hostdata)
+ kfree(starget->hostdata);
+ starget->hostdata = NULL;
+}
+
+/**
+ * mptspi_print_write_nego - negotiation parameters debug info that is being sent
+ * @hd: Pointer to a SCSI HOST structure
+ * @starget: SCSI target
+ * @ii: negotiation parameters
+ *
+ */
+static void
+mptspi_print_write_nego(struct _MPT_SCSI_HOST *hd, struct scsi_target *starget, u32 ii)
+{
+ ddvprintk((MYIOC_s_INFO_FMT "id=%d Requested = 0x%08x"
+ " ( %s factor = 0x%02x @ offset = 0x%02x %s%s%s%s%s%s%s%s)\n",
+ hd->ioc->name, starget->id, ii,
+ ii & MPI_SCSIDEVPAGE0_NP_WIDE ? "Wide ": "",
+ ((ii >> 8) & 0xFF), ((ii >> 16) & 0xFF),
+ ii & MPI_SCSIDEVPAGE0_NP_IU ? "IU ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_DT ? "DT ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_QAS ? "QAS ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_HOLD_MCS ? "HOLDMCS ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_WR_FLOW ? "WRFLOW ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_RD_STRM ? "RDSTRM ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_RTI ? "RTI ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_PCOMP_EN ? "PCOMP ": ""));
+}
+
+/**
+ * mptspi_print_read_nego - negotiation parameters debug info that is being read
+ * @hd: Pointer to a SCSI HOST structure
+ * @starget: SCSI target
+ * @ii: negotiation parameters
+ *
+ */
+static void
+mptspi_print_read_nego(struct _MPT_SCSI_HOST *hd, struct scsi_target *starget, u32 ii)
+{
+ ddvprintk((MYIOC_s_INFO_FMT "id=%d Read = 0x%08x"
+ " ( %s factor = 0x%02x @ offset = 0x%02x %s%s%s%s%s%s%s%s)\n",
+ hd->ioc->name, starget->id, ii,
+ ii & MPI_SCSIDEVPAGE0_NP_WIDE ? "Wide ": "",
+ ((ii >> 8) & 0xFF), ((ii >> 16) & 0xFF),
+ ii & MPI_SCSIDEVPAGE0_NP_IU ? "IU ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_DT ? "DT ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_QAS ? "QAS ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_HOLD_MCS ? "HOLDMCS ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_WR_FLOW ? "WRFLOW ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_RD_STRM ? "RDSTRM ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_RTI ? "RTI ": "",
+ ii & MPI_SCSIDEVPAGE0_NP_PCOMP_EN ? "PCOMP ": ""));
+}
+
static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
struct _CONFIG_PAGE_SCSI_DEVICE_0 *pass_pg0)
{
@@ -147,7 +520,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
/* No SPI parameters for RAID devices */
if (starget->channel == 0 &&
- (hd->ioc->raid_data.isRaid & (1 << starget->id)))
+ mptspi_is_raid(hd, starget->id))
return -1;
size = ioc->spi_data.sdp0length * 4;
@@ -185,6 +558,8 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
err = 0;
memcpy(pass_pg0, pg0, size);
+ mptspi_print_read_nego(hd, starget, le32_to_cpu(pg0->NegotiatedParameters));
+
out_free:
dma_free_coherent(&ioc->pcidev->dev, size, pg0, pg0_dma);
return err;
@@ -233,7 +608,7 @@ static void mptspi_read_parameters(struct scsi_target *starget)
}
static int
-mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk)
+mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, u8 channel, u8 id)
{
MpiRaidActionRequest_t *pReq;
MPT_FRAME_HDR *mf;
@@ -253,8 +628,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk)
pReq->Reserved1 = 0;
pReq->ChainOffset = 0;
pReq->Function = MPI_FUNCTION_RAID_ACTION;
- pReq->VolumeID = disk;
- pReq->VolumeBus = 0;
+ pReq->VolumeID = id;
+ pReq->VolumeBus = channel;
pReq->PhysDiskNum = 0;
pReq->MsgFlags = 0;
pReq->Reserved2 = 0;
@@ -263,8 +638,8 @@ mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk)
mpt_add_sge((char *)&pReq->ActionDataSGE,
MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
- ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
- hd->ioc->name, action, io->id));
+ ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action=%x channel=%d id=%d\n",
+ hd->ioc->name, pReq->Action, channel, id));
hd->pLocal = NULL;
hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
@@ -292,12 +667,12 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
/* no DV on RAID devices */
if (sdev->channel == 0 &&
- (hd->ioc->raid_data.isRaid & (1 << sdev->id)))
+ mptspi_is_raid(hd, sdev->id))
return;
/* If this is a piece of a RAID, then quiesce first */
if (sdev->channel == 1 &&
- mptscsih_quiesce_raid(hd, 1, vtarget->target_id) < 0) {
+ mptscsih_quiesce_raid(hd, 1, vtarget->channel, vtarget->id) < 0) {
starget_printk(KERN_ERR, scsi_target(sdev),
"Integrated RAID quiesce failed\n");
return;
@@ -306,7 +681,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
spi_dv_device(sdev);
if (sdev->channel == 1 &&
- mptscsih_quiesce_raid(hd, 0, vtarget->target_id) < 0)
+ mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0)
starget_printk(KERN_ERR, scsi_target(sdev),
"Integrated RAID resume failed\n");
@@ -317,54 +692,89 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
static int mptspi_slave_alloc(struct scsi_device *sdev)
{
- int ret;
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
- /* gcc doesn't see that all uses of this variable occur within
- * the if() statements, so stop it from whining */
- int physdisknum = 0;
-
- if (sdev->channel == 1) {
- physdisknum = mptscsih_raid_id_to_num(hd, sdev->id);
+ VirtTarget *vtarget;
+ VirtDevice *vdev;
+ struct scsi_target *starget;
- if (physdisknum < 0)
- return physdisknum;
+ if (sdev->channel == 1 &&
+ mptscsih_is_phys_disk(hd->ioc, 0, sdev->id) == 0)
+ return -ENXIO;
+
+ vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
+ if (!vdev) {
+ printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
+ hd->ioc->name, sizeof(VirtDevice));
+ return -ENOMEM;
}
- ret = mptscsih_slave_alloc(sdev);
+ vdev->lun = sdev->lun;
+ sdev->hostdata = vdev;
- if (ret)
- return ret;
+ starget = scsi_target(sdev);
+ vtarget = starget->hostdata;
+ vdev->vtarget = vtarget;
+ vtarget->num_luns++;
- if (sdev->channel == 1) {
- VirtDevice *vdev = sdev->hostdata;
+ if (sdev->channel == 1)
sdev->no_uld_attach = 1;
- vdev->vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT;
- /* The real channel for this device is zero */
- vdev->vtarget->bus_id = 0;
- /* The actual physdisknum (for RAID passthrough) */
- vdev->vtarget->target_id = physdisknum;
- }
return 0;
}
static int mptspi_slave_configure(struct scsi_device *sdev)
{
- int ret = mptscsih_slave_configure(sdev);
struct _MPT_SCSI_HOST *hd =
(struct _MPT_SCSI_HOST *)sdev->host->hostdata;
+ VirtTarget *vtarget = scsi_target(sdev)->hostdata;
+ int ret = mptscsih_slave_configure(sdev);
if (ret)
return ret;
+ mptspi_initTarget(hd, vtarget, sdev);
+
+ ddvprintk((MYIOC_s_INFO_FMT "id=%d min_period=0x%02x"
+ " max_offset=0x%02x max_width=%d\n", hd->ioc->name,
+ sdev->id, spi_min_period(scsi_target(sdev)),
+ spi_max_offset(scsi_target(sdev)),
+ spi_max_width(scsi_target(sdev))));
+
if ((sdev->channel == 1 ||
- !(hd->ioc->raid_data.isRaid & (1 << sdev->id))) &&
+ !(mptspi_is_raid(hd, sdev->id))) &&
!spi_initial_dv(sdev->sdev_target))
mptspi_dv_device(hd, sdev);
return 0;
}
+static int
+mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
+{
+ struct _MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
+ VirtDevice *vdev = SCpnt->device->hostdata;
+
+ if (!vdev || !vdev->vtarget) {
+ SCpnt->result = DID_NO_CONNECT << 16;
+ done(SCpnt);
+ return 0;
+ }
+
+ if (SCpnt->device->channel == 1 &&
+ mptscsih_is_phys_disk(hd->ioc, 0, SCpnt->device->id) == 0) {
+ SCpnt->result = DID_NO_CONNECT << 16;
+ done(SCpnt);
+ return 0;
+ }
+
+#ifdef MPT_DEBUG_DV
+ if (spi_dv_pending(scsi_target(SCpnt->device)))
+ scsi_print_command(SCpnt);
+#endif
+
+ return mptscsih_qcmd(SCpnt,done);
+}
+
static void mptspi_slave_destroy(struct scsi_device *sdev)
{
struct scsi_target *starget = scsi_target(sdev);
@@ -392,11 +802,11 @@ static struct scsi_host_template mptspi_driver_template = {
.proc_info = mptscsih_proc_info,
.name = "MPT SPI Host",
.info = mptscsih_info,
- .queuecommand = mptscsih_qcmd,
+ .queuecommand = mptspi_qcmd,
.target_alloc = mptspi_target_alloc,
.slave_alloc = mptspi_slave_alloc,
.slave_configure = mptspi_slave_configure,
- .target_destroy = mptscsih_target_destroy,
+ .target_destroy = mptspi_target_destroy,
.slave_destroy = mptspi_slave_destroy,
.change_queue_depth = mptscsih_change_queue_depth,
.eh_abort_handler = mptscsih_abort,
@@ -427,7 +837,7 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
/* don't allow updating nego parameters on RAID devices */
if (starget->channel == 0 &&
- (hd->ioc->raid_data.isRaid & (1 << starget->id)))
+ mptspi_is_raid(hd, starget->id))
return -1;
size = ioc->spi_data.sdp1length * 4;
@@ -460,6 +870,8 @@ static int mptspi_write_spi_device_pg1(struct scsi_target *starget,
pg1->Header.PageNumber = hdr.PageNumber;
pg1->Header.PageType = hdr.PageType;
+ mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters));
+
if (mpt_config(ioc, &cfg)) {
starget_printk(KERN_ERR, starget, "mpt_config failed\n");
goto out_free;
@@ -672,9 +1084,9 @@ static void mpt_work_wrapper(struct work_struct *work)
if (sdev->channel != 1)
continue;
- /* The target_id is the raid PhysDiskNum, even if
+ /* The id is the raid PhysDiskNum, even if
* starget->id is the actual target address */
- if(vtarget->target_id != disk)
+ if(vtarget->id != disk)
continue;
starget_printk(KERN_INFO, vtarget->starget,
@@ -727,7 +1139,7 @@ mptspi_deny_binding(struct scsi_target *starget)
{
struct _MPT_SCSI_HOST *hd =
(struct _MPT_SCSI_HOST *)dev_to_shost(starget->dev.parent)->hostdata;
- return ((hd->ioc->raid_data.isRaid & (1 << starget->id)) &&
+ return ((mptspi_is_raid(hd, starget->id)) &&
starget->channel == 0) ? 1 : 0;
}
@@ -945,14 +1357,13 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
* max_lun = 1 + actual last lun,
* see hosts.h :o(
*/
- sh->max_id = MPT_MAX_SCSI_DEVICES;
+ sh->max_id = ioc->devices_per_bus;
sh->max_lun = MPT_LAST_LUN + 1;
/*
* If RAID Firmware Detected, setup virtual channel
*/
- if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
- > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
+ if (ioc->ir_firmware)
sh->max_channel = 1;
else
sh->max_channel = 0;
@@ -1009,20 +1420,6 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
ioc->name, hd->ScsiLookup));
- /* Allocate memory for the device structures.
- * A non-Null pointer at an offset
- * indicates a device exists.
- * max_id = 1 + maximum id (hosts.h)
- */
- hd->Targets = kcalloc(sh->max_id * (sh->max_channel + 1),
- sizeof(void *), GFP_ATOMIC);
- if (!hd->Targets) {
- error = -ENOMEM;
- goto out_mptspi_probe;
- }
-
- dprintk((KERN_INFO " vdev @ %p\n", hd->Targets));
-
/* Clear the TM flags
*/
hd->tmPending = 0;
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index e33d446e7493..8ba275a12773 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -1111,7 +1111,7 @@ static int cfg_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations config_fops = {
+static const struct file_operations config_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = i2o_cfg_ioctl,
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index a61cb17c5c12..06892ac2286e 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -1703,133 +1703,133 @@ static int i2o_seq_open_dev_name(struct inode *inode, struct file *file)
return single_open(file, i2o_seq_show_dev_name, PDE(inode)->data);
};
-static struct file_operations i2o_seq_fops_lct = {
+static const struct file_operations i2o_seq_fops_lct = {
.open = i2o_seq_open_lct,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_hrt = {
+static const struct file_operations i2o_seq_fops_hrt = {
.open = i2o_seq_open_hrt,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_status = {
+static const struct file_operations i2o_seq_fops_status = {
.open = i2o_seq_open_status,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_hw = {
+static const struct file_operations i2o_seq_fops_hw = {
.open = i2o_seq_open_hw,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_ddm_table = {
+static const struct file_operations i2o_seq_fops_ddm_table = {
.open = i2o_seq_open_ddm_table,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_driver_store = {
+static const struct file_operations i2o_seq_fops_driver_store = {
.open = i2o_seq_open_driver_store,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_drivers_stored = {
+static const struct file_operations i2o_seq_fops_drivers_stored = {
.open = i2o_seq_open_drivers_stored,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_groups = {
+static const struct file_operations i2o_seq_fops_groups = {
.open = i2o_seq_open_groups,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_phys_device = {
+static const struct file_operations i2o_seq_fops_phys_device = {
.open = i2o_seq_open_phys_device,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_claimed = {
+static const struct file_operations i2o_seq_fops_claimed = {
.open = i2o_seq_open_claimed,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_users = {
+static const struct file_operations i2o_seq_fops_users = {
.open = i2o_seq_open_users,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_priv_msgs = {
+static const struct file_operations i2o_seq_fops_priv_msgs = {
.open = i2o_seq_open_priv_msgs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_authorized_users = {
+static const struct file_operations i2o_seq_fops_authorized_users = {
.open = i2o_seq_open_authorized_users,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_dev_name = {
+static const struct file_operations i2o_seq_fops_dev_name = {
.open = i2o_seq_open_dev_name,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_dev_identity = {
+static const struct file_operations i2o_seq_fops_dev_identity = {
.open = i2o_seq_open_dev_identity,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_ddm_identity = {
+static const struct file_operations i2o_seq_fops_ddm_identity = {
.open = i2o_seq_open_ddm_identity,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_uinfo = {
+static const struct file_operations i2o_seq_fops_uinfo = {
.open = i2o_seq_open_uinfo,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_sgl_limits = {
+static const struct file_operations i2o_seq_fops_sgl_limits = {
.open = i2o_seq_open_sgl_limits,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
-static struct file_operations i2o_seq_fops_sensors = {
+static const struct file_operations i2o_seq_fops_sensors = {
.open = i2o_seq_open_sensors,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
index 11a801be71c8..ca86f113f36a 100644
--- a/drivers/misc/hdpuftrs/hdpu_cpustate.c
+++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c
@@ -169,7 +169,7 @@ static struct platform_driver hdpu_cpustate_driver = {
/*
* The various file operations we support.
*/
-static struct file_operations cpustate_fops = {
+static const struct file_operations cpustate_fops = {
owner:THIS_MODULE,
open:cpustate_open,
release:cpustate_release,
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
index ea9d5f233c83..6a51e99a8079 100644
--- a/drivers/misc/hdpuftrs/hdpu_nexus.c
+++ b/drivers/misc/hdpuftrs/hdpu_nexus.c
@@ -72,11 +72,9 @@ static int hdpu_nexus_probe(struct platform_device *pdev)
printk("Could not map slot id\n");
hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, &proc_root);
hdpu_slot_id->read_proc = hdpu_slot_id_read;
- hdpu_slot_id->nlink = 1;
hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, &proc_root);
hdpu_chassis_id->read_proc = hdpu_chassis_id_read;
- hdpu_chassis_id->nlink = 1;
return 0;
}
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
index b99dc507de2e..c436d3de8b8b 100644
--- a/drivers/misc/ibmasm/ibmasmfs.c
+++ b/drivers/misc/ibmasm/ibmasmfs.c
@@ -156,7 +156,7 @@ static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode)
static struct dentry *ibmasmfs_create_file (struct super_block *sb,
struct dentry *parent,
const char *name,
- struct file_operations *fops,
+ const struct file_operations *fops,
void *data,
int mode)
{
@@ -581,28 +581,28 @@ static ssize_t remote_settings_file_write(struct file *file, const char __user *
return count;
}
-static struct file_operations command_fops = {
+static const struct file_operations command_fops = {
.open = command_file_open,
.release = command_file_close,
.read = command_file_read,
.write = command_file_write,
};
-static struct file_operations event_fops = {
+static const struct file_operations event_fops = {
.open = event_file_open,
.release = event_file_close,
.read = event_file_read,
.write = event_file_write,
};
-static struct file_operations r_heartbeat_fops = {
+static const struct file_operations r_heartbeat_fops = {
.open = r_heartbeat_file_open,
.release = r_heartbeat_file_close,
.read = r_heartbeat_file_read,
.write = r_heartbeat_file_write,
};
-static struct file_operations remote_settings_fops = {
+static const struct file_operations remote_settings_fops = {
.open = remote_settings_file_open,
.release = remote_settings_file_close,
.read = remote_settings_file_read,
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index b995a15b7526..6a5a05d1f392 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -309,7 +309,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
ret = -ENODEV;
goto out_pci;
}
- if (!request_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
+ if (!request_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
"ioc4_misc")) {
printk(KERN_WARNING
"%s: Unable to request IOC4 misc region "
@@ -379,7 +379,7 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
return 0;
out_misc_region:
- release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
+ release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
out_pci:
kfree(idd);
out_idd:
@@ -418,7 +418,7 @@ ioc4_remove(struct pci_dev *pdev)
"Device removal may be incomplete.\n",
__FUNCTION__, pci_name(idd->idd_pdev));
}
- release_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
+ release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
/* Disable IOC4 and relinquish */
pci_disable_device(pdev);
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 4bf1fea5e2c4..7522f76b15ec 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -22,9 +22,6 @@
#include "sdhci.h"
#define DRIVER_NAME "sdhci"
-#define DRIVER_VERSION "0.12"
-
-#define BUGMAIL "<sdhci-devel@list.drzeus.cx>"
#define DBG(f, x...) \
pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x)
@@ -154,8 +151,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
/* hw clears the bit when it's done */
while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) {
if (timeout == 0) {
- printk(KERN_ERR "%s: Reset 0x%x never completed. "
- "Please report this to " BUGMAIL ".\n",
+ printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
mmc_hostname(host->mmc), (int)mask);
sdhci_dumpregs(host);
return;
@@ -474,12 +470,11 @@ static void sdhci_finish_data(struct sdhci_host *host)
if ((data->error == MMC_ERR_NONE) && blocks) {
printk(KERN_ERR "%s: Controller signalled completion even "
- "though there were blocks left. Please report this "
- "to " BUGMAIL ".\n", mmc_hostname(host->mmc));
+ "though there were blocks left.\n",
+ mmc_hostname(host->mmc));
data->error = MMC_ERR_FAILED;
} else if (host->size != 0) {
- printk(KERN_ERR "%s: %d bytes were left untransferred. "
- "Please report this to " BUGMAIL ".\n",
+ printk(KERN_ERR "%s: %d bytes were left untransferred.\n",
mmc_hostname(host->mmc), host->size);
data->error = MMC_ERR_FAILED;
}
@@ -526,8 +521,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
if (timeout == 0) {
printk(KERN_ERR "%s: Controller never released "
- "inhibit bit(s). Please report this to "
- BUGMAIL ".\n", mmc_hostname(host->mmc));
+ "inhibit bit(s).\n", mmc_hostname(host->mmc));
sdhci_dumpregs(host);
cmd->error = MMC_ERR_FAILED;
tasklet_schedule(&host->finish_tasklet);
@@ -548,8 +542,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
sdhci_set_transfer_mode(host, cmd->data);
if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
- printk(KERN_ERR "%s: Unsupported response type! "
- "Please report this to " BUGMAIL ".\n",
+ printk(KERN_ERR "%s: Unsupported response type!\n",
mmc_hostname(host->mmc));
cmd->error = MMC_ERR_INVALID;
tasklet_schedule(&host->finish_tasklet);
@@ -647,9 +640,8 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
& SDHCI_CLOCK_INT_STABLE)) {
if (timeout == 0) {
- printk(KERN_ERR "%s: Internal clock never stabilised. "
- "Please report this to " BUGMAIL ".\n",
- mmc_hostname(host->mmc));
+ printk(KERN_ERR "%s: Internal clock never "
+ "stabilised.\n", mmc_hostname(host->mmc));
sdhci_dumpregs(host);
return;
}
@@ -899,9 +891,8 @@ static void sdhci_timeout_timer(unsigned long data)
spin_lock_irqsave(&host->lock, flags);
if (host->mrq) {
- printk(KERN_ERR "%s: Timeout waiting for hardware interrupt. "
- "Please report this to " BUGMAIL ".\n",
- mmc_hostname(host->mmc));
+ printk(KERN_ERR "%s: Timeout waiting for hardware "
+ "interrupt.\n", mmc_hostname(host->mmc));
sdhci_dumpregs(host);
if (host->data) {
@@ -935,8 +926,6 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask)
printk(KERN_ERR "%s: Got command interrupt even though no "
"command operation was in progress.\n",
mmc_hostname(host->mmc));
- printk(KERN_ERR "%s: Please report this to " BUGMAIL ".\n",
- mmc_hostname(host->mmc));
sdhci_dumpregs(host);
return;
}
@@ -972,8 +961,6 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
printk(KERN_ERR "%s: Got data interrupt even though no "
"data operation was in progress.\n",
mmc_hostname(host->mmc));
- printk(KERN_ERR "%s: Please report this to " BUGMAIL ".\n",
- mmc_hostname(host->mmc));
sdhci_dumpregs(host);
return;
@@ -1045,8 +1032,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
intmask &= SDHCI_INT_BUS_POWER;
if (intmask) {
- printk(KERN_ERR "%s: Unexpected interrupt 0x%08x. Please "
- "report this to " BUGMAIL ".\n",
+ printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n",
mmc_hostname(host->mmc), intmask);
sdhci_dumpregs(host);
@@ -1528,8 +1514,7 @@ static struct pci_driver sdhci_driver = {
static int __init sdhci_drv_init(void)
{
printk(KERN_INFO DRIVER_NAME
- ": Secure Digital Host Controller Interface driver, "
- DRIVER_VERSION "\n");
+ ": Secure Digital Host Controller Interface driver\n");
printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
return pci_register_driver(&sdhci_driver);
@@ -1551,7 +1536,6 @@ module_param(debug_quirks, uint, 0444);
MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
MODULE_DESCRIPTION("Secure Digital Host Controller Interface driver");
-MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
MODULE_PARM_DESC(debug_nodma, "Forcefully disable DMA transfers. (default 0)");
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index e65f8a0a9349..0581d09c58fc 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -36,8 +36,8 @@ module_param(fixed_timeout, bool, 0644);
#define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */
#define TIFM_MMCSD_READ 0x8000
-#define TIFM_MMCSD_DATAMASK 0x001d /* set bits: EOFB, BRS, CB, EOC */
-#define TIFM_MMCSD_ERRMASK 0x41e0 /* set bits: CERR, CCRC, CTO, DCRC, DTO */
+#define TIFM_MMCSD_DATAMASK 0x401d /* set bits: CERR, EOFB, BRS, CB, EOC */
+#define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */
#define TIFM_MMCSD_EOC 0x0001 /* end of command phase */
#define TIFM_MMCSD_CB 0x0004 /* card enter busy state */
#define TIFM_MMCSD_BRS 0x0008 /* block received/sent */
@@ -242,7 +242,7 @@ change_state:
case IDLE:
return;
case CMD:
- if (host_status & TIFM_MMCSD_EOC) {
+ if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) {
tifm_sd_fetch_resp(cmd, sock);
if (cmd->data) {
host->state = BRS;
@@ -341,10 +341,7 @@ static void tifm_sd_signal_irq(struct tifm_dev *sock,
goto done;
if (host_status & TIFM_MMCSD_ERRMASK) {
- if (host_status & TIFM_MMCSD_CERR)
- error_code = MMC_ERR_FAILED;
- else if (host_status
- & (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO))
+ if (host_status & (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO))
error_code = MMC_ERR_TIMEOUT;
else if (host_status
& (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC))
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index a44d8777ab9f..05ccfc43168f 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -42,7 +42,6 @@
#include "wbsd.h"
#define DRIVER_NAME "wbsd"
-#define DRIVER_VERSION "1.6"
#define DBG(x...) \
pr_debug(DRIVER_NAME ": " x)
@@ -344,7 +343,6 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
memcpy(sgbuf, dmabuf, size);
else
memcpy(sgbuf, dmabuf, sg[i].length);
- kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
dmabuf += sg[i].length;
if (size < sg[i].length)
@@ -2101,8 +2099,7 @@ static int __init wbsd_drv_init(void)
int result;
printk(KERN_INFO DRIVER_NAME
- ": Winbond W83L51xD SD/MMC card interface driver, "
- DRIVER_VERSION "\n");
+ ": Winbond W83L51xD SD/MMC card interface driver\n");
printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
#ifdef CONFIG_PNP
@@ -2166,7 +2163,6 @@ module_param(dma, int, 0444);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");
-MODULE_VERSION(DRIVER_VERSION);
#ifdef CONFIG_PNP
MODULE_PARM_DESC(nopnp, "Scan for device instead of relying on PNP. (default 0)");
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 6d917a4daa9d..f9f2ce7806b0 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -278,7 +278,8 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
kfree(dev->mtd.name);
if (dev->blkdev) {
- invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping);
+ invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
+ 0, -1);
close_bdev_excl(dev->blkdev);
}
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 3013d0883b97..61a994ea8af1 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -759,7 +759,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
return ret;
} /* memory_ioctl */
-static struct file_operations mtd_fops = {
+static const struct file_operations mtd_fops = {
.owner = THIS_MODULE,
.llseek = mtd_lseek,
.read = mtd_read,
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index aa9dd8f11269..4218075c8aa3 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -338,7 +338,8 @@ static void com20020_set_mc_list(struct net_device *dev)
}
#if defined(CONFIG_ARCNET_COM20020_PCI_MODULE) || \
- defined(CONFIG_ARCNET_COM20020_ISA_MODULE)
+ defined(CONFIG_ARCNET_COM20020_ISA_MODULE) || \
+ defined(CONFIG_ARCNET_COM20020_CS_MODULE)
EXPORT_SYMBOL(com20020_check);
EXPORT_SYMBOL(com20020_found);
#endif
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8ce8fec615ba..61a6fa465d71 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3120,7 +3120,7 @@ static int bond_info_open(struct inode *inode, struct file *file)
return res;
}
-static struct file_operations bond_info_fops = {
+static const struct file_operations bond_info_fops = {
.owner = THIS_MODULE,
.open = bond_info_open,
.read = seq_read,
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 9dd387fb3d74..6e2166a7601a 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -39,13 +39,15 @@
#include "gianfar.h"
#define GFAR_ATTR(_name) \
-static ssize_t gfar_show_##_name(struct class_device *cdev, char *buf); \
-static ssize_t gfar_set_##_name(struct class_device *cdev, \
+static ssize_t gfar_show_##_name(struct device *dev, \
+ struct device_attribute *attr, char *buf); \
+static ssize_t gfar_set_##_name(struct device *dev, \
+ struct device_attribute *attr, \
const char *buf, size_t count); \
-static CLASS_DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
+static DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
#define GFAR_CREATE_FILE(_dev, _name) \
- class_device_create_file(&_dev->class_dev, &class_device_attr_##_name)
+ device_create_file(&_dev->dev, &dev_attr_##_name)
GFAR_ATTR(bd_stash);
GFAR_ATTR(rx_stash_size);
@@ -54,29 +56,28 @@ GFAR_ATTR(fifo_threshold);
GFAR_ATTR(fifo_starve);
GFAR_ATTR(fifo_starve_off);
-#define to_net_dev(cd) container_of(cd, struct net_device, class_dev)
-
-static ssize_t gfar_show_bd_stash(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_bd_stash(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
- return sprintf(buf, "%s\n", priv->bd_stash_en? "on" : "off");
+ return sprintf(buf, "%s\n", priv->bd_stash_en ? "on" : "off");
}
-static ssize_t gfar_set_bd_stash(struct class_device *cdev,
- const char *buf, size_t count)
+static ssize_t gfar_set_bd_stash(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
int new_setting = 0;
u32 temp;
unsigned long flags;
/* Find out the new setting */
- if (!strncmp("on", buf, count-1) || !strncmp("1", buf, count-1))
+ if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
new_setting = 1;
- else if (!strncmp("off", buf, count-1) || !strncmp("0", buf, count-1))
+ else if (!strncmp("off", buf, count - 1)
+ || !strncmp("0", buf, count - 1))
new_setting = 0;
else
return count;
@@ -100,19 +101,19 @@ static ssize_t gfar_set_bd_stash(struct class_device *cdev,
return count;
}
-static ssize_t gfar_show_rx_stash_size(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_rx_stash_size(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%d\n", priv->rx_stash_size);
}
-static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
- const char *buf, size_t count)
+static ssize_t gfar_set_rx_stash_size(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
unsigned int length = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
@@ -146,21 +147,21 @@ static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
return count;
}
-
/* Stashing will only be enabled when rx_stash_size != 0 */
-static ssize_t gfar_show_rx_stash_index(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_rx_stash_index(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%d\n", priv->rx_stash_index);
}
-static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
- const char *buf, size_t count)
+static ssize_t gfar_set_rx_stash_index(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
unsigned short index = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
@@ -184,19 +185,20 @@ static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
return count;
}
-static ssize_t gfar_show_fifo_threshold(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_fifo_threshold(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%d\n", priv->fifo_threshold);
}
-static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
- const char *buf, size_t count)
+static ssize_t gfar_set_fifo_threshold(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
unsigned int length = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
@@ -218,20 +220,19 @@ static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
return count;
}
-static ssize_t gfar_show_fifo_starve(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_fifo_starve(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%d\n", priv->fifo_starve);
}
-
-static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
- const char *buf, size_t count)
+static ssize_t gfar_set_fifo_starve(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
unsigned int num = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
@@ -253,19 +254,20 @@ static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
return count;
}
-static ssize_t gfar_show_fifo_starve_off(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_fifo_starve_off(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
return sprintf(buf, "%d\n", priv->fifo_starve_off);
}
-static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
- const char *buf, size_t count)
+static ssize_t gfar_set_fifo_starve_off(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- struct net_device *dev = to_net_dev(cdev);
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(to_net_dev(dev));
unsigned int num = simple_strtoul(buf, NULL, 0);
u32 temp;
unsigned long flags;
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 5b788d84011f..d2542697e298 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -459,7 +459,7 @@ static int bpq_info_open(struct inode *inode, struct file *file)
return seq_open(file, &bpq_seqops);
}
-static struct file_operations bpq_info_fops = {
+static const struct file_operations bpq_info_fops = {
.owner = THIS_MODULE,
.open = bpq_info_open,
.read = seq_read,
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 2ce047e9d262..6fdaad5a4577 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -2083,7 +2083,7 @@ static int scc_net_seq_open(struct inode *inode, struct file *file)
return seq_open(file, &scc_net_seq_ops);
}
-static struct file_operations scc_net_seq_fops = {
+static const struct file_operations scc_net_seq_fops = {
.owner = THIS_MODULE,
.open = scc_net_seq_open,
.read = seq_read,
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 6d74f08720d5..08f27119a807 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -804,7 +804,7 @@ static int yam_info_open(struct inode *inode, struct file *file)
return seq_open(file, &yam_seqops);
}
-static struct file_operations yam_info_fops = {
+static const struct file_operations yam_info_fops = {
.owner = THIS_MODULE,
.open = yam_info_open,
.read = seq_read,
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 99343b5836b8..458db0538a9a 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1156,7 +1156,7 @@ static int ibmveth_proc_open(struct inode *inode, struct file *file)
return rc;
}
-static struct file_operations ibmveth_proc_fops = {
+static const struct file_operations ibmveth_proc_fops = {
.owner = THIS_MODULE,
.open = ibmveth_proc_open,
.read = seq_read,
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index e2b1af618450..3457e9d8b667 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -385,7 +385,7 @@ static int vlsi_seq_open(struct inode *inode, struct file *file)
return single_open(file, vlsi_seq_show, PDE(inode)->data);
}
-static struct file_operations vlsi_proc_fops = {
+static const struct file_operations vlsi_proc_fops = {
.owner = THIS_MODULE,
.open = vlsi_seq_open,
.read = seq_read,
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index c6de566188e4..11b575f89856 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -83,7 +83,7 @@ struct ppp_file {
int dead; /* unit/channel has been shut down */
};
-#define PF_TO_X(pf, X) ((X *)((char *)(pf) - offsetof(X, file)))
+#define PF_TO_X(pf, X) container_of(pf, X, file)
#define PF_TO_PPP(pf) PF_TO_X(pf, struct ppp)
#define PF_TO_CHANNEL(pf) PF_TO_X(pf, struct channel)
@@ -834,7 +834,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
return err;
}
-static struct file_operations ppp_device_fops = {
+static const struct file_operations ppp_device_fops = {
.owner = THIS_MODULE,
.read = ppp_read,
.write = ppp_write,
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 315d5c3fc66a..860bb0f60f68 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -1043,7 +1043,7 @@ static int pppoe_seq_open(struct inode *inode, struct file *file)
return seq_open(file, &pppoe_seq_ops);
}
-static struct file_operations pppoe_seq_fops = {
+static const struct file_operations pppoe_seq_fops = {
.owner = THIS_MODULE,
.open = pppoe_seq_open,
.read = seq_read,
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 151a2e10e4f3..5643d1e84ed6 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -744,7 +744,7 @@ static int tun_chr_close(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations tun_fops = {
+static const struct file_operations tun_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = do_sync_read,
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 6c7dfb50143f..e91b5a84a20a 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -311,7 +311,7 @@ static int cosa_chardev_ioctl(struct inode *inode, struct file *file,
static int cosa_fasync(struct inode *inode, struct file *file, int on);
#endif
-static struct file_operations cosa_fops = {
+static const struct file_operations cosa_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = cosa_read,
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 44a22701da97..b08055abe83a 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4430,53 +4430,53 @@ static int proc_BSSList_open( struct inode *inode, struct file *file );
static int proc_config_open( struct inode *inode, struct file *file );
static int proc_wepkey_open( struct inode *inode, struct file *file );
-static struct file_operations proc_statsdelta_ops = {
+static const struct file_operations proc_statsdelta_ops = {
.read = proc_read,
.open = proc_statsdelta_open,
.release = proc_close
};
-static struct file_operations proc_stats_ops = {
+static const struct file_operations proc_stats_ops = {
.read = proc_read,
.open = proc_stats_open,
.release = proc_close
};
-static struct file_operations proc_status_ops = {
+static const struct file_operations proc_status_ops = {
.read = proc_read,
.open = proc_status_open,
.release = proc_close
};
-static struct file_operations proc_SSID_ops = {
+static const struct file_operations proc_SSID_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_SSID_open,
.release = proc_close
};
-static struct file_operations proc_BSSList_ops = {
+static const struct file_operations proc_BSSList_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_BSSList_open,
.release = proc_close
};
-static struct file_operations proc_APList_ops = {
+static const struct file_operations proc_APList_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_APList_open,
.release = proc_close
};
-static struct file_operations proc_config_ops = {
+static const struct file_operations proc_config_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_config_open,
.release = proc_close
};
-static struct file_operations proc_wepkey_ops = {
+static const struct file_operations proc_wepkey_ops = {
.read = proc_read,
.write = proc_write,
.open = proc_wepkey_open,
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
index b9df06a06ea9..35dbe4554513 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
@@ -355,37 +355,37 @@ out_up:
#undef fappend
-static struct file_operations devinfo_fops = {
+static const struct file_operations devinfo_fops = {
.read = devinfo_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
-static struct file_operations spromdump_fops = {
+static const struct file_operations spromdump_fops = {
.read = spromdump_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
-static struct file_operations drvinfo_fops = {
+static const struct file_operations drvinfo_fops = {
.read = drvinfo_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
-static struct file_operations tsf_fops = {
+static const struct file_operations tsf_fops = {
.read = tsf_read_file,
.write = tsf_write_file,
.open = open_file_generic,
};
-static struct file_operations txstat_fops = {
+static const struct file_operations txstat_fops = {
.read = txstat_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
-static struct file_operations restart_fops = {
+static const struct file_operations restart_fops = {
.write = restart_write_file,
.open = open_file_generic,
};
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index ce3a8bac66ff..f5ce1c6063d8 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -1160,7 +1160,7 @@ static int strip_seq_open(struct inode *inode, struct file *file)
return seq_open(file, &strip_seq_ops);
}
-static struct file_operations strip_seq_fops = {
+static const struct file_operations strip_seq_fops = {
.owner = THIS_MODULE,
.open = strip_seq_open,
.read = seq_read,
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
index 04d641714d34..00e937e9240e 100644
--- a/drivers/oprofile/event_buffer.c
+++ b/drivers/oprofile/event_buffer.c
@@ -181,7 +181,7 @@ out:
return retval;
}
-struct file_operations event_buffer_fops = {
+const struct file_operations event_buffer_fops = {
.open = event_buffer_open,
.release = event_buffer_release,
.read = event_buffer_read,
diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h
index 92416276e577..9b6a4ebd03e3 100644
--- a/drivers/oprofile/event_buffer.h
+++ b/drivers/oprofile/event_buffer.h
@@ -41,7 +41,7 @@ void wake_up_buffer_waiter(void);
/* add data to the event buffer */
void add_event_entry(unsigned long data);
-extern struct file_operations event_buffer_fops;
+extern const struct file_operations event_buffer_fops;
/* mutex between sync_cpu_buffers() and the
* file reading code.
diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c
index a72006c08f2b..ef953ba5ab6b 100644
--- a/drivers/oprofile/oprofile_files.c
+++ b/drivers/oprofile/oprofile_files.c
@@ -44,7 +44,7 @@ static ssize_t depth_write(struct file * file, char const __user * buf, size_t c
}
-static struct file_operations depth_fops = {
+static const struct file_operations depth_fops = {
.read = depth_read,
.write = depth_write
};
@@ -56,7 +56,7 @@ static ssize_t pointer_size_read(struct file * file, char __user * buf, size_t c
}
-static struct file_operations pointer_size_fops = {
+static const struct file_operations pointer_size_fops = {
.read = pointer_size_read,
};
@@ -67,7 +67,7 @@ static ssize_t cpu_type_read(struct file * file, char __user * buf, size_t count
}
-static struct file_operations cpu_type_fops = {
+static const struct file_operations cpu_type_fops = {
.read = cpu_type_read,
};
@@ -101,7 +101,7 @@ static ssize_t enable_write(struct file * file, char const __user * buf, size_t
}
-static struct file_operations enable_fops = {
+static const struct file_operations enable_fops = {
.read = enable_read,
.write = enable_write,
};
@@ -114,7 +114,7 @@ static ssize_t dump_write(struct file * file, char const __user * buf, size_t co
}
-static struct file_operations dump_fops = {
+static const struct file_operations dump_fops = {
.write = dump_write,
};
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c
index 5756401fb15b..6e67b42ca46d 100644
--- a/drivers/oprofile/oprofilefs.c
+++ b/drivers/oprofile/oprofilefs.c
@@ -115,14 +115,14 @@ static int default_open(struct inode * inode, struct file * filp)
}
-static struct file_operations ulong_fops = {
+static const struct file_operations ulong_fops = {
.read = ulong_read_file,
.write = ulong_write_file,
.open = default_open,
};
-static struct file_operations ulong_ro_fops = {
+static const struct file_operations ulong_ro_fops = {
.read = ulong_read_file,
.open = default_open,
};
@@ -182,7 +182,7 @@ static ssize_t atomic_read_file(struct file * file, char __user * buf, size_t co
}
-static struct file_operations atomic_ro_fops = {
+static const struct file_operations atomic_ro_fops = {
.read = atomic_read_file,
.open = default_open,
};
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index fe3f5f5365c5..894fdb9d44c0 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1091,7 +1091,7 @@ static int ccio_proc_info_open(struct inode *inode, struct file *file)
return single_open(file, &ccio_proc_info, NULL);
}
-static struct file_operations ccio_proc_info_fops = {
+static const struct file_operations ccio_proc_info_fops = {
.owner = THIS_MODULE,
.open = ccio_proc_info_open,
.read = seq_read,
@@ -1127,7 +1127,7 @@ static int ccio_proc_bitmap_open(struct inode *inode, struct file *file)
return single_open(file, &ccio_proc_bitmap_info, NULL);
}
-static struct file_operations ccio_proc_bitmap_fops = {
+static const struct file_operations ccio_proc_bitmap_fops = {
.owner = THIS_MODULE,
.open = ccio_proc_bitmap_open,
.read = seq_read,
diff --git a/drivers/parisc/eisa_eeprom.c b/drivers/parisc/eisa_eeprom.c
index e13aafa70bf5..86e9c84a965e 100644
--- a/drivers/parisc/eisa_eeprom.c
+++ b/drivers/parisc/eisa_eeprom.c
@@ -97,7 +97,7 @@ static int eisa_eeprom_release(struct inode *inode, struct file *file)
/*
* The various file operations we support.
*/
-static struct file_operations eisa_eeprom_fops = {
+static const struct file_operations eisa_eeprom_fops = {
.owner = THIS_MODULE,
.llseek = eisa_eeprom_llseek,
.read = eisa_eeprom_read,
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 8dac2ba82bb9..9a731c101d10 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -252,7 +252,6 @@ static int __init led_create_procfs(void)
proc_pdc_root->owner = THIS_MODULE;
ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
if (!ent) return -1;
- ent->nlink = 1;
ent->data = (void *)LED_NOLCD; /* LED */
ent->read_proc = led_proc_read;
ent->write_proc = led_proc_write;
@@ -262,7 +261,6 @@ static int __init led_create_procfs(void)
{
ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
if (!ent) return -1;
- ent->nlink = 1;
ent->data = (void *)LED_HASLCD; /* LCD */
ent->read_proc = led_proc_read;
ent->write_proc = led_proc_write;
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index f1e7ccd5475b..76a29dadd519 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1799,7 +1799,7 @@ sba_proc_open(struct inode *i, struct file *f)
return single_open(f, &sba_proc_info, NULL);
}
-static struct file_operations sba_proc_fops = {
+static const struct file_operations sba_proc_fops = {
.owner = THIS_MODULE,
.open = sba_proc_open,
.read = seq_read,
@@ -1831,7 +1831,7 @@ sba_proc_bitmap_open(struct inode *i, struct file *f)
return single_open(f, &sba_proc_bitmap_info, NULL);
}
-static struct file_operations sba_proc_bitmap_fops = {
+static const struct file_operations sba_proc_bitmap_fops = {
.owner = THIS_MODULE,
.open = sba_proc_bitmap_open,
.read = seq_read,
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 3cfb0a3575e6..5ea5bc70cb82 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -4,7 +4,7 @@
config PCI_MSI
bool "Message Signaled Interrupts (MSI and MSI-X)"
depends on PCI
- depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64
+ depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 || SPARC64
help
This allows device drivers to enable MSI (Message Signaled
Interrupts). Message Signaled Interrupts enable a device to
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index 634f74d919d3..a13abf55d784 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -202,7 +202,7 @@ static int release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations debug_ops = {
+static const struct file_operations debug_ops = {
.owner = THIS_MODULE,
.open = open,
.llseek = lseek,
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 84c757ba0664..8b44cff2c176 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -744,6 +744,104 @@ int pci_enable_device(struct pci_dev *dev)
return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
}
+/*
+ * Managed PCI resources. This manages device on/off, intx/msi/msix
+ * on/off and BAR regions. pci_dev itself records msi/msix status, so
+ * there's no need to track it separately. pci_devres is initialized
+ * when a device is enabled using managed PCI device enable interface.
+ */
+struct pci_devres {
+ unsigned int disable:1;
+ unsigned int orig_intx:1;
+ unsigned int restore_intx:1;
+ u32 region_mask;
+};
+
+static void pcim_release(struct device *gendev, void *res)
+{
+ struct pci_dev *dev = container_of(gendev, struct pci_dev, dev);
+ struct pci_devres *this = res;
+ int i;
+
+ if (dev->msi_enabled)
+ pci_disable_msi(dev);
+ if (dev->msix_enabled)
+ pci_disable_msix(dev);
+
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+ if (this->region_mask & (1 << i))
+ pci_release_region(dev, i);
+
+ if (this->restore_intx)
+ pci_intx(dev, this->orig_intx);
+
+ if (this->disable)
+ pci_disable_device(dev);
+}
+
+static struct pci_devres * get_pci_dr(struct pci_dev *pdev)
+{
+ struct pci_devres *dr, *new_dr;
+
+ dr = devres_find(&pdev->dev, pcim_release, NULL, NULL);
+ if (dr)
+ return dr;
+
+ new_dr = devres_alloc(pcim_release, sizeof(*new_dr), GFP_KERNEL);
+ if (!new_dr)
+ return NULL;
+ return devres_get(&pdev->dev, new_dr, NULL, NULL);
+}
+
+static struct pci_devres * find_pci_dr(struct pci_dev *pdev)
+{
+ if (pci_is_managed(pdev))
+ return devres_find(&pdev->dev, pcim_release, NULL, NULL);
+ return NULL;
+}
+
+/**
+ * pcim_enable_device - Managed pci_enable_device()
+ * @pdev: PCI device to be initialized
+ *
+ * Managed pci_enable_device().
+ */
+int pcim_enable_device(struct pci_dev *pdev)
+{
+ struct pci_devres *dr;
+ int rc;
+
+ dr = get_pci_dr(pdev);
+ if (unlikely(!dr))
+ return -ENOMEM;
+ WARN_ON(!!dr->disable);
+
+ rc = pci_enable_device(pdev);
+ if (!rc) {
+ pdev->is_managed = 1;
+ dr->disable = 1;
+ }
+ return rc;
+}
+
+/**
+ * pcim_pin_device - Pin managed PCI device
+ * @pdev: PCI device to pin
+ *
+ * Pin managed PCI device @pdev. Pinned device won't be disabled on
+ * driver detach. @pdev must have been enabled with
+ * pcim_enable_device().
+ */
+void pcim_pin_device(struct pci_dev *pdev)
+{
+ struct pci_devres *dr;
+
+ dr = find_pci_dr(pdev);
+ WARN_ON(!dr || !dr->disable);
+ if (dr)
+ dr->disable = 0;
+}
+
/**
* pcibios_disable_device - disable arch specific PCI resources for device dev
* @dev: the PCI device to disable
@@ -767,8 +865,13 @@ void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {}
void
pci_disable_device(struct pci_dev *dev)
{
+ struct pci_devres *dr;
u16 pci_command;
+ dr = find_pci_dr(dev);
+ if (dr)
+ dr->disable = 0;
+
if (atomic_sub_return(1, &dev->enable_cnt) != 0)
return;
@@ -867,6 +970,8 @@ pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
*/
void pci_release_region(struct pci_dev *pdev, int bar)
{
+ struct pci_devres *dr;
+
if (pci_resource_len(pdev, bar) == 0)
return;
if (pci_resource_flags(pdev, bar) & IORESOURCE_IO)
@@ -875,6 +980,10 @@ void pci_release_region(struct pci_dev *pdev, int bar)
else if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM)
release_mem_region(pci_resource_start(pdev, bar),
pci_resource_len(pdev, bar));
+
+ dr = find_pci_dr(pdev);
+ if (dr)
+ dr->region_mask &= ~(1 << bar);
}
/**
@@ -893,6 +1002,8 @@ void pci_release_region(struct pci_dev *pdev, int bar)
*/
int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
{
+ struct pci_devres *dr;
+
if (pci_resource_len(pdev, bar) == 0)
return 0;
@@ -906,7 +1017,11 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
pci_resource_len(pdev, bar), res_name))
goto err_out;
}
-
+
+ dr = find_pci_dr(pdev);
+ if (dr)
+ dr->region_mask |= 1 << bar;
+
return 0;
err_out:
@@ -1144,7 +1259,15 @@ pci_intx(struct pci_dev *pdev, int enable)
}
if (new != pci_command) {
+ struct pci_devres *dr;
+
pci_write_config_word(pdev, PCI_COMMAND, new);
+
+ dr = find_pci_dr(pdev);
+ if (dr && !dr->restore_intx) {
+ dr->restore_intx = 1;
+ dr->orig_intx = !enable;
+ }
}
}
@@ -1226,6 +1349,8 @@ device_initcall(pci_init);
EXPORT_SYMBOL_GPL(pci_restore_bars);
EXPORT_SYMBOL(pci_enable_device_bars);
EXPORT_SYMBOL(pci_enable_device);
+EXPORT_SYMBOL(pcim_enable_device);
+EXPORT_SYMBOL(pcim_pin_device);
EXPORT_SYMBOL(pci_disable_device);
EXPORT_SYMBOL(pci_find_capability);
EXPORT_SYMBOL(pci_bus_find_capability);
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 4a6760a3b31f..ed87aa59f0b1 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -287,7 +287,7 @@ static int proc_bus_pci_release(struct inode *inode, struct file *file)
}
#endif /* HAVE_PCI_MMAP */
-static struct file_operations proc_bus_pci_operations = {
+static const struct file_operations proc_bus_pci_operations = {
.llseek = proc_bus_pci_lseek,
.read = proc_bus_pci_read,
.write = proc_bus_pci_write,
@@ -456,7 +456,7 @@ static int proc_bus_pci_dev_open(struct inode *inode, struct file *file)
{
return seq_open(file, &proc_bus_pci_devices_op);
}
-static struct file_operations proc_bus_pci_dev_operations = {
+static const struct file_operations proc_bus_pci_dev_operations = {
.open = proc_bus_pci_dev_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 11217bda4b9e..1e6eda25c0d8 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -871,7 +871,7 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0xa, 6);
pci_write_config_byte(pdev, 0x40, tmp);
- pdev->class = 0x010601;
+ pdev->class = PCI_CLASS_STORAGE_SATA_AHCI;
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 88494149e910..27523c5f4dad 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -765,7 +765,7 @@ free_out:
/*====================================================================*/
-static struct file_operations ds_fops = {
+static const struct file_operations ds_fops = {
.owner = THIS_MODULE,
.open = ds_open,
.release = ds_release,
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 6b8c4cfd02a6..31a633f65547 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -1,4 +1,3 @@
-extern struct bus_type pnp_bus_type;
extern spinlock_t pnp_lock;
void *pnp_alloc(long size);
int pnp_interface_attach_device(struct pnp_dev *dev);
diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c
index d21f3c1e72fc..40b724ebe23b 100644
--- a/drivers/pnp/isapnp/proc.c
+++ b/drivers/pnp/isapnp/proc.c
@@ -85,7 +85,7 @@ static ssize_t isapnp_proc_bus_read(struct file *file, char __user *buf, size_t
return nbytes;
}
-static struct file_operations isapnp_proc_bus_file_operations =
+static const struct file_operations isapnp_proc_bus_file_operations =
{
.llseek = isapnp_proc_bus_lseek,
.read = isapnp_proc_bus_read,
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 95b79685a9d1..3c2ab8394e3f 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -530,7 +530,6 @@ pnpbios_parse_compatible_ids(unsigned char *p, unsigned char *end, struct pnp_de
dev_id = kzalloc(sizeof (struct pnp_id), GFP_KERNEL);
if (!dev_id)
return NULL;
- memset(dev_id, 0, sizeof(struct pnp_id));
pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24,id);
memcpy(&dev_id->id, id, 7);
pnp_add_id(dev_id, dev);
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile
index d547cf50ca9d..96958c03cf61 100644
--- a/drivers/ps3/Makefile
+++ b/drivers/ps3/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_PS3_VUART) += vuart.o
+obj-$(CONFIG_PS3_PS3AV) += ps3av.o ps3av_cmd.o
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
new file mode 100644
index 000000000000..1926b4d3e1f4
--- /dev/null
+++ b/drivers/ps3/ps3av.c
@@ -0,0 +1,974 @@
+/*
+ * Copyright (C) 2006 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation
+ *
+ * AV backend support for PS3
+ *
+ * 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 of the License.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/kernel.h>
+#include <linux/ioctl.h>
+#include <asm/lv1call.h>
+#include <asm/ps3av.h>
+#include <asm/ps3.h>
+
+#include "vuart.h"
+
+#define BUFSIZE 4096 /* vuart buf size */
+#define PS3AV_BUF_SIZE 512 /* max packet size */
+
+static int timeout = 5000; /* in msec ( 5 sec ) */
+module_param(timeout, int, 0644);
+
+static struct ps3av ps3av;
+
+static struct ps3_vuart_port_device ps3av_dev = {
+ .match_id = PS3_MATCH_ID_AV_SETTINGS
+};
+
+/* color space */
+#define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8
+#define RGB8 PS3AV_CMD_VIDEO_CS_RGB_8
+/* format */
+#define XRGB PS3AV_CMD_VIDEO_FMT_X8R8G8B8
+/* aspect */
+#define A_N PS3AV_CMD_AV_ASPECT_4_3
+#define A_W PS3AV_CMD_AV_ASPECT_16_9
+static const struct avset_video_mode {
+ u32 cs;
+ u32 fmt;
+ u32 vid;
+ u32 aspect;
+ u32 x;
+ u32 y;
+ u32 interlace;
+ u32 freq;
+} video_mode_table[] = {
+ { 0, }, /* auto */
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480, 1, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480, 0, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720, 0, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080, 1, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080, 0, 60},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576, 1, 50},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576, 0, 50},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720, 0, 50},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080, 1, 50},
+ {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080, 0, 50},
+ { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768, 0, 60},
+ { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA, A_N, 1280, 1024, 0, 60},
+ { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA, A_W, 1920, 1200, 0, 60},
+};
+
+/* supported CIDs */
+static u32 cmd_table[] = {
+ /* init */
+ PS3AV_CID_AV_INIT,
+ PS3AV_CID_AV_FIN,
+ PS3AV_CID_VIDEO_INIT,
+ PS3AV_CID_AUDIO_INIT,
+
+ /* set */
+ PS3AV_CID_AV_ENABLE_EVENT,
+ PS3AV_CID_AV_DISABLE_EVENT,
+
+ PS3AV_CID_AV_VIDEO_CS,
+ PS3AV_CID_AV_VIDEO_MUTE,
+ PS3AV_CID_AV_VIDEO_DISABLE_SIG,
+ PS3AV_CID_AV_AUDIO_PARAM,
+ PS3AV_CID_AV_AUDIO_MUTE,
+ PS3AV_CID_AV_HDMI_MODE,
+ PS3AV_CID_AV_TV_MUTE,
+
+ PS3AV_CID_VIDEO_MODE,
+ PS3AV_CID_VIDEO_FORMAT,
+ PS3AV_CID_VIDEO_PITCH,
+
+ PS3AV_CID_AUDIO_MODE,
+ PS3AV_CID_AUDIO_MUTE,
+ PS3AV_CID_AUDIO_ACTIVE,
+ PS3AV_CID_AUDIO_INACTIVE,
+ PS3AV_CID_AVB_PARAM,
+
+ /* get */
+ PS3AV_CID_AV_GET_HW_CONF,
+ PS3AV_CID_AV_GET_MONITOR_INFO,
+
+ /* event */
+ PS3AV_CID_EVENT_UNPLUGGED,
+ PS3AV_CID_EVENT_PLUGGED,
+ PS3AV_CID_EVENT_HDCP_DONE,
+ PS3AV_CID_EVENT_HDCP_FAIL,
+ PS3AV_CID_EVENT_HDCP_AUTH,
+ PS3AV_CID_EVENT_HDCP_ERROR,
+
+ 0
+};
+
+#define PS3AV_EVENT_CMD_MASK 0x10000000
+#define PS3AV_EVENT_ID_MASK 0x0000ffff
+#define PS3AV_CID_MASK 0xffffffff
+#define PS3AV_REPLY_BIT 0x80000000
+
+#define ps3av_event_get_port_id(cid) ((cid >> 16) & 0xff)
+
+static u32 *ps3av_search_cmd_table(u32 cid, u32 mask)
+{
+ u32 *table;
+ int i;
+
+ table = cmd_table;
+ for (i = 0;; table++, i++) {
+ if ((*table & mask) == (cid & mask))
+ break;
+ if (*table == 0)
+ return NULL;
+ }
+ return table;
+}
+
+static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr)
+{
+ u32 *table;
+
+ if (hdr->cid & PS3AV_EVENT_CMD_MASK) {
+ table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK);
+ if (table)
+ dev_dbg(&ps3av_dev.core,
+ "recv event packet cid:%08x port:0x%x size:%d\n",
+ hdr->cid, ps3av_event_get_port_id(hdr->cid),
+ hdr->size);
+ else
+ printk(KERN_ERR
+ "%s: failed event packet, cid:%08x size:%d\n",
+ __FUNCTION__, hdr->cid, hdr->size);
+ return 1; /* receive event packet */
+ }
+ return 0;
+}
+
+static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
+ struct ps3av_reply_hdr *recv_buf, int write_len,
+ int read_len)
+{
+ int res;
+ u32 cmd;
+ int event;
+
+ if (!ps3av.available)
+ return -ENODEV;
+
+ /* send pkt */
+ res = ps3av_vuart_write(ps3av.dev, send_buf, write_len);
+ if (res < 0) {
+ dev_dbg(&ps3av_dev.core,
+ "%s: ps3av_vuart_write() failed (result=%d)\n",
+ __FUNCTION__, res);
+ return res;
+ }
+
+ /* recv pkt */
+ cmd = send_buf->cid;
+ do {
+ /* read header */
+ res = ps3av_vuart_read(ps3av.dev, recv_buf, PS3AV_HDR_SIZE,
+ timeout);
+ if (res != PS3AV_HDR_SIZE) {
+ dev_dbg(&ps3av_dev.core,
+ "%s: ps3av_vuart_read() failed (result=%d)\n",
+ __FUNCTION__, res);
+ return res;
+ }
+
+ /* read body */
+ res = ps3av_vuart_read(ps3av.dev, &recv_buf->cid,
+ recv_buf->size, timeout);
+ if (res < 0) {
+ dev_dbg(&ps3av_dev.core,
+ "%s: ps3av_vuart_read() failed (result=%d)\n",
+ __FUNCTION__, res);
+ return res;
+ }
+ res += PS3AV_HDR_SIZE; /* total len */
+ event = ps3av_parse_event_packet(recv_buf);
+ /* ret > 0 event packet */
+ } while (event);
+
+ if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) {
+ dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n",
+ __FUNCTION__, recv_buf->cid);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ps3av_process_reply_packet(struct ps3av_send_hdr *cmd_buf,
+ const struct ps3av_reply_hdr *recv_buf,
+ int user_buf_size)
+{
+ int return_len;
+
+ if (recv_buf->version != PS3AV_VERSION) {
+ dev_dbg(&ps3av_dev.core, "reply_packet invalid version:%x\n",
+ recv_buf->version);
+ return -EFAULT;
+ }
+ return_len = recv_buf->size + PS3AV_HDR_SIZE;
+ if (return_len > user_buf_size)
+ return_len = user_buf_size;
+ memcpy(cmd_buf, recv_buf, return_len);
+ return 0; /* success */
+}
+
+void ps3av_set_hdr(u32 cid, u16 size, struct ps3av_send_hdr *hdr)
+{
+ hdr->version = PS3AV_VERSION;
+ hdr->size = size - PS3AV_HDR_SIZE;
+ hdr->cid = cid;
+}
+
+int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
+ struct ps3av_send_hdr *buf)
+{
+ int res = 0;
+ union {
+ struct ps3av_reply_hdr reply_hdr;
+ u8 raw[PS3AV_BUF_SIZE];
+ } recv_buf;
+
+ u32 *table;
+
+ BUG_ON(!ps3av.available);
+
+ if (down_interruptible(&ps3av.sem))
+ return -ERESTARTSYS;
+
+ table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK);
+ BUG_ON(!table);
+ BUG_ON(send_len < PS3AV_HDR_SIZE);
+ BUG_ON(usr_buf_size < send_len);
+ BUG_ON(usr_buf_size > PS3AV_BUF_SIZE);
+
+ /* create header */
+ ps3av_set_hdr(cid, send_len, buf);
+
+ /* send packet via vuart */
+ res = ps3av_send_cmd_pkt(buf, &recv_buf.reply_hdr, send_len,
+ usr_buf_size);
+ if (res < 0) {
+ printk(KERN_ERR
+ "%s: ps3av_send_cmd_pkt() failed (result=%d)\n",
+ __FUNCTION__, res);
+ goto err;
+ }
+
+ /* process reply packet */
+ res = ps3av_process_reply_packet(buf, &recv_buf.reply_hdr,
+ usr_buf_size);
+ if (res < 0) {
+ printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n",
+ __FUNCTION__, res);
+ goto err;
+ }
+
+ up(&ps3av.sem);
+ return 0;
+
+ err:
+ up(&ps3av.sem);
+ printk(KERN_ERR "%s: failed cid:%x res:%d\n", __FUNCTION__, cid, res);
+ return res;
+}
+
+static int ps3av_set_av_video_mute(u32 mute)
+{
+ int i, num_of_av_port, res;
+
+ num_of_av_port = ps3av.av_hw_conf.num_of_hdmi +
+ ps3av.av_hw_conf.num_of_avmulti;
+ /* video mute on */
+ for (i = 0; i < num_of_av_port; i++) {
+ res = ps3av_cmd_av_video_mute(1, &ps3av.av_port[i], mute);
+ if (res < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int ps3av_set_video_disable_sig(void)
+{
+ int i, num_of_hdmi_port, num_of_av_port, res;
+
+ num_of_hdmi_port = ps3av.av_hw_conf.num_of_hdmi;
+ num_of_av_port = ps3av.av_hw_conf.num_of_hdmi +
+ ps3av.av_hw_conf.num_of_avmulti;
+
+ /* tv mute */
+ for (i = 0; i < num_of_hdmi_port; i++) {
+ res = ps3av_cmd_av_tv_mute(ps3av.av_port[i],
+ PS3AV_CMD_MUTE_ON);
+ if (res < 0)
+ return -1;
+ }
+ msleep(100);
+
+ /* video mute on */
+ for (i = 0; i < num_of_av_port; i++) {
+ res = ps3av_cmd_av_video_disable_sig(ps3av.av_port[i]);
+ if (res < 0)
+ return -1;
+ if (i < num_of_hdmi_port) {
+ res = ps3av_cmd_av_tv_mute(ps3av.av_port[i],
+ PS3AV_CMD_MUTE_OFF);
+ if (res < 0)
+ return -1;
+ }
+ }
+ msleep(300);
+
+ return 0;
+}
+
+static int ps3av_set_audio_mute(u32 mute)
+{
+ int i, num_of_av_port, num_of_opt_port, res;
+
+ num_of_av_port = ps3av.av_hw_conf.num_of_hdmi +
+ ps3av.av_hw_conf.num_of_avmulti;
+ num_of_opt_port = ps3av.av_hw_conf.num_of_spdif;
+
+ for (i = 0; i < num_of_av_port; i++) {
+ res = ps3av_cmd_av_audio_mute(1, &ps3av.av_port[i], mute);
+ if (res < 0)
+ return -1;
+ }
+ for (i = 0; i < num_of_opt_port; i++) {
+ res = ps3av_cmd_audio_mute(1, &ps3av.opt_port[i], mute);
+ if (res < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source)
+{
+ struct ps3av_pkt_avb_param avb_param;
+ int i, num_of_audio, vid, res;
+ struct ps3av_pkt_audio_mode audio_mode;
+ u32 len = 0;
+
+ num_of_audio = ps3av.av_hw_conf.num_of_hdmi +
+ ps3av.av_hw_conf.num_of_avmulti +
+ ps3av.av_hw_conf.num_of_spdif;
+
+ avb_param.num_of_video_pkt = 0;
+ avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */
+ avb_param.num_of_av_video_pkt = 0;
+ avb_param.num_of_av_audio_pkt = ps3av.av_hw_conf.num_of_hdmi;
+
+ vid = video_mode_table[ps3av.ps3av_mode].vid;
+
+ /* audio mute */
+ ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON);
+
+ /* audio inactive */
+ res = ps3av_cmd_audio_active(0, ps3av.audio_port);
+ if (res < 0)
+ dev_dbg(&ps3av_dev.core,
+ "ps3av_cmd_audio_active OFF failed\n");
+
+ /* audio_pkt */
+ for (i = 0; i < num_of_audio; i++) {
+ ps3av_cmd_set_audio_mode(&audio_mode, ps3av.av_port[i], ch, fs,
+ word_bits, format, source);
+ if (i < ps3av.av_hw_conf.num_of_hdmi) {
+ /* hdmi only */
+ len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len],
+ ps3av.av_port[i],
+ &audio_mode, vid);
+ }
+ /* audio_mode pkt should be sent separately */
+ res = ps3av_cmd_audio_mode(&audio_mode);
+ if (res < 0)
+ dev_dbg(&ps3av_dev.core,
+ "ps3av_cmd_audio_mode failed, port:%x\n", i);
+ }
+
+ /* send command using avb pkt */
+ len += offsetof(struct ps3av_pkt_avb_param, buf);
+ res = ps3av_cmd_avb_param(&avb_param, len);
+ if (res < 0)
+ dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n");
+
+ /* audio mute */
+ ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF);
+
+ /* audio active */
+ res = ps3av_cmd_audio_active(1, ps3av.audio_port);
+ if (res < 0)
+ dev_dbg(&ps3av_dev.core, "ps3av_cmd_audio_active ON failed\n");
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_set_audio_mode);
+
+static int ps3av_set_videomode(void)
+{
+ /* av video mute */
+ ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON);
+
+ /* wake up ps3avd to do the actual video mode setting */
+ up(&ps3av.ping);
+
+ return 0;
+}
+
+static void ps3av_set_videomode_cont(u32 id, u32 old_id)
+{
+ struct ps3av_pkt_avb_param avb_param;
+ int i;
+ u32 len = 0, av_video_cs;
+ const struct avset_video_mode *video_mode;
+ int res;
+
+ video_mode = &video_mode_table[id & PS3AV_MODE_MASK];
+
+ avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */
+ avb_param.num_of_audio_pkt = 0;
+ avb_param.num_of_av_video_pkt = ps3av.av_hw_conf.num_of_hdmi +
+ ps3av.av_hw_conf.num_of_avmulti;
+ avb_param.num_of_av_audio_pkt = 0;
+
+ /* video signal off */
+ ps3av_set_video_disable_sig();
+
+ /* Retail PS3 product doesn't support this */
+ if (id & PS3AV_MODE_HDCP_OFF) {
+ res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
+ if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
+ dev_dbg(&ps3av_dev.core, "Not supported\n");
+ else if (res)
+ dev_dbg(&ps3av_dev.core,
+ "ps3av_cmd_av_hdmi_mode failed\n");
+ } else if (old_id & PS3AV_MODE_HDCP_OFF) {
+ res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
+ if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
+ dev_dbg(&ps3av_dev.core,
+ "ps3av_cmd_av_hdmi_mode failed\n");
+ }
+
+ /* video_pkt */
+ for (i = 0; i < avb_param.num_of_video_pkt; i++)
+ len += ps3av_cmd_set_video_mode(&avb_param.buf[len],
+ ps3av.head[i], video_mode->vid,
+ video_mode->fmt, id);
+ /* av_video_pkt */
+ for (i = 0; i < avb_param.num_of_av_video_pkt; i++) {
+ if (id & PS3AV_MODE_DVI || id & PS3AV_MODE_RGB)
+ av_video_cs = RGB8;
+ else
+ av_video_cs = video_mode->cs;
+#ifndef PS3AV_HDMI_YUV
+ if (ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 ||
+ ps3av.av_port[i] == PS3AV_CMD_AVPORT_HDMI_1)
+ av_video_cs = RGB8; /* use RGB for HDMI */
+#endif
+ len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len],
+ ps3av.av_port[i],
+ video_mode->vid, av_video_cs,
+ video_mode->aspect, id);
+ }
+ /* send command using avb pkt */
+ len += offsetof(struct ps3av_pkt_avb_param, buf);
+ res = ps3av_cmd_avb_param(&avb_param, len);
+ if (res == PS3AV_STATUS_NO_SYNC_HEAD)
+ printk(KERN_WARNING
+ "%s: Command failed. Please try your request again. \n",
+ __FUNCTION__);
+ else if (res)
+ dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n");
+
+ msleep(1500);
+ /* av video mute */
+ ps3av_set_av_video_mute(PS3AV_CMD_MUTE_OFF);
+}
+
+static int ps3avd(void *p)
+{
+ struct ps3av *info = p;
+
+ daemonize("ps3avd");
+ while (1) {
+ down(&info->ping);
+ ps3av_set_videomode_cont(info->ps3av_mode,
+ info->ps3av_mode_old);
+ up(&info->pong);
+ }
+ return 0;
+}
+
+static int ps3av_vid2table_id(int vid)
+{
+ int i;
+
+ for (i = 1; i < ARRAY_SIZE(video_mode_table); i++)
+ if (video_mode_table[i].vid == vid)
+ return i;
+ return -1;
+}
+
+static int ps3av_resbit2vid(u32 res_50, u32 res_60)
+{
+ int vid = -1;
+
+ if (res_50 > res_60) { /* if res_50 == res_60, res_60 will be used */
+ if (res_50 & PS3AV_RESBIT_1920x1080P)
+ vid = PS3AV_CMD_VIDEO_VID_1080P_50HZ;
+ else if (res_50 & PS3AV_RESBIT_1920x1080I)
+ vid = PS3AV_CMD_VIDEO_VID_1080I_50HZ;
+ else if (res_50 & PS3AV_RESBIT_1280x720P)
+ vid = PS3AV_CMD_VIDEO_VID_720P_50HZ;
+ else if (res_50 & PS3AV_RESBIT_720x576P)
+ vid = PS3AV_CMD_VIDEO_VID_576P;
+ else
+ vid = -1;
+ } else {
+ if (res_60 & PS3AV_RESBIT_1920x1080P)
+ vid = PS3AV_CMD_VIDEO_VID_1080P_60HZ;
+ else if (res_60 & PS3AV_RESBIT_1920x1080I)
+ vid = PS3AV_CMD_VIDEO_VID_1080I_60HZ;
+ else if (res_60 & PS3AV_RESBIT_1280x720P)
+ vid = PS3AV_CMD_VIDEO_VID_720P_60HZ;
+ else if (res_60 & PS3AV_RESBIT_720x480P)
+ vid = PS3AV_CMD_VIDEO_VID_480P;
+ else
+ vid = -1;
+ }
+ return vid;
+}
+
+static int ps3av_hdmi_get_vid(struct ps3av_info_monitor *info)
+{
+ u32 res_50, res_60;
+ int vid = -1;
+
+ if (info->monitor_type != PS3AV_MONITOR_TYPE_HDMI)
+ return -1;
+
+ /* check native resolution */
+ res_50 = info->res_50.native & PS3AV_RES_MASK_50;
+ res_60 = info->res_60.native & PS3AV_RES_MASK_60;
+ if (res_50 || res_60) {
+ vid = ps3av_resbit2vid(res_50, res_60);
+ return vid;
+ }
+
+ /* check resolution */
+ res_50 = info->res_50.res_bits & PS3AV_RES_MASK_50;
+ res_60 = info->res_60.res_bits & PS3AV_RES_MASK_60;
+ if (res_50 || res_60) {
+ vid = ps3av_resbit2vid(res_50, res_60);
+ return vid;
+ }
+
+ if (ps3av.region & PS3AV_REGION_60)
+ vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
+ else
+ vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
+ return vid;
+}
+
+static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf,
+ int boot)
+{
+ int i, res, vid = -1, dvi = 0, rgb = 0;
+ struct ps3av_pkt_av_get_monitor_info monitor_info;
+ struct ps3av_info_monitor *info;
+
+ /* get vid for hdmi */
+ for (i = 0; i < av_hw_conf->num_of_hdmi; i++) {
+ res = ps3av_cmd_video_get_monitor_info(&monitor_info,
+ PS3AV_CMD_AVPORT_HDMI_0 +
+ i);
+ if (res < 0)
+ return -1;
+
+ ps3av_cmd_av_monitor_info_dump(&monitor_info);
+ info = &monitor_info.info;
+ /* check DVI */
+ if (info->monitor_type == PS3AV_MONITOR_TYPE_DVI) {
+ dvi = PS3AV_MODE_DVI;
+ break;
+ }
+ /* check HDMI */
+ vid = ps3av_hdmi_get_vid(info);
+ if (vid != -1) {
+ /* got valid vid */
+ break;
+ }
+ }
+
+ if (dvi) {
+ /* DVI mode */
+ vid = PS3AV_DEFAULT_DVI_VID;
+ } else if (vid == -1) {
+ /* no HDMI interface or HDMI is off */
+ if (ps3av.region & PS3AV_REGION_60)
+ vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60;
+ else
+ vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50;
+ if (ps3av.region & PS3AV_REGION_RGB)
+ rgb = PS3AV_MODE_RGB;
+ } else if (boot) {
+ /* HDMI: using DEFAULT HDMI_VID while booting up */
+ info = &monitor_info.info;
+ if (ps3av.region & PS3AV_REGION_60) {
+ if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
+ vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
+ else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
+ vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
+ else {
+ /* default */
+ vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
+ }
+ } else {
+ if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
+ vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
+ else if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
+ vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
+ else {
+ /* default */
+ vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
+ }
+ }
+ }
+
+ return (ps3av_vid2table_id(vid) | dvi | rgb);
+}
+
+static int ps3av_get_hw_conf(struct ps3av *ps3av)
+{
+ int i, j, k, res;
+
+ /* get av_hw_conf */
+ res = ps3av_cmd_av_get_hw_conf(&ps3av->av_hw_conf);
+ if (res < 0)
+ return -1;
+
+ ps3av_cmd_av_hw_conf_dump(&ps3av->av_hw_conf);
+
+ for (i = 0; i < PS3AV_HEAD_MAX; i++)
+ ps3av->head[i] = PS3AV_CMD_VIDEO_HEAD_A + i;
+ for (i = 0; i < PS3AV_OPT_PORT_MAX; i++)
+ ps3av->opt_port[i] = PS3AV_CMD_AVPORT_SPDIF_0 + i;
+ for (i = 0; i < ps3av->av_hw_conf.num_of_hdmi; i++)
+ ps3av->av_port[i] = PS3AV_CMD_AVPORT_HDMI_0 + i;
+ for (j = 0; j < ps3av->av_hw_conf.num_of_avmulti; j++)
+ ps3av->av_port[i + j] = PS3AV_CMD_AVPORT_AVMULTI_0 + j;
+ for (k = 0; k < ps3av->av_hw_conf.num_of_spdif; k++)
+ ps3av->av_port[i + j + k] = PS3AV_CMD_AVPORT_SPDIF_0 + k;
+
+ /* set all audio port */
+ ps3av->audio_port = PS3AV_CMD_AUDIO_PORT_HDMI_0
+ | PS3AV_CMD_AUDIO_PORT_HDMI_1
+ | PS3AV_CMD_AUDIO_PORT_AVMULTI_0
+ | PS3AV_CMD_AUDIO_PORT_SPDIF_0 | PS3AV_CMD_AUDIO_PORT_SPDIF_1;
+
+ return 0;
+}
+
+/* set mode using id */
+int ps3av_set_video_mode(u32 id, int boot)
+{
+ int size;
+ u32 option;
+
+ size = ARRAY_SIZE(video_mode_table);
+ if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) {
+ dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __FUNCTION__,
+ id);
+ return -EINVAL;
+ }
+
+ /* auto mode */
+ option = id & ~PS3AV_MODE_MASK;
+ if ((id & PS3AV_MODE_MASK) == 0) {
+ id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot);
+ if (id < 1) {
+ printk(KERN_ERR "%s: invalid id :%d\n", __FUNCTION__,
+ id);
+ return -EINVAL;
+ }
+ id |= option;
+ }
+
+ /* set videomode */
+ down(&ps3av.pong);
+ ps3av.ps3av_mode_old = ps3av.ps3av_mode;
+ ps3av.ps3av_mode = id;
+ if (ps3av_set_videomode())
+ ps3av.ps3av_mode = ps3av.ps3av_mode_old;
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
+
+int ps3av_set_mode(u32 id, int boot)
+{
+ int res;
+
+ res = ps3av_set_video_mode(id, boot);
+ if (res)
+ return res;
+
+ res = ps3av_set_audio_mode(PS3AV_CMD_AUDIO_NUM_OF_CH_2,
+ PS3AV_CMD_AUDIO_FS_48K,
+ PS3AV_CMD_AUDIO_WORD_BITS_16,
+ PS3AV_CMD_AUDIO_FORMAT_PCM,
+ PS3AV_CMD_AUDIO_SOURCE_SERIAL);
+ if (res)
+ return res;
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_set_mode);
+
+int ps3av_get_mode(void)
+{
+ return ps3av.ps3av_mode;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_get_mode);
+
+int ps3av_get_scanmode(int id)
+{
+ int size;
+
+ id = id & PS3AV_MODE_MASK;
+ size = ARRAY_SIZE(video_mode_table);
+ if (id > size - 1 || id < 0) {
+ printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id);
+ return -EINVAL;
+ }
+ return video_mode_table[id].interlace;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_get_scanmode);
+
+int ps3av_get_refresh_rate(int id)
+{
+ int size;
+
+ id = id & PS3AV_MODE_MASK;
+ size = ARRAY_SIZE(video_mode_table);
+ if (id > size - 1 || id < 0) {
+ printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id);
+ return -EINVAL;
+ }
+ return video_mode_table[id].freq;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_get_refresh_rate);
+
+/* get resolution by video_mode */
+int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres)
+{
+ int size;
+
+ id = id & PS3AV_MODE_MASK;
+ size = ARRAY_SIZE(video_mode_table);
+ if (id > size - 1 || id < 0) {
+ printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id);
+ return -EINVAL;
+ }
+ *xres = video_mode_table[id].x;
+ *yres = video_mode_table[id].y;
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_video_mode2res);
+
+/* mute */
+int ps3av_video_mute(int mute)
+{
+ return ps3av_set_av_video_mute(mute ? PS3AV_CMD_MUTE_ON
+ : PS3AV_CMD_MUTE_OFF);
+}
+
+EXPORT_SYMBOL_GPL(ps3av_video_mute);
+
+int ps3av_audio_mute(int mute)
+{
+ return ps3av_set_audio_mute(mute ? PS3AV_CMD_MUTE_ON
+ : PS3AV_CMD_MUTE_OFF);
+}
+
+EXPORT_SYMBOL_GPL(ps3av_audio_mute);
+
+int ps3av_dev_open(void)
+{
+ int status = 0;
+
+ mutex_lock(&ps3av.mutex);
+ if (!ps3av.open_count++) {
+ status = lv1_gpu_open(0);
+ if (status) {
+ printk(KERN_ERR "%s: lv1_gpu_open failed %d\n",
+ __FUNCTION__, status);
+ ps3av.open_count--;
+ }
+ }
+ mutex_unlock(&ps3av.mutex);
+
+ return status;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_dev_open);
+
+int ps3av_dev_close(void)
+{
+ int status = 0;
+
+ mutex_lock(&ps3av.mutex);
+ if (ps3av.open_count <= 0) {
+ printk(KERN_ERR "%s: GPU already closed\n", __FUNCTION__);
+ status = -1;
+ } else if (!--ps3av.open_count) {
+ status = lv1_gpu_close();
+ if (status)
+ printk(KERN_WARNING "%s: lv1_gpu_close failed %d\n",
+ __FUNCTION__, status);
+ }
+ mutex_unlock(&ps3av.mutex);
+
+ return status;
+}
+
+EXPORT_SYMBOL_GPL(ps3av_dev_close);
+
+static int ps3av_probe(struct ps3_vuart_port_device *dev)
+{
+ int res;
+ u32 id;
+
+ dev_dbg(&ps3av_dev.core, "init ...\n");
+ dev_dbg(&ps3av_dev.core, " timeout=%d\n", timeout);
+
+ memset(&ps3av, 0, sizeof(ps3av));
+
+ init_MUTEX(&ps3av.sem);
+ init_MUTEX_LOCKED(&ps3av.ping);
+ init_MUTEX(&ps3av.pong);
+ mutex_init(&ps3av.mutex);
+ ps3av.ps3av_mode = 0;
+ ps3av.dev = dev;
+ kernel_thread(ps3avd, &ps3av, CLONE_KERNEL);
+
+ ps3av.available = 1;
+ switch (ps3_os_area_get_av_multi_out()) {
+ case PS3_PARAM_AV_MULTI_OUT_NTSC:
+ ps3av.region = PS3AV_REGION_60;
+ break;
+ case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR:
+ case PS3_PARAM_AV_MULTI_OUT_SECAM:
+ ps3av.region = PS3AV_REGION_50;
+ break;
+ case PS3_PARAM_AV_MULTI_OUT_PAL_RGB:
+ ps3av.region = PS3AV_REGION_50 | PS3AV_REGION_RGB;
+ break;
+ default:
+ ps3av.region = PS3AV_REGION_60;
+ break;
+ }
+
+ /* init avsetting modules */
+ res = ps3av_cmd_init();
+ if (res < 0)
+ printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __FUNCTION__,
+ res);
+
+ ps3av_get_hw_conf(&ps3av);
+ id = ps3av_auto_videomode(&ps3av.av_hw_conf, 1);
+ mutex_lock(&ps3av.mutex);
+ ps3av.ps3av_mode = id;
+ mutex_unlock(&ps3av.mutex);
+
+ dev_dbg(&ps3av_dev.core, "init...done\n");
+
+ return 0;
+}
+
+static int ps3av_remove(struct ps3_vuart_port_device *dev)
+{
+ if (ps3av.available) {
+ ps3av_cmd_fin();
+ ps3av.available = 0;
+ }
+
+ return 0;
+}
+
+static void ps3av_shutdown(struct ps3_vuart_port_device *dev)
+{
+ ps3av_remove(dev);
+}
+
+static struct ps3_vuart_port_driver ps3av_driver = {
+ .match_id = PS3_MATCH_ID_AV_SETTINGS,
+ .core = {
+ .name = "ps3_av",
+ },
+ .probe = ps3av_probe,
+ .remove = ps3av_remove,
+ .shutdown = ps3av_shutdown,
+};
+
+static int ps3av_module_init(void)
+{
+ int error = ps3_vuart_port_driver_register(&ps3av_driver);
+ if (error) {
+ printk(KERN_ERR
+ "%s: ps3_vuart_port_driver_register failed %d\n",
+ __FUNCTION__, error);
+ return error;
+ }
+
+ error = ps3_vuart_port_device_register(&ps3av_dev);
+ if (error)
+ printk(KERN_ERR
+ "%s: ps3_vuart_port_device_register failed %d\n",
+ __FUNCTION__, error);
+
+ return error;
+}
+
+static void __exit ps3av_module_exit(void)
+{
+ device_unregister(&ps3av_dev.core);
+ ps3_vuart_port_driver_unregister(&ps3av_driver);
+}
+
+subsys_initcall(ps3av_module_init);
+module_exit(ps3av_module_exit);
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
new file mode 100644
index 000000000000..21c97c80aa2e
--- /dev/null
+++ b/drivers/ps3/ps3av_cmd.c
@@ -0,0 +1,1020 @@
+/*
+ * Copyright (C) 2006 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation
+ *
+ * AV backend support for PS3
+ *
+ * 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 of the License.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <asm/ps3av.h>
+#include <asm/ps3fb.h>
+#include <asm/ps3.h>
+
+#include "vuart.h"
+
+static const struct video_fmt {
+ u32 format;
+ u32 order;
+} ps3av_video_fmt_table[] = {
+ { PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT, PS3AV_CMD_VIDEO_ORDER_RGB },
+ { PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT, PS3AV_CMD_VIDEO_ORDER_BGR },
+};
+
+static const struct {
+ int cs;
+ u32 av;
+ u32 bl;
+} ps3av_cs_video2av_table[] = {
+ {
+ .cs = PS3AV_CMD_VIDEO_CS_RGB_8,
+ .av = PS3AV_CMD_AV_CS_RGB_8,
+ .bl = PS3AV_CMD_AV_CS_8
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_RGB_10,
+ .av = PS3AV_CMD_AV_CS_RGB_8,
+ .bl = PS3AV_CMD_AV_CS_8
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_RGB_12,
+ .av = PS3AV_CMD_AV_CS_RGB_8,
+ .bl = PS3AV_CMD_AV_CS_8
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_YUV444_8,
+ .av = PS3AV_CMD_AV_CS_YUV444_8,
+ .bl = PS3AV_CMD_AV_CS_8
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_YUV444_10,
+ .av = PS3AV_CMD_AV_CS_YUV444_8,
+ .bl = PS3AV_CMD_AV_CS_10
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_YUV444_12,
+ .av = PS3AV_CMD_AV_CS_YUV444_8,
+ .bl = PS3AV_CMD_AV_CS_10
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_YUV422_8,
+ .av = PS3AV_CMD_AV_CS_YUV422_8,
+ .bl = PS3AV_CMD_AV_CS_10
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_YUV422_10,
+ .av = PS3AV_CMD_AV_CS_YUV422_8,
+ .bl = PS3AV_CMD_AV_CS_10
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_YUV422_12,
+ .av = PS3AV_CMD_AV_CS_YUV422_8,
+ .bl = PS3AV_CMD_AV_CS_12
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_XVYCC_8,
+ .av = PS3AV_CMD_AV_CS_XVYCC_8,
+ .bl = PS3AV_CMD_AV_CS_12
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_XVYCC_10,
+ .av = PS3AV_CMD_AV_CS_XVYCC_8,
+ .bl = PS3AV_CMD_AV_CS_12
+ }, {
+ .cs = PS3AV_CMD_VIDEO_CS_XVYCC_12,
+ .av = PS3AV_CMD_AV_CS_XVYCC_8,
+ .bl = PS3AV_CMD_AV_CS_12
+ }
+};
+
+static u32 ps3av_cs_video2av(int cs)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ps3av_cs_video2av_table); i++)
+ if (ps3av_cs_video2av_table[i].cs == cs)
+ return ps3av_cs_video2av_table[i].av;
+
+ return PS3AV_CMD_AV_CS_RGB_8;
+}
+
+static u32 ps3av_cs_video2av_bitlen(int cs)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ps3av_cs_video2av_table); i++)
+ if (ps3av_cs_video2av_table[i].cs == cs)
+ return ps3av_cs_video2av_table[i].bl;
+
+ return PS3AV_CMD_AV_CS_8;
+}
+
+static const struct {
+ int vid;
+ u32 av;
+} ps3av_vid_video2av_table[] = {
+ { PS3AV_CMD_VIDEO_VID_480I, PS3AV_CMD_AV_VID_480I },
+ { PS3AV_CMD_VIDEO_VID_480P, PS3AV_CMD_AV_VID_480P },
+ { PS3AV_CMD_VIDEO_VID_576I, PS3AV_CMD_AV_VID_576I },
+ { PS3AV_CMD_VIDEO_VID_576P, PS3AV_CMD_AV_VID_576P },
+ { PS3AV_CMD_VIDEO_VID_1080I_60HZ, PS3AV_CMD_AV_VID_1080I_60HZ },
+ { PS3AV_CMD_VIDEO_VID_720P_60HZ, PS3AV_CMD_AV_VID_720P_60HZ },
+ { PS3AV_CMD_VIDEO_VID_1080P_60HZ, PS3AV_CMD_AV_VID_1080P_60HZ },
+ { PS3AV_CMD_VIDEO_VID_1080I_50HZ, PS3AV_CMD_AV_VID_1080I_50HZ },
+ { PS3AV_CMD_VIDEO_VID_720P_50HZ, PS3AV_CMD_AV_VID_720P_50HZ },
+ { PS3AV_CMD_VIDEO_VID_1080P_50HZ, PS3AV_CMD_AV_VID_1080P_50HZ },
+ { PS3AV_CMD_VIDEO_VID_WXGA, PS3AV_CMD_AV_VID_WXGA },
+ { PS3AV_CMD_VIDEO_VID_SXGA, PS3AV_CMD_AV_VID_SXGA },
+ { PS3AV_CMD_VIDEO_VID_WUXGA, PS3AV_CMD_AV_VID_WUXGA }
+};
+
+static u32 ps3av_vid_video2av(int vid)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ps3av_vid_video2av_table); i++)
+ if (ps3av_vid_video2av_table[i].vid == vid)
+ return ps3av_vid_video2av_table[i].av;
+
+ return PS3AV_CMD_AV_VID_480P;
+}
+
+int ps3av_cmd_init(void)
+{
+ int res;
+ struct ps3av_pkt_av_init av_init;
+ struct ps3av_pkt_video_init video_init;
+ struct ps3av_pkt_audio_init audio_init;
+
+ /* video init */
+ memset(&video_init, 0, sizeof(video_init));
+
+ res = ps3av_do_pkt(PS3AV_CID_VIDEO_INIT, sizeof(video_init.send_hdr),
+ sizeof(video_init), &video_init.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&video_init);
+ if (res) {
+ printk(KERN_ERR "PS3AV_CID_VIDEO_INIT: failed %x\n", res);
+ return res;
+ }
+
+ /* audio init */
+ memset(&audio_init, 0, sizeof(audio_init));
+
+ res = ps3av_do_pkt(PS3AV_CID_AUDIO_INIT, sizeof(audio_init.send_hdr),
+ sizeof(audio_init), &audio_init.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&audio_init);
+ if (res) {
+ printk(KERN_ERR "PS3AV_CID_AUDIO_INIT: failed %x\n", res);
+ return res;
+ }
+
+ /* av init */
+ memset(&av_init, 0, sizeof(av_init));
+ av_init.event_bit = 0;
+
+ res = ps3av_do_pkt(PS3AV_CID_AV_INIT, sizeof(av_init), sizeof(av_init),
+ &av_init.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&av_init);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AV_INIT: failed %x\n", res);
+
+ return res;
+}
+
+int ps3av_cmd_fin(void)
+{
+ int res;
+ struct ps3av_pkt_av_fin av_fin;
+
+ memset(&av_fin, 0, sizeof(av_fin));
+
+ res = ps3av_do_pkt(PS3AV_CID_AV_FIN, sizeof(av_fin.send_hdr),
+ sizeof(av_fin), &av_fin.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&av_fin);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AV_FIN: failed %x\n", res);
+
+ return res;
+}
+
+int ps3av_cmd_av_video_mute(int num_of_port, u32 *port, u32 mute)
+{
+ int i, send_len, res;
+ struct ps3av_pkt_av_video_mute av_video_mute;
+
+ if (num_of_port > PS3AV_MUTE_PORT_MAX)
+ return -EINVAL;
+
+ memset(&av_video_mute, 0, sizeof(av_video_mute));
+ for (i = 0; i < num_of_port; i++) {
+ av_video_mute.mute[i].avport = port[i];
+ av_video_mute.mute[i].mute = mute;
+ }
+
+ send_len = sizeof(av_video_mute.send_hdr) +
+ sizeof(struct ps3av_av_mute) * num_of_port;
+ res = ps3av_do_pkt(PS3AV_CID_AV_VIDEO_MUTE, send_len,
+ sizeof(av_video_mute), &av_video_mute.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&av_video_mute);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AV_VIDEO_MUTE: failed %x\n", res);
+
+ return res;
+}
+
+int ps3av_cmd_av_video_disable_sig(u32 port)
+{
+ int res;
+ struct ps3av_pkt_av_video_disable_sig av_video_sig;
+
+ memset(&av_video_sig, 0, sizeof(av_video_sig));
+ av_video_sig.avport = port;
+
+ res = ps3av_do_pkt(PS3AV_CID_AV_VIDEO_DISABLE_SIG,
+ sizeof(av_video_sig), sizeof(av_video_sig),
+ &av_video_sig.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&av_video_sig);
+ if (res)
+ printk(KERN_ERR
+ "PS3AV_CID_AV_VIDEO_DISABLE_SIG: failed %x port:%x\n",
+ res, port);
+
+ return res;
+}
+
+int ps3av_cmd_av_tv_mute(u32 avport, u32 mute)
+{
+ int res;
+ struct ps3av_pkt_av_tv_mute tv_mute;
+
+ memset(&tv_mute, 0, sizeof(tv_mute));
+ tv_mute.avport = avport;
+ tv_mute.mute = mute;
+
+ res = ps3av_do_pkt(PS3AV_CID_AV_TV_MUTE, sizeof(tv_mute),
+ sizeof(tv_mute), &tv_mute.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&tv_mute);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AV_TV_MUTE: failed %x port:%x\n",
+ res, avport);
+
+ return res;
+}
+
+int ps3av_cmd_enable_event(void)
+{
+ int res;
+ struct ps3av_pkt_av_event av_event;
+
+ memset(&av_event, 0, sizeof(av_event));
+ av_event.event_bit = PS3AV_CMD_EVENT_BIT_UNPLUGGED |
+ PS3AV_CMD_EVENT_BIT_PLUGGED | PS3AV_CMD_EVENT_BIT_HDCP_DONE;
+
+ res = ps3av_do_pkt(PS3AV_CID_AV_ENABLE_EVENT, sizeof(av_event),
+ sizeof(av_event), &av_event.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&av_event);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AV_ENABLE_EVENT: failed %x\n", res);
+
+ return res;
+}
+
+int ps3av_cmd_av_hdmi_mode(u8 mode)
+{
+ int res;
+ struct ps3av_pkt_av_hdmi_mode hdmi_mode;
+
+ memset(&hdmi_mode, 0, sizeof(hdmi_mode));
+ hdmi_mode.mode = mode;
+
+ res = ps3av_do_pkt(PS3AV_CID_AV_HDMI_MODE, sizeof(hdmi_mode),
+ sizeof(hdmi_mode), &hdmi_mode.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&hdmi_mode);
+ if (res && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
+ printk(KERN_ERR "PS3AV_CID_AV_HDMI_MODE: failed %x\n", res);
+
+ return res;
+}
+
+u32 ps3av_cmd_set_av_video_cs(void *p, u32 avport, int video_vid, int cs_out,
+ int aspect, u32 id)
+{
+ struct ps3av_pkt_av_video_cs *av_video_cs;
+
+ av_video_cs = (struct ps3av_pkt_av_video_cs *)p;
+ if (video_vid == -1)
+ video_vid = PS3AV_CMD_VIDEO_VID_720P_60HZ;
+ if (cs_out == -1)
+ cs_out = PS3AV_CMD_VIDEO_CS_YUV444_8;
+ if (aspect == -1)
+ aspect = 0;
+
+ memset(av_video_cs, 0, sizeof(*av_video_cs));
+ ps3av_set_hdr(PS3AV_CID_AV_VIDEO_CS, sizeof(*av_video_cs),
+ &av_video_cs->send_hdr);
+ av_video_cs->avport = avport;
+ /* should be same as video_mode.resolution */
+ av_video_cs->av_vid = ps3av_vid_video2av(video_vid);
+ av_video_cs->av_cs_out = ps3av_cs_video2av(cs_out);
+ /* should be same as video_mode.video_cs_out */
+ av_video_cs->av_cs_in = ps3av_cs_video2av(PS3AV_CMD_VIDEO_CS_RGB_8);
+ av_video_cs->bitlen_out = ps3av_cs_video2av_bitlen(cs_out);
+ av_video_cs->aspect = aspect;
+ if (id & PS3AV_MODE_DITHER) {
+ av_video_cs->dither = PS3AV_CMD_AV_DITHER_ON
+ | PS3AV_CMD_AV_DITHER_8BIT;
+ } else {
+ /* default off */
+ av_video_cs->dither = PS3AV_CMD_AV_DITHER_OFF;
+ }
+
+ return sizeof(*av_video_cs);
+}
+
+u32 ps3av_cmd_set_video_mode(void *p, u32 head, int video_vid, int video_fmt,
+ u32 id)
+{
+ struct ps3av_pkt_video_mode *video_mode;
+ u32 x, y;
+
+ video_mode = (struct ps3av_pkt_video_mode *)p;
+ if (video_vid == -1)
+ video_vid = PS3AV_CMD_VIDEO_VID_720P_60HZ;
+ if (video_fmt == -1)
+ video_fmt = PS3AV_CMD_VIDEO_FMT_X8R8G8B8;
+
+ if (ps3av_video_mode2res(id, &x, &y))
+ return 0;
+
+ /* video mode */
+ memset(video_mode, 0, sizeof(*video_mode));
+ ps3av_set_hdr(PS3AV_CID_VIDEO_MODE, sizeof(*video_mode),
+ &video_mode->send_hdr);
+ video_mode->video_head = head;
+ if (video_vid == PS3AV_CMD_VIDEO_VID_480I
+ && head == PS3AV_CMD_VIDEO_HEAD_B)
+ video_mode->video_vid = PS3AV_CMD_VIDEO_VID_480I_A;
+ else
+ video_mode->video_vid = video_vid;
+ video_mode->width = (u16) x;
+ video_mode->height = (u16) y;
+ video_mode->pitch = video_mode->width * 4; /* line_length */
+ video_mode->video_out_format = PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT;
+ video_mode->video_format = ps3av_video_fmt_table[video_fmt].format;
+ video_mode->video_order = ps3av_video_fmt_table[video_fmt].order;
+
+ pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n",
+ __FUNCTION__, video_vid, video_mode->width, video_mode->height,
+ video_mode->pitch, video_mode->video_out_format,
+ video_mode->video_format, video_mode->video_order);
+ return sizeof(*video_mode);
+}
+
+int ps3av_cmd_video_format_black(u32 head, u32 video_fmt, u32 mute)
+{
+ int res;
+ struct ps3av_pkt_video_format video_format;
+
+ memset(&video_format, 0, sizeof(video_format));
+ video_format.video_head = head;
+ if (mute != PS3AV_CMD_MUTE_OFF)
+ video_format.video_format = PS3AV_CMD_VIDEO_FORMAT_BLACK;
+ else
+ video_format.video_format =
+ ps3av_video_fmt_table[video_fmt].format;
+ video_format.video_order = ps3av_video_fmt_table[video_fmt].order;
+
+ res = ps3av_do_pkt(PS3AV_CID_VIDEO_FORMAT, sizeof(video_format),
+ sizeof(video_format), &video_format.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&video_format);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_VIDEO_FORMAT: failed %x\n", res);
+
+ return res;
+}
+
+
+int ps3av_cmd_av_audio_mute(int num_of_port, u32 *port, u32 mute)
+{
+ int i, res;
+ struct ps3av_pkt_av_audio_mute av_audio_mute;
+
+ if (num_of_port > PS3AV_MUTE_PORT_MAX)
+ return -EINVAL;
+
+ /* audio mute */
+ memset(&av_audio_mute, 0, sizeof(av_audio_mute));
+ for (i = 0; i < num_of_port; i++) {
+ av_audio_mute.mute[i].avport = port[i];
+ av_audio_mute.mute[i].mute = mute;
+ }
+
+ res = ps3av_do_pkt(PS3AV_CID_AV_AUDIO_MUTE,
+ sizeof(av_audio_mute.send_hdr) +
+ sizeof(struct ps3av_av_mute) * num_of_port,
+ sizeof(av_audio_mute), &av_audio_mute.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&av_audio_mute);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AV_AUDIO_MUTE: failed %x\n", res);
+
+ return res;
+}
+
+static const struct {
+ u32 fs;
+ u8 mclk;
+} ps3av_cnv_mclk_table[] = {
+ { PS3AV_CMD_AUDIO_FS_44K, PS3AV_CMD_AV_MCLK_512 },
+ { PS3AV_CMD_AUDIO_FS_48K, PS3AV_CMD_AV_MCLK_512 },
+ { PS3AV_CMD_AUDIO_FS_88K, PS3AV_CMD_AV_MCLK_256 },
+ { PS3AV_CMD_AUDIO_FS_96K, PS3AV_CMD_AV_MCLK_256 },
+ { PS3AV_CMD_AUDIO_FS_176K, PS3AV_CMD_AV_MCLK_128 },
+ { PS3AV_CMD_AUDIO_FS_192K, PS3AV_CMD_AV_MCLK_128 }
+};
+
+static u8 ps3av_cnv_mclk(u32 fs)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(ps3av_cnv_mclk_table); i++)
+ if (ps3av_cnv_mclk_table[i].fs == fs)
+ return ps3av_cnv_mclk_table[i].mclk;
+
+ printk(KERN_ERR "%s failed, fs:%x\n", __FUNCTION__, fs);
+ return 0;
+}
+
+#define BASE PS3AV_CMD_AUDIO_FS_44K
+
+static const u32 ps3av_ns_table[][5] = {
+ /* D1, D2, D3, D4, D5 */
+ [PS3AV_CMD_AUDIO_FS_44K-BASE] { 6272, 6272, 17836, 17836, 8918 },
+ [PS3AV_CMD_AUDIO_FS_48K-BASE] { 6144, 6144, 11648, 11648, 5824 },
+ [PS3AV_CMD_AUDIO_FS_88K-BASE] { 12544, 12544, 35672, 35672, 17836 },
+ [PS3AV_CMD_AUDIO_FS_96K-BASE] { 12288, 12288, 23296, 23296, 11648 },
+ [PS3AV_CMD_AUDIO_FS_176K-BASE] { 25088, 25088, 71344, 71344, 35672 },
+ [PS3AV_CMD_AUDIO_FS_192K-BASE] { 24576, 24576, 46592, 46592, 23296 }
+};
+
+static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
+{
+ u32 av_vid, ns_val;
+ u8 *p = ns;
+ int d;
+
+ d = ns_val = 0;
+ av_vid = ps3av_vid_video2av(video_vid);
+ switch (av_vid) {
+ case PS3AV_CMD_AV_VID_480I:
+ case PS3AV_CMD_AV_VID_576I:
+ d = 0;
+ break;
+ case PS3AV_CMD_AV_VID_480P:
+ case PS3AV_CMD_AV_VID_576P:
+ d = 1;
+ break;
+ case PS3AV_CMD_AV_VID_1080I_60HZ:
+ case PS3AV_CMD_AV_VID_1080I_50HZ:
+ d = 2;
+ break;
+ case PS3AV_CMD_AV_VID_720P_60HZ:
+ case PS3AV_CMD_AV_VID_720P_50HZ:
+ d = 3;
+ break;
+ case PS3AV_CMD_AV_VID_1080P_60HZ:
+ case PS3AV_CMD_AV_VID_1080P_50HZ:
+ case PS3AV_CMD_AV_VID_WXGA:
+ case PS3AV_CMD_AV_VID_SXGA:
+ case PS3AV_CMD_AV_VID_WUXGA:
+ d = 4;
+ break;
+ default:
+ printk(KERN_ERR "%s failed, vid:%x\n", __FUNCTION__,
+ video_vid);
+ break;
+ }
+
+ if (fs < PS3AV_CMD_AUDIO_FS_44K || fs > PS3AV_CMD_AUDIO_FS_192K)
+ printk(KERN_ERR "%s failed, fs:%x\n", __FUNCTION__, fs);
+ else
+ ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d];
+
+ *p++ = ns_val & 0x000000FF;
+ *p++ = (ns_val & 0x0000FF00) >> 8;
+ *p = (ns_val & 0x00FF0000) >> 16;
+}
+
+#undef BASE
+
+static u8 ps3av_cnv_enable(u32 source, u8 *enable)
+{
+ u8 *p, ret = 0;
+
+ if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) {
+ ret = 0x03;
+ } else if (source == PS3AV_CMD_AUDIO_SOURCE_SERIAL) {
+ p = enable;
+ ret = ((p[0] << 4) + (p[1] << 5) + (p[2] << 6) + (p[3] << 7)) |
+ 0x01;
+ } else
+ printk(KERN_ERR "%s failed, source:%x\n", __FUNCTION__,
+ source);
+ return ret;
+}
+
+static u8 ps3av_cnv_fifomap(u8 *map)
+{
+ u8 *p, ret = 0;
+
+ p = map;
+ ret = p[0] + (p[1] << 2) + (p[2] << 4) + (p[3] << 6);
+ return ret;
+}
+
+static u8 ps3av_cnv_inputlen(u32 word_bits)
+{
+ u8 ret = 0;
+
+ switch (word_bits) {
+ case PS3AV_CMD_AUDIO_WORD_BITS_16:
+ ret = PS3AV_CMD_AV_INPUTLEN_16;
+ break;
+ case PS3AV_CMD_AUDIO_WORD_BITS_20:
+ ret = PS3AV_CMD_AV_INPUTLEN_20;
+ break;
+ case PS3AV_CMD_AUDIO_WORD_BITS_24:
+ ret = PS3AV_CMD_AV_INPUTLEN_24;
+ break;
+ default:
+ printk(KERN_ERR "%s failed, word_bits:%x\n", __FUNCTION__,
+ word_bits);
+ break;
+ }
+ return ret;
+}
+
+static u8 ps3av_cnv_layout(u32 num_of_ch)
+{
+ if (num_of_ch > PS3AV_CMD_AUDIO_NUM_OF_CH_8) {
+ printk(KERN_ERR "%s failed, num_of_ch:%x\n", __FUNCTION__,
+ num_of_ch);
+ return 0;
+ }
+
+ return num_of_ch == PS3AV_CMD_AUDIO_NUM_OF_CH_2 ? 0x0 : 0x1;
+}
+
+static void ps3av_cnv_info(struct ps3av_audio_info_frame *info,
+ const struct ps3av_pkt_audio_mode *mode)
+{
+ info->pb1.cc = mode->audio_num_of_ch + 1; /* CH2:0x01 --- CH8:0x07 */
+ info->pb1.ct = 0;
+ info->pb2.sf = 0;
+ info->pb2.ss = 0;
+
+ info->pb3 = 0; /* check mode->audio_format ?? */
+ info->pb4 = mode->audio_layout;
+ info->pb5.dm = mode->audio_downmix;
+ info->pb5.lsv = mode->audio_downmix_level;
+}
+
+static void ps3av_cnv_chstat(u8 *chstat, u8 *cs_info)
+{
+ memcpy(chstat, cs_info, 5);
+}
+
+u32 ps3av_cmd_set_av_audio_param(void *p, u32 port,
+ const struct ps3av_pkt_audio_mode *audio_mode,
+ u32 video_vid)
+{
+ struct ps3av_pkt_av_audio_param *param;
+
+ param = (struct ps3av_pkt_av_audio_param *)p;
+
+ memset(param, 0, sizeof(*param));
+ ps3av_set_hdr(PS3AV_CID_AV_AUDIO_PARAM, sizeof(*param),
+ &param->send_hdr);
+
+ param->avport = port;
+ param->mclk = ps3av_cnv_mclk(audio_mode->audio_fs) | 0x80;
+ ps3av_cnv_ns(param->ns, audio_mode->audio_fs, video_vid);
+ param->enable = ps3av_cnv_enable(audio_mode->audio_source,
+ audio_mode->audio_enable);
+ param->swaplr = 0x09;
+ param->fifomap = ps3av_cnv_fifomap(audio_mode->audio_map);
+ param->inputctrl = 0x49;
+ param->inputlen = ps3av_cnv_inputlen(audio_mode->audio_word_bits);
+ param->layout = ps3av_cnv_layout(audio_mode->audio_num_of_ch);
+ ps3av_cnv_info(&param->info, audio_mode);
+ ps3av_cnv_chstat(param->chstat, audio_mode->audio_cs_info);
+
+ return sizeof(*param);
+}
+
+/* default cs val */
+static const u8 ps3av_mode_cs_info[] = {
+ 0x00, 0x09, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00
+};
+
+#define CS_44 0x00
+#define CS_48 0x02
+#define CS_88 0x08
+#define CS_96 0x0a
+#define CS_176 0x0c
+#define CS_192 0x0e
+#define CS_MASK 0x0f
+#define CS_BIT 0x40
+
+void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport,
+ u32 ch, u32 fs, u32 word_bits, u32 format,
+ u32 source)
+{
+ int spdif_through, spdif_bitstream;
+ int i;
+
+ if (!(ch | fs | format | word_bits | source)) {
+ ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2;
+ fs = PS3AV_CMD_AUDIO_FS_48K;
+ word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16;
+ format = PS3AV_CMD_AUDIO_FORMAT_PCM;
+ source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
+ }
+ spdif_through = spdif_bitstream = 0; /* XXX not supported */
+
+ /* audio mode */
+ memset(audio, 0, sizeof(*audio));
+ ps3av_set_hdr(PS3AV_CID_AUDIO_MODE, sizeof(*audio), &audio->send_hdr);
+
+ audio->avport = (u8) avport;
+ audio->mask = 0x0FFF; /* XXX set all */
+ audio->audio_num_of_ch = ch;
+ audio->audio_fs = fs;
+ audio->audio_word_bits = word_bits;
+ audio->audio_format = format;
+ audio->audio_source = source;
+
+ switch (ch) {
+ case PS3AV_CMD_AUDIO_NUM_OF_CH_8:
+ audio->audio_enable[3] = 1;
+ /* fall through */
+ case PS3AV_CMD_AUDIO_NUM_OF_CH_6:
+ audio->audio_enable[2] = 1;
+ audio->audio_enable[1] = 1;
+ /* fall through */
+ case PS3AV_CMD_AUDIO_NUM_OF_CH_2:
+ default:
+ audio->audio_enable[0] = 1;
+ }
+
+ /* audio swap L/R */
+ for (i = 0; i < 4; i++)
+ audio->audio_swap[i] = PS3AV_CMD_AUDIO_SWAP_0; /* no swap */
+
+ /* audio serial input mapping */
+ audio->audio_map[0] = PS3AV_CMD_AUDIO_MAP_OUTPUT_0;
+ audio->audio_map[1] = PS3AV_CMD_AUDIO_MAP_OUTPUT_1;
+ audio->audio_map[2] = PS3AV_CMD_AUDIO_MAP_OUTPUT_2;
+ audio->audio_map[3] = PS3AV_CMD_AUDIO_MAP_OUTPUT_3;
+
+ /* audio speaker layout */
+ if (avport == PS3AV_CMD_AVPORT_HDMI_0 ||
+ avport == PS3AV_CMD_AVPORT_HDMI_1) {
+ switch (ch) {
+ case PS3AV_CMD_AUDIO_NUM_OF_CH_8:
+ audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_8CH;
+ break;
+ case PS3AV_CMD_AUDIO_NUM_OF_CH_6:
+ audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_6CH;
+ break;
+ case PS3AV_CMD_AUDIO_NUM_OF_CH_2:
+ default:
+ audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH;
+ break;
+ }
+ } else {
+ audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH;
+ }
+
+ /* audio downmix permission */
+ audio->audio_downmix = PS3AV_CMD_AUDIO_DOWNMIX_PERMITTED;
+ /* audio downmix level shift (0:0dB to 15:15dB) */
+ audio->audio_downmix_level = 0; /* 0dB */
+
+ /* set ch status */
+ for (i = 0; i < 8; i++)
+ audio->audio_cs_info[i] = ps3av_mode_cs_info[i];
+
+ switch (fs) {
+ case PS3AV_CMD_AUDIO_FS_44K:
+ audio->audio_cs_info[3] &= ~CS_MASK;
+ audio->audio_cs_info[3] |= CS_44;
+ break;
+ case PS3AV_CMD_AUDIO_FS_88K:
+ audio->audio_cs_info[3] &= ~CS_MASK;
+ audio->audio_cs_info[3] |= CS_88;
+ break;
+ case PS3AV_CMD_AUDIO_FS_96K:
+ audio->audio_cs_info[3] &= ~CS_MASK;
+ audio->audio_cs_info[3] |= CS_96;
+ break;
+ case PS3AV_CMD_AUDIO_FS_176K:
+ audio->audio_cs_info[3] &= ~CS_MASK;
+ audio->audio_cs_info[3] |= CS_176;
+ break;
+ case PS3AV_CMD_AUDIO_FS_192K:
+ audio->audio_cs_info[3] &= ~CS_MASK;
+ audio->audio_cs_info[3] |= CS_192;
+ break;
+ default:
+ break;
+ }
+
+ /* pass through setting */
+ if (spdif_through &&
+ (avport == PS3AV_CMD_AVPORT_SPDIF_0 ||
+ avport == PS3AV_CMD_AVPORT_SPDIF_1)) {
+ audio->audio_word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16;
+ audio->audio_source = PS3AV_CMD_AUDIO_SOURCE_SPDIF;
+ if (spdif_bitstream) {
+ audio->audio_format = PS3AV_CMD_AUDIO_FORMAT_BITSTREAM;
+ audio->audio_cs_info[0] |= CS_BIT;
+ }
+ }
+}
+
+int ps3av_cmd_audio_mode(struct ps3av_pkt_audio_mode *audio_mode)
+{
+ int res;
+
+ res = ps3av_do_pkt(PS3AV_CID_AUDIO_MODE, sizeof(*audio_mode),
+ sizeof(*audio_mode), &audio_mode->send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(audio_mode);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AUDIO_MODE: failed %x\n", res);
+
+ return res;
+}
+
+int ps3av_cmd_audio_mute(int num_of_port, u32 *port, u32 mute)
+{
+ int i, res;
+ struct ps3av_pkt_audio_mute audio_mute;
+
+ if (num_of_port > PS3AV_OPT_PORT_MAX)
+ return -EINVAL;
+
+ /* audio mute */
+ memset(&audio_mute, 0, sizeof(audio_mute));
+ for (i = 0; i < num_of_port; i++) {
+ audio_mute.mute[i].avport = port[i];
+ audio_mute.mute[i].mute = mute;
+ }
+
+ res = ps3av_do_pkt(PS3AV_CID_AUDIO_MUTE,
+ sizeof(audio_mute.send_hdr) +
+ sizeof(struct ps3av_audio_mute) * num_of_port,
+ sizeof(audio_mute), &audio_mute.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&audio_mute);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AUDIO_MUTE: failed %x\n", res);
+
+ return res;
+}
+
+int ps3av_cmd_audio_active(int active, u32 port)
+{
+ int res;
+ struct ps3av_pkt_audio_active audio_active;
+ u32 cid;
+
+ /* audio active */
+ memset(&audio_active, 0, sizeof(audio_active));
+ audio_active.audio_port = port;
+ cid = active ? PS3AV_CID_AUDIO_ACTIVE : PS3AV_CID_AUDIO_INACTIVE;
+
+ res = ps3av_do_pkt(cid, sizeof(audio_active), sizeof(audio_active),
+ &audio_active.send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(&audio_active);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AUDIO_ACTIVE:%x failed %x\n", cid,
+ res);
+
+ return res;
+}
+
+int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len)
+{
+ int res;
+
+ ps3fb_flip_ctl(0); /* flip off */
+
+ /* avb packet */
+ res = ps3av_do_pkt(PS3AV_CID_AVB_PARAM, send_len, sizeof(*avb),
+ &avb->send_hdr);
+ if (res < 0)
+ goto out;
+
+ res = get_status(avb);
+ if (res)
+ pr_debug("%s: PS3AV_CID_AVB_PARAM: failed %x\n", __FUNCTION__,
+ res);
+
+ out:
+ ps3fb_flip_ctl(1); /* flip on */
+ return res;
+}
+
+int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *hw_conf)
+{
+ int res;
+
+ memset(hw_conf, 0, sizeof(*hw_conf));
+
+ res = ps3av_do_pkt(PS3AV_CID_AV_GET_HW_CONF, sizeof(hw_conf->send_hdr),
+ sizeof(*hw_conf), &hw_conf->send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(hw_conf);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AV_GET_HW_CONF: failed %x\n", res);
+
+ return res;
+}
+
+int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *info,
+ u32 avport)
+{
+ int res;
+
+ memset(info, 0, sizeof(*info));
+ info->avport = avport;
+
+ res = ps3av_do_pkt(PS3AV_CID_AV_GET_MONITOR_INFO,
+ sizeof(info->send_hdr) + sizeof(info->avport) +
+ sizeof(info->reserved),
+ sizeof(*info), &info->send_hdr);
+ if (res < 0)
+ return res;
+
+ res = get_status(info);
+ if (res)
+ printk(KERN_ERR "PS3AV_CID_AV_GET_MONITOR_INFO: failed %x\n",
+ res);
+
+ return res;
+}
+
+#ifdef PS3AV_DEBUG
+void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *hw_conf)
+{
+ printk("av_h_conf:num of hdmi:%d\n", hw_conf->num_of_hdmi);
+ printk("av_h_conf:num of avmulti:%d\n", hw_conf->num_of_avmulti);
+ printk("av_h_conf:num of spdif:%d\n", hw_conf->num_of_spdif);
+}
+
+void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info)
+{
+ const struct ps3av_info_monitor *info = &monitor_info->info;
+ const struct ps3av_info_audio *audio = info->audio;
+ int i;
+
+ printk("Monitor Info: size%d\n", monitor_info->send_hdr.size);
+
+ printk("avport:%02x\n", info->avport);
+ printk("monitor_id:");
+ for (i = 0; i < 10; i++)
+ printk("%02x ", info->monitor_id[i]);
+ printk("\nmonitor_type:%02x\n", info->monitor_type);
+ printk("monitor_name:");
+ for (i = 0; i < 16; i++)
+ printk("%c", info->monitor_name[i]);
+
+ /* resolution */
+ printk("\nresolution_60: bits:%08x native:%08x\n",
+ info->res_60.res_bits, info->res_60.native);
+ printk("resolution_50: bits:%08x native:%08x\n",
+ info->res_50.res_bits, info->res_50.native);
+ printk("resolution_other: bits:%08x native:%08x\n",
+ info->res_other.res_bits, info->res_other.native);
+ printk("resolution_vesa: bits:%08x native:%08x\n",
+ info->res_vesa.res_bits, info->res_vesa.native);
+
+ /* color space */
+ printk("color space rgb:%02x\n", info->cs.rgb);
+ printk("color space yuv444:%02x\n", info->cs.yuv444);
+ printk("color space yuv422:%02x\n", info->cs.yuv422);
+
+ /* color info */
+ printk("color info red:X %04x Y %04x\n",
+ info->color.red_x, info->color.red_y);
+ printk("color info green:X %04x Y %04x\n",
+ info->color.green_x, info->color.green_y);
+ printk("color info blue:X %04x Y %04x\n",
+ info->color.blue_x, info->color.blue_y);
+ printk("color info white:X %04x Y %04x\n",
+ info->color.white_x, info->color.white_y);
+ printk("color info gamma: %08x\n", info->color.gamma);
+
+ /* other info */
+ printk("supported_AI:%02x\n", info->supported_ai);
+ printk("speaker_info:%02x\n", info->speaker_info);
+ printk("num of audio:%02x\n", info->num_of_audio_block);
+
+ /* audio block */
+ for (i = 0; i < info->num_of_audio_block; i++) {
+ printk("audio[%d] type:%02x max_ch:%02x fs:%02x sbit:%02x\n",
+ i, audio->type, audio->max_num_of_ch, audio->fs,
+ audio->sbit);
+ audio++;
+ }
+}
+#endif /* PS3AV_DEBUG */
+
+#define PS3AV_AV_LAYOUT_0 (PS3AV_CMD_AV_LAYOUT_32 \
+ | PS3AV_CMD_AV_LAYOUT_44 \
+ | PS3AV_CMD_AV_LAYOUT_48)
+
+#define PS3AV_AV_LAYOUT_1 (PS3AV_AV_LAYOUT_0 \
+ | PS3AV_CMD_AV_LAYOUT_88 \
+ | PS3AV_CMD_AV_LAYOUT_96 \
+ | PS3AV_CMD_AV_LAYOUT_176 \
+ | PS3AV_CMD_AV_LAYOUT_192)
+
+/************************* vuart ***************************/
+
+#define POLLING_INTERVAL 25 /* in msec */
+
+int ps3av_vuart_write(struct ps3_vuart_port_device *dev, const void *buf,
+ unsigned long size)
+{
+ int error = ps3_vuart_write(dev, buf, size);
+ return error ? error : size;
+}
+
+int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf,
+ unsigned long size, int timeout)
+{
+ int error;
+ int loopcnt = 0;
+
+ timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL;
+ while (loopcnt++ <= timeout) {
+ error = ps3_vuart_read(dev, buf, size);
+ if (!error)
+ return size;
+ if (error != -EAGAIN) {
+ printk(KERN_ERR "%s: ps3_vuart_read failed %d\n",
+ __FUNCTION__, error);
+ return error;
+ }
+ msleep(POLLING_INTERVAL);
+ }
+ return -EWOULDBLOCK;
+}
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index a72da8f651f8..ef8fd4c30875 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -867,6 +867,22 @@ static int ps3_vuart_remove(struct device *_dev)
return 0;
}
+static void ps3_vuart_shutdown(struct device *_dev)
+{
+ struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
+ struct ps3_vuart_port_driver *drv =
+ to_ps3_vuart_port_driver(_dev->driver);
+
+ dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__,
+ dev->core.bus_id);
+
+ if (drv->shutdown)
+ drv->shutdown(dev);
+ else
+ dev_dbg(&dev->core, "%s:%d: %s no shutdown method\n", __func__,
+ __LINE__, dev->core.bus_id);
+}
+
/**
* ps3_vuart - The vuart instance.
*
@@ -878,6 +894,7 @@ struct bus_type ps3_vuart = {
.match = ps3_vuart_match,
.probe = ps3_vuart_probe,
.remove = ps3_vuart_remove,
+ .shutdown = ps3_vuart_shutdown,
};
int __init ps3_vuart_init(void)
diff --git a/drivers/ps3/vuart.h b/drivers/ps3/vuart.h
index 11c421cf7a03..2cbf728a3a0b 100644
--- a/drivers/ps3/vuart.h
+++ b/drivers/ps3/vuart.h
@@ -30,6 +30,7 @@ struct ps3_vuart_port_driver {
struct device_driver core;
int (*probe)(struct ps3_vuart_port_device *);
int (*remove)(struct ps3_vuart_port_device *);
+ void (*shutdown)(struct ps3_vuart_port_device *);
int (*tx_event)(struct ps3_vuart_port_device *dev);
int (*rx_event)(struct ps3_vuart_port_device *dev);
int (*disconnect_event)(struct ps3_vuart_port_device *dev);
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 7bf7b2c88245..f935c1f71a58 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -326,14 +326,17 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
&rdev->dst_ops);
- if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)
- && do_enum) {
- rio_set_device_id(port, destid, hopcount, next_destid);
- rdev->destid = next_destid++;
- if (next_destid == port->host_deviceid)
- next_destid++;
+ if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) {
+ if (do_enum) {
+ rio_set_device_id(port, destid, hopcount, next_destid);
+ rdev->destid = next_destid++;
+ if (next_destid == port->host_deviceid)
+ next_destid++;
+ } else
+ rdev->destid = rio_get_device_id(port, destid, hopcount);
} else
- rdev->destid = rio_get_device_id(port, destid, hopcount);
+ /* Switch device has an associated destID */
+ rdev->destid = RIO_INVALID_DESTID;
/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
@@ -347,7 +350,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
}
rswitch->switchid = next_switchid;
rswitch->hopcount = hopcount;
- rswitch->destid = 0xffff;
+ rswitch->destid = destid;
/* Initialize switch route table */
for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
@@ -422,7 +425,7 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
/**
* rio_route_add_entry- Add a route entry to a switch routing table
* @mport: Master port to send transaction
- * @rdev: Switch device
+ * @rswitch: Switch device
* @table: Routing table ID
* @route_destid: Destination ID to be routed
* @route_port: Port number to be routed
@@ -434,18 +437,18 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
* %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
* on failure.
*/
-static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
+static int rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch,
u16 table, u16 route_destid, u8 route_port)
{
- return rdev->rswitch->add_entry(mport, rdev->rswitch->destid,
- rdev->rswitch->hopcount, table,
+ return rswitch->add_entry(mport, rswitch->destid,
+ rswitch->hopcount, table,
route_destid, route_port);
}
/**
* rio_route_get_entry- Read a route entry in a switch routing table
* @mport: Master port to send transaction
- * @rdev: Switch device
+ * @rswitch: Switch device
* @table: Routing table ID
* @route_destid: Destination ID to be routed
* @route_port: Pointer to read port number into
@@ -458,11 +461,11 @@ static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
* on failure.
*/
static int
-rio_route_get_entry(struct rio_mport *mport, struct rio_dev *rdev, u16 table,
+rio_route_get_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 table,
u16 route_destid, u8 * route_port)
{
- return rdev->rswitch->get_entry(mport, rdev->rswitch->destid,
- rdev->rswitch->hopcount, table,
+ return rswitch->get_entry(mport, rswitch->destid,
+ rswitch->hopcount, table,
route_destid, route_port);
}
@@ -552,6 +555,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
int port_num;
int num_ports;
int cur_destid;
+ int sw_destid;
+ int sw_inport;
struct rio_dev *rdev;
u16 destid;
int tmp;
@@ -594,15 +599,17 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
if (rio_is_switch(rdev)) {
next_switchid++;
+ sw_inport = rio_get_swpinfo_inport(port, RIO_ANY_DESTID, hopcount);
+ rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
+ port->host_deviceid, sw_inport);
+ rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
for (destid = 0; destid < next_destid; destid++) {
- rio_route_add_entry(port, rdev, RIO_GLOBAL_TABLE,
- destid, rio_get_swpinfo_inport(port,
- RIO_ANY_DESTID,
- hopcount));
- rdev->rswitch->route_table[destid] =
- rio_get_swpinfo_inport(port, RIO_ANY_DESTID,
- hopcount);
+ if (destid == port->host_deviceid)
+ continue;
+ rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
+ destid, sw_inport);
+ rdev->rswitch->route_table[destid] = sw_inport;
}
num_ports =
@@ -610,9 +617,9 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
pr_debug(
"RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
rio_name(rdev), rdev->vid, rdev->did, num_ports);
+ sw_destid = next_destid;
for (port_num = 0; port_num < num_ports; port_num++) {
- if (rio_get_swpinfo_inport
- (port, RIO_ANY_DESTID, hopcount) == port_num)
+ if (sw_inport == port_num)
continue;
cur_destid = next_destid;
@@ -622,7 +629,7 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
- rio_route_add_entry(port, rdev,
+ rio_route_add_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
RIO_ANY_DESTID, port_num);
@@ -633,7 +640,9 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
if (next_destid > cur_destid) {
for (destid = cur_destid;
destid < next_destid; destid++) {
- rio_route_add_entry(port, rdev,
+ if (destid == port->host_deviceid)
+ continue;
+ rio_route_add_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
destid,
port_num);
@@ -641,10 +650,18 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
route_table[destid] =
port_num;
}
- rdev->rswitch->destid = cur_destid;
}
}
}
+
+ /* Check for empty switch */
+ if (next_destid == sw_destid) {
+ next_destid++;
+ if (next_destid == port->host_deviceid)
+ next_destid++;
+ }
+
+ rdev->rswitch->destid = sw_destid;
} else
pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
rio_name(rdev), rdev->vid, rdev->did);
@@ -721,7 +738,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
port_num);
for (ndestid = 0; ndestid < RIO_ANY_DESTID;
ndestid++) {
- rio_route_get_entry(port, rdev,
+ rio_route_get_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
ndestid,
&route_port);
@@ -798,6 +815,44 @@ static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
}
/**
+ * rio_update_route_tables- Updates route tables in switches
+ * @port: Master port associated with the RIO network
+ *
+ * For each enumerated device, ensure that each switch in a system
+ * has correct routing entries. Add routes for devices that where
+ * unknown dirung the first enumeration pass through the switch.
+ */
+static void rio_update_route_tables(struct rio_mport *port)
+{
+ struct rio_dev *rdev;
+ struct rio_switch *rswitch;
+ u8 sport;
+ u16 destid;
+
+ list_for_each_entry(rdev, &rio_devices, global_list) {
+
+ destid = (rio_is_switch(rdev))?rdev->rswitch->destid:rdev->destid;
+
+ list_for_each_entry(rswitch, &rio_switches, node) {
+
+ if (rio_is_switch(rdev) && (rdev->rswitch == rswitch))
+ continue;
+
+ if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) {
+
+ sport = rio_get_swpinfo_inport(port,
+ rswitch->destid, rswitch->hopcount);
+
+ if (rswitch->add_entry) {
+ rio_route_add_entry(port, rswitch, RIO_GLOBAL_TABLE, destid, sport);
+ rswitch->route_table[destid] = sport;
+ }
+ }
+ }
+ }
+}
+
+/**
* rio_enum_mport- Start enumeration through a master port
* @mport: Master port to send transactions
*
@@ -838,6 +893,7 @@ int rio_enum_mport(struct rio_mport *mport)
rc = -EBUSY;
goto out;
}
+ rio_update_route_tables(mport);
rio_clear_locks(mport);
} else {
printk(KERN_INFO "RIO: master port %d link inactive\n",
@@ -865,8 +921,8 @@ static void rio_build_route_tables(void)
if (rio_is_switch(rdev))
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
if (rio_route_get_entry
- (rdev->net->hport, rdev, RIO_GLOBAL_TABLE, i,
- &sport) < 0)
+ (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE,
+ i, &sport) < 0)
continue;
rdev->rswitch->route_table[i] = sport;
}
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 09660e2ab051..4bbca500d3d2 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1,4 +1,4 @@
-\#
+#
# RTC class/drivers configuration
#
@@ -95,6 +95,29 @@ config RTC_INTF_DEV_UIE_EMUL
comment "RTC drivers"
depends on RTC_CLASS
+# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
+# requires <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a
+# global rtc_lock ... it's not yet just another platform_device.
+
+config RTC_DRV_CMOS
+ tristate "PC-style 'CMOS' real time clock"
+ depends on RTC_CLASS && (X86_PC || ALPHA || ARM26 || ARM \
+ || M32R || ATARI || POWERPC)
+ help
+ Say "yes" here to get direct support for the real time clock
+ found in every PC or ACPI-based system, and some other boards.
+ Specifically the original MC146818, compatibles like those in
+ PC south bridges, the DS12887 or M48T86, some multifunction
+ or LPC bus chips, and so on.
+
+ Your system will need to define the platform device used by
+ this driver, otherwise it won't be accessible. This means
+ you can safely enable this driver if you don't know whether
+ or not your board has this kind of hardware.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-cmos.
+
config RTC_DRV_X1205
tristate "Xicor/Intersil X1205"
depends on RTC_CLASS && I2C
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index e6beedacc966..92bfe1b3a5fa 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
+obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
new file mode 100644
index 000000000000..85bf795abdcc
--- /dev/null
+++ b/drivers/rtc/rtc-cmos.c
@@ -0,0 +1,725 @@
+/*
+ * RTC class driver for "CMOS RTC": PCs, ACPI, etc
+ *
+ * Copyright (C) 1996 Paul Gortmaker (drivers/char/rtc.c)
+ * Copyright (C) 2006 David Brownell (convert to new framework)
+ *
+ * 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.
+ */
+
+/*
+ * The original "cmos clock" chip was an MC146818 chip, now obsolete.
+ * That defined the register interface now provided by all PCs, some
+ * non-PC systems, and incorporated into ACPI. Modern PC chipsets
+ * integrate an MC146818 clone in their southbridge, and boards use
+ * that instead of discrete clones like the DS12887 or M48T86. There
+ * are also clones that connect using the LPC bus.
+ *
+ * That register API is also used directly by various other drivers
+ * (notably for integrated NVRAM), infrastructure (x86 has code to
+ * bypass the RTC framework, directly reading the RTC during boot
+ * and updating minutes/seconds for systems using NTP synch) and
+ * utilities (like userspace 'hwclock', if no /dev node exists).
+ *
+ * So **ALL** calls to CMOS_READ and CMOS_WRITE must be done with
+ * interrupts disabled, holding the global rtc_lock, to exclude those
+ * other drivers and utilities on correctly configured systems.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/mod_devicetable.h>
+
+/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
+#include <asm-generic/rtc.h>
+
+
+struct cmos_rtc {
+ struct rtc_device *rtc;
+ struct device *dev;
+ int irq;
+ struct resource *iomem;
+
+ u8 suspend_ctrl;
+
+ /* newer hardware extends the original register set */
+ u8 day_alrm;
+ u8 mon_alrm;
+ u8 century;
+};
+
+/* both platform and pnp busses use negative numbers for invalid irqs */
+#define is_valid_irq(n) ((n) >= 0)
+
+static const char driver_name[] = "rtc_cmos";
+
+/*----------------------------------------------------------------*/
+
+static int cmos_read_time(struct device *dev, struct rtc_time *t)
+{
+ /* REVISIT: if the clock has a "century" register, use
+ * that instead of the heuristic in get_rtc_time().
+ * That'll make Y3K compatility (year > 2070) easy!
+ */
+ get_rtc_time(t);
+ return 0;
+}
+
+static int cmos_set_time(struct device *dev, struct rtc_time *t)
+{
+ /* REVISIT: set the "century" register if available
+ *
+ * NOTE: this ignores the issue whereby updating the seconds
+ * takes effect exactly 500ms after we write the register.
+ * (Also queueing and other delays before we get this far.)
+ */
+ return set_rtc_time(t);
+}
+
+static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ unsigned char rtc_control;
+
+ if (!is_valid_irq(cmos->irq))
+ return -EIO;
+
+ /* Basic alarms only support hour, minute, and seconds fields.
+ * Some also support day and month, for alarms up to a year in
+ * the future.
+ */
+ t->time.tm_mday = -1;
+ t->time.tm_mon = -1;
+
+ spin_lock_irq(&rtc_lock);
+ t->time.tm_sec = CMOS_READ(RTC_SECONDS_ALARM);
+ t->time.tm_min = CMOS_READ(RTC_MINUTES_ALARM);
+ t->time.tm_hour = CMOS_READ(RTC_HOURS_ALARM);
+
+ if (cmos->day_alrm) {
+ t->time.tm_mday = CMOS_READ(cmos->day_alrm);
+ if (!t->time.tm_mday)
+ t->time.tm_mday = -1;
+
+ if (cmos->mon_alrm) {
+ t->time.tm_mon = CMOS_READ(cmos->mon_alrm);
+ if (!t->time.tm_mon)
+ t->time.tm_mon = -1;
+ }
+ }
+
+ rtc_control = CMOS_READ(RTC_CONTROL);
+ spin_unlock_irq(&rtc_lock);
+
+ /* REVISIT this assumes PC style usage: always BCD */
+
+ if (((unsigned)t->time.tm_sec) < 0x60)
+ t->time.tm_sec = BCD2BIN(t->time.tm_sec);
+ else
+ t->time.tm_sec = -1;
+ if (((unsigned)t->time.tm_min) < 0x60)
+ t->time.tm_min = BCD2BIN(t->time.tm_min);
+ else
+ t->time.tm_min = -1;
+ if (((unsigned)t->time.tm_hour) < 0x24)
+ t->time.tm_hour = BCD2BIN(t->time.tm_hour);
+ else
+ t->time.tm_hour = -1;
+
+ if (cmos->day_alrm) {
+ if (((unsigned)t->time.tm_mday) <= 0x31)
+ t->time.tm_mday = BCD2BIN(t->time.tm_mday);
+ else
+ t->time.tm_mday = -1;
+ if (cmos->mon_alrm) {
+ if (((unsigned)t->time.tm_mon) <= 0x12)
+ t->time.tm_mon = BCD2BIN(t->time.tm_mon) - 1;
+ else
+ t->time.tm_mon = -1;
+ }
+ }
+ t->time.tm_year = -1;
+
+ t->enabled = !!(rtc_control & RTC_AIE);
+ t->pending = 0;
+
+ return 0;
+}
+
+static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ unsigned char mon, mday, hrs, min, sec;
+ unsigned char rtc_control, rtc_intr;
+
+ if (!is_valid_irq(cmos->irq))
+ return -EIO;
+
+ /* REVISIT this assumes PC style usage: always BCD */
+
+ /* Writing 0xff means "don't care" or "match all". */
+
+ mon = t->time.tm_mon;
+ mon = (mon < 12) ? BIN2BCD(mon) : 0xff;
+ mon++;
+
+ mday = t->time.tm_mday;
+ mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff;
+
+ hrs = t->time.tm_hour;
+ hrs = (hrs < 24) ? BIN2BCD(hrs) : 0xff;
+
+ min = t->time.tm_min;
+ min = (min < 60) ? BIN2BCD(min) : 0xff;
+
+ sec = t->time.tm_sec;
+ sec = (sec < 60) ? BIN2BCD(sec) : 0xff;
+
+ spin_lock_irq(&rtc_lock);
+
+ /* next rtc irq must not be from previous alarm setting */
+ rtc_control = CMOS_READ(RTC_CONTROL);
+ rtc_control &= ~RTC_AIE;
+ CMOS_WRITE(rtc_control, RTC_CONTROL);
+ rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
+ if (rtc_intr)
+ rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
+
+ /* update alarm */
+ CMOS_WRITE(hrs, RTC_HOURS_ALARM);
+ CMOS_WRITE(min, RTC_MINUTES_ALARM);
+ CMOS_WRITE(sec, RTC_SECONDS_ALARM);
+
+ /* the system may support an "enhanced" alarm */
+ if (cmos->day_alrm) {
+ CMOS_WRITE(mday, cmos->day_alrm);
+ if (cmos->mon_alrm)
+ CMOS_WRITE(mon, cmos->mon_alrm);
+ }
+
+ if (t->enabled) {
+ rtc_control |= RTC_AIE;
+ CMOS_WRITE(rtc_control, RTC_CONTROL);
+ rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
+ if (rtc_intr)
+ rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
+ }
+
+ spin_unlock_irq(&rtc_lock);
+
+ return 0;
+}
+
+static int cmos_set_freq(struct device *dev, int freq)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ int f;
+ unsigned long flags;
+
+ if (!is_valid_irq(cmos->irq))
+ return -ENXIO;
+
+ /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */
+ f = ffs(freq);
+ if (f != 0) {
+ if (f-- > 16 || freq != (1 << f))
+ return -EINVAL;
+ f = 16 - f;
+ }
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+
+ return 0;
+}
+
+#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
+
+static int
+cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ unsigned char rtc_control, rtc_intr;
+ unsigned long flags;
+
+ switch (cmd) {
+ case RTC_AIE_OFF:
+ case RTC_AIE_ON:
+ case RTC_UIE_OFF:
+ case RTC_UIE_ON:
+ case RTC_PIE_OFF:
+ case RTC_PIE_ON:
+ if (!is_valid_irq(cmos->irq))
+ return -EINVAL;
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
+
+ spin_lock_irqsave(&rtc_lock, flags);
+ rtc_control = CMOS_READ(RTC_CONTROL);
+ switch (cmd) {
+ case RTC_AIE_OFF: /* alarm off */
+ rtc_control &= ~RTC_AIE;
+ break;
+ case RTC_AIE_ON: /* alarm on */
+ rtc_control |= RTC_AIE;
+ break;
+ case RTC_UIE_OFF: /* update off */
+ rtc_control &= ~RTC_UIE;
+ break;
+ case RTC_UIE_ON: /* update on */
+ rtc_control |= RTC_UIE;
+ break;
+ case RTC_PIE_OFF: /* periodic off */
+ rtc_control &= ~RTC_PIE;
+ break;
+ case RTC_PIE_ON: /* periodic on */
+ rtc_control |= RTC_PIE;
+ break;
+ }
+ CMOS_WRITE(rtc_control, RTC_CONTROL);
+ rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
+ if (rtc_intr)
+ rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr);
+ spin_unlock_irqrestore(&rtc_lock, flags);
+ return 0;
+}
+
+#else
+#define cmos_rtc_ioctl NULL
+#endif
+
+#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
+
+static int cmos_procfs(struct device *dev, struct seq_file *seq)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ unsigned char rtc_control, valid;
+
+ spin_lock_irq(&rtc_lock);
+ rtc_control = CMOS_READ(RTC_CONTROL);
+ valid = CMOS_READ(RTC_VALID);
+ spin_unlock_irq(&rtc_lock);
+
+ /* NOTE: at least ICH6 reports battery status using a different
+ * (non-RTC) bit; and SQWE is ignored on many current systems.
+ */
+ return seq_printf(seq,
+ "periodic_IRQ\t: %s\n"
+ "update_IRQ\t: %s\n"
+ // "square_wave\t: %s\n"
+ // "BCD\t\t: %s\n"
+ "DST_enable\t: %s\n"
+ "periodic_freq\t: %d\n"
+ "batt_status\t: %s\n",
+ (rtc_control & RTC_PIE) ? "yes" : "no",
+ (rtc_control & RTC_UIE) ? "yes" : "no",
+ // (rtc_control & RTC_SQWE) ? "yes" : "no",
+ // (rtc_control & RTC_DM_BINARY) ? "no" : "yes",
+ (rtc_control & RTC_DST_EN) ? "yes" : "no",
+ cmos->rtc->irq_freq,
+ (valid & RTC_VRT) ? "okay" : "dead");
+}
+
+#else
+#define cmos_procfs NULL
+#endif
+
+static const struct rtc_class_ops cmos_rtc_ops = {
+ .ioctl = cmos_rtc_ioctl,
+ .read_time = cmos_read_time,
+ .set_time = cmos_set_time,
+ .read_alarm = cmos_read_alarm,
+ .set_alarm = cmos_set_alarm,
+ .proc = cmos_procfs,
+ .irq_set_freq = cmos_set_freq,
+};
+
+/*----------------------------------------------------------------*/
+
+static struct cmos_rtc cmos_rtc;
+
+static irqreturn_t cmos_interrupt(int irq, void *p)
+{
+ u8 irqstat;
+
+ spin_lock(&rtc_lock);
+ irqstat = CMOS_READ(RTC_INTR_FLAGS);
+ spin_unlock(&rtc_lock);
+
+ if (irqstat) {
+ /* NOTE: irqstat may have e.g. RTC_PF set
+ * even when RTC_PIE is clear...
+ */
+ rtc_update_irq(p, 1, irqstat);
+ return IRQ_HANDLED;
+ } else
+ return IRQ_NONE;
+}
+
+#ifdef CONFIG_PNPACPI
+#define is_pnpacpi() 1
+#define INITSECTION
+
+#else
+#define is_pnpacpi() 0
+#define INITSECTION __init
+#endif
+
+static int INITSECTION
+cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
+{
+ struct cmos_rtc_board_info *info = dev->platform_data;
+ int retval = 0;
+ unsigned char rtc_control;
+
+ /* there can be only one ... */
+ if (cmos_rtc.dev)
+ return -EBUSY;
+
+ if (!ports)
+ return -ENODEV;
+
+ cmos_rtc.irq = rtc_irq;
+ cmos_rtc.iomem = ports;
+
+ /* For ACPI systems the info comes from the FADT. On others,
+ * board specific setup provides it as appropriate.
+ */
+ if (info) {
+ cmos_rtc.day_alrm = info->rtc_day_alarm;
+ cmos_rtc.mon_alrm = info->rtc_mon_alarm;
+ cmos_rtc.century = info->rtc_century;
+ }
+
+ cmos_rtc.rtc = rtc_device_register(driver_name, dev,
+ &cmos_rtc_ops, THIS_MODULE);
+ if (IS_ERR(cmos_rtc.rtc))
+ return PTR_ERR(cmos_rtc.rtc);
+
+ cmos_rtc.dev = dev;
+ dev_set_drvdata(dev, &cmos_rtc);
+
+ /* platform and pnp busses handle resources incompatibly.
+ *
+ * REVISIT for non-x86 systems we may need to handle io memory
+ * resources: ioremap them, and request_mem_region().
+ */
+ if (is_pnpacpi()) {
+ retval = request_resource(&ioport_resource, ports);
+ if (retval < 0) {
+ dev_dbg(dev, "i/o registers already in use\n");
+ goto cleanup0;
+ }
+ }
+ rename_region(ports, cmos_rtc.rtc->class_dev.class_id);
+
+ spin_lock_irq(&rtc_lock);
+
+ /* force periodic irq to CMOS reset default of 1024Hz;
+ *
+ * REVISIT it's been reported that at least one x86_64 ALI mobo
+ * doesn't use 32KHz here ... for portability we might need to
+ * do something about other clock frequencies.
+ */
+ CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT);
+ cmos_rtc.rtc->irq_freq = 1024;
+
+ /* disable irqs.
+ *
+ * NOTE after changing RTC_xIE bits we always read INTR_FLAGS;
+ * allegedly some older rtcs need that to handle irqs properly
+ */
+ rtc_control = CMOS_READ(RTC_CONTROL);
+ rtc_control &= ~(RTC_PIE | RTC_AIE | RTC_UIE);
+ CMOS_WRITE(rtc_control, RTC_CONTROL);
+ CMOS_READ(RTC_INTR_FLAGS);
+
+ spin_unlock_irq(&rtc_lock);
+
+ /* FIXME teach the alarm code how to handle binary mode;
+ * <asm-generic/rtc.h> doesn't know 12-hour mode either.
+ */
+ if (!(rtc_control & RTC_24H) || (rtc_control & (RTC_DM_BINARY))) {
+ dev_dbg(dev, "only 24-hr BCD mode supported\n");
+ retval = -ENXIO;
+ goto cleanup1;
+ }
+
+ if (is_valid_irq(rtc_irq))
+ retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED,
+ cmos_rtc.rtc->class_dev.class_id,
+ &cmos_rtc.rtc->class_dev);
+ if (retval < 0) {
+ dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
+ goto cleanup1;
+ }
+
+ /* REVISIT optionally make 50 or 114 bytes NVRAM available,
+ * like rtc-ds1553, rtc-ds1742 ... this will often include
+ * registers for century, and day/month alarm.
+ */
+
+ pr_info("%s: alarms up to one %s%s\n",
+ cmos_rtc.rtc->class_dev.class_id,
+ is_valid_irq(rtc_irq)
+ ? (cmos_rtc.mon_alrm
+ ? "year"
+ : (cmos_rtc.day_alrm
+ ? "month" : "day"))
+ : "no",
+ cmos_rtc.century ? ", y3k" : ""
+ );
+
+ return 0;
+
+cleanup1:
+ rename_region(ports, NULL);
+cleanup0:
+ rtc_device_unregister(cmos_rtc.rtc);
+ return retval;
+}
+
+static void cmos_do_shutdown(void)
+{
+ unsigned char rtc_control;
+
+ spin_lock_irq(&rtc_lock);
+ rtc_control = CMOS_READ(RTC_CONTROL);
+ rtc_control &= ~(RTC_PIE|RTC_AIE|RTC_UIE);
+ CMOS_WRITE(rtc_control, RTC_CONTROL);
+ CMOS_READ(RTC_INTR_FLAGS);
+ spin_unlock_irq(&rtc_lock);
+}
+
+static void __exit cmos_do_remove(struct device *dev)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+
+ cmos_do_shutdown();
+
+ if (is_pnpacpi())
+ release_resource(cmos->iomem);
+ rename_region(cmos->iomem, NULL);
+
+ if (is_valid_irq(cmos->irq))
+ free_irq(cmos->irq, &cmos_rtc.rtc->class_dev);
+
+ rtc_device_unregister(cmos_rtc.rtc);
+
+ cmos_rtc.dev = NULL;
+ dev_set_drvdata(dev, NULL);
+}
+
+#ifdef CONFIG_PM
+
+static int cmos_suspend(struct device *dev, pm_message_t mesg)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ int do_wake = device_may_wakeup(dev);
+ unsigned char tmp, irqstat;
+
+ /* only the alarm might be a wakeup event source */
+ spin_lock_irq(&rtc_lock);
+ cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL);
+ if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {
+ if (do_wake)
+ tmp &= ~(RTC_PIE|RTC_UIE);
+ else
+ tmp &= ~(RTC_PIE|RTC_AIE|RTC_UIE);
+ CMOS_WRITE(tmp, RTC_CONTROL);
+ irqstat = CMOS_READ(RTC_INTR_FLAGS);
+ } else
+ irqstat = 0;
+ spin_unlock_irq(&rtc_lock);
+
+ if (irqstat)
+ rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat);
+
+ /* ACPI HOOK: enable ACPI_EVENT_RTC when (tmp & RTC_AIE)
+ * ... it'd be best if we could do that under rtc_lock.
+ */
+
+ pr_debug("%s: suspend%s, ctrl %02x\n",
+ cmos_rtc.rtc->class_dev.class_id,
+ (tmp & RTC_AIE) ? ", alarm may wake" : "",
+ tmp);
+
+ return 0;
+}
+
+static int cmos_resume(struct device *dev)
+{
+ struct cmos_rtc *cmos = dev_get_drvdata(dev);
+ unsigned char tmp = cmos->suspend_ctrl;
+
+ /* REVISIT: a mechanism to resync the system clock (jiffies)
+ * on resume should be portable between platforms ...
+ */
+
+ /* re-enable any irqs previously active */
+ if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {
+
+ /* ACPI HOOK: disable ACPI_EVENT_RTC when (tmp & RTC_AIE) */
+
+ spin_lock_irq(&rtc_lock);
+ CMOS_WRITE(tmp, RTC_CONTROL);
+ tmp = CMOS_READ(RTC_INTR_FLAGS);
+ spin_unlock_irq(&rtc_lock);
+ if (tmp)
+ rtc_update_irq(&cmos->rtc->class_dev, 1, tmp);
+ }
+
+ pr_debug("%s: resume, ctrl %02x\n",
+ cmos_rtc.rtc->class_dev.class_id,
+ cmos->suspend_ctrl);
+
+
+ return 0;
+}
+
+#else
+#define cmos_suspend NULL
+#define cmos_resume NULL
+#endif
+
+/*----------------------------------------------------------------*/
+
+/* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems,
+ * the device node may alternatively be created as a PNP device.
+ */
+
+#ifdef CONFIG_PNPACPI
+
+#include <linux/pnp.h>
+
+static int __devinit
+cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
+{
+ /* REVISIT paranoia argues for a shutdown notifier, since PNP
+ * drivers can't provide shutdown() methods to disable IRQs.
+ * Or better yet, fix PNP to allow those methods...
+ */
+ return cmos_do_probe(&pnp->dev,
+ &pnp->res.port_resource[0],
+ pnp->res.irq_resource[0].start);
+}
+
+static void __exit cmos_pnp_remove(struct pnp_dev *pnp)
+{
+ cmos_do_remove(&pnp->dev);
+}
+
+#ifdef CONFIG_PM
+
+static int cmos_pnp_suspend(struct pnp_dev *pnp, pm_message_t mesg)
+{
+ return cmos_suspend(&pnp->dev, mesg);
+}
+
+static int cmos_pnp_resume(struct pnp_dev *pnp)
+{
+ return cmos_resume(&pnp->dev);
+}
+
+#else
+#define cmos_pnp_suspend NULL
+#define cmos_pnp_resume NULL
+#endif
+
+
+static const struct pnp_device_id rtc_ids[] = {
+ { .id = "PNP0b00", },
+ { .id = "PNP0b01", },
+ { .id = "PNP0b02", },
+ { },
+};
+MODULE_DEVICE_TABLE(pnp, rtc_ids);
+
+static struct pnp_driver cmos_pnp_driver = {
+ .name = (char *) driver_name,
+ .id_table = rtc_ids,
+ .probe = cmos_pnp_probe,
+ .remove = __exit_p(cmos_pnp_remove),
+
+ /* flag ensures resume() gets called, and stops syslog spam */
+ .flags = PNP_DRIVER_RES_DO_NOT_CHANGE,
+ .suspend = cmos_pnp_suspend,
+ .resume = cmos_pnp_resume,
+};
+
+static int __init cmos_init(void)
+{
+ return pnp_register_driver(&cmos_pnp_driver);
+}
+module_init(cmos_init);
+
+static void __exit cmos_exit(void)
+{
+ pnp_unregister_driver(&cmos_pnp_driver);
+}
+module_exit(cmos_exit);
+
+#else /* no PNPACPI */
+
+/*----------------------------------------------------------------*/
+
+/* Platform setup should have set up an RTC device, when PNPACPI is
+ * unavailable ... this is the normal case, common even on PCs.
+ */
+
+static int __init cmos_platform_probe(struct platform_device *pdev)
+{
+ return cmos_do_probe(&pdev->dev,
+ platform_get_resource(pdev, IORESOURCE_IO, 0),
+ platform_get_irq(pdev, 0));
+}
+
+static int __exit cmos_platform_remove(struct platform_device *pdev)
+{
+ cmos_do_remove(&pdev->dev);
+ return 0;
+}
+
+static void cmos_platform_shutdown(struct platform_device *pdev)
+{
+ cmos_do_shutdown();
+}
+
+static struct platform_driver cmos_platform_driver = {
+ .remove = __exit_p(cmos_platform_remove),
+ .shutdown = cmos_platform_shutdown,
+ .driver = {
+ .name = (char *) driver_name,
+ .suspend = cmos_suspend,
+ .resume = cmos_resume,
+ }
+};
+
+static int __init cmos_init(void)
+{
+ return platform_driver_probe(&cmos_platform_driver,
+ cmos_platform_probe);
+}
+module_init(cmos_init);
+
+static void __exit cmos_exit(void)
+{
+ platform_driver_unregister(&cmos_platform_driver);
+}
+module_exit(cmos_exit);
+
+
+#endif /* !PNPACPI */
+
+MODULE_AUTHOR("David Brownell");
+MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 82f2ac87ccd4..137330b8636b 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -384,7 +384,7 @@ static int rtc_dev_fasync(int fd, struct file *file, int on)
return fasync_helper(fd, file, on, &rtc->async_queue);
}
-static struct file_operations rtc_dev_fops = {
+static const struct file_operations rtc_dev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = rtc_dev_read,
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 001eb1123a65..e27176c0e18f 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -297,7 +297,7 @@ static struct bin_attribute ds1553_nvram_attr = {
.write = ds1553_nvram_write,
};
-static int __init ds1553_rtc_probe(struct platform_device *pdev)
+static int __devinit ds1553_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
struct resource *res;
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 17633bfa8480..d68288b389dc 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -165,7 +165,7 @@ static struct bin_attribute ds1742_nvram_attr = {
.write = ds1742_nvram_write,
};
-static int __init ds1742_rtc_probe(struct platform_device *pdev)
+static int __devinit ds1742_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
struct resource *res;
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index c272afd62173..1bd624fc685c 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -96,7 +96,7 @@ static int rtc_proc_release(struct inode *inode, struct file *file)
return res;
}
-static struct file_operations rtc_proc_fops = {
+static const struct file_operations rtc_proc_fops = {
.open = rtc_proc_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 2ddd0cf07140..899ab8c514fa 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -78,6 +78,92 @@ static struct attribute_group rtc_attr_group = {
.attrs = rtc_attrs,
};
+
+static ssize_t
+rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf)
+{
+ ssize_t retval;
+ unsigned long alarm;
+ struct rtc_wkalrm alm;
+
+ /* Don't show disabled alarms; but the RTC could leave the
+ * alarm enabled after it's already triggered. Alarms are
+ * conceptually one-shot, even though some common hardware
+ * (PCs) doesn't actually work that way.
+ *
+ * REVISIT maybe we should require RTC implementations to
+ * disable the RTC alarm after it triggers, for uniformity.
+ */
+ retval = rtc_read_alarm(dev, &alm);
+ if (retval == 0 && alm.enabled) {
+ rtc_tm_to_time(&alm.time, &alarm);
+ retval = sprintf(buf, "%lu\n", alarm);
+ }
+
+ return retval;
+}
+
+static ssize_t
+rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n)
+{
+ ssize_t retval;
+ unsigned long now, alarm;
+ struct rtc_wkalrm alm;
+
+ /* Only request alarms that trigger in the future. Disable them
+ * by writing another time, e.g. 0 meaning Jan 1 1970 UTC.
+ */
+ retval = rtc_read_time(dev, &alm.time);
+ if (retval < 0)
+ return retval;
+ rtc_tm_to_time(&alm.time, &now);
+
+ alarm = simple_strtoul(buf, NULL, 0);
+ if (alarm > now) {
+ /* Avoid accidentally clobbering active alarms; we can't
+ * entirely prevent that here, without even the minimal
+ * locking from the /dev/rtcN api.
+ */
+ retval = rtc_read_alarm(dev, &alm);
+ if (retval < 0)
+ return retval;
+ if (alm.enabled)
+ return -EBUSY;
+
+ alm.enabled = 1;
+ } else {
+ alm.enabled = 0;
+
+ /* Provide a valid future alarm time. Linux isn't EFI,
+ * this time won't be ignored when disabling the alarm.
+ */
+ alarm = now + 300;
+ }
+ rtc_time_to_tm(alarm, &alm.time);
+
+ retval = rtc_set_alarm(dev, &alm);
+ return (retval < 0) ? retval : n;
+}
+static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR,
+ rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm);
+
+
+/* The reason to trigger an alarm with no process watching it (via sysfs)
+ * is its side effect: waking from a system state like suspend-to-RAM or
+ * suspend-to-disk. So: no attribute unless that side effect is possible.
+ * (Userspace may disable that mechanism later.)
+ */
+static inline int rtc_does_wakealarm(struct class_device *class_dev)
+{
+ struct rtc_device *rtc;
+
+ if (!device_can_wakeup(class_dev->dev))
+ return 0;
+ rtc = to_rtc_device(class_dev);
+ return rtc->ops->set_alarm != NULL;
+}
+
+
static int rtc_sysfs_add_device(struct class_device *class_dev,
struct class_interface *class_intf)
{
@@ -87,8 +173,18 @@ static int rtc_sysfs_add_device(struct class_device *class_dev,
err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group);
if (err)
- dev_err(class_dev->dev,
- "failed to create sysfs attributes\n");
+ dev_err(class_dev->dev, "failed to create %s\n",
+ "sysfs attributes");
+ else if (rtc_does_wakealarm(class_dev)) {
+ /* not all RTCs support both alarms and wakeup */
+ err = class_device_create_file(class_dev,
+ &class_device_attr_wakealarm);
+ if (err) {
+ dev_err(class_dev->dev, "failed to create %s\n",
+ "alarm attribute");
+ sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
+ }
+ }
return err;
}
@@ -96,6 +192,9 @@ static int rtc_sysfs_add_device(struct class_device *class_dev,
static void rtc_sysfs_remove_device(struct class_device *class_dev,
struct class_interface *class_intf)
{
+ if (rtc_does_wakealarm(class_dev))
+ class_device_remove_file(class_dev,
+ &class_device_attr_wakealarm);
sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
}
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 6cedc914077e..4b8a95fba1e5 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -650,7 +650,7 @@ static unsigned int dasd_eer_poll(struct file *filp, poll_table *ptable)
return mask;
}
-static struct file_operations dasd_eer_fops = {
+static const struct file_operations dasd_eer_fops = {
.open = &dasd_eer_open,
.release = &dasd_eer_close,
.read = &dasd_eer_read,
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 8b7e11815d70..8b3b0f4a157c 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -147,7 +147,7 @@ static int dasd_devices_open(struct inode *inode, struct file *file)
return seq_open(file, &dasd_devices_seq_ops);
}
-static struct file_operations dasd_devices_file_ops = {
+static const struct file_operations dasd_devices_file_ops = {
.open = dasd_devices_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index e1a746269c4c..ef36f2132aa4 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -493,7 +493,7 @@ fs3270_close(struct inode *inode, struct file *filp)
return 0;
}
-static struct file_operations fs3270_fops = {
+static const struct file_operations fs3270_fops = {
.owner = THIS_MODULE, /* owner */
.read = fs3270_read, /* read */
.write = fs3270_write, /* write */
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index 3a1a958fb5f2..8df7b1323c05 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -547,7 +547,7 @@ static unsigned int mon_poll(struct file *filp, struct poll_table_struct *p)
return 0;
}
-static struct file_operations mon_fops = {
+static const struct file_operations mon_fops = {
.owner = THIS_MODULE,
.open = &mon_open,
.release = &mon_close,
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 9e451acc6491..268598ef3efe 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -255,7 +255,7 @@ out_error:
return rc;
}
-static struct file_operations monwrite_fops = {
+static const struct file_operations monwrite_fops = {
.owner = THIS_MODULE,
.open = &monwrite_open,
.release = &monwrite_close,
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 9faea04e11e9..b830a8cbef78 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -39,7 +39,7 @@ static int tapechar_ioctl(struct inode *, struct file *, unsigned int,
static long tapechar_compat_ioctl(struct file *, unsigned int,
unsigned long);
-static struct file_operations tape_fops =
+static const struct file_operations tape_fops =
{
.owner = THIS_MODULE,
.read = tapechar_read,
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index 56b87618b100..2e0d29730b67 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -36,7 +36,7 @@ static struct class *tape_class;
struct tape_class_device *register_tape_dev(
struct device * device,
dev_t dev,
- struct file_operations *fops,
+ const struct file_operations *fops,
char * device_name,
char * mode_name)
{
diff --git a/drivers/s390/char/tape_class.h b/drivers/s390/char/tape_class.h
index 3d0ca054cdee..a8bd9b47fad6 100644
--- a/drivers/s390/char/tape_class.h
+++ b/drivers/s390/char/tape_class.h
@@ -52,7 +52,7 @@ struct tape_class_device {
struct tape_class_device *register_tape_dev(
struct device * device,
dev_t dev,
- struct file_operations *fops,
+ const struct file_operations *fops,
char * device_name,
char * node_name
);
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c
index 655d375ab22b..cea49f001f89 100644
--- a/drivers/s390/char/tape_proc.c
+++ b/drivers/s390/char/tape_proc.c
@@ -109,7 +109,7 @@ static int tape_proc_open(struct inode *inode, struct file *file)
return seq_open(file, &tape_proc_seq);
}
-static struct file_operations tape_proc_ops =
+static const struct file_operations tape_proc_ops =
{
.open = tape_proc_open,
.read = seq_read,
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index a420cd099041..fce3dac5cb3e 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -173,7 +173,7 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
}
-static struct file_operations vmcp_fops = {
+static const struct file_operations vmcp_fops = {
.owner = THIS_MODULE,
.open = &vmcp_open,
.release = &vmcp_release,
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 8432a76b961e..b87d3b019936 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -88,7 +88,7 @@ static int vmlogrdr_release(struct inode *, struct file *);
static ssize_t vmlogrdr_read (struct file *filp, char __user *data,
size_t count, loff_t * ppos);
-static struct file_operations vmlogrdr_fops = {
+static const struct file_operations vmlogrdr_fops = {
.owner = THIS_MODULE,
.open = vmlogrdr_open,
.release = vmlogrdr_release,
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index 4b868f72fe89..680b9b58b80e 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -228,7 +228,7 @@ static ssize_t vmwdt_write(struct file *f, const char __user *buf,
return count;
}
-static struct file_operations vmwdt_fops = {
+static const struct file_operations vmwdt_fops = {
.open = &vmwdt_open,
.release = &vmwdt_close,
.ioctl = &vmwdt_ioctl,
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index aa65df4dfced..ec0404874fad 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -364,7 +364,7 @@ cio_ignore_proc_open(struct inode *inode, struct file *file)
return seq_open(file, &cio_ignore_proc_seq_ops);
}
-static struct file_operations cio_ignore_proc_fops = {
+static const struct file_operations cio_ignore_proc_fops = {
.open = cio_ignore_proc_open,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index f17275917fe5..997f46874537 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/kernel.h>
#include <asm/ccwdev.h>
#include <asm/delay.h>
@@ -138,7 +139,7 @@ VM_virtual_device_info (__u16 devno, struct senseid *ps)
ps->cu_model = 0x60;
return;
}
- for (i = 0; i < sizeof(vm_devices) / sizeof(vm_devices[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(vm_devices); i++)
if (diag_data.vrdcvcla == vm_devices[i].vrdcvcla &&
diag_data.vrdcvtyp == vm_devices[i].vrdcvtyp) {
ps->cu_type = vm_devices[i].cu_type;
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index d7b25b8f71d2..7c7775aae38a 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -23,8 +23,7 @@
#include "chsc.h"
#include "device.h"
-int
-ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
+int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags)
{
/*
* The flag usage is mutal exclusive ...
@@ -39,6 +38,33 @@ ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
return 0;
}
+int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
+{
+ /*
+ * The flag usage is mutal exclusive ...
+ */
+ if (((flags & CCWDEV_EARLY_NOTIFICATION) &&
+ (flags & CCWDEV_REPORT_ALL)) ||
+ ((flags & CCWDEV_EARLY_NOTIFICATION) &&
+ cdev->private->options.repall) ||
+ ((flags & CCWDEV_REPORT_ALL) &&
+ cdev->private->options.fast))
+ return -EINVAL;
+ cdev->private->options.fast |= (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
+ cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0;
+ cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0;
+ cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0;
+ return 0;
+}
+
+void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags)
+{
+ cdev->private->options.fast &= (flags & CCWDEV_EARLY_NOTIFICATION) == 0;
+ cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0;
+ cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0;
+ cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0;
+}
+
int
ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
{
@@ -601,7 +627,9 @@ _ccw_device_get_device_number(struct ccw_device *cdev)
MODULE_LICENSE("GPL");
+EXPORT_SYMBOL(ccw_device_set_options_mask);
EXPORT_SYMBOL(ccw_device_set_options);
+EXPORT_SYMBOL(ccw_device_clear_options);
EXPORT_SYMBOL(ccw_device_clear);
EXPORT_SYMBOL(ccw_device_halt);
EXPORT_SYMBOL(ccw_device_resume);
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index d726cd5777de..5b1e3ff26c0b 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -3194,7 +3194,7 @@ qdio_establish(struct qdio_initialize *init_data)
spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags);
- ccw_device_set_options(cdev, 0);
+ ccw_device_set_options_mask(cdev, 0);
result=ccw_device_start_timeout(cdev,&irq_ptr->ccw,
QDIO_DOING_ESTABLISH,0, 0,
QDIO_ESTABLISH_TIMEOUT);
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index b9e59bc9435a..99761391f340 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -807,7 +807,7 @@ static long zcrypt_compat_ioctl(struct file *filp, unsigned int cmd,
/**
* Misc device file operations.
*/
-static struct file_operations zcrypt_fops = {
+static const struct file_operations zcrypt_fops = {
.owner = THIS_MODULE,
.read = zcrypt_read,
.write = zcrypt_write,
@@ -1063,7 +1063,6 @@ int __init zcrypt_api_init(void)
rc = -ENOMEM;
goto out_misc;
}
- zcrypt_entry->nlink = 1;
zcrypt_entry->data = NULL;
zcrypt_entry->read_proc = zcrypt_status_read;
zcrypt_entry->write_proc = zcrypt_status_write;
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index b97dd15bdb9a..ecca1046714e 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -1511,8 +1511,7 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
LCS_DBF_TEXT(5, trace, "txbuffcb");
/* Put buffer back to pool. */
lcs_release_buffer(channel, buffer);
- card = (struct lcs_card *)
- ((char *) channel - offsetof(struct lcs_card, write));
+ card = container_of(channel, struct lcs_card, write);
if (netif_queue_stopped(card->dev) && netif_carrier_ok(card->dev))
netif_wake_queue(card->dev);
spin_lock(&card->lock);
@@ -1810,8 +1809,7 @@ lcs_get_frames_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
LCS_DBF_TEXT(4, trace, "-eiogpkt");
return;
}
- card = (struct lcs_card *)
- ((char *) channel - offsetof(struct lcs_card, read));
+ card = container_of(channel, struct lcs_card, read);
offset = 0;
while (lcs_hdr->offset != 0) {
if (lcs_hdr->offset <= 0 ||
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index faa768e59257..81f805cc5ee7 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -161,7 +161,7 @@ qeth_procfile_open(struct inode *inode, struct file *file)
return seq_open(file, &qeth_procfile_seq_ops);
}
-static struct file_operations qeth_procfile_fops = {
+static const struct file_operations qeth_procfile_fops = {
.owner = THIS_MODULE,
.open = qeth_procfile_open,
.read = seq_read,
@@ -273,7 +273,7 @@ qeth_perf_procfile_open(struct inode *inode, struct file *file)
return seq_open(file, &qeth_perf_procfile_seq_ops);
}
-static struct file_operations qeth_perf_procfile_fops = {
+static const struct file_operations qeth_perf_procfile_fops = {
.owner = THIS_MODULE,
.open = qeth_perf_procfile_open,
.read = seq_read,
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 39a885266790..1f9554e08013 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -60,7 +60,7 @@ static long zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long);
_IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_sense_data)
-static struct file_operations zfcp_cfdc_fops = {
+static const struct file_operations zfcp_cfdc_fops = {
.unlocked_ioctl = zfcp_cfdc_dev_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = zfcp_cfdc_dev_ioctl
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 88642dec080c..421da1e7c0ea 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -838,32 +838,28 @@ zfcp_erp_action_exists(struct zfcp_erp_action *erp_action)
* and does appropriate preparations (dismiss fsf request, ...)
*
* locks: called under erp_lock (disabled interrupts)
- *
- * returns: 0
*/
-static int
+static void
zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
{
- int retval = 0;
- struct zfcp_fsf_req *fsf_req = NULL;
struct zfcp_adapter *adapter = erp_action->adapter;
if (erp_action->fsf_req) {
/* take lock to ensure that request is not deleted meanwhile */
spin_lock(&adapter->req_list_lock);
- if ((!zfcp_reqlist_ismember(adapter,
- erp_action->fsf_req->req_id)) &&
- (fsf_req->erp_action == erp_action)) {
+ if (zfcp_reqlist_ismember(adapter,
+ erp_action->fsf_req->req_id)) {
/* fsf_req still exists */
debug_text_event(adapter->erp_dbf, 3, "a_ca_req");
- debug_event(adapter->erp_dbf, 3, &fsf_req,
+ debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req,
sizeof (unsigned long));
/* dismiss fsf_req of timed out/dismissed erp_action */
if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED |
ZFCP_STATUS_ERP_TIMEDOUT)) {
debug_text_event(adapter->erp_dbf, 3,
"a_ca_disreq");
- fsf_req->status |= ZFCP_STATUS_FSFREQ_DISMISSED;
+ erp_action->fsf_req->status |=
+ ZFCP_STATUS_FSFREQ_DISMISSED;
}
if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
ZFCP_LOG_NORMAL("error: erp step timed out "
@@ -876,11 +872,11 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
* then keep it running asynchronously and don't mess
* with the association of erp_action and fsf_req.
*/
- if (fsf_req->status & (ZFCP_STATUS_FSFREQ_COMPLETED |
+ if (erp_action->fsf_req->status &
+ (ZFCP_STATUS_FSFREQ_COMPLETED |
ZFCP_STATUS_FSFREQ_DISMISSED)) {
/* forget about association between fsf_req
and erp_action */
- fsf_req->erp_action = NULL;
erp_action->fsf_req = NULL;
}
} else {
@@ -894,8 +890,6 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
spin_unlock(&adapter->req_list_lock);
} else
debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq");
-
- return retval;
}
/**
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index cda0cc095ad1..01386ac688a2 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -89,7 +89,7 @@ extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **,
u32, u32, struct zfcp_sg_list *);
extern void zfcp_fsf_start_timer(struct zfcp_fsf_req *, unsigned long);
extern void zfcp_erp_start_timer(struct zfcp_fsf_req *);
-extern int zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
+extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
extern int zfcp_fsf_status_read(struct zfcp_adapter *, int);
extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *,
unsigned long *, struct zfcp_fsf_req **);
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 4b3ae3f22e78..ef16f7ca4bb1 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -176,28 +176,25 @@ static void zfcp_fsf_req_dismiss(struct zfcp_adapter *adapter,
/**
* zfcp_fsf_req_dismiss_all - dismiss all remaining fsf requests
*/
-int zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
+void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
{
struct zfcp_fsf_req *request, *tmp;
unsigned long flags;
+ LIST_HEAD(remove_queue);
unsigned int i, counter;
spin_lock_irqsave(&adapter->req_list_lock, flags);
atomic_set(&adapter->reqs_active, 0);
- for (i=0; i<REQUEST_LIST_SIZE; i++) {
- if (list_empty(&adapter->req_list[i]))
- continue;
-
- counter = 0;
- list_for_each_entry_safe(request, tmp,
- &adapter->req_list[i], list) {
- zfcp_fsf_req_dismiss(adapter, request, counter);
- counter++;
- }
- }
+ for (i=0; i<REQUEST_LIST_SIZE; i++)
+ list_splice_init(&adapter->req_list[i], &remove_queue);
+
spin_unlock_irqrestore(&adapter->req_list_lock, flags);
- return 0;
+ counter = 0;
+ list_for_each_entry_safe(request, tmp, &remove_queue, list) {
+ zfcp_fsf_req_dismiss(adapter, request, counter);
+ counter++;
+ }
}
/*
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index ac7d1258efee..a39ee80c9715 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -846,7 +846,7 @@ static int bpp_ioctl(struct inode *inode, struct file *f, unsigned int cmd,
return errno;
}
-static struct file_operations bpp_fops = {
+static const struct file_operations bpp_fops = {
.owner = THIS_MODULE,
.read = bpp_read,
.write = bpp_write,
diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
index ad1c7db96cb4..0cfd1e4c032c 100644
--- a/drivers/sbus/char/cpwatchdog.c
+++ b/drivers/sbus/char/cpwatchdog.c
@@ -459,7 +459,7 @@ static irqreturn_t wd_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static struct file_operations wd_fops = {
+static const struct file_operations wd_fops = {
.owner = THIS_MODULE,
.ioctl = wd_ioctl,
.compat_ioctl = wd_compat_ioctl,
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index a4909e0c7f83..2d14a29effe4 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -166,7 +166,7 @@ static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return error;
}
-static struct file_operations d7s_fops = {
+static const struct file_operations d7s_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = d7s_ioctl,
.compat_ioctl = d7s_ioctl,
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index fff4660cdf96..2cea4f5d2084 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -705,7 +705,7 @@ envctrl_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations envctrl_fops = {
+static const struct file_operations envctrl_fops = {
.owner = THIS_MODULE,
.read = envctrl_read,
.unlocked_ioctl = envctrl_ioctl,
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index fa2418f7ad39..6e99507aeb12 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -142,7 +142,7 @@ flash_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations flash_fops = {
+static const struct file_operations flash_fops = {
/* no write to the Flash, use mmap
* and play flash dependent tricks.
*/
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index 14631ac11bc7..512857a23169 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -431,7 +431,7 @@ static int jsf_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations jsf_fops = {
+static const struct file_operations jsf_fops = {
.owner = THIS_MODULE,
.llseek = jsf_lseek,
.read = jsf_read,
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 4e2a0e2dcc2e..e8776230782b 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -704,7 +704,7 @@ static int openprom_release(struct inode * inode, struct file * file)
return 0;
}
-static struct file_operations openprom_fops = {
+static const struct file_operations openprom_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = openprom_ioctl,
diff --git a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c
index 2a9cc8204429..a2fc6b8c1334 100644
--- a/drivers/sbus/char/riowatchdog.c
+++ b/drivers/sbus/char/riowatchdog.c
@@ -193,7 +193,7 @@ static ssize_t riowd_write(struct file *file, const char __user *buf, size_t cou
return 0;
}
-static struct file_operations riowd_fops = {
+static const struct file_operations riowd_fops = {
.owner = THIS_MODULE,
.ioctl = riowd_ioctl,
.open = riowd_open,
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 9b988baf0b51..94d185829119 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -233,7 +233,7 @@ static int rtc_release(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations rtc_fops = {
+static const struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = rtc_ioctl,
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index b30372f17f1c..4d1a505e9e74 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -224,7 +224,7 @@ static irqreturn_t uctrl_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static struct file_operations uctrl_fops = {
+static const struct file_operations uctrl_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = uctrl_ioctl,
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 386e7de0b7e3..37a04a0cecfa 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -44,7 +44,7 @@
#include "vfc.h"
#include <asm/vfc_ioctls.h>
-static struct file_operations vfc_fops;
+static const struct file_operations vfc_fops;
struct vfc_dev **vfc_dev_lst;
static char vfcstr[]="vfc";
static unsigned char saa9051_init_array[VFC_SAA9051_NR] = {
@@ -633,7 +633,7 @@ static int vfc_mmap(struct file *file, struct vm_area_struct *vma)
}
-static struct file_operations vfc_fops = {
+static const struct file_operations vfc_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = vfc_ioctl,
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
index 98fcbb3d5560..6349dd617f85 100644
--- a/drivers/sbus/sbus.c
+++ b/drivers/sbus/sbus.c
@@ -7,6 +7,7 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/device.h>
#include <asm/system.h>
#include <asm/sbus.h>
@@ -17,13 +18,25 @@
#include <asm/bpp.h>
#include <asm/irq.h>
+static ssize_t
+show_sbusobppath_attr(struct device * dev, struct device_attribute * attr, char * buf)
+{
+ struct sbus_dev *sbus;
+
+ sbus = to_sbus_device(dev);
+
+ return snprintf (buf, PAGE_SIZE, "%s\n", sbus->ofdev.node->full_name);
+}
+
+static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_sbusobppath_attr, NULL);
+
struct sbus_bus *sbus_root;
static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev)
{
unsigned long base;
void *pval;
- int len;
+ int len, err;
sdev->prom_node = dp->node;
strcpy(sdev->prom_name, dp->name);
@@ -66,6 +79,9 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde
if (of_device_register(&sdev->ofdev) != 0)
printk(KERN_DEBUG "sbus: device registration error for %s!\n",
dp->path_component_name);
+
+ /* WE HAVE BEEN INVADED BY ALIENS! */
+ err = sysfs_create_file(&sdev->ofdev.dev.kobj, &dev_attr_obppath.attr);
}
static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus)
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index b091a0fc4eb0..eb766c3af1c8 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -197,7 +197,7 @@ static struct class_device_attribute *twa_host_attrs[] = {
};
/* File operations struct for character device */
-static struct file_operations twa_fops = {
+static const struct file_operations twa_fops = {
.owner = THIS_MODULE,
.ioctl = twa_chrdev_ioctl,
.open = twa_chrdev_open,
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index e1b44d6c0c32..bf5d63e1beee 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1040,7 +1040,7 @@ static int tw_chrdev_open(struct inode *inode, struct file *file)
} /* End tw_chrdev_open() */
/* File operations struct for character device */
-static struct file_operations tw_fops = {
+static const struct file_operations tw_fops = {
.owner = THIS_MODULE,
.ioctl = tw_chrdev_ioctl,
.open = tw_chrdev_open,
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 68103e508db7..88e061d13d0b 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -667,12 +667,30 @@ NCR_700_chip_setup(struct Scsi_Host *host)
__u8 min_xferp = (hostdata->chip710 ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP);
if(hostdata->chip710) {
- __u8 burst_disable = hostdata->burst_disable
- ? BURST_DISABLE : 0;
+ __u8 burst_disable = 0;
+ __u8 burst_length = 0;
+
+ switch (hostdata->burst_length) {
+ case 1:
+ burst_length = BURST_LENGTH_1;
+ break;
+ case 2:
+ burst_length = BURST_LENGTH_2;
+ break;
+ case 4:
+ burst_length = BURST_LENGTH_4;
+ break;
+ case 8:
+ burst_length = BURST_LENGTH_8;
+ break;
+ default:
+ burst_disable = BURST_DISABLE;
+ break;
+ }
dcntl_extra = COMPAT_700_MODE;
NCR_700_writeb(dcntl_extra, host, DCNTL_REG);
- NCR_700_writeb(BURST_LENGTH_8 | hostdata->dmode_extra,
+ NCR_700_writeb(burst_length | hostdata->dmode_extra,
host, DMODE_710_REG);
NCR_700_writeb(burst_disable | (hostdata->differential ?
DIFF : 0), host, CTEST7_REG);
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
index f38822db4210..841e1bb27d57 100644
--- a/drivers/scsi/53c700.h
+++ b/drivers/scsi/53c700.h
@@ -203,7 +203,7 @@ struct NCR_700_Host_Parameters {
__u32 force_le_on_be:1;
#endif
__u32 chip710:1; /* set if really a 710 not 700 */
- __u32 burst_disable:1; /* set to 1 to disable 710 bursting */
+ __u32 burst_length:4; /* set to 0 to disable 710 bursting */
/* NOTHING BELOW HERE NEEDS ALTERING */
__u32 fast:1; /* if we can alter the SCSI bus clock
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
index 640536ef77dc..93b41f45638a 100644
--- a/drivers/scsi/53c7xx.c
+++ b/drivers/scsi/53c7xx.c
@@ -3099,7 +3099,6 @@ allocate_cmd (Scsi_Cmnd *cmd) {
real = get_zeroed_page(GFP_ATOMIC);
if (real == 0)
return NULL;
- memset((void *)real, 0, 4096);
cache_push(virt_to_phys((void *)real), 4096);
cache_clear(virt_to_phys((void *)real), 4096);
kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
@@ -4400,7 +4399,7 @@ abort_connected (struct Scsi_Host *host) {
* account the current synchronous offset)
*/
- sstat = (NCR53c8x0_read8 (SSTAT2_REG);
+ sstat = NCR53c8x0_read8 (SSTAT2_REG);
offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
phase = sstat & SSTAT2_PHASE_MASK;
@@ -5423,7 +5422,7 @@ insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
--buffers, offset += segment->length, ++segment)
#if 0
printk("scsi%d: comparing 0x%p to 0x%p\n",
- cmd->device->host->host_no, saved, page_address(segment->page+segment->offset);
+ cmd->device->host->host_no, saved, page_address(segment->page+segment->offset));
#else
;
#endif
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 3075204915c8..e874b8944875 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -192,7 +192,7 @@ static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter, vo
BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
*/
-static boolean __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter)
+static bool __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter)
{
int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
void *BlockPointer;
@@ -238,7 +238,7 @@ static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter)
multiple host adapters share the same IRQ Channel.
*/
-static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, boolean SuccessMessageP)
+static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter, int AdditionalCCBs, bool SuccessMessageP)
{
int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
@@ -362,10 +362,8 @@ static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter, enum BusLo
interrupt could occur if the IRQ Channel was previously enabled by another
BusLogic Host Adapter or another driver sharing the same IRQ Channel.
*/
- if (!HostAdapter->IRQ_ChannelAcquired) {
+ if (!HostAdapter->IRQ_ChannelAcquired)
local_irq_save(ProcessorFlags);
- local_irq_disable();
- }
/*
Wait for the Host Adapter Ready bit to be set and the Command/Parameter
Register Busy bit to be reset in the Status Register.
@@ -639,9 +637,9 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd
struct BusLogic_ProbeInfo *PrimaryProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
- boolean ForceBusDeviceScanningOrder = false;
- boolean ForceBusDeviceScanningOrderChecked = false;
- boolean StandardAddressSeen[6];
+ bool ForceBusDeviceScanningOrder = false;
+ bool ForceBusDeviceScanningOrderChecked = false;
+ bool StandardAddressSeen[6];
struct pci_dev *PCI_Device = NULL;
int i;
if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters)
@@ -1011,7 +1009,7 @@ static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
BusLogic_Failure prints a standardized error message, and then returns false.
*/
-static boolean BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage)
+static bool BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *ErrorMessage)
{
BusLogic_AnnounceDriver(HostAdapter);
if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus) {
@@ -1030,7 +1028,7 @@ static boolean BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter, char *
BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
*/
-static boolean __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
+static bool __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
{
union BusLogic_StatusRegister StatusRegister;
union BusLogic_InterruptRegister InterruptRegister;
@@ -1101,8 +1099,8 @@ static boolean __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *Hos
SCSI Bus Reset.
*/
-static boolean BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
- *HostAdapter, boolean HardReset)
+static bool BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
+ *HostAdapter, bool HardReset)
{
union BusLogic_StatusRegister StatusRegister;
int TimeoutCounter;
@@ -1205,11 +1203,11 @@ static boolean BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
Host Adapter.
*/
-static boolean __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
+static bool __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
{
struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
unsigned char RequestedReplyLength;
- boolean Result = true;
+ bool Result = true;
/*
FlashPoint Host Adapters do not require this protection.
*/
@@ -1239,7 +1237,7 @@ static boolean __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *Hos
from Host Adapter and initializes the Host Adapter structure.
*/
-static boolean __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter
+static bool __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter
*HostAdapter)
{
struct BusLogic_BoardID BoardID;
@@ -1686,14 +1684,14 @@ static boolean __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_Host
Host Adapter.
*/
-static boolean __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter
+static bool __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter
*HostAdapter)
{
unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
unsigned short SynchronousPermitted, FastPermitted;
unsigned short UltraPermitted, WidePermitted;
unsigned short DisconnectPermitted, TaggedQueuingPermitted;
- boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
+ bool CommonSynchronousNegotiation, CommonTaggedQueueDepth;
char SynchronousString[BusLogic_MaxTargetDevices + 1];
char WideString[BusLogic_MaxTargetDevices + 1];
char DisconnectString[BusLogic_MaxTargetDevices + 1];
@@ -1835,7 +1833,7 @@ static boolean __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_Ho
Host Adapter.
*/
-static boolean __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter)
+static bool __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter)
{
if (HostAdapter->IRQ_Channel == 0) {
BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n", HostAdapter);
@@ -1903,7 +1901,7 @@ static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter)
of the Host Adapter from its initial power on or hard reset state.
*/
-static boolean BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
+static bool BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
*HostAdapter)
{
struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest;
@@ -2002,7 +2000,7 @@ static boolean BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
through Host Adapter.
*/
-static boolean __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter
+static bool __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter
*HostAdapter)
{
u16 InstalledDevices;
@@ -2739,7 +2737,7 @@ static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel, void *DeviceIdenti
already have been acquired by the caller.
*/
-static boolean BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter
+static bool BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter
*HostAdapter, enum BusLogic_ActionCode ActionCode, struct BusLogic_CCB *CCB)
{
struct BusLogic_OutgoingMailbox *NextOutgoingMailbox;
@@ -3058,7 +3056,7 @@ static int BusLogic_AbortCommand(struct scsi_cmnd *Command)
currently executing SCSI Commands as having been Reset.
*/
-static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, boolean HardReset)
+static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter, bool HardReset)
{
struct BusLogic_CCB *CCB;
int TargetID;
@@ -3309,7 +3307,7 @@ Target Requested Completed Requested Completed Requested Completed\n\
static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Format, struct BusLogic_HostAdapter *HostAdapter, ...)
{
static char Buffer[BusLogic_LineBufferSize];
- static boolean BeginningOfLine = true;
+ static bool BeginningOfLine = true;
va_list Arguments;
int Length = 0;
va_start(Arguments, HostAdapter);
@@ -3347,7 +3345,7 @@ static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel, char *Form
and updates the pointer if the keyword is recognized and false otherwise.
*/
-static boolean __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
+static bool __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
{
char *Pointer = *StringPointer;
while (*Keyword != '\0') {
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h
index cca6d45eee4d..bfbfb5c3a8f6 100644
--- a/drivers/scsi/BusLogic.h
+++ b/drivers/scsi/BusLogic.h
@@ -234,12 +234,6 @@ enum BusLogic_BIOS_DiskGeometryTranslation {
/*
- Define a Boolean data type.
-*/
-
-typedef bool boolean;
-
-/*
Define a 10^18 Statistics Byte Counter data type.
*/
@@ -269,19 +263,19 @@ struct BusLogic_ProbeInfo {
*/
struct BusLogic_ProbeOptions {
- boolean NoProbe:1; /* Bit 0 */
- boolean NoProbeISA:1; /* Bit 1 */
- boolean NoProbePCI:1; /* Bit 2 */
- boolean NoSortPCI:1; /* Bit 3 */
- boolean MultiMasterFirst:1; /* Bit 4 */
- boolean FlashPointFirst:1; /* Bit 5 */
- boolean LimitedProbeISA:1; /* Bit 6 */
- boolean Probe330:1; /* Bit 7 */
- boolean Probe334:1; /* Bit 8 */
- boolean Probe230:1; /* Bit 9 */
- boolean Probe234:1; /* Bit 10 */
- boolean Probe130:1; /* Bit 11 */
- boolean Probe134:1; /* Bit 12 */
+ bool NoProbe:1; /* Bit 0 */
+ bool NoProbeISA:1; /* Bit 1 */
+ bool NoProbePCI:1; /* Bit 2 */
+ bool NoSortPCI:1; /* Bit 3 */
+ bool MultiMasterFirst:1;/* Bit 4 */
+ bool FlashPointFirst:1; /* Bit 5 */
+ bool LimitedProbeISA:1; /* Bit 6 */
+ bool Probe330:1; /* Bit 7 */
+ bool Probe334:1; /* Bit 8 */
+ bool Probe230:1; /* Bit 9 */
+ bool Probe234:1; /* Bit 10 */
+ bool Probe130:1; /* Bit 11 */
+ bool Probe134:1; /* Bit 12 */
};
/*
@@ -289,10 +283,10 @@ struct BusLogic_ProbeOptions {
*/
struct BusLogic_GlobalOptions {
- boolean TraceProbe:1; /* Bit 0 */
- boolean TraceHardwareReset:1; /* Bit 1 */
- boolean TraceConfiguration:1; /* Bit 2 */
- boolean TraceErrors:1; /* Bit 3 */
+ bool TraceProbe:1; /* Bit 0 */
+ bool TraceHardwareReset:1; /* Bit 1 */
+ bool TraceConfiguration:1; /* Bit 2 */
+ bool TraceErrors:1; /* Bit 3 */
};
/*
@@ -300,7 +294,7 @@ struct BusLogic_GlobalOptions {
*/
struct BusLogic_LocalOptions {
- boolean InhibitTargetInquiry:1; /* Bit 0 */
+ bool InhibitTargetInquiry:1; /* Bit 0 */
};
/*
@@ -322,10 +316,10 @@ union BusLogic_ControlRegister {
unsigned char All;
struct {
unsigned char:4; /* Bits 0-3 */
- boolean SCSIBusReset:1; /* Bit 4 */
- boolean InterruptReset:1; /* Bit 5 */
- boolean SoftReset:1; /* Bit 6 */
- boolean HardReset:1; /* Bit 7 */
+ bool SCSIBusReset:1; /* Bit 4 */
+ bool InterruptReset:1; /* Bit 5 */
+ bool SoftReset:1; /* Bit 6 */
+ bool HardReset:1; /* Bit 7 */
} cr;
};
@@ -336,14 +330,14 @@ union BusLogic_ControlRegister {
union BusLogic_StatusRegister {
unsigned char All;
struct {
- boolean CommandInvalid:1; /* Bit 0 */
- boolean Reserved:1; /* Bit 1 */
- boolean DataInRegisterReady:1; /* Bit 2 */
- boolean CommandParameterRegisterBusy:1; /* Bit 3 */
- boolean HostAdapterReady:1; /* Bit 4 */
- boolean InitializationRequired:1; /* Bit 5 */
- boolean DiagnosticFailure:1; /* Bit 6 */
- boolean DiagnosticActive:1; /* Bit 7 */
+ bool CommandInvalid:1; /* Bit 0 */
+ bool Reserved:1; /* Bit 1 */
+ bool DataInRegisterReady:1; /* Bit 2 */
+ bool CommandParameterRegisterBusy:1; /* Bit 3 */
+ bool HostAdapterReady:1; /* Bit 4 */
+ bool InitializationRequired:1; /* Bit 5 */
+ bool DiagnosticFailure:1; /* Bit 6 */
+ bool DiagnosticActive:1; /* Bit 7 */
} sr;
};
@@ -354,12 +348,12 @@ union BusLogic_StatusRegister {
union BusLogic_InterruptRegister {
unsigned char All;
struct {
- boolean IncomingMailboxLoaded:1; /* Bit 0 */
- boolean OutgoingMailboxAvailable:1; /* Bit 1 */
- boolean CommandComplete:1; /* Bit 2 */
- boolean ExternalBusReset:1; /* Bit 3 */
+ bool IncomingMailboxLoaded:1; /* Bit 0 */
+ bool OutgoingMailboxAvailable:1;/* Bit 1 */
+ bool CommandComplete:1; /* Bit 2 */
+ bool ExternalBusReset:1; /* Bit 3 */
unsigned char Reserved:3; /* Bits 4-6 */
- boolean InterruptValid:1; /* Bit 7 */
+ bool InterruptValid:1; /* Bit 7 */
} ir;
};
@@ -373,7 +367,7 @@ union BusLogic_GeometryRegister {
enum BusLogic_BIOS_DiskGeometryTranslation Drive0Geometry:2; /* Bits 0-1 */
enum BusLogic_BIOS_DiskGeometryTranslation Drive1Geometry:2; /* Bits 2-3 */
unsigned char:3; /* Bits 4-6 */
- boolean ExtendedTranslationEnabled:1; /* Bit 7 */
+ bool ExtendedTranslationEnabled:1; /* Bit 7 */
} gr;
};
@@ -445,16 +439,16 @@ struct BusLogic_BoardID {
struct BusLogic_Configuration {
unsigned char:5; /* Byte 0 Bits 0-4 */
- boolean DMA_Channel5:1; /* Byte 0 Bit 5 */
- boolean DMA_Channel6:1; /* Byte 0 Bit 6 */
- boolean DMA_Channel7:1; /* Byte 0 Bit 7 */
- boolean IRQ_Channel9:1; /* Byte 1 Bit 0 */
- boolean IRQ_Channel10:1; /* Byte 1 Bit 1 */
- boolean IRQ_Channel11:1; /* Byte 1 Bit 2 */
- boolean IRQ_Channel12:1; /* Byte 1 Bit 3 */
+ bool DMA_Channel5:1; /* Byte 0 Bit 5 */
+ bool DMA_Channel6:1; /* Byte 0 Bit 6 */
+ bool DMA_Channel7:1; /* Byte 0 Bit 7 */
+ bool IRQ_Channel9:1; /* Byte 1 Bit 0 */
+ bool IRQ_Channel10:1; /* Byte 1 Bit 1 */
+ bool IRQ_Channel11:1; /* Byte 1 Bit 2 */
+ bool IRQ_Channel12:1; /* Byte 1 Bit 3 */
unsigned char:1; /* Byte 1 Bit 4 */
- boolean IRQ_Channel14:1; /* Byte 1 Bit 5 */
- boolean IRQ_Channel15:1; /* Byte 1 Bit 6 */
+ bool IRQ_Channel14:1; /* Byte 1 Bit 5 */
+ bool IRQ_Channel15:1; /* Byte 1 Bit 6 */
unsigned char:1; /* Byte 1 Bit 7 */
unsigned char HostAdapterID:4; /* Byte 2 Bits 0-3 */
unsigned char:4; /* Byte 2 Bits 4-7 */
@@ -467,12 +461,12 @@ struct BusLogic_Configuration {
struct BusLogic_SynchronousValue {
unsigned char Offset:4; /* Bits 0-3 */
unsigned char TransferPeriod:3; /* Bits 4-6 */
- boolean Synchronous:1; /* Bit 7 */
+ bool Synchronous:1; /* Bit 7 */
};
struct BusLogic_SetupInformation {
- boolean SynchronousInitiationEnabled:1; /* Byte 0 Bit 0 */
- boolean ParityCheckingEnabled:1; /* Byte 0 Bit 1 */
+ bool SynchronousInitiationEnabled:1; /* Byte 0 Bit 0 */
+ bool ParityCheckingEnabled:1; /* Byte 0 Bit 1 */
unsigned char:6; /* Byte 0 Bits 2-7 */
unsigned char BusTransferRate; /* Byte 1 */
unsigned char PreemptTimeOnBus; /* Byte 2 */
@@ -523,13 +517,13 @@ enum BusLogic_ISACompatibleIOPort {
struct BusLogic_PCIHostAdapterInformation {
enum BusLogic_ISACompatibleIOPort ISACompatibleIOPort; /* Byte 0 */
unsigned char PCIAssignedIRQChannel; /* Byte 1 */
- boolean LowByteTerminated:1; /* Byte 2 Bit 0 */
- boolean HighByteTerminated:1; /* Byte 2 Bit 1 */
+ bool LowByteTerminated:1; /* Byte 2 Bit 0 */
+ bool HighByteTerminated:1; /* Byte 2 Bit 1 */
unsigned char:2; /* Byte 2 Bits 2-3 */
- boolean JP1:1; /* Byte 2 Bit 4 */
- boolean JP2:1; /* Byte 2 Bit 5 */
- boolean JP3:1; /* Byte 2 Bit 6 */
- boolean GenericInfoValid:1; /* Byte 2 Bit 7 */
+ bool JP1:1; /* Byte 2 Bit 4 */
+ bool JP2:1; /* Byte 2 Bit 5 */
+ bool JP3:1; /* Byte 2 Bit 6 */
+ bool GenericInfoValid:1;/* Byte 2 Bit 7 */
unsigned char:8; /* Byte 3 */
};
@@ -545,17 +539,17 @@ struct BusLogic_ExtendedSetupInformation {
u32 BaseMailboxAddress; /* Bytes 5-8 */
struct {
unsigned char:2; /* Byte 9 Bits 0-1 */
- boolean FastOnEISA:1; /* Byte 9 Bit 2 */
+ bool FastOnEISA:1; /* Byte 9 Bit 2 */
unsigned char:3; /* Byte 9 Bits 3-5 */
- boolean LevelSensitiveInterrupt:1; /* Byte 9 Bit 6 */
+ bool LevelSensitiveInterrupt:1; /* Byte 9 Bit 6 */
unsigned char:1; /* Byte 9 Bit 7 */
} Misc;
unsigned char FirmwareRevision[3]; /* Bytes 10-12 */
- boolean HostWideSCSI:1; /* Byte 13 Bit 0 */
- boolean HostDifferentialSCSI:1; /* Byte 13 Bit 1 */
- boolean HostSupportsSCAM:1; /* Byte 13 Bit 2 */
- boolean HostUltraSCSI:1; /* Byte 13 Bit 3 */
- boolean HostSmartTermination:1; /* Byte 13 Bit 4 */
+ bool HostWideSCSI:1; /* Byte 13 Bit 0 */
+ bool HostDifferentialSCSI:1; /* Byte 13 Bit 1 */
+ bool HostSupportsSCAM:1; /* Byte 13 Bit 2 */
+ bool HostUltraSCSI:1; /* Byte 13 Bit 3 */
+ bool HostSmartTermination:1; /* Byte 13 Bit 4 */
unsigned char:3; /* Byte 13 Bits 5-7 */
} PACKED;
@@ -590,35 +584,35 @@ struct BusLogic_AutoSCSIData {
unsigned char InformationByteCount; /* Byte 2 */
unsigned char HostAdapterType[6]; /* Bytes 3-8 */
unsigned char:8; /* Byte 9 */
- boolean FloppyEnabled:1; /* Byte 10 Bit 0 */
- boolean FloppySecondary:1; /* Byte 10 Bit 1 */
- boolean LevelSensitiveInterrupt:1; /* Byte 10 Bit 2 */
+ bool FloppyEnabled:1; /* Byte 10 Bit 0 */
+ bool FloppySecondary:1; /* Byte 10 Bit 1 */
+ bool LevelSensitiveInterrupt:1; /* Byte 10 Bit 2 */
unsigned char:2; /* Byte 10 Bits 3-4 */
unsigned char SystemRAMAreaForBIOS:3; /* Byte 10 Bits 5-7 */
unsigned char DMA_Channel:7; /* Byte 11 Bits 0-6 */
- boolean DMA_AutoConfiguration:1; /* Byte 11 Bit 7 */
+ bool DMA_AutoConfiguration:1; /* Byte 11 Bit 7 */
unsigned char IRQ_Channel:7; /* Byte 12 Bits 0-6 */
- boolean IRQ_AutoConfiguration:1; /* Byte 12 Bit 7 */
+ bool IRQ_AutoConfiguration:1; /* Byte 12 Bit 7 */
unsigned char DMA_TransferRate; /* Byte 13 */
unsigned char SCSI_ID; /* Byte 14 */
- boolean LowByteTerminated:1; /* Byte 15 Bit 0 */
- boolean ParityCheckingEnabled:1; /* Byte 15 Bit 1 */
- boolean HighByteTerminated:1; /* Byte 15 Bit 2 */
- boolean NoisyCablingEnvironment:1; /* Byte 15 Bit 3 */
- boolean FastSynchronousNegotiation:1; /* Byte 15 Bit 4 */
- boolean BusResetEnabled:1; /* Byte 15 Bit 5 */
- boolean:1; /* Byte 15 Bit 6 */
- boolean ActiveNegationEnabled:1; /* Byte 15 Bit 7 */
+ bool LowByteTerminated:1; /* Byte 15 Bit 0 */
+ bool ParityCheckingEnabled:1; /* Byte 15 Bit 1 */
+ bool HighByteTerminated:1; /* Byte 15 Bit 2 */
+ bool NoisyCablingEnvironment:1; /* Byte 15 Bit 3 */
+ bool FastSynchronousNegotiation:1; /* Byte 15 Bit 4 */
+ bool BusResetEnabled:1; /* Byte 15 Bit 5 */
+ bool:1; /* Byte 15 Bit 6 */
+ bool ActiveNegationEnabled:1; /* Byte 15 Bit 7 */
unsigned char BusOnDelay; /* Byte 16 */
unsigned char BusOffDelay; /* Byte 17 */
- boolean HostAdapterBIOSEnabled:1; /* Byte 18 Bit 0 */
- boolean BIOSRedirectionOfINT19Enabled:1; /* Byte 18 Bit 1 */
- boolean ExtendedTranslationEnabled:1; /* Byte 18 Bit 2 */
- boolean MapRemovableAsFixedEnabled:1; /* Byte 18 Bit 3 */
- boolean:1; /* Byte 18 Bit 4 */
- boolean BIOSSupportsMoreThan2DrivesEnabled:1; /* Byte 18 Bit 5 */
- boolean BIOSInterruptModeEnabled:1; /* Byte 18 Bit 6 */
- boolean FlopticalSupportEnabled:1; /* Byte 19 Bit 7 */
+ bool HostAdapterBIOSEnabled:1; /* Byte 18 Bit 0 */
+ bool BIOSRedirectionOfINT19Enabled:1; /* Byte 18 Bit 1 */
+ bool ExtendedTranslationEnabled:1; /* Byte 18 Bit 2 */
+ bool MapRemovableAsFixedEnabled:1; /* Byte 18 Bit 3 */
+ bool:1; /* Byte 18 Bit 4 */
+ bool BIOSSupportsMoreThan2DrivesEnabled:1; /* Byte 18 Bit 5 */
+ bool BIOSInterruptModeEnabled:1; /* Byte 18 Bit 6 */
+ bool FlopticalSupportEnabled:1; /* Byte 19 Bit 7 */
unsigned short DeviceEnabled; /* Bytes 19-20 */
unsigned short WidePermitted; /* Bytes 21-22 */
unsigned short FastPermitted; /* Bytes 23-24 */
@@ -628,22 +622,22 @@ struct BusLogic_AutoSCSIData {
unsigned short IgnoreInBIOSScan; /* Bytes 31-32 */
unsigned char PCIInterruptPin:2; /* Byte 33 Bits 0-1 */
unsigned char HostAdapterIOPortAddress:2; /* Byte 33 Bits 2-3 */
- boolean StrictRoundRobinModeEnabled:1; /* Byte 33 Bit 4 */
- boolean VESABusSpeedGreaterThan33MHz:1; /* Byte 33 Bit 5 */
- boolean VESABurstWriteEnabled:1; /* Byte 33 Bit 6 */
- boolean VESABurstReadEnabled:1; /* Byte 33 Bit 7 */
+ bool StrictRoundRobinModeEnabled:1; /* Byte 33 Bit 4 */
+ bool VESABusSpeedGreaterThan33MHz:1; /* Byte 33 Bit 5 */
+ bool VESABurstWriteEnabled:1; /* Byte 33 Bit 6 */
+ bool VESABurstReadEnabled:1; /* Byte 33 Bit 7 */
unsigned short UltraPermitted; /* Bytes 34-35 */
unsigned int:32; /* Bytes 36-39 */
unsigned char:8; /* Byte 40 */
unsigned char AutoSCSIMaximumLUN; /* Byte 41 */
- boolean:1; /* Byte 42 Bit 0 */
- boolean SCAM_Dominant:1; /* Byte 42 Bit 1 */
- boolean SCAM_Enabled:1; /* Byte 42 Bit 2 */
- boolean SCAM_Level2:1; /* Byte 42 Bit 3 */
+ bool:1; /* Byte 42 Bit 0 */
+ bool SCAM_Dominant:1; /* Byte 42 Bit 1 */
+ bool SCAM_Enabled:1; /* Byte 42 Bit 2 */
+ bool SCAM_Level2:1; /* Byte 42 Bit 3 */
unsigned char:4; /* Byte 42 Bits 4-7 */
- boolean INT13ExtensionEnabled:1; /* Byte 43 Bit 0 */
- boolean:1; /* Byte 43 Bit 1 */
- boolean CDROMBootEnabled:1; /* Byte 43 Bit 2 */
+ bool INT13ExtensionEnabled:1; /* Byte 43 Bit 0 */
+ bool:1; /* Byte 43 Bit 1 */
+ bool CDROMBootEnabled:1; /* Byte 43 Bit 2 */
unsigned char:5; /* Byte 43 Bits 3-7 */
unsigned char BootTargetID:4; /* Byte 44 Bits 0-3 */
unsigned char BootChannel:4; /* Byte 44 Bits 4-7 */
@@ -852,7 +846,7 @@ struct BusLogic_CCB {
enum BusLogic_CCB_Opcode Opcode; /* Byte 0 */
unsigned char:3; /* Byte 1 Bits 0-2 */
enum BusLogic_DataDirection DataDirection:2; /* Byte 1 Bits 3-4 */
- boolean TagEnable:1; /* Byte 1 Bit 5 */
+ bool TagEnable:1; /* Byte 1 Bit 5 */
enum BusLogic_QueueTag QueueTag:2; /* Byte 1 Bits 6-7 */
unsigned char CDB_Length; /* Byte 2 */
unsigned char SenseDataLength; /* Byte 3 */
@@ -864,7 +858,7 @@ struct BusLogic_CCB {
enum BusLogic_TargetDeviceStatus TargetDeviceStatus; /* Byte 15 */
unsigned char TargetID; /* Byte 16 */
unsigned char LogicalUnit:5; /* Byte 17 Bits 0-4 */
- boolean LegacyTagEnable:1; /* Byte 17 Bit 5 */
+ bool LegacyTagEnable:1; /* Byte 17 Bit 5 */
enum BusLogic_QueueTag LegacyQueueTag:2; /* Byte 17 Bits 6-7 */
SCSI_CDB_T CDB; /* Bytes 18-29 */
unsigned char:8; /* Byte 30 */
@@ -939,13 +933,13 @@ struct BusLogic_DriverOptions {
*/
struct BusLogic_TargetFlags {
- boolean TargetExists:1;
- boolean TaggedQueuingSupported:1;
- boolean WideTransfersSupported:1;
- boolean TaggedQueuingActive:1;
- boolean WideTransfersActive:1;
- boolean CommandSuccessfulFlag:1;
- boolean TargetInfoReported:1;
+ bool TargetExists:1;
+ bool TaggedQueuingSupported:1;
+ bool WideTransfersSupported:1;
+ bool TaggedQueuingActive:1;
+ bool WideTransfersActive:1;
+ bool CommandSuccessfulFlag:1;
+ bool TargetInfoReported:1;
};
/*
@@ -992,7 +986,7 @@ typedef unsigned int FlashPoint_CardHandle_T;
struct FlashPoint_Info {
u32 BaseAddress; /* Bytes 0-3 */
- boolean Present; /* Byte 4 */
+ bool Present; /* Byte 4 */
unsigned char IRQ_Channel; /* Byte 5 */
unsigned char SCSI_ID; /* Byte 6 */
unsigned char SCSI_LUN; /* Byte 7 */
@@ -1002,15 +996,15 @@ struct FlashPoint_Info {
unsigned short UltraPermitted; /* Bytes 14-15 */
unsigned short DisconnectPermitted; /* Bytes 16-17 */
unsigned short WidePermitted; /* Bytes 18-19 */
- boolean ParityCheckingEnabled:1; /* Byte 20 Bit 0 */
- boolean HostWideSCSI:1; /* Byte 20 Bit 1 */
- boolean HostSoftReset:1; /* Byte 20 Bit 2 */
- boolean ExtendedTranslationEnabled:1; /* Byte 20 Bit 3 */
- boolean LowByteTerminated:1; /* Byte 20 Bit 4 */
- boolean HighByteTerminated:1; /* Byte 20 Bit 5 */
- boolean ReportDataUnderrun:1; /* Byte 20 Bit 6 */
- boolean SCAM_Enabled:1; /* Byte 20 Bit 7 */
- boolean SCAM_Level2:1; /* Byte 21 Bit 0 */
+ bool ParityCheckingEnabled:1; /* Byte 20 Bit 0 */
+ bool HostWideSCSI:1; /* Byte 20 Bit 1 */
+ bool HostSoftReset:1; /* Byte 20 Bit 2 */
+ bool ExtendedTranslationEnabled:1; /* Byte 20 Bit 3 */
+ bool LowByteTerminated:1; /* Byte 20 Bit 4 */
+ bool HighByteTerminated:1; /* Byte 20 Bit 5 */
+ bool ReportDataUnderrun:1; /* Byte 20 Bit 6 */
+ bool SCAM_Enabled:1; /* Byte 20 Bit 7 */
+ bool SCAM_Level2:1; /* Byte 21 Bit 0 */
unsigned char:7; /* Byte 21 Bits 1-7 */
unsigned char Family; /* Byte 22 */
unsigned char BusType; /* Byte 23 */
@@ -1044,29 +1038,29 @@ struct BusLogic_HostAdapter {
unsigned char IRQ_Channel;
unsigned char DMA_Channel;
unsigned char SCSI_ID;
- boolean IRQ_ChannelAcquired:1;
- boolean DMA_ChannelAcquired:1;
- boolean ExtendedTranslationEnabled:1;
- boolean ParityCheckingEnabled:1;
- boolean BusResetEnabled:1;
- boolean LevelSensitiveInterrupt:1;
- boolean HostWideSCSI:1;
- boolean HostDifferentialSCSI:1;
- boolean HostSupportsSCAM:1;
- boolean HostUltraSCSI:1;
- boolean ExtendedLUNSupport:1;
- boolean TerminationInfoValid:1;
- boolean LowByteTerminated:1;
- boolean HighByteTerminated:1;
- boolean BounceBuffersRequired:1;
- boolean StrictRoundRobinModeSupport:1;
- boolean SCAM_Enabled:1;
- boolean SCAM_Level2:1;
- boolean HostAdapterInitialized:1;
- boolean HostAdapterExternalReset:1;
- boolean HostAdapterInternalError:1;
- boolean ProcessCompletedCCBsActive;
- volatile boolean HostAdapterCommandCompleted;
+ bool IRQ_ChannelAcquired:1;
+ bool DMA_ChannelAcquired:1;
+ bool ExtendedTranslationEnabled:1;
+ bool ParityCheckingEnabled:1;
+ bool BusResetEnabled:1;
+ bool LevelSensitiveInterrupt:1;
+ bool HostWideSCSI:1;
+ bool HostDifferentialSCSI:1;
+ bool HostSupportsSCAM:1;
+ bool HostUltraSCSI:1;
+ bool ExtendedLUNSupport:1;
+ bool TerminationInfoValid:1;
+ bool LowByteTerminated:1;
+ bool HighByteTerminated:1;
+ bool BounceBuffersRequired:1;
+ bool StrictRoundRobinModeSupport:1;
+ bool SCAM_Enabled:1;
+ bool SCAM_Level2:1;
+ bool HostAdapterInitialized:1;
+ bool HostAdapterExternalReset:1;
+ bool HostAdapterInternalError:1;
+ bool ProcessCompletedCCBsActive;
+ volatile bool HostAdapterCommandCompleted;
unsigned short HostAdapterScatterGatherLimit;
unsigned short DriverScatterGatherLimit;
unsigned short MaxTargetDevices;
@@ -1141,25 +1135,25 @@ struct SCSI_Inquiry {
unsigned char PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */
unsigned char PeripheralQualifier:3; /* Byte 0 Bits 5-7 */
unsigned char DeviceTypeModifier:7; /* Byte 1 Bits 0-6 */
- boolean RMB:1; /* Byte 1 Bit 7 */
+ bool RMB:1; /* Byte 1 Bit 7 */
unsigned char ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */
unsigned char ECMA_Version:3; /* Byte 2 Bits 3-5 */
unsigned char ISO_Version:2; /* Byte 2 Bits 6-7 */
unsigned char ResponseDataFormat:4; /* Byte 3 Bits 0-3 */
unsigned char:2; /* Byte 3 Bits 4-5 */
- boolean TrmIOP:1; /* Byte 3 Bit 6 */
- boolean AENC:1; /* Byte 3 Bit 7 */
+ bool TrmIOP:1; /* Byte 3 Bit 6 */
+ bool AENC:1; /* Byte 3 Bit 7 */
unsigned char AdditionalLength; /* Byte 4 */
unsigned char:8; /* Byte 5 */
unsigned char:8; /* Byte 6 */
- boolean SftRe:1; /* Byte 7 Bit 0 */
- boolean CmdQue:1; /* Byte 7 Bit 1 */
- boolean:1; /* Byte 7 Bit 2 */
- boolean Linked:1; /* Byte 7 Bit 3 */
- boolean Sync:1; /* Byte 7 Bit 4 */
- boolean WBus16:1; /* Byte 7 Bit 5 */
- boolean WBus32:1; /* Byte 7 Bit 6 */
- boolean RelAdr:1; /* Byte 7 Bit 7 */
+ bool SftRe:1; /* Byte 7 Bit 0 */
+ bool CmdQue:1; /* Byte 7 Bit 1 */
+ bool:1; /* Byte 7 Bit 2 */
+ bool Linked:1; /* Byte 7 Bit 3 */
+ bool Sync:1; /* Byte 7 Bit 4 */
+ bool WBus16:1; /* Byte 7 Bit 5 */
+ bool WBus32:1; /* Byte 7 Bit 6 */
+ bool RelAdr:1; /* Byte 7 Bit 7 */
unsigned char VendorIdentification[8]; /* Bytes 8-15 */
unsigned char ProductIdentification[16]; /* Bytes 16-31 */
unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */
@@ -1348,7 +1342,7 @@ static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *, char *, char **, off_t
static int BusLogic_SlaveConfigure(struct scsi_device *);
static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *);
static irqreturn_t BusLogic_InterruptHandler(int, void *);
-static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *, boolean HardReset);
+static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *, bool HardReset);
static void BusLogic_Message(enum BusLogic_MessageLevel, char *, struct BusLogic_HostAdapter *, ...);
static int __init BusLogic_Setup(char *);
diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c
index 7c0068049586..a7f916c0c9cd 100644
--- a/drivers/scsi/FlashPoint.c
+++ b/drivers/scsi/FlashPoint.c
@@ -7609,7 +7609,7 @@ FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle,
FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
}
-static inline boolean
+static inline bool
FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
{
return FlashPoint_InterruptPending(CardHandle);
@@ -7640,7 +7640,7 @@ extern FlashPoint_CardHandle_T
FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
-extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
+extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 7869c34a4a3e..5bf3f07870ba 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -973,6 +973,15 @@ config SCSI_LASI700
many PA-RISC workstations & servers. If you do not know whether you
have a Lasi chip, it is safe to say "Y" here.
+config SCSI_SNI_53C710
+ tristate "SNI RM SCSI support for 53c710"
+ depends on SNI_RM && SCSI
+ select SCSI_SPI_ATTRS
+ select 53C700_LE_ON_BE
+ help
+ This is a driver for the onboard SCSI controller found in older
+ SNI RM workstations & servers.
+
config 53C700_LE_ON_BE
bool
depends on SCSI_LASI700
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index bd7c9888f7f4..79ecf4ebe6eb 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -124,6 +124,7 @@ obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o
obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o
obj-$(CONFIG_SCSI_FCAL) += fcal.o
obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
+obj-$(CONFIG_SCSI_SNI_53C710) += 53c700.o sni_53c710.o
obj-$(CONFIG_SCSI_NSP32) += nsp32.o
obj-$(CONFIG_SCSI_IPR) += ipr.o
obj-$(CONFIG_SCSI_SRP) += libsrp.o
diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
index 9859cd17fc57..f12864abed2f 100644
--- a/drivers/scsi/NCR_D700.c
+++ b/drivers/scsi/NCR_D700.c
@@ -200,6 +200,7 @@ NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq,
hostdata->base = ioport_map(region, 64);
hostdata->differential = (((1<<siop) & differential) != 0);
hostdata->clock = NCR_D700_CLOCK_MHZ;
+ hostdata->burst_length = 8;
/* and register the siop */
host = NCR_700_detect(&NCR_D700_driver_template, hostdata, p->dev);
diff --git a/drivers/scsi/aacraid/Makefile b/drivers/scsi/aacraid/Makefile
index 28d133a3094f..f1cca4ee5410 100644
--- a/drivers/scsi/aacraid/Makefile
+++ b/drivers/scsi/aacraid/Makefile
@@ -3,6 +3,6 @@
obj-$(CONFIG_SCSI_AACRAID) := aacraid.o
aacraid-objs := linit.o aachba.o commctrl.o comminit.o commsup.o \
- dpcsup.o rx.o sa.o rkt.o
+ dpcsup.o rx.o sa.o rkt.o nark.o
EXTRA_CFLAGS := -Idrivers/scsi
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 426cd6f49f5d..ddb33b06e0ef 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -170,9 +170,9 @@ int acbsize = -1;
module_param(acbsize, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware.");
-int expose_physicals = 0;
+int expose_physicals = -1;
module_param(expose_physicals, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. 0=off, 1=on");
+MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on");
/**
* aac_get_config_status - check the adapter configuration
* @common: adapter to query
@@ -706,6 +706,309 @@ static void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
}
}
+static int aac_bounds_32(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)
+{
+ if (lba & 0xffffffff00000000LL) {
+ int cid = scmd_id(cmd);
+ dprintk((KERN_DEBUG "aacraid: Illegal lba\n"));
+ cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+ SAM_STAT_CHECK_CONDITION;
+ set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
+ HARDWARE_ERROR,
+ SENCODE_INTERNAL_TARGET_FAILURE,
+ ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+ 0, 0);
+ memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+ (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(cmd->sense_buffer))
+ ? sizeof(cmd->sense_buffer)
+ : sizeof(dev->fsa_dev[cid].sense_data));
+ cmd->scsi_done(cmd);
+ return 1;
+ }
+ return 0;
+}
+
+static int aac_bounds_64(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba)
+{
+ return 0;
+}
+
+static void io_callback(void *context, struct fib * fibptr);
+
+static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_raw_io *readcmd;
+ aac_fib_init(fib);
+ readcmd = (struct aac_raw_io *) fib_data(fib);
+ readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
+ readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
+ readcmd->count = cpu_to_le32(count<<9);
+ readcmd->cid = cpu_to_le16(scmd_id(cmd));
+ readcmd->flags = cpu_to_le16(1);
+ readcmd->bpTotal = 0;
+ readcmd->bpComplete = 0;
+
+ aac_build_sgraw(cmd, &readcmd->sg);
+ fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw));
+ BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerRawIo,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_read_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_read64 *readcmd;
+ aac_fib_init(fib);
+ readcmd = (struct aac_read64 *) fib_data(fib);
+ readcmd->command = cpu_to_le32(VM_CtHostRead64);
+ readcmd->cid = cpu_to_le16(scmd_id(cmd));
+ readcmd->sector_count = cpu_to_le16(count);
+ readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
+ readcmd->pad = 0;
+ readcmd->flags = 0;
+
+ aac_build_sg64(cmd, &readcmd->sg);
+ fibsize = sizeof(struct aac_read64) +
+ ((le32_to_cpu(readcmd->sg.count) - 1) *
+ sizeof (struct sgentry64));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerCommand64,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_read_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_read *readcmd;
+ aac_fib_init(fib);
+ readcmd = (struct aac_read *) fib_data(fib);
+ readcmd->command = cpu_to_le32(VM_CtBlockRead);
+ readcmd->cid = cpu_to_le16(scmd_id(cmd));
+ readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
+ readcmd->count = cpu_to_le32(count * 512);
+
+ aac_build_sg(cmd, &readcmd->sg);
+ fibsize = sizeof(struct aac_read) +
+ ((le32_to_cpu(readcmd->sg.count) - 1) *
+ sizeof (struct sgentry));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerCommand,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_raw_io *writecmd;
+ aac_fib_init(fib);
+ writecmd = (struct aac_raw_io *) fib_data(fib);
+ writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
+ writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
+ writecmd->count = cpu_to_le32(count<<9);
+ writecmd->cid = cpu_to_le16(scmd_id(cmd));
+ writecmd->flags = 0;
+ writecmd->bpTotal = 0;
+ writecmd->bpComplete = 0;
+
+ aac_build_sgraw(cmd, &writecmd->sg);
+ fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw));
+ BUG_ON(fibsize > (fib->dev->max_fib_size - sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerRawIo,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_write_block64(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_write64 *writecmd;
+ aac_fib_init(fib);
+ writecmd = (struct aac_write64 *) fib_data(fib);
+ writecmd->command = cpu_to_le32(VM_CtHostWrite64);
+ writecmd->cid = cpu_to_le16(scmd_id(cmd));
+ writecmd->sector_count = cpu_to_le16(count);
+ writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
+ writecmd->pad = 0;
+ writecmd->flags = 0;
+
+ aac_build_sg64(cmd, &writecmd->sg);
+ fibsize = sizeof(struct aac_write64) +
+ ((le32_to_cpu(writecmd->sg.count) - 1) *
+ sizeof (struct sgentry64));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerCommand64,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static int aac_write_block(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count)
+{
+ u16 fibsize;
+ struct aac_write *writecmd;
+ aac_fib_init(fib);
+ writecmd = (struct aac_write *) fib_data(fib);
+ writecmd->command = cpu_to_le32(VM_CtBlockWrite);
+ writecmd->cid = cpu_to_le16(scmd_id(cmd));
+ writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
+ writecmd->count = cpu_to_le32(count * 512);
+ writecmd->sg.count = cpu_to_le32(1);
+ /* ->stable is not used - it did mean which type of write */
+
+ aac_build_sg(cmd, &writecmd->sg);
+ fibsize = sizeof(struct aac_write) +
+ ((le32_to_cpu(writecmd->sg.count) - 1) *
+ sizeof (struct sgentry));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ContainerCommand,
+ fib,
+ fibsize,
+ FsaNormal,
+ 0, 1,
+ (fib_callback) io_callback,
+ (void *) cmd);
+}
+
+static struct aac_srb * aac_scsi_common(struct fib * fib, struct scsi_cmnd * cmd)
+{
+ struct aac_srb * srbcmd;
+ u32 flag;
+ u32 timeout;
+
+ aac_fib_init(fib);
+ switch(cmd->sc_data_direction){
+ case DMA_TO_DEVICE:
+ flag = SRB_DataOut;
+ break;
+ case DMA_BIDIRECTIONAL:
+ flag = SRB_DataIn | SRB_DataOut;
+ break;
+ case DMA_FROM_DEVICE:
+ flag = SRB_DataIn;
+ break;
+ case DMA_NONE:
+ default: /* shuts up some versions of gcc */
+ flag = SRB_NoDataXfer;
+ break;
+ }
+
+ srbcmd = (struct aac_srb*) fib_data(fib);
+ srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
+ srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(cmd)));
+ srbcmd->id = cpu_to_le32(scmd_id(cmd));
+ srbcmd->lun = cpu_to_le32(cmd->device->lun);
+ srbcmd->flags = cpu_to_le32(flag);
+ timeout = cmd->timeout_per_command/HZ;
+ if (timeout == 0)
+ timeout = 1;
+ srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds
+ srbcmd->retry_limit = 0; /* Obsolete parameter */
+ srbcmd->cdb_size = cpu_to_le32(cmd->cmd_len);
+ return srbcmd;
+}
+
+static void aac_srb_callback(void *context, struct fib * fibptr);
+
+static int aac_scsi_64(struct fib * fib, struct scsi_cmnd * cmd)
+{
+ u16 fibsize;
+ struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);
+
+ aac_build_sg64(cmd, (struct sgmap64*) &srbcmd->sg);
+ srbcmd->count = cpu_to_le32(cmd->request_bufflen);
+
+ memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
+ memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);
+ /*
+ * Build Scatter/Gather list
+ */
+ fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) +
+ ((le32_to_cpu(srbcmd->sg.count) & 0xff) *
+ sizeof (struct sgentry64));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ScsiPortCommand64, fib,
+ fibsize, FsaNormal, 0, 1,
+ (fib_callback) aac_srb_callback,
+ (void *) cmd);
+}
+
+static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
+{
+ u16 fibsize;
+ struct aac_srb * srbcmd = aac_scsi_common(fib, cmd);
+
+ aac_build_sg(cmd, (struct sgmap*)&srbcmd->sg);
+ srbcmd->count = cpu_to_le32(cmd->request_bufflen);
+
+ memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
+ memcpy(srbcmd->cdb, cmd->cmnd, cmd->cmd_len);
+ /*
+ * Build Scatter/Gather list
+ */
+ fibsize = sizeof (struct aac_srb) +
+ (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) *
+ sizeof (struct sgentry));
+ BUG_ON (fibsize > (fib->dev->max_fib_size -
+ sizeof(struct aac_fibhdr)));
+
+ /*
+ * Now send the Fib to the adapter
+ */
+ return aac_fib_send(ScsiPortCommand, fib, fibsize, FsaNormal, 0, 1,
+ (fib_callback) aac_srb_callback, (void *) cmd);
+}
+
int aac_get_adapter_info(struct aac_dev* dev)
{
struct fib* fibptr;
@@ -874,14 +1177,27 @@ int aac_get_adapter_info(struct aac_dev* dev)
}
}
/*
- * 57 scatter gather elements
+ * Deal with configuring for the individualized limits of each packet
+ * interface.
*/
- if (!(dev->raw_io_interface)) {
+ dev->a_ops.adapter_scsi = (dev->dac_support)
+ ? aac_scsi_64
+ : aac_scsi_32;
+ if (dev->raw_io_interface) {
+ dev->a_ops.adapter_bounds = (dev->raw_io_64)
+ ? aac_bounds_64
+ : aac_bounds_32;
+ dev->a_ops.adapter_read = aac_read_raw_io;
+ dev->a_ops.adapter_write = aac_write_raw_io;
+ } else {
+ dev->a_ops.adapter_bounds = aac_bounds_32;
dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
sizeof(struct aac_fibhdr) -
sizeof(struct aac_write) + sizeof(struct sgentry)) /
sizeof(struct sgentry);
if (dev->dac_support) {
+ dev->a_ops.adapter_read = aac_read_block64;
+ dev->a_ops.adapter_write = aac_write_block64;
/*
* 38 scatter gather elements
*/
@@ -891,6 +1207,9 @@ int aac_get_adapter_info(struct aac_dev* dev)
sizeof(struct aac_write64) +
sizeof(struct sgentry64)) /
sizeof(struct sgentry64);
+ } else {
+ dev->a_ops.adapter_read = aac_read_block;
+ dev->a_ops.adapter_write = aac_write_block;
}
dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
@@ -1004,8 +1323,6 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
u64 lba;
u32 count;
int status;
-
- u16 fibsize;
struct aac_dev *dev;
struct fib * cmd_fibcontext;
@@ -1059,23 +1376,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
}
dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n",
smp_processor_id(), (unsigned long long)lba, jiffies));
- if ((!(dev->raw_io_interface) || !(dev->raw_io_64)) &&
- (lba & 0xffffffff00000000LL)) {
- dprintk((KERN_DEBUG "aac_read: Illegal lba\n"));
- scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
- SAM_STAT_CHECK_CONDITION;
- set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
- HARDWARE_ERROR,
- SENCODE_INTERNAL_TARGET_FAILURE,
- ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
- 0, 0);
- memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
- (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
- ? sizeof(scsicmd->sense_buffer)
- : sizeof(dev->fsa_dev[cid].sense_data));
- scsicmd->scsi_done(scsicmd);
+ if (aac_adapter_bounds(dev,scsicmd,lba))
return 0;
- }
/*
* Alocate and initialize a Fib
*/
@@ -1083,85 +1385,7 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
return -1;
}
- aac_fib_init(cmd_fibcontext);
-
- if (dev->raw_io_interface) {
- struct aac_raw_io *readcmd;
- readcmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
- readcmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
- readcmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- readcmd->count = cpu_to_le32(count<<9);
- readcmd->cid = cpu_to_le16(cid);
- readcmd->flags = cpu_to_le16(1);
- readcmd->bpTotal = 0;
- readcmd->bpComplete = 0;
-
- aac_build_sgraw(scsicmd, &readcmd->sg);
- fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw));
- BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerRawIo,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- } else if (dev->dac_support == 1) {
- struct aac_read64 *readcmd;
- readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);
- readcmd->command = cpu_to_le32(VM_CtHostRead64);
- readcmd->cid = cpu_to_le16(cid);
- readcmd->sector_count = cpu_to_le16(count);
- readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- readcmd->pad = 0;
- readcmd->flags = 0;
-
- aac_build_sg64(scsicmd, &readcmd->sg);
- fibsize = sizeof(struct aac_read64) +
- ((le32_to_cpu(readcmd->sg.count) - 1) *
- sizeof (struct sgentry64));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerCommand64,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- } else {
- struct aac_read *readcmd;
- readcmd = (struct aac_read *) fib_data(cmd_fibcontext);
- readcmd->command = cpu_to_le32(VM_CtBlockRead);
- readcmd->cid = cpu_to_le32(cid);
- readcmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- readcmd->count = cpu_to_le32(count * 512);
-
- aac_build_sg(scsicmd, &readcmd->sg);
- fibsize = sizeof(struct aac_read) +
- ((le32_to_cpu(readcmd->sg.count) - 1) *
- sizeof (struct sgentry));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerCommand,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- }
-
-
+ status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);
/*
* Check that the command queued to the controller
@@ -1187,7 +1411,6 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
u64 lba;
u32 count;
int status;
- u16 fibsize;
struct aac_dev *dev;
struct fib * cmd_fibcontext;
@@ -1227,22 +1450,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
}
dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n",
smp_processor_id(), (unsigned long long)lba, jiffies));
- if ((!(dev->raw_io_interface) || !(dev->raw_io_64))
- && (lba & 0xffffffff00000000LL)) {
- dprintk((KERN_DEBUG "aac_write: Illegal lba\n"));
- scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
- set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
- HARDWARE_ERROR,
- SENCODE_INTERNAL_TARGET_FAILURE,
- ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
- 0, 0);
- memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
- (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
- ? sizeof(scsicmd->sense_buffer)
- : sizeof(dev->fsa_dev[cid].sense_data));
- scsicmd->scsi_done(scsicmd);
+ if (aac_adapter_bounds(dev,scsicmd,lba))
return 0;
- }
/*
* Allocate and initialize a Fib then setup a BlockWrite command
*/
@@ -1251,85 +1460,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
scsicmd->scsi_done(scsicmd);
return 0;
}
- aac_fib_init(cmd_fibcontext);
- if (dev->raw_io_interface) {
- struct aac_raw_io *writecmd;
- writecmd = (struct aac_raw_io *) fib_data(cmd_fibcontext);
- writecmd->block[0] = cpu_to_le32((u32)(lba&0xffffffff));
- writecmd->block[1] = cpu_to_le32((u32)((lba&0xffffffff00000000LL)>>32));
- writecmd->count = cpu_to_le32(count<<9);
- writecmd->cid = cpu_to_le16(cid);
- writecmd->flags = 0;
- writecmd->bpTotal = 0;
- writecmd->bpComplete = 0;
-
- aac_build_sgraw(scsicmd, &writecmd->sg);
- fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw));
- BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerRawIo,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- } else if (dev->dac_support == 1) {
- struct aac_write64 *writecmd;
- writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext);
- writecmd->command = cpu_to_le32(VM_CtHostWrite64);
- writecmd->cid = cpu_to_le16(cid);
- writecmd->sector_count = cpu_to_le16(count);
- writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- writecmd->pad = 0;
- writecmd->flags = 0;
-
- aac_build_sg64(scsicmd, &writecmd->sg);
- fibsize = sizeof(struct aac_write64) +
- ((le32_to_cpu(writecmd->sg.count) - 1) *
- sizeof (struct sgentry64));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerCommand64,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- } else {
- struct aac_write *writecmd;
- writecmd = (struct aac_write *) fib_data(cmd_fibcontext);
- writecmd->command = cpu_to_le32(VM_CtBlockWrite);
- writecmd->cid = cpu_to_le32(cid);
- writecmd->block = cpu_to_le32((u32)(lba&0xffffffff));
- writecmd->count = cpu_to_le32(count * 512);
- writecmd->sg.count = cpu_to_le32(1);
- /* ->stable is not used - it did mean which type of write */
-
- aac_build_sg(scsicmd, &writecmd->sg);
- fibsize = sizeof(struct aac_write) +
- ((le32_to_cpu(writecmd->sg.count) - 1) *
- sizeof (struct sgentry));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ContainerCommand,
- cmd_fibcontext,
- fibsize,
- FsaNormal,
- 0, 1,
- (fib_callback) io_callback,
- (void *) scsicmd);
- }
+ status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count);
/*
* Check that the command queued to the controller
@@ -2099,10 +2231,6 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
struct fib* cmd_fibcontext;
struct aac_dev* dev;
int status;
- struct aac_srb *srbcmd;
- u16 fibsize;
- u32 flag;
- u32 timeout;
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
if (scmd_id(scsicmd) >= dev->maximum_num_physicals ||
@@ -2112,88 +2240,14 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
return 0;
}
- switch(scsicmd->sc_data_direction){
- case DMA_TO_DEVICE:
- flag = SRB_DataOut;
- break;
- case DMA_BIDIRECTIONAL:
- flag = SRB_DataIn | SRB_DataOut;
- break;
- case DMA_FROM_DEVICE:
- flag = SRB_DataIn;
- break;
- case DMA_NONE:
- default: /* shuts up some versions of gcc */
- flag = SRB_NoDataXfer;
- break;
- }
-
-
/*
* Allocate and initialize a Fib then setup a BlockWrite command
*/
if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
return -1;
}
- aac_fib_init(cmd_fibcontext);
-
- srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext);
- srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
- srbcmd->channel = cpu_to_le32(aac_logical_to_phys(scmd_channel(scsicmd)));
- srbcmd->id = cpu_to_le32(scmd_id(scsicmd));
- srbcmd->lun = cpu_to_le32(scsicmd->device->lun);
- srbcmd->flags = cpu_to_le32(flag);
- timeout = scsicmd->timeout_per_command/HZ;
- if(timeout == 0){
- timeout = 1;
- }
- srbcmd->timeout = cpu_to_le32(timeout); // timeout in seconds
- srbcmd->retry_limit = 0; /* Obsolete parameter */
- srbcmd->cdb_size = cpu_to_le32(scsicmd->cmd_len);
-
- if( dev->dac_support == 1 ) {
- aac_build_sg64(scsicmd, (struct sgmap64*) &srbcmd->sg);
- srbcmd->count = cpu_to_le32(scsicmd->request_bufflen);
-
- memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
- memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len);
- /*
- * Build Scatter/Gather list
- */
- fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) +
- ((le32_to_cpu(srbcmd->sg.count) & 0xff) *
- sizeof (struct sgentry64));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
+ status = aac_adapter_scsi(cmd_fibcontext, scsicmd);
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ScsiPortCommand64, cmd_fibcontext,
- fibsize, FsaNormal, 0, 1,
- (fib_callback) aac_srb_callback,
- (void *) scsicmd);
- } else {
- aac_build_sg(scsicmd, (struct sgmap*)&srbcmd->sg);
- srbcmd->count = cpu_to_le32(scsicmd->request_bufflen);
-
- memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
- memcpy(srbcmd->cdb, scsicmd->cmnd, scsicmd->cmd_len);
- /*
- * Build Scatter/Gather list
- */
- fibsize = sizeof (struct aac_srb) +
- (((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) *
- sizeof (struct sgentry));
- BUG_ON (fibsize > (dev->max_fib_size -
- sizeof(struct aac_fibhdr)));
-
- /*
- * Now send the Fib to the adapter
- */
- status = aac_fib_send(ScsiPortCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1,
- (fib_callback) aac_srb_callback, (void *) scsicmd);
- }
/*
* Check that the command queued to the controller
*/
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 4f8b4c53d435..39ecd0d22eb0 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -5,6 +5,7 @@
#define _nblank(x) #x
#define nblank(x) _nblank(x)[0]
+#include <linux/interrupt.h>
/*------------------------------------------------------------------------------
* D E F I N E S
@@ -485,16 +486,28 @@ enum aac_log_level {
struct aac_dev;
struct fib;
+struct scsi_cmnd;
struct adapter_ops
{
+ /* Low level operations */
void (*adapter_interrupt)(struct aac_dev *dev);
void (*adapter_notify)(struct aac_dev *dev, u32 event);
void (*adapter_disable_int)(struct aac_dev *dev);
+ void (*adapter_enable_int)(struct aac_dev *dev);
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
int (*adapter_check_health)(struct aac_dev *dev);
- int (*adapter_send)(struct fib * fib);
+ /* Transport operations */
int (*adapter_ioremap)(struct aac_dev * dev, u32 size);
+ irqreturn_t (*adapter_intr)(int irq, void *dev_id);
+ /* Packet operations */
+ int (*adapter_deliver)(struct fib * fib);
+ int (*adapter_bounds)(struct aac_dev * dev, struct scsi_cmnd * cmd, u64 lba);
+ int (*adapter_read)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count);
+ int (*adapter_write)(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u32 count);
+ int (*adapter_scsi)(struct fib * fib, struct scsi_cmnd * cmd);
+ /* Administrative operations */
+ int (*adapter_comm)(struct aac_dev * dev, int comm);
};
/*
@@ -1018,7 +1031,9 @@ struct aac_dev
u8 nondasd_support;
u8 dac_support;
u8 raid_scsi_mode;
- u8 new_comm_interface;
+ u8 comm_interface;
+# define AAC_COMM_PRODUCER 0
+# define AAC_COMM_MESSAGE 1
/* macro side-effects BEWARE */
# define raw_io_interface \
init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
@@ -1036,18 +1051,36 @@ struct aac_dev
#define aac_adapter_disable_int(dev) \
(dev)->a_ops.adapter_disable_int(dev)
+#define aac_adapter_enable_int(dev) \
+ (dev)->a_ops.adapter_enable_int(dev)
+
#define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \
(dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4)
#define aac_adapter_check_health(dev) \
(dev)->a_ops.adapter_check_health(dev)
-#define aac_adapter_send(fib) \
- ((fib)->dev)->a_ops.adapter_send(fib)
-
#define aac_adapter_ioremap(dev, size) \
(dev)->a_ops.adapter_ioremap(dev, size)
+#define aac_adapter_deliver(fib) \
+ ((fib)->dev)->a_ops.adapter_deliver(fib)
+
+#define aac_adapter_bounds(dev,cmd,lba) \
+ dev->a_ops.adapter_bounds(dev,cmd,lba)
+
+#define aac_adapter_read(fib,cmd,lba,count) \
+ ((fib)->dev)->a_ops.adapter_read(fib,cmd,lba,count)
+
+#define aac_adapter_write(fib,cmd,lba,count) \
+ ((fib)->dev)->a_ops.adapter_write(fib,cmd,lba,count)
+
+#define aac_adapter_scsi(fib,cmd) \
+ ((fib)->dev)->a_ops.adapter_scsi(fib,cmd)
+
+#define aac_adapter_comm(dev,comm) \
+ (dev)->a_ops.adapter_comm(dev, comm)
+
#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)
/*
@@ -1767,7 +1800,6 @@ static inline u32 cap_to_cyls(sector_t capacity, u32 divisor)
return (u32)capacity;
}
-struct scsi_cmnd;
/* SCp.phase values */
#define AAC_OWNER_MIDLEVEL 0x101
#define AAC_OWNER_LOWLEVEL 0x102
@@ -1794,7 +1826,9 @@ int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg);
int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg);
int aac_rx_init(struct aac_dev *dev);
int aac_rkt_init(struct aac_dev *dev);
+int aac_nark_init(struct aac_dev *dev);
int aac_sa_init(struct aac_dev *dev);
+int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify);
unsigned int aac_response_normal(struct aac_queue * q);
unsigned int aac_command_normal(struct aac_queue * q);
unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index);
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 6d305b2f854e..df67ba686023 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -95,7 +95,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
init->InitFlags = 0;
- if (dev->new_comm_interface) {
+ if (dev->comm_interface == AAC_COMM_MESSAGE) {
init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
}
@@ -297,21 +297,23 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
- sizeof(struct aac_fibhdr)
- sizeof(struct aac_write) + sizeof(struct sgentry))
/ sizeof(struct sgentry);
- dev->new_comm_interface = 0;
+ dev->comm_interface = AAC_COMM_PRODUCER;
dev->raw_io_64 = 0;
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
(status[0] == 0x00000001)) {
if (status[1] & AAC_OPT_NEW_COMM_64)
dev->raw_io_64 = 1;
- if (status[1] & AAC_OPT_NEW_COMM)
- dev->new_comm_interface = dev->a_ops.adapter_send != 0;
- if (dev->new_comm_interface && (status[2] > dev->base_size)) {
+ if (dev->a_ops.adapter_comm &&
+ (status[1] & AAC_OPT_NEW_COMM))
+ dev->comm_interface = AAC_COMM_MESSAGE;
+ if ((dev->comm_interface == AAC_COMM_MESSAGE) &&
+ (status[2] > dev->base_size)) {
aac_adapter_ioremap(dev, 0);
dev->base_size = status[2];
if (aac_adapter_ioremap(dev, status[2])) {
/* remap failed, go back ... */
- dev->new_comm_interface = 0;
+ dev->comm_interface = AAC_COMM_PRODUCER;
if (aac_adapter_ioremap(dev, AAC_MIN_FOOTPRINT_SIZE)) {
printk(KERN_WARNING
"aacraid: unable to map adapter.\n");
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 4893a6d06a33..1b97f60652ba 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -317,7 +317,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
* success.
*/
-static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify)
+int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify)
{
struct aac_entry * entry = NULL;
int map = 0;
@@ -387,7 +387,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
{
struct aac_dev * dev = fibptr->dev;
struct hw_fib * hw_fib = fibptr->hw_fib;
- struct aac_queue * q;
unsigned long flags = 0;
unsigned long qflags;
@@ -469,38 +468,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
if (!dev->queues)
return -EBUSY;
- q = &dev->queues->queue[AdapNormCmdQueue];
if(wait)
spin_lock_irqsave(&fibptr->event_lock, flags);
- spin_lock_irqsave(q->lock, qflags);
- if (dev->new_comm_interface) {
- unsigned long count = 10000000L; /* 50 seconds */
- q->numpending++;
- spin_unlock_irqrestore(q->lock, qflags);
- while (aac_adapter_send(fibptr) != 0) {
- if (--count == 0) {
- if (wait)
- spin_unlock_irqrestore(&fibptr->event_lock, flags);
- spin_lock_irqsave(q->lock, qflags);
- q->numpending--;
- spin_unlock_irqrestore(q->lock, qflags);
- return -ETIMEDOUT;
- }
- udelay(5);
- }
- } else {
- u32 index;
- unsigned long nointr = 0;
- aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);
-
- q->numpending++;
- *(q->headers.producer) = cpu_to_le32(index + 1);
- spin_unlock_irqrestore(q->lock, qflags);
- dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index));
- if (!(nointr & aac_config.irq_mod))
- aac_adapter_notify(dev, AdapNormCmdQueue);
- }
+ aac_adapter_deliver(fibptr);
/*
* If the caller wanted us to wait for response wait now.
@@ -520,6 +491,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
while (down_trylock(&fibptr->event_wait)) {
int blink;
if (--count == 0) {
+ struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue];
spin_lock_irqsave(q->lock, qflags);
q->numpending--;
spin_unlock_irqrestore(q->lock, qflags);
@@ -659,7 +631,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
unsigned long qflags;
if (hw_fib->header.XferState == 0) {
- if (dev->new_comm_interface)
+ if (dev->comm_interface == AAC_COMM_MESSAGE)
kfree (hw_fib);
return 0;
}
@@ -667,7 +639,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
* If we plan to do anything check the structure type first.
*/
if ( hw_fib->header.StructType != FIB_MAGIC ) {
- if (dev->new_comm_interface)
+ if (dev->comm_interface == AAC_COMM_MESSAGE)
kfree (hw_fib);
return -EINVAL;
}
@@ -679,7 +651,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
* send the completed cdb to the adapter.
*/
if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
- if (dev->new_comm_interface) {
+ if (dev->comm_interface == AAC_COMM_MESSAGE) {
kfree (hw_fib);
} else {
u32 index;
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index d2cf875af59b..0f948c2fb609 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -157,6 +157,7 @@ static struct pci_device_id aac_pci_tbl[] = {
{ 0x9005, 0x0285, 0x17aa, PCI_ANY_ID, 0, 0, 58 }, /* Legend Catchall */
{ 0x9005, 0x0285, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 59 }, /* Adaptec Catch All */
{ 0x9005, 0x0286, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 60 }, /* Adaptec Rocket Catch All */
+ { 0x9005, 0x0288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 61 }, /* Adaptec NEMER/ARK Catch All */
{ 0,}
};
MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
@@ -230,7 +231,8 @@ static struct aac_driver_ident aac_drivers[] = {
{ aac_rx_init, "aacraid", "DELL ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Dell Catchall */
{ aac_rx_init, "aacraid", "Legend ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Legend Catchall */
{ aac_rx_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec Catch All */
- { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec Rocket Catch All */
+ { aac_rkt_init, "aacraid", "ADAPTEC ", "RAID ", 2 }, /* Adaptec Rocket Catch All */
+ { aac_nark_init, "aacraid", "ADAPTEC ", "RAID ", 2 } /* Adaptec NEMER/ARK Catch All */
};
/**
@@ -396,11 +398,15 @@ static int aac_slave_configure(struct scsi_device *sdev)
sdev->skip_ms_page_3f = 1;
}
if ((sdev->type == TYPE_DISK) &&
- !expose_physicals &&
(sdev_channel(sdev) != CONTAINER_CHANNEL)) {
- struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
- if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
- sdev->no_uld_attach = 1;
+ if (expose_physicals == 0)
+ return -ENXIO;
+ if (expose_physicals < 0) {
+ struct aac_dev *aac =
+ (struct aac_dev *)sdev->host->hostdata;
+ if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))
+ sdev->no_uld_attach = 1;
+ }
}
if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
(sdev_channel(sdev) == CONTAINER_CHANNEL)) {
@@ -768,7 +774,7 @@ static struct class_device_attribute *aac_attrs[] = {
};
-static struct file_operations aac_cfg_fops = {
+static const struct file_operations aac_cfg_fops = {
.owner = THIS_MODULE,
.ioctl = aac_cfg_ioctl,
#ifdef CONFIG_COMPAT
@@ -804,7 +810,6 @@ static struct scsi_host_template aac_driver_template = {
.emulated = 1,
};
-
static int __devinit aac_probe_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
diff --git a/drivers/scsi/aacraid/nark.c b/drivers/scsi/aacraid/nark.c
new file mode 100644
index 000000000000..c76b611b6afb
--- /dev/null
+++ b/drivers/scsi/aacraid/nark.c
@@ -0,0 +1,87 @@
+/*
+ * Adaptec AAC series RAID controller driver
+ * (c) Copyright 2001 Red Hat Inc. <alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ *
+ * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.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; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Module Name:
+ * nark.c
+ *
+ * Abstract: Hardware Device Interface for NEMER/ARK
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/blkdev.h>
+
+#include <scsi/scsi_host.h>
+
+#include "aacraid.h"
+
+/**
+ * aac_nark_ioremap
+ * @size: mapping resize request
+ *
+ */
+static int aac_nark_ioremap(struct aac_dev * dev, u32 size)
+{
+ if (!size) {
+ iounmap(dev->regs.rx);
+ dev->regs.rx = NULL;
+ iounmap(dev->base);
+ dev->base = NULL;
+ return 0;
+ }
+ dev->scsi_host_ptr->base = pci_resource_start(dev->pdev, 2);
+ dev->regs.rx = ioremap((u64)pci_resource_start(dev->pdev, 0) |
+ ((u64)pci_resource_start(dev->pdev, 1) << 32),
+ sizeof(struct rx_registers) - sizeof(struct rx_inbound));
+ dev->base = NULL;
+ if (dev->regs.rx == NULL)
+ return -1;
+ dev->base = ioremap(dev->scsi_host_ptr->base, size);
+ if (dev->base == NULL) {
+ iounmap(dev->regs.rx);
+ dev->regs.rx = NULL;
+ return -1;
+ }
+ dev->IndexRegs = &((struct rx_registers __iomem *)dev->base)->IndexRegs;
+ return 0;
+}
+
+/**
+ * aac_nark_init - initialize an NEMER/ARK Split Bar card
+ * @dev: device to configure
+ *
+ */
+
+int aac_nark_init(struct aac_dev * dev)
+{
+ extern int _aac_rx_init(struct aac_dev *dev);
+ extern int aac_rx_select_comm(struct aac_dev *dev, int comm);
+
+ /*
+ * Fill in the function dispatch table.
+ */
+ dev->a_ops.adapter_ioremap = aac_nark_ioremap;
+ dev->a_ops.adapter_comm = aac_rx_select_comm;
+
+ return _aac_rx_init(dev);
+}
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index 643f23b5ded8..d953c3fe998a 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -34,6 +34,40 @@
#include "aacraid.h"
+#define AAC_NUM_IO_FIB_RKT (246 - AAC_NUM_MGT_FIB)
+
+/**
+ * aac_rkt_select_comm - Select communications method
+ * @dev: Adapter
+ * @comm: communications method
+ */
+
+static int aac_rkt_select_comm(struct aac_dev *dev, int comm)
+{
+ int retval;
+ extern int aac_rx_select_comm(struct aac_dev *dev, int comm);
+ retval = aac_rx_select_comm(dev, comm);
+ if (comm == AAC_COMM_MESSAGE) {
+ /*
+ * FIB Setup has already been done, but we can minimize the
+ * damage by at least ensuring the OS never issues more
+ * commands than we can handle. The Rocket adapters currently
+ * can only handle 246 commands and 8 AIFs at the same time,
+ * and in fact do notify us accordingly if we negotiate the
+ * FIB size. The problem that causes us to add this check is
+ * to ensure that we do not overdo it with the adapter when a
+ * hard coded FIB override is being utilized. This special
+ * case warrants this half baked, but convenient, check here.
+ */
+ if (dev->scsi_host_ptr->can_queue > AAC_NUM_IO_FIB_RKT) {
+ dev->init->MaxIoCommands =
+ cpu_to_le32(AAC_NUM_IO_FIB_RKT + AAC_NUM_MGT_FIB);
+ dev->scsi_host_ptr->can_queue = AAC_NUM_IO_FIB_RKT;
+ }
+ }
+ return retval;
+}
+
/**
* aac_rkt_ioremap
* @size: mapping resize request
@@ -63,39 +97,13 @@ static int aac_rkt_ioremap(struct aac_dev * dev, u32 size)
int aac_rkt_init(struct aac_dev *dev)
{
- int retval;
extern int _aac_rx_init(struct aac_dev *dev);
- extern void aac_rx_start_adapter(struct aac_dev *dev);
/*
* Fill in the function dispatch table.
*/
dev->a_ops.adapter_ioremap = aac_rkt_ioremap;
+ dev->a_ops.adapter_comm = aac_rkt_select_comm;
- retval = _aac_rx_init(dev);
- if (retval)
- return retval;
- if (dev->new_comm_interface) {
- /*
- * FIB Setup has already been done, but we can minimize the
- * damage by at least ensuring the OS never issues more
- * commands than we can handle. The Rocket adapters currently
- * can only handle 246 commands and 8 AIFs at the same time,
- * and in fact do notify us accordingly if we negotiate the
- * FIB size. The problem that causes us to add this check is
- * to ensure that we do not overdo it with the adapter when a
- * hard coded FIB override is being utilized. This special
- * case warrants this half baked, but convenient, check here.
- */
- if (dev->scsi_host_ptr->can_queue > (246 - AAC_NUM_MGT_FIB)) {
- dev->init->MaxIoCommands = cpu_to_le32(246);
- dev->scsi_host_ptr->can_queue = 246 - AAC_NUM_MGT_FIB;
- }
- }
- /*
- * Tell the adapter that all is configured, and it can start
- * accepting requests
- */
- aac_rx_start_adapter(dev);
- return 0;
+ return _aac_rx_init(dev);
}
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index dcc8b0ea7a9d..c632d9354a26 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -46,60 +46,60 @@
#include "aacraid.h"
-static irqreturn_t aac_rx_intr(int irq, void *dev_id)
+static irqreturn_t aac_rx_intr_producer(int irq, void *dev_id)
{
struct aac_dev *dev = dev_id;
+ unsigned long bellbits;
+ u8 intstat = rx_readb(dev, MUnit.OISR);
- dprintk((KERN_DEBUG "aac_rx_intr(%d,%p)\n", irq, dev_id));
- if (dev->new_comm_interface) {
- u32 Index = rx_readl(dev, MUnit.OutboundQueue);
- if (Index == 0xFFFFFFFFL)
- Index = rx_readl(dev, MUnit.OutboundQueue);
- if (Index != 0xFFFFFFFFL) {
- do {
- if (aac_intr_normal(dev, Index)) {
- rx_writel(dev, MUnit.OutboundQueue, Index);
- rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady);
- }
- Index = rx_readl(dev, MUnit.OutboundQueue);
- } while (Index != 0xFFFFFFFFL);
- return IRQ_HANDLED;
+ /*
+ * Read mask and invert because drawbridge is reversed.
+ * This allows us to only service interrupts that have
+ * been enabled.
+ * Check to see if this is our interrupt. If it isn't just return
+ */
+ if (intstat & ~(dev->OIMR)) {
+ bellbits = rx_readl(dev, OutboundDoorbellReg);
+ if (bellbits & DoorBellPrintfReady) {
+ aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5]));
+ rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
+ rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
}
- } else {
- unsigned long bellbits;
- u8 intstat;
- intstat = rx_readb(dev, MUnit.OISR);
- /*
- * Read mask and invert because drawbridge is reversed.
- * This allows us to only service interrupts that have
- * been enabled.
- * Check to see if this is our interrupt. If it isn't just return
- */
- if (intstat & ~(dev->OIMR))
- {
- bellbits = rx_readl(dev, OutboundDoorbellReg);
- if (bellbits & DoorBellPrintfReady) {
- aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5]));
- rx_writel(dev, MUnit.ODR,DoorBellPrintfReady);
- rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone);
- }
- else if (bellbits & DoorBellAdapterNormCmdReady) {
- rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
- aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
- }
- else if (bellbits & DoorBellAdapterNormRespReady) {
- rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
- aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
- }
- else if (bellbits & DoorBellAdapterNormCmdNotFull) {
- rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
- }
- else if (bellbits & DoorBellAdapterNormRespNotFull) {
- rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
- rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
- }
- return IRQ_HANDLED;
+ else if (bellbits & DoorBellAdapterNormCmdReady) {
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady);
+ aac_command_normal(&dev->queues->queue[HostNormCmdQueue]);
+ }
+ else if (bellbits & DoorBellAdapterNormRespReady) {
+ rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady);
+ aac_response_normal(&dev->queues->queue[HostNormRespQueue]);
+ }
+ else if (bellbits & DoorBellAdapterNormCmdNotFull) {
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
}
+ else if (bellbits & DoorBellAdapterNormRespNotFull) {
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull);
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull);
+ }
+ return IRQ_HANDLED;
+ }
+ return IRQ_NONE;
+}
+
+static irqreturn_t aac_rx_intr_message(int irq, void *dev_id)
+{
+ struct aac_dev *dev = dev_id;
+ u32 Index = rx_readl(dev, MUnit.OutboundQueue);
+ if (Index == 0xFFFFFFFFL)
+ Index = rx_readl(dev, MUnit.OutboundQueue);
+ if (Index != 0xFFFFFFFFL) {
+ do {
+ if (aac_intr_normal(dev, Index)) {
+ rx_writel(dev, MUnit.OutboundQueue, Index);
+ rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady);
+ }
+ Index = rx_readl(dev, MUnit.OutboundQueue);
+ } while (Index != 0xFFFFFFFFL);
+ return IRQ_HANDLED;
}
return IRQ_NONE;
}
@@ -115,6 +115,26 @@ static void aac_rx_disable_interrupt(struct aac_dev *dev)
}
/**
+ * aac_rx_enable_interrupt_producer - Enable interrupts
+ * @dev: Adapter
+ */
+
+static void aac_rx_enable_interrupt_producer(struct aac_dev *dev)
+{
+ rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+}
+
+/**
+ * aac_rx_enable_interrupt_message - Enable interrupts
+ * @dev: Adapter
+ */
+
+static void aac_rx_enable_interrupt_message(struct aac_dev *dev)
+{
+ rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+}
+
+/**
* rx_sync_cmd - send a command and wait
* @dev: Adapter
* @command: Command to execute
@@ -189,10 +209,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Restore interrupt mask even though we timed out
*/
- if (dev->new_comm_interface)
- rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
- else
- rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+ aac_adapter_enable_int(dev);
return -ETIMEDOUT;
}
/*
@@ -215,10 +232,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command,
/*
* Restore interrupt mask
*/
- if (dev->new_comm_interface)
- rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
- else
- rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+ aac_adapter_enable_int(dev);
return 0;
}
@@ -360,35 +374,72 @@ static int aac_rx_check_health(struct aac_dev *dev)
}
/**
- * aac_rx_send
+ * aac_rx_deliver_producer
* @fib: fib to issue
*
* Will send a fib, returning 0 if successful.
*/
-static int aac_rx_send(struct fib * fib)
+static int aac_rx_deliver_producer(struct fib * fib)
{
- u64 addr = fib->hw_fib_pa;
struct aac_dev *dev = fib->dev;
- volatile void __iomem *device = dev->regs.rx;
+ struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
+ unsigned long qflags;
u32 Index;
+ unsigned long nointr = 0;
- dprintk((KERN_DEBUG "%p->aac_rx_send(%p->%llx)\n", dev, fib, addr));
- Index = rx_readl(dev, MUnit.InboundQueue);
- if (Index == 0xFFFFFFFFL)
+ spin_lock_irqsave(q->lock, qflags);
+ aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib, 1, fib, &nointr);
+
+ q->numpending++;
+ *(q->headers.producer) = cpu_to_le32(Index + 1);
+ spin_unlock_irqrestore(q->lock, qflags);
+ if (!(nointr & aac_config.irq_mod))
+ aac_adapter_notify(dev, AdapNormCmdQueue);
+
+ return 0;
+}
+
+/**
+ * aac_rx_deliver_message
+ * @fib: fib to issue
+ *
+ * Will send a fib, returning 0 if successful.
+ */
+static int aac_rx_deliver_message(struct fib * fib)
+{
+ struct aac_dev *dev = fib->dev;
+ struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
+ unsigned long qflags;
+ u32 Index;
+ u64 addr;
+ volatile void __iomem *device;
+
+ unsigned long count = 10000000L; /* 50 seconds */
+ spin_lock_irqsave(q->lock, qflags);
+ q->numpending++;
+ spin_unlock_irqrestore(q->lock, qflags);
+ for(;;) {
Index = rx_readl(dev, MUnit.InboundQueue);
- dprintk((KERN_DEBUG "Index = 0x%x\n", Index));
- if (Index == 0xFFFFFFFFL)
- return Index;
+ if (Index == 0xFFFFFFFFL)
+ Index = rx_readl(dev, MUnit.InboundQueue);
+ if (Index != 0xFFFFFFFFL)
+ break;
+ if (--count == 0) {
+ spin_lock_irqsave(q->lock, qflags);
+ q->numpending--;
+ spin_unlock_irqrestore(q->lock, qflags);
+ return -ETIMEDOUT;
+ }
+ udelay(5);
+ }
device = dev->base + Index;
- dprintk((KERN_DEBUG "entry = %x %x %u\n", (u32)(addr & 0xffffffff),
- (u32)(addr >> 32), (u32)le16_to_cpu(fib->hw_fib->header.Size)));
+ addr = fib->hw_fib_pa;
writel((u32)(addr & 0xffffffff), device);
device += sizeof(u32);
writel((u32)(addr >> 32), device);
device += sizeof(u32);
writel(le16_to_cpu(fib->hw_fib->header.Size), device);
rx_writel(dev, MUnit.InboundQueue, Index);
- dprintk((KERN_DEBUG "aac_rx_send - return 0\n"));
return 0;
}
@@ -430,6 +481,31 @@ static int aac_rx_restart_adapter(struct aac_dev *dev)
}
/**
+ * aac_rx_select_comm - Select communications method
+ * @dev: Adapter
+ * @comm: communications method
+ */
+
+int aac_rx_select_comm(struct aac_dev *dev, int comm)
+{
+ switch (comm) {
+ case AAC_COMM_PRODUCER:
+ dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_producer;
+ dev->a_ops.adapter_intr = aac_rx_intr_producer;
+ dev->a_ops.adapter_deliver = aac_rx_deliver_producer;
+ break;
+ case AAC_COMM_MESSAGE:
+ dev->a_ops.adapter_enable_int = aac_rx_enable_interrupt_message;
+ dev->a_ops.adapter_intr = aac_rx_intr_message;
+ dev->a_ops.adapter_deliver = aac_rx_deliver_message;
+ break;
+ default:
+ return 1;
+ }
+ return 0;
+}
+
+/**
* aac_rx_init - initialize an i960 based AAC card
* @dev: device to configure
*
@@ -489,40 +565,42 @@ int _aac_rx_init(struct aac_dev *dev)
}
msleep(1);
}
- if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, IRQF_SHARED|IRQF_DISABLED, "aacraid", (void *)dev)<0)
- {
- printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance);
- goto error_iounmap;
- }
/*
- * Fill in the function dispatch table.
+ * Fill in the common function dispatch table.
*/
dev->a_ops.adapter_interrupt = aac_rx_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_rx_disable_interrupt;
dev->a_ops.adapter_notify = aac_rx_notify_adapter;
dev->a_ops.adapter_sync_cmd = rx_sync_cmd;
dev->a_ops.adapter_check_health = aac_rx_check_health;
- dev->a_ops.adapter_send = aac_rx_send;
/*
* First clear out all interrupts. Then enable the one's that we
* can handle.
*/
- rx_writeb(dev, MUnit.OIMR, 0xff);
+ aac_adapter_comm(dev, AAC_COMM_PRODUCER);
+ aac_adapter_disable_int(dev);
rx_writel(dev, MUnit.ODR, 0xffffffff);
- rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb);
+ aac_adapter_enable_int(dev);
if (aac_init_adapter(dev) == NULL)
- goto error_irq;
- if (dev->new_comm_interface)
- rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xf7);
+ goto error_iounmap;
+ aac_adapter_comm(dev, dev->comm_interface);
+ if (request_irq(dev->scsi_host_ptr->irq, dev->a_ops.adapter_intr,
+ IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
+ printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
+ name, instance);
+ goto error_iounmap;
+ }
+ aac_adapter_enable_int(dev);
+ /*
+ * Tell the adapter that all is configured, and it can
+ * start accepting requests
+ */
+ aac_rx_start_adapter(dev);
return 0;
-error_irq:
- rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xff);
- free_irq(dev->scsi_host_ptr->irq, (void *)dev);
-
error_iounmap:
return -1;
@@ -530,20 +608,11 @@ error_iounmap:
int aac_rx_init(struct aac_dev *dev)
{
- int retval;
-
/*
* Fill in the function dispatch table.
*/
dev->a_ops.adapter_ioremap = aac_rx_ioremap;
+ dev->a_ops.adapter_comm = aac_rx_select_comm;
- retval = _aac_rx_init(dev);
- if (!retval) {
- /*
- * Tell the adapter that all is configured, and it can
- * start accepting requests
- */
- aac_rx_start_adapter(dev);
- }
- return retval;
+ return _aac_rx_init(dev);
}
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index 511b0a938fb1..8535db068c2f 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -92,6 +92,17 @@ static void aac_sa_disable_interrupt (struct aac_dev *dev)
}
/**
+ * aac_sa_enable_interrupt - enable interrupt
+ * @dev: Which adapter to enable.
+ */
+
+static void aac_sa_enable_interrupt (struct aac_dev *dev)
+{
+ sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 |
+ DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
+}
+
+/**
* aac_sa_notify_adapter - handle adapter notification
* @dev: Adapter that notification is for
* @event: Event to notidy
@@ -347,32 +358,36 @@ int aac_sa_init(struct aac_dev *dev)
msleep(1);
}
- if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, IRQF_SHARED|IRQF_DISABLED, "aacraid", (void *)dev ) < 0) {
- printk(KERN_WARNING "%s%d: Interrupt unavailable.\n", name, instance);
- goto error_iounmap;
- }
-
/*
* Fill in the function dispatch table.
*/
dev->a_ops.adapter_interrupt = aac_sa_interrupt_adapter;
dev->a_ops.adapter_disable_int = aac_sa_disable_interrupt;
+ dev->a_ops.adapter_enable_int = aac_sa_enable_interrupt;
dev->a_ops.adapter_notify = aac_sa_notify_adapter;
dev->a_ops.adapter_sync_cmd = sa_sync_cmd;
dev->a_ops.adapter_check_health = aac_sa_check_health;
+ dev->a_ops.adapter_intr = aac_sa_intr;
dev->a_ops.adapter_ioremap = aac_sa_ioremap;
/*
* First clear out all interrupts. Then enable the one's that
* we can handle.
*/
- sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
- sa_writew(dev, SaDbCSR.PRICLEARIRQMASK, (PrintfReady | DOORBELL_1 |
- DOORBELL_2 | DOORBELL_3 | DOORBELL_4));
+ aac_adapter_disable_int(dev);
+ aac_adapter_enable_int(dev);
if(aac_init_adapter(dev) == NULL)
goto error_irq;
+ if (request_irq(dev->scsi_host_ptr->irq, dev->a_ops.adapter_intr,
+ IRQF_SHARED|IRQF_DISABLED,
+ "aacraid", (void *)dev ) < 0) {
+ printk(KERN_WARNING "%s%d: Interrupt unavailable.\n",
+ name, instance);
+ goto error_iounmap;
+ }
+ aac_adapter_enable_int(dev);
/*
* Tell the adapter that all is configure, and it can start
@@ -382,7 +397,7 @@ int aac_sa_init(struct aac_dev *dev)
return 0;
error_irq:
- sa_writew(dev, SaDbCSR.PRISETIRQMASK, 0xffff);
+ aac_sa_disable_interrupt(dev);
free_irq(dev->scsi_host_ptr->irq, (void *)dev);
error_iounmap:
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 306bec355e45..9b3303b64113 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -4403,7 +4403,7 @@ advansys_detect(struct scsi_host_template *tpnt)
ASC_DBG1(1,
"advansys_detect: probing I/O port 0x%x...\n",
iop);
- if (check_region(iop, ASC_IOADR_GAP) != 0) {
+ if (!request_region(iop, ASC_IOADR_GAP, "advansys")){
printk(
"AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
/* Don't try this I/O port twice. */
@@ -4413,6 +4413,7 @@ advansys_detect(struct scsi_host_template *tpnt)
printk(
"AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
/* Don't try this I/O port twice. */
+ release_region(iop, ASC_IOADR_GAP);
asc_ioport[ioport] = 0;
goto ioport_try_again;
} else {
@@ -4431,6 +4432,7 @@ advansys_detect(struct scsi_host_template *tpnt)
* 'ioport' past this board.
*/
ioport++;
+ release_region(iop, ASC_IOADR_GAP);
goto ioport_try_again;
}
}
@@ -9740,13 +9742,14 @@ AscSearchIOPortAddr11(
}
for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
iop_base = _asc_def_iop_base[i];
- if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
+ if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")){
ASC_DBG1(1,
"AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
iop_base);
continue;
}
ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
+ release_region(iop_base, ASC_IOADR_GAP);
if (AscFindSignature(iop_base)) {
return (iop_base);
}
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h
index 170a4344cbb2..27adbb294ac1 100644
--- a/drivers/scsi/aic7xxx/aic79xx.h
+++ b/drivers/scsi/aic7xxx/aic79xx.h
@@ -1337,9 +1337,6 @@ int ahd_pci_test_register_access(struct ahd_softc *);
/************************** SCB and SCB queue management **********************/
void ahd_qinfifo_requeue_tail(struct ahd_softc *ahd,
struct scb *scb);
-int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb,
- int target, char channel, int lun,
- u_int tag, role_t role);
/****************************** Initialization ********************************/
struct ahd_softc *ahd_alloc(void *platform_arg, char *name);
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 07a86a30f676..9ddc6e4a74b0 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -262,6 +262,9 @@ static void ahd_update_coalescing_values(struct ahd_softc *ahd,
u_int mincmds);
static int ahd_verify_vpd_cksum(struct vpd_config *vpd);
static int ahd_wait_seeprom(struct ahd_softc *ahd);
+static int ahd_match_scb(struct ahd_softc *ahd, struct scb *scb,
+ int target, char channel, int lun,
+ u_int tag, role_t role);
/******************************** Private Inlines *****************************/
@@ -7256,7 +7259,7 @@ ahd_busy_tcl(struct ahd_softc *ahd, u_int tcl, u_int scbid)
}
/************************** SCB and SCB queue management **********************/
-int
+static int
ahd_match_scb(struct ahd_softc *ahd, struct scb *scb, int target,
char channel, int lun, u_int tag, role_t role)
{
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 9bfcca5ede08..c7fe478f4813 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -1126,15 +1126,6 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa
return 0;
}
-uint64_t
-ahd_linux_get_memsize(void)
-{
- struct sysinfo si;
-
- si_meminfo(&si);
- return ((uint64_t)si.totalram << PAGE_SHIFT);
-}
-
/*
* Place the SCSI bus into a known state by either resetting it,
* or forcing transfer negotiations on the next command to any
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 3a67fc578d78..147c83c456a5 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -496,8 +496,6 @@ ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
int ahd_linux_register_host(struct ahd_softc *,
struct scsi_host_template *);
-uint64_t ahd_linux_get_memsize(void);
-
/*************************** Pretty Printing **********************************/
struct info_str {
char *buffer;
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
index 1a3ab6aa856b..c62ce41f2793 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c
@@ -132,6 +132,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ahd_pci_identity *entry;
char *name;
int error;
+ struct device *dev = &pdev->dev;
pci = pdev;
entry = ahd_find_pci_device(pci);
@@ -161,20 +162,18 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
if (sizeof(dma_addr_t) > 4) {
- uint64_t memsize;
- const uint64_t mask_39bit = 0x7FFFFFFFFFULL;
+ const u64 required_mask = dma_get_required_mask(dev);
- memsize = ahd_linux_get_memsize();
-
- if (memsize >= 0x8000000000ULL
- && pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) {
+ if (required_mask > DMA_39BIT_MASK &&
+ dma_set_mask(dev, DMA_64BIT_MASK) == 0)
ahd->flags |= AHD_64BIT_ADDRESSING;
- } else if (memsize > 0x80000000
- && pci_set_dma_mask(pdev, mask_39bit) == 0) {
+ else if (required_mask > DMA_32BIT_MASK &&
+ dma_set_mask(dev, DMA_39BIT_MASK) == 0)
ahd->flags |= AHD_39BIT_ADDRESSING;
- }
+ else
+ dma_set_mask(dev, DMA_32BIT_MASK);
} else {
- pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ dma_set_mask(dev, DMA_32BIT_MASK);
}
ahd->dev_softc = pci;
error = ahd_pci_config(ahd, entry);
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
index 2cf7bb3123f0..8d72bbae96ad 100644
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -88,7 +88,7 @@ ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
#define SUBID_9005_LEGACYCONN_FUNC(id) ((id) & 0x20)
-#define SUBID_9005_SEEPTYPE(id) ((id) & 0x0C0) >> 6)
+#define SUBID_9005_SEEPTYPE(id) (((id) & 0x0C0) >> 6)
#define SUBID_9005_SEEPTYPE_NONE 0x0
#define SUBID_9005_SEEPTYPE_4K 0x1
diff --git a/drivers/scsi/aic94xx/aic94xx_dev.c b/drivers/scsi/aic94xx/aic94xx_dev.c
index 6f8901b748f7..c520e5b41fb5 100644
--- a/drivers/scsi/aic94xx/aic94xx_dev.c
+++ b/drivers/scsi/aic94xx/aic94xx_dev.c
@@ -37,18 +37,14 @@
static inline int asd_get_ddb(struct asd_ha_struct *asd_ha)
{
- unsigned long flags;
int ddb, i;
- spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
ddb = FIND_FREE_DDB(asd_ha);
if (ddb >= asd_ha->hw_prof.max_ddbs) {
ddb = -ENOMEM;
- spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
goto out;
}
SET_DDB(ddb, asd_ha);
- spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4)
asd_ddbsite_write_dword(asd_ha, ddb, i, 0);
@@ -77,14 +73,10 @@ out:
static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb)
{
- unsigned long flags;
-
if (!ddb || ddb >= 0xFFFF)
return;
asd_ddbsite_write_byte(asd_ha, ddb, DDB_TYPE, DDB_TYPE_UNUSED);
- spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
CLEAR_DDB(ddb, asd_ha);
- spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
}
static inline void asd_set_ddb_type(struct domain_device *dev)
@@ -320,8 +312,11 @@ out:
int asd_dev_found(struct domain_device *dev)
{
+ unsigned long flags;
int res = 0;
+ struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
+ spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
switch (dev->dev_type) {
case SATA_PM:
res = asd_init_sata_pm_ddb(dev);
@@ -335,14 +330,18 @@ int asd_dev_found(struct domain_device *dev)
else
res = asd_init_initiator_ddb(dev);
}
+ spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
+
return res;
}
void asd_dev_gone(struct domain_device *dev)
{
int ddb, sister_ddb;
+ unsigned long flags;
struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
+ spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
ddb = (int) (unsigned long) dev->lldd_dev;
sister_ddb = asd_ddbsite_read_word(asd_ha, ddb, SISTER_DDB);
@@ -350,4 +349,5 @@ void asd_dev_gone(struct domain_device *dev)
asd_free_ddb(asd_ha, sister_ddb);
asd_free_ddb(asd_ha, ddb);
dev->lldd_dev = NULL;
+ spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
}
diff --git a/drivers/scsi/aic94xx/aic94xx_dump.c b/drivers/scsi/aic94xx/aic94xx_dump.c
index e6ade5996d95..6bd8e3059d27 100644
--- a/drivers/scsi/aic94xx/aic94xx_dump.c
+++ b/drivers/scsi/aic94xx/aic94xx_dump.c
@@ -556,7 +556,7 @@ static void asd_dump_lseq_state(struct asd_ha_struct *asd_ha, int lseq)
PRINT_LMIP_word(asd_ha, lseq, Q_TGTXFR_TAIL);
PRINT_LMIP_byte(asd_ha, lseq, LINK_NUMBER);
PRINT_LMIP_byte(asd_ha, lseq, SCRATCH_FLAGS);
- PRINT_LMIP_qword(asd_ha, lseq, CONNECTION_STATE);
+ PRINT_LMIP_dword(asd_ha, lseq, CONNECTION_STATE);
PRINT_LMIP_word(asd_ha, lseq, CONCTL);
PRINT_LMIP_byte(asd_ha, lseq, CONSTAT);
PRINT_LMIP_byte(asd_ha, lseq, CONNECTION_MODES);
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
index da94e126ca83..0cd7eed9196c 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.c
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -1052,10 +1052,9 @@ static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
struct asd_ascb *ascb;
unsigned long flags;
- ascb = kmem_cache_alloc(asd_ascb_cache, gfp_flags);
+ ascb = kmem_cache_zalloc(asd_ascb_cache, gfp_flags);
if (ascb) {
- memset(ascb, 0, sizeof(*ascb));
ascb->dma_scb.size = sizeof(struct scb);
ascb->dma_scb.vaddr = dma_pool_alloc(asd_ha->scb_pool,
gfp_flags,
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index fbc82b00a418..bc7744e35ad0 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -38,7 +38,7 @@
#include "aic94xx_seq.h"
/* The format is "version.release.patchlevel" */
-#define ASD_DRIVER_VERSION "1.0.2"
+#define ASD_DRIVER_VERSION "1.0.3"
static int use_msi = 0;
module_param_named(use_msi, use_msi, int, S_IRUGO);
@@ -57,6 +57,8 @@ MODULE_PARM_DESC(collector, "\n"
char sas_addr_str[2*SAS_ADDR_SIZE + 1] = "";
static struct scsi_transport_template *aic94xx_transport_template;
+static int asd_scan_finished(struct Scsi_Host *, unsigned long);
+static void asd_scan_start(struct Scsi_Host *);
static struct scsi_host_template aic94xx_sht = {
.module = THIS_MODULE,
@@ -66,6 +68,8 @@ static struct scsi_host_template aic94xx_sht = {
.target_alloc = sas_target_alloc,
.slave_configure = sas_slave_configure,
.slave_destroy = sas_slave_destroy,
+ .scan_finished = asd_scan_finished,
+ .scan_start = asd_scan_start,
.change_queue_depth = sas_change_queue_depth,
.change_queue_type = sas_change_queue_type,
.bios_param = sas_bios_param,
@@ -75,6 +79,8 @@ static struct scsi_host_template aic94xx_sht = {
.sg_tablesize = SG_ALL,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,
+ .eh_device_reset_handler = sas_eh_device_reset_handler,
+ .eh_bus_reset_handler = sas_eh_bus_reset_handler,
};
static int __devinit asd_map_memio(struct asd_ha_struct *asd_ha)
@@ -234,7 +240,7 @@ static int __devinit asd_common_setup(struct asd_ha_struct *asd_ha)
}
/* Provide some sane default values. */
asd_ha->hw_prof.max_scbs = 512;
- asd_ha->hw_prof.max_ddbs = 128;
+ asd_ha->hw_prof.max_ddbs = ASD_MAX_DDBS;
asd_ha->hw_prof.num_phys = ASD_MAX_PHYS;
/* All phys are enabled, by default. */
asd_ha->hw_prof.enabled_phys = 0xFF;
@@ -526,6 +532,7 @@ static int asd_register_sas_ha(struct asd_ha_struct *asd_ha)
asd_ha->sas_ha.num_phys= ASD_MAX_PHYS;
asd_ha->sas_ha.lldd_queue_size = asd_ha->seq.can_queue;
+ asd_ha->sas_ha.lldd_max_execute_num = lldd_max_execute_num;
return sas_register_ha(&asd_ha->sas_ha);
}
@@ -671,21 +678,10 @@ static int __devinit asd_pci_probe(struct pci_dev *dev,
if (err)
goto Err_reg_sas;
- err = asd_enable_phys(asd_ha, asd_ha->hw_prof.enabled_phys);
- if (err) {
- asd_printk("coudln't enable phys, err:%d\n", err);
- goto Err_en_phys;
- }
- ASD_DPRINTK("enabled phys\n");
- /* give the phy enabling interrupt event time to come in (1s
- * is empirically about all it takes) */
- ssleep(1);
- /* Wait for discovery to finish */
- scsi_flush_work(asd_ha->sas_ha.core.shost);
+ scsi_scan_host(shost);
return 0;
-Err_en_phys:
- asd_unregister_sas_ha(asd_ha);
+
Err_reg_sas:
asd_remove_dev_attrs(asd_ha);
Err_dev_attrs:
@@ -778,6 +774,28 @@ static void __devexit asd_pci_remove(struct pci_dev *dev)
return;
}
+static void asd_scan_start(struct Scsi_Host *shost)
+{
+ struct asd_ha_struct *asd_ha;
+ int err;
+
+ asd_ha = SHOST_TO_SAS_HA(shost)->lldd_ha;
+ err = asd_enable_phys(asd_ha, asd_ha->hw_prof.enabled_phys);
+ if (err)
+ asd_printk("Couldn't enable phys, err:%d\n", err);
+}
+
+static int asd_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+ /* give the phy enabling interrupt event time to come in (1s
+ * is empirically about all it takes) */
+ if (time < HZ)
+ return 0;
+ /* Wait for discovery to finish */
+ scsi_flush_work(shost);
+ return 1;
+}
+
static ssize_t asd_version_show(struct device_driver *driver, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%s\n", ASD_DRIVER_VERSION);
@@ -885,6 +903,7 @@ static void __exit aic94xx_exit(void)
asd_remove_driver_attrs(&aic94xx_pci_driver.driver);
pci_unregister_driver(&aic94xx_pci_driver);
sas_release_transport(aic94xx_transport_template);
+ asd_release_firmware();
asd_destroy_global_caches();
asd_printk("%s version %s unloaded\n", ASD_DRIVER_DESCRIPTION,
ASD_DRIVER_VERSION);
diff --git a/drivers/scsi/aic94xx/aic94xx_reg_def.h b/drivers/scsi/aic94xx/aic94xx_reg_def.h
index a11f4e6d8bd9..a43e8cdf4ee4 100644
--- a/drivers/scsi/aic94xx/aic94xx_reg_def.h
+++ b/drivers/scsi/aic94xx/aic94xx_reg_def.h
@@ -2226,9 +2226,10 @@
#define LmSEQ_SAS_RESET_MODE(LinkNum) (LmSCRATCH(LinkNum) + 0x0074)
#define LmSEQ_LINK_RESET_RETRY_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x0075)
#define LmSEQ_NUM_LINK_RESET_RETRIES(LinkNum) (LmSCRATCH(LinkNum) + 0x0076)
-#define LmSEQ_OOB_INT_ENABLES(LinkNum) (LmSCRATCH(LinkNum) + 0x007A)
+#define LmSEQ_OOB_INT_ENABLES(LinkNum) (LmSCRATCH(LinkNum) + 0x0078)
+#define LmSEQ_NOTIFY_TIMER_DOWN_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x007A)
#define LmSEQ_NOTIFY_TIMER_TIMEOUT(LinkNum) (LmSCRATCH(LinkNum) + 0x007C)
-#define LmSEQ_NOTIFY_TIMER_DOWN_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x007E)
+#define LmSEQ_NOTIFY_TIMER_INITIAL_COUNT(LinkNum) (LmSCRATCH(LinkNum) + 0x007E)
/* Mode dependent scratch page 1, mode 0 and mode 1 */
#define LmSEQ_SG_LIST_PTR_ADDR0(LinkNum) (LmSCRATCH(LinkNum) + 0x0020)
diff --git a/drivers/scsi/aic94xx/aic94xx_sas.h b/drivers/scsi/aic94xx/aic94xx_sas.h
index 9050e93bfd5e..fa7c5290257d 100644
--- a/drivers/scsi/aic94xx/aic94xx_sas.h
+++ b/drivers/scsi/aic94xx/aic94xx_sas.h
@@ -34,6 +34,7 @@
* domain that this sequencer can maintain low-level connections for
* us. They are be 64 bytes.
*/
+#define ASD_MAX_DDBS 128
struct asd_ddb_ssp_smp_target_port {
u8 conn_type; /* byte 0 */
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c
index 75ed6b0569d1..8f43ff772f23 100644
--- a/drivers/scsi/aic94xx/aic94xx_scb.c
+++ b/drivers/scsi/aic94xx/aic94xx_scb.c
@@ -413,40 +413,6 @@ void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id)
}
}
-/* hard reset a phy later */
-static void do_phy_reset_later(struct work_struct *work)
-{
- struct sas_phy *sas_phy =
- container_of(work, struct sas_phy, reset_work);
- int error;
-
- ASD_DPRINTK("%s: About to hard reset phy %d\n", __FUNCTION__,
- sas_phy->identify.phy_identifier);
- /* Reset device port */
- error = sas_phy_reset(sas_phy, 1);
- if (error)
- ASD_DPRINTK("%s: Hard reset of phy %d failed (%d).\n",
- __FUNCTION__, sas_phy->identify.phy_identifier, error);
-}
-
-static void phy_reset_later(struct sas_phy *sas_phy, struct Scsi_Host *shost)
-{
- INIT_WORK(&sas_phy->reset_work, do_phy_reset_later);
- queue_work(shost->work_q, &sas_phy->reset_work);
-}
-
-/* start up the ABORT TASK tmf... */
-static void task_kill_later(struct asd_ascb *ascb)
-{
- struct asd_ha_struct *asd_ha = ascb->ha;
- struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
- struct Scsi_Host *shost = sas_ha->core.shost;
- struct sas_task *task = ascb->uldd_task;
-
- INIT_WORK(&task->abort_work, sas_task_abort);
- queue_work(shost->work_q, &task->abort_work);
-}
-
static void escb_tasklet_complete(struct asd_ascb *ascb,
struct done_list_struct *dl)
{
@@ -479,26 +445,55 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
case REQ_TASK_ABORT: {
struct asd_ascb *a, *b;
u16 tc_abort;
+ struct domain_device *failed_dev = NULL;
+
+ ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n",
+ __FUNCTION__, dl->status_block[3]);
+ /*
+ * Find the task that caused the abort and abort it first.
+ * The sequencer won't put anything on the done list until
+ * that happens.
+ */
tc_abort = *((u16*)(&dl->status_block[1]));
tc_abort = le16_to_cpu(tc_abort);
- ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n",
- __FUNCTION__, dl->status_block[3]);
+ list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
+ struct sas_task *task = ascb->uldd_task;
- /* Find the pending task and abort it. */
- list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list)
- if (a->tc_index == tc_abort) {
- task_kill_later(a);
+ if (task && a->tc_index == tc_abort) {
+ failed_dev = task->dev;
+ sas_task_abort(task);
break;
}
+ }
+
+ if (!failed_dev) {
+ ASD_DPRINTK("%s: Can't find task (tc=%d) to abort!\n",
+ __FUNCTION__, tc_abort);
+ goto out;
+ }
+
+ /*
+ * Now abort everything else for that device (hba?) so
+ * that the EH will wake up and do something.
+ */
+ list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) {
+ struct sas_task *task = ascb->uldd_task;
+
+ if (task &&
+ task->dev == failed_dev &&
+ a->tc_index != tc_abort)
+ sas_task_abort(task);
+ }
+
goto out;
}
case REQ_DEVICE_RESET: {
- struct Scsi_Host *shost = sas_ha->core.shost;
- struct sas_phy *dev_phy;
struct asd_ascb *a;
u16 conn_handle;
+ unsigned long flags;
+ struct sas_task *last_dev_task = NULL;
conn_handle = *((u16*)(&dl->status_block[1]));
conn_handle = le16_to_cpu(conn_handle);
@@ -506,32 +501,47 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__,
dl->status_block[3]);
- /* Kill all pending tasks and reset the device */
- dev_phy = NULL;
+ /* Find the last pending task for the device... */
list_for_each_entry(a, &asd_ha->seq.pend_q, list) {
- struct sas_task *task;
- struct domain_device *dev;
u16 x;
+ struct domain_device *dev;
+ struct sas_task *task = a->uldd_task;
- task = a->uldd_task;
if (!task)
continue;
dev = task->dev;
x = (unsigned long)dev->lldd_dev;
- if (x == conn_handle) {
- dev_phy = dev->port->phy;
- task_kill_later(a);
- }
+ if (x == conn_handle)
+ last_dev_task = task;
}
- /* Reset device port */
- if (!dev_phy) {
- ASD_DPRINTK("%s: No pending commands; can't reset.\n",
- __FUNCTION__);
+ if (!last_dev_task) {
+ ASD_DPRINTK("%s: Device reset for idle device %d?\n",
+ __FUNCTION__, conn_handle);
goto out;
}
- phy_reset_later(dev_phy, shost);
+
+ /* ...and set the reset flag */
+ spin_lock_irqsave(&last_dev_task->task_state_lock, flags);
+ last_dev_task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
+ spin_unlock_irqrestore(&last_dev_task->task_state_lock, flags);
+
+ /* Kill all pending tasks for the device */
+ list_for_each_entry(a, &asd_ha->seq.pend_q, list) {
+ u16 x;
+ struct domain_device *dev;
+ struct sas_task *task = a->uldd_task;
+
+ if (!task)
+ continue;
+ dev = task->dev;
+
+ x = (unsigned long)dev->lldd_dev;
+ if (x == conn_handle)
+ sas_task_abort(task);
+ }
+
goto out;
}
case SIGNAL_NCQ_ERROR:
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
index e5a0ec37e954..5b0932f61473 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.c
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -427,7 +427,7 @@ struct asd_manuf_sec {
struct asd_manuf_phy_desc {
u8 state; /* low 4 bits */
-#define MS_PHY_STATE_ENABLEABLE 0
+#define MS_PHY_STATE_ENABLED 0
#define MS_PHY_STATE_REPORTED 1
#define MS_PHY_STATE_HIDDEN 2
u8 phy_id;
@@ -756,11 +756,11 @@ static void *asd_find_ll_by_id(void * const start, const u8 id0, const u8 id1)
*
* HIDDEN phys do not count in the total count. REPORTED phys cannot
* be enabled but are reported and counted towards the total.
- * ENEBLEABLE phys are enabled by default and count towards the total.
+ * ENABLED phys are enabled by default and count towards the total.
* The absolute total phy number is ASD_MAX_PHYS. hw_prof->num_phys
* merely specifies the number of phys the host adapter decided to
* report. E.g., it is possible for phys 0, 1 and 2 to be HIDDEN,
- * phys 3, 4 and 5 to be REPORTED and phys 6 and 7 to be ENEBLEABLE.
+ * phys 3, 4 and 5 to be REPORTED and phys 6 and 7 to be ENABLED.
* In this case ASD_MAX_PHYS is 8, hw_prof->num_phys is 5, and only 2
* are actually enabled (enabled by default, max number of phys
* enableable in this case).
@@ -816,8 +816,8 @@ static int asd_ms_get_phy_params(struct asd_ha_struct *asd_ha,
asd_ha->hw_prof.enabled_phys &= ~(1 << i);
rep_phys++;
continue;
- case MS_PHY_STATE_ENABLEABLE:
- ASD_DPRINTK("ms: phy%d: ENEBLEABLE\n", i);
+ case MS_PHY_STATE_ENABLED:
+ ASD_DPRINTK("ms: phy%d: ENABLED\n", i);
asd_ha->hw_prof.enabled_phys |= (1 << i);
en_phys++;
break;
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c
index 845112539d05..eae7a247bece 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.c
+++ b/drivers/scsi/aic94xx/aic94xx_seq.c
@@ -810,6 +810,8 @@ static void asd_init_lseq_mdp(struct asd_ha_struct *asd_ha, int lseq)
/* No delay for the first NOTIFY to be sent to the attached target. */
asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_DOWN_COUNT(lseq),
ASD_NOTIFY_DOWN_COUNT);
+ asd_write_reg_word(asd_ha, LmSEQ_NOTIFY_TIMER_INITIAL_COUNT(lseq),
+ ASD_NOTIFY_DOWN_COUNT);
/* LSEQ Mode dependent, mode 0 and 1, page 1 setup. */
for (i = 0; i < 2; i++) {
@@ -907,6 +909,16 @@ static void asd_init_scb_sites(struct asd_ha_struct *asd_ha)
for (i = 0; i < ASD_SCB_SIZE; i += 4)
asd_scbsite_write_dword(asd_ha, site_no, i, 0);
+ /* Initialize SCB Site Opcode field to invalid. */
+ asd_scbsite_write_byte(asd_ha, site_no,
+ offsetof(struct scb_header, opcode),
+ 0xFF);
+
+ /* Initialize SCB Site Flags field to mean a response
+ * frame has been received. This means inadvertent
+ * frames received to be dropped. */
+ asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01);
+
/* Workaround needed by SEQ to fix a SATA issue is to exclude
* certain SCB sites from the free list. */
if (!SCB_SITE_VALID(site_no))
@@ -922,16 +934,6 @@ static void asd_init_scb_sites(struct asd_ha_struct *asd_ha)
/* Q_NEXT field of the last SCB is invalidated. */
asd_scbsite_write_word(asd_ha, site_no, 0, first_scb_site_no);
- /* Initialize SCB Site Opcode field to invalid. */
- asd_scbsite_write_byte(asd_ha, site_no,
- offsetof(struct scb_header, opcode),
- 0xFF);
-
- /* Initialize SCB Site Flags field to mean a response
- * frame has been received. This means inadvertent
- * frames received to be dropped. */
- asd_scbsite_write_byte(asd_ha, site_no, 0x49, 0x01);
-
first_scb_site_no = site_no;
max_scbs++;
}
@@ -1173,6 +1175,16 @@ static void asd_init_ddb_0(struct asd_ha_struct *asd_ha)
set_bit(0, asd_ha->hw_prof.ddb_bitmap);
}
+static void asd_seq_init_ddb_sites(struct asd_ha_struct *asd_ha)
+{
+ unsigned int i;
+ unsigned int ddb_site;
+
+ for (ddb_site = 0 ; ddb_site < ASD_MAX_DDBS; ddb_site++)
+ for (i = 0; i < sizeof(struct asd_ddb_ssp_smp_target_port); i+= 4)
+ asd_ddbsite_write_dword(asd_ha, ddb_site, i, 0);
+}
+
/**
* asd_seq_setup_seqs -- setup and initialize central and link sequencers
* @asd_ha: pointer to host adapter structure
@@ -1182,6 +1194,9 @@ static void asd_seq_setup_seqs(struct asd_ha_struct *asd_ha)
int lseq;
u8 lseq_mask;
+ /* Initialize DDB sites */
+ asd_seq_init_ddb_sites(asd_ha);
+
/* Initialize SCB sites. Done first to compute some values which
* the rest of the init code depends on. */
asd_init_scb_sites(asd_ha);
@@ -1232,6 +1247,13 @@ static int asd_seq_start_lseq(struct asd_ha_struct *asd_ha, int lseq)
return asd_seq_unpause_lseq(asd_ha, lseq);
}
+int asd_release_firmware(void)
+{
+ if (sequencer_fw)
+ release_firmware(sequencer_fw);
+ return 0;
+}
+
static int asd_request_firmware(struct asd_ha_struct *asd_ha)
{
int err, i;
@@ -1375,7 +1397,9 @@ void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
u8 phy_is_up;
u8 mask;
int i, err;
+ unsigned long flags;
+ spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);
for_each_phy(phy_mask, mask, i)
asd_ddbsite_write_byte(asd_ha, 0,
offsetof(struct asd_ddb_seq_shared,
@@ -1395,6 +1419,7 @@ void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
break;
}
}
+ spin_unlock_irqrestore(&asd_ha->hw_prof.ddb_lock, flags);
if (err)
asd_printk("couldn't update DDB 0:error:%d\n", err);
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.h b/drivers/scsi/aic94xx/aic94xx_seq.h
index 9e715e5496af..9437ff0ae3a4 100644
--- a/drivers/scsi/aic94xx/aic94xx_seq.h
+++ b/drivers/scsi/aic94xx/aic94xx_seq.h
@@ -63,6 +63,7 @@ int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
int asd_init_seqs(struct asd_ha_struct *asd_ha);
int asd_start_seqs(struct asd_ha_struct *asd_ha);
+int asd_release_firmware(void);
void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy);
#endif
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
index d202ed5a6709..e2ad5bed9403 100644
--- a/drivers/scsi/aic94xx/aic94xx_task.c
+++ b/drivers/scsi/aic94xx/aic94xx_task.c
@@ -349,6 +349,7 @@ Again:
spin_lock_irqsave(&task->task_state_lock, flags);
task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+ task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
task->task_state_flags |= SAS_TASK_STATE_DONE;
if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) {
spin_unlock_irqrestore(&task->task_state_lock, flags);
@@ -557,6 +558,7 @@ int asd_execute_task(struct sas_task *task, const int num,
struct sas_task *t = task;
struct asd_ascb *ascb = NULL, *a;
struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
+ unsigned long flags;
res = asd_can_queue(asd_ha, num);
if (res)
@@ -599,6 +601,10 @@ int asd_execute_task(struct sas_task *task, const int num,
}
if (res)
goto out_err_unmap;
+
+ spin_lock_irqsave(&t->task_state_lock, flags);
+ t->task_state_flags |= SAS_TASK_AT_INITIATOR;
+ spin_unlock_irqrestore(&t->task_state_lock, flags);
}
list_del_init(&alist);
@@ -617,6 +623,9 @@ out_err_unmap:
if (a == b)
break;
t = a->uldd_task;
+ spin_lock_irqsave(&t->task_state_lock, flags);
+ t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+ spin_unlock_irqrestore(&t->task_state_lock, flags);
switch (t->task_proto) {
case SATA_PROTO:
case SAS_PROTO_STP:
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c
index 61234384503b..9a14a6d97275 100644
--- a/drivers/scsi/aic94xx/aic94xx_tmf.c
+++ b/drivers/scsi/aic94xx/aic94xx_tmf.c
@@ -566,9 +566,7 @@ static int asd_initiate_ssp_tmf(struct domain_device *dev, u8 *lun,
res = TMF_RESP_FUNC_ESUPP;
break;
default:
- ASD_DPRINTK("%s: converting result 0x%x to TMF_RESP_FUNC_FAILED\n",
- __FUNCTION__, res);
- res = TMF_RESP_FUNC_FAILED;
+ /* Allow TMF response codes to propagate upwards */
break;
}
out_err:
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index f6caa4307768..d02759f13469 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -129,7 +129,7 @@ static struct scsi_driver ch_template =
},
};
-static struct file_operations changer_fops =
+static const struct file_operations changer_fops =
{
.owner = THIS_MODULE,
.open = ch_open,
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 365db537a28d..cd36e81b2d93 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -116,7 +116,7 @@ static int sys_tbl_len = 0;
static adpt_hba* hba_chain = NULL;
static int hba_count = 0;
-static struct file_operations adpt_fops = {
+static const struct file_operations adpt_fops = {
.ioctl = adpt_ioctl,
.open = adpt_open,
.release = adpt_close
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 4c698a71f66f..a1992928e671 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -687,7 +687,7 @@ MODULE_AUTHOR("Achim Leubner");
MODULE_LICENSE("GPL");
/* ioctl interface */
-static struct file_operations gdth_fops = {
+static const struct file_operations gdth_fops = {
.ioctl = gdth_ioctl,
.open = gdth_open,
.release = gdth_close,
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 821386c7b576..95045e33710d 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -595,10 +595,8 @@ static int ipr_save_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg)
{
int pcix_cmd_reg = pci_find_capability(ioa_cfg->pdev, PCI_CAP_ID_PCIX);
- if (pcix_cmd_reg == 0) {
- dev_err(&ioa_cfg->pdev->dev, "Failed to save PCI-X command register\n");
- return -EIO;
- }
+ if (pcix_cmd_reg == 0)
+ return 0;
if (pci_read_config_word(ioa_cfg->pdev, pcix_cmd_reg + PCI_X_CMD,
&ioa_cfg->saved_pcix_cmd_reg) != PCIBIOS_SUCCESSFUL) {
@@ -627,10 +625,6 @@ static int ipr_set_pcix_cmd_reg(struct ipr_ioa_cfg *ioa_cfg)
dev_err(&ioa_cfg->pdev->dev, "Failed to setup PCI-X command register\n");
return -EIO;
}
- } else {
- dev_err(&ioa_cfg->pdev->dev,
- "Failed to setup PCI-X command register\n");
- return -EIO;
}
return 0;
@@ -6314,7 +6308,6 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
int rc;
ENTER;
- pci_unblock_user_cfg_access(ioa_cfg->pdev);
rc = pci_restore_state(ioa_cfg->pdev);
if (rc != PCIBIOS_SUCCESSFUL) {
@@ -6355,6 +6348,24 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
}
/**
+ * ipr_reset_bist_done - BIST has completed on the adapter.
+ * @ipr_cmd: ipr command struct
+ *
+ * Description: Unblock config space and resume the reset process.
+ *
+ * Return value:
+ * IPR_RC_JOB_CONTINUE
+ **/
+static int ipr_reset_bist_done(struct ipr_cmnd *ipr_cmd)
+{
+ ENTER;
+ pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
+ ipr_cmd->job_step = ipr_reset_restore_cfg_space;
+ LEAVE;
+ return IPR_RC_JOB_CONTINUE;
+}
+
+/**
* ipr_reset_start_bist - Run BIST on the adapter.
* @ipr_cmd: ipr command struct
*
@@ -6376,7 +6387,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
rc = IPR_RC_JOB_CONTINUE;
} else {
- ipr_cmd->job_step = ipr_reset_restore_cfg_space;
+ ipr_cmd->job_step = ipr_reset_bist_done;
ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT);
rc = IPR_RC_JOB_RETURN;
}
@@ -7166,9 +7177,6 @@ ipr_get_chip_cfg(const struct pci_device_id *dev_id)
{
int i;
- if (dev_id->driver_data)
- return (const struct ipr_chip_cfg_t *)dev_id->driver_data;
-
for (i = 0; i < ARRAY_SIZE(ipr_chip); i++)
if (ipr_chip[i].vendor == dev_id->vendor &&
ipr_chip[i].device == dev_id->device)
@@ -7517,62 +7525,43 @@ static void ipr_shutdown(struct pci_dev *pdev)
static struct pci_device_id ipr_pci_table[] __devinitdata = {
{ PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_5702,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_5702, 0, 0, 0 },
{ PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_5703,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_5703, 0, 0, 0 },
{ PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_573D,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_573D, 0, 0, 0 },
{ PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_573E,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_573E, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571B,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571B, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572E,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572E, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571A,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571A, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575B,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575B, 0, 0, 0 },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, 0, 0, 0 },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, 0 },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, 0 },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780, 0, 0, 0 },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571E,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571E, 0, 0, 0 },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, 0, 0, 0 },
{ PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP,
- PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F,
- 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] },
+ PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, 0 },
{ }
};
MODULE_DEVICE_TABLE(pci, ipr_pci_table);
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 9f62a1d4d511..88f285de97bb 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -37,8 +37,8 @@
/*
* Literals
*/
-#define IPR_DRIVER_VERSION "2.3.0"
-#define IPR_DRIVER_DATE "(November 8, 2006)"
+#define IPR_DRIVER_VERSION "2.3.1"
+#define IPR_DRIVER_DATE "(January 23, 2007)"
/*
* IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index f0871c3ac3d9..2aae1b081fcf 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -123,6 +123,7 @@ lasi700_probe(struct parisc_device *dev)
hostdata->force_le_on_be = 0;
hostdata->chip710 = 1;
hostdata->dmode_extra = DMODE_FC2;
+ hostdata->burst_length = 8;
}
host = NCR_700_detect(&lasi700_template, hostdata, &dev->dev);
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index fb7df7b75811..a65598b1e536 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -548,7 +548,7 @@ int sas_discover_sata(struct domain_device *dev)
res = sas_notify_lldd_dev_found(dev);
if (res)
- return res;
+ goto out_err2;
switch (dev->dev_type) {
case SATA_DEV:
@@ -560,11 +560,23 @@ int sas_discover_sata(struct domain_device *dev)
default:
break;
}
+ if (res)
+ goto out_err;
sas_notify_lldd_dev_gone(dev);
- if (!res) {
- sas_notify_lldd_dev_found(dev);
- }
+ res = sas_notify_lldd_dev_found(dev);
+ if (res)
+ goto out_err2;
+
+ res = sas_rphy_add(dev->rphy);
+ if (res)
+ goto out_err;
+
+ return res;
+
+out_err:
+ sas_notify_lldd_dev_gone(dev);
+out_err2:
return res;
}
@@ -580,21 +592,17 @@ int sas_discover_end_dev(struct domain_device *dev)
res = sas_notify_lldd_dev_found(dev);
if (res)
- return res;
+ goto out_err2;
res = sas_rphy_add(dev->rphy);
if (res)
goto out_err;
- /* do this to get the end device port attributes which will have
- * been scanned in sas_rphy_add */
- sas_notify_lldd_dev_gone(dev);
- sas_notify_lldd_dev_found(dev);
-
return 0;
out_err:
sas_notify_lldd_dev_gone(dev);
+out_err2:
return res;
}
@@ -649,6 +657,7 @@ void sas_unregister_domain_devices(struct asd_sas_port *port)
*/
static void sas_discover_domain(struct work_struct *work)
{
+ struct domain_device *dev;
int error = 0;
struct sas_discovery_event *ev =
container_of(work, struct sas_discovery_event, work);
@@ -658,35 +667,42 @@ static void sas_discover_domain(struct work_struct *work)
&port->disc.pending);
if (port->port_dev)
- return ;
- else {
- error = sas_get_port_device(port);
- if (error)
- return;
- }
+ return;
+
+ error = sas_get_port_device(port);
+ if (error)
+ return;
+ dev = port->port_dev;
SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id,
current->pid);
- switch (port->port_dev->dev_type) {
+ switch (dev->dev_type) {
case SAS_END_DEV:
- error = sas_discover_end_dev(port->port_dev);
+ error = sas_discover_end_dev(dev);
break;
case EDGE_DEV:
case FANOUT_DEV:
- error = sas_discover_root_expander(port->port_dev);
+ error = sas_discover_root_expander(dev);
break;
case SATA_DEV:
case SATA_PM:
- error = sas_discover_sata(port->port_dev);
+ error = sas_discover_sata(dev);
break;
default:
- SAS_DPRINTK("unhandled device %d\n", port->port_dev->dev_type);
+ SAS_DPRINTK("unhandled device %d\n", dev->dev_type);
break;
}
if (error) {
- kfree(port->port_dev); /* not kobject_register-ed yet */
+ sas_rphy_free(dev->rphy);
+ dev->rphy = NULL;
+
+ spin_lock(&port->dev_list_lock);
+ list_del_init(&dev->dev_list_node);
+ spin_unlock(&port->dev_list_lock);
+
+ kfree(dev); /* not kobject_register-ed yet */
port->port_dev = NULL;
}
@@ -726,7 +742,7 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev)
BUG_ON(ev >= DISC_NUM_EVENTS);
sas_queue_event(ev, &disc->disc_event_lock, &disc->pending,
- &disc->disc_work[ev].work, port->ha->core.shost);
+ &disc->disc_work[ev].work, port->ha);
return 0;
}
diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c
index d83392ee6823..9db30fb5caf2 100644
--- a/drivers/scsi/libsas/sas_event.c
+++ b/drivers/scsi/libsas/sas_event.c
@@ -31,7 +31,7 @@ static void notify_ha_event(struct sas_ha_struct *sas_ha, enum ha_event event)
BUG_ON(event >= HA_NUM_EVENTS);
sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending,
- &sas_ha->ha_events[event].work, sas_ha->core.shost);
+ &sas_ha->ha_events[event].work, sas_ha);
}
static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)
@@ -41,7 +41,7 @@ static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)
BUG_ON(event >= PORT_NUM_EVENTS);
sas_queue_event(event, &ha->event_lock, &phy->port_events_pending,
- &phy->port_events[event].work, ha->core.shost);
+ &phy->port_events[event].work, ha);
}
static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
@@ -51,7 +51,7 @@ static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
BUG_ON(event >= PHY_NUM_EVENTS);
sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending,
- &phy->phy_events[event].work, ha->core.shost);
+ &phy->phy_events[event].work, ha);
}
int sas_init_events(struct sas_ha_struct *sas_ha)
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index d31e6fa466f7..dc70c180e115 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -667,8 +667,9 @@ static struct domain_device *sas_ex_discover_end_dev(
return child;
out_list_del:
+ sas_rphy_free(child->rphy);
+ child->rphy = NULL;
list_del(&child->dev_list_node);
- sas_rphy_free(rphy);
out_free:
sas_port_delete(phy->port);
out_err:
@@ -677,6 +678,29 @@ static struct domain_device *sas_ex_discover_end_dev(
return NULL;
}
+/* See if this phy is part of a wide port */
+static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
+{
+ struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
+ int i;
+
+ for (i = 0; i < parent->ex_dev.num_phys; i++) {
+ struct ex_phy *ephy = &parent->ex_dev.ex_phy[i];
+
+ if (ephy == phy)
+ continue;
+
+ if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr,
+ SAS_ADDR_SIZE) && ephy->port) {
+ sas_port_add_phy(ephy->port, phy->phy);
+ phy->phy_state = PHY_DEVICE_DISCOVERED;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
static struct domain_device *sas_ex_discover_expander(
struct domain_device *parent, int phy_id)
{
@@ -809,6 +833,13 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
return res;
}
+ res = sas_ex_join_wide_port(dev, phy_id);
+ if (!res) {
+ SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
+ phy_id, SAS_ADDR(ex_phy->attached_sas_addr));
+ return res;
+ }
+
switch (ex_phy->attached_dev_type) {
case SAS_END_DEV:
child = sas_ex_discover_end_dev(dev, phy_id);
@@ -1431,14 +1462,23 @@ int sas_discover_root_expander(struct domain_device *dev)
int res;
struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
- sas_rphy_add(dev->rphy);
+ res = sas_rphy_add(dev->rphy);
+ if (res)
+ goto out_err;
ex->level = dev->port->disc.max_level; /* 0 */
res = sas_discover_expander(dev);
- if (!res)
- sas_ex_bfs_disc(dev->port);
+ if (res)
+ goto out_err2;
+
+ sas_ex_bfs_disc(dev->port);
return res;
+
+out_err2:
+ sas_rphy_remove(dev->rphy);
+out_err:
+ return res;
}
/* ---------- Domain revalidation ---------- */
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index 2f0c07fc3f48..965698c8b7bf 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -87,6 +87,9 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
else if (sas_ha->lldd_queue_size == -1)
sas_ha->lldd_queue_size = 128; /* Sanity */
+ sas_ha->state = SAS_HA_REGISTERED;
+ spin_lock_init(&sas_ha->state_lock);
+
error = sas_register_phys(sas_ha);
if (error) {
printk(KERN_NOTICE "couldn't register sas phys:%d\n", error);
@@ -127,12 +130,22 @@ Undo_phys:
int sas_unregister_ha(struct sas_ha_struct *sas_ha)
{
+ unsigned long flags;
+
+ /* Set the state to unregistered to avoid further
+ * events to be queued */
+ spin_lock_irqsave(&sas_ha->state_lock, flags);
+ sas_ha->state = SAS_HA_UNREGISTERED;
+ spin_unlock_irqrestore(&sas_ha->state_lock, flags);
+ scsi_flush_work(sas_ha->core.shost);
+
+ sas_unregister_ports(sas_ha);
+
if (sas_ha->lldd_max_execute_num > 1) {
sas_shutdown_queue(sas_ha);
+ sas_ha->lldd_max_execute_num = 1;
}
- sas_unregister_ports(sas_ha);
-
return 0;
}
@@ -146,6 +159,36 @@ static int sas_get_linkerrors(struct sas_phy *phy)
return sas_smp_get_phy_events(phy);
}
+int sas_phy_enable(struct sas_phy *phy, int enable)
+{
+ int ret;
+ enum phy_func command;
+
+ if (enable)
+ command = PHY_FUNC_LINK_RESET;
+ else
+ command = PHY_FUNC_DISABLE;
+
+ if (scsi_is_sas_phy_local(phy)) {
+ struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+ struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
+ struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
+ struct sas_internal *i =
+ to_sas_internal(sas_ha->core.shost->transportt);
+
+ if (!enable) {
+ sas_phy_disconnected(asd_phy);
+ sas_ha->notify_phy_event(asd_phy, PHYE_LOSS_OF_SIGNAL);
+ }
+ ret = i->dft->lldd_control_phy(asd_phy, command, NULL);
+ } else {
+ struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
+ struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
+ ret = sas_smp_phy_control(ddev, phy->number, command, NULL);
+ }
+ return ret;
+}
+
int sas_phy_reset(struct sas_phy *phy, int hard_reset)
{
int ret;
@@ -172,8 +215,8 @@ int sas_phy_reset(struct sas_phy *phy, int hard_reset)
return ret;
}
-static int sas_set_phy_speed(struct sas_phy *phy,
- struct sas_phy_linkrates *rates)
+int sas_set_phy_speed(struct sas_phy *phy,
+ struct sas_phy_linkrates *rates)
{
int ret;
@@ -212,6 +255,7 @@ static int sas_set_phy_speed(struct sas_phy *phy,
}
static struct sas_function_template sft = {
+ .phy_enable = sas_phy_enable,
.phy_reset = sas_phy_reset,
.set_phy_speed = sas_set_phy_speed,
.get_linkerrors = sas_get_linkerrors,
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index 137d7e496b6d..a78638df2018 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -80,7 +80,7 @@ void sas_hae_reset(struct work_struct *work);
static inline void sas_queue_event(int event, spinlock_t *lock,
unsigned long *pending,
struct work_struct *work,
- struct Scsi_Host *shost)
+ struct sas_ha_struct *sas_ha)
{
unsigned long flags;
@@ -91,7 +91,12 @@ static inline void sas_queue_event(int event, spinlock_t *lock,
}
__set_bit(event, pending);
spin_unlock_irqrestore(lock, flags);
- scsi_queue_work(shost, work);
+
+ spin_lock_irqsave(&sas_ha->state_lock, flags);
+ if (sas_ha->state != SAS_HA_UNREGISTERED) {
+ scsi_queue_work(sas_ha->core.shost, work);
+ }
+ spin_unlock_irqrestore(&sas_ha->state_lock, flags);
}
static inline void sas_begin_event(int event, spinlock_t *lock,
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index 971c37ceecb4..e1e2d085c920 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -42,10 +42,11 @@ static void sas_form_port(struct asd_sas_phy *phy)
struct asd_sas_port *port = phy->port;
struct sas_internal *si =
to_sas_internal(sas_ha->core.shost->transportt);
+ unsigned long flags;
if (port) {
if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
- SAS_ADDR_SIZE) == 0)
+ SAS_ADDR_SIZE) != 0)
sas_deform_port(phy);
else {
SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
@@ -56,7 +57,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
}
/* find a port */
- spin_lock(&sas_ha->phy_port_lock);
+ spin_lock_irqsave(&sas_ha->phy_port_lock, flags);
for (i = 0; i < sas_ha->num_phys; i++) {
port = sas_ha->sas_port[i];
spin_lock(&port->phy_list_lock);
@@ -78,7 +79,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
if (i >= sas_ha->num_phys) {
printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n",
__FUNCTION__);
- spin_unlock(&sas_ha->phy_port_lock);
+ spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
return;
}
@@ -105,7 +106,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
} else
port->linkrate = max(port->linkrate, phy->linkrate);
spin_unlock(&port->phy_list_lock);
- spin_unlock(&sas_ha->phy_port_lock);
+ spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
if (!port->port) {
port->port = sas_port_alloc(phy->phy->dev.parent, port->id);
@@ -137,6 +138,7 @@ void sas_deform_port(struct asd_sas_phy *phy)
struct asd_sas_port *port = phy->port;
struct sas_internal *si =
to_sas_internal(sas_ha->core.shost->transportt);
+ unsigned long flags;
if (!port)
return; /* done by a phy event */
@@ -155,7 +157,7 @@ void sas_deform_port(struct asd_sas_phy *phy)
if (si->dft->lldd_port_deformed)
si->dft->lldd_port_deformed(phy);
- spin_lock(&sas_ha->phy_port_lock);
+ spin_lock_irqsave(&sas_ha->phy_port_lock, flags);
spin_lock(&port->phy_list_lock);
list_del_init(&phy->port_phy_el);
@@ -174,7 +176,7 @@ void sas_deform_port(struct asd_sas_phy *phy)
port->phy_mask = 0;
}
spin_unlock(&port->phy_list_lock);
- spin_unlock(&sas_ha->phy_port_lock);
+ spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
return;
}
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 22672d54aa27..897a5e2c55e4 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -34,6 +34,7 @@
#include <scsi/scsi_transport_sas.h>
#include "../scsi_sas_internal.h"
#include "../scsi_transport_api.h"
+#include "../scsi_priv.h"
#include <linux/err.h>
#include <linux/blkdev.h>
@@ -130,7 +131,7 @@ static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
if (cmd->request && blk_rq_tagged(cmd->request)) {
if (cmd->device->ordered_tags &&
(cmd->request->cmd_flags & REQ_HARDBARRIER))
- ta = TASK_ATTR_HOQ;
+ ta = TASK_ATTR_ORDERED;
}
return ta;
}
@@ -281,6 +282,7 @@ enum task_disposition {
TASK_IS_ABORTED,
TASK_IS_AT_LU,
TASK_IS_NOT_AT_LU,
+ TASK_ABORT_FAILED,
};
static enum task_disposition sas_scsi_find_task(struct sas_task *task)
@@ -310,15 +312,6 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task)
spin_unlock_irqrestore(&core->task_queue_lock, flags);
}
- spin_lock_irqsave(&task->task_state_lock, flags);
- if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) {
- spin_unlock_irqrestore(&task->task_state_lock, flags);
- SAS_DPRINTK("%s: task 0x%p already aborted\n",
- __FUNCTION__, task);
- return TASK_IS_ABORTED;
- }
- spin_unlock_irqrestore(&task->task_state_lock, flags);
-
for (i = 0; i < 5; i++) {
SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task);
res = si->dft->lldd_abort_task(task);
@@ -340,15 +333,21 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task)
SAS_DPRINTK("%s: querying task 0x%p\n",
__FUNCTION__, task);
res = si->dft->lldd_query_task(task);
- if (res == TMF_RESP_FUNC_SUCC) {
+ switch (res) {
+ case TMF_RESP_FUNC_SUCC:
SAS_DPRINTK("%s: task 0x%p at LU\n",
__FUNCTION__, task);
return TASK_IS_AT_LU;
- } else if (res == TMF_RESP_FUNC_COMPLETE) {
+ case TMF_RESP_FUNC_COMPLETE:
SAS_DPRINTK("%s: task 0x%p not at LU\n",
__FUNCTION__, task);
return TASK_IS_NOT_AT_LU;
- }
+ case TMF_RESP_FUNC_FAILED:
+ SAS_DPRINTK("%s: task 0x%p failed to abort\n",
+ __FUNCTION__, task);
+ return TASK_ABORT_FAILED;
+ }
+
}
}
return res;
@@ -398,35 +397,113 @@ static int sas_recover_I_T(struct domain_device *dev)
return res;
}
-void sas_scsi_recover_host(struct Scsi_Host *shost)
+/* Find the sas_phy that's attached to this device */
+struct sas_phy *find_local_sas_phy(struct domain_device *dev)
+{
+ struct domain_device *pdev = dev->parent;
+ struct ex_phy *exphy = NULL;
+ int i;
+
+ /* Directly attached device */
+ if (!pdev)
+ return dev->port->phy;
+
+ /* Otherwise look in the expander */
+ for (i = 0; i < pdev->ex_dev.num_phys; i++)
+ if (!memcmp(dev->sas_addr,
+ pdev->ex_dev.ex_phy[i].attached_sas_addr,
+ SAS_ADDR_SIZE)) {
+ exphy = &pdev->ex_dev.ex_phy[i];
+ break;
+ }
+
+ BUG_ON(!exphy);
+ return exphy->phy;
+}
+
+/* Attempt to send a LUN reset message to a device */
+int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
+{
+ struct domain_device *dev = cmd_to_domain_dev(cmd);
+ struct sas_internal *i =
+ to_sas_internal(dev->port->ha->core.shost->transportt);
+ struct scsi_lun lun;
+ int res;
+
+ int_to_scsilun(cmd->device->lun, &lun);
+
+ if (!i->dft->lldd_lu_reset)
+ return FAILED;
+
+ res = i->dft->lldd_lu_reset(dev, lun.scsi_lun);
+ if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
+ return SUCCESS;
+
+ return FAILED;
+}
+
+/* Attempt to send a phy (bus) reset */
+int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd)
+{
+ struct domain_device *dev = cmd_to_domain_dev(cmd);
+ struct sas_phy *phy = find_local_sas_phy(dev);
+ int res;
+
+ res = sas_phy_reset(phy, 1);
+ if (res)
+ SAS_DPRINTK("Bus reset of %s failed 0x%x\n",
+ phy->dev.kobj.k_name,
+ res);
+ if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
+ return SUCCESS;
+
+ return FAILED;
+}
+
+/* Try to reset a device */
+static int try_to_reset_cmd_device(struct Scsi_Host *shost,
+ struct scsi_cmnd *cmd)
+{
+ int res;
+
+ if (!shost->hostt->eh_device_reset_handler)
+ goto try_bus_reset;
+
+ res = shost->hostt->eh_device_reset_handler(cmd);
+ if (res == SUCCESS)
+ return res;
+
+try_bus_reset:
+ if (shost->hostt->eh_bus_reset_handler)
+ return shost->hostt->eh_bus_reset_handler(cmd);
+
+ return FAILED;
+}
+
+static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
+ struct list_head *work_q,
+ struct list_head *done_q)
{
- struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
- unsigned long flags;
- LIST_HEAD(error_q);
struct scsi_cmnd *cmd, *n;
enum task_disposition res = TASK_IS_DONE;
- int tmf_resp;
+ int tmf_resp, need_reset;
struct sas_internal *i = to_sas_internal(shost->transportt);
+ unsigned long flags;
+ struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
- spin_lock_irqsave(shost->host_lock, flags);
- list_splice_init(&shost->eh_cmd_q, &error_q);
- spin_unlock_irqrestore(shost->host_lock, flags);
-
- SAS_DPRINTK("Enter %s\n", __FUNCTION__);
-
- /* All tasks on this list were marked SAS_TASK_STATE_ABORTED
- * by sas_scsi_timed_out() callback.
- */
Again:
- SAS_DPRINTK("going over list...\n");
- list_for_each_entry_safe(cmd, n, &error_q, eh_entry) {
+ list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
struct sas_task *task = TO_SAS_TASK(cmd);
- list_del_init(&cmd->eh_entry);
- if (!task) {
- SAS_DPRINTK("%s: taskless cmd?!\n", __FUNCTION__);
+ if (!task)
continue;
- }
+
+ list_del_init(&cmd->eh_entry);
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ need_reset = task->task_state_flags & SAS_TASK_NEED_DEV_RESET;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+
SAS_DPRINTK("trying to find task 0x%p\n", task);
res = sas_scsi_find_task(task);
@@ -437,11 +514,15 @@ Again:
SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
task);
task->task_done(task);
+ if (need_reset)
+ try_to_reset_cmd_device(shost, cmd);
continue;
case TASK_IS_ABORTED:
SAS_DPRINTK("%s: task 0x%p is aborted\n",
__FUNCTION__, task);
task->task_done(task);
+ if (need_reset)
+ try_to_reset_cmd_device(shost, cmd);
continue;
case TASK_IS_AT_LU:
SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
@@ -452,11 +533,14 @@ Again:
SAS_ADDR(task->dev),
cmd->device->lun);
task->task_done(task);
- sas_scsi_clear_queue_lu(&error_q, cmd);
+ if (need_reset)
+ try_to_reset_cmd_device(shost, cmd);
+ sas_scsi_clear_queue_lu(work_q, cmd);
goto Again;
}
/* fallthrough */
case TASK_IS_NOT_AT_LU:
+ case TASK_ABORT_FAILED:
SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n",
task);
tmf_resp = sas_recover_I_T(task->dev);
@@ -464,7 +548,9 @@ Again:
SAS_DPRINTK("I_T %016llx recovered\n",
SAS_ADDR(task->dev->sas_addr));
task->task_done(task);
- sas_scsi_clear_queue_I_T(&error_q, task->dev);
+ if (need_reset)
+ try_to_reset_cmd_device(shost, cmd);
+ sas_scsi_clear_queue_I_T(work_q, task->dev);
goto Again;
}
/* Hammer time :-) */
@@ -477,7 +563,9 @@ Again:
SAS_DPRINTK("clear nexus port:%d "
"succeeded\n", port->id);
task->task_done(task);
- sas_scsi_clear_queue_port(&error_q,
+ if (need_reset)
+ try_to_reset_cmd_device(shost, cmd);
+ sas_scsi_clear_queue_port(work_q,
port);
goto Again;
}
@@ -489,6 +577,8 @@ Again:
SAS_DPRINTK("clear nexus ha "
"succeeded\n");
task->task_done(task);
+ if (need_reset)
+ try_to_reset_cmd_device(shost, cmd);
goto out;
}
}
@@ -502,20 +592,54 @@ Again:
cmd->device->lun);
task->task_done(task);
+ if (need_reset)
+ try_to_reset_cmd_device(shost, cmd);
goto clear_q;
}
}
out:
- scsi_eh_flush_done_q(&ha->eh_done_q);
- SAS_DPRINTK("--- Exit %s\n", __FUNCTION__);
- return;
+ return list_empty(work_q);
clear_q:
SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__);
- list_for_each_entry_safe(cmd, n, &error_q, eh_entry) {
+ list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
struct sas_task *task = TO_SAS_TASK(cmd);
list_del_init(&cmd->eh_entry);
task->task_done(task);
}
+ return list_empty(work_q);
+}
+
+void sas_scsi_recover_host(struct Scsi_Host *shost)
+{
+ struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
+ unsigned long flags;
+ LIST_HEAD(eh_work_q);
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ list_splice_init(&shost->eh_cmd_q, &eh_work_q);
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ SAS_DPRINTK("Enter %s\n", __FUNCTION__);
+ /*
+ * Deal with commands that still have SAS tasks (i.e. they didn't
+ * complete via the normal sas_task completion mechanism)
+ */
+ if (sas_eh_handle_sas_errors(shost, &eh_work_q, &ha->eh_done_q))
+ goto out;
+
+ /*
+ * Now deal with SCSI commands that completed ok but have a an error
+ * code (and hopefully sense data) attached. This is roughly what
+ * scsi_unjam_host does, but we skip scsi_eh_abort_cmds because any
+ * command we see here has no sas_task and is thus unknown to the HA.
+ */
+ if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q))
+ scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q);
+
+out:
+ scsi_eh_flush_done_q(&ha->eh_done_q);
+ SAS_DPRINTK("--- Exit %s\n", __FUNCTION__);
+ return;
}
enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
@@ -524,24 +648,30 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
unsigned long flags;
if (!task) {
- SAS_DPRINTK("command 0x%p, task 0x%p, gone: EH_HANDLED\n",
- cmd, task);
- return EH_HANDLED;
+ cmd->timeout_per_command /= 2;
+ SAS_DPRINTK("command 0x%p, task 0x%p, gone: %s\n",
+ cmd, task, (cmd->timeout_per_command ?
+ "EH_RESET_TIMER" : "EH_NOT_HANDLED"));
+ if (!cmd->timeout_per_command)
+ return EH_NOT_HANDLED;
+ return EH_RESET_TIMER;
}
spin_lock_irqsave(&task->task_state_lock, flags);
- if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) {
- spin_unlock_irqrestore(&task->task_state_lock, flags);
- SAS_DPRINTK("command 0x%p, task 0x%p, aborted by initiator: "
- "EH_NOT_HANDLED\n", cmd, task);
- return EH_NOT_HANDLED;
- }
+ BUG_ON(task->task_state_flags & SAS_TASK_STATE_ABORTED);
if (task->task_state_flags & SAS_TASK_STATE_DONE) {
spin_unlock_irqrestore(&task->task_state_lock, flags);
SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
cmd, task);
return EH_HANDLED;
}
+ if (!(task->task_state_flags & SAS_TASK_AT_INITIATOR)) {
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+ SAS_DPRINTK("command 0x%p, task 0x%p, not at initiator: "
+ "EH_RESET_TIMER\n",
+ cmd, task);
+ return EH_RESET_TIMER;
+ }
task->task_state_flags |= SAS_TASK_STATE_ABORTED;
spin_unlock_irqrestore(&task->task_state_lock, flags);
@@ -557,8 +687,9 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
struct domain_device *found_dev = NULL;
int i;
+ unsigned long flags;
- spin_lock(&ha->phy_port_lock);
+ spin_lock_irqsave(&ha->phy_port_lock, flags);
for (i = 0; i < ha->num_phys; i++) {
struct asd_sas_port *port = ha->sas_port[i];
struct domain_device *dev;
@@ -574,7 +705,7 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
spin_unlock(&port->dev_list_lock);
}
found:
- spin_unlock(&ha->phy_port_lock);
+ spin_unlock_irqrestore(&ha->phy_port_lock, flags);
return found_dev;
}
@@ -623,6 +754,8 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
scsi_deactivate_tcq(scsi_dev, 1);
}
+ scsi_dev->allow_restart = 1;
+
return 0;
}
@@ -799,46 +932,42 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha)
spin_unlock_irqrestore(&core->task_queue_lock, flags);
}
-static int do_sas_task_abort(struct sas_task *task)
+/*
+ * Call the LLDD task abort routine directly. This function is intended for
+ * use by upper layers that need to tell the LLDD to abort a task.
+ */
+int __sas_task_abort(struct sas_task *task)
{
- struct scsi_cmnd *sc = task->uldd_task;
struct sas_internal *si =
to_sas_internal(task->dev->port->ha->core.shost->transportt);
unsigned long flags;
int res;
spin_lock_irqsave(&task->task_state_lock, flags);
- if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
+ if (task->task_state_flags & SAS_TASK_STATE_ABORTED ||
+ task->task_state_flags & SAS_TASK_STATE_DONE) {
spin_unlock_irqrestore(&task->task_state_lock, flags);
- SAS_DPRINTK("%s: Task %p already aborted.\n", __FUNCTION__,
+ SAS_DPRINTK("%s: Task %p already finished.\n", __FUNCTION__,
task);
return 0;
}
-
- task->task_state_flags |= SAS_TASK_INITIATOR_ABORTED;
- if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
- task->task_state_flags |= SAS_TASK_STATE_ABORTED;
+ task->task_state_flags |= SAS_TASK_STATE_ABORTED;
spin_unlock_irqrestore(&task->task_state_lock, flags);
if (!si->dft->lldd_abort_task)
return -ENODEV;
res = si->dft->lldd_abort_task(task);
+
+ spin_lock_irqsave(&task->task_state_lock, flags);
if ((task->task_state_flags & SAS_TASK_STATE_DONE) ||
(res == TMF_RESP_FUNC_COMPLETE))
{
- /* SMP commands don't have scsi_cmds(?) */
- if (!sc) {
- task->task_done(task);
- return 0;
- }
- scsi_req_abort_cmd(sc);
- scsi_schedule_eh(sc->device->host);
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+ task->task_done(task);
return 0;
}
- spin_lock_irqsave(&task->task_state_lock, flags);
- task->task_state_flags &= ~SAS_TASK_INITIATOR_ABORTED;
if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
spin_unlock_irqrestore(&task->task_state_lock, flags);
@@ -846,17 +975,24 @@ static int do_sas_task_abort(struct sas_task *task)
return -EAGAIN;
}
-void sas_task_abort(struct work_struct *work)
+/*
+ * Tell an upper layer that it needs to initiate an abort for a given task.
+ * This should only ever be called by an LLDD.
+ */
+void sas_task_abort(struct sas_task *task)
{
- struct sas_task *task =
- container_of(work, struct sas_task, abort_work);
- int i;
+ struct scsi_cmnd *sc = task->uldd_task;
- for (i = 0; i < 5; i++)
- if (!do_sas_task_abort(task))
+ /* Escape for libsas internal commands */
+ if (!sc) {
+ if (!del_timer(&task->timer))
return;
+ task->timer.function(task->timer.data);
+ return;
+ }
- SAS_DPRINTK("%s: Could not kill task!\n", __FUNCTION__);
+ scsi_req_abort_cmd(sc);
+ scsi_schedule_eh(sc->device->host);
}
EXPORT_SYMBOL_GPL(sas_queuecommand);
@@ -866,5 +1002,9 @@ EXPORT_SYMBOL_GPL(sas_slave_destroy);
EXPORT_SYMBOL_GPL(sas_change_queue_depth);
EXPORT_SYMBOL_GPL(sas_change_queue_type);
EXPORT_SYMBOL_GPL(sas_bios_param);
+EXPORT_SYMBOL_GPL(__sas_task_abort);
EXPORT_SYMBOL_GPL(sas_task_abort);
EXPORT_SYMBOL_GPL(sas_phy_reset);
+EXPORT_SYMBOL_GPL(sas_phy_enable);
+EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler);
+EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler);
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 77d9d3804ccf..808a1b8c4043 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -92,7 +92,7 @@ static struct mega_hbas mega_hbas[MAX_CONTROLLERS];
/*
* The File Operations structure for the serial/ioctl interface of the driver
*/
-static struct file_operations megadev_fops = {
+static const struct file_operations megadev_fops = {
.owner = THIS_MODULE,
.ioctl = megadev_ioctl,
.open = megadev_open,
diff --git a/drivers/scsi/megaraid/mbox_defs.h b/drivers/scsi/megaraid/mbox_defs.h
index 3052869f51f4..170399ef06f4 100644
--- a/drivers/scsi/megaraid/mbox_defs.h
+++ b/drivers/scsi/megaraid/mbox_defs.h
@@ -748,7 +748,7 @@ typedef struct {
/**
- * private_bios_data - bios private data for boot devices
+ * struct private_bios_data - bios private data for boot devices
* @geometry : bits 0-3 - BIOS geometry, 0x0001 - 1GB, 0x0010 - 2GB,
* 0x1000 - 8GB, Others values are invalid
* @unused : bits 4-7 are unused
diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h
index b50e27e66024..26e1e6c55654 100644
--- a/drivers/scsi/megaraid/mega_common.h
+++ b/drivers/scsi/megaraid/mega_common.h
@@ -46,17 +46,17 @@
/**
* scb_t - scsi command control block
- * @param ccb : command control block for individual driver
- * @param list : list of control blocks
- * @param gp : general purpose field for LLDs
- * @param sno : all SCBs have a serial number
- * @param scp : associated scsi command
- * @param state : current state of scb
- * @param dma_dir : direction of data transfer
- * @param dma_type : transfer with sg list, buffer, or no data transfer
- * @param dev_channel : actual channel on the device
- * @param dev_target : actual target on the device
- * @param status : completion status
+ * @ccb : command control block for individual driver
+ * @list : list of control blocks
+ * @gp : general purpose field for LLDs
+ * @sno : all SCBs have a serial number
+ * @scp : associated scsi command
+ * @state : current state of scb
+ * @dma_dir : direction of data transfer
+ * @dma_type : transfer with sg list, buffer, or no data transfer
+ * @dev_channel : actual channel on the device
+ * @dev_target : actual target on the device
+ * @status : completion status
*
* This is our central data structure to issue commands the each driver.
* Driver specific data structures are maintained in the ccb field.
@@ -99,42 +99,42 @@ typedef struct {
/**
* struct adapter_t - driver's initialization structure
- * @param dpc_h : tasklet handle
- * @param pdev : pci configuration pointer for kernel
- * @param host : pointer to host structure of mid-layer
- * @param lock : synchronization lock for mid-layer and driver
- * @param quiescent : driver is quiescent for now.
- * @param outstanding_cmds : number of commands pending in the driver
- * @param kscb_list : pointer to the bulk of SCBs pointers for IO
- * @param kscb_pool : pool of free scbs for IO
- * @param kscb_pool_lock : lock for pool of free scbs
- * @param pend_list : pending commands list
- * @param pend_list_lock : exlusion lock for pending commands list
- * @param completed_list : list of completed commands
- * @param completed_list_lock : exclusion lock for list of completed commands
- * @param sglen : max sg elements supported
- * @param device_ids : to convert kernel device addr to our devices.
- * @param raid_device : raid adapter specific pointer
- * @param max_channel : maximum channel number supported - inclusive
- * @param max_target : max target supported - inclusive
- * @param max_lun : max lun supported - inclusive
- * @param unique_id : unique identifier for each adapter
- * @param irq : IRQ for this adapter
- * @param ito : internal timeout value, (-1) means no timeout
- * @param ibuf : buffer to issue internal commands
- * @param ibuf_dma_h : dma handle for the above buffer
- * @param uscb_list : SCB pointers for user cmds, common mgmt module
- * @param uscb_pool : pool of SCBs for user commands
- * @param uscb_pool_lock : exclusion lock for these SCBs
- * @param max_cmds : max outstanding commands
- * @param fw_version : firmware version
- * @param bios_version : bios version
- * @param max_cdb_sz : biggest CDB size supported.
- * @param ha : is high availability present - clustering
- * @param init_id : initiator ID, the default value should be 7
- * @param max_sectors : max sectors per request
- * @param cmd_per_lun : max outstanding commands per LUN
- * @param being_detached : set when unloading, no more mgmt calls
+ * @aram dpc_h : tasklet handle
+ * @pdev : pci configuration pointer for kernel
+ * @host : pointer to host structure of mid-layer
+ * @lock : synchronization lock for mid-layer and driver
+ * @quiescent : driver is quiescent for now.
+ * @outstanding_cmds : number of commands pending in the driver
+ * @kscb_list : pointer to the bulk of SCBs pointers for IO
+ * @kscb_pool : pool of free scbs for IO
+ * @kscb_pool_lock : lock for pool of free scbs
+ * @pend_list : pending commands list
+ * @pend_list_lock : exclusion lock for pending commands list
+ * @completed_list : list of completed commands
+ * @completed_list_lock : exclusion lock for list of completed commands
+ * @sglen : max sg elements supported
+ * @device_ids : to convert kernel device addr to our devices.
+ * @raid_device : raid adapter specific pointer
+ * @max_channel : maximum channel number supported - inclusive
+ * @max_target : max target supported - inclusive
+ * @max_lun : max lun supported - inclusive
+ * @unique_id : unique identifier for each adapter
+ * @irq : IRQ for this adapter
+ * @ito : internal timeout value, (-1) means no timeout
+ * @ibuf : buffer to issue internal commands
+ * @ibuf_dma_h : dma handle for the above buffer
+ * @uscb_list : SCB pointers for user cmds, common mgmt module
+ * @uscb_pool : pool of SCBs for user commands
+ * @uscb_pool_lock : exclusion lock for these SCBs
+ * @max_cmds : max outstanding commands
+ * @fw_version : firmware version
+ * @bios_version : bios version
+ * @max_cdb_sz : biggest CDB size supported.
+ * @ha : is high availability present - clustering
+ * @init_id : initiator ID, the default value should be 7
+ * @max_sectors : max sectors per request
+ * @cmd_per_lun : max outstanding commands per LUN
+ * @being_detached : set when unloading, no more mgmt calls
*
*
* mraid_setup_device_map() can be called anytime after the device map is
@@ -211,23 +211,23 @@ typedef struct {
#define SCP2ADAPTER(scp) (adapter_t *)SCSIHOST2ADAP(SCP2HOST(scp))
-/**
- * MRAID_GET_DEVICE_MAP - device ids
- * @param adp - Adapter's soft state
- * @param scp - mid-layer scsi command pointer
- * @param p_chan - physical channel on the controller
- * @param target - target id of the device or logical drive number
- * @param islogical - set if the command is for the logical drive
- *
- * Macro to retrieve information about device class, logical or physical and
- * the corresponding physical channel and target or logical drive number
- **/
#define MRAID_IS_LOGICAL(adp, scp) \
(SCP2CHANNEL(scp) == (adp)->max_channel) ? 1 : 0
#define MRAID_IS_LOGICAL_SDEV(adp, sdev) \
(sdev->channel == (adp)->max_channel) ? 1 : 0
+/**
+ * MRAID_GET_DEVICE_MAP - device ids
+ * @adp : adapter's soft state
+ * @scp : mid-layer scsi command pointer
+ * @p_chan : physical channel on the controller
+ * @target : target id of the device or logical drive number
+ * @islogical : set if the command is for the logical drive
+ *
+ * Macro to retrieve information about device class, logical or physical and
+ * the corresponding physical channel and target or logical drive number
+ */
#define MRAID_GET_DEVICE_MAP(adp, scp, p_chan, target, islogical) \
/* \
* Is the request coming for the virtual channel \
@@ -271,10 +271,10 @@ typedef struct {
#define ASSERT(expression)
#endif
-/*
+/**
* struct mraid_pci_blk - structure holds DMA memory block info
- * @param vaddr : virtual address to a memory block
- * @param dma_addr : DMA handle to a memory block
+ * @vaddr : virtual address to a memory block
+ * @dma_addr : DMA handle to a memory block
*
* This structure is filled up for the caller. It is the responsibilty of the
* caller to allocate this array big enough to store addresses for all
diff --git a/drivers/scsi/megaraid/megaraid_ioctl.h b/drivers/scsi/megaraid/megaraid_ioctl.h
index b8aa34202ec3..706fa05a187a 100644
--- a/drivers/scsi/megaraid/megaraid_ioctl.h
+++ b/drivers/scsi/megaraid/megaraid_ioctl.h
@@ -22,23 +22,23 @@
#include "mbox_defs.h"
+/*
+ * console messages debug levels
+ */
+#define CL_ANN 0 /* print unconditionally, announcements */
+#define CL_DLEVEL1 1 /* debug level 1, informative */
+#define CL_DLEVEL2 2 /* debug level 2, verbose */
+#define CL_DLEVEL3 3 /* debug level 3, very verbose */
+
/**
* con_log() - console log routine
- * @param level : indicates the severity of the message.
- * @fparam mt : format string
+ * @level : indicates the severity of the message.
+ * @fmt : format string
*
* con_log displays the error messages on the console based on the current
* debug level. Also it attaches the appropriate kernel severity level with
* the message.
- *
- *
- * consolge messages debug levels
*/
-#define CL_ANN 0 /* print unconditionally, announcements */
-#define CL_DLEVEL1 1 /* debug level 1, informative */
-#define CL_DLEVEL2 2 /* debug level 2, verbose */
-#define CL_DLEVEL3 3 /* debug level 3, very verbose */
-
#define con_log(level, fmt) if (LSI_DBGLVL >= level) printk fmt;
/*
@@ -157,14 +157,14 @@ typedef struct uioc {
/**
* struct mraid_hba_info - information about the controller
*
- * @param pci_vendor_id : PCI vendor id
- * @param pci_device_id : PCI device id
- * @param subsystem_vendor_id : PCI subsystem vendor id
- * @param subsystem_device_id : PCI subsystem device id
- * @param baseport : base port of hba memory
- * @param pci_bus : PCI bus
- * @param pci_dev_fn : PCI device/function values
- * @param irq : interrupt vector for the device
+ * @pci_vendor_id : PCI vendor id
+ * @pci_device_id : PCI device id
+ * @subsystem_vendor_id : PCI subsystem vendor id
+ * @subsystem_device_id : PCI subsystem device id
+ * @baseport : base port of hba memory
+ * @pci_bus : PCI bus
+ * @pci_dev_fn : PCI device/function values
+ * @irq : interrupt vector for the device
*
* Extended information of 256 bytes about the controller. Align on the single
* byte boundary so that 32-bit applications can be run on 64-bit platform
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 7bac86dda88f..04d0b6918c61 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -10,13 +10,13 @@
* 2 of the License, or (at your option) any later version.
*
* FILE : megaraid_mbox.c
- * Version : v2.20.4.9 (Jul 16 2006)
+ * Version : v2.20.5.1 (Nov 16 2006)
*
* Authors:
- * Atul Mukker <Atul.Mukker@lsil.com>
- * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>
- * Manoj Jose <Manoj.Jose@lsil.com>
- * Seokmann Ju <Seokmann.Ju@lsil.com>
+ * Atul Mukker <Atul.Mukker@lsi.com>
+ * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsi.com>
+ * Manoj Jose <Manoj.Jose@lsi.com>
+ * Seokmann Ju
*
* List of supported controllers
*
@@ -107,6 +107,7 @@ static int megaraid_mbox_support_random_del(adapter_t *);
static int megaraid_mbox_get_max_sg(adapter_t *);
static void megaraid_mbox_enum_raid_scsi(adapter_t *);
static void megaraid_mbox_flush_cache(adapter_t *);
+static int megaraid_mbox_fire_sync_cmd(adapter_t *);
static void megaraid_mbox_display_scb(adapter_t *, scb_t *);
static void megaraid_mbox_setup_device_map(adapter_t *);
@@ -137,7 +138,7 @@ static int wait_till_fw_empty(adapter_t *);
-MODULE_AUTHOR("sju@lsil.com");
+MODULE_AUTHOR("megaraidlinux@lsi.com");
MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(MEGARAID_VERSION);
@@ -146,7 +147,7 @@ MODULE_VERSION(MEGARAID_VERSION);
* ### modules parameters for driver ###
*/
-/**
+/*
* Set to enable driver to expose unconfigured disk to kernel
*/
static int megaraid_expose_unconf_disks = 0;
@@ -154,7 +155,7 @@ module_param_named(unconf_disks, megaraid_expose_unconf_disks, int, 0);
MODULE_PARM_DESC(unconf_disks,
"Set to expose unconfigured disks to kernel (default=0)");
-/**
+/*
* driver wait time if the adapter's mailbox is busy
*/
static unsigned int max_mbox_busy_wait = MBOX_BUSY_WAIT;
@@ -162,7 +163,7 @@ module_param_named(busy_wait, max_mbox_busy_wait, int, 0);
MODULE_PARM_DESC(busy_wait,
"Max wait for mailbox in microseconds if busy (default=10)");
-/**
+/*
* number of sectors per IO command
*/
static unsigned int megaraid_max_sectors = MBOX_MAX_SECTORS;
@@ -170,7 +171,7 @@ module_param_named(max_sectors, megaraid_max_sectors, int, 0);
MODULE_PARM_DESC(max_sectors,
"Maximum number of sectors per IO command (default=128)");
-/**
+/*
* number of commands per logical unit
*/
static unsigned int megaraid_cmd_per_lun = MBOX_DEF_CMD_PER_LUN;
@@ -179,7 +180,7 @@ MODULE_PARM_DESC(cmd_per_lun,
"Maximum number of commands per logical unit (default=64)");
-/**
+/*
* Fast driver load option, skip scanning for physical devices during load.
* This would result in non-disk devices being skipped during driver load
* time. These can be later added though, using /proc/scsi/scsi
@@ -190,7 +191,7 @@ MODULE_PARM_DESC(fast_load,
"Faster loading of the driver, skips physical devices! (default=0)");
-/**
+/*
* mraid_debug level - threshold for amount of information to be displayed by
* the driver. This level can be changed through modules parameters, ioctl or
* sysfs/proc interface. By default, print the announcement messages only.
@@ -337,7 +338,7 @@ static struct device_attribute *megaraid_sdev_attrs[] = {
*
* Return value:
* actual depth set
- **/
+ */
static int megaraid_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
if (qdepth > MBOX_MAX_SCSI_CMDS)
@@ -369,8 +370,8 @@ static struct scsi_host_template megaraid_template_g = {
* megaraid_init - module load hook
*
* We register ourselves as hotplug enabled module and let PCI subsystem
- * discover our adaters
- **/
+ * discover our adapters.
+ */
static int __init
megaraid_init(void)
{
@@ -405,7 +406,7 @@ megaraid_init(void)
/**
* megaraid_exit - driver unload entry point
*
- * We simply unwrap the megaraid_init routine here
+ * We simply unwrap the megaraid_init routine here.
*/
static void __exit
megaraid_exit(void)
@@ -421,12 +422,12 @@ megaraid_exit(void)
/**
* megaraid_probe_one - PCI hotplug entry point
- * @param pdev : handle to this controller's PCI configuration space
- * @param id : pci device id of the class of controllers
+ * @pdev : handle to this controller's PCI configuration space
+ * @id : pci device id of the class of controllers
*
* This routine should be called whenever a new adapter is detected by the
* PCI hotplug susbsytem.
- **/
+ */
static int __devinit
megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
@@ -542,16 +543,15 @@ out_probe_one:
/**
- * megaraid_detach_one - release the framework resources and call LLD release
- * routine
- * @param pdev : handle for our PCI cofiguration space
+ * megaraid_detach_one - release framework resources and call LLD release routine
+ * @pdev : handle for our PCI cofiguration space
*
* This routine is called during driver unload. We free all the allocated
* resources and call the corresponding LLD so that it can also release all
* its resources.
*
- * This routine is also called from the PCI hotplug system
- **/
+ * This routine is also called from the PCI hotplug system.
+ */
static void
megaraid_detach_one(struct pci_dev *pdev)
{
@@ -615,9 +615,9 @@ megaraid_detach_one(struct pci_dev *pdev)
/**
* megaraid_mbox_shutdown - PCI shutdown for megaraid HBA
- * @param device : generice driver model device
+ * @pdev : generic driver model device
*
- * Shutdown notification, perform flush cache
+ * Shutdown notification, perform flush cache.
*/
static void
megaraid_mbox_shutdown(struct pci_dev *pdev)
@@ -643,10 +643,10 @@ megaraid_mbox_shutdown(struct pci_dev *pdev)
/**
* megaraid_io_attach - attach a device with the IO subsystem
- * @param adapter : controller's soft state
+ * @adapter : controller's soft state
*
- * Attach this device with the IO subsystem
- **/
+ * Attach this device with the IO subsystem.
+ */
static int
megaraid_io_attach(adapter_t *adapter)
{
@@ -695,10 +695,10 @@ megaraid_io_attach(adapter_t *adapter)
/**
* megaraid_io_detach - detach a device from the IO subsystem
- * @param adapter : controller's soft state
+ * @adapter : controller's soft state
*
- * Detach this device from the IO subsystem
- **/
+ * Detach this device from the IO subsystem.
+ */
static void
megaraid_io_detach(adapter_t *adapter)
{
@@ -722,13 +722,13 @@ megaraid_io_detach(adapter_t *adapter)
/**
* megaraid_init_mbox - initialize controller
- * @param adapter - our soft state
+ * @adapter : our soft state
*
- * . Allocate 16-byte aligned mailbox memory for firmware handshake
- * . Allocate controller's memory resources
- * . Find out all initialization data
- * . Allocate memory required for all the commands
- * . Use internal library of FW routines, build up complete soft state
+ * - Allocate 16-byte aligned mailbox memory for firmware handshake
+ * - Allocate controller's memory resources
+ * - Find out all initialization data
+ * - Allocate memory required for all the commands
+ * - Use internal library of FW routines, build up complete soft state
*/
static int __devinit
megaraid_init_mbox(adapter_t *adapter)
@@ -779,33 +779,39 @@ megaraid_init_mbox(adapter_t *adapter)
goto out_release_regions;
}
- //
- // Setup the rest of the soft state using the library of FW routines
- //
+ /* initialize the mutual exclusion lock for the mailbox */
+ spin_lock_init(&raid_dev->mailbox_lock);
- // request IRQ and register the interrupt service routine
+ /* allocate memory required for commands */
+ if (megaraid_alloc_cmd_packets(adapter) != 0)
+ goto out_iounmap;
+
+ /*
+ * Issue SYNC cmd to flush the pending cmds in the adapter
+ * and initialize its internal state
+ */
+
+ if (megaraid_mbox_fire_sync_cmd(adapter))
+ con_log(CL_ANN, ("megaraid: sync cmd failed\n"));
+
+ /*
+ * Setup the rest of the soft state using the library of
+ * FW routines
+ */
+
+ /* request IRQ and register the interrupt service routine */
if (request_irq(adapter->irq, megaraid_isr, IRQF_SHARED, "megaraid",
adapter)) {
con_log(CL_ANN, (KERN_WARNING
"megaraid: Couldn't register IRQ %d!\n", adapter->irq));
+ goto out_alloc_cmds;
- goto out_iounmap;
- }
-
-
- // initialize the mutual exclusion lock for the mailbox
- spin_lock_init(&raid_dev->mailbox_lock);
-
- // allocate memory required for commands
- if (megaraid_alloc_cmd_packets(adapter) != 0) {
- goto out_free_irq;
}
// Product info
- if (megaraid_mbox_product_info(adapter) != 0) {
- goto out_alloc_cmds;
- }
+ if (megaraid_mbox_product_info(adapter) != 0)
+ goto out_free_irq;
// Do we support extended CDBs
adapter->max_cdb_sz = 10;
@@ -874,9 +880,8 @@ megaraid_init_mbox(adapter_t *adapter)
* Allocate resources required to issue FW calls, when sysfs is
* accessed
*/
- if (megaraid_sysfs_alloc_resources(adapter) != 0) {
- goto out_alloc_cmds;
- }
+ if (megaraid_sysfs_alloc_resources(adapter) != 0)
+ goto out_free_irq;
// Set the DMA mask to 64-bit. All supported controllers as capable of
// DMA in this range
@@ -920,10 +925,10 @@ megaraid_init_mbox(adapter_t *adapter)
out_free_sysfs_res:
megaraid_sysfs_free_resources(adapter);
-out_alloc_cmds:
- megaraid_free_cmd_packets(adapter);
out_free_irq:
free_irq(adapter->irq, adapter);
+out_alloc_cmds:
+ megaraid_free_cmd_packets(adapter);
out_iounmap:
iounmap(raid_dev->baseaddr);
out_release_regions:
@@ -937,7 +942,7 @@ out_free_raid_dev:
/**
* megaraid_fini_mbox - undo controller initialization
- * @param adapter : our soft state
+ * @adapter : our soft state
*/
static void
megaraid_fini_mbox(adapter_t *adapter)
@@ -967,12 +972,12 @@ megaraid_fini_mbox(adapter_t *adapter)
/**
* megaraid_alloc_cmd_packets - allocate shared mailbox
- * @param adapter : soft state of the raid controller
+ * @adapter : soft state of the raid controller
*
* Allocate and align the shared mailbox. This maibox is used to issue
* all the commands. For IO based controllers, the mailbox is also regsitered
* with the FW. Allocate memory for all commands as well.
- * This is our big allocator
+ * This is our big allocator.
*/
static int
megaraid_alloc_cmd_packets(adapter_t *adapter)
@@ -1132,9 +1137,9 @@ out_free_common_mbox:
/**
* megaraid_free_cmd_packets - free memory
- * @param adapter : soft state of the raid controller
+ * @adapter : soft state of the raid controller
*
- * Release memory resources allocated for commands
+ * Release memory resources allocated for commands.
*/
static void
megaraid_free_cmd_packets(adapter_t *adapter)
@@ -1156,10 +1161,10 @@ megaraid_free_cmd_packets(adapter_t *adapter)
/**
* megaraid_mbox_setup_dma_pools - setup dma pool for command packets
- * @param adapter : HBA soft state
+ * @adapter : HBA soft state
*
- * setup the dma pools for mailbox, passthru and extended passthru structures,
- * and scatter-gather lists
+ * Setup the dma pools for mailbox, passthru and extended passthru structures,
+ * and scatter-gather lists.
*/
static int
megaraid_mbox_setup_dma_pools(adapter_t *adapter)
@@ -1252,10 +1257,10 @@ fail_setup_dma_pool:
/**
* megaraid_mbox_teardown_dma_pools - teardown dma pools for command packets
- * @param adapter : HBA soft state
+ * @adapter : HBA soft state
*
- * teardown the dma pool for mailbox, passthru and extended passthru
- * structures, and scatter-gather lists
+ * Teardown the dma pool for mailbox, passthru and extended passthru
+ * structures, and scatter-gather lists.
*/
static void
megaraid_mbox_teardown_dma_pools(adapter_t *adapter)
@@ -1300,10 +1305,11 @@ megaraid_mbox_teardown_dma_pools(adapter_t *adapter)
/**
* megaraid_alloc_scb - detach and return a scb from the free list
* @adapter : controller's soft state
+ * @scp : pointer to the scsi command to be executed
*
- * return the scb from the head of the free list. NULL if there are none
- * available
- **/
+ * Return the scb from the head of the free list. %NULL if there are none
+ * available.
+ */
static scb_t *
megaraid_alloc_scb(adapter_t *adapter, struct scsi_cmnd *scp)
{
@@ -1337,11 +1343,11 @@ megaraid_alloc_scb(adapter_t *adapter, struct scsi_cmnd *scp)
* @adapter : controller's soft state
* @scb : scb to be freed
*
- * return the scb back to the free list of scbs. The caller must 'flush' the
+ * Return the scb back to the free list of scbs. The caller must 'flush' the
* SCB before calling us. E.g., performing pci_unamp and/or pci_sync etc.
* NOTE NOTE: Make sure the scb is not on any list before calling this
* routine.
- **/
+ */
static inline void
megaraid_dealloc_scb(adapter_t *adapter, scb_t *scb)
{
@@ -1362,10 +1368,10 @@ megaraid_dealloc_scb(adapter_t *adapter, scb_t *scb)
/**
* megaraid_mbox_mksgl - make the scatter-gather list
- * @adapter - controller's soft state
- * @scb - scsi control block
+ * @adapter : controller's soft state
+ * @scb : scsi control block
*
- * prepare the scatter-gather list
+ * Prepare the scatter-gather list.
*/
static int
megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb)
@@ -1435,10 +1441,10 @@ megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb)
/**
* mbox_post_cmd - issue a mailbox command
- * @adapter - controller's soft state
- * @scb - command to be issued
+ * @adapter : controller's soft state
+ * @scb : command to be issued
*
- * post the command to the controller if mailbox is availble.
+ * Post the command to the controller if mailbox is available.
*/
static int
mbox_post_cmd(adapter_t *adapter, scb_t *scb)
@@ -1518,7 +1524,7 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb)
* Queue entry point for mailbox based controllers.
*/
static int
-megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *))
+megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
{
adapter_t *adapter;
scb_t *scb;
@@ -1548,15 +1554,15 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *))
}
/**
- * megaraid_mbox_build_cmd - transform the mid-layer scsi command to megaraid
- * firmware lingua
- * @adapter - controller's soft state
- * @scp - mid-layer scsi command pointer
- * @busy - set if request could not be completed because of lack of
+ * megaraid_mbox_build_cmd - transform the mid-layer scsi commands
+ * @adapter : controller's soft state
+ * @scp : mid-layer scsi command pointer
+ * @busy : set if request could not be completed because of lack of
* resources
*
- * convert the command issued by mid-layer to format understood by megaraid
- * firmware. We also complete certain command without sending them to firmware
+ * Transform the mid-layer scsi command to megaraid firmware lingua.
+ * Convert the command issued by mid-layer to format understood by megaraid
+ * firmware. We also complete certain commands without sending them to firmware.
*/
static scb_t *
megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
@@ -1937,9 +1943,9 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
/**
* megaraid_mbox_runpendq - execute commands queued in the pending queue
* @adapter : controller's soft state
- * @scb : SCB to be queued in the pending list
+ * @scb_q : SCB to be queued in the pending list
*
- * scan the pending list for commands which are not yet issued and try to
+ * Scan the pending list for commands which are not yet issued and try to
* post to the controller. The SCB can be a null pointer, which would indicate
* no SCB to be queue, just try to execute the ones in the pending list.
*
@@ -2012,11 +2018,11 @@ megaraid_mbox_runpendq(adapter_t *adapter, scb_t *scb_q)
/**
* megaraid_mbox_prepare_pthru - prepare a command for physical devices
- * @adapter - pointer to controller's soft state
- * @scb - scsi control block
- * @scp - scsi command from the mid-layer
+ * @adapter : pointer to controller's soft state
+ * @scb : scsi control block
+ * @scp : scsi command from the mid-layer
*
- * prepare a command for the scsi physical devices
+ * Prepare a command for the scsi physical devices.
*/
static void
megaraid_mbox_prepare_pthru(adapter_t *adapter, scb_t *scb,
@@ -2060,12 +2066,12 @@ megaraid_mbox_prepare_pthru(adapter_t *adapter, scb_t *scb,
/**
* megaraid_mbox_prepare_epthru - prepare a command for physical devices
- * @adapter - pointer to controller's soft state
- * @scb - scsi control block
- * @scp - scsi command from the mid-layer
+ * @adapter : pointer to controller's soft state
+ * @scb : scsi control block
+ * @scp : scsi command from the mid-layer
*
- * prepare a command for the scsi physical devices. This rountine prepares
- * commands for devices which can take extended CDBs (>10 bytes)
+ * Prepare a command for the scsi physical devices. This rountine prepares
+ * commands for devices which can take extended CDBs (>10 bytes).
*/
static void
megaraid_mbox_prepare_epthru(adapter_t *adapter, scb_t *scb,
@@ -2109,9 +2115,9 @@ megaraid_mbox_prepare_epthru(adapter_t *adapter, scb_t *scb,
/**
* megaraid_ack_sequence - interrupt ack sequence for memory mapped HBAs
- * @adapter - controller's soft state
+ * @adapter : controller's soft state
*
- * Interrupt ackrowledgement sequence for memory mapped HBAs. Find out the
+ * Interrupt acknowledgement sequence for memory mapped HBAs. Find out the
* completed command and put them on the completed list for later processing.
*
* Returns: 1 if the interrupt is valid, 0 otherwise
@@ -2224,9 +2230,8 @@ megaraid_ack_sequence(adapter_t *adapter)
/**
* megaraid_isr - isr for memory based mailbox based controllers
- * @irq - irq
- * @devp - pointer to our soft state
- * @regs - unused
+ * @irq : irq
+ * @devp : pointer to our soft state
*
* Interrupt service routine for memory-mapped mailbox controllers.
*/
@@ -2671,7 +2676,7 @@ megaraid_abort_handler(struct scsi_cmnd *scp)
* the FW is still live, in which case the outstanding commands counter mut go
* down to 0. If that happens, also issue the reservation reset command to
* relinquish (possible) reservations on the logical drives connected to this
- * host
+ * host.
**/
static int
megaraid_reset_handler(struct scsi_cmnd *scp)
@@ -2823,11 +2828,11 @@ megaraid_reset_handler(struct scsi_cmnd *scp)
/**
* mbox_post_sync_cmd() - blocking command to the mailbox based controllers
- * @adapter - controller's soft state
- * @raw_mbox - the mailbox
+ * @adapter : controller's soft state
+ * @raw_mbox : the mailbox
*
* Issue a scb in synchronous and non-interrupt mode for mailbox based
- * controllers
+ * controllers.
*/
static int
mbox_post_sync_cmd(adapter_t *adapter, uint8_t raw_mbox[])
@@ -2955,12 +2960,12 @@ blocked_mailbox:
/**
* mbox_post_sync_cmd_fast - blocking command to the mailbox based controllers
- * @adapter - controller's soft state
- * @raw_mbox - the mailbox
+ * @adapter : controller's soft state
+ * @raw_mbox : the mailbox
*
* Issue a scb in synchronous and non-interrupt mode for mailbox based
* controllers. This is a faster version of the synchronous command and
- * therefore can be called in interrupt-context as well
+ * therefore can be called in interrupt-context as well.
*/
static int
mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[])
@@ -3008,10 +3013,10 @@ mbox_post_sync_cmd_fast(adapter_t *adapter, uint8_t raw_mbox[])
/**
* megaraid_busywait_mbox() - Wait until the controller's mailbox is available
- * @raid_dev - RAID device (HBA) soft state
+ * @raid_dev : RAID device (HBA) soft state
*
- * wait until the controller's mailbox is available to accept more commands.
- * wait for at most 1 second
+ * Wait until the controller's mailbox is available to accept more commands.
+ * Wait for at most 1 second.
*/
static int
megaraid_busywait_mbox(mraid_device_t *raid_dev)
@@ -3032,9 +3037,9 @@ megaraid_busywait_mbox(mraid_device_t *raid_dev)
/**
* megaraid_mbox_product_info - some static information about the controller
- * @adapter - our soft state
+ * @adapter : our soft state
*
- * issue commands to the controller to grab some parameters required by our
+ * Issue commands to the controller to grab some parameters required by our
* caller.
*/
static int
@@ -3157,10 +3162,10 @@ megaraid_mbox_product_info(adapter_t *adapter)
/**
* megaraid_mbox_extended_cdb - check for support for extended CDBs
- * @adapter - soft state for the controller
+ * @adapter : soft state for the controller
*
- * this routine check whether the controller in question supports extended
- * ( > 10 bytes ) CDBs
+ * This routine check whether the controller in question supports extended
+ * ( > 10 bytes ) CDBs.
*/
static int
megaraid_mbox_extended_cdb(adapter_t *adapter)
@@ -3193,8 +3198,8 @@ megaraid_mbox_extended_cdb(adapter_t *adapter)
/**
* megaraid_mbox_support_ha - Do we support clustering
- * @adapter - soft state for the controller
- * @init_id - ID of the initiator
+ * @adapter : soft state for the controller
+ * @init_id : ID of the initiator
*
* Determine if the firmware supports clustering and the ID of the initiator.
*/
@@ -3236,9 +3241,9 @@ megaraid_mbox_support_ha(adapter_t *adapter, uint16_t *init_id)
/**
* megaraid_mbox_support_random_del - Do we support random deletion
- * @adapter - soft state for the controller
+ * @adapter : soft state for the controller
*
- * Determine if the firmware supports random deletion
+ * Determine if the firmware supports random deletion.
* Return: 1 is operation supported, 0 otherwise
*/
static int
@@ -3271,10 +3276,10 @@ megaraid_mbox_support_random_del(adapter_t *adapter)
/**
* megaraid_mbox_get_max_sg - maximum sg elements supported by the firmware
- * @adapter - soft state for the controller
+ * @adapter : soft state for the controller
*
* Find out the maximum number of scatter-gather elements supported by the
- * firmware
+ * firmware.
*/
static int
megaraid_mbox_get_max_sg(adapter_t *adapter)
@@ -3311,10 +3316,10 @@ megaraid_mbox_get_max_sg(adapter_t *adapter)
/**
* megaraid_mbox_enum_raid_scsi - enumerate the RAID and SCSI channels
- * @adapter - soft state for the controller
+ * @adapter : soft state for the controller
*
- * Enumerate the RAID and SCSI channels for ROMB platoforms so that channels
- * can be exported as regular SCSI channels
+ * Enumerate the RAID and SCSI channels for ROMB platforms so that channels
+ * can be exported as regular SCSI channels.
*/
static void
megaraid_mbox_enum_raid_scsi(adapter_t *adapter)
@@ -3348,9 +3353,9 @@ megaraid_mbox_enum_raid_scsi(adapter_t *adapter)
/**
* megaraid_mbox_flush_cache - flush adapter and disks cache
- * @param adapter : soft state for the controller
+ * @adapter : soft state for the controller
*
- * Flush adapter cache followed by disks cache
+ * Flush adapter cache followed by disks cache.
*/
static void
megaraid_mbox_flush_cache(adapter_t *adapter)
@@ -3380,13 +3385,91 @@ megaraid_mbox_flush_cache(adapter_t *adapter)
/**
+ * megaraid_mbox_fire_sync_cmd - fire the sync cmd
+ * @adapter : soft state for the controller
+ *
+ * Clears the pending cmds in FW and reinits its RAID structs.
+ */
+static int
+megaraid_mbox_fire_sync_cmd(adapter_t *adapter)
+{
+ mbox_t *mbox;
+ uint8_t raw_mbox[sizeof(mbox_t)];
+ mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter);
+ mbox64_t *mbox64;
+ int status = 0;
+ int i;
+ uint32_t dword;
+
+ mbox = (mbox_t *)raw_mbox;
+
+ memset((caddr_t)raw_mbox, 0, sizeof(mbox_t));
+
+ raw_mbox[0] = 0xFF;
+
+ mbox64 = raid_dev->mbox64;
+ mbox = raid_dev->mbox;
+
+ /* Wait until mailbox is free */
+ if (megaraid_busywait_mbox(raid_dev) != 0) {
+ status = 1;
+ goto blocked_mailbox;
+ }
+
+ /* Copy mailbox data into host structure */
+ memcpy((caddr_t)mbox, (caddr_t)raw_mbox, 16);
+ mbox->cmdid = 0xFE;
+ mbox->busy = 1;
+ mbox->poll = 0;
+ mbox->ack = 0;
+ mbox->numstatus = 0;
+ mbox->status = 0;
+
+ wmb();
+ WRINDOOR(raid_dev, raid_dev->mbox_dma | 0x1);
+
+ /* Wait for maximum 1 min for status to post.
+ * If the Firmware SUPPORTS the ABOVE COMMAND,
+ * mbox->cmd will be set to 0
+ * else
+ * the firmware will reject the command with
+ * mbox->numstatus set to 1
+ */
+
+ i = 0;
+ status = 0;
+ while (!mbox->numstatus && mbox->cmd == 0xFF) {
+ rmb();
+ msleep(1);
+ i++;
+ if (i > 1000 * 60) {
+ status = 1;
+ break;
+ }
+ }
+ if (mbox->numstatus == 1)
+ status = 1; /*cmd not supported*/
+
+ /* Check for interrupt line */
+ dword = RDOUTDOOR(raid_dev);
+ WROUTDOOR(raid_dev, dword);
+ WRINDOOR(raid_dev,2);
+
+ return status;
+
+blocked_mailbox:
+ con_log(CL_ANN, (KERN_WARNING "megaraid: blocked mailbox\n"));
+ return status;
+}
+
+/**
* megaraid_mbox_display_scb - display SCB information, mostly debug purposes
- * @param adapter : controllers' soft state
- * @param scb : SCB to be displayed
- * @param level : debug level for console print
+ * @adapter : controller's soft state
+ * @scb : SCB to be displayed
+ * @level : debug level for console print
*
* Diplay information about the given SCB iff the current debug level is
- * verbose
+ * verbose.
*/
static void
megaraid_mbox_display_scb(adapter_t *adapter, scb_t *scb)
@@ -3434,7 +3517,7 @@ megaraid_mbox_display_scb(adapter_t *adapter, scb_t *scb)
* scsi addresses and megaraid scsi and logical drive addresses. We export
* scsi devices on their actual addresses, whereas the logical drives are
* exported on a virtual scsi channel.
- **/
+ */
static void
megaraid_mbox_setup_device_map(adapter_t *adapter)
{
@@ -3472,7 +3555,7 @@ megaraid_mbox_setup_device_map(adapter_t *adapter)
/**
* megaraid_cmm_register - register with the mangement module
- * @param adapter : HBA soft state
+ * @adapter : HBA soft state
*
* Register with the management module, which allows applications to issue
* ioctl calls to the drivers. This interface is used by the management module
@@ -3562,11 +3645,11 @@ megaraid_cmm_register(adapter_t *adapter)
/**
* megaraid_cmm_unregister - un-register with the mangement module
- * @param adapter : HBA soft state
+ * @adapter : HBA soft state
*
* Un-register with the management module.
* FIXME: mgmt module must return failure for unregister if it has pending
- * commands in LLD
+ * commands in LLD.
*/
static int
megaraid_cmm_unregister(adapter_t *adapter)
@@ -3579,9 +3662,9 @@ megaraid_cmm_unregister(adapter_t *adapter)
/**
* megaraid_mbox_mm_handler - interface for CMM to issue commands to LLD
- * @param drvr_data : LLD specific data
- * @param kioc : CMM interface packet
- * @param action : command action
+ * @drvr_data : LLD specific data
+ * @kioc : CMM interface packet
+ * @action : command action
*
* This routine is invoked whenever the Common Mangement Module (CMM) has a
* command for us. The 'action' parameter specifies if this is a new command
@@ -3634,8 +3717,8 @@ megaraid_mbox_mm_handler(unsigned long drvr_data, uioc_t *kioc, uint32_t action)
/**
* megaraid_mbox_mm_command - issues commands routed through CMM
- * @param adapter : HBA soft state
- * @param kioc : management command packet
+ * @adapter : HBA soft state
+ * @kioc : management command packet
*
* Issues commands, which are routed through the management module.
*/
@@ -3804,8 +3887,8 @@ megaraid_mbox_mm_done(adapter_t *adapter, scb_t *scb)
/**
* gather_hbainfo - HBA characteristics for the applications
- * @param adapter : HBA soft state
- * @param hinfo : pointer to the caller's host info strucuture
+ * @adapter : HBA soft state
+ * @hinfo : pointer to the caller's host info strucuture
*/
static int
gather_hbainfo(adapter_t *adapter, mraid_hba_info_t *hinfo)
@@ -3839,16 +3922,15 @@ gather_hbainfo(adapter_t *adapter, mraid_hba_info_t *hinfo)
/**
* megaraid_sysfs_alloc_resources - allocate sysfs related resources
+ * @adapter : controller's soft state
*
* Allocate packets required to issue FW calls whenever the sysfs attributes
* are read. These attributes would require up-to-date information from the
* FW. Also set up resources for mutual exclusion to share these resources and
* the wait queue.
*
- * @param adapter : controller's soft state
- *
- * @return 0 on success
- * @return -ERROR_CODE on failure
+ * Return 0 on success.
+ * Return -ERROR_CODE on failure.
*/
static int
megaraid_sysfs_alloc_resources(adapter_t *adapter)
@@ -3885,10 +3967,9 @@ megaraid_sysfs_alloc_resources(adapter_t *adapter)
/**
* megaraid_sysfs_free_resources - free sysfs related resources
+ * @adapter : controller's soft state
*
* Free packets allocated for sysfs FW commands
- *
- * @param adapter : controller's soft state
*/
static void
megaraid_sysfs_free_resources(adapter_t *adapter)
@@ -3907,10 +3988,9 @@ megaraid_sysfs_free_resources(adapter_t *adapter)
/**
* megaraid_sysfs_get_ldmap_done - callback for get ldmap
+ * @uioc : completed packet
*
* Callback routine called in the ISR/tasklet context for get ldmap call
- *
- * @param uioc : completed packet
*/
static void
megaraid_sysfs_get_ldmap_done(uioc_t *uioc)
@@ -3926,12 +4006,11 @@ megaraid_sysfs_get_ldmap_done(uioc_t *uioc)
/**
* megaraid_sysfs_get_ldmap_timeout - timeout handling for get ldmap
+ * @data : timed out packet
*
* Timeout routine to recover and return to application, in case the adapter
- * has stopped responding. A timeout of 60 seconds for this command seem like
- * a good value
- *
- * @param uioc : timed out packet
+ * has stopped responding. A timeout of 60 seconds for this command seems like
+ * a good value.
*/
static void
megaraid_sysfs_get_ldmap_timeout(unsigned long data)
@@ -3948,6 +4027,7 @@ megaraid_sysfs_get_ldmap_timeout(unsigned long data)
/**
* megaraid_sysfs_get_ldmap - get update logical drive map
+ * @adapter : controller's soft state
*
* This routine will be called whenever user reads the logical drive
* attributes, go get the current logical drive mapping table from the
@@ -3959,10 +4039,8 @@ megaraid_sysfs_get_ldmap_timeout(unsigned long data)
* standalone libary. For now, this should suffice since there is no other
* user of this interface.
*
- * @param adapter : controller's soft state
- *
- * @return 0 on success
- * @return -1 on failure
+ * Return 0 on success.
+ * Return -1 on failure.
*/
static int
megaraid_sysfs_get_ldmap(adapter_t *adapter)
@@ -4064,13 +4142,12 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter)
/**
* megaraid_sysfs_show_app_hndl - display application handle for this adapter
+ * @cdev : class device object representation for the host
+ * @buf : buffer to send data to
*
* Display the handle used by the applications while executing management
* tasks on the adapter. We invoke a management module API to get the adapter
* handle, since we do not interface with applications directly.
- *
- * @param cdev : class device object representation for the host
- * @param buf : buffer to send data to
*/
static ssize_t
megaraid_sysfs_show_app_hndl(struct class_device *cdev, char *buf)
@@ -4087,16 +4164,18 @@ megaraid_sysfs_show_app_hndl(struct class_device *cdev, char *buf)
/**
* megaraid_sysfs_show_ldnum - display the logical drive number for this device
+ * @dev : device object representation for the scsi device
+ * @attr : device attribute to show
+ * @buf : buffer to send data to
*
* Display the logical drive number for the device in question, if it a valid
- * logical drive. For physical devices, "-1" is returned
- * The logical drive number is displayed in following format
+ * logical drive. For physical devices, "-1" is returned.
+ *
+ * The logical drive number is displayed in following format:
*
* <SCSI ID> <LD NUM> <LD STICKY ID> <APP ADAPTER HANDLE>
- * <int> <int> <int> <int>
*
- * @param dev : device object representation for the scsi device
- * @param buf : buffer to send data to
+ * <int> <int> <int> <int>
*/
static ssize_t
megaraid_sysfs_show_ldnum(struct device *dev, struct device_attribute *attr, char *buf)
diff --git a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h
index 2b5a3285f799..9de803cebd4b 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.h
+++ b/drivers/scsi/megaraid/megaraid_mbox.h
@@ -21,8 +21,8 @@
#include "megaraid_ioctl.h"
-#define MEGARAID_VERSION "2.20.4.9"
-#define MEGARAID_EXT_VERSION "(Release Date: Sun Jul 16 12:27:22 EST 2006)"
+#define MEGARAID_VERSION "2.20.5.1"
+#define MEGARAID_EXT_VERSION "(Release Date: Thu Nov 16 15:32:35 EST 2006)"
/*
@@ -146,27 +146,27 @@ typedef struct {
/**
* mraid_device_t - adapter soft state structure for mailbox controllers
- * @param una_mbox64 : 64-bit mbox - unaligned
- * @param una_mbox64_dma : mbox dma addr - unaligned
- * @param mbox : 32-bit mbox - aligned
- * @param mbox64 : 64-bit mbox - aligned
- * @param mbox_dma : mbox dma addr - aligned
- * @param mailbox_lock : exclusion lock for the mailbox
- * @param baseport : base port of hba memory
- * @param baseaddr : mapped addr of hba memory
- * @param mbox_pool : pool of mailboxes
- * @param mbox_pool_handle : handle for the mailbox pool memory
- * @param epthru_pool : a pool for extended passthru commands
- * @param epthru_pool_handle : handle to the pool above
- * @param sg_pool : pool of scatter-gather lists for this driver
- * @param sg_pool_handle : handle to the pool above
- * @param ccb_list : list of our command control blocks
- * @param uccb_list : list of cmd control blocks for mgmt module
- * @param umbox64 : array of mailbox for user commands (cmm)
- * @param pdrv_state : array for state of each physical drive.
- * @param last_disp : flag used to show device scanning
- * @param hw_error : set if FW not responding
- * @param fast_load : If set, skip physical device scanning
+ * @una_mbox64 : 64-bit mbox - unaligned
+ * @una_mbox64_dma : mbox dma addr - unaligned
+ * @mbox : 32-bit mbox - aligned
+ * @mbox64 : 64-bit mbox - aligned
+ * @mbox_dma : mbox dma addr - aligned
+ * @mailbox_lock : exclusion lock for the mailbox
+ * @baseport : base port of hba memory
+ * @baseaddr : mapped addr of hba memory
+ * @mbox_pool : pool of mailboxes
+ * @mbox_pool_handle : handle for the mailbox pool memory
+ * @epthru_pool : a pool for extended passthru commands
+ * @epthru_pool_handle : handle to the pool above
+ * @sg_pool : pool of scatter-gather lists for this driver
+ * @sg_pool_handle : handle to the pool above
+ * @ccb_list : list of our command control blocks
+ * @uccb_list : list of cmd control blocks for mgmt module
+ * @umbox64 : array of mailbox for user commands (cmm)
+ * @pdrv_state : array for state of each physical drive.
+ * @last_disp : flag used to show device scanning
+ * @hw_error : set if FW not responding
+ * @fast_load : If set, skip physical device scanning
* @channel_class : channel class, RAID or SCSI
* @sysfs_sem : semaphore to serialize access to sysfs res.
* @sysfs_uioc : management packet to issue FW calls from sysfs
diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c
index d85b9a8f1b8d..f33a678f0897 100644
--- a/drivers/scsi/megaraid/megaraid_mm.c
+++ b/drivers/scsi/megaraid/megaraid_mm.c
@@ -67,7 +67,7 @@ static struct list_head adapters_list_g;
static wait_queue_head_t wait_q;
-static struct file_operations lsi_fops = {
+static const struct file_operations lsi_fops = {
.open = mraid_mm_open,
.ioctl = mraid_mm_ioctl,
#ifdef CONFIG_COMPAT
@@ -78,10 +78,10 @@ static struct file_operations lsi_fops = {
/**
* mraid_mm_open - open routine for char node interface
- * @inod : unused
+ * @inode : unused
* @filep : unused
*
- * allow ioctl operations by apps only if they superuser privilege
+ * Allow ioctl operations by apps only if they have superuser privilege.
*/
static int
mraid_mm_open(struct inode *inode, struct file *filep)
@@ -214,7 +214,9 @@ mraid_mm_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
/**
* mraid_mm_get_adapter - Returns corresponding adapters for the mimd packet
* @umimd : User space mimd_t ioctl packet
- * @adapter : pointer to the adapter (OUT)
+ * @rval : returned success/error status
+ *
+ * The function return value is a pointer to the located @adapter.
*/
static mraid_mmadp_t *
mraid_mm_get_adapter(mimd_t __user *umimd, int *rval)
@@ -252,11 +254,11 @@ mraid_mm_get_adapter(mimd_t __user *umimd, int *rval)
return adapter;
}
-/*
- * handle_drvrcmd - This routine checks if the opcode is a driver
- * cmd and if it is, handles it.
+/**
+ * handle_drvrcmd - Checks if the opcode is a driver cmd and if it is, handles it.
* @arg : packet sent by the user app
* @old_ioctl : mimd if 1; uioc otherwise
+ * @rval : pointer for command's returned value (not function status)
*/
static int
handle_drvrcmd(void __user *arg, uint8_t old_ioctl, int *rval)
@@ -322,8 +324,8 @@ old_packet:
/**
* mimd_to_kioc - Converter from old to new ioctl format
- *
* @umimd : user space old MIMD IOCTL
+ * @adp : adapter softstate
* @kioc : kernel space new format IOCTL
*
* Routine to convert MIMD interface IOCTL to new interface IOCTL packet. The
@@ -474,7 +476,6 @@ mimd_to_kioc(mimd_t __user *umimd, mraid_mmadp_t *adp, uioc_t *kioc)
/**
* mraid_mm_attch_buf - Attach a free dma buffer for required size
- *
* @adp : Adapter softstate
* @kioc : kioc that the buffer needs to be attached to
* @xferlen : required length for buffer
@@ -607,7 +608,6 @@ mraid_mm_alloc_kioc(mraid_mmadp_t *adp)
/**
* mraid_mm_dealloc_kioc - Return kioc to free pool
- *
* @adp : Adapter softstate
* @kioc : uioc_t node to be returned to free pool
*/
@@ -652,7 +652,6 @@ mraid_mm_dealloc_kioc(mraid_mmadp_t *adp, uioc_t *kioc)
/**
* lld_ioctl - Routine to issue ioctl to low level drvr
- *
* @adp : The adapter handle
* @kioc : The ioctl packet with kernel addresses
*/
@@ -705,7 +704,6 @@ lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc)
/**
* ioctl_done - callback from the low level driver
- *
* @kioc : completed ioctl packet
*/
static void
@@ -756,9 +754,8 @@ ioctl_done(uioc_t *kioc)
}
-/*
- * lld_timedout : callback from the expired timer
- *
+/**
+ * lld_timedout - callback from the expired timer
* @ptr : ioctl packet that timed out
*/
static void
@@ -776,8 +773,7 @@ lld_timedout(unsigned long ptr)
/**
- * kioc_to_mimd : Converter from new back to old format
- *
+ * kioc_to_mimd - Converter from new back to old format
* @kioc : Kernel space IOCTL packet (successfully issued)
* @mimd : User space MIMD packet
*/
@@ -855,7 +851,6 @@ kioc_to_mimd(uioc_t *kioc, mimd_t __user *mimd)
/**
* hinfo_to_cinfo - Convert new format hba info into old format
- *
* @hinfo : New format, more comprehensive adapter info
* @cinfo : Old format adapter info to support mimd_t apps
*/
@@ -878,10 +873,9 @@ hinfo_to_cinfo(mraid_hba_info_t *hinfo, mcontroller_t *cinfo)
}
-/*
- * mraid_mm_register_adp - Registration routine for low level drvrs
- *
- * @adp : Adapter objejct
+/**
+ * mraid_mm_register_adp - Registration routine for low level drivers
+ * @lld_adp : Adapter objejct
*/
int
mraid_mm_register_adp(mraid_mmadp_t *lld_adp)
@@ -1007,15 +1001,14 @@ memalloc_error:
/**
* mraid_mm_adapter_app_handle - return the application handle for this adapter
+ * @unique_id : adapter unique identifier
*
- * For the given driver data, locate the adadpter in our global list and
+ * For the given driver data, locate the adapter in our global list and
* return the corresponding handle, which is also used by applications to
* uniquely identify an adapter.
*
- * @param unique_id : adapter unique identifier
- *
- * @return adapter handle if found in the list
- * @return 0 if adapter could not be located, should never happen though
+ * Return adapter handle if found in the list.
+ * Return 0 if adapter could not be located, should never happen though.
*/
uint32_t
mraid_mm_adapter_app_handle(uint32_t unique_id)
@@ -1040,7 +1033,6 @@ mraid_mm_adapter_app_handle(uint32_t unique_id)
/**
* mraid_mm_setup_dma_pools - Set up dma buffer pools per adapter
- *
* @adp : Adapter softstate
*
* We maintain a pool of dma buffers per each adapter. Each pool has one
@@ -1093,11 +1085,11 @@ dma_pool_setup_error:
}
-/*
+/**
* mraid_mm_unregister_adp - Unregister routine for low level drivers
- * Assume no outstanding ioctls to llds.
- *
* @unique_id : UID of the adpater
+ *
+ * Assumes no outstanding ioctls to llds.
*/
int
mraid_mm_unregister_adp(uint32_t unique_id)
@@ -1131,7 +1123,6 @@ mraid_mm_unregister_adp(uint32_t unique_id)
/**
* mraid_mm_free_adp_resources - Free adapter softstate
- *
* @adp : Adapter softstate
*/
static void
@@ -1162,7 +1153,6 @@ mraid_mm_free_adp_resources(mraid_mmadp_t *adp)
/**
* mraid_mm_teardown_dma_pools - Free all per adapter dma buffers
- *
* @adp : Adapter softstate
*/
static void
@@ -1190,7 +1180,7 @@ mraid_mm_teardown_dma_pools(mraid_mmadp_t *adp)
}
/**
- * mraid_mm_init : Module entry point
+ * mraid_mm_init - Module entry point
*/
static int __init
mraid_mm_init(void)
@@ -1214,10 +1204,13 @@ mraid_mm_init(void)
}
+#ifdef CONFIG_COMPAT
/**
- * mraid_mm_compat_ioctl : 32bit to 64bit ioctl conversion routine
+ * mraid_mm_compat_ioctl - 32bit to 64bit ioctl conversion routine
+ * @filep : file operations pointer (ignored)
+ * @cmd : ioctl command
+ * @arg : user ioctl packet
*/
-#ifdef CONFIG_COMPAT
static long
mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd,
unsigned long arg)
@@ -1231,7 +1224,7 @@ mraid_mm_compat_ioctl(struct file *filep, unsigned int cmd,
#endif
/**
- * mraid_mm_exit : Module exit point
+ * mraid_mm_exit - Module exit point
*/
static void __exit
mraid_mm_exit(void)
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index b5bdd0d7a8bf..15e24fcc84f3 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -2913,7 +2913,7 @@ megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
/*
* File operations structure for management interface
*/
-static struct file_operations megasas_mgmt_fops = {
+static const struct file_operations megasas_mgmt_fops = {
.owner = THIS_MODULE,
.open = megasas_mgmt_open,
.release = megasas_mgmt_release,
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 55eddcf8eb15..cacb3ad92527 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -15,7 +15,7 @@
#ifndef LSI_MEGARAID_SAS_H
#define LSI_MEGARAID_SAS_H
-/**
+/*
* MegaRAID SAS Driver meta data
*/
#define MEGASAS_VERSION "00.00.03.05"
@@ -40,7 +40,7 @@
* "message frames"
*/
-/**
+/*
* FW posts its state in upper 4 bits of outbound_msg_0 register
*/
#define MFI_STATE_MASK 0xF0000000
@@ -58,7 +58,7 @@
#define MEGAMFI_FRAME_SIZE 64
-/**
+/*
* During FW init, clear pending cmds & reset state using inbound_msg_0
*
* ABORT : Abort all pending cmds
@@ -78,7 +78,7 @@
MFI_INIT_MFIMODE| \
MFI_INIT_ABORT
-/**
+/*
* MFI frame flags
*/
#define MFI_FRAME_POST_IN_REPLY_QUEUE 0x0000
@@ -92,12 +92,12 @@
#define MFI_FRAME_DIR_READ 0x0010
#define MFI_FRAME_DIR_BOTH 0x0018
-/**
+/*
* Definition for cmd_status
*/
#define MFI_CMD_STATUS_POLL_MODE 0xFF
-/**
+/*
* MFI command opcodes
*/
#define MFI_CMD_INIT 0x00
@@ -128,7 +128,7 @@
#define MR_DCMD_CLUSTER_RESET_ALL 0x08010100
#define MR_DCMD_CLUSTER_RESET_LD 0x08010200
-/**
+/*
* MFI command completion codes
*/
enum MFI_STAT {
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index bd6bbf61adb8..9668b73872c7 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5522,7 +5522,7 @@ __setup("osst=", osst_setup);
#endif
-static struct file_operations osst_fops = {
+static const struct file_operations osst_fops = {
.owner = THIS_MODULE,
.read = osst_read,
.write = osst_write,
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index 625ca97da52d..9102cbdf1359 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -290,7 +290,6 @@ typedef struct _nsp_hw_data {
#endif
} nsp_hw_data;
-
/****************************************************************************
*
*/
@@ -302,22 +301,13 @@ static int nsp_cs_config (struct pcmcia_device *link);
/* Linux SCSI subsystem specific functions */
static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-static int nsp_detect_old (struct scsi_host_template *sht);
-static int nsp_release_old(struct Scsi_Host *shpnt);
-#endif
static const char *nsp_info (struct Scsi_Host *shpnt);
static int nsp_proc_info (
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
struct Scsi_Host *host,
-#endif
char *buffer,
char **start,
off_t offset,
int length,
-#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
- int hostno,
-#endif
int inout);
static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
void (* done)(struct scsi_cmnd *SCpnt));
@@ -356,7 +346,6 @@ static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht);
static int __init nsp_cs_init(void);
static void __exit nsp_cs_exit(void);
-
/* Debug */
#ifdef NSP_DEBUG
static void show_command (struct scsi_cmnd *SCpnt);
@@ -401,7 +390,6 @@ enum _burst_mode {
BURST_MEM32 = 2,
};
-
/**************************************************************************
* SCSI messaage
*/
@@ -413,62 +401,8 @@ enum _burst_mode {
#define MSG_EXT_SDTR 0x01
-
-/**************************************************************************
- * Compatibility functions
- */
-
-/* for Kernel 2.4 */
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
-# define scsi_register_host(template) scsi_register_module(MODULE_SCSI_HA, template)
-# define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template)
-# define scsi_host_put(host) scsi_unregister(host)
-
-typedef void irqreturn_t;
-# define IRQ_NONE /* */
-# define IRQ_HANDLED /* */
-# define IRQ_RETVAL(x) /* */
-
-/* This is ad-hoc version of scsi_host_get_next() */
-static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host)
-{
- if (host == NULL) {
- return scsi_hostlist;
- } else {
- return host->next;
- }
-}
-
-/* This is ad-hoc version of scsi_host_hn_get() */
-static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno)
-{
- struct Scsi_Host *host;
-
- for (host = scsi_host_get_next(NULL); host != NULL;
- host = scsi_host_get_next(host)) {
- if (host->host_no == hostno) {
- break;
- }
- }
-
- return host;
-}
-
-static void cs_error(struct pcmcia_device *handle, int func, int ret)
-{
- error_info_t err = { func, ret };
- pcmcia_report_error(handle, &err);
-}
-
-/* scatter-gather table */
-# define BUFFER_ADDR (SCpnt->SCp.buffer->address)
-#endif
-
-/* for Kernel 2.6 */
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
/* scatter-gather table */
# define BUFFER_ADDR ((char *)((unsigned int)(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset))
-#endif
#endif /*__nsp_cs__*/
/* end */
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 7b18a6c7b7eb..8081b637d97e 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -140,6 +140,8 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off,
ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+
return (count);
}
@@ -653,6 +655,43 @@ qla2x00_beacon_store(struct class_device *cdev, const char *buf,
return count;
}
+static ssize_t
+qla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf)
+{
+ scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+
+ return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1],
+ ha->bios_revision[0]);
+}
+
+static ssize_t
+qla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf)
+{
+ scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+
+ return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1],
+ ha->efi_revision[0]);
+}
+
+static ssize_t
+qla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf)
+{
+ scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+
+ return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1],
+ ha->fcode_revision[0]);
+}
+
+static ssize_t
+qla2x00_optrom_fw_version_show(struct class_device *cdev, char *buf)
+{
+ scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
+
+ return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n",
+ ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2],
+ ha->fw_revision[3]);
+}
+
static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show,
NULL);
static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
@@ -669,6 +708,14 @@ static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show,
qla2x00_zio_timer_store);
static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show,
qla2x00_beacon_store);
+static CLASS_DEVICE_ATTR(optrom_bios_version, S_IRUGO,
+ qla2x00_optrom_bios_version_show, NULL);
+static CLASS_DEVICE_ATTR(optrom_efi_version, S_IRUGO,
+ qla2x00_optrom_efi_version_show, NULL);
+static CLASS_DEVICE_ATTR(optrom_fcode_version, S_IRUGO,
+ qla2x00_optrom_fcode_version_show, NULL);
+static CLASS_DEVICE_ATTR(optrom_fw_version, S_IRUGO,
+ qla2x00_optrom_fw_version_show, NULL);
struct class_device_attribute *qla2x00_host_attrs[] = {
&class_device_attr_driver_version,
@@ -683,6 +730,10 @@ struct class_device_attribute *qla2x00_host_attrs[] = {
&class_device_attr_zio,
&class_device_attr_zio_timer,
&class_device_attr_beacon,
+ &class_device_attr_optrom_bios_version,
+ &class_device_attr_optrom_efi_version,
+ &class_device_attr_optrom_fcode_version,
+ &class_device_attr_optrom_fw_version,
NULL,
};
@@ -836,21 +887,24 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
link_stat_t stat_buf;
struct fc_host_statistics *pfc_host_stat;
+ rval = QLA_FUNCTION_FAILED;
pfc_host_stat = &ha->fc_host_stat;
memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics));
if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf,
sizeof(stat_buf) / 4, mb_stat);
- } else {
+ } else if (atomic_read(&ha->loop_state) == LOOP_READY &&
+ !test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) &&
+ !test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) &&
+ !ha->dpc_active) {
+ /* Must be in a 'READY' state for statistics retrieval. */
rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf,
mb_stat);
}
- if (rval != 0) {
- qla_printk(KERN_WARNING, ha,
- "Unable to retrieve host statistics (%d).\n", mb_stat[0]);
- return pfc_host_stat;
- }
+
+ if (rval != QLA_SUCCESS)
+ goto done;
pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt;
pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt;
@@ -858,7 +912,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt;
pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt;
pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt;
-
+done:
return pfc_host_stat;
}
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 2c10130d9e03..05f4f2a378eb 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2045,6 +2045,29 @@ struct isp_operations {
uint32_t, uint32_t);
int (*write_optrom) (struct scsi_qla_host *, uint8_t *, uint32_t,
uint32_t);
+
+ int (*get_flash_version) (struct scsi_qla_host *, void *);
+};
+
+/* MSI-X Support *************************************************************/
+
+#define QLA_MSIX_CHIP_REV_24XX 3
+#define QLA_MSIX_FW_MODE(m) (((m) & (BIT_7|BIT_8|BIT_9)) >> 7)
+#define QLA_MSIX_FW_MODE_1(m) (QLA_MSIX_FW_MODE(m) == 1)
+
+#define QLA_MSIX_DEFAULT 0x00
+#define QLA_MSIX_RSP_Q 0x01
+
+#define QLA_MSIX_ENTRIES 2
+#define QLA_MIDX_DEFAULT 0
+#define QLA_MIDX_RSP_Q 1
+
+struct scsi_qla_host;
+
+struct qla_msix_entry {
+ int have_irq;
+ uint16_t msix_vector;
+ uint16_t msix_entry;
};
/*
@@ -2077,6 +2100,7 @@ typedef struct scsi_qla_host {
uint32_t enable_lip_full_login :1;
uint32_t enable_target_reset :1;
uint32_t enable_led_scheme :1;
+ uint32_t inta_enabled :1;
uint32_t msi_enabled :1;
uint32_t msix_enabled :1;
uint32_t disable_serdes :1;
@@ -2316,8 +2340,6 @@ typedef struct scsi_qla_host {
#define MBX_INTR_WAIT 2
#define MBX_UPDATE_FLASH_ACTIVE 3
- spinlock_t mbx_reg_lock; /* Mbx Cmd Register Lock */
-
struct semaphore mbx_cmd_sem; /* Serialialize mbx access */
struct semaphore mbx_intr_sem; /* Used for completion notification */
@@ -2358,6 +2380,7 @@ typedef struct scsi_qla_host {
uint8_t host_str[16];
uint32_t pci_attr;
+ uint16_t chip_revision;
uint16_t product_id[4];
@@ -2379,6 +2402,15 @@ typedef struct scsi_qla_host {
#define QLA_SREADING 1
#define QLA_SWRITING 2
+ /* PCI expansion ROM image information. */
+#define ROM_CODE_TYPE_BIOS 0
+#define ROM_CODE_TYPE_FCODE 1
+#define ROM_CODE_TYPE_EFI 3
+ uint8_t bios_revision[2];
+ uint8_t efi_revision[2];
+ uint8_t fcode_revision[16];
+ uint32_t fw_revision[4];
+
/* Needed for BEACON */
uint16_t beacon_blink_led;
uint8_t beacon_color_state;
@@ -2391,6 +2423,8 @@ typedef struct scsi_qla_host {
uint16_t zio_mode;
uint16_t zio_timer;
struct fc_host_statistics fc_host_stat;
+
+ struct qla_msix_entry msix_entries[QLA_MSIX_ENTRIES];
} scsi_qla_host_t;
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index e4dd12f4b80e..74544ae4b0e2 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -224,6 +224,9 @@ extern irqreturn_t qla24xx_intr_handler(int, void *);
extern void qla2x00_process_response_queue(struct scsi_qla_host *);
extern void qla24xx_process_response_queue(struct scsi_qla_host *);
+extern int qla2x00_request_irqs(scsi_qla_host_t *);
+extern void qla2x00_free_irqs(scsi_qla_host_t *);
+
/*
* Global Function Prototypes in qla_sup.c source file.
*/
@@ -259,6 +262,9 @@ extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t);
+extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
+extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
+
/*
* Global Function Prototypes in qla_dbg.c source file.
*/
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index b3dac26ddba3..98c01cd5e1a8 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -65,7 +65,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
ha->flags.reset_active = 0;
atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
atomic_set(&ha->loop_state, LOOP_DOWN);
- ha->device_flags = 0;
+ ha->device_flags = DFLG_NO_CABLE;
ha->dpc_flags = 0;
ha->flags.management_server_logged_in = 0;
ha->marker_needed = 0;
@@ -77,16 +77,23 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
qla_printk(KERN_INFO, ha, "Configuring PCI space...\n");
rval = ha->isp_ops.pci_config(ha);
if (rval) {
- DEBUG2(printk("scsi(%ld): Unable to configure PCI space=n",
+ DEBUG2(printk("scsi(%ld): Unable to configure PCI space.\n",
ha->host_no));
return (rval);
}
ha->isp_ops.reset_chip(ha);
+ ha->isp_ops.get_flash_version(ha, ha->request_ring);
+
qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n");
- ha->isp_ops.nvram_config(ha);
+ rval = ha->isp_ops.nvram_config(ha);
+ if (rval) {
+ DEBUG2(printk("scsi(%ld): Unable to verify NVRAM data.\n",
+ ha->host_no));
+ return rval;
+ }
if (ha->flags.disable_serdes) {
/* Mask HBA via NVRAM settings? */
@@ -293,6 +300,8 @@ qla24xx_pci_config(scsi_qla_host_t *ha)
d &= ~PCI_ROM_ADDRESS_ENABLE;
pci_write_config_dword(ha->pdev, PCI_ROM_ADDRESS, d);
+ pci_read_config_word(ha->pdev, PCI_REVISION_ID, &ha->chip_revision);
+
/* Get PCI bus information. */
spin_lock_irqsave(&ha->hardware_lock, flags);
ha->pci_attr = RD_REG_DWORD(&reg->ctrl_status);
@@ -1351,6 +1360,39 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
return(rval);
}
+static inline void
+qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *def)
+{
+ char *st, *en;
+ uint16_t index;
+
+ if (memcmp(model, BINZERO, len) != 0) {
+ strncpy(ha->model_number, model, len);
+ st = en = ha->model_number;
+ en += len - 1;
+ while (en > st) {
+ if (*en != 0x20 && *en != 0x00)
+ break;
+ *en-- = '\0';
+ }
+
+ index = (ha->pdev->subsystem_device & 0xff);
+ if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
+ index < QLA_MODEL_NAMES)
+ ha->model_desc = qla2x00_model_name[index * 2 + 1];
+ } else {
+ index = (ha->pdev->subsystem_device & 0xff);
+ if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
+ index < QLA_MODEL_NAMES) {
+ strcpy(ha->model_number,
+ qla2x00_model_name[index * 2]);
+ ha->model_desc = qla2x00_model_name[index * 2 + 1];
+ } else {
+ strcpy(ha->model_number, def);
+ }
+ }
+}
+
/*
* NVRAM configuration for ISP 2xxx
*
@@ -1367,7 +1409,6 @@ qla2x00_configure_hba(scsi_qla_host_t *ha)
int
qla2x00_nvram_config(scsi_qla_host_t *ha)
{
- int rval;
uint8_t chksum = 0;
uint16_t cnt;
uint8_t *dptr1, *dptr2;
@@ -1376,8 +1417,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
uint8_t *ptr = (uint8_t *)ha->request_ring;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
- rval = QLA_SUCCESS;
-
/* Determine NVRAM starting address. */
ha->nvram_size = sizeof(nvram_t);
ha->nvram_base = 0;
@@ -1401,55 +1440,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: "
"checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0],
nv->nvram_version);
- qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
- "invalid -- WWPN) defaults.\n");
-
- /*
- * Set default initialization control block.
- */
- memset(nv, 0, ha->nvram_size);
- nv->parameter_block_version = ICB_VERSION;
-
- if (IS_QLA23XX(ha)) {
- nv->firmware_options[0] = BIT_2 | BIT_1;
- nv->firmware_options[1] = BIT_7 | BIT_5;
- nv->add_firmware_options[0] = BIT_5;
- nv->add_firmware_options[1] = BIT_5 | BIT_4;
- nv->frame_payload_size = __constant_cpu_to_le16(2048);
- nv->special_options[1] = BIT_7;
- } else if (IS_QLA2200(ha)) {
- nv->firmware_options[0] = BIT_2 | BIT_1;
- nv->firmware_options[1] = BIT_7 | BIT_5;
- nv->add_firmware_options[0] = BIT_5;
- nv->add_firmware_options[1] = BIT_5 | BIT_4;
- nv->frame_payload_size = __constant_cpu_to_le16(1024);
- } else if (IS_QLA2100(ha)) {
- nv->firmware_options[0] = BIT_3 | BIT_1;
- nv->firmware_options[1] = BIT_5;
- nv->frame_payload_size = __constant_cpu_to_le16(1024);
- }
-
- nv->max_iocb_allocation = __constant_cpu_to_le16(256);
- nv->execution_throttle = __constant_cpu_to_le16(16);
- nv->retry_count = 8;
- nv->retry_delay = 1;
-
- nv->port_name[0] = 33;
- nv->port_name[3] = 224;
- nv->port_name[4] = 139;
-
- nv->login_timeout = 4;
-
- /*
- * Set default host adapter parameters
- */
- nv->host_p[1] = BIT_2;
- nv->reset_delay = 5;
- nv->port_down_retry_count = 8;
- nv->max_luns_per_target = __constant_cpu_to_le16(8);
- nv->link_down_timeout = 60;
-
- rval = 1;
+ return QLA_FUNCTION_FAILED;
}
#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
@@ -1489,33 +1480,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
strcpy(ha->model_number, "QLA2300");
}
} else {
- if (rval == 0 &&
- memcmp(nv->model_number, BINZERO,
- sizeof(nv->model_number)) != 0) {
- char *st, *en;
-
- strncpy(ha->model_number, nv->model_number,
- sizeof(nv->model_number));
- st = en = ha->model_number;
- en += sizeof(nv->model_number) - 1;
- while (en > st) {
- if (*en != 0x20 && *en != 0x00)
- break;
- *en-- = '\0';
- }
- } else {
- uint16_t index;
-
- index = (ha->pdev->subsystem_device & 0xff);
- if (index < QLA_MODEL_NAMES) {
- strcpy(ha->model_number,
- qla2x00_model_name[index * 2]);
- ha->model_desc =
- qla2x00_model_name[index * 2 + 1];
- } else {
- strcpy(ha->model_number, "QLA23xx");
- }
- }
+ qla2x00_set_model_info(ha, nv->model_number,
+ sizeof(nv->model_number), "QLA23xx");
}
} else if (IS_QLA2200(ha)) {
nv->firmware_options[0] |= BIT_2;
@@ -1687,11 +1653,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
}
}
- if (rval) {
- DEBUG2_3(printk(KERN_WARNING
- "scsi(%ld): NVRAM configuration failed!\n", ha->host_no));
- }
- return (rval);
+ return QLA_SUCCESS;
}
static void
@@ -3107,7 +3069,11 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
- ha->isp_ops.nvram_config(ha);
+ ha->isp_ops.get_flash_version(ha, ha->request_ring);
+
+ rval = ha->isp_ops.nvram_config(ha);
+ if (rval)
+ goto isp_abort_retry;
if (!qla2x00_restart_isp(ha)) {
clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
@@ -3137,6 +3103,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
}
}
} else { /* failed the ISP abort */
+isp_abort_retry:
ha->flags.online = 1;
if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) {
if (ha->isp_abort_cnt == 0) {
@@ -3326,7 +3293,6 @@ qla24xx_reset_adapter(scsi_qla_host_t *ha)
int
qla24xx_nvram_config(scsi_qla_host_t *ha)
{
- int rval;
struct init_cb_24xx *icb;
struct nvram_24xx *nv;
uint32_t *dptr;
@@ -3334,7 +3300,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
uint32_t chksum;
uint16_t cnt;
- rval = QLA_SUCCESS;
icb = (struct init_cb_24xx *)ha->init_cb;
nv = (struct nvram_24xx *)ha->request_ring;
@@ -3367,51 +3332,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: "
"checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0],
le16_to_cpu(nv->nvram_version));
- qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
- "invalid -- WWPN) defaults.\n");
-
- /*
- * Set default initialization control block.
- */
- memset(nv, 0, ha->nvram_size);
- nv->nvram_version = __constant_cpu_to_le16(ICB_VERSION);
- nv->version = __constant_cpu_to_le16(ICB_VERSION);
- nv->frame_payload_size = __constant_cpu_to_le16(2048);
- nv->execution_throttle = __constant_cpu_to_le16(0xFFFF);
- nv->exchange_count = __constant_cpu_to_le16(0);
- nv->hard_address = __constant_cpu_to_le16(124);
- nv->port_name[0] = 0x21;
- nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn);
- nv->port_name[2] = 0x00;
- nv->port_name[3] = 0xe0;
- nv->port_name[4] = 0x8b;
- nv->port_name[5] = 0x1c;
- nv->port_name[6] = 0x55;
- nv->port_name[7] = 0x86;
- nv->node_name[0] = 0x20;
- nv->node_name[1] = 0x00;
- nv->node_name[2] = 0x00;
- nv->node_name[3] = 0xe0;
- nv->node_name[4] = 0x8b;
- nv->node_name[5] = 0x1c;
- nv->node_name[6] = 0x55;
- nv->node_name[7] = 0x86;
- nv->login_retry_count = __constant_cpu_to_le16(8);
- nv->interrupt_delay_timer = __constant_cpu_to_le16(0);
- nv->login_timeout = __constant_cpu_to_le16(0);
- nv->firmware_options_1 =
- __constant_cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1);
- nv->firmware_options_2 = __constant_cpu_to_le32(2 << 4);
- nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12);
- nv->firmware_options_3 = __constant_cpu_to_le32(2 << 13);
- nv->host_p = __constant_cpu_to_le32(BIT_11|BIT_10);
- nv->efi_parameters = __constant_cpu_to_le32(0);
- nv->reset_delay = 5;
- nv->max_luns_per_target = __constant_cpu_to_le16(128);
- nv->port_down_retry_count = __constant_cpu_to_le16(30);
- nv->link_down_timeout = __constant_cpu_to_le16(30);
-
- rval = 1;
+ return QLA_FUNCTION_FAILED;
}
/* Reset Initialization control block */
@@ -3438,25 +3359,8 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
/*
* Setup driver NVRAM options.
*/
- if (memcmp(nv->model_name, BINZERO, sizeof(nv->model_name)) != 0) {
- char *st, *en;
- uint16_t index;
-
- strncpy(ha->model_number, nv->model_name,
- sizeof(nv->model_name));
- st = en = ha->model_number;
- en += sizeof(nv->model_name) - 1;
- while (en > st) {
- if (*en != 0x20 && *en != 0x00)
- break;
- *en-- = '\0';
- }
-
- index = (ha->pdev->subsystem_device & 0xff);
- if (index < QLA_MODEL_NAMES)
- ha->model_desc = qla2x00_model_name[index * 2 + 1];
- } else
- strcpy(ha->model_number, "QLA2462");
+ qla2x00_set_model_info(ha, nv->model_name, sizeof(nv->model_name),
+ "QLA2462");
/* Use alternate WWN? */
if (nv->host_p & __constant_cpu_to_le32(BIT_15)) {
@@ -3575,11 +3479,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha)
ha->flags.process_response_queue = 1;
}
- if (rval) {
- DEBUG2_3(printk(KERN_WARNING
- "scsi(%ld): NVRAM configuration failed!\n", ha->host_no));
- }
- return (rval);
+ return QLA_SUCCESS;
}
static int
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 39fd17b05be5..d4885616cd39 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -86,12 +86,8 @@ qla2100_intr_handler(int irq, void *dev_id)
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
- spin_lock_irqsave(&ha->mbx_reg_lock, flags);
-
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
up(&ha->mbx_intr_sem);
-
- spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
}
return (IRQ_HANDLED);
@@ -199,12 +195,8 @@ qla2300_intr_handler(int irq, void *dev_id)
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
- spin_lock_irqsave(&ha->mbx_reg_lock, flags);
-
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
up(&ha->mbx_intr_sem);
-
- spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
}
return (IRQ_HANDLED);
@@ -654,10 +646,8 @@ qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp)
fcport->last_queue_full + ql2xqfullrampup * HZ))
return;
- spin_unlock_irq(&ha->hardware_lock);
starget_for_each_device(sdev->sdev_target, fcport,
qla2x00_adjust_sdev_qdepth_up);
- spin_lock_irq(&ha->hardware_lock);
}
/**
@@ -927,10 +917,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
/* Adjust queue depth for all luns on the port. */
fcport->last_queue_full = jiffies;
- spin_unlock_irq(&ha->hardware_lock);
starget_for_each_device(cp->device->sdev_target,
fcport, qla2x00_adjust_sdev_qdepth_down);
- spin_lock_irq(&ha->hardware_lock);
break;
}
if (lscsi_status != SS_CHECK_CONDITION)
@@ -995,6 +983,22 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
if (lscsi_status != 0) {
cp->result = DID_OK << 16 | lscsi_status;
+ if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
+ DEBUG2(printk(KERN_INFO
+ "scsi(%ld): QUEUE FULL status detected "
+ "0x%x-0x%x.\n", ha->host_no, comp_status,
+ scsi_status));
+
+ /*
+ * Adjust queue depth for all luns on the
+ * port.
+ */
+ fcport->last_queue_full = jiffies;
+ starget_for_each_device(
+ cp->device->sdev_target, fcport,
+ qla2x00_adjust_sdev_qdepth_down);
+ break;
+ }
if (lscsi_status != SS_CHECK_CONDITION)
break;
@@ -1482,12 +1486,8 @@ qla24xx_intr_handler(int irq, void *dev_id)
if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
(status & MBX_INTERRUPT) && ha->flags.mbox_int) {
- spin_lock_irqsave(&ha->mbx_reg_lock, flags);
-
set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
up(&ha->mbx_intr_sem);
-
- spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
}
return IRQ_HANDLED;
@@ -1536,3 +1536,216 @@ qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
qla2x00_sp_compl(ha, sp);
}
+static irqreturn_t
+qla24xx_msix_rsp_q(int irq, void *dev_id)
+{
+ scsi_qla_host_t *ha;
+ struct device_reg_24xx __iomem *reg;
+ unsigned long flags;
+
+ ha = dev_id;
+ reg = &ha->iobase->isp24;
+
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+
+ qla24xx_process_response_queue(ha);
+
+ WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
+ RD_REG_DWORD_RELAXED(&reg->hccr);
+
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t
+qla24xx_msix_default(int irq, void *dev_id)
+{
+ scsi_qla_host_t *ha;
+ struct device_reg_24xx __iomem *reg;
+ int status;
+ unsigned long flags;
+ unsigned long iter;
+ uint32_t stat;
+ uint32_t hccr;
+ uint16_t mb[4];
+
+ ha = dev_id;
+ reg = &ha->iobase->isp24;
+ status = 0;
+
+ spin_lock_irqsave(&ha->hardware_lock, flags);
+ for (iter = 50; iter--; ) {
+ stat = RD_REG_DWORD(&reg->host_status);
+ if (stat & HSRX_RISC_PAUSED) {
+ hccr = RD_REG_DWORD(&reg->hccr);
+
+ qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
+ "Dumping firmware!\n", hccr);
+ ha->isp_ops.fw_dump(ha, 1);
+ set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+ break;
+ } else if ((stat & HSRX_RISC_INT) == 0)
+ break;
+
+ switch (stat & 0xff) {
+ case 0x1:
+ case 0x2:
+ case 0x10:
+ case 0x11:
+ qla24xx_mbx_completion(ha, MSW(stat));
+ status |= MBX_INTERRUPT;
+
+ break;
+ case 0x12:
+ mb[0] = MSW(stat);
+ mb[1] = RD_REG_WORD(&reg->mailbox1);
+ mb[2] = RD_REG_WORD(&reg->mailbox2);
+ mb[3] = RD_REG_WORD(&reg->mailbox3);
+ qla2x00_async_event(ha, mb);
+ break;
+ case 0x13:
+ qla24xx_process_response_queue(ha);
+ break;
+ default:
+ DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
+ "(%d).\n",
+ ha->host_no, stat & 0xff));
+ break;
+ }
+ WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
+ RD_REG_DWORD_RELAXED(&reg->hccr);
+ }
+ spin_unlock_irqrestore(&ha->hardware_lock, flags);
+
+ if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
+ (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
+ set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+ up(&ha->mbx_intr_sem);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/* Interrupt handling helpers. */
+
+struct qla_init_msix_entry {
+ uint16_t entry;
+ uint16_t index;
+ const char *name;
+ irqreturn_t (*handler)(int, void *);
+};
+
+static struct qla_init_msix_entry imsix_entries[QLA_MSIX_ENTRIES] = {
+ { QLA_MSIX_DEFAULT, QLA_MIDX_DEFAULT,
+ "qla2xxx (default)", qla24xx_msix_default },
+
+ { QLA_MSIX_RSP_Q, QLA_MIDX_RSP_Q,
+ "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
+};
+
+static void
+qla24xx_disable_msix(scsi_qla_host_t *ha)
+{
+ int i;
+ struct qla_msix_entry *qentry;
+
+ for (i = 0; i < QLA_MSIX_ENTRIES; i++) {
+ qentry = &ha->msix_entries[imsix_entries[i].index];
+ if (qentry->have_irq)
+ free_irq(qentry->msix_vector, ha);
+ }
+ pci_disable_msix(ha->pdev);
+}
+
+static int
+qla24xx_enable_msix(scsi_qla_host_t *ha)
+{
+ int i, ret;
+ struct msix_entry entries[QLA_MSIX_ENTRIES];
+ struct qla_msix_entry *qentry;
+
+ for (i = 0; i < QLA_MSIX_ENTRIES; i++)
+ entries[i].entry = imsix_entries[i].entry;
+
+ ret = pci_enable_msix(ha->pdev, entries, ARRAY_SIZE(entries));
+ if (ret) {
+ qla_printk(KERN_WARNING, ha,
+ "MSI-X: Failed to enable support -- %d/%d\n",
+ QLA_MSIX_ENTRIES, ret);
+ goto msix_out;
+ }
+ ha->flags.msix_enabled = 1;
+
+ for (i = 0; i < QLA_MSIX_ENTRIES; i++) {
+ qentry = &ha->msix_entries[imsix_entries[i].index];
+ qentry->msix_vector = entries[i].vector;
+ qentry->msix_entry = entries[i].entry;
+ qentry->have_irq = 0;
+ ret = request_irq(qentry->msix_vector,
+ imsix_entries[i].handler, 0, imsix_entries[i].name, ha);
+ if (ret) {
+ qla_printk(KERN_WARNING, ha,
+ "MSI-X: Unable to register handler -- %x/%d.\n",
+ imsix_entries[i].index, ret);
+ qla24xx_disable_msix(ha);
+ goto msix_out;
+ }
+ qentry->have_irq = 1;
+ }
+
+msix_out:
+ return ret;
+}
+
+int
+qla2x00_request_irqs(scsi_qla_host_t *ha)
+{
+ int ret;
+
+ /* If possible, enable MSI-X. */
+ if (!IS_QLA2432(ha))
+ goto skip_msix;
+
+ if (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
+ !QLA_MSIX_FW_MODE_1(ha->fw_attributes)) {
+ DEBUG2(qla_printk(KERN_WARNING, ha,
+ "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
+ ha->chip_revision, ha->fw_attributes));
+
+ goto skip_msix;
+ }
+
+ ret = qla24xx_enable_msix(ha);
+ if (!ret) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "MSI-X: Enabled (0x%X, 0x%X).\n", ha->chip_revision,
+ ha->fw_attributes));
+ return ret;
+ }
+ qla_printk(KERN_WARNING, ha,
+ "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
+skip_msix:
+ ret = request_irq(ha->pdev->irq, ha->isp_ops.intr_handler,
+ IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha);
+ if (!ret) {
+ ha->flags.inta_enabled = 1;
+ ha->host->irq = ha->pdev->irq;
+ } else {
+ qla_printk(KERN_WARNING, ha,
+ "Failed to reserve interrupt %d already in use.\n",
+ ha->pdev->irq);
+ }
+
+ return ret;
+}
+
+void
+qla2x00_free_irqs(scsi_qla_host_t *ha)
+{
+
+ if (ha->flags.msix_enabled)
+ qla24xx_disable_msix(ha);
+ else if (ha->flags.inta_enabled)
+ free_irq(ha->host->irq, ha);
+}
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 077e5789beeb..83376f6ac3db 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -55,7 +55,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
uint16_t __iomem *optr;
uint32_t cnt;
uint32_t mboxes;
- unsigned long mbx_flags = 0;
unsigned long wait_time;
rval = QLA_SUCCESS;
@@ -81,10 +80,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
/* Save mailbox command for debug */
ha->mcp = mcp;
- /* Try to get mailbox register access */
- if (!abort_active)
- spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
-
DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n",
ha->host_no, mcp->mb[0]));
@@ -161,9 +156,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
- if (!abort_active)
- spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
-
/* Wait for either the timer to expire
* or the mbox completion interrupt
*/
@@ -184,8 +176,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
else
WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
- if (!abort_active)
- spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
while (!ha->flags.mbox_int) {
@@ -201,9 +191,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
} /* while */
}
- if (!abort_active)
- spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);
-
/* Check whether we timed out */
if (ha->flags.mbox_int) {
uint16_t *iptr2;
@@ -256,9 +243,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp)
rval = QLA_FUNCTION_TIMEOUT;
}
- if (!abort_active)
- spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags);
-
ha->flags.mbox_busy = 0;
/* Clean up */
@@ -1713,7 +1697,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
lg->entry_count = 1;
lg->nport_handle = cpu_to_le16(loop_id);
lg->control_flags =
- __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_EXPL_LOGO);
+ __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
lg->port_id[0] = al_pa;
lg->port_id[1] = area;
lg->port_id[2] = domain;
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index d6445ae841ba..68f5d24b938b 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1485,6 +1485,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->isp_ops.fw_dump = qla2100_fw_dump;
ha->isp_ops.read_optrom = qla2x00_read_optrom_data;
ha->isp_ops.write_optrom = qla2x00_write_optrom_data;
+ ha->isp_ops.get_flash_version = qla2x00_get_flash_version;
if (IS_QLA2100(ha)) {
host->max_id = MAX_TARGETS_2100;
ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
@@ -1550,6 +1551,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->isp_ops.beacon_on = qla24xx_beacon_on;
ha->isp_ops.beacon_off = qla24xx_beacon_off;
ha->isp_ops.beacon_blink = qla24xx_beacon_blink;
+ ha->isp_ops.get_flash_version = qla24xx_get_flash_version;
ha->gid_list_info_size = 8;
ha->optrom_size = OPTROM_SIZE_24XX;
}
@@ -1564,14 +1566,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
INIT_LIST_HEAD(&ha->list);
INIT_LIST_HEAD(&ha->fcports);
- /*
- * These locks are used to prevent more than one CPU
- * from modifying the queue at the same time. The
- * higher level "host_lock" will reduce most
- * contention for these locks.
- */
- spin_lock_init(&ha->mbx_reg_lock);
-
qla2x00_config_dma_addressing(ha);
if (qla2x00_mem_alloc(ha)) {
qla_printk(KERN_WARNING, ha,
@@ -1615,15 +1609,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
host->max_lun = MAX_LUNS;
host->transportt = qla2xxx_transport_template;
- ret = request_irq(pdev->irq, ha->isp_ops.intr_handler,
- IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha);
- if (ret) {
- qla_printk(KERN_WARNING, ha,
- "Failed to reserve interrupt %d already in use.\n",
- pdev->irq);
+ ret = qla2x00_request_irqs(ha);
+ if (ret)
goto probe_failed;
- }
- host->irq = pdev->irq;
/* Initialized the timer */
qla2x00_start_timer(ha, qla2x00_timer, WATCH_INTERVAL);
@@ -1753,9 +1741,7 @@ qla2x00_free_device(scsi_qla_host_t *ha)
qla2x00_mem_free(ha);
- /* Detach interrupts */
- if (ha->host->irq)
- free_irq(ha->host->irq, ha);
+ qla2x00_free_irqs(ha);
/* release io space registers */
if (ha->iobase)
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 15390ad87456..ff1dd4175a7f 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -611,7 +611,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
flash_conf_to_access_addr(0x0339),
(fdata & 0xff00) | ((fdata << 16) &
0xff0000) | ((fdata >> 16) & 0xff));
- fdata = (faddr & sec_mask) << 2;
ret = qla24xx_write_flash_dword(ha, conf_addr,
(fdata & 0xff00) |((fdata << 16) &
0xff0000) | ((fdata >> 16) & 0xff));
@@ -1383,6 +1382,29 @@ qla2x00_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
qla2x00_write_flash_byte(ha, 0x5555, 0xf0);
}
+static void
+qla2x00_read_flash_data(scsi_qla_host_t *ha, uint8_t *tmp_buf, uint32_t saddr,
+ uint32_t length)
+{
+ struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
+ uint32_t midpoint, ilength;
+ uint8_t data;
+
+ midpoint = length / 2;
+
+ WRT_REG_WORD(&reg->nvram, 0);
+ RD_REG_WORD(&reg->nvram);
+ for (ilength = 0; ilength < length; saddr++, ilength++, tmp_buf++) {
+ if (ilength == midpoint) {
+ WRT_REG_WORD(&reg->nvram, NVR_SELECT);
+ RD_REG_WORD(&reg->nvram);
+ }
+ data = qla2x00_read_flash_byte(ha, saddr);
+ if (saddr % 100)
+ udelay(10);
+ *tmp_buf = data;
+ }
+}
static inline void
qla2x00_suspend_hba(struct scsi_qla_host *ha)
@@ -1722,3 +1744,327 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf,
return rval;
}
+
+/**
+ * qla2x00_get_fcode_version() - Determine an FCODE image's version.
+ * @ha: HA context
+ * @pcids: Pointer to the FCODE PCI data structure
+ *
+ * The process of retrieving the FCODE version information is at best
+ * described as interesting.
+ *
+ * Within the first 100h bytes of the image an ASCII string is present
+ * which contains several pieces of information including the FCODE
+ * version. Unfortunately it seems the only reliable way to retrieve
+ * the version is by scanning for another sentinel within the string,
+ * the FCODE build date:
+ *
+ * ... 2.00.02 10/17/02 ...
+ *
+ * Returns QLA_SUCCESS on successful retrieval of version.
+ */
+static void
+qla2x00_get_fcode_version(scsi_qla_host_t *ha, uint32_t pcids)
+{
+ int ret = QLA_FUNCTION_FAILED;
+ uint32_t istart, iend, iter, vend;
+ uint8_t do_next, rbyte, *vbyte;
+
+ memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision));
+
+ /* Skip the PCI data structure. */
+ istart = pcids +
+ ((qla2x00_read_flash_byte(ha, pcids + 0x0B) << 8) |
+ qla2x00_read_flash_byte(ha, pcids + 0x0A));
+ iend = istart + 0x100;
+ do {
+ /* Scan for the sentinel date string...eeewww. */
+ do_next = 0;
+ iter = istart;
+ while ((iter < iend) && !do_next) {
+ iter++;
+ if (qla2x00_read_flash_byte(ha, iter) == '/') {
+ if (qla2x00_read_flash_byte(ha, iter + 2) ==
+ '/')
+ do_next++;
+ else if (qla2x00_read_flash_byte(ha,
+ iter + 3) == '/')
+ do_next++;
+ }
+ }
+ if (!do_next)
+ break;
+
+ /* Backtrack to previous ' ' (space). */
+ do_next = 0;
+ while ((iter > istart) && !do_next) {
+ iter--;
+ if (qla2x00_read_flash_byte(ha, iter) == ' ')
+ do_next++;
+ }
+ if (!do_next)
+ break;
+
+ /*
+ * Mark end of version tag, and find previous ' ' (space) or
+ * string length (recent FCODE images -- major hack ahead!!!).
+ */
+ vend = iter - 1;
+ do_next = 0;
+ while ((iter > istart) && !do_next) {
+ iter--;
+ rbyte = qla2x00_read_flash_byte(ha, iter);
+ if (rbyte == ' ' || rbyte == 0xd || rbyte == 0x10)
+ do_next++;
+ }
+ if (!do_next)
+ break;
+
+ /* Mark beginning of version tag, and copy data. */
+ iter++;
+ if ((vend - iter) &&
+ ((vend - iter) < sizeof(ha->fcode_revision))) {
+ vbyte = ha->fcode_revision;
+ while (iter <= vend) {
+ *vbyte++ = qla2x00_read_flash_byte(ha, iter);
+ iter++;
+ }
+ ret = QLA_SUCCESS;
+ }
+ } while (0);
+
+ if (ret != QLA_SUCCESS)
+ memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision));
+}
+
+int
+qla2x00_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
+{
+ int ret = QLA_SUCCESS;
+ uint8_t code_type, last_image;
+ uint32_t pcihdr, pcids;
+ uint8_t *dbyte;
+ uint16_t *dcode;
+
+ if (!ha->pio_address || !mbuf)
+ return QLA_FUNCTION_FAILED;
+
+ memset(ha->bios_revision, 0, sizeof(ha->bios_revision));
+ memset(ha->efi_revision, 0, sizeof(ha->efi_revision));
+ memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision));
+ memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
+
+ qla2x00_flash_enable(ha);
+
+ /* Begin with first PCI expansion ROM header. */
+ pcihdr = 0;
+ last_image = 1;
+ do {
+ /* Verify PCI expansion ROM header. */
+ if (qla2x00_read_flash_byte(ha, pcihdr) != 0x55 ||
+ qla2x00_read_flash_byte(ha, pcihdr + 0x01) != 0xaa) {
+ /* No signature */
+ DEBUG2(printk("scsi(%ld): No matching ROM "
+ "signature.\n", ha->host_no));
+ ret = QLA_FUNCTION_FAILED;
+ break;
+ }
+
+ /* Locate PCI data structure. */
+ pcids = pcihdr +
+ ((qla2x00_read_flash_byte(ha, pcihdr + 0x19) << 8) |
+ qla2x00_read_flash_byte(ha, pcihdr + 0x18));
+
+ /* Validate signature of PCI data structure. */
+ if (qla2x00_read_flash_byte(ha, pcids) != 'P' ||
+ qla2x00_read_flash_byte(ha, pcids + 0x1) != 'C' ||
+ qla2x00_read_flash_byte(ha, pcids + 0x2) != 'I' ||
+ qla2x00_read_flash_byte(ha, pcids + 0x3) != 'R') {
+ /* Incorrect header. */
+ DEBUG2(printk("%s(): PCI data struct not found "
+ "pcir_adr=%x.\n", __func__, pcids));
+ ret = QLA_FUNCTION_FAILED;
+ break;
+ }
+
+ /* Read version */
+ code_type = qla2x00_read_flash_byte(ha, pcids + 0x14);
+ switch (code_type) {
+ case ROM_CODE_TYPE_BIOS:
+ /* Intel x86, PC-AT compatible. */
+ ha->bios_revision[0] =
+ qla2x00_read_flash_byte(ha, pcids + 0x12);
+ ha->bios_revision[1] =
+ qla2x00_read_flash_byte(ha, pcids + 0x13);
+ DEBUG3(printk("%s(): read BIOS %d.%d.\n", __func__,
+ ha->bios_revision[1], ha->bios_revision[0]));
+ break;
+ case ROM_CODE_TYPE_FCODE:
+ /* Open Firmware standard for PCI (FCode). */
+ /* Eeeewww... */
+ qla2x00_get_fcode_version(ha, pcids);
+ break;
+ case ROM_CODE_TYPE_EFI:
+ /* Extensible Firmware Interface (EFI). */
+ ha->efi_revision[0] =
+ qla2x00_read_flash_byte(ha, pcids + 0x12);
+ ha->efi_revision[1] =
+ qla2x00_read_flash_byte(ha, pcids + 0x13);
+ DEBUG3(printk("%s(): read EFI %d.%d.\n", __func__,
+ ha->efi_revision[1], ha->efi_revision[0]));
+ break;
+ default:
+ DEBUG2(printk("%s(): Unrecognized code type %x at "
+ "pcids %x.\n", __func__, code_type, pcids));
+ break;
+ }
+
+ last_image = qla2x00_read_flash_byte(ha, pcids + 0x15) & BIT_7;
+
+ /* Locate next PCI expansion ROM. */
+ pcihdr += ((qla2x00_read_flash_byte(ha, pcids + 0x11) << 8) |
+ qla2x00_read_flash_byte(ha, pcids + 0x10)) * 512;
+ } while (!last_image);
+
+ if (IS_QLA2322(ha)) {
+ /* Read firmware image information. */
+ memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
+ dbyte = mbuf;
+ memset(dbyte, 0, 8);
+ dcode = (uint16_t *)dbyte;
+
+ qla2x00_read_flash_data(ha, dbyte, FA_RISC_CODE_ADDR * 4 + 10,
+ 8);
+ DEBUG3(printk("%s(%ld): dumping fw ver from flash:\n",
+ __func__, ha->host_no));
+ DEBUG3(qla2x00_dump_buffer((uint8_t *)dbyte, 8));
+
+ if ((dcode[0] == 0xffff && dcode[1] == 0xffff &&
+ dcode[2] == 0xffff && dcode[3] == 0xffff) ||
+ (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
+ dcode[3] == 0)) {
+ DEBUG2(printk("%s(): Unrecognized fw revision at "
+ "%x.\n", __func__, FA_RISC_CODE_ADDR * 4));
+ } else {
+ /* values are in big endian */
+ ha->fw_revision[0] = dbyte[0] << 16 | dbyte[1];
+ ha->fw_revision[1] = dbyte[2] << 16 | dbyte[3];
+ ha->fw_revision[2] = dbyte[4] << 16 | dbyte[5];
+ }
+ }
+
+ qla2x00_flash_disable(ha);
+
+ return ret;
+}
+
+int
+qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf)
+{
+ int ret = QLA_SUCCESS;
+ uint32_t pcihdr, pcids;
+ uint32_t *dcode;
+ uint8_t *bcode;
+ uint8_t code_type, last_image;
+ int i;
+
+ if (!mbuf)
+ return QLA_FUNCTION_FAILED;
+
+ memset(ha->bios_revision, 0, sizeof(ha->bios_revision));
+ memset(ha->efi_revision, 0, sizeof(ha->efi_revision));
+ memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision));
+ memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
+
+ dcode = mbuf;
+
+ /* Begin with first PCI expansion ROM header. */
+ pcihdr = 0;
+ last_image = 1;
+ do {
+ /* Verify PCI expansion ROM header. */
+ qla24xx_read_flash_data(ha, dcode, pcihdr >> 2, 0x20);
+ bcode = mbuf + (pcihdr % 4);
+ if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa) {
+ /* No signature */
+ DEBUG2(printk("scsi(%ld): No matching ROM "
+ "signature.\n", ha->host_no));
+ ret = QLA_FUNCTION_FAILED;
+ break;
+ }
+
+ /* Locate PCI data structure. */
+ pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
+
+ qla24xx_read_flash_data(ha, dcode, pcids >> 2, 0x20);
+ bcode = mbuf + (pcihdr % 4);
+
+ /* Validate signature of PCI data structure. */
+ if (bcode[0x0] != 'P' || bcode[0x1] != 'C' ||
+ bcode[0x2] != 'I' || bcode[0x3] != 'R') {
+ /* Incorrect header. */
+ DEBUG2(printk("%s(): PCI data struct not found "
+ "pcir_adr=%x.\n", __func__, pcids));
+ ret = QLA_FUNCTION_FAILED;
+ break;
+ }
+
+ /* Read version */
+ code_type = bcode[0x14];
+ switch (code_type) {
+ case ROM_CODE_TYPE_BIOS:
+ /* Intel x86, PC-AT compatible. */
+ ha->bios_revision[0] = bcode[0x12];
+ ha->bios_revision[1] = bcode[0x13];
+ DEBUG3(printk("%s(): read BIOS %d.%d.\n", __func__,
+ ha->bios_revision[1], ha->bios_revision[0]));
+ break;
+ case ROM_CODE_TYPE_FCODE:
+ /* Open Firmware standard for PCI (FCode). */
+ ha->fcode_revision[0] = bcode[0x12];
+ ha->fcode_revision[1] = bcode[0x13];
+ DEBUG3(printk("%s(): read FCODE %d.%d.\n", __func__,
+ ha->fcode_revision[1], ha->fcode_revision[0]));
+ break;
+ case ROM_CODE_TYPE_EFI:
+ /* Extensible Firmware Interface (EFI). */
+ ha->efi_revision[0] = bcode[0x12];
+ ha->efi_revision[1] = bcode[0x13];
+ DEBUG3(printk("%s(): read EFI %d.%d.\n", __func__,
+ ha->efi_revision[1], ha->efi_revision[0]));
+ break;
+ default:
+ DEBUG2(printk("%s(): Unrecognized code type %x at "
+ "pcids %x.\n", __func__, code_type, pcids));
+ break;
+ }
+
+ last_image = bcode[0x15] & BIT_7;
+
+ /* Locate next PCI expansion ROM. */
+ pcihdr += ((bcode[0x11] << 8) | bcode[0x10]) * 512;
+ } while (!last_image);
+
+ /* Read firmware image information. */
+ memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
+ dcode = mbuf;
+
+ qla24xx_read_flash_data(ha, dcode, FA_RISC_CODE_ADDR + 4, 4);
+ for (i = 0; i < 4; i++)
+ dcode[i] = be32_to_cpu(dcode[i]);
+
+ if ((dcode[0] == 0xffffffff && dcode[1] == 0xffffffff &&
+ dcode[2] == 0xffffffff && dcode[3] == 0xffffffff) ||
+ (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
+ dcode[3] == 0)) {
+ DEBUG2(printk("%s(): Unrecognized fw version at %x.\n",
+ __func__, FA_RISC_CODE_ADDR));
+ } else {
+ ha->fw_revision[0] = dcode[0];
+ ha->fw_revision[1] = dcode[1];
+ ha->fw_revision[2] = dcode[2];
+ ha->fw_revision[3] = dcode[3];
+ }
+
+ return ret;
+}
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 459e0d6bd2b4..61347aee55ce 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.01.07-k4"
+#define QLA2XXX_VERSION "8.01.07-k5"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 1
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 24cffd98ee63..f33e2eb9f1b9 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -673,27 +673,6 @@ void __scsi_done(struct scsi_cmnd *cmd)
}
/*
- * Function: scsi_retry_command
- *
- * Purpose: Send a command back to the low level to be retried.
- *
- * Notes: This command is always executed in the context of the
- * bottom half handler, or the error handler thread. Low
- * level drivers should not become re-entrant as a result of
- * this.
- */
-int scsi_retry_command(struct scsi_cmnd *cmd)
-{
- /*
- * Zero the sense information from the last time we tried
- * this command.
- */
- memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
-
- return scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY);
-}
-
-/*
* Function: scsi_finish_command
*
* Purpose: Pass command off to upper layer for finishing of I/O
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 30ee3d72c021..5adbbeedec38 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -51,10 +51,10 @@
#include "scsi_logging.h"
#include "scsi_debug.h"
-#define SCSI_DEBUG_VERSION "1.80"
-static const char * scsi_debug_version_date = "20061018";
+#define SCSI_DEBUG_VERSION "1.81"
+static const char * scsi_debug_version_date = "20070104";
-/* Additional Sense Code (ASC) used */
+/* Additional Sense Code (ASC) */
#define NO_ADDITIONAL_SENSE 0x0
#define LOGICAL_UNIT_NOT_READY 0x4
#define UNRECOVERED_READ_ERR 0x11
@@ -65,9 +65,13 @@ static const char * scsi_debug_version_date = "20061018";
#define INVALID_FIELD_IN_PARAM_LIST 0x26
#define POWERON_RESET 0x29
#define SAVING_PARAMS_UNSUP 0x39
+#define TRANSPORT_PROBLEM 0x4b
#define THRESHOLD_EXCEEDED 0x5d
#define LOW_POWER_COND_ON 0x5e
+/* Additional Sense Code Qualifier (ASCQ) */
+#define ACK_NAK_TO 0x3
+
#define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */
/* Default values for driver parameters */
@@ -95,15 +99,20 @@ static const char * scsi_debug_version_date = "20061018";
#define SCSI_DEBUG_OPT_MEDIUM_ERR 2
#define SCSI_DEBUG_OPT_TIMEOUT 4
#define SCSI_DEBUG_OPT_RECOVERED_ERR 8
+#define SCSI_DEBUG_OPT_TRANSPORT_ERR 16
/* When "every_nth" > 0 then modulo "every_nth" commands:
* - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
* - a RECOVERED_ERROR is simulated on successful read and write
* commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
+ * - a TRANSPORT_ERROR is simulated on successful read and write
+ * commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set.
*
* When "every_nth" < 0 then after "- every_nth" commands:
* - a no response is simulated if SCSI_DEBUG_OPT_TIMEOUT is set
* - a RECOVERED_ERROR is simulated on successful read and write
* commands if SCSI_DEBUG_OPT_RECOVERED_ERR is set.
+ * - a TRANSPORT_ERROR is simulated on successful read and write
+ * commands if SCSI_DEBUG_OPT_TRANSPORT_ERR is set.
* This will continue until some other action occurs (e.g. the user
* writing a new value (other than -1 or 1) to every_nth via sysfs).
*/
@@ -315,6 +324,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
int target = SCpnt->device->id;
struct sdebug_dev_info * devip = NULL;
int inj_recovered = 0;
+ int inj_transport = 0;
int delay_override = 0;
if (done == NULL)
@@ -352,6 +362,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
return 0; /* ignore command causing timeout */
else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
inj_recovered = 1; /* to reads and writes below */
+ else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts)
+ inj_transport = 1; /* to reads and writes below */
}
if (devip->wlun) {
@@ -468,7 +480,11 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
mk_sense_buffer(devip, RECOVERED_ERROR,
THRESHOLD_EXCEEDED, 0);
errsts = check_condition_result;
- }
+ } else if (inj_transport && (0 == errsts)) {
+ mk_sense_buffer(devip, ABORTED_COMMAND,
+ TRANSPORT_PROBLEM, ACK_NAK_TO);
+ errsts = check_condition_result;
+ }
break;
case REPORT_LUNS: /* mandatory, ignore unit attention */
delay_override = 1;
@@ -531,6 +547,9 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
delay_override = 1;
errsts = check_readiness(SCpnt, 0, devip);
break;
+ case WRITE_BUFFER:
+ errsts = check_readiness(SCpnt, 1, devip);
+ break;
default:
if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
@@ -954,7 +973,9 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
int alloc_len, n, ret;
alloc_len = (cmd[3] << 8) + cmd[4];
- arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL);
+ arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC);
+ if (! arr)
+ return DID_REQUEUE << 16;
if (devip->wlun)
pq_pdt = 0x1e; /* present, wlun */
else if (scsi_debug_no_lun_0 && (0 == devip->lun))
@@ -1217,7 +1238,9 @@ static int resp_report_tgtpgs(struct scsi_cmnd * scp,
alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8)
+ cmd[9]);
- arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL);
+ arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC);
+ if (! arr)
+ return DID_REQUEUE << 16;
/*
* EVPD page 0x88 states we have two ports, one
* real and a fake port with no device connected.
@@ -1996,6 +2019,8 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp)
if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
devip = devInfoReg(sdp);
+ if (NULL == devip)
+ return 1; /* no resources, will be marked offline */
sdp->hostdata = devip;
if (sdp->host->cmd_per_lun)
scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
@@ -2044,7 +2069,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev)
}
}
if (NULL == open_devip) { /* try and make a new one */
- open_devip = kzalloc(sizeof(*open_devip),GFP_KERNEL);
+ open_devip = kzalloc(sizeof(*open_devip),GFP_ATOMIC);
if (NULL == open_devip) {
printk(KERN_ERR "%s: out of memory at line %d\n",
__FUNCTION__, __LINE__);
@@ -2388,7 +2413,7 @@ MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)");
MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)");
MODULE_PARM_DESC(num_parts, "number of partitions(def=0)");
MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)");
-MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->... (def=0)");
+MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)");
MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])");
MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)");
@@ -2943,7 +2968,6 @@ static int sdebug_add_adapter(void)
struct list_head *lh, *lh_sf;
sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL);
-
if (NULL == sdbg_host) {
printk(KERN_ERR "%s: out of memory at line %d\n",
__FUNCTION__, __LINE__);
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 2ecb6ff42444..b8edcf5b5451 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -359,6 +359,11 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
return SUCCESS;
case MEDIUM_ERROR:
+ if (sshdr.asc == 0x11 || /* UNRECOVERED READ ERR */
+ sshdr.asc == 0x13 || /* AMNF DATA FIELD */
+ sshdr.asc == 0x14) { /* RECORD NOT FOUND */
+ return SUCCESS;
+ }
return NEEDS_RETRY;
case HARDWARE_ERROR:
@@ -453,6 +458,128 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
}
/**
+ * scsi_try_host_reset - ask host adapter to reset itself
+ * @scmd: SCSI cmd to send hsot reset.
+ **/
+static int scsi_try_host_reset(struct scsi_cmnd *scmd)
+{
+ unsigned long flags;
+ int rtn;
+
+ SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
+ __FUNCTION__));
+
+ if (!scmd->device->host->hostt->eh_host_reset_handler)
+ return FAILED;
+
+ rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd);
+
+ if (rtn == SUCCESS) {
+ if (!scmd->device->host->hostt->skip_settle_delay)
+ ssleep(HOST_RESET_SETTLE_TIME);
+ spin_lock_irqsave(scmd->device->host->host_lock, flags);
+ scsi_report_bus_reset(scmd->device->host,
+ scmd_channel(scmd));
+ spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
+ }
+
+ return rtn;
+}
+
+/**
+ * scsi_try_bus_reset - ask host to perform a bus reset
+ * @scmd: SCSI cmd to send bus reset.
+ **/
+static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
+{
+ unsigned long flags;
+ int rtn;
+
+ SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
+ __FUNCTION__));
+
+ if (!scmd->device->host->hostt->eh_bus_reset_handler)
+ return FAILED;
+
+ rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);
+
+ if (rtn == SUCCESS) {
+ if (!scmd->device->host->hostt->skip_settle_delay)
+ ssleep(BUS_RESET_SETTLE_TIME);
+ spin_lock_irqsave(scmd->device->host->host_lock, flags);
+ scsi_report_bus_reset(scmd->device->host,
+ scmd_channel(scmd));
+ spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
+ }
+
+ return rtn;
+}
+
+/**
+ * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev
+ * @scmd: SCSI cmd used to send BDR
+ *
+ * Notes:
+ * There is no timeout for this operation. if this operation is
+ * unreliable for a given host, then the host itself needs to put a
+ * timer on it, and set the host back to a consistent state prior to
+ * returning.
+ **/
+static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
+{
+ int rtn;
+
+ if (!scmd->device->host->hostt->eh_device_reset_handler)
+ return FAILED;
+
+ rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
+ if (rtn == SUCCESS) {
+ scmd->device->was_reset = 1;
+ scmd->device->expecting_cc_ua = 1;
+ }
+
+ return rtn;
+}
+
+static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
+{
+ if (!scmd->device->host->hostt->eh_abort_handler)
+ return FAILED;
+
+ return scmd->device->host->hostt->eh_abort_handler(scmd);
+}
+
+/**
+ * scsi_try_to_abort_cmd - Ask host to abort a running command.
+ * @scmd: SCSI cmd to abort from Lower Level.
+ *
+ * Notes:
+ * This function will not return until the user's completion function
+ * has been called. there is no timeout on this operation. if the
+ * author of the low-level driver wishes this operation to be timed,
+ * they can provide this facility themselves. helper functions in
+ * scsi_error.c can be supplied to make this easier to do.
+ **/
+static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
+{
+ /*
+ * scsi_done was called just after the command timed out and before
+ * we had a chance to process it. (db)
+ */
+ if (scmd->serial_number == 0)
+ return SUCCESS;
+ return __scsi_try_to_abort_cmd(scmd);
+}
+
+static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
+{
+ if (__scsi_try_to_abort_cmd(scmd) != SUCCESS)
+ if (scsi_try_bus_device_reset(scmd) != SUCCESS)
+ if (scsi_try_bus_reset(scmd) != SUCCESS)
+ scsi_try_host_reset(scmd);
+}
+
+/**
* scsi_send_eh_cmnd - submit a scsi command as part of error recory
* @scmd: SCSI command structure to hijack
* @cmnd: CDB to send
@@ -579,13 +706,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
break;
}
} else {
- /*
- * FIXME(eric) - we are not tracking whether we could
- * abort a timed out command or not. not sure how
- * we should treat them differently anyways.
- */
- if (shost->hostt->eh_abort_handler)
- shost->hostt->eh_abort_handler(scmd);
+ scsi_abort_eh_cmnd(scmd);
rtn = FAILED;
}
@@ -672,8 +793,8 @@ EXPORT_SYMBOL(scsi_eh_finish_cmd);
* XXX: Long term this code should go away, but that needs an audit of
* all LLDDs first.
**/
-static int scsi_eh_get_sense(struct list_head *work_q,
- struct list_head *done_q)
+int scsi_eh_get_sense(struct list_head *work_q,
+ struct list_head *done_q)
{
struct scsi_cmnd *scmd, *next;
int rtn;
@@ -715,31 +836,7 @@ static int scsi_eh_get_sense(struct list_head *work_q,
return list_empty(work_q);
}
-
-/**
- * scsi_try_to_abort_cmd - Ask host to abort a running command.
- * @scmd: SCSI cmd to abort from Lower Level.
- *
- * Notes:
- * This function will not return until the user's completion function
- * has been called. there is no timeout on this operation. if the
- * author of the low-level driver wishes this operation to be timed,
- * they can provide this facility themselves. helper functions in
- * scsi_error.c can be supplied to make this easier to do.
- **/
-static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd)
-{
- if (!scmd->device->host->hostt->eh_abort_handler)
- return FAILED;
-
- /*
- * scsi_done was called just after the command timed out and before
- * we had a chance to process it. (db)
- */
- if (scmd->serial_number == 0)
- return SUCCESS;
- return scmd->device->host->hostt->eh_abort_handler(scmd);
-}
+EXPORT_SYMBOL_GPL(scsi_eh_get_sense);
/**
* scsi_eh_tur - Send TUR to device.
@@ -815,32 +912,6 @@ static int scsi_eh_abort_cmds(struct list_head *work_q,
}
/**
- * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev
- * @scmd: SCSI cmd used to send BDR
- *
- * Notes:
- * There is no timeout for this operation. if this operation is
- * unreliable for a given host, then the host itself needs to put a
- * timer on it, and set the host back to a consistent state prior to
- * returning.
- **/
-static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
-{
- int rtn;
-
- if (!scmd->device->host->hostt->eh_device_reset_handler)
- return FAILED;
-
- rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd);
- if (rtn == SUCCESS) {
- scmd->device->was_reset = 1;
- scmd->device->expecting_cc_ua = 1;
- }
-
- return rtn;
-}
-
-/**
* scsi_eh_try_stu - Send START_UNIT to device.
* @scmd: Scsi cmd to send START_UNIT
*
@@ -971,64 +1042,6 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
}
/**
- * scsi_try_bus_reset - ask host to perform a bus reset
- * @scmd: SCSI cmd to send bus reset.
- **/
-static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
-{
- unsigned long flags;
- int rtn;
-
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Bus RST\n",
- __FUNCTION__));
-
- if (!scmd->device->host->hostt->eh_bus_reset_handler)
- return FAILED;
-
- rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);
-
- if (rtn == SUCCESS) {
- if (!scmd->device->host->hostt->skip_settle_delay)
- ssleep(BUS_RESET_SETTLE_TIME);
- spin_lock_irqsave(scmd->device->host->host_lock, flags);
- scsi_report_bus_reset(scmd->device->host,
- scmd_channel(scmd));
- spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
- }
-
- return rtn;
-}
-
-/**
- * scsi_try_host_reset - ask host adapter to reset itself
- * @scmd: SCSI cmd to send hsot reset.
- **/
-static int scsi_try_host_reset(struct scsi_cmnd *scmd)
-{
- unsigned long flags;
- int rtn;
-
- SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Snd Host RST\n",
- __FUNCTION__));
-
- if (!scmd->device->host->hostt->eh_host_reset_handler)
- return FAILED;
-
- rtn = scmd->device->host->hostt->eh_host_reset_handler(scmd);
-
- if (rtn == SUCCESS) {
- if (!scmd->device->host->hostt->skip_settle_delay)
- ssleep(HOST_RESET_SETTLE_TIME);
- spin_lock_irqsave(scmd->device->host->host_lock, flags);
- scsi_report_bus_reset(scmd->device->host,
- scmd_channel(scmd));
- spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
- }
-
- return rtn;
-}
-
-/**
* scsi_eh_bus_reset - send a bus reset
* @shost: scsi host being recovered.
* @eh_done_q: list_head for processed commands.
@@ -1411,9 +1424,9 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
* @eh_done_q: list_head for processed commands.
*
**/
-static void scsi_eh_ready_devs(struct Scsi_Host *shost,
- struct list_head *work_q,
- struct list_head *done_q)
+void scsi_eh_ready_devs(struct Scsi_Host *shost,
+ struct list_head *work_q,
+ struct list_head *done_q)
{
if (!scsi_eh_stu(shost, work_q, done_q))
if (!scsi_eh_bus_device_reset(shost, work_q, done_q))
@@ -1421,6 +1434,7 @@ static void scsi_eh_ready_devs(struct Scsi_Host *shost,
if (!scsi_eh_host_reset(work_q, done_q))
scsi_eh_offline_sdevs(work_q, done_q);
}
+EXPORT_SYMBOL_GPL(scsi_eh_ready_devs);
/**
* scsi_eh_flush_done_q - finish processed commands or retry them.
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index f02f48a882a9..9f7482d0b594 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -388,10 +388,9 @@ int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
int err = 0;
int write = (data_direction == DMA_TO_DEVICE);
- sioc = kmem_cache_alloc(scsi_io_context_cache, gfp);
+ sioc = kmem_cache_zalloc(scsi_io_context_cache, gfp);
if (!sioc)
return DRIVER_ERROR << 24;
- memset(sioc, 0, sizeof(*sioc));
req = blk_get_request(sdev->request_queue, write, gfp);
if (!req)
@@ -1400,7 +1399,7 @@ static void scsi_softirq_done(struct request *rq)
scsi_finish_command(cmd);
break;
case NEEDS_RETRY:
- scsi_retry_command(cmd);
+ scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY);
break;
case ADD_TO_MLQUEUE:
scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
@@ -2250,6 +2249,8 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
size_t sg_len = 0, len_complete = 0;
struct page *page;
+ WARN_ON(!irqs_disabled());
+
for (i = 0; i < sg_count; i++) {
len_complete = sg_len; /* Complete sg-entries */
sg_len += sg[i].length;
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index f458c2f686d2..ee8efe849bf4 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -28,7 +28,6 @@ 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);
#ifdef CONFIG_SCSI_LOGGING
void scsi_log_send(struct scsi_cmnd *cmd);
void scsi_log_completion(struct scsi_cmnd *cmd, int disposition);
@@ -58,6 +57,11 @@ extern int scsi_error_handler(void *host);
extern int scsi_decide_disposition(struct scsi_cmnd *cmd);
extern void scsi_eh_wakeup(struct Scsi_Host *shost);
extern int scsi_eh_scmd_add(struct scsi_cmnd *, int);
+void scsi_eh_ready_devs(struct Scsi_Host *shost,
+ struct list_head *work_q,
+ struct list_head *done_q);
+int scsi_eh_get_sense(struct list_head *work_q,
+ struct list_head *done_q);
/* scsi_lib.c */
extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
index 524a5f7a5193..69d6e9b198c4 100644
--- a/drivers/scsi/scsi_proc.c
+++ b/drivers/scsi/scsi_proc.c
@@ -308,7 +308,7 @@ static int proc_scsi_open(struct inode *inode, struct file *file)
return single_open(file, proc_scsi_show, NULL);
}
-static struct file_operations proc_scsi_operations = {
+static const struct file_operations proc_scsi_operations = {
.open = proc_scsi_open,
.read = seq_read,
.write = proc_scsi_write,
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 96b7cbd746a8..a43b9ec3aefd 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1029,7 +1029,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
sdev_printk(KERN_INFO, sdev,
"scsi scan: consider passing scsi_mod."
- "dev_flags=%s:%s:0x240 or 0x800240\n",
+ "dev_flags=%s:%s:0x240 or 0x1000240\n",
scsi_inq_str(vend, result, 8, 16),
scsi_inq_str(mod, result, 16, 32));
});
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c
index 37bbfbdb870f..f2344ab8deff 100644
--- a/drivers/scsi/scsi_tgt_if.c
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -280,7 +280,7 @@ static int tgt_open(struct inode *inode, struct file *file)
return 0;
}
-static struct file_operations tgt_fops = {
+static const struct file_operations tgt_fops = {
.owner = THIS_MODULE,
.open = tgt_open,
.poll = tgt_poll,
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 5c0b75bbfa10..6d39150e205b 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -336,6 +336,51 @@ show_sas_device_type(struct class_device *cdev, char *buf)
}
static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL);
+static ssize_t do_sas_phy_enable(struct class_device *cdev,
+ size_t count, int enable)
+{
+ struct sas_phy *phy = transport_class_to_phy(cdev);
+ struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+ struct sas_internal *i = to_sas_internal(shost->transportt);
+ int error;
+
+ error = i->f->phy_enable(phy, enable);
+ if (error)
+ return error;
+ phy->enabled = enable;
+ return count;
+};
+
+static ssize_t store_sas_phy_enable(struct class_device *cdev,
+ const char *buf, size_t count)
+{
+ if (count < 1)
+ return -EINVAL;
+
+ switch (buf[0]) {
+ case '0':
+ do_sas_phy_enable(cdev, count, 0);
+ break;
+ case '1':
+ do_sas_phy_enable(cdev, count, 1);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return count;
+}
+
+static ssize_t show_sas_phy_enable(struct class_device *cdev, char *buf)
+{
+ struct sas_phy *phy = transport_class_to_phy(cdev);
+
+ return snprintf(buf, 20, "%d", phy->enabled);
+}
+
+static CLASS_DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, show_sas_phy_enable,
+ store_sas_phy_enable);
+
static ssize_t do_sas_phy_reset(struct class_device *cdev,
size_t count, int hard_reset)
{
@@ -435,6 +480,7 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number)
return NULL;
phy->number = number;
+ phy->enabled = 1;
device_initialize(&phy->dev);
phy->dev.parent = get_device(parent);
@@ -579,8 +625,19 @@ static void sas_port_release(struct device *dev)
static void sas_port_create_link(struct sas_port *port,
struct sas_phy *phy)
{
- sysfs_create_link(&port->dev.kobj, &phy->dev.kobj, phy->dev.bus_id);
- sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port");
+ int res;
+
+ res = sysfs_create_link(&port->dev.kobj, &phy->dev.kobj,
+ phy->dev.bus_id);
+ if (res)
+ goto err;
+ res = sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port");
+ if (res)
+ goto err;
+ return;
+err:
+ printk(KERN_ERR "%s: Cannot create port links, err=%d\n",
+ __FUNCTION__, res);
}
static void sas_port_delete_link(struct sas_port *port,
@@ -818,13 +875,20 @@ EXPORT_SYMBOL(sas_port_delete_phy);
void sas_port_mark_backlink(struct sas_port *port)
{
+ int res;
struct device *parent = port->dev.parent->parent->parent;
if (port->is_backlink)
return;
port->is_backlink = 1;
- sysfs_create_link(&port->dev.kobj, &parent->kobj,
- parent->bus_id);
+ res = sysfs_create_link(&port->dev.kobj, &parent->kobj,
+ parent->bus_id);
+ if (res)
+ goto err;
+ return;
+err:
+ printk(KERN_ERR "%s: Cannot create port backlink, err=%d\n",
+ __FUNCTION__, res);
}
EXPORT_SYMBOL(sas_port_mark_backlink);
@@ -1237,7 +1301,7 @@ int sas_rphy_add(struct sas_rphy *rphy)
if (identify->device_type == SAS_END_DEVICE &&
rphy->scsi_target_id != -1) {
scsi_scan_target(&rphy->dev, 0,
- rphy->scsi_target_id, ~0, 0);
+ rphy->scsi_target_id, SCAN_WILD_CARD, 0);
}
return 0;
@@ -1253,7 +1317,7 @@ EXPORT_SYMBOL(sas_rphy_add);
* Note:
* This function must only be called on a remote
* PHY that has not sucessfully been added using
- * sas_rphy_add().
+ * sas_rphy_add() (or has been sas_rphy_remove()'d)
*/
void sas_rphy_free(struct sas_rphy *rphy)
{
@@ -1272,18 +1336,30 @@ void sas_rphy_free(struct sas_rphy *rphy)
EXPORT_SYMBOL(sas_rphy_free);
/**
- * sas_rphy_delete -- remove SAS remote PHY
- * @rphy: SAS remote PHY to remove
+ * sas_rphy_delete -- remove and free SAS remote PHY
+ * @rphy: SAS remote PHY to remove and free
*
- * Removes the specified SAS remote PHY.
+ * Removes the specified SAS remote PHY and frees it.
*/
void
sas_rphy_delete(struct sas_rphy *rphy)
{
+ sas_rphy_remove(rphy);
+ sas_rphy_free(rphy);
+}
+EXPORT_SYMBOL(sas_rphy_delete);
+
+/**
+ * sas_rphy_remove -- remove SAS remote PHY
+ * @rphy: SAS remote phy to remove
+ *
+ * Removes the specified SAS remote PHY.
+ */
+void
+sas_rphy_remove(struct sas_rphy *rphy)
+{
struct device *dev = &rphy->dev;
struct sas_port *parent = dev_to_sas_port(dev->parent);
- struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
- struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
switch (rphy->identify.device_type) {
case SAS_END_DEVICE:
@@ -1299,17 +1375,10 @@ sas_rphy_delete(struct sas_rphy *rphy)
transport_remove_device(dev);
device_del(dev);
- transport_destroy_device(dev);
-
- mutex_lock(&sas_host->lock);
- list_del(&rphy->list);
- mutex_unlock(&sas_host->lock);
parent->rphy = NULL;
-
- put_device(dev);
}
-EXPORT_SYMBOL(sas_rphy_delete);
+EXPORT_SYMBOL(sas_rphy_remove);
/**
* scsi_is_sas_rphy -- check if a struct device represents a SAS remote PHY
@@ -1389,6 +1458,10 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel,
SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1, \
!i->f->set_phy_speed, S_IRUGO)
+#define SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(field, func) \
+ SETUP_TEMPLATE_RW(phy_attrs, field, S_IRUGO | S_IWUSR, 1, \
+ !i->f->func, S_IRUGO)
+
#define SETUP_PORT_ATTRIBUTE(field) \
SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1)
@@ -1396,10 +1469,10 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel,
SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func)
#define SETUP_PHY_ATTRIBUTE_WRONLY(field) \
- SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1)
+ SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, 1)
#define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func) \
- SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func)
+ SETUP_TEMPLATE(phy_attrs, field, S_IWUSR, i->f->func)
#define SETUP_END_DEV_ATTRIBUTE(field) \
SETUP_TEMPLATE(end_dev_attrs, field, S_IRUGO, 1)
@@ -1479,6 +1552,7 @@ sas_attach_transport(struct sas_function_template *ft)
SETUP_PHY_ATTRIBUTE(phy_reset_problem_count);
SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset);
SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset);
+ SETUP_OPTIONAL_PHY_ATTRIBUTE_RW(enable, phy_enable);
i->phy_attrs[count] = NULL;
count = 0;
@@ -1587,7 +1661,7 @@ static void __exit sas_transport_exit(void)
}
MODULE_AUTHOR("Christoph Hellwig");
-MODULE_DESCRIPTION("SAS Transphy Attributes");
+MODULE_DESCRIPTION("SAS Transport Attributes");
MODULE_LICENSE("GPL");
module_init(sas_transport_init);
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 014d7fea1ff3..6f56f8750635 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -46,7 +46,6 @@
* two cc/ua clears */
/* Private data accessors (keep these out of the header file) */
-#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending)
#define spi_dv_in_progress(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_in_progress)
#define spi_dv_mutex(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_mutex)
diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c
index 551baccec523..018c65f73ac4 100644
--- a/drivers/scsi/sim710.c
+++ b/drivers/scsi/sim710.c
@@ -123,6 +123,7 @@ sim710_probe_common(struct device *dev, unsigned long base_addr,
hostdata->differential = differential;
hostdata->clock = clock;
hostdata->chip710 = 1;
+ hostdata->burst_length = 8;
/* and register the chip */
if((host = NCR_700_detect(&sim710_driver_template, hostdata, dev))
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c
new file mode 100644
index 000000000000..6bc505115841
--- /dev/null
+++ b/drivers/scsi/sni_53c710.c
@@ -0,0 +1,159 @@
+/* -*- mode: c; c-basic-offset: 8 -*- */
+
+/* SNI RM driver
+ *
+ * Copyright (C) 2001 by James.Bottomley@HansenPartnership.com
+**-----------------------------------------------------------------------------
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+**-----------------------------------------------------------------------------
+ */
+
+/*
+ * Based on lasi700.c
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/stat.h>
+#include <linux/mm.h>
+#include <linux/blkdev.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_spi.h>
+
+#include "53c700.h"
+
+MODULE_AUTHOR("Thomas Bogendörfer");
+MODULE_DESCRIPTION("SNI RM 53c710 SCSI Driver");
+MODULE_LICENSE("GPL");
+
+#define SNIRM710_CLOCK 32
+
+static struct scsi_host_template snirm710_template = {
+ .name = "SNI RM SCSI 53c710",
+ .proc_name = "snirm_53c710",
+ .this_id = 7,
+ .module = THIS_MODULE,
+};
+
+static int __init snirm710_probe(struct platform_device *dev)
+{
+ unsigned long base;
+ struct NCR_700_Host_Parameters *hostdata;
+ struct Scsi_Host *host;
+ struct resource *res;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ base = res->start;
+ hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL);
+ if (!hostdata) {
+ printk(KERN_ERR "%s: Failed to allocate host data\n",
+ dev->dev.bus_id);
+ return -ENOMEM;
+ }
+
+ hostdata->dev = &dev->dev;
+ dma_set_mask(&dev->dev, DMA_32BIT_MASK);
+ hostdata->base = ioremap_nocache(CPHYSADDR(base), 0x100);
+ hostdata->differential = 0;
+
+ hostdata->clock = SNIRM710_CLOCK;
+ hostdata->force_le_on_be = 1;
+ hostdata->chip710 = 1;
+ hostdata->burst_length = 4;
+
+ host = NCR_700_detect(&snirm710_template, hostdata, &dev->dev);
+ if (!host)
+ goto out_kfree;
+ host->this_id = 7;
+ host->base = base;
+ host->irq = platform_get_irq(dev, 0);
+ if(request_irq(host->irq, NCR_700_intr, SA_SHIRQ, "snirm710", host)) {
+ printk(KERN_ERR "snirm710: request_irq failed!\n");
+ goto out_put_host;
+ }
+
+ dev_set_drvdata(&dev->dev, host);
+ scsi_scan_host(host);
+
+ return 0;
+
+ out_put_host:
+ scsi_host_put(host);
+ out_kfree:
+ iounmap(hostdata->base);
+ kfree(hostdata);
+ return -ENODEV;
+}
+
+static int __exit snirm710_driver_remove(struct platform_device *dev)
+{
+ struct Scsi_Host *host = dev_get_drvdata(&dev->dev);
+ struct NCR_700_Host_Parameters *hostdata =
+ (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+ scsi_remove_host(host);
+ NCR_700_release(host);
+ free_irq(host->irq, host);
+ iounmap(hostdata->base);
+ kfree(hostdata);
+
+ return 0;
+}
+
+static struct platform_driver snirm710_driver = {
+ .probe = snirm710_probe,
+ .remove = __devexit_p(snirm710_driver_remove),
+ .driver = {
+ .name = "snirm_53c710",
+ },
+};
+
+static int __init snirm710_init(void)
+{
+ int err;
+
+ if ((err = platform_driver_register(&snirm710_driver))) {
+ printk(KERN_ERR "Driver registration failed\n");
+ return err;
+ }
+ return 0;
+}
+
+static void __exit snirm710_exit(void)
+{
+ platform_driver_unregister(&snirm710_driver);
+}
+
+module_init(snirm710_init);
+module_exit(snirm710_exit);
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 488ec7948a57..3d2e02381e92 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -9,7 +9,7 @@
Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky,
Michael Schaefer, J"org Weule, and Eric Youngdale.
- Copyright 1992 - 2006 Kai Makisara
+ Copyright 1992 - 2007 Kai Makisara
email Kai.Makisara@kolumbus.fi
Some small formal changes - aeb, 950809
@@ -17,7 +17,7 @@
Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
*/
-static const char *verstr = "20061107";
+static const char *verstr = "20070203";
#include <linux/module.h>
@@ -1168,6 +1168,7 @@ static int st_open(struct inode *inode, struct file *filp)
STps = &(STp->ps[i]);
STps->rw = ST_IDLE;
}
+ STp->try_dio_now = STp->try_dio;
STp->recover_count = 0;
DEB( STp->nbr_waits = STp->nbr_finished = 0;
STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = STp->nbr_combinable = 0; )
@@ -1400,9 +1401,9 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf,
struct st_buffer *STbp = STp->buffer;
if (is_read)
- i = STp->try_dio && try_rdio;
+ i = STp->try_dio_now && try_rdio;
else
- i = STp->try_dio && try_wdio;
+ i = STp->try_dio_now && try_wdio;
if (i && ((unsigned long)buf & queue_dma_alignment(
STp->device->request_queue)) == 0) {
@@ -1599,7 +1600,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
STm->do_async_writes && STps->eof < ST_EOM_OK;
if (STp->block_size != 0 && STm->do_buffer_writes &&
- !(STp->try_dio && try_wdio) && STps->eof < ST_EOM_OK &&
+ !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK &&
STbp->buffer_bytes < STbp->buffer_size) {
STp->dirty = 1;
/* Don't write a buffer that is not full enough. */
@@ -1769,7 +1770,7 @@ static long read_tape(struct scsi_tape *STp, long count,
if (STp->block_size == 0)
blks = bytes = count;
else {
- if (!(STp->try_dio && try_rdio) && STm->do_read_ahead) {
+ if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) {
blks = (STp->buffer)->buffer_blocks;
bytes = blks * STp->block_size;
} else {
@@ -1948,10 +1949,12 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
goto out;
STm = &(STp->modes[STp->current_mode]);
- if (!(STm->do_read_ahead) && STp->block_size != 0 &&
- (count % STp->block_size) != 0) {
- retval = (-EINVAL); /* Read must be integral number of blocks */
- goto out;
+ if (STp->block_size != 0 && (count % STp->block_size) != 0) {
+ if (!STm->do_read_ahead) {
+ retval = (-EINVAL); /* Read must be integral number of blocks */
+ goto out;
+ }
+ STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */
}
STps = &(STp->ps[STp->partition]);
@@ -3861,7 +3864,7 @@ __setup("st=", st_setup);
#endif
-static struct file_operations st_fops =
+static const struct file_operations st_fops =
{
.owner = THIS_MODULE,
.read = st_read,
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index 05a5cae126ec..50f3deb1f9ed 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -117,7 +117,8 @@ struct scsi_tape {
unsigned char cln_sense_value;
unsigned char cln_sense_mask;
unsigned char use_pf; /* Set Page Format bit in all mode selects? */
- unsigned char try_dio; /* try direct i/o? */
+ unsigned char try_dio; /* try direct i/o in general? */
+ unsigned char try_dio_now; /* try direct i/o before next close? */
unsigned char c_algo; /* compression algorithm */
unsigned char pos_unknown; /* after reset position unknown */
int tape_type;
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 5261f0af8b10..2964ca9df5a0 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -920,12 +920,16 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
#ifdef __i386__
outb(0xff, 0x080);
#endif
- scratch2 = serial_inp(up, UART_IER);
+ /*
+ * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
+ * 16C754B) allow only to modify them if an EFR bit is set.
+ */
+ scratch2 = serial_inp(up, UART_IER) & 0x0f;
serial_outp(up, UART_IER, 0x0F);
#ifdef __i386__
outb(0, 0x080);
#endif
- scratch3 = serial_inp(up, UART_IER);
+ scratch3 = serial_inp(up, UART_IER) & 0x0f;
serial_outp(up, UART_IER, scratch);
if (scratch2 != 0 || scratch3 != 0x0F) {
/*
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 52e2e64c6649..a2dac378bda9 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -679,6 +679,13 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
*/
{
.vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9030,
+ .subvendor = PCI_SUBVENDOR_ID_PERLE,
+ .subdevice = PCI_ANY_ID,
+ .setup = pci_default_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
.device = PCI_DEVICE_ID_PLX_9050,
.subvendor = PCI_SUBVENDOR_ID_EXSYS,
.subdevice = PCI_SUBDEVICE_ID_EXSYS_4055,
@@ -936,6 +943,7 @@ enum pci_board_num_t {
pbn_b2_1_115200,
pbn_b2_2_115200,
+ pbn_b2_4_115200,
pbn_b2_8_115200,
pbn_b2_1_460800,
@@ -1249,6 +1257,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 115200,
.uart_offset = 8,
},
+ [pbn_b2_4_115200] = {
+ .flags = FL_BASE2,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
[pbn_b2_8_115200] = {
.flags = FL_BASE2,
.num_ports = 8,
@@ -1990,6 +2004,10 @@ static struct pci_device_id serial_pci_tbl[] = {
{ PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
pbn_panacom2 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ PCI_VENDOR_ID_ESDGMBH,
+ PCI_DEVICE_ID_ESDGMBH_CPCIASIO4, 0, 0,
+ pbn_b2_4_115200 },
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_SUBVENDOR_ID_CHASE_PCIFAST,
PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0,
@@ -2379,6 +2397,15 @@ static struct pci_device_id serial_pci_tbl[] = {
pbn_b2_2_115200 },
/*
+ * Perle PCI-RAS cards
+ */
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS4,
+ 0, 0, pbn_b2_4_921600 },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8,
+ 0, 0, pbn_b2_8_921600 },
+ /*
* These entries match devices with class COMMUNICATION_SERIAL,
* COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL
*/
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 2978c09860ee..5cc6b91f8408 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -916,6 +916,11 @@ config SERIAL_TXX9
config HAS_TXX9_SERIAL
bool
+config SERIAL_TXX9_NR_UARTS
+ int "Maximum number of TMPTX39XX/49XX SIO ports"
+ depends on SERIAL_TXX9
+ default "6"
+
config SERIAL_TXX9_CONSOLE
bool "TMPTX39XX/49XX SIO Console support"
depends on SERIAL_TXX9=y
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 881f886b91c6..df45a7ac773f 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -73,35 +73,35 @@
#define ATMEL_ISR_PASS_LIMIT 256
-#define UART_PUT_CR(port,v) writel(v, (port)->membase + ATMEL_US_CR)
-#define UART_GET_MR(port) readl((port)->membase + ATMEL_US_MR)
-#define UART_PUT_MR(port,v) writel(v, (port)->membase + ATMEL_US_MR)
-#define UART_PUT_IER(port,v) writel(v, (port)->membase + ATMEL_US_IER)
-#define UART_PUT_IDR(port,v) writel(v, (port)->membase + ATMEL_US_IDR)
-#define UART_GET_IMR(port) readl((port)->membase + ATMEL_US_IMR)
-#define UART_GET_CSR(port) readl((port)->membase + ATMEL_US_CSR)
-#define UART_GET_CHAR(port) readl((port)->membase + ATMEL_US_RHR)
-#define UART_PUT_CHAR(port,v) writel(v, (port)->membase + ATMEL_US_THR)
-#define UART_GET_BRGR(port) readl((port)->membase + ATMEL_US_BRGR)
-#define UART_PUT_BRGR(port,v) writel(v, (port)->membase + ATMEL_US_BRGR)
-#define UART_PUT_RTOR(port,v) writel(v, (port)->membase + ATMEL_US_RTOR)
-
-// #define UART_GET_CR(port) readl((port)->membase + ATMEL_US_CR) // is write-only
+#define UART_PUT_CR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_CR)
+#define UART_GET_MR(port) __raw_readl((port)->membase + ATMEL_US_MR)
+#define UART_PUT_MR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_MR)
+#define UART_PUT_IER(port,v) __raw_writel(v, (port)->membase + ATMEL_US_IER)
+#define UART_PUT_IDR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_IDR)
+#define UART_GET_IMR(port) __raw_readl((port)->membase + ATMEL_US_IMR)
+#define UART_GET_CSR(port) __raw_readl((port)->membase + ATMEL_US_CSR)
+#define UART_GET_CHAR(port) __raw_readl((port)->membase + ATMEL_US_RHR)
+#define UART_PUT_CHAR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_THR)
+#define UART_GET_BRGR(port) __raw_readl((port)->membase + ATMEL_US_BRGR)
+#define UART_PUT_BRGR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_BRGR)
+#define UART_PUT_RTOR(port,v) __raw_writel(v, (port)->membase + ATMEL_US_RTOR)
+
+// #define UART_GET_CR(port) __raw_readl((port)->membase + ATMEL_US_CR) // is write-only
/* PDC registers */
-#define UART_PUT_PTCR(port,v) writel(v, (port)->membase + ATMEL_PDC_PTCR)
-#define UART_GET_PTSR(port) readl((port)->membase + ATMEL_PDC_PTSR)
-
-#define UART_PUT_RPR(port,v) writel(v, (port)->membase + ATMEL_PDC_RPR)
-#define UART_GET_RPR(port) readl((port)->membase + ATMEL_PDC_RPR)
-#define UART_PUT_RCR(port,v) writel(v, (port)->membase + ATMEL_PDC_RCR)
-#define UART_PUT_RNPR(port,v) writel(v, (port)->membase + ATMEL_PDC_RNPR)
-#define UART_PUT_RNCR(port,v) writel(v, (port)->membase + ATMEL_PDC_RNCR)
-
-#define UART_PUT_TPR(port,v) writel(v, (port)->membase + ATMEL_PDC_TPR)
-#define UART_PUT_TCR(port,v) writel(v, (port)->membase + ATMEL_PDC_TCR)
-//#define UART_PUT_TNPR(port,v) writel(v, (port)->membase + ATMEL_PDC_TNPR)
-//#define UART_PUT_TNCR(port,v) writel(v, (port)->membase + ATMEL_PDC_TNCR)
+#define UART_PUT_PTCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_PTCR)
+#define UART_GET_PTSR(port) __raw_readl((port)->membase + ATMEL_PDC_PTSR)
+
+#define UART_PUT_RPR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_RPR)
+#define UART_GET_RPR(port) __raw_readl((port)->membase + ATMEL_PDC_RPR)
+#define UART_PUT_RCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_RCR)
+#define UART_PUT_RNPR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_RNPR)
+#define UART_PUT_RNCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_RNCR)
+
+#define UART_PUT_TPR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TPR)
+#define UART_PUT_TCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TCR)
+//#define UART_PUT_TNPR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TNPR)
+//#define UART_PUT_TNCR(port,v) __raw_writel(v, (port)->membase + ATMEL_PDC_TNCR)
static int (*atmel_open_hook)(struct uart_port *);
static void (*atmel_close_hook)(struct uart_port *);
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 42b050c46abe..312bef6bd583 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -3173,12 +3173,8 @@ do_softint(void *private_)
if (!tty)
return;
- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
- wake_up_interruptible(&tty->write_wait);
- }
+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event))
+ tty_wakeup(tty);
}
static int
@@ -3798,11 +3794,7 @@ rs_flush_buffer(struct tty_struct *tty)
info->xmit.head = info->xmit.tail = 0;
restore_flags(flags);
- wake_up_interruptible(&tty->write_wait);
-
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
+ tty_wakeup(tty);
}
/*
diff --git a/drivers/serial/ioc4_serial.c b/drivers/serial/ioc4_serial.c
index c862f67c985a..f540212e7409 100644
--- a/drivers/serial/ioc4_serial.c
+++ b/drivers/serial/ioc4_serial.c
@@ -2685,7 +2685,7 @@ static int ioc4_serial_remove_one(struct ioc4_driver_data *idd)
free_irq(control->ic_irq, soft);
if (soft->is_ioc4_serial_addr) {
iounmap(soft->is_ioc4_serial_addr);
- release_region((unsigned long)
+ release_mem_region((unsigned long)
soft->is_ioc4_serial_addr,
sizeof(struct ioc4_serial));
}
@@ -2790,7 +2790,7 @@ ioc4_serial_attach_one(struct ioc4_driver_data *idd)
/* request serial registers */
tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET;
- if (!request_region(tmp_addr1, sizeof(struct ioc4_serial),
+ if (!request_mem_region(tmp_addr1, sizeof(struct ioc4_serial),
"sioc4_uart")) {
printk(KERN_WARNING
"ioc4 (%p): unable to get request region for "
@@ -2889,7 +2889,7 @@ out3:
out2:
if (serial)
iounmap(serial);
- release_region(tmp_addr1, sizeof(struct ioc4_serial));
+ release_mem_region(tmp_addr1, sizeof(struct ioc4_serial));
out1:
return ret;
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 7186a82c4759..f4440d329310 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -37,6 +37,7 @@
* 1.06 Do not insert a char caused previous overrun.
* Fix some spin_locks.
* Do not call uart_add_one_port for absent ports.
+ * 1.07 Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup.
*/
#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -58,9 +59,8 @@
#include <linux/mutex.h>
#include <asm/io.h>
-#include <asm/irq.h>
-static char *serial_version = "1.06";
+static char *serial_version = "1.07";
static char *serial_name = "TX39/49 Serial driver";
#define PASS_LIMIT 256
@@ -88,12 +88,7 @@ static char *serial_name = "TX39/49 Serial driver";
/*
* Number of serial ports
*/
-#ifdef ENABLE_SERIAL_TXX9_PCI
-#define NR_PCI_BOARDS 4
-#define UART_NR (4 + NR_PCI_BOARDS)
-#else
-#define UART_NR 4
-#endif
+#define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS
#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
@@ -987,6 +982,7 @@ int __init early_serial_txx9_setup(struct uart_port *port)
}
#ifdef ENABLE_SERIAL_TXX9_PCI
+#ifdef CONFIG_PM
/**
* serial_txx9_suspend_port - suspend one serial port
* @line: serial line number
@@ -1008,6 +1004,7 @@ static void serial_txx9_resume_port(int line)
{
uart_resume_port(&serial_txx9_reg, &serial_txx9_ports[line].port);
}
+#endif
static DEFINE_MUTEX(serial_txx9_mutex);
@@ -1118,6 +1115,7 @@ static void __devexit pciserial_txx9_remove_one(struct pci_dev *dev)
}
}
+#ifdef CONFIG_PM
static int pciserial_txx9_suspend_one(struct pci_dev *dev, pm_message_t state)
{
int line = (int)(long)pci_get_drvdata(dev);
@@ -1142,11 +1140,10 @@ static int pciserial_txx9_resume_one(struct pci_dev *dev)
}
return 0;
}
+#endif
-static struct pci_device_id serial_txx9_pci_tbl[] = {
- { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC,
- PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0 },
+static const struct pci_device_id serial_txx9_pci_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC) },
{ 0, }
};
@@ -1154,8 +1151,10 @@ static struct pci_driver serial_txx9_pci_driver = {
.name = "serial_txx9",
.probe = pciserial_txx9_init_one,
.remove = __devexit_p(pciserial_txx9_remove_one),
+#ifdef CONFIG_PM
.suspend = pciserial_txx9_suspend_one,
.resume = pciserial_txx9_resume_one,
+#endif
.id_table = serial_txx9_pci_tbl,
};
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
index cd6b65333b71..2dd6eed50aa0 100644
--- a/drivers/sn/ioc3.c
+++ b/drivers/sn/ioc3.c
@@ -654,7 +654,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
ret = -ENODEV;
goto out_pci;
}
- if (!request_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) {
+ if (!request_mem_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) {
printk(KERN_WARNING
"%s: Unable to request IOC3 region "
"for pci_dev %s.\n",
@@ -744,7 +744,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
return 0;
out_misc_region:
- release_region(idd->pma, IOC3_PCI_SIZE);
+ release_mem_region(idd->pma, IOC3_PCI_SIZE);
out_pci:
kfree(idd);
out_idd:
@@ -785,7 +785,7 @@ static void ioc3_remove(struct pci_dev *pdev)
if(idd->dual_irq)
free_irq(idd->irq_eth, (void *)idd);
iounmap(idd->vma);
- release_region(idd->pma, IOC3_PCI_SIZE);
+ release_mem_region(idd->pma, IOC3_PCI_SIZE);
/* Disable IOC3 and relinquish */
pci_disable_device(pdev);
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index d895a1adb428..9052f4c3493b 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -75,6 +75,13 @@ config SPI_BUTTERFLY
inexpensive battery powered microcontroller evaluation board.
This same cable can be used to flash new firmware.
+config SPI_IMX
+ tristate "Freescale iMX SPI controller"
+ depends on SPI_MASTER && ARCH_IMX && EXPERIMENTAL
+ help
+ This enables using the Freescale iMX SPI controller in master
+ mode.
+
config SPI_MPC83xx
tristate "Freescale MPC83xx SPI controller"
depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL
@@ -87,6 +94,14 @@ config SPI_MPC83xx
family of PowerPC processors. The MPC83xx uses a simple set of shift
registers for data (opposed to the CPM based descriptor model).
+config SPI_OMAP_UWIRE
+ tristate "OMAP1 MicroWire"
+ depends on SPI_MASTER && ARCH_OMAP1
+ select SPI_BITBANG
+ help
+ This hooks up to the MicroWire controller on OMAP1 chips.
+
+
config SPI_PXA2XX
tristate "PXA2xx SSP SPI master"
depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
@@ -95,6 +110,12 @@ config SPI_PXA2XX
The driver can be configured to use any SSP port and additional
documentation can be found a Documentation/spi/pxa2xx.
+config SPI_S3C24XX
+ tristate "Samsung S3C24XX series SPI"
+ depends on SPI_MASTER && ARCH_S3C2410 && EXPERIMENTAL
+ help
+ SPI driver for Samsung S3C24XX series ARM SoCs
+
config SPI_S3C24XX_GPIO
tristate "Samsung S3C24XX series SPI by GPIO"
depends on SPI_MASTER && ARCH_S3C2410 && SPI_BITBANG && EXPERIMENTAL
@@ -107,13 +128,6 @@ config SPI_S3C24XX_GPIO
# Add new SPI master controllers in alphabetical order above this line
#
-
-config SPI_S3C24XX
- tristate "Samsung S3C24XX series SPI"
- depends on SPI_MASTER && ARCH_S3C2410 && EXPERIMENTAL
- help
- SPI driver for Samsung S3C24XX series ARM SoCs
-
#
# There are lots of SPI device types, with sensors and memory
# being probably the most widely used ones.
@@ -121,6 +135,16 @@ config SPI_S3C24XX
comment "SPI Protocol Masters"
depends on SPI_MASTER
+config SPI_AT25
+ tristate "SPI EEPROMs from most vendors"
+ depends on SPI_MASTER && SYSFS
+ help
+ Enable this driver to get read/write support to most SPI EEPROMs,
+ after you configure the board init code to know about each eeprom
+ on your target board.
+
+ This driver can also be built as a module. If so, the module
+ will be called at25.
#
# Add new SPI protocol masters in alphabetical order above this line
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 8f4cb67997b3..bf271fe4e536 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -13,13 +13,16 @@ obj-$(CONFIG_SPI_MASTER) += spi.o
# SPI master controller drivers (bus)
obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
+obj-$(CONFIG_SPI_IMX) += spi_imx.o
obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
+obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o
obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o
obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
# ... add above this line ...
# SPI protocol drivers (device/link on bus)
+obj-$(CONFIG_SPI_AT25) += at25.o
# ... add above this line ...
# SPI slave controller drivers (upstream link)
diff --git a/drivers/spi/at25.c b/drivers/spi/at25.c
new file mode 100644
index 000000000000..48e4f48e779f
--- /dev/null
+++ b/drivers/spi/at25.c
@@ -0,0 +1,381 @@
+/*
+ * at25.c -- support most SPI EEPROMs, such as Atmel AT25 models
+ *
+ * Copyright (C) 2006 David Brownell
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/sched.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
+
+
+struct at25_data {
+ struct spi_device *spi;
+ struct mutex lock;
+ struct spi_eeprom chip;
+ struct bin_attribute bin;
+ unsigned addrlen;
+};
+
+#define AT25_WREN 0x06 /* latch the write enable */
+#define AT25_WRDI 0x04 /* reset the write enable */
+#define AT25_RDSR 0x05 /* read status register */
+#define AT25_WRSR 0x01 /* write status register */
+#define AT25_READ 0x03 /* read byte(s) */
+#define AT25_WRITE 0x02 /* write byte(s)/sector */
+
+#define AT25_SR_nRDY 0x01 /* nRDY = write-in-progress */
+#define AT25_SR_WEN 0x02 /* write enable (latched) */
+#define AT25_SR_BP0 0x04 /* BP for software writeprotect */
+#define AT25_SR_BP1 0x08
+#define AT25_SR_WPEN 0x80 /* writeprotect enable */
+
+
+#define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */
+
+/* Specs often allow 5 msec for a page write, sometimes 20 msec;
+ * it's important to recover from write timeouts.
+ */
+#define EE_TIMEOUT 25
+
+/*-------------------------------------------------------------------------*/
+
+#define io_limit PAGE_SIZE /* bytes */
+
+static ssize_t
+at25_ee_read(
+ struct at25_data *at25,
+ char *buf,
+ unsigned offset,
+ size_t count
+)
+{
+ u8 command[EE_MAXADDRLEN + 1];
+ u8 *cp;
+ ssize_t status;
+ struct spi_transfer t[2];
+ struct spi_message m;
+
+ cp = command;
+ *cp++ = AT25_READ;
+
+ /* 8/16/24-bit address is written MSB first */
+ switch (at25->addrlen) {
+ default: /* case 3 */
+ *cp++ = offset >> 16;
+ case 2:
+ *cp++ = offset >> 8;
+ case 1:
+ case 0: /* can't happen: for better codegen */
+ *cp++ = offset >> 0;
+ }
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof t);
+
+ t[0].tx_buf = command;
+ t[0].len = at25->addrlen + 1;
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].rx_buf = buf;
+ t[1].len = count;
+ spi_message_add_tail(&t[1], &m);
+
+ mutex_lock(&at25->lock);
+
+ /* Read it all at once.
+ *
+ * REVISIT that's potentially a problem with large chips, if
+ * other devices on the bus need to be accessed regularly or
+ * this chip is clocked very slowly
+ */
+ status = spi_sync(at25->spi, &m);
+ dev_dbg(&at25->spi->dev,
+ "read %Zd bytes at %d --> %d\n",
+ count, offset, (int) status);
+
+ mutex_unlock(&at25->lock);
+ return status ? status : count;
+}
+
+static ssize_t
+at25_bin_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct device *dev;
+ struct at25_data *at25;
+
+ dev = container_of(kobj, struct device, kobj);
+ at25 = dev_get_drvdata(dev);
+
+ if (unlikely(off >= at25->bin.size))
+ return 0;
+ if ((off + count) > at25->bin.size)
+ count = at25->bin.size - off;
+ if (unlikely(!count))
+ return count;
+
+ return at25_ee_read(at25, buf, off, count);
+}
+
+
+static ssize_t
+at25_ee_write(struct at25_data *at25, char *buf, loff_t off, size_t count)
+{
+ ssize_t status = 0;
+ unsigned written = 0;
+ unsigned buf_size;
+ u8 *bounce;
+
+ /* Temp buffer starts with command and address */
+ buf_size = at25->chip.page_size;
+ if (buf_size > io_limit)
+ buf_size = io_limit;
+ bounce = kmalloc(buf_size + at25->addrlen + 1, GFP_KERNEL);
+ if (!bounce)
+ return -ENOMEM;
+
+ /* For write, rollover is within the page ... so we write at
+ * most one page, then manually roll over to the next page.
+ */
+ bounce[0] = AT25_WRITE;
+ mutex_lock(&at25->lock);
+ do {
+ unsigned long timeout, retries;
+ unsigned segment;
+ unsigned offset = (unsigned) off;
+ u8 *cp = bounce + 1;
+
+ *cp = AT25_WREN;
+ status = spi_write(at25->spi, cp, 1);
+ if (status < 0) {
+ dev_dbg(&at25->spi->dev, "WREN --> %d\n",
+ (int) status);
+ break;
+ }
+
+ /* 8/16/24-bit address is written MSB first */
+ switch (at25->addrlen) {
+ default: /* case 3 */
+ *cp++ = offset >> 16;
+ case 2:
+ *cp++ = offset >> 8;
+ case 1:
+ case 0: /* can't happen: for better codegen */
+ *cp++ = offset >> 0;
+ }
+
+ /* Write as much of a page as we can */
+ segment = buf_size - (offset % buf_size);
+ if (segment > count)
+ segment = count;
+ memcpy(cp, buf, segment);
+ status = spi_write(at25->spi, bounce,
+ segment + at25->addrlen + 1);
+ dev_dbg(&at25->spi->dev,
+ "write %u bytes at %u --> %d\n",
+ segment, offset, (int) status);
+ if (status < 0)
+ break;
+
+ /* REVISIT this should detect (or prevent) failed writes
+ * to readonly sections of the EEPROM...
+ */
+
+ /* Wait for non-busy status */
+ timeout = jiffies + msecs_to_jiffies(EE_TIMEOUT);
+ retries = 0;
+ do {
+ int sr;
+
+ sr = spi_w8r8(at25->spi, AT25_RDSR);
+ if (sr < 0 || (sr & AT25_SR_nRDY)) {
+ dev_dbg(&at25->spi->dev,
+ "rdsr --> %d (%02x)\n", sr, sr);
+ /* at HZ=100, this is sloooow */
+ msleep(1);
+ continue;
+ }
+ if (!(sr & AT25_SR_nRDY))
+ break;
+ } while (retries++ < 3 || time_before_eq(jiffies, timeout));
+
+ if (time_after(jiffies, timeout)) {
+ dev_err(&at25->spi->dev,
+ "write %d bytes offset %d, "
+ "timeout after %u msecs\n",
+ segment, offset,
+ jiffies_to_msecs(jiffies -
+ (timeout - EE_TIMEOUT)));
+ status = -ETIMEDOUT;
+ break;
+ }
+
+ off += segment;
+ buf += segment;
+ count -= segment;
+ written += segment;
+
+ } while (count > 0);
+
+ mutex_unlock(&at25->lock);
+
+ kfree(bounce);
+ return written ? written : status;
+}
+
+static ssize_t
+at25_bin_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct device *dev;
+ struct at25_data *at25;
+
+ dev = container_of(kobj, struct device, kobj);
+ at25 = dev_get_drvdata(dev);
+
+ if (unlikely(off >= at25->bin.size))
+ return -EFBIG;
+ if ((off + count) > at25->bin.size)
+ count = at25->bin.size - off;
+ if (unlikely(!count))
+ return count;
+
+ return at25_ee_write(at25, buf, off, count);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int at25_probe(struct spi_device *spi)
+{
+ struct at25_data *at25 = NULL;
+ const struct spi_eeprom *chip;
+ int err;
+ int sr;
+ int addrlen;
+
+ /* Chip description */
+ chip = spi->dev.platform_data;
+ if (!chip) {
+ dev_dbg(&spi->dev, "no chip description\n");
+ err = -ENODEV;
+ goto fail;
+ }
+
+ /* For now we only support 8/16/24 bit addressing */
+ if (chip->flags & EE_ADDR1)
+ addrlen = 1;
+ else if (chip->flags & EE_ADDR2)
+ addrlen = 2;
+ else if (chip->flags & EE_ADDR3)
+ addrlen = 3;
+ else {
+ dev_dbg(&spi->dev, "unsupported address type\n");
+ err = -EINVAL;
+ goto fail;
+ }
+
+ /* Ping the chip ... the status register is pretty portable,
+ * unlike probing manufacturer IDs. We do expect that system
+ * firmware didn't write it in the past few milliseconds!
+ */
+ sr = spi_w8r8(spi, AT25_RDSR);
+ if (sr < 0 || sr & AT25_SR_nRDY) {
+ dev_dbg(&at25->spi->dev, "rdsr --> %d (%02x)\n", sr, sr);
+ err = -ENXIO;
+ goto fail;
+ }
+
+ if (!(at25 = kzalloc(sizeof *at25, GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ mutex_init(&at25->lock);
+ at25->chip = *chip;
+ at25->spi = spi_dev_get(spi);
+ dev_set_drvdata(&spi->dev, at25);
+ at25->addrlen = addrlen;
+
+ /* Export the EEPROM bytes through sysfs, since that's convenient.
+ * Default to root-only access to the data; EEPROMs often hold data
+ * that's sensitive for read and/or write, like ethernet addresses,
+ * security codes, board-specific manufacturing calibrations, etc.
+ */
+ at25->bin.attr.name = "eeprom";
+ at25->bin.attr.mode = S_IRUSR;
+ at25->bin.attr.owner = THIS_MODULE;
+ at25->bin.read = at25_bin_read;
+
+ at25->bin.size = at25->chip.byte_len;
+ if (!(chip->flags & EE_READONLY)) {
+ at25->bin.write = at25_bin_write;
+ at25->bin.attr.mode |= S_IWUSR;
+ }
+
+ err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin);
+ if (err)
+ goto fail;
+
+ dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n",
+ (at25->bin.size < 1024)
+ ? at25->bin.size
+ : (at25->bin.size / 1024),
+ (at25->bin.size < 1024) ? "Byte" : "KByte",
+ at25->chip.name,
+ (chip->flags & EE_READONLY) ? " (readonly)" : "",
+ at25->chip.page_size);
+ return 0;
+fail:
+ dev_dbg(&spi->dev, "probe err %d\n", err);
+ kfree(at25);
+ return err;
+}
+
+static int __devexit at25_remove(struct spi_device *spi)
+{
+ struct at25_data *at25;
+
+ at25 = dev_get_drvdata(&spi->dev);
+ sysfs_remove_bin_file(&spi->dev.kobj, &at25->bin);
+ kfree(at25);
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct spi_driver at25_driver = {
+ .driver = {
+ .name = "at25",
+ .owner = THIS_MODULE,
+ },
+ .probe = at25_probe,
+ .remove = __devexit_p(at25_remove),
+};
+
+static int __init at25_init(void)
+{
+ return spi_register_driver(&at25_driver);
+}
+module_init(at25_init);
+
+static void __exit at25_exit(void)
+{
+ spi_unregister_driver(&at25_driver);
+}
+module_exit(at25_exit);
+
+MODULE_DESCRIPTION("Driver for most SPI EEPROMs");
+MODULE_AUTHOR("David Brownell");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
new file mode 100644
index 000000000000..366af4959a0f
--- /dev/null
+++ b/drivers/spi/omap_uwire.c
@@ -0,0 +1,572 @@
+/*
+ * omap_uwire.c -- MicroWire interface driver for OMAP
+ *
+ * Copyright 2003 MontaVista Software Inc. <source@mvista.com>
+ *
+ * Ported to 2.6 OMAP uwire interface.
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ * Generalization patches by Juha Yrjola <juha.yrjola@nokia.com>
+ *
+ * Copyright (C) 2005 David Brownell (ported to 2.6 SPI interface)
+ * Copyright (C) 2006 Nokia
+ *
+ * Many updates by Imre Deak <imre.deak@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/mux.h>
+#include <asm/arch/omap730.h> /* OMAP730_IO_CONF registers */
+
+
+/* FIXME address is now a platform device resource,
+ * and irqs should show there too...
+ */
+#define UWIRE_BASE_PHYS 0xFFFB3000
+#define UWIRE_BASE ((void *__iomem)IO_ADDRESS(UWIRE_BASE_PHYS))
+
+/* uWire Registers: */
+#define UWIRE_IO_SIZE 0x20
+#define UWIRE_TDR 0x00
+#define UWIRE_RDR 0x00
+#define UWIRE_CSR 0x01
+#define UWIRE_SR1 0x02
+#define UWIRE_SR2 0x03
+#define UWIRE_SR3 0x04
+#define UWIRE_SR4 0x05
+#define UWIRE_SR5 0x06
+
+/* CSR bits */
+#define RDRB (1 << 15)
+#define CSRB (1 << 14)
+#define START (1 << 13)
+#define CS_CMD (1 << 12)
+
+/* SR1 or SR2 bits */
+#define UWIRE_READ_FALLING_EDGE 0x0001
+#define UWIRE_READ_RISING_EDGE 0x0000
+#define UWIRE_WRITE_FALLING_EDGE 0x0000
+#define UWIRE_WRITE_RISING_EDGE 0x0002
+#define UWIRE_CS_ACTIVE_LOW 0x0000
+#define UWIRE_CS_ACTIVE_HIGH 0x0004
+#define UWIRE_FREQ_DIV_2 0x0000
+#define UWIRE_FREQ_DIV_4 0x0008
+#define UWIRE_FREQ_DIV_8 0x0010
+#define UWIRE_CHK_READY 0x0020
+#define UWIRE_CLK_INVERTED 0x0040
+
+
+struct uwire_spi {
+ struct spi_bitbang bitbang;
+ struct clk *ck;
+};
+
+struct uwire_state {
+ unsigned bits_per_word;
+ unsigned div1_idx;
+};
+
+/* REVISIT compile time constant for idx_shift? */
+static unsigned int uwire_idx_shift;
+
+static inline void uwire_write_reg(int idx, u16 val)
+{
+ __raw_writew(val, UWIRE_BASE + (idx << uwire_idx_shift));
+}
+
+static inline u16 uwire_read_reg(int idx)
+{
+ return __raw_readw(UWIRE_BASE + (idx << uwire_idx_shift));
+}
+
+static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags)
+{
+ u16 w, val = 0;
+ int shift, reg;
+
+ if (flags & UWIRE_CLK_INVERTED)
+ val ^= 0x03;
+ val = flags & 0x3f;
+ if (cs & 1)
+ shift = 6;
+ else
+ shift = 0;
+ if (cs <= 1)
+ reg = UWIRE_SR1;
+ else
+ reg = UWIRE_SR2;
+
+ w = uwire_read_reg(reg);
+ w &= ~(0x3f << shift);
+ w |= val << shift;
+ uwire_write_reg(reg, w);
+}
+
+static int wait_uwire_csr_flag(u16 mask, u16 val, int might_not_catch)
+{
+ u16 w;
+ int c = 0;
+ unsigned long max_jiffies = jiffies + HZ;
+
+ for (;;) {
+ w = uwire_read_reg(UWIRE_CSR);
+ if ((w & mask) == val)
+ break;
+ if (time_after(jiffies, max_jiffies)) {
+ printk(KERN_ERR "%s: timeout. reg=%#06x "
+ "mask=%#06x val=%#06x\n",
+ __FUNCTION__, w, mask, val);
+ return -1;
+ }
+ c++;
+ if (might_not_catch && c > 64)
+ break;
+ }
+ return 0;
+}
+
+static void uwire_set_clk1_div(int div1_idx)
+{
+ u16 w;
+
+ w = uwire_read_reg(UWIRE_SR3);
+ w &= ~(0x03 << 1);
+ w |= div1_idx << 1;
+ uwire_write_reg(UWIRE_SR3, w);
+}
+
+static void uwire_chipselect(struct spi_device *spi, int value)
+{
+ struct uwire_state *ust = spi->controller_state;
+ u16 w;
+ int old_cs;
+
+
+ BUG_ON(wait_uwire_csr_flag(CSRB, 0, 0));
+
+ w = uwire_read_reg(UWIRE_CSR);
+ old_cs = (w >> 10) & 0x03;
+ if (value == BITBANG_CS_INACTIVE || old_cs != spi->chip_select) {
+ /* Deselect this CS, or the previous CS */
+ w &= ~CS_CMD;
+ uwire_write_reg(UWIRE_CSR, w);
+ }
+ /* activate specfied chipselect */
+ if (value == BITBANG_CS_ACTIVE) {
+ uwire_set_clk1_div(ust->div1_idx);
+ /* invert clock? */
+ if (spi->mode & SPI_CPOL)
+ uwire_write_reg(UWIRE_SR4, 1);
+ else
+ uwire_write_reg(UWIRE_SR4, 0);
+
+ w = spi->chip_select << 10;
+ w |= CS_CMD;
+ uwire_write_reg(UWIRE_CSR, w);
+ }
+}
+
+static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct uwire_state *ust = spi->controller_state;
+ unsigned len = t->len;
+ unsigned bits = ust->bits_per_word;
+ unsigned bytes;
+ u16 val, w;
+ int status = 0;;
+
+ if (!t->tx_buf && !t->rx_buf)
+ return 0;
+
+ /* Microwire doesn't read and write concurrently */
+ if (t->tx_buf && t->rx_buf)
+ return -EPERM;
+
+ w = spi->chip_select << 10;
+ w |= CS_CMD;
+
+ if (t->tx_buf) {
+ const u8 *buf = t->tx_buf;
+
+ /* NOTE: DMA could be used for TX transfers */
+
+ /* write one or two bytes at a time */
+ while (len >= 1) {
+ /* tx bit 15 is first sent; we byteswap multibyte words
+ * (msb-first) on the way out from memory.
+ */
+ val = *buf++;
+ if (bits > 8) {
+ bytes = 2;
+ val |= *buf++ << 8;
+ } else
+ bytes = 1;
+ val <<= 16 - bits;
+
+#ifdef VERBOSE
+ pr_debug("%s: write-%d =%04x\n",
+ spi->dev.bus_id, bits, val);
+#endif
+ if (wait_uwire_csr_flag(CSRB, 0, 0))
+ goto eio;
+
+ uwire_write_reg(UWIRE_TDR, val);
+
+ /* start write */
+ val = START | w | (bits << 5);
+
+ uwire_write_reg(UWIRE_CSR, val);
+ len -= bytes;
+
+ /* Wait till write actually starts.
+ * This is needed with MPU clock 60+ MHz.
+ * REVISIT: we may not have time to catch it...
+ */
+ if (wait_uwire_csr_flag(CSRB, CSRB, 1))
+ goto eio;
+
+ status += bytes;
+ }
+
+ /* REVISIT: save this for later to get more i/o overlap */
+ if (wait_uwire_csr_flag(CSRB, 0, 0))
+ goto eio;
+
+ } else if (t->rx_buf) {
+ u8 *buf = t->rx_buf;
+
+ /* read one or two bytes at a time */
+ while (len) {
+ if (bits > 8) {
+ bytes = 2;
+ } else
+ bytes = 1;
+
+ /* start read */
+ val = START | w | (bits << 0);
+ uwire_write_reg(UWIRE_CSR, val);
+ len -= bytes;
+
+ /* Wait till read actually starts */
+ (void) wait_uwire_csr_flag(CSRB, CSRB, 1);
+
+ if (wait_uwire_csr_flag(RDRB | CSRB,
+ RDRB, 0))
+ goto eio;
+
+ /* rx bit 0 is last received; multibyte words will
+ * be properly byteswapped on the way to memory.
+ */
+ val = uwire_read_reg(UWIRE_RDR);
+ val &= (1 << bits) - 1;
+ *buf++ = (u8) val;
+ if (bytes == 2)
+ *buf++ = val >> 8;
+ status += bytes;
+#ifdef VERBOSE
+ pr_debug("%s: read-%d =%04x\n",
+ spi->dev.bus_id, bits, val);
+#endif
+
+ }
+ }
+ return status;
+eio:
+ return -EIO;
+}
+
+static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct uwire_state *ust = spi->controller_state;
+ struct uwire_spi *uwire;
+ unsigned flags = 0;
+ unsigned bits;
+ unsigned hz;
+ unsigned long rate;
+ int div1_idx;
+ int div1;
+ int div2;
+ int status;
+
+ uwire = spi_master_get_devdata(spi->master);
+
+ if (spi->chip_select > 3) {
+ pr_debug("%s: cs%d?\n", spi->dev.bus_id, spi->chip_select);
+ status = -ENODEV;
+ goto done;
+ }
+
+ bits = spi->bits_per_word;
+ if (t != NULL && t->bits_per_word)
+ bits = t->bits_per_word;
+ if (!bits)
+ bits = 8;
+
+ if (bits > 16) {
+ pr_debug("%s: wordsize %d?\n", spi->dev.bus_id, bits);
+ status = -ENODEV;
+ goto done;
+ }
+ ust->bits_per_word = bits;
+
+ /* mode 0..3, clock inverted separately;
+ * standard nCS signaling;
+ * don't treat DI=high as "not ready"
+ */
+ if (spi->mode & SPI_CS_HIGH)
+ flags |= UWIRE_CS_ACTIVE_HIGH;
+
+ if (spi->mode & SPI_CPOL)
+ flags |= UWIRE_CLK_INVERTED;
+
+ switch (spi->mode & (SPI_CPOL | SPI_CPHA)) {
+ case SPI_MODE_0:
+ case SPI_MODE_3:
+ flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;
+ break;
+ case SPI_MODE_1:
+ case SPI_MODE_2:
+ flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;
+ break;
+ }
+
+ /* assume it's already enabled */
+ rate = clk_get_rate(uwire->ck);
+
+ hz = spi->max_speed_hz;
+ if (t != NULL && t->speed_hz)
+ hz = t->speed_hz;
+
+ if (!hz) {
+ pr_debug("%s: zero speed?\n", spi->dev.bus_id);
+ status = -EINVAL;
+ goto done;
+ }
+
+ /* F_INT = mpu_xor_clk / DIV1 */
+ for (div1_idx = 0; div1_idx < 4; div1_idx++) {
+ switch (div1_idx) {
+ case 0:
+ div1 = 2;
+ break;
+ case 1:
+ div1 = 4;
+ break;
+ case 2:
+ div1 = 7;
+ break;
+ default:
+ case 3:
+ div1 = 10;
+ break;
+ }
+ div2 = (rate / div1 + hz - 1) / hz;
+ if (div2 <= 8)
+ break;
+ }
+ if (div1_idx == 4) {
+ pr_debug("%s: lowest clock %ld, need %d\n",
+ spi->dev.bus_id, rate / 10 / 8, hz);
+ status = -EDOM;
+ goto done;
+ }
+
+ /* we have to cache this and reset in uwire_chipselect as this is a
+ * global parameter and another uwire device can change it under
+ * us */
+ ust->div1_idx = div1_idx;
+ uwire_set_clk1_div(div1_idx);
+
+ rate /= div1;
+
+ switch (div2) {
+ case 0:
+ case 1:
+ case 2:
+ flags |= UWIRE_FREQ_DIV_2;
+ rate /= 2;
+ break;
+ case 3:
+ case 4:
+ flags |= UWIRE_FREQ_DIV_4;
+ rate /= 4;
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ flags |= UWIRE_FREQ_DIV_8;
+ rate /= 8;
+ break;
+ }
+ omap_uwire_configure_mode(spi->chip_select, flags);
+ pr_debug("%s: uwire flags %02x, armxor %lu KHz, SCK %lu KHz\n",
+ __FUNCTION__, flags,
+ clk_get_rate(uwire->ck) / 1000,
+ rate / 1000);
+ status = 0;
+done:
+ return status;
+}
+
+static int uwire_setup(struct spi_device *spi)
+{
+ struct uwire_state *ust = spi->controller_state;
+
+ if (ust == NULL) {
+ ust = kzalloc(sizeof(*ust), GFP_KERNEL);
+ if (ust == NULL)
+ return -ENOMEM;
+ spi->controller_state = ust;
+ }
+
+ return uwire_setup_transfer(spi, NULL);
+}
+
+static void uwire_cleanup(const struct spi_device *spi)
+{
+ kfree(spi->controller_state);
+}
+
+static void uwire_off(struct uwire_spi *uwire)
+{
+ uwire_write_reg(UWIRE_SR3, 0);
+ clk_disable(uwire->ck);
+ clk_put(uwire->ck);
+ spi_master_put(uwire->bitbang.master);
+}
+
+static int uwire_probe(struct platform_device *pdev)
+{
+ struct spi_master *master;
+ struct uwire_spi *uwire;
+ int status;
+
+ master = spi_alloc_master(&pdev->dev, sizeof *uwire);
+ if (!master)
+ return -ENODEV;
+
+ uwire = spi_master_get_devdata(master);
+ dev_set_drvdata(&pdev->dev, uwire);
+
+ uwire->ck = clk_get(&pdev->dev, "armxor_ck");
+ if (!uwire->ck || IS_ERR(uwire->ck)) {
+ dev_dbg(&pdev->dev, "no mpu_xor_clk ?\n");
+ spi_master_put(master);
+ return -ENODEV;
+ }
+ clk_enable(uwire->ck);
+
+ if (cpu_is_omap730())
+ uwire_idx_shift = 1;
+ else
+ uwire_idx_shift = 2;
+
+ uwire_write_reg(UWIRE_SR3, 1);
+
+ master->bus_num = 2; /* "official" */
+ master->num_chipselect = 4;
+ master->setup = uwire_setup;
+ master->cleanup = uwire_cleanup;
+
+ uwire->bitbang.master = master;
+ uwire->bitbang.chipselect = uwire_chipselect;
+ uwire->bitbang.setup_transfer = uwire_setup_transfer;
+ uwire->bitbang.txrx_bufs = uwire_txrx;
+
+ status = spi_bitbang_start(&uwire->bitbang);
+ if (status < 0)
+ uwire_off(uwire);
+ return status;
+}
+
+static int uwire_remove(struct platform_device *pdev)
+{
+ struct uwire_spi *uwire = dev_get_drvdata(&pdev->dev);
+ int status;
+
+ // FIXME remove all child devices, somewhere ...
+
+ status = spi_bitbang_stop(&uwire->bitbang);
+ uwire_off(uwire);
+ return status;
+}
+
+static struct platform_driver uwire_driver = {
+ .driver = {
+ .name = "omap_uwire",
+ .bus = &platform_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = uwire_probe,
+ .remove = uwire_remove,
+ // suspend ... unuse ck
+ // resume ... use ck
+};
+
+static int __init omap_uwire_init(void)
+{
+ /* FIXME move these into the relevant board init code. also, include
+ * H3 support; it uses tsc2101 like H2 (on a different chipselect).
+ */
+
+ if (machine_is_omap_h2()) {
+ /* defaults: W21 SDO, U18 SDI, V19 SCL */
+ omap_cfg_reg(N14_1610_UWIRE_CS0);
+ omap_cfg_reg(N15_1610_UWIRE_CS1);
+ }
+ if (machine_is_omap_perseus2()) {
+ /* configure pins: MPU_UW_nSCS1, MPU_UW_SDO, MPU_UW_SCLK */
+ int val = omap_readl(OMAP730_IO_CONF_9) & ~0x00EEE000;
+ omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9);
+ }
+
+ return platform_driver_register(&uwire_driver);
+}
+
+static void __exit omap_uwire_exit(void)
+{
+ platform_driver_unregister(&uwire_driver);
+}
+
+subsys_initcall(omap_uwire_init);
+module_exit(omap_uwire_exit);
+
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index 8b41f9cc2560..9f2c887ffa04 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -1214,9 +1214,9 @@ static int setup(struct spi_device *spi)
return 0;
}
-static void cleanup(const struct spi_device *spi)
+static void cleanup(struct spi_device *spi)
{
- struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
+ struct chip_data *chip = spi_get_ctldata(spi);
kfree(chip);
}
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 6307428d2c94..2328128728be 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -32,7 +32,7 @@
*/
static void spidev_release(struct device *dev)
{
- const struct spi_device *spi = to_spi_device(dev);
+ struct spi_device *spi = to_spi_device(dev);
/* spi masters may cleanup for released devices */
if (spi->master->cleanup)
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index 57289b61d0be..24a330d82395 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -210,7 +210,7 @@ int spi_bitbang_setup(struct spi_device *spi)
if (!cs->txrx_word)
return -EINVAL;
- retval = spi_bitbang_setup_transfer(spi, NULL);
+ retval = bitbang->setup_transfer(spi, NULL);
if (retval < 0)
return retval;
@@ -238,7 +238,7 @@ EXPORT_SYMBOL_GPL(spi_bitbang_setup);
/**
* spi_bitbang_cleanup - default cleanup for per-word I/O loops
*/
-void spi_bitbang_cleanup(const struct spi_device *spi)
+void spi_bitbang_cleanup(struct spi_device *spi)
{
kfree(spi->controller_state);
}
@@ -442,9 +442,10 @@ EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
* hardware that basically exposes a shift register) or per-spi_transfer
* (which takes better advantage of hardware like fifos or DMA engines).
*
- * Drivers using per-word I/O loops should use (or call) spi_bitbang_setup and
- * spi_bitbang_cleanup to handle those spi master methods. Those methods are
- * the defaults if the bitbang->txrx_bufs routine isn't initialized.
+ * Drivers using per-word I/O loops should use (or call) spi_bitbang_setup,
+ * spi_bitbang_cleanup and spi_bitbang_setup_transfer to handle those spi
+ * master methods. Those methods are the defaults if the bitbang->txrx_bufs
+ * routine isn't initialized.
*
* This routine registers the spi_master, which will process requests in a
* dedicated task, keeping IRQs unblocked most of the time. To stop
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
new file mode 100644
index 000000000000..6ccf8a12a21d
--- /dev/null
+++ b/drivers/spi/spi_imx.c
@@ -0,0 +1,1769 @@
+/*
+ * drivers/spi/spi_imx.c
+ *
+ * Copyright (C) 2006 SWAPP
+ * Andrea Paterniani <a.paterniani@swapp-eng.it>
+ *
+ * Initial version inspired by:
+ * linux-2.6.17-rc3-mm1/drivers/spi/pxa2xx_spi.c
+ *
+ * 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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/spi/spi.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/delay.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/imx-dma.h>
+#include <asm/arch/spi_imx.h>
+
+/*-------------------------------------------------------------------------*/
+/* SPI Registers offsets from peripheral base address */
+#define SPI_RXDATA (0x00)
+#define SPI_TXDATA (0x04)
+#define SPI_CONTROL (0x08)
+#define SPI_INT_STATUS (0x0C)
+#define SPI_TEST (0x10)
+#define SPI_PERIOD (0x14)
+#define SPI_DMA (0x18)
+#define SPI_RESET (0x1C)
+
+/* SPI Control Register Bit Fields & Masks */
+#define SPI_CONTROL_BITCOUNT_MASK (0xF) /* Bit Count Mask */
+#define SPI_CONTROL_BITCOUNT(n) (((n) - 1) & SPI_CONTROL_BITCOUNT_MASK)
+#define SPI_CONTROL_POL (0x1 << 4) /* Clock Polarity Mask */
+#define SPI_CONTROL_POL_ACT_HIGH (0x0 << 4) /* Active high pol. (0=idle) */
+#define SPI_CONTROL_POL_ACT_LOW (0x1 << 4) /* Active low pol. (1=idle) */
+#define SPI_CONTROL_PHA (0x1 << 5) /* Clock Phase Mask */
+#define SPI_CONTROL_PHA_0 (0x0 << 5) /* Clock Phase 0 */
+#define SPI_CONTROL_PHA_1 (0x1 << 5) /* Clock Phase 1 */
+#define SPI_CONTROL_SSCTL (0x1 << 6) /* /SS Waveform Select Mask */
+#define SPI_CONTROL_SSCTL_0 (0x0 << 6) /* Master: /SS stays low between SPI burst
+ Slave: RXFIFO advanced by BIT_COUNT */
+#define SPI_CONTROL_SSCTL_1 (0x1 << 6) /* Master: /SS insert pulse between SPI burst
+ Slave: RXFIFO advanced by /SS rising edge */
+#define SPI_CONTROL_SSPOL (0x1 << 7) /* /SS Polarity Select Mask */
+#define SPI_CONTROL_SSPOL_ACT_LOW (0x0 << 7) /* /SS Active low */
+#define SPI_CONTROL_SSPOL_ACT_HIGH (0x1 << 7) /* /SS Active high */
+#define SPI_CONTROL_XCH (0x1 << 8) /* Exchange */
+#define SPI_CONTROL_SPIEN (0x1 << 9) /* SPI Module Enable */
+#define SPI_CONTROL_MODE (0x1 << 10) /* SPI Mode Select Mask */
+#define SPI_CONTROL_MODE_SLAVE (0x0 << 10) /* SPI Mode Slave */
+#define SPI_CONTROL_MODE_MASTER (0x1 << 10) /* SPI Mode Master */
+#define SPI_CONTROL_DRCTL (0x3 << 11) /* /SPI_RDY Control Mask */
+#define SPI_CONTROL_DRCTL_0 (0x0 << 11) /* Ignore /SPI_RDY */
+#define SPI_CONTROL_DRCTL_1 (0x1 << 11) /* /SPI_RDY falling edge triggers input */
+#define SPI_CONTROL_DRCTL_2 (0x2 << 11) /* /SPI_RDY active low level triggers input */
+#define SPI_CONTROL_DATARATE (0x7 << 13) /* Data Rate Mask */
+#define SPI_PERCLK2_DIV_MIN (0) /* PERCLK2:4 */
+#define SPI_PERCLK2_DIV_MAX (7) /* PERCLK2:512 */
+#define SPI_CONTROL_DATARATE_MIN (SPI_PERCLK2_DIV_MAX << 13)
+#define SPI_CONTROL_DATARATE_MAX (SPI_PERCLK2_DIV_MIN << 13)
+#define SPI_CONTROL_DATARATE_BAD (SPI_CONTROL_DATARATE_MIN + 1)
+
+/* SPI Interrupt/Status Register Bit Fields & Masks */
+#define SPI_STATUS_TE (0x1 << 0) /* TXFIFO Empty Status */
+#define SPI_STATUS_TH (0x1 << 1) /* TXFIFO Half Status */
+#define SPI_STATUS_TF (0x1 << 2) /* TXFIFO Full Status */
+#define SPI_STATUS_RR (0x1 << 3) /* RXFIFO Data Ready Status */
+#define SPI_STATUS_RH (0x1 << 4) /* RXFIFO Half Status */
+#define SPI_STATUS_RF (0x1 << 5) /* RXFIFO Full Status */
+#define SPI_STATUS_RO (0x1 << 6) /* RXFIFO Overflow */
+#define SPI_STATUS_BO (0x1 << 7) /* Bit Count Overflow */
+#define SPI_STATUS (0xFF) /* SPI Status Mask */
+#define SPI_INTEN_TE (0x1 << 8) /* TXFIFO Empty Interrupt Enable */
+#define SPI_INTEN_TH (0x1 << 9) /* TXFIFO Half Interrupt Enable */
+#define SPI_INTEN_TF (0x1 << 10) /* TXFIFO Full Interrupt Enable */
+#define SPI_INTEN_RE (0x1 << 11) /* RXFIFO Data Ready Interrupt Enable */
+#define SPI_INTEN_RH (0x1 << 12) /* RXFIFO Half Interrupt Enable */
+#define SPI_INTEN_RF (0x1 << 13) /* RXFIFO Full Interrupt Enable */
+#define SPI_INTEN_RO (0x1 << 14) /* RXFIFO Overflow Interrupt Enable */
+#define SPI_INTEN_BO (0x1 << 15) /* Bit Count Overflow Interrupt Enable */
+#define SPI_INTEN (0xFF << 8) /* SPI Interrupt Enable Mask */
+
+/* SPI Test Register Bit Fields & Masks */
+#define SPI_TEST_TXCNT (0xF << 0) /* TXFIFO Counter */
+#define SPI_TEST_RXCNT_LSB (4) /* RXFIFO Counter LSB */
+#define SPI_TEST_RXCNT (0xF << 4) /* RXFIFO Counter */
+#define SPI_TEST_SSTATUS (0xF << 8) /* State Machine Status */
+#define SPI_TEST_LBC (0x1 << 14) /* Loop Back Control */
+
+/* SPI Period Register Bit Fields & Masks */
+#define SPI_PERIOD_WAIT (0x7FFF << 0) /* Wait Between Transactions */
+#define SPI_PERIOD_MAX_WAIT (0x7FFF) /* Max Wait Between
+ Transactions */
+#define SPI_PERIOD_CSRC (0x1 << 15) /* Period Clock Source Mask */
+#define SPI_PERIOD_CSRC_BCLK (0x0 << 15) /* Period Clock Source is
+ Bit Clock */
+#define SPI_PERIOD_CSRC_32768 (0x1 << 15) /* Period Clock Source is
+ 32.768 KHz Clock */
+
+/* SPI DMA Register Bit Fields & Masks */
+#define SPI_DMA_RHDMA (0xF << 4) /* RXFIFO Half Status */
+#define SPI_DMA_RFDMA (0x1 << 5) /* RXFIFO Full Status */
+#define SPI_DMA_TEDMA (0x1 << 6) /* TXFIFO Empty Status */
+#define SPI_DMA_THDMA (0x1 << 7) /* TXFIFO Half Status */
+#define SPI_DMA_RHDEN (0x1 << 12) /* RXFIFO Half DMA Request Enable */
+#define SPI_DMA_RFDEN (0x1 << 13) /* RXFIFO Full DMA Request Enable */
+#define SPI_DMA_TEDEN (0x1 << 14) /* TXFIFO Empty DMA Request Enable */
+#define SPI_DMA_THDEN (0x1 << 15) /* TXFIFO Half DMA Request Enable */
+
+/* SPI Soft Reset Register Bit Fields & Masks */
+#define SPI_RESET_START (0x1) /* Start */
+
+/* Default SPI configuration values */
+#define SPI_DEFAULT_CONTROL \
+( \
+ SPI_CONTROL_BITCOUNT(16) | \
+ SPI_CONTROL_POL_ACT_HIGH | \
+ SPI_CONTROL_PHA_0 | \
+ SPI_CONTROL_SPIEN | \
+ SPI_CONTROL_SSCTL_1 | \
+ SPI_CONTROL_MODE_MASTER | \
+ SPI_CONTROL_DRCTL_0 | \
+ SPI_CONTROL_DATARATE_MIN \
+)
+#define SPI_DEFAULT_ENABLE_LOOPBACK (0)
+#define SPI_DEFAULT_ENABLE_DMA (0)
+#define SPI_DEFAULT_PERIOD_WAIT (8)
+/*-------------------------------------------------------------------------*/
+
+
+/*-------------------------------------------------------------------------*/
+/* TX/RX SPI FIFO size */
+#define SPI_FIFO_DEPTH (8)
+#define SPI_FIFO_BYTE_WIDTH (2)
+#define SPI_FIFO_OVERFLOW_MARGIN (2)
+
+/* DMA burst lenght for half full/empty request trigger */
+#define SPI_DMA_BLR (SPI_FIFO_DEPTH * SPI_FIFO_BYTE_WIDTH / 2)
+
+/* Dummy char output to achieve reads.
+ Choosing something different from all zeroes may help pattern recogition
+ for oscilloscope analysis, but may break some drivers. */
+#define SPI_DUMMY_u8 0
+#define SPI_DUMMY_u16 ((SPI_DUMMY_u8 << 8) | SPI_DUMMY_u8)
+#define SPI_DUMMY_u32 ((SPI_DUMMY_u16 << 16) | SPI_DUMMY_u16)
+
+/**
+ * Macro to change a u32 field:
+ * @r : register to edit
+ * @m : bit mask
+ * @v : new value for the field correctly bit-alligned
+*/
+#define u32_EDIT(r, m, v) r = (r & ~(m)) | (v)
+
+/* Message state */
+#define START_STATE ((void*)0)
+#define RUNNING_STATE ((void*)1)
+#define DONE_STATE ((void*)2)
+#define ERROR_STATE ((void*)-1)
+
+/* Queue state */
+#define QUEUE_RUNNING (0)
+#define QUEUE_STOPPED (1)
+
+#define IS_DMA_ALIGNED(x) (((u32)(x) & 0x03) == 0)
+/*-------------------------------------------------------------------------*/
+
+
+/*-------------------------------------------------------------------------*/
+/* Driver data structs */
+
+/* Context */
+struct driver_data {
+ /* Driver model hookup */
+ struct platform_device *pdev;
+
+ /* SPI framework hookup */
+ struct spi_master *master;
+
+ /* IMX hookup */
+ struct spi_imx_master *master_info;
+
+ /* Memory resources and SPI regs virtual address */
+ struct resource *ioarea;
+ void __iomem *regs;
+
+ /* SPI RX_DATA physical address */
+ dma_addr_t rd_data_phys;
+
+ /* Driver message queue */
+ struct workqueue_struct *workqueue;
+ struct work_struct work;
+ spinlock_t lock;
+ struct list_head queue;
+ int busy;
+ int run;
+
+ /* Message Transfer pump */
+ struct tasklet_struct pump_transfers;
+
+ /* Current message, transfer and state */
+ struct spi_message *cur_msg;
+ struct spi_transfer *cur_transfer;
+ struct chip_data *cur_chip;
+
+ /* Rd / Wr buffers pointers */
+ size_t len;
+ void *tx;
+ void *tx_end;
+ void *rx;
+ void *rx_end;
+
+ u8 rd_only;
+ u8 n_bytes;
+ int cs_change;
+
+ /* Function pointers */
+ irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
+ void (*cs_control)(u32 command);
+
+ /* DMA setup */
+ int rx_channel;
+ int tx_channel;
+ dma_addr_t rx_dma;
+ dma_addr_t tx_dma;
+ int rx_dma_needs_unmap;
+ int tx_dma_needs_unmap;
+ size_t tx_map_len;
+ u32 dummy_dma_buf ____cacheline_aligned;
+};
+
+/* Runtime state */
+struct chip_data {
+ u32 control;
+ u32 period;
+ u32 test;
+
+ u8 enable_dma:1;
+ u8 bits_per_word;
+ u8 n_bytes;
+ u32 max_speed_hz;
+
+ void (*cs_control)(u32 command);
+};
+/*-------------------------------------------------------------------------*/
+
+
+static void pump_messages(struct work_struct *work);
+
+static int flush(struct driver_data *drv_data)
+{
+ unsigned long limit = loops_per_jiffy << 1;
+ void __iomem *regs = drv_data->regs;
+ volatile u32 d;
+
+ dev_dbg(&drv_data->pdev->dev, "flush\n");
+ do {
+ while (readl(regs + SPI_INT_STATUS) & SPI_STATUS_RR)
+ d = readl(regs + SPI_RXDATA);
+ } while ((readl(regs + SPI_CONTROL) & SPI_CONTROL_XCH) && limit--);
+
+ return limit;
+}
+
+static void restore_state(struct driver_data *drv_data)
+{
+ void __iomem *regs = drv_data->regs;
+ struct chip_data *chip = drv_data->cur_chip;
+
+ /* Load chip registers */
+ dev_dbg(&drv_data->pdev->dev,
+ "restore_state\n"
+ " test = 0x%08X\n"
+ " control = 0x%08X\n",
+ chip->test,
+ chip->control);
+ writel(chip->test, regs + SPI_TEST);
+ writel(chip->period, regs + SPI_PERIOD);
+ writel(0, regs + SPI_INT_STATUS);
+ writel(chip->control, regs + SPI_CONTROL);
+}
+
+static void null_cs_control(u32 command)
+{
+}
+
+static inline u32 data_to_write(struct driver_data *drv_data)
+{
+ return ((u32)(drv_data->tx_end - drv_data->tx)) / drv_data->n_bytes;
+}
+
+static inline u32 data_to_read(struct driver_data *drv_data)
+{
+ return ((u32)(drv_data->rx_end - drv_data->rx)) / drv_data->n_bytes;
+}
+
+static int write(struct driver_data *drv_data)
+{
+ void __iomem *regs = drv_data->regs;
+ void *tx = drv_data->tx;
+ void *tx_end = drv_data->tx_end;
+ u8 n_bytes = drv_data->n_bytes;
+ u32 remaining_writes;
+ u32 fifo_avail_space;
+ u32 n;
+ u16 d;
+
+ /* Compute how many fifo writes to do */
+ remaining_writes = (u32)(tx_end - tx) / n_bytes;
+ fifo_avail_space = SPI_FIFO_DEPTH -
+ (readl(regs + SPI_TEST) & SPI_TEST_TXCNT);
+ if (drv_data->rx && (fifo_avail_space > SPI_FIFO_OVERFLOW_MARGIN))
+ /* Fix misunderstood receive overflow */
+ fifo_avail_space -= SPI_FIFO_OVERFLOW_MARGIN;
+ n = min(remaining_writes, fifo_avail_space);
+
+ dev_dbg(&drv_data->pdev->dev,
+ "write type %s\n"
+ " remaining writes = %d\n"
+ " fifo avail space = %d\n"
+ " fifo writes = %d\n",
+ (n_bytes == 1) ? "u8" : "u16",
+ remaining_writes,
+ fifo_avail_space,
+ n);
+
+ if (n > 0) {
+ /* Fill SPI TXFIFO */
+ if (drv_data->rd_only) {
+ tx += n * n_bytes;
+ while (n--)
+ writel(SPI_DUMMY_u16, regs + SPI_TXDATA);
+ } else {
+ if (n_bytes == 1) {
+ while (n--) {
+ d = *(u8*)tx;
+ writel(d, regs + SPI_TXDATA);
+ tx += 1;
+ }
+ } else {
+ while (n--) {
+ d = *(u16*)tx;
+ writel(d, regs + SPI_TXDATA);
+ tx += 2;
+ }
+ }
+ }
+
+ /* Trigger transfer */
+ writel(readl(regs + SPI_CONTROL) | SPI_CONTROL_XCH,
+ regs + SPI_CONTROL);
+
+ /* Update tx pointer */
+ drv_data->tx = tx;
+ }
+
+ return (tx >= tx_end);
+}
+
+static int read(struct driver_data *drv_data)
+{
+ void __iomem *regs = drv_data->regs;
+ void *rx = drv_data->rx;
+ void *rx_end = drv_data->rx_end;
+ u8 n_bytes = drv_data->n_bytes;
+ u32 remaining_reads;
+ u32 fifo_rxcnt;
+ u32 n;
+ u16 d;
+
+ /* Compute how many fifo reads to do */
+ remaining_reads = (u32)(rx_end - rx) / n_bytes;
+ fifo_rxcnt = (readl(regs + SPI_TEST) & SPI_TEST_RXCNT) >>
+ SPI_TEST_RXCNT_LSB;
+ n = min(remaining_reads, fifo_rxcnt);
+
+ dev_dbg(&drv_data->pdev->dev,
+ "read type %s\n"
+ " remaining reads = %d\n"
+ " fifo rx count = %d\n"
+ " fifo reads = %d\n",
+ (n_bytes == 1) ? "u8" : "u16",
+ remaining_reads,
+ fifo_rxcnt,
+ n);
+
+ if (n > 0) {
+ /* Read SPI RXFIFO */
+ if (n_bytes == 1) {
+ while (n--) {
+ d = readl(regs + SPI_RXDATA);
+ *((u8*)rx) = d;
+ rx += 1;
+ }
+ } else {
+ while (n--) {
+ d = readl(regs + SPI_RXDATA);
+ *((u16*)rx) = d;
+ rx += 2;
+ }
+ }
+
+ /* Update rx pointer */
+ drv_data->rx = rx;
+ }
+
+ return (rx >= rx_end);
+}
+
+static void *next_transfer(struct driver_data *drv_data)
+{
+ struct spi_message *msg = drv_data->cur_msg;
+ struct spi_transfer *trans = drv_data->cur_transfer;
+
+ /* Move to next transfer */
+ if (trans->transfer_list.next != &msg->transfers) {
+ drv_data->cur_transfer =
+ list_entry(trans->transfer_list.next,
+ struct spi_transfer,
+ transfer_list);
+ return RUNNING_STATE;
+ }
+
+ return DONE_STATE;
+}
+
+static int map_dma_buffers(struct driver_data *drv_data)
+{
+ struct spi_message *msg;
+ struct device *dev;
+ void *buf;
+
+ drv_data->rx_dma_needs_unmap = 0;
+ drv_data->tx_dma_needs_unmap = 0;
+
+ if (!drv_data->master_info->enable_dma ||
+ !drv_data->cur_chip->enable_dma)
+ return -1;
+
+ msg = drv_data->cur_msg;
+ dev = &msg->spi->dev;
+ if (msg->is_dma_mapped) {
+ if (drv_data->tx_dma)
+ /* The caller provided at least dma and cpu virtual
+ address for write; pump_transfers() will consider the
+ transfer as write only if cpu rx virtual address is
+ NULL */
+ return 0;
+
+ if (drv_data->rx_dma) {
+ /* The caller provided dma and cpu virtual address to
+ performe read only transfer -->
+ use drv_data->dummy_dma_buf for dummy writes to
+ achive reads */
+ buf = &drv_data->dummy_dma_buf;
+ drv_data->tx_map_len = sizeof(drv_data->dummy_dma_buf);
+ drv_data->tx_dma = dma_map_single(dev,
+ buf,
+ drv_data->tx_map_len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(drv_data->tx_dma))
+ return -1;
+
+ drv_data->tx_dma_needs_unmap = 1;
+
+ /* Flags transfer as rd_only for pump_transfers() DMA
+ regs programming (should be redundant) */
+ drv_data->tx = NULL;
+
+ return 0;
+ }
+ }
+
+ if (!IS_DMA_ALIGNED(drv_data->rx) || !IS_DMA_ALIGNED(drv_data->tx))
+ return -1;
+
+ /* NULL rx means write-only transfer and no map needed
+ since rx DMA will not be used */
+ if (drv_data->rx) {
+ buf = drv_data->rx;
+ drv_data->rx_dma = dma_map_single(
+ dev,
+ buf,
+ drv_data->len,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(drv_data->rx_dma))
+ return -1;
+ drv_data->rx_dma_needs_unmap = 1;
+ }
+
+ if (drv_data->tx == NULL) {
+ /* Read only message --> use drv_data->dummy_dma_buf for dummy
+ writes to achive reads */
+ buf = &drv_data->dummy_dma_buf;
+ drv_data->tx_map_len = sizeof(drv_data->dummy_dma_buf);
+ } else {
+ buf = drv_data->tx;
+ drv_data->tx_map_len = drv_data->len;
+ }
+ drv_data->tx_dma = dma_map_single(dev,
+ buf,
+ drv_data->tx_map_len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(drv_data->tx_dma)) {
+ if (drv_data->rx_dma) {
+ dma_unmap_single(dev,
+ drv_data->rx_dma,
+ drv_data->len,
+ DMA_FROM_DEVICE);
+ drv_data->rx_dma_needs_unmap = 0;
+ }
+ return -1;
+ }
+ drv_data->tx_dma_needs_unmap = 1;
+
+ return 0;
+}
+
+static void unmap_dma_buffers(struct driver_data *drv_data)
+{
+ struct spi_message *msg = drv_data->cur_msg;
+ struct device *dev = &msg->spi->dev;
+
+ if (drv_data->rx_dma_needs_unmap) {
+ dma_unmap_single(dev,
+ drv_data->rx_dma,
+ drv_data->len,
+ DMA_FROM_DEVICE);
+ drv_data->rx_dma_needs_unmap = 0;
+ }
+ if (drv_data->tx_dma_needs_unmap) {
+ dma_unmap_single(dev,
+ drv_data->tx_dma,
+ drv_data->tx_map_len,
+ DMA_TO_DEVICE);
+ drv_data->tx_dma_needs_unmap = 0;
+ }
+}
+
+/* Caller already set message->status (dma is already blocked) */
+static void giveback(struct spi_message *message, struct driver_data *drv_data)
+{
+ void __iomem *regs = drv_data->regs;
+
+ /* Bring SPI to sleep; restore_state() and pump_transfer()
+ will do new setup */
+ writel(0, regs + SPI_INT_STATUS);
+ writel(0, regs + SPI_DMA);
+
+ drv_data->cs_control(SPI_CS_DEASSERT);
+
+ message->state = NULL;
+ if (message->complete)
+ message->complete(message->context);
+
+ drv_data->cur_msg = NULL;
+ drv_data->cur_transfer = NULL;
+ drv_data->cur_chip = NULL;
+ queue_work(drv_data->workqueue, &drv_data->work);
+}
+
+static void dma_err_handler(int channel, void *data, int errcode)
+{
+ struct driver_data *drv_data = data;
+ struct spi_message *msg = drv_data->cur_msg;
+
+ dev_dbg(&drv_data->pdev->dev, "dma_err_handler\n");
+
+ /* Disable both rx and tx dma channels */
+ imx_dma_disable(drv_data->rx_channel);
+ imx_dma_disable(drv_data->tx_channel);
+
+ if (flush(drv_data) == 0)
+ dev_err(&drv_data->pdev->dev,
+ "dma_err_handler - flush failed\n");
+
+ unmap_dma_buffers(drv_data);
+
+ msg->state = ERROR_STATE;
+ tasklet_schedule(&drv_data->pump_transfers);
+}
+
+static void dma_tx_handler(int channel, void *data)
+{
+ struct driver_data *drv_data = data;
+
+ dev_dbg(&drv_data->pdev->dev, "dma_tx_handler\n");
+
+ imx_dma_disable(channel);
+
+ /* Now waits for TX FIFO empty */
+ writel(readl(drv_data->regs + SPI_INT_STATUS) | SPI_INTEN_TE,
+ drv_data->regs + SPI_INT_STATUS);
+}
+
+static irqreturn_t dma_transfer(struct driver_data *drv_data)
+{
+ u32 status;
+ struct spi_message *msg = drv_data->cur_msg;
+ void __iomem *regs = drv_data->regs;
+ unsigned long limit;
+
+ status = readl(regs + SPI_INT_STATUS);
+
+ if ((status & SPI_INTEN_RO) && (status & SPI_STATUS_RO)) {
+ writel(status & ~SPI_INTEN, regs + SPI_INT_STATUS);
+
+ imx_dma_disable(drv_data->rx_channel);
+ unmap_dma_buffers(drv_data);
+
+ if (flush(drv_data) == 0)
+ dev_err(&drv_data->pdev->dev,
+ "dma_transfer - flush failed\n");
+
+ dev_warn(&drv_data->pdev->dev,
+ "dma_transfer - fifo overun\n");
+
+ msg->state = ERROR_STATE;
+ tasklet_schedule(&drv_data->pump_transfers);
+
+ return IRQ_HANDLED;
+ }
+
+ if (status & SPI_STATUS_TE) {
+ writel(status & ~SPI_INTEN_TE, regs + SPI_INT_STATUS);
+
+ if (drv_data->rx) {
+ /* Wait end of transfer before read trailing data */
+ limit = loops_per_jiffy << 1;
+ while ((readl(regs + SPI_CONTROL) & SPI_CONTROL_XCH) &&
+ limit--);
+
+ if (limit == 0)
+ dev_err(&drv_data->pdev->dev,
+ "dma_transfer - end of tx failed\n");
+ else
+ dev_dbg(&drv_data->pdev->dev,
+ "dma_transfer - end of tx\n");
+
+ imx_dma_disable(drv_data->rx_channel);
+ unmap_dma_buffers(drv_data);
+
+ /* Calculate number of trailing data and read them */
+ dev_dbg(&drv_data->pdev->dev,
+ "dma_transfer - test = 0x%08X\n",
+ readl(regs + SPI_TEST));
+ drv_data->rx = drv_data->rx_end -
+ ((readl(regs + SPI_TEST) &
+ SPI_TEST_RXCNT) >>
+ SPI_TEST_RXCNT_LSB)*drv_data->n_bytes;
+ read(drv_data);
+ } else {
+ /* Write only transfer */
+ unmap_dma_buffers(drv_data);
+
+ if (flush(drv_data) == 0)
+ dev_err(&drv_data->pdev->dev,
+ "dma_transfer - flush failed\n");
+ }
+
+ /* End of transfer, update total byte transfered */
+ msg->actual_length += drv_data->len;
+
+ /* Release chip select if requested, transfer delays are
+ handled in pump_transfers() */
+ if (drv_data->cs_change)
+ drv_data->cs_control(SPI_CS_DEASSERT);
+
+ /* Move to next transfer */
+ msg->state = next_transfer(drv_data);
+
+ /* Schedule transfer tasklet */
+ tasklet_schedule(&drv_data->pump_transfers);
+
+ return IRQ_HANDLED;
+ }
+
+ /* Opps problem detected */
+ return IRQ_NONE;
+}
+
+static irqreturn_t interrupt_wronly_transfer(struct driver_data *drv_data)
+{
+ struct spi_message *msg = drv_data->cur_msg;
+ void __iomem *regs = drv_data->regs;
+ u32 status;
+ irqreturn_t handled = IRQ_NONE;
+
+ status = readl(regs + SPI_INT_STATUS);
+
+ while (status & SPI_STATUS_TH) {
+ dev_dbg(&drv_data->pdev->dev,
+ "interrupt_wronly_transfer - status = 0x%08X\n", status);
+
+ /* Pump data */
+ if (write(drv_data)) {
+ writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
+ regs + SPI_INT_STATUS);
+
+ dev_dbg(&drv_data->pdev->dev,
+ "interrupt_wronly_transfer - end of tx\n");
+
+ if (flush(drv_data) == 0)
+ dev_err(&drv_data->pdev->dev,
+ "interrupt_wronly_transfer - "
+ "flush failed\n");
+
+ /* End of transfer, update total byte transfered */
+ msg->actual_length += drv_data->len;
+
+ /* Release chip select if requested, transfer delays are
+ handled in pump_transfers */
+ if (drv_data->cs_change)
+ drv_data->cs_control(SPI_CS_DEASSERT);
+
+ /* Move to next transfer */
+ msg->state = next_transfer(drv_data);
+
+ /* Schedule transfer tasklet */
+ tasklet_schedule(&drv_data->pump_transfers);
+
+ return IRQ_HANDLED;
+ }
+
+ status = readl(regs + SPI_INT_STATUS);
+
+ /* We did something */
+ handled = IRQ_HANDLED;
+ }
+
+ return handled;
+}
+
+static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
+{
+ struct spi_message *msg = drv_data->cur_msg;
+ void __iomem *regs = drv_data->regs;
+ u32 status;
+ irqreturn_t handled = IRQ_NONE;
+ unsigned long limit;
+
+ status = readl(regs + SPI_INT_STATUS);
+
+ while (status & (SPI_STATUS_TH | SPI_STATUS_RO)) {
+ dev_dbg(&drv_data->pdev->dev,
+ "interrupt_transfer - status = 0x%08X\n", status);
+
+ if (status & SPI_STATUS_RO) {
+ writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
+ regs + SPI_INT_STATUS);
+
+ dev_warn(&drv_data->pdev->dev,
+ "interrupt_transfer - fifo overun\n"
+ " data not yet written = %d\n"
+ " data not yet read = %d\n",
+ data_to_write(drv_data),
+ data_to_read(drv_data));
+
+ if (flush(drv_data) == 0)
+ dev_err(&drv_data->pdev->dev,
+ "interrupt_transfer - flush failed\n");
+
+ msg->state = ERROR_STATE;
+ tasklet_schedule(&drv_data->pump_transfers);
+
+ return IRQ_HANDLED;
+ }
+
+ /* Pump data */
+ read(drv_data);
+ if (write(drv_data)) {
+ writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
+ regs + SPI_INT_STATUS);
+
+ dev_dbg(&drv_data->pdev->dev,
+ "interrupt_transfer - end of tx\n");
+
+ /* Read trailing bytes */
+ limit = loops_per_jiffy << 1;
+ while ((read(drv_data) == 0) && limit--);
+
+ if (limit == 0)
+ dev_err(&drv_data->pdev->dev,
+ "interrupt_transfer - "
+ "trailing byte read failed\n");
+ else
+ dev_dbg(&drv_data->pdev->dev,
+ "interrupt_transfer - end of rx\n");
+
+ /* End of transfer, update total byte transfered */
+ msg->actual_length += drv_data->len;
+
+ /* Release chip select if requested, transfer delays are
+ handled in pump_transfers */
+ if (drv_data->cs_change)
+ drv_data->cs_control(SPI_CS_DEASSERT);
+
+ /* Move to next transfer */
+ msg->state = next_transfer(drv_data);
+
+ /* Schedule transfer tasklet */
+ tasklet_schedule(&drv_data->pump_transfers);
+
+ return IRQ_HANDLED;
+ }
+
+ status = readl(regs + SPI_INT_STATUS);
+
+ /* We did something */
+ handled = IRQ_HANDLED;
+ }
+
+ return handled;
+}
+
+static irqreturn_t spi_int(int irq, void *dev_id)
+{
+ struct driver_data *drv_data = (struct driver_data *)dev_id;
+
+ if (!drv_data->cur_msg) {
+ dev_err(&drv_data->pdev->dev,
+ "spi_int - bad message state\n");
+ /* Never fail */
+ return IRQ_HANDLED;
+ }
+
+ return drv_data->transfer_handler(drv_data);
+}
+
+static inline u32 spi_speed_hz(u32 data_rate)
+{
+ return imx_get_perclk2() / (4 << ((data_rate) >> 13));
+}
+
+static u32 spi_data_rate(u32 speed_hz)
+{
+ u32 div;
+ u32 quantized_hz = imx_get_perclk2() >> 2;
+
+ for (div = SPI_PERCLK2_DIV_MIN;
+ div <= SPI_PERCLK2_DIV_MAX;
+ div++, quantized_hz >>= 1) {
+ if (quantized_hz <= speed_hz)
+ /* Max available speed LEQ required speed */
+ return div << 13;
+ }
+ return SPI_CONTROL_DATARATE_BAD;
+}
+
+static void pump_transfers(unsigned long data)
+{
+ struct driver_data *drv_data = (struct driver_data *)data;
+ struct spi_message *message;
+ struct spi_transfer *transfer, *previous;
+ struct chip_data *chip;
+ void __iomem *regs;
+ u32 tmp, control;
+
+ dev_dbg(&drv_data->pdev->dev, "pump_transfer\n");
+
+ message = drv_data->cur_msg;
+
+ /* Handle for abort */
+ if (message->state == ERROR_STATE) {
+ message->status = -EIO;
+ giveback(message, drv_data);
+ return;
+ }
+
+ /* Handle end of message */
+ if (message->state == DONE_STATE) {
+ message->status = 0;
+ giveback(message, drv_data);
+ return;
+ }
+
+ chip = drv_data->cur_chip;
+
+ /* Delay if requested at end of transfer*/
+ transfer = drv_data->cur_transfer;
+ if (message->state == RUNNING_STATE) {
+ previous = list_entry(transfer->transfer_list.prev,
+ struct spi_transfer,
+ transfer_list);
+ if (previous->delay_usecs)
+ udelay(previous->delay_usecs);
+ } else {
+ /* START_STATE */
+ message->state = RUNNING_STATE;
+ drv_data->cs_control = chip->cs_control;
+ }
+
+ transfer = drv_data->cur_transfer;
+ drv_data->tx = (void *)transfer->tx_buf;
+ drv_data->tx_end = drv_data->tx + transfer->len;
+ drv_data->rx = transfer->rx_buf;
+ drv_data->rx_end = drv_data->rx + transfer->len;
+ drv_data->rx_dma = transfer->rx_dma;
+ drv_data->tx_dma = transfer->tx_dma;
+ drv_data->len = transfer->len;
+ drv_data->cs_change = transfer->cs_change;
+ drv_data->rd_only = (drv_data->tx == NULL);
+
+ regs = drv_data->regs;
+ control = readl(regs + SPI_CONTROL);
+
+ /* Bits per word setup */
+ tmp = transfer->bits_per_word;
+ if (tmp == 0) {
+ /* Use device setup */
+ tmp = chip->bits_per_word;
+ drv_data->n_bytes = chip->n_bytes;
+ } else
+ /* Use per-transfer setup */
+ drv_data->n_bytes = (tmp <= 8) ? 1 : 2;
+ u32_EDIT(control, SPI_CONTROL_BITCOUNT_MASK, tmp - 1);
+
+ /* Speed setup (surely valid because already checked) */
+ tmp = transfer->speed_hz;
+ if (tmp == 0)
+ tmp = chip->max_speed_hz;
+ tmp = spi_data_rate(tmp);
+ u32_EDIT(control, SPI_CONTROL_DATARATE, tmp);
+
+ writel(control, regs + SPI_CONTROL);
+
+ /* Assert device chip-select */
+ drv_data->cs_control(SPI_CS_ASSERT);
+
+ /* DMA cannot read/write SPI FIFOs other than 16 bits at a time; hence
+ if bits_per_word is less or equal 8 PIO transfers are performed.
+ Moreover DMA is convinient for transfer length bigger than FIFOs
+ byte size. */
+ if ((drv_data->n_bytes == 2) &&
+ (drv_data->len > SPI_FIFO_DEPTH*SPI_FIFO_BYTE_WIDTH) &&
+ (map_dma_buffers(drv_data) == 0)) {
+ dev_dbg(&drv_data->pdev->dev,
+ "pump dma transfer\n"
+ " tx = %p\n"
+ " tx_dma = %08X\n"
+ " rx = %p\n"
+ " rx_dma = %08X\n"
+ " len = %d\n",
+ drv_data->tx,
+ (unsigned int)drv_data->tx_dma,
+ drv_data->rx,
+ (unsigned int)drv_data->rx_dma,
+ drv_data->len);
+
+ /* Ensure we have the correct interrupt handler */
+ drv_data->transfer_handler = dma_transfer;
+
+ /* Trigger transfer */
+ writel(readl(regs + SPI_CONTROL) | SPI_CONTROL_XCH,
+ regs + SPI_CONTROL);
+
+ /* Setup tx DMA */
+ if (drv_data->tx)
+ /* Linear source address */
+ CCR(drv_data->tx_channel) =
+ CCR_DMOD_FIFO |
+ CCR_SMOD_LINEAR |
+ CCR_SSIZ_32 | CCR_DSIZ_16 |
+ CCR_REN;
+ else
+ /* Read only transfer -> fixed source address for
+ dummy write to achive read */
+ CCR(drv_data->tx_channel) =
+ CCR_DMOD_FIFO |
+ CCR_SMOD_FIFO |
+ CCR_SSIZ_32 | CCR_DSIZ_16 |
+ CCR_REN;
+
+ imx_dma_setup_single(
+ drv_data->tx_channel,
+ drv_data->tx_dma,
+ drv_data->len,
+ drv_data->rd_data_phys + 4,
+ DMA_MODE_WRITE);
+
+ if (drv_data->rx) {
+ /* Setup rx DMA for linear destination address */
+ CCR(drv_data->rx_channel) =
+ CCR_DMOD_LINEAR |
+ CCR_SMOD_FIFO |
+ CCR_DSIZ_32 | CCR_SSIZ_16 |
+ CCR_REN;
+ imx_dma_setup_single(
+ drv_data->rx_channel,
+ drv_data->rx_dma,
+ drv_data->len,
+ drv_data->rd_data_phys,
+ DMA_MODE_READ);
+ imx_dma_enable(drv_data->rx_channel);
+
+ /* Enable SPI interrupt */
+ writel(SPI_INTEN_RO, regs + SPI_INT_STATUS);
+
+ /* Set SPI to request DMA service on both
+ Rx and Tx half fifo watermark */
+ writel(SPI_DMA_RHDEN | SPI_DMA_THDEN, regs + SPI_DMA);
+ } else
+ /* Write only access -> set SPI to request DMA
+ service on Tx half fifo watermark */
+ writel(SPI_DMA_THDEN, regs + SPI_DMA);
+
+ imx_dma_enable(drv_data->tx_channel);
+ } else {
+ dev_dbg(&drv_data->pdev->dev,
+ "pump pio transfer\n"
+ " tx = %p\n"
+ " rx = %p\n"
+ " len = %d\n",
+ drv_data->tx,
+ drv_data->rx,
+ drv_data->len);
+
+ /* Ensure we have the correct interrupt handler */
+ if (drv_data->rx)
+ drv_data->transfer_handler = interrupt_transfer;
+ else
+ drv_data->transfer_handler = interrupt_wronly_transfer;
+
+ /* Enable SPI interrupt */
+ if (drv_data->rx)
+ writel(SPI_INTEN_TH | SPI_INTEN_RO,
+ regs + SPI_INT_STATUS);
+ else
+ writel(SPI_INTEN_TH, regs + SPI_INT_STATUS);
+ }
+}
+
+static void pump_messages(struct work_struct *work)
+{
+ struct driver_data *drv_data =
+ container_of(work, struct driver_data, work);
+ unsigned long flags;
+
+ /* Lock queue and check for queue work */
+ spin_lock_irqsave(&drv_data->lock, flags);
+ if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) {
+ drv_data->busy = 0;
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ return;
+ }
+
+ /* Make sure we are not already running a message */
+ if (drv_data->cur_msg) {
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ return;
+ }
+
+ /* Extract head of queue */
+ drv_data->cur_msg = list_entry(drv_data->queue.next,
+ struct spi_message, queue);
+ list_del_init(&drv_data->cur_msg->queue);
+ drv_data->busy = 1;
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+
+ /* Initial message state */
+ drv_data->cur_msg->state = START_STATE;
+ drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
+ struct spi_transfer,
+ transfer_list);
+
+ /* Setup the SPI using the per chip configuration */
+ drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
+ restore_state(drv_data);
+
+ /* Mark as busy and launch transfers */
+ tasklet_schedule(&drv_data->pump_transfers);
+}
+
+static int transfer(struct spi_device *spi, struct spi_message *msg)
+{
+ struct driver_data *drv_data = spi_master_get_devdata(spi->master);
+ u32 min_speed_hz, max_speed_hz, tmp;
+ struct spi_transfer *trans;
+ unsigned long flags;
+
+ msg->actual_length = 0;
+
+ /* Per transfer setup check */
+ min_speed_hz = spi_speed_hz(SPI_CONTROL_DATARATE_MIN);
+ max_speed_hz = spi->max_speed_hz;
+ list_for_each_entry(trans, &msg->transfers, transfer_list) {
+ tmp = trans->bits_per_word;
+ if (tmp > 16) {
+ dev_err(&drv_data->pdev->dev,
+ "message rejected : "
+ "invalid transfer bits_per_word (%d bits)\n",
+ tmp);
+ goto msg_rejected;
+ }
+ tmp = trans->speed_hz;
+ if (tmp) {
+ if (tmp < min_speed_hz) {
+ dev_err(&drv_data->pdev->dev,
+ "message rejected : "
+ "device min speed (%d Hz) exceeds "
+ "required transfer speed (%d Hz)\n",
+ min_speed_hz,
+ tmp);
+ goto msg_rejected;
+ } else if (tmp > max_speed_hz) {
+ dev_err(&drv_data->pdev->dev,
+ "message rejected : "
+ "transfer speed (%d Hz) exceeds "
+ "device max speed (%d Hz)\n",
+ tmp,
+ max_speed_hz);
+ goto msg_rejected;
+ }
+ }
+ }
+
+ /* Message accepted */
+ msg->status = -EINPROGRESS;
+ msg->state = START_STATE;
+
+ spin_lock_irqsave(&drv_data->lock, flags);
+ if (drv_data->run == QUEUE_STOPPED) {
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ return -ESHUTDOWN;
+ }
+
+ list_add_tail(&msg->queue, &drv_data->queue);
+ if (drv_data->run == QUEUE_RUNNING && !drv_data->busy)
+ queue_work(drv_data->workqueue, &drv_data->work);
+
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ return 0;
+
+msg_rejected:
+ /* Message rejected and not queued */
+ msg->status = -EINVAL;
+ msg->state = ERROR_STATE;
+ if (msg->complete)
+ msg->complete(msg->context);
+ return -EINVAL;
+}
+
+/* On first setup bad values must free chip_data memory since will cause
+ spi_new_device to fail. Bad value setup from protocol driver are simply not
+ applied and notified to the calling driver. */
+static int setup(struct spi_device *spi)
+{
+ struct spi_imx_chip *chip_info;
+ struct chip_data *chip;
+ int first_setup = 0;
+ u32 tmp;
+ int status = 0;
+
+ /* Get controller data */
+ chip_info = spi->controller_data;
+
+ /* Get controller_state */
+ chip = spi_get_ctldata(spi);
+ if (chip == NULL) {
+ first_setup = 1;
+
+ chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
+ if (!chip) {
+ dev_err(&spi->dev,
+ "setup - cannot allocate controller state");
+ return -ENOMEM;
+ }
+ chip->control = SPI_DEFAULT_CONTROL;
+
+ if (chip_info == NULL) {
+ /* spi_board_info.controller_data not is supplied */
+ chip_info = kzalloc(sizeof(struct spi_imx_chip),
+ GFP_KERNEL);
+ if (!chip_info) {
+ dev_err(&spi->dev,
+ "setup - "
+ "cannot allocate controller data");
+ status = -ENOMEM;
+ goto err_first_setup;
+ }
+ /* Set controller data default value */
+ chip_info->enable_loopback =
+ SPI_DEFAULT_ENABLE_LOOPBACK;
+ chip_info->enable_dma = SPI_DEFAULT_ENABLE_DMA;
+ chip_info->ins_ss_pulse = 1;
+ chip_info->bclk_wait = SPI_DEFAULT_PERIOD_WAIT;
+ chip_info->cs_control = null_cs_control;
+ }
+ }
+
+ /* Now set controller state based on controller data */
+
+ if (first_setup) {
+ /* SPI loopback */
+ if (chip_info->enable_loopback)
+ chip->test = SPI_TEST_LBC;
+ else
+ chip->test = 0;
+
+ /* SPI dma driven */
+ chip->enable_dma = chip_info->enable_dma;
+
+ /* SPI /SS pulse between spi burst */
+ if (chip_info->ins_ss_pulse)
+ u32_EDIT(chip->control,
+ SPI_CONTROL_SSCTL, SPI_CONTROL_SSCTL_1);
+ else
+ u32_EDIT(chip->control,
+ SPI_CONTROL_SSCTL, SPI_CONTROL_SSCTL_0);
+
+ /* SPI bclk waits between each bits_per_word spi burst */
+ if (chip_info->bclk_wait > SPI_PERIOD_MAX_WAIT) {
+ dev_err(&spi->dev,
+ "setup - "
+ "bclk_wait exceeds max allowed (%d)\n",
+ SPI_PERIOD_MAX_WAIT);
+ goto err_first_setup;
+ }
+ chip->period = SPI_PERIOD_CSRC_BCLK |
+ (chip_info->bclk_wait & SPI_PERIOD_WAIT);
+ }
+
+ /* SPI mode */
+ tmp = spi->mode;
+ if (tmp & SPI_LSB_FIRST) {
+ status = -EINVAL;
+ if (first_setup) {
+ dev_err(&spi->dev,
+ "setup - "
+ "HW doesn't support LSB first transfer\n");
+ goto err_first_setup;
+ } else {
+ dev_err(&spi->dev,
+ "setup - "
+ "HW doesn't support LSB first transfer, "
+ "default to MSB first\n");
+ spi->mode &= ~SPI_LSB_FIRST;
+ }
+ }
+ if (tmp & SPI_CS_HIGH) {
+ u32_EDIT(chip->control,
+ SPI_CONTROL_SSPOL, SPI_CONTROL_SSPOL_ACT_HIGH);
+ }
+ switch (tmp & SPI_MODE_3) {
+ case SPI_MODE_0:
+ tmp = 0;
+ break;
+ case SPI_MODE_1:
+ tmp = SPI_CONTROL_PHA_1;
+ break;
+ case SPI_MODE_2:
+ tmp = SPI_CONTROL_POL_ACT_LOW;
+ break;
+ default:
+ /* SPI_MODE_3 */
+ tmp = SPI_CONTROL_PHA_1 | SPI_CONTROL_POL_ACT_LOW;
+ break;
+ }
+ u32_EDIT(chip->control, SPI_CONTROL_POL | SPI_CONTROL_PHA, tmp);
+
+ /* SPI word width */
+ tmp = spi->bits_per_word;
+ if (tmp == 0) {
+ tmp = 8;
+ spi->bits_per_word = 8;
+ } else if (tmp > 16) {
+ status = -EINVAL;
+ dev_err(&spi->dev,
+ "setup - "
+ "invalid bits_per_word (%d)\n",
+ tmp);
+ if (first_setup)
+ goto err_first_setup;
+ else {
+ /* Undo setup using chip as backup copy */
+ tmp = chip->bits_per_word;
+ spi->bits_per_word = tmp;
+ }
+ }
+ chip->bits_per_word = tmp;
+ u32_EDIT(chip->control, SPI_CONTROL_BITCOUNT_MASK, tmp - 1);
+ chip->n_bytes = (tmp <= 8) ? 1 : 2;
+
+ /* SPI datarate */
+ tmp = spi_data_rate(spi->max_speed_hz);
+ if (tmp == SPI_CONTROL_DATARATE_BAD) {
+ status = -EINVAL;
+ dev_err(&spi->dev,
+ "setup - "
+ "HW min speed (%d Hz) exceeds required "
+ "max speed (%d Hz)\n",
+ spi_speed_hz(SPI_CONTROL_DATARATE_MIN),
+ spi->max_speed_hz);
+ if (first_setup)
+ goto err_first_setup;
+ else
+ /* Undo setup using chip as backup copy */
+ spi->max_speed_hz = chip->max_speed_hz;
+ } else {
+ u32_EDIT(chip->control, SPI_CONTROL_DATARATE, tmp);
+ /* Actual rounded max_speed_hz */
+ tmp = spi_speed_hz(tmp);
+ spi->max_speed_hz = tmp;
+ chip->max_speed_hz = tmp;
+ }
+
+ /* SPI chip-select management */
+ if (chip_info->cs_control)
+ chip->cs_control = chip_info->cs_control;
+ else
+ chip->cs_control = null_cs_control;
+
+ /* Save controller_state */
+ spi_set_ctldata(spi, chip);
+
+ /* Summary */
+ dev_dbg(&spi->dev,
+ "setup succeded\n"
+ " loopback enable = %s\n"
+ " dma enable = %s\n"
+ " insert /ss pulse = %s\n"
+ " period wait = %d\n"
+ " mode = %d\n"
+ " bits per word = %d\n"
+ " min speed = %d Hz\n"
+ " rounded max speed = %d Hz\n",
+ chip->test & SPI_TEST_LBC ? "Yes" : "No",
+ chip->enable_dma ? "Yes" : "No",
+ chip->control & SPI_CONTROL_SSCTL ? "Yes" : "No",
+ chip->period & SPI_PERIOD_WAIT,
+ spi->mode,
+ spi->bits_per_word,
+ spi_speed_hz(SPI_CONTROL_DATARATE_MIN),
+ spi->max_speed_hz);
+
+err_first_setup:
+ kfree(chip);
+ return status;
+}
+
+static void cleanup(const struct spi_device *spi)
+{
+ struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
+ kfree(chip);
+}
+
+static int init_queue(struct driver_data *drv_data)
+{
+ INIT_LIST_HEAD(&drv_data->queue);
+ spin_lock_init(&drv_data->lock);
+
+ drv_data->run = QUEUE_STOPPED;
+ drv_data->busy = 0;
+
+ tasklet_init(&drv_data->pump_transfers,
+ pump_transfers, (unsigned long)drv_data);
+
+ INIT_WORK(&drv_data->work, pump_messages);
+ drv_data->workqueue = create_singlethread_workqueue(
+ drv_data->master->cdev.dev->bus_id);
+ if (drv_data->workqueue == NULL)
+ return -EBUSY;
+
+ return 0;
+}
+
+static int start_queue(struct driver_data *drv_data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&drv_data->lock, flags);
+
+ if (drv_data->run == QUEUE_RUNNING || drv_data->busy) {
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ return -EBUSY;
+ }
+
+ drv_data->run = QUEUE_RUNNING;
+ drv_data->cur_msg = NULL;
+ drv_data->cur_transfer = NULL;
+ drv_data->cur_chip = NULL;
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+
+ queue_work(drv_data->workqueue, &drv_data->work);
+
+ return 0;
+}
+
+static int stop_queue(struct driver_data *drv_data)
+{
+ unsigned long flags;
+ unsigned limit = 500;
+ int status = 0;
+
+ spin_lock_irqsave(&drv_data->lock, flags);
+
+ /* This is a bit lame, but is optimized for the common execution path.
+ * A wait_queue on the drv_data->busy could be used, but then the common
+ * execution path (pump_messages) would be required to call wake_up or
+ * friends on every SPI message. Do this instead */
+ drv_data->run = QUEUE_STOPPED;
+ while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ msleep(10);
+ spin_lock_irqsave(&drv_data->lock, flags);
+ }
+
+ if (!list_empty(&drv_data->queue) || drv_data->busy)
+ status = -EBUSY;
+
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+
+ return status;
+}
+
+static int destroy_queue(struct driver_data *drv_data)
+{
+ int status;
+
+ status = stop_queue(drv_data);
+ if (status != 0)
+ return status;
+
+ if (drv_data->workqueue)
+ destroy_workqueue(drv_data->workqueue);
+
+ return 0;
+}
+
+static int spi_imx_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct spi_imx_master *platform_info;
+ struct spi_master *master;
+ struct driver_data *drv_data = NULL;
+ struct resource *res;
+ int irq, status = 0;
+
+ platform_info = dev->platform_data;
+ if (platform_info == NULL) {
+ dev_err(&pdev->dev, "probe - no platform data supplied\n");
+ status = -ENODEV;
+ goto err_no_pdata;
+ }
+
+ /* Allocate master with space for drv_data */
+ master = spi_alloc_master(dev, sizeof(struct driver_data));
+ if (!master) {
+ dev_err(&pdev->dev, "probe - cannot alloc spi_master\n");
+ status = -ENOMEM;
+ goto err_no_mem;
+ }
+ drv_data = spi_master_get_devdata(master);
+ drv_data->master = master;
+ drv_data->master_info = platform_info;
+ drv_data->pdev = pdev;
+
+ master->bus_num = pdev->id;
+ master->num_chipselect = platform_info->num_chipselect;
+ master->cleanup = cleanup;
+ master->setup = setup;
+ master->transfer = transfer;
+
+ drv_data->dummy_dma_buf = SPI_DUMMY_u32;
+
+ /* Find and map resources */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "probe - MEM resources not defined\n");
+ status = -ENODEV;
+ goto err_no_iores;
+ }
+ drv_data->ioarea = request_mem_region(res->start,
+ res->end - res->start + 1,
+ pdev->name);
+ if (drv_data->ioarea == NULL) {
+ dev_err(&pdev->dev, "probe - cannot reserve region\n");
+ status = -ENXIO;
+ goto err_no_iores;
+ }
+ drv_data->regs = ioremap(res->start, res->end - res->start + 1);
+ if (drv_data->regs == NULL) {
+ dev_err(&pdev->dev, "probe - cannot map IO\n");
+ status = -ENXIO;
+ goto err_no_iomap;
+ }
+ drv_data->rd_data_phys = (dma_addr_t)res->start;
+
+ /* Attach to IRQ */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "probe - IRQ resource not defined\n");
+ status = -ENODEV;
+ goto err_no_irqres;
+ }
+ status = request_irq(irq, spi_int, IRQF_DISABLED, dev->bus_id, drv_data);
+ if (status < 0) {
+ dev_err(&pdev->dev, "probe - cannot get IRQ (%d)\n", status);
+ goto err_no_irqres;
+ }
+
+ /* Setup DMA if requested */
+ drv_data->tx_channel = -1;
+ drv_data->rx_channel = -1;
+ if (platform_info->enable_dma) {
+ /* Get rx DMA channel */
+ status = imx_dma_request_by_prio(&drv_data->rx_channel,
+ "spi_imx_rx", DMA_PRIO_HIGH);
+ if (status < 0) {
+ dev_err(dev,
+ "probe - problem (%d) requesting rx channel\n",
+ status);
+ goto err_no_rxdma;
+ } else
+ imx_dma_setup_handlers(drv_data->rx_channel, NULL,
+ dma_err_handler, drv_data);
+
+ /* Get tx DMA channel */
+ status = imx_dma_request_by_prio(&drv_data->tx_channel,
+ "spi_imx_tx", DMA_PRIO_MEDIUM);
+ if (status < 0) {
+ dev_err(dev,
+ "probe - problem (%d) requesting tx channel\n",
+ status);
+ imx_dma_free(drv_data->rx_channel);
+ goto err_no_txdma;
+ } else
+ imx_dma_setup_handlers(drv_data->tx_channel,
+ dma_tx_handler, dma_err_handler,
+ drv_data);
+
+ /* Set request source and burst length for allocated channels */
+ switch (drv_data->pdev->id) {
+ case 1:
+ /* Using SPI1 */
+ RSSR(drv_data->rx_channel) = DMA_REQ_SPI1_R;
+ RSSR(drv_data->tx_channel) = DMA_REQ_SPI1_T;
+ break;
+ case 2:
+ /* Using SPI2 */
+ RSSR(drv_data->rx_channel) = DMA_REQ_SPI2_R;
+ RSSR(drv_data->tx_channel) = DMA_REQ_SPI2_T;
+ break;
+ default:
+ dev_err(dev, "probe - bad SPI Id\n");
+ imx_dma_free(drv_data->rx_channel);
+ imx_dma_free(drv_data->tx_channel);
+ status = -ENODEV;
+ goto err_no_devid;
+ }
+ BLR(drv_data->rx_channel) = SPI_DMA_BLR;
+ BLR(drv_data->tx_channel) = SPI_DMA_BLR;
+ }
+
+ /* Load default SPI configuration */
+ writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
+ writel(0, drv_data->regs + SPI_RESET);
+ writel(SPI_DEFAULT_CONTROL, drv_data->regs + SPI_CONTROL);
+
+ /* Initial and start queue */
+ status = init_queue(drv_data);
+ if (status != 0) {
+ dev_err(&pdev->dev, "probe - problem initializing queue\n");
+ goto err_init_queue;
+ }
+ status = start_queue(drv_data);
+ if (status != 0) {
+ dev_err(&pdev->dev, "probe - problem starting queue\n");
+ goto err_start_queue;
+ }
+
+ /* Register with the SPI framework */
+ platform_set_drvdata(pdev, drv_data);
+ status = spi_register_master(master);
+ if (status != 0) {
+ dev_err(&pdev->dev, "probe - problem registering spi master\n");
+ goto err_spi_register;
+ }
+
+ dev_dbg(dev, "probe succeded\n");
+ return 0;
+
+err_init_queue:
+err_start_queue:
+err_spi_register:
+ destroy_queue(drv_data);
+
+err_no_rxdma:
+err_no_txdma:
+err_no_devid:
+ free_irq(irq, drv_data);
+
+err_no_irqres:
+ iounmap(drv_data->regs);
+
+err_no_iomap:
+ release_resource(drv_data->ioarea);
+ kfree(drv_data->ioarea);
+
+err_no_iores:
+ spi_master_put(master);
+
+err_no_pdata:
+err_no_mem:
+ return status;
+}
+
+static int __devexit spi_imx_remove(struct platform_device *pdev)
+{
+ struct driver_data *drv_data = platform_get_drvdata(pdev);
+ int irq;
+ int status = 0;
+
+ if (!drv_data)
+ return 0;
+
+ tasklet_kill(&drv_data->pump_transfers);
+
+ /* Remove the queue */
+ status = destroy_queue(drv_data);
+ if (status != 0) {
+ dev_err(&pdev->dev, "queue remove failed (%d)\n", status);
+ return status;
+ }
+
+ /* Reset SPI */
+ writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
+ writel(0, drv_data->regs + SPI_RESET);
+
+ /* Release DMA */
+ if (drv_data->master_info->enable_dma) {
+ RSSR(drv_data->rx_channel) = 0;
+ RSSR(drv_data->tx_channel) = 0;
+ imx_dma_free(drv_data->tx_channel);
+ imx_dma_free(drv_data->rx_channel);
+ }
+
+ /* Release IRQ */
+ irq = platform_get_irq(pdev, 0);
+ if (irq >= 0)
+ free_irq(irq, drv_data);
+
+ /* Release map resources */
+ iounmap(drv_data->regs);
+ release_resource(drv_data->ioarea);
+ kfree(drv_data->ioarea);
+
+ /* Disconnect from the SPI framework */
+ spi_unregister_master(drv_data->master);
+ spi_master_put(drv_data->master);
+
+ /* Prevent double remove */
+ platform_set_drvdata(pdev, NULL);
+
+ dev_dbg(&pdev->dev, "remove succeded\n");
+
+ return 0;
+}
+
+static void spi_imx_shutdown(struct platform_device *pdev)
+{
+ struct driver_data *drv_data = platform_get_drvdata(pdev);
+
+ /* Reset SPI */
+ writel(SPI_RESET_START, drv_data->regs + SPI_RESET);
+ writel(0, drv_data->regs + SPI_RESET);
+
+ dev_dbg(&pdev->dev, "shutdown succeded\n");
+}
+
+#ifdef CONFIG_PM
+static int suspend_devices(struct device *dev, void *pm_message)
+{
+ pm_message_t *state = pm_message;
+
+ if (dev->power.power_state.event != state->event) {
+ dev_warn(dev, "pm state does not match request\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int spi_imx_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct driver_data *drv_data = platform_get_drvdata(pdev);
+ int status = 0;
+
+ status = stop_queue(drv_data);
+ if (status != 0) {
+ dev_warn(&pdev->dev, "suspend cannot stop queue\n");
+ return status;
+ }
+
+ dev_dbg(&pdev->dev, "suspended\n");
+
+ return 0;
+}
+
+static int spi_imx_resume(struct platform_device *pdev)
+{
+ struct driver_data *drv_data = platform_get_drvdata(pdev);
+ int status = 0;
+
+ /* Start the queue running */
+ status = start_queue(drv_data);
+ if (status != 0)
+ dev_err(&pdev->dev, "problem starting queue (%d)\n", status);
+ else
+ dev_dbg(&pdev->dev, "resumed\n");
+
+ return status;
+}
+#else
+#define spi_imx_suspend NULL
+#define spi_imx_resume NULL
+#endif /* CONFIG_PM */
+
+static struct platform_driver driver = {
+ .driver = {
+ .name = "imx-spi",
+ .bus = &platform_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = spi_imx_probe,
+ .remove = __devexit_p(spi_imx_remove),
+ .shutdown = spi_imx_shutdown,
+ .suspend = spi_imx_suspend,
+ .resume = spi_imx_resume,
+};
+
+static int __init spi_imx_init(void)
+{
+ return platform_driver_register(&driver);
+}
+module_init(spi_imx_init);
+
+static void __exit spi_imx_exit(void)
+{
+ platform_driver_unregister(&driver);
+}
+module_exit(spi_imx_exit);
+
+MODULE_AUTHOR("Andrea Paterniani, <a.paterniani@swapp-eng.it>");
+MODULE_DESCRIPTION("iMX SPI Contoller Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index fc3197273663..3d72aa5cfc71 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -626,10 +626,8 @@ static void do_softint(unsigned long private_)
if (!tty)
return;
- if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+ if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event))
tty_wakeup(tty);
- wake_up_interruptible(&tty->write_wait);
- }
}
static int zs_startup(struct dec_serial * info)
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index df4cc1fb5f68..71cb64e41a1b 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -648,9 +648,9 @@ static inline BYTE SLIC_GetState(IXJ *j)
return j->pld_slicr.bits.state;
}
-static BOOL SLIC_SetState(BYTE byState, IXJ *j)
+static bool SLIC_SetState(BYTE byState, IXJ *j)
{
- BOOL fRetVal = FALSE;
+ bool fRetVal = false;
if (j->cardtype == QTI_PHONECARD) {
if (j->flags.pcmciasct) {
@@ -659,14 +659,14 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
case PLD_SLIC_STATE_OC:
j->pslic.bits.powerdown = 1;
j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
- fRetVal = TRUE;
+ fRetVal = true;
break;
case PLD_SLIC_STATE_RINGING:
if (j->readers || j->writers) {
j->pslic.bits.powerdown = 0;
j->pslic.bits.ring0 = 1;
j->pslic.bits.ring1 = 0;
- fRetVal = TRUE;
+ fRetVal = true;
}
break;
case PLD_SLIC_STATE_OHT: /* On-hook transmit */
@@ -679,14 +679,14 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
j->pslic.bits.powerdown = 1;
}
j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
- fRetVal = TRUE;
+ fRetVal = true;
break;
case PLD_SLIC_STATE_APR: /* Active polarity reversal */
case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */
default:
- fRetVal = FALSE;
+ fRetVal = false;
break;
}
j->psccr.bits.dev = 3;
@@ -703,7 +703,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
j->pld_slicw.bits.c3 = 0;
j->pld_slicw.bits.b2en = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
+ fRetVal = true;
break;
case PLD_SLIC_STATE_RINGING:
j->pld_slicw.bits.c1 = 1;
@@ -711,7 +711,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
j->pld_slicw.bits.c3 = 0;
j->pld_slicw.bits.b2en = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
+ fRetVal = true;
break;
case PLD_SLIC_STATE_ACTIVE:
j->pld_slicw.bits.c1 = 0;
@@ -719,7 +719,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
j->pld_slicw.bits.c3 = 0;
j->pld_slicw.bits.b2en = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
+ fRetVal = true;
break;
case PLD_SLIC_STATE_OHT: /* On-hook transmit */
@@ -728,7 +728,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
j->pld_slicw.bits.c3 = 0;
j->pld_slicw.bits.b2en = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
+ fRetVal = true;
break;
case PLD_SLIC_STATE_TIPOPEN:
j->pld_slicw.bits.c1 = 0;
@@ -736,7 +736,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
j->pld_slicw.bits.c3 = 1;
j->pld_slicw.bits.b2en = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
+ fRetVal = true;
break;
case PLD_SLIC_STATE_STANDBY:
j->pld_slicw.bits.c1 = 1;
@@ -744,7 +744,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
j->pld_slicw.bits.c3 = 1;
j->pld_slicw.bits.b2en = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
+ fRetVal = true;
break;
case PLD_SLIC_STATE_APR: /* Active polarity reversal */
@@ -753,7 +753,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
j->pld_slicw.bits.c3 = 1;
j->pld_slicw.bits.b2en = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
+ fRetVal = true;
break;
case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */
@@ -762,10 +762,10 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
j->pld_slicw.bits.c3 = 1;
j->pld_slicw.bits.b2en = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- fRetVal = TRUE;
+ fRetVal = true;
break;
default:
- fRetVal = FALSE;
+ fRetVal = false;
break;
}
}
@@ -4969,7 +4969,8 @@ static int ixj_daa_cid_read(IXJ *j)
{
int i;
BYTES bytes;
- char CID[ALISDAA_CALLERID_SIZE], mContinue;
+ char CID[ALISDAA_CALLERID_SIZE];
+ bool mContinue;
char *pIn, *pOut;
if (!SCI_Prepare(j))
@@ -5013,7 +5014,7 @@ static int ixj_daa_cid_read(IXJ *j)
pIn = CID;
pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
- mContinue = 1;
+ mContinue = true;
while (mContinue) {
if ((pIn[1] & 0x03) == 0x01) {
pOut[0] = pIn[0];
@@ -5027,7 +5028,7 @@ static int ixj_daa_cid_read(IXJ *j)
if ((pIn[4] & 0xc0) == 0x40) {
pOut[3] = ((pIn[4] & 0x3f) << 2) | ((pIn[3] & 0xc0) >> 6);
} else {
- mContinue = FALSE;
+ mContinue = false;
}
pIn += 5, pOut += 4;
}
@@ -6662,7 +6663,7 @@ static int ixj_fasync(int fd, struct file *file_p, int mode)
return fasync_helper(fd, file_p, mode, &j->async_queue);
}
-static struct file_operations ixj_fops =
+static const struct file_operations ixj_fops =
{
.owner = THIS_MODULE,
.read = ixj_enhanced_read,
@@ -7498,7 +7499,7 @@ static BYTE PCIEE_ReadBit(WORD wEEPROMAddress, BYTE lastLCC)
return ((inb(wEEPROMAddress) >> 3) & 1);
}
-static BOOL PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult)
+static bool PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult)
{
BYTE lastLCC;
WORD wEEPROMAddress = wAddress + 3;
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h
index 8d69bcdc29c9..4c32a43b7914 100644
--- a/drivers/telephony/ixj.h
+++ b/drivers/telephony/ixj.h
@@ -48,15 +48,11 @@
typedef __u16 WORD;
typedef __u32 DWORD;
typedef __u8 BYTE;
-typedef __u8 BOOL;
#ifndef IXJMAX
#define IXJMAX 16
#endif
-#define TRUE 1
-#define FALSE 0
-
/******************************************************************************
*
* This structure when unioned with the structures below makes simple byte
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c
index e41f49afd0f4..4d8c2a5b3297 100644
--- a/drivers/telephony/phonedev.c
+++ b/drivers/telephony/phonedev.c
@@ -127,7 +127,7 @@ void phone_unregister_device(struct phone_device *pfd)
}
-static struct file_operations phone_fops =
+static const struct file_operations phone_fops =
{
.owner = THIS_MODULE,
.open = phone_open,
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index f04a29a46646..c6b6479fa4dd 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -1953,7 +1953,7 @@ static void invalidate_sub(struct lun *curlun)
struct inode *inode = filp->f_path.dentry->d_inode;
unsigned long rc;
- rc = invalidate_inode_pages(inode->i_mapping);
+ rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
VLDBG(curlun, "invalidate_inode_pages -> %ld\n", rc);
}
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 408c3380d602..6ec8cf1a3ccb 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -1419,7 +1419,6 @@ int __devinit rndis_init (void)
return -EIO;
}
- rndis_connect_state [i]->nlink = 1;
rndis_connect_state [i]->write_proc = rndis_proc_write;
rndis_connect_state [i]->read_proc = rndis_proc_read;
rndis_connect_state [i]->data = (void *)
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index 282d82efc0b0..f0ffb8907f29 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -2163,9 +2163,8 @@ static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid)
maxlen = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
- sb_desc = (USB_SB_Desc_t*)kmem_cache_alloc(usb_desc_cache, SLAB_FLAG);
+ sb_desc = kmem_cache_zalloc(usb_desc_cache, SLAB_FLAG);
assert(sb_desc != NULL);
- memset(sb_desc, 0, sizeof(USB_SB_Desc_t));
if (usb_pipeout(urb->pipe)) {
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 2cbb239e63f8..68e66b33e726 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -624,12 +624,10 @@ static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci,
{
struct urb_priv *urbp;
- urbp = kmem_cache_alloc(uhci_up_cachep, GFP_ATOMIC);
+ urbp = kmem_cache_zalloc(uhci_up_cachep, GFP_ATOMIC);
if (!urbp)
return NULL;
- memset((void *)urbp, 0, sizeof(*urbp));
-
urbp->urb = urb;
urb->hcpriv = urbp;
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c
index 5d145058a5cb..bc7f8e6f8c97 100644
--- a/drivers/usb/input/hid-ff.c
+++ b/drivers/usb/input/hid-ff.c
@@ -57,6 +57,7 @@ static struct hid_ff_initializer inits[] = {
{ 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
{ 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
{ 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
+ { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */
#endif
#ifdef CONFIG_PANTHERLORD_FF
{ 0x810, 0x0001, hid_plff_init },
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index 4f4fc3be192e..4df0968f852e 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -52,6 +52,7 @@ static const struct dev_type devices[] = {
{ 0x046d, 0xc211, ff_rumble },
{ 0x046d, 0xc219, ff_rumble },
{ 0x046d, 0xc283, ff_joystick },
+ { 0x046d, 0xca03, ff_joystick },
{ 0x0000, 0x0000, ff_joystick }
};
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index af2934e016a7..75bfab95ab3c 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -644,7 +644,7 @@ exit:
}
/* file operations needed when we register this driver */
-static struct file_operations adu_fops = {
+static const struct file_operations adu_fops = {
.owner = THIS_MODULE,
.read = adu_read,
.write = adu_write,
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index a7932a72d298..32f0e3a5b022 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -281,8 +281,8 @@ static int appledisplay_probe(struct usb_interface *iface,
/* Register backlight device */
snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
atomic_inc_return(&count_displays) - 1);
- pdata->bd = backlight_device_register(bl_name, NULL, NULL,
- &appledisplay_bl_data);
+ pdata->bd = backlight_device_register(bl_name, NULL,
+ pdata, &appledisplay_bl_data);
if (IS_ERR(pdata->bd)) {
err("appledisplay: Backlight registration failed");
goto error;
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 41c0161abdb9..0c1d66ddb812 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -1209,7 +1209,7 @@ error_1:
return retval;
}
-static struct file_operations ftdi_elan_fops = {
+static const struct file_operations ftdi_elan_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.ioctl = ftdi_elan_ioctl,
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 0b0fb51bad3e..d78692c01cfa 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -616,15 +616,7 @@ static void digi_wakeup_write_lock(struct work_struct *work)
static void digi_wakeup_write( struct usb_serial_port *port )
{
-
- struct tty_struct *tty = port->tty;
-
-
- /* wake up port processes */
- wake_up_interruptible( &port->write_wait );
-
- /* wake up line discipline */
- tty_wakeup(tty);
+ tty_wakeup(port->tty);
}
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index da514cb785b3..dd0b66a6ed5d 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -182,13 +182,8 @@ static void keyspan_pda_wakeup_write(struct work_struct *work)
struct keyspan_pda_private *priv =
container_of(work, struct keyspan_pda_private, wakeup_work);
struct usb_serial_port *port = priv->port;
- struct tty_struct *tty = port->tty;
- /* wake up port processes */
- wake_up_interruptible( &port->write_wait );
-
- /* wake up line discipline */
- tty_wakeup(tty);
+ tty_wakeup(port->tty);
}
static void keyspan_pda_request_unthrottle(struct work_struct *work)
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 6109c6704a73..2d588fb82573 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -269,18 +269,8 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
tty = mos7720_port->port->tty;
- if (tty && mos7720_port->open) {
- /* let the tty driver wakeup if it has a special *
- * write_wakeup function */
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
- tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup)(tty);
-
- /* tell the tty driver that something has changed */
- wake_up_interruptible(&tty->write_wait);
- }
-
- /* schedule_work(&mos7720_port->port->work); */
+ if (tty && mos7720_port->open)
+ tty_wakeup(tty);
}
/*
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index b2264a87617b..c6cca859af45 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -755,18 +755,8 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
tty = mos7840_port->port->tty;
- if (tty && mos7840_port->open) {
- /* let the tty driver wakeup if it has a special *
- * write_wakeup function */
-
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
- && tty->ldisc.write_wakeup) {
- (tty->ldisc.write_wakeup) (tty);
- }
-
- /* tell the tty driver that something has changed */
- wake_up_interruptible(&tty->write_wait);
- }
+ if (tty && mos7840_port->open)
+ tty_wakeup(tty);
}
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 45fe65d8d7a0..8874cf2fd279 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -85,6 +85,14 @@ config FB_CFB_IMAGEBLIT
blitting. This is used by drivers that don't provide their own
(accelerated) version.
+config FB_SVGALIB
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Common utility functions useful to fbdev drivers of VGA-based
+ cards.
+
config FB_MACMODES
tristate
depends on FB
@@ -346,42 +354,6 @@ config FB_AMIGA_AGA
and CD32. If you intend to run Linux on any of these systems, say Y;
otherwise say N.
-config FB_CYBER
- tristate "Amiga CyberVision 64 support"
- depends on FB && ZORRO && BROKEN
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This enables support for the Cybervision 64 graphics card from
- Phase5. Please note that its use is not all that intuitive (i.e. if
- you have any questions, be sure to ask!). Say N unless you have a
- Cybervision 64 or plan to get one before you next recompile the
- kernel. Please note that this driver DOES NOT support the
- Cybervision 64/3D card, as they use incompatible video chips.
-
-config FB_VIRGE
- bool "Amiga CyberVision 64/3D support "
- depends on (FB = y) && ZORRO && BROKEN
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This enables support for the Cybervision 64/3D graphics card from
- Phase5. Please note that its use is not all that intuitive (i.e. if
- you have any questions, be sure to ask!). Say N unless you have a
- Cybervision 64/3D or plan to get one before you next recompile the
- kernel. Please note that this driver DOES NOT support the older
- Cybervision 64 card, as they use incompatible video chips.
-
-config FB_RETINAZ3
- tristate "Amiga Retina Z3 support"
- depends on (FB = y) && ZORRO && BROKEN
- help
- This enables support for the Retina Z3 graphics card. Say N unless
- you have a Retina Z3 or plan to get one before you next recompile
- the kernel.
-
config FB_FM2
bool "Amiga FrameMaster II/Rainbow II support"
depends on (FB = y) && ZORRO
@@ -617,10 +589,6 @@ config FB_GBE_MEM
This is the amount of memory reserved for the framebuffer,
which can be any value between 1MB and 8MB.
-config FB_SUN3
- bool "Sun3 framebuffer support"
- depends on (FB = y) && (SUN3 || SUN3X) && BROKEN
-
config FB_SBUS
bool "SBUS and UPA framebuffers"
depends on (FB = y) && SPARC
@@ -629,7 +597,7 @@ config FB_SBUS
config FB_BW2
bool "BWtwo support"
- depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+ depends on (FB = y) && (SPARC && FB_SBUS)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -638,7 +606,7 @@ config FB_BW2
config FB_CG3
bool "CGthree support"
- depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+ depends on (FB = y) && (SPARC && FB_SBUS)
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -647,7 +615,7 @@ config FB_CG3
config FB_CG6
bool "CGsix (GX,TurboGX) support"
- depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+ depends on (FB = y) && (SPARC && FB_SBUS)
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
@@ -1141,11 +1109,16 @@ config FB_ATY_BACKLIGHT
help
Say Y here if you want to control the backlight of your display.
-config FB_S3TRIO
- bool "S3 Trio display support"
- depends on (FB = y) && PPC && BROKEN
- help
- If you have a S3 Trio say Y. Say N for S3 Virge.
+config FB_S3
+ tristate "S3 Trio/Virge support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_TILEBLITTING
+ select FB_SVGALIB
+ ---help---
+ Driver for graphics boards with S3 Trio / S3 Virge chip.
config FB_SAVAGE
tristate "S3 Savage support"
@@ -1625,6 +1598,26 @@ config FB_IBM_GXT4500
Say Y here to enable support for the IBM GXT4500P display
adaptor, found on some IBM System P (pSeries) machines.
+config FB_PS3
+ bool "PS3 GPU framebuffer driver"
+ depends on FB && PPC_PS3
+ select PS3_PS3AV
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Include support for the virtual frame buffer in the PS3 platform.
+
+config FB_PS3_DEFAULT_SIZE_M
+ int "PS3 default frame buffer size (in MiB)"
+ depends on FB_PS3
+ default 18
+ ---help---
+ This is the default size (in MiB) of the virtual frame buffer in
+ the PS3.
+ The default value can be overridden on the kernel command line
+ using the "ps3fb" option (e.g. "ps3fb=9M");
+
config FB_VIRTUAL
tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
depends on FB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 309a26dd164a..6801edff36d9 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -17,15 +17,14 @@ obj-$(CONFIG_SYSFS) += backlight/
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
+obj-$(CONFIG_FB_SVGALIB) += svgalib.o
obj-$(CONFIG_FB_MACMODES) += macmodes.o
obj-$(CONFIG_FB_DDC) += fb_ddc.o
# Hardware specific drivers go first
-obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o
obj-$(CONFIG_FB_ARC) += arcfb.o
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
-obj-$(CONFIG_FB_CYBER) += cyberfb.o
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
obj-$(CONFIG_FB_PM2) += pm2fb.o
obj-$(CONFIG_FB_PM3) += pm3fb.o
@@ -43,17 +42,16 @@ obj-$(CONFIG_FB_GEODE) += geode/
obj-$(CONFIG_FB_MBX) += mbx/
obj-$(CONFIG_FB_I810) += vgastate.o
obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
-obj-$(CONFIG_FB_VIRGE) += virgefb.o
obj-$(CONFIG_FB_3DFX) += tdfxfb.o
obj-$(CONFIG_FB_CONTROL) += controlfb.o
obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
obj-$(CONFIG_FB_CT65550) += chipsfb.o
obj-$(CONFIG_FB_IMSTT) += imsttfb.o
-obj-$(CONFIG_FB_S3TRIO) += S3triofb.o
obj-$(CONFIG_FB_FM2) += fm2fb.o
obj-$(CONFIG_FB_CYBLA) += cyblafb.o
obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
+obj-$(CONFIG_FB_S3) += s3fb.o vgastate.o
obj-$(CONFIG_FB_STI) += stifb.o
obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
@@ -75,7 +73,6 @@ obj-$(CONFIG_FB_TGA) += tgafb.o
obj-$(CONFIG_FB_HP300) += hpfb.o
obj-$(CONFIG_FB_G364) += g364fb.o
obj-$(CONFIG_FB_SA1100) += sa1100fb.o
-obj-$(CONFIG_FB_SUN3) += sun3fb.o
obj-$(CONFIG_FB_HIT) += hitfb.o
obj-$(CONFIG_FB_EPSON1355) += epson1355fb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
@@ -100,6 +97,7 @@ obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/
obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
+obj-$(CONFIG_FB_PS3) += ps3fb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_VESA) += vesafb.o
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
deleted file mode 100644
index b3717c8f1bc2..000000000000
--- a/drivers/video/S3triofb.c
+++ /dev/null
@@ -1,790 +0,0 @@
-/*
- * linux/drivers/video/S3Triofb.c -- Open Firmware based frame buffer device
- *
- * Copyright (C) 1997 Peter De Schrijver
- *
- * This driver is partly based on the PowerMac console driver:
- *
- * Copyright (C) 1996 Paul Mackerras
- *
- * and on the Open Firmware based frame buffer device:
- *
- * Copyright (C) 1997 Geert Uytterhoeven
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-/*
- Bugs : + OF dependencies should be removed.
- + This driver should be merged with the CyberVision driver. The
- CyberVision is a Zorro III implementation of the S3Trio64 chip.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/selection.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <linux/pci.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/s3blit.h>
-
-
-#define mem_in8(addr) in_8((void *)(addr))
-#define mem_in16(addr) in_le16((void *)(addr))
-#define mem_in32(addr) in_le32((void *)(addr))
-
-#define mem_out8(val, addr) out_8((void *)(addr), val)
-#define mem_out16(val, addr) out_le16((void *)(addr), val)
-#define mem_out32(val, addr) out_le32((void *)(addr), val)
-
-#define IO_OUT16VAL(v, r) (((v) << 8) | (r))
-
-static struct display disp;
-static struct fb_info fb_info;
-static struct { u_char red, green, blue, pad; } palette[256];
-static char s3trio_name[16] = "S3Trio ";
-static char *s3trio_base;
-
-static struct fb_fix_screeninfo fb_fix;
-static struct fb_var_screeninfo fb_var = { 0, };
-
-
- /*
- * Interface used by the world
- */
-
-static void __init s3triofb_of_init(struct device_node *dp);
-static int s3trio_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int s3trio_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int s3trio_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int s3trio_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-static int s3trio_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info);
-static int s3trio_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static void s3triofb_blank(int blank, struct fb_info *info);
-
- /*
- * Interface to the low level console driver
- */
-
-int s3triofb_init(void);
-static int s3triofbcon_switch(int con, struct fb_info *info);
-static int s3triofbcon_updatevar(int con, struct fb_info *info);
-
- /*
- * Text console acceleration
- */
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_trio8;
-#endif
-
- /*
- * Accelerated Functions used by the low level console driver
- */
-
-static void Trio_WaitQueue(u_short fifo);
-static void Trio_WaitBlit(void);
-static void Trio_BitBLT(u_short curx, u_short cury, u_short destx,
- u_short desty, u_short width, u_short height,
- u_short mode);
-static void Trio_RectFill(u_short x, u_short y, u_short width, u_short height,
- u_short mode, u_short color);
-static void Trio_MoveCursor(u_short x, u_short y);
-
-
- /*
- * Internal routines
- */
-
-static int s3trio_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info);
-
-static struct fb_ops s3trio_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = s3trio_get_fix,
- .fb_get_var = s3trio_get_var,
- .fb_set_var = s3trio_set_var,
- .fb_get_cmap = s3trio_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = s3trio_setcolreg,
- .fb_pan_display =s3trio_pan_display,
- .fb_blank = s3triofb_blank,
-};
-
- /*
- * Get the Fixed Part of the Display
- */
-
-static int s3trio_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- memcpy(fix, &fb_fix, sizeof(fb_fix));
- return 0;
-}
-
-
- /*
- * Get the User Defined Part of the Display
- */
-
-static int s3trio_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- memcpy(var, &fb_var, sizeof(fb_var));
- return 0;
-}
-
-
- /*
- * Set the User Defined Part of the Display
- */
-
-static int s3trio_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- if (var->xres > fb_var.xres || var->yres > fb_var.yres ||
- var->bits_per_pixel > fb_var.bits_per_pixel )
- /* || var->nonstd || var->vmode != FB_VMODE_NONINTERLACED) */
- return -EINVAL;
- if (var->xres_virtual > fb_var.xres_virtual) {
- outw(IO_OUT16VAL((var->xres_virtual /8) & 0xff, 0x13), 0x3d4);
- outw(IO_OUT16VAL(((var->xres_virtual /8 ) & 0x300) >> 3, 0x51), 0x3d4);
- fb_var.xres_virtual = var->xres_virtual;
- fb_fix.line_length = var->xres_virtual;
- }
- fb_var.yres_virtual = var->yres_virtual;
- memcpy(var, &fb_var, sizeof(fb_var));
- return 0;
-}
-
-
- /*
- * Pan or Wrap the Display
- *
- * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
- */
-
-static int s3trio_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- unsigned int base;
-
- if (var->xoffset > (var->xres_virtual - var->xres))
- return -EINVAL;
- if (var->yoffset > (var->yres_virtual - var->yres))
- return -EINVAL;
-
- fb_var.xoffset = var->xoffset;
- fb_var.yoffset = var->yoffset;
-
- base = var->yoffset * fb_fix.line_length + var->xoffset;
-
- outw(IO_OUT16VAL((base >> 8) & 0xff, 0x0c),0x03D4);
- outw(IO_OUT16VAL(base & 0xff, 0x0d),0x03D4);
- outw(IO_OUT16VAL((base >> 16) & 0xf, 0x69),0x03D4);
- return 0;
-}
-
-
- /*
- * Get the Colormap
- */
-
-static int s3trio_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- if (con == info->currcon) /* current console? */
- return fb_get_cmap(cmap, kspc, s3trio_getcolreg, info);
- else if (fb_display[con].cmap.len) /* non default colormap? */
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap(fb_default_cmap(1 << fb_display[con].var.bits_per_pixel),
- cmap, kspc ? 0 : 2);
- return 0;
-}
-
-int __init s3triofb_init(void)
-{
- struct device_node *dp;
-
- dp = find_devices("S3Trio");
- if (dp != 0)
- s3triofb_of_init(dp);
- return 0;
-}
-
-void __init s3trio_resetaccel(void){
-
-
-#define EC01_ENH_ENB 0x0005
-#define EC01_LAW_ENB 0x0010
-#define EC01_MMIO_ENB 0x0020
-
-#define EC00_RESET 0x8000
-#define EC00_ENABLE 0x4000
-#define MF_MULT_MISC 0xE000
-#define SRC_FOREGROUND 0x0020
-#define SRC_BACKGROUND 0x0000
-#define MIX_SRC 0x0007
-#define MF_T_CLIP 0x1000
-#define MF_L_CLIP 0x2000
-#define MF_B_CLIP 0x3000
-#define MF_R_CLIP 0x4000
-#define MF_PIX_CONTROL 0xA000
-#define MFA_SRC_FOREGR_MIX 0x0000
-#define MF_PIX_CONTROL 0xA000
-
- outw(EC00_RESET, 0x42e8);
- inw( 0x42e8);
- outw(EC00_ENABLE, 0x42e8);
- inw( 0x42e8);
- outw(EC01_ENH_ENB | EC01_LAW_ENB,
- 0x4ae8);
- outw(MF_MULT_MISC, 0xbee8); /* 16 bit I/O registers */
-
- /* Now set some basic accelerator registers */
- Trio_WaitQueue(0x0400);
- outw(SRC_FOREGROUND | MIX_SRC, 0xbae8);
- outw(SRC_BACKGROUND | MIX_SRC, 0xb6e8);/* direct color*/
- outw(MF_T_CLIP | 0, 0xbee8 ); /* clip virtual area */
- outw(MF_L_CLIP | 0, 0xbee8 );
- outw(MF_R_CLIP | (640 - 1), 0xbee8);
- outw(MF_B_CLIP | (480 - 1), 0xbee8);
- Trio_WaitQueue(0x0400);
- outw(0xffff, 0xaae8); /* Enable all planes */
- outw(0xffff, 0xaae8); /* Enable all planes */
- outw( MF_PIX_CONTROL | MFA_SRC_FOREGR_MIX, 0xbee8);
-}
-
-int __init s3trio_init(struct device_node *dp){
-
- u_char bus, dev;
- unsigned int t32;
- unsigned short cmd;
-
- pci_device_loc(dp,&bus,&dev);
- pcibios_read_config_dword(bus, dev, PCI_VENDOR_ID, &t32);
- if(t32 == (PCI_DEVICE_ID_S3_TRIO << 16) + PCI_VENDOR_ID_S3) {
- pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
- pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_1, &t32);
- pcibios_read_config_word(bus, dev, PCI_COMMAND,&cmd);
-
- pcibios_write_config_word(bus, dev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-
- pcibios_write_config_dword(bus, dev, PCI_BASE_ADDRESS_0,0xffffffff);
- pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
-
-/* This is a gross hack as OF only maps enough memory for the framebuffer and
- we want to use MMIO too. We should find out which chunk of address space
- we can use here */
- pcibios_write_config_dword(bus,dev,PCI_BASE_ADDRESS_0,0xc6000000);
-
- /* unlock s3 */
-
- outb(0x01, 0x3C3);
-
- outb(inb(0x03CC) | 1, 0x3c2);
-
- outw(IO_OUT16VAL(0x48, 0x38),0x03D4);
- outw(IO_OUT16VAL(0xA0, 0x39),0x03D4);
- outb(0x33,0x3d4);
- outw(IO_OUT16VAL((inb(0x3d5) & ~(0x2 | 0x10 | 0x40)) |
- 0x20, 0x33), 0x3d4);
-
- outw(IO_OUT16VAL(0x6, 0x8), 0x3c4);
-
- /* switch to MMIO only mode */
-
- outb(0x58, 0x3d4);
- outw(IO_OUT16VAL(inb(0x3d5) | 3 | 0x10, 0x58), 0x3d4);
- outw(IO_OUT16VAL(8, 0x53), 0x3d4);
-
- /* switch off I/O accesses */
-
-#if 0
- pcibios_write_config_word(bus, dev, PCI_COMMAND,
- PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-#endif
- return 1;
- }
-
- return 0;
-}
-
-
- /*
- * Initialisation
- * We heavily rely on OF for the moment. This needs fixing.
- */
-
-static void __init s3triofb_of_init(struct device_node *dp)
-{
- int i, *pp, len;
- unsigned long address, size;
- u_long *CursorBase;
-
- strncat(s3trio_name, dp->name, sizeof(s3trio_name));
- s3trio_name[sizeof(s3trio_name)-1] = '\0';
- strcpy(fb_fix.id, s3trio_name);
-
- if((pp = get_property(dp, "vendor-id", &len)) != NULL
- && *pp!=PCI_VENDOR_ID_S3) {
- printk("%s: can't find S3 Trio board\n", dp->full_name);
- return;
- }
-
- if((pp = get_property(dp, "device-id", &len)) != NULL
- && *pp!=PCI_DEVICE_ID_S3_TRIO) {
- printk("%s: can't find S3 Trio board\n", dp->full_name);
- return;
- }
-
- if ((pp = get_property(dp, "depth", &len)) != NULL
- && len == sizeof(int) && *pp != 8) {
- printk("%s: can't use depth = %d\n", dp->full_name, *pp);
- return;
- }
- if ((pp = get_property(dp, "width", &len)) != NULL
- && len == sizeof(int))
- fb_var.xres = fb_var.xres_virtual = *pp;
- if ((pp = get_property(dp, "height", &len)) != NULL
- && len == sizeof(int))
- fb_var.yres = fb_var.yres_virtual = *pp;
- if ((pp = get_property(dp, "linebytes", &len)) != NULL
- && len == sizeof(int))
- fb_fix.line_length = *pp;
- else
- fb_fix.line_length = fb_var.xres_virtual;
- fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
-
- address = 0xc6000000;
- size = 64*1024*1024;
- if (!request_mem_region(address, size, "S3triofb"))
- return;
-
- s3trio_init(dp);
- s3trio_base = ioremap(address, size);
- fb_fix.smem_start = address;
- fb_fix.type = FB_TYPE_PACKED_PIXELS;
- fb_fix.type_aux = 0;
- fb_fix.accel = FB_ACCEL_S3_TRIO64;
- fb_fix.mmio_start = address+0x1000000;
- fb_fix.mmio_len = 0x1000000;
-
- fb_fix.xpanstep = 1;
- fb_fix.ypanstep = 1;
-
- s3trio_resetaccel();
-
- mem_out8(0x30, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0x2d, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0x2e, s3trio_base+0x1008000 + 0x03D4);
-
- mem_out8(0x50, s3trio_base+0x1008000 + 0x03D4);
-
- /* disable HW cursor */
-
- mem_out8(0x39, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0xa0, s3trio_base+0x1008000 + 0x03D5);
-
- mem_out8(0x45, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
-
- mem_out8(0x4e, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
-
- mem_out8(0x4f, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
-
- /* init HW cursor */
-
- CursorBase = (u_long *)(s3trio_base + 2*1024*1024 - 0x400);
- for (i = 0; i < 8; i++) {
- *(CursorBase +(i*4)) = 0xffffff00;
- *(CursorBase+1+(i*4)) = 0xffff0000;
- *(CursorBase+2+(i*4)) = 0xffff0000;
- *(CursorBase+3+(i*4)) = 0xffff0000;
- }
- for (i = 8; i < 64; i++) {
- *(CursorBase +(i*4)) = 0xffff0000;
- *(CursorBase+1+(i*4)) = 0xffff0000;
- *(CursorBase+2+(i*4)) = 0xffff0000;
- *(CursorBase+3+(i*4)) = 0xffff0000;
- }
-
-
- mem_out8(0x4c, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(((2*1024 - 1)&0xf00)>>8, s3trio_base+0x1008000 + 0x03D5);
-
- mem_out8(0x4d, s3trio_base+0x1008000 + 0x03D4);
- mem_out8((2*1024 - 1) & 0xff, s3trio_base+0x1008000 + 0x03D5);
-
- mem_out8(0x45, s3trio_base+0x1008000 + 0x03D4);
- mem_in8(s3trio_base+0x1008000 + 0x03D4);
-
- mem_out8(0x4a, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0x80, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x80, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x80, s3trio_base+0x1008000 + 0x03D5);
-
- mem_out8(0x4b, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0x00, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x00, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x00, s3trio_base+0x1008000 + 0x03D5);
-
- mem_out8(0x45, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
-
- /* setup default color table */
-
- for(i = 0; i < 16; i++) {
- int j = color_table[i];
- palette[i].red=default_red[j];
- palette[i].green=default_grn[j];
- palette[i].blue=default_blu[j];
- }
-
- s3trio_setcolreg(255, 56, 100, 160, 0, NULL /* not used */);
- s3trio_setcolreg(254, 0, 0, 0, 0, NULL /* not used */);
- memset((char *)s3trio_base, 0, 640*480);
-
-#if 0
- Trio_RectFill(0, 0, 90, 90, 7, 1);
-#endif
-
- fb_fix.visual = FB_VISUAL_PSEUDOCOLOR ;
- fb_var.xoffset = fb_var.yoffset = 0;
- fb_var.bits_per_pixel = 8;
- fb_var.grayscale = 0;
- fb_var.red.offset = fb_var.green.offset = fb_var.blue.offset = 0;
- fb_var.red.length = fb_var.green.length = fb_var.blue.length = 8;
- fb_var.red.msb_right = fb_var.green.msb_right = fb_var.blue.msb_right = 0;
- fb_var.transp.offset = fb_var.transp.length = fb_var.transp.msb_right = 0;
- fb_var.nonstd = 0;
- fb_var.activate = 0;
- fb_var.height = fb_var.width = -1;
- fb_var.accel_flags = FB_ACCELF_TEXT;
-#warning FIXME: always obey fb_var.accel_flags
- fb_var.pixclock = 1;
- fb_var.left_margin = fb_var.right_margin = 0;
- fb_var.upper_margin = fb_var.lower_margin = 0;
- fb_var.hsync_len = fb_var.vsync_len = 0;
- fb_var.sync = 0;
- fb_var.vmode = FB_VMODE_NONINTERLACED;
-
- disp.var = fb_var;
- disp.cmap.start = 0;
- disp.cmap.len = 0;
- disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
- disp.visual = fb_fix.visual;
- disp.type = fb_fix.type;
- disp.type_aux = fb_fix.type_aux;
- disp.ypanstep = 0;
- disp.ywrapstep = 0;
- disp.line_length = fb_fix.line_length;
- disp.can_soft_blank = 1;
- disp.inverse = 0;
-#ifdef FBCON_HAS_CFB8
- if (fb_var.accel_flags & FB_ACCELF_TEXT)
- disp.dispsw = &fbcon_trio8;
- else
- disp.dispsw = &fbcon_cfb8;
-#else
- disp.dispsw = &fbcon_dummy;
-#endif
- disp.scrollmode = fb_var.accel_flags & FB_ACCELF_TEXT ? 0 : SCROLL_YREDRAW;
-
- strcpy(fb_info.modename, "Trio64 ");
- strncat(fb_info.modename, dp->full_name, sizeof(fb_info.modename));
- fb_info.currcon = -1;
- fb_info.fbops = &s3trio_ops;
- fb_info.screen_base = s3trio_base;
-#if 0
- fb_info.fbvar_num = 1;
- fb_info.fbvar = &fb_var;
-#endif
- fb_info.disp = &disp;
- fb_info.fontname[0] = '\0';
- fb_info.changevar = NULL;
- fb_info.switch_con = &s3triofbcon_switch;
- fb_info.updatevar = &s3triofbcon_updatevar;
-#if 0
- fb_info.setcmap = &s3triofbcon_setcmap;
-#endif
-
- fb_info.flags = FBINFO_FLAG_DEFAULT;
- if (register_framebuffer(&fb_info) < 0) {
- iounmap(fb_info.screen_base);
- fb_info.screen_base = NULL;
- return;
- }
-
- printk("fb%d: S3 Trio frame buffer device on %s\n",
- fb_info.node, dp->full_name);
-}
-
-
-static int s3triofbcon_switch(int con, struct fb_info *info)
-{
- /* Do we have to save the colormap? */
- if (fb_display[info->currcon].cmap.len)
- fb_get_cmap(&fb_display[info->currcon].cmap, 1, s3trio_getcolreg, info);
-
- info->currcon = con;
- /* Install new colormap */
- do_install_cmap(con,info);
- return 0;
-}
-
- /*
- * Update the `var' structure (called by fbcon.c)
- */
-
-static int s3triofbcon_updatevar(int con, struct fb_info *info)
-{
- /* Nothing */
- return 0;
-}
-
- /*
- * Blank the display.
- */
-
-static int s3triofb_blank(int blank, struct fb_info *info)
-{
- unsigned char x;
-
- mem_out8(0x1, s3trio_base+0x1008000 + 0x03c4);
- x = mem_in8(s3trio_base+0x1008000 + 0x03c5);
- mem_out8((x & (~0x20)) | (blank << 5), s3trio_base+0x1008000 + 0x03c5);
- return 0;
-}
-
- /*
- * Read a single color register and split it into
- * colors/transparent. Return != 0 for invalid regno.
- */
-
-static int s3trio_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info)
-{
- if (regno > 255)
- return 1;
- *red = (palette[regno].red << 8) | palette[regno].red;
- *green = (palette[regno].green << 8) | palette[regno].green;
- *blue = (palette[regno].blue << 8) | palette[regno].blue;
- *transp = 0;
- return 0;
-}
-
-
- /*
- * Set a single color register. Return != 0 for invalid regno.
- */
-
-static int s3trio_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
-{
- if (regno > 255)
- return 1;
-
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- palette[regno].red = red;
- palette[regno].green = green;
- palette[regno].blue = blue;
-
- mem_out8(regno,s3trio_base+0x1008000 + 0x3c8);
- mem_out8((red & 0xff) >> 2,s3trio_base+0x1008000 + 0x3c9);
- mem_out8((green & 0xff) >> 2,s3trio_base+0x1008000 + 0x3c9);
- mem_out8((blue & 0xff) >> 2,s3trio_base+0x1008000 + 0x3c9);
-
- return 0;
-}
-
-static void Trio_WaitQueue(u_short fifo) {
-
- u_short status;
-
- do
- {
- status = mem_in16(s3trio_base + 0x1000000 + 0x9AE8);
- } while (!(status & fifo));
-
-}
-
-static void Trio_WaitBlit(void) {
-
- u_short status;
-
- do
- {
- status = mem_in16(s3trio_base + 0x1000000 + 0x9AE8);
- } while (status & 0x200);
-
-}
-
-static void Trio_BitBLT(u_short curx, u_short cury, u_short destx,
- u_short desty, u_short width, u_short height,
- u_short mode) {
-
- u_short blitcmd = 0xc011;
-
- /* Set drawing direction */
- /* -Y, X maj, -X (default) */
-
- if (curx > destx)
- blitcmd |= 0x0020; /* Drawing direction +X */
- else {
- curx += (width - 1);
- destx += (width - 1);
- }
-
- if (cury > desty)
- blitcmd |= 0x0080; /* Drawing direction +Y */
- else {
- cury += (height - 1);
- desty += (height - 1);
- }
-
- Trio_WaitQueue(0x0400);
-
- outw(0xa000, 0xBEE8);
- outw(0x60 | mode, 0xBAE8);
-
- outw(curx, 0x86E8);
- outw(cury, 0x82E8);
-
- outw(destx, 0x8EE8);
- outw(desty, 0x8AE8);
-
- outw(height - 1, 0xBEE8);
- outw(width - 1, 0x96E8);
-
- outw(blitcmd, 0x9AE8);
-
-}
-
-static void Trio_RectFill(u_short x, u_short y, u_short width, u_short height,
- u_short mode, u_short color) {
-
- u_short blitcmd = 0x40b1;
-
- Trio_WaitQueue(0x0400);
-
- outw(0xa000, 0xBEE8);
- outw((0x20 | mode), 0xBAE8);
- outw(0xe000, 0xBEE8);
- outw(color, 0xA6E8);
- outw(x, 0x86E8);
- outw(y, 0x82E8);
- outw((height - 1), 0xBEE8);
- outw((width - 1), 0x96E8);
- outw(blitcmd, 0x9AE8);
-
-}
-
-
-static void Trio_MoveCursor(u_short x, u_short y) {
-
- mem_out8(0x39, s3trio_base + 0x1008000 + 0x3d4);
- mem_out8(0xa0, s3trio_base + 0x1008000 + 0x3d5);
-
- mem_out8(0x46, s3trio_base + 0x1008000 + 0x3d4);
- mem_out8((x & 0x0700) >> 8, s3trio_base + 0x1008000 + 0x3d5);
- mem_out8(0x47, s3trio_base + 0x1008000 + 0x3d4);
- mem_out8(x & 0x00ff, s3trio_base + 0x1008000 + 0x3d5);
-
- mem_out8(0x48, s3trio_base + 0x1008000 + 0x3d4);
- mem_out8((y & 0x0700) >> 8, s3trio_base + 0x1008000 + 0x3d5);
- mem_out8(0x49, s3trio_base + 0x1008000 + 0x3d4);
- mem_out8(y & 0x00ff, s3trio_base + 0x1008000 + 0x3d5);
-
-}
-
-
- /*
- * Text console acceleration
- */
-
-#ifdef FBCON_HAS_CFB8
-static void fbcon_trio8_bmove(struct display *p, int sy, int sx, int dy,
- int dx, int height, int width)
-{
- sx *= 8; dx *= 8; width *= 8;
- Trio_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
- (u_short)(dy*fontheight(p)), (u_short)width,
- (u_short)(height*fontheight(p)), (u_short)S3_NEW);
-}
-
-static void fbcon_trio8_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- unsigned char bg;
-
- sx *= 8; width *= 8;
- bg = attr_bgcol_ec(p,conp);
- Trio_RectFill((u_short)sx,
- (u_short)(sy*fontheight(p)),
- (u_short)width,
- (u_short)(height*fontheight(p)),
- (u_short)S3_NEW,
- (u_short)bg);
-}
-
-static void fbcon_trio8_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx)
-{
- Trio_WaitBlit();
- fbcon_cfb8_putc(conp, p, c, yy, xx);
-}
-
-static void fbcon_trio8_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- Trio_WaitBlit();
- fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
-}
-
-static void fbcon_trio8_revc(struct display *p, int xx, int yy)
-{
- Trio_WaitBlit();
- fbcon_cfb8_revc(p, xx, yy);
-}
-
-static struct display_switch fbcon_trio8 = {
- .setup = fbcon_cfb8_setup,
- .bmove = fbcon_trio8_bmove,
- .clear = fbcon_trio8_clear,
- .putc = fbcon_trio8_putc,
- .putcs = fbcon_trio8_putcs,
- .revc = fbcon_trio8_revc,
- .clear_margins = fbcon_cfb8_clear_margins,
- .fontwidthmask = FONTWIDTH(8)
-};
-#endif
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index f2ebdd880085..301612cef354 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2566,7 +2566,7 @@ static int __devinit aty_init(struct fb_info *info)
info->fix.smem_len == 0x80000 ? 'K' : 'M', ramname, xtal, par->pll_limits.pll_max,
par->pll_limits.mclk, par->pll_limits.xclk);
-#if defined(DEBUG) && defined(CONFIG_ATY_CT)
+#if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)
if (M64_HAS(INTEGRATED)) {
int i;
printk("debug atyfb: BUS_CNTL DAC_CNTL MEM_CNTL EXT_MEM_CNTL CRTC_GEN_CNTL "
@@ -2957,8 +2957,6 @@ extern void (*prom_palette) (int);
static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
struct fb_info *info, unsigned long addr)
{
- extern int con_is_present(void);
-
struct atyfb_par *par = info->par;
struct pcidev_cookie *pcp;
char prop[128];
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index ef5c16f7f5a6..80a81eccad36 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -468,11 +468,10 @@ int au1100fb_drv_probe(struct device *dev)
return -EINVAL;
/* Allocate new device private */
- if (!(fbdev = kmalloc(sizeof(struct au1100fb_device), GFP_KERNEL))) {
+ if (!(fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL))) {
print_err("fail to allocate device private record");
return -ENOMEM;
}
- memset((void*)fbdev, 0, sizeof(struct au1100fb_device));
fbdev->panel = &known_lcd_panels[drv_info.panel_idx];
@@ -549,10 +548,9 @@ int au1100fb_drv_probe(struct device *dev)
fbdev->info.fbops = &au1100fb_ops;
fbdev->info.fix = au1100fb_fix;
- if (!(fbdev->info.pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL))) {
+ if (!(fbdev->info.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL))) {
return -ENOMEM;
}
- memset(fbdev->info.pseudo_palette, 0, sizeof(u32) * 16);
if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
print_err("Fail to allocate colormap (%d entries)",
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 31f476a64790..ce5ac268074e 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2071,7 +2071,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
y_diff = info->var.yres - var.yres;
if (x_diff < 0 || x_diff > virt_fw ||
y_diff < 0 || y_diff > virt_fh) {
- struct fb_videomode *mode;
+ const struct fb_videomode *mode;
DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
mode = fb_find_best_mode(&var, &info->modelist);
@@ -2975,7 +2975,7 @@ static void fbcon_new_modelist(struct fb_info *info)
int i;
struct vc_data *vc;
struct fb_var_screeninfo var;
- struct fb_videomode *mode;
+ const struct fb_videomode *mode;
for (i = first_fb_vc; i <= last_fb_vc; i++) {
if (registered_fb[con2fb_map[i]] != info)
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index b9386d168c04..71f24e00fcd0 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -48,7 +48,7 @@ struct display {
struct fb_bitfield green;
struct fb_bitfield blue;
struct fb_bitfield transp;
- struct fb_videomode *mode;
+ const struct fb_videomode *mode;
};
struct fbcon_ops {
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 04c6d928189b..fd60dba294da 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -696,11 +696,10 @@ static int __init control_of_init(struct device_node *dp)
printk(KERN_ERR "can't get 2 addresses for control\n");
return -ENXIO;
}
- p = kmalloc(sizeof(*p), GFP_KERNEL);
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
if (p == 0)
return -ENXIO;
control_fb = p; /* save it for cleanups */
- memset(p, 0, sizeof(*p));
/* Map in frame buffer and registers */
p->fb_orig_base = fb_res.start;
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index aae6d9c26e88..7a6eeda5ae9a 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1539,16 +1539,21 @@ static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
/*
* Allow the CyberPro to accept PCI burst accesses
*/
- val = cyber2000_grphr(EXT_BUS_CTL, cfb);
- if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
- printk(KERN_INFO "%s: enabling PCI bursts\n", cfb->fb.fix.id);
+ if (cfb->id == ID_CYBERPRO_2010) {
+ printk(KERN_INFO "%s: NOT enabling PCI bursts\n", cfb->fb.fix.id);
+ } else {
+ val = cyber2000_grphr(EXT_BUS_CTL, cfb);
+ if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
+ printk(KERN_INFO "%s: enabling PCI bursts\n",
+ cfb->fb.fix.id);
- val |= EXT_BUS_CTL_PCIBURST_WRITE;
+ val |= EXT_BUS_CTL_PCIBURST_WRITE;
- if (cfb->id == ID_CYBERPRO_5000)
- val |= EXT_BUS_CTL_PCIBURST_READ;
+ if (cfb->id == ID_CYBERPRO_5000)
+ val |= EXT_BUS_CTL_PCIBURST_READ;
- cyber2000_grphw(EXT_BUS_CTL, val, cfb);
+ cyber2000_grphw(EXT_BUS_CTL, val, cfb);
+ }
}
return 0;
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
deleted file mode 100644
index 0b8d5b121152..000000000000
--- a/drivers/video/cyberfb.c
+++ /dev/null
@@ -1,2295 +0,0 @@
-/*
-* linux/drivers/video/cyberfb.c -- CyberVision64 frame buffer device
-* $Id: cyberfb.c,v 1.6 1998/09/11 04:54:58 abair Exp $
-*
-* Copyright (C) 1998 Alan Bair
-*
-* This file is based on two CyberVision64 frame buffer device drivers
-*
-* The second CyberVision64 frame buffer device (cvision.c cvision_core.c):
-*
-* Copyright (c) 1997 Antonio Santos
-*
-* Released as a patch to 2.1.35, but never included in the source tree.
-* This is based on work from the NetBSD CyberVision64 frame buffer driver
-* and support files (grf_cv.c, grf_cvreg.h, ite_cv.c):
-* Permission to use the source of this driver was obtained from the
-* author Michael Teske by Alan Bair.
-*
-* Copyright (c) 1995 Michael Teske
-*
-* The first CyberVision64 frame buffer device (cyberfb.c):
-*
-* Copyright (C) 1996 Martin Apel
-* Geert Uytterhoeven
-*
-* Which is based on the Amiga frame buffer device (amifb.c):
-*
-* Copyright (C) 1995 Geert Uytterhoeven
-*
-*
-* History:
-* - 22 Dec 95: Original version by Martin Apel
-* - 05 Jan 96: Geert: integration into the current source tree
-* - 01 Aug 98: Alan: Merge in code from cvision.c and cvision_core.c
-* $Log: cyberfb.c,v $
-* Revision 1.6 1998/09/11 04:54:58 abair
-* Update for 2.1.120 change in include file location.
-* Clean up for public release.
-*
-* Revision 1.5 1998/09/03 04:27:13 abair
-* Move cv64_load_video_mode to cyber_set_video so a new video mode is install
-* with each change of the 'var' data.
-*
-* Revision 1.4 1998/09/01 00:31:17 abair
-* Put in a set of default 8,16,24 bpp modes and map cyber8,16 to them.
-* Update operations with 'par' to handle a more complete set of parameter
-* values for encode/decode process.
-*
-* Revision 1.3 1998/08/31 21:31:33 abair
-* Swap 800x490 for 640x480 video mode and more cleanup.
-* Abandon idea to resurrect "custom" mode setting via kernel opts,
-* instead work on making use of fbset program to do this.
-*
-* Revision 1.2 1998/08/31 06:17:08 abair
-* Make updates for changes in cyberfb.c released in 2.1.119
-* and do some cleanup of the code.
-*
-* Revision 1.1 1998/08/29 18:38:31 abair
-* Initial revision
-*
-* Revision 1.3 1998/08/17 06:21:53 abair
-* Remove more redundant code after merging in cvision_core.c
-* Set blanking by colormap to pale red to detect this vs trying to
-* use video blanking. More formating to Linux code style.
-*
-* Revision 1.2 1998/08/15 17:51:37 abair
-* Added cvision_core.c code from 2.1.35 patches.
-* Changed to compile correctly and switch to using initialization
-* code. Added debugging and dropping of duplicate code.
-*
-*
-*
-* This file is subject to the terms and conditions of the GNU General Public
-* License. See the file COPYING in the main directory of this archive
-* for more details.
-*/
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/zorro.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
-#include <asm/amigahw.h>
-#include <asm/io.h>
-
-#include "cyberfb.h"
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-
-/*#define CYBERFBDEBUG*/
-#ifdef CYBERFBDEBUG
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
-static void cv64_dump(void);
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
-#define wb_64(regs,reg,dat) (*(((volatile unsigned char *)regs) + reg) = dat)
-#define rb_64(regs, reg) (*(((volatile unsigned char *)regs) + reg))
-
-struct cyberfb_par {
- struct fb_var_screeninfo var;
- __u32 type;
- __u32 type_aux;
- __u32 visual;
- __u32 line_length;
-};
-
-static struct cyberfb_par current_par;
-
-static int current_par_valid = 0;
-
-static struct display disp;
-static struct fb_info fb_info;
-
-
-/*
- * Frame Buffer Name
- */
-
-static char cyberfb_name[16] = "Cybervision";
-
-
-/*
- * CyberVision Graphics Board
- */
-
-static unsigned char Cyber_colour_table [256][3];
-static unsigned long CyberSize;
-static volatile unsigned char *CyberBase;
-static volatile unsigned char *CyberMem;
-static volatile unsigned char *CyberRegs;
-static unsigned long CyberMem_phys;
-static unsigned long CyberRegs_phys;
-
-/*
- * Predefined Video Modes
- */
-
-static struct {
- const char *name;
- struct fb_var_screeninfo var;
-} cyberfb_predefined[] __initdata = {
- { "640x480-8", { /* Default 8 BPP mode (cyber8) */
- 640, 480, 640, 480, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_NONINTERLACED
- }},
- { "640x480-16", { /* Default 16 BPP mode (cyber16) */
- 640, 480, 640, 480, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_NONINTERLACED
- }},
- { "640x480-24", { /* Default 24 BPP mode */
- 640, 480, 640, 480, 0, 0, 24, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_NONINTERLACED
- }},
- { "800x490-8", { /* Cybervision 8 bpp */
- /* NO Acceleration */
- 800, 490, 800, 490, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, 33333, 80, 24, 23, 1, 56, 8,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_NONINTERLACED
- }},
-/* I can't test these with my monitor, but I suspect they will
- * be OK, since Antonio Santos indicated he had tested them in
- * his system.
- */
- { "800x600-8", { /* Cybervision 8 bpp */
- 800, 600, 800, 600, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 27778, 64, 24, 22, 1, 72, 2,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_NONINTERLACED
- }},
- { "1024x768-8", { /* Cybervision 8 bpp */
- 1024, 768, 1024, 768, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 16667, 224, 72, 60, 12, 168, 4,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_NONINTERLACED
- }},
- { "1152x886-8", { /* Cybervision 8 bpp */
- 1152, 886, 1152, 886, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 15873, 184, 40, 24, 1, 56, 16,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_NONINTERLACED
- }},
- { "1280x1024-8", { /* Cybervision 8 bpp */
- 1280, 1024, 1280, 1024, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 16667, 256, 48, 50, 12, 72, 4,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_INTERLACED
- }}
-};
-
-#define NUM_TOTAL_MODES ARRAY_SIZE(cyberfb_predefined)
-
-static int Cyberfb_inverse = 0;
-
-/*
- * Some default modes
- */
-
-#define CYBER8_DEFMODE (0)
-#define CYBER16_DEFMODE (1)
-
-static struct fb_var_screeninfo cyberfb_default;
-static int cyberfb_usermode __initdata = 0;
-
-/*
- * Interface used by the world
- */
-
-int cyberfb_setup(char *options);
-
-static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int cyberfb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-static int cyberfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info);
-static int cyberfb_blank(int blank, struct fb_info *info);
-
-/*
- * Interface to the low level console driver
- */
-
-int cyberfb_init(void);
-static int Cyberfb_switch(int con, struct fb_info *info);
-static int Cyberfb_updatevar(int con, struct fb_info *info);
-
-/*
- * Text console acceleration
- */
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_cyber8;
-#endif
-
-/*
- * Accelerated Functions used by the low level console driver
- */
-
-static void Cyber_WaitQueue(u_short fifo);
-static void Cyber_WaitBlit(void);
-static void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,
- u_short desty, u_short width, u_short height,
- u_short mode);
-static void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,
- u_short mode, u_short color);
-#if 0
-static void Cyber_MoveCursor(u_short x, u_short y);
-#endif
-
-/*
- * Hardware Specific Routines
- */
-
-static int Cyber_init(void);
-static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
- struct cyberfb_par *par);
-static int Cyber_decode_var(struct fb_var_screeninfo *var,
- struct cyberfb_par *par);
-static int Cyber_encode_var(struct fb_var_screeninfo *var,
- struct cyberfb_par *par);
-static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info);
-
-/*
- * Internal routines
- */
-
-static void cyberfb_get_par(struct cyberfb_par *par);
-static void cyberfb_set_par(struct cyberfb_par *par);
-static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-static void cyberfb_set_disp(int con, struct fb_info *info);
-static int get_video_mode(const char *name);
-
-/* For cvision_core.c */
-static unsigned short cv64_compute_clock(unsigned long);
-static int cv_has_4mb (volatile unsigned char *);
-static void cv64_board_init (void);
-static void cv64_load_video_mode (struct fb_var_screeninfo *);
-
-
-/* -------------------- Hardware specific routines ------------------------- */
-
-
-/*
- * Initialization
- *
- * Set the default video mode for this chipset. If a video mode was
- * specified on the command line, it will override the default mode.
- */
-
-static int Cyber_init(void)
-{
- volatile unsigned char *regs = CyberRegs;
- volatile unsigned long *CursorBase;
- int i;
- DPRINTK("ENTER\n");
-
-/* Init local cmap as greyscale levels */
- for (i = 0; i < 256; i++) {
- Cyber_colour_table [i][0] = i;
- Cyber_colour_table [i][1] = i;
- Cyber_colour_table [i][2] = i;
- }
-
-/* Initialize the board and determine fbmem size */
- cv64_board_init();
-#ifdef CYBERFBDEBUG
- DPRINTK("Register state after initing board\n");
- cv64_dump();
-#endif
-/* Clear framebuffer memory */
- DPRINTK("Clear framebuffer memory\n");
- memset ((char *)CyberMem, 0, CyberSize);
-
-/* Disable hardware cursor */
- DPRINTK("Disable HW cursor\n");
- wb_64(regs, S3_CRTC_ADR, S3_REG_LOCK2);
- wb_64(regs, S3_CRTC_DATA, 0xa0);
- wb_64(regs, S3_CRTC_ADR, S3_HGC_MODE);
- wb_64(regs, S3_CRTC_DATA, 0x00);
- wb_64(regs, S3_CRTC_ADR, S3_HWGC_DX);
- wb_64(regs, S3_CRTC_DATA, 0x00);
- wb_64(regs, S3_CRTC_ADR, S3_HWGC_DY);
- wb_64(regs, S3_CRTC_DATA, 0x00);
-
-/* Initialize hardware cursor */
- DPRINTK("Init HW cursor\n");
- CursorBase = (u_long *)((char *)(CyberMem) + CyberSize - 0x400);
- for (i=0; i < 8; i++)
- {
- *(CursorBase +(i*4)) = 0xffffff00;
- *(CursorBase+1+(i*4)) = 0xffff0000;
- *(CursorBase+2+(i*4)) = 0xffff0000;
- *(CursorBase+3+(i*4)) = 0xffff0000;
- }
- for (i=8; i < 64; i++)
- {
- *(CursorBase +(i*4)) = 0xffff0000;
- *(CursorBase+1+(i*4)) = 0xffff0000;
- *(CursorBase+2+(i*4)) = 0xffff0000;
- *(CursorBase+3+(i*4)) = 0xffff0000;
- }
-
- cyberfb_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, NULL /* unused */);
- cyberfb_setcolreg (254, 0, 0, 0, 0, NULL /* unused */);
-
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/*
- * This function should fill in the `fix' structure based on the
- * values in the `par' structure.
- */
-
-static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
- struct cyberfb_par *par)
-{
- DPRINTK("ENTER\n");
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strcpy(fix->id, cyberfb_name);
- fix->smem_start = CyberMem_phys;
- fix->smem_len = CyberSize;
- fix->mmio_start = CyberRegs_phys;
- fix->mmio_len = 0x10000;
-
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->type_aux = 0;
- if (par->var.bits_per_pixel == 15 || par->var.bits_per_pixel == 16 ||
- par->var.bits_per_pixel == 24 || par->var.bits_per_pixel == 32) {
- fix->visual = FB_VISUAL_DIRECTCOLOR;
- } else {
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
- }
-
- fix->xpanstep = 0;
- fix->ypanstep = 0;
- fix->ywrapstep = 0;
- fix->line_length = 0;
- fix->accel = FB_ACCEL_S3_TRIO64;
-
- DPRINTK("EXIT\n");
- return(0);
-}
-
-
-/*
-* Fill the `par' structure based on the values in `var'.
-* TODO: Verify and adjust values, return -EINVAL if bad.
-*/
-
-static int Cyber_decode_var(struct fb_var_screeninfo *var,
- struct cyberfb_par *par)
-{
- DPRINTK("ENTER\n");
- par->var.xres = var->xres;
- par->var.yres = var->yres;
- par->var.xres_virtual = var->xres_virtual;
- par->var.yres_virtual = var->yres_virtual;
- par->var.xoffset = var->xoffset;
- par->var.yoffset = var->yoffset;
- par->var.bits_per_pixel = var->bits_per_pixel;
- par->var.grayscale = var->grayscale;
- par->var.red = var->red;
- par->var.green = var->green;
- par->var.blue = var->blue;
- par->var.transp = var->transp;
- par->var.nonstd = var->nonstd;
- par->var.activate = var->activate;
- par->var.height = var->height;
- par->var.width = var->width;
- if (var->accel_flags & FB_ACCELF_TEXT) {
- par->var.accel_flags = FB_ACCELF_TEXT;
- } else {
- par->var.accel_flags = 0;
- }
- par->var.pixclock = var->pixclock;
- par->var.left_margin = var->left_margin;
- par->var.right_margin = var->right_margin;
- par->var.upper_margin = var->upper_margin;
- par->var.lower_margin = var->lower_margin;
- par->var.hsync_len = var->hsync_len;
- par->var.vsync_len = var->vsync_len;
- par->var.sync = var->sync;
- par->var.vmode = var->vmode;
- DPRINTK("EXIT\n");
- return(0);
-}
-
-/*
-* Fill the `var' structure based on the values in `par' and maybe
-* other values read out of the hardware.
-*/
-
-static int Cyber_encode_var(struct fb_var_screeninfo *var,
- struct cyberfb_par *par)
-{
- DPRINTK("ENTER\n");
- var->xres = par->var.xres;
- var->yres = par->var.yres;
- var->xres_virtual = par->var.xres_virtual;
- var->yres_virtual = par->var.yres_virtual;
- var->xoffset = par->var.xoffset;
- var->yoffset = par->var.yoffset;
-
- var->bits_per_pixel = par->var.bits_per_pixel;
- var->grayscale = par->var.grayscale;
-
- var->red = par->var.red;
- var->green = par->var.green;
- var->blue = par->var.blue;
- var->transp = par->var.transp;
-
- var->nonstd = par->var.nonstd;
- var->activate = par->var.activate;
-
- var->height = par->var.height;
- var->width = par->var.width;
-
- var->accel_flags = par->var.accel_flags;
-
- var->pixclock = par->var.pixclock;
- var->left_margin = par->var.left_margin;
- var->right_margin = par->var.right_margin;
- var->upper_margin = par->var.upper_margin;
- var->lower_margin = par->var.lower_margin;
- var->hsync_len = par->var.hsync_len;
- var->vsync_len = par->var.vsync_len;
- var->sync = par->var.sync;
- var->vmode = par->var.vmode;
-
- DPRINTK("EXIT\n");
- return(0);
-}
-
-
-/*
- * Set a single color register. Return != 0 for invalid regno.
- */
-
-static int cyberfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
-{
- volatile unsigned char *regs = CyberRegs;
-
- /*DPRINTK("ENTER\n");*/
- if (regno > 255) {
- DPRINTK("EXIT - Register # > 255\n");
- return (1);
- }
-
- wb_64(regs, 0x3c8, (unsigned char) regno);
-
- red >>= 10;
- green >>= 10;
- blue >>= 10;
-
- Cyber_colour_table [regno][0] = red;
- Cyber_colour_table [regno][1] = green;
- Cyber_colour_table [regno][2] = blue;
-
- wb_64(regs, 0x3c9, red);
- wb_64(regs, 0x3c9, green);
- wb_64(regs, 0x3c9, blue);
-
- /*DPRINTK("EXIT\n");*/
- return (0);
-}
-
-
-/*
-* Read a single color register and split it into
-* colors/transparent. Return != 0 for invalid regno.
-*/
-
-static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info)
-{
- int t;
-
- /*DPRINTK("ENTER\n");*/
- if (regno > 255) {
- DPRINTK("EXIT - Register # > 255\n");
- return (1);
- }
- /* ARB This shifting & oring seems VERY strange */
- t = Cyber_colour_table [regno][0];
- *red = (t<<10) | (t<<4) | (t>>2);
- t = Cyber_colour_table [regno][1];
- *green = (t<<10) | (t<<4) | (t>>2);
- t = Cyber_colour_table [regno][2];
- *blue = (t<<10) | (t<<4) | (t>>2);
- *transp = 0;
- /*DPRINTK("EXIT\n");*/
- return (0);
-}
-
-
-/*
-* (Un)Blank the screen
-* blank: 1 = zero fb cmap
-* 0 = restore fb cmap from local cmap
-*/
-static int cyberfb_blank(int blank, struct fb_info *info)
-{
- volatile unsigned char *regs = CyberRegs;
- int i;
-
- DPRINTK("ENTER\n");
-#if 0
-/* Blank by turning gfx off */
- gfx_on_off (1, regs);
-#else
- if (blank) {
- for (i = 0; i < 256; i++) {
- wb_64(regs, 0x3c8, (unsigned char) i);
- /* ARB Pale red to detect this blanking method */
- wb_64(regs, 0x3c9, 48);
- wb_64(regs, 0x3c9, 0);
- wb_64(regs, 0x3c9, 0);
- }
- } else {
- for (i = 0; i < 256; i++) {
- wb_64(regs, 0x3c8, (unsigned char) i);
- wb_64(regs, 0x3c9, Cyber_colour_table[i][0]);
- wb_64(regs, 0x3c9, Cyber_colour_table[i][1]);
- wb_64(regs, 0x3c9, Cyber_colour_table[i][2]);
- }
- }
-#endif
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/**************************************************************
- * We are waiting for "fifo" FIFO-slots empty
- */
-static void Cyber_WaitQueue (u_short fifo)
-{
- unsigned short status;
-
- DPRINTK("ENTER\n");
- do {
- status = *((u_short volatile *)(CyberRegs + S3_GP_STAT));
- } while (status & fifo);
- DPRINTK("EXIT\n");
-}
-
-/**************************************************************
- * We are waiting for Hardware (Graphics Engine) not busy
- */
-static void Cyber_WaitBlit (void)
-{
- unsigned short status;
-
- DPRINTK("ENTER\n");
- do {
- status = *((u_short volatile *)(CyberRegs + S3_GP_STAT));
- } while (status & S3_HDW_BUSY);
- DPRINTK("EXIT\n");
-}
-
-/**************************************************************
- * BitBLT - Through the Plane
- */
-static void Cyber_BitBLT (u_short curx, u_short cury, u_short destx,
- u_short desty, u_short width, u_short height,
- u_short mode)
-{
- volatile unsigned char *regs = CyberRegs;
- u_short blitcmd = S3_BITBLT;
-
- DPRINTK("ENTER\n");
- /* Set drawing direction */
- /* -Y, X maj, -X (default) */
- if (curx > destx) {
- blitcmd |= 0x0020; /* Drawing direction +X */
- } else {
- curx += (width - 1);
- destx += (width - 1);
- }
-
- if (cury > desty) {
- blitcmd |= 0x0080; /* Drawing direction +Y */
- } else {
- cury += (height - 1);
- desty += (height - 1);
- }
-
- Cyber_WaitQueue (0x8000);
-
- *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000;
- *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0060 | mode);
-
- *((u_short volatile *)(regs + S3_CUR_X)) = curx;
- *((u_short volatile *)(regs + S3_CUR_Y)) = cury;
-
- *((u_short volatile *)(regs + S3_DESTX_DIASTP)) = destx;
- *((u_short volatile *)(regs + S3_DESTY_AXSTP)) = desty;
-
- *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1;
- *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1;
-
- *((u_short volatile *)(regs + S3_CMD)) = blitcmd;
- DPRINTK("EXIT\n");
-}
-
-/**************************************************************
- * Rectangle Fill Solid
- */
-static void Cyber_RectFill (u_short x, u_short y, u_short width,
- u_short height, u_short mode, u_short color)
-{
- volatile unsigned char *regs = CyberRegs;
- u_short blitcmd = S3_FILLEDRECT;
-
- DPRINTK("ENTER\n");
- Cyber_WaitQueue (0x8000);
-
- *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000;
- *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0020 | mode);
-
- *((u_short volatile *)(regs + S3_MULT_MISC)) = 0xe000;
- *((u_short volatile *)(regs + S3_FRGD_COLOR)) = color;
-
- *((u_short volatile *)(regs + S3_CUR_X)) = x;
- *((u_short volatile *)(regs + S3_CUR_Y)) = y;
-
- *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1;
- *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1;
-
- *((u_short volatile *)(regs + S3_CMD)) = blitcmd;
- DPRINTK("EXIT\n");
-}
-
-
-#if 0
-/**************************************************************
- * Move cursor to x, y
- */
-static void Cyber_MoveCursor (u_short x, u_short y)
-{
- volatile unsigned char *regs = CyberRegs;
- DPRINTK("ENTER\n");
- *(regs + S3_CRTC_ADR) = 0x39;
- *(regs + S3_CRTC_DATA) = 0xa0;
-
- *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_H;
- *(regs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8);
- *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_L;
- *(regs + S3_CRTC_DATA) = (char)(x & 0x00ff);
-
- *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_H;
- *(regs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8);
- *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_L;
- *(regs + S3_CRTC_DATA) = (char)(y & 0x00ff);
- DPRINTK("EXIT\n");
-}
-#endif
-
-
-/* -------------------- Generic routines ---------------------------------- */
-
-
-/*
- * Fill the hardware's `par' structure.
- */
-
-static void cyberfb_get_par(struct cyberfb_par *par)
-{
- DPRINTK("ENTER\n");
- if (current_par_valid) {
- *par = current_par;
- } else {
- Cyber_decode_var(&cyberfb_default, par);
- }
- DPRINTK("EXIT\n");
-}
-
-
-static void cyberfb_set_par(struct cyberfb_par *par)
-{
- DPRINTK("ENTER\n");
- current_par = *par;
- current_par_valid = 1;
- DPRINTK("EXIT\n");
-}
-
-
-static void cyber_set_video(struct fb_var_screeninfo *var)
-{
-
- /* Load the video mode defined by the 'var' data */
- cv64_load_video_mode (var);
-#ifdef CYBERFBDEBUG
- DPRINTK("Register state after loading video mode\n");
- cv64_dump();
-#endif
-}
-
-
-static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
-{
- int err, activate;
- struct cyberfb_par par;
-
- DPRINTK("ENTER\n");
- if ((err = Cyber_decode_var(var, &par))) {
- DPRINTK("EXIT - decode_var failed\n");
- return(err);
- }
- activate = var->activate;
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
- cyberfb_set_par(&par);
- Cyber_encode_var(var, &par);
- var->activate = activate;
-
- cyber_set_video(var);
- DPRINTK("EXIT\n");
- return 0;
-}
-
-/*
- * Get the Fixed Part of the Display
- */
-
-static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- struct cyberfb_par par;
- int error = 0;
-
- DPRINTK("ENTER\n");
- if (con == -1) {
- cyberfb_get_par(&par);
- } else {
- error = Cyber_decode_var(&fb_display[con].var, &par);
- }
- DPRINTK("EXIT\n");
- return(error ? error : Cyber_encode_fix(fix, &par));
-}
-
-
-/*
- * Get the User Defined Part of the Display
- */
-
-static int cyberfb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct cyberfb_par par;
- int error = 0;
-
- DPRINTK("ENTER\n");
- if (con == -1) {
- cyberfb_get_par(&par);
- error = Cyber_encode_var(var, &par);
- disp.var = *var; /* ++Andre: don't know if this is the right place */
- } else {
- *var = fb_display[con].var;
- }
-
- DPRINTK("EXIT\n");
- return(error);
-}
-
-
-static void cyberfb_set_disp(int con, struct fb_info *info)
-{
- struct fb_fix_screeninfo fix;
- struct display *display;
-
- DPRINTK("ENTER\n");
- if (con >= 0)
- display = &fb_display[con];
- else
- display = &disp; /* used during initialization */
-
- cyberfb_get_fix(&fix, con, info);
- if (con == -1)
- con = 0;
- display->visual = fix.visual;
- display->type = fix.type;
- display->type_aux = fix.type_aux;
- display->ypanstep = fix.ypanstep;
- display->ywrapstep = fix.ywrapstep;
- display->can_soft_blank = 1;
- display->inverse = Cyberfb_inverse;
- switch (display->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- if (display->var.accel_flags & FB_ACCELF_TEXT) {
- display->dispsw = &fbcon_cyber8;
-#warning FIXME: We should reinit the graphics engine here
- } else
- display->dispsw = &fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- display->dispsw = &fbcon_cfb16;
- break;
-#endif
- default:
- display->dispsw = NULL;
- break;
- }
- DPRINTK("EXIT\n");
-}
-
-
-/*
- * Set the User Defined Part of the Display
- */
-
-static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
-
- DPRINTK("ENTER\n");
- if ((err = do_fb_set_var(var, con == info->currcon))) {
- DPRINTK("EXIT - do_fb_set_var failed\n");
- return(err);
- }
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
- oldxres = fb_display[con].var.xres;
- oldyres = fb_display[con].var.yres;
- oldvxres = fb_display[con].var.xres_virtual;
- oldvyres = fb_display[con].var.yres_virtual;
- oldbpp = fb_display[con].var.bits_per_pixel;
- oldaccel = fb_display[con].var.accel_flags;
- fb_display[con].var = *var;
- if (oldxres != var->xres || oldyres != var->yres ||
- oldvxres != var->xres_virtual ||
- oldvyres != var->yres_virtual ||
- oldbpp != var->bits_per_pixel ||
- oldaccel != var->accel_flags) {
- cyberfb_set_disp(con, info);
- (*fb_info.changevar)(con);
- fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
- do_install_cmap(con, info);
- }
- }
- var->activate = 0;
- DPRINTK("EXIT\n");
- return(0);
-}
-
-
-/*
- * Get the Colormap
- */
-
-static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- DPRINTK("ENTER\n");
- if (con == info->currcon) { /* current console? */
- DPRINTK("EXIT - console is current console\n");
- return(fb_get_cmap(cmap, kspc, Cyber_getcolreg, info));
- } else if (fb_display[con].cmap.len) { /* non default colormap? */
- DPRINTK("Use console cmap\n");
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- } else {
- DPRINTK("Use default cmap\n");
- fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- cmap, kspc ? 0 : 2);
- }
- DPRINTK("EXIT\n");
- return(0);
-}
-
-static struct fb_ops cyberfb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = cyberfb_get_fix,
- .fb_get_var = cyberfb_get_var,
- .fb_set_var = cyberfb_set_var,
- .fb_get_cmap = cyberfb_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = cyberfb_setcolreg,
- .fb_blank = cyberfb_blank,
-};
-
-int __init cyberfb_setup(char *options)
-{
- char *this_opt;
- DPRINTK("ENTER\n");
-
- fb_info.fontname[0] = '\0';
-
- if (!options || !*options) {
- DPRINTK("EXIT - no options\n");
- return 0;
- }
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
- if (!strcmp(this_opt, "inverse")) {
- Cyberfb_inverse = 1;
- fb_invert_cmaps();
- } else if (!strncmp(this_opt, "font:", 5)) {
- strcpy(fb_info.fontname, this_opt+5);
- } else if (!strcmp (this_opt, "cyber8")) {
- cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
- cyberfb_usermode = 1;
- } else if (!strcmp (this_opt, "cyber16")) {
- cyberfb_default = cyberfb_predefined[CYBER16_DEFMODE].var;
- cyberfb_usermode = 1;
- } else get_video_mode(this_opt);
- }
-
- DPRINTK("default mode: xres=%d, yres=%d, bpp=%d\n",
- cyberfb_default.xres,
- cyberfb_default.yres,
- cyberfb_default.bits_per_pixel);
- DPRINTK("EXIT\n");
- return 0;
-}
-
-/*
- * Initialization
- */
-
-int __init cyberfb_init(void)
-{
- unsigned long board_addr, board_size;
- struct cyberfb_par par;
- struct zorro_dev *z = NULL;
- DPRINTK("ENTER\n");
-
- while ((z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64, z))) {
- board_addr = z->resource.start;
- board_size = z->resource.end-z->resource.start+1;
- CyberMem_phys = board_addr + 0x01400000;
- CyberRegs_phys = CyberMem_phys + 0x00c00000;
- if (!request_mem_region(CyberRegs_phys, 0x10000, "S3 Trio64"))
- continue;
- if (!request_mem_region(CyberMem_phys, 0x400000, "RAM")) {
- release_mem_region(CyberRegs_phys, 0x10000);
- continue;
- }
- DPRINTK("board_addr=%08lx\n", board_addr);
- DPRINTK("board_size=%08lx\n", board_size);
-
- CyberBase = ioremap(board_addr, board_size);
- CyberRegs = CyberBase + 0x02000000;
- CyberMem = CyberBase + 0x01400000;
- DPRINTK("CyberBase=%08lx CyberRegs=%08lx CyberMem=%08lx\n",
- CyberBase, (long unsigned int)CyberRegs, CyberMem);
-
-#ifdef CYBERFBDEBUG
- DPRINTK("Register state just after mapping memory\n");
- cv64_dump();
-#endif
-
- strcpy(fb_info.modename, cyberfb_name);
- fb_info.changevar = NULL;
- fb_info.fbops = &cyberfb_ops;
- fb_info.screen_base = (unsigned char *)CyberMem;
- fb_info.disp = &disp;
- fb_info.currcon = -1;
- fb_info.switch_con = &Cyberfb_switch;
- fb_info.updatevar = &Cyberfb_updatevar;
-
- Cyber_init();
- /* ++Andre: set cyberfb default mode */
- if (!cyberfb_usermode) {
- cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
- DPRINTK("Use default cyber8 mode\n");
- }
- Cyber_decode_var(&cyberfb_default, &par);
- Cyber_encode_var(&cyberfb_default, &par);
-
- do_fb_set_var(&cyberfb_default, 1);
- cyberfb_get_var(&fb_display[0].var, -1, &fb_info);
- cyberfb_set_disp(-1, &fb_info);
- do_install_cmap(0, &fb_info);
-
- if (register_framebuffer(&fb_info) < 0) {
- DPRINTK("EXIT - register_framebuffer failed\n");
- if (CyberBase)
- iounmap(CyberBase);
- release_mem_region(CyberMem_phys, 0x400000);
- release_mem_region(CyberRegs_phys, 0x10000);
- return -EINVAL;
- }
-
- printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
- fb_info.node, fb_info.modename, CyberSize>>10);
-
- /* TODO: This driver cannot be unloaded yet */
- DPRINTK("EXIT\n");
- return 0;
- }
- return -ENXIO;
-}
-
-
-static int Cyberfb_switch(int con, struct fb_info *info)
-{
- DPRINTK("ENTER\n");
- /* Do we have to save the colormap? */
- if (fb_display[info->currcon].cmap.len) {
- fb_get_cmap(&fb_display[info->currcon].cmap, 1, Cyber_getcolreg,
- info);
- }
-
- do_fb_set_var(&fb_display[con].var, 1);
- info->currcon = con;
- /* Install new colormap */
- do_install_cmap(con, info);
- DPRINTK("EXIT\n");
- return(0);
-}
-
-
-/*
- * Update the `var' structure (called by fbcon.c)
- *
- * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
- * Since it's called by a kernel driver, no range checking is done.
- */
-
-static int Cyberfb_updatevar(int con, struct fb_info *info)
-{
- DPRINTK("Enter - Exit\n");
- return(0);
-}
-
-
-/*
- * Get a Video Mode
- */
-
-static int __init get_video_mode(const char *name)
-{
- int i;
-
- DPRINTK("ENTER\n");
- for (i = 0; i < NUM_TOTAL_MODES; i++) {
- if (!strcmp(name, cyberfb_predefined[i].name)) {
- cyberfb_default = cyberfb_predefined[i].var;
- cyberfb_usermode = 1;
- DPRINTK("EXIT - Matched predefined mode\n");
- return(i);
- }
- }
- return(0);
-}
-
-
-/*
- * Text console acceleration
- */
-
-#ifdef FBCON_HAS_CFB8
-static void fbcon_cyber8_bmove(struct display *p, int sy, int sx, int dy,
- int dx, int height, int width)
-{
- DPRINTK("ENTER\n");
- sx *= 8; dx *= 8; width *= 8;
- Cyber_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
- (u_short)(dy*fontheight(p)), (u_short)width,
- (u_short)(height*fontheight(p)), (u_short)S3_NEW);
- DPRINTK("EXIT\n");
-}
-
-static void fbcon_cyber8_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- unsigned char bg;
-
- DPRINTK("ENTER\n");
- sx *= 8; width *= 8;
- bg = attr_bgcol_ec(p,conp);
- Cyber_RectFill((u_short)sx,
- (u_short)(sy*fontheight(p)),
- (u_short)width,
- (u_short)(height*fontheight(p)),
- (u_short)S3_NEW,
- (u_short)bg);
- DPRINTK("EXIT\n");
-}
-
-static void fbcon_cyber8_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx)
-{
- DPRINTK("ENTER\n");
- Cyber_WaitBlit();
- fbcon_cfb8_putc(conp, p, c, yy, xx);
- DPRINTK("EXIT\n");
-}
-
-static void fbcon_cyber8_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count,
- int yy, int xx)
-{
- DPRINTK("ENTER\n");
- Cyber_WaitBlit();
- fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
- DPRINTK("EXIT\n");
-}
-
-static void fbcon_cyber8_revc(struct display *p, int xx, int yy)
-{
- DPRINTK("ENTER\n");
- Cyber_WaitBlit();
- fbcon_cfb8_revc(p, xx, yy);
- DPRINTK("EXIT\n");
-}
-
-static struct display_switch fbcon_cyber8 = {
- .setup = fbcon_cfb8_setup,
- .bmove = fbcon_cyber8_bmove,
- .clear = fbcon_cyber8_clear,
- .putc = fbcon_cyber8_putc,
- .putcs = fbcon_cyber8_putcs,
- .revc = fbcon_cyber8_revc,
- .clear_margins =fbcon_cfb8_clear_margins,
- .fontwidthmask =FONTWIDTH(8)
-};
-#endif
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return cyberfb_init();
-}
-#endif /* MODULE */
-
-/*
- *
- * Low level initialization routines for the CyberVision64 graphics card
- *
- * Most of the following code is from cvision_core.c
- *
- */
-
-#define MAXPIXELCLOCK 135000000 /* safety */
-
-#ifdef CV_AGGRESSIVE_TIMING
-long cv64_memclk = 55000000;
-#else
-long cv64_memclk = 50000000;
-#endif
-
-/*********************/
-
-static unsigned char clocks[]={
- 0x13, 0x61, 0x6b, 0x6d, 0x51, 0x69, 0x54, 0x69,
- 0x4f, 0x68, 0x6b, 0x6b, 0x18, 0x61, 0x7b, 0x6c,
- 0x51, 0x67, 0x24, 0x62, 0x56, 0x67, 0x77, 0x6a,
- 0x1d, 0x61, 0x53, 0x66, 0x6b, 0x68, 0x79, 0x69,
- 0x7c, 0x69, 0x7f, 0x69, 0x22, 0x61, 0x54, 0x65,
- 0x56, 0x65, 0x58, 0x65, 0x67, 0x66, 0x41, 0x63,
- 0x27, 0x61, 0x13, 0x41, 0x37, 0x62, 0x6b, 0x4d,
- 0x23, 0x43, 0x51, 0x49, 0x79, 0x66, 0x54, 0x49,
- 0x7d, 0x66, 0x34, 0x56, 0x4f, 0x63, 0x1f, 0x42,
- 0x6b, 0x4b, 0x7e, 0x4d, 0x18, 0x41, 0x2a, 0x43,
- 0x7b, 0x4c, 0x74, 0x4b, 0x51, 0x47, 0x65, 0x49,
- 0x24, 0x42, 0x68, 0x49, 0x56, 0x47, 0x75, 0x4a,
- 0x77, 0x4a, 0x31, 0x43, 0x1d, 0x41, 0x71, 0x49,
- 0x53, 0x46, 0x29, 0x42, 0x6b, 0x48, 0x1f, 0x41,
- 0x79, 0x49, 0x6f, 0x48, 0x7c, 0x49, 0x38, 0x43,
- 0x7f, 0x49, 0x5d, 0x46, 0x22, 0x41, 0x53, 0x45,
- 0x54, 0x45, 0x55, 0x45, 0x56, 0x45, 0x57, 0x45,
- 0x58, 0x45, 0x25, 0x41, 0x67, 0x46, 0x5b, 0x45,
- 0x41, 0x43, 0x78, 0x47, 0x27, 0x41, 0x51, 0x44,
- 0x13, 0x21, 0x7d, 0x47, 0x37, 0x42, 0x71, 0x46,
- 0x6b, 0x2d, 0x14, 0x21, 0x23, 0x23, 0x7d, 0x2f,
- 0x51, 0x29, 0x61, 0x2b, 0x79, 0x46, 0x1d, 0x22,
- 0x54, 0x29, 0x45, 0x27, 0x7d, 0x46, 0x7f, 0x46,
- 0x4f, 0x43, 0x2f, 0x41, 0x1f, 0x22, 0x6a, 0x2b,
- 0x6b, 0x2b, 0x5b, 0x29, 0x7e, 0x2d, 0x65, 0x44,
- 0x18, 0x21, 0x5e, 0x29, 0x2a, 0x23, 0x45, 0x26,
- 0x7b, 0x2c, 0x19, 0x21, 0x74, 0x2b, 0x75, 0x2b,
- 0x51, 0x27, 0x3f, 0x25, 0x65, 0x29, 0x40, 0x25,
- 0x24, 0x22, 0x41, 0x25, 0x68, 0x29, 0x42, 0x25,
- 0x56, 0x27, 0x7e, 0x2b, 0x75, 0x2a, 0x1c, 0x21,
- 0x77, 0x2a, 0x4f, 0x26, 0x31, 0x23, 0x6f, 0x29,
- 0x1d, 0x21, 0x32, 0x23, 0x71, 0x29, 0x72, 0x29,
- 0x53, 0x26, 0x69, 0x28, 0x29, 0x22, 0x75, 0x29,
- 0x6b, 0x28, 0x1f, 0x21, 0x1f, 0x21, 0x6d, 0x28,
- 0x79, 0x29, 0x2b, 0x22, 0x6f, 0x28, 0x59, 0x26,
- 0x7c, 0x29, 0x7d, 0x29, 0x38, 0x23, 0x21, 0x21,
- 0x7f, 0x29, 0x39, 0x23, 0x5d, 0x26, 0x75, 0x28,
- 0x22, 0x21, 0x77, 0x28, 0x53, 0x25, 0x6c, 0x27,
- 0x54, 0x25, 0x61, 0x26, 0x55, 0x25, 0x30, 0x22,
- 0x56, 0x25, 0x63, 0x26, 0x57, 0x25, 0x71, 0x27,
- 0x58, 0x25, 0x7f, 0x28, 0x25, 0x21, 0x74, 0x27,
- 0x67, 0x26, 0x40, 0x23, 0x5b, 0x25, 0x26, 0x21,
- 0x41, 0x23, 0x34, 0x22, 0x78, 0x27, 0x6b, 0x26,
- 0x27, 0x21, 0x35, 0x22, 0x51, 0x24, 0x7b, 0x27,
- 0x13, 0x1, 0x13, 0x1, 0x7d, 0x27, 0x4c, 0x9,
- 0x37, 0x22, 0x5b, 0xb, 0x71, 0x26, 0x5c, 0xb,
- 0x6b, 0xd, 0x47, 0x23, 0x14, 0x1, 0x4f, 0x9,
- 0x23, 0x3, 0x75, 0x26, 0x7d, 0xf, 0x1c, 0x2,
- 0x51, 0x9, 0x59, 0x24, 0x61, 0xb, 0x69, 0x25,
- 0x79, 0x26, 0x34, 0x5, 0x1d, 0x2, 0x6b, 0x25,
- 0x54, 0x9, 0x35, 0x5, 0x45, 0x7, 0x6d, 0x25,
- 0x7d, 0x26, 0x16, 0x1, 0x7f, 0x26, 0x77, 0xd,
- 0x4f, 0x23, 0x78, 0xd, 0x2f, 0x21, 0x27, 0x3,
- 0x1f, 0x2, 0x59, 0x9, 0x6a, 0xb, 0x73, 0x25,
- 0x6b, 0xb, 0x63, 0x24, 0x5b, 0x9, 0x20, 0x2,
- 0x7e, 0xd, 0x4b, 0x7, 0x65, 0x24, 0x43, 0x22,
- 0x18, 0x1, 0x6f, 0xb, 0x5e, 0x9, 0x70, 0xb,
- 0x2a, 0x3, 0x33, 0x4, 0x45, 0x6, 0x60, 0x9,
- 0x7b, 0xc, 0x19, 0x1, 0x19, 0x1, 0x7d, 0xc,
- 0x74, 0xb, 0x50, 0x7, 0x75, 0xb, 0x63, 0x9,
- 0x51, 0x7, 0x23, 0x2, 0x3f, 0x5, 0x1a, 0x1,
- 0x65, 0x9, 0x2d, 0x3, 0x40, 0x5, 0x0, 0x0,
-};
-
-/* Console colors */
-unsigned char cvconscolors[16][3] = { /* background, foreground, hilite */
- /* R G B */
- {0x30, 0x30, 0x30},
- {0x00, 0x00, 0x00},
- {0x80, 0x00, 0x00},
- {0x00, 0x80, 0x00},
- {0x00, 0x00, 0x80},
- {0x80, 0x80, 0x00},
- {0x00, 0x80, 0x80},
- {0x80, 0x00, 0x80},
- {0xff, 0xff, 0xff},
- {0x40, 0x40, 0x40},
- {0xff, 0x00, 0x00},
- {0x00, 0xff, 0x00},
- {0x00, 0x00, 0xff},
- {0xff, 0xff, 0x00},
- {0x00, 0xff, 0xff},
- {0x00, 0x00, 0xff}
-};
-
-/* -------------------- Hardware specific routines ------------------------- */
-
-/* Read Attribute Controller Register=idx */
-inline unsigned char RAttr (volatile unsigned char *regs, short idx)
-{
- wb_64 (regs, ACT_ADDRESS_W, idx);
- mb();
- udelay(100);
- return (rb_64(regs, ACT_ADDRESS_R));
-}
-
-/* Read Sequencer Register=idx */
-inline unsigned char RSeq (volatile unsigned char *regs, short idx)
-{
- wb_64 (regs, SEQ_ADDRESS, idx);
- mb();
- return (rb_64(regs, SEQ_ADDRESS_R));
-}
-
-/* Read CRT Controller Register=idx */
-inline unsigned char RCrt (volatile unsigned char *regs, short idx)
-{
- wb_64 (regs, CRT_ADDRESS, idx);
- mb();
- return (rb_64(regs, CRT_ADDRESS_R));
-}
-
-/* Read Graphics Controller Register=idx */
-inline unsigned char RGfx (volatile unsigned char *regs, short idx)
-{
- wb_64 (regs, GCT_ADDRESS, idx);
- mb();
- return (rb_64(regs, GCT_ADDRESS_R));
-}
-
-/*
- * Special wakeup/passthrough registers on graphics boards
- */
-
-inline void cv64_write_port (unsigned short bits,
- volatile unsigned char *base)
-{
- volatile unsigned char *addr;
- static unsigned char cvportbits = 0; /* Mirror port bits here */
- DPRINTK("ENTER\n");
-
- addr = base + 0x40001;
- if (bits & 0x8000) {
- cvportbits |= bits & 0xff; /* Set bits */
- DPRINTK("Set bits: %04x\n", bits);
- } else {
- bits = bits & 0xff;
- bits = (~bits) & 0xff;
- cvportbits &= bits; /* Clear bits */
- DPRINTK("Clear bits: %04x\n", bits);
- }
-
- *addr = cvportbits;
- DPRINTK("EXIT\n");
-}
-
-/*
- * Monitor switch on CyberVision board
- *
- * toggle:
- * 0 = CyberVision Signal
- * 1 = Amiga Signal
- * board = board addr
- *
- */
-inline void cvscreen (int toggle, volatile unsigned char *board)
-{
- DPRINTK("ENTER\n");
- if (toggle == 1) {
- DPRINTK("Show Amiga video\n");
- cv64_write_port (0x10, board);
- } else {
- DPRINTK("Show CyberVision video\n");
- cv64_write_port (0x8010, board);
- }
- DPRINTK("EXIT\n");
-}
-
-/* Control screen display */
-/* toggle: 0 = on, 1 = off */
-/* board = registerbase */
-inline void gfx_on_off(int toggle, volatile unsigned char *regs)
-{
- int r;
- DPRINTK("ENTER\n");
-
- toggle &= 0x1;
- toggle = toggle << 5;
- DPRINTK("Turn display %s\n", (toggle ? "off" : "on"));
-
- r = (int) RSeq(regs, SEQ_ID_CLOCKING_MODE);
- r &= 0xdf; /* Set bit 5 to 0 */
-
- WSeq (regs, SEQ_ID_CLOCKING_MODE, r | toggle);
- DPRINTK("EXIT\n");
-}
-
-/*
- * Computes M, N, and R values from
- * given input frequency. It uses a table of
- * precomputed values, to keep CPU time low.
- *
- * The return value consist of:
- * lower byte: Bits 4-0: N Divider Value
- * Bits 5-6: R Value for e.g. SR10 or SR12
- * higher byte: Bits 0-6: M divider value for e.g. SR11 or SR13
- */
-static unsigned short cv64_compute_clock(unsigned long freq)
-{
- static unsigned char *mnr, *save; /* M, N + R vals */
- unsigned long work_freq, r;
- unsigned short erg;
- long diff, d2;
-
- DPRINTK("ENTER\n");
- if (freq < 12500000 || freq > MAXPIXELCLOCK) {
- printk("CV64 driver: Illegal clock frequency %ld, using 25MHz\n",
- freq);
- freq = 25000000;
- }
- DPRINTK("Freq = %ld\n", freq);
- mnr = clocks; /* there the vals are stored */
- d2 = 0x7fffffff;
-
- while (*mnr) { /* mnr vals are 0-terminated */
- work_freq = (0x37EE * (mnr[0] + 2)) / ((mnr[1] & 0x1F) + 2);
-
- r = (mnr[1] >> 5) & 0x03;
- if (r != 0) {
- work_freq = work_freq >> r; /* r is the freq divider */
- }
-
- work_freq *= 0x3E8; /* 2nd part of OSC */
-
- diff = abs(freq - work_freq);
-
- if (d2 >= diff) {
- d2 = diff;
- /* In save are the vals for minimal diff */
- save = mnr;
- }
- mnr += 2;
- }
- erg = *((unsigned short *)save);
-
- DPRINTK("EXIT\n");
- return (erg);
-}
-
-static int cv_has_4mb (volatile unsigned char *fb)
-{
- volatile unsigned long *tr, *tw;
- DPRINTK("ENTER\n");
-
- /* write patterns in memory and test if they can be read */
- tw = (volatile unsigned long *) fb;
- tr = (volatile unsigned long *) (fb + 0x02000000);
-
- *tw = 0x87654321;
-
- if (*tr != 0x87654321) {
- DPRINTK("EXIT - <4MB\n");
- return (0);
- }
-
- /* upper memory region */
- tw = (volatile unsigned long *) (fb + 0x00200000);
- tr = (volatile unsigned long *) (fb + 0x02200000);
-
- *tw = 0x87654321;
-
- if (*tr != 0x87654321) {
- DPRINTK("EXIT - <4MB\n");
- return (0);
- }
-
- *tw = 0xAAAAAAAA;
-
- if (*tr != 0xAAAAAAAA) {
- DPRINTK("EXIT - <4MB\n");
- return (0);
- }
-
- *tw = 0x55555555;
-
- if (*tr != 0x55555555) {
- DPRINTK("EXIT - <4MB\n");
- return (0);
- }
-
- DPRINTK("EXIT\n");
- return (1);
-}
-
-static void cv64_board_init (void)
-{
- volatile unsigned char *regs = CyberRegs;
- int i;
- unsigned int clockpar;
- unsigned char test;
-
- DPRINTK("ENTER\n");
-
- /*
- * Special CyberVision 64 board operations
- */
- /* Reset board */
- for (i = 0; i < 6; i++) {
- cv64_write_port (0xff, CyberBase);
- }
- /* Return to operational mode */
- cv64_write_port (0x8004, CyberBase);
-
- /*
- * Generic (?) S3 chip wakeup
- */
- /* Disable I/O & memory decoders, video in setup mode */
- wb_64 (regs, SREG_VIDEO_SUBS_ENABLE, 0x10);
- /* Video responds to cmds, addrs & data */
- wb_64 (regs, SREG_OPTION_SELECT, 0x1);
- /* Enable I/O & memory decoders, video in operational mode */
- wb_64 (regs, SREG_VIDEO_SUBS_ENABLE, 0x8);
- /* VGA color emulation, enable cpu access to display mem */
- wb_64 (regs, GREG_MISC_OUTPUT_W, 0x03);
- /* Unlock S3 VGA regs */
- WCrt (regs, CRT_ID_REGISTER_LOCK_1, 0x48);
- /* Unlock system control & extension registers */
- WCrt (regs, CRT_ID_REGISTER_LOCK_2, 0xA5);
-/* GRF - Enable interrupts */
- /* Enable enhanced regs access, Ready cntl 0 wait states */
- test = RCrt (regs, CRT_ID_SYSTEM_CONFIG);
- test = test | 0x01; /* enable enhanced register access */
- test = test & 0xEF; /* clear bit 4, 0 wait state */
- WCrt (regs, CRT_ID_SYSTEM_CONFIG, test);
- /*
- * bit 0=1: Enable enhaced mode functions
- * bit 2=0: Enhanced mode 8+ bits/pixel
- * bit 4=1: Enable linear addressing
- * bit 5=1: Enable MMIO
- */
- wb_64 (regs, ECR_ADV_FUNC_CNTL, 0x31);
- /*
- * bit 0=1: Color emulation
- * bit 1=1: Enable CPU access to display memory
- * bit 5=1: Select high 64K memory page
- */
-/* GRF - 0xE3 */
- wb_64 (regs, GREG_MISC_OUTPUT_W, 0x23);
-
- /* Cpu base addr */
- WCrt (regs, CRT_ID_EXT_SYS_CNTL_4, 0x0);
-
- /* Reset. This does nothing on Trio, but standard VGA practice */
- /* WSeq (CyberRegs, SEQ_ID_RESET, 0x03); */
- /* Character clocks 8 dots wide */
- WSeq (regs, SEQ_ID_CLOCKING_MODE, 0x01);
- /* Enable cpu write to all color planes */
- WSeq (regs, SEQ_ID_MAP_MASK, 0x0F);
- /* Font table in 1st 8k of plane 2, font A=B disables swtich */
- WSeq (regs, SEQ_ID_CHAR_MAP_SELECT, 0x0);
- /* Allow mem access to 256kb */
- WSeq (regs, SEQ_ID_MEMORY_MODE, 0x2);
- /* Unlock S3 extensions to VGA Sequencer regs */
- WSeq (regs, SEQ_ID_UNLOCK_EXT, 0x6);
-
- /* Enable 4MB fast page mode */
- test = RSeq (regs, SEQ_ID_BUS_REQ_CNTL);
- test = test | 1 << 6;
- WSeq (regs, SEQ_ID_BUS_REQ_CNTL, test);
-
- /* Faster LUT write: 1 DCLK LUT write cycle, RAMDAC clk doubled */
- WSeq (regs, SEQ_ID_RAMDAC_CNTL, 0xC0);
-
- /* Clear immediate clock load bit */
- test = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2);
- test = test & 0xDF;
- /* If > 55MHz, enable 2 cycle memory write */
- if (cv64_memclk >= 55000000) {
- test |= 0x80;
- }
- WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, test);
-
- /* Set MCLK value */
- clockpar = cv64_compute_clock (cv64_memclk);
- test = (clockpar & 0xFF00) >> 8;
- WSeq (regs, SEQ_ID_MCLK_HI, test);
- test = clockpar & 0xFF;
- WSeq (regs, SEQ_ID_MCLK_LO, test);
-
- /* Chip rev specific: Not in my Trio manual!!! */
- if (RCrt (regs, CRT_ID_REVISION) == 0x10)
- WSeq (regs, SEQ_ID_MORE_MAGIC, test);
-
- /* We now load an 25 MHz, 31kHz, 640x480 standard VGA Mode. */
-
- /* Set DCLK value */
- WSeq (regs, SEQ_ID_DCLK_HI, 0x13);
- WSeq (regs, SEQ_ID_DCLK_LO, 0x41);
-
- /* Load DCLK (and MCLK?) immediately */
- test = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2);
- test = test | 0x22;
- WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, test);
-
- /* Enable loading of DCLK */
- test = rb_64(regs, GREG_MISC_OUTPUT_R);
- test = test | 0x0C;
- wb_64 (regs, GREG_MISC_OUTPUT_W, test);
-
- /* Turn off immediate xCLK load */
- WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, 0x2);
-
- /* Horizontal character clock counts */
- /* 8 LSB of 9 bits = total line - 5 */
- WCrt (regs, CRT_ID_HOR_TOTAL, 0x5F);
- /* Active display line */
- WCrt (regs, CRT_ID_HOR_DISP_ENA_END, 0x4F);
- /* Blank assertion start */
- WCrt (regs, CRT_ID_START_HOR_BLANK, 0x50);
- /* Blank assertion end */
- WCrt (regs, CRT_ID_END_HOR_BLANK, 0x82);
- /* HSYNC assertion start */
- WCrt (regs, CRT_ID_START_HOR_RETR, 0x54);
- /* HSYNC assertion end */
- WCrt (regs, CRT_ID_END_HOR_RETR, 0x80);
- WCrt (regs, CRT_ID_VER_TOTAL, 0xBF);
- WCrt (regs, CRT_ID_OVERFLOW, 0x1F);
- WCrt (regs, CRT_ID_PRESET_ROW_SCAN, 0x0);
- WCrt (regs, CRT_ID_MAX_SCAN_LINE, 0x40);
- WCrt (regs, CRT_ID_CURSOR_START, 0x00);
- WCrt (regs, CRT_ID_CURSOR_END, 0x00);
- WCrt (regs, CRT_ID_START_ADDR_HIGH, 0x00);
- WCrt (regs, CRT_ID_START_ADDR_LOW, 0x00);
- WCrt (regs, CRT_ID_CURSOR_LOC_HIGH, 0x00);
- WCrt (regs, CRT_ID_CURSOR_LOC_LOW, 0x00);
- WCrt (regs, CRT_ID_START_VER_RETR, 0x9C);
- WCrt (regs, CRT_ID_END_VER_RETR, 0x0E);
- WCrt (regs, CRT_ID_VER_DISP_ENA_END, 0x8F);
- WCrt (regs, CRT_ID_SCREEN_OFFSET, 0x50);
- WCrt (regs, CRT_ID_UNDERLINE_LOC, 0x00);
- WCrt (regs, CRT_ID_START_VER_BLANK, 0x96);
- WCrt (regs, CRT_ID_END_VER_BLANK, 0xB9);
- WCrt (regs, CRT_ID_MODE_CONTROL, 0xE3);
- WCrt (regs, CRT_ID_LINE_COMPARE, 0xFF);
- WCrt (regs, CRT_ID_BACKWAD_COMP_3, 0x10); /* FIFO enabled */
- WCrt (regs, CRT_ID_MISC_1, 0x35);
- WCrt (regs, CRT_ID_DISPLAY_FIFO, 0x5A);
- WCrt (regs, CRT_ID_EXT_MEM_CNTL_2, 0x70);
- WCrt (regs, CRT_ID_LAW_POS_LO, 0x40);
- WCrt (regs, CRT_ID_EXT_MEM_CNTL_3, 0xFF);
-
- WGfx (regs, GCT_ID_SET_RESET, 0x0);
- WGfx (regs, GCT_ID_ENABLE_SET_RESET, 0x0);
- WGfx (regs, GCT_ID_COLOR_COMPARE, 0x0);
- WGfx (regs, GCT_ID_DATA_ROTATE, 0x0);
- WGfx (regs, GCT_ID_READ_MAP_SELECT, 0x0);
- WGfx (regs, GCT_ID_GRAPHICS_MODE, 0x40);
- WGfx (regs, GCT_ID_MISC, 0x01);
- WGfx (regs, GCT_ID_COLOR_XCARE, 0x0F);
- WGfx (regs, GCT_ID_BITMASK, 0xFF);
-
- /* Colors for text mode */
- for (i = 0; i < 0xf; i++)
- WAttr (regs, i, i);
-
- WAttr (regs, ACT_ID_ATTR_MODE_CNTL, 0x41);
- WAttr (regs, ACT_ID_OVERSCAN_COLOR, 0x01);
- WAttr (regs, ACT_ID_COLOR_PLANE_ENA, 0x0F);
- WAttr (regs, ACT_ID_HOR_PEL_PANNING, 0x0);
- WAttr (regs, ACT_ID_COLOR_SELECT, 0x0);
-
- wb_64 (regs, VDAC_MASK, 0xFF);
-
- *((unsigned long *) (regs + ECR_FRGD_COLOR)) = 0xFF;
- *((unsigned long *) (regs + ECR_BKGD_COLOR)) = 0;
-
- /* Colors initially set to grayscale */
-
- wb_64 (regs, VDAC_ADDRESS_W, 0);
- for (i = 255; i >= 0; i--) {
- wb_64(regs, VDAC_DATA, i);
- wb_64(regs, VDAC_DATA, i);
- wb_64(regs, VDAC_DATA, i);
- }
-
- /* GFx hardware cursor off */
- WCrt (regs, CRT_ID_HWGC_MODE, 0x00);
-
- /* Set first to 4MB, so test will work */
- WCrt (regs, CRT_ID_LAW_CNTL, 0x13);
- /* Find "correct" size of fbmem of Z3 board */
- if (cv_has_4mb (CyberMem)) {
- CyberSize = 1024 * 1024 * 4;
- WCrt (regs, CRT_ID_LAW_CNTL, 0x13);
- DPRINTK("4MB board\n");
- } else {
- CyberSize = 1024 * 1024 * 2;
- WCrt (regs, CRT_ID_LAW_CNTL, 0x12);
- DPRINTK("2MB board\n");
- }
-
- /* Initialize graphics engine */
- Cyber_WaitBlit();
- vgaw16 (regs, ECR_FRGD_MIX, 0x27);
- vgaw16 (regs, ECR_BKGD_MIX, 0x07);
- vgaw16 (regs, ECR_READ_REG_DATA, 0x1000);
- udelay(200);
- vgaw16 (regs, ECR_READ_REG_DATA, 0x2000);
- Cyber_WaitBlit();
- vgaw16 (regs, ECR_READ_REG_DATA, 0x3FFF);
- Cyber_WaitBlit();
- udelay(200);
- vgaw16 (regs, ECR_READ_REG_DATA, 0x4FFF);
- Cyber_WaitBlit();
- vgaw16 (regs, ECR_BITPLANE_WRITE_MASK, ~0);
- Cyber_WaitBlit();
- vgaw16 (regs, ECR_READ_REG_DATA, 0xE000);
- vgaw16 (regs, ECR_CURRENT_Y_POS2, 0x00);
- vgaw16 (regs, ECR_CURRENT_X_POS2, 0x00);
- vgaw16 (regs, ECR_READ_REG_DATA, 0xA000);
- vgaw16 (regs, ECR_DEST_Y__AX_STEP, 0x00);
- vgaw16 (regs, ECR_DEST_Y2__AX_STEP2, 0x00);
- vgaw16 (regs, ECR_DEST_X__DIA_STEP, 0x00);
- vgaw16 (regs, ECR_DEST_X2__DIA_STEP2, 0x00);
- vgaw16 (regs, ECR_SHORT_STROKE, 0x00);
- vgaw16 (regs, ECR_DRAW_CMD, 0x01);
-
- Cyber_WaitBlit();
-
- vgaw16 (regs, ECR_READ_REG_DATA, 0x4FFF);
- vgaw16 (regs, ECR_BKGD_COLOR, 0x01);
- vgaw16 (regs, ECR_FRGD_COLOR, 0x00);
-
-
- /* Enable video display (set bit 5) */
-/* ARB - Would also seem to write to AR13.
- * May want to use parts of WAttr to set JUST bit 5
- */
- WAttr (regs, 0x33, 0);
-
-/* GRF - function code ended here */
-
- /* Turn gfx on again */
- gfx_on_off (0, regs);
-
- /* Pass-through */
- cvscreen (0, CyberBase);
-
- DPRINTK("EXIT\n");
-}
-
-static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
-{
- volatile unsigned char *regs = CyberRegs;
- int fx, fy;
- unsigned short mnr;
- unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS, VSE, VT;
- char LACE, DBLSCAN, TEXT, CONSOLE;
- int cr50, sr15, sr18, clock_mode, test;
- int m, n;
- int tfillm, temptym;
- int hmul;
-
- /* ---------------- */
- int xres, hfront, hsync, hback;
- int yres, vfront, vsync, vback;
- int bpp;
-#if 0
- float freq_f;
-#endif
- long freq;
- /* ---------------- */
-
- DPRINTK("ENTER\n");
- TEXT = 0; /* if depth == 4 */
- CONSOLE = 0; /* mode num == 255 (console) */
- fx = fy = 8; /* force 8x8 font */
-
-/* GRF - Disable interrupts */
-
- gfx_on_off (1, regs);
-
- switch (video_mode->bits_per_pixel) {
- case 15:
- case 16:
- hmul = 2;
- break;
-
- default:
- hmul = 1;
- break;
- }
-
- bpp = video_mode->bits_per_pixel;
- xres = video_mode->xres;
- hfront = video_mode->right_margin;
- hsync = video_mode->hsync_len;
- hback = video_mode->left_margin;
-
- LACE = 0;
- DBLSCAN = 0;
-
- if (video_mode->vmode & FB_VMODE_DOUBLE) {
- yres = video_mode->yres * 2;
- vfront = video_mode->lower_margin * 2;
- vsync = video_mode->vsync_len * 2;
- vback = video_mode->upper_margin * 2;
- DBLSCAN = 1;
- } else if (video_mode->vmode & FB_VMODE_INTERLACED) {
- yres = (video_mode->yres + 1) / 2;
- vfront = (video_mode->lower_margin + 1) / 2;
- vsync = (video_mode->vsync_len + 1) / 2;
- vback = (video_mode->upper_margin + 1) / 2;
- LACE = 1;
- } else {
- yres = video_mode->yres;
- vfront = video_mode->lower_margin;
- vsync = video_mode->vsync_len;
- vback = video_mode->upper_margin;
- }
-
- /* ARB Dropping custom setup method from cvision.c */
-#if 0
- if (cvision_custom_mode) {
- HBS = hbs / 8 * hmul;
- HBE = hbe / 8 * hmul;
- HSS = hss / 8 * hmul;
- HSE = hse / 8 * hmul;
- HT = ht / 8 * hmul - 5;
-
- VBS = vbs - 1;
- VSS = vss;
- VSE = vse;
- VBE = vbe;
- VT = vt - 2;
- } else {
-#else
- {
-#endif
- HBS = hmul * (xres / 8);
- HBE = hmul * ((xres/8) + (hfront/8) + (hsync/8) + (hback/8) - 2);
- HSS = hmul * ((xres/8) + (hfront/8) + 2);
- HSE = hmul * ((xres/8) + (hfront/8) + (hsync/8) + 1);
- HT = hmul * ((xres/8) + (hfront/8) + (hsync/8) + (hback/8));
-
- VBS = yres;
- VBE = yres + vfront + vsync + vback - 2;
- VSS = yres + vfront - 1;
- VSE = yres + vfront + vsync - 1;
- VT = yres + vfront + vsync + vback - 2;
- }
-
- wb_64 (regs, ECR_ADV_FUNC_CNTL, (TEXT ? 0x00 : 0x31));
-
- if (TEXT)
- HDE = ((video_mode->xres + fx - 1) / fx) - 1;
- else
- HDE = (video_mode->xres + 3) * hmul / 8 - 1;
-
- VDE = video_mode->yres - 1;
-
- WCrt (regs, CRT_ID_HWGC_MODE, 0x00);
- WCrt (regs, CRT_ID_EXT_DAC_CNTL, 0x00);
-
- WSeq (regs, SEQ_ID_MEMORY_MODE,
- (TEXT || (video_mode->bits_per_pixel == 1)) ? 0x06 : 0x0e);
- WGfx (regs, GCT_ID_READ_MAP_SELECT, 0x00);
- WSeq (regs, SEQ_ID_MAP_MASK,
- (video_mode->bits_per_pixel == 1) ? 0x01 : 0xFF);
- WSeq (regs, SEQ_ID_CHAR_MAP_SELECT, 0x00);
-
- /* cv64_compute_clock accepts arguments in Hz */
- /* pixclock is in ps ... convert to Hz */
-
-#if 0
- freq_f = (1.0 / (float) video_mode->pixclock) * 1000000000;
- freq = ((long) freq_f) * 1000;
-#else
-/* freq = (long) ((long long)1000000000000 / (long long) video_mode->pixclock);
- */
- freq = (1000000000 / video_mode->pixclock) * 1000;
-#endif
-
- mnr = cv64_compute_clock (freq);
- WSeq (regs, SEQ_ID_DCLK_HI, ((mnr & 0xFF00) >> 8));
- WSeq (regs, SEQ_ID_DCLK_LO, (mnr & 0xFF));
-
- /* Load display parameters into board */
- WCrt (regs, CRT_ID_EXT_HOR_OVF,
- ((HT & 0x100) ? 0x01 : 0x00) |
- ((HDE & 0x100) ? 0x02 : 0x00) |
- ((HBS & 0x100) ? 0x04 : 0x00) |
- /* ((HBE & 0x40) ? 0x08 : 0x00) | */
- ((HSS & 0x100) ? 0x10 : 0x00) |
- /* ((HSE & 0x20) ? 0x20 : 0x00) | */
- (((HT-5) & 0x100) ? 0x40 : 0x00)
- );
-
- WCrt (regs, CRT_ID_EXT_VER_OVF,
- 0x40 |
- ((VT & 0x400) ? 0x01 : 0x00) |
- ((VDE & 0x400) ? 0x02 : 0x00) |
- ((VBS & 0x400) ? 0x04 : 0x00) |
- ((VSS & 0x400) ? 0x10 : 0x00)
- );
-
- WCrt (regs, CRT_ID_HOR_TOTAL, HT);
- WCrt (regs, CRT_ID_DISPLAY_FIFO, HT - 5);
- WCrt (regs, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? (HBS - 1) : HDE));
- WCrt (regs, CRT_ID_START_HOR_BLANK, HBS);
- WCrt (regs, CRT_ID_END_HOR_BLANK, ((HBE & 0x1F) | 0x80));
- WCrt (regs, CRT_ID_START_HOR_RETR, HSS);
- WCrt (regs, CRT_ID_END_HOR_RETR,
- (HSE & 0x1F) |
- ((HBE & 0x20) ? 0x80 : 0x00)
- );
- WCrt (regs, CRT_ID_VER_TOTAL, VT);
- WCrt (regs, CRT_ID_OVERFLOW,
- 0x10 |
- ((VT & 0x100) ? 0x01 : 0x00) |
- ((VDE & 0x100) ? 0x02 : 0x00) |
- ((VSS & 0x100) ? 0x04 : 0x00) |
- ((VBS & 0x100) ? 0x08 : 0x00) |
- ((VT & 0x200) ? 0x20 : 0x00) |
- ((VDE & 0x200) ? 0x40 : 0x00) |
- ((VSS & 0x200) ? 0x80 : 0x00)
- );
- WCrt (regs, CRT_ID_MAX_SCAN_LINE,
- 0x40 |
- (DBLSCAN ? 0x80 : 0x00) |
- ((VBS & 0x200) ? 0x20 : 0x00) |
- (TEXT ? ((fy - 1) & 0x1F) : 0x00)
- );
-
- WCrt (regs, CRT_ID_MODE_CONTROL, 0xE3);
-
- /* Text cursor */
-
- if (TEXT) {
-#if 1
- WCrt (regs, CRT_ID_CURSOR_START, (fy & 0x1f) - 2);
- WCrt (regs, CRT_ID_CURSOR_END, (fy & 0x1F) - 1);
-#else
- WCrt (regs, CRT_ID_CURSOR_START, 0x00);
- WCrt (regs, CRT_ID_CURSOR_END, fy & 0x1F);
-#endif
- WCrt (regs, CRT_ID_UNDERLINE_LOC, (fy - 1) & 0x1F);
- WCrt (regs, CRT_ID_CURSOR_LOC_HIGH, 0x00);
- WCrt (regs, CRT_ID_CURSOR_LOC_LOW, 0x00);
- }
-
- WCrt (regs, CRT_ID_START_ADDR_HIGH, 0x00);
- WCrt (regs, CRT_ID_START_ADDR_LOW, 0x00);
- WCrt (regs, CRT_ID_START_VER_RETR, VSS);
- WCrt (regs, CRT_ID_END_VER_RETR, (VSE & 0x0F));
- WCrt (regs, CRT_ID_VER_DISP_ENA_END, VDE);
- WCrt (regs, CRT_ID_START_VER_BLANK, VBS);
- WCrt (regs, CRT_ID_END_VER_BLANK, VBE);
- WCrt (regs, CRT_ID_LINE_COMPARE, 0xFF);
- WCrt (regs, CRT_ID_LACE_RETR_START, HT / 2);
- WCrt (regs, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00));
- WGfx (regs, GCT_ID_GRAPHICS_MODE,
- ((TEXT || (video_mode->bits_per_pixel == 1)) ? 0x00 : 0x40));
- WGfx (regs, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
- WSeq (regs, SEQ_ID_MEMORY_MODE,
- ((TEXT || (video_mode->bits_per_pixel == 1)) ? 0x06 : 0x02));
-
- wb_64 (regs, VDAC_MASK, 0xFF);
-
- /* Blank border */
- test = RCrt (regs, CRT_ID_BACKWAD_COMP_2);
- WCrt (regs, CRT_ID_BACKWAD_COMP_2, (test | 0x20));
-
- sr15 = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2);
- sr15 &= 0xEF;
- sr18 = RSeq (regs, SEQ_ID_RAMDAC_CNTL);
- sr18 &= 0x7F;
- clock_mode = 0x00;
- cr50 = 0x00;
-
- test = RCrt (regs, CRT_ID_EXT_MISC_CNTL_2);
- test &= 0xD;
-
- /* Clear roxxler byte-swapping... */
- cv64_write_port (0x0040, CyberBase);
- cv64_write_port (0x0020, CyberBase);
-
- switch (video_mode->bits_per_pixel) {
- case 1:
- case 4: /* text */
- HDE = video_mode->xres / 16;
- break;
-
- case 8:
- if (freq > 80000000) {
- clock_mode = 0x10 | 0x02;
- sr15 |= 0x10;
- sr18 |= 0x80;
- }
- HDE = video_mode->xres / 8;
- cr50 |= 0x00;
- break;
-
- case 15:
- cv64_write_port (0x8020, CyberBase);
- clock_mode = 0x30;
- HDE = video_mode->xres / 4;
- cr50 |= 0x10;
- break;
-
- case 16:
- cv64_write_port (0x8020, CyberBase);
- clock_mode = 0x50;
- HDE = video_mode->xres / 4;
- cr50 |= 0x10;
- break;
-
- case 24:
- case 32:
- cv64_write_port (0x8040, CyberBase);
- clock_mode = 0xD0;
- HDE = video_mode->xres / 2;
- cr50 |= 0x30;
- break;
- }
-
- WCrt (regs, CRT_ID_EXT_MISC_CNTL_2, clock_mode | test);
- WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, sr15);
- WSeq (regs, SEQ_ID_RAMDAC_CNTL, sr18);
- WCrt (regs, CRT_ID_SCREEN_OFFSET, HDE);
-
- WCrt (regs, CRT_ID_MISC_1, (TEXT ? 0x05 : 0x35));
-
- test = RCrt (regs, CRT_ID_EXT_SYS_CNTL_2);
- test &= ~0x30;
- test |= (HDE >> 4) & 0x30;
- WCrt (regs, CRT_ID_EXT_SYS_CNTL_2, test);
-
- /* Set up graphics engine */
- switch (video_mode->xres) {
- case 1024:
- cr50 |= 0x00;
- break;
-
- case 640:
- cr50 |= 0x40;
- break;
-
- case 800:
- cr50 |= 0x80;
- break;
-
- case 1280:
- cr50 |= 0xC0;
- break;
-
- case 1152:
- cr50 |= 0x01;
- break;
-
- case 1600:
- cr50 |= 0x81;
- break;
-
- default: /* XXX */
- break;
- }
-
- WCrt (regs, CRT_ID_EXT_SYS_CNTL_1, cr50);
-
- udelay(100);
- WAttr (regs, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x08 : 0x41));
- udelay(100);
- WAttr (regs, ACT_ID_COLOR_PLANE_ENA,
- (video_mode->bits_per_pixel == 1) ? 0x01 : 0x0F);
- udelay(100);
-
- tfillm = (96 * (cv64_memclk / 1000)) / 240000;
-
- switch (video_mode->bits_per_pixel) {
- case 32:
- case 24:
- temptym = (24 * (cv64_memclk / 1000)) / (freq / 1000);
- break;
- case 15:
- case 16:
- temptym = (48 * (cv64_memclk / 1000)) / (freq / 1000);
- break;
- case 4:
- temptym = (192 * (cv64_memclk / 1000)) / (freq / 1000);
- break;
- default:
- temptym = (96 * (cv64_memclk / 1000)) / (freq / 1000);
- break;
- }
-
- m = (temptym - tfillm - 9) / 2;
- if (m < 0)
- m = 0;
- m = (m & 0x1F) << 3;
- if (m < 0x18)
- m = 0x18;
- n = 0xFF;
-
- WCrt (regs, CRT_ID_EXT_MEM_CNTL_2, m);
- WCrt (regs, CRT_ID_EXT_MEM_CNTL_3, n);
- udelay(10);
-
- /* Text initialization */
-
- if (TEXT) {
- /* Do text initialization here ! */
- }
-
- if (CONSOLE) {
- int i;
- wb_64 (regs, VDAC_ADDRESS_W, 0);
- for (i = 0; i < 4; i++) {
- wb_64 (regs, VDAC_DATA, cvconscolors [i][0]);
- wb_64 (regs, VDAC_DATA, cvconscolors [i][1]);
- wb_64 (regs, VDAC_DATA, cvconscolors [i][2]);
- }
- }
-
- WAttr (regs, 0x33, 0);
-
- /* Turn gfx on again */
- gfx_on_off (0, (volatile unsigned char *) regs);
-
- /* Pass-through */
- cvscreen (0, CyberBase);
-
-DPRINTK("EXIT\n");
-}
-
-void cvision_bitblt (u_short sx, u_short sy, u_short dx, u_short dy,
- u_short w, u_short h)
-{
- volatile unsigned char *regs = CyberRegs;
- unsigned short drawdir = 0;
-
- DPRINTK("ENTER\n");
- if (sx > dx) {
- drawdir |= 1 << 5;
- } else {
- sx += w - 1;
- dx += w - 1;
- }
-
- if (sy > dy) {
- drawdir |= 1 << 7;
- } else {
- sy += h - 1;
- dy += h - 1;
- }
-
- Cyber_WaitBlit();
- vgaw16 (regs, ECR_READ_REG_DATA, 0xA000);
- vgaw16 (regs, ECR_BKGD_MIX, 0x7);
- vgaw16 (regs, ECR_FRGD_MIX, 0x67);
- vgaw16 (regs, ECR_BKGD_COLOR, 0x0);
- vgaw16 (regs, ECR_FRGD_COLOR, 0x1);
- vgaw16 (regs, ECR_BITPLANE_READ_MASK, 0x1);
- vgaw16 (regs, ECR_BITPLANE_WRITE_MASK, 0xFFF);
- vgaw16 (regs, ECR_CURRENT_Y_POS, sy);
- vgaw16 (regs, ECR_CURRENT_X_POS, sx);
- vgaw16 (regs, ECR_DEST_Y__AX_STEP, dy);
- vgaw16 (regs, ECR_DEST_X__DIA_STEP, dx);
- vgaw16 (regs, ECR_READ_REG_DATA, h - 1);
- vgaw16 (regs, ECR_MAJ_AXIS_PIX_CNT, w - 1);
- vgaw16 (regs, ECR_DRAW_CMD, 0xC051 | drawdir);
- DPRINTK("EXIT\n");
-}
-
-void cvision_clear (u_short dx, u_short dy, u_short w, u_short h, u_short bg)
-{
- volatile unsigned char *regs = CyberRegs;
- DPRINTK("ENTER\n");
- Cyber_WaitBlit();
- vgaw16 (regs, ECR_FRGD_MIX, 0x0027);
- vgaw16 (regs, ECR_FRGD_COLOR, bg);
- vgaw16 (regs, ECR_READ_REG_DATA, 0xA000);
- vgaw16 (regs, ECR_CURRENT_Y_POS, dy);
- vgaw16 (regs, ECR_CURRENT_X_POS, dx);
- vgaw16 (regs, ECR_READ_REG_DATA, h - 1);
- vgaw16 (regs, ECR_MAJ_AXIS_PIX_CNT, w - 1);
- vgaw16 (regs, ECR_DRAW_CMD, 0x40B1);
- DPRINTK("EXIT\n");
-}
-
-#ifdef CYBERFBDEBUG
-/*
- * Dump internal settings of CyberVision board
- */
-static void cv64_dump (void)
-{
- volatile unsigned char *regs = CyberRegs;
- DPRINTK("ENTER\n");
- /* Dump the VGA setup values */
- *(regs + S3_CRTC_ADR) = 0x00;
- DPRINTK("CR00 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x01;
- DPRINTK("CR01 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x02;
- DPRINTK("CR02 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x03;
- DPRINTK("CR03 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x04;
- DPRINTK("CR04 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x05;
- DPRINTK("CR05 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x06;
- DPRINTK("CR06 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x07;
- DPRINTK("CR07 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x08;
- DPRINTK("CR08 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x09;
- DPRINTK("CR09 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x10;
- DPRINTK("CR10 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x11;
- DPRINTK("CR11 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x12;
- DPRINTK("CR12 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x13;
- DPRINTK("CR13 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x15;
- DPRINTK("CR15 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x16;
- DPRINTK("CR16 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x36;
- DPRINTK("CR36 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x37;
- DPRINTK("CR37 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x42;
- DPRINTK("CR42 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x43;
- DPRINTK("CR43 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x50;
- DPRINTK("CR50 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x51;
- DPRINTK("CR51 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x53;
- DPRINTK("CR53 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x58;
- DPRINTK("CR58 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x59;
- DPRINTK("CR59 = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x5A;
- DPRINTK("CR5A = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x5D;
- DPRINTK("CR5D = %x\n", *(regs + S3_CRTC_DATA));
- *(regs + S3_CRTC_ADR) = 0x5E;
- DPRINTK("CR5E = %x\n", *(regs + S3_CRTC_DATA));
- DPRINTK("MISC = %x\n", *(regs + GREG_MISC_OUTPUT_R));
- *(regs + SEQ_ADDRESS) = 0x01;
- DPRINTK("SR01 = %x\n", *(regs + SEQ_ADDRESS_R));
- *(regs + SEQ_ADDRESS) = 0x02;
- DPRINTK("SR02 = %x\n", *(regs + SEQ_ADDRESS_R));
- *(regs + SEQ_ADDRESS) = 0x03;
- DPRINTK("SR03 = %x\n", *(regs + SEQ_ADDRESS_R));
- *(regs + SEQ_ADDRESS) = 0x09;
- DPRINTK("SR09 = %x\n", *(regs + SEQ_ADDRESS_R));
- *(regs + SEQ_ADDRESS) = 0x10;
- DPRINTK("SR10 = %x\n", *(regs + SEQ_ADDRESS_R));
- *(regs + SEQ_ADDRESS) = 0x11;
- DPRINTK("SR11 = %x\n", *(regs + SEQ_ADDRESS_R));
- *(regs + SEQ_ADDRESS) = 0x12;
- DPRINTK("SR12 = %x\n", *(regs + SEQ_ADDRESS_R));
- *(regs + SEQ_ADDRESS) = 0x13;
- DPRINTK("SR13 = %x\n", *(regs + SEQ_ADDRESS_R));
- *(regs + SEQ_ADDRESS) = 0x15;
- DPRINTK("SR15 = %x\n", *(regs + SEQ_ADDRESS_R));
-
- return;
-}
-#endif
diff --git a/drivers/video/cyberfb.h b/drivers/video/cyberfb.h
deleted file mode 100644
index 8435c430ad27..000000000000
--- a/drivers/video/cyberfb.h
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * linux/arch/m68k/console/cvision.h -- CyberVision64 definitions for the
- * text console driver.
- *
- * Copyright (c) 1998 Alan Bair
- *
- * This file is based on the initial port to Linux of grf_cvreg.h:
- *
- * Copyright (c) 1997 Antonio Santos
- *
- * The original work is from the NetBSD CyberVision 64 framebuffer driver
- * and support files (grf_cv.c, grf_cvreg.h, ite_cv.c):
- * Permission to use the source of this driver was obtained from the
- * author Michael Teske by Alan Bair.
- *
- * Copyright (c) 1995 Michael Teske
- *
- * History:
- *
- *
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-/* s3 commands */
-#define S3_BITBLT 0xc011
-#define S3_TWOPOINTLINE 0x2811
-#define S3_FILLEDRECT 0x40b1
-
-#define S3_FIFO_EMPTY 0x0400
-#define S3_HDW_BUSY 0x0200
-
-/* Enhanced register mapping (MMIO mode) */
-
-#define S3_READ_SEL 0xbee8 /* offset f */
-#define S3_MULT_MISC 0xbee8 /* offset e */
-#define S3_ERR_TERM 0x92e8
-#define S3_FRGD_COLOR 0xa6e8
-#define S3_BKGD_COLOR 0xa2e8
-#define S3_PIXEL_CNTL 0xbee8 /* offset a */
-#define S3_FRGD_MIX 0xbae8
-#define S3_BKGD_MIX 0xb6e8
-#define S3_CUR_Y 0x82e8
-#define S3_CUR_X 0x86e8
-#define S3_DESTY_AXSTP 0x8ae8
-#define S3_DESTX_DIASTP 0x8ee8
-#define S3_MIN_AXIS_PCNT 0xbee8 /* offset 0 */
-#define S3_MAJ_AXIS_PCNT 0x96e8
-#define S3_CMD 0x9ae8
-#define S3_GP_STAT 0x9ae8
-#define S3_ADVFUNC_CNTL 0x4ae8
-#define S3_WRT_MASK 0xaae8
-#define S3_RD_MASK 0xaee8
-
-/* Enhanced register mapping (Packed MMIO mode, write only) */
-#define S3_ALT_CURXY 0x8100
-#define S3_ALT_CURXY2 0x8104
-#define S3_ALT_STEP 0x8108
-#define S3_ALT_STEP2 0x810c
-#define S3_ALT_ERR 0x8110
-#define S3_ALT_CMD 0x8118
-#define S3_ALT_MIX 0x8134
-#define S3_ALT_PCNT 0x8148
-#define S3_ALT_PAT 0x8168
-
-/* Drawing modes */
-#define S3_NOTCUR 0x0000
-#define S3_LOGICALZERO 0x0001
-#define S3_LOGICALONE 0x0002
-#define S3_LEAVEASIS 0x0003
-#define S3_NOTNEW 0x0004
-#define S3_CURXORNEW 0x0005
-#define S3_NOT_CURXORNEW 0x0006
-#define S3_NEW 0x0007
-#define S3_NOTCURORNOTNEW 0x0008
-#define S3_CURORNOTNEW 0x0009
-#define S3_NOTCURORNEW 0x000a
-#define S3_CURORNEW 0x000b
-#define S3_CURANDNEW 0x000c
-#define S3_NOTCURANDNEW 0x000d
-#define S3_CURANDNOTNEW 0x000e
-#define S3_NOTCURANDNOTNEW 0x000f
-
-#define S3_CRTC_ADR 0x03d4
-#define S3_CRTC_DATA 0x03d5
-
-#define S3_REG_LOCK2 0x39
-#define S3_HGC_MODE 0x45
-
-#define S3_HWGC_ORGX_H 0x46
-#define S3_HWGC_ORGX_L 0x47
-#define S3_HWGC_ORGY_H 0x48
-#define S3_HWGC_ORGY_L 0x49
-#define S3_HWGC_DX 0x4e
-#define S3_HWGC_DY 0x4f
-
-#define S3_LAW_CTL 0x58
-
-/**************************************************/
-
-/* support for a BitBlt operation. The op-codes are identical
- to X11 GCs */
-#define GRFBBOPclear 0x0 /* 0 */
-#define GRFBBOPand 0x1 /* src AND dst */
-#define GRFBBOPandReverse 0x2 /* src AND NOT dst */
-#define GRFBBOPcopy 0x3 /* src */
-#define GRFBBOPandInverted 0x4 /* NOT src AND dst */
-#define GRFBBOPnoop 0x5 /* dst */
-#define GRFBBOPxor 0x6 /* src XOR dst */
-#define GRFBBOPor 0x7 /* src OR dst */
-#define GRFBBOPnor 0x8 /* NOT src AND NOT dst */
-#define GRFBBOPequiv 0x9 /* NOT src XOR dst */
-#define GRFBBOPinvert 0xa /* NOT dst */
-#define GRFBBOPorReverse 0xb /* src OR NOT dst */
-#define GRFBBOPcopyInverted 0xc /* NOT src */
-#define GRFBBOPorInverted 0xd /* NOT src OR dst */
-#define GRFBBOPnand 0xe /* NOT src OR NOT dst */
-#define GRFBBOPset 0xf /* 1 */
-
-
-/* Write 16 Bit VGA register */
-#define vgaw16(ba, reg, val) \
-*((unsigned short *) (((volatile unsigned char *)ba)+reg)) = val
-
-/*
- * Defines for the used register addresses (mw)
- *
- * NOTE: There are some registers that have different addresses when
- * in mono or color mode. We only support color mode, and thus
- * some addresses won't work in mono-mode!
- *
- * General and VGA-registers taken from retina driver. Fixed a few
- * bugs in it. (SR and GR read address is Port + 1, NOT Port)
- *
- */
-
-/* General Registers: */
-#define GREG_MISC_OUTPUT_R 0x03CC
-#define GREG_MISC_OUTPUT_W 0x03C2
-#define GREG_FEATURE_CONTROL_R 0x03CA
-#define GREG_FEATURE_CONTROL_W 0x03DA
-#define GREG_INPUT_STATUS0_R 0x03C2
-#define GREG_INPUT_STATUS1_R 0x03DA
-
-/* Setup Registers: */
-#define SREG_OPTION_SELECT 0x0102
-#define SREG_VIDEO_SUBS_ENABLE 0x46E8
-
-/* Attribute Controller: */
-#define ACT_ADDRESS 0x03C0
-#define ACT_ADDRESS_R 0x03C1
-#define ACT_ADDRESS_W 0x03C0
-#define ACT_ADDRESS_RESET 0x03DA
-#define ACT_ID_PALETTE0 0x00
-#define ACT_ID_PALETTE1 0x01
-#define ACT_ID_PALETTE2 0x02
-#define ACT_ID_PALETTE3 0x03
-#define ACT_ID_PALETTE4 0x04
-#define ACT_ID_PALETTE5 0x05
-#define ACT_ID_PALETTE6 0x06
-#define ACT_ID_PALETTE7 0x07
-#define ACT_ID_PALETTE8 0x08
-#define ACT_ID_PALETTE9 0x09
-#define ACT_ID_PALETTE10 0x0A
-#define ACT_ID_PALETTE11 0x0B
-#define ACT_ID_PALETTE12 0x0C
-#define ACT_ID_PALETTE13 0x0D
-#define ACT_ID_PALETTE14 0x0E
-#define ACT_ID_PALETTE15 0x0F
-#define ACT_ID_ATTR_MODE_CNTL 0x10
-#define ACT_ID_OVERSCAN_COLOR 0x11
-#define ACT_ID_COLOR_PLANE_ENA 0x12
-#define ACT_ID_HOR_PEL_PANNING 0x13
-#define ACT_ID_COLOR_SELECT 0x14
-
-/* Graphics Controller: */
-#define GCT_ADDRESS 0x03CE
-#define GCT_ADDRESS_R 0x03CF
-#define GCT_ADDRESS_W 0x03CF
-#define GCT_ID_SET_RESET 0x00
-#define GCT_ID_ENABLE_SET_RESET 0x01
-#define GCT_ID_COLOR_COMPARE 0x02
-#define GCT_ID_DATA_ROTATE 0x03
-#define GCT_ID_READ_MAP_SELECT 0x04
-#define GCT_ID_GRAPHICS_MODE 0x05
-#define GCT_ID_MISC 0x06
-#define GCT_ID_COLOR_XCARE 0x07
-#define GCT_ID_BITMASK 0x08
-
-/* Sequencer: */
-#define SEQ_ADDRESS 0x03C4
-#define SEQ_ADDRESS_R 0x03C5
-#define SEQ_ADDRESS_W 0x03C5
-#define SEQ_ID_RESET 0x00
-#define SEQ_ID_CLOCKING_MODE 0x01
-#define SEQ_ID_MAP_MASK 0x02
-#define SEQ_ID_CHAR_MAP_SELECT 0x03
-#define SEQ_ID_MEMORY_MODE 0x04
-#define SEQ_ID_UNKNOWN1 0x05
-#define SEQ_ID_UNKNOWN2 0x06
-#define SEQ_ID_UNKNOWN3 0x07
-/* S3 extensions */
-#define SEQ_ID_UNLOCK_EXT 0x08
-#define SEQ_ID_EXT_SEQ_REG9 0x09
-#define SEQ_ID_BUS_REQ_CNTL 0x0A
-#define SEQ_ID_EXT_MISC_SEQ 0x0B
-#define SEQ_ID_UNKNOWN4 0x0C
-#define SEQ_ID_EXT_SEQ 0x0D
-#define SEQ_ID_UNKNOWN5 0x0E
-#define SEQ_ID_UNKNOWN6 0x0F
-#define SEQ_ID_MCLK_LO 0x10
-#define SEQ_ID_MCLK_HI 0x11
-#define SEQ_ID_DCLK_LO 0x12
-#define SEQ_ID_DCLK_HI 0x13
-#define SEQ_ID_CLKSYN_CNTL_1 0x14
-#define SEQ_ID_CLKSYN_CNTL_2 0x15
-#define SEQ_ID_CLKSYN_TEST_HI 0x16 /* reserved for S3 testing of the */
-#define SEQ_ID_CLKSYN_TEST_LO 0x17 /* internal clock synthesizer */
-#define SEQ_ID_RAMDAC_CNTL 0x18
-#define SEQ_ID_MORE_MAGIC 0x1A
-
-/* CRT Controller: */
-#define CRT_ADDRESS 0x03D4
-#define CRT_ADDRESS_R 0x03D5
-#define CRT_ADDRESS_W 0x03D5
-#define CRT_ID_HOR_TOTAL 0x00
-#define CRT_ID_HOR_DISP_ENA_END 0x01
-#define CRT_ID_START_HOR_BLANK 0x02
-#define CRT_ID_END_HOR_BLANK 0x03
-#define CRT_ID_START_HOR_RETR 0x04
-#define CRT_ID_END_HOR_RETR 0x05
-#define CRT_ID_VER_TOTAL 0x06
-#define CRT_ID_OVERFLOW 0x07
-#define CRT_ID_PRESET_ROW_SCAN 0x08
-#define CRT_ID_MAX_SCAN_LINE 0x09
-#define CRT_ID_CURSOR_START 0x0A
-#define CRT_ID_CURSOR_END 0x0B
-#define CRT_ID_START_ADDR_HIGH 0x0C
-#define CRT_ID_START_ADDR_LOW 0x0D
-#define CRT_ID_CURSOR_LOC_HIGH 0x0E
-#define CRT_ID_CURSOR_LOC_LOW 0x0F
-#define CRT_ID_START_VER_RETR 0x10
-#define CRT_ID_END_VER_RETR 0x11
-#define CRT_ID_VER_DISP_ENA_END 0x12
-#define CRT_ID_SCREEN_OFFSET 0x13
-#define CRT_ID_UNDERLINE_LOC 0x14
-#define CRT_ID_START_VER_BLANK 0x15
-#define CRT_ID_END_VER_BLANK 0x16
-#define CRT_ID_MODE_CONTROL 0x17
-#define CRT_ID_LINE_COMPARE 0x18
-#define CRT_ID_GD_LATCH_RBACK 0x22
-#define CRT_ID_ACT_TOGGLE_RBACK 0x24
-#define CRT_ID_ACT_INDEX_RBACK 0x26
-/* S3 extensions: S3 VGA Registers */
-#define CRT_ID_DEVICE_HIGH 0x2D
-#define CRT_ID_DEVICE_LOW 0x2E
-#define CRT_ID_REVISION 0x2F
-#define CRT_ID_CHIP_ID_REV 0x30
-#define CRT_ID_MEMORY_CONF 0x31
-#define CRT_ID_BACKWAD_COMP_1 0x32
-#define CRT_ID_BACKWAD_COMP_2 0x33
-#define CRT_ID_BACKWAD_COMP_3 0x34
-#define CRT_ID_REGISTER_LOCK 0x35
-#define CRT_ID_CONFIG_1 0x36
-#define CRT_ID_CONFIG_2 0x37
-#define CRT_ID_REGISTER_LOCK_1 0x38
-#define CRT_ID_REGISTER_LOCK_2 0x39
-#define CRT_ID_MISC_1 0x3A
-#define CRT_ID_DISPLAY_FIFO 0x3B
-#define CRT_ID_LACE_RETR_START 0x3C
-/* S3 extensions: System Control Registers */
-#define CRT_ID_SYSTEM_CONFIG 0x40
-#define CRT_ID_BIOS_FLAG 0x41
-#define CRT_ID_LACE_CONTROL 0x42
-#define CRT_ID_EXT_MODE 0x43
-#define CRT_ID_HWGC_MODE 0x45 /* HWGC = Hardware Graphics Cursor */
-#define CRT_ID_HWGC_ORIGIN_X_HI 0x46
-#define CRT_ID_HWGC_ORIGIN_X_LO 0x47
-#define CRT_ID_HWGC_ORIGIN_Y_HI 0x48
-#define CRT_ID_HWGC_ORIGIN_Y_LO 0x49
-#define CRT_ID_HWGC_FG_STACK 0x4A
-#define CRT_ID_HWGC_BG_STACK 0x4B
-#define CRT_ID_HWGC_START_AD_HI 0x4C
-#define CRT_ID_HWGC_START_AD_LO 0x4D
-#define CRT_ID_HWGC_DSTART_X 0x4E
-#define CRT_ID_HWGC_DSTART_Y 0x4F
-/* S3 extensions: System Extension Registers */
-#define CRT_ID_EXT_SYS_CNTL_1 0x50
-#define CRT_ID_EXT_SYS_CNTL_2 0x51
-#define CRT_ID_EXT_BIOS_FLAG_1 0x52
-#define CRT_ID_EXT_MEM_CNTL_1 0x53
-#define CRT_ID_EXT_MEM_CNTL_2 0x54
-#define CRT_ID_EXT_DAC_CNTL 0x55
-#define CRT_ID_EX_SYNC_1 0x56
-#define CRT_ID_EX_SYNC_2 0x57
-#define CRT_ID_LAW_CNTL 0x58 /* LAW = Linear Address Window */
-#define CRT_ID_LAW_POS_HI 0x59
-#define CRT_ID_LAW_POS_LO 0x5A
-#define CRT_ID_GOUT_PORT 0x5C
-#define CRT_ID_EXT_HOR_OVF 0x5D
-#define CRT_ID_EXT_VER_OVF 0x5E
-#define CRT_ID_EXT_MEM_CNTL_3 0x60
-#define CRT_ID_EX_SYNC_3 0x63
-#define CRT_ID_EXT_MISC_CNTL 0x65
-#define CRT_ID_EXT_MISC_CNTL_1 0x66
-#define CRT_ID_EXT_MISC_CNTL_2 0x67
-#define CRT_ID_CONFIG_3 0x68
-#define CRT_ID_EXT_SYS_CNTL_3 0x69
-#define CRT_ID_EXT_SYS_CNTL_4 0x6A
-#define CRT_ID_EXT_BIOS_FLAG_3 0x6B
-#define CRT_ID_EXT_BIOS_FLAG_4 0x6C
-
-/* Enhanced Commands Registers: */
-#define ECR_SUBSYSTEM_STAT 0x42E8
-#define ECR_SUBSYSTEM_CNTL 0x42E8
-#define ECR_ADV_FUNC_CNTL 0x4AE8
-#define ECR_CURRENT_Y_POS 0x82E8
-#define ECR_CURRENT_Y_POS2 0x82EA /* Trio64 only */
-#define ECR_CURRENT_X_POS 0x86E8
-#define ECR_CURRENT_X_POS2 0x86EA /* Trio64 only */
-#define ECR_DEST_Y__AX_STEP 0x8AE8
-#define ECR_DEST_Y2__AX_STEP2 0x8AEA /* Trio64 only */
-#define ECR_DEST_X__DIA_STEP 0x8EE8
-#define ECR_DEST_X2__DIA_STEP2 0x8EEA /* Trio64 only */
-#define ECR_ERR_TERM 0x92E8
-#define ECR_ERR_TERM2 0x92EA /* Trio64 only */
-#define ECR_MAJ_AXIS_PIX_CNT 0x96E8
-#define ECR_MAJ_AXIS_PIX_CNT2 0x96EA /* Trio64 only */
-#define ECR_GP_STAT 0x9AE8 /* GP = Graphics Processor */
-#define ECR_DRAW_CMD 0x9AE8
-#define ECR_DRAW_CMD2 0x9AEA /* Trio64 only */
-#define ECR_SHORT_STROKE 0x9EE8
-#define ECR_BKGD_COLOR 0xA2E8 /* BKGD = Background */
-#define ECR_FRGD_COLOR 0xA6E8 /* FRGD = Foreground */
-#define ECR_BITPLANE_WRITE_MASK 0xAAE8
-#define ECR_BITPLANE_READ_MASK 0xAEE8
-#define ECR_COLOR_COMPARE 0xB2E8
-#define ECR_BKGD_MIX 0xB6E8
-#define ECR_FRGD_MIX 0xBAE8
-#define ECR_READ_REG_DATA 0xBEE8
-#define ECR_ID_MIN_AXIS_PIX_CNT 0x00
-#define ECR_ID_SCISSORS_TOP 0x01
-#define ECR_ID_SCISSORS_LEFT 0x02
-#define ECR_ID_SCISSORS_BUTTOM 0x03
-#define ECR_ID_SCISSORS_RIGHT 0x04
-#define ECR_ID_PIX_CNTL 0x0A
-#define ECR_ID_MULT_CNTL_MISC_2 0x0D
-#define ECR_ID_MULT_CNTL_MISC 0x0E
-#define ECR_ID_READ_SEL 0x0F
-#define ECR_PIX_TRANS 0xE2E8
-#define ECR_PIX_TRANS_EXT 0xE2EA
-#define ECR_PATTERN_Y 0xEAE8 /* Trio64 only */
-#define ECR_PATTERN_X 0xEAEA /* Trio64 only */
-
-
-/* Pass-through */
-#define PASS_ADDRESS 0x40001
-#define PASS_ADDRESS_W 0x40001
-
-/* Video DAC */
-#define VDAC_ADDRESS 0x03c8
-#define VDAC_ADDRESS_W 0x03c8
-#define VDAC_ADDRESS_R 0x03c7
-#define VDAC_STATE 0x03c7
-#define VDAC_DATA 0x03c9
-#define VDAC_MASK 0x03c6
-
-
-#define WGfx(ba, idx, val) \
-do { wb_64(ba, GCT_ADDRESS, idx); wb_64(ba, GCT_ADDRESS_W , val); } while (0)
-
-#define WSeq(ba, idx, val) \
-do { wb_64(ba, SEQ_ADDRESS, idx); wb_64(ba, SEQ_ADDRESS_W , val); } while (0)
-
-#define WCrt(ba, idx, val) \
-do { wb_64(ba, CRT_ADDRESS, idx); wb_64(ba, CRT_ADDRESS_W , val); } while (0)
-
-#define WAttr(ba, idx, val) \
-do { \
- unsigned char tmp;\
- tmp = rb_64(ba, ACT_ADDRESS_RESET);\
- wb_64(ba, ACT_ADDRESS_W, idx);\
- wb_64(ba, ACT_ADDRESS_W, val);\
-} while (0)
-
-#define SetTextPlane(ba, m) \
-do { \
- WGfx(ba, GCT_ID_READ_MAP_SELECT, m & 3 );\
- WSeq(ba, SEQ_ID_MAP_MASK, (1 << (m & 3)));\
-} while (0)
-
- /* --------------------------------- */
- /* prototypes */
- /* --------------------------------- */
-
-inline unsigned char RAttr(volatile unsigned char * board, short idx);
-inline unsigned char RSeq(volatile unsigned char * board, short idx);
-inline unsigned char RCrt(volatile unsigned char * board, short idx);
-inline unsigned char RGfx(volatile unsigned char * board, short idx);
-inline void cv64_write_port(unsigned short bits,
- volatile unsigned char *board);
-inline void cvscreen(int toggle, volatile unsigned char *board);
-inline void gfx_on_off(int toggle, volatile unsigned char *board);
-#if 0
-unsigned short cv64_compute_clock(unsigned long freq);
-int cv_has_4mb(volatile unsigned char * fb);
-void cv64_board_init(void);
-void cv64_load_video_mode(struct fb_var_screeninfo *video_mode);
-#endif
-
-void cvision_bitblt(u_short sx, u_short sy, u_short dx, u_short dy, u_short w,
- u_short h);
-void cvision_clear(u_short dx, u_short dy, u_short w, u_short h, u_short bg);
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 323bdf6fc7d5..818fb09105f9 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -175,7 +175,7 @@ static ssize_t store_modes(struct device *device,
acquire_console_sem();
list_splice(&fb_info->modelist, &old_list);
- fb_videomode_to_modelist((struct fb_videomode *)buf, i,
+ fb_videomode_to_modelist((const struct fb_videomode *)buf, i,
&fb_info->modelist);
if (fb_new_modelist(fb_info)) {
fb_destroy_modelist(&fb_info->modelist);
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index bcf9cea54d8b..bb20a2289760 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -401,6 +401,30 @@ static void gx1fb_remove(struct pci_dev *pdev)
framebuffer_release(info);
}
+#ifndef MODULE
+static void __init gx1fb_setup(char *options)
+{
+ char *this_opt;
+
+ if (!options || !*options)
+ return;
+
+ while ((this_opt = strsep(&options, ","))) {
+ if (!*this_opt)
+ continue;
+
+ if (!strncmp(this_opt, "mode:", 5))
+ strlcpy(mode_option, this_opt + 5, sizeof(mode_option));
+ else if (!strncmp(this_opt, "crt:", 4))
+ crt_option = !!simple_strtoul(this_opt + 4, NULL, 0);
+ else if (!strncmp(this_opt, "panel:", 6))
+ strlcpy(panel_option, this_opt + 6, sizeof(panel_option));
+ else
+ strlcpy(mode_option, this_opt, sizeof(mode_option));
+ }
+}
+#endif
+
static struct pci_device_id gx1fb_id_table[] = {
{ PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_VIDEO,
PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
@@ -420,8 +444,11 @@ static struct pci_driver gx1fb_driver = {
static int __init gx1fb_init(void)
{
#ifndef MODULE
- if (fb_get_options("gx1fb", NULL))
+ char *option = NULL;
+
+ if (fb_get_options("gx1fb", &option))
return -ENODEV;
+ gx1fb_setup(option);
#endif
return pci_register_driver(&gx1fb_driver);
}
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index 579195c2bea3..aa65ffce915b 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -264,7 +264,8 @@ struct i810fb_par {
struct heap_data cursor_heap;
struct vgastate state;
struct i810fb_i2c_chan chan[3];
- atomic_t use_count;
+ struct mutex open_lock;
+ unsigned int use_count;
u32 pseudo_palette[17];
unsigned long mmio_start_phys;
u8 __iomem *mmio_start_virtual;
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index b55a12d95eb2..ab1b8fe34d6d 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -1049,7 +1049,7 @@ static int i810_check_params(struct fb_var_screeninfo *var,
mode_valid = 1;
if (!mode_valid && info->monspecs.modedb_len) {
- struct fb_videomode *mode;
+ const struct fb_videomode *mode;
mode = fb_find_best_mode(var, &info->modelist);
if (mode) {
@@ -1235,9 +1235,9 @@ static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue,
static int i810fb_open(struct fb_info *info, int user)
{
struct i810fb_par *par = info->par;
- u32 count = atomic_read(&par->use_count);
-
- if (count == 0) {
+
+ mutex_lock(&par->open_lock);
+ if (par->use_count == 0) {
memset(&par->state, 0, sizeof(struct vgastate));
par->state.flags = VGA_SAVE_CMAP;
par->state.vgabase = par->mmio_start_virtual;
@@ -1246,7 +1246,8 @@ static int i810fb_open(struct fb_info *info, int user)
i810_save_vga_state(par);
}
- atomic_inc(&par->use_count);
+ par->use_count++;
+ mutex_unlock(&par->open_lock);
return 0;
}
@@ -1254,18 +1255,20 @@ static int i810fb_open(struct fb_info *info, int user)
static int i810fb_release(struct fb_info *info, int user)
{
struct i810fb_par *par = info->par;
- u32 count;
-
- count = atomic_read(&par->use_count);
- if (count == 0)
+
+ mutex_lock(&par->open_lock);
+ if (par->use_count == 0) {
+ mutex_unlock(&par->open_lock);
return -EINVAL;
+ }
- if (count == 1) {
+ if (par->use_count == 1) {
i810_restore_vga_state(par);
restore_vga(&par->state);
}
- atomic_dec(&par->use_count);
+ par->use_count--;
+ mutex_unlock(&par->open_lock);
return 0;
}
@@ -1752,6 +1755,8 @@ static void __devinit i810_init_monspecs(struct fb_info *info)
static void __devinit i810_init_defaults(struct i810fb_par *par,
struct fb_info *info)
{
+ mutex_init(&par->open_lock);
+
if (voffset)
v_offset_default = voffset;
else if (par->aperture.size > 32 * 1024 * 1024)
@@ -1919,7 +1924,7 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info)
fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
&info->modelist);
if (specs->modedb != NULL) {
- struct fb_videomode *m;
+ const struct fb_videomode *m;
if (xres && yres) {
if ((m = fb_find_best_mode(&var, &info->modelist))) {
@@ -2016,11 +2021,10 @@ static int __devinit i810fb_init_pci (struct pci_dev *dev,
par = info->par;
par->dev = dev;
- if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) {
+ if (!(info->pixmap.addr = kzalloc(8*1024, GFP_KERNEL))) {
i810fb_release_resource(info, par);
return -ENOMEM;
}
- memset(info->pixmap.addr, 0, 8*1024);
info->pixmap.size = 8*1024;
info->pixmap.buf_align = 8;
info->pixmap.access_align = 32;
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index 655ae0fa99ca..90592fb59156 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -370,7 +370,6 @@ static int __init iga_init(struct fb_info *info, struct iga_par *par)
int __init igafb_init(void)
{
- extern int con_is_present(void);
struct fb_info *info;
struct pci_dev *pdev;
struct iga_par *par;
@@ -402,12 +401,11 @@ int __init igafb_init(void)
size = sizeof(struct fb_info) + sizeof(struct iga_par) + sizeof(u32)*16;
- info = kmalloc(size, GFP_ATOMIC);
+ info = kzalloc(size, GFP_ATOMIC);
if (!info) {
printk("igafb_init: can't alloc fb_info\n");
return -ENOMEM;
}
- memset(info, 0, size);
par = (struct iga_par *) (info + 1);
@@ -466,7 +464,7 @@ int __init igafb_init(void)
* one additional region with size == 0.
*/
- par->mmap_map = kmalloc(4 * sizeof(*par->mmap_map), GFP_ATOMIC);
+ par->mmap_map = kzalloc(4 * sizeof(*par->mmap_map), GFP_ATOMIC);
if (!par->mmap_map) {
printk("igafb_init: can't alloc mmap_map\n");
iounmap((void *)par->io_base);
@@ -475,8 +473,6 @@ int __init igafb_init(void)
return -ENOMEM;
}
- memset(par->mmap_map, 0, 4 * sizeof(*par->mmap_map));
-
/*
* Set default vmode and cmode from PROM properties.
*/
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 664fc5cf962a..b75eda84858f 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -540,12 +540,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
dinfo->pdev = pdev;
/* Reserve pixmap space. */
- info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
+ info->pixmap.addr = kzalloc(64 * 1024, GFP_KERNEL);
if (info->pixmap.addr == NULL) {
ERR_MSG("Cannot reserve pixmap memory.\n");
goto err_out_pixmap;
}
- memset(info->pixmap.addr, 0, 64 * 1024);
/* set early this option because it could be changed by tv encoder
driver */
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index fe28848e7b52..f64c4a0984cd 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -146,7 +146,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
unsigned long flags;
struct matroxfb_dh_maven_info* m2info;
- m2info = kmalloc(sizeof(*m2info), GFP_KERNEL);
+ m2info = kzalloc(sizeof(*m2info), GFP_KERNEL);
if (!m2info)
return NULL;
@@ -155,8 +155,6 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
matroxfb_DAC_out(PMINFO DAC_XGENIOCTRL, 0x00);
matroxfb_DAC_unlock_irqrestore(flags);
- memset(m2info, 0, sizeof(*m2info));
-
switch (ACCESS_FBINFO(chip)) {
case MGA_2064:
case MGA_2164:
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 2c9801090fae..03ae55b168ff 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -694,12 +694,11 @@ static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) {
/* hardware is CRTC2 incapable... */
if (!ACCESS_FBINFO(devflags.crtc2))
return NULL;
- m2info = kmalloc(sizeof(*m2info), GFP_KERNEL);
+ m2info = kzalloc(sizeof(*m2info), GFP_KERNEL);
if (!m2info) {
printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n");
return NULL;
}
- memset(m2info, 0, sizeof(*m2info));
m2info->primary_dev = MINFO;
if (matroxfb_dh_registerfb(m2info)) {
kfree(m2info);
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/mbx/mbxdebugfs.c
index 472a3ca3d92d..15b8b3c4330e 100644
--- a/drivers/video/mbx/mbxdebugfs.c
+++ b/drivers/video/mbx/mbxdebugfs.c
@@ -170,37 +170,37 @@ static ssize_t misc_read_file(struct file *file, char __user *userbuf,
}
-static struct file_operations sysconf_fops = {
+static const struct file_operations sysconf_fops = {
.read = sysconf_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
-static struct file_operations clock_fops = {
+static const struct file_operations clock_fops = {
.read = clock_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
-static struct file_operations display_fops = {
+static const struct file_operations display_fops = {
.read = display_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
-static struct file_operations gsctl_fops = {
+static const struct file_operations gsctl_fops = {
.read = gsctl_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
-static struct file_operations sdram_fops = {
+static const struct file_operations sdram_fops = {
.read = sdram_read_file,
.write = write_file_dummy,
.open = open_file_generic,
};
-static struct file_operations misc_fops = {
+static const struct file_operations misc_fops = {
.read = misc_read_file,
.write = write_file_dummy,
.open = open_file_generic,
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 5df41f6f2b86..5162eab95539 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -610,10 +610,8 @@ done:
diff = refresh;
best = -1;
for (i = 0; i < dbsize; i++) {
- if ((name_matches(db[i], name, namelen) &&
- !fb_try_mode(var, info, &db[i], bpp)))
- return 1;
- if (res_specified && res_matches(db[i], xres, yres)) {
+ if (name_matches(db[i], name, namelen) ||
+ (res_specified && res_matches(db[i], xres, yres))) {
if(!fb_try_mode(var, info, &db[i], bpp)) {
if(!refresh_specified || db[i].refresh == refresh)
return 1;
@@ -670,7 +668,7 @@ done:
* @var: pointer to struct fb_var_screeninfo
*/
void fb_var_to_videomode(struct fb_videomode *mode,
- struct fb_var_screeninfo *var)
+ const struct fb_var_screeninfo *var)
{
u32 pixclock, hfreq, htotal, vtotal;
@@ -714,17 +712,21 @@ void fb_var_to_videomode(struct fb_videomode *mode,
* @mode: pointer to struct fb_videomode
*/
void fb_videomode_to_var(struct fb_var_screeninfo *var,
- struct fb_videomode *mode)
+ const struct fb_videomode *mode)
{
var->xres = mode->xres;
var->yres = mode->yres;
+ var->xres_virtual = mode->xres;
+ var->yres_virtual = mode->yres;
+ var->xoffset = 0;
+ var->yoffset = 0;
var->pixclock = mode->pixclock;
var->left_margin = mode->left_margin;
- var->hsync_len = mode->hsync_len;
- var->vsync_len = mode->vsync_len;
var->right_margin = mode->right_margin;
var->upper_margin = mode->upper_margin;
var->lower_margin = mode->lower_margin;
+ var->hsync_len = mode->hsync_len;
+ var->vsync_len = mode->vsync_len;
var->sync = mode->sync;
var->vmode = mode->vmode & FB_VMODE_MASK;
}
@@ -737,8 +739,8 @@ void fb_videomode_to_var(struct fb_var_screeninfo *var,
* RETURNS:
* 1 if equal, 0 if not
*/
-int fb_mode_is_equal(struct fb_videomode *mode1,
- struct fb_videomode *mode2)
+int fb_mode_is_equal(const struct fb_videomode *mode1,
+ const struct fb_videomode *mode2)
{
return (mode1->xres == mode2->xres &&
mode1->yres == mode2->yres &&
@@ -770,8 +772,8 @@ int fb_mode_is_equal(struct fb_videomode *mode1,
* var->xres and var->yres. If more than 1 videomode is found, will return
* the videomode with the highest refresh rate
*/
-struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
- struct list_head *head)
+const struct fb_videomode *fb_find_best_mode(const struct fb_var_screeninfo *var,
+ struct list_head *head)
{
struct list_head *pos;
struct fb_modelist *modelist;
@@ -808,8 +810,8 @@ struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
* If more than 1 videomode is found, will return the videomode with
* the closest refresh rate.
*/
-struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
- struct list_head *head)
+const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode,
+ struct list_head *head)
{
struct list_head *pos;
struct fb_modelist *modelist;
@@ -847,8 +849,8 @@ struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
* RETURNS:
* struct fb_videomode, NULL if none found
*/
-struct fb_videomode *fb_match_mode(struct fb_var_screeninfo *var,
- struct list_head *head)
+const struct fb_videomode *fb_match_mode(const struct fb_var_screeninfo *var,
+ struct list_head *head)
{
struct list_head *pos;
struct fb_modelist *modelist;
@@ -872,7 +874,7 @@ struct fb_videomode *fb_match_mode(struct fb_var_screeninfo *var,
* NOTES:
* Will only add unmatched mode entries
*/
-int fb_add_videomode(struct fb_videomode *mode, struct list_head *head)
+int fb_add_videomode(const struct fb_videomode *mode, struct list_head *head)
{
struct list_head *pos;
struct fb_modelist *modelist;
@@ -907,7 +909,8 @@ int fb_add_videomode(struct fb_videomode *mode, struct list_head *head)
* NOTES:
* Will remove all matching mode entries
*/
-void fb_delete_videomode(struct fb_videomode *mode, struct list_head *head)
+void fb_delete_videomode(const struct fb_videomode *mode,
+ struct list_head *head)
{
struct list_head *pos, *n;
struct fb_modelist *modelist;
@@ -943,7 +946,7 @@ void fb_destroy_modelist(struct list_head *head)
* @num: number of entries in array
* @head: struct list_head of modelist
*/
-void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
+void fb_videomode_to_modelist(const struct fb_videomode *modedb, int num,
struct list_head *head)
{
int i;
@@ -956,12 +959,12 @@ void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
}
}
-struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
- struct list_head *head)
+const struct fb_videomode *fb_find_best_display(const struct fb_monspecs *specs,
+ struct list_head *head)
{
struct list_head *pos;
struct fb_modelist *modelist;
- struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL;
+ const struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL;
int first = 0;
if (!head->prev || !head->next || list_empty(head))
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index deaf820cb38f..395ccedde9a6 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -66,7 +66,6 @@
#include <linux/init.h>
#ifdef CONFIG_TOSHIBA
#include <linux/toshiba.h>
-extern int tosh_smm(SMMRegisters *regs);
#endif
#include <asm/io.h>
@@ -557,14 +556,16 @@ static int
neofb_open(struct fb_info *info, int user)
{
struct neofb_par *par = info->par;
- int cnt = atomic_read(&par->ref_count);
- if (!cnt) {
+ mutex_lock(&par->open_lock);
+ if (!par->ref_count) {
memset(&par->state, 0, sizeof(struct vgastate));
par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
save_vga(&par->state);
}
- atomic_inc(&par->ref_count);
+ par->ref_count++;
+ mutex_unlock(&par->open_lock);
+
return 0;
}
@@ -572,14 +573,18 @@ static int
neofb_release(struct fb_info *info, int user)
{
struct neofb_par *par = info->par;
- int cnt = atomic_read(&par->ref_count);
- if (!cnt)
+ mutex_lock(&par->open_lock);
+ if (!par->ref_count) {
+ mutex_unlock(&par->open_lock);
return -EINVAL;
- if (cnt == 1) {
+ }
+ if (par->ref_count == 1) {
restore_vga(&par->state);
}
- atomic_dec(&par->ref_count);
+ par->ref_count--;
+ mutex_unlock(&par->open_lock);
+
return 0;
}
@@ -2048,6 +2053,7 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
info->fix.accel = id->driver_data;
+ mutex_init(&par->open_lock);
par->pci_burst = !nopciburst;
par->lcd_stretch = !nostretch;
par->libretto = libretto;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 538e947610e1..8e5b484db649 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -829,7 +829,7 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var,
}
if (!mode_valid) {
- struct fb_videomode *mode;
+ const struct fb_videomode *mode;
mode = fb_find_best_mode(var, &info->modelist);
if (mode) {
@@ -1046,10 +1046,10 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
}
if (specs->modedb != NULL) {
- struct fb_videomode *modedb;
+ const struct fb_videomode *mode;
- modedb = fb_find_best_display(specs, &info->modelist);
- fb_videomode_to_var(&nvidiafb_default_var, modedb);
+ mode = fb_find_best_display(specs, &info->modelist);
+ fb_videomode_to_var(&nvidiafb_default_var, mode);
nvidiafb_default_var.bits_per_pixel = bpp;
} else if (par->fpWidth && par->fpHeight) {
char buf[16];
@@ -1205,13 +1205,11 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
par = info->par;
par->pci_dev = pd;
- info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
+ info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
if (info->pixmap.addr == NULL)
goto err_out_kfree;
- memset(info->pixmap.addr, 0, 8 * 1024);
-
if (pci_enable_device(pd)) {
printk(KERN_ERR PFX "cannot enable PCI device\n");
goto err_out_enable;
@@ -1347,7 +1345,7 @@ err_out:
return -ENODEV;
}
-static void __exit nvidiafb_remove(struct pci_dev *pd)
+static void __devexit nvidiafb_remove(struct pci_dev *pd)
{
struct fb_info *info = pci_get_drvdata(pd);
struct nvidia_par *par = info->par;
@@ -1433,7 +1431,7 @@ static struct pci_driver nvidiafb_driver = {
.probe = nvidiafb_probe,
.suspend = nvidiafb_suspend,
.resume = nvidiafb_resume,
- .remove = __exit_p(nvidiafb_remove),
+ .remove = __devexit_p(nvidiafb_remove),
};
/* ------------------------------------------------------------------------- *
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 1d81ef47efd3..bd787e80177d 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -3299,14 +3299,12 @@ static void pm3fb_detect(void)
fb_info[i].dev = NULL;
}
- dev =
- pci_find_device(PCI_VENDOR_ID_3DLABS,
+ dev = pci_get_device(PCI_VENDOR_ID_3DLABS,
PCI_DEVICE_ID_3DLABS_PERMEDIA3, dev);
for (i = 0; ((i < PM3_MAX_BOARD) && dev); i++) {
dev_array[i] = dev;
- dev =
- pci_find_device(PCI_VENDOR_ID_3DLABS,
+ dev = pci_get_device(PCI_VENDOR_ID_3DLABS,
PCI_DEVICE_ID_3DLABS_PERMEDIA3, dev);
}
@@ -3353,7 +3351,7 @@ static void pm3fb_detect(void)
/* now, initialize... or not */
for (i = 0; i < PM3_MAX_BOARD; i++) {
l_fb_info = &(fb_info[i]);
- if ((l_fb_info->dev) && (!disable[i])) { /* PCI device was found and not disabled by user */
+ if (l_fb_info->dev && !disable[i]) { /* PCI device was found and not disabled by user */
DPRINTK(2,
"found @%lx Vendor %lx Device %lx ; base @ : %lx - %lx - %lx - %lx - %lx - %lx, irq %ld\n",
(unsigned long) l_fb_info->dev,
@@ -3608,7 +3606,7 @@ int init_module(void)
pm3fb_init();
- return (0);
+ return 0;
}
void cleanup_module(void)
@@ -3619,23 +3617,18 @@ void cleanup_module(void)
struct pm3fb_info *l_fb_info;
for (i = 0; i < PM3_MAX_BOARD; i++) {
l_fb_info = &(fb_info[i]);
- if ((l_fb_info->dev != NULL)
- && (!(disable[l_fb_info->board_num]))) {
- if (l_fb_info->vIOBase !=
- (unsigned char *) -1) {
+ pci_dev_put(l_fb_info->dev);
+ if (l_fb_info->dev != NULL && !(disable[l_fb_info->board_num])) {
+ if (l_fb_info->vIOBase != (unsigned char *) -1) {
pm3fb_unmapIO(l_fb_info);
release_mem_region(l_fb_info->p_fb,
- l_fb_info->
- fb_size);
- release_mem_region(l_fb_info->
- pIOBase,
- PM3_REGS_SIZE);
+ l_fb_info->fb_size);
+ release_mem_region(l_fb_info->pIOBase,
+ PM3_REGS_SIZE);
}
- unregister_framebuffer(&l_fb_info->gen.
- info);
+ unregister_framebuffer(&l_fb_info->gen.info);
}
}
}
- return;
}
#endif /* MODULE */
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
new file mode 100644
index 000000000000..81e43cda7d8b
--- /dev/null
+++ b/drivers/video/ps3fb.c
@@ -0,0 +1,1229 @@
+/*
+ * linux/drivers/video/ps3fb.c -- PS3 GPU frame buffer device
+ *
+ * Copyright (C) 2006 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation
+ *
+ * This file is based on :
+ *
+ * linux/drivers/video/vfb.c -- Virtual frame buffer device
+ *
+ * Copyright (C) 2002 James Simmons
+ *
+ * Copyright (C) 1997 Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/console.h>
+#include <linux/ioctl.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
+#include <asm/uaccess.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <asm/time.h>
+
+#include <asm/abs_addr.h>
+#include <asm/lv1call.h>
+#include <asm/ps3av.h>
+#include <asm/ps3fb.h>
+#include <asm/ps3.h>
+
+#ifdef PS3FB_DEBUG
+#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ##args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101
+#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102
+#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600
+#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
+#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT_SYNC 0x602
+
+#define L1GPU_FB_BLIT_WAIT_FOR_COMPLETION (1ULL << 32)
+
+#define L1GPU_DISPLAY_SYNC_HSYNC 1
+#define L1GPU_DISPLAY_SYNC_VSYNC 2
+
+#define DDR_SIZE (0) /* used no ddr */
+#define GPU_OFFSET (64 * 1024)
+#define GPU_IOIF (0x0d000000UL)
+
+#define PS3FB_FULL_MODE_BIT 0x80
+
+#define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */
+#define GPU_INTR_STATUS_VSYNC_1 1 /* vsync on head B */
+#define GPU_INTR_STATUS_FLIP_0 3 /* flip head A */
+#define GPU_INTR_STATUS_FLIP_1 4 /* flip head B */
+#define GPU_INTR_STATUS_QUEUE_0 5 /* queue head A */
+#define GPU_INTR_STATUS_QUEUE_1 6 /* queue head B */
+
+#define GPU_DRIVER_INFO_VERSION 0x211
+
+/* gpu internals */
+struct display_head {
+ u64 be_time_stamp;
+ u32 status;
+ u32 offset;
+ u32 res1;
+ u32 res2;
+ u32 field;
+ u32 reserved1;
+
+ u64 res3;
+ u32 raster;
+
+ u64 vblank_count;
+ u32 field_vsync;
+ u32 reserved2;
+};
+
+struct gpu_irq {
+ u32 irq_outlet;
+ u32 status;
+ u32 mask;
+ u32 video_cause;
+ u32 graph_cause;
+ u32 user_cause;
+
+ u32 res1;
+ u64 res2;
+
+ u32 reserved[4];
+};
+
+struct gpu_driver_info {
+ u32 version_driver;
+ u32 version_gpu;
+ u32 memory_size;
+ u32 hardware_channel;
+
+ u32 nvcore_frequency;
+ u32 memory_frequency;
+
+ u32 reserved[1063];
+ struct display_head display_head[8];
+ struct gpu_irq irq;
+};
+
+struct ps3fb_priv {
+ unsigned int irq_no;
+ void *dev;
+
+ u64 context_handle, memory_handle;
+ void *xdr_ea;
+ struct gpu_driver_info *dinfo;
+ struct semaphore sem;
+ u32 res_index;
+
+ u64 vblank_count; /* frame count */
+ wait_queue_head_t wait_vsync;
+
+ u32 num_frames; /* num of frame buffers */
+ atomic_t ext_flip; /* on/off flip with vsync */
+ atomic_t f_count; /* fb_open count */
+ int is_blanked;
+};
+static struct ps3fb_priv ps3fb;
+
+struct ps3fb_res_table {
+ u32 xres;
+ u32 yres;
+ u32 xoff;
+ u32 yoff;
+ u32 type;
+};
+#define PS3FB_RES_FULL 1
+static const struct ps3fb_res_table ps3fb_res[] = {
+ /* res_x,y margin_x,y full */
+ { 720, 480, 72, 48 , 0},
+ { 720, 576, 72, 58 , 0},
+ { 1280, 720, 78, 38 , 0},
+ { 1920, 1080, 116, 58 , 0},
+ /* full mode */
+ { 720, 480, 0, 0 , PS3FB_RES_FULL},
+ { 720, 576, 0, 0 , PS3FB_RES_FULL},
+ { 1280, 720, 0, 0 , PS3FB_RES_FULL},
+ { 1920, 1080, 0, 0 , PS3FB_RES_FULL},
+ /* vesa: normally full mode */
+ { 1280, 768, 0, 0 , 0},
+ { 1280, 1024, 0, 0 , 0},
+ { 1920, 1200, 0, 0 , 0},
+ { 0, 0, 0, 0 , 0} };
+
+/* default resolution */
+#define GPU_RES_INDEX 0 /* 720 x 480 */
+
+static const struct fb_videomode ps3fb_modedb[] = {
+ /* 60 Hz broadcast modes (modes "1" to "5") */
+ {
+ /* 480i */
+ "480i", 60, 576, 384, 74074, 130, 89, 78, 57, 63, 6,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
+ }, {
+ /* 480p */
+ "480p", 60, 576, 384, 37037, 130, 89, 78, 57, 63, 6,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ }, {
+ /* 720p */
+ "720p", 60, 1124, 644, 13481, 298, 148, 57, 44, 80, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1080i */
+ "1080i", 60, 1688, 964, 13481, 264, 160, 94, 62, 88, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
+ }, {
+ /* 1080p */
+ "1080p", 60, 1688, 964, 6741, 264, 160, 94, 62, 88, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ },
+
+ /* 50 Hz broadcast modes (modes "6" to "10") */
+ {
+ /* 576i */
+ "576i", 50, 576, 460, 74074, 142, 83, 97, 63, 63, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
+ }, {
+ /* 576p */
+ "576p", 50, 576, 460, 37037, 142, 83, 97, 63, 63, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ }, {
+ /* 720p */
+ "720p", 50, 1124, 644, 13468, 298, 478, 57, 44, 80, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1080 */
+ "1080i", 50, 1688, 964, 13468, 264, 600, 94, 62, 88, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
+ }, {
+ /* 1080p */
+ "1080p", 50, 1688, 964, 6734, 264, 600, 94, 62, 88, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ },
+
+ /* VESA modes (modes "11" to "13") */
+ {
+ /* WXGA */
+ "wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6,
+ 0, FB_VMODE_NONINTERLACED,
+ FB_MODE_IS_VESA
+ }, {
+ /* SXGA */
+ "sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED,
+ FB_MODE_IS_VESA
+ }, {
+ /* WUXGA */
+ "wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6,
+ FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED,
+ FB_MODE_IS_VESA
+ },
+
+ /* 60 Hz broadcast modes (full resolution versions of modes "1" to "5") */
+ {
+ /* 480if */
+ "480if", 60, 720, 480, 74074, 58, 17, 30, 9, 63, 6,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
+ }, {
+ /* 480pf */
+ "480pf", 60, 720, 480, 37037, 58, 17, 30, 9, 63, 6,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ }, {
+ /* 720pf */
+ "720pf", 60, 1280, 720, 13481, 220, 70, 19, 6, 80, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1080if */
+ "1080if", 60, 1920, 1080, 13481, 148, 44, 36, 4, 88, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
+ }, {
+ /* 1080pf */
+ "1080pf", 60, 1920, 1080, 6741, 148, 44, 36, 4, 88, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ },
+
+ /* 50 Hz broadcast modes (full resolution versions of modes "6" to "10") */
+ {
+ /* 576if */
+ "576if", 50, 720, 576, 74074, 70, 11, 39, 5, 63, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
+ }, {
+ /* 576pf */
+ "576pf", 50, 720, 576, 37037, 70, 11, 39, 5, 63, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ }, {
+ /* 720pf */
+ "720pf", 50, 1280, 720, 13468, 220, 400, 19, 6, 80, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1080if */
+ "1080f", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
+ }, {
+ /* 1080pf */
+ "1080pf", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
+ }
+};
+
+
+#define HEAD_A
+#define HEAD_B
+
+#define X_OFF(i) (ps3fb_res[i].xoff) /* left/right margin (pixel) */
+#define Y_OFF(i) (ps3fb_res[i].yoff) /* top/bottom margin (pixel) */
+#define WIDTH(i) (ps3fb_res[i].xres) /* width of FB */
+#define HEIGHT(i) (ps3fb_res[i].yres) /* height of FB */
+#define BPP 4 /* number of bytes per pixel */
+#define VP_OFF(i) (WIDTH(i) * Y_OFF(i) * BPP + X_OFF(i) * BPP)
+#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
+
+static int ps3fb_mode = 0;
+module_param(ps3fb_mode, bool, 0);
+
+static char *mode_option __initdata = NULL;
+
+
+static int ps3fb_get_res_table(u32 xres, u32 yres)
+{
+ int full_mode;
+ unsigned int i;
+ u32 x, y, f;
+
+ full_mode = (ps3fb_mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0;
+ for (i = 0;; i++) {
+ x = ps3fb_res[i].xres;
+ y = ps3fb_res[i].yres;
+ f = ps3fb_res[i].type;
+
+ if (!x) {
+ DPRINTK("ERROR: ps3fb_get_res_table()\n");
+ return -1;
+ }
+
+ if (full_mode == PS3FB_RES_FULL && f != PS3FB_RES_FULL)
+ continue;
+
+ if (x == xres && (yres == 0 || y == yres))
+ break;
+
+ x = x - 2 * ps3fb_res[i].xoff;
+ y = y - 2 * ps3fb_res[i].yoff;
+ if (x == xres && (yres == 0 || y == yres))
+ break;
+ }
+ return i;
+}
+
+static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
+ u32 *line_length)
+{
+ unsigned int i, mode;
+
+ for (i = 0; i < ARRAY_SIZE(ps3fb_modedb); i++)
+ if (var->xres == ps3fb_modedb[i].xres &&
+ var->yres == ps3fb_modedb[i].yres &&
+ var->pixclock == ps3fb_modedb[i].pixclock &&
+ var->hsync_len == ps3fb_modedb[i].hsync_len &&
+ var->vsync_len == ps3fb_modedb[i].vsync_len &&
+ var->left_margin == ps3fb_modedb[i].left_margin &&
+ var->right_margin == ps3fb_modedb[i].right_margin &&
+ var->upper_margin == ps3fb_modedb[i].upper_margin &&
+ var->lower_margin == ps3fb_modedb[i].lower_margin &&
+ var->sync == ps3fb_modedb[i].sync &&
+ (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode) {
+ /* Cropped broadcast modes use the full line_length */
+ *line_length =
+ ps3fb_modedb[i < 10 ? i + 13 : i].xres * 4;
+ /* Full broadcast modes have the full mode bit set */
+ mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
+
+ DPRINTK("ps3fb_find_mode: mode %u\n", mode);
+ return mode;
+ }
+
+ DPRINTK("ps3fb_find_mode: mode not found\n");
+ return 0;
+
+}
+
+static const struct fb_videomode *ps3fb_default_mode(void)
+{
+ u32 mode = ps3fb_mode & PS3AV_MODE_MASK;
+ u32 flags;
+
+ if (mode < 1 || mode > 13)
+ return NULL;
+
+ flags = ps3fb_mode & ~PS3AV_MODE_MASK;
+
+ if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) {
+ /* Full broadcast mode */
+ return &ps3fb_modedb[mode + 12];
+ }
+
+ return &ps3fb_modedb[mode - 1];
+}
+
+static int ps3fb_sync(u32 frame)
+{
+ int i, status;
+ u32 xres, yres;
+ u64 fb_ioif, offset;
+
+ i = ps3fb.res_index;
+ xres = ps3fb_res[i].xres;
+ yres = ps3fb_res[i].yres;
+
+ if (frame > ps3fb.num_frames - 1) {
+ printk(KERN_WARNING "%s: invalid frame number (%u)\n",
+ __FUNCTION__, frame);
+ return -EINVAL;
+ }
+ offset = xres * yres * BPP * frame;
+
+ fb_ioif = GPU_IOIF + FB_OFF(i) + offset;
+ status = lv1_gpu_context_attribute(ps3fb.context_handle,
+ L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
+ offset, fb_ioif,
+ L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
+ (xres << 16) | yres,
+ xres * BPP); /* line_length */
+ if (status)
+ printk(KERN_ERR "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
+ __FUNCTION__, status);
+#ifdef HEAD_A
+ status = lv1_gpu_context_attribute(ps3fb.context_handle,
+ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
+ 0, offset, 0, 0);
+ if (status)
+ printk(KERN_ERR "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
+ __FUNCTION__, status);
+#endif
+#ifdef HEAD_B
+ status = lv1_gpu_context_attribute(ps3fb.context_handle,
+ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
+ 1, offset, 0, 0);
+ if (status)
+ printk(KERN_ERR "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
+ __FUNCTION__, status);
+#endif
+ return 0;
+}
+
+
+static int ps3fb_open(struct fb_info *info, int user)
+{
+ atomic_inc(&ps3fb.f_count);
+ return 0;
+}
+
+static int ps3fb_release(struct fb_info *info, int user)
+{
+ if (atomic_dec_and_test(&ps3fb.f_count)) {
+ if (atomic_read(&ps3fb.ext_flip)) {
+ atomic_set(&ps3fb.ext_flip, 0);
+ ps3fb_sync(0); /* single buffer */
+ }
+ }
+ return 0;
+}
+
+ /*
+ * Setting the video mode has been split into two parts.
+ * First part, xxxfb_check_var, must not write anything
+ * to hardware, it should only verify and adjust var.
+ * This means it doesn't alter par but it does use hardware
+ * data from it to check this var.
+ */
+
+static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ u32 line_length;
+ int mode;
+ int i;
+
+ DPRINTK("var->xres:%u info->var.xres:%u\n", var->xres, info->var.xres);
+ DPRINTK("var->yres:%u info->var.yres:%u\n", var->yres, info->var.yres);
+
+ /* FIXME For now we do exact matches only */
+ mode = ps3fb_find_mode(var, &line_length);
+ if (!mode)
+ return -EINVAL;
+
+ /*
+ * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
+ * as FB_VMODE_SMOOTH_XPAN is only used internally
+ */
+
+ if (var->vmode & FB_VMODE_CONUPDATE) {
+ var->vmode |= FB_VMODE_YWRAP;
+ var->xoffset = info->var.xoffset;
+ var->yoffset = info->var.yoffset;
+ }
+
+ /* Virtual screen and panning are not supported */
+ if (var->xres_virtual > var->xres || var->yres_virtual > var->yres ||
+ var->xoffset || var->yoffset) {
+ DPRINTK("Virtual screen and panning are not supported\n");
+ return -EINVAL;
+ }
+
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres;
+
+ /* We support ARGB8888 only */
+ if (var->bits_per_pixel > 32 || var->grayscale ||
+ var->red.offset > 16 || var->green.offset > 8 ||
+ var->blue.offset > 0 || var->transp.offset > 24 ||
+ var->red.length > 8 || var->green.length > 8 ||
+ var->blue.length > 8 || var->transp.length > 8 ||
+ var->red.msb_right || var->green.msb_right ||
+ var->blue.msb_right || var->transp.msb_right || var->nonstd) {
+ DPRINTK("We support ARGB8888 only\n");
+ return -EINVAL;
+ }
+
+ var->bits_per_pixel = 32;
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->transp.offset = 24;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ var->transp.length = 8;
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+ var->transp.msb_right = 0;
+
+ /* Rotation is not supported */
+ if (var->rotate) {
+ DPRINTK("Rotation is not supported\n");
+ return -EINVAL;
+ }
+
+ /* Memory limit */
+ i = ps3fb_get_res_table(var->xres, var->yres);
+ if (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP > ps3fb_videomemory.size) {
+ DPRINTK("Not enough memory\n");
+ return -ENOMEM;
+ }
+
+ var->height = -1;
+ var->width = -1;
+
+ return 0;
+}
+
+ /*
+ * This routine actually sets the video mode.
+ */
+
+static int ps3fb_set_par(struct fb_info *info)
+{
+ unsigned int mode;
+ int i;
+ unsigned long offset;
+ static int first = 1;
+
+ DPRINTK("xres:%d xv:%d yres:%d yv:%d clock:%d\n",
+ info->var.xres, info->var.xres_virtual,
+ info->var.yres, info->var.yres_virtual, info->var.pixclock);
+ i = ps3fb_get_res_table(info->var.xres, info->var.yres);
+ ps3fb.res_index = i;
+
+ mode = ps3fb_find_mode(&info->var, &info->fix.line_length);
+ if (!mode)
+ return -EINVAL;
+
+ offset = FB_OFF(i) + VP_OFF(i);
+ info->fix.smem_len = ps3fb_videomemory.size - offset;
+ info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
+ memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
+
+ ps3fb.num_frames = ps3fb_videomemory.size/
+ (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP);
+
+ /* Keep the special bits we cannot set using fb_var_screeninfo */
+ ps3fb_mode = (ps3fb_mode & ~PS3AV_MODE_MASK) | mode;
+
+ if (ps3av_set_video_mode(ps3fb_mode, first))
+ return -EINVAL;
+
+ first = 0;
+ return 0;
+}
+
+ /*
+ * Set a single color register. The values supplied are already
+ * rounded down to the hardware's capabilities (according to the
+ * entries in the var structure). Return != 0 for invalid regno.
+ */
+
+static int ps3fb_setcolreg(unsigned int regno, unsigned int red,
+ unsigned int green, unsigned int blue,
+ unsigned int transp, struct fb_info *info)
+{
+ if (regno >= 16)
+ return 1;
+
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ transp >>= 8;
+
+ ((u32 *)info->pseudo_palette)[regno] = transp << 24 | red << 16 |
+ green << 8 | blue;
+ return 0;
+}
+
+ /*
+ * As we have a virtual frame buffer, we need our own mmap function
+ */
+
+static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ unsigned long size, offset;
+ int i;
+
+ i = ps3fb_get_res_table(info->var.xres, info->var.yres);
+ if (i == -1)
+ return -EINVAL;
+
+ size = vma->vm_end - vma->vm_start;
+ offset = vma->vm_pgoff << PAGE_SHIFT;
+ if (offset + size > info->fix.smem_len)
+ return -EINVAL;
+
+ offset += info->fix.smem_start + FB_OFF(i) + VP_OFF(i);
+ if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
+ size, vma->vm_page_prot))
+ return -EAGAIN;
+
+ printk(KERN_DEBUG "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n", offset,
+ vma->vm_start);
+ return 0;
+}
+
+ /*
+ * Blank the display
+ */
+
+static int ps3fb_blank(int blank, struct fb_info *info)
+{
+ int retval;
+
+ DPRINTK("%s: blank:%d\n", __FUNCTION__, blank);
+ switch (blank) {
+ case FB_BLANK_POWERDOWN:
+ case FB_BLANK_HSYNC_SUSPEND:
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_NORMAL:
+ retval = ps3av_video_mute(1); /* mute on */
+ if (!retval)
+ ps3fb.is_blanked = 1;
+ break;
+
+ default: /* unblank */
+ retval = ps3av_video_mute(0); /* mute off */
+ if (!retval)
+ ps3fb.is_blanked = 0;
+ break;
+ }
+ return retval;
+}
+
+static int ps3fb_get_vblank(struct fb_vblank *vblank)
+{
+ memset(vblank, 0, sizeof(&vblank));
+ vblank->flags = FB_VBLANK_HAVE_VSYNC;
+ return 0;
+}
+
+int ps3fb_wait_for_vsync(u32 crtc)
+{
+ int ret;
+ u64 count;
+
+ count = ps3fb.vblank_count;
+ ret = wait_event_interruptible_timeout(ps3fb.wait_vsync,
+ count != ps3fb.vblank_count,
+ HZ / 10);
+ if (!ret)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
+
+void ps3fb_flip_ctl(int on)
+{
+ if (on) {
+ if (atomic_read(&ps3fb.ext_flip) > 0) {
+ atomic_dec(&ps3fb.ext_flip);
+ }
+ } else {
+ atomic_inc(&ps3fb.ext_flip);
+ }
+}
+
+EXPORT_SYMBOL_GPL(ps3fb_flip_ctl);
+
+ /*
+ * ioctl
+ */
+
+static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ u32 val, old_mode;
+ int retval = -EFAULT;
+
+ switch (cmd) {
+ case FBIOGET_VBLANK:
+ {
+ struct fb_vblank vblank;
+ DPRINTK("FBIOGET_VBLANK:\n");
+ retval = ps3fb_get_vblank(&vblank);
+ if (retval)
+ break;
+
+ if (copy_to_user(argp, &vblank, sizeof(vblank)))
+ retval = -EFAULT;
+ break;
+ }
+
+ case FBIO_WAITFORVSYNC:
+ {
+ u32 crt;
+ DPRINTK("FBIO_WAITFORVSYNC:\n");
+ if (get_user(crt, (u32 __user *) arg))
+ break;
+
+ retval = ps3fb_wait_for_vsync(crt);
+ break;
+ }
+
+ case PS3FB_IOCTL_SETMODE:
+ {
+ const struct fb_videomode *mode;
+ struct fb_var_screeninfo var;
+
+ if (copy_from_user(&val, argp, sizeof(val)))
+ break;
+
+ DPRINTK("PS3FB_IOCTL_SETMODE:%x\n", val);
+ retval = -EINVAL;
+ old_mode = ps3fb_mode;
+ ps3fb_mode = val;
+ mode = ps3fb_default_mode();
+ if (mode) {
+ var = info->var;
+ fb_videomode_to_var(&var, mode);
+ acquire_console_sem();
+ info->flags |= FBINFO_MISC_USEREVENT;
+ /* Force, in case only special bits changed */
+ var.activate |= FB_ACTIVATE_FORCE;
+ retval = fb_set_var(info, &var);
+ info->flags &= ~FBINFO_MISC_USEREVENT;
+ release_console_sem();
+ }
+ if (retval)
+ ps3fb_mode = old_mode;
+ break;
+ }
+
+ case PS3FB_IOCTL_GETMODE:
+ val = ps3av_get_mode();
+ DPRINTK("PS3FB_IOCTL_GETMODE:%x\n", val);
+ if (!copy_to_user(argp, &val, sizeof(val)))
+ retval = 0;
+ break;
+
+ case PS3FB_IOCTL_SCREENINFO:
+ {
+ struct ps3fb_ioctl_res res;
+ int i = ps3fb.res_index;
+ DPRINTK("PS3FB_IOCTL_SCREENINFO:\n");
+ res.xres = ps3fb_res[i].xres;
+ res.yres = ps3fb_res[i].yres;
+ res.xoff = ps3fb_res[i].xoff;
+ res.yoff = ps3fb_res[i].yoff;
+ res.num_frames = ps3fb.num_frames;
+ if (!copy_to_user(argp, &res, sizeof(res)))
+ retval = 0;
+ break;
+ }
+
+ case PS3FB_IOCTL_ON:
+ DPRINTK("PS3FB_IOCTL_ON:\n");
+ atomic_inc(&ps3fb.ext_flip);
+ retval = 0;
+ break;
+
+ case PS3FB_IOCTL_OFF:
+ DPRINTK("PS3FB_IOCTL_OFF:\n");
+ if (atomic_read(&ps3fb.ext_flip) > 0)
+ atomic_dec(&ps3fb.ext_flip);
+ retval = 0;
+ break;
+
+ case PS3FB_IOCTL_FSEL:
+ if (copy_from_user(&val, argp, sizeof(val)))
+ break;
+
+ DPRINTK("PS3FB_IOCTL_FSEL:%d\n", val);
+ retval = ps3fb_sync(val);
+ break;
+
+ default:
+ retval = -ENOIOCTLCMD;
+ break;
+ }
+ return retval;
+}
+
+static int ps3fbd(void *arg)
+{
+ daemonize("ps3fbd");
+ for (;;) {
+ down(&ps3fb.sem);
+ if (atomic_read(&ps3fb.ext_flip) == 0)
+ ps3fb_sync(0); /* single buffer */
+ }
+ return 0;
+}
+
+static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
+{
+ u64 v1;
+ int status;
+ struct display_head *head = &ps3fb.dinfo->display_head[1];
+
+ status = lv1_gpu_context_intr(ps3fb.context_handle, &v1);
+ if (status) {
+ printk(KERN_ERR "%s: lv1_gpu_context_intr failed: %d\n",
+ __FUNCTION__, status);
+ return IRQ_NONE;
+ }
+
+ if (v1 & (1 << GPU_INTR_STATUS_VSYNC_1)) {
+ /* VSYNC */
+ ps3fb.vblank_count = head->vblank_count;
+ if (!ps3fb.is_blanked)
+ up(&ps3fb.sem);
+ wake_up_interruptible(&ps3fb.wait_vsync);
+ }
+
+ return IRQ_HANDLED;
+}
+
+#ifndef MODULE
+static int __init ps3fb_setup(char *options)
+{
+ char *this_opt;
+ int mode = 0;
+
+ if (!options || !*options)
+ return 0; /* no options */
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ if (!*this_opt)
+ continue;
+ if (!strncmp(this_opt, "mode:", 5))
+ mode = simple_strtoul(this_opt + 5, NULL, 0);
+ else
+ mode_option = this_opt;
+ }
+ return mode;
+}
+#endif /* MODULE */
+
+ /*
+ * Initialisation
+ */
+
+static void ps3fb_platform_release(struct device *device)
+{
+ /* This is called when the reference count goes to zero. */
+}
+
+static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
+{
+ int error;
+
+ DPRINTK("version_driver:%x\n", dinfo->version_driver);
+ DPRINTK("irq outlet:%x\n", dinfo->irq.irq_outlet);
+ DPRINTK("version_gpu:%x memory_size:%x ch:%x core_freq:%d mem_freq:%d\n",
+ dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel,
+ dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
+
+ if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
+ printk(KERN_ERR "%s: version_driver err:%x\n", __FUNCTION__,
+ dinfo->version_driver);
+ return -EINVAL;
+ }
+
+ ps3fb.dev = dev;
+ error = ps3_alloc_irq(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
+ &ps3fb.irq_no);
+ if (error) {
+ printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __FUNCTION__,
+ error);
+ return error;
+ }
+
+ error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
+ "ps3fb vsync", ps3fb.dev);
+ if (error) {
+ printk(KERN_ERR "%s: request_irq failed %d\n", __FUNCTION__,
+ error);
+ ps3_free_irq(ps3fb.irq_no);
+ return error;
+ }
+
+ dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) |
+ (1 << GPU_INTR_STATUS_FLIP_1);
+ return 0;
+}
+
+static int ps3fb_xdr_settings(u64 xdr_lpar)
+{
+ int status;
+
+ status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
+ xdr_lpar, ps3fb_videomemory.size, 0);
+ if (status) {
+ printk(KERN_ERR "%s: lv1_gpu_context_iomap failed: %d\n",
+ __FUNCTION__, status);
+ return -ENXIO;
+ }
+ DPRINTK("video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n",
+ ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar,
+ virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size);
+
+ status = lv1_gpu_context_attribute(ps3fb.context_handle,
+ L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
+ xdr_lpar, ps3fb_videomemory.size,
+ GPU_IOIF, 0);
+ if (status) {
+ printk(KERN_ERR "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
+ __FUNCTION__, status);
+ return -ENXIO;
+ }
+ return 0;
+}
+
+static struct fb_ops ps3fb_ops = {
+ .fb_open = ps3fb_open,
+ .fb_release = ps3fb_release,
+ .fb_check_var = ps3fb_check_var,
+ .fb_set_par = ps3fb_set_par,
+ .fb_setcolreg = ps3fb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+ .fb_mmap = ps3fb_mmap,
+ .fb_blank = ps3fb_blank,
+ .fb_ioctl = ps3fb_ioctl,
+ .fb_compat_ioctl = ps3fb_ioctl
+};
+
+static struct fb_fix_screeninfo ps3fb_fix __initdata = {
+ .id = "PS3 FB",
+ .type = FB_TYPE_PACKED_PIXELS,
+ .visual = FB_VISUAL_TRUECOLOR,
+ .accel = FB_ACCEL_NONE,
+};
+
+static int __init ps3fb_probe(struct platform_device *dev)
+{
+ struct fb_info *info;
+ int retval = -ENOMEM;
+ u64 ddr_lpar = 0;
+ u64 lpar_dma_control = 0;
+ u64 lpar_driver_info = 0;
+ u64 lpar_reports = 0;
+ u64 lpar_reports_size = 0;
+ u64 xdr_lpar;
+ int status;
+ unsigned long offset;
+
+ /* get gpu context handle */
+ status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
+ &ps3fb.memory_handle, &ddr_lpar);
+ if (status) {
+ printk(KERN_ERR "%s: lv1_gpu_memory_allocate failed: %d\n",
+ __FUNCTION__, status);
+ goto err;
+ }
+ DPRINTK("ddr:lpar:0x%lx\n", ddr_lpar);
+
+ status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0,
+ &ps3fb.context_handle,
+ &lpar_dma_control, &lpar_driver_info,
+ &lpar_reports, &lpar_reports_size);
+ if (status) {
+ printk(KERN_ERR "%s: lv1_gpu_context_attribute failed: %d\n",
+ __FUNCTION__, status);
+ goto err_gpu_memory_free;
+ }
+
+ /* vsync interrupt */
+ ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024);
+ if (!ps3fb.dinfo) {
+ printk(KERN_ERR "%s: ioremap failed\n", __FUNCTION__);
+ goto err_gpu_context_free;
+ }
+
+ retval = ps3fb_vsync_settings(ps3fb.dinfo, dev);
+ if (retval)
+ goto err_iounmap_dinfo;
+
+ /* xdr frame buffer */
+ ps3fb.xdr_ea = ps3fb_videomemory.address;
+ xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea));
+ retval = ps3fb_xdr_settings(xdr_lpar);
+ if (retval)
+ goto err_free_irq;
+
+ /*
+ * ps3fb must clear memory to prevent kernel info
+ * leakage into userspace
+ */
+ memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
+ info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
+ if (!info)
+ goto err_free_irq;
+
+ offset = FB_OFF(ps3fb.res_index) + VP_OFF(ps3fb.res_index);
+ info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset;
+ info->fbops = &ps3fb_ops;
+
+ info->fix = ps3fb_fix;
+ info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
+ info->fix.smem_len = ps3fb_videomemory.size - offset;
+ info->pseudo_palette = info->par;
+ info->par = NULL;
+ info->flags = FBINFO_FLAG_DEFAULT;
+
+ retval = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (retval < 0)
+ goto err_framebuffer_release;
+
+ if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb,
+ ARRAY_SIZE(ps3fb_modedb), ps3fb_default_mode(), 32)) {
+ retval = -EINVAL;
+ goto err_fb_dealloc;
+ }
+
+ fb_videomode_to_modelist(ps3fb_modedb, ARRAY_SIZE(ps3fb_modedb),
+ &info->modelist);
+
+ retval = register_framebuffer(info);
+ if (retval < 0)
+ goto err_fb_dealloc;
+
+ platform_set_drvdata(dev, info);
+
+ printk(KERN_INFO
+ "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
+ info->node, ps3fb_videomemory.size >> 10);
+
+ kernel_thread(ps3fbd, info, CLONE_KERNEL);
+ return 0;
+
+err_fb_dealloc:
+ fb_dealloc_cmap(&info->cmap);
+err_framebuffer_release:
+ framebuffer_release(info);
+err_free_irq:
+ free_irq(ps3fb.irq_no, ps3fb.dev);
+ ps3_free_irq(ps3fb.irq_no);
+err_iounmap_dinfo:
+ iounmap((u8 __iomem *)ps3fb.dinfo);
+err_gpu_context_free:
+ lv1_gpu_context_free(ps3fb.context_handle);
+err_gpu_memory_free:
+ lv1_gpu_memory_free(ps3fb.memory_handle);
+err:
+ return retval;
+}
+
+static void ps3fb_shutdown(struct platform_device *dev)
+{
+ ps3fb_flip_ctl(0); /* flip off */
+ ps3fb.dinfo->irq.mask = 0;
+ free_irq(ps3fb.irq_no, ps3fb.dev);
+ ps3_free_irq(ps3fb.irq_no);
+ iounmap((u8 __iomem *)ps3fb.dinfo);
+}
+
+void ps3fb_cleanup(void)
+{
+ int status;
+
+ if (ps3fb.irq_no) {
+ free_irq(ps3fb.irq_no, ps3fb.dev);
+ ps3_free_irq(ps3fb.irq_no);
+ }
+ iounmap((u8 __iomem *)ps3fb.dinfo);
+
+ status = lv1_gpu_context_free(ps3fb.context_handle);
+ if (status)
+ DPRINTK("lv1_gpu_context_free failed: %d\n", status);
+
+ status = lv1_gpu_memory_free(ps3fb.memory_handle);
+ if (status)
+ DPRINTK("lv1_gpu_memory_free failed: %d\n", status);
+
+ ps3av_dev_close();
+}
+
+EXPORT_SYMBOL_GPL(ps3fb_cleanup);
+
+static int ps3fb_remove(struct platform_device *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+
+ if (info) {
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
+ }
+ ps3fb_cleanup();
+ return 0;
+}
+
+static struct platform_driver ps3fb_driver = {
+ .probe = ps3fb_probe,
+ .remove = ps3fb_remove,
+ .shutdown = ps3fb_shutdown,
+ .driver = { .name = "ps3fb" }
+};
+
+static struct platform_device ps3fb_device = {
+ .name = "ps3fb",
+ .id = 0,
+ .dev = { .release = ps3fb_platform_release }
+};
+
+int ps3fb_set_sync(void)
+{
+ int status;
+
+#ifdef HEAD_A
+ status = lv1_gpu_context_attribute(0x0,
+ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
+ 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
+ if (status) {
+ printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
+ __FUNCTION__, status);
+ return -1;
+ }
+#endif
+#ifdef HEAD_B
+ status = lv1_gpu_context_attribute(0x0,
+ L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
+ 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
+
+ if (status) {
+ printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
+ __FUNCTION__, status);
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(ps3fb_set_sync);
+
+static int __init ps3fb_init(void)
+{
+ int error;
+#ifndef MODULE
+ int mode;
+ char *option = NULL;
+
+ if (fb_get_options("ps3fb", &option))
+ goto err;
+#endif
+
+ if (!ps3fb_videomemory.address)
+ goto err;
+
+ error = ps3av_dev_open();
+ if (error) {
+ printk(KERN_ERR "%s: ps3av_dev_open failed\n", __FUNCTION__);
+ goto err;
+ }
+
+ ps3fb_mode = ps3av_get_mode();
+ DPRINTK("ps3av_mode:%d\n", ps3fb_mode);
+#ifndef MODULE
+ mode = ps3fb_setup(option); /* check boot option */
+ if (mode)
+ ps3fb_mode = mode;
+#endif
+ if (ps3fb_mode > 0) {
+ u32 xres, yres;
+ ps3av_video_mode2res(ps3fb_mode, &xres, &yres);
+ ps3fb.res_index = ps3fb_get_res_table(xres, yres);
+ DPRINTK("res_index:%d\n", ps3fb.res_index);
+ } else
+ ps3fb.res_index = GPU_RES_INDEX;
+
+ atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
+ atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
+ init_MUTEX(&ps3fb.sem);
+ init_waitqueue_head(&ps3fb.wait_vsync);
+ ps3fb.num_frames = 1;
+
+ error = platform_driver_register(&ps3fb_driver);
+ if (!error) {
+ error = platform_device_register(&ps3fb_device);
+ if (error)
+ platform_driver_unregister(&ps3fb_driver);
+ }
+
+ ps3fb_set_sync();
+
+ return error;
+
+err:
+ return -ENXIO;
+}
+
+module_init(ps3fb_init);
+
+#ifdef MODULE
+static void __exit ps3fb_exit(void)
+{
+ platform_device_unregister(&ps3fb_device);
+ platform_driver_unregister(&ps3fb_driver);
+}
+
+module_exit(ps3fb_exit);
+
+MODULE_LICENSE("GPL");
+#endif /* MODULE */
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
deleted file mode 100644
index bc7ffc84e185..000000000000
--- a/drivers/video/retz3fb.c
+++ /dev/null
@@ -1,1588 +0,0 @@
-/*
- * Linux/drivers/video/retz3fb.c -- RetinaZ3 frame buffer device
- *
- * Copyright (C) 1997 Jes Sorensen
- *
- * This file is based on the CyberVision64 frame buffer device and
- * the generic Cirrus Logic driver.
- *
- * cyberfb.c: Copyright (C) 1996 Martin Apel,
- * Geert Uytterhoeven
- * clgen.c: Copyright (C) 1996 Frank Neumann
- *
- * History:
- * - 22 Jan 97: Initial work
- * - 14 Feb 97: Screen initialization works somewhat, still only
- * 8-bit packed pixel is supported.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/zorro.h>
-#include <linux/init.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/irq.h>
-#include <asm/pgtable.h>
-#include <asm/io.h>
-
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-
-#include "retz3fb.h"
-
-/* #define DEBUG if(1) */
-#define DEBUG if(0)
-
-/*
- * Reserve space for one pattern line.
- *
- * For the time being we only support 4MB boards!
- */
-
-#define PAT_MEM_SIZE 16*3
-#define PAT_MEM_OFF (4*1024*1024 - PAT_MEM_SIZE)
-
-struct retz3fb_par {
- int xres;
- int yres;
- int xres_vir;
- int yres_vir;
- int xoffset;
- int yoffset;
- int bpp;
-
- struct fb_bitfield red;
- struct fb_bitfield green;
- struct fb_bitfield blue;
- struct fb_bitfield transp;
-
- int pixclock;
- int left_margin; /* time from sync to picture */
- int right_margin; /* time from picture to sync */
- int upper_margin; /* time from sync to picture */
- int lower_margin;
- int hsync_len; /* length of horizontal sync */
- int vsync_len; /* length of vertical sync */
- int vmode;
-
- int accel;
-};
-
-struct display_data {
- long h_total; /* Horizontal Total */
- long h_sstart; /* Horizontal Sync Start */
- long h_sstop; /* Horizontal Sync Stop */
- long h_bstart; /* Horizontal Blank Start */
- long h_bstop; /* Horizontal Blank Stop */
- long h_dispend; /* Horizontal Display End */
- long v_total; /* Vertical Total */
- long v_sstart; /* Vertical Sync Start */
- long v_sstop; /* Vertical Sync Stop */
- long v_bstart; /* Vertical Blank Start */
- long v_bstop; /* Vertical Blank Stop */
- long v_dispend; /* Horizontal Display End */
-};
-
-struct retz3_fb_info {
- struct fb_info info;
- unsigned char *base;
- unsigned char *fbmem;
- unsigned long fbsize;
- volatile unsigned char *regs;
- unsigned long physfbmem;
- unsigned long physregs;
- int current_par_valid; /* set to 0 by memset */
- int blitbusy;
- struct display disp;
- struct retz3fb_par current_par;
- unsigned char color_table [256][3];
-};
-
-
-static char fontname[40] __initdata = { 0 };
-
-#define retz3info(info) ((struct retz3_fb_info *)(info))
-#define fbinfo(info) ((struct fb_info *)(info))
-
-
-/*
- * Frame Buffer Name
- */
-
-static char retz3fb_name[16] = "RetinaZ3";
-
-
-/*
- * A small info on how to convert XFree86 timing values into fb
- * timings - by Frank Neumann:
- *
-An XFree86 mode line consists of the following fields:
- "800x600" 50 800 856 976 1040 600 637 643 666
- < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
-
-The fields in the fb_var_screeninfo structure are:
- unsigned long pixclock; * pixel clock in ps (pico seconds) *
- unsigned long left_margin; * time from sync to picture *
- unsigned long right_margin; * time from picture to sync *
- unsigned long upper_margin; * time from sync to picture *
- unsigned long lower_margin;
- unsigned long hsync_len; * length of horizontal sync *
- unsigned long vsync_len; * length of vertical sync *
-
-1) Pixelclock:
- xfree: in MHz
- fb: In Picoseconds (ps)
-
- pixclock = 1000000 / DCF
-
-2) horizontal timings:
- left_margin = HFL - SH2
- right_margin = SH1 - HR
- hsync_len = SH2 - SH1
-
-3) vertical timings:
- upper_margin = VFL - SV2
- lower_margin = SV1 - VR
- vsync_len = SV2 - SV1
-
-Good examples for VESA timings can be found in the XFree86 source tree,
-under "programs/Xserver/hw/xfree86/doc/modeDB.txt".
-*/
-
-/*
- * Predefined Video Modes
- */
-
-static struct {
- const char *name;
- struct fb_var_screeninfo var;
-} retz3fb_predefined[] __initdata = {
- /*
- * NB: it is very important to adjust the pixel-clock to the color-depth.
- */
-
- {
- "640x480", { /* 640x480, 8 bpp */
- 640, 480, 640, 480, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, 39722, 48, 16, 33, 10, 96, 2,
- FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED
- }
- },
- /*
- ModeLine "800x600" 36 800 824 896 1024 600 601 603 625
- < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
- */
- {
- "800x600", { /* 800x600, 8 bpp */
- 800, 600, 800, 600, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 27778, 64, 24, 22, 1, 120, 2,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
- },
- {
- "800x600-60", { /* 800x600, 8 bpp */
- 800, 600, 800, 600, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 25000, 88, 40, 23, 1, 128, 4,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
- },
- {
- "800x600-70", { /* 800x600, 8 bpp */
- 800, 600, 800, 600, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 22272, 40, 24, 15, 9, 144, 12,
- FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
- },
- /*
- ModeLine "1024x768i" 45 1024 1064 1224 1264 768 777 785 817 interlace
- < name > DCF HR SH1 SH2 HFL VR SV1 SV2 VFL
- */
- {
- "1024x768i", { /* 1024x768, 8 bpp, interlaced */
- 1024, 768, 1024, 768, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 22222, 40, 40, 32, 9, 160, 8,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED
- }
- },
- {
- "1024x768", {
- 1024, 768, 1024, 768, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, 12500, 92, 112, 31, 2, 204, 4,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
- },
- {
- "640x480-16", { /* 640x480, 16 bpp */
- 640, 480, 640, 480, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, 38461/2, 28, 32, 12, 10, 96, 2,
- FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED
- }
- },
- {
- "640x480-24", { /* 640x480, 24 bpp */
- 640, 480, 640, 480, 0, 0, 24, 0,
- {8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0},
- 0, 0, -1, -1, 0, 38461/3, 28, 32, 12, 10, 96, 2,
- FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED
- }
- },
-};
-
-
-#define NUM_TOTAL_MODES ARRAY_SIZE(retz3fb_predefined)
-
-static struct fb_var_screeninfo retz3fb_default;
-
-static int z3fb_inverse = 0;
-static int z3fb_mode __initdata = 0;
-
-
-/*
- * Interface used by the world
- */
-
-int retz3fb_setup(char *options);
-
-static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int retz3fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-static int retz3fb_setcolreg(unsigned int regno, unsigned int red,
- unsigned int green, unsigned int blue,
- unsigned int transp, struct fb_info *info);
-static int retz3fb_blank(int blank, struct fb_info *info);
-
-
-/*
- * Interface to the low level console driver
- */
-
-int retz3fb_init(void);
-static int z3fb_switch(int con, struct fb_info *info);
-static int z3fb_updatevar(int con, struct fb_info *info);
-
-
-/*
- * Text console acceleration
- */
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_retz3_8;
-#endif
-
-
-/*
- * Accelerated Functions used by the low level console driver
- */
-
-static void retz3_bitblt(struct display *p,
- unsigned short curx, unsigned short cury, unsigned
- short destx, unsigned short desty, unsigned short
- width, unsigned short height, unsigned short cmd,
- unsigned short mask);
-
-/*
- * Hardware Specific Routines
- */
-
-static int retz3_encode_fix(struct fb_info *info,
- struct fb_fix_screeninfo *fix,
- struct retz3fb_par *par);
-static int retz3_decode_var(struct fb_var_screeninfo *var,
- struct retz3fb_par *par);
-static int retz3_encode_var(struct fb_var_screeninfo *var,
- struct retz3fb_par *par);
-static int retz3_getcolreg(unsigned int regno, unsigned int *red,
- unsigned int *green, unsigned int *blue,
- unsigned int *transp, struct fb_info *info);
-
-/*
- * Internal routines
- */
-
-static void retz3fb_get_par(struct fb_info *info, struct retz3fb_par *par);
-static void retz3fb_set_par(struct fb_info *info, struct retz3fb_par *par);
-static int do_fb_set_var(struct fb_info *info,
- struct fb_var_screeninfo *var, int isactive);
-static void retz3fb_set_disp(int con, struct fb_info *info);
-static int get_video_mode(const char *name);
-
-
-/* -------------------- Hardware specific routines ------------------------- */
-
-static unsigned short find_fq(unsigned int freq)
-{
- unsigned long f;
- long tmp;
- long prev = 0x7fffffff;
- long n2, n1 = 3;
- unsigned long m;
- unsigned short res = 0;
-
- if (freq <= 31250000)
- n2 = 3;
- else if (freq <= 62500000)
- n2 = 2;
- else if (freq <= 125000000)
- n2 = 1;
- else if (freq <= 250000000)
- n2 = 0;
- else
- return 0;
-
-
- do {
- f = freq >> (10 - n2);
-
- m = (f * n1) / (14318180/1024);
-
- if (m > 129)
- break;
-
- tmp = (((m * 14318180) >> n2) / n1) - freq;
- if (tmp < 0)
- tmp = -tmp;
-
- if (tmp < prev) {
- prev = tmp;
- res = (((n2 << 5) | (n1-2)) << 8) | (m-2);
- }
-
- } while ( (++n1) <= 21);
-
- return res;
-}
-
-
-static int retz3_set_video(struct fb_info *info,
- struct fb_var_screeninfo *var,
- struct retz3fb_par *par)
-{
- volatile unsigned char *regs = retz3info(info)->regs;
- unsigned int freq;
-
- int xres, hfront, hsync, hback;
- int yres, vfront, vsync, vback;
- unsigned char tmp;
- unsigned short best_freq;
- struct display_data data;
-
- short clocksel = 0; /* Apparantly this is always zero */
-
- int bpp = var->bits_per_pixel;
-
- /*
- * XXX
- */
- if (bpp == 24)
- return 0;
-
- if ((bpp != 8) && (bpp != 16) && (bpp != 24))
- return -EFAULT;
-
- par->xoffset = 0;
- par->yoffset = 0;
-
- xres = var->xres * bpp / 4;
- hfront = var->right_margin * bpp / 4;
- hsync = var->hsync_len * bpp / 4;
- hback = var->left_margin * bpp / 4;
-
- if (var->vmode & FB_VMODE_DOUBLE)
- {
- yres = var->yres * 2;
- vfront = var->lower_margin * 2;
- vsync = var->vsync_len * 2;
- vback = var->upper_margin * 2;
- }
- else if (var->vmode & FB_VMODE_INTERLACED)
- {
- yres = (var->yres + 1) / 2;
- vfront = (var->lower_margin + 1) / 2;
- vsync = (var->vsync_len + 1) / 2;
- vback = (var->upper_margin + 1) / 2;
- }
- else
- {
- yres = var->yres; /* -1 ? */
- vfront = var->lower_margin;
- vsync = var->vsync_len;
- vback = var->upper_margin;
- }
-
- data.h_total = (hback / 8) + (xres / 8)
- + (hfront / 8) + (hsync / 8) - 1 /* + 1 */;
- data.h_dispend = ((xres + bpp - 1)/ 8) - 1;
- data.h_bstart = xres / 8 - 1 /* + 1 */;
-
- data.h_bstop = data.h_total+1 + 2 + 1;
- data.h_sstart = (xres / 8) + (hfront / 8) + 1;
- data.h_sstop = (xres / 8) + (hfront / 8) + (hsync / 8) + 1;
-
- data.v_total = yres + vfront + vsync + vback - 1;
-
- data.v_dispend = yres - 1;
- data.v_bstart = yres - 1;
-
- data.v_bstop = data.v_total;
- data.v_sstart = yres + vfront - 1 - 2;
- data.v_sstop = yres + vfront + vsync - 1;
-
-#if 0 /* testing */
-
- printk("HBS: %i\n", data.h_bstart);
- printk("HSS: %i\n", data.h_sstart);
- printk("HSE: %i\n", data.h_sstop);
- printk("HBE: %i\n", data.h_bstop);
- printk("HT: %i\n", data.h_total);
-
- printk("hsync: %i\n", hsync);
- printk("hfront: %i\n", hfront);
- printk("hback: %i\n", hback);
-
- printk("VBS: %i\n", data.v_bstart);
- printk("VSS: %i\n", data.v_sstart);
- printk("VSE: %i\n", data.v_sstop);
- printk("VBE: %i\n", data.v_bstop);
- printk("VT: %i\n", data.v_total);
-
- printk("vsync: %i\n", vsync);
- printk("vfront: %i\n", vfront);
- printk("vback: %i\n", vback);
-#endif
-
- if (data.v_total >= 1024)
- printk(KERN_ERR "MAYDAY: v_total >= 1024; bailing out!\n");
-
- reg_w(regs, GREG_MISC_OUTPUT_W, 0xe3 | ((clocksel & 3) * 0x04));
- reg_w(regs, GREG_FEATURE_CONTROL_W, 0x00);
-
- seq_w(regs, SEQ_RESET, 0x00);
- seq_w(regs, SEQ_RESET, 0x03); /* reset sequencer logic */
-
- /*
- * CLOCKING_MODE bits:
- * 2: This one is only set for certain text-modes, wonder if
- * it may be for EGA-lines? (it was referred to as CLKDIV2)
- * (The CL drivers sets it to 0x21 with the comment:
- * FullBandwidth (video off) and 8/9 dot clock)
- */
- seq_w(regs, SEQ_CLOCKING_MODE, 0x01 | 0x00 /* 0x08 */);
-
- seq_w(regs, SEQ_MAP_MASK, 0x0f); /* enable writing to plane 0-3 */
- seq_w(regs, SEQ_CHAR_MAP_SELECT, 0x00); /* doesn't matter in gfx-mode */
- seq_w(regs, SEQ_MEMORY_MODE, 0x06); /* CL driver says 0x0e for 256 col mode*/
- seq_w(regs, SEQ_RESET, 0x01);
- seq_w(regs, SEQ_RESET, 0x03);
-
- seq_w(regs, SEQ_EXTENDED_ENABLE, 0x05);
-
- seq_w(regs, SEQ_CURSOR_CONTROL, 0x00); /* disable cursor */
- seq_w(regs, SEQ_PRIM_HOST_OFF_HI, 0x00);
- seq_w(regs, SEQ_PRIM_HOST_OFF_HI, 0x00);
- seq_w(regs, SEQ_LINEAR_0, 0x4a);
- seq_w(regs, SEQ_LINEAR_1, 0x00);
-
- seq_w(regs, SEQ_SEC_HOST_OFF_HI, 0x00);
- seq_w(regs, SEQ_SEC_HOST_OFF_LO, 0x00);
- seq_w(regs, SEQ_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40);
-
- /*
- * The lower 4 bits (0-3) are used to set the font-width for
- * text-mode - DON'T try to set this for gfx-mode.
- */
- seq_w(regs, SEQ_EXT_CLOCK_MODE, 0x10);
- seq_w(regs, SEQ_EXT_VIDEO_ADDR, 0x03);
-
- /*
- * Extended Pixel Control:
- * bit 0: text-mode=0, gfx-mode=1 (Graphics Byte ?)
- * bit 1: (Packed/Nibble Pixel Format ?)
- * bit 4-5: depth, 0=1-8bpp, 1=9-16bpp, 2=17-24bpp
- */
- seq_w(regs, SEQ_EXT_PIXEL_CNTL, 0x01 | (((bpp / 8) - 1) << 4));
-
- seq_w(regs, SEQ_BUS_WIDTH_FEEDB, 0x04);
- seq_w(regs, SEQ_COLOR_EXP_WFG, 0x01);
- seq_w(regs, SEQ_COLOR_EXP_WBG, 0x00);
- seq_w(regs, SEQ_EXT_RW_CONTROL, 0x00);
- seq_w(regs, SEQ_MISC_FEATURE_SEL, (0x51 | (clocksel & 8)));
- seq_w(regs, SEQ_COLOR_KEY_CNTL, 0x40);
- seq_w(regs, SEQ_COLOR_KEY_MATCH0, 0x00);
- seq_w(regs, SEQ_COLOR_KEY_MATCH1, 0x00);
- seq_w(regs, SEQ_COLOR_KEY_MATCH2, 0x00);
- seq_w(regs, SEQ_CRC_CONTROL, 0x00);
- seq_w(regs, SEQ_PERF_SELECT, 0x10);
- seq_w(regs, SEQ_ACM_APERTURE_1, 0x00);
- seq_w(regs, SEQ_ACM_APERTURE_2, 0x30);
- seq_w(regs, SEQ_ACM_APERTURE_3, 0x00);
- seq_w(regs, SEQ_MEMORY_MAP_CNTL, 0x03);
-
-
- /* unlock register CRT0..CRT7 */
- crt_w(regs, CRT_END_VER_RETR, (data.v_sstop & 0x0f) | 0x20);
-
- /* Zuerst zu schreibende Werte nur per printk ausgeben */
- DEBUG printk("CRT_HOR_TOTAL: %ld\n", data.h_total);
- crt_w(regs, CRT_HOR_TOTAL, data.h_total & 0xff);
-
- DEBUG printk("CRT_HOR_DISP_ENA_END: %ld\n", data.h_dispend);
- crt_w(regs, CRT_HOR_DISP_ENA_END, (data.h_dispend) & 0xff);
-
- DEBUG printk("CRT_START_HOR_BLANK: %ld\n", data.h_bstart);
- crt_w(regs, CRT_START_HOR_BLANK, data.h_bstart & 0xff);
-
- DEBUG printk("CRT_END_HOR_BLANK: 128+%ld\n", data.h_bstop % 32);
- crt_w(regs, CRT_END_HOR_BLANK, 0x80 | (data.h_bstop & 0x1f));
-
- DEBUG printk("CRT_START_HOR_RETR: %ld\n", data.h_sstart);
- crt_w(regs, CRT_START_HOR_RETR, data.h_sstart & 0xff);
-
- tmp = (data.h_sstop & 0x1f);
- if (data.h_bstop & 0x20)
- tmp |= 0x80;
- DEBUG printk("CRT_END_HOR_RETR: %d\n", tmp);
- crt_w(regs, CRT_END_HOR_RETR, tmp);
-
- DEBUG printk("CRT_VER_TOTAL: %ld\n", data.v_total & 0xff);
- crt_w(regs, CRT_VER_TOTAL, (data.v_total & 0xff));
-
- tmp = 0x10; /* LineCompare bit #9 */
- if (data.v_total & 256)
- tmp |= 0x01;
- if (data.v_dispend & 256)
- tmp |= 0x02;
- if (data.v_sstart & 256)
- tmp |= 0x04;
- if (data.v_bstart & 256)
- tmp |= 0x08;
- if (data.v_total & 512)
- tmp |= 0x20;
- if (data.v_dispend & 512)
- tmp |= 0x40;
- if (data.v_sstart & 512)
- tmp |= 0x80;
- DEBUG printk("CRT_OVERFLOW: %d\n", tmp);
- crt_w(regs, CRT_OVERFLOW, tmp);
-
- crt_w(regs, CRT_PRESET_ROW_SCAN, 0x00); /* not CL !!! */
-
- tmp = 0x40; /* LineCompare bit #8 */
- if (data.v_bstart & 512)
- tmp |= 0x20;
- if (var->vmode & FB_VMODE_DOUBLE)
- tmp |= 0x80;
- DEBUG printk("CRT_MAX_SCAN_LINE: %d\n", tmp);
- crt_w(regs, CRT_MAX_SCAN_LINE, tmp);
-
- crt_w(regs, CRT_CURSOR_START, 0x00);
- crt_w(regs, CRT_CURSOR_END, 8 & 0x1f); /* font height */
-
- crt_w(regs, CRT_START_ADDR_HIGH, 0x00);
- crt_w(regs, CRT_START_ADDR_LOW, 0x00);
-
- crt_w(regs, CRT_CURSOR_LOC_HIGH, 0x00);
- crt_w(regs, CRT_CURSOR_LOC_LOW, 0x00);
-
- DEBUG printk("CRT_START_VER_RETR: %ld\n", data.v_sstart & 0xff);
- crt_w(regs, CRT_START_VER_RETR, (data.v_sstart & 0xff));
-
-#if 1
- /* 5 refresh cycles per scanline */
- DEBUG printk("CRT_END_VER_RETR: 64+32+%ld\n", data.v_sstop % 16);
- crt_w(regs, CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 0x40 | 0x20));
-#else
- DEBUG printk("CRT_END_VER_RETR: 128+32+%ld\n", data.v_sstop % 16);
- crt_w(regs, CRT_END_VER_RETR, ((data.v_sstop & 0x0f) | 128 | 32));
-#endif
- DEBUG printk("CRT_VER_DISP_ENA_END: %ld\n", data.v_dispend & 0xff);
- crt_w(regs, CRT_VER_DISP_ENA_END, (data.v_dispend & 0xff));
-
- DEBUG printk("CRT_START_VER_BLANK: %ld\n", data.v_bstart & 0xff);
- crt_w(regs, CRT_START_VER_BLANK, (data.v_bstart & 0xff));
-
- DEBUG printk("CRT_END_VER_BLANK: %ld\n", data.v_bstop & 0xff);
- crt_w(regs, CRT_END_VER_BLANK, (data.v_bstop & 0xff));
-
- DEBUG printk("CRT_MODE_CONTROL: 0xe3\n");
- crt_w(regs, CRT_MODE_CONTROL, 0xe3);
-
- DEBUG printk("CRT_LINE_COMPARE: 0xff\n");
- crt_w(regs, CRT_LINE_COMPARE, 0xff);
-
- tmp = (var->xres_virtual / 8) * (bpp / 8);
- crt_w(regs, CRT_OFFSET, tmp);
-
- crt_w(regs, CRT_UNDERLINE_LOC, 0x07); /* probably font-height - 1 */
-
- tmp = 0x20; /* Enable extended end bits */
- if (data.h_total & 0x100)
- tmp |= 0x01;
- if ((data.h_dispend) & 0x100)
- tmp |= 0x02;
- if (data.h_bstart & 0x100)
- tmp |= 0x04;
- if (data.h_sstart & 0x100)
- tmp |= 0x08;
- if (var->vmode & FB_VMODE_INTERLACED)
- tmp |= 0x10;
- DEBUG printk("CRT_EXT_HOR_TIMING1: %d\n", tmp);
- crt_w(regs, CRT_EXT_HOR_TIMING1, tmp);
-
- tmp = 0x00;
- if (((var->xres_virtual / 8) * (bpp / 8)) & 0x100)
- tmp |= 0x10;
- crt_w(regs, CRT_EXT_START_ADDR, tmp);
-
- tmp = 0x00;
- if (data.h_total & 0x200)
- tmp |= 0x01;
- if ((data.h_dispend) & 0x200)
- tmp |= 0x02;
- if (data.h_bstart & 0x200)
- tmp |= 0x04;
- if (data.h_sstart & 0x200)
- tmp |= 0x08;
- tmp |= ((data.h_bstop & 0xc0) >> 2);
- tmp |= ((data.h_sstop & 0x60) << 1);
- crt_w(regs, CRT_EXT_HOR_TIMING2, tmp);
- DEBUG printk("CRT_EXT_HOR_TIMING2: %d\n", tmp);
-
- tmp = 0x10; /* Line compare bit 10 */
- if (data.v_total & 0x400)
- tmp |= 0x01;
- if ((data.v_dispend) & 0x400)
- tmp |= 0x02;
- if (data.v_bstart & 0x400)
- tmp |= 0x04;
- if (data.v_sstart & 0x400)
- tmp |= 0x08;
- tmp |= ((data.v_bstop & 0x300) >> 3);
- if (data.v_sstop & 0x10)
- tmp |= 0x80;
- crt_w(regs, CRT_EXT_VER_TIMING, tmp);
- DEBUG printk("CRT_EXT_VER_TIMING: %d\n", tmp);
-
- crt_w(regs, CRT_MONITOR_POWER, 0x00);
-
- /*
- * Convert from ps to Hz.
- */
- freq = 2000000000 / var->pixclock;
- freq = freq * 500;
-
- best_freq = find_fq(freq);
- pll_w(regs, 0x02, best_freq);
- best_freq = find_fq(61000000);
- pll_w(regs, 0x0a, best_freq);
- pll_w(regs, 0x0e, 0x22);
-
- gfx_w(regs, GFX_SET_RESET, 0x00);
- gfx_w(regs, GFX_ENABLE_SET_RESET, 0x00);
- gfx_w(regs, GFX_COLOR_COMPARE, 0x00);
- gfx_w(regs, GFX_DATA_ROTATE, 0x00);
- gfx_w(regs, GFX_READ_MAP_SELECT, 0x00);
- gfx_w(regs, GFX_GRAPHICS_MODE, 0x00);
- gfx_w(regs, GFX_MISC, 0x05);
- gfx_w(regs, GFX_COLOR_XCARE, 0x0f);
- gfx_w(regs, GFX_BITMASK, 0xff);
-
- reg_r(regs, ACT_ADDRESS_RESET);
- attr_w(regs, ACT_PALETTE0 , 0x00);
- attr_w(regs, ACT_PALETTE1 , 0x01);
- attr_w(regs, ACT_PALETTE2 , 0x02);
- attr_w(regs, ACT_PALETTE3 , 0x03);
- attr_w(regs, ACT_PALETTE4 , 0x04);
- attr_w(regs, ACT_PALETTE5 , 0x05);
- attr_w(regs, ACT_PALETTE6 , 0x06);
- attr_w(regs, ACT_PALETTE7 , 0x07);
- attr_w(regs, ACT_PALETTE8 , 0x08);
- attr_w(regs, ACT_PALETTE9 , 0x09);
- attr_w(regs, ACT_PALETTE10, 0x0a);
- attr_w(regs, ACT_PALETTE11, 0x0b);
- attr_w(regs, ACT_PALETTE12, 0x0c);
- attr_w(regs, ACT_PALETTE13, 0x0d);
- attr_w(regs, ACT_PALETTE14, 0x0e);
- attr_w(regs, ACT_PALETTE15, 0x0f);
- reg_r(regs, ACT_ADDRESS_RESET);
-
- attr_w(regs, ACT_ATTR_MODE_CNTL, 0x09); /* 0x01 for CL */
-
- attr_w(regs, ACT_OVERSCAN_COLOR, 0x00);
- attr_w(regs, ACT_COLOR_PLANE_ENA, 0x0f);
- attr_w(regs, ACT_HOR_PEL_PANNING, 0x00);
- attr_w(regs, ACT_COLOR_SELECT, 0x00);
-
- reg_r(regs, ACT_ADDRESS_RESET);
- reg_w(regs, ACT_DATA, 0x20);
-
- reg_w(regs, VDAC_MASK, 0xff);
-
- /*
- * Extended palette addressing ???
- */
- switch (bpp){
- case 8:
- reg_w(regs, 0x83c6, 0x00);
- break;
- case 16:
- reg_w(regs, 0x83c6, 0x60);
- break;
- case 24:
- reg_w(regs, 0x83c6, 0xe0);
- break;
- default:
- printk(KERN_INFO "Illegal color-depth: %i\n", bpp);
- }
-
- reg_w(regs, VDAC_ADDRESS, 0x00);
-
- seq_w(regs, SEQ_MAP_MASK, 0x0f );
-
- return 0;
-}
-
-
-/*
- * This function should fill in the `fix' structure based on the
- * values in the `par' structure.
- */
-
-static int retz3_encode_fix(struct fb_info *info,
- struct fb_fix_screeninfo *fix,
- struct retz3fb_par *par)
-{
- struct retz3_fb_info *zinfo = retz3info(info);
-
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strcpy(fix->id, retz3fb_name);
- fix->smem_start = zinfo->physfbmem;
- fix->smem_len = zinfo->fbsize;
- fix->mmio_start = zinfo->physregs;
- fix->mmio_len = 0x00c00000;
-
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->type_aux = 0;
- if (par->bpp == 8)
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
- else
- fix->visual = FB_VISUAL_TRUECOLOR;
-
- fix->xpanstep = 0;
- fix->ypanstep = 0;
- fix->ywrapstep = 0;
- fix->line_length = 0;
-
- fix->accel = FB_ACCEL_NCR_77C32BLT;
-
- return 0;
-}
-
-
-/*
- * Get the video params out of `var'. If a value doesn't fit, round
- * it up, if it's too big, return -EINVAL.
- */
-
-static int retz3_decode_var(struct fb_var_screeninfo *var,
- struct retz3fb_par *par)
-{
- par->xres = var->xres;
- par->yres = var->yres;
- par->xres_vir = var->xres_virtual;
- par->yres_vir = var->yres_virtual;
- par->bpp = var->bits_per_pixel;
- par->pixclock = var->pixclock;
- par->vmode = var->vmode;
-
- par->red = var->red;
- par->green = var->green;
- par->blue = var->blue;
- par->transp = var->transp;
-
- par->left_margin = var->left_margin;
- par->right_margin = var->right_margin;
- par->upper_margin = var->upper_margin;
- par->lower_margin = var->lower_margin;
- par->hsync_len = var->hsync_len;
- par->vsync_len = var->vsync_len;
-
- if (var->accel_flags & FB_ACCELF_TEXT)
- par->accel = FB_ACCELF_TEXT;
- else
- par->accel = 0;
-
- return 0;
-}
-
-
-/*
- * Fill the `var' structure based on the values in `par' and maybe
- * other values read out of the hardware.
- */
-
-static int retz3_encode_var(struct fb_var_screeninfo *var,
- struct retz3fb_par *par)
-{
- memset(var, 0, sizeof(struct fb_var_screeninfo));
- var->xres = par->xres;
- var->yres = par->yres;
- var->xres_virtual = par->xres_vir;
- var->yres_virtual = par->yres_vir;
- var->xoffset = 0;
- var->yoffset = 0;
-
- var->bits_per_pixel = par->bpp;
- var->grayscale = 0;
-
- var->red = par->red;
- var->green = par->green;
- var->blue = par->blue;
- var->transp = par->transp;
-
- var->nonstd = 0;
- var->activate = 0;
-
- var->height = -1;
- var->width = -1;
-
- var->accel_flags = (par->accel && par->bpp == 8) ? FB_ACCELF_TEXT : 0;
-
- var->pixclock = par->pixclock;
-
- var->sync = 0; /* ??? */
- var->left_margin = par->left_margin;
- var->right_margin = par->right_margin;
- var->upper_margin = par->upper_margin;
- var->lower_margin = par->lower_margin;
- var->hsync_len = par->hsync_len;
- var->vsync_len = par->vsync_len;
-
- var->vmode = par->vmode;
- return 0;
-}
-
-
-/*
- * Set a single color register. Return != 0 for invalid regno.
- */
-
-static int retz3fb_setcolreg(unsigned int regno, unsigned int red,
- unsigned int green, unsigned int blue,
- unsigned int transp, struct fb_info *info)
-{
- struct retz3_fb_info *zinfo = retz3info(info);
- volatile unsigned char *regs = zinfo->regs;
-
- /* We'll get to this */
-
- if (regno > 255)
- return 1;
-
- red >>= 10;
- green >>= 10;
- blue >>= 10;
-
- zinfo->color_table[regno][0] = red;
- zinfo->color_table[regno][1] = green;
- zinfo->color_table[regno][2] = blue;
-
- reg_w(regs, VDAC_ADDRESS_W, regno);
- reg_w(regs, VDAC_DATA, red);
- reg_w(regs, VDAC_DATA, green);
- reg_w(regs, VDAC_DATA, blue);
-
- return 0;
-}
-
-
-/*
- * Read a single color register and split it into
- * colors/transparent. Return != 0 for invalid regno.
- */
-
-static int retz3_getcolreg(unsigned int regno, unsigned int *red,
- unsigned int *green, unsigned int *blue,
- unsigned int *transp, struct fb_info *info)
-{
- struct retz3_fb_info *zinfo = retz3info(info);
- int t;
-
- if (regno > 255)
- return 1;
- t = zinfo->color_table[regno][0];
- *red = (t<<10) | (t<<4) | (t>>2);
- t = zinfo->color_table[regno][1];
- *green = (t<<10) | (t<<4) | (t>>2);
- t = zinfo->color_table[regno][2];
- *blue = (t<<10) | (t<<4) | (t>>2);
- *transp = 0;
- return 0;
-}
-
-
-static inline void retz3_busy(struct display *p)
-{
- struct retz3_fb_info *zinfo = retz3info(p->fb_info);
- volatile unsigned char *acm = zinfo->base + ACM_OFFSET;
- unsigned char blt_status;
-
- if (zinfo->blitbusy) {
- do{
- blt_status = *((acm) + (ACM_START_STATUS + 2));
- }while ((blt_status & 1) == 0);
- zinfo->blitbusy = 0;
- }
-}
-
-
-static void retz3_bitblt (struct display *p,
- unsigned short srcx, unsigned short srcy,
- unsigned short destx, unsigned short desty,
- unsigned short width, unsigned short height,
- unsigned short cmd, unsigned short mask)
-{
- struct fb_var_screeninfo *var = &p->var;
- struct retz3_fb_info *zinfo = retz3info(p->fb_info);
- volatile unsigned long *acm = (unsigned long *)(zinfo->base + ACM_OFFSET);
- unsigned long *pattern = (unsigned long *)(zinfo->fbmem + PAT_MEM_OFF);
-
- unsigned short mod;
- unsigned long tmp;
- unsigned long pat, src, dst;
-
- int i, xres_virtual = var->xres_virtual;
- short bpp = (var->bits_per_pixel & 0xff);
-
- if (bpp < 8)
- bpp = 8;
-
- tmp = mask | (mask << 16);
-
- retz3_busy(p);
-
- i = 0;
- do{
- *pattern++ = tmp;
- }while(i++ < bpp/4);
-
- tmp = cmd << 8;
- *(acm + ACM_RASTEROP_ROTATION/4) = tmp;
-
- mod = 0xc0c2;
-
- pat = 8 * PAT_MEM_OFF;
- dst = bpp * (destx + desty * xres_virtual);
-
- /*
- * Source is not set for clear.
- */
- if ((cmd != Z3BLTclear) && (cmd != Z3BLTset)) {
- src = bpp * (srcx + srcy * xres_virtual);
-
- if (destx > srcx) {
- mod &= ~0x8000;
- src += bpp * (width - 1);
- dst += bpp * (width - 1);
- pat += bpp * 2;
- }
- if (desty > srcy) {
- mod &= ~0x4000;
- src += bpp * (height - 1) * xres_virtual;
- dst += bpp * (height - 1) * xres_virtual;
- pat += bpp * 4;
- }
-
- *(acm + ACM_SOURCE/4) = cpu_to_le32(src);
- }
-
- *(acm + ACM_PATTERN/4) = cpu_to_le32(pat);
-
- *(acm + ACM_DESTINATION/4) = cpu_to_le32(dst);
-
- tmp = mod << 16;
- *(acm + ACM_CONTROL/4) = tmp;
-
- tmp = width | (height << 16);
-
- *(acm + ACM_BITMAP_DIMENSION/4) = cpu_to_le32(tmp);
-
- *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
- *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
- zinfo->blitbusy = 1;
-}
-
-#if 0
-/*
- * Move cursor to x, y
- */
-static void retz3_MoveCursor (unsigned short x, unsigned short y)
-{
- /* Guess we gotta deal with the cursor at some point */
-}
-#endif
-
-
-/*
- * Fill the hardware's `par' structure.
- */
-
-static void retz3fb_get_par(struct fb_info *info, struct retz3fb_par *par)
-{
- struct retz3_fb_info *zinfo = retz3info(info);
-
- if (zinfo->current_par_valid)
- *par = zinfo->current_par;
- else
- retz3_decode_var(&retz3fb_default, par);
-}
-
-
-static void retz3fb_set_par(struct fb_info *info, struct retz3fb_par *par)
-{
- struct retz3_fb_info *zinfo = retz3info(info);
-
- zinfo->current_par = *par;
- zinfo->current_par_valid = 1;
-}
-
-
-static int do_fb_set_var(struct fb_info *info,
- struct fb_var_screeninfo *var, int isactive)
-{
- int err, activate;
- struct retz3fb_par par;
- struct retz3_fb_info *zinfo = retz3info(info);
-
- if ((err = retz3_decode_var(var, &par)))
- return err;
- activate = var->activate;
-
- /* XXX ... what to do about isactive ? */
-
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
- retz3fb_set_par(info, &par);
- retz3_encode_var(var, &par);
- var->activate = activate;
-
- retz3_set_video(info, var, &zinfo->current_par);
-
- return 0;
-}
-
-/*
- * Get the Fixed Part of the Display
- */
-
-static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- struct retz3fb_par par;
- int error = 0;
-
- if (con == -1)
- retz3fb_get_par(info, &par);
- else
- error = retz3_decode_var(&fb_display[con].var, &par);
- return(error ? error : retz3_encode_fix(info, fix, &par));
-}
-
-
-/*
- * Get the User Defined Part of the Display
- */
-
-static int retz3fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct retz3fb_par par;
- int error = 0;
-
- if (con == -1) {
- retz3fb_get_par(info, &par);
- error = retz3_encode_var(var, &par);
- } else
- *var = fb_display[con].var;
- return error;
-}
-
-
-static void retz3fb_set_disp(int con, struct fb_info *info)
-{
- struct fb_fix_screeninfo fix;
- struct display *display;
- struct retz3_fb_info *zinfo = retz3info(info);
-
- if (con >= 0)
- display = &fb_display[con];
- else
- display = &zinfo->disp; /* used during initialization */
-
- retz3fb_get_fix(&fix, con, info);
-
- if (con == -1)
- con = 0;
-
- display->visual = fix.visual;
- display->type = fix.type;
- display->type_aux = fix.type_aux;
- display->ypanstep = fix.ypanstep;
- display->ywrapstep = fix.ywrapstep;
- display->can_soft_blank = 1;
- display->inverse = z3fb_inverse;
-
- /*
- * This seems to be about 20% faster.
- */
- display->scrollmode = SCROLL_YREDRAW;
-
- switch (display->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- if (display->var.accel_flags & FB_ACCELF_TEXT) {
- display->dispsw = &fbcon_retz3_8;
- retz3_set_video(info, &display->var, &zinfo->current_par);
- } else
- display->dispsw = &fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- display->dispsw = &fbcon_cfb16;
- break;
-#endif
- default:
- display->dispsw = &fbcon_dummy;
- break;
- }
-}
-
-
-/*
- * Set the User Defined Part of the Display
- */
-
-static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
- struct display *display;
- struct retz3_fb_info *zinfo = retz3info(info);
-
- if (con >= 0)
- display = &fb_display[con];
- else
- display = &zinfo->disp; /* used during initialization */
-
- if ((err = do_fb_set_var(info, var, con == info->currcon)))
- return err;
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
- oldxres = display->var.xres;
- oldyres = display->var.yres;
- oldvxres = display->var.xres_virtual;
- oldvyres = display->var.yres_virtual;
- oldbpp = display->var.bits_per_pixel;
- oldaccel = display->var.accel_flags;
- display->var = *var;
-
- if (oldxres != var->xres || oldyres != var->yres ||
- oldvxres != var->xres_virtual ||
- oldvyres != var->yres_virtual ||
- oldbpp != var->bits_per_pixel ||
- oldaccel != var->accel_flags) {
-
- struct fb_fix_screeninfo fix;
- retz3fb_get_fix(&fix, con, info);
-
- display->visual = fix.visual;
- display->type = fix.type;
- display->type_aux = fix.type_aux;
- display->ypanstep = fix.ypanstep;
- display->ywrapstep = fix.ywrapstep;
- display->line_length = fix.line_length;
- display->can_soft_blank = 1;
- display->inverse = z3fb_inverse;
- switch (display->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- if (var->accel_flags & FB_ACCELF_TEXT) {
- display->dispsw = &fbcon_retz3_8;
- } else
- display->dispsw = &fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- display->dispsw = &fbcon_cfb16;
- break;
-#endif
- default:
- display->dispsw = &fbcon_dummy;
- break;
- }
- /*
- * We still need to find a way to tell the X
- * server that the video mem has been fiddled with
- * so it redraws the entire screen when switching
- * between X and a text console.
- */
- retz3_set_video(info, var, &zinfo->current_par);
-
- if (info->changevar)
- (*info->changevar)(con);
- }
-
- if (oldbpp != var->bits_per_pixel) {
- if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
- return err;
- do_install_cmap(con, info);
- }
- }
- return 0;
-}
-
-
-/*
- * Get the Colormap
- */
-
-static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- if (con == info->currcon) /* current console? */
- return(fb_get_cmap(cmap, kspc, retz3_getcolreg, info));
- else if (fb_display[con].cmap.len) /* non default colormap? */
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- cmap, kspc ? 0 : 2);
- return 0;
-}
-
-/*
- * Blank the display.
- */
-
-static int retz3fb_blank(int blank, struct fb_info *info)
-{
- struct retz3_fb_info *zinfo = retz3info(info);
- volatile unsigned char *regs = retz3info(info)->regs;
- short i;
-
- if (blank)
- for (i = 0; i < 256; i++){
- reg_w(regs, VDAC_ADDRESS_W, i);
- reg_w(regs, VDAC_DATA, 0);
- reg_w(regs, VDAC_DATA, 0);
- reg_w(regs, VDAC_DATA, 0);
- }
- else
- for (i = 0; i < 256; i++){
- reg_w(regs, VDAC_ADDRESS_W, i);
- reg_w(regs, VDAC_DATA, zinfo->color_table[i][0]);
- reg_w(regs, VDAC_DATA, zinfo->color_table[i][1]);
- reg_w(regs, VDAC_DATA, zinfo->color_table[i][2]);
- }
- return 0;
-}
-
-static struct fb_ops retz3fb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = retz3fb_get_fix,
- .fb_get_var = retz3fb_get_var,
- .fb_set_var = retz3fb_set_var,
- .fb_get_cmap = retz3fb_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = retz3fb_setcolreg,
- .fb_blank = retz3fb_blank,
-};
-
-int __init retz3fb_setup(char *options)
-{
- char *this_opt;
-
- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
- if (!strcmp(this_opt, "inverse")) {
- z3fb_inverse = 1;
- fb_invert_cmaps();
- } else if (!strncmp(this_opt, "font:", 5)) {
- strlcpy(fontname, this_opt+5, sizeof(fontname));
- } else
- z3fb_mode = get_video_mode(this_opt);
- }
- return 0;
-}
-
-
-/*
- * Initialization
- */
-
-int __init retz3fb_init(void)
-{
- unsigned long board_addr, board_size;
- struct zorro_dev *z = NULL;
- volatile unsigned char *regs;
- struct retz3fb_par par;
- struct retz3_fb_info *zinfo;
- struct fb_info *fb_info;
- short i;
- int res = -ENXIO;
-
- while ((z = zorro_find_device(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, z))) {
- board_addr = z->resource.start;
- board_size = z->resource.end-z->resource.start+1;
- if (!request_mem_region(board_addr, 0x0c00000,
- "ncr77c32blt")) {
- continue;
- if (!request_mem_region(board_addr+VIDEO_MEM_OFFSET,
- 0x00400000, "RAM"))
- release_mem_region(board_addr, 0x00c00000);
- continue;
- }
- if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info),
- GFP_KERNEL)))
- return -ENOMEM;
- memset(zinfo, 0, sizeof(struct retz3_fb_info));
-
- zinfo->base = ioremap(board_addr, board_size);
- zinfo->regs = zinfo->base;
- zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET;
- /* Get memory size - for now we asume it's a 4MB board */
- zinfo->fbsize = 0x00400000; /* 4 MB */
- zinfo->physregs = board_addr;
- zinfo->physfbmem = board_addr + VIDEO_MEM_OFFSET;
-
- fb_info = fbinfo(zinfo);
-
- for (i = 0; i < 256; i++){
- for (i = 0; i < 256; i++){
- zinfo->color_table[i][0] = i;
- zinfo->color_table[i][1] = i;
- zinfo->color_table[i][2] = i;
- }
- }
-
- regs = zinfo->regs;
- /* Disable hardware cursor */
- seq_w(regs, SEQ_CURSOR_Y_INDEX, 0x00);
-
- retz3fb_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, fb_info);
- retz3fb_setcolreg (254, 0, 0, 0, 0, fb_info);
-
- strcpy(fb_info->modename, retz3fb_name);
- fb_info->changevar = NULL;
- fb_info->fbops = &retz3fb_ops;
- fb_info->screen_base = zinfo->fbmem;
- fb_info->disp = &zinfo->disp;
- fb_info->currcon = -1;
- fb_info->switch_con = &z3fb_switch;
- fb_info->updatevar = &z3fb_updatevar;
- fb_info->flags = FBINFO_FLAG_DEFAULT;
- strlcpy(fb_info->fontname, fontname, sizeof(fb_info->fontname));
-
- if (z3fb_mode == -1)
- retz3fb_default = retz3fb_predefined[0].var;
-
- retz3_decode_var(&retz3fb_default, &par);
- retz3_encode_var(&retz3fb_default, &par);
-
- do_fb_set_var(fb_info, &retz3fb_default, 0);
- retz3fb_get_var(&zinfo->disp.var, -1, fb_info);
-
- retz3fb_set_disp(-1, fb_info);
-
- do_install_cmap(0, fb_info);
-
- if (register_framebuffer(fb_info) < 0) {
- iounmap(zinfo->base);
- return -EINVAL;
- }
-
- printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of "
- "video memory\n", fb_info->node,
- fb_info->modename, zinfo->fbsize>>10);
-
- /* FIXME: This driver cannot be unloaded yet */
- res = 0;
- }
- return res;
-}
-
-
-static int z3fb_switch(int con, struct fb_info *info)
-{
- /* Do we have to save the colormap? */
- if (fb_display[info->currcon].cmap.len)
- fb_get_cmap(&fb_display[info->currcon].cmap, 1,
- retz3_getcolreg, info);
-
- do_fb_set_var(info, &fb_display[con].var, 1);
- info->currcon = con;
- /* Install new colormap */
- do_install_cmap(con, info);
- return 0;
-}
-
-
-/*
- * Update the `var' structure (called by fbcon.c)
- *
- * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
- * Since it's called by a kernel driver, no range checking is done.
- */
-
-static int z3fb_updatevar(int con, struct fb_info *info)
-{
- return 0;
-}
-
-/*
- * Get a Video Mode
- */
-
-static int __init get_video_mode(const char *name)
-{
- short i;
-
- for (i = 0; i < NUM_TOTAL_MODES; i++)
- if (!strcmp(name, retz3fb_predefined[i].name)){
- retz3fb_default = retz3fb_predefined[i].var;
- return i;
- }
- return -1;
-}
-
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return retz3fb_init();
-}
-#endif
-
-
-/*
- * Text console acceleration
- */
-
-#ifdef FBCON_HAS_CFB8
-static void retz3_8_bmove(struct display *p, int sy, int sx,
- int dy, int dx, int height, int width)
-{
- int fontwidth = fontwidth(p);
-
- sx *= fontwidth;
- dx *= fontwidth;
- width *= fontwidth;
-
- retz3_bitblt(p,
- (unsigned short)sx,
- (unsigned short)(sy*fontheight(p)),
- (unsigned short)dx,
- (unsigned short)(dy*fontheight(p)),
- (unsigned short)width,
- (unsigned short)(height*fontheight(p)),
- Z3BLTcopy,
- 0xffff);
-}
-
-static void retz3_8_clear(struct vc_data *conp, struct display *p,
- int sy, int sx, int height, int width)
-{
- unsigned short col;
- int fontwidth = fontwidth(p);
-
- sx *= fontwidth;
- width *= fontwidth;
-
- col = attr_bgcol_ec(p, conp);
- col &= 0xff;
- col |= (col << 8);
-
- retz3_bitblt(p,
- (unsigned short)sx,
- (unsigned short)(sy*fontheight(p)),
- (unsigned short)sx,
- (unsigned short)(sy*fontheight(p)),
- (unsigned short)width,
- (unsigned short)(height*fontheight(p)),
- Z3BLTset,
- col);
-}
-
-
-static void retz3_putc(struct vc_data *conp, struct display *p, int c,
- int yy, int xx)
-{
- retz3_busy(p);
- fbcon_cfb8_putc(conp, p, c, yy, xx);
-}
-
-
-static void retz3_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count,
- int yy, int xx)
-{
- retz3_busy(p);
- fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
-}
-
-
-static void retz3_revc(struct display *p, int xx, int yy)
-{
- retz3_busy(p);
- fbcon_cfb8_revc(p, xx, yy);
-}
-
-
-static void retz3_clear_margins(struct vc_data* conp, struct display* p,
- int bottom_only)
-{
- retz3_busy(p);
- fbcon_cfb8_clear_margins(conp, p, bottom_only);
-}
-
-
-static struct display_switch fbcon_retz3_8 = {
- .setup = fbcon_cfb8_setup,
- .bmove = retz3_8_bmove,
- .clear = retz3_8_clear,
- .putc = retz3_putc,
- .putcs = retz3_putcs,
- .revc = retz3_revc,
- .clear_margins = retz3_clear_margins,
- .fontwidthmask = FONTWIDTH(8)
-};
-#endif
diff --git a/drivers/video/retz3fb.h b/drivers/video/retz3fb.h
deleted file mode 100644
index 5cc751067720..000000000000
--- a/drivers/video/retz3fb.h
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * linux/drivers/video/retz3fb.h -- Defines and macros for the RetinaZ3 frame
- * buffer device
- *
- * Copyright (C) 1997 Jes Sorensen
- *
- * History:
- * - 22 Jan 97: Initial work
- *
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-/*
- * Macros to read and write to registers.
- */
-#define reg_w(regs, reg,dat) (*(regs + reg) = dat)
-#define reg_r(regs, reg) (*(regs + reg))
-
-/*
- * Macro to access the sequencer.
- */
-#define seq_w(regs, sreg, sdat) \
- do{ reg_w(regs, SEQ_IDX, sreg); reg_w(regs, SEQ_DATA, sdat); } while(0)
-
-/*
- * Macro to access the CRT controller.
- */
-#define crt_w(regs, creg, cdat) \
- do{ reg_w(regs, CRT_IDX, creg); reg_w(regs, CRT_DATA, cdat); } while(0)
-
-/*
- * Macro to access the graphics controller.
- */
-#define gfx_w(regs, greg, gdat) \
- do{ reg_w(regs, GFX_IDX, greg); reg_w(regs, GFX_DATA, gdat); } while(0)
-
-/*
- * Macro to access the attribute controller.
- */
-#define attr_w(regs, areg, adat) \
- do{ reg_w(regs, ACT_IDX, areg); reg_w(regs, ACT_DATA, adat); } while(0)
-
-/*
- * Macro to access the pll.
- */
-#define pll_w(regs, preg, pdat) \
- do{ reg_w(regs, PLL_IDX, preg); \
- reg_w(regs, PLL_DATA, (pdat & 0xff)); \
- reg_w(regs, PLL_DATA, (pdat >> 8));\
- } while(0)
-
-/*
- * Offsets
- */
-#define VIDEO_MEM_OFFSET 0x00c00000
-#define ACM_OFFSET 0x00b00000
-
-/*
- * Accelerator Control Menu
- */
-#define ACM_PRIMARY_OFFSET 0x00
-#define ACM_SECONDARY_OFFSET 0x04
-#define ACM_MODE_CONTROL 0x08
-#define ACM_CURSOR_POSITION 0x0c
-#define ACM_START_STATUS 0x30
-#define ACM_CONTROL 0x34
-#define ACM_RASTEROP_ROTATION 0x38
-#define ACM_BITMAP_DIMENSION 0x3c
-#define ACM_DESTINATION 0x40
-#define ACM_SOURCE 0x44
-#define ACM_PATTERN 0x48
-#define ACM_FOREGROUND 0x4c
-#define ACM_BACKGROUND 0x50
-
-/*
- * Video DAC addresses
- */
-#define VDAC_ADDRESS 0x03c8
-#define VDAC_ADDRESS_W 0x03c8
-#define VDAC_ADDRESS_R 0x03c7
-#define VDAC_STATE 0x03c7
-#define VDAC_DATA 0x03c9
-#define VDAC_MASK 0x03c6
-
-/*
- * Sequencer
- */
-#define SEQ_IDX 0x03c4 /* Sequencer Index */
-#define SEQ_DATA 0x03c5
-#define SEQ_RESET 0x00
-#define SEQ_CLOCKING_MODE 0x01
-#define SEQ_MAP_MASK 0x02
-#define SEQ_CHAR_MAP_SELECT 0x03
-#define SEQ_MEMORY_MODE 0x04
-#define SEQ_EXTENDED_ENABLE 0x05 /* NCR extensions */
-#define SEQ_UNKNOWN1 0x06
-#define SEQ_UNKNOWN2 0x07
-#define SEQ_CHIP_ID 0x08
-#define SEQ_UNKNOWN3 0x09
-#define SEQ_CURSOR_COLOR1 0x0a
-#define SEQ_CURSOR_COLOR0 0x0b
-#define SEQ_CURSOR_CONTROL 0x0c
-#define SEQ_CURSOR_X_LOC_HI 0x0d
-#define SEQ_CURSOR_X_LOC_LO 0x0e
-#define SEQ_CURSOR_Y_LOC_HI 0x0f
-#define SEQ_CURSOR_Y_LOC_LO 0x10
-#define SEQ_CURSOR_X_INDEX 0x11
-#define SEQ_CURSOR_Y_INDEX 0x12
-#define SEQ_CURSOR_STORE_HI 0x13
-#define SEQ_CURSOR_STORE_LO 0x14
-#define SEQ_CURSOR_ST_OFF_HI 0x15
-#define SEQ_CURSOR_ST_OFF_LO 0x16
-#define SEQ_CURSOR_PIXELMASK 0x17
-#define SEQ_PRIM_HOST_OFF_HI 0x18
-#define SEQ_PRIM_HOST_OFF_LO 0x19
-#define SEQ_LINEAR_0 0x1a
-#define SEQ_LINEAR_1 0x1b
-#define SEQ_SEC_HOST_OFF_HI 0x1c
-#define SEQ_SEC_HOST_OFF_LO 0x1d
-#define SEQ_EXTENDED_MEM_ENA 0x1e
-#define SEQ_EXT_CLOCK_MODE 0x1f
-#define SEQ_EXT_VIDEO_ADDR 0x20
-#define SEQ_EXT_PIXEL_CNTL 0x21
-#define SEQ_BUS_WIDTH_FEEDB 0x22
-#define SEQ_PERF_SELECT 0x23
-#define SEQ_COLOR_EXP_WFG 0x24
-#define SEQ_COLOR_EXP_WBG 0x25
-#define SEQ_EXT_RW_CONTROL 0x26
-#define SEQ_MISC_FEATURE_SEL 0x27
-#define SEQ_COLOR_KEY_CNTL 0x28
-#define SEQ_COLOR_KEY_MATCH0 0x29
-#define SEQ_COLOR_KEY_MATCH1 0x2a
-#define SEQ_COLOR_KEY_MATCH2 0x2b
-#define SEQ_UNKNOWN6 0x2c
-#define SEQ_CRC_CONTROL 0x2d
-#define SEQ_CRC_DATA_LOW 0x2e
-#define SEQ_CRC_DATA_HIGH 0x2f
-#define SEQ_MEMORY_MAP_CNTL 0x30
-#define SEQ_ACM_APERTURE_1 0x31
-#define SEQ_ACM_APERTURE_2 0x32
-#define SEQ_ACM_APERTURE_3 0x33
-#define SEQ_BIOS_UTILITY_0 0x3e
-#define SEQ_BIOS_UTILITY_1 0x3f
-
-/*
- * Graphics Controller
- */
-#define GFX_IDX 0x03ce
-#define GFX_DATA 0x03cf
-#define GFX_SET_RESET 0x00
-#define GFX_ENABLE_SET_RESET 0x01
-#define GFX_COLOR_COMPARE 0x02
-#define GFX_DATA_ROTATE 0x03
-#define GFX_READ_MAP_SELECT 0x04
-#define GFX_GRAPHICS_MODE 0x05
-#define GFX_MISC 0x06
-#define GFX_COLOR_XCARE 0x07
-#define GFX_BITMASK 0x08
-
-/*
- * CRT Controller
- */
-#define CRT_IDX 0x03d4
-#define CRT_DATA 0x03d5
-#define CRT_HOR_TOTAL 0x00
-#define CRT_HOR_DISP_ENA_END 0x01
-#define CRT_START_HOR_BLANK 0x02
-#define CRT_END_HOR_BLANK 0x03
-#define CRT_START_HOR_RETR 0x04
-#define CRT_END_HOR_RETR 0x05
-#define CRT_VER_TOTAL 0x06
-#define CRT_OVERFLOW 0x07
-#define CRT_PRESET_ROW_SCAN 0x08
-#define CRT_MAX_SCAN_LINE 0x09
-#define CRT_CURSOR_START 0x0a
-#define CRT_CURSOR_END 0x0b
-#define CRT_START_ADDR_HIGH 0x0c
-#define CRT_START_ADDR_LOW 0x0d
-#define CRT_CURSOR_LOC_HIGH 0x0e
-#define CRT_CURSOR_LOC_LOW 0x0f
-#define CRT_START_VER_RETR 0x10
-#define CRT_END_VER_RETR 0x11
-#define CRT_VER_DISP_ENA_END 0x12
-#define CRT_OFFSET 0x13
-#define CRT_UNDERLINE_LOC 0x14
-#define CRT_START_VER_BLANK 0x15
-#define CRT_END_VER_BLANK 0x16
-#define CRT_MODE_CONTROL 0x17
-#define CRT_LINE_COMPARE 0x18
-#define CRT_UNKNOWN1 0x19
-#define CRT_UNKNOWN2 0x1a
-#define CRT_UNKNOWN3 0x1b
-#define CRT_UNKNOWN4 0x1c
-#define CRT_UNKNOWN5 0x1d
-#define CRT_UNKNOWN6 0x1e
-#define CRT_UNKNOWN7 0x1f
-#define CRT_UNKNOWN8 0x20
-#define CRT_UNKNOWN9 0x21
-#define CRT_UNKNOWN10 0x22
-#define CRT_UNKNOWN11 0x23
-#define CRT_UNKNOWN12 0x24
-#define CRT_UNKNOWN13 0x25
-#define CRT_UNKNOWN14 0x26
-#define CRT_UNKNOWN15 0x27
-#define CRT_UNKNOWN16 0x28
-#define CRT_UNKNOWN17 0x29
-#define CRT_UNKNOWN18 0x2a
-#define CRT_UNKNOWN19 0x2b
-#define CRT_UNKNOWN20 0x2c
-#define CRT_UNKNOWN21 0x2d
-#define CRT_UNKNOWN22 0x2e
-#define CRT_UNKNOWN23 0x2f
-#define CRT_EXT_HOR_TIMING1 0x30 /* NCR crt extensions */
-#define CRT_EXT_START_ADDR 0x31
-#define CRT_EXT_HOR_TIMING2 0x32
-#define CRT_EXT_VER_TIMING 0x33
-#define CRT_MONITOR_POWER 0x34
-
-/*
- * General Registers
- */
-#define GREG_STATUS0_R 0x03c2
-#define GREG_STATUS1_R 0x03da
-#define GREG_MISC_OUTPUT_R 0x03cc
-#define GREG_MISC_OUTPUT_W 0x03c2
-#define GREG_FEATURE_CONTROL_R 0x03ca
-#define GREG_FEATURE_CONTROL_W 0x03da
-#define GREG_POS 0x0102
-
-/*
- * Attribute Controller
- */
-#define ACT_IDX 0x03C0
-#define ACT_ADDRESS_R 0x03C0
-#define ACT_DATA 0x03C0
-#define ACT_ADDRESS_RESET 0x03DA
-#define ACT_PALETTE0 0x00
-#define ACT_PALETTE1 0x01
-#define ACT_PALETTE2 0x02
-#define ACT_PALETTE3 0x03
-#define ACT_PALETTE4 0x04
-#define ACT_PALETTE5 0x05
-#define ACT_PALETTE6 0x06
-#define ACT_PALETTE7 0x07
-#define ACT_PALETTE8 0x08
-#define ACT_PALETTE9 0x09
-#define ACT_PALETTE10 0x0A
-#define ACT_PALETTE11 0x0B
-#define ACT_PALETTE12 0x0C
-#define ACT_PALETTE13 0x0D
-#define ACT_PALETTE14 0x0E
-#define ACT_PALETTE15 0x0F
-#define ACT_ATTR_MODE_CNTL 0x10
-#define ACT_OVERSCAN_COLOR 0x11
-#define ACT_COLOR_PLANE_ENA 0x12
-#define ACT_HOR_PEL_PANNING 0x13
-#define ACT_COLOR_SELECT 0x14
-
-/*
- * PLL
- */
-#define PLL_IDX 0x83c8
-#define PLL_DATA 0x83c9
-
-/*
- * Blitter operations
- */
-#define Z3BLTclear 0x00 /* 0 */
-#define Z3BLTand 0x80 /* src AND dst */
-#define Z3BLTandReverse 0x40 /* src AND NOT dst */
-#define Z3BLTcopy 0xc0 /* src */
-#define Z3BLTandInverted 0x20 /* NOT src AND dst */
-#define Z3BLTnoop 0xa0 /* dst */
-#define Z3BLTxor 0x60 /* src XOR dst */
-#define Z3BLTor 0xe0 /* src OR dst */
-#define Z3BLTnor 0x10 /* NOT src AND NOT dst */
-#define Z3BLTequiv 0x90 /* NOT src XOR dst */
-#define Z3BLTinvert 0x50 /* NOT dst */
-#define Z3BLTorReverse 0xd0 /* src OR NOT dst */
-#define Z3BLTcopyInverted 0x30 /* NOT src */
-#define Z3BLTorInverted 0xb0 /* NOT src OR dst */
-#define Z3BLTnand 0x70 /* NOT src OR NOT dst */
-#define Z3BLTset 0xf0 /* 1 */
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 1a13966b7d5b..f2e9b742c92f 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -894,7 +894,8 @@ out:
return rc;
}
-static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
+static void riva_update_var(struct fb_var_screeninfo *var,
+ const struct fb_videomode *modedb)
{
NVTRACE_ENTER();
var->xres = var->xres_virtual = modedb->xres;
@@ -1101,10 +1102,10 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
static int rivafb_open(struct fb_info *info, int user)
{
struct riva_par *par = info->par;
- int cnt = atomic_read(&par->ref_count);
NVTRACE_ENTER();
- if (!cnt) {
+ mutex_lock(&par->open_lock);
+ if (!par->ref_count) {
#ifdef CONFIG_X86
memset(&par->state, 0, sizeof(struct vgastate));
par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
@@ -1119,7 +1120,8 @@ static int rivafb_open(struct fb_info *info, int user)
riva_save_state(par, &par->initial_state);
}
- atomic_inc(&par->ref_count);
+ par->ref_count++;
+ mutex_unlock(&par->open_lock);
NVTRACE_LEAVE();
return 0;
}
@@ -1127,12 +1129,14 @@ static int rivafb_open(struct fb_info *info, int user)
static int rivafb_release(struct fb_info *info, int user)
{
struct riva_par *par = info->par;
- int cnt = atomic_read(&par->ref_count);
NVTRACE_ENTER();
- if (!cnt)
+ mutex_lock(&par->open_lock);
+ if (!par->ref_count) {
+ mutex_unlock(&par->open_lock);
return -EINVAL;
- if (cnt == 1) {
+ }
+ if (par->ref_count == 1) {
par->riva.LockUnlock(&par->riva, 0);
par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
riva_load_state(par, &par->initial_state);
@@ -1141,14 +1145,15 @@ static int rivafb_release(struct fb_info *info, int user)
#endif
par->riva.LockUnlock(&par->riva, 1);
}
- atomic_dec(&par->ref_count);
+ par->ref_count--;
+ mutex_unlock(&par->open_lock);
NVTRACE_LEAVE();
return 0;
}
static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
- struct fb_videomode *mode;
+ const struct fb_videomode *mode;
struct riva_par *par = info->par;
int nom, den; /* translating from pixels->bytes */
int mode_valid = 0;
@@ -1980,12 +1985,11 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
default_par = info->par;
default_par->pdev = pd;
- info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);
+ info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
if (info->pixmap.addr == NULL) {
ret = -ENOMEM;
goto err_framebuffer_release;
}
- memset(info->pixmap.addr, 0, 8 * 1024);
ret = pci_enable_device(pd);
if (ret < 0) {
@@ -1999,6 +2003,7 @@ static int __devinit rivafb_probe(struct pci_dev *pd,
goto err_disable_device;
}
+ mutex_init(&default_par->open_lock);
default_par->riva.Architecture = riva_get_arch(pd);
default_par->Chipset = (pd->vendor << 16) | pd->device;
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
index 7fa13fc9c413..48ead6d72f24 100644
--- a/drivers/video/riva/rivafb.h
+++ b/drivers/video/riva/rivafb.h
@@ -53,7 +53,8 @@ struct riva_par {
#ifdef CONFIG_X86
struct vgastate state;
#endif
- atomic_t ref_count;
+ struct mutex open_lock;
+ unsigned int ref_count;
unsigned char *EDID;
unsigned int Chipset;
int forceCRTC;
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
new file mode 100644
index 000000000000..3162c37b1447
--- /dev/null
+++ b/drivers/video/s3fb.c
@@ -0,0 +1,1180 @@
+/*
+ * linux/drivers/video/s3fb.c -- Frame buffer device driver for S3 Trio/Virge
+ *
+ * Copyright (c) 2006-2007 Ondrej Zajicek <santiago@crfreenet.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Code is based on David Boucher's viafb (http://davesdomain.org.uk/viafb/)
+ * which is based on the code of neofb.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/svga.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/console.h> /* Why should fb driver call console functions? because acquire_console_sem() */
+#include <video/vga.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+struct s3fb_info {
+ int chip, rev, mclk_freq;
+ int mtrr_reg;
+ struct vgastate state;
+ struct mutex open_lock;
+ unsigned int ref_count;
+ u32 pseudo_palette[16];
+};
+
+
+/* ------------------------------------------------------------------------- */
+
+static const struct svga_fb_format s3fb_formats[] = {
+ { 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
+ FB_TYPE_TEXT, FB_AUX_TEXT_SVGA_STEP4, FB_VISUAL_PSEUDOCOLOR, 8, 16},
+ { 4, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
+ FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 8, 16},
+ { 4, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 1,
+ FB_TYPE_INTERLEAVED_PLANES, 1, FB_VISUAL_PSEUDOCOLOR, 8, 16},
+ { 8, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
+ FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 4, 8},
+ {16, {10, 5, 0}, {5, 5, 0}, {0, 5, 0}, {0, 0, 0}, 0,
+ FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 2, 4},
+ {16, {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, 0,
+ FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 2, 4},
+ {24, {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0,
+ FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 1, 2},
+ {32, {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0,
+ FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 1, 2},
+ SVGA_FORMAT_END
+};
+
+
+static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
+ 60000, 240000, 14318};
+
+static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
+
+static const char * const s3_names[] = {"S3 Unknown", "S3 Trio32", "S3 Trio64", "S3 Trio64V+",
+ "S3 Trio64UV+", "S3 Trio64V2/DX", "S3 Trio64V2/GX",
+ "S3 Plato/PX", "S3 Aurora64VP", "S3 Virge",
+ "S3 Virge/VX", "S3 Virge/DX", "S3 Virge/GX",
+ "S3 Virge/GX2", "S3 Virge/GX2P", "S3 Virge/GX2P"};
+
+#define CHIP_UNKNOWN 0x00
+#define CHIP_732_TRIO32 0x01
+#define CHIP_764_TRIO64 0x02
+#define CHIP_765_TRIO64VP 0x03
+#define CHIP_767_TRIO64UVP 0x04
+#define CHIP_775_TRIO64V2_DX 0x05
+#define CHIP_785_TRIO64V2_GX 0x06
+#define CHIP_551_PLATO_PX 0x07
+#define CHIP_M65_AURORA64VP 0x08
+#define CHIP_325_VIRGE 0x09
+#define CHIP_988_VIRGE_VX 0x0A
+#define CHIP_375_VIRGE_DX 0x0B
+#define CHIP_385_VIRGE_GX 0x0C
+#define CHIP_356_VIRGE_GX2 0x0D
+#define CHIP_357_VIRGE_GX2P 0x0E
+#define CHIP_359_VIRGE_GX2P 0x0F
+
+#define CHIP_XXX_TRIO 0x80
+#define CHIP_XXX_TRIO64V2_DXGX 0x81
+#define CHIP_XXX_VIRGE_DXGX 0x82
+
+#define CHIP_UNDECIDED_FLAG 0x80
+#define CHIP_MASK 0xFF
+
+/* CRT timing register sets */
+
+static const struct vga_regset s3_h_total_regs[] = {{0x00, 0, 7}, {0x5D, 0, 0}, VGA_REGSET_END};
+static const struct vga_regset s3_h_display_regs[] = {{0x01, 0, 7}, {0x5D, 1, 1}, VGA_REGSET_END};
+static const struct vga_regset s3_h_blank_start_regs[] = {{0x02, 0, 7}, {0x5D, 2, 2}, VGA_REGSET_END};
+static const struct vga_regset s3_h_blank_end_regs[] = {{0x03, 0, 4}, {0x05, 7, 7}, VGA_REGSET_END};
+static const struct vga_regset s3_h_sync_start_regs[] = {{0x04, 0, 7}, {0x5D, 4, 4}, VGA_REGSET_END};
+static const struct vga_regset s3_h_sync_end_regs[] = {{0x05, 0, 4}, VGA_REGSET_END};
+
+static const struct vga_regset s3_v_total_regs[] = {{0x06, 0, 7}, {0x07, 0, 0}, {0x07, 5, 5}, {0x5E, 0, 0}, VGA_REGSET_END};
+static const struct vga_regset s3_v_display_regs[] = {{0x12, 0, 7}, {0x07, 1, 1}, {0x07, 6, 6}, {0x5E, 1, 1}, VGA_REGSET_END};
+static const struct vga_regset s3_v_blank_start_regs[] = {{0x15, 0, 7}, {0x07, 3, 3}, {0x09, 5, 5}, {0x5E, 2, 2}, VGA_REGSET_END};
+static const struct vga_regset s3_v_blank_end_regs[] = {{0x16, 0, 7}, VGA_REGSET_END};
+static const struct vga_regset s3_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07, 2, 2}, {0x07, 7, 7}, {0x5E, 4, 4}, VGA_REGSET_END};
+static const struct vga_regset s3_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END};
+
+static const struct vga_regset s3_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, {0x5E, 6, 6}, VGA_REGSET_END};
+static const struct vga_regset s3_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x31, 4, 5}, {0x51, 0, 1}, VGA_REGSET_END};
+static const struct vga_regset s3_offset_regs[] = {{0x13, 0, 7}, {0x51, 4, 5}, VGA_REGSET_END}; /* set 0x43 bit 2 to 0 */
+
+static const struct svga_timing_regs s3_timing_regs = {
+ s3_h_total_regs, s3_h_display_regs, s3_h_blank_start_regs,
+ s3_h_blank_end_regs, s3_h_sync_start_regs, s3_h_sync_end_regs,
+ s3_v_total_regs, s3_v_display_regs, s3_v_blank_start_regs,
+ s3_v_blank_end_regs, s3_v_sync_start_regs, s3_v_sync_end_regs,
+};
+
+
+/* ------------------------------------------------------------------------- */
+
+/* Module parameters */
+
+
+static char *mode = "640x480-8@60";
+
+#ifdef CONFIG_MTRR
+static int mtrr = 1;
+#endif
+
+static int fasttext = 1;
+
+
+MODULE_AUTHOR("(c) 2006-2007 Ondrej Zajicek <santiago@crfreenet.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("fbdev driver for S3 Trio/Virge");
+
+module_param(mode, charp, 0444);
+MODULE_PARM_DESC(mode, "Default video mode ('640x480-8@60', etc)");
+
+#ifdef CONFIG_MTRR
+module_param(mtrr, int, 0444);
+MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
+#endif
+
+module_param(fasttext, int, 0644);
+MODULE_PARM_DESC(fasttext, "Enable S3 fast text mode (1=enable, 0=disable, default=1)");
+
+
+/* ------------------------------------------------------------------------- */
+
+/* Set font in S3 fast text mode */
+
+static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
+{
+ const u8 *font = map->data;
+ u8* fb = (u8 *) info->screen_base;
+ int i, c;
+
+ if ((map->width != 8) || (map->height != 16) ||
+ (map->depth != 1) || (map->length != 256)) {
+ printk(KERN_ERR "fb%d: unsupported font parameters: width %d, height %d, depth %d, length %d\n",
+ info->node, map->width, map->height, map->depth, map->length);
+ return;
+ }
+
+ fb += 2;
+ for (i = 0; i < map->height; i++) {
+ for (c = 0; c < map->length; c++) {
+ fb[c * 4] = font[c * map->height + i];
+ }
+ fb += 1024;
+ }
+}
+
+
+
+static struct fb_tile_ops s3fb_tile_ops = {
+ .fb_settile = svga_settile,
+ .fb_tilecopy = svga_tilecopy,
+ .fb_tilefill = svga_tilefill,
+ .fb_tileblit = svga_tileblit,
+ .fb_tilecursor = svga_tilecursor,
+};
+
+static struct fb_tile_ops s3fb_fast_tile_ops = {
+ .fb_settile = s3fb_settile_fast,
+ .fb_tilecopy = svga_tilecopy,
+ .fb_tilefill = svga_tilefill,
+ .fb_tileblit = svga_tileblit,
+ .fb_tilecursor = svga_tilecursor,
+};
+
+
+/* ------------------------------------------------------------------------- */
+
+/* image data is MSB-first, fb structure is MSB-first too */
+static inline u32 expand_color(u32 c)
+{
+ return ((c & 1) | ((c & 2) << 7) | ((c & 4) << 14) | ((c & 8) << 21)) * 0xFF;
+}
+
+/* s3fb_iplan_imageblit silently assumes that almost everything is 8-pixel aligned */
+static void s3fb_iplan_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ u32 fg = expand_color(image->fg_color);
+ u32 bg = expand_color(image->bg_color);
+ const u8 *src1, *src;
+ u8 __iomem *dst1;
+ u32 __iomem *dst;
+ u32 val;
+ int x, y;
+
+ src1 = image->data;
+ dst1 = info->screen_base + (image->dy * info->fix.line_length)
+ + ((image->dx / 8) * 4);
+
+ for (y = 0; y < image->height; y++) {
+ src = src1;
+ dst = (u32 __iomem *) dst1;
+ for (x = 0; x < image->width; x += 8) {
+ val = *(src++) * 0x01010101;
+ val = (val & fg) | (~val & bg);
+ fb_writel(val, dst++);
+ }
+ src1 += image->width / 8;
+ dst1 += info->fix.line_length;
+ }
+
+}
+
+/* s3fb_iplan_fillrect silently assumes that almost everything is 8-pixel aligned */
+static void s3fb_iplan_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+ u32 fg = expand_color(rect->color);
+ u8 __iomem *dst1;
+ u32 __iomem *dst;
+ int x, y;
+
+ dst1 = info->screen_base + (rect->dy * info->fix.line_length)
+ + ((rect->dx / 8) * 4);
+
+ for (y = 0; y < rect->height; y++) {
+ dst = (u32 __iomem *) dst1;
+ for (x = 0; x < rect->width; x += 8) {
+ fb_writel(fg, dst++);
+ }
+ dst1 += info->fix.line_length;
+ }
+}
+
+
+/* image data is MSB-first, fb structure is high-nibble-in-low-byte-first */
+static inline u32 expand_pixel(u32 c)
+{
+ return (((c & 1) << 24) | ((c & 2) << 27) | ((c & 4) << 14) | ((c & 8) << 17) |
+ ((c & 16) << 4) | ((c & 32) << 7) | ((c & 64) >> 6) | ((c & 128) >> 3)) * 0xF;
+}
+
+/* s3fb_cfb4_imageblit silently assumes that almost everything is 8-pixel aligned */
+static void s3fb_cfb4_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ u32 fg = image->fg_color * 0x11111111;
+ u32 bg = image->bg_color * 0x11111111;
+ const u8 *src1, *src;
+ u8 __iomem *dst1;
+ u32 __iomem *dst;
+ u32 val;
+ int x, y;
+
+ src1 = image->data;
+ dst1 = info->screen_base + (image->dy * info->fix.line_length)
+ + ((image->dx / 8) * 4);
+
+ for (y = 0; y < image->height; y++) {
+ src = src1;
+ dst = (u32 __iomem *) dst1;
+ for (x = 0; x < image->width; x += 8) {
+ val = expand_pixel(*(src++));
+ val = (val & fg) | (~val & bg);
+ fb_writel(val, dst++);
+ }
+ src1 += image->width / 8;
+ dst1 += info->fix.line_length;
+ }
+}
+
+static void s3fb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+ if ((info->var.bits_per_pixel == 4) && (image->depth == 1)
+ && ((image->width % 8) == 0) && ((image->dx % 8) == 0)) {
+ if (info->fix.type == FB_TYPE_INTERLEAVED_PLANES)
+ s3fb_iplan_imageblit(info, image);
+ else
+ s3fb_cfb4_imageblit(info, image);
+ } else
+ cfb_imageblit(info, image);
+}
+
+static void s3fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
+{
+ if ((info->var.bits_per_pixel == 4)
+ && ((rect->width % 8) == 0) && ((rect->dx % 8) == 0)
+ && (info->fix.type == FB_TYPE_INTERLEAVED_PLANES))
+ s3fb_iplan_fillrect(info, rect);
+ else
+ cfb_fillrect(info, rect);
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+
+
+static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
+{
+ u16 m, n, r;
+ u8 regval;
+
+ svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node);
+
+ /* Set VGA misc register */
+ regval = vga_r(NULL, VGA_MIS_R);
+ vga_w(NULL, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
+
+ /* Set S3 clock registers */
+ vga_wseq(NULL, 0x12, ((n - 2) | (r << 5)));
+ vga_wseq(NULL, 0x13, m - 2);
+
+ udelay(1000);
+
+ /* Activate clock - write 0, 1, 0 to seq/15 bit 5 */
+ regval = vga_rseq (NULL, 0x15); /* | 0x80; */
+ vga_wseq(NULL, 0x15, regval & ~(1<<5));
+ vga_wseq(NULL, 0x15, regval | (1<<5));
+ vga_wseq(NULL, 0x15, regval & ~(1<<5));
+}
+
+
+/* Open framebuffer */
+
+static int s3fb_open(struct fb_info *info, int user)
+{
+ struct s3fb_info *par = info->par;
+
+ mutex_lock(&(par->open_lock));
+ if (par->ref_count == 0) {
+ memset(&(par->state), 0, sizeof(struct vgastate));
+ par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
+ par->state.num_crtc = 0x70;
+ par->state.num_seq = 0x20;
+ save_vga(&(par->state));
+ }
+
+ par->ref_count++;
+ mutex_unlock(&(par->open_lock));
+
+ return 0;
+}
+
+/* Close framebuffer */
+
+static int s3fb_release(struct fb_info *info, int user)
+{
+ struct s3fb_info *par = info->par;
+
+ mutex_lock(&(par->open_lock));
+ if (par->ref_count == 0) {
+ mutex_unlock(&(par->open_lock));
+ return -EINVAL;
+ }
+
+ if (par->ref_count == 1)
+ restore_vga(&(par->state));
+
+ par->ref_count--;
+ mutex_unlock(&(par->open_lock));
+
+ return 0;
+}
+
+/* Validate passed in var */
+
+static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct s3fb_info *par = info->par;
+ int rv, mem, step;
+
+ /* Find appropriate format */
+ rv = svga_match_format (s3fb_formats, var, NULL);
+ if ((rv < 0) || ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 7) : (rv == 6)))
+ { /* 24bpp on VIRGE VX, 32bpp on others */
+ printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node);
+ return rv;
+ }
+
+ /* Do not allow to have real resoulution larger than virtual */
+ if (var->xres > var->xres_virtual)
+ var->xres_virtual = var->xres;
+
+ if (var->yres > var->yres_virtual)
+ var->yres_virtual = var->yres;
+
+ /* Round up xres_virtual to have proper alignment of lines */
+ step = s3fb_formats[rv].xresstep - 1;
+ var->xres_virtual = (var->xres_virtual+step) & ~step;
+
+ /* Check whether have enough memory */
+ mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual;
+ if (mem > info->screen_size)
+ {
+ printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n",
+ info->node, mem >> 10, (unsigned int) (info->screen_size >> 10));
+ return -EINVAL;
+ }
+
+ rv = svga_check_timings (&s3_timing_regs, var, info->node);
+ if (rv < 0)
+ {
+ printk(KERN_ERR "fb%d: invalid timings requested\n", info->node);
+ return rv;
+ }
+
+ return 0;
+}
+
+/* Set video mode from par */
+
+static int s3fb_set_par(struct fb_info *info)
+{
+ struct s3fb_info *par = info->par;
+ u32 value, mode, hmul, offset_value, screen_size, multiplex;
+ u32 bpp = info->var.bits_per_pixel;
+
+ if (bpp != 0) {
+ info->fix.ypanstep = 1;
+ info->fix.line_length = (info->var.xres_virtual * bpp) / 8;
+
+ info->flags &= ~FBINFO_MISC_TILEBLITTING;
+ info->tileops = NULL;
+
+ offset_value = (info->var.xres_virtual * bpp) / 64;
+ screen_size = info->var.yres_virtual * info->fix.line_length;
+ } else {
+ info->fix.ypanstep = 16;
+ info->fix.line_length = 0;
+
+ info->flags |= FBINFO_MISC_TILEBLITTING;
+ info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops;
+
+ offset_value = info->var.xres_virtual / 16;
+ screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64;
+ }
+
+ info->var.xoffset = 0;
+ info->var.yoffset = 0;
+ info->var.activate = FB_ACTIVATE_NOW;
+
+ /* Unlock registers */
+ vga_wcrt(NULL, 0x38, 0x48);
+ vga_wcrt(NULL, 0x39, 0xA5);
+ vga_wseq(NULL, 0x08, 0x06);
+ svga_wcrt_mask(0x11, 0x00, 0x80);
+
+ /* Blank screen and turn off sync */
+ svga_wseq_mask(0x01, 0x20, 0x20);
+ svga_wcrt_mask(0x17, 0x00, 0x80);
+
+ /* Set default values */
+ svga_set_default_gfx_regs();
+ svga_set_default_atc_regs();
+ svga_set_default_seq_regs();
+ svga_set_default_crt_regs();
+ svga_wcrt_multi(s3_line_compare_regs, 0xFFFFFFFF);
+ svga_wcrt_multi(s3_start_address_regs, 0);
+
+ /* S3 specific initialization */
+ svga_wcrt_mask(0x58, 0x10, 0x10); /* enable linear framebuffer */
+ svga_wcrt_mask(0x31, 0x08, 0x08); /* enable sequencer access to framebuffer above 256 kB */
+
+/* svga_wcrt_mask(0x33, 0x08, 0x08); */ /* DDR ? */
+/* svga_wcrt_mask(0x43, 0x01, 0x01); */ /* DDR ? */
+ svga_wcrt_mask(0x33, 0x00, 0x08); /* no DDR ? */
+ svga_wcrt_mask(0x43, 0x00, 0x01); /* no DDR ? */
+
+ svga_wcrt_mask(0x5D, 0x00, 0x28); // Clear strange HSlen bits
+
+/* svga_wcrt_mask(0x58, 0x03, 0x03); */
+
+/* svga_wcrt_mask(0x53, 0x12, 0x13); */ /* enable MMIO */
+/* svga_wcrt_mask(0x40, 0x08, 0x08); */ /* enable write buffer */
+
+
+ /* Set the offset register */
+ pr_debug("fb%d: offset register : %d\n", info->node, offset_value);
+ svga_wcrt_multi(s3_offset_regs, offset_value);
+
+ vga_wcrt(NULL, 0x54, 0x18); /* M parameter */
+ vga_wcrt(NULL, 0x60, 0xff); /* N parameter */
+ vga_wcrt(NULL, 0x61, 0xff); /* L parameter */
+ vga_wcrt(NULL, 0x62, 0xff); /* L parameter */
+
+ vga_wcrt(NULL, 0x3A, 0x35);
+ svga_wattr(0x33, 0x00);
+
+ if (info->var.vmode & FB_VMODE_DOUBLE)
+ svga_wcrt_mask(0x09, 0x80, 0x80);
+ else
+ svga_wcrt_mask(0x09, 0x00, 0x80);
+
+ if (info->var.vmode & FB_VMODE_INTERLACED)
+ svga_wcrt_mask(0x42, 0x20, 0x20);
+ else
+ svga_wcrt_mask(0x42, 0x00, 0x20);
+
+ /* Disable hardware graphics cursor */
+ svga_wcrt_mask(0x45, 0x00, 0x01);
+ /* Disable Streams engine */
+ svga_wcrt_mask(0x67, 0x00, 0x0C);
+
+ mode = svga_match_format(s3fb_formats, &(info->var), &(info->fix));
+
+ /* S3 virge DX hack */
+ if (par->chip == CHIP_375_VIRGE_DX) {
+ vga_wcrt(NULL, 0x86, 0x80);
+ vga_wcrt(NULL, 0x90, 0x00);
+ }
+
+ /* S3 virge VX hack */
+ if (par->chip == CHIP_988_VIRGE_VX) {
+ vga_wcrt(NULL, 0x50, 0x00);
+ vga_wcrt(NULL, 0x67, 0x50);
+
+ vga_wcrt(NULL, 0x63, (mode <= 2) ? 0x90 : 0x09);
+ vga_wcrt(NULL, 0x66, 0x90);
+ }
+
+ svga_wcrt_mask(0x31, 0x00, 0x40);
+ multiplex = 0;
+ hmul = 1;
+
+ /* Set mode-specific register values */
+ switch (mode) {
+ case 0:
+ pr_debug("fb%d: text mode\n", info->node);
+ svga_set_textmode_vga_regs();
+
+ /* Set additional registers like in 8-bit mode */
+ svga_wcrt_mask(0x50, 0x00, 0x30);
+ svga_wcrt_mask(0x67, 0x00, 0xF0);
+
+ /* Disable enhanced mode */
+ svga_wcrt_mask(0x3A, 0x00, 0x30);
+
+ if (fasttext) {
+ pr_debug("fb%d: high speed text mode set\n", info->node);
+ svga_wcrt_mask(0x31, 0x40, 0x40);
+ }
+ break;
+ case 1:
+ pr_debug("fb%d: 4 bit pseudocolor\n", info->node);
+ vga_wgfx(NULL, VGA_GFX_MODE, 0x40);
+
+ /* Set additional registers like in 8-bit mode */
+ svga_wcrt_mask(0x50, 0x00, 0x30);
+ svga_wcrt_mask(0x67, 0x00, 0xF0);
+
+ /* disable enhanced mode */
+ svga_wcrt_mask(0x3A, 0x00, 0x30);
+ break;
+ case 2:
+ pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node);
+
+ /* Set additional registers like in 8-bit mode */
+ svga_wcrt_mask(0x50, 0x00, 0x30);
+ svga_wcrt_mask(0x67, 0x00, 0xF0);
+
+ /* disable enhanced mode */
+ svga_wcrt_mask(0x3A, 0x00, 0x30);
+ break;
+ case 3:
+ pr_debug("fb%d: 8 bit pseudocolor\n", info->node);
+ if (info->var.pixclock > 20000) {
+ svga_wcrt_mask(0x50, 0x00, 0x30);
+ svga_wcrt_mask(0x67, 0x00, 0xF0);
+ } else {
+ svga_wcrt_mask(0x50, 0x00, 0x30);
+ svga_wcrt_mask(0x67, 0x10, 0xF0);
+ multiplex = 1;
+ }
+ break;
+ case 4:
+ pr_debug("fb%d: 5/5/5 truecolor\n", info->node);
+ if (par->chip == CHIP_988_VIRGE_VX) {
+ if (info->var.pixclock > 20000)
+ svga_wcrt_mask(0x67, 0x20, 0xF0);
+ else
+ svga_wcrt_mask(0x67, 0x30, 0xF0);
+ } else {
+ svga_wcrt_mask(0x50, 0x10, 0x30);
+ svga_wcrt_mask(0x67, 0x30, 0xF0);
+ hmul = 2;
+ }
+ break;
+ case 5:
+ pr_debug("fb%d: 5/6/5 truecolor\n", info->node);
+ if (par->chip == CHIP_988_VIRGE_VX) {
+ if (info->var.pixclock > 20000)
+ svga_wcrt_mask(0x67, 0x40, 0xF0);
+ else
+ svga_wcrt_mask(0x67, 0x50, 0xF0);
+ } else {
+ svga_wcrt_mask(0x50, 0x10, 0x30);
+ svga_wcrt_mask(0x67, 0x50, 0xF0);
+ hmul = 2;
+ }
+ break;
+ case 6:
+ /* VIRGE VX case */
+ pr_debug("fb%d: 8/8/8 truecolor\n", info->node);
+ svga_wcrt_mask(0x67, 0xD0, 0xF0);
+ break;
+ case 7:
+ pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node);
+ svga_wcrt_mask(0x50, 0x30, 0x30);
+ svga_wcrt_mask(0x67, 0xD0, 0xF0);
+ break;
+ default:
+ printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node);
+ return -EINVAL;
+ }
+
+ if (par->chip != CHIP_988_VIRGE_VX) {
+ svga_wseq_mask(0x15, multiplex ? 0x10 : 0x00, 0x10);
+ svga_wseq_mask(0x18, multiplex ? 0x80 : 0x00, 0x80);
+ }
+
+ s3_set_pixclock(info, info->var.pixclock);
+ svga_set_timings(&s3_timing_regs, &(info->var), hmul, 1,
+ (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
+ (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
+ hmul, info->node);
+
+ /* Set interlaced mode start/end register */
+ value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
+ value = ((value * hmul) / 8) - 5;
+ vga_wcrt(NULL, 0x3C, (value + 1) / 2);
+
+ memset((u8*)info->screen_base, 0x00, screen_size);
+ /* Device and screen back on */
+ svga_wcrt_mask(0x17, 0x80, 0x80);
+ svga_wseq_mask(0x01, 0x00, 0x20);
+
+ return 0;
+}
+
+/* Set a colour register */
+
+static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *fb)
+{
+ switch (fb->var.bits_per_pixel) {
+ case 0:
+ case 4:
+ if (regno >= 16)
+ return -EINVAL;
+
+ if ((fb->var.bits_per_pixel == 4) &&
+ (fb->var.nonstd == 0)) {
+ outb(0xF0, VGA_PEL_MSK);
+ outb(regno*16, VGA_PEL_IW);
+ } else {
+ outb(0x0F, VGA_PEL_MSK);
+ outb(regno, VGA_PEL_IW);
+ }
+ outb(red >> 10, VGA_PEL_D);
+ outb(green >> 10, VGA_PEL_D);
+ outb(blue >> 10, VGA_PEL_D);
+ break;
+ case 8:
+ if (regno >= 256)
+ return -EINVAL;
+
+ outb(0xFF, VGA_PEL_MSK);
+ outb(regno, VGA_PEL_IW);
+ outb(red >> 10, VGA_PEL_D);
+ outb(green >> 10, VGA_PEL_D);
+ outb(blue >> 10, VGA_PEL_D);
+ break;
+ case 16:
+ if (regno >= 16)
+ return -EINVAL;
+
+ if (fb->var.green.length == 5)
+ ((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) |
+ ((green & 0xF800) >> 6) | ((blue & 0xF800) >> 11);
+ else if (fb->var.green.length == 6)
+ ((u32*)fb->pseudo_palette)[regno] = (red & 0xF800) |
+ ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
+ else return -EINVAL;
+ break;
+ case 24:
+ case 32:
+ if (regno >= 16)
+ return -EINVAL;
+
+ ((u32*)fb->pseudo_palette)[regno] = ((transp & 0xFF00) << 16) | ((red & 0xFF00) << 8) |
+ (green & 0xFF00) | ((blue & 0xFF00) >> 8);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+/* Set the display blanking state */
+
+static int s3fb_blank(int blank_mode, struct fb_info *info)
+{
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ pr_debug("fb%d: unblank\n", info->node);
+ svga_wcrt_mask(0x56, 0x00, 0x06);
+ svga_wseq_mask(0x01, 0x00, 0x20);
+ break;
+ case FB_BLANK_NORMAL:
+ pr_debug("fb%d: blank\n", info->node);
+ svga_wcrt_mask(0x56, 0x00, 0x06);
+ svga_wseq_mask(0x01, 0x20, 0x20);
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ pr_debug("fb%d: hsync\n", info->node);
+ svga_wcrt_mask(0x56, 0x02, 0x06);
+ svga_wseq_mask(0x01, 0x20, 0x20);
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ pr_debug("fb%d: vsync\n", info->node);
+ svga_wcrt_mask(0x56, 0x04, 0x06);
+ svga_wseq_mask(0x01, 0x20, 0x20);
+ break;
+ case FB_BLANK_POWERDOWN:
+ pr_debug("fb%d: sync down\n", info->node);
+ svga_wcrt_mask(0x56, 0x06, 0x06);
+ svga_wseq_mask(0x01, 0x20, 0x20);
+ break;
+ }
+
+ return 0;
+}
+
+
+/* Pan the display */
+
+static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) {
+
+ unsigned int offset;
+
+ /* Validate the offsets */
+ if ((var->xoffset + var->xres) > var->xres_virtual)
+ return -EINVAL;
+ if ((var->yoffset + var->yres) > var->yres_virtual)
+ return -EINVAL;
+
+ /* Calculate the offset */
+ if (var->bits_per_pixel == 0) {
+ offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
+ offset = offset >> 2;
+ } else {
+ offset = (var->yoffset * info->fix.line_length) +
+ (var->xoffset * var->bits_per_pixel / 8);
+ offset = offset >> 2;
+ }
+
+ /* Set the offset */
+ svga_wcrt_multi(s3_start_address_regs, offset);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Frame buffer operations */
+
+static struct fb_ops s3fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = s3fb_open,
+ .fb_release = s3fb_release,
+ .fb_check_var = s3fb_check_var,
+ .fb_set_par = s3fb_set_par,
+ .fb_setcolreg = s3fb_setcolreg,
+ .fb_blank = s3fb_blank,
+ .fb_pan_display = s3fb_pan_display,
+ .fb_fillrect = s3fb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = s3fb_imageblit,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static int __devinit s3_identification(int chip)
+{
+ if (chip == CHIP_XXX_TRIO) {
+ u8 cr30 = vga_rcrt(NULL, 0x30);
+ u8 cr2e = vga_rcrt(NULL, 0x2e);
+ u8 cr2f = vga_rcrt(NULL, 0x2f);
+
+ if ((cr30 == 0xE0) || (cr30 == 0xE1)) {
+ if (cr2e == 0x10)
+ return CHIP_732_TRIO32;
+ if (cr2e == 0x11) {
+ if (! (cr2f & 0x40))
+ return CHIP_764_TRIO64;
+ else
+ return CHIP_765_TRIO64VP;
+ }
+ }
+ }
+
+ if (chip == CHIP_XXX_TRIO64V2_DXGX) {
+ u8 cr6f = vga_rcrt(NULL, 0x6f);
+
+ if (! (cr6f & 0x01))
+ return CHIP_775_TRIO64V2_DX;
+ else
+ return CHIP_785_TRIO64V2_GX;
+ }
+
+ if (chip == CHIP_XXX_VIRGE_DXGX) {
+ u8 cr6f = vga_rcrt(NULL, 0x6f);
+
+ if (! (cr6f & 0x01))
+ return CHIP_375_VIRGE_DX;
+ else
+ return CHIP_385_VIRGE_GX;
+ }
+
+ return CHIP_UNKNOWN;
+}
+
+
+/* PCI probe */
+
+static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ struct fb_info *info;
+ struct s3fb_info *par;
+ int rc;
+ u8 regval, cr38, cr39;
+
+ /* Ignore secondary VGA device because there is no VGA arbitration */
+ if (! svga_primary_device(dev)) {
+ dev_info(&(dev->dev), "ignoring secondary device\n");
+ return -ENODEV;
+ }
+
+ /* Allocate and fill driver data structure */
+ info = framebuffer_alloc(sizeof(struct s3fb_info), NULL);
+ if (!info) {
+ dev_err(&(dev->dev), "cannot allocate memory\n");
+ return -ENOMEM;
+ }
+
+ par = info->par;
+ mutex_init(&par->open_lock);
+
+ info->flags = FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
+ info->fbops = &s3fb_ops;
+
+ /* Prepare PCI device */
+ rc = pci_enable_device(dev);
+ if (rc < 0) {
+ dev_err(&(dev->dev), "cannot enable PCI device\n");
+ goto err_enable_device;
+ }
+
+ rc = pci_request_regions(dev, "s3fb");
+ if (rc < 0) {
+ dev_err(&(dev->dev), "cannot reserve framebuffer region\n");
+ goto err_request_regions;
+ }
+
+
+ info->fix.smem_start = pci_resource_start(dev, 0);
+ info->fix.smem_len = pci_resource_len(dev, 0);
+
+ /* Map physical IO memory address into kernel space */
+ info->screen_base = pci_iomap(dev, 0, 0);
+ if (! info->screen_base) {
+ rc = -ENOMEM;
+ dev_err(&(dev->dev), "iomap for framebuffer failed\n");
+ goto err_iomap;
+ }
+
+ /* Unlock regs */
+ cr38 = vga_rcrt(NULL, 0x38);
+ cr39 = vga_rcrt(NULL, 0x39);
+ vga_wseq(NULL, 0x08, 0x06);
+ vga_wcrt(NULL, 0x38, 0x48);
+ vga_wcrt(NULL, 0x39, 0xA5);
+
+ /* Find how many physical memory there is on card */
+ /* 0x36 register is accessible even if other registers are locked */
+ regval = vga_rcrt(NULL, 0x36);
+ info->screen_size = s3_memsizes[regval >> 5] << 10;
+ info->fix.smem_len = info->screen_size;
+
+ par->chip = id->driver_data & CHIP_MASK;
+ par->rev = vga_rcrt(NULL, 0x2f);
+ if (par->chip & CHIP_UNDECIDED_FLAG)
+ par->chip = s3_identification(par->chip);
+
+ /* Find MCLK frequency */
+ regval = vga_rseq(NULL, 0x10);
+ par->mclk_freq = ((vga_rseq(NULL, 0x11) + 2) * 14318) / ((regval & 0x1F) + 2);
+ par->mclk_freq = par->mclk_freq >> (regval >> 5);
+
+ /* Restore locks */
+ vga_wcrt(NULL, 0x38, cr38);
+ vga_wcrt(NULL, 0x39, cr39);
+
+ strcpy(info->fix.id, s3_names [par->chip]);
+ info->fix.mmio_start = 0;
+ info->fix.mmio_len = 0;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ info->fix.ypanstep = 0;
+ info->fix.accel = FB_ACCEL_NONE;
+ info->pseudo_palette = (void*) (par->pseudo_palette);
+
+ /* Prepare startup mode */
+ rc = fb_find_mode(&(info->var), info, mode, NULL, 0, NULL, 8);
+ if (! ((rc == 1) || (rc == 2))) {
+ rc = -EINVAL;
+ dev_err(&(dev->dev), "mode %s not found\n", mode);
+ goto err_find_mode;
+ }
+
+ rc = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (rc < 0) {
+ dev_err(&(dev->dev), "cannot allocate colormap\n");
+ goto err_alloc_cmap;
+ }
+
+ rc = register_framebuffer(info);
+ if (rc < 0) {
+ dev_err(&(dev->dev), "cannot register framebuffer\n");
+ goto err_reg_fb;
+ }
+
+ printk(KERN_INFO "fb%d: %s on %s, %d MB RAM, %d MHz MCLK\n", info->node, info->fix.id,
+ pci_name(dev), info->fix.smem_len >> 20, (par->mclk_freq + 500) / 1000);
+
+ if (par->chip == CHIP_UNKNOWN)
+ printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n",
+ info->node, vga_rcrt(NULL, 0x2d), vga_rcrt(NULL, 0x2e),
+ vga_rcrt(NULL, 0x2f), vga_rcrt(NULL, 0x30));
+
+ /* Record a reference to the driver data */
+ pci_set_drvdata(dev, info);
+
+#ifdef CONFIG_MTRR
+ if (mtrr) {
+ par->mtrr_reg = -1;
+ par->mtrr_reg = mtrr_add(info->fix.smem_start, info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
+ }
+#endif
+
+ return 0;
+
+ /* Error handling */
+err_reg_fb:
+ fb_dealloc_cmap(&info->cmap);
+err_alloc_cmap:
+err_find_mode:
+ pci_iounmap(dev, info->screen_base);
+err_iomap:
+ pci_release_regions(dev);
+err_request_regions:
+/* pci_disable_device(dev); */
+err_enable_device:
+ framebuffer_release(info);
+ return rc;
+}
+
+
+/* PCI remove */
+
+static void __devexit s3_pci_remove(struct pci_dev *dev)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct s3fb_info *par = info->par;
+
+ if (info) {
+
+#ifdef CONFIG_MTRR
+ if (par->mtrr_reg >= 0) {
+ mtrr_del(par->mtrr_reg, 0, 0);
+ par->mtrr_reg = -1;
+ }
+#endif
+
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+
+ pci_iounmap(dev, info->screen_base);
+ pci_release_regions(dev);
+/* pci_disable_device(dev); */
+
+ pci_set_drvdata(dev, NULL);
+ framebuffer_release(info);
+ }
+}
+
+/* PCI suspend */
+
+static int s3_pci_suspend(struct pci_dev* dev, pm_message_t state)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct s3fb_info *par = info->par;
+
+ dev_info(&(dev->dev), "suspend\n");
+
+ acquire_console_sem();
+ mutex_lock(&(par->open_lock));
+
+ if ((state.event == PM_EVENT_FREEZE) || (par->ref_count == 0)) {
+ mutex_unlock(&(par->open_lock));
+ release_console_sem();
+ return 0;
+ }
+
+ fb_set_suspend(info, 1);
+
+ pci_save_state(dev);
+ pci_disable_device(dev);
+ pci_set_power_state(dev, pci_choose_state(dev, state));
+
+ mutex_unlock(&(par->open_lock));
+ release_console_sem();
+
+ return 0;
+}
+
+
+/* PCI resume */
+
+static int s3_pci_resume(struct pci_dev* dev)
+{
+ struct fb_info *info = pci_get_drvdata(dev);
+ struct s3fb_info *par = info->par;
+
+ dev_info(&(dev->dev), "resume\n");
+
+ acquire_console_sem();
+ mutex_lock(&(par->open_lock));
+
+ if (par->ref_count == 0) {
+ mutex_unlock(&(par->open_lock));
+ release_console_sem();
+ return 0;
+ }
+
+ pci_set_power_state(dev, PCI_D0);
+ pci_restore_state(dev);
+ pci_enable_device(dev);
+ pci_set_master(dev);
+
+ s3fb_set_par(info);
+ fb_set_suspend(info, 0);
+
+ mutex_unlock(&(par->open_lock));
+ release_console_sem();
+
+ return 0;
+}
+
+
+/* List of boards that we are trying to support */
+
+static struct pci_device_id s3_devices[] __devinitdata = {
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8810), .driver_data = CHIP_XXX_TRIO},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8811), .driver_data = CHIP_XXX_TRIO},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8812), .driver_data = CHIP_M65_AURORA64VP},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8814), .driver_data = CHIP_767_TRIO64UVP},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8901), .driver_data = CHIP_XXX_TRIO64V2_DXGX},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8902), .driver_data = CHIP_551_PLATO_PX},
+
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x5631), .driver_data = CHIP_325_VIRGE},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x883D), .driver_data = CHIP_988_VIRGE_VX},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A01), .driver_data = CHIP_XXX_VIRGE_DXGX},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A10), .driver_data = CHIP_356_VIRGE_GX2},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A11), .driver_data = CHIP_357_VIRGE_GX2P},
+ {PCI_DEVICE(PCI_VENDOR_ID_S3, 0x8A12), .driver_data = CHIP_359_VIRGE_GX2P},
+
+ {0, 0, 0, 0, 0, 0, 0}
+};
+
+
+MODULE_DEVICE_TABLE(pci, s3_devices);
+
+static struct pci_driver s3fb_pci_driver = {
+ .name = "s3fb",
+ .id_table = s3_devices,
+ .probe = s3_pci_probe,
+ .remove = __devexit_p(s3_pci_remove),
+ .suspend = s3_pci_suspend,
+ .resume = s3_pci_resume,
+};
+
+/* Parse user speficied options */
+
+#ifndef MODULE
+static int __init s3fb_setup(char *options)
+{
+ char *opt;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((opt = strsep(&options, ",")) != NULL) {
+
+ if (!*opt)
+ continue;
+#ifdef CONFIG_MTRR
+ else if (!strcmp(opt, "mtrr:"))
+ mtrr = simple_strtoul(opt + 5, NULL, 0);
+#endif
+ else if (!strcmp(opt, "fasttext:"))
+ mtrr = simple_strtoul(opt + 9, NULL, 0);
+ else
+ mode = opt;
+ }
+
+ return 0;
+}
+#endif
+
+/* Cleanup */
+
+static void __exit s3fb_cleanup(void)
+{
+ pr_debug("s3fb: cleaning up\n");
+ pci_unregister_driver(&s3fb_pci_driver);
+}
+
+/* Driver Initialisation */
+
+static int __init s3fb_init(void)
+{
+
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options("s3fb", &option))
+ return -ENODEV;
+ s3fb_setup(option);
+#endif
+
+ pr_debug("s3fb: initializing\n");
+ return pci_register_driver(&s3fb_pci_driver);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Modularization */
+
+module_init(s3fb_init);
+module_exit(s3fb_cleanup);
diff --git a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h
index 0b07f6ae3367..48066ef3af05 100644
--- a/drivers/video/sa1100fb.h
+++ b/drivers/video/sa1100fb.h
@@ -110,9 +110,7 @@ struct sa1100fb_info {
#endif
};
-#define __type_entry(ptr,type,member) ((type *)((char *)(ptr)-offsetof(type,member)))
-
-#define TO_INF(ptr,member) __type_entry(ptr,struct sa1100fb_info,member)
+#define TO_INF(ptr,member) container_of(ptr,struct sa1100fb_info,member)
#define SA1100_PALETTE_MODE_VAL(bpp) (((bpp) & 0x018) << 9)
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 82b3deaae02d..4afa30522fdb 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -833,7 +833,8 @@ static void savage_set_default_par(struct savagefb_par *par,
vga_out8(0x3d5, cr66, par);
}
-static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
+static void savage_update_var(struct fb_var_screeninfo *var,
+ const struct fb_videomode *modedb)
{
var->xres = var->xres_virtual = modedb->xres;
var->yres = modedb->yres;
@@ -902,7 +903,7 @@ static int savagefb_check_var(struct fb_var_screeninfo *var,
}
if (!mode_valid) {
- struct fb_videomode *mode;
+ const struct fb_videomode *mode;
mode = fb_find_best_mode(var, &info->modelist);
if (mode) {
@@ -2206,11 +2207,10 @@ static int __devinit savagefb_probe(struct pci_dev* dev,
info->monspecs.modedb, info->monspecs.modedb_len,
NULL, 8);
} else if (info->monspecs.modedb != NULL) {
- struct fb_videomode *modedb;
+ const struct fb_videomode *mode;
- modedb = fb_find_best_display(&info->monspecs,
- &info->modelist);
- savage_update_var(&info->var, modedb);
+ mode = fb_find_best_display(&info->monspecs, &info->modelist);
+ savage_update_var(&info->var, mode);
}
/* maximize virtual vertical length */
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c
index 2ab3868efde3..c311ad3c3687 100644
--- a/drivers/video/sis/init.c
+++ b/drivers/video/sis/init.c
@@ -317,23 +317,23 @@ InitTo310Pointer(struct SiS_Private *SiS_Pr)
}
#endif
-BOOLEAN
+bool
SiSInitPtr(struct SiS_Private *SiS_Pr)
{
if(SiS_Pr->ChipType < SIS_315H) {
#ifdef SIS300
InitTo300Pointer(SiS_Pr);
#else
- return FALSE;
+ return false;
#endif
} else {
#ifdef SIS315H
InitTo310Pointer(SiS_Pr);
#else
- return FALSE;
+ return false;
#endif
}
- return TRUE;
+ return true;
}
/*********************************************/
@@ -345,7 +345,7 @@ static
#endif
unsigned short
SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
- int Depth, BOOLEAN FSTN, int LCDwidth, int LCDheight)
+ int Depth, bool FSTN, int LCDwidth, int LCDheight)
{
unsigned short ModeIndex = 0;
@@ -483,7 +483,7 @@ SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
unsigned short
SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
- int Depth, BOOLEAN FSTN, unsigned short CustomT, int LCDwidth, int LCDheight,
+ int Depth, bool FSTN, unsigned short CustomT, int LCDwidth, int LCDheight,
unsigned int VBFlags2)
{
unsigned short ModeIndex = 0;
@@ -873,7 +873,7 @@ SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDispl
break;
}
- return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, FALSE, 0, 0);
+ return SiS_GetModeID(VGAEngine, 0, HDisplay, VDisplay, Depth, false, 0, 0);
}
@@ -1020,12 +1020,12 @@ SiS_GetSysFlags(struct SiS_Private *SiS_Pr)
/* 661 and newer: NEVER write non-zero to SR11[7:4] */
/* (SR11 is used for DDC and in enable/disablebridge) */
- SiS_Pr->SiS_SensibleSR11 = FALSE;
+ SiS_Pr->SiS_SensibleSR11 = false;
SiS_Pr->SiS_MyCR63 = 0x63;
if(SiS_Pr->ChipType >= SIS_330) {
SiS_Pr->SiS_MyCR63 = 0x53;
if(SiS_Pr->ChipType >= SIS_661) {
- SiS_Pr->SiS_SensibleSR11 = TRUE;
+ SiS_Pr->SiS_SensibleSR11 = true;
}
}
@@ -1253,7 +1253,7 @@ SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
/* HELPER: Determine ROM usage */
/*********************************************/
-BOOLEAN
+bool
SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
{
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
@@ -1261,16 +1261,16 @@ SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
if(SiS_Pr->ChipType >= XGI_20) {
/* XGI ROMs don't qualify */
- return FALSE;
+ return false;
} else if(SiS_Pr->ChipType >= SIS_761) {
/* I very much assume 761, 340 and newer will use new layout */
- return TRUE;
+ return true;
} else if(SiS_Pr->ChipType >= SIS_661) {
if((ROMAddr[0x1a] == 'N') &&
(ROMAddr[0x1b] == 'e') &&
(ROMAddr[0x1c] == 'w') &&
(ROMAddr[0x1d] == 'V')) {
- return TRUE;
+ return true;
}
romversoffs = ROMAddr[0x16] | (ROMAddr[0x17] << 8);
if(romversoffs) {
@@ -1280,17 +1280,17 @@ SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr)
}
}
if((romvmaj != 0) || (romvmin >= 92)) {
- return TRUE;
+ return true;
}
} else if(IS_SIS650740) {
if((ROMAddr[0x1a] == 'N') &&
(ROMAddr[0x1b] == 'e') &&
(ROMAddr[0x1c] == 'w') &&
(ROMAddr[0x1d] == 'V')) {
- return TRUE;
+ return true;
}
}
- return FALSE;
+ return false;
}
static void
@@ -1299,8 +1299,8 @@ SiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
unsigned short romptr = 0;
- SiS_Pr->SiS_UseROM = FALSE;
- SiS_Pr->SiS_ROMNew = FALSE;
+ SiS_Pr->SiS_UseROM = false;
+ SiS_Pr->SiS_ROMNew = false;
SiS_Pr->SiS_PWDOffset = 0;
if(SiS_Pr->ChipType >= XGI_20) return;
@@ -1312,15 +1312,15 @@ SiSDetermineROMUsage(struct SiS_Private *SiS_Pr)
* of the BIOS image.
*/
if((ROMAddr[3] == 0xe9) && ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
- SiS_Pr->SiS_UseROM = TRUE;
+ SiS_Pr->SiS_UseROM = true;
} else if(SiS_Pr->ChipType < SIS_315H) {
/* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
* the others do as well
*/
- SiS_Pr->SiS_UseROM = TRUE;
+ SiS_Pr->SiS_UseROM = true;
} else {
/* 315/330 series stick to the standard(s) */
- SiS_Pr->SiS_UseROM = TRUE;
+ SiS_Pr->SiS_UseROM = true;
if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) {
SiS_Pr->SiS_EMIOffset = 14;
SiS_Pr->SiS_PWDOffset = 17;
@@ -1488,7 +1488,7 @@ SiS_GetVBType(struct SiS_Private *SiS_Pr)
/*********************************************/
#ifdef SIS_LINUX_KERNEL
-static BOOLEAN
+static bool
SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex)
{
@@ -1496,10 +1496,10 @@ SiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex);
unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1;
- if(!AdapterMemSize) return TRUE;
+ if(!AdapterMemSize) return true;
- if(AdapterMemSize < memorysize) return FALSE;
- return TRUE;
+ if(AdapterMemSize < memorysize) return false;
+ return true;
}
#endif
@@ -1605,7 +1605,7 @@ SiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
/* HELPER: SearchModeID */
/*********************************************/
-BOOLEAN
+bool
SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
unsigned short *ModeIdIndex)
{
@@ -1617,7 +1617,7 @@ SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break;
- if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return FALSE;
+ if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return false;
}
if((*ModeNo) == 0x07) {
@@ -1635,11 +1635,11 @@ SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) {
if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break;
- if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return FALSE;
+ if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return false;
}
}
- return TRUE;
+ return true;
}
/*********************************************/
@@ -1696,13 +1696,13 @@ SiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide
/* HELPER: LowModeTests */
/*********************************************/
-static BOOLEAN
+static bool
SiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
unsigned short temp, temp1, temp2;
if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
- return TRUE;
+ return true;
temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
@@ -1712,13 +1712,13 @@ SiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
if((SiS_Pr->ChipType >= SIS_315H) ||
(SiS_Pr->ChipType == SIS_300)) {
- if(temp2 == 0x55) return FALSE;
- else return TRUE;
+ if(temp2 == 0x55) return false;
+ else return true;
} else {
- if(temp2 != 0x55) return TRUE;
+ if(temp2 != 0x55) return true;
else {
SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
- return FALSE;
+ return false;
}
}
}
@@ -3237,14 +3237,14 @@ static void
SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
- BOOLEAN isslavemode = FALSE;
+ bool isslavemode = false;
if( (pSiS->VBFlags2 & VB2_VIDEOBRIDGE) &&
( ((pSiS->VGAEngine == SIS_300_VGA) &&
(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
((pSiS->VGAEngine == SIS_315_VGA) &&
(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
- isslavemode = TRUE;
+ isslavemode = true;
}
/* We need to set pitch for CRT1 if bridge is in slave mode, too */
@@ -3264,10 +3264,10 @@ SiS_SetPitch(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
#ifdef SIS_XORG_XF86
/* We need pScrn for setting the pitch correctly */
-BOOLEAN
-SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, BOOLEAN dosetpitch)
+bool
+SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo, bool dosetpitch)
#else
-BOOLEAN
+bool
SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
#endif
{
@@ -3277,8 +3277,8 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
#ifdef SIS_LINUX_KERNEL
unsigned short KeepLockReg;
- SiS_Pr->UseCustomMode = FALSE;
- SiS_Pr->CRT1UsesCustomMode = FALSE;
+ SiS_Pr->UseCustomMode = false;
+ SiS_Pr->CRT1UsesCustomMode = false;
#endif
SiS_Pr->SiS_flag_clearbuffer = 0;
@@ -3317,7 +3317,7 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
SiS_UnLockCRT2(SiS_Pr);
if(!SiS_Pr->UseCustomMode) {
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+ if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
} else {
ModeIdIndex = 0;
}
@@ -3347,18 +3347,18 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
#ifdef SIS_LINUX_KERNEL
/* Check memory size (kernel framebuffer driver only) */
if(!SiS_CheckMemorySize(SiS_Pr, ModeNo, ModeIdIndex)) {
- return FALSE;
+ return false;
}
#endif
SiS_OpenCRTC(SiS_Pr);
if(SiS_Pr->UseCustomMode) {
- SiS_Pr->CRT1UsesCustomMode = TRUE;
+ SiS_Pr->CRT1UsesCustomMode = true;
SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
} else {
- SiS_Pr->CRT1UsesCustomMode = FALSE;
+ SiS_Pr->CRT1UsesCustomMode = false;
}
/* Set mode on CRT1 */
@@ -3445,7 +3445,7 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
if(KeepLockReg != 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
#endif
- return TRUE;
+ return true;
}
/*********************************************/
@@ -3454,14 +3454,14 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
/*********************************************/
#ifdef SIS_XORG_XF86
-BOOLEAN
+bool
SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, BOOLEAN IsCustom)
+ DisplayModePtr mode, bool IsCustom)
{
SISPtr pSiS = SISPTR(pScrn);
unsigned short ModeNo = 0;
- SiS_Pr->UseCustomMode = FALSE;
+ SiS_Pr->UseCustomMode = false;
if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
@@ -3475,13 +3475,13 @@ SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
/* Don't need vbflags here; checks done earlier */
ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
- if(!ModeNo) return FALSE;
+ if(!ModeNo) return false;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
}
- return(SiSSetMode(SiS_Pr, pScrn, ModeNo, TRUE));
+ return(SiSSetMode(SiS_Pr, pScrn, ModeNo, true));
}
/*********************************************/
@@ -3489,9 +3489,9 @@ SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
/* for Dual-Head modes */
/*********************************************/
-BOOLEAN
+bool
SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, BOOLEAN IsCustom)
+ DisplayModePtr mode, bool IsCustom)
{
SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
SISPtr pSiS = SISPTR(pScrn);
@@ -3502,7 +3502,7 @@ SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
unsigned short ModeNo = 0;
unsigned char backupreg = 0;
- SiS_Pr->UseCustomMode = FALSE;
+ SiS_Pr->UseCustomMode = false;
/* Remember: Custom modes for CRT2 are ONLY supported
* -) on the 30x/B/C, and
@@ -3516,7 +3516,7 @@ SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
} else {
ModeNo = SiS_GetModeNumber(pScrn, mode, pSiS->VBFlags);
- if(!ModeNo) return FALSE;
+ if(!ModeNo) return false;
}
@@ -3550,10 +3550,10 @@ SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
if(pSiSEnt->CRT1ModeNo == -1) {
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
"Setting CRT2 mode delayed until after setting CRT1 mode\n");
- return TRUE;
+ return true;
}
#endif
- pSiSEnt->CRT2ModeSet = TRUE;
+ pSiSEnt->CRT2ModeSet = true;
}
#endif
@@ -3578,7 +3578,7 @@ SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
SiS_UnLockCRT2(SiS_Pr);
if(!SiS_Pr->UseCustomMode) {
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+ if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
} else {
ModeIdIndex = 0;
}
@@ -3658,7 +3658,7 @@ SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
SiS_Handle760(SiS_Pr);
- return TRUE;
+ return true;
}
/*********************************************/
@@ -3666,9 +3666,9 @@ SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
/* for Dual-Head modes */
/*********************************************/
-BOOLEAN
+bool
SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, BOOLEAN IsCustom)
+ DisplayModePtr mode, bool IsCustom)
{
SISIOADDRESS BaseAddr = SiS_Pr->IOAddress;
SISPtr pSiS = SISPTR(pScrn);
@@ -3677,10 +3677,10 @@ SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
#ifdef SISDUALHEAD
SISEntPtr pSiSEnt = pSiS->entityPrivate;
unsigned char backupcr30, backupcr31, backupcr38, backupcr35, backupp40d=0;
- BOOLEAN backupcustom;
+ bool backupcustom;
#endif
- SiS_Pr->UseCustomMode = FALSE;
+ SiS_Pr->UseCustomMode = false;
if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
@@ -3697,7 +3697,7 @@ SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
} else {
ModeNo = SiS_GetModeNumber(pScrn, mode, 0); /* don't give VBFlags */
- if(!ModeNo) return FALSE;
+ if(!ModeNo) return false;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
"Setting standard mode 0x%x on CRT1\n", ModeNo);
@@ -3721,7 +3721,7 @@ SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
SiS_UnLockCRT2(SiS_Pr);
if(!SiS_Pr->UseCustomMode) {
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+ if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
} else {
ModeIdIndex = 0;
}
@@ -3771,11 +3771,11 @@ SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
#endif
if(SiS_Pr->UseCustomMode) {
- SiS_Pr->CRT1UsesCustomMode = TRUE;
+ SiS_Pr->CRT1UsesCustomMode = true;
SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
} else {
- SiS_Pr->CRT1UsesCustomMode = FALSE;
+ SiS_Pr->CRT1UsesCustomMode = false;
}
/* Reset CRT2 if changing mode on CRT1 */
@@ -3838,7 +3838,7 @@ SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
/* Backup/Set ModeNo in BIOS scratch area */
SiS_GetSetModeID(pScrn,ModeNo);
- return TRUE;
+ return true;
}
#endif /* Linux_XF86 */
@@ -4082,7 +4082,7 @@ SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
DisplayModePtr current
#endif
#ifdef SIS_LINUX_KERNEL
- struct fb_var_screeninfo *var, BOOLEAN writeres
+ struct fb_var_screeninfo *var, bool writeres
#endif
)
{
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index 59d12844b4dd..f40a680df86f 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -1521,13 +1521,13 @@ static const struct SiS_LVDSCRT1Data SiS_LVDSCRT1640x480_1_H[] =
0x00}}
};
-BOOLEAN SiSInitPtr(struct SiS_Private *SiS_Pr);
+bool SiSInitPtr(struct SiS_Private *SiS_Pr);
#ifdef SIS_XORG_XF86
unsigned short SiS_GetModeID(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDisplay,
- int Depth, BOOLEAN FSTN, int LCDwith, int LCDheight);
+ int Depth, bool FSTN, int LCDwith, int LCDheight);
#endif
unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
- int VDisplay, int Depth, BOOLEAN FSTN,
+ int VDisplay, int Depth, bool FSTN,
unsigned short CustomT, int LCDwith, int LCDheight,
unsigned int VBFlags2);
unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
@@ -1558,12 +1558,12 @@ void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex);
-BOOLEAN SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
+bool SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
#ifndef SIS_LINUX_KERNEL
void SiS_GetVBType(struct SiS_Private *SiS_Pr);
#endif
-BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
+bool SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
unsigned short *ModeIdIndex);
unsigned short SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex);
@@ -1581,17 +1581,17 @@ unsigned short SiS_GetLatencyFactor630(struct SiS_Private *SiS_Pr, unsigned shor
#endif
void SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
#ifdef SIS_XORG_XF86
-BOOLEAN SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo,
- BOOLEAN dosetpitch);
-BOOLEAN SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, BOOLEAN IsCustom);
-BOOLEAN SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, BOOLEAN IsCustom);
-BOOLEAN SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
- DisplayModePtr mode, BOOLEAN IsCustom);
+bool SiSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, unsigned short ModeNo,
+ bool dosetpitch);
+bool SiSBIOSSetMode(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, bool IsCustom);
+bool SiSBIOSSetModeCRT2(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, bool IsCustom);
+bool SiSBIOSSetModeCRT1(struct SiS_Private *SiS_Pr, ScrnInfoPtr pScrn,
+ DisplayModePtr mode, bool IsCustom);
#endif
#ifdef SIS_LINUX_KERNEL
-BOOLEAN SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+bool SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
#endif
void SiS_CalcCRRegisters(struct SiS_Private *SiS_Pr, int depth);
void SiS_CalcLCDACRT1Timing(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
@@ -1602,7 +1602,7 @@ void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdat
#endif
#ifdef SIS_LINUX_KERNEL
void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata, int xres,
- int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
+ int yres, struct fb_var_screeninfo *var, bool writeres);
#endif
/* From init301.c: */
@@ -1615,7 +1615,7 @@ extern void SiS_SetTVMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex);
extern void SiS_UnLockCRT2(struct SiS_Private *SiS_Pr);
extern void SiS_DisableBridge(struct SiS_Private *);
-extern BOOLEAN SiS_SetCRT2Group(struct SiS_Private *, unsigned short);
+extern bool SiS_SetCRT2Group(struct SiS_Private *, unsigned short);
extern unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex);
extern void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
@@ -1624,8 +1624,8 @@ extern unsigned short SiS_GetResInfo(struct SiS_Private *SiS_Pr, unsigned short
extern unsigned short SiS_GetCH700x(struct SiS_Private *SiS_Pr, unsigned short tempax);
extern unsigned short SiS_GetVCLK2Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex, unsigned short RRTI);
-extern BOOLEAN SiS_IsVAMode(struct SiS_Private *);
-extern BOOLEAN SiS_IsDualEdge(struct SiS_Private *);
+extern bool SiS_IsVAMode(struct SiS_Private *);
+extern bool SiS_IsDualEdge(struct SiS_Private *);
#ifdef SIS_XORG_XF86
/* From other modules: */
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c
index 47e1896cffeb..da33d801c22e 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/sis/init301.c
@@ -200,7 +200,7 @@ GetLCDStructPtr661_2(struct SiS_Private *SiS_Pr)
/* Adjust Rate for CRT2 */
/*********************************************/
-static BOOLEAN
+static bool
SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RRTI, unsigned short *i)
{
@@ -269,7 +269,7 @@ SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
/* Look backwards in table for matching CRT2 mode */
for(; SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID == modeid; (*i)--) {
infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
- if(infoflag & checkmask) return TRUE;
+ if(infoflag & checkmask) return true;
if((*i) == 0) break;
}
@@ -279,9 +279,9 @@ SiS_AdjustCRT2Rate(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
for((*i) = 0; ; (*i)++) {
if(SiS_Pr->SiS_RefIndex[RRTI + (*i)].ModeID != modeid) break;
infoflag = SiS_Pr->SiS_RefIndex[RRTI + (*i)].Ext_InfoFlag;
- if(infoflag & checkmask) return TRUE;
+ if(infoflag & checkmask) return true;
}
- return FALSE;
+ return false;
}
/*********************************************/
@@ -405,7 +405,7 @@ SiS_SaveCRT2Info(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
/*********************************************/
#ifdef SIS300
-static BOOLEAN
+static bool
SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
{
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
@@ -415,13 +415,13 @@ SiS_CR36BIOSWord23b(struct SiS_Private *SiS_Pr)
if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
temp1 = SISGETROMW(0x23b);
- if(temp1 & temp) return TRUE;
+ if(temp1 & temp) return true;
}
}
- return FALSE;
+ return false;
}
-static BOOLEAN
+static bool
SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
{
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
@@ -431,10 +431,10 @@ SiS_CR36BIOSWord23d(struct SiS_Private *SiS_Pr)
if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
temp = 1 << ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4) & 0x0f);
temp1 = SISGETROMW(0x23d);
- if(temp1 & temp) return TRUE;
+ if(temp1 & temp) return true;
}
}
- return FALSE;
+ return false;
}
#endif
@@ -687,38 +687,38 @@ SiS_VBLongWait(struct SiS_Private *SiS_Pr)
/*********************************************/
#ifdef SIS300
-static BOOLEAN
+static bool
SiS_Is301B(struct SiS_Private *SiS_Pr)
{
- if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return TRUE;
- return FALSE;
+ if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01) >= 0xb0) return true;
+ return false;
}
#endif
-static BOOLEAN
+static bool
SiS_CRT2IsLCD(struct SiS_Private *SiS_Pr)
{
if(SiS_Pr->ChipType == SIS_730) {
- if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return TRUE;
+ if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x20) return true;
}
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return TRUE;
- return FALSE;
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0x20) return true;
+ return false;
}
-BOOLEAN
+bool
SiS_IsDualEdge(struct SiS_Private *SiS_Pr)
{
#ifdef SIS315H
if(SiS_Pr->ChipType >= SIS_315H) {
if((SiS_Pr->ChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return TRUE;
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableDualEdge) return true;
}
}
#endif
- return FALSE;
+ return false;
}
-BOOLEAN
+bool
SiS_IsVAMode(struct SiS_Private *SiS_Pr)
{
#ifdef SIS315H
@@ -726,70 +726,70 @@ SiS_IsVAMode(struct SiS_Private *SiS_Pr)
if(SiS_Pr->ChipType >= SIS_315H) {
flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
+ if((flag & EnableDualEdge) && (flag & SetToLCDA)) return true;
}
#endif
- return FALSE;
+ return false;
}
#ifdef SIS315H
-static BOOLEAN
+static bool
SiS_IsVAorLCD(struct SiS_Private *SiS_Pr)
{
- if(SiS_IsVAMode(SiS_Pr)) return TRUE;
- if(SiS_CRT2IsLCD(SiS_Pr)) return TRUE;
- return FALSE;
+ if(SiS_IsVAMode(SiS_Pr)) return true;
+ if(SiS_CRT2IsLCD(SiS_Pr)) return true;
+ return false;
}
#endif
-static BOOLEAN
+static bool
SiS_IsDualLink(struct SiS_Private *SiS_Pr)
{
#ifdef SIS315H
if(SiS_Pr->ChipType >= SIS_315H) {
if((SiS_CRT2IsLCD(SiS_Pr)) ||
(SiS_IsVAMode(SiS_Pr))) {
- if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return TRUE;
+ if(SiS_Pr->SiS_LCDInfo & LCDDualLink) return true;
}
}
#endif
- return FALSE;
+ return false;
}
#ifdef SIS315H
-static BOOLEAN
+static bool
SiS_TVEnabled(struct SiS_Private *SiS_Pr)
{
- if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return TRUE;
+ if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) != 0x0c) return true;
if(SiS_Pr->SiS_VBType & VB_SISYPBPR) {
- if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return TRUE;
+ if(SiS_GetReg(SiS_Pr->SiS_Part2Port,0x4d) & 0x10) return true;
}
- return FALSE;
+ return false;
}
#endif
#ifdef SIS315H
-static BOOLEAN
+static bool
SiS_LCDAEnabled(struct SiS_Private *SiS_Pr)
{
- if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return TRUE;
- return FALSE;
+ if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) return true;
+ return false;
}
#endif
#ifdef SIS315H
-static BOOLEAN
+static bool
SiS_WeHaveBacklightCtrl(struct SiS_Private *SiS_Pr)
{
if((SiS_Pr->ChipType >= SIS_315H) && (SiS_Pr->ChipType < SIS_661)) {
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return TRUE;
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x79) & 0x10) return true;
}
- return FALSE;
+ return false;
}
#endif
#ifdef SIS315H
-static BOOLEAN
+static bool
SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
{
unsigned short flag;
@@ -798,90 +798,90 @@ SiS_IsNotM650orLater(struct SiS_Private *SiS_Pr)
flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
/* Check for revision != A0 only */
if((flag == 0xe0) || (flag == 0xc0) ||
- (flag == 0xb0) || (flag == 0x90)) return FALSE;
- } else if(SiS_Pr->ChipType >= SIS_661) return FALSE;
- return TRUE;
+ (flag == 0xb0) || (flag == 0x90)) return false;
+ } else if(SiS_Pr->ChipType >= SIS_661) return false;
+ return true;
}
#endif
#ifdef SIS315H
-static BOOLEAN
+static bool
SiS_IsYPbPr(struct SiS_Private *SiS_Pr)
{
if(SiS_Pr->ChipType >= SIS_315H) {
/* YPrPb = 0x08 */
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return TRUE;
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHYPbPr) return true;
}
- return FALSE;
+ return false;
}
#endif
#ifdef SIS315H
-static BOOLEAN
+static bool
SiS_IsChScart(struct SiS_Private *SiS_Pr)
{
if(SiS_Pr->ChipType >= SIS_315H) {
/* Scart = 0x04 */
- if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return TRUE;
+ if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x38) & EnableCHScart) return true;
}
- return FALSE;
+ return false;
}
#endif
#ifdef SIS315H
-static BOOLEAN
+static bool
SiS_IsTVOrYPbPrOrScart(struct SiS_Private *SiS_Pr)
{
unsigned short flag;
if(SiS_Pr->ChipType >= SIS_315H) {
flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(flag & SetCRT2ToTV) return TRUE;
+ if(flag & SetCRT2ToTV) return true;
flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(flag & EnableCHYPbPr) return TRUE; /* = YPrPb = 0x08 */
- if(flag & EnableCHScart) return TRUE; /* = Scart = 0x04 - TW */
+ if(flag & EnableCHYPbPr) return true; /* = YPrPb = 0x08 */
+ if(flag & EnableCHScart) return true; /* = Scart = 0x04 - TW */
} else {
flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(flag & SetCRT2ToTV) return TRUE;
+ if(flag & SetCRT2ToTV) return true;
}
- return FALSE;
+ return false;
}
#endif
#ifdef SIS315H
-static BOOLEAN
+static bool
SiS_IsLCDOrLCDA(struct SiS_Private *SiS_Pr)
{
unsigned short flag;
if(SiS_Pr->ChipType >= SIS_315H) {
flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(flag & SetCRT2ToLCD) return TRUE;
+ if(flag & SetCRT2ToLCD) return true;
flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
- if(flag & SetToLCDA) return TRUE;
+ if(flag & SetToLCDA) return true;
} else {
flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
- if(flag & SetCRT2ToLCD) return TRUE;
+ if(flag & SetCRT2ToLCD) return true;
}
- return FALSE;
+ return false;
}
#endif
-static BOOLEAN
+static bool
SiS_HaveBridge(struct SiS_Private *SiS_Pr)
{
unsigned short flag;
if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
- return TRUE;
+ return true;
} else if(SiS_Pr->SiS_VBType & VB_SISVB) {
flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
- if((flag == 1) || (flag == 2)) return TRUE;
+ if((flag == 1) || (flag == 2)) return true;
}
- return FALSE;
+ return false;
}
-static BOOLEAN
+static bool
SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
{
unsigned short flag;
@@ -890,23 +890,23 @@ SiS_BridgeIsEnabled(struct SiS_Private *SiS_Pr)
flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
if(SiS_Pr->ChipType < SIS_315H) {
flag &= 0xa0;
- if((flag == 0x80) || (flag == 0x20)) return TRUE;
+ if((flag == 0x80) || (flag == 0x20)) return true;
} else {
flag &= 0x50;
- if((flag == 0x40) || (flag == 0x10)) return TRUE;
+ if((flag == 0x40) || (flag == 0x10)) return true;
}
}
- return FALSE;
+ return false;
}
-static BOOLEAN
+static bool
SiS_BridgeInSlavemode(struct SiS_Private *SiS_Pr)
{
unsigned short flag1;
flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
- if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
- return FALSE;
+ if(flag1 & (SetInSlaveMode >> 8)) return true;
+ return false;
}
/*********************************************/
@@ -1461,11 +1461,11 @@ SiS_GetLCDInfoBIOS(struct SiS_Private *SiS_Pr)
if((ROMAddr = GetLCDStructPtr661(SiS_Pr))) {
if((temp = SISGETROMW(6)) != SiS_Pr->PanelHT) {
- SiS_Pr->SiS_NeedRomModeData = TRUE;
+ SiS_Pr->SiS_NeedRomModeData = true;
SiS_Pr->PanelHT = temp;
}
if((temp = SISGETROMW(8)) != SiS_Pr->PanelVT) {
- SiS_Pr->SiS_NeedRomModeData = TRUE;
+ SiS_Pr->SiS_NeedRomModeData = true;
SiS_Pr->PanelVT = temp;
}
SiS_Pr->PanelHRS = SISGETROMW(10);
@@ -1516,7 +1516,7 @@ void
SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex)
{
unsigned short temp,modeflag,resinfo=0,modexres=0,modeyres=0;
- BOOLEAN panelcanscale = FALSE;
+ bool panelcanscale = false;
#ifdef SIS300
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
static const unsigned char SiS300SeriesLCDRes[] =
@@ -1534,10 +1534,10 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
SiS_Pr->PanelHRE = 999; /* HSync end */
SiS_Pr->PanelVRS = 999; /* VSync start */
SiS_Pr->PanelVRE = 999; /* VSync end */
- SiS_Pr->SiS_NeedRomModeData = FALSE;
+ SiS_Pr->SiS_NeedRomModeData = false;
/* Alternative 1600x1200@60 timing for 1600x1200 LCDA */
- SiS_Pr->Alternate1600x1200 = FALSE;
+ SiS_Pr->Alternate1600x1200 = false;
if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))) return;
@@ -1633,7 +1633,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
}
- panelcanscale = (SiS_Pr->SiS_LCDInfo & DontExpandLCD) ? TRUE : FALSE;
+ panelcanscale = (bool)(SiS_Pr->SiS_LCDInfo & DontExpandLCD);
if(!SiS_Pr->UsePanelScaler) SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
@@ -1833,7 +1833,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
SiS_Pr->PanelHRS = 48; SiS_Pr->PanelHRE = 32;
SiS_Pr->PanelVRS = 2; SiS_Pr->PanelVRE = 4;
SiS_Pr->PanelVCLKIdx315 = VCLK130_315;
- SiS_Pr->Alternate1600x1200 = TRUE;
+ SiS_Pr->Alternate1600x1200 = true;
}
} else if(SiS_Pr->SiS_IF_DEF_LVDS) {
SiS_Pr->PanelHT = 2048; SiS_Pr->PanelVT = 1320;
@@ -3448,7 +3448,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
} else {
- BOOLEAN gotit = FALSE;
+ bool gotit = false;
if((SiS_Pr->SiS_LCDInfo & DontExpandLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
@@ -3456,7 +3456,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
SiS_Pr->SiS_VGAVT = SiS_Pr->PanelVT;
SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
- gotit = TRUE;
+ gotit = true;
} else if( (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) && (romptr) && (ROMAddr) ) {
@@ -3474,7 +3474,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
if(ROMAddr[romptr+9] & 0x80) SiS_Pr->SiS_RVBHRS2 -= tempax;
else SiS_Pr->SiS_RVBHRS2 += tempax;
}
- if(SiS_Pr->SiS_VGAHT) gotit = TRUE;
+ if(SiS_Pr->SiS_VGAHT) gotit = true;
else {
SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
SiS_Pr->SiS_LCDInfo &= ~LCDPass11;
@@ -3485,7 +3485,7 @@ SiS_GetCRT2Data301(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
SiS_Pr->SiS_HT = SiS_Pr->PanelHT;
SiS_Pr->SiS_VT = SiS_Pr->PanelVT;
SiS_Pr->SiS_RVBHRS2 = 0;
- gotit = TRUE;
+ gotit = true;
}
#endif
@@ -3960,8 +3960,8 @@ SiS_DisableBridge(struct SiS_Private *SiS_Pr)
#ifdef SIS315H /* 315 series */
int didpwd = 0;
- BOOLEAN custom1 = ((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
- (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) ? TRUE : FALSE;
+ bool custom1 = (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+ (SiS_Pr->SiS_CustomT == CUT_CLEVO1400);
modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34) & 0x7f;
@@ -4313,7 +4313,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
unsigned short temp=0, tempah;
#ifdef SIS315H
unsigned short temp1, pushax=0;
- BOOLEAN delaylong = FALSE;
+ bool delaylong = false;
#endif
if(SiS_Pr->SiS_VBType & VB_SISVB) {
@@ -4448,7 +4448,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
SiS_PanelDelayLoop(SiS_Pr, 3, 10);
- delaylong = TRUE;
+ delaylong = true;
}
}
@@ -4530,7 +4530,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
SiS_Pr->EMI_33 = ROMAddr[romptr + SiS_Pr->SiS_EMIOffset + 2];
if(ROMAddr[romptr + 1] & 0x10) SiS_Pr->EMI_30 = 0x40;
/* emidelay = SISGETROMW((romptr + 0x22)); */
- SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = TRUE;
+ SiS_Pr->HaveEMI = SiS_Pr->HaveEMILCD = SiS_Pr->OverruleEMI = true;
}
}
@@ -4644,7 +4644,7 @@ SiS_EnableBridge(struct SiS_Private *SiS_Pr)
SiS_PanelDelayLoop(SiS_Pr, 3, 5);
if(delaylong) {
SiS_PanelDelayLoop(SiS_Pr, 3, 5);
- delaylong = FALSE;
+ delaylong = false;
}
SiS_WaitVBRetrace(SiS_Pr);
SiS_WaitVBRetrace(SiS_Pr);
@@ -5454,7 +5454,7 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
unsigned short modeflag, resinfo = 0;
unsigned short push2, tempax, tempbx, tempcx, temp;
unsigned int tempeax = 0, tempebx, tempecx, tempvcfact = 0;
- BOOLEAN islvds = FALSE, issis = FALSE, chkdclkfirst = FALSE;
+ bool islvds = false, issis = false, chkdclkfirst = false;
#ifdef SIS300
unsigned short crt2crtc = 0;
#endif
@@ -5480,17 +5480,17 @@ SiS_SetGroup1_LVDS(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
/* is lvds if really LVDS, or 301B-DH with external LVDS transmitter */
if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBType & VB_NoLCD)) {
- islvds = TRUE;
+ islvds = true;
}
/* is really sis if sis bridge, but not 301B-DH */
if((SiS_Pr->SiS_VBType & VB_SISVB) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
- issis = TRUE;
+ issis = true;
}
if((SiS_Pr->ChipType >= SIS_315H) && (islvds) && (!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA))) {
if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
- chkdclkfirst = TRUE;
+ chkdclkfirst = true;
}
}
@@ -6447,13 +6447,13 @@ SiS_SetGroup2_C_ELV(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned
SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4e,0xeb,temp);
}
-static BOOLEAN
+static bool
SiS_GetCRT2Part2Ptr(struct SiS_Private *SiS_Pr,unsigned short ModeNo,unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex,unsigned short *CRT2Index,
unsigned short *ResIndex)
{
- if(SiS_Pr->ChipType < SIS_315H) return FALSE;
+ if(SiS_Pr->ChipType < SIS_315H) return false;
if(ModeNo <= 0x13)
(*ResIndex) = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
@@ -6688,7 +6688,7 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
unsigned short i, j, tempax, tempbx, tempcx, tempch, tempcl, temp;
unsigned short push2, modeflag, crt2crtc, bridgeoffset;
unsigned int longtemp, PhaseIndex;
- BOOLEAN newtvphase;
+ bool newtvphase;
const unsigned char *TimingPoint;
#ifdef SIS315H
unsigned short resindex, CRT2Index;
@@ -6721,11 +6721,11 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
PhaseIndex = 0x01; /* SiS_PALPhase */
TimingPoint = SiS_Pr->SiS_PALTiming;
- newtvphase = FALSE;
+ newtvphase = false;
if( (SiS_Pr->SiS_VBType & VB_SIS30xBLV) &&
( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
(SiS_Pr->SiS_TVMode & TVSetTVSimuMode) ) ) {
- newtvphase = TRUE;
+ newtvphase = true;
}
if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVision) {
@@ -7754,13 +7754,13 @@ SiS_SetGroup5(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
/* MODIFY CRT1 GROUP FOR SLAVE MODE */
/*********************************************/
-static BOOLEAN
+static bool
SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex,
unsigned short RefreshRateTableIndex, unsigned short *ResIndex,
unsigned short *DisplayType)
{
unsigned short modeflag = 0;
- BOOLEAN checkhd = TRUE;
+ bool checkhd = true;
/* Pass 1:1 not supported here */
@@ -7792,7 +7792,7 @@ SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
(*DisplayType = 0);
switch(SiS_Pr->SiS_LCDResInfo) {
case Panel_320x240_1: (*DisplayType) = 50;
- checkhd = FALSE;
+ checkhd = false;
break;
case Panel_320x240_2: (*DisplayType) = 14;
break;
@@ -7802,7 +7802,7 @@ SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
break;
case Panel_1024x600: (*DisplayType) = 26;
break;
- default: return TRUE;
+ default: return true;
}
if(checkhd) {
@@ -7815,7 +7815,7 @@ SiS_GetLVDSCRT1Ptr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned s
}
- return TRUE;
+ return true;
}
static void
@@ -8654,7 +8654,7 @@ SiS_ChrontelDoSomething1(struct SiS_Private *SiS_Pr)
/* MAIN: SET CRT2 REGISTER GROUP */
/*********************************************/
-BOOLEAN
+bool
SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
#ifdef SIS300
@@ -8690,7 +8690,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
SiS_LockCRT2(SiS_Pr);
SiS_DisplayOn(SiS_Pr);
- return TRUE;
+ return true;
}
SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex);
@@ -8828,7 +8828,7 @@ SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
SiS_LockCRT2(SiS_Pr);
}
- return TRUE;
+ return true;
}
@@ -8908,7 +8908,7 @@ SiS_SetTrumpBlockLoop(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
return NULL;
}
-static BOOLEAN
+static bool
SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
{
SiS_Pr->SiS_DDC_DeviceAddr = 0xF0; /* DAB (Device Address Byte) */
@@ -8921,14 +8921,14 @@ SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
while(*dataptr) {
dataptr = SiS_SetTrumpBlockLoop(SiS_Pr, dataptr);
- if(!dataptr) return FALSE;
+ if(!dataptr) return false;
}
#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
xf86DrvMsg(0, X_INFO, "Trumpion block success\n");
#endif
#endif
- return TRUE;
+ return true;
}
#endif
@@ -8939,7 +8939,7 @@ SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr)
* 0x0a, possibly for working around the DDC problems
*/
-static BOOLEAN
+static bool
SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val, unsigned short myor)
{
unsigned short temp, i;
@@ -8958,9 +8958,9 @@ SiS_SetChReg(struct SiS_Private *SiS_Pr, unsigned short reg, unsigned char val,
if(temp) continue; /* (ERROR: no ack) */
if(SiS_SetStop(SiS_Pr)) continue; /* Set stop condition */
SiS_Pr->SiS_ChrontelInit = 1;
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
/* Write to Chrontel 700x */
@@ -9119,7 +9119,7 @@ static
#endif
unsigned short
SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
- unsigned short adaptnum, unsigned short DDCdatatype, BOOLEAN checkcr32,
+ unsigned short adaptnum, unsigned short DDCdatatype, bool checkcr32,
unsigned int VBFlags2)
{
unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
@@ -9287,7 +9287,7 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
{
unsigned char mask, value;
unsigned short temp, ret=0;
- BOOLEAN failed = FALSE;
+ bool failed = false;
SiS_SetSwitchDDC2(SiS_Pr);
if(SiS_PrepareDDC(SiS_Pr)) {
@@ -9308,7 +9308,7 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
mask = 0xff;
value = 0xff;
} else {
- failed = TRUE;
+ failed = true;
ret = 0xFFFF;
#ifdef SIS_XORG_XF86
#ifdef TWDEBUG
@@ -9317,7 +9317,7 @@ SiS_DoProbeDDC(struct SiS_Private *SiS_Pr)
#endif
}
}
- if(failed == FALSE) {
+ if(!failed) {
temp = (unsigned char)SiS_ReadDDC2Data(SiS_Pr);
SiS_SendACK(SiS_Pr, 1);
temp &= mask;
@@ -9431,7 +9431,7 @@ SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, int VGAEngine,
if((!(VBFlags2 & VB2_VIDEOBRIDGE)) && (adaptnum > 0))
return 0xFFFF;
- if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, FALSE, VBFlags2) == 0xFFFF)
+ if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, false, VBFlags2) == 0xFFFF)
return 0xFFFF;
sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
@@ -9829,7 +9829,7 @@ SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
{
unsigned char *ROMAddr = SiS_Pr->VirtualRomBase;
unsigned short delay=0,index,myindex,temp,romptr=0;
- BOOLEAN dochiptest = TRUE;
+ bool dochiptest = true;
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x20,0xbf);
@@ -9864,7 +9864,7 @@ SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
} else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) { /* ---------- LCD/LCDA */
- BOOLEAN gotitfrompci = FALSE;
+ bool gotitfrompci = false;
/* Could we detect a PDC for LCD or did we get a user-defined? If yes, use it */
@@ -9916,22 +9916,22 @@ SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
case CUT_COMPAQ1280:
case CUT_COMPAQ12802:
if(SiS_Pr->SiS_LCDResInfo == Panel_1280x1024) {
- gotitfrompci = TRUE;
- dochiptest = FALSE;
+ gotitfrompci = true;
+ dochiptest = false;
delay = 0x03;
}
break;
case CUT_CLEVO1400:
case CUT_CLEVO14002:
- gotitfrompci = TRUE;
- dochiptest = FALSE;
+ gotitfrompci = true;
+ dochiptest = false;
delay = 0x02;
break;
case CUT_CLEVO1024:
case CUT_CLEVO10242:
if(SiS_Pr->SiS_LCDResInfo == Panel_1024x768) {
- gotitfrompci = TRUE;
- dochiptest = FALSE;
+ gotitfrompci = true;
+ dochiptest = false;
delay = 0x33;
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
delay &= 0x0f;
@@ -10009,7 +10009,7 @@ SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
- dochiptest = FALSE;
+ dochiptest = false;
}
} else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) { /* ------------ TV */
@@ -10043,12 +10043,12 @@ SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
case CUT_CLEVO1400:
case CUT_CLEVO14002:
delay = 0x02;
- dochiptest = FALSE;
+ dochiptest = false;
break;
case CUT_CLEVO1024:
case CUT_CLEVO10242:
delay = 0x03;
- dochiptest = FALSE;
+ dochiptest = false;
break;
default:
delay = SiS310_TVDelayCompensation_651301LV[index];
@@ -10085,7 +10085,7 @@ SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
if(SiS_LCDAEnabled(SiS_Pr)) {
delay &= 0x0f;
- dochiptest = FALSE;
+ dochiptest = false;
}
} else return;
@@ -10728,7 +10728,7 @@ SiS_FinalizeLCD(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned shor
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
}
- if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
+ if(SiS_Pr->Backup && (SiS_Pr->Backup_Mode == ModeNo)) {
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index 4f3a28699d37..7708e1e1d99e 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -363,8 +363,8 @@ void SiS_LockCRT2(struct SiS_Private *SiS_Pr);
void SiS_EnableCRT2(struct SiS_Private *SiS_Pr);
unsigned short SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
void SiS_WaitRetrace1(struct SiS_Private *SiS_Pr);
-BOOLEAN SiS_IsDualEdge(struct SiS_Private *SiS_Pr);
-BOOLEAN SiS_IsVAMode(struct SiS_Private *SiS_Pr);
+bool SiS_IsDualEdge(struct SiS_Private *SiS_Pr);
+bool SiS_IsVAMode(struct SiS_Private *SiS_Pr);
void SiS_GetVBInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex, int checkcrt2mode);
void SiS_SetYPbPr(struct SiS_Private *SiS_Pr);
@@ -379,7 +379,7 @@ void SiS_DisableBridge(struct SiS_Private *SiS_Pr);
#ifndef SIS_LINUX_KERNEL
void SiS_EnableBridge(struct SiS_Private *SiS_Pr);
#endif
-BOOLEAN SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+bool SiS_SetCRT2Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
void SiS_SiS30xBLOn(struct SiS_Private *SiS_Pr);
void SiS_SiS30xBLOff(struct SiS_Private *SiS_Pr);
@@ -403,7 +403,7 @@ void SiS_Chrontel701xBLOff(struct SiS_Private *SiS_Pr);
#endif /* 315 */
#ifdef SIS300
-static BOOLEAN SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
+static bool SiS_SetTrumpionBlock(struct SiS_Private *SiS_Pr, unsigned char *dataptr);
void SiS_SetChrontelGPIO(struct SiS_Private *SiS_Pr, unsigned short myvbinfo);
#endif
@@ -416,14 +416,14 @@ unsigned short SiS_HandleDDC(struct SiS_Private *SiS_Pr, unsigned int VBFlags, i
#ifdef SIS_XORG_XF86
unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
- BOOLEAN checkcr32, unsigned int VBFlags2);
+ bool checkcr32, unsigned int VBFlags2);
unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
unsigned char *buffer);
#else
static unsigned short SiS_InitDDCRegs(struct SiS_Private *SiS_Pr, unsigned int VBFlags,
int VGAEngine, unsigned short adaptnum, unsigned short DDCdatatype,
- BOOLEAN checkcr32, unsigned int VBFlags2);
+ bool checkcr32, unsigned int VBFlags2);
static unsigned short SiS_ProbeDDC(struct SiS_Private *SiS_Pr);
static unsigned short SiS_ReadDDC(struct SiS_Private *SiS_Pr, unsigned short DDCdatatype,
unsigned char *buffer);
@@ -469,7 +469,7 @@ extern void SiS_SetRegOR(SISIOADDRESS, unsigned short, unsigned short);
extern void SiS_SetRegAND(SISIOADDRESS, unsigned short, unsigned short);
extern void SiS_DisplayOff(struct SiS_Private *SiS_Pr);
extern void SiS_DisplayOn(struct SiS_Private *SiS_Pr);
-extern BOOLEAN SiS_SearchModeID(struct SiS_Private *, unsigned short *, unsigned short *);
+extern bool SiS_SearchModeID(struct SiS_Private *, unsigned short *, unsigned short *);
extern unsigned short SiS_GetModeFlag(struct SiS_Private *SiS_Pr, unsigned short ModeNo,
unsigned short ModeIdIndex);
extern unsigned short SiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex);
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
index c3884a29f4c5..47a33501549d 100644
--- a/drivers/video/sis/initextlfb.c
+++ b/drivers/video/sis/initextlfb.c
@@ -38,14 +38,14 @@ int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
unsigned char modeno, unsigned char rateindex);
int sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
unsigned char rateindex, struct fb_var_screeninfo *var);
-BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
+bool sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
int *htotal, int *vtotal, unsigned char rateindex);
-extern BOOLEAN SiSInitPtr(struct SiS_Private *SiS_Pr);
-extern BOOLEAN SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
+extern bool SiSInitPtr(struct SiS_Private *SiS_Pr);
+extern bool SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo,
unsigned short *ModeIdIndex);
extern void SiS_Generic_ConvertCRData(struct SiS_Private *SiS_Pr, unsigned char *crdata,
- int xres, int yres, struct fb_var_screeninfo *var, BOOLEAN writeres);
+ int xres, int yres, struct fb_var_screeninfo *var, bool writeres);
int
sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr, unsigned char modeno,
@@ -131,7 +131,7 @@ sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
(unsigned char *)&SiS_Pr->SiS_CRT1Table[index].CR[0],
SiS_Pr->SiS_RefIndex[RRTI].XRes,
SiS_Pr->SiS_RefIndex[RRTI].YRes,
- var, FALSE);
+ var, false);
if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & 0x8000)
var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
@@ -175,7 +175,7 @@ sisfb_mode_rate_to_ddata(struct SiS_Private *SiS_Pr, unsigned char modeno,
return 1;
}
-BOOLEAN
+bool
sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *htotal,
int *vtotal, unsigned char rateindex)
{
@@ -184,7 +184,7 @@ sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *ht
unsigned short RRTI = 0;
unsigned char sr_data, cr_data, cr_data2;
- if(!SiSInitPtr(SiS_Pr)) return FALSE;
+ if(!SiSInitPtr(SiS_Pr)) return false;
if(rateindex > 0) rateindex--;
@@ -195,7 +195,7 @@ sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *ht
}
#endif
- if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+ if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return false;
RRTI = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & HaveWideTiming) {
@@ -226,7 +226,7 @@ sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno, int *ht
if(SiS_Pr->SiS_RefIndex[RRTI].Ext_InfoFlag & InterlaceMode)
*vtotal *= 2;
- return TRUE;
+ return true;
}
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index a259446ca7fe..7d5ee2145e21 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -526,7 +526,7 @@ struct sis_video_info {
u16 vmax;
u32 dclockmax;
u8 feature;
- BOOLEAN datavalid;
+ bool datavalid;
} sisfb_thismonitor;
unsigned short chip_id; /* PCI ID of chip */
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index baaf495a0a6d..01197d740217 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -110,7 +110,7 @@ sisfb_setdefaultparms(void)
/* ------------- Parameter parsing -------------- */
static void __devinit
-sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
+sisfb_search_vesamode(unsigned int vesamode, bool quiet)
{
int i = 0, j = 0;
@@ -150,7 +150,7 @@ sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
}
static void __devinit
-sisfb_search_mode(char *name, BOOLEAN quiet)
+sisfb_search_mode(char *name, bool quiet)
{
unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
int i = 0;
@@ -251,7 +251,7 @@ sisfb_get_vga_mode_from_kernel(void)
"sisfb: Using vga mode %s pre-set by kernel as default\n",
mymode);
- sisfb_search_mode(mymode, TRUE);
+ sisfb_search_mode(mymode, true);
}
#endif
return;
@@ -307,7 +307,7 @@ static void __init
sisfb_search_specialtiming(const char *name)
{
int i = 0;
- BOOLEAN found = FALSE;
+ bool found = false;
/* We don't know the hardware specs yet and there is no ivideo */
@@ -322,7 +322,7 @@ sisfb_search_specialtiming(const char *name)
if(!strnicmp(name,mycustomttable[i].optionName,
strlen(mycustomttable[i].optionName))) {
sisfb_specialtiming = mycustomttable[i].SpecialID;
- found = TRUE;
+ found = true;
printk(KERN_INFO "sisfb: Special timing for %s %s forced (\"%s\")\n",
mycustomttable[i].vendorName,
mycustomttable[i].cardName,
@@ -353,7 +353,7 @@ sisfb_detect_custom_timing(struct sis_video_info *ivideo)
{
unsigned char *biosver = NULL;
unsigned char *biosdate = NULL;
- BOOLEAN footprint;
+ bool footprint;
u32 chksum = 0;
int i, j;
@@ -380,16 +380,16 @@ sisfb_detect_custom_timing(struct sis_video_info *ivideo)
(mycustomttable[i].bioschksum == chksum))) &&
(mycustomttable[i].pcisubsysvendor == ivideo->subsysvendor) &&
(mycustomttable[i].pcisubsyscard == ivideo->subsysdevice) ) {
- footprint = TRUE;
+ footprint = true;
for(j = 0; j < 5; j++) {
if(mycustomttable[i].biosFootprintAddr[j]) {
if(ivideo->SiS_Pr.UseROM) {
if(ivideo->SiS_Pr.VirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
mycustomttable[i].biosFootprintData[j]) {
- footprint = FALSE;
+ footprint = false;
}
} else
- footprint = FALSE;
+ footprint = false;
}
}
if(footprint) {
@@ -406,7 +406,7 @@ sisfb_detect_custom_timing(struct sis_video_info *ivideo)
} while(mycustomttable[i].chipID);
}
-static BOOLEAN __devinit
+static bool __devinit
sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
{
int i, j, xres, yres, refresh, index;
@@ -417,13 +417,13 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
buffer[4] != 0xff || buffer[5] != 0xff ||
buffer[6] != 0xff || buffer[7] != 0x00) {
printk(KERN_DEBUG "sisfb: Bad EDID header\n");
- return FALSE;
+ return false;
}
if(buffer[0x12] != 0x01) {
printk(KERN_INFO "sisfb: EDID version %d not supported\n",
buffer[0x12]);
- return FALSE;
+ return false;
}
monitor->feature = buffer[0x18];
@@ -449,7 +449,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
monitor->vmin = buffer[j + 5];
monitor->vmax = buffer[j + 6];
monitor->dclockmax = buffer[j + 9] * 10 * 1000;
- monitor->datavalid = TRUE;
+ monitor->datavalid = true;
break;
}
j += 18;
@@ -501,7 +501,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
index += 2;
}
if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
- monitor->datavalid = TRUE;
+ monitor->datavalid = true;
}
}
@@ -514,7 +514,7 @@ sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, i
unsigned short temp, i, realcrtno = crtno;
unsigned char buffer[256];
- monitor->datavalid = FALSE;
+ monitor->datavalid = false;
if(crtno) {
if(ivideo->vbflags & CRT2_LCD) realcrtno = 1;
@@ -563,7 +563,7 @@ sisfb_handle_ddc(struct sis_video_info *ivideo, struct sisfb_monitor *monitor, i
/* -------------- Mode validation --------------- */
-static BOOLEAN
+static bool
sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
int mode_idx, int rate_idx, int rate)
{
@@ -571,10 +571,10 @@ sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
unsigned int dclock, hsync;
if(!monitor->datavalid)
- return TRUE;
+ return true;
if(mode_idx < 0)
- return FALSE;
+ return false;
/* Skip for 320x200, 320x240, 640x400 */
switch(sisbios_mode[mode_idx].mode_no[ivideo->mni]) {
@@ -587,34 +587,34 @@ sisfb_verify_rate(struct sis_video_info *ivideo, struct sisfb_monitor *monitor,
case 0x2f:
case 0x5d:
case 0x5e:
- return TRUE;
+ return true;
#ifdef CONFIG_FB_SIS_315
case 0x5a:
case 0x5b:
- if(ivideo->sisvga_engine == SIS_315_VGA) return TRUE;
+ if(ivideo->sisvga_engine == SIS_315_VGA) return true;
#endif
}
if(rate < (monitor->vmin - 1))
- return FALSE;
+ return false;
if(rate > (monitor->vmax + 1))
- return FALSE;
+ return false;
if(sisfb_gettotalfrommode(&ivideo->SiS_Pr,
sisbios_mode[mode_idx].mode_no[ivideo->mni],
&htotal, &vtotal, rate_idx)) {
dclock = (htotal * vtotal * rate) / 1000;
if(dclock > (monitor->dclockmax + 1000))
- return FALSE;
+ return false;
hsync = dclock / htotal;
if(hsync < (monitor->hmin - 1))
- return FALSE;
+ return false;
if(hsync > (monitor->hmax + 1))
- return FALSE;
+ return false;
} else {
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static int
@@ -732,49 +732,49 @@ sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate, int
}
}
-static BOOLEAN
+static bool
sisfb_bridgeisslave(struct sis_video_info *ivideo)
{
unsigned char P1_00;
if(!(ivideo->vbflags2 & VB2_VIDEOBRIDGE))
- return FALSE;
+ return false;
inSISIDXREG(SISPART1,0x00,P1_00);
if( ((ivideo->sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
((ivideo->sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
- return TRUE;
+ return true;
} else {
- return FALSE;
+ return false;
}
}
-static BOOLEAN
+static bool
sisfballowretracecrt1(struct sis_video_info *ivideo)
{
u8 temp;
inSISIDXREG(SISCR,0x17,temp);
if(!(temp & 0x80))
- return FALSE;
+ return false;
inSISIDXREG(SISSR,0x1f,temp);
if(temp & 0xc0)
- return FALSE;
+ return false;
- return TRUE;
+ return true;
}
-static BOOLEAN
+static bool
sisfbcheckvretracecrt1(struct sis_video_info *ivideo)
{
if(!sisfballowretracecrt1(ivideo))
- return FALSE;
+ return false;
if(inSISREG(SISINPSTAT) & 0x08)
- return TRUE;
+ return true;
else
- return FALSE;
+ return false;
}
static void
@@ -791,7 +791,7 @@ sisfbwaitretracecrt1(struct sis_video_info *ivideo)
while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
}
-static BOOLEAN
+static bool
sisfbcheckvretracecrt2(struct sis_video_info *ivideo)
{
unsigned char temp, reg;
@@ -799,17 +799,17 @@ sisfbcheckvretracecrt2(struct sis_video_info *ivideo)
switch(ivideo->sisvga_engine) {
case SIS_300_VGA: reg = 0x25; break;
case SIS_315_VGA: reg = 0x30; break;
- default: return FALSE;
+ default: return false;
}
inSISIDXREG(SISPART1, reg, temp);
if(temp & 0x02)
- return TRUE;
+ return true;
else
- return FALSE;
+ return false;
}
-static BOOLEAN
+static bool
sisfb_CheckVBRetrace(struct sis_video_info *ivideo)
{
if(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
@@ -874,7 +874,7 @@ static int
sisfb_myblank(struct sis_video_info *ivideo, int blank)
{
u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
- BOOLEAN backlight = TRUE;
+ bool backlight = true;
switch(blank) {
case FB_BLANK_UNBLANK: /* on */
@@ -884,7 +884,7 @@ sisfb_myblank(struct sis_video_info *ivideo, int blank)
cr63 = 0x00;
p2_0 = 0x20;
p1_13 = 0x00;
- backlight = TRUE;
+ backlight = true;
break;
case FB_BLANK_NORMAL: /* blank */
sr01 = 0x20;
@@ -893,7 +893,7 @@ sisfb_myblank(struct sis_video_info *ivideo, int blank)
cr63 = 0x00;
p2_0 = 0x20;
p1_13 = 0x00;
- backlight = TRUE;
+ backlight = true;
break;
case FB_BLANK_VSYNC_SUSPEND: /* no vsync */
sr01 = 0x20;
@@ -902,7 +902,7 @@ sisfb_myblank(struct sis_video_info *ivideo, int blank)
cr63 = 0x40;
p2_0 = 0x40;
p1_13 = 0x80;
- backlight = FALSE;
+ backlight = false;
break;
case FB_BLANK_HSYNC_SUSPEND: /* no hsync */
sr01 = 0x20;
@@ -911,7 +911,7 @@ sisfb_myblank(struct sis_video_info *ivideo, int blank)
cr63 = 0x40;
p2_0 = 0x80;
p1_13 = 0x40;
- backlight = FALSE;
+ backlight = false;
break;
case FB_BLANK_POWERDOWN: /* off */
sr01 = 0x20;
@@ -920,7 +920,7 @@ sisfb_myblank(struct sis_video_info *ivideo, int blank)
cr63 = 0x40;
p2_0 = 0xc0;
p1_13 = 0xc0;
- backlight = FALSE;
+ backlight = false;
break;
default:
return 1;
@@ -1109,11 +1109,11 @@ sisfb_calc_pitch(struct sis_video_info *ivideo, struct fb_var_screeninfo *var)
static void
sisfb_set_pitch(struct sis_video_info *ivideo)
{
- BOOLEAN isslavemode = FALSE;
+ bool isslavemode = false;
unsigned short HDisplay1 = ivideo->scrnpitchCRT1 >> 3;
unsigned short HDisplay2 = ivideo->video_linelength >> 3;
- if(sisfb_bridgeisslave(ivideo)) isslavemode = TRUE;
+ if(sisfb_bridgeisslave(ivideo)) isslavemode = true;
/* We need to set pitch for CRT1 if bridge is in slave mode, too */
if((ivideo->currentvbflags & VB_DISPTYPE_DISP1) || (isslavemode)) {
@@ -1178,7 +1178,7 @@ sisfb_set_mode(struct sis_video_info *ivideo, int clrscrn)
sisfb_pre_setmode(ivideo);
- if(SiSSetMode(&ivideo->SiS_Pr, modeno) == 0) {
+ if(!SiSSetMode(&ivideo->SiS_Pr, modeno)) {
printk(KERN_ERR "sisfb: Setting mode[0x%x] failed\n", ivideo->mode_no);
return -EINVAL;
}
@@ -1446,7 +1446,7 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
unsigned int drate = 0, hrate = 0, maxyres;
int found_mode = 0;
int refresh_rate, search_idx, tidx;
- BOOLEAN recalc_clock = FALSE;
+ bool recalc_clock = false;
u32 pixclock;
htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
@@ -1524,7 +1524,7 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
(var->bits_per_pixel == 8) ) {
/* Slave modes on LVDS and 301B-DH */
refresh_rate = 60;
- recalc_clock = TRUE;
+ recalc_clock = true;
} else if( (ivideo->current_htotal == htotal) &&
(ivideo->current_vtotal == vtotal) &&
(ivideo->current_pixclock == pixclock) ) {
@@ -1545,17 +1545,17 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
} else {
refresh_rate = 60;
}
- recalc_clock = TRUE;
+ recalc_clock = true;
} else if((pixclock) && (htotal) && (vtotal)) {
drate = 1000000000 / pixclock;
hrate = (drate * 1000) / htotal;
refresh_rate = (unsigned int) (hrate * 2 / vtotal);
} else if(ivideo->current_refresh_rate) {
refresh_rate = ivideo->current_refresh_rate;
- recalc_clock = TRUE;
+ recalc_clock = true;
} else {
refresh_rate = 60;
- recalc_clock = TRUE;
+ recalc_clock = true;
}
myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx);
@@ -2181,7 +2181,7 @@ sisfb_detect_VB_connect(struct sis_video_info *ivideo)
/* ------------------ Sensing routines ------------------ */
-static BOOLEAN __devinit
+static bool __devinit
sisfb_test_DDC1(struct sis_video_info *ivideo)
{
unsigned short old;
@@ -2191,13 +2191,13 @@ sisfb_test_DDC1(struct sis_video_info *ivideo)
do {
if(old != SiS_ReadDDC1Bit(&ivideo->SiS_Pr)) break;
} while(count--);
- return (count == -1) ? FALSE : TRUE;
+ return (count != -1);
}
static void __devinit
sisfb_sense_crt1(struct sis_video_info *ivideo)
{
- BOOLEAN mustwait = FALSE;
+ bool mustwait = false;
u8 sr1F, cr17;
#ifdef CONFIG_FB_SIS_315
u8 cr63=0;
@@ -2208,7 +2208,7 @@ sisfb_sense_crt1(struct sis_video_info *ivideo)
inSISIDXREG(SISSR,0x1F,sr1F);
orSISIDXREG(SISSR,0x1F,0x04);
andSISIDXREG(SISSR,0x1F,0x3F);
- if(sr1F & 0xc0) mustwait = TRUE;
+ if(sr1F & 0xc0) mustwait = true;
#ifdef CONFIG_FB_SIS_315
if(ivideo->sisvga_engine == SIS_315_VGA) {
@@ -2222,7 +2222,7 @@ sisfb_sense_crt1(struct sis_video_info *ivideo)
cr17 &= 0x80;
if(!cr17) {
orSISIDXREG(SISCR,0x17,0x80);
- mustwait = TRUE;
+ mustwait = true;
outSISIDXREG(SISSR, 0x00, 0x01);
outSISIDXREG(SISSR, 0x00, 0x03);
}
@@ -2284,7 +2284,7 @@ SiS_SenseLCD(struct sis_video_info *ivideo)
u8 reg, cr37 = 0, paneltype = 0;
u16 xres, yres;
- ivideo->SiS_Pr.PanelSelfDetected = FALSE;
+ ivideo->SiS_Pr.PanelSelfDetected = false;
/* LCD detection only for TMDS bridges */
if(!(ivideo->vbflags2 & VB2_SISTMDSBRIDGE))
@@ -2361,7 +2361,7 @@ SiS_SenseLCD(struct sis_video_info *ivideo)
setSISIDXREG(SISCR, 0x37, 0x0c, cr37);
orSISIDXREG(SISCR, 0x32, 0x08);
- ivideo->SiS_Pr.PanelSelfDetected = TRUE;
+ ivideo->SiS_Pr.PanelSelfDetected = true;
}
static int __devinit
@@ -3016,7 +3016,7 @@ sisfb_save_pdc_emi(struct sis_video_info *ivideo)
int tmp;
inSISIDXREG(SISPART1,0x13,tmp);
if(tmp & 0x04) {
- ivideo->SiS_Pr.SiS_UseLCDA = TRUE;
+ ivideo->SiS_Pr.SiS_UseLCDA = true;
ivideo->detectedlcda = 0x03;
}
}
@@ -3071,9 +3071,9 @@ sisfb_save_pdc_emi(struct sis_video_info *ivideo)
inSISIDXREG(SISPART4,0x31,ivideo->SiS_Pr.EMI_31);
inSISIDXREG(SISPART4,0x32,ivideo->SiS_Pr.EMI_32);
inSISIDXREG(SISPART4,0x33,ivideo->SiS_Pr.EMI_33);
- ivideo->SiS_Pr.HaveEMI = TRUE;
+ ivideo->SiS_Pr.HaveEMI = true;
if((tmp & 0x20) || (ivideo->detectedlcda != 0xff)) {
- ivideo->SiS_Pr.HaveEMILCD = TRUE;
+ ivideo->SiS_Pr.HaveEMILCD = true;
}
}
}
@@ -3558,8 +3558,8 @@ sisfb_pre_setmode(struct sis_video_info *ivideo)
}
#endif
- SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
- SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+ SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
+ SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
ivideo->curFSTN = ivideo->curDSTN = 0;
switch(ivideo->currentvbflags & VB_DISPTYPE_DISP2) {
@@ -3814,8 +3814,8 @@ sisfb_set_TVyposoffset(struct sis_video_info *ivideo, int val)
static void
sisfb_post_setmode(struct sis_video_info *ivideo)
{
- BOOLEAN crt1isoff = FALSE;
- BOOLEAN doit = TRUE;
+ bool crt1isoff = false;
+ bool doit = true;
#if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
u8 reg;
#endif
@@ -3834,17 +3834,17 @@ sisfb_post_setmode(struct sis_video_info *ivideo)
/* We can't switch off CRT1 if bridge is in slave mode */
if(ivideo->vbflags2 & VB2_VIDEOBRIDGE) {
- if(sisfb_bridgeisslave(ivideo)) doit = FALSE;
+ if(sisfb_bridgeisslave(ivideo)) doit = false;
} else
ivideo->sisfb_crt1off = 0;
#ifdef CONFIG_FB_SIS_300
if(ivideo->sisvga_engine == SIS_300_VGA) {
if((ivideo->sisfb_crt1off) && (doit)) {
- crt1isoff = TRUE;
+ crt1isoff = true;
reg = 0x00;
} else {
- crt1isoff = FALSE;
+ crt1isoff = false;
reg = 0x80;
}
setSISIDXREG(SISCR, 0x17, 0x7f, reg);
@@ -3853,11 +3853,11 @@ sisfb_post_setmode(struct sis_video_info *ivideo)
#ifdef CONFIG_FB_SIS_315
if(ivideo->sisvga_engine == SIS_315_VGA) {
if((ivideo->sisfb_crt1off) && (doit)) {
- crt1isoff = TRUE;
+ crt1isoff = true;
reg = 0x40;
reg1 = 0xc0;
} else {
- crt1isoff = FALSE;
+ crt1isoff = false;
reg = 0x00;
reg1 = 0x00;
}
@@ -4004,9 +4004,9 @@ sisfb_setup(char *options)
} else if(!strnicmp(this_opt, "tvstandard:",11)) {
sisfb_search_tvstd(this_opt + 11);
} else if(!strnicmp(this_opt, "mode:", 5)) {
- sisfb_search_mode(this_opt + 5, FALSE);
+ sisfb_search_mode(this_opt + 5, false);
} else if(!strnicmp(this_opt, "vesa:", 5)) {
- sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
+ sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), false);
} else if(!strnicmp(this_opt, "rate:", 5)) {
sisfb_parm_rate = simple_strtoul(this_opt + 5, NULL, 0);
} else if(!strnicmp(this_opt, "forcecrt1:", 10)) {
@@ -4062,7 +4062,7 @@ sisfb_setup(char *options)
sisfb_lvdshl = temp;
}
} else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
- sisfb_search_mode(this_opt, TRUE);
+ sisfb_search_mode(this_opt, true);
#if !defined(__i386__) && !defined(__x86_64__)
} else if(!strnicmp(this_opt, "resetcard", 9)) {
sisfb_resetcard = 1;
@@ -4564,9 +4564,9 @@ sisfb_post_sis300(struct pci_dev *pdev)
sisfb_sense_crt1(ivideo);
/* Set default mode, don't clear screen */
- ivideo->SiS_Pr.SiS_UseOEM = FALSE;
- SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
- SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+ ivideo->SiS_Pr.SiS_UseOEM = false;
+ SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
+ SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
ivideo->curFSTN = ivideo->curDSTN = 0;
ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
@@ -5680,9 +5680,9 @@ sisfb_post_xgi(struct pci_dev *pdev)
} else {
/* Set default mode, don't clear screen */
- ivideo->SiS_Pr.SiS_UseOEM = FALSE;
- SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
- SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+ ivideo->SiS_Pr.SiS_UseOEM = false;
+ SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
+ SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
ivideo->curFSTN = ivideo->curDSTN = 0;
ivideo->SiS_Pr.VideoMemorySize = 8 << 20;
SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
@@ -5723,9 +5723,9 @@ sisfb_post_xgi(struct pci_dev *pdev)
}
/* Set default mode, don't clear screen */
- ivideo->SiS_Pr.SiS_UseOEM = FALSE;
- SiS_SetEnableDstn(&ivideo->SiS_Pr, FALSE);
- SiS_SetEnableFstn(&ivideo->SiS_Pr, FALSE);
+ ivideo->SiS_Pr.SiS_UseOEM = false;
+ SiS_SetEnableDstn(&ivideo->SiS_Pr, false);
+ SiS_SetEnableFstn(&ivideo->SiS_Pr, false);
ivideo->curFSTN = ivideo->curDSTN = 0;
SiSSetMode(&ivideo->SiS_Pr, 0x2e | 0x80);
@@ -5819,7 +5819,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ivideo->detectedpdca = 0xff;
ivideo->detectedlcda = 0xff;
- ivideo->sisfb_thismonitor.datavalid = FALSE;
+ ivideo->sisfb_thismonitor.datavalid = false;
ivideo->current_base = 0;
@@ -5871,21 +5871,21 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ivideo->SiS_Pr.SiS_Backup70xx = 0xff;
ivideo->SiS_Pr.SiS_CHOverScan = -1;
- ivideo->SiS_Pr.SiS_ChSW = FALSE;
- ivideo->SiS_Pr.SiS_UseLCDA = FALSE;
- ivideo->SiS_Pr.HaveEMI = FALSE;
- ivideo->SiS_Pr.HaveEMILCD = FALSE;
- ivideo->SiS_Pr.OverruleEMI = FALSE;
- ivideo->SiS_Pr.SiS_SensibleSR11 = FALSE;
+ ivideo->SiS_Pr.SiS_ChSW = false;
+ ivideo->SiS_Pr.SiS_UseLCDA = false;
+ ivideo->SiS_Pr.HaveEMI = false;
+ ivideo->SiS_Pr.HaveEMILCD = false;
+ ivideo->SiS_Pr.OverruleEMI = false;
+ ivideo->SiS_Pr.SiS_SensibleSR11 = false;
ivideo->SiS_Pr.SiS_MyCR63 = 0x63;
ivideo->SiS_Pr.PDC = -1;
ivideo->SiS_Pr.PDCA = -1;
- ivideo->SiS_Pr.DDCPortMixup = FALSE;
+ ivideo->SiS_Pr.DDCPortMixup = false;
#ifdef CONFIG_FB_SIS_315
if(ivideo->chip >= SIS_330) {
ivideo->SiS_Pr.SiS_MyCR63 = 0x53;
if(ivideo->chip >= SIS_661) {
- ivideo->SiS_Pr.SiS_SensibleSR11 = TRUE;
+ ivideo->SiS_Pr.SiS_SensibleSR11 = true;
}
}
#endif
@@ -5969,7 +5969,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
do {
if(mychswtable[i].subsysVendor == ivideo->subsysvendor &&
mychswtable[i].subsysCard == ivideo->subsysdevice) {
- ivideo->SiS_Pr.SiS_ChSW = TRUE;
+ ivideo->SiS_Pr.SiS_ChSW = true;
printk(KERN_DEBUG "sisfb: Identified [%s %s] "
"requiring Chrontel/GPIO setup\n",
mychswtable[i].vendorName,
@@ -6018,20 +6018,20 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Search and copy ROM image */
ivideo->bios_abase = NULL;
ivideo->SiS_Pr.VirtualRomBase = NULL;
- ivideo->SiS_Pr.UseROM = FALSE;
- ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = FALSE;
+ ivideo->SiS_Pr.UseROM = false;
+ ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = false;
if(ivideo->sisfb_userom) {
ivideo->SiS_Pr.VirtualRomBase = sisfb_find_rom(pdev);
ivideo->bios_abase = ivideo->SiS_Pr.VirtualRomBase;
- ivideo->SiS_Pr.UseROM = (ivideo->SiS_Pr.VirtualRomBase) ? TRUE : FALSE;
+ ivideo->SiS_Pr.UseROM = (bool)(ivideo->SiS_Pr.VirtualRomBase);
printk(KERN_INFO "sisfb: Video ROM %sfound\n",
ivideo->SiS_Pr.UseROM ? "" : "not ");
if((ivideo->SiS_Pr.UseROM) && (ivideo->chip >= XGI_20)) {
- ivideo->SiS_Pr.UseROM = FALSE;
- ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = TRUE;
+ ivideo->SiS_Pr.UseROM = false;
+ ivideo->haveXGIROM = ivideo->SiS_Pr.SiS_XGIROM = true;
if( (ivideo->revision_id == 2) &&
(!(ivideo->bios_abase[0x1d1] & 0x01)) ) {
- ivideo->SiS_Pr.DDCPortMixup = TRUE;
+ ivideo->SiS_Pr.DDCPortMixup = true;
}
}
} else {
@@ -6677,9 +6677,9 @@ static int __init sisfb_init_module(void)
sisfb_search_tvstd(tvstandard);
if(mode)
- sisfb_search_mode(mode, FALSE);
+ sisfb_search_mode(mode, false);
else if(vesa != -1)
- sisfb_search_vesamode(vesa, FALSE);
+ sisfb_search_vesamode(vesa, false);
sisfb_crt1off = (crt1off == 0) ? 1 : 0;
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
index 88e4f1e41470..3e3b7fa05d6c 100644
--- a/drivers/video/sis/sis_main.h
+++ b/drivers/video/sis/sis_main.h
@@ -411,54 +411,54 @@ static const struct _sis_vrate {
u16 xres;
u16 yres;
u16 refresh;
- BOOLEAN SiS730valid32bpp;
+ bool SiS730valid32bpp;
} sisfb_vrate[] = {
- {1, 320, 200, 70, TRUE},
- {1, 320, 240, 60, TRUE},
- {1, 400, 300, 60, TRUE},
- {1, 512, 384, 60, TRUE},
- {1, 640, 400, 72, TRUE},
- {1, 640, 480, 60, TRUE}, {2, 640, 480, 72, TRUE}, {3, 640, 480, 75, TRUE},
- {4, 640, 480, 85, TRUE}, {5, 640, 480, 100, TRUE}, {6, 640, 480, 120, TRUE},
- {7, 640, 480, 160, TRUE}, {8, 640, 480, 200, TRUE},
- {1, 720, 480, 60, TRUE},
- {1, 720, 576, 58, TRUE},
- {1, 768, 576, 58, TRUE},
- {1, 800, 480, 60, TRUE}, {2, 800, 480, 75, TRUE}, {3, 800, 480, 85, TRUE},
- {1, 800, 600, 56, TRUE}, {2, 800, 600, 60, TRUE}, {3, 800, 600, 72, TRUE},
- {4, 800, 600, 75, TRUE}, {5, 800, 600, 85, TRUE}, {6, 800, 600, 105, TRUE},
- {7, 800, 600, 120, TRUE}, {8, 800, 600, 160, TRUE},
- {1, 848, 480, 39, TRUE}, {2, 848, 480, 60, TRUE},
- {1, 856, 480, 39, TRUE}, {2, 856, 480, 60, TRUE},
- {1, 960, 540, 60, TRUE},
- {1, 960, 600, 60, TRUE},
- {1, 1024, 576, 60, TRUE}, {2, 1024, 576, 75, TRUE}, {3, 1024, 576, 85, TRUE},
- {1, 1024, 600, 60, TRUE},
- {1, 1024, 768, 43, TRUE}, {2, 1024, 768, 60, TRUE}, {3, 1024, 768, 70, FALSE},
- {4, 1024, 768, 75, FALSE}, {5, 1024, 768, 85, TRUE}, {6, 1024, 768, 100, TRUE},
- {7, 1024, 768, 120, TRUE},
- {1, 1152, 768, 60, TRUE},
- {1, 1152, 864, 60, TRUE}, {2, 1152, 864, 75, TRUE}, {3, 1152, 864, 84, TRUE},
- {1, 1280, 720, 60, TRUE}, {2, 1280, 720, 75, TRUE}, {3, 1280, 720, 85, TRUE},
- {1, 1280, 768, 60, TRUE},
- {1, 1280, 800, 60, TRUE},
- {1, 1280, 854, 60, TRUE},
- {1, 1280, 960, 60, TRUE}, {2, 1280, 960, 85, TRUE},
- {1, 1280, 1024, 43, TRUE}, {2, 1280, 1024, 60, TRUE}, {3, 1280, 1024, 75, TRUE},
- {4, 1280, 1024, 85, TRUE},
- {1, 1360, 768, 60, TRUE},
- {1, 1360, 1024, 59, TRUE},
- {1, 1400, 1050, 60, TRUE}, {2, 1400, 1050, 75, TRUE},
- {1, 1600, 1200, 60, TRUE}, {2, 1600, 1200, 65, TRUE}, {3, 1600, 1200, 70, TRUE},
- {4, 1600, 1200, 75, TRUE}, {5, 1600, 1200, 85, TRUE}, {6, 1600, 1200, 100, TRUE},
- {7, 1600, 1200, 120, TRUE},
- {1, 1680, 1050, 60, TRUE},
- {1, 1920, 1080, 30, TRUE},
- {1, 1920, 1440, 60, TRUE}, {2, 1920, 1440, 65, TRUE}, {3, 1920, 1440, 70, TRUE},
- {4, 1920, 1440, 75, TRUE}, {5, 1920, 1440, 85, TRUE}, {6, 1920, 1440, 100, TRUE},
- {1, 2048, 1536, 60, TRUE}, {2, 2048, 1536, 65, TRUE}, {3, 2048, 1536, 70, TRUE},
- {4, 2048, 1536, 75, TRUE}, {5, 2048, 1536, 85, TRUE},
- {0, 0, 0, 0, FALSE}
+ {1, 320, 200, 70, true},
+ {1, 320, 240, 60, true},
+ {1, 400, 300, 60, true},
+ {1, 512, 384, 60, true},
+ {1, 640, 400, 72, true},
+ {1, 640, 480, 60, true}, {2, 640, 480, 72, true}, {3, 640, 480, 75, true},
+ {4, 640, 480, 85, true}, {5, 640, 480, 100, true}, {6, 640, 480, 120, true},
+ {7, 640, 480, 160, true}, {8, 640, 480, 200, true},
+ {1, 720, 480, 60, true},
+ {1, 720, 576, 58, true},
+ {1, 768, 576, 58, true},
+ {1, 800, 480, 60, true}, {2, 800, 480, 75, true}, {3, 800, 480, 85, true},
+ {1, 800, 600, 56, true}, {2, 800, 600, 60, true}, {3, 800, 600, 72, true},
+ {4, 800, 600, 75, true}, {5, 800, 600, 85, true}, {6, 800, 600, 105, true},
+ {7, 800, 600, 120, true}, {8, 800, 600, 160, true},
+ {1, 848, 480, 39, true}, {2, 848, 480, 60, true},
+ {1, 856, 480, 39, true}, {2, 856, 480, 60, true},
+ {1, 960, 540, 60, true},
+ {1, 960, 600, 60, true},
+ {1, 1024, 576, 60, true}, {2, 1024, 576, 75, true}, {3, 1024, 576, 85, true},
+ {1, 1024, 600, 60, true},
+ {1, 1024, 768, 43, true}, {2, 1024, 768, 60, true}, {3, 1024, 768, 70, false},
+ {4, 1024, 768, 75, false}, {5, 1024, 768, 85, true}, {6, 1024, 768, 100, true},
+ {7, 1024, 768, 120, true},
+ {1, 1152, 768, 60, true},
+ {1, 1152, 864, 60, true}, {2, 1152, 864, 75, true}, {3, 1152, 864, 84, true},
+ {1, 1280, 720, 60, true}, {2, 1280, 720, 75, true}, {3, 1280, 720, 85, true},
+ {1, 1280, 768, 60, true},
+ {1, 1280, 800, 60, true},
+ {1, 1280, 854, 60, true},
+ {1, 1280, 960, 60, true}, {2, 1280, 960, 85, true},
+ {1, 1280, 1024, 43, true}, {2, 1280, 1024, 60, true}, {3, 1280, 1024, 75, true},
+ {4, 1280, 1024, 85, true},
+ {1, 1360, 768, 60, true},
+ {1, 1360, 1024, 59, true},
+ {1, 1400, 1050, 60, true}, {2, 1400, 1050, 75, true},
+ {1, 1600, 1200, 60, true}, {2, 1600, 1200, 65, true}, {3, 1600, 1200, 70, true},
+ {4, 1600, 1200, 75, true}, {5, 1600, 1200, 85, true}, {6, 1600, 1200, 100, true},
+ {7, 1600, 1200, 120, true},
+ {1, 1680, 1050, 60, true},
+ {1, 1920, 1080, 30, true},
+ {1, 1920, 1440, 60, true}, {2, 1920, 1440, 65, true}, {3, 1920, 1440, 70, true},
+ {4, 1920, 1440, 75, true}, {5, 1920, 1440, 85, true}, {6, 1920, 1440, 100, true},
+ {1, 2048, 1536, 60, true}, {2, 2048, 1536, 65, true}, {3, 2048, 1536, 70, true},
+ {4, 2048, 1536, 75, true}, {5, 2048, 1536, 85, true},
+ {0, 0, 0, 0, false}
};
static struct _sisfbddcsmodes {
@@ -691,7 +691,7 @@ extern int sisfb_initaccel(struct sis_video_info *ivideo);
extern void sisfb_syncaccel(struct sis_video_info *ivideo);
/* Internal general routines */
-static void sisfb_search_mode(char *name, BOOLEAN quiet);
+static void sisfb_search_mode(char *name, bool quiet);
static int sisfb_validate_mode(struct sis_video_info *ivideo, int modeindex, u32 vbflags);
static u8 sisfb_search_refresh_rate(struct sis_video_info *ivideo, unsigned int rate,
int index);
@@ -702,10 +702,10 @@ static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
struct fb_info *info);
static void sisfb_pre_setmode(struct sis_video_info *ivideo);
static void sisfb_post_setmode(struct sis_video_info *ivideo);
-static BOOLEAN sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
-static BOOLEAN sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
-static BOOLEAN sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
-static BOOLEAN sisfb_bridgeisslave(struct sis_video_info *ivideo);
+static bool sisfb_CheckVBRetrace(struct sis_video_info *ivideo);
+static bool sisfbcheckvretracecrt2(struct sis_video_info *ivideo);
+static bool sisfbcheckvretracecrt1(struct sis_video_info *ivideo);
+static bool sisfb_bridgeisslave(struct sis_video_info *ivideo);
static void sisfb_detect_VB_connect(struct sis_video_info *ivideo);
static void sisfb_get_VB_type(struct sis_video_info *ivideo);
static void sisfb_set_TVxposoffset(struct sis_video_info *ivideo, int val);
@@ -737,20 +737,20 @@ static void sisfb_free_node(struct SIS_HEAP *memheap, struct SIS_OH *poh);
/* Routines from init.c/init301.c */
extern unsigned short SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay,
- int VDisplay, int Depth, BOOLEAN FSTN, unsigned short CustomT,
+ int VDisplay, int Depth, bool FSTN, unsigned short CustomT,
int LCDwith, int LCDheight, unsigned int VBFlags2);
extern unsigned short SiS_GetModeID_TV(int VGAEngine, unsigned int VBFlags, int HDisplay,
int VDisplay, int Depth, unsigned int VBFlags2);
extern unsigned short SiS_GetModeID_VGA2(int VGAEngine, unsigned int VBFlags, int HDisplay,
int VDisplay, int Depth, unsigned int VBFlags2);
extern void SiSRegInit(struct SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
-extern BOOLEAN SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
+extern bool SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
extern void SiS_SetEnableDstn(struct SiS_Private *SiS_Pr, int enable);
extern void SiS_SetEnableFstn(struct SiS_Private *SiS_Pr, int enable);
-extern BOOLEAN SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
+extern bool SiSDetermineROMLayout661(struct SiS_Private *SiS_Pr);
-extern BOOLEAN sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
+extern bool sisfb_gettotalfrommode(struct SiS_Private *SiS_Pr, unsigned char modeno,
int *htotal, int *vtotal, unsigned char rateindex);
extern int sisfb_mode_rate_to_dclock(struct SiS_Private *SiS_Pr,
unsigned char modeno, unsigned char rateindex);
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index 05d08b7889a1..b532fbd2b04c 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -57,18 +57,6 @@
#include <linux/version.h>
#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef BOOLEAN
-typedef unsigned int BOOLEAN;
-#endif
-
#define SISIOMEMTYPE
#ifdef SIS_LINUX_KERNEL
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/sis/vstruct.h
index 9ae32923c142..705c85360526 100644
--- a/drivers/video/sis/vstruct.h
+++ b/drivers/video/sis/vstruct.h
@@ -240,7 +240,7 @@ struct SiS_Private
void *ivideo;
#endif
unsigned char *VirtualRomBase;
- BOOLEAN UseROM;
+ bool UseROM;
#ifdef SIS_LINUX_KERNEL
unsigned char SISIOMEMTYPE *VideoMemoryAddress;
unsigned int VideoMemorySize;
@@ -283,24 +283,24 @@ struct SiS_Private
#ifdef SIS_XORG_XF86
unsigned short SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
#endif
- BOOLEAN SiS_UseROM;
- BOOLEAN SiS_ROMNew;
- BOOLEAN SiS_XGIROM;
- BOOLEAN SiS_NeedRomModeData;
- BOOLEAN PanelSelfDetected;
- BOOLEAN DDCPortMixup;
+ bool SiS_UseROM;
+ bool SiS_ROMNew;
+ bool SiS_XGIROM;
+ bool SiS_NeedRomModeData;
+ bool PanelSelfDetected;
+ bool DDCPortMixup;
int SiS_CHOverScan;
- BOOLEAN SiS_CHSOverScan;
- BOOLEAN SiS_ChSW;
- BOOLEAN SiS_UseLCDA;
+ bool SiS_CHSOverScan;
+ bool SiS_ChSW;
+ bool SiS_UseLCDA;
int SiS_UseOEM;
unsigned int SiS_CustomT;
int SiS_UseWide, SiS_UseWideCRT2;
int SiS_TVBlue;
unsigned short SiS_Backup70xx;
- BOOLEAN HaveEMI;
- BOOLEAN HaveEMILCD;
- BOOLEAN OverruleEMI;
+ bool HaveEMI;
+ bool HaveEMILCD;
+ bool OverruleEMI;
unsigned char EMI_30,EMI_31,EMI_32,EMI_33;
unsigned short SiS_EMIOffset;
unsigned short SiS_PWDOffset;
@@ -352,7 +352,7 @@ struct SiS_Private
unsigned short SiS_DDC_ReadAddr;
unsigned short SiS_DDC_SecAddr;
unsigned short SiS_ChrontelInit;
- BOOLEAN SiS_SensibleSR11;
+ bool SiS_SensibleSR11;
unsigned short SiS661LCD2TableSize;
unsigned short SiS_PanelMinLVDS;
@@ -494,10 +494,10 @@ struct SiS_Private
unsigned short PanelVRS, PanelVRE;
unsigned short PanelVCLKIdx300;
unsigned short PanelVCLKIdx315;
- BOOLEAN Alternate1600x1200;
+ bool Alternate1600x1200;
- BOOLEAN UseCustomMode;
- BOOLEAN CRT1UsesCustomMode;
+ bool UseCustomMode;
+ bool CRT1UsesCustomMode;
unsigned short CHDisplay;
unsigned short CHSyncStart;
unsigned short CHSyncEnd;
@@ -523,7 +523,7 @@ struct SiS_Private
int LVDSHL;
- BOOLEAN Backup;
+ bool Backup;
unsigned char Backup_Mode;
unsigned char Backup_14;
unsigned char Backup_15;
@@ -542,12 +542,12 @@ struct SiS_Private
int CenterScreen;
unsigned short CP_Vendor, CP_Product;
- BOOLEAN CP_HaveCustomData;
+ bool CP_HaveCustomData;
int CP_PreferredX, CP_PreferredY, CP_PreferredIndex;
int CP_MaxX, CP_MaxY, CP_MaxClock;
unsigned char CP_PrefSR2B, CP_PrefSR2C;
unsigned short CP_PrefClock;
- BOOLEAN CP_Supports64048075;
+ bool CP_Supports64048075;
int CP_HDisplay[7], CP_VDisplay[7]; /* For Custom LCD panel dimensions */
int CP_HTotal[7], CP_VTotal[7];
int CP_HSyncStart[7], CP_VSyncStart[7];
@@ -555,8 +555,8 @@ struct SiS_Private
int CP_HBlankStart[7], CP_VBlankStart[7];
int CP_HBlankEnd[7], CP_VBlankEnd[7];
int CP_Clock[7];
- BOOLEAN CP_DataValid[7];
- BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
+ bool CP_DataValid[7];
+ bool CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
};
#endif
diff --git a/drivers/video/sun3fb.c b/drivers/video/sun3fb.c
deleted file mode 100644
index f80356dfa8e8..000000000000
--- a/drivers/video/sun3fb.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
- * linux/drivers/video/sun3fb.c -- Frame buffer driver for Sun3
- *
- * (C) 1998 Thomas Bogendoerfer
- *
- * This driver is bases on sbusfb.c, which is
- *
- * Copyright (C) 1998 Jakub Jelinek
- *
- * This driver is partly based on the Open Firmware console driver
- *
- * Copyright (C) 1997 Geert Uytterhoeven
- *
- * and SPARC console subsystem
- *
- * Copyright (C) 1995 Peter Zaitcev (zaitcev@yahoo.com)
- * Copyright (C) 1995-1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1995-1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
- * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
- * Copyright (C) 1996-1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
- * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/selection.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/kd.h>
-#include <linux/vt_kern.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h> /* io_remap_page_range() */
-
-#ifdef CONFIG_SUN3
-#include <asm/oplib.h>
-#include <asm/machines.h>
-#include <asm/idprom.h>
-
-#define CGFOUR_OBMEM_ADDR 0x1f300000
-#define BWTWO_OBMEM_ADDR 0x1f000000
-#define BWTWO_OBMEM50_ADDR 0x00100000
-
-#endif
-#ifdef CONFIG_SUN3X
-#include <asm/sun3x.h>
-#endif
-#include <video/sbusfb.h>
-
-#define DEFAULT_CURSOR_BLINK_RATE (2*HZ/5)
-
-#define CURSOR_SHAPE 1
-#define CURSOR_BLINK 2
-
-#define mymemset(x,y) memset(x,0,y)
-
- /*
- * Interface used by the world
- */
-
-int sun3fb_init(void);
-void sun3fb_setup(char *options);
-
-static char fontname[40] __initdata = { 0 };
-static int curblink __initdata = 1;
-
-static int sun3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int sun3fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int sun3fb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int sun3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-static int sun3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info);
-static int sun3fb_blank(int blank, struct fb_info *info);
-static void sun3fb_cursor(struct display *p, int mode, int x, int y);
-static void sun3fb_clear_margin(struct display *p, int s);
-
- /*
- * Interface to the low level console driver
- */
-
-static int sun3fbcon_switch(int con, struct fb_info *info);
-static int sun3fbcon_updatevar(int con, struct fb_info *info);
-
- /*
- * Internal routines
- */
-
-static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info);
-
-static struct fb_ops sun3fb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = sun3fb_get_fix,
- .fb_get_var = sun3fb_get_var,
- .fb_set_var = sun3fb_set_var,
- .fb_get_cmap = sun3fb_get_cmap,
- .fb_set_cmap = sun3fb_set_cmap,
- .fb_setcolreg = sun3fb_setcolreg,
- .fb_blank = sun3fb_blank,
-};
-
-static void sun3fb_clear_margin(struct display *p, int s)
-{
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
- return;
-
- if (fb->switch_from_graph)
- (*fb->switch_from_graph)(fb);
- if (fb->fill) {
- unsigned short rects [16];
-
- rects [0] = 0;
- rects [1] = 0;
- rects [2] = fb->var.xres_virtual;
- rects [3] = fb->y_margin;
- rects [4] = 0;
- rects [5] = fb->y_margin;
- rects [6] = fb->x_margin;
- rects [7] = fb->var.yres_virtual;
- rects [8] = fb->var.xres_virtual - fb->x_margin;
- rects [9] = fb->y_margin;
- rects [10] = fb->var.xres_virtual;
- rects [11] = fb->var.yres_virtual;
- rects [12] = fb->x_margin;
- rects [13] = fb->var.yres_virtual - fb->y_margin;
- rects [14] = fb->var.xres_virtual - fb->x_margin;
- rects [15] = fb->var.yres_virtual;
- (*fb->fill)(fb, p, s, 4, rects);
- } else {
- unsigned char *fb_base = fb->info.screen_base, *q;
- int skip_bytes = fb->y_margin * fb->var.xres_virtual;
- int scr_size = fb->var.xres_virtual * fb->var.yres_virtual;
- int h, he, incr, size;
-
- he = fb->var.yres;
- if (fb->var.bits_per_pixel == 1) {
- fb_base -= (skip_bytes + fb->x_margin) / 8;
- skip_bytes /= 8;
- scr_size /= 8;
- mymemset (fb_base, skip_bytes - fb->x_margin / 8);
- mymemset (fb_base + scr_size - skip_bytes + fb->x_margin / 8, skip_bytes - fb->x_margin / 8);
- incr = fb->var.xres_virtual / 8;
- size = fb->x_margin / 8 * 2;
- for (q = fb_base + skip_bytes - fb->x_margin / 8, h = 0;
- h <= he; q += incr, h++)
- mymemset (q, size);
- } else {
- fb_base -= (skip_bytes + fb->x_margin);
- memset (fb_base, attr_bgcol(p,s), skip_bytes - fb->x_margin);
- memset (fb_base + scr_size - skip_bytes + fb->x_margin, attr_bgcol(p,s), skip_bytes - fb->x_margin);
- incr = fb->var.xres_virtual;
- size = fb->x_margin * 2;
- for (q = fb_base + skip_bytes - fb->x_margin, h = 0;
- h <= he; q += incr, h++)
- memset (q, attr_bgcol(p,s), size);
- }
- }
-}
-
-static void sun3fb_disp_setup(struct display *p)
-{
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
- if (fb->setup)
- fb->setup(p);
- sun3fb_clear_margin(p, 0);
-}
-
- /*
- * Get the Fixed Part of the Display
- */
-
-static int sun3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- memcpy(fix, &fb->fix, sizeof(struct fb_fix_screeninfo));
- return 0;
-}
-
- /*
- * Get the User Defined Part of the Display
- */
-
-static int sun3fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo));
- return 0;
-}
-
- /*
- * Set the User Defined Part of the Display
- */
-
-static int sun3fb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (var->xres > fb->var.xres || var->yres > fb->var.yres ||
- var->xres_virtual > fb->var.xres_virtual ||
- var->yres_virtual > fb->var.yres_virtual ||
- var->bits_per_pixel != fb->var.bits_per_pixel ||
- var->nonstd ||
- (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
- return -EINVAL;
- memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo));
- return 0;
-}
-
- /*
- * Hardware cursor
- */
-
-static unsigned char hw_cursor_cmap[2] = { 0, 0xff };
-
-static void
-sun3fb_cursor_timer_handler(unsigned long dev_addr)
-{
- struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)dev_addr;
-
- if (!fb->setcursor) return;
-
- if (fb->cursor.mode & CURSOR_BLINK) {
- fb->cursor.enable ^= 1;
- fb->setcursor(fb);
- }
-
- fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate;
- add_timer(&fb->cursor.timer);
-}
-
-static void sun3fb_cursor(struct display *p, int mode, int x, int y)
-{
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
- switch (mode) {
- case CM_ERASE:
- fb->cursor.mode &= ~CURSOR_BLINK;
- fb->cursor.enable = 0;
- (*fb->setcursor)(fb);
- break;
-
- case CM_MOVE:
- case CM_DRAW:
- if (fb->cursor.mode & CURSOR_SHAPE) {
- fb->cursor.size.fbx = fontwidth(p);
- fb->cursor.size.fby = fontheight(p);
- fb->cursor.chot.fbx = 0;
- fb->cursor.chot.fby = 0;
- fb->cursor.enable = 1;
- memset (fb->cursor.bits, 0, sizeof (fb->cursor.bits));
- fb->cursor.bits[0][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p)));
- fb->cursor.bits[1][fontheight(p) - 2] = (0xffffffff << (32 - fontwidth(p)));
- fb->cursor.bits[0][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p)));
- fb->cursor.bits[1][fontheight(p) - 1] = (0xffffffff << (32 - fontwidth(p)));
- (*fb->setcursormap) (fb, hw_cursor_cmap, hw_cursor_cmap, hw_cursor_cmap);
- (*fb->setcurshape) (fb);
- }
- fb->cursor.mode = CURSOR_BLINK;
- if (fontwidthlog(p))
- fb->cursor.cpos.fbx = (x << fontwidthlog(p)) + fb->x_margin;
- else
- fb->cursor.cpos.fbx = (x * fontwidth(p)) + fb->x_margin;
- if (fontheightlog(p))
- fb->cursor.cpos.fby = (y << fontheightlog(p)) + fb->y_margin;
- else
- fb->cursor.cpos.fby = (y * fontheight(p)) + fb->y_margin;
- (*fb->setcursor)(fb);
- break;
- }
-}
-
- /*
- * Get the Colormap
- */
-
-static int sun3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- if (con == info->currcon) /* current console? */
- return fb_get_cmap(cmap, kspc, sun3fb_getcolreg, info);
- else if (fb_display[con].cmap.len) /* non default colormap? */
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2);
- return 0;
-}
-
- /*
- * Set the Colormap
- */
-
-static int sun3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- int err;
-
- if (!fb_display[con].cmap.len) { /* no colormap allocated? */
- if ((err = fb_alloc_cmap(&fb_display[con].cmap, 1<<fb_display[con].var.bits_per_pixel, 0)))
- return err;
- }
- if (con == info->currcon) { /* current console? */
- err = fb_set_cmap(cmap, kspc, info);
- if (!err) {
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (fb->loadcmap)
- (*fb->loadcmap)(fb, &fb_display[con], cmap->start, cmap->len);
- }
- return err;
- } else
- fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
- return 0;
-}
-
- /*
- * Setup: parse used options
- */
-
-void __init sun3fb_setup(char *options)
-{
- char *p;
-
- for (p = options;;) {
- if (!strncmp(p, "font=", 5)) {
- int i;
-
- for (i = 0; i < sizeof(fontname) - 1; i++)
- if (p[i+5] == ' ' || !p[i+5])
- break;
- memcpy(fontname, p+5, i);
- fontname[i] = 0;
- } else if (!strncmp(p, "noblink", 7))
- curblink = 0;
- while (*p && *p != ' ' && *p != ',') p++;
- if (*p != ',') break;
- p++;
- }
-
- return;
-}
-
-static int sun3fbcon_switch(int con, struct fb_info *info)
-{
- int x_margin, y_margin;
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
- int lastconsole;
-
- /* Do we have to save the colormap? */
- if (fb_display[info->currcon].cmap.len)
- fb_get_cmap(&fb_display[info->currcon].cmap, 1, sun3fb_getcolreg, info);
-
- if (info->display_fg) {
- lastconsole = info->display_fg->vc_num;
- if (lastconsole != con &&
- (fontwidth(&fb_display[lastconsole]) != fontwidth(&fb_display[con]) ||
- fontheight(&fb_display[lastconsole]) != fontheight(&fb_display[con])))
- fb->cursor.mode |= CURSOR_SHAPE;
- }
- x_margin = (fb_display[con].var.xres_virtual - fb_display[con].var.xres) / 2;
- y_margin = (fb_display[con].var.yres_virtual - fb_display[con].var.yres) / 2;
- if (fb->margins)
- fb->margins(fb, &fb_display[con], x_margin, y_margin);
- if (fb->graphmode || fb->x_margin != x_margin || fb->y_margin != y_margin) {
- fb->x_margin = x_margin; fb->y_margin = y_margin;
- sun3fb_clear_margin(&fb_display[con], 0);
- }
- info->currcon = con;
- /* Install new colormap */
- do_install_cmap(con, info);
- return 0;
-}
-
- /*
- * Update the `var' structure (called by fbcon.c)
- */
-
-static int sun3fbcon_updatevar(int con, struct fb_info *info)
-{
- /* Nothing */
- return 0;
-}
-
- /*
- * Blank the display.
- */
-
-static int sun3fb_blank(int blank, struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (blank && fb->blank)
- return fb->blank(fb);
- else if (!blank && fb->unblank)
- return fb->unblank(fb);
- return 0;
-}
-
- /*
- * Read a single color register and split it into
- * colors/transparent. Return != 0 for invalid regno.
- */
-
-static int sun3fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (!fb->color_map || regno > 255)
- return 1;
- *red = (fb->color_map CM(regno, 0)<<8) | fb->color_map CM(regno, 0);
- *green = (fb->color_map CM(regno, 1)<<8) | fb->color_map CM(regno, 1);
- *blue = (fb->color_map CM(regno, 2)<<8) | fb->color_map CM(regno, 2);
- *transp = 0;
- return 0;
-}
-
-
- /*
- * Set a single color register. The values supplied are already
- * rounded down to the hardware's capabilities (according to the
- * entries in the var structure). Return != 0 for invalid regno.
- */
-
-static int sun3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
-{
- struct fb_info_sbusfb *fb = sbusfbinfo(info);
-
- if (!fb->color_map || regno > 255)
- return 1;
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- fb->color_map CM(regno, 0) = red;
- fb->color_map CM(regno, 1) = green;
- fb->color_map CM(regno, 2) = blue;
- return 0;
-}
-
-static int sun3fb_set_font(struct display *p, int width, int height)
-{
- int w = p->var.xres_virtual, h = p->var.yres_virtual;
- int depth = p->var.bits_per_pixel;
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
- int x_margin, y_margin;
-
- if (depth > 8) depth = 8;
- x_margin = (w % width) / 2;
- y_margin = (h % height) / 2;
-
- p->var.xres = w - 2*x_margin;
- p->var.yres = h - 2*y_margin;
-
- fb->cursor.mode |= CURSOR_SHAPE;
-
- if (fb->margins)
- fb->margins(fb, p, x_margin, y_margin);
- if (fb->x_margin != x_margin || fb->y_margin != y_margin) {
- fb->x_margin = x_margin; fb->y_margin = y_margin;
- sun3fb_clear_margin(p, 0);
- }
-
- return 1;
-}
-
-void sun3fb_palette(int enter)
-{
- int i;
- struct display *p;
-
- for (i = 0; i < MAX_NR_CONSOLES; i++) {
- p = &fb_display[i];
- if (p->dispsw && p->dispsw->setup == sun3fb_disp_setup &&
- p->fb_info->display_fg &&
- p->fb_info->display_fg->vc_num == i) {
- struct fb_info_sbusfb *fb = sbusfbinfod(p);
-
- if (fb->restore_palette) {
- if (enter)
- fb->restore_palette(fb);
- else if (vc_cons[i].d->vc_mode != KD_GRAPHICS)
- vc_cons[i].d->vc_sw->con_set_palette(vc_cons[i].d, color_table);
- }
- }
- }
-}
-
- /*
- * Initialisation
- */
-static int __init sun3fb_init_fb(int fbtype, unsigned long addr)
-{
- static struct sbus_dev sdb;
- struct fb_fix_screeninfo *fix;
- struct fb_var_screeninfo *var;
- struct display *disp;
- struct fb_info_sbusfb *fb;
- struct fbtype *type;
- int linebytes, w, h, depth;
- char *p = NULL;
-
- fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC);
- if (!fb)
- return -ENOMEM;
-
- memset(fb, 0, sizeof(struct fb_info_sbusfb));
- fix = &fb->fix;
- var = &fb->var;
- disp = &fb->disp;
- type = &fb->type;
-
- sdb.reg_addrs[0].phys_addr = addr;
- fb->sbdp = &sdb;
-
- type->fb_type = fbtype;
-
- type->fb_height = h = 900;
- type->fb_width = w = 1152;
-sizechange:
- type->fb_depth = depth = (fbtype == FBTYPE_SUN2BW) ? 1 : 8;
- linebytes = w * depth / 8;
- type->fb_size = PAGE_ALIGN((linebytes) * h);
-/*
- fb->x_margin = (w & 7) / 2;
- fb->y_margin = (h & 15) / 2;
-*/
- fb->x_margin = fb->y_margin = 0;
-
- var->xres_virtual = w;
- var->yres_virtual = h;
- var->xres = w - 2*fb->x_margin;
- var->yres = h - 2*fb->y_margin;
-
- var->bits_per_pixel = depth;
- var->height = var->width = -1;
- var->pixclock = 10000;
- var->vmode = FB_VMODE_NONINTERLACED;
- var->red.length = var->green.length = var->blue.length = 8;
-
- fix->line_length = linebytes;
- fix->smem_len = type->fb_size;
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
-
- fb->info.fbops = &sun3fb_ops;
- fb->info.disp = disp;
- fb->info.currcon = -1;
- strcpy(fb->info.fontname, fontname);
- fb->info.changevar = NULL;
- fb->info.switch_con = &sun3fbcon_switch;
- fb->info.updatevar = &sun3fbcon_updatevar;
- fb->info.flags = FBINFO_FLAG_DEFAULT;
-
- fb->cursor.hwsize.fbx = 32;
- fb->cursor.hwsize.fby = 32;
-
- if (depth > 1 && !fb->color_map) {
- if((fb->color_map = kmalloc(256 * 3, GFP_ATOMIC))==NULL)
- return -ENOMEM;
- }
-
- switch(fbtype) {
-#ifdef CONFIG_FB_CGSIX
- case FBTYPE_SUNFAST_COLOR:
- p = cgsixfb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_BWTWO
- case FBTYPE_SUN2BW:
- p = bwtwofb_init(fb); break;
-#endif
-#ifdef CONFIG_FB_CGTHREE
- case FBTYPE_SUN4COLOR:
- case FBTYPE_SUN3COLOR:
- type->fb_size = 0x100000;
- p = cgthreefb_init(fb); break;
-#endif
- }
- fix->smem_start = (unsigned long)fb->info.screen_base; // FIXME
-
- if (!p) {
- kfree(fb);
- return -ENODEV;
- }
-
- if (p == SBUSFBINIT_SIZECHANGE)
- goto sizechange;
-
- disp->dispsw = &fb->dispsw;
- if (fb->setcursor) {
- fb->dispsw.cursor = sun3fb_cursor;
- if (curblink) {
- fb->cursor.blink_rate = DEFAULT_CURSOR_BLINK_RATE;
- init_timer(&fb->cursor.timer);
- fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate;
- fb->cursor.timer.data = (unsigned long)fb;
- fb->cursor.timer.function = sun3fb_cursor_timer_handler;
- add_timer(&fb->cursor.timer);
- }
- }
- fb->cursor.mode = CURSOR_SHAPE;
- fb->dispsw.set_font = sun3fb_set_font;
- fb->setup = fb->dispsw.setup;
- fb->dispsw.setup = sun3fb_disp_setup;
- fb->dispsw.clear_margins = NULL;
-
- disp->var = *var;
- disp->visual = fix->visual;
- disp->type = fix->type;
- disp->type_aux = fix->type_aux;
- disp->line_length = fix->line_length;
-
- if (fb->blank)
- disp->can_soft_blank = 1;
-
- sun3fb_set_var(var, -1, &fb->info);
-
- if (register_framebuffer(&fb->info) < 0) {
- kfree(fb);
- return -EINVAL;
- }
- printk("fb%d: %s\n", fb->info.node, p);
-
- return 0;
-}
-
-
-int __init sun3fb_init(void)
-{
- extern int con_is_present(void);
- unsigned long addr;
- char p4id;
-
- if (!con_is_present()) return -ENODEV;
-#ifdef CONFIG_SUN3
- switch(*(romvec->pv_fbtype))
- {
- case FBTYPE_SUN2BW:
- addr = 0xfe20000;
- return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
- case FBTYPE_SUN3COLOR:
- case FBTYPE_SUN4COLOR:
- if(idprom->id_machtype != (SM_SUN3|SM_3_60)) {
- printk("sun3fb: cgthree/four only supported on 3/60\n");
- return -ENODEV;
- }
-
- addr = CGFOUR_OBMEM_ADDR;
- return sun3fb_init_fb(*(romvec->pv_fbtype), addr);
- default:
- printk("sun3fb: unsupported framebuffer\n");
- return -ENODEV;
- }
-#else
- addr = SUN3X_VIDEO_BASE;
- p4id = *(char *)SUN3X_VIDEO_P4ID;
-
- p4id = (p4id == 0x45) ? p4id : (p4id & 0xf0);
- switch (p4id) {
- case 0x00:
- return sun3fb_init_fb(FBTYPE_SUN2BW, addr);
-#if 0 /* not yet */
- case 0x40:
- return sun3fb_init_fb(FBTYPE_SUN4COLOR, addr);
- break;
- case 0x45:
- return sun3fb_init_fb(FBTYPE_SUN8COLOR, addr);
- break;
-#endif
- case 0x60:
- return sun3fb_init_fb(FBTYPE_SUNFAST_COLOR, addr);
- }
-#endif
-
- return -ENODEV;
-}
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
new file mode 100644
index 000000000000..68b30d9eac58
--- /dev/null
+++ b/drivers/video/svgalib.c
@@ -0,0 +1,632 @@
+/*
+ * Common utility functions for VGA-based graphics cards.
+ *
+ * Copyright (c) 2006-2007 Ondrej Zajicek <santiago@crfreenet.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Some parts are based on David Boucher's viafb (http://davesdomain.org.uk/viafb/)
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <linux/svga.h>
+#include <linux/slab.h>
+#include <asm/types.h>
+#include <asm/io.h>
+
+
+/* Write a CRT register value spread across multiple registers */
+void svga_wcrt_multi(const struct vga_regset *regset, u32 value) {
+
+ u8 regval, bitval, bitnum;
+
+ while (regset->regnum != VGA_REGSET_END_VAL) {
+ regval = vga_rcrt(NULL, regset->regnum);
+ bitnum = regset->lowbit;
+ while (bitnum <= regset->highbit) {
+ bitval = 1 << bitnum;
+ regval = regval & ~bitval;
+ if (value & 1) regval = regval | bitval;
+ bitnum ++;
+ value = value >> 1;
+ }
+ vga_wcrt(NULL, regset->regnum, regval);
+ regset ++;
+ }
+}
+
+/* Write a sequencer register value spread across multiple registers */
+void svga_wseq_multi(const struct vga_regset *regset, u32 value) {
+
+ u8 regval, bitval, bitnum;
+
+ while (regset->regnum != VGA_REGSET_END_VAL) {
+ regval = vga_rseq(NULL, regset->regnum);
+ bitnum = regset->lowbit;
+ while (bitnum <= regset->highbit) {
+ bitval = 1 << bitnum;
+ regval = regval & ~bitval;
+ if (value & 1) regval = regval | bitval;
+ bitnum ++;
+ value = value >> 1;
+ }
+ vga_wseq(NULL, regset->regnum, regval);
+ regset ++;
+ }
+}
+
+static unsigned int svga_regset_size(const struct vga_regset *regset)
+{
+ u8 count = 0;
+
+ while (regset->regnum != VGA_REGSET_END_VAL) {
+ count += regset->highbit - regset->lowbit + 1;
+ regset ++;
+ }
+ return 1 << count;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+/* Set graphics controller registers to sane values */
+void svga_set_default_gfx_regs(void)
+{
+ /* All standard GFX registers (GR00 - GR08) */
+ vga_wgfx(NULL, VGA_GFX_SR_VALUE, 0x00);
+ vga_wgfx(NULL, VGA_GFX_SR_ENABLE, 0x00);
+ vga_wgfx(NULL, VGA_GFX_COMPARE_VALUE, 0x00);
+ vga_wgfx(NULL, VGA_GFX_DATA_ROTATE, 0x00);
+ vga_wgfx(NULL, VGA_GFX_PLANE_READ, 0x00);
+ vga_wgfx(NULL, VGA_GFX_MODE, 0x00);
+/* vga_wgfx(NULL, VGA_GFX_MODE, 0x20); */
+/* vga_wgfx(NULL, VGA_GFX_MODE, 0x40); */
+ vga_wgfx(NULL, VGA_GFX_MISC, 0x05);
+/* vga_wgfx(NULL, VGA_GFX_MISC, 0x01); */
+ vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x0F);
+ vga_wgfx(NULL, VGA_GFX_BIT_MASK, 0xFF);
+}
+
+/* Set attribute controller registers to sane values */
+void svga_set_default_atc_regs(void)
+{
+ u8 count;
+
+ vga_r(NULL, 0x3DA);
+ vga_w(NULL, VGA_ATT_W, 0x00);
+
+ /* All standard ATC registers (AR00 - AR14) */
+ for (count = 0; count <= 0xF; count ++)
+ svga_wattr(count, count);
+
+ svga_wattr(VGA_ATC_MODE, 0x01);
+/* svga_wattr(VGA_ATC_MODE, 0x41); */
+ svga_wattr(VGA_ATC_OVERSCAN, 0x00);
+ svga_wattr(VGA_ATC_PLANE_ENABLE, 0x0F);
+ svga_wattr(VGA_ATC_PEL, 0x00);
+ svga_wattr(VGA_ATC_COLOR_PAGE, 0x00);
+
+ vga_r(NULL, 0x3DA);
+ vga_w(NULL, VGA_ATT_W, 0x20);
+}
+
+/* Set sequencer registers to sane values */
+void svga_set_default_seq_regs(void)
+{
+ /* Standard sequencer registers (SR01 - SR04), SR00 is not set */
+ vga_wseq(NULL, VGA_SEQ_CLOCK_MODE, VGA_SR01_CHAR_CLK_8DOTS);
+ vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, VGA_SR02_ALL_PLANES);
+ vga_wseq(NULL, VGA_SEQ_CHARACTER_MAP, 0x00);
+/* vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE | VGA_SR04_CHN_4M); */
+ vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM | VGA_SR04_SEQ_MODE);
+}
+
+/* Set CRTC registers to sane values */
+void svga_set_default_crt_regs(void)
+{
+ /* Standard CRT registers CR03 CR08 CR09 CR14 CR17 */
+ svga_wcrt_mask(0x03, 0x80, 0x80); /* Enable vertical retrace EVRA */
+ vga_wcrt(NULL, VGA_CRTC_PRESET_ROW, 0);
+ svga_wcrt_mask(VGA_CRTC_MAX_SCAN, 0, 0x1F);
+ vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0);
+ vga_wcrt(NULL, VGA_CRTC_MODE, 0xE3);
+}
+
+void svga_set_textmode_vga_regs(void)
+{
+ /* svga_wseq_mask(0x1, 0x00, 0x01); */ /* Switch 8/9 pixel per char */
+ vga_wseq(NULL, VGA_SEQ_MEMORY_MODE, VGA_SR04_EXT_MEM);
+ vga_wseq(NULL, VGA_SEQ_PLANE_WRITE, 0x03);
+
+ vga_wcrt(NULL, VGA_CRTC_MAX_SCAN, 0x0f); /* 0x4f */
+ vga_wcrt(NULL, VGA_CRTC_UNDERLINE, 0x1f);
+ svga_wcrt_mask(VGA_CRTC_MODE, 0x23, 0x7f);
+
+ vga_wcrt(NULL, VGA_CRTC_CURSOR_START, 0x0d);
+ vga_wcrt(NULL, VGA_CRTC_CURSOR_END, 0x0e);
+ vga_wcrt(NULL, VGA_CRTC_CURSOR_HI, 0x00);
+ vga_wcrt(NULL, VGA_CRTC_CURSOR_LO, 0x00);
+
+ vga_wgfx(NULL, VGA_GFX_MODE, 0x10); /* Odd/even memory mode */
+ vga_wgfx(NULL, VGA_GFX_MISC, 0x0E); /* Misc graphics register - text mode enable */
+ vga_wgfx(NULL, VGA_GFX_COMPARE_MASK, 0x00);
+
+ vga_r(NULL, 0x3DA);
+ vga_w(NULL, VGA_ATT_W, 0x00);
+
+ svga_wattr(0x10, 0x0C); /* Attribute Mode Control Register - text mode, blinking and line graphics */
+ svga_wattr(0x13, 0x08); /* Horizontal Pixel Panning Register */
+
+ vga_r(NULL, 0x3DA);
+ vga_w(NULL, VGA_ATT_W, 0x20);
+}
+
+#if 0
+void svga_dump_var(struct fb_var_screeninfo *var, int node)
+{
+ pr_debug("fb%d: var.vmode : 0x%X\n", node, var->vmode);
+ pr_debug("fb%d: var.xres : %d\n", node, var->xres);
+ pr_debug("fb%d: var.yres : %d\n", node, var->yres);
+ pr_debug("fb%d: var.bits_per_pixel: %d\n", node, var->bits_per_pixel);
+ pr_debug("fb%d: var.xres_virtual : %d\n", node, var->xres_virtual);
+ pr_debug("fb%d: var.yres_virtual : %d\n", node, var->yres_virtual);
+ pr_debug("fb%d: var.left_margin : %d\n", node, var->left_margin);
+ pr_debug("fb%d: var.right_margin : %d\n", node, var->right_margin);
+ pr_debug("fb%d: var.upper_margin : %d\n", node, var->upper_margin);
+ pr_debug("fb%d: var.lower_margin : %d\n", node, var->lower_margin);
+ pr_debug("fb%d: var.hsync_len : %d\n", node, var->hsync_len);
+ pr_debug("fb%d: var.vsync_len : %d\n", node, var->vsync_len);
+ pr_debug("fb%d: var.sync : 0x%X\n", node, var->sync);
+ pr_debug("fb%d: var.pixclock : %d\n\n", node, var->pixclock);
+}
+#endif /* 0 */
+
+
+/* ------------------------------------------------------------------------- */
+
+
+void svga_settile(struct fb_info *info, struct fb_tilemap *map)
+{
+ const u8 *font = map->data;
+ u8* fb = (u8 *) info->screen_base;
+ int i, c;
+
+ if ((map->width != 8) || (map->height != 16) ||
+ (map->depth != 1) || (map->length != 256)) {
+ printk(KERN_ERR "fb%d: unsupported font parameters: width %d, height %d, depth %d, length %d\n",
+ info->node, map->width, map->height, map->depth, map->length);
+ return;
+ }
+
+ fb += 2;
+ for (c = 0; c < map->length; c++) {
+ for (i = 0; i < map->height; i++) {
+ fb[i * 4] = font[i];
+ }
+ fb += 128;
+ font += map->height;
+ }
+}
+
+/* Copy area in text (tileblit) mode */
+void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area)
+{
+ int dx, dy;
+ /* colstride is halved in this function because u16 are used */
+ int colstride = 1 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
+ int rowstride = colstride * (info->var.xres_virtual / 8);
+ u16 *fb = (u16 *) info->screen_base;
+ u16 *src, *dst;
+
+ if ((area->sy > area->dy) ||
+ ((area->sy == area->dy) && (area->sx > area->dx))) {
+ src = fb + area->sx * colstride + area->sy * rowstride;
+ dst = fb + area->dx * colstride + area->dy * rowstride;
+ } else {
+ src = fb + (area->sx + area->width - 1) * colstride
+ + (area->sy + area->height - 1) * rowstride;
+ dst = fb + (area->dx + area->width - 1) * colstride
+ + (area->dy + area->height - 1) * rowstride;
+
+ colstride = -colstride;
+ rowstride = -rowstride;
+ }
+
+ for (dy = 0; dy < area->height; dy++) {
+ u16* src2 = src;
+ u16* dst2 = dst;
+ for (dx = 0; dx < area->width; dx++) {
+ *dst2 = *src2;
+ src2 += colstride;
+ dst2 += colstride;
+ }
+ src += rowstride;
+ dst += rowstride;
+ }
+}
+
+/* Fill area in text (tileblit) mode */
+void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect)
+{
+ int dx, dy;
+ int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
+ int rowstride = colstride * (info->var.xres_virtual / 8);
+ int attr = (0x0F & rect->bg) << 4 | (0x0F & rect->fg);
+ u8 *fb = (u8 *) info->screen_base;
+ fb += rect->sx * colstride + rect->sy * rowstride;
+
+ for (dy = 0; dy < rect->height; dy++) {
+ u8* fb2 = fb;
+ for (dx = 0; dx < rect->width; dx++) {
+ fb2[0] = rect->index;
+ fb2[1] = attr;
+ fb2 += colstride;
+ }
+ fb += rowstride;
+ }
+}
+
+/* Write text in text (tileblit) mode */
+void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
+{
+ int dx, dy, i;
+ int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
+ int rowstride = colstride * (info->var.xres_virtual / 8);
+ int attr = (0x0F & blit->bg) << 4 | (0x0F & blit->fg);
+ u8* fb = (u8 *) info->screen_base;
+ fb += blit->sx * colstride + blit->sy * rowstride;
+
+ i=0;
+ for (dy=0; dy < blit->height; dy ++) {
+ u8* fb2 = fb;
+ for (dx = 0; dx < blit->width; dx ++) {
+ fb2[0] = blit->indices[i];
+ fb2[1] = attr;
+ fb2 += colstride;
+ i ++;
+ if (i == blit->length) return;
+ }
+ fb += rowstride;
+ }
+
+}
+
+/* Set cursor in text (tileblit) mode */
+void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
+{
+ u8 cs = 0x0d;
+ u8 ce = 0x0e;
+ u16 pos = cursor->sx + (info->var.xoffset / 8)
+ + (cursor->sy + (info->var.yoffset / 16))
+ * (info->var.xres_virtual / 8);
+
+ if (! cursor -> mode)
+ return;
+
+ svga_wcrt_mask(0x0A, 0x20, 0x20); /* disable cursor */
+
+ if (cursor -> shape == FB_TILE_CURSOR_NONE)
+ return;
+
+ switch (cursor -> shape) {
+ case FB_TILE_CURSOR_UNDERLINE:
+ cs = 0x0d;
+ break;
+ case FB_TILE_CURSOR_LOWER_THIRD:
+ cs = 0x09;
+ break;
+ case FB_TILE_CURSOR_LOWER_HALF:
+ cs = 0x07;
+ break;
+ case FB_TILE_CURSOR_TWO_THIRDS:
+ cs = 0x05;
+ break;
+ case FB_TILE_CURSOR_BLOCK:
+ cs = 0x01;
+ break;
+ }
+
+ /* set cursor position */
+ vga_wcrt(NULL, 0x0E, pos >> 8);
+ vga_wcrt(NULL, 0x0F, pos & 0xFF);
+
+ vga_wcrt(NULL, 0x0B, ce); /* set cursor end */
+ vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Compute PLL settings (M, N, R)
+ * F_VCO = (F_BASE * M) / N
+ * F_OUT = F_VCO / (2^R)
+ */
+
+static inline u32 abs_diff(u32 a, u32 b)
+{
+ return (a > b) ? (a - b) : (b - a);
+}
+
+int svga_compute_pll(const struct svga_pll *pll, u32 f_wanted, u16 *m, u16 *n, u16 *r, int node)
+{
+ u16 am, an, ar;
+ u32 f_vco, f_current, delta_current, delta_best;
+
+ pr_debug("fb%d: ideal frequency: %d kHz\n", node, (unsigned int) f_wanted);
+
+ ar = pll->r_max;
+ f_vco = f_wanted << ar;
+
+ /* overflow check */
+ if ((f_vco >> ar) != f_wanted)
+ return -EINVAL;
+
+ /* It is usually better to have greater VCO clock
+ because of better frequency stability.
+ So first try r_max, then r smaller. */
+ while ((ar > pll->r_min) && (f_vco > pll->f_vco_max)) {
+ ar--;
+ f_vco = f_vco >> 1;
+ }
+
+ /* VCO bounds check */
+ if ((f_vco < pll->f_vco_min) || (f_vco > pll->f_vco_max))
+ return -EINVAL;
+
+ delta_best = 0xFFFFFFFF;
+ *m = 0;
+ *n = 0;
+ *r = ar;
+
+ am = pll->m_min;
+ an = pll->n_min;
+
+ while ((am <= pll->m_max) && (an <= pll->n_max)) {
+ f_current = (pll->f_base * am) / an;
+ delta_current = abs_diff (f_current, f_vco);
+
+ if (delta_current < delta_best) {
+ delta_best = delta_current;
+ *m = am;
+ *n = an;
+ }
+
+ if (f_current <= f_vco) {
+ am ++;
+ } else {
+ an ++;
+ }
+ }
+
+ f_current = (pll->f_base * *m) / *n;
+ pr_debug("fb%d: found frequency: %d kHz (VCO %d kHz)\n", node, (int) (f_current >> ar), (int) f_current);
+ pr_debug("fb%d: m = %d n = %d r = %d\n", node, (unsigned int) *m, (unsigned int) *n, (unsigned int) *r);
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+/* Check CRT timing values */
+int svga_check_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var, int node)
+{
+ u32 value;
+
+ var->xres = (var->xres+7)&~7;
+ var->left_margin = (var->left_margin+7)&~7;
+ var->right_margin = (var->right_margin+7)&~7;
+ var->hsync_len = (var->hsync_len+7)&~7;
+
+ /* Check horizontal total */
+ value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
+ if (((value / 8) - 5) >= svga_regset_size (tm->h_total_regs))
+ return -EINVAL;
+
+ /* Check horizontal display and blank start */
+ value = var->xres;
+ if (((value / 8) - 1) >= svga_regset_size (tm->h_display_regs))
+ return -EINVAL;
+ if (((value / 8) - 1) >= svga_regset_size (tm->h_blank_start_regs))
+ return -EINVAL;
+
+ /* Check horizontal sync start */
+ value = var->xres + var->right_margin;
+ if (((value / 8) - 1) >= svga_regset_size (tm->h_sync_start_regs))
+ return -EINVAL;
+
+ /* Check horizontal blank end (or length) */
+ value = var->left_margin + var->right_margin + var->hsync_len;
+ if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_blank_end_regs)))
+ return -EINVAL;
+
+ /* Check horizontal sync end (or length) */
+ value = var->hsync_len;
+ if ((value == 0) || ((value / 8) >= svga_regset_size (tm->h_sync_end_regs)))
+ return -EINVAL;
+
+ /* Check vertical total */
+ value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
+ if ((value - 1) >= svga_regset_size(tm->v_total_regs))
+ return -EINVAL;
+
+ /* Check vertical display and blank start */
+ value = var->yres;
+ if ((value - 1) >= svga_regset_size(tm->v_display_regs))
+ return -EINVAL;
+ if ((value - 1) >= svga_regset_size(tm->v_blank_start_regs))
+ return -EINVAL;
+
+ /* Check vertical sync start */
+ value = var->yres + var->lower_margin;
+ if ((value - 1) >= svga_regset_size(tm->v_sync_start_regs))
+ return -EINVAL;
+
+ /* Check vertical blank end (or length) */
+ value = var->upper_margin + var->lower_margin + var->vsync_len;
+ if ((value == 0) || (value >= svga_regset_size (tm->v_blank_end_regs)))
+ return -EINVAL;
+
+ /* Check vertical sync end (or length) */
+ value = var->vsync_len;
+ if ((value == 0) || (value >= svga_regset_size (tm->v_sync_end_regs)))
+ return -EINVAL;
+
+ return 0;
+}
+
+/* Set CRT timing registers */
+void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninfo *var,
+ u32 hmul, u32 hdiv, u32 vmul, u32 vdiv, u32 hborder, int node)
+{
+ u8 regval;
+ u32 value;
+
+ value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
+ value = (value * hmul) / hdiv;
+ pr_debug("fb%d: horizontal total : %d\n", node, value);
+ svga_wcrt_multi(tm->h_total_regs, (value / 8) - 5);
+
+ value = var->xres;
+ value = (value * hmul) / hdiv;
+ pr_debug("fb%d: horizontal display : %d\n", node, value);
+ svga_wcrt_multi(tm->h_display_regs, (value / 8) - 1);
+
+ value = var->xres;
+ value = (value * hmul) / hdiv;
+ pr_debug("fb%d: horizontal blank start: %d\n", node, value);
+ svga_wcrt_multi(tm->h_blank_start_regs, (value / 8) - 1 + hborder);
+
+ value = var->xres + var->left_margin + var->right_margin + var->hsync_len;
+ value = (value * hmul) / hdiv;
+ pr_debug("fb%d: horizontal blank end : %d\n", node, value);
+ svga_wcrt_multi(tm->h_blank_end_regs, (value / 8) - 1 - hborder);
+
+ value = var->xres + var->right_margin;
+ value = (value * hmul) / hdiv;
+ pr_debug("fb%d: horizontal sync start : %d\n", node, value);
+ svga_wcrt_multi(tm->h_sync_start_regs, (value / 8));
+
+ value = var->xres + var->right_margin + var->hsync_len;
+ value = (value * hmul) / hdiv;
+ pr_debug("fb%d: horizontal sync end : %d\n", node, value);
+ svga_wcrt_multi(tm->h_sync_end_regs, (value / 8));
+
+ value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
+ value = (value * vmul) / vdiv;
+ pr_debug("fb%d: vertical total : %d\n", node, value);
+ svga_wcrt_multi(tm->v_total_regs, value - 2);
+
+ value = var->yres;
+ value = (value * vmul) / vdiv;
+ pr_debug("fb%d: vertical display : %d\n", node, value);
+ svga_wcrt_multi(tm->v_display_regs, value - 1);
+
+ value = var->yres;
+ value = (value * vmul) / vdiv;
+ pr_debug("fb%d: vertical blank start : %d\n", node, value);
+ svga_wcrt_multi(tm->v_blank_start_regs, value);
+
+ value = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
+ value = (value * vmul) / vdiv;
+ pr_debug("fb%d: vertical blank end : %d\n", node, value);
+ svga_wcrt_multi(tm->v_blank_end_regs, value - 2);
+
+ value = var->yres + var->lower_margin;
+ value = (value * vmul) / vdiv;
+ pr_debug("fb%d: vertical sync start : %d\n", node, value);
+ svga_wcrt_multi(tm->v_sync_start_regs, value);
+
+ value = var->yres + var->lower_margin + var->vsync_len;
+ value = (value * vmul) / vdiv;
+ pr_debug("fb%d: vertical sync end : %d\n", node, value);
+ svga_wcrt_multi(tm->v_sync_end_regs, value);
+
+ /* Set horizontal and vertical sync pulse polarity in misc register */
+
+ regval = vga_r(NULL, VGA_MIS_R);
+ if (var->sync & FB_SYNC_HOR_HIGH_ACT) {
+ pr_debug("fb%d: positive horizontal sync\n", node);
+ regval = regval & ~0x80;
+ } else {
+ pr_debug("fb%d: negative horizontal sync\n", node);
+ regval = regval | 0x80;
+ }
+ if (var->sync & FB_SYNC_VERT_HIGH_ACT) {
+ pr_debug("fb%d: positive vertical sync\n", node);
+ regval = regval & ~0x40;
+ } else {
+ pr_debug("fb%d: negative vertical sync\n\n", node);
+ regval = regval | 0x40;
+ }
+ vga_w(NULL, VGA_MIS_W, regval);
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix)
+{
+ int i = 0;
+
+ while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL)
+ {
+ if ((var->bits_per_pixel == frm->bits_per_pixel) &&
+ (var->red.length <= frm->red.length) &&
+ (var->green.length <= frm->green.length) &&
+ (var->blue.length <= frm->blue.length) &&
+ (var->transp.length <= frm->transp.length) &&
+ (var->nonstd == frm->nonstd)) {
+ var->bits_per_pixel = frm->bits_per_pixel;
+ var->red = frm->red;
+ var->green = frm->green;
+ var->blue = frm->blue;
+ var->transp = frm->transp;
+ var->nonstd = frm->nonstd;
+ if (fix != NULL) {
+ fix->type = frm->type;
+ fix->type_aux = frm->type_aux;
+ fix->visual = frm->visual;
+ fix->xpanstep = frm->xpanstep;
+ }
+ return i;
+ }
+ i++;
+ frm++;
+ }
+ return -EINVAL;
+}
+
+
+EXPORT_SYMBOL(svga_wcrt_multi);
+EXPORT_SYMBOL(svga_wseq_multi);
+
+EXPORT_SYMBOL(svga_set_default_gfx_regs);
+EXPORT_SYMBOL(svga_set_default_atc_regs);
+EXPORT_SYMBOL(svga_set_default_seq_regs);
+EXPORT_SYMBOL(svga_set_default_crt_regs);
+EXPORT_SYMBOL(svga_set_textmode_vga_regs);
+
+EXPORT_SYMBOL(svga_settile);
+EXPORT_SYMBOL(svga_tilecopy);
+EXPORT_SYMBOL(svga_tilefill);
+EXPORT_SYMBOL(svga_tileblit);
+EXPORT_SYMBOL(svga_tilecursor);
+
+EXPORT_SYMBOL(svga_compute_pll);
+EXPORT_SYMBOL(svga_check_timings);
+EXPORT_SYMBOL(svga_set_timings);
+EXPORT_SYMBOL(svga_match_format);
+
+MODULE_AUTHOR("Ondrej Zajicek <santiago@crfreenet.org>");
+MODULE_DESCRIPTION("Common utility functions for VGA-based graphics cards");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 4b88fab83b74..b604859b4ddb 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -43,8 +43,9 @@ static void tgafb_imageblit(struct fb_info *, const struct fb_image *);
static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
-static int tgafb_pci_register(struct pci_dev *, const struct pci_device_id *);
-static void tgafb_pci_unregister(struct pci_dev *);
+static int __devinit tgafb_pci_register(struct pci_dev *,
+ const struct pci_device_id *);
+static void __devexit tgafb_pci_unregister(struct pci_dev *);
static const char *mode_option = "640x480@60";
@@ -70,9 +71,10 @@ static struct fb_ops tgafb_ops = {
*/
static struct pci_device_id const tgafb_pci_table[] = {
- { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA, PCI_ANY_ID, PCI_ANY_ID,
- 0, 0, 0 }
+ { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) },
+ { }
};
+MODULE_DEVICE_TABLE(pci, tgafb_pci_table);
static struct pci_driver tgafb_driver = {
.name = "tgafb",
@@ -99,6 +101,12 @@ tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
if (var->bits_per_pixel != 32)
return -EINVAL;
}
+ var->red.length = var->green.length = var->blue.length = 8;
+ if (var->bits_per_pixel == 32) {
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ }
if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)
return -EINVAL;
@@ -137,10 +145,10 @@ tgafb_set_par(struct fb_info *info)
0x00000303
};
static unsigned int const mode_presets[4] = {
- 0x00002000,
- 0x00002300,
+ 0x00000000,
+ 0x00000300,
0xffffffff,
- 0x00002300
+ 0x00000300
};
static unsigned int const base_addr_presets[4] = {
0x00000000,
@@ -152,7 +160,7 @@ tgafb_set_par(struct fb_info *info)
struct tga_par *par = (struct tga_par *) info->par;
u32 htimings, vtimings, pll_freq;
u8 tga_type;
- int i, j;
+ int i;
/* Encode video timings. */
htimings = (((info->var.xres/4) & TGA_HORIZ_ACT_LSB)
@@ -190,7 +198,9 @@ tgafb_set_par(struct fb_info *info)
while (TGA_READ_REG(par, TGA_CMD_STAT_REG) & 1) /* wait for not busy */
continue;
mb();
- TGA_WRITE_REG(par, deep_presets[tga_type], TGA_DEEP_REG);
+ TGA_WRITE_REG(par, deep_presets[tga_type] |
+ (par->sync_on_green ? 0x0 : 0x00010000),
+ TGA_DEEP_REG);
while (TGA_READ_REG(par, TGA_CMD_STAT_REG) & 1) /* wait for not busy */
continue;
mb();
@@ -227,8 +237,10 @@ tgafb_set_par(struct fb_info *info)
BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE);
TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
+#ifdef CONFIG_HW_CONSOLE
for (i = 0; i < 16; i++) {
- j = color_table[i];
+ int j = color_table[i];
+
TGA_WRITE_REG(par, default_red[j]|(BT485_DATA_PAL<<8),
TGA_RAMDAC_REG);
TGA_WRITE_REG(par, default_grn[j]|(BT485_DATA_PAL<<8),
@@ -236,24 +248,27 @@ tgafb_set_par(struct fb_info *info)
TGA_WRITE_REG(par, default_blu[j]|(BT485_DATA_PAL<<8),
TGA_RAMDAC_REG);
}
- for (i = 0; i < 240*3; i += 4) {
- TGA_WRITE_REG(par, 0x55|(BT485_DATA_PAL<<8),
+ for (i = 0; i < 240 * 3; i += 4) {
+#else
+ for (i = 0; i < 256 * 3; i += 4) {
+#endif
+ TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8),
TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, 0x00|(BT485_DATA_PAL<<8),
+ TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, 0x00|(BT485_DATA_PAL<<8),
+ TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, 0x00|(BT485_DATA_PAL<<8),
+ TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
TGA_RAMDAC_REG);
}
} else { /* 24-plane or 24plusZ */
- /* Init BT463 registers. */
+ /* Init BT463 RAMDAC registers. */
BT463_WRITE(par, BT463_REG_ACC, BT463_CMD_REG_0, 0x40);
BT463_WRITE(par, BT463_REG_ACC, BT463_CMD_REG_1, 0x08);
BT463_WRITE(par, BT463_REG_ACC, BT463_CMD_REG_2,
- (par->sync_on_green ? 0x80 : 0x40));
+ (par->sync_on_green ? 0xc0 : 0x40));
BT463_WRITE(par, BT463_REG_ACC, BT463_READ_MASK_0, 0xff);
BT463_WRITE(par, BT463_REG_ACC, BT463_READ_MASK_1, 0xff);
@@ -267,26 +282,24 @@ tgafb_set_par(struct fb_info *info)
/* Fill the palette. */
BT463_LOAD_ADDR(par, 0x0000);
- TGA_WRITE_REG(par, BT463_PALETTE<<2, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, BT463_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
+#ifdef CONFIG_HW_CONSOLE
for (i = 0; i < 16; i++) {
- j = color_table[i];
- TGA_WRITE_REG(par, default_red[j]|(BT463_PALETTE<<10),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, default_grn[j]|(BT463_PALETTE<<10),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, default_blu[j]|(BT463_PALETTE<<10),
- TGA_RAMDAC_REG);
+ int j = color_table[i];
+
+ TGA_WRITE_REG(par, default_red[j], TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, default_grn[j], TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, default_blu[j], TGA_RAMDAC_REG);
}
- for (i = 0; i < 512*3; i += 4) {
- TGA_WRITE_REG(par, 0x55|(BT463_PALETTE<<10),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, 0x00|(BT463_PALETTE<<10),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, 0x00|(BT463_PALETTE<<10),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, 0x00|(BT463_PALETTE<<10),
- TGA_RAMDAC_REG);
+ for (i = 0; i < 512 * 3; i += 4) {
+#else
+ for (i = 0; i < 528 * 3; i += 4) {
+#endif
+ TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
}
/* Fill window type table after start of vertical retrace. */
@@ -299,15 +312,12 @@ tgafb_set_par(struct fb_info *info)
TGA_WRITE_REG(par, 0x01, TGA_INTR_STAT_REG);
BT463_LOAD_ADDR(par, BT463_WINDOW_TYPE_BASE);
- TGA_WRITE_REG(par, BT463_REG_ACC<<2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, BT463_REG_ACC << 2, TGA_RAMDAC_SETUP_REG);
for (i = 0; i < 16; i++) {
- TGA_WRITE_REG(par, 0x00|(BT463_REG_ACC<<10),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, 0x01|(BT463_REG_ACC<<10),
- TGA_RAMDAC_REG);
- TGA_WRITE_REG(par, 0x80|(BT463_REG_ACC<<10),
- TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x01, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
}
}
@@ -435,9 +445,16 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
TGA_WRITE_REG(par, red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
TGA_WRITE_REG(par, green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
TGA_WRITE_REG(par, blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
- } else if (regno < 16) {
- u32 value = (red << 16) | (green << 8) | blue;
- ((u32 *)info->pseudo_palette)[regno] = value;
+ } else {
+ if (regno < 16) {
+ u32 value = (regno << 16) | (regno << 8) | regno;
+ ((u32 *)info->pseudo_palette)[regno] = value;
+ }
+ BT463_LOAD_ADDR(par, regno);
+ TGA_WRITE_REG(par, BT463_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
+ TGA_WRITE_REG(par, red, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, green, TGA_RAMDAC_REG);
+ TGA_WRITE_REG(par, blue, TGA_RAMDAC_REG);
}
return 0;
@@ -885,7 +902,7 @@ copyarea_line_8bpp(struct fb_info *info, u32 dy, u32 sy,
n64 = (height * width) / 64;
- if (dy < sy) {
+ if (sy < dy) {
spos = (sy + height) * width;
dpos = (dy + height) * width;
@@ -933,7 +950,7 @@ copyarea_line_32bpp(struct fb_info *info, u32 dy, u32 sy,
n16 = (height * width) / 16;
- if (dy < sy) {
+ if (sy < dy) {
src = tga_fb + (sy + height) * width * 4;
dst = tga_fb + (dy + height) * width * 4;
@@ -1317,7 +1334,7 @@ tgafb_init_fix(struct fb_info *info)
info->fix.type_aux = 0;
info->fix.visual = (tga_type == TGA_TYPE_8PLANE
? FB_VISUAL_PSEUDOCOLOR
- : FB_VISUAL_TRUECOLOR);
+ : FB_VISUAL_DIRECTCOLOR);
info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);
info->fix.smem_start = (size_t) par->tga_fb_base;
@@ -1342,14 +1359,10 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
TGA_24PLUSZ_FB_OFFSET
};
- struct all_info {
- struct fb_info info;
- struct tga_par par;
- u32 pseudo_palette[16];
- } *all;
-
void __iomem *mem_base;
unsigned long bar0_start, bar0_len;
+ struct fb_info *info;
+ struct tga_par *par;
u8 tga_type;
int ret;
@@ -1360,13 +1373,14 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
}
/* Allocate the fb and par structures. */
- all = kmalloc(sizeof(*all), GFP_KERNEL);
- if (!all) {
+ info = framebuffer_alloc(sizeof(struct tga_par), &pdev->dev);
+ if (!info) {
printk(KERN_ERR "tgafb: Cannot allocate memory\n");
return -ENOMEM;
}
- memset(all, 0, sizeof(*all));
- pci_set_drvdata(pdev, all);
+
+ par = info->par;
+ pci_set_drvdata(pdev, info);
/* Request the mem regions. */
bar0_start = pci_resource_start(pdev, 0);
@@ -1386,25 +1400,23 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Grab info about the card. */
tga_type = (readl(mem_base) >> 12) & 0x0f;
- all->par.pdev = pdev;
- all->par.tga_mem_base = mem_base;
- all->par.tga_fb_base = mem_base + fb_offset_presets[tga_type];
- all->par.tga_regs_base = mem_base + TGA_REGS_OFFSET;
- all->par.tga_type = tga_type;
- pci_read_config_byte(pdev, PCI_REVISION_ID, &all->par.tga_chip_rev);
+ par->pdev = pdev;
+ par->tga_mem_base = mem_base;
+ par->tga_fb_base = mem_base + fb_offset_presets[tga_type];
+ par->tga_regs_base = mem_base + TGA_REGS_OFFSET;
+ par->tga_type = tga_type;
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &par->tga_chip_rev);
/* Setup framebuffer. */
- all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
- FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT;
- all->info.fbops = &tgafb_ops;
- all->info.screen_base = all->par.tga_fb_base;
- all->info.par = &all->par;
- all->info.pseudo_palette = all->pseudo_palette;
+ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
+ FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT;
+ info->fbops = &tgafb_ops;
+ info->screen_base = par->tga_fb_base;
+ info->pseudo_palette = (void *)(par + 1);
/* This should give a reasonable default video mode. */
- ret = fb_find_mode(&all->info.var, &all->info, mode_option,
- NULL, 0, NULL,
+ ret = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL,
tga_type == TGA_TYPE_8PLANE ? 8 : 32);
if (ret == 0 || ret == 4) {
printk(KERN_ERR "tgafb: Could not find valid video mode\n");
@@ -1412,29 +1424,28 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err1;
}
- if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+ if (fb_alloc_cmap(&info->cmap, 256, 0)) {
printk(KERN_ERR "tgafb: Could not allocate color map\n");
ret = -ENOMEM;
goto err1;
}
- tgafb_set_par(&all->info);
- tgafb_init_fix(&all->info);
+ tgafb_set_par(info);
+ tgafb_init_fix(info);
- all->info.device = &pdev->dev;
- if (register_framebuffer(&all->info) < 0) {
+ if (register_framebuffer(info) < 0) {
printk(KERN_ERR "tgafb: Could not register framebuffer\n");
ret = -EINVAL;
goto err1;
}
printk(KERN_INFO "tgafb: DC21030 [TGA] detected, rev=0x%02x\n",
- all->par.tga_chip_rev);
+ par->tga_chip_rev);
printk(KERN_INFO "tgafb: at PCI bus %d, device %d, function %d\n",
pdev->bus->number, PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn));
printk(KERN_INFO "fb%d: %s frame buffer device at 0x%lx\n",
- all->info.node, all->info.fix.id, bar0_start);
+ info->node, info->fix.id, bar0_start);
return 0;
@@ -1443,11 +1454,11 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(mem_base);
release_mem_region(bar0_start, bar0_len);
err0:
- kfree(all);
+ framebuffer_release(info);
return ret;
}
-static void __exit
+static void __devexit
tgafb_pci_unregister(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
@@ -1456,22 +1467,21 @@ tgafb_pci_unregister(struct pci_dev *pdev)
if (!info)
return;
unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
iounmap(par->tga_mem_base);
release_mem_region(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
- kfree(info);
+ framebuffer_release(info);
}
-#ifdef MODULE
-static void __exit
+static void __devexit
tgafb_exit(void)
{
pci_unregister_driver(&tgafb_driver);
}
-#endif /* MODULE */
#ifndef MODULE
-int __init
+static int __devinit
tgafb_setup(char *arg)
{
char *this_opt;
@@ -1493,7 +1503,7 @@ tgafb_setup(char *arg)
}
#endif /* !MODULE */
-int __init
+static int __devinit
tgafb_init(void)
{
#ifndef MODULE
@@ -1511,10 +1521,7 @@ tgafb_init(void)
*/
module_init(tgafb_init);
-
-#ifdef MODULE
module_exit(tgafb_exit);
-#endif
MODULE_DESCRIPTION("framebuffer driver for TGA chipset");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 6aff63d5b295..ec4c7dc54a66 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -70,7 +70,8 @@ struct vga16fb_par {
unsigned char ClockingMode; /* Seq-Controller:01h */
} vga_state;
struct vgastate state;
- atomic_t ref_count;
+ struct mutex open_lock;
+ unsigned int ref_count;
int palette_blanked, vesa_blanked, mode, isVGA;
u8 misc, pel_msk, vss, clkdiv;
u8 crtc[VGA_CRT_C];
@@ -300,28 +301,33 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
static int vga16fb_open(struct fb_info *info, int user)
{
struct vga16fb_par *par = info->par;
- int cnt = atomic_read(&par->ref_count);
- if (!cnt) {
+ mutex_lock(&par->open_lock);
+ if (!par->ref_count) {
memset(&par->state, 0, sizeof(struct vgastate));
par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE |
VGA_SAVE_CMAP;
save_vga(&par->state);
}
- atomic_inc(&par->ref_count);
+ par->ref_count++;
+ mutex_unlock(&par->open_lock);
+
return 0;
}
static int vga16fb_release(struct fb_info *info, int user)
{
struct vga16fb_par *par = info->par;
- int cnt = atomic_read(&par->ref_count);
- if (!cnt)
+ mutex_lock(&par->open_lock);
+ if (!par->ref_count) {
+ mutex_unlock(&par->open_lock);
return -EINVAL;
- if (cnt == 1)
+ }
+ if (par->ref_count == 1)
restore_vga(&par->state);
- atomic_dec(&par->ref_count);
+ par->ref_count--;
+ mutex_unlock(&par->open_lock);
return 0;
}
@@ -1357,6 +1363,7 @@ static int __init vga16fb_probe(struct platform_device *dev)
printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
par = info->par;
+ mutex_init(&par->open_lock);
par->isVGA = ORIG_VIDEO_ISVGA;
par->palette_blanked = 0;
par->vesa_blanked = 0;
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
deleted file mode 100644
index b9fb6fb3600d..000000000000
--- a/drivers/video/virgefb.c
+++ /dev/null
@@ -1,2526 +0,0 @@
-/*
- * linux/drivers/video/virgefb.c -- CyberVision64/3D frame buffer device
- *
- * Copyright (C) 1997 André Heynatz
- *
- *
- * This file is based on the CyberVision frame buffer device (cyberfb.c):
- *
- * Copyright (C) 1996 Martin Apel
- * Geert Uytterhoeven
- *
- * Zorro II additions :
- *
- * Copyright (C) 1998-2000 Christian T. Steigies
- *
- * Initialization additions :
- *
- * Copyright (C) 1998-2000 Ken Tyler
- *
- * Parts of the Initialization code are based on Cyberfb.c by Allan Bair,
- * and on the NetBSD CyberVision64 frame buffer driver by Michael Teske who gave
- * permission for its use.
- *
- * Many thanks to Frank Mariak for his assistance with ZORRO 2 access and other
- * mysteries.
- *
- *
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#undef VIRGEFBDEBUG
-#undef VIRGEFBDUMP
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/zorro.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/amigahw.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb32.h>
-
-#include "virgefb.h"
-
-#ifdef VIRGEFBDEBUG
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
-#ifdef VIRGEFBDUMP
-static void cv64_dump(void);
-#define DUMP cv64_dump()
-#else
-#define DUMP
-#endif
-
-/*
- * Macros for register access and zorro control
- */
-
-static inline void mb_inline(void) { mb(); } /* for use in comma expressions */
-
-/* Set zorro 2 map */
-
-#define SelectIO \
- mb(); \
- if (on_zorro2) { \
- (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x01); \
- mb(); \
- }
-
-#define SelectMMIO \
- mb(); \
- if (on_zorro2) { \
- (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x02); \
- mb(); \
- }
-
-#define SelectCFG \
- mb(); \
- if (on_zorro2) { \
- (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x04)) = 0x03); \
- mb(); \
- }
-
-/* Set pass through, 0 = amiga, !=0 = cv64/3d */
-
-#define SetVSwitch(x) \
- mb(); \
- (*(volatile u16 *)((u8 *)(vcode_switch_base)) = \
- (u16)(x ? 0 : 1)); \
- mb();
-
-/* Zorro2 endian 'aperture' */
-
-#define ENDIAN_BYTE 2
-#define ENDIAN_WORD 1
-#define ENDIAN_LONG 0
-
-#define Select_Zorro2_FrameBuffer(x) \
- do { \
- if (on_zorro2) { \
- mb(); \
- (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x08)) = \
- (x * 0x40)); \
- mb(); \
- } \
- } while (0)
-
-/* SetPortVal - only used for interrupt enable (not yet implemented) */
-
-#if 0
-#define SetPortVal(x) \
- mb(); \
- (*(volatile u16 *)((u8 *)(vcode_switch_base + 0x0c)) = \
- (u16)x); \
- mb();
-#endif
-
-/* IO access */
-
-#define byte_access_io(x) (((x) & 0x3ffc) | (((x) & 3)^3) | (((x) & 3) <<14))
-#define byte_access_mmio(x) (((x) & 0xfffc) | (((x) & 3)^3))
-
-/* Write 8 bit VGA register - used once for chip wakeup */
-
-#define wb_vgaio(reg, dat) \
- SelectIO; \
- (*(volatile u8 *)(vgaio_regs + ((u32)byte_access_io(reg) & 0xffff)) = \
- (dat & 0xff)); \
- SelectMMIO;
-
-/* Read 8 bit VGA register - only used in dump (SelectIO not needed on read ?) */
-
-#ifdef VIRGEFBDUMP
-#define rb_vgaio(reg) \
- ({ \
- u8 __zzyzx; \
- SelectIO; \
- __zzyzx = (*(volatile u8 *)((vgaio_regs)+(u32)byte_access_io(reg))); \
- SelectMMIO; \
- __zzyzx; \
- })
-#endif
-
-/* MMIO access */
-
-/* Read 8 bit MMIO register */
-
-#define rb_mmio(reg) \
- (mb_inline(), \
- (*(volatile u8 *)(mmio_regs + 0x8000 + (u32)byte_access_mmio(reg))))
-
-/* Write 8 bit MMIO register */
-
-#define wb_mmio(reg,dat) \
- mb(); \
- (*(volatile u8 *)(mmio_regs + 0x8000 + (byte_access_mmio((reg) & 0xffff))) = \
- (dat & 0xff)); \
- mb();
-
-/* Read 32 bit MMIO register */
-
-#define rl_mmio(reg) \
- (mb_inline(), \
- (*((volatile u32 *)((u8 *)((mmio_regs + (on_zorro2 ? 0x20000 : 0)) + (reg))))))
-
-/* Write 32 bit MMIO register */
-
-#define wl_mmio(reg,dat) \
- mb(); \
- ((*(volatile u32 *)((u8 *)((mmio_regs + (on_zorro2 ? 0x20000 : 0)) + (reg)))) = \
- (u32)(dat)); \
- mb();
-
-/* Write to virge graphics register */
-
-#define wgfx(reg, dat) do { wb_mmio(GCT_ADDRESS, (reg)); wb_mmio(GCT_ADDRESS_W, (dat)); } while (0)
-
-/* Write to virge sequencer register */
-
-#define wseq(reg, dat) do { wb_mmio(SEQ_ADDRESS, (reg)); wb_mmio(SEQ_ADDRESS_W, (dat)); } while (0)
-
-/* Write to virge CRT controller register */
-
-#define wcrt(reg, dat) do { wb_mmio(CRT_ADDRESS, (reg)); wb_mmio(CRT_ADDRESS_W, (dat)); } while (0)
-
-/* Write to virge attribute register */
-
-#define watr(reg, dat) \
- do { \
- volatile unsigned char watr_tmp; \
- watr_tmp = rb_mmio(ACT_ADDRESS_RESET); \
- wb_mmio(ACT_ADDRESS_W, (reg)); \
- wb_mmio(ACT_ADDRESS_W, (dat)); \
- udelay(10); \
- } while (0)
-
-/* end of macros */
-
-struct virgefb_par {
- struct fb_var_screeninfo var;
- __u32 type;
- __u32 type_aux;
- __u32 visual;
- __u32 line_length;
-};
-
-static struct virgefb_par current_par;
-
-static int current_par_valid = 0;
-
-static struct display disp;
-static struct fb_info fb_info;
-
-static union {
-#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB32
- u32 cfb32[16];
-#endif
-} fbcon_cmap;
-
-/*
- * Switch for Chipset Independency
- */
-
-static struct fb_hwswitch {
-
- /* Initialisation */
-
- int (*init)(void);
-
- /* Display Control */
-
- int (*encode_fix)(struct fb_fix_screeninfo *fix, struct virgefb_par *par);
- int (*decode_var)(struct fb_var_screeninfo *var, struct virgefb_par *par);
- int (*encode_var)(struct fb_var_screeninfo *var, struct virgefb_par *par);
- int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info);
- void (*blank)(int blank);
-} *fbhw;
-
-static unsigned char blit_maybe_busy = 0;
-
-/*
- * Frame Buffer Name
- */
-
-static char virgefb_name[16] = "CyberVision/3D";
-
-/*
- * CyberVision64/3d Graphics Board
- */
-
-static unsigned char virgefb_colour_table [256][3];
-static unsigned long v_ram;
-static unsigned long v_ram_size;
-static volatile unsigned char *mmio_regs;
-static volatile unsigned char *vgaio_regs;
-
-static unsigned long v_ram_phys;
-static unsigned long mmio_regs_phys;
-static unsigned long vcode_switch_base;
-static unsigned char on_zorro2;
-
-/*
- * Offsets from start of video ram to appropriate ZIII aperture
- */
-
-#ifdef FBCON_HAS_CFB8
-#define CYBMEM_OFFSET_8 0x800000 /* BGRX */
-#endif
-#ifdef FBCON_HAS_CFB16
-#define CYBMEM_OFFSET_16 0x400000 /* GBXR */
-#endif
-#ifdef FBCON_HAS_CFB32
-#define CYBMEM_OFFSET_32 0x000000 /* XRGB */
-#endif
-
-/*
- * MEMCLOCK was 32MHz, 64MHz works, 72MHz doesn't (on my board)
- */
-
-#define MEMCLOCK 50000000
-
-/*
- * Predefined Video Modes
- */
-
-static struct {
- const char *name;
- struct fb_var_screeninfo var;
-} virgefb_predefined[] __initdata = {
-#ifdef FBCON_HAS_CFB8
- {
- "640x480-8", { /* Cybervision 8 bpp */
- 640, 480, 640, 480, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 160, 136, 82, 61, 88, 2,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "768x576-8", { /* Cybervision 8 bpp */
- 768, 576, 768, 576, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "800x600-8", { /* Cybervision 8 bpp */
- 800, 600, 800, 600, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- #if 0
- "1024x768-8", { /* Cybervision 8 bpp */
- 1024, 768, 1024, 768, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
- 0, FB_VMODE_NONINTERLACED
- }
- #else
- "1024x768-8", {
- 1024, 768, 1024, 768, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- #if 0
- 0, 0, -1, -1, FB_ACCELF_TEXT, 12500, 184, 40, 40, 2, 96, 1,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
- #else
- 0, 0, -1, -1, FB_ACCELF_TEXT, 12699, 176, 16, 28, 1, 96, 3,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
- #endif
- #endif
- }, {
- "1152x886-8", { /* Cybervision 8 bpp */
- 1152, 886, 1152, 886, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "1280x1024-8", { /* Cybervision 8 bpp */
- 1280, 1024, 1280, 1024, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- #if 0
- 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
- }
- #else
- 0, 0, -1, -1, FB_ACCELF_TEXT, 7414, 232, 64, 38, 1, 112, 3,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
- #endif
- }, {
- "1600x1200-8", { /* Cybervision 8 bpp */
- 1600, 1200, 1600, 1200, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- #if 0
- 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
- 0, FB_VMODE_NONINTERLACED
- }
- #else
- 0, 0, -1, -1, FB_ACCELF_TEXT, 6411, 256, 32, 52, 10, 160, 8,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
- #endif
- },
-#endif
-
-#ifdef FBCON_HAS_CFB16
- {
- "640x480-16", { /* Cybervision 16 bpp */
- 640, 480, 640, 480, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 152, 144, 82, 61, 88, 2,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "768x576-16", { /* Cybervision 16 bpp */
- 768, 576, 768, 576, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "800x600-16", { /* Cybervision 16 bpp */
- 800, 600, 800, 600, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
-#if 0
- "1024x768-16", { /* Cybervision 16 bpp */
- 1024, 768, 1024, 768, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
- 0, FB_VMODE_NONINTERLACED
- }
-#else
- "1024x768-16", {
- 1024, 768, 1024, 768, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 12500, 184, 40, 40, 2, 96, 1,
- FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
-#endif
- }, {
- "1152x886-16", { /* Cybervision 16 bpp */
- 1152, 886, 1152, 886, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "1280x1024-16", { /* Cybervision 16 bpp */
- 1280, 1024, 1280, 1024, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "1600x1200-16", { /* Cybervision 16 bpp */
- 1600, 1200, 1600, 1200, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
- 0, FB_VMODE_NONINTERLACED
- }
- },
-#endif
-
-#ifdef FBCON_HAS_CFB32
- {
- "640x480-32", { /* Cybervision 32 bpp */
- 640, 480, 640, 480, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 31250, 160, 136, 82, 61, 88, 2,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "768x576-32", { /* Cybervision 32 bpp */
- 768, 576, 768, 576, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 29411, 144, 112, 32, 15, 64, 2,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "800x600-32", { /* Cybervision 32 bpp */
- 800, 600, 800, 600, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 28571, 168, 104, 22, 1, 48, 2,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "1024x768-32", { /* Cybervision 32 bpp */
- 1024, 768, 1024, 768, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "1152x886-32", { /* Cybervision 32 bpp */
- 1152, 886, 1152, 886, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 19230, 280, 168, 45, 1, 64, 10,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "1280x1024-32", { /* Cybervision 32 bpp */
- 1280, 1024, 1280, 1024, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
- 0, FB_VMODE_NONINTERLACED
- }
- }, {
- "1600x1200-32", { /* Cybervision 32 bpp */
- 1600, 1200, 1600, 1200, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
- 0, FB_VMODE_NONINTERLACED
- }
- },
-#endif
-
-/* interlaced modes */
-
-#ifdef FBCON_HAS_CFB8
- {
- "1024x768-8i", { /* Cybervision 8 bpp */
- 1024, 768, 1024, 768, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
- 0, FB_VMODE_INTERLACED
- }
- }, {
- "1280x1024-8i", { /* Cybervision 8 bpp */
- 1280, 1024, 1280, 1024, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
- 0, FB_VMODE_INTERLACED
- }
- }, {
- "1600x1200-8i", { /* Cybervision 8 bpp */
- 1600, 1200, 1600, 1200, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
- 0, FB_VMODE_INTERLACED
- }
- },
-#endif
-
-#ifdef FBCON_HAS_CFB16
- {
- "1024x768-16i", { /* Cybervision 16 bpp */
- 1024, 768, 1024, 768, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 20833, 272, 168, 39, 2, 72, 1,
- 0, FB_VMODE_INTERLACED
- }
- }, {
- "1280x1024-16i", { /* Cybervision 16 bpp */
- 1280, 1024, 1280, 1024, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
- 0, FB_VMODE_INTERLACED
- }
- }, {
- "1600x1200-16i", { /* Cybervision 16 bpp */
- 1600, 1200, 1600, 1200, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
- 0, FB_VMODE_INTERLACED
- }
- },
-#endif
-
-#ifdef FBCON_HAS_CFB32
- {
- "1024x768-32i", { /* Cybervision 32 bpp */
- 1024, 768, 1024, 768, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 22222, 216, 144, 39, 2, 72, 1,
- 0, FB_VMODE_INTERLACED
- }
- }, {
- "1280x1024-32i", { /* Cybervision 32 bpp */
- 1280, 1024, 1280, 1024, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {23, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 17857, 232, 232, 71, 15, 176, 12,
- 0, FB_VMODE_INTERLACED
- }
- }, {
- "1600x1200-32i", { /* Cybervision 32 bpp */
- 1600, 1200, 1600, 1200, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 13698, 336, 224, 77, 15, 176, 12,
- 0, FB_VMODE_INTERLACED
- }
- },
-#endif
-
-/* doublescan modes */
-
-#ifdef FBCON_HAS_CFB8
- {
- "320x240-8d", { /* Cybervision 8 bpp */
- 320, 240, 320, 240, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1,
- 0, FB_VMODE_DOUBLE
- }
- },
-#endif
-
-#ifdef FBCON_HAS_CFB16
- {
- "320x240-16d", { /* Cybervision 16 bpp */
- 320, 240, 320, 240, 0, 0, 16, 0,
- {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1,
- 0, FB_VMODE_DOUBLE
- }
- },
-#endif
-
-#ifdef FBCON_HAS_CFB32
- {
- "320x240-32d", { /* Cybervision 32 bpp */
- 320, 240, 320, 240, 0, 0, 32, 0,
- {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 0, 0},
- 0, 0, -1, -1, FB_ACCELF_TEXT, 59259, 80, 80, 45, 26, 32, 1,
- 0, FB_VMODE_DOUBLE
- }
- },
-#endif
-};
-
-#define NUM_TOTAL_MODES ARRAY_SIZE(virgefb_predefined)
-
-/*
- * Default to 800x600 for video=virge8:, virge16: or virge32:
- */
-
-#ifdef FBCON_HAS_CFB8
-#define VIRGE8_DEFMODE (2)
-#endif
-
-#ifdef FBCON_HAS_CFB16
-#define VIRGE16_DEFMODE (9)
-#endif
-
-#ifdef FBCON_HAS_CFB32
-#define VIRGE32_DEFMODE (16)
-#endif
-
-static struct fb_var_screeninfo virgefb_default;
-static int virgefb_inverse = 0;
-
-/*
- * Interface used by the world
- */
-
-int virgefb_setup(char*);
-static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-static int virgefb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int virgefb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-static int virgefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info);
-static int virgefb_blank(int blank, struct fb_info *info);
-
-/*
- * Interface to the low level console driver
- */
-
-int virgefb_init(void);
-static int virgefb_switch(int con, struct fb_info *info);
-static int virgefb_updatevar(int con, struct fb_info *info);
-
-/*
- * Text console acceleration
- */
-
-#ifdef FBCON_HAS_CFB8
-static struct display_switch fbcon_virge8;
-#endif
-
-#ifdef FBCON_HAS_CFB16
-static struct display_switch fbcon_virge16;
-#endif
-
-#ifdef FBCON_HAS_CFB32
-static struct display_switch fbcon_virge32;
-#endif
-
-/*
- * Hardware Specific Routines
- */
-
-static int virge_init(void);
-static int virgefb_encode_fix(struct fb_fix_screeninfo *fix,
- struct virgefb_par *par);
-static int virgefb_decode_var(struct fb_var_screeninfo *var,
- struct virgefb_par *par);
-static int virgefb_encode_var(struct fb_var_screeninfo *var,
- struct virgefb_par *par);
-static int virgefb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info);
-static void virgefb_gfx_on_off(int blank);
-static inline void virgefb_wait_for_idle(void);
-static void virgefb_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
- u_short width, u_short height, u_short stride, u_short depth);
-static void virgefb_RectFill(u_short x, u_short y, u_short width, u_short height,
- u_short color, u_short stride, u_short depth);
-
-/*
- * Internal routines
- */
-
-static void virgefb_get_par(struct virgefb_par *par);
-static void virgefb_set_par(struct virgefb_par *par);
-static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-static void virgefb_set_disp(int con, struct fb_info *info);
-static int virgefb_get_video_mode(const char *name);
-static void virgefb_set_video(struct fb_var_screeninfo *var);
-
-/*
- * Additions for Initialization
- */
-
-static void virgefb_load_video_mode(struct fb_var_screeninfo *video_mode);
-static int cv3d_has_4mb(void);
-static unsigned short virgefb_compute_clock(unsigned long freq);
-static inline unsigned char rattr(short);
-static inline unsigned char rseq(short);
-static inline unsigned char rcrt(short);
-static inline unsigned char rgfx(short);
-static inline void gfx_on_off(int toggle);
-static void virgefb_pci_init(void);
-
-/* -------------------- Hardware specific routines ------------------------- */
-
-/*
- * Functions for register access
- */
-
-/* Read attribute controller register */
-
-static inline unsigned char rattr(short idx)
-{
- volatile unsigned char rattr_tmp;
-
- rattr_tmp = rb_mmio(ACT_ADDRESS_RESET);
- wb_mmio(ACT_ADDRESS_W, idx);
- return (rb_mmio(ACT_ADDRESS_R));
-}
-
-/* Read sequencer register */
-
-static inline unsigned char rseq(short idx)
-{
- wb_mmio(SEQ_ADDRESS, idx);
- return (rb_mmio(SEQ_ADDRESS_R));
-}
-
-/* Read CRT controller register */
-
-static inline unsigned char rcrt(short idx)
-{
- wb_mmio(CRT_ADDRESS, idx);
- return (rb_mmio(CRT_ADDRESS_R));
-}
-
-/* Read graphics controller register */
-
-static inline unsigned char rgfx(short idx)
-{
- wb_mmio(GCT_ADDRESS, idx);
- return (rb_mmio(GCT_ADDRESS_R));
-}
-
-
-/*
- * Initialization
- */
-
-/* PCI init */
-
-void virgefb_pci_init(void) {
-
- DPRINTK("ENTER\n");
-
- SelectCFG;
-
- if (on_zorro2) {
- *((short *)(vgaio_regs + 0x00000010)) = 0;
- *((long *)(vgaio_regs + 0x00000004)) = 0x02000003;
- } else {
- *((short *)(vgaio_regs + 0x000e0010)) = 0;
- *((long *)(vgaio_regs + 0x000e0004)) = 0x02000003;
- }
-
- /* SelectIO is in wb_vgaio macro */
- wb_vgaio(SREG_VIDEO_SUBS_ENABLE, 0x01);
- /* SelectMMIO is in wb_vgaio macro */
-
- DPRINTK("EXIT\n");
-
- return;
-}
-
-/*
- * Initalize all mode independent regs, find mem size and clear mem
-*/
-
-static int virge_init(void)
-{
- int i;
- unsigned char tmp;
-
- DPRINTK("ENTER\n");
-
- virgefb_pci_init();
-
- wb_mmio(GREG_MISC_OUTPUT_W, 0x07); /* colour, ram enable, clk sel */
-
- wseq(SEQ_ID_UNLOCK_EXT, 0x06); /* unlock extensions */
- tmp = rb_mmio(GREG_MISC_OUTPUT_R);
- wcrt(CRT_ID_REGISTER_LOCK_1, 0x48); /* unlock CR2D to CR3F */
-
- wcrt(CRT_ID_BACKWAD_COMP_1, 0x00); /* irq disable */
-
- wcrt(CRT_ID_REGISTER_LOCK_2, 0xa5); /* unlock CR40 to CRFF and more */
- wcrt(CRT_ID_REGISTER_LOCK,0x00); /* unlock h and v timing */
- wcrt(CRT_ID_SYSTEM_CONFIG, 0x01); /* unlock enhanced programming registers */
-
- wb_mmio(GREG_FEATURE_CONTROL_W, 0x00);
-
- wcrt(CRT_ID_EXT_MISC_CNTL, 0x00); /* b2 = 0 to allow VDAC mmio access */
-#if 0
- /* write strap options ... ? */
- wcrt(CRT_ID_CONFIG_1, 0x08);
- wcrt(CRT_ID_CONFIG_2, 0xff); /* 0x0x2 bit needs to be set ?? */
- wcrt(CRT_ID_CONFIG_3, 0x0f);
- wcrt(CRT_ID_CONFIG_4, 0x1a);
-#endif
- wcrt(CRT_ID_EXT_MISC_CNTL_1, 0x82); /* PCI DE and software reset S3D engine */
- /* EXT_MISC_CNTL_1, CR66 bit 0 should be the same as bit 0 MR_ADVANCED_FUNCTION_CONTROL - check */
- wl_mmio(MR_ADVANCED_FUNCTION_CONTROL, 0x00000011); /* enhanced mode, linear addressing */
-
-/* crtc registers */
-
- wcrt(CRT_ID_PRESET_ROW_SCAN, 0x00);
-
- /* Disable h/w cursor */
-
- wcrt(CRT_ID_CURSOR_START, 0x00);
- wcrt(CRT_ID_CURSOR_END, 0x00);
- wcrt(CRT_ID_START_ADDR_HIGH, 0x00);
- wcrt(CRT_ID_START_ADDR_LOW, 0x00);
- wcrt(CRT_ID_CURSOR_LOC_HIGH, 0x00);
- wcrt(CRT_ID_CURSOR_LOC_LOW, 0x00);
- wcrt(CRT_ID_EXT_MODE, 0x00);
- wcrt(CRT_ID_HWGC_MODE, 0x00);
- wcrt(CRT_ID_HWGC_ORIGIN_X_HI, 0x00);
- wcrt(CRT_ID_HWGC_ORIGIN_X_LO, 0x00);
- wcrt(CRT_ID_HWGC_ORIGIN_Y_HI, 0x00);
- wcrt(CRT_ID_HWGC_ORIGIN_Y_LO, 0x00);
- i = rcrt(CRT_ID_HWGC_MODE);
- wcrt(CRT_ID_HWGC_FG_STACK, 0x00);
- wcrt(CRT_ID_HWGC_FG_STACK, 0x00);
- wcrt(CRT_ID_HWGC_FG_STACK, 0x00);
- wcrt(CRT_ID_HWGC_BG_STACK, 0x00);
- wcrt(CRT_ID_HWGC_BG_STACK, 0x00);
- wcrt(CRT_ID_HWGC_BG_STACK, 0x00);
- wcrt(CRT_ID_HWGC_START_AD_HI, 0x00);
- wcrt(CRT_ID_HWGC_START_AD_LO, 0x00);
- wcrt(CRT_ID_HWGC_DSTART_X, 0x00);
- wcrt(CRT_ID_HWGC_DSTART_Y, 0x00);
-
- wcrt(CRT_ID_UNDERLINE_LOC, 0x00);
-
- wcrt(CRT_ID_MODE_CONTROL, 0xe3);
- wcrt(CRT_ID_BACKWAD_COMP_2, 0x22); /* blank bdr bit 5 blanking only on 8 bit */
-
- wcrt(CRT_ID_EX_SYNC_1, 0x00);
-
- /* memory */
-
- wcrt(CRT_ID_EXT_SYS_CNTL_3, 0x00);
- wcrt(CRT_ID_MEMORY_CONF, 0x08); /* config enhanced map */
- wcrt(CRT_ID_EXT_MEM_CNTL_1, 0x08); /* MMIO Select (0x0c works as well)*/
- wcrt(CRT_ID_EXT_MEM_CNTL_2, 0x02); /* why 02 big endian 00 works ? */
- wcrt(CRT_ID_EXT_MEM_CNTL_4, 0x9f); /* config big endian - 0x00 ? */
- wcrt(CRT_ID_LAW_POS_HI, 0x00);
- wcrt(CRT_ID_LAW_POS_LO, 0x00);
- wcrt(CRT_ID_EXT_MISC_CNTL_1, 0x81);
- wcrt(CRT_ID_MISC_1, 0x90); /* must follow CRT_ID_EXT_MISC_CNTL_1 */
- wcrt(CRT_ID_LAW_CNTL, 0x13); /* force 4 Meg for test */
- if (cv3d_has_4mb()) {
- v_ram_size = 0x00400000;
- wcrt(CRT_ID_LAW_CNTL, 0x13); /* 4 MB */
- } else {
- v_ram_size = 0x00200000;
- wcrt(CRT_ID_LAW_CNTL, 0x12); /* 2 MB */
- }
-
- if (on_zorro2)
- v_ram_size -= 0x60000; /* we need some space for the registers */
-
- wcrt(CRT_ID_EXT_SYS_CNTL_4, 0x00);
- wcrt(CRT_ID_EXT_DAC_CNTL, 0x00); /* 0x10 for X11 cursor mode */
-
-/* sequencer registers */
-
- wseq(SEQ_ID_CLOCKING_MODE, 0x01); /* 8 dot clock */
- wseq(SEQ_ID_MAP_MASK, 0xff);
- wseq(SEQ_ID_CHAR_MAP_SELECT, 0x00);
- wseq(SEQ_ID_MEMORY_MODE, 0x02);
- wseq(SEQ_ID_RAMDAC_CNTL, 0x00);
- wseq(SEQ_ID_SIGNAL_SELECT, 0x00);
- wseq(SEQ_ID_EXT_SEQ_REG9, 0x00); /* MMIO and PIO reg access enabled */
- wseq(SEQ_ID_EXT_MISC_SEQ, 0x00);
- wseq(SEQ_ID_CLKSYN_CNTL_1, 0x00);
- wseq(SEQ_ID_EXT_SEQ, 0x00);
-
-/* graphic registers */
-
- wgfx(GCT_ID_SET_RESET, 0x00);
- wgfx(GCT_ID_ENABLE_SET_RESET, 0x00);
- wgfx(GCT_ID_COLOR_COMPARE, 0x00);
- wgfx(GCT_ID_DATA_ROTATE, 0x00);
- wgfx(GCT_ID_READ_MAP_SELECT, 0x00);
- wgfx(GCT_ID_GRAPHICS_MODE, 0x40);
- wgfx(GCT_ID_MISC, 0x01);
- wgfx(GCT_ID_COLOR_XCARE, 0x0f);
- wgfx(GCT_ID_BITMASK, 0xff);
-
-/* attribute registers */
-
- for(i = 0; i <= 15; i++)
- watr(ACT_ID_PALETTE0 + i, i);
- watr(ACT_ID_ATTR_MODE_CNTL, 0x41);
- watr(ACT_ID_OVERSCAN_COLOR, 0xff);
- watr(ACT_ID_COLOR_PLANE_ENA, 0x0f);
- watr(ACT_ID_HOR_PEL_PANNING, 0x00);
- watr(ACT_ID_COLOR_SELECT, 0x00);
-
- wb_mmio(VDAC_MASK, 0xff);
-
-/* init local cmap as greyscale levels */
-
- for (i = 0; i < 256; i++) {
- virgefb_colour_table [i][0] = i;
- virgefb_colour_table [i][1] = i;
- virgefb_colour_table [i][2] = i;
- }
-
-/* clear framebuffer memory */
-
- memset((char*)v_ram, 0x00, v_ram_size);
-
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/*
- * This function should fill in the `fix' structure based on the
- * values in the `par' structure.
- */
-
-static int virgefb_encode_fix(struct fb_fix_screeninfo *fix,
- struct virgefb_par *par)
-{
- DPRINTK("ENTER set video phys addr\n");
-
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strcpy(fix->id, virgefb_name);
- if (on_zorro2)
- fix->smem_start = v_ram_phys;
- switch (par->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- if (on_zorro2)
- Select_Zorro2_FrameBuffer(ENDIAN_BYTE);
- else
- fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_8);
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- if (on_zorro2)
- Select_Zorro2_FrameBuffer(ENDIAN_WORD);
- else
- fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_16);
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- if (on_zorro2)
- Select_Zorro2_FrameBuffer(ENDIAN_LONG);
- else
- fix->smem_start = (v_ram_phys + CYBMEM_OFFSET_32);
- break;
-#endif
- }
-
- fix->smem_len = v_ram_size;
- fix->mmio_start = mmio_regs_phys;
- fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */
-
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->type_aux = 0;
- if (par->var.bits_per_pixel == 8)
- fix->visual = FB_VISUAL_PSEUDOCOLOR;
- else
- fix->visual = FB_VISUAL_TRUECOLOR;
-
- fix->xpanstep = 0;
- fix->ypanstep = 0;
- fix->ywrapstep = 0;
- fix->line_length = par->var.xres_virtual*par->var.bits_per_pixel/8;
- fix->accel = FB_ACCEL_S3_VIRGE;
- DPRINTK("EXIT v_ram_phys = 0x%8.8lx\n", (unsigned long)fix->smem_start);
- return 0;
-}
-
-
-/*
- * Fill the `par' structure based on the values in `var'.
- * TODO: Verify and adjust values, return -EINVAL if bad.
- */
-
-static int virgefb_decode_var(struct fb_var_screeninfo *var,
- struct virgefb_par *par)
-{
- DPRINTK("ENTER\n");
- par->var.xres = var->xres;
- par->var.yres = var->yres;
- par->var.xres_virtual = var->xres_virtual;
- par->var.yres_virtual = var->yres_virtual;
- /* roundup and validate */
- par->var.xres = (par->var.xres+7) & ~7;
- par->var.xres_virtual = (par->var.xres_virtual+7) & ~7;
- if (par->var.xres_virtual < par->var.xres)
- par->var.xres_virtual = par->var.xres;
- if (par->var.yres_virtual < par->var.yres)
- par->var.yres_virtual = par->var.yres;
- par->var.xoffset = var->xoffset;
- par->var.yoffset = var->yoffset;
- par->var.bits_per_pixel = var->bits_per_pixel;
- if (par->var.bits_per_pixel <= 8)
- par->var.bits_per_pixel = 8;
- else if (par->var.bits_per_pixel <= 16)
- par->var.bits_per_pixel = 16;
- else
- par->var.bits_per_pixel = 32;
-#ifndef FBCON_HAS_CFB32
- if (par->var.bits_per_pixel == 32)
- par->var.bits_per_pixel = 16;
-#endif
-#ifndef FBCON_HAS_CFB16
- if (par->var.bits_per_pixel == 16)
- par->var.bits_per_pixel = 8;
-#endif
- par->var.grayscale = var->grayscale;
- par->var.red = var->red;
- par->var.green = var->green;
- par->var.blue = var->blue;
- par->var.transp = var->transp;
- par->var.nonstd = var->nonstd;
- par->var.activate = var->activate;
- par->var.height = var->height;
- par->var.width = var->width;
- if (var->accel_flags & FB_ACCELF_TEXT) {
- par->var.accel_flags = FB_ACCELF_TEXT;
- } else {
- par->var.accel_flags = 0;
- }
- par->var.pixclock = var->pixclock;
- par->var.left_margin = var->left_margin;
- par->var.right_margin = var->right_margin;
- par->var.upper_margin = var->upper_margin;
- par->var.lower_margin = var->lower_margin;
- par->var.hsync_len = var->hsync_len;
- par->var.vsync_len = var->vsync_len;
- par->var.sync = var->sync;
- par->var.vmode = var->vmode;
- DPRINTK("EXIT\n");
- return 0;
-}
-
-/*
- * Fill the `var' structure based on the values in `par' and maybe
- * other values read out of the hardware.
- */
-
-static int virgefb_encode_var(struct fb_var_screeninfo *var,
- struct virgefb_par *par)
-{
- DPRINTK("ENTER\n");
- memset(var, 0, sizeof(struct fb_var_screeninfo)); /* need this ? */
- var->xres = par->var.xres;
- var->yres = par->var.yres;
- var->xres_virtual = par->var.xres_virtual;
- var->yres_virtual = par->var.yres_virtual;
- var->xoffset = par->var.xoffset;
- var->yoffset = par->var.yoffset;
- var->bits_per_pixel = par->var.bits_per_pixel;
- var->grayscale = par->var.grayscale;
- var->red = par->var.red;
- var->green = par->var.green;
- var->blue = par->var.blue;
- var->transp = par->var.transp;
- var->nonstd = par->var.nonstd;
- var->activate = par->var.activate;
- var->height = par->var.height;
- var->width = par->var.width;
- var->accel_flags = par->var.accel_flags;
- var->pixclock = par->var.pixclock;
- var->left_margin = par->var.left_margin;
- var->right_margin = par->var.right_margin;
- var->upper_margin = par->var.upper_margin;
- var->lower_margin = par->var.lower_margin;
- var->hsync_len = par->var.hsync_len;
- var->vsync_len = par->var.vsync_len;
- var->sync = par->var.sync;
- var->vmode = par->var.vmode;
- DPRINTK("EXIT\n");
- return 0;
-}
-
-/*
- * Set a single color register. The values supplied are already
- * rounded down to the hardware's capabilities (according to the
- * entries in the var structure). Return != 0 for invalid regno.
- */
-
-static int virgefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
-{
- DPRINTK("ENTER\n");
- if (((current_par.var.bits_per_pixel==8) && (regno>255)) ||
- ((current_par.var.bits_per_pixel!=8) && (regno>15))) {
- DPRINTK("EXIT\n");
- return 1;
- }
- if (((current_par.var.bits_per_pixel==8) && (regno<256)) ||
- ((current_par.var.bits_per_pixel!=8) && (regno<16))) {
- virgefb_colour_table [regno][0] = red >> 10;
- virgefb_colour_table [regno][1] = green >> 10;
- virgefb_colour_table [regno][2] = blue >> 10;
- }
-
- switch (current_par.var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- wb_mmio(VDAC_ADDRESS_W, (unsigned char)regno);
- wb_mmio(VDAC_DATA, ((unsigned char)(red >> 10)));
- wb_mmio(VDAC_DATA, ((unsigned char)(green >> 10)));
- wb_mmio(VDAC_DATA, ((unsigned char)(blue >> 10)));
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- fbcon_cmap.cfb16[regno] =
- ((red & 0xf800) |
- ((green & 0xfc00) >> 5) |
- ((blue & 0xf800) >> 11));
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- fbcon_cmap.cfb32[regno] =
- /* transp = 0's or 1's ? */
- (((red & 0xff00) << 8) |
- ((green & 0xff00) >> 0) |
- ((blue & 0xff00) >> 8));
- break;
-#endif
- }
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/*
- * Read a single color register and split it into
- * colors/transparent. Return != 0 for invalid regno.
- */
-
-static int virgefb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info)
-{
- int t;
-
- DPRINTK("ENTER\n");
- if (regno > 255) {
- DPRINTK("EXIT\n");
- return 1;
- }
- if (((current_par.var.bits_per_pixel==8) && (regno<256)) ||
- ((current_par.var.bits_per_pixel!=8) && (regno<16))) {
-
- t = virgefb_colour_table [regno][0];
- *red = (t<<10) | (t<<4) | (t>>2);
- t = virgefb_colour_table [regno][1];
- *green = (t<<10) | (t<<4) | (t>>2);
- t = virgefb_colour_table [regno][2];
- *blue = (t<<10) | (t<<4) | (t>>2);
- }
- *transp = 0;
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/*
- * (Un)Blank the screen
- */
-
-static void virgefb_gfx_on_off(int blank)
-{
- DPRINTK("ENTER\n");
- gfx_on_off(blank);
- DPRINTK("EXIT\n");
-}
-
-/*
- * CV3D low-level support
- */
-
-
-static inline void wait_3d_fifo_slots(int n) /* WaitQueue */
-{
- do {
- mb();
- } while (((rl_mmio(MR_SUBSYSTEM_STATUS_R) >> 8) & 0x1f) < (n + 2));
-}
-
-static inline void virgefb_wait_for_idle(void) /* WaitIdle */
-{
- while(!(rl_mmio(MR_SUBSYSTEM_STATUS_R) & 0x2000)) ;
- blit_maybe_busy = 0;
-}
-
- /*
- * BitBLT - Through the Plane
- */
-
-static void virgefb_BitBLT(u_short curx, u_short cury, u_short destx, u_short desty,
- u_short width, u_short height, u_short stride, u_short depth)
-{
- unsigned int blitcmd = S3V_BITBLT | S3V_DRAW | S3V_BLT_COPY;
-
- switch (depth) {
-#ifdef FBCON_HAS_CFB8
- case 8 :
- blitcmd |= S3V_DST_8BPP;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16 :
- blitcmd |= S3V_DST_16BPP;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32 :
- /* 32 bit uses 2 by 16 bit values, see fbcon_virge32_bmove */
- blitcmd |= S3V_DST_16BPP;
- break;
-#endif
- }
-
- /* Set drawing direction */
- /* -Y, X maj, -X (default) */
- if (curx > destx) {
- blitcmd |= (1 << 25); /* Drawing direction +X */
- } else {
- curx += (width - 1);
- destx += (width - 1);
- }
-
- if (cury > desty) {
- blitcmd |= (1 << 26); /* Drawing direction +Y */
- } else {
- cury += (height - 1);
- desty += (height - 1);
- }
-
- wait_3d_fifo_slots(8); /* wait on fifo slots for 8 writes */
-
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- blit_maybe_busy = 1;
-
- wl_mmio(BLT_PATTERN_COLOR, 1); /* pattern fb color */
- wl_mmio(BLT_MONO_PATTERN_0, ~0);
- wl_mmio(BLT_MONO_PATTERN_1, ~0);
- wl_mmio(BLT_SIZE_X_Y, ((width << 16) | height));
- wl_mmio(BLT_SRC_X_Y, ((curx << 16) | cury));
- wl_mmio(BLT_DEST_X_Y, ((destx << 16) | desty));
- wl_mmio(BLT_SRC_DEST_STRIDE, (((stride << 16) | stride) /* & 0x0ff80ff8 */)); /* why is this needed now ? */
- wl_mmio(BLT_COMMAND_SET, blitcmd);
-}
-
-/*
- * Rectangle Fill Solid
- */
-
-static void virgefb_RectFill(u_short x, u_short y, u_short width, u_short height,
- u_short color, u_short stride, u_short depth)
-{
- unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW |
- S3V_BLT_CLEAR | S3V_MONO_PAT | (1 << 26) | (1 << 25);
-
- switch (depth) {
-#ifdef FBCON_HAS_CFB8
- case 8 :
- blitcmd |= S3V_DST_8BPP;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16 :
- blitcmd |= S3V_DST_16BPP;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32 :
- /* 32 bit uses 2 times 16 bit values, see fbcon_virge32_clear */
- blitcmd |= S3V_DST_16BPP;
- break;
-#endif
- }
-
- wait_3d_fifo_slots(5); /* wait on fifo slots for 5 writes */
-
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- blit_maybe_busy = 1;
-
- wl_mmio(BLT_PATTERN_COLOR, (color & 0xff));
- wl_mmio(BLT_SIZE_X_Y, ((width << 16) | height));
- wl_mmio(BLT_DEST_X_Y, ((x << 16) | y));
- wl_mmio(BLT_SRC_DEST_STRIDE, (((stride << 16) | stride) /* & 0x0ff80ff8 */));
- wl_mmio(BLT_COMMAND_SET, blitcmd);
-}
-
-/*
- * Move cursor to x, y
- */
-
-#if 0
-static void virgefb_move_cursor(u_short x, u_short y)
-{
- DPRINTK("Yuck .... MoveCursor on a 3D\n");
- return 0;
-}
-#endif
-
-/* -------------------- Interfaces to hardware functions -------------------- */
-
-static struct fb_hwswitch virgefb_hw_switch = {
- .init = virge_init,
- .encode_fix = virgefb_encode_fix,
- .decode_var = virgefb_decode_var,
- .encode_var = virgefb_encode_var,
- .getcolreg = virgefb_getcolreg,
- .blank = virgefb_gfx_on_off
-};
-
-
-/* -------------------- Generic routines ------------------------------------ */
-
-
-/*
- * Fill the hardware's `par' structure.
- */
-
-static void virgefb_get_par(struct virgefb_par *par)
-{
- DPRINTK("ENTER\n");
- if (current_par_valid) {
- *par = current_par;
- } else {
- fbhw->decode_var(&virgefb_default, par);
- }
- DPRINTK("EXIT\n");
-}
-
-
-static void virgefb_set_par(struct virgefb_par *par)
-{
- DPRINTK("ENTER\n");
- current_par = *par;
- current_par_valid = 1;
- DPRINTK("EXIT\n");
-}
-
-
-static void virgefb_set_video(struct fb_var_screeninfo *var)
-{
-/* Set clipping rectangle to current screen size */
-
- unsigned int clip;
-
- DPRINTK("ENTER\n");
- wait_3d_fifo_slots(4);
- clip = ((0 << 16) | (var->xres - 1));
- wl_mmio(BLT_CLIP_LEFT_RIGHT, clip);
- clip = ((0 << 16) | (var->yres - 1));
- wl_mmio(BLT_CLIP_TOP_BOTTOM, clip);
- wl_mmio(BLT_SRC_BASE, 0); /* seems we need to clear these two */
- wl_mmio(BLT_DEST_BASE, 0);
-
-/* Load the video mode defined by the 'var' data */
-
- virgefb_load_video_mode(var);
- DPRINTK("EXIT\n");
-}
-
-/*
-Merge these two functions, Geert's suggestion.
-static int virgefb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info);
-static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive);
-*/
-
-static int virgefb_do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
-{
- int err, activate;
- struct virgefb_par par;
-
- DPRINTK("ENTER\n");
- if ((err = fbhw->decode_var(var, &par))) {
- DPRINTK("EXIT\n");
- return (err);
- }
-
- activate = var->activate;
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
- virgefb_set_par(&par);
- fbhw->encode_var(var, &par);
- var->activate = activate;
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
- virgefb_set_video(var);
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/*
- * Get the Fixed Part of the Display
- */
-
-static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
-{
- struct virgefb_par par;
- int error = 0;
-
- DPRINTK("ENTER\n");
- if (con == -1)
- virgefb_get_par(&par);
- else
- error = fbhw->decode_var(&fb_display[con].var, &par);
-
- if (!error)
- error = fbhw->encode_fix(fix, &par);
- DPRINTK("EXIT\n");
- return(error);
-}
-
-
-/*
- * Get the User Defined Part of the Display
- */
-
-static int virgefb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- struct virgefb_par par;
- int error = 0;
-
- DPRINTK("ENTER\n");
- if (con == -1) {
- virgefb_get_par(&par);
- error = fbhw->encode_var(var, &par);
- disp.var = *var; /* ++Andre: don't know if this is the right place */
- } else {
- *var = fb_display[con].var;
- }
- DPRINTK("EXIT\n");
- return(error);
-}
-
-static void virgefb_set_disp(int con, struct fb_info *info)
-{
- struct fb_fix_screeninfo fix;
- struct display *display;
-
- DPRINTK("ENTER\n");
- if (con >= 0)
- display = &fb_display[con];
- else
- display = &disp; /* used during initialization */
-
- virgefb_get_fix(&fix, con, info);
- if (con == -1)
- con = 0;
- if(on_zorro2) {
- info->screen_base = (char*)v_ram;
- } else {
- switch (display->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- info->screen_base = (char*)(v_ram + CYBMEM_OFFSET_8);
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- info->screen_base = (char*)(v_ram + CYBMEM_OFFSET_16);
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- info->screen_base = (char*)(v_ram + CYBMEM_OFFSET_32);
- break;
-#endif
- }
- }
- display->visual = fix.visual;
- display->type = fix.type;
- display->type_aux = fix.type_aux;
- display->ypanstep = fix.ypanstep;
- display->ywrapstep = fix.ywrapstep;
- display->can_soft_blank = 1;
- display->inverse = virgefb_inverse;
- display->line_length = display->var.xres_virtual*
- display->var.bits_per_pixel/8;
-
- switch (display->var.bits_per_pixel) {
-#ifdef FBCON_HAS_CFB8
- case 8:
- if (display->var.accel_flags & FB_ACCELF_TEXT) {
- display->dispsw = &fbcon_virge8;
-#warning FIXME: We should reinit the graphics engine here
- } else
- display->dispsw = &fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- if (display->var.accel_flags & FB_ACCELF_TEXT) {
- display->dispsw = &fbcon_virge16;
- } else
- display->dispsw = &fbcon_cfb16;
- display->dispsw_data = &fbcon_cmap.cfb16;
- break;
-#endif
-#ifdef FBCON_HAS_CFB32
- case 32:
- if (display->var.accel_flags & FB_ACCELF_TEXT) {
- display->dispsw = &fbcon_virge32;
- } else
- display->dispsw = &fbcon_cfb32;
- display->dispsw_data = &fbcon_cmap.cfb32;
- break;
-#endif
- default:
- display->dispsw = &fbcon_dummy;
- break;
- }
- DPRINTK("EXIT v_ram virt = 0x%8.8lx\n",(unsigned long)display->screen_base);
-}
-
-
-/*
- * Set the User Defined Part of the Display
- */
-
-static int virgefb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
-{
- int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
-
- DPRINTK("ENTER\n");
-
- if ((err = virgefb_do_fb_set_var(var, con == info->currcon))) {
- DPRINTK("EXIT\n");
- return(err);
- }
- if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
- oldxres = fb_display[con].var.xres;
- oldyres = fb_display[con].var.yres;
- oldvxres = fb_display[con].var.xres_virtual;
- oldvyres = fb_display[con].var.yres_virtual;
- oldbpp = fb_display[con].var.bits_per_pixel;
- oldaccel = fb_display[con].var.accel_flags;
- fb_display[con].var = *var;
- if (oldxres != var->xres || oldyres != var->yres ||
- oldvxres != var->xres_virtual ||
- oldvyres != var->yres_virtual ||
- oldbpp != var->bits_per_pixel ||
- oldaccel != var->accel_flags) {
- virgefb_set_disp(con, info);
- if (fb_info.changevar)
- (*fb_info.changevar)(con);
- fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
- do_install_cmap(con, info);
- }
- }
- var->activate = 0;
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/*
- * Get the Colormap
- */
-
-static int virgefb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- DPRINTK("ENTER\n");
- if (con == info->currcon) { /* current console? */
- DPRINTK("EXIT - console is current console, fb_get_cmap\n");
- return(fb_get_cmap(cmap, kspc, fbhw->getcolreg, info));
- } else if (fb_display[con].cmap.len) { /* non default colormap? */
- DPRINTK("Use console cmap\n");
- fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- } else {
- DPRINTK("Use default cmap\n");
- fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel==8 ? 256 : 16),
- cmap, kspc ? 0 : 2);
- }
- DPRINTK("EXIT\n");
- return 0;
-}
-
-static struct fb_ops virgefb_ops = {
- .owner = THIS_MODULE,
- .fb_get_fix = virgefb_get_fix,
- .fb_get_var = virgefb_get_var,
- .fb_set_var = virgefb_set_var,
- .fb_get_cmap = virgefb_get_cmap,
- .fb_set_cmap = gen_set_cmap,
- .fb_setcolreg = virgefb_setcolreg,
- .fb_blank = virgefb_blank,
-};
-
-int __init virgefb_setup(char *options)
-{
- char *this_opt;
- fb_info.fontname[0] = '\0';
-
- DPRINTK("ENTER\n");
- if (!options || !*options) {
- DPRINTK("EXIT\n");
- return 0;
- }
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt)
- continue;
- if (!strcmp(this_opt, "inverse")) {
- virgefb_inverse = 1;
- fb_invert_cmaps();
- } else if (!strncmp(this_opt, "font:", 5))
- strcpy(fb_info.fontname, this_opt+5);
-#ifdef FBCON_HAS_CFB8
- else if (!strcmp (this_opt, "virge8")){
- virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var;
- }
-#endif
-#ifdef FBCON_HAS_CFB16
- else if (!strcmp (this_opt, "virge16")){
- virgefb_default = virgefb_predefined[VIRGE16_DEFMODE].var;
- }
-#endif
-#ifdef FBCON_HAS_CFB32
- else if (!strcmp (this_opt, "virge32")){
- virgefb_default = virgefb_predefined[VIRGE32_DEFMODE].var;
- }
-#endif
- else
- virgefb_get_video_mode(this_opt);
- }
-
- printk(KERN_INFO "mode : xres=%d, yres=%d, bpp=%d\n", virgefb_default.xres,
- virgefb_default.yres, virgefb_default.bits_per_pixel);
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/*
- * Get a Video Mode
- */
-
-static int __init virgefb_get_video_mode(const char *name)
-{
- int i;
-
- DPRINTK("ENTER\n");
- for (i = 0; i < NUM_TOTAL_MODES; i++) {
- if (!strcmp(name, virgefb_predefined[i].name)) {
- virgefb_default = virgefb_predefined[i].var;
- DPRINTK("EXIT\n");
- return(i);
- }
- }
- /* ++Andre: set virgefb default mode */
-
-/* prefer 16 bit depth, 8 if no 16, if no 8 or 16 use 32 */
-
-#ifdef FBCON_HAS_CFB32
- virgefb_default = virgefb_predefined[VIRGE32_DEFMODE].var;
-#endif
-#ifdef FBCON_HAS_CFB8
- virgefb_default = virgefb_predefined[VIRGE8_DEFMODE].var;
-#endif
-#ifdef FBCON_HAS_CFB16
- virgefb_default = virgefb_predefined[VIRGE16_DEFMODE].var;
-#endif
- DPRINTK("EXIT\n");
- return 0;
-}
-
-/*
- * Initialization
- */
-
-int __init virgefb_init(void)
-{
- struct virgefb_par par;
- unsigned long board_addr, board_size;
- struct zorro_dev *z = NULL;
-
- DPRINTK("ENTER\n");
-
- z = zorro_find_device(ZORRO_PROD_PHASE5_CYBERVISION64_3D, NULL);
- if (!z)
- return -ENODEV;
-
- board_addr = z->resource.start;
- if (board_addr < 0x01000000) {
-
- /* board running in Z2 space. This includes the video memory
- as well as the S3 register set */
-
- on_zorro2 = 1;
- board_size = 0x00400000;
-
- if (!request_mem_region(board_addr, board_size, "S3 ViRGE"))
- return -ENOMEM;
-
- v_ram_phys = board_addr;
- v_ram = ZTWO_VADDR(v_ram_phys);
- mmio_regs_phys = (unsigned long)(board_addr + 0x003c0000);
- vgaio_regs = (unsigned char *) ZTWO_VADDR(board_addr + 0x003c0000);
- mmio_regs = (unsigned char *)ZTWO_VADDR(mmio_regs_phys);
- vcode_switch_base = (unsigned long) ZTWO_VADDR(board_addr + 0x003a0000);
- printk(KERN_INFO "CV3D detected running in Z2 mode.\n");
-
- } else {
-
- /* board running in Z3 space. Separate video memory (3 apertures)
- and S3 register set */
-
- on_zorro2 = 0;
- board_size = 0x01000000;
-
- if (!request_mem_region(board_addr, board_size, "S3 ViRGE"))
- return -ENOMEM;
-
- v_ram_phys = board_addr + 0x04000000;
- v_ram = (unsigned long)ioremap(v_ram_phys, 0x01000000);
- mmio_regs_phys = board_addr + 0x05000000;
- vgaio_regs = (unsigned char *)ioremap(board_addr +0x0c000000, 0x00100000); /* includes PCI regs */
- mmio_regs = ioremap(mmio_regs_phys, 0x00010000);
- vcode_switch_base = (unsigned long)ioremap(board_addr + 0x08000000, 0x1000);
- printk(KERN_INFO "CV3D detected running in Z3 mode\n");
- }
-
-#if defined (VIRGEFBDEBUG)
- DPRINTK("board_addr : 0x%8.8lx\n",board_addr);
- DPRINTK("board_size : 0x%8.8lx\n",board_size);
- DPRINTK("mmio_regs_phy : 0x%8.8lx\n",mmio_regs_phys);
- DPRINTK("v_ram_phys : 0x%8.8lx\n",v_ram_phys);
- DPRINTK("vgaio_regs : 0x%8.8lx\n",(unsigned long)vgaio_regs);
- DPRINTK("mmio_regs : 0x%8.8lx\n",(unsigned long)mmio_regs);
- DPRINTK("v_ram : 0x%8.8lx\n",v_ram);
- DPRINTK("vcode sw base : 0x%8.8lx\n",vcode_switch_base);
-#endif
- fbhw = &virgefb_hw_switch;
- strcpy(fb_info.modename, virgefb_name);
- fb_info.changevar = NULL;
- fb_info.fbops = &virgefb_ops;
- fb_info.disp = &disp;
- fb_info.currcon = -1;
- fb_info.switch_con = &virgefb_switch;
- fb_info.updatevar = &virgefb_updatevar;
- fb_info.flags = FBINFO_FLAG_DEFAULT;
- fbhw->init();
- fbhw->decode_var(&virgefb_default, &par);
- fbhw->encode_var(&virgefb_default, &par);
- virgefb_do_fb_set_var(&virgefb_default, 1);
- virgefb_get_var(&fb_display[0].var, -1, &fb_info);
- virgefb_set_disp(-1, &fb_info);
- do_install_cmap(0, &fb_info);
-
- if (register_framebuffer(&fb_info) < 0) {
- #warning release resources
- printk(KERN_ERR "virgefb.c: register_framebuffer failed\n");
- DPRINTK("EXIT\n");
- goto out_unmap;
- }
-
- printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
- fb_info.node, fb_info.modename, v_ram_size>>10);
-
- /* TODO: This driver cannot be unloaded yet */
-
- DPRINTK("EXIT\n");
- return 0;
-
-out_unmap:
- if (board_addr >= 0x01000000) {
- if (v_ram)
- iounmap((void*)v_ram);
- if (vgaio_regs)
- iounmap(vgaio_regs);
- if (mmio_regs)
- iounmap(mmio_regs);
- if (vcode_switch_base)
- iounmap((void*)vcode_switch_base);
- v_ram = vcode_switch_base = 0;
- vgaio_regs = mmio_regs = NULL;
- }
- return -EINVAL;
-}
-
-
-static int virgefb_switch(int con, struct fb_info *info)
-{
- DPRINTK("ENTER\n");
- /* Do we have to save the colormap? */
- if (fb_display[info->currcon].cmap.len)
- fb_get_cmap(&fb_display[info->currcon].cmap, 1,
- fbhw->getcolreg, info);
- virgefb_do_fb_set_var(&fb_display[con].var, 1);
- info->currcon = con;
- /* Install new colormap */
- do_install_cmap(con, info);
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/*
- * Update the `var' structure (called by fbcon.c)
- *
- * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
- * Since it's called by a kernel driver, no range checking is done.
- */
-
-static int virgefb_updatevar(int con, struct fb_info *info)
-{
- DPRINTK("ENTER\n");
- return 0;
- DPRINTK("EXIT\n");
-}
-
-/*
- * Blank the display.
- */
-
-static int virgefb_blank(int blank, struct fb_info *info)
-{
- DPRINTK("ENTER\n");
- fbhw->blank(blank);
- DPRINTK("EXIT\n");
- return 0;
-}
-
-
-/*
- * Text console acceleration
- */
-
-#ifdef FBCON_HAS_CFB8
-static void fbcon_virge8_bmove(struct display *p, int sy, int sx, int dy,
- int dx, int height, int width)
-{
- sx *= 8; dx *= 8; width *= 8;
- virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
- (u_short)(dy*fontheight(p)), (u_short)width,
- (u_short)(height*fontheight(p)), (u_short)p->next_line, 8);
-}
-
-static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- unsigned char bg;
-
- sx *= 8; width *= 8;
- bg = attr_bgcol_ec(p,conp);
- virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
- (u_short)width, (u_short)(height*fontheight(p)),
- (u_short)bg, (u_short)p->next_line, 8);
-}
-
-static void fbcon_virge8_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb8_putc(conp, p, c, yy, xx);
-}
-
-static void fbcon_virge8_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
-}
-
-static void fbcon_virge8_revc(struct display *p, int xx, int yy)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb8_revc(p, xx, yy);
-}
-
-static void fbcon_virge8_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb8_clear_margins(conp, p, bottom_only);
-}
-
-static struct display_switch fbcon_virge8 = {
- .setup = fbcon_cfb8_setup,
- .bmove = fbcon_virge8_bmove,
- .clear = fbcon_virge8_clear,
- .putc = fbcon_virge8_putc,
- .putcs = fbcon_virge8_putcs,
- .revc = fbcon_virge8_revc,
- .clear_margins = fbcon_virge8_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-
-#ifdef FBCON_HAS_CFB16
-static void fbcon_virge16_bmove(struct display *p, int sy, int sx, int dy,
- int dx, int height, int width)
-{
- sx *= 8; dx *= 8; width *= 8;
- virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
- (u_short)(dy*fontheight(p)), (u_short)width,
- (u_short)(height*fontheight(p)), (u_short)p->next_line, 16);
-}
-
-static void fbcon_virge16_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- unsigned char bg;
-
- sx *= 8; width *= 8;
- bg = attr_bgcol_ec(p,conp);
- virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
- (u_short)width, (u_short)(height*fontheight(p)),
- (u_short)bg, (u_short)p->next_line, 16);
-}
-
-static void fbcon_virge16_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb16_putc(conp, p, c, yy, xx);
-}
-
-static void fbcon_virge16_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
-}
-
-static void fbcon_virge16_revc(struct display *p, int xx, int yy)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb16_revc(p, xx, yy);
-}
-
-static void fbcon_virge16_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb16_clear_margins(conp, p, bottom_only);
-}
-
-static struct display_switch fbcon_virge16 = {
- .setup = fbcon_cfb16_setup,
- .bmove = fbcon_virge16_bmove,
- .clear = fbcon_virge16_clear,
- .putc = fbcon_virge16_putc,
- .putcs = fbcon_virge16_putcs,
- .revc = fbcon_virge16_revc,
- .clear_margins = fbcon_virge16_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-
-#ifdef FBCON_HAS_CFB32
-static void fbcon_virge32_bmove(struct display *p, int sy, int sx, int dy,
- int dx, int height, int width)
-{
- sx *= 16; dx *= 16; width *= 16; /* doubled these values to do 32 bit blit */
- virgefb_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
- (u_short)(dy*fontheight(p)), (u_short)width,
- (u_short)(height*fontheight(p)), (u_short)p->next_line, 16);
-}
-
-static void fbcon_virge32_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
-{
- unsigned char bg;
-
- sx *= 16; width *= 16; /* doubled these values to do 32 bit blit */
- bg = attr_bgcol_ec(p,conp);
- virgefb_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
- (u_short)width, (u_short)(height*fontheight(p)),
- (u_short)bg, (u_short)p->next_line, 16);
-}
-
-static void fbcon_virge32_putc(struct vc_data *conp, struct display *p, int c, int yy,
- int xx)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb32_putc(conp, p, c, yy, xx);
-}
-
-static void fbcon_virge32_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
-}
-
-static void fbcon_virge32_revc(struct display *p, int xx, int yy)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb32_revc(p, xx, yy);
-}
-
-static void fbcon_virge32_clear_margins(struct vc_data *conp, struct display *p,
- int bottom_only)
-{
- if (blit_maybe_busy)
- virgefb_wait_for_idle();
- fbcon_cfb32_clear_margins(conp, p, bottom_only);
-}
-
-static struct display_switch fbcon_virge32 = {
- .setup = fbcon_cfb32_setup,
- .bmove = fbcon_virge32_bmove,
- .clear = fbcon_virge32_clear,
- .putc = fbcon_virge32_putc,
- .putcs = fbcon_virge32_putcs,
- .revc = fbcon_virge32_revc,
- .clear_margins = fbcon_virge32_clear_margins,
- .fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
- return virgefb_init();
-}
-#endif /* MODULE */
-
-static int cv3d_has_4mb(void)
-{
- /* cyberfb version didn't work, neither does this (not reliably)
- forced to return 4MB */
-#if 0
- volatile unsigned long *t0, *t2;
-#endif
- DPRINTK("ENTER\n");
-#if 0
- /* write patterns in memory and test if they can be read */
- t0 = (volatile unsigned long *)v_ram;
- t2 = (volatile unsigned long *)(v_ram + 0x00200000);
- *t0 = 0x87654321;
- *t2 = 0x12345678;
-
- if (*t0 != 0x87654321) {
- /* read of first location failed */
- DPRINTK("EXIT - 0MB !\n");
- return 0;
- }
-
- if (*t2 == 0x87654321) {
- /* should read 0x12345678 if 4MB */
- DPRINTK("EXIT - 2MB(a) \n");
- return 0;
- }
-
- if (*t2 != 0x12345678) {
- /* upper 2MB read back match failed */
- DPRINTK("EXIT - 2MB(b)\n");
- return 0;
- }
-
- /* may have 4MB */
-
- *t2 = 0xAAAAAAAA;
-
- if(*t2 != 0xAAAAAAAA) {
- /* upper 2MB read back match failed */
- DPRINTK("EXIT - 2MB(c)\n");
- return 0;
- }
-
- *t2 = 0x55555555;
-
- if(*t2 != 0x55555555) {
- /* upper 2MB read back match failed */
- DPRINTK("EXIT - 2MB(d)\n");
- return 0;
- }
-
-#endif
- DPRINTK("EXIT - 4MB\n");
- return 1;
-}
-
-
-/*
- * Computes M, N, and R pll params for freq arg.
- * Returns 16 bits - hi 0MMMMMM lo 0RRNNNNN
- */
-
-#define REFCLOCK 14318000
-
-static unsigned short virgefb_compute_clock(unsigned long freq)
-{
-
- unsigned char m, n, r, rpwr;
- unsigned long diff, ftry, save = ~0UL;
- unsigned short mnr;
-
- DPRINTK("ENTER\n");
-
- for (r = 0, rpwr = 1 ; r < 4 ; r++, rpwr *= 2) {
- if ((135000000 <= (rpwr * freq)) && ((rpwr * freq) <= 270000000)) {
- for (n = 1 ; n < 32 ; n++) {
- m = ((freq * (n + 2) * rpwr)/REFCLOCK) - 2;
- if (m == 0 || m >127)
- break;
- ftry = ((REFCLOCK / (n + 2)) * (m + 2)) / rpwr;
- if (ftry > freq)
- diff = ftry - freq;
- else
- diff = freq - ftry;
- if (diff < save) {
- save = diff;
- mnr = (m << 8) | (r<<5) | (n & 0x7f);
- }
- }
- }
- }
- if (save == ~0UL)
- printk("Can't compute clock PLL values for %ld Hz clock\n", freq);
- DPRINTK("EXIT\n");
- return(mnr);
-}
-
-static void virgefb_load_video_mode(struct fb_var_screeninfo *video_mode)
-{
- unsigned char lace, dblscan, tmp;
- unsigned short mnr;
- unsigned short HT, HDE, HBS, HBW, HSS, HSW;
- unsigned short VT, VDE, VBS, VBW, VSS, VSW;
- unsigned short SCO;
- int cr11;
- int cr67;
- int hmul;
- int xres, xres_virtual, hfront, hsync, hback;
- int yres, vfront, vsync, vback;
- int bpp;
- int i;
- long freq;
-
- DPRINTK("ENTER : %dx%d-%d\n",video_mode->xres, video_mode->yres,
- video_mode->bits_per_pixel);
-
- bpp = video_mode->bits_per_pixel;
- xres = video_mode->xres;
- xres_virtual = video_mode->xres_virtual;
- hfront = video_mode->right_margin;
- hsync = video_mode->hsync_len;
- hback = video_mode->left_margin;
-
- lace = 0;
- dblscan = 0;
-
- if (video_mode->vmode & FB_VMODE_DOUBLE) {
- yres = video_mode->yres * 2;
- vfront = video_mode->lower_margin * 2;
- vsync = video_mode->vsync_len * 2;
- vback = video_mode->upper_margin * 2;
- dblscan = 1;
- } else if (video_mode->vmode & FB_VMODE_INTERLACED) {
- yres = (video_mode->yres + 1) / 2;
- vfront = (video_mode->lower_margin + 1) / 2;
- vsync = (video_mode->vsync_len + 1) / 2;
- vback = (video_mode->upper_margin + 1) / 2;
- lace = 1;
- } else {
- yres = video_mode->yres;
- vfront = video_mode->lower_margin;
- vsync = video_mode->vsync_len;
- vback = video_mode->upper_margin;
- }
-
- switch (bpp) {
- case 8:
- video_mode->red.offset = 0;
- video_mode->green.offset = 0;
- video_mode->blue.offset = 0;
- video_mode->transp.offset = 0;
- video_mode->red.length = 8;
- video_mode->green.length = 8;
- video_mode->blue.length = 8;
- video_mode->transp.length = 0;
- hmul = 1;
- cr67 = 0x00;
- SCO = xres_virtual / 8;
- break;
- case 16:
- video_mode->red.offset = 11;
- video_mode->green.offset = 5;
- video_mode->blue.offset = 0;
- video_mode->transp.offset = 0;
- video_mode->red.length = 5;
- video_mode->green.length = 6;
- video_mode->blue.length = 5;
- video_mode->transp.length = 0;
- hmul = 2;
- cr67 = 0x50;
- SCO = xres_virtual / 4;
- break;
- case 32:
- video_mode->red.offset = 16;
- video_mode->green.offset = 8;
- video_mode->blue.offset = 0;
- video_mode->transp.offset = 24;
- video_mode->red.length = 8;
- video_mode->green.length = 8;
- video_mode->blue.length = 8;
- video_mode->transp.length = 8;
- hmul = 1;
- cr67 = 0xd0;
- SCO = xres_virtual / 2;
- break;
- }
-
- HT = (((xres + hfront + hsync + hback) / 8) * hmul) - 5;
- HDE = ((xres / 8) * hmul) - 1;
- HBS = (xres / 8) * hmul;
- HSS = ((xres + hfront) / 8) * hmul;
- HSW = (hsync / 8) * hmul;
- HBW = (((hfront + hsync + hback) / 8) * hmul) - 2;
-
- VT = yres + vfront + vsync + vback - 2;
- VDE = yres - 1;
- VBS = yres - 1;
- VSS = yres + vfront;
- VSW = vsync;
- VBW = vfront + vsync + vback - 2;
-
-#ifdef VIRGEFBDEBUG
- DPRINTK("HDE : 0x%4.4x, %4.4d\n", HDE, HDE);
- DPRINTK("HBS : 0x%4.4x, %4.4d\n", HBS, HBS);
- DPRINTK("HSS : 0x%4.4x, %4.4d\n", HSS, HSS);
- DPRINTK("HSW : 0x%4.4x, %4.4d\n", HSW, HSW);
- DPRINTK("HBW : 0x%4.4x, %4.4d\n", HBW, HBW);
- DPRINTK("HSS + HSW : 0x%4.4x, %4.4d\n", HSS+HSW, HSS+HSW);
- DPRINTK("HBS + HBW : 0x%4.4x, %4.4d\n", HBS+HBW, HBS+HBW);
- DPRINTK("HT : 0x%4.4x, %4.4d\n", HT, HT);
- DPRINTK("VDE : 0x%4.4x, %4.4d\n", VDE, VDE);
- DPRINTK("VBS : 0x%4.4x, %4.4d\n", VBS, VBS);
- DPRINTK("VSS : 0x%4.4x, %4.4d\n", VSS, VSS);
- DPRINTK("VSW : 0x%4.4x, %4.4d\n", VSW, VSW);
- DPRINTK("VBW : 0x%4.4x, %4.4d\n", VBW, VBW);
- DPRINTK("VT : 0x%4.4x, %4.4d\n", VT, VT);
-#endif
-
-/* turn gfx off, don't mess up the display */
-
- gfx_on_off(1);
-
-/* H and V sync polarity */
-
- tmp = rb_mmio(GREG_MISC_OUTPUT_R) & 0x2f; /* colour, ram enable, clk sr12/s13 sel */
- if (!(video_mode->sync & FB_SYNC_HOR_HIGH_ACT))
- tmp |= 0x40; /* neg H sync polarity */
- if (!(video_mode->sync & FB_SYNC_VERT_HIGH_ACT))
- tmp |= 0x80; /* neg V sync polarity */
- tmp |= 0x0c; /* clk from sr12/sr13 */
- wb_mmio(GREG_MISC_OUTPUT_W, tmp);
-
-/* clocks */
-
- wseq(SEQ_ID_BUS_REQ_CNTL, 0xc0); /* 2 clk mem wr and /RAS1 */
- wseq(SEQ_ID_CLKSYN_CNTL_2, 0x80); /* b7 is 2 mem clk wr */
- mnr = virgefb_compute_clock(MEMCLOCK);
- DPRINTK("mem clock %d, m %d, n %d, r %d.\n", MEMCLOCK, ((mnr>>8)&0x7f), (mnr&0x1f), ((mnr >> 5)&0x03));
- wseq(SEQ_ID_MCLK_LO, (mnr & 0x7f));
- wseq(SEQ_ID_MCLK_HI, ((mnr & 0x7f00) >> 8));
- freq = (1000000000 / video_mode->pixclock) * 1000; /* pixclock is in ps ... convert to Hz */
- mnr = virgefb_compute_clock(freq);
- DPRINTK("dot clock %ld, m %d, n %d, r %d.\n", freq, ((mnr>>8)&0x7f), (mnr&0x1f), ((mnr>>5)&0x03));
- wseq(SEQ_ID_DCLK_LO, (mnr & 0x7f));
- wseq(SEQ_ID_DCLK_HI, ((mnr & 0x7f00) >> 8));
- wseq(SEQ_ID_CLKSYN_CNTL_2, 0xa0);
- wseq(SEQ_ID_CLKSYN_CNTL_2, 0x80);
- udelay(100);
-
-/* load display parameters into board */
-
- /* not sure about sync and blanking extensions bits in cr5d and cr5 */
-
- wcrt(CRT_ID_EXT_HOR_OVF, /* 0x5d */
- ((HT & 0x100) ? 0x01 : 0x00) |
- ((HDE & 0x100) ? 0x02 : 0x00) |
- ((HBS & 0x100) ? 0x04 : 0x00) |
- /* (((HBS + HBW) & 0x40) ? 0x08 : 0x00) | */
- ((HSS & 0x100) ? 0x10 : 0x00) |
- /* (((HSS + HSW) & 0x20) ? 0x20 : 0x00) | */
- ((HSW >= 0x20) ? 0x20 : 0x00) |
- (((HT-5) & 0x100) ? 0x40 : 0x00));
-
- wcrt(CRT_ID_EXT_VER_OVF, /* 0x5e */
- ((VT & 0x400) ? 0x01 : 0x00) |
- ((VDE & 0x400) ? 0x02 : 0x00) |
- ((VBS & 0x400) ? 0x04 : 0x00) |
- ((VSS & 0x400) ? 0x10 : 0x00) |
- 0x40); /* line compare */
-
- wcrt(CRT_ID_START_VER_RETR, VSS);
- cr11 = rcrt(CRT_ID_END_VER_RETR) | 0x20; /* vert interrupt flag */
- wcrt(CRT_ID_END_VER_RETR, ((cr11 & 0x20) | ((VSS + VSW) & 0x0f))); /* keeps vert irq enable state, also has unlock bit cr0 to 7 */
- wcrt(CRT_ID_VER_DISP_ENA_END, VDE);
- wcrt(CRT_ID_START_VER_BLANK, VBS);
- wcrt(CRT_ID_END_VER_BLANK, VBS + VBW); /* might be +/- 1 out */
- wcrt(CRT_ID_HOR_TOTAL, HT);
- wcrt(CRT_ID_DISPLAY_FIFO, HT - 5);
- wcrt(CRT_ID_BACKWAD_COMP_3, 0x10); /* enable display fifo */
- wcrt(CRT_ID_HOR_DISP_ENA_END, HDE);
- wcrt(CRT_ID_START_HOR_BLANK , HBS);
- wcrt(CRT_ID_END_HOR_BLANK, (HBS + HBW) & 0x1f);
- wcrt(CRT_ID_START_HOR_RETR, HSS);
- wcrt(CRT_ID_END_HOR_RETR, /* cr5 */
- ((HSS + HSW) & 0x1f) |
- (((HBS + HBW) & 0x20) ? 0x80 : 0x00));
- wcrt(CRT_ID_VER_TOTAL, VT);
- wcrt(CRT_ID_OVERFLOW,
- ((VT & 0x100) ? 0x01 : 0x00) |
- ((VDE & 0x100) ? 0x02 : 0x00) |
- ((VSS & 0x100) ? 0x04 : 0x00) |
- ((VBS & 0x100) ? 0x08 : 0x00) |
- 0x10 |
- ((VT & 0x200) ? 0x20 : 0x00) |
- ((VDE & 0x200) ? 0x40 : 0x00) |
- ((VSS & 0x200) ? 0x80 : 0x00));
- wcrt(CRT_ID_MAX_SCAN_LINE,
- (dblscan ? 0x80 : 0x00) |
- 0x40 |
- ((VBS & 0x200) ? 0x20 : 0x00));
- wcrt(CRT_ID_LINE_COMPARE, 0xff);
- wcrt(CRT_ID_LACE_RETR_START, HT / 2); /* (HT-5)/2 ? */
- wcrt(CRT_ID_LACE_CONTROL, (lace ? 0x20 : 0x00));
-
- wcrt(CRT_ID_SCREEN_OFFSET, SCO);
- wcrt(CRT_ID_EXT_SYS_CNTL_2, (SCO >> 4) & 0x30 );
-
- /* wait for vert sync before cr67 update */
-
- for (i=0; i < 10000; i++) {
- udelay(10);
- mb();
- if (rb_mmio(GREG_INPUT_STATUS1_R) & 0x08)
- break;
- }
-
- wl_mmio(0x8200, 0x0000c000); /* fifo control (0x00110400 ?) */
- wcrt(CRT_ID_EXT_MISC_CNTL_2, cr67);
-
-/* enable video */
-
- tmp = rb_mmio(ACT_ADDRESS_RESET);
- wb_mmio(ACT_ADDRESS_W, ((bpp == 8) ? 0x20 : 0x00)); /* set b5, ENB PLT in attr idx reg) */
- tmp = rb_mmio(ACT_ADDRESS_RESET);
-
-/* turn gfx on again */
-
- gfx_on_off(0);
-
-/* pass-through */
-
- SetVSwitch(1); /* cv3d */
-
- DUMP;
- DPRINTK("EXIT\n");
-}
-
-static inline void gfx_on_off(int toggle)
-{
- unsigned char tmp;
-
- DPRINTK("ENTER gfx %s\n", (toggle ? "off" : "on"));
-
- toggle = (toggle & 0x01) << 5;
- tmp = rseq(SEQ_ID_CLOCKING_MODE) & (~(0x01 << 5));
- wseq(SEQ_ID_CLOCKING_MODE, tmp | toggle);
-
- DPRINTK("EXIT\n");
-}
-
-#if defined (VIRGEFBDUMP)
-
-/*
- * Dump board registers
- */
-
-static void cv64_dump(void)
-{
- int i;
- u8 c, b;
- u16 w;
- u32 l;
-
- /* crt, seq, gfx and atr regs */
-
- SelectMMIO;
-
- printk("\n");
- for (i = 0; i <= 0x6f; i++) {
- wb_mmio(CRT_ADDRESS, i);
- printk("crt idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(CRT_ADDRESS_R));
- }
- for (i = 0; i <= 0x1c; i++) {
- wb_mmio(SEQ_ADDRESS, i);
- printk("seq idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(SEQ_ADDRESS_R));
- }
- for (i = 0; i <= 8; i++) {
- wb_mmio(GCT_ADDRESS, i);
- printk("gfx idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(GCT_ADDRESS_R));
- }
- for (i = 0; i <= 0x14; i++) {
- c = rb_mmio(ACT_ADDRESS_RESET);
- wb_mmio(ACT_ADDRESS_W, i);
- printk("atr idx : 0x%2.2x : 0x%2.2x\n", i, rb_mmio(ACT_ADDRESS_R));
- }
-
- /* re-enable video access to palette */
-
- c = rb_mmio(ACT_ADDRESS_RESET);
- udelay(10);
- wb_mmio(ACT_ADDRESS_W, 0x20);
- c = rb_mmio(ACT_ADDRESS_RESET);
- udelay(10);
-
- /* general regs */
-
- printk("0x3cc(w 0x3c2) : 0x%2.2x\n", rb_mmio(0x3cc)); /* GREG_MISC_OUTPUT READ */
- printk("0x3c2(-------) : 0x%2.2x\n", rb_mmio(0x3c2)); /* GREG_INPUT_STATUS 0 READ */
- printk("0x3c3(w 0x3c3) : 0x%2.2x\n", rb_vgaio(0x3c3)); /* GREG_VIDEO_SUBS_ENABLE */
- printk("0x3ca(w 0x3da) : 0x%2.2x\n", rb_vgaio(0x3ca)); /* GREG_FEATURE_CONTROL read */
- printk("0x3da(-------) : 0x%2.2x\n", rb_mmio(0x3da)); /* GREG_INPUT_STATUS 1 READ */
-
- /* engine regs */
-
- for (i = 0x8180; i <= 0x8200; i = i + 4)
- printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
-
- i = 0x8504;
- printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
- i = 0x850c;
- printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
- for (i = 0xa4d4; i <= 0xa50c; i = i + 4)
- printk("0x%8.8x : 0x%8.8x\n", i, rl_mmio(i));
-
- /* PCI regs */
-
- SelectCFG;
-
- for (c = 0; c < 0x08; c = c + 2) {
- w = (*((u16 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 2)));
- printk("pci 0x%2.2x : 0x%4.4x\n", c, w);
- }
- c = 8;
- l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)))));
- printk("pci 0x%2.2x : 0x%8.8x\n", c, l);
- c = 0x0d;
- b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3)));
- printk("pci 0x%2.2x : 0x%2.2x\n", c, b);
- c = 0x10;
- l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)))));
- printk("pci 0x%2.2x : 0x%8.8x\n", c, l);
- c = 0x30;
- l = (*((u32 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)))));
- printk("pci 0x%2.2x : 0x%8.8x\n", c, l);
- c = 0x3c;
- b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3)));
- printk("pci 0x%2.2x : 0x%2.2x\n", c, b);
- c = 0x3d;
- b = (*((u8 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 3)));
- printk("pci 0x%2.2x : 0x%2.2x\n", c, b);
- c = 0x3e;
- w = (*((u16 *)((u32)(vgaio_regs + c + (on_zorro2 ? 0 : 0x000e0000)) ^ 2)));
- printk("pci 0x%2.2x : 0x%4.4x\n", c, w);
- SelectMMIO;
-}
-#endif
diff --git a/drivers/video/virgefb.h b/drivers/video/virgefb.h
deleted file mode 100644
index 157d66deb244..000000000000
--- a/drivers/video/virgefb.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * linux/drivers/video/virgefb.h -- CyberVision64 definitions for the
- * text console driver.
- *
- * Copyright (c) 1998 Alan Bair
- *
- * This file is based on the initial port to Linux of grf_cvreg.h:
- *
- * Copyright (c) 1997 Antonio Santos
- *
- * The original work is from the NetBSD CyberVision 64 framebuffer driver
- * and support files (grf_cv.c, grf_cvreg.h, ite_cv.c):
- * Permission to use the source of this driver was obtained from the
- * author Michael Teske by Alan Bair.
- *
- * Copyright (c) 1995 Michael Teske
- *
- * History:
- *
- *
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-/* Enhanced register mapping (MMIO mode) */
-
-#define S3_CRTC_ADR 0x03d4
-#define S3_CRTC_DATA 0x03d5
-
-#define S3_REG_LOCK2 0x39
-#define S3_HGC_MODE 0x45
-
-#define S3_HWGC_ORGX_H 0x46
-#define S3_HWGC_ORGX_L 0x47
-#define S3_HWGC_ORGY_H 0x48
-#define S3_HWGC_ORGY_L 0x49
-#define S3_HWGC_DX 0x4e
-#define S3_HWGC_DY 0x4f
-
-#define S3_LAW_CTL 0x58
-
-/**************************************************/
-
-/*
- * Defines for the used register addresses (mw)
- *
- * NOTE: There are some registers that have different addresses when
- * in mono or color mode. We only support color mode, and thus
- * some addresses won't work in mono-mode!
- *
- * General and VGA-registers taken from retina driver. Fixed a few
- * bugs in it. (SR and GR read address is Port + 1, NOT Port)
- *
- */
-
-/* General Registers: */
-#define GREG_MISC_OUTPUT_R 0x03CC
-#define GREG_MISC_OUTPUT_W 0x03C2
-#define GREG_FEATURE_CONTROL_R 0x03CA
-#define GREG_FEATURE_CONTROL_W 0x03DA
-#define GREG_INPUT_STATUS0_R 0x03C2
-#define GREG_INPUT_STATUS1_R 0x03DA
-
-/* Setup Registers: */
-#define SREG_VIDEO_SUBS_ENABLE 0x03C3 /* virge */
-
-/* Attribute Controller: */
-#define ACT_ADDRESS 0x03C0
-#define ACT_ADDRESS_R 0x03C1
-#define ACT_ADDRESS_W 0x03C0
-#define ACT_ADDRESS_RESET 0x03DA
-#define ACT_ID_PALETTE0 0x00
-#define ACT_ID_PALETTE1 0x01
-#define ACT_ID_PALETTE2 0x02
-#define ACT_ID_PALETTE3 0x03
-#define ACT_ID_PALETTE4 0x04
-#define ACT_ID_PALETTE5 0x05
-#define ACT_ID_PALETTE6 0x06
-#define ACT_ID_PALETTE7 0x07
-#define ACT_ID_PALETTE8 0x08
-#define ACT_ID_PALETTE9 0x09
-#define ACT_ID_PALETTE10 0x0A
-#define ACT_ID_PALETTE11 0x0B
-#define ACT_ID_PALETTE12 0x0C
-#define ACT_ID_PALETTE13 0x0D
-#define ACT_ID_PALETTE14 0x0E
-#define ACT_ID_PALETTE15 0x0F
-#define ACT_ID_ATTR_MODE_CNTL 0x10
-#define ACT_ID_OVERSCAN_COLOR 0x11
-#define ACT_ID_COLOR_PLANE_ENA 0x12
-#define ACT_ID_HOR_PEL_PANNING 0x13
-#define ACT_ID_COLOR_SELECT 0x14 /* virge PX_PADD pixel padding register */
-
-/* Graphics Controller: */
-#define GCT_ADDRESS 0x03CE
-#define GCT_ADDRESS_R 0x03CF
-#define GCT_ADDRESS_W 0x03CF
-#define GCT_ID_SET_RESET 0x00
-#define GCT_ID_ENABLE_SET_RESET 0x01
-#define GCT_ID_COLOR_COMPARE 0x02
-#define GCT_ID_DATA_ROTATE 0x03
-#define GCT_ID_READ_MAP_SELECT 0x04
-#define GCT_ID_GRAPHICS_MODE 0x05
-#define GCT_ID_MISC 0x06
-#define GCT_ID_COLOR_XCARE 0x07
-#define GCT_ID_BITMASK 0x08
-
-/* Sequencer: */
-#define SEQ_ADDRESS 0x03C4
-#define SEQ_ADDRESS_R 0x03C5
-#define SEQ_ADDRESS_W 0x03C5
-#define SEQ_ID_RESET 0x00
-#define SEQ_ID_CLOCKING_MODE 0x01
-#define SEQ_ID_MAP_MASK 0x02
-#define SEQ_ID_CHAR_MAP_SELECT 0x03
-#define SEQ_ID_MEMORY_MODE 0x04
-#define SEQ_ID_UNKNOWN1 0x05
-#define SEQ_ID_UNKNOWN2 0x06
-#define SEQ_ID_UNKNOWN3 0x07
-/* S3 extensions */
-#define SEQ_ID_UNLOCK_EXT 0x08
-#define SEQ_ID_EXT_SEQ_REG9 0x09 /* b7 = 1 extended reg access by MMIO only */
-#define SEQ_ID_BUS_REQ_CNTL 0x0A
-#define SEQ_ID_EXT_MISC_SEQ 0x0B
-#define SEQ_ID_UNKNOWN4 0x0C
-#define SEQ_ID_EXT_SEQ 0x0D
-#define SEQ_ID_UNKNOWN5 0x0E
-#define SEQ_ID_UNKNOWN6 0x0F
-#define SEQ_ID_MCLK_LO 0x10
-#define SEQ_ID_MCLK_HI 0x11
-#define SEQ_ID_DCLK_LO 0x12
-#define SEQ_ID_DCLK_HI 0x13
-#define SEQ_ID_CLKSYN_CNTL_1 0x14
-#define SEQ_ID_CLKSYN_CNTL_2 0x15
-#define SEQ_ID_CLKSYN_TEST_HI 0x16 /* reserved for S3 testing of the */
-#define SEQ_ID_CLKSYN_TEST_LO 0x17 /* internal clock synthesizer */
-#define SEQ_ID_RAMDAC_CNTL 0x18
-#define SEQ_ID_MORE_MAGIC 0x1A
-#define SEQ_ID_SIGNAL_SELECT 0x1C /* new for virge */
-
-/* CRT Controller: */
-#define CRT_ADDRESS 0x03D4
-#define CRT_ADDRESS_R 0x03D5
-#define CRT_ADDRESS_W 0x03D5
-#define CRT_ID_HOR_TOTAL 0x00
-#define CRT_ID_HOR_DISP_ENA_END 0x01
-#define CRT_ID_START_HOR_BLANK 0x02
-#define CRT_ID_END_HOR_BLANK 0x03
-#define CRT_ID_START_HOR_RETR 0x04
-#define CRT_ID_END_HOR_RETR 0x05
-#define CRT_ID_VER_TOTAL 0x06
-#define CRT_ID_OVERFLOW 0x07
-#define CRT_ID_PRESET_ROW_SCAN 0x08
-#define CRT_ID_MAX_SCAN_LINE 0x09
-#define CRT_ID_CURSOR_START 0x0A
-#define CRT_ID_CURSOR_END 0x0B
-#define CRT_ID_START_ADDR_HIGH 0x0C
-#define CRT_ID_START_ADDR_LOW 0x0D
-#define CRT_ID_CURSOR_LOC_HIGH 0x0E
-#define CRT_ID_CURSOR_LOC_LOW 0x0F
-#define CRT_ID_START_VER_RETR 0x10
-#define CRT_ID_END_VER_RETR 0x11
-#define CRT_ID_VER_DISP_ENA_END 0x12
-#define CRT_ID_SCREEN_OFFSET 0x13
-#define CRT_ID_UNDERLINE_LOC 0x14
-#define CRT_ID_START_VER_BLANK 0x15
-#define CRT_ID_END_VER_BLANK 0x16
-#define CRT_ID_MODE_CONTROL 0x17
-#define CRT_ID_LINE_COMPARE 0x18
-#define CRT_ID_GD_LATCH_RBACK 0x22
-#define CRT_ID_ACT_TOGGLE_RBACK 0x24
-#define CRT_ID_ACT_INDEX_RBACK 0x26
-/* S3 extensions: S3 VGA Registers */
-#define CRT_ID_DEVICE_HIGH 0x2D
-#define CRT_ID_DEVICE_LOW 0x2E
-#define CRT_ID_REVISION 0x2F
-#define CRT_ID_CHIP_ID_REV 0x30
-#define CRT_ID_MEMORY_CONF 0x31
-#define CRT_ID_BACKWAD_COMP_1 0x32
-#define CRT_ID_BACKWAD_COMP_2 0x33
-#define CRT_ID_BACKWAD_COMP_3 0x34
-#define CRT_ID_REGISTER_LOCK 0x35
-#define CRT_ID_CONFIG_1 0x36
-#define CRT_ID_CONFIG_2 0x37
-#define CRT_ID_REGISTER_LOCK_1 0x38
-#define CRT_ID_REGISTER_LOCK_2 0x39
-#define CRT_ID_MISC_1 0x3A
-#define CRT_ID_DISPLAY_FIFO 0x3B
-#define CRT_ID_LACE_RETR_START 0x3C
-/* S3 extensions: System Control Registers */
-#define CRT_ID_SYSTEM_CONFIG 0x40
-#define CRT_ID_BIOS_FLAG 0x41
-#define CRT_ID_LACE_CONTROL 0x42
-#define CRT_ID_EXT_MODE 0x43
-#define CRT_ID_HWGC_MODE 0x45 /* HWGC = Hardware Graphics Cursor */
-#define CRT_ID_HWGC_ORIGIN_X_HI 0x46
-#define CRT_ID_HWGC_ORIGIN_X_LO 0x47
-#define CRT_ID_HWGC_ORIGIN_Y_HI 0x48
-#define CRT_ID_HWGC_ORIGIN_Y_LO 0x49
-#define CRT_ID_HWGC_FG_STACK 0x4A
-#define CRT_ID_HWGC_BG_STACK 0x4B
-#define CRT_ID_HWGC_START_AD_HI 0x4C
-#define CRT_ID_HWGC_START_AD_LO 0x4D
-#define CRT_ID_HWGC_DSTART_X 0x4E
-#define CRT_ID_HWGC_DSTART_Y 0x4F
-/* S3 extensions: System Extension Registers */
-#define CRT_ID_EXT_SYS_CNTL_1 0x50 /* NOT a virge register */
-#define CRT_ID_EXT_SYS_CNTL_2 0x51
-#define CRT_ID_EXT_BIOS_FLAG_1 0x52
-#define CRT_ID_EXT_MEM_CNTL_1 0x53
-#define CRT_ID_EXT_MEM_CNTL_2 0x54
-#define CRT_ID_EXT_DAC_CNTL 0x55
-#define CRT_ID_EX_SYNC_1 0x56
-#define CRT_ID_EX_SYNC_2 0x57
-#define CRT_ID_LAW_CNTL 0x58 /* LAW = Linear Address Window */
-#define CRT_ID_LAW_POS_HI 0x59
-#define CRT_ID_LAW_POS_LO 0x5A
-#define CRT_ID_GOUT_PORT 0x5C
-#define CRT_ID_EXT_HOR_OVF 0x5D
-#define CRT_ID_EXT_VER_OVF 0x5E
-#define CRT_ID_EXT_MEM_CNTL_3 0x60 /* NOT a virge register */
-#define CRT_ID_EXT_MEM_CNTL_4 0x61
-#define CRT_ID_EX_SYNC_3 0x63 /* NOT a virge register */
-#define CRT_ID_EXT_MISC_CNTL 0x65
-#define CRT_ID_EXT_MISC_CNTL_1 0x66
-#define CRT_ID_EXT_MISC_CNTL_2 0x67
-#define CRT_ID_CONFIG_3 0x68
-#define CRT_ID_EXT_SYS_CNTL_3 0x69
-#define CRT_ID_EXT_SYS_CNTL_4 0x6A
-#define CRT_ID_EXT_BIOS_FLAG_3 0x6B
-#define CRT_ID_EXT_BIOS_FLAG_4 0x6C
-/* S3 virge extensions: more System Extension Registers */
-#define CRT_ID_EXT_BIOS_FLAG_5 0x6D
-#define CRT_ID_EXT_DAC_TEST 0x6E
-#define CRT_ID_CONFIG_4 0x6F
-
-/* Video DAC */
-#define VDAC_ADDRESS 0x03c8
-#define VDAC_ADDRESS_W 0x03c8
-#define VDAC_ADDRESS_R 0x03c7
-#define VDAC_STATE 0x03c7
-#define VDAC_DATA 0x03c9
-#define VDAC_MASK 0x03c6
-
-/* Miscellaneous Registers */
-#define MR_SUBSYSTEM_STATUS_R 0x8504 /* new for virge */
-#define MR_SUBSYSTEM_CNTL_W 0x8504 /* new for virge */
-#define MR_ADVANCED_FUNCTION_CONTROL 0x850C /* new for virge */
-
-/* Blitter */
-#define BLT_COMMAND_SET 0xA500
-#define BLT_SIZE_X_Y 0xA504
-#define BLT_SRC_X_Y 0xA508
-#define BLT_DEST_X_Y 0xA50C
-
-#define BLT_SRC_BASE 0xa4d4
-#define BLT_DEST_BASE 0xa4d8
-#define BLT_CLIP_LEFT_RIGHT 0xa4dc
-#define BLT_CLIP_TOP_BOTTOM 0xa4e0
-#define BLT_SRC_DEST_STRIDE 0xa4e4
-#define BLT_MONO_PATTERN_0 0xa4e8
-#define BLT_MONO_PATTERN_1 0xa4ec
-#define BLT_PATTERN_COLOR 0xa4f4
-
-#define L2D_COMMAND_SET 0xA900
-#define L2D_CLIP_LEFT_RIGHT 0xA8DC
-#define L2D_CLIP_TOP_BOTTOM 0xA8E0
-
-#define P2D_COMMAND_SET 0xAD00
-#define P2D_CLIP_LEFT_RIGHT 0xACDC
-#define P2D_CLIP_TOP_BOTTOM 0xACE0
-
-#define CMD_NOP (0xf << 27) /* %1111 << 27, was 0x07 */
-#define S3V_BITBLT (0x0 << 27)
-#define S3V_RECTFILL (0x2 << 27)
-#define S3V_AUTOEXE 0x01
-#define S3V_HWCLIP 0x02
-#define S3V_DRAW 0x20
-#define S3V_DST_8BPP 0x00
-#define S3V_DST_16BPP 0x04
-#define S3V_DST_24BPP 0x08
-#define S3V_MONO_PAT 0x100
-
-#define S3V_BLT_COPY (0xcc<<17)
-#define S3V_BLT_CLEAR (0x00<<17)
-#define S3V_BLT_SET (0xff<<17)
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index b022fffd8c51..732db4780042 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -141,7 +141,7 @@ static inline int w1_convert_temp(u8 rom[9], u8 fid)
{
int i;
- for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i)
+ for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i)
if (w1_therm_families[i].f->fid == fid)
return w1_therm_families[i].convert(rom);
@@ -238,7 +238,7 @@ static int __init w1_therm_init(void)
{
int err, i;
- for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i) {
+ for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) {
err = w1_register_family(w1_therm_families[i].f);
if (err)
w1_therm_families[i].broken = 1;
@@ -251,7 +251,7 @@ static void __exit w1_therm_fini(void)
{
int i;
- for (i=0; i<sizeof(w1_therm_families)/sizeof(w1_therm_families[0]); ++i)
+ for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i)
if (!w1_therm_families[i].broken)
w1_unregister_family(w1_therm_families[i].f);
}
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c
index 60b05bc15642..b3ce8859a586 100644
--- a/drivers/zorro/proc.c
+++ b/drivers/zorro/proc.c
@@ -75,7 +75,7 @@ proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *
return nbytes;
}
-static struct file_operations proc_bus_zorro_operations = {
+static const struct file_operations proc_bus_zorro_operations = {
.llseek = proc_bus_zorro_lseek,
.read = proc_bus_zorro_read,
};